1/******************************************************************************* 2* 3* (c) 1999 by Computone Corporation 4* 5******************************************************************************** 6* 7* 8* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport 9* serial I/O controllers. 10* 11* DESCRIPTION: High-level interface code for the device driver. Uses the 12* Extremely Low Level Interface Support (i2ellis.c). Provides an 13* interface to the standard loadware, to support drivers or 14* application code. (This is included source code, not a separate 15* compilation module.) 16* 17*******************************************************************************/ 18//------------------------------------------------------------------------------ 19// Note on Strategy: 20// Once the board has been initialized, it will interrupt us when: 21// 1) It has something in the fifo for us to read (incoming data, flow control 22// packets, or whatever). 23// 2) It has stripped whatever we have sent last time in the FIFO (and 24// consequently is ready for more). 25// 26// Note also that the buffer sizes declared in i2lib.h are VERY SMALL. This 27// worsens performance considerably, but is done so that a great many channels 28// might use only a little memory. 29//------------------------------------------------------------------------------ 30 31//------------------------------------------------------------------------------ 32// Revision History: 33// 34// 0.00 - 4/16/91 --- First Draft 35// 0.01 - 4/29/91 --- 1st beta release 36// 0.02 - 6/14/91 --- Changes to allow small model compilation 37// 0.03 - 6/17/91 MAG Break reporting protected from interrupts routines with 38// in-line asm added for moving data to/from ring buffers, 39// replacing a variety of methods used previously. 40// 0.04 - 6/21/91 MAG Initial flow-control packets not queued until 41// i2_enable_interrupts time. Former versions would enqueue 42// them at i2_init_channel time, before we knew how many 43// channels were supposed to exist! 44// 0.05 - 10/12/91 MAG Major changes: works through the ellis.c routines now; 45// supports new 16-bit protocol and expandable boards. 46// - 10/24/91 MAG Most changes in place and stable. 47// 0.06 - 2/20/92 MAG Format of CMD_HOTACK corrected: the command takes no 48// argument. 49// 0.07 -- 3/11/92 MAG Support added to store special packet types at interrupt 50// level (mostly responses to specific commands.) 51// 0.08 -- 3/30/92 MAG Support added for STAT_MODEM packet 52// 0.09 -- 6/24/93 MAG i2Link... needed to update number of boards BEFORE 53// turning on the interrupt. 54// 0.10 -- 6/25/93 MAG To avoid gruesome death from a bad board, we sanity check 55// some incoming. 56// 57// 1.1 - 12/25/96 AKM Linux version. 58// - 10/09/98 DMC Revised Linux version. 59//------------------------------------------------------------------------------ 60 61/ 62 63//******** 64//* Code * 65//******** 66 67static inline int 68i2Validate ( i2ChanStrPtr pCh ) 69{ 70 //ip2trace(pCh->port_index, ITRC_VERIFY,ITRC_ENTER,2,pCh->validity, 71 // (CHANNEL_MAGIC | CHANNEL_SUPPORT)); 72 return ((pCh->validity & (CHANNEL_MAGIC_BITS | CHANNEL_SUPPORT)) 73 == (CHANNEL_MAGIC | CHANNEL_SUPPORT)); 74} 75 76static void iiSendPendingMail_t(unsigned long data) 77{ 78 i2eBordStrPtr pB = (i2eBordStrPtr)data; 79 80 iiSendPendingMail(pB); 81} 82 83//****************************************************************************** 84// Function: iiSendPendingMail(pB) 85// Parameters: Pointer to a board structure 86// Returns: Nothing 87// 88// Description: 89// If any outgoing mail bits are set and there is outgoing mailbox is empty, 90// send the mail and clear the bits. 91//****************************************************************************** 92static void 93iiSendPendingMail(i2eBordStrPtr pB) 94{ 95 if (pB->i2eOutMailWaiting && (!pB->i2eWaitingForEmptyFifo) ) 96 { 97 if (iiTrySendMail(pB, pB->i2eOutMailWaiting)) 98 { 99 /* If we were already waiting for fifo to empty, 100 * or just sent MB_OUT_STUFFED, then we are 101 * still waiting for it to empty, until we should 102 * receive an MB_IN_STRIPPED from the board. 103 */ 104 pB->i2eWaitingForEmptyFifo |= 105 (pB->i2eOutMailWaiting & MB_OUT_STUFFED); 106 pB->i2eOutMailWaiting = 0; 107 pB->SendPendingRetry = 0; 108 } else { 109/* The only time we hit this area is when "iiTrySendMail" has 110 failed. That only occurs when the outbound mailbox is 111 still busy with the last message. We take a short breather 112 to let the board catch up with itself and then try again. 113 16 Retries is the limit - then we got a borked board. 114 /\/\|=mhw=|\/\/ */ 115 116 if( ++pB->SendPendingRetry < 16 ) { 117 setup_timer(&pB->SendPendingTimer, 118 iiSendPendingMail_t, (unsigned long)pB); 119 mod_timer(&pB->SendPendingTimer, jiffies + 1); 120 } else { 121 printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" ); 122 } 123 } 124 } 125} 126 127//****************************************************************************** 128// Function: i2InitChannels(pB, nChannels, pCh) 129// Parameters: Pointer to Ellis Board structure 130// Number of channels to initialize 131// Pointer to first element in an array of channel structures 132// Returns: Success or failure 133// 134// Description: 135// 136// This function patches pointers, back-pointers, and initializes all the 137// elements in the channel structure array. 138// 139// This should be run after the board structure is initialized, through having 140// loaded the standard loadware (otherwise it complains). 141// 142// In any case, it must be done before any serious work begins initializing the 143// irq's or sending commands... 144// 145//****************************************************************************** 146static int 147i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh) 148{ 149 int index, stuffIndex; 150 i2ChanStrPtr *ppCh; 151 152 if (pB->i2eValid != I2E_MAGIC) { 153 I2_COMPLETE(pB, I2EE_BADMAGIC); 154 } 155 if (pB->i2eState != II_STATE_STDLOADED) { 156 I2_COMPLETE(pB, I2EE_BADSTATE); 157 } 158 159 rwlock_init(&pB->read_fifo_spinlock); 160 rwlock_init(&pB->write_fifo_spinlock); 161 rwlock_init(&pB->Dbuf_spinlock); 162 rwlock_init(&pB->Bbuf_spinlock); 163 rwlock_init(&pB->Fbuf_spinlock); 164 165 // NO LOCK needed yet - this is init 166 167 pB->i2eChannelPtr = pCh; 168 pB->i2eChannelCnt = nChannels; 169 170 pB->i2Fbuf_strip = pB->i2Fbuf_stuff = 0; 171 pB->i2Dbuf_strip = pB->i2Dbuf_stuff = 0; 172 pB->i2Bbuf_strip = pB->i2Bbuf_stuff = 0; 173 174 pB->SendPendingRetry = 0; 175 176 memset ( pCh, 0, sizeof (i2ChanStr) * nChannels ); 177 178 for (index = stuffIndex = 0, ppCh = (i2ChanStrPtr *)(pB->i2Fbuf); 179 nChannels && index < ABS_MOST_PORTS; 180 index++) 181 { 182 if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) { 183 continue; 184 } 185 rwlock_init(&pCh->Ibuf_spinlock); 186 rwlock_init(&pCh->Obuf_spinlock); 187 rwlock_init(&pCh->Cbuf_spinlock); 188 rwlock_init(&pCh->Pbuf_spinlock); 189 // NO LOCK needed yet - this is init 190 // Set up validity flag according to support level 191 if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) { 192 pCh->validity = CHANNEL_MAGIC | CHANNEL_SUPPORT; 193 } else { 194 pCh->validity = CHANNEL_MAGIC; 195 } 196 pCh->pMyBord = pB; /* Back-pointer */ 197 198 // Prepare an outgoing flow-control packet to send as soon as the chance 199 // occurs. 200 if ( pCh->validity & CHANNEL_SUPPORT ) { 201 pCh->infl.hd.i2sChannel = index; 202 pCh->infl.hd.i2sCount = 5; 203 pCh->infl.hd.i2sType = PTYPE_BYPASS; 204 pCh->infl.fcmd = 37; 205 pCh->infl.asof = 0; 206 pCh->infl.room = IBUF_SIZE - 1; 207 208 pCh->whenSendFlow = (IBUF_SIZE/5)*4; // when 80% full 209 210 // The following is similar to calling i2QueueNeeds, except that this 211 // is done in longhand, since we are setting up initial conditions on 212 // many channels at once. 213 pCh->channelNeeds = NEED_FLOW; // Since starting from scratch 214 pCh->sinceLastFlow = 0; // No bytes received since last flow 215 // control packet was queued 216 stuffIndex++; 217 *ppCh++ = pCh; // List this channel as needing 218 // initial flow control packet sent 219 } 220 221 // Don't allow anything to be sent until the status packets come in from 222 // the board. 223 224 pCh->outfl.asof = 0; 225 pCh->outfl.room = 0; 226 227 // Initialize all the ring buffers 228 229 pCh->Ibuf_stuff = pCh->Ibuf_strip = 0; 230 pCh->Obuf_stuff = pCh->Obuf_strip = 0; 231 pCh->Cbuf_stuff = pCh->Cbuf_strip = 0; 232 233 memset( &pCh->icount, 0, sizeof (struct async_icount) ); 234 pCh->hotKeyIn = HOT_CLEAR; 235 pCh->channelOptions = 0; 236 pCh->bookMarks = 0; 237 init_waitqueue_head(&pCh->pBookmarkWait); 238 239 init_waitqueue_head(&pCh->open_wait); 240 init_waitqueue_head(&pCh->close_wait); 241 init_waitqueue_head(&pCh->delta_msr_wait); 242 243 // Set base and divisor so default custom rate is 9600 244 pCh->BaudBase = 921600; // MAX for ST654, changed after we get 245 pCh->BaudDivisor = 96; // the boxids (UART types) later 246 247 pCh->dataSetIn = 0; 248 pCh->dataSetOut = 0; 249 250 pCh->wopen = 0; 251 pCh->throttled = 0; 252 253 pCh->speed = CBR_9600; 254 255 pCh->flags = 0; 256 257 pCh->ClosingDelay = 5*HZ/10; 258 pCh->ClosingWaitTime = 30*HZ; 259 260 // Initialize task queue objects 261 INIT_WORK(&pCh->tqueue_input, do_input); 262 INIT_WORK(&pCh->tqueue_status, do_status); 263 264#ifdef IP2DEBUG_TRACE 265 pCh->trace = ip2trace; 266#endif 267 268 ++pCh; 269 --nChannels; 270 } 271 // No need to check for wrap here; this is initialization. 272 pB->i2Fbuf_stuff = stuffIndex; 273 I2_COMPLETE(pB, I2EE_GOOD); 274 275} 276 277//****************************************************************************** 278// Function: i2DeQueueNeeds(pB, type) 279// Parameters: Pointer to a board structure 280// type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW 281// Returns: 282// Pointer to a channel structure 283// 284// Description: Returns pointer struct of next channel that needs service of 285// the type specified. Otherwise returns a NULL reference. 286// 287//****************************************************************************** 288static i2ChanStrPtr 289i2DeQueueNeeds(i2eBordStrPtr pB, int type) 290{ 291 unsigned short queueIndex; 292 unsigned long flags; 293 294 i2ChanStrPtr pCh = NULL; 295 296 switch(type) { 297 298 case NEED_INLINE: 299 300 write_lock_irqsave(&pB->Dbuf_spinlock, flags); 301 if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip) 302 { 303 queueIndex = pB->i2Dbuf_strip; 304 pCh = pB->i2Dbuf[queueIndex]; 305 queueIndex++; 306 if (queueIndex >= CH_QUEUE_SIZE) { 307 queueIndex = 0; 308 } 309 pB->i2Dbuf_strip = queueIndex; 310 pCh->channelNeeds &= ~NEED_INLINE; 311 } 312 write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); 313 break; 314 315 case NEED_BYPASS: 316 317 write_lock_irqsave(&pB->Bbuf_spinlock, flags); 318 if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip) 319 { 320 queueIndex = pB->i2Bbuf_strip; 321 pCh = pB->i2Bbuf[queueIndex]; 322 queueIndex++; 323 if (queueIndex >= CH_QUEUE_SIZE) { 324 queueIndex = 0; 325 } 326 pB->i2Bbuf_strip = queueIndex; 327 pCh->channelNeeds &= ~NEED_BYPASS; 328 } 329 write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); 330 break; 331 332 case NEED_FLOW: 333 334 write_lock_irqsave(&pB->Fbuf_spinlock, flags); 335 if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip) 336 { 337 queueIndex = pB->i2Fbuf_strip; 338 pCh = pB->i2Fbuf[queueIndex]; 339 queueIndex++; 340 if (queueIndex >= CH_QUEUE_SIZE) { 341 queueIndex = 0; 342 } 343 pB->i2Fbuf_strip = queueIndex; 344 pCh->channelNeeds &= ~NEED_FLOW; 345 } 346 write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); 347 break; 348 default: 349 printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type); 350 break; 351 } 352 return pCh; 353} 354 355//****************************************************************************** 356// Function: i2QueueNeeds(pB, pCh, type) 357// Parameters: Pointer to a board structure 358// Pointer to a channel structure 359// type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW 360// Returns: Nothing 361// 362// Description: 363// For each type of need selected, if the given channel is not already in the 364// queue, adds it, and sets the flag indicating it is in the queue. 365//****************************************************************************** 366static void 367i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type) 368{ 369 unsigned short queueIndex; 370 unsigned long flags; 371 372 // We turn off all the interrupts during this brief process, since the 373 // interrupt-level code might want to put things on the queue as well. 374 375 switch (type) { 376 377 case NEED_INLINE: 378 379 write_lock_irqsave(&pB->Dbuf_spinlock, flags); 380 if ( !(pCh->channelNeeds & NEED_INLINE) ) 381 { 382 pCh->channelNeeds |= NEED_INLINE; 383 queueIndex = pB->i2Dbuf_stuff; 384 pB->i2Dbuf[queueIndex++] = pCh; 385 if (queueIndex >= CH_QUEUE_SIZE) 386 queueIndex = 0; 387 pB->i2Dbuf_stuff = queueIndex; 388 } 389 write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); 390 break; 391 392 case NEED_BYPASS: 393 394 write_lock_irqsave(&pB->Bbuf_spinlock, flags); 395 if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS)) 396 { 397 pCh->channelNeeds |= NEED_BYPASS; 398 queueIndex = pB->i2Bbuf_stuff; 399 pB->i2Bbuf[queueIndex++] = pCh; 400 if (queueIndex >= CH_QUEUE_SIZE) 401 queueIndex = 0; 402 pB->i2Bbuf_stuff = queueIndex; 403 } 404 write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); 405 break; 406 407 case NEED_FLOW: 408 409 write_lock_irqsave(&pB->Fbuf_spinlock, flags); 410 if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW)) 411 { 412 pCh->channelNeeds |= NEED_FLOW; 413 queueIndex = pB->i2Fbuf_stuff; 414 pB->i2Fbuf[queueIndex++] = pCh; 415 if (queueIndex >= CH_QUEUE_SIZE) 416 queueIndex = 0; 417 pB->i2Fbuf_stuff = queueIndex; 418 } 419 write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); 420 break; 421 422 case NEED_CREDIT: 423 pCh->channelNeeds |= NEED_CREDIT; 424 break; 425 default: 426 printk(KERN_ERR "i2QueueNeeds called with bad type:%x\n",type); 427 break; 428 } 429 return; 430} 431 432//****************************************************************************** 433// Function: i2QueueCommands(type, pCh, timeout, nCommands, pCs,...) 434// Parameters: type - PTYPE_BYPASS or PTYPE_INLINE 435// pointer to the channel structure 436// maximum period to wait 437// number of commands (n) 438// n commands 439// Returns: Number of commands sent, or -1 for error 440// 441// get board lock before calling 442// 443// Description: 444// Queues up some commands to be sent to a channel. To send possibly several 445// bypass or inline commands to the given channel. The timeout parameter 446// indicates how many HUNDREDTHS OF SECONDS to wait until there is room: 447// 0 = return immediately if no room, -ive = wait forever, +ive = number of 448// 1/100 seconds to wait. Return values: 449// -1 Some kind of nasty error: bad channel structure or invalid arguments. 450// 0 No room to send all the commands 451// (+) Number of commands sent 452//****************************************************************************** 453static int 454i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands, 455 cmdSyntaxPtr pCs0,...) 456{ 457 int totalsize = 0; 458 int blocksize; 459 int lastended; 460 cmdSyntaxPtr *ppCs; 461 cmdSyntaxPtr pCs; 462 int count; 463 int flag; 464 i2eBordStrPtr pB; 465 466 unsigned short maxBlock; 467 unsigned short maxBuff; 468 short bufroom; 469 unsigned short stuffIndex; 470 unsigned char *pBuf; 471 unsigned char *pInsert; 472 unsigned char *pDest, *pSource; 473 unsigned short channel; 474 int cnt; 475 unsigned long flags = 0; 476 rwlock_t *lock_var_p = NULL; 477 478 // Make sure the channel exists, otherwise do nothing 479 if ( !i2Validate ( pCh ) ) { 480 return -1; 481 } 482 483 ip2trace (CHANN, ITRC_QUEUE, ITRC_ENTER, 0 ); 484 485 pB = pCh->pMyBord; 486 487 // Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT 488 if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == I2_IRQ_UNDEFINED) 489 return -2; 490 // If the board has gone fatal, return bad, and also hit the trap routine if 491 // it exists. 492 if (pB->i2eFatal) { 493 if ( pB->i2eFatalTrap ) { 494 (*(pB)->i2eFatalTrap)(pB); 495 } 496 return -3; 497 } 498 // Set up some variables, Which buffers are we using? How big are they? 499 switch(type) 500 { 501 case PTYPE_INLINE: 502 flag = INL; 503 maxBlock = MAX_OBUF_BLOCK; 504 maxBuff = OBUF_SIZE; 505 pBuf = pCh->Obuf; 506 break; 507 case PTYPE_BYPASS: 508 flag = BYP; 509 maxBlock = MAX_CBUF_BLOCK; 510 maxBuff = CBUF_SIZE; 511 pBuf = pCh->Cbuf; 512 break; 513 default: 514 return -4; 515 } 516 // Determine the total size required for all the commands 517 totalsize = blocksize = sizeof(i2CmdHeader); 518 lastended = 0; 519 ppCs = &pCs0; 520 for ( count = nCommands; count; count--, ppCs++) 521 { 522 pCs = *ppCs; 523 cnt = pCs->length; 524 // Will a new block be needed for this one? 525 // Two possible reasons: too 526 // big or previous command has to be at the end of a packet. 527 if ((blocksize + cnt > maxBlock) || lastended) { 528 blocksize = sizeof(i2CmdHeader); 529 totalsize += sizeof(i2CmdHeader); 530 } 531 totalsize += cnt; 532 blocksize += cnt; 533 534 // If this command had to end a block, then we will make sure to 535 // account for it should there be any more blocks. 536 lastended = pCs->flags & END; 537 } 538 for (;;) { 539 // Make sure any pending flush commands go out before we add more data. 540 if ( !( pCh->flush_flags && i2RetryFlushOutput( pCh ) ) ) { 541 // How much room (this time through) ? 542 switch(type) { 543 case PTYPE_INLINE: 544 lock_var_p = &pCh->Obuf_spinlock; 545 write_lock_irqsave(lock_var_p, flags); 546 stuffIndex = pCh->Obuf_stuff; 547 bufroom = pCh->Obuf_strip - stuffIndex; 548 break; 549 case PTYPE_BYPASS: 550 lock_var_p = &pCh->Cbuf_spinlock; 551 write_lock_irqsave(lock_var_p, flags); 552 stuffIndex = pCh->Cbuf_stuff; 553 bufroom = pCh->Cbuf_strip - stuffIndex; 554 break; 555 default: 556 return -5; 557 } 558 if (--bufroom < 0) { 559 bufroom += maxBuff; 560 } 561 562 ip2trace (CHANN, ITRC_QUEUE, 2, 1, bufroom ); 563 564 // Check for overflow 565 if (totalsize <= bufroom) { 566 // Normal Expected path - We still hold LOCK 567 break; /* from for()- Enough room: goto proceed */ 568 } 569 ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); 570 write_unlock_irqrestore(lock_var_p, flags); 571 } else 572 ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); 573 574 /* Prepare to wait for buffers to empty */ 575 serviceOutgoingFifo(pB); // Dump what we got 576 577 if (timeout == 0) { 578 return 0; // Tired of waiting 579 } 580 if (timeout > 0) 581 timeout--; // So negative values == forever 582 583 if (!in_interrupt()) { 584 schedule_timeout_interruptible(1); // short nap 585 } else { 586 // we cannot sched/sleep in interrupt silly 587 return 0; 588 } 589 if (signal_pending(current)) { 590 return 0; // Wake up! Time to die!!! 591 } 592 593 ip2trace (CHANN, ITRC_QUEUE, 4, 0 ); 594 595 } // end of for(;;) 596 597 // At this point we have room and the lock - stick them in. 598 channel = pCh->infl.hd.i2sChannel; 599 pInsert = &pBuf[stuffIndex]; // Pointer to start of packet 600 pDest = CMD_OF(pInsert); // Pointer to start of command 601 602 // When we start counting, the block is the size of the header 603 for (blocksize = sizeof(i2CmdHeader), count = nCommands, 604 lastended = 0, ppCs = &pCs0; 605 count; 606 count--, ppCs++) 607 { 608 pCs = *ppCs; // Points to command protocol structure 609 610 // If this is a bookmark request command, post the fact that a bookmark 611 // request is pending. NOTE THIS TRICK ONLY WORKS BECAUSE CMD_BMARK_REQ 612 // has no parameters! The more general solution would be to reference 613 // pCs->cmd[0]. 614 if (pCs == CMD_BMARK_REQ) { 615 pCh->bookMarks++; 616 617 ip2trace (CHANN, ITRC_DRAIN, 30, 1, pCh->bookMarks ); 618 619 } 620 cnt = pCs->length; 621 622 // If this command would put us over the maximum block size or 623 // if the last command had to be at the end of a block, we end 624 // the existing block here and start a new one. 625 if ((blocksize + cnt > maxBlock) || lastended) { 626 627 ip2trace (CHANN, ITRC_QUEUE, 5, 0 ); 628 629 PTYPE_OF(pInsert) = type; 630 CHANNEL_OF(pInsert) = channel; 631 // count here does not include the header 632 CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader); 633 stuffIndex += blocksize; 634 if(stuffIndex >= maxBuff) { 635 stuffIndex = 0; 636 pInsert = pBuf; 637 } 638 pInsert = &pBuf[stuffIndex]; // Pointer to start of next pkt 639 pDest = CMD_OF(pInsert); 640 blocksize = sizeof(i2CmdHeader); 641 } 642 // Now we know there is room for this one in the current block 643 644 blocksize += cnt; // Total bytes in this command 645 pSource = pCs->cmd; // Copy the command into the buffer 646 while (cnt--) { 647 *pDest++ = *pSource++; 648 } 649 // If this command had to end a block, then we will make sure to account 650 // for it should there be any more blocks. 651 lastended = pCs->flags & END; 652 } // end for 653 // Clean up the final block by writing header, etc 654 655 PTYPE_OF(pInsert) = type; 656 CHANNEL_OF(pInsert) = channel; 657 // count here does not include the header 658 CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader); 659 stuffIndex += blocksize; 660 if(stuffIndex >= maxBuff) { 661 stuffIndex = 0; 662 pInsert = pBuf; 663 } 664 // Updates the index, and post the need for service. When adding these to 665 // the queue of channels, we turn off the interrupt while doing so, 666 // because at interrupt level we might want to push a channel back to the 667 // end of the queue. 668 switch(type) 669 { 670 case PTYPE_INLINE: 671 pCh->Obuf_stuff = stuffIndex; // Store buffer pointer 672 write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); 673 674 pB->debugInlineQueued++; 675 // Add the channel pointer to list of channels needing service (first 676 // come...), if it's not already there. 677 i2QueueNeeds(pB, pCh, NEED_INLINE); 678 break; 679 680 case PTYPE_BYPASS: 681 pCh->Cbuf_stuff = stuffIndex; // Store buffer pointer 682 write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); 683 684 pB->debugBypassQueued++; 685 // Add the channel pointer to list of channels needing service (first 686 // come...), if it's not already there. 687 i2QueueNeeds(pB, pCh, NEED_BYPASS); 688 break; 689 } 690 691 ip2trace (CHANN, ITRC_QUEUE, ITRC_RETURN, 1, nCommands ); 692 693 return nCommands; // Good status: number of commands sent 694} 695 696//****************************************************************************** 697// Function: i2GetStatus(pCh,resetBits) 698// Parameters: Pointer to a channel structure 699// Bit map of status bits to clear 700// Returns: Bit map of current status bits 701// 702// Description: 703// Returns the state of data set signals, and whether a break has been received, 704// (see i2lib.h for bit-mapped result). resetBits is a bit-map of any status 705// bits to be cleared: I2_BRK, I2_PAR, I2_FRA, I2_OVR,... These are cleared 706// AFTER the condition is passed. If pCh does not point to a valid channel, 707// returns -1 (which would be impossible otherwise. 708//****************************************************************************** 709static int 710i2GetStatus(i2ChanStrPtr pCh, int resetBits) 711{ 712 unsigned short status; 713 i2eBordStrPtr pB; 714 715 ip2trace (CHANN, ITRC_STATUS, ITRC_ENTER, 2, pCh->dataSetIn, resetBits ); 716 717 // Make sure the channel exists, otherwise do nothing */ 718 if ( !i2Validate ( pCh ) ) 719 return -1; 720 721 pB = pCh->pMyBord; 722 723 status = pCh->dataSetIn; 724 725 // Clear any specified error bits: but note that only actual error bits can 726 // be cleared, regardless of the value passed. 727 if (resetBits) 728 { 729 pCh->dataSetIn &= ~(resetBits & (I2_BRK | I2_PAR | I2_FRA | I2_OVR)); 730 pCh->dataSetIn &= ~(I2_DDCD | I2_DCTS | I2_DDSR | I2_DRI); 731 } 732 733 ip2trace (CHANN, ITRC_STATUS, ITRC_RETURN, 1, pCh->dataSetIn ); 734 735 return status; 736} 737 738//****************************************************************************** 739// Function: i2Input(pChpDest,count) 740// Parameters: Pointer to a channel structure 741// Pointer to data buffer 742// Number of bytes to read 743// Returns: Number of bytes read, or -1 for error 744// 745// Description: 746// Strips data from the input buffer and writes it to pDest. If there is a 747// collosal blunder, (invalid structure pointers or the like), returns -1. 748// Otherwise, returns the number of bytes read. 749//****************************************************************************** 750static int 751i2Input(i2ChanStrPtr pCh) 752{ 753 int amountToMove; 754 unsigned short stripIndex; 755 int count; 756 unsigned long flags = 0; 757 758 ip2trace (CHANN, ITRC_INPUT, ITRC_ENTER, 0); 759 760 // Ensure channel structure seems real 761 if ( !i2Validate( pCh ) ) { 762 count = -1; 763 goto i2Input_exit; 764 } 765 write_lock_irqsave(&pCh->Ibuf_spinlock, flags); 766 767 // initialize some accelerators and private copies 768 stripIndex = pCh->Ibuf_strip; 769 770 count = pCh->Ibuf_stuff - stripIndex; 771 772 // If buffer is empty or requested data count was 0, (trivial case) return 773 // without any further thought. 774 if ( count == 0 ) { 775 write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); 776 goto i2Input_exit; 777 } 778 // Adjust for buffer wrap 779 if ( count < 0 ) { 780 count += IBUF_SIZE; 781 } 782 // Don't give more than can be taken by the line discipline 783 amountToMove = pCh->pTTY->receive_room; 784 if (count > amountToMove) { 785 count = amountToMove; 786 } 787 // How much could we copy without a wrap? 788 amountToMove = IBUF_SIZE - stripIndex; 789 790 if (amountToMove > count) { 791 amountToMove = count; 792 } 793 // Move the first block 794 pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, 795 &(pCh->Ibuf[stripIndex]), NULL, amountToMove ); 796 // If we needed to wrap, do the second data move 797 if (count > amountToMove) { 798 pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, 799 pCh->Ibuf, NULL, count - amountToMove ); 800 } 801 // Bump and wrap the stripIndex all at once by the amount of data read. This 802 // method is good regardless of whether the data was in one or two pieces. 803 stripIndex += count; 804 if (stripIndex >= IBUF_SIZE) { 805 stripIndex -= IBUF_SIZE; 806 } 807 pCh->Ibuf_strip = stripIndex; 808 809 // Update our flow control information and possibly queue ourselves to send 810 // it, depending on how much data has been stripped since the last time a 811 // packet was sent. 812 pCh->infl.asof += count; 813 814 if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) { 815 pCh->sinceLastFlow -= pCh->whenSendFlow; 816 write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); 817 i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); 818 } else { 819 write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); 820 } 821 822i2Input_exit: 823 824 ip2trace (CHANN, ITRC_INPUT, ITRC_RETURN, 1, count); 825 826 return count; 827} 828 829//****************************************************************************** 830// Function: i2InputFlush(pCh) 831// Parameters: Pointer to a channel structure 832// Returns: Number of bytes stripped, or -1 for error 833// 834// Description: 835// Strips any data from the input buffer. If there is a collosal blunder, 836// (invalid structure pointers or the like), returns -1. Otherwise, returns the 837// number of bytes stripped. 838//****************************************************************************** 839static int 840i2InputFlush(i2ChanStrPtr pCh) 841{ 842 int count; 843 unsigned long flags; 844 845 // Ensure channel structure seems real 846 if ( !i2Validate ( pCh ) ) 847 return -1; 848 849 ip2trace (CHANN, ITRC_INPUT, 10, 0); 850 851 write_lock_irqsave(&pCh->Ibuf_spinlock, flags); 852 count = pCh->Ibuf_stuff - pCh->Ibuf_strip; 853 854 // Adjust for buffer wrap 855 if (count < 0) { 856 count += IBUF_SIZE; 857 } 858 859 // Expedient way to zero out the buffer 860 pCh->Ibuf_strip = pCh->Ibuf_stuff; 861 862 863 // Update our flow control information and possibly queue ourselves to send 864 // it, depending on how much data has been stripped since the last time a 865 // packet was sent. 866 867 pCh->infl.asof += count; 868 869 if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow ) 870 { 871 pCh->sinceLastFlow -= pCh->whenSendFlow; 872 write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); 873 i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); 874 } else { 875 write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); 876 } 877 878 ip2trace (CHANN, ITRC_INPUT, 19, 1, count); 879 880 return count; 881} 882 883//****************************************************************************** 884// Function: i2InputAvailable(pCh) 885// Parameters: Pointer to a channel structure 886// Returns: Number of bytes available, or -1 for error 887// 888// Description: 889// If there is a collosal blunder, (invalid structure pointers or the like), 890// returns -1. Otherwise, returns the number of bytes stripped. Otherwise, 891// returns the number of bytes available in the buffer. 892//****************************************************************************** 893 894//****************************************************************************** 895// Function: i2Output(pCh, pSource, count) 896// Parameters: Pointer to channel structure 897// Pointer to source data 898// Number of bytes to send 899// Returns: Number of bytes sent, or -1 for error 900// 901// Description: 902// Queues the data at pSource to be sent as data packets to the board. If there 903// is a collosal blunder, (invalid structure pointers or the like), returns -1. 904// Otherwise, returns the number of bytes written. What if there is not enough 905// room for all the data? If pCh->channelOptions & CO_NBLOCK_WRITE is set, then 906// we transfer as many characters as we can now, then return. If this bit is 907// clear (default), routine will spin along until all the data is buffered. 908// Should this occur, the 1-ms delay routine is called while waiting to avoid 909// applications that one cannot break out of. 910//****************************************************************************** 911static int 912i2Output(i2ChanStrPtr pCh, const char *pSource, int count) 913{ 914 i2eBordStrPtr pB; 915 unsigned char *pInsert; 916 int amountToMove; 917 int countOriginal = count; 918 unsigned short channel; 919 unsigned short stuffIndex; 920 unsigned long flags; 921 922 int bailout = 10; 923 924 ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, 0 ); 925 926 // Ensure channel structure seems real 927 if ( !i2Validate ( pCh ) ) 928 return -1; 929 930 // initialize some accelerators and private copies 931 pB = pCh->pMyBord; 932 channel = pCh->infl.hd.i2sChannel; 933 934 // If the board has gone fatal, return bad, and also hit the trap routine if 935 // it exists. 936 if (pB->i2eFatal) { 937 if (pB->i2eFatalTrap) { 938 (*(pB)->i2eFatalTrap)(pB); 939 } 940 return -1; 941 } 942 // Proceed as though we would do everything 943 while ( count > 0 ) { 944 945 // How much room in output buffer is there? 946 read_lock_irqsave(&pCh->Obuf_spinlock, flags); 947 amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; 948 read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); 949 if (amountToMove < 0) { 950 amountToMove += OBUF_SIZE; 951 } 952 // Subtract off the headers size and see how much room there is for real 953 // data. If this is negative, we will discover later. 954 amountToMove -= sizeof (i2DataHeader); 955 956 // Don't move more (now) than can go in a single packet 957 if ( amountToMove > (int)(MAX_OBUF_BLOCK - sizeof(i2DataHeader)) ) { 958 amountToMove = MAX_OBUF_BLOCK - sizeof(i2DataHeader); 959 } 960 // Don't move more than the count we were given 961 if (amountToMove > count) { 962 amountToMove = count; 963 } 964 // Now we know how much we must move: NB because the ring buffers have 965 // an overflow area at the end, we needn't worry about wrapping in the 966 // middle of a packet. 967 968// Small WINDOW here with no LOCK but I can't call Flush with LOCK 969// We would be flushing (or ending flush) anyway 970 971 ip2trace (CHANN, ITRC_OUTPUT, 10, 1, amountToMove ); 972 973 if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) ) 974 && amountToMove > 0 ) 975 { 976 write_lock_irqsave(&pCh->Obuf_spinlock, flags); 977 stuffIndex = pCh->Obuf_stuff; 978 979 // Had room to move some data: don't know whether the block size, 980 // buffer space, or what was the limiting factor... 981 pInsert = &(pCh->Obuf[stuffIndex]); 982 983 // Set up the header 984 CHANNEL_OF(pInsert) = channel; 985 PTYPE_OF(pInsert) = PTYPE_DATA; 986 TAG_OF(pInsert) = 0; 987 ID_OF(pInsert) = ID_ORDINARY_DATA; 988 DATA_COUNT_OF(pInsert) = amountToMove; 989 990 // Move the data 991 memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove ); 992 // Adjust pointers and indices 993 pSource += amountToMove; 994 pCh->Obuf_char_count += amountToMove; 995 stuffIndex += amountToMove + sizeof(i2DataHeader); 996 count -= amountToMove; 997 998 if (stuffIndex >= OBUF_SIZE) { 999 stuffIndex = 0; 1000 } 1001 pCh->Obuf_stuff = stuffIndex; 1002 1003 write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); 1004 1005 ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex ); 1006 1007 } else { 1008 1009 // Cannot move data 1010 // becuz we need to stuff a flush 1011 // or amount to move is <= 0 1012 1013 ip2trace(CHANN, ITRC_OUTPUT, 14, 3, 1014 amountToMove, pB->i2eFifoRemains, 1015 pB->i2eWaitingForEmptyFifo ); 1016 1017 // Put this channel back on queue 1018 // this ultimatly gets more data or wakes write output 1019 i2QueueNeeds(pB, pCh, NEED_INLINE); 1020 1021 if ( pB->i2eWaitingForEmptyFifo ) { 1022 1023 ip2trace (CHANN, ITRC_OUTPUT, 16, 0 ); 1024 1025 // or schedule 1026 if (!in_interrupt()) { 1027 1028 ip2trace (CHANN, ITRC_OUTPUT, 61, 0 ); 1029 1030 schedule_timeout_interruptible(2); 1031 if (signal_pending(current)) { 1032 break; 1033 } 1034 continue; 1035 } else { 1036 1037 ip2trace (CHANN, ITRC_OUTPUT, 62, 0 ); 1038 1039 // let interrupt in = WAS restore_flags() 1040 // We hold no lock nor is irq off anymore??? 1041 1042 break; 1043 } 1044 break; // from while(count) 1045 } 1046 else if ( pB->i2eFifoRemains < 32 && !pB->i2eTxMailEmpty ( pB ) ) 1047 { 1048 ip2trace (CHANN, ITRC_OUTPUT, 19, 2, 1049 pB->i2eFifoRemains, 1050 pB->i2eTxMailEmpty ); 1051 1052 break; // from while(count) 1053 } else if ( pCh->channelNeeds & NEED_CREDIT ) { 1054 1055 ip2trace (CHANN, ITRC_OUTPUT, 22, 0 ); 1056 1057 break; // from while(count) 1058 } else if ( --bailout) { 1059 1060 // Try to throw more things (maybe not us) in the fifo if we're 1061 // not already waiting for it. 1062 1063 ip2trace (CHANN, ITRC_OUTPUT, 20, 0 ); 1064 1065 serviceOutgoingFifo(pB); 1066 //break; CONTINUE; 1067 } else { 1068 ip2trace (CHANN, ITRC_OUTPUT, 21, 3, 1069 pB->i2eFifoRemains, 1070 pB->i2eOutMailWaiting, 1071 pB->i2eWaitingForEmptyFifo ); 1072 1073 break; // from while(count) 1074 } 1075 } 1076 } // End of while(count) 1077 1078 i2QueueNeeds(pB, pCh, NEED_INLINE); 1079 1080 // We drop through either when the count expires, or when there is some 1081 // count left, but there was a non-blocking write. 1082 if (countOriginal > count) { 1083 1084 ip2trace (CHANN, ITRC_OUTPUT, 17, 2, countOriginal, count ); 1085 1086 serviceOutgoingFifo( pB ); 1087 } 1088 1089 ip2trace (CHANN, ITRC_OUTPUT, ITRC_RETURN, 2, countOriginal, count ); 1090 1091 return countOriginal - count; 1092} 1093 1094//****************************************************************************** 1095// Function: i2FlushOutput(pCh) 1096// Parameters: Pointer to a channel structure 1097// Returns: Nothing 1098// 1099// Description: 1100// Sends bypass command to start flushing (waiting possibly forever until there 1101// is room), then sends inline command to stop flushing output, (again waiting 1102// possibly forever). 1103//****************************************************************************** 1104static inline void 1105i2FlushOutput(i2ChanStrPtr pCh) 1106{ 1107 1108 ip2trace (CHANN, ITRC_FLUSH, 1, 1, pCh->flush_flags ); 1109 1110 if (pCh->flush_flags) 1111 return; 1112 1113 if ( 1 != i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) { 1114 pCh->flush_flags = STARTFL_FLAG; // Failed - flag for later 1115 1116 ip2trace (CHANN, ITRC_FLUSH, 2, 0 ); 1117 1118 } else if ( 1 != i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL) ) { 1119 pCh->flush_flags = STOPFL_FLAG; // Failed - flag for later 1120 1121 ip2trace (CHANN, ITRC_FLUSH, 3, 0 ); 1122 } 1123} 1124 1125static int 1126i2RetryFlushOutput(i2ChanStrPtr pCh) 1127{ 1128 int old_flags = pCh->flush_flags; 1129 1130 ip2trace (CHANN, ITRC_FLUSH, 14, 1, old_flags ); 1131 1132 pCh->flush_flags = 0; // Clear flag so we can avoid recursion 1133 // and queue the commands 1134 1135 if ( old_flags & STARTFL_FLAG ) { 1136 if ( 1 == i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) { 1137 old_flags = STOPFL_FLAG; //Success - send stop flush 1138 } else { 1139 old_flags = STARTFL_FLAG; //Failure - Flag for retry later 1140 } 1141 1142 ip2trace (CHANN, ITRC_FLUSH, 15, 1, old_flags ); 1143 1144 } 1145 if ( old_flags & STOPFL_FLAG ) { 1146 if (1 == i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL)) { 1147 old_flags = 0; // Success - clear flags 1148 } 1149 1150 ip2trace (CHANN, ITRC_FLUSH, 16, 1, old_flags ); 1151 } 1152 pCh->flush_flags = old_flags; 1153 1154 ip2trace (CHANN, ITRC_FLUSH, 17, 1, old_flags ); 1155 1156 return old_flags; 1157} 1158 1159//****************************************************************************** 1160// Function: i2DrainOutput(pCh,timeout) 1161// Parameters: Pointer to a channel structure 1162// Maximum period to wait 1163// Returns: ? 1164// 1165// Description: 1166// Uses the bookmark request command to ask the board to send a bookmark back as 1167// soon as all the data is completely sent. 1168//****************************************************************************** 1169static void 1170i2DrainWakeup(unsigned long d) 1171{ 1172 i2ChanStrPtr pCh = (i2ChanStrPtr)d; 1173 1174 ip2trace (CHANN, ITRC_DRAIN, 10, 1, pCh->BookmarkTimer.expires ); 1175 1176 pCh->BookmarkTimer.expires = 0; 1177 wake_up_interruptible( &pCh->pBookmarkWait ); 1178} 1179 1180static void 1181i2DrainOutput(i2ChanStrPtr pCh, int timeout) 1182{ 1183 wait_queue_t wait; 1184 i2eBordStrPtr pB; 1185 1186 ip2trace (CHANN, ITRC_DRAIN, ITRC_ENTER, 1, pCh->BookmarkTimer.expires); 1187 1188 pB = pCh->pMyBord; 1189 // If the board has gone fatal, return bad, 1190 // and also hit the trap routine if it exists. 1191 if (pB->i2eFatal) { 1192 if (pB->i2eFatalTrap) { 1193 (*(pB)->i2eFatalTrap)(pB); 1194 } 1195 return; 1196 } 1197 if ((timeout > 0) && (pCh->BookmarkTimer.expires == 0 )) { 1198 // One per customer (channel) 1199 setup_timer(&pCh->BookmarkTimer, i2DrainWakeup, 1200 (unsigned long)pCh); 1201 1202 ip2trace (CHANN, ITRC_DRAIN, 1, 1, pCh->BookmarkTimer.expires ); 1203 1204 mod_timer(&pCh->BookmarkTimer, jiffies + timeout); 1205 } 1206 1207 i2QueueCommands( PTYPE_INLINE, pCh, -1, 1, CMD_BMARK_REQ ); 1208 1209 init_waitqueue_entry(&wait, current); 1210 add_wait_queue(&(pCh->pBookmarkWait), &wait); 1211 set_current_state( TASK_INTERRUPTIBLE ); 1212 1213 serviceOutgoingFifo( pB ); 1214 1215 schedule(); // Now we take our interruptible sleep on 1216 1217 // Clean up the queue 1218 set_current_state( TASK_RUNNING ); 1219 remove_wait_queue(&(pCh->pBookmarkWait), &wait); 1220 1221 // if expires == 0 then timer poped, then do not need to del_timer 1222 if ((timeout > 0) && pCh->BookmarkTimer.expires && 1223 time_before(jiffies, pCh->BookmarkTimer.expires)) { 1224 del_timer( &(pCh->BookmarkTimer) ); 1225 pCh->BookmarkTimer.expires = 0; 1226 1227 ip2trace (CHANN, ITRC_DRAIN, 3, 1, pCh->BookmarkTimer.expires ); 1228 1229 } 1230 ip2trace (CHANN, ITRC_DRAIN, ITRC_RETURN, 1, pCh->BookmarkTimer.expires ); 1231 return; 1232} 1233 1234//****************************************************************************** 1235// Function: i2OutputFree(pCh) 1236// Parameters: Pointer to a channel structure 1237// Returns: Space in output buffer 1238// 1239// Description: 1240// Returns -1 if very gross error. Otherwise returns the amount of bytes still 1241// free in the output buffer. 1242//****************************************************************************** 1243static int 1244i2OutputFree(i2ChanStrPtr pCh) 1245{ 1246 int amountToMove; 1247 unsigned long flags; 1248 1249 // Ensure channel structure seems real 1250 if ( !i2Validate ( pCh ) ) { 1251 return -1; 1252 } 1253 read_lock_irqsave(&pCh->Obuf_spinlock, flags); 1254 amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; 1255 read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); 1256 1257 if (amountToMove < 0) { 1258 amountToMove += OBUF_SIZE; 1259 } 1260 // If this is negative, we will discover later 1261 amountToMove -= sizeof(i2DataHeader); 1262 1263 return (amountToMove < 0) ? 0 : amountToMove; 1264} 1265static void 1266 1267ip2_owake( PTTY tp) 1268{ 1269 i2ChanStrPtr pCh; 1270 1271 if (tp == NULL) return; 1272 1273 pCh = tp->driver_data; 1274 1275 ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags, 1276 (1 << TTY_DO_WRITE_WAKEUP) ); 1277 1278 tty_wakeup(tp); 1279} 1280 1281static inline void 1282set_baud_params(i2eBordStrPtr pB) 1283{ 1284 int i,j; 1285 i2ChanStrPtr *pCh; 1286 1287 pCh = (i2ChanStrPtr *) pB->i2eChannelPtr; 1288 1289 for (i = 0; i < ABS_MAX_BOXES; i++) { 1290 if (pB->channelBtypes.bid_value[i]) { 1291 if (BID_HAS_654(pB->channelBtypes.bid_value[i])) { 1292 for (j = 0; j < ABS_BIGGEST_BOX; j++) { 1293 if (pCh[i*16+j] == NULL) 1294 break; 1295 (pCh[i*16+j])->BaudBase = 921600; // MAX for ST654 1296 (pCh[i*16+j])->BaudDivisor = 96; 1297 } 1298 } else { // has cirrus cd1400 1299 for (j = 0; j < ABS_BIGGEST_BOX; j++) { 1300 if (pCh[i*16+j] == NULL) 1301 break; 1302 (pCh[i*16+j])->BaudBase = 115200; // MAX for CD1400 1303 (pCh[i*16+j])->BaudDivisor = 12; 1304 } 1305 } 1306 } 1307 } 1308} 1309 1310//****************************************************************************** 1311// Function: i2StripFifo(pB) 1312// Parameters: Pointer to a board structure 1313// Returns: ? 1314// 1315// Description: 1316// Strips all the available data from the incoming FIFO, identifies the type of 1317// packet, and either buffers the data or does what needs to be done. 1318// 1319// Note there is no overflow checking here: if the board sends more data than it 1320// ought to, we will not detect it here, but blindly overflow... 1321//****************************************************************************** 1322 1323// A buffer for reading in blocks for unknown channels 1324static unsigned char junkBuffer[IBUF_SIZE]; 1325 1326// A buffer to read in a status packet. Because of the size of the count field 1327// for these things, the maximum packet size must be less than MAX_CMD_PACK_SIZE 1328static unsigned char cmdBuffer[MAX_CMD_PACK_SIZE + 4]; 1329 1330// This table changes the bit order from MSR order given by STAT_MODEM packet to 1331// status bits used in our library. 1332static char xlatDss[16] = { 13330 | 0 | 0 | 0 , 13340 | 0 | 0 | I2_CTS , 13350 | 0 | I2_DSR | 0 , 13360 | 0 | I2_DSR | I2_CTS , 13370 | I2_RI | 0 | 0 , 13380 | I2_RI | 0 | I2_CTS , 13390 | I2_RI | I2_DSR | 0 , 13400 | I2_RI | I2_DSR | I2_CTS , 1341I2_DCD | 0 | 0 | 0 , 1342I2_DCD | 0 | 0 | I2_CTS , 1343I2_DCD | 0 | I2_DSR | 0 , 1344I2_DCD | 0 | I2_DSR | I2_CTS , 1345I2_DCD | I2_RI | 0 | 0 , 1346I2_DCD | I2_RI | 0 | I2_CTS , 1347I2_DCD | I2_RI | I2_DSR | 0 , 1348I2_DCD | I2_RI | I2_DSR | I2_CTS }; 1349 1350static inline void 1351i2StripFifo(i2eBordStrPtr pB) 1352{ 1353 i2ChanStrPtr pCh; 1354 int channel; 1355 int count; 1356 unsigned short stuffIndex; 1357 int amountToRead; 1358 unsigned char *pc, *pcLimit; 1359 unsigned char uc; 1360 unsigned char dss_change; 1361 unsigned long bflags,cflags; 1362 1363// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 ); 1364 1365 while (I2_HAS_INPUT(pB)) { 1366// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 ); 1367 1368 // Process packet from fifo a one atomic unit 1369 write_lock_irqsave(&pB->read_fifo_spinlock, bflags); 1370 1371 // The first word (or two bytes) will have channel number and type of 1372 // packet, possibly other information 1373 pB->i2eLeadoffWord[0] = iiReadWord(pB); 1374 1375 switch(PTYPE_OF(pB->i2eLeadoffWord)) 1376 { 1377 case PTYPE_DATA: 1378 pB->got_input = 1; 1379 1380// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 3, 0 ); 1381 1382 channel = CHANNEL_OF(pB->i2eLeadoffWord); /* Store channel */ 1383 count = iiReadWord(pB); /* Count is in the next word */ 1384 1385// NEW: Check the count for sanity! Should the hardware fail, our death 1386// is more pleasant. While an oversize channel is acceptable (just more 1387// than the driver supports), an over-length count clearly means we are 1388// sick! 1389 if ( ((unsigned int)count) > IBUF_SIZE ) { 1390 pB->i2eFatal = 2; 1391 write_unlock_irqrestore(&pB->read_fifo_spinlock, 1392 bflags); 1393 return; /* Bail out ASAP */ 1394 } 1395 // Channel is illegally big ? 1396 if ((channel >= pB->i2eChannelCnt) || 1397 (NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel]))) 1398 { 1399 iiReadBuf(pB, junkBuffer, count); 1400 write_unlock_irqrestore(&pB->read_fifo_spinlock, 1401 bflags); 1402 break; /* From switch: ready for next packet */ 1403 } 1404 1405 // Channel should be valid, then 1406 1407 // If this is a hot-key, merely post its receipt for now. These are 1408 // always supposed to be 1-byte packets, so we won't even check the 1409 // count. Also we will post an acknowledgement to the board so that 1410 // more data can be forthcoming. Note that we are not trying to use 1411 // these sequences in this driver, merely to robustly ignore them. 1412 if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY) 1413 { 1414 pCh->hotKeyIn = iiReadWord(pB) & 0xff; 1415 write_unlock_irqrestore(&pB->read_fifo_spinlock, 1416 bflags); 1417 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK); 1418 break; /* From the switch: ready for next packet */ 1419 } 1420 1421 // Normal data! We crudely assume there is room for the data in our 1422 // buffer because the board wouldn't have exceeded his credit limit. 1423 write_lock_irqsave(&pCh->Ibuf_spinlock, cflags); 1424 // We have 2 locks now 1425 stuffIndex = pCh->Ibuf_stuff; 1426 amountToRead = IBUF_SIZE - stuffIndex; 1427 if (amountToRead > count) 1428 amountToRead = count; 1429 1430 // stuffIndex would have been already adjusted so there would 1431 // always be room for at least one, and count is always at least 1432 // one. 1433 1434 iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead); 1435 pCh->icount.rx += amountToRead; 1436 1437 // Update the stuffIndex by the amount of data moved. Note we could 1438 // never ask for more data than would just fit. However, we might 1439 // have read in one more byte than we wanted because the read 1440 // rounds up to even bytes. If this byte is on the end of the 1441 // packet, and is padding, we ignore it. If the byte is part of 1442 // the actual data, we need to move it. 1443 1444 stuffIndex += amountToRead; 1445 1446 if (stuffIndex >= IBUF_SIZE) { 1447 if ((amountToRead & 1) && (count > amountToRead)) { 1448 pCh->Ibuf[0] = pCh->Ibuf[IBUF_SIZE]; 1449 amountToRead++; 1450 stuffIndex = 1; 1451 } else { 1452 stuffIndex = 0; 1453 } 1454 } 1455 1456 // If there is anything left over, read it as well 1457 if (count > amountToRead) { 1458 amountToRead = count - amountToRead; 1459 iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead); 1460 pCh->icount.rx += amountToRead; 1461 stuffIndex += amountToRead; 1462 } 1463 1464 // Update stuff index 1465 pCh->Ibuf_stuff = stuffIndex; 1466 write_unlock_irqrestore(&pCh->Ibuf_spinlock, cflags); 1467 write_unlock_irqrestore(&pB->read_fifo_spinlock, 1468 bflags); 1469 1470#ifdef USE_IQ 1471 schedule_work(&pCh->tqueue_input); 1472#else 1473 do_input(&pCh->tqueue_input); 1474#endif 1475 1476 // Note we do not need to maintain any flow-control credits at this 1477 // time: if we were to increment .asof and decrement .room, there 1478 // would be no net effect. Instead, when we strip data, we will 1479 // increment .asof and leave .room unchanged. 1480 1481 break; // From switch: ready for next packet 1482 1483 case PTYPE_STATUS: 1484 ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 4, 0 ); 1485 1486 count = CMD_COUNT_OF(pB->i2eLeadoffWord); 1487 1488 iiReadBuf(pB, cmdBuffer, count); 1489 // We can release early with buffer grab 1490 write_unlock_irqrestore(&pB->read_fifo_spinlock, 1491 bflags); 1492 1493 pc = cmdBuffer; 1494 pcLimit = &(cmdBuffer[count]); 1495 1496 while (pc < pcLimit) { 1497 channel = *pc++; 1498 1499 ip2trace (channel, ITRC_SFIFO, 7, 2, channel, *pc ); 1500 1501 /* check for valid channel */ 1502 if (channel < pB->i2eChannelCnt 1503 && 1504 (pCh = (((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])) != NULL 1505 ) 1506 { 1507 dss_change = 0; 1508 1509 switch (uc = *pc++) 1510 { 1511 /* Breaks and modem signals are easy: just update status */ 1512 case STAT_CTS_UP: 1513 if ( !(pCh->dataSetIn & I2_CTS) ) 1514 { 1515 pCh->dataSetIn |= I2_DCTS; 1516 pCh->icount.cts++; 1517 dss_change = 1; 1518 } 1519 pCh->dataSetIn |= I2_CTS; 1520 break; 1521 1522 case STAT_CTS_DN: 1523 if ( pCh->dataSetIn & I2_CTS ) 1524 { 1525 pCh->dataSetIn |= I2_DCTS; 1526 pCh->icount.cts++; 1527 dss_change = 1; 1528 } 1529 pCh->dataSetIn &= ~I2_CTS; 1530 break; 1531 1532 case STAT_DCD_UP: 1533 ip2trace (channel, ITRC_MODEM, 1, 1, pCh->dataSetIn ); 1534 1535 if ( !(pCh->dataSetIn & I2_DCD) ) 1536 { 1537 ip2trace (CHANN, ITRC_MODEM, 2, 0 ); 1538 pCh->dataSetIn |= I2_DDCD; 1539 pCh->icount.dcd++; 1540 dss_change = 1; 1541 } 1542 pCh->dataSetIn |= I2_DCD; 1543 1544 ip2trace (channel, ITRC_MODEM, 3, 1, pCh->dataSetIn ); 1545 break; 1546 1547 case STAT_DCD_DN: 1548 ip2trace (channel, ITRC_MODEM, 4, 1, pCh->dataSetIn ); 1549 if ( pCh->dataSetIn & I2_DCD ) 1550 { 1551 ip2trace (channel, ITRC_MODEM, 5, 0 ); 1552 pCh->dataSetIn |= I2_DDCD; 1553 pCh->icount.dcd++; 1554 dss_change = 1; 1555 } 1556 pCh->dataSetIn &= ~I2_DCD; 1557 1558 ip2trace (channel, ITRC_MODEM, 6, 1, pCh->dataSetIn ); 1559 break; 1560 1561 case STAT_DSR_UP: 1562 if ( !(pCh->dataSetIn & I2_DSR) ) 1563 { 1564 pCh->dataSetIn |= I2_DDSR; 1565 pCh->icount.dsr++; 1566 dss_change = 1; 1567 } 1568 pCh->dataSetIn |= I2_DSR; 1569 break; 1570 1571 case STAT_DSR_DN: 1572 if ( pCh->dataSetIn & I2_DSR ) 1573 { 1574 pCh->dataSetIn |= I2_DDSR; 1575 pCh->icount.dsr++; 1576 dss_change = 1; 1577 } 1578 pCh->dataSetIn &= ~I2_DSR; 1579 break; 1580 1581 case STAT_RI_UP: 1582 if ( !(pCh->dataSetIn & I2_RI) ) 1583 { 1584 pCh->dataSetIn |= I2_DRI; 1585 pCh->icount.rng++; 1586 dss_change = 1; 1587 } 1588 pCh->dataSetIn |= I2_RI ; 1589 break; 1590 1591 case STAT_RI_DN: 1592 // to be compat with serial.c 1593 //if ( pCh->dataSetIn & I2_RI ) 1594 //{ 1595 // pCh->dataSetIn |= I2_DRI; 1596 // pCh->icount.rng++; 1597 // dss_change = 1; 1598 //} 1599 pCh->dataSetIn &= ~I2_RI ; 1600 break; 1601 1602 case STAT_BRK_DET: 1603 pCh->dataSetIn |= I2_BRK; 1604 pCh->icount.brk++; 1605 dss_change = 1; 1606 break; 1607 1608 // Bookmarks? one less request we're waiting for 1609 case STAT_BMARK: 1610 pCh->bookMarks--; 1611 if (pCh->bookMarks <= 0 ) { 1612 pCh->bookMarks = 0; 1613 wake_up_interruptible( &pCh->pBookmarkWait ); 1614 1615 ip2trace (channel, ITRC_DRAIN, 20, 1, pCh->BookmarkTimer.expires ); 1616 } 1617 break; 1618 1619 // Flow control packets? Update the new credits, and if 1620 // someone was waiting for output, queue him up again. 1621 case STAT_FLOW: 1622 pCh->outfl.room = 1623 ((flowStatPtr)pc)->room - 1624 (pCh->outfl.asof - ((flowStatPtr)pc)->asof); 1625 1626 ip2trace (channel, ITRC_STFLW, 1, 1, pCh->outfl.room ); 1627 1628 if (pCh->channelNeeds & NEED_CREDIT) 1629 { 1630 ip2trace (channel, ITRC_STFLW, 2, 1, pCh->channelNeeds); 1631 1632 pCh->channelNeeds &= ~NEED_CREDIT; 1633 i2QueueNeeds(pB, pCh, NEED_INLINE); 1634 if ( pCh->pTTY ) 1635 ip2_owake(pCh->pTTY); 1636 } 1637 1638 ip2trace (channel, ITRC_STFLW, 3, 1, pCh->channelNeeds); 1639 1640 pc += sizeof(flowStat); 1641 break; 1642 1643 /* Special packets: */ 1644 /* Just copy the information into the channel structure */ 1645 1646 case STAT_STATUS: 1647 1648 pCh->channelStatus = *((debugStatPtr)pc); 1649 pc += sizeof(debugStat); 1650 break; 1651 1652 case STAT_TXCNT: 1653 1654 pCh->channelTcount = *((cntStatPtr)pc); 1655 pc += sizeof(cntStat); 1656 break; 1657 1658 case STAT_RXCNT: 1659 1660 pCh->channelRcount = *((cntStatPtr)pc); 1661 pc += sizeof(cntStat); 1662 break; 1663 1664 case STAT_BOXIDS: 1665 pB->channelBtypes = *((bidStatPtr)pc); 1666 pc += sizeof(bidStat); 1667 set_baud_params(pB); 1668 break; 1669 1670 case STAT_HWFAIL: 1671 i2QueueCommands (PTYPE_INLINE, pCh, 0, 1, CMD_HW_TEST); 1672 pCh->channelFail = *((failStatPtr)pc); 1673 pc += sizeof(failStat); 1674 break; 1675 1676 /* No explicit match? then 1677 * Might be an error packet... 1678 */ 1679 default: 1680 switch (uc & STAT_MOD_ERROR) 1681 { 1682 case STAT_ERROR: 1683 if (uc & STAT_E_PARITY) { 1684 pCh->dataSetIn |= I2_PAR; 1685 pCh->icount.parity++; 1686 } 1687 if (uc & STAT_E_FRAMING){ 1688 pCh->dataSetIn |= I2_FRA; 1689 pCh->icount.frame++; 1690 } 1691 if (uc & STAT_E_OVERRUN){ 1692 pCh->dataSetIn |= I2_OVR; 1693 pCh->icount.overrun++; 1694 } 1695 break; 1696 1697 case STAT_MODEM: 1698 // the answer to DSS_NOW request (not change) 1699 pCh->dataSetIn = (pCh->dataSetIn 1700 & ~(I2_RI | I2_CTS | I2_DCD | I2_DSR) ) 1701 | xlatDss[uc & 0xf]; 1702 wake_up_interruptible ( &pCh->dss_now_wait ); 1703 default: 1704 break; 1705 } 1706 } /* End of switch on status type */ 1707 if (dss_change) { 1708#ifdef USE_IQ 1709 schedule_work(&pCh->tqueue_status); 1710#else 1711 do_status(&pCh->tqueue_status); 1712#endif 1713 } 1714 } 1715 else /* Or else, channel is invalid */ 1716 { 1717 // Even though the channel is invalid, we must test the 1718 // status to see how much additional data it has (to be 1719 // skipped) 1720 switch (*pc++) 1721 { 1722 case STAT_FLOW: 1723 pc += 4; /* Skip the data */ 1724 break; 1725 1726 default: 1727 break; 1728 } 1729 } 1730 } // End of while (there is still some status packet left) 1731 break; 1732 1733 default: // Neither packet? should be impossible 1734 ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1, 1735 PTYPE_OF(pB->i2eLeadoffWord) ); 1736 write_unlock_irqrestore(&pB->read_fifo_spinlock, 1737 bflags); 1738 1739 break; 1740 } // End of switch on type of packets 1741 } /*while(board I2_HAS_INPUT)*/ 1742 1743 ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 ); 1744 1745 // Send acknowledgement to the board even if there was no data! 1746 pB->i2eOutMailWaiting |= MB_IN_STRIPPED; 1747 return; 1748} 1749 1750//****************************************************************************** 1751// Function: i2Write2Fifo(pB,address,count) 1752// Parameters: Pointer to a board structure, source address, byte count 1753// Returns: bytes written 1754// 1755// Description: 1756// Writes count bytes to board io address(implied) from source 1757// Adjusts count, leaves reserve for next time around bypass cmds 1758//****************************************************************************** 1759static int 1760i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve) 1761{ 1762 int rc = 0; 1763 unsigned long flags; 1764 write_lock_irqsave(&pB->write_fifo_spinlock, flags); 1765 if (!pB->i2eWaitingForEmptyFifo) { 1766 if (pB->i2eFifoRemains > (count+reserve)) { 1767 pB->i2eFifoRemains -= count; 1768 iiWriteBuf(pB, source, count); 1769 pB->i2eOutMailWaiting |= MB_OUT_STUFFED; 1770 rc = count; 1771 } 1772 } 1773 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); 1774 return rc; 1775} 1776//****************************************************************************** 1777// Function: i2StuffFifoBypass(pB) 1778// Parameters: Pointer to a board structure 1779// Returns: Nothing 1780// 1781// Description: 1782// Stuffs as many bypass commands into the fifo as possible. This is simpler 1783// than stuffing data or inline commands to fifo, since we do not have 1784// flow-control to deal with. 1785//****************************************************************************** 1786static inline void 1787i2StuffFifoBypass(i2eBordStrPtr pB) 1788{ 1789 i2ChanStrPtr pCh; 1790 unsigned char *pRemove; 1791 unsigned short stripIndex; 1792 unsigned short packetSize; 1793 unsigned short paddedSize; 1794 unsigned short notClogged = 1; 1795 unsigned long flags; 1796 1797 int bailout = 1000; 1798 1799 // Continue processing so long as there are entries, or there is room in the 1800 // fifo. Each entry represents a channel with something to do. 1801 while ( --bailout && notClogged && 1802 (NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS)))) 1803 { 1804 write_lock_irqsave(&pCh->Cbuf_spinlock, flags); 1805 stripIndex = pCh->Cbuf_strip; 1806 1807 // as long as there are packets for this channel... 1808 1809 while (stripIndex != pCh->Cbuf_stuff) { 1810 pRemove = &(pCh->Cbuf[stripIndex]); 1811 packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader); 1812 paddedSize = roundup(packetSize, 2); 1813 1814 if (paddedSize > 0) { 1815 if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) { 1816 notClogged = 0; /* fifo full */ 1817 i2QueueNeeds(pB, pCh, NEED_BYPASS); // Put back on queue 1818 break; // Break from the channel 1819 } 1820 } 1821#ifdef DEBUG_FIFO 1822WriteDBGBuf("BYPS", pRemove, paddedSize); 1823#endif /* DEBUG_FIFO */ 1824 pB->debugBypassCount++; 1825 1826 pRemove += packetSize; 1827 stripIndex += packetSize; 1828 if (stripIndex >= CBUF_SIZE) { 1829 stripIndex = 0; 1830 pRemove = pCh->Cbuf; 1831 } 1832 } 1833 // Done with this channel. Move to next, removing this one from 1834 // the queue of channels if we cleaned it out (i.e., didn't get clogged. 1835 pCh->Cbuf_strip = stripIndex; 1836 write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); 1837 } // Either clogged or finished all the work 1838 1839#ifdef IP2DEBUG_TRACE 1840 if ( !bailout ) { 1841 ip2trace (ITRC_NO_PORT, ITRC_ERROR, 1, 0 ); 1842 } 1843#endif 1844} 1845 1846//****************************************************************************** 1847// Function: i2StuffFifoFlow(pB) 1848// Parameters: Pointer to a board structure 1849// Returns: Nothing 1850// 1851// Description: 1852// Stuffs as many flow control packets into the fifo as possible. This is easier 1853// even than doing normal bypass commands, because there is always at most one 1854// packet, already assembled, for each channel. 1855//****************************************************************************** 1856static inline void 1857i2StuffFifoFlow(i2eBordStrPtr pB) 1858{ 1859 i2ChanStrPtr pCh; 1860 unsigned short paddedSize = roundup(sizeof(flowIn), 2); 1861 1862 ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2, 1863 pB->i2eFifoRemains, paddedSize ); 1864 1865 // Continue processing so long as there are entries, or there is room in the 1866 // fifo. Each entry represents a channel with something to do. 1867 while ( (NULL != (pCh = i2DeQueueNeeds(pB,NEED_FLOW)))) { 1868 pB->debugFlowCount++; 1869 1870 // NO Chan LOCK needed ??? 1871 if ( 0 == i2Write2Fifo(pB,(unsigned char *)&(pCh->infl),paddedSize,0)) { 1872 break; 1873 } 1874#ifdef DEBUG_FIFO 1875 WriteDBGBuf("FLOW",(unsigned char *) &(pCh->infl), paddedSize); 1876#endif /* DEBUG_FIFO */ 1877 1878 } // Either clogged or finished all the work 1879 1880 ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_RETURN, 0 ); 1881} 1882 1883//****************************************************************************** 1884// Function: i2StuffFifoInline(pB) 1885// Parameters: Pointer to a board structure 1886// Returns: Nothing 1887// 1888// Description: 1889// Stuffs as much data and inline commands into the fifo as possible. This is 1890// the most complex fifo-stuffing operation, since there if now the channel 1891// flow-control issue to deal with. 1892//****************************************************************************** 1893static inline void 1894i2StuffFifoInline(i2eBordStrPtr pB) 1895{ 1896 i2ChanStrPtr pCh; 1897 unsigned char *pRemove; 1898 unsigned short stripIndex; 1899 unsigned short packetSize; 1900 unsigned short paddedSize; 1901 unsigned short notClogged = 1; 1902 unsigned short flowsize; 1903 unsigned long flags; 1904 1905 int bailout = 1000; 1906 int bailout2; 1907 1908 ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_ENTER, 3, pB->i2eFifoRemains, 1909 pB->i2Dbuf_strip, pB->i2Dbuf_stuff ); 1910 1911 // Continue processing so long as there are entries, or there is room in the 1912 // fifo. Each entry represents a channel with something to do. 1913 while ( --bailout && notClogged && 1914 (NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) ) 1915 { 1916 write_lock_irqsave(&pCh->Obuf_spinlock, flags); 1917 stripIndex = pCh->Obuf_strip; 1918 1919 ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff ); 1920 1921 // as long as there are packets for this channel... 1922 bailout2 = 1000; 1923 while ( --bailout2 && stripIndex != pCh->Obuf_stuff) { 1924 pRemove = &(pCh->Obuf[stripIndex]); 1925 1926 // Must determine whether this be a data or command packet to 1927 // calculate correctly the header size and the amount of 1928 // flow-control credit this type of packet will use. 1929 if (PTYPE_OF(pRemove) == PTYPE_DATA) { 1930 flowsize = DATA_COUNT_OF(pRemove); 1931 packetSize = flowsize + sizeof(i2DataHeader); 1932 } else { 1933 flowsize = CMD_COUNT_OF(pRemove); 1934 packetSize = flowsize + sizeof(i2CmdHeader); 1935 } 1936 flowsize = CREDIT_USAGE(flowsize); 1937 paddedSize = roundup(packetSize, 2); 1938 1939 ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize ); 1940 1941 // If we don't have enough credits from the board to send the data, 1942 // flag the channel that we are waiting for flow control credit, and 1943 // break out. This will clean up this channel and remove us from the 1944 // queue of hot things to do. 1945 1946 ip2trace (CHANN, ITRC_SICMD, 5, 2, pCh->outfl.room, flowsize ); 1947 1948 if (pCh->outfl.room <= flowsize) { 1949 // Do Not have the credits to send this packet. 1950 i2QueueNeeds(pB, pCh, NEED_CREDIT); 1951 notClogged = 0; 1952 break; // So to do next channel 1953 } 1954 if ( (paddedSize > 0) 1955 && ( 0 == i2Write2Fifo(pB, pRemove, paddedSize, 128))) { 1956 // Do Not have room in fifo to send this packet. 1957 notClogged = 0; 1958 i2QueueNeeds(pB, pCh, NEED_INLINE); 1959 break; // Break from the channel 1960 } 1961#ifdef DEBUG_FIFO 1962WriteDBGBuf("DATA", pRemove, paddedSize); 1963#endif /* DEBUG_FIFO */ 1964 pB->debugInlineCount++; 1965 1966 pCh->icount.tx += flowsize; 1967 // Update current credits 1968 pCh->outfl.room -= flowsize; 1969 pCh->outfl.asof += flowsize; 1970 if (PTYPE_OF(pRemove) == PTYPE_DATA) { 1971 pCh->Obuf_char_count -= DATA_COUNT_OF(pRemove); 1972 } 1973 pRemove += packetSize; 1974 stripIndex += packetSize; 1975 1976 ip2trace (CHANN, ITRC_SICMD, 6, 2, stripIndex, pCh->Obuf_strip); 1977 1978 if (stripIndex >= OBUF_SIZE) { 1979 stripIndex = 0; 1980 pRemove = pCh->Obuf; 1981 1982 ip2trace (CHANN, ITRC_SICMD, 7, 1, stripIndex ); 1983 1984 } 1985 } /* while */ 1986 if ( !bailout2 ) { 1987 ip2trace (CHANN, ITRC_ERROR, 3, 0 ); 1988 } 1989 // Done with this channel. Move to next, removing this one from the 1990 // queue of channels if we cleaned it out (i.e., didn't get clogged. 1991 pCh->Obuf_strip = stripIndex; 1992 write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); 1993 if ( notClogged ) 1994 { 1995 1996 ip2trace (CHANN, ITRC_SICMD, 8, 0 ); 1997 1998 if ( pCh->pTTY ) { 1999 ip2_owake(pCh->pTTY); 2000 } 2001 } 2002 } // Either clogged or finished all the work 2003 2004 if ( !bailout ) { 2005 ip2trace (ITRC_NO_PORT, ITRC_ERROR, 4, 0 ); 2006 } 2007 2008 ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_RETURN, 1,pB->i2Dbuf_strip); 2009} 2010 2011//****************************************************************************** 2012// Function: serviceOutgoingFifo(pB) 2013// Parameters: Pointer to a board structure 2014// Returns: Nothing 2015// 2016// Description: 2017// Helper routine to put data in the outgoing fifo, if we aren't already waiting 2018// for something to be there. If the fifo has only room for a very little data, 2019// go head and hit the board with a mailbox hit immediately. Otherwise, it will 2020// have to happen later in the interrupt processing. Since this routine may be 2021// called both at interrupt and foreground time, we must turn off interrupts 2022// during the entire process. 2023//****************************************************************************** 2024static void 2025serviceOutgoingFifo(i2eBordStrPtr pB) 2026{ 2027 // If we aren't currently waiting for the board to empty our fifo, service 2028 // everything that is pending, in priority order (especially, Bypass before 2029 // Inline). 2030 if ( ! pB->i2eWaitingForEmptyFifo ) 2031 { 2032 i2StuffFifoFlow(pB); 2033 i2StuffFifoBypass(pB); 2034 i2StuffFifoInline(pB); 2035 2036 iiSendPendingMail(pB); 2037 } 2038} 2039 2040//****************************************************************************** 2041// Function: i2ServiceBoard(pB) 2042// Parameters: Pointer to a board structure 2043// Returns: Nothing 2044// 2045// Description: 2046// Normally this is called from interrupt level, but there is deliberately 2047// nothing in here specific to being called from interrupt level. All the 2048// hardware-specific, interrupt-specific things happen at the outer levels. 2049// 2050// For example, a timer interrupt could drive this routine for some sort of 2051// polled operation. The only requirement is that the programmer deal with any 2052// atomiticity/concurrency issues that result. 2053// 2054// This routine responds to the board's having sent mailbox information to the 2055// host (which would normally cause an interrupt). This routine reads the 2056// incoming mailbox. If there is no data in it, this board did not create the 2057// interrupt and/or has nothing to be done to it. (Except, if we have been 2058// waiting to write mailbox data to it, we may do so. 2059// 2060// Based on the value in the mailbox, we may take various actions. 2061// 2062// No checking here of pB validity: after all, it shouldn't have been called by 2063// the handler unless pB were on the list. 2064//****************************************************************************** 2065static inline int 2066i2ServiceBoard ( i2eBordStrPtr pB ) 2067{ 2068 unsigned inmail; 2069 unsigned long flags; 2070 2071 2072 /* This should be atomic because of the way we are called... */ 2073 if (NO_MAIL_HERE == ( inmail = pB->i2eStartMail ) ) { 2074 inmail = iiGetMail(pB); 2075 } 2076 pB->i2eStartMail = NO_MAIL_HERE; 2077 2078 ip2trace (ITRC_NO_PORT, ITRC_INTR, 2, 1, inmail ); 2079 2080 if (inmail != NO_MAIL_HERE) { 2081 // If the board has gone fatal, nothing to do but hit a bit that will 2082 // alert foreground tasks to protest! 2083 if ( inmail & MB_FATAL_ERROR ) { 2084 pB->i2eFatal = 1; 2085 goto exit_i2ServiceBoard; 2086 } 2087 2088 /* Assuming no fatal condition, we proceed to do work */ 2089 if ( inmail & MB_IN_STUFFED ) { 2090 pB->i2eFifoInInts++; 2091 i2StripFifo(pB); /* There might be incoming packets */ 2092 } 2093 2094 if (inmail & MB_OUT_STRIPPED) { 2095 pB->i2eFifoOutInts++; 2096 write_lock_irqsave(&pB->write_fifo_spinlock, flags); 2097 pB->i2eFifoRemains = pB->i2eFifoSize; 2098 pB->i2eWaitingForEmptyFifo = 0; 2099 write_unlock_irqrestore(&pB->write_fifo_spinlock, 2100 flags); 2101 2102 ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains ); 2103 2104 } 2105 serviceOutgoingFifo(pB); 2106 } 2107 2108 ip2trace (ITRC_NO_PORT, ITRC_INTR, 8, 0 ); 2109 2110exit_i2ServiceBoard: 2111 2112 return 0; 2113} 2114