Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4949f07 authored by Frank Blaschka's avatar Frank Blaschka Committed by David S. Miller
Browse files

qeth: synchronize configuration interface



Synchronize access to the drivers configuration interface.
Also do not allow configuration changes during online/offline
transition.

Signed-off-by: default avatarFrank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 65a1f898
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -740,6 +740,7 @@ struct qeth_card {
	atomic_t force_alloc_skb;
	struct service_level qeth_service_level;
	struct qdio_ssqd_desc ssqd;
	struct mutex conf_mutex;
};

struct qeth_card_list_struct {
+1 −0
Original line number Diff line number Diff line
@@ -1100,6 +1100,7 @@ static int qeth_setup_card(struct qeth_card *card)
	spin_lock_init(&card->lock);
	spin_lock_init(&card->ip_lock);
	spin_lock_init(&card->thread_mask_lock);
	mutex_init(&card->conf_mutex);
	card->thread_start_mask = 0;
	card->thread_allowed_mask = 0;
	card->thread_running_mask = 0;
+91 −57
Original line number Diff line number Diff line
@@ -122,23 +122,32 @@ static ssize_t qeth_dev_portno_store(struct device *dev,
	struct qeth_card *card = dev_get_drvdata(dev);
	char *tmp;
	unsigned int portno, limit;
	int rc = 0;

	if (!card)
		return -EINVAL;

	mutex_lock(&card->conf_mutex);
	if ((card->state != CARD_STATE_DOWN) &&
	    (card->state != CARD_STATE_RECOVER))
		return -EPERM;
	    (card->state != CARD_STATE_RECOVER)) {
		rc = -EPERM;
		goto out;
	}

	portno = simple_strtoul(buf, &tmp, 16);
	if (portno > QETH_MAX_PORTNO)
		return -EINVAL;
	if (portno > QETH_MAX_PORTNO) {
		rc = -EINVAL;
		goto out;
	}
	limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
	if (portno > limit)
		return -EINVAL;

	if (portno > limit) {
		rc = -EINVAL;
		goto out;
	}
	card->info.portno = portno;
	return count;
out:
	mutex_unlock(&card->conf_mutex);
	return rc ? rc : count;
}

static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
@@ -165,18 +174,23 @@ static ssize_t qeth_dev_portname_store(struct device *dev,
{
	struct qeth_card *card = dev_get_drvdata(dev);
	char *tmp;
	int i;
	int i, rc = 0;

	if (!card)
		return -EINVAL;

	mutex_lock(&card->conf_mutex);
	if ((card->state != CARD_STATE_DOWN) &&
	    (card->state != CARD_STATE_RECOVER))
		return -EPERM;
	    (card->state != CARD_STATE_RECOVER)) {
		rc = -EPERM;
		goto out;
	}

	tmp = strsep((char **) &buf, "\n");
	if ((strlen(tmp) > 8) || (strlen(tmp) == 0))
		return -EINVAL;
	if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) {
		rc = -EINVAL;
		goto out;
	}

	card->info.portname[0] = strlen(tmp);
	/* for beauty reasons */
@@ -184,8 +198,9 @@ static ssize_t qeth_dev_portname_store(struct device *dev,
		card->info.portname[i] = ' ';
	strcpy(card->info.portname + 1, tmp);
	ASCEBC(card->info.portname + 1, 8);

	return count;
out:
	mutex_unlock(&card->conf_mutex);
	return rc ? rc : count;
}

static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
@@ -215,20 +230,25 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev,
{
	struct qeth_card *card = dev_get_drvdata(dev);
	char *tmp;
	int rc = 0;

	if (!card)
		return -EINVAL;

	mutex_lock(&card->conf_mutex);
	if ((card->state != CARD_STATE_DOWN) &&
	    (card->state != CARD_STATE_RECOVER))
		return -EPERM;
	    (card->state != CARD_STATE_RECOVER)) {
		rc = -EPERM;
		goto out;
	}

	/* check if 1920 devices are supported ,
	 * if though we have to permit priority queueing
	 */
	if (card->qdio.no_out_queues == 1) {
		card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
		return -EPERM;
		rc = -EPERM;
		goto out;
	}

	tmp = strsep((char **) &buf, "\n");
