X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fmisc%2Fauerswald.c;h=b5332e679c4644f86ed1ab0a45459ebf9810b04c;hb=refs%2Fheads%2Fvserver;hp=b137da951670e9e2b3791b3ca2bb8b9199f6eede;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index b137da951..b5332e679 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -2,7 +2,7 @@ /* * auerswald.c -- Auerswald PBX/System Telephone usb driver. * - * Copyright (C) 2001 Wolfgang Mües (wolfgang@iksw-muees.de) + * Copyright (C) 2001 Wolfgang Mües (wolfgang@iksw-muees.de) * * Very much code of this driver is borrowed from dabusb.c (Deti Fliegl) * and from the USB Skeleton driver (Greg Kroah-Hartman). Thank you. @@ -29,7 +29,7 @@ #include #include #include -#undef DEBUG /* include debug macros until it's done */ +#include #include /*-------------------------------------------------------------------*/ @@ -50,7 +50,7 @@ do { \ /*-------------------------------------------------------------------*/ /* Version Information */ #define DRIVER_VERSION "0.9.11" -#define DRIVER_AUTHOR "Wolfgang Mües " +#define DRIVER_AUTHOR "Wolfgang Mües " #define DRIVER_DESC "Auerswald PBX/System Telephone usb driver" /*-------------------------------------------------------------------*/ @@ -267,9 +267,9 @@ typedef struct /*-------------------------------------------------------------------*/ /* Forwards */ -static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs); +static void auerswald_ctrlread_complete (struct urb * urb); static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp); -extern struct usb_driver auerswald_driver; +static struct usb_driver auerswald_driver; /*-------------------------------------------------------------------*/ @@ -277,7 +277,7 @@ extern struct usb_driver auerswald_driver; /* -------------------------- */ /* completion function for chained urbs */ -static void auerchain_complete (struct urb * urb, struct pt_regs *regs) +static void auerchain_complete (struct urb * urb) { unsigned long flags; int result; @@ -296,7 +296,7 @@ static void auerchain_complete (struct urb * urb, struct pt_regs *regs) NOTE: this function may lead to more urbs submitted into the chain. (no chain lock at calling complete()!) acp->active != NULL is protecting us against recursion.*/ - urb->complete (urb, regs); + urb->complete (urb); /* detach element from chain data structure */ spin_lock_irqsave (&acp->lock, flags); @@ -331,7 +331,7 @@ static void auerchain_complete (struct urb * urb, struct pt_regs *regs) urb->status = result; dbg("auerchain_complete: usb_submit_urb with error code %d", result); /* and do error handling via *this* completion function (recursive) */ - auerchain_complete( urb, NULL); + auerchain_complete( urb); } } else { /* simple return without submitting a new urb. @@ -408,7 +408,7 @@ static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int ea urb->status = result; dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result); /* and do error handling via completion function */ - auerchain_complete( urb, NULL); + auerchain_complete( urb); } } @@ -425,7 +425,7 @@ static int auerchain_submit_urb (pauerchain_t acp, struct urb * urb) /* cancel an urb which is submitted to the chain the result is 0 if the urb is cancelled, or -EINPROGRESS if - URB_ASYNC_UNLINK is set and the function is successfully started. + the function is successfully started. */ static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb) { @@ -448,7 +448,7 @@ static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb) spin_unlock_irqrestore (&acp->lock, flags); dbg ("unlink waiting urb"); urb->status = -ENOENT; - urb->complete (urb, NULL); + urb->complete (urb); return 0; } } @@ -505,7 +505,7 @@ static void auerchain_unlink_all (pauerchain_t acp) spin_unlock_irqrestore (&acp->lock, flags); dbg ("unlink waiting urb"); urbp->status = -ENOENT; - urbp->complete (urbp, NULL); + urbp->complete (urbp); spin_lock_irqsave (&acp->lock, flags); } spin_unlock_irqrestore (&acp->lock, flags); @@ -514,9 +514,8 @@ static void auerchain_unlink_all (pauerchain_t acp) acep = acp->active; if (acep) { urbp = acep->urbp; - urbp->transfer_flags &= ~URB_ASYNC_UNLINK; dbg ("unlink active urb"); - usb_unlink_urb (urbp); + usb_kill_urb (urbp); } } @@ -571,10 +570,9 @@ static int auerchain_setup (pauerchain_t acp, unsigned int numElements) /* fill the list of free elements */ for (;numElements; numElements--) { - acep = (pauerchainelement_t) kmalloc (sizeof (auerchainelement_t), GFP_KERNEL); + acep = kzalloc(sizeof(auerchainelement_t), GFP_KERNEL); if (!acep) goto ac_fail; - memset (acep, 0, sizeof (auerchainelement_t)); INIT_LIST_HEAD (&acep->list); list_add_tail (&acep->list, &acp->free_list); } @@ -593,7 +591,7 @@ ac_fail:/* free the elements */ /* completion handler for synchronous chained URBs */ -static void auerchain_blocking_completion (struct urb *urb, struct pt_regs *regs) +static void auerchain_blocking_completion (struct urb *urb) { pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context; pchs->done = 1; @@ -605,7 +603,6 @@ static void auerchain_blocking_completion (struct urb *urb, struct pt_regs *regs /* Starts chained urb and waits for completion or timeout */ static int auerchain_start_wait_urb (pauerchain_t acp, struct urb *urb, int timeout, int* actual_length) { - DECLARE_WAITQUEUE (wait, current); auerchain_chs_t chs; int status; @@ -613,26 +610,13 @@ static int auerchain_start_wait_urb (pauerchain_t acp, struct urb *urb, int time init_waitqueue_head (&chs.wqh); chs.done = 0; - set_current_state (TASK_UNINTERRUPTIBLE); - add_wait_queue (&chs.wqh, &wait); urb->context = &chs; status = auerchain_submit_urb (acp, urb); - if (status) { + if (status) /* something went wrong */ - set_current_state (TASK_RUNNING); - remove_wait_queue (&chs.wqh, &wait); return status; - } - while (timeout && !chs.done) - { - timeout = schedule_timeout (timeout); - set_current_state(TASK_UNINTERRUPTIBLE); - rmb(); - } - - set_current_state (TASK_RUNNING); - remove_wait_queue (&chs.wqh, &wait); + timeout = wait_event_timeout(chs.wqh, chs.done, timeout); if (!timeout && !chs.done) { if (urb->status != -EINPROGRESS) { /* No callback?!! */ @@ -699,7 +683,7 @@ static int auerchain_control_msg (pauerchain_t acp, struct usb_device *dev, unsi dr->wLength = cpu_to_le16 (size); usb_fill_control_urb (urb, dev, pipe, (unsigned char*)dr, data, size, /* build urb */ - auerchain_blocking_completion,0); + auerchain_blocking_completion, NULL); ret = auerchain_start_wait_urb (acp, urb, timeout, &length); usb_free_urb (urb); @@ -718,16 +702,10 @@ static int auerchain_control_msg (pauerchain_t acp, struct usb_device *dev, unsi /* free a single auerbuf */ static void auerbuf_free (pauerbuf_t bp) { - if (bp->bufp) { - kfree (bp->bufp); - } - if (bp->dr) { - kfree (bp->dr); - } - if (bp->urbp) { - usb_free_urb (bp->urbp); - } - kfree (bp); + kfree(bp->bufp); + kfree(bp->dr); + usb_free_urb(bp->urbp); + kfree(bp); } /* free the buffers from an auerbuf list */ @@ -780,16 +758,15 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned /* fill the list of free elements */ for (;numElements; numElements--) { - bep = (pauerbuf_t) kmalloc (sizeof (auerbuf_t), GFP_KERNEL); + bep = kzalloc(sizeof(auerbuf_t), GFP_KERNEL); if (!bep) goto bl_fail; - memset (bep, 0, sizeof (auerbuf_t)); bep->list = bcp; INIT_LIST_HEAD (&bep->buff_list); - bep->bufp = (char *) kmalloc (bufsize, GFP_KERNEL); + bep->bufp = kmalloc (bufsize, GFP_KERNEL); if (!bep->bufp) goto bl_fail; - bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); + bep->dr = kmalloc(sizeof (struct usb_ctrlrequest), GFP_KERNEL); if (!bep->dr) goto bl_fail; bep->urbp = usb_alloc_urb (0, GFP_KERNEL); @@ -801,7 +778,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned bl_fail:/* not enough memory. Free allocated elements */ dbg ("auerbuf_setup: no more memory"); - kfree(bep); + auerbuf_free(bep); auerbuf_free_buffers (bcp); return -ENOMEM; } @@ -827,7 +804,7 @@ static void auerbuf_releasebuf( pauerbuf_t bp) 0 Initial, OK -EINPROGRESS during submission until end -ENOENT if urb is unlinked --ETIMEDOUT Transfer timed out, NAK +-ETIME Device did not respond -ENOMEM Memory Overflow -ENODEV Specified USB-device or bus doesn't exist -ENXIO URB already queued @@ -853,7 +830,7 @@ static int auerswald_status_retry (int status) { switch (status) { case 0: - case -ETIMEDOUT: + case -ETIME: case -EOVERFLOW: case -EAGAIN: case -EPIPE: @@ -867,7 +844,7 @@ static int auerswald_status_retry (int status) } /* Completion of asynchronous write block */ -static void auerchar_ctrlwrite_complete (struct urb * urb, struct pt_regs *regs) +static void auerchar_ctrlwrite_complete (struct urb * urb) { pauerbuf_t bp = (pauerbuf_t) urb->context; pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); @@ -880,7 +857,7 @@ static void auerchar_ctrlwrite_complete (struct urb * urb, struct pt_regs *regs) } /* Completion handler for dummy retry packet */ -static void auerswald_ctrlread_wretcomplete (struct urb * urb, struct pt_regs *regs) +static void auerswald_ctrlread_wretcomplete (struct urb * urb) { pauerbuf_t bp = (pauerbuf_t) urb->context; pauerswald_t cp; @@ -914,12 +891,12 @@ static void auerswald_ctrlread_wretcomplete (struct urb * urb, struct pt_regs *r if (ret) { dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret); bp->urbp->status = ret; - auerswald_ctrlread_complete (bp->urbp, NULL); + auerswald_ctrlread_complete (bp->urbp); } } /* completion handler for receiving of control messages */ -static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs) +static void auerswald_ctrlread_complete (struct urb * urb) { unsigned int serviceid; pauerswald_t cp; @@ -962,7 +939,7 @@ static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs) if (ret) { dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret); bp->urbp->status = ret; - auerswald_ctrlread_wretcomplete (bp->urbp, regs); + auerswald_ctrlread_wretcomplete (bp->urbp); } return; } @@ -991,7 +968,7 @@ static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs) messages from the USB device. */ /* int completion handler. */ -static void auerswald_int_complete (struct urb * urb, struct pt_regs *regs) +static void auerswald_int_complete (struct urb * urb) { unsigned long flags; unsigned int channelid; @@ -1037,7 +1014,8 @@ static void auerswald_int_complete (struct urb * urb, struct pt_regs *regs) /* now extract the information */ channelid = cp->intbufp[2]; - bytecount = le16_to_cpup (&cp->intbufp[3]); + bytecount = (unsigned char)cp->intbufp[3]; + bytecount |= (unsigned char)cp->intbufp[4] << 8; /* check the channel id */ if (channelid >= AUH_TYPESIZE) { @@ -1090,7 +1068,7 @@ static void auerswald_int_complete (struct urb * urb, struct pt_regs *regs) if (ret) { dbg ("auerswald_int_complete: nonzero result of auerchain_submit_urb %d", ret); bp->urbp->status = ret; - auerswald_ctrlread_complete( bp->urbp, NULL); + auerswald_ctrlread_complete( bp->urbp); /* here applies the same problem as above: device locking! */ } exit: @@ -1105,14 +1083,12 @@ exit: */ static void auerswald_int_free (pauerswald_t cp) { - if (cp->inturbp) { - usb_free_urb (cp->inturbp); - cp->inturbp = NULL; - } - if (cp->intbufp) { - kfree (cp->intbufp); - cp->intbufp = NULL; - } + if (cp->inturbp) { + usb_free_urb(cp->inturbp); + cp->inturbp = NULL; + } + kfree(cp->intbufp); + cp->intbufp = NULL; } /* This function is called to activate the interrupt @@ -1122,16 +1098,16 @@ static void auerswald_int_free (pauerswald_t cp) static int auerswald_int_open (pauerswald_t cp) { int ret; - struct usb_endpoint_descriptor *ep; + struct usb_host_endpoint *ep; int irqsize; dbg ("auerswald_int_open"); - ep = usb_epnum_to_ep_desc (cp->usbdev, USB_DIR_IN | AU_IRQENDP); + ep = cp->usbdev->ep_in[AU_IRQENDP]; if (!ep) { ret = -EFAULT; goto intoend; } - irqsize = ep->wMaxPacketSize; + irqsize = le16_to_cpu(ep->desc.wMaxPacketSize); cp->irqsize = irqsize; /* allocate the urb and data buffer */ @@ -1143,14 +1119,16 @@ static int auerswald_int_open (pauerswald_t cp) } } if (!cp->intbufp) { - cp->intbufp = (char *) kmalloc (irqsize, GFP_KERNEL); + cp->intbufp = kmalloc (irqsize, GFP_KERNEL); if (!cp->intbufp) { ret = -ENOMEM; goto intoend; } } /* setup urb */ - usb_fill_int_urb (cp->inturbp, cp->usbdev, usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval); + usb_fill_int_urb (cp->inturbp, cp->usbdev, + usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, + irqsize, auerswald_int_complete, cp, ep->desc.bInterval); /* start the urb */ cp->inturbp->status = 0; /* needed! */ ret = usb_submit_urb (cp->inturbp, GFP_KERNEL); @@ -1170,22 +1148,15 @@ intoend: endpoint. This function returns 0 if successful or an error code. NOTE: no mutex please! */ -static int auerswald_int_release (pauerswald_t cp) +static void auerswald_int_release (pauerswald_t cp) { - int ret = 0; dbg ("auerswald_int_release"); /* stop the int endpoint */ - if (cp->inturbp) { - ret = usb_unlink_urb (cp->inturbp); - if (ret) - dbg ("nonzero int unlink result received: %d", ret); - } + usb_kill_urb (cp->inturbp); /* deallocate memory */ auerswald_int_free (cp); - - return ret; } /* --------------------------------------------------------------------- */ @@ -1405,7 +1376,7 @@ static int auerchar_open (struct inode *inode, struct file *file) } /* we have access to the device. Now lets allocate memory */ - ccp = (pauerchar_t) kmalloc(sizeof(auerchar_t), GFP_KERNEL); + ccp = kzalloc(sizeof(auerchar_t), GFP_KERNEL); if (ccp == NULL) { err ("out of memory"); ret = -ENOMEM; @@ -1413,7 +1384,6 @@ static int auerchar_open (struct inode *inode, struct file *file) } /* Initialize device descriptor */ - memset( ccp, 0, sizeof(auerchar_t)); init_MUTEX( &ccp->mutex); init_MUTEX( &ccp->readmutex); auerbuf_init (&ccp->bufctl); @@ -1435,7 +1405,7 @@ static int auerchar_open (struct inode *inode, struct file *file) /* file IO stuff */ file->f_pos = 0; file->private_data = ccp; - return 0; + return nonseekable_open(inode, file); /* Error exit */ ofail: up (&cp->mutex); @@ -1452,6 +1422,8 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int audevinfo_t devinfo; pauerswald_t cp = NULL; unsigned int u; + unsigned int __user *user_arg = (unsigned int __user *)arg; + dbg ("ioctl"); /* get the mutexes */ @@ -1483,14 +1455,14 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int u = ccp->auerdev && (ccp->scontext.id != AUH_UNASSIGNED) && !list_empty (&cp->bufctl.free_buff_list); - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; /* return != 0 if connected to a service channel */ case IOCTL_AU_CONNECT: dbg ("IOCTL_AU_CONNECT"); u = (ccp->scontext.id != AUH_UNASSIGNED); - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; /* return != 0 if Receive Data available */ @@ -1511,14 +1483,14 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int u = 1; } } - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; /* return the max. buffer length for the device */ case IOCTL_AU_BUFLEN: dbg ("IOCTL_AU_BUFLEN"); u = cp->maxControlLength; - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; /* requesting a service channel */ @@ -1527,7 +1499,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int /* requesting a service means: release the previous one first */ auerswald_removeservice (cp, &ccp->scontext); /* get the channel number */ - ret = get_user (u, (unsigned int *) arg); + ret = get_user (u, user_arg); if (ret) { break; } @@ -1564,7 +1536,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int case IOCTL_AU_SLEN: dbg ("IOCTL_AU_SLEN"); u = AUSI_DLEN; - ret = put_user (u, (unsigned int *) arg); + ret = put_user (u, user_arg); break; default: @@ -1718,7 +1690,7 @@ static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t int ret; wait_queue_t wait; - dbg ("auerchar_write %d bytes", len); + dbg ("auerchar_write %zd bytes", len); /* Error checking */ if (!ccp) @@ -1882,7 +1854,7 @@ static int auerchar_release (struct inode *inode, struct file *file) /*----------------------------------------------------------------------*/ /* File operation structure */ -static struct file_operations auerswald_fops = +static const struct file_operations auerswald_fops = { .owner = THIS_MODULE, .llseek = no_llseek, @@ -1894,9 +1866,8 @@ static struct file_operations auerswald_fops = }; static struct usb_class_driver auerswald_class = { - .name = "usb/auer%d", + .name = "auer%d", .fops = &auerswald_fops, - .mode = S_IFCHR | S_IRUGO | S_IWUGO, .minor_base = AUER_MINOR_BASE, }; @@ -1928,29 +1899,25 @@ static int auerswald_probe (struct usb_interface *intf, struct usb_device *usbdev = interface_to_usbdev(intf); pauerswald_t cp = NULL; unsigned int u = 0; - char *pbuf; + __le16 *pbuf; int ret; dbg ("probe: vendor id 0x%x, device id 0x%x", - usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); - - /* See if the device offered us matches that we can accept */ - if (usbdev->descriptor.idVendor != ID_AUERSWALD) - return -ENODEV; + le16_to_cpu(usbdev->descriptor.idVendor), + le16_to_cpu(usbdev->descriptor.idProduct)); /* we use only the first -and only- interface */ if (intf->altsetting->desc.bInterfaceNumber != 0) return -ENODEV; /* allocate memory for our device and initialize it */ - cp = kmalloc (sizeof(auerswald_t), GFP_KERNEL); + cp = kzalloc (sizeof(auerswald_t), GFP_KERNEL); if (cp == NULL) { err ("out of memory"); goto pfail; } /* Initialize device descriptor */ - memset (cp, 0, sizeof(auerswald_t)); init_MUTEX (&cp->mutex); cp->usbdev = usbdev; auerchain_init (&cp->controlchain); @@ -1970,12 +1937,11 @@ static int auerswald_probe (struct usb_interface *intf, cp->dtindex = intf->minor; /* Get the usb version of the device */ - cp->version = cp->usbdev->descriptor.bcdDevice; + cp->version = le16_to_cpu(cp->usbdev->descriptor.bcdDevice); dbg ("Version is %X", cp->version); /* allow some time to settle the device */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/3); + msleep(334); /* Try to get a suitable textual description of the device */ /* Device name:*/ @@ -2001,7 +1967,7 @@ static int auerswald_probe (struct usb_interface *intf, info("device is a %s", cp->dev_desc); /* get the maximum allowed control transfer length */ - pbuf = (char *) kmalloc (2, GFP_KERNEL); /* use an allocated buffer because of urb target */ + pbuf = kmalloc(2, GFP_KERNEL); /* use an allocated buffer because of urb target */ if (!pbuf) { err( "out of memory"); goto pfail; @@ -2014,7 +1980,7 @@ static int auerswald_probe (struct usb_interface *intf, AUDI_MBCTRANS, /* USB message index value */ pbuf, /* pointer to the receive buffer */ 2, /* length of the buffer */ - HZ * 2); /* time to wait for the message to complete before timing out */ + 2000); /* time to wait for the message to complete before timing out */ if (ret == 2) { cp->maxControlLength = le16_to_cpup(pbuf); kfree(pbuf); @@ -2120,6 +2086,8 @@ static void auerswald_disconnect (struct usb_interface *intf) static struct usb_device_id auerswald_ids [] = { { USB_DEVICE (ID_AUERSWALD, 0x00C0) }, /* COMpact 2104 USB */ { USB_DEVICE (ID_AUERSWALD, 0x00DB) }, /* COMpact 4410/2206 USB */ + { USB_DEVICE (ID_AUERSWALD, 0x00DC) }, /* COMpact 4406 DSL */ + { USB_DEVICE (ID_AUERSWALD, 0x00DD) }, /* COMpact 2204 USB */ { USB_DEVICE (ID_AUERSWALD, 0x00F1) }, /* Comfort 2000 System Telephone */ { USB_DEVICE (ID_AUERSWALD, 0x00F2) }, /* Comfort 1200 System Telephone */ { } /* Terminating entry */ @@ -2130,7 +2098,6 @@ MODULE_DEVICE_TABLE (usb, auerswald_ids); /* Standard usb driver struct */ static struct usb_driver auerswald_driver = { - .owner = THIS_MODULE, .name = "auerswald", .probe = auerswald_probe, .disconnect = auerswald_disconnect,