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