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