diff options
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-core.c')
| -rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 5d837c16ee2..15e2b525310 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
| @@ -69,19 +69,33 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
| 69 | int ret, byte; | 69 | int ret, byte; |
| 70 | 70 | ||
| 71 | if (dev->state & DEV_DISCONNECTED) | 71 | if (dev->state & DEV_DISCONNECTED) |
| 72 | return(-ENODEV); | 72 | return -ENODEV; |
| 73 | |||
| 74 | if (len > URB_MAX_CTRL_SIZE) | ||
| 75 | return -EINVAL; | ||
| 73 | 76 | ||
| 74 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); | 77 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); |
| 75 | 78 | ||
| 79 | mutex_lock(&dev->ctrl_urb_lock); | ||
| 76 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 80 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
| 77 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 81 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 78 | 0x0000, reg, buf, len, HZ); | 82 | 0x0000, reg, dev->urb_buf, len, HZ); |
| 83 | if (ret < 0) { | ||
| 84 | if (reg_debug) | ||
| 85 | printk(" failed!\n"); | ||
| 86 | mutex_unlock(&dev->ctrl_urb_lock); | ||
| 87 | return ret; | ||
| 88 | } | ||
| 89 | |||
| 90 | if (len) | ||
| 91 | memcpy(buf, dev->urb_buf, len); | ||
| 92 | |||
| 93 | mutex_unlock(&dev->ctrl_urb_lock); | ||
| 79 | 94 | ||
| 80 | if (reg_debug) { | 95 | if (reg_debug) { |
| 81 | printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); | 96 | printk("%02x values: ", ret); |
| 82 | for (byte = 0; byte < len; byte++) | 97 | for (byte = 0; byte < len; byte++) |
| 83 | printk(" %02x", (unsigned char)buf[byte]); | 98 | printk(" %02x", (unsigned char)buf[byte]); |
| 84 | |||
| 85 | printk("\n"); | 99 | printk("\n"); |
| 86 | } | 100 | } |
| 87 | 101 | ||
| @@ -102,16 +116,20 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) | |||
| 102 | 116 | ||
| 103 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); | 117 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); |
| 104 | 118 | ||
| 119 | mutex_lock(&dev->ctrl_urb_lock); | ||
| 105 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 120 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
| 106 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 121 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 107 | 0x0000, reg, &val, 1, HZ); | 122 | 0x0000, reg, dev->urb_buf, 1, HZ); |
| 108 | 123 | val = dev->urb_buf[0]; | |
| 109 | if (reg_debug) | 124 | mutex_unlock(&dev->ctrl_urb_lock); |
| 110 | printk(ret < 0 ? " failed!\n" : | ||
| 111 | "%02x\n", (unsigned char) val); | ||
| 112 | 125 | ||
| 113 | if (ret < 0) | 126 | if (ret < 0) { |
| 127 | printk(" failed!\n"); | ||
| 114 | return ret; | 128 | return ret; |
| 129 | } | ||
| 130 | |||
| 131 | if (reg_debug) | ||
| 132 | printk("%02x\n", (unsigned char) val); | ||
| 115 | 133 | ||
| 116 | return val; | 134 | return val; |
| 117 | } | 135 | } |
| @@ -130,19 +148,13 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
| 130 | { | 148 | { |
| 131 | int ret; | 149 | int ret; |
| 132 | 150 | ||
| 133 | /*usb_control_msg seems to expect a kmalloced buffer */ | ||
| 134 | unsigned char *bufs; | ||
| 135 | |||
| 136 | if (dev->state & DEV_DISCONNECTED) | 151 | if (dev->state & DEV_DISCONNECTED) |
| 137 | return -ENODEV; | 152 | return -ENODEV; |
| 138 | 153 | ||
| 139 | if (len < 1) | 154 | if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) |
| 140 | return -EINVAL; | 155 | return -EINVAL; |
| 141 | 156 | ||
| 142 | bufs = kmalloc(len, GFP_KERNEL); | ||
| 143 | |||
| 144 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); | 157 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); |
| 145 | |||
| 146 | if (reg_debug) { | 158 | if (reg_debug) { |
| 147 | int i; | 159 | int i; |
| 148 | for (i = 0; i < len; ++i) | 160 | for (i = 0; i < len; ++i) |
| @@ -150,16 +162,16 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
| 150 | printk("\n"); | 162 | printk("\n"); |
| 151 | } | 163 | } |
| 152 | 164 | ||
| 153 | if (!bufs) | 165 | mutex_lock(&dev->ctrl_urb_lock); |
| 154 | return -ENOMEM; | 166 | memcpy(dev->urb_buf, buf, len); |
| 155 | memcpy(bufs, buf, len); | ||
| 156 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, | 167 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, |
| 157 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 168 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 158 | 0x0000, reg, bufs, len, HZ); | 169 | 0x0000, reg, dev->urb_buf, len, HZ); |
| 170 | mutex_unlock(&dev->ctrl_urb_lock); | ||
| 171 | |||
| 159 | if (dev->wait_after_write) | 172 | if (dev->wait_after_write) |
| 160 | msleep(dev->wait_after_write); | 173 | msleep(dev->wait_after_write); |
| 161 | 174 | ||
| 162 | kfree(bufs); | ||
| 163 | return ret; | 175 | return ret; |
| 164 | } | 176 | } |
| 165 | 177 | ||
| @@ -270,6 +282,8 @@ static int em28xx_set_audio_source(struct em28xx *dev) | |||
| 270 | break; | 282 | break; |
| 271 | case EM28XX_AMUX_LINE_IN: | 283 | case EM28XX_AMUX_LINE_IN: |
| 272 | input = EM28XX_AUDIO_SRC_LINE; | 284 | input = EM28XX_AUDIO_SRC_LINE; |
| 285 | video = disable; | ||
| 286 | line = enable; | ||
| 273 | break; | 287 | break; |
| 274 | case EM28XX_AMUX_AC97_VIDEO: | 288 | case EM28XX_AMUX_AC97_VIDEO: |
| 275 | input = EM28XX_AUDIO_SRC_LINE; | 289 | input = EM28XX_AUDIO_SRC_LINE; |
