Skip to content

Commit 48ce6f8

Browse files
julianwiedmanndavem330
authored andcommitted
s390/qeth: use callback to finalize cmd
To avoid concurrency issues, some parts of the cmd setup are delayed until qeth_send_control_data() holds the IO channel's irq_pending "lock". Rather than hard-coding those setup steps for each cmd type, have the cmd provide a callback. This will make it easier to also issue IDX commands via qeth_send_control_data(). Signed-off-by: Julian Wiedmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 61e0446 commit 48ce6f8

File tree

3 files changed

+50
-31
lines changed

3 files changed

+50
-31
lines changed

drivers/s390/net/qeth_core.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ struct qeth_cmd_buffer {
589589
struct qeth_reply *reply;
590590
long timeout;
591591
unsigned char *data;
592+
void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob,
593+
unsigned int length);
592594
void (*callback)(struct qeth_card *card, struct qeth_channel *channel,
593595
struct qeth_cmd_buffer *iob);
594596
};
@@ -991,8 +993,6 @@ void qeth_clear_qdio_buffers(struct qeth_card *);
991993
void qeth_setadp_promisc_mode(struct qeth_card *);
992994
int qeth_setadpparms_change_macaddr(struct qeth_card *);
993995
void qeth_tx_timeout(struct net_device *);
994-
void qeth_prepare_control_data(struct qeth_card *, int,
995-
struct qeth_cmd_buffer *);
996996
void qeth_release_buffer(struct qeth_channel *, struct qeth_cmd_buffer *);
997997
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
998998
u16 cmd_length);

drivers/s390/net/qeth_core_main.c

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,18 @@ static int qeth_idx_activate_get_answer(struct qeth_card *card,
18071807
return rc;
18081808
}
18091809

1810+
static void qeth_idx_finalize_cmd(struct qeth_card *card,
1811+
struct qeth_cmd_buffer *iob,
1812+
unsigned int length)
1813+
{
1814+
qeth_setup_ccw(iob->channel->ccw, CCW_CMD_WRITE, length, iob->data);
1815+
1816+
memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data), &card->seqno.trans_hdr,
1817+
QETH_SEQ_NO_LENGTH);
1818+
if (iob->channel == &card->write)
1819+
card->seqno.trans_hdr++;
1820+
}
1821+
18101822
static int qeth_idx_activate_channel(struct qeth_card *card,
18111823
struct qeth_channel *channel,
18121824
void (*reply_cb)(struct qeth_card *,
@@ -1825,18 +1837,12 @@ static int qeth_idx_activate_channel(struct qeth_card *card,
18251837
if (!iob)
18261838
return -ENOMEM;
18271839
iob->callback = reply_cb;
1828-
qeth_setup_ccw(channel->ccw, CCW_CMD_WRITE, IDX_ACTIVATE_SIZE,
1829-
iob->data);
1830-
if (channel == &card->write) {
1840+
1841+
if (channel == &card->write)
18311842
memcpy(iob->data, IDX_ACTIVATE_WRITE, IDX_ACTIVATE_SIZE);
1832-
memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1833-
&card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1834-
card->seqno.trans_hdr++;
1835-
} else {
1843+
else
18361844
memcpy(iob->data, IDX_ACTIVATE_READ, IDX_ACTIVATE_SIZE);
1837-
memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1838-
&card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1839-
}
1845+
18401846
tmp = ((u8)card->dev->dev_port) | 0x80;
18411847
memcpy(QETH_IDX_ACT_PNO(iob->data), &tmp, 1);
18421848
memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data),
@@ -1850,6 +1856,8 @@ static int qeth_idx_activate_channel(struct qeth_card *card,
18501856

18511857
wait_event(card->wait_q, qeth_trylock_channel(channel));
18521858
QETH_DBF_TEXT(SETUP, 6, "noirqpnd");
1859+
qeth_idx_finalize_cmd(card, iob, IDX_ACTIVATE_SIZE);
1860+
18531861
spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
18541862
rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw,
18551863
(addr_t) iob, 0, 0, QETH_TIMEOUT);
@@ -1977,23 +1985,21 @@ static void qeth_idx_read_cb(struct qeth_card *card,
19771985
qeth_release_buffer(channel, iob);
19781986
}
19791987

1980-
void qeth_prepare_control_data(struct qeth_card *card, int len,
1981-
struct qeth_cmd_buffer *iob)
1988+
static void qeth_mpc_finalize_cmd(struct qeth_card *card,
1989+
struct qeth_cmd_buffer *iob,
1990+
unsigned int length)
19821991
{
1983-
qeth_setup_ccw(iob->channel->ccw, CCW_CMD_WRITE, len, iob->data);
1984-
iob->callback = qeth_release_buffer_cb;
1992+
qeth_idx_finalize_cmd(card, iob, length);
19851993

1986-
memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
1987-
&card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
1988-
card->seqno.trans_hdr++;
19891994
memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
19901995
&card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
19911996
card->seqno.pdu_hdr++;
19921997
memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
19931998
&card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
1994-
QETH_DBF_HEX(CTRL, 2, iob->data, min(len, QETH_DBF_CTRL_LEN));
1999+
2000+
iob->reply->seqno = QETH_IDX_COMMAND_SEQNO;
2001+
iob->callback = qeth_release_buffer_cb;
19952002
}
1996-
EXPORT_SYMBOL_GPL(qeth_prepare_control_data);
19972003

19982004
/**
19992005
* qeth_send_control_data() - send control command to the card
@@ -2029,7 +2035,6 @@ static int qeth_send_control_data(struct qeth_card *card, int len,
20292035
long timeout = iob->timeout;
20302036
int rc;
20312037
struct qeth_reply *reply = NULL;
2032-
struct qeth_ipa_cmd *cmd = NULL;
20332038

20342039
QETH_CARD_TEXT(card, 2, "sendctl");
20352040

@@ -2058,14 +2063,8 @@ static int qeth_send_control_data(struct qeth_card *card, int len,
20582063
return (timeout == -ERESTARTSYS) ? -EINTR : -ETIME;
20592064
}
20602065

2061-
if (IS_IPA(iob->data)) {
2062-
cmd = __ipa_cmd(iob);
2063-
cmd->hdr.seqno = card->seqno.ipa++;
2064-
reply->seqno = cmd->hdr.seqno;
2065-
} else {
2066-
reply->seqno = QETH_IDX_COMMAND_SEQNO;
2067-
}
2068-
qeth_prepare_control_data(card, len, iob);
2066+
iob->finalize(card, iob, len);
2067+
QETH_DBF_HEX(CTRL, 2, iob->data, min(len, QETH_DBF_CTRL_LEN));
20692068

20702069
qeth_enqueue_reply(card, reply);
20712070

@@ -2120,7 +2119,9 @@ static int qeth_cm_enable(struct qeth_card *card)
21202119
QETH_DBF_TEXT(SETUP, 2, "cmenable");
21212120

21222121
iob = qeth_wait_for_buffer(&card->write);
2122+
iob->finalize = qeth_mpc_finalize_cmd;
21232123
memcpy(iob->data, CM_ENABLE, CM_ENABLE_SIZE);
2124+
21242125
memcpy(QETH_CM_ENABLE_ISSUER_RM_TOKEN(iob->data),
21252126
&card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
21262127
memcpy(QETH_CM_ENABLE_FILTER_TOKEN(iob->data),
@@ -2153,7 +2154,9 @@ static int qeth_cm_setup(struct qeth_card *card)
21532154
QETH_DBF_TEXT(SETUP, 2, "cmsetup");
21542155

21552156
iob = qeth_wait_for_buffer(&card->write);
2157+
iob->finalize = qeth_mpc_finalize_cmd;
21562158
memcpy(iob->data, CM_SETUP, CM_SETUP_SIZE);
2159+
21572160
memcpy(QETH_CM_SETUP_DEST_ADDR(iob->data),
21582161
&card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
21592162
memcpy(QETH_CM_SETUP_CONNECTION_TOKEN(iob->data),
@@ -2270,6 +2273,7 @@ static int qeth_ulp_enable(struct qeth_card *card)
22702273
QETH_DBF_TEXT(SETUP, 2, "ulpenabl");
22712274

22722275
iob = qeth_wait_for_buffer(&card->write);
2276+
iob->finalize = qeth_mpc_finalize_cmd;
22732277
memcpy(iob->data, ULP_ENABLE, ULP_ENABLE_SIZE);
22742278

22752279
*(QETH_ULP_ENABLE_LINKNUM(iob->data)) = (u8) card->dev->dev_port;
@@ -2316,6 +2320,7 @@ static int qeth_ulp_setup(struct qeth_card *card)
23162320
QETH_DBF_TEXT(SETUP, 2, "ulpsetup");
23172321

23182322
iob = qeth_wait_for_buffer(&card->write);
2323+
iob->finalize = qeth_mpc_finalize_cmd;
23192324
memcpy(iob->data, ULP_SETUP, ULP_SETUP_SIZE);
23202325

23212326
memcpy(QETH_ULP_SETUP_DEST_ADDR(iob->data),
@@ -2503,6 +2508,7 @@ static int qeth_dm_act(struct qeth_card *card)
25032508
QETH_DBF_TEXT(SETUP, 2, "dmact");
25042509

25052510
iob = qeth_wait_for_buffer(&card->write);
2511+
iob->finalize = qeth_mpc_finalize_cmd;
25062512
memcpy(iob->data, DM_ACT, DM_ACT_SIZE);
25072513

25082514
memcpy(QETH_DM_ACT_DEST_ADDR(iob->data),
@@ -2785,12 +2791,24 @@ static void qeth_fill_ipacmd_header(struct qeth_card *card,
27852791
cmd->hdr.prot_version = prot;
27862792
}
27872793

2794+
static void qeth_ipa_finalize_cmd(struct qeth_card *card,
2795+
struct qeth_cmd_buffer *iob,
2796+
unsigned int length)
2797+
{
2798+
qeth_mpc_finalize_cmd(card, iob, length);
2799+
2800+
/* override with IPA-specific values: */
2801+
__ipa_cmd(iob)->hdr.seqno = card->seqno.ipa;
2802+
iob->reply->seqno = card->seqno.ipa++;
2803+
}
2804+
27882805
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
27892806
u16 cmd_length)
27902807
{
27912808
u16 total_length = IPA_PDU_HEADER_SIZE + cmd_length;
27922809
u8 prot_type = qeth_mpc_select_prot_type(card);
27932810

2811+
iob->finalize = qeth_ipa_finalize_cmd;
27942812
iob->timeout = QETH_IPA_TIMEOUT;
27952813

27962814
memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);

drivers/s390/net/qeth_l2_main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,8 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len,
10511051
QETH_CARD_TEXT(card, 5, "osndctrd");
10521052

10531053
wait_event(card->wait_q, qeth_trylock_channel(channel));
1054-
qeth_prepare_control_data(card, len, iob);
1054+
iob->finalize(card, iob, len);
1055+
QETH_DBF_HEX(CTRL, 2, iob->data, min(len, QETH_DBF_CTRL_LEN));
10551056
QETH_CARD_TEXT(card, 6, "osnoirqp");
10561057
spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
10571058
rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw,

0 commit comments

Comments
 (0)