Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Nov 2009 15:18:02 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r199321 - head/sys/cam/ata
Message-ID:  <200911161518.nAGFI26S073567@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Nov 16 15:18:02 2009
New Revision: 199321
URL: http://svn.freebsd.org/changeset/base/199321

Log:
  Disable PortMultiplier Async Notifications for time of ports reset.
  They are useless at that time, but confuse Marvell AHCI.
  
  Add quirk for SiI57XX Port Multipliers, to hide extra port.

Modified:
  head/sys/cam/ata/ata_pmp.c

Modified: head/sys/cam/ata/ata_pmp.c
==============================================================================
--- head/sys/cam/ata/ata_pmp.c	Mon Nov 16 14:33:31 2009	(r199320)
+++ head/sys/cam/ata/ata_pmp.c	Mon Nov 16 15:18:02 2009	(r199321)
@@ -63,11 +63,12 @@ __FBSDID("$FreeBSD$");
 typedef enum {
 	PMP_STATE_NORMAL,
 	PMP_STATE_PORTS,
-	PMP_STATE_CONFIG,
+	PMP_STATE_PRECONFIG,
 	PMP_STATE_RESET,
 	PMP_STATE_CONNECT,
 	PMP_STATE_CHECK,
 	PMP_STATE_CLEAR,
+	PMP_STATE_CONFIG,
 	PMP_STATE_SCAN
 } pmp_state;
 
@@ -436,7 +437,7 @@ pmpstart(struct cam_periph *periph, unio
 		      pmp_default_timeout * 1000);
 		ata_pm_read_cmd(ataio, 2, 15);
 		break;
-	case PMP_STATE_CONFIG:
+	case PMP_STATE_PRECONFIG:
 		cam_fill_ataio(ataio,
 		      pmp_retry_count,
 		      pmpdone,
@@ -445,7 +446,7 @@ pmpstart(struct cam_periph *periph, unio
 		      /*data_ptr*/NULL,
 		      /*dxfer_len*/0,
 		      pmp_default_timeout * 1000);
-		ata_pm_write_cmd(ataio, 0x60, 15, 0xf);
+		ata_pm_write_cmd(ataio, 0x60, 15, 0x0);
 		break;
 	case PMP_STATE_RESET:
 		cam_fill_ataio(ataio,
@@ -495,6 +496,17 @@ printf("PM RESET %d%s\n", softc->pm_step
 		      pmp_default_timeout * 1000);
 		ata_pm_write_cmd(ataio, 1, softc->pm_step, 0xFFFFFFFF);
 		break;
+	case PMP_STATE_CONFIG:
+		cam_fill_ataio(ataio,
+		      pmp_retry_count,
+		      pmpdone,
+		      /*flags*/CAM_DIR_NONE,
+		      0,
+		      /*data_ptr*/NULL,
+		      /*dxfer_len*/0,
+		      pmp_default_timeout * 1000);
+		ata_pm_write_cmd(ataio, 0x60, 15, 0xf);
+		break;
 	default:
 		break;
 	}
@@ -554,24 +566,29 @@ pmpdone(struct cam_periph *periph, union
 		    (done_ccb->ataio.res.lba_mid << 16) +
 		    (done_ccb->ataio.res.lba_low << 8) +
 		    done_ccb->ataio.res.sector_count;
-		/* This PM declares 6 ports, while only 5 of them are real.
+		/* This PMP declares 6 ports, while only 5 of them are real.
 		 * Port 5 is enclosure management bridge port, which has implementation
 		 * problems, causing probe faults. Hide it for now. */
 		if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
 			softc->pm_ports = 5;
-		/* This PM declares 7 ports, while only 5 of them are real.
+		/* This PMP declares 7 ports, while only 5 of them are real.
 		 * Port 5 is some fake "Config  Disk" with 640 sectors size,
 		 * port 6 is enclosure management bridge port.
 		 * Both fake ports has implementation problems, causing
 		 * probe faults. Hide them for now. */
 		if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
 			softc->pm_ports = 5;
+		/* These PMPs declare one more port then actually have,
+		 * for configuration purposes. Hide it for now. */
+		if (softc->pm_pid == 0x57231095 || softc->pm_pid == 0x57331095 ||
+		    softc->pm_pid == 0x57341095 || softc->pm_pid == 0x57441095)
+			softc->pm_ports--;
 		printf("PM ports: %d\n", softc->pm_ports);
-		softc->state = PMP_STATE_CONFIG;
+		softc->state = PMP_STATE_PRECONFIG;
 		xpt_release_ccb(done_ccb);
 		xpt_schedule(periph, priority);
 		return;
-	case PMP_STATE_CONFIG:
+	case PMP_STATE_PRECONFIG:
 		softc->pm_step = 0;
 		softc->state = PMP_STATE_RESET;
 		softc->reset |= ~softc->found;
@@ -658,11 +675,15 @@ pmpdone(struct cam_periph *periph, union
 		return;
 	case PMP_STATE_CLEAR:
 		softc->pm_step++;
-		if (softc->pm_step < softc->pm_ports) {
-			xpt_release_ccb(done_ccb);
-			xpt_schedule(periph, priority);
-			return;
-		} else if (softc->found) {
+		if (softc->pm_step >= softc->pm_ports) {
+			softc->state = PMP_STATE_CONFIG;
+			softc->pm_step = 0;
+		}
+		xpt_release_ccb(done_ccb);
+		xpt_schedule(periph, priority);
+		return;
+	case PMP_STATE_CONFIG:
+		if (softc->found) {
 			softc->pm_step = 0;
 			softc->state = PMP_STATE_SCAN;
 			work_ccb = xpt_alloc_ccb_nowait();



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911161518.nAGFI26S073567>