[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;
|
||||||
__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)
|
||||||
"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
|
||||||
__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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
"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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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,
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue