[OOPS] Help needed for usb semaphore lock in 2.4.20-rc1 (since 2.4.13)

From: Duncan Haldane (f.duncan.m.haldane@worldnet.att.net)
Date: Thu Nov 14 2002 - 00:08:19 EST


I am the current maintainer of the cpia webcam driver.

I am tracking down a kernel Oops in 2.4.20-rc1 that was first
introduced in 2.4.13 by usb semaphore locking changes in usb.c,
and which was reported a while back on this list. See:
The Ooops occurs when the system boots if usb, video4linux ,
cpia and cpia_usb are compiled into the kernel.
There is no problem if they are compiled as modules.

No changes in the cpia drivers occurred when the Ooops was
introduced in 2.4.13. usb_cpia-init() in drivers/media/video/cpia_usb.c
calls usb_register() in drivers/usb/usb.c to register itself. \
usb_register() calls usb_scan_devices(). The Oops occurs when
the usb list is locked in usb_scan_devices(), by a call to
" down (&usb_bus_list_lock);".
The result is: "Unable to handle kernel NULL pointer dereference at
virtual address 00000000","Oops: 0002".

If I comment out the lock, things work again. (no OOPS, cpa works).
So the problem is isolated. Whats the fix?

Assuming this is a usb.c problem , I'm out of my depth here.

Or should some new entries to initialize something be added to
the "static struct usb_driver cpia_driver" declaration in cpia_usb.c below?
Please give me some hints on what to fix if some new initialization
in cpia_usb.c is needed since the 2.4.13 usb semaphore changes.


Please cc me directly:


static struct usb_driver cpia_driver = {
        name: "cpia",
        probe: cpia_probe,
        disconnect: cpia_disconnect,
        id_table: cpia_id_table,
static int __init usb_cpia_init(void)
        cam_list = NULL;
        return usb_register(&cpia_driver);

----(2.4.20-rc2 drivers/usb/usb.c)----------------------------

struct semaphore usb_bus_list_lock;

int usb_register(struct usb_driver *new_driver)
        if (new_driver->fops != NULL) {
                if (usb_minors[new_driver->minor/16]) {
                         err("error registering %s driver", new_driver->name);
                        return -EINVAL;
                usb_minors[new_driver->minor/16] = new_driver;

        info("registered new driver %s", new_driver->name);


        /* Add it to the list of known drivers */
        list_add_tail(&new_driver->driver_list, &usb_driver_list);


        return 0;


void usb_scan_devices(void)
        struct list_head *tmp;

        // down (&usb_bus_list_lock); <= WORKS IF THIS IS COMMENTED OUT!
        tmp = usb_bus_list.next;
        while (tmp != &usb_bus_list) {
                struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list);

                tmp = tmp->next;
        // up (&usb_bus_list_lock); <= WORKS IF THIS IS COMMENTED OUT!


-----------(old (working) lock in 2.4.12 drivers/usb/usb.c)--------------

rwlock_t usb_bus_list_lock = RW_LOCK_UNLOCKED;

        read_lock_irq (&usb_bus_list_lock);
        read_unlock_irq (&usb_bus_list_lock);


E-Mail: Duncan Haldane <f.duncan.m.haldane@worldnet.att.net>
Date: 13-Nov-2002
Time: 23:35:59

This message was sent by XFMail
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

This archive was generated by hypermail 2b29 : Fri Nov 15 2002 - 22:00:32 EST