1 /*
2 * Copyright (c) 1982, 1986 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
6 * @(#)rl.c 7.10 (Berkeley) 12/16/90
7 */
8
9 #include "rl.h"
10 #if NRL > 0
11 /*
12 * UNIBUS RL02 disk driver
13 */
14 #include "../include/pte.h"
15
16 #include "sys/param.h"
17 #include "sys/systm.h"
18 #include "sys/dkstat.h"
19 #include "sys/dkbad.h"
20 #include "sys/ioctl.h"
21 #include "sys/disklabel.h"
22 #include "sys/buf.h"
23 #include "sys/conf.h"
24 #include "sys/user.h"
25 #include "sys/map.h"
26 #include "sys/vm.h"
27 #include "sys/cmap.h"
28 #include "sys/uio.h"
29 #include "sys/kernel.h"
30 #include "sys/syslog.h"
31
32 #include "../include/cpu.h"
33 #include "../vax/nexus.h"
34 #include "ubavar.h"
35 #include "ubareg.h"
36 #include "rlreg.h"
37
38 /* Pending Controller items and statistics */
39 struct rl_softc {
40 int rl_softas; /* Attention sumary, (seeks pending) */
41 int rl_ndrive; /* Number of drives on controller */
42 int rl_wticks; /* Monitor time for function */
43 } rl_softc[NHL];
44
45 /*
46 * State of controller from last transfer.
47 * Since only one transfer can be done at a time per
48 * controller, only allocate one for each controller.
49 */
50 struct rl_stat {
51 short rl_cyl[4]; /* Current cylinder for each drive */
52 short rl_dn; /* drive number currently transferring */
53 short rl_cylnhd; /* current cylinder and head of transfer */
54 u_short rl_bleft; /* bytes left to transfer */
55 u_short rl_bpart; /* bytes transferred */
56 } rl_stat[NHL];
57
58 #define rlunit(dev) (minor(dev) >> 3)
59
60 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
61 /* Last cylinder not used. Saved for Bad Sector File */
62 struct size {
63 daddr_t nblocks;
64 int cyloff;
65 } rl02_sizes[8] = {
66 15884, 0, /* A=cyl 0 thru 397 */
67 4520, 398, /* B=cyl 398 thru 510 */
68 -1, 0, /* C=cyl 0 thru 511 */
69 4520, 398, /* D=cyl 398 thru 510 */
70 0, 0, /* E= Not Defined */
71 0, 0, /* F= Not Defined */
72 20440, 0, /* G=cyl 0 thru 510 */
73 0, 0, /* H= Not Defined */
74 };
75 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
76
77 int rlprobe(), rlslave(), rlattach(), rldgo(), rlintr();
78 struct uba_ctlr *rlminfo[NHL];
79 struct uba_device *rldinfo[NRL];
80 struct uba_device *rlip[NHL][4];
81
82 /* RL02 driver structure */
83 u_short rlstd[] = { 0174400, 0 };
84 struct uba_driver hldriver =
85 { rlprobe, rlslave, rlattach, rldgo, rlstd, "rl", rldinfo, "hl", rlminfo };
86
87 /* User table per controller */
88 struct buf rlutab[NRL];
89
90 /* RL02 drive structure */
91 struct RL02 {
92 short nbpt; /* Number of 512 byte blocks/track */
93 short ntrak;
94 short nbpc; /* Number of 512 byte blocks/cylinder */
95 short ncyl;
96 short btrak; /* Number of bytes/track */
97 struct size *sizes;
98 } rl02 = {
99 20, 2, 40, 512, 20*512, rl02_sizes /* rl02/DEC*/
100 };
101
102 #define b_cylin b_resid /* Last seek as CYL<<1 | HD */
103
104 int rlwstart, rlwatch(); /* Have started guardian */
105
106 /* Check that controller exists */
107 /*ARGSUSED*/
rlprobe(reg)108 rlprobe(reg)
109 caddr_t reg;
110 {
111 register int br, cvec;
112
113 #ifdef lint
114 br = 0; cvec = br; br = cvec;
115 rlintr(0);
116 #endif
117 ((struct rldevice *)reg)->rlcs = RL_IE | RL_NOOP;
118 DELAY(10);
119 ((struct rldevice *)reg)->rlcs &= ~RL_IE;
120 return (sizeof (struct rldevice));
121 }
122
123 rlslave(ui, reg)
124 struct uba_device *ui;
125 caddr_t reg;
126 {
127 register struct rldevice *rladdr = (struct rldevice *)reg;
128 short ctr = 0;
129
130 /*
131 * DEC reports that:
132 * For some unknown reason the RL02 (seems to be only drive 1)
133 * does not return a valid drive status the first time that a
134 * GET STATUS request is issued for the drive, in fact it can
135 * take up to three or more GET STATUS requests to obtain the
136 * correct status.
137 * In order to overcome this, the driver has been modified to
138 * issue a GET STATUS request and validate the drive status
139 * returned. If a valid status is not returned after eight
140 * attempts, then an error message is printed.
141 */
142 do {
143 rladdr->rlda.getstat = RL_RESET;
144 rladdr->rlcs = (ui->ui_slave <<8) | RL_GETSTAT; /* Get status*/
145 rlwait(rladdr);
146 } while ((rladdr->rlcs & (RL_CRDY|RL_ERR)) != RL_CRDY && ++ctr < 8);
147
148 if ((rladdr->rlcs & RL_DE) || (ctr >= 8))
149 return (0);
150 if ((rladdr->rlmp.getstat & RLMP_DT) == 0 ) {
151 printf("rl%d: rl01's not supported\n", ui->ui_slave);
152 return(0);
153 }
154 return (1);
155 }
156
rlattach(ui)157 rlattach(ui)
158 register struct uba_device *ui;
159 {
160 register struct rldevice *rladdr;
161
162 if (rlwstart == 0) {
163 timeout(rlwatch, (caddr_t)0, hz);
164 rlwstart++;
165 }
166 /* Initialize iostat values */
167 if (ui->ui_dk >= 0)
168 dk_wpms[ui->ui_dk] = 256016; /* 16bit transfer time? */
169 rlip[ui->ui_ctlr][ui->ui_slave] = ui;
170 rl_softc[ui->ui_ctlr].rl_ndrive++;
171 rladdr = (struct rldevice *)ui->ui_addr;
172 /* reset controller */
173 rladdr->rlda.getstat = RL_RESET; /* SHOULD BE REPEATED? */
174 rladdr->rlcs = (ui->ui_slave << 8) | RL_GETSTAT; /* Reset DE bit */
175 rlwait(rladdr);
176 /* determine disk posistion */
177 rladdr->rlcs = (ui->ui_slave << 8) | RL_RHDR;
178 rlwait(rladdr);
179 /* save disk drive posistion */
180 rl_stat[ui->ui_ctlr].rl_cyl[ui->ui_slave] =
181 (rladdr->rlmp.readhdr & 0177700) >> 6;
182 rl_stat[ui->ui_ctlr].rl_dn = -1;
183 }
184
rlopen(dev)185 rlopen(dev)
186 dev_t dev;
187 {
188 register int unit = rlunit(dev);
189 register struct uba_device *ui;
190
191 if (unit >= NRL || (ui = rldinfo[unit]) == 0 || ui->ui_alive == 0)
192 return (ENXIO);
193 return (0);
194 }
195
rlstrategy(bp)196 rlstrategy(bp)
197 register struct buf *bp;
198 {
199 register struct uba_device *ui;
200 register int drive;
201 register struct buf *dp;
202 int partition = minor(bp->b_dev) & 07, s;
203 long bn, sz;
204
205 sz = (bp->b_bcount+511) >> 9;
206 drive = rlunit(bp->b_dev);
207 if (drive >= NRL) {
208 bp->b_error = ENXIO;
209 goto bad;
210 }
211 ui = rldinfo[drive];
212 if (ui == 0 || ui->ui_alive == 0) {
213 bp->b_error = ENXIO;
214 goto bad;
215 }
216 if (bp->b_blkno < 0 ||
217 (bn = bp->b_blkno)+sz > rl02.sizes[partition].nblocks) {
218 if (bp->b_blkno == rl02.sizes[partition].nblocks) {
219 bp->b_resid = bp->b_bcount;
220 goto done;
221 }
222 bp->b_error = EINVAL;
223 goto bad;
224 }
225 /* bn is in 512 byte block size */
226 bp->b_cylin = bn/rl02.nbpc + rl02.sizes[partition].cyloff;
227 s = spl5();
228 dp = &rlutab[ui->ui_unit];
229 disksort(dp, bp);
230 if (dp->b_active == 0) {
231 rlustart(ui);
232 bp = &ui->ui_mi->um_tab;
233 if (bp->b_actf && bp->b_active == 0)
234 rlstart(ui->ui_mi);
235 }
236 splx(s);
237 return;
238
239 bad:
240 bp->b_flags |= B_ERROR;
241 done:
242 iodone(bp);
243 return;
244 }
245
246 /*
247 * Unit start routine.
248 * Seek the drive to be where the data is
249 * and then generate another interrupt
250 * to actually start the transfer.
251 */
rlustart(ui)252 rlustart(ui)
253 register struct uba_device *ui;
254 {
255 register struct buf *bp, *dp;
256 register struct uba_ctlr *um;
257 register struct rldevice *rladdr;
258 daddr_t bn;
259 short hd, diff;
260
261 if (ui == 0)
262 return;
263 um = ui->ui_mi;
264 dk_busy &= ~(1 << ui->ui_dk);
265 dp = &rlutab[ui->ui_unit];
266 if ((bp = dp->b_actf) == NULL)
267 return;
268 /*
269 * If the controller is active, just remember
270 * that this device has to be positioned...
271 */
272 if (um->um_tab.b_active) {
273 rl_softc[um->um_ctlr].rl_softas |= 1<<ui->ui_slave;
274 return;
275 }
276 /*
277 * If we have already positioned this drive,
278 * then just put it on the ready queue.
279 */
280 if (dp->b_active)
281 goto done;
282 dp->b_active = 1; /* positioning drive */
283 rladdr = (struct rldevice *)um->um_addr;
284
285 /*
286 * Figure out where this transfer is going to
287 * and see if we are seeked correctly.
288 */
289 bn = bp->b_blkno; /* Block # desired */
290 /*
291 * Map 512 byte logical disk blocks
292 * to 256 byte sectors (rl02's are stupid).
293 */
294 hd = (bn / rl02.nbpt) & 1; /* Get head required */
295 diff = (rl_stat[um->um_ctlr].rl_cyl[ui->ui_slave] >> 1) - bp->b_cylin;
296 if ( diff == 0 && (rl_stat[um->um_ctlr].rl_cyl[ui->ui_slave] & 1) == hd)
297 goto done; /* on cylinder and head */
298 /*
299 * Not at correct position.
300 */
301 rl_stat[um->um_ctlr].rl_cyl[ui->ui_slave] = (bp->b_cylin << 1) | hd;
302 if (diff < 0)
303 rladdr->rlda.seek = -diff << 7 | RLDA_HGH | hd << 4;
304 else
305 rladdr->rlda.seek = diff << 7 | RLDA_LOW | hd << 4;
306 rladdr->rlcs = (ui->ui_slave << 8) | RL_SEEK;
307
308 /*
309 * Mark unit busy for iostat.
310 */
311 if (ui->ui_dk >= 0) {
312 dk_busy |= 1<<ui->ui_dk;
313 dk_seek[ui->ui_dk]++;
314 }
315 rlwait(rladdr);
316 done:
317 /*
318 * Device is ready to go.
319 * Put it on the ready queue for the controller
320 * (unless its already there.)
321 */
322 if (dp->b_active != 2) {
323 dp->b_forw = NULL;
324 if (um->um_tab.b_actf == NULL)
325 um->um_tab.b_actf = dp;
326 else
327 um->um_tab.b_actl->b_forw = dp;
328 um->um_tab.b_actl = dp;
329 dp->b_active = 2; /* Request on ready queue */
330 }
331 }
332
333 /*
334 * Start up a transfer on a drive.
335 */
rlstart(um)336 rlstart(um)
337 register struct uba_ctlr *um;
338 {
339 register struct buf *bp, *dp;
340 register struct uba_device *ui;
341 register struct rldevice *rladdr;
342 register struct rl_stat *st = &rl_stat[um->um_ctlr];
343 daddr_t bn;
344 short sn, cyl, cmd;
345
346 loop:
347 if ((dp = um->um_tab.b_actf) == NULL) {
348 st->rl_dn = -1;
349 st->rl_cylnhd = 0;
350 st->rl_bleft = 0;
351 st->rl_bpart = 0;
352 return;
353 }
354 if ((bp = dp->b_actf) == NULL) {
355 um->um_tab.b_actf = dp->b_forw;
356 goto loop;
357 }
358 /*
359 * Mark controller busy, and
360 * determine destination.
361 */
362 um->um_tab.b_active++;
363 ui = rldinfo[rlunit(bp->b_dev)]; /* Controller */
364 bn = bp->b_blkno; /* 512 byte Block number */
365 cyl = bp->b_cylin << 1; /* Cylinder */
366 cyl |= (bn / rl02.nbpt) & 1; /* Get head required */
367 sn = (bn % rl02.nbpt) << 1; /* Sector number */
368 rladdr = (struct rldevice *)ui->ui_addr;
369 rlwait(rladdr);
370 rladdr->rlda.rw = cyl<<6 | sn;
371 /* save away current transfers drive status */
372 st->rl_dn = ui->ui_slave;
373 st->rl_cylnhd = cyl;
374 st->rl_bleft = bp->b_bcount;
375 st->rl_bpart = rl02.btrak - (sn * NRLBPSC);
376 /*
377 * RL02 must seek between cylinders and between tracks,
378 * determine maximum data transfer at this time.
379 */
380 if (st->rl_bleft < st->rl_bpart)
381 st->rl_bpart = st->rl_bleft;
382 rladdr->rlmp.rw = -(st->rl_bpart >> 1);
383 if (bp->b_flags & B_READ)
384 cmd = RL_IE | RL_READ | (ui->ui_slave << 8);
385 else
386 cmd = RL_IE | RL_WRITE | (ui->ui_slave << 8);
387 um->um_cmd = cmd;
388 (void) ubago(ui);
389 }
390
rldgo(um)391 rldgo(um)
392 register struct uba_ctlr *um;
393 {
394 register struct rldevice *rladdr = (struct rldevice *)um->um_addr;
395
396 rladdr->rlba = um->um_ubinfo;
397 rladdr->rlcs = um->um_cmd|((um->um_ubinfo>>12)&RL_BAE);
398 }
399
400 /*
401 * Handle a disk interrupt.
402 */
rlintr(rl21)403 rlintr(rl21)
404 register rl21;
405 {
406 register struct buf *bp, *dp;
407 register struct uba_ctlr *um = rlminfo[rl21];
408 register struct uba_device *ui;
409 register struct rldevice *rladdr = (struct rldevice *)um->um_addr;
410 register unit;
411 struct rl_softc *rl = &rl_softc[um->um_ctlr];
412 struct rl_stat *st = &rl_stat[um->um_ctlr];
413 int as = rl->rl_softas, status;
414
415 rl->rl_wticks = 0;
416 rl->rl_softas = 0;
417 dp = um->um_tab.b_actf;
418 bp = dp->b_actf;
419 ui = rldinfo[rlunit(bp->b_dev)];
420 dk_busy &= ~(1 << ui->ui_dk);
421
422 /*
423 * Check for and process errors on
424 * either the drive or the controller.
425 */
426 if (rladdr->rlcs & RL_ERR) {
427 u_short err;
428 rlwait(rladdr);
429 err = rladdr->rlcs;
430 /* get staus and reset controller */
431 rladdr->rlda.getstat = RL_GSTAT;
432 rladdr->rlcs = (ui->ui_slave << 8) | RL_GETSTAT;
433 rlwait(rladdr);
434 status = rladdr->rlmp.getstat;
435 /* reset drive */
436 rladdr->rlda.getstat = RL_RESET;
437 rladdr->rlcs = (ui->ui_slave <<8) | RL_GETSTAT; /* Get status*/
438 rlwait(rladdr);
439 if ((status & RLMP_WL) == RLMP_WL) {
440 /*
441 * Give up on write protected devices
442 * immediately.
443 */
444 printf("rl%d: write protected\n", rlunit(bp->b_dev));
445 bp->b_flags |= B_ERROR;
446 } else if (++um->um_tab.b_errcnt > 10) {
447 /*
448 * After 10 retries give up.
449 */
450 diskerr(bp, "rl", "hard error", LOG_PRINTF, -1,
451 (struct disklabel *)0);
452 printf(" cs=%b mp=%b\n", err, RLCS_BITS,
453 status, RLER_BITS);
454 bp->b_flags |= B_ERROR;
455 } else
456 um->um_tab.b_active = 0; /* force retry */
457 /* determine disk position */
458 rladdr->rlcs = (ui->ui_slave << 8) | RL_RHDR;
459 rlwait(rladdr);
460 /* save disk drive position */
461 st->rl_cyl[ui->ui_slave] =
462 (rladdr->rlmp.readhdr & 0177700) >> 6;
463 }
464 /*
465 * If still ``active'', then don't need any more retries.
466 */
467 if (um->um_tab.b_active) {
468 /* RL02 check if more data from previous request */
469 if ((bp->b_flags & B_ERROR) == 0 &&
470 (int)(st->rl_bleft -= st->rl_bpart) > 0) {
471 /*
472 * The following code was modeled from the rk07
473 * driver when an ECC error occured. It has to
474 * fix the bits then restart the transfer which is
475 * what we have to do (restart transfer).
476 */
477 int reg, npf, o, cmd, ubaddr, diff, head;
478
479 /* seek to next head/track */
480 /* increment head and/or cylinder */
481 st->rl_cylnhd++;
482 diff = (st->rl_cyl[ui->ui_slave] >> 1) -
483 (st->rl_cylnhd >> 1);
484 st->rl_cyl[ui->ui_slave] = st->rl_cylnhd;
485 head = st->rl_cylnhd & 1;
486 rlwait(rladdr);
487 if (diff < 0)
488 rladdr->rlda.seek =
489 -diff << 7 | RLDA_HGH | head << 4;
490 else
491 rladdr->rlda.seek =
492 diff << 7 | RLDA_LOW | head << 4;
493 rladdr->rlcs = (ui->ui_slave << 8) | RL_SEEK;
494 npf = btop( bp->b_bcount - st->rl_bleft );
495 reg = btop(UBAI_ADDR(um->um_ubinfo)) + npf;
496 o = (int)bp->b_un.b_addr & PGOFSET;
497 ubapurge(um);
498 um->um_tab.b_active++;
499 rlwait(rladdr);
500 rladdr->rlda.rw = st->rl_cylnhd << 6;
501 if (st->rl_bleft < (st->rl_bpart = rl02.btrak))
502 st->rl_bpart = st->rl_bleft;
503 rladdr->rlmp.rw = -(st->rl_bpart >> 1);
504 cmd = (bp->b_flags&B_READ ? RL_READ : RL_WRITE) |
505 RL_IE | (ui->ui_slave << 8);
506 ubaddr = (int)ptob(reg) + o;
507 cmd |= ((ubaddr >> 12) & RL_BAE);
508 rladdr->rlba = ubaddr;
509 rladdr->rlcs = cmd;
510 return;
511 }
512 um->um_tab.b_active = 0;
513 um->um_tab.b_errcnt = 0;
514 dp->b_active = 0;
515 dp->b_errcnt = 0;
516 /* "b_resid" words remaining after error */
517 bp->b_resid = st->rl_bleft;
518 um->um_tab.b_actf = dp->b_forw;
519 dp->b_actf = bp->av_forw;
520 st->rl_dn = -1;
521 st->rl_bpart = st->rl_bleft = 0;
522 iodone(bp);
523 /*
524 * If this unit has more work to do,
525 * then start it up right away.
526 */
527 if (dp->b_actf)
528 rlustart(ui);
529 as &= ~(1<<ui->ui_slave);
530 } else
531 as |= (1<<ui->ui_slave);
532 ubadone(um);
533 /* reset state info */
534 st->rl_dn = -1;
535 st->rl_cylnhd = st->rl_bpart = st->rl_bleft = 0;
536 /*
537 * Process other units which need attention.
538 * For each unit which needs attention, call
539 * the unit start routine to place the slave
540 * on the controller device queue.
541 */
542 while (unit = ffs((long)as)) {
543 unit--; /* was 1 origin */
544 as &= ~(1<<unit);
545 rlustart(rlip[rl21][unit]);
546 }
547 /*
548 * If the controller is not transferring, but
549 * there are devices ready to transfer, start
550 * the controller.
551 */
552 if (um->um_tab.b_actf && um->um_tab.b_active == 0)
553 rlstart(um);
554 }
555
rlwait(rladdr)556 rlwait(rladdr)
557 register struct rldevice *rladdr;
558 {
559
560 while ((rladdr->rlcs & RL_CRDY) == 0)
561 ;
562 }
563
564 /*
565 * Reset driver after UBA init.
566 * Cancel software state of all pending transfers
567 * and restart all units and the controller.
568 */
rlreset(uban)569 rlreset(uban)
570 int uban;
571 {
572 register struct uba_ctlr *um;
573 register struct uba_device *ui;
574 register struct rldevice *rladdr;
575 register struct rl_stat *st;
576 register int rl21, unit;
577
578 for (rl21 = 0; rl21 < NHL; rl21++) {
579 if ((um = rlminfo[rl21]) == 0 || um->um_ubanum != uban ||
580 um->um_alive == 0)
581 continue;
582 printf(" hl%d", rl21);
583 rladdr = (struct rldevice *)um->um_addr;
584 st = &rl_stat[rl21];
585 um->um_tab.b_active = 0;
586 um->um_tab.b_actf = um->um_tab.b_actl = 0;
587 if (um->um_ubinfo) {
588 printf("<%d>", (um->um_ubinfo>>28)&0xf);
589 um->um_ubinfo = 0;
590 }
591 /* reset controller */
592 st->rl_dn = -1;
593 st->rl_cylnhd = 0;
594 st->rl_bleft = 0;
595 st->rl_bpart = 0;
596 rlwait(rladdr);
597 for (unit = 0; unit < NRL; unit++) {
598 rladdr->rlcs = (unit << 8) | RL_GETSTAT;
599 rlwait(rladdr);
600 /* Determine disk posistion */
601 rladdr->rlcs = (unit << 8) | RL_RHDR;
602 rlwait(rladdr);
603 /* save disk drive posistion */
604 st->rl_cyl[unit] =
605 (rladdr->rlmp.readhdr & 0177700) >> 6;
606 if ((ui = rldinfo[unit]) == 0)
607 continue;
608 if (ui->ui_alive == 0 || ui->ui_mi != um)
609 continue;
610 rlutab[unit].b_active = 0;
611 rlustart(ui);
612 }
613 rlstart(um);
614 }
615 }
616
617 /*
618 * Wake up every second and if an interrupt is pending
619 * but nothing has happened increment a counter.
620 * If nothing happens for 20 seconds, reset the UNIBUS
621 * and begin anew.
622 */
rlwatch()623 rlwatch()
624 {
625 register struct uba_ctlr *um;
626 register rl21, unit;
627 register struct rl_softc *rl;
628
629 timeout(rlwatch, (caddr_t)0, hz);
630 for (rl21 = 0; rl21 < NHL; rl21++) {
631 um = rlminfo[rl21];
632 if (um == 0 || um->um_alive == 0)
633 continue;
634 rl = &rl_softc[rl21];
635 if (um->um_tab.b_active == 0) {
636 for (unit = 0; unit < NRL; unit++)
637 if (rlutab[unit].b_active &&
638 rldinfo[unit]->ui_mi == um)
639 goto active;
640 rl->rl_wticks = 0;
641 continue;
642 }
643 active:
644 rl->rl_wticks++;
645 if (rl->rl_wticks >= 20) {
646 rl->rl_wticks = 0;
647 printf("hl%d: lost interrupt\n", rl21);
648 ubareset(um->um_ubanum);
649 }
650 }
651 }
652
653 /*ARGSUSED*/
rldump(dev)654 rldump(dev)
655 dev_t dev;
656 {
657
658 /* don't think there is room on swap for it anyway. */
659 }
660
rlsize(dev)661 rlsize(dev)
662 dev_t dev;
663 {
664 register int unit = rlunit(dev);
665 register struct uba_device *ui;
666
667 if (unit >= NRL || (ui = rldinfo[unit]) == 0 || ui->ui_alive == 0)
668 return (-1);
669 return (rl02.sizes[minor(dev) & 07].nblocks);
670 }
671 #endif
672