]>
Commit | Line | Data |
---|---|---|
c609719b | 1 | /* |
34c202c7 | 2 | * (C) Copyright 2000-2011 |
c609719b WD |
3 | * Wolfgang Denk, DENX Software Engineering, [email protected]. |
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 | |
c609719b WD |
21 | #if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA) |
22 | # include <pcmcia.h> | |
23 | #endif | |
735dd97b | 24 | |
c609719b WD |
25 | #include <ide.h> |
26 | #include <ata.h> | |
735dd97b | 27 | |
c609719b WD |
28 | #ifdef CONFIG_STATUS_LED |
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) { | |
45 | puts("\nReset IDE" | |
46 | #ifdef CONFIG_IDE_8xx_DIRECT | |
47 | " on PCMCIA " PCMCIA_SLOT_MSG | |
48 | #endif | |
49 | ": "); | |
50 | ||
51 | ide_init(); | |
52 | return 0; | |
53 | } else if (strncmp(argv[1], "inf", 3) == 0) { | |
e9be1ee7 | 54 | blk_list_devices(IF_TYPE_IDE); |
ed73508d SG |
55 | return 0; |
56 | ||
57 | } else if (strncmp(argv[1], "dev", 3) == 0) { | |
e9be1ee7 SG |
58 | if (blk_print_device_num(IF_TYPE_IDE, curr_device)) { |
59 | printf("\nno IDE devices available\n"); | |
60 | return CMD_RET_FAILURE; | |
ed73508d | 61 | } |
e9be1ee7 | 62 | |
ed73508d SG |
63 | return 0; |
64 | } else if (strncmp(argv[1], "part", 4) == 0) { | |
e9be1ee7 SG |
65 | if (blk_list_part(IF_TYPE_IDE)) |
66 | printf("\nno IDE devices available\n"); | |
67 | return 1; | |
ed73508d SG |
68 | } |
69 | return CMD_RET_USAGE; | |
70 | case 3: | |
71 | if (strncmp(argv[1], "dev", 3) == 0) { | |
72 | int dev = (int)simple_strtoul(argv[2], NULL, 10); | |
c609719b | 73 | |
e9be1ee7 SG |
74 | if (!blk_show_device(IF_TYPE_IDE, dev)) { |
75 | curr_device = dev; | |
76 | printf("... is now current device\n"); | |
77 | } else { | |
78 | return CMD_RET_FAILURE; | |
ed73508d | 79 | } |
ed73508d SG |
80 | return 0; |
81 | } else if (strncmp(argv[1], "part", 4) == 0) { | |
82 | int dev = (int)simple_strtoul(argv[2], NULL, 10); | |
c609719b | 83 | |
e9be1ee7 SG |
84 | if (blk_print_part_devnum(IF_TYPE_IDE, dev)) { |
85 | printf("\nIDE device %d not available\n", dev); | |
86 | return CMD_RET_FAILURE; | |
ed73508d | 87 | } |
e9be1ee7 | 88 | return 1; |
ed73508d | 89 | } |
c609719b | 90 | |
ed73508d SG |
91 | return CMD_RET_USAGE; |
92 | default: | |
93 | /* at least 4 args */ | |
c609719b | 94 | |
ed73508d SG |
95 | if (strcmp(argv[1], "read") == 0) { |
96 | ulong addr = simple_strtoul(argv[2], NULL, 16); | |
97 | ulong cnt = simple_strtoul(argv[4], NULL, 16); | |
ed73508d | 98 | ulong n; |
c609719b | 99 | |
ed73508d SG |
100 | #ifdef CONFIG_SYS_64BIT_LBA |
101 | lbaint_t blk = simple_strtoull(argv[3], NULL, 16); | |
c609719b | 102 | |
ed73508d SG |
103 | printf("\nIDE read: device %d block # %lld, count %ld...", |
104 | curr_device, blk, cnt); | |
105 | #else | |
106 | lbaint_t blk = simple_strtoul(argv[3], NULL, 16); | |
c609719b | 107 | |
ed73508d SG |
108 | printf("\nIDE read: device %d block # %ld, count %ld...", |
109 | curr_device, blk, cnt); | |
110 | #endif | |
c609719b | 111 | |
e9be1ee7 SG |
112 | n = blk_read_devnum(IF_TYPE_IDE, curr_device, blk, cnt, |
113 | (ulong *)addr); | |
c609719b | 114 | |
ed73508d SG |
115 | printf("%ld blocks read: %s\n", |
116 | n, (n == cnt) ? "OK" : "ERROR"); | |
117 | if (n == cnt) | |
118 | return 0; | |
119 | else | |
120 | return 1; | |
121 | } else if (strcmp(argv[1], "write") == 0) { | |
122 | ulong addr = simple_strtoul(argv[2], NULL, 16); | |
123 | ulong cnt = simple_strtoul(argv[4], NULL, 16); | |
124 | ulong n; | |
c609719b | 125 | |
6d0f6bcf | 126 | #ifdef CONFIG_SYS_64BIT_LBA |
ed73508d SG |
127 | lbaint_t blk = simple_strtoull(argv[3], NULL, 16); |
128 | ||
129 | printf("\nIDE write: device %d block # %lld, count %ld...", | |
130 | curr_device, blk, cnt); | |
413bf586 | 131 | #else |
ed73508d SG |
132 | lbaint_t blk = simple_strtoul(argv[3], NULL, 16); |
133 | ||
134 | printf("\nIDE write: device %d block # %ld, count %ld...", | |
135 | curr_device, blk, cnt); | |
413bf586 | 136 | #endif |
e9be1ee7 SG |
137 | n = blk_write_devnum(IF_TYPE_IDE, curr_device, blk, cnt, |
138 | (ulong *)addr); | |
ed73508d SG |
139 | |
140 | printf("%ld blocks written: %s\n", n, | |
141 | n == cnt ? "OK" : "ERROR"); | |
142 | if (n == cnt) | |
143 | return 0; | |
144 | else | |
145 | return 1; | |
146 | } else { | |
147 | return CMD_RET_USAGE; | |
c40b2956 | 148 | } |
c40b2956 | 149 | |
ed73508d SG |
150 | return rcode; |
151 | } | |
152 | } | |
c40b2956 | 153 | |
ed73508d SG |
154 | int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) |
155 | { | |
156 | return common_diskboot(cmdtp, "ide", argc, argv); | |
157 | } | |
c609719b | 158 | |
34c202c7 WD |
159 | U_BOOT_CMD(ide, 5, 1, do_ide, |
160 | "IDE sub-system", | |
161 | "reset - reset IDE controller\n" | |
162 | "ide info - show available IDE devices\n" | |
163 | "ide device [dev] - show or set current device\n" | |
164 | "ide part [dev] - print partition table of one or all IDE devices\n" | |
165 | "ide read addr blk# cnt\n" | |
166 | "ide write addr blk# cnt - read/write `cnt'" | |
167 | " blocks starting at block `blk#'\n" | |
168 | " to/from memory address `addr'"); | |
169 | ||
170 | U_BOOT_CMD(diskboot, 3, 1, do_diskboot, | |
171 | "boot from IDE device", "loadAddr dev:part"); |