aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c36
-rw-r--r--drivers/s390/block/dasd_3990_erp.c4
-rw-r--r--drivers/s390/block/dasd_devmap.c13
-rw-r--r--drivers/s390/block/dasd_diag.c6
-rw-r--r--drivers/s390/block/dasd_eckd.c27
-rw-r--r--drivers/s390/block/dasd_fba.c10
-rw-r--r--drivers/s390/block/dasd_genhd.c3
-rw-r--r--drivers/s390/block/dasd_int.h7
-rw-r--r--drivers/s390/block/dasd_ioctl.c6
-rw-r--r--drivers/s390/char/raw3270.c2
-rw-r--r--drivers/s390/char/sclp.c2
-rw-r--r--drivers/s390/cio/device.c5
-rw-r--r--drivers/s390/cio/qdio_debug.c1
-rw-r--r--drivers/s390/cio/qdio_main.c3
-rw-r--r--drivers/s390/net/Kconfig10
-rw-r--r--drivers/s390/net/Makefile1
-rw-r--r--drivers/s390/net/qeth_core.h5
-rw-r--r--drivers/s390/net/qeth_core_main.c172
-rw-r--r--drivers/s390/net/qeth_core_mpc.h44
-rw-r--r--drivers/s390/net/qeth_core_sys.c14
-rw-r--r--drivers/s390/net/qeth_l2_main.c30
-rw-r--r--drivers/s390/net/qeth_l3.h2
-rw-r--r--drivers/s390/net/qeth_l3_main.c176
-rw-r--r--drivers/s390/net/qeth_l3_sys.c56
-rw-r--r--drivers/s390/net/smsgiucv.c15
-rw-r--r--drivers/s390/net/smsgiucv.h8
-rw-r--r--drivers/s390/net/smsgiucv_app.c211
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c2
28 files changed, 703 insertions, 168 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 4951aa82e9f5..bbea90baf98f 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -26,6 +26,7 @@
26#include <asm/ebcdic.h> 26#include <asm/ebcdic.h>
27#include <asm/idals.h> 27#include <asm/idals.h>
28#include <asm/itcw.h> 28#include <asm/itcw.h>
29#include <asm/diag.h>
29 30
30/* This is ugly... */ 31/* This is ugly... */
31#define PRINTK_HEADER "dasd:" 32#define PRINTK_HEADER "dasd:"
@@ -2212,6 +2213,13 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)
2212 goto out; 2213 goto out;
2213 } 2214 }
2214 2215
2216 if ((mode & FMODE_WRITE) &&
2217 (test_bit(DASD_FLAG_DEVICE_RO, &base->flags) ||
2218 (base->features & DASD_FEATURE_READONLY))) {
2219 rc = -EROFS;
2220 goto out;
2221 }
2222
2215 return 0; 2223 return 0;
2216 2224
2217out: 2225out:
@@ -2289,6 +2297,34 @@ dasd_exit(void)
2289 * SECTION: common functions for ccw_driver use 2297 * SECTION: common functions for ccw_driver use
2290 */ 2298 */
2291 2299
2300/*
2301 * Is the device read-only?
2302 * Note that this function does not report the setting of the
2303 * readonly device attribute, but how it is configured in z/VM.
2304 */
2305int dasd_device_is_ro(struct dasd_device *device)
2306{
2307 struct ccw_dev_id dev_id;
2308 struct diag210 diag_data;
2309 int rc;
2310
2311 if (!MACHINE_IS_VM)
2312 return 0;
2313 ccw_device_get_id(device->cdev, &dev_id);
2314 memset(&diag_data, 0, sizeof(diag_data));
2315 diag_data.vrdcdvno = dev_id.devno;
2316 diag_data.vrdclen = sizeof(diag_data);
2317 rc = diag210(&diag_data);
2318 if (rc == 0 || rc == 2) {
2319 return diag_data.vrdcvfla & 0x80;
2320 } else {
2321 DBF_EVENT(DBF_WARNING, "diag210 failed for dev=%04x with rc=%d",
2322 dev_id.devno, rc);
2323 return 0;
2324 }
2325}
2326EXPORT_SYMBOL_GPL(dasd_device_is_ro);
2327
2292static void dasd_generic_auto_online(void *data, async_cookie_t cookie) 2328static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
2293{ 2329{
2294 struct ccw_device *cdev = data; 2330 struct ccw_device *cdev = data;
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 44796ba4eb9b..51224f76b980 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -1045,6 +1045,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
1045 1045
1046 erp->retries = 5; 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 } else { 1052 } else {
1049 /* fatal error - set status to FAILED 1053 /* fatal error - set status to FAILED
1050 internal error 09 - Command Reject */ 1054 internal error 09 - Command Reject */
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index d49766f3b940..8e23919c8704 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -742,6 +742,7 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
742 const char *buf, size_t count) 742 const char *buf, size_t count)
743{ 743{
744 struct dasd_devmap *devmap; 744 struct dasd_devmap *devmap;
745 struct dasd_device *device;
745 int val; 746 int val;
746 char *endp; 747 char *endp;
747 748
@@ -758,12 +759,14 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
758 devmap->features |= DASD_FEATURE_READONLY; 759 devmap->features |= DASD_FEATURE_READONLY;
759 else 760 else
760 devmap->features &= ~DASD_FEATURE_READONLY; 761 devmap->features &= ~DASD_FEATURE_READONLY;
761 if (devmap->device) 762 device = devmap->device;
762 devmap->device->features = devmap->features; 763 if (device) {
763 if (devmap->device && devmap->device->block 764 device->features = devmap->features;
764 && devmap->device->block->gdp) 765 val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
765 set_disk_ro(devmap->device->block->gdp, val); 766 }
766 spin_unlock(&dasd_devmap_lock); 767 spin_unlock(&dasd_devmap_lock);
768 if (device && device->block && device->block->gdp)
769 set_disk_ro(device->block->gdp, val);
767 return count; 770 return count;
768} 771}
769 772
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 6e14863f5c70..687f323cdc38 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -145,12 +145,10 @@ dasd_diag_erp(struct dasd_device *device)
145 mdsk_term_io(device); 145 mdsk_term_io(device);
146 rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); 146 rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
147 if (rc == 4) { 147 if (rc == 4) {
148 if (!(device->features & DASD_FEATURE_READONLY)) { 148 if (!(test_and_set_bit(DASD_FLAG_DEVICE_RO, &device->flags)))
149 pr_warning("%s: The access mode of a DIAG device " 149 pr_warning("%s: The access mode of a DIAG device "
150 "changed to read-only\n", 150 "changed to read-only\n",
151 dev_name(&device->cdev->dev)); 151 dev_name(&device->cdev->dev));
152 device->features |= DASD_FEATURE_READONLY;
153 }
154 rc = 0; 152 rc = 0;
155 } 153 }
156 if (rc) 154 if (rc)
@@ -449,7 +447,7 @@ dasd_diag_check_device(struct dasd_device *device)
449 rc = -EIO; 447 rc = -EIO;
450 } else { 448 } else {
451 if (rc == 4) 449 if (rc == 4)
452 device->features |= DASD_FEATURE_READONLY; 450 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
453 pr_info("%s: New DASD with %ld byte/block, total size %ld " 451 pr_info("%s: New DASD with %ld byte/block, total size %ld "
454 "KB%s\n", dev_name(&device->cdev->dev), 452 "KB%s\n", dev_name(&device->cdev->dev),
455 (unsigned long) block->bp_block, 453 (unsigned long) block->bp_block,
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 1cca21aafaba..01f4e7a34aa8 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1089,6 +1089,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1089 struct dasd_eckd_private *private; 1089 struct dasd_eckd_private *private;
1090 struct dasd_block *block; 1090 struct dasd_block *block;
1091 int is_known, rc; 1091 int is_known, rc;
1092 int readonly;
1092 1093
1093 if (!ccw_device_is_pathgroup(device->cdev)) { 1094 if (!ccw_device_is_pathgroup(device->cdev)) {
1094 dev_warn(&device->cdev->dev, 1095 dev_warn(&device->cdev->dev,
@@ -1182,15 +1183,20 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1182 else 1183 else
1183 private->real_cyl = private->rdc_data.no_cyl; 1184 private->real_cyl = private->rdc_data.no_cyl;
1184 1185
1186 readonly = dasd_device_is_ro(device);
1187 if (readonly)
1188 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
1189
1185 dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) " 1190 dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
1186 "with %d cylinders, %d heads, %d sectors\n", 1191 "with %d cylinders, %d heads, %d sectors%s\n",
1187 private->rdc_data.dev_type, 1192 private->rdc_data.dev_type,
1188 private->rdc_data.dev_model, 1193 private->rdc_data.dev_model,
1189 private->rdc_data.cu_type, 1194 private->rdc_data.cu_type,
1190 private->rdc_data.cu_model.model, 1195 private->rdc_data.cu_model.model,
1191 private->real_cyl, 1196 private->real_cyl,
1192 private->rdc_data.trk_per_cyl, 1197 private->rdc_data.trk_per_cyl,
1193 private->rdc_data.sec_per_trk); 1198 private->rdc_data.sec_per_trk,
1199 readonly ? ", read-only device" : "");
1194 return 0; 1200 return 0;
1195 1201
1196out_err3: 1202out_err3:
@@ -2839,8 +2845,13 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
2839 char *psf_data, *rssd_result; 2845 char *psf_data, *rssd_result;
2840 struct dasd_ccw_req *cqr; 2846 struct dasd_ccw_req *cqr;
2841 struct ccw1 *ccw; 2847 struct ccw1 *ccw;
2848 char psf0, psf1;
2842 int rc; 2849 int rc;
2843 2850
2851 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
2852 return -EACCES;
2853 psf0 = psf1 = 0;
2854
2844 /* Copy parms from caller */ 2855 /* Copy parms from caller */
2845 rc = -EFAULT; 2856 rc = -EFAULT;
2846 if (copy_from_user(&usrparm, argp, sizeof(usrparm))) 2857 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
@@ -2869,12 +2880,8 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
2869 (void __user *)(unsigned long) usrparm.psf_data, 2880 (void __user *)(unsigned long) usrparm.psf_data,
2870 usrparm.psf_data_len)) 2881 usrparm.psf_data_len))
2871 goto out_free; 2882 goto out_free;
2872 2883 psf0 = psf_data[0];
2873 /* sanity check on syscall header */ 2884 psf1 = psf_data[1];
2874 if (psf_data[0] != 0x17 && psf_data[1] != 0xce) {
2875 rc = -EINVAL;
2876 goto out_free;
2877 }
2878 2885
2879 /* setup CCWs for PSF + RSSD */ 2886 /* setup CCWs for PSF + RSSD */
2880 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device); 2887 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device);
@@ -2925,7 +2932,9 @@ out_free:
2925 kfree(rssd_result); 2932 kfree(rssd_result);
2926 kfree(psf_data); 2933 kfree(psf_data);
2927out: 2934out:
2928 DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc); 2935 DBF_DEV_EVENT(DBF_WARNING, device,
2936 "Symmetrix ioctl (0x%02x 0x%02x): rc=%d",
2937 (int) psf0, (int) psf1, rc);
2929 return rc; 2938 return rc;
2930} 2939}
2931 2940
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 0f152444ac77..37282b90eecc 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -124,6 +124,7 @@ dasd_fba_check_characteristics(struct dasd_device *device)
124 struct dasd_fba_private *private; 124 struct dasd_fba_private *private;
125 struct ccw_device *cdev = device->cdev; 125 struct ccw_device *cdev = device->cdev;
126 int rc; 126 int rc;
127 int readonly;
127 128
128 private = (struct dasd_fba_private *) device->private; 129 private = (struct dasd_fba_private *) device->private;
129 if (!private) { 130 if (!private) {
@@ -162,16 +163,21 @@ dasd_fba_check_characteristics(struct dasd_device *device)
162 return rc; 163 return rc;
163 } 164 }
164 165
166 readonly = dasd_device_is_ro(device);
167 if (readonly)
168 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
169
165 dev_info(&device->cdev->dev, 170 dev_info(&device->cdev->dev,
166 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB " 171 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
167 "and %d B/blk\n", 172 "and %d B/blk%s\n",
168 cdev->id.dev_type, 173 cdev->id.dev_type,
169 cdev->id.dev_model, 174 cdev->id.dev_model,
170 cdev->id.cu_type, 175 cdev->id.cu_type,
171 cdev->id.cu_model, 176 cdev->id.cu_model,
172 ((private->rdc_data.blk_bdsa * 177 ((private->rdc_data.blk_bdsa *
173 (private->rdc_data.blk_size >> 9)) >> 11), 178 (private->rdc_data.blk_size >> 9)) >> 11),
174 private->rdc_data.blk_size); 179 private->rdc_data.blk_size,
180 readonly ? ", read-only device" : "");
175 return 0; 181 return 0;
176} 182}
177 183
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 94f92a1247f2..30a1ca3d08b7 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -70,7 +70,8 @@ int dasd_gendisk_alloc(struct dasd_block *block)
70 } 70 }
71 len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26)); 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 set_disk_ro(gdp, 1); 75 set_disk_ro(gdp, 1);
75 gdp->private_data = block; 76 gdp->private_data = block;
76 gdp->queue = block->request_queue; 77 gdp->queue = block->request_queue;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index ed73ce550822..a91d4a97d4f2 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -436,6 +436,10 @@ struct dasd_block {
436#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ 436#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */
437#define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ 437#define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */
438#define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ 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
440void dasd_put_device_wake(struct dasd_device *); 444void dasd_put_device_wake(struct dasd_device *);
441 445
@@ -609,6 +613,9 @@ char *dasd_get_sense(struct irb *);
609void dasd_device_set_stop_bits(struct dasd_device *, int); 613void dasd_device_set_stop_bits(struct dasd_device *, int);
610void dasd_device_remove_stop_bits(struct dasd_device *, int); 614void dasd_device_remove_stop_bits(struct dasd_device *, int);
611 615
616int dasd_device_is_ro(struct dasd_device *);
617
618
612/* externals in dasd_devmap.c */ 619/* externals in dasd_devmap.c */
613extern int dasd_max_devindex; 620extern int dasd_max_devindex;
614extern int dasd_probeonly; 621extern int dasd_probeonly;
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 7039d9cf0fb4..3479f8158a1b 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -199,7 +199,8 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp)
199 if (!argp) 199 if (!argp)
200 return -EINVAL; 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 return -EROFS; 204 return -EROFS;
204 if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) 205 if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
205 return -EFAULT; 206 return -EFAULT;
@@ -349,7 +350,8 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp)
349 return -EINVAL; 350 return -EINVAL;
350 if (get_user(intval, (int __user *)argp)) 351 if (get_user(intval, (int __user *)argp))
351 return -EFAULT; 352 return -EFAULT;
352 353 if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags))
354 return -EROFS;
353 set_disk_ro(bdev->bd_disk, intval); 355 set_disk_ro(bdev->bd_disk, intval);
354 return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); 356 return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval);
355} 357}
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 62ddf5202b79..2a4c566456e7 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -373,7 +373,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
373 rq->rc = ccw_device_start(rp->cdev, &rq->ccw, 373 rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
374 (unsigned long) rq, 0, 0); 374 (unsigned long) rq, 0, 0);
375 if (rq->rc == 0) 375 if (rq->rc == 0)
376 return; /* Sucessfully restarted. */ 376 return; /* Successfully restarted. */
377 break; 377 break;
378 case RAW3270_IO_STOP: 378 case RAW3270_IO_STOP:
379 if (!rq) 379 if (!rq)
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index ec88c59842e3..f6d72e1f2a38 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -196,7 +196,7 @@ __sclp_start_request(struct sclp_req *req)
196 req->start_count++; 196 req->start_count++;
197 197
198 if (rc == 0) { 198 if (rc == 0) {
199 /* Sucessfully started request */ 199 /* Successfully started request */
200 req->status = SCLP_REQ_RUNNING; 200 req->status = SCLP_REQ_RUNNING;
201 sclp_running_state = sclp_running_state_running; 201 sclp_running_state = sclp_running_state_running;
202 __sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ, 202 __sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ,
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index c6abb75c4615..6d229f3523a0 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -764,7 +764,7 @@ static void sch_create_and_recog_new_device(struct subchannel *sch)
764static void io_subchannel_register(struct ccw_device *cdev) 764static void io_subchannel_register(struct ccw_device *cdev)
765{ 765{
766 struct subchannel *sch; 766 struct subchannel *sch;
767 int ret; 767 int ret, adjust_init_count = 1;
768 unsigned long flags; 768 unsigned long flags;
769 769
770 sch = to_subchannel(cdev->dev.parent); 770 sch = to_subchannel(cdev->dev.parent);
@@ -793,6 +793,7 @@ static void io_subchannel_register(struct ccw_device *cdev)
793 cdev->private->dev_id.ssid, 793 cdev->private->dev_id.ssid,
794 cdev->private->dev_id.devno); 794 cdev->private->dev_id.devno);
795 } 795 }
796 adjust_init_count = 0;
796 goto out; 797 goto out;
797 } 798 }
798 /* 799 /*
@@ -818,7 +819,7 @@ out:
818 cdev->private->flags.recog_done = 1; 819 cdev->private->flags.recog_done = 1;
819 wake_up(&cdev->private->wait_q); 820 wake_up(&cdev->private->wait_q);
820out_err: 821out_err:
821 if (atomic_dec_and_test(&ccw_device_init_count)) 822 if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count))
822 wake_up(&ccw_device_init_wq); 823 wake_up(&ccw_device_init_wq);
823} 824}
824 825
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index c94eb2a0fa2e..6ce83f56d537 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -33,7 +33,6 @@ void qdio_allocate_dbf(struct qdio_initialize *init_data,
33 DBF_HEX(&init_data->input_handler, sizeof(void *)); 33 DBF_HEX(&init_data->input_handler, sizeof(void *));
34 DBF_HEX(&init_data->output_handler, sizeof(void *)); 34 DBF_HEX(&init_data->output_handler, sizeof(void *));
35 DBF_HEX(&init_data->int_parm, sizeof(long)); 35 DBF_HEX(&init_data->int_parm, sizeof(long));
36 DBF_HEX(&init_data->flags, sizeof(long));
37 DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *)); 36 DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
38 DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *)); 37 DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
39 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); 38 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 232ef047ba34..4f8f74311778 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -588,10 +588,11 @@ static void qdio_kick_handler(struct qdio_q *q)
588 if (q->is_input_q) { 588 if (q->is_input_q) {
589 qperf_inc(q, inbound_handler); 589 qperf_inc(q, inbound_handler);
590 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); 590 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
591 } else 591 } else {
592 qperf_inc(q, outbound_handler); 592 qperf_inc(q, outbound_handler);
593 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", 593 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
594 start, count); 594 start, count);
595 }
595 596
596 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count, 597 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
597 q->irq_ptr->int_parm); 598 q->irq_ptr->int_parm);
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index cb909a5b5047..977bb4d4ed15 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -43,6 +43,16 @@ config SMSGIUCV
43 Select this option if you want to be able to receive SMSG messages 43 Select this option if you want to be able to receive SMSG messages
44 from other VM guest systems. 44 from other VM guest systems.
45 45
46config 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
46config CLAW 56config CLAW
47 tristate "CLAW device support" 57 tristate "CLAW device support"
48 depends on CCW && NETDEVICES 58 depends on CCW && NETDEVICES
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 6cab5a62f99e..4dfe8c1092da 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -6,6 +6,7 @@ ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o
6obj-$(CONFIG_CTCM) += ctcm.o fsm.o 6obj-$(CONFIG_CTCM) += ctcm.o fsm.o
7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o 7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
9obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o
9obj-$(CONFIG_LCS) += lcs.o 10obj-$(CONFIG_LCS) += lcs.o
10obj-$(CONFIG_CLAW) += claw.o 11obj-$(CONFIG_CLAW) += claw.o
11qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o 12qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index b232693378cd..a3ac4456e0b1 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -649,6 +649,7 @@ struct qeth_card_options {
649 int performance_stats; 649 int performance_stats;
650 int rx_sg_cb; 650 int rx_sg_cb;
651 enum qeth_ipa_isolation_modes isolation; 651 enum qeth_ipa_isolation_modes isolation;
652 int sniffer;
652}; 653};
653 654
654/* 655/*
@@ -737,6 +738,7 @@ struct qeth_card {
737 struct qeth_discipline discipline; 738 struct qeth_discipline discipline;
738 atomic_t force_alloc_skb; 739 atomic_t force_alloc_skb;
739 struct service_level qeth_service_level; 740 struct service_level qeth_service_level;
741 struct qdio_ssqd_desc ssqd;
740}; 742};
741 743
742struct qeth_card_list_struct { 744struct qeth_card_list_struct {
@@ -811,7 +813,8 @@ int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
811struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *, 813struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *,
812 enum qeth_ipa_cmds, enum qeth_prot_versions); 814 enum qeth_ipa_cmds, enum qeth_prot_versions);
813int qeth_query_setadapterparms(struct qeth_card *); 815int qeth_query_setadapterparms(struct qeth_card *);
814int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, const char *); 816int qeth_check_qdio_errors(struct qeth_card *, struct qdio_buffer *,
817 unsigned int, const char *);
815void qeth_queue_input_buffer(struct qeth_card *, int); 818void qeth_queue_input_buffer(struct qeth_card *, int);
816struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, 819struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
817 struct qdio_buffer *, struct qdio_buffer_element **, int *, 820 struct qdio_buffer *, struct qdio_buffer_element **, int *,
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index d34804d5ece1..7d25bdd443cd 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -269,6 +269,7 @@ int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
269 card->qdio.init_pool.buf_count = bufcnt; 269 card->qdio.init_pool.buf_count = bufcnt;
270 return qeth_alloc_buffer_pool(card); 270 return qeth_alloc_buffer_pool(card);
271} 271}
272EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool);
272 273
273static int qeth_issue_next_read(struct qeth_card *card) 274static int qeth_issue_next_read(struct qeth_card *card)
274{ 275{
@@ -350,8 +351,10 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
350 if (IS_IPA(iob->data)) { 351 if (IS_IPA(iob->data)) {
351 cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data); 352 cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
352 if (IS_IPA_REPLY(cmd)) { 353 if (IS_IPA_REPLY(cmd)) {
353 if (cmd->hdr.command < IPA_CMD_SETCCID || 354 if (cmd->hdr.command != IPA_CMD_SETCCID &&
354 cmd->hdr.command > IPA_CMD_MODCCID) 355 cmd->hdr.command != IPA_CMD_DELCCID &&
356 cmd->hdr.command != IPA_CMD_MODCCID &&
357 cmd->hdr.command != IPA_CMD_SET_DIAG_ASS)
355 qeth_issue_ipa_msg(cmd, 358 qeth_issue_ipa_msg(cmd,
356 cmd->hdr.return_code, card); 359 cmd->hdr.return_code, card);
357 return cmd; 360 return cmd;
@@ -1100,11 +1103,6 @@ static int qeth_setup_card(struct qeth_card *card)
1100 card->thread_running_mask = 0; 1103 card->thread_running_mask = 0;
1101 INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread); 1104 INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
1102 INIT_LIST_HEAD(&card->ip_list); 1105 INIT_LIST_HEAD(&card->ip_list);
1103 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
1104 if (!card->ip_tbd_list) {
1105 QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
1106 return -ENOMEM;
1107 }
1108 INIT_LIST_HEAD(card->ip_tbd_list); 1106 INIT_LIST_HEAD(card->ip_tbd_list);
1109 INIT_LIST_HEAD(&card->cmd_waiter_list); 1107 INIT_LIST_HEAD(&card->cmd_waiter_list);
1110 init_waitqueue_head(&card->wait_q); 1108 init_waitqueue_head(&card->wait_q);
@@ -1138,21 +1136,30 @@ static struct qeth_card *qeth_alloc_card(void)
1138 QETH_DBF_TEXT(SETUP, 2, "alloccrd"); 1136 QETH_DBF_TEXT(SETUP, 2, "alloccrd");
1139 card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL); 1137 card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL);
1140 if (!card) 1138 if (!card)
1141 return NULL; 1139 goto out;
1142 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 1140 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
1143 if (qeth_setup_channel(&card->read)) { 1141 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
1144 kfree(card); 1142 if (!card->ip_tbd_list) {
1145 return NULL; 1143 QETH_DBF_TEXT(SETUP, 0, "iptbdnom");
1146 } 1144 goto out_card;
1147 if (qeth_setup_channel(&card->write)) {
1148 qeth_clean_channel(&card->read);
1149 kfree(card);
1150 return NULL;
1151 } 1145 }
1146 if (qeth_setup_channel(&card->read))
1147 goto out_ip;
1148 if (qeth_setup_channel(&card->write))
1149 goto out_channel;
1152 card->options.layer2 = -1; 1150 card->options.layer2 = -1;
1153 card->qeth_service_level.seq_print = qeth_core_sl_print; 1151 card->qeth_service_level.seq_print = qeth_core_sl_print;
1154 register_service_level(&card->qeth_service_level); 1152 register_service_level(&card->qeth_service_level);
1155 return card; 1153 return card;
1154
1155out_channel:
1156 qeth_clean_channel(&card->read);
1157out_ip:
1158 kfree(card->ip_tbd_list);
1159out_card:
1160 kfree(card);
1161out:
1162 return NULL;
1156} 1163}
1157 1164
1158static int qeth_determine_card_type(struct qeth_card *card) 1165static int qeth_determine_card_type(struct qeth_card *card)
@@ -1355,26 +1362,29 @@ static int qeth_read_conf_data(struct qeth_card *card, void **buffer,
1355 return ret; 1362 return ret;
1356} 1363}
1357 1364
1358static int qeth_get_unitaddr(struct qeth_card *card) 1365static void qeth_configure_unitaddr(struct qeth_card *card, char *prcd)
1359{ 1366{
1360 int length; 1367 QETH_DBF_TEXT(SETUP, 2, "cfgunit");
1361 char *prcd;
1362 int rc;
1363
1364 QETH_DBF_TEXT(SETUP, 2, "getunit");
1365 rc = qeth_read_conf_data(card, (void **) &prcd, &length);
1366 if (rc) {
1367 QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n",
1368 dev_name(&card->gdev->dev), rc);
1369 return rc;
1370 }
1371 card->info.chpid = prcd[30]; 1368 card->info.chpid = prcd[30];
1372 card->info.unit_addr2 = prcd[31]; 1369 card->info.unit_addr2 = prcd[31];
1373 card->info.cula = prcd[63]; 1370 card->info.cula = prcd[63];
1374 card->info.guestlan = ((prcd[0x10] == _ascebc['V']) && 1371 card->info.guestlan = ((prcd[0x10] == _ascebc['V']) &&
1375 (prcd[0x11] == _ascebc['M'])); 1372 (prcd[0x11] == _ascebc['M']));
1376 kfree(prcd); 1373}
1377 return 0; 1374
1375static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd)
1376{
1377 QETH_DBF_TEXT(SETUP, 2, "cfgblkt");
1378
1379 if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) {
1380 card->info.blkt.time_total = 250;
1381 card->info.blkt.inter_packet = 5;
1382 card->info.blkt.inter_packet_jumbo = 15;
1383 } else {
1384 card->info.blkt.time_total = 0;
1385 card->info.blkt.inter_packet = 0;
1386 card->info.blkt.inter_packet_jumbo = 0;
1387 }
1378} 1388}
1379 1389
1380static void qeth_init_tokens(struct qeth_card *card) 1390static void qeth_init_tokens(struct qeth_card *card)
@@ -2573,8 +2583,8 @@ int qeth_query_setadapterparms(struct qeth_card *card)
2573} 2583}
2574EXPORT_SYMBOL_GPL(qeth_query_setadapterparms); 2584EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
2575 2585
2576int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error, 2586int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
2577 const char *dbftext) 2587 unsigned int qdio_error, const char *dbftext)
2578{ 2588{
2579 if (qdio_error) { 2589 if (qdio_error) {
2580 QETH_DBF_TEXT(TRACE, 2, dbftext); 2590 QETH_DBF_TEXT(TRACE, 2, dbftext);
@@ -2584,7 +2594,11 @@ int qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
2584 QETH_DBF_TEXT_(QERR, 2, " F14=%02X", 2594 QETH_DBF_TEXT_(QERR, 2, " F14=%02X",
2585 buf->element[14].flags & 0xff); 2595 buf->element[14].flags & 0xff);
2586 QETH_DBF_TEXT_(QERR, 2, " qerr=%X", qdio_error); 2596 QETH_DBF_TEXT_(QERR, 2, " qerr=%X", qdio_error);
2587 return 1; 2597 if ((buf->element[15].flags & 0xff) == 0x12) {
2598 card->stats.rx_dropped++;
2599 return 0;
2600 } else
2601 return 1;
2588 } 2602 }
2589 return 0; 2603 return 0;
2590} 2604}
@@ -2667,7 +2681,7 @@ static int qeth_handle_send_error(struct qeth_card *card,
2667 qdio_err = 1; 2681 qdio_err = 1;
2668 } 2682 }
2669 } 2683 }
2670 qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr"); 2684 qeth_check_qdio_errors(card, buffer->buffer, qdio_err, "qouterr");
2671 2685
2672 if (!qdio_err) 2686 if (!qdio_err)
2673 return QETH_SEND_ERROR_NONE; 2687 return QETH_SEND_ERROR_NONE;
@@ -3509,6 +3523,7 @@ void qeth_tx_timeout(struct net_device *dev)
3509{ 3523{
3510 struct qeth_card *card; 3524 struct qeth_card *card;
3511 3525
3526 QETH_DBF_TEXT(TRACE, 4, "txtimeo");
3512 card = dev->ml_priv; 3527 card = dev->ml_priv;
3513 card->stats.tx_errors++; 3528 card->stats.tx_errors++;
3514 qeth_schedule_recovery(card); 3529 qeth_schedule_recovery(card);
@@ -3790,9 +3805,6 @@ static int qeth_qdio_establish(struct qeth_card *card)
3790 init_data.input_handler = card->discipline.input_handler; 3805 init_data.input_handler = card->discipline.input_handler;
3791 init_data.output_handler = card->discipline.output_handler; 3806 init_data.output_handler = card->discipline.output_handler;
3792 init_data.int_parm = (unsigned long) card; 3807 init_data.int_parm = (unsigned long) card;
3793 init_data.flags = QDIO_INBOUND_0COPY_SBALS |
3794 QDIO_OUTBOUND_0COPY_SBALS |
3795 QDIO_USE_OUTBOUND_PCIS;
3796 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; 3808 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
3797 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; 3809 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
3798 3810
@@ -3847,9 +3859,7 @@ static int qeth_core_driver_group(const char *buf, struct device *root_dev,
3847 3859
3848int qeth_core_hardsetup_card(struct qeth_card *card) 3860int qeth_core_hardsetup_card(struct qeth_card *card)
3849{ 3861{
3850 struct qdio_ssqd_desc *ssqd;
3851 int retries = 0; 3862 int retries = 0;
3852 int mpno = 0;
3853 int rc; 3863 int rc;
3854 3864
3855 QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); 3865 QETH_DBF_TEXT(SETUP, 2, "hrdsetup");
@@ -3882,31 +3892,6 @@ retriable:
3882 else 3892 else
3883 goto retry; 3893 goto retry;
3884 } 3894 }
3885
3886 rc = qeth_get_unitaddr(card);
3887 if (rc) {
3888 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
3889 return rc;
3890 }
3891
3892 ssqd = kmalloc(sizeof(struct qdio_ssqd_desc), GFP_KERNEL);
3893 if (!ssqd) {
3894 rc = -ENOMEM;
3895 goto out;
3896 }
3897 rc = qdio_get_ssqd_desc(CARD_DDEV(card), ssqd);
3898 if (rc == 0)
3899 mpno = ssqd->pcnt;
3900 kfree(ssqd);
3901
3902 if (mpno)
3903 mpno = min(mpno - 1, QETH_MAX_PORTNO);
3904 if (card->info.portno > mpno) {
3905 QETH_DBF_MESSAGE(2, "Device %s does not offer port number %d"
3906 "\n.", CARD_BUS_ID(card), card->info.portno);
3907 rc = -ENODEV;
3908 goto out;
3909 }
3910 qeth_init_tokens(card); 3895 qeth_init_tokens(card);
3911 qeth_init_func_level(card); 3896 qeth_init_func_level(card);
3912 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb); 3897 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
@@ -3990,7 +3975,7 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
3990 struct qdio_buffer_element *element = *__element; 3975 struct qdio_buffer_element *element = *__element;
3991 int offset = *__offset; 3976 int offset = *__offset;
3992 struct sk_buff *skb = NULL; 3977 struct sk_buff *skb = NULL;
3993 int skb_len; 3978 int skb_len = 0;
3994 void *data_ptr; 3979 void *data_ptr;
3995 int data_len; 3980 int data_len;
3996 int headroom = 0; 3981 int headroom = 0;
@@ -4009,20 +3994,24 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
4009 *hdr = element->addr + offset; 3994 *hdr = element->addr + offset;
4010 3995
4011 offset += sizeof(struct qeth_hdr); 3996 offset += sizeof(struct qeth_hdr);
4012 if (card->options.layer2) { 3997 switch ((*hdr)->hdr.l2.id) {
4013 if (card->info.type == QETH_CARD_TYPE_OSN) { 3998 case QETH_HEADER_TYPE_LAYER2:
4014 skb_len = (*hdr)->hdr.osn.pdu_length; 3999 skb_len = (*hdr)->hdr.l2.pkt_length;
4015 headroom = sizeof(struct qeth_hdr); 4000 break;
4016 } else { 4001 case QETH_HEADER_TYPE_LAYER3:
4017 skb_len = (*hdr)->hdr.l2.pkt_length;
4018 }
4019 } else {
4020 skb_len = (*hdr)->hdr.l3.length; 4002 skb_len = (*hdr)->hdr.l3.length;
4021 if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || 4003 if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
4022 (card->info.link_type == QETH_LINK_TYPE_HSTR)) 4004 (card->info.link_type == QETH_LINK_TYPE_HSTR))
4023 headroom = TR_HLEN; 4005 headroom = TR_HLEN;
4024 else 4006 else
4025 headroom = ETH_HLEN; 4007 headroom = ETH_HLEN;
4008 break;
4009 case QETH_HEADER_TYPE_OSN:
4010 skb_len = (*hdr)->hdr.osn.pdu_length;
4011 headroom = sizeof(struct qeth_hdr);
4012 break;
4013 default:
4014 break;
4026 } 4015 }
4027 4016
4028 if (!skb_len) 4017 if (!skb_len)
@@ -4177,6 +4166,41 @@ void qeth_core_free_discipline(struct qeth_card *card)
4177 card->discipline.ccwgdriver = NULL; 4166 card->discipline.ccwgdriver = NULL;
4178} 4167}
4179 4168
4169static void qeth_determine_capabilities(struct qeth_card *card)
4170{
4171 int rc;
4172 int length;
4173 char *prcd;
4174
4175 QETH_DBF_TEXT(SETUP, 2, "detcapab");
4176 rc = ccw_device_set_online(CARD_DDEV(card));
4177 if (rc) {
4178 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
4179 goto out;
4180 }
4181
4182
4183 rc = qeth_read_conf_data(card, (void **) &prcd, &length);
4184 if (rc) {
4185 QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n",
4186 dev_name(&card->gdev->dev), rc);
4187 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
4188 goto out_offline;
4189 }
4190 qeth_configure_unitaddr(card, prcd);
4191 qeth_configure_blkt_default(card, prcd);
4192 kfree(prcd);
4193
4194 rc = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
4195 if (rc)
4196 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
4197
4198out_offline:
4199 ccw_device_set_offline(CARD_DDEV(card));
4200out:
4201 return;
4202}
4203
4180static int qeth_core_probe_device(struct ccwgroup_device *gdev) 4204static int qeth_core_probe_device(struct ccwgroup_device *gdev)
4181{ 4205{
4182 struct qeth_card *card; 4206 struct qeth_card *card;
@@ -4242,6 +4266,8 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
4242 write_lock_irqsave(&qeth_core_card_list.rwlock, flags); 4266 write_lock_irqsave(&qeth_core_card_list.rwlock, flags);
4243 list_add_tail(&card->list, &qeth_core_card_list.list); 4267 list_add_tail(&card->list, &qeth_core_card_list.list);
4244 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags); 4268 write_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
4269
4270 qeth_determine_capabilities(card);
4245 return 0; 4271 return 0;
4246 4272
4247err_card: 4273err_card:
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 1ba51152f667..104a3351e02b 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -156,6 +156,8 @@ enum qeth_ipa_return_codes {
156 IPA_RC_IP_TABLE_FULL = 0x0002, 156 IPA_RC_IP_TABLE_FULL = 0x0002,
157 IPA_RC_UNKNOWN_ERROR = 0x0003, 157 IPA_RC_UNKNOWN_ERROR = 0x0003,
158 IPA_RC_UNSUPPORTED_COMMAND = 0x0004, 158 IPA_RC_UNSUPPORTED_COMMAND = 0x0004,
159 IPA_RC_TRACE_ALREADY_ACTIVE = 0x0005,
160 IPA_RC_INVALID_FORMAT = 0x0006,
159 IPA_RC_DUP_IPV6_REMOTE = 0x0008, 161 IPA_RC_DUP_IPV6_REMOTE = 0x0008,
160 IPA_RC_DUP_IPV6_HOME = 0x0010, 162 IPA_RC_DUP_IPV6_HOME = 0x0010,
161 IPA_RC_UNREGISTERED_ADDR = 0x0011, 163 IPA_RC_UNREGISTERED_ADDR = 0x0011,
@@ -196,6 +198,11 @@ enum qeth_ipa_return_codes {
196 IPA_RC_INVALID_IP_VERSION2 = 0xf001, 198 IPA_RC_INVALID_IP_VERSION2 = 0xf001,
197 IPA_RC_FFFF = 0xffff 199 IPA_RC_FFFF = 0xffff
198}; 200};
201/* for DELIP */
202#define IPA_RC_IP_ADDRESS_NOT_DEFINED IPA_RC_PRIMARY_ALREADY_DEFINED
203/* for SET_DIAGNOSTIC_ASSIST */
204#define IPA_RC_INVALID_SUBCMD IPA_RC_IP_TABLE_FULL
205#define IPA_RC_HARDWARE_AUTH_ERROR IPA_RC_UNKNOWN_ERROR
199 206
200/* IPA function flags; each flag marks availability of respective function */ 207/* IPA function flags; each flag marks availability of respective function */
201enum qeth_ipa_funcs { 208enum qeth_ipa_funcs {
@@ -246,6 +253,7 @@ enum qeth_ipa_setadp_cmd {
246 IPA_SETADP_SET_SNMP_CONTROL = 0x00000200L, 253 IPA_SETADP_SET_SNMP_CONTROL = 0x00000200L,
247 IPA_SETADP_QUERY_CARD_INFO = 0x00000400L, 254 IPA_SETADP_QUERY_CARD_INFO = 0x00000400L,
248 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L, 255 IPA_SETADP_SET_PROMISC_MODE = 0x00000800L,
256 IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L,
249 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L, 257 IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L,
250}; 258};
251enum qeth_ipa_mac_ops { 259enum qeth_ipa_mac_ops {
@@ -424,6 +432,40 @@ struct qeth_create_destroy_address {
424 __u8 unique_id[8]; 432 __u8 unique_id[8];
425} __attribute__ ((packed)); 433} __attribute__ ((packed));
426 434
435/* SET DIAGNOSTIC ASSIST IPA Command: *************************************/
436
437enum qeth_diags_cmds {
438 QETH_DIAGS_CMD_QUERY = 0x0001,
439 QETH_DIAGS_CMD_TRAP = 0x0002,
440 QETH_DIAGS_CMD_TRACE = 0x0004,
441 QETH_DIAGS_CMD_NOLOG = 0x0008,
442 QETH_DIAGS_CMD_DUMP = 0x0010,
443};
444
445enum qeth_diags_trace_types {
446 QETH_DIAGS_TYPE_HIPERSOCKET = 0x02,
447};
448
449enum qeth_diags_trace_cmds {
450 QETH_DIAGS_CMD_TRACE_ENABLE = 0x0001,
451 QETH_DIAGS_CMD_TRACE_DISABLE = 0x0002,
452 QETH_DIAGS_CMD_TRACE_MODIFY = 0x0004,
453 QETH_DIAGS_CMD_TRACE_REPLACE = 0x0008,
454 QETH_DIAGS_CMD_TRACE_QUERY = 0x0010,
455};
456
457struct qeth_ipacmd_diagass {
458 __u32 host_tod2;
459 __u32:32;
460 __u16 subcmd_len;
461 __u16:16;
462 __u32 subcmd;
463 __u8 type;
464 __u8 action;
465 __u16 options;
466 __u32:32;
467} __attribute__ ((packed));
468
427/* Header for each IPA command */ 469/* Header for each IPA command */
428struct qeth_ipacmd_hdr { 470struct qeth_ipacmd_hdr {
429 __u8 command; 471 __u8 command;
@@ -452,6 +494,7 @@ struct qeth_ipa_cmd {
452 struct qeth_create_destroy_address create_destroy_addr; 494 struct qeth_create_destroy_address create_destroy_addr;
453 struct qeth_ipacmd_setadpparms setadapterparms; 495 struct qeth_ipacmd_setadpparms setadapterparms;
454 struct qeth_set_routing setrtg; 496 struct qeth_set_routing setrtg;
497 struct qeth_ipacmd_diagass diagass;
455 } data; 498 } data;
456} __attribute__ ((packed)); 499} __attribute__ ((packed));
457 500
@@ -469,7 +512,6 @@ enum qeth_ipa_arp_return_codes {
469 QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008, 512 QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008,
470}; 513};
471 514
472
473extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc); 515extern char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
474extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd); 516extern char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
475 517
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 9ff2b36fdc43..88ae4357136a 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -118,7 +118,7 @@ static ssize_t qeth_dev_portno_store(struct device *dev,
118{ 118{
119 struct qeth_card *card = dev_get_drvdata(dev); 119 struct qeth_card *card = dev_get_drvdata(dev);
120 char *tmp; 120 char *tmp;
121 unsigned int portno; 121 unsigned int portno, limit;
122 122
123 if (!card) 123 if (!card)
124 return -EINVAL; 124 return -EINVAL;
@@ -128,9 +128,11 @@ static ssize_t qeth_dev_portno_store(struct device *dev,
128 return -EPERM; 128 return -EPERM;
129 129
130 portno = simple_strtoul(buf, &tmp, 16); 130 portno = simple_strtoul(buf, &tmp, 16);
131 if (portno > QETH_MAX_PORTNO) { 131 if (portno > QETH_MAX_PORTNO)
132 return -EINVAL;
133 limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);
134 if (portno > limit)
132 return -EINVAL; 135 return -EINVAL;
133 }
134 136
135 card->info.portno = portno; 137 card->info.portno = portno;
136 return count; 138 return count;
@@ -537,7 +539,7 @@ static ssize_t qeth_dev_blkt_total_store(struct device *dev,
537 struct qeth_card *card = dev_get_drvdata(dev); 539 struct qeth_card *card = dev_get_drvdata(dev);
538 540
539 return qeth_dev_blkt_store(card, buf, count, 541 return qeth_dev_blkt_store(card, buf, count,
540 &card->info.blkt.time_total, 1000); 542 &card->info.blkt.time_total, 5000);
541} 543}
542 544
543 545
@@ -559,7 +561,7 @@ static ssize_t qeth_dev_blkt_inter_store(struct device *dev,
559 struct qeth_card *card = dev_get_drvdata(dev); 561 struct qeth_card *card = dev_get_drvdata(dev);
560 562
561 return qeth_dev_blkt_store(card, buf, count, 563 return qeth_dev_blkt_store(card, buf, count,
562 &card->info.blkt.inter_packet, 100); 564 &card->info.blkt.inter_packet, 1000);
563} 565}
564 566
565static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show, 567static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
@@ -580,7 +582,7 @@ static ssize_t qeth_dev_blkt_inter_jumbo_store(struct device *dev,
580 struct qeth_card *card = dev_get_drvdata(dev); 582 struct qeth_card *card = dev_get_drvdata(dev);
581 583
582 return qeth_dev_blkt_store(card, buf, count, 584 return qeth_dev_blkt_store(card, buf, count,
583 &card->info.blkt.inter_packet_jumbo, 100); 585 &card->info.blkt.inter_packet_jumbo, 1000);
584} 586}
585 587
586static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show, 588static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 0b763396d5d1..51fde6f2e0b8 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -486,22 +486,14 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card,
486 case IPA_RC_L2_DUP_MAC: 486 case IPA_RC_L2_DUP_MAC:
487 case IPA_RC_L2_DUP_LAYER3_MAC: 487 case IPA_RC_L2_DUP_LAYER3_MAC:
488 dev_warn(&card->gdev->dev, 488 dev_warn(&card->gdev->dev,
489 "MAC address " 489 "MAC address %pM already exists\n",
490 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " 490 card->dev->dev_addr);
491 "already exists\n",
492 card->dev->dev_addr[0], card->dev->dev_addr[1],
493 card->dev->dev_addr[2], card->dev->dev_addr[3],
494 card->dev->dev_addr[4], card->dev->dev_addr[5]);
495 break; 491 break;
496 case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: 492 case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP:
497 case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: 493 case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP:
498 dev_warn(&card->gdev->dev, 494 dev_warn(&card->gdev->dev,
499 "MAC address " 495 "MAC address %pM is not authorized\n",
500 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " 496 card->dev->dev_addr);
501 "is not authorized\n",
502 card->dev->dev_addr[0], card->dev->dev_addr[1],
503 card->dev->dev_addr[2], card->dev->dev_addr[3],
504 card->dev->dev_addr[4], card->dev->dev_addr[5]);
505 break; 497 break;
506 default: 498 default:
507 break; 499 break;
@@ -512,12 +504,8 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card,
512 memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac, 504 memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac,
513 OSA_ADDR_LEN); 505 OSA_ADDR_LEN);
514 dev_info(&card->gdev->dev, 506 dev_info(&card->gdev->dev,
515 "MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " 507 "MAC address %pM successfully registered on device %s\n",
516 "successfully registered on device %s\n", 508 card->dev->dev_addr, card->dev->name);
517 card->dev->dev_addr[0], card->dev->dev_addr[1],
518 card->dev->dev_addr[2], card->dev->dev_addr[3],
519 card->dev->dev_addr[4], card->dev->dev_addr[5],
520 card->dev->name);
521 } 509 }
522 return 0; 510 return 0;
523} 511}
@@ -634,7 +622,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
634 for (dm = dev->mc_list; dm; dm = dm->next) 622 for (dm = dev->mc_list; dm; dm = dm->next)
635 qeth_l2_add_mc(card, dm->da_addr, 0); 623 qeth_l2_add_mc(card, dm->da_addr, 0);
636 624
637 list_for_each_entry(ha, &dev->uc.list, list) 625 netdev_for_each_uc_addr(ha, dev)
638 qeth_l2_add_mc(card, ha->addr, 1); 626 qeth_l2_add_mc(card, ha->addr, 1);
639 627
640 spin_unlock_bh(&card->mclock); 628 spin_unlock_bh(&card->mclock);
@@ -781,7 +769,8 @@ static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev,
781 index = i % QDIO_MAX_BUFFERS_PER_Q; 769 index = i % QDIO_MAX_BUFFERS_PER_Q;
782 buffer = &card->qdio.in_q->bufs[index]; 770 buffer = &card->qdio.in_q->bufs[index];
783 if (!(qdio_err && 771 if (!(qdio_err &&
784 qeth_check_qdio_errors(buffer->buffer, qdio_err, "qinerr"))) 772 qeth_check_qdio_errors(card, buffer->buffer, qdio_err,
773 "qinerr")))
785 qeth_l2_process_inbound_buffer(card, buffer, index); 774 qeth_l2_process_inbound_buffer(card, buffer, index);
786 /* clear buffer and give back to hardware */ 775 /* clear buffer and give back to hardware */
787 qeth_put_buffer_pool_entry(card, buffer->pool_entry); 776 qeth_put_buffer_pool_entry(card, buffer->pool_entry);
@@ -938,7 +927,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
938 QETH_DBF_TEXT(SETUP, 2, "setonlin"); 927 QETH_DBF_TEXT(SETUP, 2, "setonlin");
939 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 928 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
940 929
941 qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
942 recover_flag = card->state; 930 recover_flag = card->state;
943 rc = qeth_core_hardsetup_card(card); 931 rc = qeth_core_hardsetup_card(card);
944 if (rc) { 932 if (rc) {
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h
index 321988fa9f7d..8447d233d0b3 100644
--- a/drivers/s390/net/qeth_l3.h
+++ b/drivers/s390/net/qeth_l3.h
@@ -13,6 +13,8 @@
13 13
14#include "qeth_core.h" 14#include "qeth_core.h"
15 15
16#define QETH_SNIFF_AVAIL 0x0008
17
16struct qeth_ipaddr { 18struct qeth_ipaddr {
17 struct list_head entry; 19 struct list_head entry;
18 enum qeth_ip_types type; 20 enum qeth_ip_types type;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index fd1b6ed3721f..5475834ab916 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -242,6 +242,8 @@ static int __qeth_l3_insert_ip_todo(struct qeth_card *card,
242 struct qeth_ipaddr *tmp, *t; 242 struct qeth_ipaddr *tmp, *t;
243 int found = 0; 243 int found = 0;
244 244
245 if (card->options.sniffer)
246 return 0;
245 list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) { 247 list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) {
246 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) && 248 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
247 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC)) 249 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
@@ -457,6 +459,8 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
457 QETH_DBF_TEXT(TRACE, 2, "sdiplist"); 459 QETH_DBF_TEXT(TRACE, 2, "sdiplist");
458 QETH_DBF_HEX(TRACE, 2, &card, sizeof(void *)); 460 QETH_DBF_HEX(TRACE, 2, &card, sizeof(void *));
459 461
462 if (card->options.sniffer)
463 return;
460 spin_lock_irqsave(&card->ip_lock, flags); 464 spin_lock_irqsave(&card->ip_lock, flags);
461 tbd_list = card->ip_tbd_list; 465 tbd_list = card->ip_tbd_list;
462 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC); 466 card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
@@ -495,7 +499,7 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card)
495 spin_unlock_irqrestore(&card->ip_lock, flags); 499 spin_unlock_irqrestore(&card->ip_lock, flags);
496 rc = qeth_l3_deregister_addr_entry(card, addr); 500 rc = qeth_l3_deregister_addr_entry(card, addr);
497 spin_lock_irqsave(&card->ip_lock, flags); 501 spin_lock_irqsave(&card->ip_lock, flags);
498 if (!rc || (rc == IPA_RC_PRIMARY_ALREADY_DEFINED)) 502 if (!rc || (rc == IPA_RC_IP_ADDRESS_NOT_DEFINED))
499 kfree(addr); 503 kfree(addr);
500 else 504 else
501 list_add_tail(&addr->entry, &card->ip_list); 505 list_add_tail(&addr->entry, &card->ip_list);
@@ -513,6 +517,8 @@ static void qeth_l3_clear_ip_list(struct qeth_card *card, int clean,
513 unsigned long flags; 517 unsigned long flags;
514 518
515 QETH_DBF_TEXT(TRACE, 4, "clearip"); 519 QETH_DBF_TEXT(TRACE, 4, "clearip");
520 if (recover && card->options.sniffer)
521 return;
516 spin_lock_irqsave(&card->ip_lock, flags); 522 spin_lock_irqsave(&card->ip_lock, flags);
517 /* clear todo list */ 523 /* clear todo list */
518 list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) { 524 list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry) {
@@ -1674,6 +1680,76 @@ static int qeth_l3_get_unique_id(struct qeth_card *card)
1674 return rc; 1680 return rc;
1675} 1681}
1676 1682
1683static int
1684qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
1685 unsigned long data)
1686{
1687 struct qeth_ipa_cmd *cmd;
1688 __u16 rc;
1689
1690 QETH_DBF_TEXT(SETUP, 2, "diastrcb");
1691
1692 cmd = (struct qeth_ipa_cmd *)data;
1693 rc = cmd->hdr.return_code;
1694 if (rc) {
1695 QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc);
1696 if (cmd->data.diagass.action == QETH_DIAGS_CMD_TRACE_ENABLE) {
1697 switch (rc) {
1698 case IPA_RC_HARDWARE_AUTH_ERROR:
1699 dev_warn(&card->gdev->dev, "The device is not "
1700 "authorized to run as a HiperSockets "
1701 "network traffic analyzer\n");
1702 break;
1703 case IPA_RC_TRACE_ALREADY_ACTIVE:
1704 dev_warn(&card->gdev->dev, "A HiperSockets "
1705 "network traffic analyzer is already "
1706 "active in the HiperSockets LAN\n");
1707 break;
1708 default:
1709 break;
1710 }
1711 }
1712 return 0;
1713 }
1714
1715 switch (cmd->data.diagass.action) {
1716 case QETH_DIAGS_CMD_TRACE_QUERY:
1717 break;
1718 case QETH_DIAGS_CMD_TRACE_DISABLE:
1719 card->info.promisc_mode = SET_PROMISC_MODE_OFF;
1720 dev_info(&card->gdev->dev, "The HiperSockets network traffic "
1721 "analyzer is deactivated\n");
1722 break;
1723 case QETH_DIAGS_CMD_TRACE_ENABLE:
1724 card->info.promisc_mode = SET_PROMISC_MODE_ON;
1725 dev_info(&card->gdev->dev, "The HiperSockets network traffic "
1726 "analyzer is activated\n");
1727 break;
1728 default:
1729 QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
1730 cmd->data.diagass.action, QETH_CARD_IFNAME(card));
1731 }
1732
1733 return 0;
1734}
1735
1736static int
1737qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd)
1738{
1739 struct qeth_cmd_buffer *iob;
1740 struct qeth_ipa_cmd *cmd;
1741
1742 QETH_DBF_TEXT(SETUP, 2, "diagtrac");
1743
1744 iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
1745 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
1746 cmd->data.diagass.subcmd_len = 16;
1747 cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE;
1748 cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET;
1749 cmd->data.diagass.action = diags_cmd;
1750 return qeth_send_ipa_cmd(card, iob, qeth_diags_trace_cb, NULL);
1751}
1752
1677static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac, 1753static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac,
1678 struct net_device *dev) 1754 struct net_device *dev)
1679{ 1755{
@@ -1951,7 +2027,10 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
1951 case QETH_CAST_ANYCAST: 2027 case QETH_CAST_ANYCAST:
1952 case QETH_CAST_NOCAST: 2028 case QETH_CAST_NOCAST:
1953 default: 2029 default:
1954 skb->pkt_type = PACKET_HOST; 2030 if (card->options.sniffer)
2031 skb->pkt_type = PACKET_OTHERHOST;
2032 else
2033 skb->pkt_type = PACKET_HOST;
1955 memcpy(tg_addr, card->dev->dev_addr, 2034 memcpy(tg_addr, card->dev->dev_addr,
1956 card->dev->addr_len); 2035 card->dev->addr_len);
1957 } 2036 }
@@ -2007,7 +2086,6 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
2007 int offset; 2086 int offset;
2008 __u16 vlan_tag = 0; 2087 __u16 vlan_tag = 0;
2009 unsigned int len; 2088 unsigned int len;
2010
2011 /* get first element of current buffer */ 2089 /* get first element of current buffer */
2012 element = (struct qdio_buffer_element *)&buf->buffer->element[0]; 2090 element = (struct qdio_buffer_element *)&buf->buffer->element[0];
2013 offset = 0; 2091 offset = 0;
@@ -2026,7 +2104,7 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
2026 case QETH_HEADER_TYPE_LAYER3: 2104 case QETH_HEADER_TYPE_LAYER3:
2027 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr); 2105 vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr);
2028 len = skb->len; 2106 len = skb->len;
2029 if (vlan_tag) 2107 if (vlan_tag && !card->options.sniffer)
2030 if (card->vlangrp) 2108 if (card->vlangrp)
2031 vlan_hwaccel_rx(skb, card->vlangrp, 2109 vlan_hwaccel_rx(skb, card->vlangrp,
2032 vlan_tag); 2110 vlan_tag);
@@ -2037,6 +2115,16 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
2037 else 2115 else
2038 netif_rx(skb); 2116 netif_rx(skb);
2039 break; 2117 break;
2118 case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
2119 skb->pkt_type = PACKET_HOST;
2120 skb->protocol = eth_type_trans(skb, skb->dev);
2121 if (card->options.checksum_type == NO_CHECKSUMMING)
2122 skb->ip_summed = CHECKSUM_UNNECESSARY;
2123 else
2124 skb->ip_summed = CHECKSUM_NONE;
2125 len = skb->len;
2126 netif_receive_skb(skb);
2127 break;
2040 default: 2128 default:
2041 dev_kfree_skb_any(skb); 2129 dev_kfree_skb_any(skb);
2042 QETH_DBF_TEXT(TRACE, 3, "inbunkno"); 2130 QETH_DBF_TEXT(TRACE, 3, "inbunkno");
@@ -2118,6 +2206,9 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
2118 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 2206 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
2119 2207
2120 qeth_set_allowed_threads(card, 0, 1); 2208 qeth_set_allowed_threads(card, 0, 1);
2209 if (card->options.sniffer &&
2210 (card->info.promisc_mode == SET_PROMISC_MODE_ON))
2211 qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
2121 if (card->read.state == CH_STATE_UP && 2212 if (card->read.state == CH_STATE_UP &&
2122 card->write.state == CH_STATE_UP && 2213 card->write.state == CH_STATE_UP &&
2123 (card->state == CARD_STATE_UP)) { 2214 (card->state == CARD_STATE_UP)) {
@@ -2162,6 +2253,36 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
2162 return rc; 2253 return rc;
2163} 2254}
2164 2255
2256/*
2257 * test for and Switch promiscuous mode (on or off)
2258 * either for guestlan or HiperSocket Sniffer
2259 */
2260static void
2261qeth_l3_handle_promisc_mode(struct qeth_card *card)
2262{
2263 struct net_device *dev = card->dev;
2264
2265 if (((dev->flags & IFF_PROMISC) &&
2266 (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
2267 (!(dev->flags & IFF_PROMISC) &&
2268 (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
2269 return;
2270
2271 if (card->info.guestlan) { /* Guestlan trace */
2272 if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
2273 qeth_setadp_promisc_mode(card);
2274 } else if (card->options.sniffer && /* HiperSockets trace */
2275 qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) {
2276 if (dev->flags & IFF_PROMISC) {
2277 QETH_DBF_TEXT(TRACE, 3, "+promisc");
2278 qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_ENABLE);
2279 } else {
2280 QETH_DBF_TEXT(TRACE, 3, "-promisc");
2281 qeth_diags_trace(card, QETH_DIAGS_CMD_TRACE_DISABLE);
2282 }
2283 }
2284}
2285
2165static void qeth_l3_set_multicast_list(struct net_device *dev) 2286static void qeth_l3_set_multicast_list(struct net_device *dev)
2166{ 2287{
2167 struct qeth_card *card = dev->ml_priv; 2288 struct qeth_card *card = dev->ml_priv;
@@ -2170,15 +2291,17 @@ static void qeth_l3_set_multicast_list(struct net_device *dev)
2170 if (qeth_threads_running(card, QETH_RECOVER_THREAD) && 2291 if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
2171 (card->state != CARD_STATE_UP)) 2292 (card->state != CARD_STATE_UP))
2172 return; 2293 return;
2173 qeth_l3_delete_mc_addresses(card); 2294 if (!card->options.sniffer) {
2174 qeth_l3_add_multicast_ipv4(card); 2295 qeth_l3_delete_mc_addresses(card);
2296 qeth_l3_add_multicast_ipv4(card);
2175#ifdef CONFIG_QETH_IPV6 2297#ifdef CONFIG_QETH_IPV6
2176 qeth_l3_add_multicast_ipv6(card); 2298 qeth_l3_add_multicast_ipv6(card);
2177#endif 2299#endif
2178 qeth_l3_set_ip_addr_list(card); 2300 qeth_l3_set_ip_addr_list(card);
2179 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) 2301 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
2180 return; 2302 return;
2181 qeth_setadp_promisc_mode(card); 2303 }
2304 qeth_l3_handle_promisc_mode(card);
2182} 2305}
2183 2306
2184static const char *qeth_l3_arp_get_error_cause(int *rc) 2307static const char *qeth_l3_arp_get_error_cause(int *rc)
@@ -2778,8 +2901,9 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
2778 int nr_frags; 2901 int nr_frags;
2779 2902
2780 if ((card->info.type == QETH_CARD_TYPE_IQD) && 2903 if ((card->info.type == QETH_CARD_TYPE_IQD) &&
2781 (skb->protocol != htons(ETH_P_IPV6)) && 2904 (((skb->protocol != htons(ETH_P_IPV6)) &&
2782 (skb->protocol != htons(ETH_P_IP))) 2905 (skb->protocol != htons(ETH_P_IP))) ||
2906 card->options.sniffer))
2783 goto tx_drop; 2907 goto tx_drop;
2784 2908
2785 if ((card->state != CARD_STATE_UP) || !card->lan_online) { 2909 if ((card->state != CARD_STATE_UP) || !card->lan_online) {
@@ -3155,7 +3279,7 @@ static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev,
3155 index = i % QDIO_MAX_BUFFERS_PER_Q; 3279 index = i % QDIO_MAX_BUFFERS_PER_Q;
3156 buffer = &card->qdio.in_q->bufs[index]; 3280 buffer = &card->qdio.in_q->bufs[index];
3157 if (!(qdio_err && 3281 if (!(qdio_err &&
3158 qeth_check_qdio_errors(buffer->buffer, 3282 qeth_check_qdio_errors(card, buffer->buffer,
3159 qdio_err, "qinerr"))) 3283 qdio_err, "qinerr")))
3160 qeth_l3_process_inbound_buffer(card, buffer, index); 3284 qeth_l3_process_inbound_buffer(card, buffer, index);
3161 /* clear buffer and give back to hardware */ 3285 /* clear buffer and give back to hardware */
@@ -3214,8 +3338,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
3214 QETH_DBF_TEXT(SETUP, 2, "setonlin"); 3338 QETH_DBF_TEXT(SETUP, 2, "setonlin");
3215 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); 3339 QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
3216 3340
3217 qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
3218
3219 recover_flag = card->state; 3341 recover_flag = card->state;
3220 rc = qeth_core_hardsetup_card(card); 3342 rc = qeth_core_hardsetup_card(card);
3221 if (rc) { 3343 if (rc) {
@@ -3250,20 +3372,22 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
3250 goto out_remove; 3372 goto out_remove;
3251 } else 3373 } else
3252 card->lan_online = 1; 3374 card->lan_online = 1;
3253 qeth_l3_set_large_send(card, card->options.large_send);
3254 3375
3255 rc = qeth_l3_setadapter_parms(card); 3376 rc = qeth_l3_setadapter_parms(card);
3256 if (rc) 3377 if (rc)
3257 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); 3378 QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
3258 rc = qeth_l3_start_ipassists(card); 3379 if (!card->options.sniffer) {
3259 if (rc) 3380 rc = qeth_l3_start_ipassists(card);
3260 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); 3381 if (rc)
3261 rc = qeth_l3_setrouting_v4(card); 3382 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
3262 if (rc) 3383 qeth_l3_set_large_send(card, card->options.large_send);
3263 QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); 3384 rc = qeth_l3_setrouting_v4(card);
3264 rc = qeth_l3_setrouting_v6(card); 3385 if (rc)
3265 if (rc) 3386 QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc);
3266 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); 3387 rc = qeth_l3_setrouting_v6(card);
3388 if (rc)
3389 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
3390 }
3267 netif_tx_disable(card->dev); 3391 netif_tx_disable(card->dev);
3268 3392
3269 rc = qeth_init_qdio_queues(card); 3393 rc = qeth_init_qdio_queues(card);
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index 3360b0941aa1..3f08b11274ae 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -319,6 +319,61 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
319static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show, 319static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
320 qeth_l3_dev_checksum_store); 320 qeth_l3_dev_checksum_store);
321 321
322static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
323 struct device_attribute *attr, char *buf)
324{
325 struct qeth_card *card = dev_get_drvdata(dev);
326
327 if (!card)
328 return -EINVAL;
329
330 return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
331}
332
333static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
334 struct device_attribute *attr, const char *buf, size_t count)
335{
336 struct qeth_card *card = dev_get_drvdata(dev);
337 int ret;
338 unsigned long i;
339
340 if (!card)
341 return -EINVAL;
342
343 if (card->info.type != QETH_CARD_TYPE_IQD)
344 return -EPERM;
345
346 if ((card->state != CARD_STATE_DOWN) &&
347 (card->state != CARD_STATE_RECOVER))
348 return -EPERM;
349
350 ret = strict_strtoul(buf, 16, &i);
351 if (ret)
352 return -EINVAL;
353 switch (i) {
354 case 0:
355 card->options.sniffer = i;
356 break;
357 case 1:
358 ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
359 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
360 card->options.sniffer = i;
361 if (card->qdio.init_pool.buf_count !=
362 QETH_IN_BUF_COUNT_MAX)
363 qeth_realloc_buffer_pool(card,
364 QETH_IN_BUF_COUNT_MAX);
365 break;
366 } else
367 return -EPERM;
368 default: /* fall through */
369 return -EINVAL;
370 }
371 return count;
372}
373
374static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
375 qeth_l3_dev_sniffer_store);
376
322static ssize_t qeth_l3_dev_large_send_show(struct device *dev, 377static ssize_t qeth_l3_dev_large_send_show(struct device *dev,
323 struct device_attribute *attr, char *buf) 378 struct device_attribute *attr, char *buf)
324{ 379{
@@ -373,6 +428,7 @@ static struct attribute *qeth_l3_device_attrs[] = {
373 &dev_attr_broadcast_mode.attr, 428 &dev_attr_broadcast_mode.attr,
374 &dev_attr_canonical_macaddr.attr, 429 &dev_attr_canonical_macaddr.attr,
375 &dev_attr_checksumming.attr, 430 &dev_attr_checksumming.attr,
431 &dev_attr_sniffer.attr,
376 &dev_attr_large_send.attr, 432 &dev_attr_large_send.attr,
377 NULL, 433 NULL,
378}; 434};
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 67f2485d2372..ecef1edee701 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -31,9 +31,9 @@
31 31
32struct smsg_callback { 32struct smsg_callback {
33 struct list_head list; 33 struct list_head list;
34 char *prefix; 34 const char *prefix;
35 int len; 35 int len;
36 void (*callback)(char *from, char *str); 36 void (*callback)(const char *from, char *str);
37}; 37};
38 38
39MODULE_AUTHOR 39MODULE_AUTHOR
@@ -100,8 +100,8 @@ static void smsg_message_pending(struct iucv_path *path,
100 kfree(buffer); 100 kfree(buffer);
101} 101}
102 102
103int smsg_register_callback(char *prefix, 103int smsg_register_callback(const char *prefix,
104 void (*callback)(char *from, char *str)) 104 void (*callback)(const char *from, char *str))
105{ 105{
106 struct smsg_callback *cb; 106 struct smsg_callback *cb;
107 107
@@ -117,8 +117,9 @@ int smsg_register_callback(char *prefix,
117 return 0; 117 return 0;
118} 118}
119 119
120void smsg_unregister_callback(char *prefix, 120void smsg_unregister_callback(const char *prefix,
121 void (*callback)(char *from, char *str)) 121 void (*callback)(const char *from,
122 char *str))
122{ 123{
123 struct smsg_callback *cb, *tmp; 124 struct smsg_callback *cb, *tmp;
124 125
@@ -176,7 +177,7 @@ static const struct dev_pm_ops smsg_pm_ops = {
176 177
177static struct device_driver smsg_driver = { 178static struct device_driver smsg_driver = {
178 .owner = THIS_MODULE, 179 .owner = THIS_MODULE,
179 .name = "SMSGIUCV", 180 .name = SMSGIUCV_DRV_NAME,
180 .bus = &iucv_bus, 181 .bus = &iucv_bus,
181 .pm = &smsg_pm_ops, 182 .pm = &smsg_pm_ops,
182}; 183};
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h
index 67f5d4f8378d..149a1151608d 100644
--- a/drivers/s390/net/smsgiucv.h
+++ b/drivers/s390/net/smsgiucv.h
@@ -5,6 +5,10 @@
5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
6 */ 6 */
7 7
8int smsg_register_callback(char *, void (*)(char *, char *)); 8#define SMSGIUCV_DRV_NAME "SMSGIUCV"
9void smsg_unregister_callback(char *, void (*)(char *, char *)); 9
10int smsg_register_callback(const char *,
11 void (*)(const char *, char *));
12void smsg_unregister_callback(const char *,
13 void (*)(const char *, char *));
10 14
diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c
new file mode 100644
index 000000000000..91579dc6a2b0
--- /dev/null
+++ b/drivers/s390/net/smsgiucv_app.c
@@ -0,0 +1,211 @@
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. */
41static char *sender;
42module_param(sender, charp, 0400);
43MODULE_PARM_DESC(sender, "z/VM user ID from which CP SMSGs are accepted");
44
45/* SMSG device representation */
46static struct device *smsg_app_dev;
47
48/* list element for queuing received messages for delivery */
49struct smsg_app_event {
50 struct list_head list;
51 char *buf;
52 char *envp[4];
53};
54
55/* queue for outgoing uevents */
56static LIST_HEAD(smsg_event_queue);
57static DEFINE_SPINLOCK(smsg_event_queue_lock);
58
59static void smsg_app_event_free(struct smsg_app_event *ev)
60{
61 kfree(ev->buf);
62 kfree(ev);
63}
64
65static 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
95static 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}
117static DECLARE_WORK(smsg_event_work, smsg_event_work_fn);
118
119static 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
149static 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;
190fail_put_driver:
191 put_driver(smsgiucv_drv);
192 return rc;
193}
194module_init(smsgiucv_app_init);
195
196static 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}
207module_exit(smsgiucv_app_exit);
208
209MODULE_LICENSE("GPL v2");
210MODULE_DESCRIPTION("Deliver z/VM CP SMSG as uevents");
211MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>");
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 71b97ff77cf0..6479273a3094 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -319,8 +319,6 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
319 id->input_handler = zfcp_qdio_int_resp; 319 id->input_handler = zfcp_qdio_int_resp;
320 id->output_handler = zfcp_qdio_int_req; 320 id->output_handler = zfcp_qdio_int_req;
321 id->int_parm = (unsigned long) qdio; 321 id->int_parm = (unsigned long) qdio;
322 id->flags = QDIO_INBOUND_0COPY_SBALS |
323 QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS;
324 id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal); 322 id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal);
325 id->output_sbal_addr_array = (void **) (qdio->req_q.sbal); 323 id->output_sbal_addr_array = (void **) (qdio->req_q.sbal);
326 324