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 | #ifdef CONFIG_PCI
|
---|
698 | static int ide_pci_probe(struct dev *dev, struct pci_device *pci)
|
---|
699 | {
|
---|
700 | struct disk *disk = (struct disk *)dev;
|
---|
701 | struct harddisk_info *info;
|
---|
702 | int index;
|
---|
703 |
|
---|
704 | adjust_pci_device(pci);
|
---|
705 |
|
---|
706 | index = dev->index + 1;
|
---|
707 | if (dev->how_probe == PROBE_NEXT) {
|
---|
708 | index++;
|
---|
709 | }
|
---|
710 | for(; index < 4; index++) {
|
---|
711 | unsigned mask;
|
---|
712 | mask = (index < 2)? (1 << 0) : (1 << 2);
|
---|
713 | if ((pci->class & mask) == 0) {
|
---|
714 | /* IDE special pci mode */
|
---|
715 | uint16_t base;
|
---|
716 | base = (index < 2)?IDE_BASE0:IDE_BASE1;
|
---|
717 | controller.cmd_base = base;
|
---|
718 | controller.ctrl_base = base + IDE_REG_EXTENDED_OFFSET;
|
---|
719 | } else {
|
---|
720 | /* IDE normal pci mode */
|
---|
721 | unsigned cmd_reg, ctrl_reg;
|
---|
722 | uint32_t cmd_base, ctrl_base;
|
---|
723 | if (index < 2) {
|
---|
724 | cmd_reg = PCI_BASE_ADDRESS_0;
|
---|
725 | ctrl_reg = PCI_BASE_ADDRESS_1;
|
---|
726 | } else {
|
---|
727 | cmd_reg = PCI_BASE_ADDRESS_2;
|
---|
728 | ctrl_reg = PCI_BASE_ADDRESS_3;
|
---|
729 | }
|
---|
730 | pcibios_read_config_dword(pci->bus, pci->devfn, cmd_reg, &cmd_base);
|
---|
731 | pcibios_read_config_dword(pci->bus, pci->devfn, ctrl_reg, &ctrl_base);
|
---|
732 | controller.cmd_base = cmd_base & ~3;
|
---|
733 | controller.ctrl_base = ctrl_base & ~3;
|
---|
734 | }
|
---|
735 | if (((index & 1) == 0) || (dev->how_probe == PROBE_AWAKE)) {
|
---|
736 | if (init_controller(&controller, disk->drive, disk->buffer) < 0) {
|
---|
737 | /* nothing behind the controller */
|
---|
738 | continue;
|
---|
739 | }
|
---|
740 | }
|
---|
741 | info = &harddisk_info[index & 1];
|
---|
742 | if (!info->drive_exists) {
|
---|
743 | /* unknown drive */
|
---|
744 | continue;
|
---|
745 | }
|
---|
746 | disk->hw_sector_size = IDE_SECTOR_SIZE;
|
---|
747 | disk->sectors_per_read = 1;
|
---|
748 | disk->sectors = info->sectors;
|
---|
749 | dev->index = index;
|
---|
750 | dev->disable = ide_disable;
|
---|
751 | disk->read = ide_read;
|
---|
752 | disk->priv = info;
|
---|
753 |
|
---|
754 | return 1;
|
---|
755 | }
|
---|
756 | /* past all of the drives */
|
---|
757 | dev->index = 0;
|
---|
758 | return 0;
|
---|
759 | }
|
---|
760 | #define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
|
---|
761 | static struct pci_id ide_controllers[] = {
|
---|
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 | #endif
|
---|
835 |
|
---|
836 | /* The isa driver works but it causes disks to show up twice.
|
---|
837 | * comment it out for now.
|
---|
838 | */
|
---|
839 | #if 0 && defined(CONFIG_ISA)
|
---|
840 | static int ide_isa_probe(struct dev * dev, unsigned short *probe_addrs)
|
---|
841 | {
|
---|
842 | struct disk *disk = (struct disk *)dev;
|
---|
843 | int index;
|
---|
844 | unsigned short addr;
|
---|
845 | struct harddisk_info *info;
|
---|
846 |
|
---|
847 | index = dev->index +1;
|
---|
848 | if (dev->how_probe == PROBE_AWAKE) {
|
---|
849 | index--;
|
---|
850 | }
|
---|
851 | for(; (index >= 0) && (addr = probe_addrs[index >> 1]); index += 2) {
|
---|
852 | if ((index & 1) == 0) {
|
---|
853 | controller.cmd_base = addr;
|
---|
854 | controller.ctrl_base = addr + IDE_REG_EXTENDED_OFFSET;
|
---|
855 | if (init_controller(&controller, disk->drive, disk->buffer) < 0) {
|
---|
856 | /* nothing behind the controller */
|
---|
857 | continue;
|
---|
858 | }
|
---|
859 | }
|
---|
860 | info = &harddisk_info[index & 1];
|
---|
861 | if (!info->drive_exists) {
|
---|
862 | /* unknown drive */
|
---|
863 | return 0;
|
---|
864 | }
|
---|
865 | disk->sectors_per_read = 1;
|
---|
866 | disk->sectors = info->sectors;
|
---|
867 | dev->index = index;
|
---|
868 | dev->disable = ide_disable;
|
---|
869 | disk->read = ide_read;
|
---|
870 | disk->priv = info;
|
---|
871 |
|
---|
872 | return 1;
|
---|
873 | }
|
---|
874 | /* past all of the drives */
|
---|
875 | dev->index = -1;
|
---|
876 | return 0;
|
---|
877 | }
|
---|
878 |
|
---|
879 | static unsigned short ide_base[] = {
|
---|
880 | IDE_BASE0,
|
---|
881 | IDE_BASE1,
|
---|
882 | IDE_BASE2,
|
---|
883 | IDE_BASE3,
|
---|
884 | 0
|
---|
885 | };
|
---|
886 | static struct isa_driver ide_isa_driver __isa_driver = {
|
---|
887 | .type = DISK_DRIVER,
|
---|
888 | .name = "IDE/ISA",
|
---|
889 | .probe = ide_isa_probe,
|
---|
890 | .ioaddrs = ide_base,
|
---|
891 | };
|
---|
892 |
|
---|
893 | #endif
|
---|