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

📄 usbdcorelib.c

📁 MPC5200 BSP 支持ATA,USB, I2C,扩展网口
💻 C
📖 第 1 页 / 共 5 页
字号:
    destroyClient (pClient);    return s;    }LOCAL int fncMngmtCallbackSet    (    pURB_MNGMT_CALLBACK_SET pUrb    )    {    pUSBD_CLIENT pClient;    int s;    /* validate URB */    if ((s = validateUrb (pUrb, sizeof (*pUrb), &pClient)) != OK)	return s;    /* Set the management callback */    pClient->mngmtCallback = pUrb->mngmtCallback;    pClient->mngmtCallbackParam = pUrb->mngmtCallbackParam;    return s;    }LOCAL int fncVersionGet    (    pURB_VERSION_GET pUrb    )    {    int s;    /* validate urb */    if ((s = validateUrb (pUrb, sizeof (*pUrb), NULL)) != OK)	return s;    /* return version information */    pUrb->version = USBD_VERSION;    strncpy ((char *)pUrb->mfg, USBD_MFG, USBD_NAME_LEN);    return s;    }LOCAL VOID releaseAddress    (    pUSBD_NODE pNode    )    {    pUSBD_BUS pBus = pNode->pBus;    pBus->adrsVec [pNode->busAddress / 8] &= ~(0x1 << (pNode->busAddress % 8));    }LOCAL BOOL assignAddress    (    pUSBD_NODE pNode    )    {    pUSBD_BUS pBus = pNode->pBus;    UINT16 i;    /* Find an available address */    for (i = 1; i < USB_MAX_DEVICES; i++)	{	if ((pBus->adrsVec [i / 8] & (0x1 << (i % 8))) == 0)	    {	    /* i is the value of an unused address.  Set the device adrs. */	    if (usbdAddressSet (internalClient, pNode->nodeHandle, i) == OK)		{		pNode->busAddress = i;		pBus->adrsVec [i / 8] |= 0x1 << (i % 8);		return TRUE;		}	    else		{		return FALSE;		}	    }	}    return FALSE;    }LOCAL VOID notifyIfMatch    (    pUSBD_NODE pNode,    pUSBD_NODE_CLASS pClassType,    pUSBD_CLIENT pClient,    pUSBD_NOTIFY_REQ pNotify,    UINT16 attachCode    )    {    pNOTIFICATION pNotification;    /* Do the pClassType and pNotify structures contain matching class     * descriptions?     */    if (pNotify->deviceClass == USBD_NOTIFY_ALL ||	pClassType->deviceClass == pNotify->deviceClass)	{	if (pNotify->deviceSubClass == USBD_NOTIFY_ALL ||	    pClassType->deviceSubClass == pNotify->deviceSubClass)	    {	    if (pNotify->deviceProtocol == USBD_NOTIFY_ALL ||		pClassType->deviceProtocol == pNotify->deviceProtocol)		{				if ((pNotification = OSS_CALLOC (sizeof (*pNotification))) 		    != NULL)		    {		    pNotification->callback = pNotify->callback;		    pNotification->nodeId = pNode->nodeHandle;		    pNotification->attachCode = attachCode;		    pNotification->configuration = pClassType->configuration;		    pNotification->interface = pClassType->interface;		    pNotification->deviceClass = pClassType->deviceClass;		    pNotification->deviceSubClass = pClassType->deviceSubClass;		    pNotification->deviceProtocol = pClassType->deviceProtocol;		    usbQueuePut (pClient->callbackQueue, 			CALLBACK_FNC_NOTIFY_ATTACH, 0, (UINT32) pNotification, 			OSS_BLOCK);		    }		}	    }	}    }LOCAL VOID notifyClients    (    pUSBD_NODE pNode,    UINT16 attachCode    )    {    pUSBD_CLIENT pClient;    pUSBD_NOTIFY_REQ pNotify;    pUSBD_NODE_CLASS pClassType;    /* Scan for clients which have requested dynamic attach notification. */    pClient = usbListFirst (&clientList);    while (pClient != NULL)	{	/* Walk through the list of notification requests for this client */	pNotify = usbListFirst (&pClient->notifyReqs);	while (pNotify != NULL)	    {	    /* Walk through the class types for this node, looking for one	     * which matches the current client notification request.	     */	    pClassType = usbListFirst (&pNode->classTypes);	    while (pClassType != NULL)		{		notifyIfMatch (pNode, pClassType, pClient, pNotify, attachCode);		pClassType = usbListNext (&pClassType->classLink);		}	    pNotify = usbListNext (&pNotify->reqLink);	    }	pClient = usbListNext (&pClient->clientLink);	}    }LOCAL BOOL createNodeClass    (    pUSBD_NODE pNode,    UINT16 configuration,    UINT16 interface,    UINT16 deviceClass,    UINT16 deviceSubClass,    UINT16 deviceProtocol    )    {    pUSBD_NODE_CLASS pClassType;    if ((pClassType = OSS_CALLOC (sizeof (*pClassType))) == NULL)	return FALSE;    pClassType->configuration = configuration;    pClassType->interface = interface;    pClassType->deviceClass = deviceClass;    pClassType->deviceSubClass = deviceSubClass;    pClassType->deviceProtocol = deviceProtocol;    usbListLink (&pNode->classTypes, pClassType, &pClassType->classLink,	LINK_TAIL);    return TRUE;    }LOCAL BOOL interrogateDeviceClass    (    pUSBD_NODE pNode,    UINT16 deviceClass,    UINT16 deviceSubClass,    UINT16 deviceProtocol    )    {    pUSB_CONFIG_DESCR pCfgDescr;    pUSB_INTERFACE_DESCR pIfDescr;    pUINT8 pCfgBfr;    pUINT8 pRemBfr;    UINT16 cfgLen;    UINT16 remLen;    UINT16 numConfig;    UINT8 configIndex;    BOOL retcode = TRUE;    UINT8 configValue = 1;        /* If class information has been specified at the device level, then     * record it and return.     */    if ((deviceClass != 0) && (deviceSubClass != 0) && (deviceProtocol != 0))	return createNodeClass (pNode, 0, 0, deviceClass, deviceSubClass,	    deviceProtocol);     /* Read the device descriptor to determine the number of configurations. */    if (usbConfigCountGet (internalClient, pNode->nodeHandle, &numConfig) != OK)	return FALSE;      /* Read and process each configuration. */    for (configIndex = 0; configIndex < numConfig && retcode; configIndex++)	{	/* Read the next configuration descriptor. */		if (usbConfigDescrGet (internalClient, pNode->nodeHandle, configIndex,	    &cfgLen, &pCfgBfr) != OK)	    {	    retcode = FALSE;	    }	else	    {	    if ((pCfgDescr = usbDescrParse (pCfgBfr, cfgLen, 		USB_DESCR_CONFIGURATION)) != NULL)		{		/* Scan each interface descriptor. 		 *		 * NOTE: If we can't find an interface descriptor, we just keep		 * going. 		 */		pRemBfr = pCfgBfr;		remLen = cfgLen;		configValue = pCfgDescr->configurationValue;		while ((pIfDescr = usbDescrParseSkip (&pRemBfr, &remLen, 		    USB_DESCR_INTERFACE)) != NULL && retcode)		    {		    if (!createNodeClass (pNode, configValue,			pIfDescr->interfaceNumber, pIfDescr->interfaceClass, 			pIfDescr->interfaceSubClass, pIfDescr->interfaceProtocol))			{			retcode = FALSE;			}		    }		}	    /* Release bfr allocated by usbConfigDescrGet(). */    	    OSS_FREE (pCfgBfr);	    }	}    return retcode;    }/***************************************************************************** destroyNode - deletes node structure** RETURNS: N/A*/LOCAL VOID destroyNode    (    pUSBD_NODE pNode    )    {    pUSBD_NODE_CLASS pClassType;    pUSBD_PIPE pPipe;    /* Mark node as "going down" */    pNode->nodeDeletePending = TRUE;    /* Cancel any other pipes associated with this node...This has the     * effect of cancelling any IRPs outstanding on this node. */    while ((pPipe = usbListFirst (&pNode->pipes)) != NULL)	destroyPipe (pPipe);    /* Notify an interested clients that this node is going away. */    notifyClients (pNode, USBD_DYNA_REMOVE);    /* Delete any class type structures associated with this node. */    while ((pClassType = usbListFirst (&pNode->classTypes)) != NULL)	{	usbListUnlink (&pClassType->classLink);	OSS_FREE (pClassType);	}    /* release bus address associated with node */    releaseAddress (pNode);    /* Release node resources/memory. */    if (pNode->controlSem != NULL)	OSS_SEM_DESTROY (pNode->controlSem);    if (pNode->nodeHandle != NULL)	usbHandleDestroy (pNode->nodeHandle);    OSS_FREE (pNode->pHubStatus);    OSS_FREE (pNode);    }/***************************************************************************** destroyAllNodes - destroys all nodes in a tree of nodes** Recursively destroys all nodes from <pNode> and down.  If <pNode> is* NULL, returns immediately.** RETURNS: N/A*/LOCAL VOID destroyAllNodes    (    pUSBD_NODE pNode    )    {    int i;    if (pNode != NULL)	{	if (pNode->nodeInfo.nodeType == USB_NODETYPE_HUB &&	    pNode->pPorts != NULL)	    {	    /* destroy all children of this node */	    for (i = 0; i < pNode->numPorts; i++)		destroyAllNodes (pNode->pPorts [i].pNode);	    }	destroyNode (pNode);	}    }/***************************************************************************** updateHubPort - Determine if a device has been attached/removed** Note: The <port> parameter to this function is 0-based (0 = first port,* 1 = second port, etc.)  However, on the USB interface itself, the index* passed in a Setup packet to identify a port is 1-based.** RETURNS: N/A*/LOCAL VOID updateHubPort    (    pUSBD_NODE pNode,    UINT16 port    )    {    USB_HUB_STATUS * pStatus;    UINT16 actLen;    UINT16 nodeSpeed;    pStatus = OSS_MALLOC (sizeof (USB_HUB_STATUS));    /* retrieve status for the indicated hub port. */    if (usbdStatusGet (internalClient, 		       pNode->nodeHandle, 		       USB_RT_CLASS | USB_RT_OTHER, 		       port + 1, 		       sizeof (USB_HUB_STATUS), 		       (UINT8 *) pStatus, 		       &actLen) != OK ||	actLen < sizeof (USB_HUB_STATUS))	{	OSS_FREE (pStatus);	return;	}    /* correct the status byte order */    pStatus->status = FROM_LITTLEW (pStatus->status);    pStatus->change = FROM_LITTLEW (pStatus->change);    /* Process the change indicated by status.change */    /* NOTE: To see if a port's connection status has changed we also see     * whether our internal understanding of the port's connection status     * matches the hubs's current connection status.  If the two do not     * agree, then we also assume a connection change, whether the hub is     * indicating one or not. This covers the case at power on where the     * hub does not report a connection change (i.e., the device is already     * plugged in), but we need to initialize the port for the first time.     */    if ((pStatus->change & USB_HUB_C_PORT_CONNECTION) != 0 ||	((pNode->pPorts [port].pNode == NULL) != 	    ((pStatus->status & USB_HUB_STS_PORT_CONNECTION) == 0)))	{	/* Given that there has been a change on this port, it stands to	 * reason that all nodes connected to this port must be invalidated -	 * even if a node currently appears to be connected to the port.	 */	destroyAllNodes (pNode->pPorts [port].pNode);	pNode->pPorts [port].pNode = NULL;	/* If a node appears to be connected to the port, reset the port. */	if ((pStatus->status & USB_HUB_STS_PORT_CONNECTION) != 0)	    {	    /* Wait 100 msec after detecting a connection to allow power to	     * stabilize.  Then enable the port and issue a reset.	     */	    OSS_THREAD_SLEEP (USB_TIME_POWER_ON);	    usbdFeatureSet (internalClient, pNode->nodeHandle,		USB_RT_CLASS | USB_RT_OTHER, USB_HUB_FSEL_PORT_RESET, port + 1);	    /* 	     * Acoording to the USB spec (refer to section 7.1.7.3) we should 	     * wait 50 msec for reset signaling + an additional 10 msec reset 	     * recovery time.  We double this time for safety's sake since 	     * we have seen a few devices that do not respond to the suggested 	     * time of 60 msec.	     */ 	    OSS_THREAD_SLEEP (2*USB_TIME_RESET + USB_TIME_RESET_RECOVERY);	    }	/* Clear the port connection change indicator - whether or not it	 * appears that a device is currently connected. */	usbdFeatureClear (internalClient, pNode->nodeHandle, 	    USB_RT_CLASS | USB_RT_OTHER, USB_HUB_FSEL_C_PORT_CONNECTION, port + 1);	/* If a node appears to be connected, create a new node structure for 	 * it and attach it to this hub. */	if ((pStatus->status & USB_HUB_STS_PORT_CONNECTION) != 0)	    {	    /* If the following call to createNode() fails, it returns NULL.	     * That's fine, as the corresponding USBD_PORT structure will be	     * initialized correctly either way.	     */	    nodeSpeed = ((pStatus->status & USB_HUB_STS_PORT_LOW_SPEED) != 0) ?		USB_SPEED_LOW : USB_SPEED_FULL;	    if ((pNode->pPorts [port].pNode = createNode (pNode->pBus,		pNode->pBus->pRoot->nodeHandle, pNode->nodeHandle, port,		nodeSpeed, pNode->topologyDepth + 1)) == NULL)		{		/* Attempt to initialize the port failed.  Disable the port */		usbdFeatureClear (internalClient, pNode->nodeHandle,		    USB_RT_CLASS | USB_RT_OTHER, USB_HUB_FSEL_PORT_ENABLE, 			port + 1);		}	    }	}    if ((pStatus->change & USB_HUB_C_PORT_ENABLE) != 0)	{	/* Clear the port enable change indicator */	usbdFeatureClear (internalClient, pNode->nodeHandle, 	    USB_RT_CLASS | USB_RT_OTHER, USB_HUB_FSEL_C_PORT_ENABLE, port + 1);	}    if ((pStatus->change & USB_HUB_C_PORT_SUSPEND) != 0)	{	/* Clear the suspend change indicator */	usbdFeatureClear (internalClient, pNode->nodeHandle, 	    USB_RT_CLASS | USB_RT_OTHER, USB_HUB_FSEL_C_PORT_SUSPEND, port + 1);	}    if ((pStatus->change & USB_HUB_C_PORT_OVER_CURRENT) != 0)	{	/* Clear the over current change indicator */	usbdFeatureClear (internalClient, pNode->nodeHandle,	    USB_RT_CLASS | USB_RT_OTHER, USB_HUB_FSEL_C_PORT_OVER_CURRENT, 	    port + 1);	}    if ((pStatus->change & USB_HUB_C_PORT_RESET) != 0)	{	/* Clear the reset change indicator */	usbdFeatureClear (internalClient, pNode->nodeHandle, 	    USB_RT_CLASS | USB_RT_OTHER, USB_HUB_FSEL_C_PORT_RESET, port + 1);	}    }/***************************************************************************** hubIrpCallback - called when hub status IRP completes** By convention, the USB_IRP.userPtr field is a pointer to the USBD_NODE* for this transfer.** RETURNS: N/A*/LOCAL VOID hubIrpCallback    (    pVOID p			/* completed IRP */    )    {    pUSB_IRP pIrp = (pUSB_IRP) p;    pUSBD_NODE pNode = (pUSBD_NODE) pIrp->userPtr;    /* If the IRP was canceled, it means that the hub node is being torn     * down, so don't queue a request for the bus thread.     */    if (pIrp->result != S_usbHcdLib_IRP_CANCELED)	{	/* Let the bus thread update the port and re-queue the hub IRP. */	usbQueuePut (pNode->pBus->busQueue, BUS_FNC_UPDATE_HUB,	    0, (UINT32) pNode->nodeHandle, OSS_BLOCK);	}

⌨️ 快捷键说明

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