aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2005-11-18 16:09:45 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2005-11-18 16:09:45 -0500
commit7462cbff7d4c2dc0d182613fb4e801efb29b90ac (patch)
tree6adcf49cde0ec048e38c73334a3e8973512437e2 /drivers/ide
parent861e76a8ab7ba64a74c567fa8c4d1d38c4dfdd24 (diff)
[PATCH] via82cxxx IDE: support multiple controllers
Support multiple controllers in the via82cxxx IDE driver. Cable detection and ISA bridge finding have been moved into their own functions. Signed-off-by: Daniel Drake <dsd@gentoo.org> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/pci/via82cxxx.c195
1 files changed, 117 insertions, 78 deletions
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 2fbc215988ab..cee2c374cd2f 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -100,11 +100,15 @@ static struct via_isa_bridge {
100 { NULL } 100 { NULL }
101}; 101};
102 102
103static struct via_isa_bridge *via_config;
104static unsigned int via_80w;
105static unsigned int via_clock; 103static unsigned int via_clock;
106static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; 104static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
107 105
106struct via82cxxx_dev
107{
108 struct via_isa_bridge *via_config;
109 unsigned int via_80w;
110};
111
108/** 112/**
109 * via_set_speed - write timing registers 113 * via_set_speed - write timing registers
110 * @dev: PCI device 114 * @dev: PCI device
@@ -114,11 +118,13 @@ static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }
114 * via_set_speed writes timing values to the chipset registers 118 * via_set_speed writes timing values to the chipset registers
115 */ 119 */
116 120
117static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing) 121static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
118{ 122{
123 struct pci_dev *dev = hwif->pci_dev;
124 struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
119 u8 t; 125 u8 t;
120 126
121 if (~via_config->flags & VIA_BAD_AST) { 127 if (~vdev->via_config->flags & VIA_BAD_AST) {
122 pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); 128 pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
123 t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); 129 t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
124 pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t); 130 pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
@@ -130,7 +136,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
130 pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), 136 pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
131 ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); 137 ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
132 138
133 switch (via_config->flags & VIA_UDMA) { 139 switch (vdev->via_config->flags & VIA_UDMA) {
134 case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; 140 case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
135 case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; 141 case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
136 case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; 142 case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
@@ -154,6 +160,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
154static int via_set_drive(ide_drive_t *drive, u8 speed) 160static int via_set_drive(ide_drive_t *drive, u8 speed)
155{ 161{
156 ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); 162 ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
163 struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif);
157 struct ide_timing t, p; 164 struct ide_timing t, p;
158 unsigned int T, UT; 165 unsigned int T, UT;
159 166
@@ -162,7 +169,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
162 169
163 T = 1000000000 / via_clock; 170 T = 1000000000 / via_clock;
164 171
165 switch (via_config->flags & VIA_UDMA) { 172 switch (vdev->via_config->flags & VIA_UDMA) {
166 case VIA_UDMA_33: UT = T; break; 173 case VIA_UDMA_33: UT = T; break;
167 case VIA_UDMA_66: UT = T/2; break; 174 case VIA_UDMA_66: UT = T/2; break;
168 case VIA_UDMA_100: UT = T/3; break; 175 case VIA_UDMA_100: UT = T/3; break;
@@ -177,7 +184,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
177 ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); 184 ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
178 } 185 }
179 186
180 via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); 187 via_set_speed(HWIF(drive), drive->dn, &t);
181 188
182 if (!drive->init_speed) 189 if (!drive->init_speed)
183 drive->init_speed = speed; 190 drive->init_speed = speed;
@@ -215,20 +222,41 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
215 222
216static int via82cxxx_ide_dma_check (ide_drive_t *drive) 223static int via82cxxx_ide_dma_check (ide_drive_t *drive)
217{ 224{
218 u16 w80 = HWIF(drive)->udma_four; 225 ide_hwif_t *hwif = HWIF(drive);
226 struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
227 u16 w80 = hwif->udma_four;
219 228
220 u16 speed = ide_find_best_mode(drive, 229 u16 speed = ide_find_best_mode(drive,
221 XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | 230 XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
222 (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | 231 (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
223 (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | 232 (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
224 (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | 233 (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
225 (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0)); 234 (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
226 235
227 via_set_drive(drive, speed); 236 via_set_drive(drive, speed);
228 237
229 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) 238 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
230 return HWIF(drive)->ide_dma_on(drive); 239 return hwif->ide_dma_on(drive);
231 return HWIF(drive)->ide_dma_off_quietly(drive); 240 return hwif->ide_dma_off_quietly(drive);
241}
242
243static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
244{
245 struct via_isa_bridge *via_config;
246 u8 t;
247
248 for (via_config = via_isa_bridges; via_config->id; via_config++)
249 if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA +
250 !!(via_config->flags & VIA_BAD_ID),
251 via_config->id, NULL))) {
252
253 pci_read_config_byte(*isa, PCI_REVISION_ID, &t);
254 if (t >= via_config->rev_min &&
255 t <= via_config->rev_max)
256 break;
257 }
258
259 return via_config;
232} 260}
233 261
234/** 262/**
@@ -243,82 +271,28 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
243static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) 271static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
244{ 272{
245 struct pci_dev *isa = NULL; 273 struct pci_dev *isa = NULL;
274 struct via_isa_bridge *via_config;
246 u8 t, v; 275 u8 t, v;
247 unsigned int u; 276 unsigned int u;
248 int i;
249 277
250 /* 278 /*
251 * Find the ISA bridge to see how good the IDE is. 279 * Find the ISA bridge to see how good the IDE is.
252 */ 280 */
253 281 via_config = via_config_find(&isa);
254 for (via_config = via_isa_bridges; via_config->id; via_config++)
255 if ((isa = pci_find_device(PCI_VENDOR_ID_VIA +
256 !!(via_config->flags & VIA_BAD_ID),
257 via_config->id, NULL))) {
258
259 pci_read_config_byte(isa, PCI_REVISION_ID, &t);
260 if (t >= via_config->rev_min &&
261 t <= via_config->rev_max)
262 break;
263 }
264
265 if (!via_config->id) { 282 if (!via_config->id) {
266 printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); 283 printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
267 return -ENODEV; 284 return -ENODEV;
268 } 285 }
269 286
270 /* 287 /*
271 * Check 80-wire cable presence and setup Clk66. 288 * Setup or disable Clk66 if appropriate
272 */ 289 */
273 290
274 switch (via_config->flags & VIA_UDMA) { 291 if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) {
275 292 /* Enable Clk66 */
276 case VIA_UDMA_66: 293 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
277 /* Enable Clk66 */ 294 pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
278 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); 295 } else if (via_config->flags & VIA_BAD_CLK66) {
279 pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
280 for (i = 24; i >= 0; i -= 8)
281 if (((u >> (i & 16)) & 8) &&
282 ((u >> i) & 0x20) &&
283 (((u >> i) & 7) < 2)) {
284 /*
285 * 2x PCI clock and
286 * UDMA w/ < 3T/cycle
287 */
288 via_80w |= (1 << (1 - (i >> 4)));
289 }
290 break;
291
292 case VIA_UDMA_100:
293 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
294 for (i = 24; i >= 0; i -= 8)
295 if (((u >> i) & 0x10) ||
296 (((u >> i) & 0x20) &&
297 (((u >> i) & 7) < 4))) {
298 /* BIOS 80-wire bit or
299 * UDMA w/ < 60ns/cycle
300 */
301 via_80w |= (1 << (1 - (i >> 4)));
302 }
303 break;
304
305 case VIA_UDMA_133:
306 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
307 for (i = 24; i >= 0; i -= 8)
308 if (((u >> i) & 0x10) ||
309 (((u >> i) & 0x20) &&
310 (((u >> i) & 7) < 6))) {
311 /* BIOS 80-wire bit or
312 * UDMA w/ < 60ns/cycle
313 */
314 via_80w |= (1 << (1 - (i >> 4)));
315 }
316 break;
317
318 }
319
320 /* Disable Clk66 */
321 if (via_config->flags & VIA_BAD_CLK66) {
322 /* Would cause trouble on 596a and 686 */ 296 /* Would cause trouble on 596a and 686 */
323 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); 297 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
324 pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008); 298 pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008);
@@ -388,10 +362,75 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
388 return 0; 362 return 0;
389} 363}
390 364
365/*
366 * Check and handle 80-wire cable presence
367 */
368static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev)
369{
370 unsigned int u;
371 int i;
372 pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
373
374 switch (vdev->via_config->flags & VIA_UDMA) {
375
376 case VIA_UDMA_66:
377 for (i = 24; i >= 0; i -= 8)
378 if (((u >> (i & 16)) & 8) &&
379 ((u >> i) & 0x20) &&
380 (((u >> i) & 7) < 2)) {
381 /*
382 * 2x PCI clock and
383 * UDMA w/ < 3T/cycle
384 */
385 vdev->via_80w |= (1 << (1 - (i >> 4)));
386 }
387 break;
388
389 case VIA_UDMA_100:
390 for (i = 24; i >= 0; i -= 8)
391 if (((u >> i) & 0x10) ||
392 (((u >> i) & 0x20) &&
393 (((u >> i) & 7) < 4))) {
394 /* BIOS 80-wire bit or
395 * UDMA w/ < 60ns/cycle
396 */
397 vdev->via_80w |= (1 << (1 - (i >> 4)));
398 }
399 break;
400
401 case VIA_UDMA_133:
402 for (i = 24; i >= 0; i -= 8)
403 if (((u >> i) & 0x10) ||
404 (((u >> i) & 0x20) &&
405 (((u >> i) & 7) < 6))) {
406 /* BIOS 80-wire bit or
407 * UDMA w/ < 60ns/cycle
408 */
409 vdev->via_80w |= (1 << (1 - (i >> 4)));
410 }
411 break;
412
413 }
414}
415
391static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) 416static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
392{ 417{
418 struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev),
419 GFP_KERNEL);
420 struct pci_dev *isa = NULL;
393 int i; 421 int i;
394 422
423 if (vdev == NULL) {
424 printk(KERN_ERR "VP_IDE: out of memory :(\n");
425 return;
426 }
427
428 memset(vdev, 0, sizeof(struct via82cxxx_dev));
429 ide_set_hwifdata(hwif, vdev);
430
431 vdev->via_config = via_config_find(&isa);
432 via_cable_detect(hwif->pci_dev, vdev);
433
395 hwif->autodma = 0; 434 hwif->autodma = 0;
396 435
397 hwif->tuneproc = &via82cxxx_tune_drive; 436 hwif->tuneproc = &via82cxxx_tune_drive;
@@ -406,7 +445,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
406 445
407 for (i = 0; i < 2; i++) { 446 for (i = 0; i < 2; i++) {
408 hwif->drives[i].io_32bit = 1; 447 hwif->drives[i].io_32bit = 1;
409 hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1; 448 hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
410 hwif->drives[i].autotune = 1; 449 hwif->drives[i].autotune = 1;
411 hwif->drives[i].dn = hwif->channel * 2 + i; 450 hwif->drives[i].dn = hwif->channel * 2 + i;
412 } 451 }
@@ -420,7 +459,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
420 hwif->swdma_mask = 0x07; 459 hwif->swdma_mask = 0x07;
421 460
422 if (!hwif->udma_four) 461 if (!hwif->udma_four)
423 hwif->udma_four = (via_80w >> hwif->channel) & 1; 462 hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1;
424 hwif->ide_dma_check = &via82cxxx_ide_dma_check; 463 hwif->ide_dma_check = &via82cxxx_ide_dma_check;
425 if (!noautodma) 464 if (!noautodma)
426 hwif->autodma = 1; 465 hwif->autodma = 1;