📄 usbmpc5200sffdevlib.c
字号:
if ( (pCsw->signature != USB_SFF_BULK_SWAP_32 (USB_SFF_CSW_SIGNATURE))
|| (pCsw->tag != USB_SFF_BULK_SWAP_32 (USB_SFF_CBW_TAG))
|| (pCsw->status > USB_SFF_CSW_PHASE_ERROR))
{
USB_SFF_BULK_ERR ("usbSFFBulkCmdExecute: Logical Error in status block\n",
0, 0, 0, 0, 0, 0);
usbSFFBulkDevResetRecovery (pBulkDev);
return (USB_INVALID_CSW);
}
/* check for Data residue. */
if (pCsw->dataResidue > 0)
{
USB_SFF_BULK_ERR ("usbSFFBulkCmdExecute: 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_SFF_CSW_STATUS_FAIL ) /* Command failed */
{
USB_SFF_BULK_ERR ("usbSFFBulkCmdExecute: CBW Failed \n", 0, 0, 0, 0, 0, 0);
return (USB_COMMAND_FAILED);
}
else if (pCsw->status == USB_SFF_CSW_PHASE_ERROR)
{
/* Phase error while executing the command in CBW. Reset recovery */
USB_SFF_BULK_ERR ("usbSFFBulkCmdExecute: Phase Error\n", 0, 0, 0, 0, 0, 0);
/* fatal error. do a reset recovery */
usbSFFBulkDevResetRecovery (pBulkDev);
return (USB_PHASE_ERROR);
}
return (USB_COMMAND_SUCCESS);
}
LOCAL void usbSFFBulkDevDestroy
(
pUSB_SFF_BULK_DEV pBlkDev /* pointer to bulk device */
)
{
pUSB_SFF_BULK_DEV pBulkDev = (pUSB_SFF_BULK_DEV) pBlkDev;
if (pBulkDev != NULL)
{
/* Unlink the structure. */
usbListUnlink (&pBulkDev->bulkDevLink);
/* Release pipes and wait for IRPs. */
if (pBulkDev->outPipeHandle != NULL)
usbdPipeDestroy (usbdSFFHandle, pBulkDev->outPipeHandle);
if (pBulkDev->inPipeHandle != NULL)
usbdPipeDestroy (usbdSFFHandle, pBulkDev->inPipeHandle);
/* wait for any IRP to complete */
OSS_SEM_TAKE (sffbulkIrpSem, OSS_BLOCK);
OSS_SEM_GIVE (sffbulkIrpSem);
/* Release structure. */
OSS_FREE (pBulkDev);
}
}
LOCAL pUSB_SFF_BULK_DEV usbSFFBulkDevFind
(
USBD_NODE_ID nodeId /* node ID to be looked for */
)
{
pUSB_SFF_BULK_DEV pBulkDev = usbListFirst (&sffbulkDevList);
/* browse through the list */
while (pBulkDev != NULL)
{
if (pBulkDev->bulkDevId == nodeId)
break;
pBulkDev = usbListNext (&pBulkDev->bulkDevLink);
}
return (pBulkDev);
}
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;
}
LOCAL STATUS usbSFFBulkPhysDevCreate
(
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_SFF_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 (usbSFFBulkDevFind (nodeId) != NULL)
return (OK);
/* Allocate memory for a new structure to represent this device */
if ((pBulkDev = OSS_CALLOC (sizeof (*pBulkDev))) == NULL)
{
USB_SFF_BULK_ERR ("usbSFFBulkPhysDevCreate: 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 (usbdSFFHandle, 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_SFF_BULK_ERR ("usbSFFBulkPhysDevCreate: Unable to read configuration "\
"descriptor\n", 0, 0, 0, 0, 0, 0);
goto errorExit;
}
if ((pCfgDescr = usbDescrParse (bfr, actLength,
USB_DESCR_CONFIGURATION)) == NULL)
{
USB_SFF_BULK_ERR ("usbSFFBulkPhysDevCreate: Unable to find configuration "\
"descriptor\n", 0, 0, 0, 0, 0, 0);
goto errorExit;
}
/* Look for the interface representing the MSC/SFF/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;
if ((pInEp = findEndpoint (pBfr, actLength, USB_ENDPOINT_IN)) == NULL)
goto errorExit;
pBulkDev->outEpAddress = pOutEp->endpointAddress;
pBulkDev->inEpAddress = pInEp->endpointAddress;
/* Set the device configuration corresponding to MSC/SFF/BULK-ONLY */
if ((usbdConfigurationSet (usbdSFFHandle,
pBulkDev->bulkDevId,
pBulkDev->configuration,
pCfgDescr->maxPower * USB_POWER_MA_PER_UNIT))
!= OK )
{
USB_SFF_BULK_ERR ("usbSFFBulkPhysDevCreate: Unable to set device "\
"configuration \n", 0, 0, 0, 0, 0, 0);
goto errorExit;
}
else
{
USB_SFF_BULK_DEBUG ("usbSFFBulkPhysDevCreate: Configuration set to 0x%x \n",
pBulkDev->configuration, 0, 0, 0, 0, 0);
}
/* Select interface
*
* NOTE: Some devices may reject this command, and this does not represent
* a fatal error. Therefore, we ignore the return status.
*/
usbdInterfaceSet (usbdSFFHandle,
pBulkDev->bulkDevId,
pBulkDev->interface,
pBulkDev->altSetting);
maxPacketSize = *((pUINT8) &pOutEp->maxPacketSize) |
(*(((pUINT8) &pOutEp->maxPacketSize) + 1) << 8);
/* Create a Bulk-out pipe for the MSC/SFF/BULK-ONLY device */
if (usbdPipeCreate (usbdSFFHandle,
pBulkDev->bulkDevId,
pOutEp->endpointAddress,
pBulkDev->configuration,
pBulkDev->interface,
USB_XFRTYPE_BULK,
USB_DIR_OUT,
maxPacketSize,
0,
0,
&(pBulkDev->outPipeHandle))
!= OK)
{
USB_SFF_BULK_ERR ("usbSFFBulkPhysDevCreate: Error creating bulk out pipe\n",
0, 0, 0, 0, 0, 0);
goto errorExit;
}
maxPacketSize = *((pUINT8) &pInEp->maxPacketSize) |
(*(((pUINT8) &pInEp->maxPacketSize) + 1) << 8);
/* Create a Bulk-in pipe for the MSC/SFF/BULK-ONLY device */
if (usbdPipeCreate (usbdSFFHandle,
pBulkDev->bulkDevId,
pInEp->endpointAddress,
pBulkDev->configuration,
pBulkDev->interface,
USB_XFRTYPE_BULK,
USB_DIR_IN,
maxPacketSize,
0,
0,
&(pBulkDev->inPipeHandle))
!= OK)
{
USB_SFF_BULK_ERR ("usbSFFBulkPhysDevCreate: Error creating bulk in pipe\n",
0, 0, 0, 0, 0, 0);
goto errorExit;
}
/* Clear HALT feauture on the endpoints */
if ((usbdFeatureClear (usbdSFFHandle,
pBulkDev->bulkDevId,
USB_RT_ENDPOINT,
USB_FSEL_DEV_ENDPOINT_HALT,
(pOutEp->endpointAddress & 0x0F)))
!= OK)
{
USB_SFF_BULK_ERR ("usbSFFBulkPhysDevCreate: Failed to clear HALT feauture "\
"on bulk out Endpoint %x\n", 0, 0, 0, 0, 0, 0);
}
if ((usbdFeatureClear (usbdSFFHandle,
pBulkDev->bulkDevId,
USB_RT_ENDPOINT,
USB_FSEL_DEV_ENDPOINT_HALT,
(pOutEp->endpointAddress & 0x0F)))
!= OK)
{
USB_SFF_BULK_ERR ("usbSFFBulkPhysDevCreate: Failed to clear HALT feauture "\
"on bulk in Endpoint %x\n", 0, 0, 0, 0, 0, 0);
}
/* Link the newly created structure. */
usbListLink (&sffbulkDevList, pBulkDev, &pBulkDev->bulkDevLink, LINK_TAIL);
return (OK);
errorExit:
/* Error in creating a bulk device ..destroy */
usbSFFBulkDevDestroy (pBulkDev);
return (ERROR);
}
BLK_DEV * usbSFFBulkBlkDevCreate
(
USBD_NODE_ID nodeId, /* nodeId of the bulk-only device */
UINT32 numBlks, /* number of logical blocks on device */
UINT32 blkOffset, /* offset of the starting block */
UINT32 flags /* optional flags */
)
{
UINT8 inquiry[36]; /* store for INQUIRY data */
DOS_PART_TBL *pPart;
char blk0Buffer [512];
int offset=0;
int ix;
/* TODO : As of now only the first device is taken care */
pUSB_SFF_BULK_DEV pBulkDev = usbSFFBulkDevFind (nodeId);
/*pUSB_SFF_BULK_DEV pBulkDev = usbListFirst (&sffbulkDevList);*/
if (pBulkDev == NULL)
{
USB_SFF_BULK_ERR ("usbSFFBulkBlkDevCreate: No MSC/SFF/BULK-ONLY found\n",
0, 0, 0, 0, 0, 0);
return (NULL);
}
OSS_MUTEX_TAKE (sffbulkDevMutex, OSS_BLOCK);
/* Initialise the standard block device structure for use with file systems */
pBulkDev->blkDev.bd_blkRd = (FUNCPTR) usbSFFBulkDevBlkRd;
pBulkDev->blkDev.bd_blkWrt = (FUNCPTR) usbSFFBulkDevBlkWrt;
pBulkDev->blkDev.bd_ioctl = (FUNCPTR) usbSFFBulkDevIoctl;
pBulkDev->blkDev.bd_reset = (FUNCPTR) usbSFFBulkDevReset;
pBulkDev->blkDev.bd_statusChk = (FUNCPTR) usbSFFBulkDevStatusChk;
pBulkDev->blkDev.bd_retry = 1;
pBulkDev->blkDev.bd_mode = O_RDWR;
pBulkDev->blkDev.bd_readyChanged = TRUE;
/*
* Read out the standard INQUIRY information from the device, mainly to
* check whether the media is removable or not.
*/
pBulkDev->bulkInData = inquiry;
if ( usbSFFBulkFormSFFCmd (pBulkDev, USB_SFF_INQUIRY, NULL, NULL) != OK )
{
USB_SFF_BULK_ERR ("usbSFFBulkBlkDevCreate: Error forming command\n",
0, 0, 0, 0, 0, 0);
OSS_MUTEX_RELEASE (sffbulkDevMutex);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -