diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-01 17:09:30 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-01 17:09:30 -0500 |
commit | 8ac2b42a45896641ed292deaf038a1d2703d85a6 (patch) | |
tree | fb6c193f4a5f454c36b23c4e972fbe57bb1da6b1 /drivers/ide | |
parent | 993da8f9ea7e00d21af49d0e14a131183288bcf8 (diff) |
ide: add IDE_HFLAG_CLEAR_SIMPLEX host flag
* Rename 'simplex_stat' variable to 'dma_stat' in ide_get_or_set_dma_base().
* Factor out code for forcing host out of "simplex" mode from
ide_get_or_set_dma_base() to ide_pci_clear_simplex() helper.
* Add IDE_HFLAG_CLEAR_SIMPLEX host flag and set it in alim15x3 (for M5229),
amd74xx (for AMD 7409), cmd64x (for CMD643), generic (for Netcell) and
serverworks (for CSB5) host drivers.
* Make ide_get_or_set_dma_base() test for IDE_HFLAG_CLEAR_SIMPLEX host flag
instead of checking dev->device (BTW the code was buggy because it didn't
check for dev->vendor, luckily none of these PCI Device IDs was used by
some other vendor for PCI IDE controller).
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/pci/alim15x3.c | 7 | ||||
-rw-r--r-- | drivers/ide/pci/amd74xx.c | 1 | ||||
-rw-r--r-- | drivers/ide/pci/cmd64x.c | 4 | ||||
-rw-r--r-- | drivers/ide/pci/generic.c | 3 | ||||
-rw-r--r-- | drivers/ide/pci/serverworks.c | 4 | ||||
-rw-r--r-- | drivers/ide/setup-pci.c | 79 |
6 files changed, 48 insertions, 50 deletions
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 9dd7cb4d07d4..0b65a2c9308f 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c | |||
@@ -775,7 +775,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev | |||
775 | }; | 775 | }; |
776 | 776 | ||
777 | struct ide_port_info d = ali15x3_chipset; | 777 | struct ide_port_info d = ali15x3_chipset; |
778 | u8 rev = dev->revision; | 778 | u8 rev = dev->revision, idx = id->driver_data; |
779 | 779 | ||
780 | if (pci_dev_present(ati_rs100)) | 780 | if (pci_dev_present(ati_rs100)) |
781 | printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n"); | 781 | printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n"); |
@@ -798,6 +798,9 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev | |||
798 | d.udma_mask = ATA_UDMA6; | 798 | d.udma_mask = ATA_UDMA6; |
799 | } | 799 | } |
800 | 800 | ||
801 | if (idx == 0) | ||
802 | d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX; | ||
803 | |||
801 | #if defined(CONFIG_SPARC64) | 804 | #if defined(CONFIG_SPARC64) |
802 | d.init_hwif = init_hwif_common_ali15x3; | 805 | d.init_hwif = init_hwif_common_ali15x3; |
803 | #endif /* CONFIG_SPARC64 */ | 806 | #endif /* CONFIG_SPARC64 */ |
@@ -807,7 +810,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev | |||
807 | 810 | ||
808 | static const struct pci_device_id alim15x3_pci_tbl[] = { | 811 | static const struct pci_device_id alim15x3_pci_tbl[] = { |
809 | { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), 0 }, | 812 | { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), 0 }, |
810 | { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 0 }, | 813 | { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 1 }, |
811 | { 0, }, | 814 | { 0, }, |
812 | }; | 815 | }; |
813 | MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl); | 816 | MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl); |
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 13c9f67969cd..2e8cbcaf3ef5 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
@@ -295,6 +295,7 @@ static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_ | |||
295 | if (idx == 1) { | 295 | if (idx == 1) { |
296 | if (dev->revision <= 7) | 296 | if (dev->revision <= 7) |
297 | d.swdma_mask = 0; | 297 | d.swdma_mask = 0; |
298 | d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX; | ||
298 | } else if (idx == 4) { | 299 | } else if (idx == 4) { |
299 | if (dev->subsystem_vendor == PCI_VENDOR_ID_AMD && | 300 | if (dev->subsystem_vendor == PCI_VENDOR_ID_AMD && |
300 | dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) | 301 | dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) |
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index cd4eb9def151..effd79a715b0 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c | |||
@@ -443,7 +443,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
443 | .init_chipset = init_chipset_cmd64x, | 443 | .init_chipset = init_chipset_cmd64x, |
444 | .init_hwif = init_hwif_cmd64x, | 444 | .init_hwif = init_hwif_cmd64x, |
445 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, | 445 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, |
446 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, | 446 | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | |
447 | IDE_HFLAG_ABUSE_PREFETCH | | ||
448 | IDE_HFLAG_BOOTABLE, | ||
447 | .pio_mask = ATA_PIO5, | 449 | .pio_mask = ATA_PIO5, |
448 | .mwdma_mask = ATA_MWDMA2, | 450 | .mwdma_mask = ATA_MWDMA2, |
449 | .udma_mask = 0x00, /* no udma */ | 451 | .udma_mask = 0x00, /* no udma */ |
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 06885697ed7b..22ef34863d56 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c | |||
@@ -104,7 +104,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = { | |||
104 | 104 | ||
105 | { /* 14 */ | 105 | { /* 14 */ |
106 | .name = "Revolution", | 106 | .name = "Revolution", |
107 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | | 107 | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | |
108 | IDE_HFLAG_TRUST_BIOS_FOR_DMA | | ||
108 | IDE_HFLAG_OFF_BOARD, | 109 | IDE_HFLAG_OFF_BOARD, |
109 | .swdma_mask = ATA_SWDMA2, | 110 | .swdma_mask = ATA_SWDMA2, |
110 | .mwdma_mask = ATA_MWDMA2, | 111 | .mwdma_mask = ATA_MWDMA2, |
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 877c09bf4829..bf01c387739e 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c | |||
@@ -418,7 +418,9 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device | |||
418 | 418 | ||
419 | d = serverworks_chipsets[idx]; | 419 | d = serverworks_chipsets[idx]; |
420 | 420 | ||
421 | if (idx == 2 || idx == 3) { | 421 | if (idx == 1) |
422 | d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX; | ||
423 | else if (idx == 2 || idx == 3) { | ||
422 | if ((PCI_FUNC(dev->devfn) & 1) == 0) { | 424 | if ((PCI_FUNC(dev->devfn) & 1) == 0) { |
423 | if (pci_resource_start(dev, 0) != 0x01f1) | 425 | if (pci_resource_start(dev, 0) != 0x01f1) |
424 | d.host_flags &= ~IDE_HFLAG_BOOTABLE; | 426 | d.host_flags &= ~IDE_HFLAG_BOOTABLE; |
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index c473f45abd33..0a4b3a6857e1 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
@@ -140,6 +140,16 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name) | |||
140 | } | 140 | } |
141 | 141 | ||
142 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI | 142 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI |
143 | static void ide_pci_clear_simplex(unsigned long dma_base, const char *name) | ||
144 | { | ||
145 | u8 dma_stat = inb(dma_base + 2); | ||
146 | |||
147 | outb(dma_stat & 0x60, dma_base + 2); | ||
148 | dma_stat = inb(dma_base + 2); | ||
149 | if (dma_stat & 0x80) | ||
150 | printk(KERN_INFO "%s: simplex device: DMA forced\n", name); | ||
151 | } | ||
152 | |||
143 | /** | 153 | /** |
144 | * ide_get_or_set_dma_base - setup BMIBA | 154 | * ide_get_or_set_dma_base - setup BMIBA |
145 | * @d: IDE port info | 155 | * @d: IDE port info |
@@ -154,6 +164,7 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_ | |||
154 | { | 164 | { |
155 | unsigned long dma_base = 0; | 165 | unsigned long dma_base = 0; |
156 | struct pci_dev *dev = hwif->pci_dev; | 166 | struct pci_dev *dev = hwif->pci_dev; |
167 | u8 dma_stat = 0; | ||
157 | 168 | ||
158 | if (hwif->mmio) | 169 | if (hwif->mmio) |
159 | return hwif->dma_base; | 170 | return hwif->dma_base; |
@@ -174,52 +185,30 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_ | |||
174 | if (hwif->channel) | 185 | if (hwif->channel) |
175 | dma_base += 8; | 186 | dma_base += 8; |
176 | 187 | ||
177 | if ((d->host_flags & IDE_HFLAG_CS5520) == 0) { | 188 | if (d->host_flags & IDE_HFLAG_CS5520) |
178 | u8 simplex_stat = 0; | 189 | goto out; |
179 | 190 | ||
180 | switch(dev->device) { | 191 | if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) { |
181 | case PCI_DEVICE_ID_AL_M5219: | 192 | ide_pci_clear_simplex(dma_base, d->name); |
182 | case PCI_DEVICE_ID_AL_M5229: | 193 | goto out; |
183 | case PCI_DEVICE_ID_AMD_VIPER_7409: | 194 | } |
184 | case PCI_DEVICE_ID_CMD_643: | 195 | |
185 | case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: | 196 | /* |
186 | case PCI_DEVICE_ID_REVOLUTION: | 197 | * If the device claims "simplex" DMA, this means that only one of |
187 | simplex_stat = inb(dma_base + 2); | 198 | * the two interfaces can be trusted with DMA at any point in time |
188 | outb(simplex_stat & 0x60, dma_base + 2); | 199 | * (so we should enable DMA only on one of the two interfaces). |
189 | simplex_stat = inb(dma_base + 2); | 200 | * |
190 | if (simplex_stat & 0x80) { | 201 | * FIXME: At this point we haven't probed the drives so we can't make |
191 | printk(KERN_INFO "%s: simplex device: " | 202 | * the appropriate decision. Really we should defer this problem until |
192 | "DMA forced\n", | 203 | * we tune the drive then try to grab DMA ownership if we want to be |
193 | d->name); | 204 | * the DMA end. This has to be become dynamic to handle hot-plug. |
194 | } | 205 | */ |
195 | break; | 206 | dma_stat = hwif->INB(dma_base + 2); |
196 | default: | 207 | if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) { |
197 | /* | 208 | printk(KERN_INFO "%s: simplex device: DMA disabled\n", d->name); |
198 | * If the device claims "simplex" DMA, | 209 | dma_base = 0; |
199 | * this means only one of the two interfaces | ||
200 | * can be trusted with DMA at any point in time. | ||
201 | * So we should enable DMA only on one of the | ||
202 | * two interfaces. | ||
203 | */ | ||
204 | simplex_stat = hwif->INB(dma_base + 2); | ||
205 | if (simplex_stat & 0x80) { | ||
206 | /* simplex device? */ | ||
207 | /* | ||
208 | * At this point we haven't probed the drives so we can't make the | ||
209 | * appropriate decision. Really we should defer this problem | ||
210 | * until we tune the drive then try to grab DMA ownership if we want | ||
211 | * to be the DMA end. This has to be become dynamic to handle hot | ||
212 | * plug. | ||
213 | */ | ||
214 | if (hwif->mate && hwif->mate->dma_base) { | ||
215 | printk(KERN_INFO "%s: simplex device: " | ||
216 | "DMA disabled\n", | ||
217 | d->name); | ||
218 | dma_base = 0; | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | } | 210 | } |
211 | out: | ||
223 | return dma_base; | 212 | return dma_base; |
224 | } | 213 | } |
225 | #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ | 214 | #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ |