View | Details | Raw Unified | Return to bug 219857 | Differences between
and this patch

Collapse All | Expand All

(-)scsi_cd.c (-43 / +542 lines)
Lines 112-124 typedef enum { Link Here
112
	CD_FLAG_RETRY_UA	= 0x0200,
112
	CD_FLAG_RETRY_UA	= 0x0200,
113
	CD_FLAG_VALID_MEDIA	= 0x0400,
113
	CD_FLAG_VALID_MEDIA	= 0x0400,
114
	CD_FLAG_VALID_TOC	= 0x0800,
114
	CD_FLAG_VALID_TOC	= 0x0800,
115
	CD_FLAG_SCTX_INIT	= 0x1000
115
	CD_FLAG_SCTX_INIT	= 0x1000,
116
	CD_FLAG_MEDIA_WAIT	= 0x2000,
117
	CD_FLAG_MEDIA_SCAN_ACT	= 0x4000
116
} cd_flags;
118
} cd_flags;
117
119
118
typedef enum {
120
typedef enum {
119
	CD_CCB_PROBE		= 0x01,
121
	CD_CCB_PROBE		= 0x01,
120
	CD_CCB_BUFFER_IO	= 0x02,
122
	CD_CCB_BUFFER_IO	= 0x02,
121
	CD_CCB_TUR		= 0x04,
123
	CD_CCB_TUR		= 0x03,
124
	CD_CCB_MEDIA_PREVENT	= 0x04,
125
	CD_CCB_MEDIA_ALLOW	= 0x05,
126
	CD_CCB_MEDIA_SIZE	= 0x06,
127
	CD_CCB_MEDIA_TOC_HDR	= 0x07,
128
	CD_CCB_MEDIA_TOC_FULL	= 0x08,
129
	CD_CCB_MEDIA_TOC_LEAD	= 0x09,
122
	CD_CCB_TYPE_MASK	= 0x0F,
130
	CD_CCB_TYPE_MASK	= 0x0F,
123
	CD_CCB_RETRY_UA		= 0x10
131
	CD_CCB_RETRY_UA		= 0x10
124
} cd_ccb_state;
132
} cd_ccb_state;
Lines 138-144 struct cd_toc_single { Link Here
138
146
139
typedef enum {
147
typedef enum {
140
	CD_STATE_PROBE,
148
	CD_STATE_PROBE,
141
	CD_STATE_NORMAL
149
	CD_STATE_NORMAL,
150
	CD_STATE_MEDIA_PREVENT,
151
	CD_STATE_MEDIA_ALLOW,
152
	CD_STATE_MEDIA_SIZE,
153
	CD_STATE_MEDIA_TOC_HDR,
154
	CD_STATE_MEDIA_TOC_FULL,
155
	CD_STATE_MEDIA_TOC_LEAD
142
} cd_state;
156
} cd_state;
143
157
144
struct cd_softc {
158
struct cd_softc {
Lines 159-164 struct cd_softc { Link Here
159
	struct sysctl_oid	*sysctl_tree;
173
	struct sysctl_oid	*sysctl_tree;
160
	STAILQ_HEAD(, cd_mode_params)	mode_queue;
174
	STAILQ_HEAD(, cd_mode_params)	mode_queue;
161
	struct cd_tocdata	toc;
175
	struct cd_tocdata	toc;
176
	int			toc_read_len;
177
	struct cd_toc_single	leadout;
162
	struct disk		*disk;
178
	struct disk		*disk;
163
	struct callout		mediapoll_c;
179
	struct callout		mediapoll_c;
164
180
Lines 233-239 static void cddone(struct cam_periph *periph, Link Here
233
static	union cd_pages	*cdgetpage(struct cd_mode_params *mode_params);
249
static	union cd_pages	*cdgetpage(struct cd_mode_params *mode_params);
234
static	int		cdgetpagesize(int page_num);
250
static	int		cdgetpagesize(int page_num);
235
static	void		cdprevent(struct cam_periph *periph, int action);
251
static	void		cdprevent(struct cam_periph *periph, int action);
236
static	int		cdcheckmedia(struct cam_periph *periph);
252
static	void		cdmediaprobedone(struct cam_periph *periph);
253
static	int		cdcheckmedia(struct cam_periph *periph, int do_wait);
237
static	int		cdsize(struct cam_periph *periph, u_int32_t *size);
254
static	int		cdsize(struct cam_periph *periph, u_int32_t *size);
238
static	int		cd6byteworkaround(union ccb *ccb);
255
static	int		cd6byteworkaround(union ccb *ccb);
239
static	int		cderror(union ccb *ccb, u_int32_t cam_flags,
256
static	int		cderror(union ccb *ccb, u_int32_t cam_flags,
Lines 742-748 cdopen(struct disk *dp) Link Here
742
	 * if we don't have media, but then we don't allow anything but the
759
	 * if we don't have media, but then we don't allow anything but the
743
	 * CDIOCEJECT/CDIOCCLOSE ioctls if there is no media.
760
	 * CDIOCEJECT/CDIOCCLOSE ioctls if there is no media.
744
	 */
761
	 */
745
	cdcheckmedia(periph);
762
	cdcheckmedia(periph, /*do_wait*/ 1);
746
763
747
	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("leaving cdopen\n"));
764
	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("leaving cdopen\n"));
748
	cam_periph_unhold(periph);
765
	cam_periph_unhold(periph);
Lines 838-864 cdstrategy(struct bio *bp) Link Here
838
		return;
855
		return;
839
	}
856
	}
840
857
841
        /*
842
	 * If we don't have valid media, look for it before trying to
843
	 * schedule the I/O.
844
	 */
845
	if ((softc->flags & CD_FLAG_VALID_MEDIA) == 0) {
846
		int error;
847
848
		error = cdcheckmedia(periph);
849
		if (error != 0) {
850
			cam_periph_unlock(periph);
851
			biofinish(bp, NULL, error);
852
			return;
853
		}
854
	}
855
856
	/*
858
	/*
857
	 * Place it in the queue of disk activities for this disk
859
	 * Place it in the queue of disk activities for this disk
858
	 */
860
	 */
859
	bioq_disksort(&softc->bio_queue, bp);
861
	bioq_disksort(&softc->bio_queue, bp);
860
862
861
	xpt_schedule(periph, CAM_PRIORITY_NORMAL);
863
        /*
864
	 * If we don't know that we have valid media, schedule the media 
865
	 * check first.  The I/O will get executed after the media check.
866
	 */
867
	if ((softc->flags & CD_FLAG_VALID_MEDIA) == 0)
868
		cdcheckmedia(periph, /*do_wait*/ 0);
869
	else
870
		xpt_schedule(periph, CAM_PRIORITY_NORMAL);
862
871
863
	cam_periph_unlock(periph);
872
	cam_periph_unlock(periph);
864
	return;
873
	return;
Lines 870-876 cdstart(struct cam_periph *periph, union ccb *star Link Here
870
	struct cd_softc *softc;
879
	struct cd_softc *softc;
871
	struct bio *bp;
880
	struct bio *bp;
872
	struct ccb_scsiio *csio;
881
	struct ccb_scsiio *csio;
873
	struct scsi_read_capacity_data *rcap;
874
882
875
	softc = (struct cd_softc *)periph->softc;
883
	softc = (struct cd_softc *)periph->softc;
876
884
Lines 951-966 cdstart(struct cam_periph *periph, union ccb *star Link Here
951
		break;
959
		break;
952
	}
960
	}
953
	case CD_STATE_PROBE:
961
	case CD_STATE_PROBE:
962
	case CD_STATE_MEDIA_SIZE:
954
	{
963
	{
964
		struct scsi_read_capacity_data *rcap;
955
965
956
		rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcap),
966
		rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcap),
957
		    M_SCSICD, M_NOWAIT | M_ZERO);
967
		    M_SCSICD, M_NOWAIT | M_ZERO);
958
		if (rcap == NULL) {
968
		if (rcap == NULL) {
959
			xpt_print(periph->path,
969
			xpt_print(periph->path,
960
			    "cdstart: Couldn't malloc read_capacity data\n");
970
			    "%s: Couldn't malloc read_capacity data\n",
961
			/* cd_free_periph??? */
971
			    __func__);
972
			xpt_release_ccb(start_ccb);
973
			/*
974
			 * We can't probe because we can't allocate memory,
975
			 * so invalidate the peripheral.  The system probably
976
			 * has larger problems at this stage.  If we've
977
			 * already probed (and are re-probing capacity), we
978
			 * don't need to invalidate.
979
			 *
980
			 * XXX KDM need to reset probe state and kick out
981
			 * pending I/O.
982
			 */
983
			if (softc->state == CD_STATE_PROBE)
984
				cam_periph_invalidate(periph);
962
			break;
985
			break;
963
		}
986
		}
987
988
		/*
989
		 * Set the default capacity and sector size to something that
990
		 * GEOM can handle.  This will get reset when a read capacity
991
		 * completes successfully.
992
		 */
993
		softc->disk->d_sectorsize = 2048;
994
		softc->disk->d_mediasize = 0;
995
964
		csio = &start_ccb->csio;
996
		csio = &start_ccb->csio;
965
		scsi_read_capacity(csio,
997
		scsi_read_capacity(csio,
966
				   /*retries*/ cd_retry_count,
998
				   /*retries*/ cd_retry_count,
Lines 970-980 cdstart(struct cam_periph *periph, union ccb *star Link Here
970
				   SSD_FULL_SIZE,
1002
				   SSD_FULL_SIZE,
971
				   /*timeout*/20000);
1003
				   /*timeout*/20000);
972
		start_ccb->ccb_h.ccb_bp = NULL;
1004
		start_ccb->ccb_h.ccb_bp = NULL;
973
		start_ccb->ccb_h.ccb_state = CD_CCB_PROBE;
1005
		if (softc->state == CD_STATE_PROBE)
1006
			start_ccb->ccb_h.ccb_state = CD_CCB_PROBE;
1007
		else
1008
			start_ccb->ccb_h.ccb_state = CD_CCB_MEDIA_SIZE;
974
		xpt_action(start_ccb);
1009
		xpt_action(start_ccb);
975
		break;
1010
		break;
976
	}
1011
	}
1012
	case CD_STATE_MEDIA_ALLOW:
1013
	case CD_STATE_MEDIA_PREVENT:
1014
	{
1015
		/*
1016
		 * If the CD is already locked, we don't need to do this.
1017
		 * Move on to the capacity check.
1018
		 */
1019
		if ((softc->flags & CD_FLAG_DISC_LOCKED) != 0) {
1020
			softc->state = CD_STATE_MEDIA_SIZE;
1021
			xpt_release_ccb(start_ccb);
1022
			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1023
			break;
1024
		}
1025
1026
		scsi_prevent(&start_ccb->csio, 
1027
			     /*retries*/ cd_retry_count,
1028
			     /*cbfcnp*/ cddone,
1029
			     /*tag_action*/ MSG_SIMPLE_Q_TAG,
1030
			     /*action*/ (softc->state == CD_STATE_MEDIA_ALLOW) ?
1031
					PR_ALLOW : PR_PREVENT,
1032
			     /*sense_len*/ SSD_FULL_SIZE,
1033
			     /*timeout*/ 60000);
1034
1035
		start_ccb->ccb_h.ccb_bp = NULL;
1036
		if (softc->state == CD_STATE_MEDIA_ALLOW)
1037
			start_ccb->ccb_h.ccb_state = CD_CCB_MEDIA_ALLOW;
1038
		else
1039
			start_ccb->ccb_h.ccb_state = CD_CCB_MEDIA_PREVENT;
1040
		xpt_action(start_ccb);
1041
		break;
977
	}
1042
	}
1043
	case CD_STATE_MEDIA_TOC_HDR: {
1044
		struct ioc_toc_header *toch;
1045
		
1046
		bzero(&softc->toc, sizeof(softc->toc));
1047
1048
		toch = &softc->toc.header;
1049
1050
		scsi_read_toc(&start_ccb->csio,
1051
			      /*retries*/ cd_retry_count,
1052
			      /*cbfcnp*/ cddone,
1053
			      /*tag_action*/ MSG_SIMPLE_Q_TAG,
1054
			      /*byte1_flags*/ 0,
1055
			      /*format*/ SRTOC_FORMAT_TOC,
1056
			      /*track*/ 0,
1057
			      /*data_ptr*/ (uint8_t *)toch, 
1058
			      /*dxfer_len*/ sizeof(*toch),
1059
			      /*sense_len*/ SSD_FULL_SIZE,
1060
			      /*timeout*/ 50000);
1061
		start_ccb->ccb_h.ccb_bp = NULL;
1062
		start_ccb->ccb_h.ccb_state = CD_CCB_MEDIA_TOC_HDR;
1063
		xpt_action(start_ccb);
1064
		break;
1065
	}
1066
	case CD_STATE_MEDIA_TOC_FULL: {
1067
1068
		bzero(&softc->toc, sizeof(softc->toc));
1069
1070
		scsi_read_toc(&start_ccb->csio,
1071
			      /*retries*/ cd_retry_count,
1072
			      /*cbfcnp*/ cddone,
1073
			      /*tag_action*/ MSG_SIMPLE_Q_TAG,
1074
			      /*byte1_flags*/ 0,
1075
			      /*format*/ SRTOC_FORMAT_TOC,
1076
			      /*track*/ 0,
1077
			      /*data_ptr*/ (uint8_t *)&softc->toc,
1078
			      /*dxfer_len*/ softc->toc_read_len ?
1079
					    softc->toc_read_len :
1080
					    sizeof(softc->toc),
1081
			      /*sense_len*/ SSD_FULL_SIZE,
1082
			      /*timeout*/ 50000);
1083
		start_ccb->ccb_h.ccb_bp = NULL;
1084
		start_ccb->ccb_h.ccb_state = CD_CCB_MEDIA_TOC_FULL;
1085
		xpt_action(start_ccb);
1086
		break;
1087
	}
