Skip to content

Commit

Permalink
qeth: don't query for info if hardware not ready.
Browse files Browse the repository at this point in the history
When qeth device is queried for ethtool data, hardware operation
is performed to extract the necessary information from the card.
If the card is not online at the moment (e.g. it is undergoing
recovery), this operation produces undesired effects like
temporarily freezing the system. This patch prevents execution
of the hardware query operation when the card is not online.
In such case, ioctl() operation returns error with errno ENODEV.

Reviewed-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Eugene Crosser <Eugene.Crosser@ru.ibm.com>
Signed-off-by: Frank Blaschka <blaschka@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eugene Crosser authored and David S. Miller committed Sep 2, 2014
1 parent c24f337 commit 511c244
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 7 deletions.
1 change: 1 addition & 0 deletions drivers/s390/net/qeth_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,7 @@ extern const struct attribute_group *qeth_generic_attr_groups[];
extern const struct attribute_group *qeth_osn_attr_groups[];
extern struct workqueue_struct *qeth_wq;

int qeth_card_hw_is_reachable(struct qeth_card *);
const char *qeth_get_cardname_short(struct qeth_card *);
int qeth_realloc_buffer_pool(struct qeth_card *, int);
int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id);
Expand Down
16 changes: 15 additions & 1 deletion drivers/s390/net/qeth_core_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int);
struct workqueue_struct *qeth_wq;
EXPORT_SYMBOL_GPL(qeth_wq);

int qeth_card_hw_is_reachable(struct qeth_card *card)
{
return (card->state == CARD_STATE_SOFTSETUP) ||
(card->state == CARD_STATE_UP);
}
EXPORT_SYMBOL_GPL(qeth_card_hw_is_reachable);

static void qeth_close_dev_handler(struct work_struct *work)
{
struct qeth_card *card;
Expand Down Expand Up @@ -5790,6 +5797,7 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev,
struct qeth_card *card = netdev->ml_priv;
enum qeth_link_types link_type;
struct carrier_info carrier_info;
int rc;
u32 speed;

if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan))
Expand Down Expand Up @@ -5832,8 +5840,14 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev,
/* Check if we can obtain more accurate information. */
/* If QUERY_CARD_INFO command is not supported or fails, */
/* just return the heuristics that was filled above. */
if (qeth_query_card_info(card, &carrier_info) != 0)
if (!qeth_card_hw_is_reachable(card))
return -ENODEV;
rc = qeth_query_card_info(card, &carrier_info);
if (rc == -EOPNOTSUPP) /* for old hardware, return heuristic */
return 0;
if (rc) /* report error from the hardware operation */
return rc;
/* on success, fill in the information got from the hardware */

netdev_dbg(netdev,
"card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n",
Expand Down
7 changes: 1 addition & 6 deletions drivers/s390/net/qeth_l2_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@

#include <linux/slab.h>
#include <asm/ebcdic.h>
#include "qeth_core.h"
#include "qeth_l2.h"

#define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)

static int qeth_card_hw_is_reachable(struct qeth_card *card)
{
return (card->state == CARD_STATE_SOFTSETUP) ||
(card->state == CARD_STATE_UP);
}

static ssize_t qeth_bridge_port_role_state_show(struct device *dev,
struct device_attribute *attr, char *buf,
int show_state)
Expand Down

0 comments on commit 511c244

Please sign in to comment.