]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-io.c
ide: IDE_HFLAG_BOOTABLE -> IDE_HFLAG_NON_BOOTABLE
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-io.c
index ce8ab1085936cabeed5ea5237376cfe25a5f016c..31e5afadb7e9d9762eadda85721ddbf45e740a51 100644 (file)
@@ -58,15 +58,19 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
                             int uptodate, unsigned int nr_bytes, int dequeue)
 {
        int ret = 1;
+       int error = 0;
+
+       if (uptodate <= 0)
+               error = uptodate ? uptodate : -EIO;
 
        /*
         * if failfast is set on a request, override number of sectors and
         * complete the whole request right now
         */
-       if (blk_noretry_request(rq) && end_io_error(uptodate))
+       if (blk_noretry_request(rq) && error)
                nr_bytes = rq->hard_nr_sectors << 9;
 
-       if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors)
+       if (!blk_fs_request(rq) && error && !rq->errors)
                rq->errors = -EIO;
 
        /*
@@ -78,14 +82,9 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
                ide_dma_on(drive);
        }
 
-       if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
-               add_disk_randomness(rq->rq_disk);
-               if (dequeue) {
-                       if (!list_empty(&rq->queuelist))
-                               blkdev_dequeue_request(rq);
+       if (!__blk_end_request(rq, error, nr_bytes)) {
+               if (dequeue)
                        HWGROUP(drive)->rq = NULL;
-               }
-               end_that_request_last(rq, uptodate);
                ret = 0;
        }
 
@@ -290,9 +289,9 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
                drive->blocked = 0;
                blk_start_queue(drive->queue);
        }
-       blkdev_dequeue_request(rq);
        HWGROUP(drive)->rq = NULL;
-       end_that_request_last(rq, 1);
+       if (__blk_end_request(rq, 0, 0))
+               BUG();
        spin_unlock_irqrestore(&ide_lock, flags);
 }
 
@@ -302,39 +301,45 @@ void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
        struct ide_taskfile *tf = &task->tf;
 
        if (task->tf_flags & IDE_TFLAG_IN_DATA) {
-               u16 data = hwif->INW(IDE_DATA_REG);
+               u16 data = hwif->INW(hwif->io_ports[IDE_DATA_OFFSET]);
 
                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);
+       hwif->OUTB(drive->ctl & ~0x80, hwif->io_ports[IDE_CONTROL_OFFSET]);
 
        if (task->tf_flags & IDE_TFLAG_IN_NSECT)
-               tf->nsect  = hwif->INB(IDE_NSECTOR_REG);
+               tf->nsect  = hwif->INB(hwif->io_ports[IDE_NSECTOR_OFFSET]);
        if (task->tf_flags & IDE_TFLAG_IN_LBAL)
-               tf->lbal   = hwif->INB(IDE_SECTOR_REG);
+               tf->lbal   = hwif->INB(hwif->io_ports[IDE_SECTOR_OFFSET]);
        if (task->tf_flags & IDE_TFLAG_IN_LBAM)
-               tf->lbam   = hwif->INB(IDE_LCYL_REG);
+               tf->lbam   = hwif->INB(hwif->io_ports[IDE_LCYL_OFFSET]);
        if (task->tf_flags & IDE_TFLAG_IN_LBAH)
-               tf->lbah   = hwif->INB(IDE_HCYL_REG);
+               tf->lbah   = hwif->INB(hwif->io_ports[IDE_HCYL_OFFSET]);
        if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
-               tf->device = hwif->INB(IDE_SELECT_REG);
+               tf->device = hwif->INB(hwif->io_ports[IDE_SELECT_OFFSET]);
 
        if (task->tf_flags & IDE_TFLAG_LBA48) {
-               hwif->OUTB(drive->ctl | 0x80, IDE_CONTROL_REG);
+               hwif->OUTB(drive->ctl | 0x80,
+                          hwif->io_ports[IDE_CONTROL_OFFSET]);
 
                if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
-                       tf->hob_feature = hwif->INB(IDE_FEATURE_REG);
+                       tf->hob_feature =
+                               hwif->INB(hwif->io_ports[IDE_FEATURE_OFFSET]);
                if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
-                       tf->hob_nsect   = hwif->INB(IDE_NSECTOR_REG);
+                       tf->hob_nsect   =
+                               hwif->INB(hwif->io_ports[IDE_NSECTOR_OFFSET]);
                if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
-                       tf->hob_lbal    = hwif->INB(IDE_SECTOR_REG);
+                       tf->hob_lbal    =
+                               hwif->INB(hwif->io_ports[IDE_SECTOR_OFFSET]);
                if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
-                       tf->hob_lbam    = hwif->INB(IDE_LCYL_REG);
+                       tf->hob_lbam    =
+                               hwif->INB(hwif->io_ports[IDE_LCYL_OFFSET]);
                if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
-                       tf->hob_lbah    = hwif->INB(IDE_HCYL_REG);
+                       tf->hob_lbah    =
+                               hwif->INB(hwif->io_ports[IDE_HCYL_OFFSET]);
        }
 }
 
@@ -354,7 +359,6 @@ void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
  
 void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
 {
-       ide_hwif_t *hwif = HWIF(drive);
        unsigned long flags;
        struct request *rq;
 
@@ -362,30 +366,22 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
        rq = HWGROUP(drive)->rq;
        spin_unlock_irqrestore(&ide_lock, flags);
 
-       if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
-               u8 *args = (u8 *) rq->buffer;
-               if (rq->errors == 0)
-                       rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-
-               if (args) {
-                       args[0] = stat;
-                       args[1] = err;
-                       /* be sure we're looking at the low order bits */
-                       hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
-                       args[2] = hwif->INB(IDE_NSECTOR_REG);
-               }
-       } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
-               ide_task_t *args = (ide_task_t *) rq->special;
+       if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+               ide_task_t *task = (ide_task_t *)rq->special;
+
                if (rq->errors == 0)
