aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-11-18 12:51:08 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-11-20 14:19:31 -0500
commitc4a98793a63c423c9e1af51822325969e23c16d4 (patch)
tree9711b371b6eb6ba1ffa9a8201f3528308526cd00 /drivers/media/video/em28xx
parent625ff1679456d8adb9af0c980394ea3954e727a8 (diff)
V4L/DVB (9646): em28xx: avoid allocating/dealocating memory on every control urb
Before this patch, every register setup on em28xx were dynamically allocating a temporary buffer for control URB's to be handled. To avoid this ping-pong, use, instead a pre-allocated buffer. Also, be sure that read control URB's also use the buffer, instead of relying on a stack buffer. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c48
-rw-r--r--drivers/media/video/em28xx/em28xx.h5
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);