aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_sil24.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_sil24.c')
-rw-r--r--drivers/ata/sata_sil24.c122
1 files changed, 44 insertions, 78 deletions
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 5614df8c1ce2..e6223ba667da 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -323,7 +323,7 @@ struct sil24_port_priv {
323 struct ata_taskfile tf; /* Cached taskfile registers */ 323 struct ata_taskfile tf; /* Cached taskfile registers */
324}; 324};
325 325
326static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev); 326static void sil24_dev_config(struct ata_device *dev);
327static u8 sil24_check_status(struct ata_port *ap); 327static u8 sil24_check_status(struct ata_port *ap);
328static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); 328static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
329static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); 329static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
@@ -331,7 +331,6 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
331static void sil24_qc_prep(struct ata_queued_cmd *qc); 331static void sil24_qc_prep(struct ata_queued_cmd *qc);
332static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); 332static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
333static void sil24_irq_clear(struct ata_port *ap); 333static void sil24_irq_clear(struct ata_port *ap);
334static irqreturn_t sil24_interrupt(int irq, void *dev_instance);
335static void sil24_freeze(struct ata_port *ap); 334static void sil24_freeze(struct ata_port *ap);
336static void sil24_thaw(struct ata_port *ap); 335static void sil24_thaw(struct ata_port *ap);
337static void sil24_error_handler(struct ata_port *ap); 336static void sil24_error_handler(struct ata_port *ap);
@@ -401,7 +400,6 @@ static const struct ata_port_operations sil24_ops = {
401 .qc_prep = sil24_qc_prep, 400 .qc_prep = sil24_qc_prep,
402 .qc_issue = sil24_qc_issue, 401 .qc_issue = sil24_qc_issue,
403 402
404 .irq_handler = sil24_interrupt,
405 .irq_clear = sil24_irq_clear, 403 .irq_clear = sil24_irq_clear,
406 .irq_on = ata_dummy_irq_on, 404 .irq_on = ata_dummy_irq_on,
407 .irq_ack = ata_dummy_irq_ack, 405 .irq_ack = ata_dummy_irq_ack,
@@ -424,10 +422,9 @@ static const struct ata_port_operations sil24_ops = {
424#define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30) 422#define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30)
425#define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1) 423#define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1)
426 424
427static struct ata_port_info sil24_port_info[] = { 425static const struct ata_port_info sil24_port_info[] = {
428 /* sil_3124 */ 426 /* sil_3124 */
429 { 427 {
430 .sht = &sil24_sht,
431 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) | 428 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
432 SIL24_FLAG_PCIX_IRQ_WOC, 429 SIL24_FLAG_PCIX_IRQ_WOC,
433 .pio_mask = 0x1f, /* pio0-4 */ 430 .pio_mask = 0x1f, /* pio0-4 */
@@ -437,7 +434,6 @@ static struct ata_port_info sil24_port_info[] = {
437 }, 434 },
438 /* sil_3132 */ 435 /* sil_3132 */
439 { 436 {
440 .sht = &sil24_sht,
441 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), 437 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
442 .pio_mask = 0x1f, /* pio0-4 */ 438 .pio_mask = 0x1f, /* pio0-4 */
443 .mwdma_mask = 0x07, /* mwdma0-2 */ 439 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -446,7 +442,6 @@ static struct ata_port_info sil24_port_info[] = {
446 }, 442 },
447 /* sil_3131/sil_3531 */ 443 /* sil_3131/sil_3531 */
448 { 444 {
449 .sht = &sil24_sht,
450 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), 445 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
451 .pio_mask = 0x1f, /* pio0-4 */ 446 .pio_mask = 0x1f, /* pio0-4 */
452 .mwdma_mask = 0x07, /* mwdma0-2 */ 447 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -462,9 +457,9 @@ static int sil24_tag(int tag)
462 return tag; 457 return tag;
463} 458}
464 459
465static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev) 460static void sil24_dev_config(struct ata_device *dev)
466{ 461{
467 void __iomem *port = ap->ioaddr.cmd_addr; 462 void __iomem *port = dev->ap->ioaddr.cmd_addr;
468 463
469 if (dev->cdb_len == 16) 464 if (dev->cdb_len == 16)
470 writel(PORT_CS_CDB16, port + PORT_CTRL_STAT); 465 writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
@@ -924,11 +919,8 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
924{ 919{
925 struct ata_port *ap = qc->ap; 920 struct ata_port *ap = qc->ap;
926 921
927 if (qc->flags & ATA_QCFLAG_FAILED)
928 qc->err_mask |= AC_ERR_OTHER;
929
930 /* make DMA engine forget about the failed command */ 922 /* make DMA engine forget about the failed command */
931 if (qc->err_mask) 923 if (qc->flags & ATA_QCFLAG_FAILED)
932 sil24_init_port(ap); 924 sil24_init_port(ap);
933} 925}
934 926
@@ -964,11 +956,10 @@ static int sil24_port_start(struct ata_port *ap)
964 return 0; 956 return 0;
965} 957}
966 958
967static void sil24_init_controller(struct pci_dev *pdev, int n_ports, 959static void sil24_init_controller(struct ata_host *host)
968 unsigned long port_flags,
969 void __iomem *host_base,
970 void __iomem *port_base)
971{ 960{
961 void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
962 void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
972 u32 tmp; 963 u32 tmp;
973 int i; 964 int i;
974 965
@@ -979,7 +970,7 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
979 writel(0, host_base + HOST_CTRL); 970 writel(0, host_base + HOST_CTRL);
980 971
981 /* init ports */ 972 /* init ports */
982 for (i = 0; i < n_ports; i++) { 973 for (i = 0; i < host->n_ports; i++) {
983 void __iomem *port = port_base + i * PORT_REGS_SIZE; 974 void __iomem *port = port_base + i * PORT_REGS_SIZE;
984 975
985 /* Initial PHY setting */ 976 /* Initial PHY setting */
@@ -993,12 +984,12 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
993 PORT_CS_PORT_RST, 984 PORT_CS_PORT_RST,
994 PORT_CS_PORT_RST, 10, 100); 985 PORT_CS_PORT_RST, 10, 100);
995 if (tmp & PORT_CS_PORT_RST) 986 if (tmp & PORT_CS_PORT_RST)
996 dev_printk(KERN_ERR, &pdev->dev, 987 dev_printk(KERN_ERR, host->dev,
997 "failed to clear port RST\n"); 988 "failed to clear port RST\n");
998 } 989 }
999 990
1000 /* Configure IRQ WoC */ 991 /* Configure IRQ WoC */
1001 if (port_flags & SIL24_FLAG_PCIX_IRQ_WOC) 992 if (host->ports[0]->flags & SIL24_FLAG_PCIX_IRQ_WOC)
1002 writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT); 993 writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
1003 else 994 else
1004 writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); 995 writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
@@ -1026,18 +1017,17 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
1026static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 1017static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1027{ 1018{
1028 static int printed_version = 0; 1019 static int printed_version = 0;
1029 struct device *dev = &pdev->dev; 1020 struct ata_port_info pi = sil24_port_info[ent->driver_data];
1030 unsigned int board_id = (unsigned int)ent->driver_data; 1021 const struct ata_port_info *ppi[] = { &pi, NULL };
1031 struct ata_port_info *pinfo = &sil24_port_info[board_id]; 1022 void __iomem * const *iomap;
1032 struct ata_probe_ent *probe_ent; 1023 struct ata_host *host;
1033 void __iomem *host_base;
1034 void __iomem *port_base;
1035 int i, rc; 1024 int i, rc;
1036 u32 tmp; 1025 u32 tmp;
1037 1026
1038 if (!printed_version++) 1027 if (!printed_version++)
1039 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); 1028 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
1040 1029
1030 /* acquire resources */
1041 rc = pcim_enable_device(pdev); 1031 rc = pcim_enable_device(pdev);
1042 if (rc) 1032 if (rc)
1043 return rc; 1033 return rc;
@@ -1047,33 +1037,36 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1047 DRV_NAME); 1037 DRV_NAME);
1048 if (rc) 1038 if (rc)
1049 return rc; 1039 return rc;
1040 iomap = pcim_iomap_table(pdev);
1050 1041
1051 /* allocate & init probe_ent */ 1042 /* apply workaround for completion IRQ loss on PCI-X errata */
1052 probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); 1043 if (pi.flags & SIL24_FLAG_PCIX_IRQ_WOC) {
1053 if (!probe_ent) 1044 tmp = readl(iomap[SIL24_HOST_BAR] + HOST_CTRL);
1054 return -ENOMEM; 1045 if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
1046 dev_printk(KERN_INFO, &pdev->dev,
1047 "Applying completion IRQ loss on PCI-X "
1048 "errata fix\n");
1049 else
1050 pi.flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
1051 }
1055 1052
1056 probe_ent->dev = pci_dev_to_dev(pdev); 1053 /* allocate and fill host */
1057 INIT_LIST_HEAD(&probe_ent->node); 1054 host = ata_host_alloc_pinfo(&pdev->dev, ppi,
1055 SIL24_FLAG2NPORTS(ppi[0]->flags));
1056 if (!host)
1057 return -ENOMEM;
1058 host->iomap = iomap;
1058 1059
1059 probe_ent->sht = pinfo->sht; 1060 for (i = 0; i < host->n_ports; i++) {
1060 probe_ent->port_flags = pinfo->flags; 1061 void __iomem *port = iomap[SIL24_PORT_BAR] + i * PORT_REGS_SIZE;
1061 probe_ent->pio_mask = pinfo->pio_mask;
1062 probe_ent->mwdma_mask = pinfo->mwdma_mask;
1063 probe_ent->udma_mask = pinfo->udma_mask;
1064 probe_ent->port_ops = pinfo->port_ops;
1065 probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->flags);
1066 1062
1067 probe_ent->irq = pdev->irq; 1063 host->ports[i]->ioaddr.cmd_addr = port;
1068 probe_ent->irq_flags = IRQF_SHARED; 1064 host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL;
1069 probe_ent->iomap = pcim_iomap_table(pdev);
1070 1065
1071 host_base = probe_ent->iomap[SIL24_HOST_BAR]; 1066 ata_std_ports(&host->ports[i]->ioaddr);
1072 port_base = probe_ent->iomap[SIL24_PORT_BAR]; 1067 }
1073 1068
1074 /* 1069 /* configure and activate the device */
1075 * Configure the device
1076 */
1077 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { 1070 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1078 rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); 1071 rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
1079 if (rc) { 1072 if (rc) {
@@ -1099,36 +1092,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1099 } 1092 }
1100 } 1093 }
1101 1094
1102 /* Apply workaround for completion IRQ loss on PCI-X errata */ 1095 sil24_init_controller(host);
1103 if (probe_ent->port_flags & SIL24_FLAG_PCIX_IRQ_WOC) {
1104 tmp = readl(host_base + HOST_CTRL);
1105 if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
1106 dev_printk(KERN_INFO, &pdev->dev,
1107 "Applying completion IRQ loss on PCI-X "
1108 "errata fix\n");
1109 else
1110 probe_ent->port_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
1111 }
1112
1113 for (i = 0; i < probe_ent->n_ports; i++) {
1114 void __iomem *port = port_base + i * PORT_REGS_SIZE;
1115
1116 probe_ent->port[i].cmd_addr = port;
1117 probe_ent->port[i].scr_addr = port + PORT_SCONTROL;
1118
1119 ata_std_ports(&probe_ent->port[i]);
1120 }
1121
1122 sil24_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
1123 host_base, port_base);
1124 1096
1125 pci_set_master(pdev); 1097 pci_set_master(pdev);
1126 1098 return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED,
1127 if (!ata_device_add(probe_ent)) 1099 &sil24_sht);
1128 return -ENODEV;
1129
1130 devm_kfree(dev, probe_ent);
1131 return 0;
1132} 1100}
1133 1101
1134#ifdef CONFIG_PM 1102#ifdef CONFIG_PM
@@ -1136,7 +1104,6 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
1136{ 1104{
1137 struct ata_host *host = dev_get_drvdata(&pdev->dev); 1105 struct ata_host *host = dev_get_drvdata(&pdev->dev);
1138 void __iomem *host_base = host->iomap[SIL24_HOST_BAR]; 1106 void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
1139 void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
1140 int rc; 1107 int rc;
1141 1108
1142 rc = ata_pci_device_do_resume(pdev); 1109 rc = ata_pci_device_do_resume(pdev);
@@ -1146,8 +1113,7 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
1146 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) 1113 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
1147 writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL); 1114 writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL);
1148 1115
1149 sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags, 1116 sil24_init_controller(host);
1150 host_base, port_base);
1151 1117
1152 ata_host_resume(host); 1118 ata_host_resume(host);
1153 1119