static ssize_t lcd_write(struct file *file, const char __user * user_buffer, size_t count, loff_t *ppos) { struct usb_lcd *dev; int retval = 0; struct urb *urb = NULL; char *buf = NULL; dev = (struct usb_lcd *)file->private_data; /* verify that we actually have some data to write */ if (count == 0) goto exit; /* create a urb, and a buffer for it, and copy the data to the urb */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma); if (!buf) { retval = -ENOMEM; goto error; } if (copy_from_user(buf, user_buffer, count)) { retval = -EFAULT; goto error; } /* initialize the urb properly */ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), buf, count, lcd_write_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* send the data out the bulk port */ retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) { err("USBLCD: %s - failed submitting write urb, error %d", __FUNCTION__, retval); goto error; } /* release our reference to this urb, the USB core will eventually free it entirely */ usb_free_urb(urb); exit: return count; error: usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); usb_free_urb(urb); return retval; }
int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 alloc_sz) { #ifdef CONFIG_USB_HCI int i; struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv; struct usb_device *pusbd = pdvobjpriv->pusbdev; #ifdef CONFIG_USE_USB_BUFFER_ALLOC #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) pxmitbuf->pallocated_buf = usb_alloc_coherent(pusbd, (size_t)alloc_sz, GFP_ATOMIC, &pxmitbuf->dma_transfer_addr); #else pxmitbuf->pallocated_buf = usb_buffer_alloc(pusbd, (size_t)alloc_sz, GFP_ATOMIC, &pxmitbuf->dma_transfer_addr); #endif pxmitbuf->pbuf = pxmitbuf->pallocated_buf; if(pxmitbuf->pallocated_buf == NULL) return _FAIL; #else pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz); if (pxmitbuf->pallocated_buf == NULL) { return _FAIL; } pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); pxmitbuf->dma_transfer_addr = 0; #endif for(i=0; i<8; i++) { pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL); if(pxmitbuf->pxmit_urb[i] == NULL) { DBG_8192C("pxmitbuf->pxmit_urb[i]==NULL"); return _FAIL; } } #endif #ifdef CONFIG_PCI_HCI pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz); if (pxmitbuf->pallocated_buf == NULL) { return _FAIL; } pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); #endif return _SUCCESS; }
//alloc os related resource in struct recv_buf int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf) { int res=_SUCCESS; #ifdef CONFIG_USB_HCI struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv; struct usb_device *pusbd = pdvobjpriv->pusbdev; precvbuf->irp_pending = _FALSE; precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL); if(precvbuf->purb == NULL){ res = _FAIL; } precvbuf->pskb = NULL; precvbuf->reuse = _FALSE; precvbuf->pallocated_buf = precvbuf->pbuf = NULL; precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pend = NULL; precvbuf->transfer_len = 0; precvbuf->len = 0; #ifdef CONFIG_USE_USB_BUFFER_ALLOC #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) precvbuf->pallocated_buf = usb_alloc_coherent(pusbd, (size_t)precvbuf->alloc_sz, GFP_ATOMIC, &precvbuf->dma_transfer_addr); #else precvbuf->pallocated_buf = usb_buffer_alloc(pusbd, (size_t)precvbuf->alloc_sz, GFP_ATOMIC, &precvbuf->dma_transfer_addr); #endif precvbuf->pbuf = precvbuf->pallocated_buf; if(precvbuf->pallocated_buf == NULL) return _FAIL; #endif #endif #ifdef CONFIG_SDIO_HCI precvbuf->pskb = NULL; precvbuf->pallocated_buf = precvbuf->pbuf = NULL; precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pend = NULL; precvbuf->len = 0; #endif return res; }
static __inline int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len) { struct urb *urb = pTcb->urb; int retval = 0; urb->transfer_buffer = usb_buffer_alloc(psIntfAdapter->udev, len, GFP_ATOMIC, &urb->transfer_dma); if (!urb->transfer_buffer) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n"); return -ENOMEM; } memcpy(urb->transfer_buffer, data, len); urb->transfer_buffer_length = len; BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n"); //For T3B,INT OUT end point will be used as bulk out end point if((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE)) { usb_fill_int_urb(urb, psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe, urb->transfer_buffer, len, write_bulk_callback, pTcb, psIntfAdapter->sBulkOut.int_out_interval); } else { usb_fill_bulk_urb(urb, psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe, urb->transfer_buffer, len, write_bulk_callback, pTcb); } urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */ if(FALSE == psIntfAdapter->psAdapter->device_removed && FALSE == psIntfAdapter->psAdapter->bEndPointHalted && FALSE == psIntfAdapter->bSuspended && FALSE == psIntfAdapter->bPreparingForBusSuspend) { retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval); if(retval == -EPIPE) { psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } } } return retval; }
inline void *_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma) { #ifdef PLATFORM_LINUX #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) return usb_alloc_coherent(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma); #else return usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma); #endif #endif /* PLATFORM_LINUX */ #ifdef PLATFORM_FREEBSD return (malloc(size, M_USBDEV, M_NOWAIT | M_ZERO)); #endif /* PLATFORM_FREEBSD */ }
/* ======================================================================== Routine Description: Allocate dma-consistent buffer. Arguments: dev - the USB device size - buffer size dma - used to return DMA address of buffer Return Value: a buffer that may be used to perform DMA to the specified device Note: ======================================================================== */ void *rausb_buffer_alloc(VOID *dev, size_t size, ra_dma_addr_t *dma) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) return usb_alloc_coherent(dev, size, GFP_ATOMIC, dma); #else return usb_buffer_alloc(dev, size, GFP_ATOMIC, dma); #endif #else return kmalloc(size, GFP_ATOMIC); #endif }
static int usbmouse_as_key_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; int pipe; interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; /* a. 分配一个input_dev */ uk_dev = input_allocate_device(); /* b. 设置 */ /* b.1 能产生哪类事件 */ set_bit(EV_KEY, uk_dev->evbit); set_bit(EV_REP, uk_dev->evbit); /* b.2 能产生哪些事件 */ set_bit(KEY_L, uk_dev->keybit); set_bit(KEY_S, uk_dev->keybit); set_bit(KEY_ENTER, uk_dev->keybit); /* c. 注册 */ input_register_device(uk_dev); /* d. 硬件相关操作 */ /* 数据传输3要素: 源,目的,长度 */ /* 源: USB设备的某个端点 */ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); /* 长度: */ len = endpoint->wMaxPacketSize; /* 目的: */ usb_buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &usb_buf_phys); /* 使用"3要素" */ /* 分配usb request block */ uk_urb = usb_alloc_urb(0, GFP_KERNEL); /* 使用"3要素设置urb" */ usb_fill_int_urb(uk_urb, dev, pipe, usb_buf, len, usbmouse_as_key_irq, NULL, endpoint->bInterval); uk_urb->transfer_dma = usb_buf_phys; uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* 使用URB */ usb_submit_urb(uk_urb, GFP_KERNEL); return 0; }
static int __init rtw_mem_init(void) { int i; u32 max_recvbuf_sz = 0; SIZE_PTR tmpaddr=0; SIZE_PTR alignment=0; struct sk_buff *pskb=NULL; printk("%s\n", __func__); #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX for(i=0; i<NR_RECVBUFF; i++) { rtk_buf_mem[i] = usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma); } #endif //CONFIG_USE_USB_BUFFER_ALLOC_RX skb_queue_head_init(&rtk_skb_mem_q); rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); if (max_recvbuf_sz == 0) max_recvbuf_sz = MAX_RECVBUF_SZ; DBG_871X("%s: max_recvbuf_sz: %d\n", __func__, max_recvbuf_sz); for(i=0; i<NR_PREALLOC_RECV_SKB; i++) { pskb = __dev_alloc_skb(max_recvbuf_sz + RECVBUFF_ALIGN_SZ, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if(pskb) { tmpaddr = (SIZE_PTR)pskb->data; alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); skb_queue_tail(&rtk_skb_mem_q, pskb); } else { printk("%s, alloc skb memory fail!\n", __func__); } pskb=NULL; } printk("%s, rtk_skb_mem_q len : %d\n", __func__, skb_queue_len(&rtk_skb_mem_q)); return 0; }
lmpcm_t *lmpcm_new ( struct usb_device *dev ) { lmpcm_t *lmpcm; // Create object if (!(lmpcm = kmalloc(sizeof(lmpcm_t), GFP_KERNEL))) return NULL; // Initialize lmpcm_init(lmpcm); // Input device if ( (lmpcm->inputdev = input_allocate_device()) == NULL ) { lmpcm_free(lmpcm); return NULL; } // Create urb handler if (!(lmpcm->urb = usb_alloc_urb(0, GFP_KERNEL))) { lmpcm_free(lmpcm); return NULL; } // Create data required for urb transfer if (!(lmpcm->data = usb_buffer_alloc(dev,8,ATOMIC,&lmpcm->data_dma))) { lmpcm_free(lmpcm); return NULL; } // Set lmpcm usb device lmpcm->usbdev = dev; return lmpcm; }
static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev) { int i, ret = 0; ENTER(); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev, MAX_STREAM_URB * AS102_USB_BUF_SIZE, GFP_KERNEL, &dev->dma_addr); #else dev->stream = usb_buffer_alloc(dev->bus_adap.usb_dev, MAX_STREAM_URB * AS102_USB_BUF_SIZE, GFP_KERNEL, &dev->dma_addr); #endif if (!dev->stream) { dprintk(debug, "%s: usb_buffer_alloc failed\n", __func__); return -ENOMEM; } memset(dev->stream, 0, MAX_STREAM_URB * AS102_USB_BUF_SIZE); /* init urb buffers */ for (i = 0; i < MAX_STREAM_URB; i++) { struct urb *urb; urb = usb_alloc_urb(0, GFP_ATOMIC); if (urb == NULL) { dprintk(debug, "%s: usb_alloc_urb failed\n", __func__); as102_free_usb_stream_buffer(dev); return -ENOMEM; } urb->transfer_buffer = dev->stream + (i * AS102_USB_BUF_SIZE); urb->transfer_buffer_length = AS102_USB_BUF_SIZE; dev->stream_urb[i] = urb; } LEAVE(); return ret; }
static int qcnmea_write_buf_alloc(struct qcnmea *nmea) { int i; struct qcnmea_wb *wb; for(wb = &nmea->write_buf[0], i = 0; i < QCNMEA_NW; i++, wb++) { wb->buf = usb_buffer_alloc(nmea->usb_dev, nmea->write_size, GFP_KERNEL, &wb->dma); if(!wb->buf) { while(i != 0) { --i; --wb; usb_buffer_free(nmea->usb_dev, nmea->write_size, wb->buf, wb->dma); } return -ENOMEM; } } return 0;
/* ======================================================================== Routine Description: Allocate dma-consistent buffer. Arguments: dev - the USB device size - buffer size dma - used to return DMA address of buffer Return Value: a buffer that may be used to perform DMA to the specified device Note: ======================================================================== */ void *rausb_buffer_alloc(VOID *dev, size_t size, ra_dma_addr_t *dma) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) dma_addr_t DmaAddr = (dma_addr_t)(*dma); void *buf; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) buf = usb_alloc_coherent(dev, size, GFP_ATOMIC, &DmaAddr); #else buf = usb_buffer_alloc(dev, size, GFP_ATOMIC, &DmaAddr); #endif *dma = (ra_dma_addr_t)DmaAddr; return buf; #else return kmalloc(size, GFP_ATOMIC); #endif }
/* Little helper: write buffers allocate */ static int acm_write_buffers_alloc(struct acm *acm) { int i; struct acm_wb *wb; for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) { wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL, &wb->dmah); if (!wb->buf) { while (i != 0) { --i; --wb; usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah); } return -ENOMEM; } } return 0; }
void diodev_rx_setup(struct usb_dio_dev *dev) { struct urb *urb; char *urbBuf; int retval; FUNC_HI(); DPRINTK(KERN_ALERT "=== diodev_rx_setup() hello\n"); urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { printk(KERN_ALERT "=== diodev_rx_setup() -ENOMEM\n"); FUNC_ERR(); return; } DPRINTK(KERN_ALERT "=== Building Rx Buffer...\n"); urbBuf = usb_buffer_alloc(dev->dev, dev->bulk_in_size, GFP_KERNEL, &urb->transfer_dma); if (!urbBuf) { usb_free_urb(urb); printk(KERN_ALERT "=== diodev_rx_setup() -ENOMEM\n"); FUNC_ERR(); return; } usb_fill_bulk_urb(urb, dev->dev, dev->bulk_in_endpointPipe, urbBuf, dev->bulk_in_size, (usb_complete_t)diodev_rx_cb, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) { printk(KERN_ALERT "=== diodev_rx_setup() URB submit error %d\n", retval); usb_buffer_free(dev->dev, dev->bulk_in_size, urbBuf, urb->transfer_dma); usb_free_urb(urb); FUNC_ERR(); return; } dev->bulk_in_urb = urb; DPRINTK(KERN_ALERT "=== diodev_rx_setup() returning\n"); FUNC_BYE(); }
static int modem_write_buffers_alloc( struct modem_port *modem_ptr, struct usb_serial *serial) { int i; struct ap_wb *wb; for (wb = &modem_ptr->wb[0], i = 0; i < AP_NW; i++, wb++) { wb->buf = usb_buffer_alloc(serial->dev, modem_ptr->writesize, GFP_KERNEL, &wb->dmah); if (!wb->buf) { while (i != 0) { --i; --wb; usb_buffer_free(serial->dev, modem_ptr->writesize, wb->buf, wb->dmah); } return -ENOMEM; } } return 0; }
static struct urb *alloc_urb(struct zd_usb *usb) { struct usb_device *udev = zd_usb_to_usbdev(usb); struct urb *urb; void *buffer; urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return NULL; buffer = usb_buffer_alloc(udev, USB_MAX_RX_SIZE, GFP_KERNEL, &urb->transfer_dma); if (!buffer) { usb_free_urb(urb); return NULL; } usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, EP_DATA_IN), buffer, USB_MAX_RX_SIZE, rx_urb_complete, usb); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; return urb; }
/* Puts the frame on the USB endpoint. It doesn't wait for * completion. The frame must contain the control set. */ int zd_usb_tx(struct zd_usb *usb, const u8 *frame, unsigned int length) { int r; struct usb_device *udev = zd_usb_to_usbdev(usb); struct urb *urb; void *buffer; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { r = -ENOMEM; goto out; } buffer = usb_buffer_alloc(zd_usb_to_usbdev(usb), length, GFP_ATOMIC, &urb->transfer_dma); if (!buffer) { r = -ENOMEM; goto error_free_urb; } memcpy(buffer, frame, length); usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), buffer, length, tx_urb_complete, NULL); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; r = usb_submit_urb(urb, GFP_ATOMIC); if (r) goto error; return 0; error: usb_buffer_free(zd_usb_to_usbdev(usb), length, buffer, urb->transfer_dma); error_free_urb: usb_free_urb(urb); out: return r; }
static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) { struct usb_skel *dev; int retval = 0; struct urb *urb = NULL; char *buf = NULL; size_t writesize = min(count, (size_t)MAX_TRANSFER); dev = (struct usb_skel *)file->private_data; /* verify that we actually have some data to write */ if (count == 0) goto exit; /* limit the number of URBs in flight to stop a user from using up all RAM */ if (down_interruptible(&dev->limit_sem)) { retval = -ERESTARTSYS; goto exit; } spin_lock_irq(&dev->err_lock); if ((retval = dev->errors) < 0) { /* any error is reported once */ dev->errors = 0; /* to preserve notifications about reset */ retval = (retval == -EPIPE) ? retval : -EIO; } spin_unlock_irq(&dev->err_lock); if (retval < 0) goto error; /* create a urb, and a buffer for it, and copy the data to the urb */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { retval = -ENOMEM; goto error; } buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma); if (!buf) { retval = -ENOMEM; goto error; } if (copy_from_user(buf, user_buffer, writesize)) { retval = -EFAULT; goto error; } /* this lock makes sure we don't submit URBs to gone devices */ mutex_lock(&dev->io_mutex); if (!dev->interface) { /* disconnect() was called */ mutex_unlock(&dev->io_mutex); retval = -ENODEV; goto error; } /* initialize the urb properly */ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), buf, writesize, skel_write_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &dev->submitted); /* send the data out the bulk port */ retval = usb_submit_urb(urb, GFP_KERNEL); mutex_unlock(&dev->io_mutex); if (retval) { err("%s - failed submitting write urb, error %d", __func__, retval); goto error_unanchor; } /* release our reference to this urb, the USB core will eventually free it entirely */ usb_free_urb(urb); return writesize; error_unanchor: usb_unanchor_urb(urb); error: if (urb) { usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma); usb_free_urb(urb); } up(&dev->limit_sem); exit: return retval; }
int onetouch_connect_input(struct us_data *ss) { struct usb_device *udev = ss->pusb_dev; struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_onetouch *onetouch; struct input_dev *input_dev; int pipe, maxp; int error = -ENOMEM; interface = ss->pusb_intf->cur_altsetting; if (interface->desc.bNumEndpoints != 3) return -ENODEV; endpoint = &interface->endpoint[2].desc; if (!usb_endpoint_is_int_in(endpoint)) return -ENODEV; pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); onetouch = kzalloc(sizeof(struct usb_onetouch), GFP_KERNEL); input_dev = input_allocate_device(); if (!onetouch || !input_dev) goto fail1; onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN, GFP_ATOMIC, &onetouch->data_dma); if (!onetouch->data) goto fail1; onetouch->irq = usb_alloc_urb(0, GFP_KERNEL); if (!onetouch->irq) goto fail2; onetouch->udev = udev; onetouch->dev = input_dev; if (udev->manufacturer) strlcpy(onetouch->name, udev->manufacturer, sizeof(onetouch->name)); if (udev->product) { if (udev->manufacturer) strlcat(onetouch->name, " ", sizeof(onetouch->name)); strlcat(onetouch->name, udev->product, sizeof(onetouch->name)); } if (!strlen(onetouch->name)) snprintf(onetouch->name, sizeof(onetouch->name), "Maxtor Onetouch %04x:%04x", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); usb_make_path(udev, onetouch->phys, sizeof(onetouch->phys)); strlcat(onetouch->phys, "/input0", sizeof(onetouch->phys)); input_dev->name = onetouch->name; input_dev->phys = onetouch->phys; usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &udev->dev; set_bit(EV_KEY, input_dev->evbit); set_bit(ONETOUCH_BUTTON, input_dev->keybit); clear_bit(0, input_dev->keybit); input_set_drvdata(input_dev, onetouch); input_dev->open = usb_onetouch_open; input_dev->close = usb_onetouch_close; usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data, (maxp > 8 ? 8 : maxp), usb_onetouch_irq, onetouch, endpoint->bInterval); onetouch->irq->transfer_dma = onetouch->data_dma; onetouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ss->extra_destructor = onetouch_release_input; ss->extra = onetouch; #ifdef CONFIG_PM ss->suspend_resume_hook = usb_onetouch_pm_hook; #endif error = input_register_device(onetouch->dev); if (error) goto fail3; return 0; fail3: usb_free_urb(onetouch->irq); fail2: usb_buffer_free(udev, ONETOUCH_PKT_LEN, onetouch->data, onetouch->data_dma); fail1: kfree(onetouch); input_free_device(input_dev); return error; }
static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) { int rv = -EINVAL; struct usb_device *udev = interface_to_usbdev(intf); struct wdm_device *desc; struct usb_host_interface *iface; struct usb_endpoint_descriptor *ep; struct usb_cdc_dmm_desc *dmhd; u8 *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; u16 maxcom = 0; if (!buffer) goto out; while (buflen > 2) { if (buffer [1] != USB_DT_CS_INTERFACE) { dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; } switch (buffer [2]) { case USB_CDC_HEADER_TYPE: break; case USB_CDC_DMM_TYPE: dmhd = (struct usb_cdc_dmm_desc *)buffer; maxcom = le16_to_cpu(dmhd->wMaxCommand); dev_dbg(&intf->dev, "Finding maximum buffer length: %d", maxcom); break; default: dev_err(&intf->dev, "Ignoring extra header, type %d, length %d\n", buffer[2], buffer[0]); break; } next_desc: buflen -= buffer[0]; buffer += buffer[0]; } rv = -ENOMEM; desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); if (!desc) goto out; mutex_init(&desc->wlock); mutex_init(&desc->rlock); mutex_init(&desc->plock); spin_lock_init(&desc->iuspin); init_waitqueue_head(&desc->wait); desc->wMaxCommand = maxcom; /* this will be expanded and needed in hardware endianness */ desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber); desc->intf = intf; INIT_WORK(&desc->rxwork, wdm_rxwork); rv = -EINVAL; iface = intf->cur_altsetting; if (iface->desc.bNumEndpoints != 1) goto err; ep = &iface->endpoint[0].desc; if (!ep || !usb_endpoint_is_int_in(ep)) goto err; desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!desc->orq) goto err; desc->irq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!desc->irq) goto err; desc->validity = usb_alloc_urb(0, GFP_KERNEL); if (!desc->validity) goto err; desc->response = usb_alloc_urb(0, GFP_KERNEL); if (!desc->response) goto err; desc->command = usb_alloc_urb(0, GFP_KERNEL); if (!desc->command) goto err; desc->ubuf = kmalloc(desc->wMaxCommand, GFP_KERNEL); if (!desc->ubuf) goto err; desc->sbuf = usb_buffer_alloc(interface_to_usbdev(intf), desc->wMaxPacketSize, GFP_KERNEL, &desc->validity->transfer_dma); if (!desc->sbuf) goto err; desc->inbuf = usb_buffer_alloc(interface_to_usbdev(intf), desc->bMaxPacketSize0, GFP_KERNEL, &desc->response->transfer_dma); if (!desc->inbuf) goto err2; usb_fill_int_urb( desc->validity, interface_to_usbdev(intf), usb_rcvintpipe(interface_to_usbdev(intf), ep->bEndpointAddress), desc->sbuf, desc->wMaxPacketSize, wdm_int_callback, desc, ep->bInterval ); desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_set_intfdata(intf, desc); rv = usb_register_dev(intf, &wdm_class); if (rv < 0) goto err3; else dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", intf->minor - WDM_MINOR_BASE); out: return rv; err3: usb_set_intfdata(intf, NULL); usb_buffer_free(interface_to_usbdev(desc->intf), desc->bMaxPacketSize0, desc->inbuf, desc->response->transfer_dma); err2: usb_buffer_free(interface_to_usbdev(desc->intf), desc->wMaxPacketSize, desc->sbuf, desc->validity->transfer_dma); err: free_urbs(desc); kfree(desc->ubuf); kfree(desc->orq); kfree(desc->irq); kfree(desc); return rv; }
/* * probe function for new CPC-USB devices */ static int cpcusb_probe(struct usb_interface *interface, const struct usb_device_id *id) { CPC_USB_T *card = NULL; CPC_CHAN_T *chan = NULL; struct usb_device *udev = interface_to_usbdev(interface); struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int i, j, retval = -ENOMEM, slot; slot = cpcusb_get_free_slot(); if (slot < 0) { info("No more devices supported"); return -ENOMEM; } /* allocate memory for our device state and initialize it */ card = kzalloc(sizeof(CPC_USB_T), GFP_KERNEL); if (!card) { err("Out of memory"); return -ENOMEM; } CPCUSB_Table[slot] = card; /* allocate and initialize the channel struct */ card->chan = kmalloc(sizeof(CPC_CHAN_T), GFP_KERNEL); if (!card->chan) { kfree(card); err("Out of memory"); return -ENOMEM; } chan = card->chan; memset(chan, 0, sizeof(CPC_CHAN_T)); ResetBuffer(chan); semaphore_init(&card->sem); spin_lock_init(&card->slock); card->udev = udev; card->interface = interface; if (udev->descriptor.iSerialNumber) { usb_string(udev, udev->descriptor.iSerialNumber, card->serialNumber, 128); info("Serial %s", card->serialNumber); } card->productId = udev->descriptor.idProduct; info("Product %s", card->productId == USB_CPCUSB_LPC2119_PRODUCT_ID ? "CPC-USB/ARM7" : "CPC-USB/M16C"); /* set up the endpoint information */ /* check out the endpoints */ /* use only the first bulk-in and bulk-out endpoints */ iface_desc = &interface->altsetting[0]; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (!card->num_intr_in && (endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { card->intr_in_urb = usb_alloc_urb(0, GFP_KERNEL); card->num_intr_in = 1; if (!card->intr_in_urb) { err("No free urbs available"); goto error; } dbg("intr_in urb %d", card->num_intr_in); } if (!card->num_bulk_in && (endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { card->num_bulk_in = 2; for (j = 0; j < CPC_USB_URB_CNT; j++) { card->urbs[j].size = endpoint->wMaxPacketSize; card->urbs[j].urb = usb_alloc_urb(0, GFP_KERNEL); if (!card->urbs[j].urb) { err("No free urbs available"); goto error; } card->urbs[j].buffer = usb_buffer_alloc(udev, card->urbs[j].size, GFP_KERNEL, &card->urbs[j].urb->transfer_dma); if (!card->urbs[j].buffer) { err("Couldn't allocate bulk_in_buffer"); goto error; } } info("%s - %d reading URB's allocated", __func__, CPC_USB_URB_CNT); } if (!card->num_bulk_out && !(endpoint->bEndpointAddress & USB_DIR_IN) && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { card->num_bulk_out = 2; for (j = 0; j < CPC_USB_URB_CNT; j++) { card->wrUrbs[j].size = endpoint->wMaxPacketSize; card->wrUrbs[j].urb = usb_alloc_urb(0, GFP_KERNEL); if (!card->wrUrbs[j].urb) { err("No free urbs available"); goto error; } card->wrUrbs[j].buffer = usb_buffer_alloc(udev, card->wrUrbs[j].size, GFP_KERNEL, &card->wrUrbs[j].urb->transfer_dma); if (!card->wrUrbs[j].buffer) { err("Couldn't allocate bulk_out_buffer"); goto error; } usb_fill_bulk_urb(card->wrUrbs[j].urb, udev, usb_sndbulkpipe(udev, endpoint->bEndpointAddress), card->wrUrbs[j].buffer, card->wrUrbs[j].size, cpcusb_write_bulk_callback, card); } info("%s - %d writing URB's allocated", __func__, CPC_USB_URB_CNT); } } if (!(card->num_bulk_in && card->num_bulk_out)) { err("Couldn't find both bulk-in and bulk-out endpoints"); goto error; } /* allow device read, write and ioctl */ card->present = 1; /* we can register the device now, as it is ready */ usb_set_intfdata(interface, card); retval = usb_register_dev(interface, &cpcusb_class); if (retval) { /* something prevented us from registering this driver */ err("Not able to get a minor for this device."); usb_set_intfdata(interface, NULL); goto error; } card->chan->minor = card->minor = interface->minor; chan->buf = vmalloc(sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT); if (chan->buf == NULL) { err("Out of memory"); retval = -ENOMEM; goto error; } info("Allocated memory for %d messages (%lu kbytes)", CPC_MSG_BUF_CNT, (long unsigned int)(sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT) / 1000); memset(chan->buf, 0, sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT); ResetBuffer(chan); card->chan->CPCWait_q = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL); if (!card->chan->CPCWait_q) { err("Out of memory"); retval = -ENOMEM; goto error; } init_waitqueue_head(card->chan->CPCWait_q); CPCUSB_Table[slot] = card; card->idx = slot; CPCUsbCnt++; /* let the user know what node this device is now attached to */ info("Device now attached to USB-%d", card->minor); return 0; error: for (j = 0; j < CPC_USB_URB_CNT; j++) { if (card->urbs[j].buffer) { usb_buffer_free(card->udev, card->urbs[j].size, card->urbs[j].buffer, card->urbs[j].urb->transfer_dma); card->urbs[j].buffer = NULL; } if (card->urbs[j].urb) { usb_free_urb(card->urbs[j].urb); card->urbs[j].urb = NULL; } } cpcusb_delete(card); return retval; }
static int appledisplay_probe(struct usb_interface *iface, const struct usb_device_id *id) { struct backlight_properties props; struct appledisplay *pdata; struct usb_device *udev = interface_to_usbdev(iface); struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int int_in_endpointAddr = 0; int i, retval = -ENOMEM, brightness; char bl_name[20]; /* set up the endpoint information */ /* use only the first interrupt-in endpoint */ iface_desc = iface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { endpoint = &iface_desc->endpoint[i].desc; if (!int_in_endpointAddr && usb_endpoint_is_int_in(endpoint)) { /* we found an interrupt in endpoint */ int_in_endpointAddr = endpoint->bEndpointAddress; break; } } if (!int_in_endpointAddr) { dev_err(&iface->dev, "Could not find int-in endpoint\n"); return -EIO; } /* allocate memory for our device state and initialize it */ pdata = kzalloc(sizeof(struct appledisplay), GFP_KERNEL); if (!pdata) { retval = -ENOMEM; dev_err(&iface->dev, "Out of memory\n"); goto error; } pdata->udev = udev; spin_lock_init(&pdata->lock); INIT_DELAYED_WORK(&pdata->work, appledisplay_work); /* Allocate buffer for control messages */ pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); if (!pdata->msgdata) { retval = -ENOMEM; dev_err(&iface->dev, "Allocating buffer for control messages failed\n"); goto error; } /* Allocate interrupt URB */ pdata->urb = usb_alloc_urb(0, GFP_KERNEL); if (!pdata->urb) { retval = -ENOMEM; dev_err(&iface->dev, "Allocating URB failed\n"); goto error; } /* Allocate buffer for interrupt data */ pdata->urbdata = usb_buffer_alloc(pdata->udev, ACD_URB_BUFFER_LEN, GFP_KERNEL, &pdata->urb->transfer_dma); if (!pdata->urbdata) { retval = -ENOMEM; dev_err(&iface->dev, "Allocating URB buffer failed\n"); goto error; } /* Configure interrupt URB */ usb_fill_int_urb(pdata->urb, udev, usb_rcvintpipe(udev, int_in_endpointAddr), pdata->urbdata, ACD_URB_BUFFER_LEN, appledisplay_complete, pdata, 1); if (usb_submit_urb(pdata->urb, GFP_KERNEL)) { retval = -EIO; dev_err(&iface->dev, "Submitting URB failed\n"); goto error; } /* Register backlight device */ snprintf(bl_name, sizeof(bl_name), "appledisplay%d", atomic_inc_return(&count_displays) - 1); memset(&props, 0, sizeof(struct backlight_properties)); props.max_brightness = 0xff; pdata->bd = backlight_device_register(bl_name, NULL, pdata, &appledisplay_bl_data, &props); if (IS_ERR(pdata->bd)) { dev_err(&iface->dev, "Backlight registration failed\n"); retval = PTR_ERR(pdata->bd); goto error; } /* Try to get brightness */ brightness = appledisplay_bl_get_brightness(pdata->bd); if (brightness < 0) { retval = brightness; dev_err(&iface->dev, "Error while getting initial brightness: %d\n", retval); goto error; } /* Set brightness in backlight device */ pdata->bd->props.brightness = brightness; /* save our data pointer in the interface device */ usb_set_intfdata(iface, pdata); printk(KERN_INFO "appledisplay: Apple Cinema Display connected\n"); return 0; error: if (pdata) { if (pdata->urb) { usb_kill_urb(pdata->urb); if (pdata->urbdata) usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN, pdata->urbdata, pdata->urb->transfer_dma); usb_free_urb(pdata->urb); } if (pdata->bd && !IS_ERR(pdata->bd)) backlight_device_unregister(pdata->bd); kfree(pdata->msgdata); } usb_set_intfdata(iface, NULL); kfree(pdata); return retval; }
static ssize_t retina_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) { struct usb_retina *dev; int retval = 0; struct urb *urb = NULL; void *buf = NULL; size_t writesize; u8 request = user_buffer[0]; u16 value = (user_buffer[1]&0x00ff)+((user_buffer[2]<<8)&0xff00); u16 index = (user_buffer[3]&0x00ff)+((user_buffer[4]<<8)&0xff00); user_buffer= user_buffer+5; writesize = min(count-5, (size_t)MAX_TRANSFER); dev = (struct usb_retina *)file->private_data; /*dev_info(&dev->interface->dev,"Request,Value,Index,Count=0x%x,%d,%d,%d",request,value,index,writesize);*/ /* create a urb, and a buffer for it, and copy the data to the urb urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { retval = -ENOMEM; goto error; }*/ if (0)//writesize > 0) { buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma); if (!buf) { retval = -ENOMEM; goto error; } if (copy_from_user(buf, user_buffer, writesize)) { retval = -EFAULT; goto error; } } /* this lock makes sure we don't submit URBs to gone devices mutex_lock(&dev->io_mutex); if (!dev->interface) { disconnect() was called mutex_unlock(&dev->io_mutex); retval = -ENODEV; goto error; }*/ /* initialize the urb properly usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), buf, writesize, retina_write_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &dev->submitted); send the data out the bulk port retval = usb_submit_urb(urb, GFP_KERNEL);*/ /*use the write call for submitting vendor requests. java has no ioctl.*/ /*retval = vendorRequest(dev, request, value, index, buf, writesize);*/ retval = vendorRequest(dev, request, value, index, buf, writesize); /*dev_info(&dev->interface->dev,"retina_write(ioctl): VENDOR_REQUEST 0x%x returned %d.\n(Val,Ind,Cnt=0x%x,0x%x,0x%x)",request, retval,value,index,writesize);*/ /*mutex_unlock(&dev->io_mutex);*/ if (retval) { dev_err(&dev->interface->dev,"%s - failed vendor request, error %d", __FUNCTION__, retval); goto exit; } /* release our reference to this urb, the USB core will eventually free it entirely usb_free_urb(urb);*/ return writesize+5; error: exit: return retval; }
static int modem_startup(struct usb_serial *serial) { struct usb_serial_port *port = serial->port[0]; struct modem_port *modem_port_ptr = NULL; struct usb_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_endpoint_descriptor *epread = NULL; struct usb_endpoint_descriptor *epwrite = NULL; struct usb_host_interface *iface_desc; unsigned long flags; int readsize; int num_rx_buf; int i; int retval = 0; interface = serial->interface; iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_bulk_in(endpoint)) epread = endpoint; if (usb_endpoint_is_bulk_out(endpoint)) epwrite = endpoint; } if (epread == NULL) { dev_err(&serial->dev->dev, "%s: No Bulk In Endpoint for this Interface\n", __func__); return -EPERM; } if (epwrite == NULL) { dev_err(&serial->dev->dev, "%s: No Bulk Out Endpoint for this Interface\n", __func__); return -EPERM; } num_rx_buf = AP_NR; readsize = le16_to_cpu(epread->wMaxPacketSize) * 2; /* setup a buffer to store interface data */ modem_port_ptr = kzalloc(sizeof(struct modem_port), GFP_KERNEL); if (modem_port_ptr == NULL) { dev_err(&serial->dev->dev, "%s: error -- no memory on start up.\n", __func__); return -ENOMEM; } /* init tasklet for rx processing */ tasklet_init(&modem_port_ptr->urb_task, modem_rx_tasklet, (unsigned long)modem_port_ptr); modem_port_ptr->rx_buflimit = num_rx_buf; modem_port_ptr->rx_endpoint = usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress); spin_lock_init(&modem_port_ptr->read_lock); spin_lock_init(&modem_port_ptr->write_lock); spin_lock_init(&modem_port_ptr->last_traffic_lock); atomic_set(&modem_port_ptr->wakeup_flag, 0); modem_port_ptr->serial = serial; modem_port_ptr->susp_count = 0; modem_port_ptr->resuming = 0; modem_port_ptr->port = 0; modem_port_ptr->last_traffic = 0; modem_port_ptr->readsize = readsize; modem_port_ptr->writesize = le16_to_cpu(epwrite->wMaxPacketSize) * 20; modem_port_ptr->number = modem_attached_ports++; INIT_WORK(&modem_port_ptr->wake_and_write, modem_wake_and_write); INIT_WORK(&modem_port_ptr->usb_wkup_work, modem_usb_wkup_work); if (modem_write_buffers_alloc(modem_port_ptr, serial) < 0) { dev_err(&serial->dev->dev, "%s: out of memory\n", __func__); goto alloc_write_buf_fail; } /* allocate multiple receive urb pool */ for (i = 0; i < num_rx_buf; i++) { struct ap_ru *rcv = &(modem_port_ptr->ru[i]); rcv->urb = usb_alloc_urb(0, GFP_KERNEL); if (rcv->urb == NULL) { dev_err(&serial->dev->dev, "%s: out of memory\n", __func__); goto alloc_rb_urb_fail; } rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; rcv->instance = modem_port_ptr; } /* allocate multiple receive buffer */ for (i = 0; i < num_rx_buf; i++) { struct ap_rb *rb = &(modem_port_ptr->rb[i]); rb->base = usb_buffer_alloc(serial->dev, readsize, GFP_KERNEL, &rb->dma); if (!rb->base) { dev_err(&serial->dev->dev, "%s : out of memory\n", __func__); goto alloc_rb_buffer_fail; } } for (i = 0; i < AP_NW; i++) { struct ap_wb *snd = &(modem_port_ptr->wb[i]); snd->urb = usb_alloc_urb(0, GFP_KERNEL); if (!snd->urb) { dev_err(&serial->dev->dev, "%s : out of memory " "(write urbs usb_alloc_urb)\n", __func__); goto alloc_wb_urb_fail; } usb_fill_bulk_urb(snd->urb, serial->dev, usb_sndbulkpipe(serial->dev, epwrite->bEndpointAddress), NULL, modem_port_ptr->writesize, modem_write_bulk_callback, snd); snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; snd->instance = modem_port_ptr; } modem_port_ptr->modem_status = 0; /* The modem has presented a usb interface, remove the shutdown timer. */ spin_lock_irqsave(&modem.lock, flags); if (modem.connected == false) { modem.connected = true; cancel_delayed_work(&modem.delayed_pwr_shutdown); } spin_unlock_irqrestore(&modem.lock, flags); /* install serial private data */ usb_set_serial_data(serial, modem_port_ptr); if (modem_port_ptr->number == MODEM_INTERFACE_NUM) { modem.wq = create_singlethread_workqueue("mdm6600_usb_wq"); wake_lock_init(&modem.wakelock, WAKE_LOCK_SUSPEND, "mdm6600_usb_modem"); /* install the BP GPIO wakeup irq and disable it first */ if (modem_wake_irq) { retval = request_irq( modem_wake_irq, gpio_wkup_interrupt_handler, IRQ_DISABLED | IRQ_TYPE_EDGE_FALLING, "mdm6600_usb_wakeup", modem_port_ptr); if (retval) dev_err(&interface->dev, "%s request_irq failed \n", __func__); else disable_irq(modem_wake_irq); } } return 0; alloc_wb_urb_fail: for (i = 0; i < AP_NW; i++) usb_free_urb(modem_port_ptr->wb[i].urb); alloc_rb_buffer_fail: modem_read_buffers_free(modem_port_ptr, serial); alloc_rb_urb_fail: for (i = 0; i < num_rx_buf; i++) usb_free_urb(modem_port_ptr->ru[i].urb); alloc_write_buf_fail: modem_write_buffers_free(modem_port_ptr, serial); if (modem_port_ptr != NULL) { kfree(modem_port_ptr); usb_set_serial_data(serial, NULL); } modem_attached_ports--; return -ENOMEM; }
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev (intf); struct usb_xpad *xpad; struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; int i; int error = -ENOMEM; for (i = 0; xpad_device[i].idVendor; i++) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct)) break; } xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); input_dev = input_allocate_device(); if (!xpad || !input_dev) goto fail1; xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, GFP_ATOMIC, &xpad->idata_dma); if (!xpad->idata) goto fail1; xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_in) goto fail2; xpad->udev = udev; xpad->dpad_mapping = xpad_device[i].dpad_mapping; if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) xpad->dpad_mapping = dpad_to_buttons; xpad->dev = input_dev; usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); input_dev->name = xpad_device[i].name; input_dev->phys = xpad->phys; usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, xpad); input_dev->open = xpad_open; input_dev->close = xpad_close; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); /* set up buttons */ for (i = 0; xpad_btn[i] >= 0; i++) set_bit(xpad_btn[i], input_dev->keybit); if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) for (i = 0; xpad_btn_pad[i] >= 0; i++) set_bit(xpad_btn_pad[i], input_dev->keybit); /* set up axes */ for (i = 0; xpad_abs[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs[i]); if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) for (i = 0; xpad_abs_pad[i] >= 0; i++) xpad_set_up_abs(input_dev, xpad_abs_pad[i]); ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), xpad->idata, XPAD_PKT_LEN, xpad_irq_in, xpad, ep_irq_in->bInterval); xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; error = input_register_device(xpad->dev); if (error) goto fail3; usb_set_intfdata(intf, xpad); return 0; fail3: usb_free_urb(xpad->irq_in); fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); fail1: input_free_device(input_dev); kfree(xpad); return error; }
static int bcm5974_probe(struct usb_interface *iface, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(iface); const struct bcm5974_config *cfg; struct bcm5974 *dev; struct input_dev *input_dev; int error = -ENOMEM; /* find the product index */ cfg = bcm5974_get_config(udev); /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL); input_dev = input_allocate_device(); if (!dev || !input_dev) { err("bcm5974: out of memory"); goto err_free_devs; } dev->udev = udev; dev->intf = iface; dev->input = input_dev; dev->cfg = *cfg; mutex_init(&dev->pm_mutex); /* setup urbs */ dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->bt_urb) goto err_free_devs; dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->tp_urb) goto err_free_bt_urb; dev->bt_data = usb_buffer_alloc(dev->udev, dev->cfg.bt_datalen, GFP_KERNEL, &dev->bt_urb->transfer_dma); if (!dev->bt_data) goto err_free_urb; dev->tp_data = usb_buffer_alloc(dev->udev, dev->cfg.tp_datalen, GFP_KERNEL, &dev->tp_urb->transfer_dma); if (!dev->tp_data) goto err_free_bt_buffer; usb_fill_int_urb(dev->bt_urb, udev, usb_rcvintpipe(udev, cfg->bt_ep), dev->bt_data, dev->cfg.bt_datalen, bcm5974_irq_button, dev, 1); usb_fill_int_urb(dev->tp_urb, udev, usb_rcvintpipe(udev, cfg->tp_ep), dev->tp_data, dev->cfg.tp_datalen, bcm5974_irq_trackpad, dev, 1); /* create bcm5974 device */ usb_make_path(udev, dev->phys, sizeof(dev->phys)); strlcat(dev->phys, "/input0", sizeof(dev->phys)); input_dev->name = "bcm5974"; input_dev->phys = dev->phys; usb_to_input_id(dev->udev, &input_dev->id); /* report driver capabilities via the version field */ input_dev->id.version = cfg->caps; input_dev->dev.parent = &iface->dev; input_set_drvdata(input_dev, dev); input_dev->open = bcm5974_open; input_dev->close = bcm5974_close; setup_events_to_report(input_dev, cfg); error = input_register_device(dev->input); if (error) goto err_free_buffer; /* save our data pointer in this interface device */ usb_set_intfdata(iface, dev); return 0; err_free_buffer: usb_buffer_free(dev->udev, dev->cfg.tp_datalen, dev->tp_data, dev->tp_urb->transfer_dma); err_free_bt_buffer: usb_buffer_free(dev->udev, dev->cfg.bt_datalen, dev->bt_data, dev->bt_urb->transfer_dma); err_free_urb: usb_free_urb(dev->tp_urb); err_free_bt_urb: usb_free_urb(dev->bt_urb); err_free_devs: usb_set_intfdata(iface, NULL); input_free_device(input_dev); kfree(dev); return error; }
/* 7 bytes max write! first byte bit 7 - flush buffer (buffer will only contain result of this command) bit 6 - query? (1 = query/read, 0 = set/write) if query is set, this is a single byte command bit 5 - PORTA dir present "@00D0%02X\r" bit 4 - PORTB dir present "@00D1%02X\r" bit 3 - PORTC dir present "@00D2%02X\r" bit 2 - PORTA data present "@00P0%02X\r" bit 1 - PORTB data present "@00P1%02X\r" bit 0 - PORTC data present "@00P2%02X\r" */ static ssize_t diodev_write(struct file *file, const char __user *user_buffer, size_t count, loff_t *ppos) { #define CMDSEP "\r" //#define CMDSEP "-" struct usb_dio_dev *dev; struct usb_dio_urb_chain *bulk_out_urb_chain; struct usb_dio_urb_chain *t_urb_chain; struct urb *urb; char *urbBuf; unsigned char buf[7]; int ptr; unsigned char usbBuf[64]; /* max of 48 bytes possible */ int usbBytes = 0; int isQuery = 0; int retval; FUNC_HI(); dev = (struct usb_dio_dev *)file->private_data; if (count > 7) { printk(KERN_ALERT "=== Too many bytes! (%d)\n", (int)count); FUNC_ERR(); return -EIO; } if (copy_from_user(&(buf[0]),user_buffer,count)) { printk(KERN_ALERT "=== Copy error\n"); FUNC_ERR(); return -EIO; } if (buf[0] & 0x80) { if (down_interruptible(&dev->buffer_sem)) { FUNC_ERR(); return -EINTR; } dev->buffer_head = 0; dev->buffer_tail = 0; up(&dev->buffer_sem); DPRINTK(KERN_ALERT "=== Flushed\n"); } if (buf[0] & 0x40) { isQuery = 1; DPRINTK(KERN_ALERT "=== isQuery\n"); } /* if is a query... we only need 1 byte! */ if (buf[0] & 0x40) { DPRINTK(KERN_ALERT "=== Looking for %d bytes...\n",1); DPRINTK(KERN_ALERT "=== Given %d bytes...\n", (int)count); if (count != 1) { FUNC_ERR(); return -EIO; } } else { int c = 1; unsigned char t = 0x20; while (t) { if (buf[0] & t) c++; t >>= 1; t &= 0x7F; } DPRINTK(KERN_ALERT "=== Looking for %d bytes...\n",c); DPRINTK(KERN_ALERT "=== Given %d bytes...\n", (int)count); if (count != c) { FUNC_ERR(); return -EIO; } } if (isQuery) { DDPRINTK("Q-"); } else { DDPRINTK("W-"); } ptr = 1; if (buf[0] & 0x20) { DDPRINTK("d0"); DPRINTK(KERN_ALERT "=== D0\n"); if (isQuery) { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00D0?"CMDSEP); } else { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00D0%02X"CMDSEP,buf[ptr]); ptr++; } } if (buf[0] & 0x10) { DDPRINTK("d1"); DPRINTK(KERN_ALERT "=== D1\n"); if (isQuery) { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00D1?"CMDSEP); } else { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00D1%02X"CMDSEP,buf[ptr]); ptr++; } } if (buf[0] & 0x08) { DDPRINTK("d2"); DPRINTK(KERN_ALERT "=== D2\n"); if (isQuery) { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00D2?"CMDSEP); } else { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00D2%02X"CMDSEP,buf[ptr]); ptr++; } } if (buf[0] & 0x04) { DDPRINTK("p0"); DPRINTK(KERN_ALERT "=== P0\n"); if (isQuery) { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00P0?"CMDSEP); } else { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00P0%02X"CMDSEP,buf[ptr]); ptr++; } } if (buf[0] & 0x02) { DDPRINTK("p1"); DPRINTK(KERN_ALERT "=== P1\n"); if (isQuery) { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00P1?"CMDSEP); } else { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00P1%02X"CMDSEP,buf[ptr]); ptr++; } } if (buf[0] & 0x01) { DDPRINTK("p2"); DPRINTK(KERN_ALERT "=== P2\n"); if (isQuery) { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00P2?"CMDSEP); } else { usbBytes += snprintf(&(usbBuf[usbBytes]),64-usbBytes,"@00P2%02X"CMDSEP,buf[ptr]); ptr++; } } DPRINTK(KERN_ALERT "=== STRING:- %s\n",usbBuf); DPRINTK(KERN_ALERT "=== Building URB...\n"); urb = usb_alloc_urb(0, GFP_KERNEL); DPRINTK(KERN_ALERT "** urb @ %p\n",urb); if (!urb) { FUNC_ERR(); return -ENOMEM; } DPRINTK(KERN_ALERT "=== Building Buffer (%d)...\n",usbBytes); urbBuf = usb_buffer_alloc(dev->dev, usbBytes, GFP_KERNEL, &urb->transfer_dma); DPRINTK(KERN_ALERT "** urbBuf @ %p\n",urbBuf); if (!urbBuf) { usb_free_urb(urb); FUNC_ERR(); return -ENOMEM; } DPRINTK(KERN_ALERT "=== Populating Buffer...\n"); memcpy(urbBuf, usbBuf, usbBytes); usb_fill_bulk_urb(urb, dev->dev, dev->bulk_out_endpointPipe, urbBuf, usbBytes, (usb_complete_t)diodev_write_cb, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; t_urb_chain = kmalloc(sizeof(struct usb_dio_urb_chain), GFP_KERNEL); if (dev == NULL) { err("Out of Memory"); FUNC_ERR(); return -ENOMEM; } t_urb_chain->next = NULL; t_urb_chain->urb = urb; if (down_interruptible(&dev->bulk_out_urb_chain_sem)) { FUNC_ERR(); return -EINTR; } if (dev->bulk_out_urb_chain) { DDPRINTK("-C"); DPRINTK(KERN_ALERT "=== Chaining URB...\n"); bulk_out_urb_chain = dev->bulk_out_urb_chain; while (bulk_out_urb_chain->next) { bulk_out_urb_chain = bulk_out_urb_chain->next; } bulk_out_urb_chain->next = t_urb_chain; } else { DDPRINTK("-S"); DPRINTK(KERN_ALERT "=== Submitting URB...\n"); retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) { up(&dev->bulk_out_urb_chain_sem); DPRINTK(KERN_ALERT "=== URB submit error %d\n", retval); usb_buffer_free(dev->dev, usbBytes, urbBuf, urb->transfer_dma); usb_free_urb(urb); FUNC_ERR(); return retval; } dev->bulk_out_urb_chain = t_urb_chain; } DDPRINTK("\n"); up(&dev->bulk_out_urb_chain_sem); DPRINTK(KERN_ALERT "=== diodev_write() Returning!\n"); FUNC_BYE(); return count; }
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_host_interface *interface = intf->cur_altsetting; struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; struct wacom_features *features; struct input_dev *input_dev; int error = -ENOMEM; char rep_data[2], limit = 0; struct hid_descriptor *hid_desc; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); input_dev = input_allocate_device(); if (!wacom || !input_dev || !wacom_wac) goto fail1; wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); if (!wacom_wac->data) goto fail1; wacom->irq = usb_alloc_urb(0, GFP_KERNEL); if (!wacom->irq) goto fail2; wacom->usbdev = dev; wacom->dev = input_dev; wacom->intf = intf; mutex_init(&wacom->lock); usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); wacom_wac->features = features = get_wacom_feature(id); BUG_ON(features->pktlen > 10); input_dev->name = wacom_wac->features->name; wacom->wacom_wac = wacom_wac; usb_to_input_id(dev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_set_drvdata(input_dev, wacom); input_dev->open = wacom_open; input_dev->close = wacom_close; endpoint = &intf->cur_altsetting->endpoint[0].desc; /* Initialize touch_x_max and touch_y_max in case it is not defined */ if (wacom_wac->features->type == TABLETPC) { features->touch_x_max = 1023; features->touch_y_max = 1023; } else { features->touch_x_max = 0; features->touch_y_max = 0; } /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ if (wacom_wac->features->type == TABLETPC) { if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { if (usb_get_extra_descriptor(&interface->endpoint[0], HID_DEVICET_REPORT, &hid_desc)) { printk("wacom: can not retrive extra class descriptor\n"); goto fail2; } } error = wacom_parse_hid(intf, hid_desc, wacom_wac); if (error) goto fail2; } input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); if (features->type == TABLETPC) { input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0); input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0); } input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); wacom_init_input_dev(input_dev, wacom_wac); usb_fill_int_urb(wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), wacom_wac->data, wacom_wac->features->pktlen, wacom_sys_irq, wacom, endpoint->bInterval); wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; error = input_register_device(wacom->dev); if (error) goto fail3; /* * Ask the tablet to report tablet data if it is not a Tablet PC. * Repeat until it succeeds */ if (wacom_wac->features->type != TABLETPC) { do { rep_data[0] = 2; rep_data[1] = 2; error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); if (error >= 0) error = usb_get_report(intf, WAC_HID_FEATURE_REPORT, 2, rep_data, 2); } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); } usb_set_intfdata(intf, wacom); return 0; fail3: usb_free_urb(wacom->irq); fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); fail1: input_free_device(input_dev); kfree(wacom); kfree(wacom_wac); return error; }
static int acm_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct usb_cdc_union_desc *union_header = NULL; struct usb_cdc_country_functional_desc *cfd = NULL; unsigned char *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; struct usb_interface *control_interface; struct usb_interface *data_interface; struct usb_endpoint_descriptor *epctrl; struct usb_endpoint_descriptor *epread; struct usb_endpoint_descriptor *epwrite; struct usb_device *usb_dev = interface_to_usbdev(intf); struct acm *acm; int minor; int ctrlsize,readsize; u8 *buf; u8 ac_management_function = 0; u8 call_management_function = 0; int call_interface_num = -1; int data_interface_num; unsigned long quirks; int num_rx_buf; int i; /* normal quirks */ quirks = (unsigned long)id->driver_info; num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; /* handle quirks deadly to normal probing*/ if (quirks == NO_UNION_NORMAL) { data_interface = usb_ifnum_to_if(usb_dev, 1); control_interface = usb_ifnum_to_if(usb_dev, 0); goto skip_normal_probe; } /* normal probing*/ if (!buffer) { err("Weird descriptor references\n"); return -EINVAL; } if (!buflen) { if (intf->cur_altsetting->endpoint && intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) { dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n"); buflen = intf->cur_altsetting->endpoint->extralen; buffer = intf->cur_altsetting->endpoint->extra; } else { err("Zero length descriptor references\n"); return -EINVAL; } } while (buflen > 0) { if (buffer [1] != USB_DT_CS_INTERFACE) { err("skipping garbage\n"); goto next_desc; } switch (buffer [2]) { case USB_CDC_UNION_TYPE: /* we've found it */ if (union_header) { err("More than one union descriptor, skipping ..."); goto next_desc; } union_header = (struct usb_cdc_union_desc *) buffer; break; case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ cfd = (struct usb_cdc_country_functional_desc *)buffer; break; case USB_CDC_HEADER_TYPE: /* maybe check version */ break; /* for now we ignore it */ case USB_CDC_ACM_TYPE: ac_management_function = buffer[3]; break; case USB_CDC_CALL_MANAGEMENT_TYPE: call_management_function = buffer[3]; call_interface_num = buffer[4]; if ((call_management_function & 3) != 3) err("This device cannot do calls on its own. It is no modem."); break; default: /* there are LOTS more CDC descriptors that * could legitimately be found here. */ dev_dbg(&intf->dev, "Ignoring descriptor: " "type %02x, length %d\n", buffer[2], buffer[0]); break; } next_desc: buflen -= buffer[0]; buffer += buffer[0]; } if (!union_header) { if (call_interface_num > 0) { dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n"); data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); control_interface = intf; } else { dev_dbg(&intf->dev,"No union descriptor, giving up\n"); return -ENODEV; } } else { control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); if (!control_interface || !data_interface) { dev_dbg(&intf->dev,"no interfaces\n"); return -ENODEV; } } if (data_interface_num != call_interface_num) dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n"); skip_normal_probe: /*workaround for switched interfaces */ if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) { if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) { struct usb_interface *t; dev_dbg(&intf->dev,"Your device has switched interfaces.\n"); t = control_interface; control_interface = data_interface; data_interface = t; } else { return -EINVAL; } } /* Accept probe requests only for the control interface */ if (intf != control_interface) return -ENODEV; if (usb_interface_claimed(data_interface)) { /* valid in this context */ dev_dbg(&intf->dev,"The data interface isn't available\n"); return -EBUSY; } if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) return -EINVAL; epctrl = &control_interface->cur_altsetting->endpoint[0].desc; epread = &data_interface->cur_altsetting->endpoint[0].desc; epwrite = &data_interface->cur_altsetting->endpoint[1].desc; /* workaround for switched endpoints */ if (!usb_endpoint_dir_in(epread)) { /* descriptors are swapped */ struct usb_endpoint_descriptor *t; dev_dbg(&intf->dev,"The data interface has switched endpoints\n"); t = epread; epread = epwrite; epwrite = t; } dbg("interfaces are valid"); for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); if (minor == ACM_TTY_MINORS) { err("no more free acm devices"); return -ENODEV; } if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) { dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n"); goto alloc_fail; } ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); readsize = le16_to_cpu(epread->wMaxPacketSize)* ( quirks == SINGLE_RX_URB ? 1 : 2); acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize) * 20; acm->control = control_interface; acm->data = data_interface; acm->minor = minor; acm->dev = usb_dev; acm->ctrl_caps = ac_management_function; acm->ctrlsize = ctrlsize; acm->readsize = readsize; acm->rx_buflimit = num_rx_buf; acm->urb_task.func = acm_rx_tasklet; acm->urb_task.data = (unsigned long) acm; INIT_WORK(&acm->work, acm_softint); INIT_WORK(&acm->waker, acm_waker); spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); mutex_init(&acm->mutex); acm->write_ready = 1; acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); if (!buf) { dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n"); goto alloc_fail2; } acm->ctrl_buffer = buf; if (acm_write_buffers_alloc(acm) < 0) { dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); goto alloc_fail4; } acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->ctrlurb) { dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); goto alloc_fail5; } for (i = 0; i < num_rx_buf; i++) { struct acm_ru *rcv = &(acm->ru[i]); if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); goto alloc_fail7; } rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; rcv->instance = acm; } for (i = 0; i < num_rx_buf; i++) { struct acm_rb *buf = &(acm->rb[i]); if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); goto alloc_fail7; } } for(i = 0; i < ACM_NW; i++) { struct acm_wb *snd = &(acm->wb[i]); if (!(snd->urb = usb_alloc_urb(0, GFP_KERNEL))) { dev_dbg(&intf->dev, "out of memory (write urbs usb_alloc_urb)"); goto alloc_fail7; } usb_fill_bulk_urb(snd->urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), NULL, acm->writesize, acm_write_bulk, snd); snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; snd->instance = acm; } usb_set_intfdata (intf, acm); i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); if (i < 0) goto alloc_fail8; if (cfd) { /* export the country data */ acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); if (!acm->country_codes) goto skip_countries; acm->country_code_size = cfd->bLength - 4; memcpy(acm->country_codes, (u8 *)&cfd->wCountyCode0, cfd->bLength - 4); acm->country_rel_date = cfd->iCountryCodeRelDate; i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); if (i < 0) { kfree(acm->country_codes); goto skip_countries; } i = device_create_file(&intf->dev, &dev_attr_iCountryCodeRelDate); if (i < 0) { kfree(acm->country_codes); goto skip_countries; } } skip_countries: usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress), acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval); acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; acm->ctrlurb->transfer_dma = acm->ctrl_dma; dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); acm_set_control(acm, acm->ctrlout); acm->line.dwDTERate = cpu_to_le32(9600); acm->line.bDataBits = 8; acm_set_line(acm, &acm->line); usb_driver_claim_interface(&acm_driver, data_interface, acm); usb_get_intf(control_interface); tty_register_device(acm_tty_driver, minor, &control_interface->dev); acm_table[minor] = acm; return 0; alloc_fail8: for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); alloc_fail7: acm_read_buffers_free(acm); for (i = 0; i < num_rx_buf; i++) usb_free_urb(acm->ru[i].urb); usb_free_urb(acm->ctrlurb); alloc_fail5: acm_write_buffers_free(acm); alloc_fail4: usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); alloc_fail2: kfree(acm); alloc_fail: return -ENOMEM; }
static int usb_remote_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = NULL; struct usb_host_interface *idesc = NULL; struct usb_host_endpoint *ep_ctl2; #else static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) { struct usb_interface *intf; struct usb_interface_descriptor *idesc; struct usb_endpoint_descriptor *ep_ctl2; #endif struct igorplug *ir = NULL; struct lirc_driver *driver = NULL; int devnum, pipe, maxp; int minor = 0; char buf[63], name[128] = ""; int mem_failure = 0; int ret; dprintk(": usb probe called.\n"); #if defined(KERNEL_2_5) dev = interface_to_usbdev(intf); # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) idesc = &intf->altsetting[intf->act_altsetting]; /* in 2.6.4 */ # else idesc = intf->cur_altsetting; /* in 2.6.6 */ # endif if (idesc->desc.bNumEndpoints != 1) return -ENODEV; ep_ctl2 = idesc->endpoint; if (((ep_ctl2->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN) || (ep_ctl2->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL) return -ENODEV; pipe = usb_rcvctrlpipe(dev, ep_ctl2->desc.bEndpointAddress); #else intf = &dev->actconfig->interface[ifnum]; idesc = &intf->altsetting[intf->act_altsetting]; if (idesc->bNumEndpoints != 1) return NULL; ep_ctl2 = idesc->endpoint; if (((ep_ctl2->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN) || (ep_ctl2->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL) return NULL; pipe = usb_rcvctrlpipe(dev, ep_ctl2->bEndpointAddress); #endif devnum = dev->devnum; maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); dprintk(DRIVER_NAME "[%d]: bytes_in_key=%d maxp=%d\n", devnum, CODE_LENGTH, maxp); mem_failure = 0; ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL); if (!ir) { mem_failure = 1; goto mem_failure_switch; } driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); if (!driver) { mem_failure = 2; goto mem_failure_switch; } #if defined(KERNEL_2_5) ir->buf_in = usb_buffer_alloc(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, GFP_ATOMIC, &ir->dma_in); #else ir->buf_in = kmalloc(DEVICE_BUFLEN+DEVICE_HEADERLEN, GFP_KERNEL); #endif if (!ir->buf_in) { mem_failure = 3; goto mem_failure_switch; } strcpy(driver->name, DRIVER_NAME " "); driver->minor = -1; driver->code_length = CODE_LENGTH * 8; /* in bits */ driver->features = LIRC_CAN_REC_MODE2; driver->data = ir; driver->buffer_size = DEVICE_BUFLEN + ADDITIONAL_LIRC_BYTES; driver->set_use_inc = &set_use_inc; driver->set_use_dec = &set_use_dec; driver->sample_rate = sample_rate; /* per second */ driver->add_to_buf = &usb_remote_poll; #ifdef LIRC_HAVE_SYSFS driver->dev = &intf->dev; #endif driver->owner = THIS_MODULE; minor = lirc_register_driver(driver); if (minor < 0) mem_failure = 9; mem_failure_switch: switch (mem_failure) { case 9: #if defined(KERNEL_2_5) usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, ir->buf_in, ir->dma_in); #else kfree(ir->buf_in); #endif case 3: kfree(driver); case 2: kfree(ir); case 1: printk(KERN_ERR DRIVER_NAME "[%d]: out of memory (code=%d)\n", devnum, mem_failure); #if defined(KERNEL_2_5) return -ENOMEM; #else return NULL; #endif } driver->minor = minor; ir->d = driver; ir->devnum = devnum; ir->usbdev = dev; ir->len_in = DEVICE_BUFLEN+DEVICE_HEADERLEN; ir->in_space = 1; /* First mode2 event is a space. */ do_gettimeofday(&ir->last_time); if (dev->descriptor.iManufacturer && usb_string(dev, dev->descriptor.iManufacturer, buf, sizeof(buf)) > 0) strlcpy(name, buf, sizeof(name)); if (dev->descriptor.iProduct && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0) snprintf(name + strlen(name), sizeof(name) - strlen(name), " %s", buf); printk(KERN_INFO DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, dev->bus->busnum, devnum); /* clear device buffer */ ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, /*unused*/0, /*unused*/0, /*dummy*/ir->buf_in, /*dummy*/ir->len_in, /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); if (ret < 0) printk(KERN_WARNING DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n", devnum, ret); #if defined(KERNEL_2_5) usb_set_intfdata(intf, ir); return 0; #else return ir; #endif } #if defined(KERNEL_2_5) static void usb_remote_disconnect(struct usb_interface *intf) { struct usb_device *dev = interface_to_usbdev(intf); struct igorplug *ir = usb_get_intfdata(intf); #else static void usb_remote_disconnect(struct usb_device *dev, void *ptr) { struct igorplug *ir = ptr; #endif if (!ir || !ir->d) return; printk(KERN_INFO DRIVER_NAME "[%d]: usb remote disconnected\n", ir->devnum); lirc_unregister_driver(ir->d->minor); lirc_buffer_free(ir->d->rbuf); kfree(ir->d->rbuf); kfree(ir->d); #if defined(KERNEL_2_5) usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in); #else kfree(ir->buf_in); #endif kfree(ir); } static struct usb_device_id usb_remote_id_table [] = { /* Igor Plug USB (Atmel's Manufact. ID) */ { USB_DEVICE(0x03eb, 0x0002) }, /* Fit PC2 Infrared Adapter */ { USB_DEVICE(0x03eb, 0x21fe) }, /* Terminating entry */ { } }; static struct usb_driver usb_remote_driver = { LIRC_THIS_MODULE(.owner = THIS_MODULE) .name = DRIVER_NAME, .probe = usb_remote_probe, .disconnect = usb_remote_disconnect, .id_table = usb_remote_id_table }; static int __init usb_remote_init(void) { int i; printk(KERN_INFO DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n"); printk(KERN_INFO DRIVER_NAME ": " DRIVER_AUTHOR "\n"); dprintk(": debug mode enabled\n"); i = usb_register(&usb_remote_driver); if (i < 0) { printk(KERN_ERR DRIVER_NAME ": usb register failed, result = %d\n", i); return -ENODEV; } return 0; }