diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/sata_sil24.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index cb91894471f2..d8a2f5f04e82 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
42 | 42 | ||
43 | #define DRV_NAME "sata_sil24" | 43 | #define DRV_NAME "sata_sil24" |
44 | #define DRV_VERSION "0.20" /* Silicon Image's preview driver was 0.10 */ | 44 | #define DRV_VERSION "0.21" /* Silicon Image's preview driver was 0.10 */ |
45 | 45 | ||
46 | #define NR_PORTS 4 | 46 | #define NR_PORTS 4 |
47 | 47 | ||
@@ -426,15 +426,11 @@ static void sil24_irq_clear(struct ata_port *ap) | |||
426 | /* unused */ | 426 | /* unused */ |
427 | } | 427 | } |
428 | 428 | ||
429 | static void sil24_reset_controller(struct ata_port *ap) | 429 | static int __sil24_reset_controller(void *port) |
430 | { | 430 | { |
431 | void *port = (void *)ap->ioaddr.cmd_addr; | ||
432 | int cnt; | 431 | int cnt; |
433 | u32 tmp; | 432 | u32 tmp; |
434 | 433 | ||
435 | printk(KERN_NOTICE DRV_NAME | ||
436 | " ata%u: resetting controller...\n", ap->id); | ||
437 | |||
438 | /* Reset controller state. Is this correct? */ | 434 | /* Reset controller state. Is this correct? */ |
439 | writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT); | 435 | writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT); |
440 | readl(port + PORT_CTRL_STAT); /* sync */ | 436 | readl(port + PORT_CTRL_STAT); /* sync */ |
@@ -446,9 +442,19 @@ static void sil24_reset_controller(struct ata_port *ap) | |||
446 | if (!(tmp & PORT_CS_DEV_RST)) | 442 | if (!(tmp & PORT_CS_DEV_RST)) |
447 | break; | 443 | break; |
448 | } | 444 | } |
445 | |||
449 | if (tmp & PORT_CS_DEV_RST) | 446 | if (tmp & PORT_CS_DEV_RST) |
450 | printk(KERN_ERR DRV_NAME | 447 | return -1; |
451 | " ata%u: failed to reset controller\n", ap->id); | 448 | return 0; |
449 | } | ||
450 | |||
451 | static void sil24_reset_controller(struct ata_port *ap) | ||
452 | { | ||
453 | printk(KERN_NOTICE DRV_NAME | ||
454 | " ata%u: resetting controller...\n", ap->id); | ||
455 | if (__sil24_reset_controller((void *)ap->ioaddr.cmd_addr)) | ||
456 | printk(KERN_ERR DRV_NAME | ||
457 | " ata%u: failed to reset controller\n", ap->id); | ||
452 | } | 458 | } |
453 | 459 | ||
454 | static void sil24_eng_timeout(struct ata_port *ap) | 460 | 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) | |||
740 | /* Clear interrupts */ | 746 | /* Clear interrupts */ |
741 | writel(0x0fff0fff, port + PORT_IRQ_STAT); | 747 | writel(0x0fff0fff, port + PORT_IRQ_STAT); |
742 | writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); | 748 | writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); |
749 | |||
750 | /* Clear port multiplier enable and resume bits */ | ||
751 | writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR); | ||
752 | |||
753 | /* Reset itself */ | ||
754 | if (__sil24_reset_controller(port)) | ||
755 | printk(KERN_ERR DRV_NAME | ||
756 | "(%s): failed to reset controller\n", | ||
757 | pci_name(pdev)); | ||
743 | } | 758 | } |
744 | 759 | ||
745 | /* Turn on interrupts */ | 760 | /* Turn on interrupts */ |