diff options
Diffstat (limited to 'drivers/s390')
28 files changed, 535 insertions, 437 deletions
diff --git a/drivers/s390/Makefile b/drivers/s390/Makefile index 95bccfd3f..e5225ad9c 100644 --- a/drivers/s390/Makefile +++ b/drivers/s390/Makefile @@ -2,7 +2,7 @@ # Makefile for the S/390 specific device drivers # -obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/ +obj-y += cio/ block/ char/ crypto/ net/ scsi/ virtio/ drivers-y += drivers/s390/built-in.o diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 57fd66357..f73d2f579 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -38,6 +38,8 @@ */ #define DASD_CHANQ_MAX_SIZE 4 +#define DASD_DIAG_MOD "dasd_diag_mod" + /* * SECTION: exported variables of dasd.c */ @@ -1861,6 +1863,33 @@ static void __dasd_device_check_expire(struct dasd_device *device) } /* + * return 1 when device is not eligible for IO + */ +static int __dasd_device_is_unusable(struct dasd_device *device, + struct dasd_ccw_req *cqr) +{ + int mask = ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM); + + if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) { + /* dasd is being set offline. */ + return 1; + } + if (device->stopped) { + if (device->stopped & mask) { + /* stopped and CQR will not change that. */ + return 1; + } + if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags)) { + /* CQR is not able to change device to + * operational. */ + return 1; + } + /* CQR required to get device operational. */ + } + return 0; +} + +/* * Take a look at the first request on the ccw queue and check * if it needs to be started. */ @@ -1874,13 +1903,8 @@ static void __dasd_device_start_head(struct dasd_device *device) cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); if (cqr->status != DASD_CQR_QUEUED) return; - /* when device is stopped, return request to previous layer - * exception: only the disconnect or unresumed bits are set and the - * cqr is a path verification request - */ - if (device->stopped && - !(!(device->stopped & ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM)) - && test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))) { + /* if device is not usable return request to upper layer */ + if (__dasd_device_is_unusable(device, cqr)) { cqr->intrc = -EAGAIN; cqr->status = DASD_CQR_CLEARED; dasd_schedule_device_bh(device); @@ -3300,6 +3324,21 @@ int dasd_generic_set_online(struct ccw_device *cdev, discipline = base_discipline; if (device->features & DASD_FEATURE_USEDIAG) { if (!dasd_diag_discipline_pointer) { + /* Try to load the required module. */ + rc = request_module(DASD_DIAG_MOD); + if (rc) { + pr_warn("%s Setting the DASD online failed " + "because the required module %s " + "could not be loaded (rc=%d)\n", + dev_name(&cdev->dev), DASD_DIAG_MOD, + rc); + dasd_delete_device(device); + return -ENODEV; + } + } + /* Module init could have failed, so check again here after + * request_module(). */ + if (!dasd_diag_discipline_pointer) { pr_warn("%s Setting the DASD online failed because of missing DIAG discipline\n", dev_name(&cdev->dev)); dasd_delete_device(device); diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index a2597e683..ee3a6faae 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c @@ -699,7 +699,8 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device) struct dasd_device, alias_list); spin_unlock_irqrestore(&lcu->lock, flags); alias_priv = (struct dasd_eckd_private *) alias_device->private; - if ((alias_priv->count < private->count) && !alias_device->stopped) + if ((alias_priv->count < private->count) && !alias_device->stopped && + !test_bit(DASD_FLAG_OFFLINE, &alias_device->flags)) return alias_device; else return NULL; diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 90f39f79f..ef1d9fb06 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c @@ -99,9 +99,8 @@ void dasd_gendisk_free(struct dasd_block *block) int dasd_scan_partitions(struct dasd_block *block) { struct block_device *bdev; - int retry, rc; + int rc; - retry = 5; bdev = bdget_disk(block->gdp, 0); if (!bdev) { DBF_DEV_EVENT(DBF_ERR, block->base, "%s", @@ -116,19 +115,11 @@ int dasd_scan_partitions(struct dasd_block *block) rc); return -ENODEV; } - /* - * See fs/partition/check.c:register_disk,rescan_partitions - * Can't call rescan_partitions directly. Use ioctl. - */ - rc = ioctl_by_bdev(bdev, BLKRRPART, 0); - while (rc == -EBUSY && retry > 0) { - schedule(); - rc = ioctl_by_bdev(bdev, BLKRRPART, 0); - retry--; + + rc = blkdev_reread_part(bdev); + if (rc) DBF_DEV_EVENT(DBF_ERR, block->base, - "scan partitions error, retry %d rc %d", - retry, rc); - } + "scan partitions error, rc %d", rc); /* * Since the matching blkdev_put call to the blkdev_get in diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 01463b052..ef04a9f7a 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -433,20 +433,23 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs, case KDSKBSENT: if (!perm) return -EPERM; - len = strnlen_user(u_kbs->kb_string, - sizeof(u_kbs->kb_string) - 1); + len = strnlen_user(u_kbs->kb_string, sizeof(u_kbs->kb_string)); if (!len) return -EFAULT; - if (len > sizeof(u_kbs->kb_string) - 1) + if (len > sizeof(u_kbs->kb_string)) return -EINVAL; - p = kmalloc(len + 1, GFP_KERNEL); + p = kmalloc(len, GFP_KERNEL); if (!p) return -ENOMEM; if (copy_from_user(p, u_kbs->kb_string, len)) { kfree(p); return -EFAULT; } - p[len] = 0; + /* + * Make sure the string is terminated by 0. User could have + * modified it between us running strnlen_user() and copying it. + */ + p[len - 1] = 0; kfree(kbd->func_table[kb_func]); kbd->func_table[kb_func] = p; break; diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 41ba56d2e..5e20513c0 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -665,7 +665,7 @@ sclp_state_change_cb(struct evbuf_header *evbuf) sclp_send_mask = scbuf->sclp_send_mask; spin_unlock_irqrestore(&sclp_lock, flags); if (scbuf->validity_sclp_active_facility_mask) - sclp_facilities = scbuf->sclp_active_facility_mask; + sclp.facilities = scbuf->sclp_active_facility_mask; sclp_dispatch_state_change(); } diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index a88069f8c..026e38990 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -100,13 +100,11 @@ struct init_sccb { sccb_mask_t sclp_send_mask; } __attribute__((packed)); -extern u64 sclp_facilities; - -#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) -#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) -#define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL) -#define SCLP_HAS_CPU_RECONFIG (sclp_facilities & 0x0400000000000000ULL) -#define SCLP_HAS_PCI_RECONFIG (sclp_facilities & 0x0000000040000000ULL) +#define SCLP_HAS_CHP_INFO (sclp.facilities & 0x8000000000000000ULL) +#define SCLP_HAS_CHP_RECONFIG (sclp.facilities & 0x2000000000000000ULL) +#define SCLP_HAS_CPU_INFO (sclp.facilities & 0x0800000000000000ULL) +#define SCLP_HAS_CPU_RECONFIG (sclp.facilities & 0x0400000000000000ULL) +#define SCLP_HAS_PCI_RECONFIG (sclp.facilities & 0x0000000040000000ULL) struct gds_subvector { @@ -191,9 +189,6 @@ void sclp_sdias_exit(void); extern int sclp_console_pages; extern int sclp_console_drop; extern unsigned long sclp_console_full; -extern u8 sclp_fac84; -extern unsigned long long sclp_rzm; -extern unsigned long long sclp_rnmax; /* useful inlines */ diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 7be782116..e9485fbbb 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -92,8 +92,8 @@ struct read_cpu_info_sccb { u8 reserved[4096 - 16]; } __attribute__((packed, aligned(PAGE_SIZE))); -static void sclp_fill_cpu_info(struct sclp_cpu_info *info, - struct read_cpu_info_sccb *sccb) +static void sclp_fill_core_info(struct sclp_core_info *info, + struct read_cpu_info_sccb *sccb) { char *page = (char *) sccb; @@ -101,12 +101,11 @@ static void sclp_fill_cpu_info(struct sclp_cpu_info *info, info->configured = sccb->nr_configured; info->standby = sccb->nr_standby; info->combined = sccb->nr_configured + sccb->nr_standby; - info->has_cpu_type = sclp_fac84 & 0x1; - memcpy(&info->cpu, page + sccb->offset_configured, - info->combined * sizeof(struct sclp_cpu_entry)); + memcpy(&info->core, page + sccb->offset_configured, + info->combined * sizeof(struct sclp_core_entry)); } -int sclp_get_cpu_info(struct sclp_cpu_info *info) +int sclp_get_core_info(struct sclp_core_info *info) { int rc; struct read_cpu_info_sccb *sccb; @@ -127,7 +126,7 @@ int sclp_get_cpu_info(struct sclp_cpu_info *info) rc = -EIO; goto out; } - sclp_fill_cpu_info(info, sccb); + sclp_fill_core_info(info, sccb); out: free_page((unsigned long) sccb); return rc; @@ -137,7 +136,7 @@ struct cpu_configure_sccb { struct sccb_header header; } __attribute__((packed, aligned(8))); -static int do_cpu_configure(sclp_cmdw_t cmd) +static int do_core_configure(sclp_cmdw_t cmd) { struct cpu_configure_sccb *sccb; int rc; @@ -171,14 +170,14 @@ out: return rc; } -int sclp_cpu_configure(u8 cpu) +int sclp_core_configure(u8 core) { - return do_cpu_configure(SCLP_CMDW_CONFIGURE_CPU | cpu << 8); + return do_core_configure(SCLP_CMDW_CONFIGURE_CPU | core << 8); } -int sclp_cpu_deconfigure(u8 cpu) +int sclp_core_deconfigure(u8 core) { - return do_cpu_configure(SCLP_CMDW_DECONFIGURE_CPU | cpu << 8); + return do_core_configure(SCLP_CMDW_DECONFIGURE_CPU | core << 8); } #ifdef CONFIG_MEMORY_HOTPLUG @@ -186,7 +185,7 @@ int sclp_cpu_deconfigure(u8 cpu) static DEFINE_MUTEX(sclp_mem_mutex); static LIST_HEAD(sclp_mem_list); static u8 sclp_max_storage_id; -static unsigned long sclp_storage_ids[256 / BITS_PER_LONG]; +static DECLARE_BITMAP(sclp_storage_ids, 256); static int sclp_mem_state_changed; struct memory_increment { @@ -202,14 +201,14 @@ struct assign_storage_sccb { int arch_get_memory_phys_device(unsigned long start_pfn) { - if (!sclp_rzm) + if (!sclp.rzm) return 0; - return PFN_PHYS(start_pfn) >> ilog2(sclp_rzm); + return PFN_PHYS(start_pfn) >> ilog2(sclp.rzm); } static unsigned long long rn2addr(u16 rn) { - return (unsigned long long) (rn - 1) * sclp_rzm; + return (unsigned long long) (rn - 1) * sclp.rzm; } static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) @@ -250,7 +249,7 @@ static int sclp_assign_storage(u16 rn) if (rc) return rc; start = rn2addr(rn); - storage_key_init_range(start, start + sclp_rzm); + storage_key_init_range(start, start + sclp.rzm); return 0; } @@ -309,7 +308,7 @@ static int sclp_mem_change_state(unsigned long start, unsigned long size, istart = rn2addr(incr->rn); if (start + size - 1 < istart) break; - if (start > istart + sclp_rzm - 1) + if (start > istart + sclp.rzm - 1) continue; if (online) rc |= sclp_assign_storage(incr->rn); @@ -330,7 +329,7 @@ static bool contains_standby_increment(unsigned long start, unsigned long end) istart = rn2addr(incr->rn); if (end - 1 < istart) continue; - if (start > istart + sclp_rzm - 1) + if (start > istart + sclp.rzm - 1) continue; if (incr->standby) return true; @@ -415,7 +414,7 @@ static void __init add_memory_merged(u16 rn) if (!first_rn) goto skip_add; start = rn2addr(first_rn); - size = (unsigned long long) num * sclp_rzm; + size = (unsigned long long) num * sclp.rzm; if (start >= VMEM_MAX_PHYS) goto skip_add; if (start + size > VMEM_MAX_PHYS) @@ -465,7 +464,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned) } if (!assigned) new_incr->rn = last_rn + 1; - if (new_incr->rn > sclp_rnmax) { + if (new_incr->rn > sclp.rnmax) { kfree(new_incr); return; } @@ -508,7 +507,7 @@ static int __init sclp_detect_standby_memory(void) if (OLDMEM_BASE) /* No standby memory in kdump mode */ return 0; - if ((sclp_facilities & 0xe00000000000ULL) != 0xe00000000000ULL) + if ((sclp.facilities & 0xe00000000000ULL) != 0xe00000000000ULL) return 0; rc = -ENOMEM; sccb = (void *) __get_free_page(GFP_KERNEL | GFP_DMA); @@ -550,7 +549,7 @@ static int __init sclp_detect_standby_memory(void) } if (rc || list_empty(&sclp_mem_list)) goto out; - for (i = 1; i <= sclp_rnmax - assigned; i++) + for (i = 1; i <= sclp.rnmax - assigned; i++) insert_increment(0, 1, 0); rc = register_memory_notifier(&sclp_mem_nb); if (rc) @@ -753,8 +752,3 @@ out: free_page((unsigned long) sccb); return rc; } - -bool sclp_has_sprp(void) -{ - return !!(sclp_fac84 & 0x2); -} diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index 1efa4fdb7..7bc6df310 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -7,6 +7,7 @@ #define KMSG_COMPONENT "sclp_early" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include <linux/errno.h> #include <asm/ctl_reg.h> #include <asm/sclp.h> #include <asm/ipl.h> @@ -48,23 +49,10 @@ struct read_info_sccb { } __packed __aligned(PAGE_SIZE); static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; -static unsigned int sclp_con_has_vt220 __initdata; -static unsigned int sclp_con_has_linemode __initdata; -static unsigned long sclp_hsa_size; -static unsigned int sclp_max_cpu; static struct sclp_ipl_info sclp_ipl_info; -static unsigned char sclp_siif; -static unsigned char sclp_sigpif; -static u32 sclp_ibc; -static unsigned int sclp_mtid; -static unsigned int sclp_mtid_cp; -static unsigned int sclp_mtid_max; -static unsigned int sclp_mtid_prev; - -u64 sclp_facilities; -u8 sclp_fac84; -unsigned long long sclp_rzm; -unsigned long long sclp_rnmax; + +struct sclp_info sclp; +EXPORT_SYMBOL(sclp); static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb) { @@ -111,28 +99,29 @@ static int __init sclp_read_info_early(struct read_info_sccb *sccb) static void __init sclp_facilities_detect(struct read_info_sccb *sccb) { - struct sclp_cpu_entry *cpue; + struct sclp_core_entry *cpue; u16 boot_cpu_address, cpu; if (sclp_read_info_early(sccb)) return; - sclp_facilities = sccb->facilities; - sclp_fac84 = sccb->fac84; + sclp.facilities = sccb->facilities; + sclp.has_sprp = !!(sccb->fac84 & 0x02); + sclp.has_core_type = !!(sccb->fac84 & 0x01); if (sccb->fac85 & 0x02) S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; - sclp_rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; - sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; - sclp_rzm <<= 20; - sclp_ibc = sccb->ibc; + sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; + sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; + sclp.rzm <<= 20; + sclp.ibc = sccb->ibc; if (!sccb->hcpua) { if (MACHINE_IS_VM) - sclp_max_cpu = 64; + sclp.max_cores = 64; else - sclp_max_cpu = sccb->ncpurl; + sclp.max_cores = sccb->ncpurl; } else { - sclp_max_cpu = sccb->hcpua + 1; + sclp.max_cores = sccb->hcpua + 1; } boot_cpu_address = stap(); @@ -140,8 +129,8 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb) for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) { if (boot_cpu_address != cpue->core_id) continue; - sclp_siif = cpue->siif; - sclp_sigpif = cpue->sigpif; + sclp.has_siif = cpue->siif; + sclp.has_sigpif = cpue->sigpif; break; } @@ -151,68 +140,9 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb) sclp_ipl_info.has_dump = 1; memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN); - sclp_mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0; - sclp_mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0; - sclp_mtid_max = max(sclp_mtid, sclp_mtid_cp); - sclp_mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0; -} - -bool __init sclp_has_linemode(void) -{ - return !!sclp_con_has_linemode; -} - -bool __init sclp_has_vt220(void) -{ - return !!sclp_con_has_vt220; -} - -unsigned long long sclp_get_rnmax(void) -{ - return sclp_rnmax; -} - -unsigned long long sclp_get_rzm(void) -{ - return sclp_rzm; -} - -unsigned int sclp_get_max_cpu(void) -{ - return sclp_max_cpu; -} - -int sclp_has_siif(void) -{ - return sclp_siif; -} -EXPORT_SYMBOL(sclp_has_siif); - -int sclp_has_sigpif(void) -{ - return sclp_sigpif; -} -EXPORT_SYMBOL(sclp_has_sigpif); - -unsigned int sclp_get_ibc(void) -{ - return sclp_ibc; -} -EXPORT_SYMBOL(sclp_get_ibc); - -unsigned int sclp_get_mtid(u8 cpu_type) -{ - return cpu_type ? sclp_mtid : sclp_mtid_cp; -} - -unsigned int sclp_get_mtid_max(void) -{ - return sclp_mtid_max; -} - -unsigned int sclp_get_mtid_prev(void) -{ - return sclp_mtid_prev; + sclp.mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0; + sclp.mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0; + sclp.mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0; } /* @@ -286,11 +216,6 @@ static long __init sclp_hsa_copy_wait(struct sccb_header *sccb) return (((struct sdias_sccb *) sccb)->evbuf.blk_cnt - 1) * PAGE_SIZE; } -unsigned long sclp_get_hsa_size(void) -{ - return sclp_hsa_size; -} - static void __init sclp_hsa_size_detect(void *sccb) { long size; @@ -313,7 +238,7 @@ static void __init sclp_hsa_size_detect(void *sccb) if (size < 0) return; out: - sclp_hsa_size = size; + sclp.hsa_size = size; } static unsigned int __init sclp_con_check_linemode(struct init_sccb *sccb) @@ -331,10 +256,10 @@ static void __init sclp_console_detect(struct init_sccb *sccb) return; if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK) - sclp_con_has_vt220 = 1; + sclp.has_vt220 = 1; if (sclp_con_check_linemode(sccb)) - sclp_con_has_linemode = 1; + sclp.has_linemode = 1; } void __init sclp_early_detect(void) diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c index eb7cb076c..7cdd13dd7 100644 --- a/drivers/s390/char/sclp_sdias.c +++ b/drivers/s390/char/sclp_sdias.c @@ -21,7 +21,6 @@ #define TRACE(x...) debug_sprintf_event(sdias_dbf, 1, x) #define SDIAS_RETRIES 300 -#define SDIAS_SLEEP_TICKS 50 static struct debug_info *sdias_dbf; @@ -68,7 +67,7 @@ static int sdias_sclp_send(struct sclp_req *req) /* not initiated, wait some time and retry */ set_current_state(TASK_INTERRUPTIBLE); TRACE("add request failed: rc = %i\n",rc); - schedule_timeout(SDIAS_SLEEP_TICKS); + schedule_timeout(msecs_to_jiffies(500)); continue; } /* initiated, wait for completion of service call */ diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index a68fcfd1d..823f41fc4 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -154,7 +154,7 @@ static int __init init_cpu_info(enum arch_id arch) /* get info for boot cpu from lowcore, stored in the HSA */ - sa_ext = dump_save_area_create(0); + sa_ext = dump_save_areas.areas[0]; if (!sa_ext) return -ENOMEM; if (memcpy_hsa_kernel(&sa_ext->sa, sys_info.sa_base, @@ -330,9 +330,9 @@ static ssize_t zcore_read(struct file *file, char __user *buf, size_t count, mem_offs = 0; /* Copy from HSA data */ - if (*ppos < sclp_get_hsa_size() + HEADER_SIZE) { + if (*ppos < sclp.hsa_size + HEADER_SIZE) { size = min((count - hdr_count), - (size_t) (sclp_get_hsa_size() - mem_start)); + (size_t) (sclp.hsa_size - mem_start)); rc = memcpy_hsa_user(buf + hdr_count, mem_start, size); if (rc) goto fail; @@ -483,7 +483,7 @@ static ssize_t zcore_hsa_read(struct file *filp, char __user *buf, static char str[18]; if (hsa_available) - snprintf(str, sizeof(str), "%lx\n", sclp_get_hsa_size()); + snprintf(str, sizeof(str), "%lx\n", sclp.hsa_size); else snprintf(str, sizeof(str), "0\n"); return simple_read_from_buffer(buf, count, ppos, str, strlen(str)); @@ -558,7 +558,7 @@ static int __init sys_info_init(enum arch_id arch, unsigned long mem_end) static int __init check_sdias(void) { - if (!sclp_get_hsa_size()) { + if (!sclp.hsa_size) { TRACE("Could not determine HSA size\n"); return -ENODEV; } @@ -619,7 +619,7 @@ static int __init zcore_reipl_init(void) ipl_block = (void *) __get_free_page(GFP_KERNEL); if (!ipl_block) return -ENOMEM; - if (ipib_info.ipib < sclp_get_hsa_size()) + if (ipib_info.ipib < sclp.hsa_size) rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE); else rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE); diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 3ba611419..559a9dcdb 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -60,7 +60,7 @@ static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags); static int ap_device_remove(struct device *dev); static int ap_device_probe(struct device *dev); static void ap_interrupt_handler(struct airq_struct *airq); -static void ap_reset(struct ap_device *ap_dev); +static void ap_reset(struct ap_device *ap_dev, unsigned long *flags); static void ap_config_timeout(unsigned long ptr); static int ap_select_domain(void); static void ap_query_configuration(void); @@ -310,35 +310,26 @@ static inline int __ap_query_configuration(struct ap_config_info *config) static int ap_query_functions(ap_qid_t qid, unsigned int *functions) { struct ap_queue_status status; - int i; + status = __ap_query_functions(qid, functions); - for (i = 0; i < AP_MAX_RESET; i++) { - if (ap_queue_status_invalid_test(&status)) - return -ENODEV; + if (ap_queue_status_invalid_test(&status)) + return -ENODEV; - switch (status.response_code) { - case AP_RESPONSE_NORMAL: - return 0; - case AP_RESPONSE_RESET_IN_PROGRESS: - case AP_RESPONSE_BUSY: - break; - case AP_RESPONSE_Q_NOT_AVAIL: - case AP_RESPONSE_DECONFIGURED: - case AP_RESPONSE_CHECKSTOPPED: - case AP_RESPONSE_INVALID_ADDRESS: - return -ENODEV; - case AP_RESPONSE_OTHERWISE_CHANGED: - break; - default: - break; - } - if (i < AP_MAX_RESET - 1) { - udelay(5); - status = __ap_query_functions(qid, functions); - } + switch (status.response_code) { + case AP_RESPONSE_NORMAL: + return 0; + case AP_RESPONSE_Q_NOT_AVAIL: + case AP_RESPONSE_DECONFIGURED: + case AP_RESPONSE_CHECKSTOPPED: + case AP_RESPONSE_INVALID_ADDRESS: + return -ENODEV; + case AP_RESPONSE_RESET_IN_PROGRESS: + case AP_RESPONSE_BUSY: + case AP_RESPONSE_OTHERWISE_CHANGED: + default: + return -EBUSY; } - return -EBUSY; } /** @@ -350,47 +341,25 @@ static int ap_query_functions(ap_qid_t qid, unsigned int *functions) * on the return value it waits a while and tests the AP queue if interrupts * have been switched on using ap_test_queue(). */ -static int ap_queue_enable_interruption(ap_qid_t qid, void *ind) +static int ap_queue_enable_interruption(struct ap_device *ap_dev, void *ind) { struct ap_queue_status status; - int t_depth, t_device_type, rc, i; - rc = -EBUSY; - status = ap_queue_interruption_control(qid, ind); - - for (i = 0; i < AP_MAX_RESET; i++) { - switch (status.response_code) { - case AP_RESPONSE_NORMAL: - if (status.int_enabled) - return 0; - break; - case AP_RESPONSE_RESET_IN_PROGRESS: - case AP_RESPONSE_BUSY: - if (i < AP_MAX_RESET - 1) { - udelay(5); - status = ap_queue_interruption_control(qid, - ind); - continue; - } - break; - case AP_RESPONSE_Q_NOT_AVAIL: - case AP_RESPONSE_DECONFIGURED: - case AP_RESPONSE_CHECKSTOPPED: - case AP_RESPONSE_INVALID_ADDRESS: - return -ENODEV; - case AP_RESPONSE_OTHERWISE_CHANGED: - if (status.int_enabled) - return 0; - break; - default: - break; - } - if (i < AP_MAX_RESET - 1) { - udelay(5); - status = ap_test_queue(qid, &t_depth, &t_device_type); - } + status = ap_queue_interruption_control(ap_dev->qid, ind); + switch (status.response_code) { + case AP_RESPONSE_NORMAL: + case AP_RESPONSE_OTHERWISE_CHANGED: + return 0; + case AP_RESPONSE_Q_NOT_AVAIL: + case AP_RESPONSE_DECONFIGURED: + case AP_RESPONSE_CHECKSTOPPED: + case AP_RESPONSE_INVALID_ADDRESS: + return -ENODEV; + case AP_RESPONSE_RESET_IN_PROGRESS: + case AP_RESPONSE_BUSY: + default: + return -EBUSY; } - return rc; } /** @@ -511,109 +480,94 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length) EXPORT_SYMBOL(ap_recv); /** + * __ap_schedule_poll_timer(): Schedule poll timer. + * + * Set up the timer to run the poll tasklet + */ +static inline void __ap_schedule_poll_timer(void) +{ + ktime_t hr_time; + + spin_lock_bh(&ap_poll_timer_lock); + if (!hrtimer_is_queued(&ap_poll_timer) && !ap_suspend_flag) { + hr_time = ktime_set(0, poll_timeout); + hrtimer_forward_now(&ap_poll_timer, hr_time); + hrtimer_restart(&ap_poll_timer); + } + spin_unlock_bh(&ap_poll_timer_lock); +} + +/** + * ap_schedule_poll_timer(): Schedule poll timer. + * + * Set up the timer to run the poll tasklet + */ +static inline void ap_schedule_poll_timer(void) +{ + if (ap_using_interrupts()) + return; + __ap_schedule_poll_timer(); +} + + +/** * ap_query_queue(): Check if an AP queue is available. * @qid: The AP queue number * @queue_depth: Pointer to queue depth value * @device_type: Pointer to device type value - * - * The test is repeated for AP_MAX_RESET times. */ static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type) { struct ap_queue_status status; - int t_depth, t_device_type, rc, i; + int t_depth, t_device_type; - rc = -EBUSY; - for (i = 0; i < AP_MAX_RESET; i++) { - status = ap_test_queue(qid, &t_depth, &t_device_type); - switch (status.response_code) { - case AP_RESPONSE_NORMAL: - *queue_depth = t_depth + 1; - *device_type = t_device_type; - rc = 0; - break; - case AP_RESPONSE_Q_NOT_AVAIL: - rc = -ENODEV; - break; - case AP_RESPONSE_RESET_IN_PROGRESS: - break; - case AP_RESPONSE_DECONFIGURED: - rc = -ENODEV; - break; - case AP_RESPONSE_CHECKSTOPPED: - rc = -ENODEV; - break; - case AP_RESPONSE_INVALID_ADDRESS: - rc = -ENODEV; - break; - case AP_RESPONSE_OTHERWISE_CHANGED: - break; - case AP_RESPONSE_BUSY: - break; - default: - BUG(); - } - if (rc != -EBUSY) - break; - if (i < AP_MAX_RESET - 1) - udelay(5); + status = ap_test_queue(qid, &t_depth, &t_device_type); + switch (status.response_code) { + case AP_RESPONSE_NORMAL: + *queue_depth = t_depth + 1; + *device_type = t_device_type; + return 0; + case AP_RESPONSE_Q_NOT_AVAIL: + case AP_RESPONSE_DECONFIGURED: + case AP_RESPONSE_CHECKSTOPPED: + case AP_RESPONSE_INVALID_ADDRESS: + return -ENODEV; + case AP_RESPONSE_RESET_IN_PROGRESS: + case AP_RESPONSE_OTHERWISE_CHANGED: + case AP_RESPONSE_BUSY: + return -EBUSY; + default: + BUG(); } - return rc; } /** * ap_init_queue(): Reset an AP queue. * @qid: The AP queue number * - * Reset an AP queue and wait for it to become available again. + * Submit the Reset command to an AP queue. + * Since the reset is asynchron set the state to 'RESET_IN_PROGRESS' + * and check later via ap_poll_queue() if the reset is done. */ -static int ap_init_queue(ap_qid_t qid) +static int ap_init_queue(struct ap_device *ap_dev) { struct ap_queue_status status; - int rc, dummy, i; - rc = -ENODEV; - status = ap_reset_queue(qid); - for (i = 0; i < AP_MAX_RESET; i++) { - switch (status.response_code) { - case AP_RESPONSE_NORMAL: - if (status.queue_empty) - rc = 0; - break; - case AP_RESPONSE_Q_NOT_AVAIL: - case AP_RESPONSE_DECONFIGURED: - case AP_RESPONSE_CHECKSTOPPED: - i = AP_MAX_RESET; /* return with -ENODEV */ - break; - case AP_RESPONSE_RESET_IN_PROGRESS: - rc = -EBUSY; - case AP_RESPONSE_BUSY: - default: - break; - } - if (rc != -ENODEV && rc != -EBUSY) - break; - if (i < AP_MAX_RESET - 1) { - /* Time we are waiting until we give up (0.7sec * 90). - * Since the actual request (in progress) will not - * interrupted immediately for the reset command, - * we have to be patient. In worst case we have to - * wait 60sec + reset time (some msec). - */ - schedule_timeout(AP_RESET_TIMEOUT); - status = ap_test_queue(qid, &dummy, &dummy); - } - } - if (rc == 0 && ap_using_interrupts()) { - rc = ap_queue_enable_interruption(qid, ap_airq.lsi_ptr); - /* If interruption mode is supported by the machine, - * but an AP can not be enabled for interruption then - * the AP will be discarded. */ - if (rc) - pr_err("Registering adapter interrupts for " - "AP %d failed\n", AP_QID_DEVICE(qid)); + status = ap_reset_queue(ap_dev->qid); + switch (status.response_code) { + case AP_RESPONSE_NORMAL: + ap_dev->interrupt = AP_INTR_DISABLED; + ap_dev->reset = AP_RESET_IN_PROGRESS; + return 0; + case AP_RESPONSE_RESET_IN_PROGRESS: + case AP_RESPONSE_BUSY: + return -EBUSY; + case AP_RESPONSE_Q_NOT_AVAIL: + case AP_RESPONSE_DECONFIGURED: + case AP_RESPONSE_CHECKSTOPPED: + default: + return -ENODEV; } - return rc; } /** @@ -729,10 +683,63 @@ static ssize_t ap_pendingq_count_show(struct device *dev, static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL); +static ssize_t ap_reset_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ap_device *ap_dev = to_ap_dev(dev); + int rc = 0; + + spin_lock_bh(&ap_dev->lock); + switch (ap_dev->reset) { + case AP_RESET_IGNORE: + rc = snprintf(buf, PAGE_SIZE, "No Reset Timer set.\n"); + break; + case AP_RESET_ARMED: + rc = snprintf(buf, PAGE_SIZE, "Reset Timer armed.\n"); + break; + case AP_RESET_DO: + rc = snprintf(buf, PAGE_SIZE, "Reset Timer expired.\n"); + break; + case AP_RESET_IN_PROGRESS: + rc = snprintf(buf, PAGE_SIZE, "Reset in progress.\n"); + break; + default: + break; + } + spin_unlock_bh(&ap_dev->lock); + return rc; +} + +static DEVICE_ATTR(reset, 0444, ap_reset_show, NULL); + +static ssize_t ap_interrupt_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ap_device *ap_dev = to_ap_dev(dev); + int rc = 0; + + spin_lock_bh(&ap_dev->lock); + switch (ap_dev->interrupt) { + case AP_INTR_DISABLED: + rc = snprintf(buf, PAGE_SIZE, "Interrupts disabled.\n"); + break; + case AP_INTR_ENABLED: + rc = snprintf(buf, PAGE_SIZE, "Interrupts enabled.\n"); + break; + case AP_INTR_IN_PROGRESS: + rc = snprintf(buf, PAGE_SIZE, "Enable Interrupt pending.\n"); + break; + } + spin_unlock_bh(&ap_dev->lock); + return rc; +} + +static DEVICE_ATTR(interrupt, 0444, ap_interrupt_show, NULL); + static ssize_t ap_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "ap:t%02X", to_ap_dev(dev)->device_type); + return sprintf(buf, "ap:t%02X\n", to_ap_dev(dev)->device_type); } static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL); @@ -753,6 +760,8 @@ static struct attribute *ap_dev_attrs[] = { &dev_attr_request_count.attr, &dev_attr_requestq_count.attr, &dev_attr_pendingq_count.attr, + &dev_attr_reset.attr, + &dev_attr_interrupt.attr, &dev_attr_modalias.attr, &dev_attr_ap_functions.attr, NULL @@ -926,6 +935,10 @@ static int ap_device_probe(struct device *dev) spin_lock_bh(&ap_device_list_lock); list_del_init(&ap_dev->list); spin_unlock_bh(&ap_device_list_lock); + } else { + if (ap_dev->reset == AP_RESET_IN_PROGRESS || + ap_dev->interrupt == AP_INTR_IN_PROGRESS) + __ap_schedule_poll_timer(); } return rc; } @@ -1411,7 +1424,7 @@ static void ap_scan_bus(struct work_struct *unused) struct ap_device *ap_dev; struct device *dev; ap_qid_t qid; - int queue_depth, device_type; + int queue_depth = 0, device_type = 0; unsigned int device_functions; int rc, i; @@ -1429,15 +1442,9 @@ static void ap_scan_bus(struct work_struct *unused) else rc = -ENODEV; if (dev) { - if (rc == -EBUSY) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(AP_RESET_TIMEOUT); - rc = ap_query_queue(qid, &queue_depth, - &device_type); - } ap_dev = to_ap_dev(dev); spin_lock_bh(&ap_dev->lock); - if (rc || ap_dev->unregistered) { + if (rc == -ENODEV || ap_dev->unregistered) { spin_unlock_bh(&ap_dev->lock); if (ap_dev->unregistered) i--; @@ -1451,13 +1458,15 @@ static void ap_scan_bus(struct work_struct *unused) } if (rc) continue; - rc = ap_init_queue(qid); - if (rc) - continue; ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL); if (!ap_dev) break; ap_dev->qid = qid; + rc = ap_init_queue(ap_dev); + if ((rc != 0) && (rc != -EBUSY)) { + kfree(ap_dev); + continue; + } ap_dev->queue_depth = queue_depth; ap_dev->unregistered = 1; spin_lock_init(&ap_dev->lock); @@ -1520,36 +1529,6 @@ ap_config_timeout(unsigned long ptr) } /** - * __ap_schedule_poll_timer(): Schedule poll timer. - * - * Set up the timer to run the poll tasklet - */ -static inline void __ap_schedule_poll_timer(void) -{ - ktime_t hr_time; - - spin_lock_bh(&ap_poll_timer_lock); - if (!hrtimer_is_queued(&ap_poll_timer) && !ap_suspend_flag) { - hr_time = ktime_set(0, poll_timeout); - hrtimer_forward_now(&ap_poll_timer, hr_time); - hrtimer_restart(&ap_poll_timer); - } - spin_unlock_bh(&ap_poll_timer_lock); -} - -/** - * ap_schedule_poll_timer(): Schedule poll timer. - * - * Set up the timer to run the poll tasklet - */ -static inline void ap_schedule_poll_timer(void) -{ - if (ap_using_interrupts()) - return; - __ap_schedule_poll_timer(); -} - -/** * ap_poll_read(): Receive pending reply messages from an AP device. * @ap_dev: pointer to the AP device * @flags: pointer to control flags, bit 2^0 is set if another poll is @@ -1568,6 +1547,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) ap_dev->reply->message, ap_dev->reply->length); switch (status.response_code) { case AP_RESPONSE_NORMAL: + ap_dev->interrupt = status.int_enabled; atomic_dec(&ap_poll_requests); ap_decrease_queue_count(ap_dev); list_for_each_entry(ap_msg, &ap_dev->pendingq, list) { @@ -1582,6 +1562,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) *flags |= 1; break; case AP_RESPONSE_NO_PENDING_REPLY: + ap_dev->interrupt = status.int_enabled; if (status.queue_empty) { /* The card shouldn't forget requests but who knows. */ atomic_sub(ap_dev->queue_count, &ap_poll_requests); @@ -1612,7 +1593,8 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) struct ap_message *ap_msg; if (ap_dev->requestq_count <= 0 || - ap_dev->queue_count >= ap_dev->queue_depth) + (ap_dev->queue_count >= ap_dev->queue_depth) || + (ap_dev->reset == AP_RESET_IN_PROGRESS)) return 0; /* Start the next request on the queue. */ ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list); @@ -1646,6 +1628,8 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) /** * ap_poll_queue(): Poll AP device for pending replies and send new messages. + * Check if the queue has a pending reset. In case it's done re-enable + * interrupts, otherwise reschedule the poll_timer for another attempt. * @ap_dev: pointer to the bus device * @flags: pointer to control flags, bit 2^0 is set if another poll is * required, bit 2^1 is set if the poll timer needs to get armed @@ -1656,7 +1640,51 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) */ static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags) { - int rc; + int rc, depth, type; + struct ap_queue_status status; + + + if (ap_dev->reset == AP_RESET_IN_PROGRESS) { + status = ap_test_queue(ap_dev->qid, &depth, &type); + switch (status.response_code) { + case AP_RESPONSE_NORMAL: + ap_dev->reset = AP_RESET_IGNORE; + if (ap_using_interrupts()) { + rc = ap_queue_enable_interruption( + ap_dev, ap_airq.lsi_ptr); + if (!rc) + ap_dev->interrupt = AP_INTR_IN_PROGRESS; + else if (rc == -ENODEV) { + pr_err("Registering adapter interrupts for " + "AP %d failed\n", AP_QID_DEVICE(ap_dev->qid)); + return rc; + } + } + /* fall through */ + case AP_RESPONSE_BUSY: + case AP_RESPONSE_RESET_IN_PROGRESS: + *flags |= AP_POLL_AFTER_TIMEOUT; + break; + case AP_RESPONSE_Q_NOT_AVAIL: + case AP_RESPONSE_DECONFIGURED: + case AP_RESPONSE_CHECKSTOPPED: + return -ENODEV; + default: + break; + } + } + + if ((ap_dev->reset != AP_RESET_IN_PROGRESS) && + (ap_dev->interrupt == AP_INTR_IN_PROGRESS)) { + status = ap_test_queue(ap_dev->qid, &depth, &type); + if (ap_using_interrupts()) { + if (status.int_enabled == 1) + ap_dev->interrupt = AP_INTR_ENABLED; + else + *flags |= AP_POLL_AFTER_TIMEOUT; + } else + ap_dev->interrupt = AP_INTR_DISABLED; + } rc = ap_poll_read(ap_dev, flags); if (rc) @@ -1676,7 +1704,8 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms struct ap_queue_status status; if (list_empty(&ap_dev->requestq) && - ap_dev->queue_count < ap_dev->queue_depth) { + (ap_dev->queue_count < ap_dev->queue_depth) && + (ap_dev->reset != AP_RESET_IN_PROGRESS)) { status = __ap_send(ap_dev->qid, ap_msg->psmid, ap_msg->message, ap_msg->length, ap_msg->special); @@ -1789,21 +1818,20 @@ static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused) * Reset a not responding AP device and move all requests from the * pending queue to the request queue. */ -static void ap_reset(struct ap_device *ap_dev) +static void ap_reset(struct ap_device *ap_dev, unsigned long *flags) { int rc; - ap_dev->reset = AP_RESET_IGNORE; atomic_sub(ap_dev->queue_count, &ap_poll_requests); ap_dev->queue_count = 0; list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); ap_dev->requestq_count += ap_dev->pendingq_count; ap_dev->pendingq_count = 0; - rc = ap_init_queue(ap_dev->qid); + rc = ap_init_queue(ap_dev); if (rc == -ENODEV) ap_dev->unregistered = 1; else - __ap_schedule_poll_timer(); + *flags |= AP_POLL_AFTER_TIMEOUT; } static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags) @@ -1812,7 +1840,7 @@ static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags) if (ap_poll_queue(ap_dev, flags)) ap_dev->unregistered = 1; if (ap_dev->reset == AP_RESET_DO) - ap_reset(ap_dev); + ap_reset(ap_dev, flags); } return 0; } @@ -1845,9 +1873,9 @@ static void ap_poll_all(unsigned long dummy) spin_unlock(&ap_dev->lock); } spin_unlock(&ap_device_list_lock); - } while (flags & 1); - if (flags & 2) - ap_schedule_poll_timer(); + } while (flags & AP_POLL_IMMEDIATELY); + if (flags & AP_POLL_AFTER_TIMEOUT) + __ap_schedule_poll_timer(); } /** diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 2737d261a..00468c8d0 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -32,11 +32,13 @@ #define AP_DEVICES 64 /* Number of AP devices. */ #define AP_DOMAINS 256 /* Number of AP domains. */ -#define AP_MAX_RESET 90 /* Maximum number of resets. */ #define AP_RESET_TIMEOUT (HZ*0.7) /* Time in ticks for reset timeouts. */ #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ +#define AP_POLL_IMMEDIATELY 1 /* continue running poll tasklet */ +#define AP_POLL_AFTER_TIMEOUT 2 /* run poll tasklet again after timout */ + extern int ap_domain_index; /** @@ -135,6 +137,14 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr) #define AP_RESET_IGNORE 0 /* request timeout will be ignored */ #define AP_RESET_ARMED 1 /* request timeout timer is active */ #define AP_RESET_DO 2 /* AP reset required */ +#define AP_RESET_IN_PROGRESS 3 /* AP reset in progress */ + +/* + * AP interrupt states + */ +#define AP_INTR_DISABLED 0 /* AP interrupt disabled */ +#define AP_INTR_ENABLED 1 /* AP interrupt enabled */ +#define AP_INTR_IN_PROGRESS 3 /* AP interrupt in progress */ struct ap_device; struct ap_message; @@ -168,6 +178,7 @@ struct ap_device { struct timer_list timeout; /* Timer for request timeouts. */ int reset; /* Reset required after req. timeout. */ + int interrupt; /* indicate if interrupts are enabled */ int queue_count; /* # messages currently on AP queue. */ struct list_head pendingq; /* List of message sent to AP queue. */ diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 08f1830cb..01bf1f5cf 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -54,6 +54,10 @@ MODULE_DESCRIPTION("Cryptographic Coprocessor interface, " \ "Copyright IBM Corp. 2001, 2012"); MODULE_LICENSE("GPL"); +static int zcrypt_hwrng_seed = 1; +module_param_named(hwrng_seed, zcrypt_hwrng_seed, int, S_IRUSR|S_IRGRP); +MODULE_PARM_DESC(hwrng_seed, "Turn on/off hwrng auto seed, default is 1 (on)."); + static DEFINE_SPINLOCK(zcrypt_device_lock); static LIST_HEAD(zcrypt_device_list); static int zcrypt_device_count = 0; @@ -1373,6 +1377,7 @@ static int zcrypt_rng_data_read(struct hwrng *rng, u32 *data) static struct hwrng zcrypt_rng_dev = { .name = "zcrypt", .data_read = zcrypt_rng_data_read, + .quality = 990, }; static int zcrypt_rng_device_add(void) @@ -1387,6 +1392,8 @@ static int zcrypt_rng_device_add(void) goto out; } zcrypt_rng_buffer_index = 0; + if (!zcrypt_hwrng_seed) + zcrypt_rng_dev.quality = 0; rc = hwrng_register(&zcrypt_rng_dev); if (rc) goto out_free; diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c index 71e698b85..bb3908818 100644 --- a/drivers/s390/crypto/zcrypt_cex4.c +++ b/drivers/s390/crypto/zcrypt_cex4.c @@ -39,7 +39,7 @@ * But the maximum time limit managed by the stomper code is set to 60sec. * Hence we have to wait at least that time period. */ -#define CEX4_CLEANUP_TIME (61*HZ) +#define CEX4_CLEANUP_TIME (900*HZ) static struct ap_device_id zcrypt_cex4_ids[] = { { AP_DEVICE(AP_DEVICE_TYPE_CEX4) }, diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index 4d14c04b7..9f18876f0 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c @@ -98,11 +98,11 @@ static struct ap_driver zcrypt_pcicc_driver = { * - VUD block */ static struct CPRB static_cprb = { - .cprb_len = __constant_cpu_to_le16(0x0070), + .cprb_len = cpu_to_le16(0x0070), .cprb_ver_id = 0x41, .func_id = {0x54,0x32}, .checkpoint_flag= 0x01, - .svr_namel = __constant_cpu_to_le16(0x0008), + .svr_namel = cpu_to_le16(0x0008), .svr_name = {'I','C','S','F',' ',' ',' ',' '} }; @@ -164,7 +164,7 @@ static int ICAMEX_msg_to_type6MEX_msg(struct zcrypt_device *zdev, }; static struct function_and_rules_block static_pke_function_and_rules ={ .function_code = {'P','K'}, - .ulen = __constant_cpu_to_le16(10), + .ulen = cpu_to_le16(10), .only_rule = {'P','K','C','S','-','1','.','2'} }; struct { @@ -251,7 +251,7 @@ static int ICACRT_msg_to_type6CRT_msg(struct zcrypt_device *zdev, }; static struct function_and_rules_block static_pkd_function_and_rules ={ .function_code = {'P','D'}, - .ulen = __constant_cpu_to_le16(10), + .ulen = cpu_to_le16(10), .only_rule = {'P','K','C','S','-','1','.','2'} }; struct { diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 00b7d9c9f..2f5b518b0 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -2150,7 +2150,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) rc = lcs_detect(card); if (rc) { LCS_DBF_TEXT(2, setup, "dtctfail"); - dev_err(&card->dev->dev, + dev_err(&ccwgdev->dev, "Detecting a network adapter for LCS devices" " failed with rc=%d (0x%x)\n", rc, rc); lcs_stopcard(card); diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 3abac0288..ba974a2e4 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -175,6 +175,8 @@ struct qeth_sbp_info { __u32 supported_funcs; enum qeth_sbp_roles role; __u32 hostnotification:1; + __u32 reflect_promisc:1; + __u32 reflect_promisc_primary:1; }; static inline int qeth_is_ipa_supported(struct qeth_ipa_info *ipa, diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3466d3cb7..5e20fba37 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -645,7 +645,8 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card, card->info.hwtrap = 2; qeth_schedule_recovery(card); return NULL; - case IPA_CMD_SETBRIDGEPORT: + case IPA_CMD_SETBRIDGEPORT_IQD: + case IPA_CMD_SETBRIDGEPORT_OSA: case IPA_CMD_ADDRESS_CHANGE_NOTIF: if (card->discipline->control_event_handler (card, cmd)) diff --git a/drivers/s390/net/qeth_core_mpc.c b/drivers/s390/net/qeth_core_mpc.c index 7b55768a9..beb4bdc26 100644 --- a/drivers/s390/net/qeth_core_mpc.c +++ b/drivers/s390/net/qeth_core_mpc.c @@ -237,6 +237,7 @@ static struct ipa_cmd_names qeth_ipa_cmd_names[] = { {IPA_CMD_DELGMAC, "delgmac"}, {IPA_CMD_SETVLAN, "setvlan"}, {IPA_CMD_DELVLAN, "delvlan"}, + {IPA_CMD_SETBRIDGEPORT_OSA, "set_bridge_port(osa)"}, {IPA_CMD_SETCCID, "setccid"}, {IPA_CMD_DELCCID, "delccid"}, {IPA_CMD_MODCCID, "modccid"}, @@ -249,7 +250,7 @@ static struct ipa_cmd_names qeth_ipa_cmd_names[] = { {IPA_CMD_DELIP, "delip"}, {IPA_CMD_SETADAPTERPARMS, "setadapterparms"}, {IPA_CMD_SET_DIAG_ASS, "set_diag_ass"}, - {IPA_CMD_SETBRIDGEPORT, "set_bridge_port"}, + {IPA_CMD_SETBRIDGEPORT_IQD, "set_bridge_port(hs)"}, {IPA_CMD_CREATE_ADDR, "create_addr"}, {IPA_CMD_DESTROY_ADDR, "destroy_addr"}, {IPA_CMD_REGISTER_LOCAL_ADDR, "register_local_addr"}, diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index 1558be1af..6cccc9a49 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -92,6 +92,7 @@ enum qeth_ipa_cmds { IPA_CMD_DELGMAC = 0x24, IPA_CMD_SETVLAN = 0x25, IPA_CMD_DELVLAN = 0x26, + IPA_CMD_SETBRIDGEPORT_OSA = 0x2b, IPA_CMD_SETCCID = 0x41, IPA_CMD_DELCCID = 0x42, IPA_CMD_MODCCID = 0x43, @@ -104,7 +105,7 @@ enum qeth_ipa_cmds { IPA_CMD_DELIP = 0xb7, IPA_CMD_SETADAPTERPARMS = 0xb8, IPA_CMD_SET_DIAG_ASS = 0xb9, - IPA_CMD_SETBRIDGEPORT = 0xbe, + IPA_CMD_SETBRIDGEPORT_IQD = 0xbe, IPA_CMD_CREATE_ADDR = 0xc3, IPA_CMD_DESTROY_ADDR = 0xc4, IPA_CMD_REGISTER_LOCAL_ADDR = 0xd1, diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 0ea086912..2e65b989a 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -137,7 +137,7 @@ static int qeth_setdel_makerc(struct qeth_card *card, int retcode) rc = 0; break; case IPA_RC_L2_UNSUPPORTED_CMD: - rc = -ENOSYS; + rc = -EOPNOTSUPP; break; case IPA_RC_L2_ADDR_TABLE_FULL: rc = -ENOSPC; @@ -683,6 +683,39 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) return rc ? -EINVAL : 0; } +static void qeth_promisc_to_bridge(struct qeth_card *card) +{ + struct net_device *dev = card->dev; + enum qeth_ipa_promisc_modes promisc_mode; + int role; + int rc; + + QETH_CARD_TEXT(card, 3, "pmisc2br"); + + if (!card->options.sbp.reflect_promisc) + return; + promisc_mode = (dev->flags & IFF_PROMISC) ? SET_PROMISC_MODE_ON + : SET_PROMISC_MODE_OFF; + if (promisc_mode == card->info.promisc_mode) + return; + + if (promisc_mode == SET_PROMISC_MODE_ON) { + if (card->options.sbp.reflect_promisc_primary) + role = QETH_SBP_ROLE_PRIMARY; + else + role = QETH_SBP_ROLE_SECONDARY; + } else + role = QETH_SBP_ROLE_NONE; + + rc = qeth_bridgeport_setrole(card, role); + QETH_DBF_TEXT_(SETUP, 2, "bpm%c%04x", + (promisc_mode == SET_PROMISC_MODE_ON) ? '+' : '-', rc); + if (!rc) { + card->options.sbp.role = role; + card->info.promisc_mode = promisc_mode; + } +} + static void qeth_l2_set_multicast_list(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; @@ -704,9 +737,10 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) qeth_l2_add_mc(card, ha->addr, 1); spin_unlock_bh(&card->mclock); - if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) - return; - qeth_setadp_promisc_mode(card); + if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) + qeth_setadp_promisc_mode(card); + else + qeth_promisc_to_bridge(card); } static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) @@ -994,7 +1028,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) qeth_bridgeport_query_support(card); if (card->options.sbp.supported_funcs) dev_info(&card->gdev->dev, - "The device represents a HiperSockets Bridge Capable Port\n"); + "The device represents a Bridge Capable Port\n"); qeth_trace_features(card); if (!card->dev && qeth_l2_setup_netdev(card)) { @@ -1247,7 +1281,8 @@ static int qeth_l2_control_event(struct qeth_card *card, struct qeth_ipa_cmd *cmd) { switch (cmd->hdr.command) { - case IPA_CMD_SETBRIDGEPORT: + case IPA_CMD_SETBRIDGEPORT_OSA: + case IPA_CMD_SETBRIDGEPORT_IQD: if (cmd->data.sbp.hdr.command_code == IPA_SBP_BRIDGE_PORT_STATE_CHANGE) { qeth_bridge_state_change(card, cmd); @@ -1533,7 +1568,7 @@ static void qeth_bridge_host_event_worker(struct work_struct *work) if (data->hostevs.lost_event_mask) { dev_info(&data->card->gdev->dev, -"Address notification from the HiperSockets Bridge Port stopped %s (%s)\n", +"Address notification from the Bridge Port stopped %s (%s)\n", data->card->dev->name, (data->hostevs.lost_event_mask == 0x01) ? "Overflow" @@ -1617,70 +1652,80 @@ static int qeth_bridgeport_makerc(struct qeth_card *card, struct _qeth_sbp_cbctl *cbctl, enum qeth_ipa_sbp_cmd setcmd) { int rc; + int is_iqd = (card->info.type == QETH_CARD_TYPE_IQD); - switch (cbctl->ipa_rc) { - case IPA_RC_SUCCESS: + if ((is_iqd && (cbctl->ipa_rc == IPA_RC_SUCCESS)) || + (!is_iqd && (cbctl->ipa_rc == cbctl->cmd_rc))) switch (cbctl->cmd_rc) { case 0x0000: rc = 0; break; + case 0x2B04: case 0x0004: - rc = -ENOSYS; + rc = -EOPNOTSUPP; break; + case 0x2B0C: case 0x000C: /* Not configured as bridge Port */ rc = -ENODEV; /* maybe not the best code here? */ dev_err(&card->gdev->dev, - "The HiperSockets device is not configured as a Bridge Port\n"); + "The device is not configured as a Bridge Port\n"); break; + case 0x2B14: case 0x0014: /* Another device is Primary */ switch (setcmd) { case IPA_SBP_SET_PRIMARY_BRIDGE_PORT: rc = -EEXIST; dev_err(&card->gdev->dev, - "The HiperSockets LAN already has a primary Bridge Port\n"); + "The LAN already has a primary Bridge Port\n"); break; case IPA_SBP_SET_SECONDARY_BRIDGE_PORT: rc = -EBUSY; dev_err(&card->gdev->dev, - "The HiperSockets device is already a primary Bridge Port\n"); + "The device is already a primary Bridge Port\n"); break; default: rc = -EIO; } break; + case 0x2B18: case 0x0018: /* This device is currently Secondary */ rc = -EBUSY; dev_err(&card->gdev->dev, - "The HiperSockets device is already a secondary Bridge Port\n"); + "The device is already a secondary Bridge Port\n"); break; + case 0x2B1C: case 0x001C: /* Limit for Secondary devices reached */ rc = -EEXIST; dev_err(&card->gdev->dev, - "The HiperSockets LAN cannot have more secondary Bridge Ports\n"); + "The LAN cannot have more secondary Bridge Ports\n"); break; + case 0x2B24: case 0x0024: /* This device is currently Primary */ rc = -EBUSY; dev_err(&card->gdev->dev, - "The HiperSockets device is already a primary Bridge Port\n"); + "The device is already a primary Bridge Port\n"); break; + case 0x2B20: case 0x0020: /* Not authorized by zManager */ rc = -EACCES; dev_err(&card->gdev->dev, - "The HiperSockets device is not authorized to be a Bridge Port\n"); + "The device is not authorized to be a Bridge Port\n"); break; default: rc = -EIO; } - break; - case IPA_RC_NOTSUPP: - rc = -ENOSYS; - break; - case IPA_RC_UNSUPPORTED_COMMAND: - rc = -ENOSYS; - break; - default: - rc = -EIO; - } + else + switch (cbctl->ipa_rc) { + case IPA_RC_NOTSUPP: + rc = -EOPNOTSUPP; + break; + case IPA_RC_UNSUPPORTED_COMMAND: + rc = -EOPNOTSUPP; + break; + default: + rc = -EIO; + } + if (rc) { QETH_CARD_TEXT_(card, 2, "SBPi%04x", cbctl->ipa_rc); QETH_CARD_TEXT_(card, 2, "SBPc%04x", cbctl->cmd_rc); @@ -1688,6 +1733,13 @@ static int qeth_bridgeport_makerc(struct qeth_card *card, return rc; } +static inline int ipa_cmd_sbp(struct qeth_card *card) +{ + return (card->info.type == QETH_CARD_TYPE_IQD) ? + IPA_CMD_SETBRIDGEPORT_IQD : + IPA_CMD_SETBRIDGEPORT_OSA; +} + static int qeth_bridgeport_query_support_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) { @@ -1719,7 +1771,7 @@ static void qeth_bridgeport_query_support(struct qeth_card *card) struct _qeth_sbp_cbctl cbctl; QETH_CARD_TEXT(card, 2, "brqsuppo"); - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); + iob = qeth_get_ipacmd_buffer(card, ipa_cmd_sbp(card), 0); if (!iob) return; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); @@ -1796,7 +1848,7 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, QETH_CARD_TEXT(card, 2, "brqports"); if (!(card->options.sbp.supported_funcs & IPA_SBP_QUERY_BRIDGE_PORTS)) return -EOPNOTSUPP; - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); + iob = qeth_get_ipacmd_buffer(card, ipa_cmd_sbp(card), 0); if (!iob) return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); @@ -1808,10 +1860,9 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, cmd->data.sbp.hdr.seq_no = 1; rc = qeth_send_ipa_cmd(card, iob, qeth_bridgeport_query_ports_cb, (void *)&cbctl); - if (rc) + if (rc < 0) return rc; - rc = qeth_bridgeport_makerc(card, &cbctl, IPA_SBP_QUERY_BRIDGE_PORTS); - return rc; + return qeth_bridgeport_makerc(card, &cbctl, IPA_SBP_QUERY_BRIDGE_PORTS); } EXPORT_SYMBOL_GPL(qeth_bridgeport_query_ports); @@ -1864,7 +1915,7 @@ int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role) } if (!(card->options.sbp.supported_funcs & setcmd)) return -EOPNOTSUPP; - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); + iob = qeth_get_ipacmd_buffer(card, ipa_cmd_sbp(card), 0); if (!iob) return -ENOMEM; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); @@ -1874,10 +1925,9 @@ int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role) cmd->data.sbp.hdr.seq_no = 1; rc = qeth_send_ipa_cmd(card, iob, qeth_bridgeport_set_cb, (void *)&cbctl); - if (rc) + if (rc < 0) return rc; - rc = qeth_bridgeport_makerc(card, &cbctl, setcmd); - return rc; + return qeth_bridgeport_makerc(card, &cbctl, setcmd); } /** @@ -1898,7 +1948,7 @@ static int qeth_anset_makerc(struct qeth_card *card, int pnso_rc, u16 response) case 0x0004: case 0x0100: case 0x0106: - rc = -ENOSYS; + rc = -EOPNOTSUPP; dev_err(&card->gdev->dev, "Setting address notification failed\n"); break; diff --git a/drivers/s390/net/qeth_l2_sys.c b/drivers/s390/net/qeth_l2_sys.c index 59e3aa538..52673cd1d 100644 --- a/drivers/s390/net/qeth_l2_sys.c +++ b/drivers/s390/net/qeth_l2_sys.c @@ -23,8 +23,6 @@ static ssize_t qeth_bridge_port_role_state_show(struct device *dev, if (!card) return -EINVAL; - mutex_lock(&card->conf_mutex); - if (qeth_card_hw_is_reachable(card) && card->options.sbp.supported_funcs) rc = qeth_bridgeport_query_ports(card, @@ -59,8 +57,6 @@ static ssize_t qeth_bridge_port_role_state_show(struct device *dev, rc = sprintf(buf, "%s\n", word); } - mutex_unlock(&card->conf_mutex); - return rc; } @@ -90,7 +86,9 @@ static ssize_t qeth_bridge_port_role_store(struct device *dev, mutex_lock(&card->conf_mutex); - if (qeth_card_hw_is_reachable(card)) { + if (card->options.sbp.reflect_promisc) /* Forbid direct manipulation */ + rc = -EPERM; + else if (qeth_card_hw_is_reachable(card)) { rc = qeth_bridgeport_setrole(card, role); if (!rc) card->options.sbp.role = role; @@ -123,12 +121,8 @@ static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev, if (!card) return -EINVAL; - mutex_lock(&card->conf_mutex); - enabled = card->options.sbp.hostnotification; - mutex_unlock(&card->conf_mutex); - return sprintf(buf, "%d\n", enabled); } @@ -167,10 +161,72 @@ static DEVICE_ATTR(bridge_hostnotify, 0644, qeth_bridgeport_hostnotification_show, qeth_bridgeport_hostnotification_store); +static ssize_t qeth_bridgeport_reflect_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct qeth_card *card = dev_get_drvdata(dev); + char *state; + + if (!card) + return -EINVAL; + + if (card->options.sbp.reflect_promisc) { + if (card->options.sbp.reflect_promisc_primary) + state = "primary"; + else + state = "secondary"; + } else + state = "none"; + + return sprintf(buf, "%s\n", state); +} + +static ssize_t qeth_bridgeport_reflect_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct qeth_card *card = dev_get_drvdata(dev); + int enable, primary; + int rc = 0; + + if (!card) + return -EINVAL; + + if (sysfs_streq(buf, "none")) { + enable = 0; + primary = 0; + } else if (sysfs_streq(buf, "primary")) { + enable = 1; + primary = 1; + } else if (sysfs_streq(buf, "secondary")) { + enable = 1; + primary = 0; + } else + return -EINVAL; + + mutex_lock(&card->conf_mutex); + + if (card->options.sbp.role != QETH_SBP_ROLE_NONE) + rc = -EPERM; + else { + card->options.sbp.reflect_promisc = enable; + card->options.sbp.reflect_promisc_primary = primary; + rc = 0; + } + + mutex_unlock(&card->conf_mutex); + + return rc ? rc : count; +} + +static DEVICE_ATTR(bridge_reflect_promisc, 0644, + qeth_bridgeport_reflect_show, + qeth_bridgeport_reflect_store); + static struct attribute *qeth_l2_bridgeport_attrs[] = { &dev_attr_bridge_role.attr, &dev_attr_bridge_state.attr, &dev_attr_bridge_hostnotify.attr, + &dev_attr_bridge_reflect_promisc.attr, NULL, }; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 04e42c649..70eb2f61b 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3198,8 +3198,7 @@ static int qeth_l3_set_features(struct net_device *dev, netdev_features_t features) { struct qeth_card *card = dev->ml_priv; - u32 changed = dev->features ^ features; - int err; + netdev_features_t changed = dev->features ^ features; if (!(changed & NETIF_F_RXCSUM)) return 0; @@ -3208,11 +3207,7 @@ static int qeth_l3_set_features(struct net_device *dev, card->state == CARD_STATE_RECOVER) return 0; - err = qeth_l3_set_rx_csum(card, features & NETIF_F_RXCSUM); - if (err) - dev->features = features ^ NETIF_F_RXCSUM; - - return err; + return qeth_l3_set_rx_csum(card, features & NETIF_F_RXCSUM ? 1 : 0); } static const struct ethtool_ops qeth_l3_ethtool_ops = { diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 75f4bfc2b..b3c6ff491 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -297,7 +297,6 @@ static struct scsi_host_template zfcp_scsi_host_template = { * ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2) * 8, /* GCD, adjusted later */ .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, - .cmd_per_lun = 1, .use_clustering = 1, .shost_attrs = zfcp_sysfs_shost_attrs, .sdev_attrs = zfcp_sysfs_sdev_attrs, diff --git a/drivers/s390/kvm/Makefile b/drivers/s390/virtio/Makefile index 241891a57..241891a57 100644 --- a/drivers/s390/kvm/Makefile +++ b/drivers/s390/virtio/Makefile diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/virtio/kvm_virtio.c index dd65c8b4c..53fb975c4 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/virtio/kvm_virtio.c @@ -450,7 +450,7 @@ static int __init test_devices_support(unsigned long addr) static int __init kvm_devices_init(void) { int rc; - unsigned long total_memory_size = sclp_get_rzm() * sclp_get_rnmax(); + unsigned long total_memory_size = sclp.rzm * sclp.rnmax; if (!MACHINE_IS_KVM) return -ENODEV; @@ -497,7 +497,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) static int __init s390_virtio_console_init(void) { - if (sclp_has_vt220() || sclp_has_linemode()) + if (sclp.has_vt220 || sclp.has_linemode) return -ENODEV; return virtio_cons_early_init(early_put_chars); } diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index f8d8fdb26..f8d8fdb26 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c |