diff options
| -rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 10 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 141 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_qdio.h | 57 |
3 files changed, 69 insertions, 139 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 5f502c9cb067..0710c59b80ae 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
| @@ -732,7 +732,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) | |||
| 732 | 732 | ||
| 733 | zfcp_reqlist_add(adapter->req_list, req); | 733 | zfcp_reqlist_add(adapter->req_list, req); |
| 734 | 734 | ||
| 735 | req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q.count); | 735 | req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q_free); |
| 736 | req->issued = get_clock(); | 736 | req->issued = get_clock(); |
| 737 | if (zfcp_qdio_send(qdio, &req->qdio_req)) { | 737 | if (zfcp_qdio_send(qdio, &req->qdio_req)) { |
| 738 | del_timer(&req->timer); | 738 | del_timer(&req->timer); |
| @@ -2025,7 +2025,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) | |||
| 2025 | blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC; | 2025 | blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC; |
| 2026 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) | 2026 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
| 2027 | blktrc.flags |= ZFCP_BLK_REQ_ERROR; | 2027 | blktrc.flags |= ZFCP_BLK_REQ_ERROR; |
| 2028 | blktrc.inb_usage = req->qdio_req.qdio_inb_usage; | 2028 | blktrc.inb_usage = 0; |
| 2029 | blktrc.outb_usage = req->qdio_req.qdio_outb_usage; | 2029 | blktrc.outb_usage = req->qdio_req.qdio_outb_usage; |
| 2030 | 2030 | ||
| 2031 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA && | 2031 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA && |
| @@ -2207,7 +2207,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
| 2207 | return -EBUSY; | 2207 | return -EBUSY; |
| 2208 | 2208 | ||
| 2209 | spin_lock(&qdio->req_q_lock); | 2209 | spin_lock(&qdio->req_q_lock); |
| 2210 | if (atomic_read(&qdio->req_q.count) <= 0) { | 2210 | if (atomic_read(&qdio->req_q_free) <= 0) { |
| 2211 | atomic_inc(&qdio->req_q_full); | 2211 | atomic_inc(&qdio->req_q_full); |
| 2212 | goto out; | 2212 | goto out; |
| 2213 | } | 2213 | } |
| @@ -2407,7 +2407,7 @@ out: | |||
| 2407 | void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) | 2407 | void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) |
| 2408 | { | 2408 | { |
| 2409 | struct zfcp_adapter *adapter = qdio->adapter; | 2409 | struct zfcp_adapter *adapter = qdio->adapter; |
| 2410 | struct qdio_buffer *sbal = qdio->resp_q.sbal[sbal_idx]; | 2410 | struct qdio_buffer *sbal = qdio->res_q[sbal_idx]; |
| 2411 | struct qdio_buffer_element *sbale; | 2411 | struct qdio_buffer_element *sbale; |
| 2412 | struct zfcp_fsf_req *fsf_req; | 2412 | struct zfcp_fsf_req *fsf_req; |
| 2413 | unsigned long req_id; | 2413 | unsigned long req_id; |
| @@ -2428,8 +2428,6 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) | |||
| 2428 | req_id, dev_name(&adapter->ccw_device->dev)); | 2428 | req_id, dev_name(&adapter->ccw_device->dev)); |
| 2429 | 2429 | ||
| 2430 | fsf_req->qdio_req.sbal_response = sbal_idx; | 2430 | fsf_req->qdio_req.sbal_response = sbal_idx; |
| 2431 | fsf_req->qdio_req.qdio_inb_usage = | ||
| 2432 | atomic_read(&qdio->resp_q.count); | ||
| 2433 | zfcp_fsf_req_complete(fsf_req); | 2431 | zfcp_fsf_req_complete(fsf_req); |
| 2434 | 2432 | ||
| 2435 | if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY)) | 2433 | if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY)) |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 7ab1ac16a11f..a638278c6025 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
| @@ -55,71 +55,46 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt) | |||
| 55 | static inline void zfcp_qdio_account(struct zfcp_qdio *qdio) | 55 | static inline void zfcp_qdio_account(struct zfcp_qdio *qdio) |
| 56 | { | 56 | { |
| 57 | unsigned long long now, span; | 57 | unsigned long long now, span; |
| 58 | int free, used; | 58 | int used; |
| 59 | 59 | ||
| 60 | spin_lock(&qdio->stat_lock); | 60 | spin_lock(&qdio->stat_lock); |
| 61 | now = get_clock_monotonic(); | 61 | now = get_clock_monotonic(); |
| 62 | span = (now - qdio->req_q_time) >> 12; | 62 | span = (now - qdio->req_q_time) >> 12; |
| 63 | free = atomic_read(&qdio->req_q.count); | 63 | used = QDIO_MAX_BUFFERS_PER_Q - atomic_read(&qdio->req_q_free); |
| 64 | used = QDIO_MAX_BUFFERS_PER_Q - free; | ||
| 65 | qdio->req_q_util += used * span; | 64 | qdio->req_q_util += used * span; |
| 66 | qdio->req_q_time = now; | 65 | qdio->req_q_time = now; |
| 67 | spin_unlock(&qdio->stat_lock); | 66 | spin_unlock(&qdio->stat_lock); |
| 68 | } | 67 | } |
| 69 | 68 | ||
| 70 | static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, | 69 | static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, |
| 71 | int queue_no, int first, int count, | 70 | int queue_no, int idx, int count, |
| 72 | unsigned long parm) | 71 | unsigned long parm) |
| 73 | { | 72 | { |
| 74 | struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; | 73 | struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; |
| 75 | struct zfcp_qdio_queue *queue = &qdio->req_q; | ||
| 76 | 74 | ||
| 77 | if (unlikely(qdio_err)) { | 75 | if (unlikely(qdio_err)) { |
| 78 | zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, first, | 76 | zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count); |
| 79 | count); | ||
| 80 | zfcp_qdio_handler_error(qdio, "qdireq1"); | 77 | zfcp_qdio_handler_error(qdio, "qdireq1"); |
| 81 | return; | 78 | return; |
| 82 | } | 79 | } |
| 83 | 80 | ||
| 84 | /* cleanup all SBALs being program-owned now */ | 81 | /* cleanup all SBALs being program-owned now */ |
| 85 | zfcp_qdio_zero_sbals(queue->sbal, first, count); | 82 | zfcp_qdio_zero_sbals(qdio->req_q, idx, count); |
| 86 | 83 | ||
| 87 | zfcp_qdio_account(qdio); | 84 | zfcp_qdio_account(qdio); |
| 88 | atomic_add(count, &queue->count); | 85 | atomic_add(count, &qdio->req_q_free); |
| 89 | wake_up(&qdio->req_q_wq); | 86 | wake_up(&qdio->req_q_wq); |
| 90 | } | 87 | } |
| 91 | 88 | ||
| 92 | static void zfcp_qdio_resp_put_back(struct zfcp_qdio *qdio, int processed) | ||
| 93 | { | ||
| 94 | struct zfcp_qdio_queue *queue = &qdio->resp_q; | ||
| 95 | struct ccw_device *cdev = qdio->adapter->ccw_device; | ||
| 96 | u8 count, start = queue->first; | ||
| 97 | unsigned int retval; | ||
| 98 | |||
| 99 | count = atomic_read(&queue->count) + processed; | ||
| 100 | |||
| 101 | retval = do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, start, count); | ||
| 102 | |||
| 103 | if (unlikely(retval)) { | ||
| 104 | atomic_set(&queue->count, count); | ||
| 105 | zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdrpb_1", NULL); | ||
| 106 | } else { | ||
| 107 | queue->first += count; | ||
| 108 | queue->first %= QDIO_MAX_BUFFERS_PER_Q; | ||
| 109 | atomic_set(&queue->count, 0); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, | 89 | static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, |
| 114 | int queue_no, int first, int count, | 90 | int queue_no, int idx, int count, |
| 115 | unsigned long parm) | 91 | unsigned long parm) |
| 116 | { | 92 | { |
| 117 | struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; | 93 | struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; |
| 118 | int sbal_idx, sbal_no; | 94 | int sbal_idx, sbal_no; |
| 119 | 95 | ||
| 120 | if (unlikely(qdio_err)) { | 96 | if (unlikely(qdio_err)) { |
| 121 | zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, first, | 97 | zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count); |
| 122 | count); | ||
| 123 | zfcp_qdio_handler_error(qdio, "qdires1"); | 98 | zfcp_qdio_handler_error(qdio, "qdires1"); |
| 124 | return; | 99 | return; |
| 125 | } | 100 | } |
| @@ -129,16 +104,16 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, | |||
| 129 | * returned by QDIO layer | 104 | * returned by QDIO layer |
| 130 | */ | 105 | */ |
| 131 | for (sbal_no = 0; sbal_no < count; sbal_no++) { | 106 | for (sbal_no = 0; sbal_no < count; sbal_no++) { |
| 132 | sbal_idx = (first + sbal_no) % QDIO_MAX_BUFFERS_PER_Q; | 107 | sbal_idx = (idx + sbal_no) % QDIO_MAX_BUFFERS_PER_Q; |
| 133 | /* go through all SBALEs of SBAL */ | 108 | /* go through all SBALEs of SBAL */ |
| 134 | zfcp_fsf_reqid_check(qdio, sbal_idx); | 109 | zfcp_fsf_reqid_check(qdio, sbal_idx); |
| 135 | } | 110 | } |
| 136 | 111 | ||
| 137 | /* | 112 | /* |
| 138 | * put range of SBALs back to response queue | 113 | * put SBALs back to response queue |
| 139 | * (including SBALs which have already been free before) | ||
| 140 | */ | 114 | */ |
| 141 | zfcp_qdio_resp_put_back(qdio, count); | 115 | if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count)) |
| 116 | zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2", NULL); | ||
| 142 | } | 117 | } |
| 143 | 118 | ||
| 144 | static struct qdio_buffer_element * | 119 | static struct qdio_buffer_element * |
| @@ -185,17 +160,6 @@ zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) | |||
| 185 | return zfcp_qdio_sbale_curr(qdio, q_req); | 160 | return zfcp_qdio_sbale_curr(qdio, q_req); |
| 186 | } | 161 | } |
| 187 | 162 | ||
| 188 | static void zfcp_qdio_undo_sbals(struct zfcp_qdio *qdio, | ||
| 189 | struct zfcp_qdio_req *q_req) | ||
| 190 | { | ||
| 191 | struct qdio_buffer **sbal = qdio->req_q.sbal; | ||
| 192 | int first = q_req->sbal_first; | ||
| 193 | int last = q_req->sbal_last; | ||
| 194 | int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) % | ||
| 195 | QDIO_MAX_BUFFERS_PER_Q + 1; | ||
| 196 | zfcp_qdio_zero_sbals(sbal, first, count); | ||
| 197 | } | ||
| 198 | |||
| 199 | /** | 163 | /** |
| 200 | * zfcp_qdio_sbals_from_sg - fill SBALs from scatter-gather list | 164 | * zfcp_qdio_sbals_from_sg - fill SBALs from scatter-gather list |
| 201 | * @qdio: pointer to struct zfcp_qdio | 165 | * @qdio: pointer to struct zfcp_qdio |
| @@ -218,7 +182,8 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, | |||
| 218 | sbale = zfcp_qdio_sbale_next(qdio, q_req); | 182 | sbale = zfcp_qdio_sbale_next(qdio, q_req); |
| 219 | if (!sbale) { | 183 | if (!sbale) { |
| 220 | atomic_inc(&qdio->req_q_full); | 184 | atomic_inc(&qdio->req_q_full); |
| 221 | zfcp_qdio_undo_sbals(qdio, q_req); | 185 | zfcp_qdio_zero_sbals(qdio->req_q, q_req->sbal_first, |
| 186 | q_req->sbal_number); | ||
| 222 | return -EINVAL; | 187 | return -EINVAL; |
| 223 | } | 188 | } |
| 224 | 189 | ||
| @@ -237,10 +202,8 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, | |||
| 237 | 202 | ||
| 238 | static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) | 203 | static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) |
| 239 | { | 204 | { |
| 240 | struct zfcp_qdio_queue *req_q = &qdio->req_q; | ||
| 241 | |||
| 242 | spin_lock_bh(&qdio->req_q_lock); | 205 | spin_lock_bh(&qdio->req_q_lock); |
| 243 | if (atomic_read(&req_q->count) || | 206 | if (atomic_read(&qdio->req_q_free) || |
| 244 | !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) | 207 | !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) |
| 245 | return 1; | 208 | return 1; |
| 246 | spin_unlock_bh(&qdio->req_q_lock); | 209 | spin_unlock_bh(&qdio->req_q_lock); |
| @@ -289,25 +252,25 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio) | |||
| 289 | */ | 252 | */ |
| 290 | int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) | 253 | int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) |
| 291 | { | 254 | { |
| 292 | struct zfcp_qdio_queue *req_q = &qdio->req_q; | ||
| 293 | int first = q_req->sbal_first; | ||
| 294 | int count = q_req->sbal_number; | ||
| 295 | int retval; | 255 | int retval; |
| 296 | unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT; | 256 | u8 sbal_number = q_req->sbal_number; |
| 297 | 257 | ||
| 298 | zfcp_qdio_account(qdio); | 258 | zfcp_qdio_account(qdio); |
| 299 | 259 | ||
| 300 | retval = do_QDIO(qdio->adapter->ccw_device, qdio_flags, 0, first, | 260 | retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, |
| 301 | count); | 261 | q_req->sbal_first, sbal_number); |
| 262 | |||
| 302 | if (unlikely(retval)) { | 263 | if (unlikely(retval)) { |
| 303 | zfcp_qdio_zero_sbals(req_q->sbal, first, count); | 264 | zfcp_qdio_zero_sbals(qdio->req_q, q_req->sbal_first, |
| 265 | sbal_number); | ||
| 304 | return retval; | 266 | return retval; |
| 305 | } | 267 | } |
| 306 | 268 | ||
| 307 | /* account for transferred buffers */ | 269 | /* account for transferred buffers */ |
| 308 | atomic_sub(count, &req_q->count); | 270 | atomic_sub(sbal_number, &qdio->req_q_free); |
| 309 | req_q->first += count; | 271 | qdio->req_q_idx += sbal_number; |
| 310 | req_q->first %= QDIO_MAX_BUFFERS_PER_Q; | 272 | qdio->req_q_idx %= QDIO_MAX_BUFFERS_PER_Q; |
| 273 | |||
| 311 | return 0; | 274 | return 0; |
| 312 | } | 275 | } |
| 313 | 276 | ||
| @@ -329,8 +292,8 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, | |||
| 329 | id->input_handler = zfcp_qdio_int_resp; | 292 | id->input_handler = zfcp_qdio_int_resp; |
| 330 | id->output_handler = zfcp_qdio_int_req; | 293 | id->output_handler = zfcp_qdio_int_req; |
| 331 | id->int_parm = (unsigned long) qdio; | 294 | id->int_parm = (unsigned long) qdio; |
| 332 | id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal); | 295 | id->input_sbal_addr_array = (void **) (qdio->res_q); |
| 333 | id->output_sbal_addr_array = (void **) (qdio->req_q.sbal); | 296 | id->output_sbal_addr_array = (void **) (qdio->req_q); |
| 334 | 297 | ||
| 335 | } | 298 | } |
| 336 | /** | 299 | /** |
| @@ -343,8 +306,8 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio) | |||
| 343 | { | 306 | { |
| 344 | struct qdio_initialize init_data; | 307 | struct qdio_initialize init_data; |
| 345 | 308 | ||
| 346 | if (zfcp_qdio_buffers_enqueue(qdio->req_q.sbal) || | 309 | if (zfcp_qdio_buffers_enqueue(qdio->req_q) || |
| 347 | zfcp_qdio_buffers_enqueue(qdio->resp_q.sbal)) | 310 | zfcp_qdio_buffers_enqueue(qdio->res_q)) |
| 348 | return -ENOMEM; | 311 | return -ENOMEM; |
| 349 | 312 | ||
| 350 | zfcp_qdio_setup_init_data(&init_data, qdio); | 313 | zfcp_qdio_setup_init_data(&init_data, qdio); |
| @@ -358,34 +321,30 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio) | |||
| 358 | */ | 321 | */ |
| 359 | void zfcp_qdio_close(struct zfcp_qdio *qdio) | 322 | void zfcp_qdio_close(struct zfcp_qdio *qdio) |
| 360 | { | 323 | { |
| 361 | struct zfcp_qdio_queue *req_q; | 324 | struct zfcp_adapter *adapter = qdio->adapter; |
| 362 | int first, count; | 325 | int idx, count; |
| 363 | 326 | ||
| 364 | if (!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) | 327 | if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) |
| 365 | return; | 328 | return; |
| 366 | 329 | ||
| 367 | /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ | 330 | /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ |
| 368 | req_q = &qdio->req_q; | ||
| 369 | spin_lock_bh(&qdio->req_q_lock); | 331 | spin_lock_bh(&qdio->req_q_lock); |
| 370 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status); | 332 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); |
| 371 | spin_unlock_bh(&qdio->req_q_lock); | 333 | spin_unlock_bh(&qdio->req_q_lock); |
| 372 | 334 | ||
| 373 | wake_up(&qdio->req_q_wq); | 335 | wake_up(&qdio->req_q_wq); |
| 374 | 336 | ||
| 375 | qdio_shutdown(qdio->adapter->ccw_device, | 337 | qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); |
| 376 | QDIO_FLAG_CLEANUP_USING_CLEAR); | ||
| 377 | 338 | ||
| 378 | /* cleanup used outbound sbals */ | 339 | /* cleanup used outbound sbals */ |
| 379 | count = atomic_read(&req_q->count); | 340 | count = atomic_read(&qdio->req_q_free); |
| 380 | if (count < QDIO_MAX_BUFFERS_PER_Q) { | 341 | if (count < QDIO_MAX_BUFFERS_PER_Q) { |
| 381 | first = (req_q->first + count) % QDIO_MAX_BUFFERS_PER_Q; | 342 | idx = (qdio->req_q_idx + count) % QDIO_MAX_BUFFERS_PER_Q; |
| 382 | count = QDIO_MAX_BUFFERS_PER_Q - count; | 343 | count = QDIO_MAX_BUFFERS_PER_Q - count; |
| 383 | zfcp_qdio_zero_sbals(req_q->sbal, first, count); | 344 | zfcp_qdio_zero_sbals(qdio->req_q, idx, count); |
| 384 | } | 345 | } |
| 385 | req_q->first = 0; | 346 | qdio->req_q_idx = 0; |
| 386 | atomic_set(&req_q->count, 0); | 347 | atomic_set(&qdio->req_q_free, 0); |
| 387 | qdio->resp_q.first = 0; | ||
| 388 | atomic_set(&qdio->resp_q.count, 0); | ||
| 389 | } | 348 | } |
| 390 | 349 | ||
| 391 | /** | 350 | /** |
| @@ -397,10 +356,11 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio) | |||
| 397 | { | 356 | { |
| 398 | struct qdio_buffer_element *sbale; | 357 | struct qdio_buffer_element *sbale; |
| 399 | struct qdio_initialize init_data; | 358 | struct qdio_initialize init_data; |
| 400 | struct ccw_device *cdev = qdio->adapter->ccw_device; | 359 | struct zfcp_adapter *adapter = qdio->adapter; |
| 360 | struct ccw_device *cdev = adapter->ccw_device; | ||
| 401 | int cc; | 361 | int cc; |
| 402 | 362 | ||
| 403 | if (atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP) | 363 | if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP) |
| 404 | return -EIO; | 364 | return -EIO; |
| 405 | 365 | ||
| 406 | zfcp_qdio_setup_init_data(&init_data, qdio); | 366 | zfcp_qdio_setup_init_data(&init_data, qdio); |
| @@ -412,19 +372,18 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio) | |||
| 412 | goto failed_qdio; | 372 | goto failed_qdio; |
| 413 | 373 | ||
| 414 | for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) { | 374 | for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) { |
| 415 | sbale = &(qdio->resp_q.sbal[cc]->element[0]); | 375 | sbale = &(qdio->res_q[cc]->element[0]); |
| 416 | sbale->length = 0; | 376 | sbale->length = 0; |
| 417 | sbale->flags = SBAL_FLAGS_LAST_ENTRY; | 377 | sbale->flags = SBAL_FLAGS_LAST_ENTRY; |
| 418 | sbale->addr = NULL; | 378 | sbale->addr = NULL; |
| 419 | } | 379 | } |
| 420 | 380 | ||
| 421 | if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, | 381 | if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q)) |
| 422 | QDIO_MAX_BUFFERS_PER_Q)) | ||
| 423 | goto failed_qdio; | 382 | goto failed_qdio; |
| 424 | 383 | ||
| 425 | /* set index of first avalable SBALS / number of available SBALS */ | 384 | /* set index of first avalable SBALS / number of available SBALS */ |
| 426 | qdio->req_q.first = 0; | 385 | qdio->req_q_idx = 0; |
| 427 | atomic_set(&qdio->req_q.count, QDIO_MAX_BUFFERS_PER_Q); | 386 | atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q); |
| 428 | 387 | ||
| 429 | return 0; | 388 | return 0; |
| 430 | 389 | ||
| @@ -438,7 +397,6 @@ failed_establish: | |||
| 438 | 397 | ||
| 439 | void zfcp_qdio_destroy(struct zfcp_qdio *qdio) | 398 | void zfcp_qdio_destroy(struct zfcp_qdio *qdio) |
| 440 | { | 399 | { |
| 441 | struct qdio_buffer **sbal_req, **sbal_resp; | ||
| 442 | int p; | 400 | int p; |
| 443 | 401 | ||
| 444 | if (!qdio) | 402 | if (!qdio) |
| @@ -447,12 +405,9 @@ void zfcp_qdio_destroy(struct zfcp_qdio *qdio) | |||
| 447 | if (qdio->adapter->ccw_device) | 405 | if (qdio->adapter->ccw_device) |
| 448 | qdio_free(qdio->adapter->ccw_device); | 406 | qdio_free(qdio->adapter->ccw_device); |
| 449 | 407 | ||
| 450 | sbal_req = qdio->req_q.sbal; | ||
| 451 | sbal_resp = qdio->resp_q.sbal; | ||
| 452 | |||
| 453 | for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) { | 408 | for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) { |
| 454 | free_page((unsigned long) sbal_req[p]); | 409 | free_page((unsigned long) qdio->req_q[p]); |
| 455 | free_page((unsigned long) sbal_resp[p]); | 410 | free_page((unsigned long) qdio->res_q[p]); |
| 456 | } | 411 | } |
| 457 | 412 | ||
| 458 | kfree(qdio); | 413 | kfree(qdio); |
diff --git a/drivers/s390/scsi/zfcp_qdio.h b/drivers/s390/scsi/zfcp_qdio.h index 8bb00545f19c..10d0df99dbf4 100644 --- a/drivers/s390/scsi/zfcp_qdio.h +++ b/drivers/s390/scsi/zfcp_qdio.h | |||
| @@ -28,21 +28,11 @@ | |||
| 28 | (ZFCP_QDIO_MAX_SBALS_PER_REQ * ZFCP_QDIO_MAX_SBALES_PER_SBAL - 2) | 28 | (ZFCP_QDIO_MAX_SBALS_PER_REQ * ZFCP_QDIO_MAX_SBALES_PER_SBAL - 2) |
| 29 | 29 | ||
| 30 | /** | 30 | /** |
| 31 | * struct zfcp_qdio_queue - qdio queue buffer, zfcp index and free count | ||
| 32 | * @sbal: qdio buffers | ||
| 33 | * @first: index of next free buffer in queue | ||
| 34 | * @count: number of free buffers in queue | ||
| 35 | */ | ||
| 36 | struct zfcp_qdio_queue { | ||
| 37 | struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; | ||
| 38 | u8 first; | ||
| 39 | atomic_t count; | ||
| 40 | }; | ||
| 41 | |||
| 42 | /** | ||
| 43 | * struct zfcp_qdio - basic qdio data structure | 31 | * struct zfcp_qdio - basic qdio data structure |
| 44 | * @resp_q: response queue | 32 | * @res_q: response queue |
| 45 | * @req_q: request queue | 33 | * @req_q: request queue |
| 34 | * @req_q_idx: index of next free buffer | ||
| 35 | * @req_q_free: number of free buffers in queue | ||
| 46 | * @stat_lock: lock to protect req_q_util and req_q_time | 36 | * @stat_lock: lock to protect req_q_util and req_q_time |
| 47 | * @req_q_lock: lock to serialize access to request queue | 37 | * @req_q_lock: lock to serialize access to request queue |
| 48 | * @req_q_time: time of last fill level change | 38 | * @req_q_time: time of last fill level change |
| @@ -52,8 +42,10 @@ struct zfcp_qdio_queue { | |||
| 52 | * @adapter: adapter used in conjunction with this qdio structure | 42 | * @adapter: adapter used in conjunction with this qdio structure |
| 53 | */ | 43 | */ |
| 54 | struct zfcp_qdio { | 44 | struct zfcp_qdio { |
| 55 | struct zfcp_qdio_queue resp_q; | 45 | struct qdio_buffer *res_q[QDIO_MAX_BUFFERS_PER_Q]; |
| 56 | struct zfcp_qdio_queue req_q; | 46 | struct qdio_buffer *req_q[QDIO_MAX_BUFFERS_PER_Q]; |
| 47 | u8 req_q_idx; | ||
| 48 | atomic_t req_q_free; | ||
| 57 | spinlock_t stat_lock; | 49 | spinlock_t stat_lock; |
| 58 | spinlock_t req_q_lock; | 50 | spinlock_t req_q_lock; |
| 59 | unsigned long long req_q_time; | 51 | unsigned long long req_q_time; |
| @@ -73,7 +65,6 @@ struct zfcp_qdio { | |||
| 73 | * @sbale_curr: current sbale at creation of this request | 65 | * @sbale_curr: current sbale at creation of this request |
| 74 | * @sbal_response: sbal used in interrupt | 66 | * @sbal_response: sbal used in interrupt |
| 75 | * @qdio_outb_usage: usage of outbound queue | 67 | * @qdio_outb_usage: usage of outbound queue |
| 76 | * @qdio_inb_usage: usage of inbound queue | ||
| 77 | */ | 68 | */ |
| 78 | struct zfcp_qdio_req { | 69 | struct zfcp_qdio_req { |
| 79 | u32 sbtype; | 70 | u32 sbtype; |
| @@ -84,22 +75,9 @@ struct zfcp_qdio_req { | |||
| 84 | u8 sbale_curr; | 75 | u8 sbale_curr; |
| 85 | u8 sbal_response; | 76 | u8 sbal_response; |
| 86 | u16 qdio_outb_usage; | 77 | u16 qdio_outb_usage; |
| 87 | u16 qdio_inb_usage; | ||
| 88 | }; | 78 | }; |
| 89 | 79 | ||
| 90 | /** | 80 | /** |
| 91 | * zfcp_qdio_sbale - return pointer to sbale in qdio queue | ||
| 92 | * @q: queue where to find sbal | ||
| 93 | * @sbal_idx: sbal index in queue | ||
| 94 | * @sbale_idx: sbale index in sbal | ||
| 95 | */ | ||
| 96 | static inline struct qdio_buffer_element * | ||
| 97 | zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx) | ||
| 98 | { | ||
| 99 | return &q->sbal[sbal_idx]->element[sbale_idx]; | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 103 | * zfcp_qdio_sbale_req - return pointer to sbale on req_q for a request | 81 | * zfcp_qdio_sbale_req - return pointer to sbale on req_q for a request |
| 104 | * @qdio: pointer to struct zfcp_qdio | 82 | * @qdio: pointer to struct zfcp_qdio |
| 105 | * @q_rec: pointer to struct zfcp_qdio_req | 83 | * @q_rec: pointer to struct zfcp_qdio_req |
| @@ -108,7 +86,7 @@ zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx) | |||
| 108 | static inline struct qdio_buffer_element * | 86 | static inline struct qdio_buffer_element * |
| 109 | zfcp_qdio_sbale_req(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) | 87 | zfcp_qdio_sbale_req(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) |
| 110 | { | 88 | { |
| 111 | return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last, 0); | 89 | return &qdio->req_q[q_req->sbal_last]->element[0]; |
| 112 | } | 90 | } |
| 113 | 91 | ||
| 114 | /** | 92 | /** |
| @@ -120,8 +98,7 @@ zfcp_qdio_sbale_req(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) | |||
| 120 | static inline struct qdio_buffer_element * | 98 | static inline struct qdio_buffer_element * |
| 121 | zfcp_qdio_sbale_curr(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) | 99 | zfcp_qdio_sbale_curr(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) |
| 122 | { | 100 | { |
| 123 | return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last, | 101 | return &qdio->req_q[q_req->sbal_last]->element[q_req->sbale_curr]; |
| 124 | q_req->sbale_curr); | ||
| 125 | } | 102 | } |
| 126 | 103 | ||
| 127 | /** | 104 | /** |
| @@ -142,25 +119,25 @@ void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, | |||
| 142 | unsigned long req_id, u32 sbtype, void *data, u32 len) | 119 | unsigned long req_id, u32 sbtype, void *data, u32 len) |
| 143 | { | 120 | { |
| 144 | struct qdio_buffer_element *sbale; | 121 | struct qdio_buffer_element *sbale; |
| 145 | int count = min(atomic_read(&qdio->req_q.count), | 122 | int count = min(atomic_read(&qdio->req_q_free), |
| 146 | ZFCP_QDIO_MAX_SBALS_PER_REQ); | 123 | ZFCP_QDIO_MAX_SBALS_PER_REQ); |
| 147 | 124 | ||
| 148 | q_req->sbal_first = q_req->sbal_last = qdio->req_q.first; | 125 | q_req->sbal_first = q_req->sbal_last = qdio->req_q_idx; |
| 149 | q_req->sbal_number = 1; | 126 | q_req->sbal_number = 1; |
| 150 | q_req->sbtype = sbtype; | 127 | q_req->sbtype = sbtype; |
| 128 | q_req->sbale_curr = 1; | ||
| 151 | q_req->sbal_limit = (q_req->sbal_first + count - 1) | 129 | q_req->sbal_limit = (q_req->sbal_first + count - 1) |
| 152 | % QDIO_MAX_BUFFERS_PER_Q; | 130 | % QDIO_MAX_BUFFERS_PER_Q; |
| 153 | 131 | ||
| 154 | sbale = zfcp_qdio_sbale_req(qdio, q_req); | 132 | sbale = zfcp_qdio_sbale_req(qdio, q_req); |
| 155 | sbale->addr = (void *) req_id; | 133 | sbale->addr = (void *) req_id; |
| 156 | sbale->flags |= SBAL_FLAGS0_COMMAND; | 134 | sbale->flags = SBAL_FLAGS0_COMMAND | sbtype; |
| 157 | sbale->flags |= sbtype; | ||
| 158 | 135 | ||
| 159 | q_req->sbale_curr = 1; | 136 | if (unlikely(!data)) |
| 137 | return; | ||
| 160 | sbale++; | 138 | sbale++; |
| 161 | sbale->addr = data; | 139 | sbale->addr = data; |
| 162 | if (likely(data)) | 140 | sbale->length = len; |
| 163 | sbale->length = len; | ||
| 164 | } | 141 | } |
| 165 | 142 | ||
| 166 | /** | 143 | /** |
| @@ -232,7 +209,7 @@ static inline | |||
| 232 | void zfcp_qdio_sbal_limit(struct zfcp_qdio *qdio, | 209 | void zfcp_qdio_sbal_limit(struct zfcp_qdio *qdio, |
| 233 | struct zfcp_qdio_req *q_req, int max_sbals) | 210 | struct zfcp_qdio_req *q_req, int max_sbals) |
| 234 | { | 211 | { |
| 235 | int count = min(atomic_read(&qdio->req_q.count), max_sbals); | 212 | int count = min(atomic_read(&qdio->req_q_free), max_sbals); |
| 236 | 213 | ||
| 237 | q_req->sbal_limit = (q_req->sbal_first + count - 1) % | 214 | q_req->sbal_limit = (q_req->sbal_first + count - 1) % |
| 238 | QDIO_MAX_BUFFERS_PER_Q; | 215 | QDIO_MAX_BUFFERS_PER_Q; |
