diff options
Diffstat (limited to 'drivers/ide/pci/serverworks.c')
-rw-r--r-- | drivers/ide/pci/serverworks.c | 105 |
1 files changed, 51 insertions, 54 deletions
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index ed04e0c8dd4c..9fead2e7d4c8 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/serverworks.c Version 0.20 Jun 3 2007 | 2 | * linux/drivers/ide/pci/serverworks.c Version 0.22 Jun 27 2007 |
3 | * | 3 | * |
4 | * Copyright (C) 1998-2000 Michel Aubry | 4 | * Copyright (C) 1998-2000 Michel Aubry |
5 | * Copyright (C) 1998-2000 Andrzej Krzysztofowicz | 5 | * Copyright (C) 1998-2000 Andrzej Krzysztofowicz |
@@ -123,23 +123,45 @@ static u8 svwks_csb_check (struct pci_dev *dev) | |||
123 | } | 123 | } |
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | |||
127 | static void svwks_tune_pio(ide_drive_t *drive, const u8 pio) | ||
128 | { | ||
129 | static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; | ||
130 | static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; | ||
131 | |||
132 | struct pci_dev *dev = drive->hwif->pci_dev; | ||
133 | |||
134 | pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]); | ||
135 | |||
136 | if (svwks_csb_check(dev)) { | ||
137 | u16 csb_pio = 0; | ||
138 | |||
139 | pci_read_config_word(dev, 0x4a, &csb_pio); | ||
140 | |||
141 | csb_pio &= ~(0x0f << (4 * drive->dn)); | ||
142 | csb_pio |= (pio << (4 * drive->dn)); | ||
143 | |||
144 | pci_write_config_word(dev, 0x4a, csb_pio); | ||
145 | } | ||
146 | } | ||
147 | |||
126 | static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) | 148 | static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) |
127 | { | 149 | { |
128 | static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; | 150 | static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; |
129 | static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; | 151 | static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; |
130 | static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; | ||
131 | static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; | ||
132 | static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; | 152 | static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; |
133 | 153 | ||
134 | ide_hwif_t *hwif = HWIF(drive); | 154 | ide_hwif_t *hwif = HWIF(drive); |
135 | struct pci_dev *dev = hwif->pci_dev; | 155 | struct pci_dev *dev = hwif->pci_dev; |
136 | u8 speed = ide_rate_filter(drive, xferspeed); | 156 | u8 speed = ide_rate_filter(drive, xferspeed); |
137 | u8 pio = ide_get_best_pio_mode(drive, 255, 4, NULL); | ||
138 | u8 unit = (drive->select.b.unit & 0x01); | 157 | u8 unit = (drive->select.b.unit & 0x01); |
139 | u8 csb5 = svwks_csb_check(dev); | 158 | |
140 | u8 ultra_enable = 0, ultra_timing = 0; | 159 | u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0; |
141 | u8 dma_timing = 0, pio_timing = 0; | 160 | |
142 | u16 csb5_pio = 0; | 161 | if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) { |
162 | svwks_tune_pio(drive, speed - XFER_PIO_0); | ||
163 | return ide_config_drive_speed(drive, speed); | ||
164 | } | ||
143 | 165 | ||
144 | /* If we are about to put a disk into UDMA mode we screwed up. | 166 | /* If we are about to put a disk into UDMA mode we screwed up. |
145 | Our code assumes we never _ever_ do this on an OSB4 */ | 167 | Our code assumes we never _ever_ do this on an OSB4 */ |
@@ -149,31 +171,15 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
149 | BUG(); | 171 | BUG(); |
150 | 172 | ||
151 | pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing); | 173 | pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing); |
152 | pci_read_config_word(dev, 0x4A, &csb5_pio); | ||
153 | pci_read_config_byte(dev, 0x54, &ultra_enable); | 174 | pci_read_config_byte(dev, 0x54, &ultra_enable); |
154 | 175 | ||
155 | ultra_timing &= ~(0x0F << (4*unit)); | 176 | ultra_timing &= ~(0x0F << (4*unit)); |
156 | ultra_enable &= ~(0x01 << drive->dn); | 177 | ultra_enable &= ~(0x01 << drive->dn); |
157 | csb5_pio &= ~(0x0F << (4*drive->dn)); | ||
158 | 178 | ||
159 | switch(speed) { | 179 | switch(speed) { |
160 | case XFER_PIO_4: | ||
161 | case XFER_PIO_3: | ||
162 | case XFER_PIO_2: | ||
163 | case XFER_PIO_1: | ||
164 | case XFER_PIO_0: | ||
165 | pio_timing |= pio_modes[speed - XFER_PIO_0]; | ||
166 | csb5_pio |= ((speed - XFER_PIO_0) << (4*drive->dn)); | ||
167 | break; | ||
168 | |||
169 | case XFER_MW_DMA_2: | 180 | case XFER_MW_DMA_2: |
170 | case XFER_MW_DMA_1: | 181 | case XFER_MW_DMA_1: |
171 | case XFER_MW_DMA_0: | 182 | case XFER_MW_DMA_0: |
172 | /* | ||
173 | * TODO: always setup PIO mode so this won't be needed | ||
174 | */ | ||
175 | pio_timing |= pio_modes[pio]; | ||
176 | csb5_pio |= (pio << (4*drive->dn)); | ||
177 | dma_timing |= dma_modes[speed - XFER_MW_DMA_0]; | 183 | dma_timing |= dma_modes[speed - XFER_MW_DMA_0]; |
178 | break; | 184 | break; |
179 | 185 | ||
@@ -183,11 +189,6 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
183 | case XFER_UDMA_2: | 189 | case XFER_UDMA_2: |
184 | case XFER_UDMA_1: | 190 | case XFER_UDMA_1: |
185 | case XFER_UDMA_0: | 191 | case XFER_UDMA_0: |
186 | /* | ||
187 | * TODO: always setup PIO mode so this won't be needed | ||
188 | */ | ||
189 | pio_timing |= pio_modes[pio]; | ||
190 | csb5_pio |= (pio << (4*drive->dn)); | ||
191 | dma_timing |= dma_modes[2]; | 192 | dma_timing |= dma_modes[2]; |
192 | ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit)); | 193 | ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit)); |
193 | ultra_enable |= (0x01 << drive->dn); | 194 | ultra_enable |= (0x01 << drive->dn); |
@@ -195,10 +196,6 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
195 | break; | 196 | break; |
196 | } | 197 | } |
197 | 198 | ||
198 | pci_write_config_byte(dev, drive_pci[drive->dn], pio_timing); | ||
199 | if (csb5) | ||
200 | pci_write_config_word(dev, 0x4A, csb5_pio); | ||
201 | |||
202 | pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing); | 199 | pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing); |
203 | pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing); | 200 | pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing); |
204 | pci_write_config_byte(dev, 0x54, ultra_enable); | 201 | pci_write_config_byte(dev, 0x54, ultra_enable); |
@@ -208,8 +205,9 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
208 | 205 | ||
209 | static void svwks_tune_drive (ide_drive_t *drive, u8 pio) | 206 | static void svwks_tune_drive (ide_drive_t *drive, u8 pio) |
210 | { | 207 | { |
211 | pio = ide_get_best_pio_mode(drive, pio, 4, NULL); | 208 | pio = ide_get_best_pio_mode(drive, pio, 4); |
212 | (void)svwks_tune_chipset(drive, XFER_PIO_0 + pio); | 209 | svwks_tune_pio(drive, pio); |
210 | (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); | ||
213 | } | 211 | } |
214 | 212 | ||
215 | static int svwks_config_drive_xfer_rate (ide_drive_t *drive) | 213 | static int svwks_config_drive_xfer_rate (ide_drive_t *drive) |
@@ -389,8 +387,6 @@ static u8 __devinit ata66_svwks(ide_hwif_t *hwif) | |||
389 | 387 | ||
390 | static void __devinit init_hwif_svwks (ide_hwif_t *hwif) | 388 | static void __devinit init_hwif_svwks (ide_hwif_t *hwif) |
391 | { | 389 | { |
392 | u8 dma_stat = 0; | ||
393 | |||
394 | if (!hwif->irq) | 390 | if (!hwif->irq) |
395 | hwif->irq = hwif->channel ? 15 : 14; | 391 | hwif->irq = hwif->channel ? 15 : 14; |
396 | 392 | ||
@@ -407,11 +403,11 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) | |||
407 | 403 | ||
408 | hwif->autodma = 0; | 404 | hwif->autodma = 0; |
409 | 405 | ||
410 | if (!hwif->dma_base) { | 406 | hwif->drives[0].autotune = 1; |
411 | hwif->drives[0].autotune = 1; | 407 | hwif->drives[1].autotune = 1; |
412 | hwif->drives[1].autotune = 1; | 408 | |
409 | if (!hwif->dma_base) | ||
413 | return; | 410 | return; |
414 | } | ||
415 | 411 | ||
416 | hwif->ide_dma_check = &svwks_config_drive_xfer_rate; | 412 | hwif->ide_dma_check = &svwks_config_drive_xfer_rate; |
417 | if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { | 413 | if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { |
@@ -421,11 +417,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) | |||
421 | if (!noautodma) | 417 | if (!noautodma) |
422 | hwif->autodma = 1; | 418 | hwif->autodma = 1; |
423 | 419 | ||
424 | dma_stat = inb(hwif->dma_status); | 420 | hwif->drives[0].autodma = hwif->drives[1].autodma = 1; |
425 | hwif->drives[0].autodma = (dma_stat & 0x20); | ||
426 | hwif->drives[1].autodma = (dma_stat & 0x40); | ||
427 | hwif->drives[0].autotune = (!(dma_stat & 0x20)); | ||
428 | hwif->drives[1].autotune = (!(dma_stat & 0x40)); | ||
429 | } | 421 | } |
430 | 422 | ||
431 | static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d) | 423 | static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d) |
@@ -441,9 +433,12 @@ static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d) | |||
441 | d->bootable = ON_BOARD; | 433 | d->bootable = ON_BOARD; |
442 | } | 434 | } |
443 | 435 | ||
444 | d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || | 436 | if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || |
445 | dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && | 437 | dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && |
446 | (!(PCI_FUNC(dev->devfn) & 1))) ? 1 : 2; | 438 | (!(PCI_FUNC(dev->devfn) & 1))) |
439 | d->host_flags |= IDE_HFLAG_SINGLE; | ||
440 | else | ||
441 | d->host_flags &= ~IDE_HFLAG_SINGLE; | ||
447 | 442 | ||
448 | return ide_setup_pci_device(dev, d); | 443 | return ide_setup_pci_device(dev, d); |
449 | } | 444 | } |
@@ -454,41 +449,43 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { | |||
454 | .init_setup = init_setup_svwks, | 449 | .init_setup = init_setup_svwks, |
455 | .init_chipset = init_chipset_svwks, | 450 | .init_chipset = init_chipset_svwks, |
456 | .init_hwif = init_hwif_svwks, | 451 | .init_hwif = init_hwif_svwks, |
457 | .channels = 2, | ||
458 | .autodma = AUTODMA, | 452 | .autodma = AUTODMA, |
459 | .bootable = ON_BOARD, | 453 | .bootable = ON_BOARD, |
454 | .pio_mask = ATA_PIO4, | ||
460 | },{ /* 1 */ | 455 | },{ /* 1 */ |
461 | .name = "SvrWks CSB5", | 456 | .name = "SvrWks CSB5", |
462 | .init_setup = init_setup_svwks, | 457 | .init_setup = init_setup_svwks, |
463 | .init_chipset = init_chipset_svwks, | 458 | .init_chipset = init_chipset_svwks, |
464 | .init_hwif = init_hwif_svwks, | 459 | .init_hwif = init_hwif_svwks, |
465 | .channels = 2, | ||
466 | .autodma = AUTODMA, | 460 | .autodma = AUTODMA, |
467 | .bootable = ON_BOARD, | 461 | .bootable = ON_BOARD, |
462 | .pio_mask = ATA_PIO4, | ||
468 | },{ /* 2 */ | 463 | },{ /* 2 */ |
469 | .name = "SvrWks CSB6", | 464 | .name = "SvrWks CSB6", |
470 | .init_setup = init_setup_csb6, | 465 | .init_setup = init_setup_csb6, |
471 | .init_chipset = init_chipset_svwks, | 466 | .init_chipset = init_chipset_svwks, |
472 | .init_hwif = init_hwif_svwks, | 467 | .init_hwif = init_hwif_svwks, |
473 | .channels = 2, | ||
474 | .autodma = AUTODMA, | 468 | .autodma = AUTODMA, |
475 | .bootable = ON_BOARD, | 469 | .bootable = ON_BOARD, |
470 | .pio_mask = ATA_PIO4, | ||
476 | },{ /* 3 */ | 471 | },{ /* 3 */ |
477 | .name = "SvrWks CSB6", | 472 | .name = "SvrWks CSB6", |
478 | .init_setup = init_setup_csb6, | 473 | .init_setup = init_setup_csb6, |
479 | .init_chipset = init_chipset_svwks, | 474 | .init_chipset = init_chipset_svwks, |
480 | .init_hwif = init_hwif_svwks, | 475 | .init_hwif = init_hwif_svwks, |
481 | .channels = 1, /* 2 */ | ||
482 | .autodma = AUTODMA, | 476 | .autodma = AUTODMA, |
483 | .bootable = ON_BOARD, | 477 | .bootable = ON_BOARD, |
478 | .host_flags = IDE_HFLAG_SINGLE, | ||
479 | .pio_mask = ATA_PIO4, | ||
484 | },{ /* 4 */ | 480 | },{ /* 4 */ |
485 | .name = "SvrWks HT1000", | 481 | .name = "SvrWks HT1000", |
486 | .init_setup = init_setup_svwks, | 482 | .init_setup = init_setup_svwks, |
487 | .init_chipset = init_chipset_svwks, | 483 | .init_chipset = init_chipset_svwks, |
488 | .init_hwif = init_hwif_svwks, | 484 | .init_hwif = init_hwif_svwks, |
489 | .channels = 1, /* 2 */ | ||
490 | .autodma = AUTODMA, | 485 | .autodma = AUTODMA, |
491 | .bootable = ON_BOARD, | 486 | .bootable = ON_BOARD, |
487 | .host_flags = IDE_HFLAG_SINGLE, | ||
488 | .pio_mask = ATA_PIO4, | ||
492 | } | 489 | } |
493 | }; | 490 | }; |
494 | 491 | ||