ChangeSet 1.876, 2002/12/12 14:49:26-08:00, greg@kroah.com [PATCH] USB: usb-skeleton: removed static array of devices. This allowed a lock to be removed. Also removed the MOD_* functions, and some remove logic was cleaned up by Oliver Neukum. diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c --- a/drivers/usb/usb-skeleton.c Fri Dec 13 17:18:45 2002 +++ b/drivers/usb/usb-skeleton.c Fri Dec 13 17:18:45 2002 @@ -1,5 +1,5 @@ /* - * USB Skeleton driver - 0.8 + * USB Skeleton driver - 0.9 * * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com) * @@ -17,10 +17,10 @@ * * TODO: * - fix urb->status race condition in write sequence - * - move minor_table to a dynamic list. * * History: * + * 2002_12_12 - 0.9 - compile fixes and got rid of fixed minor array. * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device * driver. * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do @@ -83,18 +83,10 @@ #ifdef CONFIG_USB_DYNAMIC_MINORS -/* - * if the user wants to use dynamic minor numbers, then we can have up to 256 - * devices - */ #define USB_SKEL_MINOR_BASE 0 -#define MAX_DEVICES 256 #else /* Get a minor range for your devices from the usb maintainer */ #define USB_SKEL_MINOR_BASE 200 - -/* we can have up to this number of device plugged in at once */ -#define MAX_DEVICES 16 #endif /* Structure to hold all of our device specific stuff */ @@ -117,8 +109,8 @@ struct urb * write_urb; /* the urb used to send data */ __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ - struct work_struct work; /* work queue entry for line discipline waking up */ - int open_count; /* number of times this port has been opened */ + struct work_struct work; /* work queue entry for line discipline waking up */ + int open; /* if the port is open or not */ struct semaphore sem; /* locks this structure */ }; @@ -139,13 +131,6 @@ static void skel_write_bulk_callback (struct urb *urb, struct pt_regs *regs); - -/* array of pointers to our devices that are currently connected */ -static struct usb_skel *minor_table[MAX_DEVICES]; - -/* lock to protect the minor_table structure */ -static DECLARE_MUTEX (minor_table_mutex); - /* * File operations needed when we register this driver. * This assumes that this driver NEEDS file operations, @@ -218,7 +203,6 @@ */ static inline void skel_delete (struct usb_skel *dev) { - minor_table[dev->minor] = NULL; if (dev->bulk_in_buffer != NULL) kfree (dev->bulk_in_buffer); if (dev->bulk_out_buffer != NULL) @@ -235,41 +219,31 @@ static int skel_open (struct inode *inode, struct file *file) { struct usb_skel *dev = NULL; + struct usb_interface *interface; int subminor; int retval = 0; dbg("%s", __FUNCTION__); - subminor = minor (inode->i_rdev) - USB_SKEL_MINOR_BASE; - if ((subminor < 0) || - (subminor >= MAX_DEVICES)) { - return -ENODEV; - } + subminor = minor (inode->i_rdev); - /* Increment our usage count for the module. - * This is redundant here, because "struct file_operations" - * has an "owner" field. This line is included here soley as - * a reference for drivers using lesser structures... ;-) - */ - MOD_INC_USE_COUNT; - - /* lock our minor table and get our local data for this minor */ - down (&minor_table_mutex); - dev = minor_table[subminor]; - if (dev == NULL) { - up (&minor_table_mutex); - MOD_DEC_USE_COUNT; + interface = usb_find_interface (&skel_driver, + mk_kdev(USB_MAJOR, subminor)); + if (!interface) { + err ("%s - error, can't find device for minor %d", + __FUNCTION__, subminor); return -ENODEV; } + + dev = dev_get_drvdata (&interface->dev); + if (!dev) + return -ENODEV; /* lock this device */ down (&dev->sem); - /* unlock the minor table */ - up (&minor_table_mutex); - /* increment our usage count for the driver */ - ++dev->open_count; + ++dev->open; /* save our object in the file's private structure */ file->private_data = dev; @@ -297,13 +271,10 @@ dbg("%s - minor %d", __FUNCTION__, dev->minor); - /* lock our minor table */ - down (&minor_table_mutex); - /* lock our device */ down (&dev->sem); - if (dev->open_count <= 0) { + if (dev->open <= 0) { dbg ("%s - device not opened", __FUNCTION__); retval = -ENODEV; goto exit_not_opened; @@ -313,25 +284,16 @@ /* the device was unplugged before the file was released */ up (&dev->sem); skel_delete (dev); - up (&minor_table_mutex); - MOD_DEC_USE_COUNT; return 0; } - /* decrement our usage count for the device */ - --dev->open_count; - if (dev->open_count <= 0) { - /* shutdown any bulk writes that might be going on */ - usb_unlink_urb (dev->write_urb); - dev->open_count = 0; - } + /* shutdown any bulk writes that might be going on */ + usb_unlink_urb (dev->write_urb); - /* decrement our usage count for the module */ - MOD_DEC_USE_COUNT; + dev->open = 0; exit_not_opened: up (&dev->sem); - up (&minor_table_mutex); return retval; } @@ -529,7 +491,6 @@ return -ENODEV; } - down (&minor_table_mutex); retval = usb_register_dev (&skel_fops, USB_SKEL_MINOR_BASE, 1, &minor); if (retval) { /* something prevented us from registering this driver */ @@ -544,7 +505,6 @@ goto exit_minor; } memset (dev, 0x00, sizeof (*dev)); - minor_table[minor] = dev; init_MUTEX (&dev->sem); dev->udev = udev; @@ -600,13 +560,17 @@ dev->devfs = devfs_register (usb_devfs_handle, name, DEVFS_FL_DEFAULT, USB_MAJOR, - USB_SKEL_MINOR_BASE + dev->minor, + dev->minor, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, &skel_fops, NULL); /* let the user know what node this device is now attached to */ info ("USB Skeleton device now attached to USBSkel%d", dev->minor); + + /* add device id so the device works when advertised */ + interface->kdev = mk_kdev(USB_MAJOR, dev->minor); + goto exit; error: @@ -617,7 +581,6 @@ usb_deregister_dev (1, minor); exit: - up (&minor_table_mutex); if (dev) { dev_set_drvdata (&interface->dev, dev); return 0; @@ -642,9 +605,11 @@ if (!dev) return; - down (&minor_table_mutex); down (&dev->sem); + /* remove device id to disable open() */ + interface->kdev = NODEV; + minor = dev->minor; /* remove our devfs node */ @@ -654,7 +619,7 @@ usb_deregister_dev (1, minor); /* if the device is not opened, then we clean up right now */ - if (!dev->open_count) { + if (!dev->open) { up (&dev->sem); skel_delete (dev); } else { @@ -663,7 +628,6 @@ } info("USB Skeleton #%d now disconnected", minor); - up (&minor_table_mutex); }