Skip to content

Commit 7f92316

Browse files
julianwiedmanndavem330
authored andcommitted
s390/qeth: make cmd/reply matching more flexible
When data is received on the READ channel, the matching logic for cmds that are waiting for a reply is currently hard-coded into the channel's main IO callback. Move this into a per-cmd callback, so that we can apply custom matching logic for each individual cmd. This also allows us to remove the coarse-grained check for unexpected non-IPA replies, since they will no longer match against _all_ pending cmds. Note that IDX cmds use _no_ matcher, since their reply is synchronously received as part of the cmd's IO. Signed-off-by: Julian Wiedmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 91003f3 commit 7f92316

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

drivers/s390/net/qeth_core.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,8 @@ struct qeth_cmd_buffer {
608608
long timeout;
609609
unsigned char *data;
610610
void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob);
611+
bool (*match)(struct qeth_cmd_buffer *iob,
612+
struct qeth_cmd_buffer *reply);
611613
void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob,
612614
unsigned int data_length);
613615
int rc;
@@ -618,6 +620,14 @@ static inline void qeth_get_cmd(struct qeth_cmd_buffer *iob)
618620
refcount_inc(&iob->ref_count);
619621
}
620622

623+
static inline struct qeth_ipa_cmd *__ipa_reply(struct qeth_cmd_buffer *iob)
624+
{
625+
if (!IS_IPA(iob->data))
626+
return NULL;
627+
628+
return (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
629+
}
630+
621631
static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob)
622632
{
623633
return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
@@ -1023,7 +1033,9 @@ void qeth_setadp_promisc_mode(struct qeth_card *card, bool enable);
10231033
int qeth_setadpparms_change_macaddr(struct qeth_card *);
10241034
void qeth_tx_timeout(struct net_device *, unsigned int txqueue);
10251035
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
1026-
u16 cmd_length);
1036+
u16 cmd_length,
1037+
bool (*match)(struct qeth_cmd_buffer *iob,
1038+
struct qeth_cmd_buffer *reply));
10271039
int qeth_query_switch_attributes(struct qeth_card *card,
10281040
struct qeth_switch_info *sw_info);
10291041
int qeth_query_card_info(struct qeth_card *card,

drivers/s390/net/qeth_core_main.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -748,8 +748,8 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
748748
goto out;
749749
}
750750

751-
if (IS_IPA(iob->data)) {
752-
cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
751+
cmd = __ipa_reply(iob);
752+
if (cmd) {
753753
cmd = qeth_check_ipa_data(card, cmd);
754754
if (!cmd)
755755
goto out;
@@ -758,17 +758,12 @@ static void qeth_issue_next_read_cb(struct qeth_card *card,
758758
card->osn_info.assist_cb(card->dev, cmd);
759759
goto out;
760760
}
761-
} else {
762-
/* non-IPA commands should only flow during initialization */
763-
if (card->state != CARD_STATE_DOWN)
764-
goto out;
765761
}
766762

767763
/* match against pending cmd requests */
768764
spin_lock_irqsave(&card->lock, flags);
769765
list_for_each_entry(tmp, &card->cmd_waiter_list, list) {
770-
if (!IS_IPA(tmp->data) ||
771-
__ipa_cmd(tmp)->hdr.seqno == cmd->hdr.seqno) {
766+
if (tmp->match && tmp->match(tmp, iob)) {
772767
request = tmp;
773768
/* take the object outside the lock */
774769
qeth_get_cmd(request);
@@ -1688,6 +1683,13 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card,
16881683
iob->callback = qeth_release_buffer_cb;
16891684
}
16901685

1686+
static bool qeth_mpc_match_reply(struct qeth_cmd_buffer *iob,
1687+
struct qeth_cmd_buffer *reply)
1688+
{
1689+
/* MPC cmds are issued strictly in sequence. */
1690+
return !IS_IPA(reply->data);
1691+
}
1692+
16911693
static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card,
16921694
void *data,
16931695
unsigned int data_length)
@@ -1702,6 +1704,7 @@ static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card,
17021704
qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, data_length,
17031705
iob->data);
17041706
iob->finalize = qeth_mpc_finalize_cmd;
1707+
iob->match = qeth_mpc_match_reply;
17051708
return iob;
17061709
}
17071710

@@ -2722,14 +2725,17 @@ static void qeth_ipa_finalize_cmd(struct qeth_card *card,
27222725
}
27232726

27242727
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
2725-
u16 cmd_length)
2728+
u16 cmd_length,
2729+
bool (*match)(struct qeth_cmd_buffer *iob,
2730+
struct qeth_cmd_buffer *reply))
27262731
{
27272732
u8 prot_type = qeth_mpc_select_prot_type(card);
27282733
u16 total_length = iob->length;
27292734

27302735
qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, total_length,
27312736
iob->data);
27322737
iob->finalize = qeth_ipa_finalize_cmd;
2738+
iob->match = match;
27332739

27342740
memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
27352741
memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &total_length, 2);
@@ -2742,6 +2748,14 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
27422748
}
27432749
EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd);
27442750

2751+
static bool qeth_ipa_match_reply(struct qeth_cmd_buffer *iob,
2752+
struct qeth_cmd_buffer *reply)
2753+
{
2754+
struct qeth_ipa_cmd *ipa_reply = __ipa_reply(reply);
2755+
2756+
return ipa_reply && (__ipa_cmd(iob)->hdr.seqno == ipa_reply->hdr.seqno);
2757+
}
2758+
27452759
struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card,
27462760
enum qeth_ipa_cmds cmd_code,
27472761
enum qeth_prot_versions prot,
@@ -2757,7 +2771,7 @@ struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card,
27572771
if (!iob)
27582772
return NULL;
27592773

2760-
qeth_prepare_ipa_cmd(card, iob, data_length);
2774+
qeth_prepare_ipa_cmd(card, iob, data_length, qeth_ipa_match_reply);
27612775

27622776
hdr = &__ipa_cmd(iob)->hdr;
27632777
hdr->command = cmd_code;

drivers/s390/net/qeth_l2_main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,8 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
896896
if (!iob)
897897
return -ENOMEM;
898898

899-
qeth_prepare_ipa_cmd(card, iob, (u16) data_len);
899+
qeth_prepare_ipa_cmd(card, iob, (u16) data_len, NULL);
900+
900901
memcpy(__ipa_cmd(iob), data, data_len);
901902
iob->callback = qeth_osn_assist_cb;
902903
return qeth_send_ipa_cmd(card, iob, NULL, NULL);

0 commit comments

Comments
 (0)