Commit fc843a02acad62e231a3e779cebd1712688146fc
Committed by
Tom Rini
1 parent
75eb9976b7
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
Kconfig: Add a CONFIG_IDE option
At present IDE support is controlled by CONFIG_CMD_IDE. Add a separate CONFIG_IDE option so that IDE support can be enabled without requiring the 'ide' command. Update existing users and move the ide driver into drivers/block since it should not be in common/. Signed-off-by: Simon Glass <sjg@chromium.org>
Showing 38 changed files with 1291 additions and 1284 deletions Side-by-side Diff
- README
- api/api_storage.c
- arch/arm/mach-kirkwood/include/mach/config.h
- arch/powerpc/cpu/mpc5xxx/ide.c
- arch/powerpc/lib/Makefile
- board/freescale/m5253demo/m5253demo.c
- board/freescale/m5253evbe/m5253evbe.c
- board/freescale/m54455evb/m54455evb.c
- board/intercontrol/digsy_mtc/digsy_mtc.c
- board/jupiter/jupiter.c
- board/phytec/pcm030/pcm030.c
- board/tqc/tqm5200/tqm5200.c
- board/v38b/v38b.c
- cmd/Kconfig
- cmd/pcmcia.c
- common/Makefile
- common/board_r.c
- common/ide.c
- drivers/block/Kconfig
- drivers/block/Makefile
- drivers/block/ide.c
- drivers/block/sil680.c
- drivers/pcmcia/marubun_pcmcia.c
- drivers/pcmcia/mpc8xx_pcmcia.c
- drivers/pcmcia/tqm8xx_pcmcia.c
- fs/fat/fat.c
- include/config_distro_bootcmd.h
- include/config_fallbacks.h
- include/configs/M5253DEMO.h
- include/configs/edminiv2.h
- include/configs/ib62x0.h
- include/configs/lsxl.h
- include/configs/mpc5121ads.h
- include/configs/nsa310s.h
- include/configs/qemu-x86.h
- include/configs/r7780mp.h
- include/configs/sheevaplug.h
- include/pcmcia.h
README
... | ... | @@ -1081,7 +1081,7 @@ |
1081 | 1081 | disk/part_efi.c |
1082 | 1082 | CONFIG_MTD_PARTITIONS Memory Technology Device partition table. |
1083 | 1083 | |
1084 | - If IDE or SCSI support is enabled (CONFIG_CMD_IDE or | |
1084 | + If IDE or SCSI support is enabled (CONFIG_IDE or | |
1085 | 1085 | CONFIG_SCSI) you must configure support for at |
1086 | 1086 | least one non-MTD partition type as well. |
1087 | 1087 |
api/api_storage.c
arch/arm/mach-kirkwood/include/mach/config.h
... | ... | @@ -95,7 +95,7 @@ |
95 | 95 | /* |
96 | 96 | * IDE Support on SATA ports |
97 | 97 | */ |
98 | -#ifdef CONFIG_CMD_IDE | |
98 | +#ifdef CONFIG_IDE | |
99 | 99 | #define __io |
100 | 100 | #define CONFIG_MVSATA_IDE |
101 | 101 | #define CONFIG_IDE_PREINIT |
102 | 102 | |
... | ... | @@ -110,12 +110,12 @@ |
110 | 110 | #define CONFIG_SYS_ATA_STRIDE 4 |
111 | 111 | /* Controller supports 48-bits LBA addressing */ |
112 | 112 | #define CONFIG_LBA48 |
113 | -/* CONFIG_CMD_IDE requires some #defines for ATA registers */ | |
113 | +/* CONFIG_IDE requires some #defines for ATA registers */ | |
114 | 114 | #define CONFIG_SYS_IDE_MAXBUS 2 |
115 | 115 | #define CONFIG_SYS_IDE_MAXDEVICE 2 |
116 | 116 | /* ATA registers base is at SATA controller base */ |
117 | 117 | #define CONFIG_SYS_ATA_BASE_ADDR MV_SATA_BASE |
118 | -#endif /* CONFIG_CMD_IDE */ | |
118 | +#endif /* CONFIG_IDE */ | |
119 | 119 | |
120 | 120 | /* |
121 | 121 | * I2C related stuff |
arch/powerpc/cpu/mpc5xxx/ide.c
arch/powerpc/lib/Makefile
board/freescale/m5253demo/m5253demo.c
... | ... | @@ -88,7 +88,7 @@ |
88 | 88 | return (0); |
89 | 89 | } |
90 | 90 | |
91 | -#ifdef CONFIG_CMD_IDE | |
91 | +#ifdef CONFIG_IDE | |
92 | 92 | #include <ata.h> |
93 | 93 | int ide_preinit(void) |
94 | 94 | { |
... | ... | @@ -133,7 +133,7 @@ |
133 | 133 | setbits_8(&ata->cr, 0x01); |
134 | 134 | } |
135 | 135 | } |
136 | -#endif /* CONFIG_CMD_IDE */ | |
136 | +#endif /* CONFIG_IDE */ | |
137 | 137 | |
138 | 138 | |
139 | 139 | #ifdef CONFIG_DRIVER_DM9000 |
board/freescale/m5253evbe/m5253evbe.c
... | ... | @@ -81,7 +81,7 @@ |
81 | 81 | return (0); |
82 | 82 | } |
83 | 83 | |
84 | -#ifdef CONFIG_CMD_IDE | |
84 | +#ifdef CONFIG_IDE | |
85 | 85 | #include <ata.h> |
86 | 86 | int ide_preinit(void) |
87 | 87 | { |
... | ... | @@ -126,5 +126,5 @@ |
126 | 126 | setbits_8(&ata->cr, 0x01); |
127 | 127 | } |
128 | 128 | } |
129 | -#endif /* CONFIG_CMD_IDE */ | |
129 | +#endif /* CONFIG_IDE */ |
board/freescale/m54455evb/m54455evb.c
board/intercontrol/digsy_mtc/digsy_mtc.c
... | ... | @@ -325,7 +325,7 @@ |
325 | 325 | } |
326 | 326 | #endif |
327 | 327 | |
328 | -#ifdef CONFIG_CMD_IDE | |
328 | +#ifdef CONFIG_IDE | |
329 | 329 | |
330 | 330 | #ifdef CONFIG_IDE_RESET |
331 | 331 | |
... | ... | @@ -369,7 +369,7 @@ |
369 | 369 | setbits_be32((void *)MPC5XXX_WU_GPIO_ENABLE, (1 << 25)); |
370 | 370 | } |
371 | 371 | #endif /* CONFIG_IDE_RESET */ |
372 | -#endif /* CONFIG_CMD_IDE */ | |
372 | +#endif /* CONFIG_IDE */ | |
373 | 373 | |
374 | 374 | #ifdef CONFIG_OF_BOARD_SETUP |
375 | 375 | static void ft_delete_node(void *fdt, const char *compat) |
board/jupiter/jupiter.c
board/phytec/pcm030/pcm030.c
... | ... | @@ -176,7 +176,7 @@ |
176 | 176 | } |
177 | 177 | #endif /* CONFIG_OF_BOARD_SETUP */ |
178 | 178 | |
179 | -#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET) | |
179 | +#if defined(CONFIG_IDE) && defined(CONFIG_IDE_RESET) | |
180 | 180 | |
181 | 181 | #define GPIO_PSC2_4 0x02000000UL |
182 | 182 | |
... | ... | @@ -206,5 +206,5 @@ |
206 | 206 | } else |
207 | 207 | setbits_be32(&wu_gpio->dvo, GPIO_PSC2_4); |
208 | 208 | } |
209 | -#endif /* defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET) */ | |
209 | +#endif /* defined(CONFIG_IDE) && defined(CONFIG_IDE_RESET) */ |
board/tqc/tqm5200/tqm5200.c
board/v38b/v38b.c
cmd/Kconfig
cmd/pcmcia.c
common/Makefile
common/board_r.c
... | ... | @@ -23,9 +23,7 @@ |
23 | 23 | #include <dm.h> |
24 | 24 | #include <environment.h> |
25 | 25 | #include <fdtdec.h> |
26 | -#if defined(CONFIG_CMD_IDE) | |
27 | 26 | #include <ide.h> |
28 | -#endif | |
29 | 27 | #include <initcall.h> |
30 | 28 | #include <init_helpers.h> |
31 | 29 | #ifdef CONFIG_PS2KBD |
... | ... | @@ -611,7 +609,7 @@ |
611 | 609 | } |
612 | 610 | #endif |
613 | 611 | |
614 | -#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE) | |
612 | +#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_IDE) | |
615 | 613 | static int initr_pcmcia(void) |
616 | 614 | { |
617 | 615 | puts("PCMCIA:"); |
... | ... | @@ -620,7 +618,7 @@ |
620 | 618 | } |
621 | 619 | #endif |
622 | 620 | |
623 | -#if defined(CONFIG_CMD_IDE) | |
621 | +#if defined(CONFIG_IDE) | |
624 | 622 | static int initr_ide(void) |
625 | 623 | { |
626 | 624 | #ifdef CONFIG_IDE_8xx_PCCARD |
627 | 625 | |
... | ... | @@ -870,10 +868,10 @@ |
870 | 868 | #ifdef CONFIG_POST |
871 | 869 | initr_post, |
872 | 870 | #endif |
873 | -#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE) | |
871 | +#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_IDE) | |
874 | 872 | initr_pcmcia, |
875 | 873 | #endif |
876 | -#if defined(CONFIG_CMD_IDE) | |
874 | +#if defined(CONFIG_IDE) | |
877 | 875 | initr_ide, |
878 | 876 | #endif |
879 | 877 | #ifdef CONFIG_LAST_STAGE_INIT |
common/ide.c
Changes suppressed. Click to show
1 | -/* | |
2 | - * (C) Copyright 2000-2011 | |
3 | - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | - * | |
5 | - * SPDX-License-Identifier: GPL-2.0+ | |
6 | - */ | |
7 | - | |
8 | -#include <common.h> | |
9 | -#include <ata.h> | |
10 | -#include <dm.h> | |
11 | -#include <ide.h> | |
12 | -#include <watchdog.h> | |
13 | -#include <asm/io.h> | |
14 | - | |
15 | -#ifdef __PPC__ | |
16 | -# define EIEIO __asm__ volatile ("eieio") | |
17 | -# define SYNC __asm__ volatile ("sync") | |
18 | -#else | |
19 | -# define EIEIO /* nothing */ | |
20 | -# define SYNC /* nothing */ | |
21 | -#endif | |
22 | - | |
23 | -/* Current offset for IDE0 / IDE1 bus access */ | |
24 | -ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = { | |
25 | -#if defined(CONFIG_SYS_ATA_IDE0_OFFSET) | |
26 | - CONFIG_SYS_ATA_IDE0_OFFSET, | |
27 | -#endif | |
28 | -#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) && (CONFIG_SYS_IDE_MAXBUS > 1) | |
29 | - CONFIG_SYS_ATA_IDE1_OFFSET, | |
30 | -#endif | |
31 | -}; | |
32 | - | |
33 | -static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS]; | |
34 | - | |
35 | -struct blk_desc ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE]; | |
36 | - | |
37 | -#define IDE_TIME_OUT 2000 /* 2 sec timeout */ | |
38 | - | |
39 | -#define ATAPI_TIME_OUT 7000 /* 7 sec timeout (5 sec seems to work...) */ | |
40 | - | |
41 | -#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */ | |
42 | - | |
43 | -#ifndef CONFIG_SYS_ATA_PORT_ADDR | |
44 | -#define CONFIG_SYS_ATA_PORT_ADDR(port) (port) | |
45 | -#endif | |
46 | - | |
47 | -#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */ | |
48 | -# define DEVICE_LED(x) 0 | |
49 | -# define LED_IDE1 1 | |
50 | -# define LED_IDE2 2 | |
51 | -#endif | |
52 | - | |
53 | -#ifdef CONFIG_IDE_RESET | |
54 | -extern void ide_set_reset(int idereset); | |
55 | - | |
56 | -static void ide_reset(void) | |
57 | -{ | |
58 | - int i; | |
59 | - | |
60 | - for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; ++i) | |
61 | - ide_bus_ok[i] = 0; | |
62 | - for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) | |
63 | - ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; | |
64 | - | |
65 | - ide_set_reset(1); /* assert reset */ | |
66 | - | |
67 | - /* the reset signal shall be asserted for et least 25 us */ | |
68 | - udelay(25); | |
69 | - | |
70 | - WATCHDOG_RESET(); | |
71 | - | |
72 | - /* de-assert RESET signal */ | |
73 | - ide_set_reset(0); | |
74 | - | |
75 | - /* wait 250 ms */ | |
76 | - for (i = 0; i < 250; ++i) | |
77 | - udelay(1000); | |
78 | -} | |
79 | -#else | |
80 | -#define ide_reset() /* dummy */ | |
81 | -#endif /* CONFIG_IDE_RESET */ | |
82 | - | |
83 | -/* | |
84 | - * Wait until Busy bit is off, or timeout (in ms) | |
85 | - * Return last status | |
86 | - */ | |
87 | -static uchar ide_wait(int dev, ulong t) | |
88 | -{ | |
89 | - ulong delay = 10 * t; /* poll every 100 us */ | |
90 | - uchar c; | |
91 | - | |
92 | - while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) { | |
93 | - udelay(100); | |
94 | - if (delay-- == 0) | |
95 | - break; | |
96 | - } | |
97 | - return c; | |
98 | -} | |
99 | - | |
100 | -/* | |
101 | - * copy src to dest, skipping leading and trailing blanks and null | |
102 | - * terminate the string | |
103 | - * "len" is the size of available memory including the terminating '\0' | |
104 | - */ | |
105 | -static void ident_cpy(unsigned char *dst, unsigned char *src, | |
106 | - unsigned int len) | |
107 | -{ | |
108 | - unsigned char *end, *last; | |
109 | - | |
110 | - last = dst; | |
111 | - end = src + len - 1; | |
112 | - | |
113 | - /* reserve space for '\0' */ | |
114 | - if (len < 2) | |
115 | - goto OUT; | |
116 | - | |
117 | - /* skip leading white space */ | |
118 | - while ((*src) && (src < end) && (*src == ' ')) | |
119 | - ++src; | |
120 | - | |
121 | - /* copy string, omitting trailing white space */ | |
122 | - while ((*src) && (src < end)) { | |
123 | - *dst++ = *src; | |
124 | - if (*src++ != ' ') | |
125 | - last = dst; | |
126 | - } | |
127 | -OUT: | |
128 | - *last = '\0'; | |
129 | -} | |
130 | - | |
131 | -#ifdef CONFIG_ATAPI | |
132 | -/**************************************************************************** | |
133 | - * ATAPI Support | |
134 | - */ | |
135 | - | |
136 | -#if defined(CONFIG_IDE_SWAP_IO) | |
137 | -/* since ATAPI may use commands with not 4 bytes alligned length | |
138 | - * we have our own transfer functions, 2 bytes alligned */ | |
139 | -__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) | |
140 | -{ | |
141 | - ushort *dbuf; | |
142 | - volatile ushort *pbuf; | |
143 | - | |
144 | - pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
145 | - dbuf = (ushort *)sect_buf; | |
146 | - | |
147 | - debug("in output data shorts base for read is %lx\n", | |
148 | - (unsigned long) pbuf); | |
149 | - | |
150 | - while (shorts--) { | |
151 | - EIEIO; | |
152 | - *pbuf = *dbuf++; | |
153 | - } | |
154 | -} | |
155 | - | |
156 | -__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) | |
157 | -{ | |
158 | - ushort *dbuf; | |
159 | - volatile ushort *pbuf; | |
160 | - | |
161 | - pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
162 | - dbuf = (ushort *)sect_buf; | |
163 | - | |
164 | - debug("in input data shorts base for read is %lx\n", | |
165 | - (unsigned long) pbuf); | |
166 | - | |
167 | - while (shorts--) { | |
168 | - EIEIO; | |
169 | - *dbuf++ = *pbuf; | |
170 | - } | |
171 | -} | |
172 | - | |
173 | -#else /* ! CONFIG_IDE_SWAP_IO */ | |
174 | -__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) | |
175 | -{ | |
176 | - outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); | |
177 | -} | |
178 | - | |
179 | -__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) | |
180 | -{ | |
181 | - insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); | |
182 | -} | |
183 | - | |
184 | -#endif /* CONFIG_IDE_SWAP_IO */ | |
185 | - | |
186 | -/* | |
187 | - * Wait until (Status & mask) == res, or timeout (in ms) | |
188 | - * Return last status | |
189 | - * This is used since some ATAPI CD ROMs clears their Busy Bit first | |
190 | - * and then they set their DRQ Bit | |
191 | - */ | |
192 | -static uchar atapi_wait_mask(int dev, ulong t, uchar mask, uchar res) | |
193 | -{ | |
194 | - ulong delay = 10 * t; /* poll every 100 us */ | |
195 | - uchar c; | |
196 | - | |
197 | - /* prevents to read the status before valid */ | |
198 | - c = ide_inb(dev, ATA_DEV_CTL); | |
199 | - | |
200 | - while (((c = ide_inb(dev, ATA_STATUS)) & mask) != res) { | |
201 | - /* break if error occurs (doesn't make sense to wait more) */ | |
202 | - if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) | |
203 | - break; | |
204 | - udelay(100); | |
205 | - if (delay-- == 0) | |
206 | - break; | |
207 | - } | |
208 | - return c; | |
209 | -} | |
210 | - | |
211 | -/* | |
212 | - * issue an atapi command | |
213 | - */ | |
214 | -unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen, | |
215 | - unsigned char *buffer, int buflen) | |
216 | -{ | |
217 | - unsigned char c, err, mask, res; | |
218 | - int n; | |
219 | - | |
220 | - ide_led(DEVICE_LED(device), 1); /* LED on */ | |
221 | - | |
222 | - /* Select device | |
223 | - */ | |
224 | - mask = ATA_STAT_BUSY | ATA_STAT_DRQ; | |
225 | - res = 0; | |
226 | - ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
227 | - c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); | |
228 | - if ((c & mask) != res) { | |
229 | - printf("ATAPI_ISSUE: device %d not ready status %X\n", device, | |
230 | - c); | |
231 | - err = 0xFF; | |
232 | - goto AI_OUT; | |
233 | - } | |
234 | - /* write taskfile */ | |
235 | - ide_outb(device, ATA_ERROR_REG, 0); /* no DMA, no overlaped */ | |
236 | - ide_outb(device, ATA_SECT_CNT, 0); | |
237 | - ide_outb(device, ATA_SECT_NUM, 0); | |
238 | - ide_outb(device, ATA_CYL_LOW, (unsigned char) (buflen & 0xFF)); | |
239 | - ide_outb(device, ATA_CYL_HIGH, | |
240 | - (unsigned char) ((buflen >> 8) & 0xFF)); | |
241 | - ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
242 | - | |
243 | - ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET); | |
244 | - udelay(50); | |
245 | - | |
246 | - mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR; | |
247 | - res = ATA_STAT_DRQ; | |
248 | - c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); | |
249 | - | |
250 | - if ((c & mask) != res) { /* DRQ must be 1, BSY 0 */ | |
251 | - printf("ATAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n", | |
252 | - device, c); | |
253 | - err = 0xFF; | |
254 | - goto AI_OUT; | |
255 | - } | |
256 | - | |
257 | - /* write command block */ | |
258 | - ide_output_data_shorts(device, (unsigned short *)ccb, ccblen / 2); | |
259 | - | |
260 | - /* ATAPI Command written wait for completition */ | |
261 | - udelay(5000); /* device must set bsy */ | |
262 | - | |
263 | - mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR; | |
264 | - /* | |
265 | - * if no data wait for DRQ = 0 BSY = 0 | |
266 | - * if data wait for DRQ = 1 BSY = 0 | |
267 | - */ | |
268 | - res = 0; | |
269 | - if (buflen) | |
270 | - res = ATA_STAT_DRQ; | |
271 | - c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); | |
272 | - if ((c & mask) != res) { | |
273 | - if (c & ATA_STAT_ERR) { | |
274 | - err = (ide_inb(device, ATA_ERROR_REG)) >> 4; | |
275 | - debug("atapi_issue 1 returned sense key %X status %02X\n", | |
276 | - err, c); | |
277 | - } else { | |
278 | - printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x) status 0x%02x\n", | |
279 | - ccb[0], c); | |
280 | - err = 0xFF; | |
281 | - } | |
282 | - goto AI_OUT; | |
283 | - } | |
284 | - n = ide_inb(device, ATA_CYL_HIGH); | |
285 | - n <<= 8; | |
286 | - n += ide_inb(device, ATA_CYL_LOW); | |
287 | - if (n > buflen) { | |
288 | - printf("ERROR, transfer bytes %d requested only %d\n", n, | |
289 | - buflen); | |
290 | - err = 0xff; | |
291 | - goto AI_OUT; | |
292 | - } | |
293 | - if ((n == 0) && (buflen < 0)) { | |
294 | - printf("ERROR, transfer bytes %d requested %d\n", n, buflen); | |
295 | - err = 0xff; | |
296 | - goto AI_OUT; | |
297 | - } | |
298 | - if (n != buflen) { | |
299 | - debug("WARNING, transfer bytes %d not equal with requested %d\n", | |
300 | - n, buflen); | |
301 | - } | |
302 | - if (n != 0) { /* data transfer */ | |
303 | - debug("ATAPI_ISSUE: %d Bytes to transfer\n", n); | |
304 | - /* we transfer shorts */ | |
305 | - n >>= 1; | |
306 | - /* ok now decide if it is an in or output */ | |
307 | - if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) { | |
308 | - debug("Write to device\n"); | |
309 | - ide_output_data_shorts(device, (unsigned short *)buffer, | |
310 | - n); | |
311 | - } else { | |
312 | - debug("Read from device @ %p shorts %d\n", buffer, n); | |
313 | - ide_input_data_shorts(device, (unsigned short *)buffer, | |
314 | - n); | |
315 | - } | |
316 | - } | |
317 | - udelay(5000); /* seems that some CD ROMs need this... */ | |
318 | - mask = ATA_STAT_BUSY | ATA_STAT_ERR; | |
319 | - res = 0; | |
320 | - c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); | |
321 | - if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) { | |
322 | - err = (ide_inb(device, ATA_ERROR_REG) >> 4); | |
323 | - debug("atapi_issue 2 returned sense key %X status %X\n", err, | |
324 | - c); | |
325 | - } else { | |
326 | - err = 0; | |
327 | - } | |
328 | -AI_OUT: | |
329 | - ide_led(DEVICE_LED(device), 0); /* LED off */ | |
330 | - return err; | |
331 | -} | |
332 | - | |
333 | -/* | |
334 | - * sending the command to atapi_issue. If an status other than good | |
335 | - * returns, an request_sense will be issued | |
336 | - */ | |
337 | - | |
338 | -#define ATAPI_DRIVE_NOT_READY 100 | |
339 | -#define ATAPI_UNIT_ATTN 10 | |
340 | - | |
341 | -unsigned char atapi_issue_autoreq(int device, | |
342 | - unsigned char *ccb, | |
343 | - int ccblen, | |
344 | - unsigned char *buffer, int buflen) | |
345 | -{ | |
346 | - unsigned char sense_data[18], sense_ccb[12]; | |
347 | - unsigned char res, key, asc, ascq; | |
348 | - int notready, unitattn; | |
349 | - | |
350 | - unitattn = ATAPI_UNIT_ATTN; | |
351 | - notready = ATAPI_DRIVE_NOT_READY; | |
352 | - | |
353 | -retry: | |
354 | - res = atapi_issue(device, ccb, ccblen, buffer, buflen); | |
355 | - if (res == 0) | |
356 | - return 0; /* Ok */ | |
357 | - | |
358 | - if (res == 0xFF) | |
359 | - return 0xFF; /* error */ | |
360 | - | |
361 | - debug("(auto_req)atapi_issue returned sense key %X\n", res); | |
362 | - | |
363 | - memset(sense_ccb, 0, sizeof(sense_ccb)); | |
364 | - memset(sense_data, 0, sizeof(sense_data)); | |
365 | - sense_ccb[0] = ATAPI_CMD_REQ_SENSE; | |
366 | - sense_ccb[4] = 18; /* allocation Length */ | |
367 | - | |
368 | - res = atapi_issue(device, sense_ccb, 12, sense_data, 18); | |
369 | - key = (sense_data[2] & 0xF); | |
370 | - asc = (sense_data[12]); | |
371 | - ascq = (sense_data[13]); | |
372 | - | |
373 | - debug("ATAPI_CMD_REQ_SENSE returned %x\n", res); | |
374 | - debug(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n", | |
375 | - sense_data[0], key, asc, ascq); | |
376 | - | |
377 | - if ((key == 0)) | |
378 | - return 0; /* ok device ready */ | |
379 | - | |
380 | - if ((key == 6) || (asc == 0x29) || (asc == 0x28)) { /* Unit Attention */ | |
381 | - if (unitattn-- > 0) { | |
382 | - udelay(200 * 1000); | |
383 | - goto retry; | |
384 | - } | |
385 | - printf("Unit Attention, tried %d\n", ATAPI_UNIT_ATTN); | |
386 | - goto error; | |
387 | - } | |
388 | - if ((asc == 0x4) && (ascq == 0x1)) { | |
389 | - /* not ready, but will be ready soon */ | |
390 | - if (notready-- > 0) { | |
391 | - udelay(200 * 1000); | |
392 | - goto retry; | |
393 | - } | |
394 | - printf("Drive not ready, tried %d times\n", | |
395 | - ATAPI_DRIVE_NOT_READY); | |
396 | - goto error; | |
397 | - } | |
398 | - if (asc == 0x3a) { | |
399 | - debug("Media not present\n"); | |
400 | - goto error; | |
401 | - } | |
402 | - | |
403 | - printf("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n", key, asc, | |
404 | - ascq); | |
405 | -error: | |
406 | - debug("ERROR Sense key %02X ASC %02X ASCQ %02X\n", key, asc, ascq); | |
407 | - return 0xFF; | |
408 | -} | |
409 | - | |
410 | -/* | |
411 | - * atapi_read: | |
412 | - * we transfer only one block per command, since the multiple DRQ per | |
413 | - * command is not yet implemented | |
414 | - */ | |
415 | -#define ATAPI_READ_MAX_BYTES 2048 /* we read max 2kbytes */ | |
416 | -#define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */ | |
417 | -#define ATAPI_READ_MAX_BLOCK (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE) | |
418 | - | |
419 | -ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, | |
420 | - void *buffer) | |
421 | -{ | |
422 | - int device = block_dev->devnum; | |
423 | - ulong n = 0; | |
424 | - unsigned char ccb[12]; /* Command descriptor block */ | |
425 | - ulong cnt; | |
426 | - | |
427 | - debug("atapi_read dev %d start " LBAF " blocks " LBAF | |
428 | - " buffer at %lX\n", device, blknr, blkcnt, (ulong) buffer); | |
429 | - | |
430 | - do { | |
431 | - if (blkcnt > ATAPI_READ_MAX_BLOCK) | |
432 | - cnt = ATAPI_READ_MAX_BLOCK; | |
433 | - else | |
434 | - cnt = blkcnt; | |
435 | - | |
436 | - ccb[0] = ATAPI_CMD_READ_12; | |
437 | - ccb[1] = 0; /* reserved */ | |
438 | - ccb[2] = (unsigned char) (blknr >> 24) & 0xFF; /* MSB Block */ | |
439 | - ccb[3] = (unsigned char) (blknr >> 16) & 0xFF; /* */ | |
440 | - ccb[4] = (unsigned char) (blknr >> 8) & 0xFF; | |
441 | - ccb[5] = (unsigned char) blknr & 0xFF; /* LSB Block */ | |
442 | - ccb[6] = (unsigned char) (cnt >> 24) & 0xFF; /* MSB Block cnt */ | |
443 | - ccb[7] = (unsigned char) (cnt >> 16) & 0xFF; | |
444 | - ccb[8] = (unsigned char) (cnt >> 8) & 0xFF; | |
445 | - ccb[9] = (unsigned char) cnt & 0xFF; /* LSB Block */ | |
446 | - ccb[10] = 0; /* reserved */ | |
447 | - ccb[11] = 0; /* reserved */ | |
448 | - | |
449 | - if (atapi_issue_autoreq(device, ccb, 12, | |
450 | - (unsigned char *)buffer, | |
451 | - cnt * ATAPI_READ_BLOCK_SIZE) | |
452 | - == 0xFF) { | |
453 | - return n; | |
454 | - } | |
455 | - n += cnt; | |
456 | - blkcnt -= cnt; | |
457 | - blknr += cnt; | |
458 | - buffer += (cnt * ATAPI_READ_BLOCK_SIZE); | |
459 | - } while (blkcnt > 0); | |
460 | - return n; | |
461 | -} | |
462 | - | |
463 | -static void atapi_inquiry(struct blk_desc *dev_desc) | |
464 | -{ | |
465 | - unsigned char ccb[12]; /* Command descriptor block */ | |
466 | - unsigned char iobuf[64]; /* temp buf */ | |
467 | - unsigned char c; | |
468 | - int device; | |
469 | - | |
470 | - device = dev_desc->devnum; | |
471 | - dev_desc->type = DEV_TYPE_UNKNOWN; /* not yet valid */ | |
472 | - dev_desc->block_read = atapi_read; | |
473 | - | |
474 | - memset(ccb, 0, sizeof(ccb)); | |
475 | - memset(iobuf, 0, sizeof(iobuf)); | |
476 | - | |
477 | - ccb[0] = ATAPI_CMD_INQUIRY; | |
478 | - ccb[4] = 40; /* allocation Legnth */ | |
479 | - c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 40); | |
480 | - | |
481 | - debug("ATAPI_CMD_INQUIRY returned %x\n", c); | |
482 | - if (c != 0) | |
483 | - return; | |
484 | - | |
485 | - /* copy device ident strings */ | |
486 | - ident_cpy((unsigned char *)dev_desc->vendor, &iobuf[8], 8); | |
487 | - ident_cpy((unsigned char *)dev_desc->product, &iobuf[16], 16); | |
488 | - ident_cpy((unsigned char *)dev_desc->revision, &iobuf[32], 5); | |
489 | - | |
490 | - dev_desc->lun = 0; | |
491 | - dev_desc->lba = 0; | |
492 | - dev_desc->blksz = 0; | |
493 | - dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz)); | |
494 | - dev_desc->type = iobuf[0] & 0x1f; | |
495 | - | |
496 | - if ((iobuf[1] & 0x80) == 0x80) | |
497 | - dev_desc->removable = 1; | |
498 | - else | |
499 | - dev_desc->removable = 0; | |
500 | - | |
501 | - memset(ccb, 0, sizeof(ccb)); | |
502 | - memset(iobuf, 0, sizeof(iobuf)); | |
503 | - ccb[0] = ATAPI_CMD_START_STOP; | |
504 | - ccb[4] = 0x03; /* start */ | |
505 | - | |
506 | - c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0); | |
507 | - | |
508 | - debug("ATAPI_CMD_START_STOP returned %x\n", c); | |
509 | - if (c != 0) | |
510 | - return; | |
511 | - | |
512 | - memset(ccb, 0, sizeof(ccb)); | |
513 | - memset(iobuf, 0, sizeof(iobuf)); | |
514 | - c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0); | |
515 | - | |
516 | - debug("ATAPI_CMD_UNIT_TEST_READY returned %x\n", c); | |
517 | - if (c != 0) | |
518 | - return; | |
519 | - | |
520 | - memset(ccb, 0, sizeof(ccb)); | |
521 | - memset(iobuf, 0, sizeof(iobuf)); | |
522 | - ccb[0] = ATAPI_CMD_READ_CAP; | |
523 | - c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 8); | |
524 | - debug("ATAPI_CMD_READ_CAP returned %x\n", c); | |
525 | - if (c != 0) | |
526 | - return; | |
527 | - | |
528 | - debug("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n", | |
529 | - iobuf[0], iobuf[1], iobuf[2], iobuf[3], | |
530 | - iobuf[4], iobuf[5], iobuf[6], iobuf[7]); | |
531 | - | |
532 | - dev_desc->lba = ((unsigned long) iobuf[0] << 24) + | |
533 | - ((unsigned long) iobuf[1] << 16) + | |
534 | - ((unsigned long) iobuf[2] << 8) + ((unsigned long) iobuf[3]); | |
535 | - dev_desc->blksz = ((unsigned long) iobuf[4] << 24) + | |
536 | - ((unsigned long) iobuf[5] << 16) + | |
537 | - ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]); | |
538 | - dev_desc->log2blksz = LOG2(dev_desc->blksz); | |
539 | -#ifdef CONFIG_LBA48 | |
540 | - /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */ | |
541 | - dev_desc->lba48 = 0; | |
542 | -#endif | |
543 | - return; | |
544 | -} | |
545 | - | |
546 | -#endif /* CONFIG_ATAPI */ | |
547 | - | |
548 | -static void ide_ident(struct blk_desc *dev_desc) | |
549 | -{ | |
550 | - unsigned char c; | |
551 | - hd_driveid_t iop; | |
552 | - | |
553 | -#ifdef CONFIG_ATAPI | |
554 | - int retries = 0; | |
555 | -#endif | |
556 | - int device; | |
557 | - | |
558 | - device = dev_desc->devnum; | |
559 | - printf(" Device %d: ", device); | |
560 | - | |
561 | - ide_led(DEVICE_LED(device), 1); /* LED on */ | |
562 | - /* Select device | |
563 | - */ | |
564 | - ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
565 | - dev_desc->if_type = IF_TYPE_IDE; | |
566 | -#ifdef CONFIG_ATAPI | |
567 | - | |
568 | - retries = 0; | |
569 | - | |
570 | - /* Warning: This will be tricky to read */ | |
571 | - while (retries <= 1) { | |
572 | - /* check signature */ | |
573 | - if ((ide_inb(device, ATA_SECT_CNT) == 0x01) && | |
574 | - (ide_inb(device, ATA_SECT_NUM) == 0x01) && | |
575 | - (ide_inb(device, ATA_CYL_LOW) == 0x14) && | |
576 | - (ide_inb(device, ATA_CYL_HIGH) == 0xEB)) { | |
577 | - /* ATAPI Signature found */ | |
578 | - dev_desc->if_type = IF_TYPE_ATAPI; | |
579 | - /* | |
580 | - * Start Ident Command | |
581 | - */ | |
582 | - ide_outb(device, ATA_COMMAND, ATAPI_CMD_IDENT); | |
583 | - /* | |
584 | - * Wait for completion - ATAPI devices need more time | |
585 | - * to become ready | |
586 | - */ | |
587 | - c = ide_wait(device, ATAPI_TIME_OUT); | |
588 | - } else | |
589 | -#endif | |
590 | - { | |
591 | - /* | |
592 | - * Start Ident Command | |
593 | - */ | |
594 | - ide_outb(device, ATA_COMMAND, ATA_CMD_IDENT); | |
595 | - | |
596 | - /* | |
597 | - * Wait for completion | |
598 | - */ | |
599 | - c = ide_wait(device, IDE_TIME_OUT); | |
600 | - } | |
601 | - ide_led(DEVICE_LED(device), 0); /* LED off */ | |
602 | - | |
603 | - if (((c & ATA_STAT_DRQ) == 0) || | |
604 | - ((c & (ATA_STAT_FAULT | ATA_STAT_ERR)) != 0)) { | |
605 | -#ifdef CONFIG_ATAPI | |
606 | - { | |
607 | - /* | |
608 | - * Need to soft reset the device | |
609 | - * in case it's an ATAPI... | |
610 | - */ | |
611 | - debug("Retrying...\n"); | |
612 | - ide_outb(device, ATA_DEV_HD, | |
613 | - ATA_LBA | ATA_DEVICE(device)); | |
614 | - udelay(100000); | |
615 | - ide_outb(device, ATA_COMMAND, 0x08); | |
616 | - udelay(500000); /* 500 ms */ | |
617 | - } | |
618 | - /* | |
619 | - * Select device | |
620 | - */ | |
621 | - ide_outb(device, ATA_DEV_HD, | |
622 | - ATA_LBA | ATA_DEVICE(device)); | |
623 | - retries++; | |
624 | -#else | |
625 | - return; | |
626 | -#endif | |
627 | - } | |
628 | -#ifdef CONFIG_ATAPI | |
629 | - else | |
630 | - break; | |
631 | - } /* see above - ugly to read */ | |
632 | - | |
633 | - if (retries == 2) /* Not found */ | |
634 | - return; | |
635 | -#endif | |
636 | - | |
637 | - ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS); | |
638 | - | |
639 | - ident_cpy((unsigned char *)dev_desc->revision, iop.fw_rev, | |
640 | - sizeof(dev_desc->revision)); | |
641 | - ident_cpy((unsigned char *)dev_desc->vendor, iop.model, | |
642 | - sizeof(dev_desc->vendor)); | |
643 | - ident_cpy((unsigned char *)dev_desc->product, iop.serial_no, | |
644 | - sizeof(dev_desc->product)); | |
645 | -#ifdef __LITTLE_ENDIAN | |
646 | - /* | |
647 | - * firmware revision, model, and serial number have Big Endian Byte | |
648 | - * order in Word. Convert all three to little endian. | |
649 | - * | |
650 | - * See CF+ and CompactFlash Specification Revision 2.0: | |
651 | - * 6.2.1.6: Identify Drive, Table 39 for more details | |
652 | - */ | |
653 | - | |
654 | - strswab(dev_desc->revision); | |
655 | - strswab(dev_desc->vendor); | |
656 | - strswab(dev_desc->product); | |
657 | -#endif /* __LITTLE_ENDIAN */ | |
658 | - | |
659 | - if ((iop.config & 0x0080) == 0x0080) | |
660 | - dev_desc->removable = 1; | |
661 | - else | |
662 | - dev_desc->removable = 0; | |
663 | - | |
664 | -#ifdef CONFIG_ATAPI | |
665 | - if (dev_desc->if_type == IF_TYPE_ATAPI) { | |
666 | - atapi_inquiry(dev_desc); | |
667 | - return; | |
668 | - } | |
669 | -#endif /* CONFIG_ATAPI */ | |
670 | - | |
671 | -#ifdef __BIG_ENDIAN | |
672 | - /* swap shorts */ | |
673 | - dev_desc->lba = (iop.lba_capacity << 16) | (iop.lba_capacity >> 16); | |
674 | -#else /* ! __BIG_ENDIAN */ | |
675 | - /* | |
676 | - * do not swap shorts on little endian | |
677 | - * | |
678 | - * See CF+ and CompactFlash Specification Revision 2.0: | |
679 | - * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details. | |
680 | - */ | |
681 | - dev_desc->lba = iop.lba_capacity; | |
682 | -#endif /* __BIG_ENDIAN */ | |
683 | - | |
684 | -#ifdef CONFIG_LBA48 | |
685 | - if (iop.command_set_2 & 0x0400) { /* LBA 48 support */ | |
686 | - dev_desc->lba48 = 1; | |
687 | - dev_desc->lba = (unsigned long long) iop.lba48_capacity[0] | | |
688 | - ((unsigned long long) iop.lba48_capacity[1] << 16) | | |
689 | - ((unsigned long long) iop.lba48_capacity[2] << 32) | | |
690 | - ((unsigned long long) iop.lba48_capacity[3] << 48); | |
691 | - } else { | |
692 | - dev_desc->lba48 = 0; | |
693 | - } | |
694 | -#endif /* CONFIG_LBA48 */ | |
695 | - /* assuming HD */ | |
696 | - dev_desc->type = DEV_TYPE_HARDDISK; | |
697 | - dev_desc->blksz = ATA_BLOCKSIZE; | |
698 | - dev_desc->log2blksz = LOG2(dev_desc->blksz); | |
699 | - dev_desc->lun = 0; /* just to fill something in... */ | |
700 | - | |
701 | -#if 0 /* only used to test the powersaving mode, | |
702 | - * if enabled, the drive goes after 5 sec | |
703 | - * in standby mode */ | |
704 | - ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
705 | - c = ide_wait(device, IDE_TIME_OUT); | |
706 | - ide_outb(device, ATA_SECT_CNT, 1); | |
707 | - ide_outb(device, ATA_LBA_LOW, 0); | |
708 | - ide_outb(device, ATA_LBA_MID, 0); | |
709 | - ide_outb(device, ATA_LBA_HIGH, 0); | |
710 | - ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
711 | - ide_outb(device, ATA_COMMAND, 0xe3); | |
712 | - udelay(50); | |
713 | - c = ide_wait(device, IDE_TIME_OUT); /* can't take over 500 ms */ | |
714 | -#endif | |
715 | -} | |
716 | - | |
717 | -__weak void ide_led(uchar led, uchar status) | |
718 | -{ | |
719 | -#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */ | |
720 | - static uchar led_buffer; /* Buffer for current LED status */ | |
721 | - | |
722 | - uchar *led_port = LED_PORT; | |
723 | - | |
724 | - if (status) /* switch LED on */ | |
725 | - led_buffer |= led; | |
726 | - else /* switch LED off */ | |
727 | - led_buffer &= ~led; | |
728 | - | |
729 | - *led_port = led_buffer; | |
730 | -#endif | |
731 | -} | |
732 | - | |
733 | -__weak void ide_outb(int dev, int port, unsigned char val) | |
734 | -{ | |
735 | - debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n", | |
736 | - dev, port, val, | |
737 | - (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port))); | |
738 | - | |
739 | -#if defined(CONFIG_IDE_AHB) | |
740 | - if (port) { | |
741 | - /* write command */ | |
742 | - ide_write_register(dev, port, val); | |
743 | - } else { | |
744 | - /* write data */ | |
745 | - outb(val, (ATA_CURR_BASE(dev))); | |
746 | - } | |
747 | -#else | |
748 | - outb(val, (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port))); | |
749 | -#endif | |
750 | -} | |
751 | - | |
752 | -__weak unsigned char ide_inb(int dev, int port) | |
753 | -{ | |
754 | - uchar val; | |
755 | - | |
756 | -#if defined(CONFIG_IDE_AHB) | |
757 | - val = ide_read_register(dev, port); | |
758 | -#else | |
759 | - val = inb((ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port))); | |
760 | -#endif | |
761 | - | |
762 | - debug("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n", | |
763 | - dev, port, | |
764 | - (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)), val); | |
765 | - return val; | |
766 | -} | |
767 | - | |
768 | -void ide_init(void) | |
769 | -{ | |
770 | - unsigned char c; | |
771 | - int i, bus; | |
772 | - | |
773 | -#ifdef CONFIG_IDE_8xx_PCCARD | |
774 | - extern int ide_devices_found; /* Initialized in check_ide_device() */ | |
775 | -#endif /* CONFIG_IDE_8xx_PCCARD */ | |
776 | - | |
777 | -#ifdef CONFIG_IDE_PREINIT | |
778 | - WATCHDOG_RESET(); | |
779 | - | |
780 | - if (ide_preinit()) { | |
781 | - puts("ide_preinit failed\n"); | |
782 | - return; | |
783 | - } | |
784 | -#endif /* CONFIG_IDE_PREINIT */ | |
785 | - | |
786 | - WATCHDOG_RESET(); | |
787 | - | |
788 | - /* | |
789 | - * Reset the IDE just to be sure. | |
790 | - * Light LED's to show | |
791 | - */ | |
792 | - ide_led((LED_IDE1 | LED_IDE2), 1); /* LED's on */ | |
793 | - | |
794 | - /* ATAPI Drives seems to need a proper IDE Reset */ | |
795 | - ide_reset(); | |
796 | - | |
797 | -#ifdef CONFIG_IDE_INIT_POSTRESET | |
798 | - WATCHDOG_RESET(); | |
799 | - | |
800 | - if (ide_init_postreset()) { | |
801 | - puts("ide_preinit_postreset failed\n"); | |
802 | - return; | |
803 | - } | |
804 | -#endif /* CONFIG_IDE_INIT_POSTRESET */ | |
805 | - | |
806 | - /* | |
807 | - * Wait for IDE to get ready. | |
808 | - * According to spec, this can take up to 31 seconds! | |
809 | - */ | |
810 | - for (bus = 0; bus < CONFIG_SYS_IDE_MAXBUS; ++bus) { | |
811 | - int dev = | |
812 | - bus * (CONFIG_SYS_IDE_MAXDEVICE / | |
813 | - CONFIG_SYS_IDE_MAXBUS); | |
814 | - | |
815 | -#ifdef CONFIG_IDE_8xx_PCCARD | |
816 | - /* Skip non-ide devices from probing */ | |
817 | - if ((ide_devices_found & (1 << bus)) == 0) { | |
818 | - ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */ | |
819 | - continue; | |
820 | - } | |
821 | -#endif | |
822 | - printf("Bus %d: ", bus); | |
823 | - | |
824 | - ide_bus_ok[bus] = 0; | |
825 | - | |
826 | - /* Select device | |
827 | - */ | |
828 | - udelay(100000); /* 100 ms */ | |
829 | - ide_outb(dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev)); | |
830 | - udelay(100000); /* 100 ms */ | |
831 | - i = 0; | |
832 | - do { | |
833 | - udelay(10000); /* 10 ms */ | |
834 | - | |
835 | - c = ide_inb(dev, ATA_STATUS); | |
836 | - i++; | |
837 | - if (i > (ATA_RESET_TIME * 100)) { | |
838 | - puts("** Timeout **\n"); | |
839 | - /* LED's off */ | |
840 | - ide_led((LED_IDE1 | LED_IDE2), 0); | |
841 | - return; | |
842 | - } | |
843 | - if ((i >= 100) && ((i % 100) == 0)) | |
844 | - putc('.'); | |
845 | - | |
846 | - } while (c & ATA_STAT_BUSY); | |
847 | - | |
848 | - if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) { | |
849 | - puts("not available "); | |
850 | - debug("Status = 0x%02X ", c); | |
851 | -#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */ | |
852 | - } else if ((c & ATA_STAT_READY) == 0) { | |
853 | - puts("not available "); | |
854 | - debug("Status = 0x%02X ", c); | |
855 | -#endif | |
856 | - } else { | |
857 | - puts("OK "); | |
858 | - ide_bus_ok[bus] = 1; | |
859 | - } | |
860 | - WATCHDOG_RESET(); | |
861 | - } | |
862 | - | |
863 | - putc('\n'); | |
864 | - | |
865 | - ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */ | |
866 | - | |
867 | - for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) { | |
868 | - int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2; | |
869 | - ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; | |
870 | - ide_dev_desc[i].if_type = IF_TYPE_IDE; | |
871 | - ide_dev_desc[i].devnum = i; | |
872 | - ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN; | |
873 | - ide_dev_desc[i].blksz = 0; | |
874 | - ide_dev_desc[i].log2blksz = | |
875 | - LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz)); | |
876 | - ide_dev_desc[i].lba = 0; | |
877 | -#ifndef CONFIG_BLK | |
878 | - ide_dev_desc[i].block_read = ide_read; | |
879 | - ide_dev_desc[i].block_write = ide_write; | |
880 | -#endif | |
881 | - if (!ide_bus_ok[IDE_BUS(i)]) | |
882 | - continue; | |
883 | - ide_led(led, 1); /* LED on */ | |
884 | - ide_ident(&ide_dev_desc[i]); | |
885 | - ide_led(led, 0); /* LED off */ | |
886 | - dev_print(&ide_dev_desc[i]); | |
887 | - | |
888 | - if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) { | |
889 | - /* initialize partition type */ | |
890 | - part_init(&ide_dev_desc[i]); | |
891 | - } | |
892 | - } | |
893 | - WATCHDOG_RESET(); | |
894 | -} | |
895 | - | |
896 | -/* We only need to swap data if we are running on a big endian cpu. */ | |
897 | -#if defined(__LITTLE_ENDIAN) | |
898 | -__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) | |
899 | -{ | |
900 | - ide_input_data(dev, sect_buf, words); | |
901 | -} | |
902 | -#else | |
903 | -__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) | |
904 | -{ | |
905 | - volatile ushort *pbuf = | |
906 | - (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
907 | - ushort *dbuf = (ushort *)sect_buf; | |
908 | - | |
909 | - debug("in input swap data base for read is %lx\n", | |
910 | - (unsigned long) pbuf); | |
911 | - | |
912 | - while (words--) { | |
913 | -#ifdef __MIPS__ | |
914 | - *dbuf++ = swab16p((u16 *)pbuf); | |
915 | - *dbuf++ = swab16p((u16 *)pbuf); | |
916 | -#else | |
917 | - *dbuf++ = ld_le16(pbuf); | |
918 | - *dbuf++ = ld_le16(pbuf); | |
919 | -#endif /* !MIPS */ | |
920 | - } | |
921 | -} | |
922 | -#endif /* __LITTLE_ENDIAN */ | |
923 | - | |
924 | - | |
925 | -#if defined(CONFIG_IDE_SWAP_IO) | |
926 | -__weak void ide_output_data(int dev, const ulong *sect_buf, int words) | |
927 | -{ | |
928 | - ushort *dbuf; | |
929 | - volatile ushort *pbuf; | |
930 | - | |
931 | - pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
932 | - dbuf = (ushort *)sect_buf; | |
933 | - while (words--) { | |
934 | - EIEIO; | |
935 | - *pbuf = *dbuf++; | |
936 | - EIEIO; | |
937 | - *pbuf = *dbuf++; | |
938 | - } | |
939 | -} | |
940 | -#else /* ! CONFIG_IDE_SWAP_IO */ | |
941 | -__weak void ide_output_data(int dev, const ulong *sect_buf, int words) | |
942 | -{ | |
943 | -#if defined(CONFIG_IDE_AHB) | |
944 | - ide_write_data(dev, sect_buf, words); | |
945 | -#else | |
946 | - outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1); | |
947 | -#endif | |
948 | -} | |
949 | -#endif /* CONFIG_IDE_SWAP_IO */ | |
950 | - | |
951 | -#if defined(CONFIG_IDE_SWAP_IO) | |
952 | -__weak void ide_input_data(int dev, ulong *sect_buf, int words) | |
953 | -{ | |
954 | - ushort *dbuf; | |
955 | - volatile ushort *pbuf; | |
956 | - | |
957 | - pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
958 | - dbuf = (ushort *)sect_buf; | |
959 | - | |
960 | - debug("in input data base for read is %lx\n", (unsigned long) pbuf); | |
961 | - | |
962 | - while (words--) { | |
963 | - EIEIO; | |
964 | - *dbuf++ = *pbuf; | |
965 | - EIEIO; | |
966 | - *dbuf++ = *pbuf; | |
967 | - } | |
968 | -} | |
969 | -#else /* ! CONFIG_IDE_SWAP_IO */ | |
970 | -__weak void ide_input_data(int dev, ulong *sect_buf, int words) | |
971 | -{ | |
972 | -#if defined(CONFIG_IDE_AHB) | |
973 | - ide_read_data(dev, sect_buf, words); | |
974 | -#else | |
975 | - insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1); | |
976 | -#endif | |
977 | -} | |
978 | - | |
979 | -#endif /* CONFIG_IDE_SWAP_IO */ | |
980 | - | |
981 | -#ifdef CONFIG_BLK | |
982 | -ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, | |
983 | - void *buffer) | |
984 | -#else | |
985 | -ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, | |
986 | - void *buffer) | |
987 | -#endif | |
988 | -{ | |
989 | -#ifdef CONFIG_BLK | |
990 | - struct blk_desc *block_dev = dev_get_uclass_platdata(dev); | |
991 | -#endif | |
992 | - int device = block_dev->devnum; | |
993 | - ulong n = 0; | |
994 | - unsigned char c; | |
995 | - unsigned char pwrsave = 0; /* power save */ | |
996 | - | |
997 | -#ifdef CONFIG_LBA48 | |
998 | - unsigned char lba48 = 0; | |
999 | - | |
1000 | - if (blknr & 0x0000fffff0000000ULL) { | |
1001 | - /* more than 28 bits used, use 48bit mode */ | |
1002 | - lba48 = 1; | |
1003 | - } | |
1004 | -#endif | |
1005 | - debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n", | |
1006 | - device, blknr, blkcnt, (ulong) buffer); | |
1007 | - | |
1008 | - ide_led(DEVICE_LED(device), 1); /* LED on */ | |
1009 | - | |
1010 | - /* Select device | |
1011 | - */ | |
1012 | - ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
1013 | - c = ide_wait(device, IDE_TIME_OUT); | |
1014 | - | |
1015 | - if (c & ATA_STAT_BUSY) { | |
1016 | - printf("IDE read: device %d not ready\n", device); | |
1017 | - goto IDE_READ_E; | |
1018 | - } | |
1019 | - | |
1020 | - /* first check if the drive is in Powersaving mode, if yes, | |
1021 | - * increase the timeout value */ | |
1022 | - ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_PWR); | |
1023 | - udelay(50); | |
1024 | - | |
1025 | - c = ide_wait(device, IDE_TIME_OUT); /* can't take over 500 ms */ | |
1026 | - | |
1027 | - if (c & ATA_STAT_BUSY) { | |
1028 | - printf("IDE read: device %d not ready\n", device); | |
1029 | - goto IDE_READ_E; | |
1030 | - } | |
1031 | - if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) { | |
1032 | - printf("No Powersaving mode %X\n", c); | |
1033 | - } else { | |
1034 | - c = ide_inb(device, ATA_SECT_CNT); | |
1035 | - debug("Powersaving %02X\n", c); | |
1036 | - if (c == 0) | |
1037 | - pwrsave = 1; | |
1038 | - } | |
1039 | - | |
1040 | - | |
1041 | - while (blkcnt-- > 0) { | |
1042 | - c = ide_wait(device, IDE_TIME_OUT); | |
1043 | - | |
1044 | - if (c & ATA_STAT_BUSY) { | |
1045 | - printf("IDE read: device %d not ready\n", device); | |
1046 | - break; | |
1047 | - } | |
1048 | -#ifdef CONFIG_LBA48 | |
1049 | - if (lba48) { | |
1050 | - /* write high bits */ | |
1051 | - ide_outb(device, ATA_SECT_CNT, 0); | |
1052 | - ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); | |
1053 | -#ifdef CONFIG_SYS_64BIT_LBA | |
1054 | - ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF); | |
1055 | - ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); | |
1056 | -#else | |
1057 | - ide_outb(device, ATA_LBA_MID, 0); | |
1058 | - ide_outb(device, ATA_LBA_HIGH, 0); | |
1059 | -#endif | |
1060 | - } | |
1061 | -#endif | |
1062 | - ide_outb(device, ATA_SECT_CNT, 1); | |
1063 | - ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF); | |
1064 | - ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF); | |
1065 | - ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); | |
1066 | - | |
1067 | -#ifdef CONFIG_LBA48 | |
1068 | - if (lba48) { | |
1069 | - ide_outb(device, ATA_DEV_HD, | |
1070 | - ATA_LBA | ATA_DEVICE(device)); | |
1071 | - ide_outb(device, ATA_COMMAND, ATA_CMD_READ_EXT); | |
1072 | - | |
1073 | - } else | |
1074 | -#endif | |
1075 | - { | |
1076 | - ide_outb(device, ATA_DEV_HD, ATA_LBA | | |
1077 | - ATA_DEVICE(device) | ((blknr >> 24) & 0xF)); | |
1078 | - ide_outb(device, ATA_COMMAND, ATA_CMD_READ); | |
1079 | - } | |
1080 | - | |
1081 | - udelay(50); | |
1082 | - | |
1083 | - if (pwrsave) { | |
1084 | - /* may take up to 4 sec */ | |
1085 | - c = ide_wait(device, IDE_SPIN_UP_TIME_OUT); | |
1086 | - pwrsave = 0; | |
1087 | - } else { | |
1088 | - /* can't take over 500 ms */ | |
1089 | - c = ide_wait(device, IDE_TIME_OUT); | |
1090 | - } | |
1091 | - | |
1092 | - if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != | |
1093 | - ATA_STAT_DRQ) { | |
1094 | - printf("Error (no IRQ) dev %d blk " LBAF | |
1095 | - ": status %#02x\n", device, blknr, c); | |
1096 | - break; | |
1097 | - } | |
1098 | - | |
1099 | - ide_input_data(device, buffer, ATA_SECTORWORDS); | |
1100 | - (void) ide_inb(device, ATA_STATUS); /* clear IRQ */ | |
1101 | - | |
1102 | - ++n; | |
1103 | - ++blknr; | |
1104 | - buffer += ATA_BLOCKSIZE; | |
1105 | - } | |
1106 | -IDE_READ_E: | |
1107 | - ide_led(DEVICE_LED(device), 0); /* LED off */ | |
1108 | - return n; | |
1109 | -} | |
1110 | - | |
1111 | -#ifdef CONFIG_BLK | |
1112 | -ulong ide_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, | |
1113 | - const void *buffer) | |
1114 | -#else | |
1115 | -ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, | |
1116 | - const void *buffer) | |
1117 | -#endif | |
1118 | -{ | |
1119 | -#ifdef CONFIG_BLK | |
1120 | - struct blk_desc *block_dev = dev_get_uclass_platdata(dev); | |
1121 | -#endif | |
1122 | - int device = block_dev->devnum; | |
1123 | - ulong n = 0; | |
1124 | - unsigned char c; | |
1125 | - | |
1126 | -#ifdef CONFIG_LBA48 | |
1127 | - unsigned char lba48 = 0; | |
1128 | - | |
1129 | - if (blknr & 0x0000fffff0000000ULL) { | |
1130 | - /* more than 28 bits used, use 48bit mode */ | |
1131 | - lba48 = 1; | |
1132 | - } | |
1133 | -#endif | |
1134 | - | |
1135 | - ide_led(DEVICE_LED(device), 1); /* LED on */ | |
1136 | - | |
1137 | - /* Select device | |
1138 | - */ | |
1139 | - ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
1140 | - | |
1141 | - while (blkcnt-- > 0) { | |
1142 | - c = ide_wait(device, IDE_TIME_OUT); | |
1143 | - | |
1144 | - if (c & ATA_STAT_BUSY) { | |
1145 | - printf("IDE read: device %d not ready\n", device); | |
1146 | - goto WR_OUT; | |
1147 | - } | |
1148 | -#ifdef CONFIG_LBA48 | |
1149 | - if (lba48) { | |
1150 | - /* write high bits */ | |
1151 | - ide_outb(device, ATA_SECT_CNT, 0); | |
1152 | - ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); | |
1153 | -#ifdef CONFIG_SYS_64BIT_LBA | |
1154 | - ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF); | |
1155 | - ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); | |
1156 | -#else | |
1157 | - ide_outb(device, ATA_LBA_MID, 0); | |
1158 | - ide_outb(device, ATA_LBA_HIGH, 0); | |
1159 | -#endif | |
1160 | - } | |
1161 | -#endif | |
1162 | - ide_outb(device, ATA_SECT_CNT, 1); | |
1163 | - ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF); | |
1164 | - ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF); | |
1165 | - ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); | |
1166 | - | |
1167 | -#ifdef CONFIG_LBA48 | |
1168 | - if (lba48) { | |
1169 | - ide_outb(device, ATA_DEV_HD, | |
1170 | - ATA_LBA | ATA_DEVICE(device)); | |
1171 | - ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE_EXT); | |
1172 | - | |
1173 | - } else | |
1174 | -#endif | |
1175 | - { | |
1176 | - ide_outb(device, ATA_DEV_HD, ATA_LBA | | |
1177 | - ATA_DEVICE(device) | ((blknr >> 24) & 0xF)); | |
1178 | - ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE); | |
1179 | - } | |
1180 | - | |
1181 | - udelay(50); | |
1182 | - | |
1183 | - /* can't take over 500 ms */ | |
1184 | - c = ide_wait(device, IDE_TIME_OUT); | |
1185 | - | |
1186 | - if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != | |
1187 | - ATA_STAT_DRQ) { | |
1188 | - printf("Error (no IRQ) dev %d blk " LBAF | |
1189 | - ": status %#02x\n", device, blknr, c); | |
1190 | - goto WR_OUT; | |
1191 | - } | |
1192 | - | |
1193 | - ide_output_data(device, buffer, ATA_SECTORWORDS); | |
1194 | - c = ide_inb(device, ATA_STATUS); /* clear IRQ */ | |
1195 | - ++n; | |
1196 | - ++blknr; | |
1197 | - buffer += ATA_BLOCKSIZE; | |
1198 | - } | |
1199 | -WR_OUT: | |
1200 | - ide_led(DEVICE_LED(device), 0); /* LED off */ | |
1201 | - return n; | |
1202 | -} | |
1203 | - | |
1204 | -#if defined(CONFIG_OF_IDE_FIXUP) | |
1205 | -int ide_device_present(int dev) | |
1206 | -{ | |
1207 | - if (dev >= CONFIG_SYS_IDE_MAXBUS) | |
1208 | - return 0; | |
1209 | - return ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN ? 0 : 1; | |
1210 | -} | |
1211 | -#endif | |
1212 | - | |
1213 | -#ifdef CONFIG_BLK | |
1214 | -static const struct blk_ops ide_blk_ops = { | |
1215 | - .read = ide_read, | |
1216 | - .write = ide_write, | |
1217 | -}; | |
1218 | - | |
1219 | -U_BOOT_DRIVER(ide_blk) = { | |
1220 | - .name = "ide_blk", | |
1221 | - .id = UCLASS_BLK, | |
1222 | - .ops = &ide_blk_ops, | |
1223 | -}; | |
1224 | -#else | |
1225 | -U_BOOT_LEGACY_BLK(ide) = { | |
1226 | - .if_typename = "ide", | |
1227 | - .if_type = IF_TYPE_IDE, | |
1228 | - .max_devs = CONFIG_SYS_IDE_MAXDEVICE, | |
1229 | - .desc = ide_dev_desc, | |
1230 | -}; | |
1231 | -#endif |
drivers/block/Kconfig
... | ... | @@ -59,4 +59,12 @@ |
59 | 59 | Synopsys DWC AHCI module. |
60 | 60 | |
61 | 61 | endmenu |
62 | + | |
63 | +config IDE | |
64 | + bool "Support IDE controllers" | |
65 | + help | |
66 | + Enables support for IDE (Integrated Drive Electronics) hard drives. | |
67 | + This allows access to raw blocks and filesystems on an IDE drive | |
68 | + from U-Boot. See also CMD_IDE which provides an 'ide' command for | |
69 | + performing various IDE operations. |
drivers/block/Makefile
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | obj-$(CONFIG_SCSI_AHCI) += ahci.o |
18 | 18 | obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o |
19 | 19 | obj-$(CONFIG_FSL_SATA) += fsl_sata.o |
20 | +obj-$(CONFIG_IDE) += ide.o | |
20 | 21 | obj-$(CONFIG_IDE_FTIDE020) += ftide020.o |
21 | 22 | obj-$(CONFIG_LIBATA) += libata.o |
22 | 23 | obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o |
drivers/block/ide.c
Changes suppressed. Click to show
1 | +/* | |
2 | + * (C) Copyright 2000-2011 | |
3 | + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | + | |
8 | +#include <common.h> | |
9 | +#include <ata.h> | |
10 | +#include <dm.h> | |
11 | +#include <ide.h> | |
12 | +#include <watchdog.h> | |
13 | +#include <asm/io.h> | |
14 | + | |
15 | +#ifdef __PPC__ | |
16 | +# define EIEIO __asm__ volatile ("eieio") | |
17 | +# define SYNC __asm__ volatile ("sync") | |
18 | +#else | |
19 | +# define EIEIO /* nothing */ | |
20 | +# define SYNC /* nothing */ | |
21 | +#endif | |
22 | + | |
23 | +/* Current offset for IDE0 / IDE1 bus access */ | |
24 | +ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = { | |
25 | +#if defined(CONFIG_SYS_ATA_IDE0_OFFSET) | |
26 | + CONFIG_SYS_ATA_IDE0_OFFSET, | |
27 | +#endif | |
28 | +#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) && (CONFIG_SYS_IDE_MAXBUS > 1) | |
29 | + CONFIG_SYS_ATA_IDE1_OFFSET, | |
30 | +#endif | |
31 | +}; | |
32 | + | |
33 | +static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS]; | |
34 | + | |
35 | +struct blk_desc ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE]; | |
36 | + | |
37 | +#define IDE_TIME_OUT 2000 /* 2 sec timeout */ | |
38 | + | |
39 | +#define ATAPI_TIME_OUT 7000 /* 7 sec timeout (5 sec seems to work...) */ | |
40 | + | |
41 | +#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */ | |
42 | + | |
43 | +#ifndef CONFIG_SYS_ATA_PORT_ADDR | |
44 | +#define CONFIG_SYS_ATA_PORT_ADDR(port) (port) | |
45 | +#endif | |
46 | + | |
47 | +#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */ | |
48 | +# define DEVICE_LED(x) 0 | |
49 | +# define LED_IDE1 1 | |
50 | +# define LED_IDE2 2 | |
51 | +#endif | |
52 | + | |
53 | +#ifdef CONFIG_IDE_RESET | |
54 | +extern void ide_set_reset(int idereset); | |
55 | + | |
56 | +static void ide_reset(void) | |
57 | +{ | |
58 | + int i; | |
59 | + | |
60 | + for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; ++i) | |
61 | + ide_bus_ok[i] = 0; | |
62 | + for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) | |
63 | + ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; | |
64 | + | |
65 | + ide_set_reset(1); /* assert reset */ | |
66 | + | |
67 | + /* the reset signal shall be asserted for et least 25 us */ | |
68 | + udelay(25); | |
69 | + | |
70 | + WATCHDOG_RESET(); | |
71 | + | |
72 | + /* de-assert RESET signal */ | |
73 | + ide_set_reset(0); | |
74 | + | |
75 | + /* wait 250 ms */ | |
76 | + for (i = 0; i < 250; ++i) | |
77 | + udelay(1000); | |
78 | +} | |
79 | +#else | |
80 | +#define ide_reset() /* dummy */ | |
81 | +#endif /* CONFIG_IDE_RESET */ | |
82 | + | |
83 | +/* | |
84 | + * Wait until Busy bit is off, or timeout (in ms) | |
85 | + * Return last status | |
86 | + */ | |
87 | +static uchar ide_wait(int dev, ulong t) | |
88 | +{ | |
89 | + ulong delay = 10 * t; /* poll every 100 us */ | |
90 | + uchar c; | |
91 | + | |
92 | + while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) { | |
93 | + udelay(100); | |
94 | + if (delay-- == 0) | |
95 | + break; | |
96 | + } | |
97 | + return c; | |
98 | +} | |
99 | + | |
100 | +/* | |
101 | + * copy src to dest, skipping leading and trailing blanks and null | |
102 | + * terminate the string | |
103 | + * "len" is the size of available memory including the terminating '\0' | |
104 | + */ | |
105 | +static void ident_cpy(unsigned char *dst, unsigned char *src, | |
106 | + unsigned int len) | |
107 | +{ | |
108 | + unsigned char *end, *last; | |
109 | + | |
110 | + last = dst; | |
111 | + end = src + len - 1; | |
112 | + | |
113 | + /* reserve space for '\0' */ | |
114 | + if (len < 2) | |
115 | + goto OUT; | |
116 | + | |
117 | + /* skip leading white space */ | |
118 | + while ((*src) && (src < end) && (*src == ' ')) | |
119 | + ++src; | |
120 | + | |
121 | + /* copy string, omitting trailing white space */ | |
122 | + while ((*src) && (src < end)) { | |
123 | + *dst++ = *src; | |
124 | + if (*src++ != ' ') | |
125 | + last = dst; | |
126 | + } | |
127 | +OUT: | |
128 | + *last = '\0'; | |
129 | +} | |
130 | + | |
131 | +#ifdef CONFIG_ATAPI | |
132 | +/**************************************************************************** | |
133 | + * ATAPI Support | |
134 | + */ | |
135 | + | |
136 | +#if defined(CONFIG_IDE_SWAP_IO) | |
137 | +/* since ATAPI may use commands with not 4 bytes alligned length | |
138 | + * we have our own transfer functions, 2 bytes alligned */ | |
139 | +__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) | |
140 | +{ | |
141 | + ushort *dbuf; | |
142 | + volatile ushort *pbuf; | |
143 | + | |
144 | + pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
145 | + dbuf = (ushort *)sect_buf; | |
146 | + | |
147 | + debug("in output data shorts base for read is %lx\n", | |
148 | + (unsigned long) pbuf); | |
149 | + | |
150 | + while (shorts--) { | |
151 | + EIEIO; | |
152 | + *pbuf = *dbuf++; | |
153 | + } | |
154 | +} | |
155 | + | |
156 | +__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) | |
157 | +{ | |
158 | + ushort *dbuf; | |
159 | + volatile ushort *pbuf; | |
160 | + | |
161 | + pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
162 | + dbuf = (ushort *)sect_buf; | |
163 | + | |
164 | + debug("in input data shorts base for read is %lx\n", | |
165 | + (unsigned long) pbuf); | |
166 | + | |
167 | + while (shorts--) { | |
168 | + EIEIO; | |
169 | + *dbuf++ = *pbuf; | |
170 | + } | |
171 | +} | |
172 | + | |
173 | +#else /* ! CONFIG_IDE_SWAP_IO */ | |
174 | +__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) | |
175 | +{ | |
176 | + outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); | |
177 | +} | |
178 | + | |
179 | +__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) | |
180 | +{ | |
181 | + insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); | |
182 | +} | |
183 | + | |
184 | +#endif /* CONFIG_IDE_SWAP_IO */ | |
185 | + | |
186 | +/* | |
187 | + * Wait until (Status & mask) == res, or timeout (in ms) | |
188 | + * Return last status | |
189 | + * This is used since some ATAPI CD ROMs clears their Busy Bit first | |
190 | + * and then they set their DRQ Bit | |
191 | + */ | |
192 | +static uchar atapi_wait_mask(int dev, ulong t, uchar mask, uchar res) | |
193 | +{ | |
194 | + ulong delay = 10 * t; /* poll every 100 us */ | |
195 | + uchar c; | |
196 | + | |
197 | + /* prevents to read the status before valid */ | |
198 | + c = ide_inb(dev, ATA_DEV_CTL); | |
199 | + | |
200 | + while (((c = ide_inb(dev, ATA_STATUS)) & mask) != res) { | |
201 | + /* break if error occurs (doesn't make sense to wait more) */ | |
202 | + if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) | |
203 | + break; | |
204 | + udelay(100); | |
205 | + if (delay-- == 0) | |
206 | + break; | |
207 | + } | |
208 | + return c; | |
209 | +} | |
210 | + | |
211 | +/* | |
212 | + * issue an atapi command | |
213 | + */ | |
214 | +unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen, | |
215 | + unsigned char *buffer, int buflen) | |
216 | +{ | |
217 | + unsigned char c, err, mask, res; | |
218 | + int n; | |
219 | + | |
220 | + ide_led(DEVICE_LED(device), 1); /* LED on */ | |
221 | + | |
222 | + /* Select device | |
223 | + */ | |
224 | + mask = ATA_STAT_BUSY | ATA_STAT_DRQ; | |
225 | + res = 0; | |
226 | + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
227 | + c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); | |
228 | + if ((c & mask) != res) { | |
229 | + printf("ATAPI_ISSUE: device %d not ready status %X\n", device, | |
230 | + c); | |
231 | + err = 0xFF; | |
232 | + goto AI_OUT; | |
233 | + } | |
234 | + /* write taskfile */ | |
235 | + ide_outb(device, ATA_ERROR_REG, 0); /* no DMA, no overlaped */ | |
236 | + ide_outb(device, ATA_SECT_CNT, 0); | |
237 | + ide_outb(device, ATA_SECT_NUM, 0); | |
238 | + ide_outb(device, ATA_CYL_LOW, (unsigned char) (buflen & 0xFF)); | |
239 | + ide_outb(device, ATA_CYL_HIGH, | |
240 | + (unsigned char) ((buflen >> 8) & 0xFF)); | |
241 | + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
242 | + | |
243 | + ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET); | |
244 | + udelay(50); | |
245 | + | |
246 | + mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR; | |
247 | + res = ATA_STAT_DRQ; | |
248 | + c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); | |
249 | + | |
250 | + if ((c & mask) != res) { /* DRQ must be 1, BSY 0 */ | |
251 | + printf("ATAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n", | |
252 | + device, c); | |
253 | + err = 0xFF; | |
254 | + goto AI_OUT; | |
255 | + } | |
256 | + | |
257 | + /* write command block */ | |
258 | + ide_output_data_shorts(device, (unsigned short *)ccb, ccblen / 2); | |
259 | + | |
260 | + /* ATAPI Command written wait for completition */ | |
261 | + udelay(5000); /* device must set bsy */ | |
262 | + | |
263 | + mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR; | |
264 | + /* | |
265 | + * if no data wait for DRQ = 0 BSY = 0 | |
266 | + * if data wait for DRQ = 1 BSY = 0 | |
267 | + */ | |
268 | + res = 0; | |
269 | + if (buflen) | |
270 | + res = ATA_STAT_DRQ; | |
271 | + c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); | |
272 | + if ((c & mask) != res) { | |
273 | + if (c & ATA_STAT_ERR) { | |
274 | + err = (ide_inb(device, ATA_ERROR_REG)) >> 4; | |
275 | + debug("atapi_issue 1 returned sense key %X status %02X\n", | |
276 | + err, c); | |
277 | + } else { | |
278 | + printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x) status 0x%02x\n", | |
279 | + ccb[0], c); | |
280 | + err = 0xFF; | |
281 | + } | |
282 | + goto AI_OUT; | |
283 | + } | |
284 | + n = ide_inb(device, ATA_CYL_HIGH); | |
285 | + n <<= 8; | |
286 | + n += ide_inb(device, ATA_CYL_LOW); | |
287 | + if (n > buflen) { | |
288 | + printf("ERROR, transfer bytes %d requested only %d\n", n, | |
289 | + buflen); | |
290 | + err = 0xff; | |
291 | + goto AI_OUT; | |
292 | + } | |
293 | + if ((n == 0) && (buflen < 0)) { | |
294 | + printf("ERROR, transfer bytes %d requested %d\n", n, buflen); | |
295 | + err = 0xff; | |
296 | + goto AI_OUT; | |
297 | + } | |
298 | + if (n != buflen) { | |
299 | + debug("WARNING, transfer bytes %d not equal with requested %d\n", | |
300 | + n, buflen); | |
301 | + } | |
302 | + if (n != 0) { /* data transfer */ | |
303 | + debug("ATAPI_ISSUE: %d Bytes to transfer\n", n); | |
304 | + /* we transfer shorts */ | |
305 | + n >>= 1; | |
306 | + /* ok now decide if it is an in or output */ | |
307 | + if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) { | |
308 | + debug("Write to device\n"); | |
309 | + ide_output_data_shorts(device, (unsigned short *)buffer, | |
310 | + n); | |
311 | + } else { | |
312 | + debug("Read from device @ %p shorts %d\n", buffer, n); | |
313 | + ide_input_data_shorts(device, (unsigned short *)buffer, | |
314 | + n); | |
315 | + } | |
316 | + } | |
317 | + udelay(5000); /* seems that some CD ROMs need this... */ | |
318 | + mask = ATA_STAT_BUSY | ATA_STAT_ERR; | |
319 | + res = 0; | |
320 | + c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); | |
321 | + if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) { | |
322 | + err = (ide_inb(device, ATA_ERROR_REG) >> 4); | |
323 | + debug("atapi_issue 2 returned sense key %X status %X\n", err, | |
324 | + c); | |
325 | + } else { | |
326 | + err = 0; | |
327 | + } | |
328 | +AI_OUT: | |
329 | + ide_led(DEVICE_LED(device), 0); /* LED off */ | |
330 | + return err; | |
331 | +} | |
332 | + | |
333 | +/* | |
334 | + * sending the command to atapi_issue. If an status other than good | |
335 | + * returns, an request_sense will be issued | |
336 | + */ | |
337 | + | |
338 | +#define ATAPI_DRIVE_NOT_READY 100 | |
339 | +#define ATAPI_UNIT_ATTN 10 | |
340 | + | |
341 | +unsigned char atapi_issue_autoreq(int device, | |
342 | + unsigned char *ccb, | |
343 | + int ccblen, | |
344 | + unsigned char *buffer, int buflen) | |
345 | +{ | |
346 | + unsigned char sense_data[18], sense_ccb[12]; | |
347 | + unsigned char res, key, asc, ascq; | |
348 | + int notready, unitattn; | |
349 | + | |
350 | + unitattn = ATAPI_UNIT_ATTN; | |
351 | + notready = ATAPI_DRIVE_NOT_READY; | |
352 | + | |
353 | +retry: | |
354 | + res = atapi_issue(device, ccb, ccblen, buffer, buflen); | |
355 | + if (res == 0) | |
356 | + return 0; /* Ok */ | |
357 | + | |
358 | + if (res == 0xFF) | |
359 | + return 0xFF; /* error */ | |
360 | + | |
361 | + debug("(auto_req)atapi_issue returned sense key %X\n", res); | |
362 | + | |
363 | + memset(sense_ccb, 0, sizeof(sense_ccb)); | |
364 | + memset(sense_data, 0, sizeof(sense_data)); | |
365 | + sense_ccb[0] = ATAPI_CMD_REQ_SENSE; | |
366 | + sense_ccb[4] = 18; /* allocation Length */ | |
367 | + | |
368 | + res = atapi_issue(device, sense_ccb, 12, sense_data, 18); | |
369 | + key = (sense_data[2] & 0xF); | |
370 | + asc = (sense_data[12]); | |
371 | + ascq = (sense_data[13]); | |
372 | + | |
373 | + debug("ATAPI_CMD_REQ_SENSE returned %x\n", res); | |
374 | + debug(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n", | |
375 | + sense_data[0], key, asc, ascq); | |
376 | + | |
377 | + if ((key == 0)) | |
378 | + return 0; /* ok device ready */ | |
379 | + | |
380 | + if ((key == 6) || (asc == 0x29) || (asc == 0x28)) { /* Unit Attention */ | |
381 | + if (unitattn-- > 0) { | |
382 | + udelay(200 * 1000); | |
383 | + goto retry; | |
384 | + } | |
385 | + printf("Unit Attention, tried %d\n", ATAPI_UNIT_ATTN); | |
386 | + goto error; | |
387 | + } | |
388 | + if ((asc == 0x4) && (ascq == 0x1)) { | |
389 | + /* not ready, but will be ready soon */ | |
390 | + if (notready-- > 0) { | |
391 | + udelay(200 * 1000); | |
392 | + goto retry; | |
393 | + } | |
394 | + printf("Drive not ready, tried %d times\n", | |
395 | + ATAPI_DRIVE_NOT_READY); | |
396 | + goto error; | |
397 | + } | |
398 | + if (asc == 0x3a) { | |
399 | + debug("Media not present\n"); | |
400 | + goto error; | |
401 | + } | |
402 | + | |
403 | + printf("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n", key, asc, | |
404 | + ascq); | |
405 | +error: | |
406 | + debug("ERROR Sense key %02X ASC %02X ASCQ %02X\n", key, asc, ascq); | |
407 | + return 0xFF; | |
408 | +} | |
409 | + | |
410 | +/* | |
411 | + * atapi_read: | |
412 | + * we transfer only one block per command, since the multiple DRQ per | |
413 | + * command is not yet implemented | |
414 | + */ | |
415 | +#define ATAPI_READ_MAX_BYTES 2048 /* we read max 2kbytes */ | |
416 | +#define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */ | |
417 | +#define ATAPI_READ_MAX_BLOCK (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE) | |
418 | + | |
419 | +ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, | |
420 | + void *buffer) | |
421 | +{ | |
422 | + int device = block_dev->devnum; | |
423 | + ulong n = 0; | |
424 | + unsigned char ccb[12]; /* Command descriptor block */ | |
425 | + ulong cnt; | |
426 | + | |
427 | + debug("atapi_read dev %d start " LBAF " blocks " LBAF | |
428 | + " buffer at %lX\n", device, blknr, blkcnt, (ulong) buffer); | |
429 | + | |
430 | + do { | |
431 | + if (blkcnt > ATAPI_READ_MAX_BLOCK) | |
432 | + cnt = ATAPI_READ_MAX_BLOCK; | |
433 | + else | |
434 | + cnt = blkcnt; | |
435 | + | |
436 | + ccb[0] = ATAPI_CMD_READ_12; | |
437 | + ccb[1] = 0; /* reserved */ | |
438 | + ccb[2] = (unsigned char) (blknr >> 24) & 0xFF; /* MSB Block */ | |
439 | + ccb[3] = (unsigned char) (blknr >> 16) & 0xFF; /* */ | |
440 | + ccb[4] = (unsigned char) (blknr >> 8) & 0xFF; | |
441 | + ccb[5] = (unsigned char) blknr & 0xFF; /* LSB Block */ | |
442 | + ccb[6] = (unsigned char) (cnt >> 24) & 0xFF; /* MSB Block cnt */ | |
443 | + ccb[7] = (unsigned char) (cnt >> 16) & 0xFF; | |
444 | + ccb[8] = (unsigned char) (cnt >> 8) & 0xFF; | |
445 | + ccb[9] = (unsigned char) cnt & 0xFF; /* LSB Block */ | |
446 | + ccb[10] = 0; /* reserved */ | |
447 | + ccb[11] = 0; /* reserved */ | |
448 | + | |
449 | + if (atapi_issue_autoreq(device, ccb, 12, | |
450 | + (unsigned char *)buffer, | |
451 | + cnt * ATAPI_READ_BLOCK_SIZE) | |
452 | + == 0xFF) { | |
453 | + return n; | |
454 | + } | |
455 | + n += cnt; | |
456 | + blkcnt -= cnt; | |
457 | + blknr += cnt; | |
458 | + buffer += (cnt * ATAPI_READ_BLOCK_SIZE); | |
459 | + } while (blkcnt > 0); | |
460 | + return n; | |
461 | +} | |
462 | + | |
463 | +static void atapi_inquiry(struct blk_desc *dev_desc) | |
464 | +{ | |
465 | + unsigned char ccb[12]; /* Command descriptor block */ | |
466 | + unsigned char iobuf[64]; /* temp buf */ | |
467 | + unsigned char c; | |
468 | + int device; | |
469 | + | |
470 | + device = dev_desc->devnum; | |
471 | + dev_desc->type = DEV_TYPE_UNKNOWN; /* not yet valid */ | |
472 | + dev_desc->block_read = atapi_read; | |
473 | + | |
474 | + memset(ccb, 0, sizeof(ccb)); | |
475 | + memset(iobuf, 0, sizeof(iobuf)); | |
476 | + | |
477 | + ccb[0] = ATAPI_CMD_INQUIRY; | |
478 | + ccb[4] = 40; /* allocation Legnth */ | |
479 | + c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 40); | |
480 | + | |
481 | + debug("ATAPI_CMD_INQUIRY returned %x\n", c); | |
482 | + if (c != 0) | |
483 | + return; | |
484 | + | |
485 | + /* copy device ident strings */ | |
486 | + ident_cpy((unsigned char *)dev_desc->vendor, &iobuf[8], 8); | |
487 | + ident_cpy((unsigned char *)dev_desc->product, &iobuf[16], 16); | |
488 | + ident_cpy((unsigned char *)dev_desc->revision, &iobuf[32], 5); | |
489 | + | |
490 | + dev_desc->lun = 0; | |
491 | + dev_desc->lba = 0; | |
492 | + dev_desc->blksz = 0; | |
493 | + dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz)); | |
494 | + dev_desc->type = iobuf[0] & 0x1f; | |
495 | + | |
496 | + if ((iobuf[1] & 0x80) == 0x80) | |
497 | + dev_desc->removable = 1; | |
498 | + else | |
499 | + dev_desc->removable = 0; | |
500 | + | |
501 | + memset(ccb, 0, sizeof(ccb)); | |
502 | + memset(iobuf, 0, sizeof(iobuf)); | |
503 | + ccb[0] = ATAPI_CMD_START_STOP; | |
504 | + ccb[4] = 0x03; /* start */ | |
505 | + | |
506 | + c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0); | |
507 | + | |
508 | + debug("ATAPI_CMD_START_STOP returned %x\n", c); | |
509 | + if (c != 0) | |
510 | + return; | |
511 | + | |
512 | + memset(ccb, 0, sizeof(ccb)); | |
513 | + memset(iobuf, 0, sizeof(iobuf)); | |
514 | + c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0); | |
515 | + | |
516 | + debug("ATAPI_CMD_UNIT_TEST_READY returned %x\n", c); | |
517 | + if (c != 0) | |
518 | + return; | |
519 | + | |
520 | + memset(ccb, 0, sizeof(ccb)); | |
521 | + memset(iobuf, 0, sizeof(iobuf)); | |
522 | + ccb[0] = ATAPI_CMD_READ_CAP; | |
523 | + c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 8); | |
524 | + debug("ATAPI_CMD_READ_CAP returned %x\n", c); | |
525 | + if (c != 0) | |
526 | + return; | |
527 | + | |
528 | + debug("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n", | |
529 | + iobuf[0], iobuf[1], iobuf[2], iobuf[3], | |
530 | + iobuf[4], iobuf[5], iobuf[6], iobuf[7]); | |
531 | + | |
532 | + dev_desc->lba = ((unsigned long) iobuf[0] << 24) + | |
533 | + ((unsigned long) iobuf[1] << 16) + | |
534 | + ((unsigned long) iobuf[2] << 8) + ((unsigned long) iobuf[3]); | |
535 | + dev_desc->blksz = ((unsigned long) iobuf[4] << 24) + | |
536 | + ((unsigned long) iobuf[5] << 16) + | |
537 | + ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]); | |
538 | + dev_desc->log2blksz = LOG2(dev_desc->blksz); | |
539 | +#ifdef CONFIG_LBA48 | |
540 | + /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */ | |
541 | + dev_desc->lba48 = 0; | |
542 | +#endif | |
543 | + return; | |
544 | +} | |
545 | + | |
546 | +#endif /* CONFIG_ATAPI */ | |
547 | + | |
548 | +static void ide_ident(struct blk_desc *dev_desc) | |
549 | +{ | |
550 | + unsigned char c; | |
551 | + hd_driveid_t iop; | |
552 | + | |
553 | +#ifdef CONFIG_ATAPI | |
554 | + int retries = 0; | |
555 | +#endif | |
556 | + int device; | |
557 | + | |
558 | + device = dev_desc->devnum; | |
559 | + printf(" Device %d: ", device); | |
560 | + | |
561 | + ide_led(DEVICE_LED(device), 1); /* LED on */ | |
562 | + /* Select device | |
563 | + */ | |
564 | + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
565 | + dev_desc->if_type = IF_TYPE_IDE; | |
566 | +#ifdef CONFIG_ATAPI | |
567 | + | |
568 | + retries = 0; | |
569 | + | |
570 | + /* Warning: This will be tricky to read */ | |
571 | + while (retries <= 1) { | |
572 | + /* check signature */ | |
573 | + if ((ide_inb(device, ATA_SECT_CNT) == 0x01) && | |
574 | + (ide_inb(device, ATA_SECT_NUM) == 0x01) && | |
575 | + (ide_inb(device, ATA_CYL_LOW) == 0x14) && | |
576 | + (ide_inb(device, ATA_CYL_HIGH) == 0xEB)) { | |
577 | + /* ATAPI Signature found */ | |
578 | + dev_desc->if_type = IF_TYPE_ATAPI; | |
579 | + /* | |
580 | + * Start Ident Command | |
581 | + */ | |
582 | + ide_outb(device, ATA_COMMAND, ATAPI_CMD_IDENT); | |
583 | + /* | |
584 | + * Wait for completion - ATAPI devices need more time | |
585 | + * to become ready | |
586 | + */ | |
587 | + c = ide_wait(device, ATAPI_TIME_OUT); | |
588 | + } else | |
589 | +#endif | |
590 | + { | |
591 | + /* | |
592 | + * Start Ident Command | |
593 | + */ | |
594 | + ide_outb(device, ATA_COMMAND, ATA_CMD_IDENT); | |
595 | + | |
596 | + /* | |
597 | + * Wait for completion | |
598 | + */ | |
599 | + c = ide_wait(device, IDE_TIME_OUT); | |
600 | + } | |
601 | + ide_led(DEVICE_LED(device), 0); /* LED off */ | |
602 | + | |
603 | + if (((c & ATA_STAT_DRQ) == 0) || | |
604 | + ((c & (ATA_STAT_FAULT | ATA_STAT_ERR)) != 0)) { | |
605 | +#ifdef CONFIG_ATAPI | |
606 | + { | |
607 | + /* | |
608 | + * Need to soft reset the device | |
609 | + * in case it's an ATAPI... | |
610 | + */ | |
611 | + debug("Retrying...\n"); | |
612 | + ide_outb(device, ATA_DEV_HD, | |
613 | + ATA_LBA | ATA_DEVICE(device)); | |
614 | + udelay(100000); | |
615 | + ide_outb(device, ATA_COMMAND, 0x08); | |
616 | + udelay(500000); /* 500 ms */ | |
617 | + } | |
618 | + /* | |
619 | + * Select device | |
620 | + */ | |
621 | + ide_outb(device, ATA_DEV_HD, | |
622 | + ATA_LBA | ATA_DEVICE(device)); | |
623 | + retries++; | |
624 | +#else | |
625 | + return; | |
626 | +#endif | |
627 | + } | |
628 | +#ifdef CONFIG_ATAPI | |
629 | + else | |
630 | + break; | |
631 | + } /* see above - ugly to read */ | |
632 | + | |
633 | + if (retries == 2) /* Not found */ | |
634 | + return; | |
635 | +#endif | |
636 | + | |
637 | + ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS); | |
638 | + | |
639 | + ident_cpy((unsigned char *)dev_desc->revision, iop.fw_rev, | |
640 | + sizeof(dev_desc->revision)); | |
641 | + ident_cpy((unsigned char *)dev_desc->vendor, iop.model, | |
642 | + sizeof(dev_desc->vendor)); | |
643 | + ident_cpy((unsigned char *)dev_desc->product, iop.serial_no, | |
644 | + sizeof(dev_desc->product)); | |
645 | +#ifdef __LITTLE_ENDIAN | |
646 | + /* | |
647 | + * firmware revision, model, and serial number have Big Endian Byte | |
648 | + * order in Word. Convert all three to little endian. | |
649 | + * | |
650 | + * See CF+ and CompactFlash Specification Revision 2.0: | |
651 | + * 6.2.1.6: Identify Drive, Table 39 for more details | |
652 | + */ | |
653 | + | |
654 | + strswab(dev_desc->revision); | |
655 | + strswab(dev_desc->vendor); | |
656 | + strswab(dev_desc->product); | |
657 | +#endif /* __LITTLE_ENDIAN */ | |
658 | + | |
659 | + if ((iop.config & 0x0080) == 0x0080) | |
660 | + dev_desc->removable = 1; | |
661 | + else | |
662 | + dev_desc->removable = 0; | |
663 | + | |
664 | +#ifdef CONFIG_ATAPI | |
665 | + if (dev_desc->if_type == IF_TYPE_ATAPI) { | |
666 | + atapi_inquiry(dev_desc); | |
667 | + return; | |
668 | + } | |
669 | +#endif /* CONFIG_ATAPI */ | |
670 | + | |
671 | +#ifdef __BIG_ENDIAN | |
672 | + /* swap shorts */ | |
673 | + dev_desc->lba = (iop.lba_capacity << 16) | (iop.lba_capacity >> 16); | |
674 | +#else /* ! __BIG_ENDIAN */ | |
675 | + /* | |
676 | + * do not swap shorts on little endian | |
677 | + * | |
678 | + * See CF+ and CompactFlash Specification Revision 2.0: | |
679 | + * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details. | |
680 | + */ | |
681 | + dev_desc->lba = iop.lba_capacity; | |
682 | +#endif /* __BIG_ENDIAN */ | |
683 | + | |
684 | +#ifdef CONFIG_LBA48 | |
685 | + if (iop.command_set_2 & 0x0400) { /* LBA 48 support */ | |
686 | + dev_desc->lba48 = 1; | |
687 | + dev_desc->lba = (unsigned long long) iop.lba48_capacity[0] | | |
688 | + ((unsigned long long) iop.lba48_capacity[1] << 16) | | |
689 | + ((unsigned long long) iop.lba48_capacity[2] << 32) | | |
690 | + ((unsigned long long) iop.lba48_capacity[3] << 48); | |
691 | + } else { | |
692 | + dev_desc->lba48 = 0; | |
693 | + } | |
694 | +#endif /* CONFIG_LBA48 */ | |
695 | + /* assuming HD */ | |
696 | + dev_desc->type = DEV_TYPE_HARDDISK; | |
697 | + dev_desc->blksz = ATA_BLOCKSIZE; | |
698 | + dev_desc->log2blksz = LOG2(dev_desc->blksz); | |
699 | + dev_desc->lun = 0; /* just to fill something in... */ | |
700 | + | |
701 | +#if 0 /* only used to test the powersaving mode, | |
702 | + * if enabled, the drive goes after 5 sec | |
703 | + * in standby mode */ | |
704 | + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
705 | + c = ide_wait(device, IDE_TIME_OUT); | |
706 | + ide_outb(device, ATA_SECT_CNT, 1); | |
707 | + ide_outb(device, ATA_LBA_LOW, 0); | |
708 | + ide_outb(device, ATA_LBA_MID, 0); | |
709 | + ide_outb(device, ATA_LBA_HIGH, 0); | |
710 | + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
711 | + ide_outb(device, ATA_COMMAND, 0xe3); | |
712 | + udelay(50); | |
713 | + c = ide_wait(device, IDE_TIME_OUT); /* can't take over 500 ms */ | |
714 | +#endif | |
715 | +} | |
716 | + | |
717 | +__weak void ide_led(uchar led, uchar status) | |
718 | +{ | |
719 | +#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */ | |
720 | + static uchar led_buffer; /* Buffer for current LED status */ | |
721 | + | |
722 | + uchar *led_port = LED_PORT; | |
723 | + | |
724 | + if (status) /* switch LED on */ | |
725 | + led_buffer |= led; | |
726 | + else /* switch LED off */ | |
727 | + led_buffer &= ~led; | |
728 | + | |
729 | + *led_port = led_buffer; | |
730 | +#endif | |
731 | +} | |
732 | + | |
733 | +__weak void ide_outb(int dev, int port, unsigned char val) | |
734 | +{ | |
735 | + debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n", | |
736 | + dev, port, val, | |
737 | + (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port))); | |
738 | + | |
739 | +#if defined(CONFIG_IDE_AHB) | |
740 | + if (port) { | |
741 | + /* write command */ | |
742 | + ide_write_register(dev, port, val); | |
743 | + } else { | |
744 | + /* write data */ | |
745 | + outb(val, (ATA_CURR_BASE(dev))); | |
746 | + } | |
747 | +#else | |
748 | + outb(val, (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port))); | |
749 | +#endif | |
750 | +} | |
751 | + | |
752 | +__weak unsigned char ide_inb(int dev, int port) | |
753 | +{ | |
754 | + uchar val; | |
755 | + | |
756 | +#if defined(CONFIG_IDE_AHB) | |
757 | + val = ide_read_register(dev, port); | |
758 | +#else | |
759 | + val = inb((ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port))); | |
760 | +#endif | |
761 | + | |
762 | + debug("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n", | |
763 | + dev, port, | |
764 | + (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)), val); | |
765 | + return val; | |
766 | +} | |
767 | + | |
768 | +void ide_init(void) | |
769 | +{ | |
770 | + unsigned char c; | |
771 | + int i, bus; | |
772 | + | |
773 | +#ifdef CONFIG_IDE_8xx_PCCARD | |
774 | + extern int ide_devices_found; /* Initialized in check_ide_device() */ | |
775 | +#endif /* CONFIG_IDE_8xx_PCCARD */ | |
776 | + | |
777 | +#ifdef CONFIG_IDE_PREINIT | |
778 | + WATCHDOG_RESET(); | |
779 | + | |
780 | + if (ide_preinit()) { | |
781 | + puts("ide_preinit failed\n"); | |
782 | + return; | |
783 | + } | |
784 | +#endif /* CONFIG_IDE_PREINIT */ | |
785 | + | |
786 | + WATCHDOG_RESET(); | |
787 | + | |
788 | + /* | |
789 | + * Reset the IDE just to be sure. | |
790 | + * Light LED's to show | |
791 | + */ | |
792 | + ide_led((LED_IDE1 | LED_IDE2), 1); /* LED's on */ | |
793 | + | |
794 | + /* ATAPI Drives seems to need a proper IDE Reset */ | |
795 | + ide_reset(); | |
796 | + | |
797 | +#ifdef CONFIG_IDE_INIT_POSTRESET | |
798 | + WATCHDOG_RESET(); | |
799 | + | |
800 | + if (ide_init_postreset()) { | |
801 | + puts("ide_preinit_postreset failed\n"); | |
802 | + return; | |
803 | + } | |
804 | +#endif /* CONFIG_IDE_INIT_POSTRESET */ | |
805 | + | |
806 | + /* | |
807 | + * Wait for IDE to get ready. | |
808 | + * According to spec, this can take up to 31 seconds! | |
809 | + */ | |
810 | + for (bus = 0; bus < CONFIG_SYS_IDE_MAXBUS; ++bus) { | |
811 | + int dev = | |
812 | + bus * (CONFIG_SYS_IDE_MAXDEVICE / | |
813 | + CONFIG_SYS_IDE_MAXBUS); | |
814 | + | |
815 | +#ifdef CONFIG_IDE_8xx_PCCARD | |
816 | + /* Skip non-ide devices from probing */ | |
817 | + if ((ide_devices_found & (1 << bus)) == 0) { | |
818 | + ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */ | |
819 | + continue; | |
820 | + } | |
821 | +#endif | |
822 | + printf("Bus %d: ", bus); | |
823 | + | |
824 | + ide_bus_ok[bus] = 0; | |
825 | + | |
826 | + /* Select device | |
827 | + */ | |
828 | + udelay(100000); /* 100 ms */ | |
829 | + ide_outb(dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev)); | |
830 | + udelay(100000); /* 100 ms */ | |
831 | + i = 0; | |
832 | + do { | |
833 | + udelay(10000); /* 10 ms */ | |
834 | + | |
835 | + c = ide_inb(dev, ATA_STATUS); | |
836 | + i++; | |
837 | + if (i > (ATA_RESET_TIME * 100)) { | |
838 | + puts("** Timeout **\n"); | |
839 | + /* LED's off */ | |
840 | + ide_led((LED_IDE1 | LED_IDE2), 0); | |
841 | + return; | |
842 | + } | |
843 | + if ((i >= 100) && ((i % 100) == 0)) | |
844 | + putc('.'); | |
845 | + | |
846 | + } while (c & ATA_STAT_BUSY); | |
847 | + | |
848 | + if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) { | |
849 | + puts("not available "); | |
850 | + debug("Status = 0x%02X ", c); | |
851 | +#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */ | |
852 | + } else if ((c & ATA_STAT_READY) == 0) { | |
853 | + puts("not available "); | |
854 | + debug("Status = 0x%02X ", c); | |
855 | +#endif | |
856 | + } else { | |
857 | + puts("OK "); | |
858 | + ide_bus_ok[bus] = 1; | |
859 | + } | |
860 | + WATCHDOG_RESET(); | |
861 | + } | |
862 | + | |
863 | + putc('\n'); | |
864 | + | |
865 | + ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */ | |
866 | + | |
867 | + for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) { | |
868 | + int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2; | |
869 | + ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; | |
870 | + ide_dev_desc[i].if_type = IF_TYPE_IDE; | |
871 | + ide_dev_desc[i].devnum = i; | |
872 | + ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN; | |
873 | + ide_dev_desc[i].blksz = 0; | |
874 | + ide_dev_desc[i].log2blksz = | |
875 | + LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz)); | |
876 | + ide_dev_desc[i].lba = 0; | |
877 | +#ifndef CONFIG_BLK | |
878 | + ide_dev_desc[i].block_read = ide_read; | |
879 | + ide_dev_desc[i].block_write = ide_write; | |
880 | +#endif | |
881 | + if (!ide_bus_ok[IDE_BUS(i)]) | |
882 | + continue; | |
883 | + ide_led(led, 1); /* LED on */ | |
884 | + ide_ident(&ide_dev_desc[i]); | |
885 | + ide_led(led, 0); /* LED off */ | |
886 | + dev_print(&ide_dev_desc[i]); | |
887 | + | |
888 | + if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) { | |
889 | + /* initialize partition type */ | |
890 | + part_init(&ide_dev_desc[i]); | |
891 | + } | |
892 | + } | |
893 | + WATCHDOG_RESET(); | |
894 | +} | |
895 | + | |
896 | +/* We only need to swap data if we are running on a big endian cpu. */ | |
897 | +#if defined(__LITTLE_ENDIAN) | |
898 | +__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) | |
899 | +{ | |
900 | + ide_input_data(dev, sect_buf, words); | |
901 | +} | |
902 | +#else | |
903 | +__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) | |
904 | +{ | |
905 | + volatile ushort *pbuf = | |
906 | + (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
907 | + ushort *dbuf = (ushort *)sect_buf; | |
908 | + | |
909 | + debug("in input swap data base for read is %lx\n", | |
910 | + (unsigned long) pbuf); | |
911 | + | |
912 | + while (words--) { | |
913 | +#ifdef __MIPS__ | |
914 | + *dbuf++ = swab16p((u16 *)pbuf); | |
915 | + *dbuf++ = swab16p((u16 *)pbuf); | |
916 | +#else | |
917 | + *dbuf++ = ld_le16(pbuf); | |
918 | + *dbuf++ = ld_le16(pbuf); | |
919 | +#endif /* !MIPS */ | |
920 | + } | |
921 | +} | |
922 | +#endif /* __LITTLE_ENDIAN */ | |
923 | + | |
924 | + | |
925 | +#if defined(CONFIG_IDE_SWAP_IO) | |
926 | +__weak void ide_output_data(int dev, const ulong *sect_buf, int words) | |
927 | +{ | |
928 | + ushort *dbuf; | |
929 | + volatile ushort *pbuf; | |
930 | + | |
931 | + pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
932 | + dbuf = (ushort *)sect_buf; | |
933 | + while (words--) { | |
934 | + EIEIO; | |
935 | + *pbuf = *dbuf++; | |
936 | + EIEIO; | |
937 | + *pbuf = *dbuf++; | |
938 | + } | |
939 | +} | |
940 | +#else /* ! CONFIG_IDE_SWAP_IO */ | |
941 | +__weak void ide_output_data(int dev, const ulong *sect_buf, int words) | |
942 | +{ | |
943 | +#if defined(CONFIG_IDE_AHB) | |
944 | + ide_write_data(dev, sect_buf, words); | |
945 | +#else | |
946 | + outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1); | |
947 | +#endif | |
948 | +} | |
949 | +#endif /* CONFIG_IDE_SWAP_IO */ | |
950 | + | |
951 | +#if defined(CONFIG_IDE_SWAP_IO) | |
952 | +__weak void ide_input_data(int dev, ulong *sect_buf, int words) | |
953 | +{ | |
954 | + ushort *dbuf; | |
955 | + volatile ushort *pbuf; | |
956 | + | |
957 | + pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); | |
958 | + dbuf = (ushort *)sect_buf; | |
959 | + | |
960 | + debug("in input data base for read is %lx\n", (unsigned long) pbuf); | |
961 | + | |
962 | + while (words--) { | |
963 | + EIEIO; | |
964 | + *dbuf++ = *pbuf; | |
965 | + EIEIO; | |
966 | + *dbuf++ = *pbuf; | |
967 | + } | |
968 | +} | |
969 | +#else /* ! CONFIG_IDE_SWAP_IO */ | |
970 | +__weak void ide_input_data(int dev, ulong *sect_buf, int words) | |
971 | +{ | |
972 | +#if defined(CONFIG_IDE_AHB) | |
973 | + ide_read_data(dev, sect_buf, words); | |
974 | +#else | |
975 | + insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1); | |
976 | +#endif | |
977 | +} | |
978 | + | |
979 | +#endif /* CONFIG_IDE_SWAP_IO */ | |
980 | + | |
981 | +#ifdef CONFIG_BLK | |
982 | +ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, | |
983 | + void *buffer) | |
984 | +#else | |
985 | +ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, | |
986 | + void *buffer) | |
987 | +#endif | |
988 | +{ | |
989 | +#ifdef CONFIG_BLK | |
990 | + struct blk_desc *block_dev = dev_get_uclass_platdata(dev); | |
991 | +#endif | |
992 | + int device = block_dev->devnum; | |
993 | + ulong n = 0; | |
994 | + unsigned char c; | |
995 | + unsigned char pwrsave = 0; /* power save */ | |
996 | + | |
997 | +#ifdef CONFIG_LBA48 | |
998 | + unsigned char lba48 = 0; | |
999 | + | |
1000 | + if (blknr & 0x0000fffff0000000ULL) { | |
1001 | + /* more than 28 bits used, use 48bit mode */ | |
1002 | + lba48 = 1; | |
1003 | + } | |
1004 | +#endif | |
1005 | + debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n", | |
1006 | + device, blknr, blkcnt, (ulong) buffer); | |
1007 | + | |
1008 | + ide_led(DEVICE_LED(device), 1); /* LED on */ | |
1009 | + | |
1010 | + /* Select device | |
1011 | + */ | |
1012 | + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
1013 | + c = ide_wait(device, IDE_TIME_OUT); | |
1014 | + | |
1015 | + if (c & ATA_STAT_BUSY) { | |
1016 | + printf("IDE read: device %d not ready\n", device); | |
1017 | + goto IDE_READ_E; | |
1018 | + } | |
1019 | + | |
1020 | + /* first check if the drive is in Powersaving mode, if yes, | |
1021 | + * increase the timeout value */ | |
1022 | + ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_PWR); | |
1023 | + udelay(50); | |
1024 | + | |
1025 | + c = ide_wait(device, IDE_TIME_OUT); /* can't take over 500 ms */ | |
1026 | + | |
1027 | + if (c & ATA_STAT_BUSY) { | |
1028 | + printf("IDE read: device %d not ready\n", device); | |
1029 | + goto IDE_READ_E; | |
1030 | + } | |
1031 | + if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) { | |
1032 | + printf("No Powersaving mode %X\n", c); | |
1033 | + } else { | |
1034 | + c = ide_inb(device, ATA_SECT_CNT); | |
1035 | + debug("Powersaving %02X\n", c); | |
1036 | + if (c == 0) | |
1037 | + pwrsave = 1; | |
1038 | + } | |
1039 | + | |
1040 | + | |
1041 | + while (blkcnt-- > 0) { | |
1042 | + c = ide_wait(device, IDE_TIME_OUT); | |
1043 | + | |
1044 | + if (c & ATA_STAT_BUSY) { | |
1045 | + printf("IDE read: device %d not ready\n", device); | |
1046 | + break; | |
1047 | + } | |
1048 | +#ifdef CONFIG_LBA48 | |
1049 | + if (lba48) { | |
1050 | + /* write high bits */ | |
1051 | + ide_outb(device, ATA_SECT_CNT, 0); | |
1052 | + ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); | |
1053 | +#ifdef CONFIG_SYS_64BIT_LBA | |
1054 | + ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF); | |
1055 | + ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); | |
1056 | +#else | |
1057 | + ide_outb(device, ATA_LBA_MID, 0); | |
1058 | + ide_outb(device, ATA_LBA_HIGH, 0); | |
1059 | +#endif | |
1060 | + } | |
1061 | +#endif | |
1062 | + ide_outb(device, ATA_SECT_CNT, 1); | |
1063 | + ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF); | |
1064 | + ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF); | |
1065 | + ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); | |
1066 | + | |
1067 | +#ifdef CONFIG_LBA48 | |
1068 | + if (lba48) { | |
1069 | + ide_outb(device, ATA_DEV_HD, | |
1070 | + ATA_LBA | ATA_DEVICE(device)); | |
1071 | + ide_outb(device, ATA_COMMAND, ATA_CMD_READ_EXT); | |
1072 | + | |
1073 | + } else | |
1074 | +#endif | |
1075 | + { | |
1076 | + ide_outb(device, ATA_DEV_HD, ATA_LBA | | |
1077 | + ATA_DEVICE(device) | ((blknr >> 24) & 0xF)); | |
1078 | + ide_outb(device, ATA_COMMAND, ATA_CMD_READ); | |
1079 | + } | |
1080 | + | |
1081 | + udelay(50); | |
1082 | + | |
1083 | + if (pwrsave) { | |
1084 | + /* may take up to 4 sec */ | |
1085 | + c = ide_wait(device, IDE_SPIN_UP_TIME_OUT); | |
1086 | + pwrsave = 0; | |
1087 | + } else { | |
1088 | + /* can't take over 500 ms */ | |
1089 | + c = ide_wait(device, IDE_TIME_OUT); | |
1090 | + } | |
1091 | + | |
1092 | + if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != | |
1093 | + ATA_STAT_DRQ) { | |
1094 | + printf("Error (no IRQ) dev %d blk " LBAF | |
1095 | + ": status %#02x\n", device, blknr, c); | |
1096 | + break; | |
1097 | + } | |
1098 | + | |
1099 | + ide_input_data(device, buffer, ATA_SECTORWORDS); | |
1100 | + (void) ide_inb(device, ATA_STATUS); /* clear IRQ */ | |
1101 | + | |
1102 | + ++n; | |
1103 | + ++blknr; | |
1104 | + buffer += ATA_BLOCKSIZE; | |
1105 | + } | |
1106 | +IDE_READ_E: | |
1107 | + ide_led(DEVICE_LED(device), 0); /* LED off */ | |
1108 | + return n; | |
1109 | +} | |
1110 | + | |
1111 | +#ifdef CONFIG_BLK | |
1112 | +ulong ide_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, | |
1113 | + const void *buffer) | |
1114 | +#else | |
1115 | +ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, | |
1116 | + const void *buffer) | |
1117 | +#endif | |
1118 | +{ | |
1119 | +#ifdef CONFIG_BLK | |
1120 | + struct blk_desc *block_dev = dev_get_uclass_platdata(dev); | |
1121 | +#endif | |
1122 | + int device = block_dev->devnum; | |
1123 | + ulong n = 0; | |
1124 | + unsigned char c; | |
1125 | + | |
1126 | +#ifdef CONFIG_LBA48 | |
1127 | + unsigned char lba48 = 0; | |
1128 | + | |
1129 | + if (blknr & 0x0000fffff0000000ULL) { | |
1130 | + /* more than 28 bits used, use 48bit mode */ | |
1131 | + lba48 = 1; | |
1132 | + } | |
1133 | +#endif | |
1134 | + | |
1135 | + ide_led(DEVICE_LED(device), 1); /* LED on */ | |
1136 | + | |
1137 | + /* Select device | |
1138 | + */ | |
1139 | + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); | |
1140 | + | |
1141 | + while (blkcnt-- > 0) { | |
1142 | + c = ide_wait(device, IDE_TIME_OUT); | |
1143 | + | |
1144 | + if (c & ATA_STAT_BUSY) { | |
1145 | + printf("IDE read: device %d not ready\n", device); | |
1146 | + goto WR_OUT; | |
1147 | + } | |
1148 | +#ifdef CONFIG_LBA48 | |
1149 | + if (lba48) { | |
1150 | + /* write high bits */ | |
1151 | + ide_outb(device, ATA_SECT_CNT, 0); | |
1152 | + ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); | |
1153 | +#ifdef CONFIG_SYS_64BIT_LBA | |
1154 | + ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF); | |
1155 | + ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); | |
1156 | +#else | |
1157 | + ide_outb(device, ATA_LBA_MID, 0); | |
1158 | + ide_outb(device, ATA_LBA_HIGH, 0); | |
1159 | +#endif | |
1160 | + } | |
1161 | +#endif | |
1162 | + ide_outb(device, ATA_SECT_CNT, 1); | |
1163 | + ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF); | |
1164 | + ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF); | |
1165 | + ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); | |
1166 | + | |
1167 | +#ifdef CONFIG_LBA48 | |
1168 | + if (lba48) { | |
1169 | + ide_outb(device, ATA_DEV_HD, | |
1170 | + ATA_LBA | ATA_DEVICE(device)); | |
1171 | + ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE_EXT); | |
1172 | + | |
1173 | + } else | |
1174 | +#endif | |
1175 | + { | |
1176 | + ide_outb(device, ATA_DEV_HD, ATA_LBA | | |
1177 | + ATA_DEVICE(device) | ((blknr >> 24) & 0xF)); | |
1178 | + ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE); | |
1179 | + } | |
1180 | + | |
1181 | + udelay(50); | |
1182 | + | |
1183 | + /* can't take over 500 ms */ | |
1184 | + c = ide_wait(device, IDE_TIME_OUT); | |
1185 | + | |
1186 | + if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != | |
1187 | + ATA_STAT_DRQ) { | |
1188 | + printf("Error (no IRQ) dev %d blk " LBAF | |
1189 | + ": status %#02x\n", device, blknr, c); | |
1190 | + goto WR_OUT; | |
1191 | + } | |
1192 | + | |
1193 | + ide_output_data(device, buffer, ATA_SECTORWORDS); | |
1194 | + c = ide_inb(device, ATA_STATUS); /* clear IRQ */ | |
1195 | + ++n; | |
1196 | + ++blknr; | |
1197 | + buffer += ATA_BLOCKSIZE; | |
1198 | + } | |
1199 | +WR_OUT: | |
1200 | + ide_led(DEVICE_LED(device), 0); /* LED off */ | |
1201 | + return n; | |
1202 | +} | |
1203 | + | |
1204 | +#if defined(CONFIG_OF_IDE_FIXUP) | |
1205 | +int ide_device_present(int dev) | |
1206 | +{ | |
1207 | + if (dev >= CONFIG_SYS_IDE_MAXBUS) | |
1208 | + return 0; | |
1209 | + return ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN ? 0 : 1; | |
1210 | +} | |
1211 | +#endif | |
1212 | + | |
1213 | +#ifdef CONFIG_BLK | |
1214 | +static const struct blk_ops ide_blk_ops = { | |
1215 | + .read = ide_read, | |
1216 | + .write = ide_write, | |
1217 | +}; | |
1218 | + | |
1219 | +U_BOOT_DRIVER(ide_blk) = { | |
1220 | + .name = "ide_blk", | |
1221 | + .id = UCLASS_BLK, | |
1222 | + .ops = &ide_blk_ops, | |
1223 | +}; | |
1224 | +#else | |
1225 | +U_BOOT_LEGACY_BLK(ide) = { | |
1226 | + .if_typename = "ide", | |
1227 | + .if_type = IF_TYPE_IDE, | |
1228 | + .max_devs = CONFIG_SYS_IDE_MAXDEVICE, | |
1229 | + .desc = ide_dev_desc, | |
1230 | +}; | |
1231 | +#endif |
drivers/block/sil680.c
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | * incorrect for the target board (e.g. the sequoia board requires 0). |
18 | 18 | * #define CONFIG_SYS_PCI_CACHE_LINE_SIZE 0 |
19 | 19 | * |
20 | - * #define CONFIG_CMD_IDE | |
20 | + * #define CONFIG_IDE | |
21 | 21 | * #undef CONFIG_IDE_8xx_DIRECT |
22 | 22 | * #undef CONFIG_IDE_LED |
23 | 23 | * #undef CONFIG_IDE_RESET |
drivers/pcmcia/marubun_pcmcia.c
drivers/pcmcia/mpc8xx_pcmcia.c
drivers/pcmcia/tqm8xx_pcmcia.c
fs/fat/fat.c
include/config_distro_bootcmd.h
... | ... | @@ -186,16 +186,16 @@ |
186 | 186 | BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_SCSI |
187 | 187 | #endif |
188 | 188 | |
189 | -#ifdef CONFIG_CMD_IDE | |
189 | +#ifdef CONFIG_IDE | |
190 | 190 | #define BOOTENV_SHARED_IDE BOOTENV_SHARED_BLKDEV(ide) |
191 | 191 | #define BOOTENV_DEV_IDE BOOTENV_DEV_BLKDEV |
192 | 192 | #define BOOTENV_DEV_NAME_IDE BOOTENV_DEV_NAME_BLKDEV |
193 | 193 | #else |
194 | 194 | #define BOOTENV_SHARED_IDE |
195 | 195 | #define BOOTENV_DEV_IDE \ |
196 | - BOOT_TARGET_DEVICES_references_IDE_without_CONFIG_CMD_IDE | |
196 | + BOOT_TARGET_DEVICES_references_IDE_without_CONFIG_IDE | |
197 | 197 | #define BOOTENV_DEV_NAME_IDE \ |
198 | - BOOT_TARGET_DEVICES_references_IDE_without_CONFIG_CMD_IDE | |
198 | + BOOT_TARGET_DEVICES_references_IDE_without_CONFIG_IDE | |
199 | 199 | #endif |
200 | 200 | |
201 | 201 | #if defined(CONFIG_CMD_PCI_ENUM) || defined(CONFIG_DM_PCI) |
include/config_fallbacks.h
include/configs/M5253DEMO.h
include/configs/edminiv2.h
include/configs/ib62x0.h
... | ... | @@ -87,14 +87,14 @@ |
87 | 87 | /* |
88 | 88 | * SATA driver configuration |
89 | 89 | */ |
90 | -#ifdef CONFIG_CMD_IDE | |
90 | +#ifdef CONFIG_IDE | |
91 | 91 | #define __io |
92 | 92 | #define CONFIG_IDE_PREINIT |
93 | 93 | #define CONFIG_MVSATA_IDE_USE_PORT0 |
94 | 94 | #define CONFIG_MVSATA_IDE_USE_PORT1 |
95 | 95 | #define CONFIG_SYS_ATA_IDE0_OFFSET MV_SATA_PORT0_OFFSET |
96 | 96 | #define CONFIG_SYS_ATA_IDE1_OFFSET MV_SATA_PORT1_OFFSET |
97 | -#endif /* CONFIG_CMD_IDE */ | |
97 | +#endif /* CONFIG_IDE */ | |
98 | 98 | |
99 | 99 | /* |
100 | 100 | * RTC driver configuration |
include/configs/lsxl.h
include/configs/mpc5121ads.h
... | ... | @@ -411,10 +411,10 @@ |
411 | 411 | "1m(u-boot);" \ |
412 | 412 | "mpc5121.nand:-(data)" |
413 | 413 | |
414 | -#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_EXT2) || defined(CONFIG_CMD_USB) | |
414 | +#if defined(CONFIG_IDE) || defined(CONFIG_CMD_EXT2) || defined(CONFIG_CMD_USB) | |
415 | 415 | #define CONFIG_SUPPORT_VFAT |
416 | 416 | |
417 | -#endif /* defined(CONFIG_CMD_IDE) */ | |
417 | +#endif /* defined(CONFIG_IDE) */ | |
418 | 418 | |
419 | 419 | /* |
420 | 420 | * Watchdog timeout = CONFIG_SYS_WATCHDOG_VALUE * 65536 / IPS clock. |
include/configs/nsa310s.h
... | ... | @@ -79,12 +79,12 @@ |
79 | 79 | #endif /* CONFIG_CMD_NET */ |
80 | 80 | |
81 | 81 | /* SATA driver configuration */ |
82 | -#ifdef CONFIG_CMD_IDE | |
82 | +#ifdef CONFIG_IDE | |
83 | 83 | #define __io |
84 | 84 | #define CONFIG_IDE_PREINIT |
85 | 85 | #define CONFIG_MVSATA_IDE_USE_PORT0 |
86 | 86 | #define CONFIG_SYS_ATA_IDE0_OFFSET MV_SATA_PORT0_OFFSET |
87 | -#endif /* CONFIG_CMD_IDE */ | |
87 | +#endif /* CONFIG_IDE */ | |
88 | 88 | |
89 | 89 | /* RTC driver configuration */ |
90 | 90 | #ifdef CONFIG_CMD_DATE |
include/configs/qemu-x86.h
... | ... | @@ -25,9 +25,9 @@ |
25 | 25 | * - AHCI controller is supported for QEMU '-M q35' target |
26 | 26 | * |
27 | 27 | * Default configuraion is to support the QEMU default x86 target |
28 | - * Undefine CONFIG_CMD_IDE to support q35 target | |
28 | + * Undefine CONFIG_IDE to support q35 target | |
29 | 29 | */ |
30 | -#ifdef CONFIG_CMD_IDE | |
30 | +#ifdef CONFIG_IDE | |
31 | 31 | #define CONFIG_SYS_IDE_MAXBUS 2 |
32 | 32 | #define CONFIG_SYS_IDE_MAXDEVICE 4 |
33 | 33 | #define CONFIG_SYS_ATA_BASE_ADDR 0 |
include/configs/r7780mp.h
... | ... | @@ -119,7 +119,7 @@ |
119 | 119 | #endif |
120 | 120 | |
121 | 121 | /* Compact flash Support */ |
122 | -#if defined(CONFIG_CMD_IDE) | |
122 | +#if defined(CONFIG_IDE) | |
123 | 123 | #define CONFIG_IDE_RESET 1 |
124 | 124 | #define CONFIG_SYS_PIO_MODE 1 |
125 | 125 | #define CONFIG_SYS_IDE_MAXBUS 1 /* IDE bus */ |
... | ... | @@ -130,7 +130,7 @@ |
130 | 130 | #define CONFIG_SYS_ATA_REG_OFFSET 0x1000 /* reg offset */ |
131 | 131 | #define CONFIG_SYS_ATA_ALT_OFFSET 0x800 /* alternate register offset */ |
132 | 132 | #define CONFIG_IDE_SWAP_IO |
133 | -#endif /* CONFIG_CMD_IDE */ | |
133 | +#endif /* CONFIG_IDE */ | |
134 | 134 | |
135 | 135 | #endif /* __R7780RP_H */ |
include/configs/sheevaplug.h
... | ... | @@ -90,14 +90,14 @@ |
90 | 90 | /* |
91 | 91 | * SATA driver configuration |
92 | 92 | */ |
93 | -#ifdef CONFIG_CMD_IDE | |
93 | +#ifdef CONFIG_IDE | |
94 | 94 | #define __io |
95 | 95 | #define CONFIG_IDE_PREINIT |
96 | 96 | #define CONFIG_MVSATA_IDE_USE_PORT0 |
97 | 97 | #define CONFIG_MVSATA_IDE_USE_PORT1 |
98 | 98 | #define CONFIG_SYS_ATA_IDE0_OFFSET MV_SATA_PORT0_OFFSET |
99 | 99 | #define CONFIG_SYS_ATA_IDE1_OFFSET MV_SATA_PORT1_OFFSET |
100 | -#endif /* CONFIG_CMD_IDE */ | |
100 | +#endif /* CONFIG_IDE */ | |
101 | 101 | |
102 | 102 | #endif /* _CONFIG_SHEEVAPLUG_H */ |
include/pcmcia.h
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | * or try to generate a useful default |
17 | 17 | */ |
18 | 18 | #if defined(CONFIG_CMD_PCMCIA) || \ |
19 | - (defined(CONFIG_CMD_IDE) && \ | |
19 | + (defined(CONFIG_IDE) && \ | |
20 | 20 | (defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) ) ) |
21 | 21 | |
22 | 22 | #if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) |
... | ... | @@ -268,7 +268,7 @@ |
268 | 268 | #define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot]) |
269 | 269 | #endif |
270 | 270 | |
271 | -#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) | |
271 | +#if defined(CONFIG_IDE) && defined(CONFIG_IDE_8xx_PCCARD) | |
272 | 272 | extern int check_ide_device(int slot); |
273 | 273 | #endif |
274 | 274 |