Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* $OpenBSD: scsiconf.c,v 1.167 2010/10/12 00:53:32 krw Exp $ */ | 1 /* $OpenBSD: scsiconf.c,v 1.167 2010/10/12 00:53:32 krw Exp $ */ |
2 /* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */ | 2 /* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */ |
3 | 3 |
4 /* | 4 /* |
5 * Copyright (c) 1994 Charles Hannum. All rights reserved. | 5 * Copyright (c) 1994 Charles Hannum. All rights reserved. |
6 * | 6 * |
7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
9 * are met: | 9 * are met: |
10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 | 47 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 |
48 */ | 48 */ |
49 | 49 |
50 #include "bio.h" | 50 #include "bio.h" |
51 #include "mpath.h" | 51 #include "mpath.h" |
52 | 52 |
53 #include <sys/types.h> | 53 #include <sys/types.h> |
54 #include <sys/param.h> | 54 #include <sys/param.h> |
55 #include <sys/systm.h> | 55 #include <sys/systm.h> |
56 #include <sys/malloc.h> | 56 #include <sys/malloc.h> |
57 #include <sys/pool.h> | |
57 #include <sys/device.h> | 58 #include <sys/device.h> |
58 #include <sys/buf.h> | 59 #include <sys/buf.h> |
59 #include <sys/lock.h> | 60 #include <sys/lock.h> |
60 | 61 |
61 #include <scsi/scsi_all.h> | 62 #include <scsi/scsi_all.h> |
62 #include <scsi/scsiconf.h> | 63 #include <scsi/scsiconf.h> |
63 | 64 |
64 #if NBIO > 0 | 65 #if NBIO > 0 |
65 #include <sys/ioctl.h> | 66 #include <sys/ioctl.h> |
66 #include <sys/scsiio.h> | 67 #include <sys/scsiio.h> |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 | 375 |
375 if (scsi_probe_lun(sc, target, 0) == EINVAL) | 376 if (scsi_probe_lun(sc, target, 0) == EINVAL) |
376 return (EINVAL); | 377 return (EINVAL); |
377 | 378 |
378 link = scsi_get_link(sc, target, 0); | 379 link = scsi_get_link(sc, target, 0); |
379 if (link == NULL) | 380 if (link == NULL) |
380 return (ENXIO); | 381 return (ENXIO); |
381 | 382 |
382 if ((link->flags & (SDEV_UMASS | SDEV_ATAPI)) == 0 && | 383 if ((link->flags & (SDEV_UMASS | SDEV_ATAPI)) == 0 && |
383 SCSISPC(link->inqdata.version) > 2) { | 384 SCSISPC(link->inqdata.version) > 2) { |
384 » » report = malloc(sizeof(*report), M_TEMP, M_WAITOK); | 385 » » report = dma_alloc(sizeof(*report), PR_WAITOK); |
385 if (report == NULL) | 386 if (report == NULL) |
386 goto dumbscan; | 387 goto dumbscan; |
387 | 388 |
388 if (scsi_report_luns(link, REPORT_NORMAL, report, | 389 if (scsi_report_luns(link, REPORT_NORMAL, report, |
389 sizeof(*report), scsi_autoconf | SCSI_SILENT | | 390 sizeof(*report), scsi_autoconf | SCSI_SILENT | |
390 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY | | 391 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY | |
391 SCSI_IGNORE_MEDIA_CHANGE, 10000) != 0) { | 392 SCSI_IGNORE_MEDIA_CHANGE, 10000) != 0) { |
392 » » » free(report, M_TEMP); | 393 » » » dma_free(report, sizeof(*report)); |
393 goto dumbscan; | 394 goto dumbscan; |
394 } | 395 } |
395 | 396 |
396 /* | 397 /* |
397 * XXX In theory we should check if data is full, which | 398 * XXX In theory we should check if data is full, which |
398 * would indicate it needs to be enlarged and REPORT | 399 * would indicate it needs to be enlarged and REPORT |
399 * LUNS tried again. Solaris tries up to 3 times with | 400 * LUNS tried again. Solaris tries up to 3 times with |
400 * larger sizes for data. | 401 * larger sizes for data. |
401 */ | 402 */ |
402 nluns = _4btol(report->length) / RPL_LUNDATA_SIZE; | 403 nluns = _4btol(report->length) / RPL_LUNDATA_SIZE; |
403 for (i = 0; i < nluns; i++) { | 404 for (i = 0; i < nluns; i++) { |
404 if (report->luns[i].lundata[0] != 0) | 405 if (report->luns[i].lundata[0] != 0) |
405 continue; | 406 continue; |
406 lun = report->luns[i].lundata[RPL_LUNDATA_T0LUN]; | 407 lun = report->luns[i].lundata[RPL_LUNDATA_T0LUN]; |
407 if (lun == 0) | 408 if (lun == 0) |
408 continue; | 409 continue; |
409 | 410 |
410 /* Probe the provided LUN. Don't check LUN 0. */ | 411 /* Probe the provided LUN. Don't check LUN 0. */ |
411 scsi_remove_link(sc, link); | 412 scsi_remove_link(sc, link); |
412 scsi_probe_lun(sc, target, lun); | 413 scsi_probe_lun(sc, target, lun); |
413 scsi_add_link(sc, link); | 414 scsi_add_link(sc, link); |
414 } | 415 } |
415 | 416 |
416 » » free(report, M_TEMP); | 417 » » dma_free(report, sizeof(*report)); |
417 return (0); | 418 return (0); |
418 } | 419 } |
419 | 420 |
420 dumbscan: | 421 dumbscan: |
421 for (i = 1; i < alink->luns; i++) { | 422 for (i = 1; i < alink->luns; i++) { |
422 if (scsi_probe_lun(sc, target, i) == EINVAL) | 423 if (scsi_probe_lun(sc, target, i) == EINVAL) |
423 break; | 424 break; |
424 } | 425 } |
425 | 426 |
426 return (0); | 427 return (0); |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1129 | 1130 |
1130 return (bestmatch); | 1131 return (bestmatch); |
1131 } | 1132 } |
1132 | 1133 |
1133 void | 1134 void |
1134 scsi_devid(struct scsi_link *link) | 1135 scsi_devid(struct scsi_link *link) |
1135 { | 1136 { |
1136 struct { | 1137 struct { |
1137 struct scsi_vpd_hdr hdr; | 1138 struct scsi_vpd_hdr hdr; |
1138 u_int8_t list[32]; | 1139 u_int8_t list[32]; |
1139 » } __packed pg; | 1140 » } __packed *pg; |
1140 int pg80 = 0, pg83 = 0, i; | 1141 int pg80 = 0, pg83 = 0, i; |
1141 size_t len; | 1142 size_t len; |
1142 | 1143 |
1143 if (link->id != NULL) | 1144 if (link->id != NULL) |
1144 return; | 1145 return; |
1145 | 1146 |
1147 pg = dma_alloc(sizeof(*pg), PR_WAITOK | PR_ZERO); | |
1148 | |
1146 if (SCSISPC(link->inqdata.version) >= 2) { | 1149 if (SCSISPC(link->inqdata.version) >= 2) { |
1147 » » if (scsi_inquire_vpd(link, &pg, sizeof(pg), SI_PG_SUPPORTED, | 1150 » » if (scsi_inquire_vpd(link, pg, sizeof(pg), SI_PG_SUPPORTED, |
Matthew Dempsky
2011/03/12 02:06:00
Need sizeof(*pg) here.
| |
1148 scsi_autoconf) != 0) | 1151 scsi_autoconf) != 0) |
1149 » » » return; | 1152 » » » goto done; |
1150 | 1153 |
1151 » » len = MIN(sizeof(pg.list), _2btol(pg.hdr.page_length)); | 1154 » » len = MIN(sizeof(pg->list), _2btol(pg->hdr.page_length)); |
1152 for (i = 0; i < len; i++) { | 1155 for (i = 0; i < len; i++) { |
1153 » » » switch (pg.list[i]) { | 1156 » » » switch (pg->list[i]) { |
1154 case SI_PG_SERIAL: | 1157 case SI_PG_SERIAL: |
1155 pg80 = 1; | 1158 pg80 = 1; |
1156 break; | 1159 break; |
1157 case SI_PG_DEVID: | 1160 case SI_PG_DEVID: |
1158 pg83 = 1; | 1161 pg83 = 1; |
1159 break; | 1162 break; |
1160 } | 1163 } |
1161 } | 1164 } |
1162 | 1165 |
1163 if (pg83 && scsi_devid_pg83(link) == 0) | 1166 if (pg83 && scsi_devid_pg83(link) == 0) |
1164 » » » return; | 1167 » » » goto done; |
1165 #ifdef notyet | 1168 #ifdef notyet |
1166 if (pg80 && scsi_devid_pg80(link) == 0) | 1169 if (pg80 && scsi_devid_pg80(link) == 0) |
1167 » » » return; | 1170 » » » goto done; |
1168 #endif | 1171 #endif |
1169 } | 1172 } |
1173 done: | |
1174 dma_free(pg, sizeof(*pg)); | |
1170 } | 1175 } |
1171 | 1176 |
1172 int | 1177 int |
1173 scsi_devid_pg83(struct scsi_link *link) | 1178 scsi_devid_pg83(struct scsi_link *link) |
1174 { | 1179 { |
1175 » struct scsi_vpd_hdr hdr; | 1180 » struct scsi_vpd_hdr *hdr = NULL; |
1176 struct scsi_vpd_devid_hdr dhdr, chdr; | 1181 struct scsi_vpd_devid_hdr dhdr, chdr; |
1177 » u_int8_t *pg, *id; | 1182 » u_int8_t *pg = NULL, *id; |
1178 int type, idtype = 0; | 1183 int type, idtype = 0; |
1179 u_char idflags; | 1184 u_char idflags; |
1180 int len, pos; | 1185 int len, pos; |
1181 int rv; | 1186 int rv; |
1182 | 1187 |
1183 » rv = scsi_inquire_vpd(link, &hdr, sizeof(hdr), SI_PG_DEVID, | 1188 » hdr = dma_alloc(sizeof(*hdr), PR_WAITOK | PR_ZERO); |
1189 | |
1190 » rv = scsi_inquire_vpd(link, hdr, sizeof(*hdr), SI_PG_DEVID, | |
1184 scsi_autoconf); | 1191 scsi_autoconf); |
1185 if (rv != 0) | 1192 if (rv != 0) |
1186 » » return (rv); | 1193 » » goto done; |
1187 | 1194 |
1188 » len = sizeof(hdr) + _2btol(hdr.page_length); | 1195 » len = sizeof(*hdr) + _2btol(hdr->page_length); |
1189 » pg = malloc(len, M_TEMP, M_WAITOK); | 1196 » pg = dma_alloc(len, PR_WAITOK | PR_ZERO); |
1190 | 1197 |
1191 rv = scsi_inquire_vpd(link, pg, len, SI_PG_DEVID, scsi_autoconf); | 1198 rv = scsi_inquire_vpd(link, pg, len, SI_PG_DEVID, scsi_autoconf); |
1192 if (rv != 0) | 1199 if (rv != 0) |
1193 » » goto err; | 1200 » » goto done; |
1194 | 1201 |
1195 » pos = sizeof(hdr); | 1202 » pos = sizeof(*hdr); |
1196 | 1203 |
1197 do { | 1204 do { |
1198 if (len - pos < sizeof(dhdr)) { | 1205 if (len - pos < sizeof(dhdr)) { |
1199 rv = EIO; | 1206 rv = EIO; |
1200 » » » goto err; | 1207 » » » goto done; |
1201 } | 1208 } |
1202 memcpy(&dhdr, &pg[pos], sizeof(dhdr)); | 1209 memcpy(&dhdr, &pg[pos], sizeof(dhdr)); |
1203 pos += sizeof(dhdr); | 1210 pos += sizeof(dhdr); |
1204 if (len - pos < dhdr.len) { | 1211 if (len - pos < dhdr.len) { |
1205 rv = EIO; | 1212 rv = EIO; |
1206 » » » goto err; | 1213 » » » goto done; |
1207 } | 1214 } |
1208 | 1215 |
1209 if (VPD_DEVID_ASSOC(dhdr.flags) == VPD_DEVID_ASSOC_LU) { | 1216 if (VPD_DEVID_ASSOC(dhdr.flags) == VPD_DEVID_ASSOC_LU) { |
1210 type = VPD_DEVID_TYPE(dhdr.flags); | 1217 type = VPD_DEVID_TYPE(dhdr.flags); |
1211 switch (type) { | 1218 switch (type) { |
1212 case VPD_DEVID_TYPE_NAA: | 1219 case VPD_DEVID_TYPE_NAA: |
1213 case VPD_DEVID_TYPE_EUI64: | 1220 case VPD_DEVID_TYPE_EUI64: |
1214 case VPD_DEVID_TYPE_T10: | 1221 case VPD_DEVID_TYPE_T10: |
1215 if (type >= idtype) { | 1222 if (type >= idtype) { |
1216 idtype = type; | 1223 idtype = type; |
(...skipping 30 matching lines...) Expand all Loading... | |
1247 idflags = DEVID_F_PRINT; | 1254 idflags = DEVID_F_PRINT; |
1248 break; | 1255 break; |
1249 default: | 1256 default: |
1250 idflags = 0; | 1257 idflags = 0; |
1251 break; | 1258 break; |
1252 } | 1259 } |
1253 link->id = devid_alloc(idtype, idflags, chdr.len, id); | 1260 link->id = devid_alloc(idtype, idflags, chdr.len, id); |
1254 } else | 1261 } else |
1255 rv = ENODEV; | 1262 rv = ENODEV; |
1256 | 1263 |
1257 err: | 1264 done: |
1258 » free(pg, M_TEMP); | 1265 » if (pg) |
1266 » » dma_free(pg, sizeof(*pg)); | |
Matthew Dempsky
2011/03/12 02:06:00
Should be dma_free(pg, len).
| |
1267 » if (hdr) | |
1268 » » dma_free(hdr, len); | |
Matthew Dempsky
2011/03/12 02:06:00
Should be dma_free(hdr, sizeof(*hdr)).
| |
1259 return (rv); | 1269 return (rv); |
1260 } | 1270 } |
1261 | 1271 |
1262 /* | 1272 /* |
1263 * scsi_minphys member of struct scsi_adapter for drivers which don't | 1273 * scsi_minphys member of struct scsi_adapter for drivers which don't |
1264 * need any specific routine. | 1274 * need any specific routine. |
1265 */ | 1275 */ |
1266 void | 1276 void |
1267 scsi_minphys(struct buf *bp, struct scsi_link *sl) | 1277 scsi_minphys(struct buf *bp, struct scsi_link *sl) |
1268 { | 1278 { |
(...skipping 24 matching lines...) Expand all Loading... | |
1293 d->d_refcount++; | 1303 d->d_refcount++; |
1294 return (d); | 1304 return (d); |
1295 } | 1305 } |
1296 | 1306 |
1297 void | 1307 void |
1298 devid_free(struct devid *d) | 1308 devid_free(struct devid *d) |
1299 { | 1309 { |
1300 if (--d->d_refcount == 0) | 1310 if (--d->d_refcount == 0) |
1301 free(d, M_DEVBUF); | 1311 free(d, M_DEVBUF); |
1302 } | 1312 } |
OLD | NEW |