1 /* 2 * @(#)uda.c 6.8 (Berkeley) 08/05/85 3 */ 4 5 /************************************************************************ 6 * * 7 * Copyright (c) 1983 by * 8 * Digital Equipment Corporation, Maynard, MA * 9 * All rights reserved. * 10 * * 11 ************************************************************************/ 12 /* 13 * uda.c - UDA50A Driver 14 * 15 * Date: Jan 30 1984 16 * 17 * This thing has been beaten beyound belief. It still has two main features. 18 * 1) When this device is on the same unibus as another DMA device 19 * like a versatec or a rk07. the Udstrat routine complains that it still 20 * has a buffered data path that it shouldn't. I don't know why. 21 * 22 * decvax!rich. 23 * 24 */ 25 26 #define DEBUG 27 #define UDADEVNUM (9) /* entry in bdevsw */ 28 #include "ra.h" 29 #if NUDA > 0 30 /* 31 * UDA50/RAxx disk device driver 32 * 33 * Restrictions: 34 * Unit numbers must be less than 8. 35 * Partitions A and B must be the same size on all RA drives. 36 */ 37 #include "../machine/pte.h" 38 39 #include "param.h" 40 #include "systm.h" 41 #include "buf.h" 42 #include "conf.h" 43 #include "dir.h" 44 #include "user.h" 45 #include "map.h" 46 #include "vm.h" 47 #include "dk.h" 48 #include "cmap.h" 49 #include "uio.h" 50 51 #include "../vax/cpu.h" 52 #include "ubareg.h" 53 #include "ubavar.h" 54 #include "../vax/mtpr.h" 55 56 #define TENSEC (1000) 57 58 #define NRSPL2 3 /* log2 number of response packets */ 59 #define NCMDL2 3 /* log2 number of command packets */ 60 #define NRSP (1<<NRSPL2) 61 #define NCMD (1<<NCMDL2) 62 63 #include "../vaxuba/udareg.h" 64 #include "../vax/mscp.h" 65 66 67 struct uda_softc { 68 short sc_state; /* state of controller */ 69 short sc_mapped; /* Unibus map allocated for uda struct? */ 70 int sc_ubainfo; /* Unibus mapping info */ 71 struct uda *sc_uda; /* Unibus address of uda struct */ 72 int sc_ivec; /* interrupt vector address */ 73 short sc_credits; /* transfer credits */ 74 short sc_lastcmd; /* pointer into command ring */ 75 short sc_lastrsp; /* pointer into response ring */ 76 } uda_softc[NUDA]; 77 struct uda { 78 struct udaca uda_ca; /* communications area */ 79 struct mscp uda_rsp[NRSP]; /* response packets */ 80 struct mscp uda_cmd[NCMD]; /* command packets */ 81 } uda[NUDA]; 82 83 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 84 struct size { 85 daddr_t nblocks; 86 daddr_t blkoff; 87 } ra25_sizes[8] = { 88 15884, 0, /* A=blk 0 thru 15883 */ 89 10032, 15884, /* B=blk 15884 thru 49323 */ 90 -1, 0, /* C=blk 0 thru end */ 91 0, 0, /* D=blk 340670 thru 356553 */ 92 0, 0, /* E=blk 356554 thru 412489 */ 93 0, 0, /* F=blk 412490 thru end */ 94 -1, 25916, /* G=blk 49324 thru 131403 */ 95 0, 0, /* H=blk 131404 thru end */ 96 }, ra60_sizes[8] = { 97 15884, 0, /* A=blk 0 thru 15883 */ 98 33440, 15884, /* B=blk 15884 thru 49323 */ 99 -1, 0, /* C=blk 0 thru end */ 100 15884, 242606, /* D=blk 242606 thru 258489 */ 101 -1, 258490, /* E=blk 258490 thru end */ 102 0, 0, /* F=unused */ 103 -1, 242606, /* G=blk 242606 thru end */ 104 193282, 49324, /* H=blk 49324 thru 242605 */ 105 }, ra80_sizes[8] = { 106 15884, 0, /* A=blk 0 thru 15883 */ 107 33440, 15884, /* B=blk 15884 thru 49323 */ 108 -1, 0, /* C=blk 0 thru end */ 109 0, 0, /* D=unused */ 110 0, 0, /* E=unused */ 111 0, 0, /* F=unused */ 112 0, 0, /* G=unused */ 113 193282, 49324, /* H=blk 49324 thru 242605 */ 114 }, ra81_sizes[8] ={ 115 15884, 0, /* A=blk 0 thru 15883 */ 116 33440, 15884, /* B=blk 15884 thru 49323 */ 117 -1, 0, /* C=blk 0 thru end */ 118 15884, 242606, /* D=blk 242606 thru 258489 */ 119 307200, 258490, /* E=blk 258490 thru 565689 */ 120 -1, 565690, /* F=blk 565690 thru end */ 121 -1, 242606, /* G=blk 242606 thru end */ 122 193282, 49324, /* H=blk 49324 thru 242605 */ 123 }; 124 125 struct ra_info { 126 struct size *ra_sizes; /* Partion tables for drive */ 127 daddr_t radsize; /* Max user size form online pkt */ 128 unsigned ratype; /* Drive type int field */ 129 unsigned rastatus; /* Command status from */ 130 /* last onlin or GTUNT */ 131 } ra_info[NRA]; 132 133 134 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 135 struct uba_ctlr *udminfo[NUDA]; 136 struct uba_device *uddinfo[NRA]; 137 struct uba_device *udip[NUDA][8]; /* 8 == max number of drives */ 138 struct buf rudbuf[NRA]; 139 struct buf udutab[NRA]; 140 struct buf udwtab[NUDA]; /* I/O wait queue, per controller */ 141 142 143 int nNRA = NRA; 144 int nNUDA = NUDA; 145 int udamicro[NUDA]; /* to store microcode level */ 146 147 148 /* 149 * Controller states 150 */ 151 #define S_IDLE 0 /* hasn't been initialized */ 152 #define S_STEP1 1 /* doing step 1 init */ 153 #define S_STEP2 2 /* doing step 2 init */ 154 #define S_STEP3 3 /* doing step 3 init */ 155 #define S_SCHAR 4 /* doing "set controller characteristics" */ 156 #define S_RUN 5 /* running */ 157 158 159 int udaerror = 0; /* causes hex dump of packets */ 160 int udadebug = 0; 161 int uda_cp_wait = 0; /* Something to wait on for command */ 162 /* packets and or credits. */ 163 int wakeup(); 164 extern int hz; /* Should find the right include */ 165 #ifdef DEBUG 166 #define printd if (udadebug) printf 167 #define printd10 if(udadebug >= 10) printf 168 #endif 169 #define mprintf printf /* temporary JG hack until Rich fixes*/ 170 171 int udprobe(), udslave(), udattach(), udintr(); 172 struct mscp *udgetcp(); 173 174 u_short udstd[] = { 0772150, 0772550, 0777550, 0 }; 175 struct uba_driver udadriver = 176 { udprobe, udslave, udattach, 0, udstd, "ra", uddinfo, "uda", udminfo, 0 }; 177 178 #define b_qsize b_resid /* queue size per drive, in udutab */ 179 #define b_ubinfo b_resid /* Unibus mapping info, per buffer */ 180 181 udprobe(reg, ctlr) 182 caddr_t reg; 183 int ctlr; 184 { 185 register int br, cvec; 186 register struct uda_softc *sc = &uda_softc[ctlr]; 187 struct udadevice *udaddr; 188 189 int cur_time; 190 191 #ifdef lint 192 br = 0; cvec = br; br = cvec; 193 udreset(0); udintr(0); 194 #endif 195 udaddr = (struct udadevice *) reg; 196 197 sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4); 198 udaddr->udaip = 0; /* start initialization */ 199 200 cur_time = mfpr(TODR); /* Time of day */ 201 while(cur_time + TENSEC > mfpr(TODR)){ /* wait for at most 10 secs */ 202 if((udaddr->udasa & UDA_STEP1) != 0) 203 break; 204 } 205 if(cur_time + TENSEC <= mfpr(TODR)) 206 return(0); /* Not a uda or it won't init as it */ 207 /* should within ten seconds. */ 208 udaddr->udasa=UDA_ERR|(NCMDL2<<11)|(NRSPL2<<8)|UDA_IE|(sc->sc_ivec/4); 209 while((udaddr->udasa&UDA_STEP2)==0) 210 DELAY(1000); /* intr should have */ 211 /* have happened by now */ 212 213 return(sizeof (struct udadevice)); 214 } 215 216 udslave(ui, reg) 217 struct uba_device *ui; 218 caddr_t reg; 219 { 220 register struct uba_ctlr *um = udminfo[ui->ui_ctlr]; 221 register struct uda_softc *sc = &uda_softc[ui->ui_ctlr]; 222 struct udadevice *udaddr; 223 struct mscp *mp; 224 int i; /* Something to write into to start */ 225 /* the uda polling */ 226 227 228 #ifdef lint 229 ui = ui; reg = reg; i = i; 230 #endif 231 udaddr = (struct udadevice *)um->um_addr; 232 if(sc->sc_state != S_RUN){ 233 if(!udinit(ui->ui_ctlr)) 234 return(0); 235 } 236 /* Here we will wait for the controller */ 237 /* to come into the run state or go idle. If we go idle we are in */ 238 /* touble and I don't yet know what to do so I will punt */ 239 while(sc->sc_state != S_RUN && sc->sc_state != S_IDLE); /* spin */ 240 if(sc->sc_state == S_IDLE){ /* The Uda failed to initialize */ 241 printf("UDA failed to init\n"); 242 return(0); 243 } 244 /* The controller is up so let see if the drive is there! */ 245 if(0 == (mp = udgetcp(um))){ /* ditto */ 246 printf("UDA can't get command packet\n"); 247 return(0); 248 } 249 mp->mscp_opcode = M_OP_GTUNT; /* This should give us the drive type*/ 250 mp->mscp_unit = ui->ui_slave; 251 mp->mscp_cmdref = (long) ui->ui_slave; 252 #ifdef DEBUG 253 printd("uda%d Get unit status slave %d\n",ui->ui_ctlr,ui->ui_slave); 254 #endif 255 ra_info[ui->ui_unit].rastatus = 0; /* set to zero */ 256 udip[ui->ui_ctlr][ui->ui_slave] = ui; 257 *((long *) mp->mscp_dscptr ) |= UDA_OWN | UDA_INT;/* maybe we should poll*/ 258 i = udaddr->udaip; 259 while(!ra_info[ui->ui_unit].rastatus); /* Wait for some status */ 260 udip[ui->ui_ctlr][ui->ui_slave] = 0; 261 if(!ra_info[ui->ui_unit].ratype) /* packet from a GTUNT */ 262 return(0); /* Failed No such drive */ 263 else 264 return(1); /* Got it and it is there */ 265 } 266 267 udattach(ui) 268 register struct uba_device *ui; 269 { 270 register struct uba_ctlr *um = ui->ui_mi ; 271 struct udadevice *udaddr = (struct udadevice *) um->um_addr; 272 struct mscp *mp; 273 int i; /* Something to write into to start */ 274 /* the uda polling */ 275 #ifdef lint 276 i = i; 277 #endif 278 if (ui->ui_dk >= 0) 279 dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256); /* approx */ 280 ui->ui_flags = 0; 281 udip[ui->ui_ctlr][ui->ui_slave] = ui; 282 /* check to see if the drive is a available if it is bring it online */ 283 /* if not then just return. open will try an online later */ 284 if(ra_info[ui->ui_unit].rastatus != M_ST_AVLBL) 285 return; /* status was set by a GTUNT */ 286 if(0 == (mp = udgetcp(um))){ /* ditto */ 287 printf("UDA can't get command packet\n"); 288 return; 289 } 290 mp->mscp_opcode = M_OP_ONLIN; 291 mp->mscp_unit = ui->ui_slave; 292 mp->mscp_cmdref = (long) ui->ui_slave; 293 #ifdef DEBUG 294 printd("uda%d ONLIN slave %d\n",ui->ui_ctlr,ui->ui_slave); 295 #endif 296 *((long *) mp->mscp_dscptr ) |= UDA_OWN | UDA_INT; 297 i = udaddr->udaip; 298 while(ui->ui_flags == 0 && ra_info[ui->ui_unit].ratype != 0); 299 } 300 301 /* 302 * Open a UDA. Initialize the device and 303 * set the unit online. 304 */ 305 udopen(dev, flag) 306 dev_t dev; 307 int flag; 308 { 309 register int unit; 310 register struct uba_device *ui; 311 register struct uda_softc *sc; 312 register struct mscp *mp; 313 register struct uba_ctlr *um; 314 struct udadevice *udaddr; 315 int s,i; 316 extern quota; 317 318 #ifdef lint 319 flag = flag; i = i; 320 #endif 321 unit = minor(dev) >> 3; 322 if (unit >= nNRA || (ui = uddinfo[unit]) == 0 || ui->ui_alive == 0) 323 return (ENXIO); 324 sc = &uda_softc[ui->ui_ctlr]; 325 s = spl5(); 326 if (sc->sc_state != S_RUN) { 327 if (sc->sc_state == S_IDLE) 328 if(!udinit(ui->ui_ctlr)){ 329 printf("uda: Controller failed to init\n"); 330 return(ENXIO); 331 } 332 /* wait for initialization to complete */ 333 timeout(wakeup,(caddr_t)ui->ui_mi,11*hz); /* to be sure*/ 334 sleep((caddr_t)ui->ui_mi, 0); 335 if (sc->sc_state != S_RUN) 336 { 337 (void) splx(s); /* added by Rich */ 338 return (EIO); 339 } 340 } 341 /* check to see if the device is really there. */ 342 /* this code was taken from Fred Canters 11 driver */ 343 um = ui->ui_mi; 344 udaddr = (struct udadevice *) um->um_addr; 345 (void) splx(s); 346 if(ui->ui_flags == 0){ 347 s = spl5(); 348 while(0 ==(mp = udgetcp(um))){ 349 uda_cp_wait++; 350 sleep(&uda_cp_wait,PSWP+1); 351 uda_cp_wait--; 352 } 353 mp->mscp_opcode = M_OP_ONLIN; 354 mp->mscp_unit = ui->ui_slave; 355 mp->mscp_cmdref = (long) & ra_info[ui->ui_unit].ratype; 356 /* need to sleep on something */ 357 #ifdef DEBUG 358 printd("uda: bring unit %d online\n",ui->ui_unit); 359 #endif 360 *((long *) mp->mscp_dscptr ) |= UDA_OWN | UDA_INT ; 361 i = udaddr->udaip; 362 timeout(wakeup,(caddr_t) mp->mscp_cmdref,10 * hz); 363 /* make sure we wake up */ 364 sleep((caddr_t) mp->mscp_cmdref,PSWP+1); /*wakeup in udrsp() */ 365 (void) splx(s); 366 } 367 if(ui->ui_flags == 0){ 368 return(ENXIO); /* Didn't go online */ 369 } 370 return (0); 371 } 372 373 /* 374 * Initialize a UDA. Set up UBA mapping registers, 375 * initialize data structures, and start hardware 376 * initialization sequence. 377 */ 378 udinit(d) 379 int d; 380 { 381 register struct uda_softc *sc; 382 register struct uda *ud; 383 struct udadevice *udaddr; 384 struct uba_ctlr *um; 385 386 sc = &uda_softc[d]; 387 um = udminfo[d]; 388 um->um_tab.b_active++; 389 ud = &uda[d]; 390 udaddr = (struct udadevice *)um->um_addr; 391 if (sc->sc_mapped == 0) { 392 /* 393 * Map the communications area and command 394 * and response packets into Unibus address 395 * space. 396 */ 397 sc->sc_ubainfo = uballoc(um->um_ubanum, (caddr_t)ud, 398 sizeof (struct uda), 0); 399 sc->sc_uda = (struct uda *)(sc->sc_ubainfo & 0x3ffff); 400 sc->sc_mapped = 1; 401 } 402 403 /* 404 * Start the hardware initialization sequence. 405 */ 406 407 udaddr->udaip = 0; /* start initialization */ 408 409 while((udaddr->udasa & UDA_STEP1) == 0){ 410 if(udaddr->udasa & UDA_ERR) 411 return(0); /* CHECK */ 412 } 413 udaddr->udasa=UDA_ERR|(NCMDL2<<11)|(NRSPL2<<8)|UDA_IE|(sc->sc_ivec/4); 414 /* 415 * Initialization continues in interrupt routine. 416 */ 417 sc->sc_state = S_STEP1; 418 sc->sc_credits = 0; 419 return(1); 420 } 421 422 udstrategy(bp) 423 register struct buf *bp; 424 { 425 register struct uba_device *ui; 426 register struct uba_ctlr *um; 427 register struct buf *dp; 428 register int unit; 429 register struct size *rasizes; 430 int xunit = minor(bp->b_dev) & 07; 431 daddr_t sz, maxsz; 432 int s; 433 434 sz = (bp->b_bcount+511) >> 9; 435 unit = dkunit(bp); 436 if (unit >= nNRA) 437 goto bad; 438 rasizes = ra_info[unit].ra_sizes; 439 ui = uddinfo[unit]; 440 um = ui->ui_mi; 441 if (ui == 0 || ui->ui_alive == 0) 442 goto bad; 443 if ((maxsz = rasizes[xunit].nblocks) < 0) 444 maxsz = ra_info[unit].radsize - rasizes[xunit].blkoff; 445 if (bp->b_blkno < 0 || bp->b_blkno+sz > maxsz || 446 rasizes[xunit].blkoff >= ra_info[unit].radsize) 447 goto bad; 448 s = spl5(); 449 /* 450 * Link the buffer onto the drive queue 451 */ 452 dp = &udutab[ui->ui_unit]; 453 if (dp->b_actf == 0) 454 dp->b_actf = bp; 455 else 456 dp->b_actl->av_forw = bp; 457 dp->b_actl = bp; 458 bp->av_forw = 0; 459 /* 460 * Link the drive onto the controller queue 461 */ 462 if (dp->b_active == 0) { 463 dp->b_forw = NULL; 464 if (um->um_tab.b_actf == NULL) 465 um->um_tab.b_actf = dp; 466 else 467 um->um_tab.b_actl->b_forw = dp; 468 um->um_tab.b_actl = dp; 469 dp->b_active = 1; 470 } 471 if (um->um_tab.b_active == 0) { 472 #if defined(VAX750) 473 if (cpu == VAX_750 474 && udwtab[um->um_ctlr].av_forw == &udwtab[um->um_ctlr]) { 475 if (um->um_ubinfo != 0) { 476 printd("udastrat: ubinfo 0x%x\n",um->um_ubinfo); 477 } else 478 um->um_ubinfo = 479 uballoc(um->um_ubanum, (caddr_t)0, 0, 480 UBA_NEEDBDP); 481 } 482 #endif 483 (void) udstart(um); 484 } 485 splx(s); 486 return; 487 488 bad: 489 bp->b_flags |= B_ERROR; 490 iodone(bp); 491 return; 492 } 493 494 udstart(um) 495 register struct uba_ctlr *um; 496 { 497 register struct buf *bp, *dp; 498 register struct mscp *mp; 499 register struct uda_softc *sc; 500 register struct uba_device *ui; 501 struct size *rasizes; 502 struct udadevice *udaddr; 503 struct uda *ud = &uda[um->um_ctlr]; 504 int i; 505 506 sc = &uda_softc[um->um_ctlr]; 507 508 loop: 509 if ((dp = um->um_tab.b_actf) == NULL) { 510 /* 511 * Release uneeded UBA resources and return 512 */ 513 um->um_tab.b_active = 0; 514 /* Check for response ring transitions lost in the 515 * Race condition 516 */ 517 for (i = sc->sc_lastrsp;; i++) { 518 i %= NRSP; 519 if (ud->uda_ca.ca_rspdsc[i]&UDA_OWN) 520 break; 521 udrsp(um, ud, sc, i); 522 ud->uda_ca.ca_rspdsc[i] |= UDA_OWN; 523 } 524 sc->sc_lastrsp = i; 525 return (0); 526 } 527 if ((bp = dp->b_actf) == NULL) { 528 /* 529 * No more requests for this drive, remove 530 * from controller queue and look at next drive. 531 * We know we're at the head of the controller queue. 532 */ 533 dp->b_active = 0; 534 um->um_tab.b_actf = dp->b_forw; 535 goto loop; /* Need to check for loop */ 536 } 537 um->um_tab.b_active++; 538 udaddr = (struct udadevice *)um->um_addr; 539 if ((udaddr->udasa&UDA_ERR) || sc->sc_state != S_RUN) { 540 harderr(bp, "ra"); 541 mprintf("Uda%d udasa %o, state %d\n",um->um_ctlr , udaddr->udasa&0xffff, sc->sc_state); 542 udinit(um->um_ctlr); 543 /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE UDRESET */ 544 return (0); 545 } 546 ui = uddinfo[dkunit(bp)]; 547 rasizes = ra_info[ui->ui_unit].ra_sizes; 548 if (ui->ui_flags == 0) { /* not online */ 549 if ((mp = udgetcp(um)) == NULL){ 550 return (0); 551 } 552 mp->mscp_opcode = M_OP_ONLIN; 553 mp->mscp_unit = ui->ui_slave; 554 dp->b_active = 2; 555 um->um_tab.b_actf = dp->b_forw; /* remove from controller q */ 556 #ifdef DEBUG 557 printd("uda: bring unit %d online\n", ui->ui_slave); 558 #endif 559 *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT; 560 if (udaddr->udasa&UDA_ERR) 561 printf("Uda (%d) Error (%x)\n",um->um_ctlr , udaddr->udasa&0xffff); 562 i = udaddr->udaip; 563 goto loop; 564 } 565 switch (cpu) { 566 case VAX_8600: 567 case VAX_780: 568 i = UBA_NEEDBDP|UBA_CANTWAIT; 569 break; 570 571 case VAX_750: 572 i = um->um_ubinfo|UBA_HAVEBDP|UBA_CANTWAIT; 573 break; 574 575 case VAX_730: 576 i = UBA_CANTWAIT; 577 break; 578 } 579 if ((i = ubasetup(um->um_ubanum, bp, i)) == 0) { 580 if(dp->b_qsize != 0){ 581 return(0); /* When a command completes and */ 582 /* frees a bdp udstart will be called */ 583 } 584 if ((mp = udgetcp(um)) == NULL){ 585 return (0); 586 } 587 mp->mscp_opcode = M_OP_GTUNT; 588 mp->mscp_unit = ui->ui_slave; 589 *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT; 590 if (udaddr->udasa&UDA_ERR) 591 printf("Uda(%d) udasa (%x)\n",um->um_ctlr, udaddr->udasa&0xffff); 592 i = udaddr->udaip; /* initiate polling */ 593 return(1); /* wait for interrupt */ 594 } 595 if ((mp = udgetcp(um)) == NULL) { 596 ubarelse(um->um_ubanum,&i); 597 return(0); 598 } 599 mp->mscp_cmdref = (long)bp; /* pointer to get back */ 600 mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE; 601 mp->mscp_unit = ui->ui_slave; 602 mp->mscp_lbn = bp->b_blkno + rasizes[minor(bp->b_dev)&7].blkoff; 603 mp->mscp_bytecnt = bp->b_bcount; 604 mp->mscp_buffer = (i & 0x3ffff) | (((i>>28)&0xf)<<24); 605 #if defined(VAX750) 606 if (cpu == VAX_750) 607 i &= 0xfffffff; /* mask off bdp */ 608 #endif 609 bp->b_ubinfo = i; /* save mapping info */ 610 *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT; 611 if (udaddr->udasa&UDA_ERR) 612 printf("Uda(%d) udasa (%x)\n",um->um_ctlr , udaddr->udasa&0xffff); 613 i = udaddr->udaip; /* initiate polling */ 614 dp->b_qsize++; 615 if (ui->ui_dk >= 0) { 616 dk_busy |= 1<<ui->ui_dk; 617 dk_xfer[ui->ui_dk]++; 618 dk_wds[ui->ui_dk] += bp->b_bcount>>6; 619 } 620 621 /* 622 * Move drive to the end of the controller queue 623 */ 624 if (dp->b_forw != NULL) { 625 um->um_tab.b_actf = dp->b_forw; 626 um->um_tab.b_actl->b_forw = dp; 627 um->um_tab.b_actl = dp; 628 dp->b_forw = NULL; 629 } 630 /* 631 * Move buffer to I/O wait queue 632 */ 633 dp->b_actf = bp->av_forw; 634 dp = &udwtab[um->um_ctlr]; 635 bp->av_forw = dp; 636 bp->av_back = dp->av_back; 637 dp->av_back->av_forw = bp; 638 dp->av_back = bp; 639 goto loop; 640 } 641 642 /* 643 * UDA interrupt routine. 644 */ 645 udintr(d) 646 int d; 647 { 648 register struct uba_ctlr *um = udminfo[d]; 649 register struct udadevice *udaddr = (struct udadevice *)um->um_addr; 650 struct buf *bp; 651 register int i; 652 register struct uda_softc *sc = &uda_softc[d]; 653 register struct uda *ud = &uda[d]; 654 struct uda *uud; 655 struct mscp *mp; 656 657 #ifdef DEBUG 658 printd10("udintr: state %d, udasa %o\n", sc->sc_state, udaddr->udasa); 659 #endif 660 switch (sc->sc_state) { 661 case S_IDLE: 662 printf("uda%d: random interrupt ignored\n", d); 663 return; 664 665 case S_STEP1: 666 #define STEP1MASK 0174377 667 #define STEP1GOOD (UDA_STEP2|UDA_IE|(NCMDL2<<3)|NRSPL2) 668 if ((udaddr->udasa&STEP1MASK) != STEP1GOOD) { 669 sc->sc_state = S_IDLE; 670 wakeup((caddr_t)um); 671 return; 672 } 673 udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)| 674 ((cpu == VAX_780) || (cpu == VAX_8600) ? UDA_PI : 0); 675 sc->sc_state = S_STEP2; 676 return; 677 678 case S_STEP2: 679 #define STEP2MASK 0174377 680 #define STEP2GOOD (UDA_STEP3|UDA_IE|(sc->sc_ivec/4)) 681 if ((udaddr->udasa&STEP2MASK) != STEP2GOOD) { 682 sc->sc_state = S_IDLE; 683 wakeup((caddr_t)um); 684 return; 685 } 686 udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)>>16; 687 sc->sc_state = S_STEP3; 688 return; 689 690 case S_STEP3: 691 #define STEP3MASK 0174000 692 #define STEP3GOOD UDA_STEP4 693 if ((udaddr->udasa&STEP3MASK) != STEP3GOOD) { 694 sc->sc_state = S_IDLE; 695 wakeup((caddr_t)um); 696 return; 697 } 698 udamicro[d] = udaddr->udasa; 699 #ifdef DEBUG 700 printd("Uda%d Version %d model %d\n",d,udamicro[d]&0xF, 701 (udamicro[d]>>4) & 0xF); 702 /* 703 * Requesting the error status (|= 2) 704 * may hang older controllers. 705 */ 706 udaddr->udasa = UDA_GO | (udaerror? 2 : 0); 707 #endif 708 udaddr->udasa = UDA_GO; 709 sc->sc_state = S_SCHAR; 710 711 /* 712 * Initialize the data structures. 713 */ 714 uud = sc->sc_uda; 715 for (i = 0; i < NRSP; i++) { 716 ud->uda_ca.ca_rspdsc[i] = UDA_OWN|UDA_INT| 717 (long)&uud->uda_rsp[i].mscp_cmdref; 718 ud->uda_rsp[i].mscp_dscptr = &ud->uda_ca.ca_rspdsc[i]; 719 ud->uda_rsp[i].mscp_header.uda_msglen = mscp_msglen; 720 } 721 for (i = 0; i < NCMD; i++) { 722 ud->uda_ca.ca_cmddsc[i] = UDA_INT| 723 (long)&uud->uda_cmd[i].mscp_cmdref; 724 ud->uda_cmd[i].mscp_dscptr = &ud->uda_ca.ca_cmddsc[i]; 725 ud->uda_cmd[i].mscp_header.uda_msglen = mscp_msglen; 726 } 727 bp = &udwtab[d]; 728 bp->av_forw = bp->av_back = bp; 729 sc->sc_lastcmd = 1; 730 sc->sc_lastrsp = 0; 731 mp = &uda[um->um_ctlr].uda_cmd[0]; 732 mp->mscp_unit = mp->mscp_modifier = 0; 733 mp->mscp_flags = 0; 734 mp->mscp_bytecnt = mp->mscp_buffer = 0; 735 mp->mscp_errlgfl = mp->mscp_copyspd = 0; 736 mp->mscp_opcode = M_OP_STCON; 737 mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS; 738 *((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT; 739 i = udaddr->udaip; /* initiate polling */ 740 return; 741 742 case S_SCHAR: 743 case S_RUN: 744 break; 745 746 default: 747 printf("uda%d: interrupt in unknown state %d ignored\n", 748 d, sc->sc_state); 749 return; 750 } 751 752 if (udaddr->udasa&UDA_ERR) { 753 printf("uda(%d): fatal error (%o)\n", d, udaddr->udasa&0xffff); 754 udaddr->udaip = 0; 755 wakeup((caddr_t)um); 756 } 757 758 /* 759 * Check for a buffer purge request. 760 */ 761 if (ud->uda_ca.ca_bdp) { 762 /* 763 * THIS IS A KLUDGE. 764 * Maybe we should change the entire 765 * UBA interface structure. 766 */ 767 int s = spl6(); /* was spl7 but I don't like turning */ 768 /* off machine checks */ 769 i = um->um_ubinfo; 770 #ifdef DEBUG 771 printd("uda: purge bdp %d\n", ud->uda_ca.ca_bdp); 772 #endif 773 um->um_ubinfo = ud->uda_ca.ca_bdp<<28; 774 ubapurge(um); 775 um->um_ubinfo = i; 776 (void) splx(s); 777 ud->uda_ca.ca_bdp = 0; 778 udaddr->udasa = 0; /* signal purge complete */ 779 } 780 781 /* 782 * Check for response ring transition. 783 */ 784 if (ud->uda_ca.ca_rspint) { 785 ud->uda_ca.ca_rspint = 0; 786 for (i = sc->sc_lastrsp;; i++) { 787 i %= NRSP; 788 if (ud->uda_ca.ca_rspdsc[i]&UDA_OWN) 789 break; 790 udrsp(um, ud, sc, i); 791 ud->uda_ca.ca_rspdsc[i] |= UDA_OWN; 792 } 793 sc->sc_lastrsp = i; 794 } 795 796 /* 797 * Check for command ring transition. 798 */ 799 if (ud->uda_ca.ca_cmdint) { 800 #ifdef DEBUG 801 printd("uda: command ring transition\n"); 802 #endif 803 ud->uda_ca.ca_cmdint = 0; 804 } 805 if(uda_cp_wait) 806 wakeup(&uda_cp_wait); 807 (void) udstart(um); 808 } 809 810 /* 811 * Process a response packet 812 */ 813 udrsp(um, ud, sc, i) 814 register struct uba_ctlr *um; 815 register struct uda *ud; 816 register struct uda_softc *sc; 817 int i; 818 { 819 register struct mscp *mp; 820 struct uba_device *ui; 821 struct buf *dp, *bp,nullbp; 822 int st; 823 824 mp = &ud->uda_rsp[i]; 825 mp->mscp_header.uda_msglen = mscp_msglen; 826 sc->sc_credits += mp->mscp_header.uda_credits & 0xf; /* just 4 bits?*/ 827 if ((mp->mscp_header.uda_credits & 0xf0) > 0x10) /* Check */ 828 return; 829 #ifdef DEBUG 830 printd10("udarsp, opcode 0x%x status 0x%x\n",mp->mscp_opcode,mp->mscp_status); 831 #endif 832 /* 833 * If it's an error log message (datagram), 834 * pass it on for more extensive processing. 835 */ 836 if ((mp->mscp_header.uda_credits & 0xf0) == 0x10) { /* check */ 837 uderror(um, (struct mslg *)mp); 838 return; 839 } 840 st = mp->mscp_status&M_ST_MASK; 841 /* The controller interrupts as drive 0 */ 842 /* this means that you must check for controller interrupts */ 843 /* before you check to see if there is a drive 0 */ 844 if((M_OP_STCON|M_OP_END) == mp->mscp_opcode){ 845 if (st == M_ST_SUCC) 846 sc->sc_state = S_RUN; 847 else 848 sc->sc_state = S_IDLE; 849 um->um_tab.b_active = 0; 850 wakeup((caddr_t)um); 851 return; 852 } 853 if (mp->mscp_unit >= 8) 854 return; 855 if ((ui = udip[um->um_ctlr][mp->mscp_unit]) == 0) 856 return; 857 switch (mp->mscp_opcode) { 858 859 case M_OP_ONLIN|M_OP_END: 860 ra_info[ui->ui_unit].rastatus = st; 861 ra_info[ui->ui_unit].ratype = mp->mscp_mediaid; 862 dp = &udutab[ui->ui_unit]; 863 if (st == M_ST_SUCC) { 864 /* 865 * Link the drive onto the controller queue 866 */ 867 dp->b_forw = NULL; 868 if (um->um_tab.b_actf == NULL) 869 um->um_tab.b_actf = dp; 870 else 871 um->um_tab.b_actl->b_forw = dp; 872 um->um_tab.b_actl = dp; 873 ui->ui_flags = 1; /* mark it online */ 874 ra_info[ui->ui_unit].radsize=(daddr_t)mp->mscp_untsize; 875 #ifdef DEBUG 876 printd("uda: unit %d online\n", mp->mscp_unit); 877 #endif 878 #define F_to_C(x,i) ( ((x)->mscp_mediaid) >> (i*5+7) & 0x1f ? ( ( (((x)->mscp_mediaid) >>( i*5 + 7)) & 0x1f) + 'A' - 1): ' ') 879 /* this mess decodes the Media type identifier */ 880 #ifdef DEBUG 881 printd("uda: unit %d online %x %c%c %c%c%c%d\n" 882 ,mp->mscp_unit, mp->mscp_mediaid 883 ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2) 884 ,F_to_C(mp,1),F_to_C(mp,0) 885 ,mp->mscp_mediaid & 0x7f); 886 #endif 887 switch(mp->mscp_mediaid & 0x7f){ 888 case 25: 889 ra_info[ui->ui_unit].ra_sizes = ra25_sizes; 890 break; 891 case 60: 892 ra_info[ui->ui_unit].ra_sizes = ra60_sizes; 893 break; 894 case 80: 895 ra_info[ui->ui_unit].ra_sizes = ra80_sizes; 896 break; 897 case 81: 898 ra_info[ui->ui_unit].ra_sizes = ra81_sizes; 899 break; 900 default: 901 ui->ui_flags = 0; /* mark it offline */ 902 ra_info[ui->ui_unit].ratype = 0; 903 printf("Don't have a parition table for "); 904 printf("a %c%c %c%c%c%d\n" 905 ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2) 906 ,F_to_C(mp,1),F_to_C(mp,0) 907 ,mp->mscp_mediaid & 0x7f); 908 while (bp = dp->b_actf) { 909 dp->b_actf = bp->av_forw; 910 bp->b_flags |= B_ERROR; 911 iodone(bp); 912 } 913 } 914 dp->b_active = 1; 915 } else { 916 if(dp->b_actf){ 917 harderr(dp->b_actf,"ra"); 918 } else { 919 nullbp.b_blkno = 0; 920 nullbp.b_dev = makedev(UDADEVNUM,ui->ui_unit); 921 harderr(&nullbp, "ra"); 922 } 923 printf("OFFLINE\n"); 924 while (bp = dp->b_actf) { 925 dp->b_actf = bp->av_forw; 926 bp->b_flags |= B_ERROR; 927 iodone(bp); 928 } 929 } 930 if(mp->mscp_cmdref!=NULL){/* Seems to get lost sometimes */ 931 wakeup((caddr_t *) mp->mscp_cmdref); 932 } 933 break; 934 935 /* 936 * The AVAILABLE ATTENTION messages occurs when the 937 * unit becomes available after spinup, 938 * marking the unit offline will force an online command 939 * prior to using the unit. 940 */ 941 case M_OP_AVATN: 942 #ifdef DEBUG 943 printd("uda: unit %d attention\n", mp->mscp_unit); 944 #endif 945 ui->ui_flags = 0; /* it went offline and we didn't notice */ 946 ra_info[ui->ui_unit].ratype = mp->mscp_mediaid; 947 break; 948 949 case M_OP_END: 950 /* 951 * An endcode without an opcode (0200) is an invalid command. 952 * The mscp specification states that this would be a protocol 953 * type error, such as illegal opcodes. The mscp spec. also 954 * states that parameter error type of invalid commands should 955 * return the normal end message for the command. This does not appear 956 * to be the case. An invalid logical block number returned an endcode 957 * of 0200 instead of the 0241 (read) that was expected. 958 */ 959 960 printf("endcd=%o, stat=%o\n", mp->mscp_opcode, mp->mscp_status); 961 break; 962 case M_OP_READ|M_OP_END: 963 case M_OP_WRITE|M_OP_END: 964 bp = (struct buf *)mp->mscp_cmdref; 965 ubarelse(um->um_ubanum, (int *)&bp->b_ubinfo); 966 /* 967 * Unlink buffer from I/O wait queue. 968 */ 969 bp->av_back->av_forw = bp->av_forw; 970 bp->av_forw->av_back = bp->av_back; 971 #if defined(VAX750) 972 if (cpu == VAX_750 973 && udwtab[um->um_ctlr].av_forw == &udwtab[um->um_ctlr]) { 974 if (um->um_ubinfo == 0) 975 printf("udintr: um_ubinfo == 0\n"); 976 else 977 ubarelse(um->um_ubanum, &um->um_ubinfo); 978 } 979 #endif 980 dp = &udutab[ui->ui_unit]; 981 dp->b_qsize--; 982 if (ui->ui_dk >= 0) 983 if (dp->b_qsize == 0) 984 dk_busy &= ~(1<<ui->ui_dk); 985 if (st == M_ST_OFFLN || st == M_ST_AVLBL) { 986 ui->ui_flags = 0; /* mark unit offline */ 987 /* 988 * Link the buffer onto the front of the drive queue 989 */ 990 if ((bp->av_forw = dp->b_actf) == 0) 991 dp->b_actl = bp; 992 dp->b_actf = bp; 993 /* 994 * Link the drive onto the controller queue 995 */ 996 if (dp->b_active == 0) { 997 dp->b_forw = NULL; 998 if (um->um_tab.b_actf == NULL) 999 um->um_tab.b_actf = dp; 1000 else 1001 um->um_tab.b_actl->b_forw = dp; 1002 um->um_tab.b_actl = dp; 1003 dp->b_active = 1; 1004 } 1005 #if defined(VAX750) 1006 if (cpu == VAX750 && um->um_ubinfo == 0) 1007 um->um_ubinfo = 1008 uballoc(um->um_ubanum, (caddr_t)0, 0, 1009 UBA_NEEDBDP); 1010 #endif 1011 return; 1012 } 1013 if (st != M_ST_SUCC) { 1014 harderr(bp, "ra"); 1015 #ifdef DEBUG 1016 printd("status %o\n", mp->mscp_status); 1017 #endif 1018 bp->b_flags |= B_ERROR; 1019 } 1020 bp->b_resid = bp->b_bcount - mp->mscp_bytecnt; 1021 iodone(bp); 1022 break; 1023 1024 case M_OP_GTUNT|M_OP_END: 1025 #ifdef DEBUG 1026 printd("GTUNT end packet status = 0x%x media id 0x%x\n" 1027 ,st,mp->mscp_mediaid); 1028 #endif 1029 ra_info[ui->ui_unit].rastatus = st; 1030 ra_info[ui->ui_unit].ratype = mp->mscp_mediaid; 1031 break; 1032 1033 default: 1034 printf("uda: unknown packet\n"); 1035 uderror(um, (struct mslg *)mp); 1036 } 1037 } 1038 1039 1040 /* 1041 * Process an error log message 1042 * 1043 * For now, just log the error on the console. 1044 * Only minimal decoding is done, only "useful" 1045 * information is printed. Eventually should 1046 * send message to an error logger. 1047 */ 1048 uderror(um, mp) 1049 register struct uba_ctlr *um; 1050 register struct mslg *mp; 1051 { 1052 register i; 1053 1054 1055 if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT))) 1056 printf("uda%d: hard error\n"); 1057 1058 mprintf("uda%d: %s error, ", um->um_ctlr, 1059 mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard"); 1060 switch (mp->mslg_format) { 1061 case M_FM_CNTERR: 1062 mprintf("controller error, event 0%o\n", mp->mslg_event); 1063 break; 1064 1065 case M_FM_BUSADDR: 1066 mprintf("host memory access error, event 0%o, addr 0%o\n", 1067 mp->mslg_event, mp->mslg_busaddr); 1068 break; 1069 1070 case M_FM_DISKTRN: 1071 mprintf("disk transfer error, unit %d, grp 0x%x, hdr 0x%x, event 0%o\n", 1072 mp->mslg_unit, mp->mslg_group, mp->mslg_hdr, 1073 mp->mslg_event); 1074 break; 1075 1076 case M_FM_SDI: 1077 mprintf("SDI error, unit %d, event 0%o, hdr 0x%x\n", 1078 mp->mslg_unit, mp->mslg_event, mp->mslg_hdr); 1079 for(i = 0; i < 12;i++) 1080 mprintf("\t0x%x",mp->mslg_sdistat[i] & 0xff); 1081 mprintf("\n"); 1082 break; 1083 1084 case M_FM_SMLDSK: 1085 mprintf("small disk error, unit %d, event 0%o, cyl %d\n", 1086 mp->mslg_unit, mp->mslg_event, mp->mslg_sdecyl); 1087 break; 1088 1089 default: 1090 mprintf("unknown error, unit %d, format 0%o, event 0%o\n", 1091 mp->mslg_unit, mp->mslg_format, mp->mslg_event); 1092 } 1093 1094 if (udaerror) { 1095 register long *p = (long *)mp; 1096 1097 for (i = 0; i < mp->mslg_header.uda_msglen; i += sizeof(*p)) 1098 printf("%x ", *p++); 1099 printf("\n"); 1100 } 1101 } 1102 1103 1104 /* 1105 * Find an unused command packet 1106 */ 1107 struct mscp * 1108 udgetcp(um) 1109 struct uba_ctlr *um; 1110 { 1111 register struct mscp *mp; 1112 register struct udaca *cp; 1113 register struct uda_softc *sc; 1114 register int i; 1115 int s; 1116 1117 s = spl5(); 1118 cp = &uda[um->um_ctlr].uda_ca; 1119 sc = &uda_softc[um->um_ctlr]; 1120 /* 1121 * If no credits, can't issue any commands 1122 * until some outstanding commands complete. 1123 */ 1124 i = sc->sc_lastcmd; 1125 if(((cp->ca_cmddsc[i]&(UDA_OWN|UDA_INT))==UDA_INT)&& 1126 (sc->sc_credits >= 2)) { 1127 sc->sc_credits--; /* committed to issuing a command */ 1128 cp->ca_cmddsc[i] &= ~UDA_INT; 1129 mp = &uda[um->um_ctlr].uda_cmd[i]; 1130 mp->mscp_unit = mp->mscp_modifier = 0; 1131 mp->mscp_opcode = mp->mscp_flags = 0; 1132 mp->mscp_bytecnt = mp->mscp_buffer = 0; 1133 mp->mscp_errlgfl = mp->mscp_copyspd = 0; 1134 sc->sc_lastcmd = (i + 1) % NCMD; 1135 (void) splx(s); 1136 return(mp); 1137 } 1138 (void) splx(s); 1139 return(NULL); 1140 } 1141 1142 udread(dev, uio) 1143 dev_t dev; 1144 struct uio *uio; 1145 { 1146 register int unit = minor(dev) >> 3; 1147 1148 if (unit >= nNRA) 1149 return (ENXIO); 1150 return (physio(udstrategy, &rudbuf[unit], dev, B_READ, minphys, uio)); 1151 } 1152 1153 udwrite(dev, uio) 1154 dev_t dev; 1155 struct uio *uio; 1156 { 1157 register int unit = minor(dev) >> 3; 1158 1159 if (unit >= nNRA) 1160 return (ENXIO); 1161 return (physio(udstrategy, &rudbuf[unit], dev, B_WRITE, minphys, uio)); 1162 } 1163 1164 udreset(uban) 1165 int uban; 1166 { 1167 register struct uba_ctlr *um; 1168 register struct uba_device *ui; 1169 register struct buf *bp, *dp; 1170 register int unit; 1171 struct buf *nbp; 1172 int d; 1173 1174 for (d = 0; d < NUDA; d++) { 1175 if ((um = udminfo[d]) == 0 || um->um_ubanum != uban || 1176 um->um_alive == 0) 1177 continue; 1178 printf(" uda%d", d); 1179 um->um_tab.b_active = 0; 1180 um->um_tab.b_actf = um->um_tab.b_actl = 0; 1181 uda_softc[d].sc_state = S_IDLE; 1182 uda_softc[d].sc_mapped = 0; /* Rich */ 1183 for (unit = 0; unit < nNRA; unit++) { 1184 if ((ui = uddinfo[unit]) == 0) 1185 continue; 1186 if (ui->ui_alive == 0 || ui->ui_mi != um) 1187 continue; 1188 udutab[unit].b_active = 0; 1189 udutab[unit].b_qsize = 0; 1190 } 1191 for (bp = udwtab[d].av_forw; bp != &udwtab[d]; bp = nbp) { 1192 nbp = bp->av_forw; 1193 bp->b_ubinfo = 0; 1194 /* 1195 * Link the buffer onto the drive queue 1196 */ 1197 dp = &udutab[dkunit(bp)]; 1198 if (dp->b_actf == 0) 1199 dp->b_actf = bp; 1200 else 1201 dp->b_actl->av_forw = bp; 1202 dp->b_actl = bp; 1203 bp->av_forw = 0; 1204 /* 1205 * Link the drive onto the controller queue 1206 */ 1207 if (dp->b_active == 0) { 1208 dp->b_forw = NULL; 1209 if (um->um_tab.b_actf == NULL) 1210 um->um_tab.b_actf = dp; 1211 else 1212 um->um_tab.b_actl->b_forw = dp; 1213 um->um_tab.b_actl = dp; 1214 dp->b_active = 1; 1215 } 1216 } 1217 udinit(d); 1218 } 1219 } 1220 1221 #define DBSIZE 32 1222 1223 #define ca_Rspdsc ca_rspdsc[0] 1224 #define ca_Cmddsc ca_rspdsc[1] 1225 #define uda_Rsp uda_rsp[0] 1226 #define uda_Cmd uda_cmd[0] 1227 1228 struct uda udad[NUDA]; 1229 1230 uddump(dev) 1231 dev_t dev; 1232 { 1233 struct udadevice *udaddr; 1234 struct uda *ud_ubaddr; 1235 char *start; 1236 int num, blk, unit; 1237 int maxsz; 1238 int blkoff; 1239 register struct uba_regs *uba; 1240 register struct uba_device *ui; 1241 register struct uda *udp; 1242 register struct pte *io; 1243 register int i; 1244 struct size *rasizes; 1245 unit = minor(dev) >> 3; 1246 if (unit >= nNRA) 1247 return (ENXIO); 1248 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 1249 ui = phys(struct uba_device *, uddinfo[unit]); 1250 if (ui->ui_alive == 0) 1251 return (ENXIO); 1252 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 1253 ubainit(uba); 1254 udaddr = (struct udadevice *)ui->ui_physaddr; 1255 DELAY(2000000); 1256 udp = phys(struct uda *, &udad[ui->ui_ctlr]); 1257 1258 num = btoc(sizeof(struct uda)) + 1; 1259 io = &uba->uba_map[NUBMREG-num]; 1260 for(i = 0; i<num; i++) 1261 *(int *)io++ = UBAMR_MRV|(btop(udp)+i); 1262 ud_ubaddr = (struct uda *)(((int)udp & PGOFSET)|((NUBMREG-num)<<9)); 1263 1264 udaddr->udaip = 0; 1265 while ((udaddr->udasa & UDA_STEP1) == 0) 1266 if(udaddr->udasa & UDA_ERR) return(EFAULT); 1267 udaddr->udasa = UDA_ERR; 1268 while ((udaddr->udasa & UDA_STEP2) == 0) 1269 if(udaddr->udasa & UDA_ERR) return(EFAULT); 1270 udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase; 1271 while ((udaddr->udasa & UDA_STEP3) == 0) 1272 if(udaddr->udasa & UDA_ERR) return(EFAULT); 1273 udaddr->udasa = (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16); 1274 while ((udaddr->udasa & UDA_STEP4) == 0) 1275 if(udaddr->udasa & UDA_ERR) return(EFAULT); 1276 udaddr->udasa = UDA_GO; 1277 udp->uda_ca.ca_Rspdsc = (long)&ud_ubaddr->uda_Rsp.mscp_cmdref; 1278 udp->uda_ca.ca_Cmddsc = (long)&ud_ubaddr->uda_Cmd.mscp_cmdref; 1279 udp->uda_Cmd.mscp_cntflgs = 0; 1280 udp->uda_Cmd.mscp_version = 0; 1281 if (udcmd(M_OP_STCON, udp, udaddr) == 0) { 1282 return(EFAULT); 1283 } 1284 udp->uda_Cmd.mscp_unit = ui->ui_slave; 1285 if (udcmd(M_OP_ONLIN, udp, udaddr) == 0) { 1286 return(EFAULT); 1287 } 1288 1289 num = maxfree; 1290 start = 0; 1291 rasizes = ra_info[ui->ui_unit].ra_sizes; 1292 maxsz = rasizes[minor(dev)&07].nblocks; 1293 blkoff = rasizes[minor(dev)&07].blkoff; 1294 if(maxsz < 0) 1295 maxsz = ra_info[unit].radsize-blkoff; 1296 if (dumplo < 0 || dumplo + num >= maxsz) 1297 return (EINVAL); 1298 blkoff += dumplo; 1299 while (num > 0) { 1300 blk = num > DBSIZE ? DBSIZE : num; 1301 io = uba->uba_map; 1302 for (i = 0; i < blk; i++) 1303 *(int *)io++ = (btop(start)+i) | UBAMR_MRV; 1304 *(int *)io = 0; 1305 udp->uda_Cmd.mscp_lbn = btop(start) + blkoff; 1306 udp->uda_Cmd.mscp_unit = ui->ui_slave; 1307 udp->uda_Cmd.mscp_bytecnt = blk*NBPG; 1308 udp->uda_Cmd.mscp_buffer = 0; 1309 if (udcmd(M_OP_WRITE, udp, udaddr) == 0) { 1310 return(EIO); 1311 } 1312 start += blk*NBPG; 1313 num -= blk; 1314 } 1315 return (0); 1316 } 1317 1318 1319 udcmd(op, udp, udaddr) 1320 int op; 1321 register struct uda *udp; 1322 struct udadevice *udaddr; 1323 { 1324 int i; 1325 1326 #ifdef lint 1327 i = i; 1328 #endif 1329 1330 udp->uda_Cmd.mscp_opcode = op; 1331 udp->uda_Rsp.mscp_header.uda_msglen = mscp_msglen; 1332 udp->uda_Cmd.mscp_header.uda_msglen = mscp_msglen; 1333 udp->uda_ca.ca_Rspdsc |= UDA_OWN|UDA_INT; 1334 udp->uda_ca.ca_Cmddsc |= UDA_OWN|UDA_INT; 1335 if (udaddr->udasa&UDA_ERR) 1336 printf("Udaerror udasa (%x)\n", udaddr->udasa&0xffff); 1337 i = udaddr->udaip; 1338 for (;;) { 1339 if (udp->uda_ca.ca_cmdint) 1340 udp->uda_ca.ca_cmdint = 0; 1341 if (udp->uda_ca.ca_rspint) 1342 break; 1343 } 1344 udp->uda_ca.ca_rspint = 0; 1345 if (udp->uda_Rsp.mscp_opcode != (op|M_OP_END) || 1346 (udp->uda_Rsp.mscp_status&M_ST_MASK) != M_ST_SUCC) { 1347 printf("error: com %d opc 0x%x stat 0x%x\ndump ", 1348 op, 1349 udp->uda_Rsp.mscp_opcode, 1350 udp->uda_Rsp.mscp_status); 1351 return(0); 1352 } 1353 return(1); 1354 } 1355 1356 udsize(dev) 1357 dev_t dev; 1358 { 1359 int unit = minor(dev) >> 3; 1360 struct uba_device *ui; 1361 struct size *rasizes; 1362 1363 if (unit >= nNRA || (ui = uddinfo[unit]) == 0 || ui->ui_alive == 0 1364 || ui->ui_flags == 0) 1365 return (-1); 1366 rasizes = ra_info[ui->ui_unit].ra_sizes; 1367 return (rasizes[minor(dev) & 07].nblocks); 1368 } 1369 1370 #endif 1371