X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fimage%2Fmdc800.c;h=83f3c9feae2b81e720c40c53927a8205c0f9f17d;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=f1b934c54088724e9b3c85e662ff534737da2bf3;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index f1b934c54..83f3c9fea 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -33,7 +33,7 @@ * Fix: mdc800 used sleep_on and slept with io_lock held. * Converted sleep_on to waitqueues with schedule_timeout and made io_lock * a semaphore from a spinlock. - * by Oliver Neukum <520047054719-0001@t-online.de> + * by Oliver Neukum * (02/12/2001) * * Identify version on module load. @@ -41,7 +41,7 @@ * * version 0.7.5 * Fixed potential SMP races with Spinlocks. - * Thanks to Oliver Neukum who + * Thanks to Oliver Neukum who * noticed the race conditions. * (30/10/2000) * @@ -182,15 +182,50 @@ struct mdc800_data /* 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; /*************************************************************************** @@ -312,17 +347,18 @@ static void mdc800_usb_irq (struct urb *urb, struct pt_regs *res) 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); - if (!mdc800->irq_woken) + timeout = msec*HZ/1000; + while (!mdc800->irq_woken && timeout) { - schedule_timeout (msec*HZ/1000); + set_current_state(TASK_UNINTERRUPTIBLE); + timeout = schedule_timeout (timeout); } remove_wait_queue(&mdc800->irq_wait, &wait); - set_current_state(TASK_RUNNING); mdc800->irq_woken = 0; if (mdc800->camera_request_ready>0) @@ -420,7 +456,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, dbg ("(mdc800_usb_probe) called."); - if (mdc800->dev != 0) + if (mdc800->dev != NULL) { warn ("only one Mustek MDC800 is supported."); return -ENODEV; @@ -540,11 +576,11 @@ static void mdc800_usb_disconnect (struct usb_interface *intf) 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."); @@ -646,9 +682,9 @@ static int mdc800_device_release (struct inode* inode, struct file *file) 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 @@ -664,10 +700,11 @@ static int mdc800_device_release (struct inode* inode, struct file *file) /* * 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; + char __user *ptr = buf; + long timeout; DECLARE_WAITQUEUE(wait, current); down (&mdc800->io_lock); @@ -715,12 +752,12 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof return len-left; } add_wait_queue(&mdc800->download_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - if (!mdc800->downloaded) + timeout = TO_DOWNLOAD_GET_READY*HZ/1000; + while (!mdc800->downloaded && timeout) { - schedule_timeout (TO_DOWNLOAD_GET_READY*HZ/1000); + set_current_state(TASK_UNINTERRUPTIBLE); + timeout = schedule_timeout (timeout); } - set_current_state(TASK_RUNNING); remove_wait_queue(&mdc800->download_wait, &wait); mdc800->downloaded = 0; if (mdc800->download_urb->status != 0) @@ -762,7 +799,7 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof * 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); @@ -819,6 +856,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l if (mdc800->in_count == 8) { int answersize; + long timeout; if (mdc800_usb_waitForIRQ (0,TO_GET_READY)) { @@ -839,17 +877,17 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l return -EIO; } add_wait_queue(&mdc800->write_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - if (!mdc800->written) + timeout = TO_WRITE_GET_READY*HZ/1000; + while (!mdc800->written && timeout) { - schedule_timeout (TO_WRITE_GET_READY*HZ/1000); + set_current_state(TASK_UNINTERRUPTIBLE); + timeout = schedule_timeout (timeout); } - set_current_state(TASK_RUNNING); remove_wait_queue(&mdc800->write_wait, &wait); 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; } @@ -964,9 +1002,7 @@ static struct usb_driver mdc800_usb_driver = 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; } +#define try(A) if (!(A)) goto cleanup_on_fail; static int __init usb_mdc800_init (void) { @@ -975,7 +1011,7 @@ static int __init usb_mdc800_init (void) try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL)); 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); @@ -1009,21 +1045,21 @@ static int __init usb_mdc800_init (void) 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; } @@ -1041,7 +1077,7 @@ static void __exit usb_mdc800_cleanup (void) kfree (mdc800->download_urb_buffer); kfree (mdc800); - mdc800=0; + mdc800 = NULL; } module_init (usb_mdc800_init);