hp.c revision 1.1 1 /* $NetBSD: hp.c,v 1.1 1995/02/13 00:43:59 ragge 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 "param.h"
39 #include "types.h"
40 #include "fcntl.h"
41 #include "syslog.h"
42 #include "disklabel.h"
43 #include "buf.h"
44 #include "vax/mba/mbareg.h"
45 #include "vax/mba/mbavar.h"
46 #include "vax/mba/hpdefs.h"
47 #include "hp.h"
48
49 struct mba_device *hpinfo[NHP];
50 struct hp_info hp_info[NHP];
51 struct disklabel hplabel[NHP];
52 int hpslave(), hpattach();
53
54 char hptypes[]={
55 0x22,0
56 };
57
58 struct mba_driver hpdriver={
59 hpslave, 0, "hp", hptypes, hpattach, hpinfo
60 };
61
62 hpslave(){
63 printf("Hpslave.\n");
64 asm("halt");
65 };
66
67 hpopen(){
68 printf("hpopen");
69 asm("halt");
70 };
71
72 hpclose(){
73 printf("hpclose\n");
74 asm("halt");
75 };
76
77 hpioctl(){
78 printf("hpioctl\n");
79 asm("halt");
80 }
81
82 hpdump(){
83 printf("hpdump\n");
84 asm("halt");
85 };
86
87 hpsize(){
88 printf("hpsize");
89 asm("halt");
90 };
91
92
93
94 hpattach(mi)
95 struct mba_device *mi;
96 {
97 struct mba_drv *md;
98
99 /*
100 * We check status of the drive first; to see if there is any idea
101 * to try to read the label.
102 */
103 md=&(mi->mi_mba->mba_drv[mi->drive]);
104 if(!md->rmcs1&HPCS1_DVA){
105 printf(": Drive not available");
106 return;
107 }
108 if(!md->rmds&HPDS_MOL){
109 printf(": Drive offline");
110 return;
111 }
112 if (hpinit(mi, 0))
113 printf(": offline");
114 /* else if (ra_info[unit].ra_state == OPEN) {
115 printf(": %s, size = %d sectors",
116 udalabel[unit].d_typename, ra_info[unit].ra_dsize);
117 */
118 printf("rmcs1: %x, rmds: %x, rmdt: %x rmsn: %x\n",
119 md->rmcs1, md->rmds, md->rmdt, md->rmsn);
120
121
122 /* asm("halt"); */
123 /*
124 if (MSCP_MID_ECH(1, ra_info[unit].ra_mediaid) == 'X' - '@') {
125 printf(": floppy");
126 return;
127 }
128 if (ui->ui_dk >= 0)
129 dk_wpms[ui->ui_dk] = (60 * 31 * 256);
130 udaip[ui->ui_ctlr][ui->ui_slave] = ui;
131
132 if (uda_rainit(ui, 0))
133 printf(": offline");
134 else if (ra_info[unit].ra_state == OPEN) {
135 printf(": %s, size = %d sectors",
136 udalabel[unit].d_typename, ra_info[unit].ra_dsize);
137 }*/
138 }
139
140
141 /*
142 * Initialise a drive. If it is not already, bring it on line,
143 * and set a timeout on it in case it fails to respond.
144 * When on line, read in the pack label.
145 */
146 hpinit(mi, flags)
147 struct mba_device *mi;
148 {
149 /* struct uda_softc *sc = &uda_softc[ui->ui_ctlr]; */
150 struct disklabel *lp;
151 struct hp_info *hp;
152 /* struct mscp *mp; */
153 int unit = mi->unit;
154 char *msg, *readdisklabel();
155 int s, i, hpstrategy();
156 extern int cold;
157
158 hp = &hp_info[unit];
159 /*
160 if ((ui->ui_flags & UNIT_ONLINE) == 0) {
161 mp = mscp_getcp(&sc->sc_mi, MSCP_WAIT);
162 mp->mscp_opcode = M_OP_ONLINE;
163 mp->mscp_unit = ui->ui_slave;
164 mp->mscp_cmdref = (long)&ui->ui_flags;
165 *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
166 ra->ra_state = WANTOPEN;
167 if (!cold)
168 s = spl5();
169 i = ((struct udadevice *)ui->ui_addr)->udaip;
170
171 if (cold) {
172 i = todr() + 1000;
173 while ((ui->ui_flags & UNIT_ONLINE) == 0)
174 if (todr() > i)
175 break;
176 } else {
177 timeout(wakeup, (caddr_t)&ui->ui_flags, 10 * hz);
178 sleep((caddr_t)&ui->ui_flags, PSWP + 1);
179 splx(s);
180 untimeout(wakeup, (caddr_t)&ui->ui_flags);
181 }
182 if (ra->ra_state != OPENRAW) {
183 ra->ra_state = CLOSED;
184 wakeup((caddr_t)ra);
185 return (EIO);
186 }
187 }
188 */
189 lp = &hplabel[unit];
190 lp->d_secsize = DEV_BSIZE;
191
192 lp->d_secsize = DEV_BSIZE;
193 lp->d_secperunit = 15 /*ra->ra_dsize*/;
194
195 if (flags & O_NDELAY)
196 return (0);
197 hp->hp_state = RDLABEL;
198 /*
199 * Set up default sizes until we have the label, or longer
200 * if there is none. Set secpercyl, as readdisklabel wants
201 * to compute b_cylin (although we do not need it), and set
202 * nsectors in case diskerr is called.
203 */
204 lp->d_secpercyl = 1;
205 lp->d_npartitions = 1;
206 lp->d_secsize = 512;
207 /* lp->d_secperunit = ra->ra_dsize; */
208 lp->d_nsectors = 15 /*ra->ra_geom.rg_nsectors*/;
209 lp->d_partitions[0].p_size = lp->d_secperunit;
210 lp->d_partitions[0].p_offset = 0;
211
212 /*
213 * Read pack label.
214 */
215 if ((msg = readdisklabel(hpminor(unit, 0), hpstrategy, lp)) != NULL) {
216 if (cold)
217 printf(": %s", msg);
218 else
219 log(LOG_ERR, "hp%d: %s", unit, msg);
220 /* ra->ra_state = OPENRAW; */
221 /* uda_makefakelabel(ra, lp); */
222 } else
223 /* ra->ra_state = OPEN; */
224 /* wakeup((caddr_t)hp); */
225 return (0);
226 }
227
228 /*
229 * Queue a transfer request, and if possible, hand it to the controller.
230 *
231 * This routine is broken into two so that the internal version
232 * udastrat1() can be called by the (nonexistent, as yet) bad block
233 * revectoring routine.
234 */
235 hpstrategy(bp)
236 register struct buf *bp;
237 {
238 register int unit;
239 register struct uba_device *ui;
240 register struct hp_info *hp;
241 struct partition *pp;
242 int p;
243 daddr_t sz, maxsz;
244
245 /*
246 * Make sure this is a reasonable drive to use.
247 */
248 /* bp->b_error = ENXIO;
249 goto bad;
250 */
251 unit = hpunit(bp->b_dev);
252
253 /*
254 * If drive is open `raw' or reading label, let it at it.
255 */
256
257 if (hp->hp_state < OPEN) {
258 hpstrat1(bp);
259 return;
260 }
261
262
263 /* if ((unit = udaunit(bp->b_dev)) >= NRA ||
264 (ui = udadinfo[unit]) == NULL || ui->ui_alive == 0 ||
265 (ra = &ra_info[unit])->ra_state == CLOSED) {
266 bp->b_error = ENXIO;
267 goto bad;
268 }
269 */
270 /*
271 * If drive is open `raw' or reading label, let it at it.
272 */
273 /*
274 if (ra->ra_state < OPEN) {
275 udastrat1(bp);
276 return;
277 }
278 p = udapart(bp->b_dev);
279 if ((ra->ra_openpart & (1 << p)) == 0) {
280 bp->b_error = ENODEV;
281 goto bad;
282 }
283 */
284 /*
285 * Determine the size of the transfer, and make sure it is
286 * within the boundaries of the partition.
287 */
288 /*
289 pp = &udalabel[unit].d_partitions[p];
290 maxsz = pp->p_size;
291 if (pp->p_offset + pp->p_size > ra->ra_dsize)
292 maxsz = ra->ra_dsize - pp->p_offset;
293 sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
294 if (bp->b_blkno + pp->p_offset <= LABELSECTOR &&
295 #if LABELSECTOR != 0
296 bp->b_blkno + pp->p_offset + sz > LABELSECTOR &&
297 #endif
298 (bp->b_flags & B_READ) == 0 && ra->ra_wlabel == 0) {
299 bp->b_error = EROFS;
300 goto bad;
301 }
302 if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
303 /* if exactly at end of disk, return an EOF */
304 /*
305 if (bp->b_blkno == maxsz) {
306 bp->b_resid = bp->b_bcount;
307 biodone(bp);
308 return;
309 }
310 /* or truncate if part of it fits */
311 /*
312 sz = maxsz - bp->b_blkno;
313 if (sz <= 0) {
314 bp->b_error = EINVAL; /* or hang it up */
315 /*
316 goto bad;
317 }
318 bp->b_bcount = sz << DEV_BSHIFT;
319 }
320 udastrat1(bp);
321 return;
322 */
323 bad:
324 bp->b_flags |= B_ERROR;
325 biodone(bp);
326 }
327
328 /*
329 * Work routine for udastrategy.
330 */
331 hpstrat1(bp)
332 register struct buf *bp;
333 {
334 register int unit = hpunit(bp->b_dev);
335 register struct hp_ctlr *um;
336 register struct buf *dp;
337 struct hp_device *ui;
338 /* int s = spl5(); */
339
340 asm("halt");
341 /*
342 * Append the buffer to the drive queue, and if it is not
343 * already there, the drive to the controller queue. (However,
344 * if the drive queue is marked to be requeued, we must be
345 * awaiting an on line or get unit status command; in this
346 * case, leave it off the controller queue.)
347 */
348 /*
349 um = (ui = udadinfo[unit])->ui_mi;
350 dp = &udautab[unit];
351 APPEND(bp, dp, av_forw);
352 if (dp->b_active == 0 && (ui->ui_flags & UNIT_REQUEUE) == 0) {
353 APPEND(dp, &um->um_tab, b_forw);
354 dp->b_active++;
355 }
356
357 /*
358 * Start activity on the controller. Note that unlike other
359 * Unibus drivers, we must always do this, not just when the
360 * controller is not active.
361 */
362 /*
363 udastart(um);
364 splx(s);
365 */
366 }
367