diff options
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r-- | drivers/ata/libata-sff.c | 122 |
1 files changed, 54 insertions, 68 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index c24127dd6ef2..4cadfa28f940 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
36 | #include <linux/gfp.h> | 36 | #include <linux/gfp.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/module.h> | ||
38 | #include <linux/libata.h> | 39 | #include <linux/libata.h> |
39 | #include <linux/highmem.h> | 40 | #include <linux/highmem.h> |
40 | 41 | ||
@@ -569,7 +570,7 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf, | |||
569 | 570 | ||
570 | /* Transfer trailing byte, if any. */ | 571 | /* Transfer trailing byte, if any. */ |
571 | if (unlikely(buflen & 0x01)) { | 572 | if (unlikely(buflen & 0x01)) { |
572 | unsigned char pad[2]; | 573 | unsigned char pad[2] = { }; |
573 | 574 | ||
574 | /* Point buf to the tail of buffer */ | 575 | /* Point buf to the tail of buffer */ |
575 | buf += buflen - 1; | 576 | buf += buflen - 1; |
@@ -628,7 +629,7 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf, | |||
628 | 629 | ||
629 | /* Transfer trailing bytes, if any */ | 630 | /* Transfer trailing bytes, if any */ |
630 | if (unlikely(slop)) { | 631 | if (unlikely(slop)) { |
631 | unsigned char pad[4]; | 632 | unsigned char pad[4] = { }; |
632 | 633 | ||
633 | /* Point buf to the tail of buffer */ | 634 | /* Point buf to the tail of buffer */ |
634 | buf += buflen - slop; | 635 | buf += buflen - slop; |
@@ -678,7 +679,7 @@ unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, unsigned char *buf, | |||
678 | unsigned int consumed; | 679 | unsigned int consumed; |
679 | 680 | ||
680 | local_irq_save(flags); | 681 | local_irq_save(flags); |
681 | consumed = ata_sff_data_xfer(dev, buf, buflen, rw); | 682 | consumed = ata_sff_data_xfer32(dev, buf, buflen, rw); |
682 | local_irq_restore(flags); | 683 | local_irq_restore(flags); |
683 | 684 | ||
684 | return consumed; | 685 | return consumed; |
@@ -2507,31 +2508,10 @@ static const struct ata_port_info *ata_sff_find_valid_pi( | |||
2507 | return NULL; | 2508 | return NULL; |
2508 | } | 2509 | } |
2509 | 2510 | ||
2510 | /** | 2511 | static int ata_pci_init_one(struct pci_dev *pdev, |
2511 | * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller | 2512 | const struct ata_port_info * const *ppi, |
2512 | * @pdev: Controller to be initialized | 2513 | struct scsi_host_template *sht, void *host_priv, |
2513 | * @ppi: array of port_info, must be enough for two ports | 2514 | int hflags, bool bmdma) |
2514 | * @sht: scsi_host_template to use when registering the host | ||
2515 | * @host_priv: host private_data | ||
2516 | * @hflag: host flags | ||
2517 | * | ||
2518 | * This is a helper function which can be called from a driver's | ||
2519 | * xxx_init_one() probe function if the hardware uses traditional | ||
2520 | * IDE taskfile registers and is PIO only. | ||
2521 | * | ||
2522 | * ASSUMPTION: | ||
2523 | * Nobody makes a single channel controller that appears solely as | ||
2524 | * the secondary legacy port on PCI. | ||
2525 | * | ||
2526 | * LOCKING: | ||
2527 | * Inherited from PCI layer (may sleep). | ||
2528 | * | ||
2529 | * RETURNS: | ||
2530 | * Zero on success, negative on errno-based value on error. | ||
2531 | */ | ||
2532 | int ata_pci_sff_init_one(struct pci_dev *pdev, | ||
2533 | const struct ata_port_info * const *ppi, | ||
2534 | struct scsi_host_template *sht, void *host_priv, int hflag) | ||
2535 | { | 2515 | { |
2536 | struct device *dev = &pdev->dev; | 2516 | struct device *dev = &pdev->dev; |
2537 | const struct ata_port_info *pi; | 2517 | const struct ata_port_info *pi; |
@@ -2553,14 +2533,26 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, | |||
2553 | if (rc) | 2533 | if (rc) |
2554 | goto out; | 2534 | goto out; |
2555 | 2535 | ||
2556 | /* prepare and activate SFF host */ | 2536 | #ifdef CONFIG_ATA_BMDMA |
2557 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | 2537 | if (bmdma) |
2538 | /* prepare and activate BMDMA host */ | ||
2539 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); | ||
2540 | else | ||
2541 | #endif | ||
2542 | /* prepare and activate SFF host */ | ||
2543 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | ||
2558 | if (rc) | 2544 | if (rc) |
2559 | goto out; | 2545 | goto out; |
2560 | host->private_data = host_priv; | 2546 | host->private_data = host_priv; |
2561 | host->flags |= hflag; | 2547 | host->flags |= hflags; |
2562 | 2548 | ||
2563 | rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); | 2549 | #ifdef CONFIG_ATA_BMDMA |
2550 | if (bmdma) { | ||
2551 | pci_set_master(pdev); | ||
2552 | rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); | ||
2553 | } else | ||
2554 | #endif | ||
2555 | rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); | ||
2564 | out: | 2556 | out: |
2565 | if (rc == 0) | 2557 | if (rc == 0) |
2566 | devres_remove_group(&pdev->dev, NULL); | 2558 | devres_remove_group(&pdev->dev, NULL); |
@@ -2569,6 +2561,35 @@ out: | |||
2569 | 2561 | ||
2570 | return rc; | 2562 | return rc; |
2571 | } | 2563 | } |
2564 | |||
2565 | /** | ||
2566 | * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller | ||
2567 | * @pdev: Controller to be initialized | ||
2568 | * @ppi: array of port_info, must be enough for two ports | ||
2569 | * @sht: scsi_host_template to use when registering the host | ||
2570 | * @host_priv: host private_data | ||
2571 | * @hflag: host flags | ||
2572 | * | ||
2573 | * This is a helper function which can be called from a driver's | ||
2574 | * xxx_init_one() probe function if the hardware uses traditional | ||
2575 | * IDE taskfile registers and is PIO only. | ||
2576 | * | ||
2577 | * ASSUMPTION: | ||
2578 | * Nobody makes a single channel controller that appears solely as | ||
2579 | * the secondary legacy port on PCI. | ||
2580 | * | ||
2581 | * LOCKING: | ||
2582 | * Inherited from PCI layer (may sleep). | ||
2583 | * | ||
2584 | * RETURNS: | ||
2585 | * Zero on success, negative on errno-based value on error. | ||
2586 | */ | ||
2587 | int ata_pci_sff_init_one(struct pci_dev *pdev, | ||
2588 | const struct ata_port_info * const *ppi, | ||
2589 | struct scsi_host_template *sht, void *host_priv, int hflag) | ||
2590 | { | ||
2591 | return ata_pci_init_one(pdev, ppi, sht, host_priv, hflag, 0); | ||
2592 | } | ||
2572 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); | 2593 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); |
2573 | 2594 | ||
2574 | #endif /* CONFIG_PCI */ | 2595 | #endif /* CONFIG_PCI */ |
@@ -3286,42 +3307,7 @@ int ata_pci_bmdma_init_one(struct pci_dev *pdev, | |||
3286 | struct scsi_host_template *sht, void *host_priv, | 3307 | struct scsi_host_template *sht, void *host_priv, |
3287 | int hflags) | 3308 | int hflags) |
3288 | { | 3309 | { |
3289 | struct device *dev = &pdev->dev; | 3310 | return ata_pci_init_one(pdev, ppi, sht, host_priv, hflags, 1); |
3290 | const struct ata_port_info *pi; | ||
3291 | struct ata_host *host = NULL; | ||
3292 | int rc; | ||
3293 | |||
3294 | DPRINTK("ENTER\n"); | ||
3295 | |||
3296 | pi = ata_sff_find_valid_pi(ppi); | ||
3297 | if (!pi) { | ||
3298 | dev_err(&pdev->dev, "no valid port_info specified\n"); | ||
3299 | return -EINVAL; | ||
3300 | } | ||
3301 | |||
3302 | if (!devres_open_group(dev, NULL, GFP_KERNEL)) | ||
3303 | return -ENOMEM; | ||
3304 | |||
3305 | rc = pcim_enable_device(pdev); | ||
3306 | if (rc) | ||
3307 | goto out; | ||
3308 | |||
3309 | /* prepare and activate BMDMA host */ | ||
3310 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); | ||
3311 | if (rc) | ||
3312 | goto out; | ||
3313 | host->private_data = host_priv; | ||
3314 | host->flags |= hflags; | ||
3315 | |||
3316 | pci_set_master(pdev); | ||
3317 | rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); | ||
3318 | out: | ||
3319 | if (rc == 0) | ||
3320 | devres_remove_group(&pdev->dev, NULL); | ||
3321 | else | ||
3322 | devres_release_group(&pdev->dev, NULL); | ||
3323 | |||
3324 | return rc; | ||
3325 | } | 3311 | } |
3326 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one); | 3312 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one); |
3327 | 3313 | ||