Skip to contentSkip to conversation

s390: qeth some more patches for 2.6.36

PATCH In review [email protected] 2 participants 10 messages Jul 23, 2010

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover s390: qeth some more patches for 2.6.36

Hi Dave,

this is the second patch set (qeth + 1 claw) for 2.6.36 (net-next).

shortlog:
Klaus Wacker (1)
qeth: IP address takeover flag setting

Ursula Braun (5)
qeth: serialize sysfs-triggered device configurations
qeth: avoid loop if ipa command response is missing
claw: A claw device is a group of just 2 ccw devices
qeth: return zero from reply callback functions
qeth: avoid useless removal of multicast addresses

Julia Lawall (1)
qeth: Use memdup_user when user data is immediately copied into the allocated region.

Carsten Otte (1)
qeth: Clear mac_bits field when switching between Layer 2 and Layer 3

Thanks,
Frank

#1 lore raw

PATCH 1/8 qeth: IP address takeover flag setting

From: Klaus-Dieter Wacker <[email protected]>

The qeth IP address flag setting is possible when device is offline. When setting device online afterwards the current set IP addresses have to be correctly registered with the device regarding the IP address takeover attribute.

---

 drivers/s390/net/qeth_core.h      |    3 +--
 drivers/s390/net/qeth_core_main.c |    7 +------
 drivers/s390/net/qeth_l3.h        |    1 +
 drivers/s390/net/qeth_l3_main.c   |    2 +-
 drivers/s390/net/qeth_l3_sys.c    |   14 ++++++++++++++
 5 files changed, 18 insertions(+), 9 deletions(-)
drivers/s390/net/qeth_core.h +1 -2
diff -urpN linux-2.6/drivers/s390/net/qeth_core.h linux-2.6-patched/drivers/s390/net/qeth_core.h
@@ -188,8 +188,7 @@ static inline int qeth_is_ipa_enabled(st
 		qeth_is_enabled6(c, f) : qeth_is_enabled(c, f))
 
 #define QETH_IDX_FUNC_LEVEL_OSD		 0x0101
-#define QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT 0x4108
-#define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108
+#define QETH_IDX_FUNC_LEVEL_IQD		 0x4108
 
 #define QETH_MODELLIST_ARRAY \
 	{{0x1731, 0x01, 0x1732, QETH_CARD_TYPE_OSD, QETH_MAX_QUEUES, 0}, \
drivers/s390/net/qeth_core_main.c +1 -6
diff -urpN linux-2.6/drivers/s390/net/qeth_core_main.c linux-2.6-patched/drivers/s390/net/qeth_core_main.c
@@ -1383,12 +1383,7 @@ static void qeth_init_func_level(struct 
 {
 	switch (card->info.type) {
 	case QETH_CARD_TYPE_IQD:
-		if (card->ipato.enabled)
-			card->info.func_level =
-				QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT;
-		else
-			card->info.func_level =
-				QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
+		card->info.func_level =	QETH_IDX_FUNC_LEVEL_IQD;
 		break;
 	case QETH_CARD_TYPE_OSD:
 	case QETH_CARD_TYPE_OSN:
drivers/s390/net/qeth_l3.h +1 -0
diff -urpN linux-2.6/drivers/s390/net/qeth_l3.h linux-2.6-patched/drivers/s390/net/qeth_l3.h
@@ -64,5 +64,6 @@ void qeth_l3_del_rxip(struct qeth_card *
 			const u8 *);
 int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types);
 int qeth_l3_set_rx_csum(struct qeth_card *, enum qeth_checksum_types);
+int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
 
 #endif /* __QETH_L3_H__ */
drivers/s390/net/qeth_l3_main.c +1 -1
diff -urpN linux-2.6/drivers/s390/net/qeth_l3_main.c linux-2.6-patched/drivers/s390/net/qeth_l3_main.c
@@ -195,7 +195,7 @@ static void qeth_l3_convert_addr_to_bits
 	}
 }
 
-static int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
+int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
 						struct qeth_ipaddr *addr)
 {
 	struct qeth_ipato_entry *ipatoe;
drivers/s390/net/qeth_l3_sys.c +14 -0
diff -urpN linux-2.6/drivers/s390/net/qeth_l3_sys.c linux-2.6-patched/drivers/s390/net/qeth_l3_sys.c
@@ -479,6 +479,7 @@ static ssize_t qeth_l3_dev_ipato_enable_
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev_get_drvdata(dev);
+	struct qeth_ipaddr *tmpipa, *t;
 	char *tmp;
 	int rc = 0;
 
@@ -497,8 +498,21 @@ static ssize_t qeth_l3_dev_ipato_enable_
 		card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
 	} else if (!strcmp(tmp, "1")) {
 		card->ipato.enabled = 1;
+		list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) {
+			if ((tmpipa->type == QETH_IP_TYPE_NORMAL) &&
+				qeth_l3_is_addr_covered_by_ipato(card, tmpipa))
+				tmpipa->set_flags |=
+					QETH_IPA_SETIP_TAKEOVER_FLAG;
+		}
+
 	} else if (!strcmp(tmp, "0")) {
 		card->ipato.enabled = 0;
+		list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) {
+			if (tmpipa->set_flags &
+				QETH_IPA_SETIP_TAKEOVER_FLAG)
+				tmpipa->set_flags &=
+					~QETH_IPA_SETIP_TAKEOVER_FLAG;
+		}
 	} else
 		rc = -EINVAL;
 out:
