aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-sff.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-05-19 16:10:22 -0400
committerJeff Garzik <jgarzik@redhat.com>2010-05-25 19:40:30 -0400
commit1c5afdf7a629d2e77de8dd043b97a33dcd7e6dfa (patch)
tree9f29bfdd32dd1bf497167cd7a8f596c7680059dd /drivers/ata/libata-sff.c
parentc3b2889424c26f3b42962b6f39aabb4f1fd1b576 (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.c138
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)
2315EXPORT_SYMBOL_GPL(ata_pci_sff_init_host); 2315EXPORT_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}
2459EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); 2456EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
2460 2457
2458static 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);
2528out: 2526out:
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}
3197EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); 3195EXPORT_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 */
3212int 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}
3225EXPORT_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 */
3244int 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}
3287EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one);
3288
3199#endif /* CONFIG_PCI */ 3289#endif /* CONFIG_PCI */
3200 3290
3201/** 3291/**