PERFORCE change 164342 for review

Alexander Motin mav at FreeBSD.org
Sun Jun 14 14:30:54 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=164342

Change 164342 by mav at mav_mavbook on 2009/06/14 14:30:10

	Expose PM as device.
	Implement softer PM rescan, to not interrupt devices operation.

Affected files ...

.. //depot/projects/scottl-camlock/src/sbin/camcontrol/camcontrol.c#8 edit
.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#21 edit
.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#91 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sbin/camcontrol/camcontrol.c#8 (text+ko) ====

@@ -415,7 +415,8 @@
 					   sizeof(revision));
 				    sprintf(tmpstr, "<%s %s %s>", vendor, product,
 					revision);
-				} else if (dev_result->protocol == PROTO_ATA) {
+				} else if (dev_result->protocol == PROTO_ATA ||
+				    dev_result->protocol == PROTO_SATAPM) {
 				    cam_strvis(product,
 					   dev_result->ident_data.model,
 					   sizeof(dev_result->ident_data.model),

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

@@ -145,7 +145,6 @@
 	int		pm_ports;
 	int		pm_step;
 	int		pm_try;
-	int		pm_found;
 	struct cam_periph *periph;
 } probe_softc;
 
@@ -321,6 +320,8 @@
 
 	if (periph->path->device->flags & CAM_DEV_UNCONFIGURED)
 		PROBE_SET_ACTION(softc, PROBE_RESET);
+	else if (periph->path->device->protocol == PROTO_SATAPM)
+		PROBE_SET_ACTION(softc, PROBE_RESET);
 	else
 		PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
 
@@ -457,6 +458,9 @@
 		ata_pm_read_cmd(ataio, 2, 15);
 		break;
 	case PROBE_PM_RESET:
+	{
+		struct ata_params *ident_buf =
+		    &periph->path->device->ident_data;
 		cam_fill_ataio(ataio,
 		      1,
 		      probedone,
@@ -465,8 +469,12 @@
 		      /*data_ptr*/NULL,
 		      /*dxfer_len*/0,
 		      10 * 1000);
-		ata_pm_write_cmd(ataio, 2, softc->pm_step, 1);
+		ata_pm_write_cmd(ataio, 2, softc->pm_step,
+		    (ident_buf->cylinders & (1 << softc->pm_step)) ? 0 : 1);
+printf("PM RESET %d %04x %d\n", softc->pm_step, ident_buf->cylinders,
+    (ident_buf->cylinders & (1 << softc->pm_step)) ? 0 : 1);
 		break;
+	}
 	case PROBE_PM_CONNECT:
 		cam_fill_ataio(ataio,
 		      1,
@@ -634,6 +642,7 @@
 static void
 probedone(struct cam_periph *periph, union ccb *done_ccb)
 {
+	struct ata_params *ident_buf;
 	probe_softc *softc;
 	struct cam_path *path;
 	u_int32_t  priority;
@@ -644,6 +653,7 @@
 	softc = (probe_softc *)periph->softc;
 	path = done_ccb->ccb_h.path;
 	priority = done_ccb->ccb_h.pinfo.priority;
+	ident_buf = &path->device->ident_data;
 
 	switch (softc->action) {
 	case PROBE_RESET:
@@ -685,16 +695,12 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		xpt_release_ccb(done_ccb);
-		break;
+		goto device_fail;
 	case PROBE_IDENTIFY:
 	{
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
-			struct ata_params *ident_buf;
 			int16_t *ptr;
 
-			ident_buf = &path->device->ident_data;
-
 			for (ptr = (int16_t *)ident_buf;
 			     ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
 				*ptr = le16toh(*ptr);
@@ -788,6 +794,7 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
+device_fail:
 		/*
 		 * If we get to this point, we got an error status back
 		 * from the inquiry and the error status doesn't require
@@ -863,30 +870,19 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		/*
-		 * If we get to this point, we got an error status back
-		 * from the inquiry and the error status doesn't require
-		 * automatically retrying the command.  Therefore, the
-		 * inquiry failed.  If we had inquiry information before
-		 * for this device, but this latest inquiry command failed,
-		 * the device has probably gone away.  If this device isn't
-		 * already marked unconfigured, notify the peripheral
-		 * drivers that this device is no more.
-		 */
-		if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
-			/* Send the async notification. */
-			xpt_async(AC_LOST_DEVICE, path, NULL);
-
-		xpt_release_ccb(done_ccb);
-		break;
+		goto device_fail;
 	}
 	case PROBE_PM_PID:
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+			if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0)
+				bzero(ident_buf, sizeof(*ident_buf));
 			softc->pm_pid = (done_ccb->ataio.res.lba_high << 24) +
 			    (done_ccb->ataio.res.lba_mid << 16) +
 			    (done_ccb->ataio.res.lba_low << 8) +
 			    done_ccb->ataio.res.sector_count;
 			printf("PM Product ID: %08x\n", softc->pm_pid);
+			snprintf(ident_buf->model, sizeof(ident_buf->model),
+			    "Port Multiplier %08x", softc->pm_pid);
 			PROBE_SET_ACTION(softc, PROBE_PM_PRV);
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
@@ -902,8 +898,7 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		xpt_release_ccb(done_ccb);
-		break;
+		goto device_fail;
 	case PROBE_PM_PRV:
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 			softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) +
@@ -911,6 +906,8 @@
 			    (done_ccb->ataio.res.lba_low << 8) +
 			    done_ccb->ataio.res.sector_count;
 			printf("PM Revision: %08x\n", softc->pm_prv);
+			snprintf(ident_buf->revision, sizeof(ident_buf->revision),
+			    "%04x", softc->pm_prv);
 			PROBE_SET_ACTION(softc, PROBE_PM_PORTS);
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
@@ -926,8 +923,7 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		xpt_release_ccb(done_ccb);
-		break;
+		goto device_fail;
 	case PROBE_PM_PORTS:
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 			softc->pm_ports = (done_ccb->ataio.res.lba_high << 24) +
@@ -947,6 +943,8 @@
 			if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
 				softc->pm_ports = 5;
 			printf("PM ports: %d\n", softc->pm_ports);
+			ident_buf->config = softc->pm_ports;
+			path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
 			softc->pm_step = 0;
 			PROBE_SET_ACTION(softc, PROBE_PM_RESET);
 			xpt_release_ccb(done_ccb);
@@ -963,8 +961,7 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		xpt_release_ccb(done_ccb);
-		break;
+		goto device_fail;
 	case PROBE_PM_RESET:
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 			softc->pm_step++;
@@ -992,8 +989,7 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		xpt_release_ccb(done_ccb);
-		break;
+		goto device_fail;
 	case PROBE_PM_CONNECT:
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 			softc->pm_step++;
@@ -1004,7 +1000,6 @@
 			} else {
 				softc->pm_step = 0;
 				softc->pm_try = 0;
-				softc->pm_found = 0x8000;
 				printf("PM connect done\n");
 				PROBE_SET_ACTION(softc, PROBE_PM_CHECK);
 				xpt_release_ccb(done_ccb);
@@ -1022,8 +1017,7 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		xpt_release_ccb(done_ccb);
-		break;
+		goto device_fail;
 	case PROBE_PM_CHECK:
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 			int res = (done_ccb->ataio.res.lba_high << 24) +
@@ -1032,7 +1026,7 @@
 			    done_ccb->ataio.res.sector_count;
 			if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) {
 				printf("PM status: %d - %08x\n", softc->pm_step, res);
-				softc->pm_found |= (1 << softc->pm_step);
+				ident_buf->cylinders |= (1 << softc->pm_step);
 				softc->pm_step++;
 			} else {
 				if (softc->pm_try < 100) {
@@ -1040,6 +1034,7 @@
 					softc->pm_try++;
 				} else {
 					printf("PM status: %d - %08x\n", softc->pm_step, res);
+					ident_buf->cylinders &= ~(1 << softc->pm_step);
 					softc->pm_step++;
 				}
 			}
@@ -1065,8 +1060,7 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		xpt_release_ccb(done_ccb);
-		break;
+		goto device_fail;
 	case PROBE_PM_CLEAR:
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 			softc->pm_step++;
@@ -1075,7 +1069,16 @@
 				xpt_schedule(periph, priority);
 				return;
 			}
-			found = softc->pm_found;
+			found = ident_buf->cylinders | 0x8000;
+			if (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);
+				xpt_release_ccb(done_ccb);
+			}
+			break;
 		} else if (cam_periph_error(done_ccb, 0,
 					    done_ccb->ccb_h.target_lun > 0
 					    ? SF_RETRY_UA|SF_QUIET_IR
@@ -1087,8 +1090,7 @@
 			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 					 /*run_queue*/TRUE);
 		}
-		xpt_release_ccb(done_ccb);
-		break;
+		goto device_fail;
 	case PROBE_INVALID:
 		CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_INFO,
 		    ("probedone: invalid action state\n"));

==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#91 (text+ko) ====

@@ -1043,8 +1043,9 @@
 	printf("%s%d: ", periph->periph_name, periph->unit_number);
 	if (path->device->protocol == PROTO_SCSI)
 	    scsi_print_inquiry(&path->device->inq_data);
-	else if (path->device->protocol == PROTO_ATA)
-	    ata_print_ident(&path->device->ident_data);
+	else if (path->device->protocol == PROTO_ATA ||
+	    path->device->protocol == PROTO_SATAPM)
+		ata_print_ident(&path->device->ident_data);
 	else
 	    printf("Unknown protocol device\n");
 	if (bootverbose && path->device->serial_num_len > 0) {


More information about the p4-projects mailing list