diff options
Diffstat (limited to 'drivers/ide/setup-pci.c')
| -rw-r--r-- | drivers/ide/setup-pci.c | 85 |
1 files changed, 23 insertions, 62 deletions
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 7a3a12d6e638..ab3db61d2ba0 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | 2 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> |
| 3 | * Copyright (C) 1995-1998 Mark Lord | 3 | * Copyright (C) 1995-1998 Mark Lord |
| 4 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz | 4 | * Copyright (C) 2007-2009 Bartlomiej Zolnierkiewicz |
| 5 | * | 5 | * |
| 6 | * May be copied or modified under the terms of the GNU General Public License | 6 | * May be copied or modified under the terms of the GNU General Public License |
| 7 | */ | 7 | */ |
| @@ -301,11 +301,11 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info * | |||
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | /** | 303 | /** |
| 304 | * ide_hw_configure - configure a hw_regs_t instance | 304 | * ide_hw_configure - configure a struct ide_hw instance |
| 305 | * @dev: PCI device holding interface | 305 | * @dev: PCI device holding interface |
| 306 | * @d: IDE port info | 306 | * @d: IDE port info |
| 307 | * @port: port number | 307 | * @port: port number |
| 308 | * @hw: hw_regs_t instance corresponding to this port | 308 | * @hw: struct ide_hw instance corresponding to this port |
| 309 | * | 309 | * |
| 310 | * Perform the initial set up for the hardware interface structure. This | 310 | * Perform the initial set up for the hardware interface structure. This |
| 311 | * is done per interface port rather than per PCI device. There may be | 311 | * is done per interface port rather than per PCI device. There may be |
| @@ -315,7 +315,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info * | |||
| 315 | */ | 315 | */ |
| 316 | 316 | ||
| 317 | static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d, | 317 | static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d, |
| 318 | unsigned int port, hw_regs_t *hw) | 318 | unsigned int port, struct ide_hw *hw) |
| 319 | { | 319 | { |
| 320 | unsigned long ctl = 0, base = 0; | 320 | unsigned long ctl = 0, base = 0; |
| 321 | 321 | ||
| @@ -344,7 +344,6 @@ static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d, | |||
| 344 | 344 | ||
| 345 | memset(hw, 0, sizeof(*hw)); | 345 | memset(hw, 0, sizeof(*hw)); |
| 346 | hw->dev = &dev->dev; | 346 | hw->dev = &dev->dev; |
| 347 | hw->chipset = d->chipset ? d->chipset : ide_pci; | ||
| 348 | ide_std_init_ports(hw, base, ctl | 2); | 347 | ide_std_init_ports(hw, base, ctl | 2); |
| 349 | 348 | ||
| 350 | return 0; | 349 | return 0; |
| @@ -446,8 +445,8 @@ out: | |||
| 446 | * ide_pci_setup_ports - configure ports/devices on PCI IDE | 445 | * ide_pci_setup_ports - configure ports/devices on PCI IDE |
| 447 | * @dev: PCI device | 446 | * @dev: PCI device |
| 448 | * @d: IDE port info | 447 | * @d: IDE port info |
| 449 | * @hw: hw_regs_t instances corresponding to this PCI IDE device | 448 | * @hw: struct ide_hw instances corresponding to this PCI IDE device |
| 450 | * @hws: hw_regs_t pointers table to update | 449 | * @hws: struct ide_hw pointers table to update |
| 451 | * | 450 | * |
| 452 | * Scan the interfaces attached to this device and do any | 451 | * Scan the interfaces attached to this device and do any |
| 453 | * necessary per port setup. Attach the devices and ask the | 452 | * necessary per port setup. Attach the devices and ask the |
| @@ -459,7 +458,7 @@ out: | |||
| 459 | */ | 458 | */ |
| 460 | 459 | ||
| 461 | void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, | 460 | void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, |
| 462 | hw_regs_t *hw, hw_regs_t **hws) | 461 | struct ide_hw *hw, struct ide_hw **hws) |
| 463 | { | 462 | { |
| 464 | int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port; | 463 | int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port; |
| 465 | u8 tmp; | 464 | u8 tmp; |
| @@ -535,61 +534,15 @@ out: | |||
| 535 | return ret; | 534 | return ret; |
| 536 | } | 535 | } |
| 537 | 536 | ||
| 538 | int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d, | ||
| 539 | void *priv) | ||
| 540 | { | ||
| 541 | struct ide_host *host; | ||
| 542 | hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL }; | ||
| 543 | int ret; | ||
| 544 | |||
| 545 | ret = ide_setup_pci_controller(dev, d, 1); | ||
| 546 | if (ret < 0) | ||
| 547 | goto out; | ||
| 548 | |||
| 549 | ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); | ||
| 550 | |||
| 551 | host = ide_host_alloc(d, hws); | ||
| 552 | if (host == NULL) { | ||
| 553 | ret = -ENOMEM; | ||
| 554 | goto out; | ||
| 555 | } | ||
| 556 | |||
| 557 | host->dev[0] = &dev->dev; | ||
| 558 | |||
| 559 | host->host_priv = priv; | ||
| 560 | |||
| 561 | host->irq_flags = IRQF_SHARED; | ||
| 562 | |||
| 563 | pci_set_drvdata(dev, host); | ||
| 564 | |||
| 565 | ret = do_ide_setup_pci_device(dev, d, 1); | ||
| 566 | if (ret < 0) | ||
| 567 | goto out; | ||
| 568 | |||
| 569 | /* fixup IRQ */ | ||
| 570 | if (ide_pci_is_in_compatibility_mode(dev)) { | ||
| 571 | hw[0].irq = pci_get_legacy_ide_irq(dev, 0); | ||
| 572 | hw[1].irq = pci_get_legacy_ide_irq(dev, 1); | ||
| 573 | } else | ||
| 574 | hw[1].irq = hw[0].irq = ret; | ||
| 575 | |||
| 576 | ret = ide_host_register(host, d, hws); | ||
| 577 | if (ret) | ||
| 578 | ide_host_free(host); | ||
| 579 | out: | ||
| 580 | return ret; | ||
| 581 | } | ||
| 582 | EXPORT_SYMBOL_GPL(ide_pci_init_one); | ||
| 583 | |||
| 584 | int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, | 537 | int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, |
| 585 | const struct ide_port_info *d, void *priv) | 538 | const struct ide_port_info *d, void *priv) |
| 586 | { | 539 | { |
| 587 | struct pci_dev *pdev[] = { dev1, dev2 }; | 540 | struct pci_dev *pdev[] = { dev1, dev2 }; |
| 588 | struct ide_host *host; | 541 | struct ide_host *host; |
| 589 | int ret, i; | 542 | int ret, i, n_ports = dev2 ? 4 : 2; |
| 590 | hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL }; | 543 | struct ide_hw hw[4], *hws[] = { NULL, NULL, NULL, NULL }; |
| 591 | 544 | ||
| 592 | for (i = 0; i < 2; i++) { | 545 | for (i = 0; i < n_ports / 2; i++) { |
| 593 | ret = ide_setup_pci_controller(pdev[i], d, !i); | 546 | ret = ide_setup_pci_controller(pdev[i], d, !i); |
| 594 | if (ret < 0) | 547 | if (ret < 0) |
| 595 | goto out; | 548 | goto out; |
| @@ -597,23 +550,24 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, | |||
| 597 | ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]); | 550 | ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]); |
| 598 | } | 551 | } |
| 599 | 552 | ||
| 600 | host = ide_host_alloc(d, hws); | 553 | host = ide_host_alloc(d, hws, n_ports); |
| 601 | if (host == NULL) { | 554 | if (host == NULL) { |
| 602 | ret = -ENOMEM; | 555 | ret = -ENOMEM; |
| 603 | goto out; | 556 | goto out; |
| 604 | } | 557 | } |
| 605 | 558 | ||
| 606 | host->dev[0] = &dev1->dev; | 559 | host->dev[0] = &dev1->dev; |
| 607 | host->dev[1] = &dev2->dev; | 560 | if (dev2) |
| 561 | host->dev[1] = &dev2->dev; | ||
| 608 | 562 | ||
| 609 | host->host_priv = priv; | 563 | host->host_priv = priv; |
| 610 | |||
| 611 | host->irq_flags = IRQF_SHARED; | 564 | host->irq_flags = IRQF_SHARED; |
| 612 | 565 | ||
| 613 | pci_set_drvdata(pdev[0], host); | 566 | pci_set_drvdata(pdev[0], host); |
| 614 | pci_set_drvdata(pdev[1], host); | 567 | if (dev2) |
| 568 | pci_set_drvdata(pdev[1], host); | ||
| 615 | 569 | ||
| 616 | for (i = 0; i < 2; i++) { | 570 | for (i = 0; i < n_ports / 2; i++) { |
| 617 | ret = do_ide_setup_pci_device(pdev[i], d, !i); | 571 | ret = do_ide_setup_pci_device(pdev[i], d, !i); |
| 618 | 572 | ||
| 619 | /* | 573 | /* |
| @@ -639,6 +593,13 @@ out: | |||
| 639 | } | 593 | } |
| 640 | EXPORT_SYMBOL_GPL(ide_pci_init_two); | 594 | EXPORT_SYMBOL_GPL(ide_pci_init_two); |
| 641 | 595 | ||
| 596 | int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d, | ||
| 597 | void *priv) | ||
| 598 | { | ||
| 599 | return ide_pci_init_two(dev, NULL, d, priv); | ||
| 600 | } | ||
| 601 | EXPORT_SYMBOL_GPL(ide_pci_init_one); | ||
| 602 | |||
| 642 | void ide_pci_remove(struct pci_dev *dev) | 603 | void ide_pci_remove(struct pci_dev *dev) |
| 643 | { | 604 | { |
| 644 | struct ide_host *host = pci_get_drvdata(dev); | 605 | struct ide_host *host = pci_get_drvdata(dev); |
