If certain ELS events are received during module removal, after the kthread
is stopped, the rmmod can hang. This fixes the ibmvfc driver so that ELS
events during rmmod are ignored by stopping all device activity prior to
killing the kthread and also changes reinitialization to not attempt a reinit
if the adapter has been taken offline.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
static void ibmvfc_reinit_host(struct ibmvfc_host *vhost)
{
if (vhost->action == IBMVFC_HOST_ACTION_NONE) {
static void ibmvfc_reinit_host(struct ibmvfc_host *vhost)
{
if (vhost->action == IBMVFC_HOST_ACTION_NONE) {
- scsi_block_requests(vhost->host);
- ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING);
- ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
+ if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) {
+ scsi_block_requests(vhost->host);
+ ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
+ }
} else
vhost->reinit = 1;
} else
vhost->reinit = 1;
ENTER;
ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr);
ENTER;
ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr);
+ ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE);
+ ibmvfc_wait_while_resetting(vhost);
+ ibmvfc_release_crq_queue(vhost);
kthread_stop(vhost->work_thread);
fc_remove_host(vhost->host);
scsi_remove_host(vhost->host);
kthread_stop(vhost->work_thread);
fc_remove_host(vhost->host);
scsi_remove_host(vhost->host);
- ibmvfc_release_crq_queue(vhost);
spin_lock_irqsave(vhost->host->host_lock, flags);
ibmvfc_purge_requests(vhost, DID_ERROR);
spin_lock_irqsave(vhost->host->host_lock, flags);
ibmvfc_purge_requests(vhost, DID_ERROR);