aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2005-09-13 00:21:29 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-14 08:19:27 -0400
commit923f122573851d18a3832ca808269fa2d5046fb1 (patch)
tree41f30af97a513387389429ad45037651e08d513d
parent905ec87e93bc9e01b15c60035cd6a50c636cbaef (diff)
[PATCH] sil24: initialization fix
sil24 0.20 didn't use to perform (what seems to be) port multiplier initialization and controller reset 0.10 driver does. This makes some sil24 controllers malfunction. This patch adds PM initialization and controller resetting to initilization and bumps version to 0.21. Please refer to the following thread for more information. http://marc.theaimsgroup.com/?l=linux-ide&m=112582819830324&w=2 http://marc.theaimsgroup.com/?l=linux-ide&m=112636045531060&w=2 Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-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 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
429static void sil24_reset_controller(struct ata_port *ap) 429static 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
451static 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
454static void sil24_eng_timeout(struct ata_port *ap) 460static 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 */