ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / linux / atapi.h
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);