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