12e192b24SSimon Glass /* 22e192b24SSimon Glass * (C) Copyright 2001 32e192b24SSimon Glass * Denis Peter, MPL AG Switzerland 42e192b24SSimon Glass * 52e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 62e192b24SSimon Glass */ 72e192b24SSimon Glass 82e192b24SSimon Glass /* 92e192b24SSimon Glass * SCSI support. 102e192b24SSimon Glass */ 112e192b24SSimon Glass #include <common.h> 122e192b24SSimon Glass #include <command.h> 132e192b24SSimon Glass #include <scsi.h> 142e192b24SSimon Glass 152e192b24SSimon Glass static int scsi_curr_dev; /* current device */ 162e192b24SSimon Glass 172e192b24SSimon Glass /* 182e192b24SSimon Glass * scsi boot command intepreter. Derived from diskboot 192e192b24SSimon Glass */ 202e192b24SSimon Glass int do_scsiboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 212e192b24SSimon Glass { 222e192b24SSimon Glass return common_diskboot(cmdtp, "scsi", argc, argv); 232e192b24SSimon Glass } 242e192b24SSimon Glass 25*11f610edSSimon Glass /* 262e192b24SSimon Glass * scsi command intepreter 272e192b24SSimon Glass */ 282e192b24SSimon Glass int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 292e192b24SSimon Glass { 302e192b24SSimon Glass switch (argc) { 312e192b24SSimon Glass case 0: 322e192b24SSimon Glass case 1: 332e192b24SSimon Glass return CMD_RET_USAGE; 342e192b24SSimon Glass case 2: 352e192b24SSimon Glass if (strncmp(argv[1], "res", 3) == 0) { 362e192b24SSimon Glass printf("\nReset SCSI\n"); 372e192b24SSimon Glass scsi_bus_reset(); 382e192b24SSimon Glass scsi_scan(1); 392e192b24SSimon Glass return 0; 402e192b24SSimon Glass } 412e192b24SSimon Glass if (strncmp(argv[1], "inf", 3) == 0) { 42*11f610edSSimon Glass blk_list_devices(IF_TYPE_SCSI); 432e192b24SSimon Glass return 0; 442e192b24SSimon Glass } 452e192b24SSimon Glass if (strncmp(argv[1], "dev", 3) == 0) { 46*11f610edSSimon Glass if (blk_print_device_num(IF_TYPE_SCSI, scsi_curr_dev)) { 472e192b24SSimon Glass printf("\nno SCSI devices available\n"); 48*11f610edSSimon Glass return CMD_RET_FAILURE; 492e192b24SSimon Glass } 50*11f610edSSimon Glass 512e192b24SSimon Glass return 0; 522e192b24SSimon Glass } 532e192b24SSimon Glass if (strncmp(argv[1], "scan", 4) == 0) { 542e192b24SSimon Glass scsi_scan(1); 552e192b24SSimon Glass return 0; 562e192b24SSimon Glass } 572e192b24SSimon Glass if (strncmp(argv[1], "part", 4) == 0) { 58*11f610edSSimon Glass if (blk_list_part(IF_TYPE_SCSI)) 592e192b24SSimon Glass printf("\nno SCSI devices available\n"); 60*11f610edSSimon Glass return 0; 612e192b24SSimon Glass } 622e192b24SSimon Glass return CMD_RET_USAGE; 632e192b24SSimon Glass case 3: 642e192b24SSimon Glass if (strncmp(argv[1], "dev", 3) == 0) { 652e192b24SSimon Glass int dev = (int)simple_strtoul(argv[2], NULL, 10); 66*11f610edSSimon Glass 67*11f610edSSimon Glass if (!blk_show_device(IF_TYPE_SCSI, dev)) { 682e192b24SSimon Glass scsi_curr_dev = dev; 692e192b24SSimon Glass printf("... is now current device\n"); 70*11f610edSSimon Glass } else { 71*11f610edSSimon Glass return CMD_RET_FAILURE; 72*11f610edSSimon Glass } 732e192b24SSimon Glass return 0; 742e192b24SSimon Glass } 752e192b24SSimon Glass if (strncmp(argv[1], "part", 4) == 0) { 762e192b24SSimon Glass int dev = (int)simple_strtoul(argv[2], NULL, 10); 77*11f610edSSimon Glass 78*11f610edSSimon Glass if (blk_print_part_devnum(IF_TYPE_SCSI, dev)) { 79*11f610edSSimon Glass printf("\nSCSI device %d not available\n", 80*11f610edSSimon Glass dev); 81*11f610edSSimon Glass return CMD_RET_FAILURE; 82*11f610edSSimon Glass } 83*11f610edSSimon Glass return 0; 842e192b24SSimon Glass } 852e192b24SSimon Glass return CMD_RET_USAGE; 862e192b24SSimon Glass default: 872e192b24SSimon Glass /* at least 4 args */ 882e192b24SSimon Glass if (strcmp(argv[1], "read") == 0) { 892e192b24SSimon Glass ulong addr = simple_strtoul(argv[2], NULL, 16); 902e192b24SSimon Glass ulong blk = simple_strtoul(argv[3], NULL, 16); 912e192b24SSimon Glass ulong cnt = simple_strtoul(argv[4], NULL, 16); 922e192b24SSimon Glass ulong n; 93*11f610edSSimon Glass 942e192b24SSimon Glass printf("\nSCSI read: device %d block # %ld, count %ld ... ", 952e192b24SSimon Glass scsi_curr_dev, blk, cnt); 96*11f610edSSimon Glass n = blk_read_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk, 97*11f610edSSimon Glass cnt, (ulong *)addr); 98f1d4d937SSimon Glass printf("%ld blocks read: %s\n", n, 99f1d4d937SSimon Glass n == cnt ? "OK" : "ERROR"); 1002e192b24SSimon Glass return 0; 1012e192b24SSimon Glass } else if (strcmp(argv[1], "write") == 0) { 1022e192b24SSimon Glass ulong addr = simple_strtoul(argv[2], NULL, 16); 1032e192b24SSimon Glass ulong blk = simple_strtoul(argv[3], NULL, 16); 1042e192b24SSimon Glass ulong cnt = simple_strtoul(argv[4], NULL, 16); 1052e192b24SSimon Glass ulong n; 106*11f610edSSimon Glass 107f1d4d937SSimon Glass printf("\nSCSI write: device %d block # %ld, count %ld ... ", 1082e192b24SSimon Glass scsi_curr_dev, blk, cnt); 109*11f610edSSimon Glass n = blk_write_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk, 110*11f610edSSimon Glass cnt, (ulong *)addr); 1112e192b24SSimon Glass printf("%ld blocks written: %s\n", n, 112f1d4d937SSimon Glass n == cnt ? "OK" : "ERROR"); 1132e192b24SSimon Glass return 0; 1142e192b24SSimon Glass } 1152e192b24SSimon Glass } /* switch */ 1162e192b24SSimon Glass return CMD_RET_USAGE; 1172e192b24SSimon Glass } 1182e192b24SSimon Glass 119ba524269STom Rini U_BOOT_CMD( 120ba524269STom Rini scsi, 5, 1, do_scsi, 121ba524269STom Rini "SCSI sub-system", 122ba524269STom Rini "reset - reset SCSI controller\n" 123ba524269STom Rini "scsi info - show available SCSI devices\n" 124ba524269STom Rini "scsi scan - (re-)scan SCSI bus\n" 125ba524269STom Rini "scsi device [dev] - show or set current device\n" 126ba524269STom Rini "scsi part [dev] - print partition table of one or all SCSI devices\n" 127ba524269STom Rini "scsi read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" 128ba524269STom Rini " to memory address `addr'\n" 129ba524269STom Rini "scsi write addr blk# cnt - write `cnt' blocks starting at block\n" 130ba524269STom Rini " `blk#' from memory address `addr'" 131ba524269STom Rini ); 132ba524269STom Rini 133ba524269STom Rini U_BOOT_CMD( 134ba524269STom Rini scsiboot, 3, 1, do_scsiboot, 135ba524269STom Rini "boot from SCSI device", 136ba524269STom Rini "loadAddr dev:part" 137ba524269STom Rini ); 138