mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 11:53:01 +00:00
Merge "usb: gadget: diag: fix read/write race with unbind"
This commit is contained in:
commit
8b000bf25c
|
@ -422,6 +422,7 @@ int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req)
|
|||
struct diag_context *ctxt = ch->priv_usb;
|
||||
unsigned long flags;
|
||||
struct usb_request *req;
|
||||
struct usb_ep *out;
|
||||
static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
|
||||
|
||||
if (!ctxt)
|
||||
|
@ -429,11 +430,13 @@ int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req)
|
|||
|
||||
spin_lock_irqsave(&ctxt->lock, flags);
|
||||
|
||||
if (!ctxt->configured) {
|
||||
if (!ctxt->configured || !ctxt->out) {
|
||||
spin_unlock_irqrestore(&ctxt->lock, flags);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
out = ctxt->out;
|
||||
|
||||
if (list_empty(&ctxt->read_pool)) {
|
||||
spin_unlock_irqrestore(&ctxt->lock, flags);
|
||||
ERROR(ctxt->cdev, "%s: no requests available\n", __func__);
|
||||
|
@ -447,7 +450,14 @@ int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req)
|
|||
req->buf = d_req->buf;
|
||||
req->length = d_req->length;
|
||||
req->context = d_req;
|
||||
if (usb_ep_queue(ctxt->out, req, GFP_ATOMIC)) {
|
||||
|
||||
/* make sure context is still valid after releasing lock */
|
||||
if (ctxt != ch->priv_usb) {
|
||||
usb_ep_free_request(out, req);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (usb_ep_queue(out, req, GFP_ATOMIC)) {
|
||||
/* If error add the link to linked list again*/
|
||||
spin_lock_irqsave(&ctxt->lock, flags);
|
||||
list_add_tail(&req->list, &ctxt->read_pool);
|
||||
|
@ -481,6 +491,7 @@ int usb_diag_write(struct usb_diag_ch *ch, struct diag_request *d_req)
|
|||
struct diag_context *ctxt = ch->priv_usb;
|
||||
unsigned long flags;
|
||||
struct usb_request *req = NULL;
|
||||
struct usb_ep *in;
|
||||
static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1);
|
||||
|
||||
if (!ctxt)
|
||||
|
@ -488,11 +499,13 @@ int usb_diag_write(struct usb_diag_ch *ch, struct diag_request *d_req)
|
|||
|
||||
spin_lock_irqsave(&ctxt->lock, flags);
|
||||
|
||||
if (!ctxt->configured) {
|
||||
if (!ctxt->configured || !ctxt->in) {
|
||||
spin_unlock_irqrestore(&ctxt->lock, flags);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
in = ctxt->in;
|
||||
|
||||
if (list_empty(&ctxt->write_pool)) {
|
||||
spin_unlock_irqrestore(&ctxt->lock, flags);
|
||||
ERROR(ctxt->cdev, "%s: no requests available\n", __func__);
|
||||
|
@ -506,7 +519,14 @@ int usb_diag_write(struct usb_diag_ch *ch, struct diag_request *d_req)
|
|||
req->buf = d_req->buf;
|
||||
req->length = d_req->length;
|
||||
req->context = d_req;
|
||||
if (usb_ep_queue(ctxt->in, req, GFP_ATOMIC)) {
|
||||
|
||||
/* make sure context is still valid after releasing lock */
|
||||
if (ctxt != ch->priv_usb) {
|
||||
usb_ep_free_request(in, req);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (usb_ep_queue(in, req, GFP_ATOMIC)) {
|
||||
/* If error add the link to linked list again*/
|
||||
spin_lock_irqsave(&ctxt->lock, flags);
|
||||
list_add_tail(&req->list, &ctxt->write_pool);
|
||||
|
|
Loading…
Reference in a new issue