*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000)
MODULE_DEVICE_TABLE(usb, idmouse_table);
+static DEFINE_MUTEX(open_disc_mutex);
/* structure to hold all of our device specific stuff */
struct usb_idmouse {
int open; /* if the port is open or not */
int present; /* if the device is not disconnected */
- struct semaphore sem; /* locks this structure */
+ struct mutex lock; /* locks this structure */
};
static void idmouse_disconnect(struct usb_interface *interface);
/* file operation pointers */
-static struct file_operations idmouse_fops = {
+static const struct file_operations idmouse_fops = {
.owner = THIS_MODULE,
.read = idmouse_read,
.open = idmouse_open,
.id_table = idmouse_table,
};
-/* prevent races between open() and disconnect() */
-static DECLARE_MUTEX(disconnect_sem);
-
static int idmouse_create_image(struct usb_idmouse *dev)
{
- int bytes_read = 0;
- int bulk_read = 0;
- int result = 0;
+ int bytes_read;
+ int bulk_read;
+ int result;
memcpy(dev->bulk_in_buffer, HEADER, sizeof(HEADER)-1);
- bytes_read += sizeof(HEADER)-1;
+ bytes_read = sizeof(HEADER)-1;
/* reset the device and set a fast blink rate */
result = ftip_command(dev, FTIP_RELEASE, 0, 0);
static int idmouse_open(struct inode *inode, struct file *file)
{
- struct usb_idmouse *dev = NULL;
+ struct usb_idmouse *dev;
struct usb_interface *interface;
- int result = 0;
-
- /* prevent disconnects */
- down(&disconnect_sem);
+ int result;
/* get the interface from minor number and driver information */
interface = usb_find_interface (&idmouse_driver, iminor (inode));
- if (!interface) {
- up(&disconnect_sem);
+ if (!interface)
return -ENODEV;
- }
+
+ mutex_lock(&open_disc_mutex);
/* get the device information block from the interface */
dev = usb_get_intfdata(interface);
if (!dev) {
- up(&disconnect_sem);
+ mutex_unlock(&open_disc_mutex);
return -ENODEV;
}
/* lock this device */
- down(&dev->sem);
+ mutex_lock(&dev->lock);
+ mutex_unlock(&open_disc_mutex);
/* check if already open */
if (dev->open) {
error:
/* unlock this device */
- up(&dev->sem);
-
- /* unlock the disconnect semaphore */
- up(&disconnect_sem);
+ mutex_unlock(&dev->lock);
return result;
}
{
struct usb_idmouse *dev;
- /* prevent a race condition with open() */
- down(&disconnect_sem);
-
- dev = (struct usb_idmouse *) file->private_data;
+ dev = file->private_data;
- if (dev == NULL) {
- up(&disconnect_sem);
+ if (dev == NULL)
return -ENODEV;
- }
+ mutex_lock(&open_disc_mutex);
/* lock our device */
- down(&dev->sem);
+ mutex_lock(&dev->lock);
/* are we really open? */
if (dev->open <= 0) {
- up(&dev->sem);
- up(&disconnect_sem);
+ mutex_unlock(&dev->lock);
+ mutex_unlock(&open_disc_mutex);
return -ENODEV;
}
if (!dev->present) {
/* the device was unplugged before the file was released */
- up(&dev->sem);
+ mutex_unlock(&dev->lock);
+ mutex_unlock(&open_disc_mutex);
idmouse_delete(dev);
- up(&disconnect_sem);
- return 0;
+ } else {
+ mutex_unlock(&dev->lock);
+ mutex_unlock(&open_disc_mutex);
}
-
- up(&dev->sem);
- up(&disconnect_sem);
return 0;
}
static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count,
loff_t * ppos)
{
- struct usb_idmouse *dev;
- int result = 0;
-
- dev = (struct usb_idmouse *) file->private_data;
+ struct usb_idmouse *dev = file->private_data;
+ int result;
/* lock this object */
- down (&dev->sem);
+ mutex_lock(&dev->lock);
/* verify that the device wasn't unplugged */
if (!dev->present) {
- up (&dev->sem);
+ mutex_unlock(&dev->lock);
return -ENODEV;
}
result = simple_read_from_buffer(buffer, count, ppos,
dev->bulk_in_buffer, IMGSIZE);
/* unlock the device */
- up(&dev->sem);
+ mutex_unlock(&dev->lock);
return result;
}
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
- struct usb_idmouse *dev = NULL;
+ struct usb_idmouse *dev;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int result;
return -ENODEV;
/* allocate memory for our device state and initialize it */
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL)
return -ENOMEM;
- memset(dev, 0x00, sizeof(*dev));
- init_MUTEX(&dev->sem);
+ mutex_init(&dev->lock);
dev->udev = udev;
dev->interface = interface;
/* set up the endpoint information - use only the first bulk-in endpoint */
endpoint = &iface_desc->endpoint[0].desc;
- if (!dev->bulk_in_endpointAddr
- && (endpoint->bEndpointAddress & USB_DIR_IN)
- && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_BULK)) {
-
+ if (!dev->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) {
/* we found a bulk in endpoint */
dev->orig_bi_size = le16_to_cpu(endpoint->wMaxPacketSize);
dev->bulk_in_size = 0x200; /* works _much_ faster */
{
struct usb_idmouse *dev;
- /* prevent races with open() */
- down(&disconnect_sem);
-
/* get device structure */
dev = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
-
- /* lock it */
- down(&dev->sem);
/* give back our minor */
usb_deregister_dev(interface, &idmouse_class);
+ mutex_lock(&open_disc_mutex);
+ usb_set_intfdata(interface, NULL);
+ /* lock the device */
+ mutex_lock(&dev->lock);
+ mutex_unlock(&open_disc_mutex);
+
/* prevent device read, write and ioctl */
dev->present = 0;
- /* unlock */
- up(&dev->sem);
-
/* if the device is opened, idmouse_release will clean this up */
- if (!dev->open)
+ if (!dev->open) {
+ mutex_unlock(&dev->lock);
idmouse_delete(dev);
-
- up(&disconnect_sem);
+ } else {
+ /* unlock */
+ mutex_unlock(&dev->lock);
+ }
info("%s disconnected", DRIVER_DESC);
}