Commit 9123e0d7 authored by Ursula Braun's avatar Ursula Braun Committed by Jeff Garzik

[PATCH] s390: qeth driver fixes

From: Peter Tiedemann <ptiedem@de.ibm.com>
From: Frank Pavlic <pavlic@de.ibm.com>
	minor qeth fixes:
	- free old skb in qeth_realloc_headroom after duplicating skb
	- disable IPV6 support for Hipersockets devices
	- call ccw_device_set_offline on every channel regardless
	  of the return value of the prior ccw_device_set_offline calls
	- allocate qdio structures in DMA-area
	- schedule recovery of appropriate card
	  when cable has been inserted again.
	- add missing initialization of card->lock
	- write sequence number in skb->cb for SNA protocol which
	  requires strictly serialized packets.
Signed-off-by: default avatarFrank Pavlic <pavlic@de.ibm.com>

diffstat:
 qeth.h      |    2 ++
 qeth_main.c |   37 +++++++++++++++++--------------------
 2 files changed, 19 insertions(+), 20 deletions(-)
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent bb53d6d0
...@@ -686,6 +686,7 @@ struct qeth_seqno { ...@@ -686,6 +686,7 @@ struct qeth_seqno {
__u32 pdu_hdr; __u32 pdu_hdr;
__u32 pdu_hdr_ack; __u32 pdu_hdr_ack;
__u16 ipa; __u16 ipa;
__u32 pkt_seqno;
}; };
struct qeth_reply { struct qeth_reply {
...@@ -848,6 +849,7 @@ qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size) ...@@ -848,6 +849,7 @@ qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size)
"on interface %s", QETH_CARD_IFNAME(card)); "on interface %s", QETH_CARD_IFNAME(card));
return -ENOMEM; return -ENOMEM;
} }
kfree_skb(*skb);
*skb = new_skb; *skb = new_skb;
} }
return 0; return 0;
......
...@@ -511,7 +511,7 @@ static int ...@@ -511,7 +511,7 @@ static int
__qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
{ {
struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data; struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
int rc = 0; int rc = 0, rc2 = 0, rc3 = 0;
enum qeth_card_states recover_flag; enum qeth_card_states recover_flag;
QETH_DBF_TEXT(setup, 3, "setoffl"); QETH_DBF_TEXT(setup, 3, "setoffl");
...@@ -523,11 +523,13 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) ...@@ -523,11 +523,13 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
CARD_BUS_ID(card)); CARD_BUS_ID(card));
return -ERESTARTSYS; return -ERESTARTSYS;
} }
if ((rc = ccw_device_set_offline(CARD_DDEV(card))) || rc = ccw_device_set_offline(CARD_DDEV(card));
(rc = ccw_device_set_offline(CARD_WDEV(card))) || rc2 = ccw_device_set_offline(CARD_WDEV(card));
(rc = ccw_device_set_offline(CARD_RDEV(card)))) { rc3 = ccw_device_set_offline(CARD_RDEV(card));
if (!rc)
rc = (rc2) ? rc2 : rc3;
if (rc)
QETH_DBF_TEXT_(setup, 2, "1err%d", rc); QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
}
if (recover_flag == CARD_STATE_UP) if (recover_flag == CARD_STATE_UP)
card->state = CARD_STATE_RECOVER; card->state = CARD_STATE_RECOVER;
qeth_notify_processes(); qeth_notify_processes();
...@@ -1046,6 +1048,7 @@ qeth_setup_card(struct qeth_card *card) ...@@ -1046,6 +1048,7 @@ qeth_setup_card(struct qeth_card *card)
spin_lock_init(&card->vlanlock); spin_lock_init(&card->vlanlock);
card->vlangrp = NULL; card->vlangrp = NULL;
#endif #endif
spin_lock_init(&card->lock);
spin_lock_init(&card->ip_lock); spin_lock_init(&card->ip_lock);
spin_lock_init(&card->thread_mask_lock); spin_lock_init(&card->thread_mask_lock);
card->thread_start_mask = 0; card->thread_start_mask = 0;
...@@ -1626,16 +1629,6 @@ qeth_cmd_timeout(unsigned long data) ...@@ -1626,16 +1629,6 @@ qeth_cmd_timeout(unsigned long data)
spin_unlock_irqrestore(&reply->card->lock, flags); spin_unlock_irqrestore(&reply->card->lock, flags);
} }
static void
qeth_reset_ip_addresses(struct qeth_card *card)
{
QETH_DBF_TEXT(trace, 2, "rstipadd");
qeth_clear_ip_list(card, 0, 1);
/* this function will also schedule the SET_IP_THREAD */
qeth_set_multicast_list(card->dev);
}
static struct qeth_ipa_cmd * static struct qeth_ipa_cmd *
qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
{ {
...@@ -1664,9 +1657,8 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) ...@@ -1664,9 +1657,8 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
"IP address reset.\n", "IP address reset.\n",
QETH_CARD_IFNAME(card), QETH_CARD_IFNAME(card),
card->info.chpid); card->info.chpid);
card->lan_online = 1;
netif_carrier_on(card->dev); netif_carrier_on(card->dev);
qeth_reset_ip_addresses(card); qeth_schedule_recovery(card);
return NULL; return NULL;
case IPA_CMD_REGISTER_LOCAL_ADDR: case IPA_CMD_REGISTER_LOCAL_ADDR:
QETH_DBF_TEXT(trace,3, "irla"); QETH_DBF_TEXT(trace,3, "irla");
...@@ -2387,6 +2379,7 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, ...@@ -2387,6 +2379,7 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
skb_pull(skb, VLAN_HLEN); skb_pull(skb, VLAN_HLEN);
} }
#endif #endif
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
return vlan_id; return vlan_id;
} }
...@@ -3014,7 +3007,7 @@ qeth_alloc_buffer_pool(struct qeth_card *card) ...@@ -3014,7 +3007,7 @@ qeth_alloc_buffer_pool(struct qeth_card *card)
return -ENOMEM; return -ENOMEM;
} }
for(j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j){ for(j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j){
ptr = (void *) __get_free_page(GFP_KERNEL); ptr = (void *) __get_free_page(GFP_KERNEL|GFP_DMA);
if (!ptr) { if (!ptr) {
while (j > 0) while (j > 0)
free_page((unsigned long) free_page((unsigned long)
...@@ -3058,7 +3051,8 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) ...@@ -3058,7 +3051,8 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
if (card->qdio.state == QETH_QDIO_ALLOCATED) if (card->qdio.state == QETH_QDIO_ALLOCATED)
return 0; return 0;
card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), GFP_KERNEL); card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
GFP_KERNEL|GFP_DMA);
if (!card->qdio.in_q) if (!card->qdio.in_q)
return - ENOMEM; return - ENOMEM;
QETH_DBF_TEXT(setup, 2, "inq"); QETH_DBF_TEXT(setup, 2, "inq");
...@@ -3083,7 +3077,7 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) ...@@ -3083,7 +3077,7 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
} }
for (i = 0; i < card->qdio.no_out_queues; ++i){ for (i = 0; i < card->qdio.no_out_queues; ++i){
card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q), card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q),
GFP_KERNEL); GFP_KERNEL|GFP_DMA);
if (!card->qdio.out_qs[i]){ if (!card->qdio.out_qs[i]){
while (i > 0) while (i > 0)
kfree(card->qdio.out_qs[--i]); kfree(card->qdio.out_qs[--i]);
...@@ -6470,6 +6464,9 @@ qeth_query_ipassists_cb(struct qeth_card *card, struct qeth_reply *reply, ...@@ -6470,6 +6464,9 @@ qeth_query_ipassists_cb(struct qeth_card *card, struct qeth_reply *reply,
if (cmd->hdr.prot_version == QETH_PROT_IPV4) { if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported; card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
/* Disable IPV6 support hard coded for Hipersockets */
if(card->info.type == QETH_CARD_TYPE_IQD)
card->options.ipa4.supported_funcs &= ~IPA_IPV6;
} else { } else {
#ifdef CONFIG_QETH_IPV6 #ifdef CONFIG_QETH_IPV6
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported; card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment