📄 rtusb_io.c
字号:
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 + -