Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
422 | giacomo | 1 | /**** vi:set ts=8 sts=8 sw=8:************************************************ |
2 | * |
||
3 | * Copyright (C) 2002 Marcin Dalecki <martin@dalecki.de> |
||
4 | * |
||
5 | * This program is free software; you can redistribute it and/or modify it |
||
6 | * under the terms of the GNU General Public License version 2 as published by |
||
7 | * the Free Software Foundation. |
||
8 | * |
||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT |
||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
||
12 | * more details. |
||
13 | */ |
||
14 | |||
15 | #include <linux/types.h> |
||
16 | #include <asm/byteorder.h> |
||
17 | |||
18 | /* |
||
19 | * With each packet command, we allocate a buffer. |
||
20 | * This is used for several packet |
||
21 | * commands (Not for READ/WRITE commands). |
||
22 | */ |
||
23 | #define IDEFLOPPY_PC_BUFFER_SIZE 256 |
||
24 | #define IDETAPE_PC_BUFFER_SIZE 256 |
||
25 | |||
26 | /* |
||
27 | * Packet flags bits. |
||
28 | */ |
||
29 | |||
30 | #define PC_ABORT 0 /* set when an error is considered normal - we won't retry */ |
||
31 | #define PC_WAIT_FOR_DSC 1 /* 1 when polling for DSC on a media access command */ |
||
32 | #define PC_DMA_RECOMMENDED 2 /* 1 when we prefer to use DMA if possible */ |
||
33 | #define PC_DMA_IN_PROGRESS 3 /* 1 while DMA in progress */ |
||
34 | #define PC_DMA_ERROR 4 /* 1 when encountered problem during DMA */ |
||
35 | #define PC_WRITING 5 /* data direction */ |
||
36 | #define PC_SUPPRESS_ERROR 6 /* suppress error reporting */ |
||
37 | #define PC_TRANSFORM 7 /* transform SCSI commands */ |
||
38 | |||
39 | /* This struct get's shared between different drivers. |
||
40 | */ |
||
41 | struct atapi_packet_command { |
||
42 | u8 c[12]; /* Actual packet bytes */ |
||
43 | char *buffer; /* Data buffer */ |
||
44 | int buffer_size; /* Size of our data buffer */ |
||
45 | char *current_position; /* Pointer into the above buffer */ |
||
46 | int request_transfer; /* Bytes to transfer */ |
||
47 | int actually_transferred; /* Bytes actually transferred */ |
||
48 | |||
49 | unsigned long flags; /* Status/Action bit flags: long for set_bit */ |
||
50 | |||
51 | /* FIXME: the following is ugly as hell, but the only way we can start |
||
52 | * actually to unify the code. |
||
53 | */ |
||
54 | /* driver specific data. */ |
||
55 | /* floppy/tape */ |
||
56 | int retries; /* On each retry, we increment retries */ |
||
57 | int error; /* Error code */ |
||
58 | char *b_data; /* Pointer which runs on the buffers */ |
||
59 | unsigned int b_count; /* Missing/Available data on the current buffer */ |
||
60 | u8 pc_buffer[IDEFLOPPY_PC_BUFFER_SIZE]; /* Temporary buffer */ |
||
61 | /* Called when this packet command is completed */ |
||
62 | void (*callback) (struct ata_device *, struct request *); |
||
63 | |||
64 | /* only tape */ |
||
65 | struct bio *bio; |
||
66 | |||
67 | /* only scsi */ |
||
68 | struct { |
||
69 | unsigned int b_count; /* Bytes transferred from current entry */ |
||
70 | struct scatterlist *sg; /* Scatter gather table */ |
||
71 | struct scsi_cmnd *scsi_cmd; /* SCSI command */ |
||
72 | void (*done)(struct scsi_cmnd *); /* Scsi completion routine */ |
||
73 | unsigned long timeout; /* Command timeout */ |
||
74 | } s; |
||
75 | }; |
||
76 | |||
77 | /* |
||
78 | * ATAPI Status Register. |
||
79 | */ |
||
80 | typedef union { |
||
81 | u8 all : 8; |
||
82 | struct { |
||
83 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
84 | u8 check : 1; /* Error occurred */ |
||
85 | u8 idx : 1; /* Reserved */ |
||
86 | u8 corr : 1; /* Correctable error occurred */ |
||
87 | u8 drq : 1; /* Data is request by the device */ |
||
88 | u8 dsc : 1; /* Media access command finished / Buffer availability */ |
||
89 | u8 reserved5 : 1; /* Reserved */ |
||
90 | u8 drdy : 1; /* Ignored for ATAPI commands (ready to accept ATA command) */ |
||
91 | u8 bsy : 1; /* The device has access to the command block */ |
||
92 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
93 | u8 bsy : 1; |
||
94 | u8 drdy : 1; |
||
95 | u8 reserved5 : 1; |
||
96 | u8 dsc : 1; |
||
97 | u8 drq : 1; |
||
98 | u8 corr : 1; |
||
99 | u8 idx : 1; |
||
100 | u8 check : 1; |
||
101 | #else |
||
102 | #error "Please fix <asm/byteorder.h>" |
||
103 | #endif |
||
104 | } b; |
||
105 | } atapi_status_reg_t; |
||
106 | |||
107 | /* |
||
108 | * ATAPI error register. |
||
109 | */ |
||
110 | typedef union { |
||
111 | u8 all : 8; |
||
112 | struct { |
||
113 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
114 | u8 ili : 1; /* Illegal Length Indication */ |
||
115 | u8 eom : 1; /* End Of Media Detected */ |
||
116 | u8 abrt : 1; /* Aborted command - As defined by ATA */ |
||
117 | u8 mcr : 1; /* Media Change Requested - As defined by ATA */ |
||
118 | u8 sense_key : 4; /* Sense key of the last failed packet command */ |
||
119 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
120 | u8 sense_key : 4; |
||
121 | u8 mcr : 1; |
||
122 | u8 abrt : 1; |
||
123 | u8 eom : 1; |
||
124 | u8 ili : 1; |
||
125 | #else |
||
126 | #error "Please fix <asm/byteorder.h>" |
||
127 | #endif |
||
128 | } b; |
||
129 | } atapi_error_reg_t; |
||
130 | |||
131 | /* Currently unused, but please do not remove. --bkz */ |
||
132 | /* |
||
133 | * ATAPI Feature Register. |
||
134 | */ |
||
135 | typedef union { |
||
136 | u8 all : 8; |
||
137 | struct { |
||
138 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
139 | u8 dma : 1; /* Using DMA or PIO */ |
||
140 | u8 reserved321 : 3; /* Reserved */ |
||
141 | u8 reserved654 : 3; /* Reserved (Tag Type) */ |
||
142 | u8 reserved7 : 1; /* Reserved */ |
||
143 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
144 | u8 reserved7 : 1; |
||
145 | u8 reserved654 : 3; |
||
146 | u8 reserved321 : 3; |
||
147 | u8 dma : 1; |
||
148 | #else |
||
149 | #error "Please fix <asm/byteorder.h>" |
||
150 | #endif |
||
151 | } b; |
||
152 | } atapi_feature_reg_t; |
||
153 | |||
154 | /* |
||
155 | * ATAPI Byte Count Register. |
||
156 | */ |
||
157 | typedef union { |
||
158 | u16 all : 16; |
||
159 | struct { |
||
160 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
161 | u8 low; /* LSB */ |
||
162 | u8 high; /* MSB */ |
||
163 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
164 | u8 high; |
||
165 | u8 low; |
||
166 | #else |
||
167 | #error "Please fix <asm/byteorder.h>" |
||
168 | #endif |
||
169 | } b; |
||
170 | } atapi_bcount_reg_t; |
||
171 | |||
172 | /* |
||
173 | * ATAPI Interrupt Reason Register. |
||
174 | */ |
||
175 | typedef union { |
||
176 | u8 all : 8; |
||
177 | struct { |
||
178 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
179 | u8 cod : 1; /* Information transferred is command (1) or data (0) */ |
||
180 | u8 io : 1; /* The device requests us to read (1) or write (0) */ |
||
181 | u8 reserved : 6; /* Reserved */ |
||
182 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
183 | u8 reserved : 6; |
||
184 | u8 io : 1; |
||
185 | u8 cod : 1; |
||
186 | #else |
||
187 | #error "Please fix <asm/byteorder.h>" |
||
188 | #endif |
||
189 | } b; |
||
190 | } atapi_ireason_reg_t; |
||
191 | |||
192 | /* Currently unused, but please do not remove. --bkz */ |
||
193 | /* |
||
194 | * ATAPI Drive Select Register. |
||
195 | */ |
||
196 | typedef union { |
||
197 | u8 all :8; |
||
198 | struct { |
||
199 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
200 | u8 sam_lun :3; /* Logical unit number */ |
||
201 | u8 reserved3 :1; /* Reserved */ |
||
202 | u8 drv :1; /* The responding drive will be drive 0 (0) or drive 1 (1) */ |
||
203 | u8 one5 :1; /* Should be set to 1 */ |
||
204 | u8 reserved6 :1; /* Reserved */ |
||
205 | u8 one7 :1; /* Should be set to 1 */ |
||
206 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
207 | u8 one7 :1; |
||
208 | u8 reserved6 :1; |
||
209 | u8 one5 :1; |
||
210 | u8 drv :1; |
||
211 | u8 reserved3 :1; |
||
212 | u8 sam_lun :3; |
||
213 | #else |
||
214 | #error "Please fix <asm/byteorder.h>" |
||
215 | #endif |
||
216 | } b; |
||
217 | } atapi_drivesel_reg_t; |
||
218 | |||
219 | /* Currently unused, but please do not remove. --bkz */ |
||
220 | /* |
||
221 | * ATAPI Device Control Register. |
||
222 | */ |
||
223 | typedef union { |
||
224 | u8 all : 8; |
||
225 | struct { |
||
226 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
227 | u8 zero0 : 1; /* Should be set to zero */ |
||
228 | u8 nien : 1; /* Device interrupt is disabled (1) or enabled (0) */ |
||
229 | u8 srst : 1; /* ATA software reset. ATAPI devices should use the new ATAPI srst. */ |
||
230 | u8 one3 : 1; /* Should be set to 1 */ |
||
231 | u8 reserved4567 : 4; /* Reserved */ |
||
232 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
233 | u8 reserved4567 : 4; |
||
234 | u8 one3 : 1; |
||
235 | u8 srst : 1; |
||
236 | u8 nien : 1; |
||
237 | u8 zero0 : 1; |
||
238 | #else |
||
239 | #error "Please fix <asm/byteorder.h>" |
||
240 | #endif |
||
241 | } b; |
||
242 | } atapi_control_reg_t; |
||
243 | |||
244 | /* |
||
245 | * The following is used to format the general configuration word |
||
246 | * of the ATAPI IDENTIFY DEVICE command. |
||
247 | */ |
||
248 | struct atapi_id_gcw { |
||
249 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
250 | u8 packet_size : 2; /* Packet Size */ |
||
251 | u8 reserved234 : 3; /* Reserved */ |
||
252 | u8 drq_type : 2; /* Command packet DRQ type */ |
||
253 | u8 removable : 1; /* Removable media */ |
||
254 | u8 device_type : 5; /* Device type */ |
||
255 | u8 reserved13 : 1; /* Reserved */ |
||
256 | u8 protocol : 2; /* Protocol type */ |
||
257 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
258 | u8 protocol : 2; |
||
259 | u8 reserved13 : 1; |
||
260 | u8 device_type : 5; |
||
261 | u8 removable : 1; |
||
262 | u8 drq_type : 2; |
||
263 | u8 reserved234 : 3; |
||
264 | u8 packet_size : 2; |
||
265 | #else |
||
266 | #error "Please fix <asm/byteorder.h>" |
||
267 | #endif |
||
268 | }; |
||
269 | |||
270 | /* |
||
271 | * INQUIRY packet command - Data Format. |
||
272 | */ |
||
273 | typedef struct { |
||
274 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
275 | u8 device_type : 5; /* Peripheral Device Type */ |
||
276 | u8 reserved0_765 : 3; /* Peripheral Qualifier - Reserved */ |
||
277 | u8 reserved1_6t0 : 7; /* Reserved */ |
||
278 | u8 rmb : 1; /* Removable Medium Bit */ |
||
279 | u8 ansi_version : 3; /* ANSI Version */ |
||
280 | u8 ecma_version : 3; /* ECMA Version */ |
||
281 | u8 iso_version : 2; /* ISO Version */ |
||
282 | u8 response_format : 4; /* Response Data Format */ |
||
283 | u8 reserved3_45 : 2; /* Reserved */ |
||
284 | u8 reserved3_6 : 1; /* TrmIOP - Reserved */ |
||
285 | u8 reserved3_7 : 1; /* AENC - Reserved */ |
||
286 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
287 | u8 reserved0_765 : 3; |
||
288 | u8 device_type : 5; |
||
289 | u8 rmb : 1; |
||
290 | u8 reserved1_6t0 : 7; |
||
291 | u8 iso_version : 2; |
||
292 | u8 ecma_version : 3; |
||
293 | u8 ansi_version : 3; |
||
294 | u8 reserved3_7 : 1; |
||
295 | u8 reserved3_6 : 1; |
||
296 | u8 reserved3_45 : 2; |
||
297 | u8 response_format : 4; |
||
298 | #else |
||
299 | #error "Please fix <asm/byteorder.h>" |
||
300 | #endif |
||
301 | u8 additional_length; /* Additional Length (total_length-4) */ |
||
302 | u8 rsv5, rsv6, rsv7; /* Reserved */ |
||
303 | u8 vendor_id[8]; /* Vendor Identification */ |
||
304 | u8 product_id[16]; /* Product Identification */ |
||
305 | u8 revision_level[4]; /* Revision Level */ |
||
306 | u8 vendor_specific[20]; /* Vendor Specific - Optional */ |
||
307 | u8 reserved56t95[40]; /* Reserved - Optional */ |
||
308 | /* Additional information may be returned */ |
||
309 | } atapi_inquiry_result_t; |
||
310 | |||
311 | /* |
||
312 | * REQUEST SENSE packet command result - Data Format. |
||
313 | */ |
||
314 | typedef struct atapi_request_sense { |
||
315 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
316 | u8 error_code : 7; /* Error Code (0x70 - current or 0x71 - deferred) */ |
||
317 | u8 valid : 1; /* The information field conforms to standard */ |
||
318 | u8 reserved1 : 8; /* Reserved (Segment Number) */ |
||
319 | u8 sense_key : 4; /* Sense Key */ |
||
320 | u8 reserved2_4 : 1; /* Reserved */ |
||
321 | u8 ili : 1; /* Incorrect Length Indicator */ |
||
322 | u8 eom : 1; /* End Of Medium */ |
||
323 | u8 filemark : 1; /* Filemark */ |
||
324 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
325 | u8 valid : 1; |
||
326 | u8 error_code : 7; |
||
327 | u8 reserved1 : 8; |
||
328 | u8 filemark : 1; |
||
329 | u8 eom : 1; |
||
330 | u8 ili : 1; |
||
331 | u8 reserved2_4 : 1; |
||
332 | u8 sense_key : 4; |
||
333 | #else |
||
334 | #error "Please fix <asm/byteorder.h>" |
||
335 | #endif |
||
336 | u32 information __attribute__ ((packed)); |
||
337 | u8 asl; /* Additional sense length (n-7) */ |
||
338 | u32 command_specific; /* Additional command specific information */ |
||
339 | u8 asc; /* Additional Sense Code */ |
||
340 | u8 ascq; /* Additional Sense Code Qualifier */ |
||
341 | u8 replaceable_unit_code; /* Field Replaceable Unit Code */ |
||
342 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
||
343 | u8 sk_specific1 : 7; /* Sense Key Specific */ |
||
344 | u8 sksv : 1; /* Sense Key Specific information is valid */ |
||
345 | #elif defined(__BIG_ENDIAN_BITFIELD) |
||
346 | u8 sksv : 1; /* Sense Key Specific information is valid */ |
||
347 | u8 sk_specific1 : 7; /* Sense Key Specific */ |
||
348 | #else |
||
349 | #error "Please fix <asm/byteorder.h>" |
||
350 | #endif |
||
351 | u8 sk_specific[2]; /* Sense Key Specific */ |
||
352 | u8 pad[2]; /* Padding to 20 bytes */ |
||
353 | } atapi_request_sense_result_t; |
||
354 | |||
355 | |||
356 | extern void atapi_init_pc(struct atapi_packet_command *pc); |
||
357 | |||
358 | extern void atapi_discard_data(struct ata_device *, unsigned int); |
||
359 | extern void atapi_write_zeros(struct ata_device *, unsigned int); |
||
360 | |||
361 | extern void atapi_read(struct ata_device *, u8 *, unsigned int); |
||
362 | extern void atapi_write(struct ata_device *, u8 *, unsigned int); |
||
363 | |||
364 | typedef enum { |
||
365 | ide_wait, /* insert rq at end of list, and wait for it */ |
||
366 | ide_preempt, /* insert rq in front of current request */ |
||
367 | ide_end /* insert rq at end of list, but don't wait for it */ |
||
368 | } ide_action_t; |
||
369 | |||
370 | extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t); |