aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fsf.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-30 20:43:10 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-30 20:43:10 -0500
commit590cf28580c999c8ba70dc39b40bab09d69e2630 (patch)
tree22b9aa4b148bea8a310b760521d1032eef7d743f /drivers/s390/scsi/zfcp_fsf.c
parentf54a6ec0fd85002d94d05b4bb679508eeb066683 (diff)
parentfb5edd020fa0fbe991f4a473611ad530d2237425 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (104 commits) [SCSI] fcoe: fix configuration problems [SCSI] cxgb3i: fix select/depend problem [SCSI] fcoe: fix incorrect use of struct module [SCSI] cxgb3i: remove use of skb->sp [SCSI] cxgb3i: Add cxgb3i iSCSI driver. [SCSI] zfcp: Remove unnecessary warning message [SCSI] zfcp: Add support for unchained FSF requests [SCSI] zfcp: Remove busid macro [SCSI] zfcp: remove DID_DID flag [SCSI] zfcp: Simplify mask lookups for incoming RSCNs [SCSI] zfcp: Remove initial device data from zfcp_data [SCSI] zfcp: fix compile warning [SCSI] zfcp: Remove adapter list [SCSI] zfcp: Simplify SBAL allocation to fix sparse warnings [SCSI] zfcp: register with SCSI layer on ccw registration [SCSI] zfcp: Fix message line break [SCSI] qla2xxx: changes in multiq code [SCSI] eata: fix the data buffer accessors conversion regression [SCSI] ibmvfc: Improve async event handling [SCSI] lpfc : correct printk types on PPC compiles ...
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c77
1 files changed, 44 insertions, 33 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 9c72e083559d..e6416f8541b0 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -644,38 +644,38 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
644 } 644 }
645} 645}
646 646
647static int zfcp_fsf_sbal_check(struct zfcp_adapter *adapter) 647static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter)
648{ 648{
649 struct zfcp_qdio_queue *req_q = &adapter->req_q; 649 if (atomic_read(&adapter->req_q.count) > 0)
650
651 spin_lock_bh(&adapter->req_q_lock);
652 if (atomic_read(&req_q->count))
653 return 1; 650 return 1;
654 spin_unlock_bh(&adapter->req_q_lock); 651 atomic_inc(&adapter->qdio_outb_full);
655 return 0; 652 return 0;
656} 653}
657 654
658static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter)
659{
660 unsigned int count = atomic_read(&adapter->req_q.count);
661 if (!count)
662 atomic_inc(&adapter->qdio_outb_full);
663 return count > 0;
664}
665
666static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) 655static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
656 __releases(&adapter->req_q_lock)
657 __acquires(&adapter->req_q_lock)
667{ 658{
659 struct zfcp_qdio_queue *req_q = &adapter->req_q;
668 long ret; 660 long ret;
669 661
662 if (atomic_read(&req_q->count) <= -REQUEST_LIST_SIZE)
663 return -EIO;
664 if (atomic_read(&req_q->count) > 0)
665 return 0;
666
667 atomic_dec(&req_q->count);
670 spin_unlock_bh(&adapter->req_q_lock); 668 spin_unlock_bh(&adapter->req_q_lock);
671 ret = wait_event_interruptible_timeout(adapter->request_wq, 669 ret = wait_event_interruptible_timeout(adapter->request_wq,
672 zfcp_fsf_sbal_check(adapter), 5 * HZ); 670 atomic_read(&req_q->count) >= 0,
671 5 * HZ);
672 spin_lock_bh(&adapter->req_q_lock);
673 atomic_inc(&req_q->count);
674
673 if (ret > 0) 675 if (ret > 0)
674 return 0; 676 return 0;
675 if (!ret) 677 if (!ret)
676 atomic_inc(&adapter->qdio_outb_full); 678 atomic_inc(&adapter->qdio_outb_full);
677
678 spin_lock_bh(&adapter->req_q_lock);
679 return -EIO; 679 return -EIO;
680} 680}
681 681
@@ -1013,12 +1013,29 @@ skip_fsfstatus:
1013 send_ct->handler(send_ct->handler_data); 1013 send_ct->handler(send_ct->handler_data);
1014} 1014}
1015 1015
1016static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req, 1016static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
1017 struct scatterlist *sg_req, 1017 struct scatterlist *sg_req,
1018 struct scatterlist *sg_resp, int max_sbals) 1018 struct scatterlist *sg_resp,
1019 int max_sbals)
1019{ 1020{
1021 struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(req);
1022 u32 feat = req->adapter->adapter_features;
1020 int bytes; 1023 int bytes;
1021 1024
1025 if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) {
1026 if (sg_req->length > PAGE_SIZE || sg_resp->length > PAGE_SIZE ||
1027 !sg_is_last(sg_req) || !sg_is_last(sg_resp))
1028 return -EOPNOTSUPP;
1029
1030 sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;
1031 sbale[2].addr = sg_virt(sg_req);
1032 sbale[2].length = sg_req->length;
1033 sbale[3].addr = sg_virt(sg_resp);
1034 sbale[3].length = sg_resp->length;
1035 sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
1036 return 0;
1037 }
1038
1022 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ, 1039 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,
1023 sg_req, max_sbals); 1040 sg_req, max_sbals);
1024 if (bytes <= 0) 1041 if (bytes <= 0)
@@ -1060,8 +1077,8 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
1060 goto out; 1077 goto out;
1061 } 1078 }
1062 1079
1063 ret = zfcp_fsf_setup_sbals(req, ct->req, ct->resp, 1080 ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp,
1064 FSF_MAX_SBALS_PER_REQ); 1081 FSF_MAX_SBALS_PER_REQ);
1065 if (ret) 1082 if (ret)
1066 goto failed_send; 1083 goto failed_send;
1067 1084
@@ -1171,7 +1188,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
1171 goto out; 1188 goto out;
1172 } 1189 }
1173 1190
1174 ret = zfcp_fsf_setup_sbals(req, els->req, els->resp, 2); 1191 ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2);
1175 1192
1176 if (ret) 1193 if (ret)
1177 goto failed_send; 1194 goto failed_send;
@@ -1406,13 +1423,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1406 switch (header->fsf_status_qual.word[0]) { 1423 switch (header->fsf_status_qual.word[0]) {
1407 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: 1424 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
1408 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: 1425 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
1409 req->status |= ZFCP_STATUS_FSFREQ_ERROR;
1410 break;
1411 case FSF_SQ_NO_RETRY_POSSIBLE: 1426 case FSF_SQ_NO_RETRY_POSSIBLE:
1412 dev_warn(&req->adapter->ccw_device->dev,
1413 "Remote port 0x%016Lx could not be opened\n",
1414 (unsigned long long)port->wwpn);
1415 zfcp_erp_port_failed(port, 32, req);
1416 req->status |= ZFCP_STATUS_FSFREQ_ERROR; 1427 req->status |= ZFCP_STATUS_FSFREQ_ERROR;
1417 break; 1428 break;
1418 } 1429 }
@@ -1440,10 +1451,10 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1440 * Alternately, an ADISC/PDISC ELS should suffice, as well. 1451 * Alternately, an ADISC/PDISC ELS should suffice, as well.
1441 */ 1452 */
1442 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; 1453 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
1443 if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) { 1454 if (req->qtcb->bottom.support.els1_length >=
1455 FSF_PLOGI_MIN_LEN) {
1444 if (plogi->serv_param.wwpn != port->wwpn) 1456 if (plogi->serv_param.wwpn != port->wwpn)
1445 atomic_clear_mask(ZFCP_STATUS_PORT_DID_DID, 1457 port->d_id = 0;
1446 &port->status);
1447 else { 1458 else {
1448 port->wwnn = plogi->serv_param.wwnn; 1459 port->wwnn = plogi->serv_param.wwnn;
1449 zfcp_fc_plogi_evaluate(port, plogi); 1460 zfcp_fc_plogi_evaluate(port, plogi);
@@ -1907,7 +1918,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
1907 dev_err(&adapter->ccw_device->dev, 1918 dev_err(&adapter->ccw_device->dev,
1908 "Shared read-write access not " 1919 "Shared read-write access not "
1909 "supported (unit 0x%016Lx, port " 1920 "supported (unit 0x%016Lx, port "
1910 "0x%016Lx\n)", 1921 "0x%016Lx)\n",
1911 (unsigned long long)unit->fcp_lun, 1922 (unsigned long long)unit->fcp_lun,
1912 (unsigned long long)unit->port->wwpn); 1923 (unsigned long long)unit->port->wwpn);
1913 zfcp_erp_unit_failed(unit, 36, req); 1924 zfcp_erp_unit_failed(unit, 36, req);