[PATCH 3/5] s390: qeth driver fixes
From: Frank Blaschka [EMAIL PROTECTED]
- 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 [EMAIL PROTECTED]
---
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