@@ -35,7 +35,7 @@ struct iguanair {
35
35
struct device * dev ;
36
36
struct usb_device * udev ;
37
37
38
- int pipe_in , pipe_out ;
38
+ int pipe_out ;
39
39
uint8_t bufsize ;
40
40
uint8_t version [2 ];
41
41
@@ -82,11 +82,6 @@ struct packet {
82
82
uint8_t cmd ;
83
83
};
84
84
85
- struct response_packet {
86
- struct packet header ;
87
- uint8_t data [4 ];
88
- };
89
-
90
85
struct send_packet {
91
86
struct packet header ;
92
87
uint8_t length ;
@@ -100,6 +95,26 @@ static void process_ir_data(struct iguanair *ir, unsigned len)
100
95
{
101
96
if (len >= 4 && ir -> buf_in [0 ] == 0 && ir -> buf_in [1 ] == 0 ) {
102
97
switch (ir -> buf_in [3 ]) {
98
+ case CMD_GET_VERSION :
99
+ if (len == 6 ) {
100
+ ir -> version [0 ] = ir -> buf_in [4 ];
101
+ ir -> version [1 ] = ir -> buf_in [5 ];
102
+ complete (& ir -> completion );
103
+ }
104
+ break ;
105
+ case CMD_GET_BUFSIZE :
106
+ if (len >= 5 ) {
107
+ ir -> bufsize = ir -> buf_in [4 ];
108
+ complete (& ir -> completion );
109
+ }
110
+ break ;
111
+ case CMD_GET_FEATURES :
112
+ if (len > 5 ) {
113
+ if (ir -> version [0 ] >= 4 )
114
+ ir -> cycle_overhead = ir -> buf_in [5 ];
115
+ complete (& ir -> completion );
116
+ }
117
+ break ;
103
118
case CMD_TX_OVERFLOW :
104
119
ir -> tx_overflow = true;
105
120
case CMD_RECEIVER_OFF :
@@ -169,98 +184,63 @@ static void iguanair_rx(struct urb *urb)
169
184
usb_submit_urb (urb , GFP_ATOMIC );
170
185
}
171
186
172
- static int iguanair_send (struct iguanair * ir , void * data , unsigned size ,
173
- struct response_packet * response , unsigned * res_len )
187
+ static int iguanair_send (struct iguanair * ir , void * data , unsigned size )
174
188
{
175
- unsigned offset , len ;
176
189
int rc , transferred ;
177
190
178
- for (offset = 0 ; offset < size ; offset += MAX_PACKET_SIZE ) {
179
- len = min (size - offset , MAX_PACKET_SIZE );
180
-
181
- if (ir -> tx_overflow )
182
- return - EOVERFLOW ;
191
+ INIT_COMPLETION (ir -> completion );
183
192
184
- rc = usb_interrupt_msg (ir -> udev , ir -> pipe_out , data + offset ,
185
- len , & transferred , TIMEOUT );
186
- if (rc )
187
- return rc ;
193
+ rc = usb_interrupt_msg (ir -> udev , ir -> pipe_out , data , size ,
194
+ & transferred , TIMEOUT );
195
+ if (rc )
196
+ return rc ;
188
197
189
- if (transferred != len )
190
- return - EIO ;
191
- }
198
+ if (transferred != size )
199
+ return - EIO ;
192
200
193
- if (response ) {
194
- rc = usb_interrupt_msg (ir -> udev , ir -> pipe_in , response ,
195
- sizeof (* response ), res_len , TIMEOUT );
196
- }
201
+ if (wait_for_completion_timeout (& ir -> completion , TIMEOUT ) == 0 )
202
+ return - ETIMEDOUT ;
197
203
198
204
return rc ;
199
205
}
200
206
201
207
static int iguanair_get_features (struct iguanair * ir )
202
208
{
203
209
struct packet packet ;
204
- struct response_packet response ;
205
- int rc , len ;
210
+ int rc ;
206
211
207
212
packet .start = 0 ;
208
213
packet .direction = DIR_OUT ;
209
214
packet .cmd = CMD_GET_VERSION ;
210
215
211
- rc = iguanair_send (ir , & packet , sizeof (packet ), & response , & len );
216
+ rc = iguanair_send (ir , & packet , sizeof (packet ));
212
217
if (rc ) {
213
218
dev_info (ir -> dev , "failed to get version\n" );
214
219
goto out ;
215
220
}
216
221
217
- if (len != 6 ) {
218
- dev_info (ir -> dev , "failed to get version\n" );
219
- rc = - EIO ;
220
- goto out ;
221
- }
222
-
223
- ir -> version [0 ] = response .data [0 ];
224
- ir -> version [1 ] = response .data [1 ];
225
222
ir -> bufsize = 150 ;
226
223
ir -> cycle_overhead = 65 ;
227
224
228
225
packet .cmd = CMD_GET_BUFSIZE ;
229
226
230
- rc = iguanair_send (ir , & packet , sizeof (packet ), & response , & len );
227
+ rc = iguanair_send (ir , & packet , sizeof (packet ));
231
228
if (rc ) {
232
229
dev_info (ir -> dev , "failed to get buffer size\n" );
233
230
goto out ;
234
231
}
235
232
236
- if (len != 5 ) {
237
- dev_info (ir -> dev , "failed to get buffer size\n" );
238
- rc = - EIO ;
239
- goto out ;
240
- }
241
-
242
- ir -> bufsize = response .data [0 ];
243
-
244
233
if (ir -> version [0 ] == 0 || ir -> version [1 ] == 0 )
245
234
goto out ;
246
235
247
236
packet .cmd = CMD_GET_FEATURES ;
248
237
249
- rc = iguanair_send (ir , & packet , sizeof (packet ), & response , & len );
238
+ rc = iguanair_send (ir , & packet , sizeof (packet ));
250
239
if (rc ) {
251
240
dev_info (ir -> dev , "failed to get features\n" );
252
241
goto out ;
253
242
}
254
243
255
- if (len < 5 ) {
256
- dev_info (ir -> dev , "failed to get features\n" );
257
- rc = - EIO ;
258
- goto out ;
259
- }
260
-
261
- if (len > 5 && ir -> version [0 ] >= 4 )
262
- ir -> cycle_overhead = response .data [1 ];
263
-
264
244
out :
265
245
return rc ;
266
246
}
@@ -269,17 +249,8 @@ static int iguanair_receiver(struct iguanair *ir, bool enable)
269
249
{
270
250
struct packet packet = { 0 , DIR_OUT , enable ?
271
251
CMD_RECEIVER_ON : CMD_RECEIVER_OFF };
272
- int rc ;
273
-
274
- INIT_COMPLETION (ir -> completion );
275
-
276
- rc = iguanair_send (ir , & packet , sizeof (packet ), NULL , NULL );
277
- if (rc )
278
- return rc ;
279
-
280
- wait_for_completion_timeout (& ir -> completion , TIMEOUT );
281
252
282
- return 0 ;
253
+ return iguanair_send ( ir , & packet , sizeof ( packet )) ;
283
254
}
284
255
285
256
/*
@@ -406,17 +377,10 @@ static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
406
377
407
378
ir -> tx_overflow = false;
408
379
409
- INIT_COMPLETION (ir -> completion );
410
-
411
- rc = iguanair_send (ir , packet , size + 8 , NULL , NULL );
380
+ rc = iguanair_send (ir , packet , size + 8 );
412
381
413
- if (rc == 0 ) {
414
- wait_for_completion_timeout (& ir -> completion , TIMEOUT );
415
- if (ir -> tx_overflow )
416
- rc = - EOVERFLOW ;
417
- }
418
-
419
- ir -> tx_overflow = false;
382
+ if (rc == 0 && ir -> tx_overflow )
383
+ rc = - EOVERFLOW ;
420
384
421
385
if (ir -> receiver_on ) {
422
386
if (iguanair_receiver (ir , true))
@@ -437,8 +401,6 @@ static int iguanair_open(struct rc_dev *rdev)
437
401
438
402
mutex_lock (& ir -> lock );
439
403
440
- usb_submit_urb (ir -> urb_in , GFP_KERNEL );
441
-
442
404
BUG_ON (ir -> receiver_on );
443
405
444
406
rc = iguanair_receiver (ir , true);
@@ -462,8 +424,6 @@ static void iguanair_close(struct rc_dev *rdev)
462
424
if (rc )
463
425
dev_warn (ir -> dev , "failed to disable receiver: %d\n" , rc );
464
426
465
- usb_kill_urb (ir -> urb_in );
466
-
467
427
mutex_unlock (& ir -> lock );
468
428
}
469
429
@@ -473,7 +433,7 @@ static int __devinit iguanair_probe(struct usb_interface *intf,
473
433
struct usb_device * udev = interface_to_usbdev (intf );
474
434
struct iguanair * ir ;
475
435
struct rc_dev * rc ;
476
- int ret ;
436
+ int ret , pipein ;
477
437
struct usb_host_interface * idesc ;
478
438
479
439
ir = kzalloc (sizeof (* ir ), GFP_KERNEL );
@@ -483,7 +443,7 @@ static int __devinit iguanair_probe(struct usb_interface *intf,
483
443
goto out ;
484
444
}
485
445
486
- ir -> buf_in = usb_alloc_coherent (udev , MAX_PACKET_SIZE , GFP_ATOMIC ,
446
+ ir -> buf_in = usb_alloc_coherent (udev , MAX_PACKET_SIZE , GFP_KERNEL ,
487
447
& ir -> dma_in );
488
448
ir -> urb_in = usb_alloc_urb (0 , GFP_KERNEL );
489
449
@@ -502,25 +462,28 @@ static int __devinit iguanair_probe(struct usb_interface *intf,
502
462
ir -> rc = rc ;
503
463
ir -> dev = & intf -> dev ;
504
464
ir -> udev = udev ;
505
- ir -> pipe_in = usb_rcvintpipe (udev ,
506
- idesc -> endpoint [0 ].desc .bEndpointAddress );
507
465
ir -> pipe_out = usb_sndintpipe (udev ,
508
466
idesc -> endpoint [1 ].desc .bEndpointAddress );
509
467
mutex_init (& ir -> lock );
510
468
init_completion (& ir -> completion );
511
469
512
- ret = iguanair_get_features (ir );
513
- if (ret ) {
514
- dev_warn (& intf -> dev , "failed to get device features" );
515
- goto out ;
516
- }
517
-
518
- usb_fill_int_urb (ir -> urb_in , ir -> udev , ir -> pipe_in , ir -> buf_in ,
470
+ pipein = usb_rcvintpipe (udev , idesc -> endpoint [0 ].desc .bEndpointAddress );
471
+ usb_fill_int_urb (ir -> urb_in , udev , pipein , ir -> buf_in ,
519
472
MAX_PACKET_SIZE , iguanair_rx , ir ,
520
473
idesc -> endpoint [0 ].desc .bInterval );
521
474
ir -> urb_in -> transfer_dma = ir -> dma_in ;
522
475
ir -> urb_in -> transfer_flags |= URB_NO_TRANSFER_DMA_MAP ;
523
476
477
+ ret = usb_submit_urb (ir -> urb_in , GFP_KERNEL );
478
+ if (ret ) {
479
+ dev_warn (& intf -> dev , "failed to submit urb: %d\n" , ret );
480
+ goto out ;
481
+ }
482
+
483
+ ret = iguanair_get_features (ir );
484
+ if (ret )
485
+ goto out2 ;
486
+
524
487
snprintf (ir -> name , sizeof (ir -> name ),
525
488
"IguanaWorks USB IR Transceiver version %d.%d" ,
526
489
ir -> version [0 ], ir -> version [1 ]);
@@ -547,14 +510,16 @@ static int __devinit iguanair_probe(struct usb_interface *intf,
547
510
ret = rc_register_device (rc );
548
511
if (ret < 0 ) {
549
512
dev_err (& intf -> dev , "failed to register rc device %d" , ret );
550
- goto out ;
513
+ goto out2 ;
551
514
}
552
515
553
516
usb_set_intfdata (intf , ir );
554
517
555
518
dev_info (& intf -> dev , "Registered %s" , ir -> name );
556
519
557
520
return 0 ;
521
+ out2 :
522
+ usb_kill_urb (ir -> urb_in );
558
523
out :
559
524
if (ir ) {
560
525
usb_free_urb (ir -> urb_in );
0 commit comments