@@ -338,6 +338,7 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
338
338
size_t count , loff_t * offp )
339
339
{
340
340
struct f_hidg * hidg = file -> private_data ;
341
+ struct usb_request * req ;
341
342
unsigned long flags ;
342
343
ssize_t status = - ENOMEM ;
343
344
@@ -347,7 +348,7 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
347
348
spin_lock_irqsave (& hidg -> write_spinlock , flags );
348
349
349
350
#define WRITE_COND (!hidg->write_pending)
350
-
351
+ try_again :
351
352
/* write queue */
352
353
while (!WRITE_COND ) {
353
354
spin_unlock_irqrestore (& hidg -> write_spinlock , flags );
@@ -362,6 +363,7 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
362
363
}
363
364
364
365
hidg -> write_pending = 1 ;
366
+ req = hidg -> req ;
365
367
count = min_t (unsigned , count , hidg -> report_length );
366
368
367
369
spin_unlock_irqrestore (& hidg -> write_spinlock , flags );
@@ -374,24 +376,38 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
374
376
goto release_write_pending ;
375
377
}
376
378
377
- hidg -> req -> status = 0 ;
378
- hidg -> req -> zero = 0 ;
379
- hidg -> req -> length = count ;
380
- hidg -> req -> complete = f_hidg_req_complete ;
381
- hidg -> req -> context = hidg ;
379
+ spin_lock_irqsave (& hidg -> write_spinlock , flags );
380
+
381
+ /* we our function has been disabled by host */
382
+ if (!hidg -> req ) {
383
+ free_ep_req (hidg -> in_ep , hidg -> req );
384
+ /*
385
+ * TODO
386
+ * Should we fail with error here?
387
+ */
388
+ goto try_again ;
389
+ }
390
+
391
+ req -> status = 0 ;
392
+ req -> zero = 0 ;
393
+ req -> length = count ;
394
+ req -> complete = f_hidg_req_complete ;
395
+ req -> context = hidg ;
382
396
383
397
status = usb_ep_queue (hidg -> in_ep , hidg -> req , GFP_ATOMIC );
384
398
if (status < 0 ) {
385
399
ERROR (hidg -> func .config -> cdev ,
386
400
"usb_ep_queue error on int endpoint %zd\n" , status );
387
- goto release_write_pending ;
401
+ goto release_write_pending_unlocked ;
388
402
} else {
389
403
status = count ;
390
404
}
405
+ spin_unlock_irqrestore (& hidg -> write_spinlock , flags );
391
406
392
407
return status ;
393
408
release_write_pending :
394
409
spin_lock_irqsave (& hidg -> write_spinlock , flags );
410
+ release_write_pending_unlocked :
395
411
hidg -> write_pending = 0 ;
396
412
spin_unlock_irqrestore (& hidg -> write_spinlock , flags );
397
413
@@ -595,12 +611,23 @@ static void hidg_disable(struct usb_function *f)
595
611
kfree (list );
596
612
}
597
613
spin_unlock_irqrestore (& hidg -> read_spinlock , flags );
614
+
615
+ spin_lock_irqsave (& hidg -> write_spinlock , flags );
616
+ if (!hidg -> write_pending ) {
617
+ free_ep_req (hidg -> in_ep , hidg -> req );
618
+ hidg -> write_pending = 1 ;
619
+ }
620
+
621
+ hidg -> req = NULL ;
622
+ spin_unlock_irqrestore (& hidg -> write_spinlock , flags );
598
623
}
599
624
600
625
static int hidg_set_alt (struct usb_function * f , unsigned intf , unsigned alt )
601
626
{
602
627
struct usb_composite_dev * cdev = f -> config -> cdev ;
603
628
struct f_hidg * hidg = func_to_hidg (f );
629
+ struct usb_request * req_in = NULL ;
630
+ unsigned long flags ;
604
631
int i , status = 0 ;
605
632
606
633
VDBG (cdev , "hidg_set_alt intf:%d alt:%d\n" , intf , alt );
@@ -621,6 +648,12 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
621
648
goto fail ;
622
649
}
623
650
hidg -> in_ep -> driver_data = hidg ;
651
+
652
+ req_in = hidg_alloc_ep_req (hidg -> in_ep , hidg -> report_length );
653
+ if (!req_in ) {
654
+ status = - ENOMEM ;
655
+ goto disable_ep_in ;
656
+ }
624
657
}
625
658
626
659
@@ -632,12 +665,12 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
632
665
hidg -> out_ep );
633
666
if (status ) {
634
667
ERROR (cdev , "config_ep_by_speed FAILED!\n" );
635
- goto fail ;
668
+ goto free_req_in ;
636
669
}
637
670
status = usb_ep_enable (hidg -> out_ep );
638
671
if (status < 0 ) {
639
672
ERROR (cdev , "Enable OUT endpoint FAILED!\n" );
640
- goto fail ;
673
+ goto free_req_in ;
641
674
}
642
675
hidg -> out_ep -> driver_data = hidg ;
643
676
@@ -653,17 +686,37 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
653
686
req -> context = hidg ;
654
687
status = usb_ep_queue (hidg -> out_ep , req ,
655
688
GFP_ATOMIC );
656
- if (status )
689
+ if (status ) {
657
690
ERROR (cdev , "%s queue req --> %d\n" ,
658
691
hidg -> out_ep -> name , status );
692
+ free_ep_req (hidg -> out_ep , req );
693
+ }
659
694
} else {
660
- usb_ep_disable (hidg -> out_ep );
661
695
status = - ENOMEM ;
662
- goto fail ;
696
+ goto disable_out_ep ;
663
697
}
664
698
}
665
699
}
666
700
701
+ if (hidg -> in_ep != NULL ) {
702
+ spin_lock_irqsave (& hidg -> write_spinlock , flags );
703
+ hidg -> req = req_in ;
704
+ hidg -> write_pending = 0 ;
705
+ spin_unlock_irqrestore (& hidg -> write_spinlock , flags );
706
+
707
+ wake_up (& hidg -> write_queue );
708
+ }
709
+ return 0 ;
710
+ disable_out_ep :
711
+ usb_ep_disable (hidg -> out_ep );
712
+ free_req_in :
713
+ if (req_in )
714
+ free_ep_req (hidg -> in_ep , req_in );
715
+
716
+ disable_ep_in :
717
+ if (hidg -> in_ep )
718
+ usb_ep_disable (hidg -> in_ep );
719
+
667
720
fail :
668
721
return status ;
669
722
}
@@ -712,12 +765,6 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
712
765
goto fail ;
713
766
hidg -> out_ep = ep ;
714
767
715
- /* preallocate request and buffer */
716
- status = - ENOMEM ;
717
- hidg -> req = alloc_ep_req (hidg -> in_ep , hidg -> report_length );
718
- if (!hidg -> req )
719
- goto fail ;
720
-
721
768
/* set descriptor dynamic values */
722
769
hidg_interface_desc .bInterfaceSubClass = hidg -> bInterfaceSubClass ;
723
770
hidg_interface_desc .bInterfaceProtocol = hidg -> bInterfaceProtocol ;
@@ -755,6 +802,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
755
802
goto fail ;
756
803
757
804
spin_lock_init (& hidg -> write_spinlock );
805
+ hidg -> write_pending = 1 ;
806
+ hidg -> req = NULL ;
758
807
spin_lock_init (& hidg -> read_spinlock );
759
808
init_waitqueue_head (& hidg -> write_queue );
760
809
init_waitqueue_head (& hidg -> read_queue );
@@ -1019,10 +1068,6 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
1019
1068
device_destroy (hidg_class , MKDEV (major , hidg -> minor ));
1020
1069
cdev_del (& hidg -> cdev );
1021
1070
1022
- /* disable/free request and end point */
1023
- usb_ep_disable (hidg -> in_ep );
1024
- free_ep_req (hidg -> in_ep , hidg -> req );
1025
-
1026
1071
usb_free_all_descriptors (f );
1027
1072
}
1028
1073
0 commit comments