Loading drivers/usb/gadget/function/f_gsi.c +30 −14 Original line number Diff line number Diff line Loading @@ -2965,6 +2965,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; int status; __u8 class; __u8 subclass; Loading Loading @@ -3157,18 +3158,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 IPA_USB_RMNET: Loading Loading @@ -3331,6 +3329,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 @@ -3365,8 +3364,11 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f) rndis_deregister(gsi->params); } if (gsi->prot_id == IPA_USB_MBIM) mbim_gsi_ext_config_desc.function.subCompatibleID[0] = 0; if (gsi->prot_id == IPA_USB_MBIM) { kfree(f->os_desc_table); f->os_desc_table = NULL; f->os_desc_n = 0; } usb_free_all_descriptors(f); Loading Loading @@ -3766,6 +3768,8 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, char gsi_inst_name[MAX_INST_NAME_LEN + sizeof("gsi.") + 1]; void *ipc_log_ctxt; struct gsi_opts *opts, *opts_prev; struct usb_os_desc *descs[1]; char *names[1]; opts = container_of(fi, struct gsi_opts, func_inst); Loading Loading @@ -3799,6 +3803,16 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, fi->group.cg_item.ci_name, &gsi_func_ecm_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 = gsi_function_init(prot_id); if (IS_ERR(gsi)) return PTR_ERR(gsi); Loading Loading @@ -3847,6 +3861,8 @@ static void gsi_free_inst(struct usb_function_instance *f) } ipc_log_context_destroy(opts->gsi->ipc_log_ctxt); if (opts && opts->interf_group) kfree(opts->interf_group); /* Clear instance status */ gsi_inst_clean(opts); inst_status[prot_id].inst_exist = false; Loading drivers/usb/gadget/function/f_gsi.h +7 −44 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <linux/ipc_logging.h> #include <linux/timer.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 @@ -334,6 +336,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 @@ -1080,50 +1087,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; __le16 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 @@ -2965,6 +2965,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; int status; __u8 class; __u8 subclass; Loading Loading @@ -3157,18 +3158,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 IPA_USB_RMNET: Loading Loading @@ -3331,6 +3329,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 @@ -3365,8 +3364,11 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f) rndis_deregister(gsi->params); } if (gsi->prot_id == IPA_USB_MBIM) mbim_gsi_ext_config_desc.function.subCompatibleID[0] = 0; if (gsi->prot_id == IPA_USB_MBIM) { kfree(f->os_desc_table); f->os_desc_table = NULL; f->os_desc_n = 0; } usb_free_all_descriptors(f); Loading Loading @@ -3766,6 +3768,8 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, char gsi_inst_name[MAX_INST_NAME_LEN + sizeof("gsi.") + 1]; void *ipc_log_ctxt; struct gsi_opts *opts, *opts_prev; struct usb_os_desc *descs[1]; char *names[1]; opts = container_of(fi, struct gsi_opts, func_inst); Loading Loading @@ -3799,6 +3803,16 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, fi->group.cg_item.ci_name, &gsi_func_ecm_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 = gsi_function_init(prot_id); if (IS_ERR(gsi)) return PTR_ERR(gsi); Loading Loading @@ -3847,6 +3861,8 @@ static void gsi_free_inst(struct usb_function_instance *f) } ipc_log_context_destroy(opts->gsi->ipc_log_ctxt); if (opts && opts->interf_group) kfree(opts->interf_group); /* Clear instance status */ gsi_inst_clean(opts); inst_status[prot_id].inst_exist = false; Loading
drivers/usb/gadget/function/f_gsi.h +7 −44 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <linux/ipc_logging.h> #include <linux/timer.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 @@ -334,6 +336,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 @@ -1080,50 +1087,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; __le16 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