@@ -81,6 +81,7 @@ static int raw_event_queue_add(struct raw_event_queue *queue,
81
81
static struct usb_raw_event * raw_event_queue_fetch (
82
82
struct raw_event_queue * queue )
83
83
{
84
+ int ret ;
84
85
unsigned long flags ;
85
86
struct usb_raw_event * event ;
86
87
@@ -89,11 +90,18 @@ static struct usb_raw_event *raw_event_queue_fetch(
89
90
* there's at least one event queued by decrementing the semaphore,
90
91
* and then take the lock to protect queue struct fields.
91
92
*/
92
- if (down_interruptible (& queue -> sema ))
93
- return NULL ;
93
+ ret = down_interruptible (& queue -> sema );
94
+ if (ret )
95
+ return ERR_PTR (ret );
94
96
spin_lock_irqsave (& queue -> lock , flags );
95
- if (WARN_ON (!queue -> size ))
96
- return NULL ;
97
+ /*
98
+ * queue->size must have the same value as queue->sema counter (before
99
+ * the down_interruptible() call above), so this check is a fail-safe.
100
+ */
101
+ if (WARN_ON (!queue -> size )) {
102
+ spin_unlock_irqrestore (& queue -> lock , flags );
103
+ return ERR_PTR (- ENODEV );
104
+ }
97
105
event = queue -> events [0 ];
98
106
queue -> size -- ;
99
107
memmove (& queue -> events [0 ], & queue -> events [1 ],
@@ -522,10 +530,17 @@ static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value)
522
530
spin_unlock_irqrestore (& dev -> lock , flags );
523
531
524
532
event = raw_event_queue_fetch (& dev -> queue );
525
- if (! event ) {
533
+ if (PTR_ERR ( event ) == - EINTR ) {
526
534
dev_dbg (& dev -> gadget -> dev , "event fetching interrupted\n" );
527
535
return - EINTR ;
528
536
}
537
+ if (IS_ERR (event )) {
538
+ dev_err (& dev -> gadget -> dev , "failed to fetch event\n" );
539
+ spin_lock_irqsave (& dev -> lock , flags );
540
+ dev -> state = STATE_DEV_FAILED ;
541
+ spin_unlock_irqrestore (& dev -> lock , flags );
542
+ return - ENODEV ;
543
+ }
529
544
length = min (arg .length , event -> length );
530
545
if (copy_to_user ((void __user * )value , event , sizeof (* event ) + length ))
531
546
return - EFAULT ;
0 commit comments