Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6

* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6:
[S390] smsgiucv_app: deliver z/VM CP special messages (SMSG) as uevents
[S390] smsgiucv: declare char pointers as "const"
[S390] dasd: automatic recognition of read-only devices
[S390] remove unused qdio flags in zfcp and qeth
[S390] Cleanup xtime usage
[S390] qdio: add missing bracket
[S390] cio: fix init_count in case of recognition after steal lock
[S390] dasd: security and PSF update patch for EMC CKD ioctl
[S390] hvc_iucv: allocate memory buffers for IUCV in zone DMA
[S390] uaccess: make sure copy_from_user_overflow is builtin

+342 -57
-7
arch/s390/include/asm/qdio.h
··· 321 321 #define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40 322 322 #define QDIO_ERROR_SLSB_STATE 0x80 323 323 324 - /* for qdio_initialize */ 325 - #define QDIO_INBOUND_0COPY_SBALS 0x01 326 - #define QDIO_OUTBOUND_0COPY_SBALS 0x02 327 - #define QDIO_USE_OUTBOUND_PCIS 0x04 328 - 329 324 /* for qdio_cleanup */ 330 325 #define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01 331 326 #define QDIO_FLAG_CLEANUP_USING_HALT 0x02 ··· 339 344 * @input_handler: handler to be called for input queues 340 345 * @output_handler: handler to be called for output queues 341 346 * @int_parm: interruption parameter 342 - * @flags: initialization flags 343 347 * @input_sbal_addr_array: address of no_input_qs * 128 pointers 344 348 * @output_sbal_addr_array: address of no_output_qs * 128 pointers 345 349 */ ··· 355 361 qdio_handler_t *input_handler; 356 362 qdio_handler_t *output_handler; 357 363 unsigned long int_parm; 358 - unsigned long flags; 359 364 void **input_sbal_addr_array; 360 365 void **output_sbal_addr_array; 361 366 };
+5 -5
arch/s390/kernel/time.c
··· 73 73 } 74 74 EXPORT_SYMBOL(monotonic_clock); 75 75 76 - void tod_to_timeval(__u64 todval, struct timespec *xtime) 76 + void tod_to_timeval(__u64 todval, struct timespec *xt) 77 77 { 78 78 unsigned long long sec; 79 79 80 80 sec = todval >> 12; 81 81 do_div(sec, 1000000); 82 - xtime->tv_sec = sec; 82 + xt->tv_sec = sec; 83 83 todval -= (sec * 1000000) << 12; 84 - xtime->tv_nsec = ((todval * 1000) >> 12); 84 + xt->tv_nsec = ((todval * 1000) >> 12); 85 85 } 86 86 EXPORT_SYMBOL(tod_to_timeval); 87 87 ··· 216 216 ++vdso_data->tb_update_count; 217 217 smp_wmb(); 218 218 vdso_data->xtime_tod_stamp = clock->cycle_last; 219 - vdso_data->xtime_clock_sec = xtime.tv_sec; 220 - vdso_data->xtime_clock_nsec = xtime.tv_nsec; 219 + vdso_data->xtime_clock_sec = wall_time->tv_sec; 220 + vdso_data->xtime_clock_nsec = wall_time->tv_nsec; 221 221 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; 222 222 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; 223 223 smp_wmb();
+2 -1
arch/s390/lib/Makefile
··· 2 2 # Makefile for s390-specific library files.. 3 3 # 4 4 5 - lib-y += delay.o string.o uaccess_std.o uaccess_pt.o usercopy.o 5 + lib-y += delay.o string.o uaccess_std.o uaccess_pt.o 6 + obj-y += usercopy.o 6 7 obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o 7 8 lib-$(CONFIG_64BIT) += uaccess_mvcos.o 8 9 lib-$(CONFIG_SMP) += spinlock.o
+1 -1
arch/s390/mm/cmm.c
··· 374 374 #ifdef CONFIG_CMM_IUCV 375 375 #define SMSG_PREFIX "CMM" 376 376 static void 377 - cmm_smsg_target(char *from, char *msg) 377 + cmm_smsg_target(const char *from, char *msg) 378 378 { 379 379 long nr, seconds; 380 380
+4 -2
drivers/char/hvc_iucv.c
··· 139 139 * 140 140 * This function allocates a new struct iucv_tty_buffer element and, optionally, 141 141 * allocates an internal data buffer with the specified size @size. 142 + * The internal data buffer is always allocated with GFP_DMA which is 143 + * required for receiving and sending data with IUCV. 142 144 * Note: The total message size arises from the internal buffer size and the 143 145 * members of the iucv_tty_msg structure. 144 146 * The function returns NULL if memory allocation has failed. ··· 156 154 157 155 if (size > 0) { 158 156 bufp->msg.length = MSG_SIZE(size); 159 - bufp->mbuf = kmalloc(bufp->msg.length, flags); 157 + bufp->mbuf = kmalloc(bufp->msg.length, flags | GFP_DMA); 160 158 if (!bufp->mbuf) { 161 159 mempool_free(bufp, hvc_iucv_mempool); 162 160 return NULL; ··· 239 237 if (!rb->mbuf) { /* message not yet received ... */ 240 238 /* allocate mem to store msg data; if no memory is available 241 239 * then leave the buffer on the list and re-try later */ 242 - rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC); 240 + rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC | GFP_DMA); 243 241 if (!rb->mbuf) 244 242 return -ENOMEM; 245 243
+36
drivers/s390/block/dasd.c
··· 26 26 #include <asm/ebcdic.h> 27 27 #include <asm/idals.h> 28 28 #include <asm/itcw.h> 29 + #include <asm/diag.h> 29 30 30 31 /* This is ugly... */ 31 32 #define PRINTK_HEADER "dasd:" ··· 2213 2212 goto out; 2214 2213 } 2215 2214 2215 + if ((mode & FMODE_WRITE) && 2216 + (test_bit(DASD_FLAG_DEVICE_RO, &base->flags) || 2217 + (base->features & DASD_FEATURE_READONLY))) { 2218 + rc = -EROFS; 2219 + goto out; 2220 + } 2221 + 2216 2222 return 0; 2217 2223 2218 2224 out: ··· 2296 2288 /* 2297 2289 * SECTION: common functions for ccw_driver use 2298 2290 */ 2291 + 2292 + /* 2293 + * Is the device read-only? 2294 + * Note that this function does not report the setting of the 2295 + * readonly device attribute, but how it is configured in z/VM. 2296 + */ 2297 + int dasd_device_is_ro(struct dasd_device *device) 2298 + { 2299 + struct ccw_dev_id dev_id; 2300 + struct diag210 diag_data; 2301 + int rc; 2302 + 2303 + if (!MACHINE_IS_VM) 2304 + return 0; 2305 + ccw_device_get_id(device->cdev, &dev_id); 2306 + memset(&diag_data, 0, sizeof(diag_data)); 2307 + diag_data.vrdcdvno = dev_id.devno; 2308 + diag_data.vrdclen = sizeof(diag_data); 2309 + rc = diag210(&diag_data); 2310 + if (rc == 0 || rc == 2) { 2311 + return diag_data.vrdcvfla & 0x80; 2312 + } else { 2313 + DBF_EVENT(DBF_WARNING, "diag210 failed for dev=%04x with rc=%d", 2314 + dev_id.devno, rc); 2315 + return 0; 2316 + } 2317 + } 2318 + EXPORT_SYMBOL_GPL(dasd_device_is_ro); 2299 2319 2300 2320 static void dasd_generic_auto_online(void *data, async_cookie_t cookie) 2301 2321 {
+4
drivers/s390/block/dasd_3990_erp.c
··· 1045 1045 1046 1046 erp->retries = 5; 1047 1047 1048 + } else if (sense[1] & SNS1_WRITE_INHIBITED) { 1049 + dev_err(&device->cdev->dev, "An I/O request was rejected" 1050 + " because writing is inhibited\n"); 1051 + erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); 1048 1052 } else { 1049 1053 /* fatal error - set status to FAILED 1050 1054 internal error 09 - Command Reject */
+8 -5
drivers/s390/block/dasd_devmap.c
··· 742 742 const char *buf, size_t count) 743 743 { 744 744 struct dasd_devmap *devmap; 745 + struct dasd_device *device; 745 746 int val; 746 747 char *endp; 747 748 ··· 759 758 devmap->features |= DASD_FEATURE_READONLY; 760 759 else 761 760 devmap->features &= ~DASD_FEATURE_READONLY; 762 - if (devmap->device) 763 - devmap->device->features = devmap->features; 764 - if (devmap->device && devmap->device->block 765 - && devmap->device->block->gdp) 766 - set_disk_ro(devmap->device->block->gdp, val); 761 + device = devmap->device; 762 + if (device) { 763 + device->features = devmap->features; 764 + val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags); 765 + } 767 766 spin_unlock(&dasd_devmap_lock); 767 + if (device && device->block && device->block->gdp) 768 + set_disk_ro(device->block->gdp, val); 768 769 return count; 769 770 } 770 771
+2 -4
drivers/s390/block/dasd_diag.c
··· 145 145 mdsk_term_io(device); 146 146 rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); 147 147 if (rc == 4) { 148 - if (!(device->features & DASD_FEATURE_READONLY)) { 148 + if (!(test_and_set_bit(DASD_FLAG_DEVICE_RO, &device->flags))) 149 149 pr_warning("%s: The access mode of a DIAG device " 150 150 "changed to read-only\n", 151 151 dev_name(&device->cdev->dev)); 152 - device->features |= DASD_FEATURE_READONLY; 153 - } 154 152 rc = 0; 155 153 } 156 154 if (rc) ··· 447 449 rc = -EIO; 448 450 } else { 449 451 if (rc == 4) 450 - device->features |= DASD_FEATURE_READONLY; 452 + set_bit(DASD_FLAG_DEVICE_RO, &device->flags); 451 453 pr_info("%s: New DASD with %ld byte/block, total size %ld " 452 454 "KB%s\n", dev_name(&device->cdev->dev), 453 455 (unsigned long) block->bp_block,
+18 -9
drivers/s390/block/dasd_eckd.c
··· 1089 1089 struct dasd_eckd_private *private; 1090 1090 struct dasd_block *block; 1091 1091 int is_known, rc; 1092 + int readonly; 1092 1093 1093 1094 if (!ccw_device_is_pathgroup(device->cdev)) { 1094 1095 dev_warn(&device->cdev->dev, ··· 1183 1182 else 1184 1183 private->real_cyl = private->rdc_data.no_cyl; 1185 1184 1185 + readonly = dasd_device_is_ro(device); 1186 + if (readonly) 1187 + set_bit(DASD_FLAG_DEVICE_RO, &device->flags); 1188 + 1186 1189 dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) " 1187 - "with %d cylinders, %d heads, %d sectors\n", 1190 + "with %d cylinders, %d heads, %d sectors%s\n", 1188 1191 private->rdc_data.dev_type, 1189 1192 private->rdc_data.dev_model, 1190 1193 private->rdc_data.cu_type, 1191 1194 private->rdc_data.cu_model.model, 1192 1195 private->real_cyl, 1193 1196 private->rdc_data.trk_per_cyl, 1194 - private->rdc_data.sec_per_trk); 1197 + private->rdc_data.sec_per_trk, 1198 + readonly ? ", read-only device" : ""); 1195 1199 return 0; 1196 1200 1197 1201 out_err3: ··· 2845 2839 char *psf_data, *rssd_result; 2846 2840 struct dasd_ccw_req *cqr; 2847 2841 struct ccw1 *ccw; 2842 + char psf0, psf1; 2848 2843 int rc; 2844 + 2845 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) 2846 + return -EACCES; 2847 + psf0 = psf1 = 0; 2849 2848 2850 2849 /* Copy parms from caller */ 2851 2850 rc = -EFAULT; ··· 2880 2869 (void __user *)(unsigned long) usrparm.psf_data, 2881 2870 usrparm.psf_data_len)) 2882 2871 goto out_free; 2883 - 2884 - /* sanity check on syscall header */ 2885 - if (psf_data[0] != 0x17 && psf_data[1] != 0xce) { 2886 - rc = -EINVAL; 2887 - goto out_free; 2888 - } 2872 + psf0 = psf_data[0]; 2873 + psf1 = psf_data[1]; 2889 2874 2890 2875 /* setup CCWs for PSF + RSSD */ 2891 2876 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device); ··· 2932 2925 kfree(rssd_result); 2933 2926 kfree(psf_data); 2934 2927 out: 2935 - DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc); 2928 + DBF_DEV_EVENT(DBF_WARNING, device, 2929 + "Symmetrix ioctl (0x%02x 0x%02x): rc=%d", 2930 + (int) psf0, (int) psf1, rc); 2936 2931 return rc; 2937 2932 } 2938 2933
+8 -2
drivers/s390/block/dasd_fba.c
··· 124 124 struct dasd_fba_private *private; 125 125 struct ccw_device *cdev = device->cdev; 126 126 int rc; 127 + int readonly; 127 128 128 129 private = (struct dasd_fba_private *) device->private; 129 130 if (!private) { ··· 163 162 return rc; 164 163 } 165 164 165 + readonly = dasd_device_is_ro(device); 166 + if (readonly) 167 + set_bit(DASD_FLAG_DEVICE_RO, &device->flags); 168 + 166 169 dev_info(&device->cdev->dev, 167 170 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB " 168 - "and %d B/blk\n", 171 + "and %d B/blk%s\n", 169 172 cdev->id.dev_type, 170 173 cdev->id.dev_model, 171 174 cdev->id.cu_type, 172 175 cdev->id.cu_model, 173 176 ((private->rdc_data.blk_bdsa * 174 177 (private->rdc_data.blk_size >> 9)) >> 11), 175 - private->rdc_data.blk_size); 178 + private->rdc_data.blk_size, 179 + readonly ? ", read-only device" : ""); 176 180 return 0; 177 181 } 178 182
+2 -1
drivers/s390/block/dasd_genhd.c
··· 70 70 } 71 71 len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26)); 72 72 73 - if (block->base->features & DASD_FEATURE_READONLY) 73 + if (base->features & DASD_FEATURE_READONLY || 74 + test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) 74 75 set_disk_ro(gdp, 1); 75 76 gdp->private_data = block; 76 77 gdp->queue = block->request_queue;
+7
drivers/s390/block/dasd_int.h
··· 436 436 #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ 437 437 #define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ 438 438 #define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ 439 + #define DASD_FLAG_DEVICE_RO 6 /* The device itself is read-only. Don't 440 + * confuse this with the user specified 441 + * read-only feature. 442 + */ 439 443 440 444 void dasd_put_device_wake(struct dasd_device *); 441 445 ··· 612 608 613 609 void dasd_device_set_stop_bits(struct dasd_device *, int); 614 610 void dasd_device_remove_stop_bits(struct dasd_device *, int); 611 + 612 + int dasd_device_is_ro(struct dasd_device *); 613 + 615 614 616 615 /* externals in dasd_devmap.c */ 617 616 extern int dasd_max_devindex;
+4 -2
drivers/s390/block/dasd_ioctl.c
··· 199 199 if (!argp) 200 200 return -EINVAL; 201 201 202 - if (block->base->features & DASD_FEATURE_READONLY) 202 + if (block->base->features & DASD_FEATURE_READONLY || 203 + test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) 203 204 return -EROFS; 204 205 if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) 205 206 return -EFAULT; ··· 350 349 return -EINVAL; 351 350 if (get_user(intval, (int __user *)argp)) 352 351 return -EFAULT; 353 - 352 + if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) 353 + return -EROFS; 354 354 set_disk_ro(bdev->bd_disk, intval); 355 355 return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); 356 356 }
+3 -2
drivers/s390/cio/device.c
··· 764 764 static void io_subchannel_register(struct ccw_device *cdev) 765 765 { 766 766 struct subchannel *sch; 767 - int ret; 767 + int ret, adjust_init_count = 1; 768 768 unsigned long flags; 769 769 770 770 sch = to_subchannel(cdev->dev.parent); ··· 793 793 cdev->private->dev_id.ssid, 794 794 cdev->private->dev_id.devno); 795 795 } 796 + adjust_init_count = 0; 796 797 goto out; 797 798 } 798 799 /* ··· 819 818 cdev->private->flags.recog_done = 1; 820 819 wake_up(&cdev->private->wait_q); 821 820 out_err: 822 - if (atomic_dec_and_test(&ccw_device_init_count)) 821 + if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count)) 823 822 wake_up(&ccw_device_init_wq); 824 823 } 825 824
-1
drivers/s390/cio/qdio_debug.c
··· 33 33 DBF_HEX(&init_data->input_handler, sizeof(void *)); 34 34 DBF_HEX(&init_data->output_handler, sizeof(void *)); 35 35 DBF_HEX(&init_data->int_parm, sizeof(long)); 36 - DBF_HEX(&init_data->flags, sizeof(long)); 37 36 DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *)); 38 37 DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *)); 39 38 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
+2 -1
drivers/s390/cio/qdio_main.c
··· 588 588 if (q->is_input_q) { 589 589 qperf_inc(q, inbound_handler); 590 590 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); 591 - } else 591 + } else { 592 592 qperf_inc(q, outbound_handler); 593 593 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", 594 594 start, count); 595 + } 595 596 596 597 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count, 597 598 q->irq_ptr->int_parm);
+10
drivers/s390/net/Kconfig
··· 43 43 Select this option if you want to be able to receive SMSG messages 44 44 from other VM guest systems. 45 45 46 + config SMSGIUCV_EVENT 47 + tristate "Deliver IUCV special messages as uevents (VM only)" 48 + depends on SMSGIUCV 49 + help 50 + Select this option to deliver CP special messages (SMSGs) as 51 + uevents. The driver handles only those special messages that 52 + start with "APP". 53 + 54 + To compile as a module, choose M. The module name is "smsgiucv_app". 55 + 46 56 config CLAW 47 57 tristate "CLAW device support" 48 58 depends on CCW && NETDEVICES
+1
drivers/s390/net/Makefile
··· 6 6 obj-$(CONFIG_CTCM) += ctcm.o fsm.o 7 7 obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o 8 8 obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 9 + obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o 9 10 obj-$(CONFIG_LCS) += lcs.o 10 11 obj-$(CONFIG_CLAW) += claw.o 11 12 qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
-3
drivers/s390/net/qeth_core_main.c
··· 3805 3805 init_data.input_handler = card->discipline.input_handler; 3806 3806 init_data.output_handler = card->discipline.output_handler; 3807 3807 init_data.int_parm = (unsigned long) card; 3808 - init_data.flags = QDIO_INBOUND_0COPY_SBALS | 3809 - QDIO_OUTBOUND_0COPY_SBALS | 3810 - QDIO_USE_OUTBOUND_PCIS; 3811 3808 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; 3812 3809 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; 3813 3810
+8 -7
drivers/s390/net/smsgiucv.c
··· 31 31 32 32 struct smsg_callback { 33 33 struct list_head list; 34 - char *prefix; 34 + const char *prefix; 35 35 int len; 36 - void (*callback)(char *from, char *str); 36 + void (*callback)(const char *from, char *str); 37 37 }; 38 38 39 39 MODULE_AUTHOR ··· 100 100 kfree(buffer); 101 101 } 102 102 103 - int smsg_register_callback(char *prefix, 104 - void (*callback)(char *from, char *str)) 103 + int smsg_register_callback(const char *prefix, 104 + void (*callback)(const char *from, char *str)) 105 105 { 106 106 struct smsg_callback *cb; 107 107 ··· 117 117 return 0; 118 118 } 119 119 120 - void smsg_unregister_callback(char *prefix, 121 - void (*callback)(char *from, char *str)) 120 + void smsg_unregister_callback(const char *prefix, 121 + void (*callback)(const char *from, 122 + char *str)) 122 123 { 123 124 struct smsg_callback *cb, *tmp; 124 125 ··· 177 176 178 177 static struct device_driver smsg_driver = { 179 178 .owner = THIS_MODULE, 180 - .name = "SMSGIUCV", 179 + .name = SMSGIUCV_DRV_NAME, 181 180 .bus = &iucv_bus, 182 181 .pm = &smsg_pm_ops, 183 182 };
+6 -2
drivers/s390/net/smsgiucv.h
··· 5 5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 6 6 */ 7 7 8 - int smsg_register_callback(char *, void (*)(char *, char *)); 9 - void smsg_unregister_callback(char *, void (*)(char *, char *)); 8 + #define SMSGIUCV_DRV_NAME "SMSGIUCV" 9 + 10 + int smsg_register_callback(const char *, 11 + void (*)(const char *, char *)); 12 + void smsg_unregister_callback(const char *, 13 + void (*)(const char *, char *)); 10 14
+211
drivers/s390/net/smsgiucv_app.c
··· 1 + /* 2 + * Deliver z/VM CP special messages (SMSG) as uevents. 3 + * 4 + * The driver registers for z/VM CP special messages with the 5 + * "APP" prefix. Incoming messages are delivered to user space 6 + * as uevents. 7 + * 8 + * Copyright IBM Corp. 2010 9 + * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> 10 + * 11 + */ 12 + #define KMSG_COMPONENT "smsgiucv_app" 13 + #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 14 + 15 + #include <linux/ctype.h> 16 + #include <linux/err.h> 17 + #include <linux/device.h> 18 + #include <linux/list.h> 19 + #include <linux/kobject.h> 20 + #include <linux/module.h> 21 + #include <linux/spinlock.h> 22 + #include <linux/workqueue.h> 23 + #include <net/iucv/iucv.h> 24 + #include "smsgiucv.h" 25 + 26 + /* prefix used for SMSG registration */ 27 + #define SMSG_PREFIX "APP" 28 + 29 + /* SMSG related uevent environment variables */ 30 + #define ENV_SENDER_STR "SMSG_SENDER=" 31 + #define ENV_SENDER_LEN (strlen(ENV_SENDER_STR) + 8 + 1) 32 + #define ENV_PREFIX_STR "SMSG_ID=" 33 + #define ENV_PREFIX_LEN (strlen(ENV_PREFIX_STR) + \ 34 + strlen(SMSG_PREFIX) + 1) 35 + #define ENV_TEXT_STR "SMSG_TEXT=" 36 + #define ENV_TEXT_LEN(msg) (strlen(ENV_TEXT_STR) + strlen((msg)) + 1) 37 + 38 + /* z/VM user ID which is permitted to send SMSGs 39 + * If the value is undefined or empty (""), special messages are 40 + * accepted from any z/VM user ID. */ 41 + static char *sender; 42 + module_param(sender, charp, 0400); 43 + MODULE_PARM_DESC(sender, "z/VM user ID from which CP SMSGs are accepted"); 44 + 45 + /* SMSG device representation */ 46 + static struct device *smsg_app_dev; 47 + 48 + /* list element for queuing received messages for delivery */ 49 + struct smsg_app_event { 50 + struct list_head list; 51 + char *buf; 52 + char *envp[4]; 53 + }; 54 + 55 + /* queue for outgoing uevents */ 56 + static LIST_HEAD(smsg_event_queue); 57 + static DEFINE_SPINLOCK(smsg_event_queue_lock); 58 + 59 + static void smsg_app_event_free(struct smsg_app_event *ev) 60 + { 61 + kfree(ev->buf); 62 + kfree(ev); 63 + } 64 + 65 + static struct smsg_app_event *smsg_app_event_alloc(const char *from, 66 + const char *msg) 67 + { 68 + struct smsg_app_event *ev; 69 + 70 + ev = kzalloc(sizeof(*ev), GFP_ATOMIC); 71 + if (!ev) 72 + return NULL; 73 + 74 + ev->buf = kzalloc(ENV_SENDER_LEN + ENV_PREFIX_LEN + 75 + ENV_TEXT_LEN(msg), GFP_ATOMIC); 76 + if (!ev->buf) { 77 + kfree(ev); 78 + return NULL; 79 + } 80 + 81 + /* setting up environment pointers into buf */ 82 + ev->envp[0] = ev->buf; 83 + ev->envp[1] = ev->envp[0] + ENV_SENDER_LEN; 84 + ev->envp[2] = ev->envp[1] + ENV_PREFIX_LEN; 85 + ev->envp[3] = NULL; 86 + 87 + /* setting up environment: sender, prefix name, and message text */ 88 + snprintf(ev->envp[0], ENV_SENDER_LEN, ENV_SENDER_STR "%s", from); 89 + snprintf(ev->envp[1], ENV_PREFIX_LEN, ENV_PREFIX_STR "%s", SMSG_PREFIX); 90 + snprintf(ev->envp[2], ENV_TEXT_LEN(msg), ENV_TEXT_STR "%s", msg); 91 + 92 + return ev; 93 + } 94 + 95 + static void smsg_event_work_fn(struct work_struct *work) 96 + { 97 + LIST_HEAD(event_queue); 98 + struct smsg_app_event *p, *n; 99 + struct device *dev; 100 + 101 + dev = get_device(smsg_app_dev); 102 + if (!dev) 103 + return; 104 + 105 + spin_lock_bh(&smsg_event_queue_lock); 106 + list_splice_init(&smsg_event_queue, &event_queue); 107 + spin_unlock_bh(&smsg_event_queue_lock); 108 + 109 + list_for_each_entry_safe(p, n, &event_queue, list) { 110 + list_del(&p->list); 111 + kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, p->envp); 112 + smsg_app_event_free(p); 113 + } 114 + 115 + put_device(dev); 116 + } 117 + static DECLARE_WORK(smsg_event_work, smsg_event_work_fn); 118 + 119 + static void smsg_app_callback(const char *from, char *msg) 120 + { 121 + struct smsg_app_event *se; 122 + 123 + /* check if the originating z/VM user ID matches 124 + * the configured sender. */ 125 + if (sender && strlen(sender) > 0 && strcmp(from, sender) != 0) 126 + return; 127 + 128 + /* get start of message text (skip prefix and leading blanks) */ 129 + msg += strlen(SMSG_PREFIX); 130 + while (*msg && isspace(*msg)) 131 + msg++; 132 + if (*msg == '\0') 133 + return; 134 + 135 + /* allocate event list element and its environment */ 136 + se = smsg_app_event_alloc(from, msg); 137 + if (!se) 138 + return; 139 + 140 + /* queue event and schedule work function */ 141 + spin_lock(&smsg_event_queue_lock); 142 + list_add_tail(&se->list, &smsg_event_queue); 143 + spin_unlock(&smsg_event_queue_lock); 144 + 145 + schedule_work(&smsg_event_work); 146 + return; 147 + } 148 + 149 + static int __init smsgiucv_app_init(void) 150 + { 151 + struct device_driver *smsgiucv_drv; 152 + int rc; 153 + 154 + if (!MACHINE_IS_VM) 155 + return -ENODEV; 156 + 157 + smsg_app_dev = kzalloc(sizeof(*smsg_app_dev), GFP_KERNEL); 158 + if (!smsg_app_dev) 159 + return -ENOMEM; 160 + 161 + smsgiucv_drv = driver_find(SMSGIUCV_DRV_NAME, &iucv_bus); 162 + if (!smsgiucv_drv) { 163 + kfree(smsg_app_dev); 164 + return -ENODEV; 165 + } 166 + 167 + rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT); 168 + if (rc) { 169 + kfree(smsg_app_dev); 170 + goto fail_put_driver; 171 + } 172 + smsg_app_dev->bus = &iucv_bus; 173 + smsg_app_dev->parent = iucv_root; 174 + smsg_app_dev->release = (void (*)(struct device *)) kfree; 175 + smsg_app_dev->driver = smsgiucv_drv; 176 + rc = device_register(smsg_app_dev); 177 + if (rc) { 178 + put_device(smsg_app_dev); 179 + goto fail_put_driver; 180 + } 181 + 182 + /* register with the smsgiucv device driver */ 183 + rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback); 184 + if (rc) { 185 + device_unregister(smsg_app_dev); 186 + goto fail_put_driver; 187 + } 188 + 189 + rc = 0; 190 + fail_put_driver: 191 + put_driver(smsgiucv_drv); 192 + return rc; 193 + } 194 + module_init(smsgiucv_app_init); 195 + 196 + static void __exit smsgiucv_app_exit(void) 197 + { 198 + /* unregister callback */ 199 + smsg_unregister_callback(SMSG_PREFIX, smsg_app_callback); 200 + 201 + /* cancel pending work and flush any queued event work */ 202 + cancel_work_sync(&smsg_event_work); 203 + smsg_event_work_fn(&smsg_event_work); 204 + 205 + device_unregister(smsg_app_dev); 206 + } 207 + module_exit(smsgiucv_app_exit); 208 + 209 + MODULE_LICENSE("GPL v2"); 210 + MODULE_DESCRIPTION("Deliver z/VM CP SMSG as uevents"); 211 + MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>");
-2
drivers/s390/scsi/zfcp_qdio.c
··· 319 319 id->input_handler = zfcp_qdio_int_resp; 320 320 id->output_handler = zfcp_qdio_int_req; 321 321 id->int_parm = (unsigned long) qdio; 322 - id->flags = QDIO_INBOUND_0COPY_SBALS | 323 - QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS; 324 322 id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal); 325 323 id->output_sbal_addr_array = (void **) (qdio->req_q.sbal); 326 324