diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2009-08-18 09:43:18 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-05 09:49:24 -0400 |
commit | 42428f747a8a0db9c6de03e105932316defad65d (patch) | |
tree | 84cd4b28678c94e5c6780517f89e803121cd73a7 /drivers/s390/scsi/zfcp_qdio.c | |
parent | 4544683a4b1d4e65ccca8c736bac56a195a5206b (diff) |
[SCSI] zfcp: Separate qdio attributes from zfcp_fsf_req
Split all qdio related attributes out of zfcp_fsf_req and put it in
new 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 | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 2e9b3a9cebd9..e118874976f0 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Setup and helper functions to access QDIO. | 4 | * Setup and helper functions to access QDIO. |
5 | * | 5 | * |
6 | * Copyright IBM Corporation 2002, 2008 | 6 | * Copyright IBM Corporation 2002, 2009 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #define KMSG_COMPONENT "zfcp" | 9 | #define KMSG_COMPONENT "zfcp" |
@@ -165,12 +165,14 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, | |||
165 | 165 | ||
166 | /** | 166 | /** |
167 | * zfcp_qdio_sbale_req - return ptr to SBALE of req_q for a struct zfcp_fsf_req | 167 | * zfcp_qdio_sbale_req - return ptr to SBALE of req_q for a struct zfcp_fsf_req |
168 | * @fsf_req: pointer to struct fsf_req | 168 | * @adapter: pointer to struct zfcp_adapter |
169 | * @q_rec: pointer to struct zfcp_queue_rec | ||
169 | * Returns: pointer to qdio_buffer_element (SBALE) structure | 170 | * Returns: pointer to qdio_buffer_element (SBALE) structure |
170 | */ | 171 | */ |
171 | struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req) | 172 | struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_adapter *adapter, |
173 | struct zfcp_queue_req *q_req) | ||
172 | { | 174 | { |
173 | return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, 0); | 175 | return zfcp_qdio_sbale(&adapter->req_q, q_req->sbal_last, 0); |
174 | } | 176 | } |
175 | 177 | ||
176 | /** | 178 | /** |
@@ -178,74 +180,80 @@ struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req) | |||
178 | * @fsf_req: pointer to struct fsf_req | 180 | * @fsf_req: pointer to struct fsf_req |
179 | * Returns: pointer to qdio_buffer_element (SBALE) structure | 181 | * Returns: pointer to qdio_buffer_element (SBALE) structure |
180 | */ | 182 | */ |
181 | struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req) | 183 | struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_adapter *adapter, |
184 | struct zfcp_queue_req *q_req) | ||
182 | { | 185 | { |
183 | return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, | 186 | return zfcp_qdio_sbale(&adapter->req_q, q_req->sbal_last, |
184 | req->sbale_curr); | 187 | q_req->sbale_curr); |
185 | } | 188 | } |
186 | 189 | ||
187 | static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals) | 190 | static void zfcp_qdio_sbal_limit(struct zfcp_adapter *adapter, |
191 | struct zfcp_queue_req *q_req, int max_sbals) | ||
188 | { | 192 | { |
189 | int count = atomic_read(&fsf_req->adapter->req_q.count); | 193 | int count = atomic_read(&adapter->req_q.count); |
190 | count = min(count, max_sbals); | 194 | count = min(count, max_sbals); |
191 | fsf_req->sbal_limit = (fsf_req->sbal_first + count - 1) | 195 | q_req->sbal_limit = (q_req->sbal_first + count - 1) |
192 | % QDIO_MAX_BUFFERS_PER_Q; | 196 | % QDIO_MAX_BUFFERS_PER_Q; |
193 | } | 197 | } |
194 | 198 | ||
195 | static struct qdio_buffer_element * | 199 | static struct qdio_buffer_element * |
196 | zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) | 200 | zfcp_qdio_sbal_chain(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req, |
201 | unsigned long sbtype) | ||
197 | { | 202 | { |
198 | struct qdio_buffer_element *sbale; | 203 | struct qdio_buffer_element *sbale; |
199 | 204 | ||
200 | /* set last entry flag in current SBALE of current SBAL */ | 205 | /* set last entry flag in current SBALE of current SBAL */ |
201 | sbale = zfcp_qdio_sbale_curr(fsf_req); | 206 | sbale = zfcp_qdio_sbale_curr(adapter, q_req); |
202 | sbale->flags |= SBAL_FLAGS_LAST_ENTRY; | 207 | sbale->flags |= SBAL_FLAGS_LAST_ENTRY; |
203 | 208 | ||
204 | /* don't exceed last allowed SBAL */ | 209 | /* don't exceed last allowed SBAL */ |
205 | if (fsf_req->sbal_last == fsf_req->sbal_limit) | 210 | if (q_req->sbal_last == q_req->sbal_limit) |
206 | return NULL; | 211 | return NULL; |
207 | 212 | ||
208 | /* set chaining flag in first SBALE of current SBAL */ | 213 | /* set chaining flag in first SBALE of current SBAL */ |
209 | sbale = zfcp_qdio_sbale_req(fsf_req); | 214 | sbale = zfcp_qdio_sbale_req(adapter, q_req); |
210 | sbale->flags |= SBAL_FLAGS0_MORE_SBALS; | 215 | sbale->flags |= SBAL_FLAGS0_MORE_SBALS; |
211 | 216 | ||
212 | /* calculate index of next SBAL */ | 217 | /* calculate index of next SBAL */ |
213 | fsf_req->sbal_last++; | 218 | q_req->sbal_last++; |
214 | fsf_req->sbal_last %= QDIO_MAX_BUFFERS_PER_Q; | 219 | q_req->sbal_last %= QDIO_MAX_BUFFERS_PER_Q; |
215 | 220 | ||
216 | /* keep this requests number of SBALs up-to-date */ | 221 | /* keep this requests number of SBALs up-to-date */ |
217 | fsf_req->sbal_number++; | 222 | q_req->sbal_number++; |
218 | 223 | ||
219 | /* start at first SBALE of new SBAL */ | 224 | /* start at first SBALE of new SBAL */ |
220 | fsf_req->sbale_curr = 0; | 225 | q_req->sbale_curr = 0; |
221 | 226 | ||
222 | /* set storage-block type for new SBAL */ | 227 | /* set storage-block type for new SBAL */ |
223 | sbale = zfcp_qdio_sbale_curr(fsf_req); | 228 | sbale = zfcp_qdio_sbale_curr(adapter, q_req); |
224 | sbale->flags |= sbtype; | 229 | sbale->flags |= sbtype; |
225 | 230 | ||
226 | return sbale; | 231 | return sbale; |
227 | } | 232 | } |
228 | 233 | ||
229 | static struct qdio_buffer_element * | 234 | static struct qdio_buffer_element * |
230 | zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) | 235 | zfcp_qdio_sbale_next(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req, |
236 | unsigned int sbtype) | ||
231 | { | 237 | { |
232 | if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL) | 238 | if (q_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL) |
233 | return zfcp_qdio_sbal_chain(fsf_req, sbtype); | 239 | return zfcp_qdio_sbal_chain(adapter, q_req, sbtype); |
234 | fsf_req->sbale_curr++; | 240 | q_req->sbale_curr++; |
235 | return zfcp_qdio_sbale_curr(fsf_req); | 241 | return zfcp_qdio_sbale_curr(adapter, q_req); |
236 | } | 242 | } |
237 | 243 | ||
238 | static void zfcp_qdio_undo_sbals(struct zfcp_fsf_req *fsf_req) | 244 | static void zfcp_qdio_undo_sbals(struct zfcp_adapter *adapter, |
245 | struct zfcp_queue_req *q_req) | ||
239 | { | 246 | { |
240 | struct qdio_buffer **sbal = fsf_req->adapter->req_q.sbal; | 247 | struct qdio_buffer **sbal = adapter->req_q.sbal; |
241 | int first = fsf_req->sbal_first; | 248 | int first = q_req->sbal_first; |
242 | int last = fsf_req->sbal_last; | 249 | int last = q_req->sbal_last; |
243 | int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) % | 250 | int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) % |
244 | QDIO_MAX_BUFFERS_PER_Q + 1; | 251 | QDIO_MAX_BUFFERS_PER_Q + 1; |
245 | zfcp_qdio_zero_sbals(sbal, first, count); | 252 | zfcp_qdio_zero_sbals(sbal, first, count); |
246 | } | 253 | } |
247 | 254 | ||
248 | static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, | 255 | static int zfcp_qdio_fill_sbals(struct zfcp_adapter *adapter, |
256 | struct zfcp_queue_req *q_req, | ||
249 | unsigned int sbtype, void *start_addr, | 257 | unsigned int sbtype, void *start_addr, |
250 | unsigned int total_length) | 258 | unsigned int total_length) |
251 | { | 259 | { |
@@ -256,10 +264,10 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, | |||
256 | /* split segment up */ | 264 | /* split segment up */ |
257 | for (addr = start_addr, remaining = total_length; remaining > 0; | 265 | for (addr = start_addr, remaining = total_length; remaining > 0; |
258 | addr += length, remaining -= length) { | 266 | addr += length, remaining -= length) { |
259 | sbale = zfcp_qdio_sbale_next(fsf_req, sbtype); | 267 | sbale = zfcp_qdio_sbale_next(adapter, q_req, sbtype); |
260 | if (!sbale) { | 268 | if (!sbale) { |
261 | atomic_inc(&fsf_req->adapter->qdio_outb_full); | 269 | atomic_inc(&adapter->qdio_outb_full); |
262 | zfcp_qdio_undo_sbals(fsf_req); | 270 | zfcp_qdio_undo_sbals(adapter, q_req); |
263 | return -EINVAL; | 271 | return -EINVAL; |
264 | } | 272 | } |
265 | 273 | ||
@@ -281,29 +289,31 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, | |||
281 | * @max_sbals: upper bound for number of SBALs to be used | 289 | * @max_sbals: upper bound for number of SBALs to be used |
282 | * Returns: number of bytes, or error (negativ) | 290 | * Returns: number of bytes, or error (negativ) |
283 | */ | 291 | */ |
284 | int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, | 292 | int zfcp_qdio_sbals_from_sg(struct zfcp_adapter *adapter, |
285 | struct scatterlist *sg, int max_sbals) | 293 | struct zfcp_queue_req *q_req, |
294 | unsigned long sbtype, struct scatterlist *sg, | ||
295 | int max_sbals) | ||
286 | { | 296 | { |
287 | struct qdio_buffer_element *sbale; | 297 | struct qdio_buffer_element *sbale; |
288 | int retval, bytes = 0; | 298 | int retval, bytes = 0; |
289 | 299 | ||
290 | /* figure out last allowed SBAL */ | 300 | /* figure out last allowed SBAL */ |
291 | zfcp_qdio_sbal_limit(fsf_req, max_sbals); | 301 | zfcp_qdio_sbal_limit(adapter, q_req, max_sbals); |
292 | 302 | ||
293 | /* set storage-block type for this request */ | 303 | /* set storage-block type for this request */ |
294 | sbale = zfcp_qdio_sbale_req(fsf_req); | 304 | sbale = zfcp_qdio_sbale_req(adapter, q_req); |
295 | sbale->flags |= sbtype; | 305 | sbale->flags |= sbtype; |
296 | 306 | ||
297 | for (; sg; sg = sg_next(sg)) { | 307 | for (; sg; sg = sg_next(sg)) { |
298 | retval = zfcp_qdio_fill_sbals(fsf_req, sbtype, sg_virt(sg), | 308 | retval = zfcp_qdio_fill_sbals(adapter, q_req, sbtype, |
299 | sg->length); | 309 | sg_virt(sg), sg->length); |
300 | if (retval < 0) | 310 | if (retval < 0) |
301 | return retval; | 311 | return retval; |
302 | bytes += sg->length; | 312 | bytes += sg->length; |
303 | } | 313 | } |
304 | 314 | ||
305 | /* assume that no other SBALEs are to follow in the same SBAL */ | 315 | /* assume that no other SBALEs are to follow in the same SBAL */ |
306 | sbale = zfcp_qdio_sbale_curr(fsf_req); | 316 | sbale = zfcp_qdio_sbale_curr(adapter, q_req); |
307 | sbale->flags |= SBAL_FLAGS_LAST_ENTRY; | 317 | sbale->flags |= SBAL_FLAGS_LAST_ENTRY; |
308 | 318 | ||
309 | return bytes; | 319 | return bytes; |
@@ -314,12 +324,11 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, | |||
314 | * @fsf_req: pointer to struct zfcp_fsf_req | 324 | * @fsf_req: pointer to struct zfcp_fsf_req |
315 | * Returns: 0 on success, error otherwise | 325 | * Returns: 0 on success, error otherwise |
316 | */ | 326 | */ |
317 | int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) | 327 | int zfcp_qdio_send(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req) |
318 | { | 328 | { |
319 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
320 | struct zfcp_qdio_queue *req_q = &adapter->req_q; | 329 | struct zfcp_qdio_queue *req_q = &adapter->req_q; |
321 | int first = fsf_req->sbal_first; | 330 | int first = q_req->sbal_first; |
322 | int count = fsf_req->sbal_number; | 331 | int count = q_req->sbal_number; |
323 | int retval; | 332 | int retval; |
324 | unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT; | 333 | unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT; |
325 | 334 | ||