xref: /netbsd-src/sys/arch/vax/mba/hp.c (revision ce0bb6e8d2e560ecacbe865a848624f94498063b)
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