aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_qdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_qdio.c')
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index b2635759721c..d9c40ea73eef 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -41,7 +41,7 @@ static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
41 zfcp_qdio_siosl(adapter); 41 zfcp_qdio_siosl(adapter);
42 zfcp_erp_adapter_reopen(adapter, 42 zfcp_erp_adapter_reopen(adapter,
43 ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | 43 ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
44 ZFCP_STATUS_COMMON_ERP_FAILED, id, NULL); 44 ZFCP_STATUS_COMMON_ERP_FAILED, id);
45} 45}
46 46
47static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt) 47static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
@@ -60,13 +60,11 @@ static inline void zfcp_qdio_account(struct zfcp_qdio *qdio)
60 unsigned long long now, span; 60 unsigned long long now, span;
61 int used; 61 int used;
62 62
63 spin_lock(&qdio->stat_lock);
64 now = get_clock_monotonic(); 63 now = get_clock_monotonic();
65 span = (now - qdio->req_q_time) >> 12; 64 span = (now - qdio->req_q_time) >> 12;
66 used = QDIO_MAX_BUFFERS_PER_Q - atomic_read(&qdio->req_q_free); 65 used = QDIO_MAX_BUFFERS_PER_Q - atomic_read(&qdio->req_q_free);
67 qdio->req_q_util += used * span; 66 qdio->req_q_util += used * span;
68 qdio->req_q_time = now; 67 qdio->req_q_time = now;
69 spin_unlock(&qdio->stat_lock);
70} 68}
71 69
72static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, 70static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
@@ -76,7 +74,6 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
76 struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; 74 struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
77 75
78 if (unlikely(qdio_err)) { 76 if (unlikely(qdio_err)) {
79 zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
80 zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err); 77 zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err);
81 return; 78 return;
82 } 79 }
@@ -84,7 +81,9 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
84 /* cleanup all SBALs being program-owned now */ 81 /* cleanup all SBALs being program-owned now */
85 zfcp_qdio_zero_sbals(qdio->req_q, idx, count); 82 zfcp_qdio_zero_sbals(qdio->req_q, idx, count);
86 83
84 spin_lock_irq(&qdio->stat_lock);
87 zfcp_qdio_account(qdio); 85 zfcp_qdio_account(qdio);
86 spin_unlock_irq(&qdio->stat_lock);
88 atomic_add(count, &qdio->req_q_free); 87 atomic_add(count, &qdio->req_q_free);
89 wake_up(&qdio->req_q_wq); 88 wake_up(&qdio->req_q_wq);
90} 89}
@@ -97,7 +96,6 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
97 int sbal_idx, sbal_no; 96 int sbal_idx, sbal_no;
98 97
99 if (unlikely(qdio_err)) { 98 if (unlikely(qdio_err)) {
100 zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
101 zfcp_qdio_handler_error(qdio, "qdires1", qdio_err); 99 zfcp_qdio_handler_error(qdio, "qdires1", qdio_err);
102 return; 100 return;
103 } 101 }
@@ -116,7 +114,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
116 * put SBALs back to response queue 114 * put SBALs back to response queue
117 */ 115 */
118 if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count)) 116 if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count))
119 zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2", NULL); 117 zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2");
120} 118}
121 119
122static struct qdio_buffer_element * 120static struct qdio_buffer_element *
@@ -126,7 +124,7 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
126 124
127 /* set last entry flag in current SBALE of current SBAL */ 125 /* set last entry flag in current SBALE of current SBAL */
128 sbale = zfcp_qdio_sbale_curr(qdio, q_req); 126 sbale = zfcp_qdio_sbale_curr(qdio, q_req);
129 sbale->flags |= SBAL_FLAGS_LAST_ENTRY; 127 sbale->eflags |= SBAL_EFLAGS_LAST_ENTRY;
130 128
131 /* don't exceed last allowed SBAL */ 129 /* don't exceed last allowed SBAL */
132 if (q_req->sbal_last == q_req->sbal_limit) 130 if (q_req->sbal_last == q_req->sbal_limit)
@@ -134,7 +132,7 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
134 132
135 /* set chaining flag in first SBALE of current SBAL */ 133 /* set chaining flag in first SBALE of current SBAL */
136 sbale = zfcp_qdio_sbale_req(qdio, q_req); 134 sbale = zfcp_qdio_sbale_req(qdio, q_req);
137 sbale->flags |= SBAL_FLAGS0_MORE_SBALS; 135 sbale->sflags |= SBAL_SFLAGS0_MORE_SBALS;
138 136
139 /* calculate index of next SBAL */ 137 /* calculate index of next SBAL */
140 q_req->sbal_last++; 138 q_req->sbal_last++;
@@ -149,7 +147,7 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
149 147
150 /* set storage-block type for new SBAL */ 148 /* set storage-block type for new SBAL */
151 sbale = zfcp_qdio_sbale_curr(qdio, q_req); 149 sbale = zfcp_qdio_sbale_curr(qdio, q_req);
152 sbale->flags |= q_req->sbtype; 150 sbale->sflags |= q_req->sbtype;
153 151
154 return sbale; 152 return sbale;
155} 153}
@@ -179,7 +177,7 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
179 177
180 /* set storage-block type for this request */ 178 /* set storage-block type for this request */
181 sbale = zfcp_qdio_sbale_req(qdio, q_req); 179 sbale = zfcp_qdio_sbale_req(qdio, q_req);
182 sbale->flags |= q_req->sbtype; 180 sbale->sflags |= q_req->sbtype;
183 181
184 for (; sg; sg = sg_next(sg)) { 182 for (; sg; sg = sg_next(sg)) {
185 sbale = zfcp_qdio_sbale_next(qdio, q_req); 183 sbale = zfcp_qdio_sbale_next(qdio, q_req);
@@ -201,11 +199,11 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
201 199
202static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) 200static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio)
203{ 201{
204 spin_lock_bh(&qdio->req_q_lock); 202 spin_lock_irq(&qdio->req_q_lock);
205 if (atomic_read(&qdio->req_q_free) || 203 if (atomic_read(&qdio->req_q_free) ||
206 !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) 204 !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
207 return 1; 205 return 1;
208 spin_unlock_bh(&qdio->req_q_lock); 206 spin_unlock_irq(&qdio->req_q_lock);
209 return 0; 207 return 0;
210} 208}
211 209
@@ -223,7 +221,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio)
223{ 221{
224 long ret; 222 long ret;
225 223
226 spin_unlock_bh(&qdio->req_q_lock); 224 spin_unlock_irq(&qdio->req_q_lock);
227 ret = wait_event_interruptible_timeout(qdio->req_q_wq, 225 ret = wait_event_interruptible_timeout(qdio->req_q_wq,
228 zfcp_qdio_sbal_check(qdio), 5 * HZ); 226 zfcp_qdio_sbal_check(qdio), 5 * HZ);
229 227
@@ -236,10 +234,10 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio)
236 if (!ret) { 234 if (!ret) {
237 atomic_inc(&qdio->req_q_full); 235 atomic_inc(&qdio->req_q_full);
238 /* assume hanging outbound queue, try queue recovery */ 236 /* assume hanging outbound queue, try queue recovery */
239 zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1", NULL); 237 zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1");
240 } 238 }
241 239
242 spin_lock_bh(&qdio->req_q_lock); 240 spin_lock_irq(&qdio->req_q_lock);
243 return -EIO; 241 return -EIO;
244} 242}
245 243
@@ -254,7 +252,9 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
254 int retval; 252 int retval;
255 u8 sbal_number = q_req->sbal_number; 253 u8 sbal_number = q_req->sbal_number;
256 254
255 spin_lock(&qdio->stat_lock);
257 zfcp_qdio_account(qdio); 256 zfcp_qdio_account(qdio);
257 spin_unlock(&qdio->stat_lock);
258 258
259 retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, 259 retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0,
260 q_req->sbal_first, sbal_number); 260 q_req->sbal_first, sbal_number);
@@ -277,16 +277,12 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
277static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, 277static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
278 struct zfcp_qdio *qdio) 278 struct zfcp_qdio *qdio)
279{ 279{
280 280 memset(id, 0, sizeof(*id));
281 id->cdev = qdio->adapter->ccw_device; 281 id->cdev = qdio->adapter->ccw_device;
282 id->q_format = QDIO_ZFCP_QFMT; 282 id->q_format = QDIO_ZFCP_QFMT;
283 memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8); 283 memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8);
284 ASCEBC(id->adapter_name, 8); 284 ASCEBC(id->adapter_name, 8);
285 id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV; 285 id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV;
286 id->qib_param_field_format = 0;
287 id->qib_param_field = NULL;
288 id->input_slib_elements = NULL;
289 id->output_slib_elements = NULL;
290 id->no_input_qs = 1; 286 id->no_input_qs = 1;
291 id->no_output_qs = 1; 287 id->no_output_qs = 1;
292 id->input_handler = zfcp_qdio_int_resp; 288 id->input_handler = zfcp_qdio_int_resp;
@@ -294,6 +290,8 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
294 id->int_parm = (unsigned long) qdio; 290 id->int_parm = (unsigned long) qdio;
295 id->input_sbal_addr_array = (void **) (qdio->res_q); 291 id->input_sbal_addr_array = (void **) (qdio->res_q);
296 id->output_sbal_addr_array = (void **) (qdio->req_q); 292 id->output_sbal_addr_array = (void **) (qdio->req_q);
293 id->scan_threshold =
294 QDIO_MAX_BUFFERS_PER_Q - ZFCP_QDIO_MAX_SBALS_PER_REQ * 2;
297} 295}
298 296
299/** 297/**
@@ -311,6 +309,7 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
311 return -ENOMEM; 309 return -ENOMEM;
312 310
313 zfcp_qdio_setup_init_data(&init_data, qdio); 311 zfcp_qdio_setup_init_data(&init_data, qdio);
312 init_waitqueue_head(&qdio->req_q_wq);
314 313
315 return qdio_allocate(&init_data); 314 return qdio_allocate(&init_data);
316} 315}
@@ -328,9 +327,9 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio)
328 return; 327 return;
329 328
330 /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ 329 /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
331 spin_lock_bh(&qdio->req_q_lock); 330 spin_lock_irq(&qdio->req_q_lock);
332 atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); 331 atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
333 spin_unlock_bh(&qdio->req_q_lock); 332 spin_unlock_irq(&qdio->req_q_lock);
334 333
335 wake_up(&qdio->req_q_wq); 334 wake_up(&qdio->req_q_wq);
336 335
@@ -385,16 +384,18 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
385 for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) { 384 for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) {
386 sbale = &(qdio->res_q[cc]->element[0]); 385 sbale = &(qdio->res_q[cc]->element[0]);
387 sbale->length = 0; 386 sbale->length = 0;
388 sbale->flags = SBAL_FLAGS_LAST_ENTRY; 387 sbale->eflags = SBAL_EFLAGS_LAST_ENTRY;
388 sbale->sflags = 0;
389 sbale->addr = NULL; 389 sbale->addr = NULL;
390 } 390 }
391 391
392 if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q)) 392 if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q))
393 goto failed_qdio; 393 goto failed_qdio;
394 394
395 /* set index of first avalable SBALS / number of available SBALS */ 395 /* set index of first available SBALS / number of available SBALS */
396 qdio->req_q_idx = 0; 396 qdio->req_q_idx = 0;
397 atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q); 397 atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q);
398 atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status);
398 399
399 return 0; 400 return 0;
400 401