Commit 6e40de8b authored by Tyrel Datwyler's avatar Tyrel Datwyler Committed by Martin K. Petersen

scsi: ibmvscsi: redo driver work thread to use enum action states

The current implemenation relies on two flags in the driver's private host
structure to signal the need for a host reset or to reenable the CRQ after
a LPAR migration. This patch does away with those flags and introduces a
single action flag and defined enums for the supported kthread work
actions. Lastly, the if/else logic is replaced with a switch statement.
Signed-off-by: default avatarTyrel Datwyler <tyreld@linux.ibm.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 2e225204
...@@ -828,7 +828,7 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) ...@@ -828,7 +828,7 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata)
atomic_set(&hostdata->request_limit, 0); atomic_set(&hostdata->request_limit, 0);
purge_requests(hostdata, DID_ERROR); purge_requests(hostdata, DID_ERROR);
hostdata->reset_crq = 1; hostdata->action = IBMVSCSI_HOST_ACTION_RESET;
wake_up(&hostdata->work_wait_q); wake_up(&hostdata->work_wait_q);
} }
...@@ -1797,7 +1797,7 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq, ...@@ -1797,7 +1797,7 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq,
/* We need to re-setup the interpartition connection */ /* We need to re-setup the interpartition connection */
dev_info(hostdata->dev, "Re-enabling adapter!\n"); dev_info(hostdata->dev, "Re-enabling adapter!\n");
hostdata->client_migrated = 1; hostdata->client_migrated = 1;
hostdata->reenable_crq = 1; hostdata->action = IBMVSCSI_HOST_ACTION_REENABLE;
purge_requests(hostdata, DID_REQUEUE); purge_requests(hostdata, DID_REQUEUE);
wake_up(&hostdata->work_wait_q); wake_up(&hostdata->work_wait_q);
} else { } else {
...@@ -2116,48 +2116,71 @@ static unsigned long ibmvscsi_get_desired_dma(struct vio_dev *vdev) ...@@ -2116,48 +2116,71 @@ static unsigned long ibmvscsi_get_desired_dma(struct vio_dev *vdev)
static void ibmvscsi_do_work(struct ibmvscsi_host_data *hostdata) static void ibmvscsi_do_work(struct ibmvscsi_host_data *hostdata)
{ {
unsigned long flags;
int rc; int rc;
char *action = "reset"; char *action = "reset";
if (hostdata->reset_crq) { spin_lock_irqsave(hostdata->host->host_lock, flags);
smp_rmb(); switch (hostdata->action) {
hostdata->reset_crq = 0; case IBMVSCSI_HOST_ACTION_NONE:
break;
case IBMVSCSI_HOST_ACTION_RESET:
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
rc = ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata); rc = ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata);
spin_lock_irqsave(hostdata->host->host_lock, flags);
if (!rc) if (!rc)
rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0); rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0);
vio_enable_interrupts(to_vio_dev(hostdata->dev)); vio_enable_interrupts(to_vio_dev(hostdata->dev));
} else if (hostdata->reenable_crq) { break;
smp_rmb(); case IBMVSCSI_HOST_ACTION_REENABLE:
action = "enable"; action = "enable";
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
rc = ibmvscsi_reenable_crq_queue(&hostdata->queue, hostdata); rc = ibmvscsi_reenable_crq_queue(&hostdata->queue, hostdata);
hostdata->reenable_crq = 0; spin_lock_irqsave(hostdata->host->host_lock, flags);
if (!rc) if (!rc)
rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0); rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0);
} else break;
return; default:
break;
}
hostdata->action = IBMVSCSI_HOST_ACTION_NONE;
if (rc) { if (rc) {
atomic_set(&hostdata->request_limit, -1); atomic_set(&hostdata->request_limit, -1);
dev_err(hostdata->dev, "error after %s\n", action); dev_err(hostdata->dev, "error after %s\n", action);
} }
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
scsi_unblock_requests(hostdata->host); scsi_unblock_requests(hostdata->host);
} }
static int ibmvscsi_work_to_do(struct ibmvscsi_host_data *hostdata) static int __ibmvscsi_work_to_do(struct ibmvscsi_host_data *hostdata)
{ {
if (kthread_should_stop()) if (kthread_should_stop())
return 1; return 1;
else if (hostdata->reset_crq) { switch (hostdata->action) {
smp_rmb(); case IBMVSCSI_HOST_ACTION_NONE:
return 1; return 0;
} else if (hostdata->reenable_crq) { case IBMVSCSI_HOST_ACTION_RESET:
smp_rmb(); case IBMVSCSI_HOST_ACTION_REENABLE:
return 1; default:
break;
} }
return 0; return 1;
}
static int ibmvscsi_work_to_do(struct ibmvscsi_host_data *hostdata)
{
unsigned long flags;
int rc;
spin_lock_irqsave(hostdata->host->host_lock, flags);
rc = __ibmvscsi_work_to_do(hostdata);
spin_unlock_irqrestore(hostdata->host->host_lock, flags);
return rc;
} }
static int ibmvscsi_work(void *data) static int ibmvscsi_work(void *data)
......
...@@ -88,13 +88,18 @@ struct event_pool { ...@@ -88,13 +88,18 @@ struct event_pool {
dma_addr_t iu_token; dma_addr_t iu_token;
}; };
enum ibmvscsi_host_action {
IBMVSCSI_HOST_ACTION_NONE = 0,
IBMVSCSI_HOST_ACTION_RESET,
IBMVSCSI_HOST_ACTION_REENABLE,
};
/* all driver data associated with a host adapter */ /* all driver data associated with a host adapter */
struct ibmvscsi_host_data { struct ibmvscsi_host_data {
struct list_head host_list; struct list_head host_list;
atomic_t request_limit; atomic_t request_limit;
int client_migrated; int client_migrated;
int reset_crq; enum ibmvscsi_host_action action;
int reenable_crq;
struct device *dev; struct device *dev;
struct event_pool pool; struct event_pool pool;
struct crq_queue queue; struct crq_queue queue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment