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);
} }
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "sata_mv" #define DRV_NAME "sata_mv"
#define DRV_VERSION "1.20" #define DRV_VERSION "1.21"
enum { enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */ /* BAR's are enumerated in terms of pci_resource_start() terms */
...@@ -128,8 +128,13 @@ enum { ...@@ -128,8 +128,13 @@ enum {
MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
ATA_FLAG_PIO_POLLING, ATA_FLAG_PIO_POLLING,
MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE,
MV_GENIIE_FLAGS = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
ATA_FLAG_NCQ | ATA_FLAG_AN,
CRQB_FLAG_READ = (1 << 0), CRQB_FLAG_READ = (1 << 0),
CRQB_TAG_SHIFT = 1, CRQB_TAG_SHIFT = 1,
CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */ CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */
...@@ -197,13 +202,6 @@ enum { ...@@ -197,13 +202,6 @@ enum {
HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */
HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */
HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */ HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */
HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE |
PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE |
PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT |
HC_MAIN_RSVD),
HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE |
HC_MAIN_RSVD_5),
HC_MAIN_MASKED_IRQS_SOC = (PORTS_0_3_COAL_DONE | HC_MAIN_RSVD_SOC),
/* SATAHC registers */ /* SATAHC registers */
HC_CFG_OFS = 0, HC_CFG_OFS = 0,
...@@ -221,6 +219,7 @@ enum { ...@@ -221,6 +219,7 @@ enum {
SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */
SATA_ACTIVE_OFS = 0x350, SATA_ACTIVE_OFS = 0x350,
SATA_FIS_IRQ_CAUSE_OFS = 0x364, SATA_FIS_IRQ_CAUSE_OFS = 0x364,
SATA_FIS_IRQ_AN = (1 << 9), /* async notification */
LTMODE_OFS = 0x30c, LTMODE_OFS = 0x30c,
LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */ LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */
...@@ -459,6 +458,7 @@ struct mv_port_signal { ...@@ -459,6 +458,7 @@ struct mv_port_signal {
struct mv_host_priv { struct mv_host_priv {
u32 hp_flags; u32 hp_flags;
u32 main_irq_mask;
struct mv_port_signal signal[8]; struct mv_port_signal signal[8];
const struct mv_hw_ops *ops; const struct mv_hw_ops *ops;
int n_ports; int n_ports;
...@@ -640,25 +640,19 @@ static const struct ata_port_info mv_port_info[] = { ...@@ -640,25 +640,19 @@ static const struct ata_port_info mv_port_info[] = {
.port_ops = &mv6_ops, .port_ops = &mv6_ops,
}, },
{ /* chip_6042 */ { /* chip_6042 */
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | .flags = MV_GENIIE_FLAGS,
ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
ATA_FLAG_NCQ,
.pio_mask = 0x1f, /* pio0-4 */ .pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops, .port_ops = &mv_iie_ops,
}, },
{ /* chip_7042 */ { /* chip_7042 */
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | .flags = MV_GENIIE_FLAGS,
ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
ATA_FLAG_NCQ,
.pio_mask = 0x1f, /* pio0-4 */ .pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops, .port_ops = &mv_iie_ops,
}, },
{ /* chip_soc */ { /* chip_soc */
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | .flags = MV_GENIIE_FLAGS | MV_FLAG_SOC,
ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
ATA_FLAG_NCQ | MV_FLAG_SOC,
.pio_mask = 0x1f, /* pio0-4 */ .pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops, .port_ops = &mv_iie_ops,
...@@ -844,6 +838,33 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, ...@@ -844,6 +838,33 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio,
port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
} }
static void mv_set_main_irq_mask(struct ata_host *host,
u32 disable_bits, u32 enable_bits)
{
struct mv_host_priv *hpriv = host->private_data;
u32 old_mask, new_mask;
old_mask = hpriv->main_irq_mask;
new_mask = (old_mask & ~disable_bits) | enable_bits;
if (new_mask != old_mask) {
hpriv->main_irq_mask = new_mask;
writelfl(new_mask, hpriv->main_irq_mask_addr);
}
}
static void mv_enable_port_irqs(struct ata_port *ap,
unsigned int port_bits)
{
unsigned int shift, hardport, port = ap->port_no;
u32 disable_bits, enable_bits;
MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport);
disable_bits = (DONE_IRQ | ERR_IRQ) << shift;
enable_bits = port_bits << shift;
mv_set_main_irq_mask(ap->host, disable_bits, enable_bits);
}
/** /**
* mv_start_dma - Enable eDMA engine * mv_start_dma - Enable eDMA engine
* @base: port base address * @base: port base address
...@@ -886,9 +907,11 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, ...@@ -886,9 +907,11 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
mv_edma_cfg(ap, want_ncq); mv_edma_cfg(ap, want_ncq);
/* clear FIS IRQ Cause */ /* clear FIS IRQ Cause */
writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); if (IS_GEN_IIE(hpriv))
writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
mv_set_edma_ptrs(port_mmio, hpriv, pp); mv_set_edma_ptrs(port_mmio, hpriv, pp);
mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ);
writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS);
pp->pp_flags |= MV_PP_FLAG_EDMA_EN; pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
...@@ -1341,6 +1364,7 @@ static int mv_port_start(struct ata_port *ap) ...@@ -1341,6 +1364,7 @@ static int mv_port_start(struct ata_port *ap)
static void mv_port_stop(struct ata_port *ap) static void mv_port_stop(struct ata_port *ap)
{ {
mv_stop_edma(ap); mv_stop_edma(ap);
mv_enable_port_irqs(ap, 0);
mv_port_free_dma_mem(ap); mv_port_free_dma_mem(ap);
} }
...@@ -1582,6 +1606,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) ...@@ -1582,6 +1606,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
* shadow block, etc registers. * shadow block, etc registers.
*/ */
mv_stop_edma(ap); mv_stop_edma(ap);
mv_enable_port_irqs(ap, ERR_IRQ);
mv_pmp_select(ap, qc->dev->link->pmp); mv_pmp_select(ap, qc->dev->link->pmp);
return ata_sff_qc_issue(qc); return ata_sff_qc_issue(qc);
} }
...@@ -1670,6 +1695,18 @@ static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map) ...@@ -1670,6 +1695,18 @@ static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map)
} }
} }
static int mv_req_q_empty(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
u32 in_ptr, out_ptr;
in_ptr = (readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS)
>> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
out_ptr = (readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS)
>> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
return (in_ptr == out_ptr); /* 1 == queue_is_empty */
}
static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap)
{ {
struct mv_port_priv *pp = ap->private_data; struct mv_port_priv *pp = ap->private_data;
...@@ -1703,7 +1740,7 @@ static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) ...@@ -1703,7 +1740,7 @@ static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap)
ap->qc_active, failed_links, ap->qc_active, failed_links,
ap->nr_active_links); ap->nr_active_links);
if (ap->nr_active_links <= failed_links) { if (ap->nr_active_links <= failed_links && mv_req_q_empty(ap)) {
mv_process_crpb_entries(ap, pp); mv_process_crpb_entries(ap, pp);
mv_stop_edma(ap); mv_stop_edma(ap);
mv_eh_freeze(ap); mv_eh_freeze(ap);
...@@ -1812,6 +1849,7 @@ static void mv_err_intr(struct ata_port *ap) ...@@ -1812,6 +1849,7 @@ static void mv_err_intr(struct ata_port *ap)
{ {
void __iomem *port_mmio = mv_ap_base(ap); void __iomem *port_mmio = mv_ap_base(ap);
u32 edma_err_cause, eh_freeze_mask, serr = 0; u32 edma_err_cause, eh_freeze_mask, serr = 0;
u32 fis_cause = 0;
struct mv_port_priv *pp = ap->private_data; struct mv_port_priv *pp = ap->private_data;
struct mv_host_priv *hpriv = ap->host->private_data; struct mv_host_priv *hpriv = ap->host->private_data;
unsigned int action = 0, err_mask = 0; unsigned int action = 0, err_mask = 0;
...@@ -1821,16 +1859,19 @@ static void mv_err_intr(struct ata_port *ap) ...@@ -1821,16 +1859,19 @@ static void mv_err_intr(struct ata_port *ap)
/* /*
* Read and clear the SError and err_cause bits. * Read and clear the SError and err_cause bits.
* For GenIIe, if EDMA_ERR_TRANS_IRQ_7 is set, we also must read/clear
* the FIS_IRQ_CAUSE register before clearing edma_err_cause.
*/ */
sata_scr_read(&ap->link, SCR_ERROR, &serr); sata_scr_read(&ap->link, SCR_ERROR, &serr);
sata_scr_write_flush(&ap->link, SCR_ERROR, serr); sata_scr_write_flush(&ap->link, SCR_ERROR, serr);
edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) {
fis_cause = readl(port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
writelfl(~fis_cause, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
}
writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
ata_port_printk(ap, KERN_INFO, "%s: err_cause=%08x pp_flags=0x%x\n",
__func__, edma_err_cause, pp->pp_flags);
if (edma_err_cause & EDMA_ERR_DEV) { if (edma_err_cause & EDMA_ERR_DEV) {
/* /*
* Device errors during FIS-based switching operation * Device errors during FIS-based switching operation
...@@ -1844,6 +1885,18 @@ static void mv_err_intr(struct ata_port *ap) ...@@ -1844,6 +1885,18 @@ static void mv_err_intr(struct ata_port *ap)
ata_ehi_clear_desc(ehi); ata_ehi_clear_desc(ehi);
ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x", ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x",
edma_err_cause, pp->pp_flags); edma_err_cause, pp->pp_flags);
if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) {
ata_ehi_push_desc(ehi, "fis_cause=%08x", fis_cause);
if (fis_cause & SATA_FIS_IRQ_AN) {
u32 ec = edma_err_cause &
~(EDMA_ERR_TRANS_IRQ_7 | EDMA_ERR_IRQ_TRANSIENT);
sata_async_notification(ap);
if (!ec)
return; /* Just an AN; no need for the nukes */
ata_ehi_push_desc(ehi, "SDB notify");
}
}
/* /*
* All generations share these EDMA error cause bits: * All generations share these EDMA error cause bits:
*/ */
...@@ -2162,20 +2215,20 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) ...@@ -2162,20 +2215,20 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
struct ata_host *host = dev_instance; struct ata_host *host = dev_instance;
struct mv_host_priv *hpriv = host->private_data; struct mv_host_priv *hpriv = host->private_data;
unsigned int handled = 0; unsigned int handled = 0;
u32 main_irq_cause, main_irq_mask; u32 main_irq_cause, pending_irqs;
spin_lock(&host->lock); spin_lock(&host->lock);
main_irq_cause = readl(hpriv->main_irq_cause_addr); main_irq_cause = readl(hpriv->main_irq_cause_addr);
main_irq_mask = readl(hpriv->main_irq_mask_addr); pending_irqs = main_irq_cause & hpriv->main_irq_mask;
/* /*
* Deal with cases where we either have nothing pending, or have read * Deal with cases where we either have nothing pending, or have read
* a bogus register value which can indicate HW removal or PCI fault. * a bogus register value which can indicate HW removal or PCI fault.
*/ */
if ((main_irq_cause & main_irq_mask) && (main_irq_cause != 0xffffffffU)) { if (pending_irqs && main_irq_cause != 0xffffffffU) {
if (unlikely((main_irq_cause & PCI_ERR) && HAS_PCI(host))) if (unlikely((pending_irqs & PCI_ERR) && HAS_PCI(host)))
handled = mv_pci_error(host, hpriv->base); handled = mv_pci_error(host, hpriv->base);
else else
handled = mv_host_intr(host, main_irq_cause); handled = mv_host_intr(host, pending_irqs);
} }
spin_unlock(&host->lock); spin_unlock(&host->lock);
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
...@@ -2373,7 +2426,6 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio) ...@@ -2373,7 +2426,6 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio)
ZERO(MV_PCI_DISC_TIMER); ZERO(MV_PCI_DISC_TIMER);
ZERO(MV_PCI_MSI_TRIGGER); ZERO(MV_PCI_MSI_TRIGGER);
writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS); writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS);
ZERO(PCI_HC_MAIN_IRQ_MASK_OFS);
ZERO(MV_PCI_SERR_MASK); ZERO(MV_PCI_SERR_MASK);
ZERO(hpriv->irq_cause_ofs); ZERO(hpriv->irq_cause_ofs);
ZERO(hpriv->irq_mask_ofs); ZERO(hpriv->irq_mask_ofs);
...@@ -2728,6 +2780,7 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, ...@@ -2728,6 +2780,7 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
rc = sata_link_hardreset(link, timing, deadline + extra, rc = sata_link_hardreset(link, timing, deadline + extra,
&online, NULL); &online, NULL);
rc = online ? -EAGAIN : rc;
if (rc) if (rc)
return rc; return rc;
sata_scr_read(link, SCR_STATUS, &sstatus); sata_scr_read(link, SCR_STATUS, &sstatus);
...@@ -2744,32 +2797,18 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, ...@@ -2744,32 +2797,18 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
static void mv_eh_freeze(struct ata_port *ap) static void mv_eh_freeze(struct ata_port *ap)
{ {
struct mv_host_priv *hpriv = ap->host->private_data;
unsigned int shift, hardport, port = ap->port_no;
u32 main_irq_mask;
/* FIXME: handle coalescing completion events properly */
mv_stop_edma(ap); mv_stop_edma(ap);
MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); mv_enable_port_irqs(ap, 0);
/* disable assertion of portN err, done events */
main_irq_mask = readl(hpriv->main_irq_mask_addr);
main_irq_mask &= ~((DONE_IRQ | ERR_IRQ) << shift);
writelfl(main_irq_mask, hpriv->main_irq_mask_addr);
} }
static void mv_eh_thaw(struct ata_port *ap) static void mv_eh_thaw(struct ata_port *ap)
{ {
struct mv_host_priv *hpriv = ap->host->private_data; struct mv_host_priv *hpriv = ap->host->private_data;
unsigned int shift, hardport, port = ap->port_no; unsigned int port = ap->port_no;
unsigned int hardport = mv_hardport_from_port(port);
void __iomem *hc_mmio = mv_hc_base_from_port(hpriv->base, port); void __iomem *hc_mmio = mv_hc_base_from_port(hpriv->base, port);
void __iomem *port_mmio = mv_ap_base(ap); void __iomem *port_mmio = mv_ap_base(ap);
u32 main_irq_mask, hc_irq_cause; u32 hc_irq_cause;
/* FIXME: handle coalescing completion events properly */
MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport);
/* clear EDMA errors on this port */ /* clear EDMA errors on this port */
writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
...@@ -2779,10 +2818,7 @@ static void mv_eh_thaw(struct ata_port *ap) ...@@ -2779,10 +2818,7 @@ static void mv_eh_thaw(struct ata_port *ap)
hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport); hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport);
writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
/* enable assertion of portN err, done events */ mv_enable_port_irqs(ap, ERR_IRQ);
main_irq_mask = readl(hpriv->main_irq_mask_addr);
main_irq_mask |= ((DONE_IRQ | ERR_IRQ) << shift);
writelfl(main_irq_mask, hpriv->main_irq_mask_addr);
} }
/** /**
...@@ -3035,7 +3071,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) ...@@ -3035,7 +3071,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
} }
/* global interrupt mask: 0 == mask everything */ /* global interrupt mask: 0 == mask everything */
writel(0, hpriv->main_irq_mask_addr); mv_set_main_irq_mask(host, ~0, 0);
n_hc = mv_get_hc_count(host->ports[0]->flags); n_hc = mv_get_hc_count(host->ports[0]->flags);
...@@ -3083,25 +3119,12 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) ...@@ -3083,25 +3119,12 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
/* and unmask interrupt generation for host regs */ /* and unmask interrupt generation for host regs */
writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
if (IS_GEN_I(hpriv))
writelfl(~HC_MAIN_MASKED_IRQS_5, /*
hpriv->main_irq_mask_addr); * enable only global host interrupts for now.
else * The per-port interrupts get done later as ports are set up.
writelfl(~HC_MAIN_MASKED_IRQS, */
hpriv->main_irq_mask_addr); mv_set_main_irq_mask(host, 0, PCI_ERR);
VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x "
"PCI int cause/mask=0x%08x/0x%08x\n",
readl(hpriv->main_irq_cause_addr),
readl(hpriv->main_irq_mask_addr),
readl(mmio + hpriv->irq_cause_ofs),
readl(mmio + hpriv->irq_mask_ofs));
} else {
writelfl(~HC_MAIN_MASKED_IRQS_SOC,
hpriv->main_irq_mask_addr);
VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x\n",
readl(hpriv->main_irq_cause_addr),
readl(hpriv->main_irq_mask_addr));
} }
done: done:
return rc; return rc;
......
...@@ -53,7 +53,15 @@ enum { ...@@ -53,7 +53,15 @@ enum {
PDC_MMIO_BAR = 3, PDC_MMIO_BAR = 3,
PDC_MAX_PRD = LIBATA_MAX_PRD - 1, /* -1 for ASIC PRD bug workaround */ PDC_MAX_PRD = LIBATA_MAX_PRD - 1, /* -1 for ASIC PRD bug workaround */
/* register offsets */ /* host register offsets (from host->iomap[PDC_MMIO_BAR]) */
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
PDC_FLASH_CTL = 0x44, /* Flash control register */
PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */
PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */
PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */
PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */
/* per-port ATA register offsets (from ap->ioaddr.cmd_addr) */
PDC_FEATURE = 0x04, /* Feature/Error reg (per port) */ PDC_FEATURE = 0x04, /* Feature/Error reg (per port) */
PDC_SECTOR_COUNT = 0x08, /* Sector count reg (per port) */ PDC_SECTOR_COUNT = 0x08, /* Sector count reg (per port) */
PDC_SECTOR_NUMBER = 0x0C, /* Sector number reg (per port) */ PDC_SECTOR_NUMBER = 0x0C, /* Sector number reg (per port) */
...@@ -63,14 +71,11 @@ enum { ...@@ -63,14 +71,11 @@ enum {
PDC_COMMAND = 0x1C, /* Command/status reg (per port) */ PDC_COMMAND = 0x1C, /* Command/status reg (per port) */
PDC_ALTSTATUS = 0x38, /* Alternate-status/device-control reg (per port) */ PDC_ALTSTATUS = 0x38, /* Alternate-status/device-control reg (per port) */
PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */ PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
PDC_FLASH_CTL = 0x44, /* Flash control register */
PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */ PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */
PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */ PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */
PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */
PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */ /* per-port SATA register offsets (from ap->ioaddr.scr_addr) */
PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */ PDC_PHYMODE4 = 0x14,
PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */
/* PDC_GLOBAL_CTL bit definitions */ /* PDC_GLOBAL_CTL bit definitions */
PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */ PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */
...@@ -134,7 +139,7 @@ struct pdc_port_priv { ...@@ -134,7 +139,7 @@ struct pdc_port_priv {
static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int pdc_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int pdc_common_port_start(struct ata_port *ap); static int pdc_common_port_start(struct ata_port *ap);
static int pdc_sata_port_start(struct ata_port *ap); static int pdc_sata_port_start(struct ata_port *ap);
static void pdc_qc_prep(struct ata_queued_cmd *qc); static void pdc_qc_prep(struct ata_queued_cmd *qc);
...@@ -332,12 +337,12 @@ static int pdc_sata_port_start(struct ata_port *ap) ...@@ -332,12 +337,12 @@ static int pdc_sata_port_start(struct ata_port *ap)
/* fix up PHYMODE4 align timing */ /* fix up PHYMODE4 align timing */
if (ap->flags & PDC_FLAG_GEN_II) { if (ap->flags & PDC_FLAG_GEN_II) {
void __iomem *mmio = ap->ioaddr.scr_addr; void __iomem *sata_mmio = ap->ioaddr.scr_addr;
unsigned int tmp; unsigned int tmp;
tmp = readl(mmio + 0x014); tmp = readl(sata_mmio + PDC_PHYMODE4);
tmp = (tmp & ~3) | 1; /* set bits 1:0 = 0:1 */ tmp = (tmp & ~3) | 1; /* set bits 1:0 = 0:1 */
writel(tmp, mmio + 0x014); writel(tmp, sata_mmio + PDC_PHYMODE4);
} }
return 0; return 0;
...@@ -345,32 +350,32 @@ static int pdc_sata_port_start(struct ata_port *ap) ...@@ -345,32 +350,32 @@ static int pdc_sata_port_start(struct ata_port *ap)
static void pdc_reset_port(struct ata_port *ap) static void pdc_reset_port(struct ata_port *ap)
{ {
void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; void __iomem *ata_ctlstat_mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT;
unsigned int i; unsigned int i;
u32 tmp; u32 tmp;
for (i = 11; i > 0; i--) { for (i = 11; i > 0; i--) {
tmp = readl(mmio); tmp = readl(ata_ctlstat_mmio);
if (tmp & PDC_RESET) if (tmp & PDC_RESET)
break; break;
udelay(100); udelay(100);
tmp |= PDC_RESET; tmp |= PDC_RESET;
writel(tmp, mmio); writel(tmp, ata_ctlstat_mmio);
} }
tmp &= ~PDC_RESET; tmp &= ~PDC_RESET;
writel(tmp, mmio); writel(tmp, ata_ctlstat_mmio);
readl(mmio); /* flush */ readl(ata_ctlstat_mmio); /* flush */
} }
static int pdc_pata_cable_detect(struct ata_port *ap) static int pdc_pata_cable_detect(struct ata_port *ap)
{ {
u8 tmp; u8 tmp;
void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
tmp = readb(mmio); tmp = readb(ata_mmio + PDC_CTLSTAT + 3);
if (tmp & 0x01) if (tmp & 0x01)
return ATA_CBL_PATA40; return ATA_CBL_PATA40;
return ATA_CBL_PATA80; return ATA_CBL_PATA80;
...@@ -557,31 +562,25 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc) ...@@ -557,31 +562,25 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
switch (qc->tf.protocol) { switch (qc->tf.protocol) {
case ATA_PROT_DMA: case ATA_PROT_DMA:
pdc_fill_sg(qc); pdc_fill_sg(qc);
/* fall through */ /*FALLTHROUGH*/
case ATA_PROT_NODATA: case ATA_PROT_NODATA:
i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma, i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma,
qc->dev->devno, pp->pkt); qc->dev->devno, pp->pkt);
if (qc->tf.flags & ATA_TFLAG_LBA48) if (qc->tf.flags & ATA_TFLAG_LBA48)
i = pdc_prep_lba48(&qc->tf, pp->pkt, i); i = pdc_prep_lba48(&qc->tf, pp->pkt, i);
else else
i = pdc_prep_lba28(&qc->tf, pp->pkt, i); i = pdc_prep_lba28(&qc->tf, pp->pkt, i);
pdc_pkt_footer(&qc->tf, pp->pkt, i); pdc_pkt_footer(&qc->tf, pp->pkt, i);
break; break;
case ATAPI_PROT_PIO: case ATAPI_PROT_PIO:
pdc_fill_sg(qc); pdc_fill_sg(qc);
break; break;
case ATAPI_PROT_DMA: case ATAPI_PROT_DMA:
pdc_fill_sg(qc); pdc_fill_sg(qc);
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case ATAPI_PROT_NODATA: case ATAPI_PROT_NODATA:
pdc_atapi_pkt(qc); pdc_atapi_pkt(qc);
break; break;
default: default:
break; break;
} }
...@@ -611,7 +610,7 @@ static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap) ...@@ -611,7 +610,7 @@ static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap)
unsigned int nr_ports = pdc_sata_nr_ports(ap); unsigned int nr_ports = pdc_sata_nr_ports(ap);
unsigned int i; unsigned int i;
for(i = 0; i < nr_ports && host->ports[i] != ap; ++i) for (i = 0; i < nr_ports && host->ports[i] != ap; ++i)
; ;
BUG_ON(i >= nr_ports); BUG_ON(i >= nr_ports);
return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags)); return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags));
...@@ -624,14 +623,14 @@ static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap) ...@@ -624,14 +623,14 @@ static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap)
static void pdc_freeze(struct ata_port *ap) static void pdc_freeze(struct ata_port *ap)
{ {
void __iomem *mmio = ap->ioaddr.cmd_addr; void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
u32 tmp; u32 tmp;
tmp = readl(mmio + PDC_CTLSTAT); tmp = readl(ata_mmio + PDC_CTLSTAT);
tmp |= PDC_IRQ_DISABLE; tmp |= PDC_IRQ_DISABLE;
tmp &= ~PDC_DMA_ENABLE; tmp &= ~PDC_DMA_ENABLE;
writel(tmp, mmio + PDC_CTLSTAT); writel(tmp, ata_mmio + PDC_CTLSTAT);
readl(mmio + PDC_CTLSTAT); /* flush */ readl(ata_mmio + PDC_CTLSTAT); /* flush */
} }
static void pdc_sata_freeze(struct ata_port *ap) static void pdc_sata_freeze(struct ata_port *ap)
...@@ -659,17 +658,17 @@ static void pdc_sata_freeze(struct ata_port *ap) ...@@ -659,17 +658,17 @@ static void pdc_sata_freeze(struct ata_port *ap)
static void pdc_thaw(struct ata_port *ap) static void pdc_thaw(struct ata_port *ap)
{ {
void __iomem *mmio = ap->ioaddr.cmd_addr; void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
u32 tmp; u32 tmp;
/* clear IRQ */ /* clear IRQ */
readl(mmio + PDC_INT_SEQMASK); readl(ata_mmio + PDC_COMMAND);
/* turn IRQ back on */ /* turn IRQ back on */
tmp = readl(mmio + PDC_CTLSTAT); tmp = readl(ata_mmio + PDC_CTLSTAT);
tmp &= ~PDC_IRQ_DISABLE; tmp &= ~PDC_IRQ_DISABLE;
writel(tmp, mmio + PDC_CTLSTAT); writel(tmp, ata_mmio + PDC_CTLSTAT);
readl(mmio + PDC_CTLSTAT); /* flush */ readl(ata_mmio + PDC_CTLSTAT); /* flush */
} }
static void pdc_sata_thaw(struct ata_port *ap) static void pdc_sata_thaw(struct ata_port *ap)
...@@ -743,11 +742,11 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, ...@@ -743,11 +742,11 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
ata_port_abort(ap); ata_port_abort(ap);
} }
static inline unsigned int pdc_host_intr(struct ata_port *ap, static unsigned int pdc_host_intr(struct ata_port *ap,
struct ata_queued_cmd *qc) struct ata_queued_cmd *qc)
{ {
unsigned int handled = 0; unsigned int handled = 0;
void __iomem *port_mmio = ap->ioaddr.cmd_addr; void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
u32 port_status, err_mask; u32 port_status, err_mask;
err_mask = PDC_ERR_MASK; err_mask = PDC_ERR_MASK;
...@@ -755,7 +754,7 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, ...@@ -755,7 +754,7 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap,
err_mask &= ~PDC1_ERR_MASK; err_mask &= ~PDC1_ERR_MASK;
else else
err_mask &= ~PDC2_ERR_MASK; err_mask &= ~PDC2_ERR_MASK;
port_status = readl(port_mmio + PDC_GLOBAL_CTL); port_status = readl(ata_mmio + PDC_GLOBAL_CTL);
if (unlikely(port_status & err_mask)) { if (unlikely(port_status & err_mask)) {
pdc_error_intr(ap, qc, port_status, err_mask); pdc_error_intr(ap, qc, port_status, err_mask);
return 1; return 1;
...@@ -770,7 +769,6 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, ...@@ -770,7 +769,6 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap,
ata_qc_complete(qc); ata_qc_complete(qc);
handled = 1; handled = 1;
break; break;
default: default:
ap->stats.idle_irq++; ap->stats.idle_irq++;
break; break;
...@@ -781,10 +779,9 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, ...@@ -781,10 +779,9 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap,
static void pdc_irq_clear(struct ata_port *ap) static void pdc_irq_clear(struct ata_port *ap)
{ {
struct ata_host *host = ap->host; void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
readl(mmio + PDC_INT_SEQMASK); readl(ata_mmio + PDC_COMMAND);
} }
static irqreturn_t pdc_interrupt(int irq, void *dev_instance) static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
...@@ -794,7 +791,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) ...@@ -794,7 +791,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
u32 mask = 0; u32 mask = 0;
unsigned int i, tmp; unsigned int i, tmp;
unsigned int handled = 0; unsigned int handled = 0;
void __iomem *mmio_base; void __iomem *host_mmio;
unsigned int hotplug_offset, ata_no; unsigned int hotplug_offset, ata_no;
u32 hotplug_status; u32 hotplug_status;
int is_sataii_tx4; int is_sataii_tx4;
...@@ -806,7 +803,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) ...@@ -806,7 +803,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
return IRQ_NONE; return IRQ_NONE;
} }
mmio_base = host->iomap[PDC_MMIO_BAR]; host_mmio = host->iomap[PDC_MMIO_BAR];
spin_lock(&host->lock); spin_lock(&host->lock);
...@@ -815,26 +812,26 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) ...@@ -815,26 +812,26 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
hotplug_offset = PDC2_SATA_PLUG_CSR; hotplug_offset = PDC2_SATA_PLUG_CSR;
else else
hotplug_offset = PDC_SATA_PLUG_CSR; hotplug_offset = PDC_SATA_PLUG_CSR;
hotplug_status = readl(mmio_base + hotplug_offset); hotplug_status = readl(host_mmio + hotplug_offset);
if (hotplug_status & 0xff) if (hotplug_status & 0xff)
writel(hotplug_status | 0xff, mmio_base + hotplug_offset); writel(hotplug_status | 0xff, host_mmio + hotplug_offset);
hotplug_status &= 0xff; /* clear uninteresting bits */ hotplug_status &= 0xff; /* clear uninteresting bits */
/* reading should also clear interrupts */ /* reading should also clear interrupts */
mask = readl(mmio_base + PDC_INT_SEQMASK); mask = readl(host_mmio + PDC_INT_SEQMASK);
if (mask == 0xffffffff && hotplug_status == 0) { if (mask == 0xffffffff && hotplug_status == 0) {
VPRINTK("QUICK EXIT 2\n"); VPRINTK("QUICK EXIT 2\n");
goto done_irq; goto done_irq;
} }
mask &= 0xffff; /* only 16 tags possible */ mask &= 0xffff; /* only 16 SEQIDs possible */
if (mask == 0 && hotplug_status == 0) { if (mask == 0 && hotplug_status == 0) {
VPRINTK("QUICK EXIT 3\n"); VPRINTK("QUICK EXIT 3\n");
goto done_irq; goto done_irq;
} }
writel(mask, mmio_base + PDC_INT_SEQMASK); writel(mask, host_mmio + PDC_INT_SEQMASK);
is_sataii_tx4 = pdc_is_sataii_tx4(host->ports[0]->flags); is_sataii_tx4 = pdc_is_sataii_tx4(host->ports[0]->flags);
...@@ -875,23 +872,24 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) ...@@ -875,23 +872,24 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
} }
static inline void pdc_packet_start(struct ata_queued_cmd *qc) static void pdc_packet_start(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct pdc_port_priv *pp = ap->private_data; struct pdc_port_priv *pp = ap->private_data;
void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR]; void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
unsigned int port_no = ap->port_no; unsigned int port_no = ap->port_no;
u8 seq = (u8) (port_no + 1); u8 seq = (u8) (port_no + 1);
VPRINTK("ENTER, ap %p\n", ap); VPRINTK("ENTER, ap %p\n", ap);
writel(0x00000001, mmio + (seq * 4)); writel(0x00000001, host_mmio + (seq * 4));
readl(mmio + (seq * 4)); /* flush */ readl(host_mmio + (seq * 4)); /* flush */
pp->pkt[2] = seq; pp->pkt[2] = seq;
wmb(); /* flush PRD, pkt writes */ wmb(); /* flush PRD, pkt writes */
writel(pp->pkt_dma, ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); writel(pp->pkt_dma, ata_mmio + PDC_PKT_SUBMIT);
readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */ readl(ata_mmio + PDC_PKT_SUBMIT); /* flush */
} }
static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc) static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc)
...@@ -909,11 +907,9 @@ static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc) ...@@ -909,11 +907,9 @@ static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc)
case ATA_PROT_DMA: case ATA_PROT_DMA:
pdc_packet_start(qc); pdc_packet_start(qc);
return 0; return 0;
default: default:
break; break;
} }
return ata_sff_qc_issue(qc); return ata_sff_qc_issue(qc);
} }
...@@ -987,7 +983,7 @@ static void pdc_ata_setup_port(struct ata_port *ap, ...@@ -987,7 +983,7 @@ static void pdc_ata_setup_port(struct ata_port *ap,
static void pdc_host_init(struct ata_host *host) static void pdc_host_init(struct ata_host *host)
{ {
void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II; int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II;
int hotplug_offset; int hotplug_offset;
u32 tmp; u32 tmp;
...@@ -1004,38 +1000,38 @@ static void pdc_host_init(struct ata_host *host) ...@@ -1004,38 +1000,38 @@ static void pdc_host_init(struct ata_host *host)
*/ */
/* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */ /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */
tmp = readl(mmio + PDC_FLASH_CTL); tmp = readl(host_mmio + PDC_FLASH_CTL);
tmp |= 0x02000; /* bit 13 (enable bmr burst) */ tmp |= 0x02000; /* bit 13 (enable bmr burst) */
if (!is_gen2) if (!is_gen2)
tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */ tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */
writel(tmp, mmio + PDC_FLASH_CTL); writel(tmp, host_mmio + PDC_FLASH_CTL);
/* clear plug/unplug flags for all ports */ /* clear plug/unplug flags for all ports */
tmp = readl(mmio + hotplug_offset); tmp = readl(host_mmio + hotplug_offset);
writel(tmp | 0xff, mmio + hotplug_offset); writel(tmp | 0xff, host_mmio + hotplug_offset);
/* unmask plug/unplug ints */ /* unmask plug/unplug ints */
tmp = readl(mmio + hotplug_offset); tmp = readl(host_mmio + hotplug_offset);
writel(tmp & ~0xff0000, mmio + hotplug_offset); writel(tmp & ~0xff0000, host_mmio + hotplug_offset);
/* don't initialise TBG or SLEW on 2nd generation chips */ /* don't initialise TBG or SLEW on 2nd generation chips */
if (is_gen2) if (is_gen2)
return; return;
/* reduce TBG clock to 133 Mhz. */ /* reduce TBG clock to 133 Mhz. */
tmp = readl(mmio + PDC_TBG_MODE); tmp = readl(host_mmio + PDC_TBG_MODE);
tmp &= ~0x30000; /* clear bit 17, 16*/ tmp &= ~0x30000; /* clear bit 17, 16*/
tmp |= 0x10000; /* set bit 17:16 = 0:1 */ tmp |= 0x10000; /* set bit 17:16 = 0:1 */
writel(tmp, mmio + PDC_TBG_MODE); writel(tmp, host_mmio + PDC_TBG_MODE);
readl(mmio + PDC_TBG_MODE); /* flush */ readl(host_mmio + PDC_TBG_MODE); /* flush */
msleep(10); msleep(10);
/* adjust slew rate control register. */ /* adjust slew rate control register. */
tmp = readl(mmio + PDC_SLEW_CTL); tmp = readl(host_mmio + PDC_SLEW_CTL);
tmp &= 0xFFFFF03F; /* clear bit 11 ~ 6 */ tmp &= 0xFFFFF03F; /* clear bit 11 ~ 6 */
tmp |= 0x00000900; /* set bit 11-9 = 100b , bit 8-6 = 100 */ tmp |= 0x00000900; /* set bit 11-9 = 100b , bit 8-6 = 100 */
writel(tmp, mmio + PDC_SLEW_CTL); writel(tmp, host_mmio + PDC_SLEW_CTL);
} }
static int pdc_ata_init_one(struct pci_dev *pdev, static int pdc_ata_init_one(struct pci_dev *pdev,
...@@ -1045,7 +1041,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, ...@@ -1045,7 +1041,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev,
const struct ata_port_info *pi = &pdc_port_info[ent->driver_data]; const struct ata_port_info *pi = &pdc_port_info[ent->driver_data];
const struct ata_port_info *ppi[PDC_MAX_PORTS]; const struct ata_port_info *ppi[PDC_MAX_PORTS];
struct ata_host *host; struct ata_host *host;
void __iomem *base; void __iomem *host_mmio;
int n_ports, i, rc; int n_ports, i, rc;
int is_sataii_tx4; int is_sataii_tx4;
...@@ -1062,7 +1058,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, ...@@ -1062,7 +1058,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev,
pcim_pin_device(pdev); pcim_pin_device(pdev);
if (rc) if (rc)
return rc; return rc;
base = pcim_iomap_table(pdev)[PDC_MMIO_BAR]; host_mmio = pcim_iomap_table(pdev)[PDC_MMIO_BAR];
/* determine port configuration and setup host */ /* determine port configuration and setup host */
n_ports = 2; n_ports = 2;
...@@ -1072,7 +1068,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, ...@@ -1072,7 +1068,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev,
ppi[i] = pi; ppi[i] = pi;
if (pi->flags & PDC_FLAG_SATA_PATA) { if (pi->flags & PDC_FLAG_SATA_PATA) {
u8 tmp = readb(base + PDC_FLASH_CTL+1); u8 tmp = readb(host_mmio + PDC_FLASH_CTL + 1);
if (!(tmp & 0x80)) if (!(tmp & 0x80))
ppi[n_ports++] = pi + 1; ppi[n_ports++] = pi + 1;
} }
...@@ -1088,13 +1084,13 @@ static int pdc_ata_init_one(struct pci_dev *pdev, ...@@ -1088,13 +1084,13 @@ static int pdc_ata_init_one(struct pci_dev *pdev,
for (i = 0; i < host->n_ports; i++) { for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i]; struct ata_port *ap = host->ports[i];
unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4); unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
unsigned int port_offset = 0x200 + ata_no * 0x80; unsigned int ata_offset = 0x200 + ata_no * 0x80;
unsigned int scr_offset = 0x400 + ata_no * 0x100; unsigned int scr_offset = 0x400 + ata_no * 0x100;
pdc_ata_setup_port(ap, base + port_offset, base + scr_offset); pdc_ata_setup_port(ap, host_mmio + ata_offset, host_mmio + scr_offset);
ata_port_pbar_desc(ap, PDC_MMIO_BAR, -1, "mmio"); ata_port_pbar_desc(ap, PDC_MMIO_BAR, -1, "mmio");
ata_port_pbar_desc(ap, PDC_MMIO_BAR, port_offset, "port"); ata_port_pbar_desc(ap, PDC_MMIO_BAR, ata_offset, "ata");
} }
/* initialize adapter */ /* initialize adapter */
......
...@@ -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