diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_qdio.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 49 |
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 | ||
47 | static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt) | 47 | static 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 | ||
72 | static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, | 70 | static 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 | ||
122 | static struct qdio_buffer_element * | 120 | static 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 | ||
202 | static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) | 200 | static 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) | |||
277 | static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, | 277 | static 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 | ||