diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index b29f3121b666..74dee32afba8 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -172,12 +172,16 @@ static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id, | |||
172 | struct fsf_link_down_info *link_down) | 172 | struct fsf_link_down_info *link_down) |
173 | { | 173 | { |
174 | struct zfcp_adapter *adapter = req->adapter; | 174 | struct zfcp_adapter *adapter = req->adapter; |
175 | unsigned long flags; | ||
175 | 176 | ||
176 | if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED) | 177 | if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED) |
177 | return; | 178 | return; |
178 | 179 | ||
179 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); | 180 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); |
181 | |||
182 | read_lock_irqsave(&zfcp_data.config_lock, flags); | ||
180 | zfcp_scsi_schedule_rports_block(adapter); | 183 | zfcp_scsi_schedule_rports_block(adapter); |
184 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
181 | 185 | ||
182 | if (!link_down) | 186 | if (!link_down) |
183 | goto out; | 187 | goto out; |
@@ -645,30 +649,30 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) | |||
645 | } | 649 | } |
646 | } | 650 | } |
647 | 651 | ||
648 | static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) | 652 | static int zfcp_fsf_sbal_check(struct zfcp_adapter *adapter) |
649 | __releases(&adapter->req_q_lock) | ||
650 | __acquires(&adapter->req_q_lock) | ||
651 | { | 653 | { |
652 | struct zfcp_qdio_queue *req_q = &adapter->req_q; | 654 | struct zfcp_qdio_queue *req_q = &adapter->req_q; |
653 | long ret; | ||
654 | 655 | ||
655 | if (atomic_read(&req_q->count) <= -REQUEST_LIST_SIZE) | 656 | spin_lock_bh(&adapter->req_q_lock); |
656 | return -EIO; | 657 | if (atomic_read(&req_q->count)) |
657 | if (atomic_read(&req_q->count) > 0) | 658 | return 1; |
658 | return 0; | 659 | spin_unlock_bh(&adapter->req_q_lock); |
660 | return 0; | ||
661 | } | ||
662 | |||
663 | static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) | ||
664 | { | ||
665 | long ret; | ||
659 | 666 | ||
660 | atomic_dec(&req_q->count); | ||
661 | spin_unlock_bh(&adapter->req_q_lock); | 667 | spin_unlock_bh(&adapter->req_q_lock); |
662 | ret = wait_event_interruptible_timeout(adapter->request_wq, | 668 | ret = wait_event_interruptible_timeout(adapter->request_wq, |
663 | atomic_read(&req_q->count) >= 0, | 669 | zfcp_fsf_sbal_check(adapter), 5 * HZ); |
664 | 5 * HZ); | ||
665 | spin_lock_bh(&adapter->req_q_lock); | ||
666 | atomic_inc(&req_q->count); | ||
667 | |||
668 | if (ret > 0) | 670 | if (ret > 0) |
669 | return 0; | 671 | return 0; |
670 | if (!ret) | 672 | if (!ret) |
671 | atomic_inc(&adapter->qdio_outb_full); | 673 | atomic_inc(&adapter->qdio_outb_full); |
674 | |||
675 | spin_lock_bh(&adapter->req_q_lock); | ||
672 | return -EIO; | 676 | return -EIO; |
673 | } | 677 | } |
674 | 678 | ||
@@ -766,8 +770,9 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | |||
766 | static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) | 770 | static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) |
767 | { | 771 | { |
768 | struct zfcp_adapter *adapter = req->adapter; | 772 | struct zfcp_adapter *adapter = req->adapter; |
769 | unsigned long flags; | 773 | unsigned long flags; |
770 | int idx; | 774 | int idx; |
775 | int with_qtcb = (req->qtcb != NULL); | ||
771 | 776 | ||
772 | /* put allocated FSF request into hash table */ | 777 | /* put allocated FSF request into hash table */ |
773 | spin_lock_irqsave(&adapter->req_list_lock, flags); | 778 | spin_lock_irqsave(&adapter->req_list_lock, flags); |
@@ -789,7 +794,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) | |||
789 | } | 794 | } |
790 | 795 | ||
791 | /* Don't increase for unsolicited status */ | 796 | /* Don't increase for unsolicited status */ |
792 | if (req->qtcb) | 797 | if (with_qtcb) |
793 | adapter->fsf_req_seq_no++; | 798 | adapter->fsf_req_seq_no++; |
794 | adapter->req_no++; | 799 | adapter->req_no++; |
795 | 800 | ||
@@ -1253,13 +1258,13 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, | |||
1253 | 1258 | ||
1254 | spin_lock_bh(&adapter->req_q_lock); | 1259 | spin_lock_bh(&adapter->req_q_lock); |
1255 | if (zfcp_fsf_req_sbal_get(adapter)) | 1260 | if (zfcp_fsf_req_sbal_get(adapter)) |
1256 | goto out; | 1261 | goto out_unlock; |
1257 | 1262 | ||
1258 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, | 1263 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, |
1259 | 0, NULL); | 1264 | 0, NULL); |
1260 | if (IS_ERR(req)) { | 1265 | if (IS_ERR(req)) { |
1261 | retval = PTR_ERR(req); | 1266 | retval = PTR_ERR(req); |
1262 | goto out; | 1267 | goto out_unlock; |
1263 | } | 1268 | } |
1264 | 1269 | ||
1265 | sbale = zfcp_qdio_sbale_req(req); | 1270 | sbale = zfcp_qdio_sbale_req(req); |
@@ -1278,14 +1283,16 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, | |||
1278 | 1283 | ||
1279 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | 1284 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); |
1280 | retval = zfcp_fsf_req_send(req); | 1285 | retval = zfcp_fsf_req_send(req); |
1281 | out: | ||
1282 | spin_unlock_bh(&adapter->req_q_lock); | 1286 | spin_unlock_bh(&adapter->req_q_lock); |
1283 | if (!retval) | 1287 | if (!retval) |
1284 | wait_event(req->completion_wq, | 1288 | wait_event(req->completion_wq, |
1285 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | 1289 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); |
1286 | 1290 | ||
1287 | zfcp_fsf_req_free(req); | 1291 | zfcp_fsf_req_free(req); |
1292 | return retval; | ||
1288 | 1293 | ||
1294 | out_unlock: | ||
1295 | spin_unlock_bh(&adapter->req_q_lock); | ||
1289 | return retval; | 1296 | return retval; |
1290 | } | 1297 | } |
1291 | 1298 | ||
@@ -1352,13 +1359,13 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, | |||
1352 | 1359 | ||
1353 | spin_lock_bh(&adapter->req_q_lock); | 1360 | spin_lock_bh(&adapter->req_q_lock); |
1354 | if (zfcp_fsf_req_sbal_get(adapter)) | 1361 | if (zfcp_fsf_req_sbal_get(adapter)) |
1355 | goto out; | 1362 | goto out_unlock; |
1356 | 1363 | ||
1357 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, | 1364 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, |
1358 | NULL); | 1365 | NULL); |
1359 | if (IS_ERR(req)) { | 1366 | if (IS_ERR(req)) { |
1360 | retval = PTR_ERR(req); | 1367 | retval = PTR_ERR(req); |
1361 | goto out; | 1368 | goto out_unlock; |
1362 | } | 1369 | } |
1363 | 1370 | ||
1364 | if (data) | 1371 | if (data) |
@@ -1371,14 +1378,18 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, | |||
1371 | req->handler = zfcp_fsf_exchange_port_data_handler; | 1378 | req->handler = zfcp_fsf_exchange_port_data_handler; |
1372 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | 1379 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); |
1373 | retval = zfcp_fsf_req_send(req); | 1380 | retval = zfcp_fsf_req_send(req); |
1374 | out: | ||
1375 | spin_unlock_bh(&adapter->req_q_lock); | 1381 | spin_unlock_bh(&adapter->req_q_lock); |
1382 | |||
1376 | if (!retval) | 1383 | if (!retval) |
1377 | wait_event(req->completion_wq, | 1384 | wait_event(req->completion_wq, |
1378 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | 1385 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); |
1379 | zfcp_fsf_req_free(req); | 1386 | zfcp_fsf_req_free(req); |
1380 | 1387 | ||
1381 | return retval; | 1388 | return retval; |
1389 | |||
1390 | out_unlock: | ||
1391 | spin_unlock_bh(&adapter->req_q_lock); | ||
1392 | return retval; | ||
1382 | } | 1393 | } |
1383 | 1394 | ||
1384 | static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | 1395 | static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) |
@@ -2472,8 +2483,6 @@ out: | |||
2472 | 2483 | ||
2473 | static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *req) | 2484 | static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *req) |
2474 | { | 2485 | { |
2475 | if (req->qtcb->header.fsf_status != FSF_GOOD) | ||
2476 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | ||
2477 | } | 2486 | } |
2478 | 2487 | ||
2479 | /** | 2488 | /** |