View | Details | Raw Unified | Return to bug 220371
Collapse All | Expand All

(-)b/usr.sbin/camdd/camdd.c (-98 / +208 lines)
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
- 

Return to bug 220371