Loading drivers/usb/gadget/function/f_qc_rndis.c +64 −21 Original line number Original line Diff line number Diff line Loading @@ -1289,8 +1289,6 @@ rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], rndis->port.func.suspend = rndis_qc_suspend; rndis->port.func.suspend = rndis_qc_suspend; rndis->port.func.resume = rndis_qc_resume; rndis->port.func.resume = rndis_qc_resume; _rndis_qc = rndis; if (rndis->xport == USB_GADGET_XPORT_BAM2BAM_IPA) { if (rndis->xport == USB_GADGET_XPORT_BAM2BAM_IPA) { status = rndis_ipa_init(&rndis_ipa_params); status = rndis_ipa_init(&rndis_ipa_params); if (status) { if (status) { Loading @@ -1305,6 +1303,9 @@ rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], rndis_ipa_cleanup(rndis_ipa_params.private); rndis_ipa_cleanup(rndis_ipa_params.private); goto fail; goto fail; } } _rndis_qc = rndis; c->cdev->gadget->bam2bam_func_enabled = true; c->cdev->gadget->bam2bam_func_enabled = true; return 0; return 0; Loading @@ -1317,74 +1318,115 @@ fail: static int rndis_qc_open_dev(struct inode *ip, struct file *fp) static int rndis_qc_open_dev(struct inode *ip, struct file *fp) { { int ret = 0; unsigned long flags; pr_info("Open rndis QC driver\n"); pr_info("Open rndis QC driver\n"); spin_lock_irqsave(&rndis_lock, flags); if (!_rndis_qc) { if (!_rndis_qc) { pr_err("rndis_qc_dev not created yet\n"); pr_err("rndis_qc_dev not created yet\n"); return -ENODEV; ret = -ENODEV; goto fail; } } if (rndis_qc_lock(&_rndis_qc->open_excl)) { if (rndis_qc_lock(&_rndis_qc->open_excl)) { pr_err("Already opened\n"); pr_err("Already opened\n"); return -EBUSY; ret = -EBUSY; goto fail; } } fp->private_data = _rndis_qc; fp->private_data = _rndis_qc; fail: spin_unlock_irqrestore(&rndis_lock, flags); if (!ret) pr_info("rndis QC file opened\n"); pr_info("rndis QC file opened\n"); return 0; return ret; } } static int rndis_qc_release_dev(struct inode *ip, struct file *fp) static int rndis_qc_release_dev(struct inode *ip, struct file *fp) { { struct f_rndis_qc *rndis = fp->private_data; unsigned long flags; pr_info("Close rndis QC file\n"); pr_info("Close rndis QC file\n"); rndis_qc_unlock(&rndis->open_excl); spin_lock_irqsave(&rndis_lock, flags); if (!_rndis_qc) { pr_err("rndis_qc_dev not present\n"); spin_unlock_irqrestore(&rndis_lock, flags); return -ENODEV; } rndis_qc_unlock(&_rndis_qc->open_excl); spin_unlock_irqrestore(&rndis_lock, flags); return 0; return 0; } } static long rndis_qc_ioctl(struct file *fp, unsigned cmd, unsigned long arg) static long rndis_qc_ioctl(struct file *fp, unsigned cmd, unsigned long arg) { { struct f_rndis_qc *rndis = fp->private_data; u8 qc_max_pkt_per_xfer = 0; u32 qc_max_pkt_size = 0; int ret = 0; int ret = 0; unsigned long flags; pr_info("Received command %d\n", cmd); spin_lock_irqsave(&rndis_lock, flags); if (!_rndis_qc) { pr_err("rndis_qc_dev not present\n"); ret = -ENODEV; goto fail; } if (rndis_qc_lock(&rndis->ioctl_excl)) qc_max_pkt_per_xfer = _rndis_qc->ul_max_pkt_per_xfer; return -EBUSY; qc_max_pkt_size = _rndis_qc->max_pkt_size; if (rndis_qc_lock(&_rndis_qc->ioctl_excl)) { ret = -EBUSY; goto fail; } spin_unlock_irqrestore(&rndis_lock, flags); pr_info("Received command %d\n", cmd); switch (cmd) { switch (cmd) { case RNDIS_QC_GET_MAX_PKT_PER_XFER: case RNDIS_QC_GET_MAX_PKT_PER_XFER: ret = copy_to_user((void __user *)arg, ret = copy_to_user((void __user *)arg, &rndis->ul_max_pkt_per_xfer, &qc_max_pkt_per_xfer, sizeof(rndis->ul_max_pkt_per_xfer)); sizeof(qc_max_pkt_per_xfer)); if (ret) { if (ret) { pr_err("copying to user space failed\n"); pr_err("copying to user space failed\n"); ret = -EFAULT; ret = -EFAULT; } } pr_info("Sent UL max packets per xfer %d\n", pr_info("Sent UL max packets per xfer %d\n", rndis->ul_max_pkt_per_xfer); qc_max_pkt_per_xfer); break; break; case RNDIS_QC_GET_MAX_PKT_SIZE: case RNDIS_QC_GET_MAX_PKT_SIZE: ret = copy_to_user((void __user *)arg, ret = copy_to_user((void __user *)arg, &rndis->max_pkt_size, &qc_max_pkt_size, sizeof(rndis->max_pkt_size)); sizeof(qc_max_pkt_size)); if (ret) { if (ret) { pr_err("copying to user space failed\n"); pr_err("copying to user space failed\n"); ret = -EFAULT; ret = -EFAULT; } } pr_debug("Sent max packet size %d\n", pr_debug("Sent max packet size %d\n", rndis->max_pkt_size); qc_max_pkt_size); break; break; default: default: pr_err("Unsupported IOCTL\n"); pr_err("Unsupported IOCTL\n"); ret = -EINVAL; ret = -EINVAL; } } rndis_qc_unlock(&rndis->ioctl_excl); spin_lock_irqsave(&rndis_lock, flags); if (!_rndis_qc) { pr_err("rndis_qc_dev not present\n"); ret = -ENODEV; goto fail; } rndis_qc_unlock(&_rndis_qc->ioctl_excl); fail: spin_unlock_irqrestore(&rndis_lock, flags); return ret; return ret; } } Loading @@ -1407,10 +1449,11 @@ static int rndis_qc_init(void) pr_info("initialize rndis QC instance\n"); pr_info("initialize rndis QC instance\n"); spin_lock_init(&rndis_lock); ret = misc_register(&rndis_qc_device); ret = misc_register(&rndis_qc_device); if (ret) if (ret) pr_err("rndis QC driver failed to register\n"); pr_err("rndis QC driver failed to register\n"); spin_lock_init(&rndis_lock); ret = bam_data_setup(USB_FUNC_RNDIS, RNDIS_QC_NO_PORTS); ret = bam_data_setup(USB_FUNC_RNDIS, RNDIS_QC_NO_PORTS); if (ret) { if (ret) { Loading Loading
drivers/usb/gadget/function/f_qc_rndis.c +64 −21 Original line number Original line Diff line number Diff line Loading @@ -1289,8 +1289,6 @@ rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], rndis->port.func.suspend = rndis_qc_suspend; rndis->port.func.suspend = rndis_qc_suspend; rndis->port.func.resume = rndis_qc_resume; rndis->port.func.resume = rndis_qc_resume; _rndis_qc = rndis; if (rndis->xport == USB_GADGET_XPORT_BAM2BAM_IPA) { if (rndis->xport == USB_GADGET_XPORT_BAM2BAM_IPA) { status = rndis_ipa_init(&rndis_ipa_params); status = rndis_ipa_init(&rndis_ipa_params); if (status) { if (status) { Loading @@ -1305,6 +1303,9 @@ rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], rndis_ipa_cleanup(rndis_ipa_params.private); rndis_ipa_cleanup(rndis_ipa_params.private); goto fail; goto fail; } } _rndis_qc = rndis; c->cdev->gadget->bam2bam_func_enabled = true; c->cdev->gadget->bam2bam_func_enabled = true; return 0; return 0; Loading @@ -1317,74 +1318,115 @@ fail: static int rndis_qc_open_dev(struct inode *ip, struct file *fp) static int rndis_qc_open_dev(struct inode *ip, struct file *fp) { { int ret = 0; unsigned long flags; pr_info("Open rndis QC driver\n"); pr_info("Open rndis QC driver\n"); spin_lock_irqsave(&rndis_lock, flags); if (!_rndis_qc) { if (!_rndis_qc) { pr_err("rndis_qc_dev not created yet\n"); pr_err("rndis_qc_dev not created yet\n"); return -ENODEV; ret = -ENODEV; goto fail; } } if (rndis_qc_lock(&_rndis_qc->open_excl)) { if (rndis_qc_lock(&_rndis_qc->open_excl)) { pr_err("Already opened\n"); pr_err("Already opened\n"); return -EBUSY; ret = -EBUSY; goto fail; } } fp->private_data = _rndis_qc; fp->private_data = _rndis_qc; fail: spin_unlock_irqrestore(&rndis_lock, flags); if (!ret) pr_info("rndis QC file opened\n"); pr_info("rndis QC file opened\n"); return 0; return ret; } } static int rndis_qc_release_dev(struct inode *ip, struct file *fp) static int rndis_qc_release_dev(struct inode *ip, struct file *fp) { { struct f_rndis_qc *rndis = fp->private_data; unsigned long flags; pr_info("Close rndis QC file\n"); pr_info("Close rndis QC file\n"); rndis_qc_unlock(&rndis->open_excl); spin_lock_irqsave(&rndis_lock, flags); if (!_rndis_qc) { pr_err("rndis_qc_dev not present\n"); spin_unlock_irqrestore(&rndis_lock, flags); return -ENODEV; } rndis_qc_unlock(&_rndis_qc->open_excl); spin_unlock_irqrestore(&rndis_lock, flags); return 0; return 0; } } static long rndis_qc_ioctl(struct file *fp, unsigned cmd, unsigned long arg) static long rndis_qc_ioctl(struct file *fp, unsigned cmd, unsigned long arg) { { struct f_rndis_qc *rndis = fp->private_data; u8 qc_max_pkt_per_xfer = 0; u32 qc_max_pkt_size = 0; int ret = 0; int ret = 0; unsigned long flags; pr_info("Received command %d\n", cmd); spin_lock_irqsave(&rndis_lock, flags); if (!_rndis_qc) { pr_err("rndis_qc_dev not present\n"); ret = -ENODEV; goto fail; } if (rndis_qc_lock(&rndis->ioctl_excl)) qc_max_pkt_per_xfer = _rndis_qc->ul_max_pkt_per_xfer; return -EBUSY; qc_max_pkt_size = _rndis_qc->max_pkt_size; if (rndis_qc_lock(&_rndis_qc->ioctl_excl)) { ret = -EBUSY; goto fail; } spin_unlock_irqrestore(&rndis_lock, flags); pr_info("Received command %d\n", cmd); switch (cmd) { switch (cmd) { case RNDIS_QC_GET_MAX_PKT_PER_XFER: case RNDIS_QC_GET_MAX_PKT_PER_XFER: ret = copy_to_user((void __user *)arg, ret = copy_to_user((void __user *)arg, &rndis->ul_max_pkt_per_xfer, &qc_max_pkt_per_xfer, sizeof(rndis->ul_max_pkt_per_xfer)); sizeof(qc_max_pkt_per_xfer)); if (ret) { if (ret) { pr_err("copying to user space failed\n"); pr_err("copying to user space failed\n"); ret = -EFAULT; ret = -EFAULT; } } pr_info("Sent UL max packets per xfer %d\n", pr_info("Sent UL max packets per xfer %d\n", rndis->ul_max_pkt_per_xfer); qc_max_pkt_per_xfer); break; break; case RNDIS_QC_GET_MAX_PKT_SIZE: case RNDIS_QC_GET_MAX_PKT_SIZE: ret = copy_to_user((void __user *)arg, ret = copy_to_user((void __user *)arg, &rndis->max_pkt_size, &qc_max_pkt_size, sizeof(rndis->max_pkt_size)); sizeof(qc_max_pkt_size)); if (ret) { if (ret) { pr_err("copying to user space failed\n"); pr_err("copying to user space failed\n"); ret = -EFAULT; ret = -EFAULT; } } pr_debug("Sent max packet size %d\n", pr_debug("Sent max packet size %d\n", rndis->max_pkt_size); qc_max_pkt_size); break; break; default: default: pr_err("Unsupported IOCTL\n"); pr_err("Unsupported IOCTL\n"); ret = -EINVAL; ret = -EINVAL; } } rndis_qc_unlock(&rndis->ioctl_excl); spin_lock_irqsave(&rndis_lock, flags); if (!_rndis_qc) { pr_err("rndis_qc_dev not present\n"); ret = -ENODEV; goto fail; } rndis_qc_unlock(&_rndis_qc->ioctl_excl); fail: spin_unlock_irqrestore(&rndis_lock, flags); return ret; return ret; } } Loading @@ -1407,10 +1449,11 @@ static int rndis_qc_init(void) pr_info("initialize rndis QC instance\n"); pr_info("initialize rndis QC instance\n"); spin_lock_init(&rndis_lock); ret = misc_register(&rndis_qc_device); ret = misc_register(&rndis_qc_device); if (ret) if (ret) pr_err("rndis QC driver failed to register\n"); pr_err("rndis QC driver failed to register\n"); spin_lock_init(&rndis_lock); ret = bam_data_setup(USB_FUNC_RNDIS, RNDIS_QC_NO_PORTS); ret = bam_data_setup(USB_FUNC_RNDIS, RNDIS_QC_NO_PORTS); if (ret) { if (ret) { Loading