]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] 2.5.13 IDE 53
authorMartin Dalecki <dalecki@evision-ventures.com>
Sun, 5 May 2002 08:03:45 +0000 (01:03 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 5 May 2002 08:03:45 +0000 (01:03 -0700)
 - Start splitting the functions for host chip handling in to separate entities.
   This change is quite sensitive and may cause some trouble but it's for
   certain worth it anyway, because it should for example provide a much better
   infrastructure for th handling of different architectures.

24 files changed:
drivers/ide/Config.in
drivers/ide/aec62xx.c
drivers/ide/alim15x3.c
drivers/ide/cmd64x.c
drivers/ide/cs5530.c
drivers/ide/hpt34x.c
drivers/ide/hpt366.c
drivers/ide/ide-cd.c
drivers/ide/ide-dma.c
drivers/ide/ide-floppy.c
drivers/ide/ide-pci.c
drivers/ide/ide-pmac.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/ns87415.c
drivers/ide/pdc202xx.c
drivers/ide/serverworks.c
drivers/ide/sis5513.c
drivers/ide/sl82c105.c
drivers/ide/tcq.c
drivers/ide/trm290.c
drivers/scsi/ide-scsi.c
include/linux/ide.h

index 14cd869542434388a0fb8c13b1e1c545825d0cd0..261bde462542aaf8b193c00812b1670980d49de2 100644 (file)
@@ -33,16 +33,16 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
    dep_tristate '  Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
    dep_tristate '  SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI
 
-   comment 'IDE chipset support'
+   comment 'ATA host chipset support'
    dep_bool '  CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640 $CONFIG_X86
    dep_bool '    CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED $CONFIG_BLK_DEV_CMD640
-   dep_bool '  ISA-PNP EIDE support' CONFIG_BLK_DEV_ISAPNP $CONFIG_ISAPNP
+   dep_bool '  ISA-PNP support' CONFIG_BLK_DEV_ISAPNP $CONFIG_ISAPNP
    if [ "$CONFIG_PCI" = "y" ]; then
       dep_bool '  RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_X86
-      bool '  Generic PCI IDE chipset support' CONFIG_BLK_DEV_IDEPCI
+      bool '  PCI host chipset support' CONFIG_BLK_DEV_IDEPCI
       if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then
         bool '    Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
-        bool '    Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ
+        bool '    Sharing PCI ATA interrupts support' CONFIG_IDEPCI_SHARE_IRQ
         bool '    Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI
         dep_bool '      Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI
          dep_bool '    Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
@@ -82,11 +82,9 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
         dep_bool '    SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
         dep_bool '    Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI
         dep_bool '    VIA chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI
+        dep_bool '    Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 $CONFIG_BLK_DEV_IDEDMA_PCI
       fi
 
-      if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
-        bool '    Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
-      fi
    fi
    if [ "$CONFIG_ALL_PPC" = "y" ]; then
       bool '    Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC
index 01baf5e3710f10e84e76c051280042a482563bdf..c58e9381407bfe365b8a48bc20a58b036de78938 100644 (file)
@@ -437,7 +437,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
 
        if (id && (id->capability & 1) && drive->channel->autodma) {
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+               if (udma_black_list(drive)) {
                        dma_func = ide_dma_off;
                        goto fast_ata_pio;
                }
@@ -459,7 +459,7 @@ try_dma_modes:
                                if (dma_func != ide_dma_on)
                                        goto no_dma_set;
                        }
-               } else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+               } else if (udma_white_list(drive)) {
                        if (id->eide_dma_time > 150) {
                                goto no_dma_set;
                        }
index 01763a1e3ab4874ae78302a38e5ce5e0140c15c6..6581c4c87afc0a473c25ca2811ff72fe5231f0a2 100644 (file)
@@ -441,7 +441,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
 
        if ((id != NULL) && ((id->capability & 1) != 0) && hwif->autodma) {
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+               if (udma_black_list(drive)) {
                        dma_func = ide_dma_off;
                        goto fast_ata_pio;
                }
@@ -463,7 +463,7 @@ try_dma_modes:
                                if (dma_func != ide_dma_on)
                                        goto no_dma_set;
                        }
-               } else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+               } else if (udma_white_list(drive)) {
                        if (id->eide_dma_time > 150) {
                                goto no_dma_set;
                        }
@@ -483,21 +483,25 @@ no_dma_set:
        return hwif->udma(dma_func, drive, NULL);
 }
 
+static int ali15x3_udma_write(struct ata_device *drive, struct request *rq)
+{
+       if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
+               return 1;       /* try PIO instead of DMA */
+
+       return ata_do_udma(0, drive, rq);
+}
+
 static int ali15x3_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
        switch(func) {
                case ide_dma_check:
                        return ali15x3_config_drive_for_dma(drive);
-               case ide_dma_write:
-                       if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
-                               return 1;       /* try PIO instead of DMA */
-                       break;
                default:
                        break;
        }
        return ide_dmaproc(func, drive, rq);    /* use standard DMA stuff */
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 unsigned int __init pci_init_ali15x3(struct pci_dev *dev)
 {
@@ -679,6 +683,7 @@ void __init ide_init_ali15x3(struct ata_channel *hwif)
                /*
                 * M1543C or newer for DMAing
                 */
+               hwif->udma_write = ali15x3_udma_write;
                hwif->udma = ali15x3_dmaproc;
                hwif->autodma = 1;
        }
index f6eeb1803ca297cd45307205d92cc72bc55b73a2..43bddcede58b493c4f364b8d34ec341b5a325687 100644 (file)
@@ -783,7 +783,7 @@ static int cmd64x_config_drive_for_dma(struct ata_device *drive)
        if ((id != NULL) && ((id->capability & 1) != 0) &&
            hwif->autodma && (drive->type == ATA_DISK)) {
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+               if (udma_black_list(drive)) {
                        dma_func = ide_dma_off;
                        goto fast_ata_pio;
                }
@@ -805,7 +805,7 @@ try_dma_modes:
                                if (dma_func != ide_dma_on)
                                        goto no_dma_set;
                        }
-               } else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+               } else if (udma_white_list(drive)) {
                        if (id->eide_dma_time > 150) {
                                goto no_dma_set;
                        }
@@ -837,6 +837,34 @@ static int cmd680_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
         return ide_dmaproc(func, drive, rq);
 }
 
+static int cmd64x_udma_stop(struct ata_device *drive)
+{
+       struct ata_channel *ch = drive->channel;
+       u8 dma_stat = 0;
+       unsigned long dma_base  = ch->dma_base;
+       struct pci_dev *dev     = ch->pci_dev;
+       u8 jack_slap            = ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
+
+       drive->waiting_for_dma = 0;
+       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
+       dma_stat = inb(dma_base+2);             /* get DMA status */
+       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
+       if (jack_slap) {
+               byte dma_intr = 0;
+               byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
+               byte dma_reg = (ch->unit) ? ARTTIM2 : CFR;
+               (void) pci_read_config_byte(dev, dma_reg, &dma_intr);
+               /*
+                * DAMN BMIDE is not connected to PCI space!
+                * Have to manually jack-slap that bitch!
+                * To allow the PCI side to read incoming interrupts.
+                */
+               (void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask);  /* clear the INTR bit */
+       }
+       udma_destroy_table(ch); /* purge DMA mappings */
+       return (dma_stat & 7) != 4;             /* verify good DMA status */
+}
+
 static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
        struct ata_channel *ch = drive->channel;
@@ -845,30 +873,10 @@ static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
        u8 mask = (ch->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
        unsigned long dma_base  = ch->dma_base;
        struct pci_dev *dev     = ch->pci_dev;
-       byte jack_slap          = ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
 
        switch (func) {
                case ide_dma_check:
                        return cmd64x_config_drive_for_dma(drive);
-               case ide_dma_end: /* returns 1 on error, 0 otherwise */
-                       drive->waiting_for_dma = 0;
-                       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
-                       dma_stat = inb(dma_base+2);             /* get DMA status */
-                       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
-                       if (jack_slap) {
-                               byte dma_intr = 0;
-                               byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
-                               byte dma_reg = (ch->unit) ? ARTTIM2 : CFR;
-                               (void) pci_read_config_byte(dev, dma_reg, &dma_intr);
-                               /*
-                                * DAMN BMIDE is not connected to PCI space!
-                                * Have to manually jack-slap that bitch!
-                                * To allow the PCI side to read incoming interrupts.
-                                */
-                               (void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask);  /* clear the INTR bit */
-                       }
-                       udma_destroy_table(ch); /* purge DMA mappings */
-                       return (dma_stat & 7) != 4;             /* verify good DMA status */
                case ide_dma_test_irq:  /* returns 1 if dma irq issued, 0 otherwise */
                        dma_stat = inb(dma_base+2);
                        (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
@@ -886,26 +894,29 @@ static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
        return ide_dmaproc(func, drive, rq);
 }
 
+static int cmd646_1_udma_stop(struct ata_device *drive)
+{
+       struct ata_channel *ch = drive->channel;
+       unsigned long dma_base = ch->dma_base;
+       u8 dma_stat;
+
+       drive->waiting_for_dma = 0;
+       dma_stat = inb(dma_base+2);             /* get DMA status */
+       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
+       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
+       udma_destroy_table(ch);                 /* and free any DMA resources */
+       return (dma_stat & 7) != 4;             /* verify good DMA status */
+}
+
 /*
  * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
  * event order for DMA transfers.
  */
 static int cmd646_1_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-       struct ata_channel *ch = drive->channel;
-       unsigned long dma_base = ch->dma_base;
-       byte dma_stat;
-
        switch (func) {
                case ide_dma_check:
                        return cmd64x_config_drive_for_dma(drive);
-               case ide_dma_end:
-                       drive->waiting_for_dma = 0;
-                       dma_stat = inb(dma_base+2);             /* get DMA status */
-                       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
-                       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
-                       udma_destroy_table(ch);                 /* and free any DMA resources */
-                       return (dma_stat & 7) != 4;             /* verify good DMA status */
                default:
                        break;
        }
@@ -1134,19 +1145,22 @@ void __init ide_init_cmd64x(struct ata_channel *hwif)
                case PCI_DEVICE_ID_CMD_649:
                case PCI_DEVICE_ID_CMD_648:
                case PCI_DEVICE_ID_CMD_643:
-                       hwif->udma      = &cmd64x_dmaproc;
-                       hwif->tuneproc  = &cmd64x_tuneproc;
-                       hwif->speedproc = &cmd64x_tune_chipset;
+                       hwif->udma_stop = cmd64x_udma_stop;
+                       hwif->udma      = cmd64x_dmaproc;
+                       hwif->tuneproc  = cmd64x_tuneproc;
+                       hwif->speedproc = cmd64x_tune_chipset;
                        break;
                case PCI_DEVICE_ID_CMD_646:
                        hwif->chipset = ide_cmd646;
                        if (class_rev == 0x01) {
+                               hwif->udma_stop = &cmd646_1_udma_stop;
                                hwif->udma = &cmd646_1_dmaproc;
                        } else {
-                               hwif->udma = &cmd64x_dmaproc;
+                               hwif->udma_stop = cmd64x_udma_stop;
+                               hwif->udma = cmd64x_dmaproc;
                        }
-                       hwif->tuneproc  = &cmd64x_tuneproc;
-                       hwif->speedproc = &cmd64x_tune_chipset;
+                       hwif->tuneproc  = cmd64x_tuneproc;
+                       hwif->speedproc = cmd64x_tune_chipset;
                        break;
                default:
                        break;
index 3980d61625306c3b49b0fed6c2952009d255c760..17485ff2f43ba68266c521ae214381088f90ca3c 100644 (file)
@@ -158,7 +158,7 @@ static int cs5530_config_dma (ide_drive_t *drive)
         */
        if (mate->present) {
                struct hd_driveid *mateid = mate->id;
-               if (mateid && (mateid->capability & 1) && !hwif->udma(ide_dma_bad_drive, mate, NULL)) {
+               if (mateid && (mateid->capability & 1) && !udma_black_list(mate)) {
                        if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7))
                                udma_ok = 1;
                        else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7))
@@ -172,7 +172,7 @@ static int cs5530_config_dma (ide_drive_t *drive)
         * Now see what the current drive is capable of,
         * selecting UDMA only if the mate said it was ok.
         */
-       if (id && (id->capability & 1) && hwif->autodma && !hwif->udma(ide_dma_bad_drive, drive, NULL)) {
+       if (id && (id->capability & 1) && hwif->autodma && !udma_black_list(drive)) {
                if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) {
                        if      (id->dma_ultra & 4)
                                mode = XFER_UDMA_2;
index bc4343233858089f93599111aa2ead165d29f038..2c2c04cd507150192f12f3ef3e6b27260318f2e7 100644 (file)
@@ -256,7 +256,7 @@ static int config_drive_xfer_rate(struct ata_device *drive, struct request *rq)
 
        if (id && (id->capability & 1) && drive->channel->autodma) {
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive, rq)) {
+               if (udma_black_list(drive)) {
                        dma_func = ide_dma_off;
                        goto fast_ata_pio;
                }
@@ -278,7 +278,7 @@ try_dma_modes:
                                if (dma_func != ide_dma_on)
                                        goto no_dma_set;
                        }
-               } else if (ide_dmaproc(ide_dma_good_drive, drive, rq)) {
+               } else if (udma_white_list(drive)) {
                        if (id->eide_dma_time > 150) {
                                goto no_dma_set;
                        }
@@ -304,6 +304,55 @@ no_dma_set:
        return drive->channel->udma(dma_func, drive, rq);
 }
 
+static int hpt34x_udma_stop(struct ata_device *drive)
+{
+       struct ata_channel *ch = drive->channel;
+       unsigned long dma_base = ch->dma_base;
+       u8 dma_stat;
+
+       drive->waiting_for_dma = 0;
+       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
+       dma_stat = inb(dma_base+2);             /* get DMA status */
+       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
+       udma_destroy_table(ch);                 /* purge DMA mappings */
+
+       return (dma_stat & 7) != 4;             /* verify good DMA status */
+}
+
+static int do_udma(unsigned int reading, struct ata_device *drive, struct request *rq)
+{
+       struct ata_channel *ch = drive->channel;
+       unsigned long dma_base = ch->dma_base;
+       unsigned int count;
+
+       if (!(count = udma_new_table(ch, rq)))
+               return 1;       /* try PIO instead of DMA */
+
+       outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
+       reading |= 0x01;
+       outb(reading, dma_base);                /* specify r/w */
+       outb(inb(dma_base+2)|6, dma_base+2);    /* clear INTR & ERROR flags */
+       drive->waiting_for_dma = 1;
+
+       if (drive->type != ATA_DISK)
+               return 0;
+
+       ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);  /* issue cmd to drive */
+       OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+
+       return 0;
+}
+
+static int hpt34x_udma_read(struct ata_device *drive, struct request *rq)
+{
+       return do_udma(1 << 3, drive, rq);
+}
+
+static int hpt34x_udma_write(struct ata_device *drive, struct request *rq)
+{
+       return do_udma(0, drive, rq);
+}
+
 /*
  * hpt34x_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
  *
@@ -311,45 +360,17 @@ no_dma_set:
  * and HPT345 UDMA bios chipset (stamped HPT363)
  * by HighPoint|Triones Technologies, Inc.
  */
-
 int hpt34x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-       struct ata_channel *ch = drive->channel;
-       unsigned long dma_base = ch->dma_base;
-       unsigned int count, reading = 0;
-       byte dma_stat;
-
        switch (func) {
                case ide_dma_check:
                        return config_drive_xfer_rate(drive, rq);
-               case ide_dma_read:
-                       reading = 1 << 3;
-               case ide_dma_write:
-                       if (!(count = udma_new_table(ch, rq)))
-                               return 1;       /* try PIO instead of DMA */
-                       outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
-                       reading |= 0x01;
-                       outb(reading, dma_base);                /* specify r/w */
-                       outb(inb(dma_base+2)|6, dma_base+2);    /* clear INTR & ERROR flags */
-                       drive->waiting_for_dma = 1;
-                       if (drive->type != ATA_DISK)
-                               return 0;
-                       ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);  /* issue cmd to drive */
-                       OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
-                       return 0;
-               case ide_dma_end:       /* returns 1 on error, 0 otherwise */
-                       drive->waiting_for_dma = 0;
-                       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
-                       dma_stat = inb(dma_base+2);             /* get DMA status */
-                       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
-                       udma_destroy_table(ch);                 /* purge DMA mappings */
-                       return (dma_stat & 7) != 4;             /* verify good DMA status */
                default:
                        break;
        }
        return ide_dmaproc(func, drive, rq);    /* use standard DMA stuff */
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * If the BIOS does not set the IO base addaress to XX00, 343 will fail.
@@ -423,7 +444,10 @@ void __init ide_init_hpt34x(struct ata_channel *hwif)
                else
                        hwif->autodma = 0;
 
-               hwif->udma = &hpt34x_dmaproc;
+               hwif->udma_stop = hpt34x_udma_stop;
+               hwif->udma_read = hpt34x_udma_read;
+               hwif->udma_write = hpt34x_udma_write;
+               hwif->udma = hpt34x_dmaproc;
                hwif->highmem = 1;
        } else {
                hwif->drives[0].autotune = 1;
index 8eb7b0401ec8f922d762a0c004fcf3381b14719b..0d5f59e11bd1b9bbeb83715da2c62c24d1289862 100644 (file)
@@ -748,7 +748,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
 
        if (id && (id->capability & 1) && drive->channel->autodma) {
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+               if (udma_black_list(drive)) {
                        dma_func = ide_dma_off;
                        goto fast_ata_pio;
                }
@@ -769,7 +769,7 @@ try_dma_modes:
                                if (dma_func != ide_dma_on)
                                        goto no_dma_set;
                        }
-               } else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+               } else if (udma_white_list(drive)) {
                        if (id->eide_dma_time > 150) {
                                goto no_dma_set;
                        }
@@ -830,6 +830,86 @@ int hpt366_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct reque
        return ide_dmaproc(func, drive, rq);    /* use standard DMA stuff */
 }
 
+static void do_udma_start(struct ata_device *drive)
+{
+       struct ata_channel *ch = drive->channel;
+
+       u8 regstate = ch->unit ? 0x54 : 0x50;
+       pci_write_config_byte(ch->pci_dev, regstate, 0x37);
+       udelay(10);
+}
+
+static int hpt370_udma_start(struct ata_device *drive, struct request *__rq)
+{
+       struct ata_channel *ch = drive->channel;
+
+       do_udma_start(drive);
+
+       /* Note that this is done *after* the cmd has been issued to the drive,
+        * as per the BM-IDE spec.  The Promise Ultra33 doesn't work correctly
+        * when we do this part before issuing the drive cmd.
+        */
+
+       outb(inb(ch->dma_base) | 1, ch->dma_base);      /* start DMA */
+
+       return 0;
+}
+
+static void do_timeout_irq(struct ata_device *drive)
+{
+       u8 dma_stat;
+       u8 regstate = drive->channel->unit ? 0x54 : 0x50;
+       u8 reginfo = drive->channel->unit ? 0x56 : 0x52;
+       unsigned long dma_base = drive->channel->dma_base;
+
+       pci_read_config_byte(drive->channel->pci_dev, reginfo, &dma_stat);
+       printk(KERN_INFO "%s: %d bytes in FIFO\n", drive->name, dma_stat);
+       pci_write_config_byte(drive->channel->pci_dev, regstate, 0x37);
+       udelay(10);
+       dma_stat = inb(dma_base);
+       outb(dma_stat & ~0x1, dma_base); /* stop dma */
+       dma_stat = inb(dma_base + 2);
+       outb(dma_stat | 0x6, dma_base+2); /* clear errors */
+
+}
+
+static void hpt370_udma_timeout(struct ata_device *drive)
+{
+       do_timeout_irq(drive);
+       do_udma_start(drive);
+}
+
+static void hpt370_udma_lost_irq(struct ata_device *drive)
+{
+       do_timeout_irq(drive);
+       do_udma_start(drive);
+}
+
+static int hpt370_udma_stop(struct ata_device *drive)
+{
+       struct ata_channel *ch = drive->channel;
+       unsigned long dma_base = ch->dma_base;
+       u8 dma_stat;
+
+       dma_stat = inb(dma_base + 2);
+       if (dma_stat & 0x01) {
+               udelay(20); /* wait a little */
+               dma_stat = inb(dma_base + 2);
+       }
+       if ((dma_stat & 0x01) != 0) {
+               do_timeout_irq(drive);
+               do_udma_start(drive);
+       }
+
+       drive->waiting_for_dma = 0;
+       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
+       dma_stat = inb(dma_base+2);             /* get DMA status */
+       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
+       udma_destroy_table(ch);                 /* purge DMA mappings */
+
+       return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;     /* verify good DMA status */
+}
+
 int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
        struct ata_channel *hwif = drive->channel;
@@ -845,18 +925,6 @@ int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct reque
                        dma_stat = inb(dma_base+2);
                        return (dma_stat & 4) == 4;     /* return 1 if INTR asserted */
 
-               case ide_dma_end:
-                       dma_stat = inb(dma_base + 2);
-                       if (dma_stat & 0x01) {
-                               udelay(20); /* wait a little */
-                               dma_stat = inb(dma_base + 2);
-                       }
-                       if ((dma_stat & 0x01) == 0) 
-                               break;
-
-                       func = ide_dma_timeout;
-                       /* fallthrough */
-
                case ide_dma_timeout:
                case ide_dma_lostirq:
                        pci_read_config_byte(hwif->pci_dev, reginfo, 
@@ -871,11 +939,7 @@ int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct reque
                        outb(dma_stat | 0x6, dma_base+2); /* clear errors */
                        /* fallthrough */
 
-#ifdef HPT_RESET_STATE_ENGINE
-               case ide_dma_begin:
-#endif
-                       pci_write_config_byte(hwif->pci_dev, regstate, 0x37);
-                       udelay(10);
+                       do_udma_start(drive);
                        break;
 
                default:
@@ -883,7 +947,7 @@ int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct reque
        }
        return ide_dmaproc(func, drive, rq);    /* use standard DMA stuff */
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * Since SUN Cobalt is attempting to do this operation, I should disclose
@@ -1183,6 +1247,8 @@ void __init ide_init_hpt366(struct ata_channel *hwif)
                        pci_read_config_byte(hwif->pci_dev, 0x5a, &reg5ah);
                        if (reg5ah & 0x10)      /* interrupt force enable */
                                pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10);
+                       hwif->udma_start = hpt370_udma_start;
+                       hwif->udma_stop = hpt370_udma_stop;
                        hwif->udma = hpt370_dmaproc;
                } else {
                        hwif->udma = hpt366_dmaproc;
index 52ee7650347ec50a47f609574c13500ff5e2b757..0e8c2595af489d49e65281afd95fe4244a08ef6a 100644 (file)
@@ -737,9 +737,9 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
 
        if (info->dma) {
                if (info->cmd == READ)
-                       info->dma = !drive->channel->udma(ide_dma_read, drive, rq);
+                       info->dma = !udma_read(drive, rq);
                else if (info->cmd == WRITE)
-                       info->dma = !drive->channel->udma(ide_dma_write, drive, rq);
+                       info->dma = !udma_write(drive, rq);
                else
                        printk("ide-cd: DMA set, but not allowed\n");
        }
@@ -755,7 +755,7 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
                OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
 
        if (info->dma)
-               drive->channel->udma(ide_dma_begin, drive, NULL);
+               udma_start(drive, rq);
 
        if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
                ide_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
@@ -905,7 +905,7 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
        /* Check for errors. */
        if (dma) {
                info->dma = 0;
-               if ((dma_error = drive->channel->udma(ide_dma_end, drive, NULL)))
+               if ((dma_error = udma_stop(drive)))
                        drive->channel->udma(ide_dma_off, drive, NULL);
        }
 
@@ -1480,7 +1480,7 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request
        /* Check for errors. */
        if (dma) {
                info->dma = 0;
-               if ((dma_error = drive->channel->udma(ide_dma_end, drive, NULL))) {
+               if ((dma_error = udma_stop(drive))) {
                        printk("ide-cd: write dma error\n");
                        drive->channel->udma(ide_dma_off, drive, NULL);
                }
index 2398f3717b8a5b13e24a6f4d7137ce61ffdba0b5..fb397a7ee5e3933a741e6c1ff938d5c5357bfc28 100644 (file)
@@ -199,7 +199,7 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
 {
        u8 stat, dma_stat;
 
-       dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
+       dma_stat = udma_stop(drive);
        if (OK_STAT(stat = GET_STAT(),DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
                if (!dma_stat) {
                        __ide_end_request(drive, rq, 1, rq->nr_sectors);
@@ -288,7 +288,7 @@ int check_drive_lists(struct ata_device *drive, int good_bad)
                        printk("%s: Disabling (U)DMA for %s\n", drive->name, id->model);
                return(blacklist);
        }
-#else /* !CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */
+#else
        const char **list;
 
        if (good_bad) {
@@ -309,7 +309,7 @@ int check_drive_lists(struct ata_device *drive, int good_bad)
                        }
                }
        }
-#endif /* CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */
+#endif
        return 0;
 }
 
@@ -326,7 +326,7 @@ static int config_drive_for_dma(struct ata_device *drive)
 
        if (id && (id->capability & 1) && ch->autodma && config_allows_dma) {
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive, NULL))
+               if (udma_black_list(drive))
                        return ch->udma(ide_dma_off, drive, NULL);
 
                /* Enable DMA on any drive that has UltraDMA (mode 6/7/?) enabled */
@@ -346,7 +346,7 @@ static int config_drive_for_dma(struct ata_device *drive)
                        if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404)
                                return ch->udma(ide_dma_on, drive, NULL);
                /* Consult the list of known "good" drives */
-               if (ide_dmaproc(ide_dma_good_drive, drive, NULL))
+               if (udma_white_list(drive))
                        return ch->udma(ide_dma_on, drive, NULL);
        }
        return ch->udma(ide_dma_off_quietly, drive, NULL);
@@ -420,7 +420,7 @@ int ata_start_dma(struct ata_device *drive, struct request *rq)
  *
  * For ATAPI devices, we just prepare for DMA and return. The caller should
  * then issue the packet command to the drive and call us again with
- * ide_dma_begin afterwards.
+ * udma_start afterwards.
  *
  * Returns 0 if all went well.
  * Returns 1 if DMA read/write could not be started, in which case
@@ -432,7 +432,7 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
        struct ata_channel *ch = drive->channel;
        unsigned long dma_base = ch->dma_base;
        u8 unit = (drive->select.b.unit & 0x01);
-       unsigned int reading = 0, set_high = 1;
+       unsigned int set_high = 1;
        u8 dma_stat;
 
        switch (func) {
@@ -456,41 +456,6 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
                        return 0;
                case ide_dma_check:
                        return config_drive_for_dma (drive);
-               case ide_dma_read:
-                       reading = 1 << 3;
-               case ide_dma_write:
-                       if (ata_start_dma(drive, rq))
-                               return 1;
-
-                       if (drive->type != ATA_DISK)
-                               return 0;
-
-                       ide_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry);       /* issue cmd to drive */
-                       if ((rq->flags & REQ_DRIVE_ACB) && (drive->addressing == 1)) {
-                               struct ata_taskfile *args = rq->special;
-
-                               OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
-                       } else if (drive->addressing) {
-                               OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
-                       } else {
-                               OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
-                       }
-                       return drive->channel->udma(ide_dma_begin, drive, NULL);
-               case ide_dma_begin:
-                       /* Note that this is done *after* the cmd has
-                        * been issued to the drive, as per the BM-IDE spec.
-                        * The Promise Ultra33 doesn't work correctly when
-                        * we do this part before issuing the drive cmd.
-                        */
-                       outb(inb(dma_base)|1, dma_base);                /* start DMA */
-                       return 0;
-               case ide_dma_end: /* returns 1 on error, 0 otherwise */
-                       drive->waiting_for_dma = 0;
-                       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
-                       dma_stat = inb(dma_base+2);             /* get DMA status */
-                       outb(dma_stat|6, dma_base+2);   /* clear the INTR & ERROR bits */
-                       udma_destroy_table(ch); /* purge DMA mappings */
-                       return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;     /* verify good DMA status */
                case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
                        dma_stat = inb(dma_base+2);
 #if 0  /* do not set unless you know what you are doing */
@@ -500,13 +465,9 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
                        }
 #endif
                        return (dma_stat & 4) == 4;     /* return 1 if INTR asserted */
-               case ide_dma_bad_drive:
-               case ide_dma_good_drive:
-                       return check_drive_lists(drive, (func == ide_dma_good_drive));
                case ide_dma_timeout:
                        printk(KERN_ERR "%s: DMA timeout occured!\n", __FUNCTION__);
                        return 1;
-               case ide_dma_retune:
                case ide_dma_lostirq:
                        printk(KERN_ERR "%s: chipset supported func only: %d\n", __FUNCTION__,  func);
                        return 1;
@@ -585,8 +546,65 @@ dma_alloc_failure:
 /****************************************************************************
  * UDMA function which should have architecture specific counterparts where
  * neccessary.
+ *
+ * The intention is that at some point in time we will move this whole to
+ * architecture specific kernel sections. For now I would love the architecture
+ * maintainers to just #ifdef #endif this stuff directly here. I have for now
+ * tryed to update as much as I could in the architecture specific code.  But
+ * of course I may have done mistakes, so please bear with me and update it
+ * here the proper way.
+ *
+ * Thank you a lot in advance!
+ *
+ * Sat May  4 20:29:46 CEST 2002 Marcin Dalecki.
  */
 
+/*
+ * This is the generic part of the DMA setup used by the host chipset drivers
+ * in the corresponding DMA setup method.
+ *
+ * FIXME: there are some places where this gets used driectly for "error
+ * recovery" in the ATAPI drivers. This was just plain wrong before, in esp.
+ * not portable, and just got uncovered now.
+ */
+void udma_enable(struct ata_device *drive, int on, int verbose)
+{
+       struct ata_channel *ch = drive->channel;
+       int set_high = 1;
+       u8 unit = (drive->select.b.unit & 0x01);
+       u64 addr = BLK_BOUNCE_HIGH;
+
+       if (!on) {
+               if (verbose)
+                       printk("%s: DMA disabled\n", drive->name);
+               set_high = 0;
+               outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+               udma_tcq_enable(drive, 0);
+#endif
+       }
+
+       /* toggle bounce buffers */
+
+       if (on && drive->type == ATA_DISK && drive->channel->highmem) {
+               if (!PCI_DMA_BUS_IS_PHYS)
+                       addr = BLK_BOUNCE_ANY;
+               else
+                       addr = drive->channel->pci_dev->dma_mask;
+       }
+
+       blk_queue_bounce_limit(&drive->queue, addr);
+
+       drive->using_dma = on;
+
+       if (on) {
+               outb(inb(ch->dma_base + 2) | (1 << (5 + unit)), ch->dma_base + 2);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
+               udma_tcq_enable(drive, 1);
+#endif
+       }
+}
+
 /*
  * This prepares a dma request.  Returns 0 if all went okay, returns 1
  * otherwise.  May also be invoked from trm290.c
@@ -718,4 +736,157 @@ void udma_print(struct ata_device *drive)
 #endif
 }
 
+/*
+ * Drive back/white list handling for UDMA capability:
+ */
+
+int udma_black_list(struct ata_device *drive)
+{
+       return check_drive_lists(drive, 0);
+}
+
+int udma_white_list(struct ata_device *drive)
+{
+       return check_drive_lists(drive, 1);
+}
+
+/*
+ * Generic entry points for functions provided possibly by the host chip set
+ * drivers.
+ */
+
+/*
+ * Prepare the channel for a DMA startfer. Please note that only the broken
+ * Pacific Digital host chip needs the reques to be passed there to decide
+ * about addressing modes.
+ */
+
+int udma_start(struct ata_device *drive, struct request *rq)
+{
+       struct ata_channel *ch = drive->channel;
+       unsigned long dma_base = ch->dma_base;
+
+       if (ch->udma_start)
+               return ch->udma_start(drive, rq);
+
+       /* Note that this is done *after* the cmd has
+        * been issued to the drive, as per the BM-IDE spec.
+        * The Promise Ultra33 doesn't work correctly when
+        * we do this part before issuing the drive cmd.
+        */
+       outb(inb(dma_base)|1, dma_base);                /* start DMA */
+       return 0;
+}
+
+int udma_stop(struct ata_device *drive)
+{
+       struct ata_channel *ch = drive->channel;
+       unsigned long dma_base = ch->dma_base;
+       u8 dma_stat;
+
+       if (ch->udma_stop)
+               return ch->udma_stop(drive);
+
+       drive->waiting_for_dma = 0;
+       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
+       dma_stat = inb(dma_base+2);             /* get DMA status */
+       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
+       udma_destroy_table(ch);                 /* purge DMA mappings */
+
+       return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;     /* verify good DMA status */
+}
+
+/*
+ * This is the default read write function.
+ *
+ * It's exported only for host chips which use it for fallback or (too) late
+ * capability checking.
+ */
+
+int ata_do_udma(unsigned int reading, struct ata_device *drive, struct request *rq)
+{
+       if (ata_start_dma(drive, rq))
+               return 1;
+
+       if (drive->type != ATA_DISK)
+               return 0;
+
+       reading <<= 3;
+
+       ide_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry);       /* issue cmd to drive */
+       if ((rq->flags & REQ_DRIVE_ACB) && (drive->addressing == 1)) {
+               struct ata_taskfile *args = rq->special;
+
+               OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
+       } else if (drive->addressing) {
+               OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+       } else {
+               OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+       }
+
+       return udma_start(drive, rq);
+}
+
+int udma_read(struct ata_device *drive, struct request *rq)
+{
+       struct ata_channel *ch = drive->channel;
+
+       if (ch->udma_read)
+               return ch->udma_read(drive, rq);
+
+       return ata_do_udma(1, drive, rq);
+}
+
+int udma_write(struct ata_device *drive, struct request *rq)
+{
+       struct ata_channel *ch = drive->channel;
+
+       if (ch->udma_write)
+               return ch->udma_write(drive, rq);
+
+       return ata_do_udma(0, drive, rq);
+}
+
+/*
+ * FIXME: This should be attached to a channel as we can see now!
+ */
+int udma_irq_status(struct ata_device *drive)
+{
+       struct ata_channel *ch = drive->channel;
+       u8 dma_stat;
+
+       if (ch->udma_irq_status)
+               return ch->udma_irq_status(drive);
+
+       /* default action */
+       dma_stat = inb(ch->dma_base + 2);
+
+       return (dma_stat & 4) == 4;     /* return 1 if INTR asserted */
+}
+
+void udma_timeout(struct ata_device *drive)
+{
+       printk(KERN_ERR "ATA: UDMA timeout occured %s!\n", drive->name);
+
+       /* Invoke the chipset specific handler now. */
+       if (drive->channel->udma_timeout)
+               drive->channel->udma_timeout(drive);
+
+}
+
+void udma_lost_irq(struct ata_device *drive)
+{
+       if (drive->channel->udma_lost_irq)
+               drive->channel->udma_lost_irq(drive);
+}
+
+EXPORT_SYMBOL(udma_enable);
+EXPORT_SYMBOL(udma_start);
+EXPORT_SYMBOL(udma_stop);
+EXPORT_SYMBOL(udma_read);
+EXPORT_SYMBOL(udma_write);
+EXPORT_SYMBOL(ata_do_udma);
+EXPORT_SYMBOL(udma_irq_status);
 EXPORT_SYMBOL(udma_print);
+EXPORT_SYMBOL(udma_black_list);
+EXPORT_SYMBOL(udma_white_list);
index b9559af9dd03c81ce157ae62f66c66c53ed77111..a2d71895fd4d8b28c8ab81f61724f0d448efa085 100644 (file)
@@ -901,7 +901,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
        if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
