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