Re: pci_probe function is atomic?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, May 04, 2009 at 10:14:08PM +0530, arun c wrote:
> On Mon, May 4, 2009 at 9:40 PM, Greg KH <greg@xxxxxxxxx> wrote:
> > On Mon, May 04, 2009 at 09:16:54PM +0530, arun c wrote:
> >> On Mon, May 4, 2009 at 8:19 PM, Greg KH <greg@xxxxxxxxx> wrote:
> >> > On Mon, May 04, 2009 at 12:47:44PM +0530, arun c wrote:
> >> >> Hi all,
> >> >>
> >> >> I have a dual core system(I am running kernel  2.6.22, 2.6.16, or 2.6.27  ),
> >> >> where I can put a maximum of 8 similar PCI cards.
> >> >>
> >> >> So in my driver I register ('pci_register_driver()') with device ID and
> >> >> vender ID(same for all 8 cards).
> >> >>
> >> >> I need to access a global data from the probe functions. If there are
> >> >> 8 PCI devices detected probe function is called one after another?
> >> >>
> >> >> or is there any chance that they execute in parallel?
> >> >
> >> > Yes, in the future (and in some types of configurations today), it could
> >> > execute in parallel.
> >> >
> >> > Just use a lock to control access to your shared global data structure.
> >> >
> >> > But you might wish to revisit your usage of global data, why can't it be
> >> > a per-device field that is dynamically created for every individual
> >> > device?  That would scale much better, right?
> >>
> >> I am using a character device interface to talk to my devices.
> >> only one character driver controlling all the PCI devices.
> >
> > Only 1?  That seems like a design mistake :)
> 
> But LDD3 says "but most devices that you will see are still organized on the
> one-major-one-driver principle", that's why I decided to use one major
> no for all the devices

One major is fine.

One minor isn't :)

> And my module init looks like this
> 
> static int __init my_init_module(void)
> {
>         struct cdev *cdev = &my_cdev; /* defined global */
>         dev_t dev_id;
>         int err;
> 
>         if (major) {
>                 dev_id = MKDEV(major, 0);
>                 err = register_chrdev_region(dev_id, 32, DEVICE_NAME);
>         } else {
>                 err = alloc_chrdev_region(&dev_id, 0, 32, DEVICE_NAME);
>                 major = MAJOR(dev_id);
>         }
> 
>         if (err)
>                 return err;
> 
>         cdev_init(cdev, &my_fops);
>         cdev->owner = THIS_MODULE;
>         cdev->ops = &my_fops;
>         err = cdev_add(cdev, dev_id, 32);
>         if (err)
>                 return err;
>         err = pci_register_driver(&my_pci_driver);
>         if (err)
>                  goto clean_cdev;
> 
>         return 0;
> 
> clean_cdev:
>         cdev_del(cdev);
>         unregister_chrdev_region(dev_id, 32);
>         return err;
> 
> Are you saying that this is wrong?, and I should use only
> pci_register_driver() in my init module and use individual
> character drivers for all the pci devices probed?

Ok, no, this makes a bit more sense, although you are limiting yourself
to 32 total devices in the system.

So yes, you will need a lock to protect you giving out your minor
numbers to individual devices.

Just curious, what type of device is this that you are creating a new
major device number for?  I thought we pretty much cover all types of
devices with different subsystems in the kernel today.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux