void rtw_stop_drv_threads (_adapter *padapter)
{
	RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_stop_drv_threads\n"));	

	//Below is to termindate rtw_cmd_thread & event_thread...
	_rtw_up_sema(&padapter->cmdpriv.cmd_queue_sema);
	//_rtw_up_sema(&padapter->cmdpriv.cmd_done_sema);
	if(padapter->cmdThread){
		_rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);
	}

#ifdef CONFIG_EVENT_THREAD_MODE
        _rtw_up_sema(&padapter->evtpriv.evt_notify);
	if(padapter->evtThread){
		_rtw_down_sema(&padapter->evtpriv.terminate_evtthread_sema);
	}
#endif

#ifdef CONFIG_XMIT_THREAD_MODE
	// Below is to termindate tx_thread...
	_rtw_up_sema(&padapter->xmitpriv.xmit_sema);	
	_rtw_down_sema(&padapter->xmitpriv.terminate_xmitthread_sema);
	RT_TRACE(_module_os_intfs_c_,_drv_info_,("\n drv_halt: rtw_xmit_thread can be terminated ! \n"));
#endif
	 
#ifdef CONFIG_RECV_THREAD_MODE	
	// Below is to termindate rx_thread...
	_rtw_up_sema(&padapter->recvpriv.recv_sema);
	_rtw_down_sema(&padapter->recvpriv.terminate_recvthread_sema);
	RT_TRACE(_module_os_intfs_c_,_drv_info_,("\n drv_halt:recv_thread can be terminated! \n"));
#endif


}
/*
 * Description
 *	Transmit xmitbuf to hardware tx fifo
 *
 * Return
 *	_SUCCESS	ok
 *	_FAIL		something error
 */
s32 rtl8723as_xmit_buf_handler(PADAPTER padapter)
{
	PHAL_DATA_TYPE phal;
	struct mlme_priv *pmlmepriv;
	struct xmit_priv *pxmitpriv;
	struct dvobj_priv	*pdvobjpriv;
	struct xmit_buf *pxmitbuf;
	struct xmit_frame *pframe;
	u8 *freePage;
	u32 deviceId;
	u32 requiredPage;
	u8 PageIdx, queue_empty;
	_irqL irql;
	u32 n;
	s32 ret;


	phal = GET_HAL_DATA(padapter);
	pmlmepriv = &padapter->mlmepriv;
	pxmitpriv = &padapter->xmitpriv;
	pdvobjpriv = adapter_to_dvobj(padapter);
	freePage = phal->SdioTxFIFOFreePage;

	ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
	if (_FAIL == ret) {
		RT_TRACE(_module_hal_xmit_c_, _drv_emerg_,
				 ("%s: down SdioXmitBufSema fail!\n", __FUNCTION__));
		return _FAIL;
	}

	ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
	if (ret) {
		RT_TRACE(_module_hal_xmit_c_, _drv_err_,
				 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
				  __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
		return _FAIL;
	}

#ifdef CONFIG_LPS_LCLK
	ret = rtw_register_tx_alive(padapter);
	if (ret != _SUCCESS) {
		return _SUCCESS;
	}
#endif

	do {
		queue_empty = rtl8723_dequeue_writeport(padapter, freePage);
//	dump secondary adapter xmitbuf 
#ifdef CONFIG_CONCURRENT_MODE
		if(rtw_buddy_adapter_up(padapter))
			queue_empty &= rtl8723_dequeue_writeport(padapter->pbuddy_adapter, freePage);
#endif
	} while ( !queue_empty);
	
#ifdef CONFIG_LPS_LCLK
	rtw_unregister_tx_alive(padapter);
#endif

	return _SUCCESS;
}
u32 rtw_start_drv_threads(_adapter *padapter)
{

	u32 _status = _SUCCESS;

	RT_TRACE(_module_os_intfs_c_,_drv_info_,("+rtw_start_drv_threads\n"));

#ifdef CONFIG_SDIO_HCI
	padapter->xmitThread = kernel_thread(rtw_xmit_thread, padapter, CLONE_FS|CLONE_FILES);
	if(padapter->xmitThread < 0)
		_status = _FAIL;
#endif

#ifdef CONFIG_RECV_THREAD_MODE
	padapter->recvThread = kernel_thread(recv_thread, padapter, CLONE_FS|CLONE_FILES);
	if(padapter->recvThread < 0)
		_status = _FAIL;	
#endif

	padapter->cmdThread = kernel_thread(rtw_cmd_thread, padapter, CLONE_FS|CLONE_FILES);
	if(padapter->cmdThread < 0)
		_status = _FAIL;
	else
		_rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); //wait for cmd_thread to run
		

#ifdef CONFIG_EVENT_THREAD_MODE
	padapter->evtThread = kernel_thread(event_thread, padapter, CLONE_FS|CLONE_FILES);
	if(padapter->evtThread < 0)
		_status = _FAIL;		
#endif

	return _status;

}
Пример #4
0
/*
 * Description
 *	Transmit xmitframe from queue
 *
 * Return
 *	_SUCCESS	ok
 *	_FAIL		something error
 */
