aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-io.c10
-rw-r--r--drivers/ide/ide-iops.c2
-rw-r--r--drivers/ide/ppc/pmac.c80
-rw-r--r--include/linux/ide.h6
4 files changed, 18 insertions, 80 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 9560a8f4a86c..4cece930114c 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -836,9 +836,17 @@ static ide_startstop_t do_special (ide_drive_t *drive)
836 if (set_pio_mode_abuse(drive->hwif, req_pio)) { 836 if (set_pio_mode_abuse(drive->hwif, req_pio)) {
837 if (hwif->set_pio_mode) 837 if (hwif->set_pio_mode)
838 hwif->set_pio_mode(drive, req_pio); 838 hwif->set_pio_mode(drive, req_pio);
839 } else 839 } else {
840 int keep_dma = drive->using_dma;
841
840 ide_set_pio(drive, req_pio); 842 ide_set_pio(drive, req_pio);
841 843
844 if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
845 if (keep_dma)
846 hwif->ide_dma_on(drive);
847 }
848 }
849
842 return ide_stopped; 850 return ide_stopped;
843 } else { 851 } else {
844 if (drive->media == ide_disk) 852 if (drive->media == ide_disk)
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index f7e976c0c2f3..e5fc2e505959 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -483,7 +483,7 @@ EXPORT_SYMBOL(drive_is_ready);
483 * setting a timer to wake up at half second intervals thereafter, 483 * setting a timer to wake up at half second intervals thereafter,
484 * until timeout is achieved, before timing out. 484 * until timeout is achieved, before timing out.
485 */ 485 */
486int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) 486static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
487{ 487{
488 ide_hwif_t *hwif = drive->hwif; 488 ide_hwif_t *hwif = drive->hwif;
489 unsigned long flags; 489 unsigned long flags;
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index c68e2472345a..24f73291c4d5 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -530,81 +530,6 @@ pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port)
530} 530}
531 531
532/* 532/*
533 * Send the SET_FEATURE IDE command to the drive and update drive->id with
534 * the new state. We currently don't use the generic routine as it used to
535 * cause various trouble, especially with older mediabays.
536 * This code is sometimes triggering a spurrious interrupt though, I need
537 * to sort that out sooner or later and see if I can finally get the
538 * common version to work properly in all cases
539 */
540static int
541pmac_ide_do_setfeature(ide_drive_t *drive, u8 command)
542{
543 ide_hwif_t *hwif = HWIF(drive);
544 int result;
545 u8 stat;
546
547 disable_irq_nosync(hwif->irq);
548 udelay(1);
549 SELECT_DRIVE(drive);
550 SELECT_MASK(drive, 0);
551 udelay(1);
552 hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
553 hwif->OUTB(command, IDE_NSECTOR_REG);
554 hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG);
555 hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG);
556 result = __ide_wait_stat(drive, drive->ready_stat,
557 BUSY_STAT|DRQ_STAT|ERR_STAT,
558 WAIT_CMD, &stat);
559 if (result)
560 printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready "
561 "after SET_FEATURE !\n", drive->name);
562
563 SELECT_MASK(drive, 0);
564 if (result == 0) {
565 drive->id->dma_ultra &= ~0xFF00;
566 drive->id->dma_mword &= ~0x0F00;
567 drive->id->dma_1word &= ~0x0F00;
568 switch(command) {
569 case XFER_UDMA_7:
570 drive->id->dma_ultra |= 0x8080; break;
571 case XFER_UDMA_6:
572 drive->id->dma_ultra |= 0x4040; break;
573 case XFER_UDMA_5:
574 drive->id->dma_ultra |= 0x2020; break;
575 case XFER_UDMA_4:
576 drive->id->dma_ultra |= 0x1010; break;
577 case XFER_UDMA_3:
578 drive->id->dma_ultra |= 0x0808; break;
579 case XFER_UDMA_2:
580 drive->id->dma_ultra |= 0x0404; break;
581 case XFER_UDMA_1:
582 drive->id->dma_ultra |= 0x0202; break;
583 case XFER_UDMA_0:
584 drive->id->dma_ultra |= 0x0101; break;
585 case XFER_MW_DMA_2:
586 drive->id->dma_mword |= 0x0404; break;
587 case XFER_MW_DMA_1:
588 drive->id->dma_mword |= 0x0202; break;
589 case XFER_MW_DMA_0:
590 drive->id->dma_mword |= 0x0101; break;
591 case XFER_SW_DMA_2:
592 drive->id->dma_1word |= 0x0404; break;
593 case XFER_SW_DMA_1:
594 drive->id->dma_1word |= 0x0202; break;
595 case XFER_SW_DMA_0:
596 drive->id->dma_1word |= 0x0101; break;
597 default: break;
598 }
599 if (!drive->init_speed)
600 drive->init_speed = command;
601 drive->current_speed = command;
602 }
603 enable_irq(hwif->irq);
604 return result;
605}
606
607/*
608 * Old tuning functions (called on hdparm -p), sets up drive PIO timings 533 * Old tuning functions (called on hdparm -p), sets up drive PIO timings
609 */ 534 */
610static void 535static void
@@ -685,7 +610,7 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
685 drive->name, pio, *timings); 610 drive->name, pio, *timings);
686#endif 611#endif
687 612
688 if (pmac_ide_do_setfeature(drive, XFER_PIO_0 + pio)) 613 if (ide_config_drive_speed(drive, XFER_PIO_0 + pio))
689 return; 614 return;
690 615
691 pmac_ide_do_update_timings(drive); 616 pmac_ide_do_update_timings(drive);
@@ -948,7 +873,7 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed)
948 if (ret) 873 if (ret)
949 return ret; 874 return ret;
950 875
951 ret = pmac_ide_do_setfeature(drive, speed); 876 ret = ide_config_drive_speed(drive, speed);
952 if (ret) 877 if (ret)
953 return ret; 878 return ret;
954 879
@@ -1218,6 +1143,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
1218 hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; 1143 hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
1219 hwif->drives[0].unmask = 1; 1144 hwif->drives[0].unmask = 1;
1220 hwif->drives[1].unmask = 1; 1145 hwif->drives[1].unmask = 1;
1146 hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA;
1221 hwif->pio_mask = ATA_PIO4; 1147 hwif->pio_mask = ATA_PIO4;
1222 hwif->set_pio_mode = pmac_ide_set_pio_mode; 1148 hwif->set_pio_mode = pmac_ide_set_pio_mode;
1223 if (pmif->kind == controller_un_ata6 1149 if (pmif->kind == controller_un_ata6
diff --git a/include/linux/ide.h b/include/linux/ide.h
index d86115e9aa2c..6bb621203f30 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1153,7 +1153,6 @@ extern void SELECT_MASK(ide_drive_t *, int);
1153extern void QUIRK_LIST(ide_drive_t *); 1153extern void QUIRK_LIST(ide_drive_t *);
1154 1154
1155extern int drive_is_ready(ide_drive_t *); 1155extern int drive_is_ready(ide_drive_t *);
1156int __ide_wait_stat(ide_drive_t *, u8, u8, unsigned long);
1157 1156
1158/* 1157/*
1159 * taskfile io for disks for now...and builds request from ide_ioctl 1158 * taskfile io for disks for now...and builds request from ide_ioctl
@@ -1253,6 +1252,11 @@ enum {
1253 IDE_HFLAG_ABUSE_FAST_DEVSEL = (1 << 5), 1252 IDE_HFLAG_ABUSE_FAST_DEVSEL = (1 << 5),
1254 /* use 100-102 and 200-202 PIO values to set DMA modes */ 1253 /* use 100-102 and 200-202 PIO values to set DMA modes */
1255 IDE_HFLAG_ABUSE_DMA_MODES = (1 << 6), 1254 IDE_HFLAG_ABUSE_DMA_MODES = (1 << 6),
1255 /*
1256 * keep DMA setting when programming PIO mode, may be used only
1257 * for hosts which have separate PIO and DMA timings (ie. PMAC)
1258 */
1259 IDE_HFLAG_SET_PIO_MODE_KEEP_DMA = (1 << 7),
1256}; 1260};
1257 1261
1258typedef struct ide_pci_device_s { 1262typedef struct ide_pci_device_s {