📄 usbuhcdrhemulate.c
字号:
/* usbUhcdRhEmulate.c - USB UHCI HCD Roothub Emulation *//* Copyright 2004 Wind River Systems, Inc. This software includes software licensed to Wind River Systems, Inc. by Wipro, Ltd. Wind River licensees may use this software according to the terms of their Wind River license agreement(s) applicable to this software.*//*Modification history--------------------01e,15oct04,ami Refgen Changes01d,12Sep03,nrv Status change01c,28jul03,mat Endian Related Changes01b,26jun03,mat changing the code to WRS standards.01a,25apr03,ram written.*//*DESCRIPTIONThis file contains functions which essentialy form a wrapper aroundUHCI's root hub so as to make it appear as an ordinary hub.INCLUDE FILES: usb2/usbOsal.h, usb2/usbUhcdCommon.h, usb2/usbHst.h,usb2/usbUhcdScheduleQueue.h, usb2/usbUhcdSupport.h, usb2/BusAbstractionLayer.h, usb2/usbUhcdScheduleQSupport.h, usb2/usbUhci.h *//*INTERNAL ******************************************************************************* * Filename : usbUhcdRhEmulate.c * * Copyright : * * THE COPYRIGHT IN THE CONTENTS OF THIS SOFTWARE VEST WITH WIPRO * LIMITED A COMPANY INCORPORATED UNDER THE LAWS OF INDIA AND HAVING * ITS REGISTERED OFFICE AT DODDAKANNELLI SARJAPUR ROAD BANGALORE * 560 035. DISTRIBUTION OR COPYING OF THIS SOFTWARE BY * ANY INDIVIDUAL OR ENTITY OTHER THAN THE ADDRESSEE IS STRICTLY * PROHIBITED AND MAY INCUR LEGAL LIABILITY. IF YOU ARE NOT THE * ADDRESSEE PLEASE NOTIFY US IMMEDIATELY BY PHONE OR BY RETURN EMAIL. * THE ADDRESSEE IS ADVISED TO MAINTAIN THE PROPRIETARY INTERESTS OF * THIS COPYRIGHT AS PER APPLICABLE LAWS. * * * Description : This file contains functions which essentialy * form a wrapper around UHCI's root hub so as to * make it appear as an ordinary hub. * * ******************************************************************************//* includes */#include "usb2/usbOsal.h"#include "usb2/usbUhcdCommon.h"#include "usb2/usbHst.h"#include "usb2/usbUhcdScheduleQueue.h"#include "usb2/usbUhcdSupport.h"#include "usb2/BusAbstractionLayer.h"#include "usb2/usbUhcdScheduleQueue.h"#include "usb2/usbUhcdScheduleQSupport.h"#include "usb2/usbUhci.h"/* defines */#define INCLUDED_FROM_RH_EMULATE#include "usb2/usbUhcdRhEmulate.h"#undef INCLUDED_FROM_RH_EMULATE#define USB_UHCD_REQUEST_FAILURE ERROR/* To hold the number of ports supported by the Root hub */#define USB_UHCD_ROOT_HUB_PORTS 0x02/* define hub descriptor type value */#define USB_UHCD_HUB_DESCRIPTOR 0x29/* define Hub Characteristics */#define USB_UHCD_GANGED_POWER_SWITCHING 0x0000#define USB_UHCD_INDIVIDUAL_PORT_POWER 0x0001#define USB_UHCD_HUB_NOT_COMPOUND_DEV 0x0000#define USB_UHCD_HUB_COMPOUND_DEV 0x0004#define USB_UHCD_GLOBAL_OVER_CURRENT_PROT 0x0000#define USB_UHCD_INDIVIDUAL_PORT_OVER_CUR_PROT 0x0008#define USB_UHCD_NO_OVER_CURRENT_PROT 0x0010#define USB_UHCD_HUB_REMOVABLE 0x00#define USB_UHCD_HUB_NON_REMOVABLE 0x01#define USB_UHCD_PORT_PWR_CTRL_MASK 0xFF/***************************************************************************** usbUhcdCopy - copies the required or maximum number of bytes** This function copies the required or maximum number of bytes from the source* to the target.** RETURNS: N/A** ERRNO:* None.** \NOMANUAL*/void usbUhcdCopy ( UCHAR *target, UCHAR *source, UINT *required, UINT max ) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering UHC copy\n",0,0,0,0); OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking the pointer\n",0,0,0,0); /* * Check if the required pointer is NULL or * the required number of bytes is greater than * the maximum number of bytes requested */ if (required==NULL || (*required > max) || (*required == 0) ) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Required pointer is NULL or > MAX\n",0,0,0,0); /* Copy maximum number of bytes */ OS_MEMCPY (target, source, max); /* update *required to indicate that only max bytes were copied */ if (required != NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Required pointer is > MAX\n",0,0,0,0); *required = max; } } /* Copy the required number of bytes from the source to the target */ else { OS_LOG_MESSAGE_MEDIUM(UHCD,"Required pointer is copied\n",0,0,0,0); OS_MEMCPY (target, source, *required); } OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting UHC copy\n",0,0,0,0); return; }/* End of usbUhcdCopy() *//***************************************************************************** usbUhcdGetPortStatus - handles the hub specific request for Root hub ** This function handles the GET_PORT_STATUS hub specific request for * the Root ** RETURNS: USB_UHCD_FAIL if there is an error in retrieving the port status** ERRNO:* None.** \NOMANUAL*/INT32 usbUhcdGetPortStatus ( PUHCD_DATA pHCDData, USBHST_URB *pUrb ) { /* To hold the status of the hub */ UINT32 status = 0; /* To hold the offset of the register */ UINT32 offset = 0; /* To hold the port number */ UINT8 port = 0; UINT16 wValue = 0; UINT16 wIndex = 0; UINT16 wLength = 0; pUSBHST_SETUP_PACKET pSetupPacket = (pUSBHST_SETUP_PACKET )pUrb->pTransferSpecificData; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering get port status\n",0,0,0,0); /* Check if the URB and the DeviceRequest pointers are valid */ if (NULL == pUrb || NULL == pSetupPacket) { return USB_UHCD_FAIL; } wValue = OS_UINT16_CPU_TO_LE(pSetupPacket->wValue); wIndex = OS_UINT16_CPU_TO_LE(pSetupPacket->wIndex); wLength = OS_UINT16_CPU_TO_LE(pSetupPacket->wLength); /* Get the port index */ port = wIndex; /* * Check whether there are any invalid conditions. * i.e invalid port, invalid DevRequest parameters */ if (port < USB_UHCD_PORT_1 || port > USB_UHCD_PORT_2 || wLength!=USB_UHCD_BYTE_TX_DATA_STAGE || wValue!=0) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Invalid condition\n",0,0,0,0); return USB_UHCD_FAIL; } /* Check whether the Buffer passed is not NULL */ if (pUrb->pTransferBuffer==NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Buffer passed is NULL\n",0,0,0,0); return USB_UHCD_FAIL; } /* Get the correct offset based on port number */ offset = (port==1)? (USB_UHCD_PORT1) : (USB_UHCD_PORT2); /* * The hub's port status contains 4 bytes of information, out of which * the hub's port status is reported in the byte offsets 0 to 1 * and the hub's port status change in the byte offsets 2 to 3 */ /* Update the port status change bytes - Start */ /* Following is the interpretation of the 16 bits of port status change HUB, * which is being updated using the UHCI register * Bit 5-15 Reserved * Bit 4 - Reset change * Bit 3 - Overcurrent indicator Change * Bit 2 - Suspend Change * Bit 1 - Port Enable/Disable change * Bit 0 - Connect status change */ /* Update the reset change bit */ status |= pHCDData->usbUhcdResetChange[port-1]; status <<= 1; /* * Update the overcurrent change bit * (ie) 0 since there is no overcurrent indication in UHCI */ status |= 0; status <<= 1; /* * Update the suspend change bit * (ie) 0 since there is no suspend-change indication in UHCI */ status |= 0; status <<= 1; /* Store enable/disable change bit */ status |= usbUhcdGetBit(pHCDData, offset, 3); status <<= 1; /* Store connect status change */ status |= usbUhcdGetBit(pHCDData, offset, 1); status <<= 1; /* Update the port status change bytes - End */ /* Update the port status bytes - Start */ /* * Following is the interpretation of the 16 bits of port status * Bit 10-15 Reserved * Bit 9 - Low speed device is attached * Bit 8 - Port is powered on * Bit 5-7 Reserved * Bit 4 - Reset signalling asserted * Bit 3 - An overcurrent condition exists on the port * Bit 2 - Port is suspended * Bit 1 - Port is enabled * Bit 0 - Device is present on the port */ /* Reserved .. fill next 6 bits with 0 */ status <<= 6; /* Check whether a Low speed device is connected and update the status */ status |= usbUhcdGetBit (pHCDData,offset, 8); status <<= 1; /* Store 1 (ie) ports are always powered on .. no power switching in UHCI */ status |= 1; status <<= 1; /* Next 3 bits are 0 .. reserved */ status <<= 3; /* Read the bit indicating whether a reset is asserted. Update the status */ status |= usbUhcdGetBit (pHCDData,offset, 9); status <<= 1; /* Over current condition... store 0 ... no indication in UHCI */ status |= 0; status <<= 1; /* If port is enabled, only then do a port suspend check */ if (usbUhcdIsBitSet (pHCDData, offset, 2)) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Doing port suspend\n",0,0,0,0); status |= usbUhcdGetBit ( pHCDData, offset, 12); status <<= 1; } /* if port is not enabled, port cannot be suspended */ else { OS_LOG_MESSAGE_MEDIUM(UHCD," Port is not enabled \n",0,0,0,0); /* port Suspend = 0 */ status |= 0; status <<= 1; } /* Check if port is enabled and update the status */ status |= usbUhcdGetBit ( pHCDData, offset, 2); status <<= 1; /* Check if there is a device connected and update the status */ status |= usbUhcdGetBit (pHCDData, offset, 0); /* status has to sent in LITTLE ENDIAN format */ status = OS_UINT32_CPU_TO_LE(status); /* Update the port status bytes - End */ /* Copy the status information generated into URB's buffer */ usbUhcdCopy (pUrb->pTransferBuffer, (UCHAR *) &status, NULL, 4); OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting get port status\n",0,0,0,0); /* Return the status */ return USB_UHCD_PASS; }/* End of usbUhcdGetPortStatus() *//***************************************************************************** usbUhcdSetPortFeature - handles the hub specific request for Root hub** This function handles the SET_PORT_FEATURE hub specific , called by * usbUhcdProcessRhControlTransfer().** RETURNS: USB_UHCD_FAIL if there is an error in setting the port status** ERRNO:* None.** \NOMANUAL*/INT32 usbUhcdSetPortFeature ( PUHCD_DATA pHCDData, USBHST_URB *pUrb ) { /* To hold the offset of the register */ UINT32 offset = 0; /* To hold the port number */ UINT8 port = 0; UINT16 wValue = 0; UINT16 wIndex = 0; UINT16 wLength = 0; pUSBHST_SETUP_PACKET pSetupPacket = (pUSBHST_SETUP_PACKET )pUrb->pTransferSpecificData; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering set port feature\n",0,0,0,0); /* Check if the URB and the DevRequest pointers are valid */ if (NULL == pUrb || NULL == pUrb->pTransferSpecificData) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pointers are not validn\n",0,0,0,0); return USB_UHCD_FAIL; } wValue = OS_UINT16_CPU_TO_LE(pSetupPacket->wValue); wIndex = OS_UINT16_CPU_TO_LE(pSetupPacket->wIndex); wLength = OS_UINT16_CPU_TO_LE(pSetupPacket->wLength); /* Extract the port number from URB's DevRequest */ port = wIndex; OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking the parameters\n",0,0,0,0); /* * Check whether there are any invalid conditions. * i.e invalid port, invalid DevRequest parameters */ if (port < USB_UHCD_PORT_1 || port > USB_UHCD_PORT_2 || wLength!=0) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Invalid conditions\n",0,0,0,0); return USB_UHCD_FAIL; } /* The parameters are valid */ else { OS_LOG_MESSAGE_MEDIUM(UHCD,"valid parameters\n",0,0,0,0); /* Get the correct offset based on port number */ offset = (port==1)? (USB_UHCD_PORT1) : (USB_UHCD_PORT2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -