Commit 4186ecf8 authored by Arjan van de Ven's avatar Arjan van de Ven Committed by Greg Kroah-Hartman

[PATCH] USB: convert a bunch of USB semaphores to mutexes

the patch below converts a bunch of semaphores-used-as-mutex in the USB
code to mutexes
Signed-off-by: default avatarArjan van de Ven <arjan@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 35cce732
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#include <linux/tty_flip.h> #include <linux/tty_flip.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usb_cdc.h> #include <linux/usb_cdc.h>
...@@ -80,7 +81,7 @@ static struct usb_driver acm_driver; ...@@ -80,7 +81,7 @@ static struct usb_driver acm_driver;
static struct tty_driver *acm_tty_driver; static struct tty_driver *acm_tty_driver;
static struct acm *acm_table[ACM_TTY_MINORS]; static struct acm *acm_table[ACM_TTY_MINORS];
static DECLARE_MUTEX(open_sem); static DEFINE_MUTEX(open_mutex);
#define ACM_READY(acm) (acm && acm->dev && acm->used) #define ACM_READY(acm) (acm && acm->dev && acm->used)
...@@ -431,8 +432,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -431,8 +432,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
int rv = -EINVAL; int rv = -EINVAL;
int i; int i;
dbg("Entering acm_tty_open.\n"); dbg("Entering acm_tty_open.\n");
down(&open_sem); mutex_lock(&open_mutex);
acm = acm_table[tty->index]; acm = acm_table[tty->index];
if (!acm || !acm->dev) if (!acm || !acm->dev)
...@@ -474,14 +475,14 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -474,14 +475,14 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
done: done:
err_out: err_out:
up(&open_sem); mutex_unlock(&open_mutex);
return rv; return rv;
full_bailout: full_bailout:
usb_kill_urb(acm->ctrlurb); usb_kill_urb(acm->ctrlurb);
bail_out: bail_out:
acm->used--; acm->used--;
up(&open_sem); mutex_unlock(&open_mutex);
return -EIO; return -EIO;
} }
...@@ -507,7 +508,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) ...@@ -507,7 +508,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
if (!acm || !acm->used) if (!acm || !acm->used)
return; return;
down(&open_sem); mutex_lock(&open_mutex);
if (!--acm->used) { if (!--acm->used) {
if (acm->dev) { if (acm->dev) {
acm_set_control(acm, acm->ctrlout = 0); acm_set_control(acm, acm->ctrlout = 0);
...@@ -518,7 +519,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) ...@@ -518,7 +519,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
} else } else
acm_tty_unregister(acm); acm_tty_unregister(acm);
} }
up(&open_sem); mutex_unlock(&open_mutex);
} }
static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
...@@ -1013,9 +1014,9 @@ static void acm_disconnect(struct usb_interface *intf) ...@@ -1013,9 +1014,9 @@ static void acm_disconnect(struct usb_interface *intf)
return; return;
} }
down(&open_sem); mutex_lock(&open_mutex);
if (!usb_get_intfdata(intf)) { if (!usb_get_intfdata(intf)) {
up(&open_sem); mutex_unlock(&open_mutex);
return; return;
} }
acm->dev = NULL; acm->dev = NULL;
...@@ -1045,11 +1046,11 @@ static void acm_disconnect(struct usb_interface *intf) ...@@ -1045,11 +1046,11 @@ static void acm_disconnect(struct usb_interface *intf)
if (!acm->used) { if (!acm->used) {
acm_tty_unregister(acm); acm_tty_unregister(acm);
up(&open_sem); mutex_unlock(&open_mutex);
return; return;
} }
up(&open_sem); mutex_unlock(&open_mutex);
if (acm->tty) if (acm->tty)
tty_hangup(acm->tty); tty_hangup(acm->tty);
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/lp.h> #include <linux/lp.h>
#include <linux/mutex.h>
#undef DEBUG #undef DEBUG
#include <linux/usb.h> #include <linux/usb.h>
...@@ -223,7 +224,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp); ...@@ -223,7 +224,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp);
/* forward reference to make our lives easier */ /* forward reference to make our lives easier */
static struct usb_driver usblp_driver; static struct usb_driver usblp_driver;
static DECLARE_MUTEX(usblp_sem); /* locks the existence of usblp's */ static DEFINE_MUTEX(usblp_mutex); /* locks the existence of usblp's */
/* /*
* Functions for usblp control messages. * Functions for usblp control messages.
...@@ -351,7 +352,7 @@ static int usblp_open(struct inode *inode, struct file *file) ...@@ -351,7 +352,7 @@ static int usblp_open(struct inode *inode, struct file *file)
if (minor < 0) if (minor < 0)
return -ENODEV; return -ENODEV;
down (&usblp_sem); mutex_lock (&usblp_mutex);
retval = -ENODEV; retval = -ENODEV;
intf = usb_find_interface(&usblp_driver, minor); intf = usb_find_interface(&usblp_driver, minor);
...@@ -399,7 +400,7 @@ static int usblp_open(struct inode *inode, struct file *file) ...@@ -399,7 +400,7 @@ static int usblp_open(struct inode *inode, struct file *file)
} }
} }
out: out:
up (&usblp_sem); mutex_unlock (&usblp_mutex);
return retval; return retval;
} }
...@@ -425,13 +426,13 @@ static int usblp_release(struct inode *inode, struct file *file) ...@@ -425,13 +426,13 @@ static int usblp_release(struct inode *inode, struct file *file)
{ {
struct usblp *usblp = file->private_data; struct usblp *usblp = file->private_data;
down (&usblp_sem); mutex_lock (&usblp_mutex);
usblp->used = 0; usblp->used = 0;
if (usblp->present) { if (usblp->present) {
usblp_unlink_urbs(usblp); usblp_unlink_urbs(usblp);
} else /* finish cleanup from disconnect */ } else /* finish cleanup from disconnect */
usblp_cleanup (usblp); usblp_cleanup (usblp);
up (&usblp_sem); mutex_unlock (&usblp_mutex);
return 0; return 0;
} }
...@@ -1152,7 +1153,7 @@ static void usblp_disconnect(struct usb_interface *intf) ...@@ -1152,7 +1153,7 @@ static void usblp_disconnect(struct usb_interface *intf)
device_remove_file(&intf->dev, &dev_attr_ieee1284_id); device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
down (&usblp_sem); mutex_lock (&usblp_mutex);
down (&usblp->sem); down (&usblp->sem);
usblp->present = 0; usblp->present = 0;
usb_set_intfdata (intf, NULL); usb_set_intfdata (intf, NULL);
...@@ -1166,7 +1167,7 @@ static void usblp_disconnect(struct usb_interface *intf) ...@@ -1166,7 +1167,7 @@ static void usblp_disconnect(struct usb_interface *intf)
if (!usblp->used) if (!usblp->used)
usblp_cleanup (usblp); usblp_cleanup (usblp);
up (&usblp_sem); mutex_unlock (&usblp_mutex);
} }
static struct usb_device_id usblp_ids [] = { static struct usb_device_id usblp_ids [] = {
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/usbdevice_fs.h> #include <linux/usbdevice_fs.h>
#include <linux/mutex.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "usb.h" #include "usb.h"
...@@ -570,7 +571,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte ...@@ -570,7 +571,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte
if (!access_ok(VERIFY_WRITE, buf, nbytes)) if (!access_ok(VERIFY_WRITE, buf, nbytes))
return -EFAULT; return -EFAULT;
down (&usb_bus_list_lock); mutex_lock(&usb_bus_list_lock);
/* print devices for all busses */ /* print devices for all busses */
list_for_each_entry(bus, &usb_bus_list, bus_list) { list_for_each_entry(bus, &usb_bus_list, bus_list) {
/* recurse through all children of the root hub */ /* recurse through all children of the root hub */
...@@ -580,12 +581,12 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte ...@@ -580,12 +581,12 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte
ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0); ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
usb_unlock_device(bus->root_hub); usb_unlock_device(bus->root_hub);
if (ret < 0) { if (ret < 0) {
up(&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
return ret; return ret;
} }
total_written += ret; total_written += ret;
} }
up (&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
return total_written; return total_written;
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/mutex.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
...@@ -93,7 +94,7 @@ struct usb_busmap { ...@@ -93,7 +94,7 @@ struct usb_busmap {
static struct usb_busmap busmap; static struct usb_busmap busmap;
/* used when updating list of hcds */ /* used when updating list of hcds */
DECLARE_MUTEX (usb_bus_list_lock); /* exported only for usbfs */ DEFINE_MUTEX(usb_bus_list_lock); /* exported only for usbfs */
EXPORT_SYMBOL_GPL (usb_bus_list_lock); EXPORT_SYMBOL_GPL (usb_bus_list_lock);
/* used for controlling access to virtual root hubs */ /* used for controlling access to virtual root hubs */
...@@ -761,14 +762,14 @@ static int usb_register_bus(struct usb_bus *bus) ...@@ -761,14 +762,14 @@ static int usb_register_bus(struct usb_bus *bus)
{ {
int busnum; int busnum;
down (&usb_bus_list_lock); mutex_lock(&usb_bus_list_lock);
busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1);
if (busnum < USB_MAXBUS) { if (busnum < USB_MAXBUS) {
set_bit (busnum, busmap.busmap); set_bit (busnum, busmap.busmap);
bus->busnum = busnum; bus->busnum = busnum;
} else { } else {
printk (KERN_ERR "%s: too many buses\n", usbcore_name); printk (KERN_ERR "%s: too many buses\n", usbcore_name);
up(&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
return -E2BIG; return -E2BIG;
} }
...@@ -776,7 +777,7 @@ static int usb_register_bus(struct usb_bus *bus) ...@@ -776,7 +777,7 @@ static int usb_register_bus(struct usb_bus *bus)
bus->controller, "usb_host%d", busnum); bus->controller, "usb_host%d", busnum);
if (IS_ERR(bus->class_dev)) { if (IS_ERR(bus->class_dev)) {
clear_bit(busnum, busmap.busmap); clear_bit(busnum, busmap.busmap);
up(&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
return PTR_ERR(bus->class_dev); return PTR_ERR(bus->class_dev);
} }
...@@ -784,7 +785,7 @@ static int usb_register_bus(struct usb_bus *bus) ...@@ -784,7 +785,7 @@ static int usb_register_bus(struct usb_bus *bus)
/* Add it to the local list of buses */ /* Add it to the local list of buses */
list_add (&bus->bus_list, &usb_bus_list); list_add (&bus->bus_list, &usb_bus_list);
up (&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
usb_notify_add_bus(bus); usb_notify_add_bus(bus);
...@@ -809,9 +810,9 @@ static void usb_deregister_bus (struct usb_bus *bus) ...@@ -809,9 +810,9 @@ static void usb_deregister_bus (struct usb_bus *bus)
* controller code, as well as having it call this when cleaning * controller code, as well as having it call this when cleaning
* itself up * itself up
*/ */
down (&usb_bus_list_lock); mutex_lock(&usb_bus_list_lock);
list_del (&bus->bus_list); list_del (&bus->bus_list);
up (&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
usb_notify_remove_bus(bus); usb_notify_remove_bus(bus);
...@@ -844,14 +845,14 @@ static int register_root_hub (struct usb_device *usb_dev, ...@@ -844,14 +845,14 @@ static int register_root_hub (struct usb_device *usb_dev,
set_bit (devnum, usb_dev->bus->devmap.devicemap); set_bit (devnum, usb_dev->bus->devmap.devicemap);
usb_set_device_state(usb_dev, USB_STATE_ADDRESS); usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
down (&usb_bus_list_lock); mutex_lock(&usb_bus_list_lock);
usb_dev->bus->root_hub = usb_dev; usb_dev->bus->root_hub = usb_dev;
usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
if (retval != sizeof usb_dev->descriptor) { if (retval != sizeof usb_dev->descriptor) {
usb_dev->bus->root_hub = NULL; usb_dev->bus->root_hub = NULL;
up (&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
dev_dbg (parent_dev, "can't read %s device descriptor %d\n", dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
usb_dev->dev.bus_id, retval); usb_dev->dev.bus_id, retval);
return (retval < 0) ? retval : -EMSGSIZE; return (retval < 0) ? retval : -EMSGSIZE;
...@@ -863,7 +864,7 @@ static int register_root_hub (struct usb_device *usb_dev, ...@@ -863,7 +864,7 @@ static int register_root_hub (struct usb_device *usb_dev,
dev_err (parent_dev, "can't register root hub for %s, %d\n", dev_err (parent_dev, "can't register root hub for %s, %d\n",
usb_dev->dev.bus_id, retval); usb_dev->dev.bus_id, retval);
} }
up (&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
if (retval == 0) { if (retval == 0) {
spin_lock_irq (&hcd_root_hub_lock); spin_lock_irq (&hcd_root_hub_lock);
...@@ -1891,9 +1892,9 @@ void usb_remove_hcd(struct usb_hcd *hcd) ...@@ -1891,9 +1892,9 @@ void usb_remove_hcd(struct usb_hcd *hcd)
hcd->rh_registered = 0; hcd->rh_registered = 0;
spin_unlock_irq (&hcd_root_hub_lock); spin_unlock_irq (&hcd_root_hub_lock);
down(&usb_bus_list_lock); mutex_lock(&usb_bus_list_lock);
usb_disconnect(&hcd->self.root_hub); usb_disconnect(&hcd->self.root_hub);
up(&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
hcd->poll_rh = 0; hcd->poll_rh = 0;
del_timer_sync(&hcd->rh_timer); del_timer_sync(&hcd->rh_timer);
......
...@@ -364,7 +364,7 @@ extern void usb_set_device_state(struct usb_device *udev, ...@@ -364,7 +364,7 @@ extern void usb_set_device_state(struct usb_device *udev,
/* exported only within usbcore */ /* exported only within usbcore */
extern struct list_head usb_bus_list; extern struct list_head usb_bus_list;
extern struct semaphore usb_bus_list_lock; extern struct mutex usb_bus_list_lock;
extern wait_queue_head_t usb_kill_urb_queue; extern wait_queue_head_t usb_kill_urb_queue;
extern struct usb_bus *usb_bus_get (struct usb_bus *bus); extern struct usb_bus *usb_bus_get (struct usb_bus *bus);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usbdevice_fs.h> #include <linux/usbdevice_fs.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/mutex.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -2162,7 +2163,7 @@ static int ...@@ -2162,7 +2163,7 @@ static int
hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
int retry_counter) int retry_counter)
{ {
static DECLARE_MUTEX(usb_address0_sem); static DEFINE_MUTEX(usb_address0_mutex);
struct usb_device *hdev = hub->hdev; struct usb_device *hdev = hub->hdev;
int i, j, retval; int i, j, retval;
...@@ -2183,7 +2184,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, ...@@ -2183,7 +2184,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
if (oldspeed == USB_SPEED_LOW) if (oldspeed == USB_SPEED_LOW)
delay = HUB_LONG_RESET_TIME; delay = HUB_LONG_RESET_TIME;
down(&usb_address0_sem); mutex_lock(&usb_address0_mutex);
/* Reset the device; full speed may morph to high speed */ /* Reset the device; full speed may morph to high speed */
retval = hub_port_reset(hub, port1, udev, delay); retval = hub_port_reset(hub, port1, udev, delay);
...@@ -2381,7 +2382,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, ...@@ -2381,7 +2382,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
fail: fail:
if (retval) if (retval)
hub_port_disable(hub, port1, 0); hub_port_disable(hub, port1, 0);
up(&usb_address0_sem); mutex_unlock(&usb_address0_mutex);
return retval; return retval;
} }
......
...@@ -13,16 +13,17 @@ ...@@ -13,16 +13,17 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/mutex.h>
#include "usb.h" #include "usb.h"
static struct notifier_block *usb_notifier_list; static struct notifier_block *usb_notifier_list;
static DECLARE_MUTEX(usb_notifier_lock); static DEFINE_MUTEX(usb_notifier_lock);
static void usb_notifier_chain_register(struct notifier_block **list, static void usb_notifier_chain_register(struct notifier_block **list,
struct notifier_block *n) struct notifier_block *n)
{ {
down(&usb_notifier_lock); mutex_lock(&usb_notifier_lock);
while (*list) { while (*list) {
if (n->priority > (*list)->priority) if (n->priority > (*list)->priority)
break; break;
...@@ -30,13 +31,13 @@ static void usb_notifier_chain_register(struct notifier_block **list, ...@@ -30,13 +31,13 @@ static void usb_notifier_chain_register(struct notifier_block **list,
} }
n->next = *list; n->next = *list;
*list = n; *list = n;
up(&usb_notifier_lock); mutex_unlock(&usb_notifier_lock);
} }
static void usb_notifier_chain_unregister(struct notifier_block **nl, static void usb_notifier_chain_unregister(struct notifier_block **nl,
struct notifier_block *n) struct notifier_block *n)
{ {
down(&usb_notifier_lock); mutex_lock(&usb_notifier_lock);
while ((*nl)!=NULL) { while ((*nl)!=NULL) {
if ((*nl)==n) { if ((*nl)==n) {
*nl = n->next; *nl = n->next;
...@@ -45,7 +46,7 @@ static void usb_notifier_chain_unregister(struct notifier_block **nl, ...@@ -45,7 +46,7 @@ static void usb_notifier_chain_unregister(struct notifier_block **nl,
nl=&((*nl)->next); nl=&((*nl)->next);
} }
exit: exit:
up(&usb_notifier_lock); mutex_unlock(&usb_notifier_lock);
} }
static int usb_notifier_call_chain(struct notifier_block **n, static int usb_notifier_call_chain(struct notifier_block **n,
...@@ -54,7 +55,7 @@ static int usb_notifier_call_chain(struct notifier_block **n, ...@@ -54,7 +55,7 @@ static int usb_notifier_call_chain(struct notifier_block **n,
int ret=NOTIFY_DONE; int ret=NOTIFY_DONE;
struct notifier_block *nb = *n; struct notifier_block *nb = *n;
down(&usb_notifier_lock); mutex_lock(&usb_notifier_lock);
while (nb) { while (nb) {
ret = nb->notifier_call(nb,val,v); ret = nb->notifier_call(nb,val,v);
if (ret&NOTIFY_STOP_MASK) { if (ret&NOTIFY_STOP_MASK) {
...@@ -63,7 +64,7 @@ static int usb_notifier_call_chain(struct notifier_block **n, ...@@ -63,7 +64,7 @@ static int usb_notifier_call_chain(struct notifier_block **n,
nb = nb->next; nb = nb->next;
} }
exit: exit:
up(&usb_notifier_lock); mutex_unlock(&usb_notifier_lock);
return ret; return ret;
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/mutex.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
...@@ -639,7 +640,7 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id) ...@@ -639,7 +640,7 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id)
struct usb_bus *bus; struct usb_bus *bus;
struct usb_device *dev = NULL; struct usb_device *dev = NULL;
down(&usb_bus_list_lock); mutex_lock(&usb_bus_list_lock);
for (buslist = usb_bus_list.next; for (buslist = usb_bus_list.next;
buslist != &usb_bus_list; buslist != &usb_bus_list;
buslist = buslist->next) { buslist = buslist->next) {
...@@ -653,7 +654,7 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id) ...@@ -653,7 +654,7 @@ struct usb_device *usb_find_device(u16 vendor_id, u16 product_id)
goto exit; goto exit;
} }
exit: exit:
up(&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
return dev; return dev;
} }
......
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/fs.h> #include <linux/fs.h>
...@@ -169,7 +170,7 @@ struct mdc800_data ...@@ -169,7 +170,7 @@ struct mdc800_data
int out_count; // Bytes in the buffer int out_count; // Bytes in the buffer
int open; // Camera device open ? int open; // Camera device open ?
struct semaphore io_lock; // IO -lock struct mutex io_lock; // IO -lock
char in [8]; // Command Input Buffer char in [8]; // Command Input Buffer
int in_count; int in_count;
...@@ -497,7 +498,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, ...@@ -497,7 +498,7 @@ static int mdc800_usb_probe (struct usb_interface *intf,
info ("Found Mustek MDC800 on USB."); info ("Found Mustek MDC800 on USB.");
down (&mdc800->io_lock); mutex_lock(&mdc800->io_lock);
retval = usb_register_dev(intf, &mdc800_class); retval = usb_register_dev(intf, &mdc800_class);
if (retval) { if (retval) {
...@@ -542,7 +543,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, ...@@ -542,7 +543,7 @@ static int mdc800_usb_probe (struct usb_interface *intf,
mdc800->state=READY; mdc800->state=READY;
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
usb_set_intfdata(intf, mdc800); usb_set_intfdata(intf, mdc800);
return 0; return 0;
...@@ -620,7 +621,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file) ...@@ -620,7 +621,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file)
int retval=0; int retval=0;
int errn=0; int errn=0;
down (&mdc800->io_lock); mutex_lock(&mdc800->io_lock);
if (mdc800->state == NOT_CONNECTED) if (mdc800->state == NOT_CONNECTED)
{ {
...@@ -656,7 +657,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file) ...@@ -656,7 +657,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file)
dbg ("Mustek MDC800 device opened."); dbg ("Mustek MDC800 device opened.");
error_out: error_out:
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return errn; return errn;
} }
...@@ -669,7 +670,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file) ...@@ -669,7 +670,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file)
int retval=0; int retval=0;
dbg ("Mustek MDC800 device closed."); dbg ("Mustek MDC800 device closed.");
down (&mdc800->io_lock); mutex_lock(&mdc800->io_lock);
if (mdc800->open && (mdc800->state != NOT_CONNECTED)) if (mdc800->open && (mdc800->state != NOT_CONNECTED))
{ {
usb_kill_urb(mdc800->irq_urb); usb_kill_urb(mdc800->irq_urb);
...@@ -682,7 +683,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file) ...@@ -682,7 +683,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file)
retval=-EIO; retval=-EIO;
} }
up(&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return retval; return retval;
} }
...@@ -695,21 +696,21 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l ...@@ -695,21 +696,21 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l
size_t left=len, sts=len; /* single transfer size */ size_t left=len, sts=len; /* single transfer size */
char __user *ptr = buf; char __user *ptr = buf;
down (&mdc800->io_lock); mutex_lock(&mdc800->io_lock);
if (mdc800->state == NOT_CONNECTED) if (mdc800->state == NOT_CONNECTED)
{ {
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EBUSY; return -EBUSY;
} }
if (mdc800->state == WORKING) if (mdc800->state == WORKING)
{ {
warn ("Illegal State \"working\" reached during read ?!"); warn ("Illegal State \"working\" reached during read ?!");
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EBUSY; return -EBUSY;
} }
if (!mdc800->open) if (!mdc800->open)
{ {
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EBUSY; return -EBUSY;
} }
...@@ -717,7 +718,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l ...@@ -717,7 +718,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l
{ {
if (signal_pending (current)) if (signal_pending (current))
{ {
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EINTR; return -EINTR;
} }
...@@ -736,7 +737,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l ...@@ -736,7 +737,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l
if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL)) if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL))
{ {
err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); err ("Can't submit download urb (status=%i)",mdc800->download_urb->status);
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return len-left; return len-left;
} }
wait_event_timeout(mdc800->download_wait, mdc800->downloaded, wait_event_timeout(mdc800->download_wait, mdc800->downloaded,
...@@ -745,14 +746,14 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l ...@@ -745,14 +746,14 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l
if (mdc800->download_urb->status != 0) if (mdc800->download_urb->status != 0)
{ {
err ("request download-bytes fails (status=%i)",mdc800->download_urb->status); err ("request download-bytes fails (status=%i)",mdc800->download_urb->status);
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return len-left; return len-left;
} }
} }
else else
{ {
/* No more bytes -> that's an error*/ /* No more bytes -> that's an error*/
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EIO; return -EIO;
} }
} }
...@@ -761,7 +762,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l ...@@ -761,7 +762,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l
/* Copy Bytes */ /* Copy Bytes */
if (copy_to_user(ptr, &mdc800->out [mdc800->out_ptr], if (copy_to_user(ptr, &mdc800->out [mdc800->out_ptr],
sts)) { sts)) {
up(&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EFAULT; return -EFAULT;
} }
ptr+=sts; ptr+=sts;
...@@ -770,7 +771,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l ...@@ -770,7 +771,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l
} }
} }
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return len-left; return len-left;
} }
...@@ -785,15 +786,15 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -785,15 +786,15 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
{ {
size_t i=0; size_t i=0;
down (&mdc800->io_lock); mutex_lock(&mdc800->io_lock);
if (mdc800->state != READY) if (mdc800->state != READY)
{ {
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EBUSY; return -EBUSY;
} }
if (!mdc800->open ) if (!mdc800->open )
{ {
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EBUSY; return -EBUSY;
} }
...@@ -802,13 +803,13 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -802,13 +803,13 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
unsigned char c; unsigned char c;
if (signal_pending (current)) if (signal_pending (current))
{ {
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EINTR; return -EINTR;
} }
if(get_user(c, buf+i)) if(get_user(c, buf+i))
{ {
up(&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EFAULT; return -EFAULT;
} }
...@@ -829,7 +830,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -829,7 +830,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
} }
else else
{ {
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EIO; return -EIO;
} }
...@@ -841,7 +842,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -841,7 +842,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
if (mdc800_usb_waitForIRQ (0,TO_GET_READY)) if (mdc800_usb_waitForIRQ (0,TO_GET_READY))
{ {
err ("Camera didn't get ready.\n"); err ("Camera didn't get ready.\n");
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EIO; return -EIO;
} }
...@@ -853,7 +854,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -853,7 +854,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL)) if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL))
{ {
err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); err ("submitting write urb fails (status=%i)", mdc800->write_urb->status);
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EIO; return -EIO;
} }
wait_event_timeout(mdc800->write_wait, mdc800->written, TO_WRITE_GET_READY*HZ/1000); wait_event_timeout(mdc800->write_wait, mdc800->written, TO_WRITE_GET_READY*HZ/1000);
...@@ -861,7 +862,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -861,7 +862,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
if (mdc800->state == WORKING) if (mdc800->state == WORKING)
{ {
usb_kill_urb(mdc800->write_urb); usb_kill_urb(mdc800->write_urb);
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EIO; return -EIO;
} }
...@@ -873,7 +874,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -873,7 +874,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
{ {
err ("call 0x07 before 0x05,0x3e"); err ("call 0x07 before 0x05,0x3e");
mdc800->state=READY; mdc800->state=READY;
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EIO; return -EIO;
} }
mdc800->pic_len=-1; mdc800->pic_len=-1;
...@@ -892,7 +893,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -892,7 +893,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ)) if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ))
{ {
err ("requesting answer from irq fails"); err ("requesting answer from irq fails");
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EIO; return -EIO;
} }
...@@ -920,7 +921,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -920,7 +921,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND)) if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND))
{ {
err ("Command Timeout."); err ("Command Timeout.");
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return -EIO; return -EIO;
} }
} }
...@@ -930,7 +931,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s ...@@ -930,7 +931,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
} }
i++; i++;
} }
up (&mdc800->io_lock); mutex_unlock(&mdc800->io_lock);
return i; return i;
} }
...@@ -984,7 +985,7 @@ static int __init usb_mdc800_init (void) ...@@ -984,7 +985,7 @@ static int __init usb_mdc800_init (void)
mdc800->dev = NULL; mdc800->dev = NULL;
mdc800->state=NOT_CONNECTED; mdc800->state=NOT_CONNECTED;
init_MUTEX (&mdc800->io_lock); mutex_init (&mdc800->io_lock);
init_waitqueue_head (&mdc800->irq_wait); init_waitqueue_head (&mdc800->irq_wait);
init_waitqueue_head (&mdc800->write_wait); init_waitqueue_head (&mdc800->write_wait);
......
...@@ -159,8 +159,6 @@ static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; ...@@ -159,8 +159,6 @@ static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
*/ */
#define FILTER_TIME (HZ / 20) #define FILTER_TIME (HZ / 20)
static DECLARE_MUTEX(disconnect_sem);
struct ati_remote { struct ati_remote {
struct input_dev *idev; struct input_dev *idev;
struct usb_device *udev; struct usb_device *udev;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/mutex.h>
#include "dabusb.h" #include "dabusb.h"
#include "dabfirmware.h" #include "dabfirmware.h"
...@@ -570,7 +571,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l ...@@ -570,7 +571,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
s->readptr = 0; s->readptr = 0;
} }
} }
err: //up(&s->mutex); err: //mutex_unlock(&s->mutex);
return ret; return ret;
} }
...@@ -585,10 +586,10 @@ static int dabusb_open (struct inode *inode, struct file *file) ...@@ -585,10 +586,10 @@ static int dabusb_open (struct inode *inode, struct file *file)
s = &dabusb[devnum - DABUSB_MINOR]; s = &dabusb[devnum - DABUSB_MINOR];
dbg("dabusb_open"); dbg("dabusb_open");
down (&s->mutex); mutex_lock(&s->mutex);
while (!s->usbdev || s->opened) { while (!s->usbdev || s->opened) {
up (&s->mutex); mutex_unlock(&s->mutex);
if (file->f_flags & O_NONBLOCK) { if (file->f_flags & O_NONBLOCK) {
return -EBUSY; return -EBUSY;
...@@ -598,15 +599,15 @@ static int dabusb_open (struct inode *inode, struct file *file) ...@@ -598,15 +599,15 @@ static int dabusb_open (struct inode *inode, struct file *file)
if (signal_pending (current)) { if (signal_pending (current)) {
return -EAGAIN; return -EAGAIN;
} }
down (&s->mutex); mutex_lock(&s->mutex);
} }
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
up(&s->mutex); mutex_unlock(&s->mutex);
err("set_interface failed"); err("set_interface failed");
return -EINVAL; return -EINVAL;
} }
s->opened = 1; s->opened = 1;
up (&s->mutex); mutex_unlock(&s->mutex);
file->f_pos = 0; file->f_pos = 0;
file->private_data = s; file->private_data = s;
...@@ -620,10 +621,10 @@ static int dabusb_release (struct inode *inode, struct file *file) ...@@ -620,10 +621,10 @@ static int dabusb_release (struct inode *inode, struct file *file)
dbg("dabusb_release"); dbg("dabusb_release");
down (&s->mutex); mutex_lock(&s->mutex);
dabusb_stop (s); dabusb_stop (s);
dabusb_free_buffers (s); dabusb_free_buffers (s);
up (&s->mutex); mutex_unlock(&s->mutex);
if (!s->remove_pending) { if (!s->remove_pending) {
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
...@@ -648,10 +649,10 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm ...@@ -648,10 +649,10 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
if (s->remove_pending) if (s->remove_pending)
return -EIO; return -EIO;
down (&s->mutex); mutex_lock(&s->mutex);
if (!s->usbdev) { if (!s->usbdev) {
up (&s->mutex); mutex_unlock(&s->mutex);
return -EIO; return -EIO;
} }
...@@ -691,7 +692,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm ...@@ -691,7 +692,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
ret = -ENOIOCTLCMD; ret = -ENOIOCTLCMD;
break; break;
} }
up (&s->mutex); mutex_unlock(&s->mutex);
return ret; return ret;
} }
...@@ -737,7 +738,7 @@ static int dabusb_probe (struct usb_interface *intf, ...@@ -737,7 +738,7 @@ static int dabusb_probe (struct usb_interface *intf,
s = &dabusb[intf->minor]; s = &dabusb[intf->minor];
down (&s->mutex); mutex_lock(&s->mutex);
s->remove_pending = 0; s->remove_pending = 0;
s->usbdev = usbdev; s->usbdev = usbdev;
s->devnum = intf->minor; s->devnum = intf->minor;
...@@ -760,7 +761,7 @@ static int dabusb_probe (struct usb_interface *intf, ...@@ -760,7 +761,7 @@ static int dabusb_probe (struct usb_interface *intf,
} }
dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber); dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
usb_set_intfdata (intf, s); usb_set_intfdata (intf, s);
up (&s->mutex); mutex_unlock(&s->mutex);
retval = usb_register_dev(intf, &dabusb_class); retval = usb_register_dev(intf, &dabusb_class);
if (retval) { if (retval) {
...@@ -771,7 +772,7 @@ static int dabusb_probe (struct usb_interface *intf, ...@@ -771,7 +772,7 @@ static int dabusb_probe (struct usb_interface *intf,
return 0; return 0;
reject: reject:
up (&s->mutex); mutex_unlock(&s->mutex);
s->usbdev = NULL; s->usbdev = NULL;
return -ENODEV; return -ENODEV;
} }
...@@ -828,7 +829,7 @@ static int __init dabusb_init (void) ...@@ -828,7 +829,7 @@ static int __init dabusb_init (void)
for (u = 0; u < NRDABUSB; u++) { for (u = 0; u < NRDABUSB; u++) {
pdabusb_t s = &dabusb[u]; pdabusb_t s = &dabusb[u];
memset (s, 0, sizeof (dabusb_t)); memset (s, 0, sizeof (dabusb_t));
init_MUTEX (&s->mutex); mutex_init (&s->mutex);
s->usbdev = NULL; s->usbdev = NULL;
s->total_buffer_size = buffers; s->total_buffer_size = buffers;
init_waitqueue_head (&s->wait); init_waitqueue_head (&s->wait);
......
...@@ -18,7 +18,7 @@ typedef enum { _stopped=0, _started } driver_state_t; ...@@ -18,7 +18,7 @@ typedef enum { _stopped=0, _started } driver_state_t;
typedef struct typedef struct
{ {
struct semaphore mutex; struct mutex mutex;
struct usb_device *usbdev; struct usb_device *usbdev;
wait_queue_head_t wait; wait_queue_head_t wait;
wait_queue_head_t remove_ok; wait_queue_head_t remove_ok;
......
...@@ -365,14 +365,14 @@ reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) ...@@ -365,14 +365,14 @@ reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
PDEBUG(5, "0x%02X:0x%02X", reg, value); PDEBUG(5, "0x%02X:0x%02X", reg, value);
down(&ov->cbuf_lock); mutex_lock(&ov->cbuf_lock);
ov->cbuf[0] = value; ov->cbuf[0] = value;
rc = usb_control_msg(ov->dev, rc = usb_control_msg(ov->dev,
usb_sndctrlpipe(ov->dev, 0), usb_sndctrlpipe(ov->dev, 0),
(ov->bclass == BCL_OV518)?1:2 /* REG_IO */, (ov->bclass == BCL_OV518)?1:2 /* REG_IO */,
USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, (__u16)reg, &ov->cbuf[0], 1, 1000); 0, (__u16)reg, &ov->cbuf[0], 1, 1000);
up(&ov->cbuf_lock); mutex_unlock(&ov->cbuf_lock);
if (rc < 0) if (rc < 0)
err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc)); err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc));
...@@ -387,7 +387,7 @@ reg_r(struct usb_ov511 *ov, unsigned char reg) ...@@ -387,7 +387,7 @@ reg_r(struct usb_ov511 *ov, unsigned char reg)
{ {
int rc; int rc;
down(&ov->cbuf_lock); mutex_lock(&ov->cbuf_lock);
rc = usb_control_msg(ov->dev, rc = usb_control_msg(ov->dev,
usb_rcvctrlpipe(ov->dev, 0), usb_rcvctrlpipe(ov->dev, 0),
(ov->bclass == BCL_OV518)?1:3 /* REG_IO */, (ov->bclass == BCL_OV518)?1:3 /* REG_IO */,
...@@ -401,7 +401,7 @@ reg_r(struct usb_ov511 *ov, unsigned char reg) ...@@ -401,7 +401,7 @@ reg_r(struct usb_ov511 *ov, unsigned char reg)
PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]); PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]);
} }
up(&ov->cbuf_lock); mutex_unlock(&ov->cbuf_lock);
return rc; return rc;
} }
...@@ -444,7 +444,7 @@ ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n) ...@@ -444,7 +444,7 @@ ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n); PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n);
down(&ov->cbuf_lock); mutex_lock(&ov->cbuf_lock);
*((__le32 *)ov->cbuf) = __cpu_to_le32(val); *((__le32 *)ov->cbuf) = __cpu_to_le32(val);
...@@ -453,7 +453,7 @@ ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n) ...@@ -453,7 +453,7 @@ ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
1 /* REG_IO */, 1 /* REG_IO */,
USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, (__u16)reg, ov->cbuf, n, 1000); 0, (__u16)reg, ov->cbuf, n, 1000);
up(&ov->cbuf_lock); mutex_unlock(&ov->cbuf_lock);
if (rc < 0) if (rc < 0)
err("reg write multiple: error %d: %s", rc, err("reg write multiple: error %d: %s", rc,
...@@ -768,14 +768,14 @@ i2c_r(struct usb_ov511 *ov, unsigned char reg) ...@@ -768,14 +768,14 @@ i2c_r(struct usb_ov511 *ov, unsigned char reg)
{ {
int rc; int rc;
down(&ov->i2c_lock); mutex_lock(&ov->i2c_lock);
if (ov->bclass == BCL_OV518) if (ov->bclass == BCL_OV518)
rc = ov518_i2c_read_internal(ov, reg); rc = ov518_i2c_read_internal(ov, reg);
else else
rc = ov511_i2c_read_internal(ov, reg); rc = ov511_i2c_read_internal(ov, reg);
up(&ov->i2c_lock); mutex_unlock(&ov->i2c_lock);
return rc; return rc;
} }
...@@ -785,14 +785,14 @@ i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) ...@@ -785,14 +785,14 @@ i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
{ {
int rc; int rc;
down(&ov->i2c_lock); mutex_lock(&ov->i2c_lock);
if (ov->bclass == BCL_OV518) if (ov->bclass == BCL_OV518)
rc = ov518_i2c_write_internal(ov, reg, value); rc = ov518_i2c_write_internal(ov, reg, value);
else else
rc = ov511_i2c_write_internal(ov, reg, value); rc = ov511_i2c_write_internal(ov, reg, value);
up(&ov->i2c_lock); mutex_unlock(&ov->i2c_lock);
return rc; return rc;
} }
...@@ -842,9 +842,9 @@ i2c_w_mask(struct usb_ov511 *ov, ...@@ -842,9 +842,9 @@ i2c_w_mask(struct usb_ov511 *ov,
{ {
int rc; int rc;
down(&ov->i2c_lock); mutex_lock(&ov->i2c_lock);
rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask); rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
up(&ov->i2c_lock); mutex_unlock(&ov->i2c_lock);
return rc; return rc;
} }
...@@ -880,7 +880,7 @@ i2c_w_slave(struct usb_ov511 *ov, ...@@ -880,7 +880,7 @@ i2c_w_slave(struct usb_ov511 *ov,
{ {
int rc = 0; int rc = 0;
down(&ov->i2c_lock); mutex_lock(&ov->i2c_lock);
/* Set new slave IDs */ /* Set new slave IDs */
rc = i2c_set_slave_internal(ov, slave); rc = i2c_set_slave_internal(ov, slave);
...@@ -894,7 +894,7 @@ i2c_w_slave(struct usb_ov511 *ov, ...@@ -894,7 +894,7 @@ i2c_w_slave(struct usb_ov511 *ov,
if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
err("Couldn't restore primary I2C slave"); err("Couldn't restore primary I2C slave");
up(&ov->i2c_lock); mutex_unlock(&ov->i2c_lock);
return rc; return rc;
} }
...@@ -906,7 +906,7 @@ i2c_r_slave(struct usb_ov511 *ov, ...@@ -906,7 +906,7 @@ i2c_r_slave(struct usb_ov511 *ov,
{ {
int rc; int rc;
down(&ov->i2c_lock); mutex_lock(&ov->i2c_lock);
/* Set new slave IDs */ /* Set new slave IDs */
rc = i2c_set_slave_internal(ov, slave); rc = i2c_set_slave_internal(ov, slave);
...@@ -923,7 +923,7 @@ i2c_r_slave(struct usb_ov511 *ov, ...@@ -923,7 +923,7 @@ i2c_r_slave(struct usb_ov511 *ov,
if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
err("Couldn't restore primary I2C slave"); err("Couldn't restore primary I2C slave");
up(&ov->i2c_lock); mutex_unlock(&ov->i2c_lock);
return rc; return rc;
} }
...@@ -933,7 +933,7 @@ ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid) ...@@ -933,7 +933,7 @@ ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
{ {
int rc; int rc;
down(&ov->i2c_lock); mutex_lock(&ov->i2c_lock);
rc = i2c_set_slave_internal(ov, sid); rc = i2c_set_slave_internal(ov, sid);
if (rc < 0) if (rc < 0)
...@@ -942,7 +942,7 @@ ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid) ...@@ -942,7 +942,7 @@ ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
// FIXME: Is this actually necessary? // FIXME: Is this actually necessary?
rc = ov51x_reset(ov, OV511_RESET_NOREGS); rc = ov51x_reset(ov, OV511_RESET_NOREGS);
out: out:
up(&ov->i2c_lock); mutex_unlock(&ov->i2c_lock);
return rc; return rc;
} }
...@@ -3832,7 +3832,7 @@ ov51x_alloc(struct usb_ov511 *ov) ...@@ -3832,7 +3832,7 @@ ov51x_alloc(struct usb_ov511 *ov)
const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h); const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h);
PDEBUG(4, "entered"); PDEBUG(4, "entered");
down(&ov->buf_lock); mutex_lock(&ov->buf_lock);
if (ov->buf_state == BUF_ALLOCATED) if (ov->buf_state == BUF_ALLOCATED)
goto out; goto out;
...@@ -3879,12 +3879,12 @@ ov51x_alloc(struct usb_ov511 *ov) ...@@ -3879,12 +3879,12 @@ ov51x_alloc(struct usb_ov511 *ov)
ov->buf_state = BUF_ALLOCATED; ov->buf_state = BUF_ALLOCATED;
out: out:
up(&ov->buf_lock); mutex_unlock(&ov->buf_lock);
PDEBUG(4, "leaving"); PDEBUG(4, "leaving");
return 0; return 0;
error: error:
ov51x_do_dealloc(ov); ov51x_do_dealloc(ov);
up(&ov->buf_lock); mutex_unlock(&ov->buf_lock);
PDEBUG(4, "errored"); PDEBUG(4, "errored");
return -ENOMEM; return -ENOMEM;
} }
...@@ -3893,9 +3893,9 @@ static void ...@@ -3893,9 +3893,9 @@ static void
ov51x_dealloc(struct usb_ov511 *ov) ov51x_dealloc(struct usb_ov511 *ov)
{ {
PDEBUG(4, "entered"); PDEBUG(4, "entered");
down(&ov->buf_lock); mutex_lock(&ov->buf_lock);
ov51x_do_dealloc(ov); ov51x_do_dealloc(ov);
up(&ov->buf_lock); mutex_unlock(&ov->buf_lock);
PDEBUG(4, "leaving"); PDEBUG(4, "leaving");
} }
...@@ -3914,7 +3914,7 @@ ov51x_v4l1_open(struct inode *inode, struct file *file) ...@@ -3914,7 +3914,7 @@ ov51x_v4l1_open(struct inode *inode, struct file *file)
PDEBUG(4, "opening"); PDEBUG(4, "opening");
down(&ov->lock); mutex_lock(&ov->lock);
err = -EBUSY; err = -EBUSY;
if (ov->user) if (ov->user)
...@@ -3958,7 +3958,7 @@ ov51x_v4l1_open(struct inode *inode, struct file *file) ...@@ -3958,7 +3958,7 @@ ov51x_v4l1_open(struct inode *inode, struct file *file)
ov51x_led_control(ov, 1); ov51x_led_control(ov, 1);
out: out:
up(&ov->lock); mutex_unlock(&ov->lock);
return err; return err;
} }
...@@ -3970,7 +3970,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) ...@@ -3970,7 +3970,7 @@ ov51x_v4l1_close(struct inode *inode, struct file *file)
PDEBUG(4, "ov511_close"); PDEBUG(4, "ov511_close");
down(&ov->lock); mutex_lock(&ov->lock);
ov->user--; ov->user--;
ov51x_stop_isoc(ov); ov51x_stop_isoc(ov);
...@@ -3981,15 +3981,15 @@ ov51x_v4l1_close(struct inode *inode, struct file *file) ...@@ -3981,15 +3981,15 @@ ov51x_v4l1_close(struct inode *inode, struct file *file)
if (ov->dev) if (ov->dev)
ov51x_dealloc(ov); ov51x_dealloc(ov);
up(&ov->lock); mutex_unlock(&ov->lock);
/* Device unplugged while open. Only a minimum of unregistration is done /* Device unplugged while open. Only a minimum of unregistration is done
* here; the disconnect callback already did the rest. */ * here; the disconnect callback already did the rest. */
if (!ov->dev) { if (!ov->dev) {
down(&ov->cbuf_lock); mutex_lock(&ov->cbuf_lock);
kfree(ov->cbuf); kfree(ov->cbuf);
ov->cbuf = NULL; ov->cbuf = NULL;
up(&ov->cbuf_lock); mutex_unlock(&ov->cbuf_lock);
ov51x_dealloc(ov); ov51x_dealloc(ov);
kfree(ov); kfree(ov);
...@@ -4449,12 +4449,12 @@ ov51x_v4l1_ioctl(struct inode *inode, struct file *file, ...@@ -4449,12 +4449,12 @@ ov51x_v4l1_ioctl(struct inode *inode, struct file *file,
struct usb_ov511 *ov = video_get_drvdata(vdev); struct usb_ov511 *ov = video_get_drvdata(vdev);
int rc; int rc;
if (down_interruptible(&ov->lock)) if (mutex_lock_interruptible(&ov->lock))
return -EINTR; return -EINTR;
rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal); rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal);
up(&ov->lock); mutex_unlock(&ov->lock);
return rc; return rc;
} }
...@@ -4468,7 +4468,7 @@ ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos) ...@@ -4468,7 +4468,7 @@ ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
int i, rc = 0, frmx = -1; int i, rc = 0, frmx = -1;
struct ov511_frame *frame; struct ov511_frame *frame;
if (down_interruptible(&ov->lock)) if (mutex_lock_interruptible(&ov->lock))
return -EINTR; return -EINTR;
PDEBUG(4, "%ld bytes, noblock=%d", count, noblock); PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
...@@ -4604,11 +4604,11 @@ ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos) ...@@ -4604,11 +4604,11 @@ ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
PDEBUG(4, "read finished, returning %ld (sweet)", count); PDEBUG(4, "read finished, returning %ld (sweet)", count);
up(&ov->lock); mutex_unlock(&ov->lock);
return count; return count;
error: error:
up(&ov->lock); mutex_unlock(&ov->lock);
return rc; return rc;
} }
...@@ -4631,14 +4631,14 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -4631,14 +4631,14 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma)
+ PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
return -EINVAL; return -EINVAL;
if (down_interruptible(&ov->lock)) if (mutex_lock_interruptible(&ov->lock))
return -EINTR; return -EINTR;
pos = (unsigned long)ov->fbuf; pos = (unsigned long)ov->fbuf;
while (size > 0) { while (size > 0) {
page = vmalloc_to_pfn((void *)pos); page = vmalloc_to_pfn((void *)pos);
if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
up(&ov->lock); mutex_unlock(&ov->lock);
return -EAGAIN; return -EAGAIN;
} }
start += PAGE_SIZE; start += PAGE_SIZE;
...@@ -4649,7 +4649,7 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -4649,7 +4649,7 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma)
size = 0; size = 0;
} }
up(&ov->lock); mutex_unlock(&ov->lock);
return 0; return 0;
} }
...@@ -5738,11 +5738,10 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -5738,11 +5738,10 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
init_waitqueue_head(&ov->wq); init_waitqueue_head(&ov->wq);
init_MUTEX(&ov->lock); /* to 1 == available */ mutex_init(&ov->lock); /* to 1 == available */
init_MUTEX(&ov->buf_lock); mutex_init(&ov->buf_lock);
init_MUTEX(&ov->param_lock); mutex_init(&ov->i2c_lock);
init_MUTEX(&ov->i2c_lock); mutex_init(&ov->cbuf_lock);
init_MUTEX(&ov->cbuf_lock);
ov->buf_state = BUF_NOT_ALLOCATED; ov->buf_state = BUF_NOT_ALLOCATED;
...@@ -5833,10 +5832,10 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -5833,10 +5832,10 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
} }
if (ov->cbuf) { if (ov->cbuf) {
down(&ov->cbuf_lock); mutex_lock(&ov->cbuf_lock);
kfree(ov->cbuf); kfree(ov->cbuf);
ov->cbuf = NULL; ov->cbuf = NULL;
up(&ov->cbuf_lock); mutex_unlock(&ov->cbuf_lock);
} }
kfree(ov); kfree(ov);
...@@ -5881,10 +5880,10 @@ ov51x_disconnect(struct usb_interface *intf) ...@@ -5881,10 +5880,10 @@ ov51x_disconnect(struct usb_interface *intf)
/* Free the memory */ /* Free the memory */
if (ov && !ov->user) { if (ov && !ov->user) {
down(&ov->cbuf_lock); mutex_lock(&ov->cbuf_lock);
kfree(ov->cbuf); kfree(ov->cbuf);
ov->cbuf = NULL; ov->cbuf = NULL;
up(&ov->cbuf_lock); mutex_unlock(&ov->cbuf_lock);
ov51x_dealloc(ov); ov51x_dealloc(ov);
kfree(ov); kfree(ov);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/videodev.h> #include <linux/videodev.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/mutex.h>
#define OV511_DEBUG /* Turn on debug messages */ #define OV511_DEBUG /* Turn on debug messages */
...@@ -435,7 +436,7 @@ struct usb_ov511 { ...@@ -435,7 +436,7 @@ struct usb_ov511 {
int led_policy; /* LED: off|on|auto; OV511+ only */ int led_policy; /* LED: off|on|auto; OV511+ only */
struct semaphore lock; /* Serializes user-accessible operations */ struct mutex lock; /* Serializes user-accessible operations */
int user; /* user count for exclusive use */ int user; /* user count for exclusive use */
int streaming; /* Are we streaming Isochronous? */ int streaming; /* Are we streaming Isochronous? */
...@@ -473,11 +474,9 @@ struct usb_ov511 { ...@@ -473,11 +474,9 @@ struct usb_ov511 {
int packet_size; /* Frame size per isoc desc */ int packet_size; /* Frame size per isoc desc */
int packet_numbering; /* Is ISO frame numbering enabled? */ int packet_numbering; /* Is ISO frame numbering enabled? */
struct semaphore param_lock; /* params lock for this camera */
/* Framebuffer/sbuf management */ /* Framebuffer/sbuf management */
int buf_state; int buf_state;
struct semaphore buf_lock; struct mutex buf_lock;
struct ov51x_decomp_ops *decomp_ops; struct ov51x_decomp_ops *decomp_ops;
...@@ -494,12 +493,12 @@ struct usb_ov511 { ...@@ -494,12 +493,12 @@ struct usb_ov511 {
int pal; /* Device is designed for PAL resolution */ int pal; /* Device is designed for PAL resolution */
/* I2C interface */ /* I2C interface */
struct semaphore i2c_lock; /* Protect I2C controller regs */ struct mutex i2c_lock; /* Protect I2C controller regs */
unsigned char primary_i2c_slave; /* I2C write id of sensor */ unsigned char primary_i2c_slave; /* I2C write id of sensor */
/* Control transaction stuff */ /* Control transaction stuff */
unsigned char *cbuf; /* Buffer for payload */ unsigned char *cbuf; /* Buffer for payload */
struct semaphore cbuf_lock; struct mutex cbuf_lock;
}; };
/* Used to represent a list of values and their respective symbolic names */ /* Used to represent a list of values and their respective symbolic names */
......
...@@ -1157,21 +1157,21 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1157,21 +1157,21 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma)
unsigned long size = vma->vm_end-vma->vm_start; unsigned long size = vma->vm_end-vma->vm_start;
unsigned long page, pos; unsigned long page, pos;
down(&se401->lock); mutex_lock(&se401->lock);
if (se401->dev == NULL) { if (se401->dev == NULL) {
up(&se401->lock); mutex_unlock(&se401->lock);
return -EIO; return -EIO;
} }
if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) { if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
up(&se401->lock); mutex_unlock(&se401->lock);
return -EINVAL; return -EINVAL;
} }
pos = (unsigned long)se401->fbuf; pos = (unsigned long)se401->fbuf;
while (size > 0) { while (size > 0) {
page = vmalloc_to_pfn((void *)pos); page = vmalloc_to_pfn((void *)pos);
if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
up(&se401->lock); mutex_unlock(&se401->lock);
return -EAGAIN; return -EAGAIN;
} }
start += PAGE_SIZE; start += PAGE_SIZE;
...@@ -1181,7 +1181,7 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1181,7 +1181,7 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma)
else else
size = 0; size = 0;
} }
up(&se401->lock); mutex_unlock(&se401->lock);
return 0; return 0;
} }
...@@ -1366,7 +1366,7 @@ static int se401_probe(struct usb_interface *intf, ...@@ -1366,7 +1366,7 @@ static int se401_probe(struct usb_interface *intf,
memcpy(&se401->vdev, &se401_template, sizeof(se401_template)); memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name)); memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
init_waitqueue_head(&se401->wq); init_waitqueue_head(&se401->wq);
init_MUTEX(&se401->lock); mutex_init(&se401->lock);
wmb(); wmb();
if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/videodev.h> #include <linux/videodev.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/mutex.h>
#define se401_DEBUG /* Turn on debug messages */ #define se401_DEBUG /* Turn on debug messages */
...@@ -189,7 +190,7 @@ struct usb_se401 { ...@@ -189,7 +190,7 @@ struct usb_se401 {
int maxframesize; int maxframesize;
int cframesize; /* current framesize */ int cframesize; /* current framesize */
struct semaphore lock; struct mutex lock;
int user; /* user count for exclusive use */ int user; /* user count for exclusive use */
int removed; /* device disconnected */ int removed; /* device disconnected */
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/param.h> #include <linux/param.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/mutex.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include "sn9c102_sensor.h" #include "sn9c102_sensor.h"
...@@ -109,7 +110,7 @@ struct sn9c102_module_param { ...@@ -109,7 +110,7 @@ struct sn9c102_module_param {
u8 force_munmap; u8 force_munmap;
}; };
static DECLARE_MUTEX(sn9c102_sysfs_lock); static DEFINE_MUTEX(sn9c102_sysfs_lock);
static DECLARE_RWSEM(sn9c102_disconnect); static DECLARE_RWSEM(sn9c102_disconnect);
struct sn9c102_device { struct sn9c102_device {
...@@ -141,7 +142,7 @@ struct sn9c102_device { ...@@ -141,7 +142,7 @@ struct sn9c102_device {
enum sn9c102_dev_state state; enum sn9c102_dev_state state;
u8 users; u8 users;
struct semaphore dev_sem, fileop_sem; struct mutex dev_mutex, fileop_mutex;
spinlock_t queue_lock; spinlock_t queue_lock;
wait_queue_head_t open, wait_frame, wait_stream; wait_queue_head_t open, wait_frame, wait_stream;
}; };
......
This diff is collapsed.
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/videodev.h> #include <linux/videodev.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/mutex.h>
#include "stv680.h" #include "stv680.h"
...@@ -1258,22 +1259,22 @@ static int stv680_mmap (struct file *file, struct vm_area_struct *vma) ...@@ -1258,22 +1259,22 @@ static int stv680_mmap (struct file *file, struct vm_area_struct *vma)
unsigned long size = vma->vm_end-vma->vm_start; unsigned long size = vma->vm_end-vma->vm_start;
unsigned long page, pos; unsigned long page, pos;
down (&stv680->lock); mutex_lock(&stv680->lock);
if (stv680->udev == NULL) { if (stv680->udev == NULL) {
up (&stv680->lock); mutex_unlock(&stv680->lock);
return -EIO; return -EIO;
} }
if (size > (((STV680_NUMFRAMES * stv680->maxframesize) + PAGE_SIZE - 1) if (size > (((STV680_NUMFRAMES * stv680->maxframesize) + PAGE_SIZE - 1)
& ~(PAGE_SIZE - 1))) { & ~(PAGE_SIZE - 1))) {
up (&stv680->lock); mutex_unlock(&stv680->lock);
return -EINVAL; return -EINVAL;
} }
pos = (unsigned long) stv680->fbuf; pos = (unsigned long) stv680->fbuf;
while (size > 0) { while (size > 0) {
page = vmalloc_to_pfn((void *)pos); page = vmalloc_to_pfn((void *)pos);
if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
up (&stv680->lock); mutex_unlock(&stv680->lock);
return -EAGAIN; return -EAGAIN;
} }
start += PAGE_SIZE; start += PAGE_SIZE;
...@@ -1283,7 +1284,7 @@ static int stv680_mmap (struct file *file, struct vm_area_struct *vma) ...@@ -1283,7 +1284,7 @@ static int stv680_mmap (struct file *file, struct vm_area_struct *vma)
else else
size = 0; size = 0;
} }
up (&stv680->lock); mutex_unlock(&stv680->lock);
return 0; return 0;
} }
...@@ -1409,7 +1410,7 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id ...@@ -1409,7 +1410,7 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id
memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name)); memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name));
init_waitqueue_head (&stv680->wq); init_waitqueue_head (&stv680->wq);
init_MUTEX (&stv680->lock); mutex_init (&stv680->lock);
wmb (); wmb ();
if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
......
...@@ -118,7 +118,7 @@ struct usb_stv { ...@@ -118,7 +118,7 @@ struct usb_stv {
int origGain; int origGain;
int origMode; /* original camera mode */ int origMode; /* original camera mode */
struct semaphore lock; /* to lock the structure */ struct mutex lock; /* to lock the structure */
int user; /* user count for exclusive use */ int user; /* user count for exclusive use */
int removed; /* device disconnected */ int removed; /* device disconnected */
int streaming; /* Are we streaming video? */ int streaming; /* Are we streaming video? */
......
...@@ -714,7 +714,7 @@ int usbvideo_register( ...@@ -714,7 +714,7 @@ int usbvideo_register(
cams->md_module = md; cams->md_module = md;
if (cams->md_module == NULL) if (cams->md_module == NULL)
warn("%s: module == NULL!", __FUNCTION__); warn("%s: module == NULL!", __FUNCTION__);
init_MUTEX(&cams->lock); /* to 1 == available */ mutex_init(&cams->lock); /* to 1 == available */
for (i = 0; i < num_cams; i++) { for (i = 0; i < num_cams; i++) {
struct uvd *up = &cams->cam[i]; struct uvd *up = &cams->cam[i];
...@@ -862,7 +862,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) ...@@ -862,7 +862,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf)
if (uvd->debug > 0) if (uvd->debug > 0)
info("%s(%p.)", __FUNCTION__, intf); info("%s(%p.)", __FUNCTION__, intf);
down(&uvd->lock); mutex_lock(&uvd->lock);
uvd->remove_pending = 1; /* Now all ISO data will be ignored */ uvd->remove_pending = 1; /* Now all ISO data will be ignored */
/* At this time we ask to cancel outstanding URBs */ /* At this time we ask to cancel outstanding URBs */
...@@ -882,7 +882,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) ...@@ -882,7 +882,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf)
info("%s: In use, disconnect pending.", __FUNCTION__); info("%s: In use, disconnect pending.", __FUNCTION__);
else else
usbvideo_CameraRelease(uvd); usbvideo_CameraRelease(uvd);
up(&uvd->lock); mutex_unlock(&uvd->lock);
info("USB camera disconnected."); info("USB camera disconnected.");
usbvideo_ClientDecModCount(uvd); usbvideo_ClientDecModCount(uvd);
...@@ -929,19 +929,19 @@ static int usbvideo_find_struct(struct usbvideo *cams) ...@@ -929,19 +929,19 @@ static int usbvideo_find_struct(struct usbvideo *cams)
err("No usbvideo handle?"); err("No usbvideo handle?");
return -1; return -1;
} }
down(&cams->lock); mutex_lock(&cams->lock);
for (u = 0; u < cams->num_cameras; u++) { for (u = 0; u < cams->num_cameras; u++) {
struct uvd *uvd = &cams->cam[u]; struct uvd *uvd = &cams->cam[u];
if (!uvd->uvd_used) /* This one is free */ if (!uvd->uvd_used) /* This one is free */
{ {
uvd->uvd_used = 1; /* In use now */ uvd->uvd_used = 1; /* In use now */
init_MUTEX(&uvd->lock); /* to 1 == available */ mutex_init(&uvd->lock); /* to 1 == available */
uvd->dev = NULL; uvd->dev = NULL;
rv = u; rv = u;
break; break;
} }
} }
up(&cams->lock); mutex_unlock(&cams->lock);
return rv; return rv;
} }
...@@ -983,7 +983,7 @@ struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams) ...@@ -983,7 +983,7 @@ struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams)
/* Not relying upon caller we increase module counter ourselves */ /* Not relying upon caller we increase module counter ourselves */
usbvideo_ClientIncModCount(uvd); usbvideo_ClientIncModCount(uvd);
down(&uvd->lock); mutex_lock(&uvd->lock);
for (i=0; i < USBVIDEO_NUMSBUF; i++) { for (i=0; i < USBVIDEO_NUMSBUF; i++) {
uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
if (uvd->sbuf[i].urb == NULL) { if (uvd->sbuf[i].urb == NULL) {
...@@ -1006,7 +1006,7 @@ struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams) ...@@ -1006,7 +1006,7 @@ struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams)
* return control to the client's probe function right now. * return control to the client's probe function right now.
*/ */
allocate_done: allocate_done:
up (&uvd->lock); mutex_unlock(&uvd->lock);
usbvideo_ClientDecModCount(uvd); usbvideo_ClientDecModCount(uvd);
return uvd; return uvd;
} }
...@@ -1120,7 +1120,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) ...@@ -1120,7 +1120,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file)
info("%s($%p)", __FUNCTION__, dev); info("%s($%p)", __FUNCTION__, dev);
usbvideo_ClientIncModCount(uvd); usbvideo_ClientIncModCount(uvd);
down(&uvd->lock); mutex_lock(&uvd->lock);
if (uvd->user) { if (uvd->user) {
err("%s: Someone tried to open an already opened device!", __FUNCTION__); err("%s: Someone tried to open an already opened device!", __FUNCTION__);
...@@ -1201,7 +1201,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) ...@@ -1201,7 +1201,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file)
} }
} }
} }
up(&uvd->lock); mutex_unlock(&uvd->lock);
if (errCode != 0) if (errCode != 0)
usbvideo_ClientDecModCount(uvd); usbvideo_ClientDecModCount(uvd);
if (uvd->debug > 0) if (uvd->debug > 0)
...@@ -1230,7 +1230,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) ...@@ -1230,7 +1230,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file)
if (uvd->debug > 1) if (uvd->debug > 1)
info("%s($%p)", __FUNCTION__, dev); info("%s($%p)", __FUNCTION__, dev);
down(&uvd->lock); mutex_lock(&uvd->lock);
GET_CALLBACK(uvd, stopDataPump)(uvd); GET_CALLBACK(uvd, stopDataPump)(uvd);
usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size); usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
uvd->fbuf = NULL; uvd->fbuf = NULL;
...@@ -1251,7 +1251,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) ...@@ -1251,7 +1251,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file)
info("usbvideo_v4l_close: Final disconnect."); info("usbvideo_v4l_close: Final disconnect.");
usbvideo_CameraRelease(uvd); usbvideo_CameraRelease(uvd);
} }
up(&uvd->lock); mutex_unlock(&uvd->lock);
usbvideo_ClientDecModCount(uvd); usbvideo_ClientDecModCount(uvd);
if (uvd->debug > 1) if (uvd->debug > 1)
...@@ -1511,7 +1511,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, ...@@ -1511,7 +1511,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
if (uvd->debug >= 1) if (uvd->debug >= 1)
info("%s: %Zd. bytes, noblock=%d.", __FUNCTION__, count, noblock); info("%s: %Zd. bytes, noblock=%d.", __FUNCTION__, count, noblock);
down(&uvd->lock); mutex_lock(&uvd->lock);
/* See if a frame is completed, then use it. */ /* See if a frame is completed, then use it. */
for(i = 0; i < USBVIDEO_NUMFRAMES; i++) { for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
...@@ -1643,7 +1643,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, ...@@ -1643,7 +1643,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
} }
} }
read_done: read_done:
up(&uvd->lock); mutex_unlock(&uvd->lock);
return count; return count;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/videodev.h> #include <linux/videodev.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/mutex.h>
/* Most helpful debugging aid */ /* Most helpful debugging aid */
#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__)))) #define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
...@@ -213,7 +214,7 @@ struct uvd { ...@@ -213,7 +214,7 @@ struct uvd {
unsigned long flags; /* FLAGS_USBVIDEO_xxx */ unsigned long flags; /* FLAGS_USBVIDEO_xxx */
unsigned long paletteBits; /* Which palettes we accept? */ unsigned long paletteBits; /* Which palettes we accept? */
unsigned short defaultPalette; /* What palette to use for read() */ unsigned short defaultPalette; /* What palette to use for read() */
struct semaphore lock; struct mutex lock;
int user; /* user count for exclusive use */ int user; /* user count for exclusive use */
videosize_t videosize; /* Current setting */ videosize_t videosize; /* Current setting */
...@@ -272,7 +273,7 @@ struct usbvideo { ...@@ -272,7 +273,7 @@ struct usbvideo {
int num_cameras; /* As allocated */ int num_cameras; /* As allocated */
struct usb_driver usbdrv; /* Interface to the USB stack */ struct usb_driver usbdrv; /* Interface to the USB stack */
char drvName[80]; /* Driver name */ char drvName[80]; /* Driver name */
struct semaphore lock; /* Mutex protecting camera structures */ struct mutex lock; /* Mutex protecting camera structures */
struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */ struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */
struct video_device vdt; /* Video device template */ struct video_device vdt; /* Video device template */
struct uvd *cam; /* Array of camera structures */ struct uvd *cam; /* Array of camera structures */
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/mutex.h>
#include "usbvideo.h" #include "usbvideo.h"
// #define VICAM_DEBUG // #define VICAM_DEBUG
...@@ -407,7 +408,7 @@ struct vicam_camera { ...@@ -407,7 +408,7 @@ struct vicam_camera {
struct usb_device *udev; // usb device struct usb_device *udev; // usb device
/* guard against simultaneous accesses to the camera */ /* guard against simultaneous accesses to the camera */
struct semaphore cam_lock; struct mutex cam_lock;
int is_initialized; int is_initialized;
u8 open_count; u8 open_count;
...@@ -461,12 +462,12 @@ static int send_control_msg(struct vicam_camera *cam, ...@@ -461,12 +462,12 @@ static int send_control_msg(struct vicam_camera *cam,
u16 size) u16 size)
{ {
int status = -ENODEV; int status = -ENODEV;
down(&cam->cam_lock); mutex_lock(&cam->cam_lock);
if (cam->udev) { if (cam->udev) {
status = __send_control_msg(cam, request, value, status = __send_control_msg(cam, request, value,
index, cp, size); index, cp, size);
} }
up(&cam->cam_lock); mutex_unlock(&cam->cam_lock);
return status; return status;
} }
static int static int
...@@ -831,13 +832,13 @@ vicam_close(struct inode *inode, struct file *file) ...@@ -831,13 +832,13 @@ vicam_close(struct inode *inode, struct file *file)
rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
kfree(cam->cntrlbuf); kfree(cam->cntrlbuf);
down(&cam->cam_lock); mutex_lock(&cam->cam_lock);
cam->open_count--; cam->open_count--;
open_count = cam->open_count; open_count = cam->open_count;
udev = cam->udev; udev = cam->udev;
up(&cam->cam_lock); mutex_unlock(&cam->cam_lock);
if (!open_count && !udev) { if (!open_count && !udev) {
kfree(cam); kfree(cam);
...@@ -960,7 +961,7 @@ read_frame(struct vicam_camera *cam, int framenum) ...@@ -960,7 +961,7 @@ read_frame(struct vicam_camera *cam, int framenum)
request[8] = 0; request[8] = 0;
// bytes 9-15 do not seem to affect exposure or image quality // bytes 9-15 do not seem to affect exposure or image quality
down(&cam->cam_lock); mutex_lock(&cam->cam_lock);
if (!cam->udev) { if (!cam->udev) {
goto done; goto done;
...@@ -985,7 +986,7 @@ read_frame(struct vicam_camera *cam, int framenum) ...@@ -985,7 +986,7 @@ read_frame(struct vicam_camera *cam, int framenum)
} }
done: done:
up(&cam->cam_lock); mutex_unlock(&cam->cam_lock);
} }
static ssize_t static ssize_t
...@@ -1309,7 +1310,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1309,7 +1310,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
cam->shutter_speed = 15; cam->shutter_speed = 15;
init_MUTEX(&cam->cam_lock); mutex_init(&cam->cam_lock);
memcpy(&cam->vdev, &vicam_template, memcpy(&cam->vdev, &vicam_template,
sizeof (vicam_template)); sizeof (vicam_template));
...@@ -1351,7 +1352,7 @@ vicam_disconnect(struct usb_interface *intf) ...@@ -1351,7 +1352,7 @@ vicam_disconnect(struct usb_interface *intf)
/* stop the camera from being used */ /* stop the camera from being used */
down(&cam->cam_lock); mutex_lock(&cam->cam_lock);
/* mark the camera as gone */ /* mark the camera as gone */
...@@ -1368,7 +1369,7 @@ vicam_disconnect(struct usb_interface *intf) ...@@ -1368,7 +1369,7 @@ vicam_disconnect(struct usb_interface *intf)
open_count = cam->open_count; open_count = cam->open_count;
up(&cam->cam_lock); mutex_unlock(&cam->cam_lock);
if (!open_count) { if (!open_count) {
kfree(cam); kfree(cam);
......
...@@ -47,6 +47,13 @@ ...@@ -47,6 +47,13 @@
#include "w9968cf.h" #include "w9968cf.h"
#include "w9968cf_decoder.h" #include "w9968cf_decoder.h"
static struct w9968cf_vpp_t* w9968cf_vpp;
static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
static DEFINE_MUTEX(w9968cf_devlist_mutex); /* semaphore for list traversal */
static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */
/**************************************************************************** /****************************************************************************
...@@ -2418,7 +2425,7 @@ w9968cf_configure_camera(struct w9968cf_device* cam, ...@@ -2418,7 +2425,7 @@ w9968cf_configure_camera(struct w9968cf_device* cam,
enum w9968cf_model_id mod_id, enum w9968cf_model_id mod_id,
const unsigned short dev_nr) const unsigned short dev_nr)
{ {
init_MUTEX(&cam->fileop_sem); mutex_init(&cam->fileop_mutex);
init_waitqueue_head(&cam->open); init_waitqueue_head(&cam->open);
spin_lock_init(&cam->urb_lock); spin_lock_init(&cam->urb_lock);
spin_lock_init(&cam->flist_lock); spin_lock_init(&cam->flist_lock);
...@@ -2646,7 +2653,7 @@ static void w9968cf_adjust_configuration(struct w9968cf_device* cam) ...@@ -2646,7 +2653,7 @@ static void w9968cf_adjust_configuration(struct w9968cf_device* cam)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
static void w9968cf_release_resources(struct w9968cf_device* cam) static void w9968cf_release_resources(struct w9968cf_device* cam)
{ {
down(&w9968cf_devlist_sem); mutex_lock(&w9968cf_devlist_mutex);
DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor) DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
...@@ -2657,7 +2664,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam) ...@@ -2657,7 +2664,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam)
kfree(cam->control_buffer); kfree(cam->control_buffer);
kfree(cam->data_buffer); kfree(cam->data_buffer);
up(&w9968cf_devlist_sem); mutex_unlock(&w9968cf_devlist_mutex);
} }
...@@ -2677,14 +2684,14 @@ static int w9968cf_open(struct inode* inode, struct file* filp) ...@@ -2677,14 +2684,14 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
down(&cam->dev_sem); mutex_lock(&cam->dev_mutex);
if (cam->sensor == CC_UNKNOWN) { if (cam->sensor == CC_UNKNOWN) {
DBG(2, "No supported image sensor has been detected by the " DBG(2, "No supported image sensor has been detected by the "
"'ovcamchip' module for the %s (/dev/video%d). Make " "'ovcamchip' module for the %s (/dev/video%d). Make "
"sure it is loaded *before* (re)connecting the camera.", "sure it is loaded *before* (re)connecting the camera.",
symbolic(camlist, cam->id), cam->v4ldev->minor) symbolic(camlist, cam->id), cam->v4ldev->minor)
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
up_read(&w9968cf_disconnect); up_read(&w9968cf_disconnect);
return -ENODEV; return -ENODEV;
} }
...@@ -2693,11 +2700,11 @@ static int w9968cf_open(struct inode* inode, struct file* filp) ...@@ -2693,11 +2700,11 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
DBG(2, "%s (/dev/video%d) has been already occupied by '%s'", DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command) symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) { if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
up_read(&w9968cf_disconnect); up_read(&w9968cf_disconnect);
return -EWOULDBLOCK; return -EWOULDBLOCK;
} }
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
err = wait_event_interruptible_exclusive(cam->open, err = wait_event_interruptible_exclusive(cam->open,
cam->disconnected || cam->disconnected ||
!cam->users); !cam->users);
...@@ -2709,7 +2716,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp) ...@@ -2709,7 +2716,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
up_read(&w9968cf_disconnect); up_read(&w9968cf_disconnect);
return -ENODEV; return -ENODEV;
} }
down(&cam->dev_sem); mutex_lock(&cam->dev_mutex);
} }
DBG(5, "Opening '%s', /dev/video%d ...", DBG(5, "Opening '%s', /dev/video%d ...",
...@@ -2738,7 +2745,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp) ...@@ -2738,7 +2745,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
DBG(5, "Video device is open") DBG(5, "Video device is open")
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
up_read(&w9968cf_disconnect); up_read(&w9968cf_disconnect);
return 0; return 0;
...@@ -2746,7 +2753,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp) ...@@ -2746,7 +2753,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
deallocate_memory: deallocate_memory:
w9968cf_deallocate_memory(cam); w9968cf_deallocate_memory(cam);
DBG(2, "Failed to open the video device") DBG(2, "Failed to open the video device")
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
up_read(&w9968cf_disconnect); up_read(&w9968cf_disconnect);
return err; return err;
} }
...@@ -2758,13 +2765,13 @@ static int w9968cf_release(struct inode* inode, struct file* filp) ...@@ -2758,13 +2765,13 @@ static int w9968cf_release(struct inode* inode, struct file* filp)
cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
down(&cam->dev_sem); /* prevent disconnect() to be called */ mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */
w9968cf_stop_transfer(cam); w9968cf_stop_transfer(cam);
if (cam->disconnected) { if (cam->disconnected) {
w9968cf_release_resources(cam); w9968cf_release_resources(cam);
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
kfree(cam); kfree(cam);
return 0; return 0;
} }
...@@ -2774,7 +2781,7 @@ static int w9968cf_release(struct inode* inode, struct file* filp) ...@@ -2774,7 +2781,7 @@ static int w9968cf_release(struct inode* inode, struct file* filp)
wake_up_interruptible_nr(&cam->open, 1); wake_up_interruptible_nr(&cam->open, 1);
DBG(5, "Video device closed") DBG(5, "Video device closed")
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
return 0; return 0;
} }
...@@ -2791,18 +2798,18 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) ...@@ -2791,18 +2798,18 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
if (filp->f_flags & O_NONBLOCK) if (filp->f_flags & O_NONBLOCK)
return -EWOULDBLOCK; return -EWOULDBLOCK;
if (down_interruptible(&cam->fileop_sem)) if (mutex_lock_interruptible(&cam->fileop_mutex))
return -ERESTARTSYS; return -ERESTARTSYS;
if (cam->disconnected) { if (cam->disconnected) {
DBG(2, "Device not present") DBG(2, "Device not present")
up(&cam->fileop_sem); mutex_unlock(&cam->fileop_mutex);
return -ENODEV; return -ENODEV;
} }
if (cam->misconfigured) { if (cam->misconfigured) {
DBG(2, "The camera is misconfigured. Close and open it again.") DBG(2, "The camera is misconfigured. Close and open it again.")
up(&cam->fileop_sem); mutex_unlock(&cam->fileop_mutex);
return -EIO; return -EIO;
} }
...@@ -2817,11 +2824,11 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) ...@@ -2817,11 +2824,11 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
cam->frame[1].status == F_READY || cam->frame[1].status == F_READY ||
cam->disconnected); cam->disconnected);
if (err) { if (err) {
up(&cam->fileop_sem); mutex_unlock(&cam->fileop_mutex);
return err; return err;
} }
if (cam->disconnected) { if (cam->disconnected) {
up(&cam->fileop_sem); mutex_unlock(&cam->fileop_mutex);
return -ENODEV; return -ENODEV;
} }
...@@ -2835,7 +2842,7 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) ...@@ -2835,7 +2842,7 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
if (copy_to_user(buf, fr->buffer, count)) { if (copy_to_user(buf, fr->buffer, count)) {
fr->status = F_UNUSED; fr->status = F_UNUSED;
up(&cam->fileop_sem); mutex_unlock(&cam->fileop_mutex);
return -EFAULT; return -EFAULT;
} }
*f_pos += count; *f_pos += count;
...@@ -2844,7 +2851,7 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) ...@@ -2844,7 +2851,7 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
DBG(5, "%zu bytes read", count) DBG(5, "%zu bytes read", count)
up(&cam->fileop_sem); mutex_unlock(&cam->fileop_mutex);
return count; return count;
} }
...@@ -2898,24 +2905,24 @@ w9968cf_ioctl(struct inode* inode, struct file* filp, ...@@ -2898,24 +2905,24 @@ w9968cf_ioctl(struct inode* inode, struct file* filp,
cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
if (down_interruptible(&cam->fileop_sem)) if (mutex_lock_interruptible(&cam->fileop_mutex))
return -ERESTARTSYS; return -ERESTARTSYS;
if (cam->disconnected) { if (cam->disconnected) {
DBG(2, "Device not present") DBG(2, "Device not present")
up(&cam->fileop_sem); mutex_unlock(&cam->fileop_mutex);
return -ENODEV; return -ENODEV;
} }
if (cam->misconfigured) { if (cam->misconfigured) {
DBG(2, "The camera is misconfigured. Close and open it again.") DBG(2, "The camera is misconfigured. Close and open it again.")
up(&cam->fileop_sem); mutex_unlock(&cam->fileop_mutex);
return -EIO; return -EIO;
} }
err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg); err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
up(&cam->fileop_sem); mutex_unlock(&cam->fileop_mutex);
return err; return err;
} }
...@@ -3502,8 +3509,8 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) ...@@ -3502,8 +3509,8 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
if (!cam) if (!cam)
return -ENOMEM; return -ENOMEM;
init_MUTEX(&cam->dev_sem); mutex_init(&cam->dev_mutex);
down(&cam->dev_sem); mutex_lock(&cam->dev_mutex);
cam->usbdev = udev; cam->usbdev = udev;
/* NOTE: a local copy is used to avoid possible race conditions */ /* NOTE: a local copy is used to avoid possible race conditions */
...@@ -3515,10 +3522,10 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) ...@@ -3515,10 +3522,10 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
simcams = W9968CF_SIMCAMS; simcams = W9968CF_SIMCAMS;
/* How many cameras are connected ? */ /* How many cameras are connected ? */
down(&w9968cf_devlist_sem); mutex_lock(&w9968cf_devlist_mutex);
list_for_each(ptr, &w9968cf_dev_list) list_for_each(ptr, &w9968cf_dev_list)
sc++; sc++;
up(&w9968cf_devlist_sem); mutex_unlock(&w9968cf_devlist_mutex);
if (sc >= simcams) { if (sc >= simcams) {
DBG(2, "Device rejected: too many connected cameras " DBG(2, "Device rejected: too many connected cameras "
...@@ -3578,9 +3585,9 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) ...@@ -3578,9 +3585,9 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
w9968cf_configure_camera(cam, udev, mod_id, dev_nr); w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
/* Add a new entry into the list of V4L registered devices */ /* Add a new entry into the list of V4L registered devices */
down(&w9968cf_devlist_sem); mutex_lock(&w9968cf_devlist_mutex);
list_add(&cam->v4llist, &w9968cf_dev_list); list_add(&cam->v4llist, &w9968cf_dev_list);
up(&w9968cf_devlist_sem); mutex_unlock(&w9968cf_devlist_mutex);
dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0; dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
w9968cf_turn_on_led(cam); w9968cf_turn_on_led(cam);
...@@ -3588,7 +3595,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) ...@@ -3588,7 +3595,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
w9968cf_i2c_init(cam); w9968cf_i2c_init(cam);
usb_set_intfdata(intf, cam); usb_set_intfdata(intf, cam);
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
return 0; return 0;
fail: /* Free unused memory */ fail: /* Free unused memory */
...@@ -3596,7 +3603,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) ...@@ -3596,7 +3603,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
kfree(cam->data_buffer); kfree(cam->data_buffer);
if (cam->v4ldev) if (cam->v4ldev)
video_device_release(cam->v4ldev); video_device_release(cam->v4ldev);
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
kfree(cam); kfree(cam);
return err; return err;
} }
...@@ -3611,7 +3618,7 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) ...@@ -3611,7 +3618,7 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
if (cam) { if (cam) {
/* Prevent concurrent accesses to data */ /* Prevent concurrent accesses to data */
down(&cam->dev_sem); mutex_lock(&cam->dev_mutex);
cam->disconnected = 1; cam->disconnected = 1;
...@@ -3630,7 +3637,7 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) ...@@ -3630,7 +3637,7 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
} else } else
w9968cf_release_resources(cam); w9968cf_release_resources(cam);
up(&cam->dev_sem); mutex_unlock(&cam->dev_mutex);
if (!cam->users) if (!cam->users)
kfree(cam); kfree(cam);
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include <linux/param.h> #include <linux/param.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <asm/semaphore.h> #include <linux/mutex.h>
#include <media/ovcamchip.h> #include <media/ovcamchip.h>
...@@ -194,14 +194,6 @@ enum w9968cf_vpp_flag { ...@@ -194,14 +194,6 @@ enum w9968cf_vpp_flag {
VPP_UYVY_TO_RGBX = 0x08, VPP_UYVY_TO_RGBX = 0x08,
}; };
static struct w9968cf_vpp_t* w9968cf_vpp;
static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
static DECLARE_MUTEX(w9968cf_devlist_sem); /* semaphore for list traversal */
static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */
/* Main device driver structure */ /* Main device driver structure */
struct w9968cf_device { struct w9968cf_device {
struct device dev; /* device structure */ struct device dev; /* device structure */
...@@ -277,8 +269,8 @@ struct w9968cf_device { ...@@ -277,8 +269,8 @@ struct w9968cf_device {
struct i2c_client* sensor_client; struct i2c_client* sensor_client;
/* Locks */ /* Locks */
struct semaphore dev_sem, /* for probe, disconnect,open and close */ struct mutex dev_mutex, /* for probe, disconnect,open and close */
fileop_sem; /* for read and ioctl */ fileop_mutex; /* for read and ioctl */
spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */ spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */
flist_lock; /* for requested frame list accesses */ flist_lock; /* for requested frame list accesses */
wait_queue_head_t open, wait_queue; wait_queue_head_t open, wait_queue;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/mutex.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/usb.h> #include <linux/usb.h>
...@@ -121,7 +122,7 @@ static struct usb_driver idmouse_driver = { ...@@ -121,7 +122,7 @@ static struct usb_driver idmouse_driver = {
}; };
/* prevent races between open() and disconnect() */ /* prevent races between open() and disconnect() */
static DECLARE_MUTEX(disconnect_sem); static DEFINE_MUTEX(disconnect_mutex);
static int idmouse_create_image(struct usb_idmouse *dev) static int idmouse_create_image(struct usb_idmouse *dev)
{ {
...@@ -213,18 +214,18 @@ static int idmouse_open(struct inode *inode, struct file *file) ...@@ -213,18 +214,18 @@ static int idmouse_open(struct inode *inode, struct file *file)
int result = 0; int result = 0;
/* prevent disconnects */ /* prevent disconnects */
down(&disconnect_sem); mutex_lock(&disconnect_mutex);
/* get the interface from minor number and driver information */ /* get the interface from minor number and driver information */
interface = usb_find_interface (&idmouse_driver, iminor (inode)); interface = usb_find_interface (&idmouse_driver, iminor (inode));
if (!interface) { if (!interface) {
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
return -ENODEV; return -ENODEV;
} }
/* get the device information block from the interface */ /* get the device information block from the interface */
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
if (!dev) { if (!dev) {
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
return -ENODEV; return -ENODEV;
} }
...@@ -258,7 +259,7 @@ static int idmouse_open(struct inode *inode, struct file *file) ...@@ -258,7 +259,7 @@ static int idmouse_open(struct inode *inode, struct file *file)
up(&dev->sem); up(&dev->sem);
/* unlock the disconnect semaphore */ /* unlock the disconnect semaphore */
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
return result; return result;
} }
...@@ -267,12 +268,12 @@ static int idmouse_release(struct inode *inode, struct file *file) ...@@ -267,12 +268,12 @@ static int idmouse_release(struct inode *inode, struct file *file)
struct usb_idmouse *dev; struct usb_idmouse *dev;
/* prevent a race condition with open() */ /* prevent a race condition with open() */
down(&disconnect_sem); mutex_lock(&disconnect_mutex);
dev = (struct usb_idmouse *) file->private_data; dev = (struct usb_idmouse *) file->private_data;
if (dev == NULL) { if (dev == NULL) {
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
return -ENODEV; return -ENODEV;
} }
...@@ -282,7 +283,7 @@ static int idmouse_release(struct inode *inode, struct file *file) ...@@ -282,7 +283,7 @@ static int idmouse_release(struct inode *inode, struct file *file)
/* are we really open? */ /* are we really open? */
if (dev->open <= 0) { if (dev->open <= 0) {
up(&dev->sem); up(&dev->sem);
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
return -ENODEV; return -ENODEV;
} }
...@@ -292,12 +293,12 @@ static int idmouse_release(struct inode *inode, struct file *file) ...@@ -292,12 +293,12 @@ static int idmouse_release(struct inode *inode, struct file *file)
/* the device was unplugged before the file was released */ /* the device was unplugged before the file was released */
up(&dev->sem); up(&dev->sem);
idmouse_delete(dev); idmouse_delete(dev);
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
return 0; return 0;
} }
up(&dev->sem); up(&dev->sem);
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
return 0; return 0;
} }
...@@ -399,7 +400,7 @@ static void idmouse_disconnect(struct usb_interface *interface) ...@@ -399,7 +400,7 @@ static void idmouse_disconnect(struct usb_interface *interface)
struct usb_idmouse *dev; struct usb_idmouse *dev;
/* prevent races with open() */ /* prevent races with open() */
down(&disconnect_sem); mutex_lock(&disconnect_mutex);
/* get device structure */ /* get device structure */
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
...@@ -421,7 +422,7 @@ static void idmouse_disconnect(struct usb_interface *interface) ...@@ -421,7 +422,7 @@ static void idmouse_disconnect(struct usb_interface *interface)
if (!dev->open) if (!dev->open)
idmouse_delete(dev); idmouse_delete(dev);
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
info("%s disconnected", DRIVER_DESC); info("%s disconnected", DRIVER_DESC);
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/input.h> #include <linux/input.h>
...@@ -172,7 +173,7 @@ struct ld_usb { ...@@ -172,7 +173,7 @@ struct ld_usb {
}; };
/* prevent races between open() and disconnect() */ /* prevent races between open() and disconnect() */
static DECLARE_MUTEX(disconnect_sem); static DEFINE_MUTEX(disconnect_mutex);
static struct usb_driver ld_usb_driver; static struct usb_driver ld_usb_driver;
...@@ -293,7 +294,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) ...@@ -293,7 +294,7 @@ static int ld_usb_open(struct inode *inode, struct file *file)
nonseekable_open(inode, file); nonseekable_open(inode, file);
subminor = iminor(inode); subminor = iminor(inode);
down(&disconnect_sem); mutex_lock(&disconnect_mutex);
interface = usb_find_interface(&ld_usb_driver, subminor); interface = usb_find_interface(&ld_usb_driver, subminor);
...@@ -355,7 +356,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) ...@@ -355,7 +356,7 @@ static int ld_usb_open(struct inode *inode, struct file *file)
up(&dev->sem); up(&dev->sem);
unlock_disconnect_exit: unlock_disconnect_exit:
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
return retval; return retval;
} }
...@@ -740,7 +741,7 @@ static void ld_usb_disconnect(struct usb_interface *intf) ...@@ -740,7 +741,7 @@ static void ld_usb_disconnect(struct usb_interface *intf)
struct ld_usb *dev; struct ld_usb *dev;
int minor; int minor;
down(&disconnect_sem); mutex_lock(&disconnect_mutex);
dev = usb_get_intfdata(intf); dev = usb_get_intfdata(intf);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
...@@ -761,7 +762,7 @@ static void ld_usb_disconnect(struct usb_interface *intf) ...@@ -761,7 +762,7 @@ static void ld_usb_disconnect(struct usb_interface *intf)
up(&dev->sem); up(&dev->sem);
} }
up(&disconnect_sem); mutex_unlock(&disconnect_mutex);
dev_info(&intf->dev, "LD USB Device #%d now disconnected\n", dev_info(&intf->dev, "LD USB Device #%d now disconnected\n",
(minor - USB_LD_MINOR_BASE)); (minor - USB_LD_MINOR_BASE));
......
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/mutex.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/poll.h> #include <linux/poll.h>
...@@ -256,7 +257,7 @@ static void tower_disconnect (struct usb_interface *interface); ...@@ -256,7 +257,7 @@ static void tower_disconnect (struct usb_interface *interface);
/* prevent races between open() and disconnect */ /* prevent races between open() and disconnect */
static DECLARE_MUTEX (disconnect_sem); static DEFINE_MUTEX (disconnect_mutex);
/* file operations needed when we register this driver */ /* file operations needed when we register this driver */
static struct file_operations tower_fops = { static struct file_operations tower_fops = {
...@@ -349,7 +350,7 @@ static int tower_open (struct inode *inode, struct file *file) ...@@ -349,7 +350,7 @@ static int tower_open (struct inode *inode, struct file *file)
nonseekable_open(inode, file); nonseekable_open(inode, file);
subminor = iminor(inode); subminor = iminor(inode);
down (&disconnect_sem); mutex_lock (&disconnect_mutex);
interface = usb_find_interface (&tower_driver, subminor); interface = usb_find_interface (&tower_driver, subminor);
...@@ -427,7 +428,7 @@ static int tower_open (struct inode *inode, struct file *file) ...@@ -427,7 +428,7 @@ static int tower_open (struct inode *inode, struct file *file)
up (&dev->sem); up (&dev->sem);
unlock_disconnect_exit: unlock_disconnect_exit:
up (&disconnect_sem); mutex_unlock (&disconnect_mutex);
dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval); dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval);
...@@ -1005,7 +1006,7 @@ static void tower_disconnect (struct usb_interface *interface) ...@@ -1005,7 +1006,7 @@ static void tower_disconnect (struct usb_interface *interface)
dbg(2, "%s: enter", __FUNCTION__); dbg(2, "%s: enter", __FUNCTION__);
down (&disconnect_sem); mutex_lock (&disconnect_mutex);
dev = usb_get_intfdata (interface); dev = usb_get_intfdata (interface);
usb_set_intfdata (interface, NULL); usb_set_intfdata (interface, NULL);
...@@ -1027,7 +1028,7 @@ static void tower_disconnect (struct usb_interface *interface) ...@@ -1027,7 +1028,7 @@ static void tower_disconnect (struct usb_interface *interface)
up (&dev->sem); up (&dev->sem);
} }
up (&disconnect_sem); mutex_unlock (&disconnect_mutex);
info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE)); info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE));
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/mutex.h>
#include "usb_mon.h" #include "usb_mon.h"
#include "../core/hcd.h" #include "../core/hcd.h"
...@@ -23,7 +24,7 @@ static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); ...@@ -23,7 +24,7 @@ static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus);
static void mon_bus_drop(struct kref *r); static void mon_bus_drop(struct kref *r);
static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus); static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus);
DECLARE_MUTEX(mon_lock); DEFINE_MUTEX(mon_lock);
static struct dentry *mon_dir; /* /dbg/usbmon */ static struct dentry *mon_dir; /* /dbg/usbmon */
static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */
...@@ -196,14 +197,14 @@ static void mon_bus_remove(struct usb_bus *ubus) ...@@ -196,14 +197,14 @@ static void mon_bus_remove(struct usb_bus *ubus)
{ {
struct mon_bus *mbus = ubus->mon_bus; struct mon_bus *mbus = ubus->mon_bus;
down(&mon_lock); mutex_lock(&mon_lock);
list_del(&mbus->bus_link); list_del(&mbus->bus_link);
debugfs_remove(mbus->dent_t); debugfs_remove(mbus->dent_t);
debugfs_remove(mbus->dent_s); debugfs_remove(mbus->dent_s);
mon_dissolve(mbus, ubus); mon_dissolve(mbus, ubus);
kref_put(&mbus->ref, mon_bus_drop); kref_put(&mbus->ref, mon_bus_drop);
up(&mon_lock); mutex_unlock(&mon_lock);
} }
static int mon_notify(struct notifier_block *self, unsigned long action, static int mon_notify(struct notifier_block *self, unsigned long action,
...@@ -307,9 +308,9 @@ static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) ...@@ -307,9 +308,9 @@ static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus)
goto err_create_s; goto err_create_s;
mbus->dent_s = d; mbus->dent_s = d;
down(&mon_lock); mutex_lock(&mon_lock);
list_add_tail(&mbus->bus_link, &mon_buses); list_add_tail(&mbus->bus_link, &mon_buses);
up(&mon_lock); mutex_unlock(&mon_lock);
return; return;
err_create_s: err_create_s:
...@@ -347,11 +348,11 @@ static int __init mon_init(void) ...@@ -347,11 +348,11 @@ static int __init mon_init(void)
usb_register_notify(&mon_nb); usb_register_notify(&mon_nb);
down(&usb_bus_list_lock); mutex_lock(&usb_bus_list_lock);
list_for_each_entry (ubus, &usb_bus_list, bus_list) { list_for_each_entry (ubus, &usb_bus_list, bus_list) {
mon_bus_init(mondir, ubus); mon_bus_init(mondir, ubus);
} }
up(&usb_bus_list_lock); mutex_unlock(&usb_bus_list_lock);
return 0; return 0;
} }
...@@ -363,7 +364,7 @@ static void __exit mon_exit(void) ...@@ -363,7 +364,7 @@ static void __exit mon_exit(void)
usb_unregister_notify(&mon_nb); usb_unregister_notify(&mon_nb);
usb_mon_deregister(); usb_mon_deregister();
down(&mon_lock); mutex_lock(&mon_lock);
while (!list_empty(&mon_buses)) { while (!list_empty(&mon_buses)) {
p = mon_buses.next; p = mon_buses.next;
mbus = list_entry(p, struct mon_bus, bus_link); mbus = list_entry(p, struct mon_bus, bus_link);
...@@ -387,7 +388,7 @@ static void __exit mon_exit(void) ...@@ -387,7 +388,7 @@ static void __exit mon_exit(void)
mon_dissolve(mbus, mbus->u_bus); mon_dissolve(mbus, mbus->u_bus);
kref_put(&mbus->ref, mon_bus_drop); kref_put(&mbus->ref, mon_bus_drop);
} }
up(&mon_lock); mutex_unlock(&mon_lock);
debugfs_remove(mon_dir); debugfs_remove(mon_dir);
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/mutex.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "usb_mon.h" #include "usb_mon.h"
...@@ -54,7 +55,7 @@ struct mon_reader_text { ...@@ -54,7 +55,7 @@ struct mon_reader_text {
wait_queue_head_t wait; wait_queue_head_t wait;
int printf_size; int printf_size;
char *printf_buf; char *printf_buf;
struct semaphore printf_lock; struct mutex printf_lock;
char slab_name[SLAB_NAME_SZ]; char slab_name[SLAB_NAME_SZ];
}; };
...@@ -208,7 +209,7 @@ static int mon_text_open(struct inode *inode, struct file *file) ...@@ -208,7 +209,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
struct mon_reader_text *rp; struct mon_reader_text *rp;
int rc; int rc;
down(&mon_lock); mutex_lock(&mon_lock);
mbus = inode->u.generic_ip; mbus = inode->u.generic_ip;
ubus = mbus->u_bus; ubus = mbus->u_bus;
...@@ -220,7 +221,7 @@ static int mon_text_open(struct inode *inode, struct file *file) ...@@ -220,7 +221,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
memset(rp, 0, sizeof(struct mon_reader_text)); memset(rp, 0, sizeof(struct mon_reader_text));
INIT_LIST_HEAD(&rp->e_list); INIT_LIST_HEAD(&rp->e_list);
init_waitqueue_head(&rp->wait); init_waitqueue_head(&rp->wait);
init_MUTEX(&rp->printf_lock); mutex_init(&rp->printf_lock);
rp->printf_size = PRINTF_DFL; rp->printf_size = PRINTF_DFL;
rp->printf_buf = kmalloc(rp->printf_size, GFP_KERNEL); rp->printf_buf = kmalloc(rp->printf_size, GFP_KERNEL);
...@@ -247,7 +248,7 @@ static int mon_text_open(struct inode *inode, struct file *file) ...@@ -247,7 +248,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
mon_reader_add(mbus, &rp->r); mon_reader_add(mbus, &rp->r);
file->private_data = rp; file->private_data = rp;
up(&mon_lock); mutex_unlock(&mon_lock);
return 0; return 0;
// err_busy: // err_busy:
...@@ -257,7 +258,7 @@ static int mon_text_open(struct inode *inode, struct file *file) ...@@ -257,7 +258,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
err_alloc_pr: err_alloc_pr:
kfree(rp); kfree(rp);
err_alloc: err_alloc:
up(&mon_lock); mutex_unlock(&mon_lock);
return rc; return rc;
} }
...@@ -301,7 +302,7 @@ static ssize_t mon_text_read(struct file *file, char __user *buf, ...@@ -301,7 +302,7 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&rp->wait, &waita); remove_wait_queue(&rp->wait, &waita);
down(&rp->printf_lock); mutex_lock(&rp->printf_lock);
cnt = 0; cnt = 0;
pbuf = rp->printf_buf; pbuf = rp->printf_buf;
limit = rp->printf_size; limit = rp->printf_size;
...@@ -358,7 +359,7 @@ static ssize_t mon_text_read(struct file *file, char __user *buf, ...@@ -358,7 +359,7 @@ static ssize_t mon_text_read(struct file *file, char __user *buf,
if (copy_to_user(buf, rp->printf_buf, cnt)) if (copy_to_user(buf, rp->printf_buf, cnt))
cnt = -EFAULT; cnt = -EFAULT;
up(&rp->printf_lock); mutex_unlock(&rp->printf_lock);
kmem_cache_free(rp->e_slab, ep); kmem_cache_free(rp->e_slab, ep);
return cnt; return cnt;
} }
...@@ -371,12 +372,12 @@ static int mon_text_release(struct inode *inode, struct file *file) ...@@ -371,12 +372,12 @@ static int mon_text_release(struct inode *inode, struct file *file)
struct list_head *p; struct list_head *p;
struct mon_event_text *ep; struct mon_event_text *ep;
down(&mon_lock); mutex_lock(&mon_lock);
mbus = inode->u.generic_ip; mbus = inode->u.generic_ip;
if (mbus->nreaders <= 0) { if (mbus->nreaders <= 0) {
printk(KERN_ERR TAG ": consistency error on close\n"); printk(KERN_ERR TAG ": consistency error on close\n");
up(&mon_lock); mutex_unlock(&mon_lock);
return 0; return 0;
} }
mon_reader_del(mbus, &rp->r); mon_reader_del(mbus, &rp->r);
...@@ -402,7 +403,7 @@ static int mon_text_release(struct inode *inode, struct file *file) ...@@ -402,7 +403,7 @@ static int mon_text_release(struct inode *inode, struct file *file)
kfree(rp->printf_buf); kfree(rp->printf_buf);
kfree(rp); kfree(rp);
up(&mon_lock); mutex_unlock(&mon_lock);
return 0; return 0;
} }
......
...@@ -49,7 +49,7 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); ...@@ -49,7 +49,7 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r);
*/ */
extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len); extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len);
extern struct semaphore mon_lock; extern struct mutex mon_lock;
extern struct file_operations mon_fops_text; extern struct file_operations mon_fops_text;
extern struct file_operations mon_fops_stat; extern struct file_operations mon_fops_stat;
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
...@@ -271,9 +272,9 @@ static int device_reset(struct scsi_cmnd *srb) ...@@ -271,9 +272,9 @@ static int device_reset(struct scsi_cmnd *srb)
US_DEBUGP("%s called\n", __FUNCTION__); US_DEBUGP("%s called\n", __FUNCTION__);
/* lock the device pointers and do the reset */ /* lock the device pointers and do the reset */
down(&(us->dev_semaphore)); mutex_lock(&(us->dev_mutex));
result = us->transport_reset(us); result = us->transport_reset(us);
up(&(us->dev_semaphore)); mutex_unlock(&us->dev_mutex);
return result < 0 ? FAILED : SUCCESS; return result < 0 ? FAILED : SUCCESS;
} }
...@@ -286,9 +287,9 @@ static int bus_reset(struct scsi_cmnd *srb) ...@@ -286,9 +287,9 @@ static int bus_reset(struct scsi_cmnd *srb)
US_DEBUGP("%s called\n", __FUNCTION__); US_DEBUGP("%s called\n", __FUNCTION__);
down(&(us->dev_semaphore)); mutex_lock(&(us->dev_mutex));
result = usb_stor_port_reset(us); result = usb_stor_port_reset(us);
up(&(us->dev_semaphore)); mutex_unlock(&us->dev_mutex);
return result < 0 ? FAILED : SUCCESS; return result < 0 ? FAILED : SUCCESS;
} }
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/mutex.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
...@@ -188,7 +189,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) ...@@ -188,7 +189,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
struct us_data *us = usb_get_intfdata(iface); struct us_data *us = usb_get_intfdata(iface);
/* Wait until no command is running */ /* Wait until no command is running */
down(&us->dev_semaphore); mutex_lock(&us->dev_mutex);
US_DEBUGP("%s\n", __FUNCTION__); US_DEBUGP("%s\n", __FUNCTION__);
if (us->suspend_resume_hook) if (us->suspend_resume_hook)
...@@ -198,7 +199,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) ...@@ -198,7 +199,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
/* When runtime PM is working, we'll set a flag to indicate /* When runtime PM is working, we'll set a flag to indicate
* whether we should autoresume when a SCSI request arrives. */ * whether we should autoresume when a SCSI request arrives. */
up(&us->dev_semaphore); mutex_unlock(&us->dev_mutex);
return 0; return 0;
} }
...@@ -206,14 +207,14 @@ static int storage_resume(struct usb_interface *iface) ...@@ -206,14 +207,14 @@ static int storage_resume(struct usb_interface *iface)
{ {
struct us_data *us = usb_get_intfdata(iface); struct us_data *us = usb_get_intfdata(iface);
down(&us->dev_semaphore); mutex_lock(&us->dev_mutex);
US_DEBUGP("%s\n", __FUNCTION__); US_DEBUGP("%s\n", __FUNCTION__);
if (us->suspend_resume_hook) if (us->suspend_resume_hook)
(us->suspend_resume_hook)(us, US_RESUME); (us->suspend_resume_hook)(us, US_RESUME);
iface->dev.power.power_state.event = PM_EVENT_ON; iface->dev.power.power_state.event = PM_EVENT_ON;
up(&us->dev_semaphore); mutex_unlock(&us->dev_mutex);
return 0; return 0;
} }
...@@ -276,12 +277,12 @@ static int usb_stor_control_thread(void * __us) ...@@ -276,12 +277,12 @@ static int usb_stor_control_thread(void * __us)
US_DEBUGP("*** thread awakened.\n"); US_DEBUGP("*** thread awakened.\n");
/* lock the device pointers */ /* lock the device pointers */
down(&(us->dev_semaphore)); mutex_lock(&(us->dev_mutex));
/* if the device has disconnected, we are free to exit */ /* if the device has disconnected, we are free to exit */
if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
US_DEBUGP("-- exiting\n"); US_DEBUGP("-- exiting\n");
up(&(us->dev_semaphore)); mutex_unlock(&us->dev_mutex);
break; break;
} }
...@@ -370,7 +371,7 @@ static int usb_stor_control_thread(void * __us) ...@@ -370,7 +371,7 @@ static int usb_stor_control_thread(void * __us)
scsi_unlock(host); scsi_unlock(host);
/* unlock the device pointers */ /* unlock the device pointers */
up(&(us->dev_semaphore)); mutex_unlock(&us->dev_mutex);
} /* for (;;) */ } /* for (;;) */
scsi_host_put(host); scsi_host_put(host);
...@@ -815,8 +816,8 @@ static void quiesce_and_remove_host(struct us_data *us) ...@@ -815,8 +816,8 @@ static void quiesce_and_remove_host(struct us_data *us)
* The thread will exit when it sees the DISCONNECTING flag. */ * The thread will exit when it sees the DISCONNECTING flag. */
/* Wait for the current command to finish, then remove the host */ /* Wait for the current command to finish, then remove the host */
down(&us->dev_semaphore); mutex_lock(&us->dev_mutex);
up(&us->dev_semaphore); mutex_unlock(&us->dev_mutex);
/* queuecommand won't accept any new commands and the control /* queuecommand won't accept any new commands and the control
* thread won't execute a previously-queued command. If there * thread won't execute a previously-queued command. If there
...@@ -870,9 +871,9 @@ static int usb_stor_scan_thread(void * __us) ...@@ -870,9 +871,9 @@ static int usb_stor_scan_thread(void * __us)
/* For bulk-only devices, determine the max LUN value */ /* For bulk-only devices, determine the max LUN value */
if (us->protocol == US_PR_BULK && if (us->protocol == US_PR_BULK &&
!(us->flags & US_FL_SINGLE_LUN)) { !(us->flags & US_FL_SINGLE_LUN)) {
down(&us->dev_semaphore); mutex_lock(&us->dev_mutex);
us->max_lun = usb_stor_Bulk_max_lun(us); us->max_lun = usb_stor_Bulk_max_lun(us);
up(&us->dev_semaphore); mutex_unlock(&us->dev_mutex);
} }
scsi_scan_host(us_to_host(us)); scsi_scan_host(us_to_host(us));
printk(KERN_DEBUG "usb-storage: device scan complete\n"); printk(KERN_DEBUG "usb-storage: device scan complete\n");
...@@ -912,7 +913,7 @@ static int storage_probe(struct usb_interface *intf, ...@@ -912,7 +913,7 @@ static int storage_probe(struct usb_interface *intf,
us = host_to_us(host); us = host_to_us(host);
memset(us, 0, sizeof(struct us_data)); memset(us, 0, sizeof(struct us_data));
init_MUTEX(&(us->dev_semaphore)); mutex_init(&(us->dev_mutex));
init_MUTEX_LOCKED(&(us->sema)); init_MUTEX_LOCKED(&(us->sema));
init_completion(&(us->notify)); init_completion(&(us->notify));
init_waitqueue_head(&us->delay_wait); init_waitqueue_head(&us->delay_wait);
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/mutex.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
struct us_data; struct us_data;
...@@ -103,9 +104,9 @@ typedef void (*pm_hook)(struct us_data *, int); /* power management hook */ ...@@ -103,9 +104,9 @@ typedef void (*pm_hook)(struct us_data *, int); /* power management hook */
struct us_data { struct us_data {
/* The device we're working with /* The device we're working with
* It's important to note: * It's important to note:
* (o) you must hold dev_semaphore to change pusb_dev * (o) you must hold dev_mutex to change pusb_dev
*/ */
struct semaphore dev_semaphore; /* protect pusb_dev */ struct mutex dev_mutex; /* protect pusb_dev */
struct usb_device *pusb_dev; /* this usb_device */ struct usb_device *pusb_dev; /* this usb_device */
struct usb_interface *pusb_intf; /* this interface */ struct usb_interface *pusb_intf; /* this interface */
struct us_unusual_dev *unusual_dev; /* device-filter entry */ struct us_unusual_dev *unusual_dev; /* device-filter entry */
......
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