s32 rtl8723bs_xmit_handler(PADAPTER padapter)
{
    struct xmit_priv *pxmitpriv;
    s32 ret;
    _irqL irql;


    pxmitpriv = &padapter->xmitpriv;

wait:
    ret = _rtw_down_sema(&pxmitpriv->SdioXmitSema);
    if (_FAIL == ret) {
        DBG_871X_LEVEL(_drv_emerg_, "%s: down sema fail!\n", __FUNCTION__);
        return _FAIL;
    }

next:
    if ((padapter->bDriverStopped == _TRUE) ||
            (padapter->bSurpriseRemoved == _TRUE)) {
        RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
                 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)\n",
                  __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
        return _FAIL;
    }

    _enter_critical_bh(&pxmitpriv->lock, &irql);
    ret = rtw_txframes_pending(padapter);
    _exit_critical_bh(&pxmitpriv->lock, &irql);
    if (ret == 0) {
        if(!padapter->registrypriv.wifi_spec)
            rtw_yield_os();
        return _SUCCESS;
    }

    // dequeue frame and write to hardware

    ret = xmit_xmitframes(padapter, pxmitpriv);
    if (ret == -2) {
        //here sleep 1ms will cause big TP loss of TX
        //from 50+ to 40+
        if(padapter->registrypriv.wifi_spec)
            rtw_msleep_os(1);
        else
            rtw_yield_os();
        goto next;
    }

    _enter_critical_bh(&pxmitpriv->lock, &irql);
    ret = rtw_txframes_pending(padapter);
    _exit_critical_bh(&pxmitpriv->lock, &irql);
    if (ret == 1) {
        //rtw_msleep_os(1);
        goto next;
    }

    return _SUCCESS;
}
Пример #5
0
void rtw_stop_drv_threads(struct adapter *padapter)
{
	RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_stop_drv_threads\n"));

	/* Below is to termindate rtw_cmd_thread & event_thread... */
	up(&padapter->cmdpriv.cmd_queue_sema);
	if (padapter->cmdThread)
		_rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);

}
Пример #6
0
/*
 * Description
 *	Transmit xmitbuf to hardware tx fifo
 *
 * Return
 *	_SUCCESS	ok
 *	_FAIL		something error
 */
s32 rtl8812au_xmit_buf_handler(PADAPTER padapter)
{
	PHAL_DATA_TYPE phal;
	struct xmit_priv *pxmitpriv;
	struct xmit_buf *pxmitbuf;
	s32 ret;


	phal = GET_HAL_DATA(padapter);
	pxmitpriv = &padapter->xmitpriv;

	ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
	if (_FAIL == ret) {
		RT_TRACE(_module_hal_xmit_c_, _drv_emerg_,
				 ("%s: down SdioXmitBufSema fail!\n", __FUNCTION__));
		return _FAIL;
	}

	ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
	if (ret) {
		RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
				 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
				  __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
		return _FAIL;
	}

	if(check_pending_xmitbuf(pxmitpriv) == _FALSE)
		return _SUCCESS;

#ifdef CONFIG_LPS_LCLK
	ret = rtw_register_tx_alive(padapter);
	if (ret != _SUCCESS) {
		RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
				 ("%s: wait to leave LPS_LCLK\n", __FUNCTION__));
		return _SUCCESS;
	}
#endif

	do {
		pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
		if (pxmitbuf == NULL) break;

		rtw_write_port(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char*)pxmitbuf);

	} while (1);

#ifdef CONFIG_LPS_LCLK
	rtw_unregister_tx_alive(padapter);
#endif

	return _SUCCESS;
}
/*
 * Description
 *	Transmit xmitframe from queue
 *
 * Return
 *	_SUCCESS	ok
 *	_FAIL		something error
 */
s32 rtl8723as_xmit_handler(PADAPTER padapter)
{
	struct xmit_priv *pxmitpriv;
	PHAL_DATA_TYPE phal;
	s32 ret;
	_irqL irql;


	pxmitpriv = &padapter->xmitpriv;
	phal = GET_HAL_DATA(padapter);

wait:
	ret = _rtw_down_sema(&phal->SdioXmitSema);
	if (_FAIL == ret) {
		RT_TRACE(_module_hal_xmit_c_, _drv_emerg_, ("%s: down sema fail!\n", __FUNCTION__));
		return _FAIL;
	}

next:
	if ((padapter->bDriverStopped == _TRUE) ||
		(padapter->bSurpriseRemoved == _TRUE)) {
		RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
				 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)\n",
				  __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
		return _FAIL;
	}

	_enter_critical_bh(&pxmitpriv->lock, &irql);
	ret = rtw_txframes_pending(padapter);
	_exit_critical_bh(&pxmitpriv->lock, &irql);
	if (ret == 0) {
		return _SUCCESS;
	}

	// dequeue frame and write to hardware

	ret = xmit_xmitframes(padapter, pxmitpriv);
	if (ret == -2) {
		rtw_msleep_os(1);
		goto next;
	}

	_enter_critical_bh(&pxmitpriv->lock, &irql);
	ret = rtw_txframes_pending(padapter);
	_exit_critical_bh(&pxmitpriv->lock, &irql);
	if (ret == 1) {
		rtw_msleep_os(1);
		goto next;
	}

	return _SUCCESS;
}
Пример #8
0
u32 rtw_start_drv_threads(struct adapter *padapter)
{
	u32 _status = _SUCCESS;

	RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_start_drv_threads\n"));

	padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter, "RTW_CMD_THREAD");
	if (IS_ERR(padapter->cmdThread))
		_status = _FAIL;
	else
		_rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); /* wait for cmd_thread to run */

	return _status;
}
Пример #9
0
static int rtw_start_drv_threads(struct adapter *padapter)
{
	int err = 0;

	RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_start_drv_threads\n"));

	padapter->cmdThread = kthread_run(rtw_cmd_thread, padapter,
					  "RTW_CMD_THREAD");
	if (IS_ERR(padapter->cmdThread))
		err = PTR_ERR(padapter->cmdThread);
	else
		/* wait for cmd_thread to run */
		_rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);

	return err;
}
Пример #10
0
s32 rtl8195as_hal_xmit_handler(PADAPTER padapter)
{
	s32 ret;
	u8 is_queue_pending;
	u8 is_queue_empty ;
	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
	ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
	if(ret == _FAIL)
		return _FAIL;
	is_queue_pending = check_pending_xmitbuf(padapter);
	if(is_queue_pending == _FALSE)
		return _SUCCESS;
	do{
	is_queue_empty=rtl8195as_dequeue_writeport(padapter);
	}while(!is_queue_empty);
	return _SUCCESS;
}
Пример #11
0
u32 WaitC2Hevent( PADAPTER pAdapter,BOOLEAN *C2H_event ,u32 delay_time)
{
	PMPT_CONTEXT		pMptCtx=&(pAdapter->mppriv.MptCtx);
	pMptCtx->bMPh2c_timeout=_FALSE;
	
	_set_timer( &pMptCtx->MPh2c_timeout_timer, delay_time );
	
	_rtw_down_sema(&pMptCtx->MPh2c_Sema);

	if( pMptCtx->bMPh2c_timeout == _TRUE )
	{
		C2H_event =_FALSE;
		
		return _FALSE;
	}
	
	return _TRUE;
	
}
Пример #12
0
void usb_write_port_cancel(_adapter *padapter)
{

	sint i,j;
	struct dvobj_priv   *pdev = &padapter->dvobjpriv;
	struct xmit_priv *pxmitpriv=&padapter->xmitpriv;
	struct xmit_frame *pxmitframe;

	_rtw_spinlock(&pxmitpriv->lock);
	pxmitpriv->txirp_cnt--; //decrease 1 for Initialize ++
	_rtw_spinunlock(&pxmitpriv->lock);
	
	if (pxmitpriv->txirp_cnt) 
	{
		// Canceling Pending Recv Irp
		pxmitframe= (struct xmit_frame *)pxmitpriv->pxmit_frame_buf;
		
		for( i = 0; i < NR_XMITFRAME; i++ )
		{
			for(j=0;j<8;j++)
			{
				if (pxmitframe->bpending[j]==_TRUE)
				{			

					RT_TRACE(_module_hci_ops_os_c_,_drv_err_,(" usb_write_port_cancel() :IoCancelIrp\n"));

				}
			}
			
			pxmitframe++;
		}

		_rtw_down_sema(&(pxmitpriv->tx_retevt));
		
	}

}
Пример #13
0
int rtw_cmd_thread(void *context)
{
	u8 ret;
	struct cmd_obj *pcmd;
	u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf);
	void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd);
	struct adapter *padapter = context;
	struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);

	allow_signal(SIGTERM);

	pcmdpriv->cmdthd_running = true;
	up(&pcmdpriv->terminate_cmdthread_sema);

	RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("start r871x rtw_cmd_thread !!!!\n"));

	while (1) {
		if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL)
			break;

		if (padapter->bDriverStopped ||
		    padapter->bSurpriseRemoved) {
			DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
				__func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
			break;
		}
_next:
		if (padapter->bDriverStopped ||
		    padapter->bSurpriseRemoved) {
			DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
				__func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
			break;
		}

		pcmd = rtw_dequeue_cmd(&pcmdpriv->cmd_queue);
		if (!pcmd)
			continue;

		if (rtw_cmd_filter(pcmdpriv, pcmd) == _FAIL) {
			pcmd->res = H2C_DROPPED;
		} else {
			if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) {
			    cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;

				if (cmd_hdl) {
					ret = cmd_hdl(pcmd->padapter, pcmd->parmbuf);
					pcmd->res = ret;
				}
			} else {
				pcmd->res = H2C_PARAMETERS_ERROR;
			}

			cmd_hdl = NULL;
		}

		/* call callback function for post-processed */
		if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) {
			pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
			if (pcmd_callback == NULL) {
				RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback, pcmd->cmdcode));
				rtw_free_cmd_obj(pcmd);
			} else {
				/* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */
				pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */
			}
		} else {
			RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("%s: cmdcode = 0x%x callback not defined!\n", __func__, pcmd->cmdcode));
			rtw_free_cmd_obj(pcmd);
		}

		if (signal_pending(current))
			flush_signals(current);

		goto _next;
	}
	pcmdpriv->cmdthd_running = false;

	/*  free all cmd_obj resources */
	while ((pcmd = rtw_dequeue_cmd(&pcmdpriv->cmd_queue))) {
		/* DBG_88E("%s: leaving... drop cmdcode:%u\n", __func__, pcmd->cmdcode); */

		rtw_free_cmd_obj(pcmd);
	}

	up(&pcmdpriv->terminate_cmdthread_sema);


	complete_and_exit(NULL, 0);
}
Пример #14
0
/*
 * Description
 *	Transmit xmitbuf to hardware tx fifo
 *
 * Return
 *	_SUCCESS	ok
 *	_FAIL		something error
 */
s32 rtl8188es_xmit_buf_handler(PADAPTER padapter)
{
	struct xmit_priv *pxmitpriv;
	u8	queue_empty, queue_pending;
	s32	ret;
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);


	pxmitpriv = &padapter->xmitpriv;

	ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
	if (ret == _FAIL) {
		RT_TRACE(_module_hal_xmit_c_, _drv_emerg_, ("down SdioXmitBufSema fail!\n"));
		return _FAIL;
	}

