Commit 55b307da authored by Jiri Slaby's avatar Jiri Slaby Committed by Linus Torvalds
Browse files

[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: default avatarJiri Slaby <jirislaby@gmail.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 3306ce3d
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
#include "mxser_new.h" #include "mxser_new.h"
#define MXSER_VERSION "1.9.1" #define MXSER_VERSION "2.0"
#define MXSERMAJOR 174 #define MXSERMAJOR 174
#define MXSERCUMAJOR 175 #define MXSERCUMAJOR 175
...@@ -85,8 +85,6 @@ ...@@ -85,8 +85,6 @@
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|\ #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|\
IXON|IXOFF)) IXON|IXOFF))
#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : IRQF_DISABLED)
#define C168_ASIC_ID 1 #define C168_ASIC_ID 1
#define C104_ASIC_ID 2 #define C104_ASIC_ID 2
#define C102_ASIC_ID 0xB #define C102_ASIC_ID 0xB
...@@ -202,8 +200,6 @@ static const struct mxpciuart_info Gpci_uart_info[UART_INFO_NUM] = { ...@@ -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[] = { static struct pci_device_id mxser_pcibrds[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168), { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168),
.driver_data = MXSER_BOARD_C168_PCI }, .driver_data = MXSER_BOARD_C168_PCI },
...@@ -243,18 +239,8 @@ static struct pci_device_id mxser_pcibrds[] = { ...@@ -243,18 +239,8 @@ static struct pci_device_id mxser_pcibrds[] = {
.driver_data = MXSER_BOARD_CP104EL }, .driver_data = MXSER_BOARD_CP104EL },
{ } { }
}; };
MODULE_DEVICE_TABLE(pci, mxser_pcibrds); 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 ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 };
static int ttymajor = MXSERMAJOR; static int ttymajor = MXSERMAJOR;
static int calloutmajor = MXSERCUMAJOR; static int calloutmajor = MXSERCUMAJOR;
...@@ -301,69 +287,77 @@ struct mxser_mon_ext { ...@@ -301,69 +287,77 @@ struct mxser_mon_ext {
int iftype[32]; int iftype[32];
}; };
struct mxser_hwconf { struct mxser_board;
int board_type;
int ports; struct mxser_port {
int irq; struct mxser_board *board;
unsigned long vector; struct tty_struct *tty;
unsigned long vector_mask;
int uart_type; unsigned long ioaddr;
unsigned long ioaddr[MXSER_PORTS_PER_BOARD]; unsigned long opmode_ioaddr;
int baud_base[MXSER_PORTS_PER_BOARD]; int max_baud;
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_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_high_water;
int rx_trigger; /* Rx fifo trigger level */ int rx_trigger; /* Rx fifo trigger level */
int rx_low_water; int rx_low_water;
int baud_base; /* max. speed */ int baud_base; /* max. speed */
int flags; /* defined in tty.h */ long realbaud;
int type; /* UART type */ int type; /* UART type */
struct tty_struct *tty; int flags; /* defined in tty.h */
int read_status_mask; long session; /* Session of opening process */
int ignore_status_mask; long pgrp; /* pgrp of opening process */
int xmit_fifo_size;
int custom_divisor;
int x_char; /* xon/xoff character */ int x_char; /* xon/xoff character */
int close_delay;
unsigned short closing_wait;
int IER; /* Interrupt Enable Register */ int IER; /* Interrupt Enable Register */
int MCR; /* Modem control 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; unsigned long event;
int count; /* # of fd on device */ int count; /* # of fd on device */
int blocked_open; /* # of blocked opens */ int blocked_open; /* # of blocked opens */
long session; /* Session of opening process */ struct async_icount icount; /* kernel counters for 4 input interrupts */
long pgrp; /* pgrp of opening process */ int timeout;
int read_status_mask;
int ignore_status_mask;
int xmit_fifo_size;
unsigned char *xmit_buf; unsigned char *xmit_buf;
int xmit_head; int xmit_head;
int xmit_tail; int xmit_tail;
int xmit_cnt; int xmit_cnt;
struct work_struct tqueue;
struct termios normal_termios; struct termios normal_termios;
struct termios callout_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 open_wait;
wait_queue_head_t close_wait; wait_queue_head_t close_wait;
wait_queue_head_t delta_msr_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 */ struct mxser_board {
int MaxCanSetBaudRate; /* add by Victor Yu. 09-04-2002 */ struct pci_dev *pdev; /* temporary (until pci probing) */
unsigned long opmode_ioaddr; /* add by Victor Yu. 01-05-2004 */
unsigned char stop_rx; int irq;
unsigned char ldisc_stop_rx; int board_type;
long realbaud; unsigned int nports;
struct mxser_mon mon_data; unsigned long vector;
unsigned char err_shadow; unsigned long vector_mask;
spinlock_t slock;
int chip_flag;
int uart_type;
struct mxser_port ports[MXSER_PORTS_PER_BOARD];
}; };
struct mxser_mstatus { struct mxser_mstatus {
...@@ -381,8 +375,8 @@ static int mxserBoardCAP[MXSER_BOARDS] = { ...@@ -381,8 +375,8 @@ static int mxserBoardCAP[MXSER_BOARDS] = {
/* 0x180, 0x280, 0x200, 0x320 */ /* 0x180, 0x280, 0x200, 0x320 */
}; };
static struct mxser_board mxser_boards[MXSER_BOARDS];
static struct tty_driver *mxvar_sdriver; 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 tty_struct *mxvar_tty[MXSER_PORTS + 1];
static struct termios *mxvar_termios[MXSER_PORTS + 1]; static struct termios *mxvar_termios[MXSER_PORTS + 1];
static struct termios *mxvar_termios_locked[MXSER_PORTS + 1]; static struct termios *mxvar_termios_locked[MXSER_PORTS + 1];
...@@ -393,22 +387,14 @@ static struct mxser_mon_ext mon_data_ext; ...@@ -393,22 +387,14 @@ static struct mxser_mon_ext mon_data_ext;
static int mxser_set_baud_method[MXSER_PORTS + 1]; static int mxser_set_baud_method[MXSER_PORTS + 1];
static spinlock_t gm_lock; 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 functions:
*/ */
static void mxser_getcfg(int board, struct mxser_hwconf *hwconf);
static int mxser_init(void); static int mxser_init(void);
/* static void mxser_poll(unsigned long); */ /* static void mxser_poll(unsigned long); */
static int mxser_get_ISA_conf(int, struct mxser_hwconf *); static int mxser_get_ISA_conf(int, struct mxser_board *);
static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *);
static void mxser_do_softint(void *); static void mxser_do_softint(void *);
static int mxser_open(struct tty_struct *, struct file *); static int mxser_open(struct tty_struct *, struct file *);
static void mxser_close(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 *); ...@@ -428,24 +414,28 @@ static void mxser_start(struct tty_struct *);
static void mxser_hangup(struct tty_struct *); static void mxser_hangup(struct tty_struct *);
static void mxser_rs_break(struct tty_struct *, int); static void mxser_rs_break(struct tty_struct *, int);
static irqreturn_t mxser_interrupt(int, void *, struct pt_regs *); static irqreturn_t mxser_interrupt(int, void *, struct pt_regs *);
static void mxser_receive_chars(struct mxser_struct *, int *); static void mxser_receive_chars(struct mxser_port *, int *);
static void mxser_transmit_chars(struct mxser_struct *); static void mxser_transmit_chars(struct mxser_port *);
static void mxser_check_modem_status(struct mxser_struct *, int); static void mxser_check_modem_status(struct mxser_port *, int);
static int mxser_block_til_ready(struct tty_struct *, struct file *, struct mxser_struct *); static int mxser_block_til_ready(struct tty_struct *, struct file *,
static int mxser_startup(struct mxser_struct *); struct mxser_port *);
static void mxser_shutdown(struct mxser_struct *); static int mxser_startup(struct mxser_port *);
static int mxser_change_speed(struct mxser_struct *, struct termios *old_termios); static void mxser_shutdown(struct mxser_port *);
static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct __user *); static int mxser_change_speed(struct mxser_port *, struct termios *);
static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct __user *); static int mxser_get_serial_info(struct mxser_port *,
static int mxser_get_lsr_info(struct mxser_struct *, unsigned int __user *); struct serial_struct __user *);
static void mxser_send_break(struct mxser_struct *, int); 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_tiocmget(struct tty_struct *, struct file *);
static int mxser_tiocmset(struct tty_struct *, struct file *, unsigned int, unsigned int); static int mxser_tiocmset(struct tty_struct *, struct file *, unsigned int,
static int mxser_set_baud(struct mxser_struct *info, long newspd); unsigned int);
static void mxser_wait_until_sent(struct tty_struct *tty, int timeout); 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_startrx(struct tty_struct *);
static void mxser_stoprx(struct tty_struct *tty); static void mxser_stoprx(struct tty_struct *);
static int CheckIsMoxaMust(int io) static int CheckIsMoxaMust(int io)
...@@ -530,18 +520,18 @@ static void __exit mxser_module_exit(void) ...@@ -530,18 +520,18 @@ static void __exit mxser_module_exit(void)
for (i = 0; i < MXSER_BOARDS; i++) { for (i = 0; i < MXSER_BOARDS; i++) {
struct pci_dev *pdev; struct pci_dev *pdev;
if (mxsercfg[i].board_type == -1) if (mxser_boards[i].board_type == -1)
continue; continue;
else { else {
pdev = mxsercfg[i].pciInfo.pdev; pdev = mxser_boards[i].pdev;
free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]); free_irq(mxser_boards[i].irq, &mxser_boards[i]);
if (pdev != NULL) { /* PCI */ if (pdev != NULL) { /* PCI */
release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2)); release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3)); release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
pci_dev_put(pdev); pci_dev_put(pdev);
} else { } else {
release_region(mxsercfg[i].ioaddr[0], 8 * mxsercfg[i].ports); release_region(mxser_boards[i].ports[0].ioaddr, 8 * mxser_boards[i].nports);
release_region(mxsercfg[i].vector, 1); release_region(mxser_boards[i].vector, 1);
} }
} }
} }
...@@ -549,7 +539,7 @@ static void __exit mxser_module_exit(void) ...@@ -549,7 +539,7 @@ static void __exit mxser_module_exit(void)
printk(KERN_DEBUG "Done.\n"); 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; int i;
...@@ -558,60 +548,44 @@ static void process_txrx_fifo(struct mxser_struct *info) ...@@ -558,60 +548,44 @@ static void process_txrx_fifo(struct mxser_struct *info)
info->rx_high_water = 1; info->rx_high_water = 1;
info->rx_low_water = 1; info->rx_low_water = 1;
info->xmit_fifo_size = 1; info->xmit_fifo_size = 1;
} else { } else
for (i = 0; i < UART_INFO_NUM; i++) { for (i = 0; i < UART_INFO_NUM; i++)
if (info->IsMoxaMustChipFlag == Gpci_uart_info[i].type) { if (info->board->chip_flag == Gpci_uart_info[i].type) {
info->rx_trigger = Gpci_uart_info[i].rx_trigger; info->rx_trigger = Gpci_uart_info[i].rx_trigger;
info->rx_low_water = Gpci_uart_info[i].rx_low_water; info->rx_low_water = Gpci_uart_info[i].rx_low_water;
info->rx_high_water = Gpci_uart_info[i].rx_high_water; info->rx_high_water = Gpci_uart_info[i].rx_high_water;
info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size; info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size;
break; 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 retval;
int i, n;
n = board * MXSER_PORTS_PER_BOARD;
info = &mxvar_table[n];
/*if (verbose) */ { /*if (verbose) */ {
printk(KERN_DEBUG " ttyM%d - ttyM%d ",
n, n + hwconf->ports - 1);
printk(" max. baud rate = %d bps.\n", printk(" max. baud rate = %d bps.\n",
hwconf->MaxCanSetBaudRate[0]); brd->ports[0].max_baud);
} }
for (i = 0; i < hwconf->ports; i++, n++, info++) { for (i = 0; i < brd->nports; i++) {
info->port = n; info = &brd->ports[i];
info->base = hwconf->ioaddr[i]; info->board = brd;
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 */
info->stop_rx = 0; info->stop_rx = 0;
info->ldisc_stop_rx = 0; info->ldisc_stop_rx = 0;
info->IsMoxaMustChipFlag = hwconf->IsMoxaMustChipFlag;
/* Enhance mode enabled here */ /* Enhance mode enabled here */
if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) { if (brd->chip_flag != MOXA_OTHER_UART)
ENABLE_MOXA_MUST_ENCHANCE_MODE(info->base); ENABLE_MOXA_MUST_ENCHANCE_MODE(info->ioaddr);
}
info->flags = ASYNC_SHARE_IRQ; info->flags = ASYNC_SHARE_IRQ;
info->type = hwconf->uart_type; info->type = brd->uart_type;
info->baud_base = hwconf->baud_base[i];
info->MaxCanSetBaudRate = hwconf->MaxCanSetBaudRate[i];
process_txrx_fifo(info); process_txrx_fifo(info);
info->custom_divisor = info->baud_base * 16;
info->custom_divisor = hwconf->baud_base[i] * 16;
info->close_delay = 5 * HZ / 10; info->close_delay = 5 * HZ / 10;
info->closing_wait = 30 * HZ; info->closing_wait = 30 * HZ;
INIT_WORK(&info->tqueue, mxser_do_softint, info); INIT_WORK(&info->tqueue, mxser_do_softint, info);
...@@ -622,118 +596,102 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf) ...@@ -622,118 +596,102 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf)
memset(&info->mon_data, 0, sizeof(struct mxser_mon)); memset(&info->mon_data, 0, sizeof(struct mxser_mon));
info->err_shadow = 0; info->err_shadow = 0;
spin_lock_init(&info->slock); 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 * Allocate the IRQ if necessary
*/ */
retval = request_irq(brd->irq, mxser_interrupt,
/* before set INT ISR, disable all int */ (brd->ports[0].flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED :
for (i = 0; i < hwconf->ports; i++) { IRQF_DISABLED, "mxser", brd);
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);
if (retval) { if (retval) {
printk(KERN_ERR "Board %d: %s", printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
board, mxser_brdname[hwconf->board_type - 1]); "conflict with another device.\n",
printk(" Request irq failed, IRQ (%d) may conflict with" mxser_brdname[brd->board_type - 1], brd->irq);
" another device.\n", info->irq);
return retval; return retval;
} }
return 0; return 0;
} }
static void mxser_getcfg(int board, struct mxser_hwconf *hwconf) static int mxser_get_PCI_conf(int board_type, struct mxser_board *brd,
{ struct pci_dev *pdev)
mxsercfg[board] = *hwconf;
}
#ifdef CONFIG_PCI
static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxser_hwconf *hwconf)
{ {
int i, j; unsigned int i, j;
/* unsigned int val; */
unsigned long ioaddress; unsigned long ioaddress;
struct pci_dev *pdev = hwconf->pciInfo.pdev;
/* io address */ /* io address */
hwconf->board_type = board_type; brd->board_type = board_type;
hwconf->ports = mxser_numports[board_type - 1]; brd->nports = mxser_numports[board_type - 1];
ioaddress = pci_resource_start(pdev, 2); ioaddress = pci_resource_start(pdev, 2);
request_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2), request_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2),
"mxser(IO)"); "mxser(IO)");
for (i = 0; i < hwconf->ports; i++) for (i = 0; i < brd->nports; i++)
hwconf->ioaddr[i] = ioaddress + 8 * i; brd->ports[i].ioaddr = ioaddress + 8 * i;
/* vector */ /* vector */
ioaddress = pci_resource_start(pdev, 3); ioaddress = pci_resource_start(pdev, 3);
request_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3), request_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3),
"mxser(vector)"); "mxser(vector)");
hwconf->vector = ioaddress; brd->vector = ioaddress;
/* irq */ /* irq */
hwconf->irq = hwconf->pciInfo.pdev->irq; brd->irq = pdev->irq;
hwconf->IsMoxaMustChipFlag = CheckIsMoxaMust(hwconf->ioaddr[0]); brd->chip_flag = CheckIsMoxaMust(brd->ports[0].ioaddr);
hwconf->uart_type = PORT_16550A; brd->uart_type = PORT_16550A;
hwconf->vector_mask = 0; brd->vector_mask = 0;
for (i = 0; i < brd->nports; i++) {
for (i = 0; i < hwconf->ports; i++) {
for (j = 0; j < UART_INFO_NUM; j++) { for (j = 0; j < UART_INFO_NUM; j++) {
if (Gpci_uart_info[j].type == hwconf->IsMoxaMustChipFlag) { if (Gpci_uart_info[j].type == brd->chip_flag) {
hwconf->MaxCanSetBaudRate[i] = Gpci_uart_info[j].max_baud; brd->ports[i].max_baud =
Gpci_uart_info[j].max_baud;
/* exception....CP-102 */ /* exception....CP-102 */
if (board_type == MXSER_BOARD_CP102) if (board_type == MXSER_BOARD_CP102)
hwconf->MaxCanSetBaudRate[i] = 921600; brd->ports[i].max_baud = 921600;
break; break;
} }
} }
} }
if (hwconf->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID) { if (brd->chip_flag == MOXA_MUST_MU860_HWID) {
for (i = 0; i < hwconf->ports; i++) { for (i = 0; i < brd->nports; i++) {
if (i < 4) if (i < 4)
hwconf->opmode_ioaddr[i] = ioaddress + 4; brd->ports[i].opmode_ioaddr = ioaddress + 4;
else 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 + 4); /* default set to RS232 mode */
outb(0, ioaddress + 0x0c); /* default set to RS232 mode */ outb(0, ioaddress + 0x0c); /* default set to RS232 mode */
} }
for (i = 0; i < hwconf->ports; i++) { for (i = 0; i < brd->nports; i++) {
hwconf->vector_mask |= (1 << i); brd->vector_mask |= (1 << i);
hwconf->baud_base[i] = 921600; brd->ports[i].baud_base = 921600;
} }
return 0; return 0;
} }
#endif
</