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

[media] cxusb: don't do DMA on stack

The USB control messages require DMA to work. We cannot pass
a stack-allocated buffer, as it is not warranted that the
stack would be into a DMA enabled area.

Reviewed-by: Patrick Boettcher <patrick.boettcher@posteo.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

+41 -27
+35 -27
drivers/media/usb/dvb-usb/cxusb.c
··· 45 45 #include "si2168.h" 46 46 #include "si2157.h" 47 47 48 - /* Max transfer size done by I2C transfer functions */ 49 - #define MAX_XFER_SIZE 80 50 - 51 48 /* debug */ 52 49 static int dvb_usb_cxusb_debug; 53 50 module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); ··· 58 61 static int cxusb_ctrl_msg(struct dvb_usb_device *d, 59 62 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) 60 63 { 61 - int wo = (rbuf == NULL || rlen == 0); /* write-only */ 62 - u8 sndbuf[MAX_XFER_SIZE]; 64 + struct cxusb_state *st = d->priv; 65 + int ret, wo; 63 66 64 - if (1 + wlen > sizeof(sndbuf)) { 65 - warn("i2c wr: len=%d is too big!\n", 66 - wlen); 67 + if (1 + wlen > MAX_XFER_SIZE) { 68 + warn("i2c wr: len=%d is too big!\n", wlen); 67 69 return -EOPNOTSUPP; 68 70 } 69 71 70 - memset(sndbuf, 0, 1+wlen); 72 + wo = (rbuf == NULL || rlen == 0); /* write-only */ 71 73 72 - sndbuf[0] = cmd; 73 - memcpy(&sndbuf[1], wbuf, wlen); 74 + mutex_lock(&st->data_mutex); 75 + st->data[0] = cmd; 76 + memcpy(&st->data[1], wbuf, wlen); 74 77 if (wo) 75 - return dvb_usb_generic_write(d, sndbuf, 1+wlen); 78 + ret = dvb_usb_generic_write(d, st->data, 1 + wlen); 76 79 else 77 - return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0); 80 + ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, 81 + rbuf, rlen, 0); 82 + 83 + mutex_unlock(&st->data_mutex); 84 + return ret; 78 85 } 79 86 80 87 /* GPIO */ ··· 1461 1460 static int cxusb_probe(struct usb_interface *intf, 1462 1461 const struct usb_device_id *id) 1463 1462 { 1463 + struct dvb_usb_device *d; 1464 + struct cxusb_state *st; 1465 + 1464 1466 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties, 1465 - THIS_MODULE, NULL, adapter_nr) || 1467 + THIS_MODULE, &d, adapter_nr) || 1466 1468 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties, 1467 - THIS_MODULE, NULL, adapter_nr) || 1469 + THIS_MODULE, &d, adapter_nr) || 1468 1470 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties, 1469 - THIS_MODULE, NULL, adapter_nr) || 1471 + THIS_MODULE, &d, adapter_nr) || 1470 1472 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties, 1471 - THIS_MODULE, NULL, adapter_nr) || 1473 + THIS_MODULE, &d, adapter_nr) || 1472 1474 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties, 1473 - THIS_MODULE, NULL, adapter_nr) || 1475 + THIS_MODULE, &d, adapter_nr) || 1474 1476 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties, 1475 - THIS_MODULE, NULL, adapter_nr) || 1477 + THIS_MODULE, &d, adapter_nr) || 1476 1478 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties, 1477 - THIS_MODULE, NULL, adapter_nr) || 1479 + THIS_MODULE, &d, adapter_nr) || 1478 1480 0 == dvb_usb_device_init(intf, 1479 1481 &cxusb_bluebird_nano2_needsfirmware_properties, 1480 - THIS_MODULE, NULL, adapter_nr) || 1482 + THIS_MODULE, &d, adapter_nr) || 1481 1483 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, 1482 - THIS_MODULE, NULL, adapter_nr) || 1484 + THIS_MODULE, &d, adapter_nr) || 1483 1485 0 == dvb_usb_device_init(intf, 1484 1486 &cxusb_bluebird_dualdig4_rev2_properties, 1485 - THIS_MODULE, NULL, adapter_nr) || 1487 + THIS_MODULE, &d, adapter_nr) || 1486 1488 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, 1487 - THIS_MODULE, NULL, adapter_nr) || 1489 + THIS_MODULE, &d, adapter_nr) || 1488 1490 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, 1489 - THIS_MODULE, NULL, adapter_nr) || 1491 + THIS_MODULE, &d, adapter_nr) || 1490 1492 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, 1491 - THIS_MODULE, NULL, adapter_nr) || 1492 - 0) 1493 + THIS_MODULE, &d, adapter_nr) || 1494 + 0) { 1495 + st = d->priv; 1496 + mutex_init(&st->data_mutex); 1497 + 1493 1498 return 0; 1499 + } 1494 1500 1495 1501 return -EINVAL; 1496 1502 }
+6
drivers/media/usb/dvb-usb/cxusb.h
··· 28 28 #define CMD_ANALOG 0x50 29 29 #define CMD_DIGITAL 0x51 30 30 31 + /* Max transfer size done by I2C transfer functions */ 32 + #define MAX_XFER_SIZE 80 33 + 31 34 struct cxusb_state { 32 35 u8 gpio_write_state[3]; 33 36 struct i2c_client *i2c_client_demod; 34 37 struct i2c_client *i2c_client_tuner; 38 + 39 + unsigned char data[MAX_XFER_SIZE]; 40 + struct mutex data_mutex; 35 41 }; 36 42 37 43 #endif