[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: Arjan van de Ven <arjan@infradead.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
35cce732d9
commit
4186ecf8ad
|
@ -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;
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
} 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)
|
||||||
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)
|
||||||
|
|
||||||
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 @@
|
||||||
#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);
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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 @@
|
||||||
#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
|
||||||
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
|
||||||
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 @@
|
||||||
#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 {
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
* 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,
|
||||||
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,
|
||||||
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)
|
||||||
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,
|
||||||
/* 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 @@
|
||||||
#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
|
||||||
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,
|
||||||
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,
|
||||||
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 @@
|
||||||
#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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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 @@
|
||||||
#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)
|
||||||
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)
|
||||||
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 @@
|
||||||
#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
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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
|
||||||
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
|
||||||
{
|
{
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
/* 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
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
|
||||||
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
|
||||||
}
|
}
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
{
|
{
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
||||||
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 };
|
||||||
*/
|
*/
|
||||||
#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 @@
|
||||||
#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
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
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)
|
||||||
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;
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
{
|
{
|
||||||
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 @@ out:
|
||||||
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,
|
||||||
{
|
{
|
||||||
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 @@ out:
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
// 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)
|
||||||
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)
|
||||||
|
|
||||||
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
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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,
|
||||||
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)
|
||||||
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 @@ restart:
|
||||||
|
|
||||||
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)
|
||||||
+ 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)
|
||||||
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)
|
||||||
|
|
||||||
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 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
/* 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 @@
|
||||||
#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 {
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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 @@
|
||||||
#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 {
|
||||||
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 @@
|
||||||
#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 {
|
||||||
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 {
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -866,18 +866,18 @@ static ssize_t sn9c102_show_reg(struct class_device* cd, char* buf)
|
||||||
struct sn9c102_device* cam;
|
struct sn9c102_device* cam;
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
|
|
||||||
if (down_interruptible(&sn9c102_sysfs_lock))
|
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
cam = video_get_drvdata(to_video_device(cd));
|
cam = video_get_drvdata(to_video_device(cd));
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = sprintf(buf, "%u\n", cam->sysfs.reg);
|
count = sprintf(buf, "%u\n", cam->sysfs.reg);
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -890,18 +890,18 @@ sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len)
|
||||||
u8 index;
|
u8 index;
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
|
|
||||||
if (down_interruptible(&sn9c102_sysfs_lock))
|
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
cam = video_get_drvdata(to_video_device(cd));
|
cam = video_get_drvdata(to_video_device(cd));
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = sn9c102_strtou8(buf, len, &count);
|
index = sn9c102_strtou8(buf, len, &count);
|
||||||
if (index > 0x1f || !count) {
|
if (index > 0x1f || !count) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,7 +910,7 @@ sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len)
|
||||||
DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg);
|
DBG(2, "Moved SN9C10X register index to 0x%02X", cam->sysfs.reg);
|
||||||
DBG(3, "Written bytes: %zd", count);
|
DBG(3, "Written bytes: %zd", count);
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -922,17 +922,17 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
if (down_interruptible(&sn9c102_sysfs_lock))
|
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
cam = video_get_drvdata(to_video_device(cd));
|
cam = video_get_drvdata(to_video_device(cd));
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) {
|
if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,7 +940,7 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
|
||||||
|
|
||||||
DBG(3, "Read bytes: %zd", count);
|
DBG(3, "Read bytes: %zd", count);
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -954,24 +954,24 @@ sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (down_interruptible(&sn9c102_sysfs_lock))
|
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
cam = video_get_drvdata(to_video_device(cd));
|
cam = video_get_drvdata(to_video_device(cd));
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = sn9c102_strtou8(buf, len, &count);
|
value = sn9c102_strtou8(buf, len, &count);
|
||||||
if (!count) {
|
if (!count) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
|
err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
|
||||||
if (err) {
|
if (err) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,7 +979,7 @@ sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
|
||||||
cam->sysfs.reg, value);
|
cam->sysfs.reg, value);
|
||||||
DBG(3, "Written bytes: %zd", count);
|
DBG(3, "Written bytes: %zd", count);
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -990,12 +990,12 @@ static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf)
|
||||||
struct sn9c102_device* cam;
|
struct sn9c102_device* cam;
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
|
|
||||||
if (down_interruptible(&sn9c102_sysfs_lock))
|
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
cam = video_get_drvdata(to_video_device(cd));
|
cam = video_get_drvdata(to_video_device(cd));
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1003,7 +1003,7 @@ static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf)
|
||||||
|
|
||||||
DBG(3, "Read bytes: %zd", count);
|
DBG(3, "Read bytes: %zd", count);
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -1016,18 +1016,18 @@ sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
|
||||||
u8 index;
|
u8 index;
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
|
|
||||||
if (down_interruptible(&sn9c102_sysfs_lock))
|
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
cam = video_get_drvdata(to_video_device(cd));
|
cam = video_get_drvdata(to_video_device(cd));
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = sn9c102_strtou8(buf, len, &count);
|
index = sn9c102_strtou8(buf, len, &count);
|
||||||
if (!count) {
|
if (!count) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,7 +1036,7 @@ sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
|
||||||
DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
|
DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
|
||||||
DBG(3, "Written bytes: %zd", count);
|
DBG(3, "Written bytes: %zd", count);
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -1048,22 +1048,22 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
if (down_interruptible(&sn9c102_sysfs_lock))
|
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
cam = video_get_drvdata(to_video_device(cd));
|
cam = video_get_drvdata(to_video_device(cd));
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cam->sensor->sysfs_ops & SN9C102_I2C_READ)) {
|
if (!(cam->sensor->sysfs_ops & SN9C102_I2C_READ)) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
|
if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1071,7 +1071,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
|
||||||
|
|
||||||
DBG(3, "Read bytes: %zd", count);
|
DBG(3, "Read bytes: %zd", count);
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -1085,29 +1085,29 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (down_interruptible(&sn9c102_sysfs_lock))
|
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
cam = video_get_drvdata(to_video_device(cd));
|
cam = video_get_drvdata(to_video_device(cd));
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
|
if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = sn9c102_strtou8(buf, len, &count);
|
value = sn9c102_strtou8(buf, len, &count);
|
||||||
if (!count) {
|
if (!count) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
|
err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
|
||||||
if (err) {
|
if (err) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1115,7 +1115,7 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
|
||||||
cam->sysfs.i2c_reg, value);
|
cam->sysfs.i2c_reg, value);
|
||||||
DBG(3, "Written bytes: %zd", count);
|
DBG(3, "Written bytes: %zd", count);
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -1130,18 +1130,18 @@ sn9c102_store_green(struct class_device* cd, const char* buf, size_t len)
|
||||||
u8 value;
|
u8 value;
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
|
|
||||||
if (down_interruptible(&sn9c102_sysfs_lock))
|
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
cam = video_get_drvdata(to_video_device(cd));
|
cam = video_get_drvdata(to_video_device(cd));
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge = cam->bridge;
|
bridge = cam->bridge;
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
value = sn9c102_strtou8(buf, len, &count);
|
value = sn9c102_strtou8(buf, len, &count);
|
||||||
if (!count)
|
if (!count)
|
||||||
|
@ -1404,7 +1404,7 @@ static int sn9c102_init(struct sn9c102_device* cam)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cam->state & DEV_INITIALIZED)) {
|
if (!(cam->state & DEV_INITIALIZED)) {
|
||||||
init_MUTEX(&cam->fileop_sem);
|
mutex_init(&cam->fileop_mutex);
|
||||||
spin_lock_init(&cam->queue_lock);
|
spin_lock_init(&cam->queue_lock);
|
||||||
init_waitqueue_head(&cam->wait_frame);
|
init_waitqueue_head(&cam->wait_frame);
|
||||||
init_waitqueue_head(&cam->wait_stream);
|
init_waitqueue_head(&cam->wait_stream);
|
||||||
|
@ -1422,13 +1422,13 @@ static int sn9c102_init(struct sn9c102_device* cam)
|
||||||
|
|
||||||
static void sn9c102_release_resources(struct sn9c102_device* cam)
|
static void sn9c102_release_resources(struct sn9c102_device* cam)
|
||||||
{
|
{
|
||||||
down(&sn9c102_sysfs_lock);
|
mutex_lock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
|
DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
|
||||||
video_set_drvdata(cam->v4ldev, NULL);
|
video_set_drvdata(cam->v4ldev, NULL);
|
||||||
video_unregister_device(cam->v4ldev);
|
video_unregister_device(cam->v4ldev);
|
||||||
|
|
||||||
up(&sn9c102_sysfs_lock);
|
mutex_unlock(&sn9c102_sysfs_lock);
|
||||||
|
|
||||||
kfree(cam->control_buffer);
|
kfree(cam->control_buffer);
|
||||||
}
|
}
|
||||||
|
@ -1449,7 +1449,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
|
||||||
|
|
||||||
cam = video_get_drvdata(video_devdata(filp));
|
cam = video_get_drvdata(video_devdata(filp));
|
||||||
|
|
||||||
if (down_interruptible(&cam->dev_sem)) {
|
if (mutex_lock_interruptible(&cam->dev_mutex)) {
|
||||||
up_read(&sn9c102_disconnect);
|
up_read(&sn9c102_disconnect);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
@ -1461,7 +1461,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
|
||||||
err = -EWOULDBLOCK;
|
err = -EWOULDBLOCK;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
up(&cam->dev_sem);
|
mutex_unlock(&cam->dev_mutex);
|
||||||
err = wait_event_interruptible_exclusive(cam->open,
|
err = wait_event_interruptible_exclusive(cam->open,
|
||||||
cam->state & DEV_DISCONNECTED
|
cam->state & DEV_DISCONNECTED
|
||||||
|| !cam->users);
|
|| !cam->users);
|
||||||
|
@ -1473,7 +1473,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
|
||||||
up_read(&sn9c102_disconnect);
|
up_read(&sn9c102_disconnect);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
down(&cam->dev_sem);
|
mutex_lock(&cam->dev_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1501,7 +1501,7 @@ static int sn9c102_open(struct inode* inode, struct file* filp)
|
||||||
DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
|
DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
up(&cam->dev_sem);
|
mutex_unlock(&cam->dev_mutex);
|
||||||
up_read(&sn9c102_disconnect);
|
up_read(&sn9c102_disconnect);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1511,7 +1511,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp)
|
||||||
{
|
{
|
||||||
struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
|
struct sn9c102_device* cam = 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 */
|
||||||
|
|
||||||
sn9c102_stop_transfer(cam);
|
sn9c102_stop_transfer(cam);
|
||||||
|
|
||||||
|
@ -1519,7 +1519,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp)
|
||||||
|
|
||||||
if (cam->state & DEV_DISCONNECTED) {
|
if (cam->state & DEV_DISCONNECTED) {
|
||||||
sn9c102_release_resources(cam);
|
sn9c102_release_resources(cam);
|
||||||
up(&cam->dev_sem);
|
mutex_unlock(&cam->dev_mutex);
|
||||||
kfree(cam);
|
kfree(cam);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1529,7 +1529,7 @@ static int sn9c102_release(struct inode* inode, struct file* filp)
|
||||||
|
|
||||||
DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
|
DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
|
||||||
|
|
||||||
up(&cam->dev_sem);
|
mutex_unlock(&cam->dev_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1543,33 +1543,33 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
|
||||||
unsigned long lock_flags;
|
unsigned long lock_flags;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (down_interruptible(&cam->fileop_sem))
|
if (mutex_lock_interruptible(&cam->fileop_mutex))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
if (cam->state & DEV_DISCONNECTED) {
|
if (cam->state & DEV_DISCONNECTED) {
|
||||||
DBG(1, "Device not present");
|
DBG(1, "Device not present");
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cam->state & DEV_MISCONFIGURED) {
|
if (cam->state & DEV_MISCONFIGURED) {
|
||||||
DBG(1, "The camera is misconfigured. Close and open it "
|
DBG(1, "The camera is misconfigured. Close and open it "
|
||||||
"again.");
|
"again.");
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cam->io == IO_MMAP) {
|
if (cam->io == IO_MMAP) {
|
||||||
DBG(3, "Close and open the device again to choose "
|
DBG(3, "Close and open the device again to choose "
|
||||||
"the read method");
|
"the read method");
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cam->io == IO_NONE) {
|
if (cam->io == IO_NONE) {
|
||||||
if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
|
if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
|
||||||
DBG(1, "read() failed, not enough memory");
|
DBG(1, "read() failed, not enough memory");
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
cam->io = IO_READ;
|
cam->io = IO_READ;
|
||||||
|
@ -1583,13 +1583,13 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!count) {
|
if (!count) {
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list_empty(&cam->outqueue)) {
|
if (list_empty(&cam->outqueue)) {
|
||||||
if (filp->f_flags & O_NONBLOCK) {
|
if (filp->f_flags & O_NONBLOCK) {
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
err = wait_event_interruptible
|
err = wait_event_interruptible
|
||||||
|
@ -1598,15 +1598,15 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
|
||||||
(cam->state & DEV_DISCONNECTED) ||
|
(cam->state & DEV_DISCONNECTED) ||
|
||||||
(cam->state & DEV_MISCONFIGURED) );
|
(cam->state & DEV_MISCONFIGURED) );
|
||||||
if (err) {
|
if (err) {
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (cam->state & DEV_DISCONNECTED) {
|
if (cam->state & DEV_DISCONNECTED) {
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
if (cam->state & DEV_MISCONFIGURED) {
|
if (cam->state & DEV_MISCONFIGURED) {
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1634,7 +1634,7 @@ exit:
|
||||||
PDBGG("Frame #%lu, bytes read: %zu",
|
PDBGG("Frame #%lu, bytes read: %zu",
|
||||||
(unsigned long)f->buf.index, count);
|
(unsigned long)f->buf.index, count);
|
||||||
|
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -1647,7 +1647,7 @@ static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
|
||||||
unsigned long lock_flags;
|
unsigned long lock_flags;
|
||||||
unsigned int mask = 0;
|
unsigned int mask = 0;
|
||||||
|
|
||||||
if (down_interruptible(&cam->fileop_sem))
|
if (mutex_lock_interruptible(&cam->fileop_mutex))
|
||||||
return POLLERR;
|
return POLLERR;
|
||||||
|
|
||||||
if (cam->state & DEV_DISCONNECTED) {
|
if (cam->state & DEV_DISCONNECTED) {
|
||||||
|
@ -1685,12 +1685,12 @@ static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
|
||||||
if (!list_empty(&cam->outqueue))
|
if (!list_empty(&cam->outqueue))
|
||||||
mask |= POLLIN | POLLRDNORM;
|
mask |= POLLIN | POLLRDNORM;
|
||||||
|
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return POLLERR;
|
return POLLERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1724,25 +1724,25 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
|
||||||
void *pos;
|
void *pos;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
if (down_interruptible(&cam->fileop_sem))
|
if (mutex_lock_interruptible(&cam->fileop_mutex))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
if (cam->state & DEV_DISCONNECTED) {
|
if (cam->state & DEV_DISCONNECTED) {
|
||||||
DBG(1, "Device not present");
|
DBG(1, "Device not present");
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cam->state & DEV_MISCONFIGURED) {
|
if (cam->state & DEV_MISCONFIGURED) {
|
||||||
DBG(1, "The camera is misconfigured. Close and open it "
|
DBG(1, "The camera is misconfigured. Close and open it "
|
||||||
"again.");
|
"again.");
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
|
if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
|
||||||
size != PAGE_ALIGN(cam->frame[0].buf.length)) {
|
size != PAGE_ALIGN(cam->frame[0].buf.length)) {
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1751,7 +1751,7 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == cam->nbuffers) {
|
if (i == cam->nbuffers) {
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1761,7 +1761,7 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
|
||||||
pos = cam->frame[i].bufmem;
|
pos = cam->frame[i].bufmem;
|
||||||
while (size > 0) { /* size is page-aligned */
|
while (size > 0) { /* size is page-aligned */
|
||||||
if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
|
if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
start += PAGE_SIZE;
|
start += PAGE_SIZE;
|
||||||
|
@ -1774,7 +1774,7 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma)
|
||||||
|
|
||||||
sn9c102_vm_open(vma);
|
sn9c102_vm_open(vma);
|
||||||
|
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2655,19 +2655,19 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
|
||||||
struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
|
struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (down_interruptible(&cam->fileop_sem))
|
if (mutex_lock_interruptible(&cam->fileop_mutex))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
if (cam->state & DEV_DISCONNECTED) {
|
if (cam->state & DEV_DISCONNECTED) {
|
||||||
DBG(1, "Device not present");
|
DBG(1, "Device not present");
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cam->state & DEV_MISCONFIGURED) {
|
if (cam->state & DEV_MISCONFIGURED) {
|
||||||
DBG(1, "The camera is misconfigured. Close and open it "
|
DBG(1, "The camera is misconfigured. Close and open it "
|
||||||
"again.");
|
"again.");
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2675,7 +2675,7 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
|
||||||
|
|
||||||
err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
|
err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg);
|
||||||
|
|
||||||
up(&cam->fileop_sem);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -2722,7 +2722,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_MUTEX(&cam->dev_sem);
|
mutex_init(&cam->dev_mutex);
|
||||||
|
|
||||||
r = sn9c102_read_reg(cam, 0x00);
|
r = sn9c102_read_reg(cam, 0x00);
|
||||||
if (r < 0 || r != 0x10) {
|
if (r < 0 || r != 0x10) {
|
||||||
|
@ -2776,7 +2776,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
|
||||||
cam->v4ldev->release = video_device_release;
|
cam->v4ldev->release = video_device_release;
|
||||||
video_set_drvdata(cam->v4ldev, cam);
|
video_set_drvdata(cam->v4ldev, cam);
|
||||||
|
|
||||||
down(&cam->dev_sem);
|
mutex_lock(&cam->dev_mutex);
|
||||||
|
|
||||||
err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
|
err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
|
||||||
video_nr[dev_nr]);
|
video_nr[dev_nr]);
|
||||||
|
@ -2786,7 +2786,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
|
||||||
DBG(1, "Free /dev/videoX node not found");
|
DBG(1, "Free /dev/videoX node not found");
|
||||||
video_nr[dev_nr] = -1;
|
video_nr[dev_nr] = -1;
|
||||||
dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
|
dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
|
||||||
up(&cam->dev_sem);
|
mutex_unlock(&cam->dev_mutex);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2803,7 +2803,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
|
||||||
|
|
||||||
usb_set_intfdata(intf, cam);
|
usb_set_intfdata(intf, cam);
|
||||||
|
|
||||||
up(&cam->dev_sem);
|
mutex_unlock(&cam->dev_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -2827,7 +2827,7 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf)
|
||||||
|
|
||||||
down_write(&sn9c102_disconnect);
|
down_write(&sn9c102_disconnect);
|
||||||
|
|
||||||
down(&cam->dev_sem);
|
mutex_lock(&cam->dev_mutex);
|
||||||
|
|
||||||
DBG(2, "Disconnecting %s...", cam->v4ldev->name);
|
DBG(2, "Disconnecting %s...", cam->v4ldev->name);
|
||||||
|
|
||||||
|
@ -2847,7 +2847,7 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf)
|
||||||
sn9c102_release_resources(cam);
|
sn9c102_release_resources(cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
up(&cam->dev_sem);
|
mutex_unlock(&cam->dev_mutex);
|
||||||
|
|
||||||
if (!cam->users)
|
if (!cam->users)
|
||||||
kfree(cam);
|
kfree(cam);
|
||||||
|
|
|
@ -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)
|
||||||
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)
|
||||||
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
|
||||||
|
|
||||||
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 {
|
||||||
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(
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
/* 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)
|
||||||
* 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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_done:
|
read_done:
|
||||||
up(&uvd->lock);
|
mutex_unlock(&uvd->lock);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
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 {
|
||||||
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 @@
|
||||||
#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 {
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
|
|
||||||
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 @@
|
||||||
#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,
|
||||||
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)
|
||||||
--------------------------------------------------------------------------*/
|
--------------------------------------------------------------------------*/
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 @@ fail: /* Free unused memory */
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
} 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 @@
|
||||||
#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 {
|
||||||
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 {
|
||||||
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 @@
|
||||||
#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 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 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)
|
||||||
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 @@ error:
|
||||||
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)
|
||||||
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)
|
||||||
/* 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)
|
||||||
/* 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)
|
||||||
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)
|
||||||
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 @@
|
||||||
#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 {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 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)
|
||||||
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 @@ unlock_exit:
|
||||||
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)
|
||||||
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)
|
||||||
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 @@
|
||||||
#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);
|
||||||
|
|
||||||
|
|
||||||
/* 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)
|
||||||
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 @@ unlock_exit:
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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 @@
|
||||||
#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);
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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 @@
|
||||||
#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 {
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 @@ err_slab:
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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);
|
||||||
*/
|
*/
|
||||||
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 @@
|
||||||
|
|
||||||
#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)
|
||||||
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)
|
||||||
|
|
||||||
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 @@
|
||||||
#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)
|
||||||
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)
|
||||||
/* 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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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 @@ SkipForAbort:
|
||||||
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)
|
||||||
* 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 @@ retry:
|
||||||
/* 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,
|
||||||
|
|
||||||
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 @@
|
||||||
#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 */
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in New Issue