serial.c to support ConnectTech Blueheat PCI
Caleb Tennis
AppliedPATCH 1/1 serial.c to support ConnectTech Blueheat PCI
My first attempt at a patch - this fix was actually supported by ConnectTech but for an older version of the serial driver - this patch brings it up to date with changes made to the kernel since 2.2.
This patch was applied to a 2.4.7 kernel.
Caleb
drivers/char/serial.c renamed from drivers/char/serial_orig.bak +156 -8
@@ -57,10 +57,12 @@* 10/00: add in optional software flow control for serial console. * Kanoj Sarcar <[email protected]> (Modified by Theodore Ts'o) * +* 8/01: added support for ConnectTech Blueheat PCI boards (RS485 +* support) <[email protected]> */ -static char *serial_version ="5.05c" ; -static char *serial_revdate ="2001-07-08" ; +static char *serial_version ="5.05d" ; +static char *serial_revdate ="2001-08-10" ;/* * Serial driver configuration section. Here are the various options:
@@ -1417,6 +1419,9 @@*/ mod_timer (&serial_timer, jiffies +2 *HZ /100 ); +if (state->lmode_fn) + (state->lmode_fn)(state,TIOCSER485SET ,NULL ); +/* * Set up the tty->alt_speed kludge */
@@ -2523,6 +2528,7 @@ unsigned int cmd, unsigned long arg) {struct async_struct * info = (struct async_struct *)tty->driver_data; +struct serial_state * state = info->state;struct async_icount cprev, cnow;/* kernel counter temps */ struct serial_icounter_struct icount;unsigned long flags;
@@ -2580,6 +2586,10 @@ (tmp ? CLOCAL : 0));return 0 ;#endif +case TIOCSER485GET : +case TIOCSER485SET : +if (state->lmode_fn) +return (state->lmode_fn)(state, cmd, (unsigned int *) arg);case TIOCMGET :return get_modem_info (info, (unsigned int *) arg);case TIOCMBIS :
@@ -3985,6 +3995,7 @@if (line <0 )break ; rs_table[line].baud_base = base_baud; + rs_table[line].lmode_fn = board->lmode_fn; rs_table[line].dev = dev; } }
@@ -4138,6 +4149,131 @@ }/* +* These functions allow for setting for half, full, and slave duplex on +* ConnectTech Blueheat PCI multiport boards. cti485 does the work. +* _2 and _4 do checking for the hybrid boards. +* They rely on the fact that the ports will start at a 256 aligned +* address to calculate which port on the board it is. +*/ + +static int pci_cti485_fn (struct serial_state *state,int ioctl, +unsigned int *value) { + +static unsigned char done_init =0 ; +struct async_struct *info; +unsigned char port_offset; +unsigned char portmask; +unsigned char txctl_offset; +unsigned char rxctl_offset; +unsigned char differ_offset; +unsigned char bits; +unsigned long flags; + +if (ioctl ==TIOCSER485GET ) +return put_user (state->lmode, value); + + info = state->info; + port_offset = state->port %0x100 ; + portmask =1 << port_offset /0x08 ; + txctl_offset =0x6c - port_offset; + rxctl_offset =0x70 - port_offset; + +save_flags (flags);cli (); +if (value) + state->lmode = *value; +else if (!done_init) { + differ_offset =0x74 - port_offset; + bits =serial_in (info, differ_offset); +switch (bits) { +case 0x03 : + state->lmode =TIOCSER485SLAVEMULTIPLEX ; +break ; +default : + state->lmode =TIOCSER485FULLDUPLEX ; +break ; + } + } + done_init =1 ; + bits =serial_in (info, txctl_offset); +switch (state->lmode) { +default : +case TIOCSER485FULLDUPLEX : + bits &= ~portmask; +serial_out (info, txctl_offset, bits); + + bits =serial_in (info, rxctl_offset); + bits |= portmask; +serial_out (info, rxctl_offset, bits); + +serial_out (info,UART_LCR ,0xbf ); + bits =serial_in (info,UART_FCTR ); + bits &= ~UART_FCTR_TX_INT ; +serial_out (info,UART_FCTR , bits); +serial_out (info,UART_LCR ,0 ); + +restore_flags (flags); +return put_user (1 , value); +case TIOCSER485HALFDUPLEX : + bits |= portmask; +serial_out (info, txctl_offset, bits); + + bits =serial_in (info, rxctl_offset); + bits &= ~portmask; +serial_out (info, rxctl_offset, bits); + +serial_out (info,UART_LCR ,0xbf ); + bits =serial_in (info,UART_FCTR ); + bits |=UART_FCTR_TX_INT ; +serial_out (info,UART_FCTR , bits); +serial_out (info,UART_LCR ,0 ); + +restore_flags (flags); +return put_user (1 , value); +case TIOCSER485SLAVEMULTIPLEX : + bits |= portmask; +serial_out (info, txctl_offset, bits); + + bits =serial_in (info, rxctl_offset); + bits |= portmask; +serial_out (info, rxctl_offset, bits); + +serial_out (info,UART_LCR ,0xbf ); + bits =serial_in (info,UART_FCTR ); + bits |=UART_FCTR_TX_INT ; +serial_out (info,UART_FCTR , bits); +serial_out (info,UART_LCR ,0 ); + +restore_flags (flags); +return put_user (1 , value); + } + +restore_flags (flags); +return -EINVAL ; +} + +static int pci_cti485_4_fn (struct serial_state *state,int ioctl, +unsigned int *value) { +int port = state->port; +int board_num = (port %0x100 ) /0x08 ; + +if (board_num <4 ) +return -ENOSYS ; + +return pci_cti485_fn (state, ioctl, value); +} + +static int pci_cti485_2_fn (struct serial_state *state,int ioctl, +unsigned int *value) { +int port = state->port; +int board_num = (port %0x100 ) /0x08 ; + +if (board_num <2 ) +return -ENOSYS ; + +return pci_cti485_fn (state, ioctl, value); +} + +/* * Timedia has an explosion of boards, and to avoid the PCI table from * growing *huge*, we use this function to collapse some 70 entries * in the PCI table into one, for sanity's and compactness's sake.
@@ -4227,7 +4363,10 @@ pbn_b1_2_921600, pbn_b1_4_921600, + pbn_b1_4_2_921600,/* Added for 232/485 hybrid boards */ pbn_b1_8_921600, + pbn_b1_8_4_921600,/* Added for 232/485 hybrid boards */ + pbn_b1_8_2_921600,/* Added for 232/485 hybrid boards */ pbn_b1_2_1382400, pbn_b1_4_1382400,
@@ -4303,9 +4442,18 @@ { SPCI_FL_BASE1, 4, 115200 }, /* pbn_b1_4_115200 */ { SPCI_FL_BASE1, 8, 115200 }, /* pbn_b1_8_115200 */ - { SPCI_FL_BASE1, 2, 921600 }, /* pbn_b1_2_921600 */ - { SPCI_FL_BASE1, 4, 921600 }, /* pbn_b1_4_921600 */ - { SPCI_FL_BASE1, 8, 921600 }, /* pbn_b1_8_921600 */ + { SPCI_FL_BASE1, 2, 921600, /* pbn_b1_2_921600 */ + 0, 0, NULL, 0, pci_cti485_fn }, + { SPCI_FL_BASE1, 4, 921600, /* pbn_b1_4_921600 */ + 0, 0, NULL, 0, pci_cti485_fn }, + { SPCI_FL_BASE1, 4, 921600, /* pbn_b1_4_2_921600 */ + 0, 0, NULL, 0, pci_cti485_2_fn }, + { SPCI_FL_BASE1, 8, 921600, /* pbn_b1_8_921600 */ + 0, 0, NULL, 0, pci_cti485_fn }, + { SPCI_FL_BASE1, 8, 921600, + 0, 0, NULL, 0, pci_cti485_4_fn }, /* pbn_b1_8_4_921600 */ + { SPCI_FL_BASE1, 8, 921600, + 0, 0, NULL, 0, pci_cti485_2_fn }, /* pbn_b1_8_2_921600 */ { SPCI_FL_BASE1, 2, 1382400 }, /* pbn_b1_2_1382400 */ { SPCI_FL_BASE1, 4, 1382400 }, /* pbn_b1_4_1382400 */
@@ -4515,7 +4663,7 @@ {PCI_VENDOR_ID_V3 ,PCI_DEVICE_ID_V3_V351 ,PCI_SUBVENDOR_ID_CONNECT_TECH ,PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4 ,0 ,0 , - pbn_b1_8_921600 }, + pbn_b1_8_4_921600 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,PCI_SUBVENDOR_ID_CONNECT_TECH , PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0,
@@ -4523,7 +4671,7 @@ {PCI_VENDOR_ID_V3 ,PCI_DEVICE_ID_V3_V351 ,PCI_SUBVENDOR_ID_CONNECT_TECH ,PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2 ,0 ,0 , - pbn_b1_4_921600 }, + pbn_b1_4_2_921600 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,PCI_SUBVENDOR_ID_CONNECT_TECH , PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0,
@@ -4531,7 +4679,7 @@ {PCI_VENDOR_ID_V3 ,PCI_DEVICE_ID_V3_V351 ,PCI_SUBVENDOR_ID_CONNECT_TECH ,PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6 ,0 ,0 , - pbn_b1_8_921600 }, + pbn_b1_8_2_921600 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,PCI_SUBVENDOR_ID_CONNECT_TECH , PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0,
include/linux/serialP.h renamed from include/linux/serialP_orig.bak +5 -0
@@ -51,6 +51,9 @@struct termios normal_termios;struct termios callout_termios;int io_type; +int (*lmode_fn)(struct serial_state *state,int ioctl, +unsigned int *value); +int lmode;struct async_struct *info;struct pci_dev *dev; };
@@ -150,6 +153,8 @@int (*init_fn)(struct pci_dev *dev,struct pci_board *board,int enable);int first_uart_offset; +int (*lmode_fn)(struct serial_state *state,int ioctl, +unsigned int *value); };struct pci_board_inst {
include/asm-i386/ioctls.h renamed from include/asm-i386/ioctls_orig.bak +8 -0
@@ -68,6 +68,14 @@#define TIOCGHAYESESP 0x545E/* Get Hayes ESP configuration */ #define TIOCSHAYESESP 0x545F/* Set Hayes ESP configuration */ +#define TIOCSER485SET 0x5460/* Set the 485 line */ +#define TIOCSER485GET 0x5461/* Get the 485 line */ + +#define TIOCSER485FULLDUPLEX 0 +#define TIOCSER485HALFDUPLEX 1 +#define TIOCSER485SLAVEMULTIPLEX 2 + +/* Used for packet mode */ #define TIOCPKT_DATA 0#define TIOCPKT_FLUSHREAD 1
--
Caleb Tennis
Analytical Engineering
2555 Technology Blvd
Columbus, IN 47201
-------------------------------------------------------
Signature · 4 lines
Caleb Tennis Analytical Engineering 2555 Technology Blvd Columbus, IN 47201
From: "Caleb Tennis" <[email protected]>
Quoted 1 line
My first attempt at a patch - this fix was actually supported by
ConnectTech
Quoted 2 lines
but for an older version of the serial driver - this patch brings it up to date with changes made to the kernel since 2.2.
This patch is maintained by me; it applies to 5.05. I'm not sure how 5.05[abc] are different from vanilla 5.05 though.
The reason this patch hasn't been seen on lkml is that I prefer to have all the serial driver patches go through Ted (T'so the serial driver maintainer) first. He's rejected this patch once already on the basis that it adds specific board functionality to the driver, which he's trying to avoid. I resubmitted it Jun 27 2001 with a lengthy explanation that all boards with half duplex and slave multiplex functionality would have to have some method of doing the switching between the modes, and that this isn't specific to our products. I haven't heard back from him since.
He has been working intermittently on the driver, at the time I submitted the 485 patch in Jun I'd also done some work on his devel tarball, as we had a customer issue to fix. I'm sure that a new version will show up in a while.
Linus, Alan, whomever else maintains kernels: if you wish to apply this patch regardless of Ted's opinion, please contact me.
Caleb: I appreciate the effort, thanks.
Ted: What's the news with a new version?
..Stu
--
We make multiport serial boards.
www.connecttech.com
(519) 836-1291
Quoted 2 lines · Stuart MacDonald
This patch is maintained by me; it applies to 5.05. I'm not sure how 5.05[abc] are different from vanilla 5.05 though.
I'm maintaining a new serial driver structure in CVS at:
:pserver:[email protected]:/mnt/src/cvsroot (no password)
module: serial
There's a couple of outstanding bits in my working set left to commit, but all the code (minus makefiles and Configure scripts) is there. If you'd like to port it to the new version cleanly, then I'll keep it in there.
Note that Ted hasn't given his OK for this restructuring - he's too busy to even look and comment at the moment.
--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html
Quoted 2 lines · Stuart MacDonald
This patch is maintained by me; it applies to 5.05. I'm not sure how 5.05[abc] are different from vanilla 5.05 though.
I'm quite pleased at the support ConnectTech has for this product. We are planning on purchasing more in the future.
Quoted 10 lines
The reason this patch hasn't been seen on lkml is that I prefer to have all the serial driver patches go through Ted (T'so the serial driver maintainer) first. He's rejected this patch once already on the basis that it adds specific board functionality to the driver, which he's trying to avoid. I resubmitted it Jun 27 2001 with a lengthy explanation that all boards with half duplex and slave multiplex functionality would have to have some method of doing the switching between the modes, and that this isn't specific to our products. I haven't heard back from him since.
I originally applied the ConnectTech patch a few months ago to a 2.2.19 kernel. I ran into a lot of problems related to the serial driver 5.05 having some errors in it. it would compile just fine as as module, but not when integrated into the kernel. There were almost 20 patches to the serial driver up on sourceforge fixing most of these problems - and they took care of the situation. After looking at the sourceforge site, it seemed like Ted Tso isn't actively maintaining the serial driver anymore (though I noticed activity from him on other projects he supports, like e2fsprogs) and my assumption was that he was busy. I had noticed that in the 2.4 series, some modifications had been made to the serial driver (hence the "abc" progression), and thought it may be valuable to submit a patch related to the latest kernel.
There really isn't a good way around this patch - I understand Ted's concern on board specific functionality, but it is quite extendable to other 485/232 combination boards as well. I sure hope it makes it into the kernel at some point, but if not I'll continue hand patching away :)
Quoted 1 line
Caleb: I appreciate the effort, thanks.
Not a problem - it was a fun way to spend a day upgrading to 2.4. In fact, the serial driver was the only snag I ran into during the upgrade process.
Signature · 4 lines
Caleb Tennis Analytical Engineering 2555 Technology Blvd Columbus, IN 47201
From: "Caleb Tennis" <[email protected]>
Quoted 2 lines
I'm quite pleased at the support ConnectTech has for this product. We are planning on purchasing more in the future.
Thank you.
Quoted 1 line
progression), and thought it may be valuable to submit a patch related to
the
Quoted 1 line
latest kernel.
Again, thanks.
Quoted 1 line
There really isn't a good way around this patch - I understand Ted's
concern
Quoted 1 line
on board specific functionality, but it is quite extendable to other
485/232
Quoted 1 line
combination boards as well. I sure hope it makes it into the kernel at
some
Quoted 1 line
point, but if not I'll continue hand patching away :)
My first version of the patch was not as well designed as the current one; I reworked it a fair bit to make it extensible and keep the CTi-specific code strictly confined to a few subroutines. I'm hoping it makes it in too.
Hopefully we'll hear from Ted shortly.
..Stu