aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/pci/serverworks.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/pci/serverworks.c')
-rw-r--r--drivers/ide/pci/serverworks.c105
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
127static 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
126static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) 148static 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
209static void svwks_tune_drive (ide_drive_t *drive, u8 pio) 206static 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
215static int svwks_config_drive_xfer_rate (ide_drive_t *drive) 213static 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
390static void __devinit init_hwif_svwks (ide_hwif_t *hwif) 388static 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
431static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d) 423static 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