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 *******************************************************************************/
17 #include <linux/config.h>
18 #include <linux/module.h>
19 #include <linux/version.h>
21 #include <linux/ctype.h>
22 #include <linux/string.h>
23 #include <linux/fcntl.h>
24 #include <linux/errno.h>
26 #include <linux/signal.h>
27 #include <linux/sched.h>
28 #include <linux/timer.h>
29 #include <linux/interrupt.h>
30 #include <linux/pci.h>
32 #include <linux/malloc.h>
33 #include <linux/major.h>
34 #include <linux/wait.h>
36 #include <linux/tty.h>
37 #include <linux/tty_flip.h>
38 #include <linux/termios.h>
39 #include <linux/tty_driver.h>
40 #include <linux/serial.h>
41 #include <linux/ptrace.h>
42 #include <linux/ioport.h>
44 #include <linux/cdk.h>
45 #include <linux/comstats.h>
46 #include <linux/delay.h>
48 #include <asm/system.h>
51 #include <asm/bitops.h>
53 #include <linux/vmalloc.h>
54 #include <linux/init.h>
55 #include <asm/serial.h>
57 #include <asm/uaccess.h>
58 #define pcibios_strerror(status) \
59 printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
61 #include "./ip2/ip2types.h"
62 #include "./ip2/ip2trace.h"
63 #include "./ip2/ip2ioctl.h"
64 #include "./ip2/ip2.h"
65 #include "./ip2/i2ellis.h"
66 #include "./ip2/i2lib.h"
72 #include <linux/proc_fs.h>
74 int ip2_read_procmem(char *, char **, off_t
, int, int );
75 int ip2_read_proc(char *, char **, off_t
, int, int *, void * );
77 struct proc_dir_entry ip2_proc_entry
= {
87 /********************/
88 /* Type Definitions */
89 /********************/
95 /* String constants to identify ourselves */
96 static char *pcName
= "Computone IntelliPort Plus multiport driver";
97 static char *pcVersion
= "1.2.4";
99 /* String constants for port names */
100 static char *pcDriver_name
= "ip2";
101 static char *pcTty
= "ttyf";
102 static char *pcCallout
= "cuf";
103 static char *pcIpl
= "ip2ipl";
105 /* Serial subtype definitions */
106 #define SERIAL_TYPE_NORMAL 1
107 #define SERIAL_TYPE_CALLOUT 2
109 // cheezy kludge or genius - you decide?
110 int ip2_loadmain(int *, int *, unsigned char *, int);
111 static unsigned char *Fip_firmware
;
112 static int Fip_firmware_size
;
114 /***********************/
115 /* Function Prototypes */
116 /***********************/
118 /* Global module entry functions */
120 int init_module(void);
121 void cleanup_module(void);
124 int old_ip2_init(void);
126 /* Private (static) functions */
127 static int ip2_open(PTTY
, struct file
*);
128 static void ip2_close(PTTY
, struct file
*);
129 static int ip2_write(PTTY
, int, const unsigned char *, int);
130 static void ip2_putchar(PTTY
, unsigned char);
131 static void ip2_flush_chars(PTTY
);
132 static int ip2_write_room(PTTY
);
133 static int ip2_chars_in_buf(PTTY
);
134 static void ip2_flush_buffer(PTTY
);
135 static int ip2_ioctl(PTTY
, struct file
*, UINT
, ULONG
);
136 static void ip2_set_termios(PTTY
, struct termios
*);
137 static void ip2_set_line_discipline(PTTY
);
138 static void ip2_throttle(PTTY
);
139 static void ip2_unthrottle(PTTY
);
140 static void ip2_stop(PTTY
);
141 static void ip2_start(PTTY
);
142 static void ip2_hangup(PTTY
);
144 static void set_irq(int, int);
145 static void ip2_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
);
146 static void ip2_poll(unsigned long arg
);
147 static inline void service_all_boards(void);
148 static inline void do_input(i2ChanStrPtr pCh
);
149 static inline void do_status(i2ChanStrPtr pCh
);
151 static void ip2_wait_until_sent(PTTY
,int);
153 static void set_params (i2ChanStrPtr
, struct termios
*);
154 static int get_modem_info(i2ChanStrPtr
, unsigned int *);
155 static int set_modem_info(i2ChanStrPtr
, unsigned int, unsigned int *);
156 static int get_serial_info(i2ChanStrPtr
, struct serial_struct
*);
157 static int set_serial_info(i2ChanStrPtr
, struct serial_struct
*);
159 static ssize_t
ip2_ipl_read(struct file
*, char *, size_t, loff_t
*) ;
160 static ssize_t
ip2_ipl_write(struct file
*, const char *, size_t, loff_t
*);
161 static int ip2_ipl_ioctl(struct inode
*, struct file
*, UINT
, ULONG
);
162 static int ip2_ipl_open(struct inode
*, struct file
*);
164 void ip2trace(unsigned short,unsigned char,unsigned char,unsigned long,...);
165 static int DumpTraceBuffer(char *, int);
166 static int DumpFifoBuffer( char *, int);
168 static void ip2_init_board(int);
169 static unsigned short find_eisa_board(int);
175 static struct tty_driver ip2_tty_driver
;
176 static struct tty_driver ip2_callout_driver
;
178 static int ref_count
;
180 /* Here, then is a table of board pointers which the interrupt routine should
181 * scan through to determine who it must service.
183 static unsigned short i2nBoards
= 0; // Number of boards here
185 static i2eBordStrPtr i2BoardPtrTable
[IP2_MAX_BOARDS
];
187 static i2ChanStrPtr DevTable
[IP2_MAX_PORTS
];
188 //DevTableMem just used to save addresses for kfree
189 static void *DevTableMem
[IP2_MAX_BOARDS
] = {NULL
,NULL
,NULL
,NULL
};
191 static struct tty_struct
* TtyTable
[IP2_MAX_PORTS
];
192 static struct termios
* Termios
[IP2_MAX_PORTS
];
193 static struct termios
* TermiosLocked
[IP2_MAX_PORTS
];
195 /* This is the driver descriptor for the ip2ipl device, which is used to
196 * download the loadware to the boards.
198 static struct file_operations
216 static long irq_counter
= 0;
217 static long bh_counter
= 0;
219 // Use immediate queue to service interrupts
220 //#define USE_IQI // PCI&2.2 needs work
221 //#define USE_IQ // PCI&2.2 needs work
223 /* The timer_list entry for our poll routine. If interrupt operation is not
224 * selected, the board is serviced periodically to see if anything needs doing.
226 #define POLL_TIMEOUT (jiffies + 1)
227 static struct timer_list PollTimer
= { NULL
, NULL
, 0, 0, ip2_poll
};
228 // next, prev, expires,data, func()
229 static char TimerOn
= 0;
231 #ifdef IP2DEBUG_TRACE
232 /* Trace (debug) buffer data */
233 #define TRACEMAX 1000
234 static unsigned long tracebuf
[TRACEMAX
];
235 static int tracestuff
= 0;
236 static int tracestrip
= 0;
237 static int tracewrap
= 0;
244 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
245 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
246 kdevname(tty->device),(pCh->flags),ref_count, \
247 tty->count,/*GET_USE_COUNT(module)*/0,s)
252 #define MIN(a,b) ( ( (a) < (b) ) ? (a) : (b) )
253 #define MAX(a,b) ( ( (a) > (b) ) ? (a) : (b) )
259 #include "./ip2/i2ellis.c" /* Extremely low-level interface services */
260 #include "./ip2/i2cmd.c" /* Standard loadware command definitions */
261 #include "./ip2/i2lib.c" /* High level interface services */
263 /* Configuration area for modprobe */
265 MODULE_AUTHOR("Doug McNash");
266 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
269 static int poll_only
= 0;
271 static int Pci_index
= 0;
272 static int Eisa_irq
= 0;
273 static int Eisa_slot
= 0;
275 static int iindx
= 0;
276 static char rirqs
[IP2_MAX_BOARDS
] = {0,};
277 static int Valid_Irqs
[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
279 /******************************************************************************/
280 /* Initialisation Section */
281 /******************************************************************************/
283 ip2_loadmain(int *iop
, int *irqp
, unsigned char *firmware
, int firmsize
)
286 /* process command line arguments to modprobe or insmod i.e. iop & irqp */
287 /* otherwise ip2config is initialized by what's in ip2/ip2.h */
288 /* command line trumps initialization in ip2.h */
289 /* first two args are null if builtin to kernel */
290 if ((irqp
!= NULL
) || (iop
!= NULL
)) {
291 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
292 if (irqp
&& irqp
[i
]) {
293 ip2config
.irq
[i
] = irqp
[i
];
296 ip2config
.addr
[i
] = iop
[i
];
300 Fip_firmware
= firmware
;
301 Fip_firmware_size
= firmsize
;
302 return old_ip2_init();
305 // Some functions to keep track of what irq's we have
308 is_valid_irq(int irq
)
312 while ((*i
!= 0) && (*i
!= irq
)) {
319 mark_requested_irq( char irq
)
321 rirqs
[iindx
++] = irq
;
325 clear_requested_irq( char irq
)
328 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
329 if (rirqs
[i
] == irq
) {
338 have_requested_irq( char irq
)
340 // array init to zeros so 0 irq will not be requested as a side effect
342 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
349 /******************************************************************************/
350 /* Function: init_module() */
351 /* Parameters: None */
352 /* Returns: Success (0) */
355 /* This is a required entry point for an installable module. It simply calls */
356 /* the driver initialisation function and returns what it returns. */
357 /******************************************************************************/
363 printk (KERN_DEBUG
"Loading module ...\n" );
365 //was return old_ip2_init();
370 /******************************************************************************/
371 /* Function: cleanup_module() */
372 /* Parameters: None */
373 /* Returns: Nothing */
376 /* This is a required entry point for an installable module. It has to return */
377 /* the device and the driver to a passive state. It should not be necessary */
378 /* to reset the board fully, especially as the loadware is downloaded */
379 /* externally rather than in the driver. We just want to disable the board */
380 /* and clear the loadware to a reset state. To allow this there has to be a */
381 /* way to detect whether the board has the loadware running at init time to */
382 /* handle subsequent installations of the driver. All memory allocated by the */
383 /* driver should be returned since it may be unloaded from memory. */
384 /******************************************************************************/
393 printk (KERN_DEBUG
"Unloading %s: version %s\n", pcName
, pcVersion
);
397 /* Stop poll timer if we had one. */
399 del_timer ( &PollTimer
);
403 /* Reset the boards we have. */
404 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
405 if ( i2BoardPtrTable
[i
] ) {
406 iiReset ( i2BoardPtrTable
[i
] );
410 /* The following is done at most once, if any boards were installed. */
411 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
412 if ( i2BoardPtrTable
[i
] ) {
413 iiResetDelay( i2BoardPtrTable
[i
] );
414 /* free io addresses and Tibet */
415 release_region( ip2config
.addr
[i
], 8 );
417 /* Disable and remove interrupt handler. */
418 if ( (ip2config
.irq
[i
] > 0) && have_requested_irq(ip2config
.irq
[i
]) ) {
419 free_irq ( ip2config
.irq
[i
], (void *)&pcName
);
420 clear_requested_irq( ip2config
.irq
[i
]);
423 if ( ( err
= tty_unregister_driver ( &ip2_tty_driver
) ) ) {
424 printk(KERN_ERR
"IP2: failed to unregister tty driver (%d)\n", err
);
426 if ( ( err
= tty_unregister_driver ( &ip2_callout_driver
) ) ) {
427 printk(KERN_ERR
"IP2: failed to unregister callout driver (%d)\n", err
);
429 if ( ( err
= unregister_chrdev ( IP2_IPL_MAJOR
, pcIpl
) ) ) {
430 printk(KERN_ERR
"IP2: failed to unregister IPL driver (%d)\n", err
);
432 if ( ( err
= proc_unregister( &proc_root
, ip2_proc_entry
.low_ino
) ) ) {
433 printk(KERN_ERR
"IP2: failed to unregister read_procmem (%d)\n", err
);
437 for (i
= 0; i
< IP2_MAX_BOARDS
; i
++) {
439 if ((pB
= i2BoardPtrTable
[i
]) != 0 ) {
441 i2BoardPtrTable
[i
] = NULL
;
443 if ((DevTableMem
[i
]) != NULL
) {
444 kfree ( DevTableMem
[i
] );
445 DevTableMem
[i
] = NULL
;
449 /* Cleanup the iiEllis subsystem. */
452 printk (KERN_DEBUG
"IP2 Unloaded\n" );
457 /******************************************************************************/
458 /* Function: old_ip2_init() */
459 /* Parameters: irq, io from command line of insmod et. al. */
460 /* Returns: Success (0) */
463 /* This was the required entry point for all drivers (now in ip2.c) */
464 /* It performs all */
465 /* initialisation of the devices and driver structures, and registers itself */
466 /* with the relevant kernel modules. */
467 /******************************************************************************/
468 /* SA_INTERRUPT- if set blocks all interrupts else only this line */
469 /* SA_SHIRQ - for shared irq PCI or maybe EISA only */
470 /* SA_RANDOM - can be source for cert. random number generators */
471 #define IP2_SA_FLAGS 0
479 i2eBordStrPtr pB
= NULL
;
482 #ifdef IP2DEBUG_TRACE
483 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, ITRC_ENTER
, 0 );
486 /* Announce our presence */
487 printk( KERN_INFO
"%s version %s\n", pcName
, pcVersion
);
489 /* if all irq config is zero we shall poll_only */
490 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
491 poll_only
|= ip2config
.irq
[i
];
493 poll_only
= !poll_only
;
495 /* Initialise the iiEllis subsystem. */
498 /* Initialize arrays. */
499 memset( i2BoardPtrTable
, 0, sizeof i2BoardPtrTable
);
500 memset( DevTable
, 0, sizeof DevTable
);
501 memset( TtyTable
, 0, sizeof TtyTable
);
502 memset( Termios
, 0, sizeof Termios
);
503 memset( TermiosLocked
, 0, sizeof TermiosLocked
);
505 /* Initialise all the boards we can find (up to the maximum). */
506 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
507 switch ( ip2config
.addr
[i
] ) {
508 case 0: /* skip this slot even if card is present */
511 /* ISA address must be specified */
512 if ( (ip2config
.addr
[i
] < 0x100) || (ip2config
.addr
[i
] > 0x3f8) ) {
513 printk ( KERN_ERR
"IP2: Bad ISA board %d address %x\n",
514 i
, ip2config
.addr
[i
] );
515 ip2config
.addr
[i
] = 0;
517 ip2config
.type
[i
] = ISA
;
519 /* Check for valid irq argument, set for polling if invalid */
520 if (ip2config
.irq
[i
] && !is_valid_irq(ip2config
.irq
[i
])) {
521 printk(KERN_ERR
"IP2: Bad IRQ(%d) specified\n",ip2config
.irq
[i
]);
522 ip2config
.irq
[i
] = 0;// 0 is polling and is valid in that sense
529 struct pci_dev
*pci_dev_i
= NULL
;
530 pci_dev_i
= pci_find_device(PCI_VENDOR_ID_COMPUTONE
,
531 PCI_DEVICE_ID_COMPUTONE_IP2EX
, pci_dev_i
);
532 if (pci_dev_i
!= NULL
) {
534 unsigned char pci_irq
;
536 ip2config
.type
[i
] = PCI
;
538 * Update Pci_index, so that the next time we go
539 * searching for a PCI board we find a different
544 pci_read_config_dword(pci_dev_i
, PCI_BASE_ADDRESS_1
, &addr
);
546 ip2config
.addr
[i
]=(USHORT
)(addr
&0xfffe);
548 printk( KERN_ERR
"IP2: PCI I/O address error\n");
551 pci_read_config_byte(pci_dev_i
, PCI_INTERRUPT_LINE
, &pci_irq
);
553 if (!is_valid_irq(pci_irq
)) {
554 printk( KERN_ERR
"IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq
);
557 ip2config
.irq
[i
] = pci_irq
;
558 } else { // ann error
559 ip2config
.addr
[i
] = 0;
560 if (status
== PCIBIOS_DEVICE_NOT_FOUND
) {
561 printk( KERN_ERR
"IP2: PCI board %d not found\n", i
);
563 pcibios_strerror(status
);
568 printk( KERN_ERR
"IP2: PCI card specified but PCI support not\n");
569 printk( KERN_ERR
"IP2: configured in this kernel.\n");
570 printk( KERN_ERR
"IP2: Recompile kernel with CONFIG_PCI defined!\n");
571 #endif /* CONFIG_PCI */
574 if ( (ip2config
.addr
[i
] = find_eisa_board( Eisa_slot
+ 1 )) != 0) {
575 /* Eisa_irq set as side effect, boo */
576 ip2config
.type
[i
] = EISA
;
578 ip2config
.irq
[i
] = Eisa_irq
;
582 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
583 if ( ip2config
.addr
[i
] ) {
584 pB
= kmalloc( sizeof(i2eBordStr
), GFP_KERNEL
);
586 i2BoardPtrTable
[i
] = pB
;
587 memset( pB
, 0, sizeof(i2eBordStr
) );
588 iiSetAddress( pB
, ip2config
.addr
[i
], ii2DelayTimer
);
591 printk(KERN_ERR
"IP2: board memory allocation error\n");
595 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
596 if ( ( pB
= i2BoardPtrTable
[i
] ) != NULL
) {
601 for ( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
602 if ( i2BoardPtrTable
[i
] != NULL
) {
607 #ifdef IP2DEBUG_TRACE
608 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, 2, 0 );
611 /* Zero out the normal tty device structure. */
612 memset ( &ip2_tty_driver
, 0, sizeof ip2_tty_driver
);
614 /* Initialise the relevant fields. */
615 ip2_tty_driver
.magic
= TTY_DRIVER_MAGIC
;
616 ip2_tty_driver
.name
= pcTty
;
617 ip2_tty_driver
.driver_name
= pcDriver_name
;
618 ip2_tty_driver
.read_proc
= ip2_read_proc
;
619 ip2_tty_driver
.major
= IP2_TTY_MAJOR
;
620 ip2_tty_driver
.minor_start
= 0;
621 ip2_tty_driver
.num
= IP2_MAX_PORTS
;
622 ip2_tty_driver
.type
= TTY_DRIVER_TYPE_SERIAL
;
623 ip2_tty_driver
.subtype
= SERIAL_TYPE_NORMAL
;
624 ip2_tty_driver
.init_termios
= tty_std_termios
;
625 ip2_tty_driver
.init_termios
.c_cflag
= B9600
|CS8
|CREAD
|HUPCL
|CLOCAL
;
626 ip2_tty_driver
.flags
= TTY_DRIVER_REAL_RAW
;
627 ip2_tty_driver
.refcount
= &ref_count
;
628 ip2_tty_driver
.table
= TtyTable
;
629 ip2_tty_driver
.termios
= Termios
;
630 ip2_tty_driver
.termios_locked
= TermiosLocked
;
632 /* Setup the pointers to the implemented functions. */
633 ip2_tty_driver
.open
= ip2_open
;
634 ip2_tty_driver
.close
= ip2_close
;
635 ip2_tty_driver
.write
= ip2_write
;
636 ip2_tty_driver
.put_char
= ip2_putchar
;
637 ip2_tty_driver
.flush_chars
= ip2_flush_chars
;
638 ip2_tty_driver
.write_room
= ip2_write_room
;
639 ip2_tty_driver
.chars_in_buffer
= ip2_chars_in_buf
;
640 ip2_tty_driver
.flush_buffer
= ip2_flush_buffer
;
641 ip2_tty_driver
.ioctl
= ip2_ioctl
;
642 ip2_tty_driver
.throttle
= ip2_throttle
;
643 ip2_tty_driver
.unthrottle
= ip2_unthrottle
;
644 ip2_tty_driver
.set_termios
= ip2_set_termios
;
645 ip2_tty_driver
.set_ldisc
= ip2_set_line_discipline
;
646 ip2_tty_driver
.stop
= ip2_stop
;
647 ip2_tty_driver
.start
= ip2_start
;
648 ip2_tty_driver
.hangup
= ip2_hangup
;
650 /* Initialise the callout driver structure from the tty driver, and
651 * make the needed adjustments.
653 ip2_callout_driver
= ip2_tty_driver
;
654 ip2_callout_driver
.name
= pcCallout
;
655 ip2_callout_driver
.driver_name
= pcDriver_name
;
656 ip2_callout_driver
.read_proc
= NULL
;
657 ip2_callout_driver
.major
= IP2_CALLOUT_MAJOR
;
658 ip2_callout_driver
.subtype
= SERIAL_TYPE_CALLOUT
;
660 #ifdef IP2DEBUG_TRACE
661 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, 3, 0 );
664 /* Register the tty devices. */
665 if ( ( err
= tty_register_driver ( &ip2_tty_driver
) ) ) {
666 printk(KERN_ERR
"IP2: failed to register tty driver (%d)\n", err
);
668 if ( ( err
= tty_register_driver ( &ip2_callout_driver
) ) ) {
669 printk(KERN_ERR
"IP2: failed to register callout driver (%d)\n", err
);
671 /* Register the IPL driver. */
672 if ( ( err
= register_chrdev ( IP2_IPL_MAJOR
, pcIpl
, &ip2_ipl
) ) ) {
673 printk(KERN_ERR
"IP2: failed to register IPL device (%d)\n", err
);
675 /* Register the read_procmem thing */
676 if ( ( err
= proc_register( &proc_root
, &ip2_proc_entry
) ) ) {
677 printk(KERN_ERR
"IP2: failed to register read_procmem (%d)\n", err
);
680 #ifdef IP2DEBUG_TRACE
681 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, 4, 0 );
683 /* Register the interrupt handler or poll handler, depending upon the
684 * specified interrupt.
686 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
687 if ( 0 == ip2config
.addr
[i
] ) {
691 ip2config
.irq
[i
] = CIR_POLL
;
693 if ( ip2config
.irq
[i
] == CIR_POLL
) {
696 PollTimer
.expires
= POLL_TIMEOUT
;
697 add_timer ( &PollTimer
);
699 printk( KERN_INFO
"IP2: polling\n");
702 if (have_requested_irq(ip2config
.irq
[i
]))
704 rc
= request_irq( ip2config
.irq
[i
], ip2_interrupt
,
705 IP2_SA_FLAGS
| (ip2config
.type
[i
] == PCI
? SA_SHIRQ
: 0),
706 pcName
, (void *)&pcName
);
708 printk(KERN_ERR
"IP2: an request_irq failed: error %d\n",rc
);
709 ip2config
.irq
[i
] = CIR_POLL
;
710 printk( KERN_INFO
"IP2: Polling %ld/sec.\n",
711 (POLL_TIMEOUT
- jiffies
));
714 mark_requested_irq(ip2config
.irq
[i
]);
715 /* Initialise the interrupt handler bottom half (aka slih). */
718 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
719 if ( i2BoardPtrTable
[i
] ) {
720 set_irq( i
, ip2config
.irq
[i
] ); /* set and enable board interrupt */
724 #ifdef IP2DEBUG_TRACE
725 ip2trace (ITRC_NO_PORT
, ITRC_INIT
, ITRC_RETURN
, 0 );
731 /******************************************************************************/
732 /* Function: ip2_init_board() */
733 /* Parameters: Index of board in configuration structure */
734 /* Returns: Success (0) */
737 /* This function initializes the specified board. The loadware is copied to */
738 /* the board, the channel structures are initialized, and the board details */
739 /* are reported on the console. */
740 /******************************************************************************/
742 ip2_init_board( int boardnum
)
745 int nports
= 0, nboxes
= 0;
747 i2eBordStrPtr pB
= i2BoardPtrTable
[boardnum
];
749 if ( !iiInitialize ( pB
) ) {
750 printk ( KERN_ERR
"IP2: Failed to initialize board at 0x%x, error %d\n",
751 pB
->i2eBase
, pB
->i2eError
);
753 i2BoardPtrTable
[boardnum
] = NULL
;
756 printk(KERN_INFO
"Board %d: addr=0x%x irq=%d ", boardnum
+ 1,
757 ip2config
.addr
[boardnum
], ip2config
.irq
[boardnum
] );
759 if (0 != ( rc
= check_region( ip2config
.addr
[boardnum
], 8))) {
760 i2BoardPtrTable
[boardnum
] = NULL
;
761 printk(KERN_ERR
"bad addr=0x%x rc = %d\n",
762 ip2config
.addr
[boardnum
], rc
);
765 request_region( ip2config
.addr
[boardnum
], 8, pcName
);
767 if ( iiDownloadAll ( pB
, (loadHdrStrPtr
)Fip_firmware
, 1, Fip_firmware_size
)
769 printk ( KERN_ERR
"IP2:failed to download loadware " );
771 printk ( KERN_INFO
"fv=%d.%d.%d lv=%d.%d.%d\n",
772 pB
->i2ePom
.e
.porVersion
,
773 pB
->i2ePom
.e
.porRevision
,
774 pB
->i2ePom
.e
.porSubRev
, pB
->i2eLVersion
,
775 pB
->i2eLRevision
, pB
->i2eLSub
);
778 switch ( pB
->i2ePom
.e
.porID
& ~POR_ID_RESERVED
) {
781 printk( KERN_ERR
"IP2: Unknown board type, ID = %x",
782 pB
->i2ePom
.e
.porID
);
787 case POR_ID_II_4
: /* IntelliPort-II, ISA-4 (4xRJ45) */
788 printk ( KERN_INFO
"ISA-4" );
792 case POR_ID_II_8
: /* IntelliPort-II, 8-port using standard brick. */
793 printk ( KERN_INFO
"ISA-8 std" );
797 case POR_ID_II_8R
: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
798 printk ( KERN_INFO
"ISA-8 RJ11" );
802 case POR_ID_FIIEX
: /* IntelliPort IIEX */
804 int portnum
= IP2_PORTS_PER_BOARD
* boardnum
;
807 for( box
= 0; box
< ABS_MAX_BOXES
; ++box
) {
808 if ( pB
->i2eChannelMap
[box
] != 0 ) {
811 for( i
= 0; i
< ABS_BIGGEST_BOX
; ++i
) {
812 if ( pB
->i2eChannelMap
[box
] & 1<< i
) {
817 DevTableMem
[boardnum
] = pCh
=
818 kmalloc( sizeof(i2ChanStr
) * nports
, GFP_KERNEL
);
819 if ( !i2InitChannels( pB
, nports
, pCh
) ) {
820 printk(KERN_ERR
"i2InitChannels failed: %d\n",pB
->i2eError
);
822 pB
->i2eChannelPtr
= &DevTable
[portnum
];
823 pB
->i2eChannelCnt
= ABS_MOST_PORTS
;
825 for( box
= 0; box
< ABS_MAX_BOXES
; ++box
, portnum
+= ABS_BIGGEST_BOX
) {
826 for( i
= 0; i
< ABS_BIGGEST_BOX
; ++i
) {
827 if ( pB
->i2eChannelMap
[box
] & (1 << i
) ) {
828 DevTable
[portnum
+ i
] = pCh
;
829 pCh
->port_index
= portnum
+ i
;
834 printk(KERN_INFO
"IP2: EX box=%d ports=%d %d bit",
835 nboxes
, nports
, pB
->i2eDataWidth16
? 16 : 8 );
840 DevTableMem
[boardnum
] = pCh
=
841 kmalloc ( sizeof (i2ChanStr
) * nports
, GFP_KERNEL
);
842 pB
->i2eChannelPtr
= pCh
;
843 pB
->i2eChannelCnt
= nports
;
844 i2InitChannels ( pB
, pB
->i2eChannelCnt
, pCh
);
845 pB
->i2eChannelPtr
= &DevTable
[IP2_PORTS_PER_BOARD
* boardnum
];
847 for( i
= 0; i
< pB
->i2eChannelCnt
; ++i
) {
848 DevTable
[IP2_PORTS_PER_BOARD
* boardnum
+ i
] = pCh
;
849 pCh
->port_index
= (IP2_PORTS_PER_BOARD
* boardnum
) + i
;
853 printk ( KERN_INFO
"\n" );
856 /******************************************************************************/
857 /* Function: find_eisa_board ( int start_slot ) */
858 /* Parameters: First slot to check */
859 /* Returns: Address of EISA IntelliPort II controller */
862 /* This function searches for an EISA IntelliPort controller, starting */
863 /* from the specified slot number. If the motherboard is not identified as an */
864 /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
865 /* it returns the base address of the controller. */
866 /******************************************************************************/
867 static unsigned short __init
868 find_eisa_board( int start_slot
)
871 unsigned int idm
= 0;
872 unsigned int idp
= 0;
873 unsigned int base
= 0;
880 * First a check for an EISA motherboard, which we do by comparing the
881 * EISA ID registers for the system board and the first couple of slots.
882 * No slot ID should match the system board ID, but on an ISA or PCI
883 * machine the odds are that an empty bus will return similar values for
887 value
= (inb(i
) << 24) + (inb(i
+1) << 16) + (inb(i
+2) << 8) + inb(i
+3);
888 for( i
= 0x1c80; i
<= 0x4c80; i
+= 0x1000 ) {
889 j
= (inb(i
)<<24)+(inb(i
+1)<<16)+(inb(i
+2)<<8)+inb(i
+3);
895 * OK, so we are inclined to believe that this is an EISA machine. Find
896 * an IntelliPort controller.
898 for( i
= start_slot
; i
< 16; i
++ ) {
900 idm
= (inb(base
+ 0xc80) << 8) | (inb(base
+ 0xc81) & 0xff);
901 idp
= (inb(base
+ 0xc82) << 8) | (inb(base
+ 0xc83) & 0xff);
903 if ( idm
== 0x0e8e ) {
904 if ( idp
== 0x0281 || idp
== 0x0218 ) {
906 } else if ( idp
== 0x0282 || idp
== 0x0283 ) {
907 ismine
= 3; /* Can do edge-trigger */
918 /* It's some sort of EISA card, but at what address is it configured? */
920 setup_address
= base
+ 0xc88;
921 value
= inb(base
+ 0xc86);
922 setup_irq
= (value
& 8) ? Valid_Irqs
[value
& 7] : 0;
924 if ( (ismine
& 2) && !(value
& 0x10) ) {
925 ismine
= 1; /* Could be edging, but not */
928 if ( Eisa_irq
== 0 ) {
929 Eisa_irq
= setup_irq
;
930 } else if ( Eisa_irq
!= setup_irq
) {
931 printk ( KERN_ERR
"IP2: EISA irq mismatch between EISA controllers\n" );
935 printk(KERN_DEBUG
"Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
936 base
>> 12, idm
, idp
, setup_address
);
938 printk(KERN_DEBUG
", Interrupt %d %s\n",
939 setup_irq
, (ismine
& 2) ? "(edge)" : "(level)");
941 printk(KERN_DEBUG
", (polled)\n");
944 return setup_address
;
947 /******************************************************************************/
948 /* Function: set_irq() */
949 /* Parameters: index to board in board table */
951 /* Returns: Success (0) */
954 /******************************************************************************/
956 set_irq( int boardnum
, int boardIrq
)
959 unsigned char tempCommand
[16];
960 i2eBordStrPtr pB
= i2BoardPtrTable
[boardnum
];
964 * Notify the boards they may generate interrupts. This is done by
965 * sending an in-line command to channel 0 on each board. This is why
966 * the channels have to be defined already. For each board, if the
967 * interrupt has never been defined, we must do so NOW, directly, since
968 * board will not send flow control or even give an interrupt until this
969 * is done. If polling we must send 0 as the interrupt parameter.
972 pCh
= (i2ChanStrPtr
) pB
->i2eChannelPtr
;
974 // We will get an interrupt here at the end of this function
976 iiDisableMailIrq(pB
);
978 /* We build up the entire packet header. */
979 CHANNEL_OF(tempCommand
) = 0;
980 PTYPE_OF(tempCommand
) = PTYPE_INLINE
;
981 CMD_COUNT_OF(tempCommand
) = 2;
982 (CMD_OF(tempCommand
))[0] = CMDVALUE_IRQ
;
983 (CMD_OF(tempCommand
))[1] = boardIrq
;
985 * Write to FIFO; don't bother to adjust fifo capacity for this, since
986 * board will respond almost immediately after SendMail hit.
988 WRITE_LOCK_IRQSAVE(&pB
->write_fifo_spinlock
,flags
);
989 iiWriteBuf(pB
, tempCommand
, 4);
990 WRITE_UNLOCK_IRQRESTORE(&pB
->write_fifo_spinlock
,flags
);
991 pB
->i2eUsingIrq
= boardIrq
;
992 pB
->i2eOutMailWaiting
|= MB_OUT_STUFFED
;
994 /* Need to update number of boards before you enable mailbox int */
997 CHANNEL_OF(tempCommand
) = 0;
998 PTYPE_OF(tempCommand
) = PTYPE_BYPASS
;
999 CMD_COUNT_OF(tempCommand
) = 6;
1000 (CMD_OF(tempCommand
))[0] = 88; // SILO
1001 (CMD_OF(tempCommand
))[1] = 64; // chars
1002 (CMD_OF(tempCommand
))[2] = 32; // ms
1004 (CMD_OF(tempCommand
))[3] = 28; // MAX_BLOCK
1005 (CMD_OF(tempCommand
))[4] = 64; // chars
1007 (CMD_OF(tempCommand
))[5] = 87; // HW_TEST
1008 WRITE_LOCK_IRQSAVE(&pB
->write_fifo_spinlock
,flags
);
1009 iiWriteBuf(pB
, tempCommand
, 8);
1010 WRITE_UNLOCK_IRQRESTORE(&pB
->write_fifo_spinlock
,flags
);
1012 CHANNEL_OF(tempCommand
) = 0;
1013 PTYPE_OF(tempCommand
) = PTYPE_BYPASS
;
1014 CMD_COUNT_OF(tempCommand
) = 1;
1015 (CMD_OF(tempCommand
))[0] = 84; /* get BOX_IDS */
1016 iiWriteBuf(pB
, tempCommand
, 3);
1019 // enable heartbeat for test porpoises
1020 CHANNEL_OF(tempCommand
) = 0;
1021 PTYPE_OF(tempCommand
) = PTYPE_BYPASS
;
1022 CMD_COUNT_OF(tempCommand
) = 2;
1023 (CMD_OF(tempCommand
))[0] = 44; /* get ping */
1024 (CMD_OF(tempCommand
))[1] = 200; /* 200 ms */
1025 WRITE_LOCK_IRQSAVE(&pB
->write_fifo_spinlock
,flags
);
1026 iiWriteBuf(pB
, tempCommand
, 4);
1027 WRITE_UNLOCK_IRQRESTORE(&pB
->write_fifo_spinlock
,flags
);
1030 iiEnableMailIrq(pB
);
1031 iiSendPendingMail(pB
);
1034 /******************************************************************************/
1035 /* Interrupt Handler Section */
1036 /******************************************************************************/
1039 service_all_boards()
1044 /* Service every board on the list */
1045 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
1046 pB
= i2BoardPtrTable
[i
];
1048 i2ServiceBoard( pB
);
1055 static struct tq_struct
1057 { // it's the death that worse than fate
1060 (void(*)(void*)) service_all_boards
,
1061 NULL
, //later - board address XXX
1065 /******************************************************************************/
1066 /* Function: ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs) */
1067 /* Parameters: irq - interrupt number */
1068 /* pointer to optional device ID structure */
1069 /* pointer to register structure */
1070 /* Returns: Nothing */
1075 /******************************************************************************/
1077 ip2_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
)
1082 #ifdef IP2DEBUG_TRACE
1083 ip2trace (ITRC_NO_PORT
, ITRC_INTR
, 99, 1, irq
);
1088 queue_task(&senior_service
, &tq_immediate
);
1089 mark_bh(IMMEDIATE_BH
);
1092 /* Service just the boards on the list using this irq */
1093 for( i
= 0; i
< i2nBoards
; ++i
) {
1094 pB
= i2BoardPtrTable
[i
];
1095 if ( pB
&& (pB
->i2eUsingIrq
== irq
) ) {
1096 i2ServiceBoard( pB
);
1100 #endif /* USE_IQI */
1104 #ifdef IP2DEBUG_TRACE
1105 ip2trace (ITRC_NO_PORT
, ITRC_INTR
, ITRC_RETURN
, 0 );
1109 /******************************************************************************/
1110 /* Function: ip2_poll(unsigned long arg) */
1112 /* Returns: Nothing */
1115 /* This function calls the library routine i2ServiceBoard for each board in */
1116 /* the board table. This is used instead of the interrupt routine when polled */
1117 /* mode is specified. */
1118 /******************************************************************************/
1120 ip2_poll(unsigned long arg
)
1122 #ifdef IP2DEBUG_TRACE
1123 ip2trace (ITRC_NO_PORT
, ITRC_INTR
, 100, 0 );
1125 TimerOn
= 0; // it's the truth but not checked in service
1131 queue_task(&senior_service
, &tq_immediate
);
1132 mark_bh(IMMEDIATE_BH
);
1135 // Just polled boards, service_all might be better
1136 ip2_interrupt(0, NULL
, NULL
);
1138 #endif /* USE_IQI */
1140 PollTimer
.expires
= POLL_TIMEOUT
;
1141 add_timer( &PollTimer
);
1144 #ifdef IP2DEBUG_TRACE
1145 ip2trace (ITRC_NO_PORT
, ITRC_INTR
, ITRC_RETURN
, 0 );
1150 do_input( i2ChanStrPtr pCh
)
1152 unsigned long flags
;
1154 #ifdef IP2DEBUG_TRACE
1155 ip2trace(PORTN
, ITRC_INPUT
, 21, 0 );
1158 if ( pCh
->pTTY
!= NULL
) {
1159 READ_LOCK_IRQSAVE(&pCh
->Ibuf_spinlock
,flags
)
1160 if (!pCh
->throttled
&& (pCh
->Ibuf_stuff
!= pCh
->Ibuf_strip
)) {
1161 READ_UNLOCK_IRQRESTORE(&pCh
->Ibuf_spinlock
,flags
)
1164 READ_UNLOCK_IRQRESTORE(&pCh
->Ibuf_spinlock
,flags
)
1166 #ifdef IP2DEBUG_TRACE
1167 ip2trace(PORTN
, ITRC_INPUT
, 22, 0 );
1169 i2InputFlush( pCh
);
1173 // code duplicated from n_tty (ldisc)
1175 isig(int sig
, struct tty_struct
*tty
, int flush
)
1178 kill_pg(tty
->pgrp
, sig
, 1);
1179 if (flush
|| !L_NOFLSH(tty
)) {
1180 if ( tty
->ldisc
.flush_buffer
)
1181 tty
->ldisc
.flush_buffer(tty
);
1182 i2InputFlush( tty
->driver_data
);
1187 do_status( i2ChanStrPtr pCh
)
1191 status
= i2GetStatus( pCh
, (I2_BRK
|I2_PAR
|I2_FRA
|I2_OVR
) );
1193 #ifdef IP2DEBUG_TRACE
1194 ip2trace (PORTN
, ITRC_STATUS
, 21, 1, status
);
1197 if (pCh
->pTTY
&& (status
& (I2_BRK
|I2_PAR
|I2_FRA
|I2_OVR
)) ) {
1198 if ( (status
& I2_BRK
) ) {
1199 // code duplicated from n_tty (ldisc)
1200 if (I_IGNBRK(pCh
->pTTY
))
1202 if (I_BRKINT(pCh
->pTTY
)) {
1203 isig(SIGINT
, pCh
->pTTY
, 1);
1206 wake_up_interruptible(&pCh
->pTTY
->read_wait
);
1208 #ifdef NEVER_HAPPENS_AS_SETUP_XXX
1209 // and can't work because we don't know the_char
1210 // as the_char is reported on a seperate path
1211 // The intelligent board does this stuff as setup
1213 char brkf
= TTY_NORMAL
;
1214 unsigned char brkc
= '\0';
1216 if ( (status
& I2_BRK
) ) {
1220 else if (status
& I2_PAR
) {
1223 } else if (status
& I2_FRA
) {
1226 } else if (status
& I2_OVR
) {
1230 tmp
= pCh
->pTTY
->real_raw
;
1231 pCh
->pTTY
->real_raw
= 0;
1232 pCh
->pTTY
->ldisc
.receive_buf( pCh
->pTTY
, &brkc
, &brkf
, 1 );
1233 pCh
->pTTY
->real_raw
= tmp
;
1235 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1239 if ( status
& (I2_DDCD
| I2_DDSR
| I2_DCTS
| I2_DRI
) ) {
1240 wake_up_interruptible(&pCh
->delta_msr_wait
);
1242 if ( (pCh
->flags
& ASYNC_CHECK_CD
) && (status
& I2_DDCD
) ) {
1243 if ( status
& I2_DCD
) {
1245 wake_up_interruptible ( &pCh
->open_wait
);
1247 } else if ( !(pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) ) {
1248 if (pCh
->pTTY
&& (!(pCh
->pTTY
->termios
->c_cflag
& CLOCAL
)) ) {
1249 tty_hangup( pCh
->pTTY
);
1255 #ifdef IP2DEBUG_TRACE
1256 ip2trace (PORTN
, ITRC_STATUS
, 26, 0 );
1260 /******************************************************************************/
1261 /* Device Open/Close/Ioctl Entry Point Section */
1262 /******************************************************************************/
1264 /******************************************************************************/
1265 /* Function: open_sanity_check() */
1266 /* Parameters: Pointer to tty structure */
1267 /* Pointer to file structure */
1268 /* Returns: Success or failure */
1271 /* Verifies the structure magic numbers and cross links. */
1272 /******************************************************************************/
1273 #ifdef IP2DEBUG_OPEN
1275 open_sanity_check( i2ChanStrPtr pCh
, i2eBordStrPtr pBrd
)
1277 if ( pBrd
->i2eValid
!= I2E_MAGIC
) {
1278 printk(KERN_ERR
"IP2: invalid board structure\n" );
1279 } else if ( pBrd
!= pCh
->pMyBord
) {
1280 printk(KERN_ERR
"IP2: board structure pointer mismatch (%p)\n",
1282 } else if ( pBrd
->i2eChannelCnt
< pCh
->port_index
) {
1283 printk(KERN_ERR
"IP2: bad device index (%d)\n", pCh
->port_index
);
1284 } else if (&((i2ChanStrPtr
)pBrd
->i2eChannelPtr
)[pCh
->port_index
] != pCh
) {
1286 printk(KERN_INFO
"IP2: all pointers check out!\n" );
1292 /******************************************************************************/
1293 /* Function: ip2_open() */
1294 /* Parameters: Pointer to tty structure */
1295 /* Pointer to file structure */
1296 /* Returns: Success or failure */
1298 /* Description: (MANDATORY) */
1299 /* A successful device open has to run a gauntlet of checks before it */
1300 /* completes. After some sanity checking and pointer setup, the function */
1301 /* blocks until all conditions are satisfied. It then initialises the port to */
1302 /* the default characteristics and returns. */
1303 /******************************************************************************/
1305 ip2_open( PTTY tty
, struct file
*pFile
)
1309 i2ChanStrPtr pCh
= DevTable
[MINOR(tty
->device
)];
1311 #ifdef IP2DEBUG_TRACE
1312 ip2trace (MINOR(tty
->device
), ITRC_OPEN
, ITRC_ENTER
, 0 );
1315 if ( pCh
== NULL
) {
1318 /* Setup pointer links in device and tty structures */
1320 tty
->driver_data
= pCh
;
1323 #ifdef IP2DEBUG_OPEN
1325 "IP2:open(tty=%p,pFile=%p):dev=%x,maj=%d,min=%d,ch=%d,idx=%d\n",
1326 tty
, pFile
, tty
->device
, MAJOR(tty
->device
), MINOR(tty
->device
),
1327 pCh
->infl
.hd
.i2sChannel
, pCh
->port_index
);
1328 open_sanity_check ( pCh
, pCh
->pMyBord
);
1331 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 2, CMD_DTRUP
, CMD_RTSUP
);
1332 pCh
->dataSetOut
|= (I2_DTR
| I2_RTS
);
1333 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DCD_REP
);
1334 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 3,
1335 CMD_CTS_REP
, CMD_DSR_REP
, CMD_RI_REP
);
1336 serviceOutgoingFifo( pCh
->pMyBord
);
1338 /* Block here until the port is ready (per serial and istallion) */
1340 * 1. If the port is in the middle of closing wait for the completion
1341 * and then return the appropriate error.
1343 if ( tty_hung_up_p(pFile
) || ( pCh
->flags
& ASYNC_CLOSING
)) {
1344 if ( pCh
->flags
& ASYNC_CLOSING
) {
1345 interruptible_sleep_on( &pCh
->close_wait
);
1347 if ( tty_hung_up_p(pFile
) ) {
1348 return( pCh
->flags
& ASYNC_HUP_NOTIFY
) ? -EAGAIN
: -ERESTARTSYS
;
1352 * 2. If this is a callout device, make sure the normal port is not in
1353 * use, and that someone else doesn't have the callout device locked.
1354 * (These are the only tests the standard serial driver makes for
1357 if ( tty
->driver
.subtype
== SERIAL_TYPE_CALLOUT
) {
1358 if ( pCh
->flags
& ASYNC_NORMAL_ACTIVE
) {
1361 if ( ( pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1362 ( pCh
->flags
& ASYNC_SESSION_LOCKOUT
) &&
1363 ( pCh
->session
!= current
->session
) ) {
1366 if ( ( pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1367 ( pCh
->flags
& ASYNC_PGRP_LOCKOUT
) &&
1368 ( pCh
->pgrp
!= current
->pgrp
) ) {
1371 pCh
->flags
|= ASYNC_CALLOUT_ACTIVE
;
1375 * 3. Handle a non-blocking open of a normal port.
1377 if ( (pFile
->f_flags
& O_NONBLOCK
) || (tty
->flags
& (1<<TTY_IO_ERROR
) )) {
1378 if ( pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) {
1381 pCh
->flags
|= ASYNC_NORMAL_ACTIVE
;
1385 * 4. Now loop waiting for the port to be free and carrier present
1388 if ( pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) {
1389 if ( pCh
->NormalTermios
.c_cflag
& CLOCAL
) {
1393 if ( tty
->termios
->c_cflag
& CLOCAL
) {
1398 #ifdef IP2DEBUG_OPEN
1399 printk(KERN_DEBUG
"OpenBlock: do_clocal = %d\n", do_clocal
);
1404 if ( !(pCh
->flags
& ASYNC_CALLOUT_ACTIVE
)) {
1405 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 2, CMD_DTRUP
, CMD_RTSUP
);
1406 pCh
->dataSetOut
|= (I2_DTR
| I2_RTS
);
1407 serviceOutgoingFifo( pCh
->pMyBord
);
1409 if ( tty_hung_up_p(pFile
) ) {
1410 return ( pCh
->flags
& ASYNC_HUP_NOTIFY
) ? -EBUSY
: -ERESTARTSYS
;
1412 if ( !(pCh
->flags
& ASYNC_CALLOUT_ACTIVE
) &&
1413 !(pCh
->flags
& ASYNC_CLOSING
) &&
1414 (do_clocal
|| (pCh
->dataSetIn
& I2_DCD
) )) {
1419 #ifdef IP2DEBUG_OPEN
1420 printk(KERN_DEBUG
"ASYNC_CALLOUT_ACTIVE = %s\n",
1421 (pCh
->flags
& ASYNC_CALLOUT_ACTIVE
)?"True":"False");
1422 printk(KERN_DEBUG
"ASYNC_CLOSING = %s\n",
1423 (pCh
->flags
& ASYNC_CLOSING
)?"True":"False");
1424 printk(KERN_DEBUG
"OpenBlock: waiting for CD or signal\n");
1426 #ifdef IP2DEBUG_TRACE
1427 ip2trace (PORTN
, ITRC_OPEN
, 3, 2, (pCh
->flags
& ASYNC_CALLOUT_ACTIVE
),
1428 (pCh
->flags
& ASYNC_CLOSING
) );
1430 /* check for signal */
1431 if (signal_pending(current
)) {
1432 rc
= (( pCh
->flags
& ASYNC_HUP_NOTIFY
) ? -EAGAIN
: -ERESTARTSYS
);
1435 interruptible_sleep_on(&pCh
->open_wait
);
1437 --pCh
->wopen
; //why count?
1438 #ifdef IP2DEBUG_TRACE
1439 ip2trace (PORTN
, ITRC_OPEN
, 4, 0 );
1444 pCh
->flags
|= ASYNC_NORMAL_ACTIVE
;
1448 /* first open - Assign termios structure to port */
1449 if ( tty
->count
== 1 ) {
1450 i2QueueCommands(PTYPE_INLINE
, pCh
, 0, 2, CMD_CTSFL_DSAB
, CMD_RTSFL_DSAB
);
1451 if ( pCh
->flags
& ASYNC_SPLIT_TERMIOS
) {
1452 if ( tty
->driver
.subtype
== SERIAL_TYPE_NORMAL
) {
1453 *tty
->termios
= pCh
->NormalTermios
;
1455 *tty
->termios
= pCh
->CalloutTermios
;
1458 /* Now we must send the termios settings to the loadware */
1459 set_params( pCh
, NULL
);
1462 /* override previous and never reset ??? */
1463 pCh
->session
= current
->session
;
1464 pCh
->pgrp
= current
->pgrp
;
1467 * Now set any i2lib options. These may go away if the i2lib code ends
1468 * up rolled into the mainline.
1470 pCh
->channelOptions
|= CO_NBLOCK_WRITE
;
1472 #ifdef IP2DEBUG_OPEN
1473 printk (KERN_DEBUG
"IP2: open completed\n" );
1475 serviceOutgoingFifo( pCh
->pMyBord
);
1477 #ifdef IP2DEBUG_TRACE
1478 ip2trace (PORTN
, ITRC_OPEN
, ITRC_RETURN
, 0 );
1483 /******************************************************************************/
1484 /* Function: ip2_close() */
1485 /* Parameters: Pointer to tty structure */
1486 /* Pointer to file structure */
1487 /* Returns: Nothing */
1492 /******************************************************************************/
1494 ip2_close( PTTY tty
, struct file
*pFile
)
1496 i2ChanStrPtr pCh
= tty
->driver_data
;
1502 #ifdef IP2DEBUG_TRACE
1503 ip2trace (PORTN
, ITRC_CLOSE
, ITRC_ENTER
, 0 );
1506 #ifdef IP2DEBUG_OPEN
1507 printk(KERN_DEBUG
"IP2:close ttyF%02X:\n",MINOR(tty
->device
));
1510 if ( tty_hung_up_p ( pFile
) ) {
1513 #ifdef IP2DEBUG_TRACE
1514 ip2trace (PORTN
, ITRC_CLOSE
, 2, 1, 2 );
1518 if ( tty
->count
> 1 ) { /* not the last close */
1520 #ifdef IP2DEBUG_TRACE
1521 ip2trace (PORTN
, ITRC_CLOSE
, 2, 1, 3 );
1525 pCh
->flags
|= ASYNC_CLOSING
; // last close actually
1528 * Save the termios structure, since this port may have separate termios
1529 * for callout and dialin.
1531 if (pCh
->flags
& ASYNC_NORMAL_ACTIVE
)
1532 pCh
->NormalTermios
= *tty
->termios
;
1533 if (pCh
->flags
& ASYNC_CALLOUT_ACTIVE
)
1534 pCh
->CalloutTermios
= *tty
->termios
;
1538 if (pCh
->ClosingWaitTime
!= ASYNC_CLOSING_WAIT_NONE
) {
1540 * Before we drop DTR, make sure the transmitter has completely drained.
1541 * This uses an timeout, after which the close
1544 ip2_wait_until_sent(tty
, pCh
->ClosingWaitTime
);
1547 * At this point we stop accepting input. Here we flush the channel
1548 * input buffer which will allow the board to send up more data. Any
1549 * additional input is tossed at interrupt/poll time.
1551 i2InputFlush( pCh
);
1553 /* disable DSS reporting */
1554 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DCD_NREP
);
1555 if ( !tty
|| (tty
->termios
->c_cflag
& HUPCL
) ) {
1556 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 2, CMD_RTSDN
, CMD_DTRDN
);
1557 pCh
->dataSetOut
&= ~(I2_DTR
| I2_RTS
);
1558 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_PAUSE(25));
1560 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 3,
1561 CMD_CTS_NREP
, CMD_DSR_NREP
, CMD_RI_NREP
);
1563 serviceOutgoingFifo ( pCh
->pMyBord
);
1565 if ( tty
->driver
.flush_buffer
)
1566 tty
->driver
.flush_buffer(tty
);
1567 if ( tty
->ldisc
.flush_buffer
)
1568 tty
->ldisc
.flush_buffer(tty
);
1574 if (pCh
->ClosingDelay
) {
1575 current
->state
= TASK_INTERRUPTIBLE
;
1576 schedule_timeout(pCh
->ClosingDelay
);
1578 wake_up_interruptible(&pCh
->open_wait
);
1581 pCh
->flags
&=~(ASYNC_NORMAL_ACTIVE
|ASYNC_CALLOUT_ACTIVE
|ASYNC_CLOSING
);
1582 wake_up_interruptible(&pCh
->close_wait
);
1584 #ifdef IP2DEBUG_OPEN
1585 DBG_CNT("ip2_close: after wakeups--");
1590 #ifdef IP2DEBUG_TRACE
1591 ip2trace (PORTN
, ITRC_CLOSE
, ITRC_RETURN
, 1, 1 );
1596 /******************************************************************************/
1597 /* Function: ip2_hangup() */
1598 /* Parameters: Pointer to tty structure */
1599 /* Returns: Nothing */
1604 /******************************************************************************/
1606 ip2_hangup ( PTTY tty
)
1608 i2ChanStrPtr pCh
= tty
->driver_data
;
1610 #ifdef IP2DEBUG_TRACE
1611 ip2trace (PORTN
, ITRC_HANGUP
, ITRC_ENTER
, 0 );
1614 ip2_flush_buffer(tty
);
1616 /* disable DSS reporting */
1618 i2QueueCommands(PTYPE_BYPASS
, pCh
, 0, 1, CMD_DCD_NREP
);
1619 i2QueueCommands(PTYPE_INLINE
, pCh
, 0, 2, CMD_CTSFL_DSAB
, CMD_RTSFL_DSAB
);
1620 if ( !tty
|| (tty
->termios
->c_cflag
& HUPCL
) ) {
1621 i2QueueCommands(PTYPE_BYPASS
, pCh
, 0, 2, CMD_RTSDN
, CMD_DTRDN
);
1622 pCh
->dataSetOut
&= ~(I2_DTR
| I2_RTS
);
1623 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_PAUSE(25));
1625 i2QueueCommands(PTYPE_INLINE
, pCh
, 1, 3,
1626 CMD_CTS_NREP
, CMD_DSR_NREP
, CMD_RI_NREP
);
1627 serviceOutgoingFifo ( pCh
->pMyBord
);
1629 wake_up_interruptible ( &pCh
->delta_msr_wait
);
1631 pCh
->flags
&= ~(ASYNC_NORMAL_ACTIVE
|ASYNC_CALLOUT_ACTIVE
);
1633 wake_up_interruptible ( &pCh
->open_wait
);
1635 #ifdef IP2DEBUG_TRACE
1636 ip2trace (PORTN
, ITRC_HANGUP
, ITRC_RETURN
, 0 );
1640 /******************************************************************************/
1641 /******************************************************************************/
1642 /* Device Output Section */
1643 /******************************************************************************/
1644 /******************************************************************************/
1646 /******************************************************************************/
1647 /* Function: ip2_write() */
1648 /* Parameters: Pointer to tty structure */
1649 /* Flag denoting data is in user (1) or kernel (0) space */
1650 /* Pointer to data */
1651 /* Number of bytes to write */
1652 /* Returns: Number of bytes actually written */
1654 /* Description: (MANDATORY) */
1657 /******************************************************************************/
1659 ip2_write( PTTY tty
, int user
, const unsigned char *pData
, int count
)
1661 i2ChanStrPtr pCh
= tty
->driver_data
;
1663 unsigned long flags
;
1665 #ifdef IP2DEBUG_TRACE
1666 ip2trace (PORTN
, ITRC_WRITE
, ITRC_ENTER
, 2, count
, -1 );
1669 /* Flush out any buffered data left over from ip2_putchar() calls. */
1670 ip2_flush_chars( tty
);
1672 /* This is the actual move bit. Make sure it does what we need!!!!! */
1673 WRITE_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1674 bytesSent
= i2Output( pCh
, pData
, count
, user
);
1675 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1677 #ifdef IP2DEBUG_TRACE
1678 ip2trace (PORTN
, ITRC_WRITE
, ITRC_RETURN
, 1, bytesSent
);
1680 return bytesSent
> 0 ? bytesSent
: 0;
1683 /******************************************************************************/
1684 /* Function: ip2_putchar() */
1685 /* Parameters: Pointer to tty structure */
1686 /* Character to write */
1687 /* Returns: Nothing */
1692 /******************************************************************************/
1694 ip2_putchar( PTTY tty
, unsigned char ch
)
1696 i2ChanStrPtr pCh
= tty
->driver_data
;
1697 unsigned long flags
;
1699 #ifdef IP2DEBUG_TRACE
1700 // ip2trace (PORTN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1703 WRITE_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1704 pCh
->Pbuf
[pCh
->Pbuf_stuff
++] = ch
;
1705 if ( pCh
->Pbuf_stuff
== sizeof pCh
->Pbuf
) {
1706 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1707 ip2_flush_chars( tty
);
1709 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1711 #ifdef IP2DEBUG_TRACE
1712 // ip2trace (PORTN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1716 /******************************************************************************/
1717 /* Function: ip2_flush_chars() */
1718 /* Parameters: Pointer to tty structure */
1719 /* Returns: Nothing */
1723 /******************************************************************************/
1725 ip2_flush_chars( PTTY tty
)
1728 i2ChanStrPtr pCh
= tty
->driver_data
;
1729 unsigned long flags
;
1731 WRITE_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1732 if ( pCh
->Pbuf_stuff
) {
1733 #ifdef IP2DEBUG_TRACE
1734 // ip2trace (PORTN, ITRC_PUTC, 10, 1, strip );
1737 // We may need to restart i2Output if it does not fullfill this request
1739 strip
= i2Output( pCh
, pCh
->Pbuf
, pCh
->Pbuf_stuff
, 0 );
1740 if ( strip
!= pCh
->Pbuf_stuff
) {
1741 memmove( pCh
->Pbuf
, &pCh
->Pbuf
[strip
], pCh
->Pbuf_stuff
- strip
);
1743 pCh
->Pbuf_stuff
-= strip
;
1745 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1748 /******************************************************************************/
1749 /* Function: ip2_write_room() */
1750 /* Parameters: Pointer to tty structure */
1751 /* Returns: Number of bytes that the driver can accept */
1755 /******************************************************************************/
1757 ip2_write_room ( PTTY tty
)
1760 i2ChanStrPtr pCh
= tty
->driver_data
;
1761 unsigned long flags
;
1763 READ_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1764 bytesFree
= i2OutputFree( pCh
) - pCh
->Pbuf_stuff
;
1765 READ_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1767 #ifdef IP2DEBUG_TRACE
1768 ip2trace (PORTN
, ITRC_WRITE
, 11, 1, bytesFree
);
1771 return ((bytesFree
> 0) ? bytesFree
: 0);
1774 /******************************************************************************/
1775 /* Function: ip2_chars_in_buf() */
1776 /* Parameters: Pointer to tty structure */
1777 /* Returns: Number of bytes queued for transmission */
1782 /******************************************************************************/
1784 ip2_chars_in_buf ( PTTY tty
)
1786 i2ChanStrPtr pCh
= tty
->driver_data
;
1788 unsigned long flags
;
1789 #ifdef IP2DEBUG_TRACE
1790 ip2trace (PORTN
, ITRC_WRITE
, 12, 1, pCh
->Obuf_char_count
+ pCh
->Pbuf_stuff
);
1792 #ifdef IP2DEBUG_WRITE
1793 printk (KERN_DEBUG
"IP2: chars in buffer = %d (%d,%d)\n",
1794 pCh
->Obuf_char_count
+ pCh
->Pbuf_stuff
,
1795 pCh
->Obuf_char_count
, pCh
->Pbuf_stuff
);
1797 READ_LOCK_IRQSAVE(&pCh
->Obuf_spinlock
,flags
);
1798 rc
= pCh
->Obuf_char_count
;
1799 READ_UNLOCK_IRQRESTORE(&pCh
->Obuf_spinlock
,flags
);
1800 READ_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1801 rc
+= pCh
->Pbuf_stuff
;
1802 READ_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1806 /******************************************************************************/
1807 /* Function: ip2_flush_buffer() */
1808 /* Parameters: Pointer to tty structure */
1809 /* Returns: Nothing */
1814 /******************************************************************************/
1816 ip2_flush_buffer( PTTY tty
)
1818 i2ChanStrPtr pCh
= tty
->driver_data
;
1819 unsigned long flags
;
1821 #ifdef IP2DEBUG_TRACE
1822 ip2trace (PORTN
, ITRC_FLUSH
, ITRC_ENTER
, 0 );
1824 #ifdef IP2DEBUG_WRITE
1825 printk (KERN_DEBUG
"IP2: flush buffer\n" );
1827 WRITE_LOCK_IRQSAVE(&pCh
->Pbuf_spinlock
,flags
);
1828 pCh
->Pbuf_stuff
= 0;
1829 WRITE_UNLOCK_IRQRESTORE(&pCh
->Pbuf_spinlock
,flags
);
1830 i2FlushOutput( pCh
);
1832 #ifdef IP2DEBUG_TRACE
1833 ip2trace (PORTN
, ITRC_FLUSH
, ITRC_RETURN
, 0 );
1837 /******************************************************************************/
1838 /* Function: ip2_wait_until_sent() */
1839 /* Parameters: Pointer to tty structure */
1840 /* Timeout for wait. */
1841 /* Returns: Nothing */
1844 /* This function is used in place of the normal tty_wait_until_sent, which */
1845 /* only waits for the driver buffers to be empty (or rather, those buffers */
1846 /* reported by chars_in_buffer) which doesn't work for IP2 due to the */
1847 /* indeterminate number of bytes buffered on the board. */
1848 /******************************************************************************/
1850 ip2_wait_until_sent ( PTTY tty
, int timeout
)
1853 i2ChanStrPtr pCh
= tty
->driver_data
;
1855 tty_wait_until_sent(tty
, timeout
);
1856 if ( (i
= timeout
- (jiffies
-i
)) > 0)
1857 i2DrainOutput( pCh
, i
);
1860 /******************************************************************************/
1861 /******************************************************************************/
1862 /* Device Input Section */
1863 /******************************************************************************/
1864 /******************************************************************************/
1866 /******************************************************************************/
1867 /* Function: ip2_throttle() */
1868 /* Parameters: Pointer to tty structure */
1869 /* Returns: Nothing */
1874 /******************************************************************************/
1876 ip2_throttle ( PTTY tty
)
1878 i2ChanStrPtr pCh
= tty
->driver_data
;
1880 #ifdef IP2DEBUG_READ
1881 printk (KERN_DEBUG
"IP2: throttle\n" );
1884 * Signal the poll/interrupt handlers not to forward incoming data to
1885 * the line discipline. This will cause the buffers to fill up in the
1886 * library and thus cause the library routines to send the flow control
1892 /******************************************************************************/
1893 /* Function: ip2_unthrottle() */
1894 /* Parameters: Pointer to tty structure */
1895 /* Returns: Nothing */
1900 /******************************************************************************/
1902 ip2_unthrottle ( PTTY tty
)
1904 i2ChanStrPtr pCh
= tty
->driver_data
;
1905 unsigned long flags
;
1907 #ifdef IP2DEBUG_READ
1908 printk (KERN_DEBUG
"IP2: unthrottle\n" );
1911 /* Pass incoming data up to the line discipline again. */
1913 i2QueueCommands(PTYPE_BYPASS
, pCh
, 0, 1, CMD_RESUME
);
1914 serviceOutgoingFifo( pCh
->pMyBord
);
1915 READ_LOCK_IRQSAVE(&pCh
->Ibuf_spinlock
,flags
)
1916 if ( pCh
->Ibuf_stuff
!= pCh
->Ibuf_strip
) {
1917 READ_UNLOCK_IRQRESTORE(&pCh
->Ibuf_spinlock
,flags
)
1918 #ifdef IP2DEBUG_READ
1919 printk (KERN_DEBUG
"i2Input called from unthrottle\n" );
1923 READ_UNLOCK_IRQRESTORE(&pCh
->Ibuf_spinlock
,flags
)
1927 ip2_start ( PTTY tty
)
1929 i2ChanStrPtr pCh
= DevTable
[MINOR(tty
->device
)];
1931 i2QueueCommands(PTYPE_BYPASS
, pCh
, 0, 1, CMD_RESUME
);
1932 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_UNSUSPEND
);
1933 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_RESUME
);
1934 #ifdef IP2DEBUG_WRITE
1935 printk (KERN_DEBUG
"IP2: start tx\n" );
1940 ip2_stop ( PTTY tty
)
1942 i2ChanStrPtr pCh
= DevTable
[MINOR(tty
->device
)];
1944 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_SUSPEND
);
1945 #ifdef IP2DEBUG_WRITE
1946 printk (KERN_DEBUG
"IP2: stop tx\n" );
1950 /******************************************************************************/
1951 /* Device Ioctl Section */
1952 /******************************************************************************/
1954 /******************************************************************************/
1955 /* Function: ip2_ioctl() */
1956 /* Parameters: Pointer to tty structure */
1957 /* Pointer to file structure */
1960 /* Returns: Success or failure */
1965 /******************************************************************************/
1967 ip2_ioctl ( PTTY tty
, struct file
*pFile
, UINT cmd
, ULONG arg
)
1969 i2ChanStrPtr pCh
= DevTable
[MINOR(tty
->device
)];
1970 struct async_icount cprev
, cnow
; /* kernel counter temps */
1971 struct serial_icounter_struct
*p_cuser
; /* user space */
1974 if ( pCh
== NULL
) {
1978 #ifdef IP2DEBUG_TRACE
1979 ip2trace (PORTN
, ITRC_IOCTL
, ITRC_ENTER
, 2, cmd
, arg
);
1982 #ifdef IP2DEBUG_IOCTL
1983 printk(KERN_DEBUG
"IP2: ioctl cmd (%x), arg (%lx)\n", cmd
, arg
);
1988 #ifdef IP2DEBUG_TRACE
1989 ip2trace (PORTN
, ITRC_IOCTL
, 2, 1, rc
);
1991 rc
= get_serial_info(pCh
, (struct serial_struct
*) arg
);
1997 #ifdef IP2DEBUG_TRACE
1998 ip2trace (PORTN
, ITRC_IOCTL
, 3, 1, rc
);
2000 rc
= set_serial_info(pCh
, (struct serial_struct
*) arg
);
2006 rc
= tty_check_change(tty
);
2011 //return -ENOIOCTLCMD;
2014 //return -ENOIOCTLCMD;
2017 if (STOP_CHAR(tty
) != __DISABLED_CHAR
) {
2018 i2QueueCommands( PTYPE_BYPASS
, pCh
, 100, 1,
2019 CMD_XMIT_NOW(STOP_CHAR(tty
)));
2023 if (START_CHAR(tty
) != __DISABLED_CHAR
) {
2024 i2QueueCommands( PTYPE_BYPASS
, pCh
, 100, 1,
2025 CMD_XMIT_NOW(START_CHAR(tty
)));
2033 case TCSBRK
: /* SVID version: non-zero arg --> no break */
2034 rc
= tty_check_change(tty
);
2035 #ifdef IP2DEBUG_TRACE
2036 ip2trace (PORTN
, ITRC_IOCTL
, 4, 1, rc
);
2039 ip2_wait_until_sent(tty
,0);
2041 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_SEND_BRK(250));
2042 serviceOutgoingFifo( pCh
->pMyBord
);
2047 case TCSBRKP
: /* support for POSIX tcsendbreak() */
2048 rc
= tty_check_change(tty
);
2049 #ifdef IP2DEBUG_TRACE
2050 ip2trace (PORTN
, ITRC_IOCTL
, 5, 1, rc
);
2053 ip2_wait_until_sent(tty
,0);
2054 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1,
2055 CMD_SEND_BRK(arg
? arg
*100 : 250));
2056 serviceOutgoingFifo ( pCh
->pMyBord
);
2061 #ifdef IP2DEBUG_TRACE
2062 ip2trace (PORTN
, ITRC_IOCTL
, 6, 1, rc
);
2064 rc
=put_user(C_CLOCAL(tty
) ? 1 : 0, (unsigned long *) arg
);
2070 #ifdef IP2DEBUG_TRACE
2071 ip2trace (PORTN
, ITRC_IOCTL
, 7, 1, rc
);
2073 rc
=get_user(arg
,(unsigned long *) arg
);
2076 tty
->termios
->c_cflag
= ((tty
->termios
->c_cflag
& ~CLOCAL
)
2077 | (arg
? CLOCAL
: 0));
2082 #ifdef IP2DEBUG_TRACE
2083 ip2trace (PORTN
, ITRC_IOCTL
, 8, 1, rc
);
2085 rc
= get_modem_info(pCh
, (unsigned int *) arg
);
2093 #ifdef IP2DEBUG_TRACE
2094 ip2trace (PORTN
, ITRC_IOCTL
, 9, 0 );
2096 rc
= set_modem_info(pCh
, cmd
, (unsigned int *) arg
);
2100 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2101 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2102 * for masking). Caller should use TIOCGICOUNT to see which one it was
2105 cprev
= pCh
->icount
; /* note the counters on entry */
2107 #ifdef IP2DEBUG_TRACE
2108 ip2trace (PORTN
, ITRC_IOCTL
, 10, 0 );
2110 interruptible_sleep_on(&pCh
->delta_msr_wait
);
2111 /* see if a signal did it */
2112 if (signal_pending(current
)) {
2116 cnow
= pCh
->icount
; /* atomic copy */
2117 if (cnow
.rng
== cprev
.rng
&& cnow
.dsr
== cprev
.dsr
&&
2118 cnow
.dcd
== cprev
.dcd
&& cnow
.cts
== cprev
.cts
) {
2119 rc
= -EIO
; /* no change => rc */
2122 if ( ((arg
& TIOCM_RNG
) && (cnow
.rng
!= cprev
.rng
)) ||
2123 ((arg
& TIOCM_DSR
) && (cnow
.dsr
!= cprev
.dsr
)) ||
2124 ((arg
& TIOCM_CD
) && (cnow
.dcd
!= cprev
.dcd
)) ||
2125 ((arg
& TIOCM_CTS
) && (cnow
.cts
!= cprev
.cts
)) ) {
2135 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2136 * Return: write counters to the user passed counter struct
2137 * NB: both 1->0 and 0->1 transitions are counted except for RI where
2138 * only 0->1 is counted. The controller is quite capable of counting
2139 * both, but this done to preserve compatibility with the standard
2143 #ifdef IP2DEBUG_TRACE
2144 ip2trace (PORTN
, ITRC_IOCTL
, 11, 1, rc
);
2147 p_cuser
= (struct serial_icounter_struct
*) arg
;
2148 put_user(cnow
.cts
, &p_cuser
->cts
);
2149 put_user(cnow
.dsr
, &p_cuser
->dsr
);
2150 put_user(cnow
.rng
, &p_cuser
->rng
);
2151 put_user(cnow
.dcd
, &p_cuser
->dcd
);
2155 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2156 * will be passed to the line discipline for it to handle.
2162 case TIOCSERGSTRUCT
:
2163 case TIOCSERGETMULTI
:
2164 case TIOCSERSETMULTI
:
2167 #ifdef IP2DEBUG_TRACE
2168 ip2trace (PORTN
, ITRC_IOCTL
, 12, 0 );
2173 #ifdef IP2DEBUG_TRACE
2174 ip2trace (PORTN
, ITRC_IOCTL
, ITRC_RETURN
, 0 );
2178 /******************************************************************************/
2179 /* Function: get_modem_info() */
2180 /* Parameters: Pointer to channel structure */
2181 /* Pointer to destination for data */
2182 /* Returns: Nothing */
2185 /* This returns the current settings of the dataset signal inputs to the user */
2187 /******************************************************************************/
2189 get_modem_info(i2ChanStrPtr pCh
, unsigned int *value
)
2191 unsigned short status
;
2192 unsigned int result
;
2195 status
= pCh
->dataSetIn
; // snapshot settings
2196 result
= ((pCh
->dataSetOut
& I2_RTS
) ? TIOCM_RTS
: 0)
2197 | ((pCh
->dataSetOut
& I2_DTR
) ? TIOCM_DTR
: 0)
2198 | ((status
& I2_DCD
) ? TIOCM_CAR
: 0)
2199 | ((status
& I2_RI
) ? TIOCM_RNG
: 0)
2200 | ((status
& I2_DSR
) ? TIOCM_DSR
: 0)
2201 | ((status
& I2_CTS
) ? TIOCM_CTS
: 0);
2202 rc
=put_user(result
,value
);
2206 /******************************************************************************/
2207 /* Function: set_modem_info() */
2208 /* Parameters: Pointer to channel structure */
2209 /* Specific ioctl command */
2210 /* Pointer to source for new settings */
2211 /* Returns: Nothing */
2214 /* This returns the current settings of the dataset signal inputs to the user */
2216 /******************************************************************************/
2218 set_modem_info(i2ChanStrPtr pCh
, unsigned cmd
, unsigned int *value
)
2223 rc
=get_user(arg
,value
);
2228 if (arg
& TIOCM_RTS
) {
2229 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_RTSUP
);
2230 pCh
->dataSetOut
|= I2_RTS
;
2232 if (arg
& TIOCM_DTR
) {
2233 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DTRUP
);
2234 pCh
->dataSetOut
|= I2_DTR
;
2238 if (arg
& TIOCM_RTS
) {
2239 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_RTSDN
);
2240 pCh
->dataSetOut
&= ~I2_RTS
;
2242 if (arg
& TIOCM_DTR
) {
2243 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DTRDN
);
2244 pCh
->dataSetOut
&= ~I2_DTR
;
2248 if ( (arg
& TIOCM_RTS
) && !(pCh
->dataSetOut
& I2_RTS
) ) {
2249 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_RTSUP
);
2250 pCh
->dataSetOut
|= I2_RTS
;
2251 } else if ( !(arg
& TIOCM_RTS
) && (pCh
->dataSetOut
& I2_RTS
) ) {
2252 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_RTSDN
);
2253 pCh
->dataSetOut
&= ~I2_RTS
;
2255 if ( (arg
& TIOCM_DTR
) && !(pCh
->dataSetOut
& I2_DTR
) ) {
2256 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DTRUP
);
2257 pCh
->dataSetOut
|= I2_DTR
;
2258 } else if ( !(arg
& TIOCM_DTR
) && (pCh
->dataSetOut
& I2_DTR
) ) {
2259 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DTRDN
);
2260 pCh
->dataSetOut
&= ~I2_DTR
;
2266 serviceOutgoingFifo( pCh
->pMyBord
);
2270 /******************************************************************************/
2271 /* Function: GetSerialInfo() */
2272 /* Parameters: Pointer to channel structure */
2273 /* Pointer to old termios structure */
2274 /* Returns: Nothing */
2277 /* This is to support the setserial command, and requires processing of the */
2278 /* standard Linux serial structure. */
2279 /******************************************************************************/
2281 get_serial_info ( i2ChanStrPtr pCh
, struct serial_struct
*retinfo
)
2283 struct serial_struct tmp
;
2290 memset ( &tmp
, 0, sizeof(tmp
) );
2291 tmp
.type
= pCh
->pMyBord
->channelBtypes
.bid_value
[(pCh
->port_index
& (IP2_PORTS_PER_BOARD
-1))/16];
2292 if (BID_HAS_654(tmp
.type
)) {
2293 tmp
.type
= PORT_16650
;
2295 tmp
.type
= PORT_CIRRUS
;
2297 tmp
.line
= pCh
->port_index
;
2298 tmp
.port
= pCh
->pMyBord
->i2eBase
;
2299 tmp
.irq
= ip2config
.irq
[pCh
->port_index
/64];
2300 tmp
.flags
= pCh
->flags
;
2301 tmp
.baud_base
= pCh
->BaudBase
;
2302 tmp
.close_delay
= pCh
->ClosingDelay
;
2303 tmp
.closing_wait
= pCh
->ClosingWaitTime
;
2304 tmp
.custom_divisor
= pCh
->BaudDivisor
;
2305 if(copy_to_user(retinfo
,&tmp
,sizeof(*retinfo
)))
2310 /******************************************************************************/
2311 /* Function: SetSerialInfo() */
2312 /* Parameters: Pointer to channel structure */
2313 /* Pointer to old termios structure */
2314 /* Returns: Nothing */
2317 /* This function provides support for setserial, which uses the TIOCSSERIAL */
2318 /* ioctl. Not all setserial parameters are relevant. If the user attempts to */
2319 /* change the IRQ, address or type of the port the ioctl fails. */
2320 /******************************************************************************/
2322 set_serial_info( i2ChanStrPtr pCh
, struct serial_struct
*new_info
)
2324 struct serial_struct ns
;
2325 int old_flags
, old_baud_divisor
;
2331 rc
=copy_from_user(&ns
, new_info
, sizeof (ns
) );
2336 * We don't allow setserial to change IRQ, board address, type or baud
2337 * base. Also line nunber as such is meaningless but we use it for our
2338 * array index so it is fixed also.
2340 if ( ns
.irq
!= ip2config
.irq
2341 || (int) ns
.port
!= ((int) pCh
->pMyBord
->i2eBase
)
2342 || ns
.baud_base
!= pCh
->BaudBase
2343 || ns
.line
!= pCh
->port_index
) {
2347 old_flags
= pCh
->flags
;
2348 old_baud_divisor
= pCh
->BaudDivisor
;
2351 if ( ( ns
.close_delay
!= pCh
->ClosingDelay
) ||
2352 ( (ns
.flags
& ~ASYNC_USR_MASK
) !=
2353 (pCh
->flags
& ~ASYNC_USR_MASK
) ) ) {
2357 pCh
->flags
= (pCh
->flags
& ~ASYNC_USR_MASK
) |
2358 (ns
.flags
& ASYNC_USR_MASK
);
2359 pCh
->BaudDivisor
= ns
.custom_divisor
;
2361 pCh
->flags
= (pCh
->flags
& ~ASYNC_FLAGS
) |
2362 (ns
.flags
& ASYNC_FLAGS
);
2363 pCh
->BaudDivisor
= ns
.custom_divisor
;
2364 pCh
->ClosingDelay
= ns
.close_delay
* HZ
/100;
2365 pCh
->ClosingWaitTime
= ns
.closing_wait
* HZ
/100;
2368 if ( ( (old_flags
& ASYNC_SPD_MASK
) != (pCh
->flags
& ASYNC_SPD_MASK
) )
2369 || (old_baud_divisor
!= pCh
->BaudDivisor
) ) {
2370 // Invalidate speed and reset parameters
2371 set_params( pCh
, NULL
);
2377 /******************************************************************************/
2378 /* Function: ip2_set_termios() */
2379 /* Parameters: Pointer to tty structure */
2380 /* Pointer to old termios structure */
2381 /* Returns: Nothing */
2386 /******************************************************************************/
2388 ip2_set_termios( PTTY tty
, struct termios
*old_termios
)
2390 i2ChanStrPtr pCh
= (i2ChanStrPtr
)tty
->driver_data
;
2392 #ifdef IP2DEBUG_IOCTL
2393 printk (KERN_DEBUG
"IP2: set termios %p\n", old_termios
);
2396 set_params( pCh
, old_termios
);
2399 /******************************************************************************/
2400 /* Function: ip2_set_line_discipline() */
2401 /* Parameters: Pointer to tty structure */
2402 /* Returns: Nothing */
2404 /* Description: Does nothing */
2407 /******************************************************************************/
2409 ip2_set_line_discipline ( PTTY tty
)
2411 #ifdef IP2DEBUG_IOCTL
2412 printk (KERN_DEBUG
"IP2: set line discipline\n" );
2414 #ifdef IP2DEBUG_TRACE
2415 ip2trace (((i2ChanStrPtr
)tty
->driver_data
)->port_index
, ITRC_IOCTL
, 16, 0 );
2419 /******************************************************************************/
2420 /* Function: SetLine Characteristics() */
2421 /* Parameters: Pointer to channel structure */
2422 /* Returns: Nothing */
2425 /* This routine is called to update the channel structure with the new line */
2426 /* characteristics, and send the appropriate commands to the board when they */
2428 /******************************************************************************/
2430 set_params( i2ChanStrPtr pCh
, struct termios
*o_tios
)
2432 tcflag_t cflag
, iflag
, lflag
;
2433 char stop_char
, start_char
;
2434 struct termios dummy
;
2436 lflag
= pCh
->pTTY
->termios
->c_lflag
;
2437 cflag
= pCh
->pTTY
->termios
->c_cflag
;
2438 iflag
= pCh
->pTTY
->termios
->c_iflag
;
2440 if (o_tios
== NULL
) {
2441 dummy
.c_lflag
= ~lflag
;
2442 dummy
.c_cflag
= ~cflag
;
2443 dummy
.c_iflag
= ~iflag
;
2448 switch ( cflag
& CBAUD
) {
2450 i2QueueCommands( PTYPE_BYPASS
, pCh
, 100, 2, CMD_RTSDN
, CMD_DTRDN
);
2451 pCh
->dataSetOut
&= ~(I2_DTR
| I2_RTS
);
2452 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_PAUSE(25));
2453 pCh
->pTTY
->termios
->c_cflag
|= (CBAUD
& o_tios
->c_cflag
);
2458 * This is the speed that is overloaded with all the other high
2459 * speeds, depending upon the flag settings.
2461 if ( ( pCh
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_HI
) {
2462 pCh
->speed
= CBR_57600
;
2463 } else if ( (pCh
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_VHI
) {
2464 pCh
->speed
= CBR_115200
;
2465 } else if ( (pCh
->flags
& ASYNC_SPD_MASK
) == ASYNC_SPD_CUST
) {
2466 pCh
->speed
= CBR_C1
;
2468 pCh
->speed
= CBR_38400
;
2471 case B50
: pCh
->speed
= CBR_50
; break;
2472 case B75
: pCh
->speed
= CBR_75
; break;
2473 case B110
: pCh
->speed
= CBR_110
; break;
2474 case B134
: pCh
->speed
= CBR_134
; break;
2475 case B150
: pCh
->speed
= CBR_150
; break;
2476 case B200
: pCh
->speed
= CBR_200
; break;
2477 case B300
: pCh
->speed
= CBR_300
; break;
2478 case B600
: pCh
->speed
= CBR_600
; break;
2479 case B1200
: pCh
->speed
= CBR_1200
; break;
2480 case B1800
: pCh
->speed
= CBR_1800
; break;
2481 case B2400
: pCh
->speed
= CBR_2400
; break;
2482 case B4800
: pCh
->speed
= CBR_4800
; break;
2483 case B9600
: pCh
->speed
= CBR_9600
; break;
2484 case B19200
: pCh
->speed
= CBR_19200
; break;
2485 case B57600
: pCh
->speed
= CBR_57600
; break;
2486 case B115200
: pCh
->speed
= CBR_115200
; break;
2487 case B153600
: pCh
->speed
= CBR_153600
; break;
2488 case B230400
: pCh
->speed
= CBR_230400
; break;
2489 case B307200
: pCh
->speed
= CBR_307200
; break;
2490 case B460800
: pCh
->speed
= CBR_460800
; break;
2491 case B921600
: pCh
->speed
= CBR_921600
; break;
2492 default: pCh
->speed
= CBR_9600
; break;
2494 if ( pCh
->speed
== CBR_C1
) {
2495 // Process the custom speed parameters.
2496 int bps
= pCh
->BaudBase
/ pCh
->BaudDivisor
;
2497 if ( bps
== 921600 ) {
2498 pCh
->speed
= CBR_921600
;
2501 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_BAUD_DEF1(bps
) );
2504 i2QueueCommands( PTYPE_INLINE
, pCh
, 100, 1, CMD_SETBAUD(pCh
->speed
));
2506 i2QueueCommands ( PTYPE_INLINE
, pCh
, 100, 2, CMD_DTRUP
, CMD_RTSUP
);
2507 pCh
->dataSetOut
|= (I2_DTR
| I2_RTS
);
2509 if ( (CSTOPB
& cflag
) ^ (CSTOPB
& o_tios
->c_cflag
))
2511 i2QueueCommands ( PTYPE_INLINE
, pCh
, 100, 1,
2512 CMD_SETSTOP( ( cflag
& CSTOPB
) ? CST_2
: CST_1
));
2514 if (((PARENB
|PARODD
) & cflag
) ^ ((PARENB
|PARODD
) & o_tios
->c_cflag
))
2516 i2QueueCommands ( PTYPE_INLINE
, pCh
, 100, 1,
2518 (cflag
& PARENB
? (cflag
& PARODD
? CSP_OD
: CSP_EV
) : CSP_NP
)
2522 /* byte size and parity */
2523 if ( (CSIZE
& cflag
)^(CSIZE
& o_tios
->c_cflag
))
2526 switch ( cflag
& CSIZE
) {
2527 case CS5
: datasize
= CSZ_5
; break;
2528 case CS6
: datasize
= CSZ_6
; break;
2529 case CS7
: datasize
= CSZ_7
; break;
2530 case CS8
: datasize
= CSZ_8
; break;
2531 default: datasize
= CSZ_5
; break; /* as per serial.c */
2533 i2QueueCommands ( PTYPE_INLINE
, pCh
, 100, 1, CMD_SETBITS(datasize
) );
2535 /* Process CTS flow control flag setting */
2536 if ( (cflag
& CRTSCTS
) ) {
2537 i2QueueCommands(PTYPE_INLINE
, pCh
, 100,
2538 2, CMD_CTSFL_ENAB
, CMD_RTSFL_ENAB
);
2540 i2QueueCommands(PTYPE_INLINE
, pCh
, 100,
2541 2, CMD_CTSFL_DSAB
, CMD_RTSFL_DSAB
);
2544 // Process XON/XOFF flow control flags settings
2546 stop_char
= STOP_CHAR(pCh
->pTTY
);
2547 start_char
= START_CHAR(pCh
->pTTY
);
2549 //////////// can't be \000
2550 if (stop_char
== __DISABLED_CHAR
)
2552 stop_char
= ~__DISABLED_CHAR
;
2554 if (start_char
== __DISABLED_CHAR
)
2556 start_char
= ~__DISABLED_CHAR
;
2558 /////////////////////////////////
2560 if ( o_tios
->c_cc
[VSTART
] != start_char
)
2562 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_DEF_IXON(start_char
));
2563 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DEF_OXON(start_char
));
2565 if ( o_tios
->c_cc
[VSTOP
] != stop_char
)
2567 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1, CMD_DEF_IXOFF(stop_char
));
2568 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DEF_OXOFF(stop_char
));
2570 if (stop_char
== __DISABLED_CHAR
)
2572 stop_char
= ~__DISABLED_CHAR
; //TEST123
2575 if ((iflag
& (IXOFF
))^(o_tios
->c_iflag
& (IXOFF
)))
2577 if ( iflag
& IXOFF
) { // Enable XOFF output flow control
2578 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_OXON_OPT(COX_XON
));
2579 } else { // Disable XOFF output flow control
2581 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_OXON_OPT(COX_NONE
));
2584 if (start_char
== __DISABLED_CHAR
)
2588 if ((iflag
& (IXON
|IXANY
)) ^ (o_tios
->c_iflag
& (IXON
|IXANY
)))
2590 if ( iflag
& IXON
) {
2591 if ( iflag
& IXANY
) { // Enable XON/XANY output flow control
2592 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_IXON_OPT(CIX_XANY
));
2593 } else { // Enable XON output flow control
2594 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_IXON_OPT(CIX_XON
));
2596 } else { // Disable XON output flow control
2598 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_IXON_OPT(CIX_NONE
));
2601 if ( (iflag
& ISTRIP
) ^ ( o_tios
->c_iflag
& (ISTRIP
)) )
2603 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1,
2604 CMD_ISTRIP_OPT((iflag
& ISTRIP
? 1 : 0)));
2606 if ( (iflag
& INPCK
) ^ ( o_tios
->c_iflag
& (INPCK
)) )
2608 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1,
2609 CMD_PARCHK((iflag
& INPCK
) ? CPK_ENAB
: CPK_DSAB
));
2612 if ( (iflag
& (IGNBRK
|PARMRK
|BRKINT
|IGNPAR
))
2613 ^ ( o_tios
->c_iflag
& (IGNBRK
|PARMRK
|BRKINT
|IGNPAR
)) )
2618 if ( iflag
& IGNBRK
) { /* Ignore breaks altogether */
2619 /* Ignore breaks altogether */
2620 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_BRK_NREP
);
2622 if ( iflag
& BRKINT
) {
2623 if ( iflag
& PARMRK
) {
2624 brkrpt
= 0x0a; // exception an inline triple
2626 brkrpt
= 0x1a; // exception and NULL
2628 brkrpt
|= 0x04; // flush input
2630 if ( iflag
& PARMRK
) {
2631 brkrpt
= 0x0b; //POSIX triple \0377 \0 \0
2633 brkrpt
= 0x01; // Null only
2636 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_BRK_REP(brkrpt
));
2639 if (iflag
& IGNPAR
) {
2641 /* would be 2 for not cirrus bug */
2642 /* would be 0x20 cept for cirrus bug */
2644 if ( iflag
& PARMRK
) {
2646 * Replace error characters with 3-byte sequence (\0377,\0,char)
2649 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_ISTRIP_OPT((char)0));
2654 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_SET_ERROR(parrpt
));
2656 if (cflag
& CLOCAL
) {
2657 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DCD_NREP
);
2658 pCh
->flags
&= ~ASYNC_CHECK_CD
;
2660 i2QueueCommands(PTYPE_INLINE
, pCh
, 100, 1, CMD_DCD_REP
);
2661 pCh
->flags
|= ASYNC_CHECK_CD
;
2665 do_flags_thing
: // This is a test, we don't do the flags thing
2667 if ( (cflag
& CRTSCTS
) ) {
2668 cflag
|= 014000000000;
2670 i2QueueCommands(PTYPE_BYPASS
, pCh
, 100, 1,
2671 CMD_UNIX_FLAGS(iflag
,cflag
,lflag
));
2675 i2DrainOutput( pCh
, 100 );
2678 /******************************************************************************/
2679 /* IPL Device Section */
2680 /******************************************************************************/
2682 /******************************************************************************/
2683 /* Function: ip2_ipl_read() */
2684 /* Parameters: Pointer to device inode */
2685 /* Pointer to file structure */
2686 /* Pointer to data */
2687 /* Number of bytes to read */
2688 /* Returns: Success or failure */
2690 /* Description: Ugly */
2693 /******************************************************************************/
2697 ip2_ipl_read(struct file
*pFile
, char *pData
, size_t count
, loff_t
*off
)
2699 unsigned int minor
= MINOR( pFile
->f_dentry
->d_inode
->i_rdev
);
2703 printk (KERN_DEBUG
"IP2IPL: read %p, %d bytes\n", pData
, count
);
2707 case 0: // IPL device
2710 case 1: // Status dump
2713 case 2: // Ping device
2716 case 3: // Trace device
2717 rc
= DumpTraceBuffer ( pData
, count
);
2719 case 4: // Trace device
2720 rc
= DumpFifoBuffer ( pData
, count
);
2730 DumpFifoBuffer ( char *pData
, int count
)
2734 if(copy_to_user(pData
, DBGBuf
, count
))
2737 printk(KERN_DEBUG
"Last index %d\n", I
);
2740 #endif /* DEBUG_FIFO */
2745 DumpTraceBuffer ( char *pData
, int count
)
2747 #ifdef IP2DEBUG_TRACE
2751 int *pIndex
= (int*)pData
;
2753 if ( count
< (sizeof(int) * 6) ) {
2756 put_user(tracewrap
, pIndex
);
2757 put_user(TRACEMAX
, ++pIndex
);
2758 put_user(tracestrip
, ++pIndex
);
2759 put_user(tracestuff
, ++pIndex
);
2760 pData
+= sizeof(int) * 6;
2761 count
-= sizeof(int) * 6;
2763 dumpcount
= tracestuff
- tracestrip
;
2764 if ( dumpcount
< 0 ) {
2765 dumpcount
+= TRACEMAX
;
2767 if ( dumpcount
> count
) {
2770 chunk
= TRACEMAX
- tracestrip
;
2771 if ( dumpcount
> chunk
) {
2772 rc
=copy_to_user(pData
, &tracebuf
[tracestrip
],
2773 chunk
* sizeof(tracebuf
[0]) )?-EFAULT
:0;
2774 pData
+= chunk
* sizeof(tracebuf
[0]);
2776 chunk
= dumpcount
- chunk
;
2780 rc
=copy_to_user(pData
, &tracebuf
[tracestrip
],
2781 chunk
* sizeof(tracebuf
[0]) )?-EFAULT
:0
2782 tracestrip
+= chunk
;
2785 put_user(tracestrip
, ++pIndex
);
2786 put_user(tracestuff
, ++pIndex
);
2794 /******************************************************************************/
2795 /* Function: ip2_ipl_write() */
2797 /* Pointer to file structure */
2798 /* Pointer to data */
2799 /* Number of bytes to write */
2800 /* Returns: Success or failure */
2805 /******************************************************************************/
2807 ip2_ipl_write(struct file
*pFile
, const char *pData
, size_t count
, loff_t
*off
)
2810 printk (KERN_DEBUG
"IP2IPL: write %p, %d bytes\n", pData
, count
);
2815 /******************************************************************************/
2816 /* Function: ip2_ipl_ioctl() */
2817 /* Parameters: Pointer to device inode */
2818 /* Pointer to file structure */
2821 /* Returns: Success or failure */
2826 /******************************************************************************/
2828 ip2_ipl_ioctl ( struct inode
*pInode
, struct file
*pFile
, UINT cmd
, ULONG arg
)
2830 unsigned int iplminor
= MINOR(pInode
->i_rdev
);
2832 ULONG
*pIndex
= (ULONG
*)arg
;
2833 i2eBordStrPtr pB
= i2BoardPtrTable
[iplminor
/ 4];
2837 printk (KERN_DEBUG
"IP2IPL: ioctl cmd %d, arg %ld\n", cmd
, arg
);
2840 switch ( iplminor
) {
2841 case 0: // IPL device
2844 case 1: // Status dump
2849 case 64: /* Driver - ip2stat */
2850 put_user(ref_count
, pIndex
++ );
2851 put_user(irq_counter
, pIndex
++ );
2852 put_user(bh_counter
, pIndex
++ );
2855 case 65: /* Board - ip2stat */
2857 if(copy_to_user((char*)arg
, (char*)pB
, sizeof(i2eBordStr
) ))
2859 put_user(INB(pB
->i2eStatus
),
2860 (ULONG
*)(arg
+ (ULONG
)(&pB
->i2eStatus
) - (ULONG
)pB
) );
2867 pCh
= DevTable
[cmd
];
2870 if(copy_to_user((char*)arg
, (char*)pCh
, sizeof(i2ChanStr
) ))
2873 rc
= cmd
< 64 ? -ENODEV
: -EINVAL
;
2878 case 2: // Ping device
2881 case 3: // Trace device
2883 put_user(iiSendPendingMail
, pIndex
++ );
2884 put_user(i2InitChannels
, pIndex
++ );
2885 put_user(i2QueueNeeds
, pIndex
++ );
2886 put_user(i2QueueCommands
, pIndex
++ );
2887 put_user(i2GetStatus
, pIndex
++ );
2888 put_user(i2Input
, pIndex
++ );
2889 put_user(i2InputFlush
, pIndex
++ );
2890 put_user(i2Output
, pIndex
++ );
2891 put_user(i2FlushOutput
, pIndex
++ );
2892 put_user(i2DrainWakeup
, pIndex
++ );
2893 put_user(i2DrainOutput
, pIndex
++ );
2894 put_user(i2OutputFree
, pIndex
++ );
2895 put_user(i2StripFifo
, pIndex
++ );
2896 put_user(i2StuffFifoBypass
, pIndex
++ );
2897 put_user(i2StuffFifoFlow
, pIndex
++ );
2898 put_user(i2StuffFifoInline
, pIndex
++ );
2899 put_user(i2ServiceBoard
, pIndex
++ );
2900 put_user(serviceOutgoingFifo
, pIndex
++ );
2901 // put_user(ip2_init, pIndex++ );
2902 put_user(ip2_init_board
, pIndex
++ );
2903 put_user(find_eisa_board
, pIndex
++ );
2904 put_user(set_irq
, pIndex
++ );
2905 put_user(ip2_interrupt
, pIndex
++ );
2906 put_user(ip2_poll
, pIndex
++ );
2907 put_user(service_all_boards
, pIndex
++ );
2908 put_user(do_input
, pIndex
++ );
2909 put_user(do_status
, pIndex
++ );
2910 #ifndef IP2DEBUG_OPEN
2911 put_user(0, pIndex
++ );
2913 put_user(open_sanity_check
, pIndex
++ );
2915 put_user(ip2_open
, pIndex
++ );
2916 put_user(ip2_close
, pIndex
++ );
2917 put_user(ip2_hangup
, pIndex
++ );
2918 put_user(ip2_write
, pIndex
++ );
2919 put_user(ip2_putchar
, pIndex
++ );
2920 put_user(ip2_flush_chars
, pIndex
++ );
2921 put_user(ip2_write_room
, pIndex
++ );
2922 put_user(ip2_chars_in_buf
, pIndex
++ );
2923 put_user(ip2_flush_buffer
, pIndex
++ );
2925 //put_user(ip2_wait_until_sent, pIndex++ );
2926 put_user(0, pIndex
++ );
2928 put_user(ip2_throttle
, pIndex
++ );
2929 put_user(ip2_unthrottle
, pIndex
++ );
2930 put_user(ip2_ioctl
, pIndex
++ );
2931 put_user(get_modem_info
, pIndex
++ );
2932 put_user(set_modem_info
, pIndex
++ );
2933 put_user(get_serial_info
, pIndex
++ );
2934 put_user(set_serial_info
, pIndex
++ );
2935 put_user(ip2_set_termios
, pIndex
++ );
2936 put_user(ip2_set_line_discipline
, pIndex
++ );
2937 put_user(set_params
, pIndex
++ );
2951 /******************************************************************************/
2952 /* Function: ip2_ipl_open() */
2953 /* Parameters: Pointer to device inode */
2954 /* Pointer to file structure */
2955 /* Returns: Success or failure */
2960 /******************************************************************************/
2962 ip2_ipl_open( struct inode
*pInode
, struct file
*pFile
)
2964 unsigned int iplminor
= MINOR(pInode
->i_rdev
);
2969 printk (KERN_DEBUG
"IP2IPL: open\n" );
2972 //MOD_INC_USE_COUNT; // Needs close entry with decrement.
2975 // These are the IPL devices
2982 // These are the status devices
2989 // These are the debug devices
2994 pB
= i2BoardPtrTable
[iplminor
/ 4];
2995 pCh
= (i2ChanStrPtr
) pB
->i2eChannelPtr
;
2998 // This is the trace device
3004 /******************************************************************************/
3005 /* Function: ip2_read_procmem */
3008 /* Returns: Length of output */
3011 /* Supplies some driver operating parameters */
3012 /* Not real useful unless your debugging the fifo */
3014 /******************************************************************************/
3016 #define LIMIT (PAGE_SIZE - 120)
3019 ip2_read_procmem(char *buf
, char **start
, off_t offset
, int len
, int unused
)
3028 #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
3029 #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n"
3030 #define FMTLIN3 " 0x%04x 0x%04x rc flow\n"
3032 len
+= sprintf(buf
+len
,"\n");
3034 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
3035 pB
= i2BoardPtrTable
[i
];
3037 len
+= sprintf(buf
+len
,"board %d:\n",i
);
3038 len
+= sprintf(buf
+len
,"\tFifo rem: %d mty: %x outM %x\n",
3039 pB
->i2eFifoRemains
,pB
->i2eWaitingForEmptyFifo
,pB
->i2eOutMailWaiting
);
3043 len
+= sprintf(buf
+len
,"#: tty flags, port flags, cflags, iflags\n");
3044 for (i
=0; i
< IP2_MAX_PORTS
; i
++) {
3050 if (tty
&& tty
->count
) {
3051 len
+= sprintf(buf
+len
,FMTLINE
,i
,(int)tty
->flags
,pCh
->flags
,
3052 tty
->termios
->c_cflag
,tty
->termios
->c_iflag
);
3054 len
+= sprintf(buf
+len
,FMTLIN2
,
3055 pCh
->outfl
.asof
,pCh
->outfl
.room
,pCh
->channelNeeds
);
3056 len
+= sprintf(buf
+len
,FMTLIN3
,pCh
->infl
.asof
,pCh
->infl
.room
);
3064 * This is the handler for /proc/tty/driver/ip2
3066 * This stretch of code has been largely plagerized from at least three
3067 * different sources including ip2mkdev.c and a couple of other drivers.
3068 * The bugs are all mine. :-) =mhw=
3070 int ip2_read_proc(char *page
, char **start
, off_t off
,
3071 int count
, int *eof
, void *data
)
3081 len
+= sprintf(page
, "ip2info: 1.0 driver: %s\n", pcVersion
);
3082 len
+= sprintf(page
+len
, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
3083 IP2_TTY_MAJOR
, IP2_CALLOUT_MAJOR
, IP2_IPL_MAJOR
,
3084 IP2_MAX_BOARDS
, ABS_MAX_BOXES
, ABS_BIGGEST_BOX
);
3086 for( i
= 0; i
< IP2_MAX_BOARDS
; ++i
) {
3087 /* This need to be reset for a board by board count... */
3089 pB
= i2BoardPtrTable
[i
];
3091 switch( pB
->i2ePom
.e
.porID
& ~POR_ID_RESERVED
)
3094 len
+= sprintf( page
+len
, "Board %d: EX ports=", i
);
3095 for( box
= 0; box
< ABS_MAX_BOXES
; ++box
)
3099 if( pB
->i2eChannelMap
[box
] != 0 ) ++boxes
;
3100 for( j
= 0; j
< ABS_BIGGEST_BOX
; ++j
)
3102 if( pB
->i2eChannelMap
[box
] & 1<< j
) {
3106 len
+= sprintf( page
+len
, "%d,", ports
);
3110 --len
; /* Backup over that last comma */
3112 len
+= sprintf( page
+len
, " boxes=%d width=%d", boxes
, pB
->i2eDataWidth16
? 16 : 8 );
3116 len
+= sprintf(page
+len
, "Board %d: ISA-4 ports=4 boxes=1", i
);
3121 len
+= sprintf(page
+len
, "Board %d: ISA-8-std ports=8 boxes=1", i
);
3126 len
+= sprintf(page
+len
, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i
);
3131 len
+= sprintf(page
+len
, "Board %d: unknown", i
);
3132 /* Don't try and probe for minor numbers */
3137 /* Don't try and probe for minor numbers */
3138 len
+= sprintf(page
+len
, "Board %d: vacant", i
);
3143 len
+= sprintf(page
+len
, " minors=" );
3145 for ( box
= 0; box
< ABS_MAX_BOXES
; ++box
)
3147 for ( j
= 0; j
< ABS_BIGGEST_BOX
; ++j
)
3149 if ( pB
->i2eChannelMap
[box
] & (1 << j
) )
3151 len
+= sprintf (page
+len
,"%d,",
3152 j
+ ABS_BIGGEST_BOX
*
3153 (box
+i
*ABS_MAX_BOXES
));
3158 page
[ len
- 1 ] = '\n'; /* Overwrite that last comma */
3160 len
+= sprintf (page
+len
,"\n" );
3163 if (len
+begin
> off
+count
)
3165 if (len
+begin
< off
) {
3171 if (i
>= IP2_MAX_BOARDS
)
3173 if (off
>= len
+begin
)
3176 *start
= page
+ (begin
-off
);
3177 return ((count
< begin
+len
-off
) ? count
: begin
+len
-off
);
3180 /******************************************************************************/
3181 /* Function: ip2trace() */
3182 /* Parameters: Value to add to trace buffer */
3183 /* Returns: Nothing */
3188 /******************************************************************************/
3190 ip2trace (unsigned short pn
, unsigned char cat
, unsigned char label
, unsigned long codes
, ...)
3192 #ifdef IP2DEBUG_TRACE
3194 unsigned long *pCode
= &codes
;
3195 union ip2breadcrumb bc
;
3199 tracebuf
[tracestuff
++] = jiffies
;
3200 if ( tracestuff
== TRACEMAX
) {
3203 if ( tracestuff
== tracestrip
) {
3204 if ( ++tracestrip
== TRACEMAX
) {
3210 bc
.hdr
.port
= 0xff & pn
;
3212 bc
.hdr
.codes
= (unsigned char)( codes
& 0xff );
3213 bc
.hdr
.label
= label
;
3214 tracebuf
[tracestuff
++] = bc
.value
;
3217 if ( tracestuff
== TRACEMAX
) {
3220 if ( tracestuff
== tracestrip
) {
3221 if ( ++tracestrip
== TRACEMAX
) {
3230 tracebuf
[tracestuff
++] = *++pCode
;