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