Commit e10117d3 authored by Linus Torvalds's avatar Linus Torvalds

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

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: (26 commits)
  include/linux/libata.h: fix typo
  pata_bf54x: fix return type of bfin_set_devctl
  Drivers: ata: Makefile: replace the use of <module>-objs with <module>-y
  libahci: fix result_tf handling after an ATA PIO data-in command
  pata_sl82c105: implement sff_irq_check() method
  pata_sil680: implement sff_irq_check() method
  pata_pdc202xx_old: implement sff_irq_check() method
  pata_cmd640: implement sff_irq_check() method
  ata_piix: Add device ID for ICH4-L
  pata_sil680: make sil680_sff_exec_command() 'static'
  ata: Intel IDE-R support
  libata: reorder ata_queued_cmd to remove alignment padding on 64 bit builds
  libata: Signal that our SATL supports WRITE SAME(16) with UNMAP
  ata_piix: remove SIDPR locking
  libata: implement cross-port EH exclusion
  libata: add @ap to ata_wait_register() and introduce ata_msleep()
  ata_piix: implement LPM support
  libata: implement LPM support for port multipliers
  libata: reimplement link power management
  libata: implement sata_link_scr_lpm() and make ata_dev_set_feature() global
  ...
parents f3270b16 89692c03
What: /sys/class/ata_...
Date: August 2008
Contact: Gwendal Grignou<gwendal@google.com>
Description:
Provide a place in sysfs for storing the ATA topology of the system. This allows
retrieving various information about ATA objects.
Files under /sys/class/ata_port
-------------------------------
For each port, a directory ataX is created where X is the ata_port_id of
the port. The device parent is the ata host device.
idle_irq (read)
Number of IRQ received by the port while idle [some ata HBA only].
nr_pmp_links (read)
If a SATA Port Multiplier (PM) is connected, number of link behind it.
Files under /sys/class/ata_link
-------------------------------
Behind each port, there is a ata_link. If there is a SATA PM in the
topology, 15 ata_link objects are created.
If a link is behind a port, the directory name is linkX, where X is
ata_port_id of the port.
If a link is behind a PM, its name is linkX.Y where X is ata_port_id
of the parent port and Y the PM port.
hw_sata_spd_limit
Maximum speed supported by the connected SATA device.
sata_spd_limit
Maximum speed imposed by libata.
sata_spd
Current speed of the link [1.5, 3Gps,...].
Files under /sys/class/ata_device
---------------------------------
Behind each link, up to two ata device are created.
The name of the directory is devX[.Y].Z where:
- X is ata_port_id of the port where the device is connected,
- Y the port of the PM if any, and
- Z the device id: for PATA, there is usually 2 devices [0,1],
only 1 for SATA.
class
Device class. Can be "ata" for disk, "atapi" for packet device,
"pmp" for PM, or "none" if no device was found behind the link.
dma_mode
Transfer modes supported by the device when in DMA mode.
Mostly used by PATA device.
pio_mode
Transfer modes supported by the device when in PIO mode.
Mostly used by PATA device.
xfer_mode
Current transfer mode.
id
Cached result of IDENTIFY command, as described in ATA8 7.16 and 7.17.
Only valid if the device is not a PM.
gscr
Cached result of the dump of PM GSCR register.
Valid registers are:
0: SATA_PMP_GSCR_PROD_ID,
1: SATA_PMP_GSCR_REV,
2: SATA_PMP_GSCR_PORT_INFO,
32: SATA_PMP_GSCR_ERROR,
33: SATA_PMP_GSCR_ERROR_EN,
64: SATA_PMP_GSCR_FEAT,
96: SATA_PMP_GSCR_FEAT_EN,
130: SATA_PMP_GSCR_SII_GPIO
Only valid if the device is a PM.
spdn_cnt
Number of time libata decided to lower the speed of link due to errors.
ering
Formatted output of the error ring of the device.
......@@ -99,7 +99,7 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
libata-objs := libata-core.o libata-scsi.o libata-eh.o
libata-y := libata-core.o libata-scsi.o libata-eh.o libata-transport.o
libata-$(CONFIG_ATA_SFF) += libata-sff.o
libata-$(CONFIG_SATA_PMP) += libata-pmp.o
libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
......@@ -1208,9 +1208,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
ata_port_pbar_desc(ap, AHCI_PCI_BAR,
0x100 + ap->port_no * 0x80, "port");
/* set initial link pm policy */
ap->pm_policy = NOT_AVAILABLE;
/* set enclosure management message type */
if (ap->flags & ATA_FLAG_EM)
ap->em_message_type = hpriv->em_msg_type;
......
......@@ -72,6 +72,7 @@ enum {
AHCI_CMD_RESET = (1 << 8),
AHCI_CMD_CLR_BUSY = (1 << 10),
RX_FIS_PIO_SETUP = 0x20, /* offset of PIO Setup FIS data */
RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */
RX_FIS_SDB = 0x58, /* offset of SDB FIS data */
RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
......@@ -201,7 +202,6 @@ enum {
AHCI_HFLAG_MV_PATA = (1 << 4), /* PATA port */
AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */
AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */
AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */
AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */
AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */
AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */
......@@ -216,7 +216,7 @@ enum {
AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
ATA_FLAG_ACPI_SATA | ATA_FLAG_AN |
ATA_FLAG_IPM,
ATA_FLAG_LPM,
ICH_MAP = 0x90, /* ICH MAP register */
......
......@@ -129,9 +129,6 @@ static int __init ahci_probe(struct platform_device *pdev)
ata_port_desc(ap, "mmio %pR", mem);
ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
/* set initial link pm policy */
ap->pm_policy = NOT_AVAILABLE;
/* set enclosure management message type */
if (ap->flags & ATA_FLAG_EM)
ap->em_message_type = hpriv->em_msg_type;
......
......@@ -35,6 +35,7 @@
enum {
ATA_GEN_CLASS_MATCH = (1 << 0),
ATA_GEN_FORCE_DMA = (1 << 1),
ATA_GEN_INTEL_IDER = (1 << 2),
};
/**
......@@ -108,6 +109,49 @@ static struct ata_port_operations generic_port_ops = {
static int all_generic_ide; /* Set to claim all devices */
/**
* is_intel_ider - identify intel IDE-R devices
* @dev: PCI device
*
* Distinguish Intel IDE-R controller devices from other Intel IDE
* devices. IDE-R devices have no timing registers and are in
* most respects virtual. They should be driven by the ata_generic
* driver.
*
* IDE-R devices have PCI offset 0xF8.L as zero, later Intel ATA has
* it non zero. All Intel ATA has 0x40 writable (timing), but it is
* not writable on IDE-R devices (this is guaranteed).
*/
static int is_intel_ider(struct pci_dev *dev)
{
/* For Intel IDE the value at 0xF8 is only zero on IDE-R
interfaces */
u32 r;
u16 t;
/* Check the manufacturing ID, it will be zero for IDE-R */
pci_read_config_dword(dev, 0xF8, &r);
/* Not IDE-R: punt so that ata_(old)piix gets it */
if (r != 0)
return 0;
/* 0xF8 will also be zero on some early Intel IDE devices
but they will have a sane timing register */
pci_read_config_word(dev, 0x40, &t);
if (t != 0)
return 0;
/* Finally check if the timing register is writable so that
we eliminate any early devices hot-docked in a docking
station */
pci_write_config_word(dev, 0x40, 1);
pci_read_config_word(dev, 0x40, &t);
if (t) {
pci_write_config_word(dev, 0x40, 0);
return 0;
}
return 1;
}
/**
* ata_generic_init - attach generic IDE
* @dev: PCI device found
......@@ -134,6 +178,10 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
if ((id->driver_data & ATA_GEN_CLASS_MATCH) && all_generic_ide == 0)
return -ENODEV;
if (id->driver_data & ATA_GEN_INTEL_IDER)
if (!is_intel_ider(dev))
return -ENODEV;
/* Devices that need care */
if (dev->vendor == PCI_VENDOR_ID_UMC &&
dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
......@@ -187,6 +235,10 @@ static struct pci_device_id ata_generic[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_3), },
{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_5), },
#endif
/* Intel, IDE class device */
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL,
.driver_data = ATA_GEN_INTEL_IDER },
/* Must come last. If you add entries adjust this table appropriately */
{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL),
.driver_data = ATA_GEN_CLASS_MATCH },
......
......@@ -158,7 +158,6 @@ struct piix_map_db {
struct piix_host_priv {
const int *map;
u32 saved_iocfg;
spinlock_t sidpr_lock; /* FIXME: remove once locking in EH is fixed */
void __iomem *sidpr;
};
......@@ -175,6 +174,8 @@ 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);
static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned hints);
static bool piix_irq_check(struct ata_port *ap);
#ifdef CONFIG_PM
static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
......@@ -209,6 +210,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
{ 0x8086, 0x248A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
/* Intel ICH3 (E7500/1) UDMA 100 */
{ 0x8086, 0x248B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
/* Intel ICH4-L */
{ 0x8086, 0x24C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
/* Intel ICH4 (i845GV, i845E, i852, i855) UDMA 100 */
{ 0x8086, 0x24CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
{ 0x8086, 0x24CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
......@@ -348,11 +351,22 @@ static struct ata_port_operations ich_pata_ops = {
.set_dmamode = ich_set_dmamode,
};
static struct device_attribute *piix_sidpr_shost_attrs[] = {
&dev_attr_link_power_management_policy,
NULL
};
static struct scsi_host_template piix_sidpr_sht = {
ATA_BMDMA_SHT(DRV_NAME),
.shost_attrs = piix_sidpr_shost_attrs,
};
static struct ata_port_operations piix_sidpr_sata_ops = {
.inherits = &piix_sata_ops,
.hardreset = sata_std_hardreset,
.scr_read = piix_sidpr_scr_read,
.scr_write = piix_sidpr_scr_write,
.set_lpm = piix_sidpr_set_lpm,
};
static const struct piix_map_db ich5_map_db = {
......@@ -956,15 +970,12 @@ static int piix_sidpr_scr_read(struct ata_link *link,
unsigned int reg, u32 *val)
{
struct piix_host_priv *hpriv = link->ap->host->private_data;
unsigned long flags;
if (reg >= ARRAY_SIZE(piix_sidx_map))
return -EINVAL;
spin_lock_irqsave(&hpriv->sidpr_lock, flags);
piix_sidpr_sel(link, reg);
*val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
spin_unlock_irqrestore(&hpriv->sidpr_lock, flags);
return 0;
}
......@@ -972,18 +983,21 @@ 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;
unsigned long flags;
if (reg >= ARRAY_SIZE(piix_sidx_map))
return -EINVAL;
spin_lock_irqsave(&hpriv->sidpr_lock, flags);
piix_sidpr_sel(link, reg);
iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
spin_unlock_irqrestore(&hpriv->sidpr_lock, flags);
return 0;
}
static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned hints)
{
return sata_link_scr_lpm(link, policy, false);
}
static bool piix_irq_check(struct ata_port *ap)
{
if (unlikely(!ap->ioaddr.bmdma_addr))
......@@ -1543,6 +1557,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
struct device *dev = &pdev->dev;
struct ata_port_info port_info[2];
const struct ata_port_info *ppi[] = { &port_info[0], &port_info[1] };
struct scsi_host_template *sht = &piix_sht;
unsigned long port_flags;
struct ata_host *host;
struct piix_host_priv *hpriv;
......@@ -1577,7 +1592,6 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
spin_lock_init(&hpriv->sidpr_lock);
/* Save IOCFG, this will be used for cable detection, quirk
* detection and restoration on detach. This is necessary
......@@ -1612,6 +1626,8 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
rc = piix_init_sidpr(host);
if (rc)
return rc;
if (host->ports[0]->ops == &piix_sidpr_sata_ops)
sht = &piix_sidpr_sht;
}
/* apply IOCFG bit18 quirk */
......@@ -1638,7 +1654,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
host->flags |= ATA_HOST_PARALLEL_SCAN;
pci_set_master(pdev);
return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, &piix_sht);
return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
}
static void piix_remove_one(struct pci_dev *pdev)
......
......@@ -56,9 +56,8 @@ MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)
module_param_named(ignore_sss, ahci_ignore_sss, int, 0444);
MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)");
static int ahci_enable_alpm(struct ata_port *ap,
enum link_pm policy);
static void ahci_disable_alpm(struct ata_port *ap);
static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned hints);
static ssize_t ahci_led_show(struct ata_port *ap, char *buf);
static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
size_t size);
......@@ -164,8 +163,7 @@ struct ata_port_operations ahci_ops = {
.pmp_attach = ahci_pmp_attach,
.pmp_detach = ahci_pmp_detach,
.enable_pm = ahci_enable_alpm,
.disable_pm = ahci_disable_alpm,
.set_lpm = ahci_set_lpm,
.em_show = ahci_led_show,
.em_store = ahci_led_store,
.sw_activity_show = ahci_activity_show,
......@@ -569,7 +567,7 @@ int ahci_stop_engine(struct ata_port *ap)
writel(tmp, port_mmio + PORT_CMD);
/* wait for engine to stop. This could be as long as 500 msec */
tmp = ata_wait_register(port_mmio + PORT_CMD,
tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
if (tmp & PORT_CMD_LIST_ON)
return -EIO;
......@@ -616,7 +614,7 @@ static int ahci_stop_fis_rx(struct ata_port *ap)
writel(tmp, port_mmio + PORT_CMD);
/* wait for completion, spec says 500ms, give it 1000 */
tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_FIS_ON,
tmp = ata_wait_register(ap, port_mmio + PORT_CMD, PORT_CMD_FIS_ON,
PORT_CMD_FIS_ON, 10, 1000);
if (tmp & PORT_CMD_FIS_ON)
return -EBUSY;
......@@ -642,127 +640,56 @@ static void ahci_power_up(struct ata_port *ap)
writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD);
}
static void ahci_disable_alpm(struct ata_port *ap)
static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned int hints)
{
struct ata_port *ap = link->ap;
struct ahci_host_priv *hpriv = ap->host->private_data;
void __iomem *port_mmio = ahci_port_base(ap);
u32 cmd;
struct ahci_port_priv *pp = ap->private_data;
/* IPM bits should be disabled by libata-core */
/* get the existing command bits */
cmd = readl(port_mmio + PORT_CMD);
/* disable ALPM and ASP */
cmd &= ~PORT_CMD_ASP;
cmd &= ~PORT_CMD_ALPE;
/* force the interface back to active */
cmd |= PORT_CMD_ICC_ACTIVE;
/* write out new cmd value */
writel(cmd, port_mmio + PORT_CMD);
cmd = readl(port_mmio + PORT_CMD);
/* wait 10ms to be sure we've come out of any low power state */
msleep(10);
/* clear out any PhyRdy stuff from interrupt status */
writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT);
/* go ahead and clean out PhyRdy Change from Serror too */
ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
/*
* Clear flag to indicate that we should ignore all PhyRdy
* state changes
*/
hpriv->flags &= ~AHCI_HFLAG_NO_HOTPLUG;
/*
* Enable interrupts on Phy Ready.
*/
pp->intr_mask |= PORT_IRQ_PHYRDY;
writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
/*
* don't change the link pm policy - we can be called
* just to turn of link pm temporarily
*/
}
static int ahci_enable_alpm(struct ata_port *ap,
enum link_pm policy)
{
struct ahci_host_priv *hpriv = ap->host->private_data;
void __iomem *port_mmio = ahci_port_base(ap);
u32 cmd;
struct ahci_port_priv *pp = ap->private_data;
u32 asp;
/* Make sure the host is capable of link power management */
if (!(hpriv->cap & HOST_CAP_ALPM))
return -EINVAL;
switch (policy) {
case MAX_PERFORMANCE:
case NOT_AVAILABLE:
/*
* if we came here with NOT_AVAILABLE,
* it just means this is the first time we
* have tried to enable - default to max performance,
* and let the user go to lower power modes on request.
*/
ahci_disable_alpm(ap);
return 0;
case MIN_POWER:
/* configure HBA to enter SLUMBER */
asp = PORT_CMD_ASP;
break;
case MEDIUM_POWER:
/* configure HBA to enter PARTIAL */
asp = 0;
break;
default:
return -EINVAL;
}
if (policy != ATA_LPM_MAX_POWER) {
/*
* Disable interrupts on Phy Ready. This keeps us from
* getting woken up due to spurious phy ready interrupts
* TBD - Hot plug should be done via polling now, is
* that even supported?
* getting woken up due to spurious phy ready
* interrupts.
*/
pp->intr_mask &= ~PORT_IRQ_PHYRDY;
writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
/*
* Set a flag to indicate that we should ignore all PhyRdy
* state changes since these can happen now whenever we
* change link state
*/
hpriv->flags |= AHCI_HFLAG_NO_HOTPLUG;
sata_link_scr_lpm(link, policy, false);
}
/* get the existing command bits */
cmd = readl(port_mmio + PORT_CMD);
if (hpriv->cap & HOST_CAP_ALPM) {
u32 cmd = readl(port_mmio + PORT_CMD);
/*
* Set ASP based on Policy
*/
cmd |= asp;
if (policy == ATA_LPM_MAX_POWER || !(hints & ATA_LPM_HIPM)) {
cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE);
cmd |= PORT_CMD_ICC_ACTIVE;
/*
* Setting this bit will instruct the HBA to aggressively
* enter a lower power link state when it's appropriate and
* based on the value set above for ASP
*/
writel(cmd, port_mmio + PORT_CMD);
readl(port_mmio + PORT_CMD);
/* wait 10ms to be sure we've come out of LPM state */
ata_msleep(ap, 10);
} else {
cmd |= PORT_CMD_ALPE;
if (policy == ATA_LPM_MIN_POWER)
cmd |= PORT_CMD_ASP;
/* write out new cmd value */
writel(cmd, port_mmio + PORT_CMD);
cmd = readl(port_mmio + PORT_CMD);
}
}
if (policy == ATA_LPM_MAX_POWER) {
sata_link_scr_lpm(link, policy, false);
/* turn PHYRDY IRQ back on */
pp->intr_mask |= PORT_IRQ_PHYRDY;
writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
}
/* IPM bits should be set by libata-core */
return 0;
}
......@@ -813,7 +740,7 @@ static void ahci_start_port(struct ata_port *ap)
emp->led_state,
4);
if (rc == -EBUSY)
msleep(1);
ata_msleep(ap, 1);
else
break;
}
......@@ -872,7 +799,7 @@ int ahci_reset_controller(struct ata_host *host)
* reset must complete within 1 second, or
* the hardware should be considered fried.
*/
tmp = ata_wait_register(mmio + HOST_CTL, HOST_RESET,
tmp = ata_wait_register(NULL, mmio + HOST_CTL, HOST_RESET,
HOST_RESET, 10, 1000);
if (tmp & HOST_RESET) {
......@@ -1252,7 +1179,7 @@ int ahci_kick_engine(struct ata_port *ap)
writel(tmp, port_mmio + PORT_CMD);
rc = 0;
tmp = ata_wait_register(port_mmio + PORT_CMD,
tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
PORT_CMD_CLO, PORT_CMD_CLO, 1, 500);
if (tmp & PORT_CMD_CLO)
rc = -EIO;
......@@ -1282,8 +1209,8 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
writel(1, port_mmio + PORT_CMD_ISSUE);
if (timeout_msec) {
tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1,
1, timeout_msec);
tmp = ata_wait_register(ap, port_mmio + PORT_CMD_ISSUE,
0x1, 0x1, 1, timeout_msec);
if (tmp & 0x1) {
ahci_kick_engine(ap);
return -EBUSY;
......@@ -1330,7 +1257,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
}
/* spec says at least 5us, but be generous and sleep for 1ms */
msleep(1);
ata_msleep(ap, 1);
/* issue the second D2H Register FIS */
tf.ctl &= ~ATA_SRST;
......@@ -1660,15 +1587,10 @@ static void ahci_port_intr(struct ata_port *ap)
if (unlikely(resetting))
status &= ~PORT_IRQ_BAD_PMP;
/* If we are getting PhyRdy, this is
* just a power state change, we should
* clear out this, plus the PhyRdy/Comm
* Wake bits from Serror
*/
if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) &&
(status & PORT_IRQ_PHYRDY)) {
/* if LPM is enabled, PHYRDY doesn't mean anything */
if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) {
status &= ~PORT_IRQ_PHYRDY;
ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG);
}
if (unlikely(status & PORT_IRQ_ERROR)) {
......@@ -1830,12 +1752,24 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
{
struct ahci_port_priv *pp = qc->ap->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
u8 *rx_fis = pp->rx_fis;
if (pp->fbs_enabled)
d2h_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ;
rx_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ;
/*
* After a successful execution of an ATA PIO data-in command,
* the device doesn't send D2H Reg FIS to update the TF and
* the host should take TF and E_Status from the preceding PIO
* Setup FIS.
*/
if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE &&
!(qc->flags & ATA_QCFLAG_FAILED)) {
ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15];
} else
ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
ata_tf_from_fis(d2h_fis, &qc->result_tf);
return true;
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -11,6 +11,7 @@
#include <linux/libata.h>
#include <linux/slab.h>
#include "libata.h"
#include "libata-transport.h"
const struct ata_port_operations sata_pmp_port_ops = {
.inherits = &sata_port_ops,
......@@ -184,6 +185,27 @@ int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val)
return 0;
}
/**
* sata_pmp_set_lpm - configure LPM for a PMP link
* @link: PMP link to configure LPM for
* @policy: target LPM policy
* @hints: LPM hints
*
* Configure LPM for @link. This function will contain any PMP
* specific workarounds if necessary.
*
* LOCKING:
* EH context.
*
* RETURNS:
* 0 on success, -errno on failure.
*/
int sata_pmp_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned hints)
{
return sata_link_scr_lpm(link, policy, true);
}
/**
* sata_pmp_read_gscr - read GSCR block of SATA PMP
* @dev: PMP device
......@@ -312,10 +334,10 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info)
return rc;
}
static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
static int sata_pmp_init_links (struct ata_port *ap, int nr_ports)
{
struct ata_link *pmp_link = ap->pmp_link;
int i;
int i, err;
if (!pmp_link) {
pmp_link = kzalloc(sizeof(pmp_link[0]) * SATA_PMP_MAX_PORTS,
......@@ -327,6 +349,13 @@ static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
ata_link_init(ap, &pmp_link[i], i);
ap->pmp_link = pmp_link;
for (i = 0; i < SATA_PMP_MAX_PORTS; i++) {
err = ata_tlink_add(&pmp_link[i]);
if (err) {
goto err_tlink;
}
}
}
for (i = 0; i < nr_ports; i++) {
......@@ -339,6 +368,12 @@ static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
}
return 0;
err_tlink:
while (--i >= 0)
ata_tlink_delete(&pmp_link[i]);
kfree(pmp_link);
ap->pmp_link = NULL;
return err;
}
static void sata_pmp_quirks(struct ata_port *ap)
......@@ -351,6 +386,9 @@ static void sata_pmp_quirks(struct ata_port *ap)
if (vendor == 0x1095 && devid == 0x3726) {
/* sil3726 quirks */
ata_for_each_link(link, ap, EDGE) {
/* link reports offline after LPM */
link->flags |= ATA_LFLAG_NO_LPM;
/* Class code report is unreliable and SRST
* times out under certain configurations.
*/
......@@ -366,6 +404,9 @@ static void sata_pmp_quirks(struct ata_port *ap)
} else if (vendor == 0x1095 && devid == 0x4723) {
/* sil4723 quirks */
ata_for_each_link(link, ap, EDGE) {
/* link reports offline after LPM */
link->flags |= ATA_LFLAG_NO_LPM;
/* class code report is unreliable */
if (link->pmp < 2)
link->flags |= ATA_LFLAG_ASSUME_ATA;
......@@ -378,6 +419,9 @@ static void sata_pmp_quirks(struct ata_port *ap)
} else if (vendor == 0x1095 && devid == 0x4726) {
/* sil4726 quirks */
ata_for_each_link(link, ap, EDGE) {
/* link reports offline after LPM */
link->flags |= ATA_LFLAG_NO_LPM;
/* Class code report is unreliable and SRST
* times out under certain configurations.
* Config device can be at port 0 or 5 and
......@@ -938,15 +982,25 @@ static int sata_pmp_eh_recover(struct ata_port *ap)
if (rc)
goto link_fail;
/* Connection status might have changed while resetting other
* links, check SATA_PMP_GSCR_ERROR before returning.
*/
/* clear SNotification */
rc = sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf);
if (rc == 0)
sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf);
/*
* If LPM is active on any fan-out port, hotplug wouldn't
* work. Return w/ PHY event notification disabled.
*/
ata_for_each_link(link, ap, EDGE)
if (link->lpm_policy > ATA_LPM_MAX_POWER)
return 0;
/*
* Connection status might have changed while resetting other
* links, enable notification and check SATA_PMP_GSCR_ERROR
* before returning.
*/
/* enable notification */
if (pmp_dev->flags & ATA_DFLAG_AN) {
gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY;
......
This diff is collapsed.
......@@ -222,7 +222,7 @@ int ata_sff_busy_sleep(struct ata_port *ap,
timeout = ata_deadline(timer_start, tmout_pat);
while (status != 0xff && (status & ATA_BUSY) &&
time_before(jiffies, timeout)) {
msleep(50);
ata_msleep(ap, 50);
status = ata_sff_busy_wait(ap, ATA_BUSY, 3);
}
......@@ -234,7 +234,7 @@ int ata_sff_busy_sleep(struct ata_port *ap,
timeout = ata_deadline(timer_start, tmout);
while (status != 0xff && (status & ATA_BUSY) &&
time_before(jiffies, timeout)) {
msleep(50);
ata_msleep(ap, 50);
status = ap->ops->sff_check_status(ap);
}
......@@ -360,7 +360,7 @@ static void ata_dev_select(struct ata_port *ap, unsigned int device,
if (wait) {
if (can_sleep && ap->link.device[device].class == ATA_DEV_ATAPI)
msleep(150);
ata_msleep(ap, 150);
ata_wait_idle(ap);
}
}
......@@ -1356,7 +1356,7 @@ static void ata_sff_pio_task(struct work_struct *work)
*/
status = ata_sff_busy_wait(ap, ATA_BUSY, 5);
if (status & ATA_BUSY) {
msleep(2);
ata_msleep(ap, 2);
status = ata_sff_busy_wait(ap, ATA_BUSY, 10);
if (status & ATA_BUSY) {
ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE);
......@@ -1937,7 +1937,7 @@ int ata_sff_wait_after_reset(struct ata_link *link, unsigned int devmask,
unsigned int dev1 = devmask & (1 << 1);
int rc, ret = 0;
msleep(ATA_WAIT_AFTER_RESET);
ata_msleep(ap, ATA_WAIT_AFTER_RESET);
/* always check readiness of the master device */
rc = ata_sff_wait_ready(link, deadline);
......@@ -1966,7 +1966,7 @@ int ata_sff_wait_after_reset(struct ata_link *link, unsigned int devmask,
lbal = ioread8(ioaddr->lbal_addr);
if ((nsect == 1) && (lbal == 1))
break;
msleep(50); /* give drive a breather */
ata_msleep(ap, 50); /* give drive a breather */
}
rc = ata_sff_wait_ready(link, deadline);
......@@ -3342,7 +3342,7 @@ int __init ata_sff_init(void)
return 0;
}
void __exit ata_sff_exit(void)
void ata_sff_exit(void)
{
destroy_workqueue(ata_sff_wq);
}
This diff is collapsed.
#ifndef _LIBATA_TRANSPORT_H
#define _LIBATA_TRANSPORT_H
extern struct scsi_transport_template *ata_scsi_transport_template;
int ata_tlink_add(struct ata_link *link);
void ata_tlink_delete(struct ata_link *link);
int ata_tport_add(struct device *parent, struct ata_port *ap);
void ata_tport_delete(struct ata_port *ap);
struct scsi_transport_template *ata_attach_transport(void);
void ata_release_transport(struct scsi_transport_template *t);
__init int libata_transport_init(void);
void __exit libata_transport_exit(void);
#endif
......@@ -86,6 +86,8 @@ extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
extern int ata_dev_configure(struct ata_device *dev);
extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
extern unsigned int ata_dev_set_feature(struct ata_device *dev,
u8 enable, u8 feature);
extern void ata_sg_clean(struct ata_queued_cmd *qc);
extern void ata_qc_free(struct ata_queued_cmd *qc);
extern void ata_qc_issue(struct ata_queued_cmd *qc);
......@@ -100,8 +102,7 @@ extern int sata_link_init_spd(struct ata_link *link);
extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
extern struct ata_port *ata_port_alloc(struct ata_host *host);
extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy);
extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm);
extern const char *sata_spd_string(unsigned int spd);
/* libata-acpi.c */
#ifdef CONFIG_ATA_ACPI
......@@ -137,10 +138,15 @@ extern void ata_scsi_hotplug(struct work_struct *work);
extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
extern void ata_scsi_dev_rescan(struct work_struct *work);
extern int ata_bus_probe(struct ata_port *ap);
extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
unsigned int id, unsigned int lun);
/* 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 void ata_eh_acquire(struct ata_port *ap);
extern void ata_eh_release(struct ata_port *ap);
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);
......@@ -164,11 +170,16 @@ extern int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_postreset_fn_t postreset,
struct ata_link **r_failed_disk);
extern void ata_eh_finish(struct ata_port *ap);
extern int ata_ering_map(struct ata_ering *ering,
int (*map_fn)(struct ata_ering_entry *, void *),
void *arg);
/* libata-pmp.c */
#ifdef CONFIG_SATA_PMP
extern int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *val);
extern int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val);
extern int sata_pmp_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned hints);
extern int sata_pmp_attach(struct ata_device *dev);
#else /* CONFIG_SATA_PMP */
static inline int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *val)
......@@ -181,6 +192,12 @@ static inline int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val)
return -EINVAL;
}
static inline int sata_pmp_set_lpm(struct ata_link *link,
enum ata_lpm_policy policy, unsigned hints)
{
return -EINVAL;
}
static inline int sata_pmp_attach(struct ata_device *dev)
{
return -EINVAL;
......
......@@ -826,7 +826,7 @@ static void bfin_dev_select(struct ata_port *ap, unsigned int device)
* @ctl: value to write
*/
static u8 bfin_set_devctl(struct ata_port *ap, u8 ctl)
static void bfin_set_devctl(struct ata_port *ap, u8 ctl)
{
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
write_atapi_register(base, ATA_REG_CTRL, ctl);
......@@ -1046,7 +1046,7 @@ static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask)
dev1 = 0;
break;
}
msleep(50); /* give drive a breather */
ata_msleep(ap, 50); /* give drive a breather */
}
if (dev1)
ata_sff_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
......@@ -1087,7 +1087,7 @@ static unsigned int bfin_bus_softreset(struct ata_port *ap,
*
* Old drivers/ide uses the 2mS rule and then waits for ready
*/
msleep(150);
ata_msleep(ap, 150);
/* Before we perform post reset processing we want to see if
* the bus shows 0xFF because the odd clown forgets the D7
......
......@@ -161,6 +161,17 @@ static int cmd640_port_start(struct ata_port *ap)
return 0;
}
static bool cmd640_sff_irq_check(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int irq_reg = ap->port_no ? ARTIM23 : CFR;
u8 irq_stat, irq_mask = ap->port_no ? 0x10 : 0x04;
pci_read_config_byte(pdev, irq_reg, &irq_stat);
return irq_stat & irq_mask;
}
static struct scsi_host_template cmd640_sht = {
ATA_PIO_SHT(DRV_NAME),
};
......@@ -169,6 +180,7 @@ static struct ata_port_operations cmd640_port_ops = {
.inherits = &ata_sff_port_ops,
/* In theory xfer_noirq is not needed once we kill the prefetcher */
.sff_data_xfer = ata_sff_data_xfer_noirq,
.sff_irq_check = cmd640_sff_irq_check,
.qc_issue = cmd640_qc_issue,
.cable_detect = ata_cable_40wire,
.set_piomode = cmd640_set_piomode,
......
......@@ -44,6 +44,27 @@ static void pdc202xx_exec_command(struct ata_port *ap,
ndelay(400);
}
static bool pdc202xx_irq_check(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned long master = pci_resource_start(pdev, 4);
u8 sc1d = inb(master + 0x1d);
if (ap->port_no) {
/*
* bit 7: error, bit 6: interrupting,
* bit 5: FIFO full, bit 4: FIFO empty
*/
return sc1d & 0x40;
} else {
/*
* bit 3: error, bit 2: interrupting,
* bit 1: FIFO full, bit 0: FIFO empty
*/
return sc1d & 0x04;
}
}
/**
* pdc202xx_configure_piomode - set chip PIO timing
* @ap: ATA interface
......@@ -282,6 +303,7 @@ static struct ata_port_operations pdc2024x_port_ops = {
.set_dmamode = pdc202xx_set_dmamode,
.sff_exec_command = pdc202xx_exec_command,
.sff_irq_check = pdc202xx_irq_check,
};
static struct ata_port_operations pdc2026x_port_ops = {
......@@ -297,6 +319,7 @@ static struct ata_port_operations pdc2026x_port_ops = {
.port_start = pdc2026x_port_start,
.sff_exec_command = pdc202xx_exec_command,
.sff_irq_check = pdc202xx_irq_check,
};
static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
......
......@@ -322,7 +322,7 @@ static int pata_s3c_wait_after_reset(struct ata_link *link,
{
int rc;
msleep(ATA_WAIT_AFTER_RESET);
ata_msleep(link->ap, ATA_WAIT_AFTER_RESET);
/* always check readiness of the master device */
rc = ata_sff_wait_ready(link, deadline);
......
......@@ -530,7 +530,7 @@ static int scc_wait_after_reset(struct ata_link *link, unsigned int devmask,
*
* Old drivers/ide uses the 2mS rule and then waits for ready.
*/
msleep(150);
ata_msleep(ap, 150);
/* always check readiness of the master device */
rc = ata_sff_wait_ready(link, deadline);
......@@ -559,7 +559,7 @@ static int scc_wait_after_reset(struct ata_link *link, unsigned int devmask,
lbal = in_be32(ioaddr->lbal_addr);
if ((nsect == 1) && (lbal == 1))
break;
msleep(50); /* give drive a breather */
ata_msleep(ap, 50); /* give drive a breather */
}
rc = ata_sff_wait_ready(link, deadline);
......
......@@ -202,7 +202,7 @@ static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev)
* LOCKING:
* spin_lock_irqsave(host lock)
*/
void sil680_sff_exec_command(struct ata_port *ap,
static void sil680_sff_exec_command(struct ata_port *ap,
const struct ata_taskfile *tf)
{
DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
......@@ -210,6 +210,17 @@ void sil680_sff_exec_command(struct ata_port *ap,
ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
}
static bool sil680_sff_irq_check(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned long addr = sil680_selreg(ap, 1);
u8 val;
pci_read_config_byte(pdev, addr, &val);
return val & 0x08;
}
static struct scsi_host_template sil680_sht = {
ATA_BMDMA_SHT(DRV_NAME),
};
......@@ -218,6 +229,7 @@ static struct scsi_host_template sil680_sht = {
static struct ata_port_operations sil680_port_ops = {
.inherits = &ata_bmdma32_port_ops,
.sff_exec_command = sil680_sff_exec_command,
.sff_irq_check = sil680_sff_irq_check,
.cable_detect = sil680_cable_detect,
.set_piomode = sil680_set_piomode,
.set_dmamode = sil680_set_dmamode,
......
......@@ -227,6 +227,16 @@ static int sl82c105_qc_defer(struct ata_queued_cmd *qc)
return 0;
}
static bool sl82c105_sff_irq_check(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 val, mask = ap->port_no ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
pci_read_config_dword(pdev, 0x40, &val);
return val & mask;
}
static struct scsi_host_template sl82c105_sht = {
ATA_BMDMA_SHT(DRV_NAME),
};
......@@ -239,6 +249,7 @@ static struct ata_port_operations sl82c105_port_ops = {
.cable_detect = ata_cable_40wire,
.set_piomode = sl82c105_set_piomode,
.prereset = sl82c105_pre_reset,
.sff_irq_check = sl82c105_sff_irq_check,
};
/**
......
......@@ -678,7 +678,7 @@ static void sata_fsl_port_stop(struct ata_port *ap)
iowrite32(temp, hcr_base + HCONTROL);
/* Poll for controller to go offline - should happen immediately */
ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 1);
ata_wait_register(ap, hcr_base + HSTATUS, ONLINE, ONLINE, 1, 1);
ap->private_data = NULL;
dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ,
......@@ -729,7 +729,8 @@ static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class,
iowrite32(temp, hcr_base + HCONTROL);
/* Poll for controller to go offline */
temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 500);
temp = ata_wait_register(ap, hcr_base + HSTATUS, ONLINE, ONLINE,
1, 500);
if (temp & ONLINE) {
ata_port_printk(ap, KERN_ERR,
......@@ -752,7 +753,7 @@ static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class,
/*
* PHY reset should remain asserted for atleast 1ms
*/
msleep(1);
ata_msleep(ap, 1);
/*
* Now, bring the host controller online again, this can take time
......@@ -766,7 +767,7 @@ static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class,
temp |= HCONTROL_PMP_ATTACHED;
iowrite32(temp, hcr_base + HCONTROL);
temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, 0, 1, 500);
temp = ata_wait_register(ap, hcr_base + HSTATUS, ONLINE, 0, 1, 500);
if (!(temp & ONLINE)) {
ata_port_printk(ap, KERN_ERR,
......@@ -784,7 +785,7 @@ static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class,
* presence
*/
temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0, 1, 500);
temp = ata_wait_register(ap, hcr_base + HSTATUS, 0xFF, 0, 1, 500);
if ((!(temp & 0x10)) || ata_link_offline(link)) {
ata_port_printk(ap, KERN_WARNING,
"No Device OR PHYRDY change,Hstatus = 0x%x\n",
......@@ -797,7 +798,7 @@ static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class,
* Wait for the first D2H from device,i.e,signature update notification
*/
start_jiffies = jiffies;
temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0x10,
temp = ata_wait_register(ap, hcr_base + HSTATUS, 0xFF, 0x10,
500, jiffies_to_msecs(deadline - start_jiffies));
if ((temp & 0xFF) != 0x18) {
......@@ -880,7 +881,7 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
iowrite32(pmp, CQPMP + hcr_base);
iowrite32(1, CQ + hcr_base);
temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
temp = ata_wait_register(ap, CQ + hcr_base, 0x1, 0x1, 1, 5000);
if (temp & 0x1) {
ata_port_printk(ap, KERN_WARNING, "ATA_SRST issue failed\n");
......@@ -896,7 +897,7 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
goto err;
}
msleep(1);
ata_msleep(ap, 1);
/*
* SATA device enters reset state after receving a Control register
......@@ -915,7 +916,7 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
if (pmp != SATA_PMP_CTRL_PORT)
iowrite32(pmp, CQPMP + hcr_base);
iowrite32(1, CQ + hcr_base);
msleep(150); /* ?? */
ata_msleep(ap, 150); /* ?? */
/*
* The above command would have signalled an interrupt on command
......@@ -1137,17 +1138,13 @@ static void sata_fsl_host_intr(struct ata_port *ap)
ioread32(hcr_base + CE));
for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
if (done_mask & (1 << i)) {
qc = ata_qc_from_tag(ap, i);
if (qc) {
ata_qc_complete(qc);
}
if (done_mask & (1 << i))
DPRINTK
("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n",
i, ioread32(hcr_base + CC),
ioread32(hcr_base + CA));
}
}
ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
return;
} else if ((ap->qc_active & (1 << ATA_TAG_INTERNAL))) {
......
......@@ -614,7 +614,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
writew(IDMA_CTL_RST_ATA, idma_ctl);
readw(idma_ctl); /* flush */
msleep(1);
ata_msleep(ap, 1);
writew(0, idma_ctl);
rc = sata_link_resume(link, timing, deadline);
......
......@@ -2743,18 +2743,11 @@ static void mv_err_intr(struct ata_port *ap)
}
}
static void mv_process_crpb_response(struct ata_port *ap,
static bool mv_process_crpb_response(struct ata_port *ap,
struct mv_crpb *response, unsigned int tag, int ncq_enabled)
{
u8 ata_status;
u16 edma_status = le16_to_cpu(response->flags);
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
if (unlikely(!qc)) {
ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n",
__func__, tag);
return;
}
/*
* edma_status from a response queue entry:
......@@ -2768,13 +2761,14 @@ static void mv_process_crpb_response(struct ata_port *ap,
* Error will be seen/handled by
* mv_err_intr(). So do nothing at all here.
*/
return;
return false;
}
}
ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT;
if (!ac_err_mask(ata_status))
ata_qc_complete(qc);
return true;
/* else: leave it for mv_err_intr() */
return false;
}
static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp)
......@@ -2783,6 +2777,7 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
struct mv_host_priv *hpriv = ap->host->private_data;
u32 in_index;
bool work_done = false;
u32 done_mask = 0;
int ncq_enabled = (pp->pp_flags & MV_PP_FLAG_NCQ_EN);
/* Get the hardware queue position index */
......@@ -2803,15 +2798,19 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
/* Gen II/IIE: get command tag from CRPB entry */
tag = le16_to_cpu(response->id) & 0x1f;
}
mv_process_crpb_response(ap, response, tag, ncq_enabled);
if (mv_process_crpb_response(ap, response, tag, ncq_enabled))
done_mask |= 1 << tag;
work_done = true;
}
if (work_done) {
ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
/* Update the software queue position index in hardware */
if (work_done)
writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) |
(pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT),
port_mmio + EDMA_RSP_Q_OUT_PTR);
}
}
static void mv_port_intr(struct ata_port *ap, u32 port_cause)
......
......@@ -873,29 +873,11 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
ata_port_freeze(ap);
else
ata_port_abort(ap);
return 1;
return -1;
}
if (likely(flags & NV_CPB_RESP_DONE)) {
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
VPRINTK("CPB flags done, flags=0x%x\n", flags);
if (likely(qc)) {
DPRINTK("Completing qc from tag %d\n", cpb_num);
ata_qc_complete(qc);
} else {
struct ata_eh_info *ehi = &ap->link.eh_info;
/* Notifier bits set without a command may indicate the drive
is misbehaving. Raise host state machine violation on this
condition. */
ata_port_printk(ap, KERN_ERR,
"notifier for tag %d with no cmd?\n",
cpb_num);
ehi->err_mask |= AC_ERR_HSM;
ehi->action |= ATA_EH_RESET;
ata_port_freeze(ap);
if (likely(flags & NV_CPB_RESP_DONE))
return 1;
}
}
return 0;
}
......@@ -1018,6 +1000,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
NV_ADMA_STAT_CPBERR |
NV_ADMA_STAT_CMD_COMPLETE)) {
u32 check_commands = notifier_clears[i];
u32 done_mask = 0;
int pos, rc;
if (status & NV_ADMA_STAT_CPBERR) {
......@@ -1034,10 +1017,13 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
pos--;
rc = nv_adma_check_cpb(ap, pos,
notifier_error & (1 << pos));
if (unlikely(rc))
if (rc > 0)
done_mask |= 1 << pos;
else if (unlikely(rc < 0))
check_commands = 0;
check_commands &= ~(1 << pos);
}
ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
}
}
......@@ -2132,7 +2118,6 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
struct ata_eh_info *ehi = &ap->link.eh_info;
u32 sactive;
u32 done_mask;
int i;
u8 host_stat;
u8 lack_dhfis = 0;
......@@ -2152,27 +2137,11 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
sactive = readl(pp->sactive_block);
done_mask = pp->qc_active ^ sactive;
if (unlikely(done_mask & sactive)) {
ata_ehi_clear_desc(ehi);
ata_ehi_push_desc(ehi, "illegal SWNCQ:qc_active transition"
"(%08x->%08x)", pp->qc_active, sactive);
ehi->err_mask |= AC_ERR_HSM;
ehi->action |= ATA_EH_RESET;
return -EINVAL;
}
for (i = 0; i < ATA_MAX_QUEUE; i++) {
if (!(done_mask & (1 << i)))
continue;
qc = ata_qc_from_tag(ap, i);
if (qc) {
ata_qc_complete(qc);
pp->qc_active &= ~(1 << i);
pp->dhfis_bits &= ~(1 << i);
pp->dmafis_bits &= ~(1 << i);
pp->sdbfis_bits |= (1 << i);
}
}
pp->qc_active &= ~done_mask;
pp->dhfis_bits &= ~done_mask;
pp->dmafis_bits &= ~done_mask;
pp->sdbfis_bits |= done_mask;
ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
if (!ap->qc_active) {
DPRINTK("over\n");
......
......@@ -589,9 +589,9 @@ static int sil24_init_port(struct ata_port *ap)
sil24_clear_pmp(ap);
writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
ata_wait_register(port + PORT_CTRL_STAT,
ata_wait_register(ap, port + PORT_CTRL_STAT,
PORT_CS_INIT, PORT_CS_INIT, 10, 100);
tmp = ata_wait_register(port + PORT_CTRL_STAT,
tmp = ata_wait_register(ap, port + PORT_CTRL_STAT,
PORT_CS_RDY, 0, 10, 100);
if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY) {
......@@ -631,7 +631,7 @@ static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp,
writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
irq_stat = ata_wait_register(port + PORT_IRQ_STAT, irq_mask, 0x0,
irq_stat = ata_wait_register(ap, port + PORT_IRQ_STAT, irq_mask, 0x0,
10, timeout_msec);
writel(irq_mask, port + PORT_IRQ_STAT); /* clear IRQs */
......@@ -719,9 +719,9 @@ static int sil24_hardreset(struct ata_link *link, unsigned int *class,
"state, performing PORT_RST\n");
writel(PORT_CS_PORT_RST, port + PORT_CTRL_STAT);
msleep(10);
ata_msleep(ap, 10);
writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
ata_wait_register(port + PORT_CTRL_STAT, PORT_CS_RDY, 0,
ata_wait_register(ap, port + PORT_CTRL_STAT, PORT_CS_RDY, 0,
10, 5000);
/* restore port configuration */
......@@ -740,7 +740,7 @@ static int sil24_hardreset(struct ata_link *link, unsigned int *class,
tout_msec = 5000;
writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
tmp = ata_wait_register(port + PORT_CTRL_STAT,
tmp = ata_wait_register(ap, port + PORT_CTRL_STAT,
PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10,
tout_msec);
......@@ -1253,7 +1253,7 @@ static void sil24_init_controller(struct ata_host *host)
tmp = readl(port + PORT_CTRL_STAT);
if (tmp & PORT_CS_PORT_RST) {
writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
tmp = ata_wait_register(port + PORT_CTRL_STAT,
tmp = ata_wait_register(NULL, port + PORT_CTRL_STAT,
PORT_CS_PORT_RST,
PORT_CS_PORT_RST, 10, 100);
if (tmp & PORT_CS_PORT_RST)
......
......@@ -349,7 +349,7 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline)
/* wait for phy to become ready, if necessary */
do {
msleep(200);
ata_msleep(link->ap, 200);
svia_scr_read(link, SCR_STATUS, &sstatus);
if ((sstatus & 0xf) != 1)
break;
......
......@@ -89,6 +89,7 @@ enum {
ATA_ID_SPG = 98,
ATA_ID_LBA_CAPACITY_2 = 100,
ATA_ID_SECTOR_SIZE = 106,
ATA_ID_LOGICAL_SECTOR_SIZE = 117, /* and 118 */
ATA_ID_LAST_LUN = 126,
ATA_ID_DLF = 128,
ATA_ID_CSFO = 129,
......@@ -640,16 +641,49 @@ static inline int ata_id_flush_ext_enabled(const u16 *id)
return (id[ATA_ID_CFS_ENABLE_2] & 0x2400) == 0x2400;
}
static inline int ata_id_has_large_logical_sectors(const u16 *id)
static inline u32 ata_id_logical_sector_size(const u16 *id)
{
if ((id[ATA_ID_SECTOR_SIZE] & 0xc000) != 0x4000)
/* T13/1699-D Revision 6a, Sep 6, 2008. Page 128.
* IDENTIFY DEVICE data, word 117-118.
* 0xd000 ignores bit 13 (logical:physical > 1)
*/
if ((id[ATA_ID_SECTOR_SIZE] & 0xd000) == 0x5000)
return (((id[ATA_ID_LOGICAL_SECTOR_SIZE+1] << 16)
+ id[ATA_ID_LOGICAL_SECTOR_SIZE]) * sizeof(u16)) ;
return ATA_SECT_SIZE;
}
static inline u8 ata_id_log2_per_physical_sector(const u16 *id)
{
/* T13/1699-D Revision 6a, Sep 6, 2008. Page 128.
* IDENTIFY DEVICE data, word 106.
* 0xe000 ignores bit 12 (logical sector > 512 bytes)
*/
if ((id[ATA_ID_SECTOR_SIZE] & 0xe000) == 0x6000)
return (id[ATA_ID_SECTOR_SIZE] & 0xf);
return 0;
return id[ATA_ID_SECTOR_SIZE] & (1 << 13);
}
static inline u16 ata_id_logical_per_physical_sectors(const u16 *id)
/* Offset of logical sectors relative to physical sectors.
*
* If device has more than one logical sector per physical sector
* (aka 512 byte emulation), vendors might offset the "sector 0" address
* so sector 63 is "naturally aligned" - e.g. FAT partition table.
* This avoids Read/Mod/Write penalties when using FAT partition table
* and updating "well aligned" (FS perspective) physical sectors on every
* transaction.
*/
static inline u16 ata_id_logical_sector_offset(const u16 *id,
u8 log2_per_phys)
{
return 1 << (id[ATA_ID_SECTOR_SIZE] & 0xf);
u16 word_209 = id[209];
if ((log2_per_phys > 1) && (word_209 & 0xc000) == 0x4000) {
u16 first = word_209 & 0x3fff;
if (first > 0)
return (1 << log2_per_phys) - first;
}
return 0;
}
static inline int ata_id_has_lba48(const u16 *id)
......
......@@ -37,6 +37,7 @@
#include <scsi/scsi_host.h>
#include <linux/acpi.h>
#include <linux/cdrom.h>
#include <linux/sched.h>
/*
* Define if arch has non-standard setup. This is a _PCI_ standard
......@@ -172,6 +173,7 @@ enum {
ATA_LFLAG_NO_RETRY = (1 << 5), /* don't retry this link */
ATA_LFLAG_DISABLED = (1 << 6), /* link is disabled */
ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */
ATA_LFLAG_NO_LPM = (1 << 8), /* disable LPM on this link */
/* struct ata_port flags */
ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */
......@@ -196,7 +198,7 @@ enum {
ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
ATA_FLAG_AN = (1 << 18), /* controller supports AN */
ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */
ATA_FLAG_IPM = (1 << 20), /* driver can handle IPM */
ATA_FLAG_LPM = (1 << 20), /* driver can handle LPM */
ATA_FLAG_EM = (1 << 21), /* driver supports enclosure
* management */
ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity
......@@ -324,12 +326,11 @@ enum {
ATA_EH_HARDRESET = (1 << 2), /* meaningful only in ->prereset */
ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
ATA_EH_ENABLE_LINK = (1 << 3),
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_PARK,
ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET |
ATA_EH_ENABLE_LINK | ATA_EH_LPM,
ATA_EH_ENABLE_LINK,
/* ata_eh_info->flags */
ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */
......@@ -341,7 +342,7 @@ enum {
ATA_EHI_DID_HARDRESET = (1 << 17), /* already soft-reset this port */
ATA_EHI_PRINTINFO = (1 << 18), /* print configuration info */
ATA_EHI_SETMODE = (1 << 19), /* configure transfer mode */
ATA_EHI_POST_SETMODE = (1 << 20), /* revaildating after setmode */
ATA_EHI_POST_SETMODE = (1 << 20), /* revalidating after setmode */
ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
......@@ -377,7 +378,6 @@ enum {
ATA_HORKAGE_BROKEN_HPA = (1 << 4), /* Broken HPA */
ATA_HORKAGE_DISABLE = (1 << 5), /* Disable it */
ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */
ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */
ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */
ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */
ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */
......@@ -464,6 +464,22 @@ enum ata_completion_errors {
AC_ERR_NCQ = (1 << 10), /* marker for offending NCQ qc */
};
/*
* Link power management policy: If you alter this, you also need to
* alter libata-scsi.c (for the ascii descriptions)
*/
enum ata_lpm_policy {
ATA_LPM_UNKNOWN,
ATA_LPM_MAX_POWER,
ATA_LPM_MED_POWER,
ATA_LPM_MIN_POWER,
};
enum ata_lpm_hints {
ATA_LPM_EMPTY = (1 << 0), /* port empty/probing */
ATA_LPM_HIPM = (1 << 1), /* may use HIPM */
};
/* forward declarations */
struct scsi_device;
struct ata_port_operations;
......@@ -478,16 +494,6 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes,
unsigned long deadline);
typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes);
/*
* host pm policy: If you alter this, you also need to alter libata-scsi.c
* (for the ascii descriptions)
*/
enum link_pm {
NOT_AVAILABLE,
MIN_POWER,
MAX_PERFORMANCE,
MEDIUM_POWER,
};
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;
......@@ -530,6 +536,10 @@ struct ata_host {
void *private_data;
struct ata_port_operations *ops;
unsigned long flags;
struct mutex eh_mutex;
struct task_struct *eh_owner;
#ifdef CONFIG_ATA_ACPI
acpi_handle acpi_handle;
#endif
......@@ -560,13 +570,13 @@ struct ata_queued_cmd {
unsigned int extrabytes;
unsigned int curbytes;
struct scatterlist *cursg;
unsigned int cursg_ofs;
struct scatterlist sgent;
struct scatterlist *sg;
struct scatterlist *cursg;
unsigned int cursg_ofs;
unsigned int err_mask;
struct ata_taskfile result_tf;
ata_qc_cb_t complete_fn;
......@@ -604,6 +614,7 @@ struct ata_device {
union acpi_object *gtf_cache;
unsigned int gtf_filter;
#endif
struct device tdev;
/* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */
u64 n_sectors; /* size of device, if ATA */
u64 n_native_sectors; /* native size, if ATA */
......@@ -690,6 +701,7 @@ struct ata_link {
struct ata_port *ap;
int pmp; /* port multiplier port # */
struct device tdev;
unsigned int active_tag; /* active tag on this link */
u32 sactive; /* active NCQ commands */
......@@ -699,6 +711,7 @@ struct ata_link {
unsigned int hw_sata_spd_limit;
unsigned int sata_spd_limit;
unsigned int sata_spd; /* current SATA PHY speed */
enum ata_lpm_policy lpm_policy;
/* record runtime error info, protected by host_set lock */
struct ata_eh_info eh_info;
......@@ -707,6 +720,8 @@ struct ata_link {
struct ata_device device[ATA_MAX_DEVICES];
};
#define ATA_LINK_CLEAR_BEGIN offsetof(struct ata_link, active_tag)
#define ATA_LINK_CLEAR_END offsetof(struct ata_link, device[0])
struct ata_port {
struct Scsi_Host *scsi_host; /* our co-allocated scsi host */
......@@ -752,6 +767,7 @@ struct ata_port {
struct ata_port_stats stats;
struct ata_host *host;
struct device *dev;
struct device tdev;
struct mutex scsi_scan_mutex;
struct delayed_work hotplug_task;
......@@ -767,7 +783,7 @@ struct ata_port {
pm_message_t pm_mesg;
int *pm_result;
enum link_pm pm_policy;
enum ata_lpm_policy target_lpm_policy;
struct timer_list fastdrain_timer;
unsigned long fastdrain_cnt;
......@@ -833,8 +849,8 @@ struct ata_port_operations {
int (*scr_write)(struct ata_link *link, unsigned int sc_reg, u32 val);
void (*pmp_attach)(struct ata_port *ap);
void (*pmp_detach)(struct ata_port *ap);
int (*enable_pm)(struct ata_port *ap, enum link_pm policy);
void (*disable_pm)(struct ata_port *ap);
int (*set_lpm)(struct ata_link *link, enum ata_lpm_policy policy,
unsigned hints);
/*
* Start, stop, suspend and resume
......@@ -946,6 +962,8 @@ extern int sata_link_debounce(struct ata_link *link,
const unsigned long *params, unsigned long deadline);
extern int sata_link_resume(struct ata_link *link, const unsigned long *params,
unsigned long deadline);
extern int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
bool spm_wakeup);
extern int sata_link_hardreset(struct ata_link *link,
const unsigned long *timing, unsigned long deadline,
bool *online, int (*check_ready)(struct ata_link *));
......@@ -991,8 +1009,9 @@ extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
extern void ata_host_resume(struct ata_host *host);
#endif
extern int ata_ratelimit(void);
extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
unsigned long interval, unsigned long timeout);
extern void ata_msleep(struct ata_port *ap, unsigned int msecs);
extern u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask,
u32 val, unsigned long interval, unsigned long timeout);
extern int atapi_cmd_type(u8 opcode);
extern void ata_tf_to_fis(const struct ata_taskfile *tf,
u8 pmp, int is_cmd, u8 *fis);
......
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