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