ahci: centralize, fix port reset
This commit is contained in:
parent
f2de719cfe
commit
ad0b58fe83
@ -1192,6 +1192,21 @@ static ssize_t port_transfer(struct port_state *ps, u64_t pos, u64_t eof,
|
||||
return size;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* port_hardreset *
|
||||
*===========================================================================*/
|
||||
static void port_hardreset(struct port_state *ps)
|
||||
{
|
||||
/* Perform a port-level (hard) reset on the given port.
|
||||
*/
|
||||
|
||||
port_write(ps, AHCI_PORT_SCTL, AHCI_PORT_SCTL_DET_INIT);
|
||||
|
||||
micro_delay(COMRESET_DELAY * 1000); /* COMRESET_DELAY is in ms */
|
||||
|
||||
port_write(ps, AHCI_PORT_SCTL, AHCI_PORT_SCTL_DET_NONE);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* port_start *
|
||||
*===========================================================================*/
|
||||
@ -1242,20 +1257,18 @@ static void port_restart(struct port_state *ps)
|
||||
|
||||
dprintf(V_ERR, ("%s: port reset\n", ahci_portname(ps)));
|
||||
|
||||
/* Trigger a port reset. */
|
||||
port_write(ps, AHCI_PORT_SCTL, AHCI_PORT_SCTL_DET_INIT);
|
||||
micro_delay(SPINUP_DELAY * 1000);
|
||||
port_write(ps, AHCI_PORT_SCTL, AHCI_PORT_SCTL_DET_NONE);
|
||||
|
||||
/* To keep this driver simple, we do not transparently recover
|
||||
* ongoing requests. Instead, we mark the failing device as
|
||||
* disconnected, and assume that if the reset succeeds, the
|
||||
* disconnected, and reset it. If the reset succeeds, the
|
||||
* device (or, perhaps, eventually, another device) will come
|
||||
* back up. Any current and future requests to this port will
|
||||
* be failed until the port is fully closed and reopened.
|
||||
*/
|
||||
port_disconnect(ps);
|
||||
|
||||
/* Trigger a port reset. */
|
||||
port_hardreset(ps);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1907,13 +1920,14 @@ static void port_init(struct port_state *ps)
|
||||
/* Just listen for device status change events for now. */
|
||||
port_write(ps, AHCI_PORT_IE, AHCI_PORT_IE_PRCE);
|
||||
|
||||
/* Perform a reset on the device. */
|
||||
/* Enable device spin-up for HBAs that support staggered spin-up.
|
||||
* This is a no-op for HBAs that do not support it.
|
||||
*/
|
||||
cmd = port_read(ps, AHCI_PORT_CMD);
|
||||
port_write(ps, AHCI_PORT_CMD, cmd | AHCI_PORT_CMD_SUD);
|
||||
|
||||
port_write(ps, AHCI_PORT_SCTL, AHCI_PORT_SCTL_DET_INIT);
|
||||
micro_delay(SPINUP_DELAY * 1000); /* SPINUP_DELAY is in ms */
|
||||
port_write(ps, AHCI_PORT_SCTL, AHCI_PORT_SCTL_DET_NONE);
|
||||
/* Trigger a port reset. */
|
||||
port_hardreset(ps);
|
||||
|
||||
set_timer(&ps->cmd_info[0].timer, ahci_spinup_timeout,
|
||||
port_timeout, BUILD_ARG(ps - port_state, 0));
|
||||
|
@ -15,7 +15,7 @@
|
||||
#define FLUSH_TIMEOUT 60000 /* time to wait for flush cmd (ms) */
|
||||
|
||||
/* Time values that are defined by the standards. */
|
||||
#define SPINUP_DELAY 1 /* time to assert spin-up flag (ms) */
|
||||
#define COMRESET_DELAY 1 /* time to assert port reset (ms) */
|
||||
#define RESET_DELAY 1000 /* maximum HBA reset time (ms) */
|
||||
#define PORTREG_DELAY 500 /* maximum port register update (ms) */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user