You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: sound/core/memalloc.c
This commit is contained in:
+1
-1
@@ -662,7 +662,7 @@ config HAVE_PATA_PLATFORM
|
||||
|
||||
config PATA_PLATFORM
|
||||
tristate "Generic platform device PATA support"
|
||||
depends on EMBEDDED || ARCH_RPC || PPC || HAVE_PATA_PLATFORM
|
||||
depends on EMBEDDED || PPC || HAVE_PATA_PLATFORM
|
||||
help
|
||||
This option enables support for generic directly connected ATA
|
||||
devices commonly found on embedded systems.
|
||||
|
||||
+13
-12
@@ -267,8 +267,8 @@ struct ahci_port_priv {
|
||||
* per PM slot */
|
||||
};
|
||||
|
||||
static int ahci_scr_read(struct ata_port *ap, 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_read(struct ata_link *link, 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 unsigned int ahci_qc_issue(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[] = {
|
||||
|
||||
static struct device_attribute *ahci_sdev_attrs[] = {
|
||||
&dev_attr_sw_activity,
|
||||
&dev_attr_unload_heads,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -820,10 +821,10 @@ static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)
|
||||
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);
|
||||
int offset = ahci_scr_offset(ap, sc_reg);
|
||||
void __iomem *port_mmio = ahci_port_base(link->ap);
|
||||
int offset = ahci_scr_offset(link->ap, sc_reg);
|
||||
|
||||
if (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)
|
||||
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);
|
||||
int offset = ahci_scr_offset(ap, sc_reg);
|
||||
void __iomem *port_mmio = ahci_port_base(link->ap);
|
||||
int offset = ahci_scr_offset(link->ap, sc_reg);
|
||||
|
||||
if (offset) {
|
||||
writel(val, port_mmio + offset);
|
||||
@@ -973,7 +974,7 @@ static void ahci_disable_alpm(struct ata_port *ap)
|
||||
writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT);
|
||||
|
||||
/* 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
|
||||
@@ -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);
|
||||
|
||||
/* AHCI needs SError cleared; otherwise, it might lock up */
|
||||
ahci_scr_read(ap, SCR_ERROR, &serror);
|
||||
ahci_scr_write(ap, SCR_ERROR, serror);
|
||||
ahci_scr_read(&ap->link, SCR_ERROR, &serror);
|
||||
ahci_scr_write(&ap->link, SCR_ERROR, serror);
|
||||
host_ehi->serror |= serror;
|
||||
|
||||
/* some controllers set IRQ_IF_ERR on device errors, ignore it */
|
||||
@@ -2027,7 +2028,7 @@ static void ahci_port_intr(struct ata_port *ap)
|
||||
if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) &&
|
||||
(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)) {
|
||||
|
||||
+54
-130
@@ -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 int ich_pata_cable_detect(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_write(struct ata_port *ap, unsigned int reg, u32 val);
|
||||
static int piix_sidpr_scr_read(struct ata_link *link,
|
||||
unsigned int reg, u32 *val);
|
||||
static int piix_sidpr_scr_write(struct ata_link *link,
|
||||
unsigned int reg, u32 val);
|
||||
#ifdef CONFIG_PM
|
||||
static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
|
||||
static int piix_pci_device_resume(struct pci_dev *pdev);
|
||||
@@ -278,12 +280,15 @@ static const struct pci_device_id piix_pci_tbl[] = {
|
||||
/* SATA Controller IDE (PCH) */
|
||||
{ 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
|
||||
/* 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 },
|
||||
/* 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 },
|
||||
/* SATA Controller IDE (PCH) */
|
||||
{ 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
|
||||
@@ -582,6 +587,7 @@ static const struct ich_laptop ich_laptop[] = {
|
||||
{ 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
|
||||
{ 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
|
||||
{ 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, 0x003d }, /* ICH4 on ACER TM290 */
|
||||
{ 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)
|
||||
* Serial ATA Index/Data Pair Superset Registers access
|
||||
*
|
||||
* Beginning from ICH8, there's a sane way to access SCRs using index
|
||||
* and data register pair located at BAR5. This creates an
|
||||
* interesting problem of mapping two SCRs to one port.
|
||||
*
|
||||
* 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.
|
||||
* and data register pair located at BAR5 which means that we have
|
||||
* separate SCRs for master and slave. This is handled using libata
|
||||
* slave_link facility.
|
||||
*/
|
||||
static const int piix_sidx_map[] = {
|
||||
[SCR_STATUS] = 0,
|
||||
@@ -909,120 +901,38 @@ static const int piix_sidx_map[] = {
|
||||
[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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
struct piix_host_priv *hpriv = link->ap->host->private_data;
|
||||
|
||||
if (reg >= ARRAY_SIZE(piix_sidx_map))
|
||||
return -EINVAL;
|
||||
|
||||
if (!(ap->flags & ATA_FLAG_SLAVE_POSS)) {
|
||||
*val = piix_sidpr_read(&ap->link.device[0], reg);
|
||||
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;
|
||||
}
|
||||
|
||||
piix_sidpr_sel(link, reg);
|
||||
*val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
|
||||
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))
|
||||
return -EINVAL;
|
||||
|
||||
piix_sidpr_write(&ap->link.device[0], reg, val);
|
||||
|
||||
if (ap->flags & ATA_FLAG_SLAVE_POSS)
|
||||
piix_sidpr_write(&ap->link.device[1], reg, val);
|
||||
|
||||
piix_sidpr_sel(link, reg);
|
||||
iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1363,28 +1273,28 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev,
|
||||
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 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;
|
||||
int i;
|
||||
int i, rc;
|
||||
|
||||
/* check for availability */
|
||||
for (i = 0; i < 4; i++)
|
||||
if (hpriv->map[i] == IDE)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 ||
|
||||
pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
|
||||
|
||||
@@ -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
|
||||
* 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
|
||||
* un-inhibit power save modes as BIOS might have inhibited
|
||||
@@ -1400,18 +1310,30 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
|
||||
*/
|
||||
if ((scontrol & 0xf00) != 0x300) {
|
||||
scontrol |= 0x300;
|
||||
piix_sidpr_write(dev0, SCR_CONTROL, scontrol);
|
||||
scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
|
||||
piix_sidpr_scr_write(link0, SCR_CONTROL, scontrol);
|
||||
piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
|
||||
|
||||
if ((scontrol & 0xf00) != 0x300) {
|
||||
dev_printk(KERN_INFO, host->dev, "SCR access via "
|
||||
"SIDPR is available but doesn't work\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
host->ports[0]->ops = &piix_sidpr_sata_ops;
|
||||
host->ports[1]->ops = &piix_sidpr_sata_ops;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
|
||||
@@ -1521,7 +1443,9 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
|
||||
/* initialize controller */
|
||||
if (port_flags & ATA_FLAG_SATA) {
|
||||
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 */
|
||||
|
||||
+217
-35
@@ -163,6 +163,67 @@ MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
|
||||
/*
|
||||
* Iterator helpers. Don't use directly.
|
||||
*
|
||||
* LOCKING:
|
||||
* Host lock or EH context.
|
||||
*/
|
||||
struct ata_link *__ata_port_next_link(struct ata_port *ap,
|
||||
struct ata_link *link, bool dev_only)
|
||||
{
|
||||
/* NULL link indicates start of iteration */
|
||||
if (!link) {
|
||||
if (dev_only && sata_pmp_attached(ap))
|
||||
return ap->pmp_link;
|
||||
return &ap->link;
|
||||
}
|
||||
|
||||
/* we just iterated over the host master link, what's next? */
|
||||
if (link == &ap->link) {
|
||||
if (!sata_pmp_attached(ap)) {
|
||||
if (unlikely(ap->slave_link) && !dev_only)
|
||||
return ap->slave_link;
|
||||
return NULL;
|
||||
}
|
||||
return ap->pmp_link;
|
||||
}
|
||||
|
||||
/* slave_link excludes PMP */
|
||||
if (unlikely(link == ap->slave_link))
|
||||
return NULL;
|
||||
|
||||
/* iterate to the next PMP link */
|
||||
if (++link < ap->pmp_link + ap->nr_pmp_links)
|
||||
return link;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_dev_phys_link - find physical link for a device
|
||||
* @dev: ATA device to look up physical link for
|
||||
*
|
||||
* Look up physical link which @dev is attached to. Note that
|
||||
* this is different from @dev->link only when @dev is on slave
|
||||
* link. For all other cases, it's the same as @dev->link.
|
||||
*
|
||||
* LOCKING:
|
||||
* Don't care.
|
||||
*
|
||||
* RETURNS:
|
||||
* Pointer to the found physical link.
|
||||
*/
|
||||
struct ata_link *ata_dev_phys_link(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
|
||||
if (!ap->slave_link)
|
||||
return dev->link;
|
||||
if (!dev->devno)
|
||||
return &ap->link;
|
||||
return ap->slave_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_force_cbl - force cable type according to libata.force
|
||||
* @ap: ATA port of interest
|
||||
@@ -206,7 +267,8 @@ void ata_force_cbl(struct ata_port *ap)
|
||||
* the host link and all fan-out ports connected via PMP. If the
|
||||
* device part is specified as 0 (e.g. 1.00:), it specifies the
|
||||
* first fan-out link not the host link. Device number 15 always
|
||||
* points to the host link whether PMP is attached or not.
|
||||
* points to the host link whether PMP is attached or not. If the
|
||||
* controller has slave link, device number 16 points to it.
|
||||
*
|
||||
* LOCKING:
|
||||
* EH context.
|
||||
@@ -214,12 +276,11 @@ void ata_force_cbl(struct ata_port *ap)
|
||||
static void ata_force_link_limits(struct ata_link *link)
|
||||
{
|
||||
bool did_spd = false;
|
||||
int linkno, i;
|
||||
int linkno = link->pmp;
|
||||
int i;
|
||||
|
||||
if (ata_is_host_link(link))
|
||||
linkno = 15;
|
||||
else
|
||||
linkno = link->pmp;
|
||||
linkno += 15;
|
||||
|
||||
for (i = ata_force_tbl_size - 1; i >= 0; i--) {
|
||||
const struct ata_force_ent *fe = &ata_force_tbl[i];
|
||||
@@ -266,9 +327,9 @@ static void ata_force_xfermask(struct ata_device *dev)
|
||||
int alt_devno = devno;
|
||||
int i;
|
||||
|
||||
/* allow n.15 for the first device attached to host port */
|
||||
if (ata_is_host_link(dev->link) && devno == 0)
|
||||
alt_devno = 15;
|
||||
/* allow n.15/16 for devices attached to host port */
|
||||
if (ata_is_host_link(dev->link))
|
||||
alt_devno += 15;
|
||||
|
||||
for (i = ata_force_tbl_size - 1; i >= 0; i--) {
|
||||
const struct ata_force_ent *fe = &ata_force_tbl[i];
|
||||
@@ -320,9 +381,9 @@ static void ata_force_horkage(struct ata_device *dev)
|
||||
int alt_devno = devno;
|
||||
int i;
|
||||
|
||||
/* allow n.15 for the first device attached to host port */
|
||||
if (ata_is_host_link(dev->link) && devno == 0)
|
||||
alt_devno = 15;
|
||||
/* allow n.15/16 for devices attached to host port */
|
||||
if (ata_is_host_link(dev->link))
|
||||
alt_devno += 15;
|
||||
|
||||
for (i = 0; i < ata_force_tbl_size; i++) {
|
||||
const struct ata_force_ent *fe = &ata_force_tbl[i];
|
||||
@@ -2681,7 +2742,7 @@ static void sata_print_link_status(struct ata_link *link)
|
||||
return;
|
||||
sata_scr_read(link, SCR_CONTROL, &scontrol);
|
||||
|
||||
if (ata_link_online(link)) {
|
||||
if (ata_phys_link_online(link)) {
|
||||
tmp = (sstatus >> 4) & 0xf;
|
||||
ata_link_printk(link, KERN_INFO,
|
||||
"SATA link up %s (SStatus %X SControl %X)\n",
|
||||
@@ -3372,6 +3433,12 @@ int ata_wait_ready(struct ata_link *link, unsigned long deadline,
|
||||
unsigned long nodev_deadline = ata_deadline(start, ATA_TMOUT_FF_WAIT);
|
||||
int warned = 0;
|
||||
|
||||
/* Slave readiness can't be tested separately from master. On
|
||||
* M/S emulation configuration, this function should be called
|
||||
* only on the master and it will handle both master and slave.
|
||||
*/
|
||||
WARN_ON(link == link->ap->slave_link);
|
||||
|
||||
if (time_after(nodev_deadline, deadline))
|
||||
nodev_deadline = deadline;
|
||||
|
||||
@@ -3593,7 +3660,7 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
|
||||
}
|
||||
|
||||
/* no point in trying softreset on offline link */
|
||||
if (ata_link_offline(link))
|
||||
if (ata_phys_link_offline(link))
|
||||
ehc->i.action &= ~ATA_EH_SOFTRESET;
|
||||
|
||||
return 0;
|
||||
@@ -3671,7 +3738,7 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
|
||||
if (rc)
|
||||
goto out;
|
||||
/* if link is offline nothing more to do */
|
||||
if (ata_link_offline(link))
|
||||
if (ata_phys_link_offline(link))
|
||||
goto out;
|
||||
|
||||
/* Link is online. From this point, -ENODEV too is an error. */
|
||||
@@ -4868,10 +4935,8 @@ int sata_scr_valid(struct ata_link *link)
|
||||
int sata_scr_read(struct ata_link *link, int reg, u32 *val)
|
||||
{
|
||||
if (ata_is_host_link(link)) {
|
||||
struct ata_port *ap = link->ap;
|
||||
|
||||
if (sata_scr_valid(link))
|
||||
return ap->ops->scr_read(ap, reg, val);
|
||||
return link->ap->ops->scr_read(link, reg, val);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -4897,10 +4962,8 @@ int sata_scr_read(struct ata_link *link, int reg, u32 *val)
|
||||
int sata_scr_write(struct ata_link *link, int reg, u32 val)
|
||||
{
|
||||
if (ata_is_host_link(link)) {
|
||||
struct ata_port *ap = link->ap;
|
||||
|
||||
if (sata_scr_valid(link))
|
||||
return ap->ops->scr_write(ap, reg, val);
|
||||
return link->ap->ops->scr_write(link, reg, val);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -4925,13 +4988,12 @@ int sata_scr_write(struct ata_link *link, int reg, u32 val)
|
||||
int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
|
||||
{
|
||||
if (ata_is_host_link(link)) {
|
||||
struct ata_port *ap = link->ap;
|
||||
int rc;
|
||||
|
||||
if (sata_scr_valid(link)) {
|
||||
rc = ap->ops->scr_write(ap, reg, val);
|
||||
rc = link->ap->ops->scr_write(link, reg, val);
|
||||
if (rc == 0)
|
||||
rc = ap->ops->scr_read(ap, reg, &val);
|
||||
rc = link->ap->ops->scr_read(link, reg, &val);
|
||||
return rc;
|
||||
}
|
||||
return -EOPNOTSUPP;
|
||||
@@ -4941,7 +5003,7 @@ int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_link_online - test whether the given link is online
|
||||
* ata_phys_link_online - test whether the given link is online
|
||||
* @link: ATA link to test
|
||||
*
|
||||
* Test whether @link is online. Note that this function returns
|
||||
@@ -4952,20 +5014,20 @@ int sata_scr_write_flush(struct ata_link *link, int reg, u32 val)
|
||||
* None.
|
||||
*
|
||||
* RETURNS:
|
||||
* 1 if the port online status is available and online.
|
||||
* True if the port online status is available and online.
|
||||
*/
|
||||
int ata_link_online(struct ata_link *link)
|
||||
bool ata_phys_link_online(struct ata_link *link)
|
||||
{
|
||||
u32 sstatus;
|
||||
|
||||
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
|
||||
(sstatus & 0xf) == 0x3)
|
||||
return 1;
|
||||
return 0;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_link_offline - test whether the given link is offline
|
||||
* ata_phys_link_offline - test whether the given link is offline
|
||||
* @link: ATA link to test
|
||||
*
|
||||
* Test whether @link is offline. Note that this function
|
||||
@@ -4976,16 +5038,68 @@ int ata_link_online(struct ata_link *link)
|
||||
* None.
|
||||
*
|
||||
* RETURNS:
|
||||
* 1 if the port offline status is available and offline.
|
||||
* True if the port offline status is available and offline.
|
||||
*/
|
||||
int ata_link_offline(struct ata_link *link)
|
||||
bool ata_phys_link_offline(struct ata_link *link)
|
||||
{
|
||||
u32 sstatus;
|
||||
|
||||
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
|
||||
(sstatus & 0xf) != 0x3)
|
||||
return 1;
|
||||
return 0;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_link_online - test whether the given link is online
|
||||
* @link: ATA link to test
|
||||
*
|
||||
* Test whether @link is online. This is identical to
|
||||
* ata_phys_link_online() when there's no slave link. When
|
||||
* there's a slave link, this function should only be called on
|
||||
* the master link and will return true if any of M/S links is
|
||||
* online.
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* RETURNS:
|
||||
* True if the port online status is available and online.
|
||||
*/
|
||||
bool ata_link_online(struct ata_link *link)
|
||||
{
|
||||
struct ata_link *slave = link->ap->slave_link;
|
||||
|
||||
WARN_ON(link == slave); /* shouldn't be called on slave link */
|
||||
|
||||
return ata_phys_link_online(link) ||
|
||||
(slave && ata_phys_link_online(slave));
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_link_offline - test whether the given link is offline
|
||||
* @link: ATA link to test
|
||||
*
|
||||
* Test whether @link is offline. This is identical to
|
||||
* ata_phys_link_offline() when there's no slave link. When
|
||||
* there's a slave link, this function should only be called on
|
||||
* the master link and will return true if both M/S links are
|
||||
* offline.
|
||||
*
|
||||
* LOCKING:
|
||||
* None.
|
||||
*
|
||||
* RETURNS:
|
||||
* True if the port offline status is available and offline.
|
||||
*/
|
||||
bool ata_link_offline(struct ata_link *link)
|
||||
{
|
||||
struct ata_link *slave = link->ap->slave_link;
|
||||
|
||||
WARN_ON(link == slave); /* shouldn't be called on slave link */
|
||||
|
||||
return ata_phys_link_offline(link) &&
|
||||
(!slave || ata_phys_link_offline(slave));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
@@ -5127,11 +5241,11 @@ int ata_port_start(struct ata_port *ap)
|
||||
*/
|
||||
void ata_dev_init(struct ata_device *dev)
|
||||
{
|
||||
struct ata_link *link = dev->link;
|
||||
struct ata_link *link = ata_dev_phys_link(dev);
|
||||
struct ata_port *ap = link->ap;
|
||||
unsigned long flags;
|
||||
|
||||
/* SATA spd limit is bound to the first device */
|
||||
/* SATA spd limit is bound to the attached device, reset together */
|
||||
link->sata_spd_limit = link->hw_sata_spd_limit;
|
||||
link->sata_spd = 0;
|
||||
|
||||
@@ -5264,6 +5378,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
|
||||
INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
|
||||
INIT_LIST_HEAD(&ap->eh_done_q);
|
||||
init_waitqueue_head(&ap->eh_wait_q);
|
||||
init_completion(&ap->park_req_pending);
|
||||
init_timer_deferrable(&ap->fastdrain_timer);
|
||||
ap->fastdrain_timer.function = ata_eh_fastdrain_timerfn;
|
||||
ap->fastdrain_timer.data = (unsigned long)ap;
|
||||
@@ -5294,6 +5409,7 @@ static void ata_host_release(struct device *gendev, void *res)
|
||||
scsi_host_put(ap->scsi_host);
|
||||
|
||||
kfree(ap->pmp_link);
|
||||
kfree(ap->slave_link);
|
||||
kfree(ap);
|
||||
host->ports[i] = NULL;
|
||||
}
|
||||
@@ -5414,6 +5530,68 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_slave_link_init - initialize slave link
|
||||
* @ap: port to initialize slave link for
|
||||
*
|
||||
* Create and initialize slave link for @ap. This enables slave
|
||||
* link handling on the port.
|
||||
*
|
||||
* In libata, a port contains links and a link contains devices.
|
||||
* There is single host link but if a PMP is attached to it,
|
||||
* there can be multiple fan-out links. On SATA, there's usually
|
||||
* a single device connected to a link but PATA and SATA
|
||||
* controllers emulating TF based interface can have two - master
|
||||
* and slave.
|
||||
*
|
||||
* However, there are a few controllers which don't fit into this
|
||||
* abstraction too well - SATA controllers which emulate TF
|
||||
* interface with both master and slave devices but also have
|
||||
* separate SCR register sets for each device. These controllers
|
||||
* need separate links for physical link handling
|
||||
* (e.g. onlineness, link speed) but should be treated like a
|
||||
* traditional M/S controller for everything else (e.g. command
|
||||
* issue, softreset).
|
||||
*
|
||||
* slave_link is libata's way of handling this class of
|
||||
* controllers without impacting core layer too much. For
|
||||
* anything other than physical link handling, the default host
|
||||
* link is used for both master and slave. For physical link
|
||||
* handling, separate @ap->slave_link is used. All dirty details
|
||||
* are implemented inside libata core layer. From LLD's POV, the
|
||||
* only difference is that prereset, hardreset and postreset are
|
||||
* called once more for the slave link, so the reset sequence
|
||||
* looks like the following.
|
||||
*
|
||||
* prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) ->
|
||||
* softreset(M) -> postreset(M) -> postreset(S)
|
||||
*
|
||||
* Note that softreset is called only for the master. Softreset
|
||||
* resets both M/S by definition, so SRST on master should handle
|
||||
* both (the standard method will work just fine).
|
||||
*
|
||||
* LOCKING:
|
||||
* Should be called before host is registered.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, -errno on failure.
|
||||
*/
|
||||
int ata_slave_link_init(struct ata_port *ap)
|
||||
{
|
||||
struct ata_link *link;
|
||||
|
||||
WARN_ON(ap->slave_link);
|
||||
WARN_ON(ap->flags & ATA_FLAG_PMP);
|
||||
|
||||
link = kzalloc(sizeof(*link), GFP_KERNEL);
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
||||
ata_link_init(ap, link, 1);
|
||||
ap->slave_link = link;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ata_host_stop(struct device *gendev, void *res)
|
||||
{
|
||||
struct ata_host *host = dev_get_drvdata(gendev);
|
||||
@@ -5640,6 +5818,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
|
||||
|
||||
/* init sata_spd_limit to the current value */
|
||||
sata_link_init_spd(&ap->link);
|
||||
if (ap->slave_link)
|
||||
sata_link_init_spd(ap->slave_link);
|
||||
|
||||
/* print per-port info to dmesg */
|
||||
xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
|
||||
@@ -6260,10 +6440,12 @@ EXPORT_SYMBOL_GPL(ata_base_port_ops);
|
||||
EXPORT_SYMBOL_GPL(sata_port_ops);
|
||||
EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
|
||||
EXPORT_SYMBOL_GPL(ata_dummy_port_info);
|
||||
EXPORT_SYMBOL_GPL(__ata_port_next_link);
|
||||
EXPORT_SYMBOL_GPL(ata_std_bios_param);
|
||||
EXPORT_SYMBOL_GPL(ata_host_init);
|
||||
EXPORT_SYMBOL_GPL(ata_host_alloc);
|
||||
EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
|
||||
EXPORT_SYMBOL_GPL(ata_slave_link_init);
|
||||
EXPORT_SYMBOL_GPL(ata_host_start);
|
||||
EXPORT_SYMBOL_GPL(ata_host_register);
|
||||
EXPORT_SYMBOL_GPL(ata_host_activate);
|
||||
|
||||
+342
-33
File diff suppressed because it is too large
Load Diff
@@ -183,6 +183,105 @@ DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
|
||||
ata_scsi_lpm_show, ata_scsi_lpm_put);
|
||||
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)
|
||||
{
|
||||
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,
|
||||
ata_scsi_activity_store);
|
||||
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,
|
||||
void (*done)(struct scsi_cmnd *))
|
||||
{
|
||||
@@ -954,6 +1059,9 @@ static int atapi_drain_needed(struct request *rq)
|
||||
static int ata_scsi_dev_config(struct scsi_device *sdev,
|
||||
struct ata_device *dev)
|
||||
{
|
||||
if (!ata_id_has_unload(dev->id))
|
||||
dev->flags |= ATA_DFLAG_NO_UNLOAD;
|
||||
|
||||
/* configure max sectors */
|
||||
blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
|
||||
|
||||
@@ -977,6 +1085,10 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
|
||||
|
||||
blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
|
||||
} else {
|
||||
if (ata_id_is_ssd(dev->id))
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_NONROT,
|
||||
sdev->request_queue);
|
||||
|
||||
/* ATA devices must be sector aligned */
|
||||
blk_queue_update_dma_alignment(sdev->request_queue,
|
||||
ATA_SECT_SIZE - 1);
|
||||
|
||||
@@ -70,6 +70,7 @@ extern int atapi_passthru16;
|
||||
extern int libata_fua;
|
||||
extern int libata_noacpi;
|
||||
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 u64 ata_tf_to_lba(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);
|
||||
extern void __ata_qc_complete(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 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_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
|
||||
extern int sata_link_init_spd(struct ata_link *link);
|
||||
@@ -152,7 +155,7 @@ extern int ata_bus_probe(struct ata_port *ap);
|
||||
/* libata-eh.c */
|
||||
extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
|
||||
extern void ata_internal_cmd_timed_out(struct ata_device *dev, u8 cmd);
|
||||
extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
|
||||
extern enum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
|
||||
extern void ata_scsi_error(struct Scsi_Host *host);
|
||||
extern void ata_port_wait_eh(struct ata_port *ap);
|
||||
extern void ata_eh_fastdrain_timerfn(unsigned long arg);
|
||||
|
||||
@@ -1632,6 +1632,8 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&pdev->dev, host);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1648,6 +1650,7 @@ static int __devexit bfin_atapi_remove(struct platform_device *pdev)
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
|
||||
ata_host_detach(host);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
|
||||
peripheral_free_list(atapi_io_port);
|
||||
|
||||
@@ -1655,27 +1658,44 @@ static int __devexit bfin_atapi_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
return 0;
|
||||
struct ata_host *host = dev_get_drvdata(&pdev->dev);
|
||||
if (host)
|
||||
return ata_host_suspend(host, state);
|
||||
else
|
||||
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;
|
||||
}
|
||||
#else
|
||||
#define bfin_atapi_suspend NULL
|
||||
#define bfin_atapi_resume NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver bfin_atapi_driver = {
|
||||
.probe = bfin_atapi_probe,
|
||||
.remove = __devexit_p(bfin_atapi_remove),
|
||||
.suspend = bfin_atapi_suspend,
|
||||
.resume = bfin_atapi_resume,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.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)
|
||||
tmpbyte & 1, tmpbyte & 0x30);
|
||||
|
||||
*try_mmio = 0;
|
||||
#ifdef CONFIG_PPC_MERGE
|
||||
#ifdef CONFIG_PPC
|
||||
if (machine_is(cell))
|
||||
*try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
|
||||
#endif
|
||||
|
||||
+13
-13
@@ -469,10 +469,10 @@ static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
|
||||
u32 val)
|
||||
static int sata_fsl_scr_write(struct ata_link *link,
|
||||
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;
|
||||
unsigned int sc_reg;
|
||||
|
||||
@@ -493,10 +493,10 @@ static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sata_fsl_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
|
||||
u32 *val)
|
||||
static int sata_fsl_scr_read(struct ata_link *link,
|
||||
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;
|
||||
unsigned int sc_reg;
|
||||
|
||||
@@ -645,12 +645,12 @@ static int sata_fsl_port_start(struct ata_port *ap)
|
||||
* Workaround for 8315DS board 3gbps link-up issue,
|
||||
* 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 |= (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",
|
||||
temp);
|
||||
#endif
|
||||
@@ -868,7 +868,7 @@ issue_srst:
|
||||
ioread32(CQ + 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("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
|
||||
@@ -972,9 +972,9 @@ static void sata_fsl_error_intr(struct ata_port *ap)
|
||||
* Handle & Clear SError
|
||||
*/
|
||||
|
||||
sata_fsl_scr_read(ap, SCR_ERROR, &SError);
|
||||
sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
|
||||
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",
|
||||
@@ -1091,7 +1091,7 @@ static void sata_fsl_host_intr(struct ata_port *ap)
|
||||
|
||||
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)) {
|
||||
DPRINTK("serror @host_intr : 0x%x\n", SError);
|
||||
|
||||
@@ -269,9 +269,9 @@ static void inic_reset_port(void __iomem *port_base)
|
||||
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;
|
||||
|
||||
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)
|
||||
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)))
|
||||
return -EINVAL;
|
||||
|
||||
+14
-14
@@ -493,10 +493,10 @@ struct mv_hw_ops {
|
||||
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_write(struct ata_port *ap, 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_write(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_link *link, 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_link *link, unsigned int sc_reg_in, u32 val);
|
||||
static int mv_port_start(struct ata_port *ap);
|
||||
static void mv_port_stop(struct ata_port *ap);
|
||||
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)
|
||||
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);
|
||||
|
||||
if (ofs != 0xffffffffU) {
|
||||
*val = readl(mv_ap_base(ap) + ofs);
|
||||
*val = readl(mv_ap_base(link->ap) + ofs);
|
||||
return 0;
|
||||
} else
|
||||
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);
|
||||
|
||||
if (ofs != 0xffffffffU) {
|
||||
writelfl(val, mv_ap_base(ap) + ofs);
|
||||
writelfl(val, mv_ap_base(link->ap) + ofs);
|
||||
return 0;
|
||||
} else
|
||||
return -EINVAL;
|
||||
@@ -2251,11 +2251,11 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
|
||||
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 *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);
|
||||
|
||||
if (ofs != 0xffffffffU) {
|
||||
@@ -2265,11 +2265,11 @@ static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val)
|
||||
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 *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);
|
||||
|
||||
if (ofs != 0xffffffffU) {
|
||||
|
||||
+48
-14
@@ -302,13 +302,15 @@ 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_nf2_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_write(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_link *link, unsigned int sc_reg, u32 val);
|
||||
|
||||
static void nv_nf2_freeze(struct ata_port *ap);
|
||||
static void nv_nf2_thaw(struct ata_port *ap);
|
||||
static void nv_ck804_freeze(struct ata_port *ap);
|
||||
static void nv_ck804_thaw(struct ata_port *ap);
|
||||
static int nv_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline);
|
||||
static int nv_adma_slave_config(struct scsi_device *sdev);
|
||||
static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
|
||||
static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
|
||||
@@ -403,28 +405,45 @@ static struct scsi_host_template nv_swncq_sht = {
|
||||
.slave_configure = nv_swncq_slave_config,
|
||||
};
|
||||
|
||||
static struct ata_port_operations nv_generic_ops = {
|
||||
/* OSDL bz3352 reports that some nv controllers can't determine device
|
||||
* signature reliably and nv_hardreset is implemented to work around
|
||||
* the problem. This was reported on nf3 and it's unclear whether any
|
||||
* other controllers are affected. However, the workaround has been
|
||||
* applied to all variants and there isn't much to gain by trying to
|
||||
* find out exactly which ones are affected at this point especially
|
||||
* because NV has moved over to ahci for newer controllers.
|
||||
*/
|
||||
static struct ata_port_operations nv_common_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.hardreset = ATA_OP_NULL,
|
||||
.hardreset = nv_hardreset,
|
||||
.scr_read = nv_scr_read,
|
||||
.scr_write = nv_scr_write,
|
||||
};
|
||||
|
||||
/* OSDL bz11195 reports that link doesn't come online after hardreset
|
||||
* on generic nv's and there have been several other similar reports
|
||||
* on linux-ide. Disable hardreset for generic nv's.
|
||||
*/
|
||||
static struct ata_port_operations nv_generic_ops = {
|
||||
.inherits = &nv_common_ops,
|
||||
.hardreset = ATA_OP_NULL,
|
||||
};
|
||||
|
||||
static struct ata_port_operations nv_nf2_ops = {
|
||||
.inherits = &nv_generic_ops,
|
||||
.inherits = &nv_common_ops,
|
||||
.freeze = nv_nf2_freeze,
|
||||
.thaw = nv_nf2_thaw,
|
||||
};
|
||||
|
||||
static struct ata_port_operations nv_ck804_ops = {
|
||||
.inherits = &nv_generic_ops,
|
||||
.inherits = &nv_common_ops,
|
||||
.freeze = nv_ck804_freeze,
|
||||
.thaw = nv_ck804_thaw,
|
||||
.host_stop = nv_ck804_host_stop,
|
||||
};
|
||||
|
||||
static struct ata_port_operations nv_adma_ops = {
|
||||
.inherits = &nv_generic_ops,
|
||||
.inherits = &nv_common_ops,
|
||||
|
||||
.check_atapi_dma = nv_adma_check_atapi_dma,
|
||||
.sff_tf_read = nv_adma_tf_read,
|
||||
@@ -448,7 +467,7 @@ static struct ata_port_operations nv_adma_ops = {
|
||||
};
|
||||
|
||||
static struct ata_port_operations nv_swncq_ops = {
|
||||
.inherits = &nv_generic_ops,
|
||||
.inherits = &nv_common_ops,
|
||||
|
||||
.qc_defer = ata_std_qc_defer,
|
||||
.qc_prep = nv_swncq_qc_prep,
|
||||
@@ -1492,21 +1511,21 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance)
|
||||
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)
|
||||
return -EINVAL;
|
||||
|
||||
*val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
*val = ioread32(link->ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
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)
|
||||
return -EINVAL;
|
||||
|
||||
iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
iowrite32(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1586,6 +1605,21 @@ static void nv_mcp55_thaw(struct ata_port *ap)
|
||||
ata_sff_thaw(ap);
|
||||
}
|
||||
|
||||
static int nv_hardreset(struct ata_link *link, unsigned int *class,
|
||||
unsigned long deadline)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* SATA hardreset fails to retrieve proper device signature on
|
||||
* some controllers. Request follow up SRST. For more info,
|
||||
* see http://bugzilla.kernel.org/show_bug.cgi?id=3352
|
||||
*/
|
||||
rc = sata_sff_hardreset(link, class, deadline);
|
||||
if (rc)
|
||||
return rc;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
static void nv_adma_error_handler(struct ata_port *ap)
|
||||
{
|
||||
struct nv_adma_port_priv *pp = ap->private_data;
|
||||
@@ -2184,9 +2218,9 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
|
||||
if (!pp->qc_active)
|
||||
return;
|
||||
|
||||
if (ap->ops->scr_read(ap, SCR_ERROR, &serror))
|
||||
if (ap->ops->scr_read(&ap->link, SCR_ERROR, &serror))
|
||||
return;
|
||||
ap->ops->scr_write(ap, SCR_ERROR, serror);
|
||||
ap->ops->scr_write(&ap->link, SCR_ERROR, serror);
|
||||
|
||||
if (ata_stat & ATA_ERR) {
|
||||
ata_ehi_clear_desc(ehi);
|
||||
|
||||
@@ -137,8 +137,8 @@ struct pdc_port_priv {
|
||||
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_write(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_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_common_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)
|
||||
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)
|
||||
return -EINVAL;
|
||||
*val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
*val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
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)
|
||||
return -EINVAL;
|
||||
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -731,7 +733,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
|
||||
if (sata_scr_valid(&ap->link)) {
|
||||
u32 serror;
|
||||
|
||||
pdc_sata_scr_read(ap, SCR_ERROR, &serror);
|
||||
pdc_sata_scr_read(&ap->link, SCR_ERROR, &serror);
|
||||
ehi->serror |= serror;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,8 +111,8 @@ struct qs_port_priv {
|
||||
qs_state_t state;
|
||||
};
|
||||
|
||||
static int qs_scr_read(struct ata_port *ap, 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_read(struct ata_link *link, 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_port_start(struct ata_port *ap);
|
||||
static void qs_host_stop(struct ata_host *host);
|
||||
@@ -242,11 +242,11 @@ static int qs_prereset(struct ata_link *link, unsigned long 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)
|
||||
return -EINVAL;
|
||||
*val = readl(ap->ioaddr.scr_addr + (sc_reg * 8));
|
||||
*val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 8));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -256,11 +256,11 @@ static void qs_error_handler(struct ata_port *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)
|
||||
return -EINVAL;
|
||||
writel(val, ap->ioaddr.scr_addr + (sc_reg * 8));
|
||||
writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 8));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
#endif
|
||||
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_write(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_link *link, unsigned int sc_reg, u32 val);
|
||||
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_thaw(struct ata_port *ap);
|
||||
@@ -317,9 +317,9 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap,
|
||||
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) {
|
||||
*val = readl(mmio);
|
||||
@@ -328,9 +328,9 @@ static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
|
||||
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) {
|
||||
writel(val, mmio);
|
||||
@@ -352,8 +352,8 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
|
||||
* controllers continue to assert IRQ as long as
|
||||
* SError bits are pending. Clear SError immediately.
|
||||
*/
|
||||
sil_scr_read(ap, SCR_ERROR, &serror);
|
||||
sil_scr_write(ap, SCR_ERROR, serror);
|
||||
sil_scr_read(&ap->link, SCR_ERROR, &serror);
|
||||
sil_scr_write(&ap->link, SCR_ERROR, serror);
|
||||
|
||||
/* Sometimes spurious interrupts occur, double check
|
||||
* it's PHYRDY CHG.
|
||||
|
||||
@@ -340,8 +340,8 @@ struct sil24_port_priv {
|
||||
};
|
||||
|
||||
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_write(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_link *link, unsigned sc_reg, u32 val);
|
||||
static int sil24_qc_defer(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);
|
||||
@@ -504,9 +504,9 @@ static int sil24_scr_map[] = {
|
||||
[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)) {
|
||||
void __iomem *addr;
|
||||
@@ -517,9 +517,9 @@ static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
|
||||
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)) {
|
||||
void __iomem *addr;
|
||||
|
||||
+16
-12
@@ -64,8 +64,8 @@ enum {
|
||||
};
|
||||
|
||||
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_write(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_link *link, unsigned int sc_reg, u32 val);
|
||||
|
||||
static const struct pci_device_id sis_pci_tbl[] = {
|
||||
{ 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)
|
||||
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);
|
||||
unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
|
||||
struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
|
||||
unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
|
||||
u32 val2 = 0;
|
||||
u8 pmr;
|
||||
|
||||
@@ -158,10 +159,11 @@ static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
|
||||
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);
|
||||
unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
|
||||
struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
|
||||
unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
|
||||
u8 pmr;
|
||||
|
||||
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)
|
||||
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);
|
||||
u8 pmr;
|
||||
|
||||
@@ -187,7 +190,7 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
|
||||
return -EINVAL;
|
||||
|
||||
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);
|
||||
|
||||
@@ -202,8 +205,9 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
|
||||
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);
|
||||
u8 pmr;
|
||||
|
||||
@@ -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);
|
||||
|
||||
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 {
|
||||
iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
|
||||
|
||||
@@ -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)
|
||||
return -EINVAL;
|
||||
*val = readl(ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
*val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
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)
|
||||
return -EINVAL;
|
||||
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 4));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -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_scr_read(struct ata_port *ap, 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_read(struct ata_link *link, 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[] = {
|
||||
{ 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)
|
||||
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);
|
||||
unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
|
||||
struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
|
||||
unsigned int cfg_addr = get_scr_cfg_addr(link->ap, sc_reg);
|
||||
u32 val;
|
||||
|
||||
pci_read_config_dword(pdev, cfg_addr, &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);
|
||||
unsigned int cfg_addr = get_scr_cfg_addr(ap, scr);
|
||||
struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
|
||||
unsigned int cfg_addr = get_scr_cfg_addr(link->ap, scr);
|
||||
|
||||
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)
|
||||
return -EINVAL;
|
||||
|
||||
*val = uli_scr_cfg_read(ap, sc_reg);
|
||||
*val = uli_scr_cfg_read(link, sc_reg);
|
||||
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
|
||||
return -EINVAL;
|
||||
|
||||
uli_scr_cfg_write(ap, sc_reg, val);
|
||||
uli_scr_cfg_write(link, sc_reg, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user