aboutsummaryrefslogtreecommitdiff
path: root/drivers/char/mxser_new.c
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2006-12-08 02:38:14 -0800
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 08:28:53 -0800
commit55b307da3e00b2281788860eefb42976a86d7752 (patch)
tree8d942f774c9bce13e90a5c97d3845568f4ac7961 /drivers/char/mxser_new.c
parent3306ce3d0554e2e59cc429b7133e17e1513307cb (diff)
[PATCH] Char: mxser_new, rework to allow dynamic structs
This patch is preparation for further patches (pci probing) to allow allocated structures to be private data in pci_dev structure. Union two different structures used in the driver (hw_conf and port/board descriptor) to another 2: port and board not to initialize 2 different things and to have ports contained in board structure. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/mxser_new.c')
-rw-r--r--drivers/char/mxser_new.c1196
1 files changed, 576 insertions, 620 deletions
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index befff0548da..7e53c739783 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -57,7 +57,7 @@
#include "mxser_new.h"
-#define MXSER_VERSION "1.9.1"
+#define MXSER_VERSION "2.0"
#define MXSERMAJOR 174
#define MXSERCUMAJOR 175
@@ -85,8 +85,6 @@
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|\
IXON|IXOFF))
-#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : IRQF_DISABLED)
-
#define C168_ASIC_ID 1
#define C104_ASIC_ID 2
#define C102_ASIC_ID 0xB
@@ -202,8 +200,6 @@ static const struct mxpciuart_info Gpci_uart_info[UART_INFO_NUM] = {
};
-#ifdef CONFIG_PCI
-
static struct pci_device_id mxser_pcibrds[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168),
.driver_data = MXSER_BOARD_C168_PCI },
@@ -243,18 +239,8 @@ static struct pci_device_id mxser_pcibrds[] = {
.driver_data = MXSER_BOARD_CP104EL },
{ }
};
-
MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
-
-#endif
-
-typedef struct _moxa_pci_info {
- unsigned short busNum;
- unsigned short devNum;
- struct pci_dev *pdev; /* add by Victor Yu. 06-23-2003 */
-} moxa_pci_info;
-
static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 };
static int ttymajor = MXSERMAJOR;
static int calloutmajor = MXSERCUMAJOR;
@@ -301,69 +287,77 @@ struct mxser_mon_ext {
int iftype[32];
};
-struct mxser_hwconf {
- int board_type;
- int ports;
- int irq;
- unsigned long vector;
- unsigned long vector_mask;
- int uart_type;
- unsigned long ioaddr[MXSER_PORTS_PER_BOARD];
- int baud_base[MXSER_PORTS_PER_BOARD];
- moxa_pci_info pciInfo;
- int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */
- int MaxCanSetBaudRate[MXSER_PORTS_PER_BOARD]; /* add by Victor Yu. 09-04-2002 */
- unsigned long opmode_ioaddr[MXSER_PORTS_PER_BOARD]; /* add by Victor Yu. 01-05-2004 */
-};
+struct mxser_board;
+
+struct mxser_port {
+ struct mxser_board *board;
+ struct tty_struct *tty;
+
+ unsigned long ioaddr;
+ unsigned long opmode_ioaddr;
+ int max_baud;
-struct mxser_struct {
- int port;
- unsigned long base; /* port base address */
- int irq; /* port using irq no. */
- unsigned long vector; /* port irq vector */
- unsigned long vectormask; /* port vector mask */
int rx_high_water;
int rx_trigger; /* Rx fifo trigger level */
int rx_low_water;
int baud_base; /* max. speed */
- int flags; /* defined in tty.h */
+ long realbaud;
int type; /* UART type */
- struct tty_struct *tty;
- int read_status_mask;
- int ignore_status_mask;
- int xmit_fifo_size;
- int custom_divisor;
+ int flags; /* defined in tty.h */
+ long session; /* Session of opening process */
+ long pgrp; /* pgrp of opening process */
+
int x_char; /* xon/xoff character */
- int close_delay;
- unsigned short closing_wait;
int IER; /* Interrupt Enable Register */
int MCR; /* Modem control register */
+
+ unsigned char stop_rx;
+ unsigned char ldisc_stop_rx;
+
+ int custom_divisor;
+ int close_delay;
+ unsigned short closing_wait;
+ unsigned char err_shadow;
unsigned long event;
+
int count; /* # of fd on device */
int blocked_open; /* # of blocked opens */
- long session; /* Session of opening process */
- long pgrp; /* pgrp of opening process */
+ struct async_icount icount; /* kernel counters for 4 input interrupts */
+ int timeout;
+
+ int read_status_mask;
+ int ignore_status_mask;
+ int xmit_fifo_size;
unsigned char *xmit_buf;
int xmit_head;
int xmit_tail;
int xmit_cnt;
- struct work_struct tqueue;
+
struct termios normal_termios;
struct termios callout_termios;
+
+ struct mxser_mon mon_data;
+
+ spinlock_t slock;
+ struct work_struct tqueue;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
wait_queue_head_t delta_msr_wait;
- struct async_icount icount; /* kernel counters for the 4 input interrupts */
- int timeout;
- int IsMoxaMustChipFlag; /* add by Victor Yu. 08-30-2002 */
- int MaxCanSetBaudRate; /* add by Victor Yu. 09-04-2002 */
- unsigned long opmode_ioaddr; /* add by Victor Yu. 01-05-2004 */
- unsigned char stop_rx;
- unsigned char ldisc_stop_rx;
- long realbaud;
- struct mxser_mon mon_data;
- unsigned char err_shadow;
- spinlock_t slock;
+};
+
+struct mxser_board {
+ struct pci_dev *pdev; /* temporary (until pci probing) */
+
+ int irq;
+ int board_type;
+ unsigned int nports;
+ unsigned long vector;
+ unsigned long vector_mask;
+
+ int chip_flag;
+ int uart_type;
+
+ struct mxser_port ports[MXSER_PORTS_PER_BOARD];
};
struct mxser_mstatus {
@@ -381,8 +375,8 @@ static int mxserBoardCAP[MXSER_BOARDS] = {
/* 0x180, 0x280, 0x200, 0x320 */
};
+static struct mxser_board mxser_boards[MXSER_BOARDS];
static struct tty_driver *mxvar_sdriver;
-static struct mxser_struct mxvar_table[MXSER_PORTS];
static struct tty_struct *mxvar_tty[MXSER_PORTS + 1];
static struct termios *mxvar_termios[MXSER_PORTS + 1];
static struct termios *mxvar_termios_locked[MXSER_PORTS + 1];
@@ -394,21 +388,13 @@ static int mxser_set_baud_method[MXSER_PORTS + 1];
static spinlock_t gm_lock;
/*
- * This is used to figure out the divisor speeds and the timeouts
- */
-
-static struct mxser_hwconf mxsercfg[MXSER_BOARDS];
-
-/*
* static functions:
*/
-static void mxser_getcfg(int board, struct mxser_hwconf *hwconf);
static int mxser_init(void);
/* static void mxser_poll(unsigned long); */
-static int mxser_get_ISA_conf(int, struct mxser_hwconf *);
-static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *);
+static int mxser_get_ISA_conf(int, struct mxser_board *);
static void mxser_do_softint(void *);
static int mxser_open(struct tty_struct *, struct file *);
static void mxser_close(struct tty_struct *, struct file *);
@@ -428,24 +414,28 @@ static void mxser_start(struct tty_struct *);
static void mxser_hangup(struct tty_struct *);
static void mxser_rs_break(struct tty_struct *, int);
static irqreturn_t mxser_interrupt(int, void *, struct pt_regs *);
-static void mxser_receive_chars(struct mxser_struct *, int *);
-static void mxser_transmit_chars(struct mxser_struct *);
-static void mxser_check_modem_status(struct mxser_struct *, int);
-static int mxser_block_til_ready(struct tty_struct *, struct file *, struct mxser_struct *);
-static int mxser_startup(struct mxser_struct *);
-static void mxser_shutdown(struct mxser_struct *);
-static int mxser_change_speed(struct mxser_struct *, struct termios *old_termios);
-static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct __user *);
-static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct __user *);
-static int mxser_get_lsr_info(struct mxser_struct *, unsigned int __user *);
-static void mxser_send_break(struct mxser_struct *, int);
+static void mxser_receive_chars(struct mxser_port *, int *);
+static void mxser_transmit_chars(struct mxser_port *);
+static void mxser_check_modem_status(struct mxser_port *, int);
+static int mxser_block_til_ready(struct tty_struct *, struct file *,
+ struct mxser_port *);
+static int mxser_startup(struct mxser_port *);
+static void mxser_shutdown(struct mxser_port *);
+static int mxser_change_speed(struct mxser_port *, struct termios *);
+static int mxser_get_serial_info(struct mxser_port *,
+ struct serial_struct __user *);
+static int mxser_set_serial_info(struct mxser_port *,
+ struct serial_struct __user *);
+static int mxser_get_lsr_info(struct mxser_port *, unsigned int __user *);
+static void mxser_send_break(struct mxser_port *, int);
static int mxser_tiocmget(struct tty_struct *, struct file *);
-static int mxser_tiocmset(struct tty_struct *, struct file *, unsigned int, unsigned int);
-static int mxser_set_baud(struct mxser_struct *info, long newspd);
-static void mxser_wait_until_sent(struct tty_struct *tty, int timeout);
+static int mxser_tiocmset(struct tty_struct *, struct file *, unsigned int,
+ unsigned int);
+static int mxser_set_baud(struct mxser_port *, long);
+static void mxser_wait_until_sent(struct tty_struct *, int);
-static void mxser_startrx(struct tty_struct *tty);
-static void mxser_stoprx(struct tty_struct *tty);
+static void mxser_startrx(struct tty_struct *);
+static void mxser_stoprx(struct tty_struct *);
static int CheckIsMoxaMust(int io)
@@ -530,18 +520,18 @@ static void __exit mxser_module_exit(void)
for (i = 0; i < MXSER_BOARDS; i++) {
struct pci_dev *pdev;
- if (mxsercfg[i].board_type == -1)
+ if (mxser_boards[i].board_type == -1)
continue;
else {
- pdev = mxsercfg[i].pciInfo.pdev;
- free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]);
+ pdev = mxser_boards[i].pdev;
+ free_irq(mxser_boards[i].irq, &mxser_boards[i]);
if (pdev != NULL) { /* PCI */
release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
pci_dev_put(pdev);
} else {
- release_region(mxsercfg[i].ioaddr[0], 8 * mxsercfg[i].ports);
- release_region(mxsercfg[i].vector, 1);
+ release_region(mxser_boards[i].ports[0].ioaddr, 8 * mxser_boards[i].nports);
+ release_region(mxser_boards[i].vector, 1);
}
}
}
@@ -549,7 +539,7 @@ static void __exit mxser_module_exit(void)
printk(KERN_DEBUG "Done.\n");
}
-static void process_txrx_fifo(struct mxser_struct *info)
+static void process_txrx_fifo(struct mxser_port *info)
{
int i;
@@ -558,60 +548,44 @@ static void process_txrx_fifo(struct mxser_struct *info)
info->rx_high_water = 1;
info->rx_low_water = 1;
info->xmit_fifo_size = 1;
- } else {
- for (i = 0; i < UART_INFO_NUM; i++) {
- if (info->IsMoxaMustChipFlag == Gpci_uart_info[i].type) {
+ } else
+ for (i = 0; i < UART_INFO_NUM; i++)
+ if (info->board->chip_flag == Gpci_uart_info[i].type) {
info->rx_trigger = Gpci_uart_info[i].rx_trigger;
info->rx_low_water = Gpci_uart_info[i].rx_low_water;
info->rx_high_water = Gpci_uart_info[i].rx_high_water;
info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size;
break;
}
- }
- }
}
-static int mxser_initbrd(int board, struct mxser_hwconf *hwconf)
+static int mxser_initbrd(struct mxser_board *brd)
{
- struct mxser_struct *info;
+ struct mxser_port *info;
+ unsigned int i;
int retval;
- int i, n;
- n = board * MXSER_PORTS_PER_BOARD;
- info = &mxvar_table[n];
/*if (verbose) */ {
- printk(KERN_DEBUG " ttyM%d - ttyM%d ",
- n, n + hwconf->ports - 1);
printk(" max. baud rate = %d bps.\n",
- hwconf->MaxCanSetBaudRate[0]);
+ brd->ports[0].max_baud);
}
- for (i = 0; i < hwconf->ports; i++, n++, info++) {
- info->port = n;
- info->base = hwconf->ioaddr[i];
- info->irq = hwconf->irq;
- info->vector = hwconf->vector;
- info->vectormask = hwconf->vector_mask;
- info->opmode_ioaddr = hwconf->opmode_ioaddr[i]; /* add by Victor Yu. 01-05-2004 */
+ for (i = 0; i < brd->nports; i++) {
+ info = &brd->ports[i];
+ info->board = brd;
info->stop_rx = 0;
info->ldisc_stop_rx = 0;
- info->IsMoxaMustChipFlag = hwconf->IsMoxaMustChipFlag;
/* Enhance mode enabled here */
- if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {
- ENABLE_MOXA_MUST_ENCHANCE_MODE(info->base);
- }
+ if (brd->chip_flag != MOXA_OTHER_UART)
+ ENABLE_MOXA_MUST_ENCHANCE_MODE(info->ioaddr);
info->flags = ASYNC_SHARE_IRQ;
- info->type = hwconf->uart_type;
- info->baud_base = hwconf->baud_base[i];
-
- info->MaxCanSetBaudRate = hwconf->MaxCanSetBaudRate[i];
+ info->type = brd->uart_type;
process_txrx_fifo(info);
-
- info->custom_divisor = hwconf->baud_base[i] * 16;
+ info->custom_divisor = info->baud_base * 16;
info->close_delay = 5 * HZ / 10;
info->closing_wait = 30 * HZ;
INIT_WORK(&info->tqueue, mxser_do_softint, info);
@@ -622,118 +596,102 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf)
memset(&info->mon_data, 0, sizeof(struct mxser_mon));
info->err_shadow = 0;
spin_lock_init(&info->slock);
+
+ /* before set INT ISR, disable all int */
+ outb(inb(info->ioaddr + UART_IER) & 0xf0,
+ info->ioaddr + UART_IER);
}
/*
* Allocate the IRQ if necessary
*/
-
- /* before set INT ISR, disable all int */
- for (i = 0; i < hwconf->ports; i++) {
- outb(inb(hwconf->ioaddr[i] + UART_IER) & 0xf0,
- hwconf->ioaddr[i] + UART_IER);
- }
-
- n = board * MXSER_PORTS_PER_BOARD;
- info = &mxvar_table[n];
-
- retval = request_irq(hwconf->irq, mxser_interrupt, IRQ_T(info),
- "mxser", info);
+ retval = request_irq(brd->irq, mxser_interrupt,
+ (brd->ports[0].flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED :
+ IRQF_DISABLED, "mxser", brd);
if (retval) {
- printk(KERN_ERR "Board %d: %s",
- board, mxser_brdname[hwconf->board_type - 1]);
- printk(" Request irq failed, IRQ (%d) may conflict with"
- " another device.\n", info->irq);
+ printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
+ "conflict with another device.\n",
+ mxser_brdname[brd->board_type - 1], brd->irq);
return retval;
}
return 0;
}
-static void mxser_getcfg(int board, struct mxser_hwconf *hwconf)
-{
- mxsercfg[board] = *hwconf;
-}
-
-#ifdef CONFIG_PCI
-static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxser_hwconf *hwconf)
+static int mxser_get_PCI_conf(int board_type, struct mxser_board *brd,
+ struct pci_dev *pdev)
{
- int i, j;
- /* unsigned int val; */
+ unsigned int i, j;
unsigned long ioaddress;
- struct pci_dev *pdev = hwconf->pciInfo.pdev;
/* io address */
- hwconf->board_type = board_type;
- hwconf->ports = mxser_numports[board_type - 1];
+ brd->board_type = board_type;
+ brd->nports = mxser_numports[board_type - 1];
ioaddress = pci_resource_start(pdev, 2);
request_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2),
"mxser(IO)");
- for (i = 0; i < hwconf->ports; i++)
- hwconf->ioaddr[i] = ioaddress + 8 * i;
+ for (i = 0; i < brd->nports; i++)
+ brd->ports[i].ioaddr = ioaddress + 8 * i;
/* vector */
ioaddress = pci_resource_start(pdev, 3);
request_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3),
"mxser(vector)");
- hwconf->vector = ioaddress;
+ brd->vector = ioaddress;
/* irq */
- hwconf->irq = hwconf->pciInfo.pdev->irq;
+ brd->irq = pdev->irq;
- hwconf->IsMoxaMustChipFlag = CheckIsMoxaMust(hwconf->ioaddr[0]);
- hwconf->uart_type = PORT_16550A;
- hwconf->vector_mask = 0;
+ brd->chip_flag = CheckIsMoxaMust(brd->ports[0].ioaddr);
+ brd->uart_type = PORT_16550A;
+ brd->vector_mask = 0;
-
- for (i = 0; i < hwconf->ports; i++) {
+ for (i = 0; i < brd->nports; i++) {
for (j = 0; j < UART_INFO_NUM; j++) {
- if (Gpci_uart_info[j].type == hwconf->IsMoxaMustChipFlag) {
- hwconf->MaxCanSetBaudRate[i] = Gpci_uart_info[j].max_baud;
+ if (Gpci_uart_info[j].type == brd->chip_flag) {
+ brd->ports[i].max_baud =
+ Gpci_uart_info[j].max_baud;
/* exception....CP-102 */
if (board_type == MXSER_BOARD_CP102)
- hwconf->MaxCanSetBaudRate[i] = 921600;
+ brd->ports[i].max_baud = 921600;
break;
}
}
}
- if (hwconf->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID) {
- for (i = 0; i < hwconf->ports; i++) {
+ if (brd->chip_flag == MOXA_MUST_MU860_HWID) {
+ for (i = 0; i < brd->nports; i++) {
if (i < 4)
- hwconf->opmode_ioaddr[i] = ioaddress + 4;
+ brd->ports[i].opmode_ioaddr = ioaddress + 4;
else
- hwconf->opmode_ioaddr[i] = ioaddress + 0x0c;
+ brd->ports[i].opmode_ioaddr = ioaddress + 0x0c;
}
outb(0, ioaddress + 4); /* default set to RS232 mode */
outb(0, ioaddress + 0x0c); /* default set to RS232 mode */
}
- for (i = 0; i < hwconf->ports; i++) {
- hwconf->vector_mask |= (1 << i);
- hwconf->baud_base[i] = 921600;
+ for (i = 0; i < brd->nports; i++) {
+ brd->vector_mask |= (1 << i);
+ brd->ports[i].baud_base = 921600;
}
return 0;
}
-#endif
static int mxser_init(void)
{
- int i, m, retval, b, n;
struct pci_dev *pdev = NULL;
- int index;
- unsigned char busnum, devnum;
- struct mxser_hwconf hwconf;
+ struct mxser_board *brd;
+ unsigned int i, m;
+ int retval, b, n;
mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1);
if (!mxvar_sdriver)
return -ENOMEM;
spin_lock_init(&gm_lock);
- for (i = 0; i < MXSER_BOARDS; i++) {
- mxsercfg[i].board_type = -1;
- }
+ for (i = 0; i < MXSER_BOARDS; i++)
+ mxser_boards[i].board_type = -1;
printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n",
MXSER_VERSION);
@@ -756,13 +714,12 @@ static int mxser_init(void)
mxvar_sdriver->termios_locked = mxvar_termios_locked;
mxvar_diagflag = 0;
- memset(mxvar_table, 0, MXSER_PORTS * sizeof(struct mxser_struct));
+ memset(mxser_boards, 0, sizeof(mxser_boards));
memset(&mxvar_log, 0, sizeof(struct mxser_log));
memset(&mxser_msr, 0, sizeof(unsigned char) * (MXSER_PORTS + 1));
memset(&mon_data_ext, 0, sizeof(struct mxser_mon_ext));
memset(&mxser_set_baud_method, 0, sizeof(int) * (MXSER_PORTS + 1));
- memset(&hwconf, 0, sizeof(struct mxser_hwconf));
m = 0;
/* Start finding ISA boards here */
@@ -772,11 +729,12 @@ static int mxser_init(void)
if (!(cap = mxserBoardCAP[b]))
continue;
- retval = mxser_get_ISA_conf(cap, &hwconf);
+ brd = &mxser_boards[m];
+ retval = mxser_get_ISA_conf(cap, brd);
if (retval != 0)
printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n",
- mxser_brdname[hwconf.board_type - 1], ioaddr[b]);
+ mxser_brdname[brd->board_type - 1], ioaddr[b]);
if (retval <= 0) {
if (retval == MXSER_ERR_IRQ)
@@ -795,17 +753,10 @@ static int mxser_init(void)
continue;
}
- hwconf.pciInfo.busNum = 0;
- hwconf.pciInfo.devNum = 0;
- hwconf.pciInfo.pdev = NULL;
+ brd->pdev = NULL;
- mxser_getcfg(m, &hwconf);
- /*
- * init mxsercfg first,
- * or mxsercfg data is not correct on ISR.
- */
/* mxser_initbrd will hook ISR. */
- if (mxser_initbrd(m, &hwconf) < 0)
+ if (mxser_initbrd(brd) < 0)
continue;
m++;
@@ -818,11 +769,12 @@ static int mxser_init(void)
if (!(cap = ioaddr[b]))
continue;
- retval = mxser_get_ISA_conf(cap, &hwconf);
+ brd = &mxser_boards[m];
+ retval = mxser_get_ISA_conf(cap, &mxser_boards[m]);
if (retval != 0)
printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n",
- mxser_brdname[hwconf.board_type - 1], ioaddr[b]);
+ mxser_brdname[brd->board_type - 1], ioaddr[b]);
if (retval <= 0) {
if (retval == MXSER_ERR_IRQ)
@@ -841,26 +793,16 @@ static int mxser_init(void)
continue;
}
- hwconf.pciInfo.busNum = 0;
- hwconf.pciInfo.devNum = 0;
- hwconf.pciInfo.pdev = NULL;
-
- mxser_getcfg(m, &hwconf);
- /*
- * init mxsercfg first,
- * or mxsercfg data is not correct on ISR.
- */
+ brd->pdev = NULL;
/* mxser_initbrd will hook ISR. */
- if (mxser_initbrd(m, &hwconf) < 0)
+ if (mxser_initbrd(brd) < 0)
continue;
m++;
}
/* start finding PCI board here */
-#ifdef CONFIG_PCI
n = ARRAY_SIZE(mxser_pcibrds) - 1;
- index = 0;
b = 0;
while (b < n) {
pdev = pci_get_device(mxser_pcibrds[b].vendor,
@@ -869,13 +811,9 @@ static int mxser_init(void)
b++;
continue;
}
- hwconf.pciInfo.busNum = busnum = pdev->bus->number;
- hwconf.pciInfo.devNum = devnum = PCI_SLOT(pdev->devfn) << 3;
- hwconf.pciInfo.pdev = pdev;
printk(KERN_INFO "Found MOXA %s board(BusNo=%d,DevNo=%d)\n",
mxser_brdname[(int) (mxser_pcibrds[b].driver_data) - 1],
- busnum, devnum >> 3);
- index++;
+ pdev->bus->number, PCI_SLOT(pdev->devfn));
if (m >= MXSER_BOARDS)
printk(KERN_ERR
"Too many Smartio/Industio family boards find "
@@ -887,9 +825,11 @@ static int mxser_init(void)
"fail !\n");
continue;
}
- retval = mxser_get_PCI_conf(busnum, devnum,
+ brd = &mxser_boards[m];
+ brd->pdev = pdev;
+ retval = mxser_get_PCI_conf(
(int)mxser_pcibrds[b].driver_data,
- &hwconf);
+ brd, pdev);
if (retval < 0) {
if (retval == MXSER_ERR_IRQ)
printk(KERN_ERR
@@ -909,12 +849,8 @@ static int mxser_init(void)
"board not configured\n");
continue;
}
- mxser_getcfg(m, &hwconf);
- /* init mxsercfg first,
- * or mxsercfg data is not correct on ISR.
- */
/* mxser_initbrd will hook ISR. */
- if (mxser_initbrd(m, &hwconf) < 0)
+ if (mxser_initbrd(brd) < 0)
continue;
m++;
/* Keep an extra reference if we succeeded. It will
@@ -922,7 +858,6 @@ static int mxser_init(void)
pci_dev_get(pdev);
}
}
-#endif
retval = tty_register_driver(mxvar_sdriver);
if (retval) {
@@ -931,10 +866,10 @@ static int mxser_init(void)
put_tty_driver(mxvar_sdriver);
for (i = 0; i < MXSER_BOARDS; i++) {
- if (mxsercfg[i].board_type == -1)
+ if (mxser_boards[i].board_type == -1)
continue;
else {
- free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]);
+ free_irq(mxser_boards[i].irq, &mxser_boards[i]);
/* todo: release io, vector */
}
}
@@ -946,7 +881,7 @@ static int mxser_init(void)
static void mxser_do_softint(void *private_)
{
- struct mxser_struct *info = private_;
+ struct mxser_port *info = private_;
struct tty_struct *tty;
tty = info->tty;
@@ -957,7 +892,7 @@ static void mxser_do_softint(void *private_)
tty_hangup(tty);
}
-static unsigned char mxser_get_msr(int baseaddr, int mode, int port, struct mxser_struct *info)
+static unsigned char mxser_get_msr(int baseaddr, int mode, int port)
{
unsigned char status = 0;
@@ -980,7 +915,7 @@ static unsigned char mxser_get_msr(int baseaddr, int mode, int port, struct mxse
*/
static int mxser_open(struct tty_struct *tty, struct file *filp)
{
- struct mxser_struct *info;
+ struct mxser_port *info;
int retval, line;
/* initialize driver_data in case something fails */
@@ -991,8 +926,8 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
return 0;
if (line < 0 || line > MXSER_PORTS)
return -ENODEV;
- info = mxvar_table + line;
- if (!info->base)
+ info = &mxser_boards[line / MXSER_PORTS_PER_BOARD].ports[line % MXSER_PORTS_PER_BOARD];
+ if (!info->ioaddr)
return -ENODEV;
tty->driver_data = info;
@@ -1038,7 +973,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
*/
static void mxser_close(struct tty_struct *tty, struct file *filp)
{
- struct mxser_struct *info = tty->driver_data;
+ struct mxser_port *info = tty->driver_data;
unsigned long timeout;
unsigned long flags;
@@ -1069,7 +1004,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
}
if (--info->count < 0) {
printk(KERN_ERR "mxser_close: bad serial port count for "
- "ttys%d: %d\n", info->port, info->count);
+ "ttys%d: %d\n", tty->index, info->count);
info->count = 0;
}
if (info->count) {
@@ -1098,20 +1033,20 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
* line status register.
*/
info->IER &= ~UART_IER_RLSI;
- if (info->IsMoxaMustChipFlag)
+ if (info->board->chip_flag)
info->IER &= ~MOXA_MUST_RECV_ISR;
/* by William
info->read_status_mask &= ~UART_LSR_DR;
*/
if (info->flags & ASYNC_INITIALIZED) {
- outb(info->IER, info->base + UART_IER);
+ outb(info->IER, info->ioaddr + UART_IER);
/*
* Before we drop DTR, make sure the UART transmitter
* has completely drained; this is especially
* important if there is a transmit FIFO!
*/
timeout = jiffies + HZ;
- while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) {
+ while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
schedule_timeout_interruptible(5);
if (time_after(jiffies, timeout))
break;
@@ -1146,7 +1081,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
int c, total = 0;
- struct mxser_struct *info = tty->driver_data;
+ struct mxser_port *info = tty->driver_data;
unsigned long flags;
if (!info->xmit_buf)
@@ -1174,11 +1109,12 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou
/*&& !(info->IER & UART_IER_THRI)*/) {
if (!tty->hw_stopped ||
(info->type == PORT_16550A) ||
- (info->IsMoxaMustChipFlag)) {
+ (info->board->chip_flag)) {
spin_lock_irqsave(&info->slock, flags);
- outb(info->IER & ~UART_IER_THRI, info->base + UART_IER);
+ outb(info->IER & ~UART_IER_THRI, info->ioaddr +
+ UART_IER);
info->IER |= UART_IER_THRI;
- outb(info->IER, info->base + UART_IER);
+ outb(info->IER, info->ioaddr + UART_IER);
spin_unlock_irqrestore(&info->slock, flags);
}
}
@@ -1187,7 +1123,7 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou
static void mxser_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct mxser_struct *info = tty->driver_data;
+ struct mxser_port *info = tty->driver_data;
unsigned long flags;
if (!info->xmit_buf)
@@ -1204,11 +1140,11 @@ static void mxser_put_char(struct tty_struct *tty, unsigned char ch)
if (!tty->stopped /*&& !(info->IER & UART_IER_THRI)*/) {
if (!tty->hw_stopped ||
(info->type == PORT_16550A) ||
- info->IsMoxaMustChipFlag) {
+ info->board->chip_flag) {
spin_lock_irqsave(&info->slock, flags);
- outb(info->IER & ~UART_IER_THRI, info->base + UART_IER);
+ outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER);
info->IER |= UART_IER_THRI;
- outb(info->IER, info->base + UART_IER);
+ outb(info->IER, info->ioaddr + UART_IER);
spin_unlock_irqrestore(&info->slock, flags);
}
}
@@ -1217,7 +1153,7 @@ static void mxser_put_char(struct tty_struct *tty, unsigned char ch)
static void mxser_flush_chars(struct tty_struct *tty)
{
- struct mxser_struct *info = tty->driver_data;
+ struct mxser_port *info = tty->driver_data;
unsigned long flags;
if (info->xmit_cnt <= 0 ||
@@ -1225,22 +1161,22 @@ static void mxser_flush_chars(struct tty_struct *tty)
!info->xmit_buf ||
(tty->hw_stopped &&
(info->type != PORT_16550A) &&
- (!info->IsMoxaMustChipFlag)
+ (!info->board->chip_flag)
))
return;
spin_lock_irqsave(&info->slock, flags);
- outb(info->IER & ~UART_IER_THRI, info->base + UART_IER);
+ outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER);
info->IER |= UART_IER_THRI;
- outb(info->IER, info->base + UART_IER);
+ outb(info->IER, info->ioaddr + UART_IER);
spin_unlock_irqrestore(&info->slock, flags);
}
static int mxser_write_room(struct tty_struct *tty)
{
- struct mxser_struct *info = tty->driver_data;
+ struct mxser_port *info = tty->driver_data;
int ret;
ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
@@ -1251,10 +1187,10 @@ static int mxser_write_room(struct tty_struct *tty)
static int mxser_chars_in_buffer(struct tty_struct *tty)
{
- struct mxser_struct *info = tty->driver_data;
+ struct mxser_port *info = tty->driver_data;
int len = info->xmit_cnt;
- if (!(inb(info->base + UART_LSR) & UART_LSR_THRE))
+ if (!(inb(info->ioaddr + UART_LSR) & UART_LSR_THRE))
len++;
return len;
@@ -1262,7 +1198,7 @@ static int mxser_chars_in_buffer(struct tty_struct *tty)
static void mxser_flush_buffer(struct tty_struct *tty)
{
- struct mxser_struct *info = tty->driver_data;
+ struct mxser_port *info = tty->driver_data;
char fcr;
unsigned long flags;
@@ -1271,10 +1207,10 @@ static void mxser_flush_buffer(struct tty_struct *tty)
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
/* below added by shinhay */
- fcr = inb(info->base + UART_FCR);
+ fcr = inb(info->ioaddr + UART_FCR);
outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
- info->base + UART_FCR);
- outb(fcr, info->base + UART_FCR);
+ info->ioaddr + UART_FCR);
+ outb(fcr, info->ioaddr + UART_FCR);
spin_unlock_irqrestore(&info->slock, flags);
/* above added by shinhay */
@@ -1286,7 +1222,7 @@ static void mxser_flush_buffer(struct tty_struct *tty)
static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
{
- struct mxser_struct *info = tty->driver_data;
+ struct mxser_port *info = tty->driver_data;
int retval;
struct async_icount cprev, cnow; /* kernel counter temps */
struct serial_icounter_struct __user *p_cuser;
@@ -1305,7 +1241,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
int shiftbit;
unsigned char val, mask;
- p = info->port % 4;
+ p = tty->index % 4;
if (cmd == MOXA_SET_OP_MODE) {
if (get_user(opmode, (int __user *) argp))
return -EFAULT;
@@ -1465,7 +1401,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
len = mxser_chars_in_buffer(tty);
- lsr = inb(info->base + UART_LSR) & UART_LSR_TEMT;
+ lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT;
len += (lsr ? 0 : 1);
@@ -1479,10 +1415,10 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
/* info->mon_data.ser_param = tty->termios->c_cflag; */
- status = mxser_get_msr(info->base, 1, info->port, info);
+ status = mxser_get_msr(info->ioaddr, 1, tty->index);
mxser_check_modem_status(info, status);
- mcr = inb(info->base + UART_MCR);
+ mcr = inb(info->ioaddr + UART_MCR);
if (mcr & MOXA_MUST_MCR_XON_FLAG)
info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
else
@@ -1518,7 +1454,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
if (get_user(method, (int __user *)argp))
return -EFAULT;
- mxser_set_baud_method[info->port] = method;
+ mxser_set_baud_method[tty->index] = method;
if (copy_to_user(argp, &method, sizeof(int)))
return -EFAULT;
@@ -1536,14 +1472,17 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
{
- int i, result, status;
+ struct mxser_port *port;
+ int result, status;
+ unsigned int i, j;
switch (cmd) {
case MOXA_GET_CONF:
- if (copy_to_user(argp, mxsercfg,
+/* if (copy_to_user(argp, mxsercfg,
sizeof(struct mxser_hwconf) * 4))
return -EFAULT;
- return 0;
+ return 0;*/
+ return -ENXIO;
case MOXA_GET_MAJOR:
if (copy_to_user(argp, &ttymajor, sizeof(int)))
return -EFAULT;
@@ -1556,96 +1495,106 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
case MOXA_CHKPORTENABLE:
result = 0;
- for (i = 0; i < MXSER_PORTS; i++) {
- if (mxvar_table[i].base)
- result |= (1 << i);
- }
+
+ for (i = 0; i < MXSER_BOARDS; i++)
+ for (j = 0; j < MXSER_PORTS_PER_BOARD; j++)
+ if (mxser_boards[i].ports[j].ioaddr)
+ result |= (1 << i);
+
return put_user(result, (unsigned long __user *)argp);
case MOXA_GETDATACOUNT:
if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log)))
return -EFAULT;
return 0;
case MOXA_GETMSTATUS:
- for (i = 0; i < MXSER_PORTS; i++) {
- GMStatus[i].ri = 0;
- if (!mxvar_table[i].base) {
- GMStatus[i].dcd = 0;
- GMStatus[i].dsr = 0;
- GMStatus[i].cts = 0;
- continue;
- }
+ for (i = 0; i < MXSER_BOARDS; i++)
+ for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) {
+ port = &mxser_boards[i].ports[j];
+
+ GMStatus[i].ri = 0;
+ if (!port->ioaddr) {
+ GMStatus[i].dcd = 0;
+ GMStatus[i].dsr = 0;
+ GMStatus[i].cts = 0;
+ continue;
+ }
- if (!mxvar_table[i].tty || !mxvar_table[i].tty->termios)
- GMStatus[i].cflag = mxvar_table[i].normal_termios.c_cflag;
- else
- GMStatus[i].cflag = mxvar_table[i].tty->termios->c_cflag;
+ if (!port->tty || !port->tty->termios)
+ GMStatus[i].cflag =
+ port->normal_termios.c_cflag;
+ else
+ GMStatus[i].cflag =
+ port->tty->termios->c_cflag;
- status = inb(mxvar_table[i].base + UART_MSR);
- if (status & 0x80 /*UART_MSR_DCD */ )
- GMStatus[i].dcd = 1;
- else
- GMStatus[i].dcd = 0;
+ status = inb(port->ioaddr + UART_MSR);
+ if (status & 0x80 /*UART_MSR_DCD */ )
+ GMStatus[i].dcd = 1;
+ else
+ GMStatus[i].dcd = 0;
- if (status & 0x20 /*UART_MSR_DSR */ )
- GMStatus[i].dsr = 1;
- else
- GMStatus[i].dsr = 0;
+ if (status & 0x20 /*UART_MSR_DSR */ )
+ GMStatus[i].dsr = 1;
+ else
+ GMStatus[i].dsr = 0;
- if (status & 0x10 /*UART_MSR_CTS */ )
- GMStatus[i].cts = 1;
- else
- GMStatus[i].cts = 0;
- }
+ if (status & 0x10 /*UART_MSR_CTS */ )
+ GMStatus[i].cts = 1;
+ else
+ GMStatus[i].cts = 0;
+ }
if (copy_to_user(argp, GMStatus,
sizeof(struct mxser_mstatus) * MXSER_PORTS))
return -EFAULT;
return 0;
case MOXA_ASPP_MON_EXT: {
- int status, p, shiftbit;
- unsigned long opmode;
- unsigned cflag, iflag;
+ int status, p, shiftbit;
+ unsigned long opmode;
+ unsigned cflag, iflag;
- for (i = 0; i < MXSER_PORTS; i++) {
- if (!mxvar_table[i].base)
+ for (i = 0; i < MXSER_BOARDS; i++)
+ for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) {
+ port = &mxser_boards[i].ports[j];
+ if (!port->ioaddr)
continue;
- status = mxser_get_msr(mxvar_table[i].base, 0,
- i, &(mxvar_table[i]));
- /*
- mxser_check_modem_status(&mxvar_table[i],
- status);
- */
+ status = mxser_get_msr(port->ioaddr, 0, i);
+/* mxser_check_modem_status(port, status); */
+
if (status & UART_MSR_TERI)
- mxvar_table[i].icount.rng++;
+ port->icount.rng++;
if (status & UART_MSR_DDSR)
- mxvar_table[i].icount.dsr++;
+ port->icount.dsr++;
if (status & UART_MSR_DDCD)
- mxvar_table[i].icount.dcd++;
+ port->icount.dcd++;
if (status & UART_MSR_DCTS)
- mxvar_ta