12e192b24SSimon Glass /* 22e192b24SSimon Glass * (C) Copyright 2000-2011 32e192b24SSimon Glass * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 42e192b24SSimon Glass * 52e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 62e192b24SSimon Glass */ 72e192b24SSimon Glass 82e192b24SSimon Glass /* 92e192b24SSimon Glass * IDE support 102e192b24SSimon Glass */ 112e192b24SSimon Glass 122e192b24SSimon Glass #include <common.h> 132a981dc2SSimon Glass #include <blk.h> 142e192b24SSimon Glass #include <config.h> 152e192b24SSimon Glass #include <watchdog.h> 162e192b24SSimon Glass #include <command.h> 172e192b24SSimon Glass #include <image.h> 182e192b24SSimon Glass #include <asm/byteorder.h> 192e192b24SSimon Glass #include <asm/io.h> 202e192b24SSimon Glass 212e192b24SSimon Glass #if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA) 222e192b24SSimon Glass # include <pcmcia.h> 232e192b24SSimon Glass #endif 242e192b24SSimon Glass 252e192b24SSimon Glass #include <ide.h> 262e192b24SSimon Glass #include <ata.h> 272e192b24SSimon Glass 28*2d8d190cSUri Mashiach #ifdef CONFIG_LED_STATUS 292e192b24SSimon Glass # include <status_led.h> 302e192b24SSimon Glass #endif 312e192b24SSimon Glass 322e192b24SSimon Glass /* Current I/O Device */ 332e192b24SSimon Glass static int curr_device = -1; 342e192b24SSimon Glass 352e192b24SSimon Glass int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 362e192b24SSimon Glass { 372e192b24SSimon Glass int rcode = 0; 382e192b24SSimon Glass 392e192b24SSimon Glass switch (argc) { 402e192b24SSimon Glass case 0: 412e192b24SSimon Glass case 1: 422e192b24SSimon Glass return CMD_RET_USAGE; 432e192b24SSimon Glass case 2: 442e192b24SSimon Glass if (strncmp(argv[1], "res", 3) == 0) { 452e192b24SSimon Glass puts("\nReset IDE" 462e192b24SSimon Glass #ifdef CONFIG_IDE_8xx_DIRECT 472e192b24SSimon Glass " on PCMCIA " PCMCIA_SLOT_MSG 482e192b24SSimon Glass #endif 492e192b24SSimon Glass ": "); 502e192b24SSimon Glass 512e192b24SSimon Glass ide_init(); 522e192b24SSimon Glass return 0; 532e192b24SSimon Glass } else if (strncmp(argv[1], "inf", 3) == 0) { 54e9be1ee7SSimon Glass blk_list_devices(IF_TYPE_IDE); 552e192b24SSimon Glass return 0; 562e192b24SSimon Glass 572e192b24SSimon Glass } else if (strncmp(argv[1], "dev", 3) == 0) { 58e9be1ee7SSimon Glass if (blk_print_device_num(IF_TYPE_IDE, curr_device)) { 59e9be1ee7SSimon Glass printf("\nno IDE devices available\n"); 60e9be1ee7SSimon Glass return CMD_RET_FAILURE; 612e192b24SSimon Glass } 62e9be1ee7SSimon Glass 632e192b24SSimon Glass return 0; 642e192b24SSimon Glass } else if (strncmp(argv[1], "part", 4) == 0) { 65e9be1ee7SSimon Glass if (blk_list_part(IF_TYPE_IDE)) 66e9be1ee7SSimon Glass printf("\nno IDE devices available\n"); 67e9be1ee7SSimon Glass return 1; 682e192b24SSimon Glass } 692e192b24SSimon Glass return CMD_RET_USAGE; 702e192b24SSimon Glass case 3: 712e192b24SSimon Glass if (strncmp(argv[1], "dev", 3) == 0) { 722e192b24SSimon Glass int dev = (int)simple_strtoul(argv[2], NULL, 10); 732e192b24SSimon Glass 74e9be1ee7SSimon Glass if (!blk_show_device(IF_TYPE_IDE, dev)) { 752e192b24SSimon Glass curr_device = dev; 76e9be1ee7SSimon Glass printf("... is now current device\n"); 77e9be1ee7SSimon Glass } else { 78e9be1ee7SSimon Glass return CMD_RET_FAILURE; 79e9be1ee7SSimon Glass } 802e192b24SSimon Glass return 0; 812e192b24SSimon Glass } else if (strncmp(argv[1], "part", 4) == 0) { 822e192b24SSimon Glass int dev = (int)simple_strtoul(argv[2], NULL, 10); 832e192b24SSimon Glass 84e9be1ee7SSimon Glass if (blk_print_part_devnum(IF_TYPE_IDE, dev)) { 85e9be1ee7SSimon Glass printf("\nIDE device %d not available\n", dev); 86e9be1ee7SSimon Glass return CMD_RET_FAILURE; 872e192b24SSimon Glass } 88e9be1ee7SSimon Glass return 1; 892e192b24SSimon Glass } 902e192b24SSimon Glass 912e192b24SSimon Glass return CMD_RET_USAGE; 922e192b24SSimon Glass default: 932e192b24SSimon Glass /* at least 4 args */ 942e192b24SSimon Glass 952e192b24SSimon Glass if (strcmp(argv[1], "read") == 0) { 962e192b24SSimon Glass ulong addr = simple_strtoul(argv[2], NULL, 16); 972e192b24SSimon Glass ulong cnt = simple_strtoul(argv[4], NULL, 16); 982e192b24SSimon Glass ulong n; 992e192b24SSimon Glass 1002e192b24SSimon Glass #ifdef CONFIG_SYS_64BIT_LBA 1012e192b24SSimon Glass lbaint_t blk = simple_strtoull(argv[3], NULL, 16); 1022e192b24SSimon Glass 1032e192b24SSimon Glass printf("\nIDE read: device %d block # %lld, count %ld...", 1042e192b24SSimon Glass curr_device, blk, cnt); 1052e192b24SSimon Glass #else 1062e192b24SSimon Glass lbaint_t blk = simple_strtoul(argv[3], NULL, 16); 1072e192b24SSimon Glass 1082e192b24SSimon Glass printf("\nIDE read: device %d block # %ld, count %ld...", 1092e192b24SSimon Glass curr_device, blk, cnt); 1102e192b24SSimon Glass #endif 1112e192b24SSimon Glass 112e9be1ee7SSimon Glass n = blk_read_devnum(IF_TYPE_IDE, curr_device, blk, cnt, 113e9be1ee7SSimon Glass (ulong *)addr); 1142e192b24SSimon Glass 1152e192b24SSimon Glass printf("%ld blocks read: %s\n", 1162e192b24SSimon Glass n, (n == cnt) ? "OK" : "ERROR"); 1172e192b24SSimon Glass if (n == cnt) 1182e192b24SSimon Glass return 0; 1192e192b24SSimon Glass else 1202e192b24SSimon Glass return 1; 1212e192b24SSimon Glass } else if (strcmp(argv[1], "write") == 0) { 1222e192b24SSimon Glass ulong addr = simple_strtoul(argv[2], NULL, 16); 1232e192b24SSimon Glass ulong cnt = simple_strtoul(argv[4], NULL, 16); 1242e192b24SSimon Glass ulong n; 1252e192b24SSimon Glass 1262e192b24SSimon Glass #ifdef CONFIG_SYS_64BIT_LBA 1272e192b24SSimon Glass lbaint_t blk = simple_strtoull(argv[3], NULL, 16); 1282e192b24SSimon Glass 1292e192b24SSimon Glass printf("\nIDE write: device %d block # %lld, count %ld...", 1302e192b24SSimon Glass curr_device, blk, cnt); 1312e192b24SSimon Glass #else 1322e192b24SSimon Glass lbaint_t blk = simple_strtoul(argv[3], NULL, 16); 1332e192b24SSimon Glass 1342e192b24SSimon Glass printf("\nIDE write: device %d block # %ld, count %ld...", 1352e192b24SSimon Glass curr_device, blk, cnt); 1362e192b24SSimon Glass #endif 137e9be1ee7SSimon Glass n = blk_write_devnum(IF_TYPE_IDE, curr_device, blk, cnt, 1382e192b24SSimon Glass (ulong *)addr); 1392e192b24SSimon Glass 140ed73508dSSimon Glass printf("%ld blocks written: %s\n", n, 141ed73508dSSimon Glass n == cnt ? "OK" : "ERROR"); 1422e192b24SSimon Glass if (n == cnt) 1432e192b24SSimon Glass return 0; 1442e192b24SSimon Glass else 1452e192b24SSimon Glass return 1; 1462e192b24SSimon Glass } else { 1472e192b24SSimon Glass return CMD_RET_USAGE; 1482e192b24SSimon Glass } 1492e192b24SSimon Glass 1502e192b24SSimon Glass return rcode; 1512e192b24SSimon Glass } 1522e192b24SSimon Glass } 1532e192b24SSimon Glass 1542e192b24SSimon Glass int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 1552e192b24SSimon Glass { 1562e192b24SSimon Glass return common_diskboot(cmdtp, "ide", argc, argv); 1572e192b24SSimon Glass } 1582e192b24SSimon Glass 1592e192b24SSimon Glass U_BOOT_CMD(ide, 5, 1, do_ide, 1602e192b24SSimon Glass "IDE sub-system", 1612e192b24SSimon Glass "reset - reset IDE controller\n" 1622e192b24SSimon Glass "ide info - show available IDE devices\n" 1632e192b24SSimon Glass "ide device [dev] - show or set current device\n" 1642e192b24SSimon Glass "ide part [dev] - print partition table of one or all IDE devices\n" 1652e192b24SSimon Glass "ide read addr blk# cnt\n" 1662e192b24SSimon Glass "ide write addr blk# cnt - read/write `cnt'" 1672e192b24SSimon Glass " blocks starting at block `blk#'\n" 1682e192b24SSimon Glass " to/from memory address `addr'"); 1692e192b24SSimon Glass 1702e192b24SSimon Glass U_BOOT_CMD(diskboot, 3, 1, do_diskboot, 1712e192b24SSimon Glass "boot from IDE device", "loadAddr dev:part"); 172