aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r--drivers/scsi/ahci.c57
1 files changed, 22 insertions, 35 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index ffba65656a8..1b8429cb3c9 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -48,7 +48,7 @@
#include <asm/io.h>
#define DRV_NAME "ahci"
-#define DRV_VERSION "1.2"
+#define DRV_VERSION "1.3"
enum {
@@ -207,7 +207,6 @@ static struct scsi_host_template ahci_sht = {
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
- .eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = AHCI_MAX_SG,
@@ -293,6 +292,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
board_ahci }, /* JMicron JMB360 */
{ 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
board_ahci }, /* JMicron JMB363 */
+ { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_ahci }, /* ATI SB600 non-raid */
+ { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ board_ahci }, /* ATI SB600 raid */
{ } /* terminate list */
};
@@ -513,25 +516,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts)
pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
}
-static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val,
- unsigned long interval_msec,
- unsigned long timeout_msec)
-{
- unsigned long timeout;
- u32 tmp;
-
- timeout = jiffies + (timeout_msec * HZ) / 1000;
- do {
- tmp = readl(reg);
- if ((tmp & mask) == val)
- return 0;
- msleep(interval_msec);
- } while (time_before(jiffies, timeout));
-
- return -1;
-}
-
-static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
+static int ahci_softreset(struct ata_port *ap, unsigned int *class)
{
struct ahci_host_priv *hpriv = ap->host_set->private_data;
struct ahci_port_priv *pp = ap->private_data;
@@ -540,11 +525,18 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
const u32 cmd_fis_len = 5; /* five dwords */
const char *reason = NULL;
struct ata_taskfile tf;
+ u32 tmp;
u8 *fis;
int rc;
DPRINTK("ENTER\n");
+ if (!sata_dev_present(ap)) {
+ DPRINTK("PHY reports no device\n");
+ *class = ATA_DEV_NONE;
+ return 0;
+ }
+
/* prepare for SRST (AHCI-1.1 10.4.1) */
rc = ahci_stop_engine(ap);
if (rc) {
@@ -555,8 +547,6 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
/* check BUSY/DRQ, perform Command List Override if necessary */
ahci_tf_read(ap, &tf);
if (tf.command & (ATA_BUSY | ATA_DRQ)) {
- u32 tmp;
-
if (!(hpriv->cap & HOST_CAP_CLO)) {
rc = -EIO;
reason = "port busy but no CLO";
@@ -566,10 +556,10 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
tmp = readl(port_mmio + PORT_CMD);
tmp |= PORT_CMD_CLO;
writel(tmp, port_mmio + PORT_CMD);
- readl(port_mmio + PORT_CMD); /* flush */
- if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0,
- 1, 500)) {
+ tmp = ata_wait_register(port_mmio + PORT_CMD,
+ PORT_CMD_CLO, PORT_CMD_CLO, 1, 500);
+ if (tmp & PORT_CMD_CLO) {
rc = -EIO;
reason = "CLO failed";
goto fail_restart;
@@ -590,9 +580,9 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
fis[1] &= ~(1 << 7); /* turn off Command FIS bit */
writel(1, port_mmio + PORT_CMD_ISSUE);
- readl(port_mmio + PORT_CMD_ISSUE); /* flush */
- if (ahci_poll_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x0, 1, 500)) {
+ tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500);
+ if (tmp & 0x1) {
rc = -EIO;
reason = "1st FIS failed";
goto fail;
@@ -637,22 +627,19 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
fail_restart:
ahci_start_engine(ap);
fail:
- if (verbose)
- printk(KERN_ERR "ata%u: softreset failed (%s)\n",
- ap->id, reason);
- else
- DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason);
+ printk(KERN_ERR "ata%u: softreset failed (%s)\n",
+ ap->id, reason);
return rc;
}
-static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class)
+static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
{
int rc;
DPRINTK("ENTER\n");
ahci_stop_engine(ap);
- rc = sata_std_hardreset(ap, verbose, class);
+ rc = sata_std_hardreset(ap, class);
ahci_start_engine(ap);
if (rc == 0)