📄 hfa384x_usb.c
字号:
** Arguments:* hw device structure* cardaddr address in hfa384x data space to read* auxctl address space select* buf ptr to destination host buffer* len length of data to transfer (in bytes)** Returns: * nothing** Side effects:* buf contains the data copied** Call context:* process* interrupt----------------------------------------------------------------*/void hfa384x_copy_from_aux( hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len){ DBFENTER; WLAN_LOG_ERROR("not used in USB.\n"); DBFEXIT;}/*----------------------------------------------------------------* hfa384x_copy_to_aux** Copies a collection of bytes to the controller memory. The* Auxiliary port MUST be enabled prior to calling this function.* We _might_ be in a download state.** Arguments:* hw device structure* cardaddr address in hfa384x data space to read* auxctl address space select* buf ptr to destination host buffer* len length of data to transfer (in bytes)** Returns: * nothing** Side effects:* Controller memory now contains a copy of buf** Call context:* process* interrupt----------------------------------------------------------------*/void hfa384x_copy_to_aux( hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len){ DBFENTER; WLAN_LOG_ERROR("not used in USB.\n"); DBFEXIT;}/*----------------------------------------------------------------* hfa384x_corereset** Perform a reset of the hfa38xx MAC core. We assume that the hw * structure is in its "created" state. That is, it is initialized* with proper values. Note that if a reset is done after the * device has been active for awhile, the caller might have to clean * up some leftover cruft in the hw structure.** Arguments:* hw device structure* holdtime how long (in ms) to hold the reset* settletime how long (in ms) to wait after releasing* the reset** Returns: * nothing** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis){#if 0#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) struct usb_device *parent = hw->usb->parent; int i; int port = -1;#endif#endif int result = 0;#define P2_USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)#define P2_USB_FEAT_RESET 4#define P2_USB_FEAT_C_RESET 20 DBFENTER;#if 0#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) /* Find the hub port */ for ( i = 0; i < parent->maxchild; i++) { if (parent->children[i] == hw->usb) { port = i; break; } } if (port < 0) return -ENOENT; /* Set and clear the reset */ usb_control_msg(parent, usb_sndctrlpipe(parent, 0), USB_REQ_SET_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_RESET, port+1, NULL, 0, 1*HZ); wait_ms(holdtime); usb_control_msg(parent, usb_sndctrlpipe(parent, 0), USB_REQ_CLEAR_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_C_RESET, port+1, NULL, 0, 1*HZ); wait_ms(settletime); /* Set the device address */ result=usb_set_address(hw->usb); if (result < 0) { WLAN_LOG_ERROR("reset_usbdev: Dev not accepting address, " "result=%d\n", result); clear_bit(hw->usb->devnum, &hw->usb->bus->devmap.devicemap); hw->usb->devnum = -1; goto done; } /* Let the address settle */ wait_ms(20); /* Assume we're reusing the original descriptor data */ /* Set the configuration. */ WLAN_LOG_DEBUG(3, "Setting Configuration %d\n", hw->usb->config[0].bConfigurationValue); result=usb_set_configuration(hw->usb, hw->usb->config[0].bConfigurationValue); if ( result ) { WLAN_LOG_ERROR("usb_set_configuration() failed, result=%d.\n", result); goto done; } /* Let the configuration settle */ wait_ms(20); done: #else result=usb_reset_device(hw->usb); if(result<0) { WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result); }#endif#endif result=usb_reset_device(hw->usb); if(result<0) { WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result); } DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_usbctlx_complete_sync** Waits for a synchronous CTLX object to complete,* and then handles the response.** Arguments:* hw device structure* ctlx CTLX ptr* completor functor object to decide what to* do with the CTLX's result.** Returns:* 0 Success* -ERESTARTSYS Interrupted by a signal* -EIO CTLX failed* -ENODEV Adapter was unplugged* ??? Result from completor** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_usbctlx_complete_sync(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx, usbctlx_completor_t *completor){ unsigned long flags; int result; DBFENTER; result = wait_for_completion_interruptible(&ctlx->done); spin_lock_irqsave(&hw->ctlxq.lock, flags); /* * We can only handle the CTLX if the USB disconnect * function has not run yet ... */ cleanup: if ( hw->wlandev->hwremoved ) { spin_unlock_irqrestore(&hw->ctlxq.lock, flags); result = -ENODEV; } else if ( result != 0 ) { int runqueue = 0; /* * We were probably interrupted, so delete * this CTLX asynchronously, kill the timers * and the URB, and then start the next * pending CTLX. * * NOTE: We can only delete the timers and * the URB if this CTLX is active. */ if (ctlx == get_active_ctlx(hw)) { spin_unlock_irqrestore(&hw->ctlxq.lock, flags); del_singleshot_timer_sync(&hw->reqtimer); del_singleshot_timer_sync(&hw->resptimer); hw->req_timer_done = 1; hw->resp_timer_done = 1; usb_kill_urb(&hw->ctlx_urb); spin_lock_irqsave(&hw->ctlxq.lock, flags); runqueue = 1; /* * This scenario is so unlikely that I'm * happy with a grubby "goto" solution ... */ if ( hw->wlandev->hwremoved ) goto cleanup; } /* * The completion task will send this CTLX * to the reaper the next time it runs. We * are no longer in a hurry. */ ctlx->reapable = 1; ctlx->state = CTLX_REQ_FAILED; list_move_tail(&ctlx->list, &hw->ctlxq.completing); spin_unlock_irqrestore(&hw->ctlxq.lock, flags); if (runqueue) hfa384x_usbctlxq_run(hw); } else { if (ctlx->state == CTLX_COMPLETE) { result = completor->complete(completor); } else { WLAN_LOG_WARNING("CTLX[%d] error: state(%s)\n", hfa384x2host_16(ctlx->outbuf.type), ctlxstr(ctlx->state)); result = -EIO; } list_del(&ctlx->list); spin_unlock_irqrestore(&hw->ctlxq.lock, flags); kfree(ctlx); } DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_docmd** Constructs a command CTLX and submits it.** NOTE: Any changes to the 'post-submit' code in this function * need to be carried over to hfa384x_cbcmd() since the handling* is virtually identical.** Arguments:* hw device structure* mode DOWAIT or DOASYNC* cmd cmd structure. Includes all arguments and result* data points. All in host order. in host order* cmdcb command-specific callback* usercb user callback for async calls, NULL for DOWAIT calls* usercb_data user supplied data pointer for async calls, NULL* for DOASYNC calls** Returns: * 0 success* -EIO CTLX failure* -ERESTARTSYS Awakened on signal* >0 command indicated error, Status and Resp0-2 are* in hw structure.** Side effects:* ** Call context:* process ----------------------------------------------------------------*/static int hfa384x_docmd( hfa384x_t *hw, CMD_MODE mode, hfa384x_metacmd_t *cmd, ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data){ int result; hfa384x_usbctlx_t *ctlx; DBFENTER; ctlx = usbctlx_alloc(); if ( ctlx == NULL ) { result = -ENOMEM; goto done; } /* Initialize the command */ ctlx->outbuf.cmdreq.type = host2hfa384x_16(HFA384x_USB_CMDREQ); ctlx->outbuf.cmdreq.cmd = host2hfa384x_16(cmd->cmd); ctlx->outbuf.cmdreq.parm0 = host2hfa384x_16(cmd->parm0); ctlx->outbuf.cmdreq.parm1 = host2hfa384x_16(cmd->parm1); ctlx->outbuf.cmdreq.parm2 = host2hfa384x_16(cmd->parm2); ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq); WLAN_LOG_DEBUG(4, "cmdreq: cmd=0x%04x " "parm0=0x%04x parm1=0x%04x parm2=0x%04x\n", cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2); ctlx->reapable = mode; ctlx->cmdcb = cmdcb; ctlx->usercb = usercb; ctlx->usercb_data = usercb_data; result = hfa384x_usbctlx_submit(hw, ctlx); if (result != 0) { kfree(ctlx); } else if (mode == DOWAIT) { usbctlx_cmd_completor_t completor; result = hfa384x_usbctlx_complete_sync( hw, ctlx, init_cmd_completor(&completor, &ctlx->inbuf.cmdresp, &cmd->result) ); }done: DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_dorrid** Constructs a read rid CTLX and issues it.** NOTE: Any changes to the 'post-submit' code in this function * need to be carried over to hfa384x_cbrrid() since the handling* is virtually identical.** Arguments:* hw device structure* mode DOWAIT or DOASYNC* rid Read RID number (host order)* riddata Caller supplied buffer that MAC formatted RID.data * record will be written to for DOWAIT calls. Should* be NULL for DOASYNC calls.* riddatalen Buffer length for DOWAIT calls. Zero for DOASYNC calls.* cmdcb command callback for async calls, NULL for DOWAIT calls* usercb user callback for async calls, NULL for DOWAIT calls* usercb_data user supplied data pointer for async calls, NULL* for DOWAIT calls** Returns: * 0 success* -EIO CTLX failure* -ERESTARTSYS Awakened on signal* -ENODATA riddatalen != macdatalen* >0 command indicated error, Status and Resp0-2 are* in hw structure.** Side effects:* * Call context:* interrupt (DOASYNC)* process (DOWAIT or DOASYNC)----------------------------------------------------------------*/static inthfa384x_dorrid( hfa384x_t *hw, CMD_MODE mode, UINT16 rid, void *riddata, UINT riddatalen, ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data){ int result; hfa384x_usbctlx_t *ctlx; DBFENTER; ctlx = usbctlx_alloc(); if ( ctlx == NULL ) { result = -ENOMEM; goto done; } /* Initialize the command */ ctlx->outbuf.rridreq.type = host2hfa384x_16(HFA384x_USB_RRIDREQ); ctlx->outbuf.rridreq.frmlen = host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid)); ctlx->outbuf.rridreq.rid = host2hfa384x_16(rid); ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq); ctlx->reapable = mode; ctlx->cmdcb = cmdcb; ctlx->usercb = usercb; ctlx->usercb_data = usercb_data; /* Submit the CTLX */ result = hfa384x_usbctlx_submit(hw, ctlx); if (result != 0) { kfree(ctlx); } else if (mode == DOWAIT) { usbctlx_rrid_completor_t completor; result = hfa384x_usbctlx_complete_sync( hw, ctlx, init_rrid_completor(&completor, &ctlx->inbuf.rridresp, riddata, riddatalen) ); }done: DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_dowrid** Constructs a write rid CTLX and issues it.** NOTE: Any changes to the 'post-submit' code in this function * need to be carried over to hfa384x_cbwrid() since the handling* is virtually identical.** Arguments:* hw device structure* CMD_MODE DOWAIT or DOASYNC* rid RID code* riddata Data portion of RID formatted for MAC* riddatalen Length of the data portion in bytes* cmdcb command callback for async calls, NULL for DOWAIT calls* usercb user callback for async calls, NULL for DOWAIT calls* usercb_data user supplied data pointer for async calls** Returns: * 0 success* -ETIMEDOUT timed out waiting for register ready or* command completion* >0 command indicated error, Status and Resp0-2 are* in hw structure.** Side effects:* * Call context:* interrupt (DOASYNC)* process (DOWAIT or DOASYNC)----------------------------------------------------------------*/inthfa384x_dowrid( hfa384x_t *hw, CMD_MODE mode, UINT16 rid, void *riddata, UINT riddatalen, ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -