PERFORCE change 169823 for review

Alexander Motin mav at FreeBSD.org
Mon Oct 26 11:53:15 UTC 2009


http://p4web.freebsd.org/chv.cgi?CH=169823

Change 169823 by mav at mav_mavtest on 2009/10/26 11:52:22

	Move setting length of PIO transaction from ada driver to ATA XPT,
	ada driver is now stateless.
	
	Make aprobe driver to always set mode and max sectors on device.
	It is required after device reset.
	
	Make XPT to report length of PIO transaction to SIM. It is required
	for correct PIO modes operation.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_da.c#34 edit
.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#44 edit
.. //depot/projects/scottl-camlock/src/sys/cam/cam_ccb.h#28 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.c#31 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.h#20 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_da.c#34 (text+ko) ====

@@ -63,8 +63,7 @@
 #define ATA_MAX_28BIT_LBA               268435455UL
 
 typedef enum {
-	ADA_STATE_NORMAL,
-	ADA_STATE_SET_MULTI
+	ADA_STATE_NORMAL
 } ada_state;
 
 typedef enum {
@@ -84,7 +83,6 @@
 } ada_quirks;
 
 typedef enum {
-	ADA_CCB_SET_MULTI	= 0x01,
 	ADA_CCB_BUFFER_IO	= 0x03,
 	ADA_CCB_WAITING		= 0x04,
 	ADA_CCB_DUMP		= 0x05,
@@ -112,7 +110,6 @@
 	ada_quirks quirks;
 	int	 ordered_tag_count;
 	int	 outstanding_cmds;
-	int	 secsperint;
 	struct	 disk_params params;
 	struct	 disk *disk;
 	union	 ccb saved_ccb;
@@ -551,22 +548,6 @@
 				"due to status 0x%x\n", status);
 		break;
 	}
-	case AC_SENT_BDR:
-	case AC_BUS_RESET:
-	{
-		struct ada_softc *softc = (struct ada_softc *)periph->softc;
-
-		cam_periph_async(periph, code, path, arg);
-		if (softc->state != ADA_STATE_NORMAL)
-			break;
-		/*
-		 * Restore device configuration.
-		 */
-		softc->state = ADA_STATE_SET_MULTI;
-		cam_periph_acquire(periph);
-		xpt_schedule(periph, CAM_PRIORITY_DEV);
-		break;
-	}
 	default:
 		cam_periph_async(periph, code, path, arg);
 		break;
@@ -645,8 +626,7 @@
 	if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
 	    cgd->ident_data.queue >= 31)
 		softc->flags |= ADA_FLAG_CAN_NCQ;
-	softc->secsperint = max(1, min(cgd->ident_data.sectors_intr & 0xff, 16));
-	softc->state = ADA_STATE_SET_MULTI;
+	softc->state = ADA_STATE_NORMAL;
 
 	periph->softc = softc;
 
@@ -735,18 +715,10 @@
 	 * them and the only alternative would be to
 	 * not attach the device on failure.
 	 */
-	xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE,
+	xpt_register_async(AC_LOST_DEVICE,
 			   adaasync, periph, periph->path);
 
 	/*
-	 * Take an exclusive refcount on the periph while adastart is called
-	 * to finish the probe.  The reference will be dropped in adadone at
-	 * the end of probe.
-	 */
-	cam_periph_acquire(periph);
-	xpt_schedule(periph, CAM_PRIORITY_DEV);
-
-	/*
 	 * Schedule a periodic event to occasionally send an
 	 * ordered tag to a device.
 	 */
@@ -902,21 +874,6 @@
 		}
 		break;
 	}
-	case ADA_STATE_SET_MULTI:
-	{
-		cam_fill_ataio(ataio,
-		    ada_retry_count,
-		    adadone,
-		    CAM_DIR_NONE,
-		    0,
-		    NULL,
-		    0,
-		    ada_default_timeout*1000);
-
-		ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, softc->secsperint);
-		start_ccb->ccb_h.ccb_state = ADA_CCB_SET_MULTI;
-		xpt_action(start_ccb);
-	}
 	}
 }
 
