]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] 2.5.7 IDE 23
authorMartin Dalecki <dalecki@evision-ventures.com>
Tue, 2 Apr 2002 03:37:22 +0000 (19:37 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 2 Apr 2002 03:37:22 +0000 (19:37 -0800)
- Support for additional Promise controller id's (PDC20276).

- Remove code duplication between do_rw_taskfile and do_taskfile.
   This will evolve into a more reasonable ata_command() function
   finally. The ata_taskfile function has far too many arguments, but
   I favour this over having two different code paths for getting
   actual data to the drive.

drivers/ide/ide-disk.c
drivers/ide/ide-pci.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/pdc202xx.c
drivers/pci/pci.ids
include/linux/ide.h
include/linux/pci_ids.h

index 5f598354bd6a2f00cf396bc238e4aef5f52e5595..96ac410883d59018636ce938e36f1991567d92ac 100644 (file)
@@ -106,50 +106,6 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
        return 0;       /* lba_capacity value may be bad */
 }
 
-static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
-static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
-static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block);
-
-/*
- * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
- * otherwise, to address sectors.  It also takes care of issuing special
- * DRIVE_CMDs.
- */
-static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
-{
-       /*
-        * Wait until all request have bin finished.
-        */
-
-       while (drive->blocked) {
-               yield();
-               // panic("ide: Request while drive blocked?");
-       }
-
-       if (!(rq->flags & REQ_CMD)) {
-               blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
-               ide_end_request(drive, 0);
-               return ide_stopped;
-       }
-
-       if (IS_PDC4030_DRIVE) {
-               extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
-
-               return promise_rw_disk(drive, rq, block);
-       }
-
-       /* 48-bit LBA */
-       if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
-               return lba48_do_request(drive, rq, block);
-
-       /* 28-bit LBA */
-       if (drive->select.b.lba)
-               return lba28_do_request(drive, rq, block);
-
-       /* 28-bit CHS */
-       return chs_do_request(drive, rq, block);
-}
-
 static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
 {
        int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
@@ -158,20 +114,38 @@ static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
        lba48bit = drive->addressing;
 #endif
 
-       if (cmd == READ) {
-               if (drive->using_dma)
-                       return (lba48bit) ? WIN_READDMA_EXT : WIN_READDMA;
-               else if (drive->mult_count)
-                       return (lba48bit) ? WIN_MULTREAD_EXT : WIN_MULTREAD;
-               else
-                       return (lba48bit) ? WIN_READ_EXT : WIN_READ;
-       } else if (cmd == WRITE) {
-               if (drive->using_dma)
-                       return (lba48bit) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
-               else if (drive->mult_count)
-                       return (lba48bit) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
-               else
-                       return (lba48bit) ? WIN_WRITE_EXT : WIN_WRITE;
+       if (lba48bit) {
+               if (cmd == READ) {
+                       if (drive->using_dma)
+                               return WIN_READDMA_EXT;
+                       else if (drive->mult_count)
+                               return WIN_MULTREAD_EXT;
+                       else
+                               return WIN_READ_EXT;
+               } else if (cmd == WRITE) {
+                       if (drive->using_dma)
+                               return WIN_WRITEDMA_EXT;
+                       else if (drive->mult_count)
+                               return WIN_MULTWRITE_EXT;
+                       else
+                               return WIN_WRITE_EXT;
+               }
+       } else {
+               if (cmd == READ) {
+                       if (drive->using_dma)
+                               return WIN_READDMA;
+                       else if (drive->mult_count)
+                               return WIN_MULTREAD;
+                       else
+                               return WIN_READ;
+               } else if (cmd == WRITE) {
+                       if (drive->using_dma)
+                               return WIN_WRITEDMA;
+                       else if (drive->mult_count)
+                               return WIN_MULTWRITE;
+                       else
+                               return WIN_WRITE;
+               }
        }
        return WIN_NOP;
 }
@@ -183,8 +157,6 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
        ide_task_t                      args;
        int                             sectors;
 
-       task_ioreg_t command    = get_command(drive, rq_data_dir(rq));
-
        unsigned int track      = (block / drive->sect);
        unsigned int sect       = (block % drive->sect) + 1;
        unsigned int head       = (track % drive->head);
@@ -203,7 +175,7 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
        taskfile.high_cylinder  = (cyl>>8);
        taskfile.device_head    = head;
        taskfile.device_head    |= drive->select.all;
-       taskfile.command        = command;
+       taskfile.command        =  get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
        printk("%s: %sing: ", drive->name,
@@ -221,7 +193,12 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
        args.block = block;
        rq->special = &args;
 
-       return do_rw_taskfile(drive, &args);
+       return ata_taskfile(drive,
+                       (struct hd_drive_task_hdr *) &args.tfRegister,
+                       (struct hd_drive_hob_hdr *) &args.hobRegister,
+                       args.handler,
+                       args.prehandler,
+                       args.rq);
 }
 
 static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
@@ -231,8 +208,6 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
        ide_task_t                      args;
        int                             sectors;
 
-       task_ioreg_t command    = get_command(drive, rq_data_dir(rq));
-
        sectors = rq->nr_sectors;
        if (sectors == 256)
                sectors = 0;
@@ -246,7 +221,7 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
        taskfile.high_cylinder  = (block>>=8);
        taskfile.device_head    = ((block>>8)&0x0f);
        taskfile.device_head    |= drive->select.all;
-       taskfile.command        = command;
+       taskfile.command        = get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
        printk("%s: %sing: ", drive->name,
@@ -264,7 +239,12 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
        args.block = block;
        rq->special = &args;
 
-       return do_rw_taskfile(drive, &args);
+       return ata_taskfile(drive,
+                       (struct hd_drive_task_hdr *) &args.tfRegister,
+                       (struct hd_drive_hob_hdr *) &args.hobRegister,
+                       args.handler,
+                       args.prehandler,
+                       args.rq);
 }
 
 /*
@@ -280,8 +260,6 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
        ide_task_t                      args;
        int                             sectors;
 
-       task_ioreg_t command    = get_command(drive, rq_data_dir(rq));
-
        memset(&taskfile, 0, sizeof(task_struct_t));
        memset(&hobfile, 0, sizeof(hob_struct_t));
 
@@ -306,7 +284,7 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
        taskfile.device_head    = drive->select.all;
        hobfile.device_head     = taskfile.device_head;
        hobfile.control         = (drive->ctl|0x80);
-       taskfile.command        = command;
+       taskfile.command        = get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
        printk("%s: %sing: ", drive->name,
@@ -324,7 +302,52 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
        args.block = block;
        rq->special = &args;
 
-       return do_rw_taskfile(drive, &args);
+       return ata_taskfile(drive,
+                       (struct hd_drive_task_hdr *) &args.tfRegister,
+                       (struct hd_drive_hob_hdr *) &args.hobRegister,
+                       args.handler,
+                       args.prehandler,
+                       args.rq);
+}
+
+/*
+ * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
+ * otherwise, to address sectors.  It also takes care of issuing special
+ * DRIVE_CMDs.
+ */
+static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
+{
+       /*
+        * Wait until all request have bin finished.
+        */
+
+       while (drive->blocked) {
+               yield();
+               // panic("ide: Request while drive blocked?");
+       }
+
+       if (!(rq->flags & REQ_CMD)) {
+               blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
+               ide_end_request(drive, 0);
+               return ide_stopped;
+       }
+
+       if (IS_PDC4030_DRIVE) {
+               extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
+
+               return promise_rw_disk(drive, rq, block);
+       }
+
+       /* 48-bit LBA */
+       if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
+               return lba48_do_request(drive, rq, block);
+
+       /* 28-bit LBA */
+       if (drive->select.b.lba)
+               return lba28_do_request(drive, rq, block);
+
+       /* 28-bit CHS */
+       return chs_do_request(drive, rq, block);
 }
 
 static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
@@ -333,10 +356,13 @@ static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *dr
        if (drive->removable && drive->usage == 1) {
                struct hd_drive_task_hdr taskfile;
                struct hd_drive_hob_hdr hobfile;
+
                memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
                memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+
                check_disk_change(inode->i_rdev);
                taskfile.command = WIN_DOORLOCK;
+
                /*
                 * Ignore the return code from door_lock,
                 * since the open() has already succeeded,
@@ -355,11 +381,10 @@ static int idedisk_flushcache(ide_drive_t *drive)
        struct hd_drive_hob_hdr hobfile;
        memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
        memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
-       if (drive->id->cfs_enable_2 & 0x2400) {
+       if (drive->id->cfs_enable_2 & 0x2400)
                taskfile.command        = WIN_FLUSH_CACHE_EXT;
-       } else {
+       else
                taskfile.command        = WIN_FLUSH_CACHE;
-       }
        return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
 }
 
@@ -643,7 +668,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
                        taskfile.command = WIN_SPECIFY;
                        handler = set_geometry_intr;;
                }
-               do_taskfile(drive, &taskfile, &hobfile, handler);
+               ata_taskfile(drive, &taskfile, &hobfile, handler, NULL, NULL);
        } else if (s->b.recalibrate) {
                s->b.recalibrate = 0;
                if (!IS_PDC4030_DRIVE) {
@@ -653,7 +678,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
                        memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
                        taskfile.sector_count   = drive->sect;
                        taskfile.command        = WIN_RESTORE;
-                       do_taskfile(drive, &taskfile, &hobfile, recal_intr);
+                       ata_taskfile(drive, &taskfile, &hobfile, recal_intr, NULL, NULL);
                }
        } else if (s->b.set_multmode) {
                s->b.set_multmode = 0;
@@ -666,7 +691,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
                        memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
                        taskfile.sector_count   = drive->mult_req;
                        taskfile.command        = WIN_SETMULT;
-                       do_taskfile(drive, &taskfile, &hobfile, &set_multmode_intr);
+                       ata_taskfile(drive, &taskfile, &hobfile, set_multmode_intr, NULL, NULL);
                }
        } else if (s->all) {
                int special = s->all;
index d8c32aca8a7b085eb927cc00d4a7eaa46e483d2b..8d06a46305447e05158f0f107cd2464a37793a4a 100644 (file)
@@ -229,6 +229,7 @@ static ide_pci_device_t pci_chipsets[] __initdata = {
        {PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ  | ATA_F_DMA },
        {PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
        {PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
+       {PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
 #endif
 #ifdef CONFIG_BLK_DEV_RZ1000
        {PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, NULL, NULL, ide_init_rz1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
index 29ccab91a89725e411ab60f5e9ecf79408805642..1fe9aa1a4a6712d70628f06e8db66a894659a0f0 100644 (file)
@@ -48,7 +48,7 @@ static inline char *ide_map_rq(struct request *rq, unsigned long *flags)
        if (rq->bio)
                return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
        else
-               return rq->buffer + task_rq_offset(rq);
+               return rq->buffer + ((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE;
 }
 
 static inline void ide_unmap_rq(struct request *rq, char *to,
@@ -341,27 +341,37 @@ static ide_startstop_t task_mulout_intr(ide_drive_t *drive)
        pBuf = ide_map_rq(rq, &flags);
        DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
                pBuf, nsect, rq->current_nr_sectors);
+
        drive->io_32bit = 0;
        taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
+
        ide_unmap_rq(rq, pBuf, &flags);
+
        drive->io_32bit = io_32bit;
+
        rq->errors = 0;
        /* Are we sure that this as all been already transfered? */
        rq->current_nr_sectors -= nsect;
+
        if (hwgroup->handler == NULL)
                ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
+
        return ide_started;
 }
 
-ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
+ide_startstop_t ata_taskfile(ide_drive_t *drive,
+               struct hd_drive_task_hdr *taskfile,
+               struct hd_drive_hob_hdr *hobfile,
+               ide_handler_t *handler,
+               ide_pre_handler_t *prehandler,
+               struct request *rq
+               )
 {
-       task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
-       hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
        struct hd_driveid *id = drive->id;
-       byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
+       u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
 
        /* (ks/hs): Moved to start, do not use for multiple out commands */
-       if (task->handler != task_mulout_intr && task->handler != bio_mulout_intr) {
+       if (handler != task_mulout_intr && handler != bio_mulout_intr) {
                if (IDE_CONTROL_REG)
                        OUT_BYTE(drive->ctl, IDE_CONTROL_REG);  /* clear nIEN */
                SELECT_MASK(HWIF(drive), drive, 0);
@@ -386,17 +396,16 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
        OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
 
        OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
-       if (task->handler != NULL) {
-               ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
+       if (handler != NULL) {
+               ide_set_handler(drive, handler, WAIT_CMD, NULL);
                OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
                /*
                 * Warning check for race between handler and prehandler for
                 * writing first block of data.  however since we are well
                 * inside the boundaries of the seek, we should be okay.
                 */
-               if (task->prehandler != NULL) {
-                       return task->prehandler(drive, task->rq);
-               }
+               if (prehandler != NULL)
+                       return prehandler(drive, rq);
        } else {
                /* for dma commands we down set the handler */
                if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
@@ -405,48 +414,6 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
        return ide_started;
 }
 
-void do_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile,
-               struct hd_drive_hob_hdr *hobfile,
-               ide_handler_t *handler)
-{
-       struct hd_driveid *id = drive->id;
-       byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
-
-       /* (ks/hs): Moved to start, do not use for multiple out commands */
-       if (*handler != task_mulout_intr && handler != bio_mulout_intr) {
-               if (IDE_CONTROL_REG)
-                       OUT_BYTE(drive->ctl, IDE_CONTROL_REG);  /* clear nIEN */
-               SELECT_MASK(HWIF(drive), drive, 0);
-       }
-
-       if ((id->command_set_2 & 0x0400) &&
-           (id->cfs_enable_2 & 0x0400) &&
-           (drive->addressing == 1)) {
-               OUT_BYTE(hobfile->feature, IDE_FEATURE_REG);
-               OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG);
-               OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG);
-               OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG);
-               OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG);
-       }
-
-       OUT_BYTE(taskfile->feature, IDE_FEATURE_REG);
-       OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG);
-       /* refers to number of sectors to transfer */
-       OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG);
-       /* refers to sector offset or start sector */
-       OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG);
-       OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
-
-       OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
-       if (handler != NULL) {
-               ide_set_handler (drive, handler, WAIT_CMD, NULL);
-               OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
-       } else {
-               /* for dma commands we down set the handler */
-               if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
-       }
-}
-
 /*
  * This is invoked on completion of a WIN_SETMULT cmd.
  */
@@ -1162,8 +1129,7 @@ EXPORT_SYMBOL(atapi_input_bytes);
 EXPORT_SYMBOL(atapi_output_bytes);
 EXPORT_SYMBOL(taskfile_input_data);
 EXPORT_SYMBOL(taskfile_output_data);
-EXPORT_SYMBOL(do_rw_taskfile);
-EXPORT_SYMBOL(do_taskfile);
+EXPORT_SYMBOL(ata_taskfile);
 
 EXPORT_SYMBOL(recal_intr);
 EXPORT_SYMBOL(set_geometry_intr);
index 6cf6d4e8b9d0e4b16d879d7e42f6c9484978cffb..2b4c54c79217105a50f1dbf9894d60ae1be800b2 100644 (file)
@@ -978,7 +978,7 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
  * setting a timer to wake up at half second intervals thereafter,
  * until timeout is achieved, before timing out.
  */
-int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
+int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
        byte stat;
        int i;
        unsigned long flags;
@@ -1019,90 +1019,6 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, by
        return 1;
 }
 
-/*
- * execute_drive_cmd() issues a special drive command,
- * usually initiated by ioctl() from the external hdparm program.
- */
-static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
-{
-       if (rq->flags & REQ_DRIVE_TASKFILE) {
-               ide_task_t *args = rq->special;
-
-               if (!(args))
-                       goto args_error;
-
-               do_taskfile(drive,
-                               (struct hd_drive_task_hdr *)&args->tfRegister,
-                               (struct hd_drive_hob_hdr *)&args->hobRegister,
-                               args->handler);
-
-               if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
-                    (args->command_type == IDE_DRIVE_TASK_OUT)) &&
-                     args->prehandler && args->handler)
-                       return args->prehandler(drive, rq);
-               return ide_started;
-
-       } else if (rq->flags & REQ_DRIVE_TASK) {
-               byte *args = rq->buffer;
-               byte sel;
-
-               if (!(args)) goto args_error;
-#ifdef DEBUG
-                       printk("%s: DRIVE_TASK_CMD ", drive->name);
-                       printk("cmd=0x%02x ", args[0]);
-                       printk("fr=0x%02x ", args[1]);
-                       printk("ns=0x%02x ", args[2]);
-                       printk("sc=0x%02x ", args[3]);
-                       printk("lcyl=0x%02x ", args[4]);
-                       printk("hcyl=0x%02x ", args[5]);
-                       printk("sel=0x%02x\n", args[6]);
-#endif
-               OUT_BYTE(args[1], IDE_FEATURE_REG);
-               OUT_BYTE(args[3], IDE_SECTOR_REG);
-               OUT_BYTE(args[4], IDE_LCYL_REG);
-               OUT_BYTE(args[5], IDE_HCYL_REG);
-               sel = (args[6] & ~0x10);
-               if (drive->select.b.unit)
-                       sel |= 0x10;
-               OUT_BYTE(sel, IDE_SELECT_REG);
-               ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
-               return ide_started;
-       } else if (rq->flags & REQ_DRIVE_CMD) {
-
-               byte *args = rq->buffer;
-               if (!(args)) goto args_error;
-#ifdef DEBUG
-               printk("%s: DRIVE_CMD ", drive->name);
-               printk("cmd=0x%02x ", args[0]);
-               printk("sc=0x%02x ", args[1]);
-               printk("fr=0x%02x ", args[2]);
-               printk("xx=0x%02x\n", args[3]);
-#endif
-               if (args[0] == WIN_SMART) {
-                       OUT_BYTE(0x4f, IDE_LCYL_REG);
-                       OUT_BYTE(0xc2, IDE_HCYL_REG);
-                       OUT_BYTE(args[2],IDE_FEATURE_REG);
-                       OUT_BYTE(args[1],IDE_SECTOR_REG);
-                       ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
-                       return ide_started;
-               }
-               OUT_BYTE(args[2],IDE_FEATURE_REG);
-               ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
-               return ide_started;
-       }
-
-args_error:
-       /*
-        * NULL is actually a valid way of waiting for
-        * all current requests to be flushed from the queue.
-        */
-#ifdef DEBUG
-       printk("%s: DRIVE_CMD (null)\n", drive->name);
-#endif
-       ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
-       return ide_stopped;
-}
-
 /*
  * start_request() initiates handling of a new I/O request
  */
@@ -1150,9 +1066,100 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
                printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
                return startstop;
        }
+
+       /* FIXME: We can see nicely here that all commands should be submitted
+        * through the request queue and that the special field in drive should
+        * go as soon as possible!
+        */
+
        if (!drive->special.all) {
-               if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE))
-                       return execute_drive_cmd(drive, rq);
+               if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+                       /* This issues a special drive command, usually
+                        * initiated by ioctl() from the external hdparm
+                        * program.
+                        */
+
+                       if (rq->flags & REQ_DRIVE_TASKFILE) {
+                               ide_task_t *args = rq->special;
+
+                               if (!(args))
+                                       goto args_error;
+
+                               ata_taskfile(drive,
+                                               (struct hd_drive_task_hdr *)&args->tfRegister,
+                                               (struct hd_drive_hob_hdr *)&args->hobRegister,
+                                               args->handler, NULL, NULL);
+
+                               if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
+                                                       (args->command_type == IDE_DRIVE_TASK_OUT)) &&
+                                               args->prehandler && args->handler)
+                                       return args->prehandler(drive, rq);
+                               return ide_started;
+
+                       } else if (rq->flags & REQ_DRIVE_TASK) {
+                               byte *args = rq->buffer;
+                               byte sel;
+
+                               if (!(args)) goto args_error;
+#ifdef DEBUG
+                               printk("%s: DRIVE_TASK_CMD ", drive->name);
+                               printk("cmd=0x%02x ", args[0]);
+                               printk("fr=0x%02x ", args[1]);
+                               printk("ns=0x%02x ", args[2]);
+                               printk("sc=0x%02x ", args[3]);
+                               printk("lcyl=0x%02x ", args[4]);
+                               printk("hcyl=0x%02x ", args[5]);
+                               printk("sel=0x%02x\n", args[6]);
+#endif
+                               OUT_BYTE(args[1], IDE_FEATURE_REG);
+                               OUT_BYTE(args[3], IDE_SECTOR_REG);
+                               OUT_BYTE(args[4], IDE_LCYL_REG);
+                               OUT_BYTE(args[5], IDE_HCYL_REG);
+                               sel = (args[6] & ~0x10);
+                               if (drive->select.b.unit)
+                                       sel |= 0x10;
+                               OUT_BYTE(sel, IDE_SELECT_REG);
+                               ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
+                               return ide_started;
+                       } else if (rq->flags & REQ_DRIVE_CMD) {
+                               byte *args = rq->buffer;
+                               if (!(args)) goto args_error;
+#ifdef DEBUG
+                               printk("%s: DRIVE_CMD ", drive->name);
+                               printk("cmd=0x%02x ", args[0]);
+                               printk("sc=0x%02x ", args[1]);
+                               printk("fr=0x%02x ", args[2]);
+                               printk("xx=0x%02x\n", args[3]);
+#endif
+                               if (args[0] == WIN_SMART) {
+                                       OUT_BYTE(0x4f, IDE_LCYL_REG);
+                                       OUT_BYTE(0xc2, IDE_HCYL_REG);
+                                       OUT_BYTE(args[2],IDE_FEATURE_REG);
+                                       OUT_BYTE(args[1],IDE_SECTOR_REG);
+                                       ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
+
+                                       return ide_started;
+                               }
+                               OUT_BYTE(args[2],IDE_FEATURE_REG);
+                               ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
+                               return ide_started;
+                       }
+
+args_error:
+                       /*
+                        * NULL is actually a valid way of waiting for all
+                        * current requests to be flushed from the queue.
+                        */
+#ifdef DEBUG
+                       printk("%s: DRIVE_CMD (null)\n", drive->name);
+#endif
+                       ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
+                       return ide_stopped;
+               }
+
+               /* The normal way of execution is to pass execute the request
+                * handler.
+                */
 
                if (ata_ops(drive)) {
                        if (ata_ops(drive)->do_request)
@@ -1699,31 +1706,29 @@ void ide_init_drive_cmd (struct request *rq)
 }
 
 /*
- * This function issues a special IDE device request
- * onto the request queue.
+ * This function issues a special IDE device request onto the request queue.
  *
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
+ * If action is ide_wait, then the rq is queued at the end of the request
+ * queue, and the function sleeps until it has been processed.  This is for use
+ * when invoked from an ioctl handler.
  *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed.  This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
+ * If action is ide_preempt, then the rq is queued at the head of the request
+ * queue, displacing the currently-being-processed request and this function
+ * returns immediately without waiting for the new rq to be completed.  This is
+ * VERY DANGEROUS, and is intended for careful use by the ATAPI tape/cdrom
+ * driver code.
  *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed.  As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
+ * If action is ide_next, then the rq is queued immediately after the
+ * currently-being-processed-request (if any), and the function returns without
+ * waiting for the new rq to be completed.  As above, This is VERY DANGEROUS,
+ * and is intended for careful use by the ATAPI tape/cdrom driver code.
  *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
+ * If action is ide_end, then the rq is queued at the end of the request queue,
+ * and the function returns immediately without waiting for the new rq to be
+ * completed. This is again intended for careful use by the ATAPI tape/cdrom
+ * driver code.
  */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action)
+int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action)
 {
        unsigned long flags;
        ide_hwgroup_t *hwgroup = HWGROUP(drive);
@@ -2403,7 +2408,7 @@ static int set_pio_mode (ide_drive_t *drive, int arg)
        ide_init_drive_cmd(&rq);
        drive->tune_req = (byte) arg;
        drive->special.b.set_tune = 1;
-       (void) ide_do_drive_cmd (drive, &rq, ide_wait);
+       ide_do_drive_cmd(drive, &rq, ide_wait);
        return 0;
 }
 
index 9d072763b8fa4250bcddf383895df61211d3378d..13af48cf1c8baf998035cef14a71d4decb51110e 100644 (file)
@@ -217,6 +217,9 @@ static char * pdc202xx_info_new (char *buf, struct pci_dev *dev)
                case PCI_DEVICE_ID_PROMISE_20275:
                        p += sprintf(p, "\n                                PDC20275 Chipset.\n");
                        break;
+               case PCI_DEVICE_ID_PROMISE_20276:
+                       p += sprintf(p, "\n                                PDC20276 Chipset.\n");
+                       break;
                case PCI_DEVICE_ID_PROMISE_20269:
                        p += sprintf(p, "\n                                PDC20269 TX2 Chipset.\n");
                        break;
@@ -236,6 +239,7 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
        char *p = buffer;
        switch(bmide_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_20268:
                case PCI_DEVICE_ID_PROMISE_20268R:
@@ -732,6 +736,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
 
        switch(dev->device) {
                case PCI_DEVICE_ID_PROMISE_20275:
+               case PCI_DEVICE_ID_PROMISE_20276:
                case PCI_DEVICE_ID_PROMISE_20269:
                        udma_133 = (udma_66) ? 1 : 0;
                        udma_100 = (udma_66) ? 1 : 0;
@@ -989,6 +994,7 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 
        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:
@@ -1121,6 +1127,7 @@ unsigned int __init pci_init_pdc202xx(struct pci_dev *dev)
 
        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:
@@ -1215,6 +1222,7 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif)
 
         switch(hwif->pci_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_20268:
                case PCI_DEVICE_ID_PROMISE_20268R:
@@ -1233,6 +1241,7 @@ void __init ide_init_pdc202xx (ide_hwif_t *hwif)
 
         switch(hwif->pci_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_20268:
                case PCI_DEVICE_ID_PROMISE_20268R:
index 29a97f2b8138cac6a7c5d3b6bde75774e3945d11..461f946346303b8c14ed8aad5cc60c7c2fbacd8c 100644 (file)
 1059  Teknor Industrial Computers Inc
 105a  Promise Technology, Inc.
        0d30  20265
+       1275  20275
        4d30  20267
        4d33  20246
        4d38  20262
        4d68  20268
        6268  20268R
        4d69  20269
+       5275  20276
        5300  DC5300
 105b  Foxconn International, Inc.
 105c  Wipro Infotech Limited
index 6dafc47697ffeebef465f66461c0c0e151cf0533..2dee58229b9b385d68d825543dbfd0c45f52c08a 100644 (file)
@@ -771,35 +771,7 @@ typedef enum {
  */
 #define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
 
-#define task_rq_offset(rq) \
-       (((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE)
-
-/*
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
- *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed.  This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
- *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed.  As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
- */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action);
+extern int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action);
 
 /*
  * Clean up after success/failure of an explicit drive cmd.
@@ -827,15 +799,12 @@ void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecoun
 void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
 void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
 
-/*
- * taskfile io for disks for now...
- */
-ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task);
-
-/*
- * Builds request from ide_ioctl
- */
-void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, ide_handler_t *handler);
+extern ide_startstop_t ata_taskfile(ide_drive_t *drive,
+               struct hd_drive_task_hdr *taskfile,
+               struct hd_drive_hob_hdr *hobfile,
+               ide_handler_t *handler,
+               ide_pre_handler_t *prehandler,
+               struct request *rq);
 
 /*
  * Special Flagged Register Validation Caller
@@ -871,7 +840,7 @@ extern int system_bus_speed;
  * idedisk_input_data() is a wrapper around ide_input_data() which copes
  * with byte-swapping the input data if required.
  */
-inline void idedisk_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
+extern void idedisk_input_data(ide_drive_t *drive, void *buffer, unsigned int wcount);
 
 /*
  * ide_stall_queue() can be used by a drive to give excess bandwidth back
index 41eed9cd438e582bcbd0a8c8bfca73201fa4af06..2dc6c0319705baf44db90b966ea0d134510c8d91 100644 (file)
 #define PCI_DEVICE_ID_PROMISE_20268R   0x6268
 #define PCI_DEVICE_ID_PROMISE_20269    0x4d69
 #define PCI_DEVICE_ID_PROMISE_20275    0x1275
+#define PCI_DEVICE_ID_PROMISE_20276    0x5275
 #define PCI_DEVICE_ID_PROMISE_5300     0x5300
 
 #define PCI_VENDOR_ID_N9               0x105d