diff options
| -rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 48 | ||||
| -rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 5 |
2 files changed, 31 insertions, 22 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 038da614a734..9551b8ab8c44 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
| @@ -69,19 +69,29 @@ 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 | ||
| 76 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 79 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
| 77 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 80 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 78 | 0x0000, reg, buf, len, HZ); | 81 | 0x0000, reg, dev->urb_buf, len, HZ); |
| 82 | if (ret < 0) { | ||
| 83 | if (reg_debug) | ||
| 84 | printk(" failed!\n"); | ||
| 85 | return ret; | ||
| 86 | } | ||
| 87 | |||
| 88 | if (len) | ||
| 89 | memcpy(buf, dev->urb_buf, len); | ||
| 79 | 90 | ||
| 80 | if (reg_debug) { | 91 | if (reg_debug) { |
| 81 | printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); | 92 | printk("%02x values: ", ret); |
| 82 | for (byte = 0; byte < len; byte++) | 93 | for (byte = 0; byte < len; byte++) |
| 83 | printk(" %02x", (unsigned char)buf[byte]); | 94 | printk(" %02x", (unsigned char)buf[byte]); |
| 84 | |||
| 85 | printk("\n"); | 95 | printk("\n"); |
| 86 | } | 96 | } |
| 87 | 97 | ||
| @@ -104,14 +114,16 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) | |||
| 104 | 114 | ||
| 105 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 115 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
| 106 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 116 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 107 | 0x0000, reg, &val, 1, HZ); | 117 | 0x0000, reg, dev->urb_buf, 1, HZ); |
| 118 | if (ret < 0) { | ||
| 119 | printk(" failed!\n"); | ||
| 120 | return ret; | ||
| 121 | } | ||
| 108 | 122 | ||
| 109 | if (reg_debug) | 123 | val = dev->urb_buf[0]; |
| 110 | printk(ret < 0 ? " failed!\n" : | ||
| 111 | "%02x\n", (unsigned char) val); | ||
| 112 | 124 | ||
| 113 | if (ret < 0) | 125 | if (reg_debug) |
| 114 | return ret; | 126 | printk("%02x\n", (unsigned char) val); |
| 115 | 127 | ||
| 116 | return val; | 128 | return val; |
| 117 | } | 129 | } |
| @@ -130,19 +142,13 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
| 130 | { | 142 | { |
| 131 | int ret; | 143 | int ret; |
| 132 | 144 | ||
| 133 | /*usb_control_msg seems to expect a kmalloced buffer */ | ||
| 134 | unsigned char *bufs; | ||
| 135 | |||
| 136 | if (dev->state & DEV_DISCONNECTED) | 145 | if (dev->state & DEV_DISCONNECTED) |
| 137 | return -ENODEV; | 146 | return -ENODEV; |
| 138 | 147 | ||
| 139 | if (len < 1) | 148 | if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) |
| 140 | return -EINVAL; | 149 | return -EINVAL; |
| 141 | 150 | ||
| 142 | bufs = kmalloc(len, GFP_KERNEL); | ||
| 143 | |||
| 144 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); | 151 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); |
| 145 | |||
| 146 | if (reg_debug) { | 152 | if (reg_debug) { |
| 147 | int i; | 153 | int i; |
| 148 | for (i = 0; i < len; ++i) | 154 | for (i = 0; i < len; ++i) |
| @@ -150,16 +156,14 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
| 150 | printk("\n"); | 156 | printk("\n"); |
| 151 | } | 157 | } |
| 152 | 158 | ||
| 153 | if (!bufs) | 159 | memcpy(dev->urb_buf, buf, len); |
| 154 | return -ENOMEM; | ||
| 155 | memcpy(bufs, buf, len); | ||
| 156 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, | 160 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, |
| 157 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 161 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 158 | 0x0000, reg, bufs, len, HZ); | 162 | 0x0000, reg, dev->urb_buf, len, HZ); |
| 163 | |||
| 159 | if (dev->wait_after_write) | 164 | if (dev->wait_after_write) |
| 160 | msleep(dev->wait_after_write); | 165 | msleep(dev->wait_after_write); |
| 161 | 166 | ||
| 162 | kfree(bufs); | ||
| 163 | return ret; | 167 | return ret; |
| 164 | } | 168 | } |
| 165 | 169 | ||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 82781178e0a3..1adf3d9d9bff 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
| @@ -102,6 +102,9 @@ | |||
| 102 | #define EM28XX_MIN_BUF 4 | 102 | #define EM28XX_MIN_BUF 4 |
| 103 | #define EM28XX_DEF_BUF 8 | 103 | #define EM28XX_DEF_BUF 8 |
| 104 | 104 | ||
| 105 | /*Limits the max URB message size */ | ||
| 106 | #define URB_MAX_CTRL_SIZE 80 | ||
| 107 | |||
| 105 | /* Params for validated field */ | 108 | /* Params for validated field */ |
| 106 | #define EM28XX_BOARD_NOT_VALIDATED 1 | 109 | #define EM28XX_BOARD_NOT_VALIDATED 1 |
| 107 | #define EM28XX_BOARD_VALIDATED 0 | 110 | #define EM28XX_BOARD_VALIDATED 0 |
| @@ -451,6 +454,8 @@ struct em28xx { | |||
| 451 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ | 454 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ |
| 452 | struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ | 455 | struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ |
| 453 | char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ | 456 | char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ |
| 457 | char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ | ||
| 458 | |||
| 454 | /* helper funcs that call usb_control_msg */ | 459 | /* helper funcs that call usb_control_msg */ |
| 455 | int (*em28xx_write_regs) (struct em28xx *dev, u16 reg, | 460 | int (*em28xx_write_regs) (struct em28xx *dev, u16 reg, |
| 456 | char *buf, int len); | 461 | char *buf, int len); |
