Skip to content

Commit b430eab

Browse files
committed
[media] flexcop-usb: don't use stack for DMA
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. While here, remove a dead function calling usb_control_msg(). Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
1 parent b5f93cb commit b430eab

2 files changed

Lines changed: 72 additions & 37 deletions

File tree

drivers/media/usb/b2c2/flexcop-usb.c

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -73,23 +73,34 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
7373
u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
7474
u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
7575
(read ? 0x80 : 0);
76+
int ret;
77+
78+
mutex_lock(&fc_usb->data_mutex);
79+
if (!read)
80+
memcpy(fc_usb->data, val, sizeof(*val));
7681

77-
int len = usb_control_msg(fc_usb->udev,
82+
ret = usb_control_msg(fc_usb->udev,
7883
read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
7984
request,
8085
request_type, /* 0xc0 read or 0x40 write */
8186
wAddress,
8287
0,
83-
val,
88+
fc_usb->data,
8489
sizeof(u32),
8590
B2C2_WAIT_FOR_OPERATION_RDW * HZ);
8691

87-
if (len != sizeof(u32)) {
92+
if (ret != sizeof(u32)) {
8893
err("error while %s dword from %d (%d).", read ? "reading" :
8994
"writing", wAddress, wRegOffsPCI);
90-
return -EIO;
95+
if (ret >= 0)
96+
ret = -EIO;
9197
}
92-
return 0;
98+
99+
if (read && ret >= 0)
100+
memcpy(val, fc_usb->data, sizeof(*val));
101+
mutex_unlock(&fc_usb->data_mutex);
102+
103+
return ret;
93104
}
94105
/*
95106
* DKT 010817 - add support for V8 memory read/write and flash update
@@ -100,9 +111,14 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
100111
{
101112
u8 request_type = USB_TYPE_VENDOR;
102113
u16 wIndex;
103-
int nWaitTime, pipe, len;
114+
int nWaitTime, pipe, ret;
104115
wIndex = page << 8;
105116

117+
if (buflen > sizeof(fc_usb->data)) {
118+
err("Buffer size bigger than max URB control message\n");
119+
return -EIO;
120+
}
121+
106122
switch (req) {
107123
case B2C2_USB_READ_V8_MEM:
108124
nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
@@ -127,17 +143,32 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
127143
deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
128144
wAddress, wIndex, buflen);
129145

130-
len = usb_control_msg(fc_usb->udev, pipe,
146+
mutex_lock(&fc_usb->data_mutex);
147+
148+
if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
149+
memcpy(fc_usb->data, pbBuffer, buflen);
150+
151+
ret = usb_control_msg(fc_usb->udev, pipe,
131152
req,
132153
request_type,
133154
wAddress,
134155
wIndex,
135-
pbBuffer,
156+
fc_usb->data,
136157
buflen,
137158
nWaitTime * HZ);
159+
if (ret != buflen)
160+
ret = -EIO;
161+
162+
if (ret >= 0) {
163+
ret = 0;
164+
if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
165+
memcpy(pbBuffer, fc_usb->data, buflen);
166+
}
138167

139-
debug_dump(pbBuffer, len, deb_v8);
140-
return len == buflen ? 0 : -EIO;
168+
mutex_unlock(&fc_usb->data_mutex);
169+
170+
debug_dump(pbBuffer, ret, deb_v8);
171+
return ret;
141172
}
142173

143174
#define bytes_left_to_read_on_page(paddr,buflen) \
@@ -196,39 +227,21 @@ static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
196227
fc->dvb_adapter.proposed_mac, 6);
197228
}
198229

199-
#if 0
200-
static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
201-
flexcop_usb_utility_function_t func, u8 extra, u16 wIndex,
202-
u16 buflen, u8 *pvBuffer)
203-
{
204-
u16 wValue;
205-
u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
206-
int nWaitTime = 2,
207-
pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len;
208-
wValue = (func << 8) | extra;
209-
210-
len = usb_control_msg(fc_usb->udev,pipe,
211-
B2C2_USB_UTILITY,
212-
request_type,
213-
wValue,
214-
wIndex,
215-
pvBuffer,
216-
buflen,
217-
nWaitTime * HZ);
218-
return len == buflen ? 0 : -EIO;
219-
}
220-
#endif
221-
222230
/* usb i2c stuff */
223231
static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
224232
flexcop_usb_request_t req, flexcop_usb_i2c_function_t func,
225233
u8 chipaddr, u8 addr, u8 *buf, u8 buflen)
226234
{
227235
struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
228236
u16 wValue, wIndex;
229-
int nWaitTime,pipe,len;
237+
int nWaitTime, pipe, ret;
230238
u8 request_type = USB_TYPE_VENDOR;
231239

240+
if (buflen > sizeof(fc_usb->data)) {
241+
err("Buffer size bigger than max URB control message\n");
242+
return -EIO;
243+
}
244+
232245
switch (func) {
233246
case USB_FUNC_I2C_WRITE:
234247
case USB_FUNC_I2C_MULTIWRITE:
@@ -257,15 +270,32 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
257270
wValue & 0xff, wValue >> 8,
258271
wIndex & 0xff, wIndex >> 8);
259272

260-
len = usb_control_msg(fc_usb->udev,pipe,
273+
mutex_lock(&fc_usb->data_mutex);
274+
275+
if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
276+
memcpy(fc_usb->data, buf, buflen);
277+
278+
ret = usb_control_msg(fc_usb->udev, pipe,
261279
req,
262280
request_type,
263281
wValue,
264282
wIndex,
265-
buf,
283+
fc_usb->data,
266284
buflen,
267285
nWaitTime * HZ);
268-
return len == buflen ? 0 : -EREMOTEIO;
286+
287+
if (ret != buflen)
288+
ret = -EIO;
289+
290+
if (ret >= 0) {
291+
ret = 0;
292+
if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
293+
memcpy(buf, fc_usb->data, buflen);
294+
}
295+
296+
mutex_unlock(&fc_usb->data_mutex);
297+
298+
return 0;
269299
}
270300

271301
/* actual bus specific access functions,
@@ -516,6 +546,7 @@ static int flexcop_usb_probe(struct usb_interface *intf,
516546
/* general flexcop init */
517547
fc_usb = fc->bus_specific;
518548
fc_usb->fc_dev = fc;
549+
mutex_init(&fc_usb->data_mutex);
519550

520551
fc->read_ibi_reg = flexcop_usb_read_ibi_reg;
521552
fc->write_ibi_reg = flexcop_usb_write_ibi_reg;

drivers/media/usb/b2c2/flexcop-usb.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ struct flexcop_usb {
2929

3030
u8 tmp_buffer[1023+190];
3131
int tmp_buffer_length;
32+
33+
/* for URB control messages */
34+
u8 data[80];
35+
struct mutex data_mutex;
3236
};
3337

3438
#if 0

0 commit comments

Comments
 (0)