Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / ide / ide-taskfile.c
index d04f62a..9233b81 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
+#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/major.h>
 #include <linux/errno.h>
@@ -51,8 +52,6 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-#define DEBUG_TASKFILE 0       /* unset when fixed */
-
 static void ata_bswap_data (void *buffer, int wcount)
 {
        u16 *p = buffer;
@@ -161,8 +160,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
        return ide_stopped;
 }
 
-EXPORT_SYMBOL(do_rw_taskfile);
-
 /*
  * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
  */
@@ -312,12 +309,14 @@ static void ide_pio_multi(ide_drive_t *drive, unsigned int write)
                ide_pio_sector(drive, write);
 }
 
-static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
+static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
                                     unsigned int write)
 {
        if (rq->bio)    /* fs request */
                rq->errors = 0;
 
+       touch_softlockup_watchdog();
+
        switch (drive->hwif->data_phase) {
        case TASKFILE_MULTI_IN:
        case TASKFILE_MULTI_OUT:
@@ -376,7 +375,13 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
                }
        }
 
-       ide_end_request(drive, 1, rq->hard_nr_sectors);
+       if (rq->rq_disk) {
+               ide_driver_t *drv;
+
+               drv = *(ide_driver_t **)rq->rq_disk->private_data;;
+               drv->end_request(drive, 1, rq->hard_nr_sectors);
+       } else
+               ide_end_request(drive, 1, rq->hard_nr_sectors);
 }
 
 /*
@@ -500,6 +505,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long
        }
 
        rq.special = args;
+       args->rq = &rq;
        return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
@@ -527,9 +533,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
 //     printk("IDE Taskfile ...\n");
 
-       req_task = kmalloc(tasksize, GFP_KERNEL);
+       req_task = kzalloc(tasksize, GFP_KERNEL);
        if (req_task == NULL) return -ENOMEM;
-       memset(req_task, 0, tasksize);
        if (copy_from_user(req_task, buf, tasksize)) {
                kfree(req_task);
                return -EFAULT;
@@ -540,12 +545,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
        if (taskout) {
                int outtotal = tasksize;
-               outbuf = kmalloc(taskout, GFP_KERNEL);
+               outbuf = kzalloc(taskout, GFP_KERNEL);
                if (outbuf == NULL) {
                        err = -ENOMEM;
                        goto abort;
                }
-               memset(outbuf, 0, taskout);
                if (copy_from_user(outbuf, buf + outtotal, taskout)) {
                        err = -EFAULT;
                        goto abort;
@@ -554,12 +558,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
        if (taskin) {
                int intotal = tasksize + taskout;
-               inbuf = kmalloc(taskin, GFP_KERNEL);
+               inbuf = kzalloc(taskin, GFP_KERNEL);
                if (inbuf == NULL) {
                        err = -ENOMEM;
                        goto abort;
                }
-               memset(inbuf, 0, taskin);
                if (copy_from_user(inbuf, buf + intotal, taskin)) {
                        err = -EFAULT;
                        goto abort;
@@ -648,10 +651,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
        }
 abort:
        kfree(req_task);
-       if (outbuf != NULL)
-               kfree(outbuf);
-       if (inbuf != NULL)
-               kfree(inbuf);
+       kfree(outbuf);
+       kfree(inbuf);
 
 //     printk("IDE Taskfile ioctl ended. rc = %i\n", err);
 
@@ -708,10 +709,9 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
        if (args[3]) {
                argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
-               argbuf = kmalloc(argsize, GFP_KERNEL);
+               argbuf = kzalloc(argsize, GFP_KERNEL);
                if (argbuf == NULL)
                        return -ENOMEM;
-               memcpy(argbuf, args, 4);
        }
        if (set_transfer(drive, &tfargs)) {
                xfer_rate = args[1];
@@ -772,9 +772,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
        ide_hwif_t *hwif        = HWIF(drive);
        task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
        hob_struct_t *hobfile   = (hob_struct_t *) task->hobRegister;
-#if DEBUG_TASKFILE
-       u8 status;
-#endif
 
        if (task->data_phase == TASKFILE_MULTI_IN ||
            task->data_phase == TASKFILE_MULTI_OUT) {
@@ -785,19 +782,13 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
        }
 
        /*
-        * (ks) Check taskfile in/out flags.
+        * (ks) Check taskfile in flags.
         * If set, then execute as it is defined.
         * If not set, then define default settings.
         * The default values are:
-        *      write and read all taskfile registers (except data) 
-        *      write and read the hob registers (sector,nsector,lcyl,hcyl)
+        *      read all taskfile registers (except data)
+        *      read the hob registers (sector, nsector, lcyl, hcyl)
         */
-       if (task->tf_out_flags.all == 0) {
-               task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
-               if (drive->addressing == 1)
-                       task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
-        }
-
        if (task->tf_in_flags.all == 0) {
                task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
                if (drive->addressing == 1)
@@ -810,16 +801,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
                hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
        SELECT_MASK(drive, 0);
 
-#if DEBUG_TASKFILE
-       status = hwif->INB(IDE_STATUS_REG);
-       if (status & 0x80) {
-               printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status);
-               udelay(100);
-               status = hwif->INB(IDE_STATUS_REG);
-               printk("flagged_taskfile -> Status = %02x\n", status);
-       }
-#endif
-
        if (task->tf_out_flags.b.data) {
                u16 data =  taskfile->data + (hobfile->data << 8);
                hwif->OUTW(data, IDE_DATA_REG);