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: Laurent Pinchart <laurent.pinchart@skynet.be> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
Родитель
233548a2fd
Коммит
291358785c
|
@ -203,5 +203,5 @@ int uvc_status_resume(struct uvc_device *dev)
|
|||
if (dev->int_urb == NULL)
|
||||
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)
|
|||
* is given by the endpoint.
|
||||
*/
|
||||
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;
|
||||
unsigned int npackets, i, j;
|
||||
|
@ -611,14 +611,14 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
|
|||
size = npackets * psize;
|
||||
|
||||
for (i = 0; i < UVC_URBS; ++i) {
|
||||
urb = usb_alloc_urb(npackets, GFP_KERNEL);
|
||||
urb = usb_alloc_urb(npackets, gfp_flags);
|
||||
if (urb == NULL) {
|
||||
uvc_uninit_video(video);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
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) {
|
||||
usb_free_urb(urb);
|
||||
uvc_uninit_video(video);
|
||||
|
@ -652,7 +652,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
|
|||
* given by the endpoint.
|
||||
*/
|
||||
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;
|
||||
unsigned int pipe, i;
|
||||
|
@ -674,14 +674,14 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
|
|||
pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress);
|
||||
|
||||
for (i = 0; i < UVC_URBS; ++i) {
|
||||
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
urb = usb_alloc_urb(0, gfp_flags);
|
||||
if (urb == NULL) {
|
||||
uvc_uninit_video(video);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
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) {
|
||||
usb_free_urb(urb);
|
||||
uvc_uninit_video(video);
|
||||
|
@ -702,7 +702,7 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
|
|||
/*
|
||||
* 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_host_interface *alts;
|
||||
|
@ -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)
|
||||
return ret;
|
||||
|
||||
ret = uvc_init_video_isoc(video, ep);
|
||||
ret = uvc_init_video_isoc(video, ep, gfp_flags);
|
||||
} else {
|
||||
/* Bulk endpoint, proceed to URB initialization. */
|
||||
ep = uvc_find_endpoint(&intf->altsetting[0],
|
||||
|
@ -755,7 +755,7 @@ static int uvc_init_video(struct uvc_video_device *video)
|
|||
if (ep == NULL)
|
||||
return -EIO;
|
||||
|
||||
ret = uvc_init_video_bulk(video, ep);
|
||||
ret = uvc_init_video_bulk(video, ep, gfp_flags);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -763,7 +763,7 @@ static int uvc_init_video(struct uvc_video_device *video)
|
|||
|
||||
/* Submit the URBs. */
|
||||
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 "
|
||||
"(%d).\n", i, ret);
|
||||
uvc_uninit_video(video);
|
||||
|
@ -818,7 +818,7 @@ int uvc_video_resume(struct uvc_video_device *video)
|
|||
if (!uvc_queue_streaming(&video->queue))
|
||||
return 0;
|
||||
|
||||
if ((ret = uvc_init_video(video)) < 0)
|
||||
if ((ret = uvc_init_video(video, GFP_NOIO)) < 0)
|
||||
uvc_queue_enable(&video->queue, 0);
|
||||
|
||||
return ret;
|
||||
|
@ -930,5 +930,5 @@ int uvc_video_enable(struct uvc_video_device *video, int enable)
|
|||
if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
|
||||
return ret;
|
||||
|
||||
return uvc_init_video(video);
|
||||
return uvc_init_video(video, GFP_KERNEL);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче