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