[PATCH] 2.5.19 IDE 78

From: Martin Dalecki (dalecki@evision-ventures.com)
Date: Sun Jun 02 2002 - 01:04:59 EST


Sat Jun 1 16:54:57 CEST 2002 ide-clean-78

- Move ide_fixstring() from ide.c to probe.c, since this is the place, where it's
   most used.

- Remove GET_STAT() - it's not used any longer.

- Remove last parameter of ide_error. Rename it to ata_error().

- Don't use ide_fixstring in qd65xx.c host chip driver. The model name is
   already fixed in probe.c.

- Invent ata_irq_enable() for the handling of the trice nIEN bit of the
   control register. Consistently use ch->intrproc method every time we toggle
   this bit. This simply wasn't the case before!

- Disable interrupts on a previous channel only when we share them indeed.

- Eliminate simple drive command handling function drive_cmd.

- Simplify the ioctl handler. Move it to ioctl, since that's the only place
   where it's actually used.

diff -urN linux-2.5.19/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- linux-2.5.19/arch/cris/drivers/ide.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/arch/cris/drivers/ide.c 2002-06-01 17:14:44.000000000 +0200
@@ -707,7 +707,7 @@
                 }
                 printk("%s: bad DMA status\n", drive->name);
         }
- return ide_error(drive, "dma_intr", drive->status);
+ return ata_error(drive, __FUNCTION__);
 }
 
 /*
diff -urN linux-2.5.19/drivers/ide/device.c linux/drivers/ide/device.c
--- linux-2.5.19/drivers/ide/device.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/device.c 2002-06-01 19:45:30.000000000 +0200
@@ -15,6 +15,9 @@
 /*
  * Common low leved device access code. This is the lowest layer of hardware
  * access.
+ *
+ * This is the place where register set access portability will be handled in
+ * the future.
  */
 
 #include <linux/module.h>
@@ -23,11 +26,9 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/ioport.h>
-#include <linux/blkdev.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <linux/cdrom.h>
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 
@@ -92,4 +93,53 @@
 
 EXPORT_SYMBOL(ata_status);
 
+/*
+ * Handle the nIEN - negated Interrupt ENable of the drive.
+ * This is controlling whatever the drive will acnowlenge commands
+ * with interrupts or not.
+ */
+int ata_irq_enable(struct ata_device *drive, int on)
+{
+ struct ata_channel *ch = drive->channel;
+
+ if (!ch->io_ports[IDE_CONTROL_OFFSET])
+ return 0;
+
+ if (on)
+ OUT_BYTE(0x00, ch->io_ports[IDE_CONTROL_OFFSET]);
+ else {
+ if (!ch->intrproc)
+ OUT_BYTE(0x02, ch->io_ports[IDE_CONTROL_OFFSET]);
+ else
+ ch->intrproc(drive);
+ }
+
+ return 1;
+}
+
+EXPORT_SYMBOL(ata_irq_enable);
+
+/*
+ * Perform a reset operation on the currently selected drive.
+ */
+void ata_reset(struct ata_channel *ch)
+{
+ unsigned long timeout = jiffies + WAIT_WORSTCASE;
+ u8 stat;
+
+ if (!ch->io_ports[IDE_CONTROL_OFFSET])
+ return;
+
+ printk("%s: reset\n", ch->name);
+ OUT_BYTE(0x04, ch->io_ports[IDE_CONTROL_OFFSET]);
+ udelay(10);
+ OUT_BYTE(0x00, ch->io_ports[IDE_CONTROL_OFFSET]);
+ do {
+ mdelay(50);
+ stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
+ } while ((stat & BUSY_STAT) && time_before(jiffies, timeout));
+}
+
+EXPORT_SYMBOL(ata_reset);
+
 MODULE_LICENSE("GPL");
diff -urN linux-2.5.19/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- linux-2.5.19/drivers/ide/hpt34x.c 2002-06-01 18:53:02.000000000 +0200
+++ linux/drivers/ide/hpt34x.c 2002-06-01 17:19:02.000000000 +0200
@@ -264,7 +264,7 @@
         if (drive->type != ATA_DISK)
                 return 0;
 
- ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
+ 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;
diff -urN linux-2.5.19/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c
--- linux-2.5.19/drivers/ide/hpt366.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/hpt366.c 2002-06-01 19:41:26.000000000 +0200
@@ -813,31 +813,26 @@
         if (drive->quirk_list) {
                 /* drives in the quirk_list may not like intr setups/cleanups */
         } else {
- OUT_BYTE((drive)->ctl|2, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
+ OUT_BYTE(0x02, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
         }
 }
 
 static void hpt3xx_maskproc(struct ata_device *drive)
 {
         struct pci_dev *dev = drive->channel->pci_dev;
- const int mask = 0;
+ struct ata_channel *ch = drive->channel;
 
         if (drive->quirk_list) {
                 if (hpt_min_rev(dev, 3)) {
                         u8 reg5a;
                         pci_read_config_byte(dev, 0x5a, &reg5a);
- if (((reg5a & 0x10) >> 4) != mask)
- pci_write_config_byte(dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10));
- } else {
- if (mask) {
- disable_irq(drive->channel->irq);
- } else {
- enable_irq(drive->channel->irq);
- }
- }
+ if ((reg5a & 0x10) >> 4)
+ pci_write_config_byte(dev, 0x5a, reg5a & ~0x10);
+ } else
+ enable_irq(drive->channel->irq);
         } else {
- if (IDE_CONTROL_REG)
- OUT_BYTE(mask ? (drive->ctl | 2) : (drive->ctl & ~2), IDE_CONTROL_REG);
+ if (ch->io_ports[IDE_CONTROL_OFFSET])
+ OUT_BYTE(0x00, ch->io_ports[IDE_CONTROL_OFFSET]);
         }
 }
 
diff -urN linux-2.5.19/drivers/ide/ht6560b.c linux/drivers/ide/ht6560b.c
--- linux-2.5.19/drivers/ide/ht6560b.c 2002-05-29 20:42:48.000000000 +0200
+++ linux/drivers/ide/ht6560b.c 2002-06-01 16:31:10.000000000 +0200
@@ -123,16 +123,16 @@
 static void ht6560b_selectproc(struct ata_device *drive)
 {
         unsigned long flags;
- static byte current_select = 0;
- static byte current_timing = 0;
- byte select, timing;
-
+ static u8 current_select = 0;
+ static u8 current_timing = 0;
+ u8 select, timing;
+
         __save_flags (flags); /* local CPU only */
         __cli(); /* local CPU only */
-
+
         select = HT_CONFIG(drive);
         timing = HT_TIMING(drive);
-
+
         if (select != current_select || timing != current_timing) {
                 current_select = select;
                 current_timing = timing;
@@ -147,7 +147,7 @@
                  * Set timing for this drive:
                  */
                 outb(timing, IDE_SELECT_REG);
- (void) inb(IDE_STATUS_REG);
+ ata_status(drive, 0, 0);
 #ifdef DEBUG
                 printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, select, timing);
 #endif
@@ -160,13 +160,13 @@
  */
 static int __init try_to_init_ht6560b(void)
 {
- byte orig_value;
+ u8 orig_value;
         int i;
-
+
         /* Autodetect ht6560b */
         if ((orig_value=inb(HT_CONFIG_PORT)) == 0xff)
                 return 0;
-
+
         for (i=3;i>0;i--) {
                 outb(0x00, HT_CONFIG_PORT);
                 if (!( (~inb(HT_CONFIG_PORT)) & 0x3f )) {
@@ -183,9 +183,9 @@
          * Ht6560b autodetected
          */
         outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT);
- outb(HT_TIMING_DEFAULT, 0x1f6); /* IDE_SELECT_REG */
- (void) inb(0x1f7); /* IDE_STATUS_REG */
-
+ outb(HT_TIMING_DEFAULT, 0x1f6); /* SELECT */
+ (void) inb(0x1f7); /* STATUS */
+
         printk("\nht6560b " HT6560B_VERSION
                ": chipset detected and initialized"
 #ifdef DEBUG
@@ -228,19 +228,19 @@
                 if (recovery_cycles < 2) recovery_cycles = 2;
                 if (active_cycles > 15) active_cycles = 15;
                 if (recovery_cycles > 15) recovery_cycles = 0; /* 0==16 */
-
+
 #ifdef DEBUG
                 printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n",
                         drive->name, pio - XFER_PIO_0, recovery_cycles, recovery_time, active_cycles, active_time);
 #endif
-
+
                 return (byte)((recovery_cycles << 4) | active_cycles);
         } else {
-
+
 #ifdef DEBUG
                 printk("ht6560b: drive %s setting pio=0\n", drive->name);
 #endif
-
+
                 return HT_TIMING_DEFAULT; /* default setting */
         }
 }
@@ -252,10 +252,10 @@
 {
         unsigned long flags;
         int t = HT_PREFETCH_MODE << 8;
-
+
         save_flags (flags); /* all CPUs */
         cli(); /* all CPUs */
-
+
         /*
          * Prefetch mode and unmask irq seems to conflict
          */
@@ -267,9 +267,9 @@
                 drive->drive_data &= ~t; /* disable prefetch mode */
                 drive->channel->no_unmask = 0;
         }
-
+
         restore_flags (flags); /* all CPUs */
-
+
 #ifdef DEBUG
         printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
 #endif
@@ -279,24 +279,24 @@
 {
         unsigned long flags;
         byte timing;
-
+
         switch (pio) {
         case 8: /* set prefetch off */
         case 9: /* set prefetch on */
                 ht_set_prefetch(drive, pio & 1);
                 return;
         }
-
+
         timing = ht_pio2timings(drive, pio);
-
+
         save_flags (flags); /* all CPUs */
         cli(); /* all CPUs */
-
+
         drive->drive_data &= 0xff00;
         drive->drive_data |= timing;
-
+
         restore_flags (flags); /* all CPUs */
-
+
 #ifdef DEBUG
         printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
 #endif
@@ -305,7 +305,7 @@
 void __init init_ht6560b (void)
 {
         int t;
-
+
         if (check_region(HT_CONFIG_PORT,1)) {
                 printk(KERN_ERR "ht6560b: PORT %#x ALREADY IN USE\n", HT_CONFIG_PORT);
         } else {
diff -urN linux-2.5.19/drivers/ide/icside.c linux/drivers/ide/icside.c
--- linux-2.5.19/drivers/ide/icside.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/icside.c 2002-06-01 17:20:45.000000000 +0200
@@ -476,7 +476,7 @@
                 printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
                        drive->name, dma_stat);
         }
- return ide_error(drive, rq, "dma_intr", drive->status);
+ return ata_error(drive, rq, __FUNCTION__);
 }
 
 static int
diff -urN linux-2.5.19/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.19/drivers/ide/ide.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/ide.c 2002-06-01 19:49:34.000000000 +0200
@@ -378,42 +378,6 @@
         for (unit = 0; unit < MAX_DRIVES; ++unit)
                 check_crc_errors(&ch->drives[unit]);
 
-#if OK_TO_RESET_CONTROLLER
- if (!IDE_CONTROL_REG) {
- __restore_flags(flags);
-
- return ide_stopped;
- }
- /*
- * Note that we also set nIEN while resetting the device,
- * to mask unwanted interrupts from the interface during the reset.
- * However, due to the design of PC hardware, this will cause an
- * immediate interrupt due to the edge transition it produces.
- * This single interrupt gives us a "fast poll" for drives that
- * recover from reset very quickly, saving us the first 50ms wait time.
- */
- OUT_BYTE(drive->ctl|6,IDE_CONTROL_REG); /* set SRST and nIEN */
- udelay(10); /* more than enough time */
- if (drive->quirk_list == 2) {
- OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear SRST and nIEN */
- } else {
- OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */
- }
- udelay(10); /* more than enough time */
- ch->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler(drive, reset_pollfunc, HZ/20, NULL);
-
- /*
- * Some weird controller like resetting themselves to a strange
- * state when the disks are reset this way. At least, the Winbond
- * 553 documentation says that
- */
- if (ch->resetproc != NULL)
- ch->resetproc(drive);
-
- /* FIXME: we should handle mulit mode setting here as well ! */
-#endif
-
         __restore_flags (flags); /* local CPU only */
 
         return ide_started;
@@ -421,8 +385,8 @@
 
 static inline u32 read_24(struct ata_device *drive)
 {
- return (IN_BYTE(IDE_HCYL_REG)<<16) |
- (IN_BYTE(IDE_LCYL_REG)<<8) |
+ return (IN_BYTE(IDE_HCYL_REG) << 16) |
+ (IN_BYTE(IDE_LCYL_REG) << 8) |
                  IN_BYTE(IDE_SECTOR_REG);
 }
 
@@ -457,11 +421,9 @@
                             (drive->id->cfs_enable_2 & 0x0400) &&
                             (drive->addressing == 1)) {
                                 /* The following command goes to the hob file! */
-
- OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG);
+ OUT_BYTE(0x80, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
                                 args->hobfile.feature = IN_BYTE(IDE_FEATURE_REG);
                                 args->hobfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
-
                                 args->hobfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
                                 args->hobfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
                                 args->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
@@ -547,13 +509,13 @@
                                         __u64 sectors = 0;
                                         u32 low = 0, high = 0;
                                         low = read_24(drive);
- OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG);
+ OUT_BYTE(0x80, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
                                         high = read_24(drive);
 
                                         sectors = ((__u64)high << 24) | low;
                                         printk(", LBAsect=%lld, high=%d, low=%d", (long long) sectors, high, low);
                                 } else {
- byte cur = IN_BYTE(IDE_SELECT_REG);
+ u8 cur = IN_BYTE(IDE_SELECT_REG);
                                         if (cur & 0x40) { /* using LBA? */
                                                 printk(", LBAsect=%ld", (unsigned long)
                                                  ((cur&0xf)<<24)
@@ -632,9 +594,10 @@
 /*
  * Take action based on the error returned by the drive.
  */
-ide_startstop_t ide_error(struct ata_device *drive, struct request *rq, const char *msg, byte stat)
+ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const char *msg)
 {
- byte err;
+ u8 err;
+ u8 stat = drive->status;
 
         err = ide_dump_status(drive, rq, msg, stat);
         if (!drive || !rq)
@@ -645,18 +608,18 @@
                 ide_end_drive_cmd(drive, rq, err);
                 return ide_stopped;
         }
-
- if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else {
+ /* other bits are useless when BUSY */
+ if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr))
+ rq->errors |= ERROR_RESET; /* FIXME: What's that?! */
+ else {
                 if (drive->type == ATA_DISK && (stat & ERR_STAT)) {
                         /* err has different meaning on cdrom and tape */
                         if (err == ABRT_ERR) {
                                 if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY)
                                         return ide_stopped; /* some newer drives don't support WIN_SPECIFY */
- } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) {
+ } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR))
                                 drive->crc_count++; /* UDMA crc error -- just retry the operation */