@@ -1004,41 +961,6 @@
 		wakeup(&done_ccb->ccb_h.cbfcnp);
 		return;
 	}
-	case ADA_CCB_SET_MULTI:
-	{
-		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-		} else {
-			int	error;
-
-			error = adaerror(done_ccb, 0, 0);
-			if (error == ERESTART) {
-				/* A retry was scheduled, so just return. */
-				return;
-			}
-			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
-				cam_release_devq(done_ccb->ccb_h.path,
-						 /*relsim_flags*/0,
-						 /*reduction*/0,
-						 /*timeout*/0,
-						 /*getcount_only*/0);
-		}
-		softc->state = ADA_STATE_NORMAL;
-		/*
-		 * Since our peripheral may be invalidated by an error
-		 * above or an external event, we must release our CCB
-		 * before releasing the probe lock on the peripheral.
-		 * The peripheral will only go away once the last lock
-		 * is removed, and we need it around for the CCB release
-		 * operation.
-		 */
-		xpt_release_ccb(done_ccb);
-		if (bioq_first(&softc->bio_queue) != NULL) {
-			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
-		}
-		cam_periph_release_locked(periph);
-		return;
-	}
 	case ADA_CCB_DUMP:
 		/* No-op.  We're polling */
 		return;

==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#44 (text+ko) ====

@@ -92,6 +92,7 @@
 	PROBE_RESET,
 	PROBE_IDENTIFY,
 	PROBE_SETMODE,
+	PROBE_SET_MULTI,
 	PROBE_INQUIRY,
 	PROBE_FULL_INQUIRY,
 	PROBE_PM_PID,
@@ -103,6 +104,7 @@
 	"PROBE_RESET",
 	"PROBE_IDENTIFY",
 	"PROBE_SETMODE",
+	"PROBE_SET_MULTI",
 	"PROBE_INQUIRY",
 	"PROBE_FULL_INQUIRY",
 	"PROBE_PM_PID",
@@ -284,12 +286,16 @@
 	struct ccb_ataio *ataio;
 	struct ccb_scsiio *csio;
 	probe_softc *softc;
+	struct cam_path *path;
+	struct ata_params *ident_buf;
 
 	CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
 
 	softc = (probe_softc *)periph->softc;
+	path = start_ccb->ccb_h.path;
 	ataio = &start_ccb->ataio;
 	csio = &start_ccb->csio;
+	ident_buf = &periph->path->device->ident_data;
 
 	switch (softc->action) {
 	case PROBE_RESET:
@@ -304,10 +310,6 @@
 		ata_reset_cmd(ataio);
 		break;
 	case PROBE_IDENTIFY:
-	{
-		struct ata_params *ident_buf =
-		    &periph->path->device->ident_data;
-
 		if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
 			/* Prepare check that it is the same device. */
 			MD5_CTX context;
@@ -337,12 +339,7 @@
 		else
 			ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
 		break;
-	}
 	case PROBE_SETMODE:
-	{
-		struct ata_params *ident_buf =
-		    &periph->path->device->ident_data;
-
 		cam_fill_ataio(ataio,
 		      1,
 		      probedone,
@@ -354,6 +351,37 @@
 		ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
 		    ata_max_mode(ident_buf, ATA_UDMA6, ATA_UDMA6));
 		break;
+	case PROBE_SET_MULTI:
+	{
+		struct ccb_trans_settings cts;
+		u_int sectors;
+
+		sectors = max(1, min(ident_buf->sectors_intr & 0xff, 16));
+
+		/* Report bytecount to SIM. */
+		bzero(&cts, sizeof(cts));
+		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
+		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+		cts.type = CTS_TYPE_CURRENT_SETTINGS;
+		if (path->device->transport == XPORT_ATA) {
+			cts.xport_specific.ata.bytecount = sectors * 512;
+			cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT;
+		} else {
+			cts.xport_specific.sata.bytecount = sectors * 512;
+			cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT;
+		}
+		xpt_action((union ccb *)&cts);
+
+		cam_fill_ataio(ataio,
+		    1,
+		    probedone,
+		    CAM_DIR_NONE,
+		    0,
+		    NULL,
+		    0,
+		    30*1000);
+		ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, sectors);
+		break;
 	}
 	case PROBE_INQUIRY:
 	case PROBE_FULL_INQUIRY:
@@ -408,7 +436,7 @@
 		ata_pm_read_cmd(ataio, 1, 15);
 		break;
 	case PROBE_INVALID:
-		CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
+		CAM_DEBUG(path, CAM_DEBUG_INFO,
 		    ("probestart: invalid action state\n"));
 	default:
 		break;
@@ -666,29 +694,28 @@
 				/* Device changed. */
 				xpt_async(AC_LOST_DEVICE, path, NULL);
 			}
-			break;
-		}
+		} else {
+			/* Clean up from previous instance of this device */
+			if (path->device->serial_num != NULL) {
+				free(path->device->serial_num, M_CAMXPT);
+				path->device->serial_num = NULL;
+				path->device->serial_num_len = 0;
+			}
+			path->device->serial_num =
+				(u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
+					   M_CAMXPT, M_NOWAIT);
+			if (path->device->serial_num != NULL) {
+				bcopy(ident_buf->serial,
+				      path->device->serial_num,
+				      sizeof(ident_buf->serial));
+				path->device->serial_num[sizeof(ident_buf->serial)]
+				    = '\0';
+				path->device->serial_num_len =
+				    strlen(path->device->serial_num);
+			}
 
-		/* Clean up from previous instance of this device */
-		if (path->device->serial_num != NULL) {
-			free(path->device->serial_num, M_CAMXPT);
-			path->device->serial_num = NULL;
-			path->device->serial_num_len = 0;
-		}
-		path->device->serial_num =
-			(u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
-					   M_CAMXPT, M_NOWAIT);
-		if (path->device->serial_num != NULL) {
-			bcopy(ident_buf->serial,
-			      path->device->serial_num,
-			      sizeof(ident_buf->serial));
-			path->device->serial_num[sizeof(ident_buf->serial)]
-			    = '\0';
-			path->device->serial_num_len =
-			    strlen(path->device->serial_num);
+			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
 		}
-
-		path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
 		ata_device_transport(path);
 		PROBE_SET_ACTION(softc, PROBE_SETMODE);
 		xpt_release_ccb(done_ccb);
@@ -696,21 +723,23 @@
 		return;
 	}
 	case PROBE_SETMODE:
-	{
 		if (path->device->protocol == PROTO_ATA) {
+			PROBE_SET_ACTION(softc, PROBE_SET_MULTI);
+		} else {
+			PROBE_SET_ACTION(softc, PROBE_INQUIRY);
+		}
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
+	case PROBE_SET_MULTI:
+		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
 			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
 			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 			xpt_action(done_ccb);
 			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
 			    done_ccb);
-		} else {
-			PROBE_SET_ACTION(softc, PROBE_INQUIRY);
-			xpt_release_ccb(done_ccb);
-			xpt_schedule(periph, priority);
-			return;
 		}
 		break;
-	}
 	case PROBE_INQUIRY:
 	case PROBE_FULL_INQUIRY:
 	{
@@ -747,10 +776,12 @@
 
 		scsi_find_quirk(path->device);
 		ata_device_transport(path);
-		path->device->flags &= ~CAM_DEV_UNCONFIGURED;
-		done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
-		xpt_action(done_ccb);
-		xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
+		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
+			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+			xpt_action(done_ccb);
+			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
+		}
 		break;
 	}
 	case PROBE_PM_PID:

==== //depot/projects/scottl-camlock/src/sys/cam/cam_ccb.h#28 (text+ko) ====

