Commit 82219fce authored by Linus Torvalds's avatar Linus Torvalds

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

* 'upstream-2.6.28' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  ata_piix: IDE Mode SATA patch for Intel Ibex Peak DeviceIDs
  libata-eh: clear UNIT ATTENTION after reset
  ata_piix: add Hercules EC-900 mini-notebook to ich_laptop short cable list
  libata: reorder ata_device to remove 8 bytes of padding on 64 bits
  [libata] pata_bf54x: Add proper PM operation
  pata_sil680: convert CONFIG_PPC_MERGE to CONFIG_PPC
  libata: Implement disk shock protection support
  [libata] Introduce ata_id_has_unload()
  PATA: RPC now selects HAVE_PATA_PLATFORM for pata platform driver
  ata_piix: drop merged SCR access and use slave_link instead
  libata: implement slave_link
  libata: misc updates to prepare for slave link
  libata: reimplement link iterator
  libata: make SCR access ops per-link
parents 3fa8749e 0395e61b
...@@ -663,7 +663,7 @@ config HAVE_PATA_PLATFORM ...@@ -663,7 +663,7 @@ config HAVE_PATA_PLATFORM
config PATA_PLATFORM config PATA_PLATFORM
tristate "Generic platform device PATA support" tristate "Generic platform device PATA support"
depends on EMBEDDED || ARCH_RPC || PPC || HAVE_PATA_PLATFORM depends on EMBEDDED || PPC || HAVE_PATA_PLATFORM
help help
This option enables support for generic directly connected ATA This option enables support for generic directly connected ATA
devices commonly found on embedded systems. devices commonly found on embedded systems.
......
...@@ -267,8 +267,8 @@ struct ahci_port_priv { ...@@ -267,8 +267,8 @@ struct ahci_port_priv {
* per PM slot */ * per PM slot */
}; };
static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc); static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
...@@ -316,6 +316,7 @@ static struct device_attribute *ahci_shost_attrs[] = { ...@@ -316,6 +316,7 @@ static struct device_attribute *ahci_shost_attrs[] = {
static struct device_attribute *ahci_sdev_attrs[] = { static struct device_attribute *ahci_sdev_attrs[] = {
&dev_attr_sw_activity, &dev_attr_sw_activity,
&dev_attr_unload_heads,
NULL NULL
}; };
...@@ -820,10 +821,10 @@ static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg) ...@@ -820,10 +821,10 @@ static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)
return 0; return 0;
} }
static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
{ {
void __iomem *port_mmio = ahci_port_base(ap); void __iomem *port_mmio = ahci_port_base(link->ap);
int offset = ahci_scr_offset(ap, sc_reg); int offset = ahci_scr_offset(link->ap, sc_reg);
if (offset) { if (offset) {
*val = readl(port_mmio + offset); *val = readl(port_mmio + offset);
...@@ -832,10 +833,10 @@ static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) ...@@ -832,10 +833,10 @@ static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
return -EINVAL; return -EINVAL;
} }
static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
{ {
void __iomem *port_mmio = ahci_port_base(ap); void __iomem *port_mmio = ahci_port_base(link->ap);
int offset = ahci_scr_offset(ap, sc_reg); int offset = ahci_scr_offset(link->ap, sc_reg);
if (offset) { if (offset) {
writel(val, port_mmio + offset); writel(val, port_mmio + offset);
...@@ -973,7 +974,7 @@ static void ahci_disable_alpm(struct ata_port *ap) ...@@ -973,7 +974,7 @@ static void ahci_disable_alpm(struct ata_port *ap)
writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT); writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT);
/* go ahead and clean out PhyRdy Change from Serror too */ /* go ahead and clean out PhyRdy Change from Serror too */
ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18))); ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
/* /*
* Clear flag to indicate that we should ignore all PhyRdy * Clear flag to indicate that we should ignore all PhyRdy
...@@ -1937,8 +1938,8 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) ...@@ -1937,8 +1938,8 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
ata_ehi_push_desc(host_ehi, "irq_stat 0x%08x", irq_stat); ata_ehi_push_desc(host_ehi, "irq_stat 0x%08x", irq_stat);
/* AHCI needs SError cleared; otherwise, it might lock up */ /* AHCI needs SError cleared; otherwise, it might lock up */
ahci_scr_read(ap, SCR_ERROR, &serror); ahci_scr_read(&ap->link, SCR_ERROR, &serror);
ahci_scr_write(ap, SCR_ERROR, serror); ahci_scr_write(&ap->link, SCR_ERROR, serror);
host_ehi->serror |= serror; host_ehi->serror |= serror;
/* some controllers set IRQ_IF_ERR on device errors, ignore it */ /* some controllers set IRQ_IF_ERR on device errors, ignore it */
...@@ -2027,7 +2028,7 @@ static void ahci_port_intr(struct ata_port *ap) ...@@ -2027,7 +2028,7 @@ static void ahci_port_intr(struct ata_port *ap)
if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) && if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) &&
(status & PORT_IRQ_PHYRDY)) { (status & PORT_IRQ_PHYRDY)) {
status &= ~PORT_IRQ_PHYRDY; status &= ~PORT_IRQ_PHYRDY;
ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18))); ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
} }
if (unlikely(status & PORT_IRQ_ERROR)) { if (unlikely(status & PORT_IRQ_ERROR)) {
......
...@@ -165,8 +165,10 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev); ...@@ -165,8 +165,10 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev);
static int ich_pata_cable_detect(struct ata_port *ap); static int ich_pata_cable_detect(struct ata_port *ap);
static u8 piix_vmw_bmdma_status(struct ata_port *ap); static u8 piix_vmw_bmdma_status(struct ata_port *ap);
static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val); static int piix_sidpr_scr_read(struct ata_link *link,
static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val); unsigned int reg, u32 *val);
static int piix_sidpr_scr_write(struct ata_link *link,
unsigned int reg, u32 val);
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int piix_pci_device_resume(struct pci_dev *pdev); static int piix_pci_device_resume(struct pci_dev *pdev);
...@@ -278,12 +280,15 @@ static const struct pci_device_id piix_pci_tbl[] = { ...@@ -278,12 +280,15 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* SATA Controller IDE (PCH) */ /* SATA Controller IDE (PCH) */
{ 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, { 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
/* SATA Controller IDE (PCH) */ /* SATA Controller IDE (PCH) */
{ 0x8086, 0x3b21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (PCH) */
{ 0x8086, 0x3b26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { 0x8086, 0x3b26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (PCH) */ /* SATA Controller IDE (PCH) */
{ 0x8086, 0x3b28, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
/* SATA Controller IDE (PCH) */
{ 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (PCH) */ /* SATA Controller IDE (PCH) */
{ 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
{ } /* terminate list */ { } /* terminate list */
}; };
...@@ -582,6 +587,7 @@ static const struct ich_laptop ich_laptop[] = { ...@@ -582,6 +587,7 @@ static const struct ich_laptop ich_laptop[] = {
{ 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
{ 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
{ 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
{ 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */
{ 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
{ 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */
{ 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
...@@ -885,23 +891,9 @@ static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev) ...@@ -885,23 +891,9 @@ static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev)
* Serial ATA Index/Data Pair Superset Registers access * Serial ATA Index/Data Pair Superset Registers access
* *
* Beginning from ICH8, there's a sane way to access SCRs using index * Beginning from ICH8, there's a sane way to access SCRs using index
* and data register pair located at BAR5. This creates an * and data register pair located at BAR5 which means that we have
* interesting problem of mapping two SCRs to one port. * separate SCRs for master and slave. This is handled using libata
* * slave_link facility.
* Although they have separate SCRs, the master and slave aren't
* independent enough to be treated as separate links - e.g. softreset
* resets both. Also, there's no protocol defined for hard resetting
* singled device sharing the virtual port (no defined way to acquire
* device signature). This is worked around by merging the SCR values
* into one sensible value and requesting follow-up SRST after
* hardreset.
*
* SCR merging is perfomed in nibbles which is the unit contents in
* SCRs are organized. If two values are equal, the value is used.
* When they differ, merge table which lists precedence of possible
* values is consulted and the first match or the last entry when
* nothing matches is used. When there's no merge table for the
* specific nibble, value from the first port is used.
*/ */
static const int piix_sidx_map[] = { static const int piix_sidx_map[] = {
[SCR_STATUS] = 0, [SCR_STATUS] = 0,
...@@ -909,120 +901,38 @@ static const int piix_sidx_map[] = { ...@@ -909,120 +901,38 @@ static const int piix_sidx_map[] = {
[SCR_CONTROL] = 1, [SCR_CONTROL] = 1,
}; };
static void piix_sidpr_sel(struct ata_device *dev, unsigned int reg) static void piix_sidpr_sel(struct ata_link *link, unsigned int reg)
{ {
struct ata_port *ap = dev->link->ap; struct ata_port *ap = link->ap;
struct piix_host_priv *hpriv = ap->host->private_data; struct piix_host_priv *hpriv = ap->host->private_data;
iowrite32(((ap->port_no * 2 + dev->devno) << 8) | piix_sidx_map[reg], iowrite32(((ap->port_no * 2 + link->pmp) << 8) | piix_sidx_map[reg],
hpriv->sidpr + PIIX_SIDPR_IDX); hpriv->sidpr + PIIX_SIDPR_IDX);
} }
static int piix_sidpr_read(struct ata_device *dev, unsigned int reg) static int piix_sidpr_scr_read(struct ata_link *link,
unsigned int reg, u32 *val)
{ {
struct piix_host_priv *hpriv = dev->link->ap->host->private_data; struct piix_host_priv *hpriv = link->ap->host->private_data;
piix_sidpr_sel(dev, reg);
return ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
}
static void piix_sidpr_write(struct ata_device *dev, unsigned int reg, u32 val)
{
struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
piix_sidpr_sel(dev, reg);
iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
}
static u32 piix_merge_scr(u32 val0, u32 val1, const int * const *merge_tbl)
{
u32 val = 0;
int i, mi;
for (i = 0, mi = 0; i < 32 / 4; i++) {
u8 c0 = (val0 >> (i * 4)) & 0xf;
u8 c1 = (val1 >> (i * 4)) & 0xf;
u8 merged = c0;
const int *cur;
/* if no merge preference, assume the first value */
cur = merge_tbl[mi];
if (!cur)
goto done;
mi++;
/* if two values equal, use it */
if (c0 == c1)
goto done;
/* choose the first match or the last from the merge table */
while (*cur != -1) {
if (c0 == *cur || c1 == *cur)
break;
cur++;
}
if (*cur == -1)
cur--;
merged = *cur;
done:
val |= merged << (i * 4);
}
return val;
}
static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val)
{
const int * const sstatus_merge_tbl[] = {
/* DET */ (const int []){ 1, 3, 0, 4, 3, -1 },
/* SPD */ (const int []){ 2, 1, 0, -1 },
/* IPM */ (const int []){ 6, 2, 1, 0, -1 },
NULL,
};
const int * const scontrol_merge_tbl[] = {
/* DET */ (const int []){ 1, 0, 4, 0, -1 },
/* SPD */ (const int []){ 0, 2, 1, 0, -1 },
/* IPM */ (const int []){ 0, 1, 2, 3, 0, -1 },
NULL,
};
u32 v0, v1;
if (reg >= ARRAY_SIZE(piix_sidx_map)) if (reg >= ARRAY_SIZE(piix_sidx_map))
return -EINVAL; return -EINVAL;
if (!(ap->flags & ATA_FLAG_SLAVE_POSS)) { piix_sidpr_sel(link, reg);
*val = piix_sidpr_read(&ap->link.device[0], reg); *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
return 0;
}
v0 = piix_sidpr_read(&ap->link.device[0], reg);
v1 = piix_sidpr_read(&ap->link.device[1], reg);
switch (reg) {
case SCR_STATUS:
*val = piix_merge_scr(v0, v1, sstatus_merge_tbl);
break;
case SCR_ERROR:
*val = v0 | v1;
break;
case SCR_CONTROL:
*val = piix_merge_scr(v0, v1, scontrol_merge_tbl);
break;
}
return 0; return 0;
} }
static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val) static int piix_sidpr_scr_write(struct ata_link *link,
unsigned int reg, u32 val)
{ {
struct piix_host_priv *hpriv = link->ap->host->private_data;
if (reg >= ARRAY_SIZE(piix_sidx_map)) if (reg >= ARRAY_SIZE(piix_sidx_map))
return -EINVAL; return -EINVAL;
piix_sidpr_write(&ap->link.device[0], reg, val); piix_sidpr_sel(link, reg);
iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
if (ap->flags & ATA_FLAG_SLAVE_POSS)
piix_sidpr_write(&ap->link.device[1], reg, val);
return 0; return 0;
} }
...@@ -1363,28 +1273,28 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev, ...@@ -1363,28 +1273,28 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev,
return map; return map;
} }
static void __devinit piix_init_sidpr(struct ata_host *host) static int __devinit piix_init_sidpr(struct ata_host *host)
{ {
struct pci_dev *pdev = to_pci_dev(host->dev); struct pci_dev *pdev = to_pci_dev(host->dev);
struct piix_host_priv *hpriv = host->private_data; struct piix_host_priv *hpriv = host->private_data;
struct ata_device *dev0 = &host->ports[0]->link.device[0]; struct ata_link *link0 = &host->ports[0]->link;
u32 scontrol; u32 scontrol;
int i; int i, rc;
/* check for availability */ /* check for availability */
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
if (hpriv->map[i] == IDE) if (hpriv->map[i] == IDE)
return; return 0;
if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR)) if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR))
return; return 0;
if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 || if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 ||
pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN) pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN)
return; return 0;
if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME)) if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME))
return; return 0;
hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR]; hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
...@@ -1392,7 +1302,7 @@ static void __devinit piix_init_sidpr(struct ata_host *host) ...@@ -1392,7 +1302,7 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
* Give it a test drive by inhibiting power save modes which * Give it a test drive by inhibiting power save modes which
* we'll do anyway. * we'll do anyway.
*/ */
scontrol = piix_sidpr_read(dev0, SCR_CONTROL); piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
/* if IPM is already 3, SCR access is probably working. Don't /* if IPM is already 3, SCR access is probably working. Don't
* un-inhibit power save modes as BIOS might have inhibited * un-inhibit power save modes as BIOS might have inhibited
...@@ -1400,18 +1310,30 @@ static void __devinit piix_init_sidpr(struct ata_host *host) ...@@ -1400,18 +1310,30 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
*/ */
if ((scontrol & 0xf00) != 0x300) { if ((scontrol & 0xf00) != 0x300) {
scontrol |= 0x300; scontrol |= 0x300;
piix_sidpr_write(dev0, SCR_CONTROL, scontrol); piix_sidpr_scr_write(link0, SCR_CONTROL, scontrol);
scontrol = piix_sidpr_read(dev0, SCR_CONTROL); piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
if ((scontrol & 0xf00) != 0x300) { if ((scontrol & 0xf00) != 0x300) {
dev_printk(KERN_INFO, host->dev, "SCR access via " dev_printk(KERN_INFO, host->dev, "SCR access via "
"SIDPR is available but doesn't work\n"); "SIDPR is available but doesn't work\n");
return; return 0;
}
}
/* okay, SCRs available, set ops and ask libata for slave_link */
for (i = 0; i < 2; i++) {
struct ata_port *ap = host->ports[i];
ap->ops = &piix_sidpr_sata_ops;
if (ap->flags & ATA_FLAG_SLAVE_POSS) {
rc = ata_slave_link_init(ap);
if (rc)
return rc;
} }
} }
host->ports[0]->ops = &piix_sidpr_sata_ops; return 0;
host->ports[1]->ops = &piix_sidpr_sata_ops;
} }
static void piix_iocfg_bit18_quirk(struct pci_dev *pdev) static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
...@@ -1521,7 +1443,9 @@ static int __devinit piix_init_one(struct pci_dev *pdev, ...@@ -1521,7 +1443,9 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
/* initialize controller */ /* initialize controller */
if (port_flags & ATA_FLAG_SATA) { if (port_flags & ATA_FLAG_SATA) {
piix_init_pcs(host, piix_map_db_table[ent->driver_data]); piix_init_pcs(host, piix_map_db_table[ent->driver_data]);
piix_init_sidpr(host); rc = piix_init_sidpr(host);
if (rc)
return rc;
} }
/* apply IOCFG bit18 quirk */ /* apply IOCFG bit18 quirk */
......
This diff is collapsed.
This diff is collapsed.
...@@ -183,6 +183,105 @@ DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, ...@@ -183,6 +183,105 @@ DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
ata_scsi_lpm_show, ata_scsi_lpm_put); ata_scsi_lpm_show, ata_scsi_lpm_put);
EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy); EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy);
static ssize_t ata_scsi_park_show(struct device *device,
struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev = to_scsi_device(device);
struct ata_port *ap;
struct ata_link *link;
struct ata_device *dev;
unsigned long flags;
unsigned int uninitialized_var(msecs);
int rc = 0;
ap = ata_shost_to_port(sdev->host);
spin_lock_irqsave(ap->lock, flags);
dev = ata_scsi_find_dev(ap, sdev);
if (!dev) {
rc = -ENODEV;
goto unlock;
}
if (dev->flags & ATA_DFLAG_NO_UNLOAD) {
rc = -EOPNOTSUPP;
goto unlock;
}
link = dev->link;
if (ap->pflags & ATA_PFLAG_EH_IN_PROGRESS &&
link->eh_context.unloaded_mask & (1 << dev->devno) &&
time_after(dev->unpark_deadline, jiffies))
msecs = jiffies_to_msecs(dev->unpark_deadline - jiffies);
else
msecs = 0;
unlock:
spin_unlock_irq(ap->lock);
return rc ? rc : snprintf(buf, 20, "%u\n", msecs);
}
static ssize_t ata_scsi_park_store(struct device *device,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct scsi_device *sdev = to_scsi_device(device);
struct ata_port *ap;
struct ata_device *dev;
long int input;
unsigned long flags;
int rc;
rc = strict_strtol(buf, 10, &input);
if (rc || input < -2)
return -EINVAL;
if (input > ATA_TMOUT_MAX_PARK) {
rc = -EOVERFLOW;
input = ATA_TMOUT_MAX_PARK;
}
ap = ata_shost_to_port(sdev->host);
spin_lock_irqsave(ap->lock, flags);
dev = ata_scsi_find_dev(ap, sdev);
if (unlikely(!dev)) {
rc = -ENODEV;
goto unlock;
}
if (dev->class != ATA_DEV_ATA) {
rc = -EOPNOTSUPP;
goto unlock;
}
if (input >= 0) {
if (dev->flags & ATA_DFLAG_NO_UNLOAD) {
rc = -EOPNOTSUPP;
goto unlock;
}
dev->unpark_deadline = ata_deadline(jiffies, input);
dev->link->eh_info.dev_action[dev->devno] |= ATA_EH_PARK;
ata_port_schedule_eh(ap);
complete(&ap->park_req_pending);
} else {
switch (input) {
case -1:
dev->flags &= ~ATA_DFLAG_NO_UNLOAD;
break;
case -2:
dev->flags |= ATA_DFLAG_NO_UNLOAD;
break;
}
}
unlock:
spin_unlock_irqrestore(ap->lock, flags);
return rc ? rc : len;
}
DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
ata_scsi_park_show, ata_scsi_park_store);
EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
{ {
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
...@@ -269,6 +368,12 @@ DEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show, ...@@ -269,6 +368,12 @@ DEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show,
ata_scsi_activity_store); ata_scsi_activity_store);
EXPORT_SYMBOL_GPL(dev_attr_sw_activity); EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
struct device_attribute *ata_common_sdev_attrs[] = {
&dev_attr_unload_heads,
NULL
};
EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *)) void (*done)(struct scsi_cmnd *))
{ {
...@@ -954,6 +1059,9 @@ static int atapi_drain_needed(struct request *rq) ...@@ -954,6 +1059,9 @@ static int atapi_drain_needed(struct request *rq)
static int ata_scsi_dev_config(struct scsi_device *sdev, static int ata_scsi_dev_config(struct scsi_device *sdev,
struct ata_device *dev) struct ata_device *dev)
{ {
if (!ata_id_has_unload(dev->id))
dev->flags |= ATA_DFLAG_NO_UNLOAD;
/* configure max sectors */ /* configure max sectors */
blk_queue_max_sectors(sdev->request_queue, dev->max_sectors); blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
......
...@@ -70,6 +70,7 @@ extern int atapi_passthru16; ...@@ -70,6 +70,7 @@ extern int atapi_passthru16;
extern int libata_fua; extern int libata_fua;
extern int libata_noacpi; extern int libata_noacpi;
extern int libata_allow_tpm; extern int libata_allow_tpm;
extern struct ata_link *ata_dev_phys_link(struct ata_device *dev);
extern void ata_force_cbl(struct ata_port *ap); extern void ata_force_cbl(struct ata_port *ap);
extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); extern u64 ata_tf_to_lba(const struct ata_taskfile *tf);
extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf);
...@@ -107,6 +108,8 @@ extern void ata_qc_issue(struct ata_queued_cmd *qc); ...@@ -107,6 +108,8 @@ extern void ata_qc_issue(struct ata_queued_cmd *qc);
extern void __ata_qc_complete(struct ata_queued_cmd *qc); extern void __ata_qc_complete(struct ata_queued_cmd *qc);
extern int atapi_check_dma(struct ata_queued_cmd *qc); extern int atapi_check_dma(struct ata_queued_cmd *qc);
extern void swap_buf_le16(u16 *buf, unsigned int buf_words); extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
extern bool ata_phys_link_online(struct ata_link *link);
extern bool ata_phys_link_offline(struct ata_link *link);
extern void ata_dev_init(struct ata_device *dev); extern void ata_dev_init(struct ata_device *dev);
extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp); extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
extern int sata_link_init_spd(struct ata_link *link); extern int sata_link_init_spd(struct ata_link *link);
......
...@@ -1632,6 +1632,8 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev) ...@@ -1632,6 +1632,8 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
dev_set_drvdata(&pdev->dev, host);
return 0; return 0;
} }
...@@ -1648,6 +1650,7 @@ static int __devexit bfin_atapi_remove(struct platform_device *pdev) ...@@ -1648,6 +1650,7 @@ static int __devexit bfin_atapi_remove(struct platform_device *pdev)
struct ata_host *host = dev_get_drvdata(dev); struct ata_host *host = dev_get_drvdata(dev);
ata_host_detach(host); ata_host_detach(host);
dev_set_drvdata(&pdev->dev, NULL);
peripheral_free_list(atapi_io_port); peripheral_free_list(atapi_io_port);
...@@ -1655,27 +1658,44 @@ static int __devexit bfin_atapi_remove(struct platform_device *pdev) ...@@ -1655,27 +1658,44 @@ static int __devexit bfin_atapi_remove(struct platform_device *pdev)
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
int bfin_atapi_suspend(struct platform_device *pdev, pm_message_t state) static int bfin_atapi_suspend(struct platform_device *pdev, pm_message_t state)
{ {
struct ata_host *host = dev_get_drvdata(&pdev->dev);
if (host)
return ata_host_suspend(host, state);
else
return 0; return 0;
} }
int bfin_atapi_resume(struct platform_device *pdev) static int bfin_atapi_resume(struct platform_device *pdev)
{ {
struct ata_host *host = dev_get_drvdata(&pdev->dev);
int ret;
if (host) {
ret = bfin_reset_controller(host);
if (ret) {
printk(KERN_ERR DRV_NAME ": Error during HW init\n");
return ret;
}
ata_host_resume(host);
}
return 0; return 0;
} }
#else
#define bfin_atapi_suspend NULL
#define bfin_atapi_resume NULL
#endif #endif
static struct platform_driver bfin_atapi_driver = { static struct platform_driver bfin_atapi_driver = {
.probe = bfin_atapi_probe, .probe = bfin_atapi_probe,
.remove = __devexit_p(bfin_atapi_remove), .remove = __devexit_p(bfin_atapi_remove),
.suspend = bfin_atapi_suspend,
.resume = bfin_atapi_resume,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.owner = THIS_MODULE, .owner = THIS_MODULE,
#ifdef CONFIG_PM
.suspend = bfin_atapi_suspend,
.resume = bfin_atapi_resume,
#endif
}, },
}; };
......
...@@ -230,7 +230,7 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio) ...@@ -230,7 +230,7 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
tmpbyte & 1, tmpbyte & 0x30); tmpbyte & 1, tmpbyte & 0x30);
*try_mmio = 0; *try_mmio = 0;
#ifdef CONFIG_PPC_MERGE #ifdef CONFIG_PPC
if (machine_is(cell)) if (machine_is(cell))
*try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5); *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
#endif #endif
......
...@@ -469,10 +469,10 @@ static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc) ...@@ -469,10 +469,10 @@ static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc)
return true; return true;
} }
static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in, static int sata_fsl_scr_write(struct ata_link *link,
u32 val) unsigned int sc_reg_in, u32 val)
{ {
struct sata_fsl_host_priv *host_priv = ap->host->private_data; struct sata_fsl_host_priv *host_priv = link->ap->host->private_data;
void __iomem *ssr_base = host_priv->ssr_base; void __iomem *ssr_base = host_priv->ssr_base;
unsigned int sc_reg; unsigned int sc_reg;
...@@ -493,10 +493,10 @@ static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in, ...@@ -493,10 +493,10 @@ static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
return 0; return 0;
} }
static int sata_fsl_scr_read(struct ata_port *ap, unsigned int sc_reg_in, static int sata_fsl_scr_read(struct ata_link *link,
u32 *val) unsigned int sc_reg_in, u32 *val)
{ {
struct sata_fsl_host_priv *host_priv = ap->host->private_data; struct sata_fsl_host_priv *host_priv = link->ap->host->private_data;
void __iomem *ssr_base = host_priv->ssr_base; void __iomem *ssr_base = host_priv->ssr_base;
unsigned int sc_reg; unsigned int sc_reg;
...@@ -645,12 +645,12 @@ static int sata_fsl_port_start(struct ata_port *ap) ...@@ -645,12 +645,12 @@ static int sata_fsl_port_start(struct ata_port *ap)
* Workaround for 8315DS board 3gbps link-up issue, * Workaround for 8315DS board 3gbps link-up issue,
* currently limit SATA port to GEN1 speed * currently limit SATA port to GEN1 speed
*/ */
sata_fsl_scr_read(ap, SCR_CONTROL, &temp); sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
temp &= ~(0xF << 4); temp &= ~(0xF << 4);
temp |= (0x1 << 4); temp |= (0x1 << 4);
sata_fsl_scr_write(ap, SCR_CONTROL, temp); sata_fsl_scr_write(&ap->link, SCR_CONTROL, temp);
sata_fsl_scr_read(ap, SCR_CONTROL, &temp); sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
dev_printk(KERN_WARNING, dev, "scr_control, speed limited to %x\n", dev_printk(KERN_WARNING, dev, "scr_control, speed limited to %x\n",
temp); temp);
#endif #endif
...@@ -868,7 +868,7 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, ...@@ -868,7 +868,7 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
ioread32(CQ + hcr_base), ioread32(CQ + hcr_base),
ioread32(CA + hcr_base), ioread32(CC + hcr_base)); ioread32(CA + hcr_base), ioread32(CC + hcr_base));
sata_fsl_scr_read(ap, SCR_ERROR, &Serror); sata_fsl_scr_read(&ap->link, SCR_ERROR, &Serror);
DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
...@@ -972,9 +972,9 @@ static void sata_fsl_error_intr(struct ata_port *ap) ...@@ -972,9 +972,9 @@ static void sata_fsl_error_intr(struct ata_port *ap)
* Handle & Clear SError * Handle & Clear SError
*/ */
sata_fsl_scr_read(ap, SCR_ERROR, &SError); sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
if (unlikely(SError & 0xFFFF0000)) { if (unlikely(SError & 0xFFFF0000)) {
sata_fsl_scr_write(ap, SCR_ERROR, SError); sata_fsl_scr_write(&ap->link, SCR_ERROR, SError);
} }
DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n", DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n",
...@@ -1091,7 +1091,7 @@ static void sata_fsl_host_intr(struct ata_port *ap) ...@@ -1091,7 +1091,7 @@ static void sata_fsl_host_intr(struct ata_port *ap)
hstatus = ioread32(hcr_base + HSTATUS); hstatus = ioread32(hcr_base + HSTATUS);
sata_fsl_scr_read(ap, SCR_ERROR, &SError); sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
if (unlikely(SError & 0xFFFF0000)) { if (unlikely(SError & 0xFFFF0000)) {
DPRINTK("serror @host_intr : 0x%x\n", SError); DPRINTK("serror @host_intr : 0x%x\n", SError);
......
...@@ -269,9 +269,9 @@ static void inic_reset_port(void __iomem *port_base) ...@@ -269,9 +269,9 @@ static void inic_reset_port(void __iomem *port_base)
writeb(0xff, port_base + PORT_IRQ_STAT); writeb(0xff, port_base + PORT_IRQ_STAT);
} }
static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) static int inic_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val)
{ {
void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR; void __iomem *scr_addr = inic_port_base(link->ap) + PORT_SCR;
void __iomem *addr; void __iomem *addr;
if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
...@@ -286,9 +286,9 @@ static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) ...@@ -286,9 +286,9 @@ static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
return 0; return 0;
} }
static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) static int inic_scr_write(struct ata_link *link, unsigned sc_reg, u32 val)
{ {
void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR; void __iomem *scr_addr = inic_port_base(link->ap) + PORT_SCR;
if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
return -EINVAL; return -EINVAL;
......
...@@ -493,10 +493,10 @@ struct mv_hw_ops { ...@@ -493,10 +493,10 @@ struct mv_hw_ops {
void (*reset_bus)(struct ata_host *host, void __iomem *mmio); void (*reset_bus)(struct ata_host *host, void __iomem *mmio);
}; };
static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); static int mv_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val);
static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val);
static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); static int mv5_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val);
static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); static int mv5_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val);
static int mv_port_start(struct ata_port *ap); 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);
static int mv_qc_defer(struct ata_queued_cmd *qc); static int mv_qc_defer(struct ata_queued_cmd *qc);
...@@ -1070,23 +1070,23 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in) ...@@ -1070,23 +1070,23 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in)
return ofs; return ofs;
} }
static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) static int mv_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val)
{ {
unsigned int ofs = mv_scr_offset(sc_reg_in); unsigned int ofs = mv_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU) { if (ofs != 0xffffffffU) {
*val = readl(mv_ap_base(ap) + ofs); *val = readl(mv_ap_base(link->ap) + ofs);
return 0; return 0;
} else } else
return -EINVAL; return -EINVAL;
} }
static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val)
{ {
unsigned int ofs = mv_scr_offset(sc_reg_in); unsigned int ofs = mv_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU) { if (ofs != 0xffffffffU) {
writelfl(val, mv_ap_base(ap) + ofs); writelfl(val, mv_ap_base(link->ap) + ofs);
return 0; return 0;
} else } else
return -EINVAL; return -EINVAL;
...@@ -2251,11 +2251,11 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in) ...@@ -2251,11 +2251,11 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
return ofs; return ofs;
} }
static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) static int mv5_scr_read(struct ata_link *link, unsigned int sc_reg_in, u32 *val)
{ {
struct mv_host_priv *hpriv = ap->host->private_data; struct mv_host_priv *hpriv = link->ap->host->private_data;
void __iomem *mmio = hpriv->base; void __iomem *mmio = hpriv->base;
void __iomem *addr = mv5_phy_base(mmio, ap->port_no); void __iomem *addr = mv5_phy_base(mmio, link->ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in); unsigned int ofs = mv5_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU) { if (ofs != 0xffffffffU) {
...@@ -2265,11 +2265,11 @@ static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) ...@@ -2265,11 +2265,11 @@ static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
return -EINVAL; return -EINVAL;
} }
static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) static int mv5_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val)
{ {
struct mv_host_priv *hpriv = ap->host->private_data; struct mv_host_priv *hpriv = link->ap->host->private_data;
void __iomem *mmio = hpriv->base; void __iomem *mmio = hpriv->base;
void __iomem *addr = mv5_phy_base(mmio, ap->port_no); void __iomem *addr = mv5_phy_base(mmio, link->ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in); unsigned int ofs = mv5_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU) { if (ofs != 0xffffffffU) {
......
...@@ -302,8 +302,8 @@ static void nv_ck804_host_stop(struct ata_host *host); ...@@ -302,8 +302,8 @@ static void nv_ck804_host_stop(struct ata_host *host);
static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance);
static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance);
static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance);
static int nv_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static void nv_nf2_freeze(struct ata_port *ap); static void nv_nf2_freeze(struct ata_port *ap);
static void nv_nf2_thaw(struct ata_port *ap); static void nv_nf2_thaw(struct ata_port *ap);
...@@ -1511,21 +1511,21 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance) ...@@ -1511,21 +1511,21 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance)
return ret; return ret;
} }
static int nv_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
*val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = ioread32(link->ap->ioaddr.scr_addr + (sc_reg * 4));
return 0; return 0;
} }
static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); iowrite32(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
return 0; return 0;
} }
...@@ -2218,9 +2218,9 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) ...@@ -2218,9 +2218,9 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
if (!pp->qc_active) if (!pp->qc_active)
return; return;
if (ap->ops->scr_read(ap, SCR_ERROR, &serror)) if (ap->ops->scr_read(&ap->link, SCR_ERROR, &serror))
return; return;
ap->ops->scr_write(ap, SCR_ERROR, serror); ap->ops->scr_write(&ap->link, SCR_ERROR, serror);
if (ata_stat & ATA_ERR) { if (ata_stat & ATA_ERR) {
ata_ehi_clear_desc(ehi); ata_ehi_clear_desc(ehi);
......
...@@ -137,8 +137,8 @@ struct pdc_port_priv { ...@@ -137,8 +137,8 @@ struct pdc_port_priv {
dma_addr_t pkt_dma; dma_addr_t pkt_dma;
}; };
static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int pdc_sata_scr_read(struct ata_link *link, 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_link *link, 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);
...@@ -386,19 +386,21 @@ static int pdc_sata_cable_detect(struct ata_port *ap) ...@@ -386,19 +386,21 @@ static int pdc_sata_cable_detect(struct ata_port *ap)
return ATA_CBL_SATA; return ATA_CBL_SATA;
} }
static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int pdc_sata_scr_read(struct ata_link *link,
unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
*val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4));
return 0; return 0;
} }
static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int pdc_sata_scr_write(struct ata_link *link,
unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
return 0; return 0;
} }
...@@ -731,7 +733,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, ...@@ -731,7 +733,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
if (sata_scr_valid(&ap->link)) { if (sata_scr_valid(&ap->link)) {
u32 serror; u32 serror;
pdc_sata_scr_read(ap, SCR_ERROR, &serror); pdc_sata_scr_read(&ap->link, SCR_ERROR, &serror);
ehi->serror |= serror; ehi->serror |= serror;
} }
......
...@@ -111,8 +111,8 @@ struct qs_port_priv { ...@@ -111,8 +111,8 @@ struct qs_port_priv {
qs_state_t state; qs_state_t state;
}; };
static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int qs_port_start(struct ata_port *ap); static int qs_port_start(struct ata_port *ap);
static void qs_host_stop(struct ata_host *host); static void qs_host_stop(struct ata_host *host);
...@@ -242,11 +242,11 @@ static int qs_prereset(struct ata_link *link, unsigned long deadline) ...@@ -242,11 +242,11 @@ static int qs_prereset(struct ata_link *link, unsigned long deadline)
return ata_sff_prereset(link, deadline); return ata_sff_prereset(link, deadline);
} }
static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
*val = readl(ap->ioaddr.scr_addr + (sc_reg * 8)); *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 8));
return 0; return 0;
} }
...@@ -256,11 +256,11 @@ static void qs_error_handler(struct ata_port *ap) ...@@ -256,11 +256,11 @@ static void qs_error_handler(struct ata_port *ap)
ata_std_error_handler(ap); ata_std_error_handler(ap);
} }
static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 8)); writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 8));
return 0; return 0;
} }
......
...@@ -115,8 +115,8 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); ...@@ -115,8 +115,8 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int sil_pci_device_resume(struct pci_dev *pdev); static int sil_pci_device_resume(struct pci_dev *pdev);
#endif #endif
static void sil_dev_config(struct ata_device *dev); static void sil_dev_config(struct ata_device *dev);
static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int sil_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); static int sil_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed); static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed);
static void sil_freeze(struct ata_port *ap); static void sil_freeze(struct ata_port *ap);
static void sil_thaw(struct ata_port *ap); static void sil_thaw(struct ata_port *ap);
...@@ -317,9 +317,9 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap, ...@@ -317,9 +317,9 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap,
return NULL; return NULL;
} }
static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int sil_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
{ {
void __iomem *mmio = sil_scr_addr(ap, sc_reg); void __iomem *mmio = sil_scr_addr(link->ap, sc_reg);
if (mmio) { if (mmio) {
*val = readl(mmio); *val = readl(mmio);
...@@ -328,9 +328,9 @@ static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) ...@@ -328,9 +328,9 @@ static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
return -EINVAL; return -EINVAL;
} }
static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int sil_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
{ {
void __iomem *mmio = sil_scr_addr(ap, sc_reg); void __iomem *mmio = sil_scr_addr(link->ap, sc_reg);
if (mmio) { if (mmio) {
writel(val, mmio); writel(val, mmio);
...@@ -352,8 +352,8 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) ...@@ -352,8 +352,8 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
* controllers continue to assert IRQ as long as * controllers continue to assert IRQ as long as
* SError bits are pending. Clear SError immediately. * SError bits are pending. Clear SError immediately.
*/ */
sil_scr_read(ap, SCR_ERROR, &serror); sil_scr_read(&ap->link, SCR_ERROR, &serror);
sil_scr_write(ap, SCR_ERROR, serror); sil_scr_write(&ap->link, SCR_ERROR, serror);
/* Sometimes spurious interrupts occur, double check /* Sometimes spurious interrupts occur, double check
* it's PHYRDY CHG. * it's PHYRDY CHG.
......
...@@ -340,8 +340,8 @@ struct sil24_port_priv { ...@@ -340,8 +340,8 @@ struct sil24_port_priv {
}; };
static void sil24_dev_config(struct ata_device *dev); static void sil24_dev_config(struct ata_device *dev);
static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val); static int sil24_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val);
static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); static int sil24_scr_write(struct ata_link *link, unsigned sc_reg, u32 val);
static int sil24_qc_defer(struct ata_queued_cmd *qc); static int sil24_qc_defer(struct ata_queued_cmd *qc);
static void sil24_qc_prep(struct ata_queued_cmd *qc); static void sil24_qc_prep(struct ata_queued_cmd *qc);
static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
...@@ -504,9 +504,9 @@ static int sil24_scr_map[] = { ...@@ -504,9 +504,9 @@ static int sil24_scr_map[] = {
[SCR_ACTIVE] = 3, [SCR_ACTIVE] = 3,
}; };
static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) static int sil24_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val)
{ {
void __iomem *scr_addr = sil24_port_base(ap) + PORT_SCONTROL; void __iomem *scr_addr = sil24_port_base(link->ap) + PORT_SCONTROL;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr; void __iomem *addr;
...@@ -517,9 +517,9 @@ static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) ...@@ -517,9 +517,9 @@ static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
return -EINVAL; return -EINVAL;
} }
static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) static int sil24_scr_write(struct ata_link *link, unsigned sc_reg, u32 val)
{ {
void __iomem *scr_addr = sil24_port_base(ap) + PORT_SCONTROL; void __iomem *scr_addr = sil24_port_base(link->ap) + PORT_SCONTROL;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr; void __iomem *addr;
......
...@@ -64,8 +64,8 @@ enum { ...@@ -64,8 +64,8 @@ enum {
}; };
static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static const struct pci_device_id sis_pci_tbl[] = { static const struct pci_device_id sis_pci_tbl[] = {
{ PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */ { PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */
...@@ -134,10 +134,11 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg) ...@@ -134,10 +134,11 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
return addr; return addr;
} }
static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static u32 sis_scr_cfg_read(struct ata_link *link,
unsigned int sc_reg, u32 *val)
{ {
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg); unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
u32 val2 = 0; u32 val2 = 0;
u8 pmr; u8 pmr;
...@@ -158,10 +159,11 @@ static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) ...@@ -158,10 +159,11 @@ static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
return 0; return 0;
} }
static int sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int sis_scr_cfg_write(struct ata_link *link,
unsigned int sc_reg, u32 val)
{ {
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg); unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
u8 pmr; u8 pmr;
if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
...@@ -178,8 +180,9 @@ static int sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val) ...@@ -178,8 +180,9 @@ static int sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
return 0; return 0;
} }
static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
{ {
struct ata_port *ap = link->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 pmr; u8 pmr;
...@@ -187,7 +190,7 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) ...@@ -187,7 +190,7 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
return -EINVAL; return -EINVAL;
if (ap->flags & SIS_FLAG_CFGSCR) if (ap->flags & SIS_FLAG_CFGSCR)
return sis_scr_cfg_read(ap, sc_reg, val); return sis_scr_cfg_read(link, sc_reg, val);
pci_read_config_byte(pdev, SIS_PMR, &pmr); pci_read_config_byte(pdev, SIS_PMR, &pmr);
...@@ -202,8 +205,9 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) ...@@ -202,8 +205,9 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
return 0; return 0;
} }
static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
{ {
struct ata_port *ap = link->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 pmr; u8 pmr;
...@@ -213,7 +217,7 @@ static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) ...@@ -213,7 +217,7 @@ static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
pci_read_config_byte(pdev, SIS_PMR, &pmr); pci_read_config_byte(pdev, SIS_PMR, &pmr);
if (ap->flags & SIS_FLAG_CFGSCR) if (ap->flags & SIS_FLAG_CFGSCR)
return sis_scr_cfg_write(ap, sc_reg, val); return sis_scr_cfg_write(link, sc_reg, val);
else { else {
iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
......
...@@ -123,20 +123,22 @@ static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) ...@@ -123,20 +123,22 @@ static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
} }
} }
static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int k2_sata_scr_read(struct ata_link *link,
unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
*val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4));
return 0; return 0;
} }
static int k2_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int k2_sata_scr_write(struct ata_link *link,
unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
return 0; return 0;
} }
......
...@@ -57,8 +57,8 @@ struct uli_priv { ...@@ -57,8 +57,8 @@ struct uli_priv {
}; };
static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int uli_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int uli_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int uli_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); static int uli_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static const struct pci_device_id uli_pci_tbl[] = { static const struct pci_device_id uli_pci_tbl[] = {
{ PCI_VDEVICE(AL, 0x5289), uli_5289 }, { PCI_VDEVICE(AL, 0x5289), uli_5289 },
...@@ -107,39 +107,39 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg) ...@@ -107,39 +107,39 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
return hpriv->scr_cfg_addr[ap->port_no] + (4 * sc_reg); return hpriv->scr_cfg_addr[ap->port_no] + (4 * sc_reg);
} }
static u32 uli_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg) static u32 uli_scr_cfg_read(struct ata_link *link, unsigned int sc_reg)
{ {
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg); unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
u32 val; u32 val;
pci_read_config_dword(pdev, cfg_addr, &val); pci_read_config_dword(pdev, cfg_addr, &val);
return val; return val;
} }
static void uli_scr_cfg_write(struct ata_port *ap, unsigned int scr, u32 val) static void uli_scr_cfg_write(struct ata_link *link, unsigned int scr, u32 val)
{ {
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
unsigned int cfg_addr = get_scr_cfg_addr(ap, scr); unsigned int cfg_addr = get_scr_cfg_addr(link->ap, scr);
pci_write_config_dword(pdev, cfg_addr, val); pci_write_config_dword(pdev, cfg_addr, val);
} }
static int uli_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int uli_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
*val = uli_scr_cfg_read(ap, sc_reg); *val = uli_scr_cfg_read(link, sc_reg);
return 0; return 0;
} }
static int uli_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int uli_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0 if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0
return -EINVAL; return -EINVAL;
uli_scr_cfg_write(ap, sc_reg, val); uli_scr_cfg_write(link, sc_reg, val);
return 0; return 0;
} }
......
...@@ -68,8 +68,8 @@ enum { ...@@ -68,8 +68,8 @@ enum {
}; };
static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static void svia_noop_freeze(struct ata_port *ap); static void svia_noop_freeze(struct ata_port *ap);
static int vt6420_prereset(struct ata_link *link, unsigned long deadline); static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
static int vt6421_pata_cable_detect(struct ata_port *ap); static int vt6421_pata_cable_detect(struct ata_port *ap);
...@@ -152,19 +152,19 @@ MODULE_LICENSE("GPL"); ...@@ -152,19 +152,19 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, svia_pci_tbl); MODULE_DEVICE_TABLE(pci, svia_pci_tbl);
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
*val = ioread32(ap->ioaddr.scr_addr + (4 * sc_reg)); *val = ioread32(link->ap->ioaddr.scr_addr + (4 * sc_reg));
return 0; return 0;
} }
static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg)); iowrite32(val, link->ap->ioaddr.scr_addr + (4 * sc_reg));
return 0; return 0;
} }
...@@ -210,20 +210,20 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline) ...@@ -210,20 +210,20 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline)
goto skip_scr; goto skip_scr;
/* Resume phy. This is the old SATA resume sequence */ /* Resume phy. This is the old SATA resume sequence */
svia_scr_write(ap, SCR_CONTROL, 0x300); svia_scr_write(link, SCR_CONTROL, 0x300);
svia_scr_read(ap, SCR_CONTROL, &scontrol); /* flush */ svia_scr_read(link, SCR_CONTROL, &scontrol); /* flush */
/* wait for phy to become ready, if necessary */ /* wait for phy to become ready, if necessary */
do { do {
msleep(200); msleep(200);
svia_scr_read(ap, SCR_STATUS, &sstatus); svia_scr_read(link, SCR_STATUS, &sstatus);
if ((sstatus & 0xf) != 1) if ((sstatus & 0xf) != 1)
break; break;
} while (time_before(jiffies, timeout)); } while (time_before(jiffies, timeout));
/* open code sata_print_link_status() */ /* open code sata_print_link_status() */
svia_scr_read(ap, SCR_STATUS, &sstatus); svia_scr_read(link, SCR_STATUS, &sstatus);
svia_scr_read(ap, SCR_CONTROL, &scontrol); svia_scr_read(link, SCR_CONTROL, &scontrol);
online = (sstatus & 0xf) == 0x3; online = (sstatus & 0xf) == 0x3;
...@@ -232,7 +232,7 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline) ...@@ -232,7 +232,7 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline)
online ? "up" : "down", sstatus, scontrol); online ? "up" : "down", sstatus, scontrol);
/* SStatus is read one more time */ /* SStatus is read one more time */
svia_scr_read(ap, SCR_STATUS, &sstatus); svia_scr_read(link, SCR_STATUS, &sstatus);
if (!online) { if (!online) {
/* tell EH to bail */ /* tell EH to bail */
......
...@@ -98,20 +98,22 @@ enum { ...@@ -98,20 +98,22 @@ enum {
VSC_SATA_INT_PHY_CHANGE), VSC_SATA_INT_PHY_CHANGE),
}; };
static int vsc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) static int vsc_sata_scr_read(struct ata_link *link,
unsigned int sc_reg, u32 *val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
*val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4));
return 0; return 0;
} }
static int vsc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) static int vsc_sata_scr_write(struct ata_link *link,
unsigned int sc_reg, u32 val)
{ {
if (sc_reg > SCR_CONTROL) if (sc_reg > SCR_CONTROL)
return -EINVAL; return -EINVAL;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
return 0; return 0;
} }
......
...@@ -294,10 +294,10 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc) ...@@ -294,10 +294,10 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc)
} }
} }
static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in, static int sas_ata_scr_write(struct ata_link *link, unsigned int sc_reg_in,
u32 val) u32 val)
{ {
struct domain_device *dev = ap->private_data; struct domain_device *dev = link->ap->private_data;
SAS_DPRINTK("STUB %s\n", __func__); SAS_DPRINTK("STUB %s\n", __func__);
switch (sc_reg_in) { switch (sc_reg_in) {
...@@ -319,10 +319,10 @@ static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in, ...@@ -319,10 +319,10 @@ static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
return 0; return 0;
} }
static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in, static int sas_ata_scr_read(struct ata_link *link, unsigned int sc_reg_in,
u32 *val) u32 *val)
{ {
struct domain_device *dev = ap->private_data; struct domain_device *dev = link->ap->private_data;
SAS_DPRINTK("STUB %s\n", __func__); SAS_DPRINTK("STUB %s\n", __func__);
switch (sc_reg_in) { switch (sc_reg_in) {
......
...@@ -667,6 +667,15 @@ static inline int ata_id_has_dword_io(const u16 *id) ...@@ -667,6 +667,15 @@ static inline int ata_id_has_dword_io(const u16 *id)
return 0; return 0;
} }
static inline int ata_id_has_unload(const u16 *id)
{
if (ata_id_major_version(id) >= 7 &&
(id[ATA_ID_CFSSE] & 0xC000) == 0x4000 &&
id[ATA_ID_CFSSE] & (1 << 13))
return 1;
return 0;
}
static inline int ata_id_current_chs_valid(const u16 *id) static inline int ata_id_current_chs_valid(const u16 *id)
{ {
/* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command
......
...@@ -146,6 +146,7 @@ enum { ...@@ -146,6 +146,7 @@ enum {
ATA_DFLAG_SPUNDOWN = (1 << 14), /* XXX: for spindown_compat */ ATA_DFLAG_SPUNDOWN = (1 << 14), /* XXX: for spindown_compat */
ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */ ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */
ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */
ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */
ATA_DFLAG_INIT_MASK = (1 << 24) - 1, ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
ATA_DFLAG_DETACH = (1 << 24), ATA_DFLAG_DETACH = (1 << 24),
...@@ -244,6 +245,7 @@ enum { ...@@ -244,6 +245,7 @@ enum {
ATA_TMOUT_BOOT = 30000, /* heuristic */ ATA_TMOUT_BOOT = 30000, /* heuristic */
ATA_TMOUT_BOOT_QUICK = 7000, /* heuristic */ ATA_TMOUT_BOOT_QUICK = 7000, /* heuristic */
ATA_TMOUT_INTERNAL_QUICK = 5000, ATA_TMOUT_INTERNAL_QUICK = 5000,
ATA_TMOUT_MAX_PARK = 30000,
/* FIXME: GoVault needs 2s but we can't afford that without /* FIXME: GoVault needs 2s but we can't afford that without
* parallel probing. 800ms is enough for iVDR disk * parallel probing. 800ms is enough for iVDR disk
...@@ -319,8 +321,11 @@ enum { ...@@ -319,8 +321,11 @@ enum {
ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
ATA_EH_ENABLE_LINK = (1 << 3), ATA_EH_ENABLE_LINK = (1 << 3),
ATA_EH_LPM = (1 << 4), /* link power management action */ ATA_EH_LPM = (1 << 4), /* link power management action */
ATA_EH_PARK = (1 << 5), /* unload heads and stop I/O */
ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE, ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK,
ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET |
ATA_EH_ENABLE_LINK | ATA_EH_LPM,
/* ata_eh_info->flags */ /* ata_eh_info->flags */
ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */
...@@ -452,6 +457,7 @@ enum link_pm { ...@@ -452,6 +457,7 @@ enum link_pm {
MEDIUM_POWER, MEDIUM_POWER,
}; };
extern struct device_attribute dev_attr_link_power_management_policy; extern struct device_attribute dev_attr_link_power_management_policy;
extern struct device_attribute dev_attr_unload_heads;
extern struct device_attribute dev_attr_em_message_type; extern struct device_attribute dev_attr_em_message_type;
extern struct device_attribute dev_attr_em_message; extern struct device_attribute dev_attr_em_message;
extern struct device_attribute dev_attr_sw_activity; extern struct device_attribute dev_attr_sw_activity;
...@@ -554,8 +560,8 @@ struct ata_ering { ...@@ -554,8 +560,8 @@ struct ata_ering {
struct ata_device { struct ata_device {
struct ata_link *link; struct ata_link *link;
unsigned int devno; /* 0 or 1 */ unsigned int devno; /* 0 or 1 */
unsigned long flags; /* ATA_DFLAG_xxx */
unsigned int horkage; /* List of broken features */ unsigned int horkage; /* List of broken features */
unsigned long flags; /* ATA_DFLAG_xxx */
struct scsi_device *sdev; /* attached SCSI device */ struct scsi_device *sdev; /* attached SCSI device */
#ifdef CONFIG_ATA_ACPI #ifdef CONFIG_ATA_ACPI
acpi_handle acpi_handle; acpi_handle acpi_handle;
...@@ -564,6 +570,7 @@ struct ata_device { ...@@ -564,6 +570,7 @@ struct ata_device {
/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
u64 n_sectors; /* size of device, if ATA */ u64 n_sectors; /* size of device, if ATA */
unsigned int class; /* ATA_DEV_xxx */ unsigned int class; /* ATA_DEV_xxx */
unsigned long unpark_deadline;
u8 pio_mode; u8 pio_mode;
u8 dma_mode; u8 dma_mode;
...@@ -621,6 +628,7 @@ struct ata_eh_context { ...@@ -621,6 +628,7 @@ struct ata_eh_context {
[ATA_EH_CMD_TIMEOUT_TABLE_SIZE]; [ATA_EH_CMD_TIMEOUT_TABLE_SIZE];
unsigned int classes[ATA_MAX_DEVICES]; unsigned int classes[ATA_MAX_DEVICES];
unsigned int did_probe_mask; unsigned int did_probe_mask;
unsigned int unloaded_mask;
unsigned int saved_ncq_enabled; unsigned int saved_ncq_enabled;
u8 saved_xfer_mode[ATA_MAX_DEVICES]; u8 saved_xfer_mode[ATA_MAX_DEVICES];
/* timestamp for the last reset attempt or success */ /* timestamp for the last reset attempt or success */
...@@ -689,6 +697,7 @@ struct ata_port { ...@@ -689,6 +697,7 @@ struct ata_port {
int nr_active_links; /* #links with active qcs */ int nr_active_links; /* #links with active qcs */
struct ata_link link; /* host default link */ struct ata_link link; /* host default link */
struct ata_link *slave_link; /* see ata_slave_link_init() */
int nr_pmp_links; /* nr of available PMP links */ int nr_pmp_links; /* nr of available PMP links */
struct ata_link *pmp_link; /* array of PMP links */ struct ata_link *pmp_link; /* array of PMP links */
...@@ -709,6 +718,7 @@ struct ata_port { ...@@ -709,6 +718,7 @@ struct ata_port {
struct list_head eh_done_q; struct list_head eh_done_q;
wait_queue_head_t eh_wait_q; wait_queue_head_t eh_wait_q;
int eh_tries; int eh_tries;
struct completion park_req_pending;
pm_message_t pm_mesg; pm_message_t pm_mesg;
int *pm_result; int *pm_result;
...@@ -772,8 +782,8 @@ struct ata_port_operations { ...@@ -772,8 +782,8 @@ struct ata_port_operations {
/* /*
* Optional features * Optional features
*/ */
int (*scr_read)(struct ata_port *ap, unsigned int sc_reg, u32 *val); int (*scr_read)(struct ata_link *link, unsigned int sc_reg, u32 *val);
int (*scr_write)(struct ata_port *ap, unsigned int sc_reg, u32 val); int (*scr_write)(struct ata_link *link, unsigned int sc_reg, u32 val);
void (*pmp_attach)(struct ata_port *ap); void (*pmp_attach)(struct ata_port *ap);
void (*pmp_detach)(struct ata_port *ap); void (*pmp_detach)(struct ata_port *ap);
int (*enable_pm)(struct ata_port *ap, enum link_pm policy); int (*enable_pm)(struct ata_port *ap, enum link_pm policy);
...@@ -895,6 +905,7 @@ extern void ata_port_disable(struct ata_port *); ...@@ -895,6 +905,7 @@ extern void ata_port_disable(struct ata_port *);
extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports); extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports);
extern struct ata_host *ata_host_alloc_pinfo(struct device *dev, extern struct ata_host *ata_host_alloc_pinfo(struct device *dev,
const struct ata_port_info * const * ppi, int n_ports); const struct ata_port_info * const * ppi, int n_ports);
extern int ata_slave_link_init(struct ata_port *ap);
extern int ata_host_start(struct ata_host *host); extern int ata_host_start(struct ata_host *host);
extern int ata_host_register(struct ata_host *host, extern int ata_host_register(struct ata_host *host,
struct scsi_host_template *sht); struct scsi_host_template *sht);
...@@ -920,8 +931,8 @@ extern int sata_scr_valid(struct ata_link *link); ...@@ -920,8 +931,8 @@ extern int sata_scr_valid(struct ata_link *link);
extern int sata_scr_read(struct ata_link *link, int reg, u32 *val); extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
extern int sata_scr_write(struct ata_link *link, int reg, u32 val); extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val); extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val);
extern int ata_link_online(struct ata_link *link); extern bool ata_link_online(struct ata_link *link);
extern int ata_link_offline(struct ata_link *link); extern bool ata_link_offline(struct ata_link *link);
#ifdef CONFIG_PM #ifdef CONFIG_PM
extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
extern void ata_host_resume(struct ata_host *host); extern void ata_host_resume(struct ata_host *host);
...@@ -1098,6 +1109,7 @@ extern void ata_std_error_handler(struct ata_port *ap); ...@@ -1098,6 +1109,7 @@ extern void ata_std_error_handler(struct ata_port *ap);
*/ */
extern const struct ata_port_operations ata_base_port_ops; extern const struct ata_port_operations ata_base_port_ops;
extern const struct ata_port_operations sata_port_ops; extern const struct ata_port_operations sata_port_ops;
extern struct device_attribute *ata_common_sdev_attrs[];
#define ATA_BASE_SHT(drv_name) \ #define ATA_BASE_SHT(drv_name) \
.module = THIS_MODULE, \ .module = THIS_MODULE, \
...@@ -1112,7 +1124,8 @@ extern const struct ata_port_operations sata_port_ops; ...@@ -1112,7 +1124,8 @@ extern const struct ata_port_operations sata_port_ops;
.proc_name = drv_name, \ .proc_name = drv_name, \
.slave_configure = ata_scsi_slave_config, \ .slave_configure = ata_scsi_slave_config, \
.slave_destroy = ata_scsi_slave_destroy, \ .slave_destroy = ata_scsi_slave_destroy, \
.bios_param = ata_std_bios_param .bios_param = ata_std_bios_param, \
.sdev_attrs = ata_common_sdev_attrs
#define ATA_NCQ_SHT(drv_name) \ #define ATA_NCQ_SHT(drv_name) \
ATA_BASE_SHT(drv_name), \ ATA_BASE_SHT(drv_name), \
...@@ -1134,7 +1147,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap) ...@@ -1134,7 +1147,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap)
static inline int ata_is_host_link(const struct ata_link *link) static inline int ata_is_host_link(const struct ata_link *link)
{ {
return link == &link->ap->link; return link == &link->ap->link || link == link->ap->slave_link;
} }
#else /* CONFIG_SATA_PMP */ #else /* CONFIG_SATA_PMP */
static inline bool sata_pmp_supported(struct ata_port *ap) static inline bool sata_pmp_supported(struct ata_port *ap)
...@@ -1167,7 +1180,7 @@ static inline int sata_srst_pmp(struct ata_link *link) ...@@ -1167,7 +1180,7 @@ static inline int sata_srst_pmp(struct ata_link *link)
printk("%sata%u: "fmt, lv, (ap)->print_id , ##args) printk("%sata%u: "fmt, lv, (ap)->print_id , ##args)
#define ata_link_printk(link, lv, fmt, args...) do { \ #define ata_link_printk(link, lv, fmt, args...) do { \
if (sata_pmp_attached((link)->ap)) \ if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \ printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \ (link)->pmp , ##args); \
else \ else \
...@@ -1265,34 +1278,17 @@ static inline int ata_link_active(struct ata_link *link) ...@@ -1265,34 +1278,17 @@ static inline int ata_link_active(struct ata_link *link)
return ata_tag_valid(link->active_tag) || link->sactive; return ata_tag_valid(link->active_tag) || link->sactive;
} }
static inline struct ata_link *ata_port_first_link(struct ata_port *ap) extern struct ata_link *__ata_port_next_link(struct ata_port *ap,
{ struct ata_link *link,
if (sata_pmp_attached(ap)) bool dev_only);
return ap->pmp_link;
return &ap->link;
}
static inline struct ata_link *ata_port_next_link(struct ata_link *link)
{
struct ata_port *ap = link->ap;
if (ata_is_host_link(link)) {
if (!sata_pmp_attached(ap))
return NULL;
return ap->pmp_link;
}
if (++link < ap->nr_pmp_links + ap->pmp_link)
return link;
return NULL;
}
#define __ata_port_for_each_link(lk, ap) \ #define __ata_port_for_each_link(link, ap) \
for ((lk) = &(ap)->link; (lk); (lk) = ata_port_next_link(lk)) for ((link) = __ata_port_next_link((ap), NULL, false); (link); \
(link) = __ata_port_next_link((ap), (link), false))
#define ata_port_for_each_link(link, ap) \ #define ata_port_for_each_link(link, ap) \
for ((link) = ata_port_first_link(ap); (link); \ for ((link) = __ata_port_next_link((ap), NULL, true); (link); \
(link) = ata_port_next_link(link)) (link) = __ata_port_next_link((ap), (link), true))
#define ata_link_for_each_dev(dev, link) \ #define ata_link_for_each_dev(dev, link) \
for ((dev) = (link)->device; \ for ((dev) = (link)->device; \
......
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