Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(473)

Side by Side Diff: scsiconf.c

Issue 4279046: SCSI DMA correctness
Patch Set: diff #4 Created 14 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« safte.c ('K') | « scsi_ioctl.c ('k') | sd.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« safte.c ('K') | « scsi_ioctl.c ('k') | sd.c » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b