1 /* uda.c 4.22 83/05/14 */ 2 3 #include "ra.h" 4 #if NUDA > 0 5 /* 6 * UDA50/RAxx disk device driver 7 * 8 * Restrictions: 9 * Unit numbers must be less than 8. 10 * 11 * TO DO: 12 * write dump code 13 */ 14 #include "../machine/pte.h" 15 16 #include "../h/param.h" 17 #include "../h/systm.h" 18 #include "../h/buf.h" 19 #include "../h/conf.h" 20 #include "../h/dir.h" 21 #include "../h/user.h" 22 #include "../h/map.h" 23 #include "../h/vm.h" 24 #include "../h/dk.h" 25 #include "../h/cmap.h" 26 #include "../h/uio.h" 27 28 #include "../vax/cpu.h" 29 #include "../vaxuba/ubareg.h" 30 #include "../vaxuba/ubavar.h" 31 32 #define NRSPL2 3 /* log2 number of response packets */ 33 #define NCMDL2 3 /* log2 number of command packets */ 34 #define NRSP (1<<NRSPL2) 35 #define NCMD (1<<NCMDL2) 36 37 #include "../vaxuba/udareg.h" 38 #include "../vax/mscp.h" 39 40 struct uda_softc { 41 short sc_state; /* state of controller */ 42 short sc_mapped; /* Unibus map allocated for uda struct? */ 43 int sc_ubainfo; /* Unibus mapping info */ 44 struct uda *sc_uda; /* Unibus address of uda struct */ 45 int sc_ivec; /* interrupt vector address */ 46 short sc_credits; /* transfer credits */ 47 short sc_lastcmd; /* pointer into command ring */ 48 short sc_lastrsp; /* pointer into response ring */ 49 } uda_softc[NUDA]; 50 51 /* 52 * Controller states 53 */ 54 #define S_IDLE 0 /* hasn't been initialized */ 55 #define S_STEP1 1 /* doing step 1 init */ 56 #define S_STEP2 2 /* doing step 2 init */ 57 #define S_STEP3 3 /* doing step 3 init */ 58 #define S_SCHAR 4 /* doing "set controller characteristics" */ 59 #define S_RUN 5 /* running */ 60 61 struct uda { 62 struct udaca uda_ca; /* communications area */ 63 struct mscp uda_rsp[NRSP]; /* response packets */ 64 struct mscp uda_cmd[NCMD]; /* command packets */ 65 } uda[NUDA]; 66 67 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 68 struct size { 69 daddr_t nblocks; 70 daddr_t blkoff; 71 } ra_sizes[8] ={ 72 #ifdef notdef 73 15884, 0, /* A=blk 0 thru 15883 */ 74 33440, 15884, /* B=blk 15884 thru 49323 */ 75 -1, 0, /* C=blk 0 thru end */ 76 15884, 340670, /* D=blk 340670 thru 356553 */ 77 55936, 356554, /* E=blk 356554 thru 412489 */ 78 -1, 412490, /* F=blk 412490 thru end */ 79 82080, 49324, /* G=blk 49324 thru 131403 */ 80 -1, 131404, /* H=blk 131404 thru end */ 81 } ra81_sizes[8] = { 82 #endif 83 15884, 0, /* A=cyl 0 thru 22 */ 84 66880, 16422, /* B=cyl 23 thru 116 */ 85 -1, 0, /* C=cyl 0 thru end */ 86 15884, 375564, /* D=cyl 526 thru 548 */ 87 307200, 391986, /* E=cyl 549 thru 979 */ 88 -1, 699720, /* F=cyl 980 thru end */ 89 -1, 375564, /* G=cyl 526 thru end */ 90 291346, 83538, /* H=cyl 117 thru 525 */ 91 }; 92 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 93 94 int udaerror = 0; /* causes hex dump of packets */ 95 int udadebug = 0; 96 #define printd if (udadebug) printf 97 98 daddr_t radsize[NRA]; /* disk size, from ONLINE end packet */ 99 100 int udprobe(), udslave(), udattach(), udintr(); 101 struct mscp *udgetcp(); 102 struct uba_ctlr *udminfo[NUDA]; 103 struct uba_device *uddinfo[NRA]; 104 struct uba_device *udip[NUDA][8]; /* 8 == max number of drives */ 105 106 u_short udstd[] = { 0772150, 0772550, 0777550, 0 }; 107 struct uba_driver udadriver = 108 { udprobe, udslave, udattach, 0, udstd, "ra", uddinfo, "uda", udminfo, 0 }; 109 struct buf rudbuf[NRA]; 110 struct buf udutab[NRA]; 111 struct buf udwtab[NUDA]; /* I/O wait queue, per controller */ 112 113 #define b_qsize b_resid /* queue size per drive, in udutab */ 114 #define b_ubinfo b_resid /* Unibus mapping info, per buffer */ 115 116 udprobe(reg, ctlr) 117 caddr_t reg; 118 int ctlr; 119 { 120 register int br, cvec; 121 register struct uda_softc *sc = &uda_softc[ctlr]; 122 123 #ifdef lint 124 br = 0; cvec = br; br = cvec; reg = reg; 125 udread(0); udwrite(0); udreset(0); udintr(0); 126 #endif 127 /* SHOULD CHECK THAT IT REALLY IS A UDA */ 128 br = 0x15; 129 cvec = sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4); 130 return(sizeof (struct udadevice)); 131 } 132 133 udslave(ui, reg) 134 struct uba_device *ui; 135 caddr_t reg; 136 { 137 /* 138 * TOO HARD TO FIND OUT IF DISK IS THERE UNTIL 139 * INITIALIZED. WE'LL FIND OUT WHEN WE FIRST 140 * TRY TO ACCESS IT. 141 */ 142 #ifdef lint 143 ui = ui; reg = reg; 144 #endif 145 return(1); 146 } 147 148 udattach(ui) 149 register struct uba_device *ui; 150 { 151 152 if (ui->ui_dk >= 0) 153 dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256); /* approx */ 154 ui->ui_flags = 0; 155 udip[ui->ui_ctlr][ui->ui_slave] = ui; 156 radsize[ui->ui_unit] = (daddr_t)0xffffff; /* max possible size */ 157 } 158 159 /* 160 * Open a UDA. Initialize the device and 161 * set the unit online. 162 */ 163 udopen(dev, flag) 164 dev_t dev; 165 int flag; 166 { 167 register int unit; 168 register struct uba_device *ui; 169 register struct uda_softc *sc; 170 int s; 171 172 #ifdef lint 173 flag = flag; 174 #endif 175 unit = minor(dev) >> 3; 176 if (unit >= NRA || (ui = uddinfo[unit]) == 0 || ui->ui_alive == 0) 177 return (ENXIO); 178 sc = &uda_softc[ui->ui_ctlr]; 179 s = spl5(); 180 if (sc->sc_state != S_RUN) { 181 if (sc->sc_state == S_IDLE) 182 udinit(ui->ui_ctlr); 183 /* wait for initialization to complete */ 184 sleep((caddr_t)ui->ui_mi, 0); 185 if (sc->sc_state != S_RUN) 186 return (EIO); 187 } 188 splx(s); 189 /* SHOULD PROBABLY FORCE AN ONLINE ATTEMPT 190 TO SEE IF DISK IS REALLY THERE */ 191 return (0); 192 } 193 194 /* 195 * Initialize a UDA. Set up UBA mapping registers, 196 * initialize data structures, and start hardware 197 * initialization sequence. 198 */ 199 udinit(d) 200 int d; 201 { 202 register struct uda_softc *sc; 203 register struct uda *ud; 204 struct udadevice *udaddr; 205 struct uba_ctlr *um; 206 207 sc = &uda_softc[d]; 208 um = udminfo[d]; 209 um->um_tab.b_active++; 210 ud = &uda[d]; 211 udaddr = (struct udadevice *)um->um_addr; 212 if (sc->sc_mapped == 0) { 213 /* 214 * Map the communications area and command 215 * and response packets into Unibus address 216 * space. 217 */ 218 sc->sc_ubainfo = uballoc(um->um_ubanum, (caddr_t)ud, 219 sizeof (struct uda), 0); 220 sc->sc_uda = (struct uda *)(sc->sc_ubainfo & 0x3ffff); 221 sc->sc_mapped = 1; 222 } 223 224 /* 225 * Start the hardware initialization sequence. 226 */ 227 udaddr->udaip = 0; /* start initialization */ 228 while ((udaddr->udasa & UDA_STEP1) == 0) 229 ; 230 udaddr->udasa = UDA_ERR|(NCMDL2<<11)|(NRSPL2<<8)|UDA_IE|(sc->sc_ivec/4); 231 /* 232 * Initialization continues in interrupt routine. 233 */ 234 sc->sc_state = S_STEP1; 235 sc->sc_credits = 0; 236 } 237 238 udstrategy(bp) 239 register struct buf *bp; 240 { 241 register struct uba_device *ui; 242 register struct uba_ctlr *um; 243 register struct buf *dp; 244 register int unit; 245 int xunit = minor(bp->b_dev) & 07; 246 daddr_t sz, maxsz; 247 int s; 248 249 sz = (bp->b_bcount+511) >> 9; 250 unit = dkunit(bp); 251 if (unit >= NRA) 252 goto bad; 253 ui = uddinfo[unit]; 254 um = ui->ui_mi; 255 if (ui == 0 || ui->ui_alive == 0) 256 goto bad; 257 if ((maxsz = ra_sizes[xunit].nblocks) < 0) 258 maxsz = radsize[unit] - ra_sizes[xunit].blkoff; 259 if (bp->b_blkno < 0 || bp->b_blkno+sz > maxsz || 260 ra_sizes[xunit].blkoff >= radsize[unit]) 261 goto bad; 262 s = spl5(); 263 /* 264 * Link the buffer onto the drive queue 265 */ 266 dp = &udutab[ui->ui_unit]; 267 if (dp->b_actf == 0) 268 dp->b_actf = bp; 269 else 270 dp->b_actl->av_forw = bp; 271 dp->b_actl = bp; 272 bp->av_forw = 0; 273 /* 274 * Link the drive onto the controller queue 275 */ 276 if (dp->b_active == 0) { 277 dp->b_forw = NULL; 278 if (um->um_tab.b_actf == NULL) 279 um->um_tab.b_actf = dp; 280 else 281 um->um_tab.b_actl->b_forw = dp; 282 um->um_tab.b_actl = dp; 283 dp->b_active = 1; 284 } 285 if (um->um_tab.b_active == 0) { 286 #if defined(VAX750) 287 if (cpu == VAX_750 288 && udwtab[um->um_ctlr].av_forw == &udwtab[um->um_ctlr]) { 289 if (um->um_ubinfo != 0) 290 printf("udastrat: ubinfo 0x%x\n",um->um_ubinfo); 291 else 292 um->um_ubinfo = 293 uballoc(um->um_ubanum, (caddr_t)0, 0, 294 UBA_NEEDBDP); 295 } 296 #endif 297 (void) udstart(um); 298 } 299 splx(s); 300 return; 301 302 bad: 303 bp->b_flags |= B_ERROR; 304 iodone(bp); 305 return; 306 } 307 308 udstart(um) 309 register struct uba_ctlr *um; 310 { 311 register struct buf *bp, *dp; 312 register struct mscp *mp; 313 register struct uda_softc *sc; 314 register struct uba_device *ui; 315 struct udadevice *udaddr; 316 int i; 317 318 sc = &uda_softc[um->um_ctlr]; 319 320 loop: 321 if ((dp = um->um_tab.b_actf) == NULL) { 322 /* 323 * Release uneeded UBA resources and return 324 */ 325 um->um_tab.b_active = 0; 326 return (0); 327 } 328 if ((bp = dp->b_actf) == NULL) { 329 /* 330 * No more requests for this drive, remove 331 * from controller queue and look at next drive. 332 * We know we're at the head of the controller queue. 333 */ 334 dp->b_active = 0; 335 um->um_tab.b_actf = dp->b_forw; 336 goto loop; 337 } 338 um->um_tab.b_active++; 339 udaddr = (struct udadevice *)um->um_addr; 340 if ((udaddr->udasa&UDA_ERR) || sc->sc_state != S_RUN) { 341 harderr(bp, "ra"); 342 printf("udasa %o, state %d\n", udaddr->udasa&0xffff, sc->sc_state); 343 udinit(um->um_ctlr); 344 /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE UDRESET */ 345 return (0); 346 } 347 ui = uddinfo[dkunit(bp)]; 348 /* 349 * If no credits, can't issue any commands 350 * until some outstanding commands complete. 351 */ 352 if (sc->sc_credits < 2) 353 return (0); 354 if ((mp = udgetcp(um)) == NULL) 355 return (0); 356 sc->sc_credits--; /* committed to issuing a command */ 357 if (ui->ui_flags == 0) { /* not online */ 358 mp->mscp_opcode = M_OP_ONLIN; 359 mp->mscp_unit = ui->ui_slave; 360 dp->b_active = 2; 361 um->um_tab.b_actf = dp->b_forw; /* remove from controller q */ 362 printd("uda: bring unit %d online\n", ui->ui_slave); 363 *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT; 364 i = udaddr->udaip; 365 goto loop; 366 } 367 switch (cpu) { 368 case VAX_780: 369 i = UBA_NEEDBDP|UBA_CANTWAIT; 370 break; 371 372 case VAX_750: 373 i = um->um_ubinfo|UBA_HAVEBDP|UBA_CANTWAIT; 374 break; 375 376 case VAX_730: 377 i = UBA_CANTWAIT; 378 break; 379 } 380 if ((i = ubasetup(um->um_ubanum, bp, i)) == 0) { 381 mp->mscp_opcode = M_OP_GTUNT; 382 mp->mscp_unit = ui->ui_slave; 383 *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT; 384 i = udaddr->udaip; /* initiate polling */ 385 return(1); /* wait for interrupt */ 386 } 387 mp->mscp_cmdref = (long)bp; /* pointer to get back */ 388 mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE; 389 mp->mscp_unit = ui->ui_slave; 390 mp->mscp_lbn = bp->b_blkno + ra_sizes[minor(bp->b_dev)&7].blkoff; 391 mp->mscp_bytecnt = bp->b_bcount; 392 mp->mscp_buffer = (i & 0x3ffff) | (((i>>28)&0xf)<<24); 393 #if defined(VAX750) 394 if (cpu == VAX_750) 395 i &= 0xfffffff; /* mask off bdp */ 396 #endif 397 bp->b_ubinfo = i; /* save mapping info */ 398 *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT; 399 i = udaddr->udaip; /* initiate polling */ 400 if (ui->ui_dk >= 0) { 401 dk_busy |= 1<<ui->ui_dk; 402 dp->b_qsize++; 403 dk_xfer[ui->ui_dk]++; 404 dk_wds[ui->ui_dk] += bp->b_bcount>>6; 405 } 406 407 /* 408 * Move drive to the end of the controller queue 409 */ 410 if (dp->b_forw != NULL) { 411 um->um_tab.b_actf = dp->b_forw; 412 um->um_tab.b_actl->b_forw = dp; 413 um->um_tab.b_actl = dp; 414 dp->b_forw = NULL; 415 } 416 /* 417 * Move buffer to I/O wait queue 418 */ 419 dp->b_actf = bp->av_forw; 420 dp = &udwtab[um->um_ctlr]; 421 bp->av_forw = dp; 422 bp->av_back = dp->av_back; 423 dp->av_back->av_forw = bp; 424 dp->av_back = bp; 425 goto loop; 426 } 427 428 /* 429 * UDA interrupt routine. 430 */ 431 udintr(d) 432 int d; 433 { 434 register struct uba_ctlr *um = udminfo[d]; 435 register struct udadevice *udaddr = (struct udadevice *)um->um_addr; 436 struct buf *bp; 437 register int i; 438 register struct uda_softc *sc = &uda_softc[d]; 439 register struct uda *ud = &uda[d]; 440 struct uda *uud; 441 struct mscp *mp; 442 443 printd("udintr: state %d, udasa %o\n", sc->sc_state, udaddr->udasa); 444 switch (sc->sc_state) { 445 case S_IDLE: 446 printf("uda%d: random interrupt ignored\n", d); 447 return; 448 449 case S_STEP1: 450 #define STEP1MASK 0174377 451 #define STEP1GOOD (UDA_STEP2|UDA_IE|(NCMDL2<<3)|NRSPL2) 452 if ((udaddr->udasa&STEP1MASK) != STEP1GOOD) { 453 sc->sc_state = S_IDLE; 454 wakeup((caddr_t)um); 455 return; 456 } 457 udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)| 458 (cpu == VAX_780 ? UDA_PI : 0); 459 sc->sc_state = S_STEP2; 460 return; 461 462 case S_STEP2: 463 #define STEP2MASK 0174377 464 #define STEP2GOOD (UDA_STEP3|UDA_IE|(sc->sc_ivec/4)) 465 if ((udaddr->udasa&STEP2MASK) != STEP2GOOD) { 466 sc->sc_state = S_IDLE; 467 wakeup((caddr_t)um); 468 return; 469 } 470 udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)>>16; 471 sc->sc_state = S_STEP3; 472 return; 473 474 case S_STEP3: 475 #define STEP3MASK 0174000 476 #define STEP3GOOD UDA_STEP4 477 if ((udaddr->udasa&STEP3MASK) != STEP3GOOD) { 478 sc->sc_state = S_IDLE; 479 wakeup((caddr_t)um); 480 return; 481 } 482 udaddr->udasa = UDA_GO; 483 sc->sc_state = S_SCHAR; 484 485 /* 486 * Initialize the data structures. 487 */ 488 uud = sc->sc_uda; 489 for (i = 0; i < NRSP; i++) { 490 ud->uda_ca.ca_rspdsc[i] = UDA_OWN|UDA_INT| 491 (long)&uud->uda_rsp[i].mscp_cmdref; 492 ud->uda_rsp[i].mscp_dscptr = &ud->uda_ca.ca_rspdsc[i]; 493 ud->uda_rsp[i].mscp_header.uda_msglen = sizeof (struct mscp); 494 } 495 for (i = 0; i < NCMD; i++) { 496 ud->uda_ca.ca_cmddsc[i] = UDA_INT| 497 (long)&uud->uda_cmd[i].mscp_cmdref; 498 ud->uda_cmd[i].mscp_dscptr = &ud->uda_ca.ca_cmddsc[i]; 499 ud->uda_cmd[i].mscp_header.uda_msglen = sizeof (struct mscp); 500 } 501 bp = &udwtab[d]; 502 bp->av_forw = bp->av_back = bp; 503 sc->sc_lastcmd = 0; 504 sc->sc_lastrsp = 0; 505 if ((mp = udgetcp(um)) == NULL) { 506 sc->sc_state = S_IDLE; 507 wakeup((caddr_t)um); 508 return; 509 } 510 mp->mscp_opcode = M_OP_STCON; 511 mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS; 512 *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT; 513 i = udaddr->udaip; /* initiate polling */ 514 return; 515 516 case S_SCHAR: 517 case S_RUN: 518 break; 519 520 default: 521 printf("uda%d: interrupt in unknown state %d ignored\n", 522 d, sc->sc_state); 523 return; 524 } 525 526 if (udaddr->udasa&UDA_ERR) { 527 printf("uda%d: fatal error (%o)\n", d, udaddr->udasa&0xffff); 528 udaddr->udaip = 0; 529 wakeup((caddr_t)um); 530 } 531 532 /* 533 * Check for a buffer purge request. 534 */ 535 if (ud->uda_ca.ca_bdp) { 536 /* 537 * THIS IS A KLUDGE. 538 * Maybe we should change the entire 539 * UBA interface structure. 540 */ 541 int s = spl7(); 542 543 i = um->um_ubinfo; 544 printd("uda: purge bdp %d\n", ud->uda_ca.ca_bdp); 545 um->um_ubinfo = ud->uda_ca.ca_bdp<<28; 546 ubapurge(um); 547 um->um_ubinfo = i; 548 (void) splx(s); 549 ud->uda_ca.ca_bdp = 0; 550 udaddr->udasa = 0; /* signal purge complete */ 551 } 552 553 /* 554 * Check for response ring transition. 555 */ 556 if (ud->uda_ca.ca_rspint) { 557 ud->uda_ca.ca_rspint = 0; 558 for (i = sc->sc_lastrsp;; i++) { 559 i %= NRSP; 560 if (ud->uda_ca.ca_rspdsc[i]&UDA_OWN) 561 break; 562 udrsp(um, ud, sc, i); 563 ud->uda_ca.ca_rspdsc[i] |= UDA_OWN; 564 } 565 sc->sc_lastrsp = i; 566 } 567 568 /* 569 * Check for command ring transition. 570 */ 571 if (ud->uda_ca.ca_cmdint) { 572 printd("uda: command ring transition\n"); 573 ud->uda_ca.ca_cmdint = 0; 574 } 575 (void) udstart(um); 576 } 577 578 /* 579 * Process a response packet 580 */ 581 udrsp(um, ud, sc, i) 582 register struct uba_ctlr *um; 583 register struct uda *ud; 584 register struct uda_softc *sc; 585 int i; 586 { 587 register struct mscp *mp; 588 struct uba_device *ui; 589 struct buf *dp, *bp; 590 int st; 591 592 mp = &ud->uda_rsp[i]; 593 mp->mscp_header.uda_msglen = sizeof (struct mscp); 594 sc->sc_credits += mp->mscp_header.uda_credits & 0xf; 595 if ((mp->mscp_header.uda_credits & 0xf0) > 0x10) 596 return; 597 /* 598 * If it's an error log message (datagram), 599 * pass it on for more extensive processing. 600 */ 601 if ((mp->mscp_header.uda_credits & 0xf0) == 0x10) { 602 uderror(um, (struct mslg *)mp); 603 return; 604 } 605 if (mp->mscp_unit >= 8) 606 return; 607 if ((ui = udip[um->um_ctlr][mp->mscp_unit]) == 0) 608 return; 609 st = mp->mscp_status&M_ST_MASK; 610 switch (mp->mscp_opcode) { 611 case M_OP_STCON|M_OP_END: 612 if (st == M_ST_SUCC) 613 sc->sc_state = S_RUN; 614 else 615 sc->sc_state = S_IDLE; 616 um->um_tab.b_active = 0; 617 wakeup((caddr_t)um); 618 break; 619 620 case M_OP_ONLIN|M_OP_END: 621 /* 622 * Link the drive onto the controller queue 623 */ 624 dp = &udutab[ui->ui_unit]; 625 dp->b_forw = NULL; 626 if (um->um_tab.b_actf == NULL) 627 um->um_tab.b_actf = dp; 628 else 629 um->um_tab.b_actl->b_forw = dp; 630 um->um_tab.b_actl = dp; 631 if (st == M_ST_SUCC) { 632 ui->ui_flags = 1; /* mark it online */ 633 radsize[ui->ui_unit] = (daddr_t)mp->mscp_untsize; 634 printd("uda: unit %d online\n", mp->mscp_unit); 635 /*** New for ***/ printf("uda%d: online, size=%d\n", 636 /*** debugging **/ mp->mscp_unit, (daddr_t)mp->mscp_untsize); 637 } else { 638 harderr(dp->b_actf, "ra"); 639 printf("OFFLINE\n"); 640 while (bp = dp->b_actf) { 641 dp->b_actf = bp->av_forw; 642 bp->b_flags |= B_ERROR; 643 iodone(bp); 644 } 645 } 646 dp->b_active = 1; 647 break; 648 649 case M_OP_AVATN: 650 printd("uda: unit %d attention\n", mp->mscp_unit); 651 ui->ui_flags = 0; /* it went offline and we didn't notice */ 652 break; 653 654 case M_OP_READ|M_OP_END: 655 case M_OP_WRITE|M_OP_END: 656 bp = (struct buf *)mp->mscp_cmdref; 657 ubarelse(um->um_ubanum, (int *)&bp->b_ubinfo); 658 /* 659 * Unlink buffer from I/O wait queue. 660 */ 661 bp->av_back->av_forw = bp->av_forw; 662 bp->av_forw->av_back = bp->av_back; 663 #if defined(VAX750) 664 if (cpu == VAX_750 665 && udwtab[um->um_ctlr].av_forw == &udwtab[um->um_ctlr]) { 666 if (um->um_ubinfo == 0) 667 printf("udintr: um_ubinfo == 0\n"); 668 else 669 ubarelse(um->um_ubanum, &um->um_ubinfo); 670 } 671 #endif 672 dp = &udutab[ui->ui_unit]; 673 if (ui->ui_dk >= 0) 674 if (--dp->b_qsize == 0) 675 dk_busy &= ~(1<<ui->ui_dk); 676 if (st == M_ST_OFFLN || st == M_ST_AVLBL) { 677 ui->ui_flags = 0; /* mark unit offline */ 678 /* 679 * Link the buffer onto the front of the drive queue 680 */ 681 if ((bp->av_forw = dp->b_actf) == 0) 682 dp->b_actl = bp; 683 dp->b_actf = bp; 684 /* 685 * Link the drive onto the controller queue 686 */ 687 if (dp->b_active == 0) { 688 dp->b_forw = NULL; 689 if (um->um_tab.b_actf == NULL) 690 um->um_tab.b_actf = dp; 691 else 692 um->um_tab.b_actl->b_forw = dp; 693 um->um_tab.b_actl = dp; 694 dp->b_active = 1; 695 } 696 #if defined(VAX750) 697 if (cpu == VAX750 && um->um_ubinfo == 0) 698 um->um_ubinfo = 699 uballoc(um->um_ubanum, (caddr_t)0, 0, 700 UBA_NEEDBDP); 701 #endif 702 return; 703 } 704 if (st != M_ST_SUCC) { 705 harderr(bp, "ra"); 706 printf("status %o\n", mp->mscp_status); 707 bp->b_flags |= B_ERROR; 708 } 709 bp->b_resid = bp->b_bcount - mp->mscp_bytecnt; 710 iodone(bp); 711 break; 712 713 case M_OP_GTUNT|M_OP_END: 714 break; 715 716 default: 717 printf("uda: unknown packet\n"); 718 } 719 } 720 721 722 /* 723 * Process an error log message 724 * 725 * For now, just log the error on the console. 726 * Only minimal decoding is done, only "useful" 727 * information is printed. Eventually should 728 * send message to an error logger. 729 */ 730 uderror(um, mp) 731 register struct uba_ctlr *um; 732 register struct mslg *mp; 733 { 734 printf("uda%d: %s error, ", um->um_ctlr, 735 mp->mslg_flags&M_LF_SUCC ? "soft" : "hard"); 736 switch (mp->mslg_format) { 737 case M_FM_CNTERR: 738 printf("controller error, event 0%o\n", mp->mslg_event); 739 break; 740 741 case M_FM_BUSADDR: 742 printf("host memory access error, event 0%o, addr 0%o\n", 743 mp->mslg_event, mp->mslg_busaddr); 744 break; 745 746 case M_FM_DISKTRN: 747 printf("disk transfer error, unit %d, grp 0x%x, hdr 0x%x\n", 748 mp->mslg_unit, mp->mslg_group, mp->mslg_hdr); 749 break; 750 751 case M_FM_SDI: 752 printf("SDI error, unit %d, event 0%o, hdr 0x%x\n", 753 mp->mslg_unit, mp->mslg_event, mp->mslg_hdr); 754 break; 755 756 case M_FM_SMLDSK: 757 printf("small disk error, unit %d, event 0%o, cyl %d\n", 758 mp->mslg_unit, mp->mslg_event, mp->mslg_sdecyl); 759 break; 760 761 default: 762 printf("unknown error, unit %d, format 0%o, event 0%o\n", 763 mp->mslg_unit, mp->mslg_format, mp->mslg_event); 764 } 765 766 if (udaerror) { 767 register long *p = (long *)mp; 768 register int i; 769 770 for (i = 0; i < mp->mslg_header.uda_msglen; i += sizeof(*p)) 771 printf("%x ", *p++); 772 printf("\n"); 773 } 774 } 775 776 777 /* 778 * Find an unused command packet 779 */ 780 struct mscp * 781 udgetcp(um) 782 struct uba_ctlr *um; 783 { 784 register struct mscp *mp; 785 register struct udaca *cp; 786 register struct uda_softc *sc; 787 register int i; 788 789 cp = &uda[um->um_ctlr].uda_ca; 790 sc = &uda_softc[um->um_ctlr]; 791 i = sc->sc_lastcmd; 792 if ((cp->ca_cmddsc[i] & (UDA_OWN|UDA_INT)) == UDA_INT) { 793 cp->ca_cmddsc[i] &= ~UDA_INT; 794 mp = &uda[um->um_ctlr].uda_cmd[i]; 795 mp->mscp_unit = mp->mscp_modifier = 0; 796 mp->mscp_opcode = mp->mscp_flags = 0; 797 mp->mscp_bytecnt = mp->mscp_buffer = 0; 798 mp->mscp_errlgfl = mp->mscp_copyspd = 0; 799 sc->sc_lastcmd = (i + 1) % NCMD; 800 return(mp); 801 } 802 return(NULL); 803 } 804 805 udread(dev, uio) 806 dev_t dev; 807 struct uio *uio; 808 { 809 register int unit = minor(dev) >> 3; 810 811 if (unit >= NRA) 812 return (ENXIO); 813 return (physio(udstrategy, &rudbuf[unit], dev, B_READ, minphys, uio)); 814 } 815 816 udwrite(dev, uio) 817 dev_t dev; 818 struct uio *uio; 819 { 820 register int unit = minor(dev) >> 3; 821 822 if (unit >= NRA) 823 return (ENXIO); 824 return (physio(udstrategy, &rudbuf[unit], dev, B_WRITE, minphys, uio)); 825 } 826 827 udreset(uban) 828 int uban; 829 { 830 register struct uba_ctlr *um; 831 register struct uba_device *ui; 832 register struct buf *bp, *dp; 833 register int unit; 834 struct buf *nbp; 835 int d; 836 837 for (d = 0; d < NUDA; d++) { 838 if ((um = udminfo[d]) == 0 || um->um_ubanum != uban || 839 um->um_alive == 0) 840 continue; 841 printf(" uda%d", d); 842 um->um_tab.b_active = 0; 843 um->um_tab.b_actf = um->um_tab.b_actl = 0; 844 uda_softc[d].sc_state = S_IDLE; 845 for (unit = 0; unit < NRA; unit++) { 846 if ((ui = uddinfo[unit]) == 0) 847 continue; 848 if (ui->ui_alive == 0 || ui->ui_mi != um) 849 continue; 850 udutab[unit].b_active = 0; 851 udutab[unit].b_qsize = 0; 852 } 853 for (bp = udwtab[d].av_forw; bp != &udwtab[d]; bp = nbp) { 854 nbp = bp->av_forw; 855 bp->b_ubinfo = 0; 856 /* 857 * Link the buffer onto the drive queue 858 */ 859 dp = &udutab[dkunit(bp)]; 860 if (dp->b_actf == 0) 861 dp->b_actf = bp; 862 else 863 dp->b_actl->av_forw = bp; 864 dp->b_actl = bp; 865 bp->av_forw = 0; 866 /* 867 * Link the drive onto the controller queue 868 */ 869 if (dp->b_active == 0) { 870 dp->b_forw = NULL; 871 if (um->um_tab.b_actf == NULL) 872 um->um_tab.b_actf = dp; 873 else 874 um->um_tab.b_actl->b_forw = dp; 875 um->um_tab.b_actl = dp; 876 dp->b_active = 1; 877 } 878 } 879 udinit(d); 880 } 881 } 882 883 uddump() 884 { 885 return(ENXIO); 886 } 887