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();
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to