Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Olivier Grenie and committed by
Mauro Carvalho Chehab
ffa5899c b9f7b73c

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