|
@@ -1,892 +0,0 @@
|
1
|
|
-#include "etherboot.h"
|
2
|
|
-#include "timer.h"
|
3
|
|
-#include "pci.h"
|
4
|
|
-#include "isa.h"
|
5
|
|
-#include "disk.h"
|
6
|
|
-
|
7
|
|
-#define BSY_SET_DURING_SPINUP 1
|
8
|
|
-/*
|
9
|
|
- * UBL, The Universal Talkware Boot Loader
|
10
|
|
- * Copyright (C) 2000 Universal Talkware Inc.
|
11
|
|
- * Copyright (C) 2002 Eric Biederman
|
12
|
|
- *
|
13
|
|
- * This program is free software; you can redistribute it and/or modify
|
14
|
|
- * it under the terms of the GNU General Public License as published by
|
15
|
|
- * the Free Software Foundation; either version 2 of the License, or
|
16
|
|
- * (at your option) any later version.
|
17
|
|
- *
|
18
|
|
- * This program is distributed in the hope that it will be useful,
|
19
|
|
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20
|
|
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
21
|
|
- * GNU General Public License for more details.
|
22
|
|
- *
|
23
|
|
- * You should have received a copy of the GNU General Public License
|
24
|
|
- * along with this program; if not, write to the Free Software
|
25
|
|
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
26
|
|
- *
|
27
|
|
- *
|
28
|
|
- */
|
29
|
|
-struct controller {
|
30
|
|
- uint16_t cmd_base;
|
31
|
|
- uint16_t ctrl_base;
|
32
|
|
-};
|
33
|
|
-
|
34
|
|
-struct harddisk_info {
|
35
|
|
- struct controller *ctrl;
|
36
|
|
- uint16_t heads;
|
37
|
|
- uint16_t cylinders;
|
38
|
|
- uint16_t sectors_per_track;
|
39
|
|
- uint8_t model_number[41];
|
40
|
|
- uint8_t slave;
|
41
|
|
- sector_t sectors;
|
42
|
|
- int address_mode; /* am i lba (0x40) or chs (0x00) */
|
43
|
|
-#define ADDRESS_MODE_CHS 0
|
44
|
|
-#define ADDRESS_MODE_LBA 1
|
45
|
|
-#define ADDRESS_MODE_LBA48 2
|
46
|
|
- int drive_exists;
|
47
|
|
- int slave_absent;
|
48
|
|
- int basedrive;
|
49
|
|
-};
|
50
|
|
-
|
51
|
|
-
|
52
|
|
-#define IDE_SECTOR_SIZE 0x200
|
53
|
|
-
|
54
|
|
-#define IDE_BASE0 (0x1F0u) /* primary controller */
|
55
|
|
-#define IDE_BASE1 (0x170u) /* secondary */
|
56
|
|
-#define IDE_BASE2 (0x0F0u) /* third */
|
57
|
|
-#define IDE_BASE3 (0x070u) /* fourth */
|
58
|
|
-
|
59
|
|
-#define IDE_REG_EXTENDED_OFFSET (0x204u)
|
60
|
|
-
|
61
|
|
-#define IDE_REG_DATA(base) ((ctrl)->cmd_base + 0u) /* word register */
|
62
|
|
-#define IDE_REG_ERROR(base) ((ctrl)->cmd_base + 1u)
|
63
|
|
-#define IDE_REG_PRECOMP(base) ((ctrl)->cmd_base + 1u)
|
64
|
|
-#define IDE_REG_FEATURE(base) ((ctrl)->cmd_base + 1u)
|
65
|
|
-#define IDE_REG_SECTOR_COUNT(base) ((ctrl)->cmd_base + 2u)
|
66
|
|
-#define IDE_REG_SECTOR_NUMBER(base) ((ctrl)->cmd_base + 3u)
|
67
|
|
-#define IDE_REG_LBA_LOW(base) ((ctrl)->cmd_base + 3u)
|
68
|
|
-#define IDE_REG_CYLINDER_LSB(base) ((ctrl)->cmd_base + 4u)
|
69
|
|
-#define IDE_REG_LBA_MID(base) ((ctrl)->cmd_base + 4u)
|
70
|
|
-#define IDE_REG_CYLINDER_MSB(base) ((ctrl)->cmd_base + 5u)
|
71
|
|
-#define IDE_REG_LBA_HIGH(base) ((ctrl)->cmd_base + 5u)
|
72
|
|
-#define IDE_REG_DRIVEHEAD(base) ((ctrl)->cmd_base + 6u)
|
73
|
|
-#define IDE_REG_DEVICE(base) ((ctrl)->cmd_base + 6u)
|
74
|
|
-#define IDE_REG_STATUS(base) ((ctrl)->cmd_base + 7u)
|
75
|
|
-#define IDE_REG_COMMAND(base) ((ctrl)->cmd_base + 7u)
|
76
|
|
-#define IDE_REG_ALTSTATUS(base) ((ctrl)->ctrl_base + 2u)
|
77
|
|
-#define IDE_REG_DEVICE_CONTROL(base) ((ctrl)->ctrl_base + 2u)
|
78
|
|
-
|
79
|
|
-struct ide_pio_command
|
80
|
|
-{
|
81
|
|
- uint8_t feature;
|
82
|
|
- uint8_t sector_count;
|
83
|
|
- uint8_t lba_low;
|
84
|
|
- uint8_t lba_mid;
|
85
|
|
- uint8_t lba_high;
|
86
|
|
- uint8_t device;
|
87
|
|
-# define IDE_DH_DEFAULT (0xA0)
|
88
|
|
-# define IDE_DH_HEAD(x) ((x) & 0x0F)
|
89
|
|
-# define IDE_DH_MASTER (0x00)
|
90
|
|
-# define IDE_DH_SLAVE (0x10)
|
91
|
|
-# define IDE_DH_LBA (0x40)
|
92
|
|
-# define IDE_DH_CHS (0x00)
|
93
|
|
- uint8_t command;
|
94
|
|
- uint8_t sector_count2;
|
95
|
|
- uint8_t lba_low2;
|
96
|
|
- uint8_t lba_mid2;
|
97
|
|
- uint8_t lba_high2;
|
98
|
|
-};
|
99
|
|
-
|
100
|
|
-#define IDE_DEFAULT_COMMAND { 0xFFu, 0x01, 0x00, 0x0000, IDE_DH_DEFAULT }
|
101
|
|
-
|
102
|
|
-#define IDE_ERR_ICRC 0x80 /* ATA Ultra DMA bad CRC */
|
103
|
|
-#define IDE_ERR_BBK 0x80 /* ATA bad block */
|
104
|
|
-#define IDE_ERR_UNC 0x40 /* ATA uncorrected error */
|
105
|
|
-#define IDE_ERR_MC 0x20 /* ATA media change */
|
106
|
|
-#define IDE_ERR_IDNF 0x10 /* ATA id not found */
|
107
|
|
-#define IDE_ERR_MCR 0x08 /* ATA media change request */
|
108
|
|
-#define IDE_ERR_ABRT 0x04 /* ATA command aborted */
|
109
|
|
-#define IDE_ERR_NTK0 0x02 /* ATA track 0 not found */
|
110
|
|
-#define IDE_ERR_NDAM 0x01 /* ATA address mark not found */
|
111
|
|
-
|
112
|
|
-#define IDE_STATUS_BSY 0x80 /* busy */
|
113
|
|
-#define IDE_STATUS_RDY 0x40 /* ready */
|
114
|
|
-#define IDE_STATUS_DF 0x20 /* device fault */
|
115
|
|
-#define IDE_STATUS_WFT 0x20 /* write fault (old name) */
|
116
|
|
-#define IDE_STATUS_SKC 0x10 /* seek complete */
|
117
|
|
-#define IDE_STATUS_DRQ 0x08 /* data request */
|
118
|
|
-#define IDE_STATUS_CORR 0x04 /* corrected */
|
119
|
|
-#define IDE_STATUS_IDX 0x02 /* index */
|
120
|
|
-#define IDE_STATUS_ERR 0x01 /* error (ATA) */
|
121
|
|
-#define IDE_STATUS_CHK 0x01 /* check (ATAPI) */
|
122
|
|
-
|
123
|
|
-#define IDE_CTRL_HD15 0x08 /* bit should always be set to one */
|
124
|
|
-#define IDE_CTRL_SRST 0x04 /* soft reset */
|
125
|
|
-#define IDE_CTRL_NIEN 0x02 /* disable interrupts */
|
126
|
|
-
|
127
|
|
-
|
128
|
|
-/* Most mandtory and optional ATA commands (from ATA-3), */
|
129
|
|
-
|
130
|
|
-#define IDE_CMD_CFA_ERASE_SECTORS 0xC0
|
131
|
|
-#define IDE_CMD_CFA_REQUEST_EXT_ERR_CODE 0x03
|
132
|
|
-#define IDE_CMD_CFA_TRANSLATE_SECTOR 0x87
|
133
|
|
-#define IDE_CMD_CFA_WRITE_MULTIPLE_WO_ERASE 0xCD
|
134
|
|
-#define IDE_CMD_CFA_WRITE_SECTORS_WO_ERASE 0x38
|
135
|
|
-#define IDE_CMD_CHECK_POWER_MODE1 0xE5
|
136
|
|
-#define IDE_CMD_CHECK_POWER_MODE2 0x98
|
137
|
|
-#define IDE_CMD_DEVICE_RESET 0x08
|
138
|
|
-#define IDE_CMD_EXECUTE_DEVICE_DIAGNOSTIC 0x90
|
139
|
|
-#define IDE_CMD_FLUSH_CACHE 0xE7
|
140
|
|
-#define IDE_CMD_FORMAT_TRACK 0x50
|
141
|
|
-#define IDE_CMD_IDENTIFY_DEVICE 0xEC
|
142
|
|
-#define IDE_CMD_IDENTIFY_DEVICE_PACKET 0xA1
|
143
|
|
-#define IDE_CMD_IDENTIFY_PACKET_DEVICE 0xA1
|
144
|
|
-#define IDE_CMD_IDLE1 0xE3
|
145
|
|
-#define IDE_CMD_IDLE2 0x97
|
146
|
|
-#define IDE_CMD_IDLE_IMMEDIATE1 0xE1
|
147
|
|
-#define IDE_CMD_IDLE_IMMEDIATE2 0x95
|
148
|
|
-#define IDE_CMD_INITIALIZE_DRIVE_PARAMETERS 0x91
|
149
|
|
-#define IDE_CMD_INITIALIZE_DEVICE_PARAMETERS 0x91
|
150
|
|
-#define IDE_CMD_NOP 0x00
|
151
|
|
-#define IDE_CMD_PACKET 0xA0
|
152
|
|
-#define IDE_CMD_READ_BUFFER 0xE4
|
153
|
|
-#define IDE_CMD_READ_DMA 0xC8
|
154
|
|
-#define IDE_CMD_READ_DMA_QUEUED 0xC7
|
155
|
|
-#define IDE_CMD_READ_MULTIPLE 0xC4
|
156
|
|
-#define IDE_CMD_READ_SECTORS 0x20
|
157
|
|
-#define IDE_CMD_READ_SECTORS_EXT 0x24
|
158
|
|
-#define IDE_CMD_READ_VERIFY_SECTORS 0x40
|
159
|
|
-#define IDE_CMD_RECALIBRATE 0x10
|
160
|
|
-#define IDE_CMD_SEEK 0x70
|
161
|
|
-#define IDE_CMD_SET_FEATURES 0xEF
|
162
|
|
-#define IDE_CMD_SET_MAX_ADDR_EXT 0x24
|
163
|
|
-#define IDE_CMD_SET_MULTIPLE_MODE 0xC6
|
164
|
|
-#define IDE_CMD_SLEEP1 0xE6
|
165
|
|
-#define IDE_CMD_SLEEP2 0x99
|
166
|
|
-#define IDE_CMD_STANDBY1 0xE2
|
167
|
|
-#define IDE_CMD_STANDBY2 0x96
|
168
|
|
-#define IDE_CMD_STANDBY_IMMEDIATE1 0xE0
|
169
|
|
-#define IDE_CMD_STANDBY_IMMEDIATE2 0x94
|
170
|
|
-#define IDE_CMD_WRITE_BUFFER 0xE8
|
171
|
|
-#define IDE_CMD_WRITE_DMA 0xCA
|
172
|
|
-#define IDE_CMD_WRITE_DMA_QUEUED 0xCC
|
173
|
|
-#define IDE_CMD_WRITE_MULTIPLE 0xC5
|
174
|
|
-#define IDE_CMD_WRITE_SECTORS 0x30
|
175
|
|
-#define IDE_CMD_WRITE_VERIFY 0x3C
|
176
|
|
-
|
177
|
|
-/* IDE_CMD_SET_FEATURE sub commands */
|
178
|
|
-#define IDE_FEATURE_CFA_ENABLE_8BIT_PIO 0x01
|
179
|
|
-#define IDE_FEATURE_ENABLE_WRITE_CACHE 0x02
|
180
|
|
-#define IDE_FEATURE_SET_TRANSFER_MODE 0x03
|
181
|
|
-#define IDE_FEATURE_ENABLE_POWER_MANAGEMENT 0x05
|
182
|
|
-#define IDE_FEATURE_ENABLE_POWERUP_IN_STANDBY 0x06
|
183
|
|
-#define IDE_FEATURE_STANDBY_SPINUP_DRIVE 0x07
|
184
|
|
-#define IDE_FEATURE_CFA_ENABLE_POWER_MODE1 0x0A
|
185
|
|
-#define IDE_FEATURE_DISABLE_MEDIA_STATUS_NOTIFICATION 0x31
|
186
|
|
-#define IDE_FEATURE_ENABLE_AUTOMATIC_ACOUSTIC_MANAGEMENT 0x42
|
187
|
|
-#define IDE_FEATURE_SET_MAXIMUM_HOST_INTERFACE_SECTOR_TIMES 0x43
|
188
|
|
-#define IDE_FEATURE_DISABLE_READ_LOOKAHEAD 0x55
|
189
|
|
-#define IDE_FEATURE_ENABLE_RELEASE_INTERRUPT 0x5D
|
190
|
|
-#define IDE_FEATURE_ENABLE_SERVICE_INTERRUPT 0x5E
|
191
|
|
-#define IDE_FEATURE_DISABLE_REVERTING_TO_POWERON_DEFAULTS 0x66
|
192
|
|
-#define IDE_FEATURE_CFA_DISABLE_8BIT_PIO 0x81
|
193
|
|
-#define IDE_FEATURE_DISABLE_WRITE_CACHE 0x82
|
194
|
|
-#define IDE_FEATURE_DISABLE_POWER_MANAGEMENT 0x85
|
195
|
|
-#define IDE_FEATURE_DISABLE_POWERUP_IN_STANDBY 0x86
|
196
|
|
-#define IDE_FEATURE_CFA_DISABLE_POWER_MODE1 0x8A
|
197
|
|
-#define IDE_FEATURE_ENABLE_MEDIA_STATUS_NOTIFICATION 0x95
|
198
|
|
-#define IDE_FEATURE_ENABLE_READ_LOOKAHEAD 0xAA
|
199
|
|
-#define IDE_FEATURE_DISABLE_AUTOMATIC_ACOUSTIC_MANAGEMENT 0xC2
|
200
|
|
-#define IDE_FEATURE_ENABLE_REVERTING_TO_POWERON_DEFAULTS 0xCC
|
201
|
|
-#define IDE_FEATURE_DISABLE_SERVICE_INTERRUPT 0xDE
|
202
|
|
-
|
203
|
|
-
|
204
|
|
-
|
205
|
|
-struct controller controller;
|
206
|
|
-struct harddisk_info harddisk_info[2];
|
207
|
|
-
|
208
|
|
-static int await_ide(int (*done)(struct controller *ctrl),
|
209
|
|
- struct controller *ctrl, unsigned long timeout)
|
210
|
|
-{
|
211
|
|
- int result;
|
212
|
|
- for(;;) {
|
213
|
|
- result = done(ctrl);
|
214
|
|
- if (result) {
|
215
|
|
- return 0;
|
216
|
|
- }
|
217
|
|
- poll_interruptions();
|
218
|
|
- if ((timeout == 0) || (currticks() > timeout)) {
|
219
|
|
- break;
|
220
|
|
- }
|
221
|
|
- }
|
222
|
|
- return -1;
|
223
|
|
-}
|
224
|
|
-
|
225
|
|
-/* The maximum time any IDE command can last 31 seconds,
|
226
|
|
- * So if any IDE commands takes this long we know we have problems.
|
227
|
|
- */
|
228
|
|
-#define IDE_TIMEOUT (32*TICKS_PER_SEC)
|
229
|
|
-
|
230
|
|
-static int not_bsy(struct controller *ctrl)
|
231
|
|
-{
|
232
|
|
- return !(inb(IDE_REG_STATUS(ctrl)) & IDE_STATUS_BSY);
|
233
|
|
-}
|
234
|
|
-#if !BSY_SET_DURING_SPINUP
|
235
|
|
-static int timeout(struct controller *ctrl)
|
236
|
|
-{
|
237
|
|
- return 0;
|
238
|
|
-}
|
239
|
|
-#endif
|
240
|
|
-
|
241
|
|
-static int ide_software_reset(struct controller *ctrl)
|
242
|
|
-{
|
243
|
|
- /* Wait a little bit in case this is immediately after
|
244
|
|
- * hardware reset.
|
245
|
|
- */
|
246
|
|
- mdelay(2);
|
247
|
|
- /* A software reset should not be delivered while the bsy bit
|
248
|
|
- * is set. If the bsy bit does not clear in a reasonable
|
249
|
|
- * amount of time give up.
|
250
|
|
- */
|
251
|
|
- if (await_ide(not_bsy, ctrl, currticks() + IDE_TIMEOUT) < 0) {
|
252
|
|
- return -1;
|
253
|
|
- }
|
254
|
|
-
|
255
|
|
- /* Disable Interrupts and reset the ide bus */
|
256
|
|
- outb(IDE_CTRL_HD15 | IDE_CTRL_SRST | IDE_CTRL_NIEN,
|
257
|
|
- IDE_REG_DEVICE_CONTROL(ctrl));
|
258
|
|
- udelay(5);
|
259
|
|
- outb(IDE_CTRL_HD15 | IDE_CTRL_NIEN, IDE_REG_DEVICE_CONTROL(ctrl));
|
260
|
|
- mdelay(2);
|
261
|
|
- if (await_ide(not_bsy, ctrl, currticks() + IDE_TIMEOUT) < 0) {
|
262
|
|
- return -1;
|
263
|
|
- }
|
264
|
|
- return 0;
|
265
|
|
-}
|
266
|
|
-
|
267
|
|
-static void pio_set_registers(
|
268
|
|
- struct controller *ctrl, const struct ide_pio_command *cmd)
|
269
|
|
-{
|
270
|
|
- uint8_t device;
|
271
|
|
- /* Disable Interrupts */
|
272
|
|
- outb(IDE_CTRL_HD15 | IDE_CTRL_NIEN, IDE_REG_DEVICE_CONTROL(ctrl));
|
273
|
|
-
|
274
|
|
- /* Possibly switch selected device */
|
275
|
|
- device = inb(IDE_REG_DEVICE(ctrl));
|
276
|
|
- outb(cmd->device, IDE_REG_DEVICE(ctrl));
|
277
|
|
- if ((device & (1UL << 4)) != (cmd->device & (1UL << 4))) {
|
278
|
|
- /* Allow time for the selected drive to switch,
|
279
|
|
- * The linux ide code suggests 50ms is the right
|
280
|
|
- * amount of time to use here.
|
281
|
|
- */
|
282
|
|
- mdelay(50);
|
283
|
|
- }
|
284
|
|
- outb(cmd->feature, IDE_REG_FEATURE(ctrl));
|
285
|
|
- outb(cmd->sector_count2, IDE_REG_SECTOR_COUNT(ctrl));
|
286
|
|
- outb(cmd->sector_count, IDE_REG_SECTOR_COUNT(ctrl));
|
287
|
|
- outb(cmd->lba_low2, IDE_REG_LBA_LOW(ctrl));
|
288
|
|
- outb(cmd->lba_low, IDE_REG_LBA_LOW(ctrl));
|
289
|
|
- outb(cmd->lba_mid2, IDE_REG_LBA_MID(ctrl));
|
290
|
|
- outb(cmd->lba_mid, IDE_REG_LBA_MID(ctrl));
|
291
|
|
- outb(cmd->lba_high2, IDE_REG_LBA_HIGH(ctrl));
|
292
|
|
- outb(cmd->lba_high, IDE_REG_LBA_HIGH(ctrl));
|
293
|
|
- outb(cmd->command, IDE_REG_COMMAND(ctrl));
|
294
|
|
-}
|
295
|
|
-
|
296
|
|
-
|
297
|
|
-static int pio_non_data(struct controller *ctrl, const struct ide_pio_command *cmd)
|
298
|
|
-{
|
299
|
|
- /* Wait until the busy bit is clear */
|
300
|
|
- if (await_ide(not_bsy, ctrl, currticks() + IDE_TIMEOUT) < 0) {
|
301
|
|
- return -1;
|
302
|
|
- }
|
303
|
|
-
|
304
|
|
- pio_set_registers(ctrl, cmd);
|
305
|
|
- if (await_ide(not_bsy, ctrl, currticks() + IDE_TIMEOUT) < 0) {
|
306
|
|
- return -1;
|
307
|
|
- }
|
308
|
|
- /* FIXME is there more error checking I could do here? */
|
309
|
|
- return 0;
|
310
|
|
-}
|
311
|
|
-
|
312
|
|
-static int pio_data_in(struct controller *ctrl, const struct ide_pio_command *cmd,
|
313
|
|
- void *buffer, size_t bytes)
|
314
|
|
-{
|
315
|
|
- unsigned int status;
|
316
|
|
-
|
317
|
|
- /* FIXME handle commands with multiple blocks */
|
318
|
|
- /* Wait until the busy bit is clear */
|
319
|
|
- if (await_ide(not_bsy, ctrl, currticks() + IDE_TIMEOUT) < 0) {
|
320
|
|
- return -1;
|
321
|
|
- }
|
322
|
|
-
|
323
|
|
- /* How do I tell if INTRQ is asserted? */
|
324
|
|
- pio_set_registers(ctrl, cmd);
|
325
|
|
- if (await_ide(not_bsy, ctrl, currticks() + IDE_TIMEOUT) < 0) {
|
326
|
|
- return -1;
|
327
|
|
- }
|
328
|
|
- status = inb(IDE_REG_STATUS(ctrl));
|
329
|
|
- if (!(status & IDE_STATUS_DRQ)) {
|
330
|
|
- return -1;
|
331
|
|
- }
|
332
|
|
- insw(IDE_REG_DATA(ctrl), buffer, bytes/2);
|
333
|
|
- status = inb(IDE_REG_STATUS(ctrl));
|
334
|
|
- if (status & IDE_STATUS_DRQ) {
|
335
|
|
- return -1;
|
336
|
|
- }
|
337
|
|
- return 0;
|
338
|
|
-}
|
339
|
|
-
|
340
|
|
-#if 0
|
341
|
|
-static int pio_packet(struct controller *ctrl, int in,
|
342
|
|
- const void *packet, int packet_len,
|
343
|
|
- void *buffer, int buffer_len)
|
344
|
|
-{
|
345
|
|
- const uint8_t *pbuf;
|
346
|
|
- unsigned int status;
|
347
|
|
- struct ide_pio_command cmd;
|
348
|
|
- memset(&cmd, 0, sizeof(cmd));
|
349
|
|
-
|
350
|
|
- /* Wait until the busy bit is clear */
|
351
|
|
- if (await_ide(not_bsy, ctrl, currticks() + IDE_TIMEOUT) < 0) {
|
352
|
|
- return -1;
|
353
|
|
- }
|
354
|
|
- pio_set_registers(ctrl, cmd);
|
355
|
|
- ndelay(400);
|
356
|
|
- if (await_ide(not_bsy, ctrl, currticks() + IDE_TIMEOUT) < 0) {
|
357
|
|
- return -1;
|
358
|
|
- }
|
359
|
|
- status = inb(IDE_REG_STATUS(ctrl));
|
360
|
|
- if (!(status & IDE_STATUS_DRQ)) {
|
361
|
|
- return -1;
|
362
|
|
- }
|
363
|
|
- while(packet_len > 1) {
|
364
|
|
- outb(*pbuf, IDE_REG_DATA(ctrl));
|
365
|
|
- pbuf++;
|
366
|
|
- packet_len -= 1;
|
367
|
|
- }
|
368
|
|
- inb(IDE_REG_ALTSTATUS(ctrl));
|
369
|
|
- if (await_ide){}
|
370
|
|
- /*FIXME finish this function */
|
371
|
|
-
|
372
|
|
-
|
373
|
|
-}
|
374
|
|
-#endif
|
375
|
|
-
|
376
|
|
-static inline int ide_read_sector_chs(
|
377
|
|
- struct harddisk_info *info, void *buffer, unsigned long sector)
|
378
|
|
-{
|
379
|
|
- struct ide_pio_command cmd;
|
380
|
|
- unsigned int track;
|
381
|
|
- unsigned int offset;
|
382
|
|
- unsigned int cylinder;
|
383
|
|
-
|
384
|
|
- memset(&cmd, 0, sizeof(cmd));
|
385
|
|
- cmd.sector_count = 1;
|
386
|
|
-
|
387
|
|
- track = sector / info->sectors_per_track;
|
388
|
|
- /* Sector number */
|
389
|
|
- offset = 1 + (sector % info->sectors_per_track);
|
390
|
|
- cylinder = track / info->heads;
|
391
|
|
- cmd.lba_low = offset;
|
392
|
|
- cmd.lba_mid = cylinder & 0xff;
|
393
|
|
- cmd.lba_high = (cylinder >> 8) & 0xff;
|
394
|
|
- cmd.device = IDE_DH_DEFAULT |
|
395
|
|
- IDE_DH_HEAD(track % info->heads) |
|
396
|
|
- info->slave |
|
397
|
|
- IDE_DH_CHS;
|
398
|
|
- cmd.command = IDE_CMD_READ_SECTORS;
|
399
|
|
- return pio_data_in(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE);
|
400
|
|
-}
|
401
|
|
-
|
402
|
|
-static inline int ide_read_sector_lba(
|
403
|
|
- struct harddisk_info *info, void *buffer, unsigned long sector)
|
404
|
|
-{
|
405
|
|
- struct ide_pio_command cmd;
|
406
|
|
- memset(&cmd, 0, sizeof(cmd));
|
407
|
|
-
|
408
|
|
- cmd.sector_count = 1;
|
409
|
|
- cmd.lba_low = sector & 0xff;
|
410
|
|
- cmd.lba_mid = (sector >> 8) & 0xff;
|
411
|
|
- cmd.lba_high = (sector >> 16) & 0xff;
|
412
|
|
- cmd.device = IDE_DH_DEFAULT |
|
413
|
|
- ((sector >> 24) & 0x0f) |
|
414
|
|
- info->slave |
|
415
|
|
- IDE_DH_LBA;
|
416
|
|
- cmd.command = IDE_CMD_READ_SECTORS;
|
417
|
|
- return pio_data_in(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE);
|
418
|
|
-}
|
419
|
|
-
|
420
|
|
-static inline int ide_read_sector_lba48(
|
421
|
|
- struct harddisk_info *info, void *buffer, sector_t sector)
|
422
|
|
-{
|
423
|
|
- struct ide_pio_command cmd;
|
424
|
|
- memset(&cmd, 0, sizeof(cmd));
|
425
|
|
-
|
426
|
|
- cmd.sector_count = 1;
|
427
|
|
- cmd.lba_low = sector & 0xff;
|
428
|
|
- cmd.lba_mid = (sector >> 8) & 0xff;
|
429
|
|
- cmd.lba_high = (sector >> 16) & 0xff;
|
430
|
|
- cmd.lba_low2 = (sector >> 24) & 0xff;
|
431
|
|
- cmd.lba_mid2 = (sector >> 32) & 0xff;
|
432
|
|
- cmd.lba_high2 = (sector >> 40) & 0xff;
|
433
|
|
- cmd.device = info->slave | IDE_DH_LBA;
|
434
|
|
- cmd.command = IDE_CMD_READ_SECTORS_EXT;
|
435
|
|
- return pio_data_in(info->ctrl, &cmd, buffer, IDE_SECTOR_SIZE);
|
436
|
|
-}
|
437
|
|
-
|
438
|
|
-
|
439
|
|
-static int ide_read(struct disk *disk, sector_t sector)
|
440
|
|
-{
|
441
|
|
- struct harddisk_info *info = disk->priv;
|
442
|
|
- int result;
|
443
|
|
-
|
444
|
|
- /* Report the buffer is empty */
|
445
|
|
- disk->sector = 0;
|
446
|
|
- disk->bytes = 0;
|
447
|
|
- if (sector > info->sectors) {
|
448
|
|
- return -1;
|
449
|
|
- }
|
450
|
|
- if (info->address_mode == ADDRESS_MODE_CHS) {
|
451
|
|
- result = ide_read_sector_chs(info, disk->buffer, sector);
|
452
|
|
- }
|
453
|
|
- else if (info->address_mode == ADDRESS_MODE_LBA) {
|
454
|
|
- result = ide_read_sector_lba(info, disk->buffer, sector);
|
455
|
|
- }
|
456
|
|
- else if (info->address_mode == ADDRESS_MODE_LBA48) {
|
457
|
|
- result = ide_read_sector_lba48(info, disk->buffer, sector);
|
458
|
|
- }
|
459
|
|
- else {
|
460
|
|
- result = -1;
|
461
|
|
- }
|
462
|
|
- /* On success report the buffer has data */
|
463
|
|
- if (result != -1) {
|
464
|
|
- disk->bytes = IDE_SECTOR_SIZE;
|
465
|
|
- disk->sector = sector;
|
466
|
|
- }
|
467
|
|
- return result;
|
468
|
|
-}
|
469
|
|
-
|
470
|
|
-static int init_drive(struct harddisk_info *info, struct controller *ctrl, int slave,
|
471
|
|
- int basedrive, unsigned char *buffer)
|
472
|
|
-{
|
473
|
|
- uint16_t* drive_info;
|
474
|
|
- struct ide_pio_command cmd;
|
475
|
|
- int i;
|
476
|
|
-
|
477
|
|
- info->ctrl = ctrl;
|
478
|
|
- info->heads = 0u;
|
479
|
|
- info->cylinders = 0u;
|
480
|
|
- info->sectors_per_track = 0u;
|
481
|
|
- info->address_mode = IDE_DH_CHS;
|
482
|
|
- info->sectors = 0ul;
|
483
|
|
- info->drive_exists = 0;
|
484
|
|
- info->slave_absent = 0;
|
485
|
|
- info->slave = slave?IDE_DH_SLAVE: IDE_DH_MASTER;
|
486
|
|
- info->basedrive = basedrive;
|
487
|
|
-
|
488
|
|
-#if 0
|
489
|
|
- printf("Testing for disk %d\n", info->basedrive);
|
490
|
|
-#endif
|
491
|
|
-
|
492
|
|
- /* Select the drive that we are testing */
|
493
|
|
- outb(IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave,
|
494
|
|
- IDE_REG_DEVICE(ctrl));
|
495
|
|
- mdelay(50);
|
496
|
|
-
|
497
|
|
- /* Test to see if the drive registers exist,
|
498
|
|
- * In many cases this quickly rules out a missing drive.
|
499
|
|
- */
|
500
|
|
- for(i = 0; i < 4; i++) {
|
501
|
|
- outb(0xaa + i, (ctrl->cmd_base) + 2 + i);
|
502
|
|
- }
|
503
|
|
- for(i = 0; i < 4; i++) {
|
504
|
|
- if (inb((ctrl->cmd_base) + 2 + i) != 0xaa + i) {
|
505
|
|
- return 1;
|
506
|
|
- }
|
507
|
|
- }
|
508
|
|
- for(i = 0; i < 4; i++) {
|
509
|
|
- outb(0x55 + i, (ctrl->cmd_base) + 2 + i);
|
510
|
|
- }
|
511
|
|
- for(i = 0; i < 4; i++) {
|
512
|
|
- if (inb((ctrl->cmd_base) + 2 + i) != 0x55 + i) {
|
513
|
|
- return 1;
|
514
|
|
- }
|
515
|
|
- }
|
516
|
|
-#if 0
|
517
|
|
- printf("Probing for disk %d\n", info->basedrive);
|
518
|
|
-#endif
|
519
|
|
-
|
520
|
|
- memset(&cmd, 0, sizeof(cmd));
|
521
|
|
- cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave;
|
522
|
|
- cmd.command = IDE_CMD_IDENTIFY_DEVICE;
|
523
|
|
-
|
524
|
|
-
|
525
|
|
- if (pio_data_in(ctrl, &cmd, buffer, IDE_SECTOR_SIZE) < 0) {
|
526
|
|
- /* Well, if that command didn't work, we probably don't have drive. */
|
527
|
|
- return 1;
|
528
|
|
- }
|
529
|
|
-
|
530
|
|
-
|
531
|
|
- /* Now suck the data out */
|
532
|
|
- drive_info = (uint16_t *)buffer;
|
533
|
|
- if (drive_info[2] == 0x37C8) {
|
534
|
|
- /* If the response is incomplete spin up the drive... */
|
535
|
|
- memset(&cmd, 0, sizeof(cmd));
|
536
|
|
- cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS |
|
537
|
|
- info->slave;
|
538
|
|
- cmd.feature = IDE_FEATURE_STANDBY_SPINUP_DRIVE;
|
539
|
|
- if (pio_non_data(ctrl, &cmd) < 0) {
|
540
|
|
- /* If the command doesn't work give up on the drive */
|
541
|
|
- return 1;
|
542
|
|
- }
|
543
|
|
-
|
544
|
|
- }
|
545
|
|
- if ((drive_info[2] == 0x37C8) || (drive_info[2] == 0x8C73)) {
|
546
|
|
- /* The response is incomplete retry the drive info command */
|
547
|
|
- memset(&cmd, 0, sizeof(cmd));
|
548
|
|
- cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS |
|
549
|
|
- info->slave;
|
550
|
|
- cmd.command = IDE_CMD_IDENTIFY_DEVICE;
|
551
|
|
- if(pio_data_in(ctrl, &cmd, buffer, IDE_SECTOR_SIZE) < 0) {
|
552
|
|
- /* If the command didn't work give up on the drive. */
|
553
|
|
- return 1;
|
554
|
|
- }
|
555
|
|
- }
|
556
|
|
- if ((drive_info[2] != 0x37C8) &&
|
557
|
|
- (drive_info[2] != 0x738C) &&
|
558
|
|
- (drive_info[2] != 0x8C73) &&
|
559
|
|
- (drive_info[2] != 0xC837) &&
|
560
|
|
- (drive_info[2] != 0x0000)) {
|
561
|
|
- printf("Invalid IDE Configuration: %hx\n", drive_info[2]);
|
562
|
|
- return 1;
|
563
|
|
- }
|
564
|
|
- for(i = 27; i < 47; i++) {
|
565
|
|
- info->model_number[((i-27)<< 1)] = (drive_info[i] >> 8) & 0xff;
|
566
|
|
- info->model_number[((i-27)<< 1)+1] = drive_info[i] & 0xff;
|
567
|
|
- }
|
568
|
|
- info->model_number[40] = '\0';
|
569
|
|
- info->drive_exists = 1;
|
570
|
|
-
|
571
|
|
- /* See if LBA is supported */
|
572
|
|
- if (drive_info[49] & (1 << 9)) {
|
573
|
|
- info->address_mode = ADDRESS_MODE_LBA;
|
574
|
|
- info->sectors = (drive_info[61] << 16) | (drive_info[60]);
|
575
|
|
- /* Enable LBA48 mode if it is present */
|
576
|
|
- if (drive_info[83] & (1 <<10)) {
|
577
|
|
- /* Should LBA48 depend on LBA? */
|
578
|
|
- printf("LBA48 mode\n");
|
579
|
|
- info->address_mode = ADDRESS_MODE_LBA48;
|
580
|
|
- info->sectors =
|
581
|
|
- (((sector_t)drive_info[103]) << 48) |
|
582
|
|
- (((sector_t)drive_info[102]) << 32) |
|
583
|
|
- (((sector_t)drive_info[101]) << 16) |
|
584
|
|
- (((sector_t)drive_info[100]) << 0);
|
585
|
|
- }
|
586
|
|
- } else {
|
587
|
|
- info->address_mode = ADDRESS_MODE_CHS;
|
588
|
|
- info->heads = drive_info[3];
|
589
|
|
- info->cylinders = drive_info[1];
|
590
|
|
- info->sectors_per_track = drive_info[6];
|
591
|
|
- info->sectors =
|
592
|
|
- info->sectors_per_track *
|
593
|
|
- info->heads *
|
594
|
|
- info->cylinders;
|
595
|
|
- printf( "%s sectors_per_track=[%d], heads=[%d], cylinders=[%d]\n",
|
596
|
|
- __FUNCTION__,
|
597
|
|
- info->sectors_per_track,
|
598
|
|
- info->heads,
|
599
|
|
- info->cylinders);
|
600
|
|
- }
|
601
|
|
- /* See if we have a slave */
|
602
|
|
- if (!info->slave && (((drive_info[93] >> 14) & 3) == 1)) {
|
603
|
|
- info->slave_absent = !(drive_info[93] & (1 << 5));
|
604
|
|
- }
|
605
|
|
- /* See if we need to put the device in CFA power mode 1 */
|
606
|
|
- if ((drive_info[160] & ((1 << 15) | (1 << 13)| (1 << 12))) ==
|
607
|
|
- ((1 << 15) | (1 << 13)| (1 << 12))) {
|
608
|
|
- memset(&cmd, 0, sizeof(cmd));
|
609
|
|
- cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave;
|
610
|
|
- cmd.feature = IDE_FEATURE_CFA_ENABLE_POWER_MODE1;
|
611
|
|
- if (pio_non_data(ctrl, &cmd) < 0) {
|
612
|
|
- /* If I need to power up the drive, and I can't
|
613
|
|
- * give up.
|
614
|
|
- */
|
615
|
|
- printf("Cannot power up CFA device\n");
|
616
|
|
- return 1;
|
617
|
|
- }
|
618
|
|
- }
|
619
|
|
- printf("disk%d %dk cap: %hx\n",
|
620
|
|
- info->basedrive,
|
621
|
|
- (unsigned long)(info->sectors >> 1),
|
622
|
|
- drive_info[49]);
|
623
|
|
- return 0;
|
624
|
|
-}
|
625
|
|
-
|
626
|
|
-static int init_controller(struct controller *ctrl, int basedrive, unsigned char *buffer)
|
627
|
|
-{
|
628
|
|
- struct harddisk_info *info;
|
629
|
|
-
|
630
|
|
- /* Intialize the harddisk_info structures */
|
631
|
|
- memset(harddisk_info, 0, sizeof(harddisk_info));
|
632
|
|
-
|
633
|
|
- /* Put the drives ide channel in a know state and wait
|
634
|
|
- * for the drives to spinup.
|
635
|
|
- *
|
636
|
|
- * In practice IDE disks tend not to respond to commands until
|
637
|
|
- * they have spun up. This makes IDE hard to deal with
|
638
|
|
- * immediately after power up, as the delays can be quite
|
639
|
|
- * long, so we must be very careful here.
|
640
|
|
- *
|
641
|
|
- * There are two pathological cases that must be dealt with:
|
642
|
|
- *
|
643
|
|
- * - The BSY bit not being set while the IDE drives spin up.
|
644
|
|
- * In this cases only a hard coded delay will work. As
|
645
|
|
- * I have not reproduced it, and this is out of spec for
|
646
|
|
- * IDE drives the work around can be enabled by setting
|
647
|
|
- * BSY_SET_DURING_SPINUP to 0.
|
648
|
|
- *
|
649
|
|
- * - The BSY bit floats high when no drives are plugged in.
|
650
|
|
- * This case will not be detected except by timing out but
|
651
|
|
- * we avoid the problems by only probing devices we are
|
652
|
|
- * supposed to boot from. If we don't do the probe we
|
653
|
|
- * will not experience the problem.
|
654
|
|
- *
|
655
|
|
- * So speed wise I am only slow if the BSY bit is not set
|
656
|
|
- * or not reported by the IDE controller during spinup, which
|
657
|
|
- * is quite rare.
|
658
|
|
- *
|
659
|
|
- */
|
660
|
|
-#if !BSY_SET_DURING_SPINUP
|
661
|
|
- if (await_ide(timeout, ctrl, IDE_TIMEOUT) < 0) {
|
662
|
|
- return -1;
|
663
|
|
- }
|
664
|
|
-#endif
|
665
|
|
- if (ide_software_reset(ctrl) < 0) {
|
666
|
|
- return -1;
|
667
|
|
- }
|
668
|
|
-
|
669
|
|
- /* Note: I have just done a software reset. It may be
|
670
|
|
- * reasonable to just read the boot time signatures
|
671
|
|
- * off of the drives to see if they are present.
|
672
|
|
- *
|
673
|
|
- * For now I will go with just sending commands to the drives
|
674
|
|
- * and assuming filtering out missing drives by detecting registers
|
675
|
|
- * that won't set and commands that fail to execute properly.
|
676
|
|
- */
|
677
|
|
-
|
678
|
|
- /* Now initialize the individual drives */
|
679
|
|
- info = &harddisk_info[0];
|
680
|
|
- init_drive(info, ctrl, 0, basedrive, buffer);
|
681
|
|
- if (info->drive_exists && !info->slave_absent) {
|
682
|
|
- basedrive++;
|
683
|
|
- info++;
|
684
|
|
- init_drive(info, ctrl, 1, basedrive, buffer);
|
685
|
|
- }
|
686
|
|
-
|
687
|
|
- return 0;
|
688
|
|
-}
|
689
|
|
-
|
690
|
|
-static void ide_disable(struct dev *dev)
|
691
|
|
-{
|
692
|
|
- struct disk *disk = (struct disk *)dev;
|
693
|
|
- struct harddisk_info *info = disk->priv;
|
694
|
|
- ide_software_reset(info->ctrl);
|
695
|
|
-}
|
696
|
|
-
|
697
|
|
-static int ide_pci_probe(struct dev *dev, struct pci_device *pci)
|
698
|
|
-{
|
699
|
|
- struct disk *disk = (struct disk *)dev;
|
700
|
|
- struct harddisk_info *info;
|
701
|
|
- int index;
|
702
|
|
-
|
703
|
|
- adjust_pci_device(pci);
|
704
|
|
-
|
705
|
|
- index = dev->index + 1;
|
706
|
|
- if (dev->how_probe == PROBE_NEXT) {
|
707
|
|
- index++;
|
708
|
|
- }
|
709
|
|
- for(; index < 4; index++) {
|
710
|
|
- unsigned mask;
|
711
|
|
- mask = (index < 2)? (1 << 0) : (1 << 2);
|
712
|
|
- if ((pci->class & mask) == 0) {
|
713
|
|
- /* IDE special pci mode */
|
714
|
|
- uint16_t base;
|
715
|
|
- base = (index < 2)?IDE_BASE0:IDE_BASE1;
|
716
|
|
- controller.cmd_base = base;
|
717
|
|
- controller.ctrl_base = base + IDE_REG_EXTENDED_OFFSET;
|
718
|
|
- } else {
|
719
|
|
- /* IDE normal pci mode */
|
720
|
|
- unsigned cmd_reg, ctrl_reg;
|
721
|
|
- uint32_t cmd_base, ctrl_base;
|
722
|
|
- if (index < 2) {
|
723
|
|
- cmd_reg = PCI_BASE_ADDRESS_0;
|
724
|
|
- ctrl_reg = PCI_BASE_ADDRESS_1;
|
725
|
|
- } else {
|
726
|
|
- cmd_reg = PCI_BASE_ADDRESS_2;
|
727
|
|
- ctrl_reg = PCI_BASE_ADDRESS_3;
|
728
|
|
- }
|
729
|
|
- pcibios_read_config_dword(pci->bus, pci->devfn, cmd_reg, &cmd_base);
|
730
|
|
- pcibios_read_config_dword(pci->bus, pci->devfn, ctrl_reg, &ctrl_base);
|
731
|
|
- controller.cmd_base = cmd_base & ~3;
|
732
|
|
- controller.ctrl_base = ctrl_base & ~3;
|
733
|
|
- }
|
734
|
|
- if (((index & 1) == 0) || (dev->how_probe == PROBE_AWAKE)) {
|
735
|
|
- if (init_controller(&controller, disk->drive, disk->buffer) < 0) {
|
736
|
|
- /* nothing behind the controller */
|
737
|
|
- continue;
|
738
|
|
- }
|
739
|
|
- }
|
740
|
|
- info = &harddisk_info[index & 1];
|
741
|
|
- if (!info->drive_exists) {
|
742
|
|
- /* unknown drive */
|
743
|
|
- continue;
|
744
|
|
- }
|
745
|
|
- disk->hw_sector_size = IDE_SECTOR_SIZE;
|
746
|
|
- disk->sectors_per_read = 1;
|
747
|
|
- disk->sectors = info->sectors;
|
748
|
|
- dev->index = index;
|
749
|
|
- dev->disable = ide_disable;
|
750
|
|
- disk->read = ide_read;
|
751
|
|
- disk->priv = info;
|
752
|
|
-
|
753
|
|
- return 1;
|
754
|
|
- }
|
755
|
|
- /* past all of the drives */
|
756
|
|
- dev->index = 0;
|
757
|
|
- return 0;
|
758
|
|
-}
|
759
|
|
-#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
|
760
|
|
-static struct pci_id ide_controllers[] = {
|
761
|
|
- PCI_ROM(0x0000, 0x0000, "ide_disk", "Generic IDE disk support"),
|
762
|
|
-/* { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, "PIIX4" },*/
|
763
|
|
-#if 0 /* Currently I don't need any entries in this table so ignore it */
|
764
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, "PIIX" },
|
765
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1, "PIIX" },
|
766
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, "MPIIX" },
|
767
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, "PIIX3" },
|
768
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, "PIIX4" },
|
769
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1, "PIIX4" },
|
770
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1, "PIIX4" },
|
771
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1, "PIIX4" },
|
772
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1, "PIIX4" },
|
773
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, "PIIX4" },
|
774
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9, "PIIX4" },
|
775
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8, "PIIX4" },
|
776
|
|
-{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, "PIIX4" },
|
777
|
|
-{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561, "VIA_IDE" },
|
778
|
|
-{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, "VP_IDE" },
|
779
|
|
-{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, "VP_IDE" },
|
780
|
|
-{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, "PDC20246" },
|
781
|
|
-{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, "PDC20262" },
|
782
|
|
-{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265, "PDC20265" },
|
783
|
|
-{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267, "PDC20267" },
|
784
|
|
-{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, "PDC20268" },
|
785
|
|
-{ PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R, "PDC20268" },
|
786
|
|
-{ PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, "RZ1000" },
|
787
|
|
-{ PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001, "RZ1001" },
|
788
|
|
-{ PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE, "SAMURAI" },
|
789
|
|
-{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640, "CMD640" },
|
790
|
|
-{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643, "CMD646" },
|
791
|
|
-{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, "CMD648" },
|
792
|
|
-{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648, "CMD643" },
|
793
|
|
-{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649, "CMD649" },
|
794
|
|
-{ PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, "SIS5513" },
|
795
|
|
-{ PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, "OPTI621" },
|
796
|
|
-{ PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558, "OPTI621V" },
|
797
|
|
-{ PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C825, "OPTI621X" },
|
798
|
|
-{ PCI_VENDOR_ID_TEKRAM, PCI_DEVICE_ID_TEKRAM_DC290, "TRM290" },
|
799
|
|
-{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, "NS87410" },
|
800
|
|
-{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, "NS87415" },
|
801
|
|
-{ PCI_VENDOR_ID_HOLTEK2, PCI_DEVICE_ID_HOLTEK2_6565, "HT6565" },
|
802
|
|
-{ PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, "AEC6210" },
|
803
|
|
-{ PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860, "AEC6260" },
|
804
|
|
-{ PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R, "AEC6260R" },
|
805
|
|
-{ PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, "W82C105" },
|
806
|
|
-{ PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F, "UM8673F" },
|
807
|
|
-{ PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A, "UM8886A" },
|
808
|
|
-{ PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, "UM8886BF" },
|
809
|
|
-{ PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343, "HPT34X" },
|
810
|
|
-{ PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366, "HPT366" },
|
811
|
|
-{ PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, "ALI15X3" },
|
812
|
|
-{ PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, "CY82C693" },
|
813
|
|
-{ 0x3388, 0x8013, "HINT_IDE" },
|
814
|
|
-{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE, "CS5530" },
|
815
|
|
-{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, "AMD7401" },
|
816
|
|
-{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409, "AMD7409" },
|
817
|
|
-{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, "AMD7411" },
|
818
|
|
-{ PCI_VENDOR_ID_PDC, PCI_DEVICE_ID_PDC_1841, "PDCADMA" },
|
819
|
|
-{ PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, "SLC90E66" },
|
820
|
|
-{ PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, "OSB4" },
|
821
|
|
-{ PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, "OSB5" },
|
822
|
|
-{ PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G, "ITE8172G" },
|
823
|
|
-#endif
|
824
|
|
-};
|
825
|
|
-
|
826
|
|
-static struct pci_driver ide_driver __pci_driver = {
|
827
|
|
- .type = DISK_DRIVER,
|
828
|
|
- .name = "IDE",
|
829
|
|
- .probe = ide_pci_probe,
|
830
|
|
- .ids = ide_controllers,
|
831
|
|
- .id_count = sizeof(ide_controllers)/sizeof(ide_controllers),
|
832
|
|
- .class = PCI_CLASS_STORAGE_IDE,
|
833
|
|
-};
|
834
|
|
-
|
835
|
|
-/* The isa driver works but it causes disks to show up twice.
|
836
|
|
- * comment it out for now.
|
837
|
|
- */
|
838
|
|
-#if 0
|
839
|
|
-static int ide_isa_probe(struct dev * dev, unsigned short *probe_addrs)
|
840
|
|
-{
|
841
|
|
- struct disk *disk = (struct disk *)dev;
|
842
|
|
- int index;
|
843
|
|
- unsigned short addr;
|
844
|
|
- struct harddisk_info *info;
|
845
|
|
-
|
846
|
|
- index = dev->index +1;
|
847
|
|
- if (dev->how_probe == PROBE_AWAKE) {
|
848
|
|
- index--;
|
849
|
|
- }
|
850
|
|
- for(; (index >= 0) && (addr = probe_addrs[index >> 1]); index += 2) {
|
851
|
|
- if ((index & 1) == 0) {
|
852
|
|
- controller.cmd_base = addr;
|
853
|
|
- controller.ctrl_base = addr + IDE_REG_EXTENDED_OFFSET;
|
854
|
|
- if (init_controller(&controller, disk->drive, disk->buffer) < 0) {
|
855
|
|
- /* nothing behind the controller */
|
856
|
|
- continue;
|
857
|
|
- }
|
858
|
|
- }
|
859
|
|
- info = &harddisk_info[index & 1];
|
860
|
|
- if (!info->drive_exists) {
|
861
|
|
- /* unknown drive */
|
862
|
|
- return 0;
|
863
|
|
- }
|
864
|
|
- disk->sectors_per_read = 1;
|
865
|
|
- disk->sectors = info->sectors;
|
866
|
|
- dev->index = index;
|
867
|
|
- dev->disable = ide_disable;
|
868
|
|
- disk->read = ide_read;
|
869
|
|
- disk->priv = info;
|
870
|
|
-
|
871
|
|
- return 1;
|
872
|
|
- }
|
873
|
|
- /* past all of the drives */
|
874
|
|
- dev->index = -1;
|
875
|
|
- return 0;
|
876
|
|
-}
|
877
|
|
-
|
878
|
|
-static unsigned short ide_base[] = {
|
879
|
|
- IDE_BASE0,
|
880
|
|
- IDE_BASE1,
|
881
|
|
- IDE_BASE2,
|
882
|
|
- IDE_BASE3,
|
883
|
|
- 0
|
884
|
|
-};
|
885
|
|
-static struct isa_driver ide_isa_driver __isa_driver = {
|
886
|
|
- .type = DISK_DRIVER,
|
887
|
|
- .name = "IDE/ISA",
|
888
|
|
- .probe = ide_isa_probe,
|
889
|
|
- .ioaddrs = ide_base,
|
890
|
|
-};
|
891
|
|
-
|
892
|
|
-#endif
|