📄 usbpipe.c
字号:
/* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * * This software is copyrighted by and is the sole property of * VIA Networking Technologies, Inc. This software may only be used * in accordance with the corresponding license agreement. Any unauthorized * use, duplication, transmission, distribution, or disclosure of this * software is expressly forbidden. * * This software is provided by VIA Networking Technologies, Inc. "as is" * and any express or implied warranties, including, but not limited to, the * implied warranties of merchantability and fitness for a particular purpose * are disclaimed. In no event shall VIA Networking Technologies, Inc. * be liable for any direct, indirect, incidental, special, exemplary, or * consequential damages. * * * File: usbpipe.c * * Purpose: Handle USB control endpoint * * Author: Warren Hsu * * Date: Mar. 29, 2005 * * Functions: * CONTROLnsRequestOut - Write variable length bytes to MEM/BB/MAC/EEPROM * CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM * ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM * ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address * * Revision History: * 04-05-2004 Jerry Chen: Initial release * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte * */#if !defined(__UMEM_H__)#include "umem.h"#endif#if !defined(__INT_H__)#include "int.h"#endif#if !defined(__RXTX_H__)#include "rxtx.h"#endif#if !defined(__DPC_H__)#include "dpc.h"#endif#if !defined(__CONTROL_H__)#include "control.h"#endif#if !defined(__DESC_H__)#include "desc.h"#endif#if !defined(__DEVICE_H__)#include "device.h"#endif/*--------------------- Static Definitions -------------------------*///endpoint def//endpoint 0: control//endpoint 1: interrupt//endpoint 2: read bulk//endpoint 3: write bulk//RequestType://#define REQUEST_OUT (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) // 0x40//#define REQUEST_IN (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE ) //0xc0//static int msglevel =MSG_LEVEL_DEBUG;static int msglevel =MSG_LEVEL_INFO;#define USB_CTL_WAIT 500 //ms#ifndef URB_ASYNC_UNLINK#define URB_ASYNC_UNLINK 0#endif/*--------------------- Static Classes ----------------------------*//*--------------------- Static Variables --------------------------*//*--------------------- Static Functions --------------------------*///2007-0508-02<Add>by MikeLiu#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))staticVOID s_nsInterruptUsbIoCompleteRead( IN struct urb *urb, IN struct pt_regs *regs ); staticVOID s_nsBulkInUsbIoCompleteRead( IN struct urb *urb, IN struct pt_regs *regs ); staticVOID s_nsBulkOutIoCompleteWrite( IN struct urb *urb, IN struct pt_regs *regs ); staticVOID s_nsControlInUsbIoCompleteRead( IN struct urb *urb, IN struct pt_regs *regs ); staticVOID s_nsControlInUsbIoCompleteWrite( IN struct urb *urb, IN struct pt_regs *regs ); #elsestaticVOID s_nsInterruptUsbIoCompleteRead( IN struct urb *urb ); staticVOID s_nsBulkInUsbIoCompleteRead( IN struct urb *urb ); staticVOID s_nsBulkOutIoCompleteWrite( IN struct urb *urb ); staticVOID s_nsControlInUsbIoCompleteRead( IN struct urb *urb ); staticVOID s_nsControlInUsbIoCompleteWrite( IN struct urb *urb ); #endif /*--------------------- Export Variables --------------------------*//*--------------------- Export Functions --------------------------*/NTSTATUSPIPEnsControlOutAsyn( IN PSDevice pDevice, IN BYTE byRequest, IN WORD wValue, IN WORD wIndex, IN WORD wLength, IN PBYTE pbyBuffer ){ NTSTATUS ntStatus; if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED)) return STATUS_FAILURE; if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) { return STATUS_FAILURE; } if (in_interrupt()) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"in_interrupt return ..byRequest %x\n", byRequest); return STATUS_FAILURE; } ntStatus = usb_control_msg( pDevice->usb, usb_sndctrlpipe(pDevice->usb , 0), byRequest, 0x40, // RequestType wValue, wIndex, (PVOID) pbyBuffer, wLength, HZ ); if (ntStatus >= 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe ntStatus= %d\n", ntStatus); ntStatus = 0; } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe fail, ntStatus= %d\n", ntStatus); } return ntStatus;}NTSTATUSPIPEnsControlOut( IN PSDevice pDevice, IN BYTE byRequest, IN WORD wValue, IN WORD wIndex, IN WORD wLength, IN PBYTE pbyBuffer ){ NTSTATUS ntStatus = 0; int ii; if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED)) return STATUS_FAILURE; if (MP_TEST_FLAG(pDevice, 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); if ((ntStatus = vntwusb_submit_urb(pDevice->pControlURB) != 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 (MP_TEST_FLAG(pDevice, 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; }NTSTATUSPIPEnsControlIn( IN PSDevice pDevice, IN BYTE byRequest, IN WORD wValue, IN WORD wIndex, IN WORD wLength, IN OUT PBYTE pbyBuffer ){ NTSTATUS ntStatus = 0; int ii; if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED)) return STATUS_FAILURE; if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS)) { return STATUS_FAILURE; } 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); if ((ntStatus = vntwusb_submit_urb(pDevice->pControlURB) != 0)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control request submission failed: %d\n", ntStatus); }else { MP_SET_FLAG(pDevice, fMP_CONTROL_READS); } spin_unlock_irq(&pDevice->lock); for (ii = 0; ii <= USB_CTL_WAIT; ii ++) { if (MP_TEST_FLAG(pDevice, 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;}//2007-0508-03<Add>by MikeLiu#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))staticVOID s_nsControlInUsbIoCompleteWrite( IN struct urb *urb, IN struct pt_regs *regs )#else staticVOID s_nsControlInUsbIoCompleteWrite( IN struct urb *urb )#endif { PSDevice pDevice; pDevice = urb->context; switch (urb->status) { case 0: break; case -EINPROGRESS: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status EINPROGRESS%d\n", urb->status); break; case -ENOENT: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status ENOENT %d\n", urb->status); break; default: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status %d\n", urb->status); } MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);}/* * Description: * Complete function of usb Control callback * * Parameters: * In: * pDevice - Pointer to the adapter * * Out: * none * * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver * *///2007-0508-04<Add>by MikeLiu#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))&&(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))staticVOID s_nsControlInUsbIoCompleteRead( IN struct urb *urb, IN struct pt_regs *regs )#elsestaticVOID s_nsControlInUsbIoCompleteRead( IN struct urb *urb )#endif { PSDevice pDevice; pDevice = urb->context; switch (urb->status) { case 0: break; case -EINPROGRESS: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status EINPROGRESS%d\n", urb->status); break; case -ENOENT: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status = ENOENT %d\n", urb->status); break; default: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status %d\n", urb->status); } MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);}/* * Description: * Allocates an usb interrupt in irp and calls USBD. * * Parameters: * In: * pDevice - Pointer to the adapter * Out: * none * * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver * */NTSTATUSPIPEnsInterruptRead( IN PSDevice pDevice ){ NTSTATUS ntStatus = STATUS_FAILURE; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartInterruptUsbRead()\n"); if(pDevice->intBuf.bInUse == TRUE){ return (STATUS_FAILURE); } pDevice->intBuf.bInUse = TRUE;// pDevice->bEventAvailable = FALSE; pDevice->ulIntInPosted++; // // Now that we have created the urb, we will send a // request to the USB device object. //#if 0 //reserve int URB submit usb_fill_int_urb(pDevice->pInterruptURB, pDevice->usb, usb_rcvintpipe(pDevice->usb, 1), (PVOID) pDevice->intBuf.pDataBuf, MAX_INTERRUPT_SIZE, s_nsInterruptUsbIoCompleteRead, pDevice, pDevice->int_interval );#else //replace int URB submit by bulk transfer #ifndef Safe_Close usb_fill_int_urb(pDevice->pInterruptURB, pDevice->usb, usb_rcvintpipe(pDevice->usb, 1), (PVOID) pDevice->intBuf.pDataBuf, MAX_INTERRUPT_SIZE, s_nsInterruptUsbIoCompleteRead, pDevice, pDevice->int_interval );#else//2008-0526-01<Add>by MikeLiu#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) pDevice->pInterruptURB->interval = pDevice->int_interval;#endif usb_fill_bulk_urb(pDevice->pInterruptURB,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -