Commit 0dc80d7c authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] s390: network driver.

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

s390 network driver changes:
 - ctc/lcs/qeth: prevent a ccw-device to be grouped multiple times.
 - icuv: clear correct field in iucv_register_program if no userid is specified.
 - lcs: fix online/offline cycle again.
 - lcs: fix ungrouping of lcs group device. The channels of the lcs card
   should be offline afterwards.
 - lcs: don't do netif_stop_queue if no tx buffer is available, just
   return -EBUSY and drop the packets.
parent ba0ce578
/*
* drivers/s390/cio/ccwgroup.c
* bus driver for ccwgroup
* $Revision: 1.24 $
* $Revision: 1.25 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
......@@ -102,8 +102,10 @@ ccwgroup_release (struct device *dev)
gdev = to_ccwgroupdev(dev);
for (i = 0; i < gdev->count; i++)
for (i = 0; i < gdev->count; i++) {
gdev->cdev[i]->dev.driver_data = NULL;
put_device(&gdev->cdev[i]->dev);
}
kfree(gdev);
}
......@@ -155,6 +157,7 @@ ccwgroup_create(struct device *root,
struct ccwgroup_device *gdev;
int i;
int rc;
int del_drvdata;
if (argc > 256) /* disallow dumb users */
return -EINVAL;
......@@ -166,6 +169,7 @@ ccwgroup_create(struct device *root,
memset(gdev, 0, sizeof(*gdev) + argc*sizeof(gdev->cdev[0]));
atomic_set(&gdev->onoff, 0);
del_drvdata = 0;
for (i = 0; i < argc; i++) {
gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]);
......@@ -177,7 +181,15 @@ ccwgroup_create(struct device *root,
rc = -EINVAL;
goto error;
}
/* Don't allow a device to belong to more than one group. */
if (gdev->cdev[i]->dev.driver_data) {
rc = -EINVAL;
goto error;
}
}
for (i = 0; i < argc; i++)
gdev->cdev[i]->dev.driver_data = gdev;
del_drvdata = 1;
*gdev = (struct ccwgroup_device) {
.creator_id = creator_id,
......@@ -212,9 +224,11 @@ ccwgroup_create(struct device *root,
device_unregister(&gdev->dev);
error:
for (i = 0; i < argc; i++)
if (gdev->cdev[i])
if (gdev->cdev[i]) {
put_device(&gdev->cdev[i]->dev);
if (del_drvdata)
gdev->cdev[i]->dev.driver_data = NULL;
}
kfree(gdev);
return rc;
......@@ -399,40 +413,14 @@ static inline struct ccwgroup_device *
__ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev)
{
struct ccwgroup_device *gdev;
struct list_head *entry;
struct device *dev;
int i, found;
/*
* Find groupdevice cdev belongs to.
* Unfortunately, we can't use bus_for_each_dev() because of the
* semaphore (and return value of fn() is int).
*/
if (!get_bus(&ccwgroup_bus_type))
return NULL;
gdev = NULL;
down_read(&ccwgroup_bus_type.subsys.rwsem);
list_for_each(entry, &ccwgroup_bus_type.devices.list) {
dev = get_device(container_of(entry, struct device, bus_list));
found = 0;
if (!dev)
continue;
gdev = to_ccwgroupdev(dev);
for (i = 0; i < gdev->count && (!found); i++) {
if (gdev->cdev[i] == cdev)
found = 1;
}
if (found)
break;
put_device(dev);
gdev = NULL;
if (cdev->dev.driver_data) {
gdev = (struct ccwgroup_device *)cdev->dev.driver_data;
if (get_device(&gdev->dev))
return gdev;
return NULL;
}
up_read(&ccwgroup_bus_type.subsys.rwsem);
put_bus(&ccwgroup_bus_type);
return gdev;
return NULL;
}
void
......
/*
* $Id: ctcmain.c,v 1.57 2004/03/02 15:34:01 mschwide Exp $
* $Id: ctcmain.c,v 1.58 2004/03/24 10:51:56 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.57 $
* RELEASE-TAG: CTC/ESCON network driver $Revision: 1.58 $
*
*/
......@@ -319,7 +319,7 @@ static void
print_banner(void)
{
static int printed = 0;
char vbuf[] = "$Revision: 1.57 $";
char vbuf[] = "$Revision: 1.58 $";
char *version = vbuf;
if (printed)
......@@ -2067,7 +2067,8 @@ ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
return;
}
priv = cdev->dev.driver_data;
priv = ((struct ccwgroup_device *)cdev->dev.driver_data)
->dev.driver_data;
/* Try to extract channel from driver data. */
if (priv->channel[READ]->cdev == cdev)
......@@ -2963,8 +2964,6 @@ ctc_probe_device(struct ccwgroup_device *cgdev)
cgdev->cdev[0]->handler = ctc_irq_handler;
cgdev->cdev[1]->handler = ctc_irq_handler;
cgdev->dev.driver_data = priv;
cgdev->cdev[0]->dev.driver_data = priv;
cgdev->cdev[1]->dev.driver_data = priv;
return 0;
}
......
/*
* $Id: iucv.c,v 1.26 2004/03/10 11:55:31 braunu Exp $
* $Id: iucv.c,v 1.27 2004/03/22 07:43:43 braunu Exp $
*
* IUCV network driver
*
......@@ -29,7 +29,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* RELEASE-TAG: IUCV lowlevel driver $Revision: 1.26 $
* RELEASE-TAG: IUCV lowlevel driver $Revision: 1.27 $
*
*/
......@@ -351,7 +351,7 @@ do { \
static void
iucv_banner(void)
{
char vbuf[] = "$Revision: 1.26 $";
char vbuf[] = "$Revision: 1.27 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
......@@ -374,14 +374,14 @@ iucv_init(void)
{
int ret;
if (iucv_external_int_buffer)
return 0;
if (!MACHINE_IS_VM) {
printk(KERN_ERR "IUCV: IUCV connection needs VM as base\n");
return -EPROTONOSUPPORT;
}
if (iucv_external_int_buffer)
return 0;
ret = bus_register(&iucv_bus);
if (ret != 0) {
printk(KERN_ERR "IUCV: failed to register bus.\n");
......@@ -830,7 +830,7 @@ iucv_register_program (__u8 pgmname[16],
memset (new_handler->id.mask, 0xFF,
sizeof (new_handler->id.mask));
}
memset (new_handler->id.mask, 0x00,
memset (new_handler->id.userid, 0x00,
sizeof (new_handler->id.userid));
}
/* fill in the rest of handler */
......
This diff is collapsed.
......@@ -6,18 +6,35 @@
#include <linux/workqueue.h>
#include <asm/ccwdev.h>
#define VERSION_LCS_H "$Revision: 1.13 $"
#define VERSION_LCS_H "$Revision: 1.15 $"
#define LCS_DBF_TEXT(level, name, text) \
do { \
debug_text_event(lcs_dbf_##name, level, text); \
} while (0)
#define LCS_DBF_HEX(level,name,addr,len) \
do { \
debug_event(lcs_dbf_##name,level,(void*)(addr),len); \
} while (0)
#define LCS_DBF_TEXT_(level,name,text...) \
do { \
sprintf(debug_buffer, text); \
debug_text_event(lcs_dbf_##name,level, debug_buffer);\
} while (0)
/**
* some more definitions for debug or output stuff
*/
#define PRINTK_HEADER " lcs: "
/**
* sysfs related stuff
*/
#define CARD_FROM_DEV(cdev) \
(struct lcs_card *) \
((struct ccwgroup_device *)cdev->dev.driver_data)->dev.driver_data;
/**
* CCW commands used in this driver
*/
......@@ -123,6 +140,7 @@ enum lcs_channel_states {
CH_STATE_STOPPED,
CH_STATE_RUNNING,
CH_STATE_SUSPENDED,
CH_STATE_CLEARED,
};
/**
......@@ -131,6 +149,7 @@ enum lcs_channel_states {
enum lcs_dev_states {
DEV_STATE_DOWN,
DEV_STATE_UP,
DEV_STATE_RECOVER,
};
/**
......
/*
* $Id: netiucv.c,v 1.45 2004/03/15 08:48:48 braunu Exp $
* $Id: netiucv.c,v 1.47 2004/03/22 07:41:42 braunu 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.45 $
* RELEASE-TAG: IUCV network driver $Revision: 1.47 $
*
*/
......@@ -764,7 +764,7 @@ conn_action_start(fsm_instance *fi, int event, void *arg)
{
struct iucv_event *ev = (struct iucv_event *)arg;
struct iucv_connection *conn = ev->conn;
__u16 msglimit;
int rc;
pr_debug("%s() called\n", __FUNCTION__);
......@@ -793,10 +793,11 @@ conn_action_start(fsm_instance *fi, int event, void *arg)
fsm_newstate(fi, CONN_STATE_SETUPWAIT);
rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic,
conn->userid, iucv_host, 0, NULL, NULL, conn->handle,
conn->userid, iucv_host, 0, NULL, &msglimit, conn->handle,
conn);
switch (rc) {
case 0:
conn->netdev->tx_queue_len = msglimit;
return;
case 11:
printk(KERN_NOTICE
......@@ -1911,7 +1912,7 @@ static struct device_driver netiucv_driver = {
static void
netiucv_banner(void)
{
char vbuf[] = "$Revision: 1.45 $";
char vbuf[] = "$Revision: 1.47 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
......
......@@ -755,7 +755,7 @@ qeth_get_cards_problem(struct ccw_device *cdev, unsigned char *buffer,
int problem = 0;
struct qeth_card *card;
card = cdev->dev.driver_data;
card = CARD_FROM_CDEV(cdev);
if (atomic_read(&card->shutdown_phase))
return 0;
......@@ -6105,7 +6105,7 @@ qeth_interrupt_handler_read(struct ccw_device *cdev, unsigned long intparm,
sprintf(dbf_text, "%4x", rqparam);
QETH_DBF_TEXT4(0, trace, dbf_text);
card = cdev->dev.driver_data;
card = CARD_FROM_CDEV(cdev);
if (!card)
return;
......@@ -6231,7 +6231,7 @@ qeth_interrupt_handler_write(struct ccw_device *cdev, unsigned long intparm,
sprintf(dbf_text, "%4x", rqparam);
QETH_DBF_TEXT4(0, trace, dbf_text);
card = cdev->dev.driver_data;
card = CARD_FROM_CDEV(cdev);
if (!card)
return;
......@@ -6343,7 +6343,7 @@ qeth_interrupt_handler_qdio(struct ccw_device *cdev, unsigned long intparm,
sprintf(dbf_text, "%4x", rqparam);
QETH_DBF_TEXT4(0, trace, dbf_text);
card = cdev->dev.driver_data;
card = CARD_FROM_CDEV(cdev);
if (!card)
return;
......@@ -10620,13 +10620,10 @@ qeth_probe_device(struct ccwgroup_device *gdev)
card->gdev = gdev;
gdev->cdev[0]->handler = qeth_interrupt_handler_read;
gdev->cdev[0]->dev.driver_data = card;
gdev->cdev[1]->handler = qeth_interrupt_handler_write;
gdev->cdev[1]->dev.driver_data = card;
gdev->cdev[2]->handler = qeth_interrupt_handler_qdio;
gdev->cdev[2]->dev.driver_data = card;
ret = __qeth_create_attributes(&gdev->dev);
if (ret != 0)
......
......@@ -696,6 +696,8 @@ struct sparebufs {
#define CARD_RDEV_ID(card) card->gdev->cdev[0]->dev.bus_id
#define CARD_WDEV_ID(card) card->gdev->cdev[1]->dev.bus_id
#define CARD_DDEV_ID(card) card->gdev->cdev[2]->dev.bus_id
#define CARD_FROM_CDEV(cdev) (struct qeth_card *) \
((struct ccwgroup_device *) cdev->dev.driver_data)->dev.driver_data
#define SENSE_COMMAND_REJECT_BYTE 0
#define SENSE_COMMAND_REJECT_FLAG 0x80
......
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