-               if (drive->channel->udma(ide_dma_end, drive, NULL)) {
+               if (udma_stop(drive)) {
                        set_bit (PC_DMA_ERROR, &pc->flags);
                } else {
                        pc->actually_transferred=pc->request_transfer;
@@ -1122,8 +1122,12 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
        if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
                (void) drive->channel->udma(ide_dma_off, drive, NULL);
        }
-       if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
-               dma_ok=!drive->channel->udma(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive, rq);
+       if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
+               if (test_bit (PC_WRITING, &pc->flags))
+                       dma_ok = !udma_write(drive, rq);
+               else
+                       dma_ok = !udma_read(drive, rq);
+       }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
        if (IDE_CONTROL_REG)
@@ -1136,7 +1140,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
 #ifdef CONFIG_BLK_DEV_IDEDMA
        if (dma_ok) {                                                   /* Begin DMA, if necessary */
                set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
-               (void) drive->channel->udma(ide_dma_begin, drive, NULL);
+               udma_start(drive, rq);
        }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
index 45514652e1266751568c7e0b92b8fa779274476d..9d2283c6b0b79175dd2c1f9f324128a436c11051 100644 (file)
@@ -709,7 +709,7 @@ check_if_enabled:
                d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
        }
 
-       printk("%s: chipset revision %d\n", dev->name, class_rev);
+       printk(KERN_INFO "ATA: chipset rev.: %d\n", class_rev);
 
        /*
         * Can we trust the reported IRQ?
@@ -722,11 +722,11 @@ check_if_enabled:
                   to act otherwise on those. The Supertrak however we need
                   to skip */
                if (d->vendor == PCI_VENDOR_ID_PROMISE && d->device == PCI_DEVICE_ID_PROMISE_20265) {
-                       printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n");
+                       printk(KERN_INFO "ATA: Found promise 20265 in RAID mode.\n");
                        if(dev->bus->self && dev->bus->self->vendor == PCI_VENDOR_ID_INTEL &&
                                dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960)
                        {
-                               printk(KERN_INFO "ide: Skipping Promise PDC20265 attached to I2O RAID controller.\n");
+                               printk(KERN_INFO "ATA: Skipping Promise PDC20265 attached to I2O RAID controller.\n");
                                return;
                        }
                }
@@ -734,9 +734,10 @@ check_if_enabled:
                   Suspect a fastrak and fall through */
        }
        if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) {
-               printk("%s: not 100%% native mode: will probe irqs later\n", dev->name);
+               printk(KERN_INFO "ATA: non-legacy mode: IRQ probe delayed\n");
+
                /*
-                * This allows off board ide-pci cards the enable a BIOS,
+                * This allows off board ide-pci cards to enable a BIOS,
                 * verify interrupt settings of split-mirror pci-config
                 * space, place chipset into init-mode, and/or preserve
                 * an interrupt if the card is not native ide support.
@@ -746,19 +747,18 @@ check_if_enabled:
                else
                        pciirq = trust_pci_irq(d, dev);
        } else if (tried_config) {
-               printk("%s: will probe IRQs later\n", dev->name);
+               printk(KERN_INFO "ATA: will probe IRQs later\n");
                pciirq = 0;
        } else if (!pciirq) {
-               printk("%s: bad IRQ (%d): will probe later\n", dev->name, pciirq);
+               printk(KERN_INFO "ATA: invalid IRQ (%d): will probe later\n", pciirq);
                pciirq = 0;
        } else {
                if (d->init_chipset)
                        d->init_chipset(dev);
 #ifdef __sparc__
-               printk("%s: 100%% native mode on irq %s\n",
-                      dev->name, __irq_itoa(pciirq));
+               printk(KERN_INFO "ATA: 100%% native mode on irq\n", __irq_itoa(pciirq));
 #else
-               printk("%s: 100%% native mode on irq %d\n", dev->name, pciirq);
+               printk(KERN_INFO "ATA: 100%% native mode on irq %d\n", pciirq);
 #endif
        }
 
@@ -889,10 +889,10 @@ static void __init scan_pcidev(struct pci_dev *dev)
                pdc20270_device_order_fixup(dev, d);
        else if (!(d->vendor == 0 && d->device == 0) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
                if (d->vendor == 0 && d->device == 0)
-                       printk(KERN_INFO "ATA: unknown ATA interface %s (%04x:%04x) on PCI slot %s\n",
+                       printk(KERN_INFO "ATA: unknown interface: %s (%04x:%04x) on PCI slot %s\n",
                               dev->name, vendor, device, dev->slot_name);
                else
-                       printk(KERN_INFO "ATA: interface %s on PCI slot %s\n", dev->name, dev->slot_name);
+                       printk(KERN_INFO "ATA: interface: %s, on PCI slot %s\n", dev->name, dev->slot_name);
                setup_pci_device(dev, d);
        }
 }
index f948d6c3efa2bd3a288c55b952a4ca1bb2553083..f70d048308acad5e8c5a33e9d37c4f88442e3375 100644 (file)
@@ -1449,7 +1449,6 @@ static int pmac_ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, str
        case ide_dma_bad_drive:
        case ide_dma_good_drive:
                return check_drive_lists(drive, (func == ide_dma_good_drive));
-       case ide_dma_retune:
        case ide_dma_lostirq:
        case ide_dma_timeout:
                printk(KERN_WARNING "ide_pmac_dmaproc: chipset supported func only: %d\n", func);
index c951bb8c777adc96fbcc44f3e4ece35404fc7091..df308e059335719a45d10c2a4fc143d407f6a50b 100644 (file)
@@ -2058,7 +2058,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
        if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
-               if (drive->channel->udma(ide_dma_end, drive, NULL)) {
+               if (udma_stop(drive)) {
                        /*
                         * A DMA error is sometimes expected. For example,
                         * if the tape is crossing a filemark during a
@@ -2311,9 +2311,13 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st
                printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n");
                (void) drive->channel->udma(ide_dma_off, drive, NULL);
        }
-       if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
-               dma_ok = !drive->channel->udma(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive, rq);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+       if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
+               if (test_bit (PC_WRITING, &pc->flags))
+                       dma_ok = !udma_write(drive, rq);
+               else
+                       dma_ok = !udma_read(drive, rq);
+       }
+#endif
 
        if (IDE_CONTROL_REG)
                OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
@@ -2324,7 +2328,7 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st
 #ifdef CONFIG_BLK_DEV_IDEDMA
        if (dma_ok) {                                           /* Begin DMA, if necessary */
                set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
-               (void) drive->channel->udma(ide_dma_begin, drive, NULL);
+               udma_start(drive, rq);
        }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
        if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
index 41ac1895de095d6133f67624064f91fbda9e439d..fad49c558326c1c08c8860dcc647cf65ad060f4a 100644 (file)
@@ -461,7 +461,6 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
                 * regular dma proc -- basically split stuff that needs to act
                 * on a request from things like ide_dma_check etc.
                 */
-               ide_dma_action_t dma_act;
 
                if (!drive->using_dma)
                        return ide_started;
@@ -469,10 +468,10 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
                /* for dma commands we don't set the handler */
                if (args->taskfile.command == WIN_WRITEDMA
                 || args->taskfile.command == WIN_WRITEDMA_EXT)
-                       dma_act = ide_dma_write;
+                       udma_write(drive, rq);
                else if (args->taskfile.command == WIN_READDMA
                      || args->taskfile.command == WIN_READDMA_EXT)
-                       dma_act = ide_dma_read;
+                       udma_read(drive, rq);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ
                else if (args->taskfile.command == WIN_WRITEDMA_QUEUED
                      || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT
@@ -484,10 +483,6 @@ ide_startstop_t ata_taskfile(struct ata_device *drive,
                        printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
                        return ide_stopped;
                }
-
-
-               if (drive->channel->udma(dma_act, drive, rq))
-                       return ide_stopped;
        }
 
        return ide_started;
index 2f6d1cd878b863c3f24e1f07b6ec73e0e28ebbe6..98f07bc98cb47c65a4f8bd57b25813af27b980fd 100644 (file)
@@ -1407,7 +1407,7 @@ static void dma_timeout_retry(struct ata_device *drive, struct request *rq)
        /*
         * end current dma transaction
         */
-       ch->udma(ide_dma_end, drive, rq);
+       ch->udma_stop(drive);
 
        /*
         * complain a little, later we might remove some of this verbosity
@@ -2127,6 +2127,13 @@ void ide_unregister(struct ata_channel *ch)
        ch->atapi_read = old.atapi_read;
        ch->atapi_write = old.atapi_write;
        ch->udma = old.udma;
+       ch->udma_start = old.udma_start;
+       ch->udma_stop = old.udma_stop;
+       ch->udma_read = old.udma_read;
+       ch->udma_write = old.udma_write;
+       ch->udma_irq_status = old.udma_irq_status;
+       ch->udma_timeout = old.udma_timeout;
+       ch->udma_lost_irq = old.udma_lost_irq;
        ch->busproc = old.busproc;
        ch->bus_state = old.bus_state;
        ch->dma_base = old.dma_base;
index 942274b143cee02349c043b8f30f4e2af5dfdc9f..e57b77dce0a9de069861058bea343afcaadc2b9b 100644 (file)
@@ -82,26 +82,50 @@ static void ns87415_selectproc (ide_drive_t *drive)
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int ns87415_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+
+static int ns87415_udma_stop(struct ata_device *drive)
 {
-       struct ata_channel *hwif = drive->channel;
-       byte            dma_stat;
+       struct ata_channel *ch = drive->channel;
+       unsigned long dma_base = ch->dma_base;
+       u8 dma_stat;
+
+       drive->waiting_for_dma = 0;
+       dma_stat = inb(ch->dma_base+2);
+       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
+       outb(inb(dma_base)|6, dma_base);        /* from ERRATA: clear the INTR & ERROR bits */
+       udma_destroy_table(ch);                         /* and free any DMA resources */
+
+       return (dma_stat & 7) != 4;     /* verify good DMA status */
+
+}
+
+static int ns87415_udma_read(struct ata_device *drive, struct request *rq)
+{
+       ns87415_prepare_drive(drive, 1);        /* select DMA xfer */
 
+       if (!ata_do_udma(1, drive, rq))         /* use standard DMA stuff */
+               return 0;
+
+       ns87415_prepare_drive(drive, 0);        /* DMA failed: select PIO xfer */
+
+       return 1;
+}
+
+static int ns87415_udma_write(struct ata_device *drive, struct request *rq)
+{
+       ns87415_prepare_drive(drive, 1);        /* select DMA xfer */
+
+       if (!ata_do_udma(0, drive, rq))         /* use standard DMA stuff */
+               return 0;
+
+       ns87415_prepare_drive(drive, 0);        /* DMA failed: select PIO xfer */
+
+       return 1;
+}
+
+static int ns87415_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+{
        switch (func) {
-               case ide_dma_end: /* returns 1 on error, 0 otherwise */
-                       drive->waiting_for_dma = 0;
-                       dma_stat = inb(hwif->dma_base+2);
-                       outb(inb(hwif->dma_base)&~1, hwif->dma_base);   /* stop DMA */
-                       outb(inb(hwif->dma_base)|6, hwif->dma_base);    /* from ERRATA: clear the INTR & ERROR bits */
-                       udma_destroy_table(hwif);                       /* and free any DMA resources */
-                       return (dma_stat & 7) != 4;             /* verify good DMA status */
-               case ide_dma_write:
-               case ide_dma_read:
-                       ns87415_prepare_drive(drive, 1);        /* select DMA xfer */
-                       if (!ide_dmaproc(func, drive, rq))              /* use standard DMA stuff */
-                               return 0;
-                       ns87415_prepare_drive(drive, 0);        /* DMA failed: select PIO xfer */
-                       return 1;
                case ide_dma_check:
                        if (drive->type != ATA_DISK)
                                return ide_dmaproc(ide_dma_off_quietly, drive, rq);
@@ -205,8 +229,12 @@ void __init ide_init_ns87415(struct ata_channel *hwif)
        }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-       if (hwif->dma_base)
+       if (hwif->dma_base) {
+               hwif->udma_stop = ns87415_udma_stop;
+               hwif->udma_read = ns87415_udma_read;
+               hwif->udma_write = ns87415_udma_write;
                hwif->udma = ns87415_dmaproc;
+       }
 #endif
 
        hwif->selectproc = &ns87415_selectproc;
index 9fe4f6e4b9342b565b70254f1dbee3c61685b743..ae07bdb1578203df38838a925fd3130365302ada 100644 (file)
@@ -916,7 +916,7 @@ jumpbit_is_set:
        return ((int)   ((id->dma_ultra >> 14) & 3) ? ide_dma_on :
                        ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
                        ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-                       ((id->dma_mword >> 8) & 7) ? ide_dma_on : 
+                       ((id->dma_mword >> 8) & 7) ? ide_dma_on :
                        ((id->dma_1word >> 8) & 7) ? ide_dma_on :
                                                     ide_dma_off_quietly);
 }
@@ -929,7 +929,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
 
        if (id && (id->capability & 1) && hwif->autodma) {
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+               if (udma_black_list(drive)) {
                        dma_func = ide_dma_off;
                        goto fast_ata_pio;
                }
@@ -951,7 +951,7 @@ try_dma_modes:
                                if (dma_func != ide_dma_on)
                                        goto no_dma_set;
                        }
-               } else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+               } else if (udma_white_list(drive)) {
                        if (id->eide_dma_time > 150) {
                                goto no_dma_set;
                        }
@@ -977,20 +977,107 @@ int pdc202xx_quirkproc (ide_drive_t *drive)
        return ((int) check_in_drive_lists(drive, pdc_quirk_drives));
 }
 
+static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
+{
+       u8 clock                = 0;
+       u8 hardware48hack       = 0;
+       struct ata_channel *ch = drive->channel;
+       struct pci_dev *dev     = ch->pci_dev;
+       unsigned long high_16   = pci_resource_start(dev, 4);
+       unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00);
+
+
+       switch (dev->device) {
+               case PCI_DEVICE_ID_PROMISE_20275:
+               case PCI_DEVICE_ID_PROMISE_20276:
+               case PCI_DEVICE_ID_PROMISE_20269:
+               case PCI_DEVICE_ID_PROMISE_20268R:
+               case PCI_DEVICE_ID_PROMISE_20268:
+                       break;
+               case PCI_DEVICE_ID_PROMISE_20267:
+               case PCI_DEVICE_ID_PROMISE_20265:
+               case PCI_DEVICE_ID_PROMISE_20262:
+                       hardware48hack = 1;
+                       clock = IN_BYTE(high_16 + 0x11);
+               default:
+                       break;
+       }
+
+       if ((drive->addressing) && (hardware48hack)) {
+               unsigned long word_count = 0;
+
+               outb(clock|(ch->unit ? 0x08 : 0x02), high_16 + 0x11);
+               word_count = (rq->nr_sectors << 8);
+               word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000;
+               outl(word_count, atapi_reg);
+       }
+
+       /* Note that this is done *after* the cmd has been issued to the drive,
+        * as per the BM-IDE spec.  The Promise Ultra33 doesn't work correctly
+        * when we do this part before issuing the drive cmd.
+        */
+
+       outb(inb(ch->dma_base) | 1, ch->dma_base); /* start DMA */
+
+       return 0;
+}
+
+int pdc202xx_udma_stop(struct ata_device *drive)
+{
+       u8 newchip              = 0;
+       u8 clock                = 0;
+       u8 hardware48hack       = 0;
+       struct ata_channel *ch = drive->channel;
+       struct pci_dev *dev     = ch->pci_dev;
+       unsigned long high_16   = pci_resource_start(dev, 4);
+       unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00);
+       unsigned long dma_base = ch->dma_base;
+       u8 dma_stat;
+
+       switch (dev->device) {
+               case PCI_DEVICE_ID_PROMISE_20275:
+               case PCI_DEVICE_ID_PROMISE_20276:
+               case PCI_DEVICE_ID_PROMISE_20269:
+               case PCI_DEVICE_ID_PROMISE_20268R:
+               case PCI_DEVICE_ID_PROMISE_20268:
+                       newchip = 1;
+                       break;
+               case PCI_DEVICE_ID_PROMISE_20267:
+               case PCI_DEVICE_ID_PROMISE_20265:
+               case PCI_DEVICE_ID_PROMISE_20262:
+                       hardware48hack = 1;
+                       clock = IN_BYTE(high_16 + 0x11);
+               default:
+                       break;
+       }
+       if ((drive->addressing) && (hardware48hack)) {
+               outl(0, atapi_reg);     /* zero out extra */
+               clock = IN_BYTE(high_16 + 0x11);
+               OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + 0x11);
+       }
+
+       drive->waiting_for_dma = 0;
+       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
+       dma_stat = inb(dma_base+2);             /* get DMA status */
+       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
+       udma_destroy_table(ch);                 /* purge DMA mappings */
+
+       return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;     /* verify good DMA status */
+}
+
 /*
  * pdc202xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
  */
 int pdc202xx_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-       byte dma_stat           = 0;
-       byte sc1d               = 0;
-       byte newchip            = 0;
-       byte clock              = 0;
-       byte hardware48hack     = 0;
+       u8 dma_stat     = 0;
+       u8 sc1d         = 0;
+       u8 newchip      = 0;
+       u8 clock        = 0;
+       u8 hardware48hack = 0;
        struct ata_channel *hwif = drive->channel;
        struct pci_dev *dev     = hwif->pci_dev;
        unsigned long high_16   = pci_resource_start(dev, 4);
