s390/qeth: dynamically allocate vnicc cmds
The VNICC code is somewhat quirky in that it defers the whole cmd setup to a common helper qeth_l2_vnicc_request(). Some of the cmd specifics are then passed in via parameter, while others are simply hard-coded. Split the whole machinery up into the usual format: one helper that allocates the cmd & fills in the common fields, while all the cmd originators take care of their sub-cmd type specific work. This makes it much easier to calculate the cmd's precise length, and reduces code complexity. Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> Reviewed-by: Alexandra Winter <wintera@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5cfbe10a00
commit
2cfb4810a3
|
@ -630,12 +630,6 @@ struct qeth_ipacmd_diagass {
|
|||
|
||||
/* VNICC header */
|
||||
struct qeth_ipacmd_vnicc_hdr {
|
||||
u32 sup;
|
||||
u32 cur;
|
||||
};
|
||||
|
||||
/* VNICC sub command header */
|
||||
struct qeth_vnicc_sub_hdr {
|
||||
u16 data_length;
|
||||
u16 reserved;
|
||||
u32 sub_command;
|
||||
|
@ -660,15 +654,18 @@ struct qeth_vnicc_getset_timeout {
|
|||
|
||||
/* complete VNICC IPA command message */
|
||||
struct qeth_ipacmd_vnicc {
|
||||
struct qeth_ipa_caps vnicc_cmds;
|
||||
struct qeth_ipacmd_vnicc_hdr hdr;
|
||||
struct qeth_vnicc_sub_hdr sub_hdr;
|
||||
union {
|
||||
struct qeth_vnicc_query_cmds query_cmds;
|
||||
struct qeth_vnicc_set_char set_char;
|
||||
struct qeth_vnicc_getset_timeout getset_timeout;
|
||||
};
|
||||
} data;
|
||||
};
|
||||
|
||||
#define VNICC_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_vnicc,\
|
||||
data.field)
|
||||
|
||||
/* SETBRIDGEPORT IPA Command: *********************************************/
|
||||
enum qeth_ipa_sbp_cmd {
|
||||
IPA_SBP_QUERY_COMMANDS_SUPPORTED = 0x00000000L,
|
||||
|
|
|
@ -1735,10 +1735,6 @@ static int qeth_l2_vnicc_makerc(struct qeth_card *card, u16 ipa_rc)
|
|||
/* generic VNICC request call back control */
|
||||
struct _qeth_l2_vnicc_request_cbctl {
|
||||
u32 sub_cmd;
|
||||
struct {
|
||||
u32 vnic_char;
|
||||
u32 timeout;
|
||||
} param;
|
||||
struct {
|
||||
union{
|
||||
u32 *sup_cmds;
|
||||
|
@ -1761,80 +1757,52 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card,
|
|||
if (cmd->hdr.return_code)
|
||||
return qeth_l2_vnicc_makerc(card, cmd->hdr.return_code);
|
||||
/* return results to caller */
|
||||
card->options.vnicc.sup_chars = rep->hdr.sup;
|
||||
card->options.vnicc.cur_chars = rep->hdr.cur;
|
||||
card->options.vnicc.sup_chars = rep->vnicc_cmds.supported;
|
||||
card->options.vnicc.cur_chars = rep->vnicc_cmds.enabled;
|
||||
|
||||
if (cbctl->sub_cmd == IPA_VNICC_QUERY_CMDS)
|
||||
*cbctl->result.sup_cmds = rep->query_cmds.sup_cmds;
|
||||
*cbctl->result.sup_cmds = rep->data.query_cmds.sup_cmds;
|
||||
|
||||
if (cbctl->sub_cmd == IPA_VNICC_GET_TIMEOUT)
|
||||
*cbctl->result.timeout = rep->getset_timeout.timeout;
|
||||
*cbctl->result.timeout = rep->data.getset_timeout.timeout;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* generic VNICC request */
|
||||
static int qeth_l2_vnicc_request(struct qeth_card *card,
|
||||
struct _qeth_l2_vnicc_request_cbctl *cbctl)
|
||||
static struct qeth_cmd_buffer *qeth_l2_vnicc_build_cmd(struct qeth_card *card,
|
||||
u32 vnicc_cmd,
|
||||
unsigned int data_length)
|
||||
{
|
||||
struct qeth_ipacmd_vnicc *req;
|
||||
struct qeth_ipacmd_vnicc_hdr *hdr;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
struct qeth_ipa_cmd *cmd;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "vniccreq");
|
||||
|
||||
/* get new buffer for request */
|
||||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_VNICC, 0);
|
||||
iob = qeth_ipa_alloc_cmd(card, IPA_CMD_VNICC, QETH_PROT_NONE,
|
||||
data_length +
|
||||
offsetof(struct qeth_ipacmd_vnicc, data));
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
return NULL;
|
||||
|
||||
/* create header for request */
|
||||
cmd = __ipa_cmd(iob);
|
||||
req = &cmd->data.vnicc;
|
||||
|
||||
/* create sub command header for request */
|
||||
req->sub_hdr.data_length = sizeof(req->sub_hdr);
|
||||
req->sub_hdr.sub_command = cbctl->sub_cmd;
|
||||
|
||||
/* create sub command specific request fields */
|
||||
switch (cbctl->sub_cmd) {
|
||||
case IPA_VNICC_QUERY_CHARS:
|
||||
break;
|
||||
case IPA_VNICC_QUERY_CMDS:
|
||||
req->sub_hdr.data_length += sizeof(req->query_cmds);
|
||||
req->query_cmds.vnic_char = cbctl->param.vnic_char;
|
||||
break;
|
||||
case IPA_VNICC_ENABLE:
|
||||
case IPA_VNICC_DISABLE:
|
||||
req->sub_hdr.data_length += sizeof(req->set_char);
|
||||
req->set_char.vnic_char = cbctl->param.vnic_char;
|
||||
break;
|
||||
case IPA_VNICC_SET_TIMEOUT:
|
||||
req->getset_timeout.timeout = cbctl->param.timeout;
|
||||
/* fallthrough */
|
||||
case IPA_VNICC_GET_TIMEOUT:
|
||||
req->sub_hdr.data_length += sizeof(req->getset_timeout);
|
||||
req->getset_timeout.vnic_char = cbctl->param.vnic_char;
|
||||
break;
|
||||
default:
|
||||
qeth_release_buffer(iob);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* send request */
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, cbctl);
|
||||
hdr = &__ipa_cmd(iob)->data.vnicc.hdr;
|
||||
hdr->data_length = sizeof(*hdr) + data_length;
|
||||
hdr->sub_command = vnicc_cmd;
|
||||
return iob;
|
||||
}
|
||||
|
||||
/* VNICC query VNIC characteristics request */
|
||||
static int qeth_l2_vnicc_query_chars(struct qeth_card *card)
|
||||
{
|
||||
struct _qeth_l2_vnicc_request_cbctl cbctl;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "vniccqch");
|
||||
iob = qeth_l2_vnicc_build_cmd(card, IPA_VNICC_QUERY_CHARS, 0);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
|
||||
/* prepare callback control */
|
||||
cbctl.sub_cmd = IPA_VNICC_QUERY_CHARS;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "vniccqch");
|
||||
return qeth_l2_vnicc_request(card, &cbctl);
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
|
||||
}
|
||||
|
||||
/* VNICC query sub commands request */
|
||||
|
@ -1842,14 +1810,21 @@ static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char,
|
|||
u32 *sup_cmds)
|
||||
{
|
||||
struct _qeth_l2_vnicc_request_cbctl cbctl;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "vniccqcm");
|
||||
iob = qeth_l2_vnicc_build_cmd(card, IPA_VNICC_QUERY_CMDS,
|
||||
VNICC_DATA_SIZEOF(query_cmds));
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
|
||||
__ipa_cmd(iob)->data.vnicc.data.query_cmds.vnic_char = vnic_char;
|
||||
|
||||
/* prepare callback control */
|
||||
cbctl.sub_cmd = IPA_VNICC_QUERY_CMDS;
|
||||
cbctl.param.vnic_char = vnic_char;
|
||||
cbctl.result.sup_cmds = sup_cmds;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "vniccqcm");
|
||||
return qeth_l2_vnicc_request(card, &cbctl);
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
|
||||
}
|
||||
|
||||
/* VNICC enable/disable characteristic request */
|
||||
|
@ -1857,31 +1832,47 @@ static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char,
|
|||
u32 cmd)
|
||||
{
|
||||
struct _qeth_l2_vnicc_request_cbctl cbctl;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "vniccedc");
|
||||
iob = qeth_l2_vnicc_build_cmd(card, cmd, VNICC_DATA_SIZEOF(set_char));
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
|
||||
__ipa_cmd(iob)->data.vnicc.data.set_char.vnic_char = vnic_char;
|
||||
|
||||
/* prepare callback control */
|
||||
cbctl.sub_cmd = cmd;
|
||||
cbctl.param.vnic_char = vnic_char;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "vniccedc");
|
||||
return qeth_l2_vnicc_request(card, &cbctl);
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
|
||||
}
|
||||
|
||||
/* VNICC get/set timeout for characteristic request */
|
||||
static int qeth_l2_vnicc_getset_timeout(struct qeth_card *card, u32 vnicc,
|
||||
u32 cmd, u32 *timeout)
|
||||
{
|
||||
struct qeth_vnicc_getset_timeout *getset_timeout;
|
||||
struct _qeth_l2_vnicc_request_cbctl cbctl;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "vniccgst");
|
||||
iob = qeth_l2_vnicc_build_cmd(card, cmd,
|
||||
VNICC_DATA_SIZEOF(getset_timeout));
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
|
||||
getset_timeout = &__ipa_cmd(iob)->data.vnicc.data.getset_timeout;
|
||||
getset_timeout->vnic_char = vnicc;
|
||||
|
||||
if (cmd == IPA_VNICC_SET_TIMEOUT)
|
||||
getset_timeout->timeout = *timeout;
|
||||
|
||||
/* prepare callback control */
|
||||
cbctl.sub_cmd = cmd;
|
||||
cbctl.param.vnic_char = vnicc;
|
||||
if (cmd == IPA_VNICC_SET_TIMEOUT)
|
||||
cbctl.param.timeout = *timeout;
|
||||
if (cmd == IPA_VNICC_GET_TIMEOUT)
|
||||
cbctl.result.timeout = timeout;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "vniccgst");
|
||||
return qeth_l2_vnicc_request(card, &cbctl);
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
|
||||
}
|
||||
|
||||
/* set current VNICC flag state; called from sysfs store function */
|
||||
|
|
Loading…
Reference in New Issue