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

📄 usbbulkdevlib.c

📁 SL811 USB接口芯片用于VxWorks系统的驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                OSS_SEM_GIVE (bulkIrpSem);  
                return (USB_INTERNAL_ERROR);
                }
       
            /* 
             * wait till the data transfer ends on bulk out pipe before reading
             * the command status 
             */

            if ( OSS_SEM_TAKE (bulkIrpSem, 
                               usbBulkIrpTimeOut + USB_BULK_OFFS) == ERROR )
                {
                USB_BULK_DEBUG ("usbBulkCmdExecute: Irp time out \n", 
                                0, 0, 0, 0, 0, 0);
                OSS_SEM_GIVE (bulkIrpSem);
                return (USB_INTERNAL_ERROR);
                }
            }  
        }

    /* read the command status from the device. */

    memset (&pBulkDev->statusIrp, 0, sizeof (USB_IRP));

    /* Form an IRP to read the CSW from the BULK_IN pipe */

    pBulkDev->statusIrp.irpLen            = sizeof( USB_IRP );
    pBulkDev->statusIrp.userCallback      = usbBulkIrpCallback;
    pBulkDev->statusIrp.timeout           = usbBulkIrpTimeOut;
    pBulkDev->statusIrp.transferLen       = USB_CSW_LENGTH;
    pBulkDev->statusIrp.bfrCount          = 0x01;  
    pBulkDev->statusIrp.bfrList[0].pid    = USB_PID_IN;
    pBulkDev->statusIrp.bfrList[0].pBfr   = (UINT8 *)(&pBulkDev->bulkCsw);
    pBulkDev->statusIrp.bfrList[0].bfrLen = USB_CSW_LENGTH;
    pBulkDev->statusIrp.userPtr           = pBulkDev;

    /* Submit IRP */

    if (usbdTransfer (usbdHandle, 
		      pBulkDev->inPipeHandle, 
		      &pBulkDev->statusIrp) 
		    != OK)
        {
        USB_BULK_ERR ("usbBulkCmdExecute: Unable to submit Status IRP\n",
                      0, 0, 0, 0, 0, 0);
        OSS_SEM_GIVE (bulkIrpSem);
        return (USB_INTERNAL_ERROR);
        }

    if ( OSS_SEM_TAKE (bulkIrpSem, 
                       usbBulkIrpTimeOut + USB_BULK_OFFS) 
		     == ERROR )
        {
        USB_BULK_DEBUG ("usbBulkCmdExecute: Irp time out \n", 
                        0, 0, 0, 0, 0, 0);
        OSS_SEM_GIVE (bulkIrpSem);
        return (USB_INTERNAL_ERROR);
        }

    /* Check whether status IRP was transferred */
        
    if (pBulkDev->statusIrp.result == S_usbHcdLib_STALLED)  /* if stalled */
        { 
 
        /* Clear STALL on the BULK IN endpoint */

        if ((usbdFeatureClear (usbdHandle, 
			       pBulkDev->bulkDevId, 
			       USB_RT_ENDPOINT, 
			       USB_FSEL_DEV_ENDPOINT_HALT, 
			       (pBulkDev->inEpAddress & 0x7F))) 
			      != OK)
            {
            USB_BULK_ERR ("usbBulkCmdExecute: Failed to clear HALT feauture "\
                          "on bulk in Endpoint %x\n", 0, 0, 0, 0, 0, 0);
            }  

        /* Try to read the CSW once again */

        if (usbdTransfer (usbdHandle, 
			  pBulkDev->inPipeHandle, 
			  &pBulkDev->statusIrp) 
			!= OK)
            {
            USB_BULK_ERR ("usbBulkCmdExecute: Unable to submit Status IRP\n",
                          0, 0, 0, 0, 0, 0);
            OSS_SEM_GIVE (bulkIrpSem);
            return (USB_INTERNAL_ERROR);
            } 

        if ( OSS_SEM_TAKE (bulkIrpSem, 
                           usbBulkIrpTimeOut + USB_BULK_OFFS) 
			 == ERROR )
            {
            USB_BULK_DEBUG ("usbBulkCmdExecute: Irp time out \n", 
                            0, 0, 0, 0, 0, 0);
            OSS_SEM_GIVE (bulkIrpSem);
            return (USB_INTERNAL_ERROR);
            }

        /* how about the status this time */

        if (pBulkDev->statusIrp.result == S_usbHcdLib_STALLED)
            {
            /* Failed to read CSW again. Do reset recovery */
            
            OSS_SEM_GIVE (bulkIrpSem);
            usbBulkDevResetRecovery (pBulkDev); 
            return (USB_BULK_IO_ERROR);
            }
        }

    OSS_SEM_GIVE (bulkIrpSem);    

    /* If any error other than STALL on Endpoint. */ 

    if ( pBulkDev->statusIrp.result != OK )
        {
        return (USB_IRP_FAILED);
        }

    /* If successful in transferring the CSW IRP, check the buffer */

    pCsw = (pUSB_BULK_CSW)(pBulkDev->statusIrp.bfrList[0].pBfr);

    /* Check the length of CSW received. If not USB_CSW_LENGTH, invalid CSW. */


    if ( pBulkDev->statusIrp.bfrList[0].actLen != USB_CSW_LENGTH)
        {
        USB_BULK_ERR ("usbBulkCmdExecute: Invalid CSW\n", 0, 0, 0, 0, 0, 0);
        usbBulkDevResetRecovery (pBulkDev);   
        return (USB_INVALID_CSW);
        }

    /* check the signature/tag/status in command status block */

    if ( (pCsw->signature != USB_BULK_SWAP_32 (USB_CSW_SIGNATURE)) 
         || (pCsw->tag != USB_BULK_SWAP_32 (USB_CBW_TAG))
         || (pCsw->status > USB_CSW_PHASE_ERROR))
        {
        USB_BULK_ERR ("usbBulkCmdExecute: Logical Error in status block\n", 
                      0, 0, 0, 0, 0, 0);   
        usbBulkDevResetRecovery (pBulkDev);
        return (USB_INVALID_CSW);
        }
 
    /* check for Data residue. */ 
        
    if (pCsw->dataResidue > 0) 
        { 
        USB_BULK_ERR ("usbBulkCmdExecute: Data transfer incomplete\n", 
                      0, 0, 0, 0, 0, 0);   
        return (USB_DATA_INCOMPLETE); 
        }

    /* It is a valid CSW. Check for the status of the CBW executed */

    if ( pCsw->status == USB_CSW_STATUS_FAIL )  /* Command failed */
        {
        USB_BULK_ERR ("usbBulkCmdExecute: CBW Failed \n", 0, 0, 0, 0, 0, 0);
        return (USB_COMMAND_FAILED); 
        } 
    else if (pCsw->status == USB_CSW_PHASE_ERROR) 
        {
        /* Phase error while executing the command in CBW. Reset recovery */ 

        USB_BULK_ERR ("usbBulkCmdExecute: Phase Error\n", 0, 0, 0, 0, 0, 0);
           
        /* fatal error. do a reset recovery */        

        usbBulkDevResetRecovery (pBulkDev);
        return (USB_PHASE_ERROR);
        }    

    return (USB_COMMAND_SUCCESS);
    }


