From 3a6b95c81c522d9dbd36b33d33b08e66c87a6088 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 28 Dec 2006 13:05:36 +0100 Subject: qeth: fix uaccess handling and get rid of unused variable [patch] qeth: fix uaccess handling and get rid of unused variable drivers/s390/net/qeth_main.c: In function `qeth_process_inbound_buffer': drivers/s390/net/qeth_main.c:2563: warning: unused variable `vlan_addr' include/asm/uaccess.h: In function `qeth_do_ioctl': drivers/s390/net/qeth_main.c:4847: warning: ignoring return value of `copy_to_user' drivers/s390/net/qeth_main.c:4849: warning: ignoring return value of `copy_to_user' drivers/s390/net/qeth_main.c:4996: warning: ignoring return value of `copy_to_user' Cc: Frank Pavlic Signed-off-by: Heiko Carstens Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_main.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 2bde4f1fb9c..f17d7cfb420 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -2560,7 +2560,6 @@ qeth_process_inbound_buffer(struct qeth_card *card, int offset; int rxrc; __u16 vlan_tag = 0; - __u16 *vlan_addr; /* get first element of current buffer */ element = (struct qdio_buffer_element *)&buf->buffer->element[0]; @@ -4844,9 +4843,11 @@ qeth_arp_query(struct qeth_card *card, char __user *udata) "(0x%x/%d)\n", QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc), tmp, tmp); - copy_to_user(udata, qinfo.udata, 4); + if (copy_to_user(udata, qinfo.udata, 4)) + rc = -EFAULT; } else { - copy_to_user(udata, qinfo.udata, qinfo.udata_len); + if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) + rc = -EFAULT; } kfree(qinfo.udata); return rc; @@ -4992,8 +4993,10 @@ qeth_snmp_command(struct qeth_card *card, char __user *udata) if (rc) PRINT_WARN("SNMP command failed on %s: (0x%x)\n", QETH_CARD_IFNAME(card), rc); - else - copy_to_user(udata, qinfo.udata, qinfo.udata_len); + else { + if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) + rc = -EFAULT; + } kfree(ureq); kfree(qinfo.udata); -- cgit v1.2.3 From 95c78c8bfe8d0b49a43f392b9a74e2f9e89765ab Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Mon, 8 Jan 2007 17:29:34 +0100 Subject: s390: qeth driver fixes: VLAN hdr, perf stats From: Ursula Braun - VLAN header reordering did not work on packets received through qeth interface in layer 2 mode. This caused dhcpcd not to work with VLAN devices. - set qeth performance statistics initally inactive Signed-off-by: Frank Pavlic Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_main.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index f17d7cfb420..015dc4c9fc1 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -1074,7 +1074,7 @@ qeth_set_intial_options(struct qeth_card *card) card->options.layer2 = 1; else card->options.layer2 = 0; - card->options.performance_stats = 1; + card->options.performance_stats = 0; } /** @@ -2466,32 +2466,17 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, qeth_rebuild_skb_fake_ll_eth(card, skb, hdr); } -static inline __u16 +static inline void qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, struct qeth_hdr *hdr) { - unsigned short vlan_id = 0; -#ifdef CONFIG_QETH_VLAN - struct vlan_hdr *vhdr; -#endif - skb->pkt_type = PACKET_HOST; skb->protocol = qeth_type_trans(skb, skb->dev); if (card->options.checksum_type == NO_CHECKSUMMING) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb->ip_summed = CHECKSUM_NONE; -#ifdef CONFIG_QETH_VLAN - if (hdr->hdr.l2.flags[2] & (QETH_LAYER2_FLAG_VLAN)) { - vhdr = (struct vlan_hdr *) skb->data; - skb->protocol = - __constant_htons(vhdr->h_vlan_encapsulated_proto); - vlan_id = hdr->hdr.l2.vlan_id; - skb_pull(skb, VLAN_HLEN); - } -#endif *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; - return vlan_id; } static inline __u16 @@ -2570,7 +2555,7 @@ qeth_process_inbound_buffer(struct qeth_card *card, &offset, &hdr))) { skb->dev = card->dev; if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) - vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr); + qeth_layer2_rebuild_skb(card, skb, hdr); else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3) vlan_tag = qeth_rebuild_skb(card, skb, hdr); else { /*in case of OSN*/ -- cgit v1.2.3 From 2d36c16eb032239cb038ad875ecf83c545002461 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Mon, 8 Jan 2007 17:29:58 +0100 Subject: s390: qeth driver fixes: packet socket - packet socket support is not complete. Recvfrom a packet socket does not fill the sockaddr_ll structure. device function hard_header_parse is not implemented. For layer 2 mode and layer 3 mode with fake_ll turned on, we have the information to fill sockaddr_ll. Signed-off-by: Frank Pavlic Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_main.c | 58 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 5 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 015dc4c9fc1..bfc37bae19b 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -3952,13 +3952,22 @@ static inline struct sk_buff * qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, struct qeth_hdr **hdr, int ipv) { - struct sk_buff *new_skb; + struct sk_buff *new_skb, *new_skb2; QETH_DBF_TEXT(trace, 6, "prepskb"); - - new_skb = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); - if (new_skb == NULL) + new_skb = skb; + new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC); + if (!new_skb) return NULL; + new_skb2 = qeth_realloc_headroom(card, new_skb, + sizeof(struct qeth_hdr)); + if (!new_skb2) { + __qeth_free_new_skb(skb, new_skb); + return NULL; + } + if (new_skb != skb) + __qeth_free_new_skb(new_skb2, new_skb); + new_skb = new_skb2; *hdr = __qeth_prepare_skb(card, new_skb, ipv); if (*hdr == NULL) { __qeth_free_new_skb(skb, new_skb); @@ -6338,6 +6347,42 @@ static struct ethtool_ops qeth_ethtool_ops = { .set_tso = qeth_ethtool_set_tso, }; +static int +qeth_hard_header_parse(struct sk_buff *skb, unsigned char *haddr) +{ + struct qeth_card *card; + struct ethhdr *eth; + + card = qeth_get_card_from_dev(skb->dev); + if (card->options.layer2) + goto haveheader; +#ifdef CONFIG_QETH_IPV6 + /* cause of the manipulated arp constructor and the ARP + flag for OSAE devices we have some nasty exceptions */ + if (card->info.type == QETH_CARD_TYPE_OSAE) { + if (!card->options.fake_ll) { + if ((skb->pkt_type==PACKET_OUTGOING) && + (skb->protocol==ETH_P_IPV6)) + goto haveheader; + else + return 0; + } else { + if ((skb->pkt_type==PACKET_OUTGOING) && + (skb->protocol==ETH_P_IP)) + return 0; + else + goto haveheader; + } + } +#endif + if (!card->options.fake_ll) + return 0; +haveheader: + eth = eth_hdr(skb); + memcpy(haddr, eth->h_source, ETH_ALEN); + return ETH_ALEN; +} + static int qeth_netdev_init(struct net_device *dev) { @@ -6376,7 +6421,10 @@ qeth_netdev_init(struct net_device *dev) if (card->options.fake_ll && (qeth_get_netdev_flags(card) & IFF_NOARP)) dev->hard_header = qeth_fake_header; - dev->hard_header_parse = NULL; + if (dev->type == ARPHRD_IEEE802_TR) + dev->hard_header_parse = NULL; + else + dev->hard_header_parse = qeth_hard_header_parse; dev->set_mac_address = qeth_layer2_set_mac_address; dev->flags |= qeth_get_netdev_flags(card); if ((card->options.fake_broadcast) || -- cgit v1.2.3 From ee2db684b4b92d138ee3b7326e69f4297cf4beca Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Mon, 8 Jan 2007 17:30:11 +0100 Subject: s390: qeth driver fixes: atomic context fixups - 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 Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth.h | 2 +- drivers/s390/net/qeth_main.c | 125 ++++++++++--------------------------------- 2 files changed, 30 insertions(+), 97 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 53c358c7d36..e95c281f1e3 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 bfc37bae19b..d2efa5ff125 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, unsigned long intparm, struct irb *irb) 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); @@ -950,40 +950,6 @@ qeth_do_run_thread(struct qeth_card *card, unsigned long thread) return rc; } -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) { @@ -1047,11 +1013,6 @@ qeth_start_kernel_thread(struct work_struct *work) 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 *card) 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 *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_channel *channel, &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 *card, int len, 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 *card, int len, 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 *card, int len, 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; @@ -5541,12 +5482,10 @@ qeth_set_multicast_list(struct net_device *dev) 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 @@ -8271,8 +8210,7 @@ qeth_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto, } 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; } @@ -8300,8 +8238,7 @@ qeth_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto, 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); } /* @@ -8344,8 +8281,7 @@ qeth_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto, } 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; } @@ -8373,8 +8309,7 @@ qeth_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto, 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); } /** @@ -8416,8 +8351,7 @@ qeth_ip_event(struct notifier_block *this, 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; } @@ -8469,8 +8403,7 @@ qeth_ip6_event(struct notifier_block *this, 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; } -- cgit v1.2.3 From 45d2530167027e96686a1b6a7892c55af1f516f5 Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Mon, 8 Jan 2007 17:30:33 +0100 Subject: s390: iucv Kconfig help description changes [PATCH 4/5] s390: iucv Kconfig help description changes From: Ursula Braun remove text from help description which does not apply anymore for 2.6 kernel series. Signed-off-by: Frank Pavlic Signed-off-by: Jeff Garzik --- drivers/s390/net/Kconfig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index 1a93fa684e9..52625153a4f 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig @@ -27,10 +27,7 @@ config IUCV help Select this option if you want to use inter-user communication under VM or VIF. If unsure, say "Y" to enable a fast communication - link between VM guests. At boot time the user ID of the guest needs - to be passed to the kernel. Note that both kernels need to be - compiled with this option and both need to be booted with the user ID - of the other VM guest. + link between VM guests. config NETIUCV tristate "IUCV network device support (VM only)" -- cgit v1.2.3