diff options
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 105 |
1 files changed, 40 insertions, 65 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 10cad5d9a76d..cb9b9ac12b4c 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -347,7 +347,6 @@ static void mv_port_stop(struct ata_port *ap); | |||
347 | static void mv_qc_prep(struct ata_queued_cmd *qc); | 347 | static void mv_qc_prep(struct ata_queued_cmd *qc); |
348 | static void mv_qc_prep_iie(struct ata_queued_cmd *qc); | 348 | static void mv_qc_prep_iie(struct ata_queued_cmd *qc); |
349 | static unsigned int mv_qc_issue(struct ata_queued_cmd *qc); | 349 | static unsigned int mv_qc_issue(struct ata_queued_cmd *qc); |
350 | static irqreturn_t mv_interrupt(int irq, void *dev_instance); | ||
351 | static void mv_eng_timeout(struct ata_port *ap); | 350 | static void mv_eng_timeout(struct ata_port *ap); |
352 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 351 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
353 | 352 | ||
@@ -410,7 +409,6 @@ static const struct ata_port_operations mv5_ops = { | |||
410 | 409 | ||
411 | .eng_timeout = mv_eng_timeout, | 410 | .eng_timeout = mv_eng_timeout, |
412 | 411 | ||
413 | .irq_handler = mv_interrupt, | ||
414 | .irq_clear = mv_irq_clear, | 412 | .irq_clear = mv_irq_clear, |
415 | .irq_on = ata_irq_on, | 413 | .irq_on = ata_irq_on, |
416 | .irq_ack = ata_irq_ack, | 414 | .irq_ack = ata_irq_ack, |
@@ -440,7 +438,6 @@ static const struct ata_port_operations mv6_ops = { | |||
440 | 438 | ||
441 | .eng_timeout = mv_eng_timeout, | 439 | .eng_timeout = mv_eng_timeout, |
442 | 440 | ||
443 | .irq_handler = mv_interrupt, | ||
444 | .irq_clear = mv_irq_clear, | 441 | .irq_clear = mv_irq_clear, |
445 | .irq_on = ata_irq_on, | 442 | .irq_on = ata_irq_on, |
446 | .irq_ack = ata_irq_ack, | 443 | .irq_ack = ata_irq_ack, |
@@ -470,7 +467,6 @@ static const struct ata_port_operations mv_iie_ops = { | |||
470 | 467 | ||
471 | .eng_timeout = mv_eng_timeout, | 468 | .eng_timeout = mv_eng_timeout, |
472 | 469 | ||
473 | .irq_handler = mv_interrupt, | ||
474 | .irq_clear = mv_irq_clear, | 470 | .irq_clear = mv_irq_clear, |
475 | .irq_on = ata_irq_on, | 471 | .irq_on = ata_irq_on, |
476 | .irq_ack = ata_irq_ack, | 472 | .irq_ack = ata_irq_ack, |
@@ -484,35 +480,30 @@ static const struct ata_port_operations mv_iie_ops = { | |||
484 | 480 | ||
485 | static const struct ata_port_info mv_port_info[] = { | 481 | static const struct ata_port_info mv_port_info[] = { |
486 | { /* chip_504x */ | 482 | { /* chip_504x */ |
487 | .sht = &mv_sht, | ||
488 | .flags = MV_COMMON_FLAGS, | 483 | .flags = MV_COMMON_FLAGS, |
489 | .pio_mask = 0x1f, /* pio0-4 */ | 484 | .pio_mask = 0x1f, /* pio0-4 */ |
490 | .udma_mask = 0x7f, /* udma0-6 */ | 485 | .udma_mask = 0x7f, /* udma0-6 */ |
491 | .port_ops = &mv5_ops, | 486 | .port_ops = &mv5_ops, |
492 | }, | 487 | }, |
493 | { /* chip_508x */ | 488 | { /* chip_508x */ |
494 | .sht = &mv_sht, | ||
495 | .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), | 489 | .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), |
496 | .pio_mask = 0x1f, /* pio0-4 */ | 490 | .pio_mask = 0x1f, /* pio0-4 */ |
497 | .udma_mask = 0x7f, /* udma0-6 */ | 491 | .udma_mask = 0x7f, /* udma0-6 */ |
498 | .port_ops = &mv5_ops, | 492 | .port_ops = &mv5_ops, |
499 | }, | 493 | }, |
500 | { /* chip_5080 */ | 494 | { /* chip_5080 */ |
501 | .sht = &mv_sht, | ||
502 | .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), | 495 | .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), |
503 | .pio_mask = 0x1f, /* pio0-4 */ | 496 | .pio_mask = 0x1f, /* pio0-4 */ |
504 | .udma_mask = 0x7f, /* udma0-6 */ | 497 | .udma_mask = 0x7f, /* udma0-6 */ |
505 | .port_ops = &mv5_ops, | 498 | .port_ops = &mv5_ops, |
506 | }, | 499 | }, |
507 | { /* chip_604x */ | 500 | { /* chip_604x */ |
508 | .sht = &mv_sht, | ||
509 | .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), | 501 | .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), |
510 | .pio_mask = 0x1f, /* pio0-4 */ | 502 | .pio_mask = 0x1f, /* pio0-4 */ |
511 | .udma_mask = 0x7f, /* udma0-6 */ | 503 | .udma_mask = 0x7f, /* udma0-6 */ |
512 | .port_ops = &mv6_ops, | 504 | .port_ops = &mv6_ops, |
513 | }, | 505 | }, |
514 | { /* chip_608x */ | 506 | { /* chip_608x */ |
515 | .sht = &mv_sht, | ||
516 | .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 507 | .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | |
517 | MV_FLAG_DUAL_HC), | 508 | MV_FLAG_DUAL_HC), |
518 | .pio_mask = 0x1f, /* pio0-4 */ | 509 | .pio_mask = 0x1f, /* pio0-4 */ |
@@ -520,14 +511,12 @@ static const struct ata_port_info mv_port_info[] = { | |||
520 | .port_ops = &mv6_ops, | 511 | .port_ops = &mv6_ops, |
521 | }, | 512 | }, |
522 | { /* chip_6042 */ | 513 | { /* chip_6042 */ |
523 | .sht = &mv_sht, | ||
524 | .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), | 514 | .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), |
525 | .pio_mask = 0x1f, /* pio0-4 */ | 515 | .pio_mask = 0x1f, /* pio0-4 */ |
526 | .udma_mask = 0x7f, /* udma0-6 */ | 516 | .udma_mask = 0x7f, /* udma0-6 */ |
527 | .port_ops = &mv_iie_ops, | 517 | .port_ops = &mv_iie_ops, |
528 | }, | 518 | }, |
529 | { /* chip_7042 */ | 519 | { /* chip_7042 */ |
530 | .sht = &mv_sht, | ||
531 | .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), | 520 | .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), |
532 | .pio_mask = 0x1f, /* pio0-4 */ | 521 | .pio_mask = 0x1f, /* pio0-4 */ |
533 | .udma_mask = 0x7f, /* udma0-6 */ | 522 | .udma_mask = 0x7f, /* udma0-6 */ |
@@ -2099,9 +2088,10 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) | |||
2099 | readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); | 2088 | readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); |
2100 | } | 2089 | } |
2101 | 2090 | ||
2102 | static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, | 2091 | static int mv_chip_id(struct ata_host *host, unsigned int board_idx) |
2103 | unsigned int board_idx) | ||
2104 | { | 2092 | { |
2093 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
2094 | struct mv_host_priv *hpriv = host->private_data; | ||
2105 | u8 rev_id; | 2095 | u8 rev_id; |
2106 | u32 hp_flags = hpriv->hp_flags; | 2096 | u32 hp_flags = hpriv->hp_flags; |
2107 | 2097 | ||
@@ -2199,8 +2189,8 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, | |||
2199 | 2189 | ||
2200 | /** | 2190 | /** |
2201 | * mv_init_host - Perform some early initialization of the host. | 2191 | * mv_init_host - Perform some early initialization of the host. |
2202 | * @pdev: host PCI device | 2192 | * @host: ATA host to initialize |
2203 | * @probe_ent: early data struct representing the host | 2193 | * @board_idx: controller index |
2204 | * | 2194 | * |
2205 | * If possible, do an early global reset of the host. Then do | 2195 | * If possible, do an early global reset of the host. Then do |
2206 | * our port init and clear/unmask all/relevant host interrupts. | 2196 | * our port init and clear/unmask all/relevant host interrupts. |
@@ -2208,24 +2198,23 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, | |||
2208 | * LOCKING: | 2198 | * LOCKING: |
2209 | * Inherited from caller. | 2199 | * Inherited from caller. |
2210 | */ | 2200 | */ |
2211 | static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, | 2201 | static int mv_init_host(struct ata_host *host, unsigned int board_idx) |
2212 | unsigned int board_idx) | ||
2213 | { | 2202 | { |
2214 | int rc = 0, n_hc, port, hc; | 2203 | int rc = 0, n_hc, port, hc; |
2215 | void __iomem *mmio = probe_ent->iomap[MV_PRIMARY_BAR]; | 2204 | struct pci_dev *pdev = to_pci_dev(host->dev); |
2216 | struct mv_host_priv *hpriv = probe_ent->private_data; | 2205 | void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; |
2206 | struct mv_host_priv *hpriv = host->private_data; | ||
2217 | 2207 | ||
2218 | /* global interrupt mask */ | 2208 | /* global interrupt mask */ |
2219 | writel(0, mmio + HC_MAIN_IRQ_MASK_OFS); | 2209 | writel(0, mmio + HC_MAIN_IRQ_MASK_OFS); |
2220 | 2210 | ||
2221 | rc = mv_chip_id(pdev, hpriv, board_idx); | 2211 | rc = mv_chip_id(host, board_idx); |
2222 | if (rc) | 2212 | if (rc) |
2223 | goto done; | 2213 | goto done; |
2224 | 2214 | ||
2225 | n_hc = mv_get_hc_count(probe_ent->port_flags); | 2215 | n_hc = mv_get_hc_count(host->ports[0]->flags); |
2226 | probe_ent->n_ports = MV_PORTS_PER_HC * n_hc; | ||
2227 | 2216 | ||
2228 | for (port = 0; port < probe_ent->n_ports; port++) | 2217 | for (port = 0; port < host->n_ports; port++) |
2229 | hpriv->ops->read_preamp(hpriv, port, mmio); | 2218 | hpriv->ops->read_preamp(hpriv, port, mmio); |
2230 | 2219 | ||
2231 | rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc); | 2220 | rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc); |
@@ -2236,7 +2225,7 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, | |||
2236 | hpriv->ops->reset_bus(pdev, mmio); | 2225 | hpriv->ops->reset_bus(pdev, mmio); |
2237 | hpriv->ops->enable_leds(hpriv, mmio); | 2226 | hpriv->ops->enable_leds(hpriv, mmio); |
2238 | 2227 | ||
2239 | for (port = 0; port < probe_ent->n_ports; port++) { | 2228 | for (port = 0; port < host->n_ports; port++) { |
2240 | if (IS_60XX(hpriv)) { | 2229 | if (IS_60XX(hpriv)) { |
2241 | void __iomem *port_mmio = mv_port_base(mmio, port); | 2230 | void __iomem *port_mmio = mv_port_base(mmio, port); |
2242 | 2231 | ||
@@ -2249,9 +2238,9 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, | |||
2249 | hpriv->ops->phy_errata(hpriv, mmio, port); | 2238 | hpriv->ops->phy_errata(hpriv, mmio, port); |
2250 | } | 2239 | } |
2251 | 2240 | ||
2252 | for (port = 0; port < probe_ent->n_ports; port++) { | 2241 | for (port = 0; port < host->n_ports; port++) { |
2253 | void __iomem *port_mmio = mv_port_base(mmio, port); | 2242 | void __iomem *port_mmio = mv_port_base(mmio, port); |
2254 | mv_port_init(&probe_ent->port[port], port_mmio); | 2243 | mv_port_init(&host->ports[port]->ioaddr, port_mmio); |
2255 | } | 2244 | } |
2256 | 2245 | ||
2257 | for (hc = 0; hc < n_hc; hc++) { | 2246 | for (hc = 0; hc < n_hc; hc++) { |
@@ -2290,17 +2279,17 @@ done: | |||
2290 | 2279 | ||
2291 | /** | 2280 | /** |
2292 | * mv_print_info - Dump key info to kernel log for perusal. | 2281 | * mv_print_info - Dump key info to kernel log for perusal. |
2293 | * @probe_ent: early data struct representing the host | 2282 | * @host: ATA host to print info about |
2294 | * | 2283 | * |
2295 | * FIXME: complete this. | 2284 | * FIXME: complete this. |
2296 | * | 2285 | * |
2297 | * LOCKING: | 2286 | * LOCKING: |
2298 | * Inherited from caller. | 2287 | * Inherited from caller. |
2299 | */ | 2288 | */ |
2300 | static void mv_print_info(struct ata_probe_ent *probe_ent) | 2289 | static void mv_print_info(struct ata_host *host) |
2301 | { | 2290 | { |
2302 | struct pci_dev *pdev = to_pci_dev(probe_ent->dev); | 2291 | struct pci_dev *pdev = to_pci_dev(host->dev); |
2303 | struct mv_host_priv *hpriv = probe_ent->private_data; | 2292 | struct mv_host_priv *hpriv = host->private_data; |
2304 | u8 rev_id, scc; | 2293 | u8 rev_id, scc; |
2305 | const char *scc_s; | 2294 | const char *scc_s; |
2306 | 2295 | ||
@@ -2319,7 +2308,7 @@ static void mv_print_info(struct ata_probe_ent *probe_ent) | |||
2319 | 2308 | ||
2320 | dev_printk(KERN_INFO, &pdev->dev, | 2309 | dev_printk(KERN_INFO, &pdev->dev, |
2321 | "%u slots %u ports %s mode IRQ via %s\n", | 2310 | "%u slots %u ports %s mode IRQ via %s\n", |
2322 | (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports, | 2311 | (unsigned)MV_MAX_Q_DEPTH, host->n_ports, |
2323 | scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx"); | 2312 | scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx"); |
2324 | } | 2313 | } |
2325 | 2314 | ||
@@ -2334,54 +2323,42 @@ static void mv_print_info(struct ata_probe_ent *probe_ent) | |||
2334 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2323 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2335 | { | 2324 | { |
2336 | static int printed_version = 0; | 2325 | static int printed_version = 0; |
2337 | struct device *dev = &pdev->dev; | ||
2338 | struct ata_probe_ent *probe_ent; | ||
2339 | struct mv_host_priv *hpriv; | ||
2340 | unsigned int board_idx = (unsigned int)ent->driver_data; | 2326 | unsigned int board_idx = (unsigned int)ent->driver_data; |
2341 | int rc; | 2327 | const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; |
2328 | struct ata_host *host; | ||
2329 | struct mv_host_priv *hpriv; | ||
2330 | int n_ports, rc; | ||
2342 | 2331 | ||
2343 | if (!printed_version++) | 2332 | if (!printed_version++) |
2344 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); | 2333 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); |
2345 | 2334 | ||
2335 | /* allocate host */ | ||
2336 | n_ports = mv_get_hc_count(ppi[0]->flags) * MV_PORTS_PER_HC; | ||
2337 | |||
2338 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | ||
2339 | hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); | ||
2340 | if (!host || !hpriv) | ||
2341 | return -ENOMEM; | ||
2342 | host->private_data = hpriv; | ||
2343 | |||
2344 | /* acquire resources */ | ||
2346 | rc = pcim_enable_device(pdev); | 2345 | rc = pcim_enable_device(pdev); |
2347 | if (rc) | 2346 | if (rc) |
2348 | return rc; | 2347 | return rc; |
2349 | pci_set_master(pdev); | ||
2350 | 2348 | ||
2351 | rc = pcim_iomap_regions(pdev, 1 << MV_PRIMARY_BAR, DRV_NAME); | 2349 | rc = pcim_iomap_regions(pdev, 1 << MV_PRIMARY_BAR, DRV_NAME); |
2352 | if (rc == -EBUSY) | 2350 | if (rc == -EBUSY) |
2353 | pcim_pin_device(pdev); | 2351 | pcim_pin_device(pdev); |
2354 | if (rc) | 2352 | if (rc) |
2355 | return rc; | 2353 | return rc; |
2354 | host->iomap = pcim_iomap_table(pdev); | ||
2356 | 2355 | ||
2357 | rc = pci_go_64(pdev); | 2356 | rc = pci_go_64(pdev); |
2358 | if (rc) | 2357 | if (rc) |
2359 | return rc; | 2358 | return rc; |
2360 | 2359 | ||
2361 | probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); | ||
2362 | if (probe_ent == NULL) | ||
2363 | return -ENOMEM; | ||
2364 | |||
2365 | probe_ent->dev = pci_dev_to_dev(pdev); | ||
2366 | INIT_LIST_HEAD(&probe_ent->node); | ||
2367 | |||
2368 | hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); | ||
2369 | if (!hpriv) | ||
2370 | return -ENOMEM; | ||
2371 | |||
2372 | probe_ent->sht = mv_port_info[board_idx].sht; | ||
2373 | probe_ent->port_flags = mv_port_info[board_idx].flags; | ||
2374 | probe_ent->pio_mask = mv_port_info[board_idx].pio_mask; | ||
2375 | probe_ent->udma_mask = mv_port_info[board_idx].udma_mask; | ||
2376 | probe_ent->port_ops = mv_port_info[board_idx].port_ops; | ||
2377 | |||
2378 | probe_ent->irq = pdev->irq; | ||
2379 | probe_ent->irq_flags = IRQF_SHARED; | ||
2380 | probe_ent->iomap = pcim_iomap_table(pdev); | ||
2381 | probe_ent->private_data = hpriv; | ||
2382 | |||
2383 | /* initialize adapter */ | 2360 | /* initialize adapter */ |
2384 | rc = mv_init_host(pdev, probe_ent, board_idx); | 2361 | rc = mv_init_host(host, board_idx); |
2385 | if (rc) | 2362 | if (rc) |
2386 | return rc; | 2363 | return rc; |
2387 | 2364 | ||
@@ -2390,13 +2367,11 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2390 | pci_intx(pdev, 1); | 2367 | pci_intx(pdev, 1); |
2391 | 2368 | ||
2392 | mv_dump_pci_cfg(pdev, 0x68); | 2369 | mv_dump_pci_cfg(pdev, 0x68); |
2393 | mv_print_info(probe_ent); | 2370 | mv_print_info(host); |
2394 | |||
2395 | if (ata_device_add(probe_ent) == 0) | ||
2396 | return -ENODEV; | ||
2397 | 2371 | ||
2398 | devm_kfree(dev, probe_ent); | 2372 | pci_set_master(pdev); |
2399 | return 0; | 2373 | return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, |
2374 | &mv_sht); | ||
2400 | } | 2375 | } |
2401 | 2376 | ||
2402 | static int __init mv_init(void) | 2377 | static int __init mv_init(void) |