diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 92 |
1 files changed, 49 insertions, 43 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index ed06a1d17b73..96c580ee7509 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include "zfcp_dbf.h" | 14 | #include "zfcp_dbf.h" |
15 | 15 | ||
16 | #define ZFCP_REQ_AUTO_CLEANUP 0x00000002 | 16 | #define ZFCP_REQ_AUTO_CLEANUP 0x00000002 |
17 | #define ZFCP_REQ_NO_QTCB 0x00000008 | ||
18 | 17 | ||
19 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 18 | static void zfcp_fsf_request_timeout_handler(unsigned long data) |
20 | { | 19 | { |
@@ -112,14 +111,15 @@ static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req) | |||
112 | void zfcp_fsf_req_free(struct zfcp_fsf_req *req) | 111 | void zfcp_fsf_req_free(struct zfcp_fsf_req *req) |
113 | { | 112 | { |
114 | if (likely(req->pool)) { | 113 | if (likely(req->pool)) { |
114 | if (likely(req->qtcb)) | ||
115 | mempool_free(req->qtcb, req->adapter->pool.qtcb_pool); | ||
115 | mempool_free(req, req->pool); | 116 | mempool_free(req, req->pool); |
116 | return; | 117 | return; |
117 | } | 118 | } |
118 | 119 | ||
119 | if (req->qtcb) { | 120 | if (likely(req->qtcb)) |
120 | kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, req); | 121 | kmem_cache_free(zfcp_data.qtcb_cache, req->qtcb); |
121 | return; | 122 | kfree(req); |
122 | } | ||
123 | } | 123 | } |
124 | 124 | ||
125 | static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) | 125 | static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) |
@@ -251,7 +251,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
251 | 251 | ||
252 | if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { | 252 | if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { |
253 | zfcp_hba_dbf_event_fsf_unsol("dism", adapter, sr_buf); | 253 | zfcp_hba_dbf_event_fsf_unsol("dism", adapter, sr_buf); |
254 | mempool_free(sr_buf, adapter->pool.data_status_read); | 254 | mempool_free(sr_buf, adapter->pool.status_read_data); |
255 | zfcp_fsf_req_free(req); | 255 | zfcp_fsf_req_free(req); |
256 | return; | 256 | return; |
257 | } | 257 | } |
@@ -303,7 +303,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
303 | break; | 303 | break; |
304 | } | 304 | } |
305 | 305 | ||
306 | mempool_free(sr_buf, adapter->pool.data_status_read); | 306 | mempool_free(sr_buf, adapter->pool.status_read_data); |
307 | zfcp_fsf_req_free(req); | 307 | zfcp_fsf_req_free(req); |
308 | 308 | ||
309 | atomic_inc(&adapter->stat_miss); | 309 | atomic_inc(&adapter->stat_miss); |
@@ -669,34 +669,37 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) | |||
669 | return -EIO; | 669 | return -EIO; |
670 | } | 670 | } |
671 | 671 | ||
672 | static struct zfcp_fsf_req *zfcp_fsf_alloc_noqtcb(mempool_t *pool) | 672 | static struct zfcp_fsf_req *zfcp_fsf_alloc(mempool_t *pool) |
673 | { | 673 | { |
674 | struct zfcp_fsf_req *req; | 674 | struct zfcp_fsf_req *req; |
675 | req = mempool_alloc(pool, GFP_ATOMIC); | 675 | |
676 | if (!req) | 676 | if (likely(pool)) |
677 | req = mempool_alloc(pool, GFP_ATOMIC); | ||
678 | else | ||
679 | req = kmalloc(sizeof(*req), GFP_ATOMIC); | ||
680 | |||
681 | if (unlikely(!req)) | ||
677 | return NULL; | 682 | return NULL; |
683 | |||
678 | memset(req, 0, sizeof(*req)); | 684 | memset(req, 0, sizeof(*req)); |
679 | req->pool = pool; | 685 | req->pool = pool; |
680 | return req; | 686 | return req; |
681 | } | 687 | } |
682 | 688 | ||
683 | static struct zfcp_fsf_req *zfcp_fsf_alloc_qtcb(mempool_t *pool) | 689 | static struct fsf_qtcb *zfcp_qtcb_alloc(mempool_t *pool) |
684 | { | 690 | { |
685 | struct zfcp_fsf_req_qtcb *qtcb; | 691 | struct fsf_qtcb *qtcb; |
686 | 692 | ||
687 | if (likely(pool)) | 693 | if (likely(pool)) |
688 | qtcb = mempool_alloc(pool, GFP_ATOMIC); | 694 | qtcb = mempool_alloc(pool, GFP_ATOMIC); |
689 | else | 695 | else |
690 | qtcb = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache, | 696 | qtcb = kmem_cache_alloc(zfcp_data.qtcb_cache, GFP_ATOMIC); |
691 | GFP_ATOMIC); | 697 | |
692 | if (unlikely(!qtcb)) | 698 | if (unlikely(!qtcb)) |
693 | return NULL; | 699 | return NULL; |
694 | 700 | ||
695 | memset(qtcb, 0, sizeof(*qtcb)); | 701 | memset(qtcb, 0, sizeof(*qtcb)); |
696 | qtcb->fsf_req.qtcb = &qtcb->qtcb; | 702 | return qtcb; |
697 | qtcb->fsf_req.pool = pool; | ||
698 | |||
699 | return &qtcb->fsf_req; | ||
700 | } | 703 | } |
701 | 704 | ||
702 | static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | 705 | static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, |
@@ -704,14 +707,8 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | |||
704 | mempool_t *pool) | 707 | mempool_t *pool) |
705 | { | 708 | { |
706 | struct qdio_buffer_element *sbale; | 709 | struct qdio_buffer_element *sbale; |
707 | |||
708 | struct zfcp_fsf_req *req; | ||
709 | struct zfcp_qdio_queue *req_q = &adapter->req_q; | 710 | struct zfcp_qdio_queue *req_q = &adapter->req_q; |
710 | 711 | struct zfcp_fsf_req *req = zfcp_fsf_alloc(pool); | |
711 | if (req_flags & ZFCP_REQ_NO_QTCB) | ||
712 | req = zfcp_fsf_alloc_noqtcb(pool); | ||
713 | else | ||
714 | req = zfcp_fsf_alloc_qtcb(pool); | ||
715 | 712 | ||
716 | if (unlikely(!req)) | 713 | if (unlikely(!req)) |
717 | return ERR_PTR(-ENOMEM); | 714 | return ERR_PTR(-ENOMEM); |
@@ -735,7 +732,17 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | |||
735 | sbale[0].addr = (void *) req->req_id; | 732 | sbale[0].addr = (void *) req->req_id; |
736 | sbale[0].flags |= SBAL_FLAGS0_COMMAND; | 733 | sbale[0].flags |= SBAL_FLAGS0_COMMAND; |
737 | 734 | ||
738 | if (likely(req->qtcb)) { | 735 | if (likely(fsf_cmd != FSF_QTCB_UNSOLICITED_STATUS)) { |
736 | if (likely(pool)) | ||
737 | req->qtcb = zfcp_qtcb_alloc(adapter->pool.qtcb_pool); | ||
738 | else | ||
739 | req->qtcb = zfcp_qtcb_alloc(NULL); | ||
740 | |||
741 | if (unlikely(!req->qtcb)) { | ||
742 | zfcp_fsf_req_free(req); | ||
743 | return ERR_PTR(-ENOMEM); | ||
744 | } | ||
745 | |||
739 | req->qtcb->prefix.req_seq_no = req->adapter->fsf_req_seq_no; | 746 | req->qtcb->prefix.req_seq_no = req->adapter->fsf_req_seq_no; |
740 | req->qtcb->prefix.req_id = req->req_id; | 747 | req->qtcb->prefix.req_id = req->req_id; |
741 | req->qtcb->prefix.ulp_info = 26; | 748 | req->qtcb->prefix.ulp_info = 26; |
@@ -811,9 +818,8 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) | |||
811 | if (zfcp_fsf_req_sbal_get(adapter)) | 818 | if (zfcp_fsf_req_sbal_get(adapter)) |
812 | goto out; | 819 | goto out; |
813 | 820 | ||
814 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS, | 821 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS, 0, |
815 | ZFCP_REQ_NO_QTCB, | 822 | adapter->pool.status_read_req); |
816 | adapter->pool.fsf_req_status_read); | ||
817 | if (IS_ERR(req)) { | 823 | if (IS_ERR(req)) { |
818 | retval = PTR_ERR(req); | 824 | retval = PTR_ERR(req); |
819 | goto out; | 825 | goto out; |
@@ -823,7 +829,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) | |||
823 | sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; | 829 | sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; |
824 | req->sbale_curr = 2; | 830 | req->sbale_curr = 2; |
825 | 831 | ||
826 | sr_buf = mempool_alloc(adapter->pool.data_status_read, GFP_ATOMIC); | 832 | sr_buf = mempool_alloc(adapter->pool.status_read_data, GFP_ATOMIC); |
827 | if (!sr_buf) { | 833 | if (!sr_buf) { |
828 | retval = -ENOMEM; | 834 | retval = -ENOMEM; |
829 | goto failed_buf; | 835 | goto failed_buf; |
@@ -841,7 +847,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) | |||
841 | goto out; | 847 | goto out; |
842 | 848 | ||
843 | failed_req_send: | 849 | failed_req_send: |
844 | mempool_free(sr_buf, adapter->pool.data_status_read); | 850 | mempool_free(sr_buf, adapter->pool.status_read_data); |
845 | failed_buf: | 851 | failed_buf: |
846 | zfcp_fsf_req_free(req); | 852 | zfcp_fsf_req_free(req); |
847 | zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); | 853 | zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); |
@@ -919,7 +925,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, | |||
919 | if (zfcp_fsf_req_sbal_get(adapter)) | 925 | if (zfcp_fsf_req_sbal_get(adapter)) |
920 | goto out; | 926 | goto out; |
921 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, | 927 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, |
922 | 0, adapter->pool.fsf_req_abort); | 928 | 0, adapter->pool.scsi_abort); |
923 | if (IS_ERR(req)) { | 929 | if (IS_ERR(req)) { |
924 | req = NULL; | 930 | req = NULL; |
925 | goto out; | 931 | goto out; |
@@ -1231,7 +1237,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) | |||
1231 | req = zfcp_fsf_req_create(adapter, | 1237 | req = zfcp_fsf_req_create(adapter, |
1232 | FSF_QTCB_EXCHANGE_CONFIG_DATA, | 1238 | FSF_QTCB_EXCHANGE_CONFIG_DATA, |
1233 | ZFCP_REQ_AUTO_CLEANUP, | 1239 | ZFCP_REQ_AUTO_CLEANUP, |
1234 | adapter->pool.fsf_req_erp); | 1240 | adapter->pool.erp_req); |
1235 | if (IS_ERR(req)) { | 1241 | if (IS_ERR(req)) { |
1236 | retval = PTR_ERR(req); | 1242 | retval = PTR_ERR(req); |
1237 | goto out; | 1243 | goto out; |
@@ -1327,7 +1333,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) | |||
1327 | goto out; | 1333 | goto out; |
1328 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, | 1334 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, |
1329 | ZFCP_REQ_AUTO_CLEANUP, | 1335 | ZFCP_REQ_AUTO_CLEANUP, |
1330 | adapter->pool.fsf_req_erp); | 1336 | adapter->pool.erp_req); |
1331 | if (IS_ERR(req)) { | 1337 | if (IS_ERR(req)) { |
1332 | retval = PTR_ERR(req); | 1338 | retval = PTR_ERR(req); |
1333 | goto out; | 1339 | goto out; |
@@ -1497,7 +1503,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) | |||
1497 | req = zfcp_fsf_req_create(adapter, | 1503 | req = zfcp_fsf_req_create(adapter, |
1498 | FSF_QTCB_OPEN_PORT_WITH_DID, | 1504 | FSF_QTCB_OPEN_PORT_WITH_DID, |
1499 | ZFCP_REQ_AUTO_CLEANUP, | 1505 | ZFCP_REQ_AUTO_CLEANUP, |
1500 | adapter->pool.fsf_req_erp); | 1506 | adapter->pool.erp_req); |
1501 | if (IS_ERR(req)) { | 1507 | if (IS_ERR(req)) { |
1502 | retval = PTR_ERR(req); | 1508 | retval = PTR_ERR(req); |
1503 | goto out; | 1509 | goto out; |
@@ -1566,7 +1572,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) | |||
1566 | 1572 | ||
1567 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, | 1573 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, |
1568 | ZFCP_REQ_AUTO_CLEANUP, | 1574 | ZFCP_REQ_AUTO_CLEANUP, |
1569 | adapter->pool.fsf_req_erp); | 1575 | adapter->pool.erp_req); |
1570 | if (IS_ERR(req)) { | 1576 | if (IS_ERR(req)) { |
1571 | retval = PTR_ERR(req); | 1577 | retval = PTR_ERR(req); |
1572 | goto out; | 1578 | goto out; |
@@ -1643,7 +1649,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port) | |||
1643 | req = zfcp_fsf_req_create(adapter, | 1649 | req = zfcp_fsf_req_create(adapter, |
1644 | FSF_QTCB_OPEN_PORT_WITH_DID, | 1650 | FSF_QTCB_OPEN_PORT_WITH_DID, |
1645 | ZFCP_REQ_AUTO_CLEANUP, | 1651 | ZFCP_REQ_AUTO_CLEANUP, |
1646 | adapter->pool.fsf_req_erp); | 1652 | adapter->pool.erp_req); |
1647 | if (unlikely(IS_ERR(req))) { | 1653 | if (unlikely(IS_ERR(req))) { |
1648 | retval = PTR_ERR(req); | 1654 | retval = PTR_ERR(req); |
1649 | goto out; | 1655 | goto out; |
@@ -1697,7 +1703,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port) | |||
1697 | 1703 | ||
1698 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, | 1704 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, |
1699 | ZFCP_REQ_AUTO_CLEANUP, | 1705 | ZFCP_REQ_AUTO_CLEANUP, |
1700 | adapter->pool.fsf_req_erp); | 1706 | adapter->pool.erp_req); |
1701 | if (unlikely(IS_ERR(req))) { | 1707 | if (unlikely(IS_ERR(req))) { |
1702 | retval = PTR_ERR(req); | 1708 | retval = PTR_ERR(req); |
1703 | goto out; | 1709 | goto out; |
@@ -1788,7 +1794,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) | |||
1788 | 1794 | ||
1789 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT, | 1795 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT, |
1790 | ZFCP_REQ_AUTO_CLEANUP, | 1796 | ZFCP_REQ_AUTO_CLEANUP, |
1791 | adapter->pool.fsf_req_erp); | 1797 | adapter->pool.erp_req); |
1792 | if (IS_ERR(req)) { | 1798 | if (IS_ERR(req)) { |
1793 | retval = PTR_ERR(req); | 1799 | retval = PTR_ERR(req); |
1794 | goto out; | 1800 | goto out; |
@@ -1960,7 +1966,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) | |||
1960 | 1966 | ||
1961 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN, | 1967 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN, |
1962 | ZFCP_REQ_AUTO_CLEANUP, | 1968 | ZFCP_REQ_AUTO_CLEANUP, |
1963 | adapter->pool.fsf_req_erp); | 1969 | adapter->pool.erp_req); |
1964 | if (IS_ERR(req)) { | 1970 | if (IS_ERR(req)) { |
1965 | retval = PTR_ERR(req); | 1971 | retval = PTR_ERR(req); |
1966 | goto out; | 1972 | goto out; |
@@ -2045,7 +2051,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) | |||
2045 | goto out; | 2051 | goto out; |
2046 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN, | 2052 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN, |
2047 | ZFCP_REQ_AUTO_CLEANUP, | 2053 | ZFCP_REQ_AUTO_CLEANUP, |
2048 | adapter->pool.fsf_req_erp); | 2054 | adapter->pool.erp_req); |
2049 | if (IS_ERR(req)) { | 2055 | if (IS_ERR(req)) { |
2050 | retval = PTR_ERR(req); | 2056 | retval = PTR_ERR(req); |
2051 | goto out; | 2057 | goto out; |
@@ -2349,7 +2355,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2349 | } | 2355 | } |
2350 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, | 2356 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, |
2351 | ZFCP_REQ_AUTO_CLEANUP, | 2357 | ZFCP_REQ_AUTO_CLEANUP, |
2352 | adapter->pool.fsf_req_scsi); | 2358 | adapter->pool.scsi_req); |
2353 | if (IS_ERR(req)) { | 2359 | if (IS_ERR(req)) { |
2354 | retval = PTR_ERR(req); | 2360 | retval = PTR_ERR(req); |
2355 | goto out; | 2361 | goto out; |
@@ -2460,7 +2466,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) | |||
2460 | if (zfcp_fsf_req_sbal_get(adapter)) | 2466 | if (zfcp_fsf_req_sbal_get(adapter)) |
2461 | goto out; | 2467 | goto out; |
2462 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, 0, | 2468 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, 0, |
2463 | adapter->pool.fsf_req_scsi); | 2469 | adapter->pool.scsi_req); |
2464 | if (IS_ERR(req)) { | 2470 | if (IS_ERR(req)) { |
2465 | req = NULL; | 2471 | req = NULL; |
2466 | goto out; | 2472 | goto out; |