Commit e07bc7096424b977e53a16d72ec02645389107ba
1 parent
c0bc113373
Exists in
master
and in
4 other branches
[PATCH] ide: remove dead code from flagged_taskfile()
flagged_taskfile() is called from execute_drive_cmd() (the only user) only if args->tf_out_flags.all != 0. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Showing 2 changed files with 7 additions and 11 deletions Inline Diff
drivers/ide/ide-taskfile.c
1 | /* | 1 | /* |
2 | * linux/drivers/ide/ide-taskfile.c Version 0.38 March 05, 2003 | 2 | * linux/drivers/ide/ide-taskfile.c Version 0.38 March 05, 2003 |
3 | * | 3 | * |
4 | * Copyright (C) 2000-2002 Michael Cornwell <cornwell@acm.org> | 4 | * Copyright (C) 2000-2002 Michael Cornwell <cornwell@acm.org> |
5 | * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> | 5 | * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> |
6 | * Copyright (C) 2001-2002 Klaus Smolin | 6 | * Copyright (C) 2001-2002 Klaus Smolin |
7 | * IBM Storage Technology Division | 7 | * IBM Storage Technology Division |
8 | * Copyright (C) 2003-2004 Bartlomiej Zolnierkiewicz | 8 | * Copyright (C) 2003-2004 Bartlomiej Zolnierkiewicz |
9 | * | 9 | * |
10 | * The big the bad and the ugly. | 10 | * The big the bad and the ugly. |
11 | * | 11 | * |
12 | * Problems to be fixed because of BH interface or the lack therefore. | 12 | * Problems to be fixed because of BH interface or the lack therefore. |
13 | * | 13 | * |
14 | * Fill me in stupid !!! | 14 | * Fill me in stupid !!! |
15 | * | 15 | * |
16 | * HOST: | 16 | * HOST: |
17 | * General refers to the Controller and Driver "pair". | 17 | * General refers to the Controller and Driver "pair". |
18 | * DATA HANDLER: | 18 | * DATA HANDLER: |
19 | * Under the context of Linux it generally refers to an interrupt handler. | 19 | * Under the context of Linux it generally refers to an interrupt handler. |
20 | * However, it correctly describes the 'HOST' | 20 | * However, it correctly describes the 'HOST' |
21 | * DATA BLOCK: | 21 | * DATA BLOCK: |
22 | * The amount of data needed to be transfered as predefined in the | 22 | * The amount of data needed to be transfered as predefined in the |
23 | * setup of the device. | 23 | * setup of the device. |
24 | * STORAGE ATOMIC: | 24 | * STORAGE ATOMIC: |
25 | * The 'DATA BLOCK' associated to the 'DATA HANDLER', and can be as | 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 | 26 | * small as a single sector or as large as the entire command block |
27 | * request. | 27 | * request. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/config.h> | 30 | #include <linux/config.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/major.h> | 38 | #include <linux/major.h> |
39 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
40 | #include <linux/genhd.h> | 40 | #include <linux/genhd.h> |
41 | #include <linux/blkpg.h> | 41 | #include <linux/blkpg.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/pci.h> | 43 | #include <linux/pci.h> |
44 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
45 | #include <linux/hdreg.h> | 45 | #include <linux/hdreg.h> |
46 | #include <linux/ide.h> | 46 | #include <linux/ide.h> |
47 | #include <linux/bitops.h> | 47 | #include <linux/bitops.h> |
48 | 48 | ||
49 | #include <asm/byteorder.h> | 49 | #include <asm/byteorder.h> |
50 | #include <asm/irq.h> | 50 | #include <asm/irq.h> |
51 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
52 | #include <asm/io.h> | 52 | #include <asm/io.h> |
53 | 53 | ||
54 | static void ata_bswap_data (void *buffer, int wcount) | 54 | static void ata_bswap_data (void *buffer, int wcount) |
55 | { | 55 | { |
56 | u16 *p = buffer; | 56 | u16 *p = buffer; |
57 | 57 | ||
58 | while (wcount--) { | 58 | while (wcount--) { |
59 | *p = *p << 8 | *p >> 8; p++; | 59 | *p = *p << 8 | *p >> 8; p++; |
60 | *p = *p << 8 | *p >> 8; p++; | 60 | *p = *p << 8 | *p >> 8; p++; |
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | static void taskfile_input_data(ide_drive_t *drive, void *buffer, u32 wcount) | 64 | static void taskfile_input_data(ide_drive_t *drive, void *buffer, u32 wcount) |
65 | { | 65 | { |
66 | HWIF(drive)->ata_input_data(drive, buffer, wcount); | 66 | HWIF(drive)->ata_input_data(drive, buffer, wcount); |
67 | if (drive->bswap) | 67 | if (drive->bswap) |
68 | ata_bswap_data(buffer, wcount); | 68 | ata_bswap_data(buffer, wcount); |
69 | } | 69 | } |
70 | 70 | ||
71 | static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount) | 71 | static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount) |
72 | { | 72 | { |
73 | if (drive->bswap) { | 73 | if (drive->bswap) { |
74 | ata_bswap_data(buffer, wcount); | 74 | ata_bswap_data(buffer, wcount); |
75 | HWIF(drive)->ata_output_data(drive, buffer, wcount); | 75 | HWIF(drive)->ata_output_data(drive, buffer, wcount); |
76 | ata_bswap_data(buffer, wcount); | 76 | ata_bswap_data(buffer, wcount); |
77 | } else { | 77 | } else { |
78 | HWIF(drive)->ata_output_data(drive, buffer, wcount); | 78 | HWIF(drive)->ata_output_data(drive, buffer, wcount); |
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | 82 | int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) |
83 | { | 83 | { |
84 | ide_task_t args; | 84 | ide_task_t args; |
85 | memset(&args, 0, sizeof(ide_task_t)); | 85 | memset(&args, 0, sizeof(ide_task_t)); |
86 | args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01; | 86 | args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01; |
87 | if (drive->media == ide_disk) | 87 | if (drive->media == ide_disk) |
88 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_IDENTIFY; | 88 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_IDENTIFY; |
89 | else | 89 | else |
90 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_PIDENTIFY; | 90 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_PIDENTIFY; |
91 | args.command_type = IDE_DRIVE_TASK_IN; | 91 | args.command_type = IDE_DRIVE_TASK_IN; |
92 | args.data_phase = TASKFILE_IN; | 92 | args.data_phase = TASKFILE_IN; |
93 | args.handler = &task_in_intr; | 93 | args.handler = &task_in_intr; |
94 | return ide_raw_taskfile(drive, &args, buf); | 94 | return ide_raw_taskfile(drive, &args, buf); |
95 | } | 95 | } |
96 | 96 | ||
97 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | 97 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) |
98 | { | 98 | { |
99 | ide_hwif_t *hwif = HWIF(drive); | 99 | ide_hwif_t *hwif = HWIF(drive); |
100 | task_struct_t *taskfile = (task_struct_t *) task->tfRegister; | 100 | task_struct_t *taskfile = (task_struct_t *) task->tfRegister; |
101 | hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; | 101 | hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; |
102 | u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF; | 102 | u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF; |
103 | 103 | ||
104 | /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ | 104 | /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ |
105 | if (IDE_CONTROL_REG) { | 105 | if (IDE_CONTROL_REG) { |
106 | /* clear nIEN */ | 106 | /* clear nIEN */ |
107 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | 107 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); |
108 | } | 108 | } |
109 | SELECT_MASK(drive, 0); | 109 | SELECT_MASK(drive, 0); |
110 | 110 | ||
111 | if (drive->addressing == 1) { | 111 | if (drive->addressing == 1) { |
112 | hwif->OUTB(hobfile->feature, IDE_FEATURE_REG); | 112 | hwif->OUTB(hobfile->feature, IDE_FEATURE_REG); |
113 | hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); | 113 | hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); |
114 | hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); | 114 | hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); |
115 | hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); | 115 | hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); |
116 | hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); | 116 | hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); |
117 | } | 117 | } |
118 | 118 | ||
119 | hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); | 119 | hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); |
120 | hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); | 120 | hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); |
121 | hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); | 121 | hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); |
122 | hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); | 122 | hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); |
123 | hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); | 123 | hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); |
124 | 124 | ||
125 | hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); | 125 | hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); |
126 | 126 | ||
127 | if (task->handler != NULL) { | 127 | if (task->handler != NULL) { |
128 | if (task->prehandler != NULL) { | 128 | if (task->prehandler != NULL) { |
129 | hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); | 129 | hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); |
130 | ndelay(400); /* FIXME */ | 130 | ndelay(400); /* FIXME */ |
131 | return task->prehandler(drive, task->rq); | 131 | return task->prehandler(drive, task->rq); |
132 | } | 132 | } |
133 | ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); | 133 | ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); |
134 | return ide_started; | 134 | return ide_started; |
135 | } | 135 | } |
136 | 136 | ||
137 | if (!drive->using_dma) | 137 | if (!drive->using_dma) |
138 | return ide_stopped; | 138 | return ide_stopped; |
139 | 139 | ||
140 | switch (taskfile->command) { | 140 | switch (taskfile->command) { |
141 | case WIN_WRITEDMA_ONCE: | 141 | case WIN_WRITEDMA_ONCE: |
142 | case WIN_WRITEDMA: | 142 | case WIN_WRITEDMA: |
143 | case WIN_WRITEDMA_EXT: | 143 | case WIN_WRITEDMA_EXT: |
144 | case WIN_READDMA_ONCE: | 144 | case WIN_READDMA_ONCE: |
145 | case WIN_READDMA: | 145 | case WIN_READDMA: |
146 | case WIN_READDMA_EXT: | 146 | case WIN_READDMA_EXT: |
147 | case WIN_IDENTIFY_DMA: | 147 | case WIN_IDENTIFY_DMA: |
148 | if (!hwif->dma_setup(drive)) { | 148 | if (!hwif->dma_setup(drive)) { |
149 | hwif->dma_exec_cmd(drive, taskfile->command); | 149 | hwif->dma_exec_cmd(drive, taskfile->command); |
150 | hwif->dma_start(drive); | 150 | hwif->dma_start(drive); |
151 | return ide_started; | 151 | return ide_started; |
152 | } | 152 | } |
153 | break; | 153 | break; |
154 | default: | 154 | default: |
155 | if (task->handler == NULL) | 155 | if (task->handler == NULL) |
156 | return ide_stopped; | 156 | return ide_stopped; |
157 | } | 157 | } |
158 | 158 | ||
159 | return ide_stopped; | 159 | return ide_stopped; |
160 | } | 160 | } |
161 | 161 | ||
162 | /* | 162 | /* |
163 | * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. | 163 | * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. |
164 | */ | 164 | */ |
165 | ide_startstop_t set_multmode_intr (ide_drive_t *drive) | 165 | ide_startstop_t set_multmode_intr (ide_drive_t *drive) |
166 | { | 166 | { |
167 | ide_hwif_t *hwif = HWIF(drive); | 167 | ide_hwif_t *hwif = HWIF(drive); |
168 | u8 stat; | 168 | u8 stat; |
169 | 169 | ||
170 | if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { | 170 | if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { |
171 | drive->mult_count = drive->mult_req; | 171 | drive->mult_count = drive->mult_req; |
172 | } else { | 172 | } else { |
173 | drive->mult_req = drive->mult_count = 0; | 173 | drive->mult_req = drive->mult_count = 0; |
174 | drive->special.b.recalibrate = 1; | 174 | drive->special.b.recalibrate = 1; |
175 | (void) ide_dump_status(drive, "set_multmode", stat); | 175 | (void) ide_dump_status(drive, "set_multmode", stat); |
176 | } | 176 | } |
177 | return ide_stopped; | 177 | return ide_stopped; |
178 | } | 178 | } |
179 | 179 | ||
180 | /* | 180 | /* |
181 | * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd. | 181 | * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd. |
182 | */ | 182 | */ |
183 | ide_startstop_t set_geometry_intr (ide_drive_t *drive) | 183 | ide_startstop_t set_geometry_intr (ide_drive_t *drive) |
184 | { | 184 | { |
185 | ide_hwif_t *hwif = HWIF(drive); | 185 | ide_hwif_t *hwif = HWIF(drive); |
186 | int retries = 5; | 186 | int retries = 5; |
187 | u8 stat; | 187 | u8 stat; |
188 | 188 | ||
189 | while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--) | 189 | while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--) |
190 | udelay(10); | 190 | udelay(10); |
191 | 191 | ||
192 | if (OK_STAT(stat, READY_STAT, BAD_STAT)) | 192 | if (OK_STAT(stat, READY_STAT, BAD_STAT)) |
193 | return ide_stopped; | 193 | return ide_stopped; |
194 | 194 | ||
195 | if (stat & (ERR_STAT|DRQ_STAT)) | 195 | if (stat & (ERR_STAT|DRQ_STAT)) |
196 | return ide_error(drive, "set_geometry_intr", stat); | 196 | return ide_error(drive, "set_geometry_intr", stat); |
197 | 197 | ||
198 | if (HWGROUP(drive)->handler != NULL) | 198 | if (HWGROUP(drive)->handler != NULL) |
199 | BUG(); | 199 | BUG(); |
200 | ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL); | 200 | ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL); |
201 | return ide_started; | 201 | return ide_started; |
202 | } | 202 | } |
203 | 203 | ||
204 | /* | 204 | /* |
205 | * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd. | 205 | * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd. |
206 | */ | 206 | */ |
207 | ide_startstop_t recal_intr (ide_drive_t *drive) | 207 | ide_startstop_t recal_intr (ide_drive_t *drive) |
208 | { | 208 | { |
209 | ide_hwif_t *hwif = HWIF(drive); | 209 | ide_hwif_t *hwif = HWIF(drive); |
210 | u8 stat; | 210 | u8 stat; |
211 | 211 | ||
212 | if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), READY_STAT, BAD_STAT)) | 212 | if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), READY_STAT, BAD_STAT)) |
213 | return ide_error(drive, "recal_intr", stat); | 213 | return ide_error(drive, "recal_intr", stat); |
214 | return ide_stopped; | 214 | return ide_stopped; |
215 | } | 215 | } |
216 | 216 | ||
217 | /* | 217 | /* |
218 | * Handler for commands without a data phase | 218 | * Handler for commands without a data phase |
219 | */ | 219 | */ |
220 | ide_startstop_t task_no_data_intr (ide_drive_t *drive) | 220 | ide_startstop_t task_no_data_intr (ide_drive_t *drive) |
221 | { | 221 | { |
222 | ide_task_t *args = HWGROUP(drive)->rq->special; | 222 | ide_task_t *args = HWGROUP(drive)->rq->special; |
223 | ide_hwif_t *hwif = HWIF(drive); | 223 | ide_hwif_t *hwif = HWIF(drive); |
224 | u8 stat; | 224 | u8 stat; |
225 | 225 | ||
226 | local_irq_enable(); | 226 | local_irq_enable(); |
227 | if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { | 227 | if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { |
228 | return ide_error(drive, "task_no_data_intr", stat); | 228 | return ide_error(drive, "task_no_data_intr", stat); |
229 | /* calls ide_end_drive_cmd */ | 229 | /* calls ide_end_drive_cmd */ |
230 | } | 230 | } |
231 | if (args) | 231 | if (args) |
232 | ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG)); | 232 | ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG)); |
233 | 233 | ||
234 | return ide_stopped; | 234 | return ide_stopped; |
235 | } | 235 | } |
236 | 236 | ||
237 | EXPORT_SYMBOL(task_no_data_intr); | 237 | EXPORT_SYMBOL(task_no_data_intr); |
238 | 238 | ||
239 | static u8 wait_drive_not_busy(ide_drive_t *drive) | 239 | static u8 wait_drive_not_busy(ide_drive_t *drive) |
240 | { | 240 | { |
241 | ide_hwif_t *hwif = HWIF(drive); | 241 | ide_hwif_t *hwif = HWIF(drive); |
242 | int retries = 100; | 242 | int retries = 100; |
243 | u8 stat; | 243 | u8 stat; |
244 | 244 | ||
245 | /* | 245 | /* |
246 | * Last sector was transfered, wait until drive is ready. | 246 | * Last sector was transfered, wait until drive is ready. |
247 | * This can take up to 10 usec, but we will wait max 1 ms | 247 | * This can take up to 10 usec, but we will wait max 1 ms |
248 | * (drive_cmd_intr() waits that long). | 248 | * (drive_cmd_intr() waits that long). |
249 | */ | 249 | */ |
250 | while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--) | 250 | while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--) |
251 | udelay(10); | 251 | udelay(10); |
252 | 252 | ||
253 | if (!retries) | 253 | if (!retries) |
254 | printk(KERN_ERR "%s: drive still BUSY!\n", drive->name); | 254 | printk(KERN_ERR "%s: drive still BUSY!\n", drive->name); |
255 | 255 | ||
256 | return stat; | 256 | return stat; |
257 | } | 257 | } |
258 | 258 | ||
259 | static void ide_pio_sector(ide_drive_t *drive, unsigned int write) | 259 | static void ide_pio_sector(ide_drive_t *drive, unsigned int write) |
260 | { | 260 | { |
261 | ide_hwif_t *hwif = drive->hwif; | 261 | ide_hwif_t *hwif = drive->hwif; |
262 | struct scatterlist *sg = hwif->sg_table; | 262 | struct scatterlist *sg = hwif->sg_table; |
263 | struct page *page; | 263 | struct page *page; |
264 | #ifdef CONFIG_HIGHMEM | 264 | #ifdef CONFIG_HIGHMEM |
265 | unsigned long flags; | 265 | unsigned long flags; |
266 | #endif | 266 | #endif |
267 | unsigned int offset; | 267 | unsigned int offset; |
268 | u8 *buf; | 268 | u8 *buf; |
269 | 269 | ||
270 | page = sg[hwif->cursg].page; | 270 | page = sg[hwif->cursg].page; |
271 | offset = sg[hwif->cursg].offset + hwif->cursg_ofs * SECTOR_SIZE; | 271 | offset = sg[hwif->cursg].offset + hwif->cursg_ofs * SECTOR_SIZE; |
272 | 272 | ||
273 | /* get the current page and offset */ | 273 | /* get the current page and offset */ |
274 | page = nth_page(page, (offset >> PAGE_SHIFT)); | 274 | page = nth_page(page, (offset >> PAGE_SHIFT)); |
275 | offset %= PAGE_SIZE; | 275 | offset %= PAGE_SIZE; |
276 | 276 | ||
277 | #ifdef CONFIG_HIGHMEM | 277 | #ifdef CONFIG_HIGHMEM |
278 | local_irq_save(flags); | 278 | local_irq_save(flags); |
279 | #endif | 279 | #endif |
280 | buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; | 280 | buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; |
281 | 281 | ||
282 | hwif->nleft--; | 282 | hwif->nleft--; |
283 | hwif->cursg_ofs++; | 283 | hwif->cursg_ofs++; |
284 | 284 | ||
285 | if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) { | 285 | if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) { |
286 | hwif->cursg++; | 286 | hwif->cursg++; |
287 | hwif->cursg_ofs = 0; | 287 | hwif->cursg_ofs = 0; |
288 | } | 288 | } |
289 | 289 | ||
290 | /* do the actual data transfer */ | 290 | /* do the actual data transfer */ |
291 | if (write) | 291 | if (write) |
292 | taskfile_output_data(drive, buf, SECTOR_WORDS); | 292 | taskfile_output_data(drive, buf, SECTOR_WORDS); |
293 | else | 293 | else |
294 | taskfile_input_data(drive, buf, SECTOR_WORDS); | 294 | taskfile_input_data(drive, buf, SECTOR_WORDS); |
295 | 295 | ||
296 | kunmap_atomic(buf, KM_BIO_SRC_IRQ); | 296 | kunmap_atomic(buf, KM_BIO_SRC_IRQ); |
297 | #ifdef CONFIG_HIGHMEM | 297 | #ifdef CONFIG_HIGHMEM |
298 | local_irq_restore(flags); | 298 | local_irq_restore(flags); |
299 | #endif | 299 | #endif |
300 | } | 300 | } |
301 | 301 | ||
302 | static void ide_pio_multi(ide_drive_t *drive, unsigned int write) | 302 | static void ide_pio_multi(ide_drive_t *drive, unsigned int write) |
303 | { | 303 | { |
304 | unsigned int nsect; | 304 | unsigned int nsect; |
305 | 305 | ||
306 | nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count); | 306 | nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count); |
307 | while (nsect--) | 307 | while (nsect--) |
308 | ide_pio_sector(drive, write); | 308 | ide_pio_sector(drive, write); |
309 | } | 309 | } |
310 | 310 | ||
311 | static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq, | 311 | static inline void ide_pio_datablock(ide_drive_t *drive, struct request *rq, |
312 | unsigned int write) | 312 | unsigned int write) |
313 | { | 313 | { |
314 | if (rq->bio) /* fs request */ | 314 | if (rq->bio) /* fs request */ |
315 | rq->errors = 0; | 315 | rq->errors = 0; |
316 | 316 | ||
317 | switch (drive->hwif->data_phase) { | 317 | switch (drive->hwif->data_phase) { |
318 | case TASKFILE_MULTI_IN: | 318 | case TASKFILE_MULTI_IN: |
319 | case TASKFILE_MULTI_OUT: | 319 | case TASKFILE_MULTI_OUT: |
320 | ide_pio_multi(drive, write); | 320 | ide_pio_multi(drive, write); |
321 | break; | 321 | break; |
322 | default: | 322 | default: |
323 | ide_pio_sector(drive, write); | 323 | ide_pio_sector(drive, write); |
324 | break; | 324 | break; |
325 | } | 325 | } |
326 | } | 326 | } |
327 | 327 | ||
328 | static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, | 328 | static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, |
329 | const char *s, u8 stat) | 329 | const char *s, u8 stat) |
330 | { | 330 | { |
331 | if (rq->bio) { | 331 | if (rq->bio) { |
332 | ide_hwif_t *hwif = drive->hwif; | 332 | ide_hwif_t *hwif = drive->hwif; |
333 | int sectors = hwif->nsect - hwif->nleft; | 333 | int sectors = hwif->nsect - hwif->nleft; |
334 | 334 | ||
335 | switch (hwif->data_phase) { | 335 | switch (hwif->data_phase) { |
336 | case TASKFILE_IN: | 336 | case TASKFILE_IN: |
337 | if (hwif->nleft) | 337 | if (hwif->nleft) |
338 | break; | 338 | break; |
339 | /* fall through */ | 339 | /* fall through */ |
340 | case TASKFILE_OUT: | 340 | case TASKFILE_OUT: |
341 | sectors--; | 341 | sectors--; |
342 | break; | 342 | break; |
343 | case TASKFILE_MULTI_IN: | 343 | case TASKFILE_MULTI_IN: |
344 | if (hwif->nleft) | 344 | if (hwif->nleft) |
345 | break; | 345 | break; |
346 | /* fall through */ | 346 | /* fall through */ |
347 | case TASKFILE_MULTI_OUT: | 347 | case TASKFILE_MULTI_OUT: |
348 | sectors -= drive->mult_count; | 348 | sectors -= drive->mult_count; |
349 | default: | 349 | default: |
350 | break; | 350 | break; |
351 | } | 351 | } |
352 | 352 | ||
353 | if (sectors > 0) { | 353 | if (sectors > 0) { |
354 | ide_driver_t *drv; | 354 | ide_driver_t *drv; |
355 | 355 | ||
356 | drv = *(ide_driver_t **)rq->rq_disk->private_data; | 356 | drv = *(ide_driver_t **)rq->rq_disk->private_data; |
357 | drv->end_request(drive, 1, sectors); | 357 | drv->end_request(drive, 1, sectors); |
358 | } | 358 | } |
359 | } | 359 | } |
360 | return ide_error(drive, s, stat); | 360 | return ide_error(drive, s, stat); |
361 | } | 361 | } |
362 | 362 | ||
363 | static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | 363 | static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) |
364 | { | 364 | { |
365 | if (rq->flags & REQ_DRIVE_TASKFILE) { | 365 | if (rq->flags & REQ_DRIVE_TASKFILE) { |
366 | ide_task_t *task = rq->special; | 366 | ide_task_t *task = rq->special; |
367 | 367 | ||
368 | if (task->tf_out_flags.all) { | 368 | if (task->tf_out_flags.all) { |
369 | u8 err = drive->hwif->INB(IDE_ERROR_REG); | 369 | u8 err = drive->hwif->INB(IDE_ERROR_REG); |
370 | ide_end_drive_cmd(drive, stat, err); | 370 | ide_end_drive_cmd(drive, stat, err); |
371 | return; | 371 | return; |
372 | } | 372 | } |
373 | } | 373 | } |
374 | 374 | ||
375 | ide_end_request(drive, 1, rq->hard_nr_sectors); | 375 | ide_end_request(drive, 1, rq->hard_nr_sectors); |
376 | } | 376 | } |
377 | 377 | ||
378 | /* | 378 | /* |
379 | * Handler for command with PIO data-in phase (Read/Read Multiple). | 379 | * Handler for command with PIO data-in phase (Read/Read Multiple). |
380 | */ | 380 | */ |
381 | ide_startstop_t task_in_intr (ide_drive_t *drive) | 381 | ide_startstop_t task_in_intr (ide_drive_t *drive) |
382 | { | 382 | { |
383 | ide_hwif_t *hwif = drive->hwif; | 383 | ide_hwif_t *hwif = drive->hwif; |
384 | struct request *rq = HWGROUP(drive)->rq; | 384 | struct request *rq = HWGROUP(drive)->rq; |
385 | u8 stat = hwif->INB(IDE_STATUS_REG); | 385 | u8 stat = hwif->INB(IDE_STATUS_REG); |
386 | 386 | ||
387 | /* new way for dealing with premature shared PCI interrupts */ | 387 | /* new way for dealing with premature shared PCI interrupts */ |
388 | if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { | 388 | if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { |
389 | if (stat & (ERR_STAT | DRQ_STAT)) | 389 | if (stat & (ERR_STAT | DRQ_STAT)) |
390 | return task_error(drive, rq, __FUNCTION__, stat); | 390 | return task_error(drive, rq, __FUNCTION__, stat); |
391 | /* No data yet, so wait for another IRQ. */ | 391 | /* No data yet, so wait for another IRQ. */ |
392 | ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); | 392 | ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); |
393 | return ide_started; | 393 | return ide_started; |
394 | } | 394 | } |
395 | 395 | ||
396 | ide_pio_datablock(drive, rq, 0); | 396 | ide_pio_datablock(drive, rq, 0); |
397 | 397 | ||
398 | /* If it was the last datablock check status and finish transfer. */ | 398 | /* If it was the last datablock check status and finish transfer. */ |
399 | if (!hwif->nleft) { | 399 | if (!hwif->nleft) { |
400 | stat = wait_drive_not_busy(drive); | 400 | stat = wait_drive_not_busy(drive); |
401 | if (!OK_STAT(stat, 0, BAD_R_STAT)) | 401 | if (!OK_STAT(stat, 0, BAD_R_STAT)) |
402 | return task_error(drive, rq, __FUNCTION__, stat); | 402 | return task_error(drive, rq, __FUNCTION__, stat); |
403 | task_end_request(drive, rq, stat); | 403 | task_end_request(drive, rq, stat); |
404 | return ide_stopped; | 404 | return ide_stopped; |
405 | } | 405 | } |
406 | 406 | ||
407 | /* Still data left to transfer. */ | 407 | /* Still data left to transfer. */ |
408 | ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); | 408 | ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL); |
409 | 409 | ||
410 | return ide_started; | 410 | return ide_started; |
411 | } | 411 | } |
412 | EXPORT_SYMBOL(task_in_intr); | 412 | EXPORT_SYMBOL(task_in_intr); |
413 | 413 | ||
414 | /* | 414 | /* |
415 | * Handler for command with PIO data-out phase (Write/Write Multiple). | 415 | * Handler for command with PIO data-out phase (Write/Write Multiple). |
416 | */ | 416 | */ |
417 | static ide_startstop_t task_out_intr (ide_drive_t *drive) | 417 | static ide_startstop_t task_out_intr (ide_drive_t *drive) |
418 | { | 418 | { |
419 | ide_hwif_t *hwif = drive->hwif; | 419 | ide_hwif_t *hwif = drive->hwif; |
420 | struct request *rq = HWGROUP(drive)->rq; | 420 | struct request *rq = HWGROUP(drive)->rq; |
421 | u8 stat = hwif->INB(IDE_STATUS_REG); | 421 | u8 stat = hwif->INB(IDE_STATUS_REG); |
422 | 422 | ||
423 | if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) | 423 | if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) |
424 | return task_error(drive, rq, __FUNCTION__, stat); | 424 | return task_error(drive, rq, __FUNCTION__, stat); |
425 | 425 | ||
426 | /* Deal with unexpected ATA data phase. */ | 426 | /* Deal with unexpected ATA data phase. */ |
427 | if (((stat & DRQ_STAT) == 0) ^ !hwif->nleft) | 427 | if (((stat & DRQ_STAT) == 0) ^ !hwif->nleft) |
428 | return task_error(drive, rq, __FUNCTION__, stat); | 428 | return task_error(drive, rq, __FUNCTION__, stat); |
429 | 429 | ||
430 | if (!hwif->nleft) { | 430 | if (!hwif->nleft) { |
431 | task_end_request(drive, rq, stat); | 431 | task_end_request(drive, rq, stat); |
432 | return ide_stopped; | 432 | return ide_stopped; |
433 | } | 433 | } |
434 | 434 | ||
435 | /* Still data left to transfer. */ | 435 | /* Still data left to transfer. */ |
436 | ide_pio_datablock(drive, rq, 1); | 436 | ide_pio_datablock(drive, rq, 1); |
437 | ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); | 437 | ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); |
438 | 438 | ||
439 | return ide_started; | 439 | return ide_started; |
440 | } | 440 | } |
441 | 441 | ||
442 | ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) | 442 | ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) |
443 | { | 443 | { |
444 | ide_startstop_t startstop; | 444 | ide_startstop_t startstop; |
445 | 445 | ||
446 | if (ide_wait_stat(&startstop, drive, DATA_READY, | 446 | if (ide_wait_stat(&startstop, drive, DATA_READY, |
447 | drive->bad_wstat, WAIT_DRQ)) { | 447 | drive->bad_wstat, WAIT_DRQ)) { |
448 | printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", | 448 | printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", |
449 | drive->name, | 449 | drive->name, |
450 | drive->hwif->data_phase ? "MULT" : "", | 450 | drive->hwif->data_phase ? "MULT" : "", |
451 | drive->addressing ? "_EXT" : ""); | 451 | drive->addressing ? "_EXT" : ""); |
452 | return startstop; | 452 | return startstop; |
453 | } | 453 | } |
454 | 454 | ||
455 | if (!drive->unmask) | 455 | if (!drive->unmask) |
456 | local_irq_disable(); | 456 | local_irq_disable(); |
457 | 457 | ||
458 | ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); | 458 | ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL); |
459 | ide_pio_datablock(drive, rq, 1); | 459 | ide_pio_datablock(drive, rq, 1); |
460 | 460 | ||
461 | return ide_started; | 461 | return ide_started; |
462 | } | 462 | } |
463 | EXPORT_SYMBOL(pre_task_out_intr); | 463 | EXPORT_SYMBOL(pre_task_out_intr); |
464 | 464 | ||
465 | static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf) | 465 | static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf) |
466 | { | 466 | { |
467 | struct request rq; | 467 | struct request rq; |
468 | 468 | ||
469 | memset(&rq, 0, sizeof(rq)); | 469 | memset(&rq, 0, sizeof(rq)); |
470 | rq.flags = REQ_DRIVE_TASKFILE; | 470 | rq.flags = REQ_DRIVE_TASKFILE; |
471 | rq.buffer = buf; | 471 | rq.buffer = buf; |
472 | 472 | ||
473 | /* | 473 | /* |
474 | * (ks) We transfer currently only whole sectors. | 474 | * (ks) We transfer currently only whole sectors. |
475 | * This is suffient for now. But, it would be great, | 475 | * This is suffient for now. But, it would be great, |
476 | * if we would find a solution to transfer any size. | 476 | * if we would find a solution to transfer any size. |
477 | * To support special commands like READ LONG. | 477 | * To support special commands like READ LONG. |
478 | */ | 478 | */ |
479 | if (args->command_type != IDE_DRIVE_TASK_NO_DATA) { | 479 | if (args->command_type != IDE_DRIVE_TASK_NO_DATA) { |
480 | if (data_size == 0) | 480 | if (data_size == 0) |
481 | rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET]; | 481 | rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET]; |
482 | else | 482 | else |
483 | rq.nr_sectors = data_size / SECTOR_SIZE; | 483 | rq.nr_sectors = data_size / SECTOR_SIZE; |
484 | 484 | ||
485 | if (!rq.nr_sectors) { | 485 | if (!rq.nr_sectors) { |
486 | printk(KERN_ERR "%s: in/out command without data\n", | 486 | printk(KERN_ERR "%s: in/out command without data\n", |
487 | drive->name); | 487 | drive->name); |
488 | return -EFAULT; | 488 | return -EFAULT; |
489 | } | 489 | } |
490 | 490 | ||
491 | rq.hard_nr_sectors = rq.nr_sectors; | 491 | rq.hard_nr_sectors = rq.nr_sectors; |
492 | rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors; | 492 | rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors; |
493 | 493 | ||
494 | if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) | 494 | if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) |
495 | rq.flags |= REQ_RW; | 495 | rq.flags |= REQ_RW; |
496 | } | 496 | } |
497 | 497 | ||
498 | rq.special = args; | 498 | rq.special = args; |
499 | args->rq = &rq; | 499 | args->rq = &rq; |
500 | return ide_do_drive_cmd(drive, &rq, ide_wait); | 500 | return ide_do_drive_cmd(drive, &rq, ide_wait); |
501 | } | 501 | } |
502 | 502 | ||
503 | int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf) | 503 | int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf) |
504 | { | 504 | { |
505 | return ide_diag_taskfile(drive, args, 0, buf); | 505 | return ide_diag_taskfile(drive, args, 0, buf); |
506 | } | 506 | } |
507 | 507 | ||
508 | EXPORT_SYMBOL(ide_raw_taskfile); | 508 | EXPORT_SYMBOL(ide_raw_taskfile); |
509 | 509 | ||
510 | int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | 510 | int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) |
511 | { | 511 | { |
512 | ide_task_request_t *req_task; | 512 | ide_task_request_t *req_task; |
513 | ide_task_t args; | 513 | ide_task_t args; |
514 | u8 *outbuf = NULL; | 514 | u8 *outbuf = NULL; |
515 | u8 *inbuf = NULL; | 515 | u8 *inbuf = NULL; |
516 | task_ioreg_t *argsptr = args.tfRegister; | 516 | task_ioreg_t *argsptr = args.tfRegister; |
517 | task_ioreg_t *hobsptr = args.hobRegister; | 517 | task_ioreg_t *hobsptr = args.hobRegister; |
518 | int err = 0; | 518 | int err = 0; |
519 | int tasksize = sizeof(struct ide_task_request_s); | 519 | int tasksize = sizeof(struct ide_task_request_s); |
520 | int taskin = 0; | 520 | int taskin = 0; |
521 | int taskout = 0; | 521 | int taskout = 0; |
522 | u8 io_32bit = drive->io_32bit; | 522 | u8 io_32bit = drive->io_32bit; |
523 | char __user *buf = (char __user *)arg; | 523 | char __user *buf = (char __user *)arg; |
524 | 524 | ||
525 | // printk("IDE Taskfile ...\n"); | 525 | // printk("IDE Taskfile ...\n"); |
526 | 526 | ||
527 | req_task = kzalloc(tasksize, GFP_KERNEL); | 527 | req_task = kzalloc(tasksize, GFP_KERNEL); |
528 | if (req_task == NULL) return -ENOMEM; | 528 | if (req_task == NULL) return -ENOMEM; |
529 | if (copy_from_user(req_task, buf, tasksize)) { | 529 | if (copy_from_user(req_task, buf, tasksize)) { |
530 | kfree(req_task); | 530 | kfree(req_task); |
531 | return -EFAULT; | 531 | return -EFAULT; |
532 | } | 532 | } |
533 | 533 | ||
534 | taskout = (int) req_task->out_size; | 534 | taskout = (int) req_task->out_size; |
535 | taskin = (int) req_task->in_size; | 535 | taskin = (int) req_task->in_size; |
536 | 536 | ||
537 | if (taskout) { | 537 | if (taskout) { |
538 | int outtotal = tasksize; | 538 | int outtotal = tasksize; |
539 | outbuf = kzalloc(taskout, GFP_KERNEL); | 539 | outbuf = kzalloc(taskout, GFP_KERNEL); |
540 | if (outbuf == NULL) { | 540 | if (outbuf == NULL) { |
541 | err = -ENOMEM; | 541 | err = -ENOMEM; |
542 | goto abort; | 542 | goto abort; |
543 | } | 543 | } |
544 | if (copy_from_user(outbuf, buf + outtotal, taskout)) { | 544 | if (copy_from_user(outbuf, buf + outtotal, taskout)) { |
545 | err = -EFAULT; | 545 | err = -EFAULT; |
546 | goto abort; | 546 | goto abort; |
547 | } | 547 | } |
548 | } | 548 | } |
549 | 549 | ||
550 | if (taskin) { | 550 | if (taskin) { |
551 | int intotal = tasksize + taskout; | 551 | int intotal = tasksize + taskout; |
552 | inbuf = kzalloc(taskin, GFP_KERNEL); | 552 | inbuf = kzalloc(taskin, GFP_KERNEL); |
553 | if (inbuf == NULL) { | 553 | if (inbuf == NULL) { |
554 | err = -ENOMEM; | 554 | err = -ENOMEM; |
555 | goto abort; | 555 | goto abort; |
556 | } | 556 | } |
557 | if (copy_from_user(inbuf, buf + intotal, taskin)) { | 557 | if (copy_from_user(inbuf, buf + intotal, taskin)) { |
558 | err = -EFAULT; | 558 | err = -EFAULT; |
559 | goto abort; | 559 | goto abort; |
560 | } | 560 | } |
561 | } | 561 | } |
562 | 562 | ||
563 | memset(&args, 0, sizeof(ide_task_t)); | 563 | memset(&args, 0, sizeof(ide_task_t)); |
564 | memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); | 564 | memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); |
565 | memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE); | 565 | memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE); |
566 | 566 | ||
567 | args.tf_in_flags = req_task->in_flags; | 567 | args.tf_in_flags = req_task->in_flags; |
568 | args.tf_out_flags = req_task->out_flags; | 568 | args.tf_out_flags = req_task->out_flags; |
569 | args.data_phase = req_task->data_phase; | 569 | args.data_phase = req_task->data_phase; |
570 | args.command_type = req_task->req_cmd; | 570 | args.command_type = req_task->req_cmd; |
571 | 571 | ||
572 | drive->io_32bit = 0; | 572 | drive->io_32bit = 0; |
573 | switch(req_task->data_phase) { | 573 | switch(req_task->data_phase) { |
574 | case TASKFILE_OUT_DMAQ: | 574 | case TASKFILE_OUT_DMAQ: |
575 | case TASKFILE_OUT_DMA: | 575 | case TASKFILE_OUT_DMA: |
576 | err = ide_diag_taskfile(drive, &args, taskout, outbuf); | 576 | err = ide_diag_taskfile(drive, &args, taskout, outbuf); |
577 | break; | 577 | break; |
578 | case TASKFILE_IN_DMAQ: | 578 | case TASKFILE_IN_DMAQ: |
579 | case TASKFILE_IN_DMA: | 579 | case TASKFILE_IN_DMA: |
580 | err = ide_diag_taskfile(drive, &args, taskin, inbuf); | 580 | err = ide_diag_taskfile(drive, &args, taskin, inbuf); |
581 | break; | 581 | break; |
582 | case TASKFILE_MULTI_OUT: | 582 | case TASKFILE_MULTI_OUT: |
583 | if (!drive->mult_count) { | 583 | if (!drive->mult_count) { |
584 | /* (hs): give up if multcount is not set */ | 584 | /* (hs): give up if multcount is not set */ |
585 | printk(KERN_ERR "%s: %s Multimode Write " \ | 585 | printk(KERN_ERR "%s: %s Multimode Write " \ |
586 | "multcount is not set\n", | 586 | "multcount is not set\n", |
587 | drive->name, __FUNCTION__); | 587 | drive->name, __FUNCTION__); |
588 | err = -EPERM; | 588 | err = -EPERM; |
589 | goto abort; | 589 | goto abort; |
590 | } | 590 | } |
591 | /* fall through */ | 591 | /* fall through */ |
592 | case TASKFILE_OUT: | 592 | case TASKFILE_OUT: |
593 | args.prehandler = &pre_task_out_intr; | 593 | args.prehandler = &pre_task_out_intr; |
594 | args.handler = &task_out_intr; | 594 | args.handler = &task_out_intr; |
595 | err = ide_diag_taskfile(drive, &args, taskout, outbuf); | 595 | err = ide_diag_taskfile(drive, &args, taskout, outbuf); |
596 | break; | 596 | break; |
597 | case TASKFILE_MULTI_IN: | 597 | case TASKFILE_MULTI_IN: |
598 | if (!drive->mult_count) { | 598 | if (!drive->mult_count) { |
599 | /* (hs): give up if multcount is not set */ | 599 | /* (hs): give up if multcount is not set */ |
600 | printk(KERN_ERR "%s: %s Multimode Read failure " \ | 600 | printk(KERN_ERR "%s: %s Multimode Read failure " \ |
601 | "multcount is not set\n", | 601 | "multcount is not set\n", |
602 | drive->name, __FUNCTION__); | 602 | drive->name, __FUNCTION__); |
603 | err = -EPERM; | 603 | err = -EPERM; |
604 | goto abort; | 604 | goto abort; |
605 | } | 605 | } |
606 | /* fall through */ | 606 | /* fall through */ |
607 | case TASKFILE_IN: | 607 | case TASKFILE_IN: |
608 | args.handler = &task_in_intr; | 608 | args.handler = &task_in_intr; |
609 | err = ide_diag_taskfile(drive, &args, taskin, inbuf); | 609 | err = ide_diag_taskfile(drive, &args, taskin, inbuf); |
610 | break; | 610 | break; |
611 | case TASKFILE_NO_DATA: | 611 | case TASKFILE_NO_DATA: |
612 | args.handler = &task_no_data_intr; | 612 | args.handler = &task_no_data_intr; |
613 | err = ide_diag_taskfile(drive, &args, 0, NULL); | 613 | err = ide_diag_taskfile(drive, &args, 0, NULL); |
614 | break; | 614 | break; |
615 | default: | 615 | default: |
616 | err = -EFAULT; | 616 | err = -EFAULT; |
617 | goto abort; | 617 | goto abort; |
618 | } | 618 | } |
619 | 619 | ||
620 | memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE); | 620 | memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE); |
621 | memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE); | 621 | memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE); |
622 | req_task->in_flags = args.tf_in_flags; | 622 | req_task->in_flags = args.tf_in_flags; |
623 | req_task->out_flags = args.tf_out_flags; | 623 | req_task->out_flags = args.tf_out_flags; |
624 | 624 | ||
625 | if (copy_to_user(buf, req_task, tasksize)) { | 625 | if (copy_to_user(buf, req_task, tasksize)) { |
626 | err = -EFAULT; | 626 | err = -EFAULT; |
627 | goto abort; | 627 | goto abort; |
628 | } | 628 | } |
629 | if (taskout) { | 629 | if (taskout) { |
630 | int outtotal = tasksize; | 630 | int outtotal = tasksize; |
631 | if (copy_to_user(buf + outtotal, outbuf, taskout)) { | 631 | if (copy_to_user(buf + outtotal, outbuf, taskout)) { |
632 | err = -EFAULT; | 632 | err = -EFAULT; |
633 | goto abort; | 633 | goto abort; |
634 | } | 634 | } |
635 | } | 635 | } |
636 | if (taskin) { | 636 | if (taskin) { |
637 | int intotal = tasksize + taskout; | 637 | int intotal = tasksize + taskout; |
638 | if (copy_to_user(buf + intotal, inbuf, taskin)) { | 638 | if (copy_to_user(buf + intotal, inbuf, taskin)) { |
639 | err = -EFAULT; | 639 | err = -EFAULT; |
640 | goto abort; | 640 | goto abort; |
641 | } | 641 | } |
642 | } | 642 | } |
643 | abort: | 643 | abort: |
644 | kfree(req_task); | 644 | kfree(req_task); |
645 | kfree(outbuf); | 645 | kfree(outbuf); |
646 | kfree(inbuf); | 646 | kfree(inbuf); |
647 | 647 | ||
648 | // printk("IDE Taskfile ioctl ended. rc = %i\n", err); | 648 | // printk("IDE Taskfile ioctl ended. rc = %i\n", err); |
649 | 649 | ||
650 | drive->io_32bit = io_32bit; | 650 | drive->io_32bit = io_32bit; |
651 | 651 | ||
652 | return err; | 652 | return err; |
653 | } | 653 | } |
654 | 654 | ||
655 | int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf) | 655 | int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf) |
656 | { | 656 | { |
657 | struct request rq; | 657 | struct request rq; |
658 | u8 buffer[4]; | 658 | u8 buffer[4]; |
659 | 659 | ||
660 | if (!buf) | 660 | if (!buf) |
661 | buf = buffer; | 661 | buf = buffer; |
662 | memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors); | 662 | memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors); |
663 | ide_init_drive_cmd(&rq); | 663 | ide_init_drive_cmd(&rq); |
664 | rq.buffer = buf; | 664 | rq.buffer = buf; |
665 | *buf++ = cmd; | 665 | *buf++ = cmd; |
666 | *buf++ = nsect; | 666 | *buf++ = nsect; |
667 | *buf++ = feature; | 667 | *buf++ = feature; |
668 | *buf++ = sectors; | 668 | *buf++ = sectors; |
669 | return ide_do_drive_cmd(drive, &rq, ide_wait); | 669 | return ide_do_drive_cmd(drive, &rq, ide_wait); |
670 | } | 670 | } |
671 | 671 | ||
672 | /* | 672 | /* |
673 | * FIXME : this needs to map into at taskfile. <andre@linux-ide.org> | 673 | * FIXME : this needs to map into at taskfile. <andre@linux-ide.org> |
674 | */ | 674 | */ |
675 | int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | 675 | int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) |
676 | { | 676 | { |
677 | int err = 0; | 677 | int err = 0; |
678 | u8 args[4], *argbuf = args; | 678 | u8 args[4], *argbuf = args; |
679 | u8 xfer_rate = 0; | 679 | u8 xfer_rate = 0; |
680 | int argsize = 4; | 680 | int argsize = 4; |
681 | ide_task_t tfargs; | 681 | ide_task_t tfargs; |
682 | 682 | ||
683 | if (NULL == (void *) arg) { | 683 | if (NULL == (void *) arg) { |
684 | struct request rq; | 684 | struct request rq; |
685 | ide_init_drive_cmd(&rq); | 685 | ide_init_drive_cmd(&rq); |
686 | return ide_do_drive_cmd(drive, &rq, ide_wait); | 686 | return ide_do_drive_cmd(drive, &rq, ide_wait); |
687 | } | 687 | } |
688 | 688 | ||
689 | if (copy_from_user(args, (void __user *)arg, 4)) | 689 | if (copy_from_user(args, (void __user *)arg, 4)) |
690 | return -EFAULT; | 690 | return -EFAULT; |
691 | 691 | ||
692 | memset(&tfargs, 0, sizeof(ide_task_t)); | 692 | memset(&tfargs, 0, sizeof(ide_task_t)); |
693 | tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2]; | 693 | tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2]; |
694 | tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3]; | 694 | tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3]; |
695 | tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1]; | 695 | tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1]; |
696 | tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00; | 696 | tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00; |
697 | tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00; | 697 | tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00; |
698 | tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00; | 698 | tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00; |
699 | tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0]; | 699 | tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0]; |
700 | 700 | ||
701 | if (args[3]) { | 701 | if (args[3]) { |
702 | argsize = 4 + (SECTOR_WORDS * 4 * args[3]); | 702 | argsize = 4 + (SECTOR_WORDS * 4 * args[3]); |
703 | argbuf = kzalloc(argsize, GFP_KERNEL); | 703 | argbuf = kzalloc(argsize, GFP_KERNEL); |
704 | if (argbuf == NULL) | 704 | if (argbuf == NULL) |
705 | return -ENOMEM; | 705 | return -ENOMEM; |
706 | } | 706 | } |
707 | if (set_transfer(drive, &tfargs)) { | 707 | if (set_transfer(drive, &tfargs)) { |
708 | xfer_rate = args[1]; | 708 | xfer_rate = args[1]; |
709 | if (ide_ata66_check(drive, &tfargs)) | 709 | if (ide_ata66_check(drive, &tfargs)) |
710 | goto abort; | 710 | goto abort; |
711 | } | 711 | } |
712 | 712 | ||
713 | err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); | 713 | err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); |
714 | 714 | ||
715 | if (!err && xfer_rate) { | 715 | if (!err && xfer_rate) { |
716 | /* active-retuning-calls future */ | 716 | /* active-retuning-calls future */ |
717 | ide_set_xfer_rate(drive, xfer_rate); | 717 | ide_set_xfer_rate(drive, xfer_rate); |
718 | ide_driveid_update(drive); | 718 | ide_driveid_update(drive); |
719 | } | 719 | } |
720 | abort: | 720 | abort: |
721 | if (copy_to_user((void __user *)arg, argbuf, argsize)) | 721 | if (copy_to_user((void __user *)arg, argbuf, argsize)) |
722 | err = -EFAULT; | 722 | err = -EFAULT; |
723 | if (argsize > 4) | 723 | if (argsize > 4) |
724 | kfree(argbuf); | 724 | kfree(argbuf); |
725 | return err; | 725 | return err; |
726 | } | 726 | } |
727 | 727 | ||
728 | static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf) | 728 | static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf) |
729 | { | 729 | { |
730 | struct request rq; | 730 | struct request rq; |
731 | 731 | ||
732 | ide_init_drive_cmd(&rq); | 732 | ide_init_drive_cmd(&rq); |
733 | rq.flags = REQ_DRIVE_TASK; | 733 | rq.flags = REQ_DRIVE_TASK; |
734 | rq.buffer = buf; | 734 | rq.buffer = buf; |
735 | return ide_do_drive_cmd(drive, &rq, ide_wait); | 735 | return ide_do_drive_cmd(drive, &rq, ide_wait); |
736 | } | 736 | } |
737 | 737 | ||
738 | /* | 738 | /* |
739 | * FIXME : this needs to map into at taskfile. <andre@linux-ide.org> | 739 | * FIXME : this needs to map into at taskfile. <andre@linux-ide.org> |
740 | */ | 740 | */ |
741 | int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | 741 | int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) |
742 | { | 742 | { |
743 | void __user *p = (void __user *)arg; | 743 | void __user *p = (void __user *)arg; |
744 | int err = 0; | 744 | int err = 0; |
745 | u8 args[7], *argbuf = args; | 745 | u8 args[7], *argbuf = args; |
746 | int argsize = 7; | 746 | int argsize = 7; |
747 | 747 | ||
748 | if (copy_from_user(args, p, 7)) | 748 | if (copy_from_user(args, p, 7)) |
749 | return -EFAULT; | 749 | return -EFAULT; |
750 | err = ide_wait_cmd_task(drive, argbuf); | 750 | err = ide_wait_cmd_task(drive, argbuf); |
751 | if (copy_to_user(p, argbuf, argsize)) | 751 | if (copy_to_user(p, argbuf, argsize)) |
752 | err = -EFAULT; | 752 | err = -EFAULT; |
753 | return err; | 753 | return err; |
754 | } | 754 | } |
755 | 755 | ||
756 | /* | 756 | /* |
757 | * NOTICE: This is additions from IBM to provide a discrete interface, | 757 | * NOTICE: This is additions from IBM to provide a discrete interface, |
758 | * for selective taskregister access operations. Nice JOB Klaus!!! | 758 | * for selective taskregister access operations. Nice JOB Klaus!!! |
759 | * Glad to be able to work and co-develop this with you and IBM. | 759 | * Glad to be able to work and co-develop this with you and IBM. |
760 | */ | 760 | */ |
761 | ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) | 761 | ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) |
762 | { | 762 | { |
763 | ide_hwif_t *hwif = HWIF(drive); | 763 | ide_hwif_t *hwif = HWIF(drive); |
764 | task_struct_t *taskfile = (task_struct_t *) task->tfRegister; | 764 | task_struct_t *taskfile = (task_struct_t *) task->tfRegister; |
765 | hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; | 765 | hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; |
766 | 766 | ||
767 | if (task->data_phase == TASKFILE_MULTI_IN || | 767 | if (task->data_phase == TASKFILE_MULTI_IN || |
768 | task->data_phase == TASKFILE_MULTI_OUT) { | 768 | task->data_phase == TASKFILE_MULTI_OUT) { |
769 | if (!drive->mult_count) { | 769 | if (!drive->mult_count) { |
770 | printk(KERN_ERR "%s: multimode not set!\n", drive->name); | 770 | printk(KERN_ERR "%s: multimode not set!\n", drive->name); |
771 | return ide_stopped; | 771 | return ide_stopped; |
772 | } | 772 | } |
773 | } | 773 | } |
774 | 774 | ||
775 | /* | 775 | /* |
776 | * (ks) Check taskfile in/out flags. | 776 | * (ks) Check taskfile in flags. |
777 | * If set, then execute as it is defined. | 777 | * If set, then execute as it is defined. |
778 | * If not set, then define default settings. | 778 | * If not set, then define default settings. |
779 | * The default values are: | 779 | * The default values are: |
780 | * write and read all taskfile registers (except data) | 780 | * read all taskfile registers (except data) |
781 | * write and read the hob registers (sector,nsector,lcyl,hcyl) | 781 | * read the hob registers (sector, nsector, lcyl, hcyl) |
782 | */ | 782 | */ |
783 | if (task->tf_out_flags.all == 0) { | ||
784 | task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS; | ||
785 | if (drive->addressing == 1) | ||
786 | task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8); | ||
787 | } | ||
788 | |||
789 | if (task->tf_in_flags.all == 0) { | 783 | if (task->tf_in_flags.all == 0) { |
790 | task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; | 784 | task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; |
791 | if (drive->addressing == 1) | 785 | if (drive->addressing == 1) |
792 | task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8); | 786 | task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8); |
793 | } | 787 | } |
794 | 788 | ||
795 | /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ | 789 | /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ |
796 | if (IDE_CONTROL_REG) | 790 | if (IDE_CONTROL_REG) |
797 | /* clear nIEN */ | 791 | /* clear nIEN */ |
798 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | 792 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); |
799 | SELECT_MASK(drive, 0); | 793 | SELECT_MASK(drive, 0); |
800 | 794 | ||
801 | if (task->tf_out_flags.b.data) { | 795 | if (task->tf_out_flags.b.data) { |
802 | u16 data = taskfile->data + (hobfile->data << 8); | 796 | u16 data = taskfile->data + (hobfile->data << 8); |
803 | hwif->OUTW(data, IDE_DATA_REG); | 797 | hwif->OUTW(data, IDE_DATA_REG); |
804 | } | 798 | } |
805 | 799 | ||
806 | /* (ks) send hob registers first */ | 800 | /* (ks) send hob registers first */ |
807 | if (task->tf_out_flags.b.nsector_hob) | 801 | if (task->tf_out_flags.b.nsector_hob) |
808 | hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); | 802 | hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); |
809 | if (task->tf_out_flags.b.sector_hob) | 803 | if (task->tf_out_flags.b.sector_hob) |
810 | hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); | 804 | hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); |
811 | if (task->tf_out_flags.b.lcyl_hob) | 805 | if (task->tf_out_flags.b.lcyl_hob) |
812 | hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); | 806 | hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); |
813 | if (task->tf_out_flags.b.hcyl_hob) | 807 | if (task->tf_out_flags.b.hcyl_hob) |
814 | hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); | 808 | hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); |
815 | 809 | ||
816 | /* (ks) Send now the standard registers */ | 810 | /* (ks) Send now the standard registers */ |
817 | if (task->tf_out_flags.b.error_feature) | 811 | if (task->tf_out_flags.b.error_feature) |
818 | hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); | 812 | hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); |
819 | /* refers to number of sectors to transfer */ | 813 | /* refers to number of sectors to transfer */ |
820 | if (task->tf_out_flags.b.nsector) | 814 | if (task->tf_out_flags.b.nsector) |
821 | hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); | 815 | hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); |
822 | /* refers to sector offset or start sector */ | 816 | /* refers to sector offset or start sector */ |
823 | if (task->tf_out_flags.b.sector) | 817 | if (task->tf_out_flags.b.sector) |
824 | hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); | 818 | hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); |
825 | if (task->tf_out_flags.b.lcyl) | 819 | if (task->tf_out_flags.b.lcyl) |
826 | hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); | 820 | hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); |
827 | if (task->tf_out_flags.b.hcyl) | 821 | if (task->tf_out_flags.b.hcyl) |
828 | hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); | 822 | hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); |
829 | 823 | ||
830 | /* | 824 | /* |
831 | * (ks) In the flagged taskfile approch, we will use all specified | 825 | * (ks) In the flagged taskfile approch, we will use all specified |
832 | * registers and the register value will not be changed, except the | 826 | * registers and the register value will not be changed, except the |
833 | * select bit (master/slave) in the drive_head register. We must make | 827 | * select bit (master/slave) in the drive_head register. We must make |
834 | * sure that the desired drive is selected. | 828 | * sure that the desired drive is selected. |
835 | */ | 829 | */ |
836 | hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG); | 830 | hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG); |
837 | switch(task->data_phase) { | 831 | switch(task->data_phase) { |
838 | 832 | ||
839 | case TASKFILE_OUT_DMAQ: | 833 | case TASKFILE_OUT_DMAQ: |
840 | case TASKFILE_OUT_DMA: | 834 | case TASKFILE_OUT_DMA: |
841 | case TASKFILE_IN_DMAQ: | 835 | case TASKFILE_IN_DMAQ: |
842 | case TASKFILE_IN_DMA: | 836 | case TASKFILE_IN_DMA: |
843 | hwif->dma_setup(drive); | 837 | hwif->dma_setup(drive); |
844 | hwif->dma_exec_cmd(drive, taskfile->command); | 838 | hwif->dma_exec_cmd(drive, taskfile->command); |
845 | hwif->dma_start(drive); | 839 | hwif->dma_start(drive); |
846 | break; | 840 | break; |
847 | 841 | ||
848 | default: | 842 | default: |
849 | if (task->handler == NULL) | 843 | if (task->handler == NULL) |
850 | return ide_stopped; | 844 | return ide_stopped; |
851 | 845 | ||
852 | /* Issue the command */ | 846 | /* Issue the command */ |
853 | if (task->prehandler) { | 847 | if (task->prehandler) { |
854 | hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); | 848 | hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); |
855 | ndelay(400); /* FIXME */ | 849 | ndelay(400); /* FIXME */ |
856 | return task->prehandler(drive, task->rq); | 850 | return task->prehandler(drive, task->rq); |
857 | } | 851 | } |
858 | ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); | 852 | ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); |
859 | } | 853 | } |
860 | 854 | ||
861 | return ide_started; | 855 | return ide_started; |
862 | } | 856 | } |
863 | 857 |
include/linux/hdreg.h
1 | #ifndef _LINUX_HDREG_H | 1 | #ifndef _LINUX_HDREG_H |
2 | #define _LINUX_HDREG_H | 2 | #define _LINUX_HDREG_H |
3 | 3 | ||
4 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
5 | #include <linux/ata.h> | 5 | #include <linux/ata.h> |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * This file contains some defines for the AT-hd-controller. | 8 | * This file contains some defines for the AT-hd-controller. |
9 | * Various sources. | 9 | * Various sources. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | /* ide.c has its own port definitions in "ide.h" */ | 12 | /* ide.c has its own port definitions in "ide.h" */ |
13 | 13 | ||
14 | #define HD_IRQ 14 | 14 | #define HD_IRQ 14 |
15 | 15 | ||
16 | /* Hd controller regs. Ref: IBM AT Bios-listing */ | 16 | /* Hd controller regs. Ref: IBM AT Bios-listing */ |
17 | #define HD_DATA 0x1f0 /* _CTL when writing */ | 17 | #define HD_DATA 0x1f0 /* _CTL when writing */ |
18 | #define HD_ERROR 0x1f1 /* see err-bits */ | 18 | #define HD_ERROR 0x1f1 /* see err-bits */ |
19 | #define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ | 19 | #define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ |
20 | #define HD_SECTOR 0x1f3 /* starting sector */ | 20 | #define HD_SECTOR 0x1f3 /* starting sector */ |
21 | #define HD_LCYL 0x1f4 /* starting cylinder */ | 21 | #define HD_LCYL 0x1f4 /* starting cylinder */ |
22 | #define HD_HCYL 0x1f5 /* high byte of starting cyl */ | 22 | #define HD_HCYL 0x1f5 /* high byte of starting cyl */ |
23 | #define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ | 23 | #define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ |
24 | #define HD_STATUS 0x1f7 /* see status-bits */ | 24 | #define HD_STATUS 0x1f7 /* see status-bits */ |
25 | #define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ | 25 | #define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ |
26 | #define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ | 26 | #define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ |
27 | #define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ | 27 | #define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ |
28 | 28 | ||
29 | #define HD_CMD 0x3f6 /* used for resets */ | 29 | #define HD_CMD 0x3f6 /* used for resets */ |
30 | #define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ | 30 | #define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ |
31 | 31 | ||
32 | /* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */ | 32 | /* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */ |
33 | 33 | ||
34 | /* Bits of HD_STATUS */ | 34 | /* Bits of HD_STATUS */ |
35 | #define ERR_STAT 0x01 | 35 | #define ERR_STAT 0x01 |
36 | #define INDEX_STAT 0x02 | 36 | #define INDEX_STAT 0x02 |
37 | #define ECC_STAT 0x04 /* Corrected error */ | 37 | #define ECC_STAT 0x04 /* Corrected error */ |
38 | #define DRQ_STAT 0x08 | 38 | #define DRQ_STAT 0x08 |
39 | #define SEEK_STAT 0x10 | 39 | #define SEEK_STAT 0x10 |
40 | #define SRV_STAT 0x10 | 40 | #define SRV_STAT 0x10 |
41 | #define WRERR_STAT 0x20 | 41 | #define WRERR_STAT 0x20 |
42 | #define READY_STAT 0x40 | 42 | #define READY_STAT 0x40 |
43 | #define BUSY_STAT 0x80 | 43 | #define BUSY_STAT 0x80 |
44 | 44 | ||
45 | /* Bits for HD_ERROR */ | 45 | /* Bits for HD_ERROR */ |
46 | #define MARK_ERR 0x01 /* Bad address mark */ | 46 | #define MARK_ERR 0x01 /* Bad address mark */ |
47 | #define TRK0_ERR 0x02 /* couldn't find track 0 */ | 47 | #define TRK0_ERR 0x02 /* couldn't find track 0 */ |
48 | #define ABRT_ERR 0x04 /* Command aborted */ | 48 | #define ABRT_ERR 0x04 /* Command aborted */ |
49 | #define MCR_ERR 0x08 /* media change request */ | 49 | #define MCR_ERR 0x08 /* media change request */ |
50 | #define ID_ERR 0x10 /* ID field not found */ | 50 | #define ID_ERR 0x10 /* ID field not found */ |
51 | #define MC_ERR 0x20 /* media changed */ | 51 | #define MC_ERR 0x20 /* media changed */ |
52 | #define ECC_ERR 0x40 /* Uncorrectable ECC error */ | 52 | #define ECC_ERR 0x40 /* Uncorrectable ECC error */ |
53 | #define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ | 53 | #define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ |
54 | #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ | 54 | #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ |
55 | 55 | ||
56 | /* Bits of HD_NSECTOR */ | 56 | /* Bits of HD_NSECTOR */ |
57 | #define CD 0x01 | 57 | #define CD 0x01 |
58 | #define IO 0x02 | 58 | #define IO 0x02 |
59 | #define REL 0x04 | 59 | #define REL 0x04 |
60 | #define TAG_MASK 0xf8 | 60 | #define TAG_MASK 0xf8 |
61 | #endif /* __KERNEL__ */ | 61 | #endif /* __KERNEL__ */ |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * Command Header sizes for IOCTL commands | 64 | * Command Header sizes for IOCTL commands |
65 | */ | 65 | */ |
66 | 66 | ||
67 | #define HDIO_DRIVE_CMD_HDR_SIZE (4 * sizeof(u8)) | 67 | #define HDIO_DRIVE_CMD_HDR_SIZE (4 * sizeof(u8)) |
68 | #define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(u8)) | 68 | #define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(u8)) |
69 | #define HDIO_DRIVE_TASK_HDR_SIZE (8 * sizeof(u8)) | 69 | #define HDIO_DRIVE_TASK_HDR_SIZE (8 * sizeof(u8)) |
70 | 70 | ||
71 | #define IDE_DRIVE_TASK_INVALID -1 | 71 | #define IDE_DRIVE_TASK_INVALID -1 |
72 | #define IDE_DRIVE_TASK_NO_DATA 0 | 72 | #define IDE_DRIVE_TASK_NO_DATA 0 |
73 | #define IDE_DRIVE_TASK_SET_XFER 1 | 73 | #define IDE_DRIVE_TASK_SET_XFER 1 |
74 | 74 | ||
75 | #define IDE_DRIVE_TASK_IN 2 | 75 | #define IDE_DRIVE_TASK_IN 2 |
76 | 76 | ||
77 | #define IDE_DRIVE_TASK_OUT 3 | 77 | #define IDE_DRIVE_TASK_OUT 3 |
78 | #define IDE_DRIVE_TASK_RAW_WRITE 4 | 78 | #define IDE_DRIVE_TASK_RAW_WRITE 4 |
79 | 79 | ||
80 | /* | 80 | /* |
81 | * Define standard taskfile in/out register | 81 | * Define standard taskfile in/out register |
82 | */ | 82 | */ |
83 | #define IDE_TASKFILE_STD_OUT_FLAGS 0xFE | ||
84 | #define IDE_TASKFILE_STD_IN_FLAGS 0xFE | 83 | #define IDE_TASKFILE_STD_IN_FLAGS 0xFE |
85 | #define IDE_HOB_STD_OUT_FLAGS 0x3C | ||
86 | #define IDE_HOB_STD_IN_FLAGS 0x3C | 84 | #define IDE_HOB_STD_IN_FLAGS 0x3C |
85 | #ifndef __KERNEL__ | ||
86 | #define IDE_TASKFILE_STD_OUT_FLAGS 0xFE | ||
87 | #define IDE_HOB_STD_OUT_FLAGS 0x3C | ||
88 | #endif | ||
87 | 89 | ||
88 | typedef unsigned char task_ioreg_t; | 90 | typedef unsigned char task_ioreg_t; |
89 | typedef unsigned long sata_ioreg_t; | 91 | typedef unsigned long sata_ioreg_t; |
90 | 92 | ||
91 | typedef union ide_reg_valid_s { | 93 | typedef union ide_reg_valid_s { |
92 | unsigned all : 16; | 94 | unsigned all : 16; |
93 | struct { | 95 | struct { |
94 | unsigned data : 1; | 96 | unsigned data : 1; |
95 | unsigned error_feature : 1; | 97 | unsigned error_feature : 1; |
96 | unsigned sector : 1; | 98 | unsigned sector : 1; |
97 | unsigned nsector : 1; | 99 | unsigned nsector : 1; |
98 | unsigned lcyl : 1; | 100 | unsigned lcyl : 1; |
99 | unsigned hcyl : 1; | 101 | unsigned hcyl : 1; |
100 | unsigned select : 1; | 102 | unsigned select : 1; |
101 | unsigned status_command : 1; | 103 | unsigned status_command : 1; |
102 | 104 | ||
103 | unsigned data_hob : 1; | 105 | unsigned data_hob : 1; |
104 | unsigned error_feature_hob : 1; | 106 | unsigned error_feature_hob : 1; |
105 | unsigned sector_hob : 1; | 107 | unsigned sector_hob : 1; |
106 | unsigned nsector_hob : 1; | 108 | unsigned nsector_hob : 1; |
107 | unsigned lcyl_hob : 1; | 109 | unsigned lcyl_hob : 1; |
108 | unsigned hcyl_hob : 1; | 110 | unsigned hcyl_hob : 1; |
109 | unsigned select_hob : 1; | 111 | unsigned select_hob : 1; |
110 | unsigned control_hob : 1; | 112 | unsigned control_hob : 1; |
111 | } b; | 113 | } b; |
112 | } ide_reg_valid_t; | 114 | } ide_reg_valid_t; |
113 | 115 | ||
114 | typedef struct ide_task_request_s { | 116 | typedef struct ide_task_request_s { |
115 | task_ioreg_t io_ports[8]; | 117 | task_ioreg_t io_ports[8]; |
116 | task_ioreg_t hob_ports[8]; | 118 | task_ioreg_t hob_ports[8]; |
117 | ide_reg_valid_t out_flags; | 119 | ide_reg_valid_t out_flags; |
118 | ide_reg_valid_t in_flags; | 120 | ide_reg_valid_t in_flags; |
119 | int data_phase; | 121 | int data_phase; |
120 | int req_cmd; | 122 | int req_cmd; |
121 | unsigned long out_size; | 123 | unsigned long out_size; |
122 | unsigned long in_size; | 124 | unsigned long in_size; |
123 | } ide_task_request_t; | 125 | } ide_task_request_t; |
124 | 126 | ||
125 | typedef struct ide_ioctl_request_s { | 127 | typedef struct ide_ioctl_request_s { |
126 | ide_task_request_t *task_request; | 128 | ide_task_request_t *task_request; |
127 | unsigned char *out_buffer; | 129 | unsigned char *out_buffer; |
128 | unsigned char *in_buffer; | 130 | unsigned char *in_buffer; |
129 | } ide_ioctl_request_t; | 131 | } ide_ioctl_request_t; |
130 | 132 | ||
131 | struct hd_drive_cmd_hdr { | 133 | struct hd_drive_cmd_hdr { |
132 | task_ioreg_t command; | 134 | task_ioreg_t command; |
133 | task_ioreg_t sector_number; | 135 | task_ioreg_t sector_number; |
134 | task_ioreg_t feature; | 136 | task_ioreg_t feature; |
135 | task_ioreg_t sector_count; | 137 | task_ioreg_t sector_count; |
136 | }; | 138 | }; |
137 | 139 | ||
138 | typedef struct hd_drive_task_hdr { | 140 | typedef struct hd_drive_task_hdr { |
139 | task_ioreg_t data; | 141 | task_ioreg_t data; |
140 | task_ioreg_t feature; | 142 | task_ioreg_t feature; |
141 | task_ioreg_t sector_count; | 143 | task_ioreg_t sector_count; |
142 | task_ioreg_t sector_number; | 144 | task_ioreg_t sector_number; |
143 | task_ioreg_t low_cylinder; | 145 | task_ioreg_t low_cylinder; |
144 | task_ioreg_t high_cylinder; | 146 | task_ioreg_t high_cylinder; |
145 | task_ioreg_t device_head; | 147 | task_ioreg_t device_head; |
146 | task_ioreg_t command; | 148 | task_ioreg_t command; |
147 | } task_struct_t; | 149 | } task_struct_t; |
148 | 150 | ||
149 | typedef struct hd_drive_hob_hdr { | 151 | typedef struct hd_drive_hob_hdr { |
150 | task_ioreg_t data; | 152 | task_ioreg_t data; |
151 | task_ioreg_t feature; | 153 | task_ioreg_t feature; |
152 | task_ioreg_t sector_count; | 154 | task_ioreg_t sector_count; |
153 | task_ioreg_t sector_number; | 155 | task_ioreg_t sector_number; |
154 | task_ioreg_t low_cylinder; | 156 | task_ioreg_t low_cylinder; |
155 | task_ioreg_t high_cylinder; | 157 | task_ioreg_t high_cylinder; |
156 | task_ioreg_t device_head; | 158 | task_ioreg_t device_head; |
157 | task_ioreg_t control; | 159 | task_ioreg_t control; |
158 | } hob_struct_t; | 160 | } hob_struct_t; |
159 | 161 | ||
160 | #define TASKFILE_INVALID 0x7fff | 162 | #define TASKFILE_INVALID 0x7fff |
161 | #define TASKFILE_48 0x8000 | 163 | #define TASKFILE_48 0x8000 |
162 | 164 | ||
163 | #define TASKFILE_NO_DATA 0x0000 | 165 | #define TASKFILE_NO_DATA 0x0000 |
164 | 166 | ||
165 | #define TASKFILE_IN 0x0001 | 167 | #define TASKFILE_IN 0x0001 |
166 | #define TASKFILE_MULTI_IN 0x0002 | 168 | #define TASKFILE_MULTI_IN 0x0002 |
167 | 169 | ||
168 | #define TASKFILE_OUT 0x0004 | 170 | #define TASKFILE_OUT 0x0004 |
169 | #define TASKFILE_MULTI_OUT 0x0008 | 171 | #define TASKFILE_MULTI_OUT 0x0008 |
170 | #define TASKFILE_IN_OUT 0x0010 | 172 | #define TASKFILE_IN_OUT 0x0010 |
171 | 173 | ||
172 | #define TASKFILE_IN_DMA 0x0020 | 174 | #define TASKFILE_IN_DMA 0x0020 |
173 | #define TASKFILE_OUT_DMA 0x0040 | 175 | #define TASKFILE_OUT_DMA 0x0040 |
174 | #define TASKFILE_IN_DMAQ 0x0080 | 176 | #define TASKFILE_IN_DMAQ 0x0080 |
175 | #define TASKFILE_OUT_DMAQ 0x0100 | 177 | #define TASKFILE_OUT_DMAQ 0x0100 |
176 | 178 | ||
177 | #define TASKFILE_P_IN 0x0200 | 179 | #define TASKFILE_P_IN 0x0200 |
178 | #define TASKFILE_P_OUT 0x0400 | 180 | #define TASKFILE_P_OUT 0x0400 |
179 | #define TASKFILE_P_IN_DMA 0x0800 | 181 | #define TASKFILE_P_IN_DMA 0x0800 |
180 | #define TASKFILE_P_OUT_DMA 0x1000 | 182 | #define TASKFILE_P_OUT_DMA 0x1000 |
181 | #define TASKFILE_P_IN_DMAQ 0x2000 | 183 | #define TASKFILE_P_IN_DMAQ 0x2000 |
182 | #define TASKFILE_P_OUT_DMAQ 0x4000 | 184 | #define TASKFILE_P_OUT_DMAQ 0x4000 |
183 | 185 | ||
184 | /* ATA/ATAPI Commands pre T13 Spec */ | 186 | /* ATA/ATAPI Commands pre T13 Spec */ |
185 | #define WIN_NOP 0x00 | 187 | #define WIN_NOP 0x00 |
186 | /* | 188 | /* |
187 | * 0x01->0x02 Reserved | 189 | * 0x01->0x02 Reserved |
188 | */ | 190 | */ |
189 | #define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended Error Code */ | 191 | #define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended Error Code */ |
190 | /* | 192 | /* |
191 | * 0x04->0x07 Reserved | 193 | * 0x04->0x07 Reserved |
192 | */ | 194 | */ |
193 | #define WIN_SRST 0x08 /* ATAPI soft reset command */ | 195 | #define WIN_SRST 0x08 /* ATAPI soft reset command */ |
194 | #define WIN_DEVICE_RESET 0x08 | 196 | #define WIN_DEVICE_RESET 0x08 |
195 | /* | 197 | /* |
196 | * 0x09->0x0F Reserved | 198 | * 0x09->0x0F Reserved |
197 | */ | 199 | */ |
198 | #define WIN_RECAL 0x10 | 200 | #define WIN_RECAL 0x10 |
199 | #define WIN_RESTORE WIN_RECAL | 201 | #define WIN_RESTORE WIN_RECAL |
200 | /* | 202 | /* |
201 | * 0x10->0x1F Reserved | 203 | * 0x10->0x1F Reserved |
202 | */ | 204 | */ |
203 | #define WIN_READ 0x20 /* 28-Bit */ | 205 | #define WIN_READ 0x20 /* 28-Bit */ |
204 | #define WIN_READ_ONCE 0x21 /* 28-Bit without retries */ | 206 | #define WIN_READ_ONCE 0x21 /* 28-Bit without retries */ |
205 | #define WIN_READ_LONG 0x22 /* 28-Bit */ | 207 | #define WIN_READ_LONG 0x22 /* 28-Bit */ |
206 | #define WIN_READ_LONG_ONCE 0x23 /* 28-Bit without retries */ | 208 | #define WIN_READ_LONG_ONCE 0x23 /* 28-Bit without retries */ |
207 | #define WIN_READ_EXT 0x24 /* 48-Bit */ | 209 | #define WIN_READ_EXT 0x24 /* 48-Bit */ |
208 | #define WIN_READDMA_EXT 0x25 /* 48-Bit */ | 210 | #define WIN_READDMA_EXT 0x25 /* 48-Bit */ |
209 | #define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit */ | 211 | #define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit */ |
210 | #define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */ | 212 | #define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */ |
211 | /* | 213 | /* |
212 | * 0x28 | 214 | * 0x28 |
213 | */ | 215 | */ |
214 | #define WIN_MULTREAD_EXT 0x29 /* 48-Bit */ | 216 | #define WIN_MULTREAD_EXT 0x29 /* 48-Bit */ |
215 | /* | 217 | /* |
216 | * 0x2A->0x2F Reserved | 218 | * 0x2A->0x2F Reserved |
217 | */ | 219 | */ |
218 | #define WIN_WRITE 0x30 /* 28-Bit */ | 220 | #define WIN_WRITE 0x30 /* 28-Bit */ |
219 | #define WIN_WRITE_ONCE 0x31 /* 28-Bit without retries */ | 221 | #define WIN_WRITE_ONCE 0x31 /* 28-Bit without retries */ |
220 | #define WIN_WRITE_LONG 0x32 /* 28-Bit */ | 222 | #define WIN_WRITE_LONG 0x32 /* 28-Bit */ |
221 | #define WIN_WRITE_LONG_ONCE 0x33 /* 28-Bit without retries */ | 223 | #define WIN_WRITE_LONG_ONCE 0x33 /* 28-Bit without retries */ |
222 | #define WIN_WRITE_EXT 0x34 /* 48-Bit */ | 224 | #define WIN_WRITE_EXT 0x34 /* 48-Bit */ |
223 | #define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */ | 225 | #define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */ |
224 | #define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */ | 226 | #define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */ |
225 | #define WIN_SET_MAX_EXT 0x37 /* 48-Bit */ | 227 | #define WIN_SET_MAX_EXT 0x37 /* 48-Bit */ |
226 | #define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors without erase */ | 228 | #define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors without erase */ |
227 | #define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */ | 229 | #define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */ |
228 | /* | 230 | /* |
229 | * 0x3A->0x3B Reserved | 231 | * 0x3A->0x3B Reserved |
230 | */ | 232 | */ |
231 | #define WIN_WRITE_VERIFY 0x3C /* 28-Bit */ | 233 | #define WIN_WRITE_VERIFY 0x3C /* 28-Bit */ |
232 | /* | 234 | /* |
233 | * 0x3D->0x3F Reserved | 235 | * 0x3D->0x3F Reserved |
234 | */ | 236 | */ |
235 | #define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */ | 237 | #define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */ |
236 | #define WIN_VERIFY_ONCE 0x41 /* 28-Bit - without retries */ | 238 | #define WIN_VERIFY_ONCE 0x41 /* 28-Bit - without retries */ |
237 | #define WIN_VERIFY_EXT 0x42 /* 48-Bit */ | 239 | #define WIN_VERIFY_EXT 0x42 /* 48-Bit */ |
238 | /* | 240 | /* |
239 | * 0x43->0x4F Reserved | 241 | * 0x43->0x4F Reserved |
240 | */ | 242 | */ |
241 | #define WIN_FORMAT 0x50 | 243 | #define WIN_FORMAT 0x50 |
242 | /* | 244 | /* |
243 | * 0x51->0x5F Reserved | 245 | * 0x51->0x5F Reserved |
244 | */ | 246 | */ |
245 | #define WIN_INIT 0x60 | 247 | #define WIN_INIT 0x60 |
246 | /* | 248 | /* |
247 | * 0x61->0x5F Reserved | 249 | * 0x61->0x5F Reserved |
248 | */ | 250 | */ |
249 | #define WIN_SEEK 0x70 /* 0x70-0x7F Reserved */ | 251 | #define WIN_SEEK 0x70 /* 0x70-0x7F Reserved */ |
250 | 252 | ||
251 | #define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */ | 253 | #define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */ |
252 | #define WIN_DIAGNOSE 0x90 | 254 | #define WIN_DIAGNOSE 0x90 |
253 | #define WIN_SPECIFY 0x91 /* set drive geometry translation */ | 255 | #define WIN_SPECIFY 0x91 /* set drive geometry translation */ |
254 | #define WIN_DOWNLOAD_MICROCODE 0x92 | 256 | #define WIN_DOWNLOAD_MICROCODE 0x92 |
255 | #define WIN_STANDBYNOW2 0x94 | 257 | #define WIN_STANDBYNOW2 0x94 |
256 | #define WIN_STANDBY2 0x96 | 258 | #define WIN_STANDBY2 0x96 |
257 | #define WIN_SETIDLE2 0x97 | 259 | #define WIN_SETIDLE2 0x97 |
258 | #define WIN_CHECKPOWERMODE2 0x98 | 260 | #define WIN_CHECKPOWERMODE2 0x98 |
259 | #define WIN_SLEEPNOW2 0x99 | 261 | #define WIN_SLEEPNOW2 0x99 |
260 | /* | 262 | /* |
261 | * 0x9A VENDOR | 263 | * 0x9A VENDOR |
262 | */ | 264 | */ |
263 | #define WIN_PACKETCMD 0xA0 /* Send a packet command. */ | 265 | #define WIN_PACKETCMD 0xA0 /* Send a packet command. */ |
264 | #define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */ | 266 | #define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */ |
265 | #define WIN_QUEUED_SERVICE 0xA2 | 267 | #define WIN_QUEUED_SERVICE 0xA2 |
266 | #define WIN_SMART 0xB0 /* self-monitoring and reporting */ | 268 | #define WIN_SMART 0xB0 /* self-monitoring and reporting */ |
267 | #define CFA_ERASE_SECTORS 0xC0 | 269 | #define CFA_ERASE_SECTORS 0xC0 |
268 | #define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/ | 270 | #define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/ |
269 | #define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */ | 271 | #define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */ |
270 | #define WIN_SETMULT 0xC6 /* enable/disable multiple mode */ | 272 | #define WIN_SETMULT 0xC6 /* enable/disable multiple mode */ |
271 | #define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */ | 273 | #define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */ |
272 | #define WIN_READDMA 0xC8 /* read sectors using DMA transfers */ | 274 | #define WIN_READDMA 0xC8 /* read sectors using DMA transfers */ |
273 | #define WIN_READDMA_ONCE 0xC9 /* 28-Bit - without retries */ | 275 | #define WIN_READDMA_ONCE 0xC9 /* 28-Bit - without retries */ |
274 | #define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */ | 276 | #define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */ |
275 | #define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */ | 277 | #define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */ |
276 | #define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */ | 278 | #define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */ |
277 | #define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */ | 279 | #define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */ |
278 | #define WIN_GETMEDIASTATUS 0xDA | 280 | #define WIN_GETMEDIASTATUS 0xDA |
279 | #define WIN_ACKMEDIACHANGE 0xDB /* ATA-1, ATA-2 vendor */ | 281 | #define WIN_ACKMEDIACHANGE 0xDB /* ATA-1, ATA-2 vendor */ |
280 | #define WIN_POSTBOOT 0xDC | 282 | #define WIN_POSTBOOT 0xDC |
281 | #define WIN_PREBOOT 0xDD | 283 | #define WIN_PREBOOT 0xDD |
282 | #define WIN_DOORLOCK 0xDE /* lock door on removable drives */ | 284 | #define WIN_DOORLOCK 0xDE /* lock door on removable drives */ |
283 | #define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */ | 285 | #define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */ |
284 | #define WIN_STANDBYNOW1 0xE0 | 286 | #define WIN_STANDBYNOW1 0xE0 |
285 | #define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */ | 287 | #define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */ |
286 | #define WIN_STANDBY 0xE2 /* Set device in Standby Mode */ | 288 | #define WIN_STANDBY 0xE2 /* Set device in Standby Mode */ |
287 | #define WIN_SETIDLE1 0xE3 | 289 | #define WIN_SETIDLE1 0xE3 |
288 | #define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */ | 290 | #define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */ |
289 | #define WIN_CHECKPOWERMODE1 0xE5 | 291 | #define WIN_CHECKPOWERMODE1 0xE5 |
290 | #define WIN_SLEEPNOW1 0xE6 | 292 | #define WIN_SLEEPNOW1 0xE6 |
291 | #define WIN_FLUSH_CACHE 0xE7 | 293 | #define WIN_FLUSH_CACHE 0xE7 |
292 | #define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */ | 294 | #define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */ |
293 | #define WIN_WRITE_SAME 0xE9 /* read ata-2 to use */ | 295 | #define WIN_WRITE_SAME 0xE9 /* read ata-2 to use */ |
294 | /* SET_FEATURES 0x22 or 0xDD */ | 296 | /* SET_FEATURES 0x22 or 0xDD */ |
295 | #define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */ | 297 | #define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */ |
296 | #define WIN_IDENTIFY 0xEC /* ask drive to identify itself */ | 298 | #define WIN_IDENTIFY 0xEC /* ask drive to identify itself */ |
297 | #define WIN_MEDIAEJECT 0xED | 299 | #define WIN_MEDIAEJECT 0xED |
298 | #define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */ | 300 | #define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */ |
299 | #define WIN_SETFEATURES 0xEF /* set special drive features */ | 301 | #define WIN_SETFEATURES 0xEF /* set special drive features */ |
300 | #define EXABYTE_ENABLE_NEST 0xF0 | 302 | #define EXABYTE_ENABLE_NEST 0xF0 |
301 | #define WIN_SECURITY_SET_PASS 0xF1 | 303 | #define WIN_SECURITY_SET_PASS 0xF1 |
302 | #define WIN_SECURITY_UNLOCK 0xF2 | 304 | #define WIN_SECURITY_UNLOCK 0xF2 |
303 | #define WIN_SECURITY_ERASE_PREPARE 0xF3 | 305 | #define WIN_SECURITY_ERASE_PREPARE 0xF3 |
304 | #define WIN_SECURITY_ERASE_UNIT 0xF4 | 306 | #define WIN_SECURITY_ERASE_UNIT 0xF4 |
305 | #define WIN_SECURITY_FREEZE_LOCK 0xF5 | 307 | #define WIN_SECURITY_FREEZE_LOCK 0xF5 |
306 | #define WIN_SECURITY_DISABLE 0xF6 | 308 | #define WIN_SECURITY_DISABLE 0xF6 |
307 | #define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */ | 309 | #define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */ |
308 | #define WIN_SET_MAX 0xF9 | 310 | #define WIN_SET_MAX 0xF9 |
309 | #define DISABLE_SEAGATE 0xFB | 311 | #define DISABLE_SEAGATE 0xFB |
310 | 312 | ||
311 | /* WIN_SMART sub-commands */ | 313 | /* WIN_SMART sub-commands */ |
312 | 314 | ||
313 | #define SMART_READ_VALUES 0xD0 | 315 | #define SMART_READ_VALUES 0xD0 |
314 | #define SMART_READ_THRESHOLDS 0xD1 | 316 | #define SMART_READ_THRESHOLDS 0xD1 |
315 | #define SMART_AUTOSAVE 0xD2 | 317 | #define SMART_AUTOSAVE 0xD2 |
316 | #define SMART_SAVE 0xD3 | 318 | #define SMART_SAVE 0xD3 |
317 | #define SMART_IMMEDIATE_OFFLINE 0xD4 | 319 | #define SMART_IMMEDIATE_OFFLINE 0xD4 |
318 | #define SMART_READ_LOG_SECTOR 0xD5 | 320 | #define SMART_READ_LOG_SECTOR 0xD5 |
319 | #define SMART_WRITE_LOG_SECTOR 0xD6 | 321 | #define SMART_WRITE_LOG_SECTOR 0xD6 |
320 | #define SMART_WRITE_THRESHOLDS 0xD7 | 322 | #define SMART_WRITE_THRESHOLDS 0xD7 |
321 | #define SMART_ENABLE 0xD8 | 323 | #define SMART_ENABLE 0xD8 |
322 | #define SMART_DISABLE 0xD9 | 324 | #define SMART_DISABLE 0xD9 |
323 | #define SMART_STATUS 0xDA | 325 | #define SMART_STATUS 0xDA |
324 | #define SMART_AUTO_OFFLINE 0xDB | 326 | #define SMART_AUTO_OFFLINE 0xDB |
325 | 327 | ||
326 | /* Password used in TF4 & TF5 executing SMART commands */ | 328 | /* Password used in TF4 & TF5 executing SMART commands */ |
327 | 329 | ||
328 | #define SMART_LCYL_PASS 0x4F | 330 | #define SMART_LCYL_PASS 0x4F |
329 | #define SMART_HCYL_PASS 0xC2 | 331 | #define SMART_HCYL_PASS 0xC2 |
330 | 332 | ||
331 | /* WIN_SETFEATURES sub-commands */ | 333 | /* WIN_SETFEATURES sub-commands */ |
332 | #define SETFEATURES_EN_8BIT 0x01 /* Enable 8-Bit Transfers */ | 334 | #define SETFEATURES_EN_8BIT 0x01 /* Enable 8-Bit Transfers */ |
333 | #define SETFEATURES_EN_WCACHE 0x02 /* Enable write cache */ | 335 | #define SETFEATURES_EN_WCACHE 0x02 /* Enable write cache */ |
334 | #define SETFEATURES_DIS_DEFECT 0x04 /* Disable Defect Management */ | 336 | #define SETFEATURES_DIS_DEFECT 0x04 /* Disable Defect Management */ |
335 | #define SETFEATURES_EN_APM 0x05 /* Enable advanced power management */ | 337 | #define SETFEATURES_EN_APM 0x05 /* Enable advanced power management */ |
336 | #define SETFEATURES_EN_SAME_R 0x22 /* for a region ATA-1 */ | 338 | #define SETFEATURES_EN_SAME_R 0x22 /* for a region ATA-1 */ |
337 | #define SETFEATURES_DIS_MSN 0x31 /* Disable Media Status Notification */ | 339 | #define SETFEATURES_DIS_MSN 0x31 /* Disable Media Status Notification */ |
338 | #define SETFEATURES_DIS_RETRY 0x33 /* Disable Retry */ | 340 | #define SETFEATURES_DIS_RETRY 0x33 /* Disable Retry */ |
339 | #define SETFEATURES_EN_AAM 0x42 /* Enable Automatic Acoustic Management */ | 341 | #define SETFEATURES_EN_AAM 0x42 /* Enable Automatic Acoustic Management */ |
340 | #define SETFEATURES_RW_LONG 0x44 /* Set Length of VS bytes */ | 342 | #define SETFEATURES_RW_LONG 0x44 /* Set Length of VS bytes */ |
341 | #define SETFEATURES_SET_CACHE 0x54 /* Set Cache segments to SC Reg. Val */ | 343 | #define SETFEATURES_SET_CACHE 0x54 /* Set Cache segments to SC Reg. Val */ |
342 | #define SETFEATURES_DIS_RLA 0x55 /* Disable read look-ahead feature */ | 344 | #define SETFEATURES_DIS_RLA 0x55 /* Disable read look-ahead feature */ |
343 | #define SETFEATURES_EN_RI 0x5D /* Enable release interrupt */ | 345 | #define SETFEATURES_EN_RI 0x5D /* Enable release interrupt */ |
344 | #define SETFEATURES_EN_SI 0x5E /* Enable SERVICE interrupt */ | 346 | #define SETFEATURES_EN_SI 0x5E /* Enable SERVICE interrupt */ |
345 | #define SETFEATURES_DIS_RPOD 0x66 /* Disable reverting to power on defaults */ | 347 | #define SETFEATURES_DIS_RPOD 0x66 /* Disable reverting to power on defaults */ |
346 | #define SETFEATURES_DIS_ECC 0x77 /* Disable ECC byte count */ | 348 | #define SETFEATURES_DIS_ECC 0x77 /* Disable ECC byte count */ |
347 | #define SETFEATURES_DIS_8BIT 0x81 /* Disable 8-Bit Transfers */ | 349 | #define SETFEATURES_DIS_8BIT 0x81 /* Disable 8-Bit Transfers */ |
348 | #define SETFEATURES_DIS_WCACHE 0x82 /* Disable write cache */ | 350 | #define SETFEATURES_DIS_WCACHE 0x82 /* Disable write cache */ |
349 | #define SETFEATURES_EN_DEFECT 0x84 /* Enable Defect Management */ | 351 | #define SETFEATURES_EN_DEFECT 0x84 /* Enable Defect Management */ |
350 | #define SETFEATURES_DIS_APM 0x85 /* Disable advanced power management */ | 352 | #define SETFEATURES_DIS_APM 0x85 /* Disable advanced power management */ |
351 | #define SETFEATURES_EN_ECC 0x88 /* Enable ECC byte count */ | 353 | #define SETFEATURES_EN_ECC 0x88 /* Enable ECC byte count */ |
352 | #define SETFEATURES_EN_MSN 0x95 /* Enable Media Status Notification */ | 354 | #define SETFEATURES_EN_MSN 0x95 /* Enable Media Status Notification */ |
353 | #define SETFEATURES_EN_RETRY 0x99 /* Enable Retry */ | 355 | #define SETFEATURES_EN_RETRY 0x99 /* Enable Retry */ |
354 | #define SETFEATURES_EN_RLA 0xAA /* Enable read look-ahead feature */ | 356 | #define SETFEATURES_EN_RLA 0xAA /* Enable read look-ahead feature */ |
355 | #define SETFEATURES_PREFETCH 0xAB /* Sets drive prefetch value */ | 357 | #define SETFEATURES_PREFETCH 0xAB /* Sets drive prefetch value */ |
356 | #define SETFEATURES_EN_REST 0xAC /* ATA-1 */ | 358 | #define SETFEATURES_EN_REST 0xAC /* ATA-1 */ |
357 | #define SETFEATURES_4B_RW_LONG 0xBB /* Set Lenght of 4 bytes */ | 359 | #define SETFEATURES_4B_RW_LONG 0xBB /* Set Lenght of 4 bytes */ |
358 | #define SETFEATURES_DIS_AAM 0xC2 /* Disable Automatic Acoustic Management */ | 360 | #define SETFEATURES_DIS_AAM 0xC2 /* Disable Automatic Acoustic Management */ |
359 | #define SETFEATURES_EN_RPOD 0xCC /* Enable reverting to power on defaults */ | 361 | #define SETFEATURES_EN_RPOD 0xCC /* Enable reverting to power on defaults */ |
360 | #define SETFEATURES_DIS_RI 0xDD /* Disable release interrupt ATAPI */ | 362 | #define SETFEATURES_DIS_RI 0xDD /* Disable release interrupt ATAPI */ |
361 | #define SETFEATURES_EN_SAME_M 0xDD /* for a entire device ATA-1 */ | 363 | #define SETFEATURES_EN_SAME_M 0xDD /* for a entire device ATA-1 */ |
362 | #define SETFEATURES_DIS_SI 0xDE /* Disable SERVICE interrupt ATAPI */ | 364 | #define SETFEATURES_DIS_SI 0xDE /* Disable SERVICE interrupt ATAPI */ |
363 | 365 | ||
364 | /* WIN_SECURITY sub-commands */ | 366 | /* WIN_SECURITY sub-commands */ |
365 | 367 | ||
366 | #define SECURITY_SET_PASSWORD 0xBA | 368 | #define SECURITY_SET_PASSWORD 0xBA |
367 | #define SECURITY_UNLOCK 0xBB | 369 | #define SECURITY_UNLOCK 0xBB |
368 | #define SECURITY_ERASE_PREPARE 0xBC | 370 | #define SECURITY_ERASE_PREPARE 0xBC |
369 | #define SECURITY_ERASE_UNIT 0xBD | 371 | #define SECURITY_ERASE_UNIT 0xBD |
370 | #define SECURITY_FREEZE_LOCK 0xBE | 372 | #define SECURITY_FREEZE_LOCK 0xBE |
371 | #define SECURITY_DISABLE_PASSWORD 0xBF | 373 | #define SECURITY_DISABLE_PASSWORD 0xBF |
372 | 374 | ||
373 | struct hd_geometry { | 375 | struct hd_geometry { |
374 | unsigned char heads; | 376 | unsigned char heads; |
375 | unsigned char sectors; | 377 | unsigned char sectors; |
376 | unsigned short cylinders; | 378 | unsigned short cylinders; |
377 | unsigned long start; | 379 | unsigned long start; |
378 | }; | 380 | }; |
379 | 381 | ||
380 | /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */ | 382 | /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */ |
381 | #define HDIO_GETGEO 0x0301 /* get device geometry */ | 383 | #define HDIO_GETGEO 0x0301 /* get device geometry */ |
382 | #define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */ | 384 | #define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */ |
383 | #define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */ | 385 | #define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */ |
384 | #define HDIO_GET_QDMA 0x0305 /* get use-qdma flag */ | 386 | #define HDIO_GET_QDMA 0x0305 /* get use-qdma flag */ |
385 | 387 | ||
386 | #define HDIO_SET_XFER 0x0306 /* set transfer rate via proc */ | 388 | #define HDIO_SET_XFER 0x0306 /* set transfer rate via proc */ |
387 | 389 | ||
388 | #define HDIO_OBSOLETE_IDENTITY 0x0307 /* OBSOLETE, DO NOT USE: returns 142 bytes */ | 390 | #define HDIO_OBSOLETE_IDENTITY 0x0307 /* OBSOLETE, DO NOT USE: returns 142 bytes */ |
389 | #define HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */ | 391 | #define HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */ |
390 | #define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */ | 392 | #define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */ |
391 | #define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */ | 393 | #define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */ |
392 | #define HDIO_GET_DMA 0x030b /* get use-dma flag */ | 394 | #define HDIO_GET_DMA 0x030b /* get use-dma flag */ |
393 | #define HDIO_GET_NICE 0x030c /* get nice flags */ | 395 | #define HDIO_GET_NICE 0x030c /* get nice flags */ |
394 | #define HDIO_GET_IDENTITY 0x030d /* get IDE identification info */ | 396 | #define HDIO_GET_IDENTITY 0x030d /* get IDE identification info */ |
395 | #define HDIO_GET_WCACHE 0x030e /* get write cache mode on|off */ | 397 | #define HDIO_GET_WCACHE 0x030e /* get write cache mode on|off */ |
396 | #define HDIO_GET_ACOUSTIC 0x030f /* get acoustic value */ | 398 | #define HDIO_GET_ACOUSTIC 0x030f /* get acoustic value */ |
397 | #define HDIO_GET_ADDRESS 0x0310 /* */ | 399 | #define HDIO_GET_ADDRESS 0x0310 /* */ |
398 | 400 | ||
399 | #define HDIO_GET_BUSSTATE 0x031a /* get the bus state of the hwif */ | 401 | #define HDIO_GET_BUSSTATE 0x031a /* get the bus state of the hwif */ |
400 | #define HDIO_TRISTATE_HWIF 0x031b /* execute a channel tristate */ | 402 | #define HDIO_TRISTATE_HWIF 0x031b /* execute a channel tristate */ |
401 | #define HDIO_DRIVE_RESET 0x031c /* execute a device reset */ | 403 | #define HDIO_DRIVE_RESET 0x031c /* execute a device reset */ |
402 | #define HDIO_DRIVE_TASKFILE 0x031d /* execute raw taskfile */ | 404 | #define HDIO_DRIVE_TASKFILE 0x031d /* execute raw taskfile */ |
403 | #define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */ | 405 | #define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */ |
404 | #define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */ | 406 | #define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */ |
405 | #define HDIO_DRIVE_CMD_AEB HDIO_DRIVE_TASK | 407 | #define HDIO_DRIVE_CMD_AEB HDIO_DRIVE_TASK |
406 | 408 | ||
407 | /* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */ | 409 | /* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */ |
408 | #define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */ | 410 | #define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */ |
409 | #define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */ | 411 | #define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */ |
410 | #define HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */ | 412 | #define HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */ |
411 | #define HDIO_SET_32BIT 0x0324 /* change io_32bit flags */ | 413 | #define HDIO_SET_32BIT 0x0324 /* change io_32bit flags */ |
412 | #define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */ | 414 | #define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */ |
413 | #define HDIO_SET_DMA 0x0326 /* change use-dma flag */ | 415 | #define HDIO_SET_DMA 0x0326 /* change use-dma flag */ |
414 | #define HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */ | 416 | #define HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */ |
415 | #define HDIO_SCAN_HWIF 0x0328 /* register and (re)scan interface */ | 417 | #define HDIO_SCAN_HWIF 0x0328 /* register and (re)scan interface */ |
416 | #define HDIO_SET_NICE 0x0329 /* set nice flags */ | 418 | #define HDIO_SET_NICE 0x0329 /* set nice flags */ |
417 | #define HDIO_UNREGISTER_HWIF 0x032a /* unregister interface */ | 419 | #define HDIO_UNREGISTER_HWIF 0x032a /* unregister interface */ |
418 | #define HDIO_SET_WCACHE 0x032b /* change write cache enable-disable */ | 420 | #define HDIO_SET_WCACHE 0x032b /* change write cache enable-disable */ |
419 | #define HDIO_SET_ACOUSTIC 0x032c /* change acoustic behavior */ | 421 | #define HDIO_SET_ACOUSTIC 0x032c /* change acoustic behavior */ |
420 | #define HDIO_SET_BUSSTATE 0x032d /* set the bus state of the hwif */ | 422 | #define HDIO_SET_BUSSTATE 0x032d /* set the bus state of the hwif */ |
421 | #define HDIO_SET_QDMA 0x032e /* change use-qdma flag */ | 423 | #define HDIO_SET_QDMA 0x032e /* change use-qdma flag */ |
422 | #define HDIO_SET_ADDRESS 0x032f /* change lba addressing modes */ | 424 | #define HDIO_SET_ADDRESS 0x032f /* change lba addressing modes */ |
423 | 425 | ||
424 | /* bus states */ | 426 | /* bus states */ |
425 | enum { | 427 | enum { |
426 | BUSSTATE_OFF = 0, | 428 | BUSSTATE_OFF = 0, |
427 | BUSSTATE_ON, | 429 | BUSSTATE_ON, |
428 | BUSSTATE_TRISTATE | 430 | BUSSTATE_TRISTATE |
429 | }; | 431 | }; |
430 | 432 | ||
431 | /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x033n/0x033n */ | 433 | /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x033n/0x033n */ |
432 | /* 0x330 is reserved - used to be HDIO_GETGEO_BIG */ | 434 | /* 0x330 is reserved - used to be HDIO_GETGEO_BIG */ |
433 | /* 0x331 is reserved - used to be HDIO_GETGEO_BIG_RAW */ | 435 | /* 0x331 is reserved - used to be HDIO_GETGEO_BIG_RAW */ |
434 | /* 0x338 is reserved - used to be HDIO_SET_IDE_SCSI */ | 436 | /* 0x338 is reserved - used to be HDIO_SET_IDE_SCSI */ |
435 | /* 0x339 is reserved - used to be HDIO_SET_SCSI_IDE */ | 437 | /* 0x339 is reserved - used to be HDIO_SET_SCSI_IDE */ |
436 | 438 | ||
437 | #define __NEW_HD_DRIVE_ID | 439 | #define __NEW_HD_DRIVE_ID |
438 | 440 | ||
439 | /* | 441 | /* |
440 | * Structure returned by HDIO_GET_IDENTITY, as per ANSI NCITS ATA6 rev.1b spec. | 442 | * Structure returned by HDIO_GET_IDENTITY, as per ANSI NCITS ATA6 rev.1b spec. |
441 | * | 443 | * |
442 | * If you change something here, please remember to update fix_driveid() in | 444 | * If you change something here, please remember to update fix_driveid() in |
443 | * ide/probe.c. | 445 | * ide/probe.c. |
444 | */ | 446 | */ |
445 | struct hd_driveid { | 447 | struct hd_driveid { |
446 | unsigned short config; /* lots of obsolete bit flags */ | 448 | unsigned short config; /* lots of obsolete bit flags */ |
447 | unsigned short cyls; /* Obsolete, "physical" cyls */ | 449 | unsigned short cyls; /* Obsolete, "physical" cyls */ |
448 | unsigned short reserved2; /* reserved (word 2) */ | 450 | unsigned short reserved2; /* reserved (word 2) */ |
449 | unsigned short heads; /* Obsolete, "physical" heads */ | 451 | unsigned short heads; /* Obsolete, "physical" heads */ |
450 | unsigned short track_bytes; /* unformatted bytes per track */ | 452 | unsigned short track_bytes; /* unformatted bytes per track */ |
451 | unsigned short sector_bytes; /* unformatted bytes per sector */ | 453 | unsigned short sector_bytes; /* unformatted bytes per sector */ |
452 | unsigned short sectors; /* Obsolete, "physical" sectors per track */ | 454 | unsigned short sectors; /* Obsolete, "physical" sectors per track */ |
453 | unsigned short vendor0; /* vendor unique */ | 455 | unsigned short vendor0; /* vendor unique */ |
454 | unsigned short vendor1; /* vendor unique */ | 456 | unsigned short vendor1; /* vendor unique */ |
455 | unsigned short vendor2; /* Retired vendor unique */ | 457 | unsigned short vendor2; /* Retired vendor unique */ |
456 | unsigned char serial_no[20]; /* 0 = not_specified */ | 458 | unsigned char serial_no[20]; /* 0 = not_specified */ |
457 | unsigned short buf_type; /* Retired */ | 459 | unsigned short buf_type; /* Retired */ |
458 | unsigned short buf_size; /* Retired, 512 byte increments | 460 | unsigned short buf_size; /* Retired, 512 byte increments |
459 | * 0 = not_specified | 461 | * 0 = not_specified |
460 | */ | 462 | */ |
461 | unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */ | 463 | unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */ |
462 | unsigned char fw_rev[8]; /* 0 = not_specified */ | 464 | unsigned char fw_rev[8]; /* 0 = not_specified */ |
463 | unsigned char model[40]; /* 0 = not_specified */ | 465 | unsigned char model[40]; /* 0 = not_specified */ |
464 | unsigned char max_multsect; /* 0=not_implemented */ | 466 | unsigned char max_multsect; /* 0=not_implemented */ |
465 | unsigned char vendor3; /* vendor unique */ | 467 | unsigned char vendor3; /* vendor unique */ |
466 | unsigned short dword_io; /* 0=not_implemented; 1=implemented */ | 468 | unsigned short dword_io; /* 0=not_implemented; 1=implemented */ |
467 | unsigned char vendor4; /* vendor unique */ | 469 | unsigned char vendor4; /* vendor unique */ |
468 | unsigned char capability; /* (upper byte of word 49) | 470 | unsigned char capability; /* (upper byte of word 49) |
469 | * 3: IORDYsup | 471 | * 3: IORDYsup |
470 | * 2: IORDYsw | 472 | * 2: IORDYsw |
471 | * 1: LBA | 473 | * 1: LBA |
472 | * 0: DMA | 474 | * 0: DMA |
473 | */ | 475 | */ |
474 | unsigned short reserved50; /* reserved (word 50) */ | 476 | unsigned short reserved50; /* reserved (word 50) */ |
475 | unsigned char vendor5; /* Obsolete, vendor unique */ | 477 | unsigned char vendor5; /* Obsolete, vendor unique */ |
476 | unsigned char tPIO; /* Obsolete, 0=slow, 1=medium, 2=fast */ | 478 | unsigned char tPIO; /* Obsolete, 0=slow, 1=medium, 2=fast */ |
477 | unsigned char vendor6; /* Obsolete, vendor unique */ | 479 | unsigned char vendor6; /* Obsolete, vendor unique */ |
478 | unsigned char tDMA; /* Obsolete, 0=slow, 1=medium, 2=fast */ | 480 | unsigned char tDMA; /* Obsolete, 0=slow, 1=medium, 2=fast */ |
479 | unsigned short field_valid; /* (word 53) | 481 | unsigned short field_valid; /* (word 53) |
480 | * 2: ultra_ok word 88 | 482 | * 2: ultra_ok word 88 |
481 | * 1: eide_ok words 64-70 | 483 | * 1: eide_ok words 64-70 |
482 | * 0: cur_ok words 54-58 | 484 | * 0: cur_ok words 54-58 |
483 | */ | 485 | */ |
484 | unsigned short cur_cyls; /* Obsolete, logical cylinders */ | 486 | unsigned short cur_cyls; /* Obsolete, logical cylinders */ |
485 | unsigned short cur_heads; /* Obsolete, l heads */ | 487 | unsigned short cur_heads; /* Obsolete, l heads */ |
486 | unsigned short cur_sectors; /* Obsolete, l sectors per track */ | 488 | unsigned short cur_sectors; /* Obsolete, l sectors per track */ |
487 | unsigned short cur_capacity0; /* Obsolete, l total sectors on drive */ | 489 | unsigned short cur_capacity0; /* Obsolete, l total sectors on drive */ |
488 | unsigned short cur_capacity1; /* Obsolete, (2 words, misaligned int) */ | 490 | unsigned short cur_capacity1; /* Obsolete, (2 words, misaligned int) */ |
489 | unsigned char multsect; /* current multiple sector count */ | 491 | unsigned char multsect; /* current multiple sector count */ |
490 | unsigned char multsect_valid; /* when (bit0==1) multsect is ok */ | 492 | unsigned char multsect_valid; /* when (bit0==1) multsect is ok */ |
491 | unsigned int lba_capacity; /* Obsolete, total number of sectors */ | 493 | unsigned int lba_capacity; /* Obsolete, total number of sectors */ |
492 | unsigned short dma_1word; /* Obsolete, single-word dma info */ | 494 | unsigned short dma_1word; /* Obsolete, single-word dma info */ |
493 | unsigned short dma_mword; /* multiple-word dma info */ | 495 | unsigned short dma_mword; /* multiple-word dma info */ |
494 | unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */ | 496 | unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */ |
495 | unsigned short eide_dma_min; /* min mword dma cycle time (ns) */ | 497 | unsigned short eide_dma_min; /* min mword dma cycle time (ns) */ |
496 | unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */ | 498 | unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */ |
497 | unsigned short eide_pio; /* min cycle time (ns), no IORDY */ | 499 | unsigned short eide_pio; /* min cycle time (ns), no IORDY */ |
498 | unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */ | 500 | unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */ |
499 | unsigned short words69_70[2]; /* reserved words 69-70 | 501 | unsigned short words69_70[2]; /* reserved words 69-70 |
500 | * future command overlap and queuing | 502 | * future command overlap and queuing |
501 | */ | 503 | */ |
502 | /* HDIO_GET_IDENTITY currently returns only words 0 through 70 */ | 504 | /* HDIO_GET_IDENTITY currently returns only words 0 through 70 */ |
503 | unsigned short words71_74[4]; /* reserved words 71-74 | 505 | unsigned short words71_74[4]; /* reserved words 71-74 |
504 | * for IDENTIFY PACKET DEVICE command | 506 | * for IDENTIFY PACKET DEVICE command |
505 | */ | 507 | */ |
506 | unsigned short queue_depth; /* (word 75) | 508 | unsigned short queue_depth; /* (word 75) |
507 | * 15:5 reserved | 509 | * 15:5 reserved |
508 | * 4:0 Maximum queue depth -1 | 510 | * 4:0 Maximum queue depth -1 |
509 | */ | 511 | */ |
510 | unsigned short words76_79[4]; /* reserved words 76-79 */ | 512 | unsigned short words76_79[4]; /* reserved words 76-79 */ |
511 | unsigned short major_rev_num; /* (word 80) */ | 513 | unsigned short major_rev_num; /* (word 80) */ |
512 | unsigned short minor_rev_num; /* (word 81) */ | 514 | unsigned short minor_rev_num; /* (word 81) */ |
513 | unsigned short command_set_1; /* (word 82) supported | 515 | unsigned short command_set_1; /* (word 82) supported |
514 | * 15: Obsolete | 516 | * 15: Obsolete |
515 | * 14: NOP command | 517 | * 14: NOP command |
516 | * 13: READ_BUFFER | 518 | * 13: READ_BUFFER |
517 | * 12: WRITE_BUFFER | 519 | * 12: WRITE_BUFFER |
518 | * 11: Obsolete | 520 | * 11: Obsolete |
519 | * 10: Host Protected Area | 521 | * 10: Host Protected Area |
520 | * 9: DEVICE Reset | 522 | * 9: DEVICE Reset |
521 | * 8: SERVICE Interrupt | 523 | * 8: SERVICE Interrupt |
522 | * 7: Release Interrupt | 524 | * 7: Release Interrupt |
523 | * 6: look-ahead | 525 | * 6: look-ahead |
524 | * 5: write cache | 526 | * 5: write cache |
525 | * 4: PACKET Command | 527 | * 4: PACKET Command |
526 | * 3: Power Management Feature Set | 528 | * 3: Power Management Feature Set |
527 | * 2: Removable Feature Set | 529 | * 2: Removable Feature Set |
528 | * 1: Security Feature Set | 530 | * 1: Security Feature Set |
529 | * 0: SMART Feature Set | 531 | * 0: SMART Feature Set |
530 | */ | 532 | */ |
531 | unsigned short command_set_2; /* (word 83) | 533 | unsigned short command_set_2; /* (word 83) |
532 | * 15: Shall be ZERO | 534 | * 15: Shall be ZERO |
533 | * 14: Shall be ONE | 535 | * 14: Shall be ONE |
534 | * 13: FLUSH CACHE EXT | 536 | * 13: FLUSH CACHE EXT |
535 | * 12: FLUSH CACHE | 537 | * 12: FLUSH CACHE |
536 | * 11: Device Configuration Overlay | 538 | * 11: Device Configuration Overlay |
537 | * 10: 48-bit Address Feature Set | 539 | * 10: 48-bit Address Feature Set |
538 | * 9: Automatic Acoustic Management | 540 | * 9: Automatic Acoustic Management |
539 | * 8: SET MAX security | 541 | * 8: SET MAX security |
540 | * 7: reserved 1407DT PARTIES | 542 | * 7: reserved 1407DT PARTIES |
541 | * 6: SetF sub-command Power-Up | 543 | * 6: SetF sub-command Power-Up |
542 | * 5: Power-Up in Standby Feature Set | 544 | * 5: Power-Up in Standby Feature Set |
543 | * 4: Removable Media Notification | 545 | * 4: Removable Media Notification |
544 | * 3: APM Feature Set | 546 | * 3: APM Feature Set |
545 | * 2: CFA Feature Set | 547 | * 2: CFA Feature Set |
546 | * 1: READ/WRITE DMA QUEUED | 548 | * 1: READ/WRITE DMA QUEUED |
547 | * 0: Download MicroCode | 549 | * 0: Download MicroCode |
548 | */ | 550 | */ |
549 | unsigned short cfsse; /* (word 84) | 551 | unsigned short cfsse; /* (word 84) |
550 | * cmd set-feature supported extensions | 552 | * cmd set-feature supported extensions |
551 | * 15: Shall be ZERO | 553 | * 15: Shall be ZERO |
552 | * 14: Shall be ONE | 554 | * 14: Shall be ONE |
553 | * 13:6 reserved | 555 | * 13:6 reserved |
554 | * 5: General Purpose Logging | 556 | * 5: General Purpose Logging |
555 | * 4: Streaming Feature Set | 557 | * 4: Streaming Feature Set |
556 | * 3: Media Card Pass Through | 558 | * 3: Media Card Pass Through |
557 | * 2: Media Serial Number Valid | 559 | * 2: Media Serial Number Valid |
558 | * 1: SMART selt-test supported | 560 | * 1: SMART selt-test supported |
559 | * 0: SMART error logging | 561 | * 0: SMART error logging |
560 | */ | 562 | */ |
561 | unsigned short cfs_enable_1; /* (word 85) | 563 | unsigned short cfs_enable_1; /* (word 85) |
562 | * command set-feature enabled | 564 | * command set-feature enabled |
563 | * 15: Obsolete | 565 | * 15: Obsolete |
564 | * 14: NOP command | 566 | * 14: NOP command |
565 | * 13: READ_BUFFER | 567 | * 13: READ_BUFFER |
566 | * 12: WRITE_BUFFER | 568 | * 12: WRITE_BUFFER |
567 | * 11: Obsolete | 569 | * 11: Obsolete |
568 | * 10: Host Protected Area | 570 | * 10: Host Protected Area |
569 | * 9: DEVICE Reset | 571 | * 9: DEVICE Reset |
570 | * 8: SERVICE Interrupt | 572 | * 8: SERVICE Interrupt |
571 | * 7: Release Interrupt | 573 | * 7: Release Interrupt |
572 | * 6: look-ahead | 574 | * 6: look-ahead |
573 | * 5: write cache | 575 | * 5: write cache |
574 | * 4: PACKET Command | 576 | * 4: PACKET Command |
575 | * 3: Power Management Feature Set | 577 | * 3: Power Management Feature Set |
576 | * 2: Removable Feature Set | 578 | * 2: Removable Feature Set |
577 | * 1: Security Feature Set | 579 | * 1: Security Feature Set |
578 | * 0: SMART Feature Set | 580 | * 0: SMART Feature Set |
579 | */ | 581 | */ |
580 | unsigned short cfs_enable_2; /* (word 86) | 582 | unsigned short cfs_enable_2; /* (word 86) |
581 | * command set-feature enabled | 583 | * command set-feature enabled |
582 | * 15: Shall be ZERO | 584 | * 15: Shall be ZERO |
583 | * 14: Shall be ONE | 585 | * 14: Shall be ONE |
584 | * 13: FLUSH CACHE EXT | 586 | * 13: FLUSH CACHE EXT |
585 | * 12: FLUSH CACHE | 587 | * 12: FLUSH CACHE |
586 | * 11: Device Configuration Overlay | 588 | * 11: Device Configuration Overlay |
587 | * 10: 48-bit Address Feature Set | 589 | * 10: 48-bit Address Feature Set |
588 | * 9: Automatic Acoustic Management | 590 | * 9: Automatic Acoustic Management |
589 | * 8: SET MAX security | 591 | * 8: SET MAX security |
590 | * 7: reserved 1407DT PARTIES | 592 | * 7: reserved 1407DT PARTIES |
591 | * 6: SetF sub-command Power-Up | 593 | * 6: SetF sub-command Power-Up |
592 | * 5: Power-Up in Standby Feature Set | 594 | * 5: Power-Up in Standby Feature Set |
593 | * 4: Removable Media Notification | 595 | * 4: Removable Media Notification |
594 | * 3: APM Feature Set | 596 | * 3: APM Feature Set |
595 | * 2: CFA Feature Set | 597 | * 2: CFA Feature Set |
596 | * 1: READ/WRITE DMA QUEUED | 598 | * 1: READ/WRITE DMA QUEUED |
597 | * 0: Download MicroCode | 599 | * 0: Download MicroCode |
598 | */ | 600 | */ |
599 | unsigned short csf_default; /* (word 87) | 601 | unsigned short csf_default; /* (word 87) |
600 | * command set-feature default | 602 | * command set-feature default |
601 | * 15: Shall be ZERO | 603 | * 15: Shall be ZERO |
602 | * 14: Shall be ONE | 604 | * 14: Shall be ONE |
603 | * 13:6 reserved | 605 | * 13:6 reserved |
604 | * 5: General Purpose Logging enabled | 606 | * 5: General Purpose Logging enabled |
605 | * 4: Valid CONFIGURE STREAM executed | 607 | * 4: Valid CONFIGURE STREAM executed |
606 | * 3: Media Card Pass Through enabled | 608 | * 3: Media Card Pass Through enabled |
607 | * 2: Media Serial Number Valid | 609 | * 2: Media Serial Number Valid |
608 | * 1: SMART selt-test supported | 610 | * 1: SMART selt-test supported |
609 | * 0: SMART error logging | 611 | * 0: SMART error logging |
610 | */ | 612 | */ |
611 | unsigned short dma_ultra; /* (word 88) */ | 613 | unsigned short dma_ultra; /* (word 88) */ |
612 | unsigned short trseuc; /* time required for security erase */ | 614 | unsigned short trseuc; /* time required for security erase */ |
613 | unsigned short trsEuc; /* time required for enhanced erase */ | 615 | unsigned short trsEuc; /* time required for enhanced erase */ |
614 | unsigned short CurAPMvalues; /* current APM values */ | 616 | unsigned short CurAPMvalues; /* current APM values */ |
615 | unsigned short mprc; /* master password revision code */ | 617 | unsigned short mprc; /* master password revision code */ |
616 | unsigned short hw_config; /* hardware config (word 93) | 618 | unsigned short hw_config; /* hardware config (word 93) |
617 | * 15: Shall be ZERO | 619 | * 15: Shall be ZERO |
618 | * 14: Shall be ONE | 620 | * 14: Shall be ONE |
619 | * 13: | 621 | * 13: |
620 | * 12: | 622 | * 12: |
621 | * 11: | 623 | * 11: |
622 | * 10: | 624 | * 10: |
623 | * 9: | 625 | * 9: |
624 | * 8: | 626 | * 8: |
625 | * 7: | 627 | * 7: |
626 | * 6: | 628 | * 6: |
627 | * 5: | 629 | * 5: |
628 | * 4: | 630 | * 4: |
629 | * 3: | 631 | * 3: |
630 | * 2: | 632 | * 2: |
631 | * 1: | 633 | * 1: |
632 | * 0: Shall be ONE | 634 | * 0: Shall be ONE |
633 | */ | 635 | */ |
634 | unsigned short acoustic; /* (word 94) | 636 | unsigned short acoustic; /* (word 94) |
635 | * 15:8 Vendor's recommended value | 637 | * 15:8 Vendor's recommended value |
636 | * 7:0 current value | 638 | * 7:0 current value |
637 | */ | 639 | */ |
638 | unsigned short msrqs; /* min stream request size */ | 640 | unsigned short msrqs; /* min stream request size */ |
639 | unsigned short sxfert; /* stream transfer time */ | 641 | unsigned short sxfert; /* stream transfer time */ |
640 | unsigned short sal; /* stream access latency */ | 642 | unsigned short sal; /* stream access latency */ |
641 | unsigned int spg; /* stream performance granularity */ | 643 | unsigned int spg; /* stream performance granularity */ |
642 | unsigned long long lba_capacity_2;/* 48-bit total number of sectors */ | 644 | unsigned long long lba_capacity_2;/* 48-bit total number of sectors */ |
643 | unsigned short words104_125[22];/* reserved words 104-125 */ | 645 | unsigned short words104_125[22];/* reserved words 104-125 */ |
644 | unsigned short last_lun; /* (word 126) */ | 646 | unsigned short last_lun; /* (word 126) */ |
645 | unsigned short word127; /* (word 127) Feature Set | 647 | unsigned short word127; /* (word 127) Feature Set |
646 | * Removable Media Notification | 648 | * Removable Media Notification |
647 | * 15:2 reserved | 649 | * 15:2 reserved |
648 | * 1:0 00 = not supported | 650 | * 1:0 00 = not supported |
649 | * 01 = supported | 651 | * 01 = supported |
650 | * 10 = reserved | 652 | * 10 = reserved |
651 | * 11 = reserved | 653 | * 11 = reserved |
652 | */ | 654 | */ |
653 | unsigned short dlf; /* (word 128) | 655 | unsigned short dlf; /* (word 128) |
654 | * device lock function | 656 | * device lock function |
655 | * 15:9 reserved | 657 | * 15:9 reserved |
656 | * 8 security level 1:max 0:high | 658 | * 8 security level 1:max 0:high |
657 | * 7:6 reserved | 659 | * 7:6 reserved |
658 | * 5 enhanced erase | 660 | * 5 enhanced erase |
659 | * 4 expire | 661 | * 4 expire |
660 | * 3 frozen | 662 | * 3 frozen |
661 | * 2 locked | 663 | * 2 locked |
662 | * 1 en/disabled | 664 | * 1 en/disabled |
663 | * 0 capability | 665 | * 0 capability |
664 | */ | 666 | */ |
665 | unsigned short csfo; /* (word 129) | 667 | unsigned short csfo; /* (word 129) |
666 | * current set features options | 668 | * current set features options |
667 | * 15:4 reserved | 669 | * 15:4 reserved |
668 | * 3: auto reassign | 670 | * 3: auto reassign |
669 | * 2: reverting | 671 | * 2: reverting |
670 | * 1: read-look-ahead | 672 | * 1: read-look-ahead |
671 | * 0: write cache | 673 | * 0: write cache |
672 | */ | 674 | */ |
673 | unsigned short words130_155[26];/* reserved vendor words 130-155 */ | 675 | unsigned short words130_155[26];/* reserved vendor words 130-155 */ |
674 | unsigned short word156; /* reserved vendor word 156 */ | 676 | unsigned short word156; /* reserved vendor word 156 */ |
675 | unsigned short words157_159[3];/* reserved vendor words 157-159 */ | 677 | unsigned short words157_159[3];/* reserved vendor words 157-159 */ |
676 | unsigned short cfa_power; /* (word 160) CFA Power Mode | 678 | unsigned short cfa_power; /* (word 160) CFA Power Mode |
677 | * 15 word 160 supported | 679 | * 15 word 160 supported |
678 | * 14 reserved | 680 | * 14 reserved |
679 | * 13 | 681 | * 13 |
680 | * 12 | 682 | * 12 |
681 | * 11:0 | 683 | * 11:0 |
682 | */ | 684 | */ |
683 | unsigned short words161_175[15];/* Reserved for CFA */ | 685 | unsigned short words161_175[15];/* Reserved for CFA */ |
684 | unsigned short words176_205[30];/* Current Media Serial Number */ | 686 | unsigned short words176_205[30];/* Current Media Serial Number */ |
685 | unsigned short words206_254[49];/* reserved words 206-254 */ | 687 | unsigned short words206_254[49];/* reserved words 206-254 */ |
686 | unsigned short integrity_word; /* (word 255) | 688 | unsigned short integrity_word; /* (word 255) |
687 | * 15:8 Checksum | 689 | * 15:8 Checksum |
688 | * 7:0 Signature | 690 | * 7:0 Signature |
689 | */ | 691 | */ |
690 | }; | 692 | }; |
691 | 693 | ||
692 | /* | 694 | /* |
693 | * IDE "nice" flags. These are used on a per drive basis to determine | 695 | * IDE "nice" flags. These are used on a per drive basis to determine |
694 | * when to be nice and give more bandwidth to the other devices which | 696 | * when to be nice and give more bandwidth to the other devices which |
695 | * share the same IDE bus. | 697 | * share the same IDE bus. |
696 | */ | 698 | */ |
697 | #define IDE_NICE_DSC_OVERLAP (0) /* per the DSC overlap protocol */ | 699 | #define IDE_NICE_DSC_OVERLAP (0) /* per the DSC overlap protocol */ |
698 | #define IDE_NICE_ATAPI_OVERLAP (1) /* not supported yet */ | 700 | #define IDE_NICE_ATAPI_OVERLAP (1) /* not supported yet */ |
699 | #define IDE_NICE_0 (2) /* when sure that it won't affect us */ | 701 | #define IDE_NICE_0 (2) /* when sure that it won't affect us */ |
700 | #define IDE_NICE_1 (3) /* when probably won't affect us much */ | 702 | #define IDE_NICE_1 (3) /* when probably won't affect us much */ |
701 | #define IDE_NICE_2 (4) /* when we know it's on our expense */ | 703 | #define IDE_NICE_2 (4) /* when we know it's on our expense */ |
702 | 704 |