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

📄 usbdcorelib.c

📁 T2.0 USB driver.rar T2.0 USB driver.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (usbdPipeCreate (internalClient, pNode->nodeHandle, 	    pEpDescr->endpointAddress, pCfgDescr->configurationValue, 0, 	    USB_XFRTYPE_INTERRUPT, USB_DIR_IN, 	    FROM_LITTLEW (pEpDescr->maxPacketSize), HUB_STATUS_LEN (pNode), 	    pEpDescr->interval, &pNode->hubStatusPipe) != OK)	    {	    return FALSE;	    }	/* Allocate structures for downstream nodes. */	if ((pNode->pPorts = OSS_CALLOC (pNode->numPorts * sizeof (USBD_PORT))) 	    == NULL)	    return FALSE;	/* Initialize each hub port */	for (port = 0; port < pNode->numPorts; port++)	    {	    /* Enable power to the port */	    usbdFeatureSet (internalClient, pNode->nodeHandle, 		USB_RT_CLASS | USB_RT_OTHER, USB_HUB_FSEL_PORT_POWER, port + 1);	    }	OSS_THREAD_SLEEP (pNode->pwrGoodDelay); /* let power stabilize */	/* Initialize an IRP to listen for status changes on the hub */	if (!initHubIrp (pNode))	    return FALSE;	}        return TRUE;    }/***************************************************************************** createNode - Creates and initializes new USBD_NODE** If the node is a hub, then automatically initializes hub.** RETURNS: pointer to newly created USBD_NODE, or*	   NULL if not successful*/LOCAL pUSBD_NODE createNode     (    pUSBD_BUS pBus,		    /* node's parent bus */    USBD_NODE_ID rootId,	    /* root id */    USBD_NODE_ID parentHubId,	    /* parent hub id */    UINT16 parentHubPort,	    /* parent hub port no */    UINT16 nodeSpeed,		    /* node speed */    UINT16 topologyDepth	    /* this node's depth in topology */    )    {    pUSBD_NODE pNode;    pUSBD_PIPE pPipe;    UINT16 actLen;    /* Allocate/initialize USBD_NODE */    if ((pNode = OSS_CALLOC (sizeof (*pNode))) == NULL)	return NULL;    if (usbHandleCreate (USBD_NODE_SIG, pNode, &pNode->nodeHandle) != OK ||	OSS_SEM_CREATE (1, 1, &pNode->controlSem) != OK)	{	destroyNode (pNode);	return NULL;	}    pNode->pBus = pBus;    pNode->nodeInfo.nodeSpeed = nodeSpeed;    pNode->nodeInfo.parentHubId = parentHubId;    pNode->nodeInfo.parentHubPort = parentHubPort;    pNode->nodeInfo.rootId = (rootId == 0) ? pNode->nodeHandle : rootId;    pNode->topologyDepth = topologyDepth;    /* Create a pipe for control transfers to this device. */    if (usbdPipeCreate (internalClient, pNode->nodeHandle, USB_ENDPOINT_CONTROL,	0, 0, USB_XFRTYPE_CONTROL, USB_DIR_INOUT, USB_MIN_CTRL_PACKET_SIZE, 0, 0, 	&pNode->controlPipe) != OK)	{	destroyNode (pNode);	return NULL;	}    /* Read the device descriptor to get the maximum payload size and to     * determine if this is a hub or not.     *     * NOTE: We read only the first 8 bytes of the device descriptor (which     * takes us through the maxPacketSize field) as suggested by the USB     * spec.     */    if (usbdDescriptorGet (internalClient, pNode->nodeHandle,	USB_RT_STANDARD | USB_RT_DEVICE, USB_DESCR_DEVICE, 0, 0,	USB_MIN_CTRL_PACKET_SIZE, (pUINT8) &pNode->devDescr, &actLen) != OK ||	actLen < USB_MIN_CTRL_PACKET_SIZE)	{	destroyNode (pNode);	return NULL;	}    /* Now that we've read the device descriptor, we know the actual     * packet size supported by the control pipe.  Update the pipe     * accordingly.     */    validatePipe (pNode->controlPipe, &pPipe);    pPipe->maxPacketSize = pNode->devDescr.maxPacketSize0;  /* field is byte wide */    /* Set a unique address for this device. */    if (!assignAddress (pNode))	{	destroyNode (pNode);	return NULL;	}    /* Notify the HCD of the change in device address and max packet size */    usbHcdPipeModify (&pBus->pHcd->nexus, pPipe->hcdHandle, 	pNode->busAddress, pPipe->maxPacketSize);    /* If this is a hub node, it requires additional initialization.  Otherwise,     * we're done unless and until a client performs additional I/O to this     * device.     */    if (pNode->devDescr.deviceClass == USB_CLASS_HUB)	{	pNode->nodeInfo.nodeType = USB_NODETYPE_HUB;	if (!initHubNode (pNode))	    {	    destroyNode (pNode);	    return NULL;	    }	}    else	{	pNode->nodeInfo.nodeType = USB_NODETYPE_DEVICE;	}    /* Read the device class type(s) from the device and notify interested     * clients of the device's insertion.     */    interrogateDeviceClass (pNode, pNode->devDescr.deviceClass,	pNode->devDescr.deviceSubClass, pNode->devDescr.deviceProtocol);    notifyClients (pNode, USBD_DYNA_ATTACH);    return pNode;    }/***************************************************************************** checkHubStatus - checks hub status and updates hub as necessary** Note: We take a Node ID as our parameter (instead of, say, a pointer* to a USBD_NODE structure) so that we can validate the node upon entry.* There are cases where this routine may be called when the underlying* node has already disappeared.** RETURNS: N/A*/LOCAL VOID checkHubStatus    (    USBD_NODE_ID nodeId    )    {    pUSBD_NODE pNode;    pUSB_IRP pIrp;    UINT16 port;    UINT8 portMask;    UINT8 statusIndex;    /* Is the node still valid? */    if (!validateNode (nodeId, &pNode))	return;    pIrp = &pNode->hubIrp;    /* Determine what status is available.     *     * The hubStatus vector contains one bit for the hub itself and      * then one bit for each port.     */    if (pIrp->result == OK)	{	port = 0;	statusIndex = 0;	portMask = USB_HUB_ENDPOINT_STS_PORT0;	while (port < pNode->numPorts && statusIndex < pIrp->bfrList [0].actLen)	    {	    if ((pNode->hubStatus [statusIndex] & portMask) != 0)		{		/* This port appears to have status to report */		updateHubPort (pNode, port);		}	    port++;	    portMask <<= 1;	    if (portMask == 0)		{		portMask = 0x01;    /* next byte starts with bit 0 */		statusIndex++;		}	    }	}    /* resubmit the IRP */    if (pIrp->result != S_usbHcdLib_IRP_CANCELED)	initHubIrp (pNode);    }/***************************************************************************** busThread - bus monitor thread** A separate busThread() thread is spawned for each bus currently* attached to the USBD.  This thread is responsible for monitoring and* responding to bus events, like the attachment and removal of devices.* Using a separate thread for each bus helps to ensure that one bus's * behavior won't affect the throughput of other buses.** By convention, the <param> is a pointer to the USBD_BUS structure* for the associated bus.  This thread waits on the bus queue* in the bus structure.  At the time this thread is first created,* the USBD_BUS structure is only guaranteed to have an initialized* queue...other fields may not yet be initialized.** RETURNS: N/A*/LOCAL VOID busThread    (    pVOID param 		    /* thread parameter */    )    {    pUSBD_BUS pBus = (pUSBD_BUS) param;    USB_MESSAGE msg;    /* Execute messages from the busQueue until a BUS_FNC_TERMINATE    message is received. */    do	{	if (usbQueueGet (pBus->busQueue, &msg, OSS_BLOCK) != OK)	    break;	switch (msg.msg)	    {	    case BUS_FNC_UPDATE_HUB:		OSS_MUTEX_TAKE (structMutex, OSS_BLOCK);		checkHubStatus ((USBD_NODE_ID) msg.lParam);		OSS_MUTEX_RELEASE (structMutex);		break;	    }	}    while (msg.msg != BUS_FNC_TERMINATE);    /* Mark the callback routine as having terminated. */    OSS_SEM_GIVE (pBus->busExit);    }/***************************************************************************** hcdMngmtCallback - invoked when HCD detects managment event** RETURNS: N/A*/LOCAL VOID hcdMngmtCallback    (    pVOID mngmtCallbackParam,	    /* caller-defined param */    HCD_CLIENT_HANDLE handle,	    /* handle to host controller */    UINT16 busNo,		    /* bus number */    UINT16 mngmtCode		    /* management code */    )    {    pUSBD_HCD pHcd = (pUSBD_HCD) mngmtCallbackParam;    pUSBD_BUS pBus;    pUSBD_CLIENT pClient;    /* In an unusual case, this routine could be invoked by the HCD     * before we have completely initialized our structures.  In that     * case, just ignore the event.     */    if (pHcd->pBuses == NULL)	return;    pBus = &pHcd->pBuses [busNo];    if (pBus->busThread == NULL || pBus->busQueue == NULL ||	pBus->pRoot == NULL || pBus->pRoot->nodeHandle == NULL)	return;    /* Reflect the management event to interested clients */    OSS_MUTEX_TAKE (structMutex, OSS_BLOCK);    pClient = usbListFirst (&clientList);    while (pClient != NULL)	{	if (pClient->mngmtCallback != NULL)	    usbQueuePut (pClient->callbackQueue, CALLBACK_FNC_MNGMT_EVENT, 		mngmtCode, (UINT32) pBus->pRoot->nodeHandle, OSS_BLOCK);	pClient = usbListNext (&pClient->clientLink);	}    OSS_MUTEX_RELEASE (structMutex);    }/***************************************************************************** initHcdBus - Initialize USBD_BUS element of USBD_HCD structure** <pHcd> points to the USBD_HCD being initialized.  <busNo> is the index* of the HCD bus to be initialized.** RETURNS: S_usbdLib_xxxx*/LOCAL int initHcdBus    (    pUSBD_HCD pHcd,		    /* USBD_HCD being initialized */    UINT16 busNo		    /* Bus number to initialize */    )    {    pUSBD_BUS pBus = &pHcd->pBuses [busNo];    int s = OK;    /* Allocate resources for this bus. */    pBus->pHcd = pHcd;    pBus->busNo = busNo;    if (OSS_SEM_CREATE (1, 0, &pBus->busExit) != OK ||	usbQueueCreate (BUS_Q_DEPTH, &pBus->busQueue) != OK ||	OSS_THREAD_CREATE (busThread, pBus, OSS_PRIORITY_HIGH, "tUsbdBus", 	    &pBus->busThread) != OK ||	(pBus->pRoot = createNode (pBus, 0, 0, 0, USB_SPEED_FULL, 0)) == NULL)	{	/* NOTE: If we fail here, destroyHcd() will clean up partially	 * allocate structures/resources/etc.	 */	return S_usbdLib_OUT_OF_RESOURCES;	}    return s;    }/***************************************************************************** destroyHcd - tears down a USBD_HCD structure** Detaches the indicated HCD and tears down the HCD structures.** RETURNS: N/A*/LOCAL VOID destroyHcd    (    pUSBD_HCD pHcd    )    {    pUSBD_BUS pBus;    UINT16 busNo;    /* Unlink the HCD */    usbListUnlink (&pHcd->hcdLink);    /* Begin by de-allocating resources related to each bus */    for (busNo = 0; pHcd->pBuses != NULL && busNo < pHcd->busCount; busNo++)	{	pBus = &pHcd->pBuses [busNo];	/* Destroy all nodes associated with this bus */	destroyAllNodes (pBus->pRoot);	/* NOTE: The busQueue is always allocated before the busThread. */	if (pBus->busThread != NULL)	    {	    /* Issue a terminate request to the bus thread */	    usbQueuePut (pBus->busQueue, BUS_FNC_TERMINATE, 0, 0, BUS_TIMEOUT);	    OSS_SEM_TAKE (pBus->busExit, BUS_TIMEOUT);	    OSS_THREAD_DESTROY (pBus->busThread);	    }	if (pBus->busQueue != NULL)	    usbQueueDestroy (pBus->busQueue);	if (pBus->busExit != NULL)	    OSS_SEM_DESTROY (pBus->busQueue);	}    /* Detach the HCD */    if (pHcd->nexus.hcdExecFunc != NULL && pHcd->nexus.handle != NULL)	usbHcdDetach (&pHcd->nexus);    /* Release USBD_HCD resources */    if (pHcd->attachToken != NULL)	usbHandleDestroy (pHcd->attachToken);    OSS_FREE (pHcd);    }/***************************************************************************** fncHcdAttach - Attach an HCD to the USBD** RETURNS: S_usbdLib_xxxx*/LOCAL int fncHcdAttach    (    pURB_HCD_ATTACH pUrb    )    {    pUSBD_HCD pHcd = NULL;    UINT16 busNo;    int s;    /* validate URB */    if ((s = validateUrb (pUrb, sizeof (*pUrb), NULL)) != OK)	return s;    /* Allocate structure for this host controller */    if ((pHcd = OSS_CALLOC (sizeof (*pHcd))) == NULL)	return S_usbdLib_OUT_OF_MEMORY;    /* Issue an attach request to the HCD.  If it succeeds, determine the     * number of buses managed by the HCD.     */    if (usbHcdAttach (pUrb->hcdExecFunc, pUrb->param, hcdMngmtCallback,	pHcd, &pHcd->nexus, &pHcd->busCount) != OK)	{	OSS_FREE (pHcd);	return S_usbdLib_GENERAL_FAULT;	}    if ((pHcd->pBuses = OSS_CALLOC (sizeof (USBD_BUS) * pHcd->busCount)) == NULL)	{	destroyHcd (pHcd);	return S_usbdLib_OUT_OF_MEMORY;	}    /* Initialize the USBD_HCD */    if (usbHandleCreate (USBD_HCD_SIG, pHcd, &pHcd->attachToken) != OK)	{	s = S_usbdLib_OUT_OF_RESOURCES;	}    else	{	/* Fetch information about each bus from the HCD. */	for (busNo = 0; busNo < pHcd->busCount; busNo++)	    {	    if ((s = initHcdBus (pHcd, busNo)) != OK)		break;	    }	}    /* If we succeeded in initializing each bus, then the USBD_HCD     * is fully initialized...link it into the list of HCDs     */    if (s == OK)	{	usbListLink (&hcdList, pHcd, &pHcd->hcdLink, LINK_TAIL);	/* Return attachToken to caller */	pUrb->attachToken = pHcd->attachToken;

⌨️ 快捷键说明

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