1088
	case CD_STATE_MEDIA_TOC_LEAD: {
1089
		struct cd_toc_single *leadout;
1090
1091
		leadout = &softc->leadout;
1092
		bzero(leadout, sizeof(*leadout));
1093
1094
		scsi_read_toc(&start_ccb->csio,
1095
			      /*retries*/ cd_retry_count,
1096
			      /*cbfcnp*/ cddone,
1097
			      /*tag_action*/ MSG_SIMPLE_Q_TAG,
1098
			      /*byte1_flags*/ CD_MSF,
1099
			      /*format*/ SRTOC_FORMAT_TOC,
1100
			      /*track*/ LEADOUT,
1101
			      /*data_ptr*/ (uint8_t *)leadout, 
1102
			      /*dxfer_len*/ sizeof(*leadout),
1103
			      /*sense_len*/ SSD_FULL_SIZE,
1104
			      /*timeout*/ 50000);
1105
		start_ccb->ccb_h.ccb_bp = NULL;
1106
		start_ccb->ccb_h.ccb_state = CD_CCB_MEDIA_TOC_LEAD;
1107
		xpt_action(start_ccb);
1108
		break;
1109
	}
1110
	}
978
}
1111
}
979
1112
980
static void
1113
static void
Lines 1238-1243 cddone(struct cam_periph *periph, union ccb *done_ Link Here
1238
		cam_periph_release_locked(periph);
1371
		cam_periph_release_locked(periph);
1239
		return;
1372
		return;
1240
	}
1373
	}
1374
	case CD_CCB_MEDIA_ALLOW: 
1375
	case CD_CCB_MEDIA_PREVENT:
1376
	{
1377
		int error;
1378
		int is_prevent;
1379
1380
		error = 0;
1381
1382
		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1383
			error = cderror(done_ccb, CAM_RETRY_SELTO,
1384
			    SF_RETRY_UA | SF_NO_PRINT);
1385
		}
1386
		if (error == ERESTART)
1387
			return;
1388
		if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1389
			cam_release_devq(done_ccb->ccb_h.path,
1390
					 /*relsim_flags*/0,
1391
					 /*reduction*/0,
1392
					 /*timeout*/0,
1393
					 /*getcount_only*/0);
1394
1395
		/*
1396
		 * Note that just like the original cdcheckmedia(), we do
1397
		 * a prevent without failing the whole operation if the
1398
		 * prevent fails.  We try, but keep going if it doesn't
1399
		 * work.
1400
		 */
1401
1402
		if ((done_ccb->ccb_h.ccb_state & CD_CCB_TYPE_MASK) ==
1403
		     CD_CCB_MEDIA_PREVENT)
1404
			is_prevent = 1;
1405
		else
1406
			is_prevent = 0;
1407
1408
		xpt_release_ccb(done_ccb);
1409
1410
		if (is_prevent != 0) {
1411
			if (error == 0)
1412
				softc->flags |= CD_FLAG_DISC_LOCKED;
1413
			else
1414
				softc->flags &= ~CD_FLAG_DISC_LOCKED;
1415
			softc->state = CD_STATE_MEDIA_SIZE;
1416
			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1417
		} else {
1418
			if (error == 0)
1419
				softc->flags &= ~CD_FLAG_DISC_LOCKED;
1420
			softc->state = CD_STATE_NORMAL;
1421
			if (bioq_first(&softc->bio_queue) != NULL)
1422
				xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1423
		}
1424
		return;
1425
	}
1426
	case CD_CCB_MEDIA_SIZE:
1427
	{
1428
		struct scsi_read_capacity_data *rdcap;
1429
		int error;
1430
1431
		error = 0;
1432
		if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1433
			error = cderror(done_ccb, CAM_RETRY_SELTO,
1434
			    SF_RETRY_UA | SF_NO_PRINT);
1435
		}
1436
		if (error == ERESTART)
1437
			return;
1438
		if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1439
			cam_release_devq(done_ccb->ccb_h.path,
1440
					 /*relsim_flags*/0,
1441
					 /*reduction*/0,
1442
					 /*timeout*/0,
1443
					 /*getcount_only*/0);
1444
		rdcap = (struct scsi_read_capacity_data *)csio->data_ptr;
1445
1446
		if (error == 0) {
1447
			softc->params.disksize =scsi_4btoul(rdcap->addr) + 1;
1448
			softc->params.blksize  = scsi_4btoul(rdcap->length);
1449
1450
			/* Make sure we got at least some block size. */
1451
			if (softc->params.blksize == 0)
1452
				error = EIO;
1453
			/*
1454
			 * SCSI-3 mandates that the reported blocksize shall be
1455
			 * 2048.  Older drives sometimes report funny values,
1456
			 * trim it down to 2048, or other parts of the kernel
1457
			 * will get confused.
1458
			 *
1459
			 * XXX we leave drives alone that might report 512
1460
			 * bytes, as well as drives reporting more weird
1461
			 * sizes like perhaps 4K.
1462
			 */
1463
			if (softc->params.blksize > 2048
1464
			 && softc->params.blksize <= 2352)
1465
				softc->params.blksize = 2048;
1466
		}
1467
		free(rdcap, M_SCSICD);
1468
1469
		if (error == 0) {
1470
			softc->disk->d_sectorsize = softc->params.blksize;
1471
			softc->disk->d_mediasize =
1472
			    (off_t)softc->params.blksize *
1473
			    softc->params.disksize;
1474
			softc->flags |= CD_FLAG_SAW_MEDIA | CD_FLAG_VALID_MEDIA;
1475
			softc->state = CD_STATE_MEDIA_TOC_HDR;
1476
		} else {
1477
			softc->flags &= ~(CD_FLAG_VALID_MEDIA |
1478
					  CD_FLAG_VALID_TOC);
1479
			bioq_flush(&softc->bio_queue, NULL, EINVAL);
1480
			softc->state = CD_STATE_MEDIA_ALLOW;
1481
			cdmediaprobedone(periph);
1482
		}
1483
		xpt_release_ccb(done_ccb);
1484
		xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1485
		return;
1486
	}
1487
	case CD_CCB_MEDIA_TOC_HDR:
1488
	case CD_CCB_MEDIA_TOC_FULL:
1489
	case CD_CCB_MEDIA_TOC_LEAD:
1490
	{
1491
		int error;
1492
		struct ioc_toc_header *toch;
1493
		int num_entries;
1494
		int cdindex;
1495
1496
		error = 0;
1497
1498
		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1499
			error = cderror(done_ccb, CAM_RETRY_SELTO,
1500
			    SF_RETRY_UA | SF_NO_PRINT);
1501
		}
1502
		if (error == ERESTART)
1503
			return;
1504
1505
		if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1506
			cam_release_devq(done_ccb->ccb_h.path,
1507
					 /*relsim_flags*/0,
1508
					 /*reduction*/0,
1509
					 /*timeout*/0,
1510
					 /*getcount_only*/0);
1511
1512
		/*
1513
		 * We will get errors here for media that doesn't have a table
1514
		 * of contents.  According to the MMC-3 spec: "When a Read 
1515
		 * TOC/PMA/ATIP command is presented for a DDCD/CD-R/RW media,
1516
		 * where the first TOC has not been recorded (no complete
1517
		 * session) and the Format codes 0000b, 0001b, or 0010b are
1518
		 * specified, this command shall be rejected with an INVALID 
1519
		 * FIELD IN CDB.  Devices that are not capable of reading an 
1520
		 * incomplete session on DDC/CD-R/RW media shall report
1521
		 * CANNOT READ MEDIUM - INCOMPATIBLE FORMAT."
1522
		 *
1523
		 * So this isn't fatal if we can't read the table of contents,
1524
		 * it just means that the user won't be able to issue the
1525
		 * play tracks ioctl, and likely lots of other stuff won't
1526
		 * work either.  They need to burn the CD before we can do
1527
		 * a whole lot with it.  So we don't print anything here if
1528
		 * we get an error back.
1529
		 *
1530
		 * We also bail out if the drive doesn't at least give us
1531
		 * the full TOC header.
1532
		 */
1533
		if ((error != 0)
1534
		 || ((csio->dxfer_len - csio->resid) <
1535
		      sizeof(struct ioc_toc_header))) {
1536
			softc->flags &= ~CD_FLAG_VALID_TOC;
1537
			bzero(&softc->toc, sizeof(softc->toc));
1538
			/*
1539
			 * Failing the TOC read is not an error.
1540
			 */
1541
			softc->state = CD_STATE_NORMAL;
1542
			xpt_release_ccb(done_ccb);
1543
1544
			cdmediaprobedone(periph);
1545
1546
			/*
1547
			 * Go ahead and schedule I/O execution if there is
1548
			 * anything in the queue.  It'll probably get
1549
			 * kicked out with an error.
1550
			 */
1551
			if (bioq_first(&softc->bio_queue) != NULL)
1552
				xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1553
			return;
1554
		}
1555
1556
		/*
1557
		 * Note that this is NOT the storage location used for the
1558
		 * leadout!
1559
		 */
1560
		toch = &softc->toc.header;
1561
1562
		if (softc->quirks & CD_Q_BCD_TRACKS) {
1563
			toch->starting_track = bcd2bin(toch->starting_track);
1564
			toch->ending_track = bcd2bin(toch->ending_track);
1565
		}
1566
1567
		/* Number of TOC entries, plus leadout */
1568
		num_entries = (toch->ending_track - toch->starting_track) + 2;
1569
		cdindex = toch->starting_track + num_entries -1;
1570
1571
		if ((done_ccb->ccb_h.ccb_state & CD_CCB_TYPE_MASK) ==
1572
		     CD_CCB_MEDIA_TOC_HDR) {
1573
			if (num_entries <= 0) {
1574
				softc->flags &= ~CD_FLAG_VALID_TOC;
1575
				bzero(&softc->toc, sizeof(softc->toc));
1576
				/*
1577
				 * Failing the TOC read is not an error.
1578
				 */
1579
				softc->state = CD_STATE_NORMAL;
1580
				xpt_release_ccb(done_ccb);
1581
1582
				cdmediaprobedone(periph);
1583
1584
				/*
1585
				 * Go ahead and schedule I/O execution if
1586
				 * there is anything in the queue.  It'll
1587
				 * probably get kicked out with an error.
1588
				 */
1589
				if (bioq_first(&softc->bio_queue) != NULL)
1590
					xpt_schedule(periph,
1591
					    CAM_PRIORITY_NORMAL);
1592
			} else {
1593
				softc->toc_read_len = num_entries *
1594
				    sizeof(struct cd_toc_entry);
1595
				softc->toc_read_len += sizeof(*toch);
1596
1597
				softc->state = CD_STATE_MEDIA_TOC_FULL;
1598
				xpt_release_ccb(done_ccb);
1599
				xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1600
			}
1601
1602
			return;
1603
		} else if ((done_ccb->ccb_h.ccb_state & CD_CCB_TYPE_MASK) ==
1604
			    CD_CCB_MEDIA_TOC_LEAD) {
1605
			struct cd_toc_single *leadout;
1606
1607
			leadout = (struct cd_toc_single *)csio->data_ptr;
1608
			softc->toc.entries[cdindex - toch->starting_track] =
1609
			    leadout->entry;
1610
		} else if (((done_ccb->ccb_h.ccb_state & CD_CCB_TYPE_MASK) ==
1611
			    CD_CCB_MEDIA_TOC_FULL)
1612
			&& (cdindex == toch->ending_track + 1)) {
1613
			/*
1614
			 * XXX KDM is this necessary?  Probably only if the
1615
			 * drive doesn't return leadout information with the
1616
			 * table of contents.
1617
			 */
1618
			softc->state = CD_STATE_MEDIA_TOC_LEAD;
1619
			xpt_release_ccb(done_ccb);
1620
			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1621
			return;
1622
		}
1623
1624
		if (softc->quirks & CD_Q_BCD_TRACKS) {
1625
			for (cdindex = 0; cdindex < num_entries - 1; cdindex++){
1626
				softc->toc.entries[cdindex].track =
1627
				    bcd2bin(softc->toc.entries[cdindex].track);
1628
			}
1629
		}
1630
1631
		softc->flags |= CD_FLAG_VALID_TOC;
1632
		/* If the first track is audio, correct sector size. */
1633
		if ((softc->toc.entries[0].control & 4) == 0) {
1634
			softc->disk->d_sectorsize =softc->params.blksize = 2352;
1635
			softc->disk->d_mediasize =
1636
			    (off_t)softc->params.blksize *
1637
			    softc->params.disksize;
1638
		}
1639
		softc->state = CD_STATE_NORMAL;
1640
1641
		/*
1642
		 * We unconditionally (re)set the blocksize each time the
1643
		 * CD device is opened.  This is because the CD can change,
1644
		 * and therefore the blocksize might change.
1645
		 * XXX problems here if some slice or partition is still
1646
		 * open with the old size?
1647
		 */
1648
		if ((softc->disk->d_devstat->flags & DEVSTAT_BS_UNAVAILABLE)!=0)
1649
			softc->disk->d_devstat->flags &=
1650
			    ~DEVSTAT_BS_UNAVAILABLE;
1651
		softc->disk->d_devstat->block_size = softc->params.blksize;
1652
1653
		xpt_release_ccb(done_ccb);
1654
1655
		cdmediaprobedone(periph);
1656
1657
		if (bioq_first(&softc->bio_queue) != NULL)
1658
			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
1659
		return;
1660
	}
1241
	default:
1661
	default:
1242
		break;
1662
		break;
1243
	}
1663
	}
Lines 1307-1313 cdioctl(struct disk *dp, u_long cmd, void *addr, i Link Here
1307
	 && ((cmd != CDIOCCLOSE)
1727
	 && ((cmd != CDIOCCLOSE)
1308
	  && (cmd != CDIOCEJECT))
1728
	  && (cmd != CDIOCEJECT))
1309
	 && (IOCGROUP(cmd) == 'c')) {
1729
	 && (IOCGROUP(cmd) == 'c')) {
1310
		error = cdcheckmedia(periph);
1730
		error = cdcheckmedia(periph, /*do_wait*/ 1);
1311
		if (error != 0) {
1731
		if (error != 0) {
1312
			cam_periph_unhold(periph);
1732
			cam_periph_unhold(periph);
1313
			cam_periph_unlock(periph);
1733
			cam_periph_unlock(periph);
Lines 2197-2207 cdprevent(struct cam_periph *periph, int action) Link Here
2197
	}
2617
	}
2198
}
2618
}
2199
2619
2620
static void
2621
cdmediaprobedone(struct cam_periph *periph)
2622
{
2623
	struct cd_softc *softc;
2624
2625
	softc = (struct cd_softc *)periph->softc;
2626
2627
	softc->flags &= ~CD_FLAG_MEDIA_SCAN_ACT;
2628
2629
	if ((softc->flags & CD_FLAG_MEDIA_WAIT) != 0) {
2630
		softc->flags &= ~CD_FLAG_MEDIA_WAIT;
2631
		wakeup(&softc->toc);
2632
	}
2633
}
2634
2200
/*
2635
/*
2201
 * XXX: the disk media and sector size is only really able to change
2636
 * XXX: the disk media and sector size is only really able to change
2202
 * XXX: while the device is closed.
2637
 * XXX: while the device is closed.
2203
 */
2638
 */
2639
2204
static int
2640
static int
2641
cdcheckmedia(struct cam_periph *periph, int do_wait)
2642
{
2643
	struct cd_softc *softc;
2644
	int error;
2645
2646
	softc = (struct cd_softc *)periph->softc;
2647
	error = 0;
2648
2649
	if ((do_wait != 0)
2650
	 && ((softc->flags & CD_FLAG_MEDIA_WAIT) == 0)) {
2651
		softc->flags |= CD_FLAG_MEDIA_WAIT;
2652
	}
2653
	if ((softc->flags & CD_FLAG_MEDIA_SCAN_ACT) == 0) {
2654
		softc->state = CD_STATE_MEDIA_PREVENT;
2655
		softc->flags |= CD_FLAG_MEDIA_SCAN_ACT;
2656
		xpt_schedule(periph, CAM_PRIORITY_NORMAL);
2657
	}
2658
2659
	if (do_wait == 0)
2660
		goto bailout;
2661
2662
	error = msleep(&softc->toc, cam_periph_mtx(periph), PRIBIO,"cdmedia",0);
2663
	
2664
	if (error != 0)
2665
		goto bailout;
2666
2667
	/*
2668
	 * Check to see whether we have a valid size from the media.  We
2669
	 * may or may not have a valid TOC.
2670
	 */
2671
	if ((softc->flags & CD_FLAG_VALID_MEDIA) == 0)
2672
		error = EINVAL;
2673
bailout:
2674
2675
	return (error);
2676
}
2677
2678
#if 0
2679
static int
2205
cdcheckmedia(struct cam_periph *periph)
2680
cdcheckmedia(struct cam_periph *periph)
2206
{
2681
{
2207
	struct cd_softc *softc;
2682
	struct cd_softc *softc;
Lines 2341-2346 bailout: Link Here
2341
2816
2342
	return (error);
2817
	return (error);
2343
}
2818
}
2819
#endif
2344
2820
2345
static int
2821
static int
2346
cdsize(struct cam_periph *periph, u_int32_t *size)
2822
cdsize(struct cam_periph *periph, u_int32_t *size)
Lines 2620-2626 static int Link Here
2620
cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start, 
3096
cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start, 
2621
	  u_int8_t *data, u_int32_t len, u_int32_t sense_flags)
3097
	  u_int8_t *data, u_int32_t len, u_int32_t sense_flags)
2622
{
3098
{
2623
	struct scsi_read_toc *scsi_cmd;
2624
	u_int32_t ntoc;
3099
	u_int32_t ntoc;
2625
        struct ccb_scsiio *csio;
3100
        struct ccb_scsiio *csio;
2626
	union ccb *ccb;
3101
	union ccb *ccb;
Lines 2633-2661 cdreadtoc(struct cam_periph *periph, u_int32_t mod Link Here
2633
3108
2634
	csio = &ccb->csio;
3109
	csio = &ccb->csio;
2635
3110
2636
	cam_fill_csio(csio, 
3111
	scsi_read_toc(csio,
2637
		      /* retries */ cd_retry_count, 
3112
		      /* retries */ cd_retry_count, 
2638
		      /* cbfcnp */ NULL,
3113
		      /* cbfcnp */ NULL,
2639
		      /* flags */ CAM_DIR_IN,
2640
		      /* tag_action */ MSG_SIMPLE_Q_TAG,
3114
		      /* tag_action */ MSG_SIMPLE_Q_TAG,
3115
		      /* byte1_flags */ (mode == CD_MSF_FORMAT) ? CD_MSF : 0,
3116
		      /* format */ SRTOC_FORMAT_TOC,
3117
		      /* track*/ start,
2641
		      /* data_ptr */ data,
3118
		      /* data_ptr */ data,
2642
		      /* dxfer_len */ len,
3119
		      /* dxfer_len */ len,
2643
		      /* sense_len */ SSD_FULL_SIZE,
3120
		      /* sense_len */ SSD_FULL_SIZE,
2644
		      sizeof(struct scsi_read_toc),
3121
		      /* timeout */ 50000);
2645
 		      /* timeout */ 50000);
2646
3122
2647
	scsi_cmd = (struct scsi_read_toc *)&csio->cdb_io.cdb_bytes;
2648
	bzero (scsi_cmd, sizeof(*scsi_cmd));
2649
2650
	if (mode == CD_MSF_FORMAT)
2651
		scsi_cmd->byte2 |= CD_MSF;
2652
	scsi_cmd->from_track = start;
2653
	/* scsi_ulto2b(ntoc, (u_int8_t *)scsi_cmd->data_len); */
2654
	scsi_cmd->data_len[0] = (ntoc) >> 8;
2655
	scsi_cmd->data_len[1] = (ntoc) & 0xff;
2656
2657
	scsi_cmd->op_code = READ_TOC;
2658
2659
	error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO,
3123
	error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO,
2660
			 /*sense_flags*/SF_RETRY_UA | sense_flags);
3124
			 /*sense_flags*/SF_RETRY_UA | sense_flags);
2661
3125
Lines 3713-3715 scsi_read_dvd_structure(struct ccb_scsiio *csio, u Link Here
3713
		      sizeof(*scsi_cmd),
4177
		      sizeof(*scsi_cmd),
3714
		      timeout);
4178
		      timeout);
