xref: /netbsd-src/sys/arch/luna68k/stand/boot/scsi.c (revision 8dc4ac44b8c4edfe9d75764f8f1e456036bf233b)
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