* [PATCH 3/5] s390: qeth driver fixes
@ 2006-05-24 7:51 Frank Pavlic
0 siblings, 0 replies; 2+ messages in thread
From: Frank Pavlic @ 2006-05-24 7:51 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
From: Ursula Braun <braunu@de.ibm.com>
From: Frank Blaschka <Frank.Blaschka@de.ibm.com>
From: Frank Pavlic <fpavlic@de.ibm.com>
- fix fake_ll during initial device bringup. fake_ll was
not active after first start of the device.
Problem only occured when qeth was built without IPV6 support.
- avoid skb usage after invocation of qeth_flush_buffers,
because skb might already be freed.
- remove yet another useless netif_wake_queue in
qeth_softsetup_ipv6 since this function is only called
when device is going online. In this case card->state will
never be in state UP. So let the net_device queue down .
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
---
drivers/s390/net/qeth_main.c | 23 +++++++++++++----------
1 files changed, 13 insertions(+), 10 deletions(-)
e32bb8db95c84a0af8c5688b92ed6691982e4f9c
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 0f6648f..9dbb5be 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -3798,11 +3798,11 @@ qeth_open(struct net_device *dev)
QETH_DBF_TEXT(trace,4,"nomacadr");
return -EPERM;
}
- card->dev->flags |= IFF_UP;
- netif_start_queue(dev);
card->data.state = CH_STATE_UP;
card->state = CARD_STATE_UP;
-
+ card->dev->flags |= IFF_UP;
+ netif_start_queue(dev);
+
if (!card->lan_online && netif_carrier_ok(dev))
netif_carrier_off(dev);
return 0;
@@ -3958,7 +3958,7 @@ qeth_prepare_skb(struct qeth_card *card,
#endif
*hdr = (struct qeth_hdr *)
qeth_push_skb(card, skb, sizeof(struct qeth_hdr));
- if (hdr == NULL)
+ if (*hdr == NULL)
return -EINVAL;
return 0;
}
@@ -4416,6 +4416,8 @@ qeth_send_packet(struct qeth_card *card,
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
struct qeth_eddp_context *ctx = NULL;
int tx_bytes = skb->len;
+ unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
+ unsigned short tso_size = skb_shinfo(skb)->tso_size;
int rc;
QETH_DBF_TEXT(trace, 6, "sendpkt");
@@ -4498,16 +4500,16 @@ qeth_send_packet(struct qeth_card *card,
card->stats.tx_packets++;
card->stats.tx_bytes += tx_bytes;
#ifdef CONFIG_QETH_PERF_STATS
- if (skb_shinfo(skb)->tso_size &&
+ if (tso_size &&
!(large_send == QETH_LARGE_SEND_NO)) {
- card->perf_stats.large_send_bytes += skb->len;
+ card->perf_stats.large_send_bytes += tx_bytes;
card->perf_stats.large_send_cnt++;
}
- if (skb_shinfo(skb)->nr_frags > 0){
+ if (nr_frags > 0){
card->perf_stats.sg_skbs_sent++;
/* nr_frags + skb->data */
card->perf_stats.sg_frags_sent +=
- skb_shinfo(skb)->nr_frags + 1;
+ nr_frags + 1;
}
#endif /* CONFIG_QETH_PERF_STATS */
}
@@ -6370,6 +6372,9 @@ qeth_netdev_init(struct net_device *dev)
if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
card->dev->dev_id = card->info.unique_id & 0xffff;
#endif
+ if (card->options.fake_ll &&
+ (qeth_get_netdev_flags(card) & IFF_NOARP))
+ dev->hard_header = qeth_fake_header;
dev->hard_header_parse = NULL;
dev->set_mac_address = qeth_layer2_set_mac_address;
dev->flags |= qeth_get_netdev_flags(card);
@@ -7031,14 +7036,12 @@ qeth_softsetup_ipv6(struct qeth_card *ca
QETH_DBF_TEXT(trace,3,"softipv6");
- netif_tx_disable(card->dev);
rc = qeth_send_startlan(card, QETH_PROT_IPV6);
if (rc) {
PRINT_ERR("IPv6 startlan failed on %s\n",
QETH_CARD_IFNAME(card));
return rc;
}
- netif_wake_queue(card->dev);
rc = qeth_query_ipassists(card,QETH_PROT_IPV6);
if (rc) {
PRINT_ERR("IPv6 query ipassist failed on %s\n",
--
1.2.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 3/5] s390: qeth driver fixes
@ 2007-01-08 16:30 Frank Pavlic
0 siblings, 0 replies; 2+ messages in thread
From: Frank Pavlic @ 2007-01-08 16:30 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[PATCH 3/5] s390: qeth driver fixes
From: Frank Blaschka <Frank.Blaschka@de.ibm.com>
- qeth device functions were not callable
in atomic context due to usage of wait_event_xxx operations in qeth.
"schedule while atomic" message appeared and kernel dumped when
removing slave from bond device.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
---
drivers/s390/net/qeth.h | 2 -
drivers/s390/net/qeth_main.c | 125 ++++++++++--------------------------------
2 files changed, 30 insertions(+), 97 deletions(-)
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 53c358c..e95c281 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -710,7 +710,7 @@ struct qeth_reply {
int (*callback)(struct qeth_card *,struct qeth_reply *,unsigned long);
u32 seqno;
unsigned long offset;
- int received;
+ atomic_t received;
int rc;
void *param;
struct qeth_card *card;
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 337304d..19ec4c8 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -471,7 +471,7 @@ qeth_irq(struct ccw_device *cdev, unsign
channel->state == CH_STATE_UP)
qeth_issue_next_read(card);
- tasklet_schedule(&channel->irq_tasklet);
+ qeth_irq_tasklet((unsigned long)channel);
return;
out:
wake_up(&card->wait_q);
@@ -951,40 +951,6 @@ qeth_do_run_thread(struct qeth_card *car
}
static int
-qeth_register_ip_addresses(void *ptr)
-{
- struct qeth_card *card;
-
- card = (struct qeth_card *) ptr;
- daemonize("qeth_reg_ip");
- QETH_DBF_TEXT(trace,4,"regipth1");
- if (!qeth_do_run_thread(card, QETH_SET_IP_THREAD))
- return 0;
- QETH_DBF_TEXT(trace,4,"regipth2");
- qeth_set_ip_addr_list(card);
- qeth_clear_thread_running_bit(card, QETH_SET_IP_THREAD);
- return 0;
-}
-
-/*
- * Drive the SET_PROMISC_MODE thread
- */
-static int
-qeth_set_promisc_mode(void *ptr)
-{
- struct qeth_card *card = (struct qeth_card *) ptr;
-
- daemonize("qeth_setprm");
- QETH_DBF_TEXT(trace,4,"setprm1");
- if (!qeth_do_run_thread(card, QETH_SET_PROMISC_MODE_THREAD))
- return 0;
- QETH_DBF_TEXT(trace,4,"setprm2");
- qeth_setadp_promisc_mode(card);
- qeth_clear_thread_running_bit(card, QETH_SET_PROMISC_MODE_THREAD);
- return 0;
-}
-
-static int
qeth_recover(void *ptr)
{
struct qeth_card *card;
@@ -1047,11 +1013,6 @@ qeth_start_kernel_thread(struct work_str
if (card->read.state != CH_STATE_UP &&
card->write.state != CH_STATE_UP)
return;
-
- if (qeth_do_start_thread(card, QETH_SET_IP_THREAD))
- kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD);
- if (qeth_do_start_thread(card, QETH_SET_PROMISC_MODE_THREAD))
- kernel_thread(qeth_set_promisc_mode, (void *)card, SIGCHLD);
if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
kernel_thread(qeth_recover, (void *) card, SIGCHLD);
}
@@ -1613,8 +1574,6 @@ qeth_issue_next_read(struct qeth_card *c
return -ENOMEM;
}
qeth_setup_ccw(&card->read, iob->data, QETH_BUFSIZE);
- wait_event(card->wait_q,
- atomic_cmpxchg(&card->read.irq_pending, 0, 1) == 0);
QETH_DBF_TEXT(trace, 6, "noirqpnd");
rc = ccw_device_start(card->read.ccwdev, &card->read.ccw,
(addr_t) iob, 0, 0);
@@ -1635,6 +1594,7 @@ qeth_alloc_reply(struct qeth_card *card)
reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC);
if (reply){
atomic_set(&reply->refcnt, 1);
+ atomic_set(&reply->received, 0);
reply->card = card;
};
return reply;
@@ -1655,31 +1615,6 @@ qeth_put_reply(struct qeth_reply *reply)
kfree(reply);
}
-static void
-qeth_cmd_timeout(unsigned long data)
-{
- struct qeth_reply *reply, *list_reply, *r;
- unsigned long flags;
-
- reply = (struct qeth_reply *) data;
- spin_lock_irqsave(&reply->card->lock, flags);
- list_for_each_entry_safe(list_reply, r,
- &reply->card->cmd_waiter_list, list) {
- if (reply == list_reply){
- qeth_get_reply(reply);
- list_del_init(&reply->list);
- spin_unlock_irqrestore(&reply->card->lock, flags);
- reply->rc = -ETIME;
- reply->received = 1;
- wake_up(&reply->wait_q);
- qeth_put_reply(reply);
- return;
- }
- }
- spin_unlock_irqrestore(&reply->card->lock, flags);
-}
-
-
static struct qeth_ipa_cmd *
qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
{
@@ -1745,7 +1680,7 @@ qeth_clear_ipacmd_list(struct qeth_card
list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
qeth_get_reply(reply);
reply->rc = -EIO;
- reply->received = 1;
+ atomic_inc(&reply->received);
list_del_init(&reply->list);
wake_up(&reply->wait_q);
qeth_put_reply(reply);
@@ -1814,7 +1749,7 @@ qeth_send_control_data_cb(struct qeth_ch
&card->cmd_waiter_list);
spin_unlock_irqrestore(&card->lock, flags);
} else {
- reply->received = 1;
+ atomic_inc(&reply->received);
wake_up(&reply->wait_q);
}
qeth_put_reply(reply);
@@ -1858,7 +1793,7 @@ qeth_send_control_data(struct qeth_card
int rc;
unsigned long flags;
struct qeth_reply *reply = NULL;
- struct timer_list timer;
+ unsigned long timeout;
QETH_DBF_TEXT(trace, 2, "sendctl");
@@ -1873,21 +1808,20 @@ qeth_send_control_data(struct qeth_card
reply->seqno = QETH_IDX_COMMAND_SEQNO;
else
reply->seqno = card->seqno.ipa++;
- init_timer(&timer);
- timer.function = qeth_cmd_timeout;
- timer.data = (unsigned long) reply;
init_waitqueue_head(&reply->wait_q);
spin_lock_irqsave(&card->lock, flags);
list_add_tail(&reply->list, &card->cmd_waiter_list);
spin_unlock_irqrestore(&card->lock, flags);
QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
- wait_event(card->wait_q,
- atomic_cmpxchg(&card->write.irq_pending, 0, 1) == 0);
+
+ while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
qeth_prepare_control_data(card, len, iob);
+
if (IS_IPA(iob->data))
- timer.expires = jiffies + QETH_IPA_TIMEOUT;
+ timeout = jiffies + QETH_IPA_TIMEOUT;
else
- timer.expires = jiffies + QETH_TIMEOUT;
+ timeout = jiffies + QETH_TIMEOUT;
+
QETH_DBF_TEXT(trace, 6, "noirqpnd");
spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
@@ -1906,9 +1840,16 @@ qeth_send_control_data(struct qeth_card
wake_up(&card->wait_q);
return rc;
}
- add_timer(&timer);
- wait_event(reply->wait_q, reply->received);
- del_timer_sync(&timer);
+ while (!atomic_read(&reply->received)) {
+ if (time_after(jiffies, timeout)) {
+ spin_lock_irqsave(&reply->card->lock, flags);
+ list_del_init(&reply->list);
+ spin_unlock_irqrestore(&reply->card->lock, flags);
+ reply->rc = -ETIME;
+ atomic_inc(&reply->received);
+ wake_up(&reply->wait_q);
+ }
+ };
rc = reply->rc;
qeth_put_reply(reply);
return rc;
@@ -5538,12 +5479,10 @@ #ifdef CONFIG_QETH_IPV6
qeth_add_multicast_ipv6(card);
#endif
out:
- if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
- schedule_work(&card->kernel_thread_starter);
+ qeth_set_ip_addr_list(card);
if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
return;
- if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0)
- schedule_work(&card->kernel_thread_starter);
+ qeth_setadp_promisc_mode(card);
}
static int
@@ -8268,8 +8207,7 @@ #endif
}
if (!qeth_add_ip(card, ipaddr))
kfree(ipaddr);
- if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
- schedule_work(&card->kernel_thread_starter);
+ qeth_set_ip_addr_list(card);
return rc;
}
@@ -8297,8 +8235,7 @@ #endif
return;
if (!qeth_delete_ip(card, ipaddr))
kfree(ipaddr);
- if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
- schedule_work(&card->kernel_thread_starter);
+ qeth_set_ip_addr_list(card);
}
/*
@@ -8341,8 +8278,7 @@ #endif
}
if (!qeth_add_ip(card, ipaddr))
kfree(ipaddr);
- if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
- schedule_work(&card->kernel_thread_starter);
+ qeth_set_ip_addr_list(card);
return 0;
}
@@ -8370,8 +8306,7 @@ #endif
return;
if (!qeth_delete_ip(card, ipaddr))
kfree(ipaddr);
- if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
- schedule_work(&card->kernel_thread_starter);
+ qeth_set_ip_addr_list(card);
}
/**
@@ -8413,8 +8348,7 @@ qeth_ip_event(struct notifier_block *thi
default:
break;
}
- if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
- schedule_work(&card->kernel_thread_starter);
+ qeth_set_ip_addr_list(card);
out:
return NOTIFY_DONE;
}
@@ -8466,8 +8400,7 @@ qeth_ip6_event(struct notifier_block *th
default:
break;
}
- if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
- schedule_work(&card->kernel_thread_starter);
+ qeth_set_ip_addr_list(card);
out:
return NOTIFY_DONE;
}
--
1.4.2.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-01-08 16:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-08 16:30 [PATCH 3/5] s390: qeth driver fixes Frank Pavlic
-- strict thread matches above, loose matches on Subject: below --
2006-05-24 7:51 Frank Pavlic
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).