3715
}
4179
}
4180
4181
void
4182
scsi_read_toc(struct ccb_scsiio *csio, uint32_t retries,
4183
	      void (*cbfcnp)(struct cam_periph *, union ccb *),
4184
	      uint8_t tag_action, uint8_t byte1_flags, uint8_t format,
4185
	      uint8_t track, uint8_t *data_ptr, uint32_t dxfer_len,
4186
	      int sense_len, int timeout)
4187
{
4188
	struct scsi_read_toc *scsi_cmd;
4189
4190
	scsi_cmd = (struct scsi_read_toc *)&csio->cdb_io.cdb_bytes;
4191
	bzero(scsi_cmd, sizeof(*scsi_cmd));
4192
	scsi_cmd->op_code = READ_TOC;
4193
4194
	/*
4195
	 * The structure is counting from 1, the function counting from 0.
4196
	 * The spec counts from 0.  In MMC-6, there is only one flag, the
4197
	 * MSF flag.  But we put the whole byte in for a bit a future-proofing.
4198
	 */
4199
	scsi_cmd->byte2 = byte1_flags;
4200
	scsi_cmd->format = format;
4201
	scsi_cmd->from_track = track;
4202
	scsi_ulto2b(dxfer_len, scsi_cmd->data_len);
4203
4204
	cam_fill_csio(csio, 
4205
		      /* retries */ retries, 
4206
		      /* cbfcnp */ cbfcnp,
4207
		      /* flags */ CAM_DIR_IN,
4208
		      /* tag_action */ tag_action,
4209
		      /* data_ptr */ data_ptr,
4210
		      /* dxfer_len */ dxfer_len,
4211
		      /* sense_len */ sense_len,
4212
		      sizeof(*scsi_cmd),
4213
 		      /* timeout */ timeout);
4214
}
(-)scsi_cd.h (+12 lines)
Lines 231-236 struct scsi_read_toc Link Here
231
	u_int8_t op_code;
231
	u_int8_t op_code;
232
	u_int8_t byte2;
232
	u_int8_t byte2;
233
	u_int8_t format;
233
	u_int8_t format;
234
#define	SRTOC_FORMAT_TOC	0x00
235
#define	SRTOC_FORMAT_LAST_ADDR	0x01
236
#define	SRTOC_FORMAT_QSUB_TOC	0x02
237
#define	SRTOC_FORMAT_QSUB_PMA	0x03
238
#define	SRTOC_FORMAT_ATIP	0x04
239
#define	SRTOC_FORMAT_CD_TEXT	0x05
234
	u_int8_t unused[3];
240
	u_int8_t unused[3];
235
	u_int8_t from_track;
241
	u_int8_t from_track;
236
	u_int8_t data_len[2];
242
	u_int8_t data_len[2];
Lines 871-876 void scsi_read_dvd_structure(struct ccb_scsiio *cs Link Here
871
			     u_int32_t dxfer_len, u_int8_t sense_len,
877
			     u_int32_t dxfer_len, u_int8_t sense_len,
872
			     u_int32_t timeout);
878
			     u_int32_t timeout);
873
879
880
void scsi_read_toc(struct ccb_scsiio *csio, uint32_t retries,
881
		   void (*cbfcnp)(struct cam_periph *, union ccb *),
882
		   uint8_t tag_action, uint8_t byte1_flags, uint8_t format,
883
		   uint8_t track, uint8_t *data_ptr, uint32_t dxfer_len,
884
		   int sense_len, int timeout);
885
874
__END_DECLS
886
__END_DECLS
875
887
876
#endif /*_SCSI_SCSI_CD_H*/
888
#endif /*_SCSI_SCSI_CD_H*/

Return to bug 219857