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