/***************************************************************************
*
* usbBulkDevDestroy - release USB_BULK_DEV structure and its links
*
* Unlinks the indicated USB_BULK_DEV structure and de-allocates
* resources associated with the device.
*
* RETURNS: N/A
*/

LOCAL void usbBulkDevDestroy
    (
    pUSB_BULK_DEV pBlkDev       /* pointer to bulk device   */
    )

    {
    pUSB_BULK_DEV pBulkDev = (pUSB_BULK_DEV) pBlkDev;

    if (pBulkDev != NULL)
        {

        /* Unlink the structure. */

        usbListUnlink (&pBulkDev->bulkDevLink);

        /* Release pipes and wait for IRPs. */

        if (pBulkDev->outPipeHandle != NULL)
            usbdPipeDestroy (usbdHandle, pBulkDev->outPipeHandle);

        if (pBulkDev->inPipeHandle != NULL)
            usbdPipeDestroy (usbdHandle, pBulkDev->inPipeHandle);

        /* wait for any IRP to complete */

        OSS_SEM_TAKE (bulkIrpSem, OSS_BLOCK); 

        OSS_SEM_GIVE (bulkIrpSem);

        /* Release structure. */

        OSS_FREE (pBulkDev);
        }
    }

/***************************************************************************
*
* usbBulkDevFind - Searches for a USB_BULK_DEV for indicated node ID
*
* RETURNS: pointer to matching USB_BULK_DEV or NULL if not found
*/

LOCAL pUSB_BULK_DEV usbBulkDevFind
    (
    USBD_NODE_ID nodeId          /* node ID to be looked for */
    )

    {
    pUSB_BULK_DEV pBulkDev = usbListFirst (&bulkDevList);

    /* browse through the list */

    while (pBulkDev != NULL)
        {
        if (pBulkDev->bulkDevId == nodeId)
        break;

        pBulkDev = usbListNext (&pBulkDev->bulkDevLink);
        }

    return (pBulkDev);
    }

/***************************************************************************
*
* findEndpoint - Searches for a BULK endpoint of the indicated direction.
*
* RETURNS: pointer to matching endpoint descriptor or NULL if not found
*/

LOCAL pUSB_ENDPOINT_DESCR findEndpoint
    (
    pUINT8 pBfr,
    UINT16 bfrLen,
    UINT16 direction
    )

    {
    pUSB_ENDPOINT_DESCR pEp;

    while ((pEp = usbDescrParseSkip (&pBfr, &bfrLen, USB_DESCR_ENDPOINT)) 
          != NULL)
        {
        if ((pEp->attributes & USB_ATTR_EPTYPE_MASK) == USB_ATTR_BULK &&
            (pEp->endpointAddress & USB_ENDPOINT_DIR_MASK) == direction)
            break;
        }

    return pEp;
    }


/***************************************************************************
*
* usbBulkPhysDevCreate - create a USB_BULK_DEV Structure for the device attached
*
* This function is invoked from the dynamic attach callback routine whenever 
* a USB_BULK_DEV device is attached.  It allocates memory for the structure,
* sets device configuration, and creates pipe for bulk-in and bulk-out endpoints.
* 
* RETURNS: OK on success, ERROR if failed to create pipes, set configuration
*/

LOCAL STATUS usbBulkPhysDevCreate
    (
    USBD_NODE_ID nodeId,         /* USBD Node Id ofthe device */     
    UINT16       configuration,  /* Configuration value       */ 
    UINT16       interface       /* Interface Number          */ 
    )
    {
    UINT16   actLength;
    UINT8    bfr[255];           /* store for descriptors     */ 
    UINT8  * pBfr = bfr;         /* pointer to the above store*/ 
    UINT     ifNo;
    UINT16   maxPacketSize;  

    pUSB_BULK_DEV     pBulkDev;
    pUSB_CONFIG_DESCR pCfgDescr;
    pUSB_INTERFACE_DESCR pIfDescr;
    pUSB_ENDPOINT_DESCR pOutEp;
    pUSB_ENDPOINT_DESCR pInEp;

    /*
     * A new device is being attached.	Check if we already 
     * have a structure for this device.
     */

    if (usbBulkDevFind (nodeId) != NULL)
        return (OK);

    /* Allocate memory for a new structure to represent this device */

    if ((pBulkDev = OSS_CALLOC (sizeof (*pBulkDev))) == NULL)
        {
        USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to allocate memory\n",
                        0, 0, 0, 0, 0, 0);
        goto errorExit;
        }

    pBulkDev->bulkDevId     = nodeId; 
    pBulkDev->configuration = configuration;
    pBulkDev->interface     = interface;
    pBulkDev->connected     = TRUE;

    /* Check out the device configuration */

    /* Configuration index is assumed to be one less than config'n value */

    if (usbdDescriptorGet (usbdHandle, pBulkDev->bulkDevId, 
                           USB_RT_STANDARD | USB_RT_DEVICE, 
#if 0
                           USB_DESCR_CONFIGURATION, (configuration - 1), 
#else
                           USB_DESCR_CONFIGURATION, 0, 
#endif
                           0, 255, bfr, &actLength) != OK)  
        {
        USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to read configuration "\
                      "descriptor\n", 0, 0, 0, 0, 0, 0);
        goto errorExit;
        }

    if ((pCfgDescr = usbDescrParse (bfr, actLength, 
                                    USB_DESCR_CONFIGURATION)) == NULL)
        {
        USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to find configuration "\
                      "descriptor\n", 0, 0, 0, 0, 0, 0);
        goto errorExit;
        }
   
    /* Look for the interface representing the MSC/SCSI/BULK_ONLY. */

    ifNo = 0;
    while ((pIfDescr = usbDescrParseSkip (&pBfr, &actLength, 
                       USB_DESCR_INTERFACE)) != NULL)
        {
        if (ifNo == pBulkDev->interface)
            break;
        ifNo++;
        }

    if (pIfDescr == NULL)
        goto errorExit;

    pBulkDev->altSetting = pIfDescr->alternateSetting;

    /* 
     * Retrieve the endpoint descriptor(s) following the identified interface
     * descriptor.
     */

    if ((pOutEp = findEndpoint (pBfr, actLength, USB_ENDPOINT_OUT)) == NULL)
        goto errorExit;

⌨️ 快捷键说明

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