summaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 21:41:17 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 21:41:17 +0200
commite60b9a0346ee08af4715ee5b2d82f705fbe6e309 (patch)
tree886e1be2a283806e1dc940b7379a5a6e4683a97b /drivers/s390
parentMerge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next (diff)
parents390/ap: Fix wrong or missing comments (diff)
downloadlinux-e60b9a0346ee08af4715ee5b2d82f705fbe6e309.tar.xz
linux-e60b9a0346ee08af4715ee5b2d82f705fbe6e309.zip
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "Just a random collection of bug-fixes and cleanups, nothing new in this merge request." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (46 commits) s390/ap: Fix wrong or missing comments s390/ap: move receive callback to message struct s390/dasd: re-prioritize partition detection message s390/qeth: reshuffle initialization s390/qeth: cleanup drv attr usage s390/claw: cleanup drv attr usage s390/lcs: cleanup drv attr usage s390/ctc: cleanup drv attr usage s390/ccwgroup: remove ccwgroup_create_from_string s390/qeth: stop using struct ccwgroup driver for discipline callbacks s390/qeth: switch to ccwgroup_create_dev s390/claw: switch to ccwgroup_create_dev s390/lcs: switch to ccwgroup_create_dev s390/ctcm: switch to ccwgroup_create_dev s390/ccwgroup: exploit ccwdev_by_dev_id s390/ccwgroup: introduce ccwgroup_create_dev s390: fix race on TIF_MCCK_PENDING s390/barrier: make use of fast-bcr facility s390/barrier: cleanup barrier functions s390/claw: remove "eieio" calls ...
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/sclp_cmd.c12
-rw-r--r--drivers/s390/char/tape.h43
-rw-r--r--drivers/s390/char/tape_34xx.c136
-rw-r--r--drivers/s390/char/tape_3590.c105
-rw-r--r--drivers/s390/char/tape_char.c13
-rw-r--r--drivers/s390/char/tape_core.c16
-rw-r--r--drivers/s390/cio/ccwgroup.c112
-rw-r--r--drivers/s390/cio/cio.c73
-rw-r--r--drivers/s390/cio/device.c13
-rw-r--r--drivers/s390/cio/device.h1
-rw-r--r--drivers/s390/cio/qdio_main.c47
-rw-r--r--drivers/s390/crypto/ap_bus.c24
-rw-r--r--drivers/s390/crypto/ap_bus.h7
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c3
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.c3
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.c3
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c5
-rw-r--r--drivers/s390/net/claw.c165
-rw-r--r--drivers/s390/net/ctcm_main.c52
-rw-r--r--drivers/s390/net/ctcm_main.h8
-rw-r--r--drivers/s390/net/ctcm_sysfs.c37
-rw-r--r--drivers/s390/net/lcs.c52
-rw-r--r--drivers/s390/net/qeth_core.h24
-rw-r--r--drivers/s390/net/qeth_core_main.c178
-rw-r--r--drivers/s390/net/qeth_core_sys.c49
-rw-r--r--drivers/s390/net/qeth_l2_main.c16
-rw-r--r--drivers/s390/net/qeth_l3_main.c16
27 files changed, 375 insertions, 838 deletions
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 231a1d85127b..36506366158d 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -352,7 +352,17 @@ out:
static int sclp_assign_storage(u16 rn)
{
- return do_assign_storage(0x000d0001, rn);
+ unsigned long long start, address;
+ int rc;
+
+ rc = do_assign_storage(0x000d0001, rn);
+ if (rc)
+ goto out;
+ start = address = rn2addr(rn);
+ for (; address < start + rzm; address += PAGE_SIZE)
+ page_set_storage_key(address, PAGE_DEFAULT_KEY, 0);
+out:
+ return rc;
}
static int sclp_unassign_storage(u16 rn)
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index 267b54e8ff5a..bc6c7cfd36b6 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -154,12 +154,6 @@ struct tape_discipline {
struct tape_request *(*read_block)(struct tape_device *, size_t);
struct tape_request *(*write_block)(struct tape_device *, size_t);
void (*process_eov)(struct tape_device*);
-#ifdef CONFIG_S390_TAPE_BLOCK
- /* Block device stuff. */
- struct tape_request *(*bread)(struct tape_device *, struct request *);
- void (*check_locate)(struct tape_device *, struct tape_request *);
- void (*free_bread)(struct tape_request *);
-#endif
/* ioctl function for additional ioctls. */
int (*ioctl_fn)(struct tape_device *, unsigned int, unsigned long);
/* Array of tape commands with TAPE_NR_MTOPS entries */
@@ -182,26 +176,6 @@ struct tape_char_data {
int block_size; /* of size block_size. */
};
-#ifdef CONFIG_S390_TAPE_BLOCK
-/* Block Frontend Data */
-struct tape_blk_data
-{
- struct tape_device * device;
- /* Block device request queue. */
- struct request_queue * request_queue;
- spinlock_t request_queue_lock;
-
- /* Task to move entries from block request to CCS request queue. */
- struct work_struct requeue_task;
- atomic_t requeue_scheduled;
-
- /* Current position on the tape. */
- long block_position;
- int medium_changed;
- struct gendisk * disk;
-};
-#endif
-
/* Tape Info */
struct tape_device {
/* entry in tape_device_list */
@@ -248,10 +222,6 @@ struct tape_device {
/* Character device frontend data */
struct tape_char_data char_data;
-#ifdef CONFIG_S390_TAPE_BLOCK
- /* Block dev frontend data */
- struct tape_blk_data blk_data;
-#endif
/* Function to start or stop the next request later. */
struct delayed_work tape_dnr;
@@ -313,19 +283,6 @@ extern void tapechar_exit(void);
extern int tapechar_setup_device(struct tape_device *);
extern void tapechar_cleanup_device(struct tape_device *);
-/* Externals from tape_block.c */
-#ifdef CONFIG_S390_TAPE_BLOCK
-extern int tapeblock_init (void);
-extern void tapeblock_exit(void);
-extern int tapeblock_setup_device(struct tape_device *);
-extern void tapeblock_cleanup_device(struct tape_device *);
-#else
-static inline int tapeblock_init (void) {return 0;}
-static inline void tapeblock_exit (void) {;}
-static inline int tapeblock_setup_device(struct tape_device *t) {return 0;}
-static inline void tapeblock_cleanup_device (struct tape_device *t) {;}
-#endif
-
/* tape initialisation functions */
#ifdef CONFIG_PROC_FS
extern void tape_proc_init (void);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 934ef33eb9a4..b28de80b7ca4 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -323,20 +323,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0;
sense = irb->ecw;
-#ifdef CONFIG_S390_TAPE_BLOCK
- if (request->op == TO_BLOCK) {
- /*
- * Recovery for block device requests. Set the block_position
- * to something invalid and retry.
- */
- device->blk_data.block_position = -1;
- if (request->retries-- <= 0)
- return tape_34xx_erp_failed(request, -EIO);
- else
- return tape_34xx_erp_retry(request);
- }
-#endif
-
if (
sense[0] & SENSE_COMMAND_REJECT &&
sense[1] & SENSE_WRITE_PROTECT
@@ -1129,123 +1115,6 @@ tape_34xx_mtseek(struct tape_device *device, int mt_count)
return tape_do_io_free(device, request);
}
-#ifdef CONFIG_S390_TAPE_BLOCK
-/*
- * Tape block read for 34xx.
- */
-static struct tape_request *
-tape_34xx_bread(struct tape_device *device, struct request *req)
-{
- struct tape_request *request;
- struct ccw1 *ccw;
- int count = 0;
- unsigned off;
- char *dst;
- struct bio_vec *bv;
- struct req_iterator iter;
- struct tape_34xx_block_id * start_block;
-
- DBF_EVENT(6, "xBREDid:");
-
- /* Count the number of blocks for the request. */
- rq_for_each_segment(bv, req, iter)
- count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9);
-
- /* Allocate the ccw request. */
- request = tape_alloc_request(3+count+1, 8);
- if (IS_ERR(request))
- return request;
-
- /* Setup ccws. */
- request->op = TO_BLOCK;
- start_block = (struct tape_34xx_block_id *) request->cpdata;
- start_block->block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B;
- DBF_EVENT(6, "start_block = %i\n", start_block->block);
-
- ccw = request->cpaddr;
- ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte);
-
- /*
- * We always setup a nop after the mode set ccw. This slot is
- * used in tape_std_check_locate to insert a locate ccw if the
- * current tape position doesn't match the start block to be read.
- * The second nop will be filled with a read block id which is in
- * turn used by tape_34xx_free_bread to populate the segment bid
- * table.
- */
- ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
- ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
-
- rq_for_each_segment(bv, req, iter) {
- dst = kmap(bv->bv_page) + bv->bv_offset;
- for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) {
- ccw->flags = CCW_FLAG_CC;
- ccw->cmd_code = READ_FORWARD;
- ccw->count = TAPEBLOCK_HSEC_SIZE;
- set_normalized_cda(ccw, (void*) __pa(dst));
- ccw++;
- dst += TAPEBLOCK_HSEC_SIZE;
- }
- }
-
- ccw = tape_ccw_end(ccw, NOP, 0, NULL);
- DBF_EVENT(6, "xBREDccwg\n");
- return request;
-}
-
-static void
-tape_34xx_free_bread (struct tape_request *request)
-{
- struct ccw1* ccw;
-
- ccw = request->cpaddr;
- if ((ccw + 2)->cmd_code == READ_BLOCK_ID) {
- struct {
- struct tape_34xx_block_id cbid;
- struct tape_34xx_block_id dbid;
- } __attribute__ ((packed)) *rbi_data;
-
- rbi_data = request->cpdata;
-
- if (request->device)
- tape_34xx_add_sbid(request->device, rbi_data->cbid);
- }
-
- /* Last ccw is a nop and doesn't need clear_normalized_cda */
- for (; ccw->flags & CCW_FLAG_CC; ccw++)
- if (ccw->cmd_code == READ_FORWARD)
- clear_normalized_cda(ccw);
- tape_free_request(request);
-}
-
-/*
- * check_locate is called just before the tape request is passed to
- * the common io layer for execution. It has to check the current
- * tape position and insert a locate ccw if it doesn't match the
- * start block for the request.
- */
-static void
-tape_34xx_check_locate(struct tape_device *device, struct tape_request *request)
-{
- struct tape_34xx_block_id * start_block;
-
- start_block = (struct tape_34xx_block_id *) request->cpdata;
- if (start_block->block == device->blk_data.block_position)
- return;
-
- DBF_LH(4, "Block seek(%06d+%06d)\n", start_block->block, device->bof);
- start_block->wrap = 0;
- start_block->segment = 1;
- start_block->format = (*device->modeset_byte & 0x08) ?
- TAPE34XX_FMT_3480_XF :
- TAPE34XX_FMT_3480;
- start_block->block = start_block->block + device->bof;
- tape_34xx_merge_sbid(device, start_block);
- tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata);
- tape_ccw_cc(request->cpaddr + 2, READ_BLOCK_ID, 8, request->cpdata);
-}
-#endif
-
/*
* List of 3480/3490 magnetic tape commands.
*/
@@ -1295,11 +1164,6 @@ static struct tape_discipline tape_discipline_34xx = {
.irq = tape_34xx_irq,
.read_block = tape_std_read_block,
.write_block = tape_std_write_block,
-#ifdef CONFIG_S390_TAPE_BLOCK
- .bread = tape_34xx_bread,
- .free_bread = tape_34xx_free_bread,
- .check_locate = tape_34xx_check_locate,
-#endif
.ioctl_fn = tape_34xx_ioctl,
.mtop_array = tape_34xx_mtop
};
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index 49c6aab7ad78..a5c6614b0db2 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -670,92 +670,6 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
return 0;
}
-#ifdef CONFIG_S390_TAPE_BLOCK
-/*
- * Tape Block READ
- */
-static struct tape_request *
-tape_3590_bread(struct tape_device *device, struct request *req)
-{
- struct tape_request *request;
- struct ccw1 *ccw;
- int count = 0, start_block;
- unsigned off;
- char *dst;
- struct bio_vec *bv;
- struct req_iterator iter;
-
- DBF_EVENT(6, "xBREDid:");
- start_block = blk_rq_pos(req) >> TAPEBLOCK_HSEC_S2B;
- DBF_EVENT(6, "start_block = %i\n", start_block);
-
- rq_for_each_segment(bv, req, iter)
- count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9);
-
- request = tape_alloc_request(2 + count + 1, 4);
- if (IS_ERR(request))
- return request;
- request->op = TO_BLOCK;
- *(__u32 *) request->cpdata = start_block;
- ccw = request->cpaddr;
- ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte);
-
- /*
- * We always setup a nop after the mode set ccw. This slot is
- * used in tape_std_check_locate to insert a locate ccw if the
- * current tape position doesn't match the start block to be read.
- */
- ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
-
- rq_for_each_segment(bv, req, iter) {
- dst = page_address(bv->bv_page) + bv->bv_offset;
- for (off = 0; off < bv->bv_len; off += TAPEBLOCK_HSEC_SIZE) {
- ccw->flags = CCW_FLAG_CC;
- ccw->cmd_code = READ_FORWARD;
- ccw->count = TAPEBLOCK_HSEC_SIZE;
- set_normalized_cda(ccw, (void *) __pa(dst));
- ccw++;
- dst += TAPEBLOCK_HSEC_SIZE;
- }
- BUG_ON(off > bv->bv_len);
- }
- ccw = tape_ccw_end(ccw, NOP, 0, NULL);
- DBF_EVENT(6, "xBREDccwg\n");
- return request;
-}
-
-static void
-tape_3590_free_bread(struct tape_request *request)
-{
- struct ccw1 *ccw;
-
- /* Last ccw is a nop and doesn't need clear_normalized_cda */
- for (ccw = request->cpaddr; ccw->flags & CCW_FLAG_CC; ccw++)
- if (ccw->cmd_code == READ_FORWARD)
- clear_normalized_cda(ccw);
- tape_free_request(request);
-}
-
-/*
- * check_locate is called just before the tape request is passed to
- * the common io layer for execution. It has to check the current
- * tape position and insert a locate ccw if it doesn't match the
- * start block for the request.
- */
-static void
-tape_3590_check_locate(struct tape_device *device, struct tape_request *request)
-{
- __u32 *start_block;
-
- start_block = (__u32 *) request->cpdata;
- if (*start_block != device->blk_data.block_position) {
- /* Add the start offset of the file to get the real block. */
- *start_block += device->bof;
- tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata);
- }
-}
-#endif
-
static void tape_3590_med_state_set(struct tape_device *device,
struct tape_3590_med_sense *sense)
{
@@ -1423,20 +1337,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
{
struct tape_3590_sense *sense;
-#ifdef CONFIG_S390_TAPE_BLOCK
- if (request->op == TO_BLOCK) {
- /*
- * Recovery for block device requests. Set the block_position
- * to something invalid and retry.
- */
- device->blk_data.block_position = -1;
- if (request->retries-- <= 0)
- return tape_3590_erp_failed(device, request, irb, -EIO);
- else
- return tape_3590_erp_retry(device, request, irb);
- }
-#endif
-
sense = (struct tape_3590_sense *) irb->ecw;
DBF_EVENT(6, "Unit Check: RQC = %x\n", sense->rc_rqc);
@@ -1729,11 +1629,6 @@ static struct tape_discipline tape_discipline_3590 = {
.irq = tape_3590_irq,
.read_block = tape_std_read_block,
.write_block = tape_std_write_block,
-#ifdef CONFIG_S390_TAPE_BLOCK
- .bread = tape_3590_bread,
- .free_bread = tape_3590_free_bread,
- .check_locate = tape_3590_check_locate,
-#endif
.ioctl_fn = tape_3590_ioctl,
.mtop_array = tape_3590_mtop
};
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 87cd0ab242de..46886a7578c6 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -161,11 +161,6 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
if (rc)
return rc;
-#ifdef CONFIG_S390_TAPE_BLOCK
- /* Changes position. */
- device->blk_data.medium_changed = 1;
-#endif
-
DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size);
/* Let the discipline build the ccw chain. */
request = device->discipline->read_block(device, block_size);
@@ -218,11 +213,6 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t
if (rc)
return rc;
-#ifdef CONFIG_S390_TAPE_BLOCK
- /* Changes position. */
- device->blk_data.medium_changed = 1;
-#endif
-
DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size);
DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks);
/* Let the discipline build the ccw chain. */
@@ -379,9 +369,6 @@ __tapechar_ioctl(struct tape_device *device,
case MTBSFM:
case MTFSFM:
case MTSEEK:
-#ifdef CONFIG_S390_TAPE_BLOCK
- device->blk_data.medium_changed = 1;
-#endif
if (device->required_tapemarks)
tape_std_terminate_write(device);
default:
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index b3a3e8e8656e..585618663ba4 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -401,9 +401,6 @@ tape_generic_online(struct tape_device *device,
rc = tapechar_setup_device(device);
if (rc)
goto out_minor;
- rc = tapeblock_setup_device(device);
- if (rc)
- goto out_char;
tape_state_set(device, TS_UNUSED);
@@ -411,8 +408,6 @@ tape_generic_online(struct tape_device *device,
return 0;
-out_char:
- tapechar_cleanup_device(device);
out_minor:
tape_remove_minor(device);
out_discipline:
@@ -426,7 +421,6 @@ out:
static void
tape_cleanup_device(struct tape_device *device)
{
- tapeblock_cleanup_device(device);
tapechar_cleanup_device(device);
device->discipline->cleanup_device(device);
module_put(device->discipline->owner);
@@ -785,10 +779,6 @@ __tape_start_io(struct tape_device *device, struct tape_request *request)
{
int rc;
-#ifdef CONFIG_S390_TAPE_BLOCK
- if (request->op == TO_BLOCK)
- device->discipline->check_locate(device, request);
-#endif
rc = ccw_device_start(
device->cdev,
request->cpaddr,
@@ -1253,7 +1243,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
}
/*
- * Tape device open function used by tape_char & tape_block frontends.
+ * Tape device open function used by tape_char frontend.
*/
int
tape_open(struct tape_device *device)
@@ -1283,7 +1273,7 @@ tape_open(struct tape_device *device)
}
/*
- * Tape device release function used by tape_char & tape_block frontends.
+ * Tape device release function used by tape_char frontend.
*/
int
tape_release(struct tape_device *device)
@@ -1344,7 +1334,6 @@ tape_init (void)
DBF_EVENT(3, "tape init\n");
tape_proc_init();
tapechar_init ();
- tapeblock_init ();
return 0;
}
@@ -1358,7 +1347,6 @@ tape_exit(void)
/* Get rid of the frontends */
tapechar_exit();
- tapeblock_exit();
tape_proc_cleanup();
debug_unregister (TAPE_DBF_AREA);
}
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 5f1dc6fb5708..731470e68493 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,7 +1,7 @@
/*
* bus driver for ccwgroup
*
- * Copyright IBM Corp. 2002, 2009
+ * Copyright IBM Corp. 2002, 2012
*
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
* Cornelia Huck (cornelia.huck@de.ibm.com)
@@ -15,10 +15,13 @@
#include <linux/ctype.h>
#include <linux/dcache.h>
+#include <asm/cio.h>
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
-#define CCW_BUS_ID_SIZE 20
+#include "device.h"
+
+#define CCW_BUS_ID_SIZE 10
/* In Linux 2.4, we had a channel device layer called "chandev"
* that did all sorts of obscure stuff for networking devices.
@@ -27,19 +30,6 @@
* to devices that use multiple subchannels.
*/
-/* a device matches a driver if all its slave devices match the same
- * entry of the driver */
-static int ccwgroup_bus_match(struct device *dev, struct device_driver * drv)
-{
- struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
- struct ccwgroup_driver *gdrv = to_ccwgroupdrv(drv);
-
- if (gdev->creator_id == gdrv->driver_id)
- return 1;
-
- return 0;
-}
-
static struct bus_type ccwgroup_bus_type;
static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
@@ -254,9 +244,10 @@ static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
return 0;
}
-static int __get_next_bus_id(const char **buf, char *bus_id)
+static int __get_next_id(const char **buf, struct ccw_dev_id *id)
{
- int rc, len;
+ unsigned int cssid, ssid, devno;
+ int ret = 0, len;
char *start, *end;
start = (char *)*buf;
@@ -271,49 +262,40 @@ static int __get_next_bus_id(const char **buf, char *bus_id)
len = end - start + 1;
end++;
}
- if (len < CCW_BUS_ID_SIZE) {
- strlcpy(bus_id, start, len);
- rc = 0;
+ if (len <= CCW_BUS_ID_SIZE) {
+ if (sscanf(start, "%2x.%1x.%04x", &cssid, &ssid, &devno) != 3)
+ ret = -EINVAL;
} else
- rc = -EINVAL;
- *buf = end;
- return rc;
-}
-
-static int __is_valid_bus_id(char bus_id[CCW_BUS_ID_SIZE])
-{
- int cssid, ssid, devno;
+ ret = -EINVAL;
- /* Must be of form %x.%x.%04x */
- if (sscanf(bus_id, "%x.%1x.%04x", &cssid, &ssid, &devno) != 3)
- return 0;
- return 1;
+ if (!ret) {
+ id->ssid = ssid;
+ id->devno = devno;
+ }
+ *buf = end;
+ return ret;
}
/**
- * ccwgroup_create_from_string() - create and register a ccw group device
- * @root: parent device for the new device
- * @creator_id: identifier of creating driver
- * @cdrv: ccw driver of slave devices
+ * ccwgroup_create_dev() - create and register a ccw group device
+ * @parent: parent device for the new device
+ * @gdrv: driver for the new group device
* @num_devices: number of slave devices
* @buf: buffer containing comma separated bus ids of slave devices
*
- * Create and register a new ccw group device as a child of @root. Slave
- * devices are obtained from the list of bus ids given in @buf and must all
- * belong to @cdrv.
+ * Create and register a new ccw group device as a child of @parent. Slave
+ * devices are obtained from the list of bus ids given in @buf.
* Returns:
* %0 on success and an error code on failure.
* Context:
* non-atomic
*/
-int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
- struct ccw_driver *cdrv, int num_devices,
- const char *buf)
+int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv,
+ int num_devices, const char *buf)
{
struct ccwgroup_device *gdev;
+ struct ccw_dev_id dev_id;
int rc, i;
- char tmp_bus_id[CCW_BUS_ID_SIZE];
- const char *curr_buf;
gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]),
GFP_KERNEL);
@@ -323,29 +305,24 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
atomic_set(&gdev->onoff, 0);
mutex_init(&gdev->reg_mutex);
mutex_lock(&gdev->reg_mutex);
- gdev->creator_id = creator_id;
gdev->count = num_devices;
gdev->dev.bus = &ccwgroup_bus_type;
- gdev->dev.parent = root;
+ gdev->dev.parent = parent;
gdev->dev.release = ccwgroup_release;
device_initialize(&gdev->dev);
- curr_buf = buf;
- for (i = 0; i < num_devices && curr_buf; i++) {
- rc = __get_next_bus_id(&curr_buf, tmp_bus_id);
+ for (i = 0; i < num_devices && buf; i++) {
+ rc = __get_next_id(&buf, &dev_id);
if (rc != 0)
goto error;
- if (!__is_valid_bus_id(tmp_bus_id)) {
- rc = -EINVAL;
- goto error;
- }
- gdev->cdev[i] = get_ccwdev_by_busid(cdrv, tmp_bus_id);
+ gdev->cdev[i] = get_ccwdev_by_dev_id(&dev_id);
/*
* All devices have to be of the same type in
* order to be grouped.
*/
- if (!gdev->cdev[i]
- || gdev->cdev[i]->id.driver_info !=
+ if (!gdev->cdev[i] || !gdev->cdev[i]->drv ||
+ gdev->cdev[i]->drv != gdev->cdev[0]->drv ||
+ gdev->cdev[i]->id.driver_info !=
gdev->cdev[0]->id.driver_info) {
rc = -EINVAL;
goto error;
@@ -361,18 +338,25 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
spin_unlock_irq(gdev->cdev[i]->ccwlock);
}
/* Check for sufficient number of bus ids. */
- if (i < num_devices && !curr_buf) {
+ if (i < num_devices) {
rc = -EINVAL;
goto error;
}
/* Check for trailing stuff. */
- if (i == num_devices && strlen(curr_buf) > 0) {
+ if (i == num_devices && strlen(buf) > 0) {
rc = -EINVAL;
goto error;
}
dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
gdev->dev.groups = ccwgroup_attr_groups;
+
+ if (gdrv) {
+ gdev->dev.driver = &gdrv->driver;
+ rc = gdrv->setup ? gdrv->setup(gdev) : 0;
+ if (rc)
+ goto error;
+ }
rc = device_add(&gdev->dev);
if (rc)
goto error;
@@ -397,7 +381,7 @@ error:
put_device(&gdev->dev);
return rc;
}
-EXPORT_SYMBOL(ccwgroup_create_from_string);
+EXPORT_SYMBOL(ccwgroup_create_dev);
static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
void *data)
@@ -440,14 +424,6 @@ module_exit(cleanup_ccwgroup);
/************************** driver stuff ******************************/
-static int ccwgroup_probe(struct device *dev)
-{
- struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
- struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
-
- return gdrv->probe ? gdrv->probe(gdev) : -ENODEV;
-}
-
static int ccwgroup_remove(struct device *dev)
{
struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
@@ -542,8 +518,6 @@ static const struct dev_pm_ops ccwgroup_pm_ops = {
static struct bus_type ccwgroup_bus_type = {
.name = "ccwgroup",
- .match = ccwgroup_bus_match,
- .probe = ccwgroup_probe,
.remove = ccwgroup_remove,
.shutdown = ccwgroup_shutdown,
.pm = &ccwgroup_pm_ops,
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index a49c46c91983..a6ddaed8793d 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -656,51 +656,34 @@ static struct io_subchannel_private console_priv;
static int console_subchannel_in_use;
/*
- * Use cio_tpi to get a pending interrupt and call the interrupt handler.
- * Return non-zero if an interrupt was processed, zero otherwise.
+ * Use cio_tsch to update the subchannel status and call the interrupt handler
+ * if status had been pending. Called with the console_subchannel lock.
*/
-static int cio_tpi(void)
+static void cio_tsch(struct subchannel *sch)
{
- struct tpi_info *tpi_info;
- struct subchannel *sch;
struct irb *irb;
int irq_context;
- tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id;
- if (tpi(NULL) != 1)
- return 0;
- kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++;
- if (tpi_info->adapter_IO) {
- do_adapter_IO(tpi_info->isc);
- return 1;
- }
irb = (struct irb *)&S390_lowcore.irb;
/* Store interrupt response block to lowcore. */
- if (tsch(tpi_info->schid, irb) != 0) {
+ if (tsch(sch->schid, irb) != 0)
/* Not status pending or not operational. */
- kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
- return 1;
- }
- sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
- if (!sch) {
- kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
- return 1;
- }
+ return;
+ memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw));
+ /* Call interrupt handler with updated status. */
irq_context = in_interrupt();
- if (!irq_context)
+ if (!irq_context) {
local_bh_disable();
- irq_enter();
- spin_lock(sch->lock);
- memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw));
+ irq_enter();
+ }
if (sch->driver && sch->driver->irq)
sch->driver->irq(sch);
else
kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
- spin_unlock(sch->lock);
- irq_exit();
- if (!irq_context)
+ if (!irq_context) {
+ irq_exit();
_local_bh_enable();
- return 1;
+ }
}
void *cio_get_console_priv(void)
@@ -712,34 +695,16 @@ void *cio_get_console_priv(void)
* busy wait for the next interrupt on the console
*/
void wait_cons_dev(void)
- __releases(console_subchannel.lock)
- __acquires(console_subchannel.lock)
{
- unsigned long cr6 __attribute__ ((aligned (8)));
- unsigned long save_cr6 __attribute__ ((aligned (8)));
-
- /*
- * before entering the spinlock we may already have
- * processed the interrupt on a different CPU...
- */
if (!console_subchannel_in_use)
return;
- /* disable all but the console isc */
- __ctl_store (save_cr6, 6, 6);
- cr6 = 1UL << (31 - CONSOLE_ISC);
- __ctl_load (cr6, 6, 6);
-
- do {
- spin_unlock(console_subchannel.lock);
- if (!cio_tpi())
- cpu_relax();
- spin_lock(console_subchannel.lock);
- } while (console_subchannel.schib.scsw.cmd.actl != 0);
- /*
- * restore previous isc value
- */
- __ctl_load (save_cr6, 6, 6);
+ while (1) {
+ cio_tsch(&console_subchannel);
+ if (console_subchannel.schib.scsw.cmd.actl == 0)
+ break;
+ udelay_simple(100);
+ }
}
static int
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 02d015259461..f8f952d52045 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -695,7 +695,17 @@ static int match_dev_id(struct device *dev, void *data)
return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id);
}
-static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id)
+/**
+ * get_ccwdev_by_dev_id() - obtain device from a ccw device id
+ * @dev_id: id of the device to be searched
+ *
+ * This function searches all devices attached to the ccw bus for a device
+ * matching @dev_id.
+ * Returns:
+ * If a device is found its reference count is increased and returned;
+ * else %NULL is returned.
+ */
+struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id)
{
struct device *dev;
@@ -703,6 +713,7 @@ static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id)
return dev ? to_ccwdev(dev) : NULL;
}
+EXPORT_SYMBOL_GPL(get_ccwdev_by_dev_id);
static void ccw_device_do_unbind_bind(struct ccw_device *cdev)
{
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 179824b3082f..6bace6942396 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -101,6 +101,7 @@ int ccw_device_test_sense_data(struct ccw_device *);
void ccw_device_schedule_sch_unregister(struct ccw_device *);
int ccw_purge_blacklisted(void);
void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo);
+struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id);
/* Function prototypes for device status and basic sense stuff. */
void ccw_device_accumulate_irb(struct ccw_device *, struct irb *);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 35c685c374e9..7493efafa0d5 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -63,7 +63,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask,
" ipm %0\n"
" srl %0,28\n"
: "=d" (cc)
- : "d" (__fc), "d" (__schid), "d" (__mask) : "cc", "memory");
+ : "d" (__fc), "d" (__schid), "d" (__mask) : "cc");
return cc;
}
@@ -74,7 +74,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask,
* @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer
* @fc: function code to perform
*
- * Returns cc or QDIO_ERROR_SIGA_ACCESS_EXCEPTION.
+ * Returns condition code.
* Note: For IQDC unicast queues only the highest priority queue is processed.
*/
static inline int do_siga_output(unsigned long schid, unsigned long mask,
@@ -85,18 +85,16 @@ static inline int do_siga_output(unsigned long schid, unsigned long mask,
register unsigned long __schid asm("1") = schid;
register unsigned long __mask asm("2") = mask;
register unsigned long __aob asm("3") = aob;
- int cc = QDIO_ERROR_SIGA_ACCESS_EXCEPTION;
+ int cc;
asm volatile(
" siga 0\n"
- "0: ipm %0\n"
+ " ipm %0\n"
" srl %0,28\n"
- "1:\n"
- EX_TABLE(0b, 1b)
- : "+d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask),
- "+d" (__aob)
- : : "cc", "memory");
- *bb = ((unsigned int) __fc) >> 31;
+ : "=d" (cc), "+d" (__fc), "+d" (__aob)
+ : "d" (__schid), "d" (__mask)
+ : "cc");
+ *bb = __fc >> 31;
return cc;
}
@@ -167,7 +165,7 @@ again:
DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
- q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
+ q->handler(q->irq_ptr->cdev, QDIO_ERROR_GET_BUF_STATE,
q->nr, q->first_to_kick, count, q->irq_ptr->int_parm);
return 0;
}
@@ -215,7 +213,7 @@ again:
DBF_ERROR("%4x SQBS ERROR", SCH_NO(q));
DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
- q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
+ q->handler(q->irq_ptr->cdev, QDIO_ERROR_SET_BUF_STATE,
q->nr, q->first_to_kick, count, q->irq_ptr->int_parm);
return 0;
}
@@ -313,7 +311,7 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
cc = do_siga_sync(schid, output, input, fc);
if (unlikely(cc))
DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc);
- return cc;
+ return (cc) ? -EIO : 0;
}
static inline int qdio_siga_sync_q(struct qdio_q *q)
@@ -384,7 +382,7 @@ static inline int qdio_siga_input(struct qdio_q *q)
cc = do_siga_input(schid, q->mask, fc);
if (unlikely(cc))
DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc);
- return cc;
+ return (cc) ? -EIO : 0;
}
#define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0)
@@ -443,7 +441,7 @@ static void process_buffer_error(struct qdio_q *q, int count)
unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT :
SLSB_P_OUTPUT_NOT_INIT;
- q->qdio_error |= QDIO_ERROR_SLSB_STATE;
+ q->qdio_error = QDIO_ERROR_SLSB_STATE;
/* special handling for no target buffer empty */
if ((!q->is_input_q &&
@@ -519,7 +517,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
int count, stop;
unsigned char state = 0;
- q->timestamp = get_clock_fast();
+ q->timestamp = get_clock();
/*
* Don't check 128 buffers, as otherwise qdio_inbound_q_moved
@@ -575,7 +573,7 @@ static int qdio_inbound_q_moved(struct qdio_q *q)
bufnr = get_inbound_buffer_frontier(q);
- if ((bufnr != q->last_move) || q->qdio_error) {
+ if (bufnr != q->last_move) {
q->last_move = bufnr;
if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR)
q->u.in.timestamp = get_clock();
@@ -790,7 +788,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
int count, stop;
unsigned char state = 0;
- q->timestamp = get_clock_fast();
+ q->timestamp = get_clock();
if (need_siga_sync(q))
if (((queue_type(q) != QDIO_IQDIO_QFMT) &&
@@ -863,7 +861,7 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q)
bufnr = get_outbound_buffer_frontier(q);
- if ((bufnr != q->last_move) || q->qdio_error) {
+ if (bufnr != q->last_move) {
q->last_move = bufnr;
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
return 1;
@@ -894,13 +892,16 @@ retry:
goto retry;
}
DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr);
- cc |= QDIO_ERROR_SIGA_BUSY;
- } else
+ cc = -EBUSY;
+ } else {
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr);
+ cc = -ENOBUFS;
+ }
break;
case 1:
case 3:
DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc);
+ cc = -EIO;
break;
}
if (retries) {
@@ -1090,7 +1091,7 @@ static void qdio_handle_activate_check(struct ccw_device *cdev,
}
count = sub_buf(q->first_to_check, q->first_to_kick);
- q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
+ q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE,
q->nr, q->first_to_kick, count, irq_ptr->int_parm);
no_handler:
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
@@ -1691,7 +1692,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
"do%02x b:%02x c:%02x", callflags, bufnr, count);
if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)
- return -EBUSY;
+ return -EIO;
if (!count)
return 0;
if (callflags & QDIO_FLAG_SYNC_INPUT)
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 7e9a72eb2fe0..b987d4619586 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -215,7 +215,7 @@ ap_queue_interruption_control(ap_qid_t qid, void *ind)
register struct ap_queue_status reg1_out asm ("1");
register void *reg2 asm ("2") = ind;
asm volatile(
- ".long 0xb2af0000" /* PQAP(RAPQ) */
+ ".long 0xb2af0000" /* PQAP(AQIC) */
: "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2)
:
: "cc" );
@@ -232,7 +232,7 @@ __ap_query_functions(ap_qid_t qid, unsigned int *functions)
register unsigned long reg2 asm ("2");
asm volatile(
- ".long 0xb2af0000\n"
+ ".long 0xb2af0000\n" /* PQAP(TAPQ) */
"0:\n"
EX_TABLE(0b, 0b)
: "+d" (reg0), "+d" (reg1), "=d" (reg2)
@@ -391,7 +391,7 @@ __ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
reg0 |= 0x400000UL;
asm volatile (
- "0: .long 0xb2ad0042\n" /* DQAP */
+ "0: .long 0xb2ad0042\n" /* NQAP */
" brc 2,0b"
: "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
: "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
@@ -450,7 +450,7 @@ __ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
asm volatile(
- "0: .long 0xb2ae0064\n"
+ "0: .long 0xb2ae0064\n" /* DQAP */
" brc 6,0b\n"
: "+d" (reg0), "=d" (reg1), "+d" (reg2),
"+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7),
@@ -836,12 +836,12 @@ static void __ap_flush_queue(struct ap_device *ap_dev)
list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
list_del_init(&ap_msg->list);
ap_dev->pendingq_count--;
- ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+ ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
}
list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
list_del_init(&ap_msg->list);
ap_dev->requestq_count--;
- ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+ ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
}
}
@@ -1329,7 +1329,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
continue;
list_del_init(&ap_msg->list);
ap_dev->pendingq_count--;
- ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply);
+ ap_msg->receive(ap_dev, ap_msg, ap_dev->reply);
break;
}
if (ap_dev->queue_count > 0)
@@ -1450,10 +1450,10 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms
return -EBUSY;
case AP_RESPONSE_REQ_FAC_NOT_INST:
case AP_RESPONSE_MESSAGE_TOO_BIG:
- ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
+ ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
return -EINVAL;
default: /* Device is gone. */
- ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+ ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
return -ENODEV;
}
} else {
@@ -1471,6 +1471,10 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
unsigned long flags;
int rc;
+ /* For asynchronous message handling a valid receive-callback
+ * is required. */
+ BUG_ON(!ap_msg->receive);
+
spin_lock_bh(&ap_dev->lock);
if (!ap_dev->unregistered) {
/* Make room on the queue by polling for finished requests. */
@@ -1482,7 +1486,7 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
if (rc == -ENODEV)
ap_dev->unregistered = 1;
} else {
- ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+ ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
rc = -ENODEV;
}
spin_unlock_bh(&ap_dev->lock);
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index d960a6309eec..726fc65809d8 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -136,9 +136,6 @@ struct ap_driver {
int (*probe)(struct ap_device *);
void (*remove)(struct ap_device *);
- /* receive is called from tasklet context */
- void (*receive)(struct ap_device *, struct ap_message *,
- struct ap_message *);
int request_timeout; /* request timeout in jiffies */
};
@@ -183,6 +180,9 @@ struct ap_message {
void *private; /* ap driver private pointer. */
unsigned int special:1; /* Used for special commands. */
+ /* receive is called from tasklet context */
+ void (*receive)(struct ap_device *, struct ap_message *,
+ struct ap_message *);
};
#define AP_DEVICE(dt) \
@@ -199,6 +199,7 @@ static inline void ap_init_message(struct ap_message *ap_msg)
ap_msg->psmid = 0;
ap_msg->length = 0;
ap_msg->special = 0;
+ ap_msg->receive = NULL;
}
/*
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index 084286728166..46812440425a 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -77,7 +77,6 @@ static void zcrypt_cex2a_receive(struct ap_device *, struct ap_message *,
static struct ap_driver zcrypt_cex2a_driver = {
.probe = zcrypt_cex2a_probe,
.remove = zcrypt_cex2a_remove,
- .receive = zcrypt_cex2a_receive,
.ids = zcrypt_cex2a_ids,
.request_timeout = CEX2A_CLEANUP_TIME,
};
@@ -349,6 +348,7 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev,
ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_cex2a_receive;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg.private = &work;
@@ -390,6 +390,7 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev,
ap_msg.message = kmalloc(CEX3A_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_cex2a_receive;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg.private = &work;
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index 0effca925451..ad7951c21b79 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -67,7 +67,6 @@ static void zcrypt_pcica_receive(struct ap_device *, struct ap_message *,
static struct ap_driver zcrypt_pcica_driver = {
.probe = zcrypt_pcica_probe,
.remove = zcrypt_pcica_remove,
- .receive = zcrypt_pcica_receive,
.ids = zcrypt_pcica_ids,
.request_timeout = PCICA_CLEANUP_TIME,
};
@@ -284,6 +283,7 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev,
ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_pcica_receive;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg.private = &work;
@@ -322,6 +322,7 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev,
ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_pcica_receive;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg.private = &work;
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
index f9523c0cc8d2..e5dd335fda53 100644
--- a/drivers/s390/crypto/zcrypt_pcicc.c
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -79,7 +79,6 @@ static void zcrypt_pcicc_receive(struct ap_device *, struct ap_message *,
static struct ap_driver zcrypt_pcicc_driver = {
.probe = zcrypt_pcicc_probe,
.remove = zcrypt_pcicc_remove,
- .receive = zcrypt_pcicc_receive,
.ids = zcrypt_pcicc_ids,
.request_timeout = PCICC_CLEANUP_TIME,
};
@@ -488,6 +487,7 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev,
ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_pcicc_receive;
ap_msg.length = PAGE_SIZE;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
@@ -527,6 +527,7 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev,
ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_pcicc_receive;
ap_msg.length = PAGE_SIZE;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index cf1cbd4747f4..f7cc43401816 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -89,7 +89,6 @@ static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
static struct ap_driver zcrypt_pcixcc_driver = {
.probe = zcrypt_pcixcc_probe,
.remove = zcrypt_pcixcc_remove,
- .receive = zcrypt_pcixcc_receive,
.ids = zcrypt_pcixcc_ids,
.request_timeout = PCIXCC_CLEANUP_TIME,
};
@@ -698,6 +697,7 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_pcixcc_receive;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg.private = &resp_type;
@@ -738,6 +738,7 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_pcixcc_receive;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg.private = &resp_type;
@@ -778,6 +779,7 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_pcixcc_receive;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg.private = &resp_type;
@@ -818,6 +820,7 @@ static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
if (!ap_msg.message)
return -ENOMEM;
+ ap_msg.receive = zcrypt_pcixcc_receive;
ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg.private = &resp_type;
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index b41fae37d3af..6b1ff90d2f00 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -136,7 +136,6 @@ static inline void
claw_set_busy(struct net_device *dev)
{
((struct claw_privbk *)dev->ml_priv)->tbusy = 1;
- eieio();
}
static inline void
@@ -144,13 +143,11 @@ claw_clear_busy(struct net_device *dev)
{
clear_bit(0, &(((struct claw_privbk *) dev->ml_priv)->tbusy));
netif_wake_queue(dev);
- eieio();
}
static inline int
claw_check_busy(struct net_device *dev)
{
- eieio();
return ((struct claw_privbk *) dev->ml_priv)->tbusy;
}
@@ -233,8 +230,6 @@ static ssize_t claw_rbuff_show(struct device *dev,
static ssize_t claw_rbuff_write(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count);
-static int claw_add_files(struct device *dev);
-static void claw_remove_files(struct device *dev);
/* Functions for System Validate */
static int claw_process_control( struct net_device *dev, struct ccwbk * p_ccw);
@@ -267,12 +262,10 @@ static struct ccwgroup_driver claw_group_driver = {
.owner = THIS_MODULE,
.name = "claw",
},
- .max_slaves = 2,
- .driver_id = 0xC3D3C1E6,
- .probe = claw_probe,
- .remove = claw_remove_device,
- .set_online = claw_new_device,
- .set_offline = claw_shutdown_device,
+ .setup = claw_probe,
+ .remove = claw_remove_device,
+ .set_online = claw_new_device,
+ .set_offline = claw_shutdown_device,
.prepare = claw_pm_prepare,
};
@@ -293,30 +286,24 @@ static struct ccw_driver claw_ccw_driver = {
.int_class = IOINT_CLW,
};
-static ssize_t
-claw_driver_group_store(struct device_driver *ddrv, const char *buf,
- size_t count)
+static ssize_t claw_driver_group_store(struct device_driver *ddrv,
+ const char *buf, size_t count)
{
int err;
- err = ccwgroup_create_from_string(claw_root_dev,
- claw_group_driver.driver_id,
- &claw_ccw_driver, 2, buf);
+ err = ccwgroup_create_dev(claw_root_dev, &claw_group_driver, 2, buf);
return err ? err : count;
}
-
static DRIVER_ATTR(group, 0200, NULL, claw_driver_group_store);
-static struct attribute *claw_group_attrs[] = {
+static struct attribute *claw_drv_attrs[] = {
&driver_attr_group.attr,
NULL,
};
-
-static struct attribute_group claw_group_attr_group = {
- .attrs = claw_group_attrs,
+static struct attribute_group claw_drv_attr_group = {
+ .attrs = claw_drv_attrs,
};
-
-static const struct attribute_group *claw_group_attr_groups[] = {
- &claw_group_attr_group,
+static const struct attribute_group *claw_drv_attr_groups[] = {
+ &claw_drv_attr_group,
NULL,
};
@@ -324,60 +311,6 @@ static const struct attribute_group *claw_group_attr_groups[] = {
* Key functions
*/
-/*----------------------------------------------------------------*
- * claw_probe *
- * this function is called for each CLAW device. *
- *----------------------------------------------------------------*/
-static int
-claw_probe(struct ccwgroup_device *cgdev)
-{
- int rc;
- struct claw_privbk *privptr=NULL;
-
- CLAW_DBF_TEXT(2, setup, "probe");
- if (!get_device(&cgdev->dev))
- return -ENODEV;
- privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL);
- dev_set_drvdata(&cgdev->dev, privptr);
- if (privptr == NULL) {
- probe_error(cgdev);
- put_device(&cgdev->dev);
- CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM);
- return -ENOMEM;
- }
- privptr->p_mtc_envelope= kzalloc( MAX_ENVELOPE_SIZE, GFP_KERNEL);
- privptr->p_env = kzalloc(sizeof(struct claw_env), GFP_KERNEL);
- if ((privptr->p_mtc_envelope==NULL) || (privptr->p_env==NULL)) {
- probe_error(cgdev);
- put_device(&cgdev->dev);
- CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM);
- return -ENOMEM;
- }
- memcpy(privptr->p_env->adapter_name,WS_NAME_NOT_DEF,8);
- memcpy(privptr->p_env->host_name,WS_NAME_NOT_DEF,8);
- memcpy(privptr->p_env->api_type,WS_NAME_NOT_DEF,8);
- privptr->p_env->packing = 0;
- privptr->p_env->write_buffers = 5;
- privptr->p_env->read_buffers = 5;
- privptr->p_env->read_size = CLAW_FRAME_SIZE;
- privptr->p_env->write_size = CLAW_FRAME_SIZE;
- rc = claw_add_files(&cgdev->dev);
- if (rc) {
- probe_error(cgdev);
- put_device(&cgdev->dev);
- dev_err(&cgdev->dev, "Creating the /proc files for a new"
- " CLAW device failed\n");
- CLAW_DBF_TEXT_(2, setup, "probex%d", rc);
- return rc;
- }
- privptr->p_env->p_priv = privptr;
- cgdev->cdev[0]->handler = claw_irq_handler;
- cgdev->cdev[1]->handler = claw_irq_handler;
- CLAW_DBF_TEXT(2, setup, "prbext 0");
-
- return 0;
-} /* end of claw_probe */
-
/*-------------------------------------------------------------------*
* claw_tx *
*-------------------------------------------------------------------*/
@@ -3093,7 +3026,6 @@ claw_remove_device(struct ccwgroup_device *cgdev)
dev_info(&cgdev->dev, " will be removed.\n");
if (cgdev->state == CCWGROUP_ONLINE)
claw_shutdown_device(cgdev);
- claw_remove_files(&cgdev->dev);
kfree(priv->p_mtc_envelope);
priv->p_mtc_envelope=NULL;
kfree(priv->p_env);
@@ -3321,7 +3253,6 @@ claw_rbuff_write(struct device *dev, struct device_attribute *attr,
CLAW_DBF_TEXT_(2, setup, "RB=%d", p_env->read_buffers);
return count;
}
-
static DEVICE_ATTR(read_buffer, 0644, claw_rbuff_show, claw_rbuff_write);
static struct attribute *claw_attr[] = {
@@ -3332,40 +3263,73 @@ static struct attribute *claw_attr[] = {
&dev_attr_host_name.attr,
NULL,
};
-
static struct attribute_group claw_attr_group = {
.attrs = claw_attr,
};
+static const struct attribute_group *claw_attr_groups[] = {
+ &claw_attr_group,
+ NULL,
+};
+static const struct device_type claw_devtype = {
+ .name = "claw",
+ .groups = claw_attr_groups,
+};
-static int
-claw_add_files(struct device *dev)
+/*----------------------------------------------------------------*
+ * claw_probe *
+ * this function is called for each CLAW device. *
+ *----------------------------------------------------------------*/
+static int claw_probe(struct ccwgroup_device *cgdev)
{
- CLAW_DBF_TEXT(2, setup, "add_file");
- return sysfs_create_group(&dev->kobj, &claw_attr_group);
-}
+ struct claw_privbk *privptr = NULL;
-static void
-claw_remove_files(struct device *dev)
-{
- CLAW_DBF_TEXT(2, setup, "rem_file");
- sysfs_remove_group(&dev->kobj, &claw_attr_group);
-}
+ CLAW_DBF_TEXT(2, setup, "probe");
+ if (!get_device(&cgdev->dev))
+ return -ENODEV;
+ privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL);
+ dev_set_drvdata(&cgdev->dev, privptr);
+ if (privptr == NULL) {
+ probe_error(cgdev);
+ put_device(&cgdev->dev);
+ CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM);
+ return -ENOMEM;
+ }
+ privptr->p_mtc_envelope = kzalloc(MAX_ENVELOPE_SIZE, GFP_KERNEL);
+ privptr->p_env = kzalloc(sizeof(struct claw_env), GFP_KERNEL);
+ if ((privptr->p_mtc_envelope == NULL) || (privptr->p_env == NULL)) {
+ probe_error(cgdev);
+ put_device(&cgdev->dev);
+ CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM);
+ return -ENOMEM;
+ }
+ memcpy(privptr->p_env->adapter_name, WS_NAME_NOT_DEF, 8);
+ memcpy(privptr->p_env->host_name, WS_NAME_NOT_DEF, 8);
+ memcpy(privptr->p_env->api_type, WS_NAME_NOT_DEF, 8);
+ privptr->p_env->packing = 0;
+ privptr->p_env->write_buffers = 5;
+ privptr->p_env->read_buffers = 5;
+ privptr->p_env->read_size = CLAW_FRAME_SIZE;
+ privptr->p_env->write_size = CLAW_FRAME_SIZE;
+ privptr->p_env->p_priv = privptr;
+ cgdev->cdev[0]->handler = claw_irq_handler;
+ cgdev->cdev[1]->handler = claw_irq_handler;
+ cgdev->dev.type = &claw_devtype;
+ CLAW_DBF_TEXT(2, setup, "prbext 0");
+
+ return 0;
+} /* end of claw_probe */
/*--------------------------------------------------------------------*
* claw_init and cleanup *
*---------------------------------------------------------------------*/
-static void __exit
-claw_cleanup(void)
+static void __exit claw_cleanup(void)
{
- driver_remove_file(&claw_group_driver.driver,
- &driver_attr_group);
ccwgroup_driver_unregister(&claw_group_driver);
ccw_driver_unregister(&claw_ccw_driver);
root_device_unregister(claw_root_dev);
claw_unregister_debug_facility();
pr_info("Driver unloaded\n");
-
}
/**
@@ -3374,8 +3338,7 @@ claw_cleanup(void)
*
* @return 0 on success, !0 on error.
*/
-static int __init
-claw_init(void)
+static int __init claw_init(void)
{
int ret = 0;
@@ -3394,7 +3357,7 @@ claw_init(void)
ret = ccw_driver_register(&claw_ccw_driver);
if (ret)
goto ccw_err;
- claw_group_driver.driver.groups = claw_group_attr_groups;
+ claw_group_driver.driver.groups = claw_drv_attr_groups;
ret = ccwgroup_driver_register(&claw_group_driver);
if (ret)
goto ccwgroup_err;
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 11f3b071f305..3cd25544a27a 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1296,6 +1296,11 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
}
+static const struct device_type ctcm_devtype = {
+ .name = "ctcm",
+ .groups = ctcm_attr_groups,
+};
+
/**
* Add ctcm specific attributes.
* Add ctcm private data.
@@ -1307,7 +1312,6 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
static int ctcm_probe_device(struct ccwgroup_device *cgdev)
{
struct ctcm_priv *priv;
- int rc;
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
"%s %p",
@@ -1324,17 +1328,11 @@ static int ctcm_probe_device(struct ccwgroup_device *cgdev)
put_device(&cgdev->dev);
return -ENOMEM;
}
-
- rc = ctcm_add_files(&cgdev->dev);
- if (rc) {
- kfree(priv);
- put_device(&cgdev->dev);
- return rc;
- }
priv->buffer_size = CTCM_BUFSIZE_DEFAULT;
cgdev->cdev[0]->handler = ctcm_irq_handler;
cgdev->cdev[1]->handler = ctcm_irq_handler;
dev_set_drvdata(&cgdev->dev, priv);
+ cgdev->dev.type = &ctcm_devtype;
return 0;
}
@@ -1611,11 +1609,6 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
goto out_dev;
}
- if (ctcm_add_attributes(&cgdev->dev)) {
- result = -ENODEV;
- goto out_unregister;
- }
-
strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name));
dev_info(&dev->dev,
@@ -1629,8 +1622,6 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
priv->channel[CTCM_WRITE]->id, priv->protocol);
return 0;
-out_unregister:
- unregister_netdev(dev);
out_dev:
ctcm_free_netdevice(dev);
out_ccw2:
@@ -1669,7 +1660,6 @@ static int ctcm_shutdown_device(struct ccwgroup_device *cgdev)
/* Close the device */
ctcm_close(dev);
dev->flags &= ~IFF_RUNNING;
- ctcm_remove_attributes(&cgdev->dev);
channel_free(priv->channel[CTCM_READ]);
} else
dev = NULL;
@@ -1711,7 +1701,6 @@ static void ctcm_remove_device(struct ccwgroup_device *cgdev)
if (cgdev->state == CCWGROUP_ONLINE)
ctcm_shutdown_device(cgdev);
- ctcm_remove_files(&cgdev->dev);
dev_set_drvdata(&cgdev->dev, NULL);
kfree(priv);
put_device(&cgdev->dev);
@@ -1778,9 +1767,7 @@ static struct ccwgroup_driver ctcm_group_driver = {
.owner = THIS_MODULE,
.name = CTC_DRIVER_NAME,
},
- .max_slaves = 2,
- .driver_id = 0xC3E3C3D4, /* CTCM */
- .probe = ctcm_probe_device,
+ .setup = ctcm_probe_device,
.remove = ctcm_remove_device,
.set_online = ctcm_new_device,
.set_offline = ctcm_shutdown_device,
@@ -1789,31 +1776,25 @@ static struct ccwgroup_driver ctcm_group_driver = {
.restore = ctcm_pm_resume,
};
-static ssize_t
-ctcm_driver_group_store(struct device_driver *ddrv, const char *buf,
- size_t count)
+static ssize_t ctcm_driver_group_store(struct device_driver *ddrv,
+ const char *buf, size_t count)
{
int err;
- err = ccwgroup_create_from_string(ctcm_root_dev,
- ctcm_group_driver.driver_id,
- &ctcm_ccw_driver, 2, buf);
+ err = ccwgroup_create_dev(ctcm_root_dev, &ctcm_group_driver, 2, buf);
return err ? err : count;
}
-
static DRIVER_ATTR(group, 0200, NULL, ctcm_driver_group_store);
-static struct attribute *ctcm_group_attrs[] = {
+static struct attribute *ctcm_drv_attrs[] = {
&driver_attr_group.attr,
NULL,
};
-
-static struct attribute_group ctcm_group_attr_group = {
- .attrs = ctcm_group_attrs,
+static struct attribute_group ctcm_drv_attr_group = {
+ .attrs = ctcm_drv_attrs,
};
-
-static const struct attribute_group *ctcm_group_attr_groups[] = {
- &ctcm_group_attr_group,
+static const struct attribute_group *ctcm_drv_attr_groups[] = {
+ &ctcm_drv_attr_group,
NULL,
};
@@ -1829,7 +1810,6 @@ static const struct attribute_group *ctcm_group_attr_groups[] = {
*/
static void __exit ctcm_exit(void)
{
- driver_remove_file(&ctcm_group_driver.driver, &driver_attr_group);
ccwgroup_driver_unregister(&ctcm_group_driver);
ccw_driver_unregister(&ctcm_ccw_driver);
root_device_unregister(ctcm_root_dev);
@@ -1867,7 +1847,7 @@ static int __init ctcm_init(void)
ret = ccw_driver_register(&ctcm_ccw_driver);
if (ret)
goto ccw_err;
- ctcm_group_driver.driver.groups = ctcm_group_attr_groups;
+ ctcm_group_driver.driver.groups = ctcm_drv_attr_groups;
ret = ccwgroup_driver_register(&ctcm_group_driver);
if (ret)
goto ccwgroup_err;
diff --git a/drivers/s390/net/ctcm_main.h b/drivers/s390/net/ctcm_main.h
index 24d5215eb0c4..b9056a55d995 100644
--- a/drivers/s390/net/ctcm_main.h
+++ b/drivers/s390/net/ctcm_main.h
@@ -225,13 +225,7 @@ struct ctcm_priv {
int ctcm_open(struct net_device *dev);
int ctcm_close(struct net_device *dev);
-/*
- * prototypes for non-static sysfs functions
- */
-int ctcm_add_attributes(struct device *dev);
-void ctcm_remove_attributes(struct device *dev);
-int ctcm_add_files(struct device *dev);
-void ctcm_remove_files(struct device *dev);
+extern const struct attribute_group *ctcm_attr_groups[];
/*
* Compatibility macros for busy handling
diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c
index 650aec1839e9..0c27ae726475 100644
--- a/drivers/s390/net/ctcm_sysfs.c
+++ b/drivers/s390/net/ctcm_sysfs.c
@@ -13,6 +13,7 @@
#define KMSG_COMPONENT "ctcm"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/device.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include "ctcm_main.h"
@@ -108,10 +109,12 @@ static void ctcm_print_statistics(struct ctcm_priv *priv)
}
static ssize_t stats_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
+ struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
struct ctcm_priv *priv = dev_get_drvdata(dev);
- if (!priv)
+
+ if (!priv || gdev->state != CCWGROUP_ONLINE)
return -ENODEV;
ctcm_print_statistics(priv);
return sprintf(buf, "0\n");
@@ -190,34 +193,14 @@ static struct attribute *ctcm_attr[] = {
&dev_attr_protocol.attr,
&dev_attr_type.attr,
&dev_attr_buffer.attr,
+ &dev_attr_stats.attr,
NULL,
};
static struct attribute_group ctcm_attr_group = {
.attrs = ctcm_attr,
};
-
-int ctcm_add_attributes(struct device *dev)
-{
- int rc;
-
- rc = device_create_file(dev, &dev_attr_stats);
-
- return rc;
-}
-
-void ctcm_remove_attributes(struct device *dev)
-{
- device_remove_file(dev, &dev_attr_stats);
-}
-
-int ctcm_add_files(struct device *dev)
-{
- return sysfs_create_group(&dev->kobj, &ctcm_attr_group);
-}
-
-void ctcm_remove_files(struct device *dev)
-{
- sysfs_remove_group(&dev->kobj, &ctcm_attr_group);
-}
-
+const struct attribute_group *ctcm_attr_groups[] = {
+ &ctcm_attr_group,
+ NULL,
+};
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 6056cf6da035..a3adf4b1c60d 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -2040,10 +2040,17 @@ static struct attribute * lcs_attrs[] = {
&dev_attr_recover.attr,
NULL,
};
-
static struct attribute_group lcs_attr_group = {
.attrs = lcs_attrs,
};
+static const struct attribute_group *lcs_attr_groups[] = {
+ &lcs_attr_group,
+ NULL,
+};
+static const struct device_type lcs_devtype = {
+ .name = "lcs",
+ .groups = lcs_attr_groups,
+};
/**
* lcs_probe_device is called on establishing a new ccwgroup_device.
@@ -2052,7 +2059,6 @@ static int
lcs_probe_device(struct ccwgroup_device *ccwgdev)
{
struct lcs_card *card;
- int ret;
if (!get_device(&ccwgdev->dev))
return -ENODEV;
@@ -2064,12 +2070,6 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev)
put_device(&ccwgdev->dev);
return -ENOMEM;
}
- ret = sysfs_create_group(&ccwgdev->dev.kobj, &lcs_attr_group);
- if (ret) {
- lcs_free_card(card);
- put_device(&ccwgdev->dev);
- return ret;
- }
dev_set_drvdata(&ccwgdev->dev, card);
ccwgdev->cdev[0]->handler = lcs_irq;
ccwgdev->cdev[1]->handler = lcs_irq;
@@ -2078,7 +2078,9 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev)
card->thread_start_mask = 0;
card->thread_allowed_mask = 0;
card->thread_running_mask = 0;
- return 0;
+ ccwgdev->dev.type = &lcs_devtype;
+
+ return 0;
}
static int
@@ -2306,9 +2308,9 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev)
}
if (card->dev)
unregister_netdev(card->dev);
- sysfs_remove_group(&ccwgdev->dev.kobj, &lcs_attr_group);
lcs_cleanup_card(card);
lcs_free_card(card);
+ dev_set_drvdata(&ccwgdev->dev, NULL);
put_device(&ccwgdev->dev);
}
@@ -2393,9 +2395,7 @@ static struct ccwgroup_driver lcs_group_driver = {
.owner = THIS_MODULE,
.name = "lcs",
},
- .max_slaves = 2,
- .driver_id = 0xD3C3E2,
- .probe = lcs_probe_device,
+ .setup = lcs_probe_device,
.remove = lcs_remove_device,
.set_online = lcs_new_device,
.set_offline = lcs_shutdown_device,
@@ -2406,30 +2406,24 @@ static struct ccwgroup_driver lcs_group_driver = {
.restore = lcs_restore,
};
-static ssize_t
-lcs_driver_group_store(struct device_driver *ddrv, const char *buf,
- size_t count)
+static ssize_t lcs_driver_group_store(struct device_driver *ddrv,
+ const char *buf, size_t count)
{
int err;
- err = ccwgroup_create_from_string(lcs_root_dev,
- lcs_group_driver.driver_id,
- &lcs_ccw_driver, 2, buf);
+ err = ccwgroup_create_dev(lcs_root_dev, &lcs_group_driver, 2, buf);
return err ? err : count;
}
-
static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store);
-static struct attribute *lcs_group_attrs[] = {
+static struct attribute *lcs_drv_attrs[] = {
&driver_attr_group.attr,
NULL,
};
-
-static struct attribute_group lcs_group_attr_group = {
- .attrs = lcs_group_attrs,
+static struct attribute_group lcs_drv_attr_group = {
+ .attrs = lcs_drv_attrs,
};
-
-static const struct attribute_group *lcs_group_attr_groups[] = {
- &lcs_group_attr_group,
+static const struct attribute_group *lcs_drv_attr_groups[] = {
+ &lcs_drv_attr_group,
NULL,
};
@@ -2453,7 +2447,7 @@ __init lcs_init_module(void)
rc = ccw_driver_register(&lcs_ccw_driver);
if (rc)
goto ccw_err;
- lcs_group_driver.driver.groups = lcs_group_attr_groups;
+ lcs_group_driver.driver.groups = lcs_drv_attr_groups;
rc = ccwgroup_driver_register(&lcs_group_driver);
if (rc)
goto ccwgroup_err;
@@ -2479,8 +2473,6 @@ __exit lcs_cleanup_module(void)
{
pr_info("Terminating lcs module.\n");
LCS_DBF_TEXT(0, trace, "cleanup");
- driver_remove_file(&lcs_group_driver.driver,
- &driver_attr_group);
ccwgroup_driver_unregister(&lcs_group_driver);
ccw_driver_unregister(&lcs_ccw_driver);
root_device_unregister(lcs_root_dev);
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 40285dc9ae5c..06e8f31ff3dc 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -707,7 +707,16 @@ struct qeth_discipline {
qdio_handler_t *input_handler;
qdio_handler_t *output_handler;
int (*recover)(void *ptr);
- struct ccwgroup_driver *ccwgdriver;
+ int (*setup) (struct ccwgroup_device *);
+ void (*remove) (struct ccwgroup_device *);
+ int (*set_online) (struct ccwgroup_device *);
+ int (*set_offline) (struct ccwgroup_device *);
+ void (*shutdown)(struct ccwgroup_device *);
+ int (*prepare) (struct ccwgroup_device *);
+ void (*complete) (struct ccwgroup_device *);
+ int (*freeze)(struct ccwgroup_device *);
+ int (*thaw) (struct ccwgroup_device *);
+ int (*restore)(struct ccwgroup_device *);
};
struct qeth_vlan_vid {
@@ -771,7 +780,7 @@ struct qeth_card {
struct qeth_perf_stats perf_stats;
int read_or_write_problem;
struct qeth_osn_info osn_info;
- struct qeth_discipline discipline;
+ struct qeth_discipline *discipline;
atomic_t force_alloc_skb;
struct service_level qeth_service_level;
struct qdio_ssqd_desc ssqd;
@@ -837,16 +846,15 @@ static inline int qeth_is_diagass_supported(struct qeth_card *card,
return card->info.diagass_support & (__u32)cmd;
}
-extern struct ccwgroup_driver qeth_l2_ccwgroup_driver;
-extern struct ccwgroup_driver qeth_l3_ccwgroup_driver;
+extern struct qeth_discipline qeth_l2_discipline;
+extern struct qeth_discipline qeth_l3_discipline;
+extern const struct attribute_group *qeth_generic_attr_groups[];
+extern const struct attribute_group *qeth_osn_attr_groups[];
+
const char *qeth_get_cardname_short(struct qeth_card *);
int qeth_realloc_buffer_pool(struct qeth_card *, int);
int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id);
void qeth_core_free_discipline(struct qeth_card *);
-int qeth_core_create_device_attributes(struct device *);
-void qeth_core_remove_device_attributes(struct device *);
-int qeth_core_create_osn_attributes(struct device *);
-void qeth_core_remove_osn_attributes(struct device *);
void qeth_buffer_reclaim_work(struct work_struct *);
/* exports for qeth discipline device drivers */
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index e000001539bf..e118e1e1e1c1 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -1363,7 +1363,7 @@ static void qeth_start_kernel_thread(struct work_struct *work)
card->write.state != CH_STATE_UP)
return;
if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) {
- ts = kthread_run(card->discipline.recover, (void *)card,
+ ts = kthread_run(card->discipline->recover, (void *)card,
"qeth_recover");
if (IS_ERR(ts)) {
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
@@ -3337,7 +3337,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
if (rc) {
queue->card->stats.tx_errors += count;
/* ignore temporary SIGA errors without busy condition */
- if (rc == QDIO_ERROR_SIGA_TARGET)
+ if (rc == -ENOBUFS)
return;
QETH_CARD_TEXT(queue->card, 2, "flushbuf");
QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no);
@@ -3531,7 +3531,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
int i;
QETH_CARD_TEXT(card, 6, "qdouhdl");
- if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
+ if (qdio_error & QDIO_ERROR_FATAL) {
QETH_CARD_TEXT(card, 2, "achkcond");
netif_stop_queue(card->dev);
qeth_schedule_recovery(card);
@@ -4627,7 +4627,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
goto out_free_in_sbals;
}
for (i = 0; i < card->qdio.no_in_queues; ++i)
- queue_start_poll[i] = card->discipline.start_poll;
+ queue_start_poll[i] = card->discipline->start_poll;
qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll);
@@ -4651,8 +4651,8 @@ static int qeth_qdio_establish(struct qeth_card *card)
init_data.qib_param_field = qib_param_field;
init_data.no_input_qs = card->qdio.no_in_queues;
init_data.no_output_qs = card->qdio.no_out_queues;
- init_data.input_handler = card->discipline.input_handler;
- init_data.output_handler = card->discipline.output_handler;
+ init_data.input_handler = card->discipline->input_handler;
+ init_data.output_handler = card->discipline->output_handler;
init_data.queue_start_poll_array = queue_start_poll;
init_data.int_parm = (unsigned long) card;
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
@@ -4737,13 +4737,6 @@ static struct ccw_driver qeth_ccw_driver = {
.remove = ccwgroup_remove_ccwdev,
};
-static int qeth_core_driver_group(const char *buf, struct device *root_dev,
- unsigned long driver_id)
-{
- return ccwgroup_create_from_string(root_dev, driver_id,
- &qeth_ccw_driver, 3, buf);
-}
-
int qeth_core_hardsetup_card(struct qeth_card *card)
{
int retries = 0;
@@ -5040,17 +5033,15 @@ int qeth_core_load_discipline(struct qeth_card *card,
mutex_lock(&qeth_mod_mutex);
switch (discipline) {
case QETH_DISCIPLINE_LAYER3:
- card->discipline.ccwgdriver = try_then_request_module(
- symbol_get(qeth_l3_ccwgroup_driver),
- "qeth_l3");
+ card->discipline = try_then_request_module(
+ symbol_get(qeth_l3_discipline), "qeth_l3");
break;
case QETH_DISCIPLINE_LAYER2:
- card->discipline.ccwgdriver = try_then_request_module(
- symbol_get(qeth_l2_ccwgroup_driver),
- "qeth_l2");
+ card->discipline = try_then_request_module(
+ symbol_get(qeth_l2_discipline), "qeth_l2");
break;
}
- if (!card->discipline.ccwgdriver) {
+ if (!card->discipline) {
dev_err(&card->gdev->dev, "There is no kernel module to "
"support discipline %d\n", discipline);
rc = -EINVAL;
@@ -5062,12 +5053,21 @@ int qeth_core_load_discipline(struct qeth_card *card,
void qeth_core_free_discipline(struct qeth_card *card)
{
if (card->options.layer2)
- symbol_put(qeth_l2_ccwgroup_driver);
+ symbol_put(qeth_l2_discipline);
else
- symbol_put(qeth_l3_ccwgroup_driver);
- card->discipline.ccwgdriver = NULL;
+ symbol_put(qeth_l3_discipline);
+ card->discipline = NULL;
}
+static const struct device_type qeth_generic_devtype = {
+ .name = "qeth_generic",
+ .groups = qeth_generic_attr_groups,
+};
+static const struct device_type qeth_osn_devtype = {
+ .name = "qeth_osn",
+ .groups = qeth_osn_attr_groups,
+};
+
static int qeth_core_probe_device(struct ccwgroup_device *gdev)
{
struct qeth_card *card;
@@ -5122,18 +5122,17 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
}
if (card->info.type == QETH_CARD_TYPE_OSN)
- rc = qeth_core_create_osn_attributes(dev);
+ gdev->dev.type = &qeth_osn_devtype;
else
- rc = qeth_core_create_device_attributes(dev);
- if (rc)
- goto err_dbf;
+ gdev->dev.type = &qeth_generic_devtype;
+
switch (card->info.type) {
case QETH_CARD_TYPE_OSN:
case QETH_CARD_TYPE_OSM:
rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2);
if (rc)
- goto err_attr;
- rc = card->discipline.ccwgdriver->probe(card->gdev);
+ goto err_dbf;
+ rc = card->discipline->setup(card->gdev);
if (rc)
goto err_disc;
case QETH_CARD_TYPE_OSD:
@@ -5151,11 +5150,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
err_disc:
qeth_core_free_discipline(card);
-err_attr:
- if (card->info.type == QETH_CARD_TYPE_OSN)
- qeth_core_remove_osn_attributes(dev);
- else
- qeth_core_remove_device_attributes(dev);
err_dbf:
debug_unregister(card->debug);
err_card:
@@ -5172,14 +5166,8 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
QETH_DBF_TEXT(SETUP, 2, "removedv");
- if (card->info.type == QETH_CARD_TYPE_OSN) {
- qeth_core_remove_osn_attributes(&gdev->dev);
- } else {
- qeth_core_remove_device_attributes(&gdev->dev);
- }
-
- if (card->discipline.ccwgdriver) {
- card->discipline.ccwgdriver->remove(gdev);
+ if (card->discipline) {
+ card->discipline->remove(gdev);
qeth_core_free_discipline(card);
}
@@ -5199,7 +5187,7 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
int rc = 0;
int def_discipline;
- if (!card->discipline.ccwgdriver) {
+ if (!card->discipline) {
if (card->info.type == QETH_CARD_TYPE_IQD)
def_discipline = QETH_DISCIPLINE_LAYER3;
else
@@ -5207,11 +5195,11 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
rc = qeth_core_load_discipline(card, def_discipline);
if (rc)
goto err;
- rc = card->discipline.ccwgdriver->probe(card->gdev);
+ rc = card->discipline->setup(card->gdev);
if (rc)
goto err;
}
- rc = card->discipline.ccwgdriver->set_online(gdev);
+ rc = card->discipline->set_online(gdev);
err:
return rc;
}
@@ -5219,58 +5207,52 @@ err:
static int qeth_core_set_offline(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
- return card->discipline.ccwgdriver->set_offline(gdev);
+ return card->discipline->set_offline(gdev);
}
static void qeth_core_shutdown(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
- if (card->discipline.ccwgdriver &&
- card->discipline.ccwgdriver->shutdown)
- card->discipline.ccwgdriver->shutdown(gdev);
+ if (card->discipline && card->discipline->shutdown)
+ card->discipline->shutdown(gdev);
}
static int qeth_core_prepare(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
- if (card->discipline.ccwgdriver &&
- card->discipline.ccwgdriver->prepare)
- return card->discipline.ccwgdriver->prepare(gdev);
+ if (card->discipline && card->discipline->prepare)
+ return card->discipline->prepare(gdev);
return 0;
}
static void qeth_core_complete(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
- if (card->discipline.ccwgdriver &&
- card->discipline.ccwgdriver->complete)
- card->discipline.ccwgdriver->complete(gdev);
+ if (card->discipline && card->discipline->complete)
+ card->discipline->complete(gdev);
}
static int qeth_core_freeze(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
- if (card->discipline.ccwgdriver &&
- card->discipline.ccwgdriver->freeze)
- return card->discipline.ccwgdriver->freeze(gdev);
+ if (card->discipline && card->discipline->freeze)
+ return card->discipline->freeze(gdev);
return 0;
}
static int qeth_core_thaw(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
- if (card->discipline.ccwgdriver &&
- card->discipline.ccwgdriver->thaw)
- return card->discipline.ccwgdriver->thaw(gdev);
+ if (card->discipline && card->discipline->thaw)
+ return card->discipline->thaw(gdev);
return 0;
}
static int qeth_core_restore(struct ccwgroup_device *gdev)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
- if (card->discipline.ccwgdriver &&
- card->discipline.ccwgdriver->restore)
- return card->discipline.ccwgdriver->restore(gdev);
+ if (card->discipline && card->discipline->restore)
+ return card->discipline->restore(gdev);
return 0;
}
@@ -5279,8 +5261,7 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
.owner = THIS_MODULE,
.name = "qeth",
},
- .driver_id = 0xD8C5E3C8,
- .probe = qeth_core_probe_device,
+ .setup = qeth_core_probe_device,
.remove = qeth_core_remove_device,
.set_online = qeth_core_set_online,
.set_offline = qeth_core_set_offline,
@@ -5292,21 +5273,30 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
.restore = qeth_core_restore,
};
-static ssize_t
-qeth_core_driver_group_store(struct device_driver *ddrv, const char *buf,
- size_t count)
+static ssize_t qeth_core_driver_group_store(struct device_driver *ddrv,
+ const char *buf, size_t count)
{
int err;
- err = qeth_core_driver_group(buf, qeth_core_root_dev,
- qeth_core_ccwgroup_driver.driver_id);
- if (err)
- return err;
- else
- return count;
-}
+ err = ccwgroup_create_dev(qeth_core_root_dev,
+ &qeth_core_ccwgroup_driver, 3, buf);
+
+ return err ? err : count;
+}
static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store);
+static struct attribute *qeth_drv_attrs[] = {
+ &driver_attr_group.attr,
+ NULL,
+};
+static struct attribute_group qeth_drv_attr_group = {
+ .attrs = qeth_drv_attrs,
+};
+static const struct attribute_group *qeth_drv_attr_groups[] = {
+ &qeth_drv_attr_group,
+ NULL,
+};
+
static struct {
const char str[ETH_GSTRING_LEN];
} qeth_ethtool_stats_keys[] = {
@@ -5544,49 +5534,41 @@ static int __init qeth_core_init(void)
rc = qeth_register_dbf_views();
if (rc)
goto out_err;
- rc = ccw_driver_register(&qeth_ccw_driver);
- if (rc)
- goto ccw_err;
- rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver);
- if (rc)
- goto ccwgroup_err;
- rc = driver_create_file(&qeth_core_ccwgroup_driver.driver,
- &driver_attr_group);
- if (rc)
- goto driver_err;
qeth_core_root_dev = root_device_register("qeth");
rc = IS_ERR(qeth_core_root_dev) ? PTR_ERR(qeth_core_root_dev) : 0;
if (rc)
goto register_err;
-
qeth_core_header_cache = kmem_cache_create("qeth_hdr",
sizeof(struct qeth_hdr) + ETH_HLEN, 64, 0, NULL);
if (!qeth_core_header_cache) {
rc = -ENOMEM;
goto slab_err;
}
-
qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf",
sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL);
if (!qeth_qdio_outbuf_cache) {
rc = -ENOMEM;
goto cqslab_err;
}
+ rc = ccw_driver_register(&qeth_ccw_driver);
+ if (rc)
+ goto ccw_err;
+ qeth_core_ccwgroup_driver.driver.groups = qeth_drv_attr_groups;
+ rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver);
+ if (rc)
+ goto ccwgroup_err;
return 0;
+
+ccwgroup_err:
+ ccw_driver_unregister(&qeth_ccw_driver);
+ccw_err:
+ kmem_cache_destroy(qeth_qdio_outbuf_cache);
cqslab_err:
kmem_cache_destroy(qeth_core_header_cache);
slab_err:
root_device_unregister(qeth_core_root_dev);
register_err:
- driver_remove_file(&qeth_core_ccwgroup_driver.driver,
- &driver_attr_group);
-driver_err:
- ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
-ccwgroup_err:
- ccw_driver_unregister(&qeth_ccw_driver);
-ccw_err:
- QETH_DBF_MESSAGE(2, "Initialization failed with code %d\n", rc);
qeth_unregister_dbf_views();
out_err:
pr_err("Initializing the qeth device driver failed\n");
@@ -5595,13 +5577,11 @@ out_err:
static void __exit qeth_core_exit(void)
{
- root_device_unregister(qeth_core_root_dev);
- driver_remove_file(&qeth_core_ccwgroup_driver.driver,
- &driver_attr_group);
ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
ccw_driver_unregister(&qeth_ccw_driver);
kmem_cache_destroy(qeth_qdio_outbuf_cache);
kmem_cache_destroy(qeth_core_header_cache);
+ root_device_unregister(qeth_core_root_dev);
qeth_unregister_dbf_views();
pr_info("core functions removed\n");
}
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 0a8e86c1b0ea..f163af575c48 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -434,8 +434,8 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
goto out;
else {
card->info.mac_bits = 0;
- if (card->discipline.ccwgdriver) {
- card->discipline.ccwgdriver->remove(card->gdev);
+ if (card->discipline) {
+ card->discipline->remove(card->gdev);
qeth_core_free_discipline(card);
}
}
@@ -444,7 +444,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
if (rc)
goto out;
- rc = card->discipline.ccwgdriver->probe(card->gdev);
+ rc = card->discipline->setup(card->gdev);
out:
mutex_unlock(&card->discipline_mutex);
return rc ? rc : count;
@@ -693,7 +693,6 @@ static struct attribute *qeth_blkt_device_attrs[] = {
&dev_attr_inter_jumbo.attr,
NULL,
};
-
static struct attribute_group qeth_device_blkt_group = {
.name = "blkt",
.attrs = qeth_blkt_device_attrs,
@@ -716,11 +715,16 @@ static struct attribute *qeth_device_attrs[] = {
&dev_attr_hw_trap.attr,
NULL,
};
-
static struct attribute_group qeth_device_attr_group = {
.attrs = qeth_device_attrs,
};
+const struct attribute_group *qeth_generic_attr_groups[] = {
+ &qeth_device_attr_group,
+ &qeth_device_blkt_group,
+ NULL,
+};
+
static struct attribute *qeth_osn_device_attrs[] = {
&dev_attr_state.attr,
&dev_attr_chpid.attr,
@@ -730,37 +734,10 @@ static struct attribute *qeth_osn_device_attrs[] = {
&dev_attr_recover.attr,
NULL,
};
-
static struct attribute_group qeth_osn_device_attr_group = {
.attrs = qeth_osn_device_attrs,
};
-
-int qeth_core_create_device_attributes(struct device *dev)
-{
- int ret;
- ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group);
- if (ret)
- return ret;
- ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group);
- if (ret)
- sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
-
- return 0;
-}
-
-void qeth_core_remove_device_attributes(struct device *dev)
-{
- sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
- sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group);
-}
-
-int qeth_core_create_osn_attributes(struct device *dev)
-{
- return sysfs_create_group(&dev->kobj, &qeth_osn_device_attr_group);
-}
-
-void qeth_core_remove_osn_attributes(struct device *dev)
-{
- sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group);
- return;
-}
+const struct attribute_group *qeth_osn_attr_groups[] = {
+ &qeth_osn_device_attr_group,
+ NULL,
+};
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 0e7c29d1d7ef..426986518e96 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -882,12 +882,6 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
INIT_LIST_HEAD(&card->mc_list);
card->options.layer2 = 1;
card->info.hwtrap = 0;
- card->discipline.start_poll = qeth_qdio_start_poll;
- card->discipline.input_handler = (qdio_handler_t *)
- qeth_qdio_input_handler;
- card->discipline.output_handler = (qdio_handler_t *)
- qeth_qdio_output_handler;
- card->discipline.recover = qeth_l2_recover;
return 0;
}
@@ -1227,8 +1221,12 @@ out:
return rc;
}
-struct ccwgroup_driver qeth_l2_ccwgroup_driver = {
- .probe = qeth_l2_probe_device,
+struct qeth_discipline qeth_l2_discipline = {
+ .start_poll = qeth_qdio_start_poll,
+ .input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
+ .output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
+ .recover = qeth_l2_recover,
+ .setup = qeth_l2_probe_device,
.remove = qeth_l2_remove_device,
.set_online = qeth_l2_set_online,
.set_offline = qeth_l2_set_offline,
@@ -1237,7 +1235,7 @@ struct ccwgroup_driver qeth_l2_ccwgroup_driver = {
.thaw = qeth_l2_pm_resume,
.restore = qeth_l2_pm_resume,
};
-EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver);
+EXPORT_SYMBOL_GPL(qeth_l2_discipline);
static int qeth_osn_send_control_data(struct qeth_card *card, int len,
struct qeth_cmd_buffer *iob)
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index e7ad03209cb2..7be5e9775691 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -3298,12 +3298,6 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
qeth_l3_create_device_attributes(&gdev->dev);
card->options.layer2 = 0;
card->info.hwtrap = 0;
- card->discipline.start_poll = qeth_qdio_start_poll;
- card->discipline.input_handler = (qdio_handler_t *)
- qeth_qdio_input_handler;
- card->discipline.output_handler = (qdio_handler_t *)
- qeth_qdio_output_handler;
- card->discipline.recover = qeth_l3_recover;
return 0;
}
@@ -3578,8 +3572,12 @@ out:
return rc;
}
-struct ccwgroup_driver qeth_l3_ccwgroup_driver = {
- .probe = qeth_l3_probe_device,
+struct qeth_discipline qeth_l3_discipline = {
+ .start_poll = qeth_qdio_start_poll,
+ .input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
+ .output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
+ .recover = qeth_l3_recover,
+ .setup = qeth_l3_probe_device,
.remove = qeth_l3_remove_device,
.set_online = qeth_l3_set_online,
.set_offline = qeth_l3_set_offline,
@@ -3588,7 +3586,7 @@ struct ccwgroup_driver qeth_l3_ccwgroup_driver = {
.thaw = qeth_l3_pm_resume,
.restore = qeth_l3_pm_resume,
};
-EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver);
+EXPORT_SYMBOL_GPL(qeth_l3_discipline);
static int qeth_l3_ip_event(struct notifier_block *this,
unsigned long event, void *ptr)