Commit 7747d41e authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] s390: network driver

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

Network driver changes:
 - lcs: Add missing irb error checking.
 - lcs: Fix multicasting.
 - lcs: Use a seperate lock (ipm_lock) for multicast list.
 - lcs: Add missing in_dev_put in multicase address list handling.
 - iucv: Set static variables to NULL after kfree.
 - iucv: Do bus_unregister if module initialization fails.
 - netiucv: Convert iucvMagic to EBCDIC in con_action_start.
 - netiucv: Remove administration of ifno-stuff for device name,
 - netiucv: Add attribute to remove a netiucv device.
 - qeth: Add version string that is displayed at driver load time.
 - qeth: Fix memory leak in qeth_arp_query.
 - qeth: Remove duplicate case statements in qeth_do_ioctl.
 - qeth: Fix OSA broadcast filtering.
 - qeth: Increase timeout for purge ARP cache IPA.
 - qeth: Fix hsi device naming.
 - qeth: Add do_QDIO count to qeth performance statistics.
 - qeth: Allow writing to IP address takeover attribute only in
         state DOWN or RECOVER.
 - qeth: Fix hang when removing a vlan device.
 - qeth: Cleanup error messages for ARP commands.
 - qeth: Return EOPNOTSUPP for purge ARP on HiperSockets.
 - qeth: Drop skbs if the net_device of a qeth device is down.
 - qeth: Simplify ip address list processing.
parent a7a53392
/* /*
* $Id: iucv.c,v 1.28 2004/04/15 06:34:58 braunu Exp $ * $Id: iucv.c,v 1.30 2004/05/13 09:21:23 braunu Exp $
* *
* IUCV network driver * IUCV network driver
* *
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* RELEASE-TAG: IUCV lowlevel driver $Revision: 1.28 $ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.30 $
* *
*/ */
...@@ -98,7 +98,7 @@ typedef struct { ...@@ -98,7 +98,7 @@ typedef struct {
__u8 res3[24]; __u8 res3[24];
} iucv_GeneralInterrupt; } iucv_GeneralInterrupt;
static iucv_GeneralInterrupt *iucv_external_int_buffer; static iucv_GeneralInterrupt *iucv_external_int_buffer = NULL;
/* Spin Lock declaration */ /* Spin Lock declaration */
...@@ -351,7 +351,7 @@ do { \ ...@@ -351,7 +351,7 @@ do { \
static void static void
iucv_banner(void) iucv_banner(void)
{ {
char vbuf[] = "$Revision: 1.28 $"; char vbuf[] = "$Revision: 1.30 $";
char *version = vbuf; char *version = vbuf;
if ((version = strchr(version, ':'))) { if ((version = strchr(version, ':'))) {
...@@ -403,6 +403,7 @@ iucv_init(void) ...@@ -403,6 +403,7 @@ iucv_init(void)
"%s: Could not allocate external interrupt buffer\n", "%s: Could not allocate external interrupt buffer\n",
__FUNCTION__); __FUNCTION__);
s390_root_dev_unregister(iucv_root); s390_root_dev_unregister(iucv_root);
bus_unregister(&iucv_bus);
return -ENOMEM; return -ENOMEM;
} }
memset(iucv_external_int_buffer, 0, sizeof(iucv_GeneralInterrupt)); memset(iucv_external_int_buffer, 0, sizeof(iucv_GeneralInterrupt));
...@@ -416,6 +417,7 @@ iucv_init(void) ...@@ -416,6 +417,7 @@ iucv_init(void)
kfree(iucv_external_int_buffer); kfree(iucv_external_int_buffer);
iucv_external_int_buffer = NULL; iucv_external_int_buffer = NULL;
s390_root_dev_unregister(iucv_root); s390_root_dev_unregister(iucv_root);
bus_unregister(&iucv_bus);
return -ENOMEM; return -ENOMEM;
} }
memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE); memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE);
...@@ -441,10 +443,14 @@ static void ...@@ -441,10 +443,14 @@ static void
iucv_exit(void) iucv_exit(void)
{ {
iucv_retrieve_buffer(); iucv_retrieve_buffer();
if (iucv_external_int_buffer) if (iucv_external_int_buffer) {
kfree(iucv_external_int_buffer); kfree(iucv_external_int_buffer);
if (iucv_param_pool) iucv_external_int_buffer = NULL;
}
if (iucv_param_pool) {
kfree(iucv_param_pool); kfree(iucv_param_pool);
iucv_param_pool = NULL;
}
s390_root_dev_unregister(iucv_root); s390_root_dev_unregister(iucv_root);
bus_unregister(&iucv_bus); bus_unregister(&iucv_bus);
printk(KERN_INFO "IUCV lowlevel driver unloaded\n"); printk(KERN_INFO "IUCV lowlevel driver unloaded\n");
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Frank Pavlic (pavlic@de.ibm.com) and * Frank Pavlic (pavlic@de.ibm.com) and
* Martin Schwidefsky <schwidefsky@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com>
* *
* $Revision: 1.74 $ $Date: 2004/04/05 00:01:04 $ * $Revision: 1.80 $ $Date: 2004/05/13 08:22:06 $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
/** /**
* initialization string for output * initialization string for output
*/ */
#define VERSION_LCS_C "$Revision: 1.74 $" #define VERSION_LCS_C "$Revision: 1.80 $"
static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
static char debug_buffer[255]; static char debug_buffer[255];
...@@ -99,9 +99,9 @@ lcs_register_debug_facility(void) ...@@ -99,9 +99,9 @@ lcs_register_debug_facility(void)
return -ENOMEM; return -ENOMEM;
} }
debug_register_view(lcs_dbf_setup, &debug_hex_ascii_view); debug_register_view(lcs_dbf_setup, &debug_hex_ascii_view);
debug_set_level(lcs_dbf_setup, 5); debug_set_level(lcs_dbf_setup, 2);
debug_register_view(lcs_dbf_trace, &debug_hex_ascii_view); debug_register_view(lcs_dbf_trace, &debug_hex_ascii_view);
debug_set_level(lcs_dbf_trace, 5); debug_set_level(lcs_dbf_trace, 2);
return 0; return 0;
} }
...@@ -338,6 +338,7 @@ lcs_setup_card(struct lcs_card *card) ...@@ -338,6 +338,7 @@ lcs_setup_card(struct lcs_card *card)
(void *)lcs_start_kernel_thread,card); (void *)lcs_start_kernel_thread,card);
card->thread_mask = 0; card->thread_mask = 0;
spin_lock_init(&card->lock); spin_lock_init(&card->lock);
spin_lock_init(&card->ipm_lock);
#ifdef CONFIG_IP_MULTICAST #ifdef CONFIG_IP_MULTICAST
INIT_LIST_HEAD(&card->ipm_list); INIT_LIST_HEAD(&card->ipm_list);
#endif #endif
...@@ -935,18 +936,14 @@ lcs_check_multicast_support(struct lcs_card *card) ...@@ -935,18 +936,14 @@ lcs_check_multicast_support(struct lcs_card *card)
/** /**
* set or del multicast address on LCS card * set or del multicast address on LCS card
*/ */
static int static void
lcs_fix_multicast_list(void *data) lcs_fix_multicast_list(struct lcs_card *card)
{ {
struct list_head *l, *n; struct list_head *l, *n;
struct lcs_ipm_list *ipm; struct lcs_ipm_list *ipm;
struct lcs_card *card;
card = (struct lcs_card *) data;
daemonize("fixipm");
LCS_DBF_TEXT(4,trace, "fixipm"); LCS_DBF_TEXT(4,trace, "fixipm");
spin_lock(&card->lock); spin_lock(&card->ipm_lock);
list_for_each_safe(l, n, &card->ipm_list) { list_for_each_safe(l, n, &card->ipm_list) {
ipm = list_entry(l, struct lcs_ipm_list, list); ipm = list_entry(l, struct lcs_ipm_list, list);
switch (ipm->ipm_state) { switch (ipm->ipm_state) {
...@@ -968,8 +965,7 @@ lcs_fix_multicast_list(void *data) ...@@ -968,8 +965,7 @@ lcs_fix_multicast_list(void *data)
} }
if (card->state == DEV_STATE_UP) if (card->state == DEV_STATE_UP)
netif_wake_queue(card->dev); netif_wake_queue(card->dev);
spin_unlock(&card->lock); spin_unlock(&card->ipm_lock);
return 0;
} }
/** /**
...@@ -988,28 +984,30 @@ lcs_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev) ...@@ -988,28 +984,30 @@ lcs_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev)
/** /**
* function called by net device to handle multicast address relevant things * function called by net device to handle multicast address relevant things
*/ */
static void static int
lcs_set_multicast_list(struct net_device *dev) lcs_register_mc_addresses(void *data)
{ {
struct lcs_card *card;
char buf[MAX_ADDR_LEN]; char buf[MAX_ADDR_LEN];
struct list_head *l; struct list_head *l;
struct ip_mc_list *im4; struct ip_mc_list *im4;
struct in_device *in4_dev; struct in_device *in4_dev;
struct lcs_ipm_list *ipm, *tmp; struct lcs_ipm_list *ipm, *tmp;
struct lcs_card *card;
LCS_DBF_TEXT(4, trace, "setmulti"); daemonize("regipm");
in4_dev = in_dev_get(dev); LCS_DBF_TEXT(4, trace, "regmulti");
card = (struct lcs_card *) data;
in4_dev = in_dev_get(card->dev);
if (in4_dev == NULL) if (in4_dev == NULL)
return; return 0;
read_lock(&in4_dev->lock); read_lock(&in4_dev->lock);
card = (struct lcs_card *) dev->priv; spin_lock(&card->ipm_lock);
spin_lock(&card->lock);
/* Check for multicast addresses to be removed. */ /* Check for multicast addresses to be removed. */
list_for_each(l, &card->ipm_list) { list_for_each(l, &card->ipm_list) {
ipm = list_entry(l, struct lcs_ipm_list, list); ipm = list_entry(l, struct lcs_ipm_list, list);
for (im4 = in4_dev->mc_list; im4 != NULL; im4 = im4->next) { for (im4 = in4_dev->mc_list; im4 != NULL; im4 = im4->next) {
lcs_get_mac_for_ipm(im4->multiaddr, buf, dev); lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev);
if (memcmp(buf, &ipm->ipm.mac_addr, if (memcmp(buf, &ipm->ipm.mac_addr,
LCS_MAC_LENGTH) == 0 && LCS_MAC_LENGTH) == 0 &&
ipm->ipm.ip_addr == im4->multiaddr) ipm->ipm.ip_addr == im4->multiaddr)
...@@ -1020,7 +1018,7 @@ lcs_set_multicast_list(struct net_device *dev) ...@@ -1020,7 +1018,7 @@ lcs_set_multicast_list(struct net_device *dev)
} }
/* Check for multicast addresses to be added. */ /* Check for multicast addresses to be added. */
for (im4 = in4_dev->mc_list; im4; im4 = im4->next) { for (im4 = in4_dev->mc_list; im4; im4 = im4->next) {
lcs_get_mac_for_ipm(im4->multiaddr, buf, dev); lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev);
ipm = NULL; ipm = NULL;
list_for_each(l, &card->ipm_list) { list_for_each(l, &card->ipm_list) {
tmp = list_entry(l, struct lcs_ipm_list, list); tmp = list_entry(l, struct lcs_ipm_list, list);
...@@ -1046,14 +1044,56 @@ lcs_set_multicast_list(struct net_device *dev) ...@@ -1046,14 +1044,56 @@ lcs_set_multicast_list(struct net_device *dev)
ipm->ipm_state = LCS_IPM_STATE_SET_REQUIRED; ipm->ipm_state = LCS_IPM_STATE_SET_REQUIRED;
list_add(&ipm->list, &card->ipm_list); list_add(&ipm->list, &card->ipm_list);
} }
spin_unlock(&card->lock); spin_unlock(&card->ipm_lock);
read_unlock(&in4_dev->lock); read_unlock(&in4_dev->lock);
lcs_fix_multicast_list(card);
in_dev_put(in4_dev);
return 0;
}
/**
* function called by net device to
* handle multicast address relevant things
*/
static void
lcs_set_multicast_list(struct net_device *dev)
{
struct lcs_card *card;
LCS_DBF_TEXT(4, trace, "setmulti");
card = (struct lcs_card *) dev->priv;
set_bit(3, &card->thread_mask); set_bit(3, &card->thread_mask);
schedule_work(&card->kernel_thread_starter); schedule_work(&card->kernel_thread_starter);
} }
#endif /* CONFIG_IP_MULTICAST */ #endif /* CONFIG_IP_MULTICAST */
static long
lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb)
{
if (!IS_ERR(irb))
return 0;
switch (PTR_ERR(irb)) {
case -EIO:
PRINT_WARN("i/o-error on device %s\n", cdev->dev.bus_id);
LCS_DBF_TEXT(2, trace, "ckirberr");
LCS_DBF_TEXT_(2, trace, " rc%d", -EIO);
break;
case -ETIMEDOUT:
PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id);
LCS_DBF_TEXT(2, trace, "ckirberr");
LCS_DBF_TEXT_(2, trace, " rc%d", -ETIMEDOUT);
break;
default:
PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb),
cdev->dev.bus_id);
LCS_DBF_TEXT(2, trace, "ckirberr");
LCS_DBF_TEXT(2, trace, " rc???");
}
return PTR_ERR(irb);
}
/** /**
* IRQ Handler for LCS channels * IRQ Handler for LCS channels
*/ */
...@@ -1064,6 +1104,9 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) ...@@ -1064,6 +1104,9 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
struct lcs_channel *channel; struct lcs_channel *channel;
int index; int index;
if (lcs_check_irb_error(cdev, irb))
return;
card = CARD_FROM_DEV(cdev); card = CARD_FROM_DEV(cdev);
if (card->read.ccwdev == cdev) if (card->read.ccwdev == cdev)
channel = &card->read; channel = &card->read;
...@@ -1513,7 +1556,7 @@ lcs_start_kernel_thread(struct lcs_card *card) ...@@ -1513,7 +1556,7 @@ lcs_start_kernel_thread(struct lcs_card *card)
kernel_thread(lcs_lgw_stoplan_thread, (void *) card, SIGCHLD); kernel_thread(lcs_lgw_stoplan_thread, (void *) card, SIGCHLD);
#ifdef CONFIG_IP_MULTICAST #ifdef CONFIG_IP_MULTICAST
if (test_and_clear_bit(3, &card->thread_mask)) if (test_and_clear_bit(3, &card->thread_mask))
kernel_thread(lcs_fix_multicast_list, (void *) card, SIGCHLD); kernel_thread(lcs_register_mc_addresses, (void *) card, SIGCHLD);
#endif #endif
} }
...@@ -1903,7 +1946,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) ...@@ -1903,7 +1946,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
goto out; goto out;
memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH); memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH);
#ifdef CONFIG_IP_MULTICAST #ifdef CONFIG_IP_MULTICAST
if (lcs_check_multicast_support(card)) if (!lcs_check_multicast_support(card))
card->dev->set_multicast_list = lcs_set_multicast_list; card->dev->set_multicast_list = lcs_set_multicast_list;
#endif #endif
netif_stop_queue(card->dev); netif_stop_queue(card->dev);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <asm/ccwdev.h> #include <asm/ccwdev.h>
#define VERSION_LCS_H "$Revision: 1.15 $" #define VERSION_LCS_H "$Revision: 1.16 $"
#define LCS_DBF_TEXT(level, name, text) \ #define LCS_DBF_TEXT(level, name, text) \
do { \ do { \
...@@ -273,6 +273,7 @@ struct lcs_channel { ...@@ -273,6 +273,7 @@ struct lcs_channel {
*/ */
struct lcs_card { struct lcs_card {
spinlock_t lock; spinlock_t lock;
spinlock_t ipm_lock;
enum lcs_dev_states state; enum lcs_dev_states state;
struct net_device *dev; struct net_device *dev;
struct net_device_stats stats; struct net_device_stats stats;
......
/* /*
* $Id: netiucv.c,v 1.51 2004/04/23 08:11:21 mschwide Exp $ * $Id: netiucv.c,v 1.53 2004/05/07 14:29:37 mschwide Exp $
* *
* IUCV network driver * IUCV network driver
* *
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* RELEASE-TAG: IUCV network driver $Revision: 1.51 $ * RELEASE-TAG: IUCV network driver $Revision: 1.53 $
* *
*/ */
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/ebcdic.h>
#include "iucv.h" #include "iucv.h"
#include "fsm.h" #include "fsm.h"
...@@ -113,9 +114,6 @@ struct iucv_connection { ...@@ -113,9 +114,6 @@ struct iucv_connection {
*/ */
static struct iucv_connection *connections; static struct iucv_connection *connections;
/* Keep track of interfaces. */
static int ifno;
/** /**
* Representation of event-data for the * Representation of event-data for the
* connection state machine. * connection state machine.
...@@ -549,7 +547,7 @@ conn_action_rx(fsm_instance *fi, int event, void *arg) ...@@ -549,7 +547,7 @@ conn_action_rx(fsm_instance *fi, int event, void *arg)
iucv_MessagePending *eib = (iucv_MessagePending *)ev->data; iucv_MessagePending *eib = (iucv_MessagePending *)ev->data;
struct netiucv_priv *privptr = (struct netiucv_priv *)conn->netdev->priv; struct netiucv_priv *privptr = (struct netiucv_priv *)conn->netdev->priv;
__u16 msglen = eib->ln1msg2.ipbfln1f; __u32 msglen = eib->ln1msg2.ipbfln1f;
int rc; int rc;
pr_debug("%s() called\n", __FUNCTION__); pr_debug("%s() called\n", __FUNCTION__);
...@@ -571,6 +569,7 @@ conn_action_rx(fsm_instance *fi, int event, void *arg) ...@@ -571,6 +569,7 @@ conn_action_rx(fsm_instance *fi, int event, void *arg)
conn->rx_buff->data, msglen, NULL, NULL, NULL); conn->rx_buff->data, msglen, NULL, NULL, NULL);
if (rc != 0 || msglen < 5) { if (rc != 0 || msglen < 5) {
privptr->stats.rx_errors++; privptr->stats.rx_errors++;
printk(KERN_INFO "iucv_receive returned %08x\n", rc);
return; return;
} }
netiucv_unpack_skb(conn, conn->rx_buff); netiucv_unpack_skb(conn, conn->rx_buff);
...@@ -647,7 +646,7 @@ conn_action_txdone(fsm_instance *fi, int event, void *arg) ...@@ -647,7 +646,7 @@ conn_action_txdone(fsm_instance *fi, int event, void *arg)
fsm_newstate(fi, CONN_STATE_IDLE); fsm_newstate(fi, CONN_STATE_IDLE);
if (privptr) if (privptr)
privptr->stats.tx_errors += txpackets; privptr->stats.tx_errors += txpackets;
printk(KERN_DEBUG "iucv_send returned %08x\n", printk(KERN_INFO "iucv_send returned %08x\n",
rc); rc);
} else { } else {
if (privptr) { if (privptr) {
...@@ -770,7 +769,7 @@ conn_action_start(fsm_instance *fi, int event, void *arg) ...@@ -770,7 +769,7 @@ conn_action_start(fsm_instance *fi, int event, void *arg)
struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_event *ev = (struct iucv_event *)arg;
struct iucv_connection *conn = ev->conn; struct iucv_connection *conn = ev->conn;
__u16 msglimit; __u16 msglimit;
int rc; int rc, len;
__u8 iucvMagic[16] = { __u8 iucvMagic[16] = {
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
...@@ -778,7 +777,10 @@ conn_action_start(fsm_instance *fi, int event, void *arg) ...@@ -778,7 +777,10 @@ conn_action_start(fsm_instance *fi, int event, void *arg)
pr_debug("%s() called\n", __FUNCTION__); pr_debug("%s() called\n", __FUNCTION__);
memcpy(iucvMagic, conn->netdev->name, IFNAMSIZ); len = (IFNAMSIZ < sizeof(conn->netdev->name)) ?
IFNAMSIZ : sizeof(conn->netdev->name);
memcpy(iucvMagic, conn->netdev->name, len);
ASCEBC (iucvMagic, len);
if (conn->handle == 0) { if (conn->handle == 0) {
conn->handle = conn->handle =
iucv_register_program(iucvMagic, conn->userid, mask, iucv_register_program(iucvMagic, conn->userid, mask,
...@@ -992,6 +994,7 @@ static void ...@@ -992,6 +994,7 @@ static void
dev_action_connup(fsm_instance *fi, int event, void *arg) dev_action_connup(fsm_instance *fi, int event, void *arg)
{ {
struct net_device *dev = (struct net_device *)arg; struct net_device *dev = (struct net_device *)arg;
struct netiucv_priv *privptr = dev->priv;
pr_debug("%s() called\n", __FUNCTION__); pr_debug("%s() called\n", __FUNCTION__);
...@@ -999,8 +1002,8 @@ dev_action_connup(fsm_instance *fi, int event, void *arg) ...@@ -999,8 +1002,8 @@ dev_action_connup(fsm_instance *fi, int event, void *arg)
case DEV_STATE_STARTWAIT: case DEV_STATE_STARTWAIT:
fsm_newstate(fi, DEV_STATE_RUNNING); fsm_newstate(fi, DEV_STATE_RUNNING);
printk(KERN_INFO printk(KERN_INFO
"%s: connected with remote side\n", "%s: connected with remote side %s\n",
dev->name); dev->name, privptr->conn->userid);
break; break;
case DEV_STATE_STOPWAIT: case DEV_STATE_STOPWAIT:
printk(KERN_INFO printk(KERN_INFO
...@@ -1140,7 +1143,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) { ...@@ -1140,7 +1143,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
skb_pull(skb, NETIUCV_HDRLEN); skb_pull(skb, NETIUCV_HDRLEN);
skb_trim(skb, skb->len - NETIUCV_HDRLEN); skb_trim(skb, skb->len - NETIUCV_HDRLEN);
} }
printk(KERN_DEBUG "iucv_send returned %08x\n", printk(KERN_INFO "iucv_send returned %08x\n",
rc); rc);
} else { } else {
if (copied) if (copied)
...@@ -1612,7 +1615,7 @@ netiucv_remove_files(struct device *dev) ...@@ -1612,7 +1615,7 @@ netiucv_remove_files(struct device *dev)
} }
static int static int
netiucv_register_device(struct net_device *ndev, int ifno) netiucv_register_device(struct net_device *ndev)
{ {
struct netiucv_priv *priv = ndev->priv; struct netiucv_priv *priv = ndev->priv;
struct device *dev = kmalloc(sizeof(struct device), GFP_KERNEL); struct device *dev = kmalloc(sizeof(struct device), GFP_KERNEL);
...@@ -1623,7 +1626,7 @@ netiucv_register_device(struct net_device *ndev, int ifno) ...@@ -1623,7 +1626,7 @@ netiucv_register_device(struct net_device *ndev, int ifno)
if (dev) { if (dev) {
memset(dev, 0, sizeof(struct device)); memset(dev, 0, sizeof(struct device));
snprintf(dev->bus_id, BUS_ID_SIZE, "netiucv%x", ifno); snprintf(dev->bus_id, BUS_ID_SIZE, "net%s", ndev->name);
dev->bus = &iucv_bus; dev->bus = &iucv_bus;
dev->parent = iucv_root; dev->parent = iucv_root;
/* /*
...@@ -1801,16 +1804,15 @@ netiucv_setup_netdevice(struct net_device *dev) ...@@ -1801,16 +1804,15 @@ netiucv_setup_netdevice(struct net_device *dev)
* Allocate and initialize everything of a net device. * Allocate and initialize everything of a net device.
*/ */
static struct net_device * static struct net_device *
netiucv_init_netdevice(int ifno, char *username) netiucv_init_netdevice(char *username)
{ {
struct netiucv_priv *privptr; struct netiucv_priv *privptr;
struct net_device *dev; struct net_device *dev;
dev = alloc_netdev(sizeof(struct netiucv_priv), "", dev = alloc_netdev(sizeof(struct netiucv_priv), "iucv%d",
netiucv_setup_netdevice); netiucv_setup_netdevice);
if (!dev) if (!dev)
return NULL; return NULL;
sprintf(dev->name, "iucv%d", ifno);
privptr = (struct netiucv_priv *)dev->priv; privptr = (struct netiucv_priv *)dev->priv;
privptr->fsm = init_fsm("netiucvdev", dev_state_names, privptr->fsm = init_fsm("netiucvdev", dev_state_names,
...@@ -1861,7 +1863,7 @@ conn_write(struct device_driver *drv, const char *buf, size_t count) ...@@ -1861,7 +1863,7 @@ conn_write(struct device_driver *drv, const char *buf, size_t count)
while (i<9) while (i<9)
username[i++] = ' '; username[i++] = ' ';
username[9] = '\0'; username[9] = '\0';
dev = netiucv_init_netdevice(ifno, username); dev = netiucv_init_netdevice(username);
if (!dev) { if (!dev) {
printk(KERN_WARNING printk(KERN_WARNING
"netiucv: Could not allocate network device structure " "netiucv: Could not allocate network device structure "
...@@ -1869,16 +1871,18 @@ conn_write(struct device_driver *drv, const char *buf, size_t count) ...@@ -1869,16 +1871,18 @@ conn_write(struct device_driver *drv, const char *buf, size_t count)
return -ENODEV; return -ENODEV;
} }
if ((ret = netiucv_register_device(dev, ifno)))
goto out_free_ndev;
/* sysfs magic */
SET_NETDEV_DEV(dev, (struct device*)((struct netiucv_priv*)dev->priv)->dev);
if ((ret = register_netdev(dev))) { if ((ret = register_netdev(dev))) {
netiucv_unregister_device((struct device*)((struct netiucv_priv*)dev->priv)->dev);
goto out_free_ndev; goto out_free_ndev;
} }
if ((ret = netiucv_register_device(dev))) {
unregister_netdev(dev);
goto out_free_ndev;
}
/* sysfs magic */
SET_NETDEV_DEV(dev, (struct device*)((struct netiucv_priv*)dev->priv)->dev);
printk(KERN_INFO "%s: '%s'\n", dev->name, netiucv_printname(username)); printk(KERN_INFO "%s: '%s'\n", dev->name, netiucv_printname(username));
ifno++;
return count; return count;
...@@ -1891,6 +1895,61 @@ conn_write(struct device_driver *drv, const char *buf, size_t count) ...@@ -1891,6 +1895,61 @@ conn_write(struct device_driver *drv, const char *buf, size_t count)
DRIVER_ATTR(connection, 0200, NULL, conn_write); DRIVER_ATTR(connection, 0200, NULL, conn_write);
static ssize_t
remove_write (struct device_driver *drv, const char *buf, size_t count)
{
struct iucv_connection **clist = &connections;
struct net_device *ndev;
struct netiucv_priv *priv;
struct device *dev;
char name[IFNAMSIZ];
char *p;
int i;
pr_debug("%s() called\n", __FUNCTION__);
if (count >= IFNAMSIZ)
count = IFNAMSIZ-1;
for (i=0, p=(char *)buf; i<count && *p; i++, p++) {
if ((*p == '\n') | (*p == ' ')) {
/* trailing lf, grr */
break;
} else {
name[i]=*p;
}
}
name[i] = '\0';
while (*clist) {
ndev = (*clist)->netdev;
priv = (struct netiucv_priv*)ndev->priv;
dev = priv->dev;
if (strncmp(name, ndev->name, count)) {
clist = &((*clist)->next);
continue;
}
if (ndev->flags & (IFF_UP | IFF_RUNNING)) {
printk(KERN_WARNING
"netiucv: net device %s active with peer %s\n",
ndev->name, priv->conn->userid);
printk(KERN_WARNING
"netiucv: %s cannot be removed\n",
ndev->name);
return -EBUSY;
}
unregister_netdev(ndev);
netiucv_unregister_device(dev);
return count;
}
printk(KERN_WARNING
"netiucv: net device %s unknown\n", name);
return -EINVAL;
}
DRIVER_ATTR(remove, 0200, NULL, remove_write);
static struct device_driver netiucv_driver = { static struct device_driver netiucv_driver = {
.name = "netiucv", .name = "netiucv",
.bus = &iucv_bus, .bus = &iucv_bus,
...@@ -1899,7 +1958,7 @@ static struct device_driver netiucv_driver = { ...@@ -1899,7 +1958,7 @@ static struct device_driver netiucv_driver = {
static void static void
netiucv_banner(void) netiucv_banner(void)
{ {
char vbuf[] = "$Revision: 1.51 $"; char vbuf[] = "$Revision: 1.53 $";
char *version = vbuf; char *version = vbuf;
if ((version = strchr(version, ':'))) { if ((version = strchr(version, ':'))) {
...@@ -1924,6 +1983,7 @@ netiucv_exit(void) ...@@ -1924,6 +1983,7 @@ netiucv_exit(void)
} }
driver_remove_file(&netiucv_driver, &driver_attr_connection); driver_remove_file(&netiucv_driver, &driver_attr_connection);
driver_remove_file(&netiucv_driver, &driver_attr_remove);
driver_unregister(&netiucv_driver); driver_unregister(&netiucv_driver);
printk(KERN_INFO "NETIUCV driver unloaded\n"); printk(KERN_INFO "NETIUCV driver unloaded\n");
...@@ -1943,10 +2003,10 @@ netiucv_init(void) ...@@ -1943,10 +2003,10 @@ netiucv_init(void)
/* Add entry for specifying connections. */ /* Add entry for specifying connections. */
ret = driver_create_file(&netiucv_driver, &driver_attr_connection); ret = driver_create_file(&netiucv_driver, &driver_attr_connection);
if (ret == 0) {
if (ret == 0) ret = driver_create_file(&netiucv_driver, &driver_attr_remove);
netiucv_banner(); netiucv_banner();
else { } else {
printk(KERN_ERR "NETIUCV: failed to add driver attribute.\n"); printk(KERN_ERR "NETIUCV: failed to add driver attribute.\n");
driver_unregister(&netiucv_driver); driver_unregister(&netiucv_driver);
} }
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "qeth_mpc.h" #include "qeth_mpc.h"
#define VERSION_QETH_H "$Revision: 1.102 $" #define VERSION_QETH_H "$Revision: 1.107 $"
#ifdef CONFIG_QETH_IPV6 #ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6" #define QETH_VERSION_IPV6 ":IPv6"
...@@ -186,6 +186,8 @@ struct qeth_perf_stats { ...@@ -186,6 +186,8 @@ struct qeth_perf_stats {
__u64 outbound_start_time; __u64 outbound_start_time;
unsigned int outbound_cnt; unsigned int outbound_cnt;
unsigned int outbound_time; unsigned int outbound_time;
unsigned int inbound_do_qdio;
unsigned int outbound_do_qdio;
}; };
#endif /* CONFIG_QETH_PERF_STATS */ #endif /* CONFIG_QETH_PERF_STATS */
...@@ -279,7 +281,7 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) ...@@ -279,7 +281,7 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
#define QETH_IN_BUF_COUNT_MAX 128 #define QETH_IN_BUF_COUNT_MAX 128
#define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12) #define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12)
#define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \ #define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \
((card)->qdio.in_buf_pool.buf_count / 4) ((card)->qdio.in_buf_pool.buf_count / 2)
/* buffers we have to be behind before we get a PCI */ /* buffers we have to be behind before we get a PCI */
#define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1) #define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1)
...@@ -606,6 +608,7 @@ struct qeth_reply { ...@@ -606,6 +608,7 @@ struct qeth_reply {
wait_queue_head_t wait_q; wait_queue_head_t wait_q;
int (*callback)(struct qeth_card *,struct qeth_reply *,unsigned long); int (*callback)(struct qeth_card *,struct qeth_reply *,unsigned long);
int seqno; int seqno;
unsigned long offset;
int received; int received;
int rc; int rc;
void *param; void *param;
...@@ -613,8 +616,10 @@ struct qeth_reply { ...@@ -613,8 +616,10 @@ struct qeth_reply {
atomic_t refcnt; atomic_t refcnt;
}; };
struct qeth_card_info { #define QETH_BROADCAST_WITH_ECHO 1
#define QETH_BROADCAST_WITHOUT_ECHO 2
struct qeth_card_info {
char if_name[IF_NAME_LEN]; char if_name[IF_NAME_LEN];
unsigned short unit_addr2; unsigned short unit_addr2;
unsigned short cula; unsigned short cula;
...@@ -646,7 +651,6 @@ struct qeth_card_options { ...@@ -646,7 +651,6 @@ struct qeth_card_options {
enum qeth_checksum_types checksum_type; enum qeth_checksum_types checksum_type;
int broadcast_mode; int broadcast_mode;
int macaddr_mode; int macaddr_mode;
int enable_takeover;
int fake_broadcast; int fake_broadcast;
int add_hhlen; int add_hhlen;
int fake_ll; int fake_ll;
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
#ifndef __QETH_FS_H__ #ifndef __QETH_FS_H__
#define __QETH_FS_H__ #define __QETH_FS_H__
#define VERSION_QETH_FS_H "$Revision: 1.8 $"
extern const char *VERSION_QETH_PROC_C;
extern const char *VERSION_QETH_SYS_C;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
extern int extern int
qeth_create_procfs_entries(void); qeth_create_procfs_entries(void);
......
This diff is collapsed.
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <asm/cio.h> #include <asm/cio.h>
#include "qeth_mpc.h" #include "qeth_mpc.h"
const char *VERSION_QETH_MPC_C = "$Revision: 1.11 $";
unsigned char IDX_ACTIVATE_READ[]={ unsigned char IDX_ACTIVATE_READ[]={
0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
0x19,0x01,0x01,0x80, 0x00,0x00,0x00,0x00, 0x19,0x01,0x01,0x80, 0x00,0x00,0x00,0x00,
...@@ -129,8 +131,7 @@ unsigned char IPA_PDU_HEADER[]={ ...@@ -129,8 +131,7 @@ unsigned char IPA_PDU_HEADER[]={
0x00,0x00,0x00,0x14, 0x00,0x00, 0x00,0x00,0x00,0x14, 0x00,0x00,
(IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))/256, (IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))/256,
(IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))%256, (IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))%256,
0x10,0x00,0x00,0x01, 0x10,0x00,0x00,0x01, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0xc1,0x03,0x00,0x01, 0x00,0x00,0x00,0x00, 0xc1,0x03,0x00,0x01, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, 0x00,0x24, 0x00,0x00,0x00,0x00, 0x00,0x24,
sizeof(struct qeth_ipa_cmd)/256, sizeof(struct qeth_ipa_cmd)/256,
......
...@@ -14,7 +14,9 @@ ...@@ -14,7 +14,9 @@
#include <asm/qeth.h> #include <asm/qeth.h>
#define VERSION_QETH_MPC_H "$Revision: 1.27 $" #define VERSION_QETH_MPC_H "$Revision: 1.34 $"
extern const char *VERSION_QETH_MPC_C;
#define IPA_PDU_HEADER_SIZE 0x40 #define IPA_PDU_HEADER_SIZE 0x40
#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e) #define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e)
...@@ -33,6 +35,7 @@ extern unsigned char IPA_PDU_HEADER[]; ...@@ -33,6 +35,7 @@ extern unsigned char IPA_PDU_HEADER[];
#define OSA_ADDR_LEN 6 #define OSA_ADDR_LEN 6
#define QETH_TIMEOUT (10 * HZ) #define QETH_TIMEOUT (10 * HZ)
#define QETH_IPA_TIMEOUT (45 * HZ)
#define QETH_IDX_COMMAND_SEQNO -1 #define QETH_IDX_COMMAND_SEQNO -1
#define SR_INFO_LEN 16 #define SR_INFO_LEN 16
...@@ -245,12 +248,28 @@ struct qeth_ipacmd_setassparms_hdr { ...@@ -245,12 +248,28 @@ struct qeth_ipacmd_setassparms_hdr {
__u8 seq_no; __u8 seq_no;
} __attribute__((packed)); } __attribute__((packed));
struct qeth_arp_query_data {
__u16 request_bits;
__u16 reply_bits;
__u32 no_entries;
char data;
} __attribute__((packed));
/* used as parameter for arp_query reply */
struct qeth_arp_query_info {
__u32 udata_len;
__u32 udata_offset;
__u32 no_entries;
char *udata;
};
/* SETASSPARMS IPA Command: */ /* SETASSPARMS IPA Command: */
struct qeth_ipacmd_setassparms { struct qeth_ipacmd_setassparms {
struct qeth_ipacmd_setassparms_hdr hdr; struct qeth_ipacmd_setassparms_hdr hdr;
union { union {
__u32 flags_32bit; __u32 flags_32bit;
struct qeth_arp_cache_entry add_arp_entry; struct qeth_arp_cache_entry add_arp_entry;
struct qeth_arp_query_data query_arp;
__u8 ip[16]; __u8 ip[16];
} data; } data;
} __attribute__ ((packed)); } __attribute__ ((packed));
...@@ -277,16 +296,20 @@ struct qeth_change_addr { ...@@ -277,16 +296,20 @@ struct qeth_change_addr {
__u8 addr[OSA_ADDR_LEN]; __u8 addr[OSA_ADDR_LEN];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct qeth_ipacmd_setadpparms { struct qeth_ipacmd_setadpparms_hdr {
__u32 supp_hw_cmds; __u32 supp_hw_cmds;
__u32 reserved1; __u32 reserved1;
__u16 cmdlength; __u16 cmdlength;
__u16 reserved2; __u16 reserved2;
__u32 command_code; __u32 command_code;
__u16 return_code; __u16 return_code;
__u8 frames_used_total; __u8 used_total;
__u8 frame_seq_no; __u8 seq_no;
__u32 reserved3; __u32 reserved3;
} __attribute__ ((packed));
struct qeth_ipacmd_setadpparms {
struct qeth_ipacmd_setadpparms_hdr hdr;
union { union {
struct qeth_query_cmds_supp query_cmds_supp; struct qeth_query_cmds_supp query_cmds_supp;
struct qeth_change_addr change_addr; struct qeth_change_addr change_addr;
...@@ -357,36 +380,16 @@ enum qeth_ipa_arp_return_codes { ...@@ -357,36 +380,16 @@ enum qeth_ipa_arp_return_codes {
QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008, QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008,
}; };
#define QETH_QARP_DATA_SIZE 3968 #define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
struct qeth_arp_query_data {
__u16 request_bits;
__u16 reply_bits;
__u32 no_entries;
char data[QETH_QARP_DATA_SIZE];
} __attribute__((packed));
/* used as parameter for arp_query reply */
struct qeth_arp_query_info {
__u32 udata_len;
__u32 udata_offset;
__u32 no_entries;
char *udata;
};
#define IPA_ARP_CMD_LEN (IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_arp_cmd))
#define QETH_ARP_CMD_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
sizeof(struct qeth_ipacmd_setassparms_hdr)) sizeof(struct qeth_ipacmd_setassparms_hdr))
#define QETH_IPA_ARP_DATA_POS(buffer) (buffer + IPA_PDU_HEADER_SIZE + \ #define QETH_IPA_ARP_DATA_POS(buffer) (buffer + IPA_PDU_HEADER_SIZE + \
QETH_ARP_CMD_BASE_LEN) QETH_SETASS_BASE_LEN)
struct qeth_ipa_arp_cmd { #define QETH_SETADP_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
struct qeth_ipacmd_hdr ihdr; sizeof(struct qeth_ipacmd_setadpparms_hdr))
struct qeth_ipacmd_setassparms_hdr shdr; #define QETH_SNMP_SETADP_CMDLENGTH 16
union {
struct qeth_arp_query_data query_arp;
} data;
} __attribute__((packed));
#define QETH_ARP_DATA_SIZE 3968
#define QETH_ARP_CMD_LEN (QETH_ARP_DATA_SIZE + 8)
/* Helper functions */ /* Helper functions */
#define IS_IPA_REPLY(cmd) (cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) #define IS_IPA_REPLY(cmd) (cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST)
......
/* /*
* *
* linux/drivers/s390/net/qeth_fs.c ($Revision: 1.5 $) * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.9 $)
* *
* Linux on zSeries OSA Express and HiperSockets support * Linux on zSeries OSA Express and HiperSockets support
* This file contains code related to procfs. * This file contains code related to procfs.
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include "qeth_mpc.h" #include "qeth_mpc.h"
#include "qeth_fs.h" #include "qeth_fs.h"
const char *VERSION_QETH_PROC_C = "$Revision: 1.9 $";
/***** /proc/qeth *****/ /***** /proc/qeth *****/
#define QETH_PROCFILE_NAME "qeth" #define QETH_PROCFILE_NAME "qeth"
static struct proc_dir_entry *qeth_procfile; static struct proc_dir_entry *qeth_procfile;
...@@ -91,13 +93,19 @@ qeth_get_router_str(struct qeth_card *card, int ipv) ...@@ -91,13 +93,19 @@ qeth_get_router_str(struct qeth_card *card, int ipv)
return "pri"; return "pri";
else if (routing_type == SECONDARY_ROUTER) else if (routing_type == SECONDARY_ROUTER)
return "sec"; return "sec";
else if (routing_type == MULTICAST_ROUTER) else if (routing_type == MULTICAST_ROUTER) {
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "mc+";
return "mc"; return "mc";
else if (routing_type == PRIMARY_CONNECTOR) } else if (routing_type == PRIMARY_CONNECTOR) {
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "p+c";
return "p.c"; return "p.c";
else if (routing_type == SECONDARY_CONNECTOR) } else if (routing_type == SECONDARY_CONNECTOR) {
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "s+c";
return "s.c"; return "s.c";
else if (routing_type == NO_ROUTER) } else if (routing_type == NO_ROUTER)
return "no"; return "no";
else else
return "unk"; return "unk";
...@@ -244,14 +252,18 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it) ...@@ -244,14 +252,18 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
: 0 : 0
); );
seq_printf(s, " Inbound time (in us) : %i\n" seq_printf(s, " Inbound time (in us) : %i\n"
" Inbound cnt : %i\n" " Inbound count : %i\n"
" Inboud do_QDIO count : %i\n"
" Outbound time (in us, incl QDIO) : %i\n" " Outbound time (in us, incl QDIO) : %i\n"
" Outbound cnt : %i\n" " Outbound count : %i\n"
" Outbound do_QDIO count : %i\n"
" Watermarks L/H : %i/%i\n\n", " Watermarks L/H : %i/%i\n\n",
card->perf_stats.inbound_time, card->perf_stats.inbound_time,
card->perf_stats.inbound_cnt, card->perf_stats.inbound_cnt,
card->perf_stats.inbound_do_qdio,
card->perf_stats.outbound_time, card->perf_stats.outbound_time,
card->perf_stats.outbound_cnt, card->perf_stats.outbound_cnt,
card->perf_stats.outbound_do_qdio,
QETH_LOW_WATERMARK_PACK, QETH_HIGH_WATERMARK_PACK QETH_LOW_WATERMARK_PACK, QETH_HIGH_WATERMARK_PACK
); );
......
/* /*
* *
* linux/drivers/s390/net/qeth_sys.c ($Revision: 1.24 $) * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.29 $)
* *
* Linux on zSeries OSA Express and HiperSockets support * Linux on zSeries OSA Express and HiperSockets support
* This file contains code related to sysfs. * This file contains code related to sysfs.
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include "qeth_mpc.h" #include "qeth_mpc.h"
#include "qeth_fs.h" #include "qeth_fs.h"
const char *VERSION_QETH_SYS_C = "$Revision: 1.29 $";
/*****************************************************************************/ /*****************************************************************************/
/* */ /* */
/* /sys-fs stuff UNDER DEVELOPMENT !!! */ /* /sys-fs stuff UNDER DEVELOPMENT !!! */
...@@ -737,6 +739,10 @@ qeth_dev_ipato_enable_store(struct device *dev, const char *buf, size_t count) ...@@ -737,6 +739,10 @@ qeth_dev_ipato_enable_store(struct device *dev, const char *buf, size_t count)
if (!card) if (!card)
return -EINVAL; return -EINVAL;
if ((card->state != CARD_STATE_DOWN) &&
(card->state != CARD_STATE_RECOVER))
return -EPERM;
tmp = strsep((char **) &buf, "\n"); tmp = strsep((char **) &buf, "\n");
if (!strcmp(tmp, "toggle")){ if (!strcmp(tmp, "toggle")){
card->ipato.enabled = (card->ipato.enabled)? 0 : 1; card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
......
...@@ -12,15 +12,13 @@ ...@@ -12,15 +12,13 @@
#define __ASM_S390_IOCTL_H__ #define __ASM_S390_IOCTL_H__
#include <linux/ioctl.h> #include <linux/ioctl.h>
#define QETH_IOCTL_LETTER 'Q' #define SIOC_QETH_ARP_SET_NO_ENTRIES (SIOCDEVPRIVATE)
#define SIOC_QETH_ARP_QUERY_INFO (SIOCDEVPRIVATE + 1)
#define SIOC_QETH_ARP_SET_NO_ENTRIES _IOWR(QETH_IOCTL_LETTER, 1, int) #define SIOC_QETH_ARP_ADD_ENTRY (SIOCDEVPRIVATE + 2)
#define SIOC_QETH_ARP_QUERY_INFO _IOWR(QETH_IOCTL_LETTER, 2, int) #define SIOC_QETH_ARP_REMOVE_ENTRY (SIOCDEVPRIVATE + 3)
#define SIOC_QETH_ARP_ADD_ENTRY _IOWR(QETH_IOCTL_LETTER, 3, int) #define SIOC_QETH_ARP_FLUSH_CACHE (SIOCDEVPRIVATE + 4)
#define SIOC_QETH_ARP_REMOVE_ENTRY _IOWR(QETH_IOCTL_LETTER, 4, int) #define SIOC_QETH_ADP_SET_SNMP_CONTROL (SIOCDEVPRIVATE + 5)
#define SIOC_QETH_ARP_FLUSH_CACHE _IOWR(QETH_IOCTL_LETTER, 5, int) #define SIOC_QETH_GET_CARD_TYPE (SIOCDEVPRIVATE + 6)
#define SIOC_QETH_ADP_SET_SNMP_CONTROL _IOWR(QETH_IOCTL_LETTER, 6, int)
#define SIOC_QETH_GET_CARD_TYPE _IOWR(QETH_IOCTL_LETTER, 7, int)
struct qeth_arp_cache_entry { struct qeth_arp_cache_entry {
__u8 macaddr[6]; __u8 macaddr[6];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment