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