mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
UPSTREAM: media: uvcvideo: Abstract streaming object lifetime
The streaming object is a key part of handling the UVC device. Although
not critical, we are currently missing a call to destroy the mutex on
clean up paths, and we are due to extend the objects complexity in the
near future.
Facilitate easy management of a stream object by creating a pair of
functions to handle creating and destroying the allocation. The new
uvc_stream_delete() function also performs the missing mutex_destroy()
operation.
Previously a failed streaming object allocation would cause
uvc_parse_streaming() to return -EINVAL, which is inappropriate. If the
constructor failes, we will instead return -ENOMEM.
While we're here, fix the trivial spelling error in the function banner
of uvc_delete().
Change-Id: I695d511a6e20b908f5f49da5cdd0833ee3641b92
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: Tao Huang <huangtao@rock-chips.com>
(cherry picked from commit ece41454c6)
This commit is contained in:
committed by
Tao Huang
parent
b17c9d8251
commit
e58f39f37d
@@ -391,6 +391,39 @@ static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Streaming Object Management
|
||||
*/
|
||||
|
||||
static void uvc_stream_delete(struct uvc_streaming *stream)
|
||||
{
|
||||
mutex_destroy(&stream->mutex);
|
||||
|
||||
usb_put_intf(stream->intf);
|
||||
|
||||
kfree(stream->format);
|
||||
kfree(stream->header.bmaControls);
|
||||
kfree(stream);
|
||||
}
|
||||
|
||||
static struct uvc_streaming *uvc_stream_new(struct uvc_device *dev,
|
||||
struct usb_interface *intf)
|
||||
{
|
||||
struct uvc_streaming *stream;
|
||||
|
||||
stream = kzalloc(sizeof(*stream), GFP_KERNEL);
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
|
||||
mutex_init(&stream->mutex);
|
||||
|
||||
stream->dev = dev;
|
||||
stream->intf = usb_get_intf(intf);
|
||||
stream->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Descriptors parsing
|
||||
*/
|
||||
@@ -683,17 +716,12 @@ static int uvc_parse_streaming(struct uvc_device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
streaming = kzalloc(sizeof(*streaming), GFP_KERNEL);
|
||||
streaming = uvc_stream_new(dev, intf);
|
||||
if (streaming == NULL) {
|
||||
usb_driver_release_interface(&uvc_driver.driver, intf);
|
||||
return -EINVAL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&streaming->mutex);
|
||||
streaming->dev = dev;
|
||||
streaming->intf = usb_get_intf(intf);
|
||||
streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
|
||||
|
||||
/* The Pico iMage webcam has its class-specific interface descriptors
|
||||
* after the endpoint descriptors.
|
||||
*/
|
||||
@@ -900,10 +928,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
|
||||
|
||||
error:
|
||||
usb_driver_release_interface(&uvc_driver.driver, intf);
|
||||
usb_put_intf(intf);
|
||||
kfree(streaming->format);
|
||||
kfree(streaming->header.bmaControls);
|
||||
kfree(streaming);
|
||||
uvc_stream_delete(streaming);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1819,7 +1844,7 @@ static int uvc_scan_device(struct uvc_device *dev)
|
||||
* is released.
|
||||
*
|
||||
* As this function is called after or during disconnect(), all URBs have
|
||||
* already been canceled by the USB core. There is no need to kill the
|
||||
* already been cancelled by the USB core. There is no need to kill the
|
||||
* interrupt URB manually.
|
||||
*/
|
||||
static void uvc_delete(struct kref *kref)
|
||||
@@ -1857,10 +1882,7 @@ static void uvc_delete(struct kref *kref)
|
||||
streaming = list_entry(p, struct uvc_streaming, list);
|
||||
usb_driver_release_interface(&uvc_driver.driver,
|
||||
streaming->intf);
|
||||
usb_put_intf(streaming->intf);
|
||||
kfree(streaming->format);
|
||||
kfree(streaming->header.bmaControls);
|
||||
kfree(streaming);
|
||||
uvc_stream_delete(streaming);
|
||||
}
|
||||
|
||||
kfree(dev);
|
||||
|
||||
Reference in New Issue
Block a user