Hi Hao, Please see the comments inline.
> -----Original Message----- > From: Wu, Hao A <hao.a...@intel.com> > Sent: Monday, May 11, 2020 1:25 PM > To: Jiang, Guomin <guomin.ji...@intel.com>; devel@edk2.groups.io > Cc: jeremy.lin...@arm.com; Wang, Jian J <jian.j.w...@intel.com>; Ni, Ray > <ray...@intel.com> > Subject: RE: [PATCH v3 1/1] MdeModulePkg/UsbBusDxe: Rebuild the > description table after Reset Device > > > -----Original Message----- > > From: Jiang, Guomin <guomin.ji...@intel.com> > > Sent: Saturday, May 9, 2020 4:27 PM > > To: devel@edk2.groups.io > > Cc: jeremy.lin...@arm.com; Wang, Jian J <jian.j.w...@intel.com>; Wu, > > Hao A <hao.a...@intel.com>; Ni, Ray <ray...@intel.com> > > Subject: [PATCH v3 1/1] MdeModulePkg/UsbBusDxe: Rebuild the > > description table after Reset Device > > > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2694 > > > > When the USB fail and then Reset Device, it should rebuild description. > > > Hello Guomin, > > Could you help to add a brief summary of the relationship between the > proposed fix and the issue reported in the above BZ tracker? It would be > helpful for clarifying the purpose of the commit. Thanks. I will add the brief summary in next version patch. > > One more inline comments below: > > > > > > Signed-off-by: Guomin Jiang <guomin.ji...@intel.com> > > Cc: Jian J Wang <jian.j.w...@intel.com> > > Cc: Hao A Wu <hao.a...@intel.com> > > Cc: Ray Ni <ray...@intel.com> > > --- > > MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c | 7 ++ > > MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c | 152 > > +++++++++++++++++++++++ > MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.h > > | 14 +++ > > 3 files changed, 173 insertions(+) > > > > diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c > > b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c > > index 4b4915c019ad..7bb9373a6adf 100644 > > --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c > > +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c > > @@ -874,6 +874,13 @@ UsbIoPortReset ( > > // is in CONFIGURED state. > > // > > if (Dev->ActiveConfig != NULL) { > > + Status = UsbRebuildDescTable (Dev); > > + > > + if (EFI_ERROR (Status)) { > > + DEBUG (( DEBUG_ERROR, "UsbIoPortReset: failed to rebuild desc > > + table - > > %r\n", Status)); > > + goto ON_EXIT; > > + } > > + > > Status = UsbSetConfig (Dev, > > Dev->ActiveConfig->Desc.ConfigurationValue); > > > > if (EFI_ERROR (Status)) { > > diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c > > b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c > > index b08188b1bc78..d8e5e50b7c5a 100644 > > --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c > > +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c > > @@ -900,6 +900,158 @@ UsbBuildDescTable ( > > return EFI_SUCCESS; > > } > > > > +/** > > + Copy the interface descriptor > > + > > + @param[out] DescBuf The buffer of raw descriptor. > > + @param[in] SrcBuf The buffer of raw descriptor > > +**/ > > +VOID > > +UsbCopyInterfaceDesc ( > > + OUT USB_INTERFACE_DESC *DescBuf, > > + IN USB_INTERFACE_DESC *SrcBuf > > + ) > > +{ > > + UINTN Index, IndexI; > > + > > + ASSERT ((DescBuf != NULL) && (SrcBuf != NULL)); > > + > > + if (DescBuf->NumOfSetting == SrcBuf->NumOfSetting) { > > + DescBuf->ActiveIndex = SrcBuf->ActiveIndex; > > + > > + for (Index = 0; Index < DescBuf->NumOfSetting; Index++) { > > + CopyMem (&DescBuf->Settings[Index]->Desc, > > + &SrcBuf->Settings[Index]->Desc, > > + sizeof(EFI_USB_INTERFACE_DESCRIPTOR)); > > + > > + if (DescBuf->Settings[Index]->Desc.NumEndpoints == > > + SrcBuf->Settings[Index]->Desc.NumEndpoints) { > > + > > + for (IndexI = 0; IndexI < DescBuf->Settings[Index]- > >Desc.NumEndpoints; > > + IndexI++) { > > + CopyMem (DescBuf->Settings[Index]->Endpoints[IndexI], > > + SrcBuf->Settings[Index]->Endpoints[IndexI], > > + sizeof(USB_ENDPOINT_DESC)); > > + } > > + } > > + } > > + } > > +} > > + > > +/** > > + Copy the configuration descriptor and its interfaces. > > + > > + @param[out] DescBuf The buffer of raw descriptor. > > + @param[in] SrcBuf The buffer of raw descriptor > > +**/ > > +VOID > > +UsbCopyConfigDesc ( > > + OUT USB_CONFIG_DESC *DescBuf, > > + IN USB_CONFIG_DESC *SrcBuf > > + ) > > +{ > > + UINTN Index; > > + > > + ASSERT ((DescBuf != NULL) && (SrcBuf != NULL)); > > + > > + if (DescBuf->Desc.NumInterfaces == SrcBuf->Desc.NumInterfaces) { > > + CopyMem (&DescBuf->Desc, &SrcBuf->Desc, > > + sizeof(EFI_USB_CONFIG_DESCRIPTOR)); > > + > > + for (Index = 0; Index < DescBuf->Desc.NumInterfaces; Index++) { > > + UsbCopyInterfaceDesc (DescBuf->Interfaces[Index], SrcBuf- > > >Interfaces[Index]); > > + } > > + } > > +} > > + > > +/** > > + Rebuild the whole array of descriptors. > > + > > + @param[in] UsbDev The Usb device. > > + > > + @retval EFI_SUCCESS The descriptor table is build. > > + @retval EFI_DEVICE_ERROR Invalid config > > + @retval Others Command error when get descriptor. > > +**/ > > +EFI_STATUS > > +UsbRebuildDescTable ( > > + IN USB_DEVICE *UsbDev > > + ) > > +{ > > + EFI_USB_CONFIG_DESCRIPTOR *Config; > > + USB_CONFIG_DESC *ConfigDesc; > > + UINT8 NumConfig; > > + EFI_STATUS Status; > > + UINT8 Index; > > + > > + // > > + // Override the device descriptor, Current device fail but the > > + original // descriptor pointer array is still exist. > > + // > > + Status = UsbCtrlGetDesc ( > > + UsbDev, > > + USB_DESC_TYPE_DEVICE, > > + 0, > > + 0, > > + UsbDev->DevDesc, > > + sizeof (EFI_USB_DEVICE_DESCRIPTOR) > > + ); > > + > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "UsbRebuildDescTable: failed to override > > + device > > descriptor - %r\n", Status)); > > + return Status; > > + } > > + > > + NumConfig = UsbDev->DevDesc->Desc.NumConfigurations; > > + if (NumConfig == 0) { > > + return EFI_DEVICE_ERROR; > > + } > > + > > + DEBUG ((DEBUG_INFO, "UsbReuildDescTable: device has %d > > + configures\n", NumConfig)); > > + > > + // > > + // Read each configurations, then parse them // for (Index = 0; > > + Index < NumConfig; Index++) { > > + Config = UsbGetOneConfig (UsbDev, Index); > > + > > + if (Config == NULL) { > > + DEBUG ((DEBUG_INFO, "UsbRebuildDescTable: failed to get > > + configure (index %d)\n", Index)); > > + > > + // > > + // If we can get the default descriptor, it is likely that the > > + // device is still operational. > > + // > > + if (Index == 0) { > > + return EFI_DEVICE_ERROR; > > + } > > + > > + break; > > + } > > + > > + ConfigDesc = UsbParseConfigDesc ((UINT8 *) Config, > > + Config->TotalLength); > > + > > + FreePool (Config); > > + > > + if (ConfigDesc == NULL) { > > + DEBUG ((DEBUG_ERROR, "UsbRebuildDescTable: failed to parse > > + configure (index %d)\n", Index)); > > + > > + // > > + // If we can get the default descriptor, it is likely that the > > + // device is still operational. > > + // > > + if (Index == 0) { > > + return EFI_DEVICE_ERROR; > > + } > > + > > + break; > > + } else { > > + UsbCopyConfigDesc (UsbDev->DevDesc->Configs[Index], ConfigDesc); > > + UsbFreeConfigDesc (ConfigDesc); > > > For the above codes in the 'else' block, how about: > 1. Free the origin descriptor in UsbDev->DevDesc->Configs 2. Assign the new > descriptor 'ConfigDesc' to UsbDev->DevDesc->Configs By doing so, I think > the memory copy of the descriptors can be skipped. Current memory layout as below: UsbDev->DevDesc --> [many configs] --> Configs[0] --> [many interfaces] --> interface[0] --> [many endpoints] --> endpoint[0] --> endpoint[1] ... --> endpoint[NumEndpoints-1] --> Configs[1] --> [many interfaces] --> endpoint[0] --> endpoint[1] ... --> endpoint[NumEndpoints-1] ... --> Configs[NumConfig-1] --> [many interfaces] --> endpoint[0] --> endpoint[1] ... --> endpoint[NumEndpoints-1] Some code may refer the original interface and endpoint, if free it, it may be dereferenced. In previous practice, I use UsbFreeDevDesc() function to free the buffer but observe the issue. > > The reminder of the patch looks good to me. > > Best Regards, > Hao Wu > > > > + } > > + } > > + > > + return EFI_SUCCESS; > > +} > > > > /** > > Set the device's address. > > diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.h > > b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.h > > index 7b0c77fdc79c..54367133241a 100644 > > --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.h > > +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.h > > @@ -169,6 +169,20 @@ UsbBuildDescTable ( > > IN USB_DEVICE *UsbDev > > ); > > > > +/** > > + Rebuild the whole array of descriptors. > > + > > + @param[in] UsbDev The Usb device. > > + > > + @retval EFI_SUCCESS The descriptor table is build. > > + @retval EFI_DEVICE_ERROR Invalid config > > + @retval Others Command error when get descriptor. > > +**/ > > +EFI_STATUS > > +UsbRebuildDescTable ( > > + IN USB_DEVICE *UsbDev > > + ); > > + > > /** > > Set the device's address. > > > > -- > > 2.25.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#59056): https://edk2.groups.io/g/devel/message/59056 Mute This Topic: https://groups.io/mt/74091912/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-