aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorVolker Sameske <sameske@de.ibm.com>2006-08-02 05:05:16 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-08-06 12:31:00 -0400
commitfea9d6c7bcd8ff1d60ff74f27ba483b3820b18a3 (patch)
tree9fd3c531809f5b7a275540e5467a59e50b6630b7 /drivers/s390
parentc2602c48b5ebde55b418ba252737bf60caa4bab0 (diff)
[SCSI] zfcp: improve management of request IDs
Improve request handling. Use hash table to manage request IDs. Signed-off-by: Volker Sameske <sameske@de.ibm.com> Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c120
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c5
-rw-r--r--drivers/s390/scsi/zfcp_def.h11
-rw-r--r--drivers/s390/scsi/zfcp_erp.c16
-rw-r--r--drivers/s390/scsi/zfcp_ext.h6
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c122
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c79
7 files changed, 231 insertions, 128 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 9cd789b8acd4..adc9d8f2c28f 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -112,6 +112,105 @@ _zfcp_hex_dump(char *addr, int count)
112 printk("\n"); 112 printk("\n");
113} 113}
114 114
115
116/****************************************************************/
117/****** Functions to handle the request ID hash table ********/
118/****************************************************************/
119
120#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF
121
122static int zfcp_reqlist_init(struct zfcp_adapter *adapter)
123{
124 int i;
125
126 adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head),
127 GFP_KERNEL);
128
129 if (!adapter->req_list)
130 return -ENOMEM;
131
132 for (i=0; i<REQUEST_LIST_SIZE; i++)
133 INIT_LIST_HEAD(&adapter->req_list[i]);
134
135 return 0;
136}
137
138static void zfcp_reqlist_free(struct zfcp_adapter *adapter)
139{
140 struct zfcp_fsf_req *request, *tmp;
141 unsigned int i;
142
143 for (i=0; i<REQUEST_LIST_SIZE; i++) {
144 if (list_empty(&adapter->req_list[i]))
145 continue;
146
147 list_for_each_entry_safe(request, tmp,
148 &adapter->req_list[i], list)
149 list_del(&request->list);
150 }
151
152 kfree(adapter->req_list);
153}
154
155void zfcp_reqlist_add(struct zfcp_adapter *adapter,
156 struct zfcp_fsf_req *fsf_req)
157{
158 unsigned int i;
159
160 i = fsf_req->req_id % REQUEST_LIST_SIZE;
161 list_add_tail(&fsf_req->list, &adapter->req_list[i]);
162}
163
164void zfcp_reqlist_remove(struct zfcp_adapter *adapter, unsigned long req_id)
165{
166 struct zfcp_fsf_req *request, *tmp;
167 unsigned int i, counter;
168 u64 dbg_tmp[2];
169
170 i = req_id % REQUEST_LIST_SIZE;
171 BUG_ON(list_empty(&adapter->req_list[i]));
172
173 counter = 0;
174 list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) {
175 if (request->req_id == req_id) {
176 dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
177 dbg_tmp[1] = (u64) counter;
178 debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
179 list_del(&request->list);
180 break;
181 }
182 counter++;
183 }
184}
185
186struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *adapter,
187 unsigned long req_id)
188{
189 struct zfcp_fsf_req *request, *tmp;
190 unsigned int i;
191
192 i = req_id % REQUEST_LIST_SIZE;
193
194 list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list)
195 if (request->req_id == req_id)
196 return request;
197
198 return NULL;
199}
200
201int zfcp_reqlist_isempty(struct zfcp_adapter *adapter)
202{
203 unsigned int i;
204
205 for (i=0; i<REQUEST_LIST_SIZE; i++)
206 if (!list_empty(&adapter->req_list[i]))
207 return 0;
208
209 return 1;
210}
211
212#undef ZFCP_LOG_AREA
213
115/****************************************************************/ 214/****************************************************************/
116/************** Uncategorised Functions *************************/ 215/************** Uncategorised Functions *************************/
117/****************************************************************/ 216/****************************************************************/
@@ -961,8 +1060,12 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
961 INIT_LIST_HEAD(&adapter->port_remove_lh); 1060 INIT_LIST_HEAD(&adapter->port_remove_lh);
962 1061
963 /* initialize list of fsf requests */ 1062 /* initialize list of fsf requests */
964 spin_lock_init(&adapter->fsf_req_list_lock); 1063 spin_lock_init(&adapter->req_list_lock);
965 INIT_LIST_HEAD(&adapter->fsf_req_list_head); 1064 retval = zfcp_reqlist_init(adapter);
1065 if (retval) {
1066 ZFCP_LOG_INFO("request list initialization failed\n");
1067 goto failed_low_mem_buffers;
1068 }
966 1069
967 /* initialize debug locks */ 1070 /* initialize debug locks */
968 1071
@@ -1041,8 +1144,6 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
1041 * !0 - struct zfcp_adapter data structure could not be removed 1144 * !0 - struct zfcp_adapter data structure could not be removed
1042 * (e.g. still used) 1145 * (e.g. still used)
1043 * locks: adapter list write lock is assumed to be held by caller 1146 * locks: adapter list write lock is assumed to be held by caller
1044 * adapter->fsf_req_list_lock is taken and released within this
1045 * function and must not be held on entry
1046 */ 1147 */
1047void 1148void
1048zfcp_adapter_dequeue(struct zfcp_adapter *adapter) 1149zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
@@ -1054,14 +1155,14 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
1054 zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); 1155 zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
1055 dev_set_drvdata(&adapter->ccw_device->dev, NULL); 1156 dev_set_drvdata(&adapter->ccw_device->dev, NULL);
1056 /* sanity check: no pending FSF requests */ 1157 /* sanity check: no pending FSF requests */
1057 spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); 1158 spin_lock_irqsave(&adapter->req_list_lock, flags);
1058 retval = !list_empty(&adapter->fsf_req_list_head); 1159 retval = zfcp_reqlist_isempty(adapter);
1059 spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); 1160 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
1060 if (retval) { 1161 if (!retval) {
1061 ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, " 1162 ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, "
1062 "%i requests outstanding\n", 1163 "%i requests outstanding\n",
1063 zfcp_get_busid_by_adapter(adapter), adapter, 1164 zfcp_get_busid_by_adapter(adapter), adapter,
1064 atomic_read(&adapter->fsf_reqs_active)); 1165 atomic_read(&adapter->reqs_active));
1065 retval = -EBUSY; 1166 retval = -EBUSY;
1066 goto out; 1167 goto out;
1067 } 1168 }
@@ -1087,6 +1188,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
1087 zfcp_free_low_mem_buffers(adapter); 1188 zfcp_free_low_mem_buffers(adapter);
1088 /* free memory of adapter data structure and queues */ 1189 /* free memory of adapter data structure and queues */
1089 zfcp_qdio_free_queues(adapter); 1190 zfcp_qdio_free_queues(adapter);
1191 zfcp_reqlist_free(adapter);
1090 kfree(adapter->fc_stats); 1192 kfree(adapter->fc_stats);
1091 kfree(adapter->stats_reset_data); 1193 kfree(adapter->stats_reset_data);
1092 ZFCP_LOG_TRACE("freeing adapter structure\n"); 1194 ZFCP_LOG_TRACE("freeing adapter structure\n");
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 57d8e4bfb8d9..fdabadeaa9ee 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -164,6 +164,11 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
164 retval = zfcp_adapter_scsi_register(adapter); 164 retval = zfcp_adapter_scsi_register(adapter);
165 if (retval) 165 if (retval)
166 goto out_scsi_register; 166 goto out_scsi_register;
167
168 /* initialize request counter */
169 BUG_ON(!zfcp_reqlist_isempty(adapter));
170 adapter->req_no = 0;
171
167 zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING, 172 zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING,
168 ZFCP_SET); 173 ZFCP_SET);
169 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED); 174 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 2df512a18e2c..72293f3870b5 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -886,11 +886,11 @@ struct zfcp_adapter {
886 struct list_head port_remove_lh; /* head of ports to be 886 struct list_head port_remove_lh; /* head of ports to be
887 removed */ 887 removed */
888 u32 ports; /* number of remote ports */ 888 u32 ports; /* number of remote ports */
889 struct timer_list scsi_er_timer; /* SCSI err recovery watch */ 889 struct timer_list scsi_er_timer; /* SCSI err recovery watch */
890 struct list_head fsf_req_list_head; /* head of FSF req list */ 890 atomic_t reqs_active; /* # active FSF reqs */
891 spinlock_t fsf_req_list_lock; /* lock for ops on list of 891 unsigned long req_no; /* unique FSF req number */
892 FSF requests */ 892 struct list_head *req_list; /* list of pending reqs */
893 atomic_t fsf_reqs_active; /* # active FSF reqs */ 893 spinlock_t req_list_lock; /* request list lock */
894 struct zfcp_qdio_queue request_queue; /* request queue */ 894 struct zfcp_qdio_queue request_queue; /* request queue */
895 u32 fsf_req_seq_no; /* FSF cmnd seq number */ 895 u32 fsf_req_seq_no; /* FSF cmnd seq number */
896 wait_queue_head_t request_wq; /* can be used to wait for 896 wait_queue_head_t request_wq; /* can be used to wait for
@@ -986,6 +986,7 @@ struct zfcp_unit {
986/* FSF request */ 986/* FSF request */
987struct zfcp_fsf_req { 987struct zfcp_fsf_req {
988 struct list_head list; /* list of FSF requests */ 988 struct list_head list; /* list of FSF requests */
989 unsigned long req_id; /* unique request ID */
989 struct zfcp_adapter *adapter; /* adapter request belongs to */ 990 struct zfcp_adapter *adapter; /* adapter request belongs to */
990 u8 sbal_number; /* nr of SBALs free for use */ 991 u8 sbal_number; /* nr of SBALs free for use */
991 u8 sbal_first; /* first SBAL for this request */ 992 u8 sbal_first; /* first SBAL for this request */
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 8ec8da0beaa8..f74412bd9d6a 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -848,18 +848,16 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
848 struct zfcp_adapter *adapter = erp_action->adapter; 848 struct zfcp_adapter *adapter = erp_action->adapter;
849 849
850 if (erp_action->fsf_req) { 850 if (erp_action->fsf_req) {
851 /* take lock to ensure that request is not being deleted meanwhile */ 851 /* take lock to ensure that request is not deleted meanwhile */
852 spin_lock(&adapter->fsf_req_list_lock); 852 spin_lock(&adapter->req_list_lock);
853 /* check whether fsf req does still exist */ 853 if ((!zfcp_reqlist_ismember(adapter,
854 list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list) 854 erp_action->fsf_req->req_id)) &&
855 if (fsf_req == erp_action->fsf_req) 855 (fsf_req->erp_action == erp_action)) {
856 break;
857 if (fsf_req && (fsf_req->erp_action == erp_action)) {
858 /* fsf_req still exists */ 856 /* fsf_req still exists */
859 debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); 857 debug_text_event(adapter->erp_dbf, 3, "a_ca_req");
860 debug_event(adapter->erp_dbf, 3, &fsf_req, 858 debug_event(adapter->erp_dbf, 3, &fsf_req,
861 sizeof (unsigned long)); 859 sizeof (unsigned long));
862 /* dismiss fsf_req of timed out or dismissed erp_action */ 860 /* dismiss fsf_req of timed out/dismissed erp_action */
863 if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED | 861 if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED |
864 ZFCP_STATUS_ERP_TIMEDOUT)) { 862 ZFCP_STATUS_ERP_TIMEDOUT)) {
865 debug_text_event(adapter->erp_dbf, 3, 863 debug_text_event(adapter->erp_dbf, 3,
@@ -892,7 +890,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
892 */ 890 */
893 erp_action->fsf_req = NULL; 891 erp_action->fsf_req = NULL;
894 } 892 }
895 spin_unlock(&adapter->fsf_req_list_lock); 893 spin_unlock(&adapter->req_list_lock);
896 } else 894 } else
897 debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq"); 895 debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq");
898 896
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index d02366004cdd..04bb3a9d90a8 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -63,7 +63,6 @@ extern int zfcp_qdio_allocate_queues(struct zfcp_adapter *);
63extern void zfcp_qdio_free_queues(struct zfcp_adapter *); 63extern void zfcp_qdio_free_queues(struct zfcp_adapter *);
64extern int zfcp_qdio_determine_pci(struct zfcp_qdio_queue *, 64extern int zfcp_qdio_determine_pci(struct zfcp_qdio_queue *,
65 struct zfcp_fsf_req *); 65 struct zfcp_fsf_req *);
66extern int zfcp_qdio_reqid_check(struct zfcp_adapter *, void *);
67 66
68extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req 67extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req
69 (struct zfcp_fsf_req *, int, int); 68 (struct zfcp_fsf_req *, int, int);
@@ -190,5 +189,10 @@ extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *,
190 struct zfcp_fsf_req *); 189 struct zfcp_fsf_req *);
191extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, 190extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
192 struct scsi_cmnd *); 191 struct scsi_cmnd *);
192extern void zfcp_reqlist_add(struct zfcp_adapter *, struct zfcp_fsf_req *);
193extern void zfcp_reqlist_remove(struct zfcp_adapter *, unsigned long);
194extern struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *,
195 unsigned long);
196extern int zfcp_reqlist_isempty(struct zfcp_adapter *);
193 197
194#endif /* ZFCP_EXT_H */ 198#endif /* ZFCP_EXT_H */
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 31db2b06faba..ff2eacf5ec8c 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -49,7 +49,6 @@ static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *);
49static void zfcp_fsf_link_down_info_eval(struct zfcp_adapter *, 49static void zfcp_fsf_link_down_info_eval(struct zfcp_adapter *,
50 struct fsf_link_down_info *); 50 struct fsf_link_down_info *);
51static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *); 51static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *);
52static void zfcp_fsf_req_dismiss(struct zfcp_fsf_req *);
53 52
54/* association between FSF command and FSF QTCB type */ 53/* association between FSF command and FSF QTCB type */
55static u32 fsf_qtcb_type[] = { 54static u32 fsf_qtcb_type[] = {
@@ -146,47 +145,48 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
146 kfree(fsf_req); 145 kfree(fsf_req);
147} 146}
148 147
149/* 148/**
150 * function: 149 * zfcp_fsf_req_dismiss - dismiss a single fsf request
151 *
152 * purpose:
153 *
154 * returns:
155 *
156 * note: qdio queues shall be down (no ongoing inbound processing)
157 */ 150 */
158int 151static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
159zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) 152 struct zfcp_fsf_req *fsf_req,
153 unsigned int counter)
160{ 154{
161 struct zfcp_fsf_req *fsf_req, *tmp; 155 u64 dbg_tmp[2];
162 unsigned long flags;
163 LIST_HEAD(remove_queue);
164 156
165 spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); 157 dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
166 list_splice_init(&adapter->fsf_req_list_head, &remove_queue); 158 dbg_tmp[1] = (u64) counter;
167 atomic_set(&adapter->fsf_reqs_active, 0); 159 debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
168 spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); 160 list_del(&fsf_req->list);
169 161 fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
170 list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) { 162 zfcp_fsf_req_complete(fsf_req);
171 list_del(&fsf_req->list);
172 zfcp_fsf_req_dismiss(fsf_req);
173 }
174
175 return 0;
176} 163}
177 164
178/* 165/**
179 * function: 166 * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
180 *
181 * purpose:
182 *
183 * returns:
184 */ 167 */
185static void 168int zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
186zfcp_fsf_req_dismiss(struct zfcp_fsf_req *fsf_req)
187{ 169{
188 fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; 170 struct zfcp_fsf_req *request, *tmp;
189 zfcp_fsf_req_complete(fsf_req); 171 unsigned long flags;
172 unsigned int i, counter;
173
174 spin_lock_irqsave(&adapter->req_list_lock, flags);
175 atomic_set(&adapter->reqs_active, 0);
176 for (i=0; i<REQUEST_LIST_SIZE; i++) {
177 if (list_empty(&adapter->req_list[i]))
178 continue;
179
180 counter = 0;
181 list_for_each_entry_safe(request, tmp,
182 &adapter->req_list[i], list) {
183 zfcp_fsf_req_dismiss(adapter, request, counter);
184 counter++;
185 }
186 }
187 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
188
189 return 0;
190} 190}
191 191
192/* 192/*
@@ -4592,12 +4592,14 @@ static inline void
4592zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req) 4592zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req)
4593{ 4593{
4594 if (likely(fsf_req->qtcb != NULL)) { 4594 if (likely(fsf_req->qtcb != NULL)) {
4595 fsf_req->qtcb->prefix.req_seq_no = fsf_req->adapter->fsf_req_seq_no; 4595 fsf_req->qtcb->prefix.req_seq_no =
4596 fsf_req->qtcb->prefix.req_id = (unsigned long)fsf_req; 4596 fsf_req->adapter->fsf_req_seq_no;
4597 fsf_req->qtcb->prefix.req_id = fsf_req->req_id;
4597 fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION; 4598 fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION;
4598 fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_req->fsf_command]; 4599 fsf_req->qtcb->prefix.qtcb_type =
4600 fsf_qtcb_type[fsf_req->fsf_command];
4599 fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION; 4601 fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION;
4600 fsf_req->qtcb->header.req_handle = (unsigned long)fsf_req; 4602 fsf_req->qtcb->header.req_handle = fsf_req->req_id;
4601 fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command; 4603 fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command;
4602 } 4604 }
4603} 4605}
@@ -4654,6 +4656,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
4654{ 4656{
4655 volatile struct qdio_buffer_element *sbale; 4657 volatile struct qdio_buffer_element *sbale;
4656 struct zfcp_fsf_req *fsf_req = NULL; 4658 struct zfcp_fsf_req *fsf_req = NULL;
4659 unsigned long flags;
4657 int ret = 0; 4660 int ret = 0;
4658 struct zfcp_qdio_queue *req_queue = &adapter->request_queue; 4661 struct zfcp_qdio_queue *req_queue = &adapter->request_queue;
4659 4662
@@ -4668,6 +4671,12 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
4668 4671
4669 fsf_req->adapter = adapter; 4672 fsf_req->adapter = adapter;
4670 fsf_req->fsf_command = fsf_cmd; 4673 fsf_req->fsf_command = fsf_cmd;
4674 INIT_LIST_HEAD(&fsf_req->list);
4675
4676 /* unique request id */
4677 spin_lock_irqsave(&adapter->req_list_lock, flags);
4678 fsf_req->req_id = adapter->req_no++;
4679 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
4671 4680
4672 zfcp_fsf_req_qtcb_init(fsf_req); 4681 zfcp_fsf_req_qtcb_init(fsf_req);
4673 4682
@@ -4707,7 +4716,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
4707 sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); 4716 sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
4708 4717
4709 /* setup common SBALE fields */ 4718 /* setup common SBALE fields */
4710 sbale[0].addr = fsf_req; 4719 sbale[0].addr = (void *) fsf_req->req_id;
4711 sbale[0].flags |= SBAL_FLAGS0_COMMAND; 4720 sbale[0].flags |= SBAL_FLAGS0_COMMAND;
4712 if (likely(fsf_req->qtcb != NULL)) { 4721 if (likely(fsf_req->qtcb != NULL)) {
4713 sbale[1].addr = (void *) fsf_req->qtcb; 4722 sbale[1].addr = (void *) fsf_req->qtcb;
@@ -4747,7 +4756,7 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
4747 volatile struct qdio_buffer_element *sbale; 4756 volatile struct qdio_buffer_element *sbale;
4748 int inc_seq_no; 4757 int inc_seq_no;
4749 int new_distance_from_int; 4758 int new_distance_from_int;
4750 unsigned long flags; 4759 u64 dbg_tmp[2];
4751 int retval = 0; 4760 int retval = 0;
4752 4761
4753 adapter = fsf_req->adapter; 4762 adapter = fsf_req->adapter;
@@ -4761,10 +4770,10 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
4761 ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr, 4770 ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr,
4762 sbale[1].length); 4771 sbale[1].length);
4763 4772
4764 /* put allocated FSF request at list tail */ 4773 /* put allocated FSF request into hash table */
4765 spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); 4774 spin_lock(&adapter->req_list_lock);
4766 list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head); 4775 zfcp_reqlist_add(adapter, fsf_req);
4767 spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); 4776 spin_unlock(&adapter->req_list_lock);
4768 4777
4769 inc_seq_no = (fsf_req->qtcb != NULL); 4778 inc_seq_no = (fsf_req->qtcb != NULL);
4770 4779
@@ -4803,6 +4812,10 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
4803 QDIO_FLAG_SYNC_OUTPUT, 4812 QDIO_FLAG_SYNC_OUTPUT,
4804 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL); 4813 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL);
4805 4814
4815 dbg_tmp[0] = (unsigned long) sbale[0].addr;
4816 dbg_tmp[1] = (u64) retval;
4817 debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
4818
4806 if (unlikely(retval)) { 4819 if (unlikely(retval)) {
4807 /* Queues are down..... */ 4820 /* Queues are down..... */
4808 retval = -EIO; 4821 retval = -EIO;
@@ -4812,22 +4825,17 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
4812 */ 4825 */
4813 if (timer) 4826 if (timer)
4814 del_timer(timer); 4827 del_timer(timer);
4815 spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); 4828 spin_lock(&adapter->req_list_lock);
4816 list_del(&fsf_req->list); 4829 zfcp_reqlist_remove(adapter, fsf_req->req_id);
4817 spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); 4830 spin_unlock(&adapter->req_list_lock);
4818 /* 4831 /* undo changes in request queue made for this request */
4819 * adjust the number of free SBALs in request queue as well as
4820 * position of first one
4821 */
4822 zfcp_qdio_zero_sbals(req_queue->buffer, 4832 zfcp_qdio_zero_sbals(req_queue->buffer,
4823 fsf_req->sbal_first, fsf_req->sbal_number); 4833 fsf_req->sbal_first, fsf_req->sbal_number);
4824 atomic_add(fsf_req->sbal_number, &req_queue->free_count); 4834 atomic_add(fsf_req->sbal_number, &req_queue->free_count);
4825 req_queue->free_index -= fsf_req->sbal_number; /* increase */ 4835 req_queue->free_index -= fsf_req->sbal_number;
4826 req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q; 4836 req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q;
4827 req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */ 4837 req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */
4828 ZFCP_LOG_DEBUG 4838 zfcp_erp_adapter_reopen(adapter, 0);
4829 ("error: do_QDIO failed. Buffers could not be enqueued "
4830 "to request queue.\n");
4831 } else { 4839 } else {
4832 req_queue->distance_from_int = new_distance_from_int; 4840 req_queue->distance_from_int = new_distance_from_int;
4833 /* 4841 /*
@@ -4843,7 +4851,7 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
4843 adapter->fsf_req_seq_no++; 4851 adapter->fsf_req_seq_no++;
4844 4852
4845 /* count FSF requests pending */ 4853 /* count FSF requests pending */
4846 atomic_inc(&adapter->fsf_reqs_active); 4854 atomic_inc(&adapter->reqs_active);
4847 } 4855 }
4848 return retval; 4856 return retval;
4849} 4857}
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 49ea5add4abc..dbd9f48e863e 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -282,6 +282,37 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device,
282 return; 282 return;
283} 283}
284 284
285/**
286 * zfcp_qdio_reqid_check - checks for valid reqids or unsolicited status
287 */
288static int zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
289 unsigned long req_id)
290{
291 struct zfcp_fsf_req *fsf_req;
292 unsigned long flags;
293
294 debug_long_event(adapter->erp_dbf, 4, req_id);
295
296 spin_lock_irqsave(&adapter->req_list_lock, flags);
297 fsf_req = zfcp_reqlist_ismember(adapter, req_id);
298
299 if (!fsf_req) {
300 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
301 ZFCP_LOG_NORMAL("error: unknown request id (%ld).\n", req_id);
302 zfcp_erp_adapter_reopen(adapter, 0);
303 return -EINVAL;
304 }
305
306 zfcp_reqlist_remove(adapter, req_id);
307 atomic_dec(&adapter->reqs_active);
308 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
309
310 /* finish the FSF request */
311 zfcp_fsf_req_complete(fsf_req);
312
313 return 0;
314}
315
285/* 316/*
286 * function: zfcp_qdio_response_handler 317 * function: zfcp_qdio_response_handler
287 * 318 *
@@ -344,7 +375,7 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device,
344 /* look for QDIO request identifiers in SB */ 375 /* look for QDIO request identifiers in SB */
345 buffere = &buffer->element[buffere_index]; 376 buffere = &buffer->element[buffere_index];
346 retval = zfcp_qdio_reqid_check(adapter, 377 retval = zfcp_qdio_reqid_check(adapter,
347 (void *) buffere->addr); 378 (unsigned long) buffere->addr);
348 379
349 if (retval) { 380 if (retval) {
350 ZFCP_LOG_NORMAL("bug: unexpected inbound " 381 ZFCP_LOG_NORMAL("bug: unexpected inbound "
@@ -415,52 +446,6 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device,
415 return; 446 return;
416} 447}
417 448
418/*
419 * function: zfcp_qdio_reqid_check
420 *
421 * purpose: checks for valid reqids or unsolicited status
422 *
423 * returns: 0 - valid request id or unsolicited status
424 * !0 - otherwise
425 */
426int
427zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
428{
429 struct zfcp_fsf_req *fsf_req;
430 unsigned long flags;
431
432 /* invalid (per convention used in this driver) */
433 if (unlikely(!sbale_addr)) {
434 ZFCP_LOG_NORMAL("bug: invalid reqid\n");
435 return -EINVAL;
436 }
437
438 /* valid request id and thus (hopefully :) valid fsf_req address */
439 fsf_req = (struct zfcp_fsf_req *) sbale_addr;
440
441 /* serialize with zfcp_fsf_req_dismiss_all */
442 spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
443 if (list_empty(&adapter->fsf_req_list_head)) {
444 spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
445 return 0;
446 }
447 list_del(&fsf_req->list);
448 atomic_dec(&adapter->fsf_reqs_active);
449 spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
450
451 if (unlikely(adapter != fsf_req->adapter)) {
452 ZFCP_LOG_NORMAL("bug: invalid reqid (fsf_req=%p, "
453 "fsf_req->adapter=%p, adapter=%p)\n",
454 fsf_req, fsf_req->adapter, adapter);
455 return -EINVAL;
456 }
457
458 /* finish the FSF request */
459 zfcp_fsf_req_complete(fsf_req);
460
461 return 0;
462}
463
464/** 449/**
465 * zfcp_qdio_sbale_get - return pointer to SBALE of qdio_queue 450 * zfcp_qdio_sbale_get - return pointer to SBALE of qdio_queue
466 * @queue: queue from which SBALE should be returned 451 * @queue: queue from which SBALE should be returned