1 /* $NetBSD: scsi.c,v 1.8 2024/07/05 20:19:43 andvar Exp $ */
2
3 /*
4 * Copyright (c) 1992 OMRON Corporation.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * OMRON Corporation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * @(#)scsi.c 8.1 (Berkeley) 6/10/93
38 */
39 /*
40 * Copyright (c) 1992, 1993
41 * The Regents of the University of California. All rights reserved.
42 *
43 * This code is derived from software contributed to Berkeley by
44 * OMRON Corporation.
45 *
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
48 * are met:
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 * 3. Neither the name of the University nor the names of its contributors
55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE.
69 *
70 * @(#)scsi.c 8.1 (Berkeley) 6/10/93
71 */
72
73 /*
74 * scsi.c -- front end of SCSI test commands
75 * by A.Fujita, FEB-09-1992
76 */
77
78 #include <sys/param.h>
79 #include <lib/libkern/libkern.h>
80 #include <luna68k/stand/boot/samachdep.h>
81 #include <luna68k/stand/boot/scsireg.h>
82 #include <luna68k/stand/boot/status.h>
83
84
85 int scsi_device = 6;
86
87 #define SENSBUFF 8 /* デバイスドライバでセンスデータ */
88 /* の長さを8バイト以内に固定して */
89 uint8_t sensbuff[SENSBUFF]; /* 8以上は無意味である。 */
90
91 static struct scsi_inquiry inquirybuf;
92 static struct scsi_generic_cdb inquiry = {
93 6,
94 { CMD_INQUIRY, 0, 0, 0, sizeof(inquirybuf), 0 }
95 };
96
97 static u_long capacitybuf[2];
98 struct scsi_generic_cdb capacity = {
99 10,
100 { CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
101 };
102
103
104 int
scsi(int argc,char * argv[])105 scsi(int argc, char *argv[])
106 {
107 char *p;
108 int i, status;
109
110 if (argc < 2) {
111 printf("This command is required subcommand !!\n");
112 return ST_ERROR;
113 }
114
115 if (!strcmp(argv[1], "device")) {
116 if (argc > 2) {
117 i = 0;
118 for (p = argv[2]; *p != '\0' ; p++) {
119 i = i * 10 + *p - '0';
120 }
121 if (i < 8 && i >= 0) {
122 scsi_device = i;
123 }
124 }
125 printf("Current Device ID: %d\n", scsi_device);
126 } else if (!strcmp(argv[1], "test_unit_rdy")) {
127 /* CTLR SLAVE LUN */
128 scsi_test_unit_rdy( 0, scsi_device, 0);
129 } else if (!strcmp(argv[1], "request_sense")) {
130 /* CTLR SLAVE LUN */
131 scsi_request_sense( 0, scsi_device, 0, sensbuff, SENSBUFF);
132 } else if (!strcmp(argv[1], "inquiry")) {
133 if (scsi_immed_command( 0, scsi_device, 0, &inquiry,
134 (uint8_t *)&inquirybuf, sizeof(inquirybuf)) == 0) {
135 printf("Type:\t0x%x\n", inquirybuf.type);
136 printf("Qualifier:\t0x%x\n", inquirybuf.qual);
137 printf("Version:\t0x%x\n", inquirybuf.version);
138 printf("RDF:\t0x%x\n", inquirybuf.rsvd);
139
140 printf("Vendor ID:\t");
141 for (i = 0; i < 8; i++)
142 printf("%c", inquirybuf.vendor_id[i]);
143 printf("\n");
144
145 printf("Product ID:\t");
146 for (i = 0; i < 16; i++)
147 printf("%c", inquirybuf.product_id[i]);
148 printf("\n");
149
150 printf("Revision:\t");
151 for (i = 0; i < 4; i++)
152 printf("%c", inquirybuf.rev[i]);
153 printf("\n");
154 }
155 } else if (!strcmp(argv[1], "read_capacity")) {
156 if (scsi_immed_command( 0, scsi_device, 0, &capacity,
157 (uint8_t *)&capacitybuf, sizeof(capacitybuf)) == 0) {
158 printf("Logical Block Address:\t%ld (0x%lx)\n",
159 capacitybuf[0], capacitybuf[0]);
160 printf("Block Length:\t\t%ld (0x%lx)\n",
161 capacitybuf[1], capacitybuf[1]);
162 }
163 } else if (!strcmp(argv[1], "trace")) {
164 for (i = 0; i < 7; i++) {
165 printf("SCSI ID %d .... ", i);
166 status = scsi_test_unit_rdy(0, i, 0);
167 if (status >= 0)
168 printf("found.\n");
169 else
170 printf("no.\n");
171 }
172 } else if (!strcmp(argv[1], "format_unit")) {
173 i = 0;
174 while (i == 0) {
175 printf("Do you really want to format SCSI %d device ?"
176 " [y/n]: ", scsi_device);
177 i = getchar();
178 printf("\n");
179 if ((i != 'y') && (i != 'Y') &&
180 (i != 'n') && (i != 'N'))
181 i = 0;
182 }
183
184 if ((i == 'y') || (i == 'Y'))
185 status = scsi_format_unit(0, scsi_device, 0);
186 }
187
188 return ST_NORMAL;
189 }
190
191 static struct scsi_generic_cdb scsi_cdb = {
192 10,
193 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
194 };
195
196 int
scsi_read_raw(u_int target,u_int blk,u_int nblk,uint8_t * buff,u_int len)197 scsi_read_raw(u_int target, u_int blk, u_int nblk, uint8_t *buff, u_int len)
198 {
199 struct scsi_generic_cdb *cdb = &scsi_cdb;
200
201 cdb->cdb[0] = CMD_READ_EXT;
202
203 cdb->cdb[2] = (blk & 0xff000000) >> 24;
204 cdb->cdb[3] = (blk & 0x00ff0000) >> 16;
205 cdb->cdb[4] = (blk & 0x0000ff00) >> 8;
206 cdb->cdb[5] = (blk & 0x000000ff);
207
208 cdb->cdb[7] = (nblk & 0xff00) >> 8;
209 cdb->cdb[8] = (nblk & 0x00ff);
210
211 if (scsi_immed_command(0, target, 0, cdb, buff, len) == 0)
212 return 1;
213 else
214 return 0;
215 }
216
217 int
scsi_read(u_int blk,uint8_t * buff,u_int len)218 scsi_read(u_int blk, uint8_t *buff, u_int len)
219 {
220 u_int nblk = len >> DEV_BSHIFT;
221
222 return scsi_read_raw(scsi_device, blk, nblk, buff, len);
223 }
224
225 int
scsi_write(u_int blk,uint8_t * buff,u_int len)226 scsi_write(u_int blk, uint8_t *buff, u_int len)
227 {
228 struct scsi_generic_cdb *cdb = &scsi_cdb;
229
230 cdb->cdb[0] = CMD_WRITE_EXT;
231
232 cdb->cdb[2] = (blk & 0xff000000) >> 24;
233 cdb->cdb[3] = (blk & 0x00ff0000) >> 16;
234 cdb->cdb[4] = (blk & 0x0000ff00) >> 8;
235 cdb->cdb[5] = (blk & 0x000000ff);
236
237 cdb->cdb[7] = ((len >> DEV_BSHIFT) & 0xff00) >> 8;
238 cdb->cdb[8] = ((len >> DEV_BSHIFT) & 0x00ff);
239
240 if (scsi_immed_command(0, scsi_device, 0, cdb, buff, len) == 0)
241 return 1;
242 else
243 return 0;
244 }
245