home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.os.linux
- Path: sparky!uunet!mcsun!Germany.EU.net!horga!agsc!veeble.han.sub.org!gkminix!gero
- From: gero@gkminix.han.de (Gero Kuhlmann)
- Subject: Re: internal modem and serial device driver
- References: <1992Dec16.230026.9878@sfu.ca>
- Organization: gkminix, Hannover, Germany
- Date: Tue, 22 Dec 92 02:09:50 GMT
- Message-ID: <1992Dec22.020950.3470@gkminix.han.de>
- Lines: 119
-
- rchen@fraser.sfu.ca (Robert Chen) writes:
- > Now for the problem. I have a 9600bps mouse on /dev/ttys0. While
- > getty_ps is running (and hence accessing ttys2), my X cursor is jumpy
- > when I move the mouse. Since ttys0 and ttys2 share IRQ3, I assume
- > that this has something to do with the serial driver (and the fact
- > that my modem on ttys2 is not recognised at bootup).
- >
- > What I would like to be able to do is access all three com ports
- > simultaneously. I would rather not move the 2400 baud modem to
- > another IRQ (not 5 anyway) because I have an ethernet board using that
- > IRQ (and it shouldn't be neccessary since at 2400bps, sharing an IRQ
- > shouldn't be a problem).
- >
- > Can anybody point me to a solution? Is anybody successfully using
- > COM1 and COM3 simultaneously? Why is my internal modem not
- > recognised?
-
- Well, this seems to become a FAQ, so I try to give an answer here.
-
- The problem with the PC hardware is that it uses an active high interrupt
- system with three-state outputs on the serial cards. That means that normally
- the interrupt line is pulled down to zero by the output transistor
- (if the interrupt is enabled on the serial card with OUT2). Now if two
- cards share the same interrupt line, suppose only one line is trying to
- send an interrupt. It then shuts off it's low-driving transistor and enables
- it's high driving transistor. Unfortunately the low fan out of the standard
- LS-TTL's is 8mA while the high fan out is only -400microA. You can think of
- the low driving transistor being about twenty times stronger than the high
- pulling one. So the single card trying to send out an interrupt doesn't
- have any chance to bring the interrupt line up above the minimum high level
- of approx. 2V because there is the low output of the other card. But that
- low-to-high-transition is required by the interrupt controller.
-
- There is one way to solve that problem. The goal is to combine both output
- interrupt lines with a logical OR function. That means, wether one line or
- the other is going high, the interrupt controller sees the necessary level
- transition. To do this you can either use a 7432 or just a couple of diodes
- and resistors. The first solution is not very easy to implement since you
- need a lot of wiring. The latter is pretty easy to implement if you know
- a bit about digital electronics.
- In order to prevent the stronger low-driving transistors on each serial card
- to drive the IRQ line to low, it is necessary to insert a diode into each
- of the interrupt output lines in the reverse direction of the low current.
- Besides, this is the basic logical OR combination:
-
-
- I1 -------->|--------+
- |
- I2 -------->|--------+----------- O
-
- I1 and I2 are the interrupt outputs of the serial cards and O is the output
- of the OR function which goes into the interrupt controller.
- This logic prevents the IRQ line from going to low. But if no interrupt is
- active, it must become low. So we have to simulate the strong pulldown-
- transistors of the output drivers by a weaker resistor:
-
- I1 -------->|--------+
- |
- I2 -------->|--------+----------- O
- |
- R
- |
- GND
-
- This resistor just has to be added onto one of the serial cards because it is
- only needed to compensate for the internal pullup-resistor of the interrupt
- controller and is thus only required once per IRQ line.
-
- How to implement this all? Well on most serial cards and internal modems there
- is a jumper field to select the desired interrupt. Normally the output of the
- interrupt driver goes onto one side of that jumper, and the other side then
- goes directly to the system io bus. Instead of placing a real jumper there
- you have to solder in the diode. On one of the serial cards you have to find
- GND using a multimeter and then connect a resistor between that ground point
- and the output side of the jumper pins.
- As diodes I used 1N4148 which worked fine. But they have a pretty high voltage
- decrease, so if you have any troubles better use some shottky-diodes. For the
- resistors I used 470 ohm types.
- Still a problem might be if you don't have a jumper configuration as mentioned
- above. My old 2400Baud internal modem had a PAL driving the interrupt directly.
- I inserted the diodes between the PAL output and the IC socket. Some newer
- serial cards use SMD's. I think it's almost impossible to change anything on
- those.
-
- Nevertheless there is still a software problem with the linux driver. At least
- my pl1 driver had those problems and I think they are still in the pl5 kernel.
- I don't know if there are any changes in version 0.99. Well, the problem is
- that the driver has to detect, which one of the serial cards issued the inter-
- rupt on the IRQ line. To do that it has to look up each serial controller's
- interrupt status in sequence. Suppose the driver didn't find anything on the
- first controller, it steps over to the second one. There it reads the ISR and
- finds exactly one interrupt pending. The serial controller only releases it's
- interrupt output AFTER the interrupt source (for example the input channel)
- has been processed. The driver finds the receiving interrupt and steps over to
- read the input buffer. At this time the first serial card gets a character and
- issues an interrupt. After reading the second controller's buffer, that one
- sets the IRQ to low, but in the meantime controller 1 pulls IRQ high and so
- the line stays active high (remember the logical OR combination). The interrupt
- gets only recognized if the line transitions from low to high, but there is no
- such transition. After checking out the second serial card the driver termi-
- nates and never gets called again for that interrupt: the hardware has blocked.
- I wrote a patch for this problem but never made it public because I think
- using two serial cards on one interrupt is not a common problem. Obviously
- I'm wrong :-) The patch is still for my pl1-kernel, but it should be possible
- to adapt it to the new serial driver (if it isn't in there already - but then
- it doesn't come from me :-). Send me a mail if you are interested.
-
- Not to mention that the above configuration (with the kernel patch) worked
- perfectly well on my system. Unfortunately the patch adds some extra code to
- the serial driver which makes it a bit slower. I didn't use it at 14.4kBaud
- but it should be possible to use 9600Baud and 2400Baud at the same time. As
- far as I know the new driver is a bit faster so there shouldn't be any problem
- with your mentioned configuration.
-
- gero.
- --
- Gero Kuhlmann Zerberus: G.KUHLMANN@A-LINK-H.ZER
- Donarweg 4 SubNet: gero@gkminix.sub.org
- D-3000 Hannover 51 IN: gero@gkminix.han.de
-