⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtusb_io.c

📁 TP Link 321 Linux Driver
💻 C
📖 第 1 页 / 共 4 页
字号:
		length);	RTUSBMacRegUp(pAd);	return Status;}/*	========================================================================		Routine Description:	Arguments:	Return Value:		Note:		========================================================================*/NTSTATUS RTUSBPutToSleep(	IN	PRTMP_ADAPTER	pAd){	NTSTATUS	Status;//2008/01/07:KH add to solve the racing condition of Mac Registers	wait_queue_head_t wait;	init_waitqueue_head(&wait);			for(;pAd->MacRegWrite_Processing==1;)		wait_event_interruptible_timeout(wait,0,1);		RTUSBMacRegDown(pAd);		Status = RTUSB_VendorRequest(		pAd,		0,		DEVICE_VENDOR_REQUEST_OUT,		0x01,		0x07,		0,		NULL,		0);	RTUSBMacRegUp(pAd);	return Status;}/*	========================================================================		Routine Description:	Arguments:	Return Value:		Note:		========================================================================*/NTSTATUS RTUSBWakeUp(	IN	PRTMP_ADAPTER	pAd){	NTSTATUS	Status;	//2008/01/07:KH add to solve the racing condition of Mac Registers	wait_queue_head_t wait;	init_waitqueue_head(&wait);			for(;pAd->MacRegWrite_Processing==1;)		wait_event_interruptible_timeout(wait,0,1);		RTUSBMacRegDown(pAd);		Status = RTUSB_VendorRequest(		pAd,		0,		DEVICE_VENDOR_REQUEST_OUT,		0x01,		0x09,		0,		NULL,		0);	RTUSBMacRegUp(pAd);	return Status;}/*	========================================================================		Routine Description:	Arguments:	Return Value:		Note:		========================================================================*/VOID	RTUSBInitializeCmdQ(	IN	PCmdQ	cmdq){	cmdq->head = NULL;	cmdq->tail = NULL;	cmdq->size = 0;}/*	========================================================================		Routine Description:	Arguments:	Return Value:		Note:		========================================================================*/NDIS_STATUS	RTUSBEnqueueCmdFromNdis(	IN	PRTMP_ADAPTER	pAd,	IN	NDIS_OID		Oid,	IN	BOOLEAN			SetInformation,	IN	PVOID			pInformationBuffer,	IN	ULONG			InformationBufferLength){	PCmdQElmt	cmdqelmt = NULL;	unsigned long	IrqFlags;		if (pAd->RTUSBCmdThr_pid < 0) 		return (NDIS_STATUS_RESOURCES);            cmdqelmt = (PCmdQElmt) kmalloc(sizeof(CmdQElmt), MEM_ALLOC_FLAG);	if (!cmdqelmt) 	{		DBGPRINT(RT_DEBUG_ERROR,"Not enough memory\n");		kfree((PCmdQElmt)cmdqelmt);		return NDIS_STATUS_RESOURCES;	}	if ((Oid == RT_OID_MULTI_READ_MAC) ||		(Oid == RT_OID_VENDOR_READ_BBP) ||#ifdef DBG				(Oid == RT_OID_802_11_QUERY_HARDWARE_REGISTER) ||#endif				(Oid == RT_OID_USB_VENDOR_EEPROM_READ))	{		cmdqelmt->buffer = pInformationBuffer;	}	else	{		cmdqelmt->buffer = NULL;		if (pInformationBuffer != NULL)		{			cmdqelmt->buffer =	kmalloc(InformationBufferLength, MEM_ALLOC_FLAG);			if ((!cmdqelmt->buffer) )			{                       kfree((PVOID)cmdqelmt->buffer);				kfree((PCmdQElmt)cmdqelmt);				return (NDIS_STATUS_RESOURCES);			}			else			{				NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);				cmdqelmt->bufferlength = InformationBufferLength;			}		}		else			cmdqelmt->bufferlength = 0;	}		cmdqelmt->command = Oid;	cmdqelmt->CmdFromNdis = TRUE;	if (SetInformation == TRUE)		cmdqelmt->SetOperation = TRUE;	else		cmdqelmt->SetOperation = FALSE;	NdisAcquireSpinLock(&pAd->CmdQLock,  IrqFlags);	EnqueueCmd((&pAd->CmdQ), cmdqelmt);	NdisReleaseSpinLock(&pAd->CmdQLock,  IrqFlags);	    RTUSBCMDUp(pAd);		if ((Oid == OID_802_11_BSSID_LIST_SCAN) ||		(Oid == RT_OID_802_11_BSSID) ||		(Oid == OID_802_11_SSID) ||		(Oid == OID_802_11_DISASSOCIATE))	{		return(NDIS_STATUS_SUCCESS);	}	    return(NDIS_STATUS_SUCCESS);}/*	========================================================================		Routine Description:	Arguments:	Return Value:		Note:		========================================================================*/VOID	RTUSBEnqueueInternalCmd(	IN	PRTMP_ADAPTER	pAd,	IN	NDIS_OID		Oid){	PCmdQElmt	cmdqelmt = NULL;	unsigned long	IrqFlags;	    if (pAd->RTUSBCmdThr_pid < 0) 		return;			switch (Oid)	{		case RT_OID_CHECK_GPIO:			cmdqelmt = &(pAd->CmdQElements[CMD_CHECK_GPIO]);			break;					case RT_OID_PERIODIC_EXECUT:			cmdqelmt = &(pAd->CmdQElements[CMD_PERIODIC_EXECUT]);			break;					//For Alpha only		case RT_OID_ASICLED_EXECUT:			cmdqelmt = &(pAd->CmdQElements[CMD_ASICLED_EXECUT]);			break;		case RT_OID_UPDATE_TX_RATE:			cmdqelmt = &(pAd->CmdQElements[CMD_UPDATE_TX_RATE]);			break;					case RT_OID_SET_PSM_BIT_SAVE:			cmdqelmt = &(pAd->CmdQElements[CMD_SET_PSM_SAVE]);			break;					case RT_OID_LINK_DOWN:			cmdqelmt = &(pAd->CmdQElements[CMD_LINK_DOWN]);			break;					case RT_OID_USB_RESET_BULK_IN:			cmdqelmt = &(pAd->CmdQElements[CMD_RESET_BULKIN]);			break;					case RT_OID_USB_RESET_BULK_OUT:			cmdqelmt = &(pAd->CmdQElements[CMD_RESET_BULKOUT]);			break;					case RT_OID_RESET_FROM_ERROR:			cmdqelmt = &(pAd->CmdQElements[CMD_RESET_FROM_ERROR]);			break;					case RT_OID_RESET_FROM_NDIS:			cmdqelmt = &(pAd->CmdQElements[CMD_RESET_FROM_NDIS]);			break;		case RT_PERFORM_SOFT_DIVERSITY:			cmdqelmt = &(pAd->CmdQElements[CMD_SOFT_DIVERSITY]);			break;        case RT_OID_FORCE_WAKE_UP:            cmdqelmt = &(pAd->CmdQElements[CMD_FORCE_WAKEUP]);            break;         case RT_OID_SET_PSM_BIT_ACTIVE:            cmdqelmt = &(pAd->CmdQElements[CMD_SET_PSM_ACTIVE]);        break; 		default:			break;	}	if ((cmdqelmt != NULL) && (cmdqelmt->InUse == FALSE) && (pAd->RTUSBCmdThr_pid > 0))	{		cmdqelmt->InUse = TRUE;		cmdqelmt->command = Oid;		NdisAcquireSpinLock(&pAd->CmdQLock, IrqFlags);		EnqueueCmd((&pAd->CmdQ), cmdqelmt);		NdisReleaseSpinLock(&pAd->CmdQLock, IrqFlags);				RTUSBCMDUp(pAd);	}}/*	========================================================================		Routine Description:	Arguments:	Return Value:		Note:		========================================================================*/VOID	RTUSBDequeueCmd(	IN	PCmdQ		cmdq,	OUT	PCmdQElmt	*pcmdqelmt){	*pcmdqelmt = cmdq->head;		if (*pcmdqelmt != NULL)	{		cmdq->head = cmdq->head->next;		cmdq->size--;		if (cmdq->size == 0)			cmdq->tail = NULL;	}}/*    ========================================================================	  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.  		Routine Description:	Arguments:	Return Value:		Note:		========================================================================*/INT	    RTUSB_VendorRequest(	IN	PRTMP_ADAPTER	pAd,	IN	ULONG			TransferFlags,	IN	UCHAR			RequestType,	IN	UCHAR			Request,	IN	USHORT			Value,	IN	USHORT			Index,	IN	PVOID			TransferBuffer,	IN	ULONG			TransferBufferLength){	int ret;	int RetryCnt;	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))	{		DBGPRINT(RT_DEBUG_ERROR,"device disconnected\n");		return -1;	}	else if (in_interrupt())		{		DBGPRINT(RT_DEBUG_ERROR,"in_interrupt, return RTUSB_VendorRequest\n");		return -1;	}	else	{		RetryCnt = 0;		do		{			if( RequestType == DEVICE_VENDOR_REQUEST_OUT)				ret=usb_control_msg(pAd->pUsb_Dev, usb_sndctrlpipe( pAd->pUsb_Dev, 0 ), Request, RequestType, Value,Index, TransferBuffer, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);			else if(RequestType == DEVICE_VENDOR_REQUEST_IN)				ret=usb_control_msg(pAd->pUsb_Dev, usb_rcvctrlpipe( pAd->pUsb_Dev, 0 ), Request, RequestType, Value,Index, TransferBuffer, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);			else			{				DBGPRINT(RT_DEBUG_ERROR,"vendor request direction is failed\n");				ret = -1;				break;			}			DBGPRINT(RT_DEBUG_INFO,"%x\t%x\t%x\t%x\n",Request,RequestType,Value,Index);			if( ret >= 0)				break;			else				RTMPusecDelay(50 * 1000); /* pause for 50 ms. */		} while (RetryCnt++ < 5);        if (ret < 0)			DBGPRINT(RT_DEBUG_ERROR,"USBVendorRequest failed ret=%d \n",ret);	}	return ret;}/*	========================================================================		Routine Description:	  Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT	  synchronously. Callers of this function must be running at	  PASSIVE LEVEL.	Arguments:	Return Value:	Note:		========================================================================*/NTSTATUS	RTUSB_ResetDevice(	IN	PRTMP_ADAPTER	pAd){	NTSTATUS		Status = TRUE;	DBGPRINT_RAW(RT_DEBUG_TRACE, "--->USB_ResetDevice\n");	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);	return Status;}VOID CMDHandler(    IN PRTMP_ADAPTER pAd) {	PCmdQElmt	cmdqelmt;	PUCHAR	    pData;	NDIS_STATUS	NdisStatus = NDIS_STATUS_SUCCESS;	unsigned long	IrqFlags;	ULONG       Now;    	while (pAd->CmdQ.size > 0)	{		NdisStatus = NDIS_STATUS_SUCCESS;		NdisAcquireSpinLock(&pAd->CmdQLock, IrqFlags);		RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);		NdisReleaseSpinLock(&pAd->CmdQLock, IrqFlags);		if (cmdqelmt == NULL)			break;		pData = cmdqelmt->buffer;        //DBGPRINT_RAW(RT_DEBUG_INFO, "Cmd = %x\n", cmdqelmt->command);		switch (cmdqelmt->command)		{			case RT_OID_CHECK_GPIO:			{				ULONG data;				// Read GPIO pin7 as Hardware controlled radio state				RTUSBReadMACRegister(pAd, MAC_CSR13, &data);				if (data & 0x80)				{					pAd->PortCfg.bHwRadio = TRUE;				}				else				{					pAd->PortCfg.bHwRadio = FALSE;				}				if (pAd->PortCfg.bRadio != (pAd->PortCfg.bHwRadio && pAd->PortCfg.bSwRadio))				{					pAd->PortCfg.bRadio = (pAd->PortCfg.bHwRadio && pAd->PortCfg.bSwRadio);					if (pAd->PortCfg.bRadio == TRUE)					{						MlmeRadioOn(pAd);						// Update extra information						pAd->ExtraInfo = EXTRA_INFO_CLEAR;					}					else					{						MlmeRadioOff(pAd);						// Update extra information						pAd->ExtraInfo = HW_RADIO_OFF;					}				}					}			break;			case RT_OID_PERIODIC_EXECUT:				//printk("RT_OID_PERIODIC_EXECUT\n");			    STAMlmePeriodicExec(pAd);			break;			case OID_802_11_BSSID_LIST_SCAN:			{				if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)				{					MlmeEnqueue(pAd, 					            MLME_CNTL_STATE_MACHINE,					            RT_CMD_RESET_MLME,					            0,					            NULL);				}				Now = jiffies;				// Reset Missed scan number				pAd->PortCfg.ScanCnt = 0;				pAd->PortCfg.LastScanTime = Now;				MlmeEnqueue(pAd,							MLME_CNTL_STATE_MACHINE,							OID_802_11_BSSID_LIST_SCAN,							0,							NULL);				RTUSBMlmeUp(pAd);			}			break;						case RT_OID_802_11_BSSID:			{				if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)				{					MlmeEnqueue(pAd, 					            MLME_CNTL_STATE_MACHINE,					            RT_CMD_RESET_MLME,					            0,					            NULL);				}				// Reset allowed scan retries				pAd->PortCfg.ScanCnt = 0;				MlmeEnqueue(pAd,							MLME_CNTL_STATE_MACHINE,							OID_802_11_BSSID,							cmdqelmt->bufferlength,							cmdqelmt->buffer);				RTUSBMlmeUp(pAd);			}			break;						case OID_802_11_SSID:			{				if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)				{									MlmeEnqueue(pAd, 					            MLME_CNTL_STATE_MACHINE,					            RT_CMD_RESET_MLME,					            0,					            NULL);					}				// Reset allowed scan retries				pAd->PortCfg.ScanCnt = 0;				pAd->bConfigChanged = TRUE;				MlmeEnqueue(pAd,							MLME_CNTL_STATE_MACHINE,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -