Subversion Repositories shark

Rev

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);