From 87e7597b5a3f99238d95d63c44c9f872a41b37ae Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 1 Feb 2012 10:49:17 +0000 Subject: qeth: Move away from using neighbour entries in qeth_l3_fill_header() We've moving to a model where dst_entry objects to not have a reference to the associated neighbour entry, instead such neighbours must be looked up on-demand. Here in qeth_l3_fill_header() it's actually much simpler to use the information in the route itself. The code is already conditionalized upon protocol type. Signed-off-by: David S. Miller Tested-by: Ursula Braun --- drivers/s390/net/qeth_l3_main.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 9648e4e68337..25cd3799a76c 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -2832,7 +2834,6 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card, static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, struct sk_buff *skb, int ipv, int cast_type) { - struct neighbour *n = NULL; struct dst_entry *dst; memset(hdr, 0, sizeof(struct qeth_hdr)); @@ -2855,33 +2856,29 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, rcu_read_lock(); dst = skb_dst(skb); - if (dst) - n = dst_get_neighbour_noref(dst); if (ipv == 4) { + struct rtable *rt = (struct rtable *) dst; + __be32 *pkey = &ip_hdr(skb)->daddr; + + if (rt->rt_gateway) + pkey = &rt->rt_gateway; + /* IPv4 */ hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type); memset(hdr->hdr.l3.dest_addr, 0, 12); - if (n) { - *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = - *((u32 *) n->primary_key); - } else { - /* fill in destination address used in ip header */ - *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = - ip_hdr(skb)->daddr; - } + *((__be32 *) (&hdr->hdr.l3.dest_addr[12])) = *pkey; } else if (ipv == 6) { + struct rt6_info *rt = (struct rt6_info *) dst; + struct in6_addr *pkey = &ipv6_hdr(skb)->daddr; + + if (!ipv6_addr_any(&rt->rt6i_gateway)) + pkey = &rt->rt6i_gateway; + /* IPv6 */ hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type); if (card->info.type == QETH_CARD_TYPE_IQD) hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; - if (n) { - memcpy(hdr->hdr.l3.dest_addr, - n->primary_key, 16); - } else { - /* fill in destination address used in ip header */ - memcpy(hdr->hdr.l3.dest_addr, - &ipv6_hdr(skb)->daddr, 16); - } + memcpy(hdr->hdr.l3.dest_addr, pkey, 16); } else { /* passthrough */ if ((skb->dev->type == ARPHRD_IEEE802_TR) && -- cgit v1.2.3 From c3ab96f36aa308fa5bf432d5a4dafc80b7373805 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Wed, 8 Feb 2012 00:19:49 +0000 Subject: qeth: add query OSA address table support Add qeth device private ioctl to query the OSA address table. This helps debugging hw related problems. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 1 + drivers/s390/net/qeth_core_main.c | 99 +++++++++++++++++++++++++++++++++++++++ drivers/s390/net/qeth_core_mpc.h | 13 +++++ drivers/s390/net/qeth_l2_main.c | 3 ++ drivers/s390/net/qeth_l3_main.c | 3 ++ 5 files changed, 119 insertions(+) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 4abc79d3963f..ec7921b5138e 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -906,6 +906,7 @@ void qeth_prepare_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, char); struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *); int qeth_mdio_read(struct net_device *, int, int); int qeth_snmp_command(struct qeth_card *, char __user *); +int qeth_query_oat_command(struct qeth_card *, char __user *); struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32); int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *, unsigned long); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 9c3f38da4c01..0565584b52c3 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "qeth_core.h" @@ -4402,6 +4403,104 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) } EXPORT_SYMBOL_GPL(qeth_snmp_command); +static int qeth_setadpparms_query_oat_cb(struct qeth_card *card, + struct qeth_reply *reply, unsigned long data) +{ + struct qeth_ipa_cmd *cmd; + struct qeth_qoat_priv *priv; + char *resdata; + int resdatalen; + + QETH_CARD_TEXT(card, 3, "qoatcb"); + + cmd = (struct qeth_ipa_cmd *)data; + priv = (struct qeth_qoat_priv *)reply->param; + resdatalen = cmd->data.setadapterparms.hdr.cmdlength; + resdata = (char *)data + 28; + + if (resdatalen > (priv->buffer_len - priv->response_len)) { + cmd->hdr.return_code = IPA_RC_FFFF; + return 0; + } + + memcpy((priv->buffer + priv->response_len), resdata, + resdatalen); + priv->response_len += resdatalen; + + if (cmd->data.setadapterparms.hdr.seq_no < + cmd->data.setadapterparms.hdr.used_total) + return 1; + return 0; +} + +int qeth_query_oat_command(struct qeth_card *card, char __user *udata) +{ + int rc = 0; + struct qeth_cmd_buffer *iob; + struct qeth_ipa_cmd *cmd; + struct qeth_query_oat *oat_req; + struct qeth_query_oat_data oat_data; + struct qeth_qoat_priv priv; + void __user *tmp; + + QETH_CARD_TEXT(card, 3, "qoatcmd"); + + if (!qeth_adp_supported(card, IPA_SETADP_QUERY_OAT)) { + rc = -EOPNOTSUPP; + goto out; + } + + if (copy_from_user(&oat_data, udata, + sizeof(struct qeth_query_oat_data))) { + rc = -EFAULT; + goto out; + } + + priv.buffer_len = oat_data.buffer_len; + priv.response_len = 0; + priv.buffer = kzalloc(oat_data.buffer_len, GFP_KERNEL); + if (!priv.buffer) { + rc = -ENOMEM; + goto out; + } + + iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT, + sizeof(struct qeth_ipacmd_setadpparms_hdr) + + sizeof(struct qeth_query_oat)); + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); + oat_req = &cmd->data.setadapterparms.data.query_oat; + oat_req->subcmd_code = oat_data.command; + + rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_query_oat_cb, + &priv); + if (!rc) { + if (is_compat_task()) + tmp = compat_ptr(oat_data.ptr); + else + tmp = (void __user *)(unsigned long)oat_data.ptr; + + if (copy_to_user(tmp, priv.buffer, + priv.response_len)) { + rc = -EFAULT; + goto out_free; + } + + oat_data.response_len = priv.response_len; + + if (copy_to_user(udata, &oat_data, + sizeof(struct qeth_query_oat_data))) + rc = -EFAULT; + } else + if (rc == IPA_RC_FFFF) + rc = -EFAULT; + +out_free: + kfree(priv.buffer); +out: + return rc; +} +EXPORT_SYMBOL_GPL(qeth_query_oat_command); + static inline int qeth_get_qdio_q_format(struct qeth_card *card) { switch (card->info.type) { diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index e5a9d1c03839..578e19a2de6b 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -249,6 +249,7 @@ enum qeth_ipa_setadp_cmd { IPA_SETADP_SET_PROMISC_MODE = 0x00000800L, IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L, IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L, + IPA_SETADP_QUERY_OAT = 0x00080000L, }; enum qeth_ipa_mac_ops { CHANGE_ADDR_READ_MAC = 0, @@ -398,6 +399,17 @@ struct qeth_set_access_ctrl { __u32 subcmd_code; } __attribute__((packed)); +struct qeth_query_oat { + __u32 subcmd_code; + __u8 reserved[12]; +} __packed; + +struct qeth_qoat_priv { + __u32 buffer_len; + __u32 response_len; + char *buffer; +}; + struct qeth_ipacmd_setadpparms_hdr { __u32 supp_hw_cmds; __u32 reserved1; @@ -417,6 +429,7 @@ struct qeth_ipacmd_setadpparms { struct qeth_change_addr change_addr; struct qeth_snmp_cmd snmp; struct qeth_set_access_ctrl set_access_ctrl; + struct qeth_query_oat query_oat; __u32 mode; } data; } __attribute__ ((packed)); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index c12967133114..e5c9cf15e5c6 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -75,6 +75,9 @@ static int qeth_l2_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) mii_data->val_out = qeth_mdio_read(dev, mii_data->phy_id, mii_data->reg_num); break; + case SIOC_QETH_QUERY_OAT: + rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data); + break; default: rc = -EOPNOTSUPP; } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 25cd3799a76c..73bf8889984b 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2745,6 +2745,9 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) mii_data->phy_id, mii_data->reg_num); break; + case SIOC_QETH_QUERY_OAT: + rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data); + break; default: rc = -EOPNOTSUPP; } -- cgit v1.2.3 From 039055b965b9cfbeacb8cdcd1ef57e18b6374e58 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Wed, 8 Feb 2012 00:19:50 +0000 Subject: qeth: add wake_up on write channel To send commands on the write channel 8 buffers exist. If all 8 buffers are used, a wait is triggered on the write channel. When such buffer are freed, a wake_up is needed. This patch adds the missing wake_up in qeth_release_buffer(). This fix is especially important when running Communications Controller for Linux on System z. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 0565584b52c3..cbb101828dc3 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -678,6 +678,7 @@ void qeth_release_buffer(struct qeth_channel *channel, iob->callback = qeth_send_control_data_cb; iob->rc = 0; spin_unlock_irqrestore(&channel->iob_lock, flags); + wake_up(&channel->wait_q); } EXPORT_SYMBOL_GPL(qeth_release_buffer); -- cgit v1.2.3 From 2022e00cd5c0a9b43163834a51af664de16cfc3c Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Wed, 7 Mar 2012 02:06:25 +0000 Subject: qeth: synchronize discipline module loading During system startup udev may try to configure devices in parallel so we have to synchronize discipline module loading. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index cbb101828dc3..ef17d8366ce2 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -51,6 +51,7 @@ static struct kmem_cache *qeth_qdio_outbuf_cache; static struct device *qeth_core_root_dev; static unsigned int known_devices[][6] = QETH_MODELLIST_ARRAY; static struct lock_class_key qdio_out_skb_queue_key; +static struct mutex qeth_mod_mutex; static void qeth_send_control_data_cb(struct qeth_channel *, struct qeth_cmd_buffer *); @@ -5040,6 +5041,7 @@ int qeth_core_load_discipline(struct qeth_card *card, enum qeth_discipline_id discipline) { int rc = 0; + mutex_lock(&qeth_mod_mutex); switch (discipline) { case QETH_DISCIPLINE_LAYER3: card->discipline.ccwgdriver = try_then_request_module( @@ -5057,6 +5059,7 @@ int qeth_core_load_discipline(struct qeth_card *card, "support discipline %d\n", discipline); rc = -EINVAL; } + mutex_unlock(&qeth_mod_mutex); return rc; } @@ -5540,6 +5543,7 @@ static int __init qeth_core_init(void) pr_info("loading core functions\n"); INIT_LIST_HEAD(&qeth_core_card_list.list); rwlock_init(&qeth_core_card_list.rwlock); + mutex_init(&qeth_mod_mutex); rc = qeth_register_dbf_views(); if (rc) -- cgit v1.2.3 From ce1f893837afeee8aea0c5f6a32ebba16816beec Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Wed, 7 Mar 2012 02:06:26 +0000 Subject: ctcm: make ctcmpc debugging compilable ctcmpc debugging can be activated defining constant DEBUGCCW. The debugging part contains wrong checks for 64 bit addresses. Thus the debugging version does not compile. This patch corrects the 64-bit address checks to make it compilable. Signed-off-by: Ursula Braun Reviewed-by: Belinda Thompson Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/ctcm_main.c | 3 +++ drivers/s390/net/ctcm_mpc.c | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 5cb93a8e3403..11f3b071f305 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -562,6 +562,9 @@ static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb) skb_queue_tail(&ch->io_queue, skb); ccw_idx = 3; } + if (do_debug_ccw) + ctcmpc_dumpit((char *)&ch->ccw[ccw_idx], + sizeof(struct ccw1) * 3); ch->retry = 0; fsm_newstate(ch->fsm, CTC_STATE_TX); fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index da4c747335e7..ac7975b7a837 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -53,8 +53,8 @@ #include #include -#include "ctcm_mpc.h" #include "ctcm_main.h" +#include "ctcm_mpc.h" #include "ctcm_fsms.h" static const struct xid2 init_xid = { @@ -132,7 +132,7 @@ void ctcmpc_dumpit(char *buf, int len) __u32 ct, sw, rm, dup; char *ptr, *rptr; char tbuf[82], tdup[82]; - #if (UTS_MACHINE == s390x) + #ifdef CONFIG_64BIT char addr[22]; #else char addr[12]; @@ -149,8 +149,8 @@ void ctcmpc_dumpit(char *buf, int len) for (ct = 0; ct < len; ct++, ptr++, rptr++) { if (sw == 0) { - #if (UTS_MACHINE == s390x) - sprintf(addr, "%16.16lx", (__u64)rptr); + #ifdef CONFIG_64BIT + sprintf(addr, "%16.16llx", (__u64)rptr); #else sprintf(addr, "%8.8X", (__u32)rptr); #endif @@ -164,8 +164,8 @@ void ctcmpc_dumpit(char *buf, int len) if (sw == 8) strcat(bhex, " "); - #if (UTS_MACHINE == s390x) - sprintf(tbuf, "%2.2lX", (__u64)*ptr); + #if CONFIG_64BIT + sprintf(tbuf, "%2.2llX", (__u64)*ptr); #else sprintf(tbuf, "%2.2X", (__u32)*ptr); #endif -- cgit v1.2.3 From 205a8b649cf6c0a1e6e7512b65c72df480e2a883 Mon Sep 17 00:00:00 2001 From: Belinda Thompson Date: Wed, 7 Mar 2012 02:06:27 +0000 Subject: ctcm: use correct idal word list for ctcmpc Communication Server Linux uses the ctcmpc code of the ctcm driver. Sending problems have shown up caused by a wrong idal word list for the first ccw. Function ctcmpc_chx_txdone() invokes the function to prepare the idal word list without setting an appropriate length for the first ccw, which may lead to an incomplete idal word list. This patch sets the maximum buffer size as data length of the first ccw. Thus correct idal word lists are guaranteed in all cases. Signed-off-by: Belinda Thompson Reviewed-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/ctcm_fsms.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/s390') diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c index 2d602207541b..a69766900a17 100644 --- a/drivers/s390/net/ctcm_fsms.c +++ b/drivers/s390/net/ctcm_fsms.c @@ -1341,6 +1341,12 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg) spin_unlock(&ch->collect_lock); clear_normalized_cda(&ch->ccw[1]); + + CTCM_PR_DBGDATA("ccwcda=0x%p data=0x%p\n", + (void *)(unsigned long)ch->ccw[1].cda, + ch->trans_skb->data); + ch->ccw[1].count = ch->max_bufsize; + if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) { dev_kfree_skb_any(ch->trans_skb); ch->trans_skb = NULL; @@ -1350,6 +1356,11 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg) fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev); return; } + + CTCM_PR_DBGDATA("ccwcda=0x%p data=0x%p\n", + (void *)(unsigned long)ch->ccw[1].cda, + ch->trans_skb->data); + ch->ccw[1].count = ch->trans_skb->len; fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch); ch->prof.send_stamp = current_kernel_time(); /* xtime */ -- cgit v1.2.3 From e0a8114c034cf8012565c5d56dd90967023cc724 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Wed, 7 Mar 2012 02:06:28 +0000 Subject: qeth: meaningful return code for set_mac_address Setting an invalid mac-address for a qeth layer2 device returns with a strange error code: # ip link set hsi1 address 00:00:00:00:00:01 RTNETLINK answers: Unknown error 18446744073709486085 Problem is caused by wrong usage of the return_code field within structure qeth_ipa_cmd. With this patch the ip command above returns SIOCSIFHWADDR: Invalid argument Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 6 +++--- drivers/s390/net/qeth_core_mpc.c | 1 + drivers/s390/net/qeth_core_mpc.h | 1 + drivers/s390/net/qeth_l2_main.c | 4 +--- drivers/s390/net/qeth_l3_main.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index ef17d8366ce2..120955c66410 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2945,8 +2945,8 @@ static int qeth_query_ipassists_cb(struct qeth_card *card, card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled; } QETH_DBF_TEXT(SETUP, 2, "suppenbl"); - QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported); - QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled); + QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported); + QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled); return 0; } @@ -4322,7 +4322,7 @@ static int qeth_snmp_command_cb(struct qeth_card *card, /* check if there is enough room in userspace */ if ((qinfo->udata_len - qinfo->udata_offset) < data_len) { QETH_CARD_TEXT_(card, 4, "scer3%i", -ENOMEM); - cmd->hdr.return_code = -ENOMEM; + cmd->hdr.return_code = IPA_RC_ENOMEM; return 0; } QETH_CARD_TEXT_(card, 4, "snore%i", diff --git a/drivers/s390/net/qeth_core_mpc.c b/drivers/s390/net/qeth_core_mpc.c index ec24901c802c..7fab6544def6 100644 --- a/drivers/s390/net/qeth_core_mpc.c +++ b/drivers/s390/net/qeth_core_mpc.c @@ -207,6 +207,7 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = { {IPA_RC_MC_ADDR_ALREADY_DEFINED, "Multicast address already defined"}, {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"}, {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"}, + {IPA_RC_ENOMEM, "Memory problem"}, {IPA_RC_FFFF, "Unknown Error"} }; diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index 578e19a2de6b..ff41e42004ac 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -190,6 +190,7 @@ enum qeth_ipa_return_codes { IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013, IPA_RC_LAN_OFFLINE = 0xe080, IPA_RC_INVALID_IP_VERSION2 = 0xf001, + IPA_RC_ENOMEM = 0xfffe, IPA_RC_FFFF = 0xffff }; /* for DELIP */ diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index e5c9cf15e5c6..0e7c29d1d7ef 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -576,7 +576,6 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card, default: break; } - cmd->hdr.return_code = -EIO; } else { card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac, @@ -605,7 +604,6 @@ static int qeth_l2_send_delmac_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data; if (cmd->hdr.return_code) { QETH_CARD_TEXT_(card, 2, "err%d", cmd->hdr.return_code); - cmd->hdr.return_code = -EIO; return 0; } card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; @@ -682,7 +680,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); if (!rc) rc = qeth_l2_send_setmac(card, addr->sa_data); - return rc; + return rc ? -EINVAL : 0; } static void qeth_l2_set_multicast_list(struct net_device *dev) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 73bf8889984b..f85921607686 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2430,7 +2430,7 @@ static int qeth_l3_arp_query_cb(struct qeth_card *card, if ((qinfo->udata_len - qinfo->udata_offset) < esize) { QETH_CARD_TEXT_(card, 4, "qaer3%i", -ENOMEM); - cmd->hdr.return_code = -ENOMEM; + cmd->hdr.return_code = IPA_RC_ENOMEM; goto out_error; } -- cgit v1.2.3 From e427babeefe10023d348e2a3db272612d6e79dc3 Mon Sep 17 00:00:00 2001 From: Klaus-Dieter Wacker Date: Wed, 7 Mar 2012 02:06:29 +0000 Subject: lcs: Return zero from ccwgroup devs set_offline function A return code of non-zero of the devs ccwgroup set_offline function leaves the dev in online state. Having done a partly offlining may leave the dev in unusable state. To make sure the dev is set to offline, zero is returned. A setup trace entry is written in case the offlining steps encountered some trouble. Signed-off-by: Klaus-Dieter Wacker Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/lcs.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 863fc2197155..687efe4d589a 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -2240,7 +2240,7 @@ __lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode) { struct lcs_card *card; enum lcs_dev_states recover_state; - int ret; + int ret = 0, ret2 = 0, ret3 = 0; LCS_DBF_TEXT(3, setup, "shtdndev"); card = dev_get_drvdata(&ccwgdev->dev); @@ -2255,13 +2255,15 @@ __lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode) recover_state = card->state; ret = lcs_stop_device(card->dev); - ret = ccw_device_set_offline(card->read.ccwdev); - ret = ccw_device_set_offline(card->write.ccwdev); + ret2 = ccw_device_set_offline(card->read.ccwdev); + ret3 = ccw_device_set_offline(card->write.ccwdev); + if (!ret) + ret = (ret2) ? ret2 : ret3; + if (ret) + LCS_DBF_TEXT_(3, setup, "1err:%d", ret); if (recover_state == DEV_STATE_UP) { card->state = DEV_STATE_RECOVER; } - if (ret) - return ret; return 0; } -- cgit v1.2.3