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;
|
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 *
|
* port_start *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
@ -1242,20 +1257,18 @@ static void port_restart(struct port_state *ps)
|
|||||||
|
|
||||||
dprintf(V_ERR, ("%s: port reset\n", ahci_portname(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
|
/* To keep this driver simple, we do not transparently recover
|
||||||
* ongoing requests. Instead, we mark the failing device as
|
* 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
|
* device (or, perhaps, eventually, another device) will come
|
||||||
* back up. Any current and future requests to this port will
|
* back up. Any current and future requests to this port will
|
||||||
* be failed until the port is fully closed and reopened.
|
* be failed until the port is fully closed and reopened.
|
||||||
*/
|
*/
|
||||||
port_disconnect(ps);
|
port_disconnect(ps);
|
||||||
|
|
||||||
|
/* Trigger a port reset. */
|
||||||
|
port_hardreset(ps);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1907,13 +1920,14 @@ static void port_init(struct port_state *ps)
|
|||||||
/* Just listen for device status change events for now. */
|
/* Just listen for device status change events for now. */
|
||||||
port_write(ps, AHCI_PORT_IE, AHCI_PORT_IE_PRCE);
|
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);
|
cmd = port_read(ps, AHCI_PORT_CMD);
|
||||||
port_write(ps, AHCI_PORT_CMD, cmd | AHCI_PORT_CMD_SUD);
|
port_write(ps, AHCI_PORT_CMD, cmd | AHCI_PORT_CMD_SUD);
|
||||||
|
|
||||||
port_write(ps, AHCI_PORT_SCTL, AHCI_PORT_SCTL_DET_INIT);
|
/* Trigger a port reset. */
|
||||||
micro_delay(SPINUP_DELAY * 1000); /* SPINUP_DELAY is in ms */
|
port_hardreset(ps);
|
||||||
port_write(ps, AHCI_PORT_SCTL, AHCI_PORT_SCTL_DET_NONE);
|
|
||||||
|
|
||||||
set_timer(&ps->cmd_info[0].timer, ahci_spinup_timeout,
|
set_timer(&ps->cmd_info[0].timer, ahci_spinup_timeout,
|
||||||
port_timeout, BUILD_ARG(ps - port_state, 0));
|
port_timeout, BUILD_ARG(ps - port_state, 0));
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#define FLUSH_TIMEOUT 60000 /* time to wait for flush cmd (ms) */
|
#define FLUSH_TIMEOUT 60000 /* time to wait for flush cmd (ms) */
|
||||||
|
|
||||||
/* Time values that are defined by the standards. */
|
/* 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 RESET_DELAY 1000 /* maximum HBA reset time (ms) */
|
||||||
#define PORTREG_DELAY 500 /* maximum port register update (ms) */
|
#define PORTREG_DELAY 500 /* maximum port register update (ms) */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user