diff options
author | Tejun Heo <tj@kernel.org> | 2010-05-19 16:10:22 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-05-25 19:40:30 -0400 |
commit | 1c5afdf7a629d2e77de8dd043b97a33dcd7e6dfa (patch) | |
tree | 9f29bfdd32dd1bf497167cd7a8f596c7680059dd /drivers/ata/libata-sff.c | |
parent | c3b2889424c26f3b42962b6f39aabb4f1fd1b576 (diff) |
libata-sff: separate out BMDMA init
Separate out ata_pci_bmdma_prepare_host() and ata_pci_bmdma_init_one()
from their SFF counterparts. SFF ones no longer try to initialize
BMDMA or set PCI master.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r-- | drivers/ata/libata-sff.c | 138 |
1 files changed, 114 insertions, 24 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index bef7571a1d42..c29f1468e164 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -2315,13 +2315,13 @@ int ata_pci_sff_init_host(struct ata_host *host) | |||
2315 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_host); | 2315 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_host); |
2316 | 2316 | ||
2317 | /** | 2317 | /** |
2318 | * ata_pci_sff_prepare_host - helper to prepare native PCI ATA host | 2318 | * ata_pci_sff_prepare_host - helper to prepare PCI PIO-only SFF ATA host |
2319 | * @pdev: target PCI device | 2319 | * @pdev: target PCI device |
2320 | * @ppi: array of port_info, must be enough for two ports | 2320 | * @ppi: array of port_info, must be enough for two ports |
2321 | * @r_host: out argument for the initialized ATA host | 2321 | * @r_host: out argument for the initialized ATA host |
2322 | * | 2322 | * |
2323 | * Helper to allocate ATA host for @pdev, acquire all native PCI | 2323 | * Helper to allocate PIO-only SFF ATA host for @pdev, acquire |
2324 | * resources and initialize it accordingly in one go. | 2324 | * all PCI resources and initialize it accordingly in one go. |
2325 | * | 2325 | * |
2326 | * LOCKING: | 2326 | * LOCKING: |
2327 | * Inherited from calling layer (may sleep). | 2327 | * Inherited from calling layer (may sleep). |
@@ -2351,9 +2351,6 @@ int ata_pci_sff_prepare_host(struct pci_dev *pdev, | |||
2351 | if (rc) | 2351 | if (rc) |
2352 | goto err_out; | 2352 | goto err_out; |
2353 | 2353 | ||
2354 | /* init DMA related stuff */ | ||
2355 | ata_pci_bmdma_init(host); | ||
2356 | |||
2357 | devres_remove_group(&pdev->dev, NULL); | 2354 | devres_remove_group(&pdev->dev, NULL); |
2358 | *r_host = host; | 2355 | *r_host = host; |
2359 | return 0; | 2356 | return 0; |
@@ -2458,8 +2455,21 @@ out: | |||
2458 | } | 2455 | } |
2459 | EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); | 2456 | EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); |
2460 | 2457 | ||
2458 | static const struct ata_port_info *ata_sff_find_valid_pi( | ||
2459 | const struct ata_port_info * const *ppi) | ||
2460 | { | ||
2461 | int i; | ||
2462 | |||
2463 | /* look up the first valid port_info */ | ||
2464 | for (i = 0; i < 2 && ppi[i]; i++) | ||
2465 | if (ppi[i]->port_ops != &ata_dummy_port_ops) | ||
2466 | return ppi[i]; | ||
2467 | |||
2468 | return NULL; | ||
2469 | } | ||
2470 | |||
2461 | /** | 2471 | /** |
2462 | * ata_pci_sff_init_one - Initialize/register PCI IDE host controller | 2472 | * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller |
2463 | * @pdev: Controller to be initialized | 2473 | * @pdev: Controller to be initialized |
2464 | * @ppi: array of port_info, must be enough for two ports | 2474 | * @ppi: array of port_info, must be enough for two ports |
2465 | * @sht: scsi_host_template to use when registering the host | 2475 | * @sht: scsi_host_template to use when registering the host |
@@ -2468,11 +2478,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); | |||
2468 | * | 2478 | * |
2469 | * This is a helper function which can be called from a driver's | 2479 | * This is a helper function which can be called from a driver's |
2470 | * xxx_init_one() probe function if the hardware uses traditional | 2480 | * xxx_init_one() probe function if the hardware uses traditional |
2471 | * IDE taskfile registers. | 2481 | * IDE taskfile registers and is PIO only. |
2472 | * | ||
2473 | * This function calls pci_enable_device(), reserves its register | ||
2474 | * regions, sets the dma mask, enables bus master mode, and calls | ||
2475 | * ata_device_add() | ||
2476 | * | 2482 | * |
2477 | * ASSUMPTION: | 2483 | * ASSUMPTION: |
2478 | * Nobody makes a single channel controller that appears solely as | 2484 | * Nobody makes a single channel controller that appears solely as |
@@ -2489,20 +2495,13 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, | |||
2489 | struct scsi_host_template *sht, void *host_priv, int hflag) | 2495 | struct scsi_host_template *sht, void *host_priv, int hflag) |
2490 | { | 2496 | { |
2491 | struct device *dev = &pdev->dev; | 2497 | struct device *dev = &pdev->dev; |
2492 | const struct ata_port_info *pi = NULL; | 2498 | const struct ata_port_info *pi; |
2493 | struct ata_host *host = NULL; | 2499 | struct ata_host *host = NULL; |
2494 | int i, rc; | 2500 | int rc; |
2495 | 2501 | ||
2496 | DPRINTK("ENTER\n"); | 2502 | DPRINTK("ENTER\n"); |
2497 | 2503 | ||
2498 | /* look up the first valid port_info */ | 2504 | pi = ata_sff_find_valid_pi(ppi); |
2499 | for (i = 0; i < 2 && ppi[i]; i++) { | ||
2500 | if (ppi[i]->port_ops != &ata_dummy_port_ops) { | ||
2501 | pi = ppi[i]; | ||
2502 | break; | ||
2503 | } | ||
2504 | } | ||
2505 | |||
2506 | if (!pi) { | 2505 | if (!pi) { |
2507 | dev_printk(KERN_ERR, &pdev->dev, | 2506 | dev_printk(KERN_ERR, &pdev->dev, |
2508 | "no valid port_info specified\n"); | 2507 | "no valid port_info specified\n"); |
@@ -2523,8 +2522,7 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, | |||
2523 | host->private_data = host_priv; | 2522 | host->private_data = host_priv; |
2524 | host->flags |= hflag; | 2523 | host->flags |= hflag; |
2525 | 2524 | ||
2526 | pci_set_master(pdev); | 2525 | rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); |
2527 | rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); | ||
2528 | out: | 2526 | out: |
2529 | if (rc == 0) | 2527 | if (rc == 0) |
2530 | devres_remove_group(&pdev->dev, NULL); | 2528 | devres_remove_group(&pdev->dev, NULL); |
@@ -3196,6 +3194,98 @@ void ata_pci_bmdma_init(struct ata_host *host) | |||
3196 | } | 3194 | } |
3197 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); | 3195 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); |
3198 | 3196 | ||
3197 | /** | ||
3198 | * ata_pci_bmdma_prepare_host - helper to prepare PCI BMDMA ATA host | ||
3199 | * @pdev: target PCI device | ||
3200 | * @ppi: array of port_info, must be enough for two ports | ||
3201 | * @r_host: out argument for the initialized ATA host | ||
3202 | * | ||
3203 | * Helper to allocate BMDMA ATA host for @pdev, acquire all PCI | ||
3204 | * resources and initialize it accordingly in one go. | ||
3205 | * | ||
3206 | * LOCKING: | ||
3207 | * Inherited from calling layer (may sleep). | ||
3208 | * | ||
3209 | * RETURNS: | ||
3210 | * 0 on success, -errno otherwise. | ||
3211 | */ | ||
3212 | int ata_pci_bmdma_prepare_host(struct pci_dev *pdev, | ||
3213 | const struct ata_port_info * const * ppi, | ||
3214 | struct ata_host **r_host) | ||
3215 | { | ||
3216 | int rc; | ||
3217 | |||
3218 | rc = ata_pci_sff_prepare_host(pdev, ppi, r_host); | ||
3219 | if (rc) | ||
3220 | return rc; | ||
3221 | |||
3222 | ata_pci_bmdma_init(*r_host); | ||
3223 | return 0; | ||
3224 | } | ||
3225 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host); | ||
3226 | |||
3227 | /** | ||
3228 | * ata_pci_bmdma_init_one - Initialize/register BMDMA PCI IDE controller | ||
3229 | * @pdev: Controller to be initialized | ||
3230 | * @ppi: array of port_info, must be enough for two ports | ||
3231 | * @sht: scsi_host_template to use when registering the host | ||
3232 | * @host_priv: host private_data | ||
3233 | * @hflags: host flags | ||
3234 | * | ||
3235 | * This function is similar to ata_pci_sff_init_one() but also | ||
3236 | * takes care of BMDMA initialization. | ||
3237 | * | ||
3238 | * LOCKING: | ||
3239 | * Inherited from PCI layer (may sleep). | ||
3240 | * | ||
3241 | * RETURNS: | ||
3242 | * Zero on success, negative on errno-based value on error. | ||
3243 | */ | ||
3244 | int ata_pci_bmdma_init_one(struct pci_dev *pdev, | ||
3245 | const struct ata_port_info * const * ppi, | ||
3246 | struct scsi_host_template *sht, void *host_priv, | ||
3247 | int hflags) | ||
3248 | { | ||
3249 | struct device *dev = &pdev->dev; | ||
3250 | const struct ata_port_info *pi; | ||
3251 | struct ata_host *host = NULL; | ||
3252 | int rc; | ||
3253 | |||
3254 | DPRINTK("ENTER\n"); | ||
3255 | |||
3256 | pi = ata_sff_find_valid_pi(ppi); | ||
3257 | if (!pi) { | ||
3258 | dev_printk(KERN_ERR, &pdev->dev, | ||
3259 | "no valid port_info specified\n"); | ||
3260 | return -EINVAL; | ||
3261 | } | ||
3262 | |||
3263 | if (!devres_open_group(dev, NULL, GFP_KERNEL)) | ||
3264 | return -ENOMEM; | ||
3265 | |||
3266 | rc = pcim_enable_device(pdev); | ||
3267 | if (rc) | ||
3268 | goto out; | ||
3269 | |||
3270 | /* prepare and activate BMDMA host */ | ||
3271 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); | ||
3272 | if (rc) | ||
3273 | goto out; | ||
3274 | host->private_data = host_priv; | ||
3275 | host->flags |= hflags; | ||
3276 | |||
3277 | pci_set_master(pdev); | ||
3278 | rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); | ||
3279 | out: | ||
3280 | if (rc == 0) | ||
3281 | devres_remove_group(&pdev->dev, NULL); | ||
3282 | else | ||
3283 | devres_release_group(&pdev->dev, NULL); | ||
3284 | |||
3285 | return rc; | ||
3286 | } | ||
3287 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one); | ||
3288 | |||
3199 | #endif /* CONFIG_PCI */ | 3289 | #endif /* CONFIG_PCI */ |
3200 | 3290 | ||
3201 | /** | 3291 | /** |