On Mon, 06 Sep 2021 11:18:27 -0700
Fix the warning by replacing usb_unlink_urb() with usb_kill_urb() in
case of IO timeout. And in case of error while submitting urb, which
triggered the report.
To do that, replace the wait loop
while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
wait_for_completion(&hdw->ctl_done);
with
wait_for_completion_timeout(&hdw->ctl_done, timeout);
because it makes no sense to wait more than once for completion.
Finally clean up hdw_timer by moving the timer callback after the wait.
Only for thoughts now.
--- x/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ y/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -3546,26 +3546,6 @@ static void pvr2_ctl_read_complete(struc
complete(&hdw->ctl_done);
}
-struct hdw_timer {
- struct timer_list timer;
- struct pvr2_hdw *hdw;
-};
-
-static void pvr2_ctl_timeout(struct timer_list *t)
-{
- struct hdw_timer *timer = from_timer(timer, t, timer);
- struct pvr2_hdw *hdw = timer->hdw;
-
- if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
- hdw->ctl_timeout_flag = !0;
- if (hdw->ctl_write_pend_flag)
- usb_unlink_urb(hdw->ctl_write_urb);
- if (hdw->ctl_read_pend_flag)
- usb_unlink_urb(hdw->ctl_read_urb);
- }
-}
-
-
/* Issue a command and get a response from the device. This extended
version includes a probe flag (which if set means that device errors
should not be logged or treated as fatal) and a timeout in jiffies.
@@ -3577,9 +3557,6 @@ static int pvr2_send_request_ex(struct p
{
unsigned int idx;
int status = 0;
- struct hdw_timer timer = {
- .hdw = hdw,
- };
if (!hdw->ctl_lock_held) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -3637,8 +3614,6 @@ static int pvr2_send_request_ex(struct p
hdw->ctl_timeout_flag = 0;
hdw->ctl_write_pend_flag = 0;
hdw->ctl_read_pend_flag = 0;
- timer_setup_on_stack(&timer.timer, pvr2_ctl_timeout, 0);
- timer.timer.expires = jiffies + timeout;
if (write_len && write_data) {
hdw->cmd_debug_state = 2;
@@ -3657,7 +3632,6 @@ static int pvr2_send_request_ex(struct p
pvr2_ctl_write_complete,
hdw);
hdw->ctl_write_urb->actual_length = 0;
- hdw->ctl_write_pend_flag = !0;
if (usb_urb_ep_type_check(hdw->ctl_write_urb)) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS,
@@ -3672,6 +3646,7 @@ status);
hdw->ctl_write_pend_flag = 0;
goto done;
}
+ hdw->ctl_write_pend_flag = !0;
}
if (read_len) {
@@ -3687,12 +3662,12 @@ status);
pvr2_ctl_read_complete,
hdw);
hdw->ctl_read_urb->actual_length = 0;
- hdw->ctl_read_pend_flag = !0;
if (usb_urb_ep_type_check(hdw->ctl_read_urb)) {
pvr2_trace(
PVR2_TRACE_ERROR_LEGS,
"Invalid read control endpoint");
- return -EINVAL;
+ status = -EINVAL;
+ goto kill;
}
status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
if (status < 0) {
@@ -3700,25 +3675,25 @@ status);
"Failed to submit read-control URB status=%d",
status);
hdw->ctl_read_pend_flag = 0;
- goto done;
+ goto kill;
}
+ hdw->ctl_read_pend_flag = !0;
}
- /* Start timer */
- add_timer(&timer.timer);
-
/* Now wait for all I/O to complete */
hdw->cmd_debug_state = 4;
- while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
- wait_for_completion(&hdw->ctl_done);
+ status = 0;
+ wait_for_completion_timeout(&hdw->ctl_done, timeout);
+ if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
+ hdw->ctl_timeout_flag = !0;
+ kill:
+ if (hdw->ctl_write_pend_flag)
+ usb_kill_urb(hdw->ctl_write_urb);
+ if (hdw->ctl_read_pend_flag)
+ usb_kill_urb(hdw->ctl_read_urb);
}
hdw->cmd_debug_state = 5;
-
- /* Stop timer */
- del_timer_sync(&timer.timer);
-
hdw->cmd_debug_state = 6;
- status = 0;
if (hdw->ctl_timeout_flag) {
status = -ETIMEDOUT;
@@ -3726,8 +3701,9 @@ status);
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"Timed out control-write");
}
- goto done;
}
+ if (status)
+ goto done;
if (write_len) {
/* Validate results of write request */
@@ -3797,8 +3773,6 @@ status);
if ((status < 0) && (!probe_fl)) {
pvr2_hdw_render_useless(hdw);
}
- destroy_timer_on_stack(&timer.timer);
-
return status;
}