aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/raw3270.c4
-rw-r--r--drivers/s390/net/lcs.c4
-rw-r--r--drivers/s390/net/qeth.h77
-rw-r--r--drivers/s390/net/qeth_eddp.c3
-rw-r--r--drivers/s390/net/qeth_main.c316
-rw-r--r--drivers/s390/net/qeth_mpc.c4
-rw-r--r--drivers/s390/net/qeth_mpc.h15
-rw-r--r--drivers/s390/net/qeth_proc.c250
-rw-r--r--drivers/s390/net/qeth_sys.c10
-rw-r--r--drivers/s390/net/qeth_tso.h6
-rw-r--r--drivers/s390/scsi/zfcp_aux.c14
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c4
-rw-r--r--drivers/s390/scsi/zfcp_erp.c94
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c110
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c2
15 files changed, 463 insertions, 450 deletions
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index f5b7d360fc10..1026f2bc3185 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1179,12 +1179,12 @@ raw3270_create_attributes(struct raw3270 *rp)
1179 //FIXME: check return code 1179 //FIXME: check return code
1180 sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); 1180 sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
1181 rp->clttydev = 1181 rp->clttydev =
1182 class_device_create(class3270, 1182 class_device_create(class3270, NULL,
1183 MKDEV(IBM_TTY3270_MAJOR, rp->minor), 1183 MKDEV(IBM_TTY3270_MAJOR, rp->minor),
1184 &rp->cdev->dev, "tty%s", 1184 &rp->cdev->dev, "tty%s",
1185 rp->cdev->dev.bus_id); 1185 rp->cdev->dev.bus_id);
1186 rp->cltubdev = 1186 rp->cltubdev =
1187 class_device_create(class3270, 1187 class_device_create(class3270, NULL,
1188 MKDEV(IBM_FS3270_MAJOR, rp->minor), 1188 MKDEV(IBM_FS3270_MAJOR, rp->minor),
1189 &rp->cdev->dev, "tub%s", 1189 &rp->cdev->dev, "tub%s",
1190 rp->cdev->dev.bus_id); 1190 rp->cdev->dev.bus_id);
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 1c8ad2fcad8a..da8c515743e8 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -8,7 +8,7 @@
8 * Author(s): Original Code written by 8 * Author(s): Original Code written by
9 * DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 9 * DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
10 * Rewritten by 10 * Rewritten by
11 * Frank Pavlic (pavlic@de.ibm.com) and 11 * Frank Pavlic (fpavlic@de.ibm.com) and
12 * Martin Schwidefsky <schwidefsky@de.ibm.com> 12 * Martin Schwidefsky <schwidefsky@de.ibm.com>
13 * 13 *
14 * $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $ 14 * $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $
@@ -2342,6 +2342,6 @@ __exit lcs_cleanup_module(void)
2342module_init(lcs_init_module); 2342module_init(lcs_init_module);
2343module_exit(lcs_cleanup_module); 2343module_exit(lcs_cleanup_module);
2344 2344
2345MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); 2345MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");
2346MODULE_LICENSE("GPL"); 2346MODULE_LICENSE("GPL");
2347 2347
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 38a2441564d7..d238c7ed103b 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -8,6 +8,7 @@
8#include <linux/trdevice.h> 8#include <linux/trdevice.h>
9#include <linux/etherdevice.h> 9#include <linux/etherdevice.h>
10#include <linux/if_vlan.h> 10#include <linux/if_vlan.h>
11#include <linux/ctype.h>
11 12
12#include <net/ipv6.h> 13#include <net/ipv6.h>
13#include <linux/in6.h> 14#include <linux/in6.h>
@@ -24,7 +25,7 @@
24 25
25#include "qeth_mpc.h" 26#include "qeth_mpc.h"
26 27
27#define VERSION_QETH_H "$Revision: 1.142 $" 28#define VERSION_QETH_H "$Revision: 1.152 $"
28 29
29#ifdef CONFIG_QETH_IPV6 30#ifdef CONFIG_QETH_IPV6
30#define QETH_VERSION_IPV6 ":IPv6" 31#define QETH_VERSION_IPV6 ":IPv6"
@@ -718,8 +719,6 @@ struct qeth_reply {
718 atomic_t refcnt; 719 atomic_t refcnt;
719}; 720};
720 721
721#define QETH_BROADCAST_WITH_ECHO 1
722#define QETH_BROADCAST_WITHOUT_ECHO 2
723 722
724struct qeth_card_blkt { 723struct qeth_card_blkt {
725 int time_total; 724 int time_total;
@@ -727,8 +726,10 @@ struct qeth_card_blkt {
727 int inter_packet_jumbo; 726 int inter_packet_jumbo;
728}; 727};
729 728
730 729#define QETH_BROADCAST_WITH_ECHO 0x01
731 730#define QETH_BROADCAST_WITHOUT_ECHO 0x02
731#define QETH_LAYER2_MAC_READ 0x01
732#define QETH_LAYER2_MAC_REGISTERED 0x02
732struct qeth_card_info { 733struct qeth_card_info {
733 unsigned short unit_addr2; 734 unsigned short unit_addr2;
734 unsigned short cula; 735 unsigned short cula;
@@ -736,7 +737,7 @@ struct qeth_card_info {
736 __u16 func_level; 737 __u16 func_level;
737 char mcl_level[QETH_MCL_LENGTH + 1]; 738 char mcl_level[QETH_MCL_LENGTH + 1];
738 int guestlan; 739 int guestlan;
739 int layer2_mac_registered; 740 int mac_bits;
740 int portname_required; 741 int portname_required;
741 int portno; 742 int portno;
742 char portname[9]; 743 char portname[9];
@@ -749,6 +750,7 @@ struct qeth_card_info {
749 int unique_id; 750 int unique_id;
750 struct qeth_card_blkt blkt; 751 struct qeth_card_blkt blkt;
751 __u32 csum_mask; 752 __u32 csum_mask;
753 enum qeth_ipa_promisc_modes promisc_mode;
752}; 754};
753 755
754struct qeth_card_options { 756struct qeth_card_options {
@@ -775,6 +777,7 @@ struct qeth_card_options {
775enum qeth_threads { 777enum qeth_threads {
776 QETH_SET_IP_THREAD = 1, 778 QETH_SET_IP_THREAD = 1,
777 QETH_RECOVER_THREAD = 2, 779 QETH_RECOVER_THREAD = 2,
780 QETH_SET_PROMISC_MODE_THREAD = 4,
778}; 781};
779 782
780struct qeth_osn_info { 783struct qeth_osn_info {
@@ -1074,6 +1077,26 @@ qeth_get_qdio_q_format(struct qeth_card *card)
1074 } 1077 }
1075} 1078}
1076 1079
1080static inline int
1081qeth_isdigit(char * buf)
1082{
1083 while (*buf) {
1084 if (!isdigit(*buf++))
1085 return 0;
1086 }
1087 return 1;
1088}
1089
1090static inline int
1091qeth_isxdigit(char * buf)
1092{
1093 while (*buf) {
1094 if (!isxdigit(*buf++))
1095 return 0;
1096 }
1097 return 1;
1098}
1099
1077static inline void 1100static inline void
1078qeth_ipaddr4_to_string(const __u8 *addr, char *buf) 1101qeth_ipaddr4_to_string(const __u8 *addr, char *buf)
1079{ 1102{
@@ -1090,18 +1113,27 @@ qeth_string_to_ipaddr4(const char *buf, __u8 *addr)
1090 int i; 1113 int i;
1091 1114
1092 start = buf; 1115 start = buf;
1093 for (i = 0; i < 3; i++) { 1116 for (i = 0; i < 4; i++) {
1094 if (!(end = strchr(start, '.'))) 1117 if (i == 3) {
1118 end = strchr(start,0xa);
1119 if (end)
1120 len = end - start;
1121 else
1122 len = strlen(start);
1123 }
1124 else {
1125 end = strchr(start, '.');
1126 len = end - start;
1127 }
1128 if ((len <= 0) || (len > 3))
1095 return -EINVAL; 1129 return -EINVAL;
1096 len = end - start;
1097 memset(abuf, 0, 4); 1130 memset(abuf, 0, 4);
1098 strncpy(abuf, start, len); 1131 strncpy(abuf, start, len);
1132 if (!qeth_isdigit(abuf))
1133 return -EINVAL;
1099 addr[i] = simple_strtoul(abuf, &tmp, 10); 1134 addr[i] = simple_strtoul(abuf, &tmp, 10);
1100 start = end + 1; 1135 start = end + 1;
1101 } 1136 }
1102 memset(abuf, 0, 4);
1103 strcpy(abuf, start);
1104 addr[3] = simple_strtoul(abuf, &tmp, 10);
1105 return 0; 1137 return 0;
1106} 1138}
1107 1139
@@ -1128,18 +1160,27 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr)
1128 1160
1129 tmp_addr = (u16 *)addr; 1161 tmp_addr = (u16 *)addr;
1130 start = buf; 1162 start = buf;
1131 for (i = 0; i < 7; i++) { 1163 for (i = 0; i < 8; i++) {
1132 if (!(end = strchr(start, ':'))) 1164 if (i == 7) {
1165 end = strchr(start,0xa);
1166 if (end)
1167 len = end - start;
1168 else
1169 len = strlen(start);
1170 }
1171 else {
1172 end = strchr(start, ':');
1173 len = end - start;
1174 }
1175 if ((len <= 0) || (len > 4))
1133 return -EINVAL; 1176 return -EINVAL;
1134 len = end - start;
1135 memset(abuf, 0, 5); 1177 memset(abuf, 0, 5);
1136 strncpy(abuf, start, len); 1178 strncpy(abuf, start, len);
1179 if (!qeth_isxdigit(abuf))
1180 return -EINVAL;
1137 tmp_addr[i] = simple_strtoul(abuf, &tmp, 16); 1181 tmp_addr[i] = simple_strtoul(abuf, &tmp, 16);
1138 start = end + 1; 1182 start = end + 1;
1139 } 1183 }
1140 memset(abuf, 0, 5);
1141 strcpy(abuf, start);
1142 tmp_addr[7] = simple_strtoul(abuf, &tmp, 16);
1143 return 0; 1184 return 0;
1144} 1185}
1145 1186
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index 011915d5e243..f94f1f25eec6 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -62,7 +62,8 @@ qeth_eddp_free_context(struct qeth_eddp_context *ctx)
62 for (i = 0; i < ctx->num_pages; ++i) 62 for (i = 0; i < ctx->num_pages; ++i)
63 free_page((unsigned long)ctx->pages[i]); 63 free_page((unsigned long)ctx->pages[i]);
64 kfree(ctx->pages); 64 kfree(ctx->pages);
65 kfree(ctx->elements); 65 if (ctx->elements != NULL)
66 kfree(ctx->elements);
66 kfree(ctx); 67 kfree(ctx);
67} 68}
68 69
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 692003c9f896..f8f55cc468ba 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * linux/drivers/s390/net/qeth_main.c ($Revision: 1.224 $) 3 * linux/drivers/s390/net/qeth_main.c ($Revision: 1.251 $)
4 * 4 *
5 * Linux on zSeries OSA Express and HiperSockets support 5 * Linux on zSeries OSA Express and HiperSockets support
6 * 6 *
@@ -9,10 +9,10 @@
9 * Author(s): Original Code written by 9 * Author(s): Original Code written by
10 * Utz Bacher (utz.bacher@de.ibm.com) 10 * Utz Bacher (utz.bacher@de.ibm.com)
11 * Rewritten by 11 * Rewritten by
12 * Frank Pavlic (pavlic@de.ibm.com) and 12 * Frank Pavlic (fpavlic@de.ibm.com) and
13 * Thomas Spatzier <tspat@de.ibm.com> 13 * Thomas Spatzier <tspat@de.ibm.com>
14 * 14 *
15 * $Revision: 1.224 $ $Date: 2005/05/04 20:19:18 $ 15 * $Revision: 1.251 $ $Date: 2005/05/04 20:19:18 $
16 * 16 *
17 * This program is free software; you can redistribute it and/or modify 17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by 18 * it under the terms of the GNU General Public License as published by
@@ -72,7 +72,7 @@
72#include "qeth_eddp.h" 72#include "qeth_eddp.h"
73#include "qeth_tso.h" 73#include "qeth_tso.h"
74 74
75#define VERSION_QETH_C "$Revision: 1.224 $" 75#define VERSION_QETH_C "$Revision: 1.251 $"
76static const char *version = "qeth S/390 OSA-Express driver"; 76static const char *version = "qeth S/390 OSA-Express driver";
77 77
78/** 78/**
@@ -160,6 +160,9 @@ static void
160qeth_set_multicast_list(struct net_device *); 160qeth_set_multicast_list(struct net_device *);
161 161
162static void 162static void
163qeth_setadp_promisc_mode(struct qeth_card *);
164
165static void
163qeth_notify_processes(void) 166qeth_notify_processes(void)
164{ 167{
165 /*notify all registered processes */ 168 /*notify all registered processes */
@@ -515,7 +518,8 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
515 518
516 QETH_DBF_TEXT(setup, 3, "setoffl"); 519 QETH_DBF_TEXT(setup, 3, "setoffl");
517 QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); 520 QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
518 521
522 netif_carrier_off(card->dev);
519 recover_flag = card->state; 523 recover_flag = card->state;
520 if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ 524 if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){
521 PRINT_WARN("Stopping card %s interrupted by user!\n", 525 PRINT_WARN("Stopping card %s interrupted by user!\n",
@@ -602,11 +606,20 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
602 int found = 0; 606 int found = 0;
603 607
604 list_for_each_entry(addr, &card->ip_list, entry) { 608 list_for_each_entry(addr, &card->ip_list, entry) {
609 if (card->options.layer2) {
610 if ((addr->type == todo->type) &&
611 (memcmp(&addr->mac, &todo->mac,
612 OSA_ADDR_LEN) == 0)) {
613 found = 1;
614 break;
615 }
616 continue;
617 }
605 if ((addr->proto == QETH_PROT_IPV4) && 618 if ((addr->proto == QETH_PROT_IPV4) &&
606 (todo->proto == QETH_PROT_IPV4) && 619 (todo->proto == QETH_PROT_IPV4) &&
607 (addr->type == todo->type) && 620 (addr->type == todo->type) &&
608 (addr->u.a4.addr == todo->u.a4.addr) && 621 (addr->u.a4.addr == todo->u.a4.addr) &&
609 (addr->u.a4.mask == todo->u.a4.mask) ){ 622 (addr->u.a4.mask == todo->u.a4.mask)) {
610 found = 1; 623 found = 1;
611 break; 624 break;
612 } 625 }
@@ -615,12 +628,12 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
615 (addr->type == todo->type) && 628 (addr->type == todo->type) &&
616 (addr->u.a6.pfxlen == todo->u.a6.pfxlen) && 629 (addr->u.a6.pfxlen == todo->u.a6.pfxlen) &&
617 (memcmp(&addr->u.a6.addr, &todo->u.a6.addr, 630 (memcmp(&addr->u.a6.addr, &todo->u.a6.addr,
618 sizeof(struct in6_addr)) == 0)) { 631 sizeof(struct in6_addr)) == 0)) {
619 found = 1; 632 found = 1;
620 break; 633 break;
621 } 634 }
622 } 635 }
623 if (found){ 636 if (found) {
624 addr->users += todo->users; 637 addr->users += todo->users;
625 if (addr->users <= 0){ 638 if (addr->users <= 0){
626 *__addr = addr; 639 *__addr = addr;
@@ -632,7 +645,7 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
632 return 0; 645 return 0;
633 } 646 }
634 } 647 }
635 if (todo->users > 0){ 648 if (todo->users > 0) {
636 /* for VIPA and RXIP limit refcount to 1 */ 649 /* for VIPA and RXIP limit refcount to 1 */
637 if (todo->type != QETH_IP_TYPE_NORMAL) 650 if (todo->type != QETH_IP_TYPE_NORMAL)
638 todo->users = 1; 651 todo->users = 1;
@@ -682,12 +695,22 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
682 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) && 695 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
683 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC)) 696 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
684 return 0; 697 return 0;
698 if (card->options.layer2) {
699 if ((tmp->type == addr->type) &&
700 (tmp->is_multicast == addr->is_multicast) &&
701 (memcmp(&tmp->mac, &addr->mac,
702 OSA_ADDR_LEN) == 0)) {
703 found = 1;
704 break;
705 }
706 continue;
707 }
685 if ((tmp->proto == QETH_PROT_IPV4) && 708 if ((tmp->proto == QETH_PROT_IPV4) &&
686 (addr->proto == QETH_PROT_IPV4) && 709 (addr->proto == QETH_PROT_IPV4) &&
687 (tmp->type == addr->type) && 710 (tmp->type == addr->type) &&
688 (tmp->is_multicast == addr->is_multicast) && 711 (tmp->is_multicast == addr->is_multicast) &&
689 (tmp->u.a4.addr == addr->u.a4.addr) && 712 (tmp->u.a4.addr == addr->u.a4.addr) &&
690 (tmp->u.a4.mask == addr->u.a4.mask) ){ 713 (tmp->u.a4.mask == addr->u.a4.mask)) {
691 found = 1; 714 found = 1;
692 break; 715 break;
693 } 716 }
@@ -697,7 +720,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
697 (tmp->is_multicast == addr->is_multicast) && 720 (tmp->is_multicast == addr->is_multicast) &&
698 (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) && 721 (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) &&
699 (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr, 722 (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
700 sizeof(struct in6_addr)) == 0) ){ 723 sizeof(struct in6_addr)) == 0)) {
701 found = 1; 724 found = 1;
702 break; 725 break;
703 } 726 }
@@ -707,7 +730,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
707 tmp->users += addr->users; 730 tmp->users += addr->users;
708 else 731 else
709 tmp->users += add? 1:-1; 732 tmp->users += add? 1:-1;
710 if (tmp->users == 0){ 733 if (tmp->users == 0) {
711 list_del(&tmp->entry); 734 list_del(&tmp->entry);
712 kfree(tmp); 735 kfree(tmp);
713 } 736 }
@@ -738,12 +761,15 @@ qeth_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
738 unsigned long flags; 761 unsigned long flags;
739 int rc = 0; 762 int rc = 0;
740 763
741 QETH_DBF_TEXT(trace,4,"delip"); 764 QETH_DBF_TEXT(trace, 4, "delip");
742 if (addr->proto == QETH_PROT_IPV4) 765
743 QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4); 766 if (card->options.layer2)
767 QETH_DBF_HEX(trace, 4, &addr->mac, 6);
768 else if (addr->proto == QETH_PROT_IPV4)
769 QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
744 else { 770 else {
745 QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8); 771 QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
746 QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8); 772 QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
747 } 773 }
748 spin_lock_irqsave(&card->ip_lock, flags); 774 spin_lock_irqsave(&card->ip_lock, flags);
749 rc = __qeth_insert_ip_todo(card, addr, 0); 775 rc = __qeth_insert_ip_todo(card, addr, 0);
@@ -757,12 +783,14 @@ qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
757 unsigned long flags; 783 unsigned long flags;
758 int rc = 0; 784 int rc = 0;
759 785
760 QETH_DBF_TEXT(trace,4,"addip"); 786 QETH_DBF_TEXT(trace, 4, "addip");
761 if (addr->proto == QETH_PROT_IPV4) 787 if (card->options.layer2)
762 QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4); 788 QETH_DBF_HEX(trace, 4, &addr->mac, 6);
789 else if (addr->proto == QETH_PROT_IPV4)
790 QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
763 else { 791 else {
764 QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8); 792 QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
765 QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8); 793 QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
766 } 794 }
767 spin_lock_irqsave(&card->ip_lock, flags); 795 spin_lock_irqsave(&card->ip_lock, flags);
768 rc = __qeth_insert_ip_todo(card, addr, 1); 796 rc = __qeth_insert_ip_todo(card, addr, 1);
@@ -775,7 +803,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
775{ 803{
776 struct qeth_ipaddr *addr, *tmp; 804 struct qeth_ipaddr *addr, *tmp;
777 int rc; 805 int rc;
778 806again:
779 list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) { 807 list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
780 if (addr->is_multicast) { 808 if (addr->is_multicast) {
781 spin_unlock_irqrestore(&card->ip_lock, *flags); 809 spin_unlock_irqrestore(&card->ip_lock, *flags);
@@ -784,6 +812,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
784 if (!rc) { 812 if (!rc) {
785 list_del(&addr->entry); 813 list_del(&addr->entry);
786 kfree(addr); 814 kfree(addr);
815 goto again;
787 } 816 }
788 } 817 }
789 } 818 }
@@ -851,6 +880,7 @@ qeth_set_ip_addr_list(struct qeth_card *card)
851 880
852static void qeth_delete_mc_addresses(struct qeth_card *); 881static void qeth_delete_mc_addresses(struct qeth_card *);
853static void qeth_add_multicast_ipv4(struct qeth_card *); 882static void qeth_add_multicast_ipv4(struct qeth_card *);
883static void qeth_layer2_add_multicast(struct qeth_card *);
854#ifdef CONFIG_QETH_IPV6 884#ifdef CONFIG_QETH_IPV6
855static void qeth_add_multicast_ipv6(struct qeth_card *); 885static void qeth_add_multicast_ipv6(struct qeth_card *);
856#endif 886#endif
@@ -939,6 +969,24 @@ qeth_register_ip_addresses(void *ptr)
939 return 0; 969 return 0;
940} 970}
941 971
972/*
973 * Drive the SET_PROMISC_MODE thread
974 */
975static int
976qeth_set_promisc_mode(void *ptr)
977{
978 struct qeth_card *card = (struct qeth_card *) ptr;
979
980 daemonize("qeth_setprm");
981 QETH_DBF_TEXT(trace,4,"setprm1");
982 if (!qeth_do_run_thread(card, QETH_SET_PROMISC_MODE_THREAD))
983 return 0;
984 QETH_DBF_TEXT(trace,4,"setprm2");
985 qeth_setadp_promisc_mode(card);
986 qeth_clear_thread_running_bit(card, QETH_SET_PROMISC_MODE_THREAD);
987 return 0;
988}
989
942static int 990static int
943qeth_recover(void *ptr) 991qeth_recover(void *ptr)
944{ 992{
@@ -973,7 +1021,6 @@ void
973qeth_schedule_recovery(struct qeth_card *card) 1021qeth_schedule_recovery(struct qeth_card *card)
974{ 1022{
975 QETH_DBF_TEXT(trace,2,"startrec"); 1023 QETH_DBF_TEXT(trace,2,"startrec");
976
977 if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0) 1024 if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
978 schedule_work(&card->kernel_thread_starter); 1025 schedule_work(&card->kernel_thread_starter);
979} 1026}
@@ -1005,6 +1052,8 @@ qeth_start_kernel_thread(struct qeth_card *card)
1005 1052
1006 if (qeth_do_start_thread(card, QETH_SET_IP_THREAD)) 1053 if (qeth_do_start_thread(card, QETH_SET_IP_THREAD))
1007 kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD); 1054 kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD);
1055 if (qeth_do_start_thread(card, QETH_SET_PROMISC_MODE_THREAD))
1056 kernel_thread(qeth_set_promisc_mode, (void *)card, SIGCHLD);
1008 if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) 1057 if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
1009 kernel_thread(qeth_recover, (void *) card, SIGCHLD); 1058 kernel_thread(qeth_recover, (void *) card, SIGCHLD);
1010} 1059}
@@ -1661,7 +1710,6 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
1661 "IP address reset.\n", 1710 "IP address reset.\n",
1662 QETH_CARD_IFNAME(card), 1711 QETH_CARD_IFNAME(card),
1663 card->info.chpid); 1712 card->info.chpid);
1664 netif_carrier_on(card->dev);
1665 qeth_schedule_recovery(card); 1713 qeth_schedule_recovery(card);
1666 return NULL; 1714 return NULL;
1667 case IPA_CMD_MODCCID: 1715 case IPA_CMD_MODCCID:
@@ -1910,7 +1958,7 @@ qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
1910{ 1958{
1911 u16 s1, s2; 1959 u16 s1, s2;
1912 1960
1913QETH_DBF_TEXT(trace,4,"osndipa"); 1961 QETH_DBF_TEXT(trace,4,"osndipa");
1914 1962
1915 qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2); 1963 qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
1916 s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len); 1964 s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
@@ -2154,24 +2202,21 @@ qeth_ulp_setup(struct qeth_card *card)
2154} 2202}
2155 2203
2156static inline int 2204static inline int
2157qeth_check_for_inbound_error(struct qeth_qdio_buffer *buf, 2205qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
2158 unsigned int qdio_error, 2206 unsigned int siga_error, const char *dbftext)
2159 unsigned int siga_error)
2160{ 2207{
2161 int rc = 0;
2162
2163 if (qdio_error || siga_error) { 2208 if (qdio_error || siga_error) {
2164 QETH_DBF_TEXT(trace, 2, "qdinerr"); 2209 QETH_DBF_TEXT(trace, 2, dbftext);
2165 QETH_DBF_TEXT(qerr, 2, "qdinerr"); 2210 QETH_DBF_TEXT(qerr, 2, dbftext);
2166 QETH_DBF_TEXT_(qerr, 2, " F15=%02X", 2211 QETH_DBF_TEXT_(qerr, 2, " F15=%02X",
2167 buf->buffer->element[15].flags & 0xff); 2212 buf->element[15].flags & 0xff);
2168 QETH_DBF_TEXT_(qerr, 2, " F14=%02X", 2213 QETH_DBF_TEXT_(qerr, 2, " F14=%02X",
2169 buf->buffer->element[14].flags & 0xff); 2214 buf->element[14].flags & 0xff);
2170 QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error); 2215 QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error);
2171 QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error); 2216 QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error);
2172 rc = 1; 2217 return 1;
2173 } 2218 }
2174 return rc; 2219 return 0;
2175} 2220}
2176 2221
2177static inline struct sk_buff * 2222static inline struct sk_buff *
@@ -2720,8 +2765,9 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
2720 for (i = first_element; i < (first_element + count); ++i) { 2765 for (i = first_element; i < (first_element + count); ++i) {
2721 index = i % QDIO_MAX_BUFFERS_PER_Q; 2766 index = i % QDIO_MAX_BUFFERS_PER_Q;
2722 buffer = &card->qdio.in_q->bufs[index]; 2767 buffer = &card->qdio.in_q->bufs[index];
2723 if (!((status == QDIO_STATUS_LOOK_FOR_ERROR) && 2768 if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) &&
2724 qeth_check_for_inbound_error(buffer, qdio_err, siga_err))) 2769 qeth_check_qdio_errors(buffer->buffer,
2770 qdio_err, siga_err,"qinerr")))
2725 qeth_process_inbound_buffer(card, buffer, index); 2771 qeth_process_inbound_buffer(card, buffer, index);
2726 /* clear buffer and give back to hardware */ 2772 /* clear buffer and give back to hardware */
2727 qeth_put_buffer_pool_entry(card, buffer->pool_entry); 2773 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
@@ -2736,12 +2782,13 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
2736static inline int 2782static inline int
2737qeth_handle_send_error(struct qeth_card *card, 2783qeth_handle_send_error(struct qeth_card *card,
2738 struct qeth_qdio_out_buffer *buffer, 2784 struct qeth_qdio_out_buffer *buffer,
2739 int qdio_err, int siga_err) 2785 unsigned int qdio_err, unsigned int siga_err)
2740{ 2786{
2741 int sbalf15 = buffer->buffer->element[15].flags & 0xff; 2787 int sbalf15 = buffer->buffer->element[15].flags & 0xff;
2742 int cc = siga_err & 3; 2788 int cc = siga_err & 3;
2743 2789
2744 QETH_DBF_TEXT(trace, 6, "hdsnderr"); 2790 QETH_DBF_TEXT(trace, 6, "hdsnderr");
2791 qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err, "qouterr");
2745 switch (cc) { 2792 switch (cc) {
2746 case 0: 2793 case 0:
2747 if (qdio_err){ 2794 if (qdio_err){
@@ -2998,7 +3045,8 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
2998 for(i = first_element; i < (first_element + count); ++i){ 3045 for(i = first_element; i < (first_element + count); ++i){
2999 buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; 3046 buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
3000 /*we only handle the KICK_IT error by doing a recovery */ 3047 /*we only handle the KICK_IT error by doing a recovery */
3001 if (qeth_handle_send_error(card, buffer, qdio_error, siga_error) 3048 if (qeth_handle_send_error(card, buffer,
3049 qdio_error, siga_error)
3002 == QETH_SEND_ERROR_KICK_IT){ 3050 == QETH_SEND_ERROR_KICK_IT){
3003 netif_stop_queue(card->dev); 3051 netif_stop_queue(card->dev);
3004 qeth_schedule_recovery(card); 3052 qeth_schedule_recovery(card);
@@ -3240,7 +3288,6 @@ qeth_init_qdio_info(struct qeth_card *card)
3240 card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count; 3288 card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count;
3241 INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list); 3289 INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
3242 INIT_LIST_HEAD(&card->qdio.init_pool.entry_list); 3290 INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
3243 /* outbound */
3244} 3291}
3245 3292
3246static int 3293static int
@@ -3682,6 +3729,9 @@ qeth_verify_vlan_dev(struct net_device *dev, struct qeth_card *card)
3682 break; 3729 break;
3683 } 3730 }
3684 } 3731 }
3732 if (rc && !(VLAN_DEV_INFO(dev)->real_dev->priv == (void *)card))
3733 return 0;
3734
3685#endif 3735#endif
3686 return rc; 3736 return rc;
3687} 3737}
@@ -3749,7 +3799,7 @@ qeth_open(struct net_device *dev)
3749 3799
3750 if ( (card->info.type != QETH_CARD_TYPE_OSN) && 3800 if ( (card->info.type != QETH_CARD_TYPE_OSN) &&
3751 (card->options.layer2) && 3801 (card->options.layer2) &&
3752 (!card->info.layer2_mac_registered)) { 3802 (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) {
3753 QETH_DBF_TEXT(trace,4,"nomacadr"); 3803 QETH_DBF_TEXT(trace,4,"nomacadr");
3754 return -EPERM; 3804 return -EPERM;
3755 } 3805 }
@@ -3758,10 +3808,8 @@ qeth_open(struct net_device *dev)
3758 card->data.state = CH_STATE_UP; 3808 card->data.state = CH_STATE_UP;
3759 card->state = CARD_STATE_UP; 3809 card->state = CARD_STATE_UP;
3760 3810
3761 if (!card->lan_online){ 3811 if (!card->lan_online && netif_carrier_ok(dev))
3762 if (netif_carrier_ok(dev)) 3812 netif_carrier_off(dev);
3763 netif_carrier_off(dev);
3764 }
3765 return 0; 3813 return 0;
3766} 3814}
3767 3815
@@ -4311,6 +4359,8 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
4311out: 4359out:
4312 if (flush_count) 4360 if (flush_count)
4313 qeth_flush_buffers(queue, 0, start_index, flush_count); 4361 qeth_flush_buffers(queue, 0, start_index, flush_count);
4362 else if (!atomic_read(&queue->set_pci_flags_count))
4363 atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
4314 /* 4364 /*
4315 * queue->state will go from LOCKED -> UNLOCKED or from 4365 * queue->state will go from LOCKED -> UNLOCKED or from
4316 * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us 4366 * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us
@@ -4975,6 +5025,10 @@ qeth_default_setassparms_cb(struct qeth_card *, struct qeth_reply *,
4975 unsigned long); 5025 unsigned long);
4976 5026
4977static int 5027static int
5028qeth_default_setadapterparms_cb(struct qeth_card *card,
5029 struct qeth_reply *reply,
5030 unsigned long data);
5031static int
4978qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *, 5032qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *,
4979 __u16, long, 5033 __u16, long,
4980 int (*reply_cb) 5034 int (*reply_cb)
@@ -5301,8 +5355,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid)
5301 struct qeth_ipaddr *addr; 5355 struct qeth_ipaddr *addr;
5302 5356
5303 QETH_DBF_TEXT(trace, 4, "frvaddr4"); 5357 QETH_DBF_TEXT(trace, 4, "frvaddr4");
5304 if (!card->vlangrp) 5358
5305 return;
5306 rcu_read_lock(); 5359 rcu_read_lock();
5307 in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]); 5360 in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]);
5308 if (!in_dev) 5361 if (!in_dev)
@@ -5330,8 +5383,7 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
5330 struct qeth_ipaddr *addr; 5383 struct qeth_ipaddr *addr;
5331 5384
5332 QETH_DBF_TEXT(trace, 4, "frvaddr6"); 5385 QETH_DBF_TEXT(trace, 4, "frvaddr6");
5333 if (!card->vlangrp) 5386
5334 return;
5335 in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]); 5387 in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]);
5336 if (!in6_dev) 5388 if (!in6_dev)
5337 return; 5389 return;
@@ -5351,10 +5403,38 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
5351} 5403}
5352 5404
5353static void 5405static void
5406qeth_free_vlan_addresses(struct qeth_card *card, unsigned short vid)
5407{
5408 if (card->options.layer2 || !card->vlangrp)
5409 return;
5410 qeth_free_vlan_addresses4(card, vid);
5411 qeth_free_vlan_addresses6(card, vid);
5412}
5413
5414static int
5415qeth_layer2_send_setdelvlan_cb(struct qeth_card *card,
5416 struct qeth_reply *reply,
5417 unsigned long data)
5418{
5419 struct qeth_ipa_cmd *cmd;
5420
5421 QETH_DBF_TEXT(trace, 2, "L2sdvcb");
5422 cmd = (struct qeth_ipa_cmd *) data;
5423 if (cmd->hdr.return_code) {
5424 PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
5425 "Continuing\n",cmd->data.setdelvlan.vlan_id,
5426 QETH_CARD_IFNAME(card), cmd->hdr.return_code);
5427 QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command);
5428 QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
5429 QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
5430 }
5431 return 0;
5432}
5433
5434static int
5354qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i, 5435qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
5355 enum qeth_ipa_cmds ipacmd) 5436 enum qeth_ipa_cmds ipacmd)
5356{ 5437{
5357 int rc;
5358 struct qeth_ipa_cmd *cmd; 5438 struct qeth_ipa_cmd *cmd;
5359 struct qeth_cmd_buffer *iob; 5439 struct qeth_cmd_buffer *iob;
5360 5440
@@ -5362,15 +5442,8 @@ qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
5362 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); 5442 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
5363 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 5443 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
5364 cmd->data.setdelvlan.vlan_id = i; 5444 cmd->data.setdelvlan.vlan_id = i;
5365 5445 return qeth_send_ipa_cmd(card, iob,
5366 rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); 5446 qeth_layer2_send_setdelvlan_cb, NULL);
5367 if (rc) {
5368 PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
5369 "Continuing\n",i, QETH_CARD_IFNAME(card), rc);
5370 QETH_DBF_TEXT_(trace, 2, "L2VL%4x", ipacmd);
5371 QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
5372 QETH_DBF_TEXT_(trace, 2, "err%d", rc);
5373 }
5374} 5447}
5375 5448
5376static void 5449static void
@@ -5420,8 +5493,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
5420 qeth_free_vlan_skbs(card, vid); 5493 qeth_free_vlan_skbs(card, vid);
5421 spin_lock_irqsave(&card->vlanlock, flags); 5494 spin_lock_irqsave(&card->vlanlock, flags);
5422 /* unregister IP addresses of vlan device */ 5495 /* unregister IP addresses of vlan device */
5423 qeth_free_vlan_addresses4(card, vid); 5496 qeth_free_vlan_addresses(card, vid);
5424 qeth_free_vlan_addresses6(card, vid);
5425 if (card->vlangrp) 5497 if (card->vlangrp)
5426 card->vlangrp->vlan_devices[vid] = NULL; 5498 card->vlangrp->vlan_devices[vid] = NULL;
5427 spin_unlock_irqrestore(&card->vlanlock, flags); 5499 spin_unlock_irqrestore(&card->vlanlock, flags);
@@ -5430,6 +5502,59 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
5430 qeth_set_multicast_list(card->dev); 5502 qeth_set_multicast_list(card->dev);
5431} 5503}
5432#endif 5504#endif
5505/**
5506 * Examine hardware response to SET_PROMISC_MODE
5507 */
5508static int
5509qeth_setadp_promisc_mode_cb(struct qeth_card *card,
5510 struct qeth_reply *reply,
5511 unsigned long data)
5512{
5513 struct qeth_ipa_cmd *cmd;
5514 struct qeth_ipacmd_setadpparms *setparms;
5515
5516 QETH_DBF_TEXT(trace,4,"prmadpcb");
5517
5518 cmd = (struct qeth_ipa_cmd *) data;
5519 setparms = &(cmd->data.setadapterparms);
5520
5521 qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
5522 if (cmd->hdr.return_code) {
5523 QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);
5524 setparms->data.mode = SET_PROMISC_MODE_OFF;
5525 }
5526 card->info.promisc_mode = setparms->data.mode;
5527 return 0;
5528}
5529/*
5530 * Set promiscuous mode (on or off) (SET_PROMISC_MODE command)
5531 */
5532static void
5533qeth_setadp_promisc_mode(struct qeth_card *card)
5534{
5535 enum qeth_ipa_promisc_modes mode;
5536 struct net_device *dev = card->dev;
5537 struct qeth_cmd_buffer *iob;
5538 struct qeth_ipa_cmd *cmd;
5539
5540 QETH_DBF_TEXT(trace, 4, "setprom");
5541
5542 if (((dev->flags & IFF_PROMISC) &&
5543 (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
5544 (!(dev->flags & IFF_PROMISC) &&
5545 (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
5546 return;
5547 mode = SET_PROMISC_MODE_OFF;
5548 if (dev->flags & IFF_PROMISC)
5549 mode = SET_PROMISC_MODE_ON;
5550 QETH_DBF_TEXT_(trace, 4, "mode:%x", mode);
5551
5552 iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
5553 sizeof(struct qeth_ipacmd_setadpparms));
5554 cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
5555 cmd->data.setadapterparms.data.mode = mode;
5556 qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
5557}
5433 5558
5434/** 5559/**
5435 * set multicast address on card 5560 * set multicast address on card
@@ -5444,12 +5569,22 @@ qeth_set_multicast_list(struct net_device *dev)
5444 5569
5445 QETH_DBF_TEXT(trace,3,"setmulti"); 5570 QETH_DBF_TEXT(trace,3,"setmulti");
5446 qeth_delete_mc_addresses(card); 5571 qeth_delete_mc_addresses(card);
5572 if (card->options.layer2) {
5573 qeth_layer2_add_multicast(card);
5574 goto out;
5575 }
5447 qeth_add_multicast_ipv4(card); 5576 qeth_add_multicast_ipv4(card);
5448#ifdef CONFIG_QETH_IPV6 5577#ifdef CONFIG_QETH_IPV6
5449 qeth_add_multicast_ipv6(card); 5578 qeth_add_multicast_ipv6(card);
5450#endif 5579#endif
5580out:
5451 if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) 5581 if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
5452 schedule_work(&card->kernel_thread_starter); 5582 schedule_work(&card->kernel_thread_starter);
5583 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
5584 return;
5585 if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0)
5586 schedule_work(&card->kernel_thread_starter);
5587
5453} 5588}
5454 5589
5455static int 5590static int
@@ -5657,6 +5792,24 @@ qeth_add_multicast_ipv4(struct qeth_card *card)
5657 in_dev_put(in4_dev); 5792 in_dev_put(in4_dev);
5658} 5793}
5659 5794
5795static void
5796qeth_layer2_add_multicast(struct qeth_card *card)
5797{
5798 struct qeth_ipaddr *ipm;
5799 struct dev_mc_list *dm;
5800
5801 QETH_DBF_TEXT(trace,4,"L2addmc");
5802 for (dm = card->dev->mc_list; dm; dm = dm->next) {
5803 ipm = qeth_get_addr_buffer(QETH_PROT_IPV4);
5804 if (!ipm)
5805 continue;
5806 memcpy(ipm->mac,dm->dmi_addr,MAX_ADDR_LEN);
5807 ipm->is_multicast = 1;
5808 if (!qeth_add_ip(card, ipm))
5809 kfree(ipm);
5810 }
5811}
5812
5660#ifdef CONFIG_QETH_IPV6 5813#ifdef CONFIG_QETH_IPV6
5661static inline void 5814static inline void
5662qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev) 5815qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
@@ -5716,10 +5869,8 @@ qeth_add_multicast_ipv6(struct qeth_card *card)
5716 struct inet6_dev *in6_dev; 5869 struct inet6_dev *in6_dev;
5717 5870
5718 QETH_DBF_TEXT(trace,4,"chkmcv6"); 5871 QETH_DBF_TEXT(trace,4,"chkmcv6");
5719 if ((card->options.layer2 == 0) && 5872 if (!qeth_is_supported(card, IPA_IPV6))
5720 (!qeth_is_supported(card, IPA_IPV6)) )
5721 return ; 5873 return ;
5722
5723 in6_dev = in6_dev_get(card->dev); 5874 in6_dev = in6_dev_get(card->dev);
5724 if (in6_dev == NULL) 5875 if (in6_dev == NULL)
5725 return; 5876 return;
@@ -5825,10 +5976,10 @@ qeth_layer2_send_setmac_cb(struct qeth_card *card,
5825 PRINT_WARN("Error in registering MAC address on " \ 5976 PRINT_WARN("Error in registering MAC address on " \
5826 "device %s: x%x\n", CARD_BUS_ID(card), 5977 "device %s: x%x\n", CARD_BUS_ID(card),
5827 cmd->hdr.return_code); 5978 cmd->hdr.return_code);
5828 card->info.layer2_mac_registered = 0; 5979 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
5829 cmd->hdr.return_code = -EIO; 5980 cmd->hdr.return_code = -EIO;
5830 } else { 5981 } else {
5831 card->info.layer2_mac_registered = 1; 5982 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
5832 memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac, 5983 memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac,
5833 OSA_ADDR_LEN); 5984 OSA_ADDR_LEN);
5834 PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " 5985 PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
@@ -5866,7 +6017,7 @@ qeth_layer2_send_delmac_cb(struct qeth_card *card,
5866 cmd->hdr.return_code = -EIO; 6017 cmd->hdr.return_code = -EIO;
5867 return 0; 6018 return 0;
5868 } 6019 }
5869 card->info.layer2_mac_registered = 0; 6020 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
5870 6021
5871 return 0; 6022 return 0;
5872} 6023}
@@ -5874,7 +6025,7 @@ static int
5874qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac) 6025qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac)
5875{ 6026{
5876 QETH_DBF_TEXT(trace, 2, "L2Delmac"); 6027 QETH_DBF_TEXT(trace, 2, "L2Delmac");
5877 if (!card->info.layer2_mac_registered) 6028 if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
5878 return 0; 6029 return 0;
5879 return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, 6030 return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC,
5880 qeth_layer2_send_delmac_cb); 6031 qeth_layer2_send_delmac_cb);
@@ -5896,7 +6047,7 @@ qeth_layer2_set_mac_address(struct net_device *dev, void *p)
5896 card = (struct qeth_card *) dev->priv; 6047 card = (struct qeth_card *) dev->priv;
5897 6048
5898 if (!card->options.layer2) { 6049 if (!card->options.layer2) {
5899 PRINT_WARN("Setting MAC address on %s is not supported" 6050 PRINT_WARN("Setting MAC address on %s is not supported "
5900 "in Layer 3 mode.\n", dev->name); 6051 "in Layer 3 mode.\n", dev->name);
5901 QETH_DBF_TEXT(trace, 3, "setmcLY3"); 6052 QETH_DBF_TEXT(trace, 3, "setmcLY3");
5902 return -EOPNOTSUPP; 6053 return -EOPNOTSUPP;
@@ -6441,6 +6592,8 @@ qeth_default_setadapterparms_cb(struct qeth_card *card,
6441 return 0; 6592 return 0;
6442} 6593}
6443 6594
6595
6596
6444static int 6597static int
6445qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply, 6598qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply,
6446 unsigned long data) 6599 unsigned long data)
@@ -6481,8 +6634,13 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
6481 QETH_DBF_TEXT(trace,4,"chgmaccb"); 6634 QETH_DBF_TEXT(trace,4,"chgmaccb");
6482 6635
6483 cmd = (struct qeth_ipa_cmd *) data; 6636 cmd = (struct qeth_ipa_cmd *) data;
6484 memcpy(card->dev->dev_addr, 6637 if (!card->options.layer2 || card->info.guestlan ||
6485 &cmd->data.setadapterparms.data.change_addr.addr,OSA_ADDR_LEN); 6638 !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
6639 memcpy(card->dev->dev_addr,
6640 &cmd->data.setadapterparms.data.change_addr.addr,
6641 OSA_ADDR_LEN);
6642 card->info.mac_bits |= QETH_LAYER2_MAC_READ;
6643 }
6486 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); 6644 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
6487 return 0; 6645 return 0;
6488} 6646}
@@ -6602,6 +6760,12 @@ qeth_layer2_initialize(struct qeth_card *card)
6602 QETH_DBF_TEXT(setup, 2, "doL2init"); 6760 QETH_DBF_TEXT(setup, 2, "doL2init");
6603 QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card)); 6761 QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card));
6604 6762
6763 rc = qeth_query_setadapterparms(card);
6764 if (rc) {
6765 PRINT_WARN("could not query adapter parameters on device %s: "
6766 "x%x\n", CARD_BUS_ID(card), rc);
6767 }
6768
6605 rc = qeth_setadpparms_change_macaddr(card); 6769 rc = qeth_setadpparms_change_macaddr(card);
6606 if (rc) { 6770 if (rc) {
6607 PRINT_WARN("couldn't get MAC address on " 6771 PRINT_WARN("couldn't get MAC address on "
@@ -7769,8 +7933,8 @@ __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
7769 QETH_DBF_TEXT_(setup, 2, "6err%d", rc); 7933 QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
7770 goto out_remove; 7934 goto out_remove;
7771 } 7935 }
7772/*maybe it was set offline without ifconfig down 7936 netif_carrier_on(card->dev);
7773 * we can also use this state for recovery purposes*/ 7937
7774 qeth_set_allowed_threads(card, 0xffffffff, 0); 7938 qeth_set_allowed_threads(card, 0xffffffff, 0);
7775 if (recover_flag == CARD_STATE_RECOVER) 7939 if (recover_flag == CARD_STATE_RECOVER)
7776 qeth_start_again(card, recovery_mode); 7940 qeth_start_again(card, recovery_mode);
@@ -8548,7 +8712,7 @@ EXPORT_SYMBOL(qeth_osn_deregister);
8548EXPORT_SYMBOL(qeth_osn_assist); 8712EXPORT_SYMBOL(qeth_osn_assist);
8549module_init(qeth_init); 8713module_init(qeth_init);
8550module_exit(qeth_exit); 8714module_exit(qeth_exit);
8551MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); 8715MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");
8552MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \ 8716MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \
8553 "Copyright 2000,2003 IBM Corporation\n"); 8717 "Copyright 2000,2003 IBM Corporation\n");
8554 8718
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
index 30e053d3cac2..5f8754addc14 100644
--- a/drivers/s390/net/qeth_mpc.c
+++ b/drivers/s390/net/qeth_mpc.c
@@ -4,14 +4,14 @@
4 * Linux on zSeries OSA Express and HiperSockets support 4 * Linux on zSeries OSA Express and HiperSockets support
5 * 5 *
6 * Copyright 2000,2003 IBM Corporation 6 * Copyright 2000,2003 IBM Corporation
7 * Author(s): Frank Pavlic <pavlic@de.ibm.com> 7 * Author(s): Frank Pavlic <fpavlic@de.ibm.com>
8 * Thomas Spatzier <tspat@de.ibm.com> 8 * Thomas Spatzier <tspat@de.ibm.com>
9 * 9 *
10 */ 10 */
11#include <asm/cio.h> 11#include <asm/cio.h>
12#include "qeth_mpc.h" 12#include "qeth_mpc.h"
13 13
14const char *VERSION_QETH_MPC_C = "$Revision: 1.12 $"; 14const char *VERSION_QETH_MPC_C = "$Revision: 1.13 $";
15 15
16unsigned char IDX_ACTIVATE_READ[]={ 16unsigned char IDX_ACTIVATE_READ[]={
17 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00, 17 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
index 7edc5f1fc0d2..864cec5f6c62 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_mpc.h
@@ -6,7 +6,7 @@
6 * Copyright 2000,2003 IBM Corporation 6 * Copyright 2000,2003 IBM Corporation
7 * Author(s): Utz Bacher <utz.bacher@de.ibm.com> 7 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
8 * Thomas Spatzier <tspat@de.ibm.com> 8 * Thomas Spatzier <tspat@de.ibm.com>
9 * Frank Pavlic <pavlic@de.ibm.com> 9 * Frank Pavlic <fpavlic@de.ibm.com>
10 * 10 *
11 */ 11 */
12#ifndef __QETH_MPC_H__ 12#ifndef __QETH_MPC_H__
@@ -14,14 +14,14 @@
14 14
15#include <asm/qeth.h> 15#include <asm/qeth.h>
16 16
17#define VERSION_QETH_MPC_H "$Revision: 1.43 $" 17#define VERSION_QETH_MPC_H "$Revision: 1.46 $"
18 18
19extern const char *VERSION_QETH_MPC_C; 19extern const char *VERSION_QETH_MPC_C;
20 20
21#define IPA_PDU_HEADER_SIZE 0x40 21#define IPA_PDU_HEADER_SIZE 0x40
22#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e) 22#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e)
23#define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26) 23#define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26)
24#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x2a) 24#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x29)
25#define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer+0x3a) 25#define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer+0x3a)
26 26
27extern unsigned char IPA_PDU_HEADER[]; 27extern unsigned char IPA_PDU_HEADER[];
@@ -217,7 +217,7 @@ enum qeth_ipa_setadp_cmd {
217 IPA_SETADP_SEND_OSA_MESSAGE = 0x0100, 217 IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
218 IPA_SETADP_SET_SNMP_CONTROL = 0x0200, 218 IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
219 IPA_SETADP_READ_SNMP_PARMS = 0x0400, 219 IPA_SETADP_READ_SNMP_PARMS = 0x0400,
220 IPA_SETADP_WRITE_SNMP_PARMS = 0x0800, 220 IPA_SETADP_SET_PROMISC_MODE = 0x0800,
221 IPA_SETADP_QUERY_CARD_INFO = 0x1000, 221 IPA_SETADP_QUERY_CARD_INFO = 0x1000,
222}; 222};
223enum qeth_ipa_mac_ops { 223enum qeth_ipa_mac_ops {
@@ -232,9 +232,12 @@ enum qeth_ipa_addr_ops {
232 CHANGE_ADDR_ADD_ADDR = 1, 232 CHANGE_ADDR_ADD_ADDR = 1,
233 CHANGE_ADDR_DEL_ADDR = 2, 233 CHANGE_ADDR_DEL_ADDR = 2,
234 CHANGE_ADDR_FLUSH_ADDR_TABLE = 4, 234 CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
235
236
237}; 235};
236enum qeth_ipa_promisc_modes {
237 SET_PROMISC_MODE_OFF = 0,
238 SET_PROMISC_MODE_ON = 1,
239};
240
238/* (SET)DELIP(M) IPA stuff ***************************************************/ 241/* (SET)DELIP(M) IPA stuff ***************************************************/
239struct qeth_ipacmd_setdelip4 { 242struct qeth_ipacmd_setdelip4 {
240 __u8 ip_addr[4]; 243 __u8 ip_addr[4];
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index f2ccfea8fdb8..7bf35098831e 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.13 $) 3 * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.16 $)
4 * 4 *
5 * Linux on zSeries OSA Express and HiperSockets support 5 * Linux on zSeries OSA Express and HiperSockets support
6 * This file contains code related to procfs. 6 * This file contains code related to procfs.
@@ -21,7 +21,7 @@
21#include "qeth_mpc.h" 21#include "qeth_mpc.h"
22#include "qeth_fs.h" 22#include "qeth_fs.h"
23 23
24const char *VERSION_QETH_PROC_C = "$Revision: 1.13 $"; 24const char *VERSION_QETH_PROC_C = "$Revision: 1.16 $";
25 25
26/***** /proc/qeth *****/ 26/***** /proc/qeth *****/
27#define QETH_PROCFILE_NAME "qeth" 27#define QETH_PROCFILE_NAME "qeth"
@@ -30,30 +30,26 @@ static struct proc_dir_entry *qeth_procfile;
30static int 30static int
31qeth_procfile_seq_match(struct device *dev, void *data) 31qeth_procfile_seq_match(struct device *dev, void *data)
32{ 32{
33 return 1; 33 return(dev ? 1 : 0);
34} 34}
35 35
36static void * 36static void *
37qeth_procfile_seq_start(struct seq_file *s, loff_t *offset) 37qeth_procfile_seq_start(struct seq_file *s, loff_t *offset)
38{ 38{
39 struct device *dev; 39 struct device *dev = NULL;
40 loff_t nr; 40 loff_t nr = 0;
41 41
42 down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); 42 down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
43 43 if (*offset == 0)
44 nr = *offset;
45 if (nr == 0)
46 return SEQ_START_TOKEN; 44 return SEQ_START_TOKEN;
47 45 while (1) {
48 dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL,
49 NULL, qeth_procfile_seq_match);
50
51 /* get card at pos *offset */
52 nr = *offset;
53 while (nr-- > 1 && dev)
54 dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev, 46 dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
55 NULL, qeth_procfile_seq_match); 47 NULL, qeth_procfile_seq_match);
56 return (void *) dev; 48 if (++nr == *offset)
49 break;
50 put_device(dev);
51 }
52 return dev;
57} 53}
58 54
59static void 55static void
@@ -66,19 +62,14 @@ static void *
66qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) 62qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
67{ 63{
68 struct device *prev, *next; 64 struct device *prev, *next;
69 65
70 if (it == SEQ_START_TOKEN) { 66 if (it == SEQ_START_TOKEN)
71 next = driver_find_device(&qeth_ccwgroup_driver.driver, 67 prev = NULL;
72 NULL, NULL, qeth_procfile_seq_match); 68 else
73 if (next) 69 prev = (struct device *) it;
74 (*offset)++;
75 return (void *) next;
76 }
77 prev = (struct device *) it;
78 next = driver_find_device(&qeth_ccwgroup_driver.driver, 70 next = driver_find_device(&qeth_ccwgroup_driver.driver,
79 prev, NULL, qeth_procfile_seq_match); 71 prev, NULL, qeth_procfile_seq_match);
80 if (next) 72 (*offset)++;
81 (*offset)++;
82 return (void *) next; 73 return (void *) next;
83} 74}
84 75
@@ -87,7 +78,7 @@ qeth_get_router_str(struct qeth_card *card, int ipv)
87{ 78{
88 int routing_type = 0; 79 int routing_type = 0;
89 80
90 if (ipv == 4){ 81 if (ipv == 4) {
91 routing_type = card->options.route4.type; 82 routing_type = card->options.route4.type;
92 } else { 83 } else {
93#ifdef CONFIG_QETH_IPV6 84#ifdef CONFIG_QETH_IPV6
@@ -154,6 +145,7 @@ qeth_procfile_seq_show(struct seq_file *s, void *it)
154 card->qdio.in_buf_pool.buf_count); 145 card->qdio.in_buf_pool.buf_count);
155 else 146 else
156 seq_printf(s, " +++ LAN OFFLINE +++\n"); 147 seq_printf(s, " +++ LAN OFFLINE +++\n");
148 put_device(device);
157 } 149 }
158 return 0; 150 return 0;
159} 151}
@@ -184,51 +176,16 @@ static struct file_operations qeth_procfile_fops = {
184static struct proc_dir_entry *qeth_perf_procfile; 176static struct proc_dir_entry *qeth_perf_procfile;
185 177
186#ifdef CONFIG_QETH_PERF_STATS 178#ifdef CONFIG_QETH_PERF_STATS
187
188static void *
189qeth_perf_procfile_seq_start(struct seq_file *s, loff_t *offset)
190{
191 struct device *dev = NULL;
192 int nr;
193
194 down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
195 /* get card at pos *offset */
196 dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
197 qeth_procfile_seq_match);
198
199 /* get card at pos *offset */
200 nr = *offset;
201 while (nr-- > 1 && dev)
202 dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
203 NULL, qeth_procfile_seq_match);
204 return (void *) dev;
205}
206
207static void
208qeth_perf_procfile_seq_stop(struct seq_file *s, void* it)
209{
210 up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
211}
212
213static void *
214qeth_perf_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
215{
216 struct device *prev, *next;
217
218 prev = (struct device *) it;
219 next = driver_find_device(&qeth_ccwgroup_driver.driver, prev,
220 NULL, qeth_procfile_seq_match);
221 if (next)
222 (*offset)++;
223 return (void *) next;
224}
225
226static int 179static int
227qeth_perf_procfile_seq_show(struct seq_file *s, void *it) 180qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
228{ 181{
229 struct device *device; 182 struct device *device;
230 struct qeth_card *card; 183 struct qeth_card *card;
231 184
185
186 if (it == SEQ_START_TOKEN)
187 return 0;
188
232 device = (struct device *) it; 189 device = (struct device *) it;
233 card = device->driver_data; 190 card = device->driver_data;
234 seq_printf(s, "For card with devnos %s/%s/%s (%s):\n", 191 seq_printf(s, "For card with devnos %s/%s/%s (%s):\n",
@@ -295,13 +252,14 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
295 card->perf_stats.outbound_do_qdio_time, 252 card->perf_stats.outbound_do_qdio_time,
296 card->perf_stats.outbound_do_qdio_cnt 253 card->perf_stats.outbound_do_qdio_cnt
297 ); 254 );
255 put_device(device);
298 return 0; 256 return 0;
299} 257}
300 258
301static struct seq_operations qeth_perf_procfile_seq_ops = { 259static struct seq_operations qeth_perf_procfile_seq_ops = {
302 .start = qeth_perf_procfile_seq_start, 260 .start = qeth_procfile_seq_start,
303 .stop = qeth_perf_procfile_seq_stop, 261 .stop = qeth_procfile_seq_stop,
304 .next = qeth_perf_procfile_seq_next, 262 .next = qeth_procfile_seq_next,
305 .show = qeth_perf_procfile_seq_show, 263 .show = qeth_perf_procfile_seq_show,
306}; 264};
307 265
@@ -324,93 +282,6 @@ static struct file_operations qeth_perf_procfile_fops = {
324#define qeth_perf_procfile_created 1 282#define qeth_perf_procfile_created 1
325#endif /* CONFIG_QETH_PERF_STATS */ 283#endif /* CONFIG_QETH_PERF_STATS */
326 284
327/***** /proc/qeth_ipa_takeover *****/
328#define QETH_IPATO_PROCFILE_NAME "qeth_ipa_takeover"
329static struct proc_dir_entry *qeth_ipato_procfile;
330
331static void *
332qeth_ipato_procfile_seq_start(struct seq_file *s, loff_t *offset)
333{
334 struct device *dev;
335 loff_t nr;
336
337 down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
338 /* TODO: finish this */
339 /*
340 * maybe SEQ_SATRT_TOKEN can be returned for offset 0
341 * output driver settings then;
342 * else output setting for respective card
343 */
344
345 dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
346 qeth_procfile_seq_match);
347
348 /* get card at pos *offset */
349 nr = *offset;
350 while (nr-- > 1 && dev)
351 dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
352 NULL, qeth_procfile_seq_match);
353 return (void *) dev;
354}
355
356static void
357qeth_ipato_procfile_seq_stop(struct seq_file *s, void* it)
358{
359 up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
360}
361
362static void *
363qeth_ipato_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
364{
365 struct device *prev, *next;
366
367 prev = (struct device *) it;
368 next = driver_find_device(&qeth_ccwgroup_driver.driver, prev,
369 NULL, qeth_procfile_seq_match);
370 if (next)
371 (*offset)++;
372 return (void *) next;
373}
374
375static int
376qeth_ipato_procfile_seq_show(struct seq_file *s, void *it)
377{
378 struct device *device;
379 struct qeth_card *card;
380
381 /* TODO: finish this */
382 /*
383 * maybe SEQ_SATRT_TOKEN can be returned for offset 0
384 * output driver settings then;
385 * else output setting for respective card
386 */
387 device = (struct device *) it;
388 card = device->driver_data;
389
390 return 0;
391}
392
393static struct seq_operations qeth_ipato_procfile_seq_ops = {
394 .start = qeth_ipato_procfile_seq_start,
395 .stop = qeth_ipato_procfile_seq_stop,
396 .next = qeth_ipato_procfile_seq_next,
397 .show = qeth_ipato_procfile_seq_show,
398};
399
400static int
401qeth_ipato_procfile_open(struct inode *inode, struct file *file)
402{
403 return seq_open(file, &qeth_ipato_procfile_seq_ops);
404}
405
406static struct file_operations qeth_ipato_procfile_fops = {
407 .owner = THIS_MODULE,
408 .open = qeth_ipato_procfile_open,
409 .read = seq_read,
410 .llseek = seq_lseek,
411 .release = seq_release,
412};
413
414int __init 285int __init
415qeth_create_procfs_entries(void) 286qeth_create_procfs_entries(void)
416{ 287{
@@ -426,13 +297,7 @@ qeth_create_procfs_entries(void)
426 qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops; 297 qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops;
427#endif /* CONFIG_QETH_PERF_STATS */ 298#endif /* CONFIG_QETH_PERF_STATS */
428 299
429 qeth_ipato_procfile = create_proc_entry(QETH_IPATO_PROCFILE_NAME,
430 S_IFREG | 0444, NULL);
431 if (qeth_ipato_procfile)
432 qeth_ipato_procfile->proc_fops = &qeth_ipato_procfile_fops;
433
434 if (qeth_procfile && 300 if (qeth_procfile &&
435 qeth_ipato_procfile &&
436 qeth_perf_procfile_created) 301 qeth_perf_procfile_created)
437 return 0; 302 return 0;
438 else 303 else
@@ -446,62 +311,5 @@ qeth_remove_procfs_entries(void)
446 remove_proc_entry(QETH_PROCFILE_NAME, NULL); 311 remove_proc_entry(QETH_PROCFILE_NAME, NULL);
447 if (qeth_perf_procfile) 312 if (qeth_perf_procfile)
448 remove_proc_entry(QETH_PERF_PROCFILE_NAME, NULL); 313 remove_proc_entry(QETH_PERF_PROCFILE_NAME, NULL);
449 if (qeth_ipato_procfile)
450 remove_proc_entry(QETH_IPATO_PROCFILE_NAME, NULL);
451} 314}
452 315
453
454/* ONLY FOR DEVELOPMENT! -> make it as module */
455/*
456static void
457qeth_create_sysfs_entries(void)
458{
459 struct device *dev;
460
461 down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
462
463 list_for_each_entry(dev, &qeth_ccwgroup_driver.driver.devices,
464 driver_list)
465 qeth_create_device_attributes(dev);
466
467 up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
468}
469
470static void
471qeth_remove_sysfs_entries(void)
472{
473 struct device *dev;
474
475 down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
476
477 list_for_each_entry(dev, &qeth_ccwgroup_driver.driver.devices,
478 driver_list)
479 qeth_remove_device_attributes(dev);
480
481 up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
482}
483
484static int __init
485qeth_fs_init(void)
486{
487 printk(KERN_INFO "qeth_fs_init\n");
488 qeth_create_procfs_entries();
489 qeth_create_sysfs_entries();
490
491 return 0;
492}
493
494static void __exit
495qeth_fs_exit(void)
496{
497 printk(KERN_INFO "qeth_fs_exit\n");
498 qeth_remove_procfs_entries();
499 qeth_remove_sysfs_entries();
500}
501
502
503module_init(qeth_fs_init);
504module_exit(qeth_fs_exit);
505
506MODULE_LICENSE("GPL");
507*/
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index f91a02db5743..0ea185f70f75 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.55 $) 3 * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.60 $)
4 * 4 *
5 * Linux on zSeries OSA Express and HiperSockets support 5 * Linux on zSeries OSA Express and HiperSockets support
6 * This file contains code related to sysfs. 6 * This file contains code related to sysfs.
@@ -8,7 +8,7 @@
8 * Copyright 2000,2003 IBM Corporation 8 * Copyright 2000,2003 IBM Corporation
9 * 9 *
10 * Author(s): Thomas Spatzier <tspat@de.ibm.com> 10 * Author(s): Thomas Spatzier <tspat@de.ibm.com>
11 * Frank Pavlic <pavlic@de.ibm.com> 11 * Frank Pavlic <fpavlic@de.ibm.com>
12 * 12 *
13 */ 13 */
14#include <linux/list.h> 14#include <linux/list.h>
@@ -20,7 +20,7 @@
20#include "qeth_mpc.h" 20#include "qeth_mpc.h"
21#include "qeth_fs.h" 21#include "qeth_fs.h"
22 22
23const char *VERSION_QETH_SYS_C = "$Revision: 1.55 $"; 23const char *VERSION_QETH_SYS_C = "$Revision: 1.60 $";
24 24
25/*****************************************************************************/ 25/*****************************************************************************/
26/* */ 26/* */
@@ -160,7 +160,7 @@ qeth_dev_portname_store(struct device *dev, struct device_attribute *attr, const
160 return -EPERM; 160 return -EPERM;
161 161
162 tmp = strsep((char **) &buf, "\n"); 162 tmp = strsep((char **) &buf, "\n");
163 if ((strlen(tmp) > 8) || (strlen(tmp) < 2)) 163 if ((strlen(tmp) > 8) || (strlen(tmp) == 0))
164 return -EINVAL; 164 return -EINVAL;
165 165
166 card->info.portname[0] = strlen(tmp); 166 card->info.portname[0] = strlen(tmp);
@@ -1117,7 +1117,7 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
1117 start = buf; 1117 start = buf;
1118 /* get address string */ 1118 /* get address string */
1119 end = strchr(start, '/'); 1119 end = strchr(start, '/');
1120 if (!end){ 1120 if (!end || (end-start >= 49)){
1121 PRINT_WARN("Invalid format for ipato_addx/delx. " 1121 PRINT_WARN("Invalid format for ipato_addx/delx. "
1122 "Use <ip addr>/<mask bits>\n"); 1122 "Use <ip addr>/<mask bits>\n");
1123 return -EINVAL; 1123 return -EINVAL;
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
index ad33e6f466f1..3c50b6f24f51 100644
--- a/drivers/s390/net/qeth_tso.h
+++ b/drivers/s390/net/qeth_tso.h
@@ -1,13 +1,13 @@
1/* 1/*
2 * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.7 $) 2 * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.8 $)
3 * 3 *
4 * Header file for qeth TCP Segmentation Offload support. 4 * Header file for qeth TCP Segmentation Offload support.
5 * 5 *
6 * Copyright 2004 IBM Corporation 6 * Copyright 2004 IBM Corporation
7 * 7 *
8 * Author(s): Frank Pavlic <pavlic@de.ibm.com> 8 * Author(s): Frank Pavlic <fpavlic@de.ibm.com>
9 * 9 *
10 * $Revision: 1.7 $ $Date: 2005/05/04 20:19:18 $ 10 * $Revision: 1.8 $ $Date: 2005/05/04 20:19:18 $
11 * 11 *
12 */ 12 */
13#ifndef __QETH_TSO_H__ 13#ifndef __QETH_TSO_H__
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index c218b5c944a6..5e84c5aa7779 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -996,6 +996,20 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
996 spin_lock_init(&adapter->fsf_req_list_lock); 996 spin_lock_init(&adapter->fsf_req_list_lock);
997 INIT_LIST_HEAD(&adapter->fsf_req_list_head); 997 INIT_LIST_HEAD(&adapter->fsf_req_list_head);
998 998
999 /* initialize debug locks */
1000
1001 spin_lock_init(&adapter->erp_dbf_lock);
1002 spin_lock_init(&adapter->hba_dbf_lock);
1003 spin_lock_init(&adapter->san_dbf_lock);
1004 spin_lock_init(&adapter->scsi_dbf_lock);
1005
1006 /* initialize error recovery stuff */
1007
1008 rwlock_init(&adapter->erp_lock);
1009 sema_init(&adapter->erp_ready_sem, 0);
1010 INIT_LIST_HEAD(&adapter->erp_ready_head);
1011 INIT_LIST_HEAD(&adapter->erp_running_head);
1012
999 /* initialize abort lock */ 1013 /* initialize abort lock */
1000 rwlock_init(&adapter->abort_lock); 1014 rwlock_init(&adapter->abort_lock);
1001 1015
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 826fb3b00605..95599719f8ab 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -926,7 +926,6 @@ int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
926 char dbf_name[DEBUG_MAX_NAME_LEN]; 926 char dbf_name[DEBUG_MAX_NAME_LEN];
927 927
928 /* debug feature area which records recovery activity */ 928 /* debug feature area which records recovery activity */
929 spin_lock_init(&adapter->erp_dbf_lock);
930 sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter)); 929 sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter));
931 adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2, 930 adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2,
932 sizeof(struct zfcp_erp_dbf_record)); 931 sizeof(struct zfcp_erp_dbf_record));
@@ -936,7 +935,6 @@ int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
936 debug_set_level(adapter->erp_dbf, 3); 935 debug_set_level(adapter->erp_dbf, 3);
937 936
938 /* debug feature area which records HBA (FSF and QDIO) conditions */ 937 /* debug feature area which records HBA (FSF and QDIO) conditions */
939 spin_lock_init(&adapter->hba_dbf_lock);
940 sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter)); 938 sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
941 adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1, 939 adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,
942 sizeof(struct zfcp_hba_dbf_record)); 940 sizeof(struct zfcp_hba_dbf_record));
@@ -947,7 +945,6 @@ int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
947 debug_set_level(adapter->hba_dbf, 3); 945 debug_set_level(adapter->hba_dbf, 3);
948 946
949 /* debug feature area which records SAN command failures and recovery */ 947 /* debug feature area which records SAN command failures and recovery */
950 spin_lock_init(&adapter->san_dbf_lock);
951 sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter)); 948 sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter));
952 adapter->san_dbf = debug_register(dbf_name, dbfsize, 1, 949 adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,
953 sizeof(struct zfcp_san_dbf_record)); 950 sizeof(struct zfcp_san_dbf_record));
@@ -958,7 +955,6 @@ int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
958 debug_set_level(adapter->san_dbf, 6); 955 debug_set_level(adapter->san_dbf, 6);
959 956
960 /* debug feature area which records SCSI command failures and recovery */ 957 /* debug feature area which records SCSI command failures and recovery */
961 spin_lock_init(&adapter->scsi_dbf_lock);
962 sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter)); 958 sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter));
963 adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1, 959 adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,
964 sizeof(struct zfcp_scsi_dbf_record)); 960 sizeof(struct zfcp_scsi_dbf_record));
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 023f4e558ae4..ee7314d8c2da 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -1071,11 +1071,6 @@ zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
1071 1071
1072 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); 1072 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
1073 1073
1074 rwlock_init(&adapter->erp_lock);
1075 INIT_LIST_HEAD(&adapter->erp_ready_head);
1076 INIT_LIST_HEAD(&adapter->erp_running_head);
1077 sema_init(&adapter->erp_ready_sem, 0);
1078
1079 retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); 1074 retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD);
1080 if (retval < 0) { 1075 if (retval < 0) {
1081 ZFCP_LOG_NORMAL("error: creation of erp thread failed for " 1076 ZFCP_LOG_NORMAL("error: creation of erp thread failed for "
@@ -2248,29 +2243,26 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
2248 return retval; 2243 return retval;
2249} 2244}
2250 2245
2251/*
2252 * function: zfcp_fsf_init
2253 *
2254 * purpose: initializes FSF operation for the specified adapter
2255 *
2256 * returns: 0 - succesful initialization of FSF operation
2257 * !0 - failed to initialize FSF operation
2258 */
2259static int 2246static int
2260zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action) 2247zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
2261{ 2248{
2262 int xconfig, xport; 2249 int retval;
2263 2250
2264 if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, 2251 if ((atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
2265 &erp_action->adapter->status)) { 2252 &erp_action->adapter->status)) &&
2253 (erp_action->adapter->adapter_features &
2254 FSF_FEATURE_HBAAPI_MANAGEMENT)) {
2266 zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); 2255 zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
2267 atomic_set(&erp_action->adapter->erp_counter, 0); 2256 atomic_set(&erp_action->adapter->erp_counter, 0);
2268 return ZFCP_ERP_FAILED; 2257 return ZFCP_ERP_FAILED;
2269 } 2258 }
2270 2259
2271 xconfig = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action); 2260 retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
2272 xport = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action); 2261 if (retval == ZFCP_ERP_FAILED)
2273 if ((xconfig == ZFCP_ERP_FAILED) || (xport == ZFCP_ERP_FAILED)) 2262 return ZFCP_ERP_FAILED;
2263
2264 retval = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
2265 if (retval == ZFCP_ERP_FAILED)
2274 return ZFCP_ERP_FAILED; 2266 return ZFCP_ERP_FAILED;
2275 2267
2276 return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action); 2268 return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
@@ -2359,41 +2351,29 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
2359static int 2351static int
2360zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) 2352zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
2361{ 2353{
2362 int retval = ZFCP_ERP_SUCCEEDED; 2354 int ret;
2363 int retries; 2355 int retries;
2364 int sleep; 2356 int sleep;
2365 struct zfcp_adapter *adapter = erp_action->adapter; 2357 struct zfcp_adapter *adapter = erp_action->adapter;
2366 2358
2367 atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); 2359 atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
2368 2360
2369 for (retries = 0; ; retries++) { 2361 retries = 0;
2370 ZFCP_LOG_DEBUG("Doing exchange port data\n"); 2362 do {
2363 write_lock(&adapter->erp_lock);
2371 zfcp_erp_action_to_running(erp_action); 2364 zfcp_erp_action_to_running(erp_action);
2365 write_unlock(&adapter->erp_lock);
2372 zfcp_erp_timeout_init(erp_action); 2366 zfcp_erp_timeout_init(erp_action);
2373 if (zfcp_fsf_exchange_port_data(erp_action, adapter, NULL)) { 2367 ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
2374 retval = ZFCP_ERP_FAILED; 2368 if (ret == -EOPNOTSUPP) {
2375 debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf"); 2369 debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
2376 ZFCP_LOG_INFO("error: initiation of exchange of " 2370 return ZFCP_ERP_SUCCEEDED;
2377 "port data failed for adapter %s\n", 2371 } else if (ret) {
2378 zfcp_get_busid_by_adapter(adapter)); 2372 debug_text_event(adapter->erp_dbf, 3, "a_xport_failed");
2379 break; 2373 return ZFCP_ERP_FAILED;
2380 } 2374 }
2381 debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok"); 2375 debug_text_event(adapter->erp_dbf, 6, "a_xport_ok");
2382 ZFCP_LOG_DEBUG("Xchange underway\n");
2383 2376
2384 /*
2385 * Why this works:
2386 * Both the normal completion handler as well as the timeout
2387 * handler will do an 'up' when the 'exchange port data'
2388 * request completes or times out. Thus, the signal to go on
2389 * won't be lost utilizing this semaphore.
2390 * Furthermore, this 'adapter_reopen' action is
2391 * guaranteed to be the only action being there (highest action
2392 * which prevents other actions from being created).
2393 * Resulting from that, the wake signal recognized here
2394 * _must_ be the one belonging to the 'exchange port
2395 * data' request.
2396 */
2397 down(&adapter->erp_ready_sem); 2377 down(&adapter->erp_ready_sem);
2398 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { 2378 if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
2399 ZFCP_LOG_INFO("error: exchange of port data " 2379 ZFCP_LOG_INFO("error: exchange of port data "
@@ -2401,29 +2381,19 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
2401 zfcp_get_busid_by_adapter(adapter)); 2381 zfcp_get_busid_by_adapter(adapter));
2402 break; 2382 break;
2403 } 2383 }
2404
2405 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, 2384 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
2406 &adapter->status)) 2385 &adapter->status))
2407 break; 2386 break;
2408 2387
2409 ZFCP_LOG_DEBUG("host connection still initialising... " 2388 if (retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES) {
2410 "waiting and retrying...\n"); 2389 sleep = ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP;
2411 /* sleep a little bit before retry */ 2390 retries++;
2412 sleep = retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES ? 2391 } else
2413 ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP : 2392 sleep = ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP;
2414 ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP; 2393 schedule_timeout(sleep);
2415 msleep(jiffies_to_msecs(sleep)); 2394 } while (1);
2416 }
2417
2418 if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
2419 &adapter->status)) {
2420 ZFCP_LOG_INFO("error: exchange of port data for "
2421 "adapter %s failed\n",
2422 zfcp_get_busid_by_adapter(adapter));
2423 retval = ZFCP_ERP_FAILED;
2424 }
2425 2395
2426 return retval; 2396 return ZFCP_ERP_SUCCEEDED;
2427} 2397}
2428 2398
2429/* 2399/*
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 3b0fc1163f5f..59587951c847 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -554,6 +554,17 @@ static void
554zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, 554zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
555 struct fsf_link_down_info *link_down) 555 struct fsf_link_down_info *link_down)
556{ 556{
557 if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
558 &adapter->status))
559 return;
560
561 atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
562
563 if (link_down == NULL) {
564 zfcp_erp_adapter_reopen(adapter, 0);
565 return;
566 }
567
557 switch (link_down->error_code) { 568 switch (link_down->error_code) {
558 case FSF_PSQ_LINK_NO_LIGHT: 569 case FSF_PSQ_LINK_NO_LIGHT:
559 ZFCP_LOG_NORMAL("The local link to adapter %s is down " 570 ZFCP_LOG_NORMAL("The local link to adapter %s is down "
@@ -634,20 +645,15 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
634 link_down->explanation_code, 645 link_down->explanation_code,
635 link_down->vendor_specific_code); 646 link_down->vendor_specific_code);
636 647
637 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, 648 switch (link_down->error_code) {
638 &adapter->status)) { 649 case FSF_PSQ_LINK_NO_LIGHT:
639 atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, 650 case FSF_PSQ_LINK_WRAP_PLUG:
640 &adapter->status); 651 case FSF_PSQ_LINK_NO_FCP:
641 switch (link_down->error_code) { 652 case FSF_PSQ_LINK_FIRMWARE_UPDATE:
642 case FSF_PSQ_LINK_NO_LIGHT: 653 zfcp_erp_adapter_reopen(adapter, 0);
643 case FSF_PSQ_LINK_WRAP_PLUG: 654 break;
644 case FSF_PSQ_LINK_NO_FCP: 655 default:
645 case FSF_PSQ_LINK_FIRMWARE_UPDATE: 656 zfcp_erp_adapter_failed(adapter);
646 zfcp_erp_adapter_reopen(adapter, 0);
647 break;
648 default:
649 zfcp_erp_adapter_failed(adapter);
650 }
651 } 657 }
652} 658}
653 659
@@ -919,30 +925,36 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
919 case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: 925 case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
920 ZFCP_LOG_INFO("Physical link to adapter %s is down\n", 926 ZFCP_LOG_INFO("Physical link to adapter %s is down\n",
921 zfcp_get_busid_by_adapter(adapter)); 927 zfcp_get_busid_by_adapter(adapter));
928 zfcp_fsf_link_down_info_eval(adapter,
929 (struct fsf_link_down_info *)
930 &status_buffer->payload);
922 break; 931 break;
923 case FSF_STATUS_READ_SUB_FDISC_FAILED: 932 case FSF_STATUS_READ_SUB_FDISC_FAILED:
924 ZFCP_LOG_INFO("Local link to adapter %s is down " 933 ZFCP_LOG_INFO("Local link to adapter %s is down "
925 "due to failed FDISC login\n", 934 "due to failed FDISC login\n",
926 zfcp_get_busid_by_adapter(adapter)); 935 zfcp_get_busid_by_adapter(adapter));
936 zfcp_fsf_link_down_info_eval(adapter,
937 (struct fsf_link_down_info *)
938 &status_buffer->payload);
927 break; 939 break;
928 case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE: 940 case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
929 ZFCP_LOG_INFO("Local link to adapter %s is down " 941 ZFCP_LOG_INFO("Local link to adapter %s is down "
930 "due to firmware update on adapter\n", 942 "due to firmware update on adapter\n",
931 zfcp_get_busid_by_adapter(adapter)); 943 zfcp_get_busid_by_adapter(adapter));
944 zfcp_fsf_link_down_info_eval(adapter, NULL);
932 break; 945 break;
933 default: 946 default:
934 ZFCP_LOG_INFO("Local link to adapter %s is down " 947 ZFCP_LOG_INFO("Local link to adapter %s is down "
935 "due to unknown reason\n", 948 "due to unknown reason\n",
936 zfcp_get_busid_by_adapter(adapter)); 949 zfcp_get_busid_by_adapter(adapter));
950 zfcp_fsf_link_down_info_eval(adapter, NULL);
937 }; 951 };
938 zfcp_fsf_link_down_info_eval(adapter,
939 (struct fsf_link_down_info *) &status_buffer->payload);
940 break; 952 break;
941 953
942 case FSF_STATUS_READ_LINK_UP: 954 case FSF_STATUS_READ_LINK_UP:
943 ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. " 955 ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. "
944 "Restarting operations on this adapter\n", 956 "Restarting operations on this adapter\n",
945 zfcp_get_busid_by_adapter(adapter)); 957 zfcp_get_busid_by_adapter(adapter));
946 /* All ports should be marked as ready to run again */ 958 /* All ports should be marked as ready to run again */
947 zfcp_erp_modify_adapter_status(adapter, 959 zfcp_erp_modify_adapter_status(adapter,
948 ZFCP_STATUS_COMMON_RUNNING, 960 ZFCP_STATUS_COMMON_RUNNING,
@@ -2191,13 +2203,10 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
2191 return -EOPNOTSUPP; 2203 return -EOPNOTSUPP;
2192 } 2204 }
2193 2205
2194 timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
2195 if (!timer)
2196 return -ENOMEM;
2197
2198 /* setup new FSF request */ 2206 /* setup new FSF request */
2199 retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 2207 retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
2200 0, 0, &lock_flags, &fsf_req); 2208 erp_action ? ZFCP_REQ_AUTO_CLEANUP : 0,
2209 0, &lock_flags, &fsf_req);
2201 if (retval < 0) { 2210 if (retval < 0) {
2202 ZFCP_LOG_INFO("error: Out of resources. Could not create an " 2211 ZFCP_LOG_INFO("error: Out of resources. Could not create an "
2203 "exchange port data request for" 2212 "exchange port data request for"
@@ -2205,25 +2214,33 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
2205 zfcp_get_busid_by_adapter(adapter)); 2214 zfcp_get_busid_by_adapter(adapter));
2206 write_unlock_irqrestore(&adapter->request_queue.queue_lock, 2215 write_unlock_irqrestore(&adapter->request_queue.queue_lock,
2207 lock_flags); 2216 lock_flags);
2208 goto out; 2217 return retval;
2209 }
2210
2211 if (erp_action) {
2212 erp_action->fsf_req = fsf_req;
2213 fsf_req->erp_action = erp_action;
2214 } 2218 }
2215 2219
2216 if (data) 2220 if (data)
2217 fsf_req->data = (unsigned long) data; 2221 fsf_req->data = (unsigned long) data;
2218 2222
2219 sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); 2223 sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
2220 sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; 2224 sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
2221 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; 2225 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
2222 2226
2223 init_timer(timer); 2227 if (erp_action) {
2224 timer->function = zfcp_fsf_request_timeout_handler; 2228 erp_action->fsf_req = fsf_req;
2225 timer->data = (unsigned long) adapter; 2229 fsf_req->erp_action = erp_action;
2226 timer->expires = ZFCP_FSF_REQUEST_TIMEOUT; 2230 timer = &erp_action->timer;
2231 } else {
2232 timer = kmalloc(sizeof(struct timer_list), GFP_ATOMIC);
2233 if (!timer) {
2234 write_unlock_irqrestore(&adapter->request_queue.queue_lock,
2235 lock_flags);
2236 zfcp_fsf_req_free(fsf_req);
2237 return -ENOMEM;
2238 }
2239 init_timer(timer);
2240 timer->function = zfcp_fsf_request_timeout_handler;
2241 timer->data = (unsigned long) adapter;
2242 timer->expires = ZFCP_FSF_REQUEST_TIMEOUT;
2243 }
2227 2244
2228 retval = zfcp_fsf_req_send(fsf_req, timer); 2245 retval = zfcp_fsf_req_send(fsf_req, timer);
2229 if (retval) { 2246 if (retval) {
@@ -2233,23 +2250,22 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
2233 zfcp_fsf_req_free(fsf_req); 2250 zfcp_fsf_req_free(fsf_req);
2234 if (erp_action) 2251 if (erp_action)
2235 erp_action->fsf_req = NULL; 2252 erp_action->fsf_req = NULL;
2253 else
2254 kfree(timer);
2236 write_unlock_irqrestore(&adapter->request_queue.queue_lock, 2255 write_unlock_irqrestore(&adapter->request_queue.queue_lock,
2237 lock_flags); 2256 lock_flags);
2238 goto out; 2257 return retval;
2239 } 2258 }
2240 2259
2241 ZFCP_LOG_DEBUG("Exchange Port Data request initiated (adapter %s)\n", 2260 write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
2242 zfcp_get_busid_by_adapter(adapter));
2243
2244 write_unlock_irqrestore(&adapter->request_queue.queue_lock,
2245 lock_flags);
2246 2261
2247 wait_event(fsf_req->completion_wq, 2262 if (!erp_action) {
2248 fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); 2263 wait_event(fsf_req->completion_wq,
2249 del_timer_sync(timer); 2264 fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
2250 zfcp_fsf_req_free(fsf_req); 2265 del_timer_sync(timer);
2251 out: 2266 zfcp_fsf_req_free(fsf_req);
2252 kfree(timer); 2267 kfree(timer);
2268 }
2253 return retval; 2269 return retval;
2254} 2270}
2255 2271
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 3dcd1bfba3b4..66608d13a634 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -179,7 +179,7 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp)
179 struct zfcp_adapter *adapter; 179 struct zfcp_adapter *adapter;
180 struct zfcp_unit *unit; 180 struct zfcp_unit *unit;
181 unsigned long flags; 181 unsigned long flags;
182 int retval = -ENODEV; 182 int retval = -ENXIO;
183 183
184 adapter = (struct zfcp_adapter *) sdp->host->hostdata[0]; 184 adapter = (struct zfcp_adapter *) sdp->host->hostdata[0];
185 if (!adapter) 185 if (!adapter)