//#ifdef CONFIG_CONCURRENT_MODE
//	if (padapter->pbuddy_adapter->bup){
//		if ((padapter->pbuddy_adapter->bSurpriseRemoved == _TRUE) || 
//			(padapter->pbuddy_adapter->bDriverStopped == _TRUE))
//			buddy_rm_stop = _TRUE; 
//	}
//#endif
	if ((padapter->bSurpriseRemoved == _TRUE) || 
		(padapter->bDriverStopped == _TRUE) 
//#ifdef CONFIG_CONCURRENT_MODE
//		||(buddy_rm_stop == _TRUE)
//#endif
	) {
		RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
				 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)\n",
				  __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
		return _FAIL;
	}

	queue_pending = check_pending_xmitbuf(pxmitpriv);

#ifdef CONFIG_CONCURRENT_MODE
	if(rtw_buddy_adapter_up(padapter))
		queue_pending |= check_pending_xmitbuf(&padapter->pbuddy_adapter->xmitpriv);
#endif

	if(queue_pending == _FALSE)
		return _SUCCESS;

#ifdef CONFIG_LPS_LCLK
	ret = rtw_register_tx_alive(padapter);
	if (ret != _SUCCESS) return _SUCCESS;
#endif

	do {
		queue_empty = rtl8188es_dequeue_writeport(padapter);
//	dump secondary adapter xmitbuf 
#ifdef CONFIG_CONCURRENT_MODE
		if(rtw_buddy_adapter_up(padapter))
			queue_empty &= rtl8188es_dequeue_writeport(padapter->pbuddy_adapter);
#endif

	} while ( !queue_empty);

#ifdef CONFIG_LPS_LCLK
	rtw_unregister_tx_alive(padapter);
#endif
	return _SUCCESS;
}
Пример #15
0
/*
 * Description
 *	Transmit xmitbuf to hardware tx fifo
 *
 * Return
 *	_SUCCESS	ok
 *	_FAIL		something error
 */
s32 rtl8188es_xmit_buf_handler(PADAPTER padapter)
{
	struct mlme_priv *pmlmepriv;
	struct xmit_priv *pxmitpriv;
	struct xmit_buf *pxmitbuf;
	struct xmit_frame *pframe;
	u8 *freePage;
	u32 requiredPage;
	u8 PageIdx , queue_empty;
	_irqL irql;
	u32 n;
	s32 ret;
	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
#ifdef CONFIG_CONCURRENT_MODE
	s32 buddy_rm_stop = _FAIL;
#endif

	pmlmepriv = &padapter->mlmepriv;
	pxmitpriv = &padapter->xmitpriv;
	freePage = pHalData->SdioTxFIFOFreePage;

	ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
	if (ret == _FAIL) {
		RT_TRACE(_module_hal_xmit_c_, _drv_emerg_, ("down SdioXmitBufSema fail!\n"));
		return _FAIL;
	}

//#ifdef CONFIG_CONCURRENT_MODE
//	if (padapter->pbuddy_adapter->bup){
//		if ((padapter->pbuddy_adapter->bSurpriseRemoved == _TRUE) ||
//			(padapter->pbuddy_adapter->bDriverStopped == _TRUE))
//			buddy_rm_stop = _TRUE;
//	}
//#endif
	if ((padapter->bSurpriseRemoved == _TRUE) ||
		(padapter->bDriverStopped == _TRUE)
//#ifdef CONFIG_CONCURRENT_MODE
//		||(buddy_rm_stop == _TRUE)
//#endif
	) {

#ifdef CONFIG_LPS_LCLK
		rtw_unregister_tx_alive(padapter);
#endif
		RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
				 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)\n",
				  __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
		return _FAIL;
	}

#ifdef CONFIG_LPS_LCLK
	ret = rtw_register_tx_alive(padapter);
	if (ret != _SUCCESS) return _SUCCESS;
#endif

	do {
		queue_empty = rtl8188es_dequeue_writeport(padapter, freePage);
//	dump secondary adapter xmitbuf
#ifdef CONFIG_CONCURRENT_MODE
		if(rtw_buddy_adapter_up(padapter))
			queue_empty &= rtl8188es_dequeue_writeport(padapter->pbuddy_adapter, freePage);
#endif

	} while ( !queue_empty);

