On Thu, 18 Oct 2018, Mayuresh Kulkarni wrote:
> > The only way to make the ioctl work properly is to have it do a
> > runtime-PM put at the start and then a runtime-PM get before it
> > returns. This is true regardless of the reason for returning: normal
> > termination, timeout, signal, whatever. Nothing else would be safe.
> >
>
> Will below steps work safely (sometimes pseudo-code/snippets help to align)? -
>
> "new" ioctl -
>
> timeout is parameter to ioctl.
>
> /* attempt suspend of device */
> usb_autosuspend_device(dev);
>
> usb_unlock_device(dev);
> r = wait_event_interruptible_timeout(ps->resume_wait,
> (ps->resume_done == true), timeout * HZ);
Not exactly. The condition to test here is whether the device has been
suspended, so it's more like this:
r = wait_event_interruptible_timeout(ps->suspend_wait,
(ps->suspend_done == true), timeout * HZ);
where ps->suspend_done is set by the runtime_suspend callback. After
this we will do:
if (r > 0) /* Device suspended before the timeout expired */
r = wait_event_interruptible(ps->resume_wait,
(ps->resume_done == true));
> usb_lock_device(dev);
>
> /*
> * There are 3 possibilities here:
> * 1. Device did suspend and resume (success)
> * 2. Signal was received (failed suspend)
> * 3. Time-out happened (failed suspend)
4. Device did suspend but a signal was received before the device
resumed.
> * In any of above cases, we need to resume device.
> */
> usb_autoresume_device(dev);
>
> ps->resume_done = false;
>
> "ps->resume_done = true;" will be done by the runtime resume call-back.
Exactly. You got it. Will that let you accomplish what you want?
Alan Stern