1*26199Ssklower /* 2*26199Ssklower * Copyright (c) 1986 MICOM-Interlan, Inc., Foxborough Mass 3*26199Ssklower * 4*26199Ssklower * This software is furnished under a license and may only be used 5*26199Ssklower * or copied in accordance with the terms of that license. 6*26199Ssklower * 7*26199Ssklower * @(#)np.c 6.1 (Berkeley) 02/17/86 8*26199Ssklower */ 9*26199Ssklower 10*26199Ssklower /****************************************** 11*26199Ssklower * * 12*26199Ssklower * NPDRIVER * 13*26199Ssklower * * 14*26199Ssklower ******************************************/ 15*26199Ssklower 16*26199Ssklower /* 17*26199Ssklower * The NP Driver is used to route requests, independent of protocol type, 18*26199Ssklower * to the NP series Intelligent Board. The facilities it provides are 19*26199Ssklower * used for board maintainance by the superuser and by protocol pseudo-drivers, 20*26199Ssklower * such as WN, for sending requests to a board. The board maintainance and 21*26199Ssklower * control functions are accessed via npioctl() by the NP support utilities. 22*26199Ssklower */ 23*26199Ssklower 24*26199Ssklower 25*26199Ssklower /* 26*26199Ssklower * Include Files 27*26199Ssklower */ 28*26199Ssklower 29*26199Ssklower #include "np.h" 30*26199Ssklower #if NNP > 0 31*26199Ssklower #include "param.h" 32*26199Ssklower #include "buf.h" 33*26199Ssklower #include "signal.h" 34*26199Ssklower #include "systm.h" 35*26199Ssklower #include "dir.h" 36*26199Ssklower #include "user.h" 37*26199Ssklower #include "proc.h" 38*26199Ssklower #include "uio.h" 39*26199Ssklower #include "errno.h" 40*26199Ssklower 41*26199Ssklower #include "../vaxuba/ubavar.h" 42*26199Ssklower #include "../vaxuba/npreg.h" 43*26199Ssklower 44*26199Ssklower /* 45*26199Ssklower * Global variables for pseudo-drivers. 46*26199Ssklower */ 47*26199Ssklower 48*26199Ssklower int WnInitFlag; 49*26199Ssklower int IsInitFlag; 50*26199Ssklower 51*26199Ssklower /* 52*26199Ssklower * Debugging level. 53*26199Ssklower */ 54*26199Ssklower 55*26199Ssklower int NpDebug = 0; 56*26199Ssklower 57*26199Ssklower /* Driver Wide State used by the ICP */ 58*26199Ssklower 59*26199Ssklower int NpState = NPCLEAR; 60*26199Ssklower 61*26199Ssklower 62*26199Ssklower /* 63*26199Ssklower * Master structure, one per board, contains request queue header, 64*26199Ssklower * shared memory address, and memory mapping information. 65*26199Ssklower */ 66*26199Ssklower 67*26199Ssklower struct npmaster npmasters[NNP]; 68*26199Ssklower 69*26199Ssklower /* Structure of the shared memory area */ 70*26199Ssklower 71*26199Ssklower static struct npspace npspaces[NNP]; 72*26199Ssklower 73*26199Ssklower /* Panic Message data structures */ 74*26199Ssklower 75*26199Ssklower static int panicmap; /* Mapping information */ 76*26199Ssklower static char NpPbuf[PANLEN] = 0; /* Panic message buffer */ 77*26199Ssklower static caddr_t pstring; /* Panic string address on board, absolute */ 78*26199Ssklower static unsign16 panaddr[2]; /* Panic string address on board (seg/offset) */ 79*26199Ssklower 80*26199Ssklower /* Driver Wide Connection Table */ 81*26199Ssklower 82*26199Ssklower static struct npconn npcnxtab[NNP][NNPCNN]; 83*26199Ssklower 84*26199Ssklower /* Head of the request queue, one per board */ 85*26199Ssklower 86*26199Ssklower static struct npreq reqhdr[NNP]; 87*26199Ssklower 88*26199Ssklower /* The request structures, one pool per board */ 89*26199Ssklower 90*26199Ssklower static struct npreq npreqs[NNP][NUMCQE]; 91*26199Ssklower 92*26199Ssklower 93*26199Ssklower /* 94*26199Ssklower * Data structures needed for BSD 4.2 Device Drivers 95*26199Ssklower */ 96*26199Ssklower 97*26199Ssklower int npprobe(), npattach(), npintr(); 98*26199Ssklower struct uba_device *npdinfo[NNP]; 99*26199Ssklower 100*26199Ssklower /* UNIBUS address of Network Processors */ 101*26199Ssklower 102*26199Ssklower u_short npstd[] = { 0166000, 0166020, 0 }; 103*26199Ssklower 104*26199Ssklower /* Interrupt vectors used by the Network Processors */ 105*26199Ssklower 106*26199Ssklower static unsign16 npvectors[NNP]; 107*26199Ssklower 108*26199Ssklower struct uba_driver npdriver = 109*26199Ssklower { npprobe, 0, npattach, 0, npstd, "np", npdinfo }; 110*26199Ssklower struct buf np_tab[NNP]; 111*26199Ssklower 112*26199Ssklower 113*26199Ssklower /* 114*26199Ssklower * External function and data structure declarations. 115*26199Ssklower */ 116*26199Ssklower 117*26199Ssklower struct npreq * NpGetReq(); 118*26199Ssklower struct npmaster *NpBoardChange(); 119*26199Ssklower int NpTimer(); 120*26199Ssklower struct CQE * NpRemCQE(); 121*26199Ssklower int (*IxAttach)(); 122*26199Ssklower int (*IxReset)(); 123*26199Ssklower 124*26199Ssklower extern struct user u; 125*26199Ssklower 126*26199Ssklower /* 127*26199Ssklower * Np_init() is responsible for hardware initializiation and the software 128*26199Ssklower * initialization of the connection table and driver software data structures. 129*26199Ssklower */ 130*26199Ssklower 131*26199Ssklower npinit(unit) 132*26199Ssklower int unit; 133*26199Ssklower { 134*26199Ssklower register int j; 135*26199Ssklower 136*26199Ssklower 137*26199Ssklower /* Software Initialization */ 138*26199Ssklower 139*26199Ssklower npmasters[unit].flags = NPCLEAR; 140*26199Ssklower 141*26199Ssklower NpSWinit(unit); 142*26199Ssklower 143*26199Ssklower /* Hardware Initialization */ 144*26199Ssklower 145*26199Ssklower NpHWinit(unit); 146*26199Ssklower 147*26199Ssklower /* Connection Table Initialization */ 148*26199Ssklower 149*26199Ssklower for(j=0;j<NNPCNN;j++) { 150*26199Ssklower npcnxtab[unit][j].protocol = NPCLCONN; 151*26199Ssklower npcnxtab[unit][j].unit = &npmasters[unit]; 152*26199Ssklower } 153*26199Ssklower } 154*26199Ssklower 155*26199Ssklower /* 156*26199Ssklower * Np_open establishes a connection to the NP Driver using the minor 157*26199Ssklower * device number as an identifier. A default protocol, NPMAINT, is assigned 158*26199Ssklower * with the specified unit. Protocol and unit may be changed using the 159*26199Ssklower * NpProtChange and NpBoardChange functions. 160*26199Ssklower * Since the maintainance protocol does not need a working I-Board, entries 161*26199Ssklower * are always made in the Connection Table, npcnxtab, if the board exists. 162*26199Ssklower */ 163*26199Ssklower 164*26199Ssklower /*ARGSUSED*/ 165*26199Ssklower npopen(dev,flag) 166*26199Ssklower dev_t dev; 167*26199Ssklower int flag; 168*26199Ssklower { 169*26199Ssklower int unit; 170*26199Ssklower unsign16 conn; 171*26199Ssklower struct npmaster *mp; 172*26199Ssklower int error; 173*26199Ssklower 174*26199Ssklower if(NpDebug & DEBENTRY) 175*26199Ssklower printf("npopen\n"); 176*26199Ssklower 177*26199Ssklower /* Clear error */ 178*26199Ssklower 179*26199Ssklower error = 0; 180*26199Ssklower 181*26199Ssklower /* Make sure it's the superuser */ 182*26199Ssklower 183*26199Ssklower if(u.u_uid) 184*26199Ssklower return(EPERM); 185*26199Ssklower 186*26199Ssklower /* Get the connection identifier */ 187*26199Ssklower 188*26199Ssklower if(((conn = NPCONN(dev)) >= NNPCNN) || 189*26199Ssklower ((unit = NPUNIT(dev)) >= NNP)) 190*26199Ssklower return(ENODEV); 191*26199Ssklower 192*26199Ssklower 193*26199Ssklower if(NpDebug & DEBOPEN) 194*26199Ssklower printf("conn = %x unit = %d\n",conn,unit); 195*26199Ssklower 196*26199Ssklower /* Get the board for the specified unit */ 197*26199Ssklower 198*26199Ssklower mp = NpBoardChange(NPMAINT,unit); 199*26199Ssklower 200*26199Ssklower if(mp != (struct npmaster *) 0) { 201*26199Ssklower npcnxtab[unit][conn].unit = mp; 202*26199Ssklower npcnxtab[unit][conn].protocol = NPMAINT; 203*26199Ssklower } 204*26199Ssklower else error = ENXIO; 205*26199Ssklower 206*26199Ssklower if(NpDebug & DEBENTRY) 207*26199Ssklower printf("npopen...\n"); 208*26199Ssklower 209*26199Ssklower return(error); 210*26199Ssklower } 211*26199Ssklower 212*26199Ssklower /* 213*26199Ssklower * Np_close is responsible updating the connection table for 214*26199Ssklower * that connection by marking it closed. 215*26199Ssklower */ 216*26199Ssklower 217*26199Ssklower npclose(dev) 218*26199Ssklower dev_t dev; 219*26199Ssklower { 220*26199Ssklower 221*26199Ssklower if(NpDebug & DEBENTRY) 222*26199Ssklower printf("npclose\n"); 223*26199Ssklower 224*26199Ssklower /* Get the connection identifier */ 225*26199Ssklower 226*26199Ssklower npcnxtab[NPUNIT(dev)][NPCONN(dev)].protocol = NPCLCONN; 227*26199Ssklower 228*26199Ssklower if(NpDebug & DEBENTRY) 229*26199Ssklower printf("npclose...\n"); 230*26199Ssklower 231*26199Ssklower return(0); 232*26199Ssklower 233*26199Ssklower } 234*26199Ssklower 235*26199Ssklower /* 236*26199Ssklower * Npioctl is the main conduit of commands between the I-Board and the 237*26199Ssklower * NP support utilities. Relevant information for the request is found in the 238*26199Ssklower * cmd and addr parameters. Cmd specifies the function to perform, addr is 239*26199Ssklower * command specific. Npioctl returns 0 if successful, or an error number 240*26199Ssklower * (which winds up in errno). 241*26199Ssklower */ 242*26199Ssklower 243*26199Ssklower /*ARGSUSED*/ 244*26199Ssklower npioctl(dev,cmd,addr,flag) 245*26199Ssklower dev_t dev; 246*26199Ssklower int cmd; 247*26199Ssklower caddr_t *addr; 248*26199Ssklower int flag; 249*26199Ssklower { 250*26199Ssklower unsign16 protocol; 251*26199Ssklower unsign16 conn; 252*26199Ssklower unsign16 unit; 253*26199Ssklower int error; 254*26199Ssklower 255*26199Ssklower register struct npmaster *mp; 256*26199Ssklower register struct npreq *rp; 257*26199Ssklower unsigned usrarg; 258*26199Ssklower 259*26199Ssklower if(NpDebug & DEBENTRY) 260*26199Ssklower printf("npioctl\n"); 261*26199Ssklower 262*26199Ssklower /* Clear error */ 263*26199Ssklower 264*26199Ssklower error = 0; 265*26199Ssklower 266*26199Ssklower /* Strip off IOC_VOID bit */ 267*26199Ssklower 268*26199Ssklower cmd &= CMDMASK; 269*26199Ssklower 270*26199Ssklower /* Get connection identifier */ 271*26199Ssklower 272*26199Ssklower conn = NPCONN(dev); 273*26199Ssklower unit = NPUNIT(dev); 274*26199Ssklower 275*26199Ssklower /* Master pointer for this unit */ 276*26199Ssklower 277*26199Ssklower mp = npcnxtab[unit][conn].unit; 278*26199Ssklower 279*26199Ssklower protocol = npcnxtab[unit][conn].protocol; 280*26199Ssklower 281*26199Ssklower /* Get a request structure from the pool and initialize it */ 282*26199Ssklower 283*26199Ssklower while((rp = NpGetReq(mp->reqtab)) == NULL) { 284*26199Ssklower mp->reqtab->flags |= WANTREQ; 285*26199Ssklower sleep((caddr_t)(mp->reqtab),PZERO -1); 286*26199Ssklower } 287*26199Ssklower 288*26199Ssklower if(NpDebug & DEBREQ) 289*26199Ssklower printf("NP Reqp is %x\n",rp); 290*26199Ssklower 291*26199Ssklower /* Initializations of request structure */ 292*26199Ssklower 293*26199Ssklower rp->intr = (int (*)())0; /* Do not call interrupt routine */ 294*26199Ssklower rp->bufoffset = 0; /* Offset into data buffer */ 295*26199Ssklower rp->flags = NPCLEAR; /* Clear flags */ 296*26199Ssklower rp->procp = u.u_procp; /* Process structure for this user */ 297*26199Ssklower 298*26199Ssklower /* Copy in user's argument to ioctl() call */ 299*26199Ssklower 300*26199Ssklower if(error = copyin(*addr,&usrarg,sizeof(usrarg))) 301*26199Ssklower return(error); 302*26199Ssklower 303*26199Ssklower 304*26199Ssklower if(NpDebug & DEBIOCTL) 305*26199Ssklower printf("arg = %x\n",usrarg); 306*26199Ssklower 307*26199Ssklower /* Execute the specified command */ 308*26199Ssklower 309*26199Ssklower switch(cmd) { 310*26199Ssklower 311*26199Ssklower case NPSETPROT: 312*26199Ssklower if((error = NpProtChange(usrarg,mp->unit)) == 0) 313*26199Ssklower npcnxtab[unit][conn].protocol = usrarg; 314*26199Ssklower break; 315*26199Ssklower case NPSETBOARD: 316*26199Ssklower if(mp = NpBoardChange(protocol,usrarg)) 317*26199Ssklower npcnxtab[unit][conn].unit = mp; 318*26199Ssklower else { 319*26199Ssklower mp = npcnxtab[unit][conn].unit; 320*26199Ssklower error = ENXIO; 321*26199Ssklower } 322*26199Ssklower break; 323*26199Ssklower case NPRESET: 324*26199Ssklower error = NpReset(mp,rp); 325*26199Ssklower break; 326*26199Ssklower case NPSETNPDEB: 327*26199Ssklower NpDebug = usrarg; 328*26199Ssklower break; 329*26199Ssklower case NPINIT: 330*26199Ssklower error = NpSWinit(mp->unit); 331*26199Ssklower break; 332*26199Ssklower case NPSTART: 333*26199Ssklower 334*26199Ssklower #ifdef OLDROM 335*26199Ssklower /* 336*26199Ssklower * Kludge to work around I-Board boot from Host. Read two bytes 337*26199Ssklower * from the board into the Device Configuration Word 338*26199Ssklower * in Shared Memory. 339*26199Ssklower */ 340*26199Ssklower 341*26199Ssklower NPIO(mp,(paddr_t)0x500,(paddr_t)(&mp->shmemp->statblock.sb_dcw),2,B_READ); 342*26199Ssklower 343*26199Ssklower mp->shmemp->statblock.sb_drw = 0; 344*26199Ssklower #endif 345*26199Ssklower 346*26199Ssklower /* Set the Address at which to begin On-Board execution */ 347*26199Ssklower 348*26199Ssklower error = NpSetXeqAddr(mp,(caddr_t)usrarg); 349*26199Ssklower break; 350*26199Ssklower case NPSTATS: 351*26199Ssklower error = NpStats(); 352*26199Ssklower break; 353*26199Ssklower case NPGPANIC: 354*26199Ssklower error = copyout((caddr_t)NpPbuf,*addr,PANLEN); 355*26199Ssklower 356*26199Ssklower /* Clear panic request flag and leave */ 357*26199Ssklower 358*26199Ssklower mp->flags &= ~PANICREQ; 359*26199Ssklower break; 360*26199Ssklower case NPPOLL: 361*26199Ssklower error = NpPoll(mp,*addr); 362*26199Ssklower break; 363*26199Ssklower case NPKILL: 364*26199Ssklower error = NpKill(mp,rp); 365*26199Ssklower break; 366*26199Ssklower case NPSETADDR: 367*26199Ssklower error = NpSetMemAddr(mp,*addr); 368*26199Ssklower break; 369*26199Ssklower case NPRCSR0: 370*26199Ssklower usrarg = RCSR0(mp->iobase); 371*26199Ssklower error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 372*26199Ssklower break; 373*26199Ssklower case NPRCSR1: 374*26199Ssklower usrarg = RCSR1(mp->iobase); 375*26199Ssklower error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 376*26199Ssklower break; 377*26199Ssklower case NPRCSR2: 378*26199Ssklower usrarg = RCSR2(mp->iobase); 379*26199Ssklower error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 380*26199Ssklower break; 381*26199Ssklower case NPRCSR3: 382*26199Ssklower usrarg = RCSR3(mp->iobase); 383*26199Ssklower error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 384*26199Ssklower break; 385*26199Ssklower case NPWCSR0: 386*26199Ssklower WCSR0(mp->iobase,usrarg); 387*26199Ssklower break; 388*26199Ssklower case NPWCSR1: 389*26199Ssklower WCSR1(mp->iobase,usrarg); 390*26199Ssklower break; 391*26199Ssklower case NPWCSR2: 392*26199Ssklower WCSR2(mp->iobase,usrarg); 393*26199Ssklower break; 394*26199Ssklower case NPWCSR3: 395*26199Ssklower WCSR3(mp->iobase,usrarg); 396*26199Ssklower break; 397*26199Ssklower case NPNETBOOT: 398*26199Ssklower error = NpSetIntLevel(mp,mp->vector); 399*26199Ssklower if(error) break; 400*26199Ssklower error = NpSetXeqAddr(mp,(caddr_t)INETBOOT); 401*26199Ssklower break; 402*26199Ssklower default: 403*26199Ssklower printf("Bad Maintenance command: %d!\n",cmd); 404*26199Ssklower error = EIO; 405*26199Ssklower break; 406*26199Ssklower 407*26199Ssklower } 408*26199Ssklower if((cmd != NPRESET) && (cmd != NPINIT)) 409*26199Ssklower NpFreeReq(mp->reqtab,rp); 410*26199Ssklower 411*26199Ssklower if(NpDebug & DEBENTRY) 412*26199Ssklower printf("npioctl...\n"); 413*26199Ssklower 414*26199Ssklower return(error); 415*26199Ssklower } 416*26199Ssklower 417*26199Ssklower /* 418*26199Ssklower * np_start - start io activity 419*26199Ssklower */ 420*26199Ssklower npstart(mp) 421*26199Ssklower register struct npmaster *mp; 422*26199Ssklower { 423*26199Ssklower 424*26199Ssklower register struct buf *bp; 425*26199Ssklower register struct npreq *rp; 426*26199Ssklower 427*26199Ssklower int error; /* Return from NPIO call */ 428*26199Ssklower 429*26199Ssklower if(NpDebug & DEBENTRY) 430*26199Ssklower printf("npstart\n"); 431*26199Ssklower 432*26199Ssklower if((bp = np_tab[mp->unit].b_actf) == (struct buf *)0) { 433*26199Ssklower np_tab[mp->unit].b_active = 0; 434*26199Ssklower return; 435*26199Ssklower } 436*26199Ssklower if((rp = (struct npreq *)(bp->av_back)) == (struct npreq *)0) { 437*26199Ssklower bp->b_flags = B_ERROR; 438*26199Ssklower iodone(bp); 439*26199Ssklower return; 440*26199Ssklower } 441*26199Ssklower np_tab[mp->unit].b_active = 1; 442*26199Ssklower 443*26199Ssklower if(NpDebug & DEBIO) 444*26199Ssklower printf("NP IO src %x dst = %x cnt = %x\n",bp->b_un.b_addr,bp->b_blkno << DEV_BSHIFT,bp->b_bcount); 445*26199Ssklower 446*26199Ssklower /* Send the request to the board via the CSR0 command interface */ 447*26199Ssklower 448*26199Ssklower if(bp->b_flags & B_READ) 449*26199Ssklower 450*26199Ssklower error = NPIO(mp,(paddr_t)((long)bp->b_blkno << DEV_BSHIFT),(paddr_t)(rp->bufaddr), 451*26199Ssklower bp->b_bcount,(bp->b_flags & B_READ)); 452*26199Ssklower 453*26199Ssklower else 454*26199Ssklower error = NPIO(mp,(paddr_t)(rp->bufaddr),(paddr_t)((long)bp->b_blkno << DEV_BSHIFT), 455*26199Ssklower bp->b_bcount,(bp->b_flags & B_READ)); 456*26199Ssklower 457*26199Ssklower 458*26199Ssklower /* Check return from I/O */ 459*26199Ssklower 460*26199Ssklower if(error) { 461*26199Ssklower bp->b_flags |= B_ERROR; 462*26199Ssklower np_tab[mp->unit].b_actf = bp->av_forw; 463*26199Ssklower 464*26199Ssklower if(NpDebug & DEBIO) 465*26199Ssklower printf("NPIO return error: b_flags is %x \n",bp->b_flags); 466*26199Ssklower iodone(bp); 467*26199Ssklower } 468*26199Ssklower 469*26199Ssklower if(NpDebug & DEBENTRY) 470*26199Ssklower printf("npstart...\n"); 471*26199Ssklower 472*26199Ssklower } 473*26199Ssklower /* 474*26199Ssklower * npstratagey - the strategy routine 475*26199Ssklower */ 476*26199Ssklower 477*26199Ssklower npstrategy(bp) 478*26199Ssklower register struct buf *bp; 479*26199Ssklower { 480*26199Ssklower 481*26199Ssklower register struct buf *ip; /* quick pointer */ 482*26199Ssklower register struct npmaster *mp; /* master structure for this device */ 483*26199Ssklower register struct npreq *rp; /* reqest struct pointer */ 484*26199Ssklower int s; /* priority to return to */ 485*26199Ssklower 486*26199Ssklower if(NpDebug & DEBENTRY) 487*26199Ssklower printf("npstrategy\n"); 488*26199Ssklower if(NpDebug & DEBIO) 489*26199Ssklower printf("flag = %x count = %x paddr = %x %x blkno = %x %x\n", 490*26199Ssklower bp->b_flags,bp->b_bcount,bp->b_un.b_addr,bp->b_un.b_addr,bp->b_blkno,bp->b_blkno); 491*26199Ssklower 492*26199Ssklower /* get master structure */ 493*26199Ssklower 494*26199Ssklower mp = npcnxtab[NPUNIT(bp->b_dev)][NPCONN(bp->b_dev)].unit; 495*26199Ssklower 496*26199Ssklower /* make sure the boards ok */ 497*26199Ssklower 498*26199Ssklower if (mp->flags & BADBOARD) { 499*26199Ssklower bp->b_flags |= B_ERROR; 500*26199Ssklower 501*26199Ssklower if(NpDebug & DEBMEM) 502*26199Ssklower printf("Bad Board %x bp %x\n",mp->flags,bp->b_flags); 503*26199Ssklower 504*26199Ssklower np_tab[mp->unit].b_actf = bp->av_forw; 505*26199Ssklower iodone(bp); 506*26199Ssklower return; 507*26199Ssklower } 508*26199Ssklower 509*26199Ssklower /* Initializations of request structure */ 510*26199Ssklower 511*26199Ssklower while((rp = NpGetReq(mp->reqtab)) == NULL) { 512*26199Ssklower mp->reqtab->flags |= WANTREQ; 513*26199Ssklower sleep((caddr_t)(mp->reqtab),PZERO -1); 514*26199Ssklower } 515*26199Ssklower 516*26199Ssklower rp->bufoffset = 0; /* This is the start of the buffer */ 517*26199Ssklower ip = &np_tab[mp->unit]; 518*26199Ssklower bp->av_forw = (struct buf *)0; 519*26199Ssklower bp->av_back = (struct buf *)rp; 520*26199Ssklower 521*26199Ssklower rp->flags |= KERNREQ; /* Mark it as kernel so not to map */ 522*26199Ssklower 523*26199Ssklower rp->mapbase = ubasetup(mp->devp->ui_ubanum,bp,0); 524*26199Ssklower rp->bufaddr = (caddr_t)((int)(rp->mapbase) & UBADDRMASK); 525*26199Ssklower 526*26199Ssklower s = spl5(); 527*26199Ssklower if(ip->b_actf ==(struct buf *)0) 528*26199Ssklower ip->b_actf = bp; 529*26199Ssklower else { 530*26199Ssklower if(ip->b_actf->av_forw) 531*26199Ssklower printf("Panic NP100 bad buffer chain\n"); 532*26199Ssklower ip->b_actf->av_forw = bp; 533*26199Ssklower } 534*26199Ssklower ip->b_actl = bp; 535*26199Ssklower 536*26199Ssklower NpAddReq(mp->reqtab,rp); /* Queue onto active list */ 537*26199Ssklower 538*26199Ssklower if(ip->b_active == 0) { 539*26199Ssklower 540*26199Ssklower if(NpDebug & DEBIO) 541*26199Ssklower printf("calling npstart %x\n",mp); 542*26199Ssklower 543*26199Ssklower npstart(mp); 544*26199Ssklower } 545*26199Ssklower splx(s); 546*26199Ssklower 547*26199Ssklower if(NpDebug & DEBIO) 548*26199Ssklower printf("back from npstart\n"); 549*26199Ssklower 550*26199Ssklower /* Await completion of I/O */ 551*26199Ssklower 552*26199Ssklower iowait(bp); 553*26199Ssklower 554*26199Ssklower if(NpDebug & DEBIO) 555*26199Ssklower printf("after iowait in npstrategy\n"); 556*26199Ssklower 557*26199Ssklower /* Remove request from queue */ 558*26199Ssklower 559*26199Ssklower NpRemReq(rp); 560*26199Ssklower 561*26199Ssklower /* Release mapping registers */ 562*26199Ssklower 563*26199Ssklower ubarelse(mp->devp->ui_ubanum,&rp->mapbase); 564*26199Ssklower 565*26199Ssklower /* Free up request structure */ 566*26199Ssklower 567*26199Ssklower NpFreeReq(mp->reqtab,rp); 568*26199Ssklower 569*26199Ssklower if(NpDebug & DEBENTRY) 570*26199Ssklower printf("Leaving npstrategy flags is %x\n",bp->b_flags); 571*26199Ssklower } 572*26199Ssklower 573*26199Ssklower unsigned 574*26199Ssklower nptrim(bp) 575*26199Ssklower register struct buf *bp; 576*26199Ssklower { 577*26199Ssklower 578*26199Ssklower if(bp->b_bcount > NPMAXXFR) 579*26199Ssklower bp->b_bcount = NPMAXXFR; 580*26199Ssklower } 581*26199Ssklower 582*26199Ssklower /* 583*26199Ssklower * Npread dumps data from the board to the user's buffer 584*26199Ssklower */ 585*26199Ssklower npread(dev,uio) 586*26199Ssklower dev_t dev; 587*26199Ssklower struct uio *uio; 588*26199Ssklower { 589*26199Ssklower 590*26199Ssklower if(NpDebug & DEBENTRY) 591*26199Ssklower printf("in npread\n"); 592*26199Ssklower 593*26199Ssklower return(physio(npstrategy,&npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_rbuf,dev,B_READ ,nptrim,uio)); 594*26199Ssklower 595*26199Ssklower } 596*26199Ssklower 597*26199Ssklower /* 598*26199Ssklower * Npwrite loads the np100 board from the user's buffer 599*26199Ssklower */ 600*26199Ssklower 601*26199Ssklower npwrite(dev,uio) 602*26199Ssklower dev_t dev; 603*26199Ssklower struct uio *uio; 604*26199Ssklower { 605*26199Ssklower struct buf *bp; 606*26199Ssklower bp = &npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_wbuf; 607*26199Ssklower 608*26199Ssklower if(NpDebug & DEBENTRY) 609*26199Ssklower printf("in npwrite \n"); 610*26199Ssklower 611*26199Ssklower return(physio(npstrategy,bp,dev,B_WRITE ,nptrim,uio)); 612*26199Ssklower } 613*26199Ssklower /* 614*26199Ssklower 615*26199Ssklower * npreset - called as result of a UNIBUS reset. 616*26199Ssklower */ 617*26199Ssklower 618*26199Ssklower npreset(uban) 619*26199Ssklower int uban; 620*26199Ssklower { 621*26199Ssklower 622*26199Ssklower register struct npmaster *mp; 623*26199Ssklower register struct npreq *rp; 624*26199Ssklower register struct uba_device *ui; 625*26199Ssklower int i; 626*26199Ssklower 627*26199Ssklower for(i = 0; i < NNP; i++) { 628*26199Ssklower 629*26199Ssklower if(((ui = npdinfo[i]) == (struct uba_device *)NULL) || 630*26199Ssklower (ui->ui_ubanum != uban)) 631*26199Ssklower continue; 632*26199Ssklower 633*26199Ssklower mp = &npmasters[i]; 634*26199Ssklower mp->iomapbase = 0; 635*26199Ssklower NpReset(mp,0); 636*26199Ssklower } 637*26199Ssklower } 638*26199Ssklower 639*26199Ssklower /* 640*26199Ssklower * Nppoll looks for work by polling each board. He goes to sleep if there are 641*26199Ssklower * no outstanding requests for him but reminds the board that he's there when 642*26199Ssklower * needed. 643*26199Ssklower */ 644*26199Ssklower 645*26199Ssklower NpPoll(mp,addr) 646*26199Ssklower struct npmaster *mp; 647*26199Ssklower caddr_t addr; 648*26199Ssklower { 649*26199Ssklower int error; 650*26199Ssklower 651*26199Ssklower struct { 652*26199Ssklower unsign16 request; 653*26199Ssklower unsign16 unit; 654*26199Ssklower }icpreq; 655*26199Ssklower 656*26199Ssklower if(NpDebug & DEBMAINT) 657*26199Ssklower printf("NpPoll: flags is %x.\n",mp->flags); 658*26199Ssklower 659*26199Ssklower while(TRUE) { 660*26199Ssklower 661*26199Ssklower for(mp = npmasters; mp; mp = mp->next) { 662*26199Ssklower 663*26199Ssklower if(mp->flags & BOARDREQ) { 664*26199Ssklower 665*26199Ssklower /* Get request type from master structure */ 666*26199Ssklower 667*26199Ssklower if(mp->flags & BRDRESET) { 668*26199Ssklower icpreq.request = ICPPOLL; 669*26199Ssklower mp->reqtab->reqcnt--; 670*26199Ssklower 671*26199Ssklower if(NpDebug & DEBMAINT) 672*26199Ssklower printf("Waking NpResetter!\n"); 673*26199Ssklower 674*26199Ssklower wakeup((caddr_t)(&mp->reqtab)); 675*26199Ssklower } 676*26199Ssklower else if(mp->flags & PANICREQ) 677*26199Ssklower icpreq.request = ICPPANIC; 678*26199Ssklower else if(mp->flags & DUMPREQ) 679*26199Ssklower icpreq.request = ICPDUMP; 680*26199Ssklower else if(mp->flags & LOADREQ) 681*26199Ssklower icpreq.request = ICPLOAD; 682*26199Ssklower else { 683*26199Ssklower mp->flags &= ~BOARDREQ; 684*26199Ssklower continue; 685*26199Ssklower } 686*26199Ssklower 687*26199Ssklower if(NpDebug & DEBMAINT) 688*26199Ssklower printf("ProcICP servicing %d \n",icpreq.request ); 689*26199Ssklower 690*26199Ssklower /* Request and unit number to be sent */ 691*26199Ssklower 692*26199Ssklower icpreq.unit = mp->unit; 693*26199Ssklower 694*26199Ssklower /* Copy service request to calling process */ 695*26199Ssklower 696*26199Ssklower error = copyout(&icpreq,addr,sizeof(icpreq)); 697*26199Ssklower 698*26199Ssklower /* Mark Poller as being unavailable */ 699*26199Ssklower 700*26199Ssklower NpState &= ~ICPAVAIL; 701*26199Ssklower 702*26199Ssklower return(error); 703*26199Ssklower } 704*26199Ssklower } 705*26199Ssklower 706*26199Ssklower /* Mark Poller as being available */ 707*26199Ssklower 708*26199Ssklower NpState |= ICPAVAIL; 709*26199Ssklower 710*26199Ssklower sleep((caddr_t)&NpState, PZERO + 1); 711*26199Ssklower 712*26199Ssklower if(NpDebug & DEBMAINT) 713*26199Ssklower printf("wakeup in NpPoll\n"); 714*26199Ssklower 715*26199Ssklower } 716*26199Ssklower } 717*26199Ssklower 718*26199Ssklower /* 719*26199Ssklower * Software initialization of Driver data structures for the specified unit. 720*26199Ssklower */ 721*26199Ssklower 722*26199Ssklower NpSWinit(unit) 723*26199Ssklower int unit; 724*26199Ssklower { 725*26199Ssklower 726*26199Ssklower register int j; 727*26199Ssklower register struct npmaster *mp; 728*26199Ssklower register struct npspace *npsp; 729*26199Ssklower register struct CmdQue *cqp; 730*26199Ssklower int offset; 731*26199Ssklower 732*26199Ssklower if(NpDebug & DEBINIT) 733*26199Ssklower printf("SW reset on unit %d.\n",unit); 734*26199Ssklower 735*26199Ssklower /* Initialize master structure pointer for this unit */ 736*26199Ssklower 737*26199Ssklower mp = &npmasters[unit]; 738*26199Ssklower 739*26199Ssklower /* Initialize unit buffer headers */ 740*26199Ssklower 741*26199Ssklower np_tab[unit].b_active = 0; 742*26199Ssklower np_tab[unit].b_actf = 0; 743*26199Ssklower 744*26199Ssklower /* UBA device structure for this unit */ 745*26199Ssklower 746*26199Ssklower mp->devp = npdinfo[unit]; 747*26199Ssklower 748*26199Ssklower /* Interrupt vector for this unit */ 749*26199Ssklower 750*26199Ssklower mp->vector = npvectors[unit]; 751*26199Ssklower 752*26199Ssklower if(unit == (NNP -1)) 753*26199Ssklower mp->next = (struct npmaster *)NULL; 754*26199Ssklower else mp->next = &npmasters[unit + 1]; 755*26199Ssklower 756*26199Ssklower /* 757*26199Ssklower * Guarantee alignment of shared memory area on a 758*26199Ssklower * 16 byte boundary as required by I-Board 759*26199Ssklower */ 760*26199Ssklower 761*26199Ssklower mp->shmemp = &npspaces[unit]; 762*26199Ssklower mp->shmemp = (struct npspace *)ROUND16((int)(mp->shmemp)); 763*26199Ssklower 764*26199Ssklower /* Base address of this controller */ 765*26199Ssklower 766*26199Ssklower mp->iobase = (struct NPREG *)(mp->devp->ui_addr); 767*26199Ssklower 768*26199Ssklower if(NpDebug & DEBMEM) { 769*26199Ssklower printf("Npspaces starts at %x.\n",npspaces); 770*26199Ssklower printf("Shared memory starts at %x.\n",mp->shmemp); 771*26199Ssklower printf("End of shared memory is %x.\n",&npspaces[unit + 1]); 772*26199Ssklower printf("Iobase is %x.\n",mp->iobase); 773*26199Ssklower printf("Npmasters start at %x\n",npmasters); 774*26199Ssklower printf("Reqhdr start at %x\n",reqhdr); 775*26199Ssklower printf("Npreqs start at %x\n",npreqs); 776*26199Ssklower } 777*26199Ssklower 778*26199Ssklower /* Initialize the request header */ 779*26199Ssklower 780*26199Ssklower mp->reqtab = &reqhdr[unit]; 781*26199Ssklower 782*26199Ssklower /* Unit initialization */ 783*26199Ssklower 784*26199Ssklower mp->unit = unit; 785*26199Ssklower 786*26199Ssklower /* Initialize Status Block */ 787*26199Ssklower 788*26199Ssklower npsp = mp->shmemp; 789*26199Ssklower offset = (int) (mp->shmemp); 790*26199Ssklower 791*26199Ssklower npsp->statblock.sb_drw = 0; 792*26199Ssklower npsp->statblock.sb_hcw = HOSTCONF; 793*26199Ssklower npsp->statblock.sb_dcw = 0; 794*26199Ssklower npsp->statblock.sb_dpm = 0; 795*26199Ssklower 796*26199Ssklower npsp->statblock.sb_dcq = (unsign16)((int)(&npsp->devcq))-offset; 797*26199Ssklower 798*26199Ssklower npsp->statblock.sb_hcq = (unsign16)((int)(&npsp->hostcq))-offset; 799*26199Ssklower 800*26199Ssklower /* Initialize Device Command Queue */ 801*26199Ssklower 802*26199Ssklower cqp = (struct CmdQue *) &npsp->devcq; 803*26199Ssklower 804*26199Ssklower if(NpDebug & DEBCQ) 805*26199Ssklower printf("Device CQ at %x\n",cqp); 806*26199Ssklower 807*26199Ssklower cqp->scanflag = NPCLEAR; 808*26199Ssklower cqp->chngflag = NPCLEAR; 809*26199Ssklower 810*26199Ssklower cqp->cq_add = (unsign16)(int)(&cqp->cq_cqe[0]) - offset; 811*26199Ssklower cqp->cq_rem = cqp->cq_add; 812*26199Ssklower 813*26199Ssklower cqp->cq_wrap = (unsign16)(int)(&cqp->cq_cqe[NUMCQE]) - offset; 814*26199Ssklower 815*26199Ssklower for(j = 0; j < NUMCQE; j++) 816*26199Ssklower cqp->cq_cqe[j] = (unsign16)NULL; 817*26199Ssklower 818*26199Ssklower /* Initialize Host Command Queue */ 819*26199Ssklower 820*26199Ssklower cqp = (struct CmdQue *) &npsp->hostcq; 821*26199Ssklower 822*26199Ssklower if(NpDebug & DEBCQ) 823*26199Ssklower printf("HOST CQ at %x\n",cqp); 824*26199Ssklower 825*26199Ssklower cqp->scanflag = NPCLEAR; 826*26199Ssklower cqp->chngflag = NPCLEAR; 827*26199Ssklower 828*26199Ssklower cqp->cq_add = (unsign16)(int)(&cqp->cq_cqe[0]) - offset; 829*26199Ssklower cqp->cq_rem = cqp->cq_add; 830*26199Ssklower 831*26199Ssklower cqp->cq_wrap = (unsign16)(int)(&cqp->cq_cqe[NUMCQE]) - offset; 832*26199Ssklower 833*26199Ssklower for(j = 0; j < NUMCQE; j++) 834*26199Ssklower cqp->cq_cqe[j] = (unsign16)NULL; 835*26199Ssklower 836*26199Ssklower /* 837*26199Ssklower * Initialize the reqid of the elements to the address 838*26199Ssklower * of the corresponding Npreq structure. These don't change. 839*26199Ssklower */ 840*26199Ssklower 841*26199Ssklower for(j = 0; j < NUMCQE; j++) 842*26199Ssklower npsp->elements[j].cqe_reqid = &npreqs[unit][j]; 843*26199Ssklower 844*26199Ssklower /* 845*26199Ssklower * Initialize the Request Header (reqhdr), free list of 846*26199Ssklower * npreqs, and pointers to CQEs. 847*26199Ssklower */ 848*26199Ssklower 849*26199Ssklower reqhdr[unit].forw = reqhdr[unit].back = &reqhdr[unit]; 850*26199Ssklower reqhdr[unit].free = &npreqs[unit][0]; 851*26199Ssklower 852*26199Ssklower for(j = 0; j < NUMCQE; j++) { 853*26199Ssklower 854*26199Ssklower npreqs[unit][j].free = &npreqs[unit][j + 1]; 855*26199Ssklower npreqs[unit][j].element = &npsp->elements[j]; 856*26199Ssklower npreqs[unit][j].forw = npreqs[unit][j].back = (struct npreq *)NULL; 857*26199Ssklower } 858*26199Ssklower npreqs[unit][--j].free = &reqhdr[unit]; 859*26199Ssklower 860*26199Ssklower /* 861*26199Ssklower * Set up the UNIBUS I/O Map Registers for the 862*26199Ssklower * Shared memory area. 863*26199Ssklower */ 864*26199Ssklower 865*26199Ssklower mp->iomapbase = uballoc(mp->devp->ui_ubanum,(caddr_t)(mp->shmemp),sizeof(struct npspace),0); 866*26199Ssklower 867*26199Ssklower 868*26199Ssklower if(NpDebug & DEBENTRY) 869*26199Ssklower printf("SW_Init...\n"); 870*26199Ssklower } 871*26199Ssklower 872*26199Ssklower /* 873*26199Ssklower * NpHWinit() issues a hardware reset to the specified board and waits 874*26199Ssklower * for on-board diagnostics to complete. It returns 0 if the board is 875*26199Ssklower * present and passed diagnostics, an error value otherwise. 876*26199Ssklower */ 877*26199Ssklower 878*26199Ssklower NpHWinit(unit) 879*26199Ssklower int unit; 880*26199Ssklower { 881*26199Ssklower register struct npmaster *mp; 882*26199Ssklower struct NPREG *REG; 883*26199Ssklower unsign16 status; 884*26199Ssklower int dflag; 885*26199Ssklower 886*26199Ssklower if(unit >= NNP) 887*26199Ssklower return(ENXIO); 888*26199Ssklower 889*26199Ssklower mp = &npmasters[unit]; 890*26199Ssklower 891*26199Ssklower if(NpDebug & DEBENTRY) 892*26199Ssklower printf("NpHWinit\n"); 893*26199Ssklower 894*26199Ssklower /* See if the board is out there */ 895*26199Ssklower 896*26199Ssklower REG = (struct NPREG *)mp->iobase; 897*26199Ssklower 898*26199Ssklower if(NpDebug & DEBINIT) 899*26199Ssklower printf("REG in HWinit is %x.\n",mp->iobase); 900*26199Ssklower 901*26199Ssklower if(!(mp->flags & BRDRESET)) 902*26199Ssklower 903*26199Ssklower if(badaddr(REG,2)) { 904*26199Ssklower mp->flags |= BADBOARD; 905*26199Ssklower printf("\nNP100 unit %d not found!\n",unit); 906*26199Ssklower return(ENXIO); 907*26199Ssklower } 908*26199Ssklower 909*26199Ssklower 910*26199Ssklower #ifdef mc500 911*26199Ssklower if(setjmp(u.u_tsav) == 0) { 912*26199Ssklower u.u_nofault = TRUE; 913*26199Ssklower status = RCSR1(mp->iobase); 914*26199Ssklower u.u_nofault = FALSE; 915*26199Ssklower } 916*26199Ssklower else { 917*26199Ssklower np__addr[unit] = 0; 918*26199Ssklower mp->flags |= BADBOARD; 919*26199Ssklower u.u_error = ENXIO; 920*26199Ssklower printf("\nNP100 Unit %x not here!\n",unit); 921*26199Ssklower return(0); 922*26199Ssklower } 923*26199Ssklower #endif 924*26199Ssklower 925*26199Ssklower if(NpDebug & DEBENTRY) 926*26199Ssklower printf("Resetting the NP100 Board at %x\n",mp->iobase); 927*26199Ssklower 928*26199Ssklower /* Reset the Board */ 929*26199Ssklower 930*26199Ssklower RESET(mp); 931*26199Ssklower 932*26199Ssklower dflag = NPCLEAR; 933*26199Ssklower 934*26199Ssklower timeout(NpTimer,&dflag,DIAGTIME); 935*26199Ssklower 936*26199Ssklower /* Wait for Enable and Read Data Ready to go high */ 937*26199Ssklower 938*26199Ssklower while(! ((RCSR1(mp->iobase) & NPENB) && (RCSR1(mp->iobase) & NPRDR))) { 939*26199Ssklower if(dflag) 940*26199Ssklower break; 941*26199Ssklower 942*26199Ssklower } 943*26199Ssklower 944*26199Ssklower untimeout(NpTimer,&dflag); 945*26199Ssklower 946*26199Ssklower if(NpDebug & DEBINIT) 947*26199Ssklower printf("np reset %d \n",dflag); 948*26199Ssklower 949*26199Ssklower if(dflag) { 950*26199Ssklower mp->flags |= BADBOARD; 951*26199Ssklower printf("NP100 Unit %d timed out!\n",unit); 952*26199Ssklower return(EIO); 953*26199Ssklower } 954*26199Ssklower 955*26199Ssklower status = RCSR0(mp->iobase); 956*26199Ssklower 957*26199Ssklower /* Check for Hardware OK */ 958*26199Ssklower 959*26199Ssklower if(!(RCSR1(mp->iobase) & NPHOK)) { 960*26199Ssklower mp->flags |= BADBOARD; 961*26199Ssklower u.u_error = EIO; 962*26199Ssklower printf("NP100 Unit %d Failed diagnostics!\n",unit); 963*26199Ssklower printf("Status from CSR0: %x.\n",status); 964*26199Ssklower return(EIO); 965*26199Ssklower } 966*26199Ssklower 967*26199Ssklower if(NpDebug & DEBENTRY) 968*26199Ssklower printf("HWinit...\n"); 969*26199Ssklower 970*26199Ssklower return(0); 971*26199Ssklower } 972*26199Ssklower 973*26199Ssklower /* 974*26199Ssklower * NP Driver Interrupt Handler 975*26199Ssklower */ 976*26199Ssklower 977*26199Ssklower npintr(unit) 978*26199Ssklower int unit; 979*26199Ssklower { 980*26199Ssklower register struct npmaster *mp; 981*26199Ssklower register struct buf *bp; 982*26199Ssklower 983*26199Ssklower if(NpDebug & DEBENTRY) 984*26199Ssklower printf("npintr on unit %d!\n",unit); 985*26199Ssklower 986*26199Ssklower mp = &npmasters[unit]; 987*26199Ssklower 988*26199Ssklower if(NpDebug & DEBINTR) 989*26199Ssklower printf("npintr mp->flags = %x\n",mp->flags); 990*26199Ssklower 991*26199Ssklower /* Wake up anyone sleeping on a CSR0 Command */ 992*26199Ssklower 993*26199Ssklower if(mp->flags & CSRPEND) { 994*26199Ssklower 995*26199Ssklower mp->flags &= ~CSRPEND; 996*26199Ssklower if(np_tab[mp->unit].b_active) { 997*26199Ssklower np_tab[mp->unit].b_active = 0; 998*26199Ssklower bp = np_tab[mp->unit].b_actf; 999*26199Ssklower np_tab[mp->unit].b_actf = bp->av_forw; 1000*26199Ssklower 1001*26199Ssklower if(NpDebug & DEBINTR) 1002*26199Ssklower printf("bp = %x resid = %d forw = %x\n",bp, 1003*26199Ssklower bp->b_resid,bp->av_forw); 1004*26199Ssklower 1005*26199Ssklower bp->b_resid = 0; 1006*26199Ssklower iodone(bp); 1007*26199Ssklower } 1008*26199Ssklower if(mp->flags & PANIC3) { 1009*26199Ssklower mp->flags &= ~PANIC3; 1010*26199Ssklower mp->flags = AVAILABLE; 1011*26199Ssklower ubarelse(mp->devp->ui_ubanum,&panicmap); 1012*26199Ssklower } 1013*26199Ssklower if(mp->flags & PANIC2) { 1014*26199Ssklower mp->flags &= ~PANIC2; 1015*26199Ssklower printf("Panic Message: %s",NpPbuf); 1016*26199Ssklower mp->flags |= PANIC3; 1017*26199Ssklower NpPbuf[0] = 0; 1018*26199Ssklower NPIO(mp,(paddr_t)((int) panicmap & UBADDRMASK),(paddr_t)pstring,sizeof(NpPbuf),B_WRITE); 1019*26199Ssklower } 1020*26199Ssklower if(mp->flags & PANIC1) { 1021*26199Ssklower mp->flags &= ~PANIC1; 1022*26199Ssklower mp->flags |= PANIC2; 1023*26199Ssklower ubarelse(mp->devp->ui_ubanum,&panicmap); 1024*26199Ssklower panicmap = uballoc(mp->devp->ui_ubanum,(caddr_t)NpPbuf,sizeof(NpPbuf),0); 1025*26199Ssklower pstring = (caddr_t)((panaddr[1] << 4) + panaddr[0]); 1026*26199Ssklower NPIO(mp,(paddr_t)pstring,(paddr_t)((int) panicmap & UBADDRMASK),sizeof(NpPbuf),B_READ); 1027*26199Ssklower } 1028*26199Ssklower 1029*26199Ssklower wakeup((caddr_t)mp); 1030*26199Ssklower goto out; 1031*26199Ssklower } 1032*26199Ssklower 1033*26199Ssklower /* Mark unit as being available if Device Protocol Mask set */ 1034*26199Ssklower 1035*26199Ssklower if(!(mp->flags & AVAILABLE)) { 1036*26199Ssklower 1037*26199Ssklower if((mp->shmemp->statblock.sb_dpm) && (!(mp->flags & BRDRESET))){ 1038*26199Ssklower 1039*26199Ssklower mp->flags = AVAILABLE; 1040*26199Ssklower printf("\nNP100 unit #%d available!\n",mp->unit); 1041*26199Ssklower } 1042*26199Ssklower } 1043*26199Ssklower 1044*26199Ssklower /* Honor service requests from the device */ 1045*26199Ssklower 1046*26199Ssklower switch(mp->shmemp->statblock.sb_drw) { 1047*26199Ssklower 1048*26199Ssklower case NOREQ: 1049*26199Ssklower break; 1050*26199Ssklower 1051*26199Ssklower case NPPANIC: 1052*26199Ssklower 1053*26199Ssklower printf("\nPanic from NP100 unit %d!\n",mp->unit); 1054*26199Ssklower mp->flags &= ~AVAILABLE; 1055*26199Ssklower mp->flags |= PANIC1; 1056*26199Ssklower 1057*26199Ssklower /* Clear device request word */ 1058*26199Ssklower 1059*26199Ssklower mp->shmemp->statblock.sb_drw = 0; 1060*26199Ssklower 1061*26199Ssklower panicmap = uballoc(mp->devp->ui_ubanum,(caddr_t)panaddr,sizeof(panaddr),0); 1062*26199Ssklower NPIO(mp,(paddr_t)NPPSADDR,(paddr_t)((int)panicmap & UBADDRMASK),sizeof(panaddr),B_READ); 1063*26199Ssklower goto out; 1064*26199Ssklower break; 1065*26199Ssklower 1066*26199Ssklower case NPDUMP: 1067*26199Ssklower mp->flags |= (DUMPREQ | BOARDREQ); 1068*26199Ssklower 1069*26199Ssklower /* Clear device request word */ 1070*26199Ssklower 1071*26199Ssklower mp->shmemp->statblock.sb_drw = 0; 1072*26199Ssklower 1073*26199Ssklower if(NpState & ICPAVAIL) 1074*26199Ssklower wakeup((caddr_t)&NpState); 1075*26199Ssklower break; 1076*26199Ssklower 1077*26199Ssklower case NPLOAD: 1078*26199Ssklower mp->flags |= (LOADREQ | BOARDREQ); 1079*26199Ssklower 1080*26199Ssklower /* Clear device request word */ 1081*26199Ssklower 1082*26199Ssklower mp->shmemp->statblock.sb_drw = 0; 1083*26199Ssklower 1084*26199Ssklower if(NpState & ICPAVAIL) 1085*26199Ssklower wakeup((caddr_t)&NpState); 1086*26199Ssklower break; 1087*26199Ssklower 1088*26199Ssklower default: 1089*26199Ssklower printf("Bad Req: %x.\n",mp->shmemp->statblock.sb_drw); 1090*26199Ssklower goto out; 1091*26199Ssklower 1092*26199Ssklower } 1093*26199Ssklower 1094*26199Ssklower /* Process the Host Command Queue for this device */ 1095*26199Ssklower 1096*26199Ssklower NpProcQueue(mp); 1097*26199Ssklower 1098*26199Ssklower out: 1099*26199Ssklower CLEARINT(mp); /* Clear the interrupt */ 1100*26199Ssklower 1101*26199Ssklower if(NpDebug & DEBENTRY) 1102*26199Ssklower printf("npintr...\n"); 1103*26199Ssklower 1104*26199Ssklower return(1); /* Interrupt serviced */ 1105*26199Ssklower 1106*26199Ssklower } 1107*26199Ssklower 1108*26199Ssklower /* 1109*26199Ssklower * This routine, called from the interrupt handler, is used to process the 1110*26199Ssklower * Host Command Queue for the specified device. 1111*26199Ssklower */ 1112*26199Ssklower 1113*26199Ssklower NpProcQueue(mp) 1114*26199Ssklower struct npmaster *mp; 1115*26199Ssklower { 1116*26199Ssklower register struct CmdQue *cqp; 1117*26199Ssklower register struct CQE *ep; 1118*26199Ssklower register struct npreq *rp; 1119*26199Ssklower register int base; 1120*26199Ssklower 1121*26199Ssklower if(NpDebug & DEBENTRY) 1122*26199Ssklower printf("NpProcQueue\n"); 1123*26199Ssklower 1124*26199Ssklower cqp = &mp->shmemp->hostcq; /* Command Queue pointer */ 1125*26199Ssklower 1126*26199Ssklower if(cqp->scanflag & ON) 1127*26199Ssklower return; 1128*26199Ssklower 1129*26199Ssklower else cqp->scanflag | = ON; 1130*26199Ssklower 1131*26199Ssklower base = (int)mp->shmemp; /* Shared memory base address */ 1132*26199Ssklower 1133*26199Ssklower while(cqp->scanflag & ON) { 1134*26199Ssklower 1135*26199Ssklower while(ep = NpRemCQE(cqp,base)) { 1136*26199Ssklower 1137*26199Ssklower rp = ep->cqe_reqid; 1138*26199Ssklower 1139*26199Ssklower if(NpDebug & DEBCQE) 1140*26199Ssklower printf("cqe_sts is %x ep = %x\n",ep->cqe_sts,ep); 1141*26199Ssklower 1142*26199Ssklower switch (ep->cqe_sts) { 1143*26199Ssklower 1144*26199Ssklower case NPDONE: 1145*26199Ssklower rp->flags |= REQDONE; /* Normal completion */ 1146*26199Ssklower break; 1147*26199Ssklower case NPIFC: /* IFC Request */ 1148*26199Ssklower rp->flags |= IOIFC; 1149*26199Ssklower break; 1150*26199Ssklower case NPPERR: /* Protocol Error */ 1151*26199Ssklower rp->flags |= (NPPERR | REQDONE); 1152*26199Ssklower break; 1153*26199Ssklower case NPMERR: /* Memory allocation */ 1154*26199Ssklower rp->flags |= (NPMERR | REQDONE); 1155*26199Ssklower break; 1156*26199Ssklower default: /* Error on Board */ 1157*26199Ssklower rp->flags |= (IOERR | REQDONE); 1158*26199Ssklower break; 1159*26199Ssklower 1160*26199Ssklower } 1161*26199Ssklower 1162*26199Ssklower if(NpDebug & DEBCQE) { 1163*26199Ssklower printf("flag is %x reqid = %x\n",rp->flags,ep->cqe_reqid); 1164*26199Ssklower printf("wakeup in procqueue\n"); 1165*26199Ssklower } 1166*26199Ssklower 1167*26199Ssklower if(rp->intr) { 1168*26199Ssklower 1169*26199Ssklower if(NpDebug & DEBINTR) 1170*26199Ssklower printf("calling usr intr at %x\n", 1171*26199Ssklower rp->intr); 1172*26199Ssklower 1173*26199Ssklower /* Call interrupt routine */ 1174*26199Ssklower 1175*26199Ssklower (*rp->intr)(mp,rp); 1176*26199Ssklower 1177*26199Ssklower } 1178*26199Ssklower else { 1179*26199Ssklower 1180*26199Ssklower if(NpDebug & DEBINTR) 1181*26199Ssklower printf("waking up %x\n",rp); 1182*26199Ssklower 1183*26199Ssklower if(rp->flags & NPUIO) 1184*26199Ssklower iodone(&rp->buf); 1185*26199Ssklower else wakeup((caddr_t) (rp)); /* Awaken */ 1186*26199Ssklower 1187*26199Ssklower if(NpDebug & DEBINTR) 1188*26199Ssklower printf("AWAKE\n"); 1189*26199Ssklower } 1190*26199Ssklower 1191*26199Ssklower } 1192*26199Ssklower 1193*26199Ssklower if(!(cqp->chngflag & ON)) 1194*26199Ssklower cqp->scanflag &= ~ON; 1195*26199Ssklower 1196*26199Ssklower } 1197*26199Ssklower 1198*26199Ssklower if(NpDebug & DEBENTRY) 1199*26199Ssklower printf("NpProcQueue...\n"); 1200*26199Ssklower } 1201*26199Ssklower 1202*26199Ssklower /* 1203*26199Ssklower * NpIFC - processes an IFC (Internal Fuction Call) request 1204*26199Ssklower * NOTE: this function must be called from the user context 1205*26199Ssklower * on all virtual pageing systems 1206*26199Ssklower * 1207*26199Ssklower */ 1208*26199Ssklower NpIFC(mp,rp) 1209*26199Ssklower register struct npmaster *mp; 1210*26199Ssklower register struct npreq *rp; 1211*26199Ssklower { 1212*26199Ssklower register struct CQE *ep; 1213*26199Ssklower 1214*26199Ssklower if(NpDebug & DEBENTRY) 1215*26199Ssklower printf("NpIFC\n"); 1216*26199Ssklower 1217*26199Ssklower ep = rp->element; 1218*26199Ssklower rp->flags &= ~IOIFC; 1219*26199Ssklower switch(ep->cqe_func) { 1220*26199Ssklower 1221*26199Ssklower case NPUNLOCK: /* Unlock process, free up mapping registers */ 1222*26199Ssklower 1223*26199Ssklower if(NpDebug & DEBIFC) 1224*26199Ssklower printf("NPUNLOCK\n"); 1225*26199Ssklower 1226*26199Ssklower if(rp->mapbase) 1227*26199Ssklower NpUnMapMem(mp,rp); 1228*26199Ssklower break; 1229*26199Ssklower 1230*26199Ssklower case NPLOCK: /* Lock process, get mapping registers */ 1231*26199Ssklower 1232*26199Ssklower if(NpDebug & DEBIFC) 1233*26199Ssklower printf("NPLOCK\n"); 1234*26199Ssklower NpMapMem(mp,rp,rp->virtmem,rp->bytecnt); 1235*26199Ssklower ep->cqe_dma[0] = LOWORD(rp->bufaddr); 1236*26199Ssklower ep->cqe_dma[1] = HIWORD(rp->bufaddr); 1237*26199Ssklower break; 1238*26199Ssklower 1239*26199Ssklower case NPREMAP: 1240*26199Ssklower 1241*26199Ssklower if(NpDebug & DEBIFC) 1242*26199Ssklower printf("NPREMAP\n"); 1243*26199Ssklower 1244*26199Ssklower /* Remap user buffer and update buffer offset */ 1245*26199Ssklower #ifdef USG 1246*26199Ssklower np_remapmem(rp,rp->virtmem); 1247*26199Ssklower ep->cqe_dma[0] = LOWORD(rp->bufaddr); 1248*26199Ssklower ep->cqe_dma[1] = HIWORD(rp->bufaddr); 1249*26199Ssklower break; 1250*26199Ssklower #endif 1251*26199Ssklower 1252*26199Ssklower default: 1253*26199Ssklower if(NpDebug & DEBIFC) 1254*26199Ssklower printf("Bad case %x in IFC\n", ep->cqe_func); 1255*26199Ssklower 1256*26199Ssklower rp->flags |= (REQDONE | IOERR); 1257*26199Ssklower break; 1258*26199Ssklower } 1259*26199Ssklower } 1260*26199Ssklower 1261*26199Ssklower /* 1262*26199Ssklower * The following contains various routines for allocating and deallocating 1263*26199Ssklower * structures used by the NP Driver. Routines are also here for addding 1264*26199Ssklower * and removing Command Queue Elements from a Command Queue. 1265*26199Ssklower */ 1266*26199Ssklower 1267*26199Ssklower /* 1268*26199Ssklower * Get a free NP Request structure from the list pointed to by head. Returns 1269*26199Ssklower * a pointer to a npreq or NULL if none left. 1270*26199Ssklower */ 1271*26199Ssklower 1272*26199Ssklower struct npreq * 1273*26199Ssklower NpGetReq(head) 1274*26199Ssklower struct npreq *head; 1275*26199Ssklower { 1276*26199Ssklower 1277*26199Ssklower register struct npreq *p; 1278*26199Ssklower 1279*26199Ssklower p = head->free; 1280*26199Ssklower head->free = p->free; 1281*26199Ssklower return(p==head ? (struct npreq *)NULL : p); 1282*26199Ssklower } 1283*26199Ssklower 1284*26199Ssklower /* 1285*26199Ssklower * Return a NP Request structure to the free list pointed to by head. 1286*26199Ssklower */ 1287*26199Ssklower 1288*26199Ssklower NpFreeReq(head,nprp) 1289*26199Ssklower register struct npreq *head, *nprp; 1290*26199Ssklower { 1291*26199Ssklower 1292*26199Ssklower if(NpDebug & DEBREQ) 1293*26199Ssklower printf("NpFreeReq, head is %x rp is %x\n",head,nprp); 1294*26199Ssklower 1295*26199Ssklower nprp->forw = nprp->back = (struct npreq *)NULL; 1296*26199Ssklower nprp->free = head->free; 1297*26199Ssklower head->free = nprp; 1298*26199Ssklower 1299*26199Ssklower /* Wake up any processes waiting for a request structure */ 1300*26199Ssklower 1301*26199Ssklower if(head->flags & WANTREQ) { 1302*26199Ssklower head->flags &= ~WANTREQ; 1303*26199Ssklower wakeup((caddr_t)head); 1304*26199Ssklower } 1305*26199Ssklower 1306*26199Ssklower if(NpDebug & DEBENTRY) 1307*26199Ssklower printf("NpFreeReq...\n"); 1308*26199Ssklower } 1309*26199Ssklower 1310*26199Ssklower /* 1311*26199Ssklower * Add a Command Queue Element onto the specified Command Queue and 1312*26199Ssklower * update its Add offset. 1313*26199Ssklower */ 1314*26199Ssklower 1315*26199Ssklower NpAddCQE(ep,cqp,mp) 1316*26199Ssklower struct CQE *ep; 1317*26199Ssklower struct CmdQue *cqp; 1318*26199Ssklower struct npmaster *mp; 1319*26199Ssklower { 1320*26199Ssklower 1321*26199Ssklower register unsign16 *temp; 1322*26199Ssklower register unsign16 cqe_offset; 1323*26199Ssklower register int base; 1324*26199Ssklower 1325*26199Ssklower base = (int)mp->shmemp; /* Shared memory base address */ 1326*26199Ssklower 1327*26199Ssklower temp = (unsign16 *)(base + cqp->cq_add); /* Offset to add element */ 1328*26199Ssklower 1329*26199Ssklower cqe_offset = (unsign16)((int)ep - base); 1330*26199Ssklower 1331*26199Ssklower if(*temp) { /* Should never happen */ 1332*26199Ssklower 1333*26199Ssklower printf("No more room on Command Queue!\n"); 1334*26199Ssklower u.u_error = EIO; 1335*26199Ssklower return; 1336*26199Ssklower } 1337*26199Ssklower else *temp = cqe_offset; /* Enter this request's offset */ 1338*26199Ssklower 1339*26199Ssklower cqp->chngflag |= ON; /* Set change flag unconditionally */ 1340*26199Ssklower 1341*26199Ssklower /* Update cqe_add where next request is to be added */ 1342*26199Ssklower 1343*26199Ssklower cqp->cq_add += sizeof(unsign16); 1344*26199Ssklower 1345*26199Ssklower if(cqp->cq_add == cqp->cq_wrap) /* Wrap if necessary */ 1346*26199Ssklower cqp->cq_add = (unsign16)((int)cqp->cq_cqe - base); 1347*26199Ssklower 1348*26199Ssklower /* Interrupt the Board if his scan flag isn't on */ 1349*26199Ssklower 1350*26199Ssklower if(!(cqp->scanflag & ON)) 1351*26199Ssklower 1352*26199Ssklower INTNI(mp); /* Interrupt the Board */ 1353*26199Ssklower 1354*26199Ssklower } 1355*26199Ssklower 1356*26199Ssklower /* 1357*26199Ssklower * The NpRemCQE routine is used to remove the next CQE from the Command Queue 1358*26199Ssklower * specified by cqp. The common offset of shared memory used by the device 1359*26199Ssklower * is specified by base. NpRemCQE returns a pointer to the next CQE or 1360*26199Ssklower * NULL if there are none left. This routine will also update the cqe_rem 1361*26199Ssklower * offset which specifies where the next element to be removed from the 1362*26199Ssklower * queue is located. 1363*26199Ssklower */ 1364*26199Ssklower 1365*26199Ssklower struct CQE * 1366*26199Ssklower NpRemCQE(cqp,base) 1367*26199Ssklower struct CmdQue *cqp; 1368*26199Ssklower int base; 1369*26199Ssklower { 1370*26199Ssklower 1371*26199Ssklower register unsign16 *temp; 1372*26199Ssklower register unsign16 cqe_offset; 1373*26199Ssklower 1374*26199Ssklower cqp->chngflag &= ~ON; /* Turn off unconditionally */ 1375*26199Ssklower 1376*26199Ssklower /* Get address of element to remove */ 1377*26199Ssklower 1378*26199Ssklower temp = (unsign16 *)(base +cqp->cq_rem); 1379*26199Ssklower 1380*26199Ssklower if(*temp == NULL) /* If none left, go home */ 1381*26199Ssklower return((struct CQE *) NULL); 1382*26199Ssklower 1383*26199Ssklower else cqe_offset = *temp; /* Offset of CQE to remove */ 1384*26199Ssklower 1385*26199Ssklower /* Update the Command Queue's cqe_rem offset */ 1386*26199Ssklower 1387*26199Ssklower *temp = NULL; /* Clear out this entry */ 1388*26199Ssklower 1389*26199Ssklower cqp->cq_rem += sizeof(unsign16); /* Bump offset */ 1390*26199Ssklower 1391*26199Ssklower if(cqp->cq_rem == cqp->cq_wrap) /* Wrap if necessary */ 1392*26199Ssklower cqp->cq_rem = (unsign16)((int)cqp->cq_cqe - base); 1393*26199Ssklower 1394*26199Ssklower temp = (unsign16 *)(base + cqe_offset); /* CQE address */ 1395*26199Ssklower return((struct CQE *)temp); /* is returned */ 1396*26199Ssklower } 1397*26199Ssklower 1398*26199Ssklower /* 1399*26199Ssklower * NpAddReq will add the specified npreq structure to the queue controlled 1400*26199Ssklower * by head. 1401*26199Ssklower */ 1402*26199Ssklower 1403*26199Ssklower NpAddReq(head,rp) 1404*26199Ssklower register struct npreq *head, *rp; 1405*26199Ssklower { 1406*26199Ssklower 1407*26199Ssklower if(NpDebug & DEBENTRY) 1408*26199Ssklower printf("NpAddReq\n"); 1409*26199Ssklower 1410*26199Ssklower if(NpDebug & DEBREQ) 1411*26199Ssklower printf("NpAddReq: %x\n",rp); 1412*26199Ssklower 1413*26199Ssklower rp->forw = head->forw; 1414*26199Ssklower rp->forw->back = rp; 1415*26199Ssklower rp->back = head; 1416*26199Ssklower head->forw = rp; 1417*26199Ssklower 1418*26199Ssklower if(NpDebug & DEBENTRY) 1419*26199Ssklower printf("NpAddReq...\n"); 1420*26199Ssklower } 1421*26199Ssklower 1422*26199Ssklower /* 1423*26199Ssklower * NpRemReq is used to remove a npreq structure from the queue specified by 1424*26199Ssklower * head. 1425*26199Ssklower */ 1426*26199Ssklower 1427*26199Ssklower NpRemReq(rp) 1428*26199Ssklower register struct npreq *rp; 1429*26199Ssklower { 1430*26199Ssklower 1431*26199Ssklower if(NpDebug & DEBENTRY) 1432*26199Ssklower printf("NpRemReq\n"); 1433*26199Ssklower 1434*26199Ssklower if(NpDebug & DEBREQ) 1435*26199Ssklower printf("NpRemReq: %x\n",rp); 1436*26199Ssklower 1437*26199Ssklower rp->back->forw = rp->forw; 1438*26199Ssklower rp->forw->back = rp->back; 1439*26199Ssklower 1440*26199Ssklower if(NpDebug & DEBENTRY) 1441*26199Ssklower printf("NpRemReq...\n"); 1442*26199Ssklower } 1443*26199Ssklower 1444*26199Ssklower 1445*26199Ssklower /* 1446*26199Ssklower * The following routines are used to communicate with the 1447*26199Ssklower * NI Hardware via the CSR0 commands. These commands are issued during 1448*26199Ssklower * the hardware initializtion process and may also be used subsequently 1449*26199Ssklower * by privileged processes who wish to communicate in this way. The 1450*26199Ssklower * convention for passing data as a Command Block is discussed in detail 1451*26199Ssklower * in the NI1510 UNIBUS Compatible Ethernet Communications Processor 1452*26199Ssklower * Hardware Specification. 1453*26199Ssklower */ 1454*26199Ssklower 1455*26199Ssklower NpSendCSR0(iobase,src,bcount) 1456*26199Ssklower struct NPREG *iobase; 1457*26199Ssklower register unsign16 *src; 1458*26199Ssklower int bcount; 1459*26199Ssklower { 1460*26199Ssklower register int wcount; 1461*26199Ssklower int i; 1462*26199Ssklower int csrflag; 1463*26199Ssklower unsign16 tmp; 1464*26199Ssklower 1465*26199Ssklower if(NpDebug & DEBENTRY) 1466*26199Ssklower printf("NpSendCSR0\n"); 1467*26199Ssklower 1468*26199Ssklower /* Jolt the board into CSR0 command mode if necessary */ 1469*26199Ssklower 1470*26199Ssklower if(!(RCSR1(iobase) & NPENB)){ 1471*26199Ssklower tmp = NPCLEAR; /* MC68000 clr reads before writing */ 1472*26199Ssklower WCSR0(iobase,tmp); 1473*26199Ssklower } 1474*26199Ssklower 1475*26199Ssklower wcount = (bcount +1) >> 1; /* Convert byte count to word count */ 1476*26199Ssklower 1477*26199Ssklower /* Clear timer flag before beginning the timer */ 1478*26199Ssklower 1479*26199Ssklower csrflag = NPCLEAR; 1480*26199Ssklower timeout(NpTimer,&csrflag,DIAGTIME); 1481*26199Ssklower 1482*26199Ssklower for(i = 0; (i < wcount) & (csrflag == NPCLEAR); i++) { 1483*26199Ssklower while(! ((RCSR1(iobase) & NPENB) && (RCSR1(iobase) & NPRDY))) 1484*26199Ssklower if(csrflag) break; 1485*26199Ssklower WCSR0(iobase,*src); 1486*26199Ssklower src++; /* Better do this WCSR is a macro */ 1487*26199Ssklower } 1488*26199Ssklower 1489*26199Ssklower /* Clear the timer entry */ 1490*26199Ssklower 1491*26199Ssklower untimeout(NpTimer,&csrflag); 1492*26199Ssklower 1493*26199Ssklower /* Error if timer went off */ 1494*26199Ssklower 1495*26199Ssklower if(csrflag) 1496*26199Ssklower return(EIO); 1497*26199Ssklower 1498*26199Ssklower if(NpDebug & DEBENTRY) 1499*26199Ssklower printf("NpSendCSR0...\n"); 1500*26199Ssklower return(0); 1501*26199Ssklower } 1502*26199Ssklower 1503*26199Ssklower /* 1504*26199Ssklower * NpSetIntLev sets the UNIBUS interrupt vector to be used by the NP board when 1505*26199Ssklower * interupting the host. The board is specified by mp. 1506*26199Ssklower */ 1507*26199Ssklower 1508*26199Ssklower NpSetIntLevel(mp,level) 1509*26199Ssklower struct npmaster *mp; 1510*26199Ssklower int level; 1511*26199Ssklower { 1512*26199Ssklower 1513*26199Ssklower struct { 1514*26199Ssklower unsign16 cmd_word; 1515*26199Ssklower unsign16 int_level; 1516*26199Ssklower }cmd_block; 1517*26199Ssklower 1518*26199Ssklower cmd_block.cmd_word = NPCBI | CBICNT; 1519*26199Ssklower cmd_block.int_level = level; 1520*26199Ssklower 1521*26199Ssklower return(NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block))); 1522*26199Ssklower } 1523*26199Ssklower 1524*26199Ssklower /* 1525*26199Ssklower * NpSetMemAddr is used to declare the shared memory area address to be used 1526*26199Ssklower * for communication between the driver and the device. This address is used 1527*26199Ssklower * to access data structures by acting as a base from which defined offsets 1528*26199Ssklower * locate data. The board is specified by mp. 1529*26199Ssklower */ 1530*26199Ssklower 1531*26199Ssklower NpSetMemAddr(mp,addr) 1532*26199Ssklower struct npmaster *mp; 1533*26199Ssklower caddr_t addr; 1534*26199Ssklower { 1535*26199Ssklower 1536*26199Ssklower caddr_t shmaddr; 1537*26199Ssklower int error; 1538*26199Ssklower 1539*26199Ssklower struct { 1540*26199Ssklower unsign16 cmd_word; 1541*26199Ssklower unsign16 hi_addr; 1542*26199Ssklower unsign16 lo_addr; 1543*26199Ssklower } cmd_block; 1544*26199Ssklower 1545*26199Ssklower if(NpDebug & DEBENTRY) 1546*26199Ssklower printf("NpSetMemAddr\n"); 1547*26199Ssklower 1548*26199Ssklower shmaddr = addr; 1549*26199Ssklower 1550*26199Ssklower if(NpDebug & DEBMEM) 1551*26199Ssklower printf("NpSetMemAddr, addr is %x shmaddr is %x.\n",addr,shmaddr); 1552*26199Ssklower 1553*26199Ssklower cmd_block.cmd_word = NPCMD | CMDCNT; 1554*26199Ssklower cmd_block.hi_addr = HIWORD(shmaddr); 1555*26199Ssklower cmd_block.lo_addr = LOWORD(shmaddr); 1556*26199Ssklower 1557*26199Ssklower error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)); 1558*26199Ssklower 1559*26199Ssklower if(NpDebug & DEBENTRY) 1560*26199Ssklower printf("NpSetMemAddr...\n"); 1561*26199Ssklower 1562*26199Ssklower return(error); 1563*26199Ssklower } 1564*26199Ssklower 1565*26199Ssklower 1566*26199Ssklower /* 1567*26199Ssklower * NpSetXeqAddr specifies the address at which the board should begin 1568*26199Ssklower * execution of its on-board software. It also indicates the shared memory 1569*26199Ssklower * address to be used. The board is specified by mp. 1570*26199Ssklower */ 1571*26199Ssklower 1572*26199Ssklower NpSetXeqAddr(mp,addr) 1573*26199Ssklower struct npmaster *mp; 1574*26199Ssklower caddr_t addr; 1575*26199Ssklower { 1576*26199Ssklower caddr_t shmaddr; 1577*26199Ssklower int error; 1578*26199Ssklower 1579*26199Ssklower struct { 1580*26199Ssklower unsign16 cmd_word; 1581*26199Ssklower unsign16 hi_addr; 1582*26199Ssklower unsign16 lo_addr; 1583*26199Ssklower unsign16 mhi_addr; 1584*26199Ssklower unsign16 mlo_addr; 1585*26199Ssklower } cmd_block; 1586*26199Ssklower 1587*26199Ssklower if(NpDebug & DEBENTRY) 1588*26199Ssklower printf("NpSetXeqAddr\n"); 1589*26199Ssklower 1590*26199Ssklower shmaddr = (caddr_t)((int)mp->iomapbase & UBADDRMASK); 1591*26199Ssklower 1592*26199Ssklower cmd_block.cmd_word = NPBGN | NPCMD | NPLST | (BGNCNT + CMDCNT); 1593*26199Ssklower cmd_block.hi_addr = HIWORD(addr); 1594*26199Ssklower cmd_block.lo_addr = LOWORD(addr); 1595*26199Ssklower cmd_block.mhi_addr = HIWORD(shmaddr); 1596*26199Ssklower cmd_block.mlo_addr = LOWORD(shmaddr); 1597*26199Ssklower 1598*26199Ssklower if(NpDebug & DEBINIT) { 1599*26199Ssklower printf("NpSetXeqAdddr: hi: %x lo: %x\n",HIWORD(addr), LOWORD(addr)); 1600*26199Ssklower printf("NpSetXeqAdddr: mhi: %x mlo: %x\n",HIWORD(shmaddr),LOWORD(shmaddr)); 1601*26199Ssklower } 1602*26199Ssklower 1603*26199Ssklower error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)); 1604*26199Ssklower 1605*26199Ssklower if(NpDebug & DEBENTRY) 1606*26199Ssklower printf("NpSetXeqAddr...\n"); 1607*26199Ssklower 1608*26199Ssklower return(error); 1609*26199Ssklower } 1610*26199Ssklower 1611*26199Ssklower /* 1612*26199Ssklower * NPIO issues a CSR0 load or dump request to the I-Board after packaging a 1613*26199Ssklower * CSR0 Command Block. 1614*26199Ssklower */ 1615*26199Ssklower 1616*26199Ssklower NPIO(mp,src,dest,count,dir) 1617*26199Ssklower struct npmaster *mp; 1618*26199Ssklower paddr_t dest; 1619*26199Ssklower paddr_t src; 1620*26199Ssklower unsign16 count; 1621*26199Ssklower int dir; /* Direction READ/WRITE */ 1622*26199Ssklower { 1623*26199Ssklower 1624*26199Ssklower int error; 1625*26199Ssklower 1626*26199Ssklower struct { 1627*26199Ssklower unsign16 cmd_word; /* Command Word */ 1628*26199Ssklower unsign16 shi_addr; /* High word of Source Address */ 1629*26199Ssklower unsign16 slo_addr; /* Low word of Source Address */ 1630*26199Ssklower unsign16 dhi_addr; /* High word of Destination Address */ 1631*26199Ssklower unsign16 dlo_addr; /* Low word of Destination Address */ 1632*26199Ssklower unsign16 count; /* Byte count */ 1633*26199Ssklower unsign16 intlevel; /* Interrupt level to host */ 1634*26199Ssklower } cmd_block; 1635*26199Ssklower 1636*26199Ssklower if(NpDebug & DEBENTRY) 1637*26199Ssklower printf("NPIO\n"); 1638*26199Ssklower if(NpDebug & DEBMAINT) { 1639*26199Ssklower printf("I/O src addr = %x, dest addr = %x \n",src,dest); 1640*26199Ssklower printf("I/O count = %d \n",count); 1641*26199Ssklower } 1642*26199Ssklower 1643*26199Ssklower cmd_block.cmd_word = NPCBI | NPLST | (CBICNT + IOCNT); 1644*26199Ssklower cmd_block.intlevel = mp->vector; 1645*26199Ssklower cmd_block.shi_addr = HIWORD(src); 1646*26199Ssklower cmd_block.slo_addr = LOWORD(src); 1647*26199Ssklower cmd_block.dhi_addr = HIWORD(dest); 1648*26199Ssklower cmd_block.dlo_addr = LOWORD(dest); 1649*26199Ssklower cmd_block.count = count; 1650*26199Ssklower if(dir == B_READ) 1651*26199Ssklower cmd_block.cmd_word |= NPDMP; 1652*26199Ssklower else 1653*26199Ssklower cmd_block.cmd_word |= NPLD; 1654*26199Ssklower 1655*26199Ssklower 1656*26199Ssklower if(NpDebug & DEBIO) { 1657*26199Ssklower printf("cmd: %x int: %o shi: %x slo: %x dhi: %x dlo: %x cnt: %x\n", 1658*26199Ssklower cmd_block.cmd_word,cmd_block.intlevel,cmd_block.shi_addr,cmd_block.slo_addr, 1659*26199Ssklower cmd_block.dhi_addr,cmd_block.dlo_addr,cmd_block.count); 1660*26199Ssklower } 1661*26199Ssklower 1662*26199Ssklower mp->flags |= CSRPEND; /* CSR0 command pending */ 1663*26199Ssklower 1664*26199Ssklower error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)); 1665*26199Ssklower if(NpDebug & DEBENTRY) 1666*26199Ssklower printf("NPIO...\n"); 1667*26199Ssklower 1668*26199Ssklower return(error); 1669*26199Ssklower } 1670*26199Ssklower 1671*26199Ssklower 1672*26199Ssklower /* 1673*26199Ssklower * NpKill will terminate all outstanding requests for the specified board. 1674*26199Ssklower */ 1675*26199Ssklower 1676*26199Ssklower NpKill(mp,curr_rp) 1677*26199Ssklower struct npmaster *mp; 1678*26199Ssklower struct npreq *curr_rp; 1679*26199Ssklower { 1680*26199Ssklower struct npreq *rp; 1681*26199Ssklower int s; 1682*26199Ssklower 1683*26199Ssklower if(NpDebug & DEBENTRY) 1684*26199Ssklower printf("NpKill\n"); 1685*26199Ssklower 1686*26199Ssklower mp->reqtab->reqcnt = 0; /* Init request count */ 1687*26199Ssklower 1688*26199Ssklower s = spl4(); /* Disable interrupts */ 1689*26199Ssklower 1690*26199Ssklower /* Mark each active request as having an error and wake him up */ 1691*26199Ssklower 1692*26199Ssklower for(rp = mp->reqtab->forw;rp != mp->reqtab;rp = rp->forw) { 1693*26199Ssklower 1694*26199Ssklower if(rp == curr_rp) continue; 1695*26199Ssklower 1696*26199Ssklower rp->flags |= (IOABORT | REQDONE); 1697*26199Ssklower mp->reqtab->reqcnt++; 1698*26199Ssklower if(rp->flags & NPUIO) 1699*26199Ssklower iodone(&rp->buf); 1700*26199Ssklower else wakeup((caddr_t)rp); 1701*26199Ssklower } 1702*26199Ssklower 1703*26199Ssklower if(NpDebug & DEBMAINT) 1704*26199Ssklower printf("NpKill, req count is %d\n",mp->reqtab->reqcnt); 1705*26199Ssklower 1706*26199Ssklower splx(s); 1707*26199Ssklower 1708*26199Ssklower if(NpDebug & DEBENTRY) 1709*26199Ssklower printf("NpKill...\n"); 1710*26199Ssklower 1711*26199Ssklower return(0); 1712*26199Ssklower 1713*26199Ssklower } 1714*26199Ssklower 1715*26199Ssklower /* Hardware and Software Initializations for the specified unit */ 1716*26199Ssklower 1717*26199Ssklower NpReset(mp,rp) 1718*26199Ssklower register struct npmaster *mp; 1719*26199Ssklower struct npreq *rp; 1720*26199Ssklower { 1721*26199Ssklower int error; 1722*26199Ssklower 1723*26199Ssklower if(NpDebug & DEBENTRY) 1724*26199Ssklower printf("NpReset!\n"); 1725*26199Ssklower 1726*26199Ssklower /* Mark board as being reset and make unavailable */ 1727*26199Ssklower 1728*26199Ssklower mp->flags = BRDRESET; 1729*26199Ssklower 1730*26199Ssklower /* Abort outstanding requests for this board */ 1731*26199Ssklower 1732*26199Ssklower mp->reqtab->reqcnt = 0; /* Init request count */ 1733*26199Ssklower 1734*26199Ssklower /* Wakeup Poller if available and wait until he's gone */ 1735*26199Ssklower 1736*26199Ssklower if(NpState & ICPAVAIL) { 1737*26199Ssklower 1738*26199Ssklower mp->flags |= BOARDREQ; 1739*26199Ssklower mp->reqtab->reqcnt++; 1740*26199Ssklower 1741*26199Ssklower if(NpDebug & DEBMAINT) 1742*26199Ssklower printf("Waking ICP in reset!\n"); 1743*26199Ssklower 1744*26199Ssklower wakeup((caddr_t)&NpState); 1745*26199Ssklower 1746*26199Ssklower while(mp->reqtab->reqcnt) 1747*26199Ssklower sleep((caddr_t)(&mp->reqtab),PZERO +1); 1748*26199Ssklower 1749*26199Ssklower if(NpDebug & DEBMAINT) 1750*26199Ssklower printf("Reset:awoken by ICP senior!\n"); 1751*26199Ssklower 1752*26199Ssklower } 1753*26199Ssklower 1754*26199Ssklower /* Abort outstanding requests and wait till they're gone */ 1755*26199Ssklower 1756*26199Ssklower NpKill(mp,rp); 1757*26199Ssklower 1758*26199Ssklower while(mp->reqtab->reqcnt) { 1759*26199Ssklower 1760*26199Ssklower if(NpDebug & DEBMAINT) { 1761*26199Ssklower printf("Sleeping in NpReset on reqtab!\n"); 1762*26199Ssklower printf("Reqcnt is %d.\n",mp->reqtab->reqcnt); 1763*26199Ssklower } 1764*26199Ssklower 1765*26199Ssklower sleep((caddr_t)(&mp->reqtab),PZERO +1); 1766*26199Ssklower 1767*26199Ssklower } 1768*26199Ssklower 1769*26199Ssklower /* Free up I/O Map registers if any allocated */ 1770*26199Ssklower 1771*26199Ssklower if(mp->iomapbase) { 1772*26199Ssklower 1773*26199Ssklower if(NpDebug & DEBMEM) 1774*26199Ssklower printf("freeing shared memory map.\n"); 1775*26199Ssklower 1776*26199Ssklower ubarelse(mp->devp->ui_ubanum,&mp->iomapbase); 1777*26199Ssklower mp->iomapbase = 0; 1778*26199Ssklower } 1779*26199Ssklower 1780*26199Ssklower /* Initialize S/W data structures in NP Driver */ 1781*26199Ssklower 1782*26199Ssklower NpSWinit(mp->unit); /* Software initialization */ 1783*26199Ssklower 1784*26199Ssklower /* Hardware initialization of the board */ 1785*26199Ssklower 1786*26199Ssklower error = NpHWinit(mp->unit); /* Hardware initialization */ 1787*26199Ssklower 1788*26199Ssklower mp->flags &= ~BRDRESET; /* Initialization complete */ 1789*26199Ssklower 1790*26199Ssklower /* Initialize Pseudo-Drivers */ 1791*26199Ssklower 1792*26199Ssklower WnInitFlag = 0; /* WN Pseudo-Driver */ 1793*26199Ssklower IsInitFlag = 0; /* IS Pseudo-Driver */ 1794*26199Ssklower 1795*26199Ssklower if (IxReset) 1796*26199Ssklower (*IxReset)(mp->unit, mp->devp->ui_ubanum, rp); 1797*26199Ssklower 1798*26199Ssklower /* Clear Poller's State Flag */ 1799*26199Ssklower 1800*26199Ssklower NpState = NPCLEAR; 1801*26199Ssklower 1802*26199Ssklower if(NpDebug & DEBENTRY) 1803*26199Ssklower printf("NpReset...\n"); 1804*26199Ssklower 1805*26199Ssklower return(error); 1806*26199Ssklower } 1807*26199Ssklower 1808*26199Ssklower /* 1809*26199Ssklower * General purpose timeout function which sets the flag passed to it 1810*26199Ssklower * as argument. 1811*26199Ssklower */ 1812*26199Ssklower 1813*26199Ssklower NpTimer(flagp) 1814*26199Ssklower int *flagp; 1815*26199Ssklower { 1816*26199Ssklower *flagp = NPSET; 1817*26199Ssklower } 1818*26199Ssklower 1819*26199Ssklower NpStats() 1820*26199Ssklower { 1821*26199Ssklower if(NpDebug & DEBENTRY) 1822*26199Ssklower printf("npstats\n"); 1823*26199Ssklower return(0); 1824*26199Ssklower } 1825*26199Ssklower 1826*26199Ssklower /* 1827*26199Ssklower * NpCloseConn is called to issue a close connection command to the I-Board. 1828*26199Ssklower */ 1829*26199Ssklower 1830*26199Ssklower NpCloseConn(mp,protocol) 1831*26199Ssklower struct npmaster *mp; 1832*26199Ssklower unsign16 protocol; 1833*26199Ssklower { 1834*26199Ssklower 1835*26199Ssklower register struct npreq *rp; 1836*26199Ssklower register struct CQE *ep; 1837*26199Ssklower int pri; 1838*26199Ssklower 1839*26199Ssklower if(NpDebug & DEBENTRY) 1840*26199Ssklower printf("NpCloseConn\n"); 1841*26199Ssklower 1842*26199Ssklower /* 1843*26199Ssklower * Don't issue the Close Connection command if the Board 1844*26199Ssklower * isn't up. 1845*26199Ssklower */ 1846*26199Ssklower 1847*26199Ssklower if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) { 1848*26199Ssklower return; 1849*26199Ssklower } 1850*26199Ssklower 1851*26199Ssklower /* Get a Request structure */ 1852*26199Ssklower 1853*26199Ssklower while((rp = NpGetReq(mp->reqtab)) == NULL) { 1854*26199Ssklower mp->reqtab->flags |= WANTREQ; 1855*26199Ssklower sleep((caddr_t)(mp->reqtab),PZERO -1); 1856*26199Ssklower } 1857*26199Ssklower 1858*26199Ssklower rp->intr = (int (*)())0; /* Do not call interrupt routine */ 1859*26199Ssklower rp->flags = NPCLEAR; 1860*26199Ssklower rp->mapbase = 0; /* Clear mapping information */ 1861*26199Ssklower 1862*26199Ssklower ep = rp->element; /* Handy pointer */ 1863*26199Ssklower 1864*26199Ssklower /* Fill in CQE */ 1865*26199Ssklower 1866*26199Ssklower ep->cqe_wind = 0; /* Entire buffer mapped */ 1867*26199Ssklower ep->cqe_nbuf = 1; /* Must be 1, no buffer chaining */ 1868*26199Ssklower ep->cqe_char = 0; /* Set to 0 for now */ 1869*26199Ssklower 1870*26199Ssklower ep->cqe_func = NPSTOP; /* OS_STP to I-Board */ 1871*26199Ssklower 1872*26199Ssklower ep->cqe_prot = protocol; /* Protocol of this connection */ 1873*26199Ssklower ep->cqe_lenrpb = 0; /* Parameter block length */ 1874*26199Ssklower 1875*26199Ssklower ep->cqe_ust0 = ep->cqe_ust1 = NPCLEAR; /* Clear status flags */ 1876*26199Ssklower 1877*26199Ssklower ep->cqe_famid = (unsign32)u.u_procp->p_pid; /* Process ID */ 1878*26199Ssklower 1879*26199Ssklower NpAddReq(mp->reqtab,rp); /* Queue onto active list */ 1880*26199Ssklower 1881*26199Ssklower pri = spl4(); /* Mask our interrupts */ 1882*26199Ssklower 1883*26199Ssklower NpAddCQE(ep,&mp->shmemp->devcq,mp); /* Add CQE to device's queue */ 1884*26199Ssklower 1885*26199Ssklower /* Wait for command to complete */ 1886*26199Ssklower 1887*26199Ssklower while(!(rp->flags & REQDONE)) 1888*26199Ssklower sleep((caddr_t)rp,PZERO - 1); 1889*26199Ssklower 1890*26199Ssklower splx(pri); 1891*26199Ssklower 1892*26199Ssklower NpRemReq(rp); /* Remove request from active list */ 1893*26199Ssklower 1894*26199Ssklower NpFreeReq(mp->reqtab,rp); /* Deallocate request structure */ 1895*26199Ssklower 1896*26199Ssklower if(NpDebug & DEBENTRY) 1897*26199Ssklower printf("NpCloseConn...\n"); 1898*26199Ssklower 1899*26199Ssklower } 1900*26199Ssklower 1901*26199Ssklower /* 1902*26199Ssklower * This function allows the protocol to be changed for a given connection. 1903*26199Ssklower * It returns 0 for success, error code otherwise. 1904*26199Ssklower */ 1905*26199Ssklower 1906*26199Ssklower NpProtChange(protocol,unit) 1907*26199Ssklower register unsign16 protocol; 1908*26199Ssklower register int unit; 1909*26199Ssklower { 1910*26199Ssklower 1911*26199Ssklower register struct npmaster *mp; 1912*26199Ssklower 1913*26199Ssklower /* Privileged users only for Maintenance Protocol */ 1914*26199Ssklower 1915*26199Ssklower if((protocol == NPMAINT) && (u.u_uid != 0)) 1916*26199Ssklower return(EPERM); 1917*26199Ssklower 1918*26199Ssklower if(NpDebug & DEBMAINT) 1919*26199Ssklower printf("NpProtChange = %x\n",protocol); 1920*26199Ssklower 1921*26199Ssklower if(protocol != NPMAINT) { 1922*26199Ssklower 1923*26199Ssklower /* Make sure the I-Board supports the protocol */ 1924*26199Ssklower 1925*26199Ssklower mp = &npmasters[unit]; 1926*26199Ssklower 1927*26199Ssklower if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) 1928*26199Ssklower return(ENXIO); 1929*26199Ssklower } 1930*26199Ssklower 1931*26199Ssklower return(0); 1932*26199Ssklower } 1933*26199Ssklower 1934*26199Ssklower /* 1935*26199Ssklower * This function allows for the changing of the unit for a given connection. 1936*26199Ssklower */ 1937*26199Ssklower 1938*26199Ssklower struct npmaster * 1939*26199Ssklower NpBoardChange(protocol,unit) 1940*26199Ssklower register unsign16 protocol; 1941*26199Ssklower register int unit; /* Unit number */ 1942*26199Ssklower { 1943*26199Ssklower register struct npmaster *mp; 1944*26199Ssklower 1945*26199Ssklower 1946*26199Ssklower if(unit > NNP) 1947*26199Ssklower return((struct npmaster *)0); 1948*26199Ssklower 1949*26199Ssklower if(protocol != NPMAINT) { 1950*26199Ssklower 1951*26199Ssklower /* 1952*26199Ssklower * Loop through the master structures finding a board which 1953*26199Ssklower * supports the requested protocol. 1954*26199Ssklower */ 1955*26199Ssklower 1956*26199Ssklower for(mp = npmasters; mp ; mp = mp->next) { 1957*26199Ssklower 1958*26199Ssklower if(mp->flags & BADBOARD) 1959*26199Ssklower continue; 1960*26199Ssklower 1961*26199Ssklower if(((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) 1962*26199Ssklower return(mp); 1963*26199Ssklower } 1964*26199Ssklower return((struct npmaster *)0); 1965*26199Ssklower } 1966*26199Ssklower return(&npmasters[unit]); 1967*26199Ssklower } 1968*26199Ssklower 1969*26199Ssklower /* 1970*26199Ssklower * NpMapMem - maps the user's memory updating the fields in the npreq 1971*26199Ssklower * structure and returning the mapped address in rp->buffaddr. 1972*26199Ssklower */ 1973*26199Ssklower NpMapMem(mp,rp,addr,count) 1974*26199Ssklower register struct npmaster *mp; 1975*26199Ssklower register struct npreq *rp; 1976*26199Ssklower caddr_t addr; 1977*26199Ssklower int count; 1978*26199Ssklower { 1979*26199Ssklower 1980*26199Ssklower if(NpDebug & DEBENTRY) 1981*26199Ssklower printf("NpMapMem\n"); 1982*26199Ssklower if(NpDebug & DEBIO) 1983*26199Ssklower printf("mp %x rp %x addr %x count %x\n",mp,rp,addr,count); 1984*26199Ssklower 1985*26199Ssklower rp->virtmem = addr; 1986*26199Ssklower rp->bytecnt = count; 1987*26199Ssklower 1988*26199Ssklower rp->buf.b_un.b_addr = addr; 1989*26199Ssklower rp->buf.b_flags = B_PHYS | B_BUSY; 1990*26199Ssklower rp->buf.b_bcount = count; 1991*26199Ssklower rp->buf.b_proc = rp->procp; 1992*26199Ssklower 1993*26199Ssklower rp->procp->p_flag |= SPHYSIO; 1994*26199Ssklower vslock(addr,count); 1995*26199Ssklower 1996*26199Ssklower rp->mapbase = ubasetup(mp->devp->ui_ubanum,&rp->buf,0); 1997*26199Ssklower 1998*26199Ssklower rp->bufaddr = (caddr_t)(rp->mapbase & UBADDRMASK); 1999*26199Ssklower 2000*26199Ssklower if(NpDebug & DEBENTRY) 2001*26199Ssklower printf("NpMapMem...\n"); 2002*26199Ssklower } 2003*26199Ssklower 2004*26199Ssklower /* 2005*26199Ssklower * Unmap the user's memory and free up mapping registers 2006*26199Ssklower */ 2007*26199Ssklower 2008*26199Ssklower NpUnMapMem(mp,rp) 2009*26199Ssklower struct npmaster *mp; 2010*26199Ssklower struct npreq *rp; 2011*26199Ssklower { 2012*26199Ssklower if(NpDebug & DEBENTRY) 2013*26199Ssklower printf("NpUnMapMem\n"); 2014*26199Ssklower 2015*26199Ssklower ubarelse(mp->devp->ui_ubanum,&rp->mapbase); 2016*26199Ssklower rp->mapbase = 0; 2017*26199Ssklower vsunlock(rp->virtmem,rp->bytecnt,B_READ); 2018*26199Ssklower rp->procp->p_flag &= ~SPHYSIO; 2019*26199Ssklower 2020*26199Ssklower if(NpDebug & DEBENTRY) 2021*26199Ssklower printf("NpUnMapMem...\n"); 2022*26199Ssklower } 2023*26199Ssklower 2024*26199Ssklower npprobe(reg, ui) 2025*26199Ssklower caddr_t reg; 2026*26199Ssklower struct uba_device *ui; 2027*26199Ssklower { 2028*26199Ssklower register int br,cvec; 2029*26199Ssklower u_short csraddr; 2030*26199Ssklower int i; 2031*26199Ssklower 2032*26199Ssklower #ifdef lint 2033*26199Ssklower br = 0; cvec = br; br = cvec; 2034*26199Ssklower #endif 2035*26199Ssklower 2036*26199Ssklower if(NpDebug & DEBINIT) 2037*26199Ssklower printf("In npprobe, regaddr is %x!\n",reg); 2038*26199Ssklower 2039*26199Ssklower cvec = (uba_hd[numuba].uh_lastiv -= 4); 2040*26199Ssklower 2041*26199Ssklower #ifdef OLDBSD4_2 2042*26199Ssklower /* Find unit number from npstd[] by matching the csr address */ 2043*26199Ssklower 2044*26199Ssklower csraddr = (u_short)((int)reg & 0x0FFFF); 2045*26199Ssklower 2046*26199Ssklower for(i = 0; i < NNP; i++) { 2047*26199Ssklower 2048*26199Ssklower if(csraddr == npstd[i]) { 2049*26199Ssklower npvectors[i] = cvec; 2050*26199Ssklower break; 2051*26199Ssklower } 2052*26199Ssklower } 2053*26199Ssklower if(i == NNP) 2054*26199Ssklower printf("Couldn't find device in npstd[]!\n"); 2055*26199Ssklower #else 2056*26199Ssklower npvectors[ui->ui_unit] = cvec; 2057*26199Ssklower #endif 2058*26199Ssklower br = 0x15; 2059*26199Ssklower 2060*26199Ssklower if(NpDebug & DEBINIT) 2061*26199Ssklower printf("npprobe...\n"); 2062*26199Ssklower 2063*26199Ssklower return(sizeof(struct NPREG)); /* CSR Registers */ 2064*26199Ssklower 2065*26199Ssklower } 2066*26199Ssklower 2067*26199Ssklower npattach(ui) 2068*26199Ssklower register struct uba_device *ui; 2069*26199Ssklower { 2070*26199Ssklower 2071*26199Ssklower if(NpDebug & DEBINIT) 2072*26199Ssklower printf("In npattach, ui is %x.\n",ui); 2073*26199Ssklower 2074*26199Ssklower npinit(ui->ui_unit); 2075*26199Ssklower 2076*26199Ssklower if (IxAttach) 2077*26199Ssklower (*IxAttach)(ui); 2078*26199Ssklower 2079*26199Ssklower if(NpDebug & DEBINIT) 2080*26199Ssklower printf("npattach...\n"); 2081*26199Ssklower } 2082*26199Ssklower 2083*26199Ssklower #endif 2084