Loading drivers/usb/gadget/android.c +20 −0 Original line number Diff line number Diff line Loading @@ -1473,6 +1473,7 @@ static int qdss_init_transports(int *portnum) { char *ts_port; char *tname = NULL; char *ctrl_name = NULL; char buf[MAX_XPORT_STR_LEN], *type; char xport_name_buf[MAX_XPORT_STR_LEN], *tn; int err = 0; Loading @@ -1487,13 +1488,28 @@ static int qdss_init_transports(int *portnum) pr_debug("%s: qdss_debug_intf = %d\n", __func__, qdss_debug_intf); /* * QDSS function driver is being used for QDSS and DPL * functionality. ctrl_name (i.e. ctrl xport) is optional * whereas data transport name is mandatory to provide * while using QDSS/DPL as part of USB composition. */ while (type) { ctrl_name = strsep(&type, ","); ts_port = strsep(&type, ","); if (!ts_port) { pr_debug("%s:ctrl transport is not provided.\n", __func__); ts_port = ctrl_name; ctrl_name = NULL; } if (ts_port) { if (tn) tname = strsep(&tn, ","); err = qdss_init_port( ctrl_name, ts_port, tname, qdss_debug_intf); Loading @@ -1504,6 +1520,10 @@ static int qdss_init_transports(int *portnum) return err; } (*portnum)++; } else { pr_err("%s: No data transport name for QDSS port.\n", __func__); err = -ENODEV; } } return err; Loading drivers/usb/gadget/f_qdss.c +52 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/device.h> #include <linux/usb/usb_qdss.h> #include <linux/usb/msm_hsusb.h> #include <linux/usb/cdc.h> #include "gadget_chips.h" #include "f_qdss.h" Loading @@ -32,6 +33,8 @@ static unsigned int no_ipa_ports; static struct qdss_ports { enum transport_type data_xport; unsigned char data_xport_num; enum transport_type ctrl_xport; unsigned char ctrl_xport_num; unsigned char port_num; struct f_qdss *port; struct gadget_ipa_port ipa_port; Loading Loading @@ -493,10 +496,12 @@ static void usb_qdss_disconnect_work(struct work_struct *work) int status; unsigned char portno; enum transport_type dxport; enum transport_type ctrl_xport; struct gadget_ipa_port *gp; qdss = container_of(work, struct f_qdss, disconnect_w); dxport = qdss_ports[qdss->port_num].data_xport; ctrl_xport = qdss_ports[qdss->port_num].ctrl_xport; portno = qdss_ports[qdss->port_num].data_xport_num; if (qdss->port_num >= nr_qdss_ports) { Loading @@ -505,6 +510,16 @@ static void usb_qdss_disconnect_work(struct work_struct *work) return; } pr_debug("usb_qdss_disconnect_work\n"); switch (ctrl_xport) { case USB_GADGET_XPORT_QTI: gqti_ctrl_disconnect(&qdss->port, DPL_QTI_CTRL_PORT_NO); break; default: pr_err("%s(): Un-supported transport: %u\n", __func__, ctrl_xport); return; } switch (dxport) { case USB_GADGET_XPORT_BAM: /* Loading Loading @@ -635,9 +650,11 @@ static void usb_qdss_connect_work(struct work_struct *work) int status; unsigned char port_num; enum transport_type dxport; enum transport_type ctrl_xport; qdss = container_of(work, struct f_qdss, connect_w); dxport = qdss_ports[qdss->port_num].data_xport; ctrl_xport = qdss_ports[qdss->port_num].ctrl_xport; port_num = qdss_ports[qdss->port_num].data_xport_num; pr_debug("%s: data xport: %s dev: %p portno: %d\n", __func__, xport_to_str(dxport), Loading @@ -656,6 +673,25 @@ static void usb_qdss_connect_work(struct work_struct *work) } pr_debug("usb_qdss_connect_work\n"); switch (ctrl_xport) { case USB_GADGET_XPORT_QTI: status = gqti_ctrl_connect(&qdss->port, DPL_QTI_CTRL_PORT_NO, qdss->data_iface_id, ctrl_xport, USB_GADGET_DPL); if (status) { pr_err("%s: gqti_ctrl_connect failed: err:%d\n", __func__, status); return; } qdss->port.send_encap_cmd(DPL_QTI_CTRL_PORT_NO, NULL, 0); break; default: pr_err("%s(): Un-supported control transport: %u\n", __func__, ctrl_xport); return; } switch (dxport) { case USB_GADGET_XPORT_BAM: status = init_data(qdss->port.data); Loading Loading @@ -690,7 +726,6 @@ static void usb_qdss_connect_work(struct work_struct *work) return; } qdss->data_enabled = 1; qdss->usb_connected = 1; break; case USB_GADGET_XPORT_HSIC: pr_debug("usb_qdss_connect_work: HSIC transport\n"); Loading Loading @@ -740,6 +775,7 @@ static int qdss_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return -EINVAL; if (dxport == USB_GADGET_XPORT_BAM2BAM_IPA) { qdss->usb_connected = 1; usb_qdss_connect_work(&qdss->connect_w); return 0; } Loading Loading @@ -1109,7 +1145,7 @@ static int qdss_setup(void) return 0; } static int qdss_init_port(const char *data_name, static int qdss_init_port(const char *ctrl_name, const char *data_name, const char *port_name, bool debug_enable) { struct f_qdss *dev; Loading Loading @@ -1141,6 +1177,19 @@ static int qdss_init_port(const char *data_name, qdss_port->data_xport = str_to_xport(data_name); qdss_port->port->debug_inface_enabled = debug_enable; if (ctrl_name) { qdss_port->ctrl_xport = str_to_xport(ctrl_name); pr_debug("%s(): ctrl_name:%s ctrl_xport:%d\n", __func__, ctrl_name, qdss_port->ctrl_xport); switch (qdss_port->ctrl_xport) { case USB_GADGET_XPORT_QTI: pr_debug("USB_GADGET_XPORT_QTI is used.\n"); break; default: pr_debug("%s(): No ctrl transport.\n", __func__); } } switch (qdss_port->data_xport) { case USB_GADGET_XPORT_BAM: qdss_port->data_xport_num = no_data_bam_ports; Loading drivers/usb/gadget/f_qdss.h +2 −1 Original line number Diff line number Diff line Loading @@ -25,11 +25,12 @@ struct gqdss { struct usb_ep *ctrl_out; struct usb_ep *ctrl_in; struct usb_ep *data; int (*send_encap_cmd)(u8 port_num, void *buf, size_t len); void (*notify_modem)(void *g, u8 port_num, int cbits); }; /* struct f_qdss - USB qdss function driver private structure */ struct f_qdss { struct gqdss port; struct usb_composite_dev *cdev; u8 port_num; Loading drivers/usb/gadget/u_ctrl_qti.c +81 −29 Original line number Diff line number Diff line Loading @@ -20,10 +20,17 @@ #include "usb_gadget_xport.h" #define RMNET_CTRL_QTI_NAME "rmnet_ctrl" #define DPL_CTRL_QTI_NAME "dpl_ctrl" /* * Use size of gadget's qti control name. Here currently RMNET and DPL * gadget is using QTI as control transport. Hence using RMNET ctrl name * (as it is bigger in size) for QTI_CTRL_NAME_LEN. */ #define QTI_CTRL_NAME_LEN (sizeof(RMNET_CTRL_QTI_NAME)+2) struct qti_ctrl_port { void *port_usb; char name[sizeof(RMNET_CTRL_QTI_NAME) + 2]; char name[QTI_CTRL_NAME_LEN]; struct miscdevice ctrl_device; bool is_open; Loading Loading @@ -122,8 +129,8 @@ static int gqti_ctrl_send_cpkt_tomodem(u8 portno, void *buf, size_t len) memcpy(cpkt->buf, buf, len); cpkt->len = len; pr_debug("%s: Add to cpkt_req_q packet with len = %zu\n", __func__, len); pr_debug("%s: gtype:%d: Add to cpkt_req_q packet with len = %zu\n", __func__, port->gtype, len); spin_lock_irqsave(&port->lock, flags); /* drop cpkt if port is not open */ Loading Loading @@ -168,31 +175,23 @@ int gqti_ctrl_connect(void *gr, u8 port_num, unsigned intf, { struct qti_ctrl_port *port; struct grmnet *g_rmnet = NULL; struct gqdss *g_dpl = NULL; unsigned long flags; pr_debug("%s: grmnet:%p\n", __func__, gr); pr_debug("%s: gtype:%d gadget:%p\n", __func__, gtype, gr); if (port_num >= NR_QTI_PORTS) { pr_err("%s: Invalid QTI port %d\n", __func__, port_num); return -ENODEV; } if (gtype != USB_GADGET_RMNET) { pr_err("%s(): unrecognized gadget type(%d).\n", __func__, gtype); return -EINVAL; } port = ctrl_port[port_num]; if (!gr || !port) { pr_err("%s: grmnet port is null\n", __func__); if (!port) { pr_err("%s: gadget port is null\n", __func__); return -ENODEV; } spin_lock_irqsave(&port->lock, flags); port->gtype = gtype; port->port_usb = gr; if (dxport == USB_GADGET_XPORT_BAM) { /* * BAM-DMUX data transport is used for RMNET Loading @@ -216,16 +215,28 @@ int gqti_ctrl_connect(void *gr, u8 port_num, unsigned intf, port->intf = intf; } if (gr && port->gtype == USB_GADGET_RMNET) { port->port_usb = gr; g_rmnet = (struct grmnet *)gr; g_rmnet->send_encap_cmd = gqti_ctrl_send_cpkt_tomodem; g_rmnet->notify_modem = gqti_ctrl_notify_modem; } else if (gr && port->gtype == USB_GADGET_DPL) { port->port_usb = gr; g_dpl = (struct gqdss *)gr; g_dpl->send_encap_cmd = gqti_ctrl_send_cpkt_tomodem; g_dpl->notify_modem = gqti_ctrl_notify_modem; atomic_set(&port->line_state, 1); } else { spin_unlock_irqrestore(&port->lock, flags); pr_err("%s(): Port is used without gtype.\n", __func__); return -ENODEV; } spin_unlock_irqrestore(&port->lock, flags); atomic_set(&port->connected, 1); wake_up(&port->read_wq); if (g_rmnet && g_rmnet->connect) if (port->port_usb && g_rmnet && g_rmnet->connect) g_rmnet->connect(port->port_usb); return 0; Loading @@ -237,8 +248,9 @@ void gqti_ctrl_disconnect(void *gr, u8 port_num) unsigned long flags; struct rmnet_ctrl_pkt *cpkt; struct grmnet *g_rmnet = NULL; struct gqdss *g_dpl = NULL; pr_debug("%s: grmnet:%p\n", __func__, gr); pr_debug("%s: gadget:%p\n", __func__, gr); if (port_num >= NR_QTI_PORTS) { pr_err("%s: Invalid QTI port %d\n", __func__, port_num); Loading @@ -247,20 +259,23 @@ void gqti_ctrl_disconnect(void *gr, u8 port_num) port = ctrl_port[port_num]; if (!gr || !port) { pr_err("%s: grmnet port is null\n", __func__); if (!port) { pr_err("%s: gadget port is null\n", __func__); return; } if (port->gtype != USB_GADGET_RMNET) { if (gr && (port->gtype == USB_GADGET_RMNET)) { g_rmnet = (struct grmnet *)gr; g_rmnet->disconnect(port->port_usb); } else if (gr && (port->gtype == USB_GADGET_DPL)) { g_dpl = (struct gqdss *)gr; gqti_ctrl_send_cpkt_tomodem(DPL_QTI_CTRL_PORT_NO, NULL, 0); } else { pr_err("%s(): unrecognized gadget type(%d).\n", __func__, port->gtype); return; } g_rmnet = (struct grmnet *)gr; g_rmnet->disconnect(port->port_usb); atomic_set(&port->connected, 0); atomic_set(&port->line_state, 0); spin_lock_irqsave(&port->lock, flags); Loading @@ -271,6 +286,11 @@ void gqti_ctrl_disconnect(void *gr, u8 port_num) g_rmnet->notify_modem = NULL; } if (g_dpl) { g_dpl->send_encap_cmd = NULL; g_dpl->notify_modem = NULL; } while (!list_empty(&port->cpkt_req_q)) { cpkt = list_first_entry(&port->cpkt_req_q, struct rmnet_ctrl_pkt, list); Loading Loading @@ -512,6 +532,11 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg) switch (cmd) { case QTI_CTRL_MODEM_OFFLINE: if (port && (port->gtype == USB_GADGET_DPL)) { pr_err("%s(): Modem Offline not handled\n", __func__); goto exit_ioctl; } if (port && port->port_usb) gr = port->port_usb; Loading @@ -519,6 +544,11 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg) gr->disconnect(gr); break; case QTI_CTRL_MODEM_ONLINE: if (port && (port->gtype == USB_GADGET_DPL)) { pr_err("%s(): Modem Online not handled\n", __func__); goto exit_ioctl; } if (port && port->port_usb) gr = port->port_usb; Loading @@ -536,6 +566,9 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg) atomic_read(&port->line_state), port->gtype); break; case QTI_CTRL_EP_LOOKUP: pr_debug("%s(): EP_LOOKUP for gtype:%d\n", __func__, port->gtype); val = atomic_read(&port->connected); if (!val) { pr_err("EP_LOOKUP failed - not connected"); Loading Loading @@ -568,6 +601,7 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg) ret = -EINVAL; } exit_ioctl: qti_ctrl_unlock(&port->ioctl_excl); return ret; Loading Loading @@ -611,10 +645,23 @@ static const struct file_operations qti_ctrl_fops = { #endif .poll = qti_ctrl_poll, }; /* file operations for DPL device /dev/dpl_ctrl */ static const struct file_operations dpl_qti_ctrl_fops = { .owner = THIS_MODULE, .open = qti_ctrl_open, .release = qti_ctrl_release, .read = qti_ctrl_read, .write = NULL, .unlocked_ioctl = qti_ctrl_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = qti_ctrl_ioctl, #endif .poll = qti_ctrl_poll, }; static int __init gqti_ctrl_init(void) { int ret, i, sz = sizeof(RMNET_CTRL_QTI_NAME)+2; int ret, i, sz = QTI_CTRL_NAME_LEN; struct qti_ctrl_port *port = NULL; for (i = 0; i < NR_QTI_PORTS; i++) { Loading Loading @@ -644,11 +691,16 @@ static int __init gqti_ctrl_init(void) if (i == 0) strlcat(port->name, RMNET_CTRL_QTI_NAME, sz); else if (i == DPL_QTI_CTRL_PORT_NO) strlcat(port->name, DPL_CTRL_QTI_NAME, sz); else snprintf(port->name, sz, "%s%d", RMNET_CTRL_QTI_NAME, i); port->ctrl_device.name = port->name; if (i == DPL_QTI_CTRL_PORT_NO) port->ctrl_device.fops = &dpl_qti_ctrl_fops; else port->ctrl_device.fops = &qti_ctrl_fops; port->ctrl_device.minor = MISC_DYNAMIC_MINOR; Loading drivers/usb/gadget/u_rmnet.h +2 −1 Original line number Diff line number Diff line Loading @@ -47,8 +47,9 @@ struct grmnet { void (*connect)(struct grmnet *g); }; #define NR_QTI_PORTS 4 #define NR_QTI_PORTS (NR_RMNET_PORTS + NR_DPL_PORTS) #define NR_RMNET_PORTS 4 #define NR_DPL_PORTS 1 enum ctrl_client { FRMNET_CTRL_CLIENT, Loading Loading
drivers/usb/gadget/android.c +20 −0 Original line number Diff line number Diff line Loading @@ -1473,6 +1473,7 @@ static int qdss_init_transports(int *portnum) { char *ts_port; char *tname = NULL; char *ctrl_name = NULL; char buf[MAX_XPORT_STR_LEN], *type; char xport_name_buf[MAX_XPORT_STR_LEN], *tn; int err = 0; Loading @@ -1487,13 +1488,28 @@ static int qdss_init_transports(int *portnum) pr_debug("%s: qdss_debug_intf = %d\n", __func__, qdss_debug_intf); /* * QDSS function driver is being used for QDSS and DPL * functionality. ctrl_name (i.e. ctrl xport) is optional * whereas data transport name is mandatory to provide * while using QDSS/DPL as part of USB composition. */ while (type) { ctrl_name = strsep(&type, ","); ts_port = strsep(&type, ","); if (!ts_port) { pr_debug("%s:ctrl transport is not provided.\n", __func__); ts_port = ctrl_name; ctrl_name = NULL; } if (ts_port) { if (tn) tname = strsep(&tn, ","); err = qdss_init_port( ctrl_name, ts_port, tname, qdss_debug_intf); Loading @@ -1504,6 +1520,10 @@ static int qdss_init_transports(int *portnum) return err; } (*portnum)++; } else { pr_err("%s: No data transport name for QDSS port.\n", __func__); err = -ENODEV; } } return err; Loading
drivers/usb/gadget/f_qdss.c +52 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/device.h> #include <linux/usb/usb_qdss.h> #include <linux/usb/msm_hsusb.h> #include <linux/usb/cdc.h> #include "gadget_chips.h" #include "f_qdss.h" Loading @@ -32,6 +33,8 @@ static unsigned int no_ipa_ports; static struct qdss_ports { enum transport_type data_xport; unsigned char data_xport_num; enum transport_type ctrl_xport; unsigned char ctrl_xport_num; unsigned char port_num; struct f_qdss *port; struct gadget_ipa_port ipa_port; Loading Loading @@ -493,10 +496,12 @@ static void usb_qdss_disconnect_work(struct work_struct *work) int status; unsigned char portno; enum transport_type dxport; enum transport_type ctrl_xport; struct gadget_ipa_port *gp; qdss = container_of(work, struct f_qdss, disconnect_w); dxport = qdss_ports[qdss->port_num].data_xport; ctrl_xport = qdss_ports[qdss->port_num].ctrl_xport; portno = qdss_ports[qdss->port_num].data_xport_num; if (qdss->port_num >= nr_qdss_ports) { Loading @@ -505,6 +510,16 @@ static void usb_qdss_disconnect_work(struct work_struct *work) return; } pr_debug("usb_qdss_disconnect_work\n"); switch (ctrl_xport) { case USB_GADGET_XPORT_QTI: gqti_ctrl_disconnect(&qdss->port, DPL_QTI_CTRL_PORT_NO); break; default: pr_err("%s(): Un-supported transport: %u\n", __func__, ctrl_xport); return; } switch (dxport) { case USB_GADGET_XPORT_BAM: /* Loading Loading @@ -635,9 +650,11 @@ static void usb_qdss_connect_work(struct work_struct *work) int status; unsigned char port_num; enum transport_type dxport; enum transport_type ctrl_xport; qdss = container_of(work, struct f_qdss, connect_w); dxport = qdss_ports[qdss->port_num].data_xport; ctrl_xport = qdss_ports[qdss->port_num].ctrl_xport; port_num = qdss_ports[qdss->port_num].data_xport_num; pr_debug("%s: data xport: %s dev: %p portno: %d\n", __func__, xport_to_str(dxport), Loading @@ -656,6 +673,25 @@ static void usb_qdss_connect_work(struct work_struct *work) } pr_debug("usb_qdss_connect_work\n"); switch (ctrl_xport) { case USB_GADGET_XPORT_QTI: status = gqti_ctrl_connect(&qdss->port, DPL_QTI_CTRL_PORT_NO, qdss->data_iface_id, ctrl_xport, USB_GADGET_DPL); if (status) { pr_err("%s: gqti_ctrl_connect failed: err:%d\n", __func__, status); return; } qdss->port.send_encap_cmd(DPL_QTI_CTRL_PORT_NO, NULL, 0); break; default: pr_err("%s(): Un-supported control transport: %u\n", __func__, ctrl_xport); return; } switch (dxport) { case USB_GADGET_XPORT_BAM: status = init_data(qdss->port.data); Loading Loading @@ -690,7 +726,6 @@ static void usb_qdss_connect_work(struct work_struct *work) return; } qdss->data_enabled = 1; qdss->usb_connected = 1; break; case USB_GADGET_XPORT_HSIC: pr_debug("usb_qdss_connect_work: HSIC transport\n"); Loading Loading @@ -740,6 +775,7 @@ static int qdss_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return -EINVAL; if (dxport == USB_GADGET_XPORT_BAM2BAM_IPA) { qdss->usb_connected = 1; usb_qdss_connect_work(&qdss->connect_w); return 0; } Loading Loading @@ -1109,7 +1145,7 @@ static int qdss_setup(void) return 0; } static int qdss_init_port(const char *data_name, static int qdss_init_port(const char *ctrl_name, const char *data_name, const char *port_name, bool debug_enable) { struct f_qdss *dev; Loading Loading @@ -1141,6 +1177,19 @@ static int qdss_init_port(const char *data_name, qdss_port->data_xport = str_to_xport(data_name); qdss_port->port->debug_inface_enabled = debug_enable; if (ctrl_name) { qdss_port->ctrl_xport = str_to_xport(ctrl_name); pr_debug("%s(): ctrl_name:%s ctrl_xport:%d\n", __func__, ctrl_name, qdss_port->ctrl_xport); switch (qdss_port->ctrl_xport) { case USB_GADGET_XPORT_QTI: pr_debug("USB_GADGET_XPORT_QTI is used.\n"); break; default: pr_debug("%s(): No ctrl transport.\n", __func__); } } switch (qdss_port->data_xport) { case USB_GADGET_XPORT_BAM: qdss_port->data_xport_num = no_data_bam_ports; Loading
drivers/usb/gadget/f_qdss.h +2 −1 Original line number Diff line number Diff line Loading @@ -25,11 +25,12 @@ struct gqdss { struct usb_ep *ctrl_out; struct usb_ep *ctrl_in; struct usb_ep *data; int (*send_encap_cmd)(u8 port_num, void *buf, size_t len); void (*notify_modem)(void *g, u8 port_num, int cbits); }; /* struct f_qdss - USB qdss function driver private structure */ struct f_qdss { struct gqdss port; struct usb_composite_dev *cdev; u8 port_num; Loading
drivers/usb/gadget/u_ctrl_qti.c +81 −29 Original line number Diff line number Diff line Loading @@ -20,10 +20,17 @@ #include "usb_gadget_xport.h" #define RMNET_CTRL_QTI_NAME "rmnet_ctrl" #define DPL_CTRL_QTI_NAME "dpl_ctrl" /* * Use size of gadget's qti control name. Here currently RMNET and DPL * gadget is using QTI as control transport. Hence using RMNET ctrl name * (as it is bigger in size) for QTI_CTRL_NAME_LEN. */ #define QTI_CTRL_NAME_LEN (sizeof(RMNET_CTRL_QTI_NAME)+2) struct qti_ctrl_port { void *port_usb; char name[sizeof(RMNET_CTRL_QTI_NAME) + 2]; char name[QTI_CTRL_NAME_LEN]; struct miscdevice ctrl_device; bool is_open; Loading Loading @@ -122,8 +129,8 @@ static int gqti_ctrl_send_cpkt_tomodem(u8 portno, void *buf, size_t len) memcpy(cpkt->buf, buf, len); cpkt->len = len; pr_debug("%s: Add to cpkt_req_q packet with len = %zu\n", __func__, len); pr_debug("%s: gtype:%d: Add to cpkt_req_q packet with len = %zu\n", __func__, port->gtype, len); spin_lock_irqsave(&port->lock, flags); /* drop cpkt if port is not open */ Loading Loading @@ -168,31 +175,23 @@ int gqti_ctrl_connect(void *gr, u8 port_num, unsigned intf, { struct qti_ctrl_port *port; struct grmnet *g_rmnet = NULL; struct gqdss *g_dpl = NULL; unsigned long flags; pr_debug("%s: grmnet:%p\n", __func__, gr); pr_debug("%s: gtype:%d gadget:%p\n", __func__, gtype, gr); if (port_num >= NR_QTI_PORTS) { pr_err("%s: Invalid QTI port %d\n", __func__, port_num); return -ENODEV; } if (gtype != USB_GADGET_RMNET) { pr_err("%s(): unrecognized gadget type(%d).\n", __func__, gtype); return -EINVAL; } port = ctrl_port[port_num]; if (!gr || !port) { pr_err("%s: grmnet port is null\n", __func__); if (!port) { pr_err("%s: gadget port is null\n", __func__); return -ENODEV; } spin_lock_irqsave(&port->lock, flags); port->gtype = gtype; port->port_usb = gr; if (dxport == USB_GADGET_XPORT_BAM) { /* * BAM-DMUX data transport is used for RMNET Loading @@ -216,16 +215,28 @@ int gqti_ctrl_connect(void *gr, u8 port_num, unsigned intf, port->intf = intf; } if (gr && port->gtype == USB_GADGET_RMNET) { port->port_usb = gr; g_rmnet = (struct grmnet *)gr; g_rmnet->send_encap_cmd = gqti_ctrl_send_cpkt_tomodem; g_rmnet->notify_modem = gqti_ctrl_notify_modem; } else if (gr && port->gtype == USB_GADGET_DPL) { port->port_usb = gr; g_dpl = (struct gqdss *)gr; g_dpl->send_encap_cmd = gqti_ctrl_send_cpkt_tomodem; g_dpl->notify_modem = gqti_ctrl_notify_modem; atomic_set(&port->line_state, 1); } else { spin_unlock_irqrestore(&port->lock, flags); pr_err("%s(): Port is used without gtype.\n", __func__); return -ENODEV; } spin_unlock_irqrestore(&port->lock, flags); atomic_set(&port->connected, 1); wake_up(&port->read_wq); if (g_rmnet && g_rmnet->connect) if (port->port_usb && g_rmnet && g_rmnet->connect) g_rmnet->connect(port->port_usb); return 0; Loading @@ -237,8 +248,9 @@ void gqti_ctrl_disconnect(void *gr, u8 port_num) unsigned long flags; struct rmnet_ctrl_pkt *cpkt; struct grmnet *g_rmnet = NULL; struct gqdss *g_dpl = NULL; pr_debug("%s: grmnet:%p\n", __func__, gr); pr_debug("%s: gadget:%p\n", __func__, gr); if (port_num >= NR_QTI_PORTS) { pr_err("%s: Invalid QTI port %d\n", __func__, port_num); Loading @@ -247,20 +259,23 @@ void gqti_ctrl_disconnect(void *gr, u8 port_num) port = ctrl_port[port_num]; if (!gr || !port) { pr_err("%s: grmnet port is null\n", __func__); if (!port) { pr_err("%s: gadget port is null\n", __func__); return; } if (port->gtype != USB_GADGET_RMNET) { if (gr && (port->gtype == USB_GADGET_RMNET)) { g_rmnet = (struct grmnet *)gr; g_rmnet->disconnect(port->port_usb); } else if (gr && (port->gtype == USB_GADGET_DPL)) { g_dpl = (struct gqdss *)gr; gqti_ctrl_send_cpkt_tomodem(DPL_QTI_CTRL_PORT_NO, NULL, 0); } else { pr_err("%s(): unrecognized gadget type(%d).\n", __func__, port->gtype); return; } g_rmnet = (struct grmnet *)gr; g_rmnet->disconnect(port->port_usb); atomic_set(&port->connected, 0); atomic_set(&port->line_state, 0); spin_lock_irqsave(&port->lock, flags); Loading @@ -271,6 +286,11 @@ void gqti_ctrl_disconnect(void *gr, u8 port_num) g_rmnet->notify_modem = NULL; } if (g_dpl) { g_dpl->send_encap_cmd = NULL; g_dpl->notify_modem = NULL; } while (!list_empty(&port->cpkt_req_q)) { cpkt = list_first_entry(&port->cpkt_req_q, struct rmnet_ctrl_pkt, list); Loading Loading @@ -512,6 +532,11 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg) switch (cmd) { case QTI_CTRL_MODEM_OFFLINE: if (port && (port->gtype == USB_GADGET_DPL)) { pr_err("%s(): Modem Offline not handled\n", __func__); goto exit_ioctl; } if (port && port->port_usb) gr = port->port_usb; Loading @@ -519,6 +544,11 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg) gr->disconnect(gr); break; case QTI_CTRL_MODEM_ONLINE: if (port && (port->gtype == USB_GADGET_DPL)) { pr_err("%s(): Modem Online not handled\n", __func__); goto exit_ioctl; } if (port && port->port_usb) gr = port->port_usb; Loading @@ -536,6 +566,9 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg) atomic_read(&port->line_state), port->gtype); break; case QTI_CTRL_EP_LOOKUP: pr_debug("%s(): EP_LOOKUP for gtype:%d\n", __func__, port->gtype); val = atomic_read(&port->connected); if (!val) { pr_err("EP_LOOKUP failed - not connected"); Loading Loading @@ -568,6 +601,7 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg) ret = -EINVAL; } exit_ioctl: qti_ctrl_unlock(&port->ioctl_excl); return ret; Loading Loading @@ -611,10 +645,23 @@ static const struct file_operations qti_ctrl_fops = { #endif .poll = qti_ctrl_poll, }; /* file operations for DPL device /dev/dpl_ctrl */ static const struct file_operations dpl_qti_ctrl_fops = { .owner = THIS_MODULE, .open = qti_ctrl_open, .release = qti_ctrl_release, .read = qti_ctrl_read, .write = NULL, .unlocked_ioctl = qti_ctrl_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = qti_ctrl_ioctl, #endif .poll = qti_ctrl_poll, }; static int __init gqti_ctrl_init(void) { int ret, i, sz = sizeof(RMNET_CTRL_QTI_NAME)+2; int ret, i, sz = QTI_CTRL_NAME_LEN; struct qti_ctrl_port *port = NULL; for (i = 0; i < NR_QTI_PORTS; i++) { Loading Loading @@ -644,11 +691,16 @@ static int __init gqti_ctrl_init(void) if (i == 0) strlcat(port->name, RMNET_CTRL_QTI_NAME, sz); else if (i == DPL_QTI_CTRL_PORT_NO) strlcat(port->name, DPL_CTRL_QTI_NAME, sz); else snprintf(port->name, sz, "%s%d", RMNET_CTRL_QTI_NAME, i); port->ctrl_device.name = port->name; if (i == DPL_QTI_CTRL_PORT_NO) port->ctrl_device.fops = &dpl_qti_ctrl_fops; else port->ctrl_device.fops = &qti_ctrl_fops; port->ctrl_device.minor = MISC_DYNAMIC_MINOR; Loading
drivers/usb/gadget/u_rmnet.h +2 −1 Original line number Diff line number Diff line Loading @@ -47,8 +47,9 @@ struct grmnet { void (*connect)(struct grmnet *g); }; #define NR_QTI_PORTS 4 #define NR_QTI_PORTS (NR_RMNET_PORTS + NR_DPL_PORTS) #define NR_RMNET_PORTS 4 #define NR_DPL_PORTS 1 enum ctrl_client { FRMNET_CTRL_CLIENT, Loading