Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/ide/ide-taskfile.c (Version 2.6.25) and /linux/drivers/ide/ide-taskfile.c (Version 2.6.11.8)


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