-       unsigned long atapi_reg = high_16 + (hwif->unit ? 0x24 : 0x00);
        unsigned long dma_base  = hwif->dma_base;
 
        switch (dev->device) {
@@ -1013,29 +1100,6 @@ int pdc202xx_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct req
        switch (func) {
                case ide_dma_check:
                        return config_drive_xfer_rate(drive);
-               case ide_dma_begin:
-                       /* Note that this is done *after* the cmd has
-                        * been issued to the drive, as per the BM-IDE spec.
-                        * The Promise Ultra33 doesn't work correctly when
-                        * we do this part before issuing the drive cmd.
-                        */
-                       if ((drive->addressing) && (hardware48hack)) {
-                               struct request *rq = HWGROUP(drive)->rq;
-                               unsigned long word_count = 0;
-
-                               outb(clock|(hwif->unit ? 0x08 : 0x02), high_16 + 0x11);
-                               word_count = (rq->nr_sectors << 8);
-                               word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000;
-                               outl(word_count, atapi_reg);
-                       }
-                       break;
-               case ide_dma_end:
-                       if ((drive->addressing) && (hardware48hack)) {
-                               outl(0, atapi_reg);     /* zero out extra */
-                               clock = IN_BYTE(high_16 + 0x11);
-                               OUT_BYTE(clock & ~(hwif->unit ? 0x08:0x02), high_16 + 0x11);
-                       }
-                       break;
                case ide_dma_test_irq:  /* returns 1 if dma irq issued, 0 otherwise */
                        dma_stat = IN_BYTE(dma_base+2);
                        if (newchip)
@@ -1268,6 +1332,8 @@ void __init ide_init_pdc202xx(struct ata_channel *hwif)
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
        if (hwif->dma_base) {
+               hwif->udma_start = pdc202xx_udma_start;
+               hwif->udma_stop = pdc202xx_udma_stop;
                hwif->udma = pdc202xx_dmaproc;
                hwif->highmem = 1;
                if (!noautodma)
index 05d2a82cc7cb43040ef7c9d37f39948a482e704f..dc224f51de7ab034fa286055f385ca3ee9eacf49 100644 (file)
@@ -431,14 +431,14 @@ static int config_chipset_for_dma (ide_drive_t *drive)
                                                     ide_dma_off_quietly);
 }
 
-static int config_drive_xfer_rate (ide_drive_t *drive)
+static int config_drive_xfer_rate(struct ata_device *drive)
 {
        struct hd_driveid *id = drive->id;
        ide_dma_action_t dma_func = ide_dma_on;
 
        if (id && (id->capability & 1) && drive->channel->autodma) {
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+               if (udma_black_list(drive)) {
                        dma_func = ide_dma_off;
                        goto fast_ata_pio;
                }
@@ -460,7 +460,7 @@ try_dma_modes:
                                if (dma_func != ide_dma_on)
                                        goto no_dma_set;
                        }
-               } else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+               } else if (udma_white_list(drive)) {
                        if (id->eide_dma_time > 150) {
                                goto no_dma_set;
                        }
@@ -480,45 +480,54 @@ no_dma_set:
        return drive->channel->udma(dma_func, drive, NULL);
 }
 
-static int svwks_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int svwks_udma_stop(struct ata_device *drive)
 {
-       switch (func) {
-               case ide_dma_check:
-                       return config_drive_xfer_rate(drive);
-               case ide_dma_end:
-               {
-                       struct ata_channel *hwif = drive->channel;
-                       unsigned long dma_base          = hwif->dma_base;
+       struct ata_channel *ch = drive->channel;
+       unsigned long dma_base = ch->dma_base;
+       u8 dma_stat;
 
-                       if(inb(dma_base+0x02)&1)
-                       {
+       if(inb(dma_base+0x02)&1)
+       {
 #if 0
-                               int i;
-                               printk(KERN_ERR "Curious - OSB4 thinks the DMA is still running.\n");
-                               for(i=0;i<10;i++)
-                               {
-                                       if(!(inb(dma_base+0x02)&1))
-                                       {
-                                               printk(KERN_ERR "OSB4 now finished.\n");
-                                               break;
-                                       }
-                                       udelay(5);
-                               }
+               int i;
+               printk(KERN_ERR "Curious - OSB4 thinks the DMA is still running.\n");
+               for(i=0;i<10;i++)
+               {
+                       if(!(inb(dma_base+0x02)&1))
+                       {
+                               printk(KERN_ERR "OSB4 now finished.\n");
+                               break;
+                       }
+                       udelay(5);
+               }
 #endif
-                               printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n");
-                               printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n");
-                               printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n");
+               printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n");
+               printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n");
+               printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n");
 #if 0
-                               /* Panic might sys_sync -> death by corrupt disk */
-                               panic("OSB4: continuing might cause disk corruption.\n");
+               /* Panic might sys_sync -> death by corrupt disk */
+               panic("OSB4: continuing might cause disk corruption.\n");
 #else
-                               printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n");
-                               while(1)
-                                       cpu_relax();
+               printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n");
+               while(1)
+                       cpu_relax();
 #endif
-                       }
-                       /* and drop through */
-               }
+       }
+
+       drive->waiting_for_dma = 0;
+       outb(inb(dma_base)&~1, dma_base);       /* stop DMA */
+       dma_stat = inb(dma_base+2);             /* get DMA status */
+       outb(dma_stat|6, dma_base+2);           /* clear the INTR & ERROR bits */
+       udma_destroy_table(ch);                 /* purge DMA mappings */
+
+       return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;     /* verify good DMA status */
+}
+
+static int svwks_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+{
+       switch (func) {
+               case ide_dma_check:
+                       return config_drive_xfer_rate(drive);
                default:
                        break;
        }
@@ -645,6 +654,7 @@ void __init ide_init_svwks(struct ata_channel *hwif)
                if (!noautodma)
                        hwif->autodma = 1;
 #endif
+               hwif->udma_stop = svwks_udma_stop;
                hwif->udma = svwks_dmaproc;
                hwif->highmem = 1;
        } else {
index 90350608fbf3a4517c49f894404987946374cd81..4db311dbbc5f0a7d8f2b061b042a3451b5891209 100644 (file)
@@ -685,7 +685,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
 
        if (id && (id->capability & 1) && drive->channel->autodma) {
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+               if (udma_black_list(drive)) {
                        dma_func = ide_dma_off;
                        goto fast_ata_pio;
                }
@@ -707,7 +707,7 @@ try_dma_modes:
                                if (dma_func != ide_dma_on)
                                        goto no_dma_set;
                        }
-               } else if ((ide_dmaproc(ide_dma_good_drive, drive, NULL)) &&
+               } else if ((udma_white_list(drive)) &&
                           (id->eide_dma_time > 150)) {
                        /* Consult the list of known "good" drives */
                        dma_func = config_chipset_for_dma(drive, 0);
index 158070c4150c756f7c2768368beb9fd0559b181b..338e1a9a90774bbcdf715c6a5686aa8277bb92fc 100644 (file)
@@ -114,7 +114,7 @@ static int config_for_dma(ide_drive_t *drive)
  * Check to see if the drive and
  * chipset is capable of DMA mode
  */
-static int sl82c105_check_drive(ide_drive_t *drive)
+static int sl82c105_check_drive(ide_drive_t *drive, struct request *rq)
 {
        ide_dma_action_t dma_func = ide_dma_off_quietly;
 
@@ -129,7 +129,7 @@ static int sl82c105_check_drive(ide_drive_t *drive)
                        break;
 
                /* Consult the list of known "bad" drives */
-               if (ide_dmaproc(ide_dma_bad_drive, drive)) {
+               if (udma_black_list(drive)) {
                        dma_func = ide_dma_off;
                        break;
                }
@@ -140,23 +140,23 @@ static int sl82c105_check_drive(ide_drive_t *drive)
                        break;
                }
 
-               if (ide_dmaproc(ide_dma_good_drive, drive)) {
+               if (udma_white_list(drive)) {
                        dma_func = ide_dma_on;
                        break;
                }
        } while (0);
 
-       return drive->channel->dmaproc(dma_func, drive);
+       return drive->channel->udma(dma_func, drive, rq);
 }
 
 /*
  * Our own dmaproc, only to intercept ide_dma_check
  */
-static int sl82c105_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
+static int sl82c105_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
        switch (func) {
        case ide_dma_check:
-               return sl82c105_check_drive(drive);
+               return sl82c105_check_drive(drive, rq);
        case ide_dma_on:
                if (config_for_dma(drive))
                        func = ide_dma_off;
@@ -168,7 +168,7 @@ static int sl82c105_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
        default:
                break;
        }
-       return ide_dmaproc(func, drive);
+       return ide_dmaproc(func, drive, rq);
 }
 
 /*
@@ -183,8 +183,8 @@ static void tune_sl82c105(ide_drive_t *drive, byte pio)
         * We support 32-bit I/O on this interface, and it
         * doesn't have problems with interrupts.
         */
-       drive->io_32bit = 1;
-       drive->unmask = 1;
+       drive->channel->io_32bit = 1;
+       drive->channel->unmask = 1;
 }
 
 /*
@@ -252,10 +252,10 @@ void __init dma_init_sl82c105(struct ata_channel *hwif, unsigned long dma_base)
        }
        outb(dma_state, dma_base + 2);
 
-       hwif->dmaproc = NULL;
+       hwif->udma = NULL;
        ide_setup_dma(hwif, dma_base, 8);
-       if (hwif->dmaproc)
-               hwif->dmaproc = sl82c105_dmaproc;
+       if (hwif->udma)
+               hwif->udma = sl82c105_dmaproc;
 }
 
 /*
index 14f91ba98053211f834dae5b8ca50ffb3349b012..d23276a5a68da794b23461a10afc123a124c55e9 100644 (file)
@@ -95,7 +95,7 @@ static void tcq_invalidate_queue(struct ata_device *drive)
        del_timer(&hwgroup->timer);
 
        if (test_bit(IDE_DMA, &hwgroup->flags))
-               drive->channel->udma(ide_dma_end, drive, hwgroup->rq);
+               udma_stop(drive);
 
        blk_queue_invalidate_tags(q);
 
@@ -328,7 +328,7 @@ ide_startstop_t ide_dmaq_complete(struct ata_device *drive, struct request *rq,
        /*
         * transfer was in progress, stop DMA engine
         */
-       dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
+       dma_stat = udma_stop(drive);
 
        /*
         * must be end of I/O, check status and complete as necessary
@@ -531,7 +531,7 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *
                return ide_stopped;
 
        set_irq(drive, ide_dmaq_intr);
-       if (!ch->udma(ide_dma_begin, drive, rq))
+       if (!udma_start(drive, rq))
                return ide_started;
 
        return ide_stopped;
index 233d34465cc3e0d015e18553ae8ccca6f305b77d..28584ad54b2c2e0a54b55eb13e490bfa4e66456b 100644 (file)
@@ -173,36 +173,73 @@ static void trm290_selectproc (ide_drive_t *drive)
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int trm290_udma_start(struct ata_device *drive, struct request *__rq)
+{
+       /* Nothing to be done here. */
+       return 0;
+}
+
+static int trm290_udma_stop(struct ata_device *drive)
 {
        struct ata_channel *ch = drive->channel;
-       unsigned int count, reading = 2, writing = 0;
 
-       switch (func) {
-               case ide_dma_write:
-                       reading = 0;
-                       writing = 1;
+       drive->waiting_for_dma = 0;
+       udma_destroy_table(ch); /* purge DMA mappings */
+       return (inw(ch->dma_base + 2) != 0x00ff);
+}
+
+static int do_udma(unsigned int reading, struct ata_device *drive, struct request *rq)
+{
+       struct ata_channel *ch = drive->channel;
+       unsigned int count, writing;
+
+       if (!reading) {
+               reading = 0;
+               writing = 1;
 #ifdef TRM290_NO_DMA_WRITES
-                       break;  /* always use PIO for writes */
+               trm290_prepare_drive(drive, 0); /* select PIO xfer */
+
+               return 1;
 #endif
-               case ide_dma_read:
-                       if (!(count = udma_new_table(ch, rq)))
-                               break;          /* try PIO instead of DMA */
-                       trm290_prepare_drive(drive, 1); /* select DMA xfer */
-                       outl(ch->dmatable_dma|reading|writing, ch->dma_base);
-                       drive->waiting_for_dma = 1;
-                       outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
-                       if (drive->type != ATA_DISK)
-                               return 0;
-                       ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
-                       OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
-                       return 0;
-               case ide_dma_begin:
-                       return 0;
-               case ide_dma_end:
-                       drive->waiting_for_dma = 0;
-                       udma_destroy_table(ch); /* purge DMA mappings */
-                       return (inw(ch->dma_base + 2) != 0x00ff);
+       } else {
+               reading = 2;
+               writing = 0;
+       }
+
+       if (!(count = udma_new_table(ch, rq))) {
+               trm290_prepare_drive(drive, 0); /* select PIO xfer */
+               return 1;       /* try PIO instead of DMA */
+       }
+
+       trm290_prepare_drive(drive, 1); /* select DMA xfer */
+       outl(ch->dmatable_dma|reading|writing, ch->dma_base);
+       drive->waiting_for_dma = 1;
+       outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
+
+       if (drive->type != ATA_DISK)
+               return 0;
+
+       ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
+       OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+
+       return 0;
+}
+
+static int trm290_udma_read(struct ata_device *drive, struct request *rq)
+{
+       return do_udma(1, drive, rq);
+}
+
+static int trm290_udma_write(struct ata_device *drive, struct request *rq)
+{
+       return do_udma(0, drive, rq);
+}
+
+static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+{
+       struct ata_channel *ch = drive->channel;
+
+       switch (func) {
                case ide_dma_test_irq:
                        return (inw(ch->dma_base + 2) == 0x00ff);
                default:
@@ -263,6 +300,10 @@ void __init ide_init_trm290(struct ata_channel *hwif)
        ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->unit ? 0x0080 : 0x0000), 3);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
+       hwif->udma_start = trm290_udma_start;
+       hwif->udma_stop = trm290_udma_stop;
+       hwif->udma_read = trm290_udma_read;
+       hwif->udma_write = trm290_udma_write;
        hwif->udma = trm290_dmaproc;
 #endif
 
index c4f1e0744591116eec170146dc880f87b9e8c18d..cb9f7302584406f556ca0d99deb09d2a384a74ca 100644 (file)
@@ -328,7 +328,7 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
                printk ("ide-scsi: %s: DMA complete\n", drive->name);
 #endif /* IDESCSI_DEBUG_LOG */
                pc->actually_transferred=pc->request_transfer;
-               (void) drive->channel->udma(ide_dma_end, drive, NULL);
+               udma_stop(drive);
        }
 
        status = GET_STAT();                                            /* Clear the interrupt */
@@ -429,8 +429,12 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request
        pc->current_position=pc->buffer;
        bcount = min(pc->request_transfer, 63 * 1024);          /* Request to transfer the entire buffer at once */
 
-       if (drive->using_dma && rq->bio)
-               dma_ok = !drive->channel->udma(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive, rq);
+       if (drive->using_dma && rq->bio) {
+               if (test_bit (PC_WRITING, &pc->flags))
+                       dma_ok = !udma_write(drive, rq);
+               else
+                       dma_ok = !udma_read(drive, rq);
+       }
 
        SELECT_DRIVE(drive->channel, drive);
        if (IDE_CONTROL_REG)
@@ -441,7 +445,7 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request
 
        if (dma_ok) {
                set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
-               (void) drive->channel->udma(ide_dma_begin, drive, NULL);
+               udma_start(drive, rq);
        }
        if (test_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
                ide_set_handler(drive, idescsi_transfer_pc, get_timeout(pc), NULL);
index d0dc8bc4d8bfbfa35882731c4e5e47aeff4a9056..87b215e9a278d4c2cd3a42e8baba0f5ad5d77368 100644 (file)
@@ -374,15 +374,10 @@ struct ata_device {
 } ide_drive_t;
 
 typedef enum {
-       ide_dma_read,   ide_dma_write,
-       ide_dma_begin,  ide_dma_end,
        ide_dma_check,
        ide_dma_on, ide_dma_off,
        ide_dma_off_quietly,
        ide_dma_test_irq,
-       ide_dma_bad_drive,
-       ide_dma_good_drive,
-       ide_dma_retune,
        ide_dma_lostirq,
        ide_dma_timeout
 } ide_dma_action_t;
@@ -436,7 +431,19 @@ struct ata_channel {
        void (*atapi_read)(struct ata_device *, void *, unsigned int);
        void (*atapi_write)(struct ata_device *, void *, unsigned int);
 
-       int (*udma)(ide_dma_action_t, struct ata_device *, struct request *); /* dma read/write/abort routine */
+       int (*udma)(ide_dma_action_t, struct ata_device *, struct request *);
+
+       int (*udma_start) (struct ata_device *, struct request *rq);
+       int (*udma_stop) (struct ata_device *);
+
+       int (*udma_read) (struct ata_device *, struct request *rq);
+       int (*udma_write) (struct ata_device *, struct request *rq);
+
+       int (*udma_irq_status) (struct ata_device *);
+
+       void (*udma_timeout) (struct ata_device *);
+       void (*udma_lost_irq) (struct ata_device *);
+
        unsigned int    *dmatable_cpu;  /* dma physical region descriptor table (cpu view) */
        dma_addr_t      dmatable_dma;   /* dma physical region descriptor table (dma view) */
        struct scatterlist *sg_table;   /* Scatter-gather list used to build the above */
@@ -873,13 +880,25 @@ extern int udma_new_table(struct ata_channel *, struct request *);
 extern void udma_destroy_table(struct ata_channel *);
 extern void udma_print(struct ata_device *);
 
+extern void udma_enable(struct ata_device *, int, int);
+extern int udma_black_list(struct ata_device *);
+extern int udma_white_list(struct ata_device *);
+extern void udma_timeout(struct ata_device *);
+extern void udma_lost_irq(struct ata_device *);
+extern int udma_start(struct ata_device *, struct request *rq);
+extern int udma_stop(struct ata_device *);
+extern int udma_read(struct ata_device *, struct request *rq);
+extern int udma_write(struct ata_device *, struct request *rq);
+extern int udma_irq_status(struct ata_device *);
+
+extern int ata_do_udma(unsigned int reading, struct ata_device *drive, struct request *rq);
+
 extern ide_startstop_t udma_tcq_taskfile(struct ata_device *, struct request *);
 extern int udma_tcq_enable(struct ata_device *, int);
 
 extern ide_startstop_t ide_dma_intr(struct ata_device *, struct request *);
 extern int check_drive_lists(struct ata_device *, int good_bad);
 extern int ide_dmaproc(ide_dma_action_t func, struct ata_device *, struct request *);
-extern ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t, struct ata_device *, struct request *);
 extern void ide_release_dma(struct ata_channel *);
 extern void ide_setup_dma(struct ata_channel *,        unsigned long, unsigned int) __init;
 extern int ata_start_dma(struct ata_device *, struct request *rq);