New serial card development
Hello, my name is Matt and I have recently developed a PCIe card based on the Exar 17v35x series of PCIe multiport UART chips.
We have written Linux drivers for our other products in the past but they have never been what I would call the best practice for Linux development.
This time I would like to write a driver that uses the best practices and possibly submit it to the kernel when I'm done.
I am a little bit confused about what method would be best for this
device. I have been examining the sample driver provided by Exar
and it seems that the only things that they have that are really different from the generic 8250 serial driver are the interrupt handler (optimized for their multiple ports), the transmit and receive character functions (modified to use their 256 byte FIFOs) and the function that calculates the baud. Also I have two features specific to my card that I would likely need to use an ioctl for.
If these are the only differences would I be able to create a driver like what is seen in the /drivers/tty/serial/8250 directory (8250_dw.c for example)? Or would I need to do something similar to what I find in the /drviers/tty/serial directory?
Thank you for your time.
Matt Schulte
Quoted 10 lines · Matt Schulte
Hello, my name is Matt and I have recently developed a PCIe card based on the Exar 17v35x series of PCIe multiport UART chips.
We have written Linux drivers for our other products in the past but they have never been what I would call the best practice for Linux development.
This time I would like to write a driver that uses the best practices and possibly submit it to the kernel when I'm done.
Quoted 8 lines
I am a little bit confused about what method would be best for this
device. I have been examining the sample driver provided by Exar
and it seems that the only things that they have that are really different from the generic 8250 serial driver are the interrupt handler (optimized for their multiple ports), the transmit and receive character functions (modified to use their 256 byte FIFOs) and the function that calculates the baud. Also I have two features specific to my card that I would likely need to use an ioctl for.
Hi Matt,
It's been a while since I've done serial development (probably close to a decade ago), but way back when I was responsible for most of the code which is now in drivers/tty/serial/8250/serial.c, I had added support for the Exar 16C850 UART; since then someone else has added support for the Exar XR17D15x UART.
The EXAR 16C850 had a 128 byte FIFO; it sounds like this EXAR variant is similar to the 16C850, although it's been further extended.
Quoted 4 lines
If these are the only differences would I be able to create a driver like what is seen in the /drivers/tty/serial/8250 directory (
8250_dw.cfor example)? Or would I need to do something similar to what I find in the /drviers/tty/serial directory?
We support a very large number of 8250-like UART's already. It doesn't make sense create a new driver which is essentially a clone of the 8250.c driver. Instead, the 8250.c driver should be extended to support this new Exar UART variant. The preferred way to do this is to detect the EXAR UART directly, via the method documented in the EXAR data sheet, instead of using the PCI id numbers to make this determination. This way, we will be able to support that UART on other PCI serial cards, and not just yours.
If you have some features which are explicitly specific to your card, and which are not specific to the UART, then that may need to be separately triggered via the PCI vendor/device id numbers. What feature is it, by the way? If it has to do with controlling the clock crystal, there's infrastructure to deal with this already that you may be able to leverage.
Regards,
- Ted
Quoted 37 lines · Theodore Ts'o
Quoted 10 lines · Matt Schulte
Hello, my name is Matt and I have recently developed a PCIe card based on the Exar 17v35x series of PCIe multiport UART chips.
We have written Linux drivers for our other products in the past but they have never been what I would call the best practice for Linux development.
This time I would like to write a driver that uses the best practices and possibly submit it to the kernel when I'm done.
Quoted 8 lines
I am a little bit confused about what method would be best for this
device. I have been examining the sample driver provided by Exar
and it seems that the only things that they have that are really different from the generic 8250 serial driver are the interrupt handler (optimized for their multiple ports), the transmit and receive character functions (modified to use their 256 byte FIFOs) and the function that calculates the baud. Also I have two features specific to my card that I would likely need to use an ioctl for.Hi Matt,
It's been a while since I've done serial development (probably close to a decade ago), but way back when I was responsible for most of the code which is now in
drivers/tty/serial/8250/serial.c, I had added support for the Exar 16C850 UART; since then someone else has added support for the Exar XR17D15x UART.The EXAR 16C850 had a 128 byte FIFO; it sounds like this EXAR variant is similar to the 16C850, although it's been further extended.
Quoted 4 lines
If these are the only differences would I be able to create a driver like what is seen in the /drivers/tty/serial/8250 directory (
8250_dw.cfor example)? Or would I need to do something similar to what I find in the /drviers/tty/serial directory?
Quoted 8 lines
We support a very large number of 8250-like UART's already. It doesn't make sense create a new driver which is essentially a clone of the 8250.c driver. Instead, the 8250.c driver should be extended to support this new Exar UART variant. The preferred way to do this is to detect the EXAR UART directly, via the method documented in the EXAR data sheet, instead of using the PCI id numbers to make this determination. This way, we will be able to support that UART on other PCI serial cards, and not just yours.
That sounds reasonable but I am not sure what you mean my the "method documented in the Exar data sheet." I've been through this thing quite a bit and I don't see anything about how one might detect the ports without the PCI id numbers. Could you explain what you mean by this?
Quoted 8 lines
If you have some features which are explicitly specific to your card, and which are not specific to the UART, then that may need to be separately triggered via the PCI vendor/device id numbers. What feature is it, by the way? If it has to do with controlling the clock crystal, there's infrastructure to deal with this already that you may be able to leverage.
* This new Exar UART does not use a crystal it uses a clock from the PCI Express bus. Also it has a fractional divisor that gets them 1/16th (0.0625) resolution on their divisors. The normal DLL and DLM registers contain the integer part of the divisor and the DLD register provides the fractional component. The divisor is able to be set to anything between 1 and (2^16 - 0.0625) in increments of 0.0625.
* These UARTs have 256 byte FIFOs per port per direction. I would like to utilize these to their fullest potential.
* I need to toggle 16-bit general purpose IO signals to control two things on my card: Receive Echo Cancel (useful for 2-wire 485) and the selectable termination resistance on my receiver chips.
* I need to change two UART specific registers to change the sampling mode (16x, 8x and 4x).
* I need to figure out if the new RS485 elements that have been added to 8250 can be used on these Exar parts and if not I need something that can enable RS485 for us.
* I need to be able to enable 9-bit mode, what they call Normal Multi-drop as well as the Auto Address Detection Mode used in conjunction with the Multi-drop mode.
* There is an interruptible hardware timer/counter that I might like to utilize at some point.
With this laundry list of items that I would like to include, do you still feel like this is something that should be included in the kernel's 8250.c/8250_pci.c drivers?
Thanks for helping me think this through.
Matt
Quoted 5 lines
That sounds reasonable but I am not sure what you mean my the "method documented in the Exar data sheet." I've been through this thing quite a bit and I don't see anything about how one might detect the ports without the PCI id numbers. Could you explain what you mean by this?
I don't believe you can identify the new Exars except by PCI id - which is fine as the type can be passed via the 8250_pci driver.
Quoted 6 lines
* This new Exar UART does not use a crystal it uses a clock from the PCI Express bus. Also it has a fractional divisor that gets them 1/16th (0.0625) resolution on their divisors. The normal DLL and DLM registers contain the integer part of the divisor and the DLD register provides the fractional component. The divisor is able to be set to anything between 1 and (2^16 - 0.0625) in increments of 0.0625.
That probably needs a bit of tweaking to getthe best results
Quoted 2 lines
* These UARTs have 256 byte FIFOs per port per direction. I would like to utilize these to their fullest potential.
We already handle other similar fifos so again in theory you just need to set the size and it works.
Quoted 3 lines
* I need to toggle 16-bit general purpose IO signals to control two things on my card: Receive Echo Cancel (useful for 2-wire 485) and the selectable termination resistance on my receiver chips.
Ok - we don't have a generalized way of doing that in the RS485 bits but anything liek this should get added generically (in case other chips want to do it)
Quoted 2 lines
* I need to change two UART specific registers to change the sampling mode (16x, 8x and 4x).
What determines this.
Quoted 3 lines
* I need to figure out if the new RS485 elements that have been added to 8250 can be used on these Exar parts and if not I need something that can enable RS485 for us.
They should provide the basics.
Quoted 3 lines
* I need to be able to enable 9-bit mode, what they call Normal Multi-drop as well as the Auto Address Detection Mode used in conjunction with the Multi-drop mode.
That may actually be the most "fun" bit - the entire Linux tty layer is devoutly 5-8bit, although people do some horrible hacks with "8 plus parity".
Quoted 3 lines
With this laundry list of items that I would like to include, do you still feel like this is something that should be included in the kernel's
8250.c/8250_pci.cdrivers?
I think so. It's also the path that lets you do basic enabling, get it working upstream and then extend as is needed for the other features.
The one area 8250 really can't hack properly is DMA driven 8250 devices.
Alan
Quoted 8 lines · Alan Cox
Quoted 5 lines
That sounds reasonable but I am not sure what you mean my the "method documented in the Exar data sheet." I've been through this thing quite a bit and I don't see anything about how one might detect the ports without the PCI id numbers. Could you explain what you mean by this?
I don't believe you can identify the new Exars except by PCI id - which is fine as the type can be passed via the 8250_pci driver.
Yeah, I just checked out the data sheet, and it looks like there isn't a way to do this. That's unfortunate, since board vendors can change the PCI vendor and device ID. So if they reprogram the EEPROM to use their own id numbers, we won't be able to support that new board without modifying the kernel source. This is why I had tried to implement ways where if the PCI class indicated a 16550 compatible port, we would try to probe the UART registers to figure out exactly what type of advanced features beyond those supported by the standard 16550A UART. Sigh, it looks like we won't be able to do things that way.
Quoted 4 lines
Quoted 2 lines
* I need to change two UART specific registers to change the sampling mode (16x, 8x and 4x).
What determines this.
We have support for things like this already; see serial8250_get_divisor and UPF_MAGIC_MULTIPLIER. In general you only want to change the sampling mode when you need it (i.e, for the high speed baud rates).
Quoted 9 lines
They should provide the basics.
Quoted 3 lines
* I need to be able to enable 9-bit mode, what they call Normal Multi-drop as well as the Auto Address Detection Mode used in conjunction with the Multi-drop mode.
That may actually be the most "fun" bit - the entire Linux tty layer is devoutly 5-8bit, although people do some horrible hacks with "8 plus parity".
That's what is actually recommended by the Exar application note; since setting the 9th bit is only used for indicating that the lower 8 bits is the "address" bit for demultiplexing destination "drop", you don't need to do it very often compared to the data bytes. So toggling the parity bit is the best way to deal with the fact you can only use outb to send 8 bits.
- Ted
Quoted 10 lines · Theodore Ts'o
Quoted 8 lines · Alan Cox
Quoted 5 lines
That sounds reasonable but I am not sure what you mean my the "method documented in the Exar data sheet." I've been through this thing quite a bit and I don't see anything about how one might detect the ports without the PCI id numbers. Could you explain what you mean by this?
I don't believe you can identify the new Exars except by PCI id - which is fine as the type can be passed via the 8250_pci driver.
Quoted 10 lines
Yeah, I just checked out the data sheet, and it looks like there isn't a way to do this. That's unfortunate, since board vendors can change the PCI vendor and device ID. So if they reprogram the EEPROM to use their own id numbers, we won't be able to support that new board without modifying the kernel source. This is why I had tried to implement ways where if the PCI class indicated a 16550 compatible port, we would try to probe the UART registers to figure out exactly what type of advanced features beyond those supported by the standard 16550A UART. Sigh, it looks like we won't be able to do things that way.
Which is exactly what I do to the device id :)
Quoted 9 lines
Quoted 4 lines
Quoted 2 lines
* I need to change two UART specific registers to change the sampling mode (16x, 8x and 4x).
What determines this.
We have support for things like this already; see
serial8250_get_divisorandUPF_MAGIC_MULTIPLIER. In general you only want to change the sampling mode when you need it (i.e, for the high speed baud rates).
I'm not sure the UPF_MAGIC_MULTIPLIER is the same as the sampling rate that I'm looking for, though I might be able to come up with a way to hijack the flag to do what I want.
Quoted 10 lines
Quoted 9 lines
They should provide the basics.
Quoted 3 lines
* I need to be able to enable 9-bit mode, what they call Normal Multi-drop as well as the Auto Address Detection Mode used in conjunction with the Multi-drop mode.
That may actually be the most "fun" bit - the entire Linux tty layer is devoutly 5-8bit, although people do some horrible hacks with "8 plus parity".
Quoted 6 lines
That's what is actually recommended by the Exar application note; since setting the 9th bit is only used for indicating that the lower 8 bits is the "address" bit for demultiplexing destination "drop", you don't need to do it very often compared to the data bytes. So toggling the parity bit is the best way to deal with the fact you can only use outb to send 8 bits.
What I would need to have happen is for a flag to be set that says "enable 9-bit mode transmit" or something. When set, the first byte of data of a given write will go out with mark parity, then the rest of the bytes will have space parity. The one byte with mark is the address byte.
In the receive direction I would need to optionally enable a station address which the chip will use to verify all incoming data and will reject anything that is not of the appropriate address.
Matt Schulte
Quoted 6 lines · Matt Schulte
What I would need to have happen is for a flag to be set that says "enable 9-bit mode transmit" or something. When set, the first byte of data of a given write will go out with mark parity, then the rest of the bytes will have space parity. The one byte with mark is the address byte.
Why not just have a userspace library routine which simply uses tcgetattr/tcsetattr to toggle a bit (probably a new bit in c_cflag) in struct termios, issue the single byte write, and then toggle the bit back?
If you really want to implement a special case "the first byte should treated differently from the rest", that gets problemtic for a number of reasons. First of all, it's just a lot more kernel code; you'd probably need to implement a new line displine, and secondly, if userspace sends too much data so that it can't fit in the kernel buffer, you might get a partial write. In which case, when you send a second write call to send the rest of the data, you'd have to go through extra work to make sure the first byte of that second, follow-up byte doesn't have the high 9th bit set.
Of course, you could hack in even more changes to make the write system call behave entirely differently in your magic "9th bit mode", where the write system call becomes a "all or nothing" sort of thing, but that's even more evil hackery that almost certainly would be rejected with extreme prejudice by the kernel maintainers.
In Linux, system calls are fast, so using some extra ioctl's to toggle the termios structure is probably the way to go. It's also much more general since it doesn't presume a very specific protocol (i.e., your magic multi-drop protocol).
Quoted 3 lines
In the receive direction I would need to optionally enable a station address which the chip will use to verify all incoming data and will reject anything that is not of the appropriate address.
For the receive direction, my suggestion is to encode it as an extension for how PARMRK does things, and then leave the parsing of the address bits to userspace. Otherwise you'll end up needing to make the kernel know what are "appropriate" addresses, which again is a lot of very protocol specific knowledge that you would have to push into the kernel.
Alan's advice to get your card working as a basic serial card is very good one. Get basic functionality working, and then you can add the support for the extra bits later....
- Ted
Quoted 13 lines · Theodore Ts'o
Quoted 6 lines · Matt Schulte
What I would need to have happen is for a flag to be set that says "enable 9-bit mode transmit" or something. When set, the first byte of data of a given write will go out with mark parity, then the rest of the bytes will have space parity. The one byte with mark is the address byte.
Why not just have a userspace library routine which simply uses tcgetattr/tcsetattr to toggle a bit (probably a new bit in
c_cflag) in struct termios, issue the single byte write, and then toggle the bit back?
Quoted 4 lines
In Linux, system calls are fast, so using some extra ioctl's to toggle the termios structure is probably the way to go. It's also much more general since it doesn't presume a very specific protocol (i.e., your magic multi-drop protocol).
The only reason that I could come up with as to why not to do that is the probably delay between the first byte and the second byte. Perhaps the system calls will be so quick that this delay won't be an issue. Other than that I think that a new bit in c_cflag would be a pretty decent solution.
Also this isn't a magic protocol, it is a very old protocol that is apparently still in use today because I have several customers still asking for it.
Quoted 10 lines
Quoted 3 lines
In the receive direction I would need to optionally enable a station address which the chip will use to verify all incoming data and will reject anything that is not of the appropriate address.
For the receive direction, my suggestion is to encode it as an extension for how PARMRK does things, and then leave the parsing of the address bits to userspace. Otherwise you'll end up needing to make the kernel know what are "appropriate" addresses, which again is a lot of very protocol specific knowledge that you would have to push into the kernel.
The address is something that is decided by the user, it could literally be anything. All I need is a way to write a byte to the appropriate UART register and a bit to turn it on and off.
Quoted 3 lines
Alan's advice to get your card working as a basic serial card is very good one. Get basic functionality working, and then you can add the support for the extra bits later....
I can see the logic in getting it working as a basic serial card first. I think at minimum I would still need to implement the extra divisor calculations to get accurate bit rates.
So when it works as a basic serial card, I assume you would want me to use the default PCI IDs to keep it more generic. Then would I add my own PCI IDs and refer them back to the generic port?
Matt
Quoted 5 lines · Matt Schulte
Quoted 3 lines · Theodore Ts'o
Alan's advice to get your card working as a basic serial card is very good one. Get basic functionality working, and then you can add the support for the extra bits later....
Quoted 8 lines
I can see the logic in getting it working as a basic serial card first. I think at minimum I would still need to implement the extra divisor calculations to get accurate bit rates.
So when it works as a basic serial card, I assume you would want me to use the default PCI IDs to keep it more generic. Then would I add my own PCI IDs and refer them back to the generic port?
As more of a procedural question, when I go to make the patch(es) to submit which, kernel repo do I start with? Do I start with Greg KH's tty repo and then generate the patches and submit them here?
Matt
Quoted 11 lines · Matt Schulte
Quoted 9 lines · Matt Schulte
Quoted 3 lines · Theodore Ts'o
Alan's advice to get your card working as a basic serial card is very good one. Get basic functionality working, and then you can add the support for the extra bits later....
I can see the logic in getting it working as a basic serial card first. I think at minimum I would still need to implement the extra divisor calculations to get accurate bit rates.
Quoted 8 lines
Quoted 4 lines
So when it works as a basic serial card, I assume you would want me to use the default PCI IDs to keep it more generic. Then would I add my own PCI IDs and refer them back to the generic port?
As more of a procedural question, when I go to make the patch(es) to submit which, kernel repo do I start with? Do I start with Greg KH's tty repo and then generate the patches and submit them here?
That would be a great place to work off of, use the tty-next branch please.
thanks,
greg k-h
Quoted 8 lines · Greg KH
Quoted 7 lines · Matt Schulte
Quoted 5 lines · Matt Schulte
Quoted 3 lines · Theodore Ts'o
Alan's advice to get your card working as a basic serial card is very good one. Get basic functionality working, and then you can add the support for the extra bits later....
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
I can see the logic in getting it working as a basic serial card first. I think at minimum I would still need to implement the extra divisor calculations to get accurate bit rates.
So when it works as a basic serial card, I assume you would want me to use the default PCI IDs to keep it more generic. Then would I add my own PCI IDs and refer them back to the generic port?
I am working to get the Exar devices added to the 8250 driver. I think I get most of what I need to make happen until I get to the detection of the EFR register. Can someone explain to me what is going on here and where the Exar device is supposed to end up? It seems to me that I would expect them to show up somewhere around :
/*
* Exar uarts have EFR in a weird location
*/
But instead I am getting my UARTs detected as EFRv1, iir=3 and marked as type=ST16650.
For reference the Exar chips have EFR located at an address of 1001 (UART_XR_EFR). There isn't anything special that has to be done to access this location, just look at 1001.
Matt Schulte
Quoted 28 lines · Matt Schulte
Quoted 8 lines · Greg KH
Quoted 7 lines · Matt Schulte
Quoted 5 lines · Matt Schulte
Quoted 3 lines · Theodore Ts'o
Alan's advice to get your card working as a basic serial card is very good one. Get basic functionality working, and then you can add the support for the extra bits later....
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
I can see the logic in getting it working as a basic serial card first. I think at minimum I would still need to implement the extra divisor calculations to get accurate bit rates.
So when it works as a basic serial card, I assume you would want me to use the default PCI IDs to keep it more generic. Then would I add my own PCI IDs and refer them back to the generic port?
I am working to get the Exar devices added to the 8250 driver. I think I get most of what I need to make happen until I get to the detection of the EFR register. Can someone explain to me what is going on here and where the Exar device is supposed to end up? It seems to me that I would expect them to show up somewhere around :
/*
* Exar uarts have EFR in a weird location
*/
Quoted 6 lines
But instead I am getting my UARTs detected as EFRv1, iir=3 and marked as type=ST16650.
For reference the Exar chips have EFR located at an address of 1001 (
UART_XR_EFR). There isn't anything special that has to be done to access this location, just look at 1001.
I was able to work my way through the funky EFR detection. Hopefully you guys will like what I did when you see the patch.
Next I need to know the channel number of a given UART port. If I have a 4 port UART I need to know that a given channel is 0,1,2 or 3. If I have an 8 port UART I need to know if a given channel is 0,1,2,3,4,5,6 or 7.
The only way that I can find to get this number is using the idx variable that is passed to the port's .setup operation. Would I be able to add a member to the uart_port structure so that I could store this number inside my UARTs setup function?
Something like:
struct uart_port {
.
.
.
unsigned int channel;
};
pci_myuart_setup(struct serial_private *priv,
const struct pciserial_board *board, struct uart_8250_port *port, int idx)
{
...
port->port.channel = idx;
return pci_default_setup(priv, board, port, idx);
}Thank you,
Matt Schulte
Quoted 11 lines · Matt Schulte
Quoted 9 lines · Matt Schulte
Quoted 8 lines · Greg KH
Quoted 7 lines · Matt Schulte
Quoted 5 lines · Matt Schulte
Quoted 3 lines · Theodore Ts'o
Alan's advice to get your card working as a basic serial card is very good one. Get basic functionality working, and then you can add the support for the extra bits later....
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
I can see the logic in getting it working as a basic serial card first. I think at minimum I would still need to implement the extra divisor calculations to get accurate bit rates.
So when it works as a basic serial card, I assume you would want me to use the default PCI IDs to keep it more generic. Then would I add my own PCI IDs and refer them back to the generic port?
Hello, the next question that I have is how to handle the interrupts on this UART. It has a more complex interrupt scheme than a traditional 8250 UART. There is a global ISR register that tells you which port had the interrupt and then there is another set of registers that hold the actual interrupts.
In this situation where this UART needs extra code for the handling of its interrupt, where is the best place to add this special interrupt handler? Directly to the 8250.c default handler or somewhere else?
Thank you,
Matt Schulte
Quoted 5 lines
Hello, the next question that I have is how to handle the interrupts on this UART. It has a more complex interrupt scheme than a traditional 8250 UART. There is a global ISR register that tells you which port had the interrupt and then there is another set of registers that hold the actual interrupts.
port->handle_irq is half of what you need, but you probably need to be able to hook serial8250_interruot and provide your own alternative. Given you don't need the irq chain handling either probably the bit that wants to be hookable is the calls to serial_link_irq_chain and serial_unlink_irq_chain in the startup/shutdown methods.
In yor case all that and all the irq scanning the chain becomes a simple read of the port and call of the handlers (serial8250_handlee_irq(port, iir)
Alan
Quoted 12 lines · Alan Cox
Quoted 5 lines
Hello, the next question that I have is how to handle the interrupts on this UART. It has a more complex interrupt scheme than a traditional 8250 UART. There is a global ISR register that tells you which port had the interrupt and then there is another set of registers that hold the actual interrupts.
port->handle_irqis half of what you need, but you probably need to be able to hookserial8250_interruotand provide your own alternative. Given you don't need the irq chain handling either probably the bit that wants to be hookable is the calls toserial_link_irq_chainandserial_unlink_irq_chainin the startup/shutdown methods.
Quoted 3 lines
In yor case all that and all the irq scanning the chain becomes a simple read of the port and call of the handlers (
serial8250_handlee_irq(port, iir)
To be clear, I shouldn't put a custom irq handler inside 8250.c, correct?
I would want to do something along the vein of 8250_dw.c with a custom probe and a custome handle_irq?
Matt Schulte
Quoted 13 lines · On Fri, 2 Nov 2012 13:47:25 -0500 Matt Schulte <[email protected]>…
Quoted 12 lines · Alan Cox
Quoted 5 lines
Hello, the next question that I have is how to handle the interrupts on this UART. It has a more complex interrupt scheme than a traditional 8250 UART. There is a global ISR register that tells you which port had the interrupt and then there is another set of registers that hold the actual interrupts.
port->handle_irqis half of what you need, but you probably need to be able to hookserial8250_interruotand provide your own alternative. Given you don't need the irq chain handling either probably the bit that wants to be hookable is the calls toserial_link_irq_chainandserial_unlink_irq_chainin the startup/shutdown methods.
Quoted 8 lines
Quoted 3 lines
In yor case all that and all the irq scanning the chain becomes a simple read of the port and call of the handlers (
serial8250_handlee_irq(port, iir)To be clear, I shouldn't put a custom irq handler inside 8250.c, correct?
I would want to do something along the vein of
8250_dw.cwith a custom probe and a customehandle_irq?
That's my first guess - there is an awful lot of stuff you simply don't need in this situation.
Quoted 9 lines · Matt Schulte
Quoted 7 lines · Theodore Ts'o
Quoted 6 lines · Matt Schulte
What I would need to have happen is for a flag to be set that says "enable 9-bit mode transmit" or something. When set, the first byte of data of a given write will go out with mark parity, then the rest of the bytes will have space parity. The one byte with mark is the address byte.
Quoted 4 lines
Quoted 4 lines
Why not just have a userspace library routine which simply uses tcgetattr/tcsetattr to toggle a bit (probably a new bit in
c_cflag) in struct termios, issue the single byte write, and then toggle the bit back?
Can it be guaranteed that it's going to be fast enough at high baud-rates to prevent any gap between the first byte and subsequent bytes?
Quoted 8 lines
Quoted 4 lines
In Linux, system calls are fast, so using some extra ioctl's to toggle the termios structure is probably the way to go. It's also much more general since it doesn't presume a very specific protocol (i.e., your magic multi-drop protocol).
Also this isn't a magic protocol, it is a very old protocol that is apparently still in use today because I have several customers still asking for it.
It's been pretty much a standard in the microctroller world for a _long_ time. I remember 9-bit HW support with special interrupt on the "address" byte from almost 30 years ago: when I first worked with the Intel 8051 in 1983, it had 9-bit support in it's UART (and we used it).
I now work for a company that has manufactured PC serial boards for 25+ years, and we still get regular requests for that feature (and our boards do support it -- though our Linux driver does not).
Signature · 3 lines
Grant Edwards grant.b.edwards Yow! I guess you guys got
at BIG MUSCLES from doing too
gmail.com much STUDYING!Quoted 3 lines
Can it be guaranteed that it's going to be fast enough at high baud-rates to prevent any gap between the first byte and subsequent bytes?
Possibly not for some protocols (or worse yet 'almost always' for some protocols).
It's something to look at once the basic bits are in.
Quoted 3 lines
I now work for a company that has manufactured PC serial boards for 25+ years, and we still get regular requests for that feature (and our boards do support it -- though our Linux driver does not).
In which case when we get to addressing this it will be good to make sure we cover your needs as well.
Alan
Quoted 7 lines · Alan Cox
Quoted 3 lines
Can it be guaranteed that it's going to be fast enough at high baud-rates to prevent any gap between the first byte and subsequent bytes?
Possibly not for some protocols (or worse yet 'almost always' for some protocols).
Quoted 8 lines
It's something to look at once the basic bits are in.
Quoted 3 lines
I now work for a company that has manufactured PC serial boards for 25+ years, and we still get regular requests for that feature (and our boards do support it -- though our Linux driver does not).
In which case when we get to addressing this it will be good to make sure we cover your needs as well.
FWIW, in some products we're planning that will require support for various industrial serial protocols, I'm leaning towards abandoning the tty driver approach and writing a stand-alone character device driver. The byte-stream oriented tty/line-discipline layer just doesn't fit well when dealing with frame-oriented industrial protocols that depend on things like 9th bit addressing and detecting sub-millisecond inter-byte timeouts. When I add in the lack of long-term stability in the tty API it seems like it might not be such a bad idea to give up trying to make the tty abstraction fit a use case that's just nothing like a teletype.
Signature · 3 lines
Grant Edwards grant.b.edwards Yow! Gibble, Gobble, we
at ACCEPT YOU ...
gmail.com Quoted 17 lines · Grant Edwards
Quoted 7 lines · Alan Cox
Quoted 3 lines
Can it be guaranteed that it's going to be fast enough at high baud-rates to prevent any gap between the first byte and subsequent bytes?
Possibly not for some protocols (or worse yet 'almost always' for some protocols).
Quoted 8 lines
It's something to look at once the basic bits are in.
Quoted 3 lines
I now work for a company that has manufactured PC serial boards for 25+ years, and we still get regular requests for that feature (and our boards do support it -- though our Linux driver does not).
In which case when we get to addressing this it will be good to make sure we cover your needs as well.
Quoted 10 lines
FWIW, in some products we're planning that will require support for various industrial serial protocols, I'm leaning towards abandoning the tty driver approach and writing a stand-alone character device driver. The byte-stream oriented tty/line-discipline layer just doesn't fit well when dealing with frame-oriented industrial protocols that depend on things like 9th bit addressing and detecting sub-millisecond inter-byte timeouts. When I add in the lack of long-term stability in the tty API it seems like it might not be such a bad idea to give up trying to make the tty abstraction fit a use case that's just nothing like a teletype.
What do you mean "lack of long-term stability"? The userspace tty api hasn't ever changed or broken. Don't focus on in-kernel api, that's always going to change, no matter what interface you choose to use in the kernel.
Just get your drivers merged into the tree and you will not have to worry about it.
thanks,
greg k-h
Quoted 13 lines · Greg KH
Quoted 10 lines · Grant Edwards
FWIW, in some products we're planning that will require support for various industrial serial protocols, I'm leaning towards abandoning the tty driver approach and writing a stand-alone character device driver. The byte-stream oriented tty/line-discipline layer just doesn't fit well when dealing with frame-oriented industrial protocols that depend on things like 9th bit addressing and detecting sub-millisecond inter-byte timeouts. When I add in the lack of long-term stability in the tty API it seems like it might not be such a bad idea to give up trying to make the tty abstraction fit a use case that's just nothing like a teletype.
Quoted 2 lines
What do you mean "lack of long-term stability"? The userspace tty api hasn't ever changed or broken.
I meant the in-kernel api.
Quoted 1 line
Don't focus on in-kernel api,
It's my job to focus on the in-kernel api.
Quoted 2 lines
that's always going to change, no matter what interface you choose to use in the kernel.
Maybe it's just my perception, but the the tty API seems to change a more than the plain character-device API.
Signature · 3 lines
Grant Edwards grant.b.edwards Yow! I wish I was on a
at Cincinnati street corner
gmail.com holding a clean dog!Quoted 14 lines · Grant Edwards
Quoted 13 lines · Greg KH
Quoted 10 lines · Grant Edwards
FWIW, in some products we're planning that will require support for various industrial serial protocols, I'm leaning towards abandoning the tty driver approach and writing a stand-alone character device driver. The byte-stream oriented tty/line-discipline layer just doesn't fit well when dealing with frame-oriented industrial protocols that depend on things like 9th bit addressing and detecting sub-millisecond inter-byte timeouts. When I add in the lack of long-term stability in the tty API it seems like it might not be such a bad idea to give up trying to make the tty abstraction fit a use case that's just nothing like a teletype.
Quoted 8 lines
Quoted 2 lines
What do you mean "lack of long-term stability"? The userspace tty api hasn't ever changed or broken.
I meant the in-kernel api.
Quoted 1 line
Don't focus on in-kernel api,
It's my job to focus on the in-kernel api.
It's my job to ensure that you don't have to. Why are you caring? Are you trying to keep drivers outside of the kernel tree? If so, there's nothing we can do, except point out what a bad idea that really is to try to do.
Quoted 5 lines
Quoted 2 lines
that's always going to change, no matter what interface you choose to use in the kernel.
Maybe it's just my perception, but the the tty API seems to change a more than the plain character-device API.
Recently, yes. But, once that churn is over, it should settle down.
Oh, and watch out, the "plain" character-device api is going to change in the next year or so, I've been working on lots of fixups in that area, and hope to publish something in a month or so if I get it cleaned up.
My point is, all of the kernel changes, all the time, so don't use the lack of change, or the rate of change, for a specific api, as any indication that it will not change again in the future, possibly in very drastic ways.
thanks,
greg k-h
Quoted 10 lines
FWIW, in some products we're planning that will require support for various industrial serial protocols, I'm leaning towards abandoning the tty driver approach and writing a stand-alone character device driver. The byte-stream oriented tty/line-discipline layer just doesn't fit well when dealing with frame-oriented industrial protocols that depend on things like 9th bit addressing and detecting sub-millisecond inter-byte timeouts. When I add in the lack of long-term stability in the tty API it seems like it might not be such a bad idea to give up trying to make the tty abstraction fit a use case that's just nothing like a teletype.
Not unreasonable but we do need to cover it to some extent because there are a lot of 'multi-use' port types where you need to share the hardware or switch modes.
Although we don't use it that way its not entirely accidental that the tty buffer code supports chains of buffers with lengths 8)
Alan
Quoted 11 lines · Alan Cox
Quoted 10 lines
FWIW, in some products we're planning that will require support for various industrial serial protocols, I'm leaning towards abandoning the tty driver approach and writing a stand-alone character device driver. The byte-stream oriented tty/line-discipline layer just doesn't fit well when dealing with frame-oriented industrial protocols that depend on things like 9th bit addressing and detecting sub-millisecond inter-byte timeouts. When I add in the lack of long-term stability in the tty API it seems like it might not be such a bad idea to give up trying to make the tty abstraction fit a use case that's just nothing like a teletype.
Quoted 3 lines
Not unreasonable but we do need to cover it to some extent because there are a lot of 'multi-use' port types where you need to share the hardware or switch modes.
Agreed. Providing support for things like 9 bit mode, inter-byte timeouts, arbitrary baud rates, half-duplex mode, and user-selectable electrical interfaces (232/422/485/etc.) in the standard tty API would be a good thing. Half-duplex mode (sometimes called RS485 mode) and arbitrary baud rate are great recent additions.
Quoted 2 lines
Although we don't use it that way its not entirely accidental that the tty buffer code supports chains of buffers with lengths 8)
Thanks, that's good to know.
Signature · 4 lines
Grant Edwards grant.b.edwards Yow! I can't decide which
at WRONG TURN to make first!!
gmail.com I wonder if BOB GUCCIONE
has these problems!Quoted 7 lines · Grant Edwards
FWIW, in some products we're planning that will require support for various industrial serial protocols, I'm leaning towards abandoning the tty driver approach and writing a stand-alone character device driver. The byte-stream oriented tty/line-discipline layer just doesn't fit well when dealing with frame-oriented industrial protocols that depend on things like 9th bit addressing and detecting sub-millisecond inter-byte timeouts.
You might want to take a look at how the ppp line discipline (which is obviously highly packet oriented) works. One advantage of doing things that way is if you have a multiport serial card, where some ports want to play this packet-oriented approach, and other cards might be connected to a traditional modem or terminal sort of device, you won't have to figure out how to share a PCI board between two different drivers, allocating one port to the traditional tty/serial driver, and another one to your new driver, etc.
Regards,
- Ted
Quoted 10 lines · Theodore Ts'o
Quoted 7 lines · Grant Edwards
FWIW, in some products we're planning that will require support for various industrial serial protocols, I'm leaning towards abandoning the tty driver approach and writing a stand-alone character device driver. The byte-stream oriented tty/line-discipline layer just doesn't fit well when dealing with frame-oriented industrial protocols that depend on things like 9th bit addressing and detecting sub-millisecond inter-byte timeouts.
Quoted 8 lines
You might want to take a look at how the ppp line discipline (which is obviously highly packet oriented) works. One advantage of doing things that way is if you have a multiport serial card, where some ports want to play this packet-oriented approach, and other cards might be connected to a traditional modem or terminal sort of device, you won't have to figure out how to share a PCI board between two different drivers, allocating one port to the traditional tty/serial driver, and another one to your new driver, etc.
Thanks for the suggestion. I did look into line-disciplines briefly quite a while back. Most of the information I found implied that adding a line disciplilne wasn't something you could do at run-time by loading a user-built module -- it would require recompiling parts of the kernel. Articles made statements about having to modify kernel include files like tty.h. If that's wrong, then a line discipline might be a good option.
Signature · 4 lines
Grant Edwards grant.b.edwards Yow! I'm having a
at quadrophonic sensation
gmail.com of two winos alone in a
steel mill!A message that is not in the archive (sent off-list or not yet received): CAJp1Oe6k7NWqdbYkJnd787JiT55-wSbG+tX1tP7Cy-oPShdVaA@mail.gmail.com
Forgot to reply to all.
---------- Forwarded message ----------
From: Matt Schulte <[email protected]>
Date: Wed, Oct 17, 2012 at 2:10 PM
Subject: Re: New serial card development
To: Alan Cox <[email protected]>
Quoted 9 lines · Alan Cox
Quoted 5 lines
That sounds reasonable but I am not sure what you mean my the "method documented in the Exar data sheet." I've been through this thing quite a bit and I don't see anything about how one might detect the ports without the PCI id numbers. Could you explain what you mean by this?
I don't believe you can identify the new Exars except by PCI id - which is fine as the type can be passed via the 8250_pci driver.
Quoted 8 lines
Quoted 6 lines
* This new Exar UART does not use a crystal it uses a clock from the PCI Express bus. Also it has a fractional divisor that gets them 1/16th (0.0625) resolution on their divisors. The normal DLL and DLM registers contain the integer part of the divisor and the DLD register provides the fractional component. The divisor is able to be set to anything between 1 and (2^16 - 0.0625) in increments of 0.0625.
That probably needs a bit of tweaking to getthe best results
Does this make you lean one way or the other in how I would best implement this driver?
Quoted 5 lines
Quoted 2 lines
* These UARTs have 256 byte FIFOs per port per direction. I would like to utilize these to their fullest potential.
We already handle other similar fifos so again in theory you just need to set the size and it works.
Good, I'm sure it will be fine ;)
Quoted 7 lines
Quoted 3 lines
* I need to toggle 16-bit general purpose IO signals to control two things on my card: Receive Echo Cancel (useful for 2-wire 485) and the selectable termination resistance on my receiver chips.
Ok - we don't have a generalized way of doing that in the RS485 bits but anything liek this should get added generically (in case other chips want to do it)
I have two features, one that could be considered part of RS485 and one that has nothing at all to do with RS485.
Quoted 4 lines
Quoted 2 lines
* I need to change two UART specific registers to change the sampling mode (16x, 8x and 4x).
What determines this.
User would have to decide to turn on non-standard 8x or 4x sampling mode.
Quoted 5 lines
Quoted 3 lines
* I need to figure out if the new RS485 elements that have been added to 8250 can be used on these Exar parts and if not I need something that can enable RS485 for us.
They should provide the basics.
Where will I take the built in 485 flags and turn them into whatever my board needs?
Quoted 7 lines
Quoted 3 lines
* I need to be able to enable 9-bit mode, what they call Normal Multi-drop as well as the Auto Address Detection Mode used in conjunction with the Multi-drop mode.
That may actually be the most "fun" bit - the entire Linux tty layer is devoutly 5-8bit, although people do some horrible hacks with "8 plus parity".
Transmitting is a little bit interesting but manageable. In the receive direction the chip can detect the 9th bit and recognize it as an address bit and then check that byte against a preset station address that has been specified by the user.
Quoted 6 lines
Quoted 3 lines
With this laundry list of items that I would like to include, do you still feel like this is something that should be included in the kernel's
8250.c/8250_pci.cdrivers?I think so. It's also the path that lets you do basic enabling, get it working upstream and then extend as is needed for the other features.
So is there an example of a device already in the kernel that you think I should try to emulate? Will I be best served with something like 8250_dw.c or do you think I should try to get all of my things directly into 8250 and 8250_pci?
Matt Schulte
Quoted 4 lines
Quoted 1 line
That probably needs a bit of tweaking to getthe best results
Does this make you lean one way or the other in how I would best implement this driver?
I would always start from what we have.
I wonder actually if there is a bit of a disconnect here from the line of questions. I know in a lot of environments the model is
concept design
internal approval/verification
consult with other stakeholders
commit to model
build
release
but in the Linux space the model is
don't break anyone elses stuff
get it working
figure out as you go what is needed
if it doesn't work out adjust
polish as it becomes clear what can be done better repeat
So even if you submit initial patches to make it work with 8250.c and it turns out that actually this was the wrong thing everyone will be happy with the patches that then relocate it.
In addition what tends to occur is that the rules change anyway. You get half way through submitting support for 256 byte fifos and someone comes along with another different device that has the feature and so on.
So I would start from 8250.c and get trivial stuff like the fifo changes, the PCI identifiers and so forth in as a small set of patches and then work long the rest of it.
Even 'don't break other people's stuff' isn't a hard rule. The real rule is 'if you break other people's stuff fix it back up' - because it happens, and it's unavoidable.
Alan