@@ -816,12 +816,22 @@
 	u_int32_t 	bitrate;	/* Mbps */
 };
 
+struct ccb_trans_settings_ata {
+	u_int     	valid;		/* Which fields to honor */
+#define	CTS_ATA_VALID_MODE		0x01
+#define	CTS_ATA_VALID_BYTECOUNT		0x04
+	u_int32_t 	mode;
+	u_int 		bytecount;	/* Length of PIO transaction */
+};
+
 struct ccb_trans_settings_sata {
 	u_int     	valid;		/* Which fields to honor */
 #define	CTS_SATA_VALID_SPEED		0x01
 #define	CTS_SATA_VALID_PM		0x02
+#define	CTS_SATA_VALID_BYTECOUNT	0x04
 	u_int32_t 	bitrate;	/* Mbps */
 	u_int 		pm_present;	/* PM is present (XPT->SIM) */
+	u_int 		bytecount;	/* Length of PIO transaction */
 };
 
 /* Get/Set transfer rate/width/disconnection/tag queueing settings */
@@ -841,6 +851,7 @@
 		struct ccb_trans_settings_spi spi;
 		struct ccb_trans_settings_fc fc;
 		struct ccb_trans_settings_sas sas;
+		struct ccb_trans_settings_ata ata;
 		struct ccb_trans_settings_sata sata;
 	} xport_specific;
 };

==== //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.c#31 (text+ko) ====

@@ -149,6 +149,10 @@
     mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF);
     TAILQ_INIT(&ch->ata_queue);
     TASK_INIT(&ch->conntask, 0, ata_conn_event, dev);
+#ifdef ATA_CAM
+    ch->bytecount[0] = 16 * 512;
+    ch->bytecount[1] = 16 * 512;
+#endif
 
     /* reset the controller HW, the channel and device(s) */
     while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit)
@@ -1275,7 +1279,8 @@
 		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
 			request->flags |= ATA_R_WRITE;
 	}
-	request->transfersize = min(request->bytecount, 16*512);
+	request->transfersize = min(request->bytecount,
+	    ch->bytecount[ccb->ccb_h.target_id]);
 //	request->callback = ad_done;
 	request->retries = 0;
 	request->timeout = (ccb->ccb_h.timeout + 999) / 1000;
@@ -1394,12 +1399,18 @@
 		break;
 	case XPT_SET_TRAN_SETTINGS:
 	{
+		struct	ccb_trans_settings *cts = &ccb->cts;
+
+		if (ccb->ccb_h.target_id >= 0 && ccb->ccb_h.target_id <= 1 &&
+		    (cts->xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)) {
+			ch->bytecount[ccb->ccb_h.target_id] =
+			    cts->xport_specific.ata.bytecount;
+		}
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 		break;
 	}
 	case XPT_GET_TRAN_SETTINGS:
-	/* Get default/user set transfer settings for the target */
 	{
 		struct	ccb_trans_settings *cts = &ccb->cts;
 
@@ -1407,8 +1418,11 @@
 		cts->protocol_version = PROTO_VERSION_UNSPECIFIED;
 		cts->transport = XPORT_ATA;
 		cts->transport_version = XPORT_VERSION_UNSPECIFIED;
-		cts->proto_specific.valid = 0;
-		cts->xport_specific.sata.valid = 0;
+		if (ccb->ccb_h.target_id >= 0 && ccb->ccb_h.target_id <= 1) {
+			cts->proto_specific.valid = CTS_ATA_VALID_BYTECOUNT;
+			cts->xport_specific.ata.bytecount = 
+			    ch->bytecount[ccb->ccb_h.target_id];
+		}
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 		break;

==== //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.h#20 (text+ko) ====

@@ -560,6 +560,7 @@
 #ifdef ATA_CAM
 	struct cam_sim		*sim;
 	struct cam_path		*path;
+	u_int			bytecount[2];	/* Length of PIO transaction */
 #endif
 };
 


More information about the p4-projects mailing list