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 5d837c16ee22..15e2b525310d 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; |