diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2009-08-18 09:43:19 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-05 09:49:27 -0400 |
commit | 564e1c86c810f9ccfe4300afa402815e3db4886d (patch) | |
tree | ecb88038c443d6486e9df352c79b3c78be5454ef /drivers/s390/scsi/zfcp_qdio.c | |
parent | 42428f747a8a0db9c6de03e105932316defad65d (diff) |
[SCSI] zfcp: Move qdio related data out of zfcp_adapter
The zfcp_adapter structure was growing over time to a size of almost
one memory page. To reduce the size of the data structure and to
seperate different layers, put all qdio related data in the new
zfcp_qdio data structure.
Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/s390/scsi/zfcp_qdio.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 224 |
1 files changed, 119 insertions, 105 deletions
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index e118874976f0..0b3f634509bf 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -36,18 +36,18 @@ zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx) | |||
36 | 36 | ||
37 | /** | 37 | /** |
38 | * zfcp_qdio_free - free memory used by request- and resposne queue | 38 | * zfcp_qdio_free - free memory used by request- and resposne queue |
39 | * @adapter: pointer to the zfcp_adapter structure | 39 | * @qdio: pointer to the zfcp_qdio structure |
40 | */ | 40 | */ |
41 | void zfcp_qdio_free(struct zfcp_adapter *adapter) | 41 | void zfcp_qdio_free(struct zfcp_qdio *qdio) |
42 | { | 42 | { |
43 | struct qdio_buffer **sbal_req, **sbal_resp; | 43 | struct qdio_buffer **sbal_req, **sbal_resp; |
44 | int p; | 44 | int p; |
45 | 45 | ||
46 | if (adapter->ccw_device) | 46 | if (qdio->adapter->ccw_device) |
47 | qdio_free(adapter->ccw_device); | 47 | qdio_free(qdio->adapter->ccw_device); |
48 | 48 | ||
49 | sbal_req = adapter->req_q.sbal; | 49 | sbal_req = qdio->req_q.sbal; |
50 | sbal_resp = adapter->resp_q.sbal; | 50 | sbal_resp = qdio->resp_q.sbal; |
51 | 51 | ||
52 | for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) { | 52 | for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) { |
53 | free_page((unsigned long) sbal_req[p]); | 53 | free_page((unsigned long) sbal_req[p]); |
@@ -55,8 +55,10 @@ void zfcp_qdio_free(struct zfcp_adapter *adapter) | |||
55 | } | 55 | } |
56 | } | 56 | } |
57 | 57 | ||
58 | static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, char *id) | 58 | static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id) |
59 | { | 59 | { |
60 | struct zfcp_adapter *adapter = qdio->adapter; | ||
61 | |||
60 | dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n"); | 62 | dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n"); |
61 | 63 | ||
62 | zfcp_erp_adapter_reopen(adapter, | 64 | zfcp_erp_adapter_reopen(adapter, |
@@ -75,47 +77,47 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt) | |||
75 | } | 77 | } |
76 | 78 | ||
77 | /* this needs to be called prior to updating the queue fill level */ | 79 | /* this needs to be called prior to updating the queue fill level */ |
78 | static void zfcp_qdio_account(struct zfcp_adapter *adapter) | 80 | static void zfcp_qdio_account(struct zfcp_qdio *qdio) |
79 | { | 81 | { |
80 | ktime_t now; | 82 | ktime_t now; |
81 | s64 span; | 83 | s64 span; |
82 | int free, used; | 84 | int free, used; |
83 | 85 | ||
84 | spin_lock(&adapter->qdio_stat_lock); | 86 | spin_lock(&qdio->stat_lock); |
85 | now = ktime_get(); | 87 | now = ktime_get(); |
86 | span = ktime_us_delta(now, adapter->req_q_time); | 88 | span = ktime_us_delta(now, qdio->req_q_time); |
87 | free = max(0, atomic_read(&adapter->req_q.count)); | 89 | free = max(0, atomic_read(&qdio->req_q.count)); |
88 | used = QDIO_MAX_BUFFERS_PER_Q - free; | 90 | used = QDIO_MAX_BUFFERS_PER_Q - free; |
89 | adapter->req_q_util += used * span; | 91 | qdio->req_q_util += used * span; |
90 | adapter->req_q_time = now; | 92 | qdio->req_q_time = now; |
91 | spin_unlock(&adapter->qdio_stat_lock); | 93 | spin_unlock(&qdio->stat_lock); |
92 | } | 94 | } |
93 | 95 | ||
94 | static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, | 96 | static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, |
95 | int queue_no, int first, int count, | 97 | int queue_no, int first, int count, |
96 | unsigned long parm) | 98 | unsigned long parm) |
97 | { | 99 | { |
98 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm; | 100 | struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; |
99 | struct zfcp_qdio_queue *queue = &adapter->req_q; | 101 | struct zfcp_qdio_queue *queue = &qdio->req_q; |
100 | 102 | ||
101 | if (unlikely(qdio_err)) { | 103 | if (unlikely(qdio_err)) { |
102 | zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count); | 104 | zfcp_hba_dbf_event_qdio(qdio, qdio_err, first, count); |
103 | zfcp_qdio_handler_error(adapter, "qdireq1"); | 105 | zfcp_qdio_handler_error(qdio, "qdireq1"); |
104 | return; | 106 | return; |
105 | } | 107 | } |
106 | 108 | ||
107 | /* cleanup all SBALs being program-owned now */ | 109 | /* cleanup all SBALs being program-owned now */ |
108 | zfcp_qdio_zero_sbals(queue->sbal, first, count); | 110 | zfcp_qdio_zero_sbals(queue->sbal, first, count); |
109 | 111 | ||
110 | zfcp_qdio_account(adapter); | 112 | zfcp_qdio_account(qdio); |
111 | atomic_add(count, &queue->count); | 113 | atomic_add(count, &queue->count); |
112 | wake_up(&adapter->request_wq); | 114 | wake_up(&qdio->req_q_wq); |
113 | } | 115 | } |
114 | 116 | ||
115 | static void zfcp_qdio_resp_put_back(struct zfcp_adapter *adapter, int processed) | 117 | static void zfcp_qdio_resp_put_back(struct zfcp_qdio *qdio, int processed) |
116 | { | 118 | { |
117 | struct zfcp_qdio_queue *queue = &adapter->resp_q; | 119 | struct zfcp_qdio_queue *queue = &qdio->resp_q; |
118 | struct ccw_device *cdev = adapter->ccw_device; | 120 | struct ccw_device *cdev = qdio->adapter->ccw_device; |
119 | u8 count, start = queue->first; | 121 | u8 count, start = queue->first; |
120 | unsigned int retval; | 122 | unsigned int retval; |
121 | 123 | ||
@@ -137,12 +139,12 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, | |||
137 | int queue_no, int first, int count, | 139 | int queue_no, int first, int count, |
138 | unsigned long parm) | 140 | unsigned long parm) |
139 | { | 141 | { |
140 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm; | 142 | struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; |
141 | int sbal_idx, sbal_no; | 143 | int sbal_idx, sbal_no; |
142 | 144 | ||
143 | if (unlikely(qdio_err)) { | 145 | if (unlikely(qdio_err)) { |
144 | zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count); | 146 | zfcp_hba_dbf_event_qdio(qdio, qdio_err, first, count); |
145 | zfcp_qdio_handler_error(adapter, "qdires1"); | 147 | zfcp_qdio_handler_error(qdio, "qdires1"); |
146 | return; | 148 | return; |
147 | } | 149 | } |
148 | 150 | ||
@@ -153,26 +155,26 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, | |||
153 | for (sbal_no = 0; sbal_no < count; sbal_no++) { | 155 | for (sbal_no = 0; sbal_no < count; sbal_no++) { |
154 | sbal_idx = (first + sbal_no) % QDIO_MAX_BUFFERS_PER_Q; | 156 | sbal_idx = (first + sbal_no) % QDIO_MAX_BUFFERS_PER_Q; |
155 | /* go through all SBALEs of SBAL */ | 157 | /* go through all SBALEs of SBAL */ |
156 | zfcp_fsf_reqid_check(adapter, sbal_idx); | 158 | zfcp_fsf_reqid_check(qdio, sbal_idx); |
157 | } | 159 | } |
158 | 160 | ||
159 | /* | 161 | /* |
160 | * put range of SBALs back to response queue | 162 | * put range of SBALs back to response queue |
161 | * (including SBALs which have already been free before) | 163 | * (including SBALs which have already been free before) |
162 | */ | 164 | */ |
163 | zfcp_qdio_resp_put_back(adapter, count); | 165 | zfcp_qdio_resp_put_back(qdio, count); |
164 | } | 166 | } |
165 | 167 | ||
166 | /** | 168 | /** |
167 | * zfcp_qdio_sbale_req - return ptr to SBALE of req_q for a struct zfcp_fsf_req | 169 | * zfcp_qdio_sbale_req - return ptr to SBALE of req_q for a struct zfcp_fsf_req |
168 | * @adapter: pointer to struct zfcp_adapter | 170 | * @qdio: pointer to struct zfcp_qdio |
169 | * @q_rec: pointer to struct zfcp_queue_rec | 171 | * @q_rec: pointer to struct zfcp_queue_rec |
170 | * Returns: pointer to qdio_buffer_element (SBALE) structure | 172 | * Returns: pointer to qdio_buffer_element (SBALE) structure |
171 | */ | 173 | */ |
172 | struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_adapter *adapter, | 174 | struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_qdio *qdio, |
173 | struct zfcp_queue_req *q_req) | 175 | struct zfcp_queue_req *q_req) |
174 | { | 176 | { |
175 | return zfcp_qdio_sbale(&adapter->req_q, q_req->sbal_last, 0); | 177 | return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last, 0); |
176 | } | 178 | } |
177 | 179 | ||
178 | /** | 180 | /** |
@@ -180,30 +182,30 @@ struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_adapter *adapter, | |||
180 | * @fsf_req: pointer to struct fsf_req | 182 | * @fsf_req: pointer to struct fsf_req |
181 | * Returns: pointer to qdio_buffer_element (SBALE) structure | 183 | * Returns: pointer to qdio_buffer_element (SBALE) structure |
182 | */ | 184 | */ |
183 | struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_adapter *adapter, | 185 | struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_qdio *qdio, |
184 | struct zfcp_queue_req *q_req) | 186 | struct zfcp_queue_req *q_req) |
185 | { | 187 | { |
186 | return zfcp_qdio_sbale(&adapter->req_q, q_req->sbal_last, | 188 | return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last, |
187 | q_req->sbale_curr); | 189 | q_req->sbale_curr); |
188 | } | 190 | } |
189 | 191 | ||
190 | static void zfcp_qdio_sbal_limit(struct zfcp_adapter *adapter, | 192 | static void zfcp_qdio_sbal_limit(struct zfcp_qdio *qdio, |
191 | struct zfcp_queue_req *q_req, int max_sbals) | 193 | struct zfcp_queue_req *q_req, int max_sbals) |
192 | { | 194 | { |
193 | int count = atomic_read(&adapter->req_q.count); | 195 | int count = atomic_read(&qdio->req_q.count); |
194 | count = min(count, max_sbals); | 196 | count = min(count, max_sbals); |
195 | q_req->sbal_limit = (q_req->sbal_first + count - 1) | 197 | q_req->sbal_limit = (q_req->sbal_first + count - 1) |
196 | % QDIO_MAX_BUFFERS_PER_Q; | 198 | % QDIO_MAX_BUFFERS_PER_Q; |
197 | } | 199 | } |
198 | 200 | ||
199 | static struct qdio_buffer_element * | 201 | static struct qdio_buffer_element * |
200 | zfcp_qdio_sbal_chain(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req, | 202 | zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_queue_req *q_req, |
201 | unsigned long sbtype) | 203 | unsigned long sbtype) |
202 | { | 204 | { |
203 | struct qdio_buffer_element *sbale; | 205 | struct qdio_buffer_element *sbale; |
204 | 206 | ||
205 | /* set last entry flag in current SBALE of current SBAL */ | 207 | /* set last entry flag in current SBALE of current SBAL */ |
206 | sbale = zfcp_qdio_sbale_curr(adapter, q_req); | 208 | sbale = zfcp_qdio_sbale_curr(qdio, q_req); |
207 | sbale->flags |= SBAL_FLAGS_LAST_ENTRY; | 209 | sbale->flags |= SBAL_FLAGS_LAST_ENTRY; |
208 | 210 | ||
209 | /* don't exceed last allowed SBAL */ | 211 | /* don't exceed last allowed SBAL */ |
@@ -211,7 +213,7 @@ zfcp_qdio_sbal_chain(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req, | |||
211 | return NULL; | 213 | return NULL; |
212 | 214 | ||
213 | /* set chaining flag in first SBALE of current SBAL */ | 215 | /* set chaining flag in first SBALE of current SBAL */ |
214 | sbale = zfcp_qdio_sbale_req(adapter, q_req); | 216 | sbale = zfcp_qdio_sbale_req(qdio, q_req); |
215 | sbale->flags |= SBAL_FLAGS0_MORE_SBALS; | 217 | sbale->flags |= SBAL_FLAGS0_MORE_SBALS; |
216 | 218 | ||
217 | /* calculate index of next SBAL */ | 219 | /* calculate index of next SBAL */ |
@@ -225,26 +227,26 @@ zfcp_qdio_sbal_chain(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req, | |||
225 | q_req->sbale_curr = 0; | 227 | q_req->sbale_curr = 0; |
226 | 228 | ||
227 | /* set storage-block type for new SBAL */ | 229 | /* set storage-block type for new SBAL */ |
228 | sbale = zfcp_qdio_sbale_curr(adapter, q_req); | 230 | sbale = zfcp_qdio_sbale_curr(qdio, q_req); |
229 | sbale->flags |= sbtype; | 231 | sbale->flags |= sbtype; |
230 | 232 | ||
231 | return sbale; | 233 | return sbale; |
232 | } | 234 | } |
233 | 235 | ||
234 | static struct qdio_buffer_element * | 236 | static struct qdio_buffer_element * |
235 | zfcp_qdio_sbale_next(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req, | 237 | zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_queue_req *q_req, |
236 | unsigned int sbtype) | 238 | unsigned int sbtype) |
237 | { | 239 | { |
238 | if (q_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL) | 240 | if (q_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL) |
239 | return zfcp_qdio_sbal_chain(adapter, q_req, sbtype); | 241 | return zfcp_qdio_sbal_chain(qdio, q_req, sbtype); |
240 | q_req->sbale_curr++; | 242 | q_req->sbale_curr++; |
241 | return zfcp_qdio_sbale_curr(adapter, q_req); | 243 | return zfcp_qdio_sbale_curr(qdio, q_req); |
242 | } | 244 | } |
243 | 245 | ||
244 | static void zfcp_qdio_undo_sbals(struct zfcp_adapter *adapter, | 246 | static void zfcp_qdio_undo_sbals(struct zfcp_qdio *qdio, |
245 | struct zfcp_queue_req *q_req) | 247 | struct zfcp_queue_req *q_req) |
246 | { | 248 | { |
247 | struct qdio_buffer **sbal = adapter->req_q.sbal; | 249 | struct qdio_buffer **sbal = qdio->req_q.sbal; |
248 | int first = q_req->sbal_first; | 250 | int first = q_req->sbal_first; |
249 | int last = q_req->sbal_last; | 251 | int last = q_req->sbal_last; |
250 | int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) % | 252 | int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) % |
@@ -252,7 +254,7 @@ static void zfcp_qdio_undo_sbals(struct zfcp_adapter *adapter, | |||
252 | zfcp_qdio_zero_sbals(sbal, first, count); | 254 | zfcp_qdio_zero_sbals(sbal, first, count); |
253 | } | 255 | } |
254 | 256 | ||
255 | static int zfcp_qdio_fill_sbals(struct zfcp_adapter *adapter, | 257 | static int zfcp_qdio_fill_sbals(struct zfcp_qdio *qdio, |
256 | struct zfcp_queue_req *q_req, | 258 | struct zfcp_queue_req *q_req, |
257 | unsigned int sbtype, void *start_addr, | 259 | unsigned int sbtype, void *start_addr, |
258 | unsigned int total_length) | 260 | unsigned int total_length) |
@@ -264,10 +266,10 @@ static int zfcp_qdio_fill_sbals(struct zfcp_adapter *adapter, | |||
264 | /* split segment up */ | 266 | /* split segment up */ |
265 | for (addr = start_addr, remaining = total_length; remaining > 0; | 267 | for (addr = start_addr, remaining = total_length; remaining > 0; |
266 | addr += length, remaining -= length) { | 268 | addr += length, remaining -= length) { |
267 | sbale = zfcp_qdio_sbale_next(adapter, q_req, sbtype); | 269 | sbale = zfcp_qdio_sbale_next(qdio, q_req, sbtype); |
268 | if (!sbale) { | 270 | if (!sbale) { |
269 | atomic_inc(&adapter->qdio_outb_full); | 271 | atomic_inc(&qdio->req_q_full); |
270 | zfcp_qdio_undo_sbals(adapter, q_req); | 272 | zfcp_qdio_undo_sbals(qdio, q_req); |
271 | return -EINVAL; | 273 | return -EINVAL; |
272 | } | 274 | } |
273 | 275 | ||
@@ -289,7 +291,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_adapter *adapter, | |||
289 | * @max_sbals: upper bound for number of SBALs to be used | 291 | * @max_sbals: upper bound for number of SBALs to be used |
290 | * Returns: number of bytes, or error (negativ) | 292 | * Returns: number of bytes, or error (negativ) |
291 | */ | 293 | */ |
292 | int zfcp_qdio_sbals_from_sg(struct zfcp_adapter *adapter, | 294 | int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, |
293 | struct zfcp_queue_req *q_req, | 295 | struct zfcp_queue_req *q_req, |
294 | unsigned long sbtype, struct scatterlist *sg, | 296 | unsigned long sbtype, struct scatterlist *sg, |
295 | int max_sbals) | 297 | int max_sbals) |
@@ -298,14 +300,14 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_adapter *adapter, | |||
298 | int retval, bytes = 0; | 300 | int retval, bytes = 0; |
299 | 301 | ||
300 | /* figure out last allowed SBAL */ | 302 | /* figure out last allowed SBAL */ |
301 | zfcp_qdio_sbal_limit(adapter, q_req, max_sbals); | 303 | zfcp_qdio_sbal_limit(qdio, q_req, max_sbals); |
302 | 304 | ||
303 | /* set storage-block type for this request */ | 305 | /* set storage-block type for this request */ |
304 | sbale = zfcp_qdio_sbale_req(adapter, q_req); | 306 | sbale = zfcp_qdio_sbale_req(qdio, q_req); |
305 | sbale->flags |= sbtype; | 307 | sbale->flags |= sbtype; |
306 | 308 | ||
307 | for (; sg; sg = sg_next(sg)) { | 309 | for (; sg; sg = sg_next(sg)) { |
308 | retval = zfcp_qdio_fill_sbals(adapter, q_req, sbtype, | 310 | retval = zfcp_qdio_fill_sbals(qdio, q_req, sbtype, |
309 | sg_virt(sg), sg->length); | 311 | sg_virt(sg), sg->length); |
310 | if (retval < 0) | 312 | if (retval < 0) |
311 | return retval; | 313 | return retval; |
@@ -313,7 +315,7 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_adapter *adapter, | |||
313 | } | 315 | } |
314 | 316 | ||
315 | /* assume that no other SBALEs are to follow in the same SBAL */ | 317 | /* assume that no other SBALEs are to follow in the same SBAL */ |
316 | sbale = zfcp_qdio_sbale_curr(adapter, q_req); | 318 | sbale = zfcp_qdio_sbale_curr(qdio, q_req); |
317 | sbale->flags |= SBAL_FLAGS_LAST_ENTRY; | 319 | sbale->flags |= SBAL_FLAGS_LAST_ENTRY; |
318 | 320 | ||
319 | return bytes; | 321 | return bytes; |
@@ -321,20 +323,22 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_adapter *adapter, | |||
321 | 323 | ||
322 | /** | 324 | /** |
323 | * zfcp_qdio_send - set PCI flag in first SBALE and send req to QDIO | 325 | * zfcp_qdio_send - set PCI flag in first SBALE and send req to QDIO |
324 | * @fsf_req: pointer to struct zfcp_fsf_req | 326 | * @qdio: pointer to struct zfcp_qdio |
327 | * @q_req: pointer to struct zfcp_queue_req | ||
325 | * Returns: 0 on success, error otherwise | 328 | * Returns: 0 on success, error otherwise |
326 | */ | 329 | */ |
327 | int zfcp_qdio_send(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req) | 330 | int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_queue_req *q_req) |
328 | { | 331 | { |
329 | struct zfcp_qdio_queue *req_q = &adapter->req_q; | 332 | struct zfcp_qdio_queue *req_q = &qdio->req_q; |
330 | int first = q_req->sbal_first; | 333 | int first = q_req->sbal_first; |
331 | int count = q_req->sbal_number; | 334 | int count = q_req->sbal_number; |
332 | int retval; | 335 | int retval; |
333 | unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT; | 336 | unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT; |
334 | 337 | ||
335 | zfcp_qdio_account(adapter); | 338 | zfcp_qdio_account(qdio); |
336 | 339 | ||
337 | retval = do_QDIO(adapter->ccw_device, qdio_flags, 0, first, count); | 340 | retval = do_QDIO(qdio->adapter->ccw_device, qdio_flags, 0, first, |
341 | count); | ||
338 | if (unlikely(retval)) { | 342 | if (unlikely(retval)) { |
339 | zfcp_qdio_zero_sbals(req_q->sbal, first, count); | 343 | zfcp_qdio_zero_sbals(req_q->sbal, first, count); |
340 | return retval; | 344 | return retval; |
@@ -347,63 +351,69 @@ int zfcp_qdio_send(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req) | |||
347 | return 0; | 351 | return 0; |
348 | } | 352 | } |
349 | 353 | ||
354 | |||
355 | static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, | ||
356 | struct zfcp_qdio *qdio) | ||
357 | { | ||
358 | |||
359 | id->cdev = qdio->adapter->ccw_device; | ||
360 | id->q_format = QDIO_ZFCP_QFMT; | ||
361 | memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8); | ||
362 | ASCEBC(id->adapter_name, 8); | ||
363 | id->qib_param_field_format = 0; | ||
364 | id->qib_param_field = NULL; | ||
365 | id->input_slib_elements = NULL; | ||
366 | id->output_slib_elements = NULL; | ||
367 | id->no_input_qs = 1; | ||
368 | id->no_output_qs = 1; | ||
369 | id->input_handler = zfcp_qdio_int_resp; | ||
370 | id->output_handler = zfcp_qdio_int_req; | ||
371 | id->int_parm = (unsigned long) qdio; | ||
372 | id->flags = QDIO_INBOUND_0COPY_SBALS | | ||
373 | QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS; | ||
374 | id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal); | ||
375 | id->output_sbal_addr_array = (void **) (qdio->req_q.sbal); | ||
376 | |||
377 | } | ||
350 | /** | 378 | /** |
351 | * zfcp_qdio_allocate - allocate queue memory and initialize QDIO data | 379 | * zfcp_qdio_allocate - allocate queue memory and initialize QDIO data |
352 | * @adapter: pointer to struct zfcp_adapter | 380 | * @adapter: pointer to struct zfcp_adapter |
353 | * Returns: -ENOMEM on memory allocation error or return value from | 381 | * Returns: -ENOMEM on memory allocation error or return value from |
354 | * qdio_allocate | 382 | * qdio_allocate |
355 | */ | 383 | */ |
356 | int zfcp_qdio_allocate(struct zfcp_adapter *adapter) | 384 | int zfcp_qdio_allocate(struct zfcp_qdio *qdio, struct ccw_device *ccw_dev) |
357 | { | 385 | { |
358 | struct qdio_initialize *init_data; | 386 | struct qdio_initialize init_data; |
359 | 387 | ||
360 | if (zfcp_qdio_buffers_enqueue(adapter->req_q.sbal) || | 388 | if (zfcp_qdio_buffers_enqueue(qdio->req_q.sbal) || |
361 | zfcp_qdio_buffers_enqueue(adapter->resp_q.sbal)) | 389 | zfcp_qdio_buffers_enqueue(qdio->resp_q.sbal)) |
362 | return -ENOMEM; | 390 | return -ENOMEM; |
363 | 391 | ||
364 | init_data = &adapter->qdio_init_data; | 392 | zfcp_qdio_setup_init_data(&init_data, qdio); |
365 | 393 | ||
366 | init_data->cdev = adapter->ccw_device; | 394 | return qdio_allocate(&init_data); |
367 | init_data->q_format = QDIO_ZFCP_QFMT; | ||
368 | memcpy(init_data->adapter_name, dev_name(&adapter->ccw_device->dev), 8); | ||
369 | ASCEBC(init_data->adapter_name, 8); | ||
370 | init_data->qib_param_field_format = 0; | ||
371 | init_data->qib_param_field = NULL; | ||
372 | init_data->input_slib_elements = NULL; | ||
373 | init_data->output_slib_elements = NULL; | ||
374 | init_data->no_input_qs = 1; | ||
375 | init_data->no_output_qs = 1; | ||
376 | init_data->input_handler = zfcp_qdio_int_resp; | ||
377 | init_data->output_handler = zfcp_qdio_int_req; | ||
378 | init_data->int_parm = (unsigned long) adapter; | ||
379 | init_data->flags = QDIO_INBOUND_0COPY_SBALS | | ||
380 | QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS; | ||
381 | init_data->input_sbal_addr_array = | ||
382 | (void **) (adapter->resp_q.sbal); | ||
383 | init_data->output_sbal_addr_array = | ||
384 | (void **) (adapter->req_q.sbal); | ||
385 | |||
386 | return qdio_allocate(init_data); | ||
387 | } | 395 | } |
388 | 396 | ||
389 | /** | 397 | /** |
390 | * zfcp_close_qdio - close qdio queues for an adapter | 398 | * zfcp_close_qdio - close qdio queues for an adapter |
399 | * @qdio: pointer to structure zfcp_qdio | ||
391 | */ | 400 | */ |
392 | void zfcp_qdio_close(struct zfcp_adapter *adapter) | 401 | void zfcp_qdio_close(struct zfcp_qdio *qdio) |
393 | { | 402 | { |
394 | struct zfcp_qdio_queue *req_q; | 403 | struct zfcp_qdio_queue *req_q; |
395 | int first, count; | 404 | int first, count; |
396 | 405 | ||
397 | if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) | 406 | if (!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) |
398 | return; | 407 | return; |
399 | 408 | ||
400 | /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ | 409 | /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ |
401 | req_q = &adapter->req_q; | 410 | req_q = &qdio->req_q; |
402 | spin_lock_bh(&adapter->req_q_lock); | 411 | spin_lock_bh(&qdio->req_q_lock); |
403 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); | 412 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status); |
404 | spin_unlock_bh(&adapter->req_q_lock); | 413 | spin_unlock_bh(&qdio->req_q_lock); |
405 | 414 | ||
406 | qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); | 415 | qdio_shutdown(qdio->adapter->ccw_device, |
416 | QDIO_FLAG_CLEANUP_USING_CLEAR); | ||
407 | 417 | ||
408 | /* cleanup used outbound sbals */ | 418 | /* cleanup used outbound sbals */ |
409 | count = atomic_read(&req_q->count); | 419 | count = atomic_read(&req_q->count); |
@@ -414,50 +424,54 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) | |||
414 | } | 424 | } |
415 | req_q->first = 0; | 425 | req_q->first = 0; |
416 | atomic_set(&req_q->count, 0); | 426 | atomic_set(&req_q->count, 0); |
417 | adapter->resp_q.first = 0; | 427 | qdio->resp_q.first = 0; |
418 | atomic_set(&adapter->resp_q.count, 0); | 428 | atomic_set(&qdio->resp_q.count, 0); |
419 | } | 429 | } |
420 | 430 | ||
421 | /** | 431 | /** |
422 | * zfcp_qdio_open - prepare and initialize response queue | 432 | * zfcp_qdio_open - prepare and initialize response queue |
423 | * @adapter: pointer to struct zfcp_adapter | 433 | * @qdio: pointer to struct zfcp_qdio |
424 | * Returns: 0 on success, otherwise -EIO | 434 | * Returns: 0 on success, otherwise -EIO |
425 | */ | 435 | */ |
426 | int zfcp_qdio_open(struct zfcp_adapter *adapter) | 436 | int zfcp_qdio_open(struct zfcp_qdio *qdio) |
427 | { | 437 | { |
428 | struct qdio_buffer_element *sbale; | 438 | struct qdio_buffer_element *sbale; |
439 | struct qdio_initialize init_data; | ||
440 | struct ccw_device *cdev = qdio->adapter->ccw_device; | ||
429 | int cc; | 441 | int cc; |
430 | 442 | ||
431 | if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP) | 443 | if (atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP) |
432 | return -EIO; | 444 | return -EIO; |
433 | 445 | ||
434 | if (qdio_establish(&adapter->qdio_init_data)) | 446 | zfcp_qdio_setup_init_data(&init_data, qdio); |
447 | |||
448 | if (qdio_establish(&init_data)) | ||
435 | goto failed_establish; | 449 | goto failed_establish; |
436 | 450 | ||
437 | if (qdio_activate(adapter->ccw_device)) | 451 | if (qdio_activate(cdev)) |
438 | goto failed_qdio; | 452 | goto failed_qdio; |
439 | 453 | ||
440 | for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) { | 454 | for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) { |
441 | sbale = &(adapter->resp_q.sbal[cc]->element[0]); | 455 | sbale = &(qdio->resp_q.sbal[cc]->element[0]); |
442 | sbale->length = 0; | 456 | sbale->length = 0; |
443 | sbale->flags = SBAL_FLAGS_LAST_ENTRY; | 457 | sbale->flags = SBAL_FLAGS_LAST_ENTRY; |
444 | sbale->addr = NULL; | 458 | sbale->addr = NULL; |
445 | } | 459 | } |
446 | 460 | ||
447 | if (do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_INPUT, 0, 0, | 461 | if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, |
448 | QDIO_MAX_BUFFERS_PER_Q)) | 462 | QDIO_MAX_BUFFERS_PER_Q)) |
449 | goto failed_qdio; | 463 | goto failed_qdio; |
450 | 464 | ||
451 | /* set index of first avalable SBALS / number of available SBALS */ | 465 | /* set index of first avalable SBALS / number of available SBALS */ |
452 | adapter->req_q.first = 0; | 466 | qdio->req_q.first = 0; |
453 | atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q); | 467 | atomic_set(&qdio->req_q.count, QDIO_MAX_BUFFERS_PER_Q); |
454 | 468 | ||
455 | return 0; | 469 | return 0; |
456 | 470 | ||
457 | failed_qdio: | 471 | failed_qdio: |
458 | qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); | 472 | qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); |
459 | failed_establish: | 473 | failed_establish: |
460 | dev_err(&adapter->ccw_device->dev, | 474 | dev_err(&cdev->dev, |
461 | "Setting up the QDIO connection to the FCP adapter failed\n"); | 475 | "Setting up the QDIO connection to the FCP adapter failed\n"); |
462 | return -EIO; | 476 | return -EIO; |
463 | } | 477 | } |