From 9442bd2b3671f32f98f0eb0b4c245e69da51eeac Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 19 Aug 2007 17:12:50 -0700 Subject: [PATCH] --- yaml --- r: 64204 b: refs/heads/master c: 39dad26c37fdb1382e4173172a2704fa278f7fd6 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/i386/mm/fault.c | 5 +- trunk/arch/s390/hypfs/inode.c | 33 +--- trunk/arch/s390/kernel/Makefile | 2 +- trunk/arch/s390/kernel/diag.c | 102 ----------- trunk/arch/s390/kernel/dis.c | 2 +- trunk/arch/s390/kernel/kprobes.c | 2 +- trunk/arch/s390/kernel/s390_ksyms.c | 1 + trunk/arch/s390/mm/cmm.c | 1 - trunk/arch/s390/mm/init.c | 17 ++ trunk/drivers/s390/block/dasd_diag.c | 1 - trunk/drivers/s390/char/raw3270.c | 1 - trunk/drivers/s390/char/vmur.c | 250 +++++++++------------------ trunk/drivers/s390/char/vmur.h | 1 - trunk/drivers/s390/cio/cmf.c | 10 +- trunk/drivers/s390/cio/device.c | 5 +- trunk/drivers/s390/cio/device_id.c | 48 ++++- trunk/drivers/s390/cio/qdio.c | 5 +- trunk/include/asm-s390/atomic.h | 26 +-- trunk/include/asm-s390/cio.h | 15 ++ trunk/include/asm-s390/diag.h | 39 ----- trunk/include/asm-s390/pgalloc.h | 2 + trunk/net/dccp/ccids/ccid2.c | 2 +- 23 files changed, 196 insertions(+), 376 deletions(-) delete mode 100644 trunk/arch/s390/kernel/diag.c delete mode 100644 trunk/include/asm-s390/diag.h diff --git a/[refs] b/[refs] index 1c682a79d47c..2606254b10ec 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 53ce2dc2718c57346c543dab254fc900c6fe6c65 +refs/heads/master: 39dad26c37fdb1382e4173172a2704fa278f7fd6 diff --git a/trunk/arch/i386/mm/fault.c b/trunk/arch/i386/mm/fault.c index fcb38e7f3543..01ffdd4964f0 100644 --- a/trunk/arch/i386/mm/fault.c +++ b/trunk/arch/i386/mm/fault.c @@ -249,10 +249,9 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) pmd_k = pmd_offset(pud_k, address); if (!pmd_present(*pmd_k)) return NULL; - if (!pmd_present(*pmd)) { + if (!pmd_present(*pmd)) set_pmd(pmd, *pmd_k); - arch_flush_lazy_mmu_mode(); - } else + else BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); return pmd_k; } diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c index 5245717295b8..ad4ca75c0f04 100644 --- a/trunk/arch/s390/hypfs/inode.c +++ b/trunk/arch/s390/hypfs/inode.c @@ -60,28 +60,17 @@ static void hypfs_add_dentry(struct dentry *dentry) hypfs_last_dentry = dentry; } -static inline int hypfs_positive(struct dentry *dentry) -{ - return dentry->d_inode && !d_unhashed(dentry); -} - static void hypfs_remove(struct dentry *dentry) { struct dentry *parent; parent = dentry->d_parent; - if (!parent || !parent->d_inode) - return; - mutex_lock(&parent->d_inode->i_mutex); - if (hypfs_positive(dentry)) { - if (S_ISDIR(dentry->d_inode->i_mode)) - simple_rmdir(parent->d_inode, dentry); - else - simple_unlink(parent->d_inode, dentry); - } + if (S_ISDIR(dentry->d_inode->i_mode)) + simple_rmdir(parent->d_inode, dentry); + else + simple_unlink(parent->d_inode, dentry); d_delete(dentry); dput(dentry); - mutex_unlock(&parent->d_inode->i_mutex); } static void hypfs_delete_tree(struct dentry *root) @@ -326,7 +315,6 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent) } hypfs_update_update(sb); sb->s_root = root_dentry; - printk(KERN_INFO "hypfs: Hypervisor filesystem mounted\n"); return 0; err_tree: @@ -368,17 +356,13 @@ static struct dentry *hypfs_create_file(struct super_block *sb, qname.name = name; qname.len = strlen(name); qname.hash = full_name_hash(name, qname.len); - mutex_lock(&parent->d_inode->i_mutex); dentry = lookup_one_len(name, parent, strlen(name)); - if (IS_ERR(dentry)) { - dentry = ERR_PTR(-ENOMEM); - goto fail; - } + if (IS_ERR(dentry)) + return ERR_PTR(-ENOMEM); inode = hypfs_make_inode(sb, mode); if (!inode) { dput(dentry); - dentry = ERR_PTR(-ENOMEM); - goto fail; + return ERR_PTR(-ENOMEM); } if (mode & S_IFREG) { inode->i_fop = &hypfs_file_ops; @@ -395,8 +379,6 @@ static struct dentry *hypfs_create_file(struct super_block *sb, inode->i_private = data; d_instantiate(dentry, inode); dget(dentry); -fail: - mutex_unlock(&parent->d_inode->i_mutex); return dentry; } @@ -409,6 +391,7 @@ struct dentry *hypfs_mkdir(struct super_block *sb, struct dentry *parent, if (IS_ERR(dentry)) return dentry; hypfs_add_dentry(dentry); + parent->d_inode->i_nlink++; return dentry; } diff --git a/trunk/arch/s390/kernel/Makefile b/trunk/arch/s390/kernel/Makefile index 56cb71007cd9..3195d375bd51 100644 --- a/trunk/arch/s390/kernel/Makefile +++ b/trunk/arch/s390/kernel/Makefile @@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional obj-y := bitmap.o traps.o time.o process.o base.o early.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ - semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o + semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) diff --git a/trunk/arch/s390/kernel/diag.c b/trunk/arch/s390/kernel/diag.c deleted file mode 100644 index c032d11da8a1..000000000000 --- a/trunk/arch/s390/kernel/diag.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Implementation of s390 diagnose codes - * - * Copyright IBM Corp. 2007 - * Author(s): Michael Holzheu - */ - -#include -#include - -/* - * Diagnose 10: Release pages - */ -void diag10(unsigned long addr) -{ - if (addr >= 0x7ff00000) - return; - asm volatile( -#ifdef CONFIG_64BIT - " sam31\n" - " diag %0,%0,0x10\n" - "0: sam64\n" -#else - " diag %0,%0,0x10\n" - "0:\n" -#endif - EX_TABLE(0b, 0b) - : : "a" (addr)); -} -EXPORT_SYMBOL(diag10); - -/* - * Diagnose 14: Input spool file manipulation - */ -int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode) -{ - register unsigned long _ry1 asm("2") = ry1; - register unsigned long _ry2 asm("3") = subcode; - int rc = 0; - - asm volatile( -#ifdef CONFIG_64BIT - " sam31\n" - " diag %2,2,0x14\n" - " sam64\n" -#else - " diag %2,2,0x14\n" -#endif - " ipm %0\n" - " srl %0,28\n" - : "=d" (rc), "+d" (_ry2) - : "d" (rx), "d" (_ry1) - : "cc"); - - return rc; -} -EXPORT_SYMBOL(diag14); - -/* - * Diagnose 210: Get information about a virtual device - */ -int diag210(struct diag210 *addr) -{ - /* - * diag 210 needs its data below the 2GB border, so we - * use a static data area to be sure - */ - static struct diag210 diag210_tmp; - static DEFINE_SPINLOCK(diag210_lock); - unsigned long flags; - int ccode; - - spin_lock_irqsave(&diag210_lock, flags); - diag210_tmp = *addr; - -#ifdef CONFIG_64BIT - asm volatile( - " lhi %0,-1\n" - " sam31\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1: sam64\n" - EX_TABLE(0b, 1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#else - asm volatile( - " lhi %0,-1\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b, 1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#endif - - *addr = diag210_tmp; - spin_unlock_irqrestore(&diag210_lock, flags); - - return ccode; -} -EXPORT_SYMBOL(diag210); diff --git a/trunk/arch/s390/kernel/dis.c b/trunk/arch/s390/kernel/dis.c index 50d2235df732..d3057318f2bf 100644 --- a/trunk/arch/s390/kernel/dis.c +++ b/trunk/arch/s390/kernel/dis.c @@ -577,7 +577,7 @@ static struct insn opcode_b2[] = { { "esta", 0x4a, INSTR_RRE_RR }, { "lura", 0x4b, INSTR_RRE_RR }, { "tar", 0x4c, INSTR_RRE_AR }, - { "cpya", 0x4d, INSTR_RRE_AA }, + { "cpya", INSTR_RRE_AA }, { "sar", 0x4e, INSTR_RRE_AR }, { "ear", 0x4f, INSTR_RRE_RA }, { "csp", 0x50, INSTR_RRE_RR }, diff --git a/trunk/arch/s390/kernel/kprobes.c b/trunk/arch/s390/kernel/kprobes.c index e40373d9fbce..358d2bbbc481 100644 --- a/trunk/arch/s390/kernel/kprobes.c +++ b/trunk/arch/s390/kernel/kprobes.c @@ -85,7 +85,7 @@ void __kprobes get_instruction_type(struct arch_specific_insn *ainsn) ainsn->reg = (*ainsn->insn & 0xf0) >> 4; /* save the instruction length (pop 5-5) in bytes */ - switch (*(__u8 *) (ainsn->insn) >> 6) { + switch (*(__u8 *) (ainsn->insn) >> 4) { case 0: ainsn->ilen = 2; break; diff --git a/trunk/arch/s390/kernel/s390_ksyms.c b/trunk/arch/s390/kernel/s390_ksyms.c index 7234c737f825..90b5ef529eb7 100644 --- a/trunk/arch/s390/kernel/s390_ksyms.c +++ b/trunk/arch/s390/kernel/s390_ksyms.c @@ -25,6 +25,7 @@ EXPORT_SYMBOL(_oi_bitmap); EXPORT_SYMBOL(_ni_bitmap); EXPORT_SYMBOL(_zb_findmap); EXPORT_SYMBOL(_sb_findmap); +EXPORT_SYMBOL(diag10); /* * semaphore ops diff --git a/trunk/arch/s390/mm/cmm.c b/trunk/arch/s390/mm/cmm.c index fabc50adc46a..c5b2f4f078bc 100644 --- a/trunk/arch/s390/mm/cmm.c +++ b/trunk/arch/s390/mm/cmm.c @@ -20,7 +20,6 @@ #include #include -#include static char *sender = "VMRMSVM"; module_param(sender, charp, 0400); diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index 3a25bbf2eb0a..9098531a2671 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -42,6 +42,23 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); +void diag10(unsigned long addr) +{ + if (addr >= 0x7ff00000) + return; + asm volatile( +#ifdef CONFIG_64BIT + " sam31\n" + " diag %0,%0,0x10\n" + "0: sam64\n" +#else + " diag %0,%0,0x10\n" + "0:\n" +#endif + EX_TABLE(0b,0b) + : : "a" (addr)); +} + void show_mem(void) { int i, total = 0, reserved = 0; diff --git a/trunk/drivers/s390/block/dasd_diag.c b/trunk/drivers/s390/block/dasd_diag.c index d32c60dbdd82..eccac1c3b71b 100644 --- a/trunk/drivers/s390/block/dasd_diag.c +++ b/trunk/drivers/s390/block/dasd_diag.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "dasd_int.h" #include "dasd_diag.h" diff --git a/trunk/drivers/s390/char/raw3270.c b/trunk/drivers/s390/char/raw3270.c index 2edd5fb6d3dc..4f2f81b16cfa 100644 --- a/trunk/drivers/s390/char/raw3270.c +++ b/trunk/drivers/s390/char/raw3270.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "raw3270.h" diff --git a/trunk/drivers/s390/char/vmur.c b/trunk/drivers/s390/char/vmur.c index d70a6e65bf14..04b19bdc09da 100644 --- a/trunk/drivers/s390/char/vmur.c +++ b/trunk/drivers/s390/char/vmur.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "vmur.h" @@ -69,26 +68,8 @@ static struct ccw_driver ur_driver = { .set_offline = ur_set_offline, }; -static DEFINE_MUTEX(vmur_mutex); - /* * Allocation, freeing, getting and putting of urdev structures - * - * Each ur device (urd) contains a reference to its corresponding ccw device - * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the - * ur device using the cdev->dev.driver_data pointer. - * - * urd references: - * - ur_probe gets a urd reference, ur_remove drops the reference - * (cdev->dev.driver_data) - * - ur_open gets a urd reference, ur_relase drops the reference - * (urf->urd) - * - * cdev references: - * - urdev_alloc get a cdev reference (urd->cdev) - * - urdev_free drops the cdev reference (urd->cdev) - * - * Setting and clearing of cdev->dev.driver_data is protected by the ccwdev lock */ static struct urdev *urdev_alloc(struct ccw_device *cdev) { @@ -97,61 +78,42 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev) urd = kzalloc(sizeof(struct urdev), GFP_KERNEL); if (!urd) return NULL; + urd->cdev = cdev; urd->reclen = cdev->id.driver_info; ccw_device_get_id(cdev, &urd->dev_id); mutex_init(&urd->io_mutex); mutex_init(&urd->open_mutex); - atomic_set(&urd->ref_count, 1); - urd->cdev = cdev; - get_device(&cdev->dev); return urd; } static void urdev_free(struct urdev *urd) { - TRACE("urdev_free: %p\n", urd); - if (urd->cdev) - put_device(&urd->cdev->dev); kfree(urd); } -static void urdev_get(struct urdev *urd) -{ - atomic_inc(&urd->ref_count); -} - -static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev) -{ - struct urdev *urd; - unsigned long flags; - - spin_lock_irqsave(get_ccwdev_lock(cdev), flags); - urd = cdev->dev.driver_data; - if (urd) - urdev_get(urd); - spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); - return urd; -} - +/* + * This is how the character device driver gets a reference to a + * ur device. When this call returns successfully, a reference has + * been taken (by get_device) on the underlying kobject. The recipient + * of this urdev pointer must eventually drop it with urdev_put(urd) + * which does the corresponding put_device(). + */ static struct urdev *urdev_get_from_devno(u16 devno) { char bus_id[16]; struct ccw_device *cdev; - struct urdev *urd; sprintf(bus_id, "0.0.%04x", devno); cdev = get_ccwdev_by_busid(&ur_driver, bus_id); if (!cdev) return NULL; - urd = urdev_get_from_cdev(cdev); - put_device(&cdev->dev); - return urd; + + return cdev->dev.driver_data; } static void urdev_put(struct urdev *urd) { - if (atomic_dec_and_test(&urd->ref_count)) - urdev_free(urd); + put_device(&urd->cdev->dev); } /* @@ -283,7 +245,6 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, return; } urd = cdev->dev.driver_data; - BUG_ON(!urd); /* On special conditions irb is an error pointer */ if (IS_ERR(irb)) urd->io_request_rc = PTR_ERR(irb); @@ -301,15 +262,9 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, static ssize_t ur_attr_reclen_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct urdev *urd; - int rc; + struct urdev *urd = dev->driver_data; - urd = urdev_get_from_cdev(to_ccwdev(dev)); - if (!urd) - return -ENODEV; - rc = sprintf(buf, "%zu\n", urd->reclen); - urdev_put(urd); - return rc; + return sprintf(buf, "%zu\n", urd->reclen); } static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL); @@ -424,6 +379,31 @@ static ssize_t ur_write(struct file *file, const char __user *udata, return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); } +static int do_diag_14(unsigned long rx, unsigned long ry1, + unsigned long subcode) +{ + register unsigned long _ry1 asm("2") = ry1; + register unsigned long _ry2 asm("3") = subcode; + int rc = 0; + + asm volatile( +#ifdef CONFIG_64BIT + " sam31\n" + " diag %2,2,0x14\n" + " sam64\n" +#else + " diag %2,2,0x14\n" +#endif + " ipm %0\n" + " srl %0,28\n" + : "=d" (rc), "+d" (_ry2) + : "d" (rx), "d" (_ry1) + : "cc"); + + TRACE("diag 14: subcode=0x%lx, cc=%i\n", subcode, rc); + return rc; +} + /* * diagnose code 0x14 subcode 0x0028 - position spool file to designated * record @@ -435,7 +415,7 @@ static int diag_position_to_record(int devno, int record) { int cc; - cc = diag14(record, devno, 0x28); + cc = do_diag_14(record, devno, 0x28); switch (cc) { case 0: return 0; @@ -460,7 +440,7 @@ static int diag_read_file(int devno, char *buf) { int cc; - cc = diag14((unsigned long) buf, devno, 0x00); + cc = do_diag_14((unsigned long) buf, devno, 0x00); switch (cc) { case 0: return 0; @@ -553,7 +533,7 @@ static int diag_read_next_file_info(struct file_control_block *buf, int spid) { int cc; - cc = diag14((unsigned long) buf, spid, 0xfff); + cc = do_diag_14((unsigned long) buf, spid, 0xfff); switch (cc) { case 0: return 0; @@ -770,94 +750,86 @@ static struct file_operations ur_fops = { /* * ccw_device infrastructure: - * ur_probe creates the struct urdev (with refcount = 1), the device - * attributes, sets up the interrupt handler and validates the virtual - * unit record device. - * ur_remove removes the device attributes and drops the reference to - * struct urdev. - * - * ur_probe, ur_remove, ur_set_online and ur_set_offline are serialized - * by the vmur_mutex lock. - * - * urd->char_device is used as indication that the online function has - * been completed successfully. + * ur_probe gets its own ref to the device (i.e. get_device), + * creates the struct urdev, the device attributes, sets up + * the interrupt handler and validates the virtual unit record device. + * ur_remove removes the device attributes, frees the struct urdev + * and drops (put_device) the ref to the device we got in ur_probe. */ static int ur_probe(struct ccw_device *cdev) { struct urdev *urd; int rc; - TRACE("ur_probe: cdev=%p\n", cdev); + TRACE("ur_probe: cdev=%p state=%d\n", cdev, *(int *) cdev->private); + + if (!get_device(&cdev->dev)) + return -ENODEV; - mutex_lock(&vmur_mutex); urd = urdev_alloc(cdev); if (!urd) { rc = -ENOMEM; - goto fail_unlock; + goto fail; } - rc = ur_create_attributes(&cdev->dev); if (rc) { rc = -ENOMEM; - goto fail_urdev_put; + goto fail; } + cdev->dev.driver_data = urd; cdev->handler = ur_int_handler; /* validate virtual unit record device */ urd->class = get_urd_class(urd); if (urd->class < 0) { rc = urd->class; - goto fail_remove_attr; + goto fail; } if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { rc = -ENOTSUPP; - goto fail_remove_attr; + goto fail; } - spin_lock_irq(get_ccwdev_lock(cdev)); - cdev->dev.driver_data = urd; - spin_unlock_irq(get_ccwdev_lock(cdev)); - mutex_unlock(&vmur_mutex); return 0; -fail_remove_attr: - ur_remove_attributes(&cdev->dev); -fail_urdev_put: - urdev_put(urd); -fail_unlock: - mutex_unlock(&vmur_mutex); +fail: + urdev_free(urd); + put_device(&cdev->dev); return rc; } +static void ur_remove(struct ccw_device *cdev) +{ + struct urdev *urd = cdev->dev.driver_data; + + TRACE("ur_remove\n"); + if (cdev->online) + ur_set_offline(cdev); + ur_remove_attributes(&cdev->dev); + urdev_free(urd); + put_device(&cdev->dev); +} + static int ur_set_online(struct ccw_device *cdev) { struct urdev *urd; int minor, major, rc; char node_id[16]; - TRACE("ur_set_online: cdev=%p\n", cdev); - - mutex_lock(&vmur_mutex); - urd = urdev_get_from_cdev(cdev); - if (!urd) { - /* ur_remove already deleted our urd */ - rc = -ENODEV; - goto fail_unlock; - } + TRACE("ur_set_online: cdev=%p state=%d\n", cdev, + *(int *) cdev->private); - if (urd->char_device) { - /* Another ur_set_online was faster */ - rc = -EBUSY; - goto fail_urdev_put; - } + if (!try_module_get(ur_driver.owner)) + return -EINVAL; + urd = (struct urdev *) cdev->dev.driver_data; minor = urd->dev_id.devno; major = MAJOR(ur_first_dev_maj_min); urd->char_device = cdev_alloc(); if (!urd->char_device) { rc = -ENOMEM; - goto fail_urdev_put; + goto fail_module_put; } cdev_init(urd->char_device, &ur_fops); @@ -886,79 +858,29 @@ static int ur_set_online(struct ccw_device *cdev) TRACE("ur_set_online: device_create rc=%d\n", rc); goto fail_free_cdev; } - urdev_put(urd); - mutex_unlock(&vmur_mutex); + return 0; fail_free_cdev: cdev_del(urd->char_device); - urd->char_device = NULL; -fail_urdev_put: - urdev_put(urd); -fail_unlock: - mutex_unlock(&vmur_mutex); +fail_module_put: + module_put(ur_driver.owner); + return rc; } -static int ur_set_offline_force(struct ccw_device *cdev, int force) +static int ur_set_offline(struct ccw_device *cdev) { struct urdev *urd; - int rc; - TRACE("ur_set_offline: cdev=%p\n", cdev); - urd = urdev_get_from_cdev(cdev); - if (!urd) - /* ur_remove already deleted our urd */ - return -ENODEV; - if (!urd->char_device) { - /* Another ur_set_offline was faster */ - rc = -EBUSY; - goto fail_urdev_put; - } - if (!force && (atomic_read(&urd->ref_count) > 2)) { - /* There is still a user of urd (e.g. ur_open) */ - TRACE("ur_set_offline: BUSY\n"); - rc = -EBUSY; - goto fail_urdev_put; - } + TRACE("ur_set_offline: cdev=%p cdev->private=%p state=%d\n", + cdev, cdev->private, *(int *) cdev->private); + urd = (struct urdev *) cdev->dev.driver_data; device_destroy(vmur_class, urd->char_device->dev); cdev_del(urd->char_device); - urd->char_device = NULL; - rc = 0; - -fail_urdev_put: - urdev_put(urd); - return rc; -} - -static int ur_set_offline(struct ccw_device *cdev) -{ - int rc; - - mutex_lock(&vmur_mutex); - rc = ur_set_offline_force(cdev, 0); - mutex_unlock(&vmur_mutex); - return rc; -} - -static void ur_remove(struct ccw_device *cdev) -{ - unsigned long flags; - - TRACE("ur_remove\n"); + module_put(ur_driver.owner); - mutex_lock(&vmur_mutex); - - if (cdev->online) - ur_set_offline_force(cdev, 1); - ur_remove_attributes(&cdev->dev); - - spin_lock_irqsave(get_ccwdev_lock(cdev), flags); - urdev_put(cdev->dev.driver_data); - cdev->dev.driver_data = NULL; - spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); - - mutex_unlock(&vmur_mutex); + return 0; } /* diff --git a/trunk/drivers/s390/char/vmur.h b/trunk/drivers/s390/char/vmur.h index fa959644735a..2b3c564e0472 100644 --- a/trunk/drivers/s390/char/vmur.h +++ b/trunk/drivers/s390/char/vmur.h @@ -70,7 +70,6 @@ struct urdev { size_t reclen; /* Record length for *write* CCWs */ int class; /* VM device class */ int io_request_rc; /* return code from I/O request */ - atomic_t ref_count; /* reference counter */ }; /* diff --git a/trunk/drivers/s390/cio/cmf.c b/trunk/drivers/s390/cio/cmf.c index 34a796913b06..02fd00b55e1b 100644 --- a/trunk/drivers/s390/cio/cmf.c +++ b/trunk/drivers/s390/cio/cmf.c @@ -594,9 +594,6 @@ alloc_cmb (struct ccw_device *cdev) free_pages((unsigned long)mem, get_order(size)); } else if (!mem) { /* no luck */ - printk(KERN_WARNING "cio: failed to allocate area " - "for measuring %d subchannels\n", - cmb_area.num_channels); ret = -ENOMEM; goto out; } else { @@ -1282,6 +1279,13 @@ init_cmf(void) case CMF_BASIC: format_string = "basic"; cmbops = &cmbops_basic; + if (cmb_area.num_channels > 4096 || cmb_area.num_channels < 1) { + printk(KERN_ERR "cio: Basic channel measurement " + "facility can only use 1 to 4096 devices\n" + KERN_ERR "when the cmf driver is built" + " as a loadable module\n"); + return 1; + } break; case CMF_EXTENDED: format_string = "extended"; diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index e44d92eac8e9..297659fa0e26 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -117,10 +117,7 @@ static int ccw_uevent(struct device *dev, char **envp, int num_envp, snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, "MODALIAS=%s", modalias_buf); - if (ret) - return ret; - envp[i] = NULL; - return 0; + return ret; } struct bus_type ccw_bus_type; diff --git a/trunk/drivers/s390/cio/device_id.c b/trunk/drivers/s390/cio/device_id.c index f232832f2b22..60b9347f7c92 100644 --- a/trunk/drivers/s390/cio/device_id.c +++ b/trunk/drivers/s390/cio/device_id.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "cio.h" #include "cio_debug.h" @@ -25,6 +24,51 @@ #include "device.h" #include "ioasm.h" +/* + * diag210 is used under VM to get information about a virtual device + */ +int +diag210(struct diag210 * addr) +{ + /* + * diag 210 needs its data below the 2GB border, so we + * use a static data area to be sure + */ + static struct diag210 diag210_tmp; + static DEFINE_SPINLOCK(diag210_lock); + unsigned long flags; + int ccode; + + spin_lock_irqsave(&diag210_lock, flags); + diag210_tmp = *addr; + +#ifdef CONFIG_64BIT + asm volatile( + " lhi %0,-1\n" + " sam31\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1: sam64\n" + EX_TABLE(0b,1b) + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); +#else + asm volatile( + " lhi %0,-1\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b,1b) + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); +#endif + + *addr = diag210_tmp; + spin_unlock_irqrestore(&diag210_lock, flags); + + return ccode; +} + /* * Input : * devno - device number @@ -305,3 +349,5 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) break; } } + +EXPORT_SYMBOL(diag210); diff --git a/trunk/drivers/s390/cio/qdio.c b/trunk/drivers/s390/cio/qdio.c index d8d479876ec7..03347aed2b3e 100644 --- a/trunk/drivers/s390/cio/qdio.c +++ b/trunk/drivers/s390/cio/qdio.c @@ -195,8 +195,6 @@ qdio_do_eqbs(struct qdio_q *q, unsigned char *state, again: ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); rc = qdio_check_ccq(q, ccq); - if ((ccq == 96) && (tmp_cnt != *cnt)) - rc = 0; if (rc == 1) { QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); goto again; @@ -742,8 +740,7 @@ qdio_get_outbound_buffer_frontier(struct qdio_q *q) first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), (QDIO_MAX_BUFFERS_PER_Q-1)); - if (((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) || - (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) + if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) SYNC_MEMORY; check_next: diff --git a/trunk/include/asm-s390/atomic.h b/trunk/include/asm-s390/atomic.h index 2d184655bc5d..ea486952f778 100644 --- a/trunk/include/asm-s390/atomic.h +++ b/trunk/include/asm-s390/atomic.h @@ -67,17 +67,8 @@ typedef struct { #endif /* __GNUC__ */ -static inline int atomic_read(const atomic_t *v) -{ - barrier(); - return v->counter; -} - -static inline void atomic_set(atomic_t *v, int i) -{ - v->counter = i; - barrier(); -} +#define atomic_read(v) ((v)->counter) +#define atomic_set(v,i) (((v)->counter) = (i)) static __inline__ int atomic_add_return(int i, atomic_t * v) { @@ -191,17 +182,8 @@ typedef struct { #endif /* __GNUC__ */ -static inline long long atomic64_read(const atomic64_t *v) -{ - barrier(); - return v->counter; -} - -static inline void atomic64_set(atomic64_t *v, long long i) -{ - v->counter = i; - barrier(); -} +#define atomic64_read(v) ((v)->counter) +#define atomic64_set(v,i) (((v)->counter) = (i)) static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) { diff --git a/trunk/include/asm-s390/cio.h b/trunk/include/asm-s390/cio.h index 1982fb344164..f738d2827582 100644 --- a/trunk/include/asm-s390/cio.h +++ b/trunk/include/asm-s390/cio.h @@ -258,6 +258,19 @@ struct ciw { /* Sick revalidation of device. */ #define CIO_REVALIDATE 0x0008 +struct diag210 { + __u16 vrdcdvno : 16; /* device number (input) */ + __u16 vrdclen : 16; /* data block length (input) */ + __u32 vrdcvcla : 8; /* virtual device class (output) */ + __u32 vrdcvtyp : 8; /* virtual device type (output) */ + __u32 vrdcvsta : 8; /* virtual device status (output) */ + __u32 vrdcvfla : 8; /* virtual device flags (output) */ + __u32 vrdcrccl : 8; /* real device class (output) */ + __u32 vrdccrty : 8; /* real device type (output) */ + __u32 vrdccrmd : 8; /* real device model (output) */ + __u32 vrdccrft : 8; /* real device feature (output) */ +} __attribute__ ((packed,aligned(4))); + struct ccw_dev_id { u8 ssid; u16 devno; @@ -272,6 +285,8 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, return 0; } +extern int diag210(struct diag210 *addr); + extern void wait_cons_dev(void); extern void css_schedule_reprobe(void); diff --git a/trunk/include/asm-s390/diag.h b/trunk/include/asm-s390/diag.h deleted file mode 100644 index 72b2e2f2d32d..000000000000 --- a/trunk/include/asm-s390/diag.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * s390 diagnose functions - * - * Copyright IBM Corp. 2007 - * Author(s): Michael Holzheu - */ - -#ifndef _ASM_S390_DIAG_H -#define _ASM_S390_DIAG_H - -/* - * Diagnose 10: Release pages - */ -extern void diag10(unsigned long addr); - -/* - * Diagnose 14: Input spool file manipulation - */ -extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode); - -/* - * Diagnose 210: Get information about a virtual device - */ -struct diag210 { - u16 vrdcdvno; /* device number (input) */ - u16 vrdclen; /* data block length (input) */ - u8 vrdcvcla; /* virtual device class (output) */ - u8 vrdcvtyp; /* virtual device type (output) */ - u8 vrdcvsta; /* virtual device status (output) */ - u8 vrdcvfla; /* virtual device flags (output) */ - u8 vrdcrccl; /* real device class (output) */ - u8 vrdccrty; /* real device type (output) */ - u8 vrdccrmd; /* real device model (output) */ - u8 vrdccrft; /* real device feature (output) */ -} __attribute__((packed, aligned(4))); - -extern int diag210(struct diag210 *addr); - -#endif /* _ASM_S390_DIAG_H */ diff --git a/trunk/include/asm-s390/pgalloc.h b/trunk/include/asm-s390/pgalloc.h index e45d3c9a4b7e..56c8a6c80e2e 100644 --- a/trunk/include/asm-s390/pgalloc.h +++ b/trunk/include/asm-s390/pgalloc.h @@ -19,6 +19,8 @@ #define check_pgt_cache() do {} while (0) +extern void diag10(unsigned long addr); + /* * Page allocation orders. */ diff --git a/trunk/net/dccp/ccids/ccid2.c b/trunk/net/dccp/ccids/ccid2.c index 248d20f4c7c4..d29b88fe723c 100644 --- a/trunk/net/dccp/ccids/ccid2.c +++ b/trunk/net/dccp/ccids/ccid2.c @@ -298,7 +298,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) int rc; ccid2_pr_debug("allocating more space in history\n"); - rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_KERNEL); + rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, gfp_any()); BUG_ON(rc); /* XXX what do we do? */ next = hctx->ccid2hctx_seqh->ccid2s_next;