diff options
author | Tyrel Datwyler <tyreld@linux.vnet.ibm.com> | 2019-05-02 20:50:57 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-06-18 19:46:22 -0400 |
commit | 6e40de8b6b3cfa7288bb4a1fee2c7173f53b7345 (patch) | |
tree | 6f10eb57dfa2a5f0e0d46a1b13bd3ebac7a6d203 | |
parent | 2e22520475037f97b5a3234591183105ecf9845b (diff) |
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: Tyrel Datwyler <tyreld@linux.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 61 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.h | 9 |
2 files changed, 49 insertions, 21 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 65fc8ca962c5..8df82c58e7b9 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -828,7 +828,7 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) | |||
828 | atomic_set(&hostdata->request_limit, 0); | 828 | atomic_set(&hostdata->request_limit, 0); |
829 | 829 | ||
830 | purge_requests(hostdata, DID_ERROR); | 830 | purge_requests(hostdata, DID_ERROR); |
831 | hostdata->reset_crq = 1; | 831 | hostdata->action = IBMVSCSI_HOST_ACTION_RESET; |
832 | wake_up(&hostdata->work_wait_q); | 832 | wake_up(&hostdata->work_wait_q); |
833 | } | 833 | } |
834 | 834 | ||
@@ -1797,7 +1797,7 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1797 | /* We need to re-setup the interpartition connection */ | 1797 | /* We need to re-setup the interpartition connection */ |
1798 | dev_info(hostdata->dev, "Re-enabling adapter!\n"); | 1798 | dev_info(hostdata->dev, "Re-enabling adapter!\n"); |
1799 | hostdata->client_migrated = 1; | 1799 | hostdata->client_migrated = 1; |
1800 | hostdata->reenable_crq = 1; | 1800 | hostdata->action = IBMVSCSI_HOST_ACTION_REENABLE; |
1801 | purge_requests(hostdata, DID_REQUEUE); | 1801 | purge_requests(hostdata, DID_REQUEUE); |
1802 | wake_up(&hostdata->work_wait_q); | 1802 | wake_up(&hostdata->work_wait_q); |
1803 | } else { | 1803 | } else { |
@@ -2116,48 +2116,71 @@ static unsigned long ibmvscsi_get_desired_dma(struct vio_dev *vdev) | |||
2116 | 2116 | ||
2117 | static void ibmvscsi_do_work(struct ibmvscsi_host_data *hostdata) | 2117 | static void ibmvscsi_do_work(struct ibmvscsi_host_data *hostdata) |
2118 | { | 2118 | { |
2119 | unsigned long flags; | ||
2119 | int rc; | 2120 | int rc; |
2120 | char *action = "reset"; | 2121 | char *action = "reset"; |
2121 | 2122 | ||
2122 | if (hostdata->reset_crq) { | 2123 | spin_lock_irqsave(hostdata->host->host_lock, flags); |
2123 | smp_rmb(); | 2124 | switch (hostdata->action) { |
2124 | hostdata->reset_crq = 0; | 2125 | case IBMVSCSI_HOST_ACTION_NONE: |
2125 | 2126 | break; | |
2127 | case IBMVSCSI_HOST_ACTION_RESET: | ||
2128 | spin_unlock_irqrestore(hostdata->host->host_lock, flags); | ||
2126 | rc = ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata); | 2129 | rc = ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata); |
2130 | spin_lock_irqsave(hostdata->host->host_lock, flags); | ||
2127 | if (!rc) | 2131 | if (!rc) |
2128 | rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0); | 2132 | rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0); |
2129 | vio_enable_interrupts(to_vio_dev(hostdata->dev)); | 2133 | vio_enable_interrupts(to_vio_dev(hostdata->dev)); |
2130 | } else if (hostdata->reenable_crq) { | 2134 | break; |
2131 | smp_rmb(); | 2135 | case IBMVSCSI_HOST_ACTION_REENABLE: |
2132 | action = "enable"; | 2136 | action = "enable"; |
2137 | spin_unlock_irqrestore(hostdata->host->host_lock, flags); | ||
2133 | rc = ibmvscsi_reenable_crq_queue(&hostdata->queue, hostdata); | 2138 | rc = ibmvscsi_reenable_crq_queue(&hostdata->queue, hostdata); |
2134 | hostdata->reenable_crq = 0; | 2139 | spin_lock_irqsave(hostdata->host->host_lock, flags); |
2135 | if (!rc) | 2140 | if (!rc) |
2136 | rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0); | 2141 | rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0); |
2137 | } else | 2142 | break; |
2138 | return; | 2143 | default: |
2144 | break; | ||
2145 | } | ||
2146 | |||
2147 | hostdata->action = IBMVSCSI_HOST_ACTION_NONE; | ||
2139 | 2148 | ||
2140 | if (rc) { | 2149 | if (rc) { |
2141 | atomic_set(&hostdata->request_limit, -1); | 2150 | atomic_set(&hostdata->request_limit, -1); |
2142 | dev_err(hostdata->dev, "error after %s\n", action); | 2151 | dev_err(hostdata->dev, "error after %s\n", action); |
2143 | } | 2152 | } |
2153 | spin_unlock_irqrestore(hostdata->host->host_lock, flags); | ||
2144 | 2154 | ||
2145 | scsi_unblock_requests(hostdata->host); | 2155 | scsi_unblock_requests(hostdata->host); |
2146 | } | 2156 | } |
2147 | 2157 | ||
2148 | static int ibmvscsi_work_to_do(struct ibmvscsi_host_data *hostdata) | 2158 | static int __ibmvscsi_work_to_do(struct ibmvscsi_host_data *hostdata) |
2149 | { | 2159 | { |
2150 | if (kthread_should_stop()) | 2160 | if (kthread_should_stop()) |
2151 | return 1; | 2161 | return 1; |
2152 | else if (hostdata->reset_crq) { | 2162 | switch (hostdata->action) { |
2153 | smp_rmb(); | 2163 | case IBMVSCSI_HOST_ACTION_NONE: |
2154 | return 1; | 2164 | return 0; |
2155 | } else if (hostdata->reenable_crq) { | 2165 | case IBMVSCSI_HOST_ACTION_RESET: |
2156 | smp_rmb(); | 2166 | case IBMVSCSI_HOST_ACTION_REENABLE: |
2157 | return 1; | 2167 | default: |
2168 | break; | ||
2158 | } | 2169 | } |
2159 | 2170 | ||
2160 | return 0; | 2171 | return 1; |
2172 | } | ||
2173 | |||
2174 | static int ibmvscsi_work_to_do(struct ibmvscsi_host_data *hostdata) | ||
2175 | { | ||
2176 | unsigned long flags; | ||
2177 | int rc; | ||
2178 | |||
2179 | spin_lock_irqsave(hostdata->host->host_lock, flags); | ||
2180 | rc = __ibmvscsi_work_to_do(hostdata); | ||
2181 | spin_unlock_irqrestore(hostdata->host->host_lock, flags); | ||
2182 | |||
2183 | return rc; | ||
2161 | } | 2184 | } |
2162 | 2185 | ||
2163 | static int ibmvscsi_work(void *data) | 2186 | static int ibmvscsi_work(void *data) |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 3a7875575616..04bcbc832dc9 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h | |||
@@ -88,13 +88,18 @@ struct event_pool { | |||
88 | dma_addr_t iu_token; | 88 | dma_addr_t iu_token; |
89 | }; | 89 | }; |
90 | 90 | ||
91 | enum ibmvscsi_host_action { | ||
92 | IBMVSCSI_HOST_ACTION_NONE = 0, | ||
93 | IBMVSCSI_HOST_ACTION_RESET, | ||
94 | IBMVSCSI_HOST_ACTION_REENABLE, | ||
95 | }; | ||
96 | |||
91 | /* all driver data associated with a host adapter */ | 97 | /* all driver data associated with a host adapter */ |
92 | struct ibmvscsi_host_data { | 98 | struct ibmvscsi_host_data { |
93 | struct list_head host_list; | 99 | struct list_head host_list; |
94 | atomic_t request_limit; | 100 | atomic_t request_limit; |
95 | int client_migrated; | 101 | int client_migrated; |
96 | int reset_crq; | 102 | enum ibmvscsi_host_action action; |
97 | int reenable_crq; | ||
98 | struct device *dev; | 103 | struct device *dev; |
99 | struct event_pool pool; | 104 | struct event_pool pool; |
100 | struct crq_queue queue; | 105 | struct crq_queue queue; |