]>
Commit | Line | Data |
---|---|---|
c609719b | 1 | /* |
34c202c7 | 2 | * (C) Copyright 2000-2011 |
c609719b WD |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
c609719b WD |
6 | */ |
7 | ||
8 | /* | |
9 | * IDE support | |
10 | */ | |
113bfe48 | 11 | |
c609719b | 12 | #include <common.h> |
2a981dc2 | 13 | #include <blk.h> |
c609719b WD |
14 | #include <config.h> |
15 | #include <watchdog.h> | |
16 | #include <command.h> | |
17 | #include <image.h> | |
18 | #include <asm/byteorder.h> | |
f98984cb | 19 | #include <asm/io.h> |
735dd97b | 20 | |
5b8e76c3 | 21 | #if defined(CONFIG_IDE_PCMCIA) |
c609719b WD |
22 | # include <pcmcia.h> |
23 | #endif | |
735dd97b | 24 | |
c609719b WD |
25 | #include <ide.h> |
26 | #include <ata.h> | |
735dd97b | 27 | |
2d8d190c | 28 | #ifdef CONFIG_LED_STATUS |
c609719b WD |
29 | # include <status_led.h> |
30 | #endif | |
735dd97b | 31 | |
c609719b WD |
32 | /* Current I/O Device */ |
33 | static int curr_device = -1; | |
34 | ||
ed73508d SG |
35 | int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) |
36 | { | |
37 | int rcode = 0; | |
38 | ||
39 | switch (argc) { | |
40 | case 0: | |
41 | case 1: | |
42 | return CMD_RET_USAGE; | |
43 | case 2: | |
44 | if (strncmp(argv[1], "res", 3) == 0) { | |
5b8e76c3 | 45 | puts("\nReset IDE: "); |
ed73508d SG |
46 | ide_init(); |
47 | return 0; | |
48 | } else if (strncmp(argv[1], "inf", 3) == 0) { | |
e9be1ee7 | 49 | blk_list_devices(IF_TYPE_IDE); |
ed73508d SG |
50 | return 0; |
51 | ||
52 | } else if (strncmp(argv[1], "dev", 3) == 0) { | |
e9be1ee7 SG |
53 | if (blk_print_device_num(IF_TYPE_IDE, curr_device)) { |
54 | printf("\nno IDE devices available\n"); | |
55 | return CMD_RET_FAILURE; | |
ed73508d | 56 | } |
e9be1ee7 | 57 | |
ed73508d SG |
58 | return 0; |
59 | } else if (strncmp(argv[1], "part", 4) == 0) { | |
e9be1ee7 SG |
60 | if (blk_list_part(IF_TYPE_IDE)) |
61 | printf("\nno IDE devices available\n"); | |
62 | return 1; | |
ed73508d SG |
63 | } |
64 | return CMD_RET_USAGE; | |
65 | case 3: | |
66 | if (strncmp(argv[1], "dev", 3) == 0) { | |
67 | int dev = (int)simple_strtoul(argv[2], NULL, 10); | |
c609719b | 68 | |
e9be1ee7 SG |
69 | if (!blk_show_device(IF_TYPE_IDE, dev)) { |
70 | curr_device = dev; | |
71 | printf("... is now current device\n"); | |
72 | } else { | |
73 | return CMD_RET_FAILURE; | |
ed73508d | 74 | } |
ed73508d SG |
75 | return 0; |
76 | } else if (strncmp(argv[1], "part", 4) == 0) { | |
77 | int dev = (int)simple_strtoul(argv[2], NULL, 10); | |
c609719b | 78 | |
e9be1ee7 SG |
79 | if (blk_print_part_devnum(IF_TYPE_IDE, dev)) { |
80 | printf("\nIDE device %d not available\n", dev); | |
81 | return CMD_RET_FAILURE; | |
ed73508d | 82 | } |
e9be1ee7 | 83 | return 1; |
ed73508d | 84 | } |
c609719b | 85 | |
ed73508d SG |
86 | return CMD_RET_USAGE; |
87 | default: | |
88 | /* at least 4 args */ | |
c609719b | 89 | |
ed73508d SG |
90 | if (strcmp(argv[1], "read") == 0) { |
91 | ulong addr = simple_strtoul(argv[2], NULL, 16); | |
92 | ulong cnt = simple_strtoul(argv[4], NULL, 16); | |
ed73508d | 93 | ulong n; |
c609719b | 94 | |
ed73508d SG |
95 | #ifdef CONFIG_SYS_64BIT_LBA |
96 | lbaint_t blk = simple_strtoull(argv[3], NULL, 16); | |
c609719b | 97 | |
ed73508d SG |
98 | printf("\nIDE read: device %d block # %lld, count %ld...", |
99 | curr_device, blk, cnt); | |
100 | #else | |
101 | lbaint_t blk = simple_strtoul(argv[3], NULL, 16); | |
c609719b | 102 | |
ed73508d SG |
103 | printf("\nIDE read: device %d block # %ld, count %ld...", |
104 | curr_device, blk, cnt); | |
105 | #endif | |
c609719b | 106 | |
e9be1ee7 SG |
107 | n = blk_read_devnum(IF_TYPE_IDE, curr_device, blk, cnt, |
108 | (ulong *)addr); | |
c609719b | 109 | |
ed73508d SG |
110 | printf("%ld blocks read: %s\n", |
111 | n, (n == cnt) ? "OK" : "ERROR"); | |
112 | if (n == cnt) | |
113 | return 0; | |
114 | else | |
115 | return 1; | |
116 | } else if (strcmp(argv[1], "write") == 0) { | |
117 | ulong addr = simple_strtoul(argv[2], NULL, 16); | |
118 | ulong cnt = simple_strtoul(argv[4], NULL, 16); | |
119 | ulong n; | |
c609719b | 120 | |
6d0f6bcf | 121 | #ifdef CONFIG_SYS_64BIT_LBA |
ed73508d SG |
122 | lbaint_t blk = simple_strtoull(argv[3], NULL, 16); |
123 | ||
124 | printf("\nIDE write: device %d block # %lld, count %ld...", | |
125 | curr_device, blk, cnt); | |
413bf586 | 126 | #else |
ed73508d SG |
127 | lbaint_t blk = simple_strtoul(argv[3], NULL, 16); |
128 | ||
129 | printf("\nIDE write: device %d block # %ld, count %ld...", | |
130 | curr_device, blk, cnt); | |
413bf586 | 131 | #endif |
e9be1ee7 SG |
132 | n = blk_write_devnum(IF_TYPE_IDE, curr_device, blk, cnt, |
133 | (ulong *)addr); | |
ed73508d SG |
134 | |
135 | printf("%ld blocks written: %s\n", n, | |
136 | n == cnt ? "OK" : "ERROR"); | |
137 | if (n == cnt) | |
138 | return 0; | |
139 | else | |
140 | return 1; | |
141 | } else { | |
142 | return CMD_RET_USAGE; | |
c40b2956 | 143 | } |
c40b2956 | 144 | |
ed73508d SG |
145 | return rcode; |
146 | } | |
147 | } | |
c40b2956 | 148 | |
ed73508d SG |
149 | int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) |
150 | { | |
151 | return common_diskboot(cmdtp, "ide", argc, argv); | |
152 | } | |
c609719b | 153 | |
34c202c7 WD |
154 | U_BOOT_CMD(ide, 5, 1, do_ide, |
155 | "IDE sub-system", | |
156 | "reset - reset IDE controller\n" | |
157 | "ide info - show available IDE devices\n" | |
158 | "ide device [dev] - show or set current device\n" | |
159 | "ide part [dev] - print partition table of one or all IDE devices\n" | |
160 | "ide read addr blk# cnt\n" | |
161 | "ide write addr blk# cnt - read/write `cnt'" | |
162 | " blocks starting at block `blk#'\n" | |
163 | " to/from memory address `addr'"); | |
164 | ||
165 | U_BOOT_CMD(diskboot, 3, 1, do_diskboot, | |
166 | "boot from IDE device", "loadAddr dev:part"); |