diff -urN linux-2.6.9-1.6_FC2/Documentation/computone.txt linux-2.6.9-1.6_FC2-ct/Documentation/computone.txt --- linux-2.6.9-1.6_FC2/Documentation/computone.txt 2004-10-18 17:54:55.000000000 -0400 +++ linux-2.6.9-1.6_FC2-ct/Documentation/computone.txt 2004-12-22 22:46:29.618565672 -0500 @@ -6,11 +6,11 @@ These notes are for the drivers which have already been integrated into the kernel and have been tested on Linux kernels 2.0, 2.2, 2.3, and 2.4. -Version: 1.2.14 -Date: 11/01/2001 +Version: 1.2.18 +Date: 12/22/2004 Historical Author: Andrew Manison Primary Author: Doug McNash -Support: support@computone.com +Support: mhw@wittsend.com Fixes and Updates: Mike Warfield This file assumes that you are using the Computone drivers which are @@ -26,7 +26,7 @@ products previous to the Intelliport II. This driver was developed on the v2.0.x Linux tree and has been tested up -to v2.4.14; it will probably not work with earlier v1.X kernels,. +to v2.6.9; it will probably not work with earlier v1.X kernels,. 2. QUICK INSTALLATION diff -urN linux-2.6.9-1.6_FC2/drivers/char/ip2/i2cmd.c linux-2.6.9-1.6_FC2-ct/drivers/char/ip2/i2cmd.c --- linux-2.6.9-1.6_FC2/drivers/char/ip2/i2cmd.c 2004-10-18 17:53:50.000000000 -0400 +++ linux-2.6.9-1.6_FC2-ct/drivers/char/ip2/i2cmd.c 2004-12-22 18:52:12.000000000 -0500 @@ -139,7 +139,9 @@ //static UCHAR ct86[]={ 2, BTH, 0x56,0 }; // RCV_ENABLE static UCHAR ct87[] = { 1, BYP, 0x57 }; // HW_TEST //static UCHAR ct88[]={ 3, BTH, 0x58,0,0 }; // RCV_THRESHOLD +#ifdef ENABLE_DSSNOW static UCHAR ct89[]={ 1, BYP, 0x59 }; // DSS_NOW +#endif //static UCHAR ct90[]={ 3, BYP, 0x5A,0,0 }; // Set SILO //static UCHAR ct91[]={ 2, BYP, 0x5B,0 }; // timed break diff -urN linux-2.6.9-1.6_FC2/drivers/char/ip2/i2ellis.c linux-2.6.9-1.6_FC2-ct/drivers/char/ip2/i2ellis.c --- linux-2.6.9-1.6_FC2/drivers/char/ip2/i2ellis.c 2004-10-18 17:53:06.000000000 -0400 +++ linux-2.6.9-1.6_FC2-ct/drivers/char/ip2/i2ellis.c 2004-12-22 21:31:48.000000000 -0500 @@ -606,7 +606,7 @@ set_current_state( TASK_INTERRUPTIBLE ); - pDelayTimer->expires = jiffies + ( mseconds + 9 ) / 10; + pDelayTimer->expires = jiffies + msecs_to_jiffies( mseconds ); pDelayTimer->function = ii2DelayWakeup; pDelayTimer->data = 0; diff -urN linux-2.6.9-1.6_FC2/drivers/char/ip2/i2ellis.h linux-2.6.9-1.6_FC2-ct/drivers/char/ip2/i2ellis.h --- linux-2.6.9-1.6_FC2/drivers/char/ip2/i2ellis.h 2004-10-18 17:53:09.000000000 -0400 +++ linux-2.6.9-1.6_FC2-ct/drivers/char/ip2/i2ellis.h 2004-12-22 18:45:40.000000000 -0500 @@ -403,7 +403,7 @@ // For queuing interrupt bottom half handlers. /\/\|=mhw=|\/\/ struct work_struct tqueue_interrupt; - struct timer_list SendPendingTimer; // Used by iiSendPending +// struct timer_list SendPendingTimer; // Used by iiSendPending unsigned int SendPendingRetry; } i2eBordStr, *i2eBordStrPtr; diff -urN linux-2.6.9-1.6_FC2/drivers/char/ip2/i2lib.c linux-2.6.9-1.6_FC2-ct/drivers/char/ip2/i2lib.c --- linux-2.6.9-1.6_FC2/drivers/char/ip2/i2lib.c 2004-10-18 17:55:29.000000000 -0400 +++ linux-2.6.9-1.6_FC2-ct/drivers/char/ip2/i2lib.c 2004-12-22 18:48:43.000000000 -0500 @@ -174,8 +174,12 @@ pB->i2eWaitingForEmptyFifo |= (pB->i2eOutMailWaiting & MB_OUT_STUFFED); pB->i2eOutMailWaiting = 0; + if( pB->SendPendingRetry ) { + printk( KERN_DEBUG "IP2: iiSendPendingMail: busy board pickup on %d\n", pB->SendPendingRetry ); + } pB->SendPendingRetry = 0; } else { +#ifdef IP2_USE_TIMER_WAIT /* The only time we hit this area is when "iiTrySendMail" has failed. That only occurs when the outbound mailbox is still busy with the last message. We take a short breather @@ -193,6 +197,11 @@ } else { printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" ); } +#endif + pB->SendPendingRetry++; + if( 0 == ( pB->SendPendingRetry % 8 ) ) { + printk( KERN_ERR "IP2: iiSendPendingMail: board busy, retry %d\n", pB->SendPendingRetry ); + } } } } @@ -1325,8 +1334,9 @@ remove_wait_queue(&(pCh->pBookmarkWait), &wait); // if expires == 0 then timer poped, then do not need to del_timer + // jiffy wrap per Tim Schmielau (tim@physik3.uni-rostock.de) if ((timeout > 0) && pCh->BookmarkTimer.expires && - time_before(jiffies, pCh->BookmarkTimer.expires)) { + time_before(jiffies, pCh->BookmarkTimer.expires)) { del_timer( &(pCh->BookmarkTimer) ); pCh->BookmarkTimer.expires = 0; diff -urN linux-2.6.9-1.6_FC2/drivers/char/ip2.c linux-2.6.9-1.6_FC2-ct/drivers/char/ip2.c --- linux-2.6.9-1.6_FC2/drivers/char/ip2.c 2004-10-18 17:54:08.000000000 -0400 +++ linux-2.6.9-1.6_FC2-ct/drivers/char/ip2.c 2004-12-22 21:22:47.000000000 -0500 @@ -6,6 +6,8 @@ // __initdata should work as advertized // +// Removed use of __init for declarations in 2.6 kernel... + #include #include #include @@ -46,7 +48,7 @@ MODULE_PARM_DESC(poll_only,"Do not use card interrupts"); -static int __init ip2_init(void) +static int ip2_init(void) { if( poll_only ) { /* Hard lock the interrupts to zero */ @@ -55,7 +57,14 @@ return ip2_loadmain(io,irq,(unsigned char *)fip_firm,sizeof(fip_firm)); } + +static void ip2_exit(void) +{ + return; +} + module_init(ip2_init); +module_exit(ip2_exit); MODULE_LICENSE("GPL"); @@ -81,7 +90,7 @@ * Any value = -1, do not overwrite compiled in value. * ******************************************************************************/ -static int __init ip2_setup(char *str) +static int ip2_setup(char *str) { int ints[10]; /* 4 boards, 2 parameters + 2 */ int i, j; diff -urN linux-2.6.9-1.6_FC2/drivers/char/ip2main.c linux-2.6.9-1.6_FC2-ct/drivers/char/ip2main.c --- linux-2.6.9-1.6_FC2/drivers/char/ip2main.c 2004-10-18 17:55:36.000000000 -0400 +++ linux-2.6.9-1.6_FC2-ct/drivers/char/ip2main.c 2004-12-22 22:31:24.000000000 -0500 @@ -19,6 +19,30 @@ // // Done: // +// 1.2.18 /\/\|=mhw=|\/\/ +// Removed use of __init macro. Definition and utilization changed in 2.6 +// Fixed jiffies math in ii2DelayTimer +// How long has THIS been broken? Delay was basically a noop... +// Removed set_modem_info declaration +// (where did the function go???) +// Cleaned up some comments +// Dumped some groady tracing code that hasn't been used (or tested) in +// years and was only a source of warning messages. +// +// 1.2.17 /\/\|=mhw=|\/\/ +// PCI fixes submitted by Bjorn Helgaas +// Added calls to Add pci_enable_device()/pci_disable_device() per +// submitted patches. My thanks to Bjorn Helgaas . +// +// 1.2.16 /\/\|=mhw=|\/\/ +// Yet another shot at the busy board timing window (use the poll timer). +// Because of this, the poll timer is always enabled... +// Cleaned up some comments on immediate interrupt mode (ppp code elsewhere +// has been fixed and the new busy board logic won't throw a hairball). +// +// 1.2.15 dmc +// Fixed jiffy wrap, PCI card may now be set to poll. +// // 1.2.14 /\/\|=mhw=|\/\/ // Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts. // Changed the definition of ip2trace to be more consistent with kernel style @@ -150,7 +174,7 @@ /* String constants to identify ourselves */ static char *pcName = "Computone IntelliPort Plus multiport driver"; -static char *pcVersion = "1.2.14"; +static char *pcVersion = "1.2.18"; /* String constants for port names */ static char *pcDriver_name = "ip2"; @@ -202,7 +226,6 @@ static void ip2_wait_until_sent(PTTY,int); static void set_params (i2ChanStrPtr, struct termios *); -static int set_modem_info(i2ChanStrPtr, unsigned int, unsigned int *); static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *); static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *); @@ -307,7 +330,7 @@ // Some functions to keep track of what irq's we have -static int __init +static int is_valid_irq(int irq) { int *i = Valid_Irqs; @@ -318,14 +341,14 @@ return (*i); } -static void __init +static void mark_requested_irq( char irq ) { rirqs[iindx++] = irq; } #ifdef MODULE -static int __init +static int clear_requested_irq( char irq ) { int i; @@ -337,9 +360,9 @@ } return 0; } -#endif +#endif /* MODULE */ -static int __init +static int have_requested_irq( char irq ) { // array init to zeros so 0 irq will not be requested as a side effect @@ -523,17 +546,12 @@ if (iop) { ip2config.addr[i] = iop[i]; if (irqp) { - if( irqp[i] >= 0 ) { - ip2config.irq[i] = irqp[i]; - } else { - ip2config.irq[i] = 0; - } + ip2config.irq[i] = irqp[i]; // This is a little bit of a hack. If poll_only=1 on command // line back in ip2.c OR all IRQs on all specified boards are // explicitly set to 0, then drop to poll only mode and override // PCI or EISA interrupts. This superceeds the old hack of // triggering if all interrupts were zero (like da default). - // Still a hack but less prone to random acts of terrorism. // // What we really should do, now that the IRQ default is set // to -1, is to use 0 as a hard coded, do not probe. @@ -616,15 +634,8 @@ printk( KERN_ERR "IP2: PCI I/O address error\n"); } -// If the PCI BIOS assigned it, lets try and use it. If we -// can't acquire it or it screws up, deal with it then. - -// if (!is_valid_irq(pci_irq)) { -// printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq); -// pci_irq = 0; -// } ip2config.irq[i] = pci_dev_i->irq; - } else { // ann error + } else { // an error ip2config.addr[i] = 0; if (status == PCIBIOS_DEVICE_NOT_FOUND) { printk( KERN_ERR "IP2: PCI board %d not found\n", i ); @@ -789,6 +800,14 @@ /* Initialise the interrupt handler bottom half (aka slih). */ } } + + if (!TimerOn) { +// Kick the timer on for stuck board safeties... + PollTimer.expires = POLL_TIMEOUT; + add_timer ( &PollTimer ); + TimerOn = 1; + } + for( i = 0; i < IP2_MAX_BOARDS; ++i ) { if ( i2BoardPtrTable[i] ) { set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */ @@ -818,7 +837,7 @@ /* the board, the channel structures are initialized, and the board details */ /* are reported on the console. */ /******************************************************************************/ -static void __init +static void ip2_init_board( int boardnum ) { int i; @@ -961,7 +980,7 @@ /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */ /* it returns the base address of the controller. */ /******************************************************************************/ -static unsigned short __init +static unsigned short find_eisa_board( int start_slot ) { int i, j; @@ -1208,8 +1227,10 @@ // Only process those boards which match our IRQ. // IRQ = 0 for polled boards, we won't poll "IRQ" boards +// Add an additional "check" if the irq is zero for boards +// which are "stuck" - if ( pB && (pB->i2eUsingIrq == irq) ) { + if ( pB && ( pB->i2eUsingIrq == irq || ( 0 == irq && 0 != pB->SendPendingRetry ) ) ) { handled = 1; #ifdef USE_IQI @@ -1224,9 +1245,8 @@ // Make sure the immediate queue is flagged to fire. } #else -// We are using immediate servicing here. This sucks and can -// cause all sorts of havoc with ppp and others. The failsafe -// check on iiSendPendingMail could also throw a hairball. +// We are using immediate servicing here. Suboptimal +// to say the least... i2ServiceBoard( pB ); #endif /* USE_IQI */ } @@ -1251,6 +1271,9 @@ static void ip2_poll(unsigned long arg) { + int i; + i2eBordStrPtr pB; + ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); TimerOn = 0; // it's the truth but not checked in service @@ -1258,7 +1281,15 @@ // Just polled boards, IRQ = 0 will hit all non-interrupt boards. // It will NOT poll boards handled by hard interrupts. // The issue of queued BH interrups is handled in ip2_interrupt(). - ip2_interrupt(0, NULL, NULL); + + for( i = 0; i < i2nBoards; ++i ) { + pB = i2BoardPtrTable[i]; + // Service the board if the irq indicates a polled board + // OR if the SendPendingRetry indicates a retry state in the board + if ( pB && ( 0 == pB->i2eUsingIrq || 0 != pB->SendPendingRetry ) ) { + i2ServiceBoard( pB ); + } + } PollTimer.expires = POLL_TIMEOUT; add_timer( &PollTimer ); @@ -2002,7 +2033,9 @@ static int ip2_tiocmget(struct tty_struct *tty, struct file *file) { i2ChanStrPtr pCh = DevTable[tty->index]; +#ifdef ENABLE_DSSNOW wait_queue_t wait; +#endif if (pCh == NULL) return -ENODEV; @@ -2015,7 +2048,7 @@ */ /* This thing is still busted in the 1.2.12 driver on 2.4.x - and even hoses the serial console so the oops can be trapped. + and even hoses the serial console so the oops can't be trapped. /\/\|=mhw=|\/\/ */ #ifdef ENABLE_DSSNOW @@ -2912,7 +2945,16 @@ case 2: // Ping device rc = -EINVAL; break; + +#ifdef IP2_TRACE_DEVICE case 3: // Trace device +/* + This may have been useful at one time during early development + but has not been used for years and is just a source of excess + baggage and unused code and warnings. The client programs that + understood this returned "blob" don't even currently compile... + Disabled until needed in the future. /\/\|=mhw=|\/\/ 12/22/2004 +*/ if ( cmd == 1 ) { rc = put_user(iiSendPendingMail, pIndex++ ); rc = put_user(i2InitChannels, pIndex++ ); @@ -2973,6 +3015,7 @@ } break; +#endif default: rc = -ENODEV;