aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fsf.c
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2008-10-01 06:42:17 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-10-03 13:11:53 -0400
commit5ab944f97e09a3d52951fe903eed9a7b88d810b2 (patch)
tree266171323bd7c5dfc433efd70ca19aafc891598c /drivers/s390/scsi/zfcp_fsf.c
parent44cc76f2d154aa24340354b4711a0fe7f8f08adc (diff)
[SCSI] zfcp: attach and release SAN nameserver port on demand
Changing the zfcp behaviour from always having the nameserver port open to an on-demand strategy. This strategy reduces the use of limited resources like port connections. The patch provides a common infrastructure which could be used for all WKA ports in future. Also reduce the number of nameserver lookups by changing the zfcp behaviour of always querying the nameserver for the corresponding destination ID of the remote port. If the destination ID has changed during the reopen process we will be informed and then trigger a nameserver query on demand. Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c137
1 files changed, 127 insertions, 10 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index af75fd2ef1e2..23dd9088153f 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -961,7 +961,6 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
961{ 961{
962 struct zfcp_adapter *adapter = req->adapter; 962 struct zfcp_adapter *adapter = req->adapter;
963 struct zfcp_send_ct *send_ct = req->data; 963 struct zfcp_send_ct *send_ct = req->data;
964 struct zfcp_port *port = send_ct->port;
965 struct fsf_qtcb_header *header = &req->qtcb->header; 964 struct fsf_qtcb_header *header = &req->qtcb->header;
966 965
967 send_ct->status = -EINVAL; 966 send_ct->status = -EINVAL;
@@ -980,17 +979,14 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
980 case FSF_ADAPTER_STATUS_AVAILABLE: 979 case FSF_ADAPTER_STATUS_AVAILABLE:
981 switch (header->fsf_status_qual.word[0]){ 980 switch (header->fsf_status_qual.word[0]){
982 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: 981 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
983 zfcp_test_link(port);
984 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: 982 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
985 req->status |= ZFCP_STATUS_FSFREQ_ERROR; 983 req->status |= ZFCP_STATUS_FSFREQ_ERROR;
986 break; 984 break;
987 } 985 }
988 break; 986 break;
989 case FSF_ACCESS_DENIED: 987 case FSF_ACCESS_DENIED:
990 zfcp_fsf_access_denied_port(req, port);
991 break; 988 break;
992 case FSF_PORT_BOXED: 989 case FSF_PORT_BOXED:
993 zfcp_erp_port_boxed(port, 49, req);
994 req->status |= ZFCP_STATUS_FSFREQ_ERROR | 990 req->status |= ZFCP_STATUS_FSFREQ_ERROR |
995 ZFCP_STATUS_FSFREQ_RETRY; 991 ZFCP_STATUS_FSFREQ_RETRY;
996 break; 992 break;
@@ -1041,8 +1037,8 @@ static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req,
1041int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, 1037int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
1042 struct zfcp_erp_action *erp_action) 1038 struct zfcp_erp_action *erp_action)
1043{ 1039{
1044 struct zfcp_port *port = ct->port; 1040 struct zfcp_wka_port *wka_port = ct->wka_port;
1045 struct zfcp_adapter *adapter = port->adapter; 1041 struct zfcp_adapter *adapter = wka_port->adapter;
1046 struct zfcp_fsf_req *req; 1042 struct zfcp_fsf_req *req;
1047 int ret = -EIO; 1043 int ret = -EIO;
1048 1044
@@ -1063,7 +1059,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
1063 goto failed_send; 1059 goto failed_send;
1064 1060
1065 req->handler = zfcp_fsf_send_ct_handler; 1061 req->handler = zfcp_fsf_send_ct_handler;
1066 req->qtcb->header.port_handle = port->handle; 1062 req->qtcb->header.port_handle = wka_port->handle;
1067 req->qtcb->bottom.support.service_class = FSF_CLASS_3; 1063 req->qtcb->bottom.support.service_class = FSF_CLASS_3;
1068 req->qtcb->bottom.support.timeout = ct->timeout; 1064 req->qtcb->bottom.support.timeout = ct->timeout;
1069 req->data = ct; 1065 req->data = ct;
@@ -1435,9 +1431,6 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1435 * another GID_PN straight after a port has been opened. 1431 * another GID_PN straight after a port has been opened.
1436 * Alternately, an ADISC/PDISC ELS should suffice, as well. 1432 * Alternately, an ADISC/PDISC ELS should suffice, as well.
1437 */ 1433 */
1438 if (atomic_read(&port->status) & ZFCP_STATUS_PORT_NO_WWPN)
1439 break;
1440
1441 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; 1434 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
1442 if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) { 1435 if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) {
1443 if (plogi->serv_param.wwpn != port->wwpn) 1436 if (plogi->serv_param.wwpn != port->wwpn)
@@ -1568,6 +1561,130 @@ out:
1568 return retval; 1561 return retval;
1569} 1562}
1570 1563
1564static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req)
1565{
1566 struct zfcp_wka_port *wka_port = req->data;
1567 struct fsf_qtcb_header *header = &req->qtcb->header;
1568
1569 if (req->status & ZFCP_STATUS_FSFREQ_ERROR) {
1570 wka_port->status = ZFCP_WKA_PORT_OFFLINE;
1571 goto out;
1572 }
1573
1574 switch (header->fsf_status) {
1575 case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED:
1576 dev_warn(&req->adapter->ccw_device->dev,
1577 "Opening WKA port 0x%x failed\n", wka_port->d_id);
1578 case FSF_ADAPTER_STATUS_AVAILABLE:
1579 req->status |= ZFCP_STATUS_FSFREQ_ERROR;
1580 case FSF_ACCESS_DENIED:
1581 wka_port->status = ZFCP_WKA_PORT_OFFLINE;
1582 break;
1583 case FSF_PORT_ALREADY_OPEN:
1584 case FSF_GOOD:
1585 wka_port->handle = header->port_handle;
1586 wka_port->status = ZFCP_WKA_PORT_ONLINE;
1587 }
1588out:
1589 wake_up(&wka_port->completion_wq);
1590}
1591
1592/**
1593 * zfcp_fsf_open_wka_port - create and send open wka-port request
1594 * @wka_port: pointer to struct zfcp_wka_port
1595 * Returns: 0 on success, error otherwise
1596 */
1597int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port)
1598{
1599 struct qdio_buffer_element *sbale;
1600 struct zfcp_adapter *adapter = wka_port->adapter;
1601 struct zfcp_fsf_req *req;
1602 int retval = -EIO;
1603
1604 spin_lock_bh(&adapter->req_q.lock);
1605 if (zfcp_fsf_req_sbal_get(adapter))
1606 goto out;
1607
1608 req = zfcp_fsf_req_create(adapter,
1609 FSF_QTCB_OPEN_PORT_WITH_DID,
1610 ZFCP_REQ_AUTO_CLEANUP,
1611 adapter->pool.fsf_req_erp);
1612 if (unlikely(IS_ERR(req))) {
1613 retval = PTR_ERR(req);
1614 goto out;
1615 }
1616
1617 sbale = zfcp_qdio_sbale_req(req);
1618 sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
1619 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
1620
1621 req->handler = zfcp_fsf_open_wka_port_handler;
1622 req->qtcb->bottom.support.d_id = wka_port->d_id;
1623 req->data = wka_port;
1624
1625 zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
1626 retval = zfcp_fsf_req_send(req);
1627 if (retval)
1628 zfcp_fsf_req_free(req);
1629out:
1630 spin_unlock_bh(&adapter->req_q.lock);
1631 return retval;
1632}
1633
1634static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
1635{
1636 struct zfcp_wka_port *wka_port = req->data;
1637
1638 if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) {
1639 req->status |= ZFCP_STATUS_FSFREQ_ERROR;
1640 zfcp_erp_adapter_reopen(wka_port->adapter, 0, 107, req);
1641 }
1642
1643 wka_port->status = ZFCP_WKA_PORT_OFFLINE;
1644 wake_up(&wka_port->completion_wq);
1645}
1646
1647/**
1648 * zfcp_fsf_close_wka_port - create and send close wka port request
1649 * @erp_action: pointer to struct zfcp_erp_action
1650 * Returns: 0 on success, error otherwise
1651 */
1652int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port)
1653{
1654 struct qdio_buffer_element *sbale;
1655 struct zfcp_adapter *adapter = wka_port->adapter;
1656 struct zfcp_fsf_req *req;
1657 int retval = -EIO;
1658
1659 spin_lock_bh(&adapter->req_q.lock);
1660 if (zfcp_fsf_req_sbal_get(adapter))
1661 goto out;
1662
1663 req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT,
1664 ZFCP_REQ_AUTO_CLEANUP,
1665 adapter->pool.fsf_req_erp);
1666 if (unlikely(IS_ERR(req))) {
1667 retval = PTR_ERR(req);
1668 goto out;
1669 }
1670
1671 sbale = zfcp_qdio_sbale_req(req);
1672 sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
1673 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
1674
1675 req->handler = zfcp_fsf_close_wka_port_handler;
1676 req->data = wka_port;
1677 req->qtcb->header.port_handle = wka_port->handle;
1678
1679 zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
1680 retval = zfcp_fsf_req_send(req);
1681 if (retval)
1682 zfcp_fsf_req_free(req);
1683out:
1684 spin_unlock_bh(&adapter->req_q.lock);
1685 return retval;
1686}
1687
1571static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) 1688static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
1572{ 1689{
1573 struct zfcp_port *port = req->data; 1690 struct zfcp_port *port = req->data;