s390 patches against 2.6.23-rc2
Subsystems (5)
cover s390 patches against 2.6.23-rc2
The current set of s390 patches against 2.6.23-rc2. The first 10 patches are bug fixes that should go into 2.6.23, the remaining 8 are cleanups and can wait.
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 1/18 cio: avoid memory leak on error in css_alloc_subchannel().
From: Cornelia Huck <[email protected]>
sch->lock has been allocated in cio_validate_subchannel(), it must be freed if cio_modify() fails.
---
drivers/s390/cio/css.c | 1 + 1 file changed, 1 insertion(+)
drivers/s390/cio/css.c +1 -0
@@ -79,6 +79,7 @@ css_alloc_subchannel(struct subchannel_i sch->schib.pmcw.intparm = (__u32 )(unsigned long )sch; ret =cio_modify (sch);if (ret) { +kfree (sch->lock);kfree (sch);return ERR_PTR (ret); }
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 2/18 hypfs: implement show_options
In reply to Martin SchwidefskyFrom: Michael Holzheu <[email protected]>
---
arch/s390/hypfs/inode.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
arch/s390/hypfs/inode.c +12 -0
@@ -17,6 +17,8 @@#include <linux/parser.h> #include <linux/sysfs.h> #include <linux/module.h> +#include <linux/seq_file.h> +#include <linux/mount.h> #include <asm/ebcdic.h> #include "hypfs.h"
@@ -256,6 +258,15 @@ static int hypfs_parse_options(char *optreturn 0 ; } +static int hypfs_show_options (struct seq_file *s,struct vfsmount *mnt) +{ +struct hypfs_sb_info *hypfs_info = mnt->mnt_sb->s_fs_info; + +seq_printf (s,",uid=%u" , hypfs_info->uid); +seq_printf (s,",gid=%u" , hypfs_info->gid); +return 0 ; +} +static int hypfs_fill_super (struct super_block *sb,void *data,int silent) {struct inode *root_inode;
@@ -459,6 +470,7 @@ static struct file_system_type hypfs_typstatic struct super_operations hypfs_s_ops = { .statfs = simple_statfs, .drop_inode = hypfs_drop_inode, + .show_options = hypfs_show_options, }; static decl_subsys(s390, NULL, NULL);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 3/18 qdio: make sure data structures are correctly aligned.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
The slsb structure contained at the beginning of the qdio_q structure must start on a 256 byte boundary. To make sure this is the case even if slab debugging is turned on create an own slab cache for qdio_q structures.
Besides that don't use the slab allocator to allocate whole pages. Use the page allocator instead.
Also fix a few memory leaks in error handling code.
---
drivers/s390/cio/qdio.c | 92 ++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 45 deletions(-)
drivers/s390/cio/qdio.c +47 -45
@@ -81,6 +81,7 @@ static __u32 volatile spare_indicator;static atomic_t spare_indicator_usecount;#define QDIO_MEMPOOL_SCSSC_ELEMENTS 2static mempool_t *qdio_mempool_scssc; +static struct kmem_cache *qdio_q_cache;static debug_info_t *qdio_dbf_setup;static debug_info_t *qdio_dbf_sbal;
@@ -1617,23 +1618,21 @@ static void qdio_release_irq_memory(struct qdio_irq *irq_ptr) {int i; +struct qdio_q *q; -for (i=0 ;i<QDIO_MAX_QUEUES_PER_IRQ ;i++) { -if (!irq_ptr->input_qs[i]) - goto next; - -kfree (irq_ptr->input_qs[i]->slib); -kfree (irq_ptr->input_qs[i]); - -next: -if (!irq_ptr->output_qs[i]) -continue ; - -kfree (irq_ptr->output_qs[i]->slib); -kfree (irq_ptr->output_qs[i]); - +for (i =0 ; i <QDIO_MAX_QUEUES_PER_IRQ ; i++) { + q = irq_ptr->input_qs[i]; +if (q) { +free_page ((unsigned long ) q->slib); +kmem_cache_free (qdio_q_cache, q); + } + q = irq_ptr->output_qs[i]; +if (q) { +free_page ((unsigned long ) q->slib); +kmem_cache_free (qdio_q_cache, q); + } } -kfree (irq_ptr->qdr); +free_page ((unsigned long ) irq_ptr->qdr);free_page ((unsigned long ) irq_ptr); }
@@ -1680,44 +1679,35 @@ qdio_alloc_qs(struct qdio_irq *irq_ptr, {int i;struct qdio_q *q; -int result=-ENOMEM ; - -for (i=0 ;i<no_input_qs;i++) { - q =kzalloc (sizeof (struct qdio_q ),GFP_KERNEL ); -if (!q) { -QDIO_PRINT_ERR ("kmalloc of q failed!\n" ); - goto out; - } +for (i =0 ; i < no_input_qs; i++) { + q =kmem_cache_alloc (qdio_q_cache,GFP_KERNEL ); +if (!q) +return -ENOMEM ; +memset (q,0 ,sizeof (*q)); - q->slib =kmalloc (PAGE_SIZE ,GFP_KERNEL ); + q->slib = (struct slib *)__get_free_page (GFP_KERNEL );if (!q->slib) { -QDIO_PRINT_ERR ("kmalloc of slib failed!\n" ); - goto out; +kmem_cache_free (qdio_q_cache, q); +return -ENOMEM ; } - irq_ptr->input_qs[i]=q; } -for (i=0 ;i<no_output_qs;i++) { - q =kzalloc (sizeof (struct qdio_q ),GFP_KERNEL ); - -if (!q) { - goto out; - } +for (i =0 ; i < no_output_qs; i++) { + q =kmem_cache_alloc (qdio_q_cache,GFP_KERNEL ); +if (!q) +return -ENOMEM ; +memset (q,0 ,sizeof (*q)); - q->slib=kmalloc (PAGE_SIZE ,GFP_KERNEL ); + q->slib = (struct slib *)__get_free_page (GFP_KERNEL );if (!q->slib) { -QDIO_PRINT_ERR ("kmalloc of slib failed!\n" ); - goto out; +kmem_cache_free (qdio_q_cache, q); +return -ENOMEM ; } - irq_ptr->output_qs[i]=q; } - - result=0 ; -out: -return result; +return 0 ; } static void
@@ -2985,17 +2975,17 @@ qdio_allocate(struct qdio_initialize *inQDIO_DBF_HEX0 (0 ,setup,&irq_ptr,sizeof (void *));if (!irq_ptr) { -QDIO_PRINT_ERR ("kmalloc of irq_ptr failed!\n" ); +QDIO_PRINT_ERR ("allocation of irq_ptr failed!\n" );return -ENOMEM ; }init_MUTEX (&irq_ptr->setting_up_sema);/* QDR must be in DMA area since CCW data address is only 32 bit */ - irq_ptr->qdr=kmalloc (sizeof (struct qdr ),GFP_KERNEL |GFP_DMA ); + irq_ptr->qdr = (struct qdr *)__get_free_page (GFP_KERNEL |GFP_DMA );if (!(irq_ptr->qdr)) {free_page ((unsigned long ) irq_ptr); -QDIO_PRINT_ERR ("kmalloc of irq_ptr->qdr failed!\n" ); +QDIO_PRINT_ERR ("allocation of irq_ptr->qdr failed!\n" );return -ENOMEM ; }QDIO_DBF_TEXT0 (0 ,setup,"qdr:" );
@@ -3004,6 +2994,7 @@ qdio_allocate(struct qdio_initialize *inif (qdio_alloc_qs (irq_ptr, init_data->no_input_qs, init_data->no_output_qs)) { +QDIO_PRINT_ERR ("queue allocation failed!\n" );qdio_release_irq_memory (irq_ptr);return -ENOMEM ; }
@@ -3895,9 +3886,19 @@ init_QDIO(void)if (res)return res; + qdio_q_cache =kmem_cache_create ("qdio_q" ,sizeof (struct qdio_q ), +256 ,0 ,NULL ); +if (!qdio_q_cache) { +qdio_release_qdio_memory (); +return -ENOMEM ; + } + res =qdio_register_dbf_views (); -if (res) +if (res) { +kmem_cache_destroy (qdio_q_cache); +qdio_release_qdio_memory ();return res; + }QDIO_DBF_TEXT0 (0 ,setup,"initQDIO" ); res =bus_create_file (&ccw_bus_type, &bus_attr_qdio_performance_stats);
@@ -3929,6 +3930,7 @@ cleanup_QDIO(void)qdio_release_qdio_memory ();qdio_unregister_dbf_views ();mempool_destroy (qdio_mempool_scssc); +kmem_cache_destroy (qdio_q_cache);bus_remove_file (&ccw_bus_type, &bus_attr_qdio_performance_stats);printk ("qdio: %s: module removed\n" ,version); }
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 4/18 remove DEFAULT_MIGRATION_COST
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
0437e109e1841607f2988891eaa36c531c6aa6ac removes the migration cost init code. Remove the s390 leftovers as well.
---
arch/s390/Kconfig | 4 ---- 1 file changed, 4 deletions(-)
arch/s390/Kconfig +0 -4
@@ -109,10 +109,6 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. -config DEFAULT_MIGRATION_COST - int - default "1000000" - config MATHEMU bool "IEEE FPU emulation" depends on MARCH_G5
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 5/18 vmur: allocate single record buffers instead of one big data buffer
In reply to Martin SchwidefskyFrom: Michael Holzheu <[email protected]>
vmur allocates one contiguous kernel buffer to copy user data when creating ccw programs for punch or printer. If big block sizes are used, under memory pressure it can happen, that we do not get memory in one chunk. Now we allocate memory for each single record to avoid high order allocations.
---
drivers/s390/char/vmur.c | 75 +++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 38 deletions(-)
drivers/s390/char/vmur.c +37 -38
@@ -119,10 +119,12 @@ static void urdev_put(struct urdev *urd)/* * Low-level functions to do I/O to a ur device. * alloc_chan_prog +* free_chan_prog * do_ur_io * ur_int_handler * * alloc_chan_prog allocates and builds the channel program +* free_chan_prog frees memory of the channel program * * do_ur_io issues the channel program to the device and blocks waiting * on a completion event it publishes at urd->io_done. The function
@@ -137,6 +139,16 @@ static void urdev_put(struct urdev *urd)* address pointer that alloc_chan_prog returned. */ +static void free_chan_prog (struct ccw1 *cpa) +{ +struct ccw1 *ptr = cpa; + +while (ptr->cda) { +kfree ((void *)(addr_t ) ptr->cda); + ptr++; + } +kfree (cpa); +}/* * alloc_chan_prog
@@ -144,44 +156,45 @@ static void urdev_put(struct urdev *urd)* with a final NOP CCW command-chained on (which ensures that CE and DE * are presented together in a single interrupt instead of as separate * interrupts unless an incorrect length indication kicks in first). The -* data length in each CCW is reclen. The caller must ensure that count -* is an integral multiple of reclen. -* The channel program pointer returned by this function must be freed -* with kfree. The caller is responsible for checking that -* count/reclen is not ridiculously large. +* data length in each CCW is reclen. */ -static struct ccw1 *alloc_chan_prog (char *buf,size_t count,size_t reclen) +static struct ccw1 *alloc_chan_prog (const char __user *ubuf,int rec_count, +int reclen) { -size_t num_ccws;struct ccw1 *cpa; +void *kbuf;int i; -TRACE ("alloc_chan_prog(%p, %zu, %zu)\n" , buf, count, reclen); +TRACE ("alloc_chan_prog(%p, %i, %i)\n" , ubuf, rec_count, reclen);/* * We chain a NOP onto the writes to force CE+DE together. * That means we allocate room for CCWs to cover count/reclen * records plus a NOP. */ - num_ccws = count / reclen +1 ; - cpa =kmalloc (num_ccws *sizeof (struct ccw1 ),GFP_KERNEL |GFP_DMA ); + cpa =kzalloc ((rec_count +1 ) *sizeof (struct ccw1 ), +GFP_KERNEL |GFP_DMA );if (!cpa) -return NULL ; +return ERR_PTR (-ENOMEM ); -for (i =0 ; count; i++) { +for (i =0 ; i < rec_count; i++) { cpa[i].cmd_code =WRITE_CCW_CMD ; cpa[i].flags =CCW_FLAG_CC |CCW_FLAG_SLI ; cpa[i].count = reclen; - cpa[i].cda =__pa (buf); - buf += reclen; - count -= reclen; + kbuf =kmalloc (reclen,GFP_KERNEL |GFP_DMA ); +if (!kbuf) { +free_chan_prog (cpa); +return ERR_PTR (-ENOMEM ); + } + cpa[i].cda = (u32 )(addr_t ) kbuf; +if (copy_from_user (kbuf, ubuf, reclen)) { +free_chan_prog (cpa); +return ERR_PTR (-EFAULT ); + } + ubuf += reclen; }/* The following NOP CCW forces CE+DE to be presented together */ cpa[i].cmd_code =CCW_CMD_NOOP ; - cpa[i].flags =0 ; - cpa[i].count =0 ; - cpa[i].cda =0 ; -return cpa; }
@@ -325,24 +338,11 @@ static ssize_t do_write(struct urdev *ur size_t count, size_t reclen, loff_t *ppos) { struct ccw1 *cpa; -char *buf;int rc; -/* Data buffer must be under 2GB line for fmt1 CCWs: hence GFP_DMA */ - buf =kmalloc (count,GFP_KERNEL |GFP_DMA ); -if (!buf) -return -ENOMEM ; - -if (copy_from_user (buf, udata, count)) { - rc = -EFAULT ; - goto fail_kfree_buf; - } - - cpa =alloc_chan_prog (buf, count, reclen); -if (!cpa) { - rc = -ENOMEM ; - goto fail_kfree_buf; - } + cpa =alloc_chan_prog (udata, count / reclen, reclen); +if (IS_ERR (cpa)) +return PTR_ERR (cpa); rc =do_ur_io (urd, cpa);if (rc)
@@ -354,10 +354,9 @@ static ssize_t do_write(struct urdev *ur } *ppos += count; rc = count; + fail_kfree_cpa: -kfree (cpa); -fail_kfree_buf: -kfree (buf); +free_chan_prog (cpa);return rc; }
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 6/18 vmur: use DECLARE_COMPLETION_ONSTACK to keep lockdep happy
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator. 000000000ff9fb08 000000000ff9fb18 0000000000000002 0000000000000000 000000000ff9fbb8 000000000ff9fb30 000000000ff9fb30 0000000000104198 0000000000000000 0000000000000002 0000000000000000 0000000000000000 000000000ff9fb18 000000000000000c 000000000ff9fb18 000000000ff9fb88 0000000000448db0 0000000000104198 000000000ff9fb18 000000000ff9fb68
Call Trace: ([<00000000001040ea>] show_trace+0x12e/0x170) [<00000000001041f2>] show_stack+0xc6/0xf8 [<0000000000104252>] dump_stack+0x2e/0x3c [<0000000000155f9c>] __lock_acquire+0x460/0x1048 [<0000000000156c16>] lock_acquire+0x92/0xb8 [<000000000043f406>] _spin_lock_irqsave+0x62/0x80 [<0000000000121382>] complete+0x32/0x78 [<000000001082b468>] ur_int_handler+0xc8/0xec [vmur] [<0000000000313216>] ccw_device_call_handler+0xae/0xd4 [<0000000000310da4>] ccw_device_irq+0x5c/0x130 [<0000000000312c84>] io_subchannel_irq+0x8c/0x118 [<000000000030a88c>] do_IRQ+0x16c/0x194 [<0000000000111a62>] io_no_vtime+0x16/0x1c [<0000000080001394>] 0x80001394
---
drivers/s390/char/vmur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/char/vmur.c +1 -1
@@ -202,7 +202,7 @@ static int do_ur_io(struct urdev *urd, s {int rc;struct ccw_device *cdev = urd->cdev; -DECLARE_COMPLETION (event); +DECLARE_COMPLETION_ONSTACK (event);TRACE ("do_ur_io: cpa=%p\n" , cpa);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 7/18 vmur: reject open on z/VM reader files with status HOLD
In reply to Martin SchwidefskyFrom: Michael Holzheu <[email protected]>
If a reader file with HOLD status is at the top of the reader queue, currently all read requests will return data of the second file in the queue. But the semantics of vmur is that always the topmost file is read. With this fix -EPERM is returned on open, if the topmost reader file is in HOLD status.
---
drivers/s390/char/vmur.c | 4 +++- drivers/s390/char/vmur.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-)
drivers/s390/char/vmur.c +3 -1
@@ -556,7 +556,9 @@ static int verify_device(struct urdev *u rc =diag_read_next_file_info (&fcb,0 );if (rc)return rc; - +/* if file is in hold status, we do not read it */ +if (fcb.file_stat & (FLG_SYSTEM_HOLD |FLG_USER_HOLD )) +return -EPERM ;/* open file on virtual reader */ buf =kmalloc (PAGE_SIZE ,GFP_KERNEL );if (!buf)
drivers/s390/char/vmur.h +3 -1
@@ -50,7 +50,9 @@ struct file_control_block {char rest[200 ]; } __attribute__ ((packed)); -#define FLG_CP_DUMP 0x10 +#define FLG_SYSTEM_HOLD 0x04 +#define FLG_CP_DUMP 0x10 +#define FLG_USER_HOLD 0x20/* * A struct urdev is created for each ur device that is made available
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 8/18 vmur: add "top of queue" sanity check for reader open
In reply to Martin SchwidefskyFrom: Michael Holzheu <[email protected]>
If the z/VM reader is already open, it can happen that after opening the Linux reader device, not the topmost file is processed. According the semantics of the Linux z/VM unit record device driver, always the topmost file has to be processed. With this fix an error is returned if that is not the case.
---
drivers/s390/char/vmur.c | 7 ++++++- drivers/s390/char/vmur.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-)
drivers/s390/char/vmur.c +6 -1
@@ -565,9 +565,14 @@ static int verify_device(struct urdev *ureturn -ENOMEM ; rc =diag_read_file (urd->dev_id.devno, buf);kfree (buf); -if ((rc !=0 ) && (rc != -ENODATA ))/* EOF does not hurt */ return rc; +/* check if the file on top of the queue is open now */ + rc =diag_read_next_file_info (&fcb,0 ); +if (rc) +return rc; +if (!(fcb.file_stat &FLG_IN_USE )) +return -EMFILE ;return 0 ;default :return -ENOTSUPP ;
drivers/s390/char/vmur.h +1 -0
@@ -53,6 +53,7 @@ struct file_control_block {#define FLG_SYSTEM_HOLD 0x04#define FLG_CP_DUMP 0x10#define FLG_USER_HOLD 0x20 +#define FLG_IN_USE 0x80/* * A struct urdev is created for each ur device that is made available
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 9/18 vmur: diag14 only works with buffers below 2GB
In reply to Martin SchwidefskyFrom: Michael Holzheu <[email protected]>
If memory buffers above 2GB are used, diagnose 14 raises a specification exception. This fix ensures that buffer allocation is done below the 2GB boundary.
---
drivers/s390/char/vmur.c | 106 +++++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 36 deletions(-)
drivers/s390/char/vmur.c +70 -36
@@ -472,7 +472,7 @@ static ssize_t diag14_read(struct file *return rc; len =min ((size_t )PAGE_SIZE , count); - buf =kmalloc (PAGE_SIZE ,GFP_KERNEL ); + buf = (char *)__get_free_page (GFP_KERNEL |GFP_DMA );if (!buf)return -ENOMEM ;
@@ -499,7 +499,7 @@ static ssize_t diag14_read(struct file * *offs += copied; rc = copied; fail: -kfree (buf); +free_page ((unsigned long ) buf);return rc; }
@@ -542,63 +542,97 @@ static int diag_read_next_file_info(stru } } -static int verify_device (struct urdev *urd) +static int verify_uri_device (struct urdev *urd) { -struct file_control_block fcb; +struct file_control_block *fcb;char *buf;int rc; + fcb =kmalloc (sizeof (*fcb),GFP_KERNEL |GFP_DMA ); +if (!fcb) +return -ENOMEM ; + +/* check for empty reader device (beginning of chain) */ + rc =diag_read_next_file_info (fcb,0 ); +if (rc) + goto fail_free_fcb; + +/* if file is in hold status, we do not read it */ +if (fcb->file_stat & (FLG_SYSTEM_HOLD |FLG_USER_HOLD )) { + rc = -EPERM ; + goto fail_free_fcb; + } + +/* open file on virtual reader */ + buf = (char *)__get_free_page (GFP_KERNEL |GFP_DMA ); +if (!buf) { + rc = -ENOMEM ; + goto fail_free_fcb; + } + rc =diag_read_file (urd->dev_id.devno, buf); +if ((rc !=0 ) && (rc != -ENODATA ))/* EOF does not hurt */ + goto fail_free_buf; + +/* check if the file on top of the queue is open now */ + rc =diag_read_next_file_info (fcb,0 ); +if (rc) + goto fail_free_buf; +if (!(fcb->file_stat &FLG_IN_USE )) { + rc = -EMFILE ; + goto fail_free_buf; + } + rc =0 ; + +fail_free_buf: +free_page ((unsigned long ) buf); +fail_free_fcb: +kfree (fcb); +return rc; +} + +static int verify_device (struct urdev *urd) +{switch (urd->class) {case DEV_CLASS_UR_O :return 0 ;/* no check needed here */ case DEV_CLASS_UR_I : -/* check for empty reader device (beginning of chain) */ - rc =diag_read_next_file_info (&fcb,0 ); -if (rc) -return rc; -/* if file is in hold status, we do not read it */ -if (fcb.file_stat & (FLG_SYSTEM_HOLD |FLG_USER_HOLD )) -return -EPERM ; -/* open file on virtual reader */ - buf =kmalloc (PAGE_SIZE ,GFP_KERNEL ); -if (!buf) -return -ENOMEM ; - rc =diag_read_file (urd->dev_id.devno, buf); -kfree (buf); -if ((rc !=0 ) && (rc != -ENODATA ))/* EOF does not hurt */ -return rc; -/* check if the file on top of the queue is open now */ - rc =diag_read_next_file_info (&fcb,0 ); -if (rc) -return rc; -if (!(fcb.file_stat &FLG_IN_USE )) -return -EMFILE ; -return 0 ; +return verify_uri_device (urd);default :return -ENOTSUPP ; } } -static int get_file_reclen (struct urdev *urd) +static int get_uri_file_reclen (struct urdev *urd) { -struct file_control_block fcb; +struct file_control_block *fcb;int rc; + fcb =kmalloc (sizeof (*fcb),GFP_KERNEL |GFP_DMA ); +if (!fcb) +return -ENOMEM ; + rc =diag_read_next_file_info (fcb,0 ); +if (rc) + goto fail_free; +if (fcb->file_stat &FLG_CP_DUMP ) + rc =0 ; +else + rc = fcb->rec_len; + +fail_free: +kfree (fcb); +return rc; +} + +static int get_file_reclen (struct urdev *urd) +{switch (urd->class) {case DEV_CLASS_UR_O :return 0 ;case DEV_CLASS_UR_I : - rc =diag_read_next_file_info (&fcb,0 ); -if (rc) -return rc; -break ; +return get_uri_file_reclen (urd);default :return -ENOTSUPP ; } -if (fcb.file_stat &FLG_CP_DUMP ) -return 0 ; - -return fcb.rec_len; }static int ur_open (struct inode *inode,struct file *file)
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 10/18 monwriter: Serialization bug for multithreaded applications.
In reply to Martin SchwidefskyFrom: Melissa Howland <[email protected]>
Locking added so that multithreaded applications can now do writes from different threads without the risk of storage corruption.
---
drivers/s390/char/monwriter.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/s390/char/monwriter.c +6 -0
@@ -17,6 +17,7 @@#include <linux/miscdevice.h> #include <linux/ctype.h> #include <linux/poll.h> +#include <linux/mutex.h> #include <asm/uaccess.h> #include <asm/ebcdic.h> #include <asm/io.h>
@@ -41,6 +42,7 @@ struct mon_private {size_t hdr_to_read;size_t data_to_read;struct mon_buf *current_buf; +struct mutex thread_mutex; };/*
@@ -179,6 +181,7 @@ static int monwrite_open(struct inode *ireturn -ENOMEM ;INIT_LIST_HEAD (&monpriv->list); monpriv->hdr_to_read =sizeof (monpriv->hdr); +mutex_init (&monpriv->thread_mutex); filp->private_data = monpriv;return nonseekable_open (inode, filp); }
@@ -209,6 +212,7 @@ static ssize_t monwrite_write(struct filvoid *to;int rc; +mutex_lock (&monpriv->thread_mutex);for (written =0 ; written < count; ) {if (monpriv->hdr_to_read) { len =min (count - written, monpriv->hdr_to_read);
@@ -247,11 +251,13 @@ static ssize_t monwrite_write(struct fil } monpriv->hdr_to_read =sizeof (monpriv->hdr); } +mutex_unlock (&monpriv->thread_mutex);return written; out_error: monpriv->data_to_read =0 ; monpriv->hdr_to_read =sizeof (struct monwrite_hdr ); +mutex_unlock (&monpriv->thread_mutex);return rc; }
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 11/18 cio: rename css to channel_subsystems
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Rename css[] to channel_subsystems[] to avoid name clashes.
---
drivers/s390/cio/chp.c | 14 ++++---- drivers/s390/cio/css.c | 69 +++++++++++++++++++++++------------------- drivers/s390/cio/css.h | 2 - drivers/s390/cio/device_fsm.c | 3 + 4 files changed, 49 insertions(+), 39 deletions(-)
drivers/s390/cio/chp.c +7 -7
@@ -55,7 +55,7 @@ static wait_queue_head_t cfg_wait_queue;/* Return channel_path struct for given chpid. */ static inline struct channel_path *chpid_to_chp (struct chp_id chpid) { -return css[chpid.cssid]->chps[chpid.id]; +return channel_subsystems[chpid.cssid]->chps[chpid.id]; }/* Set vary state for given chpid. */
@@ -395,7 +395,7 @@ int chp_new(struct chp_id chpid)/* fill in status, etc. */ chp->chpid = chpid; chp->state =1 ; - chp->dev.parent = &css[chpid.cssid]->device; + chp->dev.parent = &channel_subsystems[chpid.cssid]->device; chp->dev.release = chp_release;snprintf (chp->dev.bus_id,BUS_ID_SIZE ,"chp%x.%02x" , chpid.cssid, chpid.id);
@@ -430,18 +430,18 @@ int chp_new(struct chp_id chpid)device_unregister (&chp->dev); goto out_free; } -mutex_lock (&css[chpid.cssid]->mutex); -if (css[chpid.cssid]->cm_enabled) { +mutex_lock (&channel_subsystems[chpid.cssid]->mutex); +if (channel_subsystems[chpid.cssid]->cm_enabled) { ret =chp_add_cmg_attr (chp);if (ret) {sysfs_remove_group (&chp->dev.kobj, &chp_attr_group);device_unregister (&chp->dev); -mutex_unlock (&css[chpid.cssid]->mutex); +mutex_unlock (&channel_subsystems[chpid.cssid]->mutex); goto out_free; } } - css[chpid.cssid]->chps[chpid.id] = chp; -mutex_unlock (&css[chpid.cssid]->mutex); + channel_subsystems[chpid.cssid]->chps[chpid.id] = chp; +mutex_unlock (&channel_subsystems[chpid.cssid]->mutex);return ret; out_free:kfree (chp);
drivers/s390/cio/css.c +39 -30
127 lines not on this page · raw message
drivers/s390/cio/css.h +1 -1
@@ -167,7 +167,7 @@ struct channel_subsystem {#define to_css (dev) container_of(dev, struct channel_subsystem, device)extern struct bus_type css_bus_type; -extern struct channel_subsystem *css[]; +extern struct channel_subsystem *channel_subsystems[];/* Some helper functions for disconnected state. */ int device_is_disconnected (struct subchannel *);
drivers/s390/cio/device_fsm.c +2 -1
@@ -446,7 +446,8 @@ static void __ccw_device_get_common_pgidif (cdev->private->pgid[last].inf.ps.state1 ==SNID_STATE1_RESET )/* No previous pgid found */ -memcpy (&cdev->private->pgid[0 ], &css[0 ]->global_pgid, +memcpy (&cdev->private->pgid[0 ], + &channel_subsystems[0 ]->global_pgid,sizeof (struct pgid ));else /* Use existing pgid */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 12/18 cio: remove subchannel_add_files()
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
subchannel_add_files() no longer exists, remove from header.
---
drivers/s390/cio/css.h | 1 - 1 file changed, 1 deletion(-)
drivers/s390/cio/css.h +0 -1
@@ -191,6 +191,5 @@ int sch_is_pseudo_sch(struct subchannelextern struct workqueue_struct *slow_path_wq; -int subchannel_add_files (struct device *);extern struct attribute_group *subch_attr_groups[];#endif
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 13/18 cio: Fix some coding style issues in cmf.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Fix some formatting and correct a comment.
---
drivers/s390/cio/cmf.c | 133 ++++++++++++++++++++++++++----------------------- include/asm-s390/cmb.h | 8 +- 2 files changed, 77 insertions(+), 64 deletions(-)
drivers/s390/cio/cmf.c +73 -60
@@ -45,7 +45,8 @@#include "ioasm.h" #include "chsc.h" -/* parameter to enable cmf during boot, possible uses are: +/* +* parameter to enable cmf during boot, possible uses are: * "s390cmf" -- enable cmf and allocate 2 MB of ram so measuring can be * used on any subchannel * "s390cmf=<num>" -- enable cmf and allocate enough memory to measure
@@ -84,6 +85,7 @@ enum cmb_format {CMF_EXTENDED , CMF_AUTODETECT = -1, }; +/** * format - actual format for all measurement blocks *
@@ -111,13 +113,13 @@ module_param(format, bool, 0444);* @align: align an allocated block so that the hardware can use it */ struct cmb_operations { -int (*alloc) (struct ccw_device *); -void (*free) (struct ccw_device *); -int (*set) (struct ccw_device *,u32 ); -u64 (*read) (struct ccw_device *,int ); -int (*readall)(struct ccw_device *,struct cmbdata *); -void (*reset) (struct ccw_device *); -void * (*align) (void *); +int (*alloc) (struct ccw_device *); +void (*free) (struct ccw_device *); +int (*set) (struct ccw_device *,u32 ); +u64 (*read) (struct ccw_device *,int ); +int (*readall)(struct ccw_device *,struct cmbdata *); +void (*reset) (struct ccw_device *); +void *(*align) (void *);struct attribute_group *attr_group; };
@@ -130,9 +132,11 @@ struct cmb_data {unsigned long long last_update;/* when last_block was updated */ }; -/* our user interface is designed in terms of nanoseconds, +/* +* Our user interface is designed in terms of nanoseconds, * while the hardware measures total times in its own -* unit.*/ +* unit. +*/ static inline u64 time_to_nsec (u32 value) {return ((u64 )value) *128000ull ;
@@ -159,12 +163,13 @@ static inline u64 time_to_avg_nsec(u32 vreturn ret; } -/* activate or deactivate the channel monitor. When area is NULL, +/* +* Activate or deactivate the channel monitor. When area is NULL, * the monitor is deactivated. The channel monitor needs to * be active in order to measure subchannels, which also need -* to be enabled. */ -static inline void -cmf_activate (void *area,unsigned int onoff) +* to be enabled. +*/ +static inline void cmf_activate (void *area,unsigned int onoff) { registervoid * __gpr2 asm("2" ); registerlong __gpr1 asm("1" );
@@ -175,8 +180,8 @@ cmf_activate(void *area, unsigned int on asm("schm" : :"d" (__gpr2),"d" (__gpr1) ); } -static int -set_schib (struct ccw_device *cdev,u32 mme,int mbfc,unsigned long address) +static int set_schib (struct ccw_device *cdev,u32 mme,int mbfc, +unsigned long address) {int ret;int retry;
@@ -484,15 +489,14 @@ static struct cmb_area cmb_area = {/* ****** old style CMB handling ********/ -/** int maxchannels -* +/* * Basic channel measurement blocks are allocated in one contiguous * block of memory, which can not be moved as long as any channel * is active. Therefore, a maximum number of subchannels needs to * be defined somewhere. This is a module parameter, defaulting to * a resonable value of 1024, or 32 kb of memory. * Current kernels don't allow kmalloc with more than 128kb, so the -* maximum is 4096 +* maximum is 4096. */ module_param_named (maxchannels, cmb_area.num_channels, uint,0444 );
@@ -516,8 +520,9 @@ struct cmb {u32 reserved[2 ]; }; -/* insert a single device into the cmb_area list -* called with cmb_area.lock held from alloc_cmb +/* +* Insert a single device into the cmb_area list. +* Called with cmb_area.lock held from alloc_cmb. */ static int alloc_cmb_single (struct ccw_device *cdev,struct cmb_data *cmb_data)
@@ -532,9 +537,11 @@ static int alloc_cmb_single(struct ccw_d goto out; } -/* find first unused cmb in cmb_area.mem. -* this is a little tricky: cmb_area.list -* remains sorted by ->cmb->hw_data pointers */ +/* +* Find first unused cmb in cmb_area.mem. +* This is a little tricky: cmb_area.list +* remains sorted by ->cmb->hw_data pointers. +*/ cmb = cmb_area.mem;list_for_each_entry (node, &cmb_area.list, cmb_list) {struct cmb_data *data;
@@ -558,8 +565,7 @@ out:return ret; } -static int -alloc_cmb (struct ccw_device *cdev) +static int alloc_cmb (struct ccw_device *cdev) {int ret;struct cmb *mem;
@@ -667,7 +673,7 @@ static int set_cmb(struct ccw_device *cdreturn set_schib_wait (cdev, mme,0 , offset); } -static u64 read_cmb (struct ccw_device *cdev,int index) +static u64 read_cmb (struct ccw_device *cdev,int index) {struct cmb *cmb;u32 val;
@@ -717,7 +723,7 @@ out:return ret; } -static int readall_cmb (struct ccw_device *cdev,struct cmbdata *data) +static int readall_cmb (struct ccw_device *cdev,struct cmbdata *data) {struct cmb *cmb;struct cmb_data *cmb_data;
@@ -813,10 +819,12 @@ struct cmbe {u32 reserved[7 ]; }; -/* kmalloc only guarantees 8 byte alignment, but we need cmbe +/* +* kmalloc only guarantees 8 byte alignment, but we need cmbe * pointers to be naturally aligned. Make sure to allocate -* enough space for two cmbes */ -static inline struct cmbe *cmbe_align (struct cmbe *c) +* enough space for two cmbes. +*/ +static inline struct cmbe *cmbe_align (struct cmbe *c) {unsigned long addr; addr = ((unsigned long)c + sizeof (struct cmbe) - sizeof(long)) &
@@ -824,7 +832,7 @@ static inline struct cmbe* cmbe_align(streturn (struct cmbe *)addr; } -static int alloc_cmbe (struct ccw_device *cdev) +static int alloc_cmbe (struct ccw_device *cdev) {struct cmbe *cmbe;struct cmb_data *cmb_data;
@@ -870,7 +878,7 @@ out_free:return ret; } -static void free_cmbe (struct ccw_device *cdev) +static void free_cmbe (struct ccw_device *cdev) {struct cmb_data *cmb_data;
@@ -909,7 +917,7 @@ static int set_cmbe(struct ccw_device *c } -static u64 read_cmbe (struct ccw_device *cdev,int index) +static u64 read_cmbe (struct ccw_device *cdev,int index) {struct cmbe *cmb;struct cmb_data *cmb_data;
@@ -967,7 +975,7 @@ out:return ret; } -static int readall_cmbe (struct ccw_device *cdev,struct cmbdata *data) +static int readall_cmbe (struct ccw_device *cdev,struct cmbdata *data) {struct cmbe *cmb;struct cmb_data *cmb_data;
@@ -1046,15 +1054,15 @@ static struct cmb_operations cmbops_exte }; -static ssize_t -cmb_show_attr (struct device *dev,char *buf,enum cmb_index idx) +static ssize_t cmb_show_attr (struct device *dev,char *buf,enum cmb_index idx) {return sprintf (buf,"%lld\n" , (unsigned long long )cmf_read (to_ccwdev (dev), idx)); } -static ssize_t -cmb_show_avg_sample_interval (struct device *dev,struct device_attribute *attr,char *buf) +static ssize_t cmb_show_avg_sample_interval (struct device *dev, +struct device_attribute *attr, +char *buf) {struct ccw_device *cdev;long interval;
@@ -1076,8 +1084,9 @@ cmb_show_avg_sample_interval(struct devireturn sprintf (buf,"%ld\n" , interval); } -static ssize_t -cmb_show_avg_utilization (struct device *dev,struct device_attribute *attr,char *buf) +static ssize_t cmb_show_avg_utilization (struct device *dev, +struct device_attribute *attr, +char *buf) {struct cmbdata data;u64 utilization;
@@ -1109,12 +1118,14 @@ cmb_show_avg_utilization(struct device * }#define cmf_attr (name) \ -static ssize_t show_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \ +static ssize_t show_ ## name (struct device *dev, \ + struct device_attribute *attr, char *buf) \ { return cmb_show_attr((dev), buf, cmb_ ## name); } \ static DEVICE_ATTR(name, 0444, show_ ## name, NULL);#define cmf_attr_avg (name) \ -static ssize_t show_avg_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \ +static ssize_t show_avg_ ## name (struct device *dev, \ + struct device_attribute *attr, char *buf) \ { return cmb_show_attr((dev), buf, cmb_ ## name); } \ static DEVICE_ATTR(avg_ ## name, 0444, show_avg_ ## name, NULL);
@@ -1128,7 +1139,8 @@ cmf_attr_avg(device_active_only_time);cmf_attr_avg (device_busy_time);cmf_attr_avg (initial_command_response_time); -static DEVICE_ATTR(avg_sample_interval, 0444, cmb_show_avg_sample_interval, NULL); +static DEVICE_ATTR(avg_sample_interval, 0444, cmb_show_avg_sample_interval, + NULL); static DEVICE_ATTR(avg_utilization, 0444, cmb_show_avg_utilization, NULL);static struct attribute *cmf_attributes[] = {
@@ -1169,12 +1181,16 @@ static struct attribute_group cmf_attr_g .attrs = cmf_attributes_ext, }; -static ssize_t cmb_enable_show (struct device *dev,struct device_attribute *attr,char *buf) +static ssize_t cmb_enable_show (struct device *dev, +struct device_attribute *attr, +char *buf) {return sprintf (buf,"%d\n" ,to_ccwdev (dev)->private->cmb ?1 :0 ); } -static ssize_t cmb_enable_store (struct device *dev,struct device_attribute *attr,const char *buf,size_t c) +static ssize_t cmb_enable_store (struct device *dev, +struct device_attribute *attr,const char *buf, +size_t c) {struct ccw_device *cdev;int ret;
@@ -1200,8 +1216,7 @@ static ssize_t cmb_enable_store(struct dDEVICE_ATTR (cmb_enable,0644 , cmb_enable_show, cmb_enable_store);/* enable_cmf/disable_cmf: module interface for cmf (de)activation */ -int -enable_cmf (struct ccw_device *cdev) +int enable_cmf (struct ccw_device *cdev) {int ret;
@@ -1222,8 +1237,7 @@ enable_cmf(struct ccw_device *cdev)return ret; } -int -disable_cmf (struct ccw_device *cdev) +int disable_cmf (struct ccw_device *cdev) {int ret;
@@ -1235,14 +1249,12 @@ disable_cmf(struct ccw_device *cdev)return ret; } -u64 -cmf_read (struct ccw_device *cdev,int index) +u64 cmf_read (struct ccw_device *cdev,int index) {return cmbops->read (cdev, index); } -int -cmf_readall (struct ccw_device *cdev,struct cmbdata *data) +int cmf_readall (struct ccw_device *cdev,struct cmbdata *data) {return cmbops->readall (cdev, data); }
@@ -1254,15 +1266,16 @@ int cmf_reenable(struct ccw_device *cdevreturn cmbops->set (cdev,2 ); } -static int __init -init_cmf (void ) +static int __init init_cmf (void ) {char *format_string;char *detect_string ="parameter" ; -/* We cannot really autoprobe this. If the user did not give a parameter, -see if we are running on z990 or up, otherwise fall back to basic mode. */ - +/* +* If the user did not give a parameter, see if we are running on a +* machine supporting extended measurement blocks, otherwise fall back +* to basic mode. +*/ if (format ==CMF_AUTODETECT ) {if (!css_characteristics_avail || !css_general_characteristics.ext_mb) {
@@ -1288,7 +1301,7 @@ init_cmf(void) }break ;case CMF_EXTENDED : - format_string ="extended" ; + format_string ="extended" ; cmbops = &cmbops_extended;break ;default :
include/asm-s390/cmb.h +4 -4
@@ -41,11 +41,11 @@ struct cmbdata { };/* enable channel measurement */ -#define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER,32) +#define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER, 32)/* enable channel measurement */ -#define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER,33) +#define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER, 33)/* read channel measurement data */ -#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata) +#define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER, 33, struct cmbdata)#ifdef __KERNEL__struct ccw_device ;
@@ -87,7 +87,7 @@ extern u64 cmf_read(struct ccw_device *c* Context: * any **/ -extern int cmf_readall (struct ccw_device *cdev,struct cmbdata *data); +extern int cmf_readall (struct ccw_device *cdev,struct cmbdata *data);#endif /* __KERNEL__ */ #endif /* S390_CMB_H */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 14/18 cio: Kerneldoc comments for cmf.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
- Fix existing kerneldoc-style comments.
- Move descriptions of functions from cmb.h to cmf.c.
---
drivers/s390/cio/cmf.c | 87 +++++++++++++++++++++++++++++++++++++++++-------- include/asm-s390/cmb.h | 65 ++++++++---------------------------- 2 files changed, 89 insertions(+), 63 deletions(-)
drivers/s390/cio/cmf.c +74 -13
@@ -74,19 +74,20 @@ enum cmb_index {* enum cmb_format - types of supported measurement block formats * * @CMF_BASIC: traditional channel measurement blocks supported -* by all machines that we run on +* by all machines that we run on * @CMF_EXTENDED: improved format that was introduced with the z990 -* machine -* @CMF_AUTODETECT: default: use extended format when running on a z990 -* or later machine, otherwise fall back to basic format -**/ +* machine +* @CMF_AUTODETECT: default: use extended format when running on a machine +* supporting extended format, otherwise fall back to +* basic format +*/ enum cmb_format {CMF_BASIC ,CMF_EXTENDED ,CMF_AUTODETECT =-1 , }; -/** +/* * format - actual format for all measurement blocks * * The format module parameter can be set to a value of 0 (zero)
@@ -107,6 +108,7 @@ module_param(format, bool, 0444);* either with the help of a special pool or with kmalloc * @free: free memory allocated with @alloc * @set: enable or disable measurement +* @read: read a measurement entry at an index * @readall: read a measurement block in a common format * @reset: clear the data in the associated measurement block and * reset its time stamp
@@ -120,7 +122,7 @@ struct cmb_operations {int (*readall)(struct ccw_device *,struct cmbdata *);void (*reset) (struct ccw_device *);void *(*align) (void *); - +/* private: */ struct attribute_group *attr_group; };static struct cmb_operations *cmbops;
@@ -471,6 +473,7 @@ static void cmf_generic_reset(struct ccw* * @mem: pointer to CMBs (only in basic measurement mode) * @list: contains a linked list of all subchannels +* @num_channels: number of channels to be measured * @lock: protect concurrent access to @mem and @list */ struct cmb_area {
@@ -503,10 +506,20 @@ module_param_named(maxchannels, cmb_area/** * struct cmb - basic channel measurement block +* @ssch_rsch_count: number of ssch and rsch +* @sample_count: number of samples +* @device_connect_time: time of device connect +* @function_pending_time: time of function pending +* @device_disconnect_time: time of device disconnect +* @control_unit_queuing_time: time of control unit queuing +* @device_active_only_time: time of device active only +* @reserved: unused in basic measurement mode +* +* The measurement block as used by the hardware. The fields are described +* further in z/Architecture Principles of Operation, chapter 17. * -* cmb as used by the hardware the fields are described in z/Architecture -* Principles of Operation, chapter 17. -* The area to be a contiguous array and may not be reallocated or freed. +* The cmb area made up from these blocks must be a contiguous array and may +* not be reallocated or freed. * Only one cmb area can be present in the system. */ struct cmb {
@@ -801,9 +814,20 @@ static struct cmb_operations cmbops_basi/** * struct cmbe - extended channel measurement block +* @ssch_rsch_count: number of ssch and rsch +* @sample_count: number of samples +* @device_connect_time: time of device connect +* @function_pending_time: time of function pending +* @device_disconnect_time: time of device disconnect +* @control_unit_queuing_time: time of control unit queuing +* @device_active_only_time: time of device active only +* @device_busy_time: time of device busy +* @initial_command_response_time: initial command response time +* @reserved: unused * -* cmb as used by the hardware, may be in any 64 bit physical location, -* the fields are described in z/Architecture Principles of Operation, +* The measurement block as used by the hardware. May be in any 64 bit physical +* location. +* The fields are described further in z/Architecture Principles of Operation, * third edition, chapter 17. */ struct cmbe {
@@ -1215,7 +1239,15 @@ static ssize_t cmb_enable_store(struct dDEVICE_ATTR (cmb_enable,0644 , cmb_enable_show, cmb_enable_store); -/* enable_cmf/disable_cmf: module interface for cmf (de)activation */ +/** +* enable_cmf() - switch on the channel measurement for a specific device +* @cdev: The ccw device to be enabled +* +* Returns %0 for success or a negative error value. +* +* Context: +* non-atomic +*/ int enable_cmf (struct ccw_device *cdev) {int ret;
@@ -1237,6 +1269,15 @@ int enable_cmf(struct ccw_device *cdev)return ret; } +/** +* disable_cmf() - switch off the channel measurement for a specific device +* @cdev: The ccw device to be disabled +* +* Returns %0 for success or a negative error value. +* +* Context: +* non-atomic +*/ int disable_cmf (struct ccw_device *cdev) {int ret;
@@ -1249,11 +1290,31 @@ int disable_cmf(struct ccw_device *cdev)return ret; } +/** +* cmf_read() - read one value from the current channel measurement block +* @cdev: the channel to be read +* @index: the index of the value to be read +* +* Returns the value read or %0 if the value cannot be read. +* +* Context: +* any +*/ u64 cmf_read (struct ccw_device *cdev,int index) {return cmbops->read (cdev, index); } +/** +* cmf_readall() - read the current channel measurement block +* @cdev: the channel to be read +* @data: a pointer to a data block that will be filled +* +* Returns %0 on success, a negative error value otherwise. +* +* Context: +* any +*/ int cmf_readall (struct ccw_device *cdev,struct cmbdata *data) {return cmbops->readall (cdev, data);
include/asm-s390/cmb.h +15 -50
88 lines not on this page · raw message
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 15/18 cio: Add docbook comments.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Comment a bunch of function in docbook style and convert existing comments on structures to docbook.
---
drivers/s390/cio/ccwgroup.c | 67 +++++++-- drivers/s390/cio/device.c | 64 +++++++-- drivers/s390/cio/device_ops.c | 241 ++++++++++++++++++++++++++++++----- include/asm-s390/ccwdev.h | 75 ++++------ include/asm-s390/ccwgroup.h | 32 +++- include/asm-s390/cio.h | 288 +++++++++++++++++++++++++++++------------- 6 files changed, 575 insertions(+), 192 deletions(-)
drivers/s390/cio/ccwgroup.c +50 -17
@@ -152,16 +152,24 @@ __ccwgroup_create_symlinks(struct ccwgroreturn 0 ; } -/* -* try to add a new ccwgroup device for one driver -* argc and argv[] are a list of bus_id's of devices -* belonging to the driver. +/** +* ccwgroup_create() - 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 +* @argc: number of slave devices +* @argv: 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 @argv[] and must all +* belong to @cdrv. +* Returns: +* %0 on success and an error code on failure. +* Context: +* non-atomic */ -int -ccwgroup_create (struct device *root, -unsigned int creator_id, -struct ccw_driver *cdrv, -int argc,char *argv[]) +int ccwgroup_create (struct device *root,unsigned int creator_id, +struct ccw_driver *cdrv,int argc,char *argv[]) {struct ccwgroup_device *gdev;int i;
@@ -390,8 +398,13 @@ static struct bus_type ccwgroup_bus_type .remove = ccwgroup_remove, }; -int -ccwgroup_driver_register (struct ccwgroup_driver *cdriver) +/** +* ccwgroup_driver_register() - register a ccw group driver +* @cdriver: driver to be registered +* +* This function is mainly a wrapper around driver_register(). +*/ +int ccwgroup_driver_register (struct ccwgroup_driver *cdriver) {/* register our new driver with the core */ cdriver->driver.bus = &ccwgroup_bus_type;
@@ -406,8 +419,13 @@ __ccwgroup_match_all(struct device *dev,return 1 ; } -void -ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) +/** +* ccwgroup_driver_unregister() - deregister a ccw group driver +* @cdriver: driver to be deregistered +* +* This function is mainly a wrapper around driver_unregister(). +*/ +void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) {struct device *dev;
@@ -427,8 +445,16 @@ ccwgroup_driver_unregister (struct ccwgrdriver_unregister (&cdriver->driver); } -int -ccwgroup_probe_ccwdev (struct ccw_device *cdev) +/** +* ccwgroup_probe_ccwdev() - probe function for slave devices +* @cdev: ccw device to be probed +* +* This is a dummy probe function for ccw devices that are slave devices in +* a ccw group device. +* Returns: +* always %0 +*/ +int ccwgroup_probe_ccwdev (struct ccw_device *cdev) {return 0 ; }
@@ -452,8 +478,15 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_dreturn NULL ; } -void -ccwgroup_remove_ccwdev (struct ccw_device *cdev) +/** +* ccwgroup_remove_ccwdev() - remove function for slave devices +* @cdev: ccw device to be removed +* +* This is a remove function for ccw devices that are slave devices in a ccw +* group device. It sets the ccw device offline and also deregisters the +* embedding ccw group device. +*/ +void ccwgroup_remove_ccwdev (struct ccw_device *cdev) {struct ccwgroup_device *gdev;
drivers/s390/cio/device.c +54 -10
94 lines not on this page · raw message
drivers/s390/cio/device_ops.c +211 -30
319 lines not on this page · raw message
include/asm-s390/ccwdev.h +33 -42
105 lines not on this page · raw message
include/asm-s390/ccwgroup.h +27 -5
@@ -4,19 +4,41 @@struct ccw_device ;struct ccw_driver ; +/** +* struct ccwgroup_device - ccw group device +* @creator_id: unique number of the driver +* @state: online/offline state +* @count: number of attached slave devices +* @dev: embedded device structure +* @cdev: variable number of slave devices, allocated as needed +*/ struct ccwgroup_device { -unsigned long creator_id;/* unique number of the driver */ +unsigned long creator_id;enum {CCWGROUP_OFFLINE ,CCWGROUP_ONLINE , } state; +/* private: */ atomic_t onoff;struct mutex reg_mutex; -unsigned int count;/* number of attached slave devices */ -struct device dev;/* master device */ -struct ccw_device *cdev[0 ];/* variable number, allocate as needed */ +/* public: */ +unsigned int count; +struct device dev; +struct ccw_device *cdev[0 ]; }; +/** +* struct ccwgroup_driver - driver for ccw group devices +* @owner: driver owner +* @name: driver name +* @max_slaves: maximum number of slave devices +* @driver_id: unique id +* @probe: function called on probe +* @remove: function called on remove +* @set_online: function called when device is set online +* @set_offline: function called when device is set offline +* @driver: embedded driver structure +*/ struct ccwgroup_driver {struct module *owner;char *name;
@@ -28,7 +50,7 @@ struct ccwgroup_driver {int (*set_online) (struct ccwgroup_device *);int (*set_offline) (struct ccwgroup_device *); -struct device_driver driver;/* this driver */ +struct device_driver driver; };extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver);
include/asm-s390/cio.h +200 -88
354 lines not on this page · raw message
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 16/18 cio: Add s390-drivers book.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
s390-drivers is generated using the docbook comments. It should eventually supersede Documentation/s390/cds.txt.
---
Documentation/DocBook/Makefile | 2 Documentation/DocBook/s390-drivers.tmpl | 149 ++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-)
Documentation/DocBook/Makefile +1 -1
@@ -11,7 +11,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mc procfs-guide.xml writing_usb_driver.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ - genericirq.xml + genericirq.xml s390-drivers.xml ### # The build process is as follows (targets):
Documentation/DocBook/s390-drivers.tmpl new file +149 -0
149 lines not on this page · raw message
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 17/18 zcrypt: make init/exit functions static.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
---
drivers/s390/crypto/zcrypt_mono.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/s390/crypto/zcrypt_mono.c +2 -2
@@ -45,7 +45,7 @@/** * The module initialization code. */ -int __init zcrypt_init (void ) +static int __init zcrypt_init (void ) {int rc;
@@ -86,7 +86,7 @@ out:/** * The module termination code. */ -void __exit zcrypt_exit(void) +static void __exit zcrypt_exit(void) {zcrypt_cex2a_exit ();zcrypt_pcixcc_exit ();
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 18/18 Get rid of a bunch of sparse warnings again.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Also removes a bunch of ^L in drivers/s390/cio/cmf.c
---
arch/s390/kernel/audit.c | 7 +------ arch/s390/kernel/audit.h | 15 +++++++++++++++ arch/s390/kernel/compat_audit.c | 1 + drivers/s390/char/con3270.c | 3 +-- drivers/s390/char/sclp.c | 5 ++--- drivers/s390/char/tty3270.c | 9 ++++++--- drivers/s390/char/tty3270.h | 16 ++++++++++++++++ drivers/s390/cio/chp.c | 8 ++++++-- drivers/s390/cio/cmf.c | 4 +--- drivers/s390/scsi/zfcp_dbf.c | 10 +++++----- drivers/s390/scsi/zfcp_erp.c | 18 ++++++++---------- 11 files changed, 62 insertions(+), 34 deletions(-)
arch/s390/kernel/audit.c +1 -6
@@ -2,6 +2,7 @@#include <linux/types.h> #include <linux/audit.h> #include <asm/unistd.h> +#include "audit.h" static unsigned dir_class[] = {#include <asm-generic/audit_dir_write.h>
@@ -40,7 +41,6 @@ int audit_classify_arch(int arch)int audit_classify_syscall (int abi,unsigned syscall) {#ifdef CONFIG_COMPAT -extern int s390_classify_syscall (unsigned );if (abi ==AUDIT_ARCH_S390 )return s390_classify_syscall (syscall);#endif
@@ -61,11 +61,6 @@ int audit_classify_syscall(int abi, unsistatic int __init audit_classes_init (void ) {#ifdef CONFIG_COMPAT -extern __u32 s390_dir_class[]; -extern __u32 s390_write_class[]; -extern __u32 s390_read_class[]; -extern __u32 s390_chattr_class[]; -extern __u32 s390_signal_class[];audit_register_class (AUDIT_CLASS_WRITE_32 , s390_write_class);audit_register_class (AUDIT_CLASS_READ_32 , s390_read_class);audit_register_class (AUDIT_CLASS_DIR_WRITE_32 , s390_dir_class);
arch/s390/kernel/audit.h new file +15 -0
@@ -0,0 +1,15 @@ +#ifndef __ARCH_S390_KERNEL_AUDIT_H +#define __ARCH_S390_KERNEL_AUDIT_H + +#include <linux/types.h> + +#ifdef CONFIG_COMPAT +extern int s390_classify_syscall (unsigned ); +extern __u32 s390_dir_class[]; +extern __u32 s390_write_class[]; +extern __u32 s390_read_class[]; +extern __u32 s390_chattr_class[]; +extern __u32 s390_signal_class[]; +#endif /* CONFIG_COMPAT */ + +#endif /* __ARCH_S390_KERNEL_AUDIT_H */
arch/s390/kernel/compat_audit.c +1 -0
@@ -1,5 +1,6 @@#undef __s390x__#include <asm/unistd.h> +#include "audit.h" unsigned s390_dir_class[] = {#include <asm-generic/audit_dir_write.h>
drivers/s390/char/con3270.c +1 -2
@@ -22,6 +22,7 @@#include <asm/ebcdic.h> #include "raw3270.h" +#include "tty3270.h" #include "ctrlchar.h" #define CON3270_OUTPUT_BUFFER_SIZE 1024
@@ -507,8 +508,6 @@ con3270_write(struct console *co, constspin_unlock_irqrestore (&cp->view.lock,flags); } -extern struct tty_driver *tty3270_driver; -static struct tty_driver *con3270_device (struct console *c,int *index) {
drivers/s390/char/sclp.c +2 -3
@@ -93,6 +93,7 @@ static volatile enum sclp_mask_state_t {#define SCLP_RETRY_INTERVAL 30static void sclp_process_queue (void ); +static void __sclp_make_read_req (void );static int sclp_init_mask (int calculate);static int sclp_init (void );
@@ -115,7 +116,6 @@ sclp_service_call(sclp_cmdw_t command, vreturn 0 ; } -static inline void __sclp_make_read_req (void );static void __sclp_queue_read_req (void )
@@ -318,8 +318,7 @@ sclp_read_cb(struct sclp_req *req, void }/* Prepare read event data request. Called while sclp_lock is locked. */ -static inline void -__sclp_make_read_req (void ) +static void __sclp_make_read_req (void ) {struct sccb_header *sccb;
drivers/s390/char/tty3270.c +6 -3
@@ -25,8 +25,8 @@#include <asm/ebcdic.h> #include <asm/uaccess.h> -#include "raw3270.h" +#include "tty3270.h" #include "keyboard.h" #define TTY3270_CHAR_BUF_SIZE 256
@@ -1338,8 +1338,11 @@ tty3270_getpar(struct tty3270 *tp, int istatic void tty3270_goto_xy (struct tty3270 *tp,int cx,int cy) { - tp->cx =min_t (int, tp->view.cols -1 ,max_t (int,0 , cx)); - cy =min_t (int, tp->view.rows -3 ,max_t (int,0 , cy)); +int max_cx =max (0 , cx); +int max_cy =max (0 , cy); + + tp->cx =min_t (int, tp->view.cols -1 , max_cx); + cy =min_t (int, tp->view.rows -3 , max_cy);if (cy != tp->cy) {tty3270_convert_line (tp, tp->cy); tp->cy = cy;
drivers/s390/char/tty3270.h new file +16 -0
@@ -0,0 +1,16 @@ +/* +* drivers/s390/char/tty3270.h +* +* Copyright IBM Corp. 2007 +* +*/ + +#ifndef __DRIVERS_S390_CHAR_TTY3270_H +#define __DRIVERS_S390_CHAR_TTY3270_H + +#include <linux/tty.h> +#include <linux/tty_driver.h> + +extern struct tty_driver *tty3270_driver; + +#endif /* __DRIVERS_S390_CHAR_TTY3270_H */
drivers/s390/cio/chp.c +6 -2
@@ -140,9 +140,11 @@ static ssize_t chp_measurement_chars_rea char *buf, loff_t off, size_t count) {struct channel_path *chp; +struct device *device;unsigned int size; - chp = to_channelpath(container_of(kobj, struct device, kobj)); + device = container_of(kobj, struct device, kobj); + chp =to_channelpath (device);if (!chp->cmg_chars)return 0 ;
@@ -193,9 +195,11 @@ static ssize_t chp_measurement_read(stru {struct channel_path *chp;struct channel_subsystem *css; +struct device *device;unsigned int size; - chp = to_channelpath(container_of(kobj, struct device, kobj)); + device = container_of(kobj, struct device, kobj); + chp =to_channelpath (device); css =to_css (chp->dev.parent); size =sizeof (struct cmg_entry );
drivers/s390/cio/cmf.c +1 -3
@@ -489,7 +489,6 @@ static struct cmb_area cmb_area = { .num_channels = 1024, }; -/* ****** old style CMB handling ********/ /*
@@ -809,7 +808,7 @@ static struct cmb_operations cmbops_basi .align = align_cmb, .attr_group = &cmf_attr_group, }; - +/* ******** extended cmb handling ********/ /**
@@ -1076,7 +1075,6 @@ static struct cmb_operations cmbops_exte .align = align_cmbe, .attr_group = &cmf_attr_group_ext, }; -static ssize_t cmb_show_attr (struct device *dev,char *buf,enum cmb_index idx) {
drivers/s390/scsi/zfcp_dbf.c +5 -5
@@ -19,8 +19,8 @@* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <asm/debug.h> #include <linux/ctype.h> +#include <asm/debug.h> #include "zfcp_ext.h" static u32 dbfsize =4 ;
@@ -35,17 +35,17 @@ static int zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck) {unsigned long long sec; -struct timespec xtime; +struct timespec dbftime;int len =0 ; stck -=0x8126d60e46000000LL - (0x3c26700LL *1000000 *4096 ); sec = stck >>12 ;do_div (sec,1000000 ); - xtime.tv_sec = sec; + dbftime.tv_sec = sec; stck -= (sec *1000000 ) <<12 ; - xtime.tv_nsec = ((stck *1000 ) >>12 ); + dbftime.tv_nsec = ((stck *1000 ) >>12 ); len +=sprintf (out_buf + len,"%-24s%011lu:%06lu\n" , - label, xtime.tv_sec, xtime.tv_nsec); + label, dbftime.tv_sec, dbftime.tv_nsec);return len; }
drivers/s390/scsi/zfcp_erp.c +8 -10
@@ -54,7 +54,7 @@ static int zfcp_erp_strategy_check_adaptstatic int zfcp_erp_strategy_statechange (int ,u32 ,struct zfcp_adapter *,struct zfcp_port *,struct zfcp_unit *,int ); -static inline int zfcp_erp_strategy_statechange_detected (atomic_t *,u32 ); +static int zfcp_erp_strategy_statechange_detected (atomic_t *,u32 );static int zfcp_erp_strategy_followup_actions (int ,struct zfcp_adapter *,struct zfcp_port *,struct zfcp_unit *,int );
@@ -106,8 +106,8 @@ static void zfcp_erp_action_cleanup(int,static void zfcp_erp_action_ready (struct zfcp_erp_action *);static int zfcp_erp_action_exists (struct zfcp_erp_action *); -static inline void zfcp_erp_action_to_ready (struct zfcp_erp_action *); -static inline void zfcp_erp_action_to_running (struct zfcp_erp_action *); +static void zfcp_erp_action_to_ready (struct zfcp_erp_action *); +static void zfcp_erp_action_to_running (struct zfcp_erp_action *);static void zfcp_erp_memwait_handler (unsigned long );
@@ -952,7 +952,7 @@ zfcp_erp_memwait_handler(unsigned long d* action gets an appropriate flag and will be processed * accordingly */ -void zfcp_erp_timeout_handler (unsigned long data) +static void zfcp_erp_timeout_handler (unsigned long data) {struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;struct zfcp_adapter *adapter = erp_action->adapter;
@@ -1491,7 +1491,7 @@ zfcp_erp_strategy_statechange(int actionreturn retval; } -static inline int +static int zfcp_erp_strategy_statechange_detected (atomic_t * target_status,u32 erp_status) {return
@@ -2001,7 +2001,7 @@ zfcp_erp_adapter_strategy_generic(struct* returns: 0 - successful setup * !0 - failed setup */ -int +static int zfcp_erp_adapter_strategy_open_qdio (struct zfcp_erp_action *erp_action) {int retval;
@@ -3248,8 +3248,7 @@ static void zfcp_erp_action_dismiss_unitzfcp_erp_action_dismiss (&unit->erp_action); } -static inline void -zfcp_erp_action_to_running (struct zfcp_erp_action *erp_action) +static void zfcp_erp_action_to_running (struct zfcp_erp_action *erp_action) {struct zfcp_adapter *adapter = erp_action->adapter;
@@ -3258,8 +3257,7 @@ zfcp_erp_action_to_running(struct zfcp_elist_move (&erp_action->list, &erp_action->adapter->erp_running_head); } -static inline void -zfcp_erp_action_to_ready (struct zfcp_erp_action *erp_action) +static void zfcp_erp_action_to_ready (struct zfcp_erp_action *erp_action) {struct zfcp_adapter *adapter = erp_action->adapter;
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.