From 1674b4054744c2cfd6573e43eca45d86ff581d0e Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Fri, 30 Apr 2010 18:09:34 +0200 Subject: [SCSI] zfcp: Move sbale handling to zfcp_qdio files Move the code accessing the qdio sbales and zfcp_qdio_req struct to the zfcp_qdio files and provide helper functions for accessing the qdio related parts. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fsf.c | 180 ++++++++++++++++--------------------------- 1 file changed, 67 insertions(+), 113 deletions(-) (limited to 'drivers/s390/scsi/zfcp_fsf.c') diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 18564891ea61..ec1b49a75532 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -705,10 +705,9 @@ static struct fsf_qtcb *zfcp_qtcb_alloc(mempool_t *pool) } static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio, - u32 fsf_cmd, mempool_t *pool) + u32 fsf_cmd, u32 sbtype, + mempool_t *pool) { - struct qdio_buffer_element *sbale; - struct zfcp_qdio_queue *req_q = &qdio->req_q; struct zfcp_adapter *adapter = qdio->adapter; struct zfcp_fsf_req *req = zfcp_fsf_alloc(pool); @@ -725,14 +724,6 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio, req->adapter = adapter; req->fsf_command = fsf_cmd; req->req_id = adapter->req_no; - req->qdio_req.sbal_number = 1; - req->qdio_req.sbal_first = req_q->first; - req->qdio_req.sbal_last = req_q->first; - req->qdio_req.sbale_curr = 1; - - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].addr = (void *) req->req_id; - sbale[0].flags |= SBAL_FLAGS0_COMMAND; if (likely(fsf_cmd != FSF_QTCB_UNSOLICITED_STATUS)) { if (likely(pool)) @@ -753,10 +744,11 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio, req->qtcb->prefix.qtcb_version = FSF_QTCB_CURRENT_VERSION; req->qtcb->header.req_handle = req->req_id; req->qtcb->header.fsf_command = req->fsf_command; - sbale[1].addr = (void *) req->qtcb; - sbale[1].length = sizeof(struct fsf_qtcb); } + zfcp_qdio_req_init(adapter->qdio, &req->qdio_req, req->req_id, sbtype, + req->qtcb, sizeof(struct fsf_qtcb)); + if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) { zfcp_fsf_req_free(req); return ERR_PTR(-EIO); @@ -803,24 +795,19 @@ int zfcp_fsf_status_read(struct zfcp_qdio *qdio) struct zfcp_adapter *adapter = qdio->adapter; struct zfcp_fsf_req *req; struct fsf_status_read_buffer *sr_buf; - struct qdio_buffer_element *sbale; int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); if (zfcp_fsf_req_sbal_get(qdio)) goto out; - req = zfcp_fsf_req_create(qdio, FSF_QTCB_UNSOLICITED_STATUS, + req = zfcp_fsf_req_create(qdio, FSF_QTCB_UNSOLICITED_STATUS, 0, adapter->pool.status_read_req); if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; - req->qdio_req.sbale_curr = 2; - sr_buf = mempool_alloc(adapter->pool.status_read_data, GFP_ATOMIC); if (!sr_buf) { retval = -ENOMEM; @@ -828,9 +815,9 @@ int zfcp_fsf_status_read(struct zfcp_qdio *qdio) } memset(sr_buf, 0, sizeof(*sr_buf)); req->data = sr_buf; - sbale = zfcp_qdio_sbale_curr(qdio, &req->qdio_req); - sbale->addr = (void *) sr_buf; - sbale->length = sizeof(*sr_buf); + + zfcp_qdio_fill_next(qdio, &req->qdio_req, sr_buf, sizeof(*sr_buf)); + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); retval = zfcp_fsf_req_send(req); if (retval) @@ -907,7 +894,6 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req) struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, struct zfcp_unit *unit) { - struct qdio_buffer_element *sbale; struct zfcp_fsf_req *req = NULL; struct zfcp_qdio *qdio = unit->port->adapter->qdio; @@ -915,6 +901,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, if (zfcp_fsf_req_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_ABORT_FCP_CMND, + SBAL_FLAGS0_TYPE_READ, qdio->adapter->pool.scsi_abort); if (IS_ERR(req)) { req = NULL; @@ -925,9 +912,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, ZFCP_STATUS_COMMON_UNBLOCKED))) goto out_error_free; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->data = unit; req->handler = zfcp_fsf_abort_fcp_command_handler; @@ -996,21 +981,14 @@ skip_fsfstatus: ct->handler(ct->handler_data); } -static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale, +static void zfcp_fsf_setup_ct_els_unchained(struct zfcp_qdio *qdio, + struct zfcp_qdio_req *q_req, struct scatterlist *sg_req, struct scatterlist *sg_resp) { - sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ; - sbale[2].addr = sg_virt(sg_req); - sbale[2].length = sg_req->length; - sbale[3].addr = sg_virt(sg_resp); - sbale[3].length = sg_resp->length; - sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; -} - -static int zfcp_fsf_one_sbal(struct scatterlist *sg) -{ - return sg_is_last(sg) && sg->length <= PAGE_SIZE; + zfcp_qdio_fill_next(qdio, q_req, sg_virt(sg_req), sg_req->length); + zfcp_qdio_fill_next(qdio, q_req, sg_virt(sg_resp), sg_resp->length); + zfcp_qdio_set_sbale_last(qdio, q_req); } static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, @@ -1019,35 +997,34 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, int max_sbals) { struct zfcp_adapter *adapter = req->adapter; - struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(adapter->qdio, - &req->qdio_req); u32 feat = adapter->adapter_features; int bytes; if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) { - if (!zfcp_fsf_one_sbal(sg_req) || !zfcp_fsf_one_sbal(sg_resp)) + if (!zfcp_qdio_sg_one_sbale(sg_req) || + !zfcp_qdio_sg_one_sbale(sg_resp)) return -EOPNOTSUPP; - zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp); + zfcp_fsf_setup_ct_els_unchained(adapter->qdio, &req->qdio_req, + sg_req, sg_resp); return 0; } /* use single, unchained SBAL if it can hold the request */ - if (zfcp_fsf_one_sbal(sg_req) && zfcp_fsf_one_sbal(sg_resp)) { - zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp); + if (zfcp_qdio_sg_one_sbale(sg_req) || zfcp_qdio_sg_one_sbale(sg_resp)) { + zfcp_fsf_setup_ct_els_unchained(adapter->qdio, &req->qdio_req, + sg_req, sg_resp); return 0; } bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req, - SBAL_FLAGS0_TYPE_WRITE_READ, sg_req, max_sbals); if (bytes <= 0) return -EIO; req->qtcb->bottom.support.req_buf_length = bytes; - req->qdio_req.sbale_curr = ZFCP_LAST_SBALE_PER_SBAL; + zfcp_qdio_skip_to_last_sbale(&req->qdio_req); bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req, - SBAL_FLAGS0_TYPE_WRITE_READ, sg_resp, max_sbals); req->qtcb->bottom.support.resp_buf_length = bytes; if (bytes <= 0) @@ -1094,7 +1071,8 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, if (zfcp_fsf_req_sbal_get(qdio)) goto out; - req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_GENERIC, pool); + req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_GENERIC, + SBAL_FLAGS0_TYPE_WRITE_READ, pool); if (IS_ERR(req)) { ret = PTR_ERR(req); @@ -1103,7 +1081,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, - FSF_MAX_SBALS_PER_REQ, timeout); + ZFCP_FSF_MAX_SBALS_PER_REQ, timeout); if (ret) goto failed_send; @@ -1190,7 +1168,8 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, if (zfcp_fsf_req_sbal_get(qdio)) goto out; - req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_ELS, NULL); + req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_ELS, + SBAL_FLAGS0_TYPE_WRITE_READ, NULL); if (IS_ERR(req)) { ret = PTR_ERR(req); @@ -1224,7 +1203,6 @@ out: int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) { - struct qdio_buffer_element *sbale; struct zfcp_fsf_req *req; struct zfcp_qdio *qdio = erp_action->adapter->qdio; int retval = -EIO; @@ -1234,6 +1212,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA, + SBAL_FLAGS0_TYPE_READ, qdio->adapter->pool.erp_req); if (IS_ERR(req)) { @@ -1242,9 +1221,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->qtcb->bottom.config.feature_selection = FSF_FEATURE_CFDC | @@ -1269,7 +1246,6 @@ out: int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio, struct fsf_qtcb_bottom_config *data) { - struct qdio_buffer_element *sbale; struct zfcp_fsf_req *req = NULL; int retval = -EIO; @@ -1277,16 +1253,15 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio, if (zfcp_fsf_req_sbal_get(qdio)) goto out_unlock; - req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA, NULL); + req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA, + SBAL_FLAGS0_TYPE_READ, NULL); if (IS_ERR(req)) { retval = PTR_ERR(req); goto out_unlock; } - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->handler = zfcp_fsf_exchange_config_data_handler; req->qtcb->bottom.config.feature_selection = @@ -1320,7 +1295,6 @@ out_unlock: int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) { struct zfcp_qdio *qdio = erp_action->adapter->qdio; - struct qdio_buffer_element *sbale; struct zfcp_fsf_req *req; int retval = -EIO; @@ -1332,6 +1306,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA, + SBAL_FLAGS0_TYPE_READ, qdio->adapter->pool.erp_req); if (IS_ERR(req)) { @@ -1340,9 +1315,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->handler = zfcp_fsf_exchange_port_data_handler; req->erp_action = erp_action; @@ -1368,7 +1341,6 @@ out: int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio, struct fsf_qtcb_bottom_port *data) { - struct qdio_buffer_element *sbale; struct zfcp_fsf_req *req = NULL; int retval = -EIO; @@ -1379,7 +1351,8 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio, if (zfcp_fsf_req_sbal_get(qdio)) goto out_unlock; - req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA, NULL); + req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA, + SBAL_FLAGS0_TYPE_READ, NULL); if (IS_ERR(req)) { retval = PTR_ERR(req); @@ -1389,9 +1362,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio, if (data) req->data = data; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->handler = zfcp_fsf_exchange_port_data_handler; zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); @@ -1485,7 +1456,6 @@ out: */ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) { - struct qdio_buffer_element *sbale; struct zfcp_qdio *qdio = erp_action->adapter->qdio; struct zfcp_port *port = erp_action->port; struct zfcp_fsf_req *req; @@ -1496,6 +1466,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID, + SBAL_FLAGS0_TYPE_READ, qdio->adapter->pool.erp_req); if (IS_ERR(req)) { @@ -1504,9 +1475,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->handler = zfcp_fsf_open_port_handler; hton24(req->qtcb->bottom.support.d_id, port->d_id); @@ -1556,7 +1525,6 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req) */ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) { - struct qdio_buffer_element *sbale; struct zfcp_qdio *qdio = erp_action->adapter->qdio; struct zfcp_fsf_req *req; int retval = -EIO; @@ -1566,6 +1534,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT, + SBAL_FLAGS0_TYPE_READ, qdio->adapter->pool.erp_req); if (IS_ERR(req)) { @@ -1574,9 +1543,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->handler = zfcp_fsf_close_port_handler; req->data = erp_action->port; @@ -1633,7 +1600,6 @@ out: */ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) { - struct qdio_buffer_element *sbale; struct zfcp_qdio *qdio = wka_port->adapter->qdio; struct zfcp_fsf_req *req; int retval = -EIO; @@ -1643,6 +1609,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID, + SBAL_FLAGS0_TYPE_READ, qdio->adapter->pool.erp_req); if (unlikely(IS_ERR(req))) { @@ -1651,9 +1618,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->handler = zfcp_fsf_open_wka_port_handler; hton24(req->qtcb->bottom.support.d_id, wka_port->d_id); @@ -1688,7 +1653,6 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req) */ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) { - struct qdio_buffer_element *sbale; struct zfcp_qdio *qdio = wka_port->adapter->qdio; struct zfcp_fsf_req *req; int retval = -EIO; @@ -1698,6 +1662,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT, + SBAL_FLAGS0_TYPE_READ, qdio->adapter->pool.erp_req); if (unlikely(IS_ERR(req))) { @@ -1706,9 +1671,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->handler = zfcp_fsf_close_wka_port_handler; req->data = wka_port; @@ -1782,7 +1745,6 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) */ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) { - struct qdio_buffer_element *sbale; struct zfcp_qdio *qdio = erp_action->adapter->qdio; struct zfcp_fsf_req *req; int retval = -EIO; @@ -1792,6 +1754,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PHYSICAL_PORT, + SBAL_FLAGS0_TYPE_READ, qdio->adapter->pool.erp_req); if (IS_ERR(req)) { @@ -1800,9 +1763,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->data = erp_action->port; req->qtcb->header.port_handle = erp_action->port->handle; @@ -1954,7 +1915,6 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) */ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) { - struct qdio_buffer_element *sbale; struct zfcp_adapter *adapter = erp_action->adapter; struct zfcp_qdio *qdio = adapter->qdio; struct zfcp_fsf_req *req; @@ -1965,6 +1925,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_LUN, + SBAL_FLAGS0_TYPE_READ, adapter->pool.erp_req); if (IS_ERR(req)) { @@ -1973,9 +1934,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->qtcb->header.port_handle = erp_action->port->handle; req->qtcb->bottom.support.fcp_lun = erp_action->unit->fcp_lun; @@ -2041,7 +2000,6 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req) */ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) { - struct qdio_buffer_element *sbale; struct zfcp_qdio *qdio = erp_action->adapter->qdio; struct zfcp_fsf_req *req; int retval = -EIO; @@ -2051,6 +2009,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_LUN, + SBAL_FLAGS0_TYPE_READ, qdio->adapter->pool.erp_req); if (IS_ERR(req)) { @@ -2059,9 +2018,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->qtcb->header.port_handle = erp_action->port->handle; req->qtcb->header.lun_handle = erp_action->unit->handle; @@ -2289,8 +2246,11 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, goto out; } + if (scsi_cmnd->sc_data_direction == DMA_TO_DEVICE) + sbtype = SBAL_FLAGS0_TYPE_WRITE; + req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND, - adapter->pool.scsi_req); + sbtype, adapter->pool.scsi_req); if (IS_ERR(req)) { retval = PTR_ERR(req); @@ -2298,7 +2258,6 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, } req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; - get_device(&unit->dev); req->unit = unit; req->data = scsi_cmnd; req->handler = zfcp_fsf_send_fcp_command_handler; @@ -2323,20 +2282,21 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, break; case DMA_TO_DEVICE: req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE; - sbtype = SBAL_FLAGS0_TYPE_WRITE; break; case DMA_BIDIRECTIONAL: goto failed_scsi_cmnd; } + get_device(&unit->dev); + fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd); - real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sbtype, + real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, scsi_sglist(scsi_cmnd), - FSF_MAX_SBALS_PER_REQ); + ZFCP_FSF_MAX_SBALS_PER_REQ); if (unlikely(real_bytes < 0)) { - if (req->qdio_req.sbal_number >= FSF_MAX_SBALS_PER_REQ) { + if (req->qdio_req.sbal_number >= ZFCP_FSF_MAX_SBALS_PER_REQ) { dev_err(&adapter->ccw_device->dev, "Oversize data package, unit 0x%016Lx " "on port 0x%016Lx closed\n", @@ -2371,7 +2331,6 @@ out: */ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) { - struct qdio_buffer_element *sbale; struct zfcp_fsf_req *req = NULL; struct fcp_cmnd *fcp_cmnd; struct zfcp_qdio *qdio = unit->port->adapter->qdio; @@ -2385,6 +2344,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND, + SBAL_FLAGS0_TYPE_WRITE, qdio->adapter->pool.scsi_req); if (IS_ERR(req)) { @@ -2401,9 +2361,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) req->qtcb->bottom.io.service_class = FSF_CLASS_3; req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; - sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; + zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; zfcp_fc_fcp_tm(fcp_cmnd, unit->device, tm_flags); @@ -2432,7 +2390,6 @@ static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *req) struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, struct zfcp_fsf_cfdc *fsf_cfdc) { - struct qdio_buffer_element *sbale; struct zfcp_qdio *qdio = adapter->qdio; struct zfcp_fsf_req *req = NULL; struct fsf_qtcb_bottom_support *bottom; @@ -2456,7 +2413,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, if (zfcp_fsf_req_sbal_get(qdio)) goto out; - req = zfcp_fsf_req_create(qdio, fsf_cfdc->command, NULL); + req = zfcp_fsf_req_create(qdio, fsf_cfdc->command, direction, NULL); if (IS_ERR(req)) { retval = -EPERM; goto out; @@ -2464,16 +2421,13 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, req->handler = zfcp_fsf_control_file_handler; - sbale = zfcp_qdio_sbale_req(qdio, &req->qdio_req); - sbale[0].flags |= direction; - bottom = &req->qtcb->bottom.support; bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; bottom->option = fsf_cfdc->option; bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, - direction, fsf_cfdc->sg, - FSF_MAX_SBALS_PER_REQ); + fsf_cfdc->sg, + ZFCP_FSF_MAX_SBALS_PER_REQ); if (bytes != ZFCP_CFDC_MAX_SIZE) { zfcp_fsf_req_free(req); goto out; -- cgit v1.2.3 From 6b9e1520094a8aa68009c265eb694e0be9f5be3f Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Fri, 30 Apr 2010 18:09:35 +0200 Subject: [SCSI] zfcp: Move sbal_get function to zfcp_qdio.c Waiting for a free sbal is a operation on the qdio queue. Move the code implementing the wait to zfcp_qdio.c and rename the functions accordingly. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_ext.h | 1 + drivers/s390/scsi/zfcp_fsf.c | 65 +++++++++++-------------------------------- drivers/s390/scsi/zfcp_qdio.c | 40 ++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 48 deletions(-) (limited to 'drivers/s390/scsi/zfcp_fsf.c') diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 172da12a2d02..48a8f93b72f5 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -143,6 +143,7 @@ extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int); /* zfcp_qdio.c */ extern int zfcp_qdio_setup(struct zfcp_adapter *); extern void zfcp_qdio_destroy(struct zfcp_qdio *); +extern int zfcp_qdio_sbal_get(struct zfcp_qdio *); extern int zfcp_qdio_send(struct zfcp_qdio *, struct zfcp_qdio_req *); extern int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *, struct zfcp_qdio_req *, struct scatterlist *, int); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index ec1b49a75532..3822f22b8150 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -640,37 +640,6 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) } } -static int zfcp_fsf_sbal_check(struct zfcp_qdio *qdio) -{ - struct zfcp_qdio_queue *req_q = &qdio->req_q; - - spin_lock_bh(&qdio->req_q_lock); - if (atomic_read(&req_q->count)) - return 1; - spin_unlock_bh(&qdio->req_q_lock); - return 0; -} - -static int zfcp_fsf_req_sbal_get(struct zfcp_qdio *qdio) -{ - struct zfcp_adapter *adapter = qdio->adapter; - long ret; - - spin_unlock_bh(&qdio->req_q_lock); - ret = wait_event_interruptible_timeout(qdio->req_q_wq, - zfcp_fsf_sbal_check(qdio), 5 * HZ); - if (ret > 0) - return 0; - if (!ret) { - atomic_inc(&qdio->req_q_full); - /* assume hanging outbound queue, try queue recovery */ - zfcp_erp_adapter_reopen(adapter, 0, "fsrsg_1", NULL); - } - - spin_lock_bh(&qdio->req_q_lock); - return -EIO; -} - static struct zfcp_fsf_req *zfcp_fsf_alloc(mempool_t *pool) { struct zfcp_fsf_req *req; @@ -798,7 +767,7 @@ int zfcp_fsf_status_read(struct zfcp_qdio *qdio) int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_UNSOLICITED_STATUS, 0, @@ -898,7 +867,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, struct zfcp_qdio *qdio = unit->port->adapter->qdio; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_ABORT_FCP_CMND, SBAL_FLAGS0_TYPE_READ, @@ -1068,7 +1037,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, int ret = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_GENERIC, @@ -1165,7 +1134,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, int ret = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_ELS, @@ -1208,7 +1177,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA, @@ -1250,7 +1219,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio, int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out_unlock; req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA, @@ -1302,7 +1271,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) return -EOPNOTSUPP; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA, @@ -1348,7 +1317,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio, return -EOPNOTSUPP; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out_unlock; req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA, @@ -1462,7 +1431,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID, @@ -1530,7 +1499,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT, @@ -1605,7 +1574,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID, @@ -1658,7 +1627,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT, @@ -1750,7 +1719,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PHYSICAL_PORT, @@ -1921,7 +1890,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_LUN, @@ -2005,7 +1974,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) int retval = -EIO; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_LUN, @@ -2340,7 +2309,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) return NULL; spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND, @@ -2410,7 +2379,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, } spin_lock_bh(&qdio->req_q_lock); - if (zfcp_fsf_req_sbal_get(qdio)) + if (zfcp_qdio_sbal_get(qdio)) goto out; req = zfcp_fsf_req_create(qdio, fsf_cfdc->command, direction, NULL); diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 98d54a9cd563..28117e130e2c 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -246,6 +246,46 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, return bytes; } +static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) +{ + struct zfcp_qdio_queue *req_q = &qdio->req_q; + + spin_lock_bh(&qdio->req_q_lock); + if (atomic_read(&req_q->count)) + return 1; + spin_unlock_bh(&qdio->req_q_lock); + return 0; +} + +/** + * zfcp_qdio_sbal_get - get free sbal in request queue, wait if necessary + * @qdio: pointer to struct zfcp_qdio + * + * The req_q_lock must be held by the caller of this function, and + * this function may only be called from process context; it will + * sleep when waiting for a free sbal. + * + * Returns: 0 on success, -EIO if there is no free sbal after waiting. + */ +int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio) +{ + long ret; + + spin_unlock_bh(&qdio->req_q_lock); + ret = wait_event_interruptible_timeout(qdio->req_q_wq, + zfcp_qdio_sbal_check(qdio), 5 * HZ); + if (ret > 0) + return 0; + if (!ret) { + atomic_inc(&qdio->req_q_full); + /* assume hanging outbound queue, try queue recovery */ + zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1", NULL); + } + + spin_lock_bh(&qdio->req_q_lock); + return -EIO; +} + /** * zfcp_qdio_send - set PCI flag in first SBALE and send req to QDIO * @qdio: pointer to struct zfcp_qdio -- cgit v1.2.3 From 64deb6efdc5504ce97b5c1c6f281fffbc150bd93 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Fri, 30 Apr 2010 18:09:36 +0200 Subject: [SCSI] zfcp: Use status_read_buf_num provided by FCP channel The FCP channel provides the number of status read buffers to issue. Use the provided number instead of the hardcoded number in zfcp. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_aux.c | 3 ++- drivers/s390/scsi/zfcp_def.h | 1 + drivers/s390/scsi/zfcp_erp.c | 2 +- drivers/s390/scsi/zfcp_fsf.c | 1 + drivers/s390/scsi/zfcp_fsf.h | 2 +- 5 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/s390/scsi/zfcp_fsf.c') diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index abf33db647ff..e331df2122f7 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -425,7 +425,8 @@ int zfcp_status_read_refill(struct zfcp_adapter *adapter) { while (atomic_read(&adapter->stat_miss) > 0) if (zfcp_fsf_status_read(adapter->qdio)) { - if (atomic_read(&adapter->stat_miss) >= 16) { + if (atomic_read(&adapter->stat_miss) >= + adapter->stat_read_buf_num) { zfcp_erp_adapter_reopen(adapter, 0, "axsref1", NULL); return 1; diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 0b2ae60a6f9f..9fa1b064893e 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -164,6 +164,7 @@ struct zfcp_adapter { stack abort/command completion races */ atomic_t stat_miss; /* # missing status reads*/ + unsigned int stat_read_buf_num; struct work_struct stat_work; atomic_t status; /* status of this adapter */ struct list_head erp_ready_head; /* error recovery for this diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 0be5e7ea2828..e3dbeda97179 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -714,7 +714,7 @@ static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *act) if (zfcp_erp_adapter_strategy_open_fsf_xport(act) == ZFCP_ERP_FAILED) return ZFCP_ERP_FAILED; - atomic_set(&act->adapter->stat_miss, 16); + atomic_set(&act->adapter->stat_miss, act->adapter->stat_read_buf_num); if (zfcp_status_read_refill(act->adapter)) return ZFCP_ERP_FAILED; diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 3822f22b8150..9f90b03ac97d 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -496,6 +496,7 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) adapter->hydra_version = bottom->adapter_type; adapter->timer_ticks = bottom->timer_interval; + adapter->stat_read_buf_num = max(bottom->status_read_buf_num, (u16)16); if (fc_host_permanent_port_name(shost) == -1) fc_host_permanent_port_name(shost) = fc_host_port_name(shost); diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index 4008bd786793..519083fd6e89 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h @@ -366,7 +366,7 @@ struct fsf_qtcb_bottom_config { u32 adapter_type; u8 res0; u8 peer_d_id[3]; - u8 res1[2]; + u16 status_read_buf_num; u16 timer_interval; u8 res2[9]; u8 s_id[3]; -- cgit v1.2.3