]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-io.c
hysdn: No longer broken on SMP.
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-io.c
index 715379605a7bb55f887eb887832c4765eccab485..696525342e9a56977c1d2ac88d72497be5a7e866 100644 (file)
@@ -218,7 +218,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
                 * we could be smarter and check for current xfer_speed
                 * in struct drive etc...
                 */
-               if (drive->hwif->dma_host_set == NULL)
+               if (drive->hwif->dma_ops == NULL)
                        break;
                /*
                 * TODO: respect ->using_dma setting
@@ -295,48 +295,6 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
        spin_unlock_irqrestore(&ide_lock, flags);
 }
 
-void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       struct ide_taskfile *tf = &task->tf;
-
-       if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-               u16 data = hwif->INW(IDE_DATA_REG);
-
-               tf->data = data & 0xff;
-               tf->hob_data = (data >> 8) & 0xff;
-       }
-
-       /* be sure we're looking at the low order bits */
-       hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
-
-       if (task->tf_flags & IDE_TFLAG_IN_NSECT)
-               tf->nsect  = hwif->INB(IDE_NSECTOR_REG);
-       if (task->tf_flags & IDE_TFLAG_IN_LBAL)
-               tf->lbal   = hwif->INB(IDE_SECTOR_REG);
-       if (task->tf_flags & IDE_TFLAG_IN_LBAM)
-               tf->lbam   = hwif->INB(IDE_LCYL_REG);
-       if (task->tf_flags & IDE_TFLAG_IN_LBAH)
-               tf->lbah   = hwif->INB(IDE_HCYL_REG);
-       if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
-               tf->device = hwif->INB(IDE_SELECT_REG);
-
-       if (task->tf_flags & IDE_TFLAG_LBA48) {
-               hwif->OUTB(drive->ctl | 0x80, IDE_CONTROL_REG);
-
-               if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-                       tf->hob_feature = hwif->INB(IDE_FEATURE_REG);
-               if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-                       tf->hob_nsect   = hwif->INB(IDE_NSECTOR_REG);
-               if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-                       tf->hob_lbal    = hwif->INB(IDE_SECTOR_REG);
-               if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-                       tf->hob_lbam    = hwif->INB(IDE_LCYL_REG);
-               if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-                       tf->hob_lbah    = hwif->INB(IDE_HCYL_REG);
-       }
-}
-
 /**
  *     ide_end_drive_cmd       -       end an explicit drive command
  *     @drive: command 
@@ -372,7 +330,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
                        tf->error = err;
                        tf->status = stat;
 
-                       ide_tf_read(drive, task);
+                       drive->hwif->tf_read(drive, task);
 
                        if (task->tf_flags & IDE_TFLAG_DYN)
                                kfree(task);
@@ -421,7 +379,7 @@ static void try_to_flush_leftover_data (ide_drive_t *drive)
                u32 wcount = (i > 16) ? 16 : i;
 
                i -= wcount;
-               HWIF(drive)->ata_input_data(drive, buffer, wcount);
+               drive->hwif->input_data(drive, NULL, buffer, wcount * 4);
        }
 }
 
@@ -448,7 +406,8 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
                if (err == ABRT_ERR) {
                        if (drive->select.b.lba &&
                            /* some newer drives don't support WIN_SPECIFY */
-                           hwif->INB(IDE_COMMAND_REG) == WIN_SPECIFY)
+                           hwif->INB(hwif->io_ports.command_addr) ==
+                               WIN_SPECIFY)
                                return ide_stopped;
                } else if ((err & BAD_CRC) == BAD_CRC) {
                        /* UDMA crc error, just retry the operation */
@@ -500,7 +459,8 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
 
        if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
                /* force an abort */
-               hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
+               hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE,
+                              hwif->io_ports.command_addr);
 
        if (rq->errors >= ERROR_MAX) {
                ide_kill_rq(drive, rq);
@@ -713,15 +673,12 @@ static ide_startstop_t do_special (ide_drive_t *drive)
 #endif
        if (s->b.set_tune) {
                ide_hwif_t *hwif = drive->hwif;
+               const struct ide_port_ops *port_ops = hwif->port_ops;
                u8 req_pio = drive->tune_req;
 
                s->b.set_tune = 0;
 
                if (set_pio_mode_abuse(drive->hwif, req_pio)) {
-
-                       if (hwif->set_pio_mode == NULL)
-                               return ide_stopped;
-
                        /*
                         * take ide_lock for drive->[no_]unmask/[no_]io_32bit
                         */
@@ -729,10 +686,10 @@ static ide_startstop_t do_special (ide_drive_t *drive)
                                unsigned long flags;
 
                                spin_lock_irqsave(&ide_lock, flags);
-                               hwif->set_pio_mode(drive, req_pio);
+                               port_ops->set_pio_mode(drive, req_pio);
                                spin_unlock_irqrestore(&ide_lock, flags);
                        } else
-                               hwif->set_pio_mode(drive, req_pio);
+                               port_ops->set_pio_mode(drive, req_pio);
                } else {
                        int keep_dma = drive->using_dma;
 
@@ -1233,12 +1190,12 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
 
        if (error < 0) {
                printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
-               (void)HWIF(drive)->ide_dma_end(drive);
+               (void)hwif->dma_ops->dma_end(drive);
                ret = ide_error(drive, "dma timeout error",
                                ide_read_status(drive));
        } else {
                printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
-               hwif->dma_timeout(drive);
+               hwif->dma_ops->dma_timeout(drive);
        }
 
        /*
@@ -1350,7 +1307,7 @@ void ide_timer_expiry (unsigned long data)
                                startstop = handler(drive);
                        } else if (drive_is_ready(drive)) {
                                if (drive->waiting_for_dma)
-                                       hwgroup->hwif->dma_lost_irq(drive);
+                                       hwif->dma_ops->dma_lost_irq(drive);
                                (void)ide_ack_intr(hwif);
                                printk(KERN_WARNING "%s: lost interrupt\n", drive->name);
                                startstop = handler(drive);
@@ -1416,7 +1373,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
         */
        do {
                if (hwif->irq == irq) {
-                       stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+                       stat = hwif->INB(hwif->io_ports.status_addr);
                        if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
                                /* Try to not flood the console with msgs */
                                static unsigned long last_msgtime, count;
@@ -1506,7 +1463,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
                         * Whack the status register, just in case
                         * we have a leftover pending IRQ.
                         */
-                       (void) hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+                       (void) hwif->INB(hwif->io_ports.status_addr);
 #endif /* CONFIG_BLK_DEV_IDEPCI */
                }
                spin_unlock_irqrestore(&ide_lock, flags);
@@ -1593,8 +1550,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
 
 void ide_init_drive_cmd (struct request *rq)
 {
-       memset(rq, 0, sizeof(*rq));
-       rq->ref_count = 1;
+       blk_rq_init(NULL, rq);
 }
 
 EXPORT_SYMBOL(ide_init_drive_cmd);
@@ -1680,7 +1636,23 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
        task.tf.lbam    = bcount & 0xff;
        task.tf.lbah    = (bcount >> 8) & 0xff;
 
-       ide_tf_load(drive, &task);
+       ide_tf_dump(drive->name, &task.tf);
+       drive->hwif->tf_load(drive, &task);
 }
 
 EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);
+
+void ide_pad_transfer(ide_drive_t *drive, int write, int len)
+{
+       ide_hwif_t *hwif = drive->hwif;
+       u8 buf[4] = { 0 };
+
+       while (len > 0) {
+               if (write)
+                       hwif->output_data(drive, NULL, buf, min(4, len));
+               else
+                       hwif->input_data(drive, NULL, buf, min(4, len));
+               len -= 4;
+       }
+}
+EXPORT_SYMBOL_GPL(ide_pad_transfer);