|
Lines 260-265
struct camdd_buf {
Link Here
|
| 260 |
|
260 |
|
| 261 |
struct camdd_dev_pass { |
261 |
struct camdd_dev_pass { |
| 262 |
int scsi_dev_type; |
262 |
int scsi_dev_type; |
|
|
263 |
int protocol; |
| 263 |
struct cam_device *dev; |
264 |
struct cam_device *dev; |
| 264 |
uint64_t max_sector; |
265 |
uint64_t max_sector; |
| 265 |
uint32_t block_len; |
266 |
uint32_t block_len; |
|
Lines 477-482
uint32_t camdd_buf_get_len(struct camdd_buf *buf);
Link Here
|
| 477 |
void camdd_buf_add_child(struct camdd_buf *buf, struct camdd_buf *child_buf); |
478 |
void camdd_buf_add_child(struct camdd_buf *buf, struct camdd_buf *child_buf); |
| 478 |
int camdd_probe_tape(int fd, char *filename, uint64_t *max_iosize, |
479 |
int camdd_probe_tape(int fd, char *filename, uint64_t *max_iosize, |
| 479 |
uint64_t *max_blk, uint64_t *min_blk, uint64_t *blk_gran); |
480 |
uint64_t *max_blk, uint64_t *min_blk, uint64_t *blk_gran); |
|
|
481 |
int camdd_probe_pass_scsi(struct cam_device *cam_dev, union ccb *ccb, |
| 482 |
camdd_argmask arglist, int probe_retry_count, |
| 483 |
int probe_timeout, uint64_t *maxsector, uint32_t *block_len); |
| 480 |
struct camdd_dev *camdd_probe_file(int fd, struct camdd_io_opts *io_opts, |
484 |
struct camdd_dev *camdd_probe_file(int fd, struct camdd_io_opts *io_opts, |
| 481 |
int retry_count, int timeout); |
485 |
int retry_count, int timeout); |
| 482 |
struct camdd_dev *camdd_probe_pass(struct cam_device *cam_dev, |
486 |
struct camdd_dev *camdd_probe_pass(struct cam_device *cam_dev, |
|
Lines 485-491
struct camdd_dev *camdd_probe_pass(struct cam_device *cam_dev,
Link Here
|
| 485 |
int probe_timeout, int io_retry_count, |
489 |
int probe_timeout, int io_retry_count, |
| 486 |
int io_timeout); |
490 |
int io_timeout); |
| 487 |
void *camdd_file_worker(void *arg); |
491 |
void *camdd_file_worker(void *arg); |
| 488 |
camdd_buf_status camdd_ccb_status(union ccb *ccb); |
492 |
camdd_buf_status camdd_ccb_status(union ccb *ccb, int protocol); |
|
|
493 |
int camdd_get_cgd(struct cam_device *device, struct ccb_getdev *cgd); |
| 489 |
int camdd_queue_peer_buf(struct camdd_dev *dev, struct camdd_buf *buf); |
494 |
int camdd_queue_peer_buf(struct camdd_dev *dev, struct camdd_buf *buf); |
| 490 |
int camdd_complete_peer_buf(struct camdd_dev *dev, struct camdd_buf *peer_buf); |
495 |
int camdd_complete_peer_buf(struct camdd_dev *dev, struct camdd_buf *peer_buf); |
| 491 |
void camdd_peer_done(struct camdd_buf *buf); |
496 |
void camdd_peer_done(struct camdd_buf *buf); |
|
Lines 1248-1303
bailout_error:
Link Here
|
| 1248 |
} |
1253 |
} |
| 1249 |
|
1254 |
|
| 1250 |
/* |
1255 |
/* |
| 1251 |
* Need to implement this. Do a basic probe: |
1256 |
* Get a get device CCB for the specified device. |
| 1252 |
* - Check the inquiry data, make sure we're talking to a device that we |
|
|
| 1253 |
* can reasonably expect to talk to -- direct, RBC, CD, WORM. |
| 1254 |
* - Send a test unit ready, make sure the device is available. |
| 1255 |
* - Get the capacity and block size. |
| 1256 |
*/ |
1257 |
*/ |
| 1257 |
struct camdd_dev * |
1258 |
int |
| 1258 |
camdd_probe_pass(struct cam_device *cam_dev, struct camdd_io_opts *io_opts, |
1259 |
camdd_get_cgd(struct cam_device *device, struct ccb_getdev *cgd) |
| 1259 |
camdd_argmask arglist, int probe_retry_count, |
|
|
| 1260 |
int probe_timeout, int io_retry_count, int io_timeout) |
| 1261 |
{ |
1260 |
{ |
| 1262 |
union ccb *ccb; |
1261 |
union ccb *ccb; |
| 1263 |
uint64_t maxsector; |
1262 |
int retval = 0; |
| 1264 |
uint32_t cpi_maxio, max_iosize, pass_numblocks; |
|
|
| 1265 |
uint32_t block_len; |
| 1266 |
struct scsi_read_capacity_data rcap; |
| 1267 |
struct scsi_read_capacity_data_long rcaplong; |
| 1268 |
struct camdd_dev *dev; |
| 1269 |
struct camdd_dev_pass *pass_dev; |
| 1270 |
struct kevent ke; |
| 1271 |
int scsi_dev_type; |
| 1272 |
|
1263 |
|
| 1273 |
dev = NULL; |
1264 |
ccb = cam_getccb(device); |
|
|
1265 |
|
| 1266 |
if (ccb == NULL) { |
| 1267 |
warnx("%s: couldn't allocate CCB", __func__); |
| 1268 |
return -1; |
| 1269 |
} |
| 1274 |
|
1270 |
|
| 1275 |
scsi_dev_type = SID_TYPE(&cam_dev->inq_data); |
1271 |
CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd); |
| 1276 |
maxsector = 0; |
|
|
| 1277 |
block_len = 0; |
| 1278 |
|
1272 |
|
| 1279 |
/* |
1273 |
ccb->ccb_h.func_code = XPT_GDEV_TYPE; |
| 1280 |
* For devices that support READ CAPACITY, we'll attempt to get the |
1274 |
|
| 1281 |
* capacity. Otherwise, we really don't support tape or other |
1275 |
if (cam_send_ccb(device, ccb) < 0) { |
| 1282 |
* devices via SCSI passthrough, so just return an error in that case. |
1276 |
warn("%s: error sending Get Device Information CCB", __func__); |
| 1283 |
*/ |
1277 |
cam_error_print(device, ccb, CAM_ESF_ALL, |
| 1284 |
switch (scsi_dev_type) { |
1278 |
CAM_EPF_ALL, stderr); |
| 1285 |
case T_DIRECT: |
1279 |
retval = -1; |
| 1286 |
case T_WORM: |
1280 |
goto bailout; |
| 1287 |
case T_CDROM: |
|
|
| 1288 |
case T_OPTICAL: |
| 1289 |
case T_RBC: |
| 1290 |
case T_ZBC_HM: |
| 1291 |
break; |
| 1292 |
default: |
| 1293 |
errx(1, "Unsupported SCSI device type %d", scsi_dev_type); |
| 1294 |
break; /*NOTREACHED*/ |
| 1295 |
} |
1281 |
} |
| 1296 |
|
1282 |
|
| 1297 |
ccb = cam_getccb(cam_dev); |
1283 |
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { |
|
|
1284 |
cam_error_print(device, ccb, CAM_ESF_ALL, |
| 1285 |
CAM_EPF_ALL, stderr); |
| 1286 |
retval = -1; |
| 1287 |
goto bailout; |
| 1288 |
} |
| 1289 |
|
| 1290 |
bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev)); |
| 1291 |
|
| 1292 |
bailout: |
| 1293 |
cam_freeccb(ccb); |
| 1294 |
|
| 1295 |
return retval; |
| 1296 |
} |
| 1297 |
|
| 1298 |
int |
| 1299 |
camdd_probe_pass_scsi(struct cam_device *cam_dev, union ccb *ccb, |
| 1300 |
camdd_argmask arglist, int probe_retry_count, |
| 1301 |
int probe_timeout, uint64_t *maxsector, uint32_t *block_len) |
| 1302 |
{ |
| 1303 |
struct scsi_read_capacity_data rcap; |
| 1304 |
struct scsi_read_capacity_data_long rcaplong; |
| 1305 |
int retval = -1; |
| 1298 |
|
1306 |
|
| 1299 |
if (ccb == NULL) { |
1307 |
if (ccb == NULL) { |
| 1300 |
warnx("%s: error allocating ccb", __func__); |
1308 |
warnx("%s: error passed ccb is NULL", __func__); |
| 1301 |
goto bailout; |
1309 |
goto bailout; |
| 1302 |
} |
1310 |
} |
| 1303 |
|
1311 |
|
|
Lines 1331-1346
camdd_probe_pass(struct cam_device *cam_dev, struct camdd_io_opts *io_opts,
Link Here
|
| 1331 |
goto bailout; |
1339 |
goto bailout; |
| 1332 |
} |
1340 |
} |
| 1333 |
|
1341 |
|
| 1334 |
maxsector = scsi_4btoul(rcap.addr); |
1342 |
*maxsector = scsi_4btoul(rcap.addr); |
| 1335 |
block_len = scsi_4btoul(rcap.length); |
1343 |
*block_len = scsi_4btoul(rcap.length); |
| 1336 |
|
1344 |
|
| 1337 |
/* |
1345 |
/* |
| 1338 |
* A last block of 2^32-1 means that the true capacity is over 2TB, |
1346 |
* A last block of 2^32-1 means that the true capacity is over 2TB, |
| 1339 |
* and we need to issue the long READ CAPACITY to get the real |
1347 |
* and we need to issue the long READ CAPACITY to get the real |
| 1340 |
* capacity. Otherwise, we're all set. |
1348 |
* capacity. Otherwise, we're all set. |
| 1341 |
*/ |
1349 |
*/ |
| 1342 |
if (maxsector != 0xffffffff) |
1350 |
if (*maxsector != 0xffffffff) { |
| 1343 |
goto rcap_done; |
1351 |
retval = 0; |
|
|
1352 |
goto bailout; |
| 1353 |
} |
| 1344 |
|
1354 |
|
| 1345 |
scsi_read_capacity_16(&ccb->csio, |
1355 |
scsi_read_capacity_16(&ccb->csio, |
| 1346 |
/*retries*/ probe_retry_count, |
1356 |
/*retries*/ probe_retry_count, |
|
Lines 1352-1358
camdd_probe_pass(struct cam_device *cam_dev, struct camdd_io_opts *io_opts,
Link Here
|
| 1352 |
(uint8_t *)&rcaplong, |
1362 |
(uint8_t *)&rcaplong, |
| 1353 |
sizeof(rcaplong), |
1363 |
sizeof(rcaplong), |
| 1354 |
/*sense_len*/ SSD_FULL_SIZE, |
1364 |
/*sense_len*/ SSD_FULL_SIZE, |
| 1355 |
/*timeout*/ probe_timeout ? probe_timeout : 5000); |
1365 |
/*timeout*/ probe_timeout ? |
|
|
1366 |
probe_timeout : 5000); |
| 1356 |
|
1367 |
|
| 1357 |
/* Disable freezing the device queue */ |
1368 |
/* Disable freezing the device queue */ |
| 1358 |
ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; |
1369 |
ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; |
|
Lines 1368-1381
camdd_probe_pass(struct cam_device *cam_dev, struct camdd_io_opts *io_opts,
Link Here
|
| 1368 |
} |
1379 |
} |
| 1369 |
|
1380 |
|
| 1370 |
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { |
1381 |
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { |
| 1371 |
cam_error_print(cam_dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); |
1382 |
cam_error_print(cam_dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, |
|
|
1383 |
stderr); |
| 1372 |
goto bailout; |
1384 |
goto bailout; |
| 1373 |
} |
1385 |
} |
| 1374 |
|
1386 |
|
| 1375 |
maxsector = scsi_8btou64(rcaplong.addr); |
1387 |
*maxsector = scsi_8btou64(rcaplong.addr); |
| 1376 |
block_len = scsi_4btoul(rcaplong.length); |
1388 |
*block_len = scsi_4btoul(rcaplong.length); |
|
|
1389 |
|
| 1390 |
retval = 0; |
| 1391 |
|
| 1392 |
bailout: |
| 1393 |
return retval; |
| 1394 |
} |
| 1395 |
|
| 1396 |
/* |
| 1397 |
* Need to implement this. Do a basic probe: |
| 1398 |
* - Check the inquiry data, make sure we're talking to a device that we |
| 1399 |
* can reasonably expect to talk to -- direct, RBC, CD, WORM. |
| 1400 |
* - Send a test unit ready, make sure the device is available. |
| 1401 |
* - Get the capacity and block size. |
| 1402 |
*/ |
| 1403 |
struct camdd_dev * |
| 1404 |
camdd_probe_pass(struct cam_device *cam_dev, struct camdd_io_opts *io_opts, |
| 1405 |
camdd_argmask arglist, int probe_retry_count, |
| 1406 |
int probe_timeout, int io_retry_count, int io_timeout) |
| 1407 |
{ |
| 1408 |
union ccb *ccb; |
| 1409 |
uint64_t maxsector = 0; |
| 1410 |
uint32_t cpi_maxio, max_iosize, pass_numblocks; |
| 1411 |
uint32_t block_len = 0; |
| 1412 |
struct camdd_dev *dev = NULL; |
| 1413 |
struct camdd_dev_pass *pass_dev; |
| 1414 |
struct kevent ke; |
| 1415 |
struct ccb_getdev cgd; |
| 1416 |
int retval; |
| 1417 |
int scsi_dev_type; |
| 1418 |
|
| 1419 |
if ((retval = camdd_get_cgd(cam_dev, &cgd)) != 0) { |
| 1420 |
warnx("%s: error retrieving CGD", __func__); |
| 1421 |
return NULL; |
| 1422 |
} |
| 1423 |
|
| 1424 |
ccb = cam_getccb(cam_dev); |
| 1425 |
|
| 1426 |
if (ccb == NULL) { |
| 1427 |
warnx("%s: error allocating ccb", __func__); |
| 1428 |
goto bailout; |
| 1429 |
} |
| 1430 |
|
| 1431 |
switch (cgd.protocol) { |
| 1432 |
case PROTO_SCSI: |
| 1433 |
scsi_dev_type = SID_TYPE(&cam_dev->inq_data); |
| 1434 |
|
| 1435 |
/* |
| 1436 |
* For devices that support READ CAPACITY, we'll attempt to get the |
| 1437 |
* capacity. Otherwise, we really don't support tape or other |
| 1438 |
* devices via SCSI passthrough, so just return an error in that case. |
| 1439 |
*/ |
| 1440 |
switch (scsi_dev_type) { |
| 1441 |
case T_DIRECT: |
| 1442 |
case T_WORM: |
| 1443 |
case T_CDROM: |
| 1444 |
case T_OPTICAL: |
| 1445 |
case T_RBC: |
| 1446 |
case T_ZBC_HM: |
| 1447 |
break; |
| 1448 |
default: |
| 1449 |
errx(1, "Unsupported SCSI device type %d", scsi_dev_type); |
| 1450 |
break; /*NOTREACHED*/ |
| 1451 |
} |
| 1452 |
|
| 1453 |
if ((retval = camdd_probe_pass_scsi(cam_dev, ccb, probe_retry_count, |
| 1454 |
arglist, probe_timeout, &maxsector, |
| 1455 |
&block_len))) { |
| 1456 |
goto bailout; |
| 1457 |
} |
| 1458 |
break; |
| 1459 |
default: |
| 1460 |
errx(1, "Unsupported PROTO type %d", cgd.protocol); |
| 1461 |
break; /*NOTREACHED*/ |
| 1462 |
} |
| 1377 |
|
1463 |
|
| 1378 |
rcap_done: |
|
|
| 1379 |
if (block_len == 0) { |
1464 |
if (block_len == 0) { |
| 1380 |
warnx("Sector size for %s%u is 0, cannot continue", |
1465 |
warnx("Sector size for %s%u is 0, cannot continue", |
| 1381 |
cam_dev->device_name, cam_dev->dev_unit_num); |
1466 |
cam_dev->device_name, cam_dev->dev_unit_num); |
|
Lines 1405-1410
rcap_done:
Link Here
|
| 1405 |
|
1490 |
|
| 1406 |
pass_dev = &dev->dev_spec.pass; |
1491 |
pass_dev = &dev->dev_spec.pass; |
| 1407 |
pass_dev->scsi_dev_type = scsi_dev_type; |
1492 |
pass_dev->scsi_dev_type = scsi_dev_type; |
|
|
1493 |
pass_dev->protocol = cgd.protocol; |
| 1408 |
pass_dev->dev = cam_dev; |
1494 |
pass_dev->dev = cam_dev; |
| 1409 |
pass_dev->max_sector = maxsector; |
1495 |
pass_dev->max_sector = maxsector; |
| 1410 |
pass_dev->block_len = block_len; |
1496 |
pass_dev->block_len = block_len; |
|
Lines 1715-1757
bailout:
Link Here
|
| 1715 |
* Simplistic translation of CCB status to our local status. |
1801 |
* Simplistic translation of CCB status to our local status. |
| 1716 |
*/ |
1802 |
*/ |
| 1717 |
camdd_buf_status |
1803 |
camdd_buf_status |
| 1718 |
camdd_ccb_status(union ccb *ccb) |
1804 |
camdd_ccb_status(union ccb *ccb, int protocol) |
| 1719 |
{ |
1805 |
{ |
| 1720 |
camdd_buf_status status = CAMDD_STATUS_NONE; |
1806 |
camdd_buf_status status = CAMDD_STATUS_NONE; |
| 1721 |
cam_status ccb_status; |
1807 |
cam_status ccb_status; |
| 1722 |
|
1808 |
|
| 1723 |
ccb_status = ccb->ccb_h.status & CAM_STATUS_MASK; |
1809 |
ccb_status = ccb->ccb_h.status & CAM_STATUS_MASK; |
| 1724 |
|
1810 |
|
| 1725 |
switch (ccb_status) { |
1811 |
switch (protocol) { |
| 1726 |
case CAM_REQ_CMP: { |
1812 |
case PROTO_SCSI: |
| 1727 |
if (ccb->csio.resid == 0) { |
1813 |
switch (ccb_status) { |
| 1728 |
status = CAMDD_STATUS_OK; |
1814 |
case CAM_REQ_CMP: { |
| 1729 |
} else if (ccb->csio.dxfer_len > ccb->csio.resid) { |
1815 |
if (ccb->csio.resid == 0) { |
| 1730 |
status = CAMDD_STATUS_SHORT_IO; |
1816 |
status = CAMDD_STATUS_OK; |
| 1731 |
} else { |
1817 |
} else if (ccb->csio.dxfer_len > ccb->csio.resid) { |
| 1732 |
status = CAMDD_STATUS_EOF; |
1818 |
status = CAMDD_STATUS_SHORT_IO; |
|
|
1819 |
} else { |
| 1820 |
status = CAMDD_STATUS_EOF; |
| 1821 |
} |
| 1822 |
break; |
| 1733 |
} |
1823 |
} |
| 1734 |
break; |
1824 |
case CAM_SCSI_STATUS_ERROR: { |
| 1735 |
} |
1825 |
switch (ccb->csio.scsi_status) { |
| 1736 |
case CAM_SCSI_STATUS_ERROR: { |
1826 |
case SCSI_STATUS_OK: |
| 1737 |
switch (ccb->csio.scsi_status) { |
1827 |
case SCSI_STATUS_COND_MET: |
| 1738 |
case SCSI_STATUS_OK: |
1828 |
case SCSI_STATUS_INTERMED: |
| 1739 |
case SCSI_STATUS_COND_MET: |
1829 |
case SCSI_STATUS_INTERMED_COND_MET: |
| 1740 |
case SCSI_STATUS_INTERMED: |
1830 |
status = CAMDD_STATUS_OK; |
| 1741 |
case SCSI_STATUS_INTERMED_COND_MET: |
1831 |
break; |
| 1742 |
status = CAMDD_STATUS_OK; |
1832 |
case SCSI_STATUS_CMD_TERMINATED: |
|
|
1833 |
case SCSI_STATUS_CHECK_COND: |
| 1834 |
case SCSI_STATUS_QUEUE_FULL: |
| 1835 |
case SCSI_STATUS_BUSY: |
| 1836 |
case SCSI_STATUS_RESERV_CONFLICT: |
| 1837 |
default: |
| 1838 |
status = CAMDD_STATUS_ERROR; |
| 1839 |
break; |
| 1840 |
} |
| 1743 |
break; |
1841 |
break; |
| 1744 |
case SCSI_STATUS_CMD_TERMINATED: |
1842 |
} |
| 1745 |
case SCSI_STATUS_CHECK_COND: |
|
|
| 1746 |
case SCSI_STATUS_QUEUE_FULL: |
| 1747 |
case SCSI_STATUS_BUSY: |
| 1748 |
case SCSI_STATUS_RESERV_CONFLICT: |
| 1749 |
default: |
1843 |
default: |
| 1750 |
status = CAMDD_STATUS_ERROR; |
1844 |
status = CAMDD_STATUS_ERROR; |
| 1751 |
break; |
1845 |
break; |
| 1752 |
} |
1846 |
} |
| 1753 |
break; |
1847 |
break; |
| 1754 |
} |
|
|
| 1755 |
default: |
1848 |
default: |
| 1756 |
status = CAMDD_STATUS_ERROR; |
1849 |
status = CAMDD_STATUS_ERROR; |
| 1757 |
break; |
1850 |
break; |
|
Lines 2149-2159
camdd_pass_fetch(struct camdd_dev *dev)
Link Here
|
| 2149 |
CAM_EPF_ALL, stderr); |
2242 |
CAM_EPF_ALL, stderr); |
| 2150 |
} |
2243 |
} |
| 2151 |
|
2244 |
|
| 2152 |
data->resid = ccb.csio.resid; |
2245 |
switch (pass_dev->protocol) { |
| 2153 |
dev->bytes_transferred += (ccb.csio.dxfer_len - ccb.csio.resid); |
2246 |
case PROTO_SCSI: |
|
|
2247 |
data->resid = ccb.csio.resid; |
| 2248 |
dev->bytes_transferred += (ccb.csio.dxfer_len - ccb.csio.resid); |
| 2249 |
break; |
| 2250 |
default: |
| 2251 |
return -1; |
| 2252 |
break; |
| 2253 |
} |
| 2154 |
|
2254 |
|
| 2155 |
if (buf->status == CAMDD_STATUS_NONE) |
2255 |
if (buf->status == CAMDD_STATUS_NONE) |
| 2156 |
buf->status = camdd_ccb_status(&ccb); |
2256 |
buf->status = camdd_ccb_status(&ccb, pass_dev->protocol); |
| 2157 |
if (buf->status == CAMDD_STATUS_ERROR) |
2257 |
if (buf->status == CAMDD_STATUS_ERROR) |
| 2158 |
error_count++; |
2258 |
error_count++; |
| 2159 |
else if (buf->status == CAMDD_STATUS_EOF) { |
2259 |
else if (buf->status == CAMDD_STATUS_EOF) { |
|
Lines 2433-2441
camdd_pass_run(struct camdd_dev *dev)
Link Here
|
| 2433 |
|
2533 |
|
| 2434 |
data = &buf->buf_type_spec.data; |
2534 |
data = &buf->buf_type_spec.data; |
| 2435 |
|
2535 |
|
| 2436 |
ccb = &data->ccb; |
|
|
| 2437 |
CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); |
| 2438 |
|
| 2439 |
/* |
2536 |
/* |
| 2440 |
* In almost every case the number of blocks should be the device |
2537 |
* In almost every case the number of blocks should be the device |
| 2441 |
* block size. The exception may be at the end of an I/O stream |
2538 |
* block size. The exception may be at the end of an I/O stream |
|
Lines 2446-2466
camdd_pass_run(struct camdd_dev *dev)
Link Here
|
| 2446 |
else |
2543 |
else |
| 2447 |
num_blocks = data->fill_len / pass_dev->block_len; |
2544 |
num_blocks = data->fill_len / pass_dev->block_len; |
| 2448 |
|
2545 |
|
| 2449 |
scsi_read_write(&ccb->csio, |
2546 |
ccb = &data->ccb; |
| 2450 |
/*retries*/ dev->retry_count, |
2547 |
|
| 2451 |
/*cbfcnp*/ NULL, |
2548 |
switch (pass_dev->protocol) { |
| 2452 |
/*tag_action*/ MSG_SIMPLE_Q_TAG, |
2549 |
case PROTO_SCSI: |
| 2453 |
/*readop*/ (dev->write_dev == 0) ? SCSI_RW_READ : |
2550 |
CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); |
| 2454 |
SCSI_RW_WRITE, |
2551 |
|
| 2455 |
/*byte2*/ 0, |
2552 |
scsi_read_write(&ccb->csio, |
| 2456 |
/*minimum_cmd_size*/ dev->min_cmd_size, |
2553 |
/*retries*/ dev->retry_count, |
| 2457 |
/*lba*/ buf->lba, |
2554 |
/*cbfcnp*/ NULL, |
| 2458 |
/*block_count*/ num_blocks, |
2555 |
/*tag_action*/ MSG_SIMPLE_Q_TAG, |
| 2459 |
/*data_ptr*/ (data->sg_count != 0) ? |
2556 |
/*readop*/ (dev->write_dev == 0) ? SCSI_RW_READ : |
| 2460 |
(uint8_t *)data->segs : data->buf, |
2557 |
SCSI_RW_WRITE, |
| 2461 |
/*dxfer_len*/ (num_blocks * pass_dev->block_len), |
2558 |
/*byte2*/ 0, |
| 2462 |
/*sense_len*/ SSD_FULL_SIZE, |
2559 |
/*minimum_cmd_size*/ dev->min_cmd_size, |
| 2463 |
/*timeout*/ dev->io_timeout); |
2560 |
/*lba*/ buf->lba, |
|
|
2561 |
/*block_count*/ num_blocks, |
| 2562 |
/*data_ptr*/ (data->sg_count != 0) ? |
| 2563 |
(uint8_t *)data->segs : data->buf, |
| 2564 |
/*dxfer_len*/ (num_blocks * pass_dev->block_len), |
| 2565 |
/*sense_len*/ SSD_FULL_SIZE, |
| 2566 |
/*timeout*/ dev->io_timeout); |
| 2567 |
|
| 2568 |
if (data->sg_count != 0) { |
| 2569 |
ccb->csio.sglist_cnt = data->sg_count; |
| 2570 |
} |
| 2571 |
break; |
| 2572 |
default: |
| 2573 |
retval = -1; |
| 2574 |
goto bailout; |
| 2575 |
} |
| 2464 |
|
2576 |
|
| 2465 |
/* Disable freezing the device queue */ |
2577 |
/* Disable freezing the device queue */ |
| 2466 |
ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; |
2578 |
ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; |
|
Lines 2469-2475
camdd_pass_run(struct camdd_dev *dev)
Link Here
|
| 2469 |
ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; |
2581 |
ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; |
| 2470 |
|
2582 |
|
| 2471 |
if (data->sg_count != 0) { |
2583 |
if (data->sg_count != 0) { |
| 2472 |
ccb->csio.sglist_cnt = data->sg_count; |
|
|
| 2473 |
ccb->ccb_h.flags |= CAM_DATA_SG; |
2584 |
ccb->ccb_h.flags |= CAM_DATA_SG; |
| 2474 |
} |
2585 |
} |
| 2475 |
|
2586 |
|
| 2476 |
- |
|
|