#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
/* 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 */
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)
/* 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 */