📄 usbbulkdevlib.c
字号:
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 + -