svn commit: r199321 - head/sys/cam/ata
Alexander Motin
mav at FreeBSD.org
Mon Nov 16 15:18:02 UTC 2009
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();
More information about the svn-src-head
mailing list