diff options
author | Tejun Heo <htejun@gmail.com> | 2007-04-17 10:44:08 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-04-28 14:16:06 -0400 |
commit | 4447d35156169cf136e829eb6b5cac2d6370f2d9 (patch) | |
tree | 20be4c582ea4ce1cce1b0f8dbea949a410a72e3c /drivers/ata/sata_sil24.c | |
parent | 9a829ccfc833269bdb85751f5048288ab93678ac (diff) |
libata: convert the remaining SATA drivers to new init model
Convert ahci, sata_sil, sata_sil24, sata_svw, sata_qstor, sata_mv,
sata_sx4, sata_vsc and sata_inic162x to new init model.
Now that host and ap are available during intialization, functions are
converted to take either host or ap instead of low level parameters
which were inevitable for functions shared between init and other
paths. This simplifies code quite a bit.
* init_one()'s now follow more consistent init order
* ahci_setup_port() and ahci_host_init() collapsed into
ahci_init_one() for init order consistency
* sata_vsc uses port_info instead of setting fields manually
* in sata_svw, k2_board_info converted to port_info (info is now in
port flags). port number is honored now.
Tested on ICH7/8 AHCI, jmb360, sil3112, 3114, 3124 and 3132.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_sil24.c')
-rw-r--r-- | drivers/ata/sata_sil24.c | 111 |
1 files changed, 40 insertions, 71 deletions
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 4f522ec04049..e6223ba667da 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
@@ -331,7 +331,6 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | |||
331 | static void sil24_qc_prep(struct ata_queued_cmd *qc); | 331 | static void sil24_qc_prep(struct ata_queued_cmd *qc); |
332 | static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); | 332 | static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); |
333 | static void sil24_irq_clear(struct ata_port *ap); | 333 | static void sil24_irq_clear(struct ata_port *ap); |
334 | static irqreturn_t sil24_interrupt(int irq, void *dev_instance); | ||
335 | static void sil24_freeze(struct ata_port *ap); | 334 | static void sil24_freeze(struct ata_port *ap); |
336 | static void sil24_thaw(struct ata_port *ap); | 335 | static void sil24_thaw(struct ata_port *ap); |
337 | static void sil24_error_handler(struct ata_port *ap); | 336 | static 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 | ||
427 | static struct ata_port_info sil24_port_info[] = { | 425 | static 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 */ |
@@ -961,11 +956,10 @@ static int sil24_port_start(struct ata_port *ap) | |||
961 | return 0; | 956 | return 0; |
962 | } | 957 | } |
963 | 958 | ||
964 | static void sil24_init_controller(struct pci_dev *pdev, int n_ports, | 959 | static void sil24_init_controller(struct ata_host *host) |
965 | unsigned long port_flags, | ||
966 | void __iomem *host_base, | ||
967 | void __iomem *port_base) | ||
968 | { | 960 | { |
961 | void __iomem *host_base = host->iomap[SIL24_HOST_BAR]; | ||
962 | void __iomem *port_base = host->iomap[SIL24_PORT_BAR]; | ||
969 | u32 tmp; | 963 | u32 tmp; |
970 | int i; | 964 | int i; |
971 | 965 | ||
@@ -976,7 +970,7 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports, | |||
976 | writel(0, host_base + HOST_CTRL); | 970 | writel(0, host_base + HOST_CTRL); |
977 | 971 | ||
978 | /* init ports */ | 972 | /* init ports */ |
979 | for (i = 0; i < n_ports; i++) { | 973 | for (i = 0; i < host->n_ports; i++) { |
980 | void __iomem *port = port_base + i * PORT_REGS_SIZE; | 974 | void __iomem *port = port_base + i * PORT_REGS_SIZE; |
981 | 975 | ||
982 | /* Initial PHY setting */ | 976 | /* Initial PHY setting */ |
@@ -990,12 +984,12 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports, | |||
990 | PORT_CS_PORT_RST, | 984 | PORT_CS_PORT_RST, |
991 | PORT_CS_PORT_RST, 10, 100); | 985 | PORT_CS_PORT_RST, 10, 100); |
992 | if (tmp & PORT_CS_PORT_RST) | 986 | if (tmp & PORT_CS_PORT_RST) |
993 | dev_printk(KERN_ERR, &pdev->dev, | 987 | dev_printk(KERN_ERR, host->dev, |
994 | "failed to clear port RST\n"); | 988 | "failed to clear port RST\n"); |
995 | } | 989 | } |
996 | 990 | ||
997 | /* Configure IRQ WoC */ | 991 | /* Configure IRQ WoC */ |
998 | if (port_flags & SIL24_FLAG_PCIX_IRQ_WOC) | 992 | if (host->ports[0]->flags & SIL24_FLAG_PCIX_IRQ_WOC) |
999 | writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT); | 993 | writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT); |
1000 | else | 994 | else |
1001 | writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); | 995 | writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR); |
@@ -1023,18 +1017,17 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports, | |||
1023 | static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 1017 | static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
1024 | { | 1018 | { |
1025 | static int printed_version = 0; | 1019 | static int printed_version = 0; |
1026 | struct device *dev = &pdev->dev; | 1020 | struct ata_port_info pi = sil24_port_info[ent->driver_data]; |
1027 | unsigned int board_id = (unsigned int)ent->driver_data; | 1021 | const struct ata_port_info *ppi[] = { &pi, NULL }; |
1028 | struct ata_port_info *pinfo = &sil24_port_info[board_id]; | 1022 | void __iomem * const *iomap; |
1029 | struct ata_probe_ent *probe_ent; | 1023 | struct ata_host *host; |
1030 | void __iomem *host_base; | ||
1031 | void __iomem *port_base; | ||
1032 | int i, rc; | 1024 | int i, rc; |
1033 | u32 tmp; | 1025 | u32 tmp; |
1034 | 1026 | ||
1035 | if (!printed_version++) | 1027 | if (!printed_version++) |
1036 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 1028 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
1037 | 1029 | ||
1030 | /* acquire resources */ | ||
1038 | rc = pcim_enable_device(pdev); | 1031 | rc = pcim_enable_device(pdev); |
1039 | if (rc) | 1032 | if (rc) |
1040 | return rc; | 1033 | return rc; |
@@ -1044,33 +1037,36 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1044 | DRV_NAME); | 1037 | DRV_NAME); |
1045 | if (rc) | 1038 | if (rc) |
1046 | return rc; | 1039 | return rc; |
1040 | iomap = pcim_iomap_table(pdev); | ||
1047 | 1041 | ||
1048 | /* allocate & init probe_ent */ | 1042 | /* apply workaround for completion IRQ loss on PCI-X errata */ |
1049 | probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); | 1043 | if (pi.flags & SIL24_FLAG_PCIX_IRQ_WOC) { |
1050 | if (!probe_ent) | 1044 | tmp = readl(iomap[SIL24_HOST_BAR] + HOST_CTRL); |
1051 | 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 | } | ||
1052 | 1052 | ||
1053 | probe_ent->dev = pci_dev_to_dev(pdev); | 1053 | /* allocate and fill host */ |
1054 | 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; | ||
1055 | 1059 | ||
1056 | probe_ent->sht = pinfo->sht; | 1060 | for (i = 0; i < host->n_ports; i++) { |
1057 | probe_ent->port_flags = pinfo->flags; | 1061 | void __iomem *port = iomap[SIL24_PORT_BAR] + i * PORT_REGS_SIZE; |
1058 | probe_ent->pio_mask = pinfo->pio_mask; | ||
1059 | probe_ent->mwdma_mask = pinfo->mwdma_mask; | ||
1060 | probe_ent->udma_mask = pinfo->udma_mask; | ||
1061 | probe_ent->port_ops = pinfo->port_ops; | ||
1062 | probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->flags); | ||
1063 | 1062 | ||
1064 | probe_ent->irq = pdev->irq; | 1063 | host->ports[i]->ioaddr.cmd_addr = port; |
1065 | probe_ent->irq_flags = IRQF_SHARED; | 1064 | host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL; |
1066 | probe_ent->iomap = pcim_iomap_table(pdev); | ||
1067 | 1065 | ||
1068 | host_base = probe_ent->iomap[SIL24_HOST_BAR]; | 1066 | ata_std_ports(&host->ports[i]->ioaddr); |
1069 | port_base = probe_ent->iomap[SIL24_PORT_BAR]; | 1067 | } |
1070 | 1068 | ||
1071 | /* | 1069 | /* configure and activate the device */ |
1072 | * Configure the device | ||
1073 | */ | ||
1074 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { | 1070 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { |
1075 | rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); | 1071 | rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); |
1076 | if (rc) { | 1072 | if (rc) { |
@@ -1096,36 +1092,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1096 | } | 1092 | } |
1097 | } | 1093 | } |
1098 | 1094 | ||
1099 | /* Apply workaround for completion IRQ loss on PCI-X errata */ | 1095 | sil24_init_controller(host); |
1100 | if (probe_ent->port_flags & SIL24_FLAG_PCIX_IRQ_WOC) { | ||
1101 | tmp = readl(host_base + HOST_CTRL); | ||
1102 | if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL)) | ||
1103 | dev_printk(KERN_INFO, &pdev->dev, | ||
1104 | "Applying completion IRQ loss on PCI-X " | ||
1105 | "errata fix\n"); | ||
1106 | else | ||
1107 | probe_ent->port_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC; | ||
1108 | } | ||
1109 | |||
1110 | for (i = 0; i < probe_ent->n_ports; i++) { | ||
1111 | void __iomem *port = port_base + i * PORT_REGS_SIZE; | ||
1112 | |||
1113 | probe_ent->port[i].cmd_addr = port; | ||
1114 | probe_ent->port[i].scr_addr = port + PORT_SCONTROL; | ||
1115 | |||
1116 | ata_std_ports(&probe_ent->port[i]); | ||
1117 | } | ||
1118 | |||
1119 | sil24_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags, | ||
1120 | host_base, port_base); | ||
1121 | 1096 | ||
1122 | pci_set_master(pdev); | 1097 | pci_set_master(pdev); |
1123 | 1098 | return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED, | |
1124 | if (!ata_device_add(probe_ent)) | 1099 | &sil24_sht); |
1125 | return -ENODEV; | ||
1126 | |||
1127 | devm_kfree(dev, probe_ent); | ||
1128 | return 0; | ||
1129 | } | 1100 | } |
1130 | 1101 | ||
1131 | #ifdef CONFIG_PM | 1102 | #ifdef CONFIG_PM |
@@ -1133,7 +1104,6 @@ static int sil24_pci_device_resume(struct pci_dev *pdev) | |||
1133 | { | 1104 | { |
1134 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | 1105 | struct ata_host *host = dev_get_drvdata(&pdev->dev); |
1135 | void __iomem *host_base = host->iomap[SIL24_HOST_BAR]; | 1106 | void __iomem *host_base = host->iomap[SIL24_HOST_BAR]; |
1136 | void __iomem *port_base = host->iomap[SIL24_PORT_BAR]; | ||
1137 | int rc; | 1107 | int rc; |
1138 | 1108 | ||
1139 | rc = ata_pci_device_do_resume(pdev); | 1109 | rc = ata_pci_device_do_resume(pdev); |
@@ -1143,8 +1113,7 @@ static int sil24_pci_device_resume(struct pci_dev *pdev) | |||
1143 | if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) | 1113 | if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) |
1144 | writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL); | 1114 | writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL); |
1145 | 1115 | ||
1146 | sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags, | 1116 | sil24_init_controller(host); |
1147 | host_base, port_base); | ||
1148 | 1117 | ||
1149 | ata_host_resume(host); | 1118 | ata_host_resume(host); |
1150 | 1119 | ||