diff options
author | Tejun Heo <htejun@gmail.com> | 2007-04-17 10:44:07 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-04-28 14:16:03 -0400 |
commit | eca25dca17630ae354f4b1df559ed90578b794fe (patch) | |
tree | e1c0864264a227bf3302480c8a5290d542acbf71 /drivers/ata/sata_promise.c | |
parent | 21b0ad4fb8306ac2bf5a249ffc978b1b8924c7d0 (diff) |
libata: convert drivers with combined SATA/PATA ports to new init model
Convert sata_via and sata_promise to new init model. Both controllers
can have combined configuration (SATA + PATA) and used twisted
initialization method (modifying port in ->port_start) to overcome
probe_ent limitations.
This patch converts both drivers to new init model in which such
configuration is natively supported.
* promise: Combined pata port now uses separate port_info entry right
after the sata counterpart entry.
* promise: Controller configuration is discerned using ap->flags.
This simplifies init path and makes it look more like other LLDs.
* via: Both SATA and PATA ports in vt6421 are represented in their
own port_info structure.
Tested on PDC20375 (SATA150 TX2plus) [105a:3375] and PDC40775 (SATA
300 TX2plus) [105a:3d73]. Couldn't test via cuz my c3 won't boot the
current kernel.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_promise.c')
-rw-r--r-- | drivers/ata/sata_promise.c | 255 |
1 files changed, 107 insertions, 148 deletions
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 8afde4a9ca7e..f56549b90aa6 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -49,6 +49,7 @@ | |||
49 | 49 | ||
50 | 50 | ||
51 | enum { | 51 | enum { |
52 | PDC_MAX_PORTS = 4, | ||
52 | PDC_MMIO_BAR = 3, | 53 | PDC_MMIO_BAR = 3, |
53 | 54 | ||
54 | /* register offsets */ | 55 | /* register offsets */ |
@@ -89,10 +90,12 @@ enum { | |||
89 | | PDC1_ERR_MASK | PDC2_ERR_MASK), | 90 | | PDC1_ERR_MASK | PDC2_ERR_MASK), |
90 | 91 | ||
91 | board_2037x = 0, /* FastTrak S150 TX2plus */ | 92 | board_2037x = 0, /* FastTrak S150 TX2plus */ |
92 | board_20319 = 1, /* FastTrak S150 TX4 */ | 93 | board_2037x_pata = 1, /* FastTrak S150 TX2plus PATA port */ |
93 | board_20619 = 2, /* FastTrak TX4000 */ | 94 | board_20319 = 2, /* FastTrak S150 TX4 */ |
94 | board_2057x = 3, /* SATAII150 Tx2plus */ | 95 | board_20619 = 3, /* FastTrak TX4000 */ |
95 | board_40518 = 4, /* SATAII150 Tx4 */ | 96 | board_2057x = 4, /* SATAII150 Tx2plus */ |
97 | board_2057x_pata = 5, /* SATAII150 Tx2plus */ | ||
98 | board_40518 = 6, /* SATAII150 Tx4 */ | ||
96 | 99 | ||
97 | PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ | 100 | PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ |
98 | 101 | ||
@@ -115,8 +118,10 @@ enum { | |||
115 | ATA_FLAG_MMIO | | 118 | ATA_FLAG_MMIO | |
116 | ATA_FLAG_PIO_POLLING, | 119 | ATA_FLAG_PIO_POLLING, |
117 | 120 | ||
118 | /* hp->flags bits */ | 121 | /* ap->flags bits */ |
119 | PDC_FLAG_GEN_II = (1 << 0), | 122 | PDC_FLAG_GEN_II = (1 << 24), |
123 | PDC_FLAG_SATA_PATA = (1 << 25), /* supports SATA + PATA */ | ||
124 | PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */ | ||
120 | }; | 125 | }; |
121 | 126 | ||
122 | 127 | ||
@@ -125,16 +130,11 @@ struct pdc_port_priv { | |||
125 | dma_addr_t pkt_dma; | 130 | dma_addr_t pkt_dma; |
126 | }; | 131 | }; |
127 | 132 | ||
128 | struct pdc_host_priv { | ||
129 | unsigned long flags; | ||
130 | unsigned long port_flags[ATA_MAX_PORTS]; | ||
131 | }; | ||
132 | |||
133 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); | 133 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); |
134 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 134 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
135 | static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 135 | static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
136 | static irqreturn_t pdc_interrupt (int irq, void *dev_instance); | 136 | static int pdc_common_port_start(struct ata_port *ap); |
137 | static int pdc_port_start(struct ata_port *ap); | 137 | static int pdc_sata_port_start(struct ata_port *ap); |
138 | static void pdc_qc_prep(struct ata_queued_cmd *qc); | 138 | static void pdc_qc_prep(struct ata_queued_cmd *qc); |
139 | static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); | 139 | static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); |
140 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); | 140 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); |
@@ -185,14 +185,13 @@ static const struct ata_port_operations pdc_sata_ops = { | |||
185 | .post_internal_cmd = pdc_post_internal_cmd, | 185 | .post_internal_cmd = pdc_post_internal_cmd, |
186 | .cable_detect = pdc_sata_cable_detect, | 186 | .cable_detect = pdc_sata_cable_detect, |
187 | .data_xfer = ata_data_xfer, | 187 | .data_xfer = ata_data_xfer, |
188 | .irq_handler = pdc_interrupt, | ||
189 | .irq_clear = pdc_irq_clear, | 188 | .irq_clear = pdc_irq_clear, |
190 | .irq_on = ata_irq_on, | 189 | .irq_on = ata_irq_on, |
191 | .irq_ack = ata_irq_ack, | 190 | .irq_ack = ata_irq_ack, |
192 | 191 | ||
193 | .scr_read = pdc_sata_scr_read, | 192 | .scr_read = pdc_sata_scr_read, |
194 | .scr_write = pdc_sata_scr_write, | 193 | .scr_write = pdc_sata_scr_write, |
195 | .port_start = pdc_port_start, | 194 | .port_start = pdc_sata_port_start, |
196 | }; | 195 | }; |
197 | 196 | ||
198 | /* First-generation chips need a more restrictive ->check_atapi_dma op */ | 197 | /* First-generation chips need a more restrictive ->check_atapi_dma op */ |
@@ -213,14 +212,13 @@ static const struct ata_port_operations pdc_old_sata_ops = { | |||
213 | .post_internal_cmd = pdc_post_internal_cmd, | 212 | .post_internal_cmd = pdc_post_internal_cmd, |
214 | .cable_detect = pdc_sata_cable_detect, | 213 | .cable_detect = pdc_sata_cable_detect, |
215 | .data_xfer = ata_data_xfer, | 214 | .data_xfer = ata_data_xfer, |
216 | .irq_handler = pdc_interrupt, | ||
217 | .irq_clear = pdc_irq_clear, | 215 | .irq_clear = pdc_irq_clear, |
218 | .irq_on = ata_irq_on, | 216 | .irq_on = ata_irq_on, |
219 | .irq_ack = ata_irq_ack, | 217 | .irq_ack = ata_irq_ack, |
220 | 218 | ||
221 | .scr_read = pdc_sata_scr_read, | 219 | .scr_read = pdc_sata_scr_read, |
222 | .scr_write = pdc_sata_scr_write, | 220 | .scr_write = pdc_sata_scr_write, |
223 | .port_start = pdc_port_start, | 221 | .port_start = pdc_sata_port_start, |
224 | }; | 222 | }; |
225 | 223 | ||
226 | static const struct ata_port_operations pdc_pata_ops = { | 224 | static const struct ata_port_operations pdc_pata_ops = { |
@@ -240,29 +238,37 @@ static const struct ata_port_operations pdc_pata_ops = { | |||
240 | .post_internal_cmd = pdc_post_internal_cmd, | 238 | .post_internal_cmd = pdc_post_internal_cmd, |
241 | .cable_detect = pdc_pata_cable_detect, | 239 | .cable_detect = pdc_pata_cable_detect, |
242 | .data_xfer = ata_data_xfer, | 240 | .data_xfer = ata_data_xfer, |
243 | .irq_handler = pdc_interrupt, | ||
244 | .irq_clear = pdc_irq_clear, | 241 | .irq_clear = pdc_irq_clear, |
245 | .irq_on = ata_irq_on, | 242 | .irq_on = ata_irq_on, |
246 | .irq_ack = ata_irq_ack, | 243 | .irq_ack = ata_irq_ack, |
247 | 244 | ||
248 | .port_start = pdc_port_start, | 245 | .port_start = pdc_common_port_start, |
249 | }; | 246 | }; |
250 | 247 | ||
251 | static const struct ata_port_info pdc_port_info[] = { | 248 | static const struct ata_port_info pdc_port_info[] = { |
252 | /* board_2037x */ | 249 | /* board_2037x */ |
253 | { | 250 | { |
254 | .sht = &pdc_ata_sht, | 251 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | |
255 | .flags = PDC_COMMON_FLAGS, | 252 | PDC_FLAG_SATA_PATA, |
256 | .pio_mask = 0x1f, /* pio0-4 */ | 253 | .pio_mask = 0x1f, /* pio0-4 */ |
257 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 254 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
258 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 255 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
259 | .port_ops = &pdc_old_sata_ops, | 256 | .port_ops = &pdc_old_sata_ops, |
260 | }, | 257 | }, |
261 | 258 | ||
259 | /* board_2037x_pata */ | ||
260 | { | ||
261 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, | ||
262 | .pio_mask = 0x1f, /* pio0-4 */ | ||
263 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
264 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | ||
265 | .port_ops = &pdc_pata_ops, | ||
266 | }, | ||
267 | |||
262 | /* board_20319 */ | 268 | /* board_20319 */ |
263 | { | 269 | { |
264 | .sht = &pdc_ata_sht, | 270 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | |
265 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, | 271 | PDC_FLAG_4_PORTS, |
266 | .pio_mask = 0x1f, /* pio0-4 */ | 272 | .pio_mask = 0x1f, /* pio0-4 */ |
267 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 273 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
268 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 274 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
@@ -271,8 +277,8 @@ static const struct ata_port_info pdc_port_info[] = { | |||
271 | 277 | ||
272 | /* board_20619 */ | 278 | /* board_20619 */ |
273 | { | 279 | { |
274 | .sht = &pdc_ata_sht, | 280 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS | |
275 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, | 281 | PDC_FLAG_4_PORTS, |
276 | .pio_mask = 0x1f, /* pio0-4 */ | 282 | .pio_mask = 0x1f, /* pio0-4 */ |
277 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 283 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
278 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 284 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
@@ -281,18 +287,28 @@ static const struct ata_port_info pdc_port_info[] = { | |||
281 | 287 | ||
282 | /* board_2057x */ | 288 | /* board_2057x */ |
283 | { | 289 | { |
284 | .sht = &pdc_ata_sht, | 290 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | |
285 | .flags = PDC_COMMON_FLAGS, | 291 | PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA, |
286 | .pio_mask = 0x1f, /* pio0-4 */ | 292 | .pio_mask = 0x1f, /* pio0-4 */ |
287 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 293 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
288 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 294 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
289 | .port_ops = &pdc_sata_ops, | 295 | .port_ops = &pdc_sata_ops, |
290 | }, | 296 | }, |
291 | 297 | ||
298 | /* board_2057x_pata */ | ||
299 | { | ||
300 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, | ||
301 | PDC_FLAG_GEN_II, | ||
302 | .pio_mask = 0x1f, /* pio0-4 */ | ||
303 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
304 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | ||
305 | .port_ops = &pdc_pata_ops, | ||
306 | }, | ||
307 | |||
292 | /* board_40518 */ | 308 | /* board_40518 */ |
293 | { | 309 | { |
294 | .sht = &pdc_ata_sht, | 310 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA | |
295 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, | 311 | PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS, |
296 | .pio_mask = 0x1f, /* pio0-4 */ | 312 | .pio_mask = 0x1f, /* pio0-4 */ |
297 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 313 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
298 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 314 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
@@ -358,7 +374,6 @@ static int pdc_common_port_start(struct ata_port *ap) | |||
358 | 374 | ||
359 | static int pdc_sata_port_start(struct ata_port *ap) | 375 | static int pdc_sata_port_start(struct ata_port *ap) |
360 | { | 376 | { |
361 | struct pdc_host_priv *hp = ap->host->private_data; | ||
362 | int rc; | 377 | int rc; |
363 | 378 | ||
364 | rc = pdc_common_port_start(ap); | 379 | rc = pdc_common_port_start(ap); |
@@ -366,7 +381,7 @@ static int pdc_sata_port_start(struct ata_port *ap) | |||
366 | return rc; | 381 | return rc; |
367 | 382 | ||
368 | /* fix up PHYMODE4 align timing */ | 383 | /* fix up PHYMODE4 align timing */ |
369 | if (hp->flags & PDC_FLAG_GEN_II) { | 384 | if (ap->flags & PDC_FLAG_GEN_II) { |
370 | void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr; | 385 | void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr; |
371 | unsigned int tmp; | 386 | unsigned int tmp; |
372 | 387 | ||
@@ -378,21 +393,6 @@ static int pdc_sata_port_start(struct ata_port *ap) | |||
378 | return 0; | 393 | return 0; |
379 | } | 394 | } |
380 | 395 | ||
381 | static int pdc_port_start(struct ata_port *ap) | ||
382 | { | ||
383 | struct pdc_host_priv *hp = ap->host->private_data; | ||
384 | |||
385 | /* fix up port flags and cable type for SATA+PATA chips */ | ||
386 | ap->flags |= hp->port_flags[ap->port_no]; | ||
387 | if (ap->flags & ATA_FLAG_SATA) { | ||
388 | ap->cbl = ATA_CBL_SATA; | ||
389 | return pdc_sata_port_start(ap); | ||
390 | } else { | ||
391 | ap->ops = &pdc_pata_ops; | ||
392 | return pdc_common_port_start(ap); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | static void pdc_reset_port(struct ata_port *ap) | 396 | static void pdc_reset_port(struct ata_port *ap) |
397 | { | 397 | { |
398 | void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; | 398 | void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; |
@@ -660,11 +660,10 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap, | |||
660 | { | 660 | { |
661 | unsigned int handled = 0; | 661 | unsigned int handled = 0; |
662 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; | 662 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; |
663 | struct pdc_host_priv *hp = ap->host->private_data; | ||
664 | u32 port_status, err_mask; | 663 | u32 port_status, err_mask; |
665 | 664 | ||
666 | err_mask = PDC_ERR_MASK; | 665 | err_mask = PDC_ERR_MASK; |
667 | if (hp->flags & PDC_FLAG_GEN_II) | 666 | if (ap->flags & PDC_FLAG_GEN_II) |
668 | err_mask &= ~PDC1_ERR_MASK; | 667 | err_mask &= ~PDC1_ERR_MASK; |
669 | else | 668 | else |
670 | err_mask &= ~PDC2_ERR_MASK; | 669 | err_mask &= ~PDC2_ERR_MASK; |
@@ -844,34 +843,34 @@ static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc) | |||
844 | return 1; | 843 | return 1; |
845 | } | 844 | } |
846 | 845 | ||
847 | static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base, | 846 | static void pdc_ata_setup_port(struct ata_port *ap, |
848 | void __iomem *scr_addr) | 847 | void __iomem *base, void __iomem *scr_addr) |
849 | { | 848 | { |
850 | port->cmd_addr = base; | 849 | ap->ioaddr.cmd_addr = base; |
851 | port->data_addr = base; | 850 | ap->ioaddr.data_addr = base; |
852 | port->feature_addr = | 851 | ap->ioaddr.feature_addr = |
853 | port->error_addr = base + 0x4; | 852 | ap->ioaddr.error_addr = base + 0x4; |
854 | port->nsect_addr = base + 0x8; | 853 | ap->ioaddr.nsect_addr = base + 0x8; |
855 | port->lbal_addr = base + 0xc; | 854 | ap->ioaddr.lbal_addr = base + 0xc; |
856 | port->lbam_addr = base + 0x10; | 855 | ap->ioaddr.lbam_addr = base + 0x10; |
857 | port->lbah_addr = base + 0x14; | 856 | ap->ioaddr.lbah_addr = base + 0x14; |
858 | port->device_addr = base + 0x18; | 857 | ap->ioaddr.device_addr = base + 0x18; |
859 | port->command_addr = | 858 | ap->ioaddr.command_addr = |
860 | port->status_addr = base + 0x1c; | 859 | ap->ioaddr.status_addr = base + 0x1c; |
861 | port->altstatus_addr = | 860 | ap->ioaddr.altstatus_addr = |
862 | port->ctl_addr = base + 0x38; | 861 | ap->ioaddr.ctl_addr = base + 0x38; |
863 | port->scr_addr = scr_addr; | 862 | ap->ioaddr.scr_addr = scr_addr; |
864 | } | 863 | } |
865 | 864 | ||
866 | 865 | ||
867 | static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) | 866 | static void pdc_host_init(struct ata_host *host) |
868 | { | 867 | { |
869 | void __iomem *mmio = pe->iomap[PDC_MMIO_BAR]; | 868 | void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; |
870 | struct pdc_host_priv *hp = pe->private_data; | 869 | int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II; |
871 | int hotplug_offset; | 870 | int hotplug_offset; |
872 | u32 tmp; | 871 | u32 tmp; |
873 | 872 | ||
874 | if (hp->flags & PDC_FLAG_GEN_II) | 873 | if (is_gen2) |
875 | hotplug_offset = PDC2_SATA_PLUG_CSR; | 874 | hotplug_offset = PDC2_SATA_PLUG_CSR; |
876 | else | 875 | else |
877 | hotplug_offset = PDC_SATA_PLUG_CSR; | 876 | hotplug_offset = PDC_SATA_PLUG_CSR; |
@@ -885,7 +884,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) | |||
885 | /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */ | 884 | /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */ |
886 | tmp = readl(mmio + PDC_FLASH_CTL); | 885 | tmp = readl(mmio + PDC_FLASH_CTL); |
887 | tmp |= 0x02000; /* bit 13 (enable bmr burst) */ | 886 | tmp |= 0x02000; /* bit 13 (enable bmr burst) */ |
888 | if (!(hp->flags & PDC_FLAG_GEN_II)) | 887 | if (!is_gen2) |
889 | tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */ | 888 | tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */ |
890 | writel(tmp, mmio + PDC_FLASH_CTL); | 889 | writel(tmp, mmio + PDC_FLASH_CTL); |
891 | 890 | ||
@@ -898,7 +897,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) | |||
898 | writel(tmp | 0xff0000, mmio + hotplug_offset); | 897 | writel(tmp | 0xff0000, mmio + hotplug_offset); |
899 | 898 | ||
900 | /* don't initialise TBG or SLEW on 2nd generation chips */ | 899 | /* don't initialise TBG or SLEW on 2nd generation chips */ |
901 | if (hp->flags & PDC_FLAG_GEN_II) | 900 | if (is_gen2) |
902 | return; | 901 | return; |
903 | 902 | ||
904 | /* reduce TBG clock to 133 Mhz. */ | 903 | /* reduce TBG clock to 133 Mhz. */ |
@@ -920,16 +919,16 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) | |||
920 | static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 919 | static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
921 | { | 920 | { |
922 | static int printed_version; | 921 | static int printed_version; |
923 | struct ata_probe_ent *probe_ent; | 922 | const struct ata_port_info *pi = &pdc_port_info[ent->driver_data]; |
924 | struct pdc_host_priv *hp; | 923 | const struct ata_port_info *ppi[PDC_MAX_PORTS]; |
924 | struct ata_host *host; | ||
925 | void __iomem *base; | 925 | void __iomem *base; |
926 | unsigned int board_idx = (unsigned int) ent->driver_data; | 926 | int n_ports, i, rc; |
927 | int rc; | ||
928 | u8 tmp; | ||
929 | 927 | ||
930 | if (!printed_version++) | 928 | if (!printed_version++) |
931 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 929 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
932 | 930 | ||
931 | /* enable and acquire resources */ | ||
933 | rc = pcim_enable_device(pdev); | 932 | rc = pcim_enable_device(pdev); |
934 | if (rc) | 933 | if (rc) |
935 | return rc; | 934 | return rc; |
@@ -939,89 +938,49 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
939 | pcim_pin_device(pdev); | 938 | pcim_pin_device(pdev); |
940 | if (rc) | 939 | if (rc) |
941 | return rc; | 940 | return rc; |
941 | base = pcim_iomap_table(pdev)[PDC_MMIO_BAR]; | ||
942 | 942 | ||
943 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 943 | /* determine port configuration and setup host */ |
944 | if (rc) | 944 | n_ports = 2; |
945 | return rc; | 945 | if (pi->flags & PDC_FLAG_4_PORTS) |
946 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | 946 | n_ports = 4; |
947 | if (rc) | 947 | for (i = 0; i < n_ports; i++) |
948 | return rc; | 948 | ppi[i] = pi; |
949 | |||
950 | probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); | ||
951 | if (probe_ent == NULL) | ||
952 | return -ENOMEM; | ||
953 | 949 | ||
954 | probe_ent->dev = pci_dev_to_dev(pdev); | 950 | if (pi->flags & PDC_FLAG_SATA_PATA) { |
955 | INIT_LIST_HEAD(&probe_ent->node); | 951 | u8 tmp = readb(base + PDC_FLASH_CTL+1); |
952 | if (!(tmp & 0x80)) { | ||
953 | ppi[n_ports++] = pi + 1; | ||
954 | dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n"); | ||
955 | } | ||
956 | } | ||
956 | 957 | ||
957 | hp = devm_kzalloc(&pdev->dev, sizeof(*hp), GFP_KERNEL); | 958 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); |
958 | if (hp == NULL) | 959 | if (!host) { |
960 | dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n"); | ||
959 | return -ENOMEM; | 961 | return -ENOMEM; |
960 | |||
961 | probe_ent->private_data = hp; | ||
962 | |||
963 | probe_ent->sht = pdc_port_info[board_idx].sht; | ||
964 | probe_ent->port_flags = pdc_port_info[board_idx].flags; | ||
965 | probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask; | ||
966 | probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask; | ||
967 | probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask; | ||
968 | probe_ent->port_ops = pdc_port_info[board_idx].port_ops; | ||
969 | |||
970 | probe_ent->irq = pdev->irq; | ||
971 | probe_ent->irq_flags = IRQF_SHARED; | ||
972 | probe_ent->iomap = pcim_iomap_table(pdev); | ||
973 | |||
974 | base = probe_ent->iomap[PDC_MMIO_BAR]; | ||
975 | |||
976 | pdc_ata_setup_port(&probe_ent->port[0], base + 0x200, base + 0x400); | ||
977 | pdc_ata_setup_port(&probe_ent->port[1], base + 0x280, base + 0x500); | ||
978 | |||
979 | /* notice 4-port boards */ | ||
980 | switch (board_idx) { | ||
981 | case board_40518: | ||
982 | hp->flags |= PDC_FLAG_GEN_II; | ||
983 | /* Fall through */ | ||
984 | case board_20319: | ||
985 | probe_ent->n_ports = 4; | ||
986 | pdc_ata_setup_port(&probe_ent->port[2], base + 0x300, base + 0x600); | ||
987 | pdc_ata_setup_port(&probe_ent->port[3], base + 0x380, base + 0x700); | ||
988 | break; | ||
989 | case board_2057x: | ||
990 | hp->flags |= PDC_FLAG_GEN_II; | ||
991 | /* Fall through */ | ||
992 | case board_2037x: | ||
993 | /* TX2plus boards also have a PATA port */ | ||
994 | tmp = readb(base + PDC_FLASH_CTL+1); | ||
995 | if (!(tmp & 0x80)) { | ||
996 | probe_ent->n_ports = 3; | ||
997 | pdc_ata_setup_port(&probe_ent->port[2], base + 0x300, NULL); | ||
998 | hp->port_flags[2] = ATA_FLAG_SLAVE_POSS; | ||
999 | printk(KERN_INFO DRV_NAME " PATA port found\n"); | ||
1000 | } else | ||
1001 | probe_ent->n_ports = 2; | ||
1002 | hp->port_flags[0] = ATA_FLAG_SATA; | ||
1003 | hp->port_flags[1] = ATA_FLAG_SATA; | ||
1004 | break; | ||
1005 | case board_20619: | ||
1006 | probe_ent->n_ports = 4; | ||
1007 | pdc_ata_setup_port(&probe_ent->port[2], base + 0x300, NULL); | ||
1008 | pdc_ata_setup_port(&probe_ent->port[3], base + 0x380, NULL); | ||
1009 | break; | ||
1010 | default: | ||
1011 | BUG(); | ||
1012 | break; | ||
1013 | } | 962 | } |
963 | host->iomap = pcim_iomap_table(pdev); | ||
1014 | 964 | ||
1015 | pci_set_master(pdev); | 965 | for (i = 0; i < host->n_ports; i++) |
966 | pdc_ata_setup_port(host->ports[i], | ||
967 | base + 0x200 + i * 0x80, | ||
968 | base + 0x400 + i * 0x100); | ||
1016 | 969 | ||
1017 | /* initialize adapter */ | 970 | /* initialize adapter */ |
1018 | pdc_host_init(board_idx, probe_ent); | 971 | pdc_host_init(host); |
1019 | 972 | ||
1020 | if (!ata_device_add(probe_ent)) | 973 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); |
1021 | return -ENODEV; | 974 | if (rc) |
975 | return rc; | ||
976 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | ||
977 | if (rc) | ||
978 | return rc; | ||
1022 | 979 | ||
1023 | devm_kfree(&pdev->dev, probe_ent); | 980 | /* start host, request IRQ and attach */ |
1024 | return 0; | 981 | pci_set_master(pdev); |
982 | return ata_host_activate(host, pdev->irq, pdc_interrupt, IRQF_SHARED, | ||
983 | &pdc_ata_sht); | ||
1025 | } | 984 | } |
1026 | 985 | ||
1027 | 986 | ||