1 /* $NetBSD: sd.c,v 1.13 2023/06/24 07:02:11 tsutsui 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 * @(#)sd.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 * @(#)sd.c 8.1 (Berkeley) 6/10/93
71 */
72
73 /*
74 * sd.c -- SCSI DISK device driver
75 * by A.Fujita, FEB-26-1992
76 */
77
78
79 /*
80 * SCSI CCS (Command Command Set) disk driver.
81 */
82 #include <sys/param.h>
83 #include <sys/disklabel.h>
84 #include <luna68k/stand/boot/samachdep.h>
85 #include <luna68k/stand/boot/scsireg.h>
86
87 struct sd_softc {
88 int sc_unit;
89 uint sc_ctlr;
90 uint sc_tgt;
91 uint sc_lun;
92 int sc_part;
93 uint sc_bshift; /* convert device blocks to DEV_BSIZE blks */
94 uint sc_blks; /* number of blocks on device */
95 int sc_blksize; /* device block size in bytes */
96 struct disklabel sc_label;
97 };
98
99 static int sdident(struct sd_softc *);
100 static struct sd_softc *sdinit(uint);
101
102 static int
sdident(struct sd_softc * sc)103 sdident(struct sd_softc *sc)
104 {
105 struct scsi_inquiry inqbuf;
106 uint32_t capbuf[2];
107 int i;
108
109 if (!scident(sc->sc_ctlr, sc->sc_tgt, sc->sc_lun, &inqbuf, capbuf))
110 return -1;
111
112 sc->sc_blks = capbuf[0];
113 sc->sc_blksize = capbuf[1];
114
115 if (sc->sc_blksize != DEV_BSIZE) {
116 if (sc->sc_blksize < DEV_BSIZE) {
117 return -1;
118 }
119 for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
120 ++sc->sc_bshift;
121 sc->sc_blks <<= sc->sc_bshift;
122 }
123 return inqbuf.type;
124 }
125
126 static struct sd_softc *
sdinit(uint unit)127 sdinit(uint unit)
128 {
129 struct sd_softc *sc;
130 struct disklabel *lp;
131 char *msg;
132 int type;
133
134 #ifdef DEBUG
135 printf("sdinit: unit = %d\n", unit);
136 #endif
137 sc = alloc(sizeof *sc);
138 memset(sc, 0, sizeof *sc);
139
140 sc->sc_unit = unit;
141 sc->sc_ctlr = CTLR(unit);
142 sc->sc_tgt = TARGET(unit);
143 sc->sc_lun = 0; /* XXX no LUN support yet */
144 type = sdident(sc);
145 if (type < 0)
146 return NULL;
147
148 /*
149 * Use the default sizes until we've read the label,
150 * or longer if there isn't one there.
151 */
152 lp = &sc->sc_label;
153
154 if (lp->d_secpercyl == 0) {
155 lp->d_secsize = DEV_BSIZE;
156 lp->d_nsectors = 32;
157 lp->d_ntracks = 20;
158 lp->d_secpercyl = 32*20;
159 lp->d_npartitions = 1;
160 lp->d_partitions[0].p_offset = 0;
161 lp->d_partitions[0].p_size = LABELSECTOR + 1;
162 }
163
164 /*
165 * read disklabel
166 */
167 msg = readdisklabel(sc->sc_ctlr, sc->sc_tgt, lp);
168 if (msg != NULL)
169 printf("sd(%d): %s\n", unit, msg);
170
171 return sc;
172 }
173
174 int
sdopen(struct open_file * f,...)175 sdopen(struct open_file *f, ...)
176 {
177 va_list ap;
178 struct sd_softc *sc;
179 int unit, part;
180
181 va_start(ap, f);
182 unit = va_arg(ap, int);
183 part = va_arg(ap, int);
184 va_end(ap);
185
186 if (unit < 0 || CTLR(unit) >= 2 || TARGET(unit) >= 7)
187 return -1;
188 if (part < 0 || part >= MAXPARTITIONS)
189 return -1;
190
191 sc = sdinit(unit);
192 if (sc == NULL)
193 return -1;
194
195 sc->sc_part = part;
196 f->f_devdata = (void *)sc;
197
198 return 0;
199 }
200
201 int
sdclose(struct open_file * f)202 sdclose(struct open_file *f)
203 {
204 struct sd_softc *sc = f->f_devdata;
205
206 dealloc(sc, sizeof *sc);
207 f->f_devdata = NULL;
208
209 return 0;
210 }
211
212 static struct scsi_generic_cdb cdb_read = {
213 10,
214 { CMD_READ_EXT, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
215 };
216
217 static struct scsi_generic_cdb cdb_write = {
218 10,
219 { CMD_WRITE_EXT, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
220 };
221
222 int
sdstrategy(void * devdata,int func,daddr_t dblk,size_t size,void * v_buf,size_t * rsize)223 sdstrategy(void *devdata, int func, daddr_t dblk, size_t size, void *v_buf,
224 size_t *rsize)
225 {
226 struct sd_softc *sc;
227 struct disklabel *lp;
228 uint8_t *buf;
229 struct scsi_generic_cdb *cdb;
230 daddr_t blk;
231 u_int nblk;
232 int stat;
233 #ifdef DEBUG
234 int i;
235 #endif
236
237 sc = devdata;
238 if (sc == NULL)
239 return -1;
240
241 buf = v_buf;
242 lp = &sc->sc_label;
243 blk = dblk + (lp->d_partitions[sc->sc_part].p_offset >> sc->sc_bshift);
244 nblk = size >> sc->sc_bshift;
245
246 if (func == F_READ)
247 cdb = &cdb_read;
248 else
249 cdb = &cdb_write;
250
251 cdb->cdb[2] = (blk & 0xff000000) >> 24;
252 cdb->cdb[3] = (blk & 0x00ff0000) >> 16;
253 cdb->cdb[4] = (blk & 0x0000ff00) >> 8;
254 cdb->cdb[5] = (blk & 0x000000ff);
255
256 cdb->cdb[7] = ((nblk >> DEV_BSHIFT) & 0xff00) >> 8;
257 cdb->cdb[8] = ((nblk >> DEV_BSHIFT) & 0x00ff);
258
259 #ifdef DEBUG
260 printf("sdstrategy: unit = %d\n", sc->sc_unit);
261 printf("sdstrategy: blk = %lu (0x%lx), nblk = %u (0x%x)\n",
262 (u_long)blk, (long)blk, nblk, nblk);
263 for (i = 0; i < 10; i++)
264 printf("sdstrategy: cdb[%d] = 0x%x\n", i, cdb->cdb[i]);
265 printf("sdstrategy: ctlr = %d, target = %d\n", sc->sc_ctlr, sc->sc_tgt);
266 #endif
267 stat = scsi_immed_command(sc->sc_ctlr, sc->sc_tgt, sc->sc_lun,
268 cdb, buf, size);
269 if (stat != 0)
270 return EIO;
271
272 if (rsize)
273 *rsize = size;
274
275 return 0;
276 }
277