-                       rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-                       
-               if (args) {
-                       struct ide_taskfile *tf = &args->tf;
+                       rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT);
+
+               if (task) {
+                       struct ide_taskfile *tf = &task->tf;
 
                        tf->error = err;
                        tf->status = stat;
 
-                       ide_tf_read(drive, args);
+                       ide_tf_read(drive, task);
+
+                       if (task->tf_flags & IDE_TFLAG_DYN)
+                               kfree(task);
                }
        } else if (blk_pm_request(rq)) {
                struct request_pm_state *pm = rq->data;
@@ -400,10 +396,11 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
        }
 
        spin_lock_irqsave(&ide_lock, flags);
-       blkdev_dequeue_request(rq);
        HWGROUP(drive)->rq = NULL;
        rq->errors = err;
-       end_that_request_last(rq, !rq->errors);
+       if (unlikely(__blk_end_request(rq, (rq->errors ? -EIO : 0),
+                                      blk_rq_bytes(rq))))
+               BUG();
        spin_unlock_irqrestore(&ide_lock, flags);
 }
 
@@ -457,7 +454,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[IDE_COMMAND_OFFSET]) ==
+                               WIN_SPECIFY)
                                return ide_stopped;
                } else if ((err & BAD_CRC) == BAD_CRC) {
                        /* UDMA crc error, just retry the operation */
@@ -480,7 +478,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
                return ide_stopped;
        }
 
-       if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
+       if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
                rq->errors |= ERROR_RESET;
 
        if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
@@ -507,9 +505,10 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
                /* add decoding error stuff */
        }
 
-       if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
+       if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
                /* force an abort */
-               hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
+               hwif->OUTB(WIN_IDLEIMMEDIATE,
+                          hwif->io_ports[IDE_COMMAND_OFFSET]);
 
        if (rq->errors >= ERROR_MAX) {
                ide_kill_rq(drive, rq);
@@ -624,48 +623,6 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
                return __ide_abort(drive, rq);
 }
 
-/**
- *     drive_cmd_intr          -       drive command completion interrupt
- *     @drive: drive the completion interrupt occurred on
- *
- *     drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
- *     We do any necessary data reading and then wait for the drive to
- *     go non busy. At that point we may read the error data and complete
- *     the request
- */
-static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
-{
-       struct request *rq = HWGROUP(drive)->rq;
-       ide_hwif_t *hwif = HWIF(drive);
-       u8 *args = (u8 *)rq->buffer, pio_in = (args && args[3]) ? 1 : 0, stat;
-
-       if (pio_in) {
-               u8 io_32bit = drive->io_32bit;
-               stat = hwif->INB(IDE_STATUS_REG);
-               if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
-                       if (stat & (ERR_STAT | DRQ_STAT))
-                               return ide_error(drive, __FUNCTION__, stat);
-                       ide_set_handler(drive, &drive_cmd_intr, WAIT_WORSTCASE,
-                                       NULL);
-                       return ide_started;
-               }
-               drive->io_32bit = 0;
-               hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
-               drive->io_32bit = io_32bit;
-               stat = wait_drive_not_busy(drive);
-       } else {
-               local_irq_enable_in_hardirq();
-               stat = hwif->INB(IDE_STATUS_REG);
-       }
-
-       if (!OK_STAT(stat, READY_STAT, BAD_STAT))
-               return ide_error(drive, "drive_cmd", stat);
-               /* calls ide_end_drive_cmd */
-       ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
-       return ide_stopped;
-}
-
 static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
 {
        tf->nsect   = drive->sect;
@@ -851,16 +808,9 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
                struct request *rq)
 {
        ide_hwif_t *hwif = HWIF(drive);
-       u8 *args = rq->buffer;
-       ide_task_t ltask;
-       struct ide_taskfile *tf = &ltask.tf;
-
-       if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
-               ide_task_t *task = rq->special;
-               if (task == NULL)
-                       goto done;
+       ide_task_t *task = rq->special;
 
+       if (task) {
                hwif->data_phase = task->data_phase;
 
                switch (hwif->data_phase) {
@@ -877,33 +827,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
                return do_rw_taskfile(drive, task);
        }
 
-       if (args == NULL)
-               goto done;
-
-       memset(&ltask, 0, sizeof(ltask));
-       if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
-#ifdef DEBUG
-               printk("%s: DRIVE_CMD\n", drive->name);
-#endif
-               tf->feature = args[2];
-               if (args[0] == WIN_SMART) {
-                       tf->nsect = args[3];
-                       tf->lbal  = args[1];
-                       tf->lbam  = 0x4f;
-                       tf->lbah  = 0xc2;
-                       ltask.tf_flags = IDE_TFLAG_OUT_TF;
-               } else {
-                       tf->nsect = args[1];
-                       ltask.tf_flags = IDE_TFLAG_OUT_FEATURE |
-                                        IDE_TFLAG_OUT_NSECT;
-               }
-       }
-       tf->command = args[0];
-       ide_tf_load(drive, &ltask);
-       ide_execute_command(drive, args[0], &drive_cmd_intr, WAIT_WORSTCASE, NULL);
-       return ide_started;
-
-done:
        /*
         * NULL is actually a valid way of waiting for
         * all current requests to be flushed from the queue.
@@ -911,9 +834,8 @@ done:
 #ifdef DEBUG
        printk("%s: DRIVE_CMD (null)\n", drive->name);
 #endif
-       ide_end_drive_cmd(drive,
-                       hwif->INB(IDE_STATUS_REG),
-                       hwif->INB(IDE_ERROR_REG));
+       ide_end_drive_cmd(drive, ide_read_status(drive), ide_read_error(drive));
+
        return ide_stopped;
 }
 
@@ -1007,8 +929,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
                if (drive->current_speed == 0xff)
                        ide_config_drive_speed(drive, drive->desired_speed);
 
-               if (rq->cmd_type == REQ_TYPE_ATA_CMD ||
-                   rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
+               if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
                        return execute_drive_cmd(drive, rq);
                else if (blk_pm_request(rq)) {
                        struct request_pm_state *pm = rq->data;
@@ -1322,7 +1243,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
                printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
                (void)HWIF(drive)->ide_dma_end(drive);
                ret = ide_error(drive, "dma timeout error",
-                                               hwif->INB(IDE_STATUS_REG));
+                               ide_read_status(drive));
        } else {
                printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
                hwif->dma_timeout(drive);
@@ -1446,7 +1367,8 @@ void ide_timer_expiry (unsigned long data)
                                        startstop = ide_dma_timeout_retry(drive, wait);
                                } else
                                        startstop =
-                                       ide_error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
+                                       ide_error(drive, "irq timeout",
+                                                 ide_read_status(drive));
                        }
                        drive->service_time = jiffies - drive->service_start;
                        spin_lock_irq(&ide_lock);
@@ -1578,7 +1500,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
                 * remove all the ifdef PCI crap
                 */
 #ifdef CONFIG_BLK_DEV_IDEPCI
-               if (hwif->pci_dev && !hwif->pci_dev->vendor)
+               if (hwif->chipset != ide_pci)
 #endif /* CONFIG_BLK_DEV_IDEPCI */
                {
                        /*