diff options
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r-- | drivers/ata/libata-sff.c | 170 |
1 files changed, 84 insertions, 86 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 6400e8751391..f1c99a3e8b2c 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -66,8 +66,6 @@ const struct ata_port_operations ata_sff_port_ops = { | |||
66 | .sff_irq_clear = ata_sff_irq_clear, | 66 | .sff_irq_clear = ata_sff_irq_clear, |
67 | 67 | ||
68 | .lost_interrupt = ata_sff_lost_interrupt, | 68 | .lost_interrupt = ata_sff_lost_interrupt, |
69 | |||
70 | .port_start = ata_sff_port_start, | ||
71 | }; | 69 | }; |
72 | EXPORT_SYMBOL_GPL(ata_sff_port_ops); | 70 | EXPORT_SYMBOL_GPL(ata_sff_port_ops); |
73 | 71 | ||
@@ -2444,50 +2442,6 @@ void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc) | |||
2444 | EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd); | 2442 | EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd); |
2445 | 2443 | ||
2446 | /** | 2444 | /** |
2447 | * ata_sff_port_start - Set port up for dma. | ||
2448 | * @ap: Port to initialize | ||
2449 | * | ||
2450 | * Called just after data structures for each port are | ||
2451 | * initialized. Allocates space for PRD table if the device | ||
2452 | * is DMA capable SFF. | ||
2453 | * | ||
2454 | * May be used as the port_start() entry in ata_port_operations. | ||
2455 | * | ||
2456 | * LOCKING: | ||
2457 | * Inherited from caller. | ||
2458 | */ | ||
2459 | int ata_sff_port_start(struct ata_port *ap) | ||
2460 | { | ||
2461 | if (ap->ioaddr.bmdma_addr) | ||
2462 | return ata_port_start(ap); | ||
2463 | return 0; | ||
2464 | } | ||
2465 | EXPORT_SYMBOL_GPL(ata_sff_port_start); | ||
2466 | |||
2467 | /** | ||
2468 | * ata_sff_port_start32 - Set port up for dma. | ||
2469 | * @ap: Port to initialize | ||
2470 | * | ||
2471 | * Called just after data structures for each port are | ||
2472 | * initialized. Allocates space for PRD table if the device | ||
2473 | * is DMA capable SFF. | ||
2474 | * | ||
2475 | * May be used as the port_start() entry in ata_port_operations for | ||
2476 | * devices that are capable of 32bit PIO. | ||
2477 | * | ||
2478 | * LOCKING: | ||
2479 | * Inherited from caller. | ||
2480 | */ | ||
2481 | int ata_sff_port_start32(struct ata_port *ap) | ||
2482 | { | ||
2483 | ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; | ||
2484 | if (ap->ioaddr.bmdma_addr) | ||
2485 | return ata_port_start(ap); | ||
2486 | return 0; | ||
2487 | } | ||
2488 | EXPORT_SYMBOL_GPL(ata_sff_port_start32); | ||
2489 | |||
2490 | /** | ||
2491 | * ata_sff_std_ports - initialize ioaddr with standard port offsets. | 2445 | * ata_sff_std_ports - initialize ioaddr with standard port offsets. |
2492 | * @ioaddr: IO address structure to be initialized | 2446 | * @ioaddr: IO address structure to be initialized |
2493 | * | 2447 | * |
@@ -2646,21 +2600,12 @@ int ata_pci_sff_prepare_host(struct pci_dev *pdev, | |||
2646 | goto err_out; | 2600 | goto err_out; |
2647 | 2601 | ||
2648 | /* init DMA related stuff */ | 2602 | /* init DMA related stuff */ |
2649 | rc = ata_pci_bmdma_init(host); | 2603 | ata_pci_bmdma_init(host); |
2650 | if (rc) | ||
2651 | goto err_bmdma; | ||
2652 | 2604 | ||
2653 | devres_remove_group(&pdev->dev, NULL); | 2605 | devres_remove_group(&pdev->dev, NULL); |
2654 | *r_host = host; | 2606 | *r_host = host; |
2655 | return 0; | 2607 | return 0; |
2656 | 2608 | ||
2657 | err_bmdma: | ||
2658 | /* This is necessary because PCI and iomap resources are | ||
2659 | * merged and releasing the top group won't release the | ||
2660 | * acquired resources if some of those have been acquired | ||
2661 | * before entering this function. | ||
2662 | */ | ||
2663 | pcim_iounmap_regions(pdev, 0xf); | ||
2664 | err_out: | 2609 | err_out: |
2665 | devres_release_group(&pdev->dev, NULL); | 2610 | devres_release_group(&pdev->dev, NULL); |
2666 | return rc; | 2611 | return rc; |
@@ -2843,12 +2788,12 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); | |||
2843 | const struct ata_port_operations ata_bmdma_port_ops = { | 2788 | const struct ata_port_operations ata_bmdma_port_ops = { |
2844 | .inherits = &ata_sff_port_ops, | 2789 | .inherits = &ata_sff_port_ops, |
2845 | 2790 | ||
2846 | .mode_filter = ata_bmdma_mode_filter, | ||
2847 | |||
2848 | .bmdma_setup = ata_bmdma_setup, | 2791 | .bmdma_setup = ata_bmdma_setup, |
2849 | .bmdma_start = ata_bmdma_start, | 2792 | .bmdma_start = ata_bmdma_start, |
2850 | .bmdma_stop = ata_bmdma_stop, | 2793 | .bmdma_stop = ata_bmdma_stop, |
2851 | .bmdma_status = ata_bmdma_status, | 2794 | .bmdma_status = ata_bmdma_status, |
2795 | |||
2796 | .port_start = ata_bmdma_port_start, | ||
2852 | }; | 2797 | }; |
2853 | EXPORT_SYMBOL_GPL(ata_bmdma_port_ops); | 2798 | EXPORT_SYMBOL_GPL(ata_bmdma_port_ops); |
2854 | 2799 | ||
@@ -2856,22 +2801,10 @@ const struct ata_port_operations ata_bmdma32_port_ops = { | |||
2856 | .inherits = &ata_bmdma_port_ops, | 2801 | .inherits = &ata_bmdma_port_ops, |
2857 | 2802 | ||
2858 | .sff_data_xfer = ata_sff_data_xfer32, | 2803 | .sff_data_xfer = ata_sff_data_xfer32, |
2859 | .port_start = ata_sff_port_start32, | 2804 | .port_start = ata_bmdma_port_start32, |
2860 | }; | 2805 | }; |
2861 | EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops); | 2806 | EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops); |
2862 | 2807 | ||
2863 | unsigned long ata_bmdma_mode_filter(struct ata_device *adev, | ||
2864 | unsigned long xfer_mask) | ||
2865 | { | ||
2866 | /* Filter out DMA modes if the device has been configured by | ||
2867 | the BIOS as PIO only */ | ||
2868 | |||
2869 | if (adev->link->ap->ioaddr.bmdma_addr == NULL) | ||
2870 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | ||
2871 | return xfer_mask; | ||
2872 | } | ||
2873 | EXPORT_SYMBOL_GPL(ata_bmdma_mode_filter); | ||
2874 | |||
2875 | /** | 2808 | /** |
2876 | * ata_bmdma_setup - Set up PCI IDE BMDMA transaction | 2809 | * ata_bmdma_setup - Set up PCI IDE BMDMA transaction |
2877 | * @qc: Info associated with this ATA transaction. | 2810 | * @qc: Info associated with this ATA transaction. |
@@ -2976,6 +2909,53 @@ u8 ata_bmdma_status(struct ata_port *ap) | |||
2976 | } | 2909 | } |
2977 | EXPORT_SYMBOL_GPL(ata_bmdma_status); | 2910 | EXPORT_SYMBOL_GPL(ata_bmdma_status); |
2978 | 2911 | ||
2912 | |||
2913 | /** | ||
2914 | * ata_bmdma_port_start - Set port up for bmdma. | ||
2915 | * @ap: Port to initialize | ||
2916 | * | ||
2917 | * Called just after data structures for each port are | ||
2918 | * initialized. Allocates space for PRD table. | ||
2919 | * | ||
2920 | * May be used as the port_start() entry in ata_port_operations. | ||
2921 | * | ||
2922 | * LOCKING: | ||
2923 | * Inherited from caller. | ||
2924 | */ | ||
2925 | int ata_bmdma_port_start(struct ata_port *ap) | ||
2926 | { | ||
2927 | if (ap->mwdma_mask || ap->udma_mask) { | ||
2928 | ap->prd = dmam_alloc_coherent(ap->host->dev, ATA_PRD_TBL_SZ, | ||
2929 | &ap->prd_dma, GFP_KERNEL); | ||
2930 | if (!ap->prd) | ||
2931 | return -ENOMEM; | ||
2932 | } | ||
2933 | |||
2934 | return 0; | ||
2935 | } | ||
2936 | EXPORT_SYMBOL_GPL(ata_bmdma_port_start); | ||
2937 | |||
2938 | /** | ||
2939 | * ata_bmdma_port_start32 - Set port up for dma. | ||
2940 | * @ap: Port to initialize | ||
2941 | * | ||
2942 | * Called just after data structures for each port are | ||
2943 | * initialized. Enables 32bit PIO and allocates space for PRD | ||
2944 | * table. | ||
2945 | * | ||
2946 | * May be used as the port_start() entry in ata_port_operations for | ||
2947 | * devices that are capable of 32bit PIO. | ||
2948 | * | ||
2949 | * LOCKING: | ||
2950 | * Inherited from caller. | ||
2951 | */ | ||
2952 | int ata_bmdma_port_start32(struct ata_port *ap) | ||
2953 | { | ||
2954 | ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; | ||
2955 | return ata_bmdma_port_start(ap); | ||
2956 | } | ||
2957 | EXPORT_SYMBOL_GPL(ata_bmdma_port_start32); | ||
2958 | |||
2979 | #ifdef CONFIG_PCI | 2959 | #ifdef CONFIG_PCI |
2980 | 2960 | ||
2981 | /** | 2961 | /** |
@@ -3004,6 +2984,19 @@ int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev) | |||
3004 | } | 2984 | } |
3005 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex); | 2985 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex); |
3006 | 2986 | ||
2987 | static void ata_bmdma_nodma(struct ata_host *host, const char *reason) | ||
2988 | { | ||
2989 | int i; | ||
2990 | |||
2991 | dev_printk(KERN_ERR, host->dev, "BMDMA: %s, falling back to PIO\n", | ||
2992 | reason); | ||
2993 | |||
2994 | for (i = 0; i < 2; i++) { | ||
2995 | host->ports[i]->mwdma_mask = 0; | ||
2996 | host->ports[i]->udma_mask = 0; | ||
2997 | } | ||
2998 | } | ||
2999 | |||
3007 | /** | 3000 | /** |
3008 | * ata_pci_bmdma_init - acquire PCI BMDMA resources and init ATA host | 3001 | * ata_pci_bmdma_init - acquire PCI BMDMA resources and init ATA host |
3009 | * @host: target ATA host | 3002 | * @host: target ATA host |
@@ -3012,33 +3005,40 @@ EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex); | |||
3012 | * | 3005 | * |
3013 | * LOCKING: | 3006 | * LOCKING: |
3014 | * Inherited from calling layer (may sleep). | 3007 | * Inherited from calling layer (may sleep). |
3015 | * | ||
3016 | * RETURNS: | ||
3017 | * 0 on success, -errno otherwise. | ||
3018 | */ | 3008 | */ |
3019 | int ata_pci_bmdma_init(struct ata_host *host) | 3009 | void ata_pci_bmdma_init(struct ata_host *host) |
3020 | { | 3010 | { |
3021 | struct device *gdev = host->dev; | 3011 | struct device *gdev = host->dev; |
3022 | struct pci_dev *pdev = to_pci_dev(gdev); | 3012 | struct pci_dev *pdev = to_pci_dev(gdev); |
3023 | int i, rc; | 3013 | int i, rc; |
3024 | 3014 | ||
3025 | /* No BAR4 allocation: No DMA */ | 3015 | /* No BAR4 allocation: No DMA */ |
3026 | if (pci_resource_start(pdev, 4) == 0) | 3016 | if (pci_resource_start(pdev, 4) == 0) { |
3027 | return 0; | 3017 | ata_bmdma_nodma(host, "BAR4 is zero"); |
3018 | return; | ||
3019 | } | ||
3028 | 3020 | ||
3029 | /* TODO: If we get no DMA mask we should fall back to PIO */ | 3021 | /* |
3022 | * Some controllers require BMDMA region to be initialized | ||
3023 | * even if DMA is not in use to clear IRQ status via | ||
3024 | * ->sff_irq_clear method. Try to initialize bmdma_addr | ||
3025 | * regardless of dma masks. | ||
3026 | */ | ||
3030 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 3027 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); |
3031 | if (rc) | 3028 | if (rc) |
3032 | return rc; | 3029 | ata_bmdma_nodma(host, "failed to set dma mask"); |
3033 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | 3030 | if (!rc) { |
3034 | if (rc) | 3031 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); |
3035 | return rc; | 3032 | if (rc) |
3033 | ata_bmdma_nodma(host, | ||
3034 | "failed to set consistent dma mask"); | ||
3035 | } | ||
3036 | 3036 | ||
3037 | /* request and iomap DMA region */ | 3037 | /* request and iomap DMA region */ |
3038 | rc = pcim_iomap_regions(pdev, 1 << 4, dev_driver_string(gdev)); | 3038 | rc = pcim_iomap_regions(pdev, 1 << 4, dev_driver_string(gdev)); |
3039 | if (rc) { | 3039 | if (rc) { |
3040 | dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n"); | 3040 | ata_bmdma_nodma(host, "failed to request/iomap BAR4"); |
3041 | return -ENOMEM; | 3041 | return; |
3042 | } | 3042 | } |
3043 | host->iomap = pcim_iomap_table(pdev); | 3043 | host->iomap = pcim_iomap_table(pdev); |
3044 | 3044 | ||
@@ -3057,8 +3057,6 @@ int ata_pci_bmdma_init(struct ata_host *host) | |||
3057 | ata_port_desc(ap, "bmdma 0x%llx", | 3057 | ata_port_desc(ap, "bmdma 0x%llx", |
3058 | (unsigned long long)pci_resource_start(pdev, 4) + 8 * i); | 3058 | (unsigned long long)pci_resource_start(pdev, 4) + 8 * i); |
3059 | } | 3059 | } |
3060 | |||
3061 | return 0; | ||
3062 | } | 3060 | } |
3063 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); | 3061 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); |
3064 | 3062 | ||