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