diff options
| -rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 82 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 36 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 3 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 4 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 2 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 17 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 4 |
7 files changed, 59 insertions, 89 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 49d5fc729bef..324899c96efe 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
| @@ -118,97 +118,32 @@ _zfcp_hex_dump(char *addr, int count) | |||
| 118 | 118 | ||
| 119 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF | 119 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF |
| 120 | 120 | ||
| 121 | static int zfcp_reqlist_init(struct zfcp_adapter *adapter) | 121 | static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) |
| 122 | { | 122 | { |
| 123 | int i; | 123 | int idx; |
| 124 | 124 | ||
| 125 | adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head), | 125 | adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head), |
| 126 | GFP_KERNEL); | 126 | GFP_KERNEL); |
| 127 | |||
| 128 | if (!adapter->req_list) | 127 | if (!adapter->req_list) |
| 129 | return -ENOMEM; | 128 | return -ENOMEM; |
| 130 | 129 | ||
| 131 | for (i=0; i<REQUEST_LIST_SIZE; i++) | 130 | for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) |
| 132 | INIT_LIST_HEAD(&adapter->req_list[i]); | 131 | INIT_LIST_HEAD(&adapter->req_list[idx]); |
| 133 | |||
| 134 | return 0; | 132 | return 0; |
| 135 | } | 133 | } |
| 136 | 134 | ||
| 137 | static void zfcp_reqlist_free(struct zfcp_adapter *adapter) | 135 | static void zfcp_reqlist_free(struct zfcp_adapter *adapter) |
| 138 | { | 136 | { |
| 139 | struct zfcp_fsf_req *request, *tmp; | ||
| 140 | unsigned int i; | ||
| 141 | |||
| 142 | for (i=0; i<REQUEST_LIST_SIZE; i++) { | ||
| 143 | if (list_empty(&adapter->req_list[i])) | ||
| 144 | continue; | ||
| 145 | |||
| 146 | list_for_each_entry_safe(request, tmp, | ||
| 147 | &adapter->req_list[i], list) | ||
| 148 | list_del(&request->list); | ||
| 149 | } | ||
| 150 | |||
| 151 | kfree(adapter->req_list); | 137 | kfree(adapter->req_list); |
| 152 | } | 138 | } |
| 153 | 139 | ||
| 154 | void zfcp_reqlist_add(struct zfcp_adapter *adapter, | ||
| 155 | struct zfcp_fsf_req *fsf_req) | ||
| 156 | { | ||
| 157 | unsigned int i; | ||
| 158 | |||
| 159 | i = fsf_req->req_id % REQUEST_LIST_SIZE; | ||
| 160 | list_add_tail(&fsf_req->list, &adapter->req_list[i]); | ||
| 161 | } | ||
| 162 | |||
| 163 | void zfcp_reqlist_remove(struct zfcp_adapter *adapter, unsigned long req_id) | ||
| 164 | { | ||
| 165 | struct zfcp_fsf_req *request, *tmp; | ||
| 166 | unsigned int i, counter; | ||
| 167 | u64 dbg_tmp[2]; | ||
| 168 | |||
| 169 | i = req_id % REQUEST_LIST_SIZE; | ||
| 170 | BUG_ON(list_empty(&adapter->req_list[i])); | ||
| 171 | |||
| 172 | counter = 0; | ||
| 173 | list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) { | ||
| 174 | if (request->req_id == req_id) { | ||
| 175 | dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active); | ||
| 176 | dbg_tmp[1] = (u64) counter; | ||
| 177 | debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16); | ||
| 178 | list_del(&request->list); | ||
| 179 | break; | ||
| 180 | } | ||
| 181 | counter++; | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *adapter, | ||
| 186 | unsigned long req_id) | ||
| 187 | { | ||
| 188 | struct zfcp_fsf_req *request, *tmp; | ||
| 189 | unsigned int i; | ||
| 190 | |||
| 191 | /* 0 is reserved as an invalid req_id */ | ||
| 192 | if (req_id == 0) | ||
| 193 | return NULL; | ||
| 194 | |||
| 195 | i = req_id % REQUEST_LIST_SIZE; | ||
| 196 | |||
| 197 | list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) | ||
| 198 | if (request->req_id == req_id) | ||
| 199 | return request; | ||
| 200 | |||
| 201 | return NULL; | ||
| 202 | } | ||
| 203 | |||
| 204 | int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) | 140 | int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) |
| 205 | { | 141 | { |
| 206 | unsigned int i; | 142 | unsigned int idx; |
| 207 | 143 | ||
| 208 | for (i=0; i<REQUEST_LIST_SIZE; i++) | 144 | for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) |
| 209 | if (!list_empty(&adapter->req_list[i])) | 145 | if (!list_empty(&adapter->req_list[idx])) |
| 210 | return 0; | 146 | return 0; |
| 211 | |||
| 212 | return 1; | 147 | return 1; |
| 213 | } | 148 | } |
| 214 | 149 | ||
| @@ -1106,7 +1041,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
| 1106 | 1041 | ||
| 1107 | /* initialize list of fsf requests */ | 1042 | /* initialize list of fsf requests */ |
| 1108 | spin_lock_init(&adapter->req_list_lock); | 1043 | spin_lock_init(&adapter->req_list_lock); |
| 1109 | retval = zfcp_reqlist_init(adapter); | 1044 | retval = zfcp_reqlist_alloc(adapter); |
| 1110 | if (retval) { | 1045 | if (retval) { |
| 1111 | ZFCP_LOG_INFO("request list initialization failed\n"); | 1046 | ZFCP_LOG_INFO("request list initialization failed\n"); |
| 1112 | goto failed_low_mem_buffers; | 1047 | goto failed_low_mem_buffers; |
| @@ -1167,6 +1102,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
| 1167 | zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); | 1102 | zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); |
| 1168 | sysfs_failed: | 1103 | sysfs_failed: |
| 1169 | dev_set_drvdata(&ccw_device->dev, NULL); | 1104 | dev_set_drvdata(&ccw_device->dev, NULL); |
| 1105 | zfcp_reqlist_free(adapter); | ||
| 1170 | failed_low_mem_buffers: | 1106 | failed_low_mem_buffers: |
| 1171 | zfcp_free_low_mem_buffers(adapter); | 1107 | zfcp_free_low_mem_buffers(adapter); |
| 1172 | if (qdio_free(ccw_device) != 0) | 1108 | if (qdio_free(ccw_device) != 0) |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 07b0957b82f3..22649639230b 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
| @@ -1090,6 +1090,42 @@ extern void _zfcp_hex_dump(char *, int); | |||
| 1090 | #define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port)) | 1090 | #define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port)) |
| 1091 | 1091 | ||
| 1092 | /* | 1092 | /* |
| 1093 | * Helper functions for request ID management. | ||
| 1094 | */ | ||
| 1095 | static inline int zfcp_reqlist_hash(unsigned long req_id) | ||
| 1096 | { | ||
| 1097 | return req_id % REQUEST_LIST_SIZE; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | static inline void zfcp_reqlist_add(struct zfcp_adapter *adapter, | ||
| 1101 | struct zfcp_fsf_req *fsf_req) | ||
| 1102 | { | ||
| 1103 | unsigned int idx; | ||
| 1104 | |||
| 1105 | idx = zfcp_reqlist_hash(fsf_req->req_id); | ||
| 1106 | list_add_tail(&fsf_req->list, &adapter->req_list[idx]); | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | static inline void zfcp_reqlist_remove(struct zfcp_adapter *adapter, | ||
| 1110 | struct zfcp_fsf_req *fsf_req) | ||
| 1111 | { | ||
| 1112 | list_del(&fsf_req->list); | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | static inline struct zfcp_fsf_req * | ||
| 1116 | zfcp_reqlist_find(struct zfcp_adapter *adapter, unsigned long req_id) | ||
| 1117 | { | ||
| 1118 | struct zfcp_fsf_req *request; | ||
| 1119 | unsigned int idx; | ||
| 1120 | |||
| 1121 | idx = zfcp_reqlist_hash(req_id); | ||
| 1122 | list_for_each_entry(request, &adapter->req_list[idx], list) | ||
| 1123 | if (request->req_id == req_id) | ||
| 1124 | return request; | ||
| 1125 | return NULL; | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | /* | ||
| 1093 | * functions needed for reference/usage counting | 1129 | * functions needed for reference/usage counting |
| 1094 | */ | 1130 | */ |
| 1095 | 1131 | ||
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 885572300589..e2a3d6fe1651 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
| @@ -847,8 +847,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | |||
| 847 | if (erp_action->fsf_req) { | 847 | if (erp_action->fsf_req) { |
| 848 | /* take lock to ensure that request is not deleted meanwhile */ | 848 | /* take lock to ensure that request is not deleted meanwhile */ |
| 849 | spin_lock(&adapter->req_list_lock); | 849 | spin_lock(&adapter->req_list_lock); |
| 850 | if (zfcp_reqlist_ismember(adapter, | 850 | if (zfcp_reqlist_find(adapter, erp_action->fsf_req->req_id)) { |
| 851 | erp_action->fsf_req->req_id)) { | ||
| 852 | /* fsf_req still exists */ | 851 | /* fsf_req still exists */ |
| 853 | debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); | 852 | debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); |
| 854 | debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req, | 853 | debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req, |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 01386ac688a2..991d45667a44 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
| @@ -184,10 +184,6 @@ extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, | |||
| 184 | unsigned long); | 184 | unsigned long); |
| 185 | extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, | 185 | extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, |
| 186 | struct scsi_cmnd *); | 186 | struct scsi_cmnd *); |
| 187 | extern void zfcp_reqlist_add(struct zfcp_adapter *, struct zfcp_fsf_req *); | ||
| 188 | extern void zfcp_reqlist_remove(struct zfcp_adapter *, unsigned long); | ||
| 189 | extern struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *, | ||
| 190 | unsigned long); | ||
| 191 | extern int zfcp_reqlist_isempty(struct zfcp_adapter *); | 187 | extern int zfcp_reqlist_isempty(struct zfcp_adapter *); |
| 192 | 188 | ||
| 193 | #endif /* ZFCP_EXT_H */ | 189 | #endif /* ZFCP_EXT_H */ |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 07094c3dc341..083308b1d3e2 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
| @@ -4787,7 +4787,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) | |||
| 4787 | retval = -EIO; | 4787 | retval = -EIO; |
| 4788 | del_timer(&fsf_req->timer); | 4788 | del_timer(&fsf_req->timer); |
| 4789 | spin_lock(&adapter->req_list_lock); | 4789 | spin_lock(&adapter->req_list_lock); |
| 4790 | zfcp_reqlist_remove(adapter, fsf_req->req_id); | 4790 | zfcp_reqlist_remove(adapter, fsf_req); |
| 4791 | spin_unlock(&adapter->req_list_lock); | 4791 | spin_unlock(&adapter->req_list_lock); |
| 4792 | /* undo changes in request queue made for this request */ | 4792 | /* undo changes in request queue made for this request */ |
| 4793 | zfcp_qdio_zero_sbals(req_queue->buffer, | 4793 | zfcp_qdio_zero_sbals(req_queue->buffer, |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index e50e6ad4e6cb..cb08ca3cc0f9 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
| @@ -283,7 +283,7 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device, | |||
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | /** | 285 | /** |
| 286 | * zfcp_qdio_reqid_check - checks for valid reqids or unsolicited status | 286 | * zfcp_qdio_reqid_check - checks for valid reqids. |
| 287 | */ | 287 | */ |
| 288 | static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, | 288 | static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, |
| 289 | unsigned long req_id) | 289 | unsigned long req_id) |
| @@ -294,14 +294,17 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, | |||
| 294 | debug_long_event(adapter->erp_dbf, 4, req_id); | 294 | debug_long_event(adapter->erp_dbf, 4, req_id); |
| 295 | 295 | ||
| 296 | spin_lock_irqsave(&adapter->req_list_lock, flags); | 296 | spin_lock_irqsave(&adapter->req_list_lock, flags); |
| 297 | fsf_req = zfcp_reqlist_ismember(adapter, req_id); | 297 | fsf_req = zfcp_reqlist_find(adapter, req_id); |
| 298 | 298 | ||
| 299 | if (!fsf_req) { | 299 | if (!fsf_req) |
| 300 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); | 300 | /* |
| 301 | panic("error: unknown request id (%ld).\n", req_id); | 301 | * Unknown request means that we have potentially memory |
| 302 | } | 302 | * corruption and must stop the machine immediatly. |
| 303 | */ | ||
| 304 | panic("error: unknown request id (%ld) on adapter %s.\n", | ||
| 305 | req_id, zfcp_get_busid_by_adapter(adapter)); | ||
| 303 | 306 | ||
| 304 | zfcp_reqlist_remove(adapter, req_id); | 307 | zfcp_reqlist_remove(adapter, fsf_req); |
| 305 | atomic_dec(&adapter->reqs_active); | 308 | atomic_dec(&adapter->reqs_active); |
| 306 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); | 309 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); |
| 307 | 310 | ||
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index e742b3de16ac..16e2d64658af 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
| @@ -407,8 +407,8 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
| 407 | 407 | ||
| 408 | /* Check whether corresponding fsf_req is still pending */ | 408 | /* Check whether corresponding fsf_req is still pending */ |
| 409 | spin_lock(&adapter->req_list_lock); | 409 | spin_lock(&adapter->req_list_lock); |
| 410 | fsf_req = zfcp_reqlist_ismember(adapter, (unsigned long) | 410 | fsf_req = zfcp_reqlist_find(adapter, |
| 411 | scpnt->host_scribble); | 411 | (unsigned long) scpnt->host_scribble); |
| 412 | spin_unlock(&adapter->req_list_lock); | 412 | spin_unlock(&adapter->req_list_lock); |
| 413 | if (!fsf_req) { | 413 | if (!fsf_req) { |
| 414 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 414 | write_unlock_irqrestore(&adapter->abort_lock, flags); |
