diff options
author | James Bottomley <jejb@mulgrave.(none)> | 2005-08-13 10:42:45 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-08-13 10:42:45 -0400 |
commit | 3a4f5c60dbe1978580ea03c1aff353d1e63d1638 (patch) | |
tree | 90a45510cbe9e03b02f44f4b135803110a5dfdb7 /drivers | |
parent | 0336ee5aed1f9a5a6a04e3deabd7797dc193ccd3 (diff) |
[SCSI] aic7xxx: lost multifunction flags handling
From: Christoph Hellwig <hch@lst.de>
Multi-function cards need to inherit the PCI flags from the master PCI
device.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index 9d318ce2c993..0d44a6907dd2 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | |||
@@ -149,6 +149,27 @@ ahc_linux_pci_dev_remove(struct pci_dev *pdev) | |||
149 | ahc_free(ahc); | 149 | ahc_free(ahc); |
150 | } | 150 | } |
151 | 151 | ||
152 | static void | ||
153 | ahc_linux_pci_inherit_flags(struct ahc_softc *ahc) | ||
154 | { | ||
155 | struct pci_dev *pdev = ahc->dev_softc, *master_pdev; | ||
156 | unsigned int master_devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0); | ||
157 | |||
158 | master_pdev = pci_get_slot(pdev->bus, master_devfn); | ||
159 | if (master_pdev) { | ||
160 | struct ahc_softc *master = pci_get_drvdata(master_pdev); | ||
161 | if (master) { | ||
162 | ahc->flags &= ~AHC_BIOS_ENABLED; | ||
163 | ahc->flags |= master->flags & AHC_BIOS_ENABLED; | ||
164 | |||
165 | ahc->flags &= ~AHC_PRIMARY_CHANNEL; | ||
166 | ahc->flags |= master->flags & AHC_PRIMARY_CHANNEL; | ||
167 | } else | ||
168 | printk(KERN_ERR "aic7xxx: no multichannel peer found!\n"); | ||
169 | pci_dev_put(master_pdev); | ||
170 | } | ||
171 | } | ||
172 | |||
152 | static int | 173 | static int |
153 | ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 174 | ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
154 | { | 175 | { |
@@ -203,6 +224,14 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
203 | ahc_free(ahc); | 224 | ahc_free(ahc); |
204 | return (-error); | 225 | return (-error); |
205 | } | 226 | } |
227 | |||
228 | /* | ||
229 | * Second Function PCI devices need to inherit some | ||
230 | * settings from function 0. | ||
231 | */ | ||
232 | if ((ahc->features & AHC_MULTI_FUNC) && PCI_FUNC(pdev->devfn) != 0) | ||
233 | ahc_linux_pci_inherit_flags(ahc); | ||
234 | |||
206 | pci_set_drvdata(pdev, ahc); | 235 | pci_set_drvdata(pdev, ahc); |
207 | ahc_linux_register_host(ahc, &aic7xxx_driver_template); | 236 | ahc_linux_register_host(ahc, &aic7xxx_driver_template); |
208 | return (0); | 237 | return (0); |