Commit 29135878 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

V4L/DVB (8208): uvcvideo: Use GFP_NOIO when allocating memory during resume

The swap device might still be asleep, so memory allocated in the resume
handler must use GFP_NOIO. Thanks to Oliver Neukum for catching and reporting
this bug.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 233548a2
...@@ -203,5 +203,5 @@ int uvc_status_resume(struct uvc_device *dev) ...@@ -203,5 +203,5 @@ int uvc_status_resume(struct uvc_device *dev)
if (dev->int_urb == NULL) if (dev->int_urb == NULL)
return 0; return 0;
return usb_submit_urb(dev->int_urb, GFP_KERNEL); return usb_submit_urb(dev->int_urb, GFP_NOIO);
} }
...@@ -586,7 +586,7 @@ static void uvc_uninit_video(struct uvc_video_device *video) ...@@ -586,7 +586,7 @@ static void uvc_uninit_video(struct uvc_video_device *video)
* is given by the endpoint. * is given by the endpoint.
*/ */
static int uvc_init_video_isoc(struct uvc_video_device *video, static int uvc_init_video_isoc(struct uvc_video_device *video,
struct usb_host_endpoint *ep) struct usb_host_endpoint *ep, gfp_t gfp_flags)
{ {
struct urb *urb; struct urb *urb;
unsigned int npackets, i, j; unsigned int npackets, i, j;
...@@ -611,14 +611,14 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, ...@@ -611,14 +611,14 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
size = npackets * psize; size = npackets * psize;
for (i = 0; i < UVC_URBS; ++i) { for (i = 0; i < UVC_URBS; ++i) {
urb = usb_alloc_urb(npackets, GFP_KERNEL); urb = usb_alloc_urb(npackets, gfp_flags);
if (urb == NULL) { if (urb == NULL) {
uvc_uninit_video(video); uvc_uninit_video(video);
return -ENOMEM; return -ENOMEM;
} }
video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
size, GFP_KERNEL, &urb->transfer_dma); size, gfp_flags, &urb->transfer_dma);
if (video->urb_buffer[i] == NULL) { if (video->urb_buffer[i] == NULL) {
usb_free_urb(urb); usb_free_urb(urb);
uvc_uninit_video(video); uvc_uninit_video(video);
...@@ -652,7 +652,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, ...@@ -652,7 +652,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
* given by the endpoint. * given by the endpoint.
*/ */
static int uvc_init_video_bulk(struct uvc_video_device *video, static int uvc_init_video_bulk(struct uvc_video_device *video,
struct usb_host_endpoint *ep) struct usb_host_endpoint *ep, gfp_t gfp_flags)
{ {
struct urb *urb; struct urb *urb;
unsigned int pipe, i; unsigned int pipe, i;
...@@ -674,14 +674,14 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, ...@@ -674,14 +674,14 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress);
for (i = 0; i < UVC_URBS; ++i) { for (i = 0; i < UVC_URBS; ++i) {
urb = usb_alloc_urb(0, GFP_KERNEL); urb = usb_alloc_urb(0, gfp_flags);
if (urb == NULL) { if (urb == NULL) {
uvc_uninit_video(video); uvc_uninit_video(video);
return -ENOMEM; return -ENOMEM;
} }
video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
size, GFP_KERNEL, &urb->transfer_dma); size, gfp_flags, &urb->transfer_dma);
if (video->urb_buffer[i] == NULL) { if (video->urb_buffer[i] == NULL) {
usb_free_urb(urb); usb_free_urb(urb);
uvc_uninit_video(video); uvc_uninit_video(video);
...@@ -702,7 +702,7 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, ...@@ -702,7 +702,7 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
/* /*
* Initialize isochronous/bulk URBs and allocate transfer buffers. * Initialize isochronous/bulk URBs and allocate transfer buffers.
*/ */
static int uvc_init_video(struct uvc_video_device *video) static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
{ {
struct usb_interface *intf = video->streaming->intf; struct usb_interface *intf = video->streaming->intf;
struct usb_host_interface *alts; struct usb_host_interface *alts;
...@@ -747,7 +747,7 @@ static int uvc_init_video(struct uvc_video_device *video) ...@@ -747,7 +747,7 @@ static int uvc_init_video(struct uvc_video_device *video)
if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0) if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0)
return ret; return ret;
ret = uvc_init_video_isoc(video, ep); ret = uvc_init_video_isoc(video, ep, gfp_flags);
} else { } else {
/* Bulk endpoint, proceed to URB initialization. */ /* Bulk endpoint, proceed to URB initialization. */
ep = uvc_find_endpoint(&intf->altsetting[0], ep = uvc_find_endpoint(&intf->altsetting[0],
...@@ -755,7 +755,7 @@ static int uvc_init_video(struct uvc_video_device *video) ...@@ -755,7 +755,7 @@ static int uvc_init_video(struct uvc_video_device *video)
if (ep == NULL) if (ep == NULL)
return -EIO; return -EIO;
ret = uvc_init_video_bulk(video, ep); ret = uvc_init_video_bulk(video, ep, gfp_flags);
} }
if (ret < 0) if (ret < 0)
...@@ -763,7 +763,7 @@ static int uvc_init_video(struct uvc_video_device *video) ...@@ -763,7 +763,7 @@ static int uvc_init_video(struct uvc_video_device *video)
/* Submit the URBs. */ /* Submit the URBs. */
for (i = 0; i < UVC_URBS; ++i) { for (i = 0; i < UVC_URBS; ++i) {
if ((ret = usb_submit_urb(video->urb[i], GFP_KERNEL)) < 0) { if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) {
uvc_printk(KERN_ERR, "Failed to submit URB %u " uvc_printk(KERN_ERR, "Failed to submit URB %u "
"(%d).\n", i, ret); "(%d).\n", i, ret);
uvc_uninit_video(video); uvc_uninit_video(video);
...@@ -818,7 +818,7 @@ int uvc_video_resume(struct uvc_video_device *video) ...@@ -818,7 +818,7 @@ int uvc_video_resume(struct uvc_video_device *video)
if (!uvc_queue_streaming(&video->queue)) if (!uvc_queue_streaming(&video->queue))
return 0; return 0;
if ((ret = uvc_init_video(video)) < 0) if ((ret = uvc_init_video(video, GFP_NOIO)) < 0)
uvc_queue_enable(&video->queue, 0); uvc_queue_enable(&video->queue, 0);
return ret; return ret;
...@@ -930,5 +930,5 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) ...@@ -930,5 +930,5 @@ int uvc_video_enable(struct uvc_video_device *video, int enable)
if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
return ret; return ret;
return uvc_init_video(video); return uvc_init_video(video, GFP_KERNEL);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment