Hi there,
I've got a problem with my communication card: It's a PCI card with a
NetMos chip, and it provides two serial and one parallel port. It's not
officially supported by the linux kernel, so I wrote my own patch and
sent it to the parallel, serial and pci maintainer. The patch itself is
basically an extension of the pci id tables; and I hope it's in the
queue for the official kernel.
The patch worked great for me with kernel 2.4.1 and .2, but no longer
with 2.4.3. The parallel port still works, but the serial port will not
be detected. I had a quite long debugging session last night (adding
printk's to the pci code takes some time, for you have to reboot to load
the new kernel), and I think I found the reason:
The card shows up on the PCI bus as one device. For the card provides
both serial and parallel ports, it will be driven by two subsystems, the
serial and the parallel driver.
I found that _either_ the parallel or the serial port works, depending
on which module you load first. The reason for this seems to be in
pci.c, especially in the pci_register_driver() function. It reads:
int pci_register_driver(struct pci_driver *drv)
{
struct pci_dev *dev;
int count = 0;
list_add_tail(&drv->node, &pci_drivers);
pci_for_each_dev(dev) {
if (!pci_dev_driver(dev))
count += pci_announce_device(drv, dev);
}
return count;
}
pci_announce_device() will be called only if there's no other driver
claiming the device. This explains why either the parallel or the serial
port will be detected: The first driver loaded will see the device, the
next drivers won't.
I'm afraid this is not a bug, but a design issue, and will be hard to
solve. Maybe we need a flag for such devices which allows it to be
claimed ba more thean one driver?
In the meantime, what can I do to get both ports working?
TIA, Michael
--
netWorks Vox: +43 316 692396
Michael Reinelt Fax: +43 316 692343
Geisslergasse 4 GSM: +43 676 3079941
A-8045 Graz, Austria e-mail: [email protected]
Michael Reinelt wrote:
> I've got a problem with my communication card: It's a PCI card with a
> NetMos chip, and it provides two serial and one parallel port. It's not
> officially supported by the linux kernel, so I wrote my own patch and
> sent it to the parallel, serial and pci maintainer. The patch itself is
> basically an extension of the pci id tables; and I hope it's in the
> queue for the official kernel.
Where is this patch available? I haven't heard of an extension to the
pci id tables, so I wonder if it's really in the queue for the official
kernel.
> The card shows up on the PCI bus as one device. For the card provides
> both serial and parallel ports, it will be driven by two subsystems, the
> serial and the parallel driver.
[...]
> pci_announce_device() will be called only if there's no other driver
> claiming the device. This explains why either the parallel or the serial
> port will be detected: The first driver loaded will see the device, the
> next drivers won't.
>
> I'm afraid this is not a bug, but a design issue, and will be hard to
> solve. Maybe we need a flag for such devices which allows it to be
> claimed ba more thean one driver?
Not so hard.
There is no need to register more than one driver per PCI device -- just
create a PCI driver whose probe routine registers serial and parallel,
and whose remove routine unregisters same.
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
On Sat, Apr 07, 2001 at 04:57:29AM -0400, Jeff Garzik wrote:
> Where is this patch available? I haven't heard of an extension to the
> pci id tables, so I wonder if it's really in the queue for the official
> kernel.
It is. <URL:http://people.redhat.com/twaugh/patches/> The
'extension' is just 'more entries', AFAIR.
> > I'm afraid this is not a bug, but a design issue, and will be hard to
> > solve. Maybe we need a flag for such devices which allows it to be
> > claimed ba more thean one driver?
>
> Not so hard.
*sigh* Jeff, when I spoke to you about this last year you said
'tough', or words to that effect. :-(
> There is no need to register more than one driver per PCI device -- just
> create a PCI driver whose probe routine registers serial and parallel,
> and whose remove routine unregisters same.
*cough* modularity *cough*
Wnat to show us some elegant code that does that?
Tim.
*/
Jeff Garzik wrote:
>
> Michael Reinelt wrote:
> > basically an extension of the pci id tables; and I hope it's in the
> > queue for the official kernel.
>
> Where is this patch available? I haven't heard of an extension to the
> pci id tables, so I wonder if it's really in the queue for the official
> kernel.
The patches went to Jens Maurer (pci_ids.h), Theodore Y. Ts'o (serial.c
and pci_ids.h) and Tim Waugh (parport_pc.c and pci_ids.h).
Well, and 'extension' may be the wrong word. I just added entries to
pci_ids.h and to the detection tables in parport_pc.c and serial.c
> > pci_announce_device() will be called only if there's no other driver
> > claiming the device. This explains why either the parallel or the serial
> > port will be detected: The first driver loaded will see the device, the
> > next drivers won't.
> There is no need to register more than one driver per PCI device -- just
> create a PCI driver whose probe routine registers serial and parallel,
> and whose remove routine unregisters same.
This means create a new module, which does the detection and uses
serial.c and parport_pc.c? I could do this (at least try to :-), but I'd
need some help here. I'm not a kernel hacker, and don't know much about
the pci code, module dependencies, driver tables, hotplugging and all
that stuff. If someone could provide a small sample (or skeleton) code
for this, I'd try my best....
On the other hand, how should the serial and parallel driver detect the
netmos card, if it's a independant module? How could this interfere with
devfs? How should devfsd know if it should load serial.o or netmos.o?
Adding PCI entries to both serial.c and parport_pc.c was that easy....
bye, Michael
--
netWorks Vox: +43 316 692396
Michael Reinelt Fax: +43 316 692343
Geisslergasse 4 GSM: +43 676 3079941
A-8045 Graz, Austria e-mail: [email protected]
On Sat, 7 Apr 2001, Michael Reinelt wrote:
> Hi there,
>
> I've got a problem with my communication card: It's a PCI card with a
> NetMos chip, and it provides two serial and one parallel port. It's not
> officially supported by the linux kernel, so I wrote my own patch and
> sent it to the parallel, serial and pci maintainer. The patch itself is
> basically an extension of the pci id tables; and I hope it's in the
> queue for the official kernel.
>
> The patch worked great for me with kernel 2.4.1 and .2, but no longer
> with 2.4.3. The parallel port still works, but the serial port will not
> be detected. I had a quite long debugging session last night (adding
> printk's to the pci code takes some time, for you have to reboot to load
> the new kernel), and I think I found the reason:
>
> The card shows up on the PCI bus as one device. For the card provides
> both serial and parallel ports, it will be driven by two subsystems, the
> serial and the parallel driver.
Given your description, this board is certainly not a multi-fonction PCI
device. Multi-function PCI devices provide separate resources for each
function in a way that allows each function to be driven by separate
software drivers. A single function PCI device that provides several
functionnalities commonly handled by separate sub-systems, is nothing but
a bag of shit we should not want to support in any O/S in my opinion.
Let me claim that ingenieers that want O/Ses to support such hardware are
either morons or bastards.
> I found that _either_ the parallel or the serial port works, depending
> on which module you load first. The reason for this seems to be in
> pci.c, especially in the pci_register_driver() function. It reads:
>
> int pci_register_driver(struct pci_driver *drv)
> {
> struct pci_dev *dev;
> int count = 0;
>
> list_add_tail(&drv->node, &pci_drivers);
> pci_for_each_dev(dev) {
> if (!pci_dev_driver(dev))
> count += pci_announce_device(drv, dev);
> }
> return count;
> }
>
>
> pci_announce_device() will be called only if there's no other driver
> claiming the device. This explains why either the parallel or the serial
> port will be detected: The first driver loaded will see the device, the
> next drivers won't.
>
> I'm afraid this is not a bug, but a design issue, and will be hard to
> solve. Maybe we need a flag for such devices which allows it to be
> claimed ba more thean one driver?
>
> In the meantime, what can I do to get both ports working?
Since the hardware does not allows the software to transparently share the
different functionnalities provided by the silicium, you must handle such
sharing by software. I mean, you must, at least, write a module (or
sub-driver or sub-system) that will handle the sharing of the PCI
function. Band-aiding the kernel code in order to cope with such
brain-deaded hardware would be a pity, in my opinion. Burden must stay
where it is deserved. If they want their 'save 0.01$ but push shit ahead'
hardware to be supported, they should write their drivers themselves, in
my opinion.
G?rard.
On Sat, Apr 07, 2001 at 01:33:25PM +0200, Michael Reinelt wrote:
> Adding PCI entries to both serial.c and parport_pc.c was that easy....
And that's how it should be, IMHO. There needs to be provision for
more than one driver to be able to talk to any given PCI device.
Tim.
*/
G?rard Roudier wrote:
>
> On Sat, 7 Apr 2001, Michael Reinelt wrote:
>
> > Hi there,
> >
> > I've got a problem with my communication card: It's a PCI card with a
> > NetMos chip, and it provides two serial and one parallel port. It's not
> > officially supported by the linux kernel, so I wrote my own patch and
> > sent it to the parallel, serial and pci maintainer. The patch itself is
> > basically an extension of the pci id tables; and I hope it's in the
> > queue for the official kernel.
> >
> > The patch worked great for me with kernel 2.4.1 and .2, but no longer
> > with 2.4.3. The parallel port still works, but the serial port will not
> > be detected. I had a quite long debugging session last night (adding
> > printk's to the pci code takes some time, for you have to reboot to load
> > the new kernel), and I think I found the reason:
> >
> > The card shows up on the PCI bus as one device. For the card provides
> > both serial and parallel ports, it will be driven by two subsystems, the
> > serial and the parallel driver.
>
> Given your description, this board is certainly not a multi-fonction PCI
> device. Multi-function PCI devices provide separate resources for each
> function in a way that allows each function to be driven by separate
> software drivers. A single function PCI device that provides several
> functionnalities commonly handled by separate sub-systems, is nothing but
> a bag of shit we should not want to support in any O/S in my opinion.
> Let me claim that ingenieers that want O/Ses to support such hardware are
> either morons or bastards.
Unfortunately, Windoze supports this configuration, and that's enough
for most hardware designers. This is also an issue with the joystick
ports on many PCI sound cards. We're not in a position to get up on the
soap box and decree this hardware "a bag of shit" though, yet.
PS. I have run into this issue before with joystick ports on many PCI
sound cards. The only one that I found that did it right (seperate PCI
function for the game port) was the SBLive.
--
Brian Gerst
Brian Gerst wrote:
>
> G?rard Roudier wrote:
> >
> > On Sat, 7 Apr 2001, Michael Reinelt wrote:
> >
> > > The card shows up on the PCI bus as one device. For the card provides
> > > both serial and parallel ports, it will be driven by two subsystems, the
> > > serial and the parallel driver.
> >
> > Given your description, this board is certainly not a multi-fonction PCI
> > device. Multi-function PCI devices provide separate resources for each
> > function in a way that allows each function to be driven by separate
> > software drivers. A single function PCI device that provides several
> > functionnalities commonly handled by separate sub-systems, is nothing but
> > a bag of shit we should not want to support in any O/S in my opinion.
> > Let me claim that ingenieers that want O/Ses to support such hardware are
> > either morons or bastards.
>
> Unfortunately, Windoze supports this configuration, and that's enough
> for most hardware designers. This is also an issue with the joystick
> ports on many PCI sound cards. We're not in a position to get up on the
> soap box and decree this hardware "a bag of shit" though, yet.
How about other Multi-I/O-Cards? I think these 2S/1P (or 2P/1S or 2P/2S)
cards are very common. At least they have been as ISA (PnP) cards. I
don't know, but I'm shure there are a lot of these out there in the
field. As mainboards without any ISA slots get more common every day,
there will be even more PCI multi-I/O-cards (apart from everyone running
to USB :-)
I needed another serial and parallel port, and I've got one of these
mainboards (Asus A7V). So I had to buy such a PCI card. Nowadays you
can't even ask for a specific hardware manufacturer, everything the guy
in the shop knows is "yes, it's PCI, and yes, it has two serial and one
parallel port".
As these cards are very cheap, you can't expect very much from them (I
don't even think there are any expensive ones out there). NetMos does
not produce this cards, they produce _chips_ for such cards. So there
are probably a lot of cards out there with these NetMos chips.
Again, how about other cards? Are there any PCI Multi-I/O-cards out
there, which are supported by linux? I'd be interested in how the driver
looks like....
bye, Michael
--
netWorks Vox: +43 316 692396
Michael Reinelt Fax: +43 316 692343
Geisslergasse 4 GSM: +43 676 3079941
A-8045 Graz, Austria e-mail: [email protected]
Tim Waugh wrote:
>
> On Sat, Apr 07, 2001 at 01:33:25PM +0200, Michael Reinelt wrote:
>
> > Adding PCI entries to both serial.c and parport_pc.c was that easy....
>
> And that's how it should be, IMHO. There needs to be provision for
> more than one driver to be able to talk to any given PCI device.
True, true, true.
But - how to deal with it? Who decides if we can deal this way or not?
PCI maintainer? Linus?
bye, Michael
P.S. I really need this. I have to unload serial and parallel and reload
them in different order when I want either print something or talk to my
Palm :-(
--
netWorks Vox: +43 316 692396
Michael Reinelt Fax: +43 316 692343
Geisslergasse 4 GSM: +43 676 3079941
A-8045 Graz, Austria e-mail: [email protected]
On Sat, 7 Apr 2001, Michael Reinelt wrote:
> Brian Gerst wrote:
> >
> > G?rard Roudier wrote:
> > >
> > > On Sat, 7 Apr 2001, Michael Reinelt wrote:
> > >
> > > > The card shows up on the PCI bus as one device. For the card provides
> > > > both serial and parallel ports, it will be driven by two subsystems, the
> > > > serial and the parallel driver.
> > >
> > > Given your description, this board is certainly not a multi-fonction PCI
> > > device. Multi-function PCI devices provide separate resources for each
> > > function in a way that allows each function to be driven by separate
> > > software drivers. A single function PCI device that provides several
> > > functionnalities commonly handled by separate sub-systems, is nothing but
> > > a bag of shit we should not want to support in any O/S in my opinion.
> > > Let me claim that ingenieers that want O/Ses to support such hardware are
> > > either morons or bastards.
> >
> > Unfortunately, Windoze supports this configuration, and that's enough
> > for most hardware designers. This is also an issue with the joystick
> > ports on many PCI sound cards. We're not in a position to get up on the
> > soap box and decree this hardware "a bag of shit" though, yet.
>
> How about other Multi-I/O-Cards? I think these 2S/1P (or 2P/1S or 2P/2S)
> cards are very common. At least they have been as ISA (PnP) cards. I
Please donnot compare ISA and PCI. ISA wasted trillions of user hours
because of its inability to allow automatic configuration.
PCI fixed this by assigning configuration space to each device.
These 'a la shitty ISA' Multi-I/O boards just kill the advantage of PCI by
moving again ISA burden to PCI. In year 2001, they stink a lot.
> don't know, but I'm shure there are a lot of these out there in the
> field. As mainboards without any ISA slots get more common every day,
> there will be even more PCI multi-I/O-cards (apart from everyone running
> to USB :-)
PCI multi I/O boards _shall_ provide a separate function for each kind of
IO. Those that donnot are kind of PCI messy IO boards.
> I needed another serial and parallel port, and I've got one of these
> mainboards (Asus A7V). So I had to buy such a PCI card. Nowadays you
> can't even ask for a specific hardware manufacturer, everything the guy
> in the shop knows is "yes, it's PCI, and yes, it has two serial and one
> parallel port".
>
> As these cards are very cheap, you can't expect very much from them (I
Cheap for whom?
What happens is that other companies or people that want to to support
such hardware must do additionnal efforts that could have been avoided if
the board had been correctly designed.
> don't even think there are any expensive ones out there). NetMos does
> not produce this cards, they produce _chips_ for such cards. So there
> are probably a lot of cards out there with these NetMos chips.
>
> Again, how about other cards? Are there any PCI Multi-I/O-cards out
> there, which are supported by linux? I'd be interested in how the driver
> looks like....
I donnot know and will never know. I only use hardware that does not look
too shitty to me. Time is too much important for me to waste even seconds
with dubious hardware. :)
G?rard.
On Sat, 7 Apr 2001, Michael Reinelt wrote:
> Tim Waugh wrote:
> >
> > On Sat, Apr 07, 2001 at 01:33:25PM +0200, Michael Reinelt wrote:
> >
> > > Adding PCI entries to both serial.c and parport_pc.c was that easy....
> >
> > And that's how it should be, IMHO. There needs to be provision for
> > more than one driver to be able to talk to any given PCI device.
>
> True, true, true.
Could you start up your brain now :) and think about the actual issue. All
the drivers must share the device resources and there is no (simple) way
to do so generically.
What you want to do is to write a single software driver, optionnaly
broken into several modules, that is aware of all the functionnalities of
the board and that will register to all involved sub-systems as needed.
> But - how to deal with it? Who decides if we can deal this way or not?
> PCI maintainer? Linus?
>
> bye, Michael
>
> P.S. I really need this. I have to unload serial and parallel and reload
> them in different order when I want either print something or talk to my
> Palm :-(
What about the option of using a different hardware ? :-)
G?rard.
Tim Waugh wrote:
>
> On Sat, Apr 07, 2001 at 01:33:25PM +0200, Michael Reinelt wrote:
>
> > Adding PCI entries to both serial.c and parport_pc.c was that easy....
>
> And that's how it should be, IMHO. There needs to be provision for
> more than one driver to be able to talk to any given PCI device.
No, because that gets really ugly. You have to create a shim driver
which allocates resources, and registers subsystems. Only a single PCI
driver like this know best how to locate and allocate resources. You
can wish to hack such into the serial or parallel driver's PCI probe id
lists, but that won't work for this case, and trying to do it any other
way looks suspiciously like a hack :)
You asked in your last message to show you code, here is a short
example. Note that I would love to rip out the SUPERIO code in parport
and make it a separate driver like this short, contrived example. Much
more modular than the existing solution.
static int __devinit foo_init_one (...)
{
u32 tmp;
int rc;
struct serial_port serial;
struct parport parport;
pci_read_config_byte(pdev, 0x40, &tmp);
serial.irq = tmp & 0xFF;
pci_read_config_word(pdev, 0x42, &tmp);
serial.port = tmp & 0xFFFF;
rc = register_serial(&serial);
if (rc < 0)
return rc;
pci_read_config_byte(pdev, 0x40, &tmp);
parport.irq = tmp & 0xFF;
pci_read_config_word(pdev, 0x42, &tmp);
parport.port = tmp & 0xFFFF;
rc = register_parport(&parport);
if (rc < 0)
return rc;
return 0;
}
static void __init foo_init(void) {
return pci_module_init(&foo_driver);
}
static void __exit foo_exit(void) {
pci_unregister_driver(&foo_driver);
}
module_init(foo_init);
module_exit(foo_exit);
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
Brian Gerst wrote:
> G?rard Roudier wrote:
> > Given your description, this board is certainly not a multi-fonction PCI
> > device. Multi-function PCI devices provide separate resources for each
> > function in a way that allows each function to be driven by separate
> > software drivers. A single function PCI device that provides several
> > functionnalities commonly handled by separate sub-systems, is nothing but
> > a bag of shit we should not want to support in any O/S in my opinion.
> > Let me claim that ingenieers that want O/Ses to support such hardware are
> > either morons or bastards.
>
> Unfortunately, Windoze supports this configuration, and that's enough
> for most hardware designers. This is also an issue with the joystick
> ports on many PCI sound cards. We're not in a position to get up on the
> soap box and decree this hardware "a bag of shit" though, yet.
>
> PS. I have run into this issue before with joystick ports on many PCI
> sound cards. The only one that I found that did it right (seperate PCI
> function for the game port) was the SBLive.
We -can- support multifunction cards such and these, and no we don't
need to hack the infrastructure to do it. You might need to hack the
subsystem drivers a bit to make them more flexible, but that's it.
WRT the specific example of joystick ports, it is already possible for a
sound driver to register a joystick port. No problem there either.
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
G?rard Roudier wrote:
>
> > Tim Waugh wrote:
> > > > Adding PCI entries to both serial.c and parport_pc.c was that easy....
> > >
> > > And that's how it should be, IMHO. There needs to be provision for
> > > more than one driver to be able to talk to any given PCI device.
> >
> > True, true, true.
>
> Could you start up your brain now :)
There's no need to start it. My brain is either 'always on', or
'suspended to ram' :-)
> and think about the actual issue. All
> the drivers must share the device resources and there is no (simple) way
> to do so generically.
> What you want to do is to write a single software driver, optionnaly
> broken into several modules, that is aware of all the functionnalities of
> the board and that will register to all involved sub-systems as needed.
I agree. that would be the clean solution. Jeff Grazik provided some
sample code, I'll try to write a driver according to this. If I find the
time....
But what I want to know before I spend time (and not-earning-money :-)
into this, I want to know: Is this the right way (TM)? How do other
multiport cards deal with this issue?
This is a specific question to the serial and parallel maintainers: are
there cards supported by _both_ the serial and parallel subsystem? Do
they work with 2.4.3? Will they work in the future? (I'm too lazy to
compare the PCI tables from serial and parallel ;-)
Another (design) question: How will such a driver/module deal with
autodetection and/or devfs? I don't like to specify 'alias /dev/tts/4
netmos', because thats pure junk to me. What about pci hotplugging?
(keep in mind that I'm new to kernel development)
> What about the option of using a different hardware ? :-)
Har har har. Could you please tell me where to get one? I don't know how
it's in your country, but here in austria you can call yourself a lucky
guy if you even find a PCI serial/parallel card. If you find one, you'll
find _one_. It's packaged in a little box where it reads "PCI 2S/1P
board". The 'manual' is a bit larger than a stamp.
I could buy one after another, and try if they have a well-designed PCI
interface.
I don't have the time for this.
I agree with you that this kind of hardware is junk. But there's a lack
of alternatives....
If there's a reasonable number of 'good' hardware out there, I'll forget
about Netmos and buy me a new card. If not, I'm willing to provide a
driver.
bye, Michael
--
netWorks Vox: +43 316 692396
Michael Reinelt Fax: +43 316 692343
Geisslergasse 4 GSM: +43 676 3079941
A-8045 Graz, Austria e-mail: [email protected]
Tim Waugh wrote:
>
> On Sat, Apr 07, 2001 at 04:57:29AM -0400, Jeff Garzik wrote:
>
> > Where is this patch available? I haven't heard of an extension to the
> > pci id tables, so I wonder if it's really in the queue for the official
> > kernel.
>
> It is. <URL:http://people.redhat.com/twaugh/patches/> The
> 'extension' is just 'more entries', AFAIR.
>
> > > I'm afraid this is not a bug, but a design issue, and will be hard to
> > > solve. Maybe we need a flag for such devices which allows it to be
> > > claimed ba more thean one driver?
> >
> > Not so hard.
>
> *sigh* Jeff, when I spoke to you about this last year you said
> 'tough', or words to that effect. :-(
>
> > There is no need to register more than one driver per PCI device -- just
> > create a PCI driver whose probe routine registers serial and parallel,
> > and whose remove routine unregisters same.
>
> *cough* modularity *cough*
>
> Wnat to show us some elegant code that does that?
Hardware has always needed quirks (linux-2.4.3 has about 60 occurences
of the word "quirks", not to mention workaround, blacklist and other synonyms)!
Please apply this little patch instead of wasting time by finger-pointing
and arguing.
Martin, comments?
Regards, Gunther
--- linux-2.4.3-orig/include/linux/pci.h Wed Apr 4 19:46:49 2001
+++ linux/include/linux/pci.h Sat Apr 7 20:01:51 2001
@@ -454,6 +454,9 @@
void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
void (*suspend)(struct pci_dev *dev); /* Device suspended */
void (*resume)(struct pci_dev *dev); /* Device woken up */
+ int multifunction_quirks; /* Quirks for PCI serial+parport cards,
+ here multiple drivers are allowed to register
+ for the same pci id match */
};
--- linux-2.4.3-orig/drivers/pci/pci.c Wed Apr 4 19:46:46 2001
+++ linux/drivers/pci/pci.c Sat Apr 7 19:59:47 2001
@@ -453,7 +453,7 @@
list_add_tail(&drv->node, &pci_drivers);
pci_for_each_dev(dev) {
- if (!pci_dev_driver(dev))
+ if (!pci_dev_driver(dev) || drv->multifunction_quirks)
count += pci_announce_device(drv, dev);
}
return count;
--- linux-2.4.3-orig/drivers/parport/parport_pc.c Wed Apr 4 19:46:46 2001
+++ linux/drivers/parport/parport_pc.c Sat Apr 7 20:18:37 2001
@@ -2539,6 +2539,7 @@
name: "parport_pc",
id_table: parport_pc_pci_tbl,
probe: parport_pc_pci_probe,
+ multifunction_quirks: 1,
};
static int __init parport_pc_init_superio (void)
--- linux-2.4.3-orig/drivers/char/serial.c Wed Apr 4 19:46:43 2001
+++ linux/drivers/char/serial.c Sat Apr 7 20:00:00 2001
@@ -4178,7 +4178,7 @@
for (i=0; timedia_data[i].num; i++) {
ids = timedia_data[i].ids;
for (j=0; ids[j]; j++) {
- if (pci_get_subvendor(dev) == ids[j]) {
+ if (pci_get_subdevice(dev) == ids[j]) {
board->num_ports = timedia_data[i].num;
return 0;
}
@@ -4718,6 +4718,7 @@
probe: serial_init_one,
remove: serial_remove_one,
id_table: serial_pci_tbl,
+ multifunction_quirks: 1,
};
Michael Reinelt wrote:
> But what I want to know before I spend time (and not-earning-money :-)
> into this, I want to know: Is this the right way (TM)? How do other
> multiport cards deal with this issue?
>
> This is a specific question to the serial and parallel maintainers: are
> there cards supported by _both_ the serial and parallel subsystem? Do
> they work with 2.4.3? Will they work in the future? (I'm too lazy to
> compare the PCI tables from serial and parallel ;-)
FWIW Tim (in this thread) is the parallel maintainer, tytso is the
serial maintainer. WRT serial, there exists serial_cs driver, and the
serial_cb driver -used- to exist. The entire purpose of these "shim"
drivers was to probe their [pcmcia, CardBus] busses for the necessary
information, and then call the existing serial layer to register ports
using the probe information already discovered. I think the pcmcia-cs
package has a similar plug-n-play shim driver for parallel ports.
To answer your question, if there are such multifunctions cards working
in 2.4.3, then their drivers are either (a) ignoring one or more
functions in favor of a primary function, or (b) lucky enough to have
hardware which export multiple PCI bus entries, one for each logical
function, making it easy to modify the subsystem driver itself to probe
for the hardware.
> Another (design) question: How will such a driver/module deal with
> autodetection and/or devfs? I don't like to specify 'alias /dev/tts/4
> netmos', because thats pure junk to me. What about pci hotplugging?
pci hotplugging happens pretty much transparently. When a new device is
plugged in, your pci_driver::probe routine is called. When a new device
is removed, your pci_driver::remove routine is called.
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
Gunther Mayer wrote:
> Hardware has always needed quirks (linux-2.4.3 has about 60 occurences
> of the word "quirks", not to mention workaround, blacklist and other synonyms)!
>
> Please apply this little patch instead of wasting time by finger-pointing
> and arguing.
>
> Martin, comments?
Is Martin still alive? He hasn't been active in PCI development well
over six months, maybe a year now. Ivan (alpha hacker) appeared on the
scene to fix serious PCI bridge bugs, DaveM has added some PCI DMA
stuff, and I've added a couple driver-related things. I haven't seen
code from Martin in a long long time, and only a comment or two in
recent memory.
> --- linux-2.4.3-orig/include/linux/pci.h Wed Apr 4 19:46:49 2001
> +++ linux/include/linux/pci.h Sat Apr 7 20:01:51 2001
> @@ -454,6 +454,9 @@
> void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
> void (*suspend)(struct pci_dev *dev); /* Device suspended */
> void (*resume)(struct pci_dev *dev); /* Device woken up */
> + int multifunction_quirks; /* Quirks for PCI serial+parport cards,
> + here multiple drivers are allowed to register
> + for the same pci id match */
> };
As has been explained, the current API supports this just fine without
modification.
Also, changing the API in the stable series should be frowned upon,
-especially- something domain specific like this.
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
On Sat, Apr 07, 2001 at 11:04:38AM +0200, G?rard Roudier wrote:
> Given your description, this board is certainly not a multi-fonction PCI
> device. Multi-function PCI devices provide separate resources for each
> function in a way that allows each function to be driven by separate
> software drivers.
Yes, but the vendor screwed it up (probably to save money). This is
_very_ common. It is very unusual to have a multifunction I/O card
that gets this right (in fact Lava is the only one I can think of
off-hand).
> Band-aiding the kernel code in order to cope with such brain-deaded
> hardware would be a pity, in my opinion. Burden must stay where it
> is deserved.
If we have to do this, then Gunther's approach (multifunc_quirks or
whatever) looks a lot better than having a separate driver for every
single multi-IO card.
Tim.
*/
On Sat, Apr 07, 2001 at 08:42:35PM +0200, Gunther Mayer wrote:
> Please apply this little patch instead of wasting time by
> finger-pointing and arguing.
This patch would make me happy.
It would allow support for new multi-IO cards to generally be the
addition of about two lines to two files (which is currently how it's
done), rather than having separate mutant hybrid monstrosity drivers
for each card (IMHO)..
Tim.
*/
On Sat, Apr 07, 2001 at 02:53:23PM -0400, Jeff Garzik wrote:
> As has been explained, the current API supports this just fine without
> modification.
The current API makes it much harder to support the breadth of
hardware we're talking about.
The hardware has quirks, and this quirk is so common that it is
absolutely the norm.
Tim.
*/
On Sat, Apr 07, 2001 at 01:23:27PM -0400, Jeff Garzik wrote:
> You asked in your last message to show you code, here is a short
> example. Note that I would love to rip out the SUPERIO code in parport
> and make it a separate driver like this short, contrived example. Much
> more modular than the existing solution.
(The superio code is on its way out anyway, for different reasons..)
More modular? Yes, it adds another module to support a card, so yes
there are more modules.
But with the multifunction_quirks approach, support is a question of
adding two lines in a table.
Tim.
*/
On Sat, Apr 07, 2001 at 03:01:57PM +0200, G?rard Roudier wrote:
> PCI multi I/O boards _shall_ provide a separate function for each kind of
> IO. Those that donnot are kind of PCI messy IO boards.
But they don't. What are you going to do about it?
> Cheap for whom?
For the guys who make them, and for the ones who buy them. Yes, it
sucks.
> > Again, how about other cards? Are there any PCI Multi-I/O-cards out
> > there, which are supported by linux? I'd be interested in how the driver
> > looks like....
>
> I donnot know and will never know. I only use hardware that does not look
> too shitty to me. Time is too much important for me to waste even seconds
> with dubious hardware. :)
Good luck finding a card that gets multifunction I/O right without
wasting any seconds then.
For a list of cards that are supported, or for which patches exist
(using the 'two lines in a table' approach), see
<URL:http://people.redhat.com/twaugh/parport/cards.html>.
Tim.
*/
Tim Waugh wrote:
> It would allow support for new multi-IO cards to generally be the
> addition of about two lines to two files (which is currently how it's
> done), rather than having separate mutant hybrid monstrosity drivers
> for each card (IMHO)..
;-)
My point of view is that hacking the kernel so that two device drivers
can pretend they are not driving the same hardware is silly. With such
hardware there are always inter-dependencies, and you can either hack
special case code into two or more drivers, or create one central
control point from which knowledge is dispatched. Like I mentioned in a
previous message, the Via parport code is ugly and should go into a Via
superio driver. It is simply not scalable to consider the alternative
-- add superio code to parport_pc.c for each ISA bridge out there. I
think the same principle applies to this discussion as well. It's just
ugly to keep hacking in special cases to handle hardware that is
multifunction like this.
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
On Sat, Apr 07, 2001 at 03:23:12PM -0400, Jeff Garzik wrote:
> It's just ugly to keep hacking in special cases to handle hardware
> that is multifunction like this.
I just don't want it to be a huge chore to add support for these
cards.
Would everyone be happy if (say) drivers/parport/parport_serial.c had
a table and a generic version of your example function, so that the
table somehow described the multifunction cards out there?
Tim.
*/
Tim Waugh wrote:
>
> On Sat, Apr 07, 2001 at 01:23:27PM -0400, Jeff Garzik wrote:
>
> > You asked in your last message to show you code, here is a short
> > example. Note that I would love to rip out the SUPERIO code in parport
> > and make it a separate driver like this short, contrived example. Much
> > more modular than the existing solution.
>
> (The superio code is on its way out anyway, for different reasons..)
I think there will be further discussion on this :)
> More modular? Yes, it adds another module to support a card, so yes
> there are more modules.
>
> But with the multifunction_quirks approach, support is a question of
> adding two lines in a table.
struct pci_driver is going to become struct driver, don't forget. With
that in mind, the "multifunction_quirks" patch appears even more of a
bus-specific hack.
Why do you want to dirty the soon-to-be generic driver API for stupid
hardware?
It takes two seconds to write a shim driver as I have described, and
further a shim driver is not necessary on sensible hardware.
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
On Sat, 7 Apr 2001, Tim Waugh wrote:
> On Sat, Apr 07, 2001 at 08:42:35PM +0200, Gunther Mayer wrote:
>
> > Please apply this little patch instead of wasting time by
> > finger-pointing and arguing.
>
> This patch would make me happy.
>
> It would allow support for new multi-IO cards to generally be the
> addition of about two lines to two files (which is currently how it's
> done), rather than having separate mutant hybrid monstrosity drivers
> for each card (IMHO)..
It is possible to design a single function PCI device that is able to do
everything. Your approach is just encouraging this kind of monstrosity.
Such montrosity will look like some single-IRQ capable ISA remake, thus
worse than 20 years old ISA.
If we want to encourage that, then we want to stay stupid for life, in my
nervous opinion.
G?rard.
Tim Waugh wrote:
> If we have to do this, then Gunther's approach (multifunc_quirks or
> whatever) looks a lot better than having a separate driver for every
> single multi-IO card.
Who said you have to have a separate driver for every single multi-IO
card? A single driver could support all serial+parallel multi-IO cards,
for example.
Due to the differences in busses and hardware implementations and such,
typically you want to provide two pieces of code for each common
hardware subsystem (like "parport" or "serial"): foo_lib.c and
foo_card.c.
foo_lib.c is the guts of the hardware support, and it provides an
[un]register_foodev() interface. foo_card.c is totally separate, and it
holds the PCI or ISAPNP or USB device ids. foo_card does all the
hardware detection, and calls register_foodev() for each hardware device
it finds.
For small subsystems, this is obviously overkill. But for common
subsystems like serial or parport, this makes complete sense. If an
sbus device appears that acts just like a PC parallel port, all DaveM
needs to do is write a parport_sbus.c shim which calls
register_foodev(). No patching one central file necessary to add
support for a new bus.
Regards,
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
On Sat, Apr 07, 2001 at 03:40:13PM -0400, Jeff Garzik wrote:
> Who said you have to have a separate driver for every single multi-IO
> card? A single driver could support all serial+parallel multi-IO cards,
> for example.
Okay, I misunderstood. I'll take a look at doing this for 2.4.
First of all, parport_pc will need to export the equivalent of
register_serial (its equivalent is probably parport_pc_probe_port).
[It actually already does this (conditionally on parport_cs).]
drivers/parport/parport_serial.c sound okay, or is a different place
better?
Tim.
*/
Jeff Garzik wrote:
>
> Tim Waugh wrote:
> > It would allow support for new multi-IO cards to generally be the
> > addition of about two lines to two files (which is currently how it's
> > done), rather than having separate mutant hybrid monstrosity drivers
> > for each card (IMHO)..
>
> ;-)
>
> My point of view is that hacking the kernel so that two device drivers
> can pretend they are not driving the same hardware is silly. With such
> hardware there are always inter-dependencies, and you can either hack
> special case code into two or more drivers, or create one central
> control point from which knowledge is dispatched. Like I mentioned in a
My point of view is making it easy for the average user.
This is the same as making it easy for maintainers of hardware drivers !
More module interdependencies == More complicated == More clueless users
Many users will be surprised if they must load another module (e.g."pci_multiio")
to get their parallel and serial ports working.
Thus _must not_ happen in the stable release.
Regards, Gunther
Jeff Garzik wrote:
>
> Gunther Mayer wrote:
> > Hardware has always needed quirks (linux-2.4.3 has about 60 occurences
> > of the word "quirks", not to mention workaround, blacklist and other synonyms)!
> >
> > Please apply this little patch instead of wasting time by finger-pointing
> > and arguing.
> >
> > Martin, comments?
>
> Is Martin still alive? He hasn't been active in PCI development well
> over six months, maybe a year now. Ivan (alpha hacker) appeared on the
> scene to fix serious PCI bridge bugs, DaveM has added some PCI DMA
> stuff, and I've added a couple driver-related things. I haven't seen
> code from Martin in a long long time, and only a comment or two in
> recent memory.
See linux/MAINTAINERS for "PCI Subsystem", the attribute is even called:
"Supported: Someone is actually paid to look after this".
Jeff Garzik wrote:
>
Like I mentioned in a
> previous message, the Via parport code is ugly and should go into a Via
> superio driver. It is simply not scalable to consider the alternative
> -- add superio code to parport_pc.c for each ISA bridge out there. I
> think the same principle applies to this discussion as well.
Yes, superio will go away and replaced by user level utility:
http://home.t-online.de/home/gunther.mayer/lssuperio-0.61.tar.bz2
PNPBIOS and ACPI will help to configure parallel ports (and others),
after some issues have been resolved.
Again this will be builtin to parport (and not parport_acpi.o etc)
to make it failproof.
G?rard Roudier wrote:
>
> On Sat, 7 Apr 2001, Tim Waugh wrote:
>
> > On Sat, Apr 07, 2001 at 08:42:35PM +0200, Gunther Mayer wrote:
> >
> > > Please apply this little patch instead of wasting time by
> > > finger-pointing and arguing.
> >
> > This patch would make me happy.
> >
> > It would allow support for new multi-IO cards to generally be the
> > addition of about two lines to two files (which is currently how it's
> > done), rather than having separate mutant hybrid monstrosity drivers
> > for each card (IMHO)..
>
> It is possible to design a single function PCI device that is able to do
> everything. Your approach is just encouraging this kind of monstrosity.
> Such montrosity will look like some single-IRQ capable ISA remake, thus
> worse than 20 years old ISA.
>
> If we want to encourage that, then we want to stay stupid for life, in my
> nervous opinion.
If you want to discourage hardware vendors, they will stay with Windows.
In article <[email protected]>,
Michael Reinelt <[email protected]> wrote:
>
>The card shows up on the PCI bus as one device. For the card provides
>both serial and parallel ports, it will be driven by two subsystems, the
>serial and the parallel driver.
Tough. The PCI specification has a perfectly good way to handle this,
namely by having subfunctions on the same chip. The particular chip
designer was lazy or something, and didn't do it the proper way. Which
means that you cannot, and should not, use a generic PCI driver for the
chip. Because it doesn't show up as separate devices for the separate
functions.
Now, that doesn't mean that you can't use the card, or the existing
drivers. It only means that you should fix up the total braindamage of
the hardware.
It only means that you should probably approach it as being a special
"invisible PCI bridge", and basically have a specific driver for that
chip that acts as a _bridge_ driver.
Writing a bridge driver is not that hard: your init routine will
instantiate the devices behind the bridge (ie you would allocate two
"struct pci_device" structures and you would add them to behind the
"bridge", and you would make _those_ look like real serial and parallell
devices.
See for example drivers/pcmcia/cardbus.c: cb_alloc() for how to create a
new "pci_dev" (see the "for i = 0; i < fn ; i++)" loop: it creates the
devices for each subfunction found behind the cardbus bridge. It really
boils down to "dev = kmalloc(); initialize_dev(dev); pci_insert_dev(dev,
bus);").
At which point you can happily use the current drivers without any
modifications.
Linus
On Sat, Apr 07, 2001 at 10:21:11PM +0200, Gunther Mayer wrote:
> Many users will be surprised if they must load another module
> (e.g."pci_multiio") to get their parallel and serial ports working.
>
> Thus _must not_ happen in the stable release.
Yes, I agree. I am planning for parport_serial.c to end up as part of
parport_pc.o for 2.4.
Tim.
*/
Gunther Mayer wrote:
>
> Jeff Garzik wrote:
> >
> Like I mentioned in a
> > previous message, the Via parport code is ugly and should go into a Via
> > superio driver. It is simply not scalable to consider the alternative
> > -- add superio code to parport_pc.c for each ISA bridge out there. I
> > think the same principle applies to this discussion as well.
>
> Yes, superio will go away and replaced by user level utility:
> http://home.t-online.de/home/gunther.mayer/lssuperio-0.61.tar.bz2
The entire point of superio is -not- configuration. That's what your
BIOS setup does, and/or user-level utilities.
The point of superio support is that you can obtain 100% accurate probe
information for legacy ISA devices, by looking at the information
exported by the ISA bridge. There is no need for "probing" per se,
because you know whether or not the parallel port is enabled, exactly
what IRQ it's on, and exactly what DMA channel it uses.
So, a superio probe occurs first because it provides the maximum
information at the least cost. Since ISA devices must still be
supported, the ISA probe should come after the PCI probe (which includes
PCI superio stuff). ISA probes to ports already registered via the
superio probe fail at the request_region level, avoiding any unnecessary
hardware access at those ports. There are tertiary benefits to such a
scheme as well, I'll be glad to elaborate on if people are interested in
the nitty gritty (read: boring) details.
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
Linus Torvalds wrote:
> It only means that you should probably approach it as being a special
> "invisible PCI bridge", and basically have a specific driver for that
> chip that acts as a _bridge_ driver.
>
> Writing a bridge driver is not that hard: your init routine will
> instantiate the devices behind the bridge (ie you would allocate two
> "struct pci_device" structures and you would add them to behind the
> "bridge", and you would make _those_ look like real serial and parallell
> devices.
>
> See for example drivers/pcmcia/cardbus.c: cb_alloc() for how to create a
> new "pci_dev" (see the "for i = 0; i < fn ; i++)" loop: it creates the
> devices for each subfunction found behind the cardbus bridge. It really
> boils down to "dev = kmalloc(); initialize_dev(dev); pci_insert_dev(dev,
> bus);").
Cool :) Creative and interesting solution.
IMHO that's a slippery slope... If you do this as a solution for
multifunction devices, you also have to consider even more stupid
hardware which exports one PCI function, but multiple BARs for different
purposes...
Another problem, which I have yet to think much about, is doing a
reverse mapping after what you just describe: how does one figure out
that a bridge+devices is really a single hardware device? Answering
that question is interesting for NICs as well, because 4-port NICs often
appear as four devices behind a bridge. Some operations, such as
sharing an EEPROM across four ports, or setting a special flag if you
are quad-port hardware, require that knowledge. [ugly hacks exist now
to get around our lack of such knowledge]
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
Gunther Mayer wrote:
> More module interdependencies == More complicated == More clueless users
With module autoloading, they don't have to care about module
interdependencies. The primary thing people care about is what string
is passed to modprobe. When that changes, things break. As long as
that doesn't change, you are ok. Who cares if two or five or ten helper
modules are automatically pulled in, and who cares if that list of
helper modules changes... Functionally speaking, the user is completely
unaware of the change.
> Many users will be surprised if they must load another module (e.g."pci_multiio")
> to get their parallel and serial ports working.
>
> Thus _must not_ happen in the stable release.
Agreed.
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
Gunther Mayer wrote:
> Jeff Garzik wrote:
> > Gunther Mayer wrote:
> > > Hardware has always needed quirks (linux-2.4.3 has about 60 occurences
> > > of the word "quirks", not to mention workaround, blacklist and other synonyms)!
> > >
> > > Please apply this little patch instead of wasting time by finger-pointing
> > > and arguing.
> > >
> > > Martin, comments?
> >
> > Is Martin still alive? He hasn't been active in PCI development well
> > over six months, maybe a year now. Ivan (alpha hacker) appeared on the
> > scene to fix serious PCI bridge bugs, DaveM has added some PCI DMA
> > stuff, and I've added a couple driver-related things. I haven't seen
> > code from Martin in a long long time, and only a comment or two in
> > recent memory.
>
> See linux/MAINTAINERS for "PCI Subsystem", the attribute is even called:
> "Supported: Someone is actually paid to look after this".
Who cares... action not words. :) A lot of those MAINTAINERS entries
do not reflect reality [which is a bug, of course].
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
[email protected] (Tim Waugh) wrote on 07.04.01 in <[email protected]>:
> On Sat, Apr 07, 2001 at 01:23:27PM -0400, Jeff Garzik wrote:
>
> > You asked in your last message to show you code, here is a short
> > example. Note that I would love to rip out the SUPERIO code in parport
> > and make it a separate driver like this short, contrived example. Much
> > more modular than the existing solution.
>
> (The superio code is on its way out anyway, for different reasons..)
>
> More modular? Yes, it adds another module to support a card, so yes
> there are more modules.
>
> But with the multifunction_quirks approach, support is a question of
> adding two lines in a table.
So why not make Jeff's example use a multifunction board table to do it's
job?
MfG Kai
Jeff Garzik wrote:
>
> > Another (design) question: How will such a driver/module deal with
> > autodetection and/or devfs? I don't like to specify 'alias /dev/tts/4
> > netmos', because thats pure junk to me. What about pci hotplugging?
>
> pci hotplugging happens pretty much transparently. When a new device is
> plugged in, your pci_driver::probe routine is called. When a new device
> is removed, your pci_driver::remove routine is called.
Thats clear to me. But the probe and remove routine can only be called
if the module is already loaded. My question was: who will load the
module? (I'll call it 'netmos.o')
devfs in its standard configuration knows about loading serial.o or
parport.o when /dev/tts/* or /dev/parport/* is accessed. Some other
module loads are triggered by module dependancies (e.g. lp.o requires
parport.o)
If I do a 'modprobe serial', how should the serial driver know that the
netmos.o should be loaded, too?
There is a file called 'modules.pcimap', which contains modules for
specific PCI devices. That's how hotplugging could detect that there's a
netmos card and that netmos.o should be loaded. That looks clean to me,
but I'm not shure if this sort of PCI hotplugging is already
implemented.
bye, Michael
--
netWorks Vox: +43 316 692396
Michael Reinelt Fax: +43 316 692343
Geisslergasse 4 GSM: +43 676 3079941
A-8045 Graz, Austria e-mail: [email protected]
Tim Waugh wrote:
>
> On Sat, Apr 07, 2001 at 03:40:13PM -0400, Jeff Garzik wrote:
>
> > Who said you have to have a separate driver for every single multi-IO
> > card? A single driver could support all serial+parallel multi-IO cards,
> > for example.
>
> Okay, I misunderstood. I'll take a look at doing this for 2.4.
>
> First of all, parport_pc will need to export the equivalent of
> register_serial (its equivalent is probably parport_pc_probe_port).
> [It actually already does this (conditionally on parport_cs).]
>
> drivers/parport/parport_serial.c sound okay, or is a different place
> better?
Heh. These multi-I/O-cards come in a lot of different fashions. Let me
explain the NetMos chips a bit:
My card shows up with lspci like that:
lizard:~ # lspci -s 00:0c -vn
00:0c.0 Class 0780: 9710:9835 (rev 01)
Subsystem: 1000:0012
Flags: medium devsel, IRQ 11
I/O ports at 9400 [size=8]
I/O ports at 9000 [size=8]
I/O ports at 8800 [size=8]
I/O ports at 8400 [size=8]
I/O ports at 8000 [size=8]
I/O ports at 7800 [size=16]
as you can see, it's class is PCI_CLASS_COMMUNICATION_OTHER
There are 8 different chips from Netmos, they differ mainly in the
number of serial and parallel ports:
9705 -/1P
9735 2S/1P
9745 2S/-
9805 -/1P
9815 -/2P
9835 2S/1P
9845 2S/-
9855 -/2P
the chip id is the same as the PCI device ID. So there are chips with
only serial or parallel ports, and chips with both of them. A chip
without a parallel port (9845) does not really belong to
parport/parport_serial.c :-) On the other hand, a chip without a serial
port should have nothing to do whith serial.c.
At the moment there is a clean solution: serial.c contains only the
device ids of cards with serial ports, the same for parport_pc.c
to summarize the discussion, there are 3 possible solution. I wanted a
simple _and_ clean solution, this seems impossible.
The simple solution: Gunters 'multifunction quirks'
clean solution #1: a new module according to Jeffs sample code
clean solution #2: 'invisible PCI bridge' from Linus
For both clean solutions I don't know how autoloading/hotplugging would
be handled. But they look good, especially Linus' one.
The simple solution would be _very_ easy to integrate, would not break
existing configurations, and would not require any design changes.
Suggestion: multifunction quirks for 2.4, one of the clean solutions for
2.5?
bye, Michael
--
netWorks Vox: +43 316 692396
Michael Reinelt Fax: +43 316 692343
Geisslergasse 4 GSM: +43 676 3079941
A-8045 Graz, Austria e-mail: [email protected]
On Sun, Apr 08, 2001 at 02:05:36PM +0200, Michael Reinelt wrote:
> The simple solution: Gunters 'multifunction quirks'
> clean solution #1: a new module according to Jeffs sample code
> clean solution #2: 'invisible PCI bridge' from Linus
[...]
> Suggestion: multifunction quirks for 2.4, one of the clean solutions for
> 2.5?
I would rather we went for something in 2.4 and stick with it in 2.5
than changing again. (The parport ID list format changed in 2.2->2.4
already in order to handle subsystem IDs.)
Tim.
*/
Hi Jeff!
> Is Martin still alive? He hasn't been active in PCI development well
> over six months, maybe a year now. Ivan (alpha hacker) appeared on the
> scene to fix serious PCI bridge bugs, DaveM has added some PCI DMA
> stuff, and I've added a couple driver-related things. I haven't seen
> code from Martin in a long long time, and only a comment or two in
> recent memory.
I'm buried alive in mail, graph theory and several other projects,
so I'm now happy I'm able to at least keep track of kernel development
and answer some bug reports, but I hope it will get better soon.
If it won't, I'll probably have to pass the maintainer's sceptre
to someone less busy, but I'd rather like to avoid it as I still like
the PCI world very much though it's got somewhat messy these days.
> > --- linux-2.4.3-orig/include/linux/pci.h Wed Apr 4 19:46:49 2001
> > +++ linux/include/linux/pci.h Sat Apr 7 20:01:51 2001
> > @@ -454,6 +454,9 @@
> > void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
> > void (*suspend)(struct pci_dev *dev); /* Device suspended */
> > void (*resume)(struct pci_dev *dev); /* Device woken up */
> > + int multifunction_quirks; /* Quirks for PCI serial+parport cards,
> > + here multiple drivers are allowed to register
> > + for the same pci id match */
> > };
This is incredibly ugly. IMHO the right solution is to add a driver for
each such multi-function device which will split the device to two virtual
devices as Linus has suggested, or maybe better to add a generic driver
doing such splitting for multiple similar multi-function cards.
Have a nice fortnight
--
Martin `MJ' Mares <[email protected]> <[email protected]> http://atrey.karlin.mff.cuni.cz/~mj/
bug, n: A son of a glitch.
Jeff Garzik <[email protected]> writes:
>Not so hard.
>There is no need to register more than one driver per PCI device -- just
>create a PCI driver whose probe routine registers serial and parallel,
>and whose remove routine unregisters same.
Sigh. Register a small dummy driver, which takes the device and then hands
out the parallel ports to the parallel driver and the serial ports to the
serial driver. All you need are just two small hooks.
Regards
Henning
--
Dipl.-Inf. (Univ.) Henning P. Schmiedehausen -- Geschaeftsfuehrer
INTERMETA - Gesellschaft fuer Mehrwertdienste mbH [email protected]
Am Schwabachgrund 22 Fon.: 09131 / 50654-0 [email protected]
D-91054 Buckenhof Fax.: 09131 / 50654-20
Michael Reinelt wrote:
>
> Jeff Garzik wrote:
> >
> > > Another (design) question: How will such a driver/module deal with
> > > autodetection and/or devfs? I don't like to specify 'alias /dev/tts/4
> > > netmos', because thats pure junk to me. What about pci hotplugging?
> >
> > pci hotplugging happens pretty much transparently. When a new device is
> > plugged in, your pci_driver::probe routine is called. When a new device
> > is removed, your pci_driver::remove routine is called.
>
> Thats clear to me. But the probe and remove routine can only be called
> if the module is already loaded. My question was: who will load the
> module? (I'll call it 'netmos.o')
typically a hotplug agent, cardmgr in this case.
> If I do a 'modprobe serial', how should the serial driver know that the
> netmos.o should be loaded, too?
cardmgr ideally should load netmos.o, which will automatically pull in
serial.o.
(cardmgr is from the pcmcia-cs package, at
http://pcmcia-cs.sourceforge.net/)
Regards,
Jeff
--
Jeff Garzik | Sam: "Mind if I drive?"
Building 1024 | Max: "Not if you don't mind me clawing at the dash
MandrakeSoft | and shrieking like a cheerleader."
Jeff Garzik wrote:
>
> Michael Reinelt wrote:
> >
> > Thats clear to me. But the probe and remove routine can only be called
> > if the module is already loaded. My question was: who will load the
> > module? (I'll call it 'netmos.o')
>
> typically a hotplug agent, cardmgr in this case.
huh? cardmgr?
I agree with the hotplug agent, but cardmgr? I know cardmgr and use it
on my laptop, but I've never heard of it dealing with PCI devices?
Doesn't he need some sort of 'card services' and stuff, none of them
available on a desktop PC?
bye, Michael
--
netWorks Vox: +43 316 692396
Michael Reinelt Fax: +43 316 692343
Geisslergasse 4 GSM: +43 676 3079941
A-8045 Graz, Austria e-mail: [email protected]
Here's a first take on a module for providing a framework for
supporting parallel/serial multi-IO cards.
Tim.
*/
2001-04-19 Tim Waugh <[email protected]>
* drivers/parport/parport_pc.c: Un-__devinit the probe function
and export it.
* drivers/parport/parport_serial.c: New file.
* drivers/parport/Makefile: Build it.
* drivers/char/Config.in: Configure it.
* drivers/parport/ChangeLog: Updated.
--- linux/drivers/parport/parport_pc.c.multiio Thu Apr 19 16:52:07 2001
+++ linux/drivers/parport/parport_pc.c Thu Apr 19 16:52:50 2001
@@ -1983,10 +1983,10 @@
/* --- Initialisation code -------------------------------- */
-struct parport *__devinit parport_pc_probe_port (unsigned long int base,
- unsigned long int base_hi,
- int irq, int dma,
- struct pci_dev *dev)
+struct parport *parport_pc_probe_port (unsigned long int base,
+ unsigned long int base_hi,
+ int irq, int dma,
+ struct pci_dev *dev)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
@@ -2631,16 +2631,7 @@
}
/* Exported symbols. */
-#ifdef CONFIG_PARPORT_PC_PCMCIA
-
-/* parport_cs needs this in order to dyncamically get us to find ports. */
EXPORT_SYMBOL (parport_pc_probe_port);
-
-#else
-
-EXPORT_NO_SYMBOLS;
-
-#endif
#ifdef MODULE
static int io[PARPORT_PC_MAX_PORTS+1] = { [0 ... PARPORT_PC_MAX_PORTS] = 0 };
--- linux/drivers/parport/Makefile.multiio Tue Jan 2 15:01:47 2001
+++ linux/drivers/parport/Makefile Thu Apr 19 16:52:50 2001
@@ -22,6 +22,7 @@
obj-$(CONFIG_PARPORT) += parport.o
obj-$(CONFIG_PARPORT_PC) += parport_pc.o
+obj-$(CONFIG_PARPORT_SERIAL) += parport_serial.o
obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o
obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o
obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o
--- linux/drivers/parport/ChangeLog.multiio Thu Apr 19 16:52:07 2001
+++ linux/drivers/parport/ChangeLog Thu Apr 19 16:52:50 2001
@@ -0,0 +1,5 @@
+2001-04-19 Tim Waugh <[email protected]>
+
+ * parport_pc.c (parport_pc_probe_port): Remove __devinit
+ attribute. Export unconditionally.
+
--- linux/drivers/parport/parport_serial.c.multiio Thu Apr 19 16:52:50 2001
+++ linux/drivers/parport/parport_serial.c Thu Apr 19 17:02:28 2001
@@ -0,0 +1,301 @@
+/*
+ * Support for common PCI multi-I/O cards (which is most of them)
+ *
+ * Copyright (C) 2001 Tim Waugh <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ *
+ * Multi-function PCI cards are supposed to present separate logical
+ * devices on the bus. A common thing to do seems to be to just use
+ * one logical device with lots of base address registers for both
+ * parallel ports and serial ports. This driver is for dealing with
+ * that.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/parport.h>
+#include <linux/parport_pc.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/list.h>
+
+#include <asm/serial.h>
+
+enum parport_pc_pci_cards {
+ titan_110l = 0,
+ titan_210l,
+};
+
+
+/* each element directly indexed from enum list, above */
+static struct parport_pc_pci {
+ int numports;
+ struct { /* BAR (base address registers) numbers in the config
+ space header */
+ int lo;
+ int hi; /* -1 if not there, >6 for offset-method (max
+ BAR is 6) */
+ } addr[4];
+} cards[] __devinitdata = {
+ /* titan_110l */ { 1, { { 3, -1 }, } },
+ /* titan_210l */ { 1, { { 3, -1 }, } },
+};
+
+// For pci_ids.h:
+#define PCI_DEVICE_ID_TITAN_110L 0x8011
+#define PCI_DEVICE_ID_TITAN_210L 0x8021
+
+static struct pci_device_id parport_serial_pci_tbl[] __devinitdata = {
+ /* PCI cards */
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l },
+ { 0, } /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
+
+struct pci_board_no_ids {
+ int flags;
+ int num_ports;
+ int base_baud;
+ int uart_offset;
+ int reg_shift;
+ int (*init_fn)(struct pci_dev *dev, struct pci_board_no_ids *board,
+ int enable);
+ int first_uart_offset;
+};
+
+static struct pci_board_no_ids pci_boards[] __devinitdata = {
+ /*
+ * PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
+ * Offset to get to next UART's registers,
+ * Register shift to use for memory-mapped I/O,
+ * Initialization function, first UART offset
+ */
+
+/* titan_110l */ { SPCI_FL_BASE1, 1, 921600 },
+/* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
+};
+
+struct parport_serial_private {
+ int num;
+ int line[20];
+ struct pci_board_no_ids ser;
+ struct parport *port;
+};
+
+static int __devinit get_pci_port (struct pci_dev *dev,
+ struct pci_board_no_ids *board,
+ struct serial_struct *req,
+ int idx)
+{
+ unsigned long port;
+ int base_idx;
+ int max_port;
+ int offset;
+
+ base_idx = SPCI_FL_GET_BASE(board->flags);
+ if (board->flags & SPCI_FL_BASE_TABLE)
+ base_idx += idx;
+
+ if (board->flags & SPCI_FL_REGION_SZ_CAP) {
+ max_port = pci_resource_len(dev, base_idx) / 8;
+ if (idx >= max_port)
+ return 1;
+ }
+
+ offset = board->first_uart_offset;
+
+ /* Timedia/SUNIX uses a mixture of BARs and offsets */
+ /* Ugh, this is ugly as all hell --- TYT */
+ if(dev->vendor == PCI_VENDOR_ID_TIMEDIA ) /* 0x1409 */
+ switch(idx) {
+ case 0: base_idx=0;
+ break;
+ case 1: base_idx=0; offset=8;
+ break;
+ case 2: base_idx=1;
+ break;
+ case 3: base_idx=1; offset=8;
+ break;
+ case 4: /* BAR 2*/
+ case 5: /* BAR 3 */
+ case 6: /* BAR 4*/
+ case 7: base_idx=idx-2; /* BAR 5*/
+ }
+
+ port = pci_resource_start(dev, base_idx) + offset;
+
+ if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
+ port += idx * (board->uart_offset ? board->uart_offset : 8);
+
+ if (pci_resource_flags (dev, base_idx) & IORESOURCE_IO) {
+ int high_bits_offset = ((sizeof(long)-sizeof(int))*8);
+ req->port = port;
+ if (high_bits_offset)
+ req->port_high = port >> high_bits_offset;
+ else
+ req->port_high = 0;
+ return 0;
+ }
+ req->io_type = SERIAL_IO_MEM;
+ req->iomem_base = ioremap(port, board->uart_offset);
+ req->iomem_reg_shift = board->reg_shift;
+ req->port = 0;
+ return req->iomem_base ? 0 : 1;
+}
+
+/* Register the serial port(s) of a PCI card. */
+static int __devinit serial_register (struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct pci_board_no_ids *board = &pci_boards[id->driver_data];
+ struct parport_serial_private *priv = pci_get_drvdata (dev);
+ struct serial_struct serial_req;
+ int base_baud;
+ int k;
+ int success = 0;
+
+ priv->ser = *board;
+ if (board->init_fn && ((board->init_fn) (dev, board, 1) != 0))
+ return 1;
+
+ base_baud = board->base_baud;
+ if (!base_baud)
+ base_baud = BASE_BAUD;
+ memset (&serial_req, 0, sizeof (serial_req));
+
+ for (k = 0; k < board->num_ports; k++) {
+ int line;
+ serial_req.irq = dev->irq;
+ if (get_pci_port (dev, board, &serial_req, k))
+ break;
+ serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
+ line = register_serial (&serial_req);
+ if (line < 0) {
+ printk (KERN_DEBUG
+ "parport_serial: register_serial failed\n");
+ continue;
+ }
+ priv->line[priv->num++] = line;
+ success = 1;
+ }
+
+ return success ? 0 : 1;
+}
+
+/* Register the parallel port(s) of a PCI card. */
+static int __devinit parport_register (struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct parport_serial_private *priv = pci_get_drvdata (dev);
+ int i = id->driver_data, n;
+ int success = 0;
+
+ for (n = 0; n < cards[i].numports; n++) {
+ int lo = cards[i].addr[n].lo;
+ int hi = cards[i].addr[n].hi;
+ unsigned long io_lo, io_hi;
+ io_lo = pci_resource_start (dev, lo);
+ io_hi = 0;
+ if ((hi >= 0) && (hi <= 6))
+ io_hi = pci_resource_start (dev, hi);
+ else if (hi > 6)
+ io_lo += hi; /* Reinterpret the meaning of
+ "hi" as an offset (see SYBA
+ def.) */
+ /* TODO: test if sharing interrupts works */
+ printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
+ "I/O at %#lx(%#lx)\n",
+ parport_serial_pci_tbl[i].vendor,
+ parport_serial_pci_tbl[i].device, io_lo, io_hi);
+ priv->port = parport_pc_probe_port (io_lo, io_hi,
+ PARPORT_IRQ_NONE,
+ PARPORT_DMA_NONE, dev);
+ if (priv->port)
+ success = 1;
+ }
+
+ return success ? 0 : 1;
+}
+
+static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct parport_serial_private *priv;
+ int err;
+
+ priv = kmalloc (sizeof *priv, GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ priv->num = 0;
+ pci_set_drvdata (dev, priv);
+
+ err = pci_enable_device (dev);
+ if (err) {
+ pci_set_drvdata (dev, NULL);
+ kfree (priv);
+ return err;
+ }
+
+ if (serial_register (dev, id) + parport_register (dev, id)) {
+ pci_set_drvdata (dev, NULL);
+ kfree (priv);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void __devexit parport_serial_pci_remove (struct pci_dev *dev)
+{
+ struct parport_serial_private *priv = pci_get_drvdata (dev);
+ int i;
+
+ for (i = 0; i < priv->num; i++) {
+ unregister_serial (priv->line[i]);
+
+ if (priv->ser.init_fn)
+ (priv->ser.init_fn) (dev, &priv->ser, 0);
+ }
+
+ parport_unregister_port (priv->port);
+
+ pci_set_drvdata (dev, NULL);
+ kfree (priv);
+ return;
+}
+
+static struct pci_driver parport_serial_pci_driver = {
+ name: "parport_serial",
+ id_table: parport_serial_pci_tbl,
+ probe: parport_serial_pci_probe,
+ remove: parport_serial_pci_remove,
+};
+
+
+static int __init parport_serial_init (void)
+{
+ return pci_module_init (&parport_serial_pci_driver);
+}
+
+static void __exit parport_serial_exit (void)
+{
+ pci_unregister_driver (&parport_serial_pci_driver);
+ return;
+}
+
+MODULE_AUTHOR("Tim Waugh <[email protected]>");
+MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards");
+
+module_init(parport_serial_init);
+module_exit(parport_serial_exit);
--- linux/Documentation/Configure.help.multiio Thu Apr 19 16:51:40 2001
+++ linux/Documentation/Configure.help Thu Apr 19 16:53:47 2001
@@ -3695,6 +3695,11 @@
If unsure, say Y.
+Parallel+serial PCI card support
+CONFIG_PARPORT_SERIAL
+ You should say Y here. If you say M, the module will be called
+ parport_serial.o.
+
Use FIFO/DMA if available
CONFIG_PARPORT_PC_FIFO
Many parallel port chipsets provide hardware that can speed up