static int zd1201_fw_upload(struct usb_device *dev, int apfw) { const struct firmware *fw_entry; const char *data; unsigned long len; int err; unsigned char ret; char *buf; char *fwfile; if (apfw) fwfile = "zd1201-ap.fw"; else fwfile = "zd1201.fw"; err = request_firmware(&fw_entry, fwfile, &dev->dev); if (err) { dev_err(&dev->dev, "Failed to load %s firmware file!\n", fwfile); dev_err(&dev->dev, "Make sure the hotplug firmware loader is installed.\n"); dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info.\n"); return err; } data = fw_entry->data; len = fw_entry->size; buf = kmalloc(1024, GFP_ATOMIC); if (!buf) { err = -ENOMEM; goto exit; } while (len > 0) { int translen = (len > 1024) ? 1024 : len; memcpy(buf, data, translen); err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, USB_DIR_OUT | 0x40, 0, 0, buf, translen, ZD1201_FW_TIMEOUT); if (err < 0) goto exit; len -= translen; data += translen; } err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x2, USB_DIR_OUT | 0x40, 0, 0, NULL, 0, ZD1201_FW_TIMEOUT); if (err < 0) goto exit; err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4, USB_DIR_IN | 0x40, 0, 0, buf, sizeof(ret), ZD1201_FW_TIMEOUT); if (err < 0) goto exit; memcpy(&ret, buf, sizeof(ret)); if (ret & 0x80) { err = -EIO; goto exit; } err = 0; exit: kfree(buf); release_firmware(fw_entry); return err; }
/* FIXME: split and cleanup */ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, struct wusb_ckhdid *ck) { int result = -ENOMEM; struct usb_device *usb_dev = wusb_dev->usb_dev; struct device *dev = &usb_dev->dev; u32 tkid; __le32 tkid_le; struct usb_handshake *hs; struct aes_ccm_nonce ccm_n; u8 mic[8]; struct wusb_keydvt_in keydvt_in; struct wusb_keydvt_out keydvt_out; hs = kcalloc(3, sizeof(hs[0]), GFP_KERNEL); if (hs == NULL) { dev_err(dev, "can't allocate handshake data\n"); goto error_kzalloc; } /* We need to turn encryption before beginning the 4way * hshake (WUSB1.0[.3.2.2]) */ result = wusb_dev_set_encryption(usb_dev, 1); if (result < 0) goto error_dev_set_encryption; tkid = wusbhc_next_tkid(wusbhc, wusb_dev); tkid_le = cpu_to_le32(tkid); hs[0].bMessageNumber = 1; hs[0].bStatus = 0; memcpy(hs[0].tTKID, &tkid_le, sizeof(hs[0].tTKID)); hs[0].bReserved = 0; memcpy(hs[0].CDID, &wusb_dev->cdid, sizeof(hs[0].CDID)); get_random_bytes(&hs[0].nonce, sizeof(hs[0].nonce)); memset(hs[0].MIC, 0, sizeof(hs[0].MIC)); /* Per WUSB1.0[T7-22] */ result = usb_control_msg( usb_dev, usb_sndctrlpipe(usb_dev, 0), USB_REQ_SET_HANDSHAKE, USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, 1, 0, &hs[0], sizeof(hs[0]), 1000 /* FIXME: arbitrary */); if (result < 0) { dev_err(dev, "Handshake1: request failed: %d\n", result); goto error_hs1; } /* Handshake 2, from the device -- need to verify fields */ result = usb_control_msg( usb_dev, usb_rcvctrlpipe(usb_dev, 0), USB_REQ_GET_HANDSHAKE, USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE, 2, 0, &hs[1], sizeof(hs[1]), 1000 /* FIXME: arbitrary */); if (result < 0) { dev_err(dev, "Handshake2: request failed: %d\n", result); goto error_hs2; } result = -EINVAL; if (hs[1].bMessageNumber != 2) { dev_err(dev, "Handshake2 failed: bad message number %u\n", hs[1].bMessageNumber); goto error_hs2; } if (hs[1].bStatus != 0) { dev_err(dev, "Handshake2 failed: bad status %u\n", hs[1].bStatus); goto error_hs2; } if (memcmp(hs[0].tTKID, hs[1].tTKID, sizeof(hs[0].tTKID))) { dev_err(dev, "Handshake2 failed: TKID mismatch " "(#1 0x%02x%02x%02x vs #2 0x%02x%02x%02x)\n", hs[0].tTKID[0], hs[0].tTKID[1], hs[0].tTKID[2], hs[1].tTKID[0], hs[1].tTKID[1], hs[1].tTKID[2]); goto error_hs2; } if (memcmp(hs[0].CDID, hs[1].CDID, sizeof(hs[0].CDID))) { dev_err(dev, "Handshake2 failed: CDID mismatch\n"); goto error_hs2; } /* Setup the CCM nonce */ memset(&ccm_n.sfn, 0, sizeof(ccm_n.sfn)); /* Per WUSB1.0[6.5.2] */ memcpy(ccm_n.tkid, &tkid_le, sizeof(ccm_n.tkid)); ccm_n.src_addr = wusbhc->uwb_rc->uwb_dev.dev_addr; ccm_n.dest_addr.data[0] = wusb_dev->addr; ccm_n.dest_addr.data[1] = 0; /* Derive the KCK and PTK from CK, the CCM, H and D nonces */ memcpy(keydvt_in.hnonce, hs[0].nonce, sizeof(keydvt_in.hnonce)); memcpy(keydvt_in.dnonce, hs[1].nonce, sizeof(keydvt_in.dnonce)); result = wusb_key_derive(&keydvt_out, ck->data, &ccm_n, &keydvt_in); if (result < 0) { dev_err(dev, "Handshake2 failed: cannot derive keys: %d\n", result); goto error_hs2; } /* Compute MIC and verify it */ result = wusb_oob_mic(mic, keydvt_out.kck, &ccm_n, &hs[1]); if (result < 0) { dev_err(dev, "Handshake2 failed: cannot compute MIC: %d\n", result); goto error_hs2; } if (memcmp(hs[1].MIC, mic, sizeof(hs[1].MIC))) { dev_err(dev, "Handshake2 failed: MIC mismatch\n"); goto error_hs2; } /* Send Handshake3 */ hs[2].bMessageNumber = 3; hs[2].bStatus = 0; memcpy(hs[2].tTKID, &tkid_le, sizeof(hs[2].tTKID)); hs[2].bReserved = 0; memcpy(hs[2].CDID, &wusb_dev->cdid, sizeof(hs[2].CDID)); memcpy(hs[2].nonce, hs[0].nonce, sizeof(hs[2].nonce)); result = wusb_oob_mic(hs[2].MIC, keydvt_out.kck, &ccm_n, &hs[2]); if (result < 0) { dev_err(dev, "Handshake3 failed: cannot compute MIC: %d\n", result); goto error_hs2; } result = usb_control_msg( usb_dev, usb_sndctrlpipe(usb_dev, 0), USB_REQ_SET_HANDSHAKE, USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, 3, 0, &hs[2], sizeof(hs[2]), 1000 /* FIXME: arbitrary */); if (result < 0) { dev_err(dev, "Handshake3: request failed: %d\n", result); goto error_hs3; } result = wusbhc->set_ptk(wusbhc, wusb_dev->port_idx, tkid, keydvt_out.ptk, sizeof(keydvt_out.ptk)); if (result < 0) goto error_wusbhc_set_ptk; result = wusb_dev_set_gtk(wusbhc, wusb_dev); if (result < 0) { dev_err(dev, "Set GTK for device: request failed: %d\n", result); goto error_wusbhc_set_gtk; } /* Update the device's address from unauth to auth */ if (usb_dev->authenticated == 0) { result = wusb_dev_update_address(wusbhc, wusb_dev); if (result < 0) goto error_dev_update_address; } result = 0; dev_info(dev, "device authenticated\n"); error_dev_update_address: error_wusbhc_set_gtk: error_wusbhc_set_ptk: error_hs3: error_hs2: error_hs1: memset(hs, 0, 3*sizeof(hs[0])); memset(&keydvt_out, 0, sizeof(keydvt_out)); memset(&keydvt_in, 0, sizeof(keydvt_in)); memset(&ccm_n, 0, sizeof(ccm_n)); memset(mic, 0, sizeof(mic)); if (result < 0) wusb_dev_set_encryption(usb_dev, 0); error_dev_set_encryption: kfree(hs); error_kzalloc: return result; }
/* * Function kingsun_net_open (dev) * * Network device is taken up. Usually this is done by "ifconfig irda0 up" */ static int ks959_net_open(struct net_device *netdev) { struct ks959_cb *kingsun = netdev_priv(netdev); int err = -ENOMEM; char hwname[16]; /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */ kingsun->receiving = 0; /* Initialize for SIR to copy data directly into skb. */ kingsun->rx_unwrap_buff.in_frame = FALSE; kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU; kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU); if (!kingsun->rx_unwrap_buff.skb) goto free_mem; skb_reserve(kingsun->rx_unwrap_buff.skb, 1); kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data; kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!kingsun->rx_urb) goto free_mem; kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!kingsun->tx_urb) goto free_mem; kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL); if (!kingsun->speed_urb) goto free_mem; /* Initialize speed for dongle */ kingsun->new_speed = 9600; err = ks959_change_speed(kingsun, 9600); if (err < 0) goto free_mem; /* * Now that everything should be initialized properly, * Open new IrLAP layer instance to take care of us... */ sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); if (!kingsun->irlap) { err = -ENOMEM; dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); goto free_mem; } /* Start reception. Setup request already pre-filled in ks959_probe */ usb_fill_control_urb(kingsun->rx_urb, kingsun->usbdev, usb_rcvctrlpipe(kingsun->usbdev, 0), (unsigned char *)kingsun->rx_setuprequest, kingsun->rx_buf, KINGSUN_RCV_FIFO_SIZE, ks959_rcv_irq, kingsun); kingsun->rx_urb->status = 0; err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); if (err) { dev_err(&kingsun->usbdev->dev, "first urb-submit failed: %d\n", err); goto close_irlap; } netif_start_queue(netdev); /* Situation at this point: - all work buffers allocated - urbs allocated and ready to fill - max rx packet known (in max_rx) - unwrap state machine initialized, in state outside of any frame - receive request in progress - IrLAP layer started, about to hand over packets to send */ return 0; close_irlap: irlap_close(kingsun->irlap); free_mem: usb_free_urb(kingsun->speed_urb); kingsun->speed_urb = NULL; usb_free_urb(kingsun->tx_urb); kingsun->tx_urb = NULL; usb_free_urb(kingsun->rx_urb); kingsun->rx_urb = NULL; if (kingsun->rx_unwrap_buff.skb) { kfree_skb(kingsun->rx_unwrap_buff.skb); kingsun->rx_unwrap_buff.skb = NULL; kingsun->rx_unwrap_buff.head = NULL; } return err; }
/* * Called when a process tries to open the device file, like * "cat /dev/usbtherm0". */ static int device_open(struct inode *inode, struct file *filp) { int err = 0; int minor = 0; struct usb_interface *interface = NULL; struct usbtherm *dev = NULL; char data[8]; char *urb_transfer_buffer; urb_transfer_buffer = kzalloc(sizeof(data), GFP_KERNEL); minor = iminor(inode); interface = usb_find_interface(&usbtherm_driver, minor); if (! interface) { err = -ENODEV; printk(KERN_WARNING "usbtherm: Could not find USB interface!\n"); goto error; } dev = usb_get_intfdata(interface); if (! dev) { err = -ENODEV; printk(KERN_WARNING "usbtherm: Could not get USB device!\n"); goto error; } /* * If dev is needed in for example device_read. */ /* filp->private_data = dev; */ /* * Send a custom "vendor" type status request to read * the temperature value from the device. */ err = usb_control_msg(dev->usbdev, usb_rcvctrlpipe(dev->usbdev, USB_DIR_OUT), CUSTOM_REQ_TEMP, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, urb_transfer_buffer, sizeof(urb_transfer_buffer), 1000); strlcpy(data, urb_transfer_buffer, sizeof(data)); kfree(urb_transfer_buffer); if (err < 0) { err = -EIO; goto error; } snprintf(message, MSG_LEN, "%s\n", data); /* printk(KERN_DEBUG "usbtherm: Device was opened"); */ return SUCCESS; error: return err; }
static void wdm_int_callback(struct urb *urb) { int rv = 0; int status = urb->status; struct wdm_device *desc; struct usb_ctrlrequest *req; struct usb_cdc_notification *dr; desc = urb->context; req = desc->irq; dr = (struct usb_cdc_notification *)desc->sbuf; if (status) { switch (status) { case -ESHUTDOWN: case -ENOENT: case -ECONNRESET: return; /* unplug */ case -EPIPE: set_bit(WDM_INT_STALL, &desc->flags); dev_err(&desc->intf->dev, "Stall on int endpoint\n"); goto sw; /* halt is cleared in work */ default: dev_err(&desc->intf->dev, "nonzero urb status received: %d\n", status); break; } } if (urb->actual_length < sizeof(struct usb_cdc_notification)) { dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n", urb->actual_length); goto exit; } switch (dr->bNotificationType) { case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: dev_dbg(&desc->intf->dev, "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d", dr->wIndex, dr->wLength); break; case USB_CDC_NOTIFY_NETWORK_CONNECTION: dev_dbg(&desc->intf->dev, "NOTIFY_NETWORK_CONNECTION %s network", dr->wValue ? "connected to" : "disconnected from"); goto exit; default: clear_bit(WDM_POLL_RUNNING, &desc->flags); dev_err(&desc->intf->dev, "unknown notification %d received: index %d len %d\n", dr->bNotificationType, dr->wIndex, dr->wLength); goto exit; } req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; req->wValue = 0; req->wIndex = desc->inum; req->wLength = cpu_to_le16(desc->wMaxCommand); usb_fill_control_urb( desc->response, interface_to_usbdev(desc->intf), /* using common endpoint 0 */ usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), (unsigned char *)req, desc->inbuf, desc->wMaxCommand, wdm_in_callback, desc ); desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); set_bit(WDM_RESPONDING, &desc->flags); if (!test_bit(WDM_DISCONNECTING, &desc->flags) && !test_bit(WDM_SUSPENDING, &desc->flags)) { rv = usb_submit_urb(desc->response, GFP_ATOMIC); dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", __func__, rv); } spin_unlock(&desc->iuspin); if (rv < 0) { clear_bit(WDM_RESPONDING, &desc->flags); if (rv == -EPERM) return; if (rv == -ENOMEM) { sw: rv = schedule_work(&desc->rxwork); if (rv) dev_err(&desc->intf->dev, "Cannot schedule work\n"); } } exit: rv = usb_submit_urb(urb, GFP_ATOMIC); if (rv) dev_err(&desc->intf->dev, "%s - usb_submit_urb failed with result %d\n", __func__, rv); }
static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) { struct usb_serial *serial; struct qt2_port_private *port_priv; u8 *data; u16 device_port; int status; unsigned long flags; device_port = port->port_number; serial = port->serial; port_priv = usb_get_serial_port_data(port); /* set the port to RS232 mode */ status = qt2_control_msg(serial->dev, QT2_GET_SET_QMCR, QT2_QMCR_RS232, device_port); if (status < 0) { dev_err(&port->dev, "%s failed to set RS232 mode for port %i error %i\n", __func__, device_port, status); return status; } data = kzalloc(2, GFP_KERNEL); if (!data) return -ENOMEM; /* open the port */ status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), QT_OPEN_CLOSE_CHANNEL, 0xc0, 0, device_port, data, 2, QT2_USB_TIMEOUT); if (status < 0) { dev_err(&port->dev, "%s - open port failed %i\n", __func__, status); kfree(data); return status; } spin_lock_irqsave(&port_priv->lock, flags); port_priv->shadowLSR = data[0]; port_priv->shadowMSR = data[1]; spin_unlock_irqrestore(&port_priv->lock, flags); kfree(data); /* set to default speed and 8bit word size */ status = qt2_set_port_config(serial->dev, device_port, DEFAULT_BAUD_RATE, UART_LCR_WLEN8); if (status < 0) { dev_err(&port->dev, "%s - initial setup failed (%i)\n", __func__, device_port); return status; } port_priv->device_port = (u8) device_port; if (tty) qt2_set_termios(tty, port, &tty->termios); return 0; }
static void notification_available_cb(struct urb *urb) { int status; struct usb_cdc_notification *ctrl; struct usb_device *udev; struct rmnet_ctrl_dev *dev = urb->context; udev = interface_to_usbdev(dev->intf); switch (urb->status) { case 0: /*success*/ break; /*do not resubmit*/ case -ESHUTDOWN: case -ENOENT: case -ECONNRESET: case -EPROTO: return; case -EPIPE: pr_err_ratelimited("%s: Stall on int endpoint\n", __func__); /* TBD : halt to be cleared in work */ return; /*resubmit*/ case -EOVERFLOW: pr_err_ratelimited("%s: Babble error happened\n", __func__); default: pr_debug_ratelimited("%s: Non zero urb status = %d\n", __func__, urb->status); goto resubmit_int_urb; } ctrl = urb->transfer_buffer; switch (ctrl->bNotificationType) { case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: dev->resp_avail_cnt++; usb_fill_control_urb(dev->rcvurb, udev, usb_rcvctrlpipe(udev, 0), (unsigned char *)dev->in_ctlreq, dev->rcvbuf, DEFAULT_READ_URB_LENGTH, resp_avail_cb, dev); status = usb_submit_urb(dev->rcvurb, GFP_ATOMIC); if (status) { dev_err(dev->devicep, "%s: Error submitting Read URB %d\n", __func__, status); goto resubmit_int_urb; } usb_mark_last_busy(udev); if (!dev->resp_available) { dev->resp_available = true; wake_up(&dev->open_wait_queue); } return; default: dev_err(dev->devicep, "%s:Command not implemented\n", __func__); } resubmit_int_urb: status = usb_submit_urb(urb, GFP_ATOMIC); if (status) dev_err(dev->devicep, "%s: Error re-submitting Int URB %d\n", __func__, status); return; }
static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req) { int ret; unsigned int pipe; u8 request; u8 requesttype; u16 value; u16 index; u8 *buf; request = req->cmd; value = req->value; index = req->index; switch (req->cmd) { case I2C_READ: case DEMOD_READ: case REG_READ: requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); break; case I2C_WRITE: case DEMOD_WRITE: case REG_WRITE: requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); break; default: err("unknown command:%02x", req->cmd); ret = -EPERM; goto error; } buf = kmalloc(req->data_len, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto error; } if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) { /* write */ memcpy(buf, req->data, req->data_len); pipe = usb_sndctrlpipe(udev, 0); } else { /* read */ pipe = usb_rcvctrlpipe(udev, 0); } msleep(1); /* avoid I2C errors */ ret = usb_control_msg(udev, pipe, request, requesttype, value, index, buf, req->data_len, CE6230_USB_TIMEOUT); ce6230_debug_dump(request, requesttype, value, index, buf, req->data_len, deb_xfer); if (ret < 0) deb_info("%s: usb_control_msg failed:%d\n", __func__, ret); else ret = 0; /* read request, copy returned data to return buf */ if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) memcpy(req->data, buf, req->data_len); kfree(buf); error: return ret; }
static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n) { struct redrat3_dev *rr3 = rcdev->priv; struct device *dev = rr3->dev; struct redrat3_signal_header header; int i, j, count, ret, ret_len, offset; int lencheck, cur_sample_len, pipe; char *buffer = NULL, *sigdata = NULL; int *sample_lens = NULL; u32 tmpi; u16 tmps; u8 *datap; u8 curlencheck = 0; u16 *lengths_ptr; int sendbuf_len; rr3_ftr(dev, "Entering %s\n", __func__); if (rr3->transmitting) { dev_warn(dev, "%s: transmitter already in use\n", __func__); return -EAGAIN; } count = n / sizeof(int); if (count > (RR3_DRIVER_MAXLENS * 2)) return -EINVAL; rr3->transmitting = true; redrat3_disable_detector(rr3); if (rr3->det_enabled) { dev_err(dev, "%s: cannot tx while rx is enabled\n", __func__); ret = -EIO; goto out; } sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL); if (!sample_lens) { ret = -ENOMEM; goto out; } for (i = 0; i < count; i++) { for (lencheck = 0; lencheck < curlencheck; lencheck++) { cur_sample_len = redrat3_us_to_len(txbuf[i]); if (sample_lens[lencheck] == cur_sample_len) break; } if (lencheck == curlencheck) { cur_sample_len = redrat3_us_to_len(txbuf[i]); rr3_dbg(dev, "txbuf[%d]=%u, pos %d, enc %u\n", i, txbuf[i], curlencheck, cur_sample_len); if (curlencheck < 255) { /* now convert the value to a proper * rr3 value.. */ sample_lens[curlencheck] = cur_sample_len; curlencheck++; } else { dev_err(dev, "signal too long\n"); ret = -EINVAL; goto out; } } } sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL); if (!sigdata) { ret = -ENOMEM; goto out; } sigdata[count] = RR3_END_OF_SIGNAL; sigdata[count + 1] = RR3_END_OF_SIGNAL; for (i = 0; i < count; i++) { for (j = 0; j < curlencheck; j++) { if (sample_lens[j] == redrat3_us_to_len(txbuf[i])) sigdata[i] = j; } } offset = RR3_TX_HEADER_OFFSET; sendbuf_len = RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS) + count + RR3_TX_TRAILER_LEN + offset; buffer = kzalloc(sendbuf_len, GFP_KERNEL); if (!buffer) { ret = -ENOMEM; goto out; } /* fill in our packet header */ header.length = sendbuf_len - offset; header.transfer_type = RR3_MOD_SIGNAL_OUT; header.pause = redrat3_len_to_us(100); header.mod_freq_count = mod_freq_to_val(rr3->carrier); header.no_periods = 0; /* n/a to transmit */ header.max_lengths = RR3_DRIVER_MAXLENS; header.no_lengths = curlencheck; header.max_sig_size = RR3_MAX_SIG_SIZE; header.sig_size = count + RR3_TX_TRAILER_LEN; /* we currently rely on repeat handling in the IR encoding source */ header.no_repeats = 0; tmps = cpu_to_be16(header.length); memcpy(buffer, &tmps, 2); tmps = cpu_to_be16(header.transfer_type); memcpy(buffer + 2, &tmps, 2); tmpi = cpu_to_be32(header.pause); memcpy(buffer + offset, &tmpi, sizeof(tmpi)); tmps = cpu_to_be16(header.mod_freq_count); memcpy(buffer + offset + RR3_FREQ_COUNT_OFFSET, &tmps, 2); buffer[offset + RR3_NUM_LENGTHS_OFFSET] = header.no_lengths; tmps = cpu_to_be16(header.sig_size); memcpy(buffer + offset + RR3_NUM_SIGS_OFFSET, &tmps, 2); buffer[offset + RR3_REPEATS_OFFSET] = header.no_repeats; lengths_ptr = (u16 *)(buffer + offset + RR3_HEADER_LENGTH); for (i = 0; i < curlencheck; ++i) lengths_ptr[i] = cpu_to_be16(sample_lens[i]); datap = (u8 *)(buffer + offset + RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS)); memcpy(datap, sigdata, (count + RR3_TX_TRAILER_LEN)); if (debug) { redrat3_dump_signal_header(&header); redrat3_dump_signal_data(buffer, header.sig_size); } pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress); tmps = usb_bulk_msg(rr3->udev, pipe, buffer, sendbuf_len, &ret_len, 10 * HZ); rr3_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, tmps); /* now tell the hardware to transmit what we sent it */ pipe = usb_rcvctrlpipe(rr3->udev, 0); ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0, 0, buffer, 2, HZ * 10); if (ret < 0) dev_err(dev, "Error: control msg send failed, rc %d\n", ret); else ret = n; out: kfree(sample_lens); kfree(buffer); kfree(sigdata); rr3->transmitting = false; redrat3_enable_detector(rr3); return ret; }
/* cdc-ncm specific functions */ static u8 cdc_ncm_setup(struct if_usb_devdata *pipe_data) { u32 val; u8 flags; u8 iface_no; int err; u16 ntb_fmt_supported; struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)pipe_data->sedata; struct usb_device *usbdev = pipe_data->usbdev; iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; mif_debug("iface_no=%d\n", iface_no); err = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), USB_CDC_GET_NTB_PARAMETERS, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, 0, iface_no, &ctx->ncm_parm, sizeof(ctx->ncm_parm), 10000); if (err < 0) { mif_debug("failed GET_NTB_PARAMETERS\n"); return 1; } /* read correct set of parameters according to device mode */ ctx->rx_max = le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize); ctx->tx_max = le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize); ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); /* devices prior to NCM Errata shall set this field to zero */ ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams); ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported); if (ctx->func_desc != NULL) flags = ctx->func_desc->bmNetworkCapabilities; else flags = 0; mif_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u " "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u " "wNdpOutAlignment=%u wNtbOutMaxDatagrams=%u flags=0x%x\n", ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus, ctx->tx_ndp_modulus, ctx->tx_max_datagrams, flags); /* max count of tx datagrams */ if ((ctx->tx_max_datagrams == 0) || (ctx->tx_max_datagrams > CDC_NCM_DPT_DATAGRAMS_MAX)) ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; /* verify maximum size of received NTB in bytes */ if (ctx->rx_max < USB_CDC_NCM_NTB_MIN_IN_SIZE) { mif_debug("Using min receive length=%d\n", USB_CDC_NCM_NTB_MIN_IN_SIZE); ctx->rx_max = USB_CDC_NCM_NTB_MIN_IN_SIZE; } if (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX) { mif_debug("Using default maximum receive length=%d\n", CDC_NCM_NTB_MAX_SIZE_RX); ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX; } /* inform device about NTB input size changes */ if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) { struct usb_cdc_ncm_ndp_input_size *ndp_in_sz; ndp_in_sz = kzalloc(sizeof(*ndp_in_sz), GFP_KERNEL); if (!ndp_in_sz) { err = -ENOMEM; goto size_err; } err = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), USB_CDC_SET_NTB_INPUT_SIZE, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, 0, iface_no, ndp_in_sz, 8, 1000); kfree(ndp_in_sz); } else { __le32 *dwNtbInMaxSize; dwNtbInMaxSize = kzalloc(sizeof(*dwNtbInMaxSize), GFP_KERNEL); if (!dwNtbInMaxSize) { err = -ENOMEM; goto size_err; } *dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); err = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), USB_CDC_SET_NTB_INPUT_SIZE, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, 0, iface_no, dwNtbInMaxSize, 4, 1000); kfree(dwNtbInMaxSize); } size_err: if (err < 0) mif_debug("Setting NTB Input Size failed\n"); } /* verify maximum size of transmitted NTB in bytes */ if ((ctx->tx_max < (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || (ctx->tx_max > CDC_NCM_NTB_MAX_SIZE_TX)) { mif_debug("Using default maximum transmit length=%d\n", CDC_NCM_NTB_MAX_SIZE_TX); ctx->tx_max = CDC_NCM_NTB_MAX_SIZE_TX; } ctx->tx_max_setup = ctx->tx_max; /* * verify that the structure alignment is: * - power of two * - not greater than the maximum transmit length * - not less than four bytes */ val = ctx->tx_ndp_modulus; if ((val < USB_CDC_NCM_NDP_ALIGN_MIN_SIZE) || (val != ((-val) & val)) || (val >= ctx->tx_max)) { mif_debug("Using default alignment: 4 bytes\n"); ctx->tx_ndp_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE; } /* * verify that the payload alignment is: * - power of two * - not greater than the maximum transmit length * - not less than four bytes */ val = ctx->tx_modulus; if ((val < USB_CDC_NCM_NDP_ALIGN_MIN_SIZE) || (val != ((-val) & val)) || (val >= ctx->tx_max)) { mif_debug("Using default transmit modulus: 4 bytes\n"); ctx->tx_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE; } /* verify the payload remainder */ if (ctx->tx_remainder >= ctx->tx_modulus) { mif_debug("Using default transmit remainder: 0 bytes\n"); ctx->tx_remainder = 0; } /* adjust TX-remainder according to NCM specification. */ ctx->tx_remainder = ((ctx->tx_remainder - ETH_HLEN) & (ctx->tx_modulus - 1)); /* additional configuration */ /* set CRC Mode */ if (flags & USB_CDC_NCM_NCAP_CRC_MODE) { err = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), USB_CDC_SET_CRC_MODE, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, USB_CDC_NCM_CRC_NOT_APPENDED, iface_no, NULL, 0, 1000); if (err < 0) mif_debug("Setting CRC mode off failed\n"); } /* set NTB format, if both formats are supported */ if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) { err = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), USB_CDC_SET_NTB_FORMAT, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, USB_CDC_NCM_NTB16_FORMAT, iface_no, NULL, 0, 1000); if (err < 0) mif_debug("Setting NTB format to 16-bit failed\n"); } ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; /* set Max Datagram Size (MTU) */ if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) { __le16 *max_datagram_size; u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); max_datagram_size = kzalloc(sizeof(*max_datagram_size), GFP_KERNEL); if (!max_datagram_size) { err = -ENOMEM; goto max_dgram_err; } err = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), USB_CDC_GET_MAX_DATAGRAM_SIZE, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, 0, iface_no, max_datagram_size, 2, 1000); if (err < 0) { mif_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", CDC_NCM_MIN_DATAGRAM_SIZE); } else { ctx->max_datagram_size = le16_to_cpu(*max_datagram_size); /* Check Eth descriptor value */ if (ctx->max_datagram_size > eth_max_sz) ctx->max_datagram_size = eth_max_sz; if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE) ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE; if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE) ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; /* if value changed, update device */ if (ctx->max_datagram_size != le16_to_cpu(*max_datagram_size)) { err = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), USB_CDC_SET_MAX_DATAGRAM_SIZE, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, 0, iface_no, max_datagram_size, 2, 1000); if (err < 0) pr_debug("SET_MAX_DGRAM_SIZE failed\n"); } } kfree(max_datagram_size); } max_dgram_err: if (pipe_data->iod->ndev->mtu != (ctx->max_datagram_size - ETH_HLEN)) pipe_data->iod->ndev->mtu = ctx->max_datagram_size - ETH_HLEN; return 0; }
static VOID adv_fai_terminate_device(adv_device *device) { private_data *privdata = (private_data *) (device->private_data); INT32U tmp; INT32S ret; /* send command to device to stop fai */ if (down_interruptible(privdata->usb_urb_sema)) { return; } if (privdata->udev == NULL) { up(privdata->usb_urb_sema); return; } ret = adv_usb_ctrl_msg(privdata->udev, usb_sndctrlpipe(privdata->udev, 0), MAJOR_AI, 0x40, MINOR_FAI_TERMINATE, 0, (INT8U *) &tmp, sizeof(INT32U)); if (ret < 0) { up(privdata->usb_urb_sema); return; } switch (privdata->device_type) { case USB4711A: break; case USB4711B: ret = adv_usb_ctrl_msg(privdata->udev, usb_rcvctrlpipe(privdata->udev, 0), MAJOR_SYSTEM, (0x40 | 0x80), MINOR_GET_USB_FLAG, 0, (INT8U *) &tmp, sizeof(INT32U)); if (ret < 0) { up(privdata->usb_urb_sema); return; } if (tmp & FAI_BUSY) { ret = adv_usb_ctrl_msg(privdata->udev, usb_sndctrlpipe(privdata->udev, 0), MAJOR_AI, 0x40, MINOR_FAI_TERMINATE, 0, (INT8U *) &tmp, sizeof(INT32U)); if (ret < 0) { up(privdata->usb_urb_sema); return; } } break; default: up(privdata->usb_urb_sema); return; } switch (privdata->device_type) { case USB4711A: { INT16U i; for (i = 0; i < 256; i++) { mdelay(500); ret = adv_usb_ctrl_msg(privdata->udev, usb_sndctrlpipe(privdata->udev, 0), MAJOR_AI, 0x40, MINOR_FAI_ZLP, 0, (INT8U *) &tmp, sizeof(INT32U)); if (ret < 0) { up(privdata->usb_urb_sema); return; } } } break; case USB4711B: break; default: up(privdata->usb_urb_sema); return; } up(privdata->usb_urb_sema); return; }
static int usb_get_hub_descriptor(USB_DEV_T *dev, void *data, int size) { return USBH_SendCtrlMsg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB, USB_DT_HUB << 8, 0, data, size, HZ); }
int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype) { _adapter *padapter = pintfhdl->padapter; struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobjpriv); struct usb_device *udev=pdvobjpriv->pusbdev; unsigned int pipe; int status = 0; u32 tmp_buflen=0; u8 reqtype; u8 *pIo_buf; int vendorreq_times = 0; #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE u8 *tmp_buf; #else // use stack memory u8 tmp_buf[MAX_USB_IO_CTL_SIZE]; #endif #ifdef CONFIG_CONCURRENT_MODE if(padapter->adapter_type > PRIMARY_ADAPTER) { padapter = padapter->pbuddy_adapter; pdvobjpriv = adapter_to_dvobj(padapter); udev = pdvobjpriv->pusbdev; } #endif //DBG_871X("%s %s:%d\n",__FUNCTION__, current->comm, current->pid); if (RTW_CANNOT_IO(padapter)){ RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usbctrl_vendorreq:(RTW_CANNOT_IO)!!!\n")); status = -EPERM; goto exit; } if(len>MAX_VENDOR_REQ_CMD_SIZE){ DBG_8192C( "[%s] Buffer len error ,vendor request failed\n", __FUNCTION__ ); status = -EINVAL; goto exit; } #ifdef CONFIG_USB_VENDOR_REQ_MUTEX _enter_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL); #endif // Acquire IO memory for vendorreq #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC pIo_buf = pdvobjpriv->usb_vendor_req_buf; #else #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE tmp_buf = rtw_malloc( (u32) len + ALIGNMENT_UNIT); tmp_buflen = (u32)len + ALIGNMENT_UNIT; #else // use stack memory tmp_buflen = MAX_USB_IO_CTL_SIZE; #endif // Added by Albert 2010/02/09 // For mstar platform, mstar suggests the address for USB IO should be 16 bytes alignment. // Trying to fix it here. pIo_buf = (tmp_buf==NULL)?NULL:tmp_buf + ALIGNMENT_UNIT -((SIZE_PTR)(tmp_buf) & 0x0f ); #endif if ( pIo_buf== NULL) { DBG_8192C( "[%s] pIo_buf == NULL \n", __FUNCTION__ ); status = -ENOMEM; goto release_mutex; } while(++vendorreq_times<= MAX_USBCTRL_VENDORREQ_TIMES) { _rtw_memset(pIo_buf, 0, len); if (requesttype == 0x01) { pipe = usb_rcvctrlpipe(udev, 0);//read_in reqtype = REALTEK_USB_VENQT_READ; } else { pipe = usb_sndctrlpipe(udev, 0);//write_out reqtype = REALTEK_USB_VENQT_WRITE; _rtw_memcpy( pIo_buf, pdata, len); } status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT); if ( status == len) // Success this control transfer. { rtw_reset_continual_io_error(pdvobjpriv); if ( requesttype == 0x01 ) { // For Control read transfer, we have to copy the read data from pIo_buf to pdata. _rtw_memcpy( pdata, pIo_buf, len ); } } else { // error cases DBG_8192C("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n" , value,(requesttype == 0x01)?"read":"write" , len, status, *(u32*)pdata, vendorreq_times); if (status < 0) { if(status == (-ESHUTDOWN) || status == -ENODEV ) { padapter->bSurpriseRemoved = _TRUE; } else { #ifdef DBG_CONFIG_ERROR_DETECT { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); pHalData->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL; } #endif } } else // status != len && status >= 0 { if(status > 0) { if ( requesttype == 0x01 ) { // For Control read transfer, we have to copy the read data from pIo_buf to pdata. _rtw_memcpy( pdata, pIo_buf, len ); } } } if(rtw_inc_and_chk_continual_io_error(pdvobjpriv) == _TRUE ){ padapter->bSurpriseRemoved = _TRUE; break; } } // firmware download is checksumed, don't retry if( (value >= FW_START_ADDRESS ) || status == len ) break; } // release IO memory used by vendorreq #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE rtw_mfree(tmp_buf, tmp_buflen); #endif release_mutex: #ifdef CONFIG_USB_VENDOR_REQ_MUTEX _exit_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL); #endif exit: return status; }
static int ehset_probe(struct usb_interface *intf, const struct usb_device_id *id) { int ret = -EINVAL; struct usb_device *dev = interface_to_usbdev(intf); struct usb_device *hub_udev = dev->parent; struct usb_device_descriptor *buf; u8 portnum = dev->portnum; u16 test_pid = le16_to_cpu(dev->descriptor.idProduct); struct otg_fsm *fsm = dev->bus->otg_fsm; switch (test_pid) { case TEST_SE0_NAK_PID: ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST, (TEST_SE0_NAK << 8) | portnum, NULL, 0, 1000); break; case TEST_J_PID: ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST, (TEST_J << 8) | portnum, NULL, 0, 1000); break; case TEST_K_PID: ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST, (TEST_K << 8) | portnum, NULL, 0, 1000); break; case TEST_PACKET_PID: ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST, (TEST_PACKET << 8) | portnum, NULL, 0, 1000); break; case TEST_HS_HOST_PORT_SUSPEND_RESUME: /* Test: wait for 15secs -> suspend -> 15secs delay -> resume */ msleep(15 * 1000); ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_SUSPEND, portnum, NULL, 0, 1000); if (ret < 0) break; msleep(15 * 1000); ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), USB_REQ_CLEAR_FEATURE, USB_RT_PORT, USB_PORT_FEAT_SUSPEND, portnum, NULL, 0, 1000); break; case TEST_SINGLE_STEP_GET_DEV_DESC: /* Test: wait for 15secs -> GetDescriptor request */ msleep(15 * 1000); buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, USB_DT_DEVICE << 8, 0, buf, USB_DT_DEVICE_SIZE, USB_CTRL_GET_TIMEOUT); kfree(buf); break; case TEST_SINGLE_STEP_SET_FEATURE: /* * GetDescriptor SETUP request -> 15secs delay -> IN & STATUS * * Note, this test is only supported on root hubs since the * SetPortFeature handling can only be done inside the HCD's * hub_control callback function. */ if (hub_udev != dev->bus->root_hub) { dev_err(&intf->dev, "SINGLE_STEP_SET_FEATURE test only supported on root hub\n"); break; } ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST, (6 << 8) | portnum, NULL, 0, 60 * 1000); break; case TEST_OTG_TEST_DEVICE_SUPPORT: if (!fsm) return ret; /* B host enumerate test device */ if (dev->bus->is_b_host) { otg_add_timer(fsm, B_TST_SUSP); ret = 0; break; } mutex_lock(&fsm->lock); fsm->tst_maint = 1; if (le16_to_cpu(dev->descriptor.bcdDevice) & 0x1) fsm->otg_vbus_off = 1; else fsm->otg_vbus_off = 0; mutex_unlock(&fsm->lock); otg_add_timer(fsm, A_TST_MAINT); ret = 0; break; default: dev_err(&intf->dev, "%s: unsupported PID: 0x%x\n", __func__, test_pid); } return (ret < 0) ? ret : 0; }
static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req) { int ret; unsigned int pipe; u8 request, requesttype; u8 *buf; switch (req->cmd) { case DOWNLOAD_FIRMWARE: case GPIO: case WRITE_I2C: case STREAMING_CTRL: requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); request = req->cmd; break; case READ_I2C: requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); request = req->cmd; break; case GET_CONFIG: requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); request = CONFIG; break; case SET_CONFIG: requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); request = CONFIG; break; case WRITE_DEMOD: requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); request = DEMOD_RW; break; case READ_DEMOD: requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); request = DEMOD_RW; break; default: err("unknown command:%02x", req->cmd); ret = -EPERM; goto error; } buf = kmalloc(req->size, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto error; } if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) { /* write */ memcpy(buf, req->data, req->size); pipe = usb_sndctrlpipe(udev, 0); } else { /* read */ pipe = usb_rcvctrlpipe(udev, 0); } msleep(1); /* avoid I2C errors */ ret = usb_control_msg(udev, pipe, request, requesttype, req->value, req->index, buf, req->size, EC168_USB_TIMEOUT); ec168_debug_dump(request, requesttype, req->value, req->index, buf, req->size, deb_xfer); if (ret < 0) goto err_dealloc; else ret = 0; /* read request, copy returned data to return buf */ if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) memcpy(req->data, buf, req->size); kfree(buf); return ret; err_dealloc: kfree(buf); error: deb_info("%s: failed:%d\n", __func__, ret); return ret; }
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, struct wacom_features *features) { struct usb_device *dev = interface_to_usbdev(intf); char limit = 0; /* */ int result = 0; int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; unsigned char *report; report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); if (!report) return -ENOMEM; /* */ do { result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, HID_DEVICET_REPORT << 8, intf->altsetting[0].desc.bInterfaceNumber, /* */ report, hid_desc->wDescriptorLength, 5000); /* */ } while (result < 0 && limit++ < WAC_MSG_RETRIES); /* */ if (result < 0) goto out; for (i = 0; i < hid_desc->wDescriptorLength; i++) { switch (report[i]) { case HID_USAGE_PAGE: switch (report[i + 1]) { case HID_USAGE_PAGE_DIGITIZER: usage = WCM_DIGITIZER; i++; break; case HID_USAGE_PAGE_DESKTOP: usage = WCM_DESKTOP; i++; break; } break; case HID_USAGE: switch (report[i + 1]) { case HID_USAGE_X: if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_FINGER; if (features->type == TABLETPC2FG) { /* */ features->pktlen = WACOM_PKGLEN_TPC2FG; } if (features->type == BAMBOO_PT) { /* */ features->pktlen = WACOM_PKGLEN_BBTOUCH; features->x_phy = get_unaligned_le16(&report[i + 5]); features->x_max = get_unaligned_le16(&report[i + 8]); i += 15; } else { features->x_max = get_unaligned_le16(&report[i + 3]); features->x_phy = get_unaligned_le16(&report[i + 6]); features->unit = report[i + 9]; features->unitExpo = report[i + 11]; i += 12; } } else if (pen) { /* */ if (features->type == TABLETPC2FG) features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->x_max = get_unaligned_le16(&report[i + 3]); i += 4; } } break; case HID_USAGE_Y: if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_FINGER; if (features->type == TABLETPC2FG) { /* */ features->pktlen = WACOM_PKGLEN_TPC2FG; features->y_max = get_unaligned_le16(&report[i + 3]); features->y_phy = get_unaligned_le16(&report[i + 6]); i += 7; } else if (features->type == BAMBOO_PT) { /* */ features->pktlen = WACOM_PKGLEN_BBTOUCH; features->y_phy = get_unaligned_le16(&report[i + 3]); features->y_max = get_unaligned_le16(&report[i + 6]); i += 12; } else { features->y_max = features->x_max; features->y_phy = get_unaligned_le16(&report[i + 3]); i += 4; } } else if (pen) { /* */ if (features->type == TABLETPC2FG) features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->y_max = get_unaligned_le16(&report[i + 3]); i += 4; } } break; case HID_USAGE_FINGER: finger = 1; i++; break; /* */ case HID_USAGE_STYLUS: pen = 1; i++; break; } break; case HID_COLLECTION_END: /* */ finger = usage = 0; break; case HID_COLLECTION: i++; switch (report[i]) { case HID_COLLECTION_LOGICAL: i += wacom_parse_logical_collection(&report[i], features); break; } break; } } out: result = 0; kfree(report); return result; }
static inline int qt2_getdevice(struct usb_device *dev, u8 *data) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), QT_SET_GET_DEVICE, 0xc0, 0, 0, data, 3, QT2_USB_TIMEOUT); }
/* * parse the format descriptor and stores the possible sample rates * on the audioformat table (audio class v2). */ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, struct audioformat *fp) { struct usb_device *dev = chip->dev; unsigned char tmp[2], *data; int nr_triplets, data_size, ret = 0; int clock = snd_usb_clock_find_source(chip, fp->clock); if (clock < 0) { snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n", __func__, clock); goto err; } /* get the number of sample rates first by only fetching 2 bytes */ ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, UAC2_CS_CONTROL_SAM_FREQ << 8, snd_usb_ctrl_intf(chip) | (clock << 8), tmp, sizeof(tmp)); if (ret < 0) { snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n", __func__, clock); goto err; } nr_triplets = (tmp[1] << 8) | tmp[0]; data_size = 2 + 12 * nr_triplets; data = kzalloc(data_size, GFP_KERNEL); if (!data) { ret = -ENOMEM; goto err; } /* now get the full information */ ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, UAC2_CS_CONTROL_SAM_FREQ << 8, snd_usb_ctrl_intf(chip) | (clock << 8), data, data_size); if (ret < 0) { snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n", __func__, clock); ret = -EINVAL; goto err_free; } /* Call the triplet parser, and make sure fp->rate_table is NULL. * We just use the return value to know how many sample rates we * will have to deal with. */ kfree(fp->rate_table); fp->rate_table = NULL; fp->nr_rates = parse_uac2_sample_rate_range(fp, nr_triplets, data); if (fp->nr_rates == 0) { /* SNDRV_PCM_RATE_CONTINUOUS */ ret = 0; goto err_free; } fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); if (!fp->rate_table) { ret = -ENOMEM; goto err_free; } /* Call the triplet parser again, but this time, fp->rate_table is * allocated, so the rates will be stored */ parse_uac2_sample_rate_range(fp, nr_triplets, data); err_free: kfree(data); err: return ret; }
static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) { struct RioCommand rio_cmd; struct rio_usb_data *rio = &rio_instance; void __user *data; unsigned char *buffer; int result, requesttype; int retries; int retval=0; mutex_lock(&(rio->lock)); /* Sanity check to make sure rio is connected, powered, etc */ if (rio->present == 0 || rio->rio_dev == NULL) { retval = -ENODEV; goto err_out; } switch (cmd) { case RIO_RECV_COMMAND: data = (void __user *) arg; if (data == NULL) break; if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { retval = -EFAULT; goto err_out; } if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) { retval = -EINVAL; goto err_out; } buffer = (unsigned char *) __get_free_page(GFP_KERNEL); if (buffer == NULL) { retval = -ENOMEM; goto err_out; } if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { retval = -EFAULT; free_page((unsigned long) buffer); goto err_out; } requesttype = rio_cmd.requesttype | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE; dbg ("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x", requesttype, rio_cmd.request, rio_cmd.value, rio_cmd.index, rio_cmd.length); /* Send rio control message */ retries = 3; while (retries) { result = usb_control_msg(rio->rio_dev, usb_rcvctrlpipe(rio-> rio_dev, 0), rio_cmd.request, requesttype, rio_cmd.value, rio_cmd.index, buffer, rio_cmd.length, jiffies_to_msecs(rio_cmd.timeout)); if (result == -ETIMEDOUT) retries--; else if (result < 0) { err("Error executing ioctrl. code = %d", result); retries = 0; } else { dbg("Executed ioctl. Result = %d (data=%02x)", result, buffer[0]); if (copy_to_user(rio_cmd.buffer, buffer, rio_cmd.length)) { free_page((unsigned long) buffer); retval = -EFAULT; goto err_out; } retries = 0; } /* rio_cmd.buffer contains a raw stream of single byte data which has been returned from rio. Data is interpreted at application level. For data that will be cast to data types longer than 1 byte, data will be little_endian and will potentially need to be swapped at the app level */ } free_page((unsigned long) buffer); break; case RIO_SEND_COMMAND: data = (void __user *) arg; if (data == NULL) break; if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { retval = -EFAULT; goto err_out; } if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) { retval = -EINVAL; goto err_out; } buffer = (unsigned char *) __get_free_page(GFP_KERNEL); if (buffer == NULL) { retval = -ENOMEM; goto err_out; } if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { free_page((unsigned long)buffer); retval = -EFAULT; goto err_out; } requesttype = rio_cmd.requesttype | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; dbg("sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x", requesttype, rio_cmd.request, rio_cmd.value, rio_cmd.index, rio_cmd.length); /* Send rio control message */ retries = 3; while (retries) { result = usb_control_msg(rio->rio_dev, usb_sndctrlpipe(rio-> rio_dev, 0), rio_cmd.request, requesttype, rio_cmd.value, rio_cmd.index, buffer, rio_cmd.length, jiffies_to_msecs(rio_cmd.timeout)); if (result == -ETIMEDOUT) retries--; else if (result < 0) { err("Error executing ioctrl. code = %d", result); retries = 0; } else { dbg("Executed ioctl. Result = %d", result); retries = 0; } } free_page((unsigned long) buffer); break; default: retval = -ENOTTY; break; } err_out: mutex_unlock(&(rio->lock)); return retval; }
static int zte_ev_usb_serial_open(struct tty_struct *tty, struct usb_serial_port *port) { struct usb_device *udev = port->serial->dev; struct device *dev = &port->dev; int result = 0; int len; unsigned char *buf; buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; /* send 1st ctl cmd(CTL 21 22 01 00 00 00 00 00) */ len = 0; result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x22, 0x21, 0x0001, 0x0000, NULL, len, USB_CTRL_GET_TIMEOUT); dev_dbg(dev, "result = %d\n", result); /* send 2st cmd and recieve data */ /* * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 25.1.0(5) * 16.0 DI 00 96 00 00 00 00 08 */ len = 0x0007; result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x21, 0xa1, 0x0000, 0x0000, buf, len, USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 3 cmd */ /* * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 30.1.0 * 16.0 DO 80 25 00 00 00 00 08 .%..... 30.2.0 */ len = 0x0007; buf[0] = 0x80; buf[1] = 0x25; buf[2] = 0x00; buf[3] = 0x00; buf[4] = 0x00; buf[5] = 0x00; buf[6] = 0x08; result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x20, 0x21, 0x0000, 0x0000, buf, len, USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 4 cmd */ /* * 16.0 CTL 21 22 03 00 00 00 00 00 */ len = 0; result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x22, 0x21, 0x0003, 0x0000, NULL, len, USB_CTRL_GET_TIMEOUT); dev_dbg(dev, "result = %d\n", result); /* send 5 cmd */ /* * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 33.1.0 * 16.0 DI 80 25 00 00 00 00 08 */ len = 0x0007; result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x21, 0xa1, 0x0000, 0x0000, buf, len, USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); /* send 6 cmd */ /* * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 34.1.0 * 16.0 DO 80 25 00 00 00 00 08 */ len = 0x0007; buf[0] = 0x80; buf[1] = 0x25; buf[2] = 0x00; buf[3] = 0x00; buf[4] = 0x00; buf[5] = 0x00; buf[6] = 0x08; result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x20, 0x21, 0x0000, 0x0000, buf, len, USB_CTRL_GET_TIMEOUT); debug_data(dev, __func__, len, buf, result); kfree(buf); return usb_serial_generic_open(tty, port); }
int rmnet_usb_ctrl_probe(struct usb_interface *intf, struct usb_host_endpoint *int_in, struct rmnet_ctrl_dev *dev) { u16 wMaxPacketSize; struct usb_endpoint_descriptor *ep; struct usb_device *udev; int interval; int ret = 0; udev = interface_to_usbdev(intf); if (!dev) { pr_err("%s: Ctrl device not found\n", __func__); return -ENODEV; } dev->int_pipe = usb_rcvintpipe(udev, int_in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); mutex_lock(&dev->dev_lock); dev->intf = intf; /*TBD: for now just update CD status*/ dev->cbits_tolocal = ACM_CTRL_CD; /*send DTR high to modem*/ dev->cbits_tomdm = ACM_CTRL_DTR; mutex_unlock(&dev->dev_lock); dev->resp_available = false; dev->snd_encap_cmd_cnt = 0; dev->get_encap_resp_cnt = 0; dev->resp_avail_cnt = 0; dev->tx_ctrl_err_cnt = 0; dev->set_ctrl_line_state_cnt = 0; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), USB_CDC_REQ_SET_CONTROL_LINE_STATE, (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE), dev->cbits_tomdm, dev->intf->cur_altsetting->desc.bInterfaceNumber, NULL, 0, USB_CTRL_SET_TIMEOUT); if (ret < 0) return ret; dev->set_ctrl_line_state_cnt++; dev->inturb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->inturb) { dev_err(dev->devicep, "Error allocating int urb\n"); return -ENOMEM; } /*use max pkt size from ep desc*/ ep = &dev->intf->cur_altsetting->endpoint[0].desc; wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); dev->intbuf = kmalloc(wMaxPacketSize, GFP_KERNEL); if (!dev->intbuf) { usb_free_urb(dev->inturb); dev_err(dev->devicep, "Error allocating int buffer\n"); return -ENOMEM; } dev->in_ctlreq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); dev->in_ctlreq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; dev->in_ctlreq->wValue = 0; dev->in_ctlreq->wIndex = dev->intf->cur_altsetting->desc.bInterfaceNumber; dev->in_ctlreq->wLength = cpu_to_le16(DEFAULT_READ_URB_LENGTH); interval = max((int)int_in->desc.bInterval, (udev->speed == USB_SPEED_HIGH) ? HS_INTERVAL : FS_LS_INTERVAL); usb_fill_int_urb(dev->inturb, udev, dev->int_pipe, dev->intbuf, wMaxPacketSize, notification_available_cb, dev, interval); usb_mark_last_busy(udev); ret = rmnet_usb_ctrl_start_rx(dev); if (!ret) dev->is_connected = true; return ret; }
/* * Interface Descriptor of wacom devices can be incomplete and * inconsistent so wacom_features table is used to store stylus * device's packet lengths, various maximum values, and tablet * resolution based on product ID's. * * For devices that contain 2 interfaces, wacom_features table is * inaccurate for the touch interface. Since the Interface Descriptor * for touch interfaces has pretty complete data, this function exists * to query tablet for this missing information instead of hard coding in * an additional table. * * A typical Interface Descriptor for a stylus will contain a * boot mouse application collection that is not of interest and this * function will ignore it. * * It also contains a digitizer application collection that also is not * of interest since any information it contains would be duplicate * of what is in wacom_features. Usually it defines a report of an array * of bytes that could be used as max length of the stylus packet returned. * If it happens to define a Digitizer-Stylus Physical Collection then * the X and Y logical values contain valid data but it is ignored. * * A typical Interface Descriptor for a touch interface will contain a * Digitizer-Finger Physical Collection which will define both logical * X/Y maximum as well as the physical size of tablet. Since touch * interfaces haven't supported pressure or distance, this is enough * information to override invalid values in the wacom_features table. * * 3rd gen Bamboo Touch no longer define a Digitizer-Finger Pysical * Collection. Instead they define a Logical Collection with a single * Logical Maximum for both X and Y. */ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, struct wacom_features *features) { struct usb_device *dev = interface_to_usbdev(intf); char limit = 0; /* result has to be defined as int for some devices */ int result = 0; int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; unsigned char *report; report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); if (!report) return -ENOMEM; /* retrive report descriptors */ do { result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, HID_DEVICET_REPORT << 8, intf->altsetting[0].desc.bInterfaceNumber, /* interface */ report, hid_desc->wDescriptorLength, 5000); /* 5 secs */ } while (result < 0 && limit++ < WAC_MSG_RETRIES); /* No need to parse the Descriptor. It isn't an error though */ if (result < 0) goto out; for (i = 0; i < hid_desc->wDescriptorLength; i++) { switch (report[i]) { case HID_USAGE_PAGE: switch (report[i + 1]) { case HID_USAGE_PAGE_DIGITIZER: usage = WCM_DIGITIZER; i++; break; case HID_USAGE_PAGE_DESKTOP: usage = WCM_DESKTOP; i++; break; } break; case HID_USAGE: switch (report[i + 1]) { case HID_USAGE_X: if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_FINGER; if (features->type == TABLETPC2FG) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_TPC2FG; } if (features->type == BAMBOO_PT) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_BBTOUCH; features->x_phy = get_unaligned_le16(&report[i + 5]); features->x_max = get_unaligned_le16(&report[i + 8]); i += 15; } else { features->x_max = get_unaligned_le16(&report[i + 3]); features->x_phy = get_unaligned_le16(&report[i + 6]); features->unit = report[i + 9]; features->unitExpo = report[i + 11]; i += 12; } } else if (pen) { /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->x_max = get_unaligned_le16(&report[i + 3]); i += 4; } } break; case HID_USAGE_Y: if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_FINGER; if (features->type == TABLETPC2FG) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_TPC2FG; features->y_max = get_unaligned_le16(&report[i + 3]); features->y_phy = get_unaligned_le16(&report[i + 6]); i += 7; } else if (features->type == BAMBOO_PT) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_BBTOUCH; features->y_phy = get_unaligned_le16(&report[i + 3]); features->y_max = get_unaligned_le16(&report[i + 6]); i += 12; } else { features->y_max = features->x_max; features->y_phy = get_unaligned_le16(&report[i + 3]); i += 4; } } else if (pen) { /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->y_max = get_unaligned_le16(&report[i + 3]); i += 4; } } break; case HID_USAGE_FINGER: finger = 1; i++; break; /* * Requiring Stylus Usage will ignore boot mouse * X/Y values and some cases of invalid Digitizer X/Y * values commonly reported. */ case HID_USAGE_STYLUS: pen = 1; i++; break; } break; case HID_COLLECTION_END: /* reset UsagePage and Finger */ finger = usage = 0; break; case HID_COLLECTION: i++; switch (report[i]) { case HID_COLLECTION_LOGICAL: i += wacom_parse_logical_collection(&report[i], features); break; } break; } } out: result = 0; kfree(report); return result; }
static int pnwotg_test_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct pnwotg_test_dev *dev; int retval, portNum; dev_dbg(&intf->dev, "Penwell OTG test mode is initiated.\n"); dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; dev->buf = kmalloc(TBUF_SIZE, GFP_KERNEL); if (!dev->buf) { kfree(dev); return -ENOMEM; } dev->udev = usb_get_dev(interface_to_usbdev(intf)); dev->hcd = usb_get_hcd(bus_to_hcd(dev->udev->bus)); usb_set_intfdata(intf, dev); portNum = dev->udev->portnum & 0xff; dev_dbg(&intf->dev, "test mode PID 0x%04x\n", le16_to_cpu(dev->udev->descriptor.idProduct)); switch (le16_to_cpu(dev->udev->descriptor.idProduct)) { case 0x0101: /* TEST_SE0_NAK */ dev->hcd->driver->hub_control(dev->hcd, SetPortFeature, USB_PORT_FEAT_TEST, 0x300 + portNum, NULL, 0); break; case 0x0102: /* TEST_J */ dev->hcd->driver->hub_control(dev->hcd, SetPortFeature, USB_PORT_FEAT_TEST, 0x100 + portNum, NULL, 0); break; case 0x0103: /* TEST_K */ dev->hcd->driver->hub_control(dev->hcd, SetPortFeature, USB_PORT_FEAT_TEST, 0x200 + portNum, NULL, 0); break; case 0x0104: /* TEST_PACKET */ dev->hcd->driver->hub_control(dev->hcd, SetPortFeature, USB_PORT_FEAT_TEST, 0x400 + portNum, NULL, 0); break; case 0x0106: /* HS_HOST_PORT_SUSPEND_RESUME */ msleep(15000); dev->hcd->driver->hub_control(dev->hcd, SetPortFeature, USB_PORT_FEAT_SUSPEND, portNum, NULL, 0); msleep(15000); dev->hcd->driver->hub_control(dev->hcd, ClearPortFeature, USB_PORT_FEAT_SUSPEND, portNum, NULL, 0); break; case 0x0107: /* SINGLE_STEP_GET_DEV_DESC */ msleep(15000); retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RECIP_DEVICE, cpu_to_le16(USB_DT_DEVICE << 8), 0, dev->buf, USB_DT_DEVICE_SIZE, USB_CTRL_GET_TIMEOUT); break; case 0x0108: /* SINGLE_STEP_SET_FEATURE */ /* FIXME */ /* set size = 0 to ignore DATA phase */ retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RECIP_DEVICE, cpu_to_le16(USB_DT_DEVICE << 8), 0, dev->buf, 0, USB_CTRL_GET_TIMEOUT); msleep(15000); retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RECIP_DEVICE, cpu_to_le16(USB_DT_DEVICE << 8), 0, dev->buf, USB_DT_DEVICE_SIZE, USB_CTRL_GET_TIMEOUT); break; default: dev_info(&intf->dev, "unknown test mode with PID 0x%04x", id->idProduct); usb_notify_warning(dev->udev, USB_WARNING_NOT_SUPPORT); } return 0; }
static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB, USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT); }
/* * RPC done RNDIS-style. Caller guarantees: * - message is properly byteswapped * - there's no other request pending * - buf can hold up to 1KB response (required by RNDIS spec) * On return, the first few entries are already byteswapped. * * Call context is likely probe(), before interface name is known, * which is why we won't try to use it in the diagnostics. */ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) { struct cdc_state *info = (void *) &dev->data; struct usb_cdc_notification notification; int master_ifnum; int retval; int partial; unsigned count; __le32 rsp; u32 xid = 0, msg_len, request_id; /* REVISIT when this gets called from contexts other than probe() or * disconnect(): either serialize, or dispatch responses on xid */ /* Issue the request; xid is unique, don't bother byteswapping it */ if (likely(buf->msg_type != RNDIS_MSG_HALT && buf->msg_type != RNDIS_MSG_RESET)) { xid = dev->xid++; if (!xid) xid = dev->xid++; buf->request_id = (__force __le32) xid; } master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber; retval = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), USB_CDC_SEND_ENCAPSULATED_COMMAND, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, master_ifnum, buf, le32_to_cpu(buf->msg_len), RNDIS_CONTROL_TIMEOUT_MS); if (unlikely(retval < 0 || xid == 0)) return retval; /* Some devices don't respond on the control channel until * polled on the status channel, so do that first. */ retval = usb_interrupt_msg( dev->udev, usb_rcvintpipe(dev->udev, dev->status->desc.bEndpointAddress), ¬ification, sizeof(notification), &partial, RNDIS_CONTROL_TIMEOUT_MS); if (unlikely(retval < 0)) return retval; /* Poll the control channel; the request probably completed immediately */ rsp = buf->msg_type | RNDIS_MSG_COMPLETION; for (count = 0; count < 10; count++) { memset(buf, 0, CONTROL_BUFFER_SIZE); retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), USB_CDC_GET_ENCAPSULATED_RESPONSE, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, master_ifnum, buf, buflen, RNDIS_CONTROL_TIMEOUT_MS); if (likely(retval >= 8)) { msg_len = le32_to_cpu(buf->msg_len); request_id = (__force u32) buf->request_id; if (likely(buf->msg_type == rsp)) { if (likely(request_id == xid)) { if (unlikely(rsp == RNDIS_MSG_RESET_C)) return 0; if (likely(RNDIS_STATUS_SUCCESS == buf->status)) return 0; dev_dbg(&info->control->dev, "rndis reply status %08x\n", le32_to_cpu(buf->status)); return -EL3RST; } dev_dbg(&info->control->dev, "rndis reply id %d expected %d\n", request_id, xid); /* then likely retry */ } else switch (buf->msg_type) { case RNDIS_MSG_INDICATE: /* fault/event */ rndis_msg_indicate(dev, (void *)buf, buflen); break; case RNDIS_MSG_KEEPALIVE: { /* ping */ struct rndis_keepalive_c *msg = (void *)buf; msg->msg_type = RNDIS_MSG_KEEPALIVE_C; msg->msg_len = cpu_to_le32(sizeof *msg); msg->status = RNDIS_STATUS_SUCCESS; retval = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), USB_CDC_SEND_ENCAPSULATED_COMMAND, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, master_ifnum, msg, sizeof *msg, RNDIS_CONTROL_TIMEOUT_MS); if (unlikely(retval < 0)) dev_dbg(&info->control->dev, "rndis keepalive err %d\n", retval); } break; default: dev_dbg(&info->control->dev, "unexpected rndis msg %08x len %d\n", le32_to_cpu(buf->msg_type), msg_len); } } else { /* device probably issued a protocol stall; ignore */ dev_dbg(&info->control->dev, "rndis response error, code %d\n", retval); } msleep(20); } dev_dbg(&info->control->dev, "rndis response timeout\n"); return -ETIMEDOUT; }
static int usb_get_port_status(struct usb_device *dev, int port, void *data) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port, data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT); }
static inline int ssu100_getdevice(struct usb_device *dev, u8 *data) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), QT_SET_GET_DEVICE, 0xc0, 0, 0, data, 3, 300); }
_adapter *padapter=(_adapter *)intf_hdl->adapter; struct dvobj_priv *pdev=&padapter->dvobjpriv; struct usb_device *udev=pdev->pusbdev; _func_enter_; if((addr>>8)==0xfe){ DEBUG_INFO(("\n fe register read access!!\n")); status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, addr|0xfe00, 0, &res, 1, HZ / 2); } else{ DEBUG_INFO(("\n ff register read access!!\n")); status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL8187_REQ_GET_REGS, RTL8187_REQT_READ, (addr&0xff)|0xff00, (addr>>8)&0x03, &res, 1, HZ / 2); } if (status < 0) { DEBUG_ERR(("reg 0x%x, usb_read8 TimeOut! status:0x%x value=0x%x\n", addr, status,res)); } _func_exit_; return res; } u16 usb_read16(struct intf_hdl *intf_hdl, u32 addr)
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, struct wacom_features *features) { struct usb_device *dev = interface_to_usbdev(intf); char limit = 0; /* result has to be defined as int for some devices */ int result = 0; int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; unsigned char *report; report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); if (!report) return -ENOMEM; /* retrive report descriptors */ do { result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, HID_DEVICET_REPORT << 8, intf->altsetting[0].desc.bInterfaceNumber, /* interface */ report, hid_desc->wDescriptorLength, 5000); /* 5 secs */ } while (result < 0 && limit++ < 5); /* No need to parse the Descriptor. It isn't an error though */ if (result < 0) goto out; for (i = 0; i < hid_desc->wDescriptorLength; i++) { switch (report[i]) { case HID_USAGE_PAGE: switch (report[i + 1]) { case HID_USAGE_PAGE_DIGITIZER: usage = WCM_DIGITIZER; i++; break; case HID_USAGE_PAGE_DESKTOP: usage = WCM_DESKTOP; i++; break; } break; case HID_USAGE: switch (report[i + 1]) { case HID_USAGE_X: if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_DOUBLETAP; if (features->type == TABLETPC2FG) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_TPC2FG; features->device_type = BTN_TOOL_TRIPLETAP; } features->x_max = wacom_le16_to_cpu(&report[i + 3]); features->x_phy = wacom_le16_to_cpu(&report[i + 6]); features->unit = report[i + 9]; features->unitExpo = report[i + 11]; i += 12; } else if (pen) { /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->x_max = wacom_le16_to_cpu(&report[i + 3]); i += 4; } } else if (usage == WCM_DIGITIZER) { /* max pressure isn't reported features->pressure_max = (unsigned short) (report[i+4] << 8 | report[i + 3]); */ features->pressure_max = 255; i += 4; } break; case HID_USAGE_Y: if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_DOUBLETAP; if (features->type == TABLETPC2FG) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_TPC2FG; features->device_type = BTN_TOOL_TRIPLETAP; features->y_max = wacom_le16_to_cpu(&report[i + 3]); features->y_phy = wacom_le16_to_cpu(&report[i + 6]); i += 7; } else { features->y_max = features->x_max; features->y_phy = wacom_le16_to_cpu(&report[i + 3]); i += 4; } } else if (pen) { /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->y_max = wacom_le16_to_cpu(&report[i + 3]); i += 4; } } break; case HID_USAGE_FINGER: finger = 1; i++; break; case HID_USAGE_STYLUS: pen = 1; i++; break; case HID_USAGE_UNDEFINED: if (usage == WCM_DESKTOP && finger) /* capacity */ features->pressure_max = wacom_le16_to_cpu(&report[i + 3]); i += 4; break; } break; case HID_COLLECTION: /* reset UsagePage and Finger */ finger = usage = 0; break; } } out: result = 0; kfree(report); return result; }
static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) { struct usb_host_interface *current_setting; struct usb_endpoint_descriptor *desc; struct device *dev; u8 *buffer; int rv; int n; int actual = 0; int max_size; dev = &data->intf->dev; dev_dbg(dev, "Sending INITIATE_CLEAR request\n"); buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL); if (!buffer) return -ENOMEM; rv = usb_control_msg(data->usb_dev, usb_rcvctrlpipe(data->usb_dev, 0), USBTMC_REQUEST_INITIATE_CLEAR, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, 0, buffer, 1, USBTMC_TIMEOUT); if (rv < 0) { dev_err(dev, "usb_control_msg returned %d\n", rv); goto exit; } dev_dbg(dev, "INITIATE_CLEAR returned %x\n", buffer[0]); if (buffer[0] != USBTMC_STATUS_SUCCESS) { dev_err(dev, "INITIATE_CLEAR returned %x\n", buffer[0]); rv = -EPERM; goto exit; } max_size = 0; current_setting = data->intf->cur_altsetting; for (n = 0; n < current_setting->desc.bNumEndpoints; n++) { desc = ¤t_setting->endpoint[n].desc; if (desc->bEndpointAddress == data->bulk_in) max_size = usb_endpoint_maxp(desc); } if (max_size == 0) { dev_err(dev, "Couldn't get wMaxPacketSize\n"); rv = -EPERM; goto exit; } dev_dbg(dev, "wMaxPacketSize is %d\n", max_size); n = 0; usbtmc_clear_check_status: dev_dbg(dev, "Sending CHECK_CLEAR_STATUS request\n"); rv = usb_control_msg(data->usb_dev, usb_rcvctrlpipe(data->usb_dev, 0), USBTMC_REQUEST_CHECK_CLEAR_STATUS, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, 0, buffer, 2, USBTMC_TIMEOUT); if (rv < 0) { dev_err(dev, "usb_control_msg returned %d\n", rv); goto exit; } dev_dbg(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]); if (buffer[0] == USBTMC_STATUS_SUCCESS) goto usbtmc_clear_bulk_out_halt; if (buffer[0] != USBTMC_STATUS_PENDING) { dev_err(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]); rv = -EPERM; goto exit; } if (buffer[1] == 1) do { dev_dbg(dev, "Reading from bulk in EP\n"); rv = usb_bulk_msg(data->usb_dev, usb_rcvbulkpipe(data->usb_dev, data->bulk_in), buffer, USBTMC_SIZE_IOBUFFER, &actual, USBTMC_TIMEOUT); n++; if (rv < 0) { dev_err(dev, "usb_control_msg returned %d\n", rv); goto exit; } } while ((actual == max_size) && (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); if (actual == max_size) { dev_err(dev, "Couldn't clear device buffer within %d cycles\n", USBTMC_MAX_READS_TO_CLEAR_BULK_IN); rv = -EPERM; goto exit; } goto usbtmc_clear_check_status; usbtmc_clear_bulk_out_halt: rv = usb_clear_halt(data->usb_dev, usb_sndbulkpipe(data->usb_dev, data->bulk_out)); if (rv < 0) { dev_err(dev, "usb_control_msg returned %d\n", rv); goto exit; } rv = 0; exit: kfree(buffer); return rv; }