diff options
Diffstat (limited to 'drivers/ide/pmac.c')
-rw-r--r-- | drivers/ide/pmac.c | 101 |
1 files changed, 54 insertions, 47 deletions
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 2bfcfedaa076..052b9bf1f8fb 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c | |||
@@ -404,8 +404,6 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time) | |||
404 | #define IDE_WAKEUP_DELAY (1*HZ) | 404 | #define IDE_WAKEUP_DELAY (1*HZ) |
405 | 405 | ||
406 | static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *); | 406 | static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *); |
407 | static void pmac_ide_selectproc(ide_drive_t *drive); | ||
408 | static void pmac_ide_kauai_selectproc(ide_drive_t *drive); | ||
409 | 407 | ||
410 | #define PMAC_IDE_REG(x) \ | 408 | #define PMAC_IDE_REG(x) \ |
411 | ((void __iomem *)((drive)->hwif->io_ports.data_addr + (x))) | 409 | ((void __iomem *)((drive)->hwif->io_ports.data_addr + (x))) |
@@ -415,8 +413,7 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive); | |||
415 | * timing register when selecting that unit. This version is for | 413 | * timing register when selecting that unit. This version is for |
416 | * ASICs with a single timing register | 414 | * ASICs with a single timing register |
417 | */ | 415 | */ |
418 | static void | 416 | static void pmac_ide_apply_timings(ide_drive_t *drive) |
419 | pmac_ide_selectproc(ide_drive_t *drive) | ||
420 | { | 417 | { |
421 | ide_hwif_t *hwif = drive->hwif; | 418 | ide_hwif_t *hwif = drive->hwif; |
422 | pmac_ide_hwif_t *pmif = | 419 | pmac_ide_hwif_t *pmif = |
@@ -434,8 +431,7 @@ pmac_ide_selectproc(ide_drive_t *drive) | |||
434 | * timing register when selecting that unit. This version is for | 431 | * timing register when selecting that unit. This version is for |
435 | * ASICs with a dual timing register (Kauai) | 432 | * ASICs with a dual timing register (Kauai) |
436 | */ | 433 | */ |
437 | static void | 434 | static void pmac_ide_kauai_apply_timings(ide_drive_t *drive) |
438 | pmac_ide_kauai_selectproc(ide_drive_t *drive) | ||
439 | { | 435 | { |
440 | ide_hwif_t *hwif = drive->hwif; | 436 | ide_hwif_t *hwif = drive->hwif; |
441 | pmac_ide_hwif_t *pmif = | 437 | pmac_ide_hwif_t *pmif = |
@@ -464,9 +460,25 @@ pmac_ide_do_update_timings(ide_drive_t *drive) | |||
464 | if (pmif->kind == controller_sh_ata6 || | 460 | if (pmif->kind == controller_sh_ata6 || |
465 | pmif->kind == controller_un_ata6 || | 461 | pmif->kind == controller_un_ata6 || |
466 | pmif->kind == controller_k2_ata6) | 462 | pmif->kind == controller_k2_ata6) |
467 | pmac_ide_kauai_selectproc(drive); | 463 | pmac_ide_kauai_apply_timings(drive); |
468 | else | 464 | else |
469 | pmac_ide_selectproc(drive); | 465 | pmac_ide_apply_timings(drive); |
466 | } | ||
467 | |||
468 | static void pmac_dev_select(ide_drive_t *drive) | ||
469 | { | ||
470 | pmac_ide_apply_timings(drive); | ||
471 | |||
472 | writeb(drive->select | ATA_DEVICE_OBS, | ||
473 | (void __iomem *)drive->hwif->io_ports.device_addr); | ||
474 | } | ||
475 | |||
476 | static void pmac_kauai_dev_select(ide_drive_t *drive) | ||
477 | { | ||
478 | pmac_ide_kauai_apply_timings(drive); | ||
479 | |||
480 | writeb(drive->select | ATA_DEVICE_OBS, | ||
481 | (void __iomem *)drive->hwif->io_ports.device_addr); | ||
470 | } | 482 | } |
471 | 483 | ||
472 | static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd) | 484 | static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd) |
@@ -476,17 +488,8 @@ static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd) | |||
476 | + IDE_TIMING_CONFIG)); | 488 | + IDE_TIMING_CONFIG)); |
477 | } | 489 | } |
478 | 490 | ||
479 | static void pmac_set_irq(ide_hwif_t *hwif, int on) | 491 | static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl) |
480 | { | 492 | { |
481 | u8 ctl = ATA_DEVCTL_OBS; | ||
482 | |||
483 | if (on == 4) { /* hack for SRST */ | ||
484 | ctl |= 4; | ||
485 | on &= ~4; | ||
486 | } | ||
487 | |||
488 | ctl |= on ? 0 : 2; | ||
489 | |||
490 | writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); | 493 | writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); |
491 | (void)readl((void __iomem *)(hwif->io_ports.data_addr | 494 | (void)readl((void __iomem *)(hwif->io_ports.data_addr |
492 | + IDE_TIMING_CONFIG)); | 495 | + IDE_TIMING_CONFIG)); |
@@ -916,10 +919,18 @@ static u8 pmac_ide_cable_detect(ide_hwif_t *hwif) | |||
916 | (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); | 919 | (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); |
917 | struct device_node *np = pmif->node; | 920 | struct device_node *np = pmif->node; |
918 | const char *cable = of_get_property(np, "cable-type", NULL); | 921 | const char *cable = of_get_property(np, "cable-type", NULL); |
922 | struct device_node *root = of_find_node_by_path("/"); | ||
923 | const char *model = of_get_property(root, "model", NULL); | ||
919 | 924 | ||
920 | /* Get cable type from device-tree. */ | 925 | /* Get cable type from device-tree. */ |
921 | if (cable && !strncmp(cable, "80-", 3)) | 926 | if (cable && !strncmp(cable, "80-", 3)) { |
922 | return ATA_CBL_PATA80; | 927 | /* Some drives fail to detect 80c cable in PowerBook */ |
928 | /* These machine use proprietary short IDE cable anyway */ | ||
929 | if (!strncmp(model, "PowerBook", 9)) | ||
930 | return ATA_CBL_PATA40_SHORT; | ||
931 | else | ||
932 | return ATA_CBL_PATA80; | ||
933 | } | ||
923 | 934 | ||
924 | /* | 935 | /* |
925 | * G5's seem to have incorrect cable type in device-tree. | 936 | * G5's seem to have incorrect cable type in device-tree. |
@@ -954,9 +965,9 @@ static const struct ide_tp_ops pmac_tp_ops = { | |||
954 | .exec_command = pmac_exec_command, | 965 | .exec_command = pmac_exec_command, |
955 | .read_status = ide_read_status, | 966 | .read_status = ide_read_status, |
956 | .read_altstatus = ide_read_altstatus, | 967 | .read_altstatus = ide_read_altstatus, |
968 | .write_devctl = pmac_write_devctl, | ||
957 | 969 | ||
958 | .set_irq = pmac_set_irq, | 970 | .dev_select = pmac_dev_select, |
959 | |||
960 | .tf_load = ide_tf_load, | 971 | .tf_load = ide_tf_load, |
961 | .tf_read = ide_tf_read, | 972 | .tf_read = ide_tf_read, |
962 | 973 | ||
@@ -964,19 +975,24 @@ static const struct ide_tp_ops pmac_tp_ops = { | |||
964 | .output_data = ide_output_data, | 975 | .output_data = ide_output_data, |
965 | }; | 976 | }; |
966 | 977 | ||
967 | static const struct ide_port_ops pmac_ide_ata6_port_ops = { | 978 | static const struct ide_tp_ops pmac_ata6_tp_ops = { |
968 | .init_dev = pmac_ide_init_dev, | 979 | .exec_command = pmac_exec_command, |
969 | .set_pio_mode = pmac_ide_set_pio_mode, | 980 | .read_status = ide_read_status, |
970 | .set_dma_mode = pmac_ide_set_dma_mode, | 981 | .read_altstatus = ide_read_altstatus, |
971 | .selectproc = pmac_ide_kauai_selectproc, | 982 | .write_devctl = pmac_write_devctl, |
972 | .cable_detect = pmac_ide_cable_detect, | 983 | |
984 | .dev_select = pmac_kauai_dev_select, | ||
985 | .tf_load = ide_tf_load, | ||
986 | .tf_read = ide_tf_read, | ||
987 | |||
988 | .input_data = ide_input_data, | ||
989 | .output_data = ide_output_data, | ||
973 | }; | 990 | }; |
974 | 991 | ||
975 | static const struct ide_port_ops pmac_ide_ata4_port_ops = { | 992 | static const struct ide_port_ops pmac_ide_ata4_port_ops = { |
976 | .init_dev = pmac_ide_init_dev, | 993 | .init_dev = pmac_ide_init_dev, |
977 | .set_pio_mode = pmac_ide_set_pio_mode, | 994 | .set_pio_mode = pmac_ide_set_pio_mode, |
978 | .set_dma_mode = pmac_ide_set_dma_mode, | 995 | .set_dma_mode = pmac_ide_set_dma_mode, |
979 | .selectproc = pmac_ide_selectproc, | ||
980 | .cable_detect = pmac_ide_cable_detect, | 996 | .cable_detect = pmac_ide_cable_detect, |
981 | }; | 997 | }; |
982 | 998 | ||
@@ -984,7 +1000,6 @@ static const struct ide_port_ops pmac_ide_port_ops = { | |||
984 | .init_dev = pmac_ide_init_dev, | 1000 | .init_dev = pmac_ide_init_dev, |
985 | .set_pio_mode = pmac_ide_set_pio_mode, | 1001 | .set_pio_mode = pmac_ide_set_pio_mode, |
986 | .set_dma_mode = pmac_ide_set_dma_mode, | 1002 | .set_dma_mode = pmac_ide_set_dma_mode, |
987 | .selectproc = pmac_ide_selectproc, | ||
988 | }; | 1003 | }; |
989 | 1004 | ||
990 | static const struct ide_dma_ops pmac_dma_ops; | 1005 | static const struct ide_dma_ops pmac_dma_ops; |
@@ -1021,15 +1036,18 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw) | |||
1021 | pmif->broken_dma = pmif->broken_dma_warn = 0; | 1036 | pmif->broken_dma = pmif->broken_dma_warn = 0; |
1022 | if (of_device_is_compatible(np, "shasta-ata")) { | 1037 | if (of_device_is_compatible(np, "shasta-ata")) { |
1023 | pmif->kind = controller_sh_ata6; | 1038 | pmif->kind = controller_sh_ata6; |
1024 | d.port_ops = &pmac_ide_ata6_port_ops; | 1039 | d.tp_ops = &pmac_ata6_tp_ops; |
1040 | d.port_ops = &pmac_ide_ata4_port_ops; | ||
1025 | d.udma_mask = ATA_UDMA6; | 1041 | d.udma_mask = ATA_UDMA6; |
1026 | } else if (of_device_is_compatible(np, "kauai-ata")) { | 1042 | } else if (of_device_is_compatible(np, "kauai-ata")) { |
1027 | pmif->kind = controller_un_ata6; | 1043 | pmif->kind = controller_un_ata6; |
1028 | d.port_ops = &pmac_ide_ata6_port_ops; | 1044 | d.tp_ops = &pmac_ata6_tp_ops; |
1045 | d.port_ops = &pmac_ide_ata4_port_ops; | ||
1029 | d.udma_mask = ATA_UDMA5; | 1046 | d.udma_mask = ATA_UDMA5; |
1030 | } else if (of_device_is_compatible(np, "K2-UATA")) { | 1047 | } else if (of_device_is_compatible(np, "K2-UATA")) { |
1031 | pmif->kind = controller_k2_ata6; | 1048 | pmif->kind = controller_k2_ata6; |
1032 | d.port_ops = &pmac_ide_ata6_port_ops; | 1049 | d.tp_ops = &pmac_ata6_tp_ops; |
1050 | d.port_ops = &pmac_ide_ata4_port_ops; | ||
1033 | d.udma_mask = ATA_UDMA5; | 1051 | d.udma_mask = ATA_UDMA5; |
1034 | } else if (of_device_is_compatible(np, "keylargo-ata")) { | 1052 | } else if (of_device_is_compatible(np, "keylargo-ata")) { |
1035 | if (strcmp(np->name, "ata-4") == 0) { | 1053 | if (strcmp(np->name, "ata-4") == 0) { |
@@ -1455,7 +1473,7 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) | |||
1455 | "switching to PIO on Ohare chipset\n", drive->name); | 1473 | "switching to PIO on Ohare chipset\n", drive->name); |
1456 | pmif->broken_dma_warn = 1; | 1474 | pmif->broken_dma_warn = 1; |
1457 | } | 1475 | } |
1458 | goto use_pio_instead; | 1476 | return 0; |
1459 | } | 1477 | } |
1460 | while (cur_len) { | 1478 | while (cur_len) { |
1461 | unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00; | 1479 | unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00; |
@@ -1463,7 +1481,7 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) | |||
1463 | if (count++ >= MAX_DCMDS) { | 1481 | if (count++ >= MAX_DCMDS) { |
1464 | printk(KERN_WARNING "%s: DMA table too small\n", | 1482 | printk(KERN_WARNING "%s: DMA table too small\n", |
1465 | drive->name); | 1483 | drive->name); |
1466 | goto use_pio_instead; | 1484 | return 0; |
1467 | } | 1485 | } |
1468 | st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE); | 1486 | st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE); |
1469 | st_le16(&table->req_count, tc); | 1487 | st_le16(&table->req_count, tc); |
@@ -1492,9 +1510,6 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) | |||
1492 | 1510 | ||
1493 | printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name); | 1511 | printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name); |
1494 | 1512 | ||
1495 | use_pio_instead: | ||
1496 | ide_destroy_dmatable(drive); | ||
1497 | |||
1498 | return 0; /* revert to PIO for this request */ | 1513 | return 0; /* revert to PIO for this request */ |
1499 | } | 1514 | } |
1500 | 1515 | ||
@@ -1510,10 +1525,8 @@ static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) | |||
1510 | u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4); | 1525 | u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4); |
1511 | u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE); | 1526 | u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE); |
1512 | 1527 | ||
1513 | if (pmac_ide_build_dmatable(drive, cmd) == 0) { | 1528 | if (pmac_ide_build_dmatable(drive, cmd) == 0) |
1514 | ide_map_sg(drive, cmd); | ||
1515 | return 1; | 1529 | return 1; |
1516 | } | ||
1517 | 1530 | ||
1518 | /* Apple adds 60ns to wrDataSetup on reads */ | 1531 | /* Apple adds 60ns to wrDataSetup on reads */ |
1519 | if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { | 1532 | if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { |
@@ -1522,8 +1535,6 @@ static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) | |||
1522 | (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG)); | 1535 | (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG)); |
1523 | } | 1536 | } |
1524 | 1537 | ||
1525 | drive->waiting_for_dma = 1; | ||
1526 | |||
1527 | return 0; | 1538 | return 0; |
1528 | } | 1539 | } |
1529 | 1540 | ||
@@ -1558,12 +1569,9 @@ pmac_ide_dma_end (ide_drive_t *drive) | |||
1558 | volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; | 1569 | volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; |
1559 | u32 dstat; | 1570 | u32 dstat; |
1560 | 1571 | ||
1561 | drive->waiting_for_dma = 0; | ||
1562 | dstat = readl(&dma->status); | 1572 | dstat = readl(&dma->status); |
1563 | writel(((RUN|WAKE|DEAD) << 16), &dma->control); | 1573 | writel(((RUN|WAKE|DEAD) << 16), &dma->control); |
1564 | 1574 | ||
1565 | ide_destroy_dmatable(drive); | ||
1566 | |||
1567 | /* verify good dma status. we don't check for ACTIVE beeing 0. We should... | 1575 | /* verify good dma status. we don't check for ACTIVE beeing 0. We should... |
1568 | * in theory, but with ATAPI decices doing buffer underruns, that would | 1576 | * in theory, but with ATAPI decices doing buffer underruns, that would |
1569 | * cause us to disable DMA, which isn't what we want | 1577 | * cause us to disable DMA, which isn't what we want |
@@ -1650,7 +1658,6 @@ static const struct ide_dma_ops pmac_dma_ops = { | |||
1650 | .dma_start = pmac_ide_dma_start, | 1658 | .dma_start = pmac_ide_dma_start, |
1651 | .dma_end = pmac_ide_dma_end, | 1659 | .dma_end = pmac_ide_dma_end, |
1652 | .dma_test_irq = pmac_ide_dma_test_irq, | 1660 | .dma_test_irq = pmac_ide_dma_test_irq, |
1653 | .dma_timeout = ide_dma_timeout, | ||
1654 | .dma_lost_irq = pmac_ide_dma_lost_irq, | 1661 | .dma_lost_irq = pmac_ide_dma_lost_irq, |
1655 | }; | 1662 | }; |
1656 | 1663 | ||