/*
- * $Id: synclinkmp.c,v 4.29 2004/08/27 20:06:41 paulkf Exp $
+ * $Id: synclinkmp.c,v 4.38 2005/07/15 13:29:44 paulkf Exp $
*
* Device driver for Microgate SyncLink Multiport
* high speed multiprotocol serial adapter.
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <asm/serial.h>
#include <linux/delay.h>
#include <linux/ioctl.h>
static int maxframe[MAX_DEVICES] = {0,};
static int dosyncppp[MAX_DEVICES] = {0,};
-MODULE_PARM(break_on_load,"i");
-MODULE_PARM(ttymajor,"i");
-MODULE_PARM(debug_level,"i");
-MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_DEVICES) "i");
-MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i");
+module_param(break_on_load, bool, 0);
+module_param(ttymajor, int, 0);
+module_param(debug_level, int, 0);
+module_param_array(maxframe, int, NULL, 0);
+module_param_array(dosyncppp, int, NULL, 0);
static char *driver_name = "SyncLink MultiPort driver";
-static char *driver_version = "$Revision: 4.29 $";
+static char *driver_version = "$Revision: 4.38 $";
static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
static void synclinkmp_remove_one(struct pci_dev *dev);
static int tx_enable(SLMP_INFO *info, int enable);
static int tx_abort(SLMP_INFO *info);
static int rx_enable(SLMP_INFO *info, int enable);
-static int map_status(int signals);
static int modem_input_wait(SLMP_INFO *info,int arg);
static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
static int tiocmget(struct tty_struct *tty, struct file *file);
static unsigned char tx_negate_fifo_level = 32; // tx request FIFO negation level in bytes
static u32 misc_ctrl_value = 0x007e4040;
-static u32 lcr1_brdr_value = 0x00800029;
+static u32 lcr1_brdr_value = 0x00800028;
static u32 read_ahead_count = 8;
}
info->params.encoding = new_encoding;
- info->params.crc_type = new_crctype;;
+ info->params.crc_type = new_crctype;
/* if network interface up, reprogram hardware */
if (info->netcount)
if ( tty ) {
if (!(status & info->ignore_status_mask1)) {
if (info->read_status_mask1 & BRKD) {
- *tty->flip.flag_buf_ptr = TTY_BREAK;
+ tty_insert_flip_char(tty, 0, TTY_BREAK);
if (info->flags & ASYNC_SAK)
do_SAK(tty);
}
while((status = read_reg(info,CST0)) & BIT0)
{
+ int flag = 0;
+ int over = 0;
DataByte = read_reg(info,TRB);
- if ( tty ) {
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- continue;
-
- *tty->flip.char_buf_ptr = DataByte;
- *tty->flip.flag_buf_ptr = 0;
- }
-
icount->rx++;
if ( status & (PE + FRME + OVRN) ) {
if ( tty ) {
if (status & PE)
- *tty->flip.flag_buf_ptr = TTY_PARITY;
+ flag = TTY_PARITY;
else if (status & FRME)
- *tty->flip.flag_buf_ptr = TTY_FRAME;
+ flag = TTY_FRAME;
if (status & OVRN) {
/* Overrun is special, since it's
* reported immediately, and doesn't
* affect the current character
*/
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- tty->flip.count++;
- tty->flip.flag_buf_ptr++;
- tty->flip.char_buf_ptr++;
- *tty->flip.flag_buf_ptr = TTY_OVERRUN;
- }
+ over = 1;
}
}
} /* end of if (error) */
if ( tty ) {
- tty->flip.flag_buf_ptr++;
- tty->flip.char_buf_ptr++;
- tty->flip.count++;
+ tty_insert_flip_char(tty, DataByte, flag);
+ if (over)
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
}
}
if ( debug_level >= DEBUG_LEVEL_ISR ) {
- printk("%s(%d):%s isr_rxrdy() flip count=%d\n",
- __FILE__,__LINE__,info->device_name,
- tty ? tty->flip.count : 0);
printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n",
__FILE__,__LINE__,info->device_name,
icount->rx,icount->brk,icount->parity,
icount->frame,icount->overrun);
}
- if ( tty && tty->flip.count )
+ if ( tty )
tty_flip_buffer_push(tty);
}
-void isr_txeom(SLMP_INFO * info, unsigned char status)
+static void isr_txeom(SLMP_INFO * info, unsigned char status)
{
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("%s(%d):%s isr_txeom status=%02x\n",
info->pending_bh = 0;
+ memset(&info->icount, 0, sizeof(info->icount));
+
/* program hardware for current parameters */
reset_port(info);
del_timer(&info->tx_timer);
del_timer(&info->status_timer);
- if (info->tx_buf) {
- kfree(info->tx_buf);
- info->tx_buf = NULL;
- }
+ kfree(info->tx_buf);
+ info->tx_buf = NULL;
spin_lock_irqsave(&info->lock,flags);
printk("%s(%d):%s get_params()\n",
__FILE__,__LINE__, info->device_name);
- COPY_TO_USER(err,user_icount, &info->icount, sizeof(struct mgsl_icount));
- if (err) {
- if ( debug_level >= DEBUG_LEVEL_INFO )
- printk( "%s(%d):%s get_stats() user buffer copy failed\n",
- __FILE__,__LINE__,info->device_name);
- return -EFAULT;
+ if (!user_icount) {
+ memset(&info->icount, 0, sizeof(info->icount));
+ } else {
+ COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
+ if (err)
+ return -EFAULT;
}
return 0;
return 0;
}
-static int map_status(int signals)
-{
- /* Map status bits to API event bits */
-
- return ((signals & SerialSignal_DSR) ? MgslEvent_DsrActive : MgslEvent_DsrInactive) +
- ((signals & SerialSignal_CTS) ? MgslEvent_CtsActive : MgslEvent_CtsInactive) +
- ((signals & SerialSignal_DCD) ? MgslEvent_DcdActive : MgslEvent_DcdInactive) +
- ((signals & SerialSignal_RI) ? MgslEvent_RiActive : MgslEvent_RiInactive);
-}
-
/* wait for specified event to occur
*/
static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
/* return immediately if state matches requested events */
get_signals(info);
- s = map_status(info->serial_signals);
+ s = info->serial_signals;
events = mask &
( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
void free_tmp_rx_buf(SLMP_INFO *info)
{
- if (info->tmp_rx_buf)
- kfree(info->tmp_rx_buf);
+ kfree(info->tmp_rx_buf);
info->tmp_rx_buf = NULL;
}
*
* Return Value: pointer to SLMP_INFO if success, otherwise NULL
*/
-SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
+static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
{
SLMP_INFO *info;
/* MD2, Mode Register 2
*
* 07..02 Reserved, must be 0
- * 01..00 CNCT<1..0> Channel connection, 0=normal
+ * 01..00 CNCT<1..0> Channel connection, 00=normal 11=local loopback
*
* 0000 0000
*/
RegValue = 0x00;
+ if (info->params.loopback)
+ RegValue |= (BIT1 + BIT0);
write_reg(info, MD2, RegValue);
/* RXS, Receive clock source
* 07..05 Reserved, must be 0
* 04..00 RRC<4..0> Rx FIFO trigger active 0x00 = 1 byte
*/
- write_reg(info, TRC0, 0x00);
+ write_reg(info, RRC, 0x00);
/* TRC0 Transmit Ready Control 0
*
write_reg(info, IE2, info->ie2_value);
set_rate( info, info->params.data_rate * 16 );
-
- if (info->params.loopback)
- enable_loopback(info,1);
}
/* Program the SCA for HDLC communications.
int register_test(SLMP_INFO *info)
{
static unsigned char testval[] = {0x00, 0xff, 0xaa, 0x55, 0x69, 0x96};
- static unsigned int count = sizeof(testval)/sizeof(unsigned char);
+ static unsigned int count = ARRAY_SIZE(testval);
unsigned int i;
int rc = TRUE;
unsigned long flags;
/* initialize individual SCA device (2 ports)
*/
-int sca_init(SLMP_INFO *info)
+static int sca_init(SLMP_INFO *info)
{
/* set wait controller to single mem partition (low), no wait states */
write_reg(info, PABR0, 0); /* wait controller addr boundary 0 */
{
static unsigned long testval[] = { 0x0, 0x55555555, 0xaaaaaaaa,
0x66666666, 0x99999999, 0xffffffff, 0x12345678 };
- unsigned long count = sizeof(testval)/sizeof(unsigned long);
+ unsigned long count = ARRAY_SIZE(testval);
unsigned long i;
unsigned long limit = SCA_MEM_SIZE/sizeof(unsigned long);
unsigned long * addr = (unsigned long *)info->memory_base;