staging: unisys: visornic: correct visornic_pause
Correct visornic_pause() to indicate completion asynchronously rather than in-line Previously, visornic_pause() (called to stop the device due to IOVM service partition recovery) was calling the passed complete_func() in-line, rather than delaying the calling until after the device had actually been stopped. The behavior has been corrected so that the calling of the complete_func() is now delayed until after the stopping of the device has been completed in visornic_serverdown_complete(), which runs asynchronously via the workqueue visornic_serverdown_workqueue. Signed-off-by: Tim Sell <Timothy.Sell@unisys.com> Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d15a65be55
commit
d01da5eac0
1 changed files with 10 additions and 4 deletions
|
@ -151,6 +151,7 @@ struct visornic_devdata {
|
||||||
* sent to the IOPART end
|
* sent to the IOPART end
|
||||||
*/
|
*/
|
||||||
struct work_struct serverdown_completion;
|
struct work_struct serverdown_completion;
|
||||||
|
visorbus_state_complete_func server_down_complete_func;
|
||||||
struct work_struct timeout_reset;
|
struct work_struct timeout_reset;
|
||||||
struct uiscmdrsp *cmdrsp_rcv; /* cmdrsp_rcv is used for
|
struct uiscmdrsp *cmdrsp_rcv; /* cmdrsp_rcv is used for
|
||||||
* posting/unposting rcv buffers
|
* posting/unposting rcv buffers
|
||||||
|
@ -545,8 +546,12 @@ visornic_serverdown_complete(struct work_struct *work)
|
||||||
atomic_set(&devdata->num_rcvbuf_in_iovm, 0);
|
atomic_set(&devdata->num_rcvbuf_in_iovm, 0);
|
||||||
spin_unlock_irqrestore(&devdata->priv_lock, flags);
|
spin_unlock_irqrestore(&devdata->priv_lock, flags);
|
||||||
|
|
||||||
|
if (devdata->server_down_complete_func)
|
||||||
|
(*devdata->server_down_complete_func)(devdata->dev, 0);
|
||||||
|
|
||||||
devdata->server_down = true;
|
devdata->server_down = true;
|
||||||
devdata->server_change_state = false;
|
devdata->server_change_state = false;
|
||||||
|
devdata->server_down_complete_func = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -558,10 +563,12 @@ visornic_serverdown_complete(struct work_struct *work)
|
||||||
* Returns 0 if we scheduled the work, -EINVAL on error.
|
* Returns 0 if we scheduled the work, -EINVAL on error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
visornic_serverdown(struct visornic_devdata *devdata)
|
visornic_serverdown(struct visornic_devdata *devdata,
|
||||||
|
visorbus_state_complete_func complete_func)
|
||||||
{
|
{
|
||||||
if (!devdata->server_down && !devdata->server_change_state) {
|
if (!devdata->server_down && !devdata->server_change_state) {
|
||||||
devdata->server_change_state = true;
|
devdata->server_change_state = true;
|
||||||
|
devdata->server_down_complete_func = complete_func;
|
||||||
queue_work(visornic_serverdown_workqueue,
|
queue_work(visornic_serverdown_workqueue,
|
||||||
&devdata->serverdown_completion);
|
&devdata->serverdown_completion);
|
||||||
} else if (devdata->server_change_state) {
|
} else if (devdata->server_change_state) {
|
||||||
|
@ -895,7 +902,7 @@ visornic_timeout_reset(struct work_struct *work)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
call_serverdown:
|
call_serverdown:
|
||||||
visornic_serverdown(devdata);
|
visornic_serverdown(devdata, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1980,8 +1987,7 @@ static int visornic_pause(struct visor_device *dev,
|
||||||
{
|
{
|
||||||
struct visornic_devdata *devdata = dev_get_drvdata(&dev->device);
|
struct visornic_devdata *devdata = dev_get_drvdata(&dev->device);
|
||||||
|
|
||||||
visornic_serverdown(devdata);
|
visornic_serverdown(devdata, complete_func);
|
||||||
complete_func(dev, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue