static int new_usb_control_msg2(struct usb_ctrlrequest *dr, struct urb *urb, struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout) { static volatile int done=1; unsigned long expire; int status; int retval; if(done==0) { //printk("%s, %d, done=%d, busy!\n", __func__, __LINE__, done); return -EBUSY; } dr->bRequestType= requesttype; dr->bRequest = request; dr->wValue = cpu_to_le16p(&value); dr->wIndex = cpu_to_le16p(&index); dr->wLength = cpu_to_le16p(&size); done = 0; usb_fill_control_urb(urb, dev, pipe, (unsigned char *)dr, data, size, new_usb_api_blocking_completion, (void *)&done); dma_cache_wback_inv((unsigned long)data, size); urb->actual_length = 0; urb->status = 0; status = usb_submit_urb(urb, GFP_ATOMIC); return status; }
/* Send a generic nonblocking control request, without completion notification. * This is safe for use in interrupt context. */ static void rwand_nb_request(struct rwand_dev *dev, unsigned short request, unsigned short wValue, unsigned short wIndex) { int retval; struct urb *urb; struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); if (!dr) { err("Out of memory in rwand_nb_request"); return; } dr->bRequestType = USB_TYPE_VENDOR; dr->bRequest = request; dr->wValue = cpu_to_le16p(&wValue); dr->wIndex = cpu_to_le16p(&wIndex); dr->wLength = 0; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { kfree(dr); err("Out of memory in rwand_nb_request"); return; } usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), (unsigned char*)dr, NULL, 0, rwand_nb_irq, dr); retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) { dbg("Error in rwand_nb_request, retval=%d", retval); } }
int PIPEnsControlOut( PSDevice pDevice, BYTE byRequest, WORD wValue, WORD wIndex, WORD wLength, PBYTE pbyBuffer ) { int ntStatus = 0; int ii; if (pDevice->Flags & fMP_DISCONNECTED) return STATUS_FAILURE; if (pDevice->Flags & fMP_CONTROL_WRITES) return STATUS_FAILURE; pDevice->sUsbCtlRequest.bRequestType = 0x40; pDevice->sUsbCtlRequest.bRequest = byRequest; pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue); pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex); pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength); pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK; pDevice->pControlURB->actual_length = 0; // Notice, pbyBuffer limited point to variable buffer, can't be constant. usb_fill_control_urb(pDevice->pControlURB, pDevice->usb, usb_sndctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest, pbyBuffer, wLength, s_nsControlInUsbIoCompleteWrite, pDevice); ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC); if (ntStatus != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission failed: %d\n", ntStatus); return STATUS_FAILURE; } else { MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES); } spin_unlock_irq(&pDevice->lock); for (ii = 0; ii <= USB_CTL_WAIT; ii ++) { if (pDevice->Flags & fMP_CONTROL_WRITES) mdelay(1); else break; if (ii >= USB_CTL_WAIT) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "control send request submission timeout\n"); spin_lock_irq(&pDevice->lock); MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES); return STATUS_FAILURE; } } spin_lock_irq(&pDevice->lock); return STATUS_SUCCESS; }
int PIPEnsControlIn(struct vnt_private *pDevice, u8 byRequest, u16 wValue, u16 wIndex, u16 wLength, u8 *pbyBuffer) { int ntStatus = 0; int ii; if (pDevice->Flags & fMP_DISCONNECTED) return STATUS_FAILURE; if (pDevice->Flags & fMP_CONTROL_READS) return STATUS_FAILURE; if (pDevice->Flags & fMP_CONTROL_WRITES) return STATUS_FAILURE; MP_SET_FLAG(pDevice, fMP_CONTROL_READS); pDevice->sUsbCtlRequest.bRequestType = 0xC0; pDevice->sUsbCtlRequest.bRequest = byRequest; pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue); pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex); pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength); pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK; pDevice->pControlURB->actual_length = 0; usb_fill_control_urb(pDevice->pControlURB, pDevice->usb, usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest, pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice); ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC); if (ntStatus != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "control request submission failed: %d\n", ntStatus); MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS); return STATUS_FAILURE; } spin_unlock_irq(&pDevice->lock); for (ii = 0; ii <= USB_CTL_WAIT; ii ++) { if (pDevice->Flags & fMP_CONTROL_READS) mdelay(1); else break; if (ii >= USB_CTL_WAIT) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "control rcv request submission timeout\n"); spin_lock_irq(&pDevice->lock); MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS); return STATUS_FAILURE; } } spin_lock_irq(&pDevice->lock); return ntStatus; }
static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, void *data) { int ret; char *buffer; DECLARE_WAITQUEUE(wait, current); buffer = kmalloc(size, GFP_KERNEL); if (!buffer) { warn("%s: looks like we're out of memory", __FUNCTION__); return -ENOMEM; } memcpy(buffer, data, size); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); while (pegasus->flags & ETH_REGS_CHANGED) schedule(); remove_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_RUNNING); pegasus->dr.bRequestType = PEGASUS_REQT_WRITE; pegasus->dr.bRequest = PEGASUS_REQ_SET_REGS; pegasus->dr.wValue = cpu_to_le16(0); pegasus->dr.wIndex = cpu_to_le16p(&indx); pegasus->dr.wLength = cpu_to_le16p(&size); pegasus->ctrl_urb->transfer_buffer_length = size; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), (char *) &pegasus->dr, buffer, size, ctrl_callback, pegasus); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { err("%s: BAD CTRL %d", __FUNCTION__, ret); goto out; } schedule(); out: remove_wait_queue(&pegasus->ctrl_wait, &wait); kfree(buffer); return ret; }
static int brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) { int ret; u16 size; brcmf_dbg(USB, "Enter\n"); if (devinfo == NULL || buf == NULL || len == 0 || devinfo->ctl_urb == NULL) return -EINVAL; size = len; devinfo->ctl_write.wLength = cpu_to_le16p(&size); devinfo->ctl_urb->transfer_buffer_length = size; devinfo->ctl_urb_status = 0; devinfo->ctl_urb_actual_length = 0; usb_fill_control_urb(devinfo->ctl_urb, devinfo->usbdev, devinfo->ctl_out_pipe, (unsigned char *) &devinfo->ctl_write, buf, size, (usb_complete_t)brcmf_usb_ctlwrite_complete, devinfo); ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); if (ret < 0) brcmf_err("usb_submit_urb failed %d\n", ret); return ret; }
static int brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) { int ret; u16 size; brcmf_dbg(USB, "Enter\n"); if ((devinfo == NULL) || (buf == NULL) || (len == 0) || (devinfo->ctl_urb == NULL)) return -EINVAL; size = len; devinfo->ctl_read.wLength = cpu_to_le16p(&size); devinfo->ctl_urb->transfer_buffer_length = size; devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; devinfo->ctl_read.bRequest = 1; usb_fill_control_urb(devinfo->ctl_urb, devinfo->usbdev, devinfo->ctl_in_pipe, (unsigned char *) &devinfo->ctl_read, buf, size, (usb_complete_t)brcmf_usb_ctlread_complete, devinfo); ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); if (ret < 0) brcmf_err("usb_submit_urb failed %d\n", ret); return ret; }
static inline void get_node_id(pegasus_t * pegasus, __u8 * id) { int i; __u16 w16; for (i = 0; i < 3; i++) { read_eprom_word(pegasus, i, &w16); ((__u16 *) id)[i] = cpu_to_le16p(&w16); } }
void tdsp_usb_set_ctrlreq(void * ctrl_req,void * req) { struct usb_ctrlrequest* set_up = (struct usb_ctrlrequest*)ctrl_req; PTDSP_USB_CTRLREQ req_cntxt= (PTDSP_USB_CTRLREQ)req; if(NULL == set_up) { printk("%s: ctlr req is NULL\n",__FUNCTION__); } if(NULL == ctrl_req) { printk("%s: input req is NULL\n",__FUNCTION__); } set_up->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; set_up->bRequest = req_cntxt->request; set_up->wValue = cpu_to_le16p(&req_cntxt->value); set_up->wIndex = cpu_to_le16p(&req_cntxt->index); set_up->wLength = cpu_to_le16p((unsigned short *)&req_cntxt->len); }
/** * usb_control_msg - Builds a control urb, sends it off and waits for completion * @dev: pointer to the usb device to send the message to * @pipe: endpoint "pipe" to send the message to * @request: USB message request value * @requesttype: USB message request type value * @value: USB message value * @index: USB message index value * @data: pointer to the data to send * @size: length in bytes of the data to send * @timeout: time in jiffies to wait for the message to complete before * timing out (if 0 the wait is forever) * Context: !in_interrupt () * * This function sends a simple control message to a specified endpoint * and waits for the message to complete, or timeout. * * If successful, it returns the number of bytes transferred, otherwise a negative error number. * * Don't use this function from within an interrupt context, like a * bottom half handler. If you need an asynchronous message, or need to send * a message from within interrupt context, use usb_submit_urb() * If a thread in your driver uses this call, make sure your disconnect() * method can wait for it to complete. Since you don't have a handle on * the URB used, you can't cancel the request. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout) { struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); int ret; if (!dr) return -ENOMEM; dr->bRequestType= requesttype; dr->bRequest = request; dr->wValue = cpu_to_le16p(&value); dr->wIndex = cpu_to_le16p(&index); dr->wLength = cpu_to_le16p(&size); //dbg("usb_control_msg"); ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout); kfree(dr); return ret; }
static void usb_ctrl_msg(struct st5481_adapter *adapter, u8 request, u8 requesttype, u16 value, u16 index, ctrl_complete_t complete, void *context) { struct st5481_ctrl *ctrl = &adapter->ctrl; int w_index; struct ctrl_msg *ctrl_msg; if ((w_index = fifo_add(&ctrl->msg_fifo.f)) < 0) { WARNING("control msg FIFO full"); return; } ctrl_msg = &ctrl->msg_fifo.data[w_index]; ctrl_msg->dr.bRequestType = requesttype; ctrl_msg->dr.bRequest = request; ctrl_msg->dr.wValue = cpu_to_le16p(&value); ctrl_msg->dr.wIndex = cpu_to_le16p(&index); ctrl_msg->dr.wLength = 0; ctrl_msg->complete = complete; ctrl_msg->context = context; usb_next_ctrl_msg(ctrl->urb, adapter); }
static int brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, void *buffer, int buflen) { int ret; char *tmpbuf; u16 size; if ((!devinfo) || (devinfo->ctl_urb == NULL)) return -EINVAL; tmpbuf = kmalloc(buflen, GFP_ATOMIC); if (!tmpbuf) return -ENOMEM; size = buflen; devinfo->ctl_urb->transfer_buffer_length = size; devinfo->ctl_read.wLength = cpu_to_le16p(&size); devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE; devinfo->ctl_read.bRequest = cmd; usb_fill_control_urb(devinfo->ctl_urb, devinfo->usbdev, usb_rcvctrlpipe(devinfo->usbdev, 0), (unsigned char *) &devinfo->ctl_read, (void *) tmpbuf, size, (usb_complete_t)brcmf_usb_sync_complete, devinfo); devinfo->ctl_completed = false; ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); if (ret < 0) { brcmf_err("usb_submit_urb failed %d\n", ret); goto finalize; } if (!brcmf_usb_ioctl_resp_wait(devinfo)) { usb_kill_urb(devinfo->ctl_urb); ret = -ETIMEDOUT; } else { memcpy(buffer, tmpbuf, buflen); } finalize: kfree(tmpbuf); return ret; }
static void ecos_usbeth_set_rx_mode(struct net_device* net) { ecos_usbeth* usbeth = (ecos_usbeth*) net->priv; __u16 promiscuous = net->flags & IFF_PROMISC; int res; if (promiscuous != usbeth->target_promiscuous) { devrequest* req; urb_t* urb; urb = usb_alloc_urb(0); if ((urb_t*)0 == urb) { return; } req = kmalloc(sizeof(devrequest), GFP_KERNEL); if ((devrequest*)0 == req) { usb_free_urb(urb); return; } req->requesttype = USB_TYPE_CLASS | USB_RECIP_DEVICE; req->request = ECOS_USBETH_CONTROL_SET_PROMISCUOUS_MODE; req->value = cpu_to_le16p(&promiscuous); req->index = 0; req->length = 0; FILL_CONTROL_URB(urb, usbeth->usb_dev, usb_sndctrlpipe(usbeth->usb_dev, 0), (unsigned char*) req, (void*) 0, 0, &ecos_usbeth_set_rx_mode_callback, (void*) usbeth); res = usb_submit_urb(urb); if (0 != res) { kfree(req); usb_free_urb(urb); } else { usbeth->target_promiscuous = promiscuous; } } }
static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, void *buffer, int buflen) { int ret = 0; char *tmpbuf; u16 size; if ((!devinfo) || (devinfo->ctl_urb == NULL)) return false; tmpbuf = kmalloc(buflen, GFP_ATOMIC); if (!tmpbuf) return false; size = buflen; devinfo->ctl_urb->transfer_buffer_length = size; devinfo->ctl_read.wLength = cpu_to_le16p(&size); devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE; devinfo->ctl_read.bRequest = cmd; usb_fill_control_urb(devinfo->ctl_urb, devinfo->usbdev, usb_rcvctrlpipe(devinfo->usbdev, 0), (unsigned char *) &devinfo->ctl_read, (void *) tmpbuf, size, (usb_complete_t)brcmf_usb_sync_complete, devinfo); ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); if (ret < 0) { brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); kfree(tmpbuf); return false; } ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT); memcpy(buffer, tmpbuf, buflen); kfree(tmpbuf); return (ret == 0); }
static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) { int i; __u8 data[4] = { phy, 0, 0, indx }; *(data + 1) = cpu_to_le16p(®d); set_register(pegasus, PhyCtrl, 0); set_registers(pegasus, PhyAddr, 4, data); set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); for (i = 0; i < REG_TIMEOUT; i++) { get_registers(pegasus, PhyCtrl, 1, data); if (data[0] & PHY_DONE) break; } if (i < REG_TIMEOUT) return 0; warn("%s: failed", __FUNCTION__); return 1; }
static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg) { int i; u8 data[3], tmp; data[0] = phy; *(data + 1) = cpu_to_le16p(®); tmp = indx | PHY_WRITE | PHY_GO; i = 0; set_registers(dev, PHYADD, sizeof(data), data); set_registers(dev, PHYCNT, 1, &tmp); do { get_registers(dev, PHYCNT, 1, data); } while ((data[0] & PHY_GO) && (i++ < HZ)); if (i < HZ) return 0; else return 1; }
static int brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) { int ret; u16 size; if ((devinfo == NULL) || (buf == NULL) || (len == 0) || (devinfo->ctl_urb == NULL)) return -EINVAL; size = len; devinfo->ctl_read.wLength = cpu_to_le16p(&size); devinfo->ctl_urb->transfer_buffer_length = size; if (devinfo->rxctl_deferrespok) { /* BMAC model */ devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE; devinfo->ctl_read.bRequest = DL_DEFER_RESP_OK; } else { /* full dongle model */ devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; devinfo->ctl_read.bRequest = 1; } usb_fill_control_urb(devinfo->ctl_urb, devinfo->usbdev, devinfo->ctl_in_pipe, (unsigned char *) &devinfo->ctl_read, buf, size, (usb_complete_t)brcmf_usb_ctlread_complete, devinfo); ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); if (ret < 0) brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); return ret; }
static int brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) { int ret; u16 size; if (devinfo == NULL || buf == NULL || len == 0 || devinfo->ctl_urb == NULL) return -EINVAL; /* If the USB/HSIC bus in sleep state, wake it up */ if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { brcmf_dbg(ERROR, "Could not Resume the bus!\n"); return -EIO; } devinfo->activity = true; size = len; devinfo->ctl_write.wLength = cpu_to_le16p(&size); devinfo->ctl_urb->transfer_buffer_length = size; devinfo->ctl_urb_status = 0; devinfo->ctl_urb_actual_length = 0; usb_fill_control_urb(devinfo->ctl_urb, devinfo->usbdev, devinfo->ctl_out_pipe, (unsigned char *) &devinfo->ctl_write, buf, size, (usb_complete_t)brcmf_usb_ctlwrite_complete, devinfo); ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); if (ret < 0) brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); return ret; }
static int brcmf_usb_up(struct device *dev) { struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); u16 ifnum; if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) return 0; /* If the USB/HSIC bus in sleep state, wake it up */ if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) { if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { brcmf_dbg(ERROR, "Could not Resume the bus!\n"); return -EIO; } } devinfo->activity = true; /* Success, indicate devinfo is fully up */ brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP); if (devinfo->intr_urb) { int ret; usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev, devinfo->intr_pipe, &devinfo->intr, devinfo->intr_size, (usb_complete_t)brcmf_usb_intr_complete, devinfo, devinfo->interval); ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); if (ret) { brcmf_dbg(ERROR, "USB_SUBMIT_URB failed with status %d\n", ret); return -EINVAL; } } if (devinfo->ctl_urb) { devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0); devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0); ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber; /* CTL Write */ devinfo->ctl_write.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; devinfo->ctl_write.bRequest = 0; devinfo->ctl_write.wValue = cpu_to_le16(0); devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum); /* CTL Read */ devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; devinfo->ctl_read.bRequest = 1; devinfo->ctl_read.wValue = cpu_to_le16(0); devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum); } brcmf_usb_rx_fill_all(devinfo); return 0; }
int new_usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout) { #ifdef CONFIG_ENABLE_MIPS16 u8 *dma_data=kmalloc(16,GFP_NOIO); #endif struct usb_ctrlrequest *dr; struct urb *urb; volatile int done=0; unsigned long expire; int retry_cnt=0; int status; int retval; #ifdef USB_LOCK_ENABLE unsigned long flags; #endif dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); if (!dr) { return -ENOMEM; } dr->bRequestType= requesttype; dr->bRequest = request; dr->wValue = cpu_to_le16p(&value); dr->wIndex = cpu_to_le16p(&index); dr->wLength = cpu_to_le16p(&size); if((value==0x300)||(value==0x320)) { printk("Can't submit control msg value=%x\n",value); if(size==4) *(u32*)(data)=0; else if(size==1) *(u8*)(data)=0; else if(size==2) *(u16*)(data)=0; kfree(dr); return 0; } #ifdef __LINUX_2_6__ urb = usb_alloc_urb(0, GFP_ATOMIC); #else urb = usb_alloc_urb(0); #endif if (!urb) { kfree(dr); return -ENOMEM; } usb_control_cnt++; if(usb_control_cnt>1) printk("Error usb_control_cnt=%x\n",usb_control_cnt); // printk("fill urb data=%x indx=%x size=%d\n",*(u8*)data,index,size); #ifdef CONFIG_ENABLE_MIPS16 usb_fill_control_urb(urb, dev, pipe, (unsigned char *)dr, (void*)dma_data, size, new_usb_api_blocking_completion, (void *)&done); #else usb_fill_control_urb(urb, dev, pipe, (unsigned char *)dr, data, size, new_usb_api_blocking_completion, (void *)&done); #endif urb->actual_length = 0; #ifdef CONFIG_ENABLE_MIPS16 if(request==RTL8192_REQ_SET_REGS) memcpy(dma_data,data,size); dma_cache_wback_inv((u32)dma_data,size); //rtl_cache_sync_wback(priv, (unsigned int)dma_data, size, 0); #else if(request==RTL8192_REQ_SET_REGS) dma_cache_wback_inv((unsigned long)data, size); #endif #ifdef __LINUX_2_6__ status = usb_submit_urb(urb, GFP_ATOMIC); #else status = usb_submit_urb(urb); #endif if (unlikely(status)) { goto out; } if(timeout) //expire = msecs_to_jiffies(timeout) + jiffies; expire = timeout + jiffies; else expire = 200 + jiffies; //cathy if(expire<200) { if(!in_atomic()) { delay_ms(2100); expire=jiffies+200; } else expire=0xffffffffL; } retry: if(done==1) goto out; if(jiffies>=expire) goto out; #ifndef USB_LOCK_ENABLE if(in_atomic()) #endif { unsigned long flags=0; retry_cnt++; if(retry_cnt>2000) goto out; #ifdef CONFIG_USB_OTG_Driver dwc_otg_hcd_irq(usbhcd, NULL); printk("%s %d done=%x jiffies=%x expire=%x\n",__FUNCTION__,__LINE__,done,jiffies,expire); #elif defined(CONFIG_USB_OTG_HOST_RTL8672) usb_scan_async(dev->bus, 0); #elif defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_RTL8652) { struct usb_hcd *hcd=bus_to_hcd(dev->bus); #ifdef __LINUX_2_6__ struct ehci_hcd *ehci=(struct ehci_hcd *)hcd->hcd_priv; spin_lock_irqsave (&ehci->lock, flags); //scan_async(ehci); ehci_irq(hcd); spin_unlock_irqrestore (&ehci->lock, flags); #else ehci_irq(hcd, NULL); #endif } #endif } #ifndef USB_LOCK_ENABLE else schedule(); #endif goto retry; out: if(retry_cnt>2000) { printk("Timeout! requesttype=%x request=%x value=%x index=%x size=%x retry_cnt=%d\n",requesttype,request,value,index,size,retry_cnt); } if(done==0) { #if 0 printk("USB Timeout!!!\n"); if(!in_atomic()) { usb_kill_urb(urb); } else { printk("in atomic, can't kill urb\n"); } status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; #else retval = new_usb_kill_urb(urb); status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; if((status != 0) && (status!= -ETIMEDOUT)) { printk("[%s,%d], urb->status = %d, retval = %d\n", __func__, __LINE__, urb->status, retval); } #endif } else { // printk("index=%x data=%x done\n",index,*(u8*)data); #ifdef CONFIG_ENABLE_MIPS16 if(request==RTL8192_REQ_GET_REGS) memcpy(data,dma_data,size); #endif status = urb->status; } usb_free_urb(urb); #ifdef CONFIG_ENABLE_MIPS16 kfree(dma_data); #endif kfree(dr); usb_control_cnt--; return status; }