Commit 1ca06429 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:
 - ctc: Add missing irb error checking.
 - iucv: Add name of net_device to iucvMagic to more than one
         connection between two guests.
 - qeth: Don't send IPA command if card is not in state SOFTSETUP or UP.
 - qeth: Fix number base in simple_strtoul call for buffer_count attribute.
 - qeth: Fix reallocating of buffers when buffer_count attribute is changed.
 - qeth: Correct handling of return codes in qeth_realloc_buffer_pool.
 - qeth: Don't call dev_close/dev_open on STOPLAN/STARTLAN commands.
         Use netif_carrier_off/netif_carrier_on instead.
parent 10281b07
/*
* $Id: ctcmain.c,v 1.58 2004/03/24 10:51:56 ptiedem Exp $
* $Id: ctcmain.c,v 1.59 2004/04/21 17:10:13 ptiedem Exp $
*
* CTC / ESCON network driver
*
......@@ -36,7 +36,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* RELEASE-TAG: CTC/ESCON network driver $Revision: 1.58 $
* RELEASE-TAG: CTC/ESCON network driver $Revision: 1.59 $
*
*/
......@@ -319,7 +319,7 @@ static void
print_banner(void)
{
static int printed = 0;
char vbuf[] = "$Revision: 1.58 $";
char vbuf[] = "$Revision: 1.59 $";
char *version = vbuf;
if (printed)
......@@ -2045,6 +2045,32 @@ extract_channel_media(char *name)
return ret;
}
static long
__ctc_check_irb_error(struct ccw_device *cdev, struct irb *irb)
{
if (!IS_ERR(irb))
return 0;
switch (PTR_ERR(irb)) {
case -EIO:
ctc_pr_warn("i/o-error on device %s\n", cdev->dev.bus_id);
// CTC_DBF_TEXT(trace, 2, "ckirberr");
// CTC_DBF_TEXT_(trace, 2, " rc%d", -EIO);
break;
case -ETIMEDOUT:
ctc_pr_warn("timeout on device %s\n", cdev->dev.bus_id);
// CTC_DBF_TEXT(trace, 2, "ckirberr");
// CTC_DBF_TEXT_(trace, 2, " rc%d", -ETIMEDOUT);
break;
default:
ctc_pr_warn("unknown error %ld on device %s\n", PTR_ERR(irb),
cdev->dev.bus_id);
// CTC_DBF_TEXT(trace, 2, "ckirberr");
// CTC_DBF_TEXT(trace, 2, " rc???");
}
return PTR_ERR(irb);
}
/**
* Main IRQ handler.
*
......@@ -2059,6 +2085,9 @@ ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
struct net_device *dev;
struct ctc_priv *priv;
if (__ctc_check_irb_error(cdev, irb))
return;
/* Check for unsolicited interrupts. */
if (!cdev->dev.driver_data) {
ctc_pr_warn("ctc: Got unsolicited irq: %s c-%02x d-%02x\n",
......
/*
* $Id: netiucv.c,v 1.49 2004/04/15 06:37:54 braunu Exp $
* $Id: netiucv.c,v 1.51 2004/04/23 08:11:21 mschwide Exp $
*
* IUCV network driver
*
......@@ -30,7 +30,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* RELEASE-TAG: IUCV network driver $Revision: 1.49 $
* RELEASE-TAG: IUCV network driver $Revision: 1.51 $
*
*/
......@@ -169,10 +169,10 @@ static __inline__ int netiucv_test_and_set_busy(struct net_device *dev)
}
static __u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static __u8 iucvMagic[16] = {
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
};
//static __u8 iucvMagic[16] = {
// 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
// 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
//};
/**
* This mask means the 16-byte IUCV "magic" and the origin userid must
......@@ -693,13 +693,20 @@ static void
conn_action_connreject(fsm_instance *fi, int event, void *arg)
{
struct iucv_event *ev = (struct iucv_event *)arg;
// struct iucv_connection *conn = ev->conn;
struct iucv_connection *conn = ev->conn;
struct net_device *netdev = conn->netdev;
iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data;
__u8 udata[16];
pr_debug("%s() called\n", __FUNCTION__);
iucv_sever(eib->ippathid, udata);
if (eib->ippathid != conn->pathid) {
printk(KERN_INFO
"%s: IR pathid %d does not match original pathid %d\n",
netdev->name, eib->ippathid, conn->pathid);
iucv_sever(conn->pathid, udata);
}
}
static void
......@@ -715,7 +722,12 @@ conn_action_connack(fsm_instance *fi, int event, void *arg)
fsm_deltimer(&conn->timer);
fsm_newstate(fi, CONN_STATE_IDLE);
if (eib->ippathid != conn->pathid) {
printk(KERN_INFO
"%s: IR pathid %d does not match original pathid %d\n",
netdev->name, eib->ippathid, conn->pathid);
conn->pathid = eib->ippathid;
}
netdev->tx_queue_len = eib->ipmsglim;
fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
}
......@@ -759,9 +771,14 @@ conn_action_start(fsm_instance *fi, int event, void *arg)
struct iucv_connection *conn = ev->conn;
__u16 msglimit;
int rc;
__u8 iucvMagic[16] = {
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
};
pr_debug("%s() called\n", __FUNCTION__);
memcpy(iucvMagic, conn->netdev->name, IFNAMSIZ);
if (conn->handle == 0) {
conn->handle =
iucv_register_program(iucvMagic, conn->userid, mask,
......@@ -1882,7 +1899,7 @@ static struct device_driver netiucv_driver = {
static void
netiucv_banner(void)
{
char vbuf[] = "$Revision: 1.49 $";
char vbuf[] = "$Revision: 1.51 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
......
......@@ -23,7 +23,7 @@
#include "qeth_mpc.h"
#define VERSION_QETH_H "$Revision: 1.100 $"
#define VERSION_QETH_H "$Revision: 1.102 $"
#ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6"
......@@ -397,11 +397,6 @@ struct qeth_qdio_buffer {
struct qeth_qdio_q {
struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
struct qeth_qdio_buffer bufs[QDIO_MAX_BUFFERS_PER_Q];
/*
* buf_to_process means "buffer primed by hardware,
* has to be read in by driver"; current state PRIMED
*/
volatile int next_buf_to_process;
/*
* buf_to_init means "buffer must be initialized by driver and must
* be made available for hardware" -> state is set to EMPTY
......@@ -493,8 +488,7 @@ enum qeth_card_states {
CARD_STATE_DOWN,
CARD_STATE_HARDSETUP,
CARD_STATE_SOFTSETUP,
CARD_STATE_UP_LAN_OFFLINE,
CARD_STATE_UP_LAN_ONLINE,
CARD_STATE_UP,
CARD_STATE_RECOVER,
};
......@@ -981,24 +975,27 @@ qeth_setrouting_v4(struct qeth_card *);
extern int
qeth_setrouting_v6(struct qeth_card *);
int
extern int
qeth_add_ipato_entry(struct qeth_card *, struct qeth_ipato_entry *);
void
extern void
qeth_del_ipato_entry(struct qeth_card *, enum qeth_prot_versions, u8 *, int);
int
extern int
qeth_add_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
void
extern void
qeth_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
int
extern int
qeth_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
void
extern void
qeth_del_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
void
extern void
qeth_schedule_recovery(struct qeth_card *);
extern int
qeth_realloc_buffer_pool(struct qeth_card *, int);
#endif /* __QETH_H__ */
This diff is collapsed.
/*
*
* linux/drivers/s390/net/qeth_sys.c ($Revision: 1.19 $)
* linux/drivers/s390/net/qeth_sys.c ($Revision: 1.24 $)
*
* Linux on zSeries OSA Express and HiperSockets support
* This file contains code related to sysfs.
......@@ -41,10 +41,11 @@ qeth_dev_state_show(struct device *dev, char *buf)
return sprintf(buf, "HARDSETUP\n");
case CARD_STATE_SOFTSETUP:
return sprintf(buf, "SOFTSETUP\n");
case CARD_STATE_UP_LAN_OFFLINE:
return sprintf(buf, "UP (LAN OFFLINE)\n");
case CARD_STATE_UP_LAN_ONLINE:
case CARD_STATE_UP:
if (card->lan_online)
return sprintf(buf, "UP (LAN ONLINE)\n");
else
return sprintf(buf, "UP (LAN OFFLINE)\n");
case CARD_STATE_RECOVER:
return sprintf(buf, "RECOVER\n");
default:
......@@ -293,7 +294,8 @@ qeth_dev_bufcnt_store(struct device *dev, const char *buf, size_t count)
{
struct qeth_card *card = dev->driver_data;
char *tmp;
unsigned int cnt;
int cnt, old_cnt;
int rc;
if (!card)
return -EINVAL;
......@@ -302,12 +304,15 @@ qeth_dev_bufcnt_store(struct device *dev, const char *buf, size_t count)
(card->state != CARD_STATE_RECOVER))
return -EPERM;
cnt = simple_strtoul(buf, &tmp, 16);
old_cnt = card->qdio.in_buf_pool.buf_count;
cnt = simple_strtoul(buf, &tmp, 10);
cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN :
((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt);
card->qdio.in_buf_pool.buf_count = cnt;
/* TODO: steel/add buffers from/to a running card's buffer pool (?) */
if (old_cnt != cnt) {
if ((rc = qeth_realloc_buffer_pool(card, cnt)))
PRINT_WARN("Error (%d) while setting "
"buffer count.\n", rc);
}
return count;
}
......@@ -356,45 +361,31 @@ qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route,
if (!strcmp(tmp, "no_router")){
route->type = NO_ROUTER;
goto check_reset;
}
if (card->info.type == QETH_CARD_TYPE_IQD) {
if (!strcmp(tmp, "primary_connector")) {
} else if (!strcmp(tmp, "primary_connector")) {
route->type = PRIMARY_CONNECTOR;
} else if (!strcmp(tmp, "secondary_connector")) {
route->type = SECONDARY_CONNECTOR;
} else if (!strcmp(tmp, "multicast_router")) {
route->type = MULTICAST_ROUTER;
} else
goto out_inval;
} else {
if (!strcmp(tmp, "primary_router")) {
} else if (!strcmp(tmp, "primary_router")) {
route->type = PRIMARY_ROUTER;
} else if (!strcmp(tmp, "secondary_router")) {
route->type = SECONDARY_ROUTER;
} else if (!strcmp(tmp, "multicast_router")) {
if (qeth_is_ipafunc_supported(card, prot,
IPA_OSA_MC_ROUTER))
route->type = MULTICAST_ROUTER;
else
goto out_inval;
} else
goto out_inval;
} else {
PRINT_WARN("Invalid routing type '%s'.\n", tmp);
return -EINVAL;
}
check_reset:
if (old_route_type != route->type){
if (((card->state == CARD_STATE_SOFTSETUP) ||
(card->state == CARD_STATE_UP)) &&
(old_route_type != route->type)){
if (prot == QETH_PROT_IPV4)
rc = qeth_setrouting_v4(card);
else if (prot == QETH_PROT_IPV6)
rc = qeth_setrouting_v6(card);
}
return count;
out_inval:
PRINT_WARN("Routing type '%s' not supported for interface %s.\n"
"Router status not changed.\n",
tmp, card->info.if_name);
return -EINVAL;
}
static ssize_t
......@@ -572,8 +563,7 @@ qeth_dev_recover_store(struct device *dev, const char *buf, size_t count)
if (!card)
return -EINVAL;
if ((card->state != CARD_STATE_UP_LAN_ONLINE) &&
(card->state != CARD_STATE_UP_LAN_OFFLINE))
if (card->state != CARD_STATE_UP)
return -EPERM;
i = simple_strtoul(buf, &tmp, 16);
......@@ -585,7 +575,6 @@ qeth_dev_recover_store(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
/* TODO */
static ssize_t
qeth_dev_broadcast_mode_show(struct device *dev, char *buf)
{
......@@ -603,7 +592,6 @@ qeth_dev_broadcast_mode_show(struct device *dev, char *buf)
"all rings":"local");
}
/* TODO */
static ssize_t
qeth_dev_broadcast_mode_store(struct device *dev, const char *buf, size_t count)
{
......@@ -642,7 +630,6 @@ qeth_dev_broadcast_mode_store(struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(broadcast_mode, 0644, qeth_dev_broadcast_mode_show,
qeth_dev_broadcast_mode_store);
/* TODO */
static ssize_t
qeth_dev_canonical_macaddr_show(struct device *dev, char *buf)
{
......@@ -659,7 +646,6 @@ qeth_dev_canonical_macaddr_show(struct device *dev, char *buf)
QETH_TR_MACADDR_CANONICAL)? 1:0);
}
/* TODO */
static ssize_t
qeth_dev_canonical_macaddr_store(struct device *dev, const char *buf,
size_t count)
......
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