Commit 88e6c949 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: (28 commits)
  drivers/ata: trim trailing whitespace
  Fixups to ATA ACPI hotplug
  libata: ignore SIMG4726 config pseudo device
  sata_sil24: don't use NCQ if marvell 4140 PMP is attached
  libata: don't schedule LPM action seperately during probing
  libata: make sure PMP notification is turned off during recovery
  libata: increase PMP register access timeout to 3s
  libata: ignore recovered PHY errors
  libata: kill hotplug related race condition
  libata: move reset freeze/thaw handling into ata_eh_reset()
  libata: reorganize ata_eh_reset() no reset method path
  libata: fix sata_link_hardreset() @online out parameter handling
  sata_promise: other cleanups
  sata_promise: mmio access cleanups
  sata_promise: fix irq clearing buglets
  ata: remove FIT() macro
  sata_mv: ensure empty request queue for FBS-NCQ EH
  sata_mv: cache main_irq_mask register in hpriv
  sata_mv: disregard masked irqs
  sata_mv: fix pmp drives not found
  ...
parents 8c4bab3a c85665ff
...@@ -118,8 +118,8 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) ...@@ -118,8 +118,8 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
} }
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device
u32 event) *dev, u32 event)
{ {
char event_string[12]; char event_string[12];
char *envp[] = { event_string, NULL }; char *envp[] = { event_string, NULL };
...@@ -127,6 +127,9 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, ...@@ -127,6 +127,9 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
struct kobject *kobj = NULL; struct kobject *kobj = NULL;
int wait = 0; int wait = 0;
unsigned long flags; unsigned long flags;
acpi_handle handle, tmphandle;
unsigned long sta;
acpi_status status;
if (!ap) if (!ap)
ap = dev->link->ap; ap = dev->link->ap;
...@@ -134,32 +137,57 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, ...@@ -134,32 +137,57 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
spin_lock_irqsave(ap->lock, flags); spin_lock_irqsave(ap->lock, flags);
if (dev)
handle = dev->acpi_handle;
else
handle = ap->acpi_handle;
status = acpi_get_handle(handle, "_EJ0", &tmphandle);
if (ACPI_FAILURE(status)) {
/* This device is not ejectable */
spin_unlock_irqrestore(ap->lock, flags);
return;
}
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
if (ACPI_FAILURE(status)) {
printk ("Unable to determine bay status\n");
spin_unlock_irqrestore(ap->lock, flags);
return;
}
switch (event) { switch (event) {
case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK: case ACPI_NOTIFY_DEVICE_CHECK:
ata_ehi_push_desc(ehi, "ACPI event"); ata_ehi_push_desc(ehi, "ACPI event");
ata_ehi_hotplugged(ehi); if (!sta) {
ata_port_freeze(ap); /* Device has been unplugged */
break; if (dev)
dev->flags |= ATA_DFLAG_DETACH;
case ACPI_NOTIFY_EJECT_REQUEST: else {
ata_ehi_push_desc(ehi, "ACPI event"); struct ata_link *tlink;
if (dev) struct ata_device *tdev;
dev->flags |= ATA_DFLAG_DETACH;
else { ata_port_for_each_link(tlink, ap) {
struct ata_link *tlink; ata_link_for_each_dev(tdev, tlink) {
struct ata_device *tdev; tdev->flags |=
ATA_DFLAG_DETACH;
ata_port_for_each_link(tlink, ap) }
ata_link_for_each_dev(tdev, tlink) }
tdev->flags |= ATA_DFLAG_DETACH; }
ata_port_schedule_eh(ap);
wait = 1;
} else {
ata_ehi_hotplugged(ehi);
ata_port_freeze(ap);
} }
ata_port_schedule_eh(ap);
wait = 1;
break;
} }
spin_unlock_irqrestore(ap->lock, flags);
if (wait)
ata_port_wait_eh(ap);
if (dev) { if (dev) {
if (dev->sdev) if (dev->sdev)
kobj = &dev->sdev->sdev_gendev.kobj; kobj = &dev->sdev->sdev_gendev.kobj;
...@@ -170,11 +198,6 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, ...@@ -170,11 +198,6 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
sprintf(event_string, "BAY_EVENT=%d", event); sprintf(event_string, "BAY_EVENT=%d", event);
kobject_uevent_env(kobj, KOBJ_CHANGE, envp); kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
} }
spin_unlock_irqrestore(ap->lock, flags);
if (wait)
ata_port_wait_eh(ap);
} }
static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
......
...@@ -2126,6 +2126,13 @@ int ata_dev_configure(struct ata_device *dev) ...@@ -2126,6 +2126,13 @@ int ata_dev_configure(struct ata_device *dev)
dev->horkage |= ata_dev_blacklisted(dev); dev->horkage |= ata_dev_blacklisted(dev);
ata_force_horkage(dev); ata_force_horkage(dev);
if (dev->horkage & ATA_HORKAGE_DISABLE) {
ata_dev_printk(dev, KERN_INFO,
"unsupported device, disabling\n");
ata_dev_disable(dev);
return 0;
}
/* let ACPI work its magic */ /* let ACPI work its magic */
rc = ata_acpi_on_devcfg(dev); rc = ata_acpi_on_devcfg(dev);
if (rc) if (rc)
...@@ -3490,22 +3497,11 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, ...@@ -3490,22 +3497,11 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,
if ((rc = sata_link_debounce(link, params, deadline))) if ((rc = sata_link_debounce(link, params, deadline)))
return rc; return rc;
/* Clear SError. PMP and some host PHYs require this to /* clear SError, some PHYs require this even for SRST to work */
* operate and clearing should be done before checking PHY
* online status to avoid race condition (hotplugging between
* link resume and status check).
*/
if (!(rc = sata_scr_read(link, SCR_ERROR, &serror))) if (!(rc = sata_scr_read(link, SCR_ERROR, &serror)))
rc = sata_scr_write(link, SCR_ERROR, serror); rc = sata_scr_write(link, SCR_ERROR, serror);
if (rc == 0 || rc == -EINVAL) {
unsigned long flags;
spin_lock_irqsave(link->ap->lock, flags); return rc != -EINVAL ? rc : 0;
link->eh_info.serror = 0;
spin_unlock_irqrestore(link->ap->lock, flags);
rc = 0;
}
return rc;
} }
/** /**
...@@ -3653,9 +3649,13 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, ...@@ -3653,9 +3649,13 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
if (check_ready) if (check_ready)
rc = ata_wait_ready(link, deadline, check_ready); rc = ata_wait_ready(link, deadline, check_ready);
out: out:
if (rc && rc != -EAGAIN) if (rc && rc != -EAGAIN) {
/* online is set iff link is online && reset succeeded */
if (online)
*online = false;
ata_link_printk(link, KERN_ERR, ata_link_printk(link, KERN_ERR,
"COMRESET failed (errno=%d)\n", rc); "COMRESET failed (errno=%d)\n", rc);
}
DPRINTK("EXIT, rc=%d\n", rc); DPRINTK("EXIT, rc=%d\n", rc);
return rc; return rc;
} }
...@@ -3700,8 +3700,14 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class, ...@@ -3700,8 +3700,14 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class,
*/ */
void ata_std_postreset(struct ata_link *link, unsigned int *classes) void ata_std_postreset(struct ata_link *link, unsigned int *classes)
{ {
u32 serror;
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
/* reset complete, clear SError */
if (!sata_scr_read(link, SCR_ERROR, &serror))
sata_scr_write(link, SCR_ERROR, serror);
/* print link status */ /* print link status */
sata_print_link_status(link); sata_print_link_status(link);
...@@ -3894,8 +3900,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ...@@ -3894,8 +3900,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA },
{ "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
/* Odd clown on sil3726/4726 PMPs */ /* Odd clown on sil3726/4726 PMPs */
{ "Config Disk", NULL, ATA_HORKAGE_NODMA | { "Config Disk", NULL, ATA_HORKAGE_DISABLE },
ATA_HORKAGE_SKIP_PM },
/* Weird ATAPI devices */ /* Weird ATAPI devices */
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
...@@ -5616,7 +5621,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) ...@@ -5616,7 +5621,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
spin_lock_irqsave(ap->lock, flags); spin_lock_irqsave(ap->lock, flags);
ehi->probe_mask |= ATA_ALL_DEVICES; ehi->probe_mask |= ATA_ALL_DEVICES;
ehi->action |= ATA_EH_RESET; ehi->action |= ATA_EH_RESET | ATA_EH_LPM;
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
ap->pflags &= ~ATA_PFLAG_INITIALIZING; ap->pflags &= ~ATA_PFLAG_INITIALIZING;
...@@ -5649,7 +5654,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) ...@@ -5649,7 +5654,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
struct ata_port *ap = host->ports[i]; struct ata_port *ap = host->ports[i];
ata_scsi_scan_host(ap, 1); ata_scsi_scan_host(ap, 1);
ata_lpm_schedule(ap, ap->pm_policy);
} }
return 0; return 0;
......
...@@ -1308,12 +1308,7 @@ static void ata_eh_analyze_serror(struct ata_link *link) ...@@ -1308,12 +1308,7 @@ static void ata_eh_analyze_serror(struct ata_link *link)
unsigned int err_mask = 0, action = 0; unsigned int err_mask = 0, action = 0;
u32 hotplug_mask; u32 hotplug_mask;
if (serror & SERR_PERSISTENT) { if (serror & (SERR_PERSISTENT | SERR_DATA)) {
err_mask |= AC_ERR_ATA_BUS;
action |= ATA_EH_RESET;
}
if (serror &
(SERR_DATA_RECOVERED | SERR_COMM_RECOVERED | SERR_DATA)) {
err_mask |= AC_ERR_ATA_BUS; err_mask |= AC_ERR_ATA_BUS;
action |= ATA_EH_RESET; action |= ATA_EH_RESET;
} }
...@@ -2047,19 +2042,11 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset, ...@@ -2047,19 +2042,11 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
unsigned int *classes, unsigned long deadline) unsigned int *classes, unsigned long deadline)
{ {
struct ata_device *dev; struct ata_device *dev;
int rc;
ata_link_for_each_dev(dev, link) ata_link_for_each_dev(dev, link)
classes[dev->devno] = ATA_DEV_UNKNOWN; classes[dev->devno] = ATA_DEV_UNKNOWN;
rc = reset(link, classes, deadline); return reset(link, classes, deadline);
/* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
ata_link_for_each_dev(dev, link)
if (classes[dev->devno] == ATA_DEV_UNKNOWN)
classes[dev->devno] = ATA_DEV_NONE;
return rc;
} }
static int ata_eh_followup_srst_needed(struct ata_link *link, static int ata_eh_followup_srst_needed(struct ata_link *link,
...@@ -2096,9 +2083,11 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2096,9 +2083,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
ata_reset_fn_t reset; ata_reset_fn_t reset;
unsigned long flags; unsigned long flags;
u32 sstatus; u32 sstatus;
int rc; int nr_known, rc;
/* about to reset */ /*
* Prepare to reset
*/
spin_lock_irqsave(ap->lock, flags); spin_lock_irqsave(ap->lock, flags);
ap->pflags |= ATA_PFLAG_RESETTING; ap->pflags |= ATA_PFLAG_RESETTING;
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
...@@ -2124,16 +2113,8 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2124,16 +2113,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
ap->ops->set_piomode(ap, dev); ap->ops->set_piomode(ap, dev);
} }
if (!softreset && !hardreset) {
if (verbose)
ata_link_printk(link, KERN_INFO, "no reset method "
"available, skipping reset\n");
if (!(lflags & ATA_LFLAG_ASSUME_CLASS))
lflags |= ATA_LFLAG_ASSUME_ATA;
goto done;
}
/* prefer hardreset */ /* prefer hardreset */
reset = NULL;
ehc->i.action &= ~ATA_EH_RESET; ehc->i.action &= ~ATA_EH_RESET;
if (hardreset) { if (hardreset) {
reset = hardreset; reset = hardreset;
...@@ -2141,11 +2122,6 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2141,11 +2122,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
} else if (softreset) { } else if (softreset) {
reset = softreset; reset = softreset;
ehc->i.action = ATA_EH_SOFTRESET; ehc->i.action = ATA_EH_SOFTRESET;
} else {
ata_link_printk(link, KERN_ERR, "BUG: no reset method, "
"please report to linux-ide@vger.kernel.org\n");
dump_stack();
return -EINVAL;
} }
if (prereset) { if (prereset) {
...@@ -2165,55 +2141,71 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2165,55 +2141,71 @@ int ata_eh_reset(struct ata_link *link, int classify,
"prereset failed (errno=%d)\n", rc); "prereset failed (errno=%d)\n", rc);
goto out; goto out;
} }
}
/* prereset() might have cleared ATA_EH_RESET */ /* prereset() might have cleared ATA_EH_RESET. If so,
if (!(ehc->i.action & ATA_EH_RESET)) { * bang classes and return.
/* prereset told us not to reset, bang classes and return */ */
ata_link_for_each_dev(dev, link) if (reset && !(ehc->i.action & ATA_EH_RESET)) {
classes[dev->devno] = ATA_DEV_NONE; ata_link_for_each_dev(dev, link)
rc = 0; classes[dev->devno] = ATA_DEV_NONE;
goto out; rc = 0;
goto out;
}
} }
retry: retry:
/*
* Perform reset
*/
if (ata_is_host_link(link))
ata_eh_freeze_port(ap);
deadline = jiffies + ata_eh_reset_timeouts[try++]; deadline = jiffies + ata_eh_reset_timeouts[try++];
/* shut up during boot probing */ if (reset) {
if (verbose) if (verbose)
ata_link_printk(link, KERN_INFO, "%s resetting link\n", ata_link_printk(link, KERN_INFO, "%s resetting link\n",
reset == softreset ? "soft" : "hard"); reset == softreset ? "soft" : "hard");
/* mark that this EH session started with reset */ /* mark that this EH session started with reset */
if (reset == hardreset) if (reset == hardreset)
ehc->i.flags |= ATA_EHI_DID_HARDRESET; ehc->i.flags |= ATA_EHI_DID_HARDRESET;
else else
ehc->i.flags |= ATA_EHI_DID_SOFTRESET; ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
rc = ata_do_reset(link, reset, classes, deadline); rc = ata_do_reset(link, reset, classes, deadline);
if (reset == hardreset && if (reset == hardreset &&
ata_eh_followup_srst_needed(link, rc, classify, classes)) { ata_eh_followup_srst_needed(link, rc, classify, classes)) {
/* okay, let's do follow-up softreset */ /* okay, let's do follow-up softreset */
reset = softreset; reset = softreset;
if (!reset) { if (!reset) {
ata_link_printk(link, KERN_ERR, ata_link_printk(link, KERN_ERR,
"follow-up softreset required " "follow-up softreset required "
"but no softreset avaliable\n"); "but no softreset avaliable\n");
rc = -EINVAL; rc = -EINVAL;
goto fail; goto fail;
}
ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
rc = ata_do_reset(link, reset, classes, deadline);
} }
ata_eh_about_to_do(link, NULL, ATA_EH_RESET); /* -EAGAIN can happen if we skipped followup SRST */
rc = ata_do_reset(link, reset, classes, deadline); if (rc && rc != -EAGAIN)
goto fail;
} else {
if (verbose)
ata_link_printk(link, KERN_INFO, "no reset method "
"available, skipping reset\n");
if (!(lflags & ATA_LFLAG_ASSUME_CLASS))
lflags |= ATA_LFLAG_ASSUME_ATA;
} }
/* -EAGAIN can happen if we skipped followup SRST */ /*
if (rc && rc != -EAGAIN) * Post-reset processing
goto fail; */
done:
ata_link_for_each_dev(dev, link) { ata_link_for_each_dev(dev, link) {
/* After the reset, the device state is PIO 0 and the /* After the reset, the device state is PIO 0 and the
* controller state is undefined. Reset also wakes up * controller state is undefined. Reset also wakes up
...@@ -2236,9 +2228,53 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2236,9 +2228,53 @@ int ata_eh_reset(struct ata_link *link, int classify,
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0)
link->sata_spd = (sstatus >> 4) & 0xf; link->sata_spd = (sstatus >> 4) & 0xf;
/* thaw the port */
if (ata_is_host_link(link))
ata_eh_thaw_port(ap);
/* postreset() should clear hardware SError. Although SError
* is cleared during link resume, clearing SError here is
* necessary as some PHYs raise hotplug events after SRST.
* This introduces race condition where hotplug occurs between
* reset and here. This race is mediated by cross checking
* link onlineness and classification result later.
*/
if (postreset) if (postreset)
postreset(link, classes); postreset(link, classes);
/* clear cached SError */
spin_lock_irqsave(link->ap->lock, flags);
link->eh_info.serror = 0;
spin_unlock_irqrestore(link->ap->lock, flags);
/* Make sure onlineness and classification result correspond.
* Hotplug could have happened during reset and some
* controllers fail to wait while a drive is spinning up after
* being hotplugged causing misdetection. By cross checking
* link onlineness and classification result, those conditions
* can be reliably detected and retried.
*/
nr_known = 0;
ata_link_for_each_dev(dev, link) {
/* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
if (classes[dev->devno] == ATA_DEV_UNKNOWN)
classes[dev->devno] = ATA_DEV_NONE;
else
nr_known++;
}
if (classify && !nr_known && ata_link_online(link)) {
if (try < max_tries) {
ata_link_printk(link, KERN_WARNING, "link online but "
"device misclassified, retrying\n");
rc = -EAGAIN;
goto fail;
}
ata_link_printk(link, KERN_WARNING,
"link online but device misclassified, "
"device detection might fail\n");
}
/* reset successful, schedule revalidation */ /* reset successful, schedule revalidation */
ata_eh_done(link, NULL, ATA_EH_RESET); ata_eh_done(link, NULL, ATA_EH_RESET);
ehc->i.action |= ATA_EH_REVALIDATE; ehc->i.action |= ATA_EH_REVALIDATE;
...@@ -2587,7 +2623,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, ...@@ -2587,7 +2623,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
struct ata_link *link; struct ata_link *link;
struct ata_device *dev; struct ata_device *dev;
int nr_failed_devs, nr_disabled_devs; int nr_failed_devs, nr_disabled_devs;
int reset, rc; int rc;
unsigned long flags; unsigned long flags;
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
...@@ -2630,7 +2666,6 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, ...@@ -2630,7 +2666,6 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
rc = 0; rc = 0;
nr_failed_devs = 0; nr_failed_devs = 0;
nr_disabled_devs = 0; nr_disabled_devs = 0;
reset = 0;
/* if UNLOADING, finish immediately */ /* if UNLOADING, finish immediately */
if (ap->pflags & ATA_PFLAG_UNLOADING) if (ap->pflags & ATA_PFLAG_UNLOADING)
...@@ -2644,40 +2679,24 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, ...@@ -2644,40 +2679,24 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
if (ata_eh_skip_recovery(link)) if (ata_eh_skip_recovery(link))
ehc->i.action = 0; ehc->i.action = 0;
/* do we need to reset? */
if (ehc->i.action & ATA_EH_RESET)
reset = 1;
ata_link_for_each_dev(dev, link) ata_link_for_each_dev(dev, link)
ehc->classes[dev->devno] = ATA_DEV_UNKNOWN; ehc->classes[dev->devno] = ATA_DEV_UNKNOWN;
} }
/* reset */ /* reset */
if (reset) { ata_port_for_each_link(link, ap) {
/* if PMP is attached, this function only deals with struct ata_eh_context *ehc = &link->eh_context;
* downstream links, port should stay thawed.
*/
if (!sata_pmp_attached(ap))
ata_eh_freeze_port(ap);
ata_port_for_each_link(link, ap) {
struct ata_eh_context *ehc = &link->eh_context;
if (!(ehc->i.action & ATA_EH_RESET)) if (!(ehc->i.action & ATA_EH_RESET))
continue; continue;
rc = ata_eh_reset(link, ata_link_nr_vacant(link), rc = ata_eh_reset(link, ata_link_nr_vacant(link),
prereset, softreset, hardreset, prereset, softreset, hardreset, postreset);
postreset); if (rc) {
if (rc) { ata_link_printk(link, KERN_ERR,
ata_link_printk(link, KERN_ERR, "reset failed, giving up\n");
"reset failed, giving up\n"); goto out;
goto out;
}
} }
if (!sata_pmp_attached(ap))
ata_eh_thaw_port(ap);
} }
/* the rest */ /* the rest */
......
...@@ -48,7 +48,7 @@ static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) ...@@ -48,7 +48,7 @@ static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val)
tf.device = link->pmp; tf.device = link->pmp;
err_mask = ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, err_mask = ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0,
SATA_PMP_SCR_TIMEOUT); SATA_PMP_RW_TIMEOUT);
if (err_mask) if (err_mask)
return err_mask; return err_mask;
...@@ -88,7 +88,7 @@ static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val) ...@@ -88,7 +88,7 @@ static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val)
tf.lbah = (val >> 24) & 0xff; tf.lbah = (val >> 24) & 0xff;
return ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, return ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0,
SATA_PMP_SCR_TIMEOUT); SATA_PMP_RW_TIMEOUT);
} }
/** /**
...@@ -257,19 +257,6 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) ...@@ -257,19 +257,6 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info)
goto fail; goto fail;
} }
/* turn off notification till fan-out ports are reset and configured */
if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) {
gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY;
err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_FEAT_EN,
gscr[SATA_PMP_GSCR_FEAT_EN]);
if (err_mask) {
rc = -EIO;
reason = "failed to write GSCR_FEAT_EN";
goto fail;
}
}
if (print_info) { if (print_info) {
ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, " ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, "
"0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n", "0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n",
...@@ -700,8 +687,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, ...@@ -700,8 +687,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
if (ehc->i.action & ATA_EH_RESET) { if (ehc->i.action & ATA_EH_RESET) {
struct ata_link *tlink; struct ata_link *tlink;
ata_eh_freeze_port(ap);
/* reset */ /* reset */
rc = ata_eh_reset(link, 0, prereset, softreset, hardreset, rc = ata_eh_reset(link, 0, prereset, softreset, hardreset,
postreset); postreset);
...@@ -711,8 +696,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, ...@@ -711,8 +696,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
goto fail; goto fail;
} }
ata_eh_thaw_port(ap);
/* PMP is reset, SErrors cannot be trusted, scan all */ /* PMP is reset, SErrors cannot be trusted, scan all */
ata_port_for_each_link(tlink, ap) { ata_port_for_each_link(tlink, ap) {
struct ata_eh_context *ehc = &tlink->eh_context; struct ata_eh_context *ehc = &tlink->eh_context;
...@@ -864,6 +847,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap) ...@@ -864,6 +847,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
struct ata_link *pmp_link = &ap->link; struct ata_link *pmp_link = &ap->link;
struct ata_device *pmp_dev = pmp_link->device; struct ata_device *pmp_dev = pmp_link->device;
struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; struct ata_eh_context *pmp_ehc = &pmp_link->eh_context;
u32 *gscr = pmp_dev->gscr;
struct ata_link *link; struct ata_link *link;
struct ata_device *dev; struct ata_device *dev;
unsigned int err_mask; unsigned int err_mask;
...@@ -901,6 +885,22 @@ static int sata_pmp_eh_recover(struct ata_port *ap) ...@@ -901,6 +885,22 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
if (rc) if (rc)
goto pmp_fail; goto pmp_fail;
/* PHY event notification can disturb reset and other recovery
* operations. Turn it off.
*/
if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) {
gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY;
err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN,
gscr[SATA_PMP_GSCR_FEAT_EN]);
if (err_mask) {
ata_link_printk(pmp_link, KERN_WARNING,
"failed to disable NOTIFY (err_mask=0x%x)\n",
err_mask);
goto pmp_fail;
}
}
/* handle disabled links */ /* handle disabled links */
rc = sata_pmp_eh_handle_disabled_links(ap); rc = sata_pmp_eh_handle_disabled_links(ap);
if (rc) if (rc)
...@@ -923,10 +923,10 @@ static int sata_pmp_eh_recover(struct ata_port *ap) ...@@ -923,10 +923,10 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
/* enable notification */ /* enable notification */
if (pmp_dev->flags & ATA_DFLAG_AN) { if (pmp_dev->flags & ATA_DFLAG_AN) {
pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY;
err_mask = sata_pmp_write(pmp_dev->link, SATA_PMP_GSCR_FEAT_EN, err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN,
pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]); gscr[SATA_PMP_GSCR_FEAT_EN]);
if (err_mask) { if (err_mask) {
ata_dev_printk(pmp_dev, KERN_ERR, "failed to write " ata_dev_printk(pmp_dev, KERN_ERR, "failed to write "
"PMP_FEAT_EN (Emask=0x%x)\n", err_mask); "PMP_FEAT_EN (Emask=0x%x)\n", err_mask);
......
...@@ -1082,12 +1082,6 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) ...@@ -1082,12 +1082,6 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
if (((cdb[4] >> 4) & 0xf) != 0) if (((cdb[4] >> 4) & 0xf) != 0)
goto invalid_fld; /* power conditions not supported */ goto invalid_fld; /* power conditions not supported */
if (qc->dev->horkage & ATA_HORKAGE_SKIP_PM) {
/* the device lacks PM support, finish without doing anything */
scmd->result = SAM_STAT_GOOD;
return 1;
}
if (cdb[4] & 0x1) { if (cdb[4] & 0x1) {
tf->nsect = 1; /* 1 sector, lba=0 */ tf->nsect = 1; /* 1 sector, lba=0 */
......
...@@ -177,11 +177,11 @@ static void ali_program_modes(struct ata_port *ap, struct ata_device *adev, stru ...@@ -177,11 +177,11 @@ static void ali_program_modes(struct ata_port *ap, struct ata_device *adev, stru
u8 udma; u8 udma;
if (t != NULL) { if (t != NULL) {
t->setup = FIT(t->setup, 1, 8) & 7; t->setup = clamp_val(t->setup, 1, 8) & 7;
t->act8b = FIT(t->act8b, 1, 8) & 7; t->act8b = clamp_val(t->act8b, 1, 8) & 7;
t->rec8b = FIT(t->rec8b, 1, 16) & 15; t->rec8b = clamp_val(t->rec8b, 1, 16) & 15;
t->active = FIT(t->active, 1, 8) & 7; t->active = clamp_val(t->active, 1, 8) & 7;
t->recover = FIT(t->recover, 1, 16) & 15; t->recover = clamp_val(t->recover, 1, 16) & 15;
pci_write_config_byte(pdev, cas, t->setup); pci_write_config_byte(pdev, cas, t->setup);
pci_write_config_byte(pdev, cbt, (t->act8b << 4) | t->rec8b); pci_write_config_byte(pdev, cbt, (t->act8b << 4) | t->rec8b);
......
...@@ -84,32 +84,32 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse ...@@ -84,32 +84,32 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
/* Configure the address set up timing */ /* Configure the address set up timing */
pci_read_config_byte(pdev, offset + 0x0C, &t); pci_read_config_byte(pdev, offset + 0x0C, &t);
t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(at.setup, 1, 4) - 1) << ((3 - dn) << 1)); t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(at.setup, 1, 4) - 1) << ((3 - dn) << 1));
pci_write_config_byte(pdev, offset + 0x0C , t); pci_write_config_byte(pdev, offset + 0x0C , t);
/* Configure the 8bit I/O timing */ /* Configure the 8bit I/O timing */
pci_write_config_byte(pdev, offset + 0x0E + (1 - (dn >> 1)), pci_write_config_byte(pdev, offset + 0x0E + (1 - (dn >> 1)),
((FIT(at.act8b, 1, 16) - 1) << 4) | (FIT(at.rec8b, 1, 16) - 1)); ((clamp_val(at.act8b, 1, 16) - 1) << 4) | (clamp_val(at.rec8b, 1, 16) - 1));
/* Drive timing */ /* Drive timing */
pci_write_config_byte(pdev, offset + 0x08 + (3 - dn), pci_write_config_byte(pdev, offset + 0x08 + (3 - dn),
((FIT(at.active, 1, 16) - 1) << 4) | (FIT(at.recover, 1, 16) - 1)); ((clamp_val(at.active, 1, 16) - 1) << 4) | (clamp_val(at.recover, 1, 16) - 1));
switch (clock) { switch (clock) {
case 1: case 1:
t = at.udma ? (0xc0 | (FIT(at.udma, 2, 5) - 2)) : 0x03; t = at.udma ? (0xc0 | (clamp_val(at.udma, 2, 5) - 2)) : 0x03;
break; break;
case 2: case 2:
t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 2, 10)]) : 0x03; t = at.udma ? (0xc0 | amd_cyc2udma[clamp_val(at.udma, 2, 10)]) : 0x03;
break; break;
case 3: case 3:
t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 10)]) : 0x03; t = at.udma ? (0xc0 | amd_cyc2udma[clamp_val(at.udma, 1, 10)]) : 0x03;
break; break;
case 4: case 4:
t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 15)]) : 0x03; t = at.udma ? (0xc0 | amd_cyc2udma[clamp_val(at.udma, 1, 15)]) : 0x03;
break; break;
default: default:
......
...@@ -291,8 +291,6 @@ static int __init pata_at32_probe(struct platform_device *pdev) ...@@ -291,8 +291,6 @@ static int __init pata_at32_probe(struct platform_device *pdev)
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
memset(info, 0, sizeof(struct at32_ide_info));
info->irq = irq; info->irq = irq;
info->cs = board->cs; info->cs = board->cs;
......
...@@ -911,7 +911,10 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc) ...@@ -911,7 +911,10 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc)
/* Reset all transfer count */ /* Reset all transfer count */
ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | TFRCNT_RST); ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | TFRCNT_RST);
/* Set transfer length to buffer len */ /* Set ATAPI state machine contorl in terminate sequence */
ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | END_ON_TERM);
/* Set transfer length to buffer len */
for_each_sg(qc->sg, sg, qc->n_elem, si) { for_each_sg(qc->sg, sg, qc->n_elem, si) {
ATAPI_SET_XFER_LEN(base, (sg_dma_len(sg) >> 1)); ATAPI_SET_XFER_LEN(base, (sg_dma_len(sg) >> 1));
} }
......
...@@ -62,14 +62,14 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -62,14 +62,14 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev)
return; return;
} }
time_16 = FIT(t.recover, 0, 15) | (FIT(t.active, 0, 15) << 4); time_16 = clamp_val(t.recover, 0, 15) | (clamp_val(t.active, 0, 15) << 4);
time_8 = FIT(t.act8b, 0, 15) | (FIT(t.rec8b, 0, 15) << 4); time_8 = clamp_val(t.act8b, 0, 15) | (clamp_val(t.rec8b, 0, 15) << 4);
if (adev->devno == 0) { if (adev->devno == 0) {
pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr);
addr &= ~0x0F; /* Mask bits */ addr &= ~0x0F; /* Mask bits */
addr |= FIT(t.setup, 0, 15); addr |= clamp_val(t.setup, 0, 15);
pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr);
pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16); pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16);
...@@ -79,7 +79,7 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -79,7 +79,7 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev)
pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr);
addr &= ~0xF0; /* Mask bits */ addr &= ~0xF0; /* Mask bits */
addr |= (FIT(t.setup, 0, 15) << 4); addr |= (clamp_val(t.setup, 0, 15) << 4);
pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr);
pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16); pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16);
......
...@@ -343,8 +343,8 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -343,8 +343,8 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev)
/* Get the timing data in cycles. For now play safe at 50Mhz */ /* Get the timing data in cycles. For now play safe at 50Mhz */
ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
active = FIT(t.active, 2, 15); active = clamp_val(t.active, 2, 15);
recover = FIT(t.recover, 4, 15); recover = clamp_val(t.recover, 4, 15);
inb(0x3E6); inb(0x3E6);
inb(0x3E6); inb(0x3E6);
...@@ -377,8 +377,8 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -377,8 +377,8 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
/* Get the timing data in cycles. For now play safe at 50Mhz */ /* Get the timing data in cycles. For now play safe at 50Mhz */
ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
active = FIT(t.active, 2, 15); active = clamp_val(t.active, 2, 15);
recover = FIT(t.recover, 2, 16); recover = clamp_val(t.recover, 2, 16);
recover &= 0x15; recover &= 0x15;
inb(0x3E6); inb(0x3E6);
...@@ -462,9 +462,9 @@ static void opti82c611a_set_piomode(struct ata_port *ap, ...@@ -462,9 +462,9 @@ static void opti82c611a_set_piomode(struct ata_port *ap,
ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
} }
active = FIT(t.active, 2, 17) - 2; active = clamp_val(t.active, 2, 17) - 2;
recover = FIT(t.recover, 1, 16) - 1; recover = clamp_val(t.recover, 1, 16) - 1;
setup = FIT(t.setup, 1, 4) - 1; setup = clamp_val(t.setup, 1, 4) - 1;
/* Select the right timing bank for write timing */ /* Select the right timing bank for write timing */
rc = ioread8(ap->ioaddr.lbal_addr); rc = ioread8(ap->ioaddr.lbal_addr);
...@@ -541,9 +541,9 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -541,9 +541,9 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
} }
active = FIT(t.active, 2, 17) - 2; active = clamp_val(t.active, 2, 17) - 2;
recover = FIT(t.recover, 1, 16) - 1; recover = clamp_val(t.recover, 1, 16) - 1;
setup = FIT(t.setup, 1, 4) - 1; setup = clamp_val(t.setup, 1, 4) - 1;
/* Select the right timing bank for write timing */ /* Select the right timing bank for write timing */
rc = ioread8(ap->ioaddr.lbal_addr); rc = ioread8(ap->ioaddr.lbal_addr);
...@@ -624,11 +624,11 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -624,11 +624,11 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (ld_qdi->fast) { if (ld_qdi->fast) {
active = 8 - FIT(t.active, 1, 8); active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18); recovery = 18 - clamp_val(t.recover, 3, 18);
} else { } else {
active = 9 - FIT(t.active, 2, 9); active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - FIT(t.recover, 0, 15); recovery = 15 - clamp_val(t.recover, 0, 15);
} }
timing = (recovery << 4) | active | 0x08; timing = (recovery << 4) | active | 0x08;
...@@ -658,11 +658,11 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -658,11 +658,11 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (ld_qdi->fast) { if (ld_qdi->fast) {
active = 8 - FIT(t.active, 1, 8); active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18); recovery = 18 - clamp_val(t.recover, 3, 18);
} else { } else {
active = 9 - FIT(t.active, 2, 9); active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - FIT(t.recover, 0, 15); recovery = 15 - clamp_val(t.recover, 0, 15);
} }
timing = (recovery << 4) | active | 0x08; timing = (recovery << 4) | active | 0x08;
...@@ -695,11 +695,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -695,11 +695,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (ld_qdi->fast) { if (ld_qdi->fast) {
active = 8 - FIT(t.active, 1, 8); active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18); recovery = 18 - clamp_val(t.recover, 3, 18);
} else { } else {
active = 9 - FIT(t.active, 2, 9); active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - FIT(t.recover, 0, 15); recovery = 15 - clamp_val(t.recover, 0, 15);
} }
timing = (recovery << 4) | active | 0x08; timing = (recovery << 4) | active | 0x08;
ld_qdi->clock[adev->devno] = timing; ld_qdi->clock[adev->devno] = timing;
...@@ -830,8 +830,8 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -830,8 +830,8 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
else else
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
active = (FIT(t.active, 3, 17) - 1) & 0x0F; active = (clamp_val(t.active, 3, 17) - 1) & 0x0F;
recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F; recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F;
timing = (active << 4) | recovery; timing = (active << 4) | recovery;
winbond_writecfg(ld_winbond->timing, timing, reg); winbond_writecfg(ld_winbond->timing, timing, reg);
...@@ -842,7 +842,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -842,7 +842,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
reg |= 0x08; /* FIFO off */ reg |= 0x08; /* FIFO off */
if (!ata_pio_need_iordy(adev)) if (!ata_pio_need_iordy(adev))
reg |= 0x02; /* IORDY off */ reg |= 0x02; /* IORDY off */
reg |= (FIT(t.setup, 0, 3) << 6); reg |= (clamp_val(t.setup, 0, 3) << 6);
winbond_writecfg(ld_winbond->timing, timing + 1, reg); winbond_writecfg(ld_winbond->timing, timing + 1, reg);
} }
......
...@@ -91,9 +91,9 @@ static void ns87410_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -91,9 +91,9 @@ static void ns87410_set_piomode(struct ata_port *ap, struct ata_device *adev)
return; return;
} }
at.active = FIT(at.active, 2, 16) - 2; at.active = clamp_val(at.active, 2, 16) - 2;
at.setup = FIT(at.setup, 1, 4) - 1; at.setup = clamp_val(at.setup, 1, 4) - 1;
at.recover = FIT(at.recover, 1, 12) - 1; at.recover = clamp_val(at.recover, 1, 12) - 1;
idetcr = (at.setup << 6) | (recoverbits[at.recover] << 3) | activebits[at.active]; idetcr = (at.setup << 6) | (recoverbits[at.recover] << 3) | activebits[at.active];
......
...@@ -66,8 +66,8 @@ static void ns87415_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo ...@@ -66,8 +66,8 @@ static void ns87415_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
ata_timing_compute(adev, adev->pio_mode, &t, T, 0); ata_timing_compute(adev, adev->pio_mode, &t, T, 0);
clocking = 17 - FIT(t.active, 2, 17); clocking = 17 - clamp_val(t.active, 2, 17);
clocking |= (16 - FIT(t.recover, 1, 16)) << 4; clocking |= (16 - clamp_val(t.recover, 1, 16)) << 4;
/* Use the same timing for read and write bytes */ /* Use the same timing for read and write bytes */
clocking |= (clocking << 8); clocking |= (clocking << 8);
pci_write_config_word(dev, timing, clocking); pci_write_config_word(dev, timing, clocking);
......
...@@ -60,11 +60,11 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -60,11 +60,11 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (qdi->fast) { if (qdi->fast) {
active = 8 - FIT(t.active, 1, 8); active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18); recovery = 18 - clamp_val(t.recover, 3, 18);
} else { } else {
active = 9 - FIT(t.active, 2, 9); active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - FIT(t.recover, 0, 15); recovery = 15 - clamp_val(t.recover, 0, 15);
} }
timing = (recovery << 4) | active | 0x08; timing = (recovery << 4) | active | 0x08;
...@@ -84,11 +84,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -84,11 +84,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (qdi->fast) { if (qdi->fast) {
active = 8 - FIT(t.active, 1, 8); active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18); recovery = 18 - clamp_val(t.recover, 3, 18);
} else { } else {
active = 9 - FIT(t.active, 2, 9); active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - FIT(t.recover, 0, 15); recovery = 15 - clamp_val(t.recover, 0, 15);
} }
timing = (recovery << 4) | active | 0x08; timing = (recovery << 4) | active | 0x08;
......
...@@ -216,7 +216,7 @@ static int sl82c105_qc_defer(struct ata_queued_cmd *qc) ...@@ -216,7 +216,7 @@ static int sl82c105_qc_defer(struct ata_queued_cmd *qc)
struct ata_port *alt = host->ports[1 ^ qc->ap->port_no]; struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
int rc; int rc;
/* First apply the usual rules */ /* First apply the usual rules */
rc = ata_std_qc_defer(qc); rc = ata_std_qc_defer(qc);
if (rc != 0) if (rc != 0)
return rc; return rc;
......
...@@ -259,15 +259,15 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo ...@@ -259,15 +259,15 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo
pci_read_config_byte(pdev, 0x4C, &setup); pci_read_config_byte(pdev, 0x4C, &setup);
setup &= ~(3 << shift); setup &= ~(3 << shift);
setup |= FIT(t.setup, 1, 4) << shift; /* 1,4 or 1,4 - 1 FIXME */ setup |= clamp_val(t.setup, 1, 4) << shift; /* 1,4 or 1,4 - 1 FIXME */
pci_write_config_byte(pdev, 0x4C, setup); pci_write_config_byte(pdev, 0x4C, setup);
} }
/* Load the PIO mode bits */ /* Load the PIO mode bits */
pci_write_config_byte(pdev, 0x4F - ap->port_no, pci_write_config_byte(pdev, 0x4F - ap->port_no,
((FIT(t.act8b, 1, 16) - 1) << 4) | (FIT(t.rec8b, 1, 16) - 1)); ((clamp_val(t.act8b, 1, 16) - 1) << 4) | (clamp_val(t.rec8b, 1, 16) - 1));
pci_write_config_byte(pdev, 0x48 + offset, pci_write_config_byte(pdev, 0x48 + offset,
((FIT(t.active, 1, 16) - 1) << 4) | (FIT(t.recover, 1, 16) - 1)); ((clamp_val(t.active, 1, 16) - 1) << 4) | (clamp_val(t.recover, 1, 16) - 1));
/* Load the UDMA bits according to type */ /* Load the UDMA bits according to type */
switch(udma_type) { switch(udma_type) {
...@@ -275,16 +275,16 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo ...@@ -275,16 +275,16 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo
/* BUG() ? */ /* BUG() ? */
/* fall through */ /* fall through */
case 33: case 33:
ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 5) - 2)) : 0x03; ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 5) - 2)) : 0x03;
break; break;
case 66: case 66:
ut = t.udma ? (0xe8 | (FIT(t.udma, 2, 9) - 2)) : 0x0f; ut = t.udma ? (0xe8 | (clamp_val(t.udma, 2, 9) - 2)) : 0x0f;
break; break;
case 100: case 100:
ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07;
break; break;
case 133: case 133:
ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07;
break; break;
} }
......
...@@ -75,8 +75,8 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -75,8 +75,8 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
else else
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
active = (FIT(t.active, 3, 17) - 1) & 0x0F; active = (clamp_val(t.active, 3, 17) - 1) & 0x0F;
recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F; recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F;
timing = (active << 4) | recovery; timing = (active << 4) | recovery;
winbond_writecfg(winbond->config, timing, reg); winbond_writecfg(winbond->config, timing, reg);
...@@ -87,7 +87,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -87,7 +87,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
reg |= 0x08; /* FIFO off */ reg |= 0x08; /* FIFO off */
if (!ata_pio_need_iordy(adev)) if (!ata_pio_need_iordy(adev))
reg |= 0x02; /* IORDY off */ reg |= 0x02; /* IORDY off */
reg |= (FIT(t.setup, 0, 3) << 6); reg |= (clamp_val(t.setup, 0, 3) << 6);
winbond_writecfg(winbond->config, timing + 1, reg); winbond_writecfg(winbond->config, timing + 1, reg);
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -899,14 +899,25 @@ static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc) ...@@ -899,14 +899,25 @@ static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc)
static void sil24_pmp_attach(struct ata_port *ap) static void sil24_pmp_attach(struct ata_port *ap)
{ {
u32 *gscr = ap->link.device->gscr;
sil24_config_pmp(ap, 1); sil24_config_pmp(ap, 1);
sil24_init_port(ap); sil24_init_port(ap);
if (sata_pmp_gscr_vendor(gscr) == 0x11ab &&
sata_pmp_gscr_devid(gscr) == 0x4140) {
ata_port_printk(ap, KERN_INFO,
"disabling NCQ support due to sil24-mv4140 quirk\n");
ap->flags &= ~ATA_FLAG_NCQ;
}
} }
static void sil24_pmp_detach(struct ata_port *ap) static void sil24_pmp_detach(struct ata_port *ap)
{ {
sil24_init_port(ap); sil24_init_port(ap);
sil24_config_pmp(ap, 0); sil24_config_pmp(ap, 0);
ap->flags |= ATA_FLAG_NCQ;
} }
static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class, static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
......
...@@ -341,7 +341,7 @@ enum { ...@@ -341,7 +341,7 @@ enum {
ATA_EH_PMP_TRIES = 5, ATA_EH_PMP_TRIES = 5,
ATA_EH_PMP_LINK_TRIES = 3, ATA_EH_PMP_LINK_TRIES = 3,
SATA_PMP_SCR_TIMEOUT = 250, SATA_PMP_RW_TIMEOUT = 3000, /* PMP read/write timeout */
/* Horkage types. May be set by libata or controller on drives /* Horkage types. May be set by libata or controller on drives
(some horkage may be drive/controller pair dependant */ (some horkage may be drive/controller pair dependant */
...@@ -351,7 +351,7 @@ enum { ...@@ -351,7 +351,7 @@ enum {
ATA_HORKAGE_NONCQ = (1 << 2), /* Don't use NCQ */ ATA_HORKAGE_NONCQ = (1 << 2), /* Don't use NCQ */
ATA_HORKAGE_MAX_SEC_128 = (1 << 3), /* Limit max sects to 128 */ ATA_HORKAGE_MAX_SEC_128 = (1 << 3), /* Limit max sects to 128 */
ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */ ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */
ATA_HORKAGE_SKIP_PM = (1 << 5), /* Skip PM operations */ ATA_HORKAGE_DISABLE = (1 << 5), /* Disable it */
ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */
ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */ ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */
ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */
...@@ -821,8 +821,6 @@ struct ata_timing { ...@@ -821,8 +821,6 @@ struct ata_timing {
unsigned short udma; /* t2CYCTYP/2 */ unsigned short udma; /* t2CYCTYP/2 */
}; };
#define FIT(v, vmin, vmax) max_t(short, min_t(short, v, vmax), vmin)
/* /*
* Core layer - drivers/ata/libata-core.c * Core layer - drivers/ata/libata-core.c
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment