Merge branch 'reset-seq' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'reset-seq' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev: [libata reset-seq] build and merge fixes libata: reimplement reset sequencing libata: improve ata_std_prereset() libata: improve 0xff status handling libata: add deadline support to prereset and reset methods
This commit is contained in:
commit
4750def52c
|
@ -874,7 +874,8 @@ static int ahci_clo(struct ata_port *ap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ahci_softreset(struct ata_port *ap, unsigned int *class)
|
||||
static int ahci_softreset(struct ata_port *ap, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
void __iomem *port_mmio = ahci_port_base(ap);
|
||||
|
@ -959,15 +960,13 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
|
|||
*/
|
||||
msleep(150);
|
||||
|
||||
*class = ATA_DEV_NONE;
|
||||
if (ata_port_online(ap)) {
|
||||
if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
|
||||
rc = -EIO;
|
||||
reason = "device not ready";
|
||||
goto fail;
|
||||
}
|
||||
*class = ahci_dev_classify(ap);
|
||||
rc = ata_wait_ready(ap, deadline);
|
||||
/* link occupied, -ENODEV too is an error */
|
||||
if (rc) {
|
||||
reason = "device not ready";
|
||||
goto fail;
|
||||
}
|
||||
*class = ahci_dev_classify(ap);
|
||||
|
||||
DPRINTK("EXIT, class=%u\n", *class);
|
||||
return 0;
|
||||
|
@ -979,7 +978,8 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ahci_port_priv *pp = ap->private_data;
|
||||
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
|
||||
|
@ -995,7 +995,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
tf.command = 0x80;
|
||||
ata_tf_to_fis(&tf, d2h_fis, 0);
|
||||
|
||||
rc = sata_std_hardreset(ap, class);
|
||||
rc = sata_std_hardreset(ap, class, deadline);
|
||||
|
||||
ahci_start_engine(ap);
|
||||
|
||||
|
@ -1008,7 +1008,8 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
@ -1016,7 +1017,8 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
|
||||
ahci_stop_engine(ap);
|
||||
|
||||
rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
|
||||
rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context),
|
||||
deadline);
|
||||
|
||||
/* vt8251 needs SError cleared for the port to operate */
|
||||
ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
|
||||
|
|
|
@ -625,17 +625,18 @@ static int ich_pata_cable_detect(struct ata_port *ap)
|
|||
/**
|
||||
* piix_pata_prereset - prereset for PATA host controller
|
||||
* @ap: Target port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* LOCKING:
|
||||
* None (inherited from caller).
|
||||
*/
|
||||
static int piix_pata_prereset(struct ata_port *ap)
|
||||
static int piix_pata_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
||||
if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
static void piix_pata_error_handler(struct ata_port *ap)
|
||||
|
@ -644,7 +645,6 @@ static void piix_pata_error_handler(struct ata_port *ap)
|
|||
ata_std_postreset);
|
||||
}
|
||||
|
||||
|
||||
static void piix_sata_error_handler(struct ata_port *ap)
|
||||
{
|
||||
ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
|
||||
|
|
|
@ -2979,23 +2979,71 @@ int ata_busy_sleep(struct ata_port *ap,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
|
||||
/**
|
||||
* ata_wait_ready - sleep until BSY clears, or timeout
|
||||
* @ap: port containing status register to be polled
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Sleep until ATA Status register bit BSY clears, or timeout
|
||||
* occurs.
|
||||
*
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep).
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int ata_wait_ready(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
unsigned long start = jiffies;
|
||||
int warned = 0;
|
||||
|
||||
while (1) {
|
||||
u8 status = ata_chk_status(ap);
|
||||
unsigned long now = jiffies;
|
||||
|
||||
if (!(status & ATA_BUSY))
|
||||
return 0;
|
||||
if (status == 0xff)
|
||||
return -ENODEV;
|
||||
if (time_after(now, deadline))
|
||||
return -EBUSY;
|
||||
|
||||
if (!warned && time_after(now, start + 5 * HZ) &&
|
||||
(deadline - now > 3 * HZ)) {
|
||||
ata_port_printk(ap, KERN_WARNING,
|
||||
"port is slow to respond, please be patient "
|
||||
"(Status 0x%x)\n", status);
|
||||
warned = 1;
|
||||
}
|
||||
|
||||
msleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
unsigned int dev0 = devmask & (1 << 0);
|
||||
unsigned int dev1 = devmask & (1 << 1);
|
||||
unsigned long timeout;
|
||||
int rc, ret = 0;
|
||||
|
||||
/* if device 0 was found in ata_devchk, wait for its
|
||||
* BSY bit to clear
|
||||
*/
|
||||
if (dev0)
|
||||
ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
|
||||
if (dev0) {
|
||||
rc = ata_wait_ready(ap, deadline);
|
||||
if (rc) {
|
||||
if (rc != -ENODEV)
|
||||
return rc;
|
||||
ret = rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* if device 1 was found in ata_devchk, wait for
|
||||
* register access, then wait for BSY to clear
|
||||
*/
|
||||
timeout = jiffies + ATA_TMOUT_BOOT;
|
||||
while (dev1) {
|
||||
u8 nsect, lbal;
|
||||
|
||||
|
@ -3004,14 +3052,18 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
|
|||
lbal = ioread8(ioaddr->lbal_addr);
|
||||
if ((nsect == 1) && (lbal == 1))
|
||||
break;
|
||||
if (time_after(jiffies, timeout)) {
|
||||
dev1 = 0;
|
||||
break;
|
||||
}
|
||||
if (time_after(jiffies, deadline))
|
||||
return -EBUSY;
|
||||
msleep(50); /* give drive a breather */
|
||||
}
|
||||
if (dev1)
|
||||
ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
|
||||
if (dev1) {
|
||||
rc = ata_wait_ready(ap, deadline);
|
||||
if (rc) {
|
||||
if (rc != -ENODEV)
|
||||
return rc;
|
||||
ret = rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* is all this really necessary? */
|
||||
ap->ops->dev_select(ap, 0);
|
||||
|
@ -3019,10 +3071,12 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
|
|||
ap->ops->dev_select(ap, 1);
|
||||
if (dev0)
|
||||
ap->ops->dev_select(ap, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int ata_bus_softreset(struct ata_port *ap,
|
||||
unsigned int devmask)
|
||||
static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct ata_ioports *ioaddr = &ap->ioaddr;
|
||||
|
||||
|
@ -3052,11 +3106,9 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
|
|||
* pulldown resistor.
|
||||
*/
|
||||
if (ata_check_status(ap) == 0xFF)
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
|
||||
ata_bus_post_reset(ap, devmask);
|
||||
|
||||
return 0;
|
||||
return ata_bus_post_reset(ap, devmask, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3085,6 +3137,7 @@ void ata_bus_reset(struct ata_port *ap)
|
|||
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
|
||||
u8 err;
|
||||
unsigned int dev0, dev1 = 0, devmask = 0;
|
||||
int rc;
|
||||
|
||||
DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no);
|
||||
|
||||
|
@ -3106,9 +3159,11 @@ void ata_bus_reset(struct ata_port *ap)
|
|||
ap->ops->dev_select(ap, 0);
|
||||
|
||||
/* issue bus reset */
|
||||
if (ap->flags & ATA_FLAG_SRST)
|
||||
if (ata_bus_softreset(ap, devmask))
|
||||
if (ap->flags & ATA_FLAG_SRST) {
|
||||
rc = ata_bus_softreset(ap, devmask, jiffies + 40 * HZ);
|
||||
if (rc && rc != -ENODEV)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* determine by signature whether we have ATA or ATAPI devices
|
||||
|
@ -3150,29 +3205,37 @@ err_out:
|
|||
* sata_phy_debounce - debounce SATA phy status
|
||||
* @ap: ATA port to debounce SATA phy status for
|
||||
* @params: timing parameters { interval, duratinon, timeout } in msec
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Make sure SStatus of @ap reaches stable state, determined by
|
||||
* holding the same value where DET is not 1 for @duration polled
|
||||
* every @interval, before @timeout. Timeout constraints the
|
||||
* beginning of the stable state. Because, after hot unplugging,
|
||||
* DET gets stuck at 1 on some controllers, this functions waits
|
||||
* beginning of the stable state. Because DET gets stuck at 1 on
|
||||
* some controllers after hot unplugging, this functions waits
|
||||
* until timeout then returns 0 if DET is stable at 1.
|
||||
*
|
||||
* @timeout is further limited by @deadline. The sooner of the
|
||||
* two is used.
|
||||
*
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep)
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno on failure.
|
||||
*/
|
||||
int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
|
||||
int sata_phy_debounce(struct ata_port *ap, const unsigned long *params,
|
||||
unsigned long deadline)
|
||||
{
|
||||
unsigned long interval_msec = params[0];
|
||||
unsigned long duration = params[1] * HZ / 1000;
|
||||
unsigned long timeout = jiffies + params[2] * HZ / 1000;
|
||||
unsigned long last_jiffies;
|
||||
unsigned long duration = msecs_to_jiffies(params[1]);
|
||||
unsigned long last_jiffies, t;
|
||||
u32 last, cur;
|
||||
int rc;
|
||||
|
||||
t = jiffies + msecs_to_jiffies(params[2]);
|
||||
if (time_before(t, deadline))
|
||||
deadline = t;
|
||||
|
||||
if ((rc = sata_scr_read(ap, SCR_STATUS, &cur)))
|
||||
return rc;
|
||||
cur &= 0xf;
|
||||
|
@ -3188,7 +3251,7 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
|
|||
|
||||
/* DET stable? */
|
||||
if (cur == last) {
|
||||
if (cur == 1 && time_before(jiffies, timeout))
|
||||
if (cur == 1 && time_before(jiffies, deadline))
|
||||
continue;
|
||||
if (time_after(jiffies, last_jiffies + duration))
|
||||
return 0;
|
||||
|
@ -3199,8 +3262,8 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
|
|||
last = cur;
|
||||
last_jiffies = jiffies;
|
||||
|
||||
/* check timeout */
|
||||
if (time_after(jiffies, timeout))
|
||||
/* check deadline */
|
||||
if (time_after(jiffies, deadline))
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
@ -3209,6 +3272,7 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
|
|||
* sata_phy_resume - resume SATA phy
|
||||
* @ap: ATA port to resume SATA phy for
|
||||
* @params: timing parameters { interval, duratinon, timeout } in msec
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Resume SATA phy of @ap and debounce it.
|
||||
*
|
||||
|
@ -3218,7 +3282,8 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
|
|||
* RETURNS:
|
||||
* 0 on success, -errno on failure.
|
||||
*/
|
||||
int sata_phy_resume(struct ata_port *ap, const unsigned long *params)
|
||||
int sata_phy_resume(struct ata_port *ap, const unsigned long *params,
|
||||
unsigned long deadline)
|
||||
{
|
||||
u32 scontrol;
|
||||
int rc;
|
||||
|
@ -3236,43 +3301,19 @@ int sata_phy_resume(struct ata_port *ap, const unsigned long *params)
|
|||
*/
|
||||
msleep(200);
|
||||
|
||||
return sata_phy_debounce(ap, params);
|
||||
}
|
||||
|
||||
static void ata_wait_spinup(struct ata_port *ap)
|
||||
{
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
unsigned long end, secs;
|
||||
int rc;
|
||||
|
||||
/* first, debounce phy if SATA */
|
||||
if (ap->cbl == ATA_CBL_SATA) {
|
||||
rc = sata_phy_debounce(ap, sata_deb_timing_hotplug);
|
||||
|
||||
/* if debounced successfully and offline, no need to wait */
|
||||
if ((rc == 0 || rc == -EOPNOTSUPP) && ata_port_offline(ap))
|
||||
return;
|
||||
}
|
||||
|
||||
/* okay, let's give the drive time to spin up */
|
||||
end = ehc->i.hotplug_timestamp + ATA_SPINUP_WAIT * HZ / 1000;
|
||||
secs = ((end - jiffies) + HZ - 1) / HZ;
|
||||
|
||||
if (time_after(jiffies, end))
|
||||
return;
|
||||
|
||||
if (secs > 5)
|
||||
ata_port_printk(ap, KERN_INFO, "waiting for device to spin up "
|
||||
"(%lu secs)\n", secs);
|
||||
|
||||
schedule_timeout_uninterruptible(end - jiffies);
|
||||
return sata_phy_debounce(ap, params, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_std_prereset - prepare for reset
|
||||
* @ap: ATA port to be reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* @ap is about to be reset. Initialize it.
|
||||
* @ap is about to be reset. Initialize it. Failure from
|
||||
* prereset makes libata abort whole reset sequence and give up
|
||||
* that port, so prereset should be best-effort. It does its
|
||||
* best to prepare for reset sequence but if things go wrong, it
|
||||
* should just whine, not fail.
|
||||
*
|
||||
* LOCKING:
|
||||
* Kernel thread context (may sleep)
|
||||
|
@ -3280,41 +3321,41 @@ static void ata_wait_spinup(struct ata_port *ap)
|
|||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int ata_std_prereset(struct ata_port *ap)
|
||||
int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
const unsigned long *timing = sata_ehc_deb_timing(ehc);
|
||||
int rc;
|
||||
|
||||
/* handle link resume & hotplug spinup */
|
||||
/* handle link resume */
|
||||
if ((ehc->i.flags & ATA_EHI_RESUME_LINK) &&
|
||||
(ap->flags & ATA_FLAG_HRST_TO_RESUME))
|
||||
ehc->i.action |= ATA_EH_HARDRESET;
|
||||
|
||||
if ((ehc->i.flags & ATA_EHI_HOTPLUGGED) &&
|
||||
(ap->flags & ATA_FLAG_SKIP_D2H_BSY))
|
||||
ata_wait_spinup(ap);
|
||||
|
||||
/* if we're about to do hardreset, nothing more to do */
|
||||
if (ehc->i.action & ATA_EH_HARDRESET)
|
||||
return 0;
|
||||
|
||||
/* if SATA, resume phy */
|
||||
if (ap->cbl == ATA_CBL_SATA) {
|
||||
rc = sata_phy_resume(ap, timing);
|
||||
if (rc && rc != -EOPNOTSUPP) {
|
||||
/* phy resume failed */
|
||||
rc = sata_phy_resume(ap, timing, deadline);
|
||||
/* whine about phy resume failure but proceed */
|
||||
if (rc && rc != -EOPNOTSUPP)
|
||||
ata_port_printk(ap, KERN_WARNING, "failed to resume "
|
||||
"link for reset (errno=%d)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for !BSY if the controller can wait for the first D2H
|
||||
* Reg FIS and we don't know that no device is attached.
|
||||
*/
|
||||
if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap))
|
||||
ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
|
||||
if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap)) {
|
||||
rc = ata_wait_ready(ap, deadline);
|
||||
if (rc) {
|
||||
ata_port_printk(ap, KERN_WARNING, "device not ready "
|
||||
"(errno=%d), forcing hardreset\n", rc);
|
||||
ehc->i.action |= ATA_EH_HARDRESET;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3323,6 +3364,7 @@ int ata_std_prereset(struct ata_port *ap)
|
|||
* ata_std_softreset - reset host port via ATA SRST
|
||||
* @ap: port to reset
|
||||
* @classes: resulting classes of attached devices
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Reset host port using ATA SRST.
|
||||
*
|
||||
|
@ -3332,10 +3374,12 @@ int ata_std_prereset(struct ata_port *ap)
|
|||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
|
||||
int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
|
||||
unsigned long deadline)
|
||||
{
|
||||
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
|
||||
unsigned int devmask = 0, err_mask;
|
||||
unsigned int devmask = 0;
|
||||
int rc;
|
||||
u8 err;
|
||||
|
||||
DPRINTK("ENTER\n");
|
||||
|
@ -3356,11 +3400,11 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
|
|||
|
||||
/* issue bus reset */
|
||||
DPRINTK("about to softreset, devmask=%x\n", devmask);
|
||||
err_mask = ata_bus_softreset(ap, devmask);
|
||||
if (err_mask) {
|
||||
ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
|
||||
err_mask);
|
||||
return -EIO;
|
||||
rc = ata_bus_softreset(ap, devmask, deadline);
|
||||
/* if link is occupied, -ENODEV too is an error */
|
||||
if (rc && (rc != -ENODEV || sata_scr_valid(ap))) {
|
||||
ata_port_printk(ap, KERN_ERR, "SRST failed (errno=%d)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* determine by signature whether we have ATA or ATAPI devices */
|
||||
|
@ -3377,6 +3421,7 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
|
|||
* sata_port_hardreset - reset port via SATA phy reset
|
||||
* @ap: port to reset
|
||||
* @timing: timing parameters { interval, duratinon, timeout } in msec
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* SATA phy-reset host port using DET bits of SControl register.
|
||||
*
|
||||
|
@ -3386,7 +3431,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
|
|||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
|
||||
int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing,
|
||||
unsigned long deadline)
|
||||
{
|
||||
u32 scontrol;
|
||||
int rc;
|
||||
|
@ -3425,7 +3471,7 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
|
|||
msleep(1);
|
||||
|
||||
/* bring phy back */
|
||||
rc = sata_phy_resume(ap, timing);
|
||||
rc = sata_phy_resume(ap, timing, deadline);
|
||||
out:
|
||||
DPRINTK("EXIT, rc=%d\n", rc);
|
||||
return rc;
|
||||
|
@ -3435,6 +3481,7 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
|
|||
* sata_std_hardreset - reset host port via SATA phy reset
|
||||
* @ap: port to reset
|
||||
* @class: resulting class of attached device
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* SATA phy-reset host port using DET bits of SControl register,
|
||||
* wait for !BSY and classify the attached device.
|
||||
|
@ -3445,7 +3492,8 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
|
|||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
int sata_std_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
|
||||
int rc;
|
||||
|
@ -3453,7 +3501,7 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
DPRINTK("ENTER\n");
|
||||
|
||||
/* do hardreset */
|
||||
rc = sata_port_hardreset(ap, timing);
|
||||
rc = sata_port_hardreset(ap, timing, deadline);
|
||||
if (rc) {
|
||||
ata_port_printk(ap, KERN_ERR,
|
||||
"COMRESET failed (errno=%d)\n", rc);
|
||||
|
@ -3470,10 +3518,12 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
/* wait a while before checking status, see SRST for more info */
|
||||
msleep(150);
|
||||
|
||||
if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
|
||||
rc = ata_wait_ready(ap, deadline);
|
||||
/* link occupied, -ENODEV too is an error */
|
||||
if (rc) {
|
||||
ata_port_printk(ap, KERN_ERR,
|
||||
"COMRESET failed (device not ready)\n");
|
||||
return -EIO;
|
||||
"COMRESET failed (errno=%d)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
ap->ops->dev_select(ap, 0); /* probably unnecessary */
|
||||
|
@ -6793,6 +6843,7 @@ EXPORT_SYMBOL_GPL(ata_port_disable);
|
|||
EXPORT_SYMBOL_GPL(ata_ratelimit);
|
||||
EXPORT_SYMBOL_GPL(ata_wait_register);
|
||||
EXPORT_SYMBOL_GPL(ata_busy_sleep);
|
||||
EXPORT_SYMBOL_GPL(ata_wait_ready);
|
||||
EXPORT_SYMBOL_GPL(ata_port_queue_task);
|
||||
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
|
||||
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
|
||||
|
|
|
@ -50,6 +50,28 @@ enum {
|
|||
ATA_EH_SPDN_FALLBACK_TO_PIO = (1 << 2),
|
||||
};
|
||||
|
||||
/* Waiting in ->prereset can never be reliable. It's sometimes nice
|
||||
* to wait there but it can't be depended upon; otherwise, we wouldn't
|
||||
* be resetting. Just give it enough time for most drives to spin up.
|
||||
*/
|
||||
enum {
|
||||
ATA_EH_PRERESET_TIMEOUT = 10 * HZ,
|
||||
};
|
||||
|
||||
/* The following table determines how we sequence resets. Each entry
|
||||
* represents timeout for that try. The first try can be soft or
|
||||
* hardreset. All others are hardreset if available. In most cases
|
||||
* the first reset w/ 10sec timeout should succeed. Following entries
|
||||
* are mostly for error handling, hotplug and retarded devices.
|
||||
*/
|
||||
static const unsigned long ata_eh_reset_timeouts[] = {
|
||||
10 * HZ, /* most drives spin up by 10sec */
|
||||
10 * HZ, /* > 99% working drives spin up before 20sec */
|
||||
35 * HZ, /* give > 30 secs of idleness for retarded devices */
|
||||
5 * HZ, /* and sweet one last chance */
|
||||
/* > 1 min has elapsed, give up */
|
||||
};
|
||||
|
||||
static void __ata_port_freeze(struct ata_port *ap);
|
||||
static void ata_eh_finish(struct ata_port *ap);
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -1558,14 +1580,14 @@ static void ata_eh_report(struct ata_port *ap)
|
|||
}
|
||||
|
||||
static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
|
||||
unsigned int *classes)
|
||||
unsigned int *classes, unsigned long deadline)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
for (i = 0; i < ATA_MAX_DEVICES; i++)
|
||||
classes[i] = ATA_DEV_UNKNOWN;
|
||||
|
||||
rc = reset(ap, classes);
|
||||
rc = reset(ap, classes, deadline);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
@ -1603,8 +1625,9 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
|
|||
{
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
unsigned int *classes = ehc->classes;
|
||||
int tries = ATA_EH_RESET_TRIES;
|
||||
int verbose = !(ehc->i.flags & ATA_EHI_QUIET);
|
||||
int try = 0;
|
||||
unsigned long deadline;
|
||||
unsigned int action;
|
||||
ata_reset_fn_t reset;
|
||||
int i, did_followup_srst, rc;
|
||||
|
@ -1624,7 +1647,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
|
|||
ehc->i.action |= ATA_EH_HARDRESET;
|
||||
|
||||
if (prereset) {
|
||||
rc = prereset(ap);
|
||||
rc = prereset(ap, jiffies + ATA_EH_PRERESET_TIMEOUT);
|
||||
if (rc) {
|
||||
if (rc == -ENOENT) {
|
||||
ata_port_printk(ap, KERN_DEBUG,
|
||||
|
@ -1665,6 +1688,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
|
|||
}
|
||||
|
||||
retry:
|
||||
deadline = jiffies + ata_eh_reset_timeouts[try++];
|
||||
|
||||
/* shut up during boot probing */
|
||||
if (verbose)
|
||||
ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
|
||||
|
@ -1676,7 +1701,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
|
|||
else
|
||||
ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
|
||||
|
||||
rc = ata_do_reset(ap, reset, classes);
|
||||
rc = ata_do_reset(ap, reset, classes, deadline);
|
||||
|
||||
did_followup_srst = 0;
|
||||
if (reset == hardreset &&
|
||||
|
@ -1693,7 +1718,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
|
|||
}
|
||||
|
||||
ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK);
|
||||
rc = ata_do_reset(ap, reset, classes);
|
||||
rc = ata_do_reset(ap, reset, classes, deadline);
|
||||
|
||||
if (rc == 0 && classify &&
|
||||
classes[0] == ATA_DEV_UNKNOWN) {
|
||||
|
@ -1703,22 +1728,21 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
|
|||
}
|
||||
}
|
||||
|
||||
if (rc && --tries) {
|
||||
const char *type;
|
||||
if (rc && try < ARRAY_SIZE(ata_eh_reset_timeouts)) {
|
||||
unsigned long now = jiffies;
|
||||
|
||||
if (reset == softreset) {
|
||||
if (did_followup_srst)
|
||||
type = "follow-up soft";
|
||||
else
|
||||
type = "soft";
|
||||
} else
|
||||
type = "hard";
|
||||
if (time_before(now, deadline)) {
|
||||
unsigned long delta = deadline - jiffies;
|
||||
|
||||
ata_port_printk(ap, KERN_WARNING,
|
||||
"%sreset failed, retrying in 5 secs\n", type);
|
||||
ssleep(5);
|
||||
ata_port_printk(ap, KERN_WARNING, "reset failed "
|
||||
"(errno=%d), retrying in %u secs\n",
|
||||
rc, (jiffies_to_msecs(delta) + 999) / 1000);
|
||||
|
||||
if (reset == hardreset)
|
||||
schedule_timeout_uninterruptible(delta);
|
||||
}
|
||||
|
||||
if (reset == hardreset &&
|
||||
try == ARRAY_SIZE(ata_eh_reset_timeouts) - 1)
|
||||
sata_down_spd_limit(ap);
|
||||
if (hardreset)
|
||||
reset = hardreset;
|
||||
|
|
|
@ -121,12 +121,13 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
|
|||
/**
|
||||
* amd_probe_init - perform reset handling
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Reset sequence checking enable bits to see which ports are
|
||||
* active.
|
||||
*/
|
||||
|
||||
static int amd_pre_reset(struct ata_port *ap)
|
||||
static int amd_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits amd_enable_bits[] = {
|
||||
{ 0x40, 1, 0x02, 0x02 },
|
||||
|
@ -138,8 +139,7 @@ static int amd_pre_reset(struct ata_port *ap)
|
|||
if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
static void amd_error_handler(struct ata_port *ap)
|
||||
|
@ -227,7 +227,8 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||
* space for us.
|
||||
*/
|
||||
|
||||
static int nv_pre_reset(struct ata_port *ap) {
|
||||
static int nv_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits nv_enable_bits[] = {
|
||||
{ 0x50, 1, 0x02, 0x02 },
|
||||
{ 0x50, 1, 0x01, 0x01 }
|
||||
|
@ -238,7 +239,7 @@ static int nv_pre_reset(struct ata_port *ap) {
|
|||
if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
static void nv_error_handler(struct ata_port *ap)
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
static int clock = 0;
|
||||
|
||||
static int artop6210_pre_reset(struct ata_port *ap)
|
||||
static int artop6210_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
const struct pci_bits artop_enable_bits[] = {
|
||||
|
@ -49,7 +49,8 @@ static int artop6210_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,12 +71,13 @@ static void artop6210_error_handler(struct ata_port *ap)
|
|||
/**
|
||||
* artop6260_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* The ARTOP hardware reports the cable detect bits in register 0x49.
|
||||
* Nothing complicated needed here.
|
||||
*/
|
||||
|
||||
static int artop6260_pre_reset(struct ata_port *ap)
|
||||
static int artop6260_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits artop_enable_bits[] = {
|
||||
{ 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */
|
||||
|
@ -87,7 +89,8 @@ static int artop6260_pre_reset(struct ata_port *ap)
|
|||
/* Odd numbered device ids are the units with enable bits (the -R cards) */
|
||||
if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,7 @@ enum {
|
|||
ATIIXP_IDE_UDMA_MODE = 0x56
|
||||
};
|
||||
|
||||
static int atiixp_pre_reset(struct ata_port *ap)
|
||||
static int atiixp_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits atiixp_enable_bits[] = {
|
||||
{ 0x48, 1, 0x01, 0x00 },
|
||||
|
@ -44,7 +44,7 @@ static int atiixp_pre_reset(struct ata_port *ap)
|
|||
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
static void atiixp_error_handler(struct ata_port *ap)
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
/**
|
||||
* cs5535_cable_detect - detect cable type
|
||||
* @ap: Port to detect on
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform cable detection for ATA66 capable cable. Return a libata
|
||||
* cable type.
|
||||
|
|
|
@ -27,12 +27,13 @@
|
|||
/**
|
||||
* efar_pre_reset - Enable bits
|
||||
* @ap: Port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform cable detection for the EFAR ATA interface. This is
|
||||
* different to the PIIX arrangement
|
||||
*/
|
||||
|
||||
static int efar_pre_reset(struct ata_port *ap)
|
||||
static int efar_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits efar_enable_bits[] = {
|
||||
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
|
||||
|
@ -43,7 +44,7 @@ static int efar_pre_reset(struct ata_port *ap)
|
|||
if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -220,7 +220,7 @@ static int hpt36x_cable_detect(struct ata_port *ap)
|
|||
return ATA_CBL_PATA80;
|
||||
}
|
||||
|
||||
static int hpt36x_pre_reset(struct ata_port *ap)
|
||||
static int hpt36x_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits hpt36x_enable_bits[] = {
|
||||
{ 0x50, 1, 0x04, 0x04 },
|
||||
|
@ -231,7 +231,7 @@ static int hpt36x_pre_reset(struct ata_port *ap)
|
|||
if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -307,11 +307,12 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
|
|||
/**
|
||||
* hpt37x_pre_reset - reset the hpt37x bus
|
||||
* @ap: ATA port to reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the initial reset handling for the 370/372 and 374 func 0
|
||||
*/
|
||||
|
||||
static int hpt37x_pre_reset(struct ata_port *ap)
|
||||
static int hpt37x_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
u8 scr2, ata66;
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
|
@ -338,7 +339,7 @@ static int hpt37x_pre_reset(struct ata_port *ap)
|
|||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -353,7 +354,7 @@ static void hpt37x_error_handler(struct ata_port *ap)
|
|||
ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
|
||||
}
|
||||
|
||||
static int hpt374_pre_reset(struct ata_port *ap)
|
||||
static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits hpt37x_enable_bits[] = {
|
||||
{ 0x50, 1, 0x04, 0x04 },
|
||||
|
@ -388,7 +389,7 @@ static int hpt374_pre_reset(struct ata_port *ap)
|
|||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -148,13 +148,14 @@ static int hpt3x2n_cable_detect(struct ata_port *ap)
|
|||
* Reset the hardware and state machine,
|
||||
*/
|
||||
|
||||
static int hpt3xn_pre_reset(struct ata_port *ap)
|
||||
static int hpt3xn_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
/* Reset the state machine */
|
||||
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
|
||||
udelay(100);
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,12 +24,13 @@
|
|||
/**
|
||||
* it8213_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Filter out ports by the enable bits before doing the normal reset
|
||||
* and probe.
|
||||
*/
|
||||
|
||||
static int it8213_pre_reset(struct ata_port *ap)
|
||||
static int it8213_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits it8213_enable_bits[] = {
|
||||
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
|
||||
|
@ -37,7 +38,8 @@ static int it8213_pre_reset(struct ata_port *ap)
|
|||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,16 +30,17 @@ typedef enum {
|
|||
/**
|
||||
* jmicron_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the PATA port setup we need.
|
||||
|
||||
*
|
||||
* On the Jmicron 361/363 there is a single PATA port that can be mapped
|
||||
* either as primary or secondary (or neither). We don't do any policy
|
||||
* and setup here. We assume that has been done by init_one and the
|
||||
* BIOS.
|
||||
*/
|
||||
|
||||
static int jmicron_pre_reset(struct ata_port *ap)
|
||||
static int jmicron_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 control;
|
||||
|
@ -102,7 +103,7 @@ static int jmicron_pre_reset(struct ata_port *ap)
|
|||
ap->cbl = ATA_CBL_SATA;
|
||||
break;
|
||||
}
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,11 +25,12 @@
|
|||
/**
|
||||
* marvell_pre_reset - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the PATA port setup we need.
|
||||
*/
|
||||
|
||||
static int marvell_pre_reset(struct ata_port *ap)
|
||||
static int marvell_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
u32 devices;
|
||||
|
@ -52,7 +53,8 @@ static int marvell_pre_reset(struct ata_port *ap)
|
|||
if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
|
||||
(!(devices & 0x10))) /* PATA enable ? */
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
static int marvell_cable_detect(struct ata_port *ap)
|
||||
|
@ -67,6 +69,7 @@ static int marvell_cable_detect(struct ata_port *ap)
|
|||
case 1: /* Legacy SATA port */
|
||||
return ATA_CBL_SATA;
|
||||
}
|
||||
|
||||
BUG();
|
||||
return 0; /* Our BUG macro needs the right markup */
|
||||
}
|
||||
|
|
|
@ -46,14 +46,15 @@ enum {
|
|||
SECONDARY = (1 << 14)
|
||||
};
|
||||
|
||||
static int mpiix_pre_reset(struct ata_port *ap)
|
||||
static int mpiix_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits mpiix_enable_bits = { 0x6D, 1, 0x80, 0x80 };
|
||||
|
||||
if (!pci_test_config_bits(pdev, &mpiix_enable_bits))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,11 +33,12 @@
|
|||
/**
|
||||
* ns87410_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Check enabled ports
|
||||
*/
|
||||
|
||||
static int ns87410_pre_reset(struct ata_port *ap)
|
||||
static int ns87410_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits ns87410_enable_bits[] = {
|
||||
|
@ -47,7 +48,8 @@ static int ns87410_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,11 +30,12 @@
|
|||
/**
|
||||
* oldpiix_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int oldpiix_pre_reset(struct ata_port *ap)
|
||||
static int oldpiix_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits oldpiix_enable_bits[] = {
|
||||
|
@ -44,7 +45,8 @@ static int oldpiix_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,11 +47,12 @@ enum {
|
|||
/**
|
||||
* opti_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int opti_pre_reset(struct ata_port *ap)
|
||||
static int opti_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits opti_enable_bits[] = {
|
||||
|
@ -61,7 +62,8 @@ static int opti_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,11 +48,12 @@ static int pci_clock; /* 0 = 33 1 = 25 */
|
|||
/**
|
||||
* optidma_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int optidma_pre_reset(struct ata_port *ap)
|
||||
static int optidma_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
static const struct pci_bits optidma_enable_bits = {
|
||||
|
@ -62,7 +63,7 @@ static int optidma_pre_reset(struct ata_port *ap)
|
|||
if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits))
|
||||
return -ENOENT;
|
||||
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -301,6 +301,7 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap)
|
|||
/**
|
||||
* pdc2027x_prereset - prereset for PATA host controller
|
||||
* @ap: Target port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Probeinit including cable detection.
|
||||
*
|
||||
|
@ -308,12 +309,12 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap)
|
|||
* None (inherited from caller).
|
||||
*/
|
||||
|
||||
static int pdc2027x_prereset(struct ata_port *ap)
|
||||
static int pdc2027x_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
/* Check whether port enabled */
|
||||
if (!pdc2027x_port_enabled(ap))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -139,12 +139,14 @@ static struct sv_cable_table cable_detect[] = {
|
|||
/**
|
||||
* serverworks_cable_detect - cable detection
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform cable detection according to the device and subvendor
|
||||
* identifications
|
||||
*/
|
||||
|
||||
static int serverworks_cable_detect(struct ata_port *ap) {
|
||||
static int serverworks_cable_detect(struct ata_port *ap)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
struct sv_cable_table *cb = cable_detect;
|
||||
|
||||
|
|
|
@ -94,11 +94,13 @@ static int sil680_cable_detect(struct ata_port *ap) {
|
|||
/**
|
||||
* sil680_bus_reset - reset the SIL680 bus
|
||||
* @ap: ATA port to reset
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform the SIL680 housekeeping when doing an ATA bus reset
|
||||
*/
|
||||
|
||||
static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes)
|
||||
static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes,
|
||||
unsigned long deadline)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
|
||||
unsigned long addr = sil680_selreg(ap, 0);
|
||||
|
@ -108,7 +110,7 @@ static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes)
|
|||
pci_write_config_byte(pdev, addr, reset | 0x03);
|
||||
udelay(25);
|
||||
pci_write_config_byte(pdev, addr, reset);
|
||||
return ata_std_softreset(ap, classes);
|
||||
return ata_std_softreset(ap, classes, deadline);
|
||||
}
|
||||
|
||||
static void sil680_error_handler(struct ata_port *ap)
|
||||
|
|
|
@ -88,6 +88,7 @@ static int sis_port_base(struct ata_device *adev)
|
|||
/**
|
||||
* sis_133_cable_detect - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform cable detection for the later UDMA133 capable
|
||||
* SiS chipset.
|
||||
|
@ -108,6 +109,7 @@ static int sis_133_cable_detect(struct ata_port *ap)
|
|||
/**
|
||||
* sis_66_cable_detect - check for 40/80 pin
|
||||
* @ap: Port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Perform cable detection on the UDMA66, UDMA100 and early UDMA133
|
||||
* SiS IDE controllers.
|
||||
|
@ -130,11 +132,12 @@ static int sis_66_cable_detect(struct ata_port *ap)
|
|||
/**
|
||||
* sis_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int sis_pre_reset(struct ata_port *ap)
|
||||
static int sis_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits sis_enable_bits[] = {
|
||||
{ 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */
|
||||
|
@ -145,7 +148,8 @@ static int sis_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -44,11 +44,12 @@ enum {
|
|||
/**
|
||||
* sl82c105_pre_reset - probe begin
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int sl82c105_pre_reset(struct ata_port *ap)
|
||||
static int sl82c105_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits sl82c105_enable_bits[] = {
|
||||
{ 0x40, 1, 0x01, 0x01 },
|
||||
|
@ -58,7 +59,7 @@ static int sl82c105_pre_reset(struct ata_port *ap)
|
|||
|
||||
if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,11 +48,12 @@
|
|||
/**
|
||||
* triflex_prereset - probe begin
|
||||
* @ap: ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* Set up cable type and use generic probe init
|
||||
*/
|
||||
|
||||
static int triflex_prereset(struct ata_port *ap)
|
||||
static int triflex_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
static const struct pci_bits triflex_enable_bits[] = {
|
||||
{ 0x80, 1, 0x01, 0x01 },
|
||||
|
@ -63,7 +64,8 @@ static int triflex_prereset(struct ata_port *ap)
|
|||
|
||||
if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ static int via_cable_detect(struct ata_port *ap) {
|
|||
return ATA_CBL_PATA40;
|
||||
}
|
||||
|
||||
static int via_pre_reset(struct ata_port *ap)
|
||||
static int via_pre_reset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
const struct via_isa_bridge *config = ap->host->private_data;
|
||||
|
||||
|
@ -167,7 +167,8 @@ static int via_pre_reset(struct ata_port *ap)
|
|||
if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no]))
|
||||
return -ENOENT;
|
||||
}
|
||||
return ata_std_prereset(ap);
|
||||
|
||||
return ata_std_prereset(ap, deadline);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -420,7 +420,8 @@ static void inic_thaw(struct ata_port *ap)
|
|||
* SRST and SControl hardreset don't give valid signature on this
|
||||
* controller. Only controller specific hardreset mechanism works.
|
||||
*/
|
||||
static int inic_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
static int inic_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
void __iomem *port_base = inic_port_base(ap);
|
||||
void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
|
||||
|
@ -437,7 +438,7 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
msleep(1);
|
||||
writew(val & ~IDMA_CTL_RST_ATA, idma_ctl);
|
||||
|
||||
rc = sata_phy_resume(ap, timing);
|
||||
rc = sata_phy_resume(ap, timing, deadline);
|
||||
if (rc) {
|
||||
ata_port_printk(ap, KERN_WARNING, "failed to resume "
|
||||
"link after reset (errno=%d)\n", rc);
|
||||
|
@ -451,10 +452,12 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
/* wait a while before checking status */
|
||||
msleep(150);
|
||||
|
||||
if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
|
||||
ata_port_printk(ap, KERN_WARNING,
|
||||
"device busy after hardreset\n");
|
||||
return -EIO;
|
||||
rc = ata_wait_ready(ap, deadline);
|
||||
/* link occupied, -ENODEV too is an error */
|
||||
if (rc) {
|
||||
ata_port_printk(ap, KERN_WARNING, "device not ready "
|
||||
"after hardreset (errno=%d)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
ata_tf_read(ap, &tf);
|
||||
|
|
|
@ -1405,7 +1405,8 @@ static void nv_ck804_thaw(struct ata_port *ap)
|
|||
writeb(mask, mmio_base + NV_INT_ENABLE_CK804);
|
||||
}
|
||||
|
||||
static int nv_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
static int nv_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
unsigned int dummy;
|
||||
|
||||
|
@ -1413,7 +1414,7 @@ static int nv_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
* some controllers. Don't classify on hardreset. For more
|
||||
* info, see http://bugme.osdl.org/show_bug.cgi?id=3352
|
||||
*/
|
||||
return sata_std_hardreset(ap, &dummy);
|
||||
return sata_std_hardreset(ap, &dummy, deadline);
|
||||
}
|
||||
|
||||
static void nv_error_handler(struct ata_port *ap)
|
||||
|
|
|
@ -534,7 +534,8 @@ static int sil24_init_port(struct ata_port *ap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sil24_softreset(struct ata_port *ap, unsigned int *class)
|
||||
static int sil24_softreset(struct ata_port *ap, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
struct sil24_port_priv *pp = ap->private_data;
|
||||
|
@ -566,7 +567,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
|
|||
|
||||
mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
|
||||
irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0,
|
||||
100, ATA_TMOUT_BOOT / HZ * 1000);
|
||||
100, jiffies_to_msecs(deadline - jiffies));
|
||||
|
||||
writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */
|
||||
irq_stat >>= PORT_IRQ_RAW_SHIFT;
|
||||
|
@ -594,7 +595,8 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
|
||||
static int sil24_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
void __iomem *port = ap->ioaddr.cmd_addr;
|
||||
const char *reason;
|
||||
|
@ -615,7 +617,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
|
|||
/* SStatus oscillates between zero and valid status after
|
||||
* DEV_RST, debounce it.
|
||||
*/
|
||||
rc = sata_phy_debounce(ap, sata_deb_timing_long);
|
||||
rc = sata_phy_debounce(ap, sata_deb_timing_long, deadline);
|
||||
if (rc) {
|
||||
reason = "PHY debouncing failed";
|
||||
goto err;
|
||||
|
|
|
@ -268,6 +268,7 @@ static void svia_noop_freeze(struct ata_port *ap)
|
|||
/**
|
||||
* vt6420_prereset - prereset for vt6420
|
||||
* @ap: target ATA port
|
||||
* @deadline: deadline jiffies for the operation
|
||||
*
|
||||
* SCR registers on vt6420 are pieces of shit and may hang the
|
||||
* whole machine completely if accessed with the wrong timing.
|
||||
|
@ -284,7 +285,7 @@ static void svia_noop_freeze(struct ata_port *ap)
|
|||
* RETURNS:
|
||||
* 0 on success, -errno otherwise.
|
||||
*/
|
||||
static int vt6420_prereset(struct ata_port *ap)
|
||||
static int vt6420_prereset(struct ata_port *ap, unsigned long deadline)
|
||||
{
|
||||
struct ata_eh_context *ehc = &ap->eh_context;
|
||||
unsigned long timeout = jiffies + (HZ * 5);
|
||||
|
@ -329,7 +330,7 @@ static int vt6420_prereset(struct ata_port *ap)
|
|||
|
||||
skip_scr:
|
||||
/* wait for !BSY */
|
||||
ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
|
||||
ata_wait_ready(ap, deadline);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -296,18 +296,8 @@ enum {
|
|||
|
||||
/* how hard are we gonna try to probe/recover devices */
|
||||
ATA_PROBE_MAX_TRIES = 3,
|
||||
ATA_EH_RESET_TRIES = 3,
|
||||
ATA_EH_DEV_TRIES = 3,
|
||||
|
||||
/* Drive spinup time (time from power-on to the first D2H FIS)
|
||||
* in msecs - 8s currently. Failing to get ready in this time
|
||||
* isn't critical. It will result in reset failure for
|
||||
* controllers which can't wait for the first D2H FIS. libata
|
||||
* will retry, so it just has to be long enough to spin up
|
||||
* most devices.
|
||||
*/
|
||||
ATA_SPINUP_WAIT = 8000,
|
||||
|
||||
/* Horkage types. May be set by libata or controller on drives
|
||||
(some horkage may be drive/controller pair dependant */
|
||||
|
||||
|
@ -348,8 +338,9 @@ struct ata_queued_cmd;
|
|||
|
||||
/* typedefs */
|
||||
typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
|
||||
typedef int (*ata_prereset_fn_t)(struct ata_port *ap);
|
||||
typedef int (*ata_reset_fn_t)(struct ata_port *ap, unsigned int *classes);
|
||||
typedef int (*ata_prereset_fn_t)(struct ata_port *ap, unsigned long deadline);
|
||||
typedef int (*ata_reset_fn_t)(struct ata_port *ap, unsigned int *classes,
|
||||
unsigned long deadline);
|
||||
typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *classes);
|
||||
|
||||
struct ata_ioports {
|
||||
|
@ -494,7 +485,6 @@ struct ata_eh_info {
|
|||
unsigned int dev_action[ATA_MAX_DEVICES]; /* dev EH action */
|
||||
unsigned int flags; /* ATA_EHI_* flags */
|
||||
|
||||
unsigned long hotplug_timestamp;
|
||||
unsigned int probe_mask;
|
||||
|
||||
char desc[ATA_EH_DESC_LEN];
|
||||
|
@ -688,13 +678,17 @@ extern void __sata_phy_reset(struct ata_port *ap);
|
|||
extern void sata_phy_reset(struct ata_port *ap);
|
||||
extern void ata_bus_reset(struct ata_port *ap);
|
||||
extern int sata_set_spd(struct ata_port *ap);
|
||||
extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param);
|
||||
extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param);
|
||||
extern int ata_std_prereset(struct ata_port *ap);
|
||||
extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
|
||||
extern int sata_port_hardreset(struct ata_port *ap,
|
||||
const unsigned long *timing);
|
||||
extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class);
|
||||
extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param,
|
||||
unsigned long deadline);
|
||||
extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param,
|
||||
unsigned long deadline);
|
||||
extern int ata_std_prereset(struct ata_port *ap, unsigned long deadline);
|
||||
extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
|
||||
unsigned long deadline);
|
||||
extern int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing,
|
||||
unsigned long deadline);
|
||||
extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class,
|
||||
unsigned long deadline);
|
||||
extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
|
||||
extern void ata_port_disable(struct ata_port *);
|
||||
extern void ata_std_ports(struct ata_ioports *ioaddr);
|
||||
|
@ -750,6 +744,7 @@ extern void ata_host_resume(struct ata_host *host);
|
|||
extern int ata_ratelimit(void);
|
||||
extern int ata_busy_sleep(struct ata_port *ap,
|
||||
unsigned long timeout_pat, unsigned long timeout);
|
||||
extern int ata_wait_ready(struct ata_port *ap, unsigned long deadline);
|
||||
extern void ata_port_queue_task(struct ata_port *ap, work_func_t fn,
|
||||
void *data, unsigned long delay);
|
||||
extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
|
||||
|
@ -919,12 +914,7 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
|
|||
|
||||
static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi)
|
||||
{
|
||||
if (ehi->flags & ATA_EHI_HOTPLUGGED)
|
||||
return;
|
||||
|
||||
ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK;
|
||||
ehi->hotplug_timestamp = jiffies;
|
||||
|
||||
ehi->action |= ATA_EH_SOFTRESET;
|
||||
ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue