1 /* 2 * (C) Copyright 2001 3 * Denis Peter, MPL AG Switzerland 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* 9 * SCSI support. 10 */ 11 #include <common.h> 12 #include <command.h> 13 #include <scsi.h> 14 15 static int scsi_curr_dev; /* current device */ 16 17 /* 18 * scsi boot command intepreter. Derived from diskboot 19 */ 20 static int do_scsiboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 21 { 22 return common_diskboot(cmdtp, "scsi", argc, argv); 23 } 24 25 /* 26 * scsi command intepreter 27 */ 28 static int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 29 { 30 int ret; 31 32 switch (argc) { 33 case 0: 34 case 1: 35 return CMD_RET_USAGE; 36 case 2: 37 if (strncmp(argv[1], "res", 3) == 0) { 38 printf("\nReset SCSI\n"); 39 scsi_bus_reset(); 40 ret = scsi_scan(1); 41 if (ret) 42 return CMD_RET_FAILURE; 43 return ret; 44 } 45 if (strncmp(argv[1], "inf", 3) == 0) { 46 blk_list_devices(IF_TYPE_SCSI); 47 return 0; 48 } 49 if (strncmp(argv[1], "dev", 3) == 0) { 50 if (blk_print_device_num(IF_TYPE_SCSI, scsi_curr_dev)) { 51 printf("\nno SCSI devices available\n"); 52 return CMD_RET_FAILURE; 53 } 54 55 return 0; 56 } 57 if (strncmp(argv[1], "scan", 4) == 0) { 58 ret = scsi_scan(1); 59 if (ret) 60 return CMD_RET_FAILURE; 61 return ret; 62 } 63 if (strncmp(argv[1], "part", 4) == 0) { 64 if (blk_list_part(IF_TYPE_SCSI)) 65 printf("\nno SCSI devices available\n"); 66 return 0; 67 } 68 return CMD_RET_USAGE; 69 case 3: 70 if (strncmp(argv[1], "dev", 3) == 0) { 71 int dev = (int)simple_strtoul(argv[2], NULL, 10); 72 73 if (!blk_show_device(IF_TYPE_SCSI, dev)) { 74 scsi_curr_dev = dev; 75 printf("... is now current device\n"); 76 } else { 77 return CMD_RET_FAILURE; 78 } 79 return 0; 80 } 81 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_SCSI, dev)) { 85 printf("\nSCSI device %d not available\n", 86 dev); 87 return CMD_RET_FAILURE; 88 } 89 return 0; 90 } 91 return CMD_RET_USAGE; 92 default: 93 /* at least 4 args */ 94 if (strcmp(argv[1], "read") == 0) { 95 ulong addr = simple_strtoul(argv[2], NULL, 16); 96 ulong blk = simple_strtoul(argv[3], NULL, 16); 97 ulong cnt = simple_strtoul(argv[4], NULL, 16); 98 ulong n; 99 100 printf("\nSCSI read: device %d block # %ld, count %ld ... ", 101 scsi_curr_dev, blk, cnt); 102 n = blk_read_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk, 103 cnt, (ulong *)addr); 104 printf("%ld blocks read: %s\n", n, 105 n == cnt ? "OK" : "ERROR"); 106 return 0; 107 } else if (strcmp(argv[1], "write") == 0) { 108 ulong addr = simple_strtoul(argv[2], NULL, 16); 109 ulong blk = simple_strtoul(argv[3], NULL, 16); 110 ulong cnt = simple_strtoul(argv[4], NULL, 16); 111 ulong n; 112 113 printf("\nSCSI write: device %d block # %ld, count %ld ... ", 114 scsi_curr_dev, blk, cnt); 115 n = blk_write_devnum(IF_TYPE_SCSI, scsi_curr_dev, blk, 116 cnt, (ulong *)addr); 117 printf("%ld blocks written: %s\n", n, 118 n == cnt ? "OK" : "ERROR"); 119 return 0; 120 } 121 } /* switch */ 122 return CMD_RET_USAGE; 123 } 124 125 U_BOOT_CMD( 126 scsi, 5, 1, do_scsi, 127 "SCSI sub-system", 128 "reset - reset SCSI controller\n" 129 "scsi info - show available SCSI devices\n" 130 "scsi scan - (re-)scan SCSI bus\n" 131 "scsi device [dev] - show or set current device\n" 132 "scsi part [dev] - print partition table of one or all SCSI devices\n" 133 "scsi read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" 134 " to memory address `addr'\n" 135 "scsi write addr blk# cnt - write `cnt' blocks starting at block\n" 136 " `blk#' from memory address `addr'" 137 ); 138 139 U_BOOT_CMD( 140 scsiboot, 3, 1, do_scsiboot, 141 "boot from SCSI device", 142 "loadAddr dev:part" 143 ); 144