USB: uss720: fix DMA-buffer allocation
Make sure the USB control request is allocated separately from containing structure to prevent potential memory corruption on non-cache-coherent systems. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
cbf30a914e
commit
9821aa9de9
1 changed files with 15 additions and 9 deletions
|
@ -75,7 +75,7 @@ struct uss720_async_request {
|
||||||
struct list_head asynclist;
|
struct list_head asynclist;
|
||||||
struct completion compl;
|
struct completion compl;
|
||||||
struct urb *urb;
|
struct urb *urb;
|
||||||
struct usb_ctrlrequest dr;
|
struct usb_ctrlrequest *dr;
|
||||||
__u8 reg[7];
|
__u8 reg[7];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,6 +98,7 @@ static void destroy_async(struct kref *kref)
|
||||||
|
|
||||||
if (likely(rq->urb))
|
if (likely(rq->urb))
|
||||||
usb_free_urb(rq->urb);
|
usb_free_urb(rq->urb);
|
||||||
|
kfree(rq->dr);
|
||||||
spin_lock_irqsave(&priv->asynclock, flags);
|
spin_lock_irqsave(&priv->asynclock, flags);
|
||||||
list_del_init(&rq->asynclist);
|
list_del_init(&rq->asynclist);
|
||||||
spin_unlock_irqrestore(&priv->asynclock, flags);
|
spin_unlock_irqrestore(&priv->asynclock, flags);
|
||||||
|
@ -120,7 +121,7 @@ static void async_complete(struct urb *urb)
|
||||||
if (status) {
|
if (status) {
|
||||||
dev_err(&urb->dev->dev, "async_complete: urb error %d\n",
|
dev_err(&urb->dev->dev, "async_complete: urb error %d\n",
|
||||||
status);
|
status);
|
||||||
} else if (rq->dr.bRequest == 3) {
|
} else if (rq->dr->bRequest == 3) {
|
||||||
memcpy(priv->reg, rq->reg, sizeof(priv->reg));
|
memcpy(priv->reg, rq->reg, sizeof(priv->reg));
|
||||||
#if 0
|
#if 0
|
||||||
dev_dbg(&priv->usbdev->dev,
|
dev_dbg(&priv->usbdev->dev,
|
||||||
|
@ -152,7 +153,7 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p
|
||||||
usbdev = priv->usbdev;
|
usbdev = priv->usbdev;
|
||||||
if (!usbdev)
|
if (!usbdev)
|
||||||
return NULL;
|
return NULL;
|
||||||
rq = kmalloc(sizeof(struct uss720_async_request), mem_flags);
|
rq = kzalloc(sizeof(struct uss720_async_request), mem_flags);
|
||||||
if (!rq) {
|
if (!rq) {
|
||||||
dev_err(&usbdev->dev, "submit_async_request out of memory\n");
|
dev_err(&usbdev->dev, "submit_async_request out of memory\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -168,13 +169,18 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p
|
||||||
dev_err(&usbdev->dev, "submit_async_request out of memory\n");
|
dev_err(&usbdev->dev, "submit_async_request out of memory\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rq->dr.bRequestType = requesttype;
|
rq->dr = kmalloc(sizeof(*rq->dr), mem_flags);
|
||||||
rq->dr.bRequest = request;
|
if (!rq->dr) {
|
||||||
rq->dr.wValue = cpu_to_le16(value);
|
kref_put(&rq->ref_count, destroy_async);
|
||||||
rq->dr.wIndex = cpu_to_le16(index);
|
return NULL;
|
||||||
rq->dr.wLength = cpu_to_le16((request == 3) ? sizeof(rq->reg) : 0);
|
}
|
||||||
|
rq->dr->bRequestType = requesttype;
|
||||||
|
rq->dr->bRequest = request;
|
||||||
|
rq->dr->wValue = cpu_to_le16(value);
|
||||||
|
rq->dr->wIndex = cpu_to_le16(index);
|
||||||
|
rq->dr->wLength = cpu_to_le16((request == 3) ? sizeof(rq->reg) : 0);
|
||||||
usb_fill_control_urb(rq->urb, usbdev, (requesttype & 0x80) ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0),
|
usb_fill_control_urb(rq->urb, usbdev, (requesttype & 0x80) ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0),
|
||||||
(unsigned char *)&rq->dr,
|
(unsigned char *)rq->dr,
|
||||||
(request == 3) ? rq->reg : NULL, (request == 3) ? sizeof(rq->reg) : 0, async_complete, rq);
|
(request == 3) ? rq->reg : NULL, (request == 3) ? sizeof(rq->reg) : 0, async_complete, rq);
|
||||||
/* rq->urb->transfer_flags |= URB_ASYNC_UNLINK; */
|
/* rq->urb->transfer_flags |= URB_ASYNC_UNLINK; */
|
||||||
spin_lock_irqsave(&priv->asynclock, flags);
|
spin_lock_irqsave(&priv->asynclock, flags);
|
||||||
|
|
Loading…
Reference in a new issue