@@ -251,10 +271,11 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev,
	} else if (!strcmp(tmp, "no_prio_queueing")) {
		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
	} else {
		return -EINVAL;
	}
	return count;
	} else
		rc = -EINVAL;
out:
	mutex_unlock(&card->conf_mutex);
	return rc ? rc : count;
}

static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,
@@ -277,14 +298,17 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev,
	struct qeth_card *card = dev_get_drvdata(dev);
	char *tmp;
	int cnt, old_cnt;
	int rc;
	int rc = 0;

	if (!card)
		return -EINVAL;

	mutex_lock(&card->conf_mutex);
	if ((card->state != CARD_STATE_DOWN) &&
	    (card->state != CARD_STATE_RECOVER))
		return -EPERM;
	    (card->state != CARD_STATE_RECOVER)) {
		rc = -EPERM;
		goto out;
	}

	old_cnt = card->qdio.in_buf_pool.buf_count;
	cnt = simple_strtoul(buf, &tmp, 10);
@@ -293,7 +317,9 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev,
	if (old_cnt != cnt) {
		rc = qeth_realloc_buffer_pool(card, cnt);
	}
	return count;
out:
	mutex_unlock(&card->conf_mutex);
	return rc ? rc : count;
}

static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
@@ -337,25 +363,27 @@ static ssize_t qeth_dev_performance_stats_store(struct device *dev,
{
	struct qeth_card *card = dev_get_drvdata(dev);
	char *tmp;
	int i;
	int i, rc = 0;

	if (!card)
		return -EINVAL;

	mutex_lock(&card->conf_mutex);
	i = simple_strtoul(buf, &tmp, 16);
	if ((i == 0) || (i == 1)) {
		if (i == card->options.performance_stats)
			return count;
			goto out;;
		card->options.performance_stats = i;
		if (i == 0)
			memset(&card->perf_stats, 0,
				sizeof(struct qeth_perf_stats));
		card->perf_stats.initial_rx_packets = card->stats.rx_packets;
		card->perf_stats.initial_tx_packets = card->stats.tx_packets;
	} else {
		return -EINVAL;
	}
	return count;
	} else
		rc = -EINVAL;
out:
	mutex_unlock(&card->conf_mutex);
	return rc ? rc : count;
}

static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
@@ -377,15 +405,17 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
{
	struct qeth_card *card = dev_get_drvdata(dev);
	char *tmp;
	int i, rc;
	int i, rc = 0;
	enum qeth_discipline_id newdis;

	if (!card)
		return -EINVAL;

	if (((card->state != CARD_STATE_DOWN) &&
	     (card->state != CARD_STATE_RECOVER)))
		return -EPERM;
	mutex_lock(&card->conf_mutex);
	if (card->state != CARD_STATE_DOWN) {
		rc = -EPERM;
		goto out;
	}

	i = simple_strtoul(buf, &tmp, 16);
	switch (i) {
@@ -396,12 +426,13 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
		newdis = QETH_DISCIPLINE_LAYER2;
		break;
	default:
		return -EINVAL;
		rc = -EINVAL;
		goto out;
	}

	if (card->options.layer2 == newdis) {
		return count;
	} else {
	if (card->options.layer2 == newdis)
		goto out;
	else {
		if (card->discipline.ccwgdriver) {
			card->discipline.ccwgdriver->remove(card->gdev);
			qeth_core_free_discipline(card);
@@ -410,12 +441,12 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,

	rc = qeth_core_load_discipline(card, newdis);
	if (rc)
		return rc;
		goto out;

	rc = card->discipline.ccwgdriver->probe(card->gdev);
	if (rc)
		return rc;
	return count;
out:
	mutex_unlock(&card->conf_mutex);
	return rc ? rc : count;
}

static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
@@ -454,11 +485,10 @@ static ssize_t qeth_dev_isolation_store(struct device *dev,
	char *tmp, *curtoken;
	curtoken = (char *) buf;

	if (!card) {
		rc = -EINVAL;
		goto out;
	}
	if (!card)
		return -EINVAL;

	mutex_lock(&card->conf_mutex);
	/* check for unknown, too, in case we do not yet know who we are */
	if (card->info.type != QETH_CARD_TYPE_OSAE &&
	    card->info.type != QETH_CARD_TYPE_UNKNOWN) {
@@ -491,6 +521,7 @@ static ssize_t qeth_dev_isolation_store(struct device *dev,
			rc = ipa_rc;
	}
out:
	mutex_unlock(&card->conf_mutex);
	return rc;
}

@@ -510,22 +541,25 @@ static ssize_t qeth_dev_blkt_store(struct qeth_card *card,
		const char *buf, size_t count, int *value, int max_value)
{
	char *tmp;
	int i;
	int i, rc = 0;

	if (!card)
		return -EINVAL;

	mutex_lock(&card->conf_mutex);
	if ((card->state != CARD_STATE_DOWN) &&
	    (card->state != CARD_STATE_RECOVER))
		return -EPERM;

	    (card->state != CARD_STATE_RECOVER)) {
		rc = -EPERM;
		goto out;
	}
	i = simple_strtoul(buf, &tmp, 10);
	if (i <= max_value) {
	if (i <= max_value)
		*value = i;
	} else {
		return -EINVAL;
	}
	return count;
	else
		rc = -EINVAL;
out:
	mutex_unlock(&card->conf_mutex);
	return rc ? rc : count;
}

static ssize_t qeth_dev_blkt_total_show(struct device *dev,
+7 −1
Original line number Diff line number Diff line
@@ -924,6 +924,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
	enum qeth_card_states recover_flag;

	BUG_ON(!card);
	mutex_lock(&card->conf_mutex);
	QETH_DBF_TEXT(SETUP, 2, "setonlin");
	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));

@@ -956,7 +957,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
			dev_warn(&card->gdev->dev,
				"The LAN is offline\n");
			card->lan_online = 0;
			return 0;
			goto out;
		}
		rc = -ENODEV;
		goto out_remove;
@@ -995,6 +996,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
	}
	/* let user_space know that device is online */
	kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
out:
	mutex_unlock(&card->conf_mutex);
	return 0;

out_remove:
@@ -1007,6 +1010,7 @@ out_remove:
		card->state = CARD_STATE_RECOVER;
	else
		card->state = CARD_STATE_DOWN;
	mutex_unlock(&card->conf_mutex);
	return rc;
}

@@ -1022,6 +1026,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
	int rc = 0, rc2 = 0, rc3 = 0;
	enum qeth_card_states recover_flag;

	mutex_lock(&card->conf_mutex);
	QETH_DBF_TEXT(SETUP, 3, "setoffl");
	QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *));

@@ -1040,6 +1045,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
		card->state = CARD_STATE_RECOVER;
	/* let user_space know that device is offline */
	kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE);
	mutex_unlock(&card->conf_mutex);
	return 0;
}

+7 −1
Original line number Diff line number Diff line
@@ -3378,6 +3378,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
	enum qeth_card_states recover_flag;

	BUG_ON(!card);
	mutex_lock(&card->conf_mutex);
	QETH_DBF_TEXT(SETUP, 2, "setonlin");
	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));

@@ -3409,7 +3410,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
			dev_warn(&card->gdev->dev,
				"The LAN is offline\n");
			card->lan_online = 0;
			return 0;
			goto out;
		}
		rc = -ENODEV;
		goto out_remove;
@@ -3456,6 +3457,8 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
	}
	/* let user_space know that device is online */
	kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
out:
	mutex_unlock(&card->conf_mutex);
	return 0;
out_remove:
	card->use_hard_stop = 1;
@@ -3467,6 +3470,7 @@ out_remove:
		card->state = CARD_STATE_RECOVER;
	else
		card->state = CARD_STATE_DOWN;
	mutex_unlock(&card->conf_mutex);
	return rc;
}

@@ -3482,6 +3486,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
	int rc = 0, rc2 = 0, rc3 = 0;
	enum qeth_card_states recover_flag;

	mutex_lock(&card->conf_mutex);
	QETH_DBF_TEXT(SETUP, 3, "setoffl");
	QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *));

@@ -3500,6 +3505,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
		card->state = CARD_STATE_RECOVER;
	/* let user_space know that device is offline */
	kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE);
	mutex_unlock(&card->conf_mutex);
	return 0;
}

Loading