*
*
* The driver brings the USB functions of the MDC800 to Linux.
- * To use the Camera you must support the USB Protocoll of the camera
+ * To use the Camera you must support the USB Protocol of the camera
* to the Kernel Node.
* The Driver uses a misc device Node. Create it with :
* mknod /dev/mustek c 180 32
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/smp_lock.h>
+#include <linux/wait.h>
#include <linux/usb.h>
#include <linux/fs.h>
/* Specification of the Endpoints */
static struct usb_endpoint_descriptor mdc800_ed [4] =
{
- { 0,0, 0x01, 0x02, 8, 0,0,0 },
- { 0,0, 0x82, 0x03, 8, 0,0,0 },
- { 0,0, 0x03, 0x02, 64, 0,0,0 },
- { 0,0, 0x84, 0x02, 64, 0,0,0 }
+ {
+ .bLength = 0,
+ .bDescriptorType = 0,
+ .bEndpointAddress = 0x01,
+ .bmAttributes = 0x02,
+ .wMaxPacketSize = __constant_cpu_to_le16(8),
+ .bInterval = 0,
+ .bRefresh = 0,
+ .bSynchAddress = 0,
+ },
+ {
+ .bLength = 0,
+ .bDescriptorType = 0,
+ .bEndpointAddress = 0x82,
+ .bmAttributes = 0x03,
+ .wMaxPacketSize = __constant_cpu_to_le16(8),
+ .bInterval = 0,
+ .bRefresh = 0,
+ .bSynchAddress = 0,
+ },
+ {
+ .bLength = 0,
+ .bDescriptorType = 0,
+ .bEndpointAddress = 0x03,
+ .bmAttributes = 0x02,
+ .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .bInterval = 0,
+ .bRefresh = 0,
+ .bSynchAddress = 0,
+ },
+ {
+ .bLength = 0,
+ .bDescriptorType = 0,
+ .bEndpointAddress = 0x84,
+ .bmAttributes = 0x02,
+ .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .bInterval = 0,
+ .bRefresh = 0,
+ .bSynchAddress = 0,
+ },
};
-
/* The Variable used by the driver */
-static struct mdc800_data* mdc800=0;
+static struct mdc800_data* mdc800;
/***************************************************************************
{
mdc800->camera_request_ready=0;
mdc800->irq_woken=1;
- wake_up_interruptible (&mdc800->irq_wait);
+ wake_up (&mdc800->irq_wait);
}
}
*/
static int mdc800_usb_waitForIRQ (int mode, int msec)
{
- DECLARE_WAITQUEUE(wait, current);
- long timeout;
-
mdc800->camera_request_ready=1+mode;
- add_wait_queue(&mdc800->irq_wait, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
- timeout = msec*HZ/1000;
- while (!mdc800->irq_woken && timeout)
- {
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout (timeout);
- }
- remove_wait_queue(&mdc800->irq_wait, &wait);
- set_current_state(TASK_RUNNING);
+ wait_event_timeout(mdc800->irq_wait, mdc800->irq_woken, msec*HZ/1000);
mdc800->irq_woken = 0;
if (mdc800->camera_request_ready>0)
mdc800->state=READY;
}
mdc800->written = 1;
- wake_up_interruptible (&mdc800->write_wait);
+ wake_up (&mdc800->write_wait);
}
err ("request bytes fails (status:%i)", urb->status);
}
mdc800->downloaded = 1;
- wake_up_interruptible (&mdc800->download_wait);
+ wake_up (&mdc800->download_wait);
}
static struct usb_driver mdc800_usb_driver;
static struct file_operations mdc800_device_ops;
static struct usb_class_driver mdc800_class = {
- .name = "usb/mdc800%d",
+ .name = "mdc800%d",
.fops = &mdc800_device_ops,
- .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
.minor_base = MDC800_DEVICE_MINOR_BASE,
};
dbg ("(mdc800_usb_probe) called.");
- if (mdc800->dev != 0)
+ if (mdc800->dev != NULL)
{
warn ("only one Mustek MDC800 is supported.");
return -ENODEV;
mdc800->state=NOT_CONNECTED;
- usb_unlink_urb (mdc800->irq_urb);
- usb_unlink_urb (mdc800->write_urb);
- usb_unlink_urb (mdc800->download_urb);
+ usb_kill_urb(mdc800->irq_urb);
+ usb_kill_urb(mdc800->write_urb);
+ usb_kill_urb(mdc800->download_urb);
- mdc800->dev=0;
+ mdc800->dev = NULL;
usb_set_intfdata(intf, NULL);
}
info ("Mustek MDC800 disconnected from USB.");
down (&mdc800->io_lock);
if (mdc800->open && (mdc800->state != NOT_CONNECTED))
{
- usb_unlink_urb (mdc800->irq_urb);
- usb_unlink_urb (mdc800->write_urb);
- usb_unlink_urb (mdc800->download_urb);
+ usb_kill_urb(mdc800->irq_urb);
+ usb_kill_urb(mdc800->write_urb);
+ usb_kill_urb(mdc800->download_urb);
mdc800->open=0;
}
else
/*
* The Device read callback Function
*/
-static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, loff_t *pos)
+static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t len, loff_t *pos)
{
size_t left=len, sts=len; /* single transfer size */
- char* ptr=buf;
- long timeout;
- DECLARE_WAITQUEUE(wait, current);
+ char __user *ptr = buf;
down (&mdc800->io_lock);
if (mdc800->state == NOT_CONNECTED)
up (&mdc800->io_lock);
return len-left;
}
- add_wait_queue(&mdc800->download_wait, &wait);
- timeout = TO_DOWNLOAD_GET_READY*HZ/1000;
- while (!mdc800->downloaded && timeout)
- {
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout (timeout);
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&mdc800->download_wait, &wait);
+ wait_event_timeout(mdc800->download_wait, mdc800->downloaded,
+ TO_DOWNLOAD_GET_READY*HZ/1000);
mdc800->downloaded = 0;
if (mdc800->download_urb->status != 0)
{
* After this the driver initiates the request for the answer or
* just waits until the camera becomes ready.
*/
-static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos)
+static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos)
{
size_t i=0;
- DECLARE_WAITQUEUE(wait, current);
down (&mdc800->io_lock);
if (mdc800->state != READY)
if (mdc800->in_count == 8)
{
int answersize;
- long timeout;
if (mdc800_usb_waitForIRQ (0,TO_GET_READY))
{
up (&mdc800->io_lock);
return -EIO;
}
- add_wait_queue(&mdc800->write_wait, &wait);
- timeout = TO_WRITE_GET_READY*HZ/1000;
- while (!mdc800->written && timeout)
- {
- set_current_state(TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout (timeout);
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&mdc800->write_wait, &wait);
+ wait_event_timeout(mdc800->write_wait, mdc800->written, TO_WRITE_GET_READY*HZ/1000);
mdc800->written = 0;
if (mdc800->state == WORKING)
{
- usb_unlink_urb (mdc800->write_urb);
+ usb_kill_urb(mdc800->write_urb);
up (&mdc800->io_lock);
return -EIO;
}
*/
static struct usb_driver mdc800_usb_driver =
{
- .owner = THIS_MODULE,
.name = "mdc800",
.probe = mdc800_usb_probe,
.disconnect = mdc800_usb_disconnect,
Init and Cleanup this driver (Main Functions)
*************************************************************************/
-#define try(A) if ((A) == 0) goto cleanup_on_fail;
-#define try_free_mem(A) if (A != 0) { kfree (A); A=0; }
-#define try_free_urb(A) if (A != 0) { usb_free_urb (A); A=0; }
-
static int __init usb_mdc800_init (void)
{
int retval = -ENODEV;
/* Allocate Memory */
- try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL));
+ mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL);
+ if (!mdc800)
+ goto cleanup_on_fail;
memset(mdc800, 0, sizeof(struct mdc800_data));
- mdc800->dev=0;
+ mdc800->dev = NULL;
mdc800->open=0;
mdc800->state=NOT_CONNECTED;
init_MUTEX (&mdc800->io_lock);
mdc800->downloaded = 0;
mdc800->written = 0;
- try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL));
- try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL));
- try (mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL));
+ mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL);
+ if (!mdc800->irq_urb_buffer)
+ goto cleanup_on_fail;
+ mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL);
+ if (!mdc800->write_urb_buffer)
+ goto cleanup_on_fail;
+ mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL);
+ if (!mdc800->download_urb_buffer)
+ goto cleanup_on_fail;
- try (mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL));
- try (mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL));
- try (mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL));
+ mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL);
+ if (!mdc800->irq_urb)
+ goto cleanup_on_fail;
+ mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL);
+ if (!mdc800->download_urb)
+ goto cleanup_on_fail;
+ mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL);
+ if (!mdc800->write_urb)
+ goto cleanup_on_fail;
/* Register the driver */
retval = usb_register(&mdc800_usb_driver);
cleanup_on_fail:
- if (mdc800 != 0)
+ if (mdc800 != NULL)
{
err ("can't alloc memory!");
- try_free_mem (mdc800->download_urb_buffer);
- try_free_mem (mdc800->write_urb_buffer);
- try_free_mem (mdc800->irq_urb_buffer);
+ kfree(mdc800->download_urb_buffer);
+ kfree(mdc800->write_urb_buffer);
+ kfree(mdc800->irq_urb_buffer);
- try_free_urb (mdc800->write_urb);
- try_free_urb (mdc800->download_urb);
- try_free_urb (mdc800->irq_urb);
+ usb_free_urb(mdc800->write_urb);
+ usb_free_urb(mdc800->download_urb);
+ usb_free_urb(mdc800->irq_urb);
kfree (mdc800);
}
- mdc800=0;
+ mdc800 = NULL;
return retval;
}
kfree (mdc800->download_urb_buffer);
kfree (mdc800);
- mdc800=0;
+ mdc800 = NULL;
}
module_init (usb_mdc800_init);