diff options
author | Julian Wiedmann <jwi@linux.ibm.com> | 2019-06-11 18:37:59 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-06-13 22:39:31 -0700 |
commit | f3b783b1d0d7d2d76e2bd8c136a80487f93dc680 (patch) | |
tree | a19c1af50a78121a09b0256936c9a41233adf7af | |
parent | 2066e1db9eef8e2057bb3a1b7cb3503a7f6725d9 (diff) | |
download | linux-stable-f3b783b1d0d7d2d76e2bd8c136a80487f93dc680.tar.gz linux-stable-f3b783b1d0d7d2d76e2bd8c136a80487f93dc680.tar.bz2 linux-stable-f3b783b1d0d7d2d76e2bd8c136a80487f93dc680.zip |
s390/qeth: command-chain the IDX sequence
The current IDX sequence first sends one WRITE cmd to activate the
device, and then sends a second cmd that READs the response.
Using qeth_alloc_cmd(), we can combine this into a single IO with two
command-chained CCWs.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 58 |
1 files changed, 14 insertions, 44 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 671754a0e591..11e6a3820421 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1709,9 +1709,6 @@ static void qeth_idx_finalize_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, unsigned int length) { - qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, length, - iob->data); - memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data), &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH); if (iob->channel == &card->write) @@ -1731,6 +1728,8 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, unsigned int length) { + qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, length, + iob->data); qeth_idx_finalize_cmd(card, iob, length); memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data), @@ -1920,8 +1919,8 @@ static int qeth_idx_check_activate_response(struct qeth_card *card, } } -static void qeth_idx_query_read_cb(struct qeth_card *card, - struct qeth_cmd_buffer *iob) +static void qeth_idx_activate_read_channel_cb(struct qeth_card *card, + struct qeth_cmd_buffer *iob) { struct qeth_channel *channel = iob->channel; u16 peer_level; @@ -1953,8 +1952,8 @@ out: qeth_release_buffer(iob); } -static void qeth_idx_query_write_cb(struct qeth_card *card, - struct qeth_cmd_buffer *iob) +static void qeth_idx_activate_write_channel_cb(struct qeth_card *card, + struct qeth_cmd_buffer *iob) { struct qeth_channel *channel = iob->channel; u16 peer_level; @@ -1980,30 +1979,19 @@ out: qeth_release_buffer(iob); } -static void qeth_idx_finalize_query_cmd(struct qeth_card *card, - struct qeth_cmd_buffer *iob, - unsigned int length) -{ - qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_READ, 0, length, iob->data); -} - -static void qeth_idx_activate_cb(struct qeth_card *card, - struct qeth_cmd_buffer *iob) -{ - qeth_notify_reply(iob->reply, 0); - qeth_release_buffer(iob); -} - static void qeth_idx_setup_activate_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob) { u16 addr = (card->info.cula << 8) + card->info.unit_addr2; u8 port = ((u8)card->dev->dev_port) | 0x80; + struct ccw1 *ccw = __ccw_from_cmd(iob); struct ccw_dev_id dev_id; + qeth_setup_ccw(&ccw[0], CCW_CMD_WRITE, CCW_FLAG_CC, IDX_ACTIVATE_SIZE, + iob->data); + qeth_setup_ccw(&ccw[1], CCW_CMD_READ, 0, iob->length, iob->data); ccw_device_get_id(CARD_DDEV(card), &dev_id); iob->finalize = qeth_idx_finalize_cmd; - iob->callback = qeth_idx_activate_cb; memcpy(QETH_IDX_ACT_PNO(iob->data), &port, 1); memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data), @@ -2022,27 +2010,18 @@ static int qeth_idx_activate_read_channel(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "idxread"); - iob = qeth_get_buffer(channel); + iob = qeth_alloc_cmd(channel, QETH_BUFSIZE, 2, QETH_TIMEOUT); if (!iob) return -ENOMEM; memcpy(iob->data, IDX_ACTIVATE_READ, IDX_ACTIVATE_SIZE); qeth_idx_setup_activate_cmd(card, iob); + iob->callback = qeth_idx_activate_read_channel_cb; rc = qeth_send_control_data(card, IDX_ACTIVATE_SIZE, iob, NULL, NULL); if (rc) return rc; - iob = qeth_get_buffer(channel); - if (!iob) - return -ENOMEM; - - iob->finalize = qeth_idx_finalize_query_cmd; - iob->callback = qeth_idx_query_read_cb; - rc = qeth_send_control_data(card, QETH_BUFSIZE, iob, NULL, NULL); - if (rc) - return rc; - channel->state = CH_STATE_UP; return 0; } @@ -2055,27 +2034,18 @@ static int qeth_idx_activate_write_channel(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "idxwrite"); - iob = qeth_get_buffer(channel); + iob = qeth_alloc_cmd(channel, QETH_BUFSIZE, 2, QETH_TIMEOUT); if (!iob) return -ENOMEM; memcpy(iob->data, IDX_ACTIVATE_WRITE, IDX_ACTIVATE_SIZE); qeth_idx_setup_activate_cmd(card, iob); + iob->callback = qeth_idx_activate_write_channel_cb; rc = qeth_send_control_data(card, IDX_ACTIVATE_SIZE, iob, NULL, NULL); if (rc) return rc; - iob = qeth_get_buffer(channel); - if (!iob) - return -ENOMEM; - - iob->finalize = qeth_idx_finalize_query_cmd; - iob->callback = qeth_idx_query_write_cb; - rc = qeth_send_control_data(card, QETH_BUFSIZE, iob, NULL, NULL); - if (rc) - return rc; - channel->state = CH_STATE_UP; return 0; } |