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