ide: remove unnecessary writes to HOB taskfile registers
[safe/jmp/linux-2.6] / drivers / ide / ide-taskfile.c
1 /*
2  * linux/drivers/ide/ide-taskfile.c     Version 0.38    March 05, 2003
3  *
4  *  Copyright (C) 2000-2002     Michael Cornwell <cornwell@acm.org>
5  *  Copyright (C) 2000-2002     Andre Hedrick <andre@linux-ide.org>
6  *  Copyright (C) 2001-2002     Klaus Smolin
7  *                                      IBM Storage Technology Division
8  *  Copyright (C) 2003-2004     Bartlomiej Zolnierkiewicz
9  *
10  *  The big the bad and the ugly.
11  */
12
13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/string.h>
16 #include <linux/kernel.h>
17 #include <linux/timer.h>
18 #include <linux/mm.h>
19 #include <linux/sched.h>
20 #include <linux/interrupt.h>
21 #include <linux/major.h>
22 #include <linux/errno.h>
23 #include <linux/genhd.h>
24 #include <linux/blkpg.h>
25 #include <linux/slab.h>
26 #include <linux/pci.h>
27 #include <linux/delay.h>
28 #include <linux/hdreg.h>
29 #include <linux/ide.h>
30 #include <linux/bitops.h>
31 #include <linux/scatterlist.h>
32
33 #include <asm/byteorder.h>
34 #include <asm/irq.h>
35 #include <asm/uaccess.h>
36 #include <asm/io.h>
37
38 static void ata_bswap_data (void *buffer, int wcount)
39 {
40         u16 *p = buffer;
41
42         while (wcount--) {
43                 *p = *p << 8 | *p >> 8; p++;
44                 *p = *p << 8 | *p >> 8; p++;
45         }
46 }
47
48 static void taskfile_input_data(ide_drive_t *drive, void *buffer, u32 wcount)
49 {
50         HWIF(drive)->ata_input_data(drive, buffer, wcount);
51         if (drive->bswap)
52                 ata_bswap_data(buffer, wcount);
53 }
54
55 static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount)
56 {
57         if (drive->bswap) {
58                 ata_bswap_data(buffer, wcount);
59                 HWIF(drive)->ata_output_data(drive, buffer, wcount);
60                 ata_bswap_data(buffer, wcount);
61         } else {
62                 HWIF(drive)->ata_output_data(drive, buffer, wcount);
63         }
64 }
65
66 void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
67 {
68         ide_hwif_t *hwif = drive->hwif;
69         struct ide_taskfile *tf = &task->tf;
70         u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
71
72         if (task->tf_flags & IDE_TFLAG_FLAGGED)
73                 HIHI = 0xFF;
74
75 #ifdef DEBUG
76         printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x "
77                 "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
78                 drive->name, tf->feature, tf->nsect, tf->lbal,
79                 tf->lbam, tf->lbah, tf->device, tf->command);
80 #endif
81
82         if (IDE_CONTROL_REG)
83                 hwif->OUTB(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
84
85         if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0)
86                 SELECT_MASK(drive, 0);
87
88         if (task->tf_flags & IDE_TFLAG_OUT_DATA)
89                 hwif->OUTW((tf->hob_data << 8) | tf->data, IDE_DATA_REG);
90
91         if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
92                 hwif->OUTB(tf->hob_feature, IDE_FEATURE_REG);
93         if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
94                 hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG);
95         if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
96                 hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG);
97         if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
98                 hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG);
99         if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
100                 hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG);
101
102         if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
103                 hwif->OUTB(tf->feature, IDE_FEATURE_REG);
104         if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
105                 hwif->OUTB(tf->nsect, IDE_NSECTOR_REG);
106         if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
107                 hwif->OUTB(tf->lbal, IDE_SECTOR_REG);
108         if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
109                 hwif->OUTB(tf->lbam, IDE_LCYL_REG);
110         if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
111                 hwif->OUTB(tf->lbah, IDE_HCYL_REG);
112
113         if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
114                 hwif->OUTB((tf->device & HIHI) | drive->select.all, IDE_SELECT_REG);
115 }
116
117 EXPORT_SYMBOL_GPL(ide_tf_load);
118
119 int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
120 {
121         ide_task_t args;
122
123         memset(&args, 0, sizeof(ide_task_t));
124         args.tf.nsect = 0x01;
125         if (drive->media == ide_disk)
126                 args.tf.command = WIN_IDENTIFY;
127         else
128                 args.tf.command = WIN_PIDENTIFY;
129         args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
130         args.command_type = IDE_DRIVE_TASK_IN;
131         args.data_phase   = TASKFILE_IN;
132         args.handler      = &task_in_intr;
133         return ide_raw_taskfile(drive, &args, buf);
134 }
135
136 static int inline task_dma_ok(ide_task_t *task)
137 {
138         if (task->tf_flags & IDE_TFLAG_FLAGGED)
139                 return 1;
140
141         switch (task->tf.command) {
142                 case WIN_WRITEDMA_ONCE:
143                 case WIN_WRITEDMA:
144                 case WIN_WRITEDMA_EXT:
145                 case WIN_READDMA_ONCE:
146                 case WIN_READDMA:
147                 case WIN_READDMA_EXT:
148                 case WIN_IDENTIFY_DMA:
149                         return 1;
150         }
151
152         return 0;
153 }
154
155 ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
156 {
157         ide_hwif_t *hwif        = HWIF(drive);
158         struct ide_taskfile *tf = &task->tf;
159
160         ide_tf_load(drive, task);
161
162         if (task->handler != NULL) {
163                 if (task->prehandler != NULL) {
164                         hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG);
165                         ndelay(400);    /* FIXME */
166                         return task->prehandler(drive, task->rq);
167                 }
168                 ide_execute_command(drive, tf->command, task->handler, WAIT_WORSTCASE, NULL);
169                 return ide_started;
170         }
171
172         if (task_dma_ok(task) && drive->using_dma && !hwif->dma_setup(drive)) {
173                 hwif->dma_exec_cmd(drive, tf->command);
174                 hwif->dma_start(drive);
175                 return ide_started;
176         }
177
178         return ide_stopped;
179 }
180
181 /*
182  * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
183  */
184 ide_startstop_t set_multmode_intr (ide_drive_t *drive)
185 {
186         ide_hwif_t *hwif = HWIF(drive);
187         u8 stat;
188
189         if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
190                 drive->mult_count = drive->mult_req;
191         } else {
192                 drive->mult_req = drive->mult_count = 0;
193                 drive->special.b.recalibrate = 1;
194                 (void) ide_dump_status(drive, "set_multmode", stat);
195         }
196         return ide_stopped;
197 }
198
199 /*
200  * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd.
201  */
202 ide_startstop_t set_geometry_intr (ide_drive_t *drive)
203 {
204         ide_hwif_t *hwif = HWIF(drive);
205         int retries = 5;
206         u8 stat;
207
208         while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
209                 udelay(10);
210
211         if (OK_STAT(stat, READY_STAT, BAD_STAT))
212                 return ide_stopped;
213
214         if (stat & (ERR_STAT|DRQ_STAT))
215                 return ide_error(drive, "set_geometry_intr", stat);
216
217         BUG_ON(HWGROUP(drive)->handler != NULL);
218         ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL);
219         return ide_started;
220 }
221
222 /*
223  * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
224  */
225 ide_startstop_t recal_intr (ide_drive_t *drive)
226 {
227         ide_hwif_t *hwif = HWIF(drive);
228         u8 stat;
229
230         if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), READY_STAT, BAD_STAT))
231                 return ide_error(drive, "recal_intr", stat);
232         return ide_stopped;
233 }
234
235 /*
236  * Handler for commands without a data phase
237  */
238 ide_startstop_t task_no_data_intr (ide_drive_t *drive)
239 {
240         ide_task_t *args        = HWGROUP(drive)->rq->special;
241         ide_hwif_t *hwif        = HWIF(drive);
242         u8 stat;
243
244         local_irq_enable_in_hardirq();
245         if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
246                 return ide_error(drive, "task_no_data_intr", stat);
247                 /* calls ide_end_drive_cmd */
248         }
249         if (args)
250                 ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
251
252         return ide_stopped;
253 }
254
255 static u8 wait_drive_not_busy(ide_drive_t *drive)
256 {
257         ide_hwif_t *hwif = HWIF(drive);
258         int retries;
259         u8 stat;
260
261         /*
262          * Last sector was transfered, wait until drive is ready.
263          * This can take up to 10 usec, but we will wait max 1 ms
264          * (drive_cmd_intr() waits that long).
265          */
266         for (retries = 0; retries < 100; retries++) {
267                 if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT)
268                         udelay(10);
269                 else
270                         break;
271         }
272
273         if (stat & BUSY_STAT)
274                 printk(KERN_ERR "%s: drive still BUSY!\n", drive->name);
275
276         return stat;
277 }
278
279 static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
280 {
281         ide_hwif_t *hwif = drive->hwif;
282         struct scatterlist *sg = hwif->sg_table;
283         struct scatterlist *cursg = hwif->cursg;
284         struct page *page;
285 #ifdef CONFIG_HIGHMEM
286         unsigned long flags;
287 #endif
288         unsigned int offset;
289         u8 *buf;
290
291         cursg = hwif->cursg;
292         if (!cursg) {
293                 cursg = sg;
294                 hwif->cursg = sg;
295         }
296
297         page = sg_page(cursg);
298         offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
299
300         /* get the current page and offset */
301         page = nth_page(page, (offset >> PAGE_SHIFT));
302         offset %= PAGE_SIZE;
303
304 #ifdef CONFIG_HIGHMEM
305         local_irq_save(flags);
306 #endif
307         buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
308
309         hwif->nleft--;
310         hwif->cursg_ofs++;
311
312         if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
313                 hwif->cursg = sg_next(hwif->cursg);
314                 hwif->cursg_ofs = 0;
315         }
316
317         /* do the actual data transfer */
318         if (write)
319                 taskfile_output_data(drive, buf, SECTOR_WORDS);
320         else
321                 taskfile_input_data(drive, buf, SECTOR_WORDS);
322
323         kunmap_atomic(buf, KM_BIO_SRC_IRQ);
324 #ifdef CONFIG_HIGHMEM
325         local_irq_restore(flags);
326 #endif
327 }
328
329 static void ide_pio_multi(ide_drive_t *drive, unsigned int write)
330 {
331         unsigned int nsect;
332
333         nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count);
334         while (nsect--)
335                 ide_pio_sector(drive, write);
336 }
337
338 static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
339                                      unsigned int write)
340 {
341         if (rq->bio)    /* fs request */
342                 rq->errors = 0;
343
344         touch_softlockup_watchdog();
345
346         switch (drive->hwif->data_phase) {
347         case TASKFILE_MULTI_IN:
348         case TASKFILE_MULTI_OUT:
349                 ide_pio_multi(drive, write);
350                 break;
351         default:
352                 ide_pio_sector(drive, write);
353                 break;
354         }
355 }
356
357 static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
358                                   const char *s, u8 stat)
359 {
360         if (rq->bio) {
361                 ide_hwif_t *hwif = drive->hwif;
362                 int sectors = hwif->nsect - hwif->nleft;
363
364                 switch (hwif->data_phase) {
365                 case TASKFILE_IN:
366                         if (hwif->nleft)
367                                 break;
368                         /* fall through */
369                 case TASKFILE_OUT:
370                         sectors--;
371                         break;
372                 case TASKFILE_MULTI_IN:
373                         if (hwif->nleft)
374                                 break;
375                         /* fall through */
376                 case TASKFILE_MULTI_OUT:
377                         sectors -= drive->mult_count;
378                 default:
379                         break;
380                 }
381
382                 if (sectors > 0) {
383                         ide_driver_t *drv;
384
385                         drv = *(ide_driver_t **)rq->rq_disk->private_data;
386                         drv->end_request(drive, 1, sectors);
387                 }
388         }
389         return ide_error(drive, s, stat);
390 }
391
392 static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
393 {
394         HWIF(drive)->cursg = NULL;
395
396         if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
397                 ide_task_t *task = rq->special;
398
399                 if (task->tf_flags & IDE_TFLAG_FLAGGED) {
400                         u8 err = drive->hwif->INB(IDE_ERROR_REG);
401                         ide_end_drive_cmd(drive, stat, err);
402                         return;
403                 }
404         }
405
406         if (rq->rq_disk) {
407                 ide_driver_t *drv;
408
409                 drv = *(ide_driver_t **)rq->rq_disk->private_data;;
410                 drv->end_request(drive, 1, rq->hard_nr_sectors);
411         } else
412                 ide_end_request(drive, 1, rq->hard_nr_sectors);
413 }
414
415 /*
416  * Handler for command with PIO data-in phase (Read/Read Multiple).
417  */
418 ide_startstop_t task_in_intr (ide_drive_t *drive)
419 {
420         ide_hwif_t *hwif = drive->hwif;
421         struct request *rq = HWGROUP(drive)->rq;
422         u8 stat = hwif->INB(IDE_STATUS_REG);
423
424         /* new way for dealing with premature shared PCI interrupts */
425         if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
426                 if (stat & (ERR_STAT | DRQ_STAT))
427                         return task_error(drive, rq, __FUNCTION__, stat);
428                 /* No data yet, so wait for another IRQ. */
429                 ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
430                 return ide_started;
431         }
432
433         ide_pio_datablock(drive, rq, 0);
434
435         /* If it was the last datablock check status and finish transfer. */
436         if (!hwif->nleft) {
437                 stat = wait_drive_not_busy(drive);
438                 if (!OK_STAT(stat, 0, BAD_R_STAT))
439                         return task_error(drive, rq, __FUNCTION__, stat);
440                 task_end_request(drive, rq, stat);
441                 return ide_stopped;
442         }
443
444         /* Still data left to transfer. */
445         ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
446
447         return ide_started;
448 }
449 EXPORT_SYMBOL(task_in_intr);
450
451 /*
452  * Handler for command with PIO data-out phase (Write/Write Multiple).
453  */
454 static ide_startstop_t task_out_intr (ide_drive_t *drive)
455 {
456         ide_hwif_t *hwif = drive->hwif;
457         struct request *rq = HWGROUP(drive)->rq;
458         u8 stat = hwif->INB(IDE_STATUS_REG);
459
460         if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
461                 return task_error(drive, rq, __FUNCTION__, stat);
462
463         /* Deal with unexpected ATA data phase. */
464         if (((stat & DRQ_STAT) == 0) ^ !hwif->nleft)
465                 return task_error(drive, rq, __FUNCTION__, stat);
466
467         if (!hwif->nleft) {
468                 task_end_request(drive, rq, stat);
469                 return ide_stopped;
470         }
471
472         /* Still data left to transfer. */
473         ide_pio_datablock(drive, rq, 1);
474         ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
475
476         return ide_started;
477 }
478
479 ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
480 {
481         ide_startstop_t startstop;
482
483         if (ide_wait_stat(&startstop, drive, DATA_READY,
484                           drive->bad_wstat, WAIT_DRQ)) {
485                 printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
486                                 drive->name,
487                                 drive->hwif->data_phase ? "MULT" : "",
488                                 drive->addressing ? "_EXT" : "");
489                 return startstop;
490         }
491
492         if (!drive->unmask)
493                 local_irq_disable();
494
495         ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
496         ide_pio_datablock(drive, rq, 1);
497
498         return ide_started;
499 }
500 EXPORT_SYMBOL(pre_task_out_intr);
501
502 static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf)
503 {
504         struct request rq;
505
506         memset(&rq, 0, sizeof(rq));
507         rq.ref_count = 1;
508         rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
509         rq.buffer = buf;
510
511         /*
512          * (ks) We transfer currently only whole sectors.
513          * This is suffient for now.  But, it would be great,
514          * if we would find a solution to transfer any size.
515          * To support special commands like READ LONG.
516          */
517         if (args->command_type != IDE_DRIVE_TASK_NO_DATA) {
518                 if (data_size == 0)
519                         rq.nr_sectors = (args->tf.hob_nsect << 8) | args->tf.nsect;
520                 else
521                         rq.nr_sectors = data_size / SECTOR_SIZE;
522
523                 if (!rq.nr_sectors) {
524                         printk(KERN_ERR "%s: in/out command without data\n",
525                                         drive->name);
526                         return -EFAULT;
527                 }
528
529                 rq.hard_nr_sectors = rq.nr_sectors;
530                 rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors;
531
532                 if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
533                         rq.cmd_flags |= REQ_RW;
534         }
535
536         rq.special = args;
537         args->rq = &rq;
538         return ide_do_drive_cmd(drive, &rq, ide_wait);
539 }
540
541 int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf)
542 {
543         return ide_diag_taskfile(drive, args, 0, buf);
544 }
545
546 EXPORT_SYMBOL(ide_raw_taskfile);
547
548 int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task)
549 {
550         task->command_type = IDE_DRIVE_TASK_NO_DATA;
551         task->data_phase   = TASKFILE_NO_DATA;
552         task->handler      = task_no_data_intr;
553
554         return ide_raw_taskfile(drive, task, NULL);
555 }
556 EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
557
558 #ifdef CONFIG_IDE_TASK_IOCTL
559 int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
560 {
561         ide_task_request_t      *req_task;
562         ide_task_t              args;
563         u8 *outbuf              = NULL;
564         u8 *inbuf               = NULL;
565         int err                 = 0;
566         int tasksize            = sizeof(struct ide_task_request_s);
567         unsigned int taskin     = 0;
568         unsigned int taskout    = 0;
569         u8 io_32bit             = drive->io_32bit;
570         char __user *buf = (char __user *)arg;
571
572 //      printk("IDE Taskfile ...\n");
573
574         req_task = kzalloc(tasksize, GFP_KERNEL);
575         if (req_task == NULL) return -ENOMEM;
576         if (copy_from_user(req_task, buf, tasksize)) {
577                 kfree(req_task);
578                 return -EFAULT;
579         }
580
581         taskout = req_task->out_size;
582         taskin  = req_task->in_size;
583         
584         if (taskin > 65536 || taskout > 65536) {
585                 err = -EINVAL;
586                 goto abort;
587         }
588
589         if (taskout) {
590                 int outtotal = tasksize;
591                 outbuf = kzalloc(taskout, GFP_KERNEL);
592                 if (outbuf == NULL) {
593                         err = -ENOMEM;
594                         goto abort;
595                 }
596                 if (copy_from_user(outbuf, buf + outtotal, taskout)) {
597                         err = -EFAULT;
598                         goto abort;
599                 }
600         }
601
602         if (taskin) {
603                 int intotal = tasksize + taskout;
604                 inbuf = kzalloc(taskin, GFP_KERNEL);
605                 if (inbuf == NULL) {
606                         err = -ENOMEM;
607                         goto abort;
608                 }
609                 if (copy_from_user(inbuf, buf + intotal, taskin)) {
610                         err = -EFAULT;
611                         goto abort;
612                 }
613         }
614
615         memset(&args, 0, sizeof(ide_task_t));
616
617         memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
618         memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
619         args.tf_in_flags  = req_task->in_flags;
620         args.data_phase   = req_task->data_phase;
621         args.command_type = req_task->req_cmd;
622
623         args.tf_flags = IDE_TFLAG_OUT_DEVICE;
624         if (drive->addressing == 1)
625                 args.tf_flags |= IDE_TFLAG_LBA48;
626
627         if (req_task->out_flags.all) {
628                 args.tf_flags |= IDE_TFLAG_FLAGGED;
629
630                 if (req_task->out_flags.b.data)
631                         args.tf_flags |= IDE_TFLAG_OUT_DATA;
632
633                 if (req_task->out_flags.b.nsector_hob)
634                         args.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
635                 if (req_task->out_flags.b.sector_hob)
636                         args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
637                 if (req_task->out_flags.b.lcyl_hob)
638                         args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
639                 if (req_task->out_flags.b.hcyl_hob)
640                         args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
641
642                 if (req_task->out_flags.b.error_feature)
643                         args.tf_flags |= IDE_TFLAG_OUT_FEATURE;
644                 if (req_task->out_flags.b.nsector)
645                         args.tf_flags |= IDE_TFLAG_OUT_NSECT;
646                 if (req_task->out_flags.b.sector)
647                         args.tf_flags |= IDE_TFLAG_OUT_LBAL;
648                 if (req_task->out_flags.b.lcyl)
649                         args.tf_flags |= IDE_TFLAG_OUT_LBAM;
650                 if (req_task->out_flags.b.hcyl)
651                         args.tf_flags |= IDE_TFLAG_OUT_LBAH;
652         } else {
653                 args.tf_flags |= IDE_TFLAG_OUT_TF;
654                 if (args.tf_flags & IDE_TFLAG_LBA48)
655                         args.tf_flags |= IDE_TFLAG_OUT_HOB;
656         }
657
658         drive->io_32bit = 0;
659         switch(req_task->data_phase) {
660                 case TASKFILE_OUT_DMAQ:
661                 case TASKFILE_OUT_DMA:
662                         err = ide_diag_taskfile(drive, &args, taskout, outbuf);
663                         break;
664                 case TASKFILE_IN_DMAQ:
665                 case TASKFILE_IN_DMA:
666                         err = ide_diag_taskfile(drive, &args, taskin, inbuf);
667                         break;
668                 case TASKFILE_MULTI_OUT:
669                         if (!drive->mult_count) {
670                                 /* (hs): give up if multcount is not set */
671                                 printk(KERN_ERR "%s: %s Multimode Write " \
672                                         "multcount is not set\n",
673                                         drive->name, __FUNCTION__);
674                                 err = -EPERM;
675                                 goto abort;
676                         }
677                         /* fall through */
678                 case TASKFILE_OUT:
679                         args.prehandler = &pre_task_out_intr;
680                         args.handler = &task_out_intr;
681                         err = ide_diag_taskfile(drive, &args, taskout, outbuf);
682                         break;
683                 case TASKFILE_MULTI_IN:
684                         if (!drive->mult_count) {
685                                 /* (hs): give up if multcount is not set */
686                                 printk(KERN_ERR "%s: %s Multimode Read failure " \
687                                         "multcount is not set\n",
688                                         drive->name, __FUNCTION__);
689                                 err = -EPERM;
690                                 goto abort;
691                         }
692                         /* fall through */
693                 case TASKFILE_IN:
694                         args.handler = &task_in_intr;
695                         err = ide_diag_taskfile(drive, &args, taskin, inbuf);
696                         break;
697                 case TASKFILE_NO_DATA:
698                         args.handler = &task_no_data_intr;
699                         err = ide_diag_taskfile(drive, &args, 0, NULL);
700                         break;
701                 default:
702                         err = -EFAULT;
703                         goto abort;
704         }
705
706         memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2);
707         memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE);
708         req_task->in_flags  = args.tf_in_flags;
709
710         if (copy_to_user(buf, req_task, tasksize)) {
711                 err = -EFAULT;
712                 goto abort;
713         }
714         if (taskout) {
715                 int outtotal = tasksize;
716                 if (copy_to_user(buf + outtotal, outbuf, taskout)) {
717                         err = -EFAULT;
718                         goto abort;
719                 }
720         }
721         if (taskin) {
722                 int intotal = tasksize + taskout;
723                 if (copy_to_user(buf + intotal, inbuf, taskin)) {
724                         err = -EFAULT;
725                         goto abort;
726                 }
727         }
728 abort:
729         kfree(req_task);
730         kfree(outbuf);
731         kfree(inbuf);
732
733 //      printk("IDE Taskfile ioctl ended. rc = %i\n", err);
734
735         drive->io_32bit = io_32bit;
736
737         return err;
738 }
739 #endif
740
741 int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
742 {
743         struct request rq;
744         u8 buffer[4];
745
746         if (!buf)
747                 buf = buffer;
748         memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors);
749         ide_init_drive_cmd(&rq);
750         rq.buffer = buf;
751         *buf++ = cmd;
752         *buf++ = nsect;
753         *buf++ = feature;
754         *buf++ = sectors;
755         return ide_do_drive_cmd(drive, &rq, ide_wait);
756 }
757
758 int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
759 {
760         int err = 0;
761         u8 args[4], *argbuf = args;
762         u8 xfer_rate = 0;
763         int argsize = 4;
764         ide_task_t tfargs;
765         struct ide_taskfile *tf = &tfargs.tf;
766
767         if (NULL == (void *) arg) {
768                 struct request rq;
769                 ide_init_drive_cmd(&rq);
770                 return ide_do_drive_cmd(drive, &rq, ide_wait);
771         }
772
773         if (copy_from_user(args, (void __user *)arg, 4))
774                 return -EFAULT;
775
776         memset(&tfargs, 0, sizeof(ide_task_t));
777         tf->feature = args[2];
778         tf->nsect   = args[3];
779         tf->lbal    = args[1];
780         tf->command = args[0];
781
782         if (args[3]) {
783                 argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
784                 argbuf = kzalloc(argsize, GFP_KERNEL);
785                 if (argbuf == NULL)
786                         return -ENOMEM;
787         }
788         if (set_transfer(drive, &tfargs)) {
789                 xfer_rate = args[1];
790                 if (ide_ata66_check(drive, &tfargs))
791                         goto abort;
792         }
793
794         err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
795
796         if (!err && xfer_rate) {
797                 /* active-retuning-calls future */
798                 ide_set_xfer_rate(drive, xfer_rate);
799                 ide_driveid_update(drive);
800         }
801 abort:
802         if (copy_to_user((void __user *)arg, argbuf, argsize))
803                 err = -EFAULT;
804         if (argsize > 4)
805                 kfree(argbuf);
806         return err;
807 }
808
809 static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf)
810 {
811         struct request rq;
812
813         ide_init_drive_cmd(&rq);
814         rq.cmd_type = REQ_TYPE_ATA_TASK;
815         rq.buffer = buf;
816         return ide_do_drive_cmd(drive, &rq, ide_wait);
817 }
818
819 int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
820 {
821         void __user *p = (void __user *)arg;
822         int err = 0;
823         u8 args[7], *argbuf = args;
824         int argsize = 7;
825
826         if (copy_from_user(args, p, 7))
827                 return -EFAULT;
828         err = ide_wait_cmd_task(drive, argbuf);
829         if (copy_to_user(p, argbuf, argsize))
830                 err = -EFAULT;
831         return err;
832 }
833
834 /*
835  * NOTICE: This is additions from IBM to provide a discrete interface,
836  * for selective taskregister access operations.  Nice JOB Klaus!!!
837  * Glad to be able to work and co-develop this with you and IBM.
838  */
839 ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
840 {
841         if (task->data_phase == TASKFILE_MULTI_IN ||
842             task->data_phase == TASKFILE_MULTI_OUT) {
843                 if (!drive->mult_count) {
844                         printk(KERN_ERR "%s: multimode not set!\n", drive->name);
845                         return ide_stopped;
846                 }
847         }
848
849         /*
850          * (ks) Check taskfile in flags.
851          * If set, then execute as it is defined.
852          * If not set, then define default settings.
853          * The default values are:
854          *      read all taskfile registers (except data)
855          *      read the hob registers (sector, nsector, lcyl, hcyl)
856          */
857         if (task->tf_in_flags.all == 0) {
858                 task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
859                 if (drive->addressing == 1)
860                         task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS  << 8);
861         }
862
863         return do_rw_taskfile(drive, task);
864 }