aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sata_sil24.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index cb91894471f..d8a2f5f04e8 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -41,7 +41,7 @@
#include <asm/io.h>
#define DRV_NAME "sata_sil24"
-#define DRV_VERSION "0.20" /* Silicon Image's preview driver was 0.10 */
+#define DRV_VERSION "0.21" /* Silicon Image's preview driver was 0.10 */
#define NR_PORTS 4
@@ -426,15 +426,11 @@ static void sil24_irq_clear(struct ata_port *ap)
/* unused */
}
-static void sil24_reset_controller(struct ata_port *ap)
+static int __sil24_reset_controller(void *port)
{
- void *port = (void *)ap->ioaddr.cmd_addr;
int cnt;
u32 tmp;
- printk(KERN_NOTICE DRV_NAME
- " ata%u: resetting controller...\n", ap->id);
-
/* Reset controller state. Is this correct? */
writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
readl(port + PORT_CTRL_STAT); /* sync */
@@ -446,9 +442,19 @@ static void sil24_reset_controller(struct ata_port *ap)
if (!(tmp & PORT_CS_DEV_RST))
break;
}
+
if (tmp & PORT_CS_DEV_RST)
- printk(KERN_ERR DRV_NAME
- " ata%u: failed to reset controller\n", ap->id);
+ return -1;
+ return 0;
+}
+
+static void sil24_reset_controller(struct ata_port *ap)
+{
+ printk(KERN_NOTICE DRV_NAME
+ " ata%u: resetting controller...\n", ap->id);
+ if (__sil24_reset_controller((void *)ap->ioaddr.cmd_addr))
+ printk(KERN_ERR DRV_NAME
+ " ata%u: failed to reset controller\n", ap->id);
}
static void sil24_eng_timeout(struct ata_port *ap)
@@ -740,6 +746,15 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Clear interrupts */
writel(0x0fff0fff, port + PORT_IRQ_STAT);
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
+
+ /* Clear port multiplier enable and resume bits */
+ writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
+
+ /* Reset itself */
+ if (__sil24_reset_controller(port))
+ printk(KERN_ERR DRV_NAME
+ "(%s): failed to reset controller\n",
+ pci_name(pdev));
}
/* Turn on interrupts */