Commit 67dd079a authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: cu3088 metadriver.

Add driver for multi-subchannel devices (ctc and lcs)

The cu3088 driver is an metadriver to make the ctc and lcs
(potentially also claw) drivers work with the new
channel subsystem driver. It uses the ccwgroup driver to
group subchannels for ctc and lcs.

Authors:
	Arnd Bergmann <arndb@de.ibm.com>
	Cornelia Huck <cohuck@de.ibm.com>
parent c768f081
...@@ -518,7 +518,13 @@ config HOTPLUG ...@@ -518,7 +518,13 @@ config HOTPLUG
config LCS config LCS
tristate "Lan Channel Station Interface" tristate "Lan Channel Station Interface"
depends on NETDEVICES && (NET_ETHERNET || TR) depends on NETDEVICES && (NET_ETHERNET || TR || FDDI)
help
Select this option if you want to use LCS networking on IBM S/390
or zSeries. This device driver supports Token Ring (IEEE 802.5),
FDDI (IEEE 802.7) and Ethernet.
This option is also available as a module which will be
called lcs.o . If you do not know what it is, it's safe to say "Y".
config CTC config CTC
tristate "CTC device support" tristate "CTC device support"
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
# S/390 network devices # S/390 network devices
# #
export-objs := iucv.o fsm.o export-objs := iucv.o fsm.o cu3088.o
ctc-objs := ctcmain.o ctctty.o ctc-objs := ctcmain.o ctctty.o
obj-$(CONFIG_IUCV) += iucv.o fsm.o obj-$(CONFIG_IUCV) += iucv.o fsm.o
obj-$(CONFIG_CTC) += ctc.o fsm.o obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o
obj-$(CONFIG_IUCV) += netiucv.o obj-$(CONFIG_IUCV) += netiucv.o
obj-$(CONFIG_LCS) += lcs.o obj-$(CONFIG_LCS) += lcs.o cu3088.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
/*
* $Id: cu3088.c,v 1.21 2002/12/03 16:26:45 cohuck Exp $
*
* CTC / LCS ccw_device driver
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Arnd Bergmann <arndb@de.ibm.com>
* Cornelia Huck <cohuck@de.ibm.com>
*
* 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
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
#include "cu3088.h"
const char *cu3088_type[] = {
"not a channel",
"CTC/A",
"ESCON channel",
"FICON channel",
"P390 LCS card",
"OSA2 card",
"unknown channel type",
"unsupported channel type",
};
/* static definitions */
static struct ccw_device_id cu3088_ids[] = {
{ CCW_DEVICE(0x3088, 0x08), .driver_info = channel_type_parallel },
{ CCW_DEVICE(0x3088, 0x1f), .driver_info = channel_type_escon },
{ CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon },
{ CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 },
{ CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 },
{ /* end of list */ }
};
static struct ccw_driver cu3088_driver;
struct device cu3088_root_dev = {
.name = "CU3088 Devices",
.bus_id = "cu3088",
};
static ssize_t
group_write(struct device_driver *drv, const char *buf, size_t count,
loff_t off)
{
const char *start, *end;
char bus_ids[2][BUS_ID_SIZE], *argv[2];
int i;
int ret;
struct ccwgroup_driver *cdrv;
if (off)
return 0;
cdrv = to_ccwgroupdrv(drv);
if (!cdrv)
return -EINVAL;
start = buf;
for (i=0; i<2; i++) {
static const char delim[] = {',', '\n'};
int len;
if (!(end = strchr(start, delim[i])))
return count;
len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start);
strncpy (bus_ids[i], start, len);
bus_ids[i][len] = '\0';
argv[i] = bus_ids[i];
start = end + 1;
}
ret = ccwgroup_create(&cu3088_root_dev, cdrv->driver_id,
&cu3088_driver, 2, argv);
return (ret == 0) ? count : ret;
}
static DRIVER_ATTR(group, 0200, NULL, group_write);
/* Register-unregister for ctc&lcs */
int
register_cu3088_discipline(struct ccwgroup_driver *dcp)
{
int rc;
if (!dcp)
return -EINVAL;
/* Register discipline.*/
rc = ccwgroup_driver_register(dcp);
if (rc)
return rc;
rc = driver_create_file(&dcp->driver, &driver_attr_group);
if (rc)
ccwgroup_driver_unregister(dcp);
return rc;
}
void
unregister_cu3088_discipline(struct ccwgroup_driver *dcp)
{
if (!dcp)
return;
driver_remove_file(&dcp->driver, &driver_attr_group);
ccwgroup_driver_unregister(dcp);
}
static struct ccw_driver cu3088_driver = {
.owner = THIS_MODULE,
.ids = cu3088_ids,
.name = "cu3088",
.probe = ccwgroup_probe_ccwdev,
.remove = ccwgroup_remove_ccwdev,
};
/* module setup */
static int __init
cu3088_init (void)
{
int rc;
rc = device_register(&cu3088_root_dev);
if (rc)
return rc;
rc = ccw_driver_register(&cu3088_driver);
if (rc) {
device_unregister(&cu3088_root_dev);
return rc;
}
return rc;
}
static void __exit
cu3088_exit (void)
{
ccw_driver_unregister(&cu3088_driver);
device_unregister(&cu3088_root_dev);
}
MODULE_DEVICE_TABLE(ccw,cu3088_ids);
MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
MODULE_LICENSE("GPL");
module_init(cu3088_init);
module_exit(cu3088_exit);
EXPORT_SYMBOL(register_cu3088_discipline);
EXPORT_SYMBOL(unregister_cu3088_discipline);
#ifndef _CU3088_H
#define _CU3088_H
/**
* Enum for classifying detected devices.
*/
enum channel_types {
/* Device is not a channel */
channel_type_none,
/* Device is a CTC/A */
channel_type_parallel,
/* Device is a ESCON channel */
channel_type_escon,
/* Device is a FICON channel */
channel_type_ficon,
/* Device is a P390 LCS card */
channel_type_p390,
/* Device is a OSA2 card */
channel_type_osa2,
/* Device is a channel, but we don't know
* anything about it */
channel_type_unknown,
/* Device is an unsupported model */
channel_type_unsupported,
/* number of type entries */
num_channel_types
};
extern const char *cu3088_type[num_channel_types];
extern int register_cu3088_discipline(struct ccwgroup_driver *);
extern void unregister_cu3088_discipline(struct ccwgroup_driver *);
#endif
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