PERFORCE change 164322 for review

Alexander Motin mav at FreeBSD.org
Sun Jun 14 06:43:55 UTC 2009


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

Change 164322 by mav at mav_mavbook on 2009/06/14 06:43:45

	Give SATA SIM information about PM probe result. It allows to avoid
	some reset command timeouts.
	Fix some probing issues.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#19 edit
.. //depot/projects/scottl-camlock/src/sys/cam/cam_ccb.h#22 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#26 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#12 edit

Differences ...

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

@@ -650,7 +650,7 @@
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 			int sign = (done_ccb->ataio.res.lba_high << 8) +
 			    done_ccb->ataio.res.lba_mid;
-			printf("SIGNATURE: %04x\n", sign);
+			xpt_print(path, "SIGNATURE: %04x\n", sign);
 			if (sign == 0x0000 &&
 			    done_ccb->ccb_h.target_id != 15) {
 				path->device->protocol = PROTO_ATA;
@@ -664,8 +664,10 @@
 				path->device->protocol = PROTO_SCSI;
 				PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
 			} else {
-				xpt_print(path,
-				    "Unexpected signature 0x%04x\n", sign);
+				if (done_ccb->ccb_h.target_id != 15) {
+					xpt_print(path,
+					    "Unexpected signature 0x%04x\n", sign);
+				}
 				xpt_release_ccb(done_ccb);
 				break;
 			}
@@ -945,6 +947,7 @@
 			if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
 				softc->pm_ports = 5;
 			printf("PM ports: %d\n", softc->pm_ports);
+			softc->pm_step = 0;
 			PROBE_SET_ACTION(softc, PROBE_PM_RESET);
 			xpt_release_ccb(done_ccb);
 			xpt_schedule(periph, priority);
@@ -972,6 +975,7 @@
 			} else {
 				softc->pm_step = 0;
 				DELAY(5000);
+				printf("PM reset done\n");
 				PROBE_SET_ACTION(softc, PROBE_PM_CONNECT);
 				xpt_release_ccb(done_ccb);
 				xpt_schedule(periph, priority);
@@ -999,7 +1003,9 @@
 				return;
 			} 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);
 				xpt_schedule(periph, priority);
@@ -1025,15 +1031,17 @@
 			    (done_ccb->ataio.res.lba_low << 8) +
 			    done_ccb->ataio.res.sector_count;
 			if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) {
-				printf("PM found: %d - %08x\n", softc->pm_step, res);
+				printf("PM status: %d - %08x\n", softc->pm_step, res);
 				softc->pm_found |= (1 << softc->pm_step);
 				softc->pm_step++;
 			} else {
 				if (softc->pm_try < 100) {
 					DELAY(10000);
 					softc->pm_try++;
-				} else
+				} else {
+					printf("PM status: %d - %08x\n", softc->pm_step, res);
 					softc->pm_step++;
+				}
 			}
 			if (softc->pm_step < softc->pm_ports) {
 				xpt_release_ccb(done_ccb);
@@ -1145,6 +1153,7 @@
 	struct	cam_path *path;
 	ata_scan_bus_info *scan_info;
 	union	ccb *work_ccb;
+	struct	ccb_trans_settings cts;
 	cam_status status;
 
 	CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
@@ -1180,7 +1189,14 @@
 		scan_info->request_ccb = request_ccb;
 		scan_info->cpi = &work_ccb->cpi;
 		scan_info->found = 0x8001;
-
+		/* Report SIM that we have no knowledge about PM presence. */
+		bzero(&cts, sizeof(cts));
+		xpt_setup_ccb(&cts.ccb_h, scan_info->request_ccb->ccb_h.path, 1);
+		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+		cts.type = CTS_TYPE_CURRENT_SETTINGS;
+		cts.xport_specific.sata.pm_present = 0;
+		cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
+		xpt_action((union ccb *)&cts);
 		/* If PM supported, probe it first. */
 		if (scan_info->cpi->hba_inquiry & PI_SATAPM)
 			scan_info->counter = 15;
@@ -1203,8 +1219,17 @@
 		 */
 		xpt_free_path(work_ccb->ccb_h.path);
 		if (scan_info->counter == 15 &&
-		    work_ccb->ccb_h.ppriv_field1 != 0)
+		    work_ccb->ccb_h.ppriv_field1 != 0) {
 			scan_info->found = work_ccb->ccb_h.ppriv_field1;
+			/* Report SIM that PM is present. */
+			bzero(&cts, sizeof(cts));
+			xpt_setup_ccb(&cts.ccb_h, scan_info->request_ccb->ccb_h.path, 1);
+			cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
+			cts.type = CTS_TYPE_CURRENT_SETTINGS;
+			cts.xport_specific.sata.pm_present = 1;
+			cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
+			xpt_action((union ccb *)&cts);
+		}
 take_next:
 		/* Take next device. Wrap from 15 (PM) to 0. */
 		scan_info->counter = (scan_info->counter + 1 ) & 0x0f;

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

@@ -216,6 +216,7 @@
 	PROTO_SCSI,	/* Small Computer System Interface */
 	PROTO_ATA,	/* AT Attachment */
 	PROTO_ATAPI,	/* AT Attachment Packetized Interface */
+	PROTO_SATAPM,	/* SATA Port Multiplier */
 } cam_proto;
 
 typedef enum {
@@ -503,6 +504,7 @@
 	PI_WIDE_16	= 0x20, /* Supports 16 bit wide SCSI */
 	PI_SDTR_ABLE	= 0x10,	/* Supports SDTR message */
 	PI_LINKED_CDB	= 0x08, /* Supports linked CDBs */
+	PI_SATAPM	= 0x04,	/* Supports SATA PM */
 	PI_TAG_ABLE	= 0x02,	/* Supports tag queue messages */
 	PI_SOFT_RST	= 0x01	/* Supports soft reset alternative */
 } pi_inqflag;
@@ -778,8 +780,10 @@
 
 struct ccb_trans_settings_sata {
 	u_int     	valid;		/* Which fields to honor */
-#define	CTS_SATA_VALID_SPEED		0x1000
+#define	CTS_SATA_VALID_SPEED		0x01
+#define	CTS_SATA_VALID_PM		0x02
 	u_int32_t 	bitrate;	/* Mbps */
+	u_int 		pm_present;	/* PM is present (XPT->SIM) */
 };
 
 /* Get/Set transfer rate/width/disconnection/tag queueing settings */

==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#26 (text+ko) ====

@@ -1256,8 +1256,8 @@
 	ATA_OUTL(ch->r_mem, AHCI_P_IS, 0xFFFFFFFF);
 	/* Start operations on this channel */
 	cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
-	ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_ST | AHCI_P_CMD_PMA);
-//	     (ch->devices & ATA_PORTMULTIPLIER ? AHCI_P_CMD_PMA : 0));
+	ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_ST |
+	    (ch->pm_present ? AHCI_P_CMD_PMA : 0));
 }
 
 static void
@@ -1556,10 +1556,16 @@
 		xpt_done(ccb);
 		break;
 	case XPT_SET_TRAN_SETTINGS:
-		/* XXX Implement */
-		ccb->ccb_h.status = CAM_PROVIDE_FAIL;
+	{
+		struct	ccb_trans_settings *cts = &ccb->cts;
+
+		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) {
+			ch->pm_present = cts->xport_specific.sata.pm_present;
+		}
+		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 */
 	{
@@ -1571,19 +1577,29 @@
 		cts->transport = XPORT_SATA;
 		cts->transport_version = 2;
 		cts->proto_specific.valid = 0;
-		cts->xport_specific.sata.valid = CTS_SATA_VALID_SPEED;
+		cts->xport_specific.sata.valid = 0;
 		if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
 			status = ATA_INL(ch->r_mem, AHCI_P_SSTS) & ATA_SS_SPD_MASK;
 		else
-			status = ATA_INL(ch->r_mem, AHCI_P_SSTS) & ATA_SC_SPD_MASK;
-		if (status & ATA_SS_SPD_GEN3)
+			status = ATA_INL(ch->r_mem, AHCI_P_SCTL) & ATA_SC_SPD_MASK;
+		if (status & ATA_SS_SPD_GEN3) {
 			cts->xport_specific.sata.bitrate = 600000;
-		else if (status & ATA_SS_SPD_GEN2)
+			cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED;
+		} else if (status & ATA_SS_SPD_GEN2) {
 			cts->xport_specific.sata.bitrate = 300000;
-		else if (status & ATA_SS_SPD_GEN1)
+			cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED;
+		} else if (status & ATA_SS_SPD_GEN1) {
 			cts->xport_specific.sata.bitrate = 150000;
-		else
-			cts->xport_specific.sata.valid = 0;
+			cts->xport_specific.sata.valid |= CTS_SATA_VALID_SPEED;
+		}
+		if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
+			cts->xport_specific.sata.pm_present =
+			    (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_PMA) ?
+			    1 : 0;
+		} else {
+			cts->xport_specific.sata.pm_present = ch->pm_present;
+		}
+		cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM;
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 		break;

==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#12 (text+ko) ====

@@ -342,6 +342,7 @@
 	struct ahci_slot	slot[AHCI_MAX_SLOTS];
 	struct mtx		mtx;		/* state lock */
 	int			devices;        /* What is present */
+	int			pm_present;	/* PM presence reported */
 	uint32_t		rslots;		/* Running slots */
 	uint32_t		aslots;		/* Slots with atomic commands  */
 	int			numrslots;	/* Number of running slots */


More information about the p4-projects mailing list