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