diff options
Diffstat (limited to 'drivers/usb/gadget')
| -rw-r--r-- | drivers/usb/gadget/composite.c | 3 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_audio_source.c | 27 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_qc_rndis.c | 91 |
3 files changed, 92 insertions, 29 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index a844ea4d06db..eeccae8bfc1b 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1654,9 +1654,6 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) DBG(cdev, "Config HS device with LPM(L1)\n"); } - } else if (!disable_l1_for_hs) { - cdev->desc.bcdUSB = cpu_to_le16(0x0210); - DBG(cdev, "Config HS device with LPM(L1)\n"); } value = min(w_length, (u16) sizeof cdev->desc); diff --git a/drivers/usb/gadget/function/f_audio_source.c b/drivers/usb/gadget/function/f_audio_source.c index 51ab794ef6f9..ab7441fcf66f 100644 --- a/drivers/usb/gadget/function/f_audio_source.c +++ b/drivers/usb/gadget/function/f_audio_source.c @@ -369,15 +369,22 @@ static void audio_send(struct audio_dev *audio) s64 msecs; s64 frames; ktime_t now; + unsigned long flags; + spin_lock_irqsave(&audio->lock, flags); /* audio->substream will be null if we have been closed */ - if (!audio->substream) + if (!audio->substream) { + spin_unlock_irqrestore(&audio->lock, flags); return; + } /* audio->buffer_pos will be null if we have been stopped */ - if (!audio->buffer_pos) + if (!audio->buffer_pos) { + spin_unlock_irqrestore(&audio->lock, flags); return; + } runtime = audio->substream->runtime; + spin_unlock_irqrestore(&audio->lock, flags); /* compute number of frames to send */ now = ktime_get(); @@ -400,8 +407,21 @@ static void audio_send(struct audio_dev *audio) while (frames > 0) { req = audio_req_get(audio); - if (!req) + spin_lock_irqsave(&audio->lock, flags); + /* audio->substream will be null if we have been closed */ + if (!audio->substream) { + spin_unlock_irqrestore(&audio->lock, flags); + return; + } + /* audio->buffer_pos will be null if we have been stopped */ + if (!audio->buffer_pos) { + spin_unlock_irqrestore(&audio->lock, flags); + return; + } + if (!req) { + spin_unlock_irqrestore(&audio->lock, flags); break; + } length = frames_to_bytes(runtime, frames); if (length > IN_EP_MAX_PACKET_SIZE) @@ -427,6 +447,7 @@ static void audio_send(struct audio_dev *audio) } req->length = length; + spin_unlock_irqrestore(&audio->lock, flags); ret = usb_ep_queue(audio->in_ep, req, GFP_ATOMIC); if (ret < 0) { pr_err("usb_ep_queue failed ret: %d\n", ret); diff --git a/drivers/usb/gadget/function/f_qc_rndis.c b/drivers/usb/gadget/function/f_qc_rndis.c index 45c39d3c4225..434af820e827 100644 --- a/drivers/usb/gadget/function/f_qc_rndis.c +++ b/drivers/usb/gadget/function/f_qc_rndis.c @@ -1245,16 +1245,19 @@ usb_function *rndis_qc_bind_config_vendor(struct usb_function_instance *fi, rndis->func.resume = rndis_qc_resume; rndis->func.free_func = rndis_qc_free; - _rndis_qc = rndis; - status = rndis_ipa_init(&rndis_ipa_params); if (status) { pr_err("%s: failed to init rndis_ipa\n", __func__); - kfree(rndis); - return ERR_PTR(status); + goto fail; } + _rndis_qc = rndis; + return &rndis->func; +fail: + kfree(rndis); + _rndis_qc = NULL; + return ERR_PTR(status); } static struct usb_function *qcrndis_alloc(struct usb_function_instance *fi) @@ -1264,74 +1267,116 @@ static struct usb_function *qcrndis_alloc(struct usb_function_instance *fi) 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"); + spin_lock_irqsave(&rndis_lock, flags); if (!_rndis_qc) { pr_err("rndis_qc_dev not created yet\n"); - return -ENODEV; + ret = -ENODEV; + goto fail; } if (rndis_qc_lock(&_rndis_qc->open_excl)) { pr_err("Already opened\n"); - return -EBUSY; + ret = -EBUSY; + goto fail; } fp->private_data = _rndis_qc; - pr_info("rndis QC file opened\n"); +fail: + spin_unlock_irqrestore(&rndis_lock, flags); - return 0; + if (!ret) + pr_info("rndis QC file opened\n"); + + return ret; } 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"); - 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; } 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; + 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; + } + + qc_max_pkt_per_xfer = _rndis_qc->ul_max_pkt_per_xfer; + 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); - if (rndis_qc_lock(&rndis->ioctl_excl)) - return -EBUSY; + pr_info("Received command %d\n", cmd); switch (cmd) { case RNDIS_QC_GET_MAX_PKT_PER_XFER: ret = copy_to_user((void __user *)arg, - &rndis->ul_max_pkt_per_xfer, - sizeof(rndis->ul_max_pkt_per_xfer)); + &qc_max_pkt_per_xfer, + sizeof(qc_max_pkt_per_xfer)); if (ret) { pr_err("copying to user space failed\n"); ret = -EFAULT; } pr_info("Sent UL max packets per xfer %d\n", - rndis->ul_max_pkt_per_xfer); + qc_max_pkt_per_xfer); break; case RNDIS_QC_GET_MAX_PKT_SIZE: ret = copy_to_user((void __user *)arg, - &rndis->max_pkt_size, - sizeof(rndis->max_pkt_size)); + &qc_max_pkt_size, + sizeof(qc_max_pkt_size)); if (ret) { pr_err("copying to user space failed\n"); ret = -EFAULT; } pr_debug("Sent max packet size %d\n", - rndis->max_pkt_size); + qc_max_pkt_size); break; default: pr_err("Unsupported IOCTL\n"); 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; } @@ -1385,11 +1430,11 @@ static int qcrndis_set_inst_name(struct usb_function_instance *fi, return -ENOMEM; } + spin_lock_init(&rndis_lock); opts->rndis = rndis; ret = misc_register(&rndis_qc_device); if (ret) pr_err("rndis QC driver failed to register\n"); - spin_lock_init(&rndis_lock); ret = ipa_data_setup(USB_IPA_FUNC_RNDIS); if (ret) { |
