hp.c revision 1.3 1 /* $NetBSD: hp.c,v 1.3 1996/02/02 18:59:27 mycroft Exp $ */
2 /*
3 * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed at Ludd, University of Lule}.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /* All bugs are subject to removal without further notice */
33
34
35
36 /* hp.c - drivrutiner f|r massbussdiskar 940325/ragge */
37
38 #include <sys/param.h>
39 #include <sys/types.h>
40 #include <sys/fcntl.h>
41 #include <sys/syslog.h>
42 #include <sys/disklabel.h>
43 #include <sys/buf.h>
44
45 #include <vax/mba/mbareg.h>
46 #include <vax/mba/mbavar.h>
47 #include <vax/mba/hpdefs.h>
48
49 #include "hp.h"
50
51 struct mba_device *hpinfo[NHP];
52 struct hp_info hp_info[NHP];
53 struct disklabel hplabel[NHP];
54 int hpslave(), hpattach();
55
56 char hptypes[]={
57 0x22,0
58 };
59
60 struct mba_driver hpdriver={
61 hpslave, 0, "hp", hptypes, hpattach, hpinfo
62 };
63
64 hpslave(){
65 printf("Hpslave.\n");
66 asm("halt");
67 };
68
69 hpopen(){
70 printf("hpopen");
71 asm("halt");
72 };
73
74 hpclose(){
75 printf("hpclose\n");
76 asm("halt");
77 };
78
79 hpioctl(){
80 printf("hpioctl\n");
81 asm("halt");
82 }
83
84 hpdump(){
85 printf("hpdump\n");
86 asm("halt");
87 };
88
89 hpsize(){
90 printf("hpsize");
91 asm("halt");
92 };
93
94
95
96 hpattach(mi)
97 struct mba_device *mi;
98 {
99 struct mba_drv *md;
100
101 /*
102 * We check status of the drive first; to see if there is any idea
103 * to try to read the label.
104 */
105 md=&(mi->mi_mba->mba_drv[mi->drive]);
106 if(!md->rmcs1&HPCS1_DVA){
107 printf(": Drive not available");
108 return;
109 }
110 if(!md->rmds&HPDS_MOL){
111 printf(": Drive offline");
112 return;
113 }
114 if (hpinit(mi, 0))
115 printf(": offline");
116 /* else if (ra_info[unit].ra_state == OPEN) {
117 printf(": %s, size = %d sectors",
118 udalabel[unit].d_typename, ra_info[unit].ra_dsize);
119 */
120 printf("rmcs1: %x, rmds: %x, rmdt: %x rmsn: %x\n",
121 md->rmcs1, md->rmds, md->rmdt, md->rmsn);
122
123
124 /* asm("halt"); */
125 /*
126 if (MSCP_MID_ECH(1, ra_info[unit].ra_mediaid) == 'X' - '@') {
127 printf(": floppy");
128 return;
129 }
130 if (ui->ui_dk >= 0)
131 dk_wpms[ui->ui_dk] = (60 * 31 * 256);
132 udaip[ui->ui_ctlr][ui->ui_slave] = ui;
133
134 if (uda_rainit(ui, 0))
135 printf(": offline");
136 else if (ra_info[unit].ra_state == OPEN) {
137 printf(": %s, size = %d sectors",
138 udalabel[unit].d_typename, ra_info[unit].ra_dsize);
139 }*/
140 }
141
142
143 /*
144 * Initialise a drive. If it is not already, bring it on line,
145 * and set a timeout on it in case it fails to respond.
146 * When on line, read in the pack label.
147 */
148 hpinit(mi, flags)
149 struct mba_device *mi;
150 {
151 /* struct uda_softc *sc = &uda_softc[ui->ui_ctlr]; */
152 struct disklabel *lp;
153 struct hp_info *hp;
154 /* struct mscp *mp; */
155 int unit = mi->unit;
156 char *msg, *readdisklabel();
157 int s, i, hpstrategy();
158 extern int cold;
159
160 hp = &hp_info[unit];
161 /*
162 if ((ui->ui_flags & UNIT_ONLINE) == 0) {
163 mp = mscp_getcp(&sc->sc_mi, MSCP_WAIT);
164 mp->mscp_opcode = M_OP_ONLINE;
165 mp->mscp_unit = ui->ui_slave;
166 mp->mscp_cmdref = (long)&ui->ui_flags;
167 *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
168 ra->ra_state = WANTOPEN;
169 if (!cold)
170 s = spl5();
171 i = ((struct udadevice *)ui->ui_addr)->udaip;
172
173 if (cold) {
174 i = todr() + 1000;
175 while ((ui->ui_flags & UNIT_ONLINE) == 0)
176 if (todr() > i)
177 break;
178 } else {
179 timeout(wakeup, (caddr_t)&ui->ui_flags, 10 * hz);
180 sleep((caddr_t)&ui->ui_flags, PSWP + 1);
181 splx(s);
182 untimeout(wakeup, (caddr_t)&ui->ui_flags);
183 }
184 if (ra->ra_state != OPENRAW) {
185 ra->ra_state = CLOSED;
186 wakeup((caddr_t)ra);
187 return (EIO);
188 }
189 }
190 */
191 lp = &hplabel[unit];
192 lp->d_secsize = DEV_BSIZE;
193
194 lp->d_secsize = DEV_BSIZE;
195 lp->d_secperunit = 15 /*ra->ra_dsize*/;
196
197 if (flags & O_NDELAY)
198 return (0);
199 hp->hp_state = RDLABEL;
200 /*
201 * Set up default sizes until we have the label, or longer
202 * if there is none. Set secpercyl, as readdisklabel wants
203 * to compute b_cylin (although we do not need it), and set
204 * nsectors in case diskerr is called.
205 */
206 lp->d_secpercyl = 1;
207 lp->d_npartitions = 1;
208 lp->d_secsize = 512;
209 /* lp->d_secperunit = ra->ra_dsize; */
210 lp->d_nsectors = 15 /*ra->ra_geom.rg_nsectors*/;
211 lp->d_partitions[0].p_size = lp->d_secperunit;
212 lp->d_partitions[0].p_offset = 0;
213
214 /*
215 * Read pack label.
216 */
217 if ((msg = readdisklabel(hpminor(unit, 0), hpstrategy, lp)) != NULL) {
218 if (cold)
219 printf(": %s", msg);
220 else
221 log(LOG_ERR, "hp%d: %s", unit, msg);
222 /* ra->ra_state = OPENRAW; */
223 /* uda_makefakelabel(ra, lp); */
224 } else
225 /* ra->ra_state = OPEN; */
226 /* wakeup((caddr_t)hp); */
227 return (0);
228 }
229
230 /*
231 * Queue a transfer request, and if possible, hand it to the controller.
232 *
233 * This routine is broken into two so that the internal version
234 * udastrat1() can be called by the (nonexistent, as yet) bad block
235 * revectoring routine.
236 */
237 hpstrategy(bp)
238 register struct buf *bp;
239 {
240 register int unit;
241 register struct uba_device *ui;
242 register struct hp_info *hp;
243 struct partition *pp;
244 int p;
245 daddr_t sz, maxsz;
246
247 /*
248 * Make sure this is a reasonable drive to use.
249 */
250 /* bp->b_error = ENXIO;
251 goto bad;
252 */
253 unit = hpunit(bp->b_dev);
254
255 /*
256 * If drive is open `raw' or reading label, let it at it.
257 */
258
259 if (hp->hp_state < OPEN) {
260 hpstrat1(bp);
261 return;
262 }
263
264
265 /* if ((unit = udaunit(bp->b_dev)) >= NRA ||
266 (ui = udadinfo[unit]) == NULL || ui->ui_alive == 0 ||
267 (ra = &ra_info[unit])->ra_state == CLOSED) {
268 bp->b_error = ENXIO;
269 goto bad;
270 }
271 */
272 /*
273 * If drive is open `raw' or reading label, let it at it.
274 */
275 /*
276 if (ra->ra_state < OPEN) {
277 udastrat1(bp);
278 return;
279 }
280 p = udapart(bp->b_dev);
281 if ((ra->ra_openpart & (1 << p)) == 0) {
282 bp->b_error = ENODEV;
283 goto bad;
284 }
285 */
286 /*
287 * Determine the size of the transfer, and make sure it is
288 * within the boundaries of the partition.
289 */
290 /*
291 pp = &udalabel[unit].d_partitions[p];
292 maxsz = pp->p_size;
293 if (pp->p_offset + pp->p_size > ra->ra_dsize)
294 maxsz = ra->ra_dsize - pp->p_offset;
295 sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
296 if (bp->b_blkno + pp->p_offset <= LABELSECTOR &&
297 #if LABELSECTOR != 0
298 bp->b_blkno + pp->p_offset + sz > LABELSECTOR &&
299 #endif
300 (bp->b_flags & B_READ) == 0 && ra->ra_wlabel == 0) {
301 bp->b_error = EROFS;
302 goto bad;
303 }
304 if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
305 /* if exactly at end of disk, return an EOF */
306 /*
307 if (bp->b_blkno == maxsz) {
308 bp->b_resid = bp->b_bcount;
309 biodone(bp);
310 return;
311 }
312 /* or truncate if part of it fits */
313 /*
314 sz = maxsz - bp->b_blkno;
315 if (sz <= 0) {
316 bp->b_error = EINVAL; /* or hang it up */
317 /*
318 goto bad;
319 }
320 bp->b_bcount = sz << DEV_BSHIFT;
321 }
322 udastrat1(bp);
323 return;
324 */
325 bad:
326 bp->b_flags |= B_ERROR;
327 biodone(bp);
328 }
329
330 /*
331 * Work routine for udastrategy.
332 */
333 hpstrat1(bp)
334 register struct buf *bp;
335 {
336 register int unit = hpunit(bp->b_dev);
337 register struct hp_ctlr *um;
338 register struct buf *dp;
339 struct hp_device *ui;
340 /* int s = spl5(); */
341
342 asm("halt");
343 /*
344 * Append the buffer to the drive queue, and if it is not
345 * already there, the drive to the controller queue. (However,
346 * if the drive queue is marked to be requeued, we must be
347 * awaiting an on line or get unit status command; in this
348 * case, leave it off the controller queue.)
349 */
350 /*
351 um = (ui = udadinfo[unit])->ui_mi;
352 dp = &udautab[unit];
353 APPEND(bp, dp, av_forw);
354 if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) {
355 APPEND(dp, &um->um_tab, b_forw);
356 dp->b_active++;
357 }
358
359 /*
360 * Start activity on the controller. Note that unlike other
361 * Unibus drivers, we must always do this, not just when the
362 * controller is not active.
363 */
364 /*
365 udastart(um);
366 splx(s);
367 */
368 }
369