2 * linux/drivers/ide/ide-taskfile.c Version 0.38 March 05, 2003
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 Bartlomiej Zolnierkiewicz
10 * The big the bad and the ugly.
12 * Problems to be fixed because of BH interface or the lack therefore.
14 * Fill me in stupid !!!
17 * General refers to the Controller and Driver "pair".
19 * Under the context of Linux it generally refers to an interrupt handler.
20 * However, it correctly describes the 'HOST'
22 * The amount of data needed to be transfered as predefined in the
23 * setup of the device.
25 * The 'DATA BLOCK' associated to the 'DATA HANDLER', and can be as
26 * small as a single sector or as large as the entire command block
30 #include <linux/config.h>
31 #include <linux/module.h>
32 #include <linux/types.h>
33 #include <linux/string.h>
34 #include <linux/kernel.h>
35 #include <linux/timer.h>
37 #include <linux/interrupt.h>
38 #include <linux/major.h>
39 #include <linux/errno.h>
40 #include <linux/genhd.h>
41 #include <linux/blkpg.h>
42 #include <linux/slab.h>
43 #include <linux/pci.h>
44 #include <linux/delay.h>
45 #include <linux/hdreg.h>
46 #include <linux/ide.h>
48 #include <asm/byteorder.h>
50 #include <asm/uaccess.h>
52 #include <asm/bitops.h>
54 #define DEBUG_TASKFILE 0 /* unset when fixed */
56 static void ata_bswap_data (void *buffer, int wcount)
61 *p = *p << 8 | *p >> 8; p++;
62 *p = *p << 8 | *p >> 8; p++;
67 void taskfile_input_data (ide_drive_t *drive, void *buffer, u32 wcount)
69 HWIF(drive)->ata_input_data(drive, buffer, wcount);
71 ata_bswap_data(buffer, wcount);
74 EXPORT_SYMBOL(taskfile_input_data);
76 void taskfile_output_data (ide_drive_t *drive, void *buffer, u32 wcount)
79 ata_bswap_data(buffer, wcount);
80 HWIF(drive)->ata_output_data(drive, buffer, wcount);
81 ata_bswap_data(buffer, wcount);
83 HWIF(drive)->ata_output_data(drive, buffer, wcount);
87 EXPORT_SYMBOL(taskfile_output_data);
89 int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
92 memset(&args, 0, sizeof(ide_task_t));
93 args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01;
94 if (drive->media == ide_disk)
95 args.tfRegister[IDE_COMMAND_OFFSET] = WIN_IDENTIFY;
97 args.tfRegister[IDE_COMMAND_OFFSET] = WIN_PIDENTIFY;
98 args.command_type = IDE_DRIVE_TASK_IN;
99 args.handler = &task_in_intr;
100 return ide_raw_taskfile(drive, &args, buf);
103 EXPORT_SYMBOL(taskfile_lib_get_identify);
105 #ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
106 void debug_taskfile (ide_drive_t *drive, ide_task_t *args)
108 printk(KERN_INFO "%s: ", drive->name);
109 // printk("TF.0=x%02x ", args->tfRegister[IDE_DATA_OFFSET]);
110 printk("TF.1=x%02x ", args->tfRegister[IDE_FEATURE_OFFSET]);
111 printk("TF.2=x%02x ", args->tfRegister[IDE_NSECTOR_OFFSET]);
112 printk("TF.3=x%02x ", args->tfRegister[IDE_SECTOR_OFFSET]);
113 printk("TF.4=x%02x ", args->tfRegister[IDE_LCYL_OFFSET]);
114 printk("TF.5=x%02x ", args->tfRegister[IDE_HCYL_OFFSET]);
115 printk("TF.6=x%02x ", args->tfRegister[IDE_SELECT_OFFSET]);
116 printk("TF.7=x%02x\n", args->tfRegister[IDE_COMMAND_OFFSET]);
117 printk(KERN_INFO "%s: ", drive->name);
118 // printk("HTF.0=x%02x ", args->hobRegister[IDE_DATA_OFFSET]);
119 printk("HTF.1=x%02x ", args->hobRegister[IDE_FEATURE_OFFSET]);
120 printk("HTF.2=x%02x ", args->hobRegister[IDE_NSECTOR_OFFSET]);
121 printk("HTF.3=x%02x ", args->hobRegister[IDE_SECTOR_OFFSET]);
122 printk("HTF.4=x%02x ", args->hobRegister[IDE_LCYL_OFFSET]);
123 printk("HTF.5=x%02x ", args->hobRegister[IDE_HCYL_OFFSET]);
124 printk("HTF.6=x%02x ", args->hobRegister[IDE_SELECT_OFFSET]);
125 printk("HTF.7=x%02x\n", args->hobRegister[IDE_CONTROL_OFFSET_HOB]);
127 #endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
129 ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
131 ide_hwif_t *hwif = HWIF(drive);
132 task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
133 hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
134 u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF;
136 #ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
137 void debug_taskfile(drive, task);
138 #endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
140 /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
141 if (IDE_CONTROL_REG) {
143 hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
145 SELECT_MASK(drive, 0);
147 if (drive->addressing == 1) {
148 hwif->OUTB(hobfile->feature, IDE_FEATURE_REG);
149 hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
150 hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
151 hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG);
152 hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG);
155 hwif->OUTB(taskfile->feature, IDE_FEATURE_REG);
156 hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
157 hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
158 hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
159 hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
161 hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
163 if (task->handler != NULL) {
164 if (task->prehandler != NULL) {
165 hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG);
166 ndelay(400); /* FIXME */
167 return task->prehandler(drive, task->rq);
169 ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL);
173 if (!drive->using_dma)
176 switch (taskfile->command) {
177 case WIN_WRITEDMA_ONCE:
179 case WIN_WRITEDMA_EXT:
180 if (!hwif->ide_dma_write(drive))
183 case WIN_READDMA_ONCE:
185 case WIN_READDMA_EXT:
186 case WIN_IDENTIFY_DMA:
187 if (!hwif->ide_dma_read(drive))
191 if (task->handler == NULL)
198 EXPORT_SYMBOL(do_rw_taskfile);
201 * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
203 ide_startstop_t set_multmode_intr (ide_drive_t *drive)
205 ide_hwif_t *hwif = HWIF(drive);
208 if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
209 drive->mult_count = drive->mult_req;
211 drive->mult_req = drive->mult_count = 0;
212 drive->special.b.recalibrate = 1;
213 (void) ide_dump_status(drive, "set_multmode", stat);
218 EXPORT_SYMBOL(set_multmode_intr);
221 * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd.
223 ide_startstop_t set_geometry_intr (ide_drive_t *drive)
225 ide_hwif_t *hwif = HWIF(drive);
229 while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
232 if (OK_STAT(stat, READY_STAT, BAD_STAT))
235 if (stat & (ERR_STAT|DRQ_STAT))
236 return DRIVER(drive)->error(drive, "set_geometry_intr", stat);
238 if (HWGROUP(drive)->handler != NULL)
240 ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL);
244 EXPORT_SYMBOL(set_geometry_intr);
247 * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
249 ide_startstop_t recal_intr (ide_drive_t *drive)
251 ide_hwif_t *hwif = HWIF(drive);
254 if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), READY_STAT, BAD_STAT))
255 return DRIVER(drive)->error(drive, "recal_intr", stat);
259 EXPORT_SYMBOL(recal_intr);
262 * Handler for commands without a data phase
264 ide_startstop_t task_no_data_intr (ide_drive_t *drive)
266 ide_task_t *args = HWGROUP(drive)->rq->special;
267 ide_hwif_t *hwif = HWIF(drive);
271 if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
272 return DRIVER(drive)->error(drive, "task_no_data_intr", stat);
273 /* calls ide_end_drive_cmd */
276 ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
281 EXPORT_SYMBOL(task_no_data_intr);
283 static void task_buffer_sectors(ide_drive_t *drive, struct request *rq,
284 unsigned nsect, unsigned rw)
286 char *buf = rq->buffer + blk_rq_offset(rq);
289 rq->current_nr_sectors -= nsect;
290 rq->nr_sectors -= nsect;
291 __task_sectors(drive, buf, nsect, rw);
294 static inline void task_buffer_multi_sectors(ide_drive_t *drive,
295 struct request *rq, unsigned rw)
297 unsigned int msect = drive->mult_count, nsect;
299 nsect = rq->current_nr_sectors;
303 task_buffer_sectors(drive, rq, nsect, rw);
306 #ifdef CONFIG_IDE_TASKFILE_IO
307 static void task_sectors(ide_drive_t *drive, struct request *rq,
308 unsigned nsect, unsigned rw)
310 if (rq->cbio) { /* fs request */
312 task_bio_sectors(drive, rq, nsect, rw);
313 } else /* task request */
314 task_buffer_sectors(drive, rq, nsect, rw);
317 static inline void task_bio_multi_sectors(ide_drive_t *drive,
318 struct request *rq, unsigned rw)
320 unsigned int nsect, msect = drive->mult_count;
323 nsect = rq->current_nr_sectors;
327 task_bio_sectors(drive, rq, nsect, rw);
336 static void task_multi_sectors(ide_drive_t *drive,
337 struct request *rq, unsigned rw)
339 if (rq->cbio) { /* fs request */
341 task_bio_multi_sectors(drive, rq, rw);
342 } else /* task request */
343 task_buffer_multi_sectors(drive, rq, rw);
346 # define task_sectors(d, rq, nsect, rw) task_buffer_sectors(d, rq, nsect, rw)
347 # define task_multi_sectors(d, rq, rw) task_buffer_multi_sectors(d, rq, rw)
348 #endif /* CONFIG_IDE_TASKFILE_IO */
350 static u8 wait_drive_not_busy(ide_drive_t *drive)
352 ide_hwif_t *hwif = HWIF(drive);
357 * Last sector was transfered, wait until drive is ready.
358 * This can take up to 10 usec, but we will wait max 1 ms
359 * (drive_cmd_intr() waits that long).
361 while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
365 printk(KERN_ERR "%s: drive still BUSY!\n", drive->name);
370 #ifdef CONFIG_IDE_TASKFILE_IO
371 static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
372 const char *s, u8 stat, unsigned cur_bad)
375 int sectors = rq->hard_nr_sectors - rq->nr_sectors - cur_bad;
378 drive->driver->end_request(drive, 1, sectors);
380 return drive->driver->error(drive, s, stat);
383 # define task_error(d, rq, s, stat, cur_bad) drive->driver->error(d, s, stat)
386 static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
388 if (rq->flags & REQ_DRIVE_TASKFILE) {
389 ide_task_t *task = rq->special;
391 if (task->tf_out_flags.all) {
392 u8 err = drive->hwif->INB(IDE_ERROR_REG);
393 ide_end_drive_cmd(drive, stat, err);
397 drive->driver->end_request(drive, 1, rq->hard_nr_sectors);
401 * Handler for command with PIO data-in phase (Read).
403 ide_startstop_t task_in_intr (ide_drive_t *drive)
405 struct request *rq = HWGROUP(drive)->rq;
406 u8 stat = HWIF(drive)->INB(IDE_STATUS_REG);
408 if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
409 if (stat & (ERR_STAT | DRQ_STAT))
410 return task_error(drive, rq, __FUNCTION__, stat, 0);
411 /* No data yet, so wait for another IRQ. */
412 ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
416 task_sectors(drive, rq, 1, IDE_PIO_IN);
418 /* If it was the last datablock check status and finish transfer. */
419 if (!rq->nr_sectors) {
420 stat = wait_drive_not_busy(drive);
421 if (!OK_STAT(stat, 0, BAD_R_STAT))
422 return task_error(drive, rq, __FUNCTION__, stat, 1);
423 task_end_request(drive, rq, stat);
427 /* Still data left to transfer. */
428 ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
432 EXPORT_SYMBOL(task_in_intr);
435 * Handler for command with PIO data-in phase (Read Multiple).
437 ide_startstop_t task_mulin_intr (ide_drive_t *drive)
439 struct request *rq = HWGROUP(drive)->rq;
440 u8 stat = HWIF(drive)->INB(IDE_STATUS_REG);
442 if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
443 if (stat & (ERR_STAT | DRQ_STAT))
444 return task_error(drive, rq, __FUNCTION__, stat, 0);
445 /* No data yet, so wait for another IRQ. */
446 ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL);
450 task_multi_sectors(drive, rq, IDE_PIO_IN);
452 /* If it was the last datablock check status and finish transfer. */
453 if (!rq->nr_sectors) {
454 stat = wait_drive_not_busy(drive);
455 if (!OK_STAT(stat, 0, BAD_R_STAT))
456 return task_error(drive, rq, __FUNCTION__, stat, drive->mult_count);
457 task_end_request(drive, rq, stat);
461 /* Still data left to transfer. */
462 ide_set_handler(drive, &task_mulin_intr, WAIT_WORSTCASE, NULL);
466 EXPORT_SYMBOL(task_mulin_intr);
469 * Handler for command with PIO data-out phase (Write).
471 ide_startstop_t task_out_intr (ide_drive_t *drive)
473 struct request *rq = HWGROUP(drive)->rq;
476 stat = HWIF(drive)->INB(IDE_STATUS_REG);
477 if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
478 return task_error(drive, rq, __FUNCTION__, stat, 1);
480 /* Deal with unexpected ATA data phase. */
481 if (((stat & DRQ_STAT) == 0) ^ !rq->nr_sectors)
482 return task_error(drive, rq, __FUNCTION__, stat, 1);
484 if (!rq->nr_sectors) {
485 task_end_request(drive, rq, stat);
489 /* Still data left to transfer. */
490 task_sectors(drive, rq, 1, IDE_PIO_OUT);
491 ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
496 EXPORT_SYMBOL(task_out_intr);
498 ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
500 ide_startstop_t startstop;
502 if (ide_wait_stat(&startstop, drive, DATA_READY,
503 drive->bad_wstat, WAIT_DRQ)) {
504 printk(KERN_ERR "%s: no DRQ after issuing WRITE%s\n",
505 drive->name, drive->addressing ? "_EXT" : "");
512 ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
513 task_sectors(drive, rq, 1, IDE_PIO_OUT);
517 EXPORT_SYMBOL(pre_task_out_intr);
520 * Handler for command with PIO data-out phase (Write Multiple).
522 ide_startstop_t task_mulout_intr (ide_drive_t *drive)
524 struct request *rq = HWGROUP(drive)->rq;
527 stat = HWIF(drive)->INB(IDE_STATUS_REG);
528 if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
529 return task_error(drive, rq, __FUNCTION__, stat, drive->mult_count);
531 /* Deal with unexpected ATA data phase. */
532 if (((stat & DRQ_STAT) == 0) ^ !rq->nr_sectors)
533 return task_error(drive, rq, __FUNCTION__, stat, drive->mult_count);
535 if (!rq->nr_sectors) {
536 task_end_request(drive, rq, stat);
540 /* Still data left to transfer. */
541 task_multi_sectors(drive, rq, IDE_PIO_OUT);
542 ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL);
546 EXPORT_SYMBOL(task_mulout_intr);
548 ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq)
550 ide_startstop_t startstop;
552 if (ide_wait_stat(&startstop, drive, DATA_READY,
553 drive->bad_wstat, WAIT_DRQ)) {
554 printk(KERN_ERR "%s: no DRQ after issuing MULTWRITE%s\n",
555 drive->name, drive->addressing ? "_EXT" : "");
562 ide_set_handler(drive, &task_mulout_intr, WAIT_WORSTCASE, NULL);
563 task_multi_sectors(drive, rq, IDE_PIO_OUT);
567 EXPORT_SYMBOL(pre_task_mulout_intr);
569 int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf)
573 memset(&rq, 0, sizeof(rq));
574 rq.flags = REQ_DRIVE_TASKFILE;
578 * (ks) We transfer currently only whole sectors.
579 * This is suffient for now. But, it would be great,
580 * if we would find a solution to transfer any size.
581 * To support special commands like READ LONG.
583 if (args->command_type != IDE_DRIVE_TASK_NO_DATA) {
585 rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET];
587 rq.nr_sectors = data_size / SECTOR_SIZE;
589 if (!rq.nr_sectors) {
590 printk(KERN_ERR "%s: in/out command without data\n",
595 rq.hard_nr_sectors = rq.nr_sectors;
596 rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors;
600 return ide_do_drive_cmd(drive, &rq, ide_wait);
603 EXPORT_SYMBOL(ide_diag_taskfile);
605 int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf)
607 return ide_diag_taskfile(drive, args, 0, buf);
610 EXPORT_SYMBOL(ide_raw_taskfile);
612 #define MAX_DMA (256*SECTOR_WORDS)
614 ide_startstop_t flagged_taskfile(ide_drive_t *, ide_task_t *);
616 int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
618 ide_task_request_t *req_task;
622 task_ioreg_t *argsptr = args.tfRegister;
623 task_ioreg_t *hobsptr = args.hobRegister;
625 int tasksize = sizeof(struct ide_task_request_s);
628 u8 io_32bit = drive->io_32bit;
629 char __user *buf = (char __user *)arg;
631 // printk("IDE Taskfile ...\n");
633 req_task = kmalloc(tasksize, GFP_KERNEL);
634 if (req_task == NULL) return -ENOMEM;
635 memset(req_task, 0, tasksize);
636 if (copy_from_user(req_task, buf, tasksize)) {
641 taskout = (int) req_task->out_size;
642 taskin = (int) req_task->in_size;
645 int outtotal = tasksize;
646 outbuf = kmalloc(taskout, GFP_KERNEL);
647 if (outbuf == NULL) {
651 memset(outbuf, 0, taskout);
652 if (copy_from_user(outbuf, buf + outtotal, taskout)) {
659 int intotal = tasksize + taskout;
660 inbuf = kmalloc(taskin, GFP_KERNEL);
665 memset(inbuf, 0, taskin);
666 if (copy_from_user(inbuf, buf + intotal, taskin)) {
672 memset(&args, 0, sizeof(ide_task_t));
673 memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
674 memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE);
676 args.tf_in_flags = req_task->in_flags;
677 args.tf_out_flags = req_task->out_flags;
678 args.data_phase = req_task->data_phase;
679 args.command_type = req_task->req_cmd;
682 switch(req_task->data_phase) {
683 case TASKFILE_OUT_DMAQ:
684 case TASKFILE_OUT_DMA:
685 err = ide_diag_taskfile(drive, &args, taskout, outbuf);
687 case TASKFILE_IN_DMAQ:
688 case TASKFILE_IN_DMA:
689 err = ide_diag_taskfile(drive, &args, taskin, inbuf);
691 case TASKFILE_IN_OUT:
693 args.prehandler = &pre_task_out_intr;
694 args.handler = &task_out_intr;
695 err = ide_diag_taskfile(drive, &args, taskout, outbuf);
696 args.prehandler = NULL;
697 args.handler = &task_in_intr;
698 err = ide_diag_taskfile(drive, &args, taskin, inbuf);
704 case TASKFILE_MULTI_OUT:
705 if (!drive->mult_count) {
706 /* (hs): give up if multcount is not set */
707 printk(KERN_ERR "%s: %s Multimode Write " \
708 "multcount is not set\n",
709 drive->name, __FUNCTION__);
713 args.prehandler = &pre_task_mulout_intr;
714 args.handler = &task_mulout_intr;
715 err = ide_diag_taskfile(drive, &args, taskout, outbuf);
718 args.prehandler = &pre_task_out_intr;
719 args.handler = &task_out_intr;
720 err = ide_diag_taskfile(drive, &args, taskout, outbuf);
722 case TASKFILE_MULTI_IN:
723 if (!drive->mult_count) {
724 /* (hs): give up if multcount is not set */
725 printk(KERN_ERR "%s: %s Multimode Read failure " \
726 "multcount is not set\n",
727 drive->name, __FUNCTION__);
731 args.handler = &task_mulin_intr;
732 err = ide_diag_taskfile(drive, &args, taskin, inbuf);
735 args.handler = &task_in_intr;
736 err = ide_diag_taskfile(drive, &args, taskin, inbuf);
738 case TASKFILE_NO_DATA:
739 args.handler = &task_no_data_intr;
740 err = ide_diag_taskfile(drive, &args, 0, NULL);
747 memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE);
748 memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE);
749 req_task->in_flags = args.tf_in_flags;
750 req_task->out_flags = args.tf_out_flags;
752 if (copy_to_user(buf, req_task, tasksize)) {
757 int outtotal = tasksize;
758 if (copy_to_user(buf + outtotal, outbuf, taskout)) {
764 int intotal = tasksize + taskout;
765 if (copy_to_user(buf + intotal, inbuf, taskin)) {
777 // printk("IDE Taskfile ioctl ended. rc = %i\n", err);
779 drive->io_32bit = io_32bit;
784 EXPORT_SYMBOL(ide_taskfile_ioctl);
786 int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
793 memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors);
794 ide_init_drive_cmd(&rq);
800 return ide_do_drive_cmd(drive, &rq, ide_wait);
803 EXPORT_SYMBOL(ide_wait_cmd);
806 * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
808 int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
811 u8 args[4], *argbuf = args;
816 if (NULL == (void *) arg) {
818 ide_init_drive_cmd(&rq);
819 return ide_do_drive_cmd(drive, &rq, ide_wait);
822 if (copy_from_user(args, (void __user *)arg, 4))
825 memset(&tfargs, 0, sizeof(ide_task_t));
826 tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2];
827 tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3];
828 tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1];
829 tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00;
830 tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00;
831 tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00;
832 tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
835 argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
836 argbuf = kmalloc(argsize, GFP_KERNEL);
839 memcpy(argbuf, args, 4);
841 if (set_transfer(drive, &tfargs)) {
843 if (ide_ata66_check(drive, &tfargs))
847 err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
849 if (!err && xfer_rate) {
850 /* active-retuning-calls future */
851 ide_set_xfer_rate(drive, xfer_rate);
852 ide_driveid_update(drive);
855 if (copy_to_user((void __user *)arg, argbuf, argsize))
862 EXPORT_SYMBOL(ide_cmd_ioctl);
864 int ide_wait_cmd_task (ide_drive_t *drive, u8 *buf)
868 ide_init_drive_cmd(&rq);
869 rq.flags = REQ_DRIVE_TASK;
871 return ide_do_drive_cmd(drive, &rq, ide_wait);
874 EXPORT_SYMBOL(ide_wait_cmd_task);
877 * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
879 int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
881 void __user *p = (void __user *)arg;
883 u8 args[7], *argbuf = args;
886 if (copy_from_user(args, p, 7))
888 err = ide_wait_cmd_task(drive, argbuf);
889 if (copy_to_user(p, argbuf, argsize))
894 EXPORT_SYMBOL(ide_task_ioctl);
897 * NOTICE: This is additions from IBM to provide a discrete interface,
898 * for selective taskregister access operations. Nice JOB Klaus!!!
899 * Glad to be able to work and co-develop this with you and IBM.
901 ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
903 ide_hwif_t *hwif = HWIF(drive);
904 task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
905 hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
911 #ifdef CONFIG_IDE_TASK_IOCTL_DEBUG
912 void debug_taskfile(drive, task);
913 #endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
915 if (task->data_phase == TASKFILE_MULTI_IN ||
916 task->data_phase == TASKFILE_MULTI_OUT) {
917 if (!drive->mult_count) {
918 printk(KERN_ERR "%s: multimode not set!\n", drive->name);
924 * (ks) Check taskfile in/out flags.
925 * If set, then execute as it is defined.
926 * If not set, then define default settings.
927 * The default values are:
928 * write and read all taskfile registers (except data)
929 * write and read the hob registers (sector,nsector,lcyl,hcyl)
931 if (task->tf_out_flags.all == 0) {
932 task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
933 if (drive->addressing == 1)
934 task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
937 if (task->tf_in_flags.all == 0) {
938 task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
939 if (drive->addressing == 1)
940 task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8);
943 /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
946 hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
947 SELECT_MASK(drive, 0);
950 status = hwif->INB(IDE_STATUS_REG);
952 printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status);
954 status = hwif->INB(IDE_STATUS_REG);
955 printk("flagged_taskfile -> Status = %02x\n", status);
959 if (task->tf_out_flags.b.data) {
960 u16 data = taskfile->data + (hobfile->data << 8);
961 hwif->OUTW(data, IDE_DATA_REG);
964 /* (ks) send hob registers first */
965 if (task->tf_out_flags.b.nsector_hob)
966 hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG);
967 if (task->tf_out_flags.b.sector_hob)
968 hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG);
969 if (task->tf_out_flags.b.lcyl_hob)
970 hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG);
971 if (task->tf_out_flags.b.hcyl_hob)
972 hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG);
974 /* (ks) Send now the standard registers */
975 if (task->tf_out_flags.b.error_feature)
976 hwif->OUTB(taskfile->feature, IDE_FEATURE_REG);
977 /* refers to number of sectors to transfer */
978 if (task->tf_out_flags.b.nsector)
979 hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);
980 /* refers to sector offset or start sector */
981 if (task->tf_out_flags.b.sector)
982 hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG);
983 if (task->tf_out_flags.b.lcyl)
984 hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);
985 if (task->tf_out_flags.b.hcyl)
986 hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);
989 * (ks) In the flagged taskfile approch, we will used all specified
990 * registers and the register value will not be changed. Except the
991 * select bit (master/slave) in the drive_head register. We must make
992 * sure that the desired drive is selected.
994 hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG);
995 switch(task->data_phase) {
997 case TASKFILE_OUT_DMAQ:
998 case TASKFILE_OUT_DMA:
999 hwif->ide_dma_write(drive);
1002 case TASKFILE_IN_DMAQ:
1003 case TASKFILE_IN_DMA:
1004 hwif->ide_dma_read(drive);
1008 if (task->handler == NULL)
1011 /* Issue the command */
1012 if (task->prehandler) {
1013 hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG);
1014 ndelay(400); /* FIXME */
1015 return task->prehandler(drive, task->rq);
1017 ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL);
1023 EXPORT_SYMBOL(flagged_taskfile);