Commit 468f8afd authored by Linus Torvalds's avatar Linus Torvalds

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

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev: (23 commits)
  libata: don't configure downstream links faster than the upstream link
  libata: request PHY speed configuration on SControl access failure
  libata: consider errors not associated with commands for speed down
  libata: more robust reset failure handling
  libata: cosmetic clean up / reorganization of ata_eh_reset()
  libata: fix timing computation in ata_eh_reset()
  libata: increase 128 KB / cmd limit for ATAPI tape drives
  sata_promise: fix endianess bug in ASIC PRD bug workaround
  libata: fix docbook
  make ata_scsi_lpm_get() static
  libata: suppress two warnings
  ata/sata_fsl: Remove ata_scsi_suspend/resume callbacks
  ata/sata_fsl: Remove sending LOG EXT command in sata_fsl_softreset()
  ata/sata_fsl: Move MPC8315DS link speed limit workaround to specific ifdef
  ata/sata_fsl: cleanup style problem
  ata/sata_fsl: remove unneeded sata_fsl_hardreset()
  ata/sata_fsl: remove unneeded on-stack copy of FIS
  ata/sata_fsl: cleanup needless casts to/from void __iomem *
  ata/sata_fsl: Remove unnecessary SCR cases
  ata/sata_fsl: Kill ata_sg_is_last()
  ...
parents ebab8990 5270222f
...@@ -704,8 +704,8 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) ...@@ -704,8 +704,8 @@ static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy)
/** /**
* ata_dev_enable_pm - enable SATA interface power management * ata_dev_enable_pm - enable SATA interface power management
* @device - device to enable ipm for * @dev: device to enable power management
* @policy - the link power management policy * @policy: the link power management policy
* *
* Enable SATA Interface power management. This will enable * Enable SATA Interface power management. This will enable
* Device Interface Power Management (DIPM) for min_power * Device Interface Power Management (DIPM) for min_power
...@@ -735,9 +735,10 @@ void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy) ...@@ -735,9 +735,10 @@ void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy)
return /* rc */; /* hopefully we can use 'rc' eventually */ return /* rc */; /* hopefully we can use 'rc' eventually */
} }
#ifdef CONFIG_PM
/** /**
* ata_dev_disable_pm - disable SATA interface power management * ata_dev_disable_pm - disable SATA interface power management
* @device - device to enable ipm for * @dev: device to disable power management
* *
* Disable SATA Interface power management. This will disable * Disable SATA Interface power management. This will disable
* Device Interface Power Management (DIPM) without changing * Device Interface Power Management (DIPM) without changing
...@@ -755,6 +756,7 @@ static void ata_dev_disable_pm(struct ata_device *dev) ...@@ -755,6 +756,7 @@ static void ata_dev_disable_pm(struct ata_device *dev)
if (ap->ops->disable_pm) if (ap->ops->disable_pm)
ap->ops->disable_pm(ap); ap->ops->disable_pm(ap);
} }
#endif /* CONFIG_PM */
void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy) void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy)
{ {
...@@ -764,6 +766,7 @@ void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy) ...@@ -764,6 +766,7 @@ void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy)
ata_port_schedule_eh(ap); ata_port_schedule_eh(ap);
} }
#ifdef CONFIG_PM
static void ata_lpm_enable(struct ata_host *host) static void ata_lpm_enable(struct ata_host *host)
{ {
struct ata_link *link; struct ata_link *link;
...@@ -789,6 +792,7 @@ static void ata_lpm_disable(struct ata_host *host) ...@@ -789,6 +792,7 @@ static void ata_lpm_disable(struct ata_host *host)
ata_lpm_schedule(ap, ap->pm_policy); ata_lpm_schedule(ap, ap->pm_policy);
} }
} }
#endif /* CONFIG_PM */
/** /**
...@@ -2300,6 +2304,10 @@ int ata_dev_configure(struct ata_device *dev) ...@@ -2300,6 +2304,10 @@ int ata_dev_configure(struct ata_device *dev)
dev->max_sectors = ATA_MAX_SECTORS; dev->max_sectors = ATA_MAX_SECTORS;
} }
if ((dev->class == ATA_DEV_ATAPI) &&
(atapi_command_packet_set(id) == TYPE_TAPE))
dev->max_sectors = ATA_MAX_SECTORS_TAPE;
if (dev->horkage & ATA_HORKAGE_MAX_SEC_128) if (dev->horkage & ATA_HORKAGE_MAX_SEC_128)
dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
dev->max_sectors); dev->max_sectors);
...@@ -2743,17 +2751,27 @@ int sata_down_spd_limit(struct ata_link *link) ...@@ -2743,17 +2751,27 @@ int sata_down_spd_limit(struct ata_link *link)
static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol) static int __sata_set_spd_needed(struct ata_link *link, u32 *scontrol)
{ {
u32 spd, limit; struct ata_link *host_link = &link->ap->link;
u32 limit, target, spd;
limit = link->sata_spd_limit;
if (link->sata_spd_limit == UINT_MAX) /* Don't configure downstream link faster than upstream link.
limit = 0; * It doesn't speed up anything and some PMPs choke on such
* configuration.
*/
if (!ata_is_host_link(link) && host_link->sata_spd)
limit &= (1 << host_link->sata_spd) - 1;
if (limit == UINT_MAX)
target = 0;
else else
limit = fls(link->sata_spd_limit); target = fls(limit);
spd = (*scontrol >> 4) & 0xf; spd = (*scontrol >> 4) & 0xf;
*scontrol = (*scontrol & ~0xf0) | ((limit & 0xf) << 4); *scontrol = (*scontrol & ~0xf0) | ((target & 0xf) << 4);
return spd != limit; return spd != target;
} }
/** /**
...@@ -2776,7 +2794,7 @@ int sata_set_spd_needed(struct ata_link *link) ...@@ -2776,7 +2794,7 @@ int sata_set_spd_needed(struct ata_link *link)
u32 scontrol; u32 scontrol;
if (sata_scr_read(link, SCR_CONTROL, &scontrol)) if (sata_scr_read(link, SCR_CONTROL, &scontrol))
return 0; return 1;
return __sata_set_spd_needed(link, &scontrol); return __sata_set_spd_needed(link, &scontrol);
} }
......
...@@ -1747,6 +1747,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) ...@@ -1747,6 +1747,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
{ {
struct ata_port *ap = link->ap; struct ata_port *ap = link->ap;
struct ata_eh_context *ehc = &link->eh_context; struct ata_eh_context *ehc = &link->eh_context;
struct ata_device *dev;
unsigned int all_err_mask = 0; unsigned int all_err_mask = 0;
int tag, is_io = 0; int tag, is_io = 0;
u32 serror; u32 serror;
...@@ -1818,18 +1819,24 @@ static void ata_eh_link_autopsy(struct ata_link *link) ...@@ -1818,18 +1819,24 @@ static void ata_eh_link_autopsy(struct ata_link *link)
(!is_io && (all_err_mask & ~AC_ERR_DEV))) (!is_io && (all_err_mask & ~AC_ERR_DEV)))
ehc->i.action |= ATA_EH_REVALIDATE; ehc->i.action |= ATA_EH_REVALIDATE;
/* if we have offending qcs and the associated failed device */ /* If we have offending qcs and the associated failed device,
* perform per-dev EH action only on the offending device.
*/
if (ehc->i.dev) { if (ehc->i.dev) {
/* speed down */
ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io,
all_err_mask);
/* perform per-dev EH action only on the offending device */
ehc->i.dev_action[ehc->i.dev->devno] |= ehc->i.dev_action[ehc->i.dev->devno] |=
ehc->i.action & ATA_EH_PERDEV_MASK; ehc->i.action & ATA_EH_PERDEV_MASK;
ehc->i.action &= ~ATA_EH_PERDEV_MASK; ehc->i.action &= ~ATA_EH_PERDEV_MASK;
} }
/* consider speeding down */
dev = ehc->i.dev;
if (!dev && ata_link_max_devices(link) == 1 &&
ata_dev_enabled(link->device))
dev = link->device;
if (dev)
ehc->i.action |= ata_eh_speed_down(dev, is_io, all_err_mask);
DPRINTK("EXIT\n"); DPRINTK("EXIT\n");
} }
...@@ -2065,16 +2072,19 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2065,16 +2072,19 @@ int ata_eh_reset(struct ata_link *link, int classify,
ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) ata_reset_fn_t hardreset, ata_postreset_fn_t postreset)
{ {
const int max_tries = ARRAY_SIZE(ata_eh_reset_timeouts);
struct ata_port *ap = link->ap; struct ata_port *ap = link->ap;
struct ata_eh_context *ehc = &link->eh_context; struct ata_eh_context *ehc = &link->eh_context;
unsigned int *classes = ehc->classes; unsigned int *classes = ehc->classes;
unsigned int lflags = link->flags;
int verbose = !(ehc->i.flags & ATA_EHI_QUIET); int verbose = !(ehc->i.flags & ATA_EHI_QUIET);
int try = 0; int try = 0;
struct ata_device *dev; struct ata_device *dev;
unsigned long deadline; unsigned long deadline, now;
unsigned int tmp_action; unsigned int tmp_action;
ata_reset_fn_t reset; ata_reset_fn_t reset;
unsigned long flags; unsigned long flags;
u32 sstatus;
int rc; int rc;
/* about to reset */ /* about to reset */
...@@ -2106,7 +2116,7 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2106,7 +2116,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
/* Determine which reset to use and record in ehc->i.action. /* Determine which reset to use and record in ehc->i.action.
* prereset() may examine and modify it. * prereset() may examine and modify it.
*/ */
if (softreset && (!hardreset || (!(link->flags & ATA_LFLAG_NO_SRST) && if (softreset && (!hardreset || (!(lflags & ATA_LFLAG_NO_SRST) &&
!sata_set_spd_needed(link) && !sata_set_spd_needed(link) &&
!(ehc->i.action & ATA_EH_HARDRESET)))) !(ehc->i.action & ATA_EH_HARDRESET))))
tmp_action = ATA_EH_SOFTRESET; tmp_action = ATA_EH_SOFTRESET;
...@@ -2181,55 +2191,36 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2181,55 +2191,36 @@ int ata_eh_reset(struct ata_link *link, int classify,
"follow-up softreset required " "follow-up softreset required "
"but no softreset avaliable\n"); "but no softreset avaliable\n");
rc = -EINVAL; rc = -EINVAL;
goto out; goto fail;
} }
ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK); ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK);
rc = ata_do_reset(link, reset, classes, deadline); rc = ata_do_reset(link, reset, classes, deadline);
}
if (rc == 0 && classify && classes[0] == ATA_DEV_UNKNOWN && /* -EAGAIN can happen if we skipped followup SRST */
!(link->flags & ATA_LFLAG_ASSUME_CLASS)) { if (rc && rc != -EAGAIN)
ata_link_printk(link, KERN_ERR, goto fail;
/* was classification successful? */
if (classify && classes[0] == ATA_DEV_UNKNOWN &&
!(lflags & ATA_LFLAG_ASSUME_CLASS)) {
if (try < max_tries) {
ata_link_printk(link, KERN_WARNING,
"classification failed\n"); "classification failed\n");
rc = -EINVAL; rc = -EINVAL;
goto out; goto fail;
}
} }
/* if we skipped follow-up srst, clear rc */ ata_link_printk(link, KERN_WARNING,
if (rc == -EAGAIN) "classfication failed, assuming ATA\n");
rc = 0; lflags |= ATA_LFLAG_ASSUME_ATA;
if (rc && rc != -ERESTART && try < ARRAY_SIZE(ata_eh_reset_timeouts)) {
unsigned long now = jiffies;
if (time_before(now, deadline)) {
unsigned long delta = deadline - jiffies;
ata_link_printk(link, KERN_WARNING, "reset failed "
"(errno=%d), retrying in %u secs\n",
rc, (jiffies_to_msecs(delta) + 999) / 1000);
while (delta)
delta = schedule_timeout_uninterruptible(delta);
} }
if (rc == -EPIPE ||
try == ARRAY_SIZE(ata_eh_reset_timeouts) - 1)
sata_down_spd_limit(link);
if (hardreset)
reset = hardreset;
goto retry;
}
if (rc == 0) {
u32 sstatus;
ata_link_for_each_dev(dev, link) { ata_link_for_each_dev(dev, link) {
/* After the reset, the device state is PIO 0 /* After the reset, the device state is PIO 0 and the
* and the controller state is undefined. * controller state is undefined. Reset also wakes up
* Reset also wakes up drives from sleeping * drives from sleeping mode.
* mode.
*/ */
dev->pio_mode = XFER_PIO_0; dev->pio_mode = XFER_PIO_0;
dev->flags &= ~ATA_DFLAG_SLEEPING; dev->flags &= ~ATA_DFLAG_SLEEPING;
...@@ -2238,9 +2229,9 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2238,9 +2229,9 @@ int ata_eh_reset(struct ata_link *link, int classify,
continue; continue;
/* apply class override and convert UNKNOWN to NONE */ /* apply class override and convert UNKNOWN to NONE */
if (link->flags & ATA_LFLAG_ASSUME_ATA) if (lflags & ATA_LFLAG_ASSUME_ATA)
classes[dev->devno] = ATA_DEV_ATA; classes[dev->devno] = ATA_DEV_ATA;
else if (link->flags & ATA_LFLAG_ASSUME_SEMB) else if (lflags & ATA_LFLAG_ASSUME_SEMB)
classes[dev->devno] = ATA_DEV_SEMB_UNSUP; /* not yet */ classes[dev->devno] = ATA_DEV_SEMB_UNSUP; /* not yet */
else if (classes[dev->devno] == ATA_DEV_UNKNOWN) else if (classes[dev->devno] == ATA_DEV_UNKNOWN)
classes[dev->devno] = ATA_DEV_NONE; classes[dev->devno] = ATA_DEV_NONE;
...@@ -2256,7 +2247,8 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2256,7 +2247,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
/* reset successful, schedule revalidation */ /* reset successful, schedule revalidation */
ata_eh_done(link, NULL, ehc->i.action & ATA_EH_RESET_MASK); ata_eh_done(link, NULL, ehc->i.action & ATA_EH_RESET_MASK);
ehc->i.action |= ATA_EH_REVALIDATE; ehc->i.action |= ATA_EH_REVALIDATE;
}
rc = 0;
out: out:
/* clear hotplug flag */ /* clear hotplug flag */
ehc->i.flags &= ~ATA_EHI_HOTPLUGGED; ehc->i.flags &= ~ATA_EHI_HOTPLUGGED;
...@@ -2266,6 +2258,28 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2266,6 +2258,28 @@ int ata_eh_reset(struct ata_link *link, int classify,
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
return rc; return rc;
fail:
if (rc == -ERESTART || try >= max_tries)
goto out;
now = jiffies;
if (time_before(now, deadline)) {
unsigned long delta = deadline - now;
ata_link_printk(link, KERN_WARNING, "reset failed "
"(errno=%d), retrying in %u secs\n",
rc, (jiffies_to_msecs(delta) + 999) / 1000);
while (delta)
delta = schedule_timeout_uninterruptible(delta);
}
if (rc == -EPIPE || try == max_tries - 1)
sata_down_spd_limit(link);
if (hardreset)
reset = hardreset;
goto retry;
} }
static int ata_eh_revalidate_and_attach(struct ata_link *link, static int ata_eh_revalidate_and_attach(struct ata_link *link,
......
...@@ -120,7 +120,7 @@ static const struct { ...@@ -120,7 +120,7 @@ static const struct {
{ MEDIUM_POWER, "medium_power" }, { MEDIUM_POWER, "medium_power" },
}; };
const char *ata_scsi_lpm_get(enum link_pm policy) static const char *ata_scsi_lpm_get(enum link_pm policy)
{ {
int i; int i;
......
This diff is collapsed.
...@@ -587,7 +587,7 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc) ...@@ -587,7 +587,7 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
VPRINTK("Splitting last PRD.\n"); VPRINTK("Splitting last PRD.\n");
addr = le32_to_cpu(ap->prd[idx - 1].addr); addr = le32_to_cpu(ap->prd[idx - 1].addr);
ap->prd[idx - 1].flags_len -= cpu_to_le32(SG_COUNT_ASIC_BUG); ap->prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG);
VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG); VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG);
addr = addr + len - SG_COUNT_ASIC_BUG; addr = addr + len - SG_COUNT_ASIC_BUG;
......
...@@ -43,6 +43,7 @@ enum { ...@@ -43,6 +43,7 @@ enum {
ATA_MAX_SECTORS_128 = 128, ATA_MAX_SECTORS_128 = 128,
ATA_MAX_SECTORS = 256, ATA_MAX_SECTORS = 256,
ATA_MAX_SECTORS_LBA48 = 65535,/* TODO: 65536? */ ATA_MAX_SECTORS_LBA48 = 65535,/* TODO: 65536? */
ATA_MAX_SECTORS_TAPE = 65535,
ATA_ID_WORDS = 256, ATA_ID_WORDS = 256,
ATA_ID_SERNO = 10, ATA_ID_SERNO = 10,
...@@ -544,6 +545,11 @@ static inline int atapi_cdb_len(const u16 *dev_id) ...@@ -544,6 +545,11 @@ static inline int atapi_cdb_len(const u16 *dev_id)
} }
} }
static inline int atapi_command_packet_set(const u16 *dev_id)
{
return (dev_id[0] >> 8) & 0x1f;
}
static inline int is_atapi_taskfile(const struct ata_taskfile *tf) static inline int is_atapi_taskfile(const struct ata_taskfile *tf)
{ {
return (tf->protocol == ATA_PROT_ATAPI) || return (tf->protocol == ATA_PROT_ATAPI) ||
......
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