02_ide_use_load_taskfile_in_do_rw_disk.patch

        Reimplements __ide_do_rw_disk() using ide_load_taskfile().
        While at it, clean up the function a little bit.

Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>

 ide-disk.c |  163 ++++++++++++++++++++++++-------------------------------------
 1 files changed, 65 insertions(+), 98 deletions(-)

Index: linux-taskfile-ng/drivers/ide/ide-disk.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-disk.c       2005-03-05 
10:46:58.305078940 +0900
+++ linux-taskfile-ng/drivers/ide/ide-disk.c    2005-03-05 10:46:58.762007508 
+0900
@@ -158,114 +158,80 @@ static int lba_capacity_is_ok (struct hd
  */
 ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, 
sector_t block)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
-       unsigned int dma        = drive->using_dma;
-       u8 lba48                = (drive->addressing == 1) ? 1 : 0;
-       task_ioreg_t command    = WIN_NOP;
-       ata_nsector_t           nsectors;
-
-       nsectors.all            = (u16) rq->nr_sectors;
-
-       if (hwif->no_lba48_dma && lba48 && dma) {
-               if (block + rq->nr_sectors > 1ULL << 28)
-                       dma = 0;
-       }
-
-       if (!dma) {
-               ide_init_sg_cmd(drive, rq);
-               ide_map_sg(drive, rq);
-       }
+       ide_hwif_t *hwif = drive->hwif;
+       int lba48 = (drive->addressing == 1) ? 1 : 0;
+       ide_task_t task;
+       struct ata_taskfile *tf = &task.tf;
+       u8 command;
 
+       /* ALL Command Block Executions SHALL clear nIEN. */
        if (IDE_CONTROL_REG)
                hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
-
        /* FIXME: SELECT_MASK(drive, 0) ? */
 
-       if (drive->select.b.lba) {
-               if (drive->addressing == 1) {
-                       task_ioreg_t tasklets[10];
-
-                       pr_debug("%s: LBA=0x%012llx\n", drive->name, block);
+       memset(&task, 0, sizeof(task));
 
-                       tasklets[0] = 0;
-                       tasklets[1] = 0;
-                       tasklets[2] = nsectors.b.low;
-                       tasklets[3] = nsectors.b.high;
-                       tasklets[4] = (task_ioreg_t) block;
-                       tasklets[5] = (task_ioreg_t) (block>>8);
-                       tasklets[6] = (task_ioreg_t) (block>>16);
-                       tasklets[7] = (task_ioreg_t) (block>>24);
-                       if (sizeof(block) == 4) {
-                               tasklets[8] = (task_ioreg_t) 0;
-                               tasklets[9] = (task_ioreg_t) 0;
-                       } else {
-                               tasklets[8] = (task_ioreg_t)((u64)block >> 32);
-                               tasklets[9] = (task_ioreg_t)((u64)block >> 40);
-                       }
-#ifdef DEBUG
-                       printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n",
-                               drive->name, tasklets[3], tasklets[2],
-                               tasklets[9], tasklets[8], tasklets[7],
-                               tasklets[6], tasklets[5], tasklets[4]);
-#endif
-                       hwif->OUTB(tasklets[1], IDE_FEATURE_REG);
-                       hwif->OUTB(tasklets[3], IDE_NSECTOR_REG);
-                       hwif->OUTB(tasklets[7], IDE_SECTOR_REG);
-                       hwif->OUTB(tasklets[8], IDE_LCYL_REG);
-                       hwif->OUTB(tasklets[9], IDE_HCYL_REG);
-
-                       hwif->OUTB(tasklets[0], IDE_FEATURE_REG);
-                       hwif->OUTB(tasklets[2], IDE_NSECTOR_REG);
-                       hwif->OUTB(tasklets[4], IDE_SECTOR_REG);
-                       hwif->OUTB(tasklets[5], IDE_LCYL_REG);
-                       hwif->OUTB(tasklets[6], IDE_HCYL_REG);
-                       hwif->OUTB(0x00|drive->select.all,IDE_SELECT_REG);
-               } else {
-                       hwif->OUTB(0x00, IDE_FEATURE_REG);
-                       hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
-                       hwif->OUTB(block, IDE_SECTOR_REG);
-                       hwif->OUTB(block>>=8, IDE_LCYL_REG);
-                       hwif->OUTB(block>>=8, IDE_HCYL_REG);
-                       
hwif->OUTB(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG);
-               }
+       if (drive->select.b.lba) {
+               /* LBA28/LBA48 */
+               tf->flags       |= ATA_TFLAG_OUT_ADDR | ATA_TFLAG_OUT_DEVICE;
+               tf->nsect       = rq->nr_sectors;
+               tf->lbal        = block;
+               tf->lbam        = block >> 8;
+               tf->lbah        = block >> 16;
+
+               if (lba48) {
+                       tf->flags       |= ATA_TFLAG_OUT_LBA48;
+                       tf->hob_nsect   = rq->nr_sectors >> 8;
+                       tf->hob_lbal    = block >> 24;
+                       tf->hob_lbam    = block >> 32;
+                       tf->hob_lbah    = block >> 40;
+               } else
+                       tf->device      = (block >> 24) & 0xf;
        } else {
-               unsigned int sect,head,cyl,track;
-               track = (int)block / drive->sect;
-               sect  = (int)block % drive->sect + 1;
-               hwif->OUTB(sect, IDE_SECTOR_REG);
-               head  = track % drive->head;
-               cyl   = track / drive->head;
-
-               pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect);
-
-               hwif->OUTB(0x00, IDE_FEATURE_REG);
-               hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
-               hwif->OUTB(cyl, IDE_LCYL_REG);
-               hwif->OUTB(cyl>>8, IDE_HCYL_REG);
-               hwif->OUTB(head|drive->select.all,IDE_SELECT_REG);
-       }
-
-       if (dma) {
-               if (!hwif->dma_setup(drive)) {
-                       if (rq_data_dir(rq)) {
-                               command = lba48 ? WIN_WRITEDMA_EXT : 
WIN_WRITEDMA;
-                               if (drive->vdma)
-                                       command = lba48 ? WIN_WRITE_EXT: 
WIN_WRITE;
-                       } else {
-                               command = lba48 ? WIN_READDMA_EXT : WIN_READDMA;
-                               if (drive->vdma)
-                                       command = lba48 ? WIN_READ_EXT: 
WIN_READ;
-                       }
-                       hwif->dma_exec_cmd(drive, command);
-                       hwif->dma_start(drive);
-                       return ide_started;
+               /* CHS */
+               int track       = (int)block / drive->sect;
+               int cyl         = track / drive->head;
+               int head        = track % drive->head;
+               int sect        = (int)block % drive->sect + 1;
+
+               tf->flags       |= ATA_TFLAG_OUT_ADDR | ATA_TFLAG_OUT_DEVICE;
+               tf->nsect       = rq->nr_sectors;
+               tf->lbal        = sect;
+               tf->lbam        = cyl;
+               tf->lbah        = cyl >> 8;
+               tf->device      = head;
+       }
+
+       tf->device |= drive->select.all;
+
+       ide_load_taskfile(drive, &task);
+
+       if (drive->using_dma &&
+           !(hwif->no_lba48_dma && block + rq->nr_sectors > 1ULL << 28)) {
+               /* DMA */
+               if (hwif->dma_setup(drive))
+                       goto fallback_to_pio;
+               if (rq_data_dir(rq) == READ) {
+                       command = lba48 ? WIN_READDMA_EXT : WIN_READDMA;
+                       if (drive->vdma)
+                               command = lba48 ? WIN_READ_EXT : WIN_READ;
+               } else {
+                       command = lba48 ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
+                       if (drive->vdma)
+                               command = lba48 ? WIN_WRITE_EXT : WIN_WRITE;
                }
-               /* fallback to PIO */
-               ide_init_sg_cmd(drive, rq);
+               hwif->dma_exec_cmd(drive, command);
+               hwif->dma_start(drive);
+               return ide_started;
        }
 
-       if (rq_data_dir(rq) == READ) {
+       /* PIO */
+       ide_map_sg(drive, rq);
+       /* dma_setup() has already done ide_map_sg(). */
+ fallback_to_pio:
+       ide_init_sg_cmd(drive, rq);
 
+       if (rq_data_dir(rq) == READ) {
                if (drive->mult_count) {
                        hwif->data_phase = TASKFILE_MULTI_IN;
                        command = lba48 ? WIN_MULTREAD_EXT : WIN_MULTREAD;
@@ -274,7 +240,8 @@ ide_startstop_t __ide_do_rw_disk (ide_dr
                        command = lba48 ? WIN_READ_EXT : WIN_READ;
                }
 
-               ide_execute_command(drive, command, &task_in_intr, WAIT_CMD, 
NULL);
+               ide_execute_command(drive, command, &task_in_intr,
+                                   WAIT_CMD, NULL);
                return ide_started;
        } else {
                if (drive->mult_count) {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to