#2 lore raw

PATCH 2/8 qeth: Clear mac_bits field when switching between Layer 2 and Layer 3

In reply to [email protected]

From: Carsten Otte <[email protected]>

This patch fixes a problem that occurs when switching from layer 3 to layer 2 mode. Resetting this mac_bits makes sure that we retrieve our mac address from the card, otherwise the interface simply would'nt work.

---

 drivers/s390/net/qeth_core_sys.c |    1 +
 1 file changed, 1 insertion(+)
drivers/s390/net/qeth_core_sys.c +1 -0
diff -urpN linux-2.6/drivers/s390/net/qeth_core_sys.c linux-2.6-patched/drivers/s390/net/qeth_core_sys.c
@@ -433,6 +433,7 @@ static ssize_t qeth_dev_layer2_store(str
 	if (card->options.layer2 == newdis)
 		goto out;
 	else {
+		card->info.mac_bits  = 0;
 		if (card->discipline.ccwgdriver) {
 			card->discipline.ccwgdriver->remove(card->gdev);
 			qeth_core_free_discipline(card);
#3 lore raw

PATCH 3/8 qeth: serialize sysfs-triggered device configurations

In reply to [email protected]

From: Ursula Braun <[email protected]>

This patch serializes device removal and other sysfs-triggered configurations by moving removal of sysfs-attributes to the beginning of the remove functions. And it serializes online/offline setting and discipline-switching (causing reestablishing of the net_device) by making use of a new discipline mutex.

---

 drivers/s390/net/qeth_core.h      |    1 +
 drivers/s390/net/qeth_core_main.c |   11 +++++++----
 drivers/s390/net/qeth_core_sys.c  |    4 ++--
 drivers/s390/net/qeth_l2_main.c   |    5 +++++
 drivers/s390/net/qeth_l3_main.c   |    8 +++++++-
 5 files changed, 22 insertions(+), 7 deletions(-)
drivers/s390/net/qeth_core.h +1 -0
diff -urpN linux-2.6/drivers/s390/net/qeth_core.h linux-2.6-patched/drivers/s390/net/qeth_core.h
@@ -747,6 +747,7 @@ struct qeth_card {
 	struct qdio_ssqd_desc ssqd;
 	debug_info_t *debug;
 	struct mutex conf_mutex;
+	struct mutex discipline_mutex;
 };
 
 struct qeth_card_list_struct {
drivers/s390/net/qeth_core_main.c +7 -4
diff -urpN linux-2.6/drivers/s390/net/qeth_core_main.c linux-2.6-patched/drivers/s390/net/qeth_core_main.c
@@ -1084,6 +1084,7 @@ static int qeth_setup_card(struct qeth_c
 	spin_lock_init(&card->ip_lock);
 	spin_lock_init(&card->thread_mask_lock);
 	mutex_init(&card->conf_mutex);
+	mutex_init(&card->discipline_mutex);
 	card->thread_start_mask = 0;
 	card->thread_allowed_mask = 0;
 	card->thread_running_mask = 0;
@@ -4348,16 +4349,18 @@ static void qeth_core_remove_device(stru
 	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
 
 	QETH_DBF_TEXT(SETUP, 2, "removedv");
-	if (card->discipline.ccwgdriver) {
-		card->discipline.ccwgdriver->remove(gdev);
-		qeth_core_free_discipline(card);
-	}
 
 	if (card->info.type == QETH_CARD_TYPE_OSN) {
 		qeth_core_remove_osn_attributes(&gdev->dev);
 	} else {
 		qeth_core_remove_device_attributes(&gdev->dev);
 	}
+
+	if (card->discipline.ccwgdriver) {
+		card->discipline.ccwgdriver->remove(gdev);
+		qeth_core_free_discipline(card);
+	}
+
 	debug_unregister(card->debug);
 	write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
 	list_del(&card->list);
drivers/s390/net/qeth_core_sys.c +2 -2
diff -urpN linux-2.6/drivers/s390/net/qeth_core_sys.c linux-2.6-patched/drivers/s390/net/qeth_core_sys.c
@@ -411,7 +411,7 @@ static ssize_t qeth_dev_layer2_store(str
 	if (!card)
 		return -EINVAL;
 
-	mutex_lock(&card->conf_mutex);
+	mutex_lock(&card->discipline_mutex);
 	if (card->state != CARD_STATE_DOWN) {
 		rc = -EPERM;
 		goto out;
@@ -446,7 +446,7 @@ static ssize_t qeth_dev_layer2_store(str
 
 	rc = card->discipline.ccwgdriver->probe(card->gdev);
 out:
-	mutex_unlock(&card->conf_mutex);
+	mutex_unlock(&card->discipline_mutex);
 	return rc ? rc : count;
 }
 
drivers/s390/net/qeth_l2_main.c +5 -0
diff -urpN linux-2.6/drivers/s390/net/qeth_l2_main.c linux-2.6-patched/drivers/s390/net/qeth_l2_main.c
@@ -935,6 +935,7 @@ static int __qeth_l2_set_online(struct c
 	enum qeth_card_states recover_flag;
 
 	BUG_ON(!card);
+	mutex_lock(&card->discipline_mutex);
 	mutex_lock(&card->conf_mutex);
 	QETH_DBF_TEXT(SETUP, 2, "setonlin");
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
@@ -1012,6 +1013,7 @@ static int __qeth_l2_set_online(struct c
 	kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
 out:
 	mutex_unlock(&card->conf_mutex);
+	mutex_unlock(&card->discipline_mutex);
 	return 0;
 
 out_remove:
@@ -1025,6 +1027,7 @@ out_remove:
 	else
 		card->state = CARD_STATE_DOWN;
 	mutex_unlock(&card->conf_mutex);
+	mutex_unlock(&card->discipline_mutex);
 	return rc;
 }
 
@@ -1040,6 +1043,7 @@ static int __qeth_l2_set_offline(struct 
 	int rc = 0, rc2 = 0, rc3 = 0;
 	enum qeth_card_states recover_flag;
 
+	mutex_lock(&card->discipline_mutex);
 	mutex_lock(&card->conf_mutex);
 	QETH_DBF_TEXT(SETUP, 3, "setoffl");
 	QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *));
@@ -1060,6 +1064,7 @@ static int __qeth_l2_set_offline(struct 
 	/* let user_space know that device is offline */
 	kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE);
 	mutex_unlock(&card->conf_mutex);
+	mutex_unlock(&card->discipline_mutex);
 	return 0;
 }
 
drivers/s390/net/qeth_l3_main.c +7 -1
diff -urpN linux-2.6/drivers/s390/net/qeth_l3_main.c linux-2.6-patched/drivers/s390/net/qeth_l3_main.c
@@ -3354,6 +3354,8 @@ static void qeth_l3_remove_device(struct
 {
 	struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
 
+	qeth_l3_remove_device_attributes(&cgdev->dev);
+
 	qeth_set_allowed_threads(card, 0, 1);
 	wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
 
@@ -3367,7 +3369,6 @@ static void qeth_l3_remove_device(struct
 		card->dev = NULL;
 	}
 
-	qeth_l3_remove_device_attributes(&cgdev->dev);
 	qeth_l3_clear_ip_list(card, 0, 0);
 	qeth_l3_clear_ipato_list(card);
 	return;
@@ -3380,6 +3381,7 @@ static int __qeth_l3_set_online(struct c
 	enum qeth_card_states recover_flag;
 
 	BUG_ON(!card);
+	mutex_lock(&card->discipline_mutex);
 	mutex_lock(&card->conf_mutex);
 	QETH_DBF_TEXT(SETUP, 2, "setonlin");
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
@@ -3461,6 +3463,7 @@ static int __qeth_l3_set_online(struct c
 	kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
 out:
 	mutex_unlock(&card->conf_mutex);
+	mutex_unlock(&card->discipline_mutex);
 	return 0;
 out_remove:
 	card->use_hard_stop = 1;
@@ -3473,6 +3476,7 @@ out_remove:
 	else
 		card->state = CARD_STATE_DOWN;
 	mutex_unlock(&card->conf_mutex);
+	mutex_unlock(&card->discipline_mutex);
 	return rc;
 }
 
@@ -3488,6 +3492,7 @@ static int __qeth_l3_set_offline(struct 
 	int rc = 0, rc2 = 0, rc3 = 0;
 	enum qeth_card_states recover_flag;
 
+	mutex_lock(&card->discipline_mutex);
 	mutex_lock(&card->conf_mutex);
 	QETH_DBF_TEXT(SETUP, 3, "setoffl");
 	QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *));
@@ -3508,6 +3513,7 @@ static int __qeth_l3_set_offline(struct 
 	/* let user_space know that device is offline */
 	kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE);
 	mutex_unlock(&card->conf_mutex);
+	mutex_unlock(&card->discipline_mutex);
 	return 0;
 }
 
#4 lore raw

PATCH 4/8 qeth: avoid loop if ipa command response is missing

In reply to [email protected]

From: Ursula Braun <[email protected]>

If qeth issues an ipa command, but for some reasons the response never comes back, qeth reaches a timeout.
Reset the irq_pending flag of the write channel in timeout handling code and trigger a recovery to avoid endless looping for the following ipa command.

---

 drivers/s390/net/qeth_core.h      |    1 +
 drivers/s390/net/qeth_core_main.c |   15 +++++++++++++++
 2 files changed, 16 insertions(+)
drivers/s390/net/qeth_core.h +1 -0
diff -urpN linux-2.6/drivers/s390/net/qeth_core.h linux-2.6-patched/drivers/s390/net/qeth_core.h
@@ -740,6 +740,7 @@ struct qeth_card {
 	struct qeth_qdio_info qdio;
 	struct qeth_perf_stats perf_stats;
 	int use_hard_stop;
+	int read_or_write_problem;
 	struct qeth_osn_info osn_info;
 	struct qeth_discipline discipline;
 	atomic_t force_alloc_skb;
drivers/s390/net/qeth_core_main.c +15 -0
diff -urpN linux-2.6/drivers/s390/net/qeth_core_main.c linux-2.6-patched/drivers/s390/net/qeth_core_main.c
@@ -262,6 +262,7 @@ static int qeth_issue_next_read(struct q
 		QETH_DBF_MESSAGE(2, "%s error in starting next read ccw! "
 			"rc=%i\n", dev_name(&card->gdev->dev), rc);
 		atomic_set(&card->read.irq_pending, 0);
+		card->read_or_write_problem = 1;
 		qeth_schedule_recovery(card);
 		wake_up(&card->wait_q);
 	}
@@ -382,6 +383,7 @@ void qeth_clear_ipacmd_list(struct qeth_
 		qeth_put_reply(reply);
 	}
 	spin_unlock_irqrestore(&card->lock, flags);
+	atomic_set(&card->write.irq_pending, 0);
 }
 EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);
 
@@ -1076,6 +1078,7 @@ static int qeth_setup_card(struct qeth_c
 	card->state = CARD_STATE_DOWN;
 	card->lan_online = 0;
 	card->use_hard_stop = 0;
+	card->read_or_write_problem = 0;
 	card->dev = NULL;
 	spin_lock_init(&card->vlanlock);
 	spin_lock_init(&card->mclock);
@@ -1658,6 +1661,10 @@ int qeth_send_control_data(struct qeth_c
 
 	QETH_CARD_TEXT(card, 2, "sendctl");
 
+	if (card->read_or_write_problem) {
+		qeth_release_buffer(iob->channel, iob);
+		return -EIO;
+	}
 	reply = qeth_alloc_reply(card);
 	if (!reply) {
 		return -ENOMEM;
@@ -1729,6 +1736,9 @@ time_err:
 	spin_unlock_irqrestore(&reply->card->lock, flags);
 	reply->rc = -ETIME;
 	atomic_inc(&reply->received);
+	atomic_set(&card->write.irq_pending, 0);
+	qeth_release_buffer(iob->channel, iob);
+	card->write.buf_no = (card->write.buf_no + 1) % QETH_CMD_BUFFER_NO;
 	wake_up(&reply->wait_q);
 	rc = reply->rc;
 	qeth_put_reply(reply);
@@ -2485,6 +2495,10 @@ int qeth_send_ipa_cmd(struct qeth_card *
 	qeth_prepare_ipa_cmd(card, iob, prot_type);
 	rc = qeth_send_control_data(card, IPA_CMD_LENGTH,
 						iob, reply_cb, reply_param);
+	if (rc == -ETIME) {
+		qeth_clear_ipacmd_list(card);
+		qeth_schedule_recovery(card);
+	}
 	return rc;
 }
 EXPORT_SYMBOL_GPL(qeth_send_ipa_cmd);
@@ -3967,6 +3981,7 @@ retriable:
 		else
 			goto retry;
 	}
+	card->read_or_write_problem = 0;
 	rc = qeth_mpc_initialize(card);
 	if (rc) {
 		QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
#5 lore raw

PATCH 5/8 claw: A claw device is a group of just 2 ccw devices

In reply to [email protected]

From: Ursula Braun <[email protected]>

When creating a claw device, just 2 subchannels have to be grouped.

---

 drivers/s390/net/claw.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/net/claw.c +1 -1
diff -urpN linux-2.6/drivers/s390/net/claw.c linux-2.6-patched/drivers/s390/net/claw.c
@@ -295,7 +295,7 @@ claw_driver_group_store(struct device_dr
 	int err;
 	err = ccwgroup_create_from_string(claw_root_dev,
 					  claw_group_driver.driver_id,
-					  &claw_ccw_driver, 3, buf);
+					  &claw_ccw_driver, 2, buf);
 	return err ? err : count;
 }
 
#6 lore raw

PATCH 6/8 qeth: return zero from reply callback functions

In reply to [email protected]

From: Ursula Braun <[email protected]>

Reply callback functions in qeth should return zero if command response consists of one part only, otherwise qeth continues waiting for further parts of the command response.

---

 drivers/s390/net/qeth_core_main.c |   10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/s390/net/qeth_core_main.c +2 -8
diff -urpN linux-2.6/drivers/s390/net/qeth_core_main.c linux-2.6-patched/drivers/s390/net/qeth_core_main.c
@@ -1996,7 +1996,7 @@ static int qeth_ulp_setup_cb(struct qeth
 		QETH_DBF_TEXT(SETUP, 2, "olmlimit");
 		dev_err(&card->gdev->dev, "A connection could not be "
 			"established because of an OLM limit\n");
-		rc = -EMLINK;
+		iob->rc = -EMLINK;
 	}
 	QETH_DBF_TEXT_(SETUP, 2, "  rc%d", iob->rc);
 	return rc;
@@ -3423,7 +3423,6 @@ static int qeth_setadpparms_set_access_c
 {
 	struct qeth_ipa_cmd *cmd;
 	struct qeth_set_access_ctrl *access_ctrl_req;
-	int rc;
 
 	QETH_CARD_TEXT(card, 4, "setaccb");
 
@@ -3450,7 +3449,6 @@ static int qeth_setadpparms_set_access_c
 			card->gdev->dev.kobj.name,
 			access_ctrl_req->subcmd_code,
 			cmd->data.setadapterparms.hdr.return_code);
-		rc = 0;
 		break;
 	}
 	case SET_ACCESS_CTRL_RC_NOT_SUPPORTED:
@@ -3464,7 +3462,6 @@ static int qeth_setadpparms_set_access_c
 
 		/* ensure isolation mode is "none" */
 		card->options.isolation = ISOLATION_MODE_NONE;
-		rc = -EOPNOTSUPP;
 		break;
 	}
 	case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER:
@@ -3479,7 +3476,6 @@ static int qeth_setadpparms_set_access_c
 
 		/* ensure isolation mode is "none" */
 		card->options.isolation = ISOLATION_MODE_NONE;
-		rc = -EOPNOTSUPP;
 		break;
 	}
 	case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF:
@@ -3493,7 +3489,6 @@ static int qeth_setadpparms_set_access_c
 
 		/* ensure isolation mode is "none" */
 		card->options.isolation = ISOLATION_MODE_NONE;
-		rc = -EPERM;
 		break;
 	}
 	default:
@@ -3507,12 +3502,11 @@ static int qeth_setadpparms_set_access_c
 
 		/* ensure isolation mode is "none" */
 		card->options.isolation = ISOLATION_MODE_NONE;
-		rc = 0;
 		break;
 	}
 	}
 	qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
-	return rc;
+	return 0;
 }
 
 static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
#7 lore raw

PATCH 7/8 qeth: Use memdup_user when user data is immediately copied into the allocated region.

In reply to [email protected]

From: Julia Lawall <[email protected]>

The semantic patch that makes this change is as follows:
(http://coccinelle.lip6.fr/)

// <smpl>
@@
expression from,to,size,flag;
position p;
identifier l1,l2;
@@

- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
+ to = memdup_user(from,size);
if (
- to==NULL
+ IS_ERR(to)

                 || ...) {

<+... when != goto l1;
- -ENOMEM
+ PTR_ERR(to)
...+>
}
- if (copy_from_user(to, from, size) != 0) {

-    <+... when != goto l2;
-    -EFAULT
-    ...+>

- }
// </smpl>

---

 drivers/s390/net/qeth_core_main.c |   11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/s390/net/qeth_core_main.c +3 -8
diff -urpN linux-2.6/drivers/s390/net/qeth_core_main.c linux-2.6-patched/drivers/s390/net/qeth_core_main.c
@@ -3748,15 +3748,10 @@ int qeth_snmp_command(struct qeth_card *
 	/* skip 4 bytes (data_len struct member) to get req_len */
 	if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int)))
 		return -EFAULT;
-	ureq = kmalloc(req_len+sizeof(struct qeth_snmp_ureq_hdr), GFP_KERNEL);
-	if (!ureq) {
+	ureq = memdup_user(udata, req_len + sizeof(struct qeth_snmp_ureq_hdr));
+	if (IS_ERR(ureq)) {
 		QETH_CARD_TEXT(card, 2, "snmpnome");
-		return -ENOMEM;
-	}
-	if (copy_from_user(ureq, udata,
-			req_len + sizeof(struct qeth_snmp_ureq_hdr))) {
-		kfree(ureq);
-		return -EFAULT;
+		return PTR_ERR(ureq);
 	}
 	qinfo.udata_len = ureq->hdr.data_len;
 	qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL);
#8 lore raw

PATCH 8/8 qeth: avoid useless removal of multicast addresses

In reply to [email protected]

From: Ursula Braun <[email protected]>

Function qeth_l2_remove_device invokes qeth_l2_del_all_mc at the end. This is needless, because it is already called in the offline function. And even more this is invalid, because multicast addresses cannot be removed in DOWN state. Thus this patch deletes invocation of qeth_l2_del_all_mc in function qeth_l2_remove_device.

---

 drivers/s390/net/qeth_l2_main.c |    2 --
 1 file changed, 2 deletions(-)
drivers/s390/net/qeth_l2_main.c +0 -2
diff -urpN linux-2.6/drivers/s390/net/qeth_l2_main.c linux-2.6-patched/drivers/s390/net/qeth_l2_main.c
@@ -860,8 +860,6 @@ static void qeth_l2_remove_device(struct
 		unregister_netdev(card->dev);
 		card->dev = NULL;
 	}
-
-	qeth_l2_del_all_mc(card);
 	return;
 }