Commit d73cb0ca authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

[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.
parent 3dba28d8
/*
* 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 @@ MODULE_DEVICE_TABLE (usb, skel_table);
#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 */
......@@ -118,7 +110,7 @@ struct usb_skel {
__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 */
int open; /* if the port is open or not */
struct semaphore sem; /* locks this structure */
};
......@@ -139,13 +131,6 @@ static void skel_disconnect (struct usb_interface *intf);
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 usb_skel_debug_data (const char *function, int size, const un
*/
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 inline void skel_delete (struct usb_skel *dev)
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)) {
subminor = minor (inode->i_rdev);
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;
}
/* 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;
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 @@ static int skel_release (struct inode *inode, struct file *file)
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 @@ static int skel_release (struct inode *inode, struct file *file)
/* 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;
}
/* 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 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
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 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
goto exit_minor;
}
memset (dev, 0x00, sizeof (*dev));
minor_table[minor] = dev;
init_MUTEX (&dev->sem);
dev->udev = udev;
......@@ -600,13 +560,17 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
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 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
usb_deregister_dev (1, minor);
exit:
up (&minor_table_mutex);
if (dev) {
dev_set_drvdata (&interface->dev, dev);
return 0;
......@@ -642,9 +605,11 @@ static void skel_disconnect(struct usb_interface *interface)
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 @@ static void skel_disconnect(struct usb_interface *interface)
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 @@ static void skel_disconnect(struct usb_interface *interface)
}
info("USB Skeleton #%d now disconnected", minor);
up (&minor_table_mutex);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment