diff options
| -rw-r--r-- | drivers/ide/pci/sl82c105.c | 148 |
1 files changed, 59 insertions, 89 deletions
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index ee6dd45a9ba7..fe3b4b91f854 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c | |||
| @@ -100,59 +100,28 @@ static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) | |||
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | /* | 102 | /* |
| 103 | * Configure the drive and the chipset for DMA | 103 | * Configure the drive for DMA. |
| 104 | * We'll program the chipset only when DMA is actually turned on. | ||
| 104 | */ | 105 | */ |
| 105 | static int config_for_dma (ide_drive_t *drive) | 106 | static int config_for_dma(ide_drive_t *drive) |
| 106 | { | 107 | { |
| 107 | ide_hwif_t *hwif = HWIF(drive); | ||
| 108 | struct pci_dev *dev = hwif->pci_dev; | ||
| 109 | unsigned int reg; | ||
| 110 | |||
| 111 | DBG(("config_for_dma(drive:%s)\n", drive->name)); | 108 | DBG(("config_for_dma(drive:%s)\n", drive->name)); |
| 112 | 109 | ||
| 113 | reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); | ||
| 114 | |||
| 115 | if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) | 110 | if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) |
| 116 | return 1; | 111 | return 0; |
| 117 | 112 | ||
| 118 | pci_write_config_word(dev, reg, 0x0240); | 113 | return ide_dma_enable(drive); |
| 119 | |||
| 120 | return 0; | ||
| 121 | } | 114 | } |
| 122 | 115 | ||
| 123 | /* | 116 | /* |
| 124 | * Check to see if the drive and | 117 | * Check to see if the drive and chipset are capable of DMA mode. |
| 125 | * chipset is capable of DMA mode | ||
| 126 | */ | 118 | */ |
| 127 | 119 | static int sl82c105_ide_dma_check(ide_drive_t *drive) | |
| 128 | static int sl82c105_check_drive (ide_drive_t *drive) | ||
| 129 | { | 120 | { |
| 130 | ide_hwif_t *hwif = HWIF(drive); | 121 | DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); |
| 131 | |||
| 132 | DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); | ||
| 133 | |||
| 134 | do { | ||
| 135 | struct hd_driveid *id = drive->id; | ||
| 136 | 122 | ||
| 137 | if (!drive->autodma) | 123 | if (ide_use_dma(drive) && config_for_dma(drive)) |
| 138 | break; | 124 | return 0; |
| 139 | |||
| 140 | if (!id || !(id->capability & 1)) | ||
| 141 | break; | ||
| 142 | |||
| 143 | /* Consult the list of known "bad" drives */ | ||
| 144 | if (__ide_dma_bad_drive(drive)) | ||
| 145 | break; | ||
| 146 | |||
| 147 | if (id->field_valid & 2) { | ||
| 148 | if ((id->dma_mword & hwif->mwdma_mask) || | ||
| 149 | (id->dma_1word & hwif->swdma_mask)) | ||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) | ||
| 154 | return 0; | ||
| 155 | } while (0); | ||
| 156 | 125 | ||
| 157 | return -1; | 126 | return -1; |
| 158 | } | 127 | } |
| @@ -181,14 +150,14 @@ static inline void sl82c105_reset_host(struct pci_dev *dev) | |||
| 181 | * This function is called when the IDE timer expires, the drive | 150 | * This function is called when the IDE timer expires, the drive |
| 182 | * indicates that it is READY, and we were waiting for DMA to complete. | 151 | * indicates that it is READY, and we were waiting for DMA to complete. |
| 183 | */ | 152 | */ |
| 184 | static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) | 153 | static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) |
| 185 | { | 154 | { |
| 186 | ide_hwif_t *hwif = HWIF(drive); | 155 | ide_hwif_t *hwif = HWIF(drive); |
| 187 | struct pci_dev *dev = hwif->pci_dev; | 156 | struct pci_dev *dev = hwif->pci_dev; |
| 188 | u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; | 157 | u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; |
| 189 | unsigned long dma_base = hwif->dma_base; | 158 | u8 dma_cmd; |
| 190 | 159 | ||
| 191 | printk("sl82c105: lost IRQ: resetting host\n"); | 160 | printk("sl82c105: lost IRQ, resetting host\n"); |
| 192 | 161 | ||
| 193 | /* | 162 | /* |
| 194 | * Check the raw interrupt from the drive. | 163 | * Check the raw interrupt from the drive. |
| @@ -201,15 +170,15 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) | |||
| 201 | * Was DMA enabled? If so, disable it - we're resetting the | 170 | * Was DMA enabled? If so, disable it - we're resetting the |
| 202 | * host. The IDE layer will be handling the drive for us. | 171 | * host. The IDE layer will be handling the drive for us. |
| 203 | */ | 172 | */ |
| 204 | val = inb(dma_base); | 173 | dma_cmd = inb(hwif->dma_command); |
| 205 | if (val & 1) { | 174 | if (dma_cmd & 1) { |
| 206 | outb(val & ~1, dma_base); | 175 | outb(dma_cmd & ~1, hwif->dma_command); |
| 207 | printk("sl82c105: DMA was enabled\n"); | 176 | printk("sl82c105: DMA was enabled\n"); |
| 208 | } | 177 | } |
| 209 | 178 | ||
| 210 | sl82c105_reset_host(dev); | 179 | sl82c105_reset_host(dev); |
| 211 | 180 | ||
| 212 | /* ide_dmaproc would return 1, so we do as well */ | 181 | /* __ide_dma_lostirq would return 1, so we do as well */ |
| 213 | return 1; | 182 | return 1; |
| 214 | } | 183 | } |
| 215 | 184 | ||
| @@ -221,10 +190,10 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) | |||
| 221 | * The generic IDE core will have disabled the BMEN bit before this | 190 | * The generic IDE core will have disabled the BMEN bit before this |
| 222 | * function is called. | 191 | * function is called. |
| 223 | */ | 192 | */ |
| 224 | static void sl82c105_ide_dma_start(ide_drive_t *drive) | 193 | static void sl82c105_dma_start(ide_drive_t *drive) |
| 225 | { | 194 | { |
| 226 | ide_hwif_t *hwif = HWIF(drive); | 195 | ide_hwif_t *hwif = HWIF(drive); |
| 227 | struct pci_dev *dev = hwif->pci_dev; | 196 | struct pci_dev *dev = hwif->pci_dev; |
| 228 | 197 | ||
| 229 | sl82c105_reset_host(dev); | 198 | sl82c105_reset_host(dev); |
| 230 | ide_dma_start(drive); | 199 | ide_dma_start(drive); |
| @@ -232,8 +201,8 @@ static void sl82c105_ide_dma_start(ide_drive_t *drive) | |||
| 232 | 201 | ||
| 233 | static int sl82c105_ide_dma_timeout(ide_drive_t *drive) | 202 | static int sl82c105_ide_dma_timeout(ide_drive_t *drive) |
| 234 | { | 203 | { |
| 235 | ide_hwif_t *hwif = HWIF(drive); | 204 | ide_hwif_t *hwif = HWIF(drive); |
| 236 | struct pci_dev *dev = hwif->pci_dev; | 205 | struct pci_dev *dev = hwif->pci_dev; |
| 237 | 206 | ||
| 238 | DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); | 207 | DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); |
| 239 | 208 | ||
| @@ -241,14 +210,20 @@ static int sl82c105_ide_dma_timeout(ide_drive_t *drive) | |||
| 241 | return __ide_dma_timeout(drive); | 210 | return __ide_dma_timeout(drive); |
| 242 | } | 211 | } |
| 243 | 212 | ||
| 244 | static int sl82c105_ide_dma_on (ide_drive_t *drive) | 213 | static int sl82c105_ide_dma_on(ide_drive_t *drive) |
| 245 | { | 214 | { |
| 215 | struct pci_dev *dev = HWIF(drive)->pci_dev; | ||
| 216 | int rc, reg = 0x44 + drive->dn * 4; | ||
| 217 | |||
| 246 | DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); | 218 | DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); |
| 247 | 219 | ||
| 248 | if (config_for_dma(drive)) | 220 | rc = __ide_dma_on(drive); |
| 249 | return 1; | 221 | if (rc == 0) { |
| 250 | printk(KERN_INFO "%s: DMA enabled\n", drive->name); | 222 | pci_write_config_word(dev, reg, 0x0200); |
| 251 | return __ide_dma_on(drive); | 223 | |
| 224 | printk(KERN_INFO "%s: DMA enabled\n", drive->name); | ||
| 225 | } | ||
| 226 | return rc; | ||
| 252 | } | 227 | } |
| 253 | 228 | ||
| 254 | static void sl82c105_dma_off_quietly(ide_drive_t *drive) | 229 | static void sl82c105_dma_off_quietly(ide_drive_t *drive) |
| @@ -272,8 +247,8 @@ static void sl82c105_dma_off_quietly(ide_drive_t *drive) | |||
| 272 | */ | 247 | */ |
| 273 | static void sl82c105_selectproc(ide_drive_t *drive) | 248 | static void sl82c105_selectproc(ide_drive_t *drive) |
| 274 | { | 249 | { |
| 275 | ide_hwif_t *hwif = HWIF(drive); | 250 | ide_hwif_t *hwif = HWIF(drive); |
| 276 | struct pci_dev *dev = hwif->pci_dev; | 251 | struct pci_dev *dev = hwif->pci_dev; |
| 277 | u32 val, old, mask; | 252 | u32 val, old, mask; |
| 278 | 253 | ||
| 279 | //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); | 254 | //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); |
| @@ -373,7 +348,7 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c | |||
| 373 | } | 348 | } |
| 374 | 349 | ||
| 375 | /* | 350 | /* |
| 376 | * Initialise the chip | 351 | * Initialise IDE channel |
| 377 | */ | 352 | */ |
| 378 | static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | 353 | static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) |
| 379 | { | 354 | { |
| @@ -398,11 +373,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
| 398 | */ | 373 | */ |
| 399 | hwif->drives[0].autotune = hwif->drives[1].autotune = 1; | 374 | hwif->drives[0].autotune = hwif->drives[1].autotune = 1; |
| 400 | 375 | ||
| 401 | hwif->atapi_dma = 0; | ||
| 402 | hwif->mwdma_mask = 0; | ||
| 403 | hwif->swdma_mask = 0; | ||
| 404 | hwif->autodma = 0; | ||
| 405 | |||
| 406 | if (!hwif->dma_base) | 376 | if (!hwif->dma_base) |
| 407 | return; | 377 | return; |
| 408 | 378 | ||
| @@ -412,27 +382,27 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
| 412 | * Never ever EVER under any circumstances enable | 382 | * Never ever EVER under any circumstances enable |
| 413 | * DMA when the bridge is this old. | 383 | * DMA when the bridge is this old. |
| 414 | */ | 384 | */ |
| 415 | printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", | 385 | printk(" %s: Winbond W83C553 bridge revision %d, " |
| 416 | hwif->name, rev); | 386 | "BM-DMA disabled\n", hwif->name, rev); |
| 417 | } else { | 387 | return; |
| 418 | hwif->atapi_dma = 1; | ||
| 419 | hwif->mwdma_mask = 0x04; | ||
| 420 | |||
| 421 | hwif->ide_dma_check = &sl82c105_check_drive; | ||
| 422 | hwif->ide_dma_on = &sl82c105_ide_dma_on; | ||
| 423 | hwif->dma_off_quietly = &sl82c105_dma_off_quietly; | ||
| 424 | hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; | ||
| 425 | hwif->dma_start = &sl82c105_ide_dma_start; | ||
| 426 | hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; | ||
| 427 | |||
| 428 | if (!noautodma) | ||
| 429 | hwif->autodma = 1; | ||
| 430 | hwif->drives[0].autodma = hwif->autodma; | ||
| 431 | hwif->drives[1].autodma = hwif->autodma; | ||
| 432 | |||
| 433 | if (hwif->mate) | ||
| 434 | hwif->serialized = hwif->mate->serialized = 1; | ||
| 435 | } | 388 | } |
| 389 | |||
| 390 | hwif->atapi_dma = 1; | ||
| 391 | hwif->mwdma_mask = 0x04; | ||
| 392 | |||
| 393 | hwif->ide_dma_check = &sl82c105_ide_dma_check; | ||
| 394 | hwif->ide_dma_on = &sl82c105_ide_dma_on; | ||
| 395 | hwif->dma_off_quietly = &sl82c105_dma_off_quietly; | ||
| 396 | hwif->ide_dma_lostirq = &sl82c105_ide_dma_lostirq; | ||
| 397 | hwif->dma_start = &sl82c105_dma_start; | ||
| 398 | hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; | ||
| 399 | |||
| 400 | if (!noautodma) | ||
| 401 | hwif->autodma = 1; | ||
| 402 | hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; | ||
| 403 | |||
| 404 | if (hwif->mate) | ||
| 405 | hwif->serialized = hwif->mate->serialized = 1; | ||
| 436 | } | 406 | } |
| 437 | 407 | ||
| 438 | static ide_pci_device_t sl82c105_chipset __devinitdata = { | 408 | static ide_pci_device_t sl82c105_chipset __devinitdata = { |
