On 2022-07-18 18:28:16 [-0700], Thinh Nguyen wrote: > diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c > index 084143213176..a10e74290664 100644 > --- a/drivers/usb/gadget/function/f_tcm.c > +++ b/drivers/usb/gadget/function/f_tcm.c > @@ -506,6 +506,22 @@ static void uasp_cleanup_old_alt(struct f_uas *fu) > uasp_free_cmdreq(fu); > } > > +static struct uas_stream *uasp_get_stream_by_tag(struct f_uas *fu, u16 tag) > +{ > + /* > + * For simplicity, we use mod operation to quickly find an in-progress > + * matching command tag to check for overlapped command. The assumption > + * is that the UASP class driver will limit to using tag id from 1 to > + * USBG_NUM_CMDS. This is based on observation from the Windows and > + * Linux UASP storage class driver behavior. If an unusual UASP class > + * driver uses a tag greater than USBG_NUM_CMDS, then this method may no > + * longer work due to possible stream id collision. In that case, we > + * need to use a proper algorithm to fetch the stream (or simply walk > + * through all active streams to check for overlap). > + */ > + return &fu->stream[tag % USBG_NUM_CMDS]; Could you please avoid the assumption what tag actually is? Please take a look at hashtable.h, hash_add(), hash_del(), hash_for_each_possible_safe() is probably all you need. That % looks efficient but gcc will try and remove the div operation which is something the hash implementation (as of hash_min()) avoids. So the only additional costs here is the additional hashtable which worth the price given that you don't assume what tag can be. Sebastian