MFC r199321:
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.
This commit is contained in:
parent
5bb9e329e2
commit
f8f174003a
@ -63,11 +63,12 @@ __FBSDID("$FreeBSD$");
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
PMP_STATE_NORMAL,
|
PMP_STATE_NORMAL,
|
||||||
PMP_STATE_PORTS,
|
PMP_STATE_PORTS,
|
||||||
PMP_STATE_CONFIG,
|
PMP_STATE_PRECONFIG,
|
||||||
PMP_STATE_RESET,
|
PMP_STATE_RESET,
|
||||||
PMP_STATE_CONNECT,
|
PMP_STATE_CONNECT,
|
||||||
PMP_STATE_CHECK,
|
PMP_STATE_CHECK,
|
||||||
PMP_STATE_CLEAR,
|
PMP_STATE_CLEAR,
|
||||||
|
PMP_STATE_CONFIG,
|
||||||
PMP_STATE_SCAN
|
PMP_STATE_SCAN
|
||||||
} pmp_state;
|
} pmp_state;
|
||||||
|
|
||||||
@ -436,7 +437,7 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb)
|
|||||||
pmp_default_timeout * 1000);
|
pmp_default_timeout * 1000);
|
||||||
ata_pm_read_cmd(ataio, 2, 15);
|
ata_pm_read_cmd(ataio, 2, 15);
|
||||||
break;
|
break;
|
||||||
case PMP_STATE_CONFIG:
|
case PMP_STATE_PRECONFIG:
|
||||||
cam_fill_ataio(ataio,
|
cam_fill_ataio(ataio,
|
||||||
pmp_retry_count,
|
pmp_retry_count,
|
||||||
pmpdone,
|
pmpdone,
|
||||||
@ -445,7 +446,7 @@ pmpstart(struct cam_periph *periph, union ccb *start_ccb)
|
|||||||
/*data_ptr*/NULL,
|
/*data_ptr*/NULL,
|
||||||
/*dxfer_len*/0,
|
/*dxfer_len*/0,
|
||||||
pmp_default_timeout * 1000);
|
pmp_default_timeout * 1000);
|
||||||
ata_pm_write_cmd(ataio, 0x60, 15, 0xf);
|
ata_pm_write_cmd(ataio, 0x60, 15, 0x0);
|
||||||
break;
|
break;
|
||||||
case PMP_STATE_RESET:
|
case PMP_STATE_RESET:
|
||||||
cam_fill_ataio(ataio,
|
cam_fill_ataio(ataio,
|
||||||
@ -495,6 +496,17 @@ printf("PM RESET %d%s\n", softc->pm_step,
|
|||||||
pmp_default_timeout * 1000);
|
pmp_default_timeout * 1000);
|
||||||
ata_pm_write_cmd(ataio, 1, softc->pm_step, 0xFFFFFFFF);
|
ata_pm_write_cmd(ataio, 1, softc->pm_step, 0xFFFFFFFF);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -554,24 +566,29 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb)
|
|||||||
(done_ccb->ataio.res.lba_mid << 16) +
|
(done_ccb->ataio.res.lba_mid << 16) +
|
||||||
(done_ccb->ataio.res.lba_low << 8) +
|
(done_ccb->ataio.res.lba_low << 8) +
|
||||||
done_ccb->ataio.res.sector_count;
|
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
|
* Port 5 is enclosure management bridge port, which has implementation
|
||||||
* problems, causing probe faults. Hide it for now. */
|
* problems, causing probe faults. Hide it for now. */
|
||||||
if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
|
if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
|
||||||
softc->pm_ports = 5;
|
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 5 is some fake "Config Disk" with 640 sectors size,
|
||||||
* port 6 is enclosure management bridge port.
|
* port 6 is enclosure management bridge port.
|
||||||
* Both fake ports has implementation problems, causing
|
* Both fake ports has implementation problems, causing
|
||||||
* probe faults. Hide them for now. */
|
* probe faults. Hide them for now. */
|
||||||
if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
|
if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
|
||||||
softc->pm_ports = 5;
|
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);
|
printf("PM ports: %d\n", softc->pm_ports);
|
||||||
softc->state = PMP_STATE_CONFIG;
|
softc->state = PMP_STATE_PRECONFIG;
|
||||||
xpt_release_ccb(done_ccb);
|
xpt_release_ccb(done_ccb);
|
||||||
xpt_schedule(periph, priority);
|
xpt_schedule(periph, priority);
|
||||||
return;
|
return;
|
||||||
case PMP_STATE_CONFIG:
|
case PMP_STATE_PRECONFIG:
|
||||||
softc->pm_step = 0;
|
softc->pm_step = 0;
|
||||||
softc->state = PMP_STATE_RESET;
|
softc->state = PMP_STATE_RESET;
|
||||||
softc->reset |= ~softc->found;
|
softc->reset |= ~softc->found;
|
||||||
@ -658,11 +675,15 @@ pmpdone(struct cam_periph *periph, union ccb *done_ccb)
|
|||||||
return;
|
return;
|
||||||
case PMP_STATE_CLEAR:
|
case PMP_STATE_CLEAR:
|
||||||
softc->pm_step++;
|
softc->pm_step++;
|
||||||
if (softc->pm_step < softc->pm_ports) {
|
if (softc->pm_step >= softc->pm_ports) {
|
||||||
xpt_release_ccb(done_ccb);
|
softc->state = PMP_STATE_CONFIG;
|
||||||
xpt_schedule(periph, priority);
|
softc->pm_step = 0;
|
||||||
return;
|
}
|
||||||
} else if (softc->found) {
|
xpt_release_ccb(done_ccb);
|
||||||
|
xpt_schedule(periph, priority);
|
||||||
|
return;
|
||||||
|
case PMP_STATE_CONFIG:
|
||||||
|
if (softc->found) {
|
||||||
softc->pm_step = 0;
|
softc->pm_step = 0;
|
||||||
softc->state = PMP_STATE_SCAN;
|
softc->state = PMP_STATE_SCAN;
|
||||||
work_ccb = xpt_alloc_ccb_nowait();
|
work_ccb = xpt_alloc_ccb_nowait();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user