@@ -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 */
223231static 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 ;
0 commit comments