diff options
Diffstat (limited to 'drivers/media/usb/hdpvr/hdpvr-core.c')
| -rw-r--r-- | drivers/media/usb/hdpvr/hdpvr-core.c | 130 |
1 files changed, 55 insertions, 75 deletions
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index cb694055ba7d..52e05a69c46e 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Hauppauge HD PVR USB driver * * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2008 Janne Grunau (j@jannau.net) * Copyright (C) 2008 John Poet - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * */ #include <linux/kernel.h> @@ -41,13 +37,11 @@ MODULE_PARM_DESC(hdpvr_debug, "enable debugging output"); static uint default_video_input = HDPVR_VIDEO_INPUTS; module_param(default_video_input, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / " - "1=S-Video / 2=Composite"); +MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / 1=S-Video / 2=Composite"); static uint default_audio_input = HDPVR_AUDIO_INPUTS; module_param(default_audio_input, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / " - "1=RCA front / 2=S/PDIF"); +MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / 1=RCA front / 2=S/PDIF"); static bool boost_audio; module_param(boost_audio, bool, S_IRUGO|S_IWUSR); @@ -55,7 +49,7 @@ MODULE_PARM_DESC(boost_audio, "boost the audio signal"); /* table of devices that work with this driver */ -static struct usb_device_id hdpvr_table[] = { +static const struct usb_device_id hdpvr_table[] = { { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) }, { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) }, { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) }, @@ -69,16 +63,13 @@ MODULE_DEVICE_TABLE(usb, hdpvr_table); void hdpvr_delete(struct hdpvr_device *dev) { hdpvr_free_buffers(dev); - - if (dev->video_dev) - video_device_release(dev->video_dev); - usb_put_dev(dev->udev); } static void challenge(u8 *bytes) { - u64 *i64P, tmp64; + __le64 *i64P; + u64 tmp64; uint i, idx; for (idx = 0; idx < 32; ++idx) { @@ -106,10 +97,10 @@ static void challenge(u8 *bytes) for (i = 0; i < 3; i++) bytes[1] *= bytes[6] + 1; for (i = 0; i < 3; i++) { - i64P = (u64 *)bytes; + i64P = (__le64 *)bytes; tmp64 = le64_to_cpup(i64P); - tmp64 <<= bytes[7] & 0x0f; - *i64P += cpu_to_le64(tmp64); + tmp64 = tmp64 + (tmp64 << (bytes[7] & 0x0f)); + *i64P = cpu_to_le64(tmp64); } break; } @@ -123,14 +114,6 @@ static int device_authorization(struct hdpvr_device *dev) int ret, retval = -ENOMEM; char request_type = 0x38, rcv_request = 0x81; char *response; -#ifdef HDPVR_DEBUG - size_t buf_size = 46; - char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL); - if (!print_buf) { - v4l2_err(&dev->v4l2_dev, "Out of memory\n"); - return retval; - } -#endif mutex_lock(&dev->usbc_mutex); ret = usb_control_msg(dev->udev, @@ -146,16 +129,15 @@ static int device_authorization(struct hdpvr_device *dev) } #ifdef HDPVR_DEBUG else { - hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf, - 5*buf_size+1, 0); v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, - "Status request returned, len %d: %s\n", - ret, print_buf); + "Status request returned, len %d: %46ph\n", + ret, dev->usbc_buf); } #endif dev->fw_ver = dev->usbc_buf[1]; + dev->usbc_buf[46] = '\0'; v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n", dev->fw_ver, &dev->usbc_buf[2]); @@ -178,8 +160,7 @@ static int device_authorization(struct hdpvr_device *dev) dev->flags |= HDPVR_FLAG_AC3_CAP; break; default: - v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might" - " not work.\n"); + v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might not work.\n"); if (dev->fw_ver >= HDPVR_FIRMWARE_VERSION_AC3) dev->flags |= HDPVR_FLAG_AC3_CAP; else @@ -188,16 +169,13 @@ static int device_authorization(struct hdpvr_device *dev) response = dev->usbc_buf+38; #ifdef HDPVR_DEBUG - hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n", - print_buf); + v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %8ph\n", + response); #endif challenge(response); #ifdef HDPVR_DEBUG - hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); - v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", - print_buf); - kfree(print_buf); + v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %8ph\n", + response); #endif msleep(100); @@ -289,9 +267,12 @@ static int hdpvr_probe(struct usb_interface *interface, struct hdpvr_device *dev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; +#if IS_ENABLED(CONFIG_I2C) struct i2c_client *client; +#endif size_t buffer_size; int i; + int dev_num; int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ @@ -301,12 +282,15 @@ static int hdpvr_probe(struct usb_interface *interface, goto error; } - dev->workqueue = 0; + /* init video transfer queues first of all */ + /* to prevent oops in hdpvr_delete() on error paths */ + INIT_LIST_HEAD(&dev->free_buff_list); + INIT_LIST_HEAD(&dev->rec_buff_list); /* register v4l2_device early so it can be used for printks */ if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { dev_err(&interface->dev, "v4l2_device_register failed\n"); - goto error; + goto error_free_dev; } mutex_init(&dev->io_mutex); @@ -315,20 +299,12 @@ static int hdpvr_probe(struct usb_interface *interface, dev->usbc_buf = kmalloc(64, GFP_KERNEL); if (!dev->usbc_buf) { v4l2_err(&dev->v4l2_dev, "Out of memory\n"); - goto error; + goto error_v4l2_unregister; } init_waitqueue_head(&dev->wait_buffer); init_waitqueue_head(&dev->wait_data); - dev->workqueue = create_singlethread_workqueue("hdpvr_buffer"); - if (!dev->workqueue) - goto error; - - /* init video transfer queues */ - INIT_LIST_HEAD(&dev->free_buff_list); - INIT_LIST_HEAD(&dev->rec_buff_list); - dev->options = hdpvr_default_options; if (default_video_input < HDPVR_VIDEO_INPUTS) @@ -361,13 +337,13 @@ static int hdpvr_probe(struct usb_interface *interface, } if (!dev->bulk_in_endpointAddr) { v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n"); - goto error; + goto error_put_usb; } /* init the device */ if (hdpvr_device_init(dev)) { v4l2_err(&dev->v4l2_dev, "device init failed\n"); - goto error; + goto error_put_usb; } mutex_lock(&dev->io_mutex); @@ -375,7 +351,7 @@ static int hdpvr_probe(struct usb_interface *interface, mutex_unlock(&dev->io_mutex); v4l2_err(&dev->v4l2_dev, "allocating transfer buffers failed\n"); - goto error; + goto error_put_usb; } mutex_unlock(&dev->io_mutex); @@ -383,48 +359,52 @@ static int hdpvr_probe(struct usb_interface *interface, retval = hdpvr_register_i2c_adapter(dev); if (retval < 0) { v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n"); - goto error; + goto error_free_buffers; } - client = hdpvr_register_ir_rx_i2c(dev); - if (!client) { - v4l2_err(&dev->v4l2_dev, "i2c IR RX device register failed\n"); - retval = -ENODEV; + client = hdpvr_register_ir_i2c(dev); + if (IS_ERR(client)) { + v4l2_err(&dev->v4l2_dev, "i2c IR device register failed\n"); + retval = PTR_ERR(client); goto reg_fail; } +#endif - client = hdpvr_register_ir_tx_i2c(dev); - if (!client) { - v4l2_err(&dev->v4l2_dev, "i2c IR TX device register failed\n"); + dev_num = atomic_inc_return(&dev_nr); + if (dev_num >= HDPVR_MAX) { + v4l2_err(&dev->v4l2_dev, + "max device number reached, device register failed\n"); + atomic_dec(&dev_nr); retval = -ENODEV; goto reg_fail; } -#endif retval = hdpvr_register_videodev(dev, &interface->dev, - video_nr[atomic_inc_return(&dev_nr)]); + video_nr[dev_num]); if (retval < 0) { v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); - goto error; + goto reg_fail; } /* let the user know what node this device is now attached to */ v4l2_info(&dev->v4l2_dev, "device now attached to %s\n", - video_device_node_name(dev->video_dev)); + video_device_node_name(&dev->video_dev)); return 0; reg_fail: #if IS_ENABLED(CONFIG_I2C) i2c_del_adapter(&dev->i2c_adapter); +error_free_buffers: #endif + hdpvr_free_buffers(dev); +error_put_usb: + usb_put_dev(dev->udev); + kfree(dev->usbc_buf); +error_v4l2_unregister: + v4l2_device_unregister(&dev->v4l2_dev); +error_free_dev: + kfree(dev); error: - if (dev) { - /* Destroy single thread */ - if (dev->workqueue) - destroy_workqueue(dev->workqueue); - /* this frees allocated memory */ - hdpvr_delete(dev); - } return retval; } @@ -433,7 +413,7 @@ static void hdpvr_disconnect(struct usb_interface *interface) struct hdpvr_device *dev = to_hdpvr_dev(usb_get_intfdata(interface)); v4l2_info(&dev->v4l2_dev, "device %s disconnected\n", - video_device_node_name(dev->video_dev)); + video_device_node_name(&dev->video_dev)); /* prevent more I/O from starting and stop any ongoing */ mutex_lock(&dev->io_mutex); dev->status = STATUS_DISCONNECTED; @@ -442,14 +422,14 @@ static void hdpvr_disconnect(struct usb_interface *interface) mutex_unlock(&dev->io_mutex); v4l2_device_disconnect(&dev->v4l2_dev); msleep(100); - flush_workqueue(dev->workqueue); + flush_work(&dev->worker); mutex_lock(&dev->io_mutex); hdpvr_cancel_queue(dev); mutex_unlock(&dev->io_mutex); #if IS_ENABLED(CONFIG_I2C) i2c_del_adapter(&dev->i2c_adapter); #endif - video_unregister_device(dev->video_dev); + video_unregister_device(&dev->video_dev); atomic_dec(&dev_nr); } |
