diff options
Diffstat (limited to 'drivers/ide/pci/cmd64x.c')
-rw-r--r-- | drivers/ide/pci/cmd64x.c | 110 |
1 files changed, 52 insertions, 58 deletions
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 5411ded791bb..5fd252e6ed08 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c | |||
@@ -223,7 +223,7 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
223 | (void) pci_write_config_byte(dev, pciU, regU); | 223 | (void) pci_write_config_byte(dev, pciU, regU); |
224 | } | 224 | } |
225 | 225 | ||
226 | static int cmd648_ide_dma_end (ide_drive_t *drive) | 226 | static int cmd648_dma_end(ide_drive_t *drive) |
227 | { | 227 | { |
228 | ide_hwif_t *hwif = HWIF(drive); | 228 | ide_hwif_t *hwif = HWIF(drive); |
229 | unsigned long base = hwif->dma_base - (hwif->channel * 8); | 229 | unsigned long base = hwif->dma_base - (hwif->channel * 8); |
@@ -239,7 +239,7 @@ static int cmd648_ide_dma_end (ide_drive_t *drive) | |||
239 | return err; | 239 | return err; |
240 | } | 240 | } |
241 | 241 | ||
242 | static int cmd64x_ide_dma_end (ide_drive_t *drive) | 242 | static int cmd64x_dma_end(ide_drive_t *drive) |
243 | { | 243 | { |
244 | ide_hwif_t *hwif = HWIF(drive); | 244 | ide_hwif_t *hwif = HWIF(drive); |
245 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 245 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
@@ -256,7 +256,7 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive) | |||
256 | return err; | 256 | return err; |
257 | } | 257 | } |
258 | 258 | ||
259 | static int cmd648_ide_dma_test_irq (ide_drive_t *drive) | 259 | static int cmd648_dma_test_irq(ide_drive_t *drive) |
260 | { | 260 | { |
261 | ide_hwif_t *hwif = HWIF(drive); | 261 | ide_hwif_t *hwif = HWIF(drive); |
262 | unsigned long base = hwif->dma_base - (hwif->channel * 8); | 262 | unsigned long base = hwif->dma_base - (hwif->channel * 8); |
@@ -279,7 +279,7 @@ static int cmd648_ide_dma_test_irq (ide_drive_t *drive) | |||
279 | return 0; | 279 | return 0; |
280 | } | 280 | } |
281 | 281 | ||
282 | static int cmd64x_ide_dma_test_irq (ide_drive_t *drive) | 282 | static int cmd64x_dma_test_irq(ide_drive_t *drive) |
283 | { | 283 | { |
284 | ide_hwif_t *hwif = HWIF(drive); | 284 | ide_hwif_t *hwif = HWIF(drive); |
285 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 285 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
@@ -310,7 +310,7 @@ static int cmd64x_ide_dma_test_irq (ide_drive_t *drive) | |||
310 | * event order for DMA transfers. | 310 | * event order for DMA transfers. |
311 | */ | 311 | */ |
312 | 312 | ||
313 | static int cmd646_1_ide_dma_end (ide_drive_t *drive) | 313 | static int cmd646_1_dma_end(ide_drive_t *drive) |
314 | { | 314 | { |
315 | ide_hwif_t *hwif = HWIF(drive); | 315 | ide_hwif_t *hwif = HWIF(drive); |
316 | u8 dma_stat = 0, dma_cmd = 0; | 316 | u8 dma_stat = 0, dma_cmd = 0; |
@@ -385,62 +385,33 @@ static u8 __devinit cmd64x_cable_detect(ide_hwif_t *hwif) | |||
385 | } | 385 | } |
386 | } | 386 | } |
387 | 387 | ||
388 | static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) | ||
389 | { | ||
390 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
391 | |||
392 | if (!hwif->dma_base) | ||
393 | return; | ||
394 | |||
395 | /* | ||
396 | * UltraDMA only supported on PCI646U and PCI646U2, which | ||
397 | * correspond to revisions 0x03, 0x05 and 0x07 respectively. | ||
398 | * Actually, although the CMD tech support people won't | ||
399 | * tell me the details, the 0x03 revision cannot support | ||
400 | * UDMA correctly without hardware modifications, and even | ||
401 | * then it only works with Quantum disks due to some | ||
402 | * hold time assumptions in the 646U part which are fixed | ||
403 | * in the 646U2. | ||
404 | * | ||
405 | * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. | ||
406 | */ | ||
407 | if (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 5) | ||
408 | hwif->ultra_mask = 0x00; | ||
409 | |||
410 | switch (dev->device) { | ||
411 | case PCI_DEVICE_ID_CMD_648: | ||
412 | case PCI_DEVICE_ID_CMD_649: | ||
413 | alt_irq_bits: | ||
414 | hwif->ide_dma_end = &cmd648_ide_dma_end; | ||
415 | hwif->ide_dma_test_irq = &cmd648_ide_dma_test_irq; | ||
416 | break; | ||
417 | case PCI_DEVICE_ID_CMD_646: | ||
418 | if (dev->revision == 0x01) { | ||
419 | hwif->ide_dma_end = &cmd646_1_ide_dma_end; | ||
420 | break; | ||
421 | } else if (dev->revision >= 0x03) | ||
422 | goto alt_irq_bits; | ||
423 | /* fall thru */ | ||
424 | default: | ||
425 | hwif->ide_dma_end = &cmd64x_ide_dma_end; | ||
426 | hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; | ||
427 | break; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | static const struct ide_port_ops cmd64x_port_ops = { | 388 | static const struct ide_port_ops cmd64x_port_ops = { |
432 | .set_pio_mode = cmd64x_set_pio_mode, | 389 | .set_pio_mode = cmd64x_set_pio_mode, |
433 | .set_dma_mode = cmd64x_set_dma_mode, | 390 | .set_dma_mode = cmd64x_set_dma_mode, |
434 | .cable_detect = cmd64x_cable_detect, | 391 | .cable_detect = cmd64x_cable_detect, |
435 | }; | 392 | }; |
436 | 393 | ||
394 | static struct ide_dma_ops cmd64x_dma_ops = { | ||
395 | .dma_end = cmd64x_dma_end, | ||
396 | .dma_test_irq = cmd64x_dma_test_irq, | ||
397 | }; | ||
398 | |||
399 | static struct ide_dma_ops cmd646_rev1_dma_ops = { | ||
400 | .dma_end = cmd646_1_dma_end, | ||
401 | }; | ||
402 | |||
403 | static struct ide_dma_ops cmd648_dma_ops = { | ||
404 | .dma_end = cmd648_dma_end, | ||
405 | .dma_test_irq = cmd648_dma_test_irq, | ||
406 | }; | ||
407 | |||
437 | static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | 408 | static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { |
438 | { /* 0 */ | 409 | { /* 0 */ |
439 | .name = "CMD643", | 410 | .name = "CMD643", |
440 | .init_chipset = init_chipset_cmd64x, | 411 | .init_chipset = init_chipset_cmd64x, |
441 | .init_hwif = init_hwif_cmd64x, | ||
442 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, | 412 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, |
443 | .port_ops = &cmd64x_port_ops, | 413 | .port_ops = &cmd64x_port_ops, |
414 | .dma_ops = &cmd64x_dma_ops, | ||
444 | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | | 415 | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | |
445 | IDE_HFLAG_ABUSE_PREFETCH, | 416 | IDE_HFLAG_ABUSE_PREFETCH, |
446 | .pio_mask = ATA_PIO5, | 417 | .pio_mask = ATA_PIO5, |
@@ -449,10 +420,10 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
449 | },{ /* 1 */ | 420 | },{ /* 1 */ |
450 | .name = "CMD646", | 421 | .name = "CMD646", |
451 | .init_chipset = init_chipset_cmd64x, | 422 | .init_chipset = init_chipset_cmd64x, |
452 | .init_hwif = init_hwif_cmd64x, | ||
453 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | 423 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
454 | .chipset = ide_cmd646, | 424 | .chipset = ide_cmd646, |
455 | .port_ops = &cmd64x_port_ops, | 425 | .port_ops = &cmd64x_port_ops, |
426 | .dma_ops = &cmd648_dma_ops, | ||
456 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, | 427 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, |
457 | .pio_mask = ATA_PIO5, | 428 | .pio_mask = ATA_PIO5, |
458 | .mwdma_mask = ATA_MWDMA2, | 429 | .mwdma_mask = ATA_MWDMA2, |
@@ -460,9 +431,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
460 | },{ /* 2 */ | 431 | },{ /* 2 */ |
461 | .name = "CMD648", | 432 | .name = "CMD648", |
462 | .init_chipset = init_chipset_cmd64x, | 433 | .init_chipset = init_chipset_cmd64x, |
463 | .init_hwif = init_hwif_cmd64x, | ||
464 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | 434 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
465 | .port_ops = &cmd64x_port_ops, | 435 | .port_ops = &cmd64x_port_ops, |
436 | .dma_ops = &cmd648_dma_ops, | ||
466 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, | 437 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, |
467 | .pio_mask = ATA_PIO5, | 438 | .pio_mask = ATA_PIO5, |
468 | .mwdma_mask = ATA_MWDMA2, | 439 | .mwdma_mask = ATA_MWDMA2, |
@@ -470,9 +441,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
470 | },{ /* 3 */ | 441 | },{ /* 3 */ |
471 | .name = "CMD649", | 442 | .name = "CMD649", |
472 | .init_chipset = init_chipset_cmd64x, | 443 | .init_chipset = init_chipset_cmd64x, |
473 | .init_hwif = init_hwif_cmd64x, | ||
474 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | 444 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
475 | .port_ops = &cmd64x_port_ops, | 445 | .port_ops = &cmd64x_port_ops, |
446 | .dma_ops = &cmd648_dma_ops, | ||
476 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, | 447 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, |
477 | .pio_mask = ATA_PIO5, | 448 | .pio_mask = ATA_PIO5, |
478 | .mwdma_mask = ATA_MWDMA2, | 449 | .mwdma_mask = ATA_MWDMA2, |
@@ -487,12 +458,35 @@ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_devic | |||
487 | 458 | ||
488 | d = cmd64x_chipsets[idx]; | 459 | d = cmd64x_chipsets[idx]; |
489 | 460 | ||
490 | /* | 461 | if (idx == 1) { |
491 | * The original PCI0646 didn't have the primary channel enable bit, | 462 | /* |
492 | * it appeared starting with PCI0646U (i.e. revision ID 3). | 463 | * UltraDMA only supported on PCI646U and PCI646U2, which |
493 | */ | 464 | * correspond to revisions 0x03, 0x05 and 0x07 respectively. |
494 | if (idx == 1 && dev->revision < 3) | 465 | * Actually, although the CMD tech support people won't |
495 | d.enablebits[0].reg = 0; | 466 | * tell me the details, the 0x03 revision cannot support |
467 | * UDMA correctly without hardware modifications, and even | ||
468 | * then it only works with Quantum disks due to some | ||
469 | * hold time assumptions in the 646U part which are fixed | ||
470 | * in the 646U2. | ||
471 | * | ||
472 | * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. | ||
473 | */ | ||
474 | if (dev->revision < 5) { | ||
475 | d.udma_mask = 0x00; | ||
476 | /* | ||
477 | * The original PCI0646 didn't have the primary | ||
478 | * channel enable bit, it appeared starting with | ||
479 | * PCI0646U (i.e. revision ID 3). | ||
480 | */ | ||
481 | if (dev->revision < 3) { | ||
482 | d.enablebits[0].reg = 0; | ||
483 | if (dev->revision == 1) | ||
484 | d.dma_ops = &cmd646_rev1_dma_ops; | ||
485 | else | ||
486 | d.dma_ops = &cmd64x_dma_ops; | ||
487 | } | ||
488 | } | ||
489 | } | ||
496 | 490 | ||
497 | return ide_setup_pci_device(dev, &d); | 491 | return ide_setup_pci_device(dev, &d); |
498 | } | 492 | } |