3 * (c) 1999 by Computone Corporation
5 ********************************************************************************
7 * PACKAGE: Linux tty Device Driver for IntelliPort family of multiport
8 * serial I/O controllers.
10 * DESCRIPTION: Mainline code for the device driver
12 *******************************************************************************/
18 // Four box EX was barfing on >128k kmalloc, made structure smaller by
19 // reducing output buffer size
22 // Device file system support (MHW)
26 // Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules
30 // DCD was not reported when CLOCAL was set on call to TIOCMGET
33 // TIOCMGET requests and waits for status return
34 // No DSS interrupts enabled except for DCD when needed
36 // For internal use only
38 //#define IP2DEBUG_INIT
39 //#define IP2DEBUG_OPEN
40 //#define IP2DEBUG_WRITE
41 //#define IP2DEBUG_READ
42 //#define IP2DEBUG_IOCTL
43 //#define IP2DEBUG_IPL
45 //#define IP2DEBUG_TRACE
51 #include <linux/config.h>
52 // Uncomment the following if you want it compiled with modversions
54 # if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
58 # include <linux/modversions.h>
62 #include <linux/version.h>
64 #include <linux/ctype.h>
65 #include <linux/string.h>
66 #include <linux/fcntl.h>
67 #include <linux/errno.h>
68 #include <linux/module.h>
69 #include <linux/signal.h>
70 #include <linux/sched.h>
71 #ifdef CONFIG_DEVFS_FS
72 #include <linux/devfs_fs_kernel.h>
74 #include <linux/timer.h>
75 #include <linux/interrupt.h>
76 #include <linux/pci.h>
78 #include <linux/malloc.h>
79 #include <linux/major.h>
80 #include <linux/wait.h>
82 #include <linux/tty.h>
83 #include <linux/tty_flip.h>
84 #include <linux/termios.h>
85 #include <linux/tty_driver.h>
86 #include <linux/serial.h>
87 #include <linux/ptrace.h>
88 #include <linux/ioport.h>
90 #include <linux/cdk.h>
91 #include <linux/comstats.h>
92 #include <linux/delay.h>
94 #include <asm/system.h>
97 #include <asm/bitops.h>
99 #ifndef KERNEL_VERSION
100 #define KERNEL_VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))
103 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
104 # include <linux/vmalloc.h>
105 # include <linux/init.h>
106 # include <asm/serial.h>
108 # include <linux/bios32.h>
111 // These VERSION switches maybe inexact because I simply don't know
112 // when the various features appeared in the 2.1.XX kernels.
113 // They are good enough for 2.0 vs 2.2 and if you are fooling with
114 // the 2.1.XX stuff then it would be trivial for you to fix.
115 // Most of these macros were stolen from some other drivers
118 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,4)
119 # include <asm/segment.h>
120 # define GET_USER(error,value,addr) error = get_user(value,addr)
121 # define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
122 # define PUT_USER(error,value,addr) error = put_user(value,addr)
123 # define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
125 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,5)
126 # include <asm/uaccess.h>
127 # define pcibios_strerror(status) \
128 printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
131 #else /* 2.0.x and 2.1.x before 2.1.4 */
133 # define proc_register_dynamic(a,b) proc_register(a,b)
135 # define GET_USER(error,value,addr) \
137 error = verify_area (VERIFY_READ, (void *) addr, sizeof (value)); \
139 value = get_user(addr); \
142 # define COPY_FROM_USER(error,dest,src,size) \
144 error = verify_area (VERIFY_READ, (void *) src, size); \
146 memcpy_fromfs (dest, src, size); \
149 # define PUT_USER(error,value,addr) \
151 error = verify_area (VERIFY_WRITE, (void *) addr, sizeof (value)); \
153 put_user (value, addr); \
156 # define COPY_TO_USER(error,dest,src,size) \
158 error = verify_area (VERIFY_WRITE, (void *) dest, size); \
160 memcpy_tofs (dest, src, size); \
165 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
167 #define __initfunc(a) a
169 #define ioremap(a,b) vremap((a),(b))
170 #define iounmap(a) vfree((a))
171 #define SERIAL_TYPE_NORMAL 1
172 #define SERIAL_TYPE_CALLOUT 2
173 #define schedule_timeout(a){current->timeout = jiffies + (a); schedule();}
174 #define signal_pending(a) ((a)->signal & ~(a)->blocked)
175 #define in_interrupt() intr_count
178 #include "./ip2/ip2types.h"
179 #include "./ip2/ip2trace.h"
180 #include "./ip2/ip2ioctl.h"
181 #include "./ip2/ip2.h"
182 #include "./ip2/i2ellis.h"
183 #include "./ip2/i2lib.h"
189 #include <linux/proc_fs.h>
191 static int ip2_read_procmem(char *, char **, off_t
, int);
192 int ip2_read_proc(char *, char **, off_t
, int, int *, void * );
194 /********************/
195 /* Type Definitions */
196 /********************/
202 /* String constants to identify ourselves */
203 static char *pcName
= "Computone IntelliPort Plus multiport driver";
204 static char *pcVersion
= "1.2.9";
206 /* String constants for port names */
207 static char *pcDriver_name
= "ip2";
208 #ifdef CONFIG_DEVFS_FS
209 static char *pcTty
= "ttf/%d";
210 static char *pcCallout
= "cuf/%d";
212 static char *pcTty
= "ttyF";
213 static char *pcCallout
= "cuf";
215 static char *pcIpl
= "ip2ipl";
217 /* Serial subtype definitions */
218 #define SERIAL_TYPE_NORMAL 1
219 #define SERIAL_TYPE_CALLOUT 2
221 // cheezy kludge or genius - you decide?
222 int ip2_loadmain(int *, int *, unsigned char *, int);
223 static unsigned char *Fip_firmware
;
224 static int Fip_firmware_size
;
226 /***********************/
227 /* Function Prototypes */
228 /***********************/
230 /* Global module entry functions */
232 int init_module(void);
233 void cleanup_module(void);
236 int old_ip2_init(void);
238 /* Private (static) functions */
239 static int ip2_open(PTTY
, struct file
*);
240 static void ip2_close(PTTY
, struct file
*);
241 static int ip2_write(PTTY
, int, const unsigned char *, int);
242 static void ip2_putchar(PTTY
, unsigned char);
243 static void ip2_flush_chars(PTTY
);
244 static int ip2_write_room(PTTY
);
245 static int ip2_chars_in_buf(PTTY
);
246 static void ip2_flush_buffer(PTTY
);
247 static int ip2_ioctl(PTTY
, struct file
*, UINT
, ULONG
);
248 static void ip2_set_termios(PTTY
, struct termios
*);
249 static void ip2_set_line_discipline(PTTY
);
250 static void ip2_throttle(PTTY
);
251 static void ip2_unthrottle(PTTY
);
252 static void ip2_stop(PTTY
);
253 static void ip2_start(PTTY
);
254 static void ip2_hangup(PTTY
);
256 static void set_irq(int, int);
257 static void ip2_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
);
258 static void ip2_poll(unsigned long arg
);
259 static inline void service_all_boards(void);
260 static inline void do_input(i2ChanStrPtr pCh
);
261 static inline void do_status(i2ChanStrPtr pCh
);
263 static void ip2_wait_until_sent(PTTY
,int);
265 static void set_params (i2ChanStrPtr
, struct termios
*);
266 static int set_modem_info(i2ChanStrPtr
, unsigned int, unsigned int *);
267 static int get_serial_info(i2ChanStrPtr
, struct serial_struct
*);
268 static int set_serial_info(i2ChanStrPtr
, struct serial_struct
*);
270 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
271 static int ip2_ipl_read(struct inode
*, char *, size_t , loff_t
*);
273 static ssize_t
ip2_ipl_read(struct file
*, char *, size_t, loff_t
*) ;
275 static ssize_t
ip2_ipl_write(struct file
*, const char *, size_t, loff_t
*);
276 static int ip2_ipl_ioctl(struct inode
*, struct file
*, UINT
, ULONG
);
277 static int ip2_ipl_open(struct inode
*, struct file
*);
279 void ip2trace(unsigned short,unsigned char,unsigned char,unsigned long,...);
280 static int DumpTraceBuffer(char *, int);
281 static int DumpFifoBuffer( char *, int);
283 static void ip2_init_board(int);
284 static unsigned short find_eisa_board(int);
290 static struct tty_driver ip2_tty_driver
;
291 static struct tty_driver ip2_callout_driver
;
293 static int ref_count
;
295 /* Here, then is a table of board pointers which the interrupt routine should
296 * scan through to determine who it must service.
298 static unsigned short i2nBoards
; // Number of boards here
300 static i2eBordStrPtr i2BoardPtrTable
[IP2_MAX_BOARDS
];
302 static i2ChanStrPtr DevTable
[IP2_MAX_PORTS
];
303 //DevTableMem just used to save addresses for kfree
304 static void *DevTableMem
[IP2_MAX_BOARDS
];
306 static struct tty_struct
* TtyTable
[IP2_MAX_PORTS
];
307 static struct termios
* Termios
[IP2_MAX_PORTS
];
308 static struct termios
* TermiosLocked
[IP2_MAX_PORTS
];
310 /* This is the driver descriptor for the ip2ipl device, which is used to
311 * download the loadware to the boards.
313 static struct file_operations ip2_ipl
= {
316 write
: ip2_ipl_write
,
317 ioctl
: ip2_ipl_ioctl
,
321 static long irq_counter
;
322 static long bh_counter
;
324 // Use immediate queue to service interrupts
325 //#define USE_IQI // PCI&2.2 needs work
326 //#define USE_IQ // PCI&2.2 needs work
328 /* The timer_list entry for our poll routine. If interrupt operation is not
329 * selected, the board is serviced periodically to see if anything needs doing.
331 #define POLL_TIMEOUT (jiffies + 1)
332 static struct timer_list PollTimer
= { function
: ip2_poll
};
335 #ifdef IP2DEBUG_TRACE
336 /* Trace (debug) buffer data */
337 #define TRACEMAX 1000
338 static unsigned long tracebuf
[TRACEMAX
];
339 static int tracestuff
;
340 static int tracestrip
;
341 static int tracewrap
;
348 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
349 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
350 kdevname(tty->device),(pCh->flags),ref_count, \
351 tty->count,/*GET_USE_COUNT(module)*/0,s)
356 #define MIN(a,b) ( ( (a) < (b) ) ? (a) : (b) )
357 #define MAX(a,b) ( ( (a) > (b) ) ? (a) : (b) )
363 #include "./ip2/i2ellis.c" /* Extremely low-level interface services */
364 #include "./ip2/i2cmd.c" /* Standard loadware command definitions */
365 #include "./ip2/i2lib.c" /* High level interface services */
367 /* Configuration area for modprobe */
369 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
370 MODULE_AUTHOR("Doug McNash");
371 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
372 # endif /* LINUX_VERSION */
375 static int poll_only
;
378 static int Eisa_slot
;
381 static char rirqs
[IP2_MAX_BOARDS
];
382 static int Valid_Irqs
[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
384 /******************************************************************************/
385 /* Initialisation Section */
386 /******************************************************************************/
388 ip2_loadmain(int *iop
, int *irqp
, unsigned char *firmware
, int firmsize
)
391 /* process command line arguments to modprobe or insmod i.e. iop & irqp */
392 /* otherwise ip2config is initialized by what's in ip2/ip2.h */
393 /* command line trumps initialization in ip2.h */
394 /* first two args are null if builtin to kernel */
395 if ((irqp
!= NULL
) || (iop
!= NULL
)) {
396 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
397 if (irqp
&& irqp
[i
]) {
398 ip2config
.irq
[i
] = irqp
[i
];
401 ip2config
.addr
[i
] = iop
[i
];
405 Fip_firmware
= firmware
;
406 Fip_firmware_size
= firmsize
;
407 return old_ip2_init();
410 // Some functions to keep track of what irq's we have
413 is_valid_irq(int irq
)
417 while ((*i
!= 0) && (*i
!= irq
)) {
424 mark_requested_irq( char irq
)
426 rirqs
[iindx
++] = irq
;
430 clear_requested_irq( char irq
)
433 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
434 if (rirqs
[i
] == irq
) {
443 have_requested_irq( char irq
)
445 // array init to zeros so 0 irq will not be requested as a side effect
447 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
454 /******************************************************************************/
455 /* Function: init_module() */
456 /* Parameters: None */
457 /* Returns: Success (0) */
460 /* This is a required entry point for an installable module. It simply calls */
461 /* the driver initialisation function and returns what it returns. */
462 /******************************************************************************/
468 printk (KERN_DEBUG
"Loading module ...\n" );
470 //was return old_ip2_init();
475 /******************************************************************************/
476 /* Function: cleanup_module() */
477 /* Parameters: None */
478 /* Returns: Nothing */
481 /* This is a required entry point for an installable module. It has to return */
482 /* the device and the driver to a passive state. It should not be necessary */
483 /* to reset the board fully, especially as the loadware is downloaded */
484 /* externally rather than in the driver. We just want to disable the board */
485 /* and clear the loadware to a reset state. To allow this there has to be a */
486 /* way to detect whether the board has the loadware running at init time to */
487 /* handle subsequent installations of the driver. All memory allocated by the */
488 /* driver should be returned since it may be unloaded from memory. */
489 /******************************************************************************/
498 printk (KERN_DEBUG
"Unloading %s: version %s\n", pcName
, pcVersion
);
500 /* Stop poll timer if we had one. */
502 del_timer ( &PollTimer
);
506 /* Reset the boards we have. */
507 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
508 if ( i2BoardPtrTable
[i
] ) {
509 iiReset( i2BoardPtrTable
[i
] );
513 /* The following is done at most once, if any boards were installed. */
514 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
515 if ( i2BoardPtrTable
[i
] ) {
516 iiResetDelay( i2BoardPtrTable
[i
] );
517 /* free io addresses and Tibet */
518 release_region( ip2config
.addr
[i
], 8 );
519 #ifdef CONFIG_DEVFS_FS
520 devfs_unregister (i2BoardPtrTable
[i
]->devfs_ipl_handle
);
521 devfs_unregister (i2BoardPtrTable
[i
]->devfs_stat_handle
);
524 /* Disable and remove interrupt handler. */
525 if ( (ip2config
.irq
[i
] > 0) && have_requested_irq(ip2config
.irq
[i
]) ) {
526 free_irq ( ip2config
.irq
[i
], (void *)&pcName
);
527 clear_requested_irq( ip2config
.irq
[i
]);
530 if ( ( err
= tty_unregister_driver ( &ip2_tty_driver
) ) ) {
531 printk(KERN_ERR
"IP2: failed to unregister tty driver (%d)\n", err
);
533 if ( ( err
= tty_unregister_driver ( &ip2_callout_driver
) ) ) {
534 printk(KERN_ERR
"IP2: failed to unregister callout driver (%d)\n", err
);
536 #ifdef CONFIG_DEVFS_FS
537 if ( ( err
= devfs_unregister_chrdev ( IP2_IPL_MAJOR
, pcIpl
) ) )
539 if ( ( err
= unregister_chrdev ( IP2_IPL_MAJOR
, pcIpl
) ) )
542 printk(KERN_ERR
"IP2: failed to unregister IPL driver (%d)\n", err
);
544 remove_proc_entry("ip2mem", &proc_root
);
547 for (i
= 0; i
< IP2_MAX_BOARDS
; i
++) {
549 if ((pB
= i2BoardPtrTable
[i
]) != 0 ) {
551 i2BoardPtrTable
[i
] = NULL
;
553 if ((DevTableMem
[i
]) != NULL
) {
554 kfree ( DevTableMem
[i
] );
555 DevTableMem
[i
] = NULL
;
559 /* Cleanup the iiEllis subsystem. */
562 printk (KERN_DEBUG
"IP2 Unloaded\n" );
567 /******************************************************************************/
568 /* Function: old_ip2_init() */
569 /* Parameters: irq, io from command line of insmod et. al. */
570 /* Returns: Success (0) */
573 /* This was the required entry point for all drivers (now in ip2.c) */
574 /* It performs all */
575 /* initialisation of the devices and driver structures, and registers itself */
576 /* with the relevant kernel modules. */
577 /******************************************************************************/
578 /* SA_INTERRUPT- if set blocks all interrupts else only this line */
579 /* SA_SHIRQ - for shared irq PCI or maybe EISA only */
580 /* SA_RANDOM - can be source for cert. random number generators */
581 #define IP2_SA_FLAGS 0
586 #ifdef CONFIG_DEVFS_FS
587 static devfs_handle_t devfs_handle
;
594 i2eBordStrPtr pB
= NULL
;
597 #ifdef IP2DEBUG_TRACE
598 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, ITRC_ENTER
, 0 );
601 /* Announce our presence */
602 printk( KERN_INFO
"%s version %s\n", pcName
, pcVersion
);
604 // ip2 can be unloaded and reloaded for no good reason
605 // we can't let that happen here or bad things happen
606 // second load hoses board but not system - fixme later
608 printk( KERN_INFO
"Still loaded\n" );
613 /* if all irq config is zero we shall poll_only */
614 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
615 poll_only
|= ip2config
.irq
[i
];
617 poll_only
= !poll_only
;
619 /* Initialise the iiEllis subsystem. */
622 /* Initialize arrays. */
623 memset( i2BoardPtrTable
, 0, sizeof i2BoardPtrTable
);
624 memset( DevTable
, 0, sizeof DevTable
);
625 memset( TtyTable
, 0, sizeof TtyTable
);
626 memset( Termios
, 0, sizeof Termios
);
627 memset( TermiosLocked
, 0, sizeof TermiosLocked
);
629 /* Initialise all the boards we can find (up to the maximum). */
630 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
631 switch ( ip2config
.addr
[i
] ) {
632 case 0: /* skip this slot even if card is present */
635 /* ISA address must be specified */
636 if ( (ip2config
.addr
[i
] < 0x100) || (ip2config
.addr
[i
] > 0x3f8) ) {
637 printk ( KERN_ERR
"IP2: Bad ISA board %d address %x\n",
638 i
, ip2config
.addr
[i
] );
639 ip2config
.addr
[i
] = 0;
641 ip2config
.type
[i
] = ISA
;
643 /* Check for valid irq argument, set for polling if invalid */
644 if (ip2config
.irq
[i
] && !is_valid_irq(ip2config
.irq
[i
])) {
645 printk(KERN_ERR
"IP2: Bad IRQ(%d) specified\n",ip2config
.irq
[i
]);
646 ip2config
.irq
[i
] = 0;// 0 is polling and is valid in that sense
652 #if (LINUX_VERSION_CODE < 0x020163) /* 2.1.99 */
653 if (pcibios_present()) {
654 unsigned char pci_bus
, pci_devfn
;
656 status
= pcibios_find_device(PCI_VENDOR_ID_COMPUTONE
,
657 PCI_DEVICE_ID_COMPUTONE_IP2EX
, Pci_index
,
658 &pci_bus
, &pci_devfn
);
661 unsigned char pci_irq
;
663 ip2config
.type
[i
] = PCI
;
665 * Update Pci_index, so that the next time we go
666 * searching for a PCI board we find a different
671 pcibios_read_config_dword(pci_bus
, pci_devfn
,
672 PCI_BASE_ADDRESS_1
, &addr
);
674 ip2config
.addr
[i
]=(USHORT
)(addr
&0xfffe);
676 printk( KERN_ERR
"IP2: PCI I/O address error\n");
678 pcibios_read_config_byte(pci_bus
, pci_devfn
,
679 PCI_INTERRUPT_LINE
, &pci_irq
);
681 if (!is_valid_irq(pci_irq
)) {
682 printk( KERN_ERR
"IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq
);
685 ip2config
.irq
[i
] = pci_irq
;
686 } else { // ann error
687 ip2config
.addr
[i
] = 0;
688 if (status
== PCIBIOS_DEVICE_NOT_FOUND
) {
689 printk( KERN_ERR
"IP2: PCI board %d not found\n", i
);
691 pcibios_strerror(status
);
695 #else /* LINUX_VERSION_CODE > 2.1.99 */
697 struct pci_dev
*pci_dev_i
= NULL
;
698 pci_dev_i
= pci_find_device(PCI_VENDOR_ID_COMPUTONE
,
699 PCI_DEVICE_ID_COMPUTONE_IP2EX
, pci_dev_i
);
700 if (pci_dev_i
!= NULL
) {
702 unsigned char pci_irq
;
704 ip2config
.type
[i
] = PCI
;
706 pci_read_config_dword(pci_dev_i
, PCI_BASE_ADDRESS_1
, &addr
);
708 ip2config
.addr
[i
]=(USHORT
)(addr
&0xfffe);
710 printk( KERN_ERR
"IP2: PCI I/O address error\n");
713 pci_read_config_byte(pci_dev_i
, PCI_INTERRUPT_LINE
, &pci_irq
);
715 if (!is_valid_irq(pci_irq
)) {
716 printk( KERN_ERR
"IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq
);
719 ip2config
.irq
[i
] = pci_irq
;
720 } else { // ann error
721 ip2config
.addr
[i
] = 0;
722 if (status
== PCIBIOS_DEVICE_NOT_FOUND
) {
723 printk( KERN_ERR
"IP2: PCI board %d not found\n", i
);
725 pcibios_strerror(status
);
731 printk( KERN_ERR
"IP2: PCI card specified but PCI support not\n");
732 printk( KERN_ERR
"IP2: configured in this kernel.\n");
733 printk( KERN_ERR
"IP2: Recompile kernel with CONFIG_PCI defined!\n");
734 #endif /* CONFIG_PCI */
737 if ( (ip2config
.addr
[i
] = find_eisa_board( Eisa_slot
+ 1 )) != 0) {
738 /* Eisa_irq set as side effect, boo */
739 ip2config
.type
[i
] = EISA
;
741 ip2config
.irq
[i
] = Eisa_irq
;
745 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
746 if ( ip2config
.addr
[i
] ) {
747 pB
= kmalloc( sizeof(i2eBordStr
), GFP_KERNEL
);
749 i2BoardPtrTable
[i
] = pB
;
750 memset( pB
, 0, sizeof(i2eBordStr
) );
751 iiSetAddress( pB
, ip2config
.addr
[i
], ii2DelayTimer
);
754 printk(KERN_ERR
"IP2: board memory allocation error\n");
758 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
759 if ( ( pB
= i2BoardPtrTable
[i
] ) != NULL
) {
764 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
765 if ( i2BoardPtrTable
[i
] != NULL
) {
770 #ifdef IP2DEBUG_TRACE
771 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, 2, 0 );
774 /* Zero out the normal tty device structure. */
775 memset ( &ip2_tty_driver
, 0, sizeof ip2_tty_driver
);
777 /* Initialise the relevant fields. */
778 ip2_tty_driver
.magic
= TTY_DRIVER_MAGIC
;
779 ip2_tty_driver
.name
= pcTty
;
780 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
781 ip2_tty_driver
.driver_name
= pcDriver_name
;
782 ip2_tty_driver
.read_proc
= ip2_read_proc
;
784 ip2_tty_driver
.major
= IP2_TTY_MAJOR
;
785 ip2_tty_driver
.minor_start
= 0;
786 ip2_tty_driver
.num
= IP2_MAX_PORTS
;
787 ip2_tty_driver
.type
= TTY_DRIVER_TYPE_SERIAL
;
788 ip2_tty_driver
.subtype
= SERIAL_TYPE_NORMAL
;
789 ip2_tty_driver
.init_termios
= tty_std_termios
;
790 ip2_tty_driver
.init_termios
.c_cflag
= B9600
|CS8
|CREAD
|HUPCL
|CLOCAL
;
791 #ifdef CONFIG_DEVFS_FS
792 ip2_tty_driver
.flags
= TTY_DRIVER_REAL_RAW
| TTY_DRIVER_NO_DEVFS
;
794 ip2_tty_driver
.flags
= TTY_DRIVER_REAL_RAW
;
796 ip2_tty_driver
.refcount
= &ref_count
;
797 ip2_tty_driver
.table
= TtyTable
;
798 ip2_tty_driver
.termios
= Termios
;
799 ip2_tty_driver
.termios_locked
= TermiosLocked
;
801 /* Setup the pointers to the implemented functions. */
802 ip2_tty_driver
.open
= ip2_open
;
803 ip2_tty_driver
.close
= ip2_close
;
804 ip2_tty_driver
.write
= ip2_write
;
805 ip2_tty_driver
.put_char
= ip2_putchar
;
806 ip2_tty_driver
.flush_chars
= ip2_flush_chars
;
807 ip2_tty_driver
.write_room
= ip2_write_room
;
808 ip2_tty_driver
.chars_in_buffer
= ip2_chars_in_buf
;
809 ip2_tty_driver
.flush_buffer
= ip2_flush_buffer
;
810 ip2_tty_driver
.ioctl
= ip2_ioctl
;
811 ip2_tty_driver
.throttle
= ip2_throttle
;
812 ip2_tty_driver
.unthrottle
= ip2_unthrottle
;
813 ip2_tty_driver
.set_termios
= ip2_set_termios
;
814 ip2_tty_driver
.set_ldisc
= ip2_set_line_discipline
;
815 ip2_tty_driver
.stop
= ip2_stop
;
816 ip2_tty_driver
.start
= ip2_start
;
817 ip2_tty_driver
.hangup
= ip2_hangup
;
819 /* Initialise the callout driver structure from the tty driver, and
820 * make the needed adjustments.
822 ip2_callout_driver
= ip2_tty_driver
;
823 ip2_callout_driver
.name
= pcCallout
;
824 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
825 ip2_callout_driver
.driver_name
= pcDriver_name
;
826 ip2_callout_driver
.read_proc
= NULL
;
828 ip2_callout_driver
.major
= IP2_CALLOUT_MAJOR
;
829 ip2_callout_driver
.subtype
= SERIAL_TYPE_CALLOUT
;
831 #ifdef IP2DEBUG_TRACE
832 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, 3, 0 );
835 /* Register the tty devices. */
836 if ( ( err
= tty_register_driver ( &ip2_tty_driver
) ) ) {
837 printk(KERN_ERR
"IP2: failed to register tty driver (%d)\n", err
);
839 if ( ( err
= tty_register_driver ( &ip2_callout_driver
) ) ) {
840 printk(KERN_ERR
"IP2: failed to register callout driver (%d)\n", err
);
842 /* Register the IPL driver. */
843 #ifdef CONFIG_DEVFS_FS
844 if (( err
= devfs_register_chrdev ( IP2_IPL_MAJOR
, pcIpl
, &ip2_ipl
)))
846 if ( ( err
= register_chrdev ( IP2_IPL_MAJOR
, pcIpl
, &ip2_ipl
) ) )
849 printk(KERN_ERR
"IP2: failed to register IPL device (%d)\n", err
);
851 /* Register the read_procmem thing */
852 if (!create_proc_info_entry("ip2mem",0,&proc_root
,ip2_read_procmem
)) {
853 printk(KERN_ERR
"IP2: failed to register read_procmem\n");
856 #ifdef IP2DEBUG_TRACE
857 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, 4, 0 );
859 /* Register the interrupt handler or poll handler, depending upon the
860 * specified interrupt.
862 #ifdef CONFIG_DEVFS_FS
864 devfs_handle
= devfs_mk_dir (NULL
, "ip2", NULL
);
867 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
868 #ifdef CONFIG_DEVFS_FS
872 if ( 0 == ip2config
.addr
[i
] ) {
876 #ifdef CONFIG_DEVFS_FS
877 sprintf( name
, "ipl%d", i
);
878 i2BoardPtrTable
[i
]->devfs_ipl_handle
=
879 devfs_register (devfs_handle
, name
,
881 IP2_IPL_MAJOR
, 4 * i
,
882 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IFCHR
,
885 sprintf( name
, "stat%d", i
);
886 i2BoardPtrTable
[i
]->devfs_stat_handle
=
887 devfs_register (devfs_handle
, name
,
889 IP2_IPL_MAJOR
, 4 * i
+ 1,
890 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IFCHR
,
893 for ( box
= 0; box
< ABS_MAX_BOXES
; ++box
)
895 for ( j
= 0; j
< ABS_BIGGEST_BOX
; ++j
)
897 if ( pB
->i2eChannelMap
[box
] & (1 << j
) )
899 tty_register_devfs(&ip2_tty_driver
,
900 0, j
+ ABS_BIGGEST_BOX
*
901 (box
+i
*ABS_MAX_BOXES
));
902 tty_register_devfs(&ip2_callout_driver
,
903 0, j
+ ABS_BIGGEST_BOX
*
904 (box
+i
*ABS_MAX_BOXES
));
911 ip2config
.irq
[i
] = CIR_POLL
;
913 if ( ip2config
.irq
[i
] == CIR_POLL
) {
916 PollTimer
.expires
= POLL_TIMEOUT
;
917 add_timer ( &PollTimer
);
919 printk( KERN_INFO
"IP2: polling\n");
922 if (have_requested_irq(ip2config
.irq
[i
]))
924 rc
= request_irq( ip2config
.irq
[i
], ip2_interrupt
,
925 IP2_SA_FLAGS
| (ip2config
.type
[i
] == PCI
? SA_SHIRQ
: 0),
926 pcName
, (void *)&pcName
);
928 printk(KERN_ERR
"IP2: an request_irq failed: error %d\n",rc
);
929 ip2config
.irq
[i
] = CIR_POLL
;
930 printk( KERN_INFO
"IP2: Polling %ld/sec.\n",
931 (POLL_TIMEOUT
- jiffies
));
934 mark_requested_irq(ip2config
.irq
[i
]);
935 /* Initialise the interrupt handler bottom half (aka slih). */
938 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
939 if ( i2BoardPtrTable
[i
] ) {
940 set_irq( i
, ip2config
.irq
[i
] ); /* set and enable board interrupt */
944 #ifdef IP2DEBUG_TRACE
945 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, ITRC_RETURN
, 0 );
951 /******************************************************************************/
952 /* Function: ip2_init_board() */
953 /* Parameters: Index of board in configuration structure */
954 /* Returns: Success (0) */
957 /* This function initializes the specified board. The loadware is copied to */
958 /* the board, the channel structures are initialized, and the board details */
959 /* are reported on the console. */
960 /******************************************************************************/
962 ip2_init_board( int boardnum
)
965 int nports
= 0, nboxes
= 0;
967 i2eBordStrPtr pB
= i2BoardPtrTable
[boardnum
];
969 if ( !iiInitialize ( pB
) ) {
970 printk ( KERN_ERR
"IP2: Failed to initialize board at 0x%x, error %d\n",
971 pB
->i2eBase
, pB
->i2eError
);
973 i2BoardPtrTable
[boardnum
] = NULL
;
976 printk(KERN_INFO
"Board %d: addr=0x%x irq=%d ", boardnum
+ 1,
977 ip2config
.addr
[boardnum
], ip2config
.irq
[boardnum
] );
979 if (0 != ( rc
= check_region( ip2config
.addr
[boardnum
], 8))) {
980 i2BoardPtrTable
[boardnum
] = NULL
;
981 printk(KERN_ERR
"bad addr=0x%x rc = %d\n",
982 ip2config
.addr
[boardnum
], rc
);
985 request_region( ip2config
.addr
[boardnum
], 8, pcName
);
987 if ( iiDownloadAll ( pB
, (loadHdrStrPtr
)Fip_firmware
, 1, Fip_firmware_size
)
989 printk ( KERN_ERR
"IP2:failed to download loadware " );
991 printk ( KERN_INFO
"fv=%d.%d.%d lv=%d.%d.%d\n",
992 pB
->i2ePom
.e
.porVersion
,
993 pB
->i2ePom
.e
.porRevision
,
994 pB
->i2ePom
.e
.porSubRev
, pB
->i2eLVersion
,
995 pB
->i2eLRevision
, pB
->i2eLSub
);
998 switch ( pB
->i2ePom
.e
.porID
& ~POR_ID_RESERVED
) {
1001 printk( KERN_ERR
"IP2: Unknown board type, ID = %x",
1002 pB
->i2ePom
.e
.porID
);
1007 case POR_ID_II_4
: /* IntelliPort-II, ISA-4 (4xRJ45) */
1008 printk ( KERN_INFO
"ISA-4" );
1012 case POR_ID_II_8
: /* IntelliPort-II, 8-port using standard brick. */
1013 printk ( KERN_INFO
"ISA-8 std" );
1017 case POR_ID_II_8R
: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
1018 printk ( KERN_INFO
"ISA-8 RJ11" );
1022 case POR_ID_FIIEX
: /* IntelliPort IIEX */
1024 int portnum
= IP2_PORTS_PER_BOARD
* boardnum
;
1027 for( box
= 0; box
< ABS_MAX_BOXES
; ++box
) {
1028 if ( pB
->i2eChannelMap
[box
] != 0 ) {
1031 for( i
= 0; i
< ABS_BIGGEST_BOX
; ++i
) {
1032 if ( pB
->i2eChannelMap
[box
] & 1<< i
) {
1037 DevTableMem
[boardnum
] = pCh
=
1038 kmalloc( sizeof(i2ChanStr
) * nports
, GFP_KERNEL
);
1039 if ( !i2InitChannels( pB
, nports
, pCh
) ) {
1040 printk(KERN_ERR
"i2InitChannels failed: %d\n",pB
->i2eError
);
1042 pB
->i2eChannelPtr
= &DevTable
[portnum
];
1043 pB
->i2eChannelCnt
= ABS_MOST_PORTS
;
1045 for( box
= 0; box
< ABS_MAX_BOXES
; ++box
, portnum
+= ABS_BIGGEST_BOX
) {
1046 for( i
= 0; i
< ABS_BIGGEST_BOX
; ++i
) {
1047 if ( pB
->i2eChannelMap
[box
] & (1 << i
) ) {
1048 DevTable
[portnum
+ i
] = pCh
;
1049 pCh
->port_index
= portnum
+ i
;
1054 printk(KERN_INFO
"IP2: EX box=%d ports=%d %d bit",
1055 nboxes
, nports
, pB
->i2eDataWidth16
? 16 : 8 );
1060 DevTableMem
[boardnum
] = pCh
=
1061 kmalloc ( sizeof (i2ChanStr
) * nports
, GFP_KERNEL
);
1062 pB
->i2eChannelPtr
= pCh
;
1063 pB
->i2eChannelCnt
= nports
;
1064 i2InitChannels ( pB
, pB
->i2eChannelCnt
, pCh
);
1065 pB
->i2eChannelPtr
= &DevTable
[IP2_PORTS_PER_BOARD
* boardnum
];
1067 for( i
= 0; i
< pB
->i2eChannelCnt
; ++i
) {
1068 DevTable
[IP2_PORTS_PER_BOARD
* boardnum
+ i
] = pCh
;
1069 pCh
->port_index
= (IP2_PORTS_PER_BOARD
* boardnum
) + i
;
1073 printk ( KERN_INFO
"\n" );
1076 /******************************************************************************/
1077 /* Function: find_eisa_board ( int start_slot ) */
1078 /* Parameters: First slot to check */
1079 /* Returns: Address of EISA IntelliPort II controller */
1082 /* This function searches for an EISA IntelliPort controller, starting */
1083 /* from the specified slot number. If the motherboard is not identified as an */
1084 /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
1085 /* it returns the base address of the controller. */
1086 /******************************************************************************/
1087 static unsigned short __init
1088 find_eisa_board( int start_slot
)
1091 unsigned int idm
= 0;
1092 unsigned int idp
= 0;
1093 unsigned int base
= 0;
1100 * First a check for an EISA motherboard, which we do by comparing the
1101 * EISA ID registers for the system board and the first couple of slots.
1102 * No slot ID should match the system board ID, but on an ISA or PCI
1103 * machine the odds are that an empty bus will return similar values for
1107 value
= (inb(i
) << 24) + (inb(i
+1) << 16) + (inb(i
+2) << 8) + inb(i
+3);
1108 for( i
= 0x1c80; i
<= 0x4c80; i
+= 0x1000 ) {
1109 j
= (inb(i
)<<24)+(inb(i
+1)<<16)+(inb(i
+2)<<8)+inb(i
+3);
1115 * OK, so we are inclined to believe that this is an EISA machine. Find
1116 * an IntelliPort controller.
1118 for( i
= start_slot
; i
< 16; i
++ ) {
1120 idm
= (inb(base
+ 0xc80) << 8) | (inb(base
+ 0xc81) & 0xff);
1121 idp
= (inb(base
+ 0xc82) << 8) | (inb(base
+ 0xc83) & 0xff);
1123 if ( idm
== 0x0e8e ) {
1124 if ( idp
== 0x0281 || idp
== 0x0218 ) {
1126 } else if ( idp
== 0x0282 || idp
== 0x0283 ) {
1127 ismine
= 3; /* Can do edge-trigger */
1138 /* It's some sort of EISA card, but at what address is it configured? */
1140 setup_address
= base
+ 0xc88;
1141 value
= inb(base
+ 0xc86);
1142 setup_irq
= (value
& 8) ? Valid_Irqs
[value
& 7] : 0;
1144 if ( (ismine
& 2) && !(value
& 0x10) ) {
1145 ismine
= 1; /* Could be edging, but not */
1148 if ( Eisa_irq
== 0 ) {
1149 Eisa_irq
= setup_irq
;
1150 } else if ( Eisa_irq
!= setup_irq
) {
1151 printk ( KERN_ERR
"IP2: EISA irq mismatch between EISA controllers\n" );
1154 #ifdef IP2DEBUG_INIT
1155 printk(KERN_DEBUG
"Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
1156 base
>> 12, idm
, idp
, setup_address
);
1158 printk(KERN_DEBUG
", Interrupt %d %s\n",
1159 setup_irq
, (ismine
& 2) ? "(edge)" : "(level)");
1161 printk(KERN_DEBUG
", (polled)\n");
1164 return setup_address
;
1167 /******************************************************************************/
1168 /* Function: set_irq() */
1169 /* Parameters: index to board in board table */
1171 /* Returns: Success (0) */
1174 /******************************************************************************/
1176 set_irq( int boardnum
, int boardIrq
)
1178 unsigned char tempCommand
[16];
1179 i2eBordStrPtr pB
= i2BoardPtrTable
[boardnum
];
1180 unsigned long flags
;
1183 * Notify the boards they may generate interrupts. This is done by
1184 * sending an in-line command to channel 0 on each board. This is why
1185 * the channels have to be defined already. For each board, if the
1186 * interrupt has never been defined, we must do so NOW, directly, since
1187 * board will not send flow control or even give an interrupt until this
1188 * is done. If polling we must send 0 as the interrupt parameter.
1191 // We will get an interrupt here at the end of this function
1193 iiDisableMailIrq(pB
);
1195 /* We build up the entire packet header. */
1196 CHANNEL_OF(tempCommand
) = 0;
1197 PTYPE_OF(tempCommand
) = PTYPE_INLINE
;
1198 CMD_COUNT_OF(tempCommand
) = 2;
1199 (CMD_OF(tempCommand
))[0] = CMDVALUE_IRQ
;
1200 (CMD_OF(tempCommand
))[1] = boardIrq
;
1202 * Write to FIFO; don't bother to adjust fifo capacity for this, since
1203 * board will respond almost immediately after SendMail hit.
1205 WRITE_LOCK_IRQSAVE(&pB
->write_fifo_spinlock
,flags
);
1206 iiWriteBuf(pB
, tempCommand
, 4);
1207 WRITE_UNLOCK_IRQRESTORE(&pB
->write_fifo_spinlock
,flags
);
1208 pB
->i2eUsingIrq
= boardIrq
;
1209 pB
->i2eOutMailWaiting
|= MB_OUT_STUFFED
;
1211 /* Need to update number of boards before you enable mailbox int */
1214 CHANNEL_OF(tempCommand
) = 0;
1215 PTYPE_OF(tempCommand
) = PTYPE_BYPASS
;
1216 CMD_COUNT_OF(tempCommand
) = 6;
1217 (CMD_OF(tempCommand
))[0] = 88; // SILO
1218 (CMD_OF(tempCommand
))[1] = 64; // chars
1219 (CMD_OF(tempCommand
))[2] = 32; // ms
1221 (CMD_OF(tempCommand
))[3] = 28; // MAX_BLOCK
1222 (CMD_OF(tempCommand
))[4] = 64; // chars
1224 (CMD_OF(tempCommand
))[5] = 87; // HW_TEST
1225 WRITE_LOCK_IRQSAVE(&pB
->write_fifo_spinlock
,flags
);
1226 iiWriteBuf(pB
, tempCommand
, 8);
1227 WRITE_UNLOCK_IRQRESTORE(&pB
->write_fifo_spinlock
,flags
);
1229 CHANNEL_OF(tempCommand
) = 0;
1230 PTYPE_OF(tempCommand
) = PTYPE_BYPASS
;
1231 CMD_COUNT_OF(tempCommand
) = 1;
1232 (CMD_OF(tempCommand
))[0] = 84; /* get BOX_IDS */
1233 iiWriteBuf(pB
, tempCommand
, 3);
1236 // enable heartbeat for test porpoises
1237 CHANNEL_OF(tempCommand
) = 0;
1238 PTYPE_OF(tempCommand
) = PTYPE_BYPASS
;
1239 CMD_COUNT_OF(tempCommand
) = 2;
1240 (CMD_OF(tempCommand
))[0] = 44; /* get ping */
1241 (CMD_OF(tempCommand
))[1] = 200; /* 200 ms */
1242 WRITE_LOCK_IRQSAVE(&pB
->write_fifo_spinlock
,flags
);
1243 iiWriteBuf(pB
, tempCommand
, 4);
1244 WRITE_UNLOCK_IRQRESTORE(&pB
->write_fifo_spinlock
,flags
);
1247 iiEnableMailIrq(pB
);
1248 iiSendPendingMail(pB
);
1251 /******************************************************************************/
1252 /* Interrupt Handler Section */
1253 /******************************************************************************/
1256 service_all_boards()
1261 /* Service every board on the list */
1262 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
1263 pB
= i2BoardPtrTable
[i
];
1265 i2ServiceBoard( pB
);
1272 static struct tq_struct
1274 { // it's the death that worse than fate
1277 (void(*)(void*)) service_all_boards
,
1278 NULL
, //later - board address XXX
1282 /******************************************************************************/
1283 /* Function: ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs) */
1284 /* Parameters: irq - interrupt number */
1285 /* pointer to optional device ID structure */
1286 /* pointer to register structure */
1287 /* Returns: Nothing */
1292 /******************************************************************************/
1294 ip2_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
)
1299 #ifdef IP2DEBUG_TRACE
1300 ip2trace (ITRC_NO_PORT
, ITRC_INTR
, 99, 1, irq
);
1305 queue_task(&senior_service
, &tq_immediate
);
1306 mark_bh(IMMEDIATE_BH
);
1309 /* Service just the boards on the list using this irq */
1310 for( i
= 0; i
< i2nBoards
; ++i
) {
1311 pB
= i2BoardPtrTable
[i
];
1312 if ( pB
&& (pB
->i2eUsingIrq
== irq
) ) {
1313 i2ServiceBoard( pB
);
1317 #endif /* USE_IQI */
1321 #ifdef IP2DEBUG_TRACE
1322 ip2trace (ITRC_NO_PORT
, ITRC_INTR
, ITRC_RETURN
, 0 );
1326 /******************************************************************************/
1327 /* Function: ip2_poll(unsigned long arg) */
1329 /* Returns: Nothing */
1332 /* This function calls the library routine i2ServiceBoard for each board in */
1333 /* the board table. This is used instead of the interrupt routine when polled */
1334 /* mode is specified. */
1335 /******************************************************************************/
1337 ip2_poll(unsigned long arg
)
1339 #ifdef IP2DEBUG_TRACE
1340 ip2trace (ITRC_NO_PORT
, ITRC_INTR
, 100, 0 );
1342 TimerOn
= 0; // it's the truth but not checked in service
1348 queue_task(&senior_service
, &tq_immediate
);
1349 mark_bh(IMMEDIATE_BH
);
1352 // Just polled boards, service_all might be better
1353 ip2_interrupt(0, NULL
, NULL
);
1355 #endif /* USE_IQI */
1357 PollTimer
.expires
= POLL_TIMEOUT
;
1358 add_timer( &PollTimer
);
1361 #ifdef IP2DEBUG_TRACE
1362 ip2trace (ITRC_NO_PORT
, ITRC_INTR
, ITRC_RETURN
, 0 );
1367 do_input( i2ChanStrPtr pCh
)
1369 unsigned long flags
;
1371 #ifdef IP2DEBUG_TRACE
1372 ip2trace(CHANN
, ITRC_INPUT
, 21, 0 );
1375 if ( pCh
->pTTY
!= NULL
) {
1376 READ_LOCK_IRQSAVE(&pCh
->Ibuf_spinlock
,flags
)
1377 if (!pCh
->throttled
&& (pCh
->Ibuf_stuff
!= pCh
->Ibuf_strip
)) {
1378 READ_UNLOCK_IRQRESTORE(&pCh
->Ibuf_spinlock
,flags
)
1381 READ_UNLOCK_IRQRESTORE(&pCh
->Ibuf_spinlock
,flags
)
1383 #ifdef IP2DEBUG_TRACE
1384 ip2trace(CHANN
, ITRC_INPUT
, 22, 0 );
1386 i2InputFlush( pCh
);
1390 // code duplicated from n_tty (ldisc)
1392 isig(int sig
, struct tty_struct
*tty
, int flush
)
1395 kill_pg(tty
->pgrp
, sig
, 1);
1396 if (flush
|| !L_NOFLSH(tty
)) {
1397 if ( tty
->ldisc
.flush_buffer
)
1398 tty
->ldisc
.flush_buffer(tty
);
1399 i2InputFlush( tty
->driver_data
);
1404 do_status( i2ChanStrPtr pCh
)
1408 status
= i2GetStatus( pCh
, (I2_BRK
|I2_PAR
|I2_FRA
|I2_OVR
) );
1410 #ifdef IP2DEBUG_TRACE
1411 ip2trace (CHANN
, ITRC_STATUS
, 21, 1, status
);
1414 if (pCh
->pTTY
&& (status
& (I2_BRK
|I2_PAR
|I2_FRA
|I2_OVR
)) ) {
1415 if ( (status
& I2_BRK
) ) {
1416 // code duplicated from n_tty (ldisc)
1417 if (I_IGNBRK(pCh
->pTTY
))
1419 if (I_BRKINT(pCh
->pTTY
)) {
1420 isig(SIGINT
, pCh
->pTTY
, 1);
1423 wake_up_interruptible(&pCh
->pTTY
->read_wait
);
1425 #ifdef NEVER_HAPPENS_AS_SETUP_XXX
1426 // and can't work because we don't know the_char
1427 // as the_char is reported on a seperate path
1428 // The intelligent board does this stuff as setup
1430 char brkf
= TTY_NORMAL
;
1431 unsigned char brkc
= '\0';
1433 if ( (status
& I2_BRK
) ) {
1437 else if (status
& I2_PAR
) {
1440 } else if (status
& I2_FRA
) {
1443 } else if (status
& I2_OVR
) {
1447 tmp
= pCh
->pTTY
->real_raw
;
1448 pCh
->pTTY
->real_raw
= 0;
1449 pCh
->pTTY
->ldisc
.receive_buf( pCh
->pTTY
, &brkc
, &brkf
, 1 );
1450 pCh
->pTTY
->real_raw
= tmp
;
1452 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1456 if ( status
& (I2_DDCD
| I2_DDSR
| I2_DCTS
| I2_DRI
) ) {
1457 wake_up_interruptible(&pCh
->delta_msr_wait
);
1459 if ( (pCh
->flags
& ASYNC_CHECK_CD
) && (status
& I2_DDCD
) ) {
1460 if ( status
& I2_DCD
) {
1462 wake_up_interruptible ( &pCh
->open_wait
);
1464 } else if ( !(pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) ) {
1465 if (pCh
->pTTY
&& (!(pCh
->pTTY
->termios
->c_cflag
& CLOCAL
)) ) {
1466 tty_hangup( pCh
->pTTY
);
1472 #ifdef IP2DEBUG_TRACE
1473 ip2trace (CHANN
, ITRC_STATUS
, 26, 0 );
1477 /******************************************************************************/
1478 /* Device Open/Close/Ioctl Entry Point Section */
1479 /******************************************************************************/
1481 /******************************************************************************/
1482 /* Function: open_sanity_check() */
1483 /* Parameters: Pointer to tty structure */
1484 /* Pointer to file structure */
1485 /* Returns: Success or failure */
1488 /* Verifies the structure magic numbers and cross links. */
1489 /******************************************************************************/
1490 #ifdef IP2DEBUG_OPEN
1492 open_sanity_check( i2ChanStrPtr pCh
, i2eBordStrPtr pBrd
)
1494 if ( pBrd
->i2eValid
!= I2E_MAGIC
) {
1495 printk(KERN_ERR
"IP2: invalid board structure\n" );
1496 } else if ( pBrd
!= pCh
->pMyBord
) {
1497 printk(KERN_ERR
"IP2: board structure pointer mismatch (%p)\n",
1499 } else if ( pBrd
->i2eChannelCnt
< pCh
->port_index
) {
1500 printk(KERN_ERR
"IP2: bad device index (%d)\n", pCh
->port_index
);
1501 } else if (&((i2ChanStrPtr
)pBrd
->i2eChannelPtr
)[pCh
->port_index
] != pCh
) {
1503 printk(KERN_INFO
"IP2: all pointers check out!\n" );
1509 /******************************************************************************/
1510 /* Function: ip2_open() */
1511 /* Parameters: Pointer to tty structure */
1512 /* Pointer to file structure */
1513 /* Returns: Success or failure */
1515 /* Description: (MANDATORY) */
1516 /* A successful device open has to run a gauntlet of checks before it */
1517 /* completes. After some sanity checking and pointer setup, the function */
1518 /* blocks until all conditions are satisfied. It then initialises the port to */
1519 /* the default characteristics and returns. */
1520 /******************************************************************************/
1522 ip2_open( PTTY tty
, struct file
*pFile
)
1526 i2ChanStrPtr pCh
= DevTable
[MINOR(tty
->device
)];
1528 #ifdef IP2DEBUG_TRACE
1529 ip2trace (MINOR(tty
->device
), ITRC_OPEN
, ITRC_ENTER
, 0 );
1532 if ( pCh
== NULL
) {
1535 /* Setup pointer links in device and tty structures */
1537 tty
->driver_data
= pCh
;
1540 #ifdef IP2DEBUG_OPEN
1542 "IP2:open(tty=%p,pFile=%p):dev=%x,maj=%d,min=%d,ch=%d,idx=%d\n",
1543 tty
, pFile
, tty
->device
, MAJOR(tty
->device
), MINOR(tty
->device
),
1544 pCh
->infl
.hd
.i2sChannel
, pCh
->port_index
);
1545 open_sanity_check ( pCh
, pCh
->pMyBord
);
1548 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 3, CMD_DTRUP
,CMD_RTSUP
,CMD_DCD_REP
);
1549 pCh
->dataSetOut
|= (I2_DTR
| I2_RTS
);
1550 serviceOutgoingFifo( pCh
->pMyBord
);
1552 /* Block here until the port is ready (per serial and istallion) */
1554 * 1. If the port is in the middle of closing wait for the completion
1555 * and then return the appropriate error.
1557 if ( tty_hung_up_p(pFile
) || ( pCh
->flags
& ASYNC_CLOSING
)) {
1558 if ( pCh
->flags
& ASYNC_CLOSING
) {
1559 interruptible_sleep_on( &pCh
->close_wait
);
1561 if ( tty_hung_up_p(pFile
) ) {
1562 return( pCh
->flags
& ASYNC_HUP_NOTIFY
) ? -EAGAIN
: -ERESTARTSYS
;
1566 * 2. If this is a callout device, make sure the normal port is not in
1567 * use, and that someone else doesn't have the callout device locked.
1568 * (These are the only tests the standard serial driver makes for
1571 if ( tty
->driver
.subtype
== SERIAL_TYPE_CALLOUT
) {
1572 if ( pCh
->flags
& ASYNC_NORMAL_ACTIVE
) {
1575 if ( ( pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1576 ( pCh
->flags
& ASYNC_SESSION_LOCKOUT
) &&
1577 ( pCh
->session
!= current
->session
) ) {
1580 if ( ( pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1581 ( pCh
->flags
& ASYNC_PGRP_LOCKOUT
) &&
1582 ( pCh
->pgrp
!= current
->pgrp
) ) {
1585 pCh
->flags
|= ASYNC_CALLOUT_ACTIVE
;
1589 * 3. Handle a non-blocking open of a normal port.
1591 if ( (pFile
->f_flags
& O_NONBLOCK
) || (tty
->flags
& (1<<TTY_IO_ERROR
) )) {
1592 if ( pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) {
1595 pCh
->flags
|= ASYNC_NORMAL_ACTIVE
;
1599 * 4. Now loop waiting for the port to be free and carrier present
1602 if ( pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) {
1603 if ( pCh
->NormalTermios
.c_cflag
& CLOCAL
) {
1607 if ( tty
->termios
->c_cflag
& CLOCAL
) {
1612 #ifdef IP2DEBUG_OPEN
1613 printk(KERN_DEBUG
"OpenBlock: do_clocal = %d\n", do_clocal
);
1618 if ( !(pCh
->flags
& ASYNC_CALLOUT_ACTIVE
)) {
1619 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 2, CMD_DTRUP
, CMD_RTSUP
);
1620 pCh
->dataSetOut
|= (I2_DTR
| I2_RTS
);
1621 serviceOutgoingFifo( pCh
->pMyBord
);
1623 if ( tty_hung_up_p(pFile
) ) {
1624 return ( pCh
->flags
& ASYNC_HUP_NOTIFY
) ? -EBUSY
: -ERESTARTSYS
;
1626 if ( !(pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1627 !(pCh
->flags
& ASYNC_CLOSING
) &&
1628 (do_clocal
|| (pCh
->dataSetIn
& I2_DCD
) )) {
1633 #ifdef IP2DEBUG_OPEN
1634 printk(KERN_DEBUG
"ASYNC_CALLOUT_ACTIVE = %s\n",
1635 (pCh
->flags
& ASYNC_CALLOUT_ACTIVE
)?"True":"False");
1636 printk(KERN_DEBUG
"ASYNC_CLOSING = %s\n",
1637 (pCh
->flags
& ASYNC_CLOSING
)?"True":"False");
1638 printk(KERN_DEBUG
"OpenBlock: waiting for CD or signal\n");
1640 #ifdef IP2DEBUG_TRACE
1641 ip2trace (CHANN
, ITRC_OPEN
, 3, 2, (pCh
->flags
& ASYNC_CALLOUT_ACTIVE
),
1642 (pCh
->flags
& ASYNC_CLOSING
) );
1644 /* check for signal */
1645 if (signal_pending(current
)) {
1646 rc
= (( pCh
->flags
& ASYNC_HUP_NOTIFY
) ? -EAGAIN
: -ERESTARTSYS
);
1649 interruptible_sleep_on(&pCh
->open_wait
);
1651 --pCh
->wopen
; //why count?
1652 #ifdef IP2DEBUG_TRACE
1653 ip2trace (CHANN
, ITRC_OPEN
, 4, 0 );
1658 pCh
->flags
|= ASYNC_NORMAL_ACTIVE
;
1662 /* first open - Assign termios structure to port */
1663 if ( tty
->count
== 1 ) {
1664 i2QueueCommands(PTYPE_INLINE
, pCh
, 0, 2, CMD_CTSFL_DSAB
, CMD_RTSFL_DSAB
);
1665 if ( pCh
->flags
& ASYNC_SPLIT_TERMIOS
) {
1666 if ( tty
->driver
.subtype
== SERIAL_TYPE_NORMAL
) {
1667 *tty
->termios
= pCh
->NormalTermios
;
1669 *tty
->termios
= pCh
->CalloutTermios
;
1672 /* Now we must send the termios settings to the loadware */
1673 set_params( pCh
, NULL
);
1676 /* override previous and never reset ??? */
1677 pCh
->session
= current
->session
;
1678 pCh
->pgrp
= current
->pgrp
;
1681 * Now set any i2lib options. These may go away if the i2lib code ends
1682 * up rolled into the mainline.
1684 pCh
->channelOptions
|= CO_NBLOCK_WRITE
;
1686 #ifdef IP2DEBUG_OPEN
1687 printk (KERN_DEBUG
"IP2: open completed\n" );
1689 serviceOutgoingFifo( pCh
->pMyBord
);
1691 #ifdef IP2DEBUG_TRACE
1692 ip2trace (CHANN
, ITRC_OPEN
, ITRC_RETURN
, 0 );
1697 /******************************************************************************/
1698 /* Function: ip2_close() */
1699 /* Parameters: Pointer to tty structure */
1700 /* Pointer to file structure */
1701 /* Returns: Nothing */
1706 /******************************************************************************/
1708 ip2_close( PTTY tty
, struct file
*pFile
)
1710 i2ChanStrPtr pCh
= tty
->driver_data
;
1716 #ifdef IP2DEBUG_TRACE
1717 ip2trace (CHANN
, ITRC_CLOSE
, ITRC_ENTER
, 0 );
1720 #ifdef IP2DEBUG_OPEN
1721 printk(KERN_DEBUG
"IP2:close ttyF%02X:\n",MINOR(tty
->device
));
1724 if ( tty_hung_up_p ( pFile
) ) {
1727 #ifdef IP2DEBUG_TRACE
1728 ip2trace (CHANN
, ITRC_CLOSE
, 2, 1, 2 );
1732 if ( tty
->count
> 1 ) { /* not the last close */
1734 #ifdef IP2DEBUG_TRACE
1735 ip2trace (CHANN
, ITRC_CLOSE
, 2, 1, 3 );
1739 pCh
->flags
|= ASYNC_CLOSING
; // last close actually
1742 * Save the termios structure, since this port may have separate termios
1743 * for callout and dialin.
1745 if (pCh
->flags
& ASYNC_NORMAL_ACTIVE
)
1746 pCh
->NormalTermios
= *tty
->termios
;
1747 if (pCh
->flags
& ASYNC_CALLOUT_ACTIVE
)
1748 pCh
->CalloutTermios
= *tty
->termios
;
1752 if (pCh
->ClosingWaitTime
!= ASYNC_CLOSING_WAIT_NONE
) {
1754 * Before we drop DTR, make sure the transmitter has completely drained.
1755 * This uses an timeout, after which the close
1758 ip2_wait_until_sent(tty
, pCh
->ClosingWaitTime
);
1761 * At this point we stop accepting input. Here we flush the channel
1762 * input buffer which will allow the board to send up more data. Any
1763 * additional input is tossed at interrupt/poll time.
1765 i2InputFlush( pCh
);
1767 /* disable DSS reporting */
1768 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 4,
1769 CMD_DCD_NREP
, CMD_CTS_NREP
, CMD_DSR_NREP
, CMD_RI_NREP
);
1770 if ( !tty
|| (tty
->termios
->c_cflag
& HUPCL
) ) {
1771 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 2, CMD_RTSDN
, CMD_DTRDN
);
1772 pCh
->dataSetOut
&= ~(I2_DTR
| I2_RTS
);
1773 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_PAUSE(25));
1776 serviceOutgoingFifo ( pCh
->pMyBord
);
1778 if ( tty
->driver
.flush_buffer
)
1779 tty
->driver
.flush_buffer(tty
);
1780 if ( tty
->ldisc
.flush_buffer
)
1781 tty
->ldisc
.flush_buffer(tty
);
1787 if (pCh
->ClosingDelay
) {
1788 current
->state
= TASK_INTERRUPTIBLE
;
1789 schedule_timeout(pCh
->ClosingDelay
);
1791 wake_up_interruptible(&pCh
->open_wait
);
1794 pCh
->flags
&=~(ASYNC_NORMAL_ACTIVE
|ASYNC_CALLOUT_ACTIVE
|ASYNC_CLOSING
);
1795 wake_up_interruptible(&pCh
->close_wait
);
1797 #ifdef IP2DEBUG_OPEN
1798 DBG_CNT("ip2_close: after wakeups--");
1803 #ifdef IP2DEBUG_TRACE
1804 ip2trace (CHANN
, ITRC_CLOSE
, ITRC_RETURN
, 1, 1 );
1809 /******************************************************************************/
1810 /* Function: ip2_hangup() */
1811 /* Parameters: Pointer to tty structure */
1812 /* Returns: Nothing */
1817 /******************************************************************************/
1819 ip2_hangup ( PTTY tty
)
1821 i2ChanStrPtr pCh
= tty
->driver_data
;
1823 #ifdef IP2DEBUG_TRACE
1824 ip2trace (CHANN
, ITRC_HANGUP
, ITRC_ENTER
, 0 );
1827 ip2_flush_buffer(tty
);
1829 /* disable DSS reporting */
1831 i2QueueCommands(PTYPE_BYPASS
, pCh
, 0, 1, CMD_DCD_NREP
);
1832 i2QueueCommands(PTYPE_INLINE
, pCh
, 0, 2, CMD_CTSFL_DSAB
, CMD_RTSFL_DSAB
);
1833 if ( !tty
|| (tty
->termios
->c_cflag
& HUPCL
) ) {
1834 i2QueueCommands(PTYPE_BYPASS
, pCh
, 0, 2, CMD_RTSDN
, CMD_DTRDN
);
1835 pCh
->dataSetOut
&= ~(I2_DTR
| I2_RTS
);
1836 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_PAUSE(25));
1838 i2QueueCommands(PTYPE_INLINE
, pCh
, 1, 3,
1839 CMD_CTS_NREP
, CMD_DSR_NREP
, CMD_RI_NREP
);
1840 serviceOutgoingFifo ( pCh
->pMyBord
);
1842 wake_up_interruptible ( &pCh
->delta_msr_wait
);
1844 pCh
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CALLOUT_ACTIVE
);
1846 wake_up_interruptible ( &pCh
->open_wait
);
1848 #ifdef IP2DEBUG_TRACE
1849 ip2trace (CHANN
, ITRC_HANGUP
, ITRC_RETURN
, 0 );
1853 /******************************************************************************/
1854 /******************************************************************************/
1855 /* Device Output Section */
1856 /******************************************************************************/
1857 /******************************************************************************/
1859 /******************************************************************************/
1860 /* Function: ip2_write() */
1861 /* Parameters: Pointer to tty structure */
1862 /* Flag denoting data is in user (1) or kernel (0) space */
1863 /* Pointer to data */
1864 /* Number of bytes to write */
1865 /* Returns: Number of bytes actually written */
1867 /* Description: (MANDATORY) */
1870 /******************************************************************************/
1872 ip2_write( PTTY tty
, int user
, const unsigned char *pData
, int count
)
1874 i2ChanStrPtr pCh
= tty
->driver_data
;
1876 unsigned long flags
;
1878 #ifdef IP2DEBUG_TRACE
1879 ip2trace (CHANN
, ITRC_WRITE
, ITRC_ENTER
, 2, count
, -1 );
1882 /* Flush out any buffered data left over from ip2_putchar() calls. */
1883 ip2_flush_chars( tty
);
1885 /* This is the actual move bit. Make sure it does what we need!!!!! */
1886 WRITE_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1887 bytesSent
= i2Output( pCh
, pData
, count
, user
);
1888 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1890 #ifdef IP2DEBUG_TRACE
1891 ip2trace (CHANN
, ITRC_WRITE
, ITRC_RETURN
, 1, bytesSent
);
1893 return bytesSent
> 0 ? bytesSent
: 0;
1896 /******************************************************************************/
1897 /* Function: ip2_putchar() */
1898 /* Parameters: Pointer to tty structure */
1899 /* Character to write */
1900 /* Returns: Nothing */
1905 /******************************************************************************/
1907 ip2_putchar( PTTY tty
, unsigned char ch
)
1909 i2ChanStrPtr pCh
= tty
->driver_data
;
1910 unsigned long flags
;
1912 #ifdef IP2DEBUG_TRACE
1913 // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1916 WRITE_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1917 pCh
->Pbuf
[pCh
->Pbuf_stuff
++] = ch
;
1918 if ( pCh
->Pbuf_stuff
== sizeof pCh
->Pbuf
) {
1919 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1920 ip2_flush_chars( tty
);
1922 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1924 #ifdef IP2DEBUG_TRACE
1925 // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1929 /******************************************************************************/
1930 /* Function: ip2_flush_chars() */
1931 /* Parameters: Pointer to tty structure */
1932 /* Returns: Nothing */
1936 /******************************************************************************/
1938 ip2_flush_chars( PTTY tty
)
1941 i2ChanStrPtr pCh
= tty
->driver_data
;
1942 unsigned long flags
;
1944 WRITE_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1945 if ( pCh
->Pbuf_stuff
) {
1946 #ifdef IP2DEBUG_TRACE
1947 // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1950 // We may need to restart i2Output if it does not fullfill this request
1952 strip
= i2Output( pCh
, pCh
->Pbuf
, pCh
->Pbuf_stuff
, 0 );
1953 if ( strip
!= pCh
->Pbuf_stuff
) {
1954 memmove( pCh
->Pbuf
, &pCh
->Pbuf
[strip
], pCh
->Pbuf_stuff
- strip
);
1956 pCh
->Pbuf_stuff
-= strip
;
1958 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1961 /******************************************************************************/
1962 /* Function: ip2_write_room() */
1963 /* Parameters: Pointer to tty structure */
1964 /* Returns: Number of bytes that the driver can accept */
1968 /******************************************************************************/
1970 ip2_write_room ( PTTY tty
)
1973 i2ChanStrPtr pCh
= tty
->driver_data
;
1974 unsigned long flags
;
1976 READ_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1977 bytesFree
= i2OutputFree( pCh
) - pCh
->Pbuf_stuff
;
1978 READ_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1980 #ifdef IP2DEBUG_TRACE
1981 ip2trace (CHANN
, ITRC_WRITE
, 11, 1, bytesFree
);
1984 return ((bytesFree
> 0) ? bytesFree
: 0);
1987 /******************************************************************************/
1988 /* Function: ip2_chars_in_buf() */
1989 /* Parameters: Pointer to tty structure */
1990 /* Returns: Number of bytes queued for transmission */
1995 /******************************************************************************/
1997 ip2_chars_in_buf ( PTTY tty
)
1999 i2ChanStrPtr pCh
= tty
->driver_data
;
2001 unsigned long flags
;
2002 #ifdef IP2DEBUG_TRACE
2003 ip2trace (CHANN
, ITRC_WRITE
, 12, 1, pCh
->Obuf_char_count
+ pCh
->Pbuf_stuff
);
2005 #ifdef IP2DEBUG_WRITE
2006 printk (KERN_DEBUG
"IP2: chars in buffer = %d (%d,%d)\n",
2007 pCh
->Obuf_char_count
+ pCh
->Pbuf_stuff
,
2008 pCh
->Obuf_char_count
, pCh
->Pbuf_stuff
);
2010 READ_LOCK_IRQSAVE(&pCh
->Obuf_spinlock
,flags
);
2011 rc
= pCh
->Obuf_char_count
;
2012 READ_UNLOCK_IRQRESTORE(&pCh
->Obuf_spinlock
,flags
);
2013 READ_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
2014 rc
+= pCh
->Pbuf_stuff
;
2015 READ_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
2019 /******************************************************************************/
2020 /* Function: ip2_flush_buffer() */
2021 /* Parameters: Pointer to tty structure */
2022 /* Returns: Nothing */
2027 /******************************************************************************/
2029 ip2_flush_buffer( PTTY tty
)
2031 i2ChanStrPtr pCh
= tty
->driver_data
;
2032 unsigned long flags
;
2034 #ifdef IP2DEBUG_TRACE
2035 ip2trace (CHANN
, ITRC_FLUSH
, ITRC_ENTER
, 0 );
2037 #ifdef IP2DEBUG_WRITE
2038 printk (KERN_DEBUG
"IP2: flush buffer\n" );
2040 WRITE_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
2041 pCh
->Pbuf_stuff
= 0;
2042 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
2043 i2FlushOutput( pCh
);
2045 #ifdef IP2DEBUG_TRACE
2046 ip2trace (CHANN
, ITRC_FLUSH
, ITRC_RETURN
, 0 );
2050 /******************************************************************************/
2051 /* Function: ip2_wait_until_sent() */
2052 /* Parameters: Pointer to tty structure */
2053 /* Timeout for wait. */
2054 /* Returns: Nothing */
2057 /* This function is used in place of the normal tty_wait_until_sent, which */
2058 /* only waits for the driver buffers to be empty (or rather, those buffers */
2059 /* reported by chars_in_buffer) which doesn't work for IP2 due to the */
2060 /* indeterminate number of bytes buffered on the board. */
2061 /******************************************************************************/
2063 ip2_wait_until_sent ( PTTY tty
, int timeout
)
2066 i2ChanStrPtr pCh
= tty
->driver_data
;
2068 tty_wait_until_sent(tty
, timeout
);
2069 if ( (i
= timeout
- (jiffies
-i
)) > 0)
2070 i2DrainOutput( pCh
, i
);
2073 /******************************************************************************/
2074 /******************************************************************************/
2075 /* Device Input Section */
2076 /******************************************************************************/
2077 /******************************************************************************/
2079 /******************************************************************************/
2080 /* Function: ip2_throttle() */
2081 /* Parameters: Pointer to tty structure */
2082 /* Returns: Nothing */
2087 /******************************************************************************/
2089 ip2_throttle ( PTTY tty
)
2091 i2ChanStrPtr pCh
= tty
->driver_data
;
2093 #ifdef IP2DEBUG_READ
2094 printk (KERN_DEBUG
"IP2: throttle\n" );
2097 * Signal the poll/interrupt handlers not to forward incoming data to
2098 * the line discipline. This will cause the buffers to fill up in the
2099 * library and thus cause the library routines to send the flow control
2105 /******************************************************************************/
2106 /* Function: ip2_unthrottle() */
2107 /* Parameters: Pointer to tty structure */
2108 /* Returns: Nothing */
2113 /******************************************************************************/
2115 ip2_unthrottle ( PTTY tty
)
2117 i2ChanStrPtr pCh
= tty
->driver_data
;
2118 unsigned long flags
;
2120 #ifdef IP2DEBUG_READ
2121 printk (KERN_DEBUG
"IP2: unthrottle\n" );
2124 /* Pass incoming data up to the line discipline again. */
2126 i2QueueCommands(PTYPE_BYPASS
, pCh
, 0, 1, CMD_RESUME
);
2127 serviceOutgoingFifo( pCh
->pMyBord
);
2128 READ_LOCK_IRQSAVE(&pCh
->Ibuf_spinlock
,flags
)
2129 if ( pCh
->Ibuf_stuff
!= pCh
->Ibuf_strip
) {
2130 READ_UNLOCK_IRQRESTORE(&pCh
->Ibuf_spinlock
,flags
)
2131 #ifdef IP2DEBUG_READ
2132 printk (KERN_DEBUG
"i2Input called from unthrottle\n" );
2136 READ_UNLOCK_IRQRESTORE(&pCh
->Ibuf_spinlock
,flags
)
2140 ip2_start ( PTTY tty
)
2142 i2ChanStrPtr pCh
= DevTable
[MINOR(tty
->device
)];
2144 i2QueueCommands(PTYPE_BYPASS
, pCh
, 0, 1, CMD_RESUME
);
2145 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_UNSUSPEND
);
2146 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_RESUME
);
2147 #ifdef IP2DEBUG_WRITE
2148 printk (KERN_DEBUG
"IP2: start tx\n" );
2153 ip2_stop ( PTTY tty
)
2155 i2ChanStrPtr pCh
= DevTable
[MINOR(tty
->device
)];
2157 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_SUSPEND
);
2158 #ifdef IP2DEBUG_WRITE
2159 printk (KERN_DEBUG
"IP2: stop tx\n" );
2163 /******************************************************************************/
2164 /* Device Ioctl Section */
2165 /******************************************************************************/
2167 /******************************************************************************/
2168 /* Function: ip2_ioctl() */
2169 /* Parameters: Pointer to tty structure */
2170 /* Pointer to file structure */
2173 /* Returns: Success or failure */
2178 /******************************************************************************/
2180 ip2_ioctl ( PTTY tty
, struct file
*pFile
, UINT cmd
, ULONG arg
)
2182 i2ChanStrPtr pCh
= DevTable
[MINOR(tty
->device
)];
2183 struct async_icount cprev
, cnow
; /* kernel counter temps */
2184 struct serial_icounter_struct
*p_cuser
; /* user space */
2186 unsigned long flags
;
2188 if ( pCh
== NULL
) {
2192 #ifdef IP2DEBUG_TRACE
2193 ip2trace (CHANN
, ITRC_IOCTL
, ITRC_ENTER
, 2, cmd
, arg
);
2196 #ifdef IP2DEBUG_IOCTL
2197 printk(KERN_DEBUG
"IP2: ioctl cmd (%x), arg (%lx)\n", cmd
, arg
);
2202 #ifdef IP2DEBUG_TRACE
2203 ip2trace (CHANN
, ITRC_IOCTL
, 2, 1, rc
);
2205 rc
= get_serial_info(pCh
, (struct serial_struct
*) arg
);
2211 #ifdef IP2DEBUG_TRACE
2212 ip2trace (CHANN
, ITRC_IOCTL
, 3, 1, rc
);
2214 rc
= set_serial_info(pCh
, (struct serial_struct
*) arg
);
2220 rc
= tty_check_change(tty
);
2225 //return -ENOIOCTLCMD;
2228 //return -ENOIOCTLCMD;
2231 if (STOP_CHAR(tty
) != __DISABLED_CHAR
) {
2232 i2QueueCommands( PTYPE_BYPASS
, pCh
, 100, 1,
2233 CMD_XMIT_NOW(STOP_CHAR(tty
)));
2237 if (START_CHAR(tty
) != __DISABLED_CHAR
) {
2238 i2QueueCommands( PTYPE_BYPASS
, pCh
, 100, 1,
2239 CMD_XMIT_NOW(START_CHAR(tty
)));
2247 case TCSBRK
: /* SVID version: non-zero arg --> no break */
2248 rc
= tty_check_change(tty
);
2249 #ifdef IP2DEBUG_TRACE
2250 ip2trace (CHANN
, ITRC_IOCTL
, 4, 1, rc
);
2253 ip2_wait_until_sent(tty
,0);
2255 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_SEND_BRK(250));
2256 serviceOutgoingFifo( pCh
->pMyBord
);
2261 case TCSBRKP
: /* support for POSIX tcsendbreak() */
2262 rc
= tty_check_change(tty
);
2263 #ifdef IP2DEBUG_TRACE
2264 ip2trace (CHANN
, ITRC_IOCTL
, 5, 1, rc
);
2267 ip2_wait_until_sent(tty
,0);
2268 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1,
2269 CMD_SEND_BRK(arg
? arg
*100 : 250));
2270 serviceOutgoingFifo ( pCh
->pMyBord
);
2275 #ifdef IP2DEBUG_TRACE
2276 ip2trace (CHANN
, ITRC_IOCTL
, 6, 1, rc
);
2278 PUT_USER(rc
,C_CLOCAL(tty
) ? 1 : 0, (unsigned long *) arg
);
2284 #ifdef IP2DEBUG_TRACE
2285 ip2trace (CHANN
, ITRC_IOCTL
, 7, 1, rc
);
2287 GET_USER(rc
,arg
,(unsigned long *) arg
);
2290 tty
->termios
->c_cflag
= ((tty
->termios
->c_cflag
& ~CLOCAL
)
2291 | (arg
? CLOCAL
: 0));
2296 #ifdef IP2DEBUG_TRACE
2297 ip2trace (CHANN
, ITRC_IOCTL
, 8, 1, rc
);
2300 FIXME - the following code is causing a NULL pointer dereference in
2301 2.3.51 in an interrupt handler. It's suppose to prompt the board
2302 to return the DSS signal status immediately. Why doesn't it do
2303 the same thing in 2.2.14?
2306 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2307 serviceOutgoingFifo( pCh->pMyBord );
2308 interruptible_sleep_on(&pCh->dss_now_wait);
2309 if (signal_pending(current)) {
2314 ((pCh
->dataSetOut
& I2_RTS
) ? TIOCM_RTS
: 0)
2315 | ((pCh
->dataSetOut
& I2_DTR
) ? TIOCM_DTR
: 0)
2316 | ((pCh
->dataSetIn
& I2_DCD
) ? TIOCM_CAR
: 0)
2317 | ((pCh
->dataSetIn
& I2_RI
) ? TIOCM_RNG
: 0)
2318 | ((pCh
->dataSetIn
& I2_DSR
) ? TIOCM_DSR
: 0)
2319 | ((pCh
->dataSetIn
& I2_CTS
) ? TIOCM_CTS
: 0),
2320 (unsigned int *) arg
);
2326 #ifdef IP2DEBUG_TRACE
2327 ip2trace (CHANN
, ITRC_IOCTL
, 9, 0 );
2329 rc
= set_modem_info(pCh
, cmd
, (unsigned int *) arg
);
2333 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2334 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2335 * for masking). Caller should use TIOCGICOUNT to see which one it was
2338 save_flags(flags
);cli();
2339 cprev
= pCh
->icount
; /* note the counters on entry */
2340 restore_flags(flags
);
2341 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 4,
2342 CMD_DCD_REP
, CMD_CTS_REP
, CMD_DSR_REP
, CMD_RI_REP
);
2343 serviceOutgoingFifo( pCh
->pMyBord
);
2345 #ifdef IP2DEBUG_TRACE
2346 ip2trace (CHANN
, ITRC_IOCTL
, 10, 0 );
2348 interruptible_sleep_on(&pCh
->delta_msr_wait
);
2349 #ifdef IP2DEBUG_TRACE
2350 ip2trace (CHANN
, ITRC_IOCTL
, 11, 0 );
2352 /* see if a signal did it */
2353 if (signal_pending(current
)) {
2357 save_flags(flags
);cli();
2358 cnow
= pCh
->icount
; /* atomic copy */
2359 restore_flags(flags
);
2360 if (cnow
.rng
== cprev
.rng
&& cnow
.dsr
== cprev
.dsr
&&
2361 cnow
.dcd
== cprev
.dcd
&& cnow
.cts
== cprev
.cts
) {
2362 rc
= -EIO
; /* no change => rc */
2365 if (((arg
& TIOCM_RNG
) && (cnow
.rng
!= cprev
.rng
)) ||
2366 ((arg
& TIOCM_DSR
) && (cnow
.dsr
!= cprev
.dsr
)) ||
2367 ((arg
& TIOCM_CD
) && (cnow
.dcd
!= cprev
.dcd
)) ||
2368 ((arg
& TIOCM_CTS
) && (cnow
.cts
!= cprev
.cts
)) ) {
2374 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 3,
2375 CMD_CTS_NREP
, CMD_DSR_NREP
, CMD_RI_NREP
);
2376 if ( ! (pCh
->flags
& ASYNC_CHECK_CD
)) {
2377 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_DCD_NREP
);
2379 serviceOutgoingFifo( pCh
->pMyBord
);
2384 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2385 * Return: write counters to the user passed counter struct
2386 * NB: both 1->0 and 0->1 transitions are counted except for RI where
2387 * only 0->1 is counted. The controller is quite capable of counting
2388 * both, but this done to preserve compatibility with the standard
2392 #ifdef IP2DEBUG_TRACE
2393 ip2trace (CHANN
, ITRC_IOCTL
, 11, 1, rc
);
2395 save_flags(flags
);cli();
2397 restore_flags(flags
);
2398 p_cuser
= (struct serial_icounter_struct
*) arg
;
2399 PUT_USER(rc
,cnow
.cts
, &p_cuser
->cts
);
2400 PUT_USER(rc
,cnow
.dsr
, &p_cuser
->dsr
);
2401 PUT_USER(rc
,cnow
.rng
, &p_cuser
->rng
);
2402 PUT_USER(rc
,cnow
.dcd
, &p_cuser
->dcd
);
2403 PUT_USER(rc
,cnow
.rx
, &p_cuser
->rx
);
2404 PUT_USER(rc
,cnow
.tx
, &p_cuser
->tx
);
2405 PUT_USER(rc
,cnow
.frame
, &p_cuser
->frame
);
2406 PUT_USER(rc
,cnow
.overrun
, &p_cuser
->overrun
);
2407 PUT_USER(rc
,cnow
.parity
, &p_cuser
->parity
);
2408 PUT_USER(rc
,cnow
.brk
, &p_cuser
->brk
);
2409 PUT_USER(rc
,cnow
.buf_overrun
, &p_cuser
->buf_overrun
);
2413 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2414 * will be passed to the line discipline for it to handle.
2420 case TIOCSERGSTRUCT
:
2421 case TIOCSERGETMULTI
:
2422 case TIOCSERSETMULTI
:
2425 #ifdef IP2DEBUG_TRACE
2426 ip2trace (CHANN
, ITRC_IOCTL
, 12, 0 );
2431 #ifdef IP2DEBUG_TRACE
2432 ip2trace (CHANN
, ITRC_IOCTL
, ITRC_RETURN
, 0 );
2437 /******************************************************************************/
2438 /* Function: set_modem_info() */
2439 /* Parameters: Pointer to channel structure */
2440 /* Specific ioctl command */
2441 /* Pointer to source for new settings */
2442 /* Returns: Nothing */
2445 /* This returns the current settings of the dataset signal inputs to the user */
2447 /******************************************************************************/
2449 set_modem_info(i2ChanStrPtr pCh
, unsigned cmd
, unsigned int *value
)
2454 GET_USER(rc
,arg
,value
);
2459 if (arg
& TIOCM_RTS
) {
2460 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_RTSUP
);
2461 pCh
->dataSetOut
|= I2_RTS
;
2463 if (arg
& TIOCM_DTR
) {
2464 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DTRUP
);
2465 pCh
->dataSetOut
|= I2_DTR
;
2469 if (arg
& TIOCM_RTS
) {
2470 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_RTSDN
);
2471 pCh
->dataSetOut
&= ~I2_RTS
;
2473 if (arg
& TIOCM_DTR
) {
2474 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DTRDN
);
2475 pCh
->dataSetOut
&= ~I2_DTR
;
2479 if ( (arg
& TIOCM_RTS
) && !(pCh
->dataSetOut
& I2_RTS
) ) {
2480 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_RTSUP
);
2481 pCh
->dataSetOut
|= I2_RTS
;
2482 } else if ( !(arg
& TIOCM_RTS
) && (pCh
->dataSetOut
& I2_RTS
) ) {
2483 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_RTSDN
);
2484 pCh
->dataSetOut
&= ~I2_RTS
;
2486 if ( (arg
& TIOCM_DTR
) && !(pCh
->dataSetOut
& I2_DTR
) ) {
2487 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DTRUP
);
2488 pCh
->dataSetOut
|= I2_DTR
;
2489 } else if ( !(arg
& TIOCM_DTR
) && (pCh
->dataSetOut
& I2_DTR
) ) {
2490 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DTRDN
);
2491 pCh
->dataSetOut
&= ~I2_DTR
;
2497 serviceOutgoingFifo( pCh
->pMyBord
);
2501 /******************************************************************************/
2502 /* Function: GetSerialInfo() */
2503 /* Parameters: Pointer to channel structure */
2504 /* Pointer to old termios structure */
2505 /* Returns: Nothing */
2508 /* This is to support the setserial command, and requires processing of the */
2509 /* standard Linux serial structure. */
2510 /******************************************************************************/
2512 get_serial_info ( i2ChanStrPtr pCh
, struct serial_struct
*retinfo
)
2514 struct serial_struct tmp
;
2521 memset ( &tmp
, 0, sizeof(tmp
) );
2522 tmp
.type
= pCh
->pMyBord
->channelBtypes
.bid_value
[(pCh
->port_index
& (IP2_PORTS_PER_BOARD
-1))/16];
2523 if (BID_HAS_654(tmp
.type
)) {
2524 tmp
.type
= PORT_16650
;
2526 tmp
.type
= PORT_CIRRUS
;
2528 tmp
.line
= pCh
->port_index
;
2529 tmp
.port
= pCh
->pMyBord
->i2eBase
;
2530 tmp
.irq
= ip2config
.irq
[pCh
->port_index
/64];
2531 tmp
.flags
= pCh
->flags
;
2532 tmp
.baud_base
= pCh
->BaudBase
;
2533 tmp
.close_delay
= pCh
->ClosingDelay
;
2534 tmp
.closing_wait
= pCh
->ClosingWaitTime
;
2535 tmp
.custom_divisor
= pCh
->BaudDivisor
;
2536 COPY_TO_USER(rc
,retinfo
,&tmp
,sizeof(*retinfo
));
2540 /******************************************************************************/
2541 /* Function: SetSerialInfo() */
2542 /* Parameters: Pointer to channel structure */
2543 /* Pointer to old termios structure */
2544 /* Returns: Nothing */
2547 /* This function provides support for setserial, which uses the TIOCSSERIAL */
2548 /* ioctl. Not all setserial parameters are relevant. If the user attempts to */
2549 /* change the IRQ, address or type of the port the ioctl fails. */
2550 /******************************************************************************/
2552 set_serial_info( i2ChanStrPtr pCh
, struct serial_struct
*new_info
)
2554 struct serial_struct ns
;
2555 int old_flags
, old_baud_divisor
;
2561 COPY_FROM_USER(rc
, &ns
, new_info
, sizeof (ns
) );
2566 * We don't allow setserial to change IRQ, board address, type or baud
2567 * base. Also line nunber as such is meaningless but we use it for our
2568 * array index so it is fixed also.
2570 if ( (ns
.irq
!= ip2config
.irq
[pCh
->port_index
])
2571 || ((int) ns
.port
!= ((int) (pCh
->pMyBord
->i2eBase
)))
2572 || (ns
.baud_base
!= pCh
->BaudBase
)
2573 || (ns
.line
!= pCh
->port_index
) ) {
2577 old_flags
= pCh
->flags
;
2578 old_baud_divisor
= pCh
->BaudDivisor
;
2581 if ( ( ns
.close_delay
!= pCh
->ClosingDelay
) ||
2582 ( (ns
.flags
& ~ASYNC_USR_MASK
) !=
2583 (pCh
->flags
& ~ASYNC_USR_MASK
) ) ) {
2587 pCh
->flags
= (pCh
->flags
& ~ASYNC_USR_MASK
) |
2588 (ns
.flags
& ASYNC_USR_MASK
);
2589 pCh
->BaudDivisor
= ns
.custom_divisor
;
2591 pCh
->flags
= (pCh
->flags
& ~ASYNC_FLAGS
) |
2592 (ns
.flags
& ASYNC_FLAGS
);
2593 pCh
->BaudDivisor
= ns
.custom_divisor
;
2594 pCh
->ClosingDelay
= ns
.close_delay
* HZ
/100;
2595 pCh
->ClosingWaitTime
= ns
.closing_wait
* HZ
/100;
2598 if ( ( (old_flags
& ASYNC_SPD_MASK
) != (pCh
->flags
& ASYNC_SPD_MASK
) )
2599 || (old_baud_divisor
!= pCh
->BaudDivisor
) ) {
2600 // Invalidate speed and reset parameters
2601 set_params( pCh
, NULL
);
2607 /******************************************************************************/
2608 /* Function: ip2_set_termios() */
2609 /* Parameters: Pointer to tty structure */
2610 /* Pointer to old termios structure */
2611 /* Returns: Nothing */
2616 /******************************************************************************/
2618 ip2_set_termios( PTTY tty
, struct termios
*old_termios
)
2620 i2ChanStrPtr pCh
= (i2ChanStrPtr
)tty
->driver_data
;
2622 #ifdef IP2DEBUG_IOCTL
2623 printk (KERN_DEBUG
"IP2: set termios %p\n", old_termios
);
2626 set_params( pCh
, old_termios
);
2629 /******************************************************************************/
2630 /* Function: ip2_set_line_discipline() */
2631 /* Parameters: Pointer to tty structure */
2632 /* Returns: Nothing */
2634 /* Description: Does nothing */
2637 /******************************************************************************/
2639 ip2_set_line_discipline ( PTTY tty
)
2641 #ifdef IP2DEBUG_IOCTL
2642 printk (KERN_DEBUG
"IP2: set line discipline\n" );
2644 #ifdef IP2DEBUG_TRACE
2645 ip2trace (((i2ChanStrPtr
)tty
->driver_data
)->port_index
, ITRC_IOCTL
, 16, 0 );
2649 /******************************************************************************/
2650 /* Function: SetLine Characteristics() */
2651 /* Parameters: Pointer to channel structure */
2652 /* Returns: Nothing */
2655 /* This routine is called to update the channel structure with the new line */
2656 /* characteristics, and send the appropriate commands to the board when they */
2658 /******************************************************************************/
2660 set_params( i2ChanStrPtr pCh
, struct termios
*o_tios
)
2662 tcflag_t cflag
, iflag
, lflag
;
2663 char stop_char
, start_char
;
2664 struct termios dummy
;
2666 lflag
= pCh
->pTTY
->termios
->c_lflag
;
2667 cflag
= pCh
->pTTY
->termios
->c_cflag
;
2668 iflag
= pCh
->pTTY
->termios
->c_iflag
;
2670 if (o_tios
== NULL
) {
2671 dummy
.c_lflag
= ~lflag
;
2672 dummy
.c_cflag
= ~cflag
;
2673 dummy
.c_iflag
= ~iflag
;
2678 switch ( cflag
& CBAUD
) {
2680 i2QueueCommands( PTYPE_BYPASS
, pCh
, 100, 2, CMD_RTSDN
, CMD_DTRDN
);
2681 pCh
->dataSetOut
&= ~(I2_DTR
| I2_RTS
);
2682 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_PAUSE(25));
2683 pCh
->pTTY
->termios
->c_cflag
|= (CBAUD
& o_tios
->c_cflag
);
2688 * This is the speed that is overloaded with all the other high
2689 * speeds, depending upon the flag settings.
2691 if ( ( pCh
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
) {
2692 pCh
->speed
= CBR_57600
;
2693 } else if ( (pCh
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
) {
2694 pCh
->speed
= CBR_115200
;
2695 } else if ( (pCh
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_CUST
) {
2696 pCh
->speed
= CBR_C1
;
2698 pCh
->speed
= CBR_38400
;
2701 case B50
: pCh
->speed
= CBR_50
; break;
2702 case B75
: pCh
->speed
= CBR_75
; break;
2703 case B110
: pCh
->speed
= CBR_110
; break;
2704 case B134
: pCh
->speed
= CBR_134
; break;
2705 case B150
: pCh
->speed
= CBR_150
; break;
2706 case B200
: pCh
->speed
= CBR_200
; break;
2707 case B300
: pCh
->speed
= CBR_300
; break;
2708 case B600
: pCh
->speed
= CBR_600
; break;
2709 case B1200
: pCh
->speed
= CBR_1200
; break;
2710 case B1800
: pCh
->speed
= CBR_1800
; break;
2711 case B2400
: pCh
->speed
= CBR_2400
; break;
2712 case B4800
: pCh
->speed
= CBR_4800
; break;
2713 case B9600
: pCh
->speed
= CBR_9600
; break;
2714 case B19200
: pCh
->speed
= CBR_19200
; break;
2715 case B57600
: pCh
->speed
= CBR_57600
; break;
2716 case B115200
: pCh
->speed
= CBR_115200
; break;
2717 case B153600
: pCh
->speed
= CBR_153600
; break;
2718 case B230400
: pCh
->speed
= CBR_230400
; break;
2719 case B307200
: pCh
->speed
= CBR_307200
; break;
2720 case B460800
: pCh
->speed
= CBR_460800
; break;
2721 case B921600
: pCh
->speed
= CBR_921600
; break;
2722 default: pCh
->speed
= CBR_9600
; break;
2724 if ( pCh
->speed
== CBR_C1
) {
2725 // Process the custom speed parameters.
2726 int bps
= pCh
->BaudBase
/ pCh
->BaudDivisor
;
2727 if ( bps
== 921600 ) {
2728 pCh
->speed
= CBR_921600
;
2731 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_BAUD_DEF1(bps
) );
2734 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_SETBAUD(pCh
->speed
));
2736 i2QueueCommands ( PTYPE_INLINE
, pCh
, 100, 2, CMD_DTRUP
, CMD_RTSUP
);
2737 pCh
->dataSetOut
|= (I2_DTR
| I2_RTS
);
2739 if ( (CSTOPB
& cflag
) ^ (CSTOPB
& o_tios
->c_cflag
))
2741 i2QueueCommands ( PTYPE_INLINE
, pCh
, 100, 1,
2742 CMD_SETSTOP( ( cflag
& CSTOPB
) ? CST_2
: CST_1
));
2744 if (((PARENB
|PARODD
) & cflag
) ^ ((PARENB
|PARODD
) & o_tios
->c_cflag
))
2746 i2QueueCommands ( PTYPE_INLINE
, pCh
, 100, 1,
2748 (cflag
& PARENB
? (cflag
& PARODD
? CSP_OD
: CSP_EV
) : CSP_NP
)
2752 /* byte size and parity */
2753 if ( (CSIZE
& cflag
)^(CSIZE
& o_tios
->c_cflag
))
2756 switch ( cflag
& CSIZE
) {
2757 case CS5
: datasize
= CSZ_5
; break;
2758 case CS6
: datasize
= CSZ_6
; break;
2759 case CS7
: datasize
= CSZ_7
; break;
2760 case CS8
: datasize
= CSZ_8
; break;
2761 default: datasize
= CSZ_5
; break; /* as per serial.c */
2763 i2QueueCommands ( PTYPE_INLINE
, pCh
, 100, 1, CMD_SETBITS(datasize
) );
2765 /* Process CTS flow control flag setting */
2766 if ( (cflag
& CRTSCTS
) ) {
2767 i2QueueCommands(PTYPE_INLINE
, pCh
, 100,
2768 2, CMD_CTSFL_ENAB
, CMD_RTSFL_ENAB
);
2770 i2QueueCommands(PTYPE_INLINE
, pCh
, 100,
2771 2, CMD_CTSFL_DSAB
, CMD_RTSFL_DSAB
);
2774 // Process XON/XOFF flow control flags settings
2776 stop_char
= STOP_CHAR(pCh
->pTTY
);
2777 start_char
= START_CHAR(pCh
->pTTY
);
2779 //////////// can't be \000
2780 if (stop_char
== __DISABLED_CHAR
)
2782 stop_char
= ~__DISABLED_CHAR
;
2784 if (start_char
== __DISABLED_CHAR
)
2786 start_char
= ~__DISABLED_CHAR
;
2788 /////////////////////////////////
2790 if ( o_tios
->c_cc
[VSTART
] != start_char
)
2792 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_DEF_IXON(start_char
));
2793 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DEF_OXON(start_char
));
2795 if ( o_tios
->c_cc
[VSTOP
] != stop_char
)
2797 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_DEF_IXOFF(stop_char
));
2798 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DEF_OXOFF(stop_char
));
2800 if (stop_char
== __DISABLED_CHAR
)
2802 stop_char
= ~__DISABLED_CHAR
; //TEST123
2805 if ((iflag
& (IXOFF
))^(o_tios
->c_iflag
& (IXOFF
)))
2807 if ( iflag
& IXOFF
) { // Enable XOFF output flow control
2808 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_OXON_OPT(COX_XON
));
2809 } else { // Disable XOFF output flow control
2811 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_OXON_OPT(COX_NONE
));
2814 if (start_char
== __DISABLED_CHAR
)
2818 if ((iflag
& (IXON
|IXANY
)) ^ (o_tios
->c_iflag
& (IXON
|IXANY
)))
2820 if ( iflag
& IXON
) {
2821 if ( iflag
& IXANY
) { // Enable XON/XANY output flow control
2822 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_IXON_OPT(CIX_XANY
));
2823 } else { // Enable XON output flow control
2824 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_IXON_OPT(CIX_XON
));
2826 } else { // Disable XON output flow control
2828 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_IXON_OPT(CIX_NONE
));
2831 if ( (iflag
& ISTRIP
) ^ ( o_tios
->c_iflag
& (ISTRIP
)) )
2833 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1,
2834 CMD_ISTRIP_OPT((iflag
& ISTRIP
? 1 : 0)));
2836 if ( (iflag
& INPCK
) ^ ( o_tios
->c_iflag
& (INPCK
)) )
2838 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1,
2839 CMD_PARCHK((iflag
& INPCK
) ? CPK_ENAB
: CPK_DSAB
));
2842 if ( (iflag
& (IGNBRK
|PARMRK
|BRKINT
|IGNPAR
))
2843 ^ ( o_tios
->c_iflag
& (IGNBRK
|PARMRK
|BRKINT
|IGNPAR
)) )
2848 if ( iflag
& IGNBRK
) { /* Ignore breaks altogether */
2849 /* Ignore breaks altogether */
2850 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_BRK_NREP
);
2852 if ( iflag
& BRKINT
) {
2853 if ( iflag
& PARMRK
) {
2854 brkrpt
= 0x0a; // exception an inline triple
2856 brkrpt
= 0x1a; // exception and NULL
2858 brkrpt
|= 0x04; // flush input
2860 if ( iflag
& PARMRK
) {
2861 brkrpt
= 0x0b; //POSIX triple \0377 \0 \0
2863 brkrpt
= 0x01; // Null only
2866 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_BRK_REP(brkrpt
));
2869 if (iflag
& IGNPAR
) {
2871 /* would be 2 for not cirrus bug */
2872 /* would be 0x20 cept for cirrus bug */
2874 if ( iflag
& PARMRK
) {
2876 * Replace error characters with 3-byte sequence (\0377,\0,char)
2879 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_ISTRIP_OPT((char)0));
2884 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_SET_ERROR(parrpt
));
2886 if (cflag
& CLOCAL
) {
2887 // Status reporting fails for DCD if this is off
2888 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DCD_NREP
);
2889 pCh
->flags
&= ~ASYNC_CHECK_CD
;
2891 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DCD_REP
);
2892 pCh
->flags
|= ASYNC_CHECK_CD
;
2896 do_flags_thing
: // This is a test, we don't do the flags thing
2898 if ( (cflag
& CRTSCTS
) ) {
2899 cflag
|= 014000000000;
2901 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1,
2902 CMD_UNIX_FLAGS(iflag
,cflag
,lflag
));
2906 i2DrainOutput( pCh
, 100 );
2909 /******************************************************************************/
2910 /* IPL Device Section */
2911 /******************************************************************************/
2913 /******************************************************************************/
2914 /* Function: ip2_ipl_read() */
2915 /* Parameters: Pointer to device inode */
2916 /* Pointer to file structure */
2917 /* Pointer to data */
2918 /* Number of bytes to read */
2919 /* Returns: Success or failure */
2921 /* Description: Ugly */
2924 /******************************************************************************/
2927 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
2929 ip2_ipl_read(struct inode
*pInode
, char *pData
, size_t count
, loff_t
*off
)
2930 unsigned int minor
= MINOR( pInode
->i_rdev
);
2933 ip2_ipl_read(struct file
*pFile
, char *pData
, size_t count
, loff_t
*off
)
2935 unsigned int minor
= MINOR( pFile
->f_dentry
->d_inode
->i_rdev
);
2940 printk (KERN_DEBUG
"IP2IPL: read %p, %d bytes\n", pData
, count
);
2944 case 0: // IPL device
2947 case 1: // Status dump
2950 case 2: // Ping device
2953 case 3: // Trace device
2954 rc
= DumpTraceBuffer ( pData
, count
);
2956 case 4: // Trace device
2957 rc
= DumpFifoBuffer ( pData
, count
);
2967 DumpFifoBuffer ( char *pData
, int count
)
2971 COPY_TO_USER(rc
, pData
, DBGBuf
, count
);
2973 printk(KERN_DEBUG
"Last index %d\n", I
);
2976 #endif /* DEBUG_FIFO */
2981 DumpTraceBuffer ( char *pData
, int count
)
2983 #ifdef IP2DEBUG_TRACE
2987 int *pIndex
= (int*)pData
;
2989 if ( count
< (sizeof(int) * 6) ) {
2992 PUT_USER(rc
, tracewrap
, pIndex
);
2993 PUT_USER(rc
, TRACEMAX
, ++pIndex
);
2994 PUT_USER(rc
, tracestrip
, ++pIndex
);
2995 PUT_USER(rc
, tracestuff
, ++pIndex
);
2996 pData
+= sizeof(int) * 6;
2997 count
-= sizeof(int) * 6;
2999 dumpcount
= tracestuff
- tracestrip
;
3000 if ( dumpcount
< 0 ) {
3001 dumpcount
+= TRACEMAX
;
3003 if ( dumpcount
> count
) {
3006 chunk
= TRACEMAX
- tracestrip
;
3007 if ( dumpcount
> chunk
) {
3008 COPY_TO_USER(rc
, pData
, &tracebuf
[tracestrip
],
3009 chunk
* sizeof(tracebuf
[0]) );
3010 pData
+= chunk
* sizeof(tracebuf
[0]);
3012 chunk
= dumpcount
- chunk
;
3016 COPY_TO_USER(rc
, pData
, &tracebuf
[tracestrip
],
3017 chunk
* sizeof(tracebuf
[0]) );
3018 tracestrip
+= chunk
;
3021 PUT_USER(rc
, tracestrip
, ++pIndex
);
3022 PUT_USER(rc
, tracestuff
, ++pIndex
);
3030 /******************************************************************************/
3031 /* Function: ip2_ipl_write() */
3033 /* Pointer to file structure */
3034 /* Pointer to data */
3035 /* Number of bytes to write */
3036 /* Returns: Success or failure */
3041 /******************************************************************************/
3043 ip2_ipl_write(struct file
*pFile
, const char *pData
, size_t count
, loff_t
*off
)
3046 printk (KERN_DEBUG
"IP2IPL: write %p, %d bytes\n", pData
, count
);
3051 /******************************************************************************/
3052 /* Function: ip2_ipl_ioctl() */
3053 /* Parameters: Pointer to device inode */
3054 /* Pointer to file structure */
3057 /* Returns: Success or failure */
3062 /******************************************************************************/
3064 ip2_ipl_ioctl ( struct inode
*pInode
, struct file
*pFile
, UINT cmd
, ULONG arg
)
3066 unsigned int iplminor
= MINOR(pInode
->i_rdev
);
3068 ULONG
*pIndex
= (ULONG
*)arg
;
3069 i2eBordStrPtr pB
= i2BoardPtrTable
[iplminor
/ 4];
3073 printk (KERN_DEBUG
"IP2IPL: ioctl cmd %d, arg %ld\n", cmd
, arg
);
3076 switch ( iplminor
) {
3077 case 0: // IPL device
3080 case 1: // Status dump
3085 case 64: /* Driver - ip2stat */
3086 PUT_USER(rc
, ref_count
, pIndex
++ );
3087 PUT_USER(rc
, irq_counter
, pIndex
++ );
3088 PUT_USER(rc
, bh_counter
, pIndex
++ );
3091 case 65: /* Board - ip2stat */
3093 COPY_TO_USER(rc
, (char*)arg
, (char*)pB
, sizeof(i2eBordStr
) );
3094 PUT_USER(rc
, INB(pB
->i2eStatus
),
3095 (ULONG
*)(arg
+ (ULONG
)(&pB
->i2eStatus
) - (ULONG
)pB
) );
3102 pCh
= DevTable
[cmd
];
3105 COPY_TO_USER(rc
, (char*)arg
, (char*)pCh
, sizeof(i2ChanStr
) );
3107 rc
= cmd
< 64 ? -ENODEV
: -EINVAL
;
3112 case 2: // Ping device
3115 case 3: // Trace device
3117 PUT_USER(rc
, iiSendPendingMail
, pIndex
++ );
3118 PUT_USER(rc
, i2InitChannels
, pIndex
++ );
3119 PUT_USER(rc
, i2QueueNeeds
, pIndex
++ );
3120 PUT_USER(rc
, i2QueueCommands
, pIndex
++ );
3121 PUT_USER(rc
, i2GetStatus
, pIndex
++ );
3122 PUT_USER(rc
, i2Input
, pIndex
++ );
3123 PUT_USER(rc
, i2InputFlush
, pIndex
++ );
3124 PUT_USER(rc
, i2Output
, pIndex
++ );
3125 PUT_USER(rc
, i2FlushOutput
, pIndex
++ );
3126 PUT_USER(rc
, i2DrainWakeup
, pIndex
++ );
3127 PUT_USER(rc
, i2DrainOutput
, pIndex
++ );
3128 PUT_USER(rc
, i2OutputFree
, pIndex
++ );
3129 PUT_USER(rc
, i2StripFifo
, pIndex
++ );
3130 PUT_USER(rc
, i2StuffFifoBypass
, pIndex
++ );
3131 PUT_USER(rc
, i2StuffFifoFlow
, pIndex
++ );
3132 PUT_USER(rc
, i2StuffFifoInline
, pIndex
++ );
3133 PUT_USER(rc
, i2ServiceBoard
, pIndex
++ );
3134 PUT_USER(rc
, serviceOutgoingFifo
, pIndex
++ );
3135 // PUT_USER(rc, ip2_init, pIndex++ );
3136 PUT_USER(rc
, ip2_init_board
, pIndex
++ );
3137 PUT_USER(rc
, find_eisa_board
, pIndex
++ );
3138 PUT_USER(rc
, set_irq
, pIndex
++ );
3139 PUT_USER(rc
, ip2_interrupt
, pIndex
++ );
3140 PUT_USER(rc
, ip2_poll
, pIndex
++ );
3141 PUT_USER(rc
, service_all_boards
, pIndex
++ );
3142 PUT_USER(rc
, do_input
, pIndex
++ );
3143 PUT_USER(rc
, do_status
, pIndex
++ );
3144 #ifndef IP2DEBUG_OPEN
3145 PUT_USER(rc
, 0, pIndex
++ );
3147 PUT_USER(rc
, open_sanity_check
, pIndex
++ );
3149 PUT_USER(rc
, ip2_open
, pIndex
++ );
3150 PUT_USER(rc
, ip2_close
, pIndex
++ );
3151 PUT_USER(rc
, ip2_hangup
, pIndex
++ );
3152 PUT_USER(rc
, ip2_write
, pIndex
++ );
3153 PUT_USER(rc
, ip2_putchar
, pIndex
++ );
3154 PUT_USER(rc
, ip2_flush_chars
, pIndex
++ );
3155 PUT_USER(rc
, ip2_write_room
, pIndex
++ );
3156 PUT_USER(rc
, ip2_chars_in_buf
, pIndex
++ );
3157 PUT_USER(rc
, ip2_flush_buffer
, pIndex
++ );
3159 //PUT_USER(rc, ip2_wait_until_sent, pIndex++ );
3160 PUT_USER(rc
, 0, pIndex
++ );
3162 PUT_USER(rc
, ip2_throttle
, pIndex
++ );
3163 PUT_USER(rc
, ip2_unthrottle
, pIndex
++ );
3164 PUT_USER(rc
, ip2_ioctl
, pIndex
++ );
3165 PUT_USER(rc
, set_modem_info
, pIndex
++ );
3166 PUT_USER(rc
, get_serial_info
, pIndex
++ );
3167 PUT_USER(rc
, set_serial_info
, pIndex
++ );
3168 PUT_USER(rc
, ip2_set_termios
, pIndex
++ );
3169 PUT_USER(rc
, ip2_set_line_discipline
, pIndex
++ );
3170 PUT_USER(rc
, set_params
, pIndex
++ );
3184 /******************************************************************************/
3185 /* Function: ip2_ipl_open() */
3186 /* Parameters: Pointer to device inode */
3187 /* Pointer to file structure */
3188 /* Returns: Success or failure */
3193 /******************************************************************************/
3195 ip2_ipl_open( struct inode
*pInode
, struct file
*pFile
)
3197 unsigned int iplminor
= MINOR(pInode
->i_rdev
);
3202 printk (KERN_DEBUG
"IP2IPL: open\n" );
3206 // These are the IPL devices
3213 // These are the status devices
3220 // These are the debug devices
3225 pB
= i2BoardPtrTable
[iplminor
/ 4];
3226 pCh
= (i2ChanStrPtr
) pB
->i2eChannelPtr
;
3229 // This is the trace device
3235 /******************************************************************************/
3236 /* Function: ip2_read_procmem */
3239 /* Returns: Length of output */
3242 /* Supplies some driver operating parameters */
3243 /* Not real useful unless your debugging the fifo */
3245 /******************************************************************************/
3247 #define LIMIT (PAGE_SIZE - 120)
3250 ip2_read_procmem(char *buf
, char **start
, off_t offset
, int len
)
3259 #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
3260 #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n"
3261 #define FMTLIN3 " 0x%04x 0x%04x rc flow\n"
3263 len
+= sprintf(buf
+len
,"\n");
3265 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
3266 pB
= i2BoardPtrTable
[i
];
3268 len
+= sprintf(buf
+len
,"board %d:\n",i
);
3269 len
+= sprintf(buf
+len
,"\tFifo rem: %d mty: %x outM %x\n",
3270 pB
->i2eFifoRemains
,pB
->i2eWaitingForEmptyFifo
,pB
->i2eOutMailWaiting
);
3274 len
+= sprintf(buf
+len
,"#: tty flags, port flags, cflags, iflags\n");
3275 for (i
=0; i
< IP2_MAX_PORTS
; i
++) {
3281 if (tty
&& tty
->count
) {
3282 len
+= sprintf(buf
+len
,FMTLINE
,i
,(int)tty
->flags
,pCh
->flags
,
3283 tty
->termios
->c_cflag
,tty
->termios
->c_iflag
);
3285 len
+= sprintf(buf
+len
,FMTLIN2
,
3286 pCh
->outfl
.asof
,pCh
->outfl
.room
,pCh
->channelNeeds
);
3287 len
+= sprintf(buf
+len
,FMTLIN3
,pCh
->infl
.asof
,pCh
->infl
.room
);
3295 * This is the handler for /proc/tty/driver/ip2
3297 * This stretch of code has been largely plagerized from at least three
3298 * different sources including ip2mkdev.c and a couple of other drivers.
3299 * The bugs are all mine. :-) =mhw=
3301 int ip2_read_proc(char *page
, char **start
, off_t off
,
3302 int count
, int *eof
, void *data
)
3312 len
+= sprintf(page
, "ip2info: 1.0 driver: %s\n", pcVersion
);
3313 len
+= sprintf(page
+len
, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
3314 IP2_TTY_MAJOR
, IP2_CALLOUT_MAJOR
, IP2_IPL_MAJOR
,
3315 IP2_MAX_BOARDS
, ABS_MAX_BOXES
, ABS_BIGGEST_BOX
);
3317 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
3318 /* This need to be reset for a board by board count... */
3320 pB
= i2BoardPtrTable
[i
];
3322 switch( pB
->i2ePom
.e
.porID
& ~POR_ID_RESERVED
)
3325 len
+= sprintf( page
+len
, "Board %d: EX ports=", i
);
3326 for( box
= 0; box
< ABS_MAX_BOXES
; ++box
)
3330 if( pB
->i2eChannelMap
[box
] != 0 ) ++boxes
;
3331 for( j
= 0; j
< ABS_BIGGEST_BOX
; ++j
)
3333 if( pB
->i2eChannelMap
[box
] & 1<< j
) {
3337 len
+= sprintf( page
+len
, "%d,", ports
);
3341 --len
; /* Backup over that last comma */
3343 len
+= sprintf( page
+len
, " boxes=%d width=%d", boxes
, pB
->i2eDataWidth16
? 16 : 8 );
3347 len
+= sprintf(page
+len
, "Board %d: ISA-4 ports=4 boxes=1", i
);
3352 len
+= sprintf(page
+len
, "Board %d: ISA-8-std ports=8 boxes=1", i
);
3357 len
+= sprintf(page
+len
, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i
);
3362 len
+= sprintf(page
+len
, "Board %d: unknown", i
);
3363 /* Don't try and probe for minor numbers */
3368 /* Don't try and probe for minor numbers */
3369 len
+= sprintf(page
+len
, "Board %d: vacant", i
);
3374 len
+= sprintf(page
+len
, " minors=" );
3376 for ( box
= 0; box
< ABS_MAX_BOXES
; ++box
)
3378 for ( j
= 0; j
< ABS_BIGGEST_BOX
; ++j
)
3380 if ( pB
->i2eChannelMap
[box
] & (1 << j
) )
3382 len
+= sprintf (page
+len
,"%d,",
3383 j
+ ABS_BIGGEST_BOX
*
3384 (box
+i
*ABS_MAX_BOXES
));
3389 page
[ len
- 1 ] = '\n'; /* Overwrite that last comma */
3391 len
+= sprintf (page
+len
,"\n" );
3394 if (len
+begin
> off
+count
)
3396 if (len
+begin
< off
) {
3402 if (i
>= IP2_MAX_BOARDS
)
3404 if (off
>= len
+begin
)
3407 *start
= page
+ (off
-begin
);
3408 return ((count
< begin
+len
-off
) ? count
: begin
+len
-off
);
3411 /******************************************************************************/
3412 /* Function: ip2trace() */
3413 /* Parameters: Value to add to trace buffer */
3414 /* Returns: Nothing */
3419 /******************************************************************************/
3421 ip2trace (unsigned short pn
, unsigned char cat
, unsigned char label
, unsigned long codes
, ...)
3423 #ifdef IP2DEBUG_TRACE
3425 unsigned long *pCode
= &codes
;
3426 union ip2breadcrumb bc
;
3430 tracebuf
[tracestuff
++] = jiffies
;
3431 if ( tracestuff
== TRACEMAX
) {
3434 if ( tracestuff
== tracestrip
) {
3435 if ( ++tracestrip
== TRACEMAX
) {
3441 bc
.hdr
.port
= 0xff & pn
;
3443 bc
.hdr
.codes
= (unsigned char)( codes
& 0xff );
3444 bc
.hdr
.label
= label
;
3445 tracebuf
[tracestuff
++] = bc
.value
;
3448 if ( tracestuff
== TRACEMAX
) {
3451 if ( tracestuff
== tracestrip
) {
3452 if ( ++tracestrip
== TRACEMAX
) {
3461 tracebuf
[tracestuff
++] = *++pCode
;