]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/ide/ide-taskfile.c
ide: merge all TASKFILE_NO_DATA data phase handlers into taskfile_no_intr()
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-taskfile.c
1 /*
2  *  Copyright (C) 2000-2002        Michael Cornwell <cornwell@acm.org>
3  *  Copyright (C) 2000-2002        Andre Hedrick <andre@linux-ide.org>
4  *  Copyright (C) 2001-2002        Klaus Smolin
5  *                                      IBM Storage Technology Division
6  *  Copyright (C) 2003-2004, 2007  Bartlomiej Zolnierkiewicz
7  *
8  *  The big the bad and the ugly.
9  */
10
11 #include <linux/types.h>
12 #include <linux/string.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/interrupt.h>
16 #include <linux/errno.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
19 #include <linux/hdreg.h>
20 #include <linux/ide.h>
21 #include <linux/scatterlist.h>
22
23 #include <asm/uaccess.h>
24 #include <asm/io.h>
25
26 void ide_tf_dump(const char *s, struct ide_taskfile *tf)
27 {
28 #ifdef DEBUG
29         printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x "
30                 "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
31                 s, tf->feature, tf->nsect, tf->lbal,
32                 tf->lbam, tf->lbah, tf->device, tf->command);
33         printk("%s: hob: nsect 0x%02x lbal 0x%02x "
34                 "lbam 0x%02x lbah 0x%02x\n",
35                 s, tf->hob_nsect, tf->hob_lbal,
36                 tf->hob_lbam, tf->hob_lbah);
37 #endif
38 }
39
40 int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
41 {
42         ide_task_t args;
43
44         memset(&args, 0, sizeof(ide_task_t));
45         args.tf.nsect = 0x01;
46         if (drive->media == ide_disk)
47                 args.tf.command = ATA_CMD_ID_ATA;
48         else
49                 args.tf.command = ATA_CMD_ID_ATAPI;
50         args.tf_flags   = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
51         args.data_phase = TASKFILE_IN;
52         return ide_raw_taskfile(drive, &args, buf, 1);
53 }
54
55 static ide_startstop_t task_no_data_intr(ide_drive_t *);
56 static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *);
57 static ide_startstop_t task_in_intr(ide_drive_t *);
58
59 ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
60 {
61         ide_hwif_t *hwif        = HWIF(drive);
62         struct ide_taskfile *tf = &task->tf;
63         ide_handler_t *handler = NULL;
64         const struct ide_tp_ops *tp_ops = hwif->tp_ops;
65         const struct ide_dma_ops *dma_ops = hwif->dma_ops;
66
67         if (task->data_phase == TASKFILE_MULTI_IN ||
68             task->data_phase == TASKFILE_MULTI_OUT) {
69                 if (!drive->mult_count) {
70                         printk(KERN_ERR "%s: multimode not set!\n",
71                                         drive->name);
72                         return ide_stopped;
73                 }
74         }
75
76         if (task->tf_flags & IDE_TFLAG_FLAGGED)
77                 task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS;
78
79         memcpy(&hwif->task, task, sizeof(*task));
80
81         if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
82                 ide_tf_dump(drive->name, tf);
83                 tp_ops->set_irq(hwif, 1);
84                 SELECT_MASK(drive, 0);
85                 tp_ops->tf_load(drive, task);
86         }
87
88         switch (task->data_phase) {
89         case TASKFILE_MULTI_OUT:
90         case TASKFILE_OUT:
91                 tp_ops->exec_command(hwif, tf->command);
92                 ndelay(400);    /* FIXME */
93                 return pre_task_out_intr(drive, task->rq);
94         case TASKFILE_MULTI_IN:
95         case TASKFILE_IN:
96                 handler = task_in_intr;
97                 /* fall-through */
98         case TASKFILE_NO_DATA:
99                 if (handler == NULL)
100                         handler = task_no_data_intr;
101                 ide_execute_command(drive, tf->command, handler,
102                                     WAIT_WORSTCASE, NULL);
103                 return ide_started;
104         default:
105                 if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
106                     dma_ops->dma_setup(drive))
107                         return ide_stopped;
108                 dma_ops->dma_exec_cmd(drive, tf->command);
109                 dma_ops->dma_start(drive);
110                 return ide_started;
111         }
112 }
113 EXPORT_SYMBOL_GPL(do_rw_taskfile);
114
115 /*
116  * Handler for commands without a data phase
117  */
118 static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
119 {
120         ide_hwif_t *hwif = drive->hwif;
121         ide_task_t *task = &hwif->task;
122         struct ide_taskfile *tf = &task->tf;
123         int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
124         int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1;
125         u8 stat;
126
127         local_irq_enable_in_hardirq();
128
129         while (1) {
130                 stat = hwif->tp_ops->read_status(hwif);
131                 if ((stat & ATA_BUSY) == 0 || retries-- == 0)
132                         break;
133                 udelay(10);
134         };
135
136         if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
137                 if (custom && tf->command == ATA_CMD_SET_MULTI) {
138                         drive->mult_req = drive->mult_count = 0;
139                         drive->special.b.recalibrate = 1;
140                         (void)ide_dump_status(drive, __func__, stat);
141                         return ide_stopped;
142                 } else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
143                         if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
144                                 ide_set_handler(drive, &task_no_data_intr,
145                                                 WAIT_WORSTCASE, NULL);
146                                 return ide_started;
147                         }
148                 }
149                 return ide_error(drive, "task_no_data_intr", stat);
150                 /* calls ide_end_drive_cmd */
151         }
152
153         if (!custom)
154                 ide_end_drive_cmd(drive, stat, ide_read_error(drive));
155         else if (tf->command == ATA_CMD_SET_MULTI)
156                 drive->mult_count = drive->mult_req;
157
158         return ide_stopped;
159 }
160
161 static u8 wait_drive_not_busy(ide_drive_t *drive)
162 {
163         ide_hwif_t *hwif = drive->hwif;
164         int retries;
165         u8 stat;
166
167         /*
168          * Last sector was transfered, wait until device is ready.  This can
169          * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.
170          */
171         for (retries = 0; retries < 1000; retries++) {
172                 stat = hwif->tp_ops->read_status(hwif);
173
174                 if (stat & ATA_BUSY)
175                         udelay(10);
176                 else
177                         break;
178         }
179
180         if (stat & ATA_BUSY)
181                 printk(KERN_ERR "%s: drive still BUSY!\n", drive->name);
182
183         return stat;
184 }
185
186 static void ide_pio_sector(ide_drive_t *drive, struct request *rq,
187                            unsigned int write)
188 {
189         ide_hwif_t *hwif = drive->hwif;
190         struct scatterlist *sg = hwif->sg_table;
191         struct scatterlist *cursg = hwif->cursg;
192         struct page *page;
193 #ifdef CONFIG_HIGHMEM
194         unsigned long flags;
195 #endif
196         unsigned int offset;
197         u8 *buf;
198
199         cursg = hwif->cursg;
200         if (!cursg) {
201                 cursg = sg;
202                 hwif->cursg = sg;
203         }
204
205         page = sg_page(cursg);
206         offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
207
208         /* get the current page and offset */
209         page = nth_page(page, (offset >> PAGE_SHIFT));
210         offset %= PAGE_SIZE;
211
212 #ifdef CONFIG_HIGHMEM
213         local_irq_save(flags);
214 #endif
215         buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
216
217         hwif->nleft--;
218         hwif->cursg_ofs++;
219
220         if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
221                 hwif->cursg = sg_next(hwif->cursg);
222                 hwif->cursg_ofs = 0;
223         }
224
225         /* do the actual data transfer */
226         if (write)
227                 hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE);
228         else
229                 hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE);
230
231         kunmap_atomic(buf, KM_BIO_SRC_IRQ);
232 #ifdef CONFIG_HIGHMEM
233         local_irq_restore(flags);
234 #endif
235 }
236
237 static void ide_pio_multi(ide_drive_t *drive, struct request *rq,
238                           unsigned int write)
239 {
240         unsigned int nsect;
241
242         nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count);
243         while (nsect--)
244                 ide_pio_sector(drive, rq, write);
245 }
246
247 static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
248                                      unsigned int write)
249 {
250         u8 saved_io_32bit = drive->io_32bit;
251
252         if (rq->bio)    /* fs request */
253                 rq->errors = 0;
254
255         if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
256                 ide_task_t *task = rq->special;
257
258                 if (task->tf_flags & IDE_TFLAG_IO_16BIT)
259                         drive->io_32bit = 0;
260         }
261
262         touch_softlockup_watchdog();
263
264         switch (drive->hwif->data_phase) {
265         case TASKFILE_MULTI_IN:
266         case TASKFILE_MULTI_OUT:
267                 ide_pio_multi(drive, rq, write);
268                 break;
269         default:
270                 ide_pio_sector(drive, rq, write);
271                 break;
272         }
273
274         drive->io_32bit = saved_io_32bit;
275 }
276
277 static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
278                                   const char *s, u8 stat)
279 {
280         if (rq->bio) {
281                 ide_hwif_t *hwif = drive->hwif;
282                 int sectors = hwif->nsect - hwif->nleft;
283
284                 switch (hwif->data_phase) {
285                 case TASKFILE_IN:
286                         if (hwif->nleft)
287                                 break;
288                         /* fall through */
289                 case TASKFILE_OUT:
290                         sectors--;
291                         break;
292                 case TASKFILE_MULTI_IN:
293                         if (hwif->nleft)
294                                 break;
295                         /* fall through */
296                 case TASKFILE_MULTI_OUT:
297                         sectors -= drive->mult_count;
298                 default:
299                         break;
300                 }
301
302                 if (sectors > 0) {
303                         ide_driver_t *drv;
304
305                         drv = *(ide_driver_t **)rq->rq_disk->private_data;
306                         drv->end_request(drive, 1, sectors);
307                 }
308         }
309         return ide_error(drive, s, stat);
310 }
311
312 void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
313 {
314         if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
315                 u8 err = ide_read_error(drive);
316
317                 ide_end_drive_cmd(drive, stat, err);
318                 return;
319         }
320
321         if (rq->rq_disk) {
322                 ide_driver_t *drv;
323
324                 drv = *(ide_driver_t **)rq->rq_disk->private_data;;
325                 drv->end_request(drive, 1, rq->nr_sectors);
326         } else
327                 ide_end_request(drive, 1, rq->nr_sectors);
328 }
329
330 /*
331  * We got an interrupt on a task_in case, but no errors and no DRQ.
332  *
333  * It might be a spurious irq (shared irq), but it might be a
334  * command that had no output.
335  */
336 static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat)
337 {
338         /* Command all done? */
339         if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) {
340                 task_end_request(drive, rq, stat);
341                 return ide_stopped;
342         }
343
344         /* Assume it was a spurious irq */
345         ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
346         return ide_started;
347 }
348
349 /*
350  * Handler for command with PIO data-in phase (Read/Read Multiple).
351  */
352 static ide_startstop_t task_in_intr(ide_drive_t *drive)
353 {
354         ide_hwif_t *hwif = drive->hwif;
355         struct request *rq = hwif->hwgroup->rq;
356         u8 stat = hwif->tp_ops->read_status(hwif);
357
358         /* Error? */
359         if (stat & ATA_ERR)
360                 return task_error(drive, rq, __func__, stat);
361
362         /* Didn't want any data? Odd. */
363         if ((stat & ATA_DRQ) == 0)
364                 return task_in_unexpected(drive, rq, stat);
365
366         ide_pio_datablock(drive, rq, 0);
367
368         /* Are we done? Check status and finish transfer. */
369         if (!hwif->nleft) {
370                 stat = wait_drive_not_busy(drive);
371                 if (!OK_STAT(stat, 0, BAD_STAT))
372                         return task_error(drive, rq, __func__, stat);
373                 task_end_request(drive, rq, stat);
374                 return ide_stopped;
375         }
376
377         /* Still data left to transfer. */
378         ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
379
380         return ide_started;
381 }
382
383 /*
384  * Handler for command with PIO data-out phase (Write/Write Multiple).
385  */
386 static ide_startstop_t task_out_intr (ide_drive_t *drive)
387 {
388         ide_hwif_t *hwif = drive->hwif;
389         struct request *rq = HWGROUP(drive)->rq;
390         u8 stat = hwif->tp_ops->read_status(hwif);
391
392         if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
393                 return task_error(drive, rq, __func__, stat);
394
395         /* Deal with unexpected ATA data phase. */
396         if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft)
397                 return task_error(drive, rq, __func__, stat);
398
399         if (!hwif->nleft) {
400                 task_end_request(drive, rq, stat);
401                 return ide_stopped;
402         }
403
404         /* Still data left to transfer. */
405         ide_pio_datablock(drive, rq, 1);
406         ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
407
408         return ide_started;
409 }
410
411 static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
412 {
413         ide_startstop_t startstop;
414
415         if (ide_wait_stat(&startstop, drive, ATA_DRQ,
416                           drive->bad_wstat, WAIT_DRQ)) {
417                 printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
418                         drive->name, drive->hwif->data_phase ? "MULT" : "",
419                         (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
420                 return startstop;
421         }
422
423         if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
424                 local_irq_disable();
425
426         ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
427         ide_pio_datablock(drive, rq, 1);
428
429         return ide_started;
430 }
431
432 int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
433 {
434         struct request *rq;
435         int error;
436
437         rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
438         rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
439         rq->buffer = buf;
440
441         /*
442          * (ks) We transfer currently only whole sectors.
443          * This is suffient for now.  But, it would be great,
444          * if we would find a solution to transfer any size.
445          * To support special commands like READ LONG.
446          */
447         rq->hard_nr_sectors = rq->nr_sectors = nsect;
448         rq->hard_cur_sectors = rq->current_nr_sectors = nsect;
449
450         if (task->tf_flags & IDE_TFLAG_WRITE)
451                 rq->cmd_flags |= REQ_RW;
452
453         rq->special = task;
454         task->rq = rq;
455
456         error = blk_execute_rq(drive->queue, NULL, rq, 0);
457         blk_put_request(rq);
458
459         return error;
460 }
461
462 EXPORT_SYMBOL(ide_raw_taskfile);
463
464 int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task)
465 {
466         task->data_phase = TASKFILE_NO_DATA;
467
468         return ide_raw_taskfile(drive, task, NULL, 0);
469 }
470 EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
471
472 #ifdef CONFIG_IDE_TASK_IOCTL
473 int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
474 {
475         ide_task_request_t      *req_task;
476         ide_task_t              args;
477         u8 *outbuf              = NULL;
478         u8 *inbuf               = NULL;
479         u8 *data_buf            = NULL;
480         int err                 = 0;
481         int tasksize            = sizeof(struct ide_task_request_s);
482         unsigned int taskin     = 0;
483         unsigned int taskout    = 0;
484         u16 nsect               = 0;
485         char __user *buf = (char __user *)arg;
486
487 //      printk("IDE Taskfile ...\n");
488
489         req_task = kzalloc(tasksize, GFP_KERNEL);
490         if (req_task == NULL) return -ENOMEM;
491         if (copy_from_user(req_task, buf, tasksize)) {
492                 kfree(req_task);
493                 return -EFAULT;
494         }
495
496         taskout = req_task->out_size;
497         taskin  = req_task->in_size;
498         
499         if (taskin > 65536 || taskout > 65536) {
500                 err = -EINVAL;
501                 goto abort;
502         }
503
504         if (taskout) {
505                 int outtotal = tasksize;
506                 outbuf = kzalloc(taskout, GFP_KERNEL);
507                 if (outbuf == NULL) {
508                         err = -ENOMEM;
509                         goto abort;
510                 }
511                 if (copy_from_user(outbuf, buf + outtotal, taskout)) {
512                         err = -EFAULT;
513                         goto abort;
514                 }
515         }
516
517         if (taskin) {
518                 int intotal = tasksize + taskout;
519                 inbuf = kzalloc(taskin, GFP_KERNEL);
520                 if (inbuf == NULL) {
521                         err = -ENOMEM;
522                         goto abort;
523                 }
524                 if (copy_from_user(inbuf, buf + intotal, taskin)) {
525                         err = -EFAULT;
526                         goto abort;
527                 }
528         }
529
530         memset(&args, 0, sizeof(ide_task_t));
531
532         memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
533         memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
534
535         args.data_phase = req_task->data_phase;
536
537         args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
538                         IDE_TFLAG_IN_TF;
539         if (drive->dev_flags & IDE_DFLAG_LBA48)
540                 args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
541
542         if (req_task->out_flags.all) {
543                 args.tf_flags |= IDE_TFLAG_FLAGGED;
544
545                 if (req_task->out_flags.b.data)
546                         args.tf_flags |= IDE_TFLAG_OUT_DATA;
547
548                 if (req_task->out_flags.b.nsector_hob)
549                         args.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
550                 if (req_task->out_flags.b.sector_hob)
551                         args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
552                 if (req_task->out_flags.b.lcyl_hob)
553                         args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
554                 if (req_task->out_flags.b.hcyl_hob)
555                         args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
556
557                 if (req_task->out_flags.b.error_feature)
558                         args.tf_flags |= IDE_TFLAG_OUT_FEATURE;
559                 if (req_task->out_flags.b.nsector)
560                         args.tf_flags |= IDE_TFLAG_OUT_NSECT;
561                 if (req_task->out_flags.b.sector)
562                         args.tf_flags |= IDE_TFLAG_OUT_LBAL;
563                 if (req_task->out_flags.b.lcyl)
564                         args.tf_flags |= IDE_TFLAG_OUT_LBAM;
565                 if (req_task->out_flags.b.hcyl)
566                         args.tf_flags |= IDE_TFLAG_OUT_LBAH;
567         } else {
568                 args.tf_flags |= IDE_TFLAG_OUT_TF;
569                 if (args.tf_flags & IDE_TFLAG_LBA48)
570                         args.tf_flags |= IDE_TFLAG_OUT_HOB;
571         }
572
573         if (req_task->in_flags.b.data)
574                 args.tf_flags |= IDE_TFLAG_IN_DATA;
575
576         switch(req_task->data_phase) {
577                 case TASKFILE_MULTI_OUT:
578                         if (!drive->mult_count) {
579                                 /* (hs): give up if multcount is not set */
580                                 printk(KERN_ERR "%s: %s Multimode Write " \
581                                         "multcount is not set\n",
582                                         drive->name, __func__);
583                                 err = -EPERM;
584                                 goto abort;
585                         }
586                         /* fall through */
587                 case TASKFILE_OUT:
588                         /* fall through */
589                 case TASKFILE_OUT_DMAQ:
590                 case TASKFILE_OUT_DMA:
591                         nsect = taskout / SECTOR_SIZE;
592                         data_buf = outbuf;
593                         break;
594                 case TASKFILE_MULTI_IN:
595                         if (!drive->mult_count) {
596                                 /* (hs): give up if multcount is not set */
597                                 printk(KERN_ERR "%s: %s Multimode Read failure " \
598                                         "multcount is not set\n",
599                                         drive->name, __func__);
600                                 err = -EPERM;
601                                 goto abort;
602                         }
603                         /* fall through */
604                 case TASKFILE_IN:
605                         /* fall through */
606                 case TASKFILE_IN_DMAQ:
607                 case TASKFILE_IN_DMA:
608                         nsect = taskin / SECTOR_SIZE;
609                         data_buf = inbuf;
610                         break;
611                 case TASKFILE_NO_DATA:
612                         break;
613                 default:
614                         err = -EFAULT;
615                         goto abort;
616         }
617
618         if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
619                 nsect = 0;
620         else if (!nsect) {
621                 nsect = (args.tf.hob_nsect << 8) | args.tf.nsect;
622
623                 if (!nsect) {
624                         printk(KERN_ERR "%s: in/out command without data\n",
625                                         drive->name);
626                         err = -EFAULT;
627                         goto abort;
628                 }
629         }
630
631         if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE)
632                 args.tf_flags |= IDE_TFLAG_WRITE;
633
634         err = ide_raw_taskfile(drive, &args, data_buf, nsect);
635
636         memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2);
637         memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE);
638
639         if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) &&
640             req_task->in_flags.all == 0) {
641                 req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
642                 if (drive->dev_flags & IDE_DFLAG_LBA48)
643                         req_task->in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8);
644         }
645
646         if (copy_to_user(buf, req_task, tasksize)) {
647                 err = -EFAULT;
648                 goto abort;
649         }
650         if (taskout) {
651                 int outtotal = tasksize;
652                 if (copy_to_user(buf + outtotal, outbuf, taskout)) {
653                         err = -EFAULT;
654                         goto abort;
655                 }
656         }
657         if (taskin) {
658                 int intotal = tasksize + taskout;
659                 if (copy_to_user(buf + intotal, inbuf, taskin)) {
660                         err = -EFAULT;
661                         goto abort;
662                 }
663         }
664 abort:
665         kfree(req_task);
666         kfree(outbuf);
667         kfree(inbuf);
668
669 //      printk("IDE Taskfile ioctl ended. rc = %i\n", err);
670
671         return err;
672 }
673 #endif