#ifdef CONFIG_LPS_LCLK
	rtw_unregister_tx_alive(padapter);
#endif
	return _SUCCESS;
}
Пример #16
0
void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
{

	NTSTATUS NtStatus = STATUS_SUCCESS;
    USB_PIPE	hPipe;
	_irqL	irqL;

	int 	fComplete	= _FALSE;
	DWORD	dwBytes 	= 0;
	DWORD	dwErr		= USB_CANCELED_ERROR;


	struct io_req 		*pio_req;

	_adapter 			*adapter 	= (_adapter *)pintfhdl->adapter;
	struct intf_priv 	*pintfpriv	= pintfhdl->pintfpriv;
	struct dvobj_priv   * pdvobj_priv   = (struct dvobj_priv*)pintfpriv->intf_dev;

	 
    struct xmit_priv	*pxmitpriv	= &adapter->xmitpriv;
	struct io_queue 	*pio_queue 	= (struct io_queue *)adapter->pio_queue; 

	LPCUSB_FUNCS usb_funcs_vp = pdvobj_priv->usb_extension._lpUsbFuncs;


_func_enter_;
	RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("usb_write_mem(%u) pintfhdl %p wmem %p\n", __LINE__, pintfhdl, wmem));

	// fetch a io_request from the io_queue
	pio_req = alloc_ioreq(pio_queue);
		
	if ((pio_req == NULL)||(adapter->bSurpriseRemoved))
	{
		RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("async_irp_write32 : pio_req =0x%x adapter->bSurpriseRemoved=0x%x",pio_req,adapter->bSurpriseRemoved ));
		goto exit;
	}	

	_enter_critical_bh(&(pio_queue->lock), &irqL);


	// insert the io_request into processing io_queue
	rtw_list_insert_tail(&(pio_req->list),&(pio_queue->processing));
	
	
	if((adapter->bDriverStopped) || (adapter->bSurpriseRemoved) ||(adapter->pwrctrlpriv.pnp_bstop_trx)) 
	{
		RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("\npadapter->pwrctrlpriv.pnp_bstop_trx==_TRUE\n"));
		goto exit;
	}
	
	//translate DMA FIFO addr to pipehandle
	hPipe = ffaddr2pipehdl(pdvobj_priv, addr);	

	RT_TRACE( _module_hci_ops_os_c_, _drv_info_,("usb_write_mem(%u)\n",__LINE__));

	pio_req->usb_transfer_write_mem = (*usb_funcs_vp->lpIssueBulkTransfer)(
		hPipe,
		usb_write_mem_complete, 
		pio_queue,
		USB_OUT_TRANSFER,
		cnt,
		wmem,
		0);

#if 0

	(*usb_funcs_vp->lpGetTransferStatus)(pio_req->usb_transfer_write_mem , &dwBytes, &dwErr);

	while( fComplete != _TRUE)
	{
		fComplete = (*usb_funcs_vp->lpIsTransferComplete)(pio_req->usb_transfer_write_mem);
		if(fComplete==_TRUE)
		{
			(*usb_funcs_vp->lpCloseTransfer)(pio_req->usb_transfer_write_mem );
			RT_TRACE( _module_hci_ops_os_c_, _drv_err_, ("usb_write_mem finished\n"));
			break;
		}
		else
		{
			RT_TRACE( _module_hci_ops_os_c_, _drv_err_, 
				("usb_write_mem not yet finished %X\n", 
				pio_req->usb_transfer_write_mem));
			rtw_msleep_os(10);
		}
		
	}

#endif


//	_rtw_down_sema(&pio_req->sema);	

	RT_TRACE( _module_hci_ops_os_c_, _drv_info_, ("-usb_write_mem(%X)\n",pio_req->usb_transfer_write_mem));

	_exit_critical_bh(&(pio_queue->lock), &irqL);

	_rtw_down_sema(&pio_req->sema); 
	free_ioreq(pio_req, pio_queue);

exit:
_func_exit_;
	return;
}