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 * @(#)up.c 7.10 (Berkeley) 12/16/90
7 */
8
9 #include "up.h"
10 #if NSC > 0
11 /*
12 * UNIBUS disk driver with:
13 * overlapped seeks,
14 * ECC recovery, and
15 * bad sector forwarding.
16 *
17 * TODO:
18 * Check that offset recovery code works
19 */
20 #include "../include/pte.h"
21
22 #include "sys/param.h"
23 #include "sys/systm.h"
24 #include "sys/dkstat.h"
25 #include "sys/dkbad.h"
26 #include "sys/ioctl.h"
27 #include "sys/disklabel.h"
28 #include "sys/buf.h"
29 #include "sys/conf.h"
30 #include "sys/user.h"
31 #include "sys/map.h"
32 #include "sys/vm.h"
33 #include "sys/cmap.h"
34 #include "sys/uio.h"
35 #include "sys/kernel.h"
36 #include "sys/syslog.h"
37
38 #include "../include/cpu.h"
39 #include "../vax/nexus.h"
40 #include "ubavar.h"
41 #include "ubareg.h"
42 #include "upreg.h"
43
44 struct up_softc {
45 int sc_softas;
46 int sc_ndrive;
47 int sc_wticks;
48 int sc_recal;
49 } up_softc[NSC];
50
51 #define upunit(dev) (minor(dev) >> 3)
52
53 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
54 struct size {
55 daddr_t nblocks;
56 int cyloff;
57 } up9300_sizes[8] = {
58 15884, 0, /* A=cyl 0 thru 26 */
59 33440, 27, /* B=cyl 27 thru 81 */
60 495520, 0, /* C=cyl 0 thru 814 */
61 15884, 562, /* D=cyl 562 thru 588 */
62 55936, 589, /* E=cyl 589 thru 680 */
63 81376, 681, /* F=cyl 681 thru 814 */
64 153728, 562, /* G=cyl 562 thru 814 */
65 291346, 82, /* H=cyl 82 thru 561 */
66 }, up9766_sizes[8] = {
67 15884, 0, /* A=cyl 0 thru 26 */
68 33440, 27, /* B=cyl 27 thru 81 */
69 500384, 0, /* C=cyl 0 thru 822 */
70 15884, 562, /* D=cyl 562 thru 588 */
71 55936, 589, /* E=cyl 589 thru 680 */
72 86240, 681, /* F=cyl 681 thru 822 */
73 158592, 562, /* G=cyl 562 thru 822 */
74 291346, 82, /* H=cyl 82 thru 561 */
75 }, up160_sizes[8] = {
76 15884, 0, /* A=cyl 0 thru 49 */
77 33440, 50, /* B=cyl 50 thru 154 */
78 263360, 0, /* C=cyl 0 thru 822 */
79 15884, 155, /* D=cyl 155 thru 204 */
80 55936, 205, /* E=cyl 205 thru 379 */
81 141664, 380, /* F=cyl 380 thru 822 */
82 213664, 155, /* G=cyl 155 thru 822 */
83 0, 0,
84 }, upam_sizes[8] = {
85 15884, 0, /* A=cyl 0 thru 31 */
86 33440, 32, /* B=cyl 32 thru 97 */
87 524288, 0, /* C=cyl 0 thru 1023 */
88 15884, 668, /* D=cyl 668 thru 699 */
89 55936, 700, /* E=cyl 700 thru 809 */
90 109472, 810, /* F=cyl 810 thru 1023 */
91 182176, 668, /* G=cyl 668 thru 1023 */
92 291346, 98, /* H=cyl 98 thru 667 */
93 }, up980_sizes[8] = {
94 15884, 0, /* A=cyl 0 thru 99 */
95 33440, 100, /* B=cyl 100 thru 308 */
96 131680, 0, /* C=cyl 0 thru 822 */
97 15884, 309, /* D=cyl 309 thru 408 */
98 55936, 409, /* E=cyl 409 thru 758 */
99 10080, 759, /* F=cyl 759 thru 822 */
100 82080, 309, /* G=cyl 309 thru 822 */
101 0, 0,
102 }, upeagle_sizes[8] = {
103 15884, 0, /* A=cyl 0 thru 16 */
104 66880, 17, /* B=cyl 17 thru 86 */
105 808320, 0, /* C=cyl 0 thru 841 */
106 15884, 391, /* D=cyl 391 thru 407 */
107 307200, 408, /* E=cyl 408 thru 727 */
108 109296, 728, /* F=cyl 728 thru 841 */
109 432816, 391, /* G=cyl 391 thru 841 */
110 291346, 87, /* H=cyl 87 thru 390 */
111 };
112 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
113
114 int upprobe(), upslave(), upattach(), updgo(), upintr();
115 struct uba_ctlr *upminfo[NSC];
116 struct uba_device *updinfo[NUP];
117 #define UPIPUNITS 8
118 struct uba_device *upip[NSC][UPIPUNITS]; /* fuji w/fixed head gives n,n+4 */
119
120 u_short upstd[] = { 0776700, 0774400, 0776300, 0 };
121 struct uba_driver scdriver =
122 { upprobe, upslave, upattach, updgo, upstd, "up", updinfo, "sc", upminfo };
123 struct buf uputab[NUP];
124 char upinit[NUP];
125
126 struct upst {
127 short nsect; /* # sectors/track */
128 short ntrak; /* # tracks/cylinder */
129 short nspc; /* # sectors/cylinder */
130 short ncyl; /* # cylinders */
131 struct size *sizes; /* partition tables */
132 short sdist; /* seek distance metric */
133 short rdist; /* rotational distance metric */
134 } upst[] = {
135 { 32, 19, 32*19, 815, up9300_sizes, 3, 4 }, /* 9300 */
136 { 32, 19, 32*19, 823, up9766_sizes, 3, 4 }, /* 9766 */
137 { 32, 10, 32*10, 823, up160_sizes, 3, 4 }, /* fuji 160m */
138 { 32, 16, 32*16, 1024, upam_sizes, 7, 8 }, /* Capricorn */
139 { 32, 5, 32*5, 823, up980_sizes, 3, 4 }, /* DM980 */
140 { 48, 20, 48*20, 842, upeagle_sizes, 15, 8 }, /* EAGLE */
141 { 0, 0, 0, 0, 0, 0, 0 }
142 };
143
144 u_char up_offset[16] = {
145 UPOF_P400, UPOF_M400, UPOF_P400, UPOF_M400,
146 UPOF_P800, UPOF_M800, UPOF_P800, UPOF_M800,
147 UPOF_P1200, UPOF_M1200, UPOF_P1200, UPOF_M1200,
148 0, 0, 0, 0
149 };
150
151 struct buf bupbuf[NUP];
152 struct dkbad upbad[NUP];
153
154 #define b_cylin b_resid
155
156 int upwstart, upwatch(); /* Have started guardian */
157 int upseek;
158 int upwaitdry;
159
160 /*ARGSUSED*/
upprobe(reg)161 upprobe(reg)
162 caddr_t reg;
163 {
164 register int br, cvec;
165
166 #ifdef lint
167 br = 0; cvec = br; br = cvec; upintr(0);
168 #endif
169 ((struct updevice *)reg)->upcs1 = UP_IE|UP_RDY;
170 DELAY(10);
171 ((struct updevice *)reg)->upcs1 = 0;
172 return (sizeof (struct updevice));
173 }
174
175 upslave(ui, reg)
176 struct uba_device *ui;
177 caddr_t reg;
178 {
179 register struct updevice *upaddr = (struct updevice *)reg;
180
181 upaddr->upcs1 = 0; /* conservative */
182 upaddr->upcs2 = ui->ui_slave;
183 upaddr->upcs1 = UP_NOP|UP_GO;
184 if (upaddr->upcs2&UPCS2_NED) {
185 upaddr->upcs1 = UP_DCLR|UP_GO;
186 return (0);
187 }
188 return (1);
189 }
190
upattach(ui)191 upattach(ui)
192 register struct uba_device *ui;
193 {
194
195 if (upwstart == 0) {
196 timeout(upwatch, (caddr_t)0, hz);
197 upwstart++;
198 }
199 if (ui->ui_dk >= 0)
200 dk_wpms[ui->ui_dk] = 491521;
201 upip[ui->ui_ctlr][ui->ui_slave] = ui;
202 up_softc[ui->ui_ctlr].sc_ndrive++;
203 ui->ui_type = upmaptype(ui);
204 }
205
upmaptype(ui)206 upmaptype(ui)
207 register struct uba_device *ui;
208 {
209 register struct updevice *upaddr = (struct updevice *)ui->ui_addr;
210 int type = ui->ui_type;
211 register struct upst *st;
212
213 upaddr->upcs1 = 0;
214 upaddr->upcs2 = ui->ui_slave;
215 upaddr->uphr = UPHR_MAXTRAK;
216 for (st = upst; st->nsect != 0; st++)
217 if (upaddr->uphr == st->ntrak - 1) {
218 type = st - upst;
219 break;
220 }
221 if (st->nsect == 0)
222 printf(": uphr=%x", upaddr->uphr);
223 if (type == 0) {
224 upaddr->uphr = UPHR_MAXCYL;
225 if (upaddr->uphr == 822)
226 type++;
227 }
228 upaddr->upcs2 = UPCS2_CLR;
229 return (type);
230 }
231
upopen(dev)232 upopen(dev)
233 dev_t dev;
234 {
235 register int unit = upunit(dev);
236 register struct uba_device *ui;
237
238 if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0)
239 return (ENXIO);
240 return (0);
241 }
242
upstrategy(bp)243 upstrategy(bp)
244 register struct buf *bp;
245 {
246 register struct uba_device *ui;
247 register struct upst *st;
248 register int unit;
249 register struct buf *dp;
250 int xunit = minor(bp->b_dev) & 07;
251 long bn, sz;
252 int s;
253
254 sz = (bp->b_bcount+511) >> 9;
255 unit = upunit(bp->b_dev);
256 if (unit >= NUP) {
257 bp->b_error = ENXIO;
258 goto bad;
259 }
260 ui = updinfo[unit];
261 if (ui == 0 || ui->ui_alive == 0) {
262 bp->b_error = ENXIO;
263 goto bad;
264 }
265 st = &upst[ui->ui_type];
266 if (bp->b_blkno < 0 ||
267 (bn = bp->b_blkno)+sz > st->sizes[xunit].nblocks) {
268 if (bp->b_blkno == st->sizes[xunit].nblocks) {
269 bp->b_resid = bp->b_bcount;
270 goto done;
271 }
272 bp->b_error = EINVAL;
273 goto bad;
274 }
275 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
276 s = spl5();
277 dp = &uputab[ui->ui_unit];
278 disksort(dp, bp);
279 if (dp->b_active == 0) {
280 (void) upustart(ui);
281 bp = &ui->ui_mi->um_tab;
282 if (bp->b_actf && bp->b_active == 0)
283 (void) upstart(ui->ui_mi);
284 }
285 splx(s);
286 return;
287
288 bad:
289 bp->b_flags |= B_ERROR;
290 done:
291 iodone(bp);
292 return;
293 }
294
295 /*
296 * Unit start routine.
297 * Seek the drive to be where the data is
298 * and then generate another interrupt
299 * to actually start the transfer.
300 * If there is only one drive on the controller,
301 * or we are very close to the data, don't
302 * bother with the search. If called after
303 * searching once, don't bother to look where
304 * we are, just queue for transfer (to avoid
305 * positioning forever without transferrring.)
306 */
upustart(ui)307 upustart(ui)
308 register struct uba_device *ui;
309 {
310 register struct buf *bp, *dp;
311 register struct uba_ctlr *um;
312 register struct updevice *upaddr;
313 register struct upst *st;
314 daddr_t bn;
315 int sn, csn;
316 /*
317 * The SC21 cancels commands if you just say
318 * cs1 = UP_IE
319 * so we are cautious about handling of cs1.
320 * Also don't bother to clear as bits other than in upintr().
321 */
322 int didie = 0;
323
324 if (ui == 0)
325 return (0);
326 um = ui->ui_mi;
327 dk_busy &= ~(1<<ui->ui_dk);
328 dp = &uputab[ui->ui_unit];
329 if ((bp = dp->b_actf) == NULL)
330 goto out;
331 /*
332 * If the controller is active, just remember
333 * that this device would like to be positioned...
334 * if we tried to position now we would confuse the SC21.
335 */
336 if (um->um_tab.b_active) {
337 up_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave;
338 return (0);
339 }
340 /*
341 * If we have already positioned this drive,
342 * then just put it on the ready queue.
343 */
344 if (dp->b_active)
345 goto done;
346 dp->b_active = 1;
347 upaddr = (struct updevice *)um->um_addr;
348 upaddr->upcs2 = ui->ui_slave;
349 /*
350 * If drive has just come up,
351 * setup the pack.
352 */
353 if ((upaddr->upds & UPDS_VV) == 0 || upinit[ui->ui_unit] == 0) {
354 struct buf *bbp = &bupbuf[ui->ui_unit];
355
356 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */
357 upinit[ui->ui_unit] = 1;
358 upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO;
359 upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO;
360 upaddr->upof = UPOF_FMT22;
361 didie = 1;
362 st = &upst[ui->ui_type];
363 bbp->b_flags = B_READ|B_BUSY;
364 bbp->b_dev = bp->b_dev;
365 bbp->b_bcount = 512;
366 bbp->b_un.b_addr = (caddr_t)&upbad[ui->ui_unit];
367 bbp->b_blkno = st->ncyl * st->nspc - st->nsect;
368 bbp->b_cylin = st->ncyl - 1;
369 dp->b_actf = bbp;
370 bbp->av_forw = bp;
371 bp = bbp;
372 }
373 /*
374 * If drive is offline, forget about positioning.
375 */
376 if ((upaddr->upds & (UPDS_DPR|UPDS_MOL)) != (UPDS_DPR|UPDS_MOL))
377 goto done;
378 /*
379 * If there is only one drive,
380 * dont bother searching.
381 */
382 if (up_softc[um->um_ctlr].sc_ndrive == 1)
383 goto done;
384 /*
385 * Figure out where this transfer is going to
386 * and see if we are close enough to justify not searching.
387 */
388 st = &upst[ui->ui_type];
389 bn = bp->b_blkno;
390 sn = bn%st->nspc;
391 sn = (sn + st->nsect - st->sdist) % st->nsect;
392 if (bp->b_cylin - upaddr->updc)
393 goto search; /* Not on-cylinder */
394 else if (upseek)
395 goto done; /* Ok just to be on-cylinder */
396 csn = (upaddr->upla>>6) - sn - 1;
397 if (csn < 0)
398 csn += st->nsect;
399 if (csn > st->nsect - st->rdist)
400 goto done;
401 search:
402 upaddr->updc = bp->b_cylin;
403 /*
404 * Not on cylinder at correct position,
405 * seek/search.
406 */
407 if (upseek)
408 upaddr->upcs1 = UP_IE|UP_SEEK|UP_GO;
409 else {
410 upaddr->upda = sn;
411 upaddr->upcs1 = UP_IE|UP_SEARCH|UP_GO;
412 }
413 didie = 1;
414 /*
415 * Mark unit busy for iostat.
416 */
417 if (ui->ui_dk >= 0) {
418 dk_busy |= 1<<ui->ui_dk;
419 dk_seek[ui->ui_dk]++;
420 }
421 goto out;
422 done:
423 /*
424 * Device is ready to go.
425 * Put it on the ready queue for the controller
426 * (unless its already there.)
427 */
428 if (dp->b_active != 2) {
429 dp->b_forw = NULL;
430 if (um->um_tab.b_actf == NULL)
431 um->um_tab.b_actf = dp;
432 else
433 um->um_tab.b_actl->b_forw = dp;
434 um->um_tab.b_actl = dp;
435 dp->b_active = 2;
436 }
437 out:
438 return (didie);
439 }
440
441 /*
442 * Start up a transfer on a drive.
443 */
upstart(um)444 upstart(um)
445 register struct uba_ctlr *um;
446 {
447 register struct buf *bp, *dp;
448 register struct uba_device *ui;
449 register struct updevice *upaddr;
450 struct upst *st;
451 daddr_t bn;
452 int dn, sn, tn, cmd, waitdry;
453
454 loop:
455 /*
456 * Pull a request off the controller queue
457 */
458 if ((dp = um->um_tab.b_actf) == NULL)
459 return (0);
460 if ((bp = dp->b_actf) == NULL) {
461 um->um_tab.b_actf = dp->b_forw;
462 goto loop;
463 }
464 /*
465 * Mark controller busy, and
466 * determine destination of this request.
467 */
468 um->um_tab.b_active++;
469 ui = updinfo[upunit(bp->b_dev)];
470 bn = bp->b_blkno;
471 dn = ui->ui_slave;
472 st = &upst[ui->ui_type];
473 sn = bn%st->nspc;
474 tn = sn/st->nsect;
475 sn %= st->nsect;
476 upaddr = (struct updevice *)ui->ui_addr;
477 /*
478 * Select drive if not selected already.
479 */
480 if ((upaddr->upcs2&07) != dn)
481 upaddr->upcs2 = dn;
482 /*
483 * Check that it is ready and online
484 */
485 waitdry = 0;
486 while ((upaddr->upds&UPDS_DRY) == 0) {
487 printf("up%d: ds wait ds=%o\n",upunit(bp->b_dev),upaddr->upds);
488 if (++waitdry > 512)
489 break;
490 upwaitdry++;
491 }
492 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
493 printf("up%d: not ready", upunit(bp->b_dev));
494 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
495 printf("\n");
496 um->um_tab.b_active = 0;
497 um->um_tab.b_errcnt = 0;
498 dp->b_actf = bp->av_forw;
499 dp->b_active = 0;
500 bp->b_flags |= B_ERROR;
501 iodone(bp);
502 goto loop;
503 }
504 /*
505 * Oh, well, sometimes this
506 * happens, for reasons unknown.
507 */
508 printf(" (flakey)\n");
509 }
510 /*
511 * Setup for the transfer, and get in the
512 * UNIBUS adaptor queue.
513 */
514 upaddr->updc = bp->b_cylin;
515 upaddr->upda = (tn << 8) + sn;
516 upaddr->upwc = -bp->b_bcount / sizeof (short);
517 if (bp->b_flags & B_READ)
518 cmd = UP_IE|UP_RCOM|UP_GO;
519 else
520 cmd = UP_IE|UP_WCOM|UP_GO;
521 um->um_cmd = cmd;
522 (void) ubago(ui);
523 return (1);
524 }
525
526 /*
527 * Now all ready to go, stuff the registers.
528 */
529 updgo(um)
530 struct uba_ctlr *um;
531 {
532 register struct updevice *upaddr = (struct updevice *)um->um_addr;
533
534 um->um_tab.b_active = 2; /* should now be 2 */
535 upaddr->upba = um->um_ubinfo;
536 upaddr->upcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
537 }
538
539 /*
540 * Handle a disk interrupt.
541 */
upintr(sc21)542 upintr(sc21)
543 register sc21;
544 {
545 register struct buf *bp, *dp;
546 register struct uba_ctlr *um = upminfo[sc21];
547 register struct uba_device *ui;
548 register struct updevice *upaddr = (struct updevice *)um->um_addr;
549 register unit;
550 struct up_softc *sc = &up_softc[um->um_ctlr];
551 int as = (upaddr->upas & 0377) | sc->sc_softas;
552 int needie = 1, waitdry;
553
554 sc->sc_wticks = 0;
555 sc->sc_softas = 0;
556 /*
557 * If controller wasn't transferring, then this is an
558 * interrupt for attention status on seeking drives.
559 * Just service them.
560 */
561 if (um->um_tab.b_active != 2 && !sc->sc_recal) {
562 if (upaddr->upcs1 & UP_TRE)
563 upaddr->upcs1 = UP_TRE;
564 goto doattn;
565 }
566 um->um_tab.b_active = 1;
567 /*
568 * Get device and block structures, and a pointer
569 * to the uba_device for the drive. Select the drive.
570 */
571 dp = um->um_tab.b_actf;
572 bp = dp->b_actf;
573 ui = updinfo[upunit(bp->b_dev)];
574 dk_busy &= ~(1 << ui->ui_dk);
575 if ((upaddr->upcs2&07) != ui->ui_slave)
576 upaddr->upcs2 = ui->ui_slave;
577 if (bp->b_flags&B_BAD) {
578 if (upecc(ui, CONT))
579 return;
580 }
581 /*
582 * Check for and process errors on
583 * either the drive or the controller.
584 */
585 if ((upaddr->upds&UPDS_ERR) || (upaddr->upcs1&UP_TRE)) {
586 waitdry = 0;
587 while ((upaddr->upds & UPDS_DRY) == 0) {
588 if (++waitdry > 512)
589 break;
590 upwaitdry++;
591 }
592 if (upaddr->uper1&UPER1_WLE) {
593 /*
594 * Give up on write locked devices
595 * immediately.
596 */
597 printf("up%d: write locked\n", upunit(bp->b_dev));
598 bp->b_flags |= B_ERROR;
599 } else if (++um->um_tab.b_errcnt > 27) {
600 /*
601 * After 28 retries (16 without offset, and
602 * 12 with offset positioning) give up.
603 * If the error was header CRC, the header is
604 * screwed up, and the sector may in fact exist
605 * in the bad sector table, better check...
606 */
607 if (upaddr->uper1&UPER1_HCRC) {
608 if (upecc(ui, BSE))
609 return;
610 }
611 hard:
612 diskerr(bp, "up", "hard error", LOG_PRINTF, -1,
613 (struct disklabel *)0);
614 printf(" cn=%d tn=%d sn=%d cs2=%b er1=%b er2=%b\n",
615 upaddr->updc, ((upaddr->upda)>>8)&077,
616 (upaddr->upda)&037,
617 upaddr->upcs2, UPCS2_BITS,
618 upaddr->uper1, UPER1_BITS,
619 upaddr->uper2, UPER2_BITS);
620 bp->b_flags |= B_ERROR;
621 } else if (upaddr->uper2 & UPER2_BSE) {
622 if (upecc(ui, BSE))
623 return;
624 else
625 goto hard;
626 } else {
627 /*
628 * Retriable error.
629 * If a soft ecc, correct it (continuing
630 * by returning if necessary.
631 * Otherwise fall through and retry the transfer
632 */
633 if ((upaddr->uper1&(UPER1_DCK|UPER1_ECH))==UPER1_DCK) {
634 if (upecc(ui, ECC))
635 return;
636 } else
637 um->um_tab.b_active = 0; /* force retry */
638 }
639 /*
640 * Clear drive error and, every eight attempts,
641 * (starting with the fourth)
642 * recalibrate to clear the slate.
643 */
644 upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO;
645 needie = 0;
646 if ((um->um_tab.b_errcnt&07) == 4 && um->um_tab.b_active == 0) {
647 upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO;
648 sc->sc_recal = 0;
649 goto nextrecal;
650 }
651 }
652 /*
653 * Advance recalibration finite state machine
654 * if recalibrate in progress, through
655 * RECAL
656 * SEEK
657 * OFFSET (optional)
658 * RETRY
659 */
660 switch (sc->sc_recal) {
661
662 case 1:
663 upaddr->updc = bp->b_cylin;
664 upaddr->upcs1 = UP_SEEK|UP_IE|UP_GO;
665 goto nextrecal;
666 case 2:
667 if (um->um_tab.b_errcnt < 16 || (bp->b_flags&B_READ) == 0)
668 goto donerecal;
669 upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | UPOF_FMT22;
670 upaddr->upcs1 = UP_IE|UP_OFFSET|UP_GO;
671 goto nextrecal;
672 nextrecal:
673 sc->sc_recal++;
674 um->um_tab.b_active = 1;
675 return;
676 donerecal:
677 case 3:
678 sc->sc_recal = 0;
679 um->um_tab.b_active = 0;
680 break;
681 }
682 /*
683 * If still ``active'', then don't need any more retries.
684 */
685 if (um->um_tab.b_active) {
686 /*
687 * If we were offset positioning,
688 * return to centerline.
689 */
690 if (um->um_tab.b_errcnt >= 16) {
691 upaddr->upof = UPOF_FMT22;
692 upaddr->upcs1 = UP_RTC|UP_GO|UP_IE;
693 while (upaddr->upds & UPDS_PIP)
694 DELAY(25);
695 needie = 0;
696 }
697 um->um_tab.b_active = 0;
698 um->um_tab.b_errcnt = 0;
699 um->um_tab.b_actf = dp->b_forw;
700 dp->b_active = 0;
701 dp->b_errcnt = 0;
702 dp->b_actf = bp->av_forw;
703 bp->b_resid = (-upaddr->upwc * sizeof(short));
704 iodone(bp);
705 /*
706 * If this unit has more work to do,
707 * then start it up right away.
708 */
709 if (dp->b_actf)
710 if (upustart(ui))
711 needie = 0;
712 }
713 as &= ~(1<<ui->ui_slave);
714 /*
715 * Release unibus resources and flush data paths.
716 */
717 ubadone(um);
718 doattn:
719 /*
720 * Process other units which need attention.
721 * For each unit which needs attention, call
722 * the unit start routine to place the slave
723 * on the controller device queue.
724 */
725 while (unit = ffs((long)as)) {
726 unit--; /* was 1 origin */
727 as &= ~(1<<unit);
728 upaddr->upas = 1<<unit;
729 if (unit < UPIPUNITS && upustart(upip[sc21][unit]))
730 needie = 0;
731 }
732 /*
733 * If the controller is not transferring, but
734 * there are devices ready to transfer, start
735 * the controller.
736 */
737 if (um->um_tab.b_actf && um->um_tab.b_active == 0)
738 if (upstart(um))
739 needie = 0;
740 if (needie)
741 upaddr->upcs1 = UP_IE;
742 }
743
744 /*
745 * Correct an ECC error, and restart the i/o to complete
746 * the transfer if necessary. This is quite complicated because
747 * the transfer may be going to an odd memory address base and/or
748 * across a page boundary.
749 */
upecc(ui,flag)750 upecc(ui, flag)
751 register struct uba_device *ui;
752 int flag;
753 {
754 register struct updevice *up = (struct updevice *)ui->ui_addr;
755 register struct buf *bp = uputab[ui->ui_unit].b_actf;
756 register struct uba_ctlr *um = ui->ui_mi;
757 register struct upst *st;
758 struct uba_regs *ubp = ui->ui_hd->uh_uba;
759 register int i;
760 caddr_t addr;
761 int reg, bit, byte, npf, mask, o, cmd, ubaddr;
762 int bn, cn, tn, sn;
763
764 /*
765 * Npf is the number of sectors transferred before the sector
766 * containing the ECC error, and reg is the UBA register
767 * mapping (the first part of) the transfer.
768 * O is offset within a memory page of the first byte transferred.
769 */
770 if (flag == CONT)
771 npf = bp->b_error;
772 else
773 npf = btodb(bp->b_bcount + (up->upwc * sizeof(short)) + 511);
774 reg = btop(UBAI_ADDR(um->um_ubinfo)) + npf;
775 o = (int)bp->b_un.b_addr & PGOFSET;
776 mask = up->upec2;
777 #ifdef UPECCDEBUG
778 printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask,
779 up->upec1);
780 #endif
781 bn = bp->b_blkno;
782 st = &upst[ui->ui_type];
783 cn = bp->b_cylin;
784 sn = bn%st->nspc + npf;
785 tn = sn/st->nsect;
786 sn %= st->nsect;
787 cn += tn/st->ntrak;
788 tn %= st->ntrak;
789 ubapurge(um);
790 um->um_tab.b_active=2;
791 /*
792 * action taken depends on the flag
793 */
794 switch(flag){
795 case ECC:
796 npf--;
797 reg--;
798 mask = up->upec2;
799 diskerr(bp, "up", "soft ecc", LOG_WARNING, npf,
800 (struct disklabel *)0);
801 addlog("\n");
802 /*
803 * Flush the buffered data path, and compute the
804 * byte and bit position of the error. The variable i
805 * is the byte offset in the transfer, the variable byte
806 * is the offset from a page boundary in main memory.
807 */
808 i = up->upec1 - 1; /* -1 makes 0 origin */
809 bit = i&07;
810 i = (i&~07)>>3;
811 byte = i + o;
812 /*
813 * Correct while possible bits remain of mask. Since mask
814 * contains 11 bits, we continue while the bit offset is > -11.
815 * Also watch out for end of this block and the end of the whole
816 * transfer.
817 */
818 while (i < 512 && (int)dbtob(npf)+i < bp->b_bcount && bit > -11) {
819 struct pte pte;
820
821 pte = ubp->uba_map[reg + btop(byte)];
822 addr = ptob(pte.pg_pfnum) + (byte & PGOFSET);
823 #ifdef UPECCDEBUG
824 printf("addr %x map reg %x\n",
825 addr, *(int *)(&ubp->uba_map[reg+btop(byte)]));
826 printf("old: %x, ", getmemc(addr));
827 #endif
828 putmemc(addr, getmemc(addr)^(mask<<bit));
829 #ifdef UPECCDEBUG
830 printf("new: %x\n", getmemc(addr));
831 #endif
832 byte++;
833 i++;
834 bit -= 8;
835 }
836 if (up->upwc == 0)
837 return (0);
838 npf++;
839 reg++;
840 break;
841 case BSE:
842 /*
843 * if not in bad sector table, return 0
844 */
845 if ((bn = isbad(&upbad[ui->ui_unit], cn, tn, sn)) < 0)
846 return(0);
847 /*
848 * flag this one as bad
849 */
850 bp->b_flags |= B_BAD;
851 bp->b_error = npf + 1;
852 #ifdef UPECCDEBUG
853 printf("BSE: restart at %d\n",npf+1);
854 #endif
855 bn = st->ncyl * st->nspc -st->nsect - 1 - bn;
856 cn = bn / st->nspc;
857 sn = bn % st->nspc;
858 tn = sn / st->nsect;
859 sn %= st->nsect;
860 up->upwc = -(512 / sizeof (short));
861 #ifdef UPECCDEBUG
862 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
863 #endif
864 break;
865 case CONT:
866 #ifdef UPECCDEBUG
867 printf("upecc, CONT: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
868 #endif
869 bp->b_flags &= ~B_BAD;
870 if ((int)dbtob(npf) >= bp->b_bcount)
871 return (0);
872 up->upwc = -((bp->b_bcount - (int)dbtob(npf)) / sizeof(short));
873 break;
874 }
875 if (up->upwc == 0) {
876 um->um_tab.b_active = 0;
877 return (0);
878 }
879 /*
880 * Have to continue the transfer... clear the drive,
881 * and compute the position where the transfer is to continue.
882 * We have completed npf+1 sectors of the transfer already;
883 * restart at offset o of next sector (i.e. in UBA register reg+1).
884 */
885 #ifdef notdef
886 up->uper1 = 0;
887 up->upcs1 |= UP_GO;
888 #else
889 up->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO;
890 up->updc = cn;
891 up->upda = (tn << 8) | sn;
892 ubaddr = (int)ptob(reg) + o;
893 up->upba = ubaddr;
894 cmd = (ubaddr >> 8) & 0x300;
895 cmd |= ((bp->b_flags&B_READ)?UP_RCOM:UP_WCOM)|UP_IE|UP_GO;
896 um->um_tab.b_errcnt = 0;
897 up->upcs1 = cmd;
898 #endif
899 return (1);
900 }
901
902 /*
903 * Reset driver after UBA init.
904 * Cancel software state of all pending transfers
905 * and restart all units and the controller.
906 */
upreset(uban)907 upreset(uban)
908 int uban;
909 {
910 register struct uba_ctlr *um;
911 register struct uba_device *ui;
912 register sc21, unit;
913
914 for (sc21 = 0; sc21 < NSC; sc21++) {
915 if ((um = upminfo[sc21]) == 0 || um->um_ubanum != uban ||
916 um->um_alive == 0)
917 continue;
918 printf(" sc%d", sc21);
919 um->um_tab.b_active = 0;
920 um->um_tab.b_actf = um->um_tab.b_actl = 0;
921 up_softc[sc21].sc_recal = 0;
922 up_softc[sc21].sc_wticks = 0;
923 if (um->um_ubinfo) {
924 printf("<%d>", (um->um_ubinfo>>28)&0xf);
925 um->um_ubinfo = 0;
926 }
927 ((struct updevice *)(um->um_addr))->upcs2 = UPCS2_CLR;
928 for (unit = 0; unit < NUP; unit++) {
929 if ((ui = updinfo[unit]) == 0)
930 continue;
931 if (ui->ui_alive == 0 || ui->ui_mi != um)
932 continue;
933 uputab[unit].b_active = 0;
934 (void) upustart(ui);
935 }
936 (void) upstart(um);
937 }
938 }
939
940 /*
941 * Wake up every second and if an interrupt is pending
942 * but nothing has happened increment a counter.
943 * If nothing happens for 20 seconds, reset the UNIBUS
944 * and begin anew.
945 */
upwatch()946 upwatch()
947 {
948 register struct uba_ctlr *um;
949 register sc21, unit;
950 register struct up_softc *sc;
951
952 timeout(upwatch, (caddr_t)0, hz);
953 for (sc21 = 0; sc21 < NSC; sc21++) {
954 um = upminfo[sc21];
955 if (um == 0 || um->um_alive == 0)
956 continue;
957 sc = &up_softc[sc21];
958 if (um->um_tab.b_active == 0) {
959 for (unit = 0; unit < NUP; unit++)
960 if (uputab[unit].b_active &&
961 updinfo[unit]->ui_mi == um)
962 goto active;
963 sc->sc_wticks = 0;
964 continue;
965 }
966 active:
967 sc->sc_wticks++;
968 if (sc->sc_wticks >= 20) {
969 sc->sc_wticks = 0;
970 printf("sc%d: lost interrupt\n", sc21);
971 ubareset(um->um_ubanum);
972 }
973 }
974 }
975
976 #define DBSIZE 20
977
updump(dev)978 updump(dev)
979 dev_t dev;
980 {
981 struct updevice *upaddr;
982 char *start;
983 int num, blk, unit;
984 struct size *sizes;
985 register struct uba_regs *uba;
986 register struct uba_device *ui;
987 register short *rp;
988 struct upst *st;
989 register int retry;
990
991 unit = upunit(dev);
992 if (unit >= NUP)
993 return (ENXIO);
994 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
995 ui = phys(struct uba_device *, updinfo[unit]);
996 if (ui->ui_alive == 0)
997 return (ENXIO);
998 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
999 ubainit(uba);
1000 upaddr = (struct updevice *)ui->ui_physaddr;
1001 DELAY(5000000);
1002 num = maxfree;
1003 upaddr->upcs2 = unit;
1004 DELAY(100);
1005 upaddr->upcs1 = UP_DCLR|UP_GO;
1006 upaddr->upcs1 = UP_PRESET|UP_GO;
1007 upaddr->upof = UPOF_FMT22;
1008 retry = 0;
1009 do {
1010 DELAY(25);
1011 if (++retry > 527)
1012 break;
1013 } while ((upaddr->upds & UP_RDY) == 0);
1014 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY)
1015 return (EFAULT);
1016 start = 0;
1017 st = &upst[ui->ui_type];
1018 sizes = phys(struct size *, st->sizes);
1019 if (dumplo < 0)
1020 return (EINVAL);
1021 if (dumplo + num >= sizes[minor(dev)&07].nblocks)
1022 num = sizes[minor(dev)&07].nblocks - dumplo;
1023 while (num > 0) {
1024 register struct pte *io;
1025 register int i;
1026 int cn, sn, tn;
1027 daddr_t bn;
1028
1029 blk = num > DBSIZE ? DBSIZE : num;
1030 io = uba->uba_map;
1031 for (i = 0; i < blk; i++)
1032 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV;
1033 *(int *)io = 0;
1034 bn = dumplo + btop(start);
1035 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff;
1036 sn = bn%st->nspc;
1037 tn = sn/st->nsect;
1038 sn = sn%st->nsect;
1039 upaddr->updc = cn;
1040 rp = (short *) &upaddr->upda;
1041 *rp = (tn << 8) + sn;
1042 *--rp = 0;
1043 *--rp = -blk*NBPG / sizeof (short);
1044 *--rp = UP_GO|UP_WCOM;
1045 retry = 0;
1046 do {
1047 DELAY(25);
1048 if (++retry > 527)
1049 break;
1050 } while ((upaddr->upcs1 & UP_RDY) == 0);
1051 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
1052 printf("up%d: not ready", unit);
1053 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
1054 printf("\n");
1055 return (EIO);
1056 }
1057 printf(" (flakey)\n");
1058 }
1059 if (upaddr->upds&UPDS_ERR)
1060 return (EIO);
1061 start += blk*NBPG;
1062 num -= blk;
1063 }
1064 return (0);
1065 }
1066
upsize(dev)1067 upsize(dev)
1068 dev_t dev;
1069 {
1070 int unit = upunit(dev);
1071 struct uba_device *ui;
1072 struct upst *st;
1073
1074 if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0)
1075 return (-1);
1076 st = &upst[ui->ui_type];
1077 return (st->sizes[minor(dev) & 07].nblocks);
1078 }
1079 #endif
1080