📄 usbh_usbds_api.c
字号:
UsbDev = USBH_USBDS_SearchDevFromClassID(classid);
if( UsbDev == NULL ){
pfnPortSuspend.retValue = USBH_USBD_STATUS_UNSUCCESSFUL;
return pfnPortSuspend.retValue;
}
wURB = USBH_USBDS_AddURBList();
// Registration of pointer of call back function
pfnPortSuspend.Callback = pfnCallback;
if(wURB != (USBH_USBD_URB *)USBH_USBD_STATUS_UNSUCCESSFUL) {
/* Save device state, turn to SUSPENDED */
UsbDevListWK = USBH_USBDS_SearchDevList( UsbDev );
UsbDevListWK->savedEnumState = UsbDev->eState;
UsbDev->eState = USBH_USBD_USB_STATE_SUSPENDED;
/* SetPortFeature(PORT_SUSPEND) */
wURB->pHCPriv = NULL;
wURB->psDev = UsbDev->psParent; /* Set device information structure of hub which correspond device is connecting */
wURB->pipe = USBH_USBD_SetPipeType(USBH_HCD_PIPE_CONTROL, ENUM_EP0, wURB->psDev->devNum, USBH_HCD_DIR_OUT);
USBH_USBDS_MkSetupPacket((SETUP_REQUEST *)wURB->pSetupPacket, BREQ_SETFEATURE_PORT, 0, UsbDev->port, USBH_USBD_PORT_SUSPEND);
USBH_USBDS_SetTranPara(wURB, 0, 0, 0, USBH_USBDS_PortSuspendCallbackProc);
pfnPortSuspend.retValue = USBH_HCD_SubmitURB((USBH_HCD_URB *)wURB);
USBH_USBDS_DelListURB(wURB);
if( pfnPortSuspend.retValue != USBH_USBD_STATUS_SUCCESS ) {
return pfnPortSuspend.retValue;
}
UsbDev->eState = USBH_USBD_USB_STATE_SUSPENDED;
} else {
pfnPortSuspend.retValue = USBH_USBD_STATUS_UNSUCCESSFUL;
}
return pfnPortSuspend.retValue;
}
/*=============================================================================================
// Function_Name: USBH_USBDS_PortResume
//
// description : Resume specified device.
//
// argument : classid Class ID ( in )
// : devaddr Device address ( in )
// : *pfnCallback Pointer to call back function to notify completion ( in )
//
// return : USBH_USBD_STATUS_SUCCESS Registration finish normally
// USBH_USBD_STATUS_INVALID_PARAMETER There were some errors in passed parameter
// USBH_USBD_STATUS_UNSUCCESSFUL Host Controller is not on suspension
===============================================================================================*/
long USBH_USBDS_PortResume( UCHAR classid, UCHAR devaddr, USBH_USBD_CALLBACK pfnCallback )
{
USBH_USBD_DEVLIST_HEAD *UsbDevListWK;
USBH_USBD_USBDEV *UsbDev=NULL ;
UsbDev = USBH_USBDS_SearchDevFromClassID(classid);
if( UsbDev == NULL ){
pfnPortResume.retValue = USBH_USBD_STATUS_UNSUCCESSFUL;
return pfnPortResume.retValue;
}
if( UsbDev->eState != USBH_USBD_USB_STATE_SUSPENDED ){
pfnPortResume.retValue = USBH_USBD_STATUS_UNSUCCESSFUL;
return pfnPortResume.retValue;
}
wURB = USBH_USBDS_AddURBList();
// Registration of pointer of call back function
pfnPortResume.Callback = pfnCallback;
if(wURB != (USBH_USBD_URB *)USBH_USBD_STATUS_UNSUCCESSFUL) {
/* Restore saved device state */
UsbDevListWK = USBH_USBDS_SearchDevList( UsbDev );
UsbDev->eState = (USBH_USBD_ENUMDEVSTATE)UsbDevListWK->savedEnumState;
// ClearPortFeature(PORT_SUSPEND)
/* Parameter setting */
wURB->psDev = UsbDev->psParent ;
wURB->pipe = USBH_USBD_SetPipeType(USBH_HCD_PIPE_CONTROL, ENUM_EP0, wURB->psDev->devNum, USBH_HCD_DIR_OUT);
USBH_USBDS_MkSetupPacket((SETUP_REQUEST *)wURB->pSetupPacket, BREQ_CLEARFEATURE_PORT, 0, UsbDev->port, USBH_USBD_PORT_SUSPEND);
USBH_USBDS_SetTranPara(wURB, 0, 0, 0, USBH_USBDS_PortResumeCallbackProc);
pfnPortResume.retValue = USBH_HCD_SubmitURB((USBH_HCD_URB *)wURB);
if( pfnPortResume.retValue != USBH_USBD_STATUS_SUCCESS ) {
USBH_USBDS_DelListURB(wURB);
}
} else {
pfnPortResume.retValue = USBH_USBD_STATUS_UNSUCCESSFUL;
}
return pfnPortResume.retValue;
}
/*=============================================================================================
// Function_Name: USBH_USBDS_ALLEndpointDisable
//
// description : Cancel URB of all endpoint of device to cut off.
//
// argument : *tmpDevInfo Device information ( in )
// : *tmpDevHead Device header list ( in )
// : type Disable type ( in )
//
// return : None
===============================================================================================*/
STATIC_T void USBH_USBDS_ALLEndpointDisable( USBH_HCD_USBDEV *tmpDevInfo, USBH_USBD_DEVLIST_HEAD *tmpDevHead, UCHAR type)
{
USBH_USBD_EPTBL *ep_cur;
USBH_USBD_IFTBL *iftbl;
USB_DESC_ENDPOINT *epinfo;
long ret;
iftbl = tmpDevHead->sUsbDes.InterTbl;
while(iftbl != NULL) {
ep_cur = iftbl->EPTbl;
while(ep_cur) {
epinfo = &ep_cur->EndP;
ret = USBH_HCD_EndpointDisable((USBH_HCD_USBDEV *)tmpDevInfo, epinfo->bEndpointAddress);
if(ret != USBH_USBD_STATUS_SUCCESS) {
return;
}
ep_cur = ep_cur->Next;
}
iftbl = iftbl->Next;
}
if(type == USBH_USBD_DEL) {
/* Free connecting device information */
ret = USBH_HCD_FreeDev((USBH_HCD_USBDEV *)tmpDevInfo);
if(ret != USBH_USBD_STATUS_SUCCESS) {
return;
}
/* Free secured memory for device descriptor information */
FreeDescripterInfo(tmpDevHead->sUsbDes.InterTbl);
USBH_USBDS_DelListDev((USBH_USBD_USBDEV *)tmpDevInfo);
}
}
/*=============================================================================================
// Function_Name: USBH_USBDS_DelALLDev
//
// description : Carry out deletion of device has been cut off.
// : Carry out deletion all devices connected if device is hub.
//
// argument : *psCurUSBDev Device structure ( in )
//
// return : None
===============================================================================================*/
STATIC_T void USBH_USBDS_DelALLDev(USBH_USBD_USBDEV *psCurUSBDev)
{
USBH_USBD_DEVLIST_HEAD *UsbDevListWK;
USBH_USBD_DEVLIST_HEAD *tmpDevHead;
struct tagUSBH_USBD_DEVLIST_HEAD *tmpNext;
USBH_USBD_URB *TmpUrb;
unsigned int k;
unsigned char deldevNum, cID;
UsbDevListWK = (USBH_USBD_DEVLIST_HEAD *)DeviceCtlTbl.DevInfo;
/* Search device has been cut off from list of device with same parent hub */
while(UsbDevListWK) {
if(UsbDevListWK->sUsbDev.psParent == psCurUSBDev) {
/* Device has been cut off is found ( agree with device has been cut off ) */
if(DelhubStat == UsbDevListWK->sUsbDev.port) {
tmpDevHead = USBH_USBDS_SearchDevList(UsbDevListWK->sUsbDev.psParent);
tmpDevHead->statRESET &= ~(1<<UsbDevListWK->sUsbDev.port);
/* Case of device to cut off is hub */
if(UsbDevListWK->sUsbDes.Dev.bDeviceClass == USBH_HSBD_HUB_CLASS_CODE) {
tmpDevHead = DeviceCtlTbl.DevInfo;
while(tmpDevHead) {
tmpNext = tmpDevHead->psNext;
/* Search device connected to device to cut off */
if(tmpDevHead->sUsbDev.psParent == &UsbDevListWK->sUsbDev) {
TmpUrb = USBH_USBDS_AddURBList();
if(TmpUrb == (USBH_USBD_URB *)USBH_USBD_STATUS_UNSUCCESSFUL) {
continue;
}
/* Parameter setting */
/* Specify parent hub of device to cut off */
TmpUrb->psDev = (USBH_USBD_USBDEV *)&UsbDevListWK->sUsbDev;
DelhubStat = tmpDevHead->sUsbDev.port;
TmpUrb->status = URBSTS_SUCCESS;
USBH_USBDS_DeviceCallbackProc(TmpUrb);
/* Incase of deletion, re-do from start */
tmpDevHead = DeviceCtlTbl.DevInfo;
} else {
tmpDevHead = tmpNext;
}
}
}
deldevNum = UsbDevListWK->sUsbDev.devNum;
/* The USBH_USBD_MSG_DISCONNECT_CMP callback is not called for the device address number of the unsetting. */
if(deldevNum != UNSET_ADDRESSNO) {
/* Throw notification of device cut off ( USBH_USBD_MSG_DISCONNECT_CMP ) */
cID = UsbDevListWK->ClassID;
if(cID != USBH_HSBD_HUB_CLASS_ID) {
/* It would call correspond driver only in fact */
for( k = 0; k < USBH_USBD_CLASSDRIVERNUM; k++ ){
if( USBH_USBDS_SearchIdentityClass( ClassINFO[k].ClassNo ) != USBH_USBD_STATUS_UNSUCCESSFUL ) {
USBH_USBDS_ExecCallback(ClassINFO[k].pfnEntryClassCallback, USBH_USBD_MSG_DISCONNECT_CMP, deldevNum, NULL);
}
}
}
}
/* Case of other than hub */
USBH_USBDS_ALLEndpointDisable((USBH_HCD_USBDEV *)&UsbDevListWK->sUsbDev, UsbDevListWK, USBH_USBD_DEL);
}
}
UsbDevListWK = UsbDevListWK->psNext;
}
}
/*=============================================================================================
// Function_Name: USBH_USBDS_DeviceCallbackProc
//
// description : Connecting device recognition call back
//
// argument : *psURB URB structure ( in )
//
// return : None
===============================================================================================*/
STATIC_T void USBH_USBDS_DeviceCallbackProc( USBH_USBD_URB *psURB )
{
long ret;
USBH_USBD_DEVLIST_HEAD *UsbDevListWK;
USBH_USBD_USBDEV *psCurUSBDev;
unsigned char connect_status=0;
unsigned int i;
UCHAR add_flg;
/* Connecting device emulation */
if(psURB->status == URBSTS_SUCCESS) {
/* At the normal finish */
switch(USBH_USBD_Mode) {
case USBH_USBD_MODE_DEVDES8: /* GET DEVICE DESCRIPTOR ( TotalLength acquisition only ) */
ret = AnalizeDescriptor(USBH_USBD_DTYPE_DEVICE, psURB->pTransBuf, &UsbDevInfo->sUsbDes, USBH_USBD_ON);
if(UsbDevInfo == &RootHubDev) {
if(ret == USBH_USBD_STATUS_SUCCESS) {
USBH_USBD_Mode = USBH_USBD_MODE_DEVDES; /* GET DEVICE DESCRIPTOR */
}
USBH_USBDS_DelListURB(psURB);
} else {
/* Set MaxPacketsize which has been gotten to 0 */
UsbDevInfo->sUsbDev.epMaxPacketIn[0] = UsbDevInfo->sUsbDes.Dev.bMaxPacketSize0;
UsbDevInfo->sUsbDev.epMaxPacketOut[0] = UsbDevInfo->sUsbDes.Dev.bMaxPacketSize0;
if(ret != USBH_USBD_STATUS_SUCCESS) {
connect_status = 1;
break;
}
USBH_USBD_Mode = USBH_USBD_MODE_DEVDES; /* GET DEVICE DESCRIPTOR */
UsbDevListWK = USBH_USBDS_SearchDevList( psURB->psDev );
USBH_USBDS_DeviceEnumeration( USBH_USBD_ENUME_DEVICE, UsbDevListWK, 0 );
}
break;
case USBH_USBD_MODE_DEVDES: /* GET DEVICE DESCRIPTOR */
ret = AnalizeDescriptor(USBH_USBD_DTYPE_DEVICE, psURB->pTransBuf, &UsbDevInfo->sUsbDes, USBH_USBD_OFF);
if(UsbDevInfo == &RootHubDev) {
if(ret == USBH_USBD_STATUS_SUCCESS) {
USBH_USBD_Mode = USBH_USBD_MODE_CFGDES8; /* CONFIGURATION DESCRIPTOR */
}
USBH_USBDS_DelListURB(psURB);
} else {
USBH_USBDS_DelListURB(psURB);
if(ret != USBH_USBD_STATUS_SUCCESS) {
connect_status = 1;
break;
}
USBH_USBD_Mode = USBH_USBD_MODE_CFGDES8; /* CONFIGURATION DESCRIPTOR */
UsbDevListWK = USBH_USBDS_SearchDevList( psURB->psDev );
USBH_USBDS_DeviceEnumeration( USBH_USBD_ENUME_DEVICE, UsbDevListWK, 0 );
}
break;
case USBH_USBD_MODE_DEVQDES: /* DEVICE QUALIFIER DESCRIPTOR */
ret = AnalizeDescriptor(USBH_USBD_DTYPE_QUALIF, psURB->pTransBuf, &UsbDevInfo->sUsbDes, USBH_USBD_ON);
if(UsbDevInfo == &RootHubDev) {
if(ret == USBH_USBD_STATUS_SUCCESS) {
USBH_USBD_Mode = USBH_USBD_MODE_CFGDES; /* CONFIGURATION DESCRIPTOR */
}
USBH_USBDS_DelListURB(psURB);
} else {
USBH_USBDS_DelListURB(psURB);
if(ret != USBH_USBD_STATUS_SUCCESS) {
connect_status = 1;
break;
}
USBH_USBD_Mode = USBH_USBD_MODE_CFGDES; /* CONFIGURATION DESCRIPTOR */
UsbDevListWK = USBH_USBDS_SearchDevList( psURB->psDev );
USBH_USBDS_DeviceEnumeration( USBH_USBD_ENUME_DEVICE, UsbDevListWK, 0 );
}
break;
case USBH_USBD_MODE_CFGDES8: /* CONFIGURATION DESCRIPTOR( Get TotalLength only ) */
ret = AnalizeDescriptor(USBH_USBD_DTYPE_CONFIG, psURB->pTransBuf, &UsbDevInfo->sUsbDes, USBH_USBD_ON);
if(UsbDevInfo == &RootHubDev) {
if(ret == USBH_USBD_STATUS_SUCCESS) {
USBH_USBD_Mode = USBH_USBD_MODE_CFGDES; /* CONFIGURATION DESCRIPTOR */
}
USBH_USBDS_DelListURB(psURB);
} else {
USBH_USBDS_DelListURB(psURB);
if(ret != USBH_USBD_STATUS_SUCCESS) {
connect_status = 1;
break;
}
USBH_USBD_Mode = USBH_USBD_MODE_CFGDES; /* CONFIGURATION DESCRIPTOR */
UsbDevListWK = USBH_USBDS_SearchDevList( psURB->psDev );
USBH_USBDS_DeviceEnumeration( USBH_USBD_ENUME_DEVICE, UsbDevListWK, 0 );
}
break;
case USBH_USBD_MODE_CFGDES: /* CONFIGURATION DESCRIPTOR */
ret = AnalizeDescriptor(USBH_USBD_DTYPE_CONFIG, psURB->pTransBuf, &UsbDevInfo->sUsbDes, USBH_USBD_OFF);
if(UsbDevInfo == &RootHubDev) {
if(ret == USBH_USBD_STATUS_SUCCESS) {
USBH_USBD_Mode = USBH_USBD_MODE_SADDR; /* SET ADDRESS */
}
USBH_USBDS_DelListURB(psURB);
} else {
/* pConfigDesc setting */
psURB->psDev->pConfigDesc = &UsbDevInfo->sUsbDes.Config;
USBH_USBDS_DelListURB(psURB);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -