xref: /openbmc/u-boot/cmd/ide.c (revision a5c289b9bca3805fa35e42f389dc8225c6b916be)
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  /*
9   * IDE support
10   */
11  
12  #include <common.h>
13  #include <blk.h>
14  #include <config.h>
15  #include <watchdog.h>
16  #include <command.h>
17  #include <image.h>
18  #include <asm/byteorder.h>
19  #include <asm/io.h>
20  
21  #if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA)
22  # include <pcmcia.h>
23  #endif
24  
25  #include <ide.h>
26  #include <ata.h>
27  
28  #ifdef CONFIG_STATUS_LED
29  # include <status_led.h>
30  #endif
31  
32  /* Current I/O Device	*/
33  static int curr_device = -1;
34  
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) {
54  			blk_list_devices(IF_TYPE_IDE);
55  			return 0;
56  
57  		} else if (strncmp(argv[1], "dev", 3) == 0) {
58  			if (blk_print_device_num(IF_TYPE_IDE, curr_device)) {
59  				printf("\nno IDE devices available\n");
60  				return CMD_RET_FAILURE;
61  			}
62  
63  			return 0;
64  		} else if (strncmp(argv[1], "part", 4) == 0) {
65  			if (blk_list_part(IF_TYPE_IDE))
66  				printf("\nno IDE devices available\n");
67  			return 1;
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);
73  
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;
79  			}
80  			return 0;
81  		} else if (strncmp(argv[1], "part", 4) == 0) {
82  			int dev = (int)simple_strtoul(argv[2], NULL, 10);
83  
84  			if (blk_print_part_devnum(IF_TYPE_IDE, dev)) {
85  				printf("\nIDE device %d not available\n", dev);
86  				return CMD_RET_FAILURE;
87  			}
88  			return 1;
89  		}
90  
91  		return CMD_RET_USAGE;
92  	default:
93  		/* at least 4 args */
94  
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);
98  			ulong n;
99  
100  #ifdef CONFIG_SYS_64BIT_LBA
101  			lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
102  
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);
107  
108  			printf("\nIDE read: device %d block # %ld, count %ld...",
109  			       curr_device, blk, cnt);
110  #endif
111  
112  			n = blk_read_devnum(IF_TYPE_IDE, curr_device, blk, cnt,
113  					    (ulong *)addr);
114  
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;
125  
126  #ifdef CONFIG_SYS_64BIT_LBA
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);
131  #else
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);
136  #endif
137  			n = blk_write_devnum(IF_TYPE_IDE, curr_device, blk, cnt,
138  					     (ulong *)addr);
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;
148  		}
149  
150  		return rcode;
151  	}
152  }
153  
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  }
158  
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");
172