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