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