[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: Frank Pavlic <pavlic@de.ibm.com> diffstat: qeth.h | 2 ++ qeth_main.c | 37 +++++++++++++++++-------------------- 2 files changed, 19 insertions(+), 20 deletions(-) Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
This commit is contained in:
parent
bb53d6d0e7
commit
9123e0d789
@ -686,6 +686,7 @@ struct qeth_seqno {
|
||||
__u32 pdu_hdr;
|
||||
__u32 pdu_hdr_ack;
|
||||
__u16 ipa;
|
||||
__u32 pkt_seqno;
|
||||
};
|
||||
|
||||
struct qeth_reply {
|
||||
@ -848,6 +849,7 @@ qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size)
|
||||
"on interface %s", QETH_CARD_IFNAME(card));
|
||||
return -ENOMEM;
|
||||
}
|
||||
kfree_skb(*skb);
|
||||
*skb = new_skb;
|
||||
}
|
||||
return 0;
|
||||
|
@ -511,7 +511,7 @@ static int
|
||||
__qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
|
||||
{
|
||||
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;
|
||||
|
||||
QETH_DBF_TEXT(setup, 3, "setoffl");
|
||||
@ -523,11 +523,13 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
|
||||
CARD_BUS_ID(card));
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
if ((rc = ccw_device_set_offline(CARD_DDEV(card))) ||
|
||||
(rc = ccw_device_set_offline(CARD_WDEV(card))) ||
|
||||
(rc = ccw_device_set_offline(CARD_RDEV(card)))) {
|
||||
rc = ccw_device_set_offline(CARD_DDEV(card));
|
||||
rc2 = ccw_device_set_offline(CARD_WDEV(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);
|
||||
}
|
||||
if (recover_flag == CARD_STATE_UP)
|
||||
card->state = CARD_STATE_RECOVER;
|
||||
qeth_notify_processes();
|
||||
@ -1046,6 +1048,7 @@ qeth_setup_card(struct qeth_card *card)
|
||||
spin_lock_init(&card->vlanlock);
|
||||
card->vlangrp = NULL;
|
||||
#endif
|
||||
spin_lock_init(&card->lock);
|
||||
spin_lock_init(&card->ip_lock);
|
||||
spin_lock_init(&card->thread_mask_lock);
|
||||
card->thread_start_mask = 0;
|
||||
@ -1626,16 +1629,6 @@ qeth_cmd_timeout(unsigned long data)
|
||||
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 *
|
||||
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",
|
||||
QETH_CARD_IFNAME(card),
|
||||
card->info.chpid);
|
||||
card->lan_online = 1;
|
||||
netif_carrier_on(card->dev);
|
||||
qeth_reset_ip_addresses(card);
|
||||
qeth_schedule_recovery(card);
|
||||
return NULL;
|
||||
case IPA_CMD_REGISTER_LOCAL_ADDR:
|
||||
QETH_DBF_TEXT(trace,3, "irla");
|
||||
@ -2387,6 +2379,7 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
|
||||
skb_pull(skb, VLAN_HLEN);
|
||||
}
|
||||
#endif
|
||||
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
|
||||
return vlan_id;
|
||||
}
|
||||
|
||||
@ -3014,7 +3007,7 @@ qeth_alloc_buffer_pool(struct qeth_card *card)
|
||||
return -ENOMEM;
|
||||
}
|
||||
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) {
|
||||
while (j > 0)
|
||||
free_page((unsigned long)
|
||||
@ -3058,7 +3051,8 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
|
||||
if (card->qdio.state == QETH_QDIO_ALLOCATED)
|
||||
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)
|
||||
return - ENOMEM;
|
||||
QETH_DBF_TEXT(setup, 2, "inq");
|
||||
@ -3083,7 +3077,7 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
|
||||
}
|
||||
for (i = 0; i < card->qdio.no_out_queues; ++i){
|
||||
card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q),
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL|GFP_DMA);
|
||||
if (!card->qdio.out_qs[i]){
|
||||
while (i > 0)
|
||||
kfree(card->qdio.out_qs[--i]);
|
||||
@ -6470,6 +6464,9 @@ qeth_query_ipassists_cb(struct qeth_card *card, struct qeth_reply *reply,
|
||||
if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
|
||||
card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
|
||||
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 {
|
||||
#ifdef CONFIG_QETH_IPV6
|
||||
card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
|
||||
|
Loading…
Reference in New Issue
Block a user