MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
static struct usb_driver iowarrior_driver;
+static DEFINE_MUTEX(iowarrior_open_disc_lock);
/*--------------*/
/* data */
/*--------------*/
/* globals */
/*--------------*/
-/* prevent races between open() and disconnect() */
-static DECLARE_MUTEX(disconnect_sem);
/*
* USB spec identifies 5 second timeouts.
*/
static void iowarrior_callback(struct urb *urb)
{
- struct iowarrior *dev = (struct iowarrior *)urb->context;
+ struct iowarrior *dev = urb->context;
int intr_idx;
int read_idx;
int aux_idx;
int offset;
- int status;
+ int status = urb->status;
+ int retval;
- switch (urb->status) {
+ switch (status) {
case 0:
/* success */
break;
wake_up_interruptible(&dev->read_wait);
exit:
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status)
- dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d",
- __FUNCTION__, status);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n",
+ __func__, retval);
}
static void iowarrior_write_callback(struct urb *urb)
{
struct iowarrior *dev;
- dev = (struct iowarrior *)urb->context;
+ int status = urb->status;
+
+ dev = urb->context;
/* sync/async unlink faults aren't errors */
- if (urb->status &&
- !(urb->status == -ENOENT ||
- urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) {
+ if (status &&
+ !(status == -ENOENT ||
+ status == -ECONNRESET || status == -ESHUTDOWN)) {
dbg("%s - nonzero write bulk status received: %d",
- __func__, urb->status);
+ __func__, status);
}
/* free up our allocated buffer */
usb_buffer_free(urb->dev, urb->transfer_buffer_length,
mutex_lock(&dev->mutex);
/* verify that the device wasn't unplugged */
- if (dev == NULL || !dev->present) {
+ if (!dev->present) {
retval = -ENODEV;
goto exit;
}
break;
default:
/* what do we have here ? An unsupported Product-ID ? */
- dev_err(&dev->interface->dev, "%s - not supported for product=0x%x",
- __FUNCTION__, dev->product_id);
+ dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n",
+ __func__, dev->product_id);
retval = -EFAULT;
goto exit;
break;
} else {
retval = -EINVAL;
dev_err(&dev->interface->dev,
- "ioctl 'IOW_WRITE' is not supported for product=0x%x.",
+ "ioctl 'IOW_WRITE' is not supported for product=0x%x.\n",
dev->product_id);
}
break;
subminor = iminor(inode);
- /* prevent disconnects */
- down(&disconnect_sem);
-
interface = usb_find_interface(&iowarrior_driver, subminor);
if (!interface) {
- err("%s - error, can't find device for minor %d", __FUNCTION__,
+ err("%s - error, can't find device for minor %d", __func__,
subminor);
- retval = -ENODEV;
- goto out;
+ return -ENODEV;
}
+ mutex_lock(&iowarrior_open_disc_lock);
dev = usb_get_intfdata(interface);
if (!dev) {
- retval = -ENODEV;
- goto out;
+ mutex_unlock(&iowarrior_open_disc_lock);
+ return -ENODEV;
}
+ mutex_lock(&dev->mutex);
+ mutex_unlock(&iowarrior_open_disc_lock);
+
/* Only one process can open each device, no sharing. */
if (dev->opened) {
retval = -EBUSY;
retval = 0;
out:
- up(&disconnect_sem);
+ mutex_unlock(&dev->mutex);
return retval;
}
* would use "struct net_driver" instead, and a serial
* device would use "struct tty_driver".
*/
-static struct file_operations iowarrior_fops = {
+static const struct file_operations iowarrior_fops = {
.owner = THIS_MODULE,
.write = iowarrior_write,
.read = iowarrior_read,
/* allocate memory for our device state and intialize it */
dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
if (dev == NULL) {
- dev_err(&interface->dev, "Out of memory");
+ dev_err(&interface->dev, "Out of memory\n");
return retval;
}
struct iowarrior *dev;
int minor;
- /* prevent races with open() */
- down(&disconnect_sem);
-
dev = usb_get_intfdata(interface);
+ mutex_lock(&iowarrior_open_disc_lock);
usb_set_intfdata(interface, NULL);
- mutex_lock(&dev->mutex);
-
minor = dev->minor;
/* give back our minor */
usb_deregister_dev(interface, &iowarrior_class);
+ mutex_lock(&dev->mutex);
+
/* prevent device read, write and ioctl */
dev->present = 0;
mutex_unlock(&dev->mutex);
+ mutex_unlock(&iowarrior_open_disc_lock);
if (dev->opened) {
/* There is a process that holds a filedescriptor to the device ,
/* no process is using the device, cleanup now */
iowarrior_delete(dev);
}
- up(&disconnect_sem);
dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
minor - IOWARRIOR_MINOR_BASE);