- } else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */
+ else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */
                                 rq->errors = ERROR_MAX;
                         else if (err & TRK0_ERR) /* help it find track zero */
                                 rq->errors |= ERROR_RECAL;
@@ -665,7 +628,8 @@
                 if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)
                         try_to_flush_leftover_data(drive);
         }
- if (!ata_status(drive, 0, BUSY_STAT|DRQ_STAT))
+
+ if (!ata_status(drive, 0, BUSY_STAT | DRQ_STAT))
                 OUT_BYTE(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); /* force an abort */
 
         if (rq->errors >= ERROR_MAX) {
@@ -680,6 +644,7 @@
                 if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
                         return do_recalibrate(drive);
         }
+
         return ide_stopped;
 }
 
@@ -689,10 +654,11 @@
 static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *rq)
 {
         u8 *args = rq->buffer;
- int retries = 10;
 
         ide__sti(); /* local CPU only */
         if (!ata_status(drive, 0, DRQ_STAT) && args && args[3]) {
+ int retries = 10;
+
                 ata_read(drive, &args[4], args[3] * SECTOR_WORDS);
 
                 while (!ata_status(drive, 0, BUSY_STAT) && retries--)
@@ -700,7 +666,7 @@
         }
 
         if (!ata_status(drive, READY_STAT, BAD_STAT))
- return ide_error(drive, rq, "drive_cmd", drive->status); /* already calls ide_end_drive_cmd */
+ return ata_error(drive, rq, __FUNCTION__); /* already calls ide_end_drive_cmd */
         ide_end_drive_cmd(drive, rq, GET_ERR());
 
         return ide_stopped;
@@ -712,8 +678,7 @@
 static void drive_cmd(struct ata_device *drive, u8 cmd, u8 nsect)
 {
         ide_set_handler(drive, drive_cmd_intr, WAIT_CMD, NULL);
- if (IDE_CONTROL_REG)
- OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
+ ata_irq_enable(drive, 1);
         ata_mask(drive);
         OUT_BYTE(nsect, IDE_NSECTOR_REG);
         OUT_BYTE(cmd, IDE_COMMAND_REG);
@@ -723,7 +688,7 @@
 /*
  * Busy-wait for the drive status to be not "busy". Check then the status for
  * all of the "good" bits and none of the "bad" bits, and if all is okay it
- * returns 0. All other cases return 1 after invoking ide_error() -- caller
+ * returns 0. All other cases return 1 after invoking error handler -- caller
  * should just return.
  *
  * This routine should get fixed to not hog the cpu during extra long waits..
@@ -744,12 +709,13 @@
                 return 1;
         }
 
- udelay(1); /* spec allows drive 400ns to assert "BUSY" */
+ /* spec allows drive 400ns to assert "BUSY" */
+ udelay(1);
         if (!ata_status(drive, 0, BUSY_STAT)) {
                 timeout += jiffies;
                 while (!ata_status(drive, 0, BUSY_STAT)) {
                         if (time_after(jiffies, timeout)) {
- *startstop = ide_error(drive, rq, "status timeout", drive->status);
+ *startstop = ata_error(drive, rq, "status timeout");
                                 return 1;
                         }
                 }
@@ -766,7 +732,7 @@
                 if (ata_status(drive, good, bad))
                         return 0;
         }
- *startstop = ide_error(drive, rq, "status error", drive->status);
+ *startstop = ata_error(drive, rq, "status error");
 
         return 1;
 }
@@ -1134,15 +1100,15 @@
 
                 ch = drive->channel;
 
- if (channel->sharing_irq && ch != channel && ch->io_ports[IDE_CONTROL_OFFSET]) {
- /* set nIEN for previous channel */
- /* FIXME: check this! It appears to act on the current channel! */
-
- if (ch->intrproc)
- ch->intrproc(drive);
- else
- OUT_BYTE((drive)->ctl|2, ch->io_ports[IDE_CONTROL_OFFSET]);
- }
+ /* Disable intrerrupts from the drive on the previous channel.
+ *
+ * FIXME: This should be only done if we are indeed sharing the same
+ * interrupt line with it.
+ *
+ * FIXME: check this! It appears to act on the current channel!
+ */
+ if (ch != channel && channel->sharing_irq && ch->irq == channel->irq)
+ ata_irq_enable(drive, 0);
 
                 /* Remember the last drive we where acting on.
                  */
@@ -1279,7 +1245,7 @@
                                         startstop = ide_stopped;
                                         dma_timeout_retry(drive, drive->rq);
                                 } else
- startstop = ide_error(drive, drive->rq, "irq timeout", drive->status);
+ startstop = ata_error(drive, drive->rq, "irq timeout");
                         }
                         enable_irq(ch->irq);
 
@@ -1571,33 +1537,6 @@
         return res;
 }
 
-void ide_fixstring (byte *s, const int bytecount, const int byteswap)
-{
- byte *p = s, *end = &s[bytecount & ~1]; /* bytecount must be even */
-
- if (byteswap) {
- /* convert from big-endian to host byte order */
- for (p = end ; p != s;) {
- unsigned short *pp = (unsigned short *) (p -= 2);
- *pp = ntohs(*pp);
- }
- }
-
- /* strip leading blanks */
- while (s != end && *s == ' ')
- ++s;
-
- /* compress internal blanks and strip trailing blanks */
- while (s != end && *s) {
- if (*s++ != ' ' || (s != end && *s && *s != ' '))
- *p++ = *(s-1);
- }
-
- /* wipe out trailing garbage */
- while (p != end)
- *p++ = '\0';
-}
-
 struct block_device_operations ide_fops[] = {{
         owner: THIS_MODULE,
         open: ide_open,
@@ -1616,8 +1555,8 @@
 
 EXPORT_SYMBOL(ide_set_handler);
 EXPORT_SYMBOL(ide_dump_status);
-EXPORT_SYMBOL(ide_error);
-EXPORT_SYMBOL(ide_fixstring);
+EXPORT_SYMBOL(ata_error);
+
 EXPORT_SYMBOL(ide_wait_stat);
 EXPORT_SYMBOL(restart_request);
 EXPORT_SYMBOL(ide_end_drive_cmd);
diff -urN linux-2.5.19/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.19/drivers/ide/ide-cd.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/ide-cd.c 2002-06-01 18:40:19.000000000 +0200
@@ -594,7 +594,7 @@
                 pc = (struct packet_command *) rq->special;
                 pc->stat = 1;
                 cdrom_end_request(drive, rq, 1);
- *startstop = ide_error(drive, rq, "request sense failure", drive->status);
+ *startstop = ata_error(drive, rq, "request sense failure");
 
                 return 1;
         } else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
@@ -673,7 +673,7 @@
                 } else if ((err & ~ABRT_ERR) != 0) {
                         /* Go to the default handler
                            for other errors. */
- *startstop = ide_error(drive, rq, __FUNCTION__, drive->status);
+ *startstop = ata_error(drive, rq, __FUNCTION__);
                         return 1;
                 } else if ((++rq->errors > ERROR_MAX)) {
                         /* We've racked up too many retries. Abort. */
@@ -751,9 +751,7 @@
 
         OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG);
         OUT_BYTE(xferlen >> 8 , IDE_HCYL_REG);
- if (IDE_CONTROL_REG)
- OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
-
+ ata_irq_enable(drive, 1);
         if (info->dma)
                 udma_start(drive, rq);
 
@@ -918,7 +916,7 @@
                         __ide_end_request(drive, rq, 1, rq->nr_sectors);
                         return ide_stopped;
                 } else
- return ide_error (drive, rq, "dma error", stat);
+ return ata_error(drive, rq, "dma error");
         }
 
         /* Read the interrupt reason and the transfer length. */
@@ -1498,7 +1496,7 @@
          */
         if (dma) {
                 if (dma_error)
- return ide_error(drive, rq, "dma error", stat);
+ return ata_error(drive, rq, "dma error");
 
                 __ide_end_request(drive, rq, 1, rq->nr_sectors);
                 return ide_stopped;
diff -urN linux-2.5.19/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.19/drivers/ide/ide-disk.c 2002-05-29 20:42:43.000000000 +0200
+++ linux/drivers/ide/ide-disk.c 2002-06-01 19:02:41.000000000 +0200
@@ -257,14 +257,15 @@
         args.taskfile.sector_number = block; /* low lba */
         args.taskfile.low_cylinder = (block >>= 8); /* mid lba */
         args.taskfile.high_cylinder = (block >>= 8); /* hi lba */
+ args.taskfile.device_head = drive->select.all;
 
         args.hobfile.sector_number = (block >>= 8); /* low lba */
         args.hobfile.low_cylinder = (block >>= 8); /* mid lba */
         args.hobfile.high_cylinder = (block >>= 8); /* hi lba */
+ args.hobfile.device_head = drive->select.all;
+
+ args.hobfile.control = 0x80;
 
- args.taskfile.device_head = drive->select.all;
- args.hobfile.device_head = args.taskfile.device_head;
- args.hobfile.control = (drive->ctl|0x80);
         args.taskfile.command = get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
@@ -727,7 +728,7 @@
         args.hobfile.high_cylinder = (addr_req >>= 8);
 
         args.hobfile.device_head = 0x40;
- args.hobfile.control = (drive->ctl | 0x80);
+ args.hobfile.control = 0x80;
 
         args.handler = task_no_data_intr;
         /* submit command request */
diff -urN linux-2.5.19/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.5.19/drivers/ide/ide-floppy.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/ide-floppy.c 2002-06-01 18:22:08.000000000 +0200
@@ -1064,8 +1064,7 @@
         }
 #endif
 
- if (IDE_CONTROL_REG)
- OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
+ ata_irq_enable(drive, 1);
         OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */
         OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG);
         OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG);
diff -urN linux-2.5.19/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.19/drivers/ide/ide-pmac.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/ide-pmac.c 2002-06-01 18:17:36.000000000 +0200
@@ -434,7 +434,7 @@
                 goto out;
         }
         udelay(10);
- OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
+ ata_irq_enale(drive, 0);
         OUT_BYTE(command, IDE_NSECTOR_REG);
         OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
         OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
@@ -443,7 +443,7 @@
         ide__sti(); /* local CPU only -- for jiffies */
         result = wait_for_ready(drive);
         __restore_flags(flags); /* local CPU only */
- OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
+ ata_irq_enable(drive, 1);
         if (result)
                 printk(KERN_ERR "pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n");
 out:
@@ -1330,7 +1330,7 @@
                         /* Normal MultiWord DMA modes. */
                         drive->using_dma = pmac_ide_mdma_enable(drive, idx);
                 }
- OUT_BYTE(0, IDE_CONTROL_REG);
+ ata_irq_enable(drive, 1);
                 /* Apply settings to controller */
                 pmac_ide_selectproc(drive);
         }
diff -urN linux-2.5.19/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux-2.5.19/drivers/ide/ide-tape.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/ide-tape.c 2002-06-01 18:32:37.000000000 +0200
@@ -2263,8 +2263,7 @@
         }
 #endif
 
- if (IDE_CONTROL_REG)
- OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
+ ata_irq_enable(drive, 1);
         OUT_BYTE (dma_ok ? 1 : 0, IDE_FEATURE_REG); /* Use PIO/DMA */
         OUT_BYTE (bcount.b.high, IDE_BCOUNTH_REG);
         OUT_BYTE (bcount.b.low, IDE_BCOUNTL_REG);
diff -urN linux-2.5.19/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.19/drivers/ide/ide-taskfile.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c 2002-06-01 19:34:02.000000000 +0200
@@ -169,12 +169,12 @@
         if (drive->waiting_for_dma)
                 return udma_irq_status(drive);
 
-#if 0
- /* need to guarantee 400ns since last command was issued */
- udelay(1);
-#endif
+ /*
+ * Need to guarantee 400ns since last command was issued?
+ */
 
- /* FIXME: promote this to the general status read method perhaps */
+ /* FIXME: promote this to the general status read method perhaps.
+ */
 #ifdef CONFIG_IDEPCI_SHARE_IRQ
         /*
          * We do a passive status test under shared PCI interrupts on
@@ -182,16 +182,16 @@
          * an interrupt with another pci card/device. We make no assumptions
          * about possible isa-pnp and pci-pnp issues yet.
          */
- if (IDE_CONTROL_REG)
+ if (drive->channel->io_ports[IDE_CONTROL_OFFSET])
                 drive->status = GET_ALTSTAT();
         else
 #endif
- ata_status(drive, 0, 0); /* Note: this may clear a pending IRQ!! */
+ ata_status(drive, 0, 0); /* Note: this may clear a pending IRQ! */
 
         if (drive->status & BUSY_STAT)
                 return 0; /* drive busy: definitely not interrupting */
 
- return 1; /* drive ready: *might* be interrupting */
+ return 1; /* drive ready: *might* be interrupting */
 }
 
 /*
@@ -246,7 +246,7 @@
 
         if (!ok || !rq->nr_sectors) {
                 if (drive->status & (ERR_STAT | DRQ_STAT)) {
- startstop = ide_error(drive, rq, __FUNCTION__, drive->status);
+ startstop = ata_error(drive, rq, __FUNCTION__);
 
                         return startstop;
                 }
@@ -316,24 +316,9 @@
         struct hd_driveid *id = drive->id;
         u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
 
-#if 0
- printk("ata_taskfile ... %p\n", args->handler);
-
- printk(" sector feature %02x\n", args->taskfile.feature);
- printk(" sector count %02x\n", args->taskfile.sector_count);
- printk(" drive/head %02x\n", args->taskfile.device_head);
- printk(" command %02x\n", args->taskfile.command);
-
- if (rq)
- printk(" rq->nr_sectors %2li\n", rq->nr_sectors);
- else
- printk(" rq-> = null\n");
-#endif
-
         /* (ks/hs): Moved to start, do not use for multiple out commands */
         if (args->handler != task_mulout_intr) {
- if (IDE_CONTROL_REG)
- OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
+ ata_irq_enable(drive, 1);
                 ata_mask(drive);
         }
 
@@ -412,7 +397,7 @@
 ide_startstop_t recal_intr(struct ata_device *drive, struct request *rq)
 {
         if (!ata_status(drive, READY_STAT, BAD_STAT))
- return ide_error(drive, rq, "recal_intr", drive->status);
+ return ata_error(drive, rq, __FUNCTION__);
 
         return ide_stopped;
 }
@@ -429,7 +414,7 @@
         if (!ata_status(drive, READY_STAT, BAD_STAT)) {
                 /* Keep quiet for NOP because it is expected to fail. */
                 if (args && args->taskfile.command != WIN_NOP)
- return ide_error(drive, rq, "task_no_data_intr", drive->status);
+ return ata_error(drive, rq, __FUNCTION__);
         }
 
         if (args)
@@ -443,12 +428,12 @@
  */
 static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
 {
- char *pBuf = NULL;
+ char *buf = NULL;
         unsigned long flags;
 
         if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
                 if (drive->status & (ERR_STAT|DRQ_STAT))
- return ide_error(drive, rq, __FUNCTION__, drive->status);
+ return ata_error(drive, rq, __FUNCTION__);
 
                 if (!(drive->status & BUSY_STAT)) {
                         DTF("task_in_intr to Soon wait for next interrupt\n");
@@ -458,11 +443,11 @@
                 }
         }
         DTF("stat: %02x\n", drive->status);
- pBuf = ide_map_rq(rq, &flags);
- DTF("Read: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);
+ buf = ide_map_rq(rq, &flags);
+ DTF("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
 
- ata_read(drive, pBuf, SECTOR_WORDS);
- ide_unmap_rq(rq, pBuf, &flags);
+ ata_read(drive, buf, SECTOR_WORDS);
+ ide_unmap_rq(rq, buf, &flags);
 
         /* First segment of the request is complete. note that this does not
          * necessarily mean that the entire request is done!! this is only true
@@ -512,22 +497,22 @@
  */
 static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
 {
- char *pBuf = NULL;
+ char *buf = NULL;
         unsigned long flags;
 
         if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
- return ide_error(drive, rq, __FUNCTION__, drive->status);
+ return ata_error(drive, rq, __FUNCTION__);
 
         if (!rq->current_nr_sectors)
                 if (!ide_end_request(drive, rq, 1))
                         return ide_stopped;
 
         if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
- pBuf = ide_map_rq(rq, &flags);
- DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);
+ buf = ide_map_rq(rq, &flags);
+ DTF("write: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
 
- ata_write(drive, pBuf, SECTOR_WORDS);
- ide_unmap_rq(rq, pBuf, &flags);
+ ata_write(drive, buf, SECTOR_WORDS);
+ ide_unmap_rq(rq, buf, &flags);
                 rq->errors = 0;
                 rq->current_nr_sectors--;
         }
@@ -542,14 +527,14 @@
  */
 static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq)
 {
- char *pBuf = NULL;
+ char *buf = NULL;
         unsigned int msect, nsect;
         unsigned long flags;
 
         if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
- if (drive->status & (ERR_STAT|DRQ_STAT)) {
- return ide_error(drive, rq, __FUNCTION__, drive->status);
- }
+ if (drive->status & (ERR_STAT|DRQ_STAT))
+ return ata_error(drive, rq, __FUNCTION__);
+
                 /* no data yet, so wait for another interrupt */
                 ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
                 return ide_started;
@@ -563,12 +548,12 @@
                 if (nsect > msect)
                         nsect = msect;
 
- pBuf = ide_map_rq(rq, &flags);
+ buf = ide_map_rq(rq, &flags);
 
                 DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n",
- pBuf, nsect, rq->current_nr_sectors);
- ata_read(drive, pBuf, nsect * SECTOR_WORDS);
- ide_unmap_rq(rq, pBuf, &flags);
+ buf, nsect, rq->current_nr_sectors);
+ ata_read(drive, buf, nsect * SECTOR_WORDS);
+ ide_unmap_rq(rq, buf, &flags);
                 rq->errors = 0;
                 rq->current_nr_sectors -= nsect;
                 msect -= nsect;
diff -urN linux-2.5.19/drivers/ide/main.c linux/drivers/ide/main.c
--- linux-2.5.19/drivers/ide/main.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/main.c 2002-06-01 18:59:44.000000000 +0200
@@ -205,9 +205,8 @@
                 struct ata_device *drive = &ch->drives[unit];
 
                 drive->type = ATA_DISK;
- drive->select.all = (unit<<4)|0xa0;
+ drive->select.all = (unit << 4) | 0xa0;
                 drive->channel = ch;
- drive->ctl = 0x08;
                 drive->ready_stat = READY_STAT;
                 drive->bad_wstat = BAD_W_STAT;
                 sprintf(drive->name, "hd%c", 'a' + (index * MAX_DRIVES) + unit);
diff -urN linux-2.5.19/drivers/ide/ns87415.c linux/drivers/ide/ns87415.c
--- linux-2.5.19/drivers/ide/ns87415.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/ns87415.c 2002-06-01 19:25:31.000000000 +0200
@@ -141,10 +141,6 @@
         struct pci_dev *dev = hwif->pci_dev;
         unsigned int ctrl, using_inta;
         byte progif;
-#ifdef __sparc_v9__
- int timeout;
- byte stat;
-#endif
 
         /* Set a good latency timer and cache line size value. */
         (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
@@ -197,16 +193,7 @@
                  * XXX: Reset the device, if we don't it will not respond
                  * to select properly during first probe.
                  */
- timeout = 10000;
- outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
- udelay(10);
- outb(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
- do {
- udelay(50);
- stat = inb(hwif->io_ports[IDE_STATUS_OFFSET]);
- if (stat == 0xff)
- break;
- } while ((stat & BUSY_STAT) && --timeout);
+ ata_reset(struct ata_channel *hwif);
 #endif
         }
 
diff -urN linux-2.5.19/drivers/ide/pcidma.c linux/drivers/ide/pcidma.c
--- linux-2.5.19/drivers/ide/pcidma.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/pcidma.c 2002-06-01 17:19:51.000000000 +0200
@@ -41,6 +41,7 @@
 {
         u8 dma_stat;
         dma_stat = udma_stop(drive);
+
         if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
                 if (!dma_stat) {
                         __ide_end_request(drive, rq, 1, rq->nr_sectors);
@@ -49,7 +50,8 @@
                 printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
                        drive->name, dma_stat);
         }
- return ide_error(drive, rq, "dma_intr", drive->status);
+
+ return ata_error(drive, rq, __FUNCTION__);
 }
 
 /*
@@ -118,7 +120,7 @@
 static int dma_timer_expiry(struct ata_device *drive, struct request *rq)
 {
         /* FIXME: What's that? */
- u8 dma_stat = inb(drive->channel->dma_base+2);
+ u8 dma_stat = inb(drive->channel->dma_base + 2);
 
 #ifdef DEBUG
         printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat);
@@ -130,10 +132,11 @@
 
         if (dma_stat & 2) { /* ERROR */
                 ata_status(drive, 0, 0);
- return ide_error(drive, rq, "dma_timer_expiry", drive->status);
+ return ata_error(drive, rq, __FUNCTION__);
         }
         if (dma_stat & 1) /* DMAing */
                 return WAIT_CMD;
+
         return 0;
 }
 
diff -urN linux-2.5.19/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.5.19/drivers/ide/pdc202xx.c 2002-05-29 20:42:58.000000000 +0200
+++ linux/drivers/ide/pdc202xx.c 2002-06-01 19:27:10.000000000 +0200
@@ -686,9 +686,11 @@
 
 void pdc202xx_new_reset(struct ata_device *drive)
 {
- set_reg_and_wait(0x04,IDE_CONTROL_REG, 1000);
- set_reg_and_wait(0x00,IDE_CONTROL_REG, 1000);
- printk("PDC202XX: %s channel reset.\n",
+ ata_reset(drive->channel);
+ mdelay(1000);
+ ata_irq_enable(drive, 1);
+ mdelay(1000);
+ printk(KERN_INFO "PDC202XX: %s channel reset.\n",
                 drive->channel->unit ? "Secondary" : "Primary");
 }
 
diff -urN linux-2.5.19/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c
--- linux-2.5.19/drivers/ide/pdc4030.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/pdc4030.c 2002-06-01 18:24:23.000000000 +0200
@@ -243,9 +243,8 @@
         if (inb(IDE_NSECTOR_REG) == 0xFF || inb(IDE_SECTOR_REG) == 0xFF) {
                 return 0;
         }
- if (IDE_CONTROL_REG)
- outb(0x08, IDE_CONTROL_REG);
- if (pdc4030_cmd(drive,PROMISE_GET_CONFIG)) {
+ ata_irq_enable(drive, 1);
+ if (pdc4030_cmd(drive, PROMISE_GET_CONFIG)) {
                 return 0;
         }
         if (ide_wait_stat(&startstop, drive, NULL, DATA_READY,BAD_W_STAT,WAIT_DRQ)) {
@@ -379,7 +378,7 @@
         char *to;
 
         if (!ata_status(drive, DATA_READY, BAD_R_STAT))
- return ide_error(drive, rq, "promise_read_intr", drive->status);
+ return ata_error(drive, rq, __FUNCTION__);
 
 read_again:
         do {
@@ -438,7 +437,7 @@
                 }
                 printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left "
                        "!DRQ !BUSY\n", drive->name);
- return ide_error(drive, rq, "promise read intr", drive->status);
+ return ata_error(drive, rq, "promise read intr");
         }
         return ide_stopped;
 }
@@ -463,7 +462,7 @@
                 ch->poll_timeout = 0;
                 printk(KERN_ERR "%s: completion timeout - still busy!\n",
                        drive->name);
- return ide_error(drive, rq, "busy timeout", drive->status);
+ return ata_error(drive, rq, "busy timeout");
         }
 
         ch->poll_timeout = 0;
@@ -540,9 +539,9 @@
                         return ide_started; /* continue polling... */
                 }
                 ch->poll_timeout = 0;
- printk(KERN_ERR "%s: write timed out!\n",drive->name);
+ printk(KERN_ERR "%s: write timed out!\n", drive->name);
                 ata_status(drive, 0, 0);
- return ide_error(drive, rq, "write timeout", drive->status);
+ return ata_error(drive, rq, "write timeout");
         }
 
         /*
@@ -616,11 +615,11 @@
         if (!(rq->flags & REQ_CMD)) {
                 blk_dump_rq_flags(rq, "pdc4030 bad flags");
                 ide_end_request(drive, rq, 0);
+
                 return ide_stopped;
         }
 
- if (IDE_CONTROL_REG)
- outb(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
+ ata_irq_enable(drive, 1); /* clear nIEN */
         ata_mask(drive);
 
         outb(taskfile->feature, IDE_FEATURE_REG);
diff -urN linux-2.5.19/drivers/ide/probe.c linux/drivers/ide/probe.c
--- linux-2.5.19/drivers/ide/probe.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/probe.c 2002-06-01 19:15:27.000000000 +0200
@@ -267,6 +267,34 @@
 #endif
 }
 
+void ide_fixstring(char *s, const int bytecount, const int byteswap)
+{
+ char *p = s;
+ char *end = &s[bytecount & ~1]; /* bytecount must be even */
+
+ if (byteswap) {
+ /* convert from big-endian to host byte order */
+ for (p = end ; p != s;) {
+ unsigned short *pp = (unsigned short *) (p -= 2);
+ *pp = ntohs(*pp);
+ }
+ }
+
+ /* strip leading blanks */
+ while (s != end && *s == ' ')
+ ++s;
+
+ /* compress internal blanks and strip trailing blanks */
+ while (s != end && *s) {
+ if (*s++ != ' ' || (s != end && *s && *s != ' '))
+ *p++ = *(s-1);
+ }
+
+ /* wipe out trailing garbage */
+ while (p != end)
+ *p++ = '\0';
+}
+
 /*
  * All hosts that use the 80c ribbon must use this!
  */
@@ -280,7 +308,7 @@
 }
 
 /*
- * Similar to ide_wait_stat(), except it never calls ide_error internally.
+ * Similar to ide_wait_stat(), except it never calls ata_error internally.
  * This is a kludge to handle the new ide_config_drive_speed() function,
  * and should not otherwise be used anywhere. Eventually, the tuneproc's
  * should be updated to return ide_startstop_t, in which case we can get
@@ -292,13 +320,13 @@
  */
 int ide_config_drive_speed(struct ata_device *drive, byte speed)
 {
- struct ata_channel *hwif = drive->channel;
+ struct ata_channel *ch = drive->channel;
         int i;
         int error = 1;
 
 #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__)
         u8 unit = (drive->select.b.unit & 0x01);
- outb(inb(hwif->dma_base + 2) & ~(1 << (5 + unit)), hwif->dma_base + 2);
+ outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2);
 #endif
 
         /*
@@ -309,18 +337,17 @@
         /*
          * Select the drive, and issue the SETFEATURES command
          */
- disable_irq(hwif->irq); /* disable_irq_nosync ?? */
+ disable_irq(ch->irq); /* disable_irq_nosync ?? */
         udelay(1);
         ata_select(drive, 0);
         ata_mask(drive);
         udelay(1);
- if (IDE_CONTROL_REG)
- OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
+ ata_irq_enable(drive, 0);
         OUT_BYTE(speed, IDE_NSECTOR_REG);
         OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
         OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
- if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
- OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
+ if (drive->quirk_list == 2)
+ ata_irq_enable(drive, 1);
         udelay(1);
 
         /*
@@ -355,7 +382,7 @@
 
         ata_mask(drive);
 
- enable_irq(hwif->irq);
+ enable_irq(ch->irq);
 
         if (error) {
                 ide_dump_status(drive, NULL, "set_drive_speed_status", drive->status);
@@ -368,9 +395,9 @@
 
 #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__)
         if (speed > XFER_PIO_4) {
- outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
+ outb(inb(ch->dma_base + 2)|(1 << (5 + unit)), ch->dma_base + 2);
         } else {
- outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
+ outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2);
         }
 #endif
 
@@ -391,6 +418,7 @@
                 case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break;
                 default: break;
         }
+
         return error;
 }
 
@@ -446,9 +474,9 @@
                  || (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */
                         bswap ^= 1; /* Vertos drives may still be weird */
         }
- ide_fixstring (id->model, sizeof(id->model), bswap);
- ide_fixstring (id->fw_rev, sizeof(id->fw_rev), bswap);
- ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap);
+ ide_fixstring(id->model, sizeof(id->model), bswap);
+ ide_fixstring(id->fw_rev, sizeof(id->fw_rev), bswap);
+ ide_fixstring(id->serial_no, sizeof(id->serial_no), bswap);
 
         if (strstr(id->model, "E X A B Y T E N E S T"))
                 goto err_misc;
@@ -566,36 +594,40 @@
  */
 static int identify(struct ata_device *drive, u8 cmd)
 {
- int rc;
+ struct ata_channel *ch = drive->channel;
+ int rc = 1;
         int autoprobe = 0;
         unsigned long cookie = 0;
         ide_ioreg_t hd_status;
         unsigned long timeout;
- u8 s;
- u8 a;
 
 
- if (IDE_CONTROL_REG && !drive->channel->irq) {
- autoprobe = 1;
- cookie = probe_irq_on();
- OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */
- }
+ /* FIXME: perhaps we should be just using allways the status register,
+ * since it should simplify the code significantly.
+ */
+ if (ch->io_ports[IDE_CONTROL_OFFSET]) {
+ u8 s;
+ u8 a;
+
+ if (!drive->channel->irq) {
+ autoprobe = 1;
+ cookie = probe_irq_on();
+ ata_irq_enable(drive, 1); /* enable device irq */
+ }
 
- rc = 1;
- if (IDE_CONTROL_REG) {
                 /* take a deep breath */
                 mdelay(50);
- a = IN_BYTE(IDE_ALTSTATUS_REG);
- s = IN_BYTE(IDE_STATUS_REG);
+ a = IN_BYTE(ch->io_ports[IDE_ALTSTATUS_OFFSET]);
+ s = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
                 if ((a ^ s) & ~INDEX_STAT) {
                         printk("%s: probing with STATUS(0x%02x) instead of ALTSTATUS(0x%02x)\n", drive->name, s, a);
- hd_status = IDE_STATUS_REG; /* ancient Seagate drives, broken interfaces */
+ hd_status = ch->io_ports[IDE_STATUS_OFFSET]; /* ancient Seagate drives, broken interfaces */
                 } else {
- hd_status = IDE_ALTSTATUS_REG; /* use non-intrusive polling */
+ hd_status = ch->io_ports[IDE_ALTSTATUS_OFFSET]; /* use non-intrusive polling */
                 }
         } else {
                 mdelay(50);
- hd_status = IDE_STATUS_REG;
+ hd_status = ch->io_ports[IDE_STATUS_OFFSET];
         }
 
         /* set features register for atapi identify command to be sure of reply */
@@ -637,8 +669,8 @@
         if (autoprobe) {
                 int irq;
 
- OUT_BYTE(drive->ctl | 0x02, IDE_CONTROL_REG); /* mask device irq */
- ata_status(drive, 0, 0); /* clear drive IRQ */
+ ata_irq_enable(drive, 0); /* mask device irq */
+ ata_status(drive, 0, 0); /* clear drive IRQ */
                 udelay(5);
                 irq = probe_irq_off(cookie);
                 if (!drive->channel->irq) {
@@ -855,19 +887,8 @@
 
         device_register(&ch->dev);
 
- if (ch->reset && ch->io_ports[IDE_CONTROL_OFFSET]) {
- unsigned long timeout = jiffies + WAIT_WORSTCASE;
- u8 stat;
-
- printk("%s: reset\n", ch->name);
- OUT_BYTE(12, ch->io_ports[IDE_CONTROL_OFFSET]);
- udelay(10);
- OUT_BYTE(8, ch->io_ports[IDE_CONTROL_OFFSET]);
- do {
- mdelay(50);
- stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
- } while ((stat & BUSY_STAT) && time_before(jiffies, timeout));
- }
+ if (ch->reset)
+ ata_reset(ch);
 
         __restore_flags(flags); /* local CPU only */
 
@@ -969,14 +990,19 @@
          * Allocate the irq, if not already obtained for another channel
          */
         if (!match || match->irq != ch->irq) {
+ struct ata_device tmp;
 #ifdef CONFIG_IDEPCI_SHARE_IRQ
                 int sa = IDE_CHIPSET_IS_PCI(ch->chipset) ? SA_SHIRQ : SA_INTERRUPT;
 #else
                 int sa = IDE_CHIPSET_IS_PCI(ch->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT;
 #endif
 
- if (ch->io_ports[IDE_CONTROL_OFFSET])
- OUT_BYTE(0x08, ch->io_ports[IDE_CONTROL_OFFSET]); /* clear nIEN */
+ /* Enable interrupts triggered by the drive. We use a shallow
+ * device structure, just to use the generic function very
+ * early.
+ */
+ tmp.channel = ch;
+ ata_irq_enable(&tmp, 1);
 
                 if (request_irq(ch->irq, &ata_irq_request, sa, ch->name, ch)) {
                         if (!match) {
@@ -1240,5 +1266,6 @@
 }
 
 EXPORT_SYMBOL(ata_fix_driveid);
+EXPORT_SYMBOL(ide_fixstring);
 EXPORT_SYMBOL(eighty_ninty_three);
 EXPORT_SYMBOL(ide_config_drive_speed);
diff -urN linux-2.5.19/drivers/ide/qd65xx.c linux/drivers/ide/qd65xx.c
--- linux-2.5.19/drivers/ide/qd65xx.c 2002-05-29 20:42:50.000000000 +0200
+++ linux/drivers/ide/qd65xx.c 2002-06-01 16:48:03.000000000 +0200
@@ -173,9 +173,7 @@
 
         if (!*drive->id->model) return 0;
 
- strncpy(model,drive->id->model,40);
- ide_fixstring(model,40,1); /* byte-swap */
-
+ strncpy(model,drive->id->model, 40);
         for (p = qd65xx_timing ; p->offset != -1 ; p++) {
                 if (!strncmp(p->model, model+p->offset, 4)) {
                         printk(KERN_DEBUG "%s: listed !\n", drive->name);
diff -urN linux-2.5.19/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.19/drivers/ide/tcq.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/ide/tcq.c 2002-06-01 17:41:40.000000000 +0200
@@ -55,17 +55,6 @@
 static ide_startstop_t ide_dmaq_intr(struct ata_device *drive, struct request *rq);
 static ide_startstop_t service(struct ata_device *drive, struct request *rq);
 
-static inline void drive_ctl_nien(struct ata_device *drive, int set)
-{
-#ifdef IDE_TCQ_NIEN
- if (IDE_CONTROL_REG) {
- int mask = set ? 0x02 : 0x00;
-
- OUT_BYTE(drive->ctl | mask, IDE_CONTROL_REG);
- }
-#endif
-}
-
 static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request *rq)
 {
         struct ata_taskfile *args = rq->special;
@@ -136,11 +125,10 @@
         rq->rq_dev = mk_kdev(drive->channel->major, (drive->select.b.unit)<<PARTN_BITS);
         _elv_add_request(q, rq, 0, 0);
 
- /*
- * make sure that nIEN is cleared
- */
 out:
- drive_ctl_nien(drive, 0);
+#ifdef IDE_TCQ_NIEN
+ ata_irq_enable(drive, 1);
+#endif
 
         /*
          * start doing stuff again
@@ -250,8 +238,9 @@
         if (drive != drive->channel->drive)
                 ata_select(drive, 10);
 
- drive_ctl_nien(drive, 1);
-
+#ifdef IDE_TCQ_NIEN
+ ata_irq_enable(drive, 0);
+#endif
         /*
          * send SERVICE, wait 400ns, wait for BUSY_STAT to clear
          */
@@ -265,7 +254,9 @@
                 return ide_stopped;
         }
 
- drive_ctl_nien(drive, 0);
+#ifdef IDE_TCQ_NIEN
+ ata_irq_enable(drive, 1);
+#endif
 
         /*
          * FIXME, invalidate queue
@@ -559,7 +550,9 @@
          * set nIEN, tag start operation will enable again when
          * it is safe
          */
- drive_ctl_nien(drive, 1);
+#ifdef IDE_TCQ_NIEN
+ ata_irq_enable(drive, 0);
+#endif
 
         OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
 
@@ -569,7 +562,9 @@
                 return ide_stopped;
         }
 
- drive_ctl_nien(drive, 0);
+#ifdef IDE_TCQ_NIEN
+ ata_irq_enable(drive, 1);
+#endif
 
         if (stat & ERR_STAT) {
                 ide_dump_status(drive, rq, "tcq_start", stat);
diff -urN linux-2.5.19/drivers/ide/trm290.c linux/drivers/ide/trm290.c
--- linux-2.5.19/drivers/ide/trm290.c 2002-05-29 20:42:48.000000000 +0200
+++ linux/drivers/ide/trm290.c 2002-06-01 17:18:46.000000000 +0200
@@ -222,7 +222,7 @@
         if (drive->type != ATA_DISK)
                 return 0;
 
- ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
+ ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
         OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 
         return 0;
diff -urN linux-2.5.19/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.5.19/drivers/scsi/ide-scsi.c 2002-06-01 18:53:06.000000000 +0200
+++ linux/drivers/scsi/ide-scsi.c 2002-06-01 19:03:48.000000000 +0200
@@ -411,8 +411,7 @@
         }
 
         ata_select(drive, 10);
- if (IDE_CONTROL_REG)
- OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
+ ata_irq_enable(drive, 1);
         OUT_BYTE (dma_ok,IDE_FEATURE_REG);
         OUT_BYTE (bcount >> 8,IDE_BCOUNTH_REG);
         OUT_BYTE (bcount & 0xff,IDE_BCOUNTL_REG);
diff -urN linux-2.5.19/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.19/include/linux/ide.h 2002-06-01 18:53:06.000000000 +0200
+++ linux/include/linux/ide.h 2002-06-01 19:36:29.000000000 +0200
@@ -38,11 +38,6 @@
 # define SUPPORT_SLOW_DATA_PORTS 1 /* 0 to reduce kernel size */
 #endif
 
-/* Right now this is only needed by a promise controlled.
- */
-#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */
-# define OK_TO_RESET_CONTROLLER 0 /* 0 for use with AH2372A/B interface */
-#endif
 #ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */
 # define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
 #endif
@@ -73,21 +68,22 @@
  */
 
 enum {
- IDE_DATA_OFFSET = 0,
- IDE_ERROR_OFFSET = 1,
- IDE_NSECTOR_OFFSET = 2,
- IDE_SECTOR_OFFSET = 3,
- IDE_LCYL_OFFSET = 4,
- IDE_HCYL_OFFSET = 5,
- IDE_SELECT_OFFSET = 6,
- IDE_STATUS_OFFSET = 7,
- IDE_CONTROL_OFFSET = 8,
- IDE_IRQ_OFFSET = 9,
- IDE_NR_PORTS = 10
+ IDE_DATA_OFFSET = 0,
+ IDE_ERROR_OFFSET = 1,
+ IDE_FEATURE_OFFSET = 1,
+ IDE_NSECTOR_OFFSET = 2,
+ IDE_SECTOR_OFFSET = 3,
+ IDE_LCYL_OFFSET = 4,
+ IDE_HCYL_OFFSET = 5,
+ IDE_SELECT_OFFSET = 6,
+ IDE_STATUS_OFFSET = 7,
+ IDE_COMMAND_OFFSET = 7,
+ IDE_CONTROL_OFFSET = 8,
+ IDE_ALTSTATUS_OFFSET = 8,
+ IDE_IRQ_OFFSET = 9,
+ IDE_NR_PORTS = 10
 };
 
-#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET
-#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET
 
 #define IDE_DATA_REG (drive->channel->io_ports[IDE_DATA_OFFSET])
 #define IDE_ERROR_REG (drive->channel->io_ports[IDE_ERROR_OFFSET])
@@ -96,20 +92,16 @@
 #define IDE_LCYL_REG (drive->channel->io_ports[IDE_LCYL_OFFSET])
 #define IDE_HCYL_REG (drive->channel->io_ports[IDE_HCYL_OFFSET])
 #define IDE_SELECT_REG (drive->channel->io_ports[IDE_SELECT_OFFSET])
-#define IDE_STATUS_REG (drive->channel->io_ports[IDE_STATUS_OFFSET])
-#define IDE_CONTROL_REG (drive->channel->io_ports[IDE_CONTROL_OFFSET])
+#define IDE_COMMAND_REG (drive->channel->io_ports[IDE_STATUS_OFFSET])
 #define IDE_IRQ_REG (drive->channel->io_ports[IDE_IRQ_OFFSET])
 
 #define IDE_FEATURE_REG IDE_ERROR_REG
-#define IDE_COMMAND_REG IDE_STATUS_REG
-#define IDE_ALTSTATUS_REG IDE_CONTROL_REG
 #define IDE_IREASON_REG IDE_NSECTOR_REG
 #define IDE_BCOUNTL_REG IDE_LCYL_REG
 #define IDE_BCOUNTH_REG IDE_HCYL_REG
 
 #define GET_ERR() IN_BYTE(IDE_ERROR_REG)
-#define GET_STAT() IN_BYTE(IDE_STATUS_REG)
-#define GET_ALTSTAT() IN_BYTE(IDE_CONTROL_REG)
+#define GET_ALTSTAT() IN_BYTE(drive->channel->io_ports[IDE_CONTROL_OFFSET])
 #define GET_FEAT() IN_BYTE(IDE_NSECTOR_REG)
 
 #define BAD_R_STAT (BUSY_STAT | ERR_STAT)
@@ -346,8 +338,6 @@
         byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */
 
         select_t select; /* basic drive/head select reg value */
-
- u8 ctl; /* "normal" value for IDE_CONTROL_REG */
         u8 status; /* last retrived status value for device */
 
         byte ready_stat; /* min status value for drive ready */
@@ -653,25 +643,10 @@
  */
 extern u8 ide_dump_status(struct ata_device *, struct request *rq, const char *, u8);
 
-extern ide_startstop_t ide_error(struct ata_device *, struct request *rq,
- const char *, byte);
+extern ide_startstop_t ata_error(struct ata_device *, struct request *rq, const char *);
 
-/*
- * ide_fixstring() cleans up and (optionally) byte-swaps a text string,
- * removing leading/trailing blanks and compressing internal blanks.
- * It is primarily used to tidy up the model name/number fields as
- * returned by the WIN_[P]IDENTIFY commands.
- */
-void ide_fixstring(byte *s, const int bytecount, const int byteswap);
+extern void ide_fixstring(char *s, const int bytecount, const int byteswap);
 
-/*
- * This routine busy-waits for the drive status to be not "busy".
- * It then checks the status for all of the "good" bits and none
- * of the "bad" bits, and if all is okay it returns 0. All other
- * cases return 1 after doing "*startstop = ide_error()", and the
- * caller should return the updated value of "startstop" in this case.
- * "startstop" is unchanged when the function returns 0;
- */
 extern int ide_wait_stat(ide_startstop_t *,
                 struct ata_device *, struct request *rq,
                 byte, byte, unsigned long);
@@ -896,5 +871,7 @@
 extern void ata_select(struct ata_device *, unsigned long);
 extern void ata_mask(struct ata_device *);
 extern int ata_status(struct ata_device *, u8, u8);
+extern int ata_irq_enable(struct ata_device *, int);
+extern void ata_reset(struct ata_channel *);
 
 #endif

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Jun 07 2002 - 22:00:12 EST