Loading drivers/usb/gadget/function/f_gsi.c +30 −14 Original line number Diff line number Diff line Loading @@ -2954,6 +2954,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) struct gsi_function_bind_info info = {0}; struct f_gsi *gsi = func_to_gsi(f); struct rndis_params *params; struct gsi_opts *opts; struct net_device *net; char *name = NULL; int status; Loading Loading @@ -3162,18 +3163,15 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) info.notify_buf_len = sizeof(struct usb_cdc_notification); mbim_gsi_desc.wMaxSegmentSize = cpu_to_le16(0x800); /* * If MBIM is bound in a config other than the first, tell * Windows about it by returning the num as a string in the * OS descriptor's subCompatibleID field. Windows only supports * up to config #4. */ if (c->bConfigurationValue >= 2 && c->bConfigurationValue <= 4) { log_event_dbg("MBIM in configuration %d", c->bConfigurationValue); mbim_gsi_ext_config_desc.function.subCompatibleID[0] = c->bConfigurationValue + '0'; if (cdev->use_os_string) { f->os_desc_table = kzalloc(sizeof(*f->os_desc_table), GFP_KERNEL); if (!f->os_desc_table) return -ENOMEM; opts = container_of(f->fi, struct gsi_opts, func_inst); f->os_desc_n = 1; f->os_desc_table[0].os_desc = &opts->os_desc; f->os_desc_table[0].if_id = gsi->data_id; } break; case USB_PROT_RMNET_IPA: Loading Loading @@ -3363,6 +3361,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) dereg_rndis: rndis_deregister(gsi->params); kfree(f->os_desc_table); fail: return status; } Loading Loading @@ -3394,8 +3393,11 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f) rndis_deregister(gsi->params); } if (gsi->prot_id == USB_PROT_MBIM_IPA) mbim_gsi_ext_config_desc.function.subCompatibleID[0] = 0; if (gsi->prot_id == USB_PROT_MBIM_IPA) { kfree(f->os_desc_table); f->os_desc_table = NULL; f->os_desc_n = 0; } usb_free_all_descriptors(f); Loading Loading @@ -3709,6 +3711,8 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, int name_len, prot_id, ret = 0; struct gsi_opts *opts; struct f_gsi *gsi; struct usb_os_desc *descs[1]; char *names[1]; opts = container_of(fi, struct gsi_opts, func_inst); Loading @@ -3728,6 +3732,16 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, fi->group.cg_item.ci_name, &gsi_func_rndis_type); if (prot_id == IPA_USB_MBIM) { opts->os_desc.ext_compat_id = opts->ext_compat_id; INIT_LIST_HEAD(&opts->os_desc.ext_prop); descs[0] = &opts->os_desc; names[0] = "MBIM"; opts->interf_group = usb_os_desc_prepare_interf_dir( &opts->func_inst.group, 1, descs, names, THIS_MODULE); } gsi = opts->gsi = __gsi[prot_id]; opts->gsi->prot_id = prot_id; ret = gsi_function_ctrl_port_init(opts->gsi); Loading Loading @@ -3764,6 +3778,8 @@ static void gsi_free_inst(struct usb_function_instance *f) ida_simple_remove(&gsi_ida, minor); } if (opts && opts->interf_group) kfree(opts->interf_group); kfree(opts); } Loading drivers/usb/gadget/function/f_gsi.h +7 −44 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ #include "u_ether.h" #include "configfs.h" #define GSI_RMNET_CTRL_NAME "rmnet_ctrl" #define GSI_MBIM_CTRL_NAME "android_mbim" #define GSI_DPL_CTRL_NAME "dpl_ctrl" Loading Loading @@ -312,6 +314,11 @@ static inline struct f_gsi *c_port_to_gsi(struct gsi_ctrl_port *d) struct gsi_opts { struct usb_function_instance func_inst; struct f_gsi *gsi; /* os desc support */ struct config_group *interf_group; char ext_compat_id[16]; struct usb_os_desc os_desc; }; static inline struct gsi_opts *to_gsi_opts(struct config_item *item) Loading Loading @@ -1063,50 +1070,6 @@ static struct usb_gadget_strings *mbim_gsi_strings[] = { NULL, }; /* Microsoft OS Descriptors */ /* * We specify our own bMS_VendorCode byte which Windows will use * as the bRequest value in subsequent device get requests. */ #define MBIM_VENDOR_CODE 0xA5 /* Microsoft Extended Configuration Descriptor Header Section */ struct mbim_gsi_ext_config_desc_header { __le32 dwLength; __u16 bcdVersion; __le16 wIndex; __u8 bCount; __u8 reserved[7]; }; /* Microsoft Extended Configuration Descriptor Function Section */ struct mbim_gsi_ext_config_desc_function { __u8 bFirstInterfaceNumber; __u8 bInterfaceCount; __u8 compatibleID[8]; __u8 subCompatibleID[8]; __u8 reserved[6]; }; /* Microsoft Extended Configuration Descriptor */ static struct { struct mbim_gsi_ext_config_desc_header header; struct mbim_gsi_ext_config_desc_function function; } mbim_gsi_ext_config_desc = { .header = { .dwLength = cpu_to_le32(sizeof(mbim_gsi_ext_config_desc)), .bcdVersion = cpu_to_le16(0x0100), .wIndex = cpu_to_le16(4), .bCount = 1, }, .function = { .bFirstInterfaceNumber = 0, .bInterfaceCount = 1, .compatibleID = { 'A', 'L', 'T', 'R', 'C', 'F', 'G' }, /* .subCompatibleID = DYNAMIC */ }, }; /* ecm device descriptors */ #define ECM_QC_LOG2_STATUS_INTERVAL_MSEC 5 #define ECM_QC_STATUS_BYTECOUNT 16 /* 8 byte header + data */ Loading Loading
drivers/usb/gadget/function/f_gsi.c +30 −14 Original line number Diff line number Diff line Loading @@ -2954,6 +2954,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) struct gsi_function_bind_info info = {0}; struct f_gsi *gsi = func_to_gsi(f); struct rndis_params *params; struct gsi_opts *opts; struct net_device *net; char *name = NULL; int status; Loading Loading @@ -3162,18 +3163,15 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) info.notify_buf_len = sizeof(struct usb_cdc_notification); mbim_gsi_desc.wMaxSegmentSize = cpu_to_le16(0x800); /* * If MBIM is bound in a config other than the first, tell * Windows about it by returning the num as a string in the * OS descriptor's subCompatibleID field. Windows only supports * up to config #4. */ if (c->bConfigurationValue >= 2 && c->bConfigurationValue <= 4) { log_event_dbg("MBIM in configuration %d", c->bConfigurationValue); mbim_gsi_ext_config_desc.function.subCompatibleID[0] = c->bConfigurationValue + '0'; if (cdev->use_os_string) { f->os_desc_table = kzalloc(sizeof(*f->os_desc_table), GFP_KERNEL); if (!f->os_desc_table) return -ENOMEM; opts = container_of(f->fi, struct gsi_opts, func_inst); f->os_desc_n = 1; f->os_desc_table[0].os_desc = &opts->os_desc; f->os_desc_table[0].if_id = gsi->data_id; } break; case USB_PROT_RMNET_IPA: Loading Loading @@ -3363,6 +3361,7 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) dereg_rndis: rndis_deregister(gsi->params); kfree(f->os_desc_table); fail: return status; } Loading Loading @@ -3394,8 +3393,11 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f) rndis_deregister(gsi->params); } if (gsi->prot_id == USB_PROT_MBIM_IPA) mbim_gsi_ext_config_desc.function.subCompatibleID[0] = 0; if (gsi->prot_id == USB_PROT_MBIM_IPA) { kfree(f->os_desc_table); f->os_desc_table = NULL; f->os_desc_n = 0; } usb_free_all_descriptors(f); Loading Loading @@ -3709,6 +3711,8 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, int name_len, prot_id, ret = 0; struct gsi_opts *opts; struct f_gsi *gsi; struct usb_os_desc *descs[1]; char *names[1]; opts = container_of(fi, struct gsi_opts, func_inst); Loading @@ -3728,6 +3732,16 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, fi->group.cg_item.ci_name, &gsi_func_rndis_type); if (prot_id == IPA_USB_MBIM) { opts->os_desc.ext_compat_id = opts->ext_compat_id; INIT_LIST_HEAD(&opts->os_desc.ext_prop); descs[0] = &opts->os_desc; names[0] = "MBIM"; opts->interf_group = usb_os_desc_prepare_interf_dir( &opts->func_inst.group, 1, descs, names, THIS_MODULE); } gsi = opts->gsi = __gsi[prot_id]; opts->gsi->prot_id = prot_id; ret = gsi_function_ctrl_port_init(opts->gsi); Loading Loading @@ -3764,6 +3778,8 @@ static void gsi_free_inst(struct usb_function_instance *f) ida_simple_remove(&gsi_ida, minor); } if (opts && opts->interf_group) kfree(opts->interf_group); kfree(opts); } Loading
drivers/usb/gadget/function/f_gsi.h +7 −44 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ #include "u_ether.h" #include "configfs.h" #define GSI_RMNET_CTRL_NAME "rmnet_ctrl" #define GSI_MBIM_CTRL_NAME "android_mbim" #define GSI_DPL_CTRL_NAME "dpl_ctrl" Loading Loading @@ -312,6 +314,11 @@ static inline struct f_gsi *c_port_to_gsi(struct gsi_ctrl_port *d) struct gsi_opts { struct usb_function_instance func_inst; struct f_gsi *gsi; /* os desc support */ struct config_group *interf_group; char ext_compat_id[16]; struct usb_os_desc os_desc; }; static inline struct gsi_opts *to_gsi_opts(struct config_item *item) Loading Loading @@ -1063,50 +1070,6 @@ static struct usb_gadget_strings *mbim_gsi_strings[] = { NULL, }; /* Microsoft OS Descriptors */ /* * We specify our own bMS_VendorCode byte which Windows will use * as the bRequest value in subsequent device get requests. */ #define MBIM_VENDOR_CODE 0xA5 /* Microsoft Extended Configuration Descriptor Header Section */ struct mbim_gsi_ext_config_desc_header { __le32 dwLength; __u16 bcdVersion; __le16 wIndex; __u8 bCount; __u8 reserved[7]; }; /* Microsoft Extended Configuration Descriptor Function Section */ struct mbim_gsi_ext_config_desc_function { __u8 bFirstInterfaceNumber; __u8 bInterfaceCount; __u8 compatibleID[8]; __u8 subCompatibleID[8]; __u8 reserved[6]; }; /* Microsoft Extended Configuration Descriptor */ static struct { struct mbim_gsi_ext_config_desc_header header; struct mbim_gsi_ext_config_desc_function function; } mbim_gsi_ext_config_desc = { .header = { .dwLength = cpu_to_le32(sizeof(mbim_gsi_ext_config_desc)), .bcdVersion = cpu_to_le16(0x0100), .wIndex = cpu_to_le16(4), .bCount = 1, }, .function = { .bFirstInterfaceNumber = 0, .bInterfaceCount = 1, .compatibleID = { 'A', 'L', 'T', 'R', 'C', 'F', 'G' }, /* .subCompatibleID = DYNAMIC */ }, }; /* ecm device descriptors */ #define ECM_QC_LOG2_STATUS_INTERVAL_MSEC 5 #define ECM_QC_STATUS_BYTECOUNT 16 /* 8 byte header + data */ Loading