Dear parport maintainers,
The patch below allows to initialize selected PCI devices by specifying
their bus/slot/function address, via 'io=-1 io_hi=0x<bus><slot><function>'.
Yours sincerely,
Servaas Vandenberghe
--- linux-2.4.23/drivers/parport/parport_pc-sub.c Thu Dec 4 05:34:08 2003
+++ linux-2.4.23/drivers/parport/parport_pc.c Sat Dec 6 02:07:12 2003
@@ -96,6 +96,7 @@
static int user_specified __devinitdata = 0;
static int verbose_probing=0;
static int registered_parport;
+static int parport_pc_pci_autoirq __devinitdata =PARPORT_IRQ_NONE;
/* frob_control, but for ECR */
static void frob_econtrol (struct parport *pb, unsigned char m,
@@ -2968,7 +2969,6 @@
};
MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);
-static int pci_autoirq=PARPORT_IRQ_NONE;
static int __devinit parport_pc_pci_probe (struct pci_dev *dev,
const struct pci_device_id *id)
{
@@ -3001,14 +3001,14 @@
io_lo += hi; /* Reinterpret the meaning of
"hi" as an offset (see SYBA def.) */
/* TODO: test if sharing interrupts works */
- if(pci_autoirq == PARPORT_IRQ_AUTO && dev->irq)
+ if(parport_pc_pci_autoirq == PARPORT_IRQ_AUTO && dev->irq)
irq=dev->irq;
else
irq=PARPORT_IRQ_NONE;
- printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x,"
- " I/O at %#lx(%#lx)\n", id->vendor, id->device,
- io_lo, io_hi);
+ printk (KERN_DEBUG "parport_pc_pci_probe: PCI parallel port"
+ " %04x:%04x, I/O at %#lx(%#lx)\n",
+ id->vendor, id->device, io_lo, io_hi);
if (parport_pc_probe_port (io_lo, io_hi, irq,
PARPORT_DMA_NONE, dev))
count++;
@@ -3017,7 +3017,7 @@
if (cards[i].postinit_hook)
cards[i].postinit_hook (dev, count == 0);
- return count == 0 ? -ENODEV : 0;
+ return(!count ? -ENODEV : count);
}
static struct pci_driver parport_pc_pci_driver = {
@@ -3091,31 +3091,96 @@
/* ISA ports and whatever (see asm/parport.h). */
count += parport_pc_find_nonpci_ports (autoirq, autodma);
-#ifdef CONFIG_PCI
- pci_autoirq=autoirq;
-#endif /* CONFIG_PCI */
+ parport_pc_pci_autoirq=autoirq;
r = pci_register_driver (&parport_pc_pci_driver);
if (r >= 0) {
registered_parport = 1;
- count += r;
+ count += r; /* number of claimed PCI devices <=parports */
}
return count;
}
+/* PCI mode
+ * io = -1
+ * io_hi= 0x<bus><slot><func>
+ * where
+ * bus = bus number 0x00 .. 0xff
+ * slot = phys slot 0x00 .. 0x1f
+ * function= chip function 0 .. 7
+ * e.g. 02:0c.0 --> io=-1 io_hi=0x020c00
+ * note
+ * devfn= bit mapped slot/function address of the device
+ * bits 7:3=slot 2:0=function (02:0c.0 -> 0x0260)
+ */
int __init parport_pc_init (int *io, int *io_hi, int *irq, int *dma)
{
- int count = 0, i = 0;
+ int count = 0;
if (io && *io) {
+ int i = 0;
/* Only probe the ports we were given. */
user_specified = 1;
do {
- if ((*io_hi) == PARPORT_IOHI_AUTO)
+ if(*io == -1) { /* PCI mode */
+#ifdef CONFIG_PCI
+ struct pci_dev *dev;
+ const struct pci_device_id *id;
+ unsigned bus, slot, func, devfn;
+ int err;
+
+ if(*io_hi == PARPORT_IOHI_AUTO) {
+ printk (KERN_WARNING "parport_pc: bad PCI io_hi=%d\n", *io_hi);
+ goto pci_end;
+ }
+
+ bus = (unsigned )*io_hi;
+ func = bus & 0xff;
+ bus>>= 8;
+ slot = bus & 0xff;
+ bus>>= 8;
+ devfn=PCI_DEVFN(slot, func);
+
+ dev=pci_find_slot(bus, devfn);
+ if(!dev) {
+ printk (KERN_WARNING "parport_pc: no PCI dev at"
+ " %02x:%02x.%02x (:%02x)\n", bus, slot, func, devfn);
+ goto pci_end;
+ }
+
+ id=pci_match_device(parport_pc_pci_tbl, dev);
+ if(!id) {
+ printk (KERN_WARNING "parport_pc: unknown PCI dev"
+ " %02x:%02x.%02x (:%02x) %04x:%04x\n",
+ bus, slot, func, devfn, dev->vendor, dev->device);
+ goto pci_end;
+ }
+
+ parport_pc_pci_autoirq=*irq;
+ err=parport_pc_pci_probe(dev, id);
+ if(err<0) {
+ printk (KERN_WARNING "parport_pc: failed PCI dev"
+ " %02x:%02x.%02x (:%02x) dev=%04x:%04x id=%04x:%04x\n",
+ bus, slot, func, devfn, dev->vendor, dev->device,
+ id->vendor, id->device);
+ goto pci_end;
+ }
+ count+=err;
+
+ pci_end:
+#else
+ printk (KERN_WARNING "parport_pc: No PCI support\n")
+#endif /* CONFIG_PCI */
+ } else {
+ if (*io_hi == PARPORT_IOHI_AUTO)
*io_hi = 0x400 + *io;
- if (parport_pc_probe_port(*(io++), *(io_hi++),
- *(irq++), *(dma++), NULL))
+ if (parport_pc_probe_port(*io, *io_hi, *irq, *dma, NULL))
count++;
+ }
+ io++;
+ io_hi++;
+ irq++;
+ dma++;
} while (*io && (++i < PARPORT_PC_MAX_PORTS));
} else {
count += parport_pc_find_ports (irq[0], dma[0]);
-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --
This archive was generated by hypermail 2b29 : Thu Dec 11 2003 - 17:53:22 EST