[PARPORT] [patch] selective PCI initialization

From: vdb128@stargate.kotnet.org
Date: Thu Dec 11 2003 - 17:51:22 EST

  • Next message: vdb128@stargate.kotnet.org: "[PARPORT] [patch] PCI shared INTX# lockup solved 0/2"

    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