pci-v4.14-fixes-4
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJZ18l8AAoJEFmIoMA60/r8lrIP/i0fNFaf6gc1vvoizwPhwGU8 0pN6LyDXDCRwaUKXK8BhEgGb2CdtoBl5bU5BJFKdmRFQqDEUmhkGD1a150E89zbm Ty4k93Ym+EpfYra/gUriT+jR21v/TVIFhx9V4PgjJY/4UIulNKDyHnFrOM2HCRC9 yMv6QDmkSaAhTJAQL+2isP0m1jfSwWD1K5b4anP7+93S81uwm68DkLsQLZhvsJY/ HtWXEo5EQFP0Sz0Q17etRZyvh1DmCHSd/6lPYQHatz1t2+7VkvF3tZ3EEw/Mjua2 hmMMLIVdoZnnRH81JzjENvANCecbT5r+FCDurfUxuI34Z8elmeIZ10lt0Du+VmA7 onC50eUow9U55RXXOv+at8UWKAGSVKX0HAgGYe2Og/AoRBo4rnNiP6sf2f+Qpj78 3fh2deLT3xxxF///3P8FZTYPuPclghJKdFyxEyVhwnyArwuJD7hNkJrb2IuOemoF 9uxleJdSYVyHcwiewP7YdCRFNnTFL60WU/fn+8QPzoNj7of9OBDwovjq0iPKHBUn UT8hsG7ZfICj1I+FBS/+tGraEOurXl4ts2hOodZJCPzoLRWnKzGCbAJrjTEVPhLs Vy+RegL2B1zJWXxbg2GHLYEV8I8vV8FXo1x2vgAh2vigZNOX8RfECFZ4aigTwkzo 5j3UGm3xXBfZhn+uHxFe =/3Ag -----END PGP SIGNATURE----- Merge tag 'pci-v4.14-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI fixes from Bjorn Helgaas: "Fix legacy IDE probe issues exposed by recent PCI core IRQ mapping changes (Bartlomiej Zolnierkiewicz, Lorenzo Pieralisi)" * tag 'pci-v4.14-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: ide: fix IRQ assignment for PCI bus order probing ide: pci: free PCI BARs on initialization failure ide: free hwif->portdev on hwif_init() failure
This commit is contained in:
commit
80cf1f8c16
|
@ -1451,6 +1451,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
|
|||
if (hwif_init(hwif) == 0) {
|
||||
printk(KERN_INFO "%s: failed to initialize IDE "
|
||||
"interface\n", hwif->name);
|
||||
device_unregister(hwif->portdev);
|
||||
device_unregister(&hwif->gendev);
|
||||
ide_disable_port(hwif);
|
||||
continue;
|
||||
|
|
|
@ -56,6 +56,7 @@ static int __init ide_scan_pcidev(struct pci_dev *dev)
|
|||
{
|
||||
struct list_head *l;
|
||||
struct pci_driver *d;
|
||||
int ret;
|
||||
|
||||
list_for_each(l, &ide_pci_drivers) {
|
||||
d = list_entry(l, struct pci_driver, node);
|
||||
|
@ -63,10 +64,14 @@ static int __init ide_scan_pcidev(struct pci_dev *dev)
|
|||
const struct pci_device_id *id =
|
||||
pci_match_id(d->id_table, dev);
|
||||
|
||||
if (id != NULL && d->probe(dev, id) >= 0) {
|
||||
dev->driver = d;
|
||||
pci_dev_get(dev);
|
||||
return 1;
|
||||
if (id != NULL) {
|
||||
pci_assign_irq(dev);
|
||||
ret = d->probe(dev, id);
|
||||
if (ret >= 0) {
|
||||
dev->driver = d;
|
||||
pci_dev_get(dev);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
|
|||
/**
|
||||
* ide_pci_enable - do PCI enables
|
||||
* @dev: PCI device
|
||||
* @bars: PCI BARs mask
|
||||
* @d: IDE port info
|
||||
*
|
||||
* Enable the IDE PCI device. We attempt to enable the device in full
|
||||
|
@ -189,9 +190,10 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
|
|||
* Returns zero on success or an error code
|
||||
*/
|
||||
|
||||
static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
|
||||
static int ide_pci_enable(struct pci_dev *dev, int bars,
|
||||
const struct ide_port_info *d)
|
||||
{
|
||||
int ret, bars;
|
||||
int ret;
|
||||
|
||||
if (pci_enable_device(dev)) {
|
||||
ret = pci_enable_device_io(dev);
|
||||
|
@ -216,18 +218,6 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (d->host_flags & IDE_HFLAG_SINGLE)
|
||||
bars = (1 << 2) - 1;
|
||||
else
|
||||
bars = (1 << 4) - 1;
|
||||
|
||||
if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
|
||||
if (d->host_flags & IDE_HFLAG_CS5520)
|
||||
bars |= (1 << 2);
|
||||
else
|
||||
bars |= (1 << 4);
|
||||
}
|
||||
|
||||
ret = pci_request_selected_regions(dev, bars, d->name);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "%s %s: can't reserve resources\n",
|
||||
|
@ -403,6 +393,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
|
|||
/**
|
||||
* ide_setup_pci_controller - set up IDE PCI
|
||||
* @dev: PCI device
|
||||
* @bars: PCI BARs mask
|
||||
* @d: IDE port info
|
||||
* @noisy: verbose flag
|
||||
*
|
||||
|
@ -411,7 +402,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
|
|||
* and enables it if need be
|
||||
*/
|
||||
|
||||
static int ide_setup_pci_controller(struct pci_dev *dev,
|
||||
static int ide_setup_pci_controller(struct pci_dev *dev, int bars,
|
||||
const struct ide_port_info *d, int noisy)
|
||||
{
|
||||
int ret;
|
||||
|
@ -420,7 +411,7 @@ static int ide_setup_pci_controller(struct pci_dev *dev,
|
|||
if (noisy)
|
||||
ide_setup_pci_noise(dev, d);
|
||||
|
||||
ret = ide_pci_enable(dev, d);
|
||||
ret = ide_pci_enable(dev, bars, d);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
|
@ -428,16 +419,20 @@ static int ide_setup_pci_controller(struct pci_dev *dev,
|
|||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s %s: error accessing PCI regs\n",
|
||||
d->name, pci_name(dev));
|
||||
goto out;
|
||||
goto out_free_bars;
|
||||
}
|
||||
if (!(pcicmd & PCI_COMMAND_IO)) { /* is device disabled? */
|
||||
ret = ide_pci_configure(dev, d);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
goto out_free_bars;
|
||||
printk(KERN_INFO "%s %s: device enabled (Linux)\n",
|
||||
d->name, pci_name(dev));
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
||||
out_free_bars:
|
||||
pci_release_selected_regions(dev, bars);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -540,13 +535,28 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
|
|||
{
|
||||
struct pci_dev *pdev[] = { dev1, dev2 };
|
||||
struct ide_host *host;
|
||||
int ret, i, n_ports = dev2 ? 4 : 2;
|
||||
int ret, i, n_ports = dev2 ? 4 : 2, bars;
|
||||
struct ide_hw hw[4], *hws[] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
if (d->host_flags & IDE_HFLAG_SINGLE)
|
||||
bars = (1 << 2) - 1;
|
||||
else
|
||||
bars = (1 << 4) - 1;
|
||||
|
||||
if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
|
||||
if (d->host_flags & IDE_HFLAG_CS5520)
|
||||
bars |= (1 << 2);
|
||||
else
|
||||
bars |= (1 << 4);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_ports / 2; i++) {
|
||||
ret = ide_setup_pci_controller(pdev[i], d, !i);
|
||||
if (ret < 0)
|
||||
ret = ide_setup_pci_controller(pdev[i], bars, d, !i);
|
||||
if (ret < 0) {
|
||||
if (i == 1)
|
||||
pci_release_selected_regions(pdev[0], bars);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]);
|
||||
}
|
||||
|
@ -554,7 +564,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
|
|||
host = ide_host_alloc(d, hws, n_ports);
|
||||
if (host == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
goto out_free_bars;
|
||||
}
|
||||
|
||||
host->dev[0] = &dev1->dev;
|
||||
|
@ -576,7 +586,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
|
|||
* do_ide_setup_pci_device() on the first device!
|
||||
*/
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
goto out_free_bars;
|
||||
|
||||
/* fixup IRQ */
|
||||
if (ide_pci_is_in_compatibility_mode(pdev[i])) {
|
||||
|
@ -589,6 +599,13 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
|
|||
ret = ide_host_register(host, d, hws);
|
||||
if (ret)
|
||||
ide_host_free(host);
|
||||
else
|
||||
goto out;
|
||||
|
||||
out_free_bars:
|
||||
i = n_ports / 2;
|
||||
while (i--)
|
||||
pci_release_selected_regions(pdev[i], bars);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue