diff options
author | Olivier Grenie <olivier.grenie@dibcom.fr> | 2011-03-24 08:32:26 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-20 08:27:51 -0400 |
commit | ffa5899ce8a6d82e42ae0ca23a10cf92d914045e (patch) | |
tree | e6ac9067873352b991180de05f16db3fd287373f /drivers/media/dvb/dvb-usb | |
parent | b9f7b73c8c107d83a4c04c4f29a2ca96f7e73faf (diff) |
[media] DiB0700: get rid of on-stack dma buffers
This patch removes the on-stack buffers for USB DMA transfers.
This is an alternative version of the patch discussed by Florian here:
http://thread.gmane.org/gmane.linux.kernel/1115695/
Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr>
Signed-off-by: Patrick Boettcher <patrick.boettcher@dibcom.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700.h | 5 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dib0700_core.c | 218 |
2 files changed, 136 insertions, 87 deletions
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index b2a87f2c2c3e..9bd6d51b3b93 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h | |||
@@ -46,8 +46,9 @@ struct dib0700_state { | |||
46 | u8 is_dib7000pc; | 46 | u8 is_dib7000pc; |
47 | u8 fw_use_new_i2c_api; | 47 | u8 fw_use_new_i2c_api; |
48 | u8 disable_streaming_master_mode; | 48 | u8 disable_streaming_master_mode; |
49 | u32 fw_version; | 49 | u32 fw_version; |
50 | u32 nb_packet_buffer_size; | 50 | u32 nb_packet_buffer_size; |
51 | u8 buf[255]; | ||
51 | }; | 52 | }; |
52 | 53 | ||
53 | extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, | 54 | extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index b79af68c54ae..0325825961b9 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
@@ -27,19 +27,25 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |||
27 | int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, | 27 | int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, |
28 | u32 *romversion, u32 *ramversion, u32 *fwtype) | 28 | u32 *romversion, u32 *ramversion, u32 *fwtype) |
29 | { | 29 | { |
30 | u8 b[16]; | 30 | struct dib0700_state *st = d->priv; |
31 | int ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), | 31 | int ret; |
32 | |||
33 | ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), | ||
32 | REQUEST_GET_VERSION, | 34 | REQUEST_GET_VERSION, |
33 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, | 35 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, |
34 | b, sizeof(b), USB_CTRL_GET_TIMEOUT); | 36 | st->buf, 16, USB_CTRL_GET_TIMEOUT); |
35 | if (hwversion != NULL) | 37 | if (hwversion != NULL) |
36 | *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; | 38 | *hwversion = (st->buf[0] << 24) | (st->buf[1] << 16) | |
39 | (st->buf[2] << 8) | st->buf[3]; | ||
37 | if (romversion != NULL) | 40 | if (romversion != NULL) |
38 | *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; | 41 | *romversion = (st->buf[4] << 24) | (st->buf[5] << 16) | |
42 | (st->buf[6] << 8) | st->buf[7]; | ||
39 | if (ramversion != NULL) | 43 | if (ramversion != NULL) |
40 | *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; | 44 | *ramversion = (st->buf[8] << 24) | (st->buf[9] << 16) | |
45 | (st->buf[10] << 8) | st->buf[11]; | ||
41 | if (fwtype != NULL) | 46 | if (fwtype != NULL) |
42 | *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; | 47 | *fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) | |
48 | (st->buf[14] << 8) | st->buf[15]; | ||
43 | return ret; | 49 | return ret; |
44 | } | 50 | } |
45 | 51 | ||
@@ -101,24 +107,31 @@ int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen | |||
101 | 107 | ||
102 | int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val) | 108 | int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val) |
103 | { | 109 | { |
104 | u8 buf[3] = { REQUEST_SET_GPIO, gpio, ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6) }; | 110 | struct dib0700_state *st = d->priv; |
105 | return dib0700_ctrl_wr(d, buf, sizeof(buf)); | 111 | s16 ret; |
112 | |||
113 | st->buf[0] = REQUEST_SET_GPIO; | ||
114 | st->buf[1] = gpio; | ||
115 | st->buf[2] = ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6); | ||
116 | |||
117 | ret = dib0700_ctrl_wr(d, st->buf, 3); | ||
118 | |||
119 | return ret; | ||
106 | } | 120 | } |
107 | 121 | ||
108 | static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets) | 122 | static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets) |
109 | { | 123 | { |
110 | struct dib0700_state *st = d->priv; | 124 | struct dib0700_state *st = d->priv; |
111 | u8 b[3]; | ||
112 | int ret; | 125 | int ret; |
113 | 126 | ||
114 | if (st->fw_version >= 0x10201) { | 127 | if (st->fw_version >= 0x10201) { |
115 | b[0] = REQUEST_SET_USB_XFER_LEN; | 128 | st->buf[0] = REQUEST_SET_USB_XFER_LEN; |
116 | b[1] = (nb_ts_packets >> 8) & 0xff; | 129 | st->buf[1] = (nb_ts_packets >> 8) & 0xff; |
117 | b[2] = nb_ts_packets & 0xff; | 130 | st->buf[2] = nb_ts_packets & 0xff; |
118 | 131 | ||
119 | deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets); | 132 | deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets); |
120 | 133 | ||
121 | ret = dib0700_ctrl_wr(d, b, sizeof(b)); | 134 | ret = dib0700_ctrl_wr(d, st->buf, 3); |
122 | } else { | 135 | } else { |
123 | deb_info("this firmware does not allow to change the USB xfer len\n"); | 136 | deb_info("this firmware does not allow to change the USB xfer len\n"); |
124 | ret = -EIO; | 137 | ret = -EIO; |
@@ -137,11 +150,11 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, | |||
137 | properly support i2c read calls not preceded by a write */ | 150 | properly support i2c read calls not preceded by a write */ |
138 | 151 | ||
139 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 152 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
153 | struct dib0700_state *st = d->priv; | ||
140 | uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */ | 154 | uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */ |
141 | uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */ | 155 | uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */ |
142 | uint8_t en_start = 0; | 156 | uint8_t en_start = 0; |
143 | uint8_t en_stop = 0; | 157 | uint8_t en_stop = 0; |
144 | uint8_t buf[255]; /* TBV: malloc ? */ | ||
145 | int result, i; | 158 | int result, i; |
146 | 159 | ||
147 | /* Ensure nobody else hits the i2c bus while we're sending our | 160 | /* Ensure nobody else hits the i2c bus while we're sending our |
@@ -195,24 +208,24 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, | |||
195 | 208 | ||
196 | } else { | 209 | } else { |
197 | /* Write request */ | 210 | /* Write request */ |
198 | buf[0] = REQUEST_NEW_I2C_WRITE; | 211 | st->buf[0] = REQUEST_NEW_I2C_WRITE; |
199 | buf[1] = msg[i].addr << 1; | 212 | st->buf[1] = msg[i].addr << 1; |
200 | buf[2] = (en_start << 7) | (en_stop << 6) | | 213 | st->buf[2] = (en_start << 7) | (en_stop << 6) | |
201 | (msg[i].len & 0x3F); | 214 | (msg[i].len & 0x3F); |
202 | /* I2C ctrl + FE bus; */ | 215 | /* I2C ctrl + FE bus; */ |
203 | buf[3] = ((gen_mode << 6) & 0xC0) | | 216 | st->buf[3] = ((gen_mode << 6) & 0xC0) | |
204 | ((bus_mode << 4) & 0x30); | 217 | ((bus_mode << 4) & 0x30); |
205 | /* The Actual i2c payload */ | 218 | /* The Actual i2c payload */ |
206 | memcpy(&buf[4], msg[i].buf, msg[i].len); | 219 | memcpy(&st->buf[4], msg[i].buf, msg[i].len); |
207 | 220 | ||
208 | deb_data(">>> "); | 221 | deb_data(">>> "); |
209 | debug_dump(buf, msg[i].len + 4, deb_data); | 222 | debug_dump(st->buf, msg[i].len + 4, deb_data); |
210 | 223 | ||
211 | result = usb_control_msg(d->udev, | 224 | result = usb_control_msg(d->udev, |
212 | usb_sndctrlpipe(d->udev, 0), | 225 | usb_sndctrlpipe(d->udev, 0), |
213 | REQUEST_NEW_I2C_WRITE, | 226 | REQUEST_NEW_I2C_WRITE, |
214 | USB_TYPE_VENDOR | USB_DIR_OUT, | 227 | USB_TYPE_VENDOR | USB_DIR_OUT, |
215 | 0, 0, buf, msg[i].len + 4, | 228 | 0, 0, st->buf, msg[i].len + 4, |
216 | USB_CTRL_GET_TIMEOUT); | 229 | USB_CTRL_GET_TIMEOUT); |
217 | if (result < 0) { | 230 | if (result < 0) { |
218 | deb_info("i2c write error (status = %d)\n", result); | 231 | deb_info("i2c write error (status = %d)\n", result); |
@@ -231,27 +244,29 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, | |||
231 | struct i2c_msg *msg, int num) | 244 | struct i2c_msg *msg, int num) |
232 | { | 245 | { |
233 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 246 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
247 | struct dib0700_state *st = d->priv; | ||
234 | int i,len; | 248 | int i,len; |
235 | u8 buf[255]; | ||
236 | 249 | ||
237 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 250 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
238 | return -EAGAIN; | 251 | return -EAGAIN; |
239 | 252 | ||
240 | for (i = 0; i < num; i++) { | 253 | for (i = 0; i < num; i++) { |
241 | /* fill in the address */ | 254 | /* fill in the address */ |
242 | buf[1] = msg[i].addr << 1; | 255 | st->buf[1] = msg[i].addr << 1; |
243 | /* fill the buffer */ | 256 | /* fill the buffer */ |
244 | memcpy(&buf[2], msg[i].buf, msg[i].len); | 257 | memcpy(&st->buf[2], msg[i].buf, msg[i].len); |
245 | 258 | ||
246 | /* write/read request */ | 259 | /* write/read request */ |
247 | if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { | 260 | if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { |
248 | buf[0] = REQUEST_I2C_READ; | 261 | st->buf[0] = REQUEST_I2C_READ; |
249 | buf[1] |= 1; | 262 | st->buf[1] |= 1; |
250 | 263 | ||
251 | /* special thing in the current firmware: when length is zero the read-failed */ | 264 | /* special thing in the current firmware: when length is zero the read-failed */ |
252 | if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) { | 265 | len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2, |
266 | msg[i+1].buf, msg[i+1].len); | ||
267 | if (len <= 0) { | ||
253 | deb_info("I2C read failed on address 0x%02x\n", | 268 | deb_info("I2C read failed on address 0x%02x\n", |
254 | msg[i].addr); | 269 | msg[i].addr); |
255 | break; | 270 | break; |
256 | } | 271 | } |
257 | 272 | ||
@@ -259,13 +274,13 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, | |||
259 | 274 | ||
260 | i++; | 275 | i++; |
261 | } else { | 276 | } else { |
262 | buf[0] = REQUEST_I2C_WRITE; | 277 | st->buf[0] = REQUEST_I2C_WRITE; |
263 | if (dib0700_ctrl_wr(d, buf, msg[i].len + 2) < 0) | 278 | if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0) |
264 | break; | 279 | break; |
265 | } | 280 | } |
266 | } | 281 | } |
267 | |||
268 | mutex_unlock(&d->i2c_mutex); | 282 | mutex_unlock(&d->i2c_mutex); |
283 | |||
269 | return i; | 284 | return i; |
270 | } | 285 | } |
271 | 286 | ||
@@ -297,15 +312,23 @@ struct i2c_algorithm dib0700_i2c_algo = { | |||
297 | int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, | 312 | int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, |
298 | struct dvb_usb_device_description **desc, int *cold) | 313 | struct dvb_usb_device_description **desc, int *cold) |
299 | { | 314 | { |
300 | u8 b[16]; | 315 | s16 ret; |
301 | s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), | 316 | u8 *b; |
317 | |||
318 | b = kmalloc(16, GFP_KERNEL); | ||
319 | if (!b) | ||
320 | return -ENOMEM; | ||
321 | |||
322 | |||
323 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
302 | REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT); | 324 | REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT); |
303 | 325 | ||
304 | deb_info("FW GET_VERSION length: %d\n",ret); | 326 | deb_info("FW GET_VERSION length: %d\n",ret); |
305 | 327 | ||
306 | *cold = ret <= 0; | 328 | *cold = ret <= 0; |
307 | |||
308 | deb_info("cold: %d\n", *cold); | 329 | deb_info("cold: %d\n", *cold); |
330 | |||
331 | kfree(b); | ||
309 | return 0; | 332 | return 0; |
310 | } | 333 | } |
311 | 334 | ||
@@ -313,43 +336,50 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, | |||
313 | u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv, | 336 | u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv, |
314 | u16 pll_loopdiv, u16 free_div, u16 dsuScaler) | 337 | u16 pll_loopdiv, u16 free_div, u16 dsuScaler) |
315 | { | 338 | { |
316 | u8 b[10]; | 339 | struct dib0700_state *st = d->priv; |
317 | b[0] = REQUEST_SET_CLOCK; | 340 | s16 ret; |
318 | b[1] = (en_pll << 7) | (pll_src << 6) | (pll_range << 5) | (clock_gpio3 << 4); | 341 | |
319 | b[2] = (pll_prediv >> 8) & 0xff; // MSB | 342 | st->buf[0] = REQUEST_SET_CLOCK; |
320 | b[3] = pll_prediv & 0xff; // LSB | 343 | st->buf[1] = (en_pll << 7) | (pll_src << 6) | |
321 | b[4] = (pll_loopdiv >> 8) & 0xff; // MSB | 344 | (pll_range << 5) | (clock_gpio3 << 4); |
322 | b[5] = pll_loopdiv & 0xff; // LSB | 345 | st->buf[2] = (pll_prediv >> 8) & 0xff; /* MSB */ |
323 | b[6] = (free_div >> 8) & 0xff; // MSB | 346 | st->buf[3] = pll_prediv & 0xff; /* LSB */ |
324 | b[7] = free_div & 0xff; // LSB | 347 | st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */ |
325 | b[8] = (dsuScaler >> 8) & 0xff; // MSB | 348 | st->buf[5] = pll_loopdiv & 0xff; /* LSB */ |
326 | b[9] = dsuScaler & 0xff; // LSB | 349 | st->buf[6] = (free_div >> 8) & 0xff; /* MSB */ |
327 | 350 | st->buf[7] = free_div & 0xff; /* LSB */ | |
328 | return dib0700_ctrl_wr(d, b, 10); | 351 | st->buf[8] = (dsuScaler >> 8) & 0xff; /* MSB */ |
352 | st->buf[9] = dsuScaler & 0xff; /* LSB */ | ||
353 | |||
354 | ret = dib0700_ctrl_wr(d, st->buf, 10); | ||
355 | |||
356 | return ret; | ||
329 | } | 357 | } |
330 | 358 | ||
331 | int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) | 359 | int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) |
332 | { | 360 | { |
361 | struct dib0700_state *st = d->priv; | ||
333 | u16 divider; | 362 | u16 divider; |
334 | u8 b[8]; | ||
335 | 363 | ||
336 | if (scl_kHz == 0) | 364 | if (scl_kHz == 0) |
337 | return -EINVAL; | 365 | return -EINVAL; |
338 | 366 | ||
339 | b[0] = REQUEST_SET_I2C_PARAM; | 367 | st->buf[0] = REQUEST_SET_I2C_PARAM; |
340 | divider = (u16) (30000 / scl_kHz); | 368 | divider = (u16) (30000 / scl_kHz); |
341 | b[2] = (u8) (divider >> 8); | 369 | st->buf[1] = 0; |
342 | b[3] = (u8) (divider & 0xff); | 370 | st->buf[2] = (u8) (divider >> 8); |
371 | st->buf[3] = (u8) (divider & 0xff); | ||
343 | divider = (u16) (72000 / scl_kHz); | 372 | divider = (u16) (72000 / scl_kHz); |
344 | b[4] = (u8) (divider >> 8); | 373 | st->buf[4] = (u8) (divider >> 8); |
345 | b[5] = (u8) (divider & 0xff); | 374 | st->buf[5] = (u8) (divider & 0xff); |
346 | divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */ | 375 | divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */ |
347 | b[6] = (u8) (divider >> 8); | 376 | st->buf[6] = (u8) (divider >> 8); |
348 | b[7] = (u8) (divider & 0xff); | 377 | st->buf[7] = (u8) (divider & 0xff); |
349 | 378 | ||
350 | deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", | 379 | deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", |
351 | (b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz); | 380 | (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) | |
352 | return dib0700_ctrl_wr(d, b, 8); | 381 | st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz); |
382 | return dib0700_ctrl_wr(d, st->buf, 8); | ||
353 | } | 383 | } |
354 | 384 | ||
355 | 385 | ||
@@ -364,32 +394,45 @@ int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) | |||
364 | 394 | ||
365 | static int dib0700_jumpram(struct usb_device *udev, u32 address) | 395 | static int dib0700_jumpram(struct usb_device *udev, u32 address) |
366 | { | 396 | { |
367 | int ret, actlen; | 397 | int ret = 0, actlen; |
368 | u8 buf[8] = { REQUEST_JUMPRAM, 0, 0, 0, | 398 | u8 *buf; |
369 | (address >> 24) & 0xff, | 399 | |
370 | (address >> 16) & 0xff, | 400 | buf = kmalloc(8, GFP_KERNEL); |
371 | (address >> 8) & 0xff, | 401 | if (!buf) |
372 | address & 0xff }; | 402 | return -ENOMEM; |
403 | buf[0] = REQUEST_JUMPRAM; | ||
404 | buf[1] = 0; | ||
405 | buf[2] = 0; | ||
406 | buf[3] = 0; | ||
407 | buf[4] = (address >> 24) & 0xff; | ||
408 | buf[5] = (address >> 16) & 0xff; | ||
409 | buf[6] = (address >> 8) & 0xff; | ||
410 | buf[7] = address & 0xff; | ||
373 | 411 | ||
374 | if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) { | 412 | if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) { |
375 | deb_fw("jumpram to 0x%x failed\n",address); | 413 | deb_fw("jumpram to 0x%x failed\n",address); |
376 | return ret; | 414 | goto out; |
377 | } | 415 | } |
378 | if (actlen != 8) { | 416 | if (actlen != 8) { |
379 | deb_fw("jumpram to 0x%x failed\n",address); | 417 | deb_fw("jumpram to 0x%x failed\n",address); |
380 | return -EIO; | 418 | ret = -EIO; |
419 | goto out; | ||
381 | } | 420 | } |
382 | return 0; | 421 | out: |
422 | kfree(buf); | ||
423 | return ret; | ||
383 | } | 424 | } |
384 | 425 | ||
385 | int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw) | 426 | int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw) |
386 | { | 427 | { |
387 | struct hexline hx; | 428 | struct hexline hx; |
388 | int pos = 0, ret, act_len, i, adap_num; | 429 | int pos = 0, ret, act_len, i, adap_num; |
389 | u8 b[16]; | 430 | u8 *buf; |
390 | u32 fw_version; | 431 | u32 fw_version; |
391 | 432 | ||
392 | u8 buf[260]; | 433 | buf = kmalloc(260, GFP_KERNEL); |
434 | if (!buf) | ||
435 | return -ENOMEM; | ||
393 | 436 | ||
394 | while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) { | 437 | while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) { |
395 | deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n", | 438 | deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n", |
@@ -411,7 +454,7 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw | |||
411 | 454 | ||
412 | if (ret < 0) { | 455 | if (ret < 0) { |
413 | err("firmware download failed at %d with %d",pos,ret); | 456 | err("firmware download failed at %d with %d",pos,ret); |
414 | return ret; | 457 | goto out; |
415 | } | 458 | } |
416 | } | 459 | } |
417 | 460 | ||
@@ -432,8 +475,8 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw | |||
432 | usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | 475 | usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
433 | REQUEST_GET_VERSION, | 476 | REQUEST_GET_VERSION, |
434 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, | 477 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, |
435 | b, sizeof(b), USB_CTRL_GET_TIMEOUT); | 478 | buf, 16, USB_CTRL_GET_TIMEOUT); |
436 | fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; | 479 | fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11]; |
437 | 480 | ||
438 | /* set the buffer size - DVB-USB is allocating URB buffers | 481 | /* set the buffer size - DVB-USB is allocating URB buffers |
439 | * only after the firwmare download was successful */ | 482 | * only after the firwmare download was successful */ |
@@ -451,14 +494,14 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw | |||
451 | } | 494 | } |
452 | } | 495 | } |
453 | } | 496 | } |
454 | 497 | out: | |
498 | kfree(buf); | ||
455 | return ret; | 499 | return ret; |
456 | } | 500 | } |
457 | 501 | ||
458 | int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | 502 | int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) |
459 | { | 503 | { |
460 | struct dib0700_state *st = adap->dev->priv; | 504 | struct dib0700_state *st = adap->dev->priv; |
461 | u8 b[4]; | ||
462 | int ret; | 505 | int ret; |
463 | 506 | ||
464 | if ((onoff != 0) && (st->fw_version >= 0x10201)) { | 507 | if ((onoff != 0) && (st->fw_version >= 0x10201)) { |
@@ -472,15 +515,17 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | |||
472 | } | 515 | } |
473 | } | 516 | } |
474 | 517 | ||
475 | b[0] = REQUEST_ENABLE_VIDEO; | 518 | st->buf[0] = REQUEST_ENABLE_VIDEO; |
476 | b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ | 519 | /* this bit gives a kind of command, |
520 | * rather than enabling something or not */ | ||
521 | st->buf[1] = (onoff << 4) | 0x00; | ||
477 | 522 | ||
478 | if (st->disable_streaming_master_mode == 1) | 523 | if (st->disable_streaming_master_mode == 1) |
479 | b[2] = 0x00; | 524 | st->buf[2] = 0x00; |
480 | else | 525 | else |
481 | b[2] = 0x01 << 4; /* Master mode */ | 526 | st->buf[2] = 0x01 << 4; /* Master mode */ |
482 | 527 | ||
483 | b[3] = 0x00; | 528 | st->buf[3] = 0x00; |
484 | 529 | ||
485 | deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); | 530 | deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); |
486 | 531 | ||
@@ -499,20 +544,23 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | |||
499 | st->channel_state |= 1 << (3-adap->stream.props.endpoint); | 544 | st->channel_state |= 1 << (3-adap->stream.props.endpoint); |
500 | } | 545 | } |
501 | 546 | ||
502 | b[2] |= st->channel_state; | 547 | st->buf[2] |= st->channel_state; |
503 | 548 | ||
504 | deb_info("data for streaming: %x %x\n", b[1], b[2]); | 549 | deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]); |
505 | 550 | ||
506 | return dib0700_ctrl_wr(adap->dev, b, 4); | 551 | return dib0700_ctrl_wr(adap->dev, st->buf, 4); |
507 | } | 552 | } |
508 | 553 | ||
509 | int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type) | 554 | int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type) |
510 | { | 555 | { |
511 | struct dvb_usb_device *d = rc->priv; | 556 | struct dvb_usb_device *d = rc->priv; |
512 | struct dib0700_state *st = d->priv; | 557 | struct dib0700_state *st = d->priv; |
513 | u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 }; | ||
514 | int new_proto, ret; | 558 | int new_proto, ret; |
515 | 559 | ||
560 | st->buf[0] = REQUEST_SET_RC; | ||
561 | st->buf[1] = 0; | ||
562 | st->buf[2] = 0; | ||
563 | |||
516 | /* Set the IR mode */ | 564 | /* Set the IR mode */ |
517 | if (rc_type == RC_TYPE_RC5) | 565 | if (rc_type == RC_TYPE_RC5) |
518 | new_proto = 1; | 566 | new_proto = 1; |
@@ -526,9 +574,9 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type) | |||
526 | } else | 574 | } else |
527 | return -EINVAL; | 575 | return -EINVAL; |
528 | 576 | ||
529 | rc_setup[1] = new_proto; | 577 | st->buf[1] = new_proto; |
530 | 578 | ||
531 | ret = dib0700_ctrl_wr(d, rc_setup, sizeof(rc_setup)); | 579 | ret = dib0700_ctrl_wr(d, st->buf, 3); |
532 | if (ret < 0) { | 580 | if (ret < 0) { |
533 | err("ir protocol setup failed"); | 581 | err("ir protocol setup failed"); |
534 | return ret; | 582 | return ret; |