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, r; 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; r = down_interruptible(&dev->limit_sem); if (r < 0) return -EINTR; /* 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 err_no_buf; } 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; usb_anchor_urb(urb, &dev->submitted); /* 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", __func__, retval); goto error_unanchor; } /* release our reference to this urb, the USB core will eventually free it entirely */ usb_free_urb(urb); exit: return count; error_unanchor: usb_unanchor_urb(urb); error: usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); usb_free_urb(urb); err_no_buf: up(&dev->limit_sem); return retval; }
/* * iowarrior_write */ static ssize_t iowarrior_write(struct file *file, const char __user *user_buffer, size_t count, loff_t *ppos) { struct iowarrior *dev; int retval = 0; char *buf = NULL; /* for IOW24 and IOW56 we need a buffer */ struct urb *int_out_urb = NULL; dev = (struct iowarrior *)file->private_data; mutex_lock(&dev->mutex); /* verify that the device wasn't unplugged */ if (dev == NULL || !dev->present) { retval = -ENODEV; goto exit; } dbg("%s - minor %d, count = %zd", __func__, dev->minor, count); /* if count is 0 we're already done */ if (count == 0) { retval = 0; goto exit; } /* We only accept full reports */ if (count != dev->report_size) { retval = -EINVAL; goto exit; } switch (dev->product_id) { case USB_DEVICE_ID_CODEMERCS_IOW24: case USB_DEVICE_ID_CODEMERCS_IOWPV1: case USB_DEVICE_ID_CODEMERCS_IOWPV2: case USB_DEVICE_ID_CODEMERCS_IOW40: /* IOW24 and IOW40 use a synchronous call */ buf = kmalloc(8, GFP_KERNEL); /* 8 bytes are enough for both products */ if (!buf) { retval = -ENOMEM; goto exit; } if (copy_from_user(buf, user_buffer, count)) { retval = -EFAULT; kfree(buf); goto exit; } retval = usb_set_report(dev->interface, 2, 0, buf, count); kfree(buf); goto exit; break; case USB_DEVICE_ID_CODEMERCS_IOW56: /* The IOW56 uses asynchronous IO and more urbs */ if (atomic_read(&dev->write_busy) == MAX_WRITES_IN_FLIGHT) { /* Wait until we are below the limit for submitted urbs */ if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto exit; } else { retval = wait_event_interruptible(dev->write_wait, (!dev->present || (atomic_read (&dev-> write_busy) < MAX_WRITES_IN_FLIGHT))); if (retval) { /* we were interrupted by a signal */ retval = -ERESTART; goto exit; } if (!dev->present) { /* The device was unplugged */ retval = -ENODEV; goto exit; } if (!dev->opened) { /* We were closed while waiting for an URB */ retval = -ENODEV; goto exit; } } } atomic_inc(&dev->write_busy); int_out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!int_out_urb) { retval = -ENOMEM; dbg("%s Unable to allocate urb ", __func__); goto error_no_urb; } buf = usb_buffer_alloc(dev->udev, dev->report_size, GFP_KERNEL, &int_out_urb->transfer_dma); if (!buf) { retval = -ENOMEM; dbg("%s Unable to allocate buffer ", __func__); goto error_no_buffer; } usb_fill_int_urb(int_out_urb, dev->udev, usb_sndintpipe(dev->udev, dev->int_out_endpoint->bEndpointAddress), buf, dev->report_size, iowarrior_write_callback, dev, dev->int_out_endpoint->bInterval); int_out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (copy_from_user(buf, user_buffer, count)) { retval = -EFAULT; goto error; } retval = usb_submit_urb(int_out_urb, GFP_KERNEL); if (retval) { dbg("%s submit error %d for urb nr.%d", __func__, retval, atomic_read(&dev->write_busy)); goto error; } /* submit was ok */ retval = count; usb_free_urb(int_out_urb); goto exit; break; default: /* what do we have here ? An unsupported Product-ID ? */ dev_err(&dev->interface->dev, "%s - not supported for product=0x%x", __FUNCTION__, dev->product_id); retval = -EFAULT; goto exit; break; } error: usb_buffer_free(dev->udev, dev->report_size, buf, int_out_urb->transfer_dma); error_no_buffer: usb_free_urb(int_out_urb); error_no_urb: atomic_dec(&dev->write_busy); wake_up_interruptible(&dev->write_wait); exit: mutex_unlock(&dev->mutex); return retval; }
static int qcnmea_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usb_dev = interface_to_usbdev(intf); struct usb_host_interface *cur_intf = intf->cur_altsetting; int epnum, minor; struct usb_endpoint_descriptor *epread, *epwrite, *eptmp; struct qcnmea *nmea; int i, num_rx_buf = QCNMEA_NR; if(cur_intf->desc.bInterfaceNumber != 1) { /*not the right interface*/ return -ENODEV; } printk(KERN_ALERT "this is qct nmea interface!\n"); epnum = cur_intf->desc.bNumEndpoints; if(epnum != 2) {/*endpoint number error*/ printk(KERN_ALERT "epnum[%d] is wrong!\n", epnum); return -EINVAL; } while(epnum > 0) { eptmp = &cur_intf->endpoint[epnum - 1].desc; if(!eptmp) return -EINVAL; if(usb_endpoint_dir_in(eptmp)) epread = eptmp; else if(usb_endpoint_dir_out(eptmp)) epwrite = eptmp; epnum--; } if(!epwrite || !epread) { printk(KERN_ALERT "epwrite[%d], epread[%d]\n", epwrite, epread); return -EINVAL; } for(minor = 0; (minor < QC_NMEA_MINORS) && qcnmea_tab[minor]; minor++) ; if(minor == QC_NMEA_MINORS) { printk(KERN_ALERT "minor is wrong!\n"); return -ENODEV; } nmea = kzalloc(sizeof(struct qcnmea), GFP_KERNEL); if(!nmea) { printk(KERN_ALERT "in alloc_fail1\n"); goto alloc_fail1; } nmea->usb_dev = usb_dev; nmea->read_size = le16_to_cpu(epread->wMaxPacketSize); nmea->write_size = le16_to_cpu(epwrite->wMaxPacketSize); nmea->intf = intf; spin_lock_init(&nmea->throttle_lock); spin_lock_init(&nmea->write_lock); spin_lock_init(&nmea->read_lock); INIT_WORK(&nmea->write_work, qcnmea_write_work, nmea); nmea->write_ready = 1; nmea->read_pipe = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); if(qcnmea_write_buf_alloc(nmea) < 0) { printk(KERN_ALERT "in alloc_fail4\n"); goto alloc_fail4; } nmea->write_urb = usb_alloc_urb(0, GFP_KERNEL); if(!nmea->write_urb) { printk(KERN_ALERT "in alloc_fail5\n"); goto alloc_fail5; } for (i = 0; i < num_rx_buf; i++) { struct qcnmea_ru *rcv = &(nmea->ru[i]); if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { //dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)"); printk(KERN_ALERT "in alloc_fail7\n"); goto alloc_fail7; } rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; rcv->instance = nmea; } for (i = 0; i < num_rx_buf; i++) { struct qcnmea_rb *buf = &(nmea->rb[i]); if (!(buf->base = usb_buffer_alloc(nmea->usb_dev, nmea->read_size, GFP_KERNEL, &buf->dma))) { //dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)"); printk(KERN_ALERT "in alloc_fail7,1\n"); goto alloc_fail7; } } tasklet_init(&nmea->rx_tasklet, qcnmea_rx_tasklet, nmea); usb_set_intfdata(intf, nmea); //if(device_create_file(&intf->dev, &dev_attr_bmCapabilities)) // goto alloc_fail7; usb_fill_bulk_urb(nmea->write_urb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), nmea->write_buf, nmea->write_size, qcnmea_write_bulk, nmea); nmea->write_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; nmea->line.dwDTERate = cpu_to_le32(9600); nmea->line.bDataBits = 8; qcnmea_set_line(nmea, &nmea->line); qcnmea_set_control(nmea, nmea->seria_out); usb_get_intf(intf); tty_register_device(qcnmea_tty_driver, minor, &intf->dev); nmea->minor = minor; qcnmea_tab[minor] = nmea; printk(KERN_ALERT "qct nmea probe ok!, read_size :%d, write_size :%d\n",nmea->read_size, nmea->write_size); return 0; alloc_fail7: for (i = 0; i < num_rx_buf; i++) usb_buffer_free(usb_dev, nmea->read_size, nmea->rb[i].base, nmea->rb[i].dma); for (i = 0; i < num_rx_buf; i++) usb_free_urb(nmea->ru[i].urb); alloc_fail6: usb_free_urb(nmea->write_urb); alloc_fail5: qcnmea_write_buf_free(nmea); alloc_fail4: alloc_fail3: alloc_fail2: kfree(nmea); alloc_fail1:
// // IOCTL // Control teensy by sending cmd to INTR endpoint // // Currently this function is unused. We leave it here // for possible future use. (It is replaced by vote_write()). // int vote_ioctl( struct inode * i_node, struct file * file, unsigned int cmd, unsigned long arg ) { struct usb_vote *vote_dev = file->private_data; int err = 0; int rc = 0; struct urb *vote_urb; // usb request char command; // g char *buf; printk(KERN_DEBUG "vote: process %i (%s) vote_ioctl cmd=%d\n", current->pid, current->comm, cmd); // // Extract the type and number bitfields, and don't decode // wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() // if (_IOC_TYPE(cmd) != VOTE_IOCTL_MAGIC) { printk(KERN_NOTICE "vote_ioctl: !vote_IOC_MAGIC\n"); return -ENOTTY; } if (_IOC_NR(cmd) > VOTE_IOCTL_MAX) { printk(KERN_NOTICE "vote_ioctl: > vote_IOC_MAXNR\n"); return -ENOTTY; } // // TURNED THIS OFF: If not root/sysadmin, go away // // if (! capable (CAP_SYS_ADMIN)) return -EPERM; // // The direction is a bitmask, // and VERIFY_WRITE catches R/W transfers. // `Type' is user-oriented, // while access_ok is kernel-oriented, // so the concept of "read" and "write" is reversed. // if (_IOC_DIR(cmd) & _IOC_READ) { err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); } else if (_IOC_DIR(cmd) & _IOC_WRITE) { err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); } if (err) { printk(KERN_NOTICE "vote_ioctl: access !ok\n"); return -EFAULT; } switch(cmd) { case VOTE_IOCTL_INIT: printk(KERN_NOTICE "VOTE_IOCTL_INIT\n"); command = 'g'; break; default: printk( KERN_NOTICE "%s: Not a known command: %x\n", __FUNCTION__, cmd ); return -EINVAL; } // switch(cmd) vote_urb = usb_alloc_urb(0, GFP_KERNEL); if (!vote_urb) { return -ENOMEM; } buf = usb_buffer_alloc( vote_dev->udev, 64, GFP_KERNEL, &vote_urb->transfer_dma ); if (!buf) { printk (KERN_NOTICE "%s: usb_buffer_alloc failed\n", __FUNCTION__); usb_buffer_free( vote_dev->udev, vote_urb->transfer_buffer_length, vote_urb->transfer_buffer, vote_urb->transfer_dma ); return -ENOMEM; } buf[0] = command; usb_fill_int_urb( vote_urb, vote_dev->udev, usb_sndintpipe(vote_dev->udev, vote_dev->intr_out_endpointAddr), buf, 64, (usb_complete_t)vote_write_intr_callback, vote_dev, 250 ); vote_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if ((rc = usb_submit_urb(vote_urb, GFP_KERNEL))) { err("%s - failed submitting write urb, error %d", __FUNCTION__, rc); } return 0; } // vote_ioctl()
// read // // wait until the teensy returns data // ssize_t vote_read (struct file *file, char __user *buf, size_t count, loff_t *pos) { struct usb_vote *vote_dev = file->private_data; int rc = 0; struct urb *vote_urb; // usb request int wqrc = 0; // return from wait queue int bytes_notcopied = 0; int copycount = 0; int actual_count; char *usbbuf; char vote_from_teensy; // single character vote from teensy printk(KERN_NOTICE "In %s\n", __FUNCTION__); if (!access_ok(VERIFY_WRITE, buf, count)) return -EINVAL; vote_urb = usb_alloc_urb(0, GFP_KERNEL); if (!vote_urb) return -ENOMEM; usbbuf = usb_buffer_alloc( vote_dev->udev, 64, GFP_KERNEL, &vote_urb->transfer_dma ); if (!usbbuf) { printk (KERN_NOTICE "%s: usb_buffer_alloc failed\n", __FUNCTION__); usb_buffer_free( vote_dev->udev, vote_urb->transfer_buffer_length, vote_urb->transfer_buffer, vote_urb->transfer_dma ); return -ENOMEM; } usb_fill_int_urb( vote_urb, vote_dev->udev, usb_rcvintpipe(vote_dev->udev, vote_dev->intr_in_endpointAddr), usbbuf, 64, (usb_complete_t) vote_read_intr_callback, vote_dev, 250 ); vote_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; // vote_dev->data_from_teensy = false; data_from_teensy = false; if ((rc = usb_submit_urb(vote_urb, GFP_KERNEL))) { err("%s - failed submitting write urb, error %d", __FUNCTION__, rc); } // // Wait until teensy returns data // We will be awoken by our callback function, // vote_read_intr_callback(). // printk(KERN_DEBUG "%s: process %i (%s) going to sleep\n", __FUNCTION__, current->pid, current->comm); wqrc = wait_event_interruptible( // vote_dev->wait4voter, // vote_dev->data_from_teensy == true wait4voter, data_from_teensy == true ); if (wqrc == -ERESTARTSYS) { // Got a signal usb_buffer_free( vote_urb->dev, vote_urb->transfer_buffer_length, vote_urb->transfer_buffer, vote_urb->transfer_dma ); printk(KERN_DEBUG "%s got signal while waiting: %i (%s):\n", __FUNCTION__, current->pid, current->comm); // What needs to be deallocated here??? kgb return -EINTR; } printk(KERN_DEBUG "%s awoken %i (%s):\n", __FUNCTION__, current->pid, current->comm); // the actual amount of data from the URB actual_count = vote_urb->actual_length; printk(KERN_NOTICE "%s: Actual Count in the URB = %d\n", __FUNCTION__, actual_count); // We are expecting exactly 1 byte from the teensy. if (actual_count == 1) { vote_from_teensy = ((char *) vote_urb->transfer_buffer)[0]; // Set the vote in vote_dev->votecast // to reflect the voter's choice. // This is for viewing in sysfs. vote_dev->votecast = vote_from_teensy; } // actual_count is 64 bytes -- not the amount of data sent from teensy // kgb: Since we know its just one byte vote_from_teensy = ((char *) vote_urb->transfer_buffer)[0]; vote_dev->votecast = vote_from_teensy; printk(KERN_NOTICE "%s: Vote from teensy. [%c]\n", __FUNCTION__, vote_dev->votecast); if(count <= actual_count) copycount = count; else copycount = actual_count; bytes_notcopied = copy_to_user( buf, (char *) vote_urb->transfer_buffer, copycount ); if (bytes_notcopied != 0) { printk(KERN_NOTICE "%s: copy_to_user failed. \n", __FUNCTION__); } printk(KERN_NOTICE "%s: after copy_to_user. bytes_not_copied=%d \n", __FUNCTION__, bytes_notcopied); printk(KERN_NOTICE "%s: after copy_to_user. %c\n", __FUNCTION__, ((char *) vote_urb->transfer_buffer)[0]); // dealloc the URB usb_buffer_free( vote_urb->dev, vote_urb->transfer_buffer_length, vote_urb->transfer_buffer, vote_urb->transfer_dma ); // return the number of bytes read return copycount; } // vote_read()
ssize_t vote_write ( struct file *file, const char __user *buf, size_t count, loff_t *pos) { unsigned long not_copied; // return from copy_to_user() struct urb *wrt_urb; // usb request: write char *tbuf; // usb transfer buffer int rc; struct usb_vote *vote_dev = file->private_data; printk(KERN_NOTICE "In %s\n", __FUNCTION__); if (!access_ok(VERIFY_READ, buf, count)) return -EINVAL; if (count > TMAX) { printk(KERN_NOTICE "In %s with count=%d > TMAX\n", __FUNCTION__, count); return -EINVAL; } // // Set up the urb // wrt_urb = usb_alloc_urb(0, GFP_KERNEL); if (!wrt_urb) return -ENOMEM; tbuf = usb_buffer_alloc( vote_dev->udev, 64, GFP_KERNEL, &wrt_urb->transfer_dma ); if (!tbuf) { printk (KERN_NOTICE "%s: usb_buffer_alloc failed\n", __FUNCTION__); usb_buffer_free( vote_dev->udev, wrt_urb->transfer_buffer_length, wrt_urb->transfer_buffer, wrt_urb->transfer_dma ); return -ENOMEM; } // Copy user data to URB transfer buffer not_copied = copy_from_user(tbuf, buf, count); // kernel user if (not_copied != 0) return -EPROTO; // really an internal error usb_fill_int_urb( wrt_urb, vote_dev->udev, usb_sndintpipe(vote_dev->udev, vote_dev->intr_out_endpointAddr), tbuf, 64, // TMAX or count kgb (usb_complete_t) vote_write_intr_callback, vote_dev, 250 ); wrt_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if ((rc = usb_submit_urb(wrt_urb, GFP_KERNEL))) { err("%s - failed submitting write urb, error %d", __FUNCTION__, rc); return rc; } // Success return count; } // vote_write()
static void xpad_deinit_output(struct usb_xpad *xpad) { usb_free_urb(xpad->irq_out); usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); }
/* static void ss801u_write_bulk_callback(struct urb *urb) { usb_ss801u *dev; dev = (usb_ss801u *)urb->context; // sync/async unlink faults aren't errors // if (urb->status) { if(!(urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) err("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); Egis_Reset_device(dev); spin_lock(&dev->err_lock); dev->errors = urb->status; spin_unlock(&dev->err_lock); } // free up our allocated buffer // usb_buffer_free(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); up(&dev->limit_sem); } */ static ssize_t ss801u_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) { printk(KERN_INFO "Patrick-> ss801u_write start\n"); printk(KERN_INFO "Patrick-> ss801u_write finish\n"); //*/ //--------------- CASE1 : return only -----------------------// //-----------------------------------------------------------// return -ENOSYS; // function not implement #if 0 /*---------------- CASE2 : bulk write -----------------------*/ /*-----------------------------------------------------------*/ usb_ss801u *dev; int retval = 0; struct urb *urb = NULL; char *buf = NULL; size_t writesize = min(count, (size_t)MAX_TRANSFER); dev = (usb_ss801u *)file->private_data; if (count == 0) goto exit; if (down_interruptible(&dev->limit_sem)) { retval = -ERESTARTSYS; goto exit; } spin_lock_irq(&dev->err_lock); retval = dev->errors; if (retval < 0) { dev->errors = 0; 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; } /*----- To NOT go to suspend -----*/ usb_autopm_get_interface(dev->interface); /*----- initialize the urb properly -----*/ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), buf, writesize, ss801u_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); /*----- Auto suspend -----*/ usb_autopm_put_interface(dev->interface); mutex_unlock(&dev->io_mutex); /*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/ if (retval) { Egis_Reset_device(dev); err("%s - failed submitting write urb, error %d", retval, 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; #endif }
static int usb_mouse_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; struct usb_mouse *mouse; struct input_dev *input_dev; int pipe, maxp; int error = -ENOMEM; interface = intf->cur_altsetting; if (interface->desc.bNumEndpoints != 1) return -ENODEV; endpoint = &interface->endpoint[0].desc; if (!usb_endpoint_is_int_in(endpoint)) return -ENODEV; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL); input_dev = input_allocate_device(); if (!mouse || !input_dev) goto fail1; mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma); if (!mouse->data) goto fail1; mouse->irq = usb_alloc_urb(0, GFP_KERNEL); if (!mouse->irq) goto fail2; mouse->usbdev = dev; mouse->dev = input_dev; if (dev->manufacturer) strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name)); if (dev->product) { if (dev->manufacturer) strlcat(mouse->name, " ", sizeof(mouse->name)); strlcat(mouse->name, dev->product, sizeof(mouse->name)); } if (!strlen(mouse->name)) snprintf(mouse->name, sizeof(mouse->name), "USB HIDBP Mouse %04x:%04x", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); usb_make_path(dev, mouse->phys, sizeof(mouse->phys)); strlcat(mouse->phys, "/input0", sizeof(mouse->phys)); input_dev->name = mouse->name; input_dev->phys = mouse->phys; usb_to_input_id(dev, &input_dev->id); input_dev->dev.parent = &intf->dev; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); input_set_drvdata(input_dev, mouse); input_dev->open = usb_mouse_open; input_dev->close = usb_mouse_close; usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data, (maxp > 8 ? 8 : maxp), usb_mouse_irq, mouse, endpoint->bInterval); mouse->irq->transfer_dma = mouse->data_dma; mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; error = input_register_device(mouse->dev); if (error) goto fail3; usb_set_intfdata(intf, mouse); return 0; fail3: usb_free_urb(mouse->irq); fail2: usb_buffer_free(dev, 8, mouse->data, mouse->data_dma); fail1: input_free_device(input_dev); kfree(mouse); return error; }
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; struct wacom_features *features; struct input_dev *input_dev; int error; if (!id->driver_info) return -EINVAL; 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) { error = -ENOMEM; goto fail1; } wacom_wac->features = *((struct wacom_features *)id->driver_info); features = &wacom_wac->features; if (features->pktlen > WACOM_PKGLEN_MAX) { error = -EINVAL; goto fail1; } wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, GFP_KERNEL, &wacom->data_dma); if (!wacom_wac->data) { error = -ENOMEM; goto fail1; } wacom->irq = usb_alloc_urb(0, GFP_KERNEL); if (!wacom->irq) { error = -ENOMEM; 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)); 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; /* Retrieve the physical and logical size for OEM devices */ error = wacom_retrieve_hid_descriptor(intf, features); if (error) goto fail2; strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); if (features->type == TABLETPC || features->type == TABLETPC2FG) { /* Append the device type to the name */ strlcat(wacom_wac->name, features->device_type == BTN_TOOL_PEN ? " Pen" : " Finger", sizeof(wacom_wac->name)); } input_dev->name = wacom_wac->name; wacom->wacom_wac = wacom_wac; input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); 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); 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, 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; /* Note that if query fails it is not a hard failure */ wacom_query_tablet_data(intf, features); usb_set_intfdata(intf, wacom); return 0; fail3: usb_free_urb(wacom->irq); fail2: usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma); fail1: input_free_device(input_dev); kfree(wacom); kfree(wacom_wac); return error; }
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 wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; struct input_dev *input_dev; int error = -ENOMEM; char rep_data[2], limit = 0; 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; usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); wacom_wac->features = get_wacom_feature(id); BUG_ON(wacom_wac->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; 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, wacom_wac->features->x_max, 4, 0); input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); wacom_init_input_dev(input_dev, wacom_wac); endpoint = &intf->cur_altsetting->endpoint[0].desc; 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. Repeat until it succeeds */ do { rep_data[0] = 2; rep_data[1] = 2; usb_set_report(intf, 3, 2, rep_data, 2); usb_get_report(intf, 3, 2, rep_data, 2); } while (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 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; }
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; 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->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: err("Ignoring extra header, type %d, length %d", 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); 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); spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); 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; } } acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->writeurb) { dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n"); goto alloc_fail7; } 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; usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), NULL, acm->writesize, acm_write_bulk, acm); acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; 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: usb_free_urb(acm->writeurb); alloc_fail7: for (i = 0; i < num_rx_buf; i++) usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); 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 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; }
/* * 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; }
/*this is transmit call-back(BULK OUT)*/ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { PUSB_TCB pTcb= (PUSB_TCB)urb->context; PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter; CONTROL_MESSAGE *pControlMsg = (CONTROL_MESSAGE *)urb->transfer_buffer; PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ; BOOLEAN bpowerDownMsg = FALSE ; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); #if 0 struct timeval tv; UINT time_ms = 0; #endif if(urb->status != STATUS_SUCCESS) { if(urb->status == -EPIPE) { psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status); } } pTcb->bUsed = FALSE; atomic_dec(&psIntfAdapter->uNumTcbUsed); if(TRUE == psAdapter->bPreparingForLowPowerMode) { #if 0 do_gettimeofday(&tv); time_ms = tv.tv_sec *1000 + tv.tv_usec/1000; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms); #endif if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) { bpowerDownMsg = TRUE ; //This covers the bus err while Idle Request msg sent down. if(urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem"); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } if(psAdapter->bDoSuspend == FALSE) { psAdapter->IdleMode = TRUE; //since going in Idle mode completed hence making this var false; psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); } } else if((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && (pControlMsg->szData[0] == LINK_UP_ACK) && (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) { //This covers the bus err while shutdown Request msg sent down. if(urb->status != STATUS_SUCCESS) { psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem"); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } bpowerDownMsg = TRUE ; if(psAdapter->bDoSuspend == FALSE) { psAdapter->bShutStatus = TRUE; //since going in shutdown mode completed hence making this var false; psAdapter->bPreparingForLowPowerMode = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State..."); //Signalling the cntrl pkt path in Ioctl wake_up(&psAdapter->lowpower_mode_wait_queue); } } if(psAdapter->bDoSuspend && bpowerDownMsg) { //issuing bus suspend request BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Issuing the Bus suspend request to USB stack"); psIntfAdapter->bPreparingForBusSuspend = TRUE; schedule_work(&psIntfAdapter->usbSuspendWork); } } err_exit : #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); #else usb_buffer_free(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); #endif }
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 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; }
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; }
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 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; }
/* 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; }
void diodev_rx_work(struct work_struct *work) { struct usb_dio_workitem *workitem; struct usb_dio_dev *dev; FUNC_HI(); workitem = (struct usb_dio_workitem*)work; dev = workitem->dev; DPRINTK(KERN_ALERT "=== diodev_rx_work() hello\n"); if (!workitem->arg) { DPRINTK(KERN_ALERT "=== diodev_rx_work() NULL arg!?\n"); } else { struct urb *urb; char *buf; int i; int p; char t[128]; DPRINTK(KERN_ALERT "=== diodev_rx_work() non-null arg!\n"); urb = workitem->arg; DPRINTK(KERN_ALERT "=== diodev_rx_work() %d\n",urb->actual_length); buf = (char *)urb->transfer_buffer; for (i = 0; i < 127 && i < urb->actual_length; i++) { t[i] = buf[i]; if (t[i] == '\r') t[i] = '-'; } t[i] = '\0'; DPRINTK(KERN_ALERT "### Recieved [%s] ###\n", t); DPRINTK(KERN_ALERT "%%%%%% %d - %d\n",dev->buffer_head,dev->buffer_tail); /* if we have a valid return value */ DDPRINTK("R"); if (urb->actual_length == 6 && buf[0] == '!' && buf[1] == '0' && buf[2] == '0' && buf[5] == '\r') { char t[3]; unsigned char c; t[0] = buf[3]; t[1] = buf[4]; t[2] = '\0'; sscanf(t,"%02X",(unsigned int *)&c); DPRINTK(KERN_ALERT "### Recieved 0x%02X ###\n", c); if (down_interruptible(&dev->buffer_sem)) { workitem->arg = NULL; diodev_rx_setup(dev); FUNC_ERR(); return; } DPRINTK(KERN_ALERT "=== diodev_rx_work() success down(buffer_sem)...\n"); if (!((dev->buffer_tail == USB_DIO_DEV_BUFFERSIZE && dev->buffer_head == 0) || (dev->buffer_tail == dev->buffer_head - 1))) { dev->buffer[dev->buffer_tail] = c; dev->buffer_tail++; if (dev->buffer_tail >= USB_DIO_DEV_BUFFERSIZE) dev->buffer_tail = 0; DPRINTK(KERN_ALERT "### Added to buffer...\n"); /* if the lock fails... then it is already locked, so unlock it! */ /* if the lock succeeds... then it is not already locked, but is now... so unlock it! */ p = down_trylock(&dev->buffer_empty_sem); DPRINTK(KERN_ALERT "### Kicking sem...\n"); up(&dev->buffer_empty_sem); DPRINTK(KERN_ALERT "%%%%%% %d - %d\n",dev->buffer_head,dev->buffer_tail); } else { DPRINTK(KERN_ALERT "### Buffer full...\n"); } DDPRINTK("-0x%02X", c); up(&dev->buffer_sem); } else { DDPRINTK("-X"); } DDPRINTK("\n"); DPRINTK(KERN_ALERT "%%%%%% %d - %d\n",dev->buffer_head,dev->buffer_tail); usb_buffer_free(dev->dev, dev->bulk_in_size, urb->transfer_buffer, urb->transfer_dma); usb_free_urb(urb); } workitem->arg = NULL; diodev_rx_setup(dev); DPRINTK(KERN_ALERT "=== diodev_rx_work() returning\n"); FUNC_BYE(); }
/* * IOCTL */ int lighty_ioctl(struct inode * i_node, struct file * file, unsigned int cmd, unsigned long arg) { int err = 0; int retval = 0; struct urb *usb_led; char command; // a, b, c ,d, e, f char *buf; struct usb_lighty *dev = file->private_data; /* * extract the type and number bitfields, and don't decode * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() */ if (_IOC_TYPE(cmd) != LIGHTY_IOCTL_MAGIC) { printk(KERN_NOTICE "lighty_ioctl: !lighty_IOC_MAGIC\n"); return -ENOTTY; } if (_IOC_NR(cmd) > LIGHTY_IOCTL_MAX) { printk(KERN_NOTICE "lighty_ioctl: > lighty_IOC_MAXNR\n"); return -ENOTTY; } /* * If not root/sysadmin, go away */ if (! capable (CAP_SYS_ADMIN)) return -EPERM; /* * the direction is a bitmask, and VERIFY_WRITE catches R/W * transfers. `Type' is user-oriented, while * access_ok is kernel-oriented, so the concept of "read" and * "write" is reversed */ if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); else if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); if (err) { printk(KERN_NOTICE "lighty_ioctl: access !ok\n"); return -EFAULT; } switch(cmd) { case LIGHTY_IOCTL_1RED: printk(KERN_NOTICE "LIGHTY_IOCTL_1RED\n"); command = 'a'; break; case LIGHTY_IOCTL_1GREEN: printk(KERN_NOTICE "LIGHTY_IOCTL_1GREEN\n"); command = 'b'; break; case LIGHTY_IOCTL_1BLUE: printk(KERN_NOTICE "LIGHTY_IOCTL_1BLUE\n"); command = 'c'; break; case LIGHTY_IOCTL_2RED: printk(KERN_NOTICE "LIGHTY_IOCTL_2RED\n"); command = 'd'; break; case LIGHTY_IOCTL_2GREEN: printk(KERN_NOTICE "LIGHTY_IOCTL_2GREEN\n"); command = 'e'; break; case LIGHTY_IOCTL_2BLUE: printk(KERN_NOTICE "LIGHTY_IOCTL_2BLUE\n"); command = 'f'; break; default: printk(KERN_NOTICE "Not a known command %x\n", cmd); return -ENOMEM; } usb_led = usb_alloc_urb(0, GFP_KERNEL); if (!usb_led) { return -ENOMEM; } buf = usb_buffer_alloc(dev->udev, 64, GFP_KERNEL, &usb_led->transfer_dma); if (!buf) { printk (KERN_NOTICE "usb_buffer_alloc failed\n"); usb_buffer_free(dev->udev, usb_led->transfer_buffer_length, usb_led->transfer_buffer, usb_led->transfer_dma); return -ENOMEM; } buf[0] = command; // a, b, c, d, e or f usb_fill_int_urb(usb_led, dev->udev, usb_sndintpipe(dev->udev, dev->intr_out_endpointAddr), buf, 64, (usb_complete_t)lighty_write_intr_callback, dev, 250); usb_led->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if( (retval = usb_submit_urb(usb_led, GFP_KERNEL)) ) { err("%s - failed submitting write urb, error %d", __FUNCTION__, retval); } return 0; }
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_KERNEL, &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; xpad->xtype = xpad_device[i].xtype; if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) xpad->dpad_mapping = !dpad_to_buttons; if (xpad->xtype == XTYPE_UNKNOWN) { if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) xpad->xtype = XTYPE_XBOX360W; else xpad->xtype = XTYPE_XBOX360; } else xpad->xtype = XTYPE_XBOX; } 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_MASK(EV_KEY) | BIT_MASK(EV_ABS); /* set up buttons */ for (i = 0; xpad_common_btn[i] >= 0; i++) set_bit(xpad_common_btn[i], input_dev->keybit); if ((xpad->xtype == XTYPE_XBOX360) || (xpad->xtype == XTYPE_XBOX360W)) for (i = 0; xpad360_btn[i] >= 0; i++) set_bit(xpad360_btn[i], input_dev->keybit); else 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]); error = xpad_init_output(intf, xpad); if (error) goto fail2; error = xpad_init_ff(xpad); if (error) goto fail3; error = xpad_led_probe(xpad); if (error) goto fail3; 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 fail4; usb_set_intfdata(intf, xpad); /* * Submit the int URB immediatly rather than waiting for open * because we get status messages from the device whether * or not any controllers are attached. In fact, it's * exactly the message that a controller has arrived that * we're waiting for. */ if (xpad->xtype == XTYPE_XBOX360W) { xpad->irq_in->dev = xpad->udev; error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); if (error) goto fail4; /* * Setup the message to set the LEDs on the * controller when it shows up */ xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); if(!xpad->bulk_out) goto fail5; xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); if(!xpad->bdata) goto fail6; xpad->bdata[2] = 0x08; switch (intf->cur_altsetting->desc.bInterfaceNumber) { case 0: xpad->bdata[3] = 0x42; break; case 2: xpad->bdata[3] = 0x43; break; case 4: xpad->bdata[3] = 0x44; break; case 6: xpad->bdata[3] = 0x45; } ep_irq_in = &intf->cur_altsetting->endpoint[1].desc; usb_fill_bulk_urb(xpad->bulk_out, udev, usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); } return 0; fail6: usb_free_urb(xpad->bulk_out); fail5: usb_kill_urb(xpad->irq_in); fail4: usb_free_urb(xpad->irq_in); fail3: xpad_deinit_output(xpad); 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 usblp_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev (intf); struct usblp *usblp = NULL; int protocol; int retval; /* Malloc and start initializing usblp structure so we can use it * directly. */ if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) { err("out of memory for usblp"); goto abort; } usblp->dev = dev; init_MUTEX (&usblp->sem); init_waitqueue_head(&usblp->wait); usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; usblp->intf = intf; usblp->writeurb = usb_alloc_urb(0, GFP_KERNEL); if (!usblp->writeurb) { err("out of memory"); goto abort; } usblp->readurb = usb_alloc_urb(0, GFP_KERNEL); if (!usblp->readurb) { err("out of memory"); goto abort; } /* Malloc device ID string buffer to the largest expected length, * since we can re-query it on an ioctl and a dynamic string * could change in length. */ if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) { err("out of memory for device_id_string"); goto abort; } usblp->writebuf = usblp->readbuf = NULL; usblp->writeurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; usblp->readurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; /* Malloc write & read buffers. We somewhat wastefully * malloc both regardless of bidirectionality, because the * alternate setting can be changed later via an ioctl. */ if (!(usblp->writebuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE, GFP_KERNEL, &usblp->writeurb->transfer_dma))) { err("out of memory for write buf"); goto abort; } if (!(usblp->readbuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE, GFP_KERNEL, &usblp->readurb->transfer_dma))) { err("out of memory for read buf"); goto abort; } /* Allocate buffer for printer status */ usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL); if (!usblp->statusbuf) { err("out of memory for statusbuf"); goto abort; } /* Lookup quirks for this printer. */ usblp->quirks = usblp_quirks( le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); /* Analyze and pick initial alternate settings and endpoints. */ protocol = usblp_select_alts(usblp); if (protocol < 0) { dbg("incompatible printer-class device 0x%4.4X/0x%4.4X", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); goto abort; } /* Setup the selected alternate setting and endpoints. */ if (usblp_set_protocol(usblp, protocol) < 0) goto abort; /* Retrieve and store the device ID string. */ usblp_cache_device_id_string(usblp); device_create_file(&intf->dev, &dev_attr_ieee1284_id); #ifdef DEBUG usblp_check_status(usblp, 0); #endif usb_set_intfdata (intf, usblp); usblp->present = 1; retval = usb_register_dev(intf, &usblp_class); if (retval) { err("Not able to get a minor for this device."); goto abort_intfdata; } usblp->minor = intf->minor; info("usblp%d: USB %sdirectional printer dev %d " "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, usblp->ifnum, usblp->protocol[usblp->current_protocol].alt_setting, usblp->current_protocol, le16_to_cpu(usblp->dev->descriptor.idVendor), le16_to_cpu(usblp->dev->descriptor.idProduct)); return 0; abort_intfdata: usb_set_intfdata (intf, NULL); device_remove_file(&intf->dev, &dev_attr_ieee1284_id); abort: if (usblp) { if (usblp->writebuf) usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, usblp->writebuf, usblp->writeurb->transfer_dma); if (usblp->readbuf) usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, usblp->readbuf, usblp->writeurb->transfer_dma); kfree(usblp->statusbuf); kfree(usblp->device_id_string); usb_free_urb(usblp->writeurb); usb_free_urb(usblp->readurb); kfree(usblp); } return -EIO; }