aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-07-19 19:11:56 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-07-19 19:11:56 -0400
commit1880a8d7f2d0587e657e3292166003636067b7ea (patch)
tree94ab0c3404fb45f73fc18dc2fa8d6ab268c9b803 /drivers
parenta5d8c5c834d3cabf4b7b477c3f6ee923c25026fc (diff)
serverworks: always tune PIO
* Always set ->autotune so PIO gets correctly auto-tuned (previously ->autotune was only set when ->dma_base wasn't available, however ->ide_dma_check()/->speedproc() was always trying to tune PIO when tuning DMA). * Move code responsible for programming chipset for PIO mode from svwks_tune_chipset() to svwks_tune_pio(). Don't tune PIO when tuning DMA (this is no longer needed since ->autotune is always set now). * Handle PIO modes early in svwks_tune_chipset() so DMA configuration registers don't get cleared when programming PIO mode. * Bump driver version. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ide/pci/serverworks.c76
1 files changed, 36 insertions, 40 deletions
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index 809deb92bc11..011245246b1f 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.21 Jun 16 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);
@@ -209,7 +206,8 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
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, NULL);
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)
@@ -407,11 +405,11 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
407 405
408 hwif->autodma = 0; 406 hwif->autodma = 0;
409 407
410 if (!hwif->dma_base) { 408 hwif->drives[0].autotune = 1;
411 hwif->drives[0].autotune = 1; 409 hwif->drives[1].autotune = 1;
412 hwif->drives[1].autotune = 1; 410
411 if (!hwif->dma_base)
413 return; 412 return;
414 }
415 413
416 hwif->ide_dma_check = &svwks_config_drive_xfer_rate; 414 hwif->ide_dma_check = &svwks_config_drive_xfer_rate;
417 if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { 415 if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
@@ -424,8 +422,6 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
424 dma_stat = inb(hwif->dma_status); 422 dma_stat = inb(hwif->dma_status);
425 hwif->drives[0].autodma = (dma_stat & 0x20); 423 hwif->drives[0].autodma = (dma_stat & 0x20);
426 hwif->drives[1].autodma = (dma_stat & 0x40); 424 hwif->drives[1].autodma = (dma_stat & 0x40);
427 hwif->drives[0].autotune = (!(dma_stat & 0x20));
428 hwif->drives[1].autotune = (!(dma_stat & 0x40));
429} 425}
430 426
431static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d) 427static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)