33 */ 34 35/* 36 * rp.c - for RocketPort FreeBSD 37 */ 38 39#include "opt_compat.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/fcntl.h> 44#include <sys/malloc.h> 45#include <sys/tty.h> 46#include <sys/proc.h> 47#include <sys/conf.h> 48#include <sys/kernel.h> 49 50#include <i386/isa/isa_device.h> 51 52#include <pci/pcivar.h> 53 54#define ROCKET_C 55#include <i386/isa/rpreg.h> 56#include <i386/isa/rpvar.h> 57 58#ifndef TRUE 59#define TRUE 1 60#endif 61 62#ifndef FALSE 63#define FALSE 0 64#endif 65 66static Byte_t RData[RDATASIZE] = 67{ 68 0x00, 0x09, 0xf6, 0x82, 69 0x02, 0x09, 0x86, 0xfb, 70 0x04, 0x09, 0x00, 0x0a, 71 0x06, 0x09, 0x01, 0x0a, 72 0x08, 0x09, 0x8a, 0x13, 73 0x0a, 0x09, 0xc5, 0x11, 74 0x0c, 0x09, 0x86, 0x85, 75 0x0e, 0x09, 0x20, 0x0a, 76 0x10, 0x09, 0x21, 0x0a, 77 0x12, 0x09, 0x41, 0xff, 78 0x14, 0x09, 0x82, 0x00, 79 0x16, 0x09, 0x82, 0x7b, 80 0x18, 0x09, 0x8a, 0x7d, 81 0x1a, 0x09, 0x88, 0x81, 82 0x1c, 0x09, 0x86, 0x7a, 83 0x1e, 0x09, 0x84, 0x81, 84 0x20, 0x09, 0x82, 0x7c, 85 0x22, 0x09, 0x0a, 0x0a 86}; 87 88static Byte_t RRegData[RREGDATASIZE]= 89{ 90 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */ 91 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */ 92 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */ 93 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */ 94 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */ 95 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */ 96 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */ 97 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */ 98 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */ 99 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */ 100 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */ 101 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */ 102 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */ 103}; 104 105static CONTROLLER_T sController[CTL_SIZE] = 106{ 107 {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}}, 108 {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}}, 109 {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}}, 110 {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}} 111}; 112 113#if 0 114/* IRQ number to MUDBAC register 2 mapping */ 115Byte_t sIRQMap[16] = 116{ 117 0,0,0,0x10,0x20,0x30,0,0,0,0x40,0x50,0x60,0x70,0,0,0x80 118}; 119#endif 120 121static Byte_t sBitMapClrTbl[8] = 122{ 123 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f 124}; 125 126static Byte_t sBitMapSetTbl[8] = 127{ 128 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 129}; 130 131/*************************************************************************** 132Function: sInitController 133Purpose: Initialization of controller global registers and controller 134 structure. 135Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize, 136 IRQNum,Frequency,PeriodicOnly) 137 CONTROLLER_T *CtlP; Ptr to controller structure 138 int CtlNum; Controller number 139 ByteIO_t MudbacIO; Mudbac base I/O address. 140 ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. 141 This list must be in the order the AIOPs will be found on the 142 controller. Once an AIOP in the list is not found, it is 143 assumed that there are no more AIOPs on the controller. 144 int AiopIOListSize; Number of addresses in AiopIOList 145 int IRQNum; Interrupt Request number. Can be any of the following: 146 0: Disable global interrupts 147 3: IRQ 3 148 4: IRQ 4 149 5: IRQ 5 150 9: IRQ 9 151 10: IRQ 10 152 11: IRQ 11 153 12: IRQ 12 154 15: IRQ 15 155 Byte_t Frequency: A flag identifying the frequency 156 of the periodic interrupt, can be any one of the following: 157 FREQ_DIS - periodic interrupt disabled 158 FREQ_137HZ - 137 Hertz 159 FREQ_69HZ - 69 Hertz 160 FREQ_34HZ - 34 Hertz 161 FREQ_17HZ - 17 Hertz 162 FREQ_9HZ - 9 Hertz 163 FREQ_4HZ - 4 Hertz 164 If IRQNum is set to 0 the Frequency parameter is 165 overidden, it is forced to a value of FREQ_DIS. 166 int PeriodicOnly: TRUE if all interrupts except the periodic 167 interrupt are to be blocked. 168 FALSE is both the periodic interrupt and 169 other channel interrupts are allowed. 170 If IRQNum is set to 0 the PeriodicOnly parameter is 171 overidden, it is forced to a value of FALSE. 172Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller 173 initialization failed. 174 175Comments: 176 If periodic interrupts are to be disabled but AIOP interrupts 177 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. 178 179 If interrupts are to be completely disabled set IRQNum to 0. 180 181 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an 182 invalid combination. 183 184 This function performs initialization of global interrupt modes, 185 but it does not actually enable global interrupts. To enable 186 and disable global interrupts use functions sEnGlobalInt() and 187 sDisGlobalInt(). Enabling of global interrupts is normally not 188 done until all other initializations are complete. 189 190 Even if interrupts are globally enabled, they must also be 191 individually enabled for each channel that is to generate 192 interrupts. 193 194Warnings: No range checking on any of the parameters is done. 195 196 No context switches are allowed while executing this function. 197 198 After this function all AIOPs on the controller are disabled, 199 they can be enabled with sEnAiop(). 200*/ 201int sInitController( CONTROLLER_T *CtlP, 202 int CtlNum, 203 ByteIO_t MudbacIO, 204 ByteIO_t *AiopIOList, 205 int AiopIOListSize, 206 int IRQNum, 207 Byte_t Frequency, 208 int PeriodicOnly) 209{ 210 int i; 211 ByteIO_t io; 212 213 CtlP->CtlNum = CtlNum; 214 CtlP->BusType = isISA; 215 CtlP->CtlID = CTLID_0001; /* controller release 1 */ 216 217 CtlP->MBaseIO = MudbacIO; 218 CtlP->MReg1IO = MudbacIO + 1; 219 CtlP->MReg2IO = MudbacIO + 2; 220 CtlP->MReg3IO = MudbacIO + 3; 221#if 1 222 CtlP->MReg2 = 0; /* interrupt disable */ 223 CtlP->MReg3 = 0; /* no periodic interrupts */ 224#else 225 if(sIRQMap[IRQNum] == 0) /* interrupts globally disabled */ 226 { 227 CtlP->MReg2 = 0; /* interrupt disable */ 228 CtlP->MReg3 = 0; /* no periodic interrupts */ 229 } 230 else 231 { 232 CtlP->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */ 233 CtlP->MReg3 = Frequency; /* set frequency */ 234 if(PeriodicOnly) /* periodic interrupt only */ 235 { 236 CtlP->MReg3 |= PERIODIC_ONLY; 237 } 238 } 239#endif 240 sOutB(CtlP->MReg2IO,CtlP->MReg2); 241 sOutB(CtlP->MReg3IO,CtlP->MReg3); 242 sControllerEOI(CtlP); /* clear EOI if warm init */ 243 244 /* Init AIOPs */ 245 CtlP->NumAiop = 0; 246 for(i=0; i < AiopIOListSize; i++) 247 { 248 io = AiopIOList[i]; 249 CtlP->AiopIO[i] = (WordIO_t)io; 250 CtlP->AiopIntChanIO[i] = io + _INT_CHAN; 251 sOutB(CtlP->MReg2IO,CtlP->MReg2 | (i & 0x03)); /* AIOP index */ 252 sOutB(MudbacIO,(Byte_t)(io >> 6)); /* set up AIOP I/O in MUDBAC */ 253 sEnAiop(CtlP,i); /* enable the AIOP */ 254 255 CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ 256 if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ 257 { 258 sDisAiop(CtlP,i); /* disable AIOP */ 259 break; /* done looking for AIOPs */ 260 } 261 262 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */ 263 sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE); /* clock prescaler */ 264 sOutB(io + _INDX_DATA,CLOCK_PRESC); 265 CtlP->NumAiop++; /* bump count of AIOPs */ 266 sDisAiop(CtlP,i); /* disable AIOP */ 267 } 268 269 if(CtlP->NumAiop == 0) 270 return(-1); 271 else 272 return(CtlP->NumAiop); 273} 274 275int sPCIInitController( CONTROLLER_T *CtlP, 276 int CtlNum, 277 ByteIO_t *AiopIOList, 278 int AiopIOListSize, 279 int IRQNum, 280 Byte_t Frequency, 281 int PeriodicOnly) 282{ 283 int i; 284 ByteIO_t io; 285 286 CtlP->CtlNum = CtlNum; 287 CtlP->BusType = isPCI; 288 CtlP->CtlID = CTLID_0001; /* controller release 1 */ 289 CtlP->PCIIO = (WordIO_t)((ByteIO_t)AiopIOList[0] + _PCI_INT_FUNC); 290 291 sPCIControllerEOI(CtlP); 292 293 /* Init AIOPs */ 294 CtlP->NumAiop = 0; 295 for(i=0; i < AiopIOListSize; i++) 296 { 297 io = AiopIOList[i]; 298 CtlP->AiopIO[i] = (WordIO_t)io; 299 CtlP->AiopIntChanIO[i] = io + _INT_CHAN; 300 301 CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ 302 if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ 303 { 304 break; /* done looking for AIOPs */ 305 } 306 307 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */ 308 sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE); /* clock prescaler */ 309 sOutB(io + _INDX_DATA,CLOCK_PRESC); 310 CtlP->NumAiop++; /* bump count of AIOPs */ 311 } 312 313 if(CtlP->NumAiop == 0) 314 return(-1); 315 else 316 return(CtlP->NumAiop); 317} 318 319/*************************************************************************** 320Function: sReadAiopID 321Purpose: Read the AIOP idenfication number directly from an AIOP. 322Call: sReadAiopID(io) 323 ByteIO_t io: AIOP base I/O address 324Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X 325 is replace by an identifying number. 326 Flag AIOPID_NULL if no valid AIOP is found 327Warnings: No context switches are allowed while executing this function. 328 329*/ 330int sReadAiopID(ByteIO_t io) 331{ 332 Byte_t AiopID; /* ID byte from AIOP */ 333 334 sOutB(io + _CMD_REG,RESET_ALL); /* reset AIOP */ 335 sOutB(io + _CMD_REG,0x0); 336 AiopID = sInB(io + _CHN_STAT0) & 0x07; 337 if(AiopID == 0x06) 338 return(1); 339 else /* AIOP does not exist */ 340 return(-1); 341} 342 343/*************************************************************************** 344Function: sReadAiopNumChan 345Purpose: Read the number of channels available in an AIOP directly from 346 an AIOP. 347Call: sReadAiopNumChan(io) 348 WordIO_t io: AIOP base I/O address 349Return: int: The number of channels available 350Comments: The number of channels is determined by write/reads from identical 351 offsets within the SRAM address spaces for channels 0 and 4. 352 If the channel 4 space is mirrored to channel 0 it is a 4 channel 353 AIOP, otherwise it is an 8 channel. 354Warnings: No context switches are allowed while executing this function. 355*/ 356int sReadAiopNumChan(WordIO_t io) 357{ 358 Word_t x; 359 360 sOutDW((DWordIO_t)io + _INDX_ADDR,0x12340000L); /* write to chan 0 SRAM */ 361 sOutW(io + _INDX_ADDR,0); /* read from SRAM, chan 0 */ 362 x = sInW(io + _INDX_DATA); 363 sOutW(io + _INDX_ADDR,0x4000); /* read from SRAM, chan 4 */ 364 if(x != sInW(io + _INDX_DATA)) /* if different must be 8 chan */ 365 return(8); 366 else 367 return(4); 368} 369 370/*************************************************************************** 371Function: sInitChan 372Purpose: Initialization of a channel and channel structure 373Call: sInitChan(CtlP,ChP,AiopNum,ChanNum) 374 CONTROLLER_T *CtlP; Ptr to controller structure 375 CHANNEL_T *ChP; Ptr to channel structure 376 int AiopNum; AIOP number within controller 377 int ChanNum; Channel number within AIOP 378Return: int: TRUE if initialization succeeded, FALSE if it fails because channel 379 number exceeds number of channels available in AIOP. 380Comments: This function must be called before a channel can be used. 381Warnings: No range checking on any of the parameters is done. 382 383 No context switches are allowed while executing this function. 384*/ 385int sInitChan( CONTROLLER_T *CtlP, 386 CHANNEL_T *ChP, 387 int AiopNum, 388 int ChanNum) 389{ 390 int i; 391 WordIO_t AiopIO; 392 WordIO_t ChIOOff; 393 Byte_t *ChR; 394 Word_t ChOff; 395 static Byte_t R[4]; 396 397 if(ChanNum >= CtlP->AiopNumChan[AiopNum]) 398 return(FALSE); /* exceeds num chans in AIOP */ 399 400 /* Channel, AIOP, and controller identifiers */ 401 ChP->CtlP = CtlP; 402 ChP->ChanID = CtlP->AiopID[AiopNum]; 403 ChP->AiopNum = AiopNum; 404 ChP->ChanNum = ChanNum; 405 406 /* Global direct addresses */ 407 AiopIO = CtlP->AiopIO[AiopNum]; 408 ChP->Cmd = (ByteIO_t)AiopIO + _CMD_REG; 409 ChP->IntChan = (ByteIO_t)AiopIO + _INT_CHAN; 410 ChP->IntMask = (ByteIO_t)AiopIO + _INT_MASK; 411 ChP->IndexAddr = (DWordIO_t)AiopIO + _INDX_ADDR; 412 ChP->IndexData = AiopIO + _INDX_DATA; 413 414 /* Channel direct addresses */ 415 ChIOOff = AiopIO + ChP->ChanNum * 2; 416 ChP->TxRxData = ChIOOff + _TD0; 417 ChP->ChanStat = ChIOOff + _CHN_STAT0; 418 ChP->TxRxCount = ChIOOff + _FIFO_CNT0; 419 ChP->IntID = (ByteIO_t)AiopIO + ChP->ChanNum + _INT_ID0; 420 421 /* Initialize the channel from the RData array */ 422 for(i=0; i < RDATASIZE; i+=4) 423 { 424 R[0] = RData[i]; 425 R[1] = RData[i+1] + 0x10 * ChanNum; 426 R[2] = RData[i+2]; 427 R[3] = RData[i+3]; 428 sOutDW(ChP->IndexAddr,*((DWord_t *)&R[0])); 429 } 430 431 ChR = ChP->R; 432 for(i=0; i < RREGDATASIZE; i+=4) 433 { 434 ChR[i] = RRegData[i]; 435 ChR[i+1] = RRegData[i+1] + 0x10 * ChanNum; 436 ChR[i+2] = RRegData[i+2]; 437 ChR[i+3] = RRegData[i+3]; 438 } 439 440 /* Indexed registers */ 441 ChOff = (Word_t)ChanNum * 0x1000; 442 443 ChP->BaudDiv[0] = (Byte_t)(ChOff + _BAUD); 444 ChP->BaudDiv[1] = (Byte_t)((ChOff + _BAUD) >> 8); 445 ChP->BaudDiv[2] = (Byte_t)BRD9600; 446 ChP->BaudDiv[3] = (Byte_t)(BRD9600 >> 8); 447 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->BaudDiv[0]); 448 449 ChP->TxControl[0] = (Byte_t)(ChOff + _TX_CTRL); 450 ChP->TxControl[1] = (Byte_t)((ChOff + _TX_CTRL) >> 8); 451 ChP->TxControl[2] = 0; 452 ChP->TxControl[3] = 0; 453 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]); 454 455 ChP->RxControl[0] = (Byte_t)(ChOff + _RX_CTRL); 456 ChP->RxControl[1] = (Byte_t)((ChOff + _RX_CTRL) >> 8); 457 ChP->RxControl[2] = 0; 458 ChP->RxControl[3] = 0; 459 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]); 460 461 ChP->TxEnables[0] = (Byte_t)(ChOff + _TX_ENBLS); 462 ChP->TxEnables[1] = (Byte_t)((ChOff + _TX_ENBLS) >> 8); 463 ChP->TxEnables[2] = 0; 464 ChP->TxEnables[3] = 0; 465 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxEnables[0]); 466 467 ChP->TxCompare[0] = (Byte_t)(ChOff + _TXCMP1); 468 ChP->TxCompare[1] = (Byte_t)((ChOff + _TXCMP1) >> 8); 469 ChP->TxCompare[2] = 0; 470 ChP->TxCompare[3] = 0; 471 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxCompare[0]); 472 473 ChP->TxReplace1[0] = (Byte_t)(ChOff + _TXREP1B1); 474 ChP->TxReplace1[1] = (Byte_t)((ChOff + _TXREP1B1) >> 8); 475 ChP->TxReplace1[2] = 0; 476 ChP->TxReplace1[3] = 0; 477 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace1[0]); 478 479 ChP->TxReplace2[0] = (Byte_t)(ChOff + _TXREP2); 480 ChP->TxReplace2[1] = (Byte_t)((ChOff + _TXREP2) >> 8); 481 ChP->TxReplace2[2] = 0; 482 ChP->TxReplace2[3] = 0; 483 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace2[0]); 484 485 ChP->TxFIFOPtrs = ChOff + _TXF_OUTP; 486 ChP->TxFIFO = ChOff + _TX_FIFO; 487 488 sOutB(ChP->Cmd,(Byte_t)ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */ 489 sOutB(ChP->Cmd,(Byte_t)ChanNum); /* remove reset Tx FIFO count */ 490 sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */ 491 sOutW(ChP->IndexData,0); 492 ChP->RxFIFOPtrs = ChOff + _RXF_OUTP; 493 ChP->RxFIFO = ChOff + _RX_FIFO; 494 495 sOutB(ChP->Cmd,(Byte_t)ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */ 496 sOutB(ChP->Cmd,(Byte_t)ChanNum); /* remove reset Rx FIFO count */ 497 sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */ 498 sOutW(ChP->IndexData,0); 499 sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */ 500 sOutW(ChP->IndexData,0); 501 ChP->TxPrioCnt = ChOff + _TXP_CNT; 502 sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioCnt); 503 sOutB(ChP->IndexData,0); 504 ChP->TxPrioPtr = ChOff + _TXP_PNTR; 505 sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioPtr); 506 sOutB(ChP->IndexData,0); 507 ChP->TxPrioBuf = ChOff + _TXP_BUF; 508 sEnRxProcessor(ChP); /* start the Rx processor */ 509 510 return(TRUE); 511} 512 513/*************************************************************************** 514Function: sStopRxProcessor 515Purpose: Stop the receive processor from processing a channel. 516Call: sStopRxProcessor(ChP) 517 CHANNEL_T *ChP; Ptr to channel structure 518 519Comments: The receive processor can be started again with sStartRxProcessor(). 520 This function causes the receive processor to skip over the 521 stopped channel. It does not stop it from processing other channels. 522 523Warnings: No context switches are allowed while executing this function. 524 525 Do not leave the receive processor stopped for more than one 526 character time. 527 528 After calling this function a delay of 4 uS is required to ensure 529 that the receive processor is no longer processing this channel. 530*/ 531void sStopRxProcessor(CHANNEL_T *ChP) 532{ 533 Byte_t R[4]; 534 535 R[0] = ChP->R[0]; 536 R[1] = ChP->R[1]; 537 R[2] = 0x0a; 538 R[3] = ChP->R[3]; 539 sOutDW(ChP->IndexAddr,*(DWord_t *)&R[0]); 540} 541 542/*************************************************************************** 543Function: sFlushRxFIFO 544Purpose: Flush the Rx FIFO 545Call: sFlushRxFIFO(ChP) 546 CHANNEL_T *ChP; Ptr to channel structure 547Return: void 548Comments: To prevent data from being enqueued or dequeued in the Tx FIFO 549 while it is being flushed the receive processor is stopped 550 and the transmitter is disabled. After these operations a 551 4 uS delay is done before clearing the pointers to allow 552 the receive processor to stop. These items are handled inside 553 this function. 554Warnings: No context switches are allowed while executing this function. 555*/ 556void sFlushRxFIFO(CHANNEL_T *ChP) 557{ 558 int i; 559 Byte_t Ch; /* channel number within AIOP */ 560 int RxFIFOEnabled; /* TRUE if Rx FIFO enabled */ 561 562 if(sGetRxCnt(ChP) == 0) /* Rx FIFO empty */ 563 return; /* don't need to flush */ 564 565 RxFIFOEnabled = FALSE; 566 if(ChP->R[0x32] == 0x08) /* Rx FIFO is enabled */ 567 { 568 RxFIFOEnabled = TRUE; 569 sDisRxFIFO(ChP); /* disable it */ 570 for(i=0; i < 2000/200; i++) /* delay 2 uS to allow proc to disable FIFO*/ 571 sInB(ChP->IntChan); /* depends on bus i/o timing */ 572 } 573 sGetChanStatus(ChP); /* clear any pending Rx errors in chan stat */ 574 Ch = (Byte_t)sGetChanNum(ChP); 575 sOutB(ChP->Cmd,Ch | RESRXFCNT); /* apply reset Rx FIFO count */ 576 sOutB(ChP->Cmd,Ch); /* remove reset Rx FIFO count */ 577 sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */ 578 sOutW(ChP->IndexData,0); 579 sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */ 580 sOutW(ChP->IndexData,0); 581 if(RxFIFOEnabled) 582 sEnRxFIFO(ChP); /* enable Rx FIFO */ 583} 584 585/*************************************************************************** 586Function: sFlushTxFIFO 587Purpose: Flush the Tx FIFO 588Call: sFlushTxFIFO(ChP) 589 CHANNEL_T *ChP; Ptr to channel structure 590Return: void 591Comments: To prevent data from being enqueued or dequeued in the Tx FIFO 592 while it is being flushed the receive processor is stopped 593 and the transmitter is disabled. After these operations a 594 4 uS delay is done before clearing the pointers to allow 595 the receive processor to stop. These items are handled inside 596 this function. 597Warnings: No context switches are allowed while executing this function. 598*/ 599void sFlushTxFIFO(CHANNEL_T *ChP) 600{ 601 int i; 602 Byte_t Ch; /* channel number within AIOP */ 603 int TxEnabled; /* TRUE if transmitter enabled */ 604 605 if(sGetTxCnt(ChP) == 0) /* Tx FIFO empty */ 606 return; /* don't need to flush */ 607 608 TxEnabled = FALSE; 609 if(ChP->TxControl[3] & TX_ENABLE) 610 { 611 TxEnabled = TRUE; 612 sDisTransmit(ChP); /* disable transmitter */ 613 } 614 sStopRxProcessor(ChP); /* stop Rx processor */ 615 for(i = 0; i < 4000/200; i++) /* delay 4 uS to allow proc to stop */ 616 sInB(ChP->IntChan); /* depends on bus i/o timing */ 617 Ch = (Byte_t)sGetChanNum(ChP); 618 sOutB(ChP->Cmd,Ch | RESTXFCNT); /* apply reset Tx FIFO count */ 619 sOutB(ChP->Cmd,Ch); /* remove reset Tx FIFO count */ 620 sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */ 621 sOutW(ChP->IndexData,0); 622 if(TxEnabled) 623 sEnTransmit(ChP); /* enable transmitter */ 624 sStartRxProcessor(ChP); /* restart Rx processor */ 625} 626 627/*************************************************************************** 628Function: sWriteTxPrioByte 629Purpose: Write a byte of priority transmit data to a channel 630Call: sWriteTxPrioByte(ChP,Data) 631 CHANNEL_T *ChP; Ptr to channel structure 632 Byte_t Data; The transmit data byte 633 634Return: int: 1 if the bytes is successfully written, otherwise 0. 635 636Comments: The priority byte is transmitted before any data in the Tx FIFO. 637 638Warnings: No context switches are allowed while executing this function. 639*/ 640int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data) 641{ 642 Byte_t DWBuf[4]; /* buffer for double word writes */ 643 Word_t *WordPtr; /* must be far because Win SS != DS */ 644 register DWordIO_t IndexAddr; 645 646 if(sGetTxCnt(ChP) > 1) /* write it to Tx priority buffer */ 647 { 648 IndexAddr = ChP->IndexAddr; 649 sOutW((WordIO_t)IndexAddr,ChP->TxPrioCnt); /* get priority buffer status */ 650 if(sInB((ByteIO_t)ChP->IndexData) & PRI_PEND) /* priority buffer busy */ 651 return(0); /* nothing sent */ 652 653 WordPtr = (Word_t *)(&DWBuf[0]); 654 *WordPtr = ChP->TxPrioBuf; /* data byte address */ 655 656 DWBuf[2] = Data; /* data byte value */ 657 sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */ 658 659 *WordPtr = ChP->TxPrioCnt; /* Tx priority count address */ 660 661 DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */ 662 DWBuf[3] = 0; /* priority buffer pointer */ 663 sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */ 664 } 665 else /* write it to Tx FIFO */ 666 { 667 sWriteTxByte(sGetTxRxDataIO(ChP),Data); 668 } 669 return(1); /* 1 byte sent */ 670} 671 672/*************************************************************************** 673Function: sEnInterrupts 674Purpose: Enable one or more interrupts for a channel 675Call: sEnInterrupts(ChP,Flags) 676 CHANNEL_T *ChP; Ptr to channel structure 677 Word_t Flags: Interrupt enable flags, can be any combination 678 of the following flags: 679 TXINT_EN: Interrupt on Tx FIFO empty 680 RXINT_EN: Interrupt on Rx FIFO at trigger level (see 681 sSetRxTrigger()) 682 SRCINT_EN: Interrupt on SRC (Special Rx Condition) 683 MCINT_EN: Interrupt on modem input change 684 CHANINT_EN: Allow channel interrupt signal to the AIOP's 685 Interrupt Channel Register. 686Return: void 687Comments: If an interrupt enable flag is set in Flags, that interrupt will be 688 enabled. If an interrupt enable flag is not set in Flags, that 689 interrupt will not be changed. Interrupts can be disabled with 690 function sDisInterrupts(). 691 692 This function sets the appropriate bit for the channel in the AIOP's 693 Interrupt Mask Register if the CHANINT_EN flag is set. This allows 694 this channel's bit to be set in the AIOP's Interrupt Channel Register. 695 696 Interrupts must also be globally enabled before channel interrupts 697 will be passed on to the host. This is done with function 698 sEnGlobalInt(). 699 700 In some cases it may be desirable to disable interrupts globally but 701 enable channel interrupts. This would allow the global interrupt 702 status register to be used to determine which AIOPs need service. 703*/ 704void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags) 705{ 706 Byte_t Mask; /* Interrupt Mask Register */ 707 708 ChP->RxControl[2] |= 709 ((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN)); 710 711 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]); 712 713 ChP->TxControl[2] |= ((Byte_t)Flags & TXINT_EN); 714 715 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]); 716 717 if(Flags & CHANINT_EN) 718 { 719 Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum]; 720 sOutB(ChP->IntMask,Mask); 721 } 722} 723 724/*************************************************************************** 725Function: sDisInterrupts 726Purpose: Disable one or more interrupts for a channel 727Call: sDisInterrupts(ChP,Flags) 728 CHANNEL_T *ChP; Ptr to channel structure 729 Word_t Flags: Interrupt flags, can be any combination 730 of the following flags: 731 TXINT_EN: Interrupt on Tx FIFO empty 732 RXINT_EN: Interrupt on Rx FIFO at trigger level (see 733 sSetRxTrigger()) 734 SRCINT_EN: Interrupt on SRC (Special Rx Condition) 735 MCINT_EN: Interrupt on modem input change 736 CHANINT_EN: Disable channel interrupt signal to the 737 AIOP's Interrupt Channel Register. 738Return: void 739Comments: If an interrupt flag is set in Flags, that interrupt will be 740 disabled. If an interrupt flag is not set in Flags, that 741 interrupt will not be changed. Interrupts can be enabled with 742 function sEnInterrupts(). 743 744 This function clears the appropriate bit for the channel in the AIOP's 745 Interrupt Mask Register if the CHANINT_EN flag is set. This blocks 746 this channel's bit from being set in the AIOP's Interrupt Channel 747 Register. 748*/ 749void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags) 750{ 751 Byte_t Mask; /* Interrupt Mask Register */ 752 753 ChP->RxControl[2] &= 754 ~((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN)); 755 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]); 756 ChP->TxControl[2] &= ~((Byte_t)Flags & TXINT_EN); 757 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]); 758 759 if(Flags & CHANINT_EN) 760 { 761 Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum]; 762 sOutB(ChP->IntMask,Mask); 763 } 764} 765 766/********************************************************************* 767 Begin FreeBsd-specific driver code 768**********************************************************************/ 769 770static int rpprobe __P((struct isa_device *)); 771static int rpattach __P((struct isa_device *)); 772 773static const char* rp_pciprobe(pcici_t tag, pcidi_t type); 774static void rp_pciattach(pcici_t tag, int unit); 775static u_long rp_pcicount; 776 777static struct pci_device rp_pcidevice = { 778 "rp", 779 rp_pciprobe, 780 rp_pciattach, 781 &rp_pcicount, 782 NULL 783}; 784 785COMPAT_PCI_DRIVER (rp_pci, rp_pcidevice); 786 787static timeout_t rpdtrwakeup; 788 789struct isa_driver rpdriver = { 790 rpprobe, rpattach, "rp" 791 }; 792 793static char driver_name[] = "rp"; 794 795static d_open_t rpopen; 796static d_close_t rpclose; 797static d_read_t rpread; 798static d_write_t rpwrite; 799static d_ioctl_t rpioctl; 800static d_stop_t rpstop; 801static d_devtotty_t rpdevtotty; 802 803#define CDEV_MAJOR 81
| 33 */ 34 35/* 36 * rp.c - for RocketPort FreeBSD 37 */ 38 39#include "opt_compat.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/fcntl.h> 44#include <sys/malloc.h> 45#include <sys/tty.h> 46#include <sys/proc.h> 47#include <sys/conf.h> 48#include <sys/kernel.h> 49 50#include <i386/isa/isa_device.h> 51 52#include <pci/pcivar.h> 53 54#define ROCKET_C 55#include <i386/isa/rpreg.h> 56#include <i386/isa/rpvar.h> 57 58#ifndef TRUE 59#define TRUE 1 60#endif 61 62#ifndef FALSE 63#define FALSE 0 64#endif 65 66static Byte_t RData[RDATASIZE] = 67{ 68 0x00, 0x09, 0xf6, 0x82, 69 0x02, 0x09, 0x86, 0xfb, 70 0x04, 0x09, 0x00, 0x0a, 71 0x06, 0x09, 0x01, 0x0a, 72 0x08, 0x09, 0x8a, 0x13, 73 0x0a, 0x09, 0xc5, 0x11, 74 0x0c, 0x09, 0x86, 0x85, 75 0x0e, 0x09, 0x20, 0x0a, 76 0x10, 0x09, 0x21, 0x0a, 77 0x12, 0x09, 0x41, 0xff, 78 0x14, 0x09, 0x82, 0x00, 79 0x16, 0x09, 0x82, 0x7b, 80 0x18, 0x09, 0x8a, 0x7d, 81 0x1a, 0x09, 0x88, 0x81, 82 0x1c, 0x09, 0x86, 0x7a, 83 0x1e, 0x09, 0x84, 0x81, 84 0x20, 0x09, 0x82, 0x7c, 85 0x22, 0x09, 0x0a, 0x0a 86}; 87 88static Byte_t RRegData[RREGDATASIZE]= 89{ 90 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */ 91 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */ 92 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */ 93 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */ 94 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */ 95 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */ 96 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */ 97 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */ 98 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */ 99 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */ 100 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */ 101 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */ 102 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */ 103}; 104 105static CONTROLLER_T sController[CTL_SIZE] = 106{ 107 {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}}, 108 {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}}, 109 {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}}, 110 {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}} 111}; 112 113#if 0 114/* IRQ number to MUDBAC register 2 mapping */ 115Byte_t sIRQMap[16] = 116{ 117 0,0,0,0x10,0x20,0x30,0,0,0,0x40,0x50,0x60,0x70,0,0,0x80 118}; 119#endif 120 121static Byte_t sBitMapClrTbl[8] = 122{ 123 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f 124}; 125 126static Byte_t sBitMapSetTbl[8] = 127{ 128 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 129}; 130 131/*************************************************************************** 132Function: sInitController 133Purpose: Initialization of controller global registers and controller 134 structure. 135Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize, 136 IRQNum,Frequency,PeriodicOnly) 137 CONTROLLER_T *CtlP; Ptr to controller structure 138 int CtlNum; Controller number 139 ByteIO_t MudbacIO; Mudbac base I/O address. 140 ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. 141 This list must be in the order the AIOPs will be found on the 142 controller. Once an AIOP in the list is not found, it is 143 assumed that there are no more AIOPs on the controller. 144 int AiopIOListSize; Number of addresses in AiopIOList 145 int IRQNum; Interrupt Request number. Can be any of the following: 146 0: Disable global interrupts 147 3: IRQ 3 148 4: IRQ 4 149 5: IRQ 5 150 9: IRQ 9 151 10: IRQ 10 152 11: IRQ 11 153 12: IRQ 12 154 15: IRQ 15 155 Byte_t Frequency: A flag identifying the frequency 156 of the periodic interrupt, can be any one of the following: 157 FREQ_DIS - periodic interrupt disabled 158 FREQ_137HZ - 137 Hertz 159 FREQ_69HZ - 69 Hertz 160 FREQ_34HZ - 34 Hertz 161 FREQ_17HZ - 17 Hertz 162 FREQ_9HZ - 9 Hertz 163 FREQ_4HZ - 4 Hertz 164 If IRQNum is set to 0 the Frequency parameter is 165 overidden, it is forced to a value of FREQ_DIS. 166 int PeriodicOnly: TRUE if all interrupts except the periodic 167 interrupt are to be blocked. 168 FALSE is both the periodic interrupt and 169 other channel interrupts are allowed. 170 If IRQNum is set to 0 the PeriodicOnly parameter is 171 overidden, it is forced to a value of FALSE. 172Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller 173 initialization failed. 174 175Comments: 176 If periodic interrupts are to be disabled but AIOP interrupts 177 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. 178 179 If interrupts are to be completely disabled set IRQNum to 0. 180 181 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an 182 invalid combination. 183 184 This function performs initialization of global interrupt modes, 185 but it does not actually enable global interrupts. To enable 186 and disable global interrupts use functions sEnGlobalInt() and 187 sDisGlobalInt(). Enabling of global interrupts is normally not 188 done until all other initializations are complete. 189 190 Even if interrupts are globally enabled, they must also be 191 individually enabled for each channel that is to generate 192 interrupts. 193 194Warnings: No range checking on any of the parameters is done. 195 196 No context switches are allowed while executing this function. 197 198 After this function all AIOPs on the controller are disabled, 199 they can be enabled with sEnAiop(). 200*/ 201int sInitController( CONTROLLER_T *CtlP, 202 int CtlNum, 203 ByteIO_t MudbacIO, 204 ByteIO_t *AiopIOList, 205 int AiopIOListSize, 206 int IRQNum, 207 Byte_t Frequency, 208 int PeriodicOnly) 209{ 210 int i; 211 ByteIO_t io; 212 213 CtlP->CtlNum = CtlNum; 214 CtlP->BusType = isISA; 215 CtlP->CtlID = CTLID_0001; /* controller release 1 */ 216 217 CtlP->MBaseIO = MudbacIO; 218 CtlP->MReg1IO = MudbacIO + 1; 219 CtlP->MReg2IO = MudbacIO + 2; 220 CtlP->MReg3IO = MudbacIO + 3; 221#if 1 222 CtlP->MReg2 = 0; /* interrupt disable */ 223 CtlP->MReg3 = 0; /* no periodic interrupts */ 224#else 225 if(sIRQMap[IRQNum] == 0) /* interrupts globally disabled */ 226 { 227 CtlP->MReg2 = 0; /* interrupt disable */ 228 CtlP->MReg3 = 0; /* no periodic interrupts */ 229 } 230 else 231 { 232 CtlP->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */ 233 CtlP->MReg3 = Frequency; /* set frequency */ 234 if(PeriodicOnly) /* periodic interrupt only */ 235 { 236 CtlP->MReg3 |= PERIODIC_ONLY; 237 } 238 } 239#endif 240 sOutB(CtlP->MReg2IO,CtlP->MReg2); 241 sOutB(CtlP->MReg3IO,CtlP->MReg3); 242 sControllerEOI(CtlP); /* clear EOI if warm init */ 243 244 /* Init AIOPs */ 245 CtlP->NumAiop = 0; 246 for(i=0; i < AiopIOListSize; i++) 247 { 248 io = AiopIOList[i]; 249 CtlP->AiopIO[i] = (WordIO_t)io; 250 CtlP->AiopIntChanIO[i] = io + _INT_CHAN; 251 sOutB(CtlP->MReg2IO,CtlP->MReg2 | (i & 0x03)); /* AIOP index */ 252 sOutB(MudbacIO,(Byte_t)(io >> 6)); /* set up AIOP I/O in MUDBAC */ 253 sEnAiop(CtlP,i); /* enable the AIOP */ 254 255 CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ 256 if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ 257 { 258 sDisAiop(CtlP,i); /* disable AIOP */ 259 break; /* done looking for AIOPs */ 260 } 261 262 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */ 263 sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE); /* clock prescaler */ 264 sOutB(io + _INDX_DATA,CLOCK_PRESC); 265 CtlP->NumAiop++; /* bump count of AIOPs */ 266 sDisAiop(CtlP,i); /* disable AIOP */ 267 } 268 269 if(CtlP->NumAiop == 0) 270 return(-1); 271 else 272 return(CtlP->NumAiop); 273} 274 275int sPCIInitController( CONTROLLER_T *CtlP, 276 int CtlNum, 277 ByteIO_t *AiopIOList, 278 int AiopIOListSize, 279 int IRQNum, 280 Byte_t Frequency, 281 int PeriodicOnly) 282{ 283 int i; 284 ByteIO_t io; 285 286 CtlP->CtlNum = CtlNum; 287 CtlP->BusType = isPCI; 288 CtlP->CtlID = CTLID_0001; /* controller release 1 */ 289 CtlP->PCIIO = (WordIO_t)((ByteIO_t)AiopIOList[0] + _PCI_INT_FUNC); 290 291 sPCIControllerEOI(CtlP); 292 293 /* Init AIOPs */ 294 CtlP->NumAiop = 0; 295 for(i=0; i < AiopIOListSize; i++) 296 { 297 io = AiopIOList[i]; 298 CtlP->AiopIO[i] = (WordIO_t)io; 299 CtlP->AiopIntChanIO[i] = io + _INT_CHAN; 300 301 CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ 302 if(CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ 303 { 304 break; /* done looking for AIOPs */ 305 } 306 307 CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */ 308 sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE); /* clock prescaler */ 309 sOutB(io + _INDX_DATA,CLOCK_PRESC); 310 CtlP->NumAiop++; /* bump count of AIOPs */ 311 } 312 313 if(CtlP->NumAiop == 0) 314 return(-1); 315 else 316 return(CtlP->NumAiop); 317} 318 319/*************************************************************************** 320Function: sReadAiopID 321Purpose: Read the AIOP idenfication number directly from an AIOP. 322Call: sReadAiopID(io) 323 ByteIO_t io: AIOP base I/O address 324Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X 325 is replace by an identifying number. 326 Flag AIOPID_NULL if no valid AIOP is found 327Warnings: No context switches are allowed while executing this function. 328 329*/ 330int sReadAiopID(ByteIO_t io) 331{ 332 Byte_t AiopID; /* ID byte from AIOP */ 333 334 sOutB(io + _CMD_REG,RESET_ALL); /* reset AIOP */ 335 sOutB(io + _CMD_REG,0x0); 336 AiopID = sInB(io + _CHN_STAT0) & 0x07; 337 if(AiopID == 0x06) 338 return(1); 339 else /* AIOP does not exist */ 340 return(-1); 341} 342 343/*************************************************************************** 344Function: sReadAiopNumChan 345Purpose: Read the number of channels available in an AIOP directly from 346 an AIOP. 347Call: sReadAiopNumChan(io) 348 WordIO_t io: AIOP base I/O address 349Return: int: The number of channels available 350Comments: The number of channels is determined by write/reads from identical 351 offsets within the SRAM address spaces for channels 0 and 4. 352 If the channel 4 space is mirrored to channel 0 it is a 4 channel 353 AIOP, otherwise it is an 8 channel. 354Warnings: No context switches are allowed while executing this function. 355*/ 356int sReadAiopNumChan(WordIO_t io) 357{ 358 Word_t x; 359 360 sOutDW((DWordIO_t)io + _INDX_ADDR,0x12340000L); /* write to chan 0 SRAM */ 361 sOutW(io + _INDX_ADDR,0); /* read from SRAM, chan 0 */ 362 x = sInW(io + _INDX_DATA); 363 sOutW(io + _INDX_ADDR,0x4000); /* read from SRAM, chan 4 */ 364 if(x != sInW(io + _INDX_DATA)) /* if different must be 8 chan */ 365 return(8); 366 else 367 return(4); 368} 369 370/*************************************************************************** 371Function: sInitChan 372Purpose: Initialization of a channel and channel structure 373Call: sInitChan(CtlP,ChP,AiopNum,ChanNum) 374 CONTROLLER_T *CtlP; Ptr to controller structure 375 CHANNEL_T *ChP; Ptr to channel structure 376 int AiopNum; AIOP number within controller 377 int ChanNum; Channel number within AIOP 378Return: int: TRUE if initialization succeeded, FALSE if it fails because channel 379 number exceeds number of channels available in AIOP. 380Comments: This function must be called before a channel can be used. 381Warnings: No range checking on any of the parameters is done. 382 383 No context switches are allowed while executing this function. 384*/ 385int sInitChan( CONTROLLER_T *CtlP, 386 CHANNEL_T *ChP, 387 int AiopNum, 388 int ChanNum) 389{ 390 int i; 391 WordIO_t AiopIO; 392 WordIO_t ChIOOff; 393 Byte_t *ChR; 394 Word_t ChOff; 395 static Byte_t R[4]; 396 397 if(ChanNum >= CtlP->AiopNumChan[AiopNum]) 398 return(FALSE); /* exceeds num chans in AIOP */ 399 400 /* Channel, AIOP, and controller identifiers */ 401 ChP->CtlP = CtlP; 402 ChP->ChanID = CtlP->AiopID[AiopNum]; 403 ChP->AiopNum = AiopNum; 404 ChP->ChanNum = ChanNum; 405 406 /* Global direct addresses */ 407 AiopIO = CtlP->AiopIO[AiopNum]; 408 ChP->Cmd = (ByteIO_t)AiopIO + _CMD_REG; 409 ChP->IntChan = (ByteIO_t)AiopIO + _INT_CHAN; 410 ChP->IntMask = (ByteIO_t)AiopIO + _INT_MASK; 411 ChP->IndexAddr = (DWordIO_t)AiopIO + _INDX_ADDR; 412 ChP->IndexData = AiopIO + _INDX_DATA; 413 414 /* Channel direct addresses */ 415 ChIOOff = AiopIO + ChP->ChanNum * 2; 416 ChP->TxRxData = ChIOOff + _TD0; 417 ChP->ChanStat = ChIOOff + _CHN_STAT0; 418 ChP->TxRxCount = ChIOOff + _FIFO_CNT0; 419 ChP->IntID = (ByteIO_t)AiopIO + ChP->ChanNum + _INT_ID0; 420 421 /* Initialize the channel from the RData array */ 422 for(i=0; i < RDATASIZE; i+=4) 423 { 424 R[0] = RData[i]; 425 R[1] = RData[i+1] + 0x10 * ChanNum; 426 R[2] = RData[i+2]; 427 R[3] = RData[i+3]; 428 sOutDW(ChP->IndexAddr,*((DWord_t *)&R[0])); 429 } 430 431 ChR = ChP->R; 432 for(i=0; i < RREGDATASIZE; i+=4) 433 { 434 ChR[i] = RRegData[i]; 435 ChR[i+1] = RRegData[i+1] + 0x10 * ChanNum; 436 ChR[i+2] = RRegData[i+2]; 437 ChR[i+3] = RRegData[i+3]; 438 } 439 440 /* Indexed registers */ 441 ChOff = (Word_t)ChanNum * 0x1000; 442 443 ChP->BaudDiv[0] = (Byte_t)(ChOff + _BAUD); 444 ChP->BaudDiv[1] = (Byte_t)((ChOff + _BAUD) >> 8); 445 ChP->BaudDiv[2] = (Byte_t)BRD9600; 446 ChP->BaudDiv[3] = (Byte_t)(BRD9600 >> 8); 447 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->BaudDiv[0]); 448 449 ChP->TxControl[0] = (Byte_t)(ChOff + _TX_CTRL); 450 ChP->TxControl[1] = (Byte_t)((ChOff + _TX_CTRL) >> 8); 451 ChP->TxControl[2] = 0; 452 ChP->TxControl[3] = 0; 453 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]); 454 455 ChP->RxControl[0] = (Byte_t)(ChOff + _RX_CTRL); 456 ChP->RxControl[1] = (Byte_t)((ChOff + _RX_CTRL) >> 8); 457 ChP->RxControl[2] = 0; 458 ChP->RxControl[3] = 0; 459 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]); 460 461 ChP->TxEnables[0] = (Byte_t)(ChOff + _TX_ENBLS); 462 ChP->TxEnables[1] = (Byte_t)((ChOff + _TX_ENBLS) >> 8); 463 ChP->TxEnables[2] = 0; 464 ChP->TxEnables[3] = 0; 465 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxEnables[0]); 466 467 ChP->TxCompare[0] = (Byte_t)(ChOff + _TXCMP1); 468 ChP->TxCompare[1] = (Byte_t)((ChOff + _TXCMP1) >> 8); 469 ChP->TxCompare[2] = 0; 470 ChP->TxCompare[3] = 0; 471 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxCompare[0]); 472 473 ChP->TxReplace1[0] = (Byte_t)(ChOff + _TXREP1B1); 474 ChP->TxReplace1[1] = (Byte_t)((ChOff + _TXREP1B1) >> 8); 475 ChP->TxReplace1[2] = 0; 476 ChP->TxReplace1[3] = 0; 477 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace1[0]); 478 479 ChP->TxReplace2[0] = (Byte_t)(ChOff + _TXREP2); 480 ChP->TxReplace2[1] = (Byte_t)((ChOff + _TXREP2) >> 8); 481 ChP->TxReplace2[2] = 0; 482 ChP->TxReplace2[3] = 0; 483 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace2[0]); 484 485 ChP->TxFIFOPtrs = ChOff + _TXF_OUTP; 486 ChP->TxFIFO = ChOff + _TX_FIFO; 487 488 sOutB(ChP->Cmd,(Byte_t)ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */ 489 sOutB(ChP->Cmd,(Byte_t)ChanNum); /* remove reset Tx FIFO count */ 490 sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */ 491 sOutW(ChP->IndexData,0); 492 ChP->RxFIFOPtrs = ChOff + _RXF_OUTP; 493 ChP->RxFIFO = ChOff + _RX_FIFO; 494 495 sOutB(ChP->Cmd,(Byte_t)ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */ 496 sOutB(ChP->Cmd,(Byte_t)ChanNum); /* remove reset Rx FIFO count */ 497 sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */ 498 sOutW(ChP->IndexData,0); 499 sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */ 500 sOutW(ChP->IndexData,0); 501 ChP->TxPrioCnt = ChOff + _TXP_CNT; 502 sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioCnt); 503 sOutB(ChP->IndexData,0); 504 ChP->TxPrioPtr = ChOff + _TXP_PNTR; 505 sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioPtr); 506 sOutB(ChP->IndexData,0); 507 ChP->TxPrioBuf = ChOff + _TXP_BUF; 508 sEnRxProcessor(ChP); /* start the Rx processor */ 509 510 return(TRUE); 511} 512 513/*************************************************************************** 514Function: sStopRxProcessor 515Purpose: Stop the receive processor from processing a channel. 516Call: sStopRxProcessor(ChP) 517 CHANNEL_T *ChP; Ptr to channel structure 518 519Comments: The receive processor can be started again with sStartRxProcessor(). 520 This function causes the receive processor to skip over the 521 stopped channel. It does not stop it from processing other channels. 522 523Warnings: No context switches are allowed while executing this function. 524 525 Do not leave the receive processor stopped for more than one 526 character time. 527 528 After calling this function a delay of 4 uS is required to ensure 529 that the receive processor is no longer processing this channel. 530*/ 531void sStopRxProcessor(CHANNEL_T *ChP) 532{ 533 Byte_t R[4]; 534 535 R[0] = ChP->R[0]; 536 R[1] = ChP->R[1]; 537 R[2] = 0x0a; 538 R[3] = ChP->R[3]; 539 sOutDW(ChP->IndexAddr,*(DWord_t *)&R[0]); 540} 541 542/*************************************************************************** 543Function: sFlushRxFIFO 544Purpose: Flush the Rx FIFO 545Call: sFlushRxFIFO(ChP) 546 CHANNEL_T *ChP; Ptr to channel structure 547Return: void 548Comments: To prevent data from being enqueued or dequeued in the Tx FIFO 549 while it is being flushed the receive processor is stopped 550 and the transmitter is disabled. After these operations a 551 4 uS delay is done before clearing the pointers to allow 552 the receive processor to stop. These items are handled inside 553 this function. 554Warnings: No context switches are allowed while executing this function. 555*/ 556void sFlushRxFIFO(CHANNEL_T *ChP) 557{ 558 int i; 559 Byte_t Ch; /* channel number within AIOP */ 560 int RxFIFOEnabled; /* TRUE if Rx FIFO enabled */ 561 562 if(sGetRxCnt(ChP) == 0) /* Rx FIFO empty */ 563 return; /* don't need to flush */ 564 565 RxFIFOEnabled = FALSE; 566 if(ChP->R[0x32] == 0x08) /* Rx FIFO is enabled */ 567 { 568 RxFIFOEnabled = TRUE; 569 sDisRxFIFO(ChP); /* disable it */ 570 for(i=0; i < 2000/200; i++) /* delay 2 uS to allow proc to disable FIFO*/ 571 sInB(ChP->IntChan); /* depends on bus i/o timing */ 572 } 573 sGetChanStatus(ChP); /* clear any pending Rx errors in chan stat */ 574 Ch = (Byte_t)sGetChanNum(ChP); 575 sOutB(ChP->Cmd,Ch | RESRXFCNT); /* apply reset Rx FIFO count */ 576 sOutB(ChP->Cmd,Ch); /* remove reset Rx FIFO count */ 577 sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */ 578 sOutW(ChP->IndexData,0); 579 sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */ 580 sOutW(ChP->IndexData,0); 581 if(RxFIFOEnabled) 582 sEnRxFIFO(ChP); /* enable Rx FIFO */ 583} 584 585/*************************************************************************** 586Function: sFlushTxFIFO 587Purpose: Flush the Tx FIFO 588Call: sFlushTxFIFO(ChP) 589 CHANNEL_T *ChP; Ptr to channel structure 590Return: void 591Comments: To prevent data from being enqueued or dequeued in the Tx FIFO 592 while it is being flushed the receive processor is stopped 593 and the transmitter is disabled. After these operations a 594 4 uS delay is done before clearing the pointers to allow 595 the receive processor to stop. These items are handled inside 596 this function. 597Warnings: No context switches are allowed while executing this function. 598*/ 599void sFlushTxFIFO(CHANNEL_T *ChP) 600{ 601 int i; 602 Byte_t Ch; /* channel number within AIOP */ 603 int TxEnabled; /* TRUE if transmitter enabled */ 604 605 if(sGetTxCnt(ChP) == 0) /* Tx FIFO empty */ 606 return; /* don't need to flush */ 607 608 TxEnabled = FALSE; 609 if(ChP->TxControl[3] & TX_ENABLE) 610 { 611 TxEnabled = TRUE; 612 sDisTransmit(ChP); /* disable transmitter */ 613 } 614 sStopRxProcessor(ChP); /* stop Rx processor */ 615 for(i = 0; i < 4000/200; i++) /* delay 4 uS to allow proc to stop */ 616 sInB(ChP->IntChan); /* depends on bus i/o timing */ 617 Ch = (Byte_t)sGetChanNum(ChP); 618 sOutB(ChP->Cmd,Ch | RESTXFCNT); /* apply reset Tx FIFO count */ 619 sOutB(ChP->Cmd,Ch); /* remove reset Tx FIFO count */ 620 sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */ 621 sOutW(ChP->IndexData,0); 622 if(TxEnabled) 623 sEnTransmit(ChP); /* enable transmitter */ 624 sStartRxProcessor(ChP); /* restart Rx processor */ 625} 626 627/*************************************************************************** 628Function: sWriteTxPrioByte 629Purpose: Write a byte of priority transmit data to a channel 630Call: sWriteTxPrioByte(ChP,Data) 631 CHANNEL_T *ChP; Ptr to channel structure 632 Byte_t Data; The transmit data byte 633 634Return: int: 1 if the bytes is successfully written, otherwise 0. 635 636Comments: The priority byte is transmitted before any data in the Tx FIFO. 637 638Warnings: No context switches are allowed while executing this function. 639*/ 640int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data) 641{ 642 Byte_t DWBuf[4]; /* buffer for double word writes */ 643 Word_t *WordPtr; /* must be far because Win SS != DS */ 644 register DWordIO_t IndexAddr; 645 646 if(sGetTxCnt(ChP) > 1) /* write it to Tx priority buffer */ 647 { 648 IndexAddr = ChP->IndexAddr; 649 sOutW((WordIO_t)IndexAddr,ChP->TxPrioCnt); /* get priority buffer status */ 650 if(sInB((ByteIO_t)ChP->IndexData) & PRI_PEND) /* priority buffer busy */ 651 return(0); /* nothing sent */ 652 653 WordPtr = (Word_t *)(&DWBuf[0]); 654 *WordPtr = ChP->TxPrioBuf; /* data byte address */ 655 656 DWBuf[2] = Data; /* data byte value */ 657 sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */ 658 659 *WordPtr = ChP->TxPrioCnt; /* Tx priority count address */ 660 661 DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */ 662 DWBuf[3] = 0; /* priority buffer pointer */ 663 sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */ 664 } 665 else /* write it to Tx FIFO */ 666 { 667 sWriteTxByte(sGetTxRxDataIO(ChP),Data); 668 } 669 return(1); /* 1 byte sent */ 670} 671 672/*************************************************************************** 673Function: sEnInterrupts 674Purpose: Enable one or more interrupts for a channel 675Call: sEnInterrupts(ChP,Flags) 676 CHANNEL_T *ChP; Ptr to channel structure 677 Word_t Flags: Interrupt enable flags, can be any combination 678 of the following flags: 679 TXINT_EN: Interrupt on Tx FIFO empty 680 RXINT_EN: Interrupt on Rx FIFO at trigger level (see 681 sSetRxTrigger()) 682 SRCINT_EN: Interrupt on SRC (Special Rx Condition) 683 MCINT_EN: Interrupt on modem input change 684 CHANINT_EN: Allow channel interrupt signal to the AIOP's 685 Interrupt Channel Register. 686Return: void 687Comments: If an interrupt enable flag is set in Flags, that interrupt will be 688 enabled. If an interrupt enable flag is not set in Flags, that 689 interrupt will not be changed. Interrupts can be disabled with 690 function sDisInterrupts(). 691 692 This function sets the appropriate bit for the channel in the AIOP's 693 Interrupt Mask Register if the CHANINT_EN flag is set. This allows 694 this channel's bit to be set in the AIOP's Interrupt Channel Register. 695 696 Interrupts must also be globally enabled before channel interrupts 697 will be passed on to the host. This is done with function 698 sEnGlobalInt(). 699 700 In some cases it may be desirable to disable interrupts globally but 701 enable channel interrupts. This would allow the global interrupt 702 status register to be used to determine which AIOPs need service. 703*/ 704void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags) 705{ 706 Byte_t Mask; /* Interrupt Mask Register */ 707 708 ChP->RxControl[2] |= 709 ((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN)); 710 711 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]); 712 713 ChP->TxControl[2] |= ((Byte_t)Flags & TXINT_EN); 714 715 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]); 716 717 if(Flags & CHANINT_EN) 718 { 719 Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum]; 720 sOutB(ChP->IntMask,Mask); 721 } 722} 723 724/*************************************************************************** 725Function: sDisInterrupts 726Purpose: Disable one or more interrupts for a channel 727Call: sDisInterrupts(ChP,Flags) 728 CHANNEL_T *ChP; Ptr to channel structure 729 Word_t Flags: Interrupt flags, can be any combination 730 of the following flags: 731 TXINT_EN: Interrupt on Tx FIFO empty 732 RXINT_EN: Interrupt on Rx FIFO at trigger level (see 733 sSetRxTrigger()) 734 SRCINT_EN: Interrupt on SRC (Special Rx Condition) 735 MCINT_EN: Interrupt on modem input change 736 CHANINT_EN: Disable channel interrupt signal to the 737 AIOP's Interrupt Channel Register. 738Return: void 739Comments: If an interrupt flag is set in Flags, that interrupt will be 740 disabled. If an interrupt flag is not set in Flags, that 741 interrupt will not be changed. Interrupts can be enabled with 742 function sEnInterrupts(). 743 744 This function clears the appropriate bit for the channel in the AIOP's 745 Interrupt Mask Register if the CHANINT_EN flag is set. This blocks 746 this channel's bit from being set in the AIOP's Interrupt Channel 747 Register. 748*/ 749void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags) 750{ 751 Byte_t Mask; /* Interrupt Mask Register */ 752 753 ChP->RxControl[2] &= 754 ~((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN)); 755 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]); 756 ChP->TxControl[2] &= ~((Byte_t)Flags & TXINT_EN); 757 sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]); 758 759 if(Flags & CHANINT_EN) 760 { 761 Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum]; 762 sOutB(ChP->IntMask,Mask); 763 } 764} 765 766/********************************************************************* 767 Begin FreeBsd-specific driver code 768**********************************************************************/ 769 770static int rpprobe __P((struct isa_device *)); 771static int rpattach __P((struct isa_device *)); 772 773static const char* rp_pciprobe(pcici_t tag, pcidi_t type); 774static void rp_pciattach(pcici_t tag, int unit); 775static u_long rp_pcicount; 776 777static struct pci_device rp_pcidevice = { 778 "rp", 779 rp_pciprobe, 780 rp_pciattach, 781 &rp_pcicount, 782 NULL 783}; 784 785COMPAT_PCI_DRIVER (rp_pci, rp_pcidevice); 786 787static timeout_t rpdtrwakeup; 788 789struct isa_driver rpdriver = { 790 rpprobe, rpattach, "rp" 791 }; 792 793static char driver_name[] = "rp"; 794 795static d_open_t rpopen; 796static d_close_t rpclose; 797static d_read_t rpread; 798static d_write_t rpwrite; 799static d_ioctl_t rpioctl; 800static d_stop_t rpstop; 801static d_devtotty_t rpdevtotty; 802 803#define CDEV_MAJOR 81
|
810}; 811 812static int rp_controller_port = 0; 813static int rp_num_ports_open = 0; 814static int ndevs = 0; 815static int minor_to_unit[128]; 816#if 0 817static struct tty rp_tty[128]; 818#endif 819 820static int rp_num_ports[4]; /* Number of ports on each controller */ 821 822#define _INLINE_ __inline 823#define POLL_INTERVAL 1 824 825#define CALLOUT_MASK 0x80 826#define CONTROL_MASK 0x60 827#define CONTROL_INIT_STATE 0x20 828#define CONTROL_LOCK_STATE 0x40 829#define DEV_UNIT(dev) (MINOR_TO_UNIT(minor(dev)) 830#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK) 831#define MINOR_MAGIC(dev) ((minor(dev)) & ~MINOR_MAGIC_MASK) 832#define IS_CALLOUT(dev) (minor(dev) & CALLOUT_MASK) 833#define IS_CONTROL(dev) (minor(dev) & CONTROL_MASK) 834 835#define RP_ISMULTIPORT(dev) ((dev)->id_flags & 0x1) 836#define RP_MPMASTER(dev) (((dev)->id_flags >> 8) & 0xff) 837#define RP_NOTAST4(dev) ((dev)->id_flags & 0x04) 838 839static struct rp_port *p_rp_addr[4]; 840static struct rp_port *p_rp_table[MAX_RP_PORTS]; 841#define rp_addr(unit) (p_rp_addr[unit]) 842#define rp_table(port) (p_rp_table[port]) 843 844/* 845 * The top-level routines begin here 846 */ 847 848int rpselect __P((dev_t, int, struct proc *)); 849 850static int rpparam __P((struct tty *, struct termios *)); 851static void rpstart __P((struct tty *)); 852static void rphardclose __P((struct rp_port *)); 853#define rpmap nomap 854#define rpreset noreset 855#define rpstrategy nostrategy 856static void rp_disc_optim __P((struct tty *tp, struct termios *t, 857 struct rp_port *rp)); 858 859static _INLINE_ void rp_do_receive(struct rp_port *rp, struct tty *tp, 860 CHANNEL_t *cp, unsigned int ChanStatus) 861{ 862 int spl; 863 unsigned int CharNStat; 864 int ToRecv, ch; 865 866 ToRecv = sGetRxCnt(cp); 867 if(ToRecv == 0) 868 return; 869 870/* If status indicates there are errored characters in the 871 FIFO, then enter status mode (a word in FIFO holds 872 characters and status) 873*/ 874 875 if(ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) { 876 if(!(ChanStatus & STATMODE)) { 877 ChanStatus |= STATMODE; 878 sEnRxStatusMode(cp); 879 } 880 } 881/* 882 if we previously entered status mode then read down the 883 FIFO one word at a time, pulling apart the character and 884 the status. Update error counters depending on status. 885*/ 886 if(ChanStatus & STATMODE) { 887 while(ToRecv) { 888 if(tp->t_state & TS_TBLOCK) { 889 break; 890 } 891 CharNStat = sInW(sGetTxRxDataIO(cp)); 892 ch = CharNStat & 0xff; 893 894 if((CharNStat & STMBREAK) || (CharNStat & STMFRAMEH)) 895 ch |= TTY_FE; 896 else if (CharNStat & STMPARITYH) 897 ch |= TTY_PE; 898 else if (CharNStat & STMRCVROVRH) 899 rp->rp_overflows++; 900 901 (*linesw[tp->t_line].l_rint)(ch, tp); 902 ToRecv--; 903 } 904/* 905 After emtying FIFO in status mode, turn off status mode 906*/ 907 908 if(sGetRxCnt(cp) == 0) 909 sDisRxStatusMode(cp); 910 } 911 else { 912 while (ToRecv) { 913 if(tp->t_state & TS_TBLOCK) { 914 break; 915 } 916 ch = (u_char) sInB(sGetTxRxDataIO(cp)); 917 spl = spltty(); 918 (*linesw[tp->t_line].l_rint)(ch, tp); 919 splx(spl); 920 ToRecv--; 921 } 922 } 923} 924 925static _INLINE_ void rp_handle_port(struct rp_port *rp) 926{ 927 CHANNEL_t *cp; 928 struct tty *tp; 929 unsigned int IntMask, ChanStatus; 930 /* int oldcts; */ 931 932 if(!rp) 933 return; 934 935 cp = &rp->rp_channel; 936 tp = rp->rp_tty; 937 IntMask = sGetChanIntID(cp); 938 IntMask = IntMask & rp->rp_intmask; 939 ChanStatus = sGetChanStatus(cp); 940 if(IntMask & RXF_TRIG) 941 if(!(tp->t_state & TS_TBLOCK) && (tp->t_state & TS_CARR_ON) && (tp->t_state & TS_ISOPEN)) { 942 rp_do_receive(rp, tp, cp, ChanStatus); 943 } 944 if(IntMask & DELTA_CD) { 945 if(ChanStatus & CD_ACT) { 946 if(!(tp->t_state & TS_CARR_ON) ) { 947 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 948 } 949 } else { 950 if((tp->t_state & TS_CARR_ON)) { 951 (void)(*linesw[tp->t_line].l_modem)(tp, 0); 952 if((*linesw[tp->t_line].l_modem)(tp, 0) == 0) { 953 rphardclose(rp); 954 } 955 } 956 } 957 } 958/* oldcts = rp->rp_cts; 959 rp->rp_cts = ((ChanStatus & CTS_ACT) != 0); 960 if(oldcts != rp->rp_cts) { 961 printf("CTS change (now %s)... on port %d\n", rp->rp_cts ? "on" : "off", rp->rp_port); 962 } 963*/ 964} 965 966static void rp_do_poll(void *not_used) 967{ 968 CONTROLLER_t *ctl; 969 struct rp_port *rp; 970 struct tty *tp; 971 int unit, aiop, ch, line, count; 972 unsigned char CtlMask, AiopMask; 973 974 for(unit = 0; unit <= ndevs; unit++) { 975 rp = rp_addr(unit); 976 ctl = rp->rp_ctlp; 977 if(ctl->BusType == isPCI) 978 CtlMask = sPCIGetControllerIntStatus(ctl); 979 else 980 CtlMask = sGetControllerIntStatus(ctl); 981 for(aiop=0; CtlMask; CtlMask >>=1, aiop++) { 982 if(CtlMask & 1) { 983 AiopMask = sGetAiopIntStatus(ctl, aiop); 984 for(ch = 0; AiopMask; AiopMask >>=1, ch++) { 985 if(AiopMask & 1) { 986 line = (unit << 5) | (aiop << 3) | ch; 987 rp = rp_table(line); 988 rp_handle_port(rp); 989 } 990 } 991 } 992 } 993 994 for(line = 0, rp = rp_addr(unit); line < rp_num_ports[unit]; 995 line++, rp++) { 996 tp = rp->rp_tty; 997 if((tp->t_state & TS_BUSY) && (tp->t_state & TS_ISOPEN)) { 998 count = sGetTxCnt(&rp->rp_channel); 999 if(count == 0) 1000 tp->t_state &= ~(TS_BUSY); 1001 if(!(tp->t_state & TS_TTSTOP) && 1002 (count <= rp->rp_restart)) { 1003 (*linesw[tp->t_line].l_start)(tp); 1004 } 1005 } 1006 } 1007 } 1008 if(rp_num_ports_open) 1009 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); 1010} 1011 1012static const char* 1013rp_pciprobe(pcici_t tag, pcidi_t type) 1014{ 1015 int vendor_id; 1016 1017 vendor_id = type & 0xffff; 1018 switch(vendor_id) 1019 case 0x11fe: 1020 return("rp"); 1021 return(NULL); 1022} 1023 1024static 1025int 1026rpprobe(dev) 1027struct isa_device *dev; 1028{ 1029 int controller, unit; 1030 int aiop, num_aiops; 1031 unsigned int aiopio[MAX_AIOPS_PER_BOARD]; 1032 CONTROLLER_t *ctlp; 1033 1034 unit = dev->id_unit; 1035 if (dev->id_unit >= 4) { 1036 printf("rpprobe: unit number %d invalid.\n", dev->id_unit); 1037 return 1; 1038 } 1039 printf("probing for RocketPort(ISA) unit %d\n", unit); 1040 if (rp_controller_port) 1041 controller = rp_controller_port; 1042 else { 1043 controller = dev->id_iobase + 0x40; 1044 } 1045 1046 for (aiop=0; aiop<MAX_AIOPS_PER_BOARD; aiop++) 1047 aiopio[aiop]= dev->id_iobase + (aiop * 0x400); 1048 1049 ctlp = sCtlNumToCtlPtr(dev->id_unit); 1050 num_aiops = sInitController(ctlp, dev->id_unit, 1051 controller + ((unit-rp_pcicount)*0x400), 1052 aiopio, MAX_AIOPS_PER_BOARD, 0, 1053 FREQ_DIS, 0); 1054 if (num_aiops <= 0) { 1055 printf("board%d init failed\n", unit); 1056 return 0; 1057 } 1058 1059 if (rp_controller_port) { 1060 dev->id_msize = 64; 1061 } else { 1062 dev->id_msize = 68; 1063 rp_controller_port = controller; 1064 } 1065 1066 dev->id_irq = 0; 1067 1068 return 1; 1069} 1070 1071static void 1072rp_pciattach(pcici_t tag, int unit) 1073{ 1074 dev_t rp_dev; 1075 int success, oldspl; 1076 u_short iobase; 1077 int num_ports, num_chan, num_aiops; 1078 int aiop, chan, port; 1079 int ChanStatus, line, i, count; 1080 unsigned int aiopio[MAX_AIOPS_PER_BOARD]; 1081 struct rp_port *rp; 1082 struct tty *tty; 1083 CONTROLLER_t *ctlp; 1084 1085 success = pci_map_port(tag, 0x10, &iobase); 1086 if(!success) 1087 printf("ioaddr mapping failed for RocketPort(PCI)\n"); 1088 1089 for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++) 1090 aiopio[aiop] = iobase + (aiop * 0x40); 1091 1092 ctlp = sCtlNumToCtlPtr(unit); 1093 num_aiops = sPCIInitController(ctlp, unit, 1094 aiopio, MAX_AIOPS_PER_BOARD, 0, 1095 FREQ_DIS, 0); 1096 1097 num_ports = 0; 1098 for(aiop=0; aiop < num_aiops; aiop++) { 1099 sResetAiopByNum(ctlp, aiop); 1100 num_ports += sGetAiopNumChan(ctlp, aiop); 1101 } 1102 printf("RocketPort%d = %d ports\n", unit, num_ports); 1103 rp_num_ports[unit] = num_ports; 1104 1105 rp = (struct rp_port *) 1106 malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT); 1107 if(rp == 0) { 1108 printf("rp_attach: Could not malloc rp_ports structures\n"); 1109 return; 1110 } 1111 1112 count = unit * 32; /* board times max ports per card SG */ 1113 for(i=count;i < (count + rp_num_ports[unit]);i++) 1114 minor_to_unit[i] = unit; 1115 1116 bzero(rp, sizeof(struct rp_port) * num_ports); 1117 tty = (struct tty *) 1118 malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT); 1119 if(tty == 0) { 1120 printf("rp_attach: Could not malloc tty structures\n"); 1121 return; 1122 } 1123 bzero(tty, sizeof(struct tty) * num_ports); 1124 1125 oldspl = spltty(); 1126 rp_addr(unit) = rp; 1127 splx(oldspl); 1128 1129 rp_dev = makedev(CDEV_MAJOR, unit); 1130 cdevsw_add(&rp_dev, &rp_cdevsw, NULL); 1131 1132 port = 0; 1133 for(aiop=0; aiop < num_aiops; aiop++) { 1134 num_chan = sGetAiopNumChan(ctlp, aiop); 1135 for(chan=0; chan < num_chan; chan++, port++, rp++, tty++) { 1136 rp->rp_tty = tty; 1137 rp->rp_port = port; 1138 rp->rp_ctlp = ctlp; 1139 rp->rp_unit = unit; 1140 rp->rp_chan = chan; 1141 rp->rp_aiop = aiop; 1142 1143 tty->t_line = 0; 1144 /* tty->t_termios = deftermios; 1145 */ 1146 rp->dtr_wait = 3 * hz; 1147 rp->it_in.c_iflag = 0; 1148 rp->it_in.c_oflag = 0; 1149 rp->it_in.c_cflag = TTYDEF_CFLAG; 1150 rp->it_in.c_lflag = 0; 1151 termioschars(&rp->it_in); 1152 /* termioschars(&tty->t_termios); 1153 */ 1154 rp->it_in.c_ispeed = rp->it_in.c_ospeed = TTYDEF_SPEED; 1155 rp->it_out = rp->it_in; 1156 1157 rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | 1158 DELTA_CD | DELTA_CTS | DELTA_DSR; 1159 ChanStatus = sGetChanStatus(&rp->rp_channel); 1160 if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) { 1161 printf("RocketPort sInitChan(%d, %d, %d) failed 1162 \n", unit, aiop, chan); 1163 return; 1164 } 1165 ChanStatus = sGetChanStatus(&rp->rp_channel); 1166 rp->rp_cts = (ChanStatus & CTS_ACT) != 0; 1167 line = (unit << 5) | (aiop << 3) | chan; 1168 rp_table(line) = rp; 1169/* devfs_add_devswf(&rp_cdevsw, 1170 port, DV_CHR, UID_ROOT, GID_WHEEL, 0600, 1171 "ttyR%r", port); 1172 devfs_add_devswf(&rp_cdevsw, 1173 port | CONTROL_INIT_STATE, DV_CHR, UID_ROOT, 1174 GID_WHEEL, 0600, "ttyRi%r", port); 1175*/ 1176 } 1177 } 1178} 1179 1180static 1181int 1182rpattach(dev) 1183struct isa_device *dev; 1184{ 1185 dev_t rp_dev; 1186 int iobase, unit, /*rpmajor,*/ oldspl; 1187 int num_ports, num_chan, num_aiops; 1188 int aiop, chan, port; 1189 int ChanStatus, line, i, count; 1190 unsigned int aiopio[MAX_AIOPS_PER_BOARD]; 1191 struct rp_port *rp; 1192 struct tty *tty; 1193 CONTROLLER_t *ctlp; 1194 1195 iobase = dev->id_iobase; 1196 unit = dev->id_unit; 1197 ndevs = unit; 1198 1199 for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++) 1200 aiopio[aiop] = iobase + (aiop * 0x400); 1201 1202 ctlp = sCtlNumToCtlPtr(unit); 1203 num_aiops = sInitController(ctlp, unit, 1204 rp_controller_port + ((unit-rp_pcicount) * 0x400), 1205 aiopio, MAX_AIOPS_PER_BOARD, 0, 1206 FREQ_DIS, 0); 1207 1208 num_ports = 0; 1209 for(aiop=0; aiop < num_aiops; aiop++) { 1210 sResetAiopByNum(ctlp, aiop); 1211 sEnAiop(ctlp, aiop); 1212 num_ports += sGetAiopNumChan(ctlp, aiop); 1213 } 1214 printf("RocketPort%d = %d ports\n", unit, num_ports); 1215 rp_num_ports[unit] = num_ports; 1216 1217 rp = (struct rp_port *) 1218 malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT); 1219 if(rp == 0) { 1220 printf("rp_attach: Could not malloc rp_ports structures\n"); 1221 return(0); 1222 } 1223 1224 count = unit * 32; /* board # times max ports per card SG */ 1225 for(i=count;i < (count + rp_num_ports[unit]);i++) 1226 minor_to_unit[i] = unit; 1227 1228 bzero(rp, sizeof(struct rp_port) * num_ports); 1229 tty = (struct tty *) 1230 malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT); 1231 if(tty == 0) { 1232 printf("rp_attach: Could not malloc tty structures\n"); 1233 return(0); 1234 } 1235 bzero(tty, sizeof(struct tty) * num_ports); 1236 1237 oldspl = spltty(); 1238 rp_addr(unit) = rp; 1239 splx(oldspl); 1240 1241 rp_dev = makedev(CDEV_MAJOR, unit); 1242 cdevsw_add(&rp_dev, &rp_cdevsw, NULL); 1243 1244 port = 0; 1245 for(aiop=0; aiop < num_aiops; aiop++) { 1246 num_chan = sGetAiopNumChan(ctlp, aiop); 1247 for(chan=0; chan < num_chan; chan++, port++, rp++, tty++) { 1248 rp->rp_tty = tty; 1249 rp->rp_port = port; 1250 rp->rp_ctlp = ctlp; 1251 rp->rp_unit = unit; 1252 rp->rp_chan = chan; 1253 rp->rp_aiop = aiop; 1254 1255 tty->t_line = 0; 1256 /* tty->t_termios = deftermios; 1257 */ 1258 rp->dtr_wait = 3 * hz; 1259 rp->it_in.c_iflag = 0; 1260 rp->it_in.c_oflag = 0; 1261 rp->it_in.c_cflag = TTYDEF_CFLAG; 1262 rp->it_in.c_lflag = 0; 1263 termioschars(&rp->it_in); 1264 /* termioschars(&tty->t_termios); 1265 */ 1266 rp->it_in.c_ispeed = rp->it_in.c_ospeed = TTYDEF_SPEED; 1267 rp->it_out = rp->it_in; 1268 1269 rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | 1270 DELTA_CD | DELTA_CTS | DELTA_DSR; 1271 ChanStatus = sGetChanStatus(&rp->rp_channel); 1272 if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) { 1273 printf("RocketPort sInitChan(%d, %d, %d) failed 1274 \n", unit, aiop, chan); 1275 return(0); 1276 } 1277 ChanStatus = sGetChanStatus(&rp->rp_channel); 1278 rp->rp_cts = (ChanStatus & CTS_ACT) != 0; 1279 line = (unit << 5) | (aiop << 3) | chan; 1280 rp_table(line) = rp; 1281 } 1282 } 1283 1284 return(1); 1285} 1286 1287int 1288rpopen(dev, flag, mode, p) 1289 dev_t dev; 1290 int flag, mode; 1291 struct proc *p; 1292{ 1293 struct rp_port *rp; 1294 int unit, port, mynor, umynor, flags; /* SG */ 1295 struct tty *tp; 1296 int oldspl, error; 1297 unsigned int IntMask, ChanStatus; 1298 1299 1300 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1301 port = (minor(dev) & 0x1f); /* SG */ 1302 mynor = (port + umynor); /* SG */ 1303 unit = minor_to_unit[mynor]; 1304 if(IS_CONTROL(dev)) 1305 return(0); 1306 rp = rp_addr(unit) + port; 1307/* rp->rp_tty = &rp_tty[rp->rp_port]; 1308*/ 1309 tp = rp->rp_tty; 1310 1311 oldspl = spltty(); 1312 1313open_top: 1314 while(rp->state & ~SET_DTR) { 1315 error = tsleep(&rp->dtr_wait, TTIPRI | PCATCH, "rpdtr", 0); 1316 if(error != 0) 1317 goto out; 1318 } 1319 1320 if(tp->t_state & TS_ISOPEN) { 1321 if(IS_CALLOUT(dev)) { 1322 if(!rp->active_out) { 1323 error = EBUSY; 1324 goto out; 1325 } 1326 } else { 1327 if(rp->active_out) { 1328 if(flag & O_NONBLOCK) { 1329 error = EBUSY; 1330 goto out; 1331 } 1332 error = tsleep(&rp->active_out, 1333 TTIPRI | PCATCH, "rpbi", 0); 1334 if(error != 0) 1335 goto out; 1336 goto open_top; 1337 } 1338 } 1339 if(tp->t_state & TS_XCLUDE && 1340 suser(p)) { 1341 splx(oldspl); 1342 return(EBUSY); 1343 } 1344 } 1345 else { 1346 tp->t_dev = dev; 1347 tp->t_param = rpparam; 1348 tp->t_oproc = rpstart; 1349 tp->t_line = 0; 1350 tp->t_termios = IS_CALLOUT(dev) ? rp->it_out : rp->it_in; 1351 flags = 0; 1352 flags |= SET_RTS; 1353 flags |= SET_DTR; 1354 rp->rp_channel.TxControl[3] = 1355 ((rp->rp_channel.TxControl[3] 1356 & ~(SET_RTS | SET_DTR)) | flags); 1357 sOutDW(rp->rp_channel.IndexAddr, 1358 *(DWord_t *) &(rp->rp_channel.TxControl[0])); 1359 sSetRxTrigger(&rp->rp_channel, TRIG_1); 1360 sDisRxStatusMode(&rp->rp_channel); 1361 sFlushRxFIFO(&rp->rp_channel); 1362 sFlushTxFIFO(&rp->rp_channel); 1363 1364 sEnInterrupts(&rp->rp_channel, 1365 (TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN)); 1366 sSetRxTrigger(&rp->rp_channel, TRIG_1); 1367 1368 sDisRxStatusMode(&rp->rp_channel); 1369 sClrTxXOFF(&rp->rp_channel); 1370 1371/* sDisRTSFlowCtl(&rp->rp_channel); 1372 sDisCTSFlowCtl(&rp->rp_channel); 1373*/ 1374 sDisTxSoftFlowCtl(&rp->rp_channel); 1375 1376 sStartRxProcessor(&rp->rp_channel); 1377 1378 sEnRxFIFO(&rp->rp_channel); 1379 sEnTransmit(&rp->rp_channel); 1380 1381/* sSetDTR(&rp->rp_channel); 1382 sSetRTS(&rp->rp_channel); 1383*/ 1384 1385 ++rp->wopeners; 1386 error = rpparam(tp, &tp->t_termios); 1387 --rp->wopeners; 1388 if(error != 0) { 1389 splx(oldspl); 1390 return(error); 1391 } 1392 1393 rp_num_ports_open++; 1394 1395 IntMask = sGetChanIntID(&rp->rp_channel); 1396 IntMask = IntMask & rp->rp_intmask; 1397 ChanStatus = sGetChanStatus(&rp->rp_channel); 1398 if((IntMask & DELTA_CD) || IS_CALLOUT(dev)) { 1399 if((ChanStatus & CD_ACT) || IS_CALLOUT(dev)) { 1400 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 1401 } 1402 } 1403 1404 if(rp_num_ports_open == 1) 1405 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); 1406 1407 } 1408 1409 if(!(flag&O_NONBLOCK) && !(tp->t_cflag&CLOCAL) && 1410 !(tp->t_state & TS_CARR_ON) && !(IS_CALLOUT(dev))) { 1411 ++rp->wopeners; 1412 error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, 1413 "rpdcd", 0); 1414 --rp->wopeners; 1415 if(error != 0) 1416 goto out; 1417 goto open_top; 1418 } 1419 error = (*linesw[tp->t_line].l_open)(dev, tp); 1420 1421 rp_disc_optim(tp, &tp->t_termios, rp); 1422 if(tp->t_state & TS_ISOPEN && IS_CALLOUT(dev)) 1423 rp->active_out = TRUE; 1424 1425/* if(rp_num_ports_open == 1) 1426 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); 1427*/ 1428out: 1429 splx(oldspl); 1430 if(!(tp->t_state & TS_ISOPEN) && rp->wopeners == 0) { 1431 rphardclose(rp); 1432 } 1433 return(error); 1434} 1435 1436int 1437rpclose(dev, flag, mode, p) 1438 dev_t dev; 1439 int flag, mode; 1440 struct proc *p; 1441{ 1442 int oldspl, unit, mynor, umynor, port; /* SG */ 1443 struct rp_port *rp; 1444 struct tty *tp; 1445 CHANNEL_t *cp; 1446 1447 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1448 port = (minor(dev) & 0x1f); /* SG */ 1449 mynor = (port + umynor); /* SG */ 1450 unit = minor_to_unit[mynor]; /* SG */ 1451 1452 if(IS_CONTROL(dev)) 1453 return(0); 1454 rp = rp_addr(unit) + port; 1455 cp = &rp->rp_channel; 1456 tp = rp->rp_tty; 1457 1458 oldspl = spltty(); 1459 (*linesw[tp->t_line].l_close)(tp, flag); 1460 rp_disc_optim(tp, &tp->t_termios, rp); 1461 rpstop(tp, FREAD | FWRITE); 1462 rphardclose(rp); 1463 1464 tp->t_state &= ~TS_BUSY; 1465 ttyclose(tp); 1466 1467 splx(oldspl); 1468 1469 return(0); 1470} 1471 1472static void 1473rphardclose(struct rp_port *rp) 1474{ 1475 int mynor; 1476 struct tty *tp; 1477 CHANNEL_t *cp; 1478 1479 cp = &rp->rp_channel; 1480 tp = rp->rp_tty; 1481 mynor = MINOR_MAGIC(tp->t_dev); 1482 1483 sFlushRxFIFO(cp); 1484 sFlushTxFIFO(cp); 1485 sDisTransmit(cp); 1486 sDisInterrupts(cp, TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN); 1487 sDisRTSFlowCtl(cp); 1488 sDisCTSFlowCtl(cp); 1489 sDisTxSoftFlowCtl(cp); 1490 sClrTxXOFF(cp); 1491 1492 if(tp->t_cflag&HUPCL || !(tp->t_state&TS_ISOPEN) || !rp->active_out) { 1493 sClrDTR(cp); 1494 } 1495 if(IS_CALLOUT(tp->t_dev)) { 1496 sClrDTR(cp); 1497 } 1498 if(rp->dtr_wait != 0) { 1499 timeout(rpdtrwakeup, rp, rp->dtr_wait); 1500 rp->state |= ~SET_DTR; 1501 } 1502 1503 rp->active_out = FALSE; 1504 wakeup(&rp->active_out); 1505 wakeup(TSA_CARR_ON(tp)); 1506} 1507 1508static 1509int 1510rpread(dev, uio, flag) 1511 dev_t dev; 1512 struct uio *uio; 1513 int flag; 1514{ 1515 struct rp_port *rp; 1516 struct tty *tp; 1517 int unit, mynor, umynor, port, error = 0; /* SG */ 1518 1519 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1520 port = (minor(dev) & 0x1f); /* SG */ 1521 mynor = (port + umynor); /* SG */ 1522 unit = minor_to_unit[mynor]; /* SG */ 1523 1524 if(IS_CONTROL(dev)) 1525 return(ENODEV); 1526 rp = rp_addr(unit) + port; 1527 tp = rp->rp_tty; 1528 error = (*linesw[tp->t_line].l_read)(tp, uio, flag); 1529 return(error); 1530} 1531 1532static 1533int 1534rpwrite(dev, uio, flag) 1535 dev_t dev; 1536 struct uio *uio; 1537 int flag; 1538{ 1539 struct rp_port *rp; 1540 struct tty *tp; 1541 int unit, mynor, port, umynor, error = 0; /* SG */ 1542 1543 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1544 port = (minor(dev) & 0x1f); /* SG */ 1545 mynor = (port + umynor); /* SG */ 1546 unit = minor_to_unit[mynor]; /* SG */ 1547 1548 if(IS_CONTROL(dev)) 1549 return(ENODEV); 1550 rp = rp_addr(unit) + port; 1551 tp = rp->rp_tty; 1552 while(rp->rp_disable_writes) { 1553 rp->rp_waiting = 1; 1554 error = ttysleep(tp, (caddr_t)rp, TTOPRI|PCATCH, "rp_write", 0); 1555 if (error) 1556 return(error); 1557 } 1558 1559 error = (*linesw[tp->t_line].l_write)(tp, uio, flag); 1560 return error; 1561} 1562 1563static void 1564rpdtrwakeup(void *chan) 1565{ 1566 struct rp_port *rp; 1567 1568 rp = (struct rp_port *)chan; 1569 rp->state &= SET_DTR; 1570 wakeup(&rp->dtr_wait); 1571} 1572 1573int 1574rpioctl(dev, cmd, data, flag, p) 1575 dev_t dev; 1576 u_long cmd; 1577 caddr_t data; 1578 int flag; 1579 struct proc *p; 1580{ 1581 struct rp_port *rp; 1582 CHANNEL_t *cp; 1583 struct tty *tp; 1584 int unit, mynor, port, umynor; /* SG */ 1585 int oldspl; 1586 int error = 0; 1587 int arg, flags, result, ChanStatus; 1588 int oldcmd; 1589 struct termios term, *t; 1590 1591 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1592 port = (minor(dev) & 0x1f); /* SG */ 1593 mynor = (port + umynor); /* SG */ 1594 unit = minor_to_unit[mynor]; 1595 rp = rp_addr(unit) + port; 1596 1597 if(IS_CONTROL(dev)) { 1598 struct termios *ct; 1599 1600 switch (IS_CONTROL(dev)) { 1601 case CONTROL_INIT_STATE: 1602 ct = IS_CALLOUT(dev) ? &rp->it_out : &rp->it_in; 1603 break; 1604 case CONTROL_LOCK_STATE: 1605 ct = IS_CALLOUT(dev) ? &rp->lt_out : &rp->lt_in; 1606 break; 1607 default: 1608 return(ENODEV); /* /dev/nodev */ 1609 } 1610 switch (cmd) { 1611 case TIOCSETA: 1612 error = suser(p); 1613 if(error != 0) 1614 return(error); 1615 *ct = *(struct termios *)data; 1616 return(0); 1617 case TIOCGETA: 1618 *(struct termios *)data = *ct; 1619 return(0); 1620 case TIOCGETD: 1621 *(int *)data = TTYDISC; 1622 return(0); 1623 case TIOCGWINSZ: 1624 bzero(data, sizeof(struct winsize)); 1625 return(0); 1626 default: 1627 return(ENOTTY); 1628 } 1629 } 1630 1631 tp = rp->rp_tty; 1632 cp = &rp->rp_channel; 1633 1634#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1635 term = tp->t_termios; 1636 oldcmd = cmd; 1637 error = ttsetcompat(tp, &cmd, data, &term); 1638 if(error != 0) 1639 return(error); 1640 if(cmd != oldcmd) { 1641 data = (caddr_t)&term; 1642 } 1643#endif 1644 if((cmd == TIOCSETA) || (cmd == TIOCSETAW) || (cmd == TIOCSETAF)) { 1645 int cc; 1646 struct termios *dt = (struct termios *)data; 1647 struct termios *lt = IS_CALLOUT(dev) 1648 ? &rp->lt_out : &rp->lt_in; 1649 1650 dt->c_iflag = (tp->t_iflag & lt->c_iflag) 1651 | (dt->c_iflag & ~lt->c_iflag); 1652 dt->c_oflag = (tp->t_oflag & lt->c_oflag) 1653 | (dt->c_oflag & ~lt->c_oflag); 1654 dt->c_cflag = (tp->t_cflag & lt->c_cflag) 1655 | (dt->c_cflag & ~lt->c_cflag); 1656 dt->c_lflag = (tp->t_lflag & lt->c_lflag) 1657 | (dt->c_lflag & ~lt->c_lflag); 1658 for(cc = 0; cc < NCCS; ++cc) 1659 if((lt->c_cc[cc] = tp->t_cc[cc]) != 0) 1660 dt->c_cc[cc] = tp->t_cc[cc]; 1661 if(lt->c_ispeed != 0) 1662 dt->c_ispeed = tp->t_ispeed; 1663 if(lt->c_ospeed != 0) 1664 dt->c_ospeed = tp->t_ospeed; 1665 } 1666 1667 t = &tp->t_termios; 1668 1669 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 1670 if(error != ENOIOCTL) { 1671 return(error); 1672 } 1673 oldspl = spltty(); 1674 1675 flags = rp->rp_channel.TxControl[3]; 1676 1677 error = ttioctl(tp, cmd, data, flag); 1678 flags = rp->rp_channel.TxControl[3]; 1679 rp_disc_optim(tp, &tp->t_termios, rp); 1680 if(error != ENOIOCTL) { 1681 splx(oldspl); 1682 return(error); 1683 } 1684 switch(cmd) { 1685 case TIOCSBRK: 1686 sSendBreak(&rp->rp_channel); 1687 break; 1688 1689 case TIOCCBRK: 1690 sClrBreak(&rp->rp_channel); 1691 break; 1692 1693 case TIOCSDTR: 1694 sSetDTR(&rp->rp_channel); 1695 sSetRTS(&rp->rp_channel); 1696 break; 1697 1698 case TIOCCDTR: 1699 sClrDTR(&rp->rp_channel); 1700 break; 1701 1702 case TIOCMSET: 1703 arg = *(int *) data; 1704 flags = 0; 1705 if(arg & TIOCM_RTS) 1706 flags |= SET_RTS; 1707 if(arg & TIOCM_DTR) 1708 flags |= SET_DTR; 1709 rp->rp_channel.TxControl[3] = 1710 ((rp->rp_channel.TxControl[3] 1711 & ~(SET_RTS | SET_DTR)) | flags); 1712 sOutDW(rp->rp_channel.IndexAddr, 1713 *(DWord_t *) &(rp->rp_channel.TxControl[0])); 1714 break; 1715 case TIOCMBIS: 1716 arg = *(int *) data; 1717 flags = 0; 1718 if(arg & TIOCM_RTS) 1719 flags |= SET_RTS; 1720 if(arg & TIOCM_DTR) 1721 flags |= SET_DTR; 1722 rp->rp_channel.TxControl[3] |= flags; 1723 sOutDW(rp->rp_channel.IndexAddr, 1724 *(DWord_t *) &(rp->rp_channel.TxControl[0])); 1725 break; 1726 case TIOCMBIC: 1727 arg = *(int *) data; 1728 flags = 0; 1729 if(arg & TIOCM_RTS) 1730 flags |= SET_RTS; 1731 if(arg & TIOCM_DTR) 1732 flags |= SET_DTR; 1733 rp->rp_channel.TxControl[3] &= ~flags; 1734 sOutDW(rp->rp_channel.IndexAddr, 1735 *(DWord_t *) &(rp->rp_channel.TxControl[0])); 1736 break; 1737 1738 1739 case TIOCMGET: 1740 ChanStatus = sGetChanStatusLo(&rp->rp_channel); 1741 flags = rp->rp_channel.TxControl[3]; 1742 result = TIOCM_LE; /* always on while open for some reason */ 1743 result |= (((flags & SET_DTR) ? TIOCM_DTR : 0) 1744 | ((flags & SET_RTS) ? TIOCM_RTS : 0) 1745 | ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) 1746 | ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) 1747 | ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0)); 1748 1749 if(rp->rp_channel.RxControl[2] & RTSFC_EN) 1750 { 1751 result |= TIOCM_RTS; 1752 } 1753 1754 *(int *)data = result; 1755 break; 1756 case TIOCMSDTRWAIT: 1757 error = suser(p); 1758 if(error != 0) { 1759 splx(oldspl); 1760 return(error); 1761 } 1762 rp->dtr_wait = *(int *)data * hz/100; 1763 break; 1764 case TIOCMGDTRWAIT: 1765 *(int *)data = rp->dtr_wait * 100/hz; 1766 break; 1767 default: 1768 splx(oldspl); 1769 return ENOTTY; 1770 } 1771 splx(oldspl); 1772 return(0); 1773} 1774 1775static struct speedtab baud_table[] = { 1776 B0, 0, B50, BRD50, B75, BRD75, 1777 B110, BRD110, B134, BRD134, B150, BRD150, 1778 B200, BRD200, B300, BRD300, B600, BRD600, 1779 B1200, BRD1200, B1800, BRD1800, B2400, BRD2400, 1780 B4800, BRD4800, B9600, BRD9600, B19200, BRD19200, 1781 B38400, BRD38400, B7200, BRD7200, B14400, BRD14400, 1782 B57600, BRD57600, B76800, BRD76800, 1783 B115200, BRD115200, B230400, BRD230400, 1784 -1, -1 1785}; 1786 1787static int 1788rpparam(tp, t) 1789 struct tty *tp; 1790 struct termios *t; 1791{ 1792 struct rp_port *rp; 1793 CHANNEL_t *cp; 1794 int unit, mynor, port, umynor; /* SG */ 1795 int oldspl, cflag, iflag, oflag, lflag; 1796 int ospeed; 1797 1798 1799 umynor = (((minor(tp->t_dev) >> 16) -1) * 32); /* SG */ 1800 port = (minor(tp->t_dev) & 0x1f); /* SG */ 1801 mynor = (port + umynor); /* SG */ 1802 1803 unit = minor_to_unit[mynor]; 1804 rp = rp_addr(unit) + port; 1805 cp = &rp->rp_channel; 1806 oldspl = spltty(); 1807 1808 cflag = t->c_cflag; 1809 iflag = t->c_iflag; 1810 oflag = t->c_oflag; 1811 lflag = t->c_lflag; 1812 1813 ospeed = ttspeedtab(t->c_ispeed, baud_table); 1814 if(ospeed < 0 || t->c_ispeed != t->c_ospeed) 1815 return(EINVAL); 1816 1817 tp->t_ispeed = t->c_ispeed; 1818 tp->t_ospeed = t->c_ospeed; 1819 tp->t_cflag = cflag; 1820 tp->t_iflag = iflag; 1821 tp->t_oflag = oflag; 1822 tp->t_lflag = lflag; 1823 1824 if(t->c_ospeed == 0) { 1825 sClrDTR(cp); 1826 return(0); 1827 } 1828 rp->rp_fifo_lw = ((t->c_ospeed*2) / 1000) +1; 1829 1830 /* Set baud rate ----- we only pay attention to ispeed */ 1831 sSetDTR(cp); 1832 sSetRTS(cp); 1833 sSetBaud(cp, ospeed); 1834 1835 if(cflag & CSTOPB) { 1836 sSetStop2(cp); 1837 } else { 1838 sSetStop1(cp); 1839 } 1840 1841 if(cflag & PARENB) { 1842 sEnParity(cp); 1843 if(cflag & PARODD) { 1844 sSetOddParity(cp); 1845 } else { 1846 sSetEvenParity(cp); 1847 } 1848 } 1849 else { 1850 sDisParity(cp); 1851 } 1852 if((cflag & CSIZE) == CS8) { 1853 sSetData8(cp); 1854 rp->rp_imask = 0xFF; 1855 } else { 1856 sSetData7(cp); 1857 rp->rp_imask = 0x7F; 1858 } 1859 1860 if(iflag & ISTRIP) { 1861 rp->rp_imask &= 0x7F; 1862 } 1863 1864 if(cflag & CLOCAL) { 1865 rp->rp_intmask &= ~DELTA_CD; 1866 } else { 1867 rp->rp_intmask |= DELTA_CD; 1868 } 1869 1870 /* Put flow control stuff here */ 1871 1872 if(cflag & CCTS_OFLOW) { 1873 sEnCTSFlowCtl(cp); 1874 } else { 1875 sDisCTSFlowCtl(cp); 1876 } 1877 1878 if(cflag & CRTS_IFLOW) { 1879 rp->rp_rts_iflow = 1; 1880 } else { 1881 rp->rp_rts_iflow = 0; 1882 } 1883 1884 if(cflag & CRTS_IFLOW) { 1885 sEnRTSFlowCtl(cp); 1886 } else { 1887 sDisRTSFlowCtl(cp); 1888 } 1889 rp_disc_optim(tp, t, rp); 1890 1891 if((cflag & CLOCAL) || (sGetChanStatusLo(cp) & CD_ACT)) { 1892 tp->t_state |= TS_CARR_ON; 1893 wakeup(TSA_CARR_ON(tp)); 1894 } 1895 1896/* tp->t_state |= TS_CAN_BYPASS_L_RINT; 1897 flags = rp->rp_channel.TxControl[3]; 1898 if(flags & SET_DTR) 1899 else 1900 if(flags & SET_RTS) 1901 else 1902*/ 1903 splx(oldspl); 1904 1905 return(0); 1906} 1907 1908static void 1909rp_disc_optim(tp, t, rp) 1910struct tty *tp; 1911struct termios *t; 1912struct rp_port *rp; 1913{ 1914 if(!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON)) 1915 &&(!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK)) 1916 &&(!(t->c_iflag & PARMRK) 1917 ||(t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK)) 1918 && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) 1919 && linesw[tp->t_line].l_rint == ttyinput) 1920 tp->t_state |= TS_CAN_BYPASS_L_RINT; 1921 else 1922 tp->t_state &= ~TS_CAN_BYPASS_L_RINT; 1923} 1924 1925static void 1926rpstart(tp) 1927 struct tty *tp; 1928{ 1929 struct rp_port *rp; 1930 CHANNEL_t *cp; 1931 struct clist *qp; 1932 int unit, mynor, port, umynor; /* SG */ 1933 char ch, flags; 1934 int spl, xmit_fifo_room; 1935 int count; 1936 1937 1938 umynor = (((minor(tp->t_dev) >> 16) -1) * 32); /* SG */ 1939 port = (minor(tp->t_dev) & 0x1f); /* SG */ 1940 mynor = (port + umynor); /* SG */ 1941 unit = minor_to_unit[mynor]; 1942 rp = rp_addr(unit) + port; 1943 cp = &rp->rp_channel; 1944 flags = rp->rp_channel.TxControl[3]; 1945 spl = spltty(); 1946 1947 if(tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { 1948 ttwwakeup(tp); 1949 splx(spl); 1950 return; 1951 } 1952 if(rp->rp_xmit_stopped) { 1953 sEnTransmit(cp); 1954 rp->rp_xmit_stopped = 0; 1955 } 1956 count = sGetTxCnt(cp); 1957 1958 if(tp->t_outq.c_cc == 0) { 1959 if((tp->t_state & TS_BUSY) && (count == 0)) { 1960 tp->t_state &= ~TS_BUSY; 1961 } 1962 ttwwakeup(tp); 1963 splx(spl); 1964 return; 1965 } 1966 xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); 1967 qp = &tp->t_outq; 1968 count = 0; 1969 if(xmit_fifo_room > 0 && qp->c_cc > 0) { 1970 tp->t_state |= TS_BUSY; 1971 } 1972 while(xmit_fifo_room > 0 && qp->c_cc > 0) { 1973 ch = getc(qp); 1974 sOutB(sGetTxRxDataIO(cp), ch); 1975 xmit_fifo_room--; 1976 count++; 1977 } 1978 rp->rp_restart = (qp->c_cc > 0) ? rp->rp_fifo_lw : 0; 1979 1980 ttwwakeup(tp); 1981 splx(spl); 1982} 1983 1984static 1985void 1986rpstop(tp, flag) 1987 register struct tty *tp; 1988 int flag; 1989{ 1990 struct rp_port *rp; 1991 CHANNEL_t *cp; 1992 int unit, mynor, port, umynor; /* SG */ 1993 int spl; 1994 1995 umynor = (((minor(tp->t_dev) >> 16) -1) * 32); /* SG */ 1996 port = (minor(tp->t_dev) & 0x1f); /* SG */ 1997 mynor = (port + umynor); /* SG */ 1998 unit = minor_to_unit[mynor]; 1999 rp = rp_addr(unit) + port; 2000 cp = &rp->rp_channel; 2001 2002 spl = spltty(); 2003 2004 if(tp->t_state & TS_BUSY) { 2005 if((tp->t_state&TS_TTSTOP) == 0) { 2006 sFlushTxFIFO(cp); 2007 } else { 2008 if(rp->rp_xmit_stopped == 0) { 2009 sDisTransmit(cp); 2010 rp->rp_xmit_stopped = 1; 2011 } 2012 } 2013 } 2014 splx(spl); 2015 rpstart(tp); 2016} 2017 2018int 2019rpselect(dev, flag, p) 2020 dev_t dev; 2021 int flag; 2022 struct proc *p; 2023{ 2024 return(0); 2025} 2026 2027struct tty * 2028rpdevtotty(dev_t dev) 2029{ 2030 struct rp_port *rp; 2031 int unit, port, mynor, umynor; /* SG */ 2032 2033 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 2034 port = (minor(dev) & 0x1f); /* SG */ 2035 mynor = (port + umynor); /* SG */ 2036 unit = minor_to_unit[mynor]; /* SG */ 2037 2038 if(IS_CONTROL(dev)) 2039 return(NULL); 2040 rp = rp_addr(unit) + port; 2041 return(rp->rp_tty); 2042}
| 824}; 825 826static int rp_controller_port = 0; 827static int rp_num_ports_open = 0; 828static int ndevs = 0; 829static int minor_to_unit[128]; 830#if 0 831static struct tty rp_tty[128]; 832#endif 833 834static int rp_num_ports[4]; /* Number of ports on each controller */ 835 836#define _INLINE_ __inline 837#define POLL_INTERVAL 1 838 839#define CALLOUT_MASK 0x80 840#define CONTROL_MASK 0x60 841#define CONTROL_INIT_STATE 0x20 842#define CONTROL_LOCK_STATE 0x40 843#define DEV_UNIT(dev) (MINOR_TO_UNIT(minor(dev)) 844#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK) 845#define MINOR_MAGIC(dev) ((minor(dev)) & ~MINOR_MAGIC_MASK) 846#define IS_CALLOUT(dev) (minor(dev) & CALLOUT_MASK) 847#define IS_CONTROL(dev) (minor(dev) & CONTROL_MASK) 848 849#define RP_ISMULTIPORT(dev) ((dev)->id_flags & 0x1) 850#define RP_MPMASTER(dev) (((dev)->id_flags >> 8) & 0xff) 851#define RP_NOTAST4(dev) ((dev)->id_flags & 0x04) 852 853static struct rp_port *p_rp_addr[4]; 854static struct rp_port *p_rp_table[MAX_RP_PORTS]; 855#define rp_addr(unit) (p_rp_addr[unit]) 856#define rp_table(port) (p_rp_table[port]) 857 858/* 859 * The top-level routines begin here 860 */ 861 862int rpselect __P((dev_t, int, struct proc *)); 863 864static int rpparam __P((struct tty *, struct termios *)); 865static void rpstart __P((struct tty *)); 866static void rphardclose __P((struct rp_port *)); 867#define rpmap nomap 868#define rpreset noreset 869#define rpstrategy nostrategy 870static void rp_disc_optim __P((struct tty *tp, struct termios *t, 871 struct rp_port *rp)); 872 873static _INLINE_ void rp_do_receive(struct rp_port *rp, struct tty *tp, 874 CHANNEL_t *cp, unsigned int ChanStatus) 875{ 876 int spl; 877 unsigned int CharNStat; 878 int ToRecv, ch; 879 880 ToRecv = sGetRxCnt(cp); 881 if(ToRecv == 0) 882 return; 883 884/* If status indicates there are errored characters in the 885 FIFO, then enter status mode (a word in FIFO holds 886 characters and status) 887*/ 888 889 if(ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) { 890 if(!(ChanStatus & STATMODE)) { 891 ChanStatus |= STATMODE; 892 sEnRxStatusMode(cp); 893 } 894 } 895/* 896 if we previously entered status mode then read down the 897 FIFO one word at a time, pulling apart the character and 898 the status. Update error counters depending on status. 899*/ 900 if(ChanStatus & STATMODE) { 901 while(ToRecv) { 902 if(tp->t_state & TS_TBLOCK) { 903 break; 904 } 905 CharNStat = sInW(sGetTxRxDataIO(cp)); 906 ch = CharNStat & 0xff; 907 908 if((CharNStat & STMBREAK) || (CharNStat & STMFRAMEH)) 909 ch |= TTY_FE; 910 else if (CharNStat & STMPARITYH) 911 ch |= TTY_PE; 912 else if (CharNStat & STMRCVROVRH) 913 rp->rp_overflows++; 914 915 (*linesw[tp->t_line].l_rint)(ch, tp); 916 ToRecv--; 917 } 918/* 919 After emtying FIFO in status mode, turn off status mode 920*/ 921 922 if(sGetRxCnt(cp) == 0) 923 sDisRxStatusMode(cp); 924 } 925 else { 926 while (ToRecv) { 927 if(tp->t_state & TS_TBLOCK) { 928 break; 929 } 930 ch = (u_char) sInB(sGetTxRxDataIO(cp)); 931 spl = spltty(); 932 (*linesw[tp->t_line].l_rint)(ch, tp); 933 splx(spl); 934 ToRecv--; 935 } 936 } 937} 938 939static _INLINE_ void rp_handle_port(struct rp_port *rp) 940{ 941 CHANNEL_t *cp; 942 struct tty *tp; 943 unsigned int IntMask, ChanStatus; 944 /* int oldcts; */ 945 946 if(!rp) 947 return; 948 949 cp = &rp->rp_channel; 950 tp = rp->rp_tty; 951 IntMask = sGetChanIntID(cp); 952 IntMask = IntMask & rp->rp_intmask; 953 ChanStatus = sGetChanStatus(cp); 954 if(IntMask & RXF_TRIG) 955 if(!(tp->t_state & TS_TBLOCK) && (tp->t_state & TS_CARR_ON) && (tp->t_state & TS_ISOPEN)) { 956 rp_do_receive(rp, tp, cp, ChanStatus); 957 } 958 if(IntMask & DELTA_CD) { 959 if(ChanStatus & CD_ACT) { 960 if(!(tp->t_state & TS_CARR_ON) ) { 961 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 962 } 963 } else { 964 if((tp->t_state & TS_CARR_ON)) { 965 (void)(*linesw[tp->t_line].l_modem)(tp, 0); 966 if((*linesw[tp->t_line].l_modem)(tp, 0) == 0) { 967 rphardclose(rp); 968 } 969 } 970 } 971 } 972/* oldcts = rp->rp_cts; 973 rp->rp_cts = ((ChanStatus & CTS_ACT) != 0); 974 if(oldcts != rp->rp_cts) { 975 printf("CTS change (now %s)... on port %d\n", rp->rp_cts ? "on" : "off", rp->rp_port); 976 } 977*/ 978} 979 980static void rp_do_poll(void *not_used) 981{ 982 CONTROLLER_t *ctl; 983 struct rp_port *rp; 984 struct tty *tp; 985 int unit, aiop, ch, line, count; 986 unsigned char CtlMask, AiopMask; 987 988 for(unit = 0; unit <= ndevs; unit++) { 989 rp = rp_addr(unit); 990 ctl = rp->rp_ctlp; 991 if(ctl->BusType == isPCI) 992 CtlMask = sPCIGetControllerIntStatus(ctl); 993 else 994 CtlMask = sGetControllerIntStatus(ctl); 995 for(aiop=0; CtlMask; CtlMask >>=1, aiop++) { 996 if(CtlMask & 1) { 997 AiopMask = sGetAiopIntStatus(ctl, aiop); 998 for(ch = 0; AiopMask; AiopMask >>=1, ch++) { 999 if(AiopMask & 1) { 1000 line = (unit << 5) | (aiop << 3) | ch; 1001 rp = rp_table(line); 1002 rp_handle_port(rp); 1003 } 1004 } 1005 } 1006 } 1007 1008 for(line = 0, rp = rp_addr(unit); line < rp_num_ports[unit]; 1009 line++, rp++) { 1010 tp = rp->rp_tty; 1011 if((tp->t_state & TS_BUSY) && (tp->t_state & TS_ISOPEN)) { 1012 count = sGetTxCnt(&rp->rp_channel); 1013 if(count == 0) 1014 tp->t_state &= ~(TS_BUSY); 1015 if(!(tp->t_state & TS_TTSTOP) && 1016 (count <= rp->rp_restart)) { 1017 (*linesw[tp->t_line].l_start)(tp); 1018 } 1019 } 1020 } 1021 } 1022 if(rp_num_ports_open) 1023 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); 1024} 1025 1026static const char* 1027rp_pciprobe(pcici_t tag, pcidi_t type) 1028{ 1029 int vendor_id; 1030 1031 vendor_id = type & 0xffff; 1032 switch(vendor_id) 1033 case 0x11fe: 1034 return("rp"); 1035 return(NULL); 1036} 1037 1038static 1039int 1040rpprobe(dev) 1041struct isa_device *dev; 1042{ 1043 int controller, unit; 1044 int aiop, num_aiops; 1045 unsigned int aiopio[MAX_AIOPS_PER_BOARD]; 1046 CONTROLLER_t *ctlp; 1047 1048 unit = dev->id_unit; 1049 if (dev->id_unit >= 4) { 1050 printf("rpprobe: unit number %d invalid.\n", dev->id_unit); 1051 return 1; 1052 } 1053 printf("probing for RocketPort(ISA) unit %d\n", unit); 1054 if (rp_controller_port) 1055 controller = rp_controller_port; 1056 else { 1057 controller = dev->id_iobase + 0x40; 1058 } 1059 1060 for (aiop=0; aiop<MAX_AIOPS_PER_BOARD; aiop++) 1061 aiopio[aiop]= dev->id_iobase + (aiop * 0x400); 1062 1063 ctlp = sCtlNumToCtlPtr(dev->id_unit); 1064 num_aiops = sInitController(ctlp, dev->id_unit, 1065 controller + ((unit-rp_pcicount)*0x400), 1066 aiopio, MAX_AIOPS_PER_BOARD, 0, 1067 FREQ_DIS, 0); 1068 if (num_aiops <= 0) { 1069 printf("board%d init failed\n", unit); 1070 return 0; 1071 } 1072 1073 if (rp_controller_port) { 1074 dev->id_msize = 64; 1075 } else { 1076 dev->id_msize = 68; 1077 rp_controller_port = controller; 1078 } 1079 1080 dev->id_irq = 0; 1081 1082 return 1; 1083} 1084 1085static void 1086rp_pciattach(pcici_t tag, int unit) 1087{ 1088 dev_t rp_dev; 1089 int success, oldspl; 1090 u_short iobase; 1091 int num_ports, num_chan, num_aiops; 1092 int aiop, chan, port; 1093 int ChanStatus, line, i, count; 1094 unsigned int aiopio[MAX_AIOPS_PER_BOARD]; 1095 struct rp_port *rp; 1096 struct tty *tty; 1097 CONTROLLER_t *ctlp; 1098 1099 success = pci_map_port(tag, 0x10, &iobase); 1100 if(!success) 1101 printf("ioaddr mapping failed for RocketPort(PCI)\n"); 1102 1103 for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++) 1104 aiopio[aiop] = iobase + (aiop * 0x40); 1105 1106 ctlp = sCtlNumToCtlPtr(unit); 1107 num_aiops = sPCIInitController(ctlp, unit, 1108 aiopio, MAX_AIOPS_PER_BOARD, 0, 1109 FREQ_DIS, 0); 1110 1111 num_ports = 0; 1112 for(aiop=0; aiop < num_aiops; aiop++) { 1113 sResetAiopByNum(ctlp, aiop); 1114 num_ports += sGetAiopNumChan(ctlp, aiop); 1115 } 1116 printf("RocketPort%d = %d ports\n", unit, num_ports); 1117 rp_num_ports[unit] = num_ports; 1118 1119 rp = (struct rp_port *) 1120 malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT); 1121 if(rp == 0) { 1122 printf("rp_attach: Could not malloc rp_ports structures\n"); 1123 return; 1124 } 1125 1126 count = unit * 32; /* board times max ports per card SG */ 1127 for(i=count;i < (count + rp_num_ports[unit]);i++) 1128 minor_to_unit[i] = unit; 1129 1130 bzero(rp, sizeof(struct rp_port) * num_ports); 1131 tty = (struct tty *) 1132 malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT); 1133 if(tty == 0) { 1134 printf("rp_attach: Could not malloc tty structures\n"); 1135 return; 1136 } 1137 bzero(tty, sizeof(struct tty) * num_ports); 1138 1139 oldspl = spltty(); 1140 rp_addr(unit) = rp; 1141 splx(oldspl); 1142 1143 rp_dev = makedev(CDEV_MAJOR, unit); 1144 cdevsw_add(&rp_dev, &rp_cdevsw, NULL); 1145 1146 port = 0; 1147 for(aiop=0; aiop < num_aiops; aiop++) { 1148 num_chan = sGetAiopNumChan(ctlp, aiop); 1149 for(chan=0; chan < num_chan; chan++, port++, rp++, tty++) { 1150 rp->rp_tty = tty; 1151 rp->rp_port = port; 1152 rp->rp_ctlp = ctlp; 1153 rp->rp_unit = unit; 1154 rp->rp_chan = chan; 1155 rp->rp_aiop = aiop; 1156 1157 tty->t_line = 0; 1158 /* tty->t_termios = deftermios; 1159 */ 1160 rp->dtr_wait = 3 * hz; 1161 rp->it_in.c_iflag = 0; 1162 rp->it_in.c_oflag = 0; 1163 rp->it_in.c_cflag = TTYDEF_CFLAG; 1164 rp->it_in.c_lflag = 0; 1165 termioschars(&rp->it_in); 1166 /* termioschars(&tty->t_termios); 1167 */ 1168 rp->it_in.c_ispeed = rp->it_in.c_ospeed = TTYDEF_SPEED; 1169 rp->it_out = rp->it_in; 1170 1171 rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | 1172 DELTA_CD | DELTA_CTS | DELTA_DSR; 1173 ChanStatus = sGetChanStatus(&rp->rp_channel); 1174 if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) { 1175 printf("RocketPort sInitChan(%d, %d, %d) failed 1176 \n", unit, aiop, chan); 1177 return; 1178 } 1179 ChanStatus = sGetChanStatus(&rp->rp_channel); 1180 rp->rp_cts = (ChanStatus & CTS_ACT) != 0; 1181 line = (unit << 5) | (aiop << 3) | chan; 1182 rp_table(line) = rp; 1183/* devfs_add_devswf(&rp_cdevsw, 1184 port, DV_CHR, UID_ROOT, GID_WHEEL, 0600, 1185 "ttyR%r", port); 1186 devfs_add_devswf(&rp_cdevsw, 1187 port | CONTROL_INIT_STATE, DV_CHR, UID_ROOT, 1188 GID_WHEEL, 0600, "ttyRi%r", port); 1189*/ 1190 } 1191 } 1192} 1193 1194static 1195int 1196rpattach(dev) 1197struct isa_device *dev; 1198{ 1199 dev_t rp_dev; 1200 int iobase, unit, /*rpmajor,*/ oldspl; 1201 int num_ports, num_chan, num_aiops; 1202 int aiop, chan, port; 1203 int ChanStatus, line, i, count; 1204 unsigned int aiopio[MAX_AIOPS_PER_BOARD]; 1205 struct rp_port *rp; 1206 struct tty *tty; 1207 CONTROLLER_t *ctlp; 1208 1209 iobase = dev->id_iobase; 1210 unit = dev->id_unit; 1211 ndevs = unit; 1212 1213 for(aiop=0; aiop < MAX_AIOPS_PER_BOARD; aiop++) 1214 aiopio[aiop] = iobase + (aiop * 0x400); 1215 1216 ctlp = sCtlNumToCtlPtr(unit); 1217 num_aiops = sInitController(ctlp, unit, 1218 rp_controller_port + ((unit-rp_pcicount) * 0x400), 1219 aiopio, MAX_AIOPS_PER_BOARD, 0, 1220 FREQ_DIS, 0); 1221 1222 num_ports = 0; 1223 for(aiop=0; aiop < num_aiops; aiop++) { 1224 sResetAiopByNum(ctlp, aiop); 1225 sEnAiop(ctlp, aiop); 1226 num_ports += sGetAiopNumChan(ctlp, aiop); 1227 } 1228 printf("RocketPort%d = %d ports\n", unit, num_ports); 1229 rp_num_ports[unit] = num_ports; 1230 1231 rp = (struct rp_port *) 1232 malloc(sizeof(struct rp_port) * num_ports, M_TTYS, M_NOWAIT); 1233 if(rp == 0) { 1234 printf("rp_attach: Could not malloc rp_ports structures\n"); 1235 return(0); 1236 } 1237 1238 count = unit * 32; /* board # times max ports per card SG */ 1239 for(i=count;i < (count + rp_num_ports[unit]);i++) 1240 minor_to_unit[i] = unit; 1241 1242 bzero(rp, sizeof(struct rp_port) * num_ports); 1243 tty = (struct tty *) 1244 malloc(sizeof(struct tty) * num_ports, M_TTYS, M_NOWAIT); 1245 if(tty == 0) { 1246 printf("rp_attach: Could not malloc tty structures\n"); 1247 return(0); 1248 } 1249 bzero(tty, sizeof(struct tty) * num_ports); 1250 1251 oldspl = spltty(); 1252 rp_addr(unit) = rp; 1253 splx(oldspl); 1254 1255 rp_dev = makedev(CDEV_MAJOR, unit); 1256 cdevsw_add(&rp_dev, &rp_cdevsw, NULL); 1257 1258 port = 0; 1259 for(aiop=0; aiop < num_aiops; aiop++) { 1260 num_chan = sGetAiopNumChan(ctlp, aiop); 1261 for(chan=0; chan < num_chan; chan++, port++, rp++, tty++) { 1262 rp->rp_tty = tty; 1263 rp->rp_port = port; 1264 rp->rp_ctlp = ctlp; 1265 rp->rp_unit = unit; 1266 rp->rp_chan = chan; 1267 rp->rp_aiop = aiop; 1268 1269 tty->t_line = 0; 1270 /* tty->t_termios = deftermios; 1271 */ 1272 rp->dtr_wait = 3 * hz; 1273 rp->it_in.c_iflag = 0; 1274 rp->it_in.c_oflag = 0; 1275 rp->it_in.c_cflag = TTYDEF_CFLAG; 1276 rp->it_in.c_lflag = 0; 1277 termioschars(&rp->it_in); 1278 /* termioschars(&tty->t_termios); 1279 */ 1280 rp->it_in.c_ispeed = rp->it_in.c_ospeed = TTYDEF_SPEED; 1281 rp->it_out = rp->it_in; 1282 1283 rp->rp_intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | 1284 DELTA_CD | DELTA_CTS | DELTA_DSR; 1285 ChanStatus = sGetChanStatus(&rp->rp_channel); 1286 if(sInitChan(ctlp, &rp->rp_channel, aiop, chan) == 0) { 1287 printf("RocketPort sInitChan(%d, %d, %d) failed 1288 \n", unit, aiop, chan); 1289 return(0); 1290 } 1291 ChanStatus = sGetChanStatus(&rp->rp_channel); 1292 rp->rp_cts = (ChanStatus & CTS_ACT) != 0; 1293 line = (unit << 5) | (aiop << 3) | chan; 1294 rp_table(line) = rp; 1295 } 1296 } 1297 1298 return(1); 1299} 1300 1301int 1302rpopen(dev, flag, mode, p) 1303 dev_t dev; 1304 int flag, mode; 1305 struct proc *p; 1306{ 1307 struct rp_port *rp; 1308 int unit, port, mynor, umynor, flags; /* SG */ 1309 struct tty *tp; 1310 int oldspl, error; 1311 unsigned int IntMask, ChanStatus; 1312 1313 1314 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1315 port = (minor(dev) & 0x1f); /* SG */ 1316 mynor = (port + umynor); /* SG */ 1317 unit = minor_to_unit[mynor]; 1318 if(IS_CONTROL(dev)) 1319 return(0); 1320 rp = rp_addr(unit) + port; 1321/* rp->rp_tty = &rp_tty[rp->rp_port]; 1322*/ 1323 tp = rp->rp_tty; 1324 1325 oldspl = spltty(); 1326 1327open_top: 1328 while(rp->state & ~SET_DTR) { 1329 error = tsleep(&rp->dtr_wait, TTIPRI | PCATCH, "rpdtr", 0); 1330 if(error != 0) 1331 goto out; 1332 } 1333 1334 if(tp->t_state & TS_ISOPEN) { 1335 if(IS_CALLOUT(dev)) { 1336 if(!rp->active_out) { 1337 error = EBUSY; 1338 goto out; 1339 } 1340 } else { 1341 if(rp->active_out) { 1342 if(flag & O_NONBLOCK) { 1343 error = EBUSY; 1344 goto out; 1345 } 1346 error = tsleep(&rp->active_out, 1347 TTIPRI | PCATCH, "rpbi", 0); 1348 if(error != 0) 1349 goto out; 1350 goto open_top; 1351 } 1352 } 1353 if(tp->t_state & TS_XCLUDE && 1354 suser(p)) { 1355 splx(oldspl); 1356 return(EBUSY); 1357 } 1358 } 1359 else { 1360 tp->t_dev = dev; 1361 tp->t_param = rpparam; 1362 tp->t_oproc = rpstart; 1363 tp->t_line = 0; 1364 tp->t_termios = IS_CALLOUT(dev) ? rp->it_out : rp->it_in; 1365 flags = 0; 1366 flags |= SET_RTS; 1367 flags |= SET_DTR; 1368 rp->rp_channel.TxControl[3] = 1369 ((rp->rp_channel.TxControl[3] 1370 & ~(SET_RTS | SET_DTR)) | flags); 1371 sOutDW(rp->rp_channel.IndexAddr, 1372 *(DWord_t *) &(rp->rp_channel.TxControl[0])); 1373 sSetRxTrigger(&rp->rp_channel, TRIG_1); 1374 sDisRxStatusMode(&rp->rp_channel); 1375 sFlushRxFIFO(&rp->rp_channel); 1376 sFlushTxFIFO(&rp->rp_channel); 1377 1378 sEnInterrupts(&rp->rp_channel, 1379 (TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN)); 1380 sSetRxTrigger(&rp->rp_channel, TRIG_1); 1381 1382 sDisRxStatusMode(&rp->rp_channel); 1383 sClrTxXOFF(&rp->rp_channel); 1384 1385/* sDisRTSFlowCtl(&rp->rp_channel); 1386 sDisCTSFlowCtl(&rp->rp_channel); 1387*/ 1388 sDisTxSoftFlowCtl(&rp->rp_channel); 1389 1390 sStartRxProcessor(&rp->rp_channel); 1391 1392 sEnRxFIFO(&rp->rp_channel); 1393 sEnTransmit(&rp->rp_channel); 1394 1395/* sSetDTR(&rp->rp_channel); 1396 sSetRTS(&rp->rp_channel); 1397*/ 1398 1399 ++rp->wopeners; 1400 error = rpparam(tp, &tp->t_termios); 1401 --rp->wopeners; 1402 if(error != 0) { 1403 splx(oldspl); 1404 return(error); 1405 } 1406 1407 rp_num_ports_open++; 1408 1409 IntMask = sGetChanIntID(&rp->rp_channel); 1410 IntMask = IntMask & rp->rp_intmask; 1411 ChanStatus = sGetChanStatus(&rp->rp_channel); 1412 if((IntMask & DELTA_CD) || IS_CALLOUT(dev)) { 1413 if((ChanStatus & CD_ACT) || IS_CALLOUT(dev)) { 1414 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 1415 } 1416 } 1417 1418 if(rp_num_ports_open == 1) 1419 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); 1420 1421 } 1422 1423 if(!(flag&O_NONBLOCK) && !(tp->t_cflag&CLOCAL) && 1424 !(tp->t_state & TS_CARR_ON) && !(IS_CALLOUT(dev))) { 1425 ++rp->wopeners; 1426 error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, 1427 "rpdcd", 0); 1428 --rp->wopeners; 1429 if(error != 0) 1430 goto out; 1431 goto open_top; 1432 } 1433 error = (*linesw[tp->t_line].l_open)(dev, tp); 1434 1435 rp_disc_optim(tp, &tp->t_termios, rp); 1436 if(tp->t_state & TS_ISOPEN && IS_CALLOUT(dev)) 1437 rp->active_out = TRUE; 1438 1439/* if(rp_num_ports_open == 1) 1440 timeout(rp_do_poll, (void *)NULL, POLL_INTERVAL); 1441*/ 1442out: 1443 splx(oldspl); 1444 if(!(tp->t_state & TS_ISOPEN) && rp->wopeners == 0) { 1445 rphardclose(rp); 1446 } 1447 return(error); 1448} 1449 1450int 1451rpclose(dev, flag, mode, p) 1452 dev_t dev; 1453 int flag, mode; 1454 struct proc *p; 1455{ 1456 int oldspl, unit, mynor, umynor, port; /* SG */ 1457 struct rp_port *rp; 1458 struct tty *tp; 1459 CHANNEL_t *cp; 1460 1461 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1462 port = (minor(dev) & 0x1f); /* SG */ 1463 mynor = (port + umynor); /* SG */ 1464 unit = minor_to_unit[mynor]; /* SG */ 1465 1466 if(IS_CONTROL(dev)) 1467 return(0); 1468 rp = rp_addr(unit) + port; 1469 cp = &rp->rp_channel; 1470 tp = rp->rp_tty; 1471 1472 oldspl = spltty(); 1473 (*linesw[tp->t_line].l_close)(tp, flag); 1474 rp_disc_optim(tp, &tp->t_termios, rp); 1475 rpstop(tp, FREAD | FWRITE); 1476 rphardclose(rp); 1477 1478 tp->t_state &= ~TS_BUSY; 1479 ttyclose(tp); 1480 1481 splx(oldspl); 1482 1483 return(0); 1484} 1485 1486static void 1487rphardclose(struct rp_port *rp) 1488{ 1489 int mynor; 1490 struct tty *tp; 1491 CHANNEL_t *cp; 1492 1493 cp = &rp->rp_channel; 1494 tp = rp->rp_tty; 1495 mynor = MINOR_MAGIC(tp->t_dev); 1496 1497 sFlushRxFIFO(cp); 1498 sFlushTxFIFO(cp); 1499 sDisTransmit(cp); 1500 sDisInterrupts(cp, TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN); 1501 sDisRTSFlowCtl(cp); 1502 sDisCTSFlowCtl(cp); 1503 sDisTxSoftFlowCtl(cp); 1504 sClrTxXOFF(cp); 1505 1506 if(tp->t_cflag&HUPCL || !(tp->t_state&TS_ISOPEN) || !rp->active_out) { 1507 sClrDTR(cp); 1508 } 1509 if(IS_CALLOUT(tp->t_dev)) { 1510 sClrDTR(cp); 1511 } 1512 if(rp->dtr_wait != 0) { 1513 timeout(rpdtrwakeup, rp, rp->dtr_wait); 1514 rp->state |= ~SET_DTR; 1515 } 1516 1517 rp->active_out = FALSE; 1518 wakeup(&rp->active_out); 1519 wakeup(TSA_CARR_ON(tp)); 1520} 1521 1522static 1523int 1524rpread(dev, uio, flag) 1525 dev_t dev; 1526 struct uio *uio; 1527 int flag; 1528{ 1529 struct rp_port *rp; 1530 struct tty *tp; 1531 int unit, mynor, umynor, port, error = 0; /* SG */ 1532 1533 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1534 port = (minor(dev) & 0x1f); /* SG */ 1535 mynor = (port + umynor); /* SG */ 1536 unit = minor_to_unit[mynor]; /* SG */ 1537 1538 if(IS_CONTROL(dev)) 1539 return(ENODEV); 1540 rp = rp_addr(unit) + port; 1541 tp = rp->rp_tty; 1542 error = (*linesw[tp->t_line].l_read)(tp, uio, flag); 1543 return(error); 1544} 1545 1546static 1547int 1548rpwrite(dev, uio, flag) 1549 dev_t dev; 1550 struct uio *uio; 1551 int flag; 1552{ 1553 struct rp_port *rp; 1554 struct tty *tp; 1555 int unit, mynor, port, umynor, error = 0; /* SG */ 1556 1557 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1558 port = (minor(dev) & 0x1f); /* SG */ 1559 mynor = (port + umynor); /* SG */ 1560 unit = minor_to_unit[mynor]; /* SG */ 1561 1562 if(IS_CONTROL(dev)) 1563 return(ENODEV); 1564 rp = rp_addr(unit) + port; 1565 tp = rp->rp_tty; 1566 while(rp->rp_disable_writes) { 1567 rp->rp_waiting = 1; 1568 error = ttysleep(tp, (caddr_t)rp, TTOPRI|PCATCH, "rp_write", 0); 1569 if (error) 1570 return(error); 1571 } 1572 1573 error = (*linesw[tp->t_line].l_write)(tp, uio, flag); 1574 return error; 1575} 1576 1577static void 1578rpdtrwakeup(void *chan) 1579{ 1580 struct rp_port *rp; 1581 1582 rp = (struct rp_port *)chan; 1583 rp->state &= SET_DTR; 1584 wakeup(&rp->dtr_wait); 1585} 1586 1587int 1588rpioctl(dev, cmd, data, flag, p) 1589 dev_t dev; 1590 u_long cmd; 1591 caddr_t data; 1592 int flag; 1593 struct proc *p; 1594{ 1595 struct rp_port *rp; 1596 CHANNEL_t *cp; 1597 struct tty *tp; 1598 int unit, mynor, port, umynor; /* SG */ 1599 int oldspl; 1600 int error = 0; 1601 int arg, flags, result, ChanStatus; 1602 int oldcmd; 1603 struct termios term, *t; 1604 1605 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 1606 port = (minor(dev) & 0x1f); /* SG */ 1607 mynor = (port + umynor); /* SG */ 1608 unit = minor_to_unit[mynor]; 1609 rp = rp_addr(unit) + port; 1610 1611 if(IS_CONTROL(dev)) { 1612 struct termios *ct; 1613 1614 switch (IS_CONTROL(dev)) { 1615 case CONTROL_INIT_STATE: 1616 ct = IS_CALLOUT(dev) ? &rp->it_out : &rp->it_in; 1617 break; 1618 case CONTROL_LOCK_STATE: 1619 ct = IS_CALLOUT(dev) ? &rp->lt_out : &rp->lt_in; 1620 break; 1621 default: 1622 return(ENODEV); /* /dev/nodev */ 1623 } 1624 switch (cmd) { 1625 case TIOCSETA: 1626 error = suser(p); 1627 if(error != 0) 1628 return(error); 1629 *ct = *(struct termios *)data; 1630 return(0); 1631 case TIOCGETA: 1632 *(struct termios *)data = *ct; 1633 return(0); 1634 case TIOCGETD: 1635 *(int *)data = TTYDISC; 1636 return(0); 1637 case TIOCGWINSZ: 1638 bzero(data, sizeof(struct winsize)); 1639 return(0); 1640 default: 1641 return(ENOTTY); 1642 } 1643 } 1644 1645 tp = rp->rp_tty; 1646 cp = &rp->rp_channel; 1647 1648#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1649 term = tp->t_termios; 1650 oldcmd = cmd; 1651 error = ttsetcompat(tp, &cmd, data, &term); 1652 if(error != 0) 1653 return(error); 1654 if(cmd != oldcmd) { 1655 data = (caddr_t)&term; 1656 } 1657#endif 1658 if((cmd == TIOCSETA) || (cmd == TIOCSETAW) || (cmd == TIOCSETAF)) { 1659 int cc; 1660 struct termios *dt = (struct termios *)data; 1661 struct termios *lt = IS_CALLOUT(dev) 1662 ? &rp->lt_out : &rp->lt_in; 1663 1664 dt->c_iflag = (tp->t_iflag & lt->c_iflag) 1665 | (dt->c_iflag & ~lt->c_iflag); 1666 dt->c_oflag = (tp->t_oflag & lt->c_oflag) 1667 | (dt->c_oflag & ~lt->c_oflag); 1668 dt->c_cflag = (tp->t_cflag & lt->c_cflag) 1669 | (dt->c_cflag & ~lt->c_cflag); 1670 dt->c_lflag = (tp->t_lflag & lt->c_lflag) 1671 | (dt->c_lflag & ~lt->c_lflag); 1672 for(cc = 0; cc < NCCS; ++cc) 1673 if((lt->c_cc[cc] = tp->t_cc[cc]) != 0) 1674 dt->c_cc[cc] = tp->t_cc[cc]; 1675 if(lt->c_ispeed != 0) 1676 dt->c_ispeed = tp->t_ispeed; 1677 if(lt->c_ospeed != 0) 1678 dt->c_ospeed = tp->t_ospeed; 1679 } 1680 1681 t = &tp->t_termios; 1682 1683 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 1684 if(error != ENOIOCTL) { 1685 return(error); 1686 } 1687 oldspl = spltty(); 1688 1689 flags = rp->rp_channel.TxControl[3]; 1690 1691 error = ttioctl(tp, cmd, data, flag); 1692 flags = rp->rp_channel.TxControl[3]; 1693 rp_disc_optim(tp, &tp->t_termios, rp); 1694 if(error != ENOIOCTL) { 1695 splx(oldspl); 1696 return(error); 1697 } 1698 switch(cmd) { 1699 case TIOCSBRK: 1700 sSendBreak(&rp->rp_channel); 1701 break; 1702 1703 case TIOCCBRK: 1704 sClrBreak(&rp->rp_channel); 1705 break; 1706 1707 case TIOCSDTR: 1708 sSetDTR(&rp->rp_channel); 1709 sSetRTS(&rp->rp_channel); 1710 break; 1711 1712 case TIOCCDTR: 1713 sClrDTR(&rp->rp_channel); 1714 break; 1715 1716 case TIOCMSET: 1717 arg = *(int *) data; 1718 flags = 0; 1719 if(arg & TIOCM_RTS) 1720 flags |= SET_RTS; 1721 if(arg & TIOCM_DTR) 1722 flags |= SET_DTR; 1723 rp->rp_channel.TxControl[3] = 1724 ((rp->rp_channel.TxControl[3] 1725 & ~(SET_RTS | SET_DTR)) | flags); 1726 sOutDW(rp->rp_channel.IndexAddr, 1727 *(DWord_t *) &(rp->rp_channel.TxControl[0])); 1728 break; 1729 case TIOCMBIS: 1730 arg = *(int *) data; 1731 flags = 0; 1732 if(arg & TIOCM_RTS) 1733 flags |= SET_RTS; 1734 if(arg & TIOCM_DTR) 1735 flags |= SET_DTR; 1736 rp->rp_channel.TxControl[3] |= flags; 1737 sOutDW(rp->rp_channel.IndexAddr, 1738 *(DWord_t *) &(rp->rp_channel.TxControl[0])); 1739 break; 1740 case TIOCMBIC: 1741 arg = *(int *) data; 1742 flags = 0; 1743 if(arg & TIOCM_RTS) 1744 flags |= SET_RTS; 1745 if(arg & TIOCM_DTR) 1746 flags |= SET_DTR; 1747 rp->rp_channel.TxControl[3] &= ~flags; 1748 sOutDW(rp->rp_channel.IndexAddr, 1749 *(DWord_t *) &(rp->rp_channel.TxControl[0])); 1750 break; 1751 1752 1753 case TIOCMGET: 1754 ChanStatus = sGetChanStatusLo(&rp->rp_channel); 1755 flags = rp->rp_channel.TxControl[3]; 1756 result = TIOCM_LE; /* always on while open for some reason */ 1757 result |= (((flags & SET_DTR) ? TIOCM_DTR : 0) 1758 | ((flags & SET_RTS) ? TIOCM_RTS : 0) 1759 | ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) 1760 | ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) 1761 | ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0)); 1762 1763 if(rp->rp_channel.RxControl[2] & RTSFC_EN) 1764 { 1765 result |= TIOCM_RTS; 1766 } 1767 1768 *(int *)data = result; 1769 break; 1770 case TIOCMSDTRWAIT: 1771 error = suser(p); 1772 if(error != 0) { 1773 splx(oldspl); 1774 return(error); 1775 } 1776 rp->dtr_wait = *(int *)data * hz/100; 1777 break; 1778 case TIOCMGDTRWAIT: 1779 *(int *)data = rp->dtr_wait * 100/hz; 1780 break; 1781 default: 1782 splx(oldspl); 1783 return ENOTTY; 1784 } 1785 splx(oldspl); 1786 return(0); 1787} 1788 1789static struct speedtab baud_table[] = { 1790 B0, 0, B50, BRD50, B75, BRD75, 1791 B110, BRD110, B134, BRD134, B150, BRD150, 1792 B200, BRD200, B300, BRD300, B600, BRD600, 1793 B1200, BRD1200, B1800, BRD1800, B2400, BRD2400, 1794 B4800, BRD4800, B9600, BRD9600, B19200, BRD19200, 1795 B38400, BRD38400, B7200, BRD7200, B14400, BRD14400, 1796 B57600, BRD57600, B76800, BRD76800, 1797 B115200, BRD115200, B230400, BRD230400, 1798 -1, -1 1799}; 1800 1801static int 1802rpparam(tp, t) 1803 struct tty *tp; 1804 struct termios *t; 1805{ 1806 struct rp_port *rp; 1807 CHANNEL_t *cp; 1808 int unit, mynor, port, umynor; /* SG */ 1809 int oldspl, cflag, iflag, oflag, lflag; 1810 int ospeed; 1811 1812 1813 umynor = (((minor(tp->t_dev) >> 16) -1) * 32); /* SG */ 1814 port = (minor(tp->t_dev) & 0x1f); /* SG */ 1815 mynor = (port + umynor); /* SG */ 1816 1817 unit = minor_to_unit[mynor]; 1818 rp = rp_addr(unit) + port; 1819 cp = &rp->rp_channel; 1820 oldspl = spltty(); 1821 1822 cflag = t->c_cflag; 1823 iflag = t->c_iflag; 1824 oflag = t->c_oflag; 1825 lflag = t->c_lflag; 1826 1827 ospeed = ttspeedtab(t->c_ispeed, baud_table); 1828 if(ospeed < 0 || t->c_ispeed != t->c_ospeed) 1829 return(EINVAL); 1830 1831 tp->t_ispeed = t->c_ispeed; 1832 tp->t_ospeed = t->c_ospeed; 1833 tp->t_cflag = cflag; 1834 tp->t_iflag = iflag; 1835 tp->t_oflag = oflag; 1836 tp->t_lflag = lflag; 1837 1838 if(t->c_ospeed == 0) { 1839 sClrDTR(cp); 1840 return(0); 1841 } 1842 rp->rp_fifo_lw = ((t->c_ospeed*2) / 1000) +1; 1843 1844 /* Set baud rate ----- we only pay attention to ispeed */ 1845 sSetDTR(cp); 1846 sSetRTS(cp); 1847 sSetBaud(cp, ospeed); 1848 1849 if(cflag & CSTOPB) { 1850 sSetStop2(cp); 1851 } else { 1852 sSetStop1(cp); 1853 } 1854 1855 if(cflag & PARENB) { 1856 sEnParity(cp); 1857 if(cflag & PARODD) { 1858 sSetOddParity(cp); 1859 } else { 1860 sSetEvenParity(cp); 1861 } 1862 } 1863 else { 1864 sDisParity(cp); 1865 } 1866 if((cflag & CSIZE) == CS8) { 1867 sSetData8(cp); 1868 rp->rp_imask = 0xFF; 1869 } else { 1870 sSetData7(cp); 1871 rp->rp_imask = 0x7F; 1872 } 1873 1874 if(iflag & ISTRIP) { 1875 rp->rp_imask &= 0x7F; 1876 } 1877 1878 if(cflag & CLOCAL) { 1879 rp->rp_intmask &= ~DELTA_CD; 1880 } else { 1881 rp->rp_intmask |= DELTA_CD; 1882 } 1883 1884 /* Put flow control stuff here */ 1885 1886 if(cflag & CCTS_OFLOW) { 1887 sEnCTSFlowCtl(cp); 1888 } else { 1889 sDisCTSFlowCtl(cp); 1890 } 1891 1892 if(cflag & CRTS_IFLOW) { 1893 rp->rp_rts_iflow = 1; 1894 } else { 1895 rp->rp_rts_iflow = 0; 1896 } 1897 1898 if(cflag & CRTS_IFLOW) { 1899 sEnRTSFlowCtl(cp); 1900 } else { 1901 sDisRTSFlowCtl(cp); 1902 } 1903 rp_disc_optim(tp, t, rp); 1904 1905 if((cflag & CLOCAL) || (sGetChanStatusLo(cp) & CD_ACT)) { 1906 tp->t_state |= TS_CARR_ON; 1907 wakeup(TSA_CARR_ON(tp)); 1908 } 1909 1910/* tp->t_state |= TS_CAN_BYPASS_L_RINT; 1911 flags = rp->rp_channel.TxControl[3]; 1912 if(flags & SET_DTR) 1913 else 1914 if(flags & SET_RTS) 1915 else 1916*/ 1917 splx(oldspl); 1918 1919 return(0); 1920} 1921 1922static void 1923rp_disc_optim(tp, t, rp) 1924struct tty *tp; 1925struct termios *t; 1926struct rp_port *rp; 1927{ 1928 if(!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON)) 1929 &&(!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK)) 1930 &&(!(t->c_iflag & PARMRK) 1931 ||(t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK)) 1932 && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN)) 1933 && linesw[tp->t_line].l_rint == ttyinput) 1934 tp->t_state |= TS_CAN_BYPASS_L_RINT; 1935 else 1936 tp->t_state &= ~TS_CAN_BYPASS_L_RINT; 1937} 1938 1939static void 1940rpstart(tp) 1941 struct tty *tp; 1942{ 1943 struct rp_port *rp; 1944 CHANNEL_t *cp; 1945 struct clist *qp; 1946 int unit, mynor, port, umynor; /* SG */ 1947 char ch, flags; 1948 int spl, xmit_fifo_room; 1949 int count; 1950 1951 1952 umynor = (((minor(tp->t_dev) >> 16) -1) * 32); /* SG */ 1953 port = (minor(tp->t_dev) & 0x1f); /* SG */ 1954 mynor = (port + umynor); /* SG */ 1955 unit = minor_to_unit[mynor]; 1956 rp = rp_addr(unit) + port; 1957 cp = &rp->rp_channel; 1958 flags = rp->rp_channel.TxControl[3]; 1959 spl = spltty(); 1960 1961 if(tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { 1962 ttwwakeup(tp); 1963 splx(spl); 1964 return; 1965 } 1966 if(rp->rp_xmit_stopped) { 1967 sEnTransmit(cp); 1968 rp->rp_xmit_stopped = 0; 1969 } 1970 count = sGetTxCnt(cp); 1971 1972 if(tp->t_outq.c_cc == 0) { 1973 if((tp->t_state & TS_BUSY) && (count == 0)) { 1974 tp->t_state &= ~TS_BUSY; 1975 } 1976 ttwwakeup(tp); 1977 splx(spl); 1978 return; 1979 } 1980 xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); 1981 qp = &tp->t_outq; 1982 count = 0; 1983 if(xmit_fifo_room > 0 && qp->c_cc > 0) { 1984 tp->t_state |= TS_BUSY; 1985 } 1986 while(xmit_fifo_room > 0 && qp->c_cc > 0) { 1987 ch = getc(qp); 1988 sOutB(sGetTxRxDataIO(cp), ch); 1989 xmit_fifo_room--; 1990 count++; 1991 } 1992 rp->rp_restart = (qp->c_cc > 0) ? rp->rp_fifo_lw : 0; 1993 1994 ttwwakeup(tp); 1995 splx(spl); 1996} 1997 1998static 1999void 2000rpstop(tp, flag) 2001 register struct tty *tp; 2002 int flag; 2003{ 2004 struct rp_port *rp; 2005 CHANNEL_t *cp; 2006 int unit, mynor, port, umynor; /* SG */ 2007 int spl; 2008 2009 umynor = (((minor(tp->t_dev) >> 16) -1) * 32); /* SG */ 2010 port = (minor(tp->t_dev) & 0x1f); /* SG */ 2011 mynor = (port + umynor); /* SG */ 2012 unit = minor_to_unit[mynor]; 2013 rp = rp_addr(unit) + port; 2014 cp = &rp->rp_channel; 2015 2016 spl = spltty(); 2017 2018 if(tp->t_state & TS_BUSY) { 2019 if((tp->t_state&TS_TTSTOP) == 0) { 2020 sFlushTxFIFO(cp); 2021 } else { 2022 if(rp->rp_xmit_stopped == 0) { 2023 sDisTransmit(cp); 2024 rp->rp_xmit_stopped = 1; 2025 } 2026 } 2027 } 2028 splx(spl); 2029 rpstart(tp); 2030} 2031 2032int 2033rpselect(dev, flag, p) 2034 dev_t dev; 2035 int flag; 2036 struct proc *p; 2037{ 2038 return(0); 2039} 2040 2041struct tty * 2042rpdevtotty(dev_t dev) 2043{ 2044 struct rp_port *rp; 2045 int unit, port, mynor, umynor; /* SG */ 2046 2047 umynor = (((minor(dev) >> 16) -1) * 32); /* SG */ 2048 port = (minor(dev) & 0x1f); /* SG */ 2049 mynor = (port + umynor); /* SG */ 2050 unit = minor_to_unit[mynor]; /* SG */ 2051 2052 if(IS_CONTROL(dev)) 2053 return(NULL); 2054 rp = rp_addr(unit) + port; 2055 return(rp->rp_tty); 2056}
|