aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c143
-rw-r--r--drivers/s390/block/dasd_devmap.c1
-rw-r--r--drivers/s390/block/dasd_diag.c1
-rw-r--r--drivers/s390/block/dasd_eckd.c152
-rw-r--r--drivers/s390/block/dasd_fba.c28
-rw-r--r--drivers/s390/block/dasd_int.h16
-rw-r--r--drivers/s390/block/dcssblk.c136
-rw-r--r--drivers/s390/block/xpram.c129
-rw-r--r--drivers/s390/char/con3215.c221
-rw-r--r--drivers/s390/char/con3270.c50
-rw-r--r--drivers/s390/char/fs3270.c16
-rw-r--r--drivers/s390/char/monreader.c140
-rw-r--r--drivers/s390/char/monwriter.c98
-rw-r--r--drivers/s390/char/raw3270.c100
-rw-r--r--drivers/s390/char/raw3270.h12
-rw-r--r--drivers/s390/char/sclp.c248
-rw-r--r--drivers/s390/char/sclp.h23
-rw-r--r--drivers/s390/char/sclp_cmd.c42
-rw-r--r--drivers/s390/char/sclp_con.c139
-rw-r--r--drivers/s390/char/sclp_rw.c20
-rw-r--r--drivers/s390/char/sclp_rw.h12
-rw-r--r--drivers/s390/char/sclp_vt220.c118
-rw-r--r--drivers/s390/char/tape.h3
-rw-r--r--drivers/s390/char/tape_34xx.c5
-rw-r--r--drivers/s390/char/tape_3590.c5
-rw-r--r--drivers/s390/char/tape_core.c74
-rw-r--r--drivers/s390/char/tty3270.c57
-rw-r--r--drivers/s390/char/vmlogrdr.c39
-rw-r--r--drivers/s390/char/vmur.c42
-rw-r--r--drivers/s390/char/vmwatchdog.c81
-rw-r--r--drivers/s390/cio/ccwgroup.c78
-rw-r--r--drivers/s390/cio/chsc.c3
-rw-r--r--drivers/s390/cio/chsc.h1
-rw-r--r--drivers/s390/cio/chsc_sch.c32
-rw-r--r--drivers/s390/cio/cio.c6
-rw-r--r--drivers/s390/cio/cmf.c5
-rw-r--r--drivers/s390/cio/css.c157
-rw-r--r--drivers/s390/cio/css.h10
-rw-r--r--drivers/s390/cio/device.c260
-rw-r--r--drivers/s390/cio/device.h3
-rw-r--r--drivers/s390/cio/device_fsm.c96
-rw-r--r--drivers/s390/cio/device_ops.c50
-rw-r--r--drivers/s390/cio/io_sch.h1
-rw-r--r--drivers/s390/cio/qdio_main.c46
-rw-r--r--drivers/s390/cio/qdio_perf.c12
-rw-r--r--drivers/s390/cio/qdio_perf.h10
-rw-r--r--drivers/s390/net/Kconfig14
-rw-r--r--drivers/s390/net/claw.c72
-rw-r--r--drivers/s390/net/ctcm_main.c43
-rw-r--r--drivers/s390/net/lcs.c94
-rw-r--r--drivers/s390/net/lcs.h4
-rw-r--r--drivers/s390/net/netiucv.c166
-rw-r--r--drivers/s390/net/qeth_core_main.c58
-rw-r--r--drivers/s390/net/qeth_core_mpc.c2
-rw-r--r--drivers/s390/net/qeth_core_mpc.h2
-rw-r--r--drivers/s390/net/qeth_l2_main.c88
-rw-r--r--drivers/s390/net/qeth_l3_main.c85
-rw-r--r--drivers/s390/net/smsgiucv.c63
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c33
-rw-r--r--drivers/s390/scsi/zfcp_fc.c2
60 files changed, 2926 insertions, 721 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 27a1be0cd4d4..e5b84db0aa03 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -5,8 +5,7 @@
5 * Carsten Otte <Cotte@de.ibm.com> 5 * Carsten Otte <Cotte@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Bugreports.to..: <Linux390@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com>
8 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 8 * Copyright IBM Corp. 1999, 2009
9 *
10 */ 9 */
11 10
12#define KMSG_COMPONENT "dasd" 11#define KMSG_COMPONENT "dasd"
@@ -61,6 +60,7 @@ static int dasd_flush_block_queue(struct dasd_block *);
61static void dasd_device_tasklet(struct dasd_device *); 60static void dasd_device_tasklet(struct dasd_device *);
62static void dasd_block_tasklet(struct dasd_block *); 61static void dasd_block_tasklet(struct dasd_block *);
63static void do_kick_device(struct work_struct *); 62static void do_kick_device(struct work_struct *);
63static void do_restore_device(struct work_struct *);
64static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *); 64static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *);
65static void dasd_device_timeout(unsigned long); 65static void dasd_device_timeout(unsigned long);
66static void dasd_block_timeout(unsigned long); 66static void dasd_block_timeout(unsigned long);
@@ -109,6 +109,7 @@ struct dasd_device *dasd_alloc_device(void)
109 device->timer.function = dasd_device_timeout; 109 device->timer.function = dasd_device_timeout;
110 device->timer.data = (unsigned long) device; 110 device->timer.data = (unsigned long) device;
111 INIT_WORK(&device->kick_work, do_kick_device); 111 INIT_WORK(&device->kick_work, do_kick_device);
112 INIT_WORK(&device->restore_device, do_restore_device);
112 device->state = DASD_STATE_NEW; 113 device->state = DASD_STATE_NEW;
113 device->target = DASD_STATE_NEW; 114 device->target = DASD_STATE_NEW;
114 115
@@ -512,6 +513,25 @@ void dasd_kick_device(struct dasd_device *device)
512} 513}
513 514
514/* 515/*
516 * dasd_restore_device will schedule a call do do_restore_device to the kernel
517 * event daemon.
518 */
519static void do_restore_device(struct work_struct *work)
520{
521 struct dasd_device *device = container_of(work, struct dasd_device,
522 restore_device);
523 device->cdev->drv->restore(device->cdev);
524 dasd_put_device(device);
525}
526
527void dasd_restore_device(struct dasd_device *device)
528{
529 dasd_get_device(device);
530 /* queue call to dasd_restore_device to the kernel event daemon. */
531 schedule_work(&device->restore_device);
532}
533
534/*
515 * Set the target state for a device and starts the state change. 535 * Set the target state for a device and starts the state change.
516 */ 536 */
517void dasd_set_target_state(struct dasd_device *device, int target) 537void dasd_set_target_state(struct dasd_device *device, int target)
@@ -851,8 +871,10 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
851 871
852 /* Check the cqr */ 872 /* Check the cqr */
853 rc = dasd_check_cqr(cqr); 873 rc = dasd_check_cqr(cqr);
854 if (rc) 874 if (rc) {
875 cqr->intrc = rc;
855 return rc; 876 return rc;
877 }
856 device = (struct dasd_device *) cqr->startdev; 878 device = (struct dasd_device *) cqr->startdev;
857 if (cqr->retries < 0) { 879 if (cqr->retries < 0) {
858 /* internal error 14 - start_IO run out of retries */ 880 /* internal error 14 - start_IO run out of retries */
@@ -906,6 +928,12 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
906 DBF_DEV_EVENT(DBF_DEBUG, device, "%s", 928 DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
907 "start_IO: -EIO device gone, retry"); 929 "start_IO: -EIO device gone, retry");
908 break; 930 break;
931 case -EINVAL:
932 /* most likely caused in power management context */
933 DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
934 "start_IO: -EINVAL device currently "
935 "not accessible");
936 break;
909 default: 937 default:
910 /* internal error 11 - unknown rc */ 938 /* internal error 11 - unknown rc */
911 snprintf(errorstring, ERRORLENGTH, "11 %d", rc); 939 snprintf(errorstring, ERRORLENGTH, "11 %d", rc);
@@ -915,6 +943,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
915 BUG(); 943 BUG();
916 break; 944 break;
917 } 945 }
946 cqr->intrc = rc;
918 return rc; 947 return rc;
919} 948}
920 949
@@ -1454,8 +1483,12 @@ int dasd_sleep_on(struct dasd_ccw_req *cqr)
1454 dasd_add_request_tail(cqr); 1483 dasd_add_request_tail(cqr);
1455 wait_event(generic_waitq, _wait_for_wakeup(cqr)); 1484 wait_event(generic_waitq, _wait_for_wakeup(cqr));
1456 1485
1457 /* Request status is either done or failed. */ 1486 if (cqr->status == DASD_CQR_DONE)
1458 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; 1487 rc = 0;
1488 else if (cqr->intrc)
1489 rc = cqr->intrc;
1490 else
1491 rc = -EIO;
1459 return rc; 1492 return rc;
1460} 1493}
1461 1494
@@ -1477,8 +1510,15 @@ int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr)
1477 dasd_cancel_req(cqr); 1510 dasd_cancel_req(cqr);
1478 /* wait (non-interruptible) for final status */ 1511 /* wait (non-interruptible) for final status */
1479 wait_event(generic_waitq, _wait_for_wakeup(cqr)); 1512 wait_event(generic_waitq, _wait_for_wakeup(cqr));
1513 cqr->intrc = rc;
1480 } 1514 }
1481 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; 1515
1516 if (cqr->status == DASD_CQR_DONE)
1517 rc = 0;
1518 else if (cqr->intrc)
1519 rc = cqr->intrc;
1520 else
1521 rc = -EIO;
1482 return rc; 1522 return rc;
1483} 1523}
1484 1524
@@ -1523,8 +1563,12 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
1523 1563
1524 wait_event(generic_waitq, _wait_for_wakeup(cqr)); 1564 wait_event(generic_waitq, _wait_for_wakeup(cqr));
1525 1565
1526 /* Request status is either done or failed. */ 1566 if (cqr->status == DASD_CQR_DONE)
1527 rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; 1567 rc = 0;
1568 else if (cqr->intrc)
1569 rc = cqr->intrc;
1570 else
1571 rc = -EIO;
1528 return rc; 1572 return rc;
1529} 1573}
1530 1574
@@ -2382,6 +2426,12 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
2382 case CIO_OPER: 2426 case CIO_OPER:
2383 /* FIXME: add a sanity check. */ 2427 /* FIXME: add a sanity check. */
2384 device->stopped &= ~DASD_STOPPED_DC_WAIT; 2428 device->stopped &= ~DASD_STOPPED_DC_WAIT;
2429 if (device->stopped & DASD_UNRESUMED_PM) {
2430 device->stopped &= ~DASD_UNRESUMED_PM;
2431 dasd_restore_device(device);
2432 ret = 1;
2433 break;
2434 }
2385 dasd_schedule_device_bh(device); 2435 dasd_schedule_device_bh(device);
2386 if (device->block) 2436 if (device->block)
2387 dasd_schedule_block_bh(device->block); 2437 dasd_schedule_block_bh(device->block);
@@ -2392,6 +2442,79 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
2392 return ret; 2442 return ret;
2393} 2443}
2394 2444
2445int dasd_generic_pm_freeze(struct ccw_device *cdev)
2446{
2447 struct dasd_ccw_req *cqr, *n;
2448 int rc;
2449 struct list_head freeze_queue;
2450 struct dasd_device *device = dasd_device_from_cdev(cdev);
2451
2452 if (IS_ERR(device))
2453 return PTR_ERR(device);
2454 /* disallow new I/O */
2455 device->stopped |= DASD_STOPPED_PM;
2456 /* clear active requests */
2457 INIT_LIST_HEAD(&freeze_queue);
2458 spin_lock_irq(get_ccwdev_lock(cdev));
2459 rc = 0;
2460 list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) {
2461 /* Check status and move request to flush_queue */
2462 if (cqr->status == DASD_CQR_IN_IO) {
2463 rc = device->discipline->term_IO(cqr);
2464 if (rc) {
2465 /* unable to terminate requeust */
2466 dev_err(&device->cdev->dev,
2467 "Unable to terminate request %p "
2468 "on suspend\n", cqr);
2469 spin_unlock_irq(get_ccwdev_lock(cdev));
2470 dasd_put_device(device);
2471 return rc;
2472 }
2473 }
2474 list_move_tail(&cqr->devlist, &freeze_queue);
2475 }
2476
2477 spin_unlock_irq(get_ccwdev_lock(cdev));
2478
2479 list_for_each_entry_safe(cqr, n, &freeze_queue, devlist) {
2480 wait_event(dasd_flush_wq,
2481 (cqr->status != DASD_CQR_CLEAR_PENDING));
2482 if (cqr->status == DASD_CQR_CLEARED)
2483 cqr->status = DASD_CQR_QUEUED;
2484 }
2485 /* move freeze_queue to start of the ccw_queue */
2486 spin_lock_irq(get_ccwdev_lock(cdev));
2487 list_splice_tail(&freeze_queue, &device->ccw_queue);
2488 spin_unlock_irq(get_ccwdev_lock(cdev));
2489
2490 if (device->discipline->freeze)
2491 rc = device->discipline->freeze(device);
2492
2493 dasd_put_device(device);
2494 return rc;
2495}
2496EXPORT_SYMBOL_GPL(dasd_generic_pm_freeze);
2497
2498int dasd_generic_restore_device(struct ccw_device *cdev)
2499{
2500 struct dasd_device *device = dasd_device_from_cdev(cdev);
2501 int rc = 0;
2502
2503 if (IS_ERR(device))
2504 return PTR_ERR(device);
2505
2506 dasd_schedule_device_bh(device);
2507 if (device->block)
2508 dasd_schedule_block_bh(device->block);
2509
2510 if (device->discipline->restore)
2511 rc = device->discipline->restore(device);
2512
2513 dasd_put_device(device);
2514 return rc;
2515}
2516EXPORT_SYMBOL_GPL(dasd_generic_restore_device);
2517
2395static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device, 2518static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
2396 void *rdc_buffer, 2519 void *rdc_buffer,
2397 int rdc_buffer_size, 2520 int rdc_buffer_size,
@@ -2427,12 +2550,12 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
2427 2550
2428 2551
2429int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic, 2552int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic,
2430 void **rdc_buffer, int rdc_buffer_size) 2553 void *rdc_buffer, int rdc_buffer_size)
2431{ 2554{
2432 int ret; 2555 int ret;
2433 struct dasd_ccw_req *cqr; 2556 struct dasd_ccw_req *cqr;
2434 2557
2435 cqr = dasd_generic_build_rdc(device, *rdc_buffer, rdc_buffer_size, 2558 cqr = dasd_generic_build_rdc(device, rdc_buffer, rdc_buffer_size,
2436 magic); 2559 magic);
2437 if (IS_ERR(cqr)) 2560 if (IS_ERR(cqr))
2438 return PTR_ERR(cqr); 2561 return PTR_ERR(cqr);
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index e77666c8e6c0..4cac5b54f26a 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -1098,6 +1098,7 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
1098 spin_unlock(&dasd_devmap_lock); 1098 spin_unlock(&dasd_devmap_lock);
1099 return 0; 1099 return 0;
1100} 1100}
1101EXPORT_SYMBOL_GPL(dasd_get_uid);
1101 1102
1102/* 1103/*
1103 * Register the given device unique identifier into devmap struct. 1104 * Register the given device unique identifier into devmap struct.
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 2efaddfae560..644086ba2ede 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -202,6 +202,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
202 rc = -EIO; 202 rc = -EIO;
203 break; 203 break;
204 } 204 }
205 cqr->intrc = rc;
205 return rc; 206 return rc;
206} 207}
207 208
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index a41c94053e64..1c28ec3e4ccb 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -5,10 +5,9 @@
5 * Carsten Otte <Cotte@de.ibm.com> 5 * Carsten Otte <Cotte@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Bugreports.to..: <Linux390@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com>
8 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 8 * Copyright IBM Corp. 1999, 2009
9 * EMC Symmetrix ioctl Copyright EMC Corporation, 2008 9 * EMC Symmetrix ioctl Copyright EMC Corporation, 2008
10 * Author.........: Nigel Hislop <hislop_nigel@emc.com> 10 * Author.........: Nigel Hislop <hislop_nigel@emc.com>
11 *
12 */ 11 */
13 12
14#define KMSG_COMPONENT "dasd" 13#define KMSG_COMPONENT "dasd"
@@ -104,17 +103,6 @@ dasd_eckd_set_online(struct ccw_device *cdev)
104 return dasd_generic_set_online(cdev, &dasd_eckd_discipline); 103 return dasd_generic_set_online(cdev, &dasd_eckd_discipline);
105} 104}
106 105
107static struct ccw_driver dasd_eckd_driver = {
108 .name = "dasd-eckd",
109 .owner = THIS_MODULE,
110 .ids = dasd_eckd_ids,
111 .probe = dasd_eckd_probe,
112 .remove = dasd_generic_remove,
113 .set_offline = dasd_generic_set_offline,
114 .set_online = dasd_eckd_set_online,
115 .notify = dasd_generic_notify,
116};
117
118static const int sizes_trk0[] = { 28, 148, 84 }; 106static const int sizes_trk0[] = { 28, 148, 84 };
119#define LABEL_SIZE 140 107#define LABEL_SIZE 140
120 108
@@ -1097,20 +1085,20 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1097{ 1085{
1098 struct dasd_eckd_private *private; 1086 struct dasd_eckd_private *private;
1099 struct dasd_block *block; 1087 struct dasd_block *block;
1100 void *rdc_data;
1101 int is_known, rc; 1088 int is_known, rc;
1102 1089
1103 private = (struct dasd_eckd_private *) device->private; 1090 private = (struct dasd_eckd_private *) device->private;
1104 if (private == NULL) { 1091 if (!private) {
1105 private = kzalloc(sizeof(struct dasd_eckd_private), 1092 private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
1106 GFP_KERNEL | GFP_DMA); 1093 if (!private) {
1107 if (private == NULL) {
1108 dev_warn(&device->cdev->dev, 1094 dev_warn(&device->cdev->dev,
1109 "Allocating memory for private DASD data " 1095 "Allocating memory for private DASD data "
1110 "failed\n"); 1096 "failed\n");
1111 return -ENOMEM; 1097 return -ENOMEM;
1112 } 1098 }
1113 device->private = (void *) private; 1099 device->private = (void *) private;
1100 } else {
1101 memset(private, 0, sizeof(*private));
1114 } 1102 }
1115 /* Invalidate status of initial analysis. */ 1103 /* Invalidate status of initial analysis. */
1116 private->init_cqr_status = -1; 1104 private->init_cqr_status = -1;
@@ -1161,9 +1149,8 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1161 goto out_err3; 1149 goto out_err3;
1162 1150
1163 /* Read Device Characteristics */ 1151 /* Read Device Characteristics */
1164 rdc_data = (void *) &(private->rdc_data); 1152 rc = dasd_generic_read_dev_chars(device, "ECKD", &private->rdc_data,
1165 memset(rdc_data, 0, sizeof(rdc_data)); 1153 64);
1166 rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64);
1167 if (rc) { 1154 if (rc) {
1168 DBF_EVENT(DBF_WARNING, 1155 DBF_EVENT(DBF_WARNING,
1169 "Read device characteristics failed, rc=%d for " 1156 "Read device characteristics failed, rc=%d for "
@@ -1183,7 +1170,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1183 private->rdc_data.dev_model, 1170 private->rdc_data.dev_model,
1184 private->rdc_data.cu_type, 1171 private->rdc_data.cu_type,
1185 private->rdc_data.cu_model.model, 1172 private->rdc_data.cu_model.model,
1186 private->real_cyl, 1173 private->real_cyl,
1187 private->rdc_data.trk_per_cyl, 1174 private->rdc_data.trk_per_cyl,
1188 private->rdc_data.sec_per_trk); 1175 private->rdc_data.sec_per_trk);
1189 return 0; 1176 return 0;
@@ -2336,9 +2323,10 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2336{ 2323{
2337 int tpm, cmdrtd, cmdwtd; 2324 int tpm, cmdrtd, cmdwtd;
2338 int use_prefix; 2325 int use_prefix;
2339 2326#if defined(CONFIG_64BIT)
2340 struct dasd_eckd_private *private;
2341 int fcx_in_css, fcx_in_gneq, fcx_in_features; 2327 int fcx_in_css, fcx_in_gneq, fcx_in_features;
2328#endif
2329 struct dasd_eckd_private *private;
2342 struct dasd_device *basedev; 2330 struct dasd_device *basedev;
2343 sector_t first_rec, last_rec; 2331 sector_t first_rec, last_rec;
2344 sector_t first_trk, last_trk; 2332 sector_t first_trk, last_trk;
@@ -2361,11 +2349,15 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2361 last_offs = sector_div(last_trk, blk_per_trk); 2349 last_offs = sector_div(last_trk, blk_per_trk);
2362 cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk); 2350 cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
2363 2351
2364 /* is transport mode supported ? */ 2352 /* is transport mode supported? */
2353#if defined(CONFIG_64BIT)
2365 fcx_in_css = css_general_characteristics.fcx; 2354 fcx_in_css = css_general_characteristics.fcx;
2366 fcx_in_gneq = private->gneq->reserved2[7] & 0x04; 2355 fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
2367 fcx_in_features = private->features.feature[40] & 0x80; 2356 fcx_in_features = private->features.feature[40] & 0x80;
2368 tpm = fcx_in_css && fcx_in_gneq && fcx_in_features; 2357 tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
2358#else
2359 tpm = 0;
2360#endif
2369 2361
2370 /* is read track data and write track data in command mode supported? */ 2362 /* is read track data and write track data in command mode supported? */
2371 cmdrtd = private->features.feature[9] & 0x20; 2363 cmdrtd = private->features.feature[9] & 0x20;
@@ -3013,8 +3005,9 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
3013 " I/O status report for device %s:\n", 3005 " I/O status report for device %s:\n",
3014 dev_name(&device->cdev->dev)); 3006 dev_name(&device->cdev->dev));
3015 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3007 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3016 " in req: %p CS: 0x%02X DS: 0x%02X\n", req, 3008 " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n",
3017 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw)); 3009 req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
3010 scsw_cc(&irb->scsw), req->intrc);
3018 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3011 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3019 " device %s: Failing CCW: %p\n", 3012 " device %s: Failing CCW: %p\n",
3020 dev_name(&device->cdev->dev), 3013 dev_name(&device->cdev->dev),
@@ -3115,9 +3108,10 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3115 " I/O status report for device %s:\n", 3108 " I/O status report for device %s:\n",
3116 dev_name(&device->cdev->dev)); 3109 dev_name(&device->cdev->dev));
3117 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3110 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3118 " in req: %p CS: 0x%02X DS: 0x%02X " 3111 " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d "
3119 "fcxs: 0x%02X schxs: 0x%02X\n", req, 3112 "fcxs: 0x%02X schxs: 0x%02X\n", req,
3120 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), 3113 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
3114 scsw_cc(&irb->scsw), req->intrc,
3121 irb->scsw.tm.fcxs, irb->scsw.tm.schxs); 3115 irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
3122 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3116 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3123 " device %s: Failing TCW: %p\n", 3117 " device %s: Failing TCW: %p\n",
@@ -3230,6 +3224,98 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
3230 dasd_eckd_dump_sense_ccw(device, req, irb); 3224 dasd_eckd_dump_sense_ccw(device, req, irb);
3231} 3225}
3232 3226
3227int dasd_eckd_pm_freeze(struct dasd_device *device)
3228{
3229 /*
3230 * the device should be disconnected from our LCU structure
3231 * on restore we will reconnect it and reread LCU specific
3232 * information like PAV support that might have changed
3233 */
3234 dasd_alias_remove_device(device);
3235 dasd_alias_disconnect_device_from_lcu(device);
3236
3237 return 0;
3238}
3239
3240int dasd_eckd_restore_device(struct dasd_device *device)
3241{
3242 struct dasd_eckd_private *private;
3243 int is_known, rc;
3244 struct dasd_uid temp_uid;
3245
3246 /* allow new IO again */
3247 device->stopped &= ~DASD_STOPPED_PM;
3248
3249 private = (struct dasd_eckd_private *) device->private;
3250
3251 /* Read Configuration Data */
3252 rc = dasd_eckd_read_conf(device);
3253 if (rc)
3254 goto out_err;
3255
3256 /* Generate device unique id and register in devmap */
3257 rc = dasd_eckd_generate_uid(device, &private->uid);
3258 dasd_get_uid(device->cdev, &temp_uid);
3259 if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0)
3260 dev_err(&device->cdev->dev, "The UID of the DASD has changed\n");
3261 if (rc)
3262 goto out_err;
3263 dasd_set_uid(device->cdev, &private->uid);
3264
3265 /* register lcu with alias handling, enable PAV if this is a new lcu */
3266 is_known = dasd_alias_make_device_known_to_lcu(device);
3267 if (is_known < 0)
3268 return is_known;
3269 if (!is_known) {
3270 /* new lcu found */
3271 rc = dasd_eckd_validate_server(device); /* will switch pav on */
3272 if (rc)
3273 goto out_err;
3274 }
3275
3276 /* Read Feature Codes */
3277 rc = dasd_eckd_read_features(device);
3278 if (rc)
3279 goto out_err;
3280
3281 /* Read Device Characteristics */
3282 memset(&private->rdc_data, 0, sizeof(private->rdc_data));
3283 rc = dasd_generic_read_dev_chars(device, "ECKD",
3284 &private->rdc_data, 64);
3285 if (rc) {
3286 DBF_EVENT(DBF_WARNING,
3287 "Read device characteristics failed, rc=%d for "
3288 "device: %s", rc, dev_name(&device->cdev->dev));
3289 goto out_err;
3290 }
3291
3292 /* add device to alias management */
3293 dasd_alias_add_device(device);
3294
3295 return 0;
3296
3297out_err:
3298 /*
3299 * if the resume failed for the DASD we put it in
3300 * an UNRESUMED stop state
3301 */
3302 device->stopped |= DASD_UNRESUMED_PM;
3303 return 0;
3304}
3305
3306static struct ccw_driver dasd_eckd_driver = {
3307 .name = "dasd-eckd",
3308 .owner = THIS_MODULE,
3309 .ids = dasd_eckd_ids,
3310 .probe = dasd_eckd_probe,
3311 .remove = dasd_generic_remove,
3312 .set_offline = dasd_generic_set_offline,
3313 .set_online = dasd_eckd_set_online,
3314 .notify = dasd_generic_notify,
3315 .freeze = dasd_generic_pm_freeze,
3316 .thaw = dasd_generic_restore_device,
3317 .restore = dasd_generic_restore_device,
3318};
3233 3319
3234/* 3320/*
3235 * max_blocks is dependent on the amount of storage that is available 3321 * max_blocks is dependent on the amount of storage that is available
@@ -3268,13 +3354,21 @@ static struct dasd_discipline dasd_eckd_discipline = {
3268 .dump_sense_dbf = dasd_eckd_dump_sense_dbf, 3354 .dump_sense_dbf = dasd_eckd_dump_sense_dbf,
3269 .fill_info = dasd_eckd_fill_info, 3355 .fill_info = dasd_eckd_fill_info,
3270 .ioctl = dasd_eckd_ioctl, 3356 .ioctl = dasd_eckd_ioctl,
3357 .freeze = dasd_eckd_pm_freeze,
3358 .restore = dasd_eckd_restore_device,
3271}; 3359};
3272 3360
3273static int __init 3361static int __init
3274dasd_eckd_init(void) 3362dasd_eckd_init(void)
3275{ 3363{
3364 int ret;
3365
3276 ASCEBC(dasd_eckd_discipline.ebcname, 4); 3366 ASCEBC(dasd_eckd_discipline.ebcname, 4);
3277 return ccw_driver_register(&dasd_eckd_driver); 3367 ret = ccw_driver_register(&dasd_eckd_driver);
3368 if (!ret)
3369 wait_for_device_probe();
3370
3371 return ret;
3278} 3372}
3279 3373
3280static void __exit 3374static void __exit
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 8912358daa2f..e21ee735f926 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -2,8 +2,7 @@
2 * File...........: linux/drivers/s390/block/dasd_fba.c 2 * File...........: linux/drivers/s390/block/dasd_fba.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
5 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 5 * Copyright IBM Corp. 1999, 2009
6 *
7 */ 6 */
8 7
9#define KMSG_COMPONENT "dasd" 8#define KMSG_COMPONENT "dasd"
@@ -75,6 +74,9 @@ static struct ccw_driver dasd_fba_driver = {
75 .set_offline = dasd_generic_set_offline, 74 .set_offline = dasd_generic_set_offline,
76 .set_online = dasd_fba_set_online, 75 .set_online = dasd_fba_set_online,
77 .notify = dasd_generic_notify, 76 .notify = dasd_generic_notify,
77 .freeze = dasd_generic_pm_freeze,
78 .thaw = dasd_generic_restore_device,
79 .restore = dasd_generic_restore_device,
78}; 80};
79 81
80static void 82static void
@@ -122,20 +124,20 @@ dasd_fba_check_characteristics(struct dasd_device *device)
122 struct dasd_block *block; 124 struct dasd_block *block;
123 struct dasd_fba_private *private; 125 struct dasd_fba_private *private;
124 struct ccw_device *cdev = device->cdev; 126 struct ccw_device *cdev = device->cdev;
125 void *rdc_data;
126 int rc; 127 int rc;
127 128
128 private = (struct dasd_fba_private *) device->private; 129 private = (struct dasd_fba_private *) device->private;
129 if (private == NULL) { 130 if (!private) {
130 private = kzalloc(sizeof(struct dasd_fba_private), 131 private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
131 GFP_KERNEL | GFP_DMA); 132 if (!private) {
132 if (private == NULL) {
133 dev_warn(&device->cdev->dev, 133 dev_warn(&device->cdev->dev,
134 "Allocating memory for private DASD " 134 "Allocating memory for private DASD "
135 "data failed\n"); 135 "data failed\n");
136 return -ENOMEM; 136 return -ENOMEM;
137 } 137 }
138 device->private = (void *) private; 138 device->private = (void *) private;
139 } else {
140 memset(private, 0, sizeof(*private));
139 } 141 }
140 block = dasd_alloc_block(); 142 block = dasd_alloc_block();
141 if (IS_ERR(block)) { 143 if (IS_ERR(block)) {
@@ -150,8 +152,8 @@ dasd_fba_check_characteristics(struct dasd_device *device)
150 block->base = device; 152 block->base = device;
151 153
152 /* Read Device Characteristics */ 154 /* Read Device Characteristics */
153 rdc_data = (void *) &(private->rdc_data); 155 rc = dasd_generic_read_dev_chars(device, "FBA ", &private->rdc_data,
154 rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32); 156 32);
155 if (rc) { 157 if (rc) {
156 DBF_EVENT(DBF_WARNING, "Read device characteristics returned " 158 DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
157 "error %d for device: %s", 159 "error %d for device: %s",
@@ -604,8 +606,14 @@ static struct dasd_discipline dasd_fba_discipline = {
604static int __init 606static int __init
605dasd_fba_init(void) 607dasd_fba_init(void)
606{ 608{
609 int ret;
610
607 ASCEBC(dasd_fba_discipline.ebcname, 4); 611 ASCEBC(dasd_fba_discipline.ebcname, 4);
608 return ccw_driver_register(&dasd_fba_driver); 612 ret = ccw_driver_register(&dasd_fba_driver);
613 if (!ret)
614 wait_for_device_probe();
615
616 return ret;
609} 617}
610 618
611static void __exit 619static void __exit
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index c1e487f774c6..fd63b2f2bda9 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -4,8 +4,7 @@
4 * Horst Hummel <Horst.Hummel@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
5 * Martin Schwidefsky <schwidefsky@de.ibm.com> 5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
6 * Bugreports.to..: <Linux390@de.ibm.com> 6 * Bugreports.to..: <Linux390@de.ibm.com>
7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 7 * Copyright IBM Corp. 1999, 2009
8 *
9 */ 8 */
10 9
11#ifndef DASD_INT_H 10#ifndef DASD_INT_H
@@ -173,6 +172,7 @@ struct dasd_ccw_req {
173 void *data; /* pointer to data area */ 172 void *data; /* pointer to data area */
174 173
175 /* these are important for recovering erroneous requests */ 174 /* these are important for recovering erroneous requests */
175 int intrc; /* internal error, e.g. from start_IO */
176 struct irb irb; /* device status in case of an error */ 176 struct irb irb; /* device status in case of an error */
177 struct dasd_ccw_req *refers; /* ERP-chain queueing. */ 177 struct dasd_ccw_req *refers; /* ERP-chain queueing. */
178 void *function; /* originating ERP action */ 178 void *function; /* originating ERP action */
@@ -294,6 +294,10 @@ struct dasd_discipline {
294 int (*fill_geometry) (struct dasd_block *, struct hd_geometry *); 294 int (*fill_geometry) (struct dasd_block *, struct hd_geometry *);
295 int (*fill_info) (struct dasd_device *, struct dasd_information2_t *); 295 int (*fill_info) (struct dasd_device *, struct dasd_information2_t *);
296 int (*ioctl) (struct dasd_block *, unsigned int, void __user *); 296 int (*ioctl) (struct dasd_block *, unsigned int, void __user *);
297
298 /* suspend/resume functions */
299 int (*freeze) (struct dasd_device *);
300 int (*restore) (struct dasd_device *);
297}; 301};
298 302
299extern struct dasd_discipline *dasd_diag_discipline_pointer; 303extern struct dasd_discipline *dasd_diag_discipline_pointer;
@@ -366,6 +370,7 @@ struct dasd_device {
366 atomic_t tasklet_scheduled; 370 atomic_t tasklet_scheduled;
367 struct tasklet_struct tasklet; 371 struct tasklet_struct tasklet;
368 struct work_struct kick_work; 372 struct work_struct kick_work;
373 struct work_struct restore_device;
369 struct timer_list timer; 374 struct timer_list timer;
370 375
371 debug_info_t *debug_area; 376 debug_info_t *debug_area;
@@ -409,6 +414,8 @@ struct dasd_block {
409#define DASD_STOPPED_PENDING 4 /* long busy */ 414#define DASD_STOPPED_PENDING 4 /* long busy */
410#define DASD_STOPPED_DC_WAIT 8 /* disconnected, wait */ 415#define DASD_STOPPED_DC_WAIT 8 /* disconnected, wait */
411#define DASD_STOPPED_SU 16 /* summary unit check handling */ 416#define DASD_STOPPED_SU 16 /* summary unit check handling */
417#define DASD_STOPPED_PM 32 /* pm state transition */
418#define DASD_UNRESUMED_PM 64 /* pm resume failed state */
412 419
413/* per device flags */ 420/* per device flags */
414#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ 421#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */
@@ -555,6 +562,7 @@ void dasd_free_block(struct dasd_block *);
555void dasd_enable_device(struct dasd_device *); 562void dasd_enable_device(struct dasd_device *);
556void dasd_set_target_state(struct dasd_device *, int); 563void dasd_set_target_state(struct dasd_device *, int);
557void dasd_kick_device(struct dasd_device *); 564void dasd_kick_device(struct dasd_device *);
565void dasd_restore_device(struct dasd_device *);
558 566
559void dasd_add_request_head(struct dasd_ccw_req *); 567void dasd_add_request_head(struct dasd_ccw_req *);
560void dasd_add_request_tail(struct dasd_ccw_req *); 568void dasd_add_request_tail(struct dasd_ccw_req *);
@@ -577,8 +585,10 @@ int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
577int dasd_generic_set_offline (struct ccw_device *cdev); 585int dasd_generic_set_offline (struct ccw_device *cdev);
578int dasd_generic_notify(struct ccw_device *, int); 586int dasd_generic_notify(struct ccw_device *, int);
579void dasd_generic_handle_state_change(struct dasd_device *); 587void dasd_generic_handle_state_change(struct dasd_device *);
588int dasd_generic_pm_freeze(struct ccw_device *);
589int dasd_generic_restore_device(struct ccw_device *);
580 590
581int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int); 591int dasd_generic_read_dev_chars(struct dasd_device *, char *, void *, int);
582char *dasd_get_sense(struct irb *); 592char *dasd_get_sense(struct irb *);
583 593
584/* externals in dasd_devmap.c */ 594/* externals in dasd_devmap.c */
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index a4c7ffcd9987..016f9e9d2591 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -14,10 +14,11 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/blkdev.h> 16#include <linux/blkdev.h>
17#include <asm/extmem.h>
18#include <asm/io.h>
19#include <linux/completion.h> 17#include <linux/completion.h>
20#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/platform_device.h>
20#include <asm/extmem.h>
21#include <asm/io.h>
21 22
22#define DCSSBLK_NAME "dcssblk" 23#define DCSSBLK_NAME "dcssblk"
23#define DCSSBLK_MINORS_PER_DISK 1 24#define DCSSBLK_MINORS_PER_DISK 1
@@ -127,7 +128,7 @@ dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info)
127 found = 0; 128 found = 0;
128 // test if minor available 129 // test if minor available
129 list_for_each_entry(entry, &dcssblk_devices, lh) 130 list_for_each_entry(entry, &dcssblk_devices, lh)
130 if (minor == MINOR(disk_devt(entry->gd))) 131 if (minor == entry->gd->first_minor)
131 found++; 132 found++;
132 if (!found) break; // got unused minor 133 if (!found) break; // got unused minor
133 } 134 }
@@ -625,7 +626,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
625 if (rc) 626 if (rc)
626 goto release_gd; 627 goto release_gd;
627 sprintf(dev_info->gd->disk_name, "dcssblk%d", 628 sprintf(dev_info->gd->disk_name, "dcssblk%d",
628 MINOR(disk_devt(dev_info->gd))); 629 dev_info->gd->first_minor);
629 list_add_tail(&dev_info->lh, &dcssblk_devices); 630 list_add_tail(&dev_info->lh, &dcssblk_devices);
630 631
631 if (!try_module_get(THIS_MODULE)) { 632 if (!try_module_get(THIS_MODULE)) {
@@ -940,11 +941,94 @@ dcssblk_check_params(void)
940} 941}
941 942
942/* 943/*
944 * Suspend / Resume
945 */
946static int dcssblk_freeze(struct device *dev)
947{
948 struct dcssblk_dev_info *dev_info;
949 int rc = 0;
950
951 list_for_each_entry(dev_info, &dcssblk_devices, lh) {
952 switch (dev_info->segment_type) {
953 case SEG_TYPE_SR:
954 case SEG_TYPE_ER:
955 case SEG_TYPE_SC:
956 if (!dev_info->is_shared)
957 rc = -EINVAL;
958 break;
959 default:
960 rc = -EINVAL;
961 break;
962 }
963 if (rc)
964 break;
965 }
966 if (rc)
967 pr_err("Suspend failed because device %s is writeable.\n",
968 dev_info->segment_name);
969 return rc;
970}
971
972static int dcssblk_restore(struct device *dev)
973{
974 struct dcssblk_dev_info *dev_info;
975 struct segment_info *entry;
976 unsigned long start, end;
977 int rc = 0;
978
979 list_for_each_entry(dev_info, &dcssblk_devices, lh) {
980 list_for_each_entry(entry, &dev_info->seg_list, lh) {
981 segment_unload(entry->segment_name);
982 rc = segment_load(entry->segment_name, SEGMENT_SHARED,
983 &start, &end);
984 if (rc < 0) {
985// TODO in_use check ?
986 segment_warning(rc, entry->segment_name);
987 goto out_panic;
988 }
989 if (start != entry->start || end != entry->end) {
990 pr_err("Mismatch of start / end address after "
991 "resuming device %s\n",
992 entry->segment_name);
993 goto out_panic;
994 }
995 }
996 }
997 return 0;
998out_panic:
999 panic("fatal dcssblk resume error\n");
1000}
1001
1002static int dcssblk_thaw(struct device *dev)
1003{
1004 return 0;
1005}
1006
1007static struct dev_pm_ops dcssblk_pm_ops = {
1008 .freeze = dcssblk_freeze,
1009 .thaw = dcssblk_thaw,
1010 .restore = dcssblk_restore,
1011};
1012
1013static struct platform_driver dcssblk_pdrv = {
1014 .driver = {
1015 .name = "dcssblk",
1016 .owner = THIS_MODULE,
1017 .pm = &dcssblk_pm_ops,
1018 },
1019};
1020
1021static struct platform_device *dcssblk_pdev;
1022
1023
1024/*
943 * The init/exit functions. 1025 * The init/exit functions.
944 */ 1026 */
945static void __exit 1027static void __exit
946dcssblk_exit(void) 1028dcssblk_exit(void)
947{ 1029{
1030 platform_device_unregister(dcssblk_pdev);
1031 platform_driver_unregister(&dcssblk_pdrv);
948 root_device_unregister(dcssblk_root_dev); 1032 root_device_unregister(dcssblk_root_dev);
949 unregister_blkdev(dcssblk_major, DCSSBLK_NAME); 1033 unregister_blkdev(dcssblk_major, DCSSBLK_NAME);
950} 1034}
@@ -954,30 +1038,44 @@ dcssblk_init(void)
954{ 1038{
955 int rc; 1039 int rc;
956 1040
957 dcssblk_root_dev = root_device_register("dcssblk"); 1041 rc = platform_driver_register(&dcssblk_pdrv);
958 if (IS_ERR(dcssblk_root_dev)) 1042 if (rc)
959 return PTR_ERR(dcssblk_root_dev);
960 rc = device_create_file(dcssblk_root_dev, &dev_attr_add);
961 if (rc) {
962 root_device_unregister(dcssblk_root_dev);
963 return rc; 1043 return rc;
1044
1045 dcssblk_pdev = platform_device_register_simple("dcssblk", -1, NULL,
1046 0);
1047 if (IS_ERR(dcssblk_pdev)) {
1048 rc = PTR_ERR(dcssblk_pdev);
1049 goto out_pdrv;
964 } 1050 }
965 rc = device_create_file(dcssblk_root_dev, &dev_attr_remove); 1051
966 if (rc) { 1052 dcssblk_root_dev = root_device_register("dcssblk");
967 root_device_unregister(dcssblk_root_dev); 1053 if (IS_ERR(dcssblk_root_dev)) {
968 return rc; 1054 rc = PTR_ERR(dcssblk_root_dev);
1055 goto out_pdev;
969 } 1056 }
1057 rc = device_create_file(dcssblk_root_dev, &dev_attr_add);
1058 if (rc)
1059 goto out_root;
1060 rc = device_create_file(dcssblk_root_dev, &dev_attr_remove);
1061 if (rc)
1062 goto out_root;
970 rc = register_blkdev(0, DCSSBLK_NAME); 1063 rc = register_blkdev(0, DCSSBLK_NAME);
971 if (rc < 0) { 1064 if (rc < 0)
972 root_device_unregister(dcssblk_root_dev); 1065 goto out_root;
973 return rc;
974 }
975 dcssblk_major = rc; 1066 dcssblk_major = rc;
976 init_rwsem(&dcssblk_devices_sem); 1067 init_rwsem(&dcssblk_devices_sem);
977 1068
978 dcssblk_check_params(); 1069 dcssblk_check_params();
979
980 return 0; 1070 return 0;
1071
1072out_root:
1073 root_device_unregister(dcssblk_root_dev);
1074out_pdev:
1075 platform_device_unregister(dcssblk_pdev);
1076out_pdrv:
1077 platform_driver_unregister(&dcssblk_pdrv);
1078 return rc;
981} 1079}
982 1080
983module_init(dcssblk_init); 1081module_init(dcssblk_init);
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 0ae0c83ef879..2e9e1ecd6d82 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -39,7 +39,10 @@
39#include <linux/hdreg.h> /* HDIO_GETGEO */ 39#include <linux/hdreg.h> /* HDIO_GETGEO */
40#include <linux/sysdev.h> 40#include <linux/sysdev.h>
41#include <linux/bio.h> 41#include <linux/bio.h>
42#include <linux/suspend.h>
43#include <linux/platform_device.h>
42#include <asm/uaccess.h> 44#include <asm/uaccess.h>
45#include <asm/checksum.h>
43 46
44#define XPRAM_NAME "xpram" 47#define XPRAM_NAME "xpram"
45#define XPRAM_DEVS 1 /* one partition */ 48#define XPRAM_DEVS 1 /* one partition */
@@ -48,6 +51,7 @@
48typedef struct { 51typedef struct {
49 unsigned int size; /* size of xpram segment in pages */ 52 unsigned int size; /* size of xpram segment in pages */
50 unsigned int offset; /* start page of xpram segment */ 53 unsigned int offset; /* start page of xpram segment */
54 unsigned int csum; /* partition checksum for suspend */
51} xpram_device_t; 55} xpram_device_t;
52 56
53static xpram_device_t xpram_devices[XPRAM_MAX_DEVS]; 57static xpram_device_t xpram_devices[XPRAM_MAX_DEVS];
@@ -138,7 +142,7 @@ static long xpram_page_out (unsigned long page_addr, unsigned int xpage_index)
138/* 142/*
139 * Check if xpram is available. 143 * Check if xpram is available.
140 */ 144 */
141static int __init xpram_present(void) 145static int xpram_present(void)
142{ 146{
143 unsigned long mem_page; 147 unsigned long mem_page;
144 int rc; 148 int rc;
@@ -154,7 +158,7 @@ static int __init xpram_present(void)
154/* 158/*
155 * Return index of the last available xpram page. 159 * Return index of the last available xpram page.
156 */ 160 */
157static unsigned long __init xpram_highest_page_index(void) 161static unsigned long xpram_highest_page_index(void)
158{ 162{
159 unsigned int page_index, add_bit; 163 unsigned int page_index, add_bit;
160 unsigned long mem_page; 164 unsigned long mem_page;
@@ -383,6 +387,106 @@ out:
383} 387}
384 388
385/* 389/*
390 * Save checksums for all partitions.
391 */
392static int xpram_save_checksums(void)
393{
394 unsigned long mem_page;
395 int rc, i;
396
397 rc = 0;
398 mem_page = (unsigned long) __get_free_page(GFP_KERNEL);
399 if (!mem_page)
400 return -ENOMEM;
401 for (i = 0; i < xpram_devs; i++) {
402 rc = xpram_page_in(mem_page, xpram_devices[i].offset);
403 if (rc)
404 goto fail;
405 xpram_devices[i].csum = csum_partial((const void *) mem_page,
406 PAGE_SIZE, 0);
407 }
408fail:
409 free_page(mem_page);
410 return rc ? -ENXIO : 0;
411}
412
413/*
414 * Verify checksums for all partitions.
415 */
416static int xpram_validate_checksums(void)
417{
418 unsigned long mem_page;
419 unsigned int csum;
420 int rc, i;
421
422 rc = 0;
423 mem_page = (unsigned long) __get_free_page(GFP_KERNEL);
424 if (!mem_page)
425 return -ENOMEM;
426 for (i = 0; i < xpram_devs; i++) {
427 rc = xpram_page_in(mem_page, xpram_devices[i].offset);
428 if (rc)
429 goto fail;
430 csum = csum_partial((const void *) mem_page, PAGE_SIZE, 0);
431 if (xpram_devices[i].csum != csum) {
432 rc = -EINVAL;
433 goto fail;
434 }
435 }
436fail:
437 free_page(mem_page);
438 return rc ? -ENXIO : 0;
439}
440
441/*
442 * Resume failed: Print error message and call panic.
443 */
444static void xpram_resume_error(const char *message)
445{
446 pr_err("Resume error: %s\n", message);
447 panic("xpram resume error\n");
448}
449
450/*
451 * Check if xpram setup changed between suspend and resume.
452 */
453static int xpram_restore(struct device *dev)
454{
455 if (!xpram_pages)
456 return 0;
457 if (xpram_present() != 0)
458 xpram_resume_error("xpram disappeared");
459 if (xpram_pages != xpram_highest_page_index() + 1)
460 xpram_resume_error("Size of xpram changed");
461 if (xpram_validate_checksums())
462 xpram_resume_error("Data of xpram changed");
463 return 0;
464}
465
466/*
467 * Save necessary state in suspend.
468 */
469static int xpram_freeze(struct device *dev)
470{
471 return xpram_save_checksums();
472}
473
474static struct dev_pm_ops xpram_pm_ops = {
475 .freeze = xpram_freeze,
476 .restore = xpram_restore,
477};
478
479static struct platform_driver xpram_pdrv = {
480 .driver = {
481 .name = XPRAM_NAME,
482 .owner = THIS_MODULE,
483 .pm = &xpram_pm_ops,
484 },
485};
486
487static struct platform_device *xpram_pdev;
488
489/*
386 * Finally, the init/exit functions. 490 * Finally, the init/exit functions.
387 */ 491 */
388static void __exit xpram_exit(void) 492static void __exit xpram_exit(void)
@@ -394,6 +498,8 @@ static void __exit xpram_exit(void)
394 put_disk(xpram_disks[i]); 498 put_disk(xpram_disks[i]);
395 } 499 }
396 unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); 500 unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
501 platform_device_unregister(xpram_pdev);
502 platform_driver_unregister(&xpram_pdrv);
397} 503}
398 504
399static int __init xpram_init(void) 505static int __init xpram_init(void)
@@ -411,7 +517,24 @@ static int __init xpram_init(void)
411 rc = xpram_setup_sizes(xpram_pages); 517 rc = xpram_setup_sizes(xpram_pages);
412 if (rc) 518 if (rc)
413 return rc; 519 return rc;
414 return xpram_setup_blkdev(); 520 rc = platform_driver_register(&xpram_pdrv);
521 if (rc)
522 return rc;
523 xpram_pdev = platform_device_register_simple(XPRAM_NAME, -1, NULL, 0);
524 if (IS_ERR(xpram_pdev)) {
525 rc = PTR_ERR(xpram_pdev);
526 goto fail_platform_driver_unregister;
527 }
528 rc = xpram_setup_blkdev();
529 if (rc)
530 goto fail_platform_device_unregister;
531 return 0;
532
533fail_platform_device_unregister:
534 platform_device_unregister(xpram_pdev);
535fail_platform_driver_unregister:
536 platform_driver_unregister(&xpram_pdrv);
537 return rc;
415} 538}
416 539
417module_init(xpram_init); 540module_init(xpram_init);
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 9ab06e0dad40..04dc734805c6 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -1,14 +1,12 @@
1/* 1/*
2 * drivers/s390/char/con3215.c 2 * 3215 line mode terminal driver.
3 * 3215 line mode terminal driver.
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 1999, 2009
6 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
8 * 6 *
9 * Updated: 7 * Updated:
10 * Aug-2000: Added tab support 8 * Aug-2000: Added tab support
11 * Dan Morrison, IBM Corporation (dmorriso@cse.buffalo.edu) 9 * Dan Morrison, IBM Corporation <dmorriso@cse.buffalo.edu>
12 */ 10 */
13 11
14#include <linux/module.h> 12#include <linux/module.h>
@@ -56,6 +54,7 @@
56#define RAW3215_CLOSING 32 /* set while in close process */ 54#define RAW3215_CLOSING 32 /* set while in close process */
57#define RAW3215_TIMER_RUNS 64 /* set if the output delay timer is on */ 55#define RAW3215_TIMER_RUNS 64 /* set if the output delay timer is on */
58#define RAW3215_FLUSHING 128 /* set to flush buffer (no delay) */ 56#define RAW3215_FLUSHING 128 /* set to flush buffer (no delay) */
57#define RAW3215_FROZEN 256 /* set if 3215 is frozen for suspend */
59 58
60#define TAB_STOP_SIZE 8 /* tab stop size */ 59#define TAB_STOP_SIZE 8 /* tab stop size */
61 60
@@ -111,8 +110,8 @@ static struct tty_driver *tty3215_driver;
111/* 110/*
112 * Get a request structure from the free list 111 * Get a request structure from the free list
113 */ 112 */
114static inline struct raw3215_req * 113static inline struct raw3215_req *raw3215_alloc_req(void)
115raw3215_alloc_req(void) { 114{
116 struct raw3215_req *req; 115 struct raw3215_req *req;
117 unsigned long flags; 116 unsigned long flags;
118 117
@@ -126,8 +125,8 @@ raw3215_alloc_req(void) {
126/* 125/*
127 * Put a request structure back to the free list 126 * Put a request structure back to the free list
128 */ 127 */
129static inline void 128static inline void raw3215_free_req(struct raw3215_req *req)
130raw3215_free_req(struct raw3215_req *req) { 129{
131 unsigned long flags; 130 unsigned long flags;
132 131
133 if (req->type == RAW3215_FREE) 132 if (req->type == RAW3215_FREE)
@@ -145,8 +144,7 @@ raw3215_free_req(struct raw3215_req *req) {
145 * because a 3215 terminal won't accept a new read before the old one is 144 * because a 3215 terminal won't accept a new read before the old one is
146 * completed. 145 * completed.
147 */ 146 */
148static void 147static void raw3215_mk_read_req(struct raw3215_info *raw)
149raw3215_mk_read_req(struct raw3215_info *raw)
150{ 148{
151 struct raw3215_req *req; 149 struct raw3215_req *req;
152 struct ccw1 *ccw; 150 struct ccw1 *ccw;
@@ -174,8 +172,7 @@ raw3215_mk_read_req(struct raw3215_info *raw)
174 * buffer to the 3215 device. If a queued write exists it is replaced by 172 * buffer to the 3215 device. If a queued write exists it is replaced by
175 * the new, probably lengthened request. 173 * the new, probably lengthened request.
176 */ 174 */
177static void 175static void raw3215_mk_write_req(struct raw3215_info *raw)
178raw3215_mk_write_req(struct raw3215_info *raw)
179{ 176{
180 struct raw3215_req *req; 177 struct raw3215_req *req;
181 struct ccw1 *ccw; 178 struct ccw1 *ccw;
@@ -251,8 +248,7 @@ raw3215_mk_write_req(struct raw3215_info *raw)
251/* 248/*
252 * Start a read or a write request 249 * Start a read or a write request
253 */ 250 */
254static void 251static void raw3215_start_io(struct raw3215_info *raw)
255raw3215_start_io(struct raw3215_info *raw)
256{ 252{
257 struct raw3215_req *req; 253 struct raw3215_req *req;
258 int res; 254 int res;
@@ -290,8 +286,7 @@ raw3215_start_io(struct raw3215_info *raw)
290/* 286/*
291 * Function to start a delayed output after RAW3215_TIMEOUT seconds 287 * Function to start a delayed output after RAW3215_TIMEOUT seconds
292 */ 288 */
293static void 289static void raw3215_timeout(unsigned long __data)
294raw3215_timeout(unsigned long __data)
295{ 290{
296 struct raw3215_info *raw = (struct raw3215_info *) __data; 291 struct raw3215_info *raw = (struct raw3215_info *) __data;
297 unsigned long flags; 292 unsigned long flags;
@@ -300,8 +295,10 @@ raw3215_timeout(unsigned long __data)
300 if (raw->flags & RAW3215_TIMER_RUNS) { 295 if (raw->flags & RAW3215_TIMER_RUNS) {
301 del_timer(&raw->timer); 296 del_timer(&raw->timer);
302 raw->flags &= ~RAW3215_TIMER_RUNS; 297 raw->flags &= ~RAW3215_TIMER_RUNS;
303 raw3215_mk_write_req(raw); 298 if (!(raw->flags & RAW3215_FROZEN)) {
304 raw3215_start_io(raw); 299 raw3215_mk_write_req(raw);
300 raw3215_start_io(raw);
301 }
305 } 302 }
306 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 303 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
307} 304}
@@ -312,10 +309,9 @@ raw3215_timeout(unsigned long __data)
312 * amount of data is bigger than RAW3215_MIN_WRITE. If a write is not 309 * amount of data is bigger than RAW3215_MIN_WRITE. If a write is not
313 * done immediately a timer is started with a delay of RAW3215_TIMEOUT. 310 * done immediately a timer is started with a delay of RAW3215_TIMEOUT.
314 */ 311 */
315static inline void 312static inline void raw3215_try_io(struct raw3215_info *raw)
316raw3215_try_io(struct raw3215_info *raw)
317{ 313{
318 if (!(raw->flags & RAW3215_ACTIVE)) 314 if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FROZEN))
319 return; 315 return;
320 if (raw->queued_read != NULL) 316 if (raw->queued_read != NULL)
321 raw3215_start_io(raw); 317 raw3215_start_io(raw);
@@ -359,8 +355,8 @@ static void raw3215_next_io(struct raw3215_info *raw)
359/* 355/*
360 * Interrupt routine, called from common io layer 356 * Interrupt routine, called from common io layer
361 */ 357 */
362static void 358static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
363raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) 359 struct irb *irb)
364{ 360{
365 struct raw3215_info *raw; 361 struct raw3215_info *raw;
366 struct raw3215_req *req; 362 struct raw3215_req *req;
@@ -368,7 +364,7 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
368 int cstat, dstat; 364 int cstat, dstat;
369 int count; 365 int count;
370 366
371 raw = cdev->dev.driver_data; 367 raw = dev_get_drvdata(&cdev->dev);
372 req = (struct raw3215_req *) intparm; 368 req = (struct raw3215_req *) intparm;
373 cstat = irb->scsw.cmd.cstat; 369 cstat = irb->scsw.cmd.cstat;
374 dstat = irb->scsw.cmd.dstat; 370 dstat = irb->scsw.cmd.dstat;
@@ -459,14 +455,40 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
459} 455}
460 456
461/* 457/*
458 * Drop the oldest line from the output buffer.
459 */
460static void raw3215_drop_line(struct raw3215_info *raw)
461{
462 int ix;
463 char ch;
464
465 BUG_ON(raw->written != 0);
466 ix = (raw->head - raw->count) & (RAW3215_BUFFER_SIZE - 1);
467 while (raw->count > 0) {
468 ch = raw->buffer[ix];
469 ix = (ix + 1) & (RAW3215_BUFFER_SIZE - 1);
470 raw->count--;
471 if (ch == 0x15)
472 break;
473 }
474 raw->head = ix;
475}
476
477/*
462 * Wait until length bytes are available int the output buffer. 478 * Wait until length bytes are available int the output buffer.
463 * Has to be called with the s390irq lock held. Can be called 479 * Has to be called with the s390irq lock held. Can be called
464 * disabled. 480 * disabled.
465 */ 481 */
466static void 482static void raw3215_make_room(struct raw3215_info *raw, unsigned int length)
467raw3215_make_room(struct raw3215_info *raw, unsigned int length)
468{ 483{
469 while (RAW3215_BUFFER_SIZE - raw->count < length) { 484 while (RAW3215_BUFFER_SIZE - raw->count < length) {
485 /* While console is frozen for suspend we have no other
486 * choice but to drop message from the buffer to make
487 * room for even more messages. */
488 if (raw->flags & RAW3215_FROZEN) {
489 raw3215_drop_line(raw);
490 continue;
491 }
470 /* there might be a request pending */ 492 /* there might be a request pending */
471 raw->flags |= RAW3215_FLUSHING; 493 raw->flags |= RAW3215_FLUSHING;
472 raw3215_mk_write_req(raw); 494 raw3215_mk_write_req(raw);
@@ -488,8 +510,8 @@ raw3215_make_room(struct raw3215_info *raw, unsigned int length)
488/* 510/*
489 * String write routine for 3215 devices 511 * String write routine for 3215 devices
490 */ 512 */
491static void 513static void raw3215_write(struct raw3215_info *raw, const char *str,
492raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length) 514 unsigned int length)
493{ 515{
494 unsigned long flags; 516 unsigned long flags;
495 int c, count; 517 int c, count;
@@ -529,8 +551,7 @@ raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length)
529/* 551/*
530 * Put character routine for 3215 devices 552 * Put character routine for 3215 devices
531 */ 553 */
532static void 554static void raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
533raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
534{ 555{
535 unsigned long flags; 556 unsigned long flags;
536 unsigned int length, i; 557 unsigned int length, i;
@@ -566,8 +587,7 @@ raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
566 * Flush routine, it simply sets the flush flag and tries to start 587 * Flush routine, it simply sets the flush flag and tries to start
567 * pending IO. 588 * pending IO.
568 */ 589 */
569static void 590static void raw3215_flush_buffer(struct raw3215_info *raw)
570raw3215_flush_buffer(struct raw3215_info *raw)
571{ 591{
572 unsigned long flags; 592 unsigned long flags;
573 593
@@ -583,8 +603,7 @@ raw3215_flush_buffer(struct raw3215_info *raw)
583/* 603/*
584 * Fire up a 3215 device. 604 * Fire up a 3215 device.
585 */ 605 */
586static int 606static int raw3215_startup(struct raw3215_info *raw)
587raw3215_startup(struct raw3215_info *raw)
588{ 607{
589 unsigned long flags; 608 unsigned long flags;
590 609
@@ -602,8 +621,7 @@ raw3215_startup(struct raw3215_info *raw)
602/* 621/*
603 * Shutdown a 3215 device. 622 * Shutdown a 3215 device.
604 */ 623 */
605static void 624static void raw3215_shutdown(struct raw3215_info *raw)
606raw3215_shutdown(struct raw3215_info *raw)
607{ 625{
608 DECLARE_WAITQUEUE(wait, current); 626 DECLARE_WAITQUEUE(wait, current);
609 unsigned long flags; 627 unsigned long flags;
@@ -628,14 +646,13 @@ raw3215_shutdown(struct raw3215_info *raw)
628 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 646 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
629} 647}
630 648
631static int 649static int raw3215_probe (struct ccw_device *cdev)
632raw3215_probe (struct ccw_device *cdev)
633{ 650{
634 struct raw3215_info *raw; 651 struct raw3215_info *raw;
635 int line; 652 int line;
636 653
637 /* Console is special. */ 654 /* Console is special. */
638 if (raw3215[0] && (cdev->dev.driver_data == raw3215[0])) 655 if (raw3215[0] && (raw3215[0] == dev_get_drvdata(&cdev->dev)))
639 return 0; 656 return 0;
640 raw = kmalloc(sizeof(struct raw3215_info) + 657 raw = kmalloc(sizeof(struct raw3215_info) +
641 RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA); 658 RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA);
@@ -669,44 +686,41 @@ raw3215_probe (struct ccw_device *cdev)
669 } 686 }
670 init_waitqueue_head(&raw->empty_wait); 687 init_waitqueue_head(&raw->empty_wait);
671 688
672 cdev->dev.driver_data = raw; 689 dev_set_drvdata(&cdev->dev, raw);
673 cdev->handler = raw3215_irq; 690 cdev->handler = raw3215_irq;
674 691
675 return 0; 692 return 0;
676} 693}
677 694
678static void 695static void raw3215_remove (struct ccw_device *cdev)
679raw3215_remove (struct ccw_device *cdev)
680{ 696{
681 struct raw3215_info *raw; 697 struct raw3215_info *raw;
682 698
683 ccw_device_set_offline(cdev); 699 ccw_device_set_offline(cdev);
684 raw = cdev->dev.driver_data; 700 raw = dev_get_drvdata(&cdev->dev);
685 if (raw) { 701 if (raw) {
686 cdev->dev.driver_data = NULL; 702 dev_set_drvdata(&cdev->dev, NULL);
687 kfree(raw->buffer); 703 kfree(raw->buffer);
688 kfree(raw); 704 kfree(raw);
689 } 705 }
690} 706}
691 707
692static int 708static int raw3215_set_online (struct ccw_device *cdev)
693raw3215_set_online (struct ccw_device *cdev)
694{ 709{
695 struct raw3215_info *raw; 710 struct raw3215_info *raw;
696 711
697 raw = cdev->dev.driver_data; 712 raw = dev_get_drvdata(&cdev->dev);
698 if (!raw) 713 if (!raw)
699 return -ENODEV; 714 return -ENODEV;
700 715
701 return raw3215_startup(raw); 716 return raw3215_startup(raw);
702} 717}
703 718
704static int 719static int raw3215_set_offline (struct ccw_device *cdev)
705raw3215_set_offline (struct ccw_device *cdev)
706{ 720{
707 struct raw3215_info *raw; 721 struct raw3215_info *raw;
708 722
709 raw = cdev->dev.driver_data; 723 raw = dev_get_drvdata(&cdev->dev);
710 if (!raw) 724 if (!raw)
711 return -ENODEV; 725 return -ENODEV;
712 726
@@ -715,6 +729,36 @@ raw3215_set_offline (struct ccw_device *cdev)
715 return 0; 729 return 0;
716} 730}
717 731
732static int raw3215_pm_stop(struct ccw_device *cdev)
733{
734 struct raw3215_info *raw;
735 unsigned long flags;
736
737 /* Empty the output buffer, then prevent new I/O. */
738 raw = cdev->dev.driver_data;
739 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
740 raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
741 raw->flags |= RAW3215_FROZEN;
742 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
743 return 0;
744}
745
746static int raw3215_pm_start(struct ccw_device *cdev)
747{
748 struct raw3215_info *raw;
749 unsigned long flags;
750
751 /* Allow I/O again and flush output buffer. */
752 raw = cdev->dev.driver_data;
753 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
754 raw->flags &= ~RAW3215_FROZEN;
755 raw->flags |= RAW3215_FLUSHING;
756 raw3215_try_io(raw);
757 raw->flags &= ~RAW3215_FLUSHING;
758 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
759 return 0;
760}
761
718static struct ccw_device_id raw3215_id[] = { 762static struct ccw_device_id raw3215_id[] = {
719 { CCW_DEVICE(0x3215, 0) }, 763 { CCW_DEVICE(0x3215, 0) },
720 { /* end of list */ }, 764 { /* end of list */ },
@@ -728,14 +772,17 @@ static struct ccw_driver raw3215_ccw_driver = {
728 .remove = &raw3215_remove, 772 .remove = &raw3215_remove,
729 .set_online = &raw3215_set_online, 773 .set_online = &raw3215_set_online,
730 .set_offline = &raw3215_set_offline, 774 .set_offline = &raw3215_set_offline,
775 .freeze = &raw3215_pm_stop,
776 .thaw = &raw3215_pm_start,
777 .restore = &raw3215_pm_start,
731}; 778};
732 779
733#ifdef CONFIG_TN3215_CONSOLE 780#ifdef CONFIG_TN3215_CONSOLE
734/* 781/*
735 * Write a string to the 3215 console 782 * Write a string to the 3215 console
736 */ 783 */
737static void 784static void con3215_write(struct console *co, const char *str,
738con3215_write(struct console *co, const char *str, unsigned int count) 785 unsigned int count)
739{ 786{
740 struct raw3215_info *raw; 787 struct raw3215_info *raw;
741 int i; 788 int i;
@@ -768,13 +815,17 @@ static struct tty_driver *con3215_device(struct console *c, int *index)
768 * panic() calls con3215_flush through a panic_notifier 815 * panic() calls con3215_flush through a panic_notifier
769 * before the system enters a disabled, endless loop. 816 * before the system enters a disabled, endless loop.
770 */ 817 */
771static void 818static void con3215_flush(void)
772con3215_flush(void)
773{ 819{
774 struct raw3215_info *raw; 820 struct raw3215_info *raw;
775 unsigned long flags; 821 unsigned long flags;
776 822
777 raw = raw3215[0]; /* console 3215 is the first one */ 823 raw = raw3215[0]; /* console 3215 is the first one */
824 if (raw->flags & RAW3215_FROZEN)
825 /* The console is still frozen for suspend. */
826 if (ccw_device_force_console())
827 /* Forcing didn't work, no panic message .. */
828 return;
778 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); 829 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
779 raw3215_make_room(raw, RAW3215_BUFFER_SIZE); 830 raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
780 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 831 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -811,8 +862,7 @@ static struct console con3215 = {
811 * 3215 console initialization code called from console_init(). 862 * 3215 console initialization code called from console_init().
812 * NOTE: This is called before kmalloc is available. 863 * NOTE: This is called before kmalloc is available.
813 */ 864 */
814static int __init 865static int __init con3215_init(void)
815con3215_init(void)
816{ 866{
817 struct ccw_device *cdev; 867 struct ccw_device *cdev;
818 struct raw3215_info *raw; 868 struct raw3215_info *raw;
@@ -848,7 +898,7 @@ con3215_init(void)
848 raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE); 898 raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE);
849 raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE); 899 raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE);
850 raw->cdev = cdev; 900 raw->cdev = cdev;
851 cdev->dev.driver_data = raw; 901 dev_set_drvdata(&cdev->dev, raw);
852 cdev->handler = raw3215_irq; 902 cdev->handler = raw3215_irq;
853 903
854 raw->flags |= RAW3215_FIXED; 904 raw->flags |= RAW3215_FIXED;
@@ -875,8 +925,7 @@ console_initcall(con3215_init);
875 * 925 *
876 * This routine is called whenever a 3215 tty is opened. 926 * This routine is called whenever a 3215 tty is opened.
877 */ 927 */
878static int 928static int tty3215_open(struct tty_struct *tty, struct file * filp)
879tty3215_open(struct tty_struct *tty, struct file * filp)
880{ 929{
881 struct raw3215_info *raw; 930 struct raw3215_info *raw;
882 int retval, line; 931 int retval, line;
@@ -909,8 +958,7 @@ tty3215_open(struct tty_struct *tty, struct file * filp)
909 * This routine is called when the 3215 tty is closed. We wait 958 * This routine is called when the 3215 tty is closed. We wait
910 * for the remaining request to be completed. Then we clean up. 959 * for the remaining request to be completed. Then we clean up.
911 */ 960 */
912static void 961static void tty3215_close(struct tty_struct *tty, struct file * filp)
913tty3215_close(struct tty_struct *tty, struct file * filp)
914{ 962{
915 struct raw3215_info *raw; 963 struct raw3215_info *raw;
916 964
@@ -927,8 +975,7 @@ tty3215_close(struct tty_struct *tty, struct file * filp)
927/* 975/*
928 * Returns the amount of free space in the output buffer. 976 * Returns the amount of free space in the output buffer.
929 */ 977 */
930static int 978static int tty3215_write_room(struct tty_struct *tty)
931tty3215_write_room(struct tty_struct *tty)
932{ 979{
933 struct raw3215_info *raw; 980 struct raw3215_info *raw;
934 981
@@ -944,9 +991,8 @@ tty3215_write_room(struct tty_struct *tty)
944/* 991/*
945 * String write routine for 3215 ttys 992 * String write routine for 3215 ttys
946 */ 993 */
947static int 994static int tty3215_write(struct tty_struct * tty,
948tty3215_write(struct tty_struct * tty, 995 const unsigned char *buf, int count)
949 const unsigned char *buf, int count)
950{ 996{
951 struct raw3215_info *raw; 997 struct raw3215_info *raw;
952 998
@@ -960,8 +1006,7 @@ tty3215_write(struct tty_struct * tty,
960/* 1006/*
961 * Put character routine for 3215 ttys 1007 * Put character routine for 3215 ttys
962 */ 1008 */
963static int 1009static int tty3215_put_char(struct tty_struct *tty, unsigned char ch)
964tty3215_put_char(struct tty_struct *tty, unsigned char ch)
965{ 1010{
966 struct raw3215_info *raw; 1011 struct raw3215_info *raw;
967 1012
@@ -972,16 +1017,14 @@ tty3215_put_char(struct tty_struct *tty, unsigned char ch)
972 return 1; 1017 return 1;
973} 1018}
974 1019
975static void 1020static void tty3215_flush_chars(struct tty_struct *tty)
976tty3215_flush_chars(struct tty_struct *tty)
977{ 1021{
978} 1022}
979 1023
980/* 1024/*
981 * Returns the number of characters in the output buffer 1025 * Returns the number of characters in the output buffer
982 */ 1026 */
983static int 1027static int tty3215_chars_in_buffer(struct tty_struct *tty)
984tty3215_chars_in_buffer(struct tty_struct *tty)
985{ 1028{
986 struct raw3215_info *raw; 1029 struct raw3215_info *raw;
987 1030
@@ -989,8 +1032,7 @@ tty3215_chars_in_buffer(struct tty_struct *tty)
989 return raw->count; 1032 return raw->count;
990} 1033}
991 1034
992static void 1035static void tty3215_flush_buffer(struct tty_struct *tty)
993tty3215_flush_buffer(struct tty_struct *tty)
994{ 1036{
995 struct raw3215_info *raw; 1037 struct raw3215_info *raw;
996 1038
@@ -1002,9 +1044,8 @@ tty3215_flush_buffer(struct tty_struct *tty)
1002/* 1044/*
1003 * Currently we don't have any io controls for 3215 ttys 1045 * Currently we don't have any io controls for 3215 ttys
1004 */ 1046 */
1005static int 1047static int tty3215_ioctl(struct tty_struct *tty, struct file * file,
1006tty3215_ioctl(struct tty_struct *tty, struct file * file, 1048 unsigned int cmd, unsigned long arg)
1007 unsigned int cmd, unsigned long arg)
1008{ 1049{
1009 if (tty->flags & (1 << TTY_IO_ERROR)) 1050 if (tty->flags & (1 << TTY_IO_ERROR))
1010 return -EIO; 1051 return -EIO;
@@ -1019,8 +1060,7 @@ tty3215_ioctl(struct tty_struct *tty, struct file * file,
1019/* 1060/*
1020 * Disable reading from a 3215 tty 1061 * Disable reading from a 3215 tty
1021 */ 1062 */
1022static void 1063static void tty3215_throttle(struct tty_struct * tty)
1023tty3215_throttle(struct tty_struct * tty)
1024{ 1064{
1025 struct raw3215_info *raw; 1065 struct raw3215_info *raw;
1026 1066
@@ -1031,8 +1071,7 @@ tty3215_throttle(struct tty_struct * tty)
1031/* 1071/*
1032 * Enable reading from a 3215 tty 1072 * Enable reading from a 3215 tty
1033 */ 1073 */
1034static void 1074static void tty3215_unthrottle(struct tty_struct * tty)
1035tty3215_unthrottle(struct tty_struct * tty)
1036{ 1075{
1037 struct raw3215_info *raw; 1076 struct raw3215_info *raw;
1038 unsigned long flags; 1077 unsigned long flags;
@@ -1049,8 +1088,7 @@ tty3215_unthrottle(struct tty_struct * tty)
1049/* 1088/*
1050 * Disable writing to a 3215 tty 1089 * Disable writing to a 3215 tty
1051 */ 1090 */
1052static void 1091static void tty3215_stop(struct tty_struct *tty)
1053tty3215_stop(struct tty_struct *tty)
1054{ 1092{
1055 struct raw3215_info *raw; 1093 struct raw3215_info *raw;
1056 1094
@@ -1061,8 +1099,7 @@ tty3215_stop(struct tty_struct *tty)
1061/* 1099/*
1062 * Enable writing to a 3215 tty 1100 * Enable writing to a 3215 tty
1063 */ 1101 */
1064static void 1102static void tty3215_start(struct tty_struct *tty)
1065tty3215_start(struct tty_struct *tty)
1066{ 1103{
1067 struct raw3215_info *raw; 1104 struct raw3215_info *raw;
1068 unsigned long flags; 1105 unsigned long flags;
@@ -1096,8 +1133,7 @@ static const struct tty_operations tty3215_ops = {
1096 * 3215 tty registration code called from tty_init(). 1133 * 3215 tty registration code called from tty_init().
1097 * Most kernel services (incl. kmalloc) are available at this poimt. 1134 * Most kernel services (incl. kmalloc) are available at this poimt.
1098 */ 1135 */
1099static int __init 1136static int __init tty3215_init(void)
1100tty3215_init(void)
1101{ 1137{
1102 struct tty_driver *driver; 1138 struct tty_driver *driver;
1103 int ret; 1139 int ret;
@@ -1142,8 +1178,7 @@ tty3215_init(void)
1142 return 0; 1178 return 0;
1143} 1179}
1144 1180
1145static void __exit 1181static void __exit tty3215_exit(void)
1146tty3215_exit(void)
1147{ 1182{
1148 tty_unregister_driver(tty3215_driver); 1183 tty_unregister_driver(tty3215_driver);
1149 put_tty_driver(tty3215_driver); 1184 put_tty_driver(tty3215_driver);
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index d028d2ee83dd..44d02e371c04 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/con3270.c 2 * IBM/3270 Driver - console view.
3 * IBM/3270 Driver - console view.
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <linux/bootmem.h> 10#include <linux/bootmem.h>
@@ -64,7 +63,7 @@ static struct con3270 *condev;
64#define CON_UPDATE_ERASE 1 /* Use EWRITEA instead of WRITE. */ 63#define CON_UPDATE_ERASE 1 /* Use EWRITEA instead of WRITE. */
65#define CON_UPDATE_LIST 2 /* Update lines in tty3270->update. */ 64#define CON_UPDATE_LIST 2 /* Update lines in tty3270->update. */
66#define CON_UPDATE_STATUS 4 /* Update status line. */ 65#define CON_UPDATE_STATUS 4 /* Update status line. */
67#define CON_UPDATE_ALL 7 66#define CON_UPDATE_ALL 8 /* Recreate screen. */
68 67
69static void con3270_update(struct con3270 *); 68static void con3270_update(struct con3270 *);
70 69
@@ -73,18 +72,10 @@ static void con3270_update(struct con3270 *);
73 */ 72 */
74static void con3270_set_timer(struct con3270 *cp, int expires) 73static void con3270_set_timer(struct con3270 *cp, int expires)
75{ 74{
76 if (expires == 0) { 75 if (expires == 0)
77 if (timer_pending(&cp->timer)) 76 del_timer(&cp->timer);
78 del_timer(&cp->timer); 77 else
79 return; 78 mod_timer(&cp->timer, jiffies + expires);
80 }
81 if (timer_pending(&cp->timer) &&
82 mod_timer(&cp->timer, jiffies + expires))
83 return;
84 cp->timer.function = (void (*)(unsigned long)) con3270_update;
85 cp->timer.data = (unsigned long) cp;
86 cp->timer.expires = jiffies + expires;
87 add_timer(&cp->timer);
88} 79}
89 80
90/* 81/*
@@ -225,6 +216,12 @@ con3270_update(struct con3270 *cp)
225 216
226 spin_lock_irqsave(&cp->view.lock, flags); 217 spin_lock_irqsave(&cp->view.lock, flags);
227 updated = 0; 218 updated = 0;
219 if (cp->update_flags & CON_UPDATE_ALL) {
220 con3270_rebuild_update(cp);
221 con3270_update_status(cp);
222 cp->update_flags = CON_UPDATE_ERASE | CON_UPDATE_LIST |
223 CON_UPDATE_STATUS;
224 }
228 if (cp->update_flags & CON_UPDATE_ERASE) { 225 if (cp->update_flags & CON_UPDATE_ERASE) {
229 /* Use erase write alternate to initialize display. */ 226 /* Use erase write alternate to initialize display. */
230 raw3270_request_set_cmd(wrq, TC_EWRITEA); 227 raw3270_request_set_cmd(wrq, TC_EWRITEA);
@@ -302,7 +299,6 @@ con3270_read_tasklet(struct raw3270_request *rrq)
302 deactivate = 1; 299 deactivate = 1;
303 break; 300 break;
304 case 0x6d: /* clear: start from scratch. */ 301 case 0x6d: /* clear: start from scratch. */
305 con3270_rebuild_update(cp);
306 cp->update_flags = CON_UPDATE_ALL; 302 cp->update_flags = CON_UPDATE_ALL;
307 con3270_set_timer(cp, 1); 303 con3270_set_timer(cp, 1);
308 break; 304 break;
@@ -382,30 +378,21 @@ con3270_issue_read(struct con3270 *cp)
382static int 378static int
383con3270_activate(struct raw3270_view *view) 379con3270_activate(struct raw3270_view *view)
384{ 380{
385 unsigned long flags;
386 struct con3270 *cp; 381 struct con3270 *cp;
387 382
388 cp = (struct con3270 *) view; 383 cp = (struct con3270 *) view;
389 spin_lock_irqsave(&cp->view.lock, flags);
390 cp->nr_up = 0;
391 con3270_rebuild_update(cp);
392 con3270_update_status(cp);
393 cp->update_flags = CON_UPDATE_ALL; 384 cp->update_flags = CON_UPDATE_ALL;
394 con3270_set_timer(cp, 1); 385 con3270_set_timer(cp, 1);
395 spin_unlock_irqrestore(&cp->view.lock, flags);
396 return 0; 386 return 0;
397} 387}
398 388
399static void 389static void
400con3270_deactivate(struct raw3270_view *view) 390con3270_deactivate(struct raw3270_view *view)
401{ 391{
402 unsigned long flags;
403 struct con3270 *cp; 392 struct con3270 *cp;
404 393
405 cp = (struct con3270 *) view; 394 cp = (struct con3270 *) view;
406 spin_lock_irqsave(&cp->view.lock, flags);
407 del_timer(&cp->timer); 395 del_timer(&cp->timer);
408 spin_unlock_irqrestore(&cp->view.lock, flags);
409} 396}
410 397
411static int 398static int
@@ -504,6 +491,7 @@ con3270_write(struct console *co, const char *str, unsigned int count)
504 con3270_cline_end(cp); 491 con3270_cline_end(cp);
505 } 492 }
506 /* Setup timer to output current console buffer after 1/10 second */ 493 /* Setup timer to output current console buffer after 1/10 second */
494 cp->nr_up = 0;
507 if (cp->view.dev && !timer_pending(&cp->timer)) 495 if (cp->view.dev && !timer_pending(&cp->timer))
508 con3270_set_timer(cp, HZ/10); 496 con3270_set_timer(cp, HZ/10);
509 spin_unlock_irqrestore(&cp->view.lock,flags); 497 spin_unlock_irqrestore(&cp->view.lock,flags);
@@ -541,6 +529,7 @@ con3270_flush(void)
541 cp = condev; 529 cp = condev;
542 if (!cp->view.dev) 530 if (!cp->view.dev)
543 return; 531 return;
532 raw3270_pm_unfreeze(&cp->view);
544 spin_lock_irqsave(&cp->view.lock, flags); 533 spin_lock_irqsave(&cp->view.lock, flags);
545 con3270_wait_write(cp); 534 con3270_wait_write(cp);
546 cp->nr_up = 0; 535 cp->nr_up = 0;
@@ -624,7 +613,8 @@ con3270_init(void)
624 613
625 INIT_LIST_HEAD(&condev->lines); 614 INIT_LIST_HEAD(&condev->lines);
626 INIT_LIST_HEAD(&condev->update); 615 INIT_LIST_HEAD(&condev->update);
627 init_timer(&condev->timer); 616 setup_timer(&condev->timer, (void (*)(unsigned long)) con3270_update,
617 (unsigned long) condev);
628 tasklet_init(&condev->readlet, 618 tasklet_init(&condev->readlet,
629 (void (*)(unsigned long)) con3270_read_tasklet, 619 (void (*)(unsigned long)) con3270_read_tasklet,
630 (unsigned long) condev->read); 620 (unsigned long) condev->read);
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 40759c33477d..097d3846a828 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/fs3270.c 2 * IBM/3270 Driver - fullscreen driver.
3 * IBM/3270 Driver - fullscreen driver.
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <linux/bootmem.h> 10#include <linux/bootmem.h>
@@ -399,6 +398,11 @@ fs3270_free_view(struct raw3270_view *view)
399static void 398static void
400fs3270_release(struct raw3270_view *view) 399fs3270_release(struct raw3270_view *view)
401{ 400{
401 struct fs3270 *fp;
402
403 fp = (struct fs3270 *) view;
404 if (fp->fs_pid)
405 kill_pid(fp->fs_pid, SIGHUP, 1);
402} 406}
403 407
404/* View to a 3270 device. Can be console, tty or fullscreen. */ 408/* View to a 3270 device. Can be console, tty or fullscreen. */
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index 97e63cf46944..75a8831eebbc 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -1,10 +1,9 @@
1/* 1/*
2 * drivers/s390/char/monreader.c
3 *
4 * Character device driver for reading z/VM *MONITOR service records. 2 * Character device driver for reading z/VM *MONITOR service records.
5 * 3 *
6 * Copyright IBM Corp. 2004, 2008 4 * Copyright IBM Corp. 2004, 2009
7 * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> 5 *
6 * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
8 */ 7 */
9 8
10#define KMSG_COMPONENT "monreader" 9#define KMSG_COMPONENT "monreader"
@@ -22,6 +21,7 @@
22#include <linux/spinlock.h> 21#include <linux/spinlock.h>
23#include <linux/interrupt.h> 22#include <linux/interrupt.h>
24#include <linux/poll.h> 23#include <linux/poll.h>
24#include <linux/device.h>
25#include <net/iucv/iucv.h> 25#include <net/iucv/iucv.h>
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/ebcdic.h> 27#include <asm/ebcdic.h>
@@ -78,6 +78,7 @@ static u8 user_data_sever[16] = {
78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79}; 79};
80 80
81static struct device *monreader_device;
81 82
82/****************************************************************************** 83/******************************************************************************
83 * helper functions * 84 * helper functions *
@@ -319,11 +320,12 @@ static int mon_open(struct inode *inode, struct file *filp)
319 goto out_path; 320 goto out_path;
320 } 321 }
321 filp->private_data = monpriv; 322 filp->private_data = monpriv;
323 monreader_device->driver_data = monpriv;
322 unlock_kernel(); 324 unlock_kernel();
323 return nonseekable_open(inode, filp); 325 return nonseekable_open(inode, filp);
324 326
325out_path: 327out_path:
326 kfree(monpriv->path); 328 iucv_path_free(monpriv->path);
327out_priv: 329out_priv:
328 mon_free_mem(monpriv); 330 mon_free_mem(monpriv);
329out_use: 331out_use:
@@ -341,10 +343,13 @@ static int mon_close(struct inode *inode, struct file *filp)
341 /* 343 /*
342 * Close IUCV connection and unregister 344 * Close IUCV connection and unregister
343 */ 345 */
344 rc = iucv_path_sever(monpriv->path, user_data_sever); 346 if (monpriv->path) {
345 if (rc) 347 rc = iucv_path_sever(monpriv->path, user_data_sever);
346 pr_warning("Disconnecting the z/VM *MONITOR system service " 348 if (rc)
347 "failed with rc=%i\n", rc); 349 pr_warning("Disconnecting the z/VM *MONITOR system "
350 "service failed with rc=%i\n", rc);
351 iucv_path_free(monpriv->path);
352 }
348 353
349 atomic_set(&monpriv->iucv_severed, 0); 354 atomic_set(&monpriv->iucv_severed, 0);
350 atomic_set(&monpriv->iucv_connected, 0); 355 atomic_set(&monpriv->iucv_connected, 0);
@@ -452,6 +457,94 @@ static struct miscdevice mon_dev = {
452 .minor = MISC_DYNAMIC_MINOR, 457 .minor = MISC_DYNAMIC_MINOR,
453}; 458};
454 459
460
461/******************************************************************************
462 * suspend / resume *
463 *****************************************************************************/
464static int monreader_freeze(struct device *dev)
465{
466 struct mon_private *monpriv = dev->driver_data;
467 int rc;
468
469 if (!monpriv)
470 return 0;
471 if (monpriv->path) {
472 rc = iucv_path_sever(monpriv->path, user_data_sever);
473 if (rc)
474 pr_warning("Disconnecting the z/VM *MONITOR system "
475 "service failed with rc=%i\n", rc);
476 iucv_path_free(monpriv->path);
477 }
478 atomic_set(&monpriv->iucv_severed, 0);
479 atomic_set(&monpriv->iucv_connected, 0);
480 atomic_set(&monpriv->read_ready, 0);
481 atomic_set(&monpriv->msglim_count, 0);
482 monpriv->write_index = 0;
483 monpriv->read_index = 0;
484 monpriv->path = NULL;
485 return 0;
486}
487
488static int monreader_thaw(struct device *dev)
489{
490 struct mon_private *monpriv = dev->driver_data;
491 int rc;
492
493 if (!monpriv)
494 return 0;
495 rc = -ENOMEM;
496 monpriv->path = iucv_path_alloc(MON_MSGLIM, IUCV_IPRMDATA, GFP_KERNEL);
497 if (!monpriv->path)
498 goto out;
499 rc = iucv_path_connect(monpriv->path, &monreader_iucv_handler,
500 MON_SERVICE, NULL, user_data_connect, monpriv);
501 if (rc) {
502 pr_err("Connecting to the z/VM *MONITOR system service "
503 "failed with rc=%i\n", rc);
504 goto out_path;
505 }
506 wait_event(mon_conn_wait_queue,
507 atomic_read(&monpriv->iucv_connected) ||
508 atomic_read(&monpriv->iucv_severed));
509 if (atomic_read(&monpriv->iucv_severed))
510 goto out_path;
511 return 0;
512out_path:
513 rc = -EIO;
514 iucv_path_free(monpriv->path);
515 monpriv->path = NULL;
516out:
517 atomic_set(&monpriv->iucv_severed, 1);
518 return rc;
519}
520
521static int monreader_restore(struct device *dev)
522{
523 int rc;
524
525 segment_unload(mon_dcss_name);
526 rc = segment_load(mon_dcss_name, SEGMENT_SHARED,
527 &mon_dcss_start, &mon_dcss_end);
528 if (rc < 0) {
529 segment_warning(rc, mon_dcss_name);
530 panic("fatal monreader resume error: no monitor dcss\n");
531 }
532 return monreader_thaw(dev);
533}
534
535static struct dev_pm_ops monreader_pm_ops = {
536 .freeze = monreader_freeze,
537 .thaw = monreader_thaw,
538 .restore = monreader_restore,
539};
540
541static struct device_driver monreader_driver = {
542 .name = "monreader",
543 .bus = &iucv_bus,
544 .pm = &monreader_pm_ops,
545};
546
547
455/****************************************************************************** 548/******************************************************************************
456 * module init/exit * 549 * module init/exit *
457 *****************************************************************************/ 550 *****************************************************************************/
@@ -475,16 +568,33 @@ static int __init mon_init(void)
475 return rc; 568 return rc;
476 } 569 }
477 570
571 rc = driver_register(&monreader_driver);
572 if (rc)
573 goto out_iucv;
574 monreader_device = kzalloc(sizeof(struct device), GFP_KERNEL);
575 if (!monreader_device)
576 goto out_driver;
577 dev_set_name(monreader_device, "monreader-dev");
578 monreader_device->bus = &iucv_bus;
579 monreader_device->parent = iucv_root;
580 monreader_device->driver = &monreader_driver;
581 monreader_device->release = (void (*)(struct device *))kfree;
582 rc = device_register(monreader_device);
583 if (rc) {
584 kfree(monreader_device);
585 goto out_driver;
586 }
587
478 rc = segment_type(mon_dcss_name); 588 rc = segment_type(mon_dcss_name);
479 if (rc < 0) { 589 if (rc < 0) {
480 segment_warning(rc, mon_dcss_name); 590 segment_warning(rc, mon_dcss_name);
481 goto out_iucv; 591 goto out_device;
482 } 592 }
483 if (rc != SEG_TYPE_SC) { 593 if (rc != SEG_TYPE_SC) {
484 pr_err("The specified *MONITOR DCSS %s does not have the " 594 pr_err("The specified *MONITOR DCSS %s does not have the "
485 "required type SC\n", mon_dcss_name); 595 "required type SC\n", mon_dcss_name);
486 rc = -EINVAL; 596 rc = -EINVAL;
487 goto out_iucv; 597 goto out_device;
488 } 598 }
489 599
490 rc = segment_load(mon_dcss_name, SEGMENT_SHARED, 600 rc = segment_load(mon_dcss_name, SEGMENT_SHARED,
@@ -492,7 +602,7 @@ static int __init mon_init(void)
492 if (rc < 0) { 602 if (rc < 0) {
493 segment_warning(rc, mon_dcss_name); 603 segment_warning(rc, mon_dcss_name);
494 rc = -EINVAL; 604 rc = -EINVAL;
495 goto out_iucv; 605 goto out_device;
496 } 606 }
497 dcss_mkname(mon_dcss_name, &user_data_connect[8]); 607 dcss_mkname(mon_dcss_name, &user_data_connect[8]);
498 608
@@ -503,6 +613,10 @@ static int __init mon_init(void)
503 613
504out: 614out:
505 segment_unload(mon_dcss_name); 615 segment_unload(mon_dcss_name);
616out_device:
617 device_unregister(monreader_device);
618out_driver:
619 driver_unregister(&monreader_driver);
506out_iucv: 620out_iucv:
507 iucv_unregister(&monreader_iucv_handler, 1); 621 iucv_unregister(&monreader_iucv_handler, 1);
508 return rc; 622 return rc;
@@ -512,6 +626,8 @@ static void __exit mon_exit(void)
512{ 626{
513 segment_unload(mon_dcss_name); 627 segment_unload(mon_dcss_name);
514 WARN_ON(misc_deregister(&mon_dev) != 0); 628 WARN_ON(misc_deregister(&mon_dev) != 0);
629 device_unregister(monreader_device);
630 driver_unregister(&monreader_driver);
515 iucv_unregister(&monreader_iucv_handler, 1); 631 iucv_unregister(&monreader_iucv_handler, 1);
516 return; 632 return;
517} 633}
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index c7d7483bab9a..66fb8eba93f4 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * drivers/s390/char/monwriter.c
3 *
4 * Character device driver for writing z/VM *MONITOR service records. 2 * Character device driver for writing z/VM *MONITOR service records.
5 * 3 *
6 * Copyright (C) IBM Corp. 2006 4 * Copyright IBM Corp. 2006, 2009
7 * 5 *
8 * Author(s): Melissa Howland <Melissa.Howland@us.ibm.com> 6 * Author(s): Melissa Howland <Melissa.Howland@us.ibm.com>
9 */ 7 */
@@ -22,6 +20,7 @@
22#include <linux/ctype.h> 20#include <linux/ctype.h>
23#include <linux/poll.h> 21#include <linux/poll.h>
24#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/platform_device.h>
25#include <asm/uaccess.h> 24#include <asm/uaccess.h>
26#include <asm/ebcdic.h> 25#include <asm/ebcdic.h>
27#include <asm/io.h> 26#include <asm/io.h>
@@ -40,7 +39,10 @@ struct mon_buf {
40 char *data; 39 char *data;
41}; 40};
42 41
42static LIST_HEAD(mon_priv_list);
43
43struct mon_private { 44struct mon_private {
45 struct list_head priv_list;
44 struct list_head list; 46 struct list_head list;
45 struct monwrite_hdr hdr; 47 struct monwrite_hdr hdr;
46 size_t hdr_to_read; 48 size_t hdr_to_read;
@@ -188,6 +190,7 @@ static int monwrite_open(struct inode *inode, struct file *filp)
188 monpriv->hdr_to_read = sizeof(monpriv->hdr); 190 monpriv->hdr_to_read = sizeof(monpriv->hdr);
189 mutex_init(&monpriv->thread_mutex); 191 mutex_init(&monpriv->thread_mutex);
190 filp->private_data = monpriv; 192 filp->private_data = monpriv;
193 list_add_tail(&monpriv->priv_list, &mon_priv_list);
191 unlock_kernel(); 194 unlock_kernel();
192 return nonseekable_open(inode, filp); 195 return nonseekable_open(inode, filp);
193} 196}
@@ -206,6 +209,7 @@ static int monwrite_close(struct inode *inode, struct file *filp)
206 kfree(entry->data); 209 kfree(entry->data);
207 kfree(entry); 210 kfree(entry);
208 } 211 }
212 list_del(&monpriv->priv_list);
209 kfree(monpriv); 213 kfree(monpriv);
210 return 0; 214 return 0;
211} 215}
@@ -281,20 +285,102 @@ static struct miscdevice mon_dev = {
281}; 285};
282 286
283/* 287/*
288 * suspend/resume
289 */
290
291static int monwriter_freeze(struct device *dev)
292{
293 struct mon_private *monpriv;
294 struct mon_buf *monbuf;
295
296 list_for_each_entry(monpriv, &mon_priv_list, priv_list) {
297 list_for_each_entry(monbuf, &monpriv->list, list) {
298 if (monbuf->hdr.mon_function != MONWRITE_GEN_EVENT)
299 monwrite_diag(&monbuf->hdr, monbuf->data,
300 APPLDATA_STOP_REC);
301 }
302 }
303 return 0;
304}
305
306static int monwriter_restore(struct device *dev)
307{
308 struct mon_private *monpriv;
309 struct mon_buf *monbuf;
310
311 list_for_each_entry(monpriv, &mon_priv_list, priv_list) {
312 list_for_each_entry(monbuf, &monpriv->list, list) {
313 if (monbuf->hdr.mon_function == MONWRITE_START_INTERVAL)
314 monwrite_diag(&monbuf->hdr, monbuf->data,
315 APPLDATA_START_INTERVAL_REC);
316 if (monbuf->hdr.mon_function == MONWRITE_START_CONFIG)
317 monwrite_diag(&monbuf->hdr, monbuf->data,
318 APPLDATA_START_CONFIG_REC);
319 }
320 }
321 return 0;
322}
323
324static int monwriter_thaw(struct device *dev)
325{
326 return monwriter_restore(dev);
327}
328
329static struct dev_pm_ops monwriter_pm_ops = {
330 .freeze = monwriter_freeze,
331 .thaw = monwriter_thaw,
332 .restore = monwriter_restore,
333};
334
335static struct platform_driver monwriter_pdrv = {
336 .driver = {
337 .name = "monwriter",
338 .owner = THIS_MODULE,
339 .pm = &monwriter_pm_ops,
340 },
341};
342
343static struct platform_device *monwriter_pdev;
344
345/*
284 * module init/exit 346 * module init/exit
285 */ 347 */
286 348
287static int __init mon_init(void) 349static int __init mon_init(void)
288{ 350{
289 if (MACHINE_IS_VM) 351 int rc;
290 return misc_register(&mon_dev); 352
291 else 353 if (!MACHINE_IS_VM)
292 return -ENODEV; 354 return -ENODEV;
355
356 rc = platform_driver_register(&monwriter_pdrv);
357 if (rc)
358 return rc;
359
360 monwriter_pdev = platform_device_register_simple("monwriter", -1, NULL,
361 0);
362 if (IS_ERR(monwriter_pdev)) {
363 rc = PTR_ERR(monwriter_pdev);
364 goto out_driver;
365 }
366
367 rc = misc_register(&mon_dev);
368 if (rc)
369 goto out_device;
370 return 0;
371
372out_device:
373 platform_device_unregister(monwriter_pdev);
374out_driver:
375 platform_driver_unregister(&monwriter_pdrv);
376 return rc;
293} 377}
294 378
295static void __exit mon_exit(void) 379static void __exit mon_exit(void)
296{ 380{
297 WARN_ON(misc_deregister(&mon_dev) != 0); 381 WARN_ON(misc_deregister(&mon_dev) != 0);
382 platform_device_unregister(monwriter_pdev);
383 platform_driver_unregister(&monwriter_pdrv);
298} 384}
299 385
300module_init(mon_init); 386module_init(mon_init);
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 0b15cf107ec9..acab7b2dfe8a 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/raw3270.c 2 * IBM/3270 Driver - core functions.
3 * IBM/3270 Driver - core functions.
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <linux/bootmem.h> 10#include <linux/bootmem.h>
@@ -61,6 +60,7 @@ struct raw3270 {
61#define RAW3270_FLAGS_ATTN 2 /* Device sent an ATTN interrupt */ 60#define RAW3270_FLAGS_ATTN 2 /* Device sent an ATTN interrupt */
62#define RAW3270_FLAGS_READY 4 /* Device is useable by views */ 61#define RAW3270_FLAGS_READY 4 /* Device is useable by views */
63#define RAW3270_FLAGS_CONSOLE 8 /* Device is the console. */ 62#define RAW3270_FLAGS_CONSOLE 8 /* Device is the console. */
63#define RAW3270_FLAGS_FROZEN 16 /* set if 3270 is frozen for suspend */
64 64
65/* Semaphore to protect global data of raw3270 (devices, views, etc). */ 65/* Semaphore to protect global data of raw3270 (devices, views, etc). */
66static DEFINE_MUTEX(raw3270_mutex); 66static DEFINE_MUTEX(raw3270_mutex);
@@ -306,7 +306,8 @@ raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
306 306
307 spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags); 307 spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);
308 rp = view->dev; 308 rp = view->dev;
309 if (!rp || rp->view != view) 309 if (!rp || rp->view != view ||
310 test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
310 rc = -EACCES; 311 rc = -EACCES;
311 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 312 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
312 rc = -ENODEV; 313 rc = -ENODEV;
@@ -323,7 +324,8 @@ raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
323 int rc; 324 int rc;
324 325
325 rp = view->dev; 326 rp = view->dev;
326 if (!rp || rp->view != view) 327 if (!rp || rp->view != view ||
328 test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
327 rc = -EACCES; 329 rc = -EACCES;
328 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 330 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
329 rc = -ENODEV; 331 rc = -ENODEV;
@@ -355,7 +357,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
355 struct raw3270_request *rq; 357 struct raw3270_request *rq;
356 int rc; 358 int rc;
357 359
358 rp = (struct raw3270 *) cdev->dev.driver_data; 360 rp = dev_get_drvdata(&cdev->dev);
359 if (!rp) 361 if (!rp)
360 return; 362 return;
361 rq = (struct raw3270_request *) intparm; 363 rq = (struct raw3270_request *) intparm;
@@ -764,7 +766,8 @@ raw3270_reset(struct raw3270_view *view)
764 int rc; 766 int rc;
765 767
766 rp = view->dev; 768 rp = view->dev;
767 if (!rp || rp->view != view) 769 if (!rp || rp->view != view ||
770 test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
768 rc = -EACCES; 771 rc = -EACCES;
769 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 772 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
770 rc = -ENODEV; 773 rc = -ENODEV;
@@ -828,7 +831,7 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
828 if (rp->minor == -1) 831 if (rp->minor == -1)
829 return -EUSERS; 832 return -EUSERS;
830 rp->cdev = cdev; 833 rp->cdev = cdev;
831 cdev->dev.driver_data = rp; 834 dev_set_drvdata(&cdev->dev, rp);
832 cdev->handler = raw3270_irq; 835 cdev->handler = raw3270_irq;
833 return 0; 836 return 0;
834} 837}
@@ -922,6 +925,8 @@ raw3270_activate_view(struct raw3270_view *view)
922 rc = 0; 925 rc = 0;
923 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 926 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
924 rc = -ENODEV; 927 rc = -ENODEV;
928 else if (test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
929 rc = -EACCES;
925 else { 930 else {
926 oldview = NULL; 931 oldview = NULL;
927 if (rp->view) { 932 if (rp->view) {
@@ -969,7 +974,8 @@ raw3270_deactivate_view(struct raw3270_view *view)
969 list_del_init(&view->list); 974 list_del_init(&view->list);
970 list_add_tail(&view->list, &rp->view_list); 975 list_add_tail(&view->list, &rp->view_list);
971 /* Try to activate another view. */ 976 /* Try to activate another view. */
972 if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) { 977 if (test_bit(RAW3270_FLAGS_READY, &rp->flags) &&
978 !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
973 list_for_each_entry(view, &rp->view_list, list) { 979 list_for_each_entry(view, &rp->view_list, list) {
974 rp->view = view; 980 rp->view = view;
975 if (view->fn->activate(view) == 0) 981 if (view->fn->activate(view) == 0)
@@ -1068,7 +1074,8 @@ raw3270_del_view(struct raw3270_view *view)
1068 rp->view = NULL; 1074 rp->view = NULL;
1069 } 1075 }
1070 list_del_init(&view->list); 1076 list_del_init(&view->list);
1071 if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) { 1077 if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags) &&
1078 !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
1072 /* Try to activate another view. */ 1079 /* Try to activate another view. */
1073 list_for_each_entry(nv, &rp->view_list, list) { 1080 list_for_each_entry(nv, &rp->view_list, list) {
1074 if (nv->fn->activate(nv) == 0) { 1081 if (nv->fn->activate(nv) == 0) {
@@ -1105,7 +1112,7 @@ raw3270_delete_device(struct raw3270 *rp)
1105 /* Disconnect from ccw_device. */ 1112 /* Disconnect from ccw_device. */
1106 cdev = rp->cdev; 1113 cdev = rp->cdev;
1107 rp->cdev = NULL; 1114 rp->cdev = NULL;
1108 cdev->dev.driver_data = NULL; 1115 dev_set_drvdata(&cdev->dev, NULL);
1109 cdev->handler = NULL; 1116 cdev->handler = NULL;
1110 1117
1111 /* Put ccw_device structure. */ 1118 /* Put ccw_device structure. */
@@ -1129,7 +1136,7 @@ static ssize_t
1129raw3270_model_show(struct device *dev, struct device_attribute *attr, char *buf) 1136raw3270_model_show(struct device *dev, struct device_attribute *attr, char *buf)
1130{ 1137{
1131 return snprintf(buf, PAGE_SIZE, "%i\n", 1138 return snprintf(buf, PAGE_SIZE, "%i\n",
1132 ((struct raw3270 *) dev->driver_data)->model); 1139 ((struct raw3270 *) dev_get_drvdata(dev))->model);
1133} 1140}
1134static DEVICE_ATTR(model, 0444, raw3270_model_show, NULL); 1141static DEVICE_ATTR(model, 0444, raw3270_model_show, NULL);
1135 1142
@@ -1137,7 +1144,7 @@ static ssize_t
1137raw3270_rows_show(struct device *dev, struct device_attribute *attr, char *buf) 1144raw3270_rows_show(struct device *dev, struct device_attribute *attr, char *buf)
1138{ 1145{
1139 return snprintf(buf, PAGE_SIZE, "%i\n", 1146 return snprintf(buf, PAGE_SIZE, "%i\n",
1140 ((struct raw3270 *) dev->driver_data)->rows); 1147 ((struct raw3270 *) dev_get_drvdata(dev))->rows);
1141} 1148}
1142static DEVICE_ATTR(rows, 0444, raw3270_rows_show, NULL); 1149static DEVICE_ATTR(rows, 0444, raw3270_rows_show, NULL);
1143 1150
@@ -1145,7 +1152,7 @@ static ssize_t
1145raw3270_columns_show(struct device *dev, struct device_attribute *attr, char *buf) 1152raw3270_columns_show(struct device *dev, struct device_attribute *attr, char *buf)
1146{ 1153{
1147 return snprintf(buf, PAGE_SIZE, "%i\n", 1154 return snprintf(buf, PAGE_SIZE, "%i\n",
1148 ((struct raw3270 *) dev->driver_data)->cols); 1155 ((struct raw3270 *) dev_get_drvdata(dev))->cols);
1149} 1156}
1150static DEVICE_ATTR(columns, 0444, raw3270_columns_show, NULL); 1157static DEVICE_ATTR(columns, 0444, raw3270_columns_show, NULL);
1151 1158
@@ -1282,7 +1289,7 @@ raw3270_remove (struct ccw_device *cdev)
1282 struct raw3270_view *v; 1289 struct raw3270_view *v;
1283 struct raw3270_notifier *np; 1290 struct raw3270_notifier *np;
1284 1291
1285 rp = cdev->dev.driver_data; 1292 rp = dev_get_drvdata(&cdev->dev);
1286 /* 1293 /*
1287 * _remove is the opposite of _probe; it's probe that 1294 * _remove is the opposite of _probe; it's probe that
1288 * should set up rp. raw3270_remove gets entered for 1295 * should set up rp. raw3270_remove gets entered for
@@ -1330,13 +1337,65 @@ raw3270_set_offline (struct ccw_device *cdev)
1330{ 1337{
1331 struct raw3270 *rp; 1338 struct raw3270 *rp;
1332 1339
1333 rp = cdev->dev.driver_data; 1340 rp = dev_get_drvdata(&cdev->dev);
1334 if (test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags)) 1341 if (test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags))
1335 return -EBUSY; 1342 return -EBUSY;
1336 raw3270_remove(cdev); 1343 raw3270_remove(cdev);
1337 return 0; 1344 return 0;
1338} 1345}
1339 1346
1347static int raw3270_pm_stop(struct ccw_device *cdev)
1348{
1349 struct raw3270 *rp;
1350 struct raw3270_view *view;
1351 unsigned long flags;
1352
1353 rp = cdev->dev.driver_data;
1354 if (!rp)
1355 return 0;
1356 spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1357 if (rp->view)
1358 rp->view->fn->deactivate(rp->view);
1359 if (!test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags)) {
1360 /*
1361 * Release tty and fullscreen for all non-console
1362 * devices.
1363 */
1364 list_for_each_entry(view, &rp->view_list, list) {
1365 if (view->fn->release)
1366 view->fn->release(view);
1367 }
1368 }
1369 set_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
1370 spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1371 return 0;
1372}
1373
1374static int raw3270_pm_start(struct ccw_device *cdev)
1375{
1376 struct raw3270 *rp;
1377 unsigned long flags;
1378
1379 rp = cdev->dev.driver_data;
1380 if (!rp)
1381 return 0;
1382 spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1383 clear_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
1384 if (rp->view)
1385 rp->view->fn->activate(rp->view);
1386 spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1387 return 0;
1388}
1389
1390void raw3270_pm_unfreeze(struct raw3270_view *view)
1391{
1392 struct raw3270 *rp;
1393
1394 rp = view->dev;
1395 if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
1396 ccw_device_force_console();
1397}
1398
1340static struct ccw_device_id raw3270_id[] = { 1399static struct ccw_device_id raw3270_id[] = {
1341 { CCW_DEVICE(0x3270, 0) }, 1400 { CCW_DEVICE(0x3270, 0) },
1342 { CCW_DEVICE(0x3271, 0) }, 1401 { CCW_DEVICE(0x3271, 0) },
@@ -1360,6 +1419,9 @@ static struct ccw_driver raw3270_ccw_driver = {
1360 .remove = &raw3270_remove, 1419 .remove = &raw3270_remove,
1361 .set_online = &raw3270_set_online, 1420 .set_online = &raw3270_set_online,
1362 .set_offline = &raw3270_set_offline, 1421 .set_offline = &raw3270_set_offline,
1422 .freeze = &raw3270_pm_stop,
1423 .thaw = &raw3270_pm_start,
1424 .restore = &raw3270_pm_start,
1363}; 1425};
1364 1426
1365static int 1427static int
diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
index 90beaa80a782..ed34eb2199cc 100644
--- a/drivers/s390/char/raw3270.h
+++ b/drivers/s390/char/raw3270.h
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/raw3270.h 2 * IBM/3270 Driver
3 * IBM/3270 Driver
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <asm/idals.h> 10#include <asm/idals.h>
@@ -195,6 +194,7 @@ void raw3270_wait_cons_dev(struct raw3270 *);
195/* Notifier for device addition/removal */ 194/* Notifier for device addition/removal */
196int raw3270_register_notifier(void (*notifier)(int, int)); 195int raw3270_register_notifier(void (*notifier)(int, int));
197void raw3270_unregister_notifier(void (*notifier)(int, int)); 196void raw3270_unregister_notifier(void (*notifier)(int, int));
197void raw3270_pm_unfreeze(struct raw3270_view *);
198 198
199/* 199/*
200 * Little memory allocator for string objects. 200 * Little memory allocator for string objects.
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 4377e93a43d7..a983f5086788 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/sclp.c 2 * core function to access sclp interface
3 * core function to access sclp interface
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 1999, 2009
6 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 *
7 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 6 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
9 */ 8 */
10 9
11#include <linux/module.h> 10#include <linux/module.h>
@@ -16,6 +15,9 @@
16#include <linux/reboot.h> 15#include <linux/reboot.h>
17#include <linux/jiffies.h> 16#include <linux/jiffies.h>
18#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/suspend.h>
19#include <linux/completion.h>
20#include <linux/platform_device.h>
19#include <asm/types.h> 21#include <asm/types.h>
20#include <asm/s390_ext.h> 22#include <asm/s390_ext.h>
21 23
@@ -47,6 +49,16 @@ static struct sclp_req sclp_init_req;
47static char sclp_read_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); 49static char sclp_read_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
48static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); 50static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
49 51
52/* Suspend request */
53static DECLARE_COMPLETION(sclp_request_queue_flushed);
54
55static void sclp_suspend_req_cb(struct sclp_req *req, void *data)
56{
57 complete(&sclp_request_queue_flushed);
58}
59
60static struct sclp_req sclp_suspend_req;
61
50/* Timer for request retries. */ 62/* Timer for request retries. */
51static struct timer_list sclp_request_timer; 63static struct timer_list sclp_request_timer;
52 64
@@ -84,6 +96,12 @@ static volatile enum sclp_mask_state_t {
84 sclp_mask_state_initializing 96 sclp_mask_state_initializing
85} sclp_mask_state = sclp_mask_state_idle; 97} sclp_mask_state = sclp_mask_state_idle;
86 98
99/* Internal state: is the driver suspended? */
100static enum sclp_suspend_state_t {
101 sclp_suspend_state_running,
102 sclp_suspend_state_suspended,
103} sclp_suspend_state = sclp_suspend_state_running;
104
87/* Maximum retry counts */ 105/* Maximum retry counts */
88#define SCLP_INIT_RETRY 3 106#define SCLP_INIT_RETRY 3
89#define SCLP_MASK_RETRY 3 107#define SCLP_MASK_RETRY 3
@@ -211,6 +229,8 @@ sclp_process_queue(void)
211 del_timer(&sclp_request_timer); 229 del_timer(&sclp_request_timer);
212 while (!list_empty(&sclp_req_queue)) { 230 while (!list_empty(&sclp_req_queue)) {
213 req = list_entry(sclp_req_queue.next, struct sclp_req, list); 231 req = list_entry(sclp_req_queue.next, struct sclp_req, list);
232 if (!req->sccb)
233 goto do_post;
214 rc = __sclp_start_request(req); 234 rc = __sclp_start_request(req);
215 if (rc == 0) 235 if (rc == 0)
216 break; 236 break;
@@ -222,6 +242,7 @@ sclp_process_queue(void)
222 sclp_request_timeout, 0); 242 sclp_request_timeout, 0);
223 break; 243 break;
224 } 244 }
245do_post:
225 /* Post-processing for aborted request */ 246 /* Post-processing for aborted request */
226 list_del(&req->list); 247 list_del(&req->list);
227 if (req->callback) { 248 if (req->callback) {
@@ -233,6 +254,19 @@ sclp_process_queue(void)
233 spin_unlock_irqrestore(&sclp_lock, flags); 254 spin_unlock_irqrestore(&sclp_lock, flags);
234} 255}
235 256
257static int __sclp_can_add_request(struct sclp_req *req)
258{
259 if (req == &sclp_suspend_req || req == &sclp_init_req)
260 return 1;
261 if (sclp_suspend_state != sclp_suspend_state_running)
262 return 0;
263 if (sclp_init_state != sclp_init_state_initialized)
264 return 0;
265 if (sclp_activation_state != sclp_activation_state_active)
266 return 0;
267 return 1;
268}
269
236/* Queue a new request. Return zero on success, non-zero otherwise. */ 270/* Queue a new request. Return zero on success, non-zero otherwise. */
237int 271int
238sclp_add_request(struct sclp_req *req) 272sclp_add_request(struct sclp_req *req)
@@ -241,9 +275,7 @@ sclp_add_request(struct sclp_req *req)
241 int rc; 275 int rc;
242 276
243 spin_lock_irqsave(&sclp_lock, flags); 277 spin_lock_irqsave(&sclp_lock, flags);
244 if ((sclp_init_state != sclp_init_state_initialized || 278 if (!__sclp_can_add_request(req)) {
245 sclp_activation_state != sclp_activation_state_active) &&
246 req != &sclp_init_req) {
247 spin_unlock_irqrestore(&sclp_lock, flags); 279 spin_unlock_irqrestore(&sclp_lock, flags);
248 return -EIO; 280 return -EIO;
249 } 281 }
@@ -254,10 +286,16 @@ sclp_add_request(struct sclp_req *req)
254 /* Start if request is first in list */ 286 /* Start if request is first in list */
255 if (sclp_running_state == sclp_running_state_idle && 287 if (sclp_running_state == sclp_running_state_idle &&
256 req->list.prev == &sclp_req_queue) { 288 req->list.prev == &sclp_req_queue) {
289 if (!req->sccb) {
290 list_del(&req->list);
291 rc = -ENODATA;
292 goto out;
293 }
257 rc = __sclp_start_request(req); 294 rc = __sclp_start_request(req);
258 if (rc) 295 if (rc)
259 list_del(&req->list); 296 list_del(&req->list);
260 } 297 }
298out:
261 spin_unlock_irqrestore(&sclp_lock, flags); 299 spin_unlock_irqrestore(&sclp_lock, flags);
262 return rc; 300 return rc;
263} 301}
@@ -560,6 +598,7 @@ sclp_register(struct sclp_register *reg)
560 /* Trigger initial state change callback */ 598 /* Trigger initial state change callback */
561 reg->sclp_receive_mask = 0; 599 reg->sclp_receive_mask = 0;
562 reg->sclp_send_mask = 0; 600 reg->sclp_send_mask = 0;
601 reg->pm_event_posted = 0;
563 list_add(&reg->list, &sclp_reg_list); 602 list_add(&reg->list, &sclp_reg_list);
564 spin_unlock_irqrestore(&sclp_lock, flags); 603 spin_unlock_irqrestore(&sclp_lock, flags);
565 rc = sclp_init_mask(1); 604 rc = sclp_init_mask(1);
@@ -880,20 +919,134 @@ static struct notifier_block sclp_reboot_notifier = {
880 .notifier_call = sclp_reboot_event 919 .notifier_call = sclp_reboot_event
881}; 920};
882 921
922/*
923 * Suspend/resume SCLP notifier implementation
924 */
925
926static void sclp_pm_event(enum sclp_pm_event sclp_pm_event, int rollback)
927{
928 struct sclp_register *reg;
929 unsigned long flags;
930
931 if (!rollback) {
932 spin_lock_irqsave(&sclp_lock, flags);
933 list_for_each_entry(reg, &sclp_reg_list, list)
934 reg->pm_event_posted = 0;
935 spin_unlock_irqrestore(&sclp_lock, flags);
936 }
937 do {
938 spin_lock_irqsave(&sclp_lock, flags);
939 list_for_each_entry(reg, &sclp_reg_list, list) {
940 if (rollback && reg->pm_event_posted)
941 goto found;
942 if (!rollback && !reg->pm_event_posted)
943 goto found;
944 }
945 spin_unlock_irqrestore(&sclp_lock, flags);
946 return;
947found:
948 spin_unlock_irqrestore(&sclp_lock, flags);
949 if (reg->pm_event_fn)
950 reg->pm_event_fn(reg, sclp_pm_event);
951 reg->pm_event_posted = rollback ? 0 : 1;
952 } while (1);
953}
954
955/*
956 * Susend/resume callbacks for platform device
957 */
958
959static int sclp_freeze(struct device *dev)
960{
961 unsigned long flags;
962 int rc;
963
964 sclp_pm_event(SCLP_PM_EVENT_FREEZE, 0);
965
966 spin_lock_irqsave(&sclp_lock, flags);
967 sclp_suspend_state = sclp_suspend_state_suspended;
968 spin_unlock_irqrestore(&sclp_lock, flags);
969
970 /* Init supend data */
971 memset(&sclp_suspend_req, 0, sizeof(sclp_suspend_req));
972 sclp_suspend_req.callback = sclp_suspend_req_cb;
973 sclp_suspend_req.status = SCLP_REQ_FILLED;
974 init_completion(&sclp_request_queue_flushed);
975
976 rc = sclp_add_request(&sclp_suspend_req);
977 if (rc == 0)
978 wait_for_completion(&sclp_request_queue_flushed);
979 else if (rc != -ENODATA)
980 goto fail_thaw;
981
982 rc = sclp_deactivate();
983 if (rc)
984 goto fail_thaw;
985 return 0;
986
987fail_thaw:
988 spin_lock_irqsave(&sclp_lock, flags);
989 sclp_suspend_state = sclp_suspend_state_running;
990 spin_unlock_irqrestore(&sclp_lock, flags);
991 sclp_pm_event(SCLP_PM_EVENT_THAW, 1);
992 return rc;
993}
994
995static int sclp_undo_suspend(enum sclp_pm_event event)
996{
997 unsigned long flags;
998 int rc;
999
1000 rc = sclp_reactivate();
1001 if (rc)
1002 return rc;
1003
1004 spin_lock_irqsave(&sclp_lock, flags);
1005 sclp_suspend_state = sclp_suspend_state_running;
1006 spin_unlock_irqrestore(&sclp_lock, flags);
1007
1008 sclp_pm_event(event, 0);
1009 return 0;
1010}
1011
1012static int sclp_thaw(struct device *dev)
1013{
1014 return sclp_undo_suspend(SCLP_PM_EVENT_THAW);
1015}
1016
1017static int sclp_restore(struct device *dev)
1018{
1019 return sclp_undo_suspend(SCLP_PM_EVENT_RESTORE);
1020}
1021
1022static struct dev_pm_ops sclp_pm_ops = {
1023 .freeze = sclp_freeze,
1024 .thaw = sclp_thaw,
1025 .restore = sclp_restore,
1026};
1027
1028static struct platform_driver sclp_pdrv = {
1029 .driver = {
1030 .name = "sclp",
1031 .owner = THIS_MODULE,
1032 .pm = &sclp_pm_ops,
1033 },
1034};
1035
1036static struct platform_device *sclp_pdev;
1037
883/* Initialize SCLP driver. Return zero if driver is operational, non-zero 1038/* Initialize SCLP driver. Return zero if driver is operational, non-zero
884 * otherwise. */ 1039 * otherwise. */
885static int 1040static int
886sclp_init(void) 1041sclp_init(void)
887{ 1042{
888 unsigned long flags; 1043 unsigned long flags;
889 int rc; 1044 int rc = 0;
890 1045
891 spin_lock_irqsave(&sclp_lock, flags); 1046 spin_lock_irqsave(&sclp_lock, flags);
892 /* Check for previous or running initialization */ 1047 /* Check for previous or running initialization */
893 if (sclp_init_state != sclp_init_state_uninitialized) { 1048 if (sclp_init_state != sclp_init_state_uninitialized)
894 spin_unlock_irqrestore(&sclp_lock, flags); 1049 goto fail_unlock;
895 return 0;
896 }
897 sclp_init_state = sclp_init_state_initializing; 1050 sclp_init_state = sclp_init_state_initializing;
898 /* Set up variables */ 1051 /* Set up variables */
899 INIT_LIST_HEAD(&sclp_req_queue); 1052 INIT_LIST_HEAD(&sclp_req_queue);
@@ -904,27 +1057,17 @@ sclp_init(void)
904 spin_unlock_irqrestore(&sclp_lock, flags); 1057 spin_unlock_irqrestore(&sclp_lock, flags);
905 rc = sclp_check_interface(); 1058 rc = sclp_check_interface();
906 spin_lock_irqsave(&sclp_lock, flags); 1059 spin_lock_irqsave(&sclp_lock, flags);
907 if (rc) { 1060 if (rc)
908 sclp_init_state = sclp_init_state_uninitialized; 1061 goto fail_init_state_uninitialized;
909 spin_unlock_irqrestore(&sclp_lock, flags);
910 return rc;
911 }
912 /* Register reboot handler */ 1062 /* Register reboot handler */
913 rc = register_reboot_notifier(&sclp_reboot_notifier); 1063 rc = register_reboot_notifier(&sclp_reboot_notifier);
914 if (rc) { 1064 if (rc)
915 sclp_init_state = sclp_init_state_uninitialized; 1065 goto fail_init_state_uninitialized;
916 spin_unlock_irqrestore(&sclp_lock, flags);
917 return rc;
918 }
919 /* Register interrupt handler */ 1066 /* Register interrupt handler */
920 rc = register_early_external_interrupt(0x2401, sclp_interrupt_handler, 1067 rc = register_early_external_interrupt(0x2401, sclp_interrupt_handler,
921 &ext_int_info_hwc); 1068 &ext_int_info_hwc);
922 if (rc) { 1069 if (rc)
923 unregister_reboot_notifier(&sclp_reboot_notifier); 1070 goto fail_unregister_reboot_notifier;
924 sclp_init_state = sclp_init_state_uninitialized;
925 spin_unlock_irqrestore(&sclp_lock, flags);
926 return rc;
927 }
928 sclp_init_state = sclp_init_state_initialized; 1071 sclp_init_state = sclp_init_state_initialized;
929 spin_unlock_irqrestore(&sclp_lock, flags); 1072 spin_unlock_irqrestore(&sclp_lock, flags);
930 /* Enable service-signal external interruption - needs to happen with 1073 /* Enable service-signal external interruption - needs to happen with
@@ -932,11 +1075,56 @@ sclp_init(void)
932 ctl_set_bit(0, 9); 1075 ctl_set_bit(0, 9);
933 sclp_init_mask(1); 1076 sclp_init_mask(1);
934 return 0; 1077 return 0;
1078
1079fail_unregister_reboot_notifier:
1080 unregister_reboot_notifier(&sclp_reboot_notifier);
1081fail_init_state_uninitialized:
1082 sclp_init_state = sclp_init_state_uninitialized;
1083fail_unlock:
1084 spin_unlock_irqrestore(&sclp_lock, flags);
1085 return rc;
935} 1086}
936 1087
1088/*
1089 * SCLP panic notifier: If we are suspended, we thaw SCLP in order to be able
1090 * to print the panic message.
1091 */
1092static int sclp_panic_notify(struct notifier_block *self,
1093 unsigned long event, void *data)
1094{
1095 if (sclp_suspend_state == sclp_suspend_state_suspended)
1096 sclp_undo_suspend(SCLP_PM_EVENT_THAW);
1097 return NOTIFY_OK;
1098}
1099
1100static struct notifier_block sclp_on_panic_nb = {
1101 .notifier_call = sclp_panic_notify,
1102 .priority = SCLP_PANIC_PRIO,
1103};
1104
937static __init int sclp_initcall(void) 1105static __init int sclp_initcall(void)
938{ 1106{
1107 int rc;
1108
1109 rc = platform_driver_register(&sclp_pdrv);
1110 if (rc)
1111 return rc;
1112 sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
1113 rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
1114 if (rc)
1115 goto fail_platform_driver_unregister;
1116 rc = atomic_notifier_chain_register(&panic_notifier_list,
1117 &sclp_on_panic_nb);
1118 if (rc)
1119 goto fail_platform_device_unregister;
1120
939 return sclp_init(); 1121 return sclp_init();
1122
1123fail_platform_device_unregister:
1124 platform_device_unregister(sclp_pdev);
1125fail_platform_driver_unregister:
1126 platform_driver_unregister(&sclp_pdrv);
1127 return rc;
940} 1128}
941 1129
942arch_initcall(sclp_initcall); 1130arch_initcall(sclp_initcall);
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index bac80e856f97..60e7cb07095b 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -1,10 +1,8 @@
1/* 1/*
2 * drivers/s390/char/sclp.h 2 * Copyright IBM Corp. 1999, 2009
3 * 3 *
4 * S390 version 4 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
5 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
6 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 */ 6 */
9 7
10#ifndef __SCLP_H__ 8#ifndef __SCLP_H__
@@ -17,7 +15,7 @@
17 15
18/* maximum number of pages concerning our own memory management */ 16/* maximum number of pages concerning our own memory management */
19#define MAX_KMEM_PAGES (sizeof(unsigned long) << 3) 17#define MAX_KMEM_PAGES (sizeof(unsigned long) << 3)
20#define MAX_CONSOLE_PAGES 4 18#define MAX_CONSOLE_PAGES 6
21 19
22#define EVTYP_OPCMD 0x01 20#define EVTYP_OPCMD 0x01
23#define EVTYP_MSG 0x02 21#define EVTYP_MSG 0x02
@@ -68,6 +66,15 @@ typedef unsigned int sclp_cmdw_t;
68 66
69#define GDS_KEY_SELFDEFTEXTMSG 0x31 67#define GDS_KEY_SELFDEFTEXTMSG 0x31
70 68
69enum sclp_pm_event {
70 SCLP_PM_EVENT_FREEZE,
71 SCLP_PM_EVENT_THAW,
72 SCLP_PM_EVENT_RESTORE,
73};
74
75#define SCLP_PANIC_PRIO 1
76#define SCLP_PANIC_PRIO_CLIENT 0
77
71typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ 78typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */
72 79
73struct sccb_header { 80struct sccb_header {
@@ -134,6 +141,10 @@ struct sclp_register {
134 void (*state_change_fn)(struct sclp_register *); 141 void (*state_change_fn)(struct sclp_register *);
135 /* called for events in cp_receive_mask/sclp_receive_mask */ 142 /* called for events in cp_receive_mask/sclp_receive_mask */
136 void (*receiver_fn)(struct evbuf_header *); 143 void (*receiver_fn)(struct evbuf_header *);
144 /* called for power management events */
145 void (*pm_event_fn)(struct sclp_register *, enum sclp_pm_event);
146 /* pm event posted flag */
147 int pm_event_posted;
137}; 148};
138 149
139/* externals from sclp.c */ 150/* externals from sclp.c */
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 77ab6e34a100..5cc11c636d38 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * drivers/s390/char/sclp_cmd.c 2 * Copyright IBM Corp. 2007, 2009
3 * 3 *
4 * Copyright IBM Corp. 2007 4 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, 5 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
6 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
7 */ 6 */
8 7
9#define KMSG_COMPONENT "sclp_cmd" 8#define KMSG_COMPONENT "sclp_cmd"
@@ -12,11 +11,13 @@
12#include <linux/completion.h> 11#include <linux/completion.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/err.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/mmzone.h> 18#include <linux/mmzone.h>
19#include <linux/memory.h> 19#include <linux/memory.h>
20#include <linux/platform_device.h>
20#include <asm/chpid.h> 21#include <asm/chpid.h>
21#include <asm/sclp.h> 22#include <asm/sclp.h>
22#include <asm/setup.h> 23#include <asm/setup.h>
@@ -292,6 +293,7 @@ static DEFINE_MUTEX(sclp_mem_mutex);
292static LIST_HEAD(sclp_mem_list); 293static LIST_HEAD(sclp_mem_list);
293static u8 sclp_max_storage_id; 294static u8 sclp_max_storage_id;
294static unsigned long sclp_storage_ids[256 / BITS_PER_LONG]; 295static unsigned long sclp_storage_ids[256 / BITS_PER_LONG];
296static int sclp_mem_state_changed;
295 297
296struct memory_increment { 298struct memory_increment {
297 struct list_head list; 299 struct list_head list;
@@ -450,6 +452,8 @@ static int sclp_mem_notifier(struct notifier_block *nb,
450 rc = -EINVAL; 452 rc = -EINVAL;
451 break; 453 break;
452 } 454 }
455 if (!rc)
456 sclp_mem_state_changed = 1;
453 mutex_unlock(&sclp_mem_mutex); 457 mutex_unlock(&sclp_mem_mutex);
454 return rc ? NOTIFY_BAD : NOTIFY_OK; 458 return rc ? NOTIFY_BAD : NOTIFY_OK;
455} 459}
@@ -525,6 +529,14 @@ static void __init insert_increment(u16 rn, int standby, int assigned)
525 list_add(&new_incr->list, prev); 529 list_add(&new_incr->list, prev);
526} 530}
527 531
532static int sclp_mem_freeze(struct device *dev)
533{
534 if (!sclp_mem_state_changed)
535 return 0;
536 pr_err("Memory hotplug state changed, suspend refused.\n");
537 return -EPERM;
538}
539
528struct read_storage_sccb { 540struct read_storage_sccb {
529 struct sccb_header header; 541 struct sccb_header header;
530 u16 max_id; 542 u16 max_id;
@@ -534,8 +546,20 @@ struct read_storage_sccb {
534 u32 entries[0]; 546 u32 entries[0];
535} __packed; 547} __packed;
536 548
549static struct dev_pm_ops sclp_mem_pm_ops = {
550 .freeze = sclp_mem_freeze,
551};
552
553static struct platform_driver sclp_mem_pdrv = {
554 .driver = {
555 .name = "sclp_mem",
556 .pm = &sclp_mem_pm_ops,
557 },
558};
559
537static int __init sclp_detect_standby_memory(void) 560static int __init sclp_detect_standby_memory(void)
538{ 561{
562 struct platform_device *sclp_pdev;
539 struct read_storage_sccb *sccb; 563 struct read_storage_sccb *sccb;
540 int i, id, assigned, rc; 564 int i, id, assigned, rc;
541 565
@@ -588,7 +612,17 @@ static int __init sclp_detect_standby_memory(void)
588 rc = register_memory_notifier(&sclp_mem_nb); 612 rc = register_memory_notifier(&sclp_mem_nb);
589 if (rc) 613 if (rc)
590 goto out; 614 goto out;
615 rc = platform_driver_register(&sclp_mem_pdrv);
616 if (rc)
617 goto out;
618 sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0);
619 rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
620 if (rc)
621 goto out_driver;
591 sclp_add_standby_memory(); 622 sclp_add_standby_memory();
623 goto out;
624out_driver:
625 platform_driver_unregister(&sclp_mem_pdrv);
592out: 626out:
593 free_page((unsigned long) sccb); 627 free_page((unsigned long) sccb);
594 return rc; 628 return rc;
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
index 9a25c4bd1421..336811a77672 100644
--- a/drivers/s390/char/sclp_con.c
+++ b/drivers/s390/char/sclp_con.c
@@ -1,11 +1,9 @@
1/* 1/*
2 * drivers/s390/char/sclp_con.c 2 * SCLP line mode console driver
3 * SCLP line mode console driver
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 1999, 2009
6 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
7 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com>
9 */ 7 */
10 8
11#include <linux/kmod.h> 9#include <linux/kmod.h>
@@ -32,13 +30,14 @@ static spinlock_t sclp_con_lock;
32static struct list_head sclp_con_pages; 30static struct list_head sclp_con_pages;
33/* List of full struct sclp_buffer structures ready for output */ 31/* List of full struct sclp_buffer structures ready for output */
34static struct list_head sclp_con_outqueue; 32static struct list_head sclp_con_outqueue;
35/* Counter how many buffers are emitted (max 1) and how many */
36/* are on the output queue. */
37static int sclp_con_buffer_count;
38/* Pointer to current console buffer */ 33/* Pointer to current console buffer */
39static struct sclp_buffer *sclp_conbuf; 34static struct sclp_buffer *sclp_conbuf;
40/* Timer for delayed output of console messages */ 35/* Timer for delayed output of console messages */
41static struct timer_list sclp_con_timer; 36static struct timer_list sclp_con_timer;
37/* Suspend mode flag */
38static int sclp_con_suspended;
39/* Flag that output queue is currently running */
40static int sclp_con_queue_running;
42 41
43/* Output format for console messages */ 42/* Output format for console messages */
44static unsigned short sclp_con_columns; 43static unsigned short sclp_con_columns;
@@ -53,42 +52,71 @@ sclp_conbuf_callback(struct sclp_buffer *buffer, int rc)
53 do { 52 do {
54 page = sclp_unmake_buffer(buffer); 53 page = sclp_unmake_buffer(buffer);
55 spin_lock_irqsave(&sclp_con_lock, flags); 54 spin_lock_irqsave(&sclp_con_lock, flags);
55
56 /* Remove buffer from outqueue */ 56 /* Remove buffer from outqueue */
57 list_del(&buffer->list); 57 list_del(&buffer->list);
58 sclp_con_buffer_count--;
59 list_add_tail((struct list_head *) page, &sclp_con_pages); 58 list_add_tail((struct list_head *) page, &sclp_con_pages);
59
60 /* Check if there is a pending buffer on the out queue. */ 60 /* Check if there is a pending buffer on the out queue. */
61 buffer = NULL; 61 buffer = NULL;
62 if (!list_empty(&sclp_con_outqueue)) 62 if (!list_empty(&sclp_con_outqueue))
63 buffer = list_entry(sclp_con_outqueue.next, 63 buffer = list_first_entry(&sclp_con_outqueue,
64 struct sclp_buffer, list); 64 struct sclp_buffer, list);
65 if (!buffer || sclp_con_suspended) {
66 sclp_con_queue_running = 0;
67 spin_unlock_irqrestore(&sclp_con_lock, flags);
68 break;
69 }
65 spin_unlock_irqrestore(&sclp_con_lock, flags); 70 spin_unlock_irqrestore(&sclp_con_lock, flags);
66 } while (buffer && sclp_emit_buffer(buffer, sclp_conbuf_callback)); 71 } while (sclp_emit_buffer(buffer, sclp_conbuf_callback));
67} 72}
68 73
69static void 74/*
70sclp_conbuf_emit(void) 75 * Finalize and emit first pending buffer.
76 */
77static void sclp_conbuf_emit(void)
71{ 78{
72 struct sclp_buffer* buffer; 79 struct sclp_buffer* buffer;
73 unsigned long flags; 80 unsigned long flags;
74 int count;
75 int rc; 81 int rc;
76 82
77 spin_lock_irqsave(&sclp_con_lock, flags); 83 spin_lock_irqsave(&sclp_con_lock, flags);
78 buffer = sclp_conbuf; 84 if (sclp_conbuf)
85 list_add_tail(&sclp_conbuf->list, &sclp_con_outqueue);
79 sclp_conbuf = NULL; 86 sclp_conbuf = NULL;
80 if (buffer == NULL) { 87 if (sclp_con_queue_running || sclp_con_suspended)
81 spin_unlock_irqrestore(&sclp_con_lock, flags); 88 goto out_unlock;
82 return; 89 if (list_empty(&sclp_con_outqueue))
83 } 90 goto out_unlock;
84 list_add_tail(&buffer->list, &sclp_con_outqueue); 91 buffer = list_first_entry(&sclp_con_outqueue, struct sclp_buffer,
85 count = sclp_con_buffer_count++; 92 list);
93 sclp_con_queue_running = 1;
86 spin_unlock_irqrestore(&sclp_con_lock, flags); 94 spin_unlock_irqrestore(&sclp_con_lock, flags);
87 if (count) 95
88 return;
89 rc = sclp_emit_buffer(buffer, sclp_conbuf_callback); 96 rc = sclp_emit_buffer(buffer, sclp_conbuf_callback);
90 if (rc) 97 if (rc)
91 sclp_conbuf_callback(buffer, rc); 98 sclp_conbuf_callback(buffer, rc);
99 return;
100out_unlock:
101 spin_unlock_irqrestore(&sclp_con_lock, flags);
102}
103
104/*
105 * Wait until out queue is empty
106 */
107static void sclp_console_sync_queue(void)
108{
109 unsigned long flags;
110
111 spin_lock_irqsave(&sclp_con_lock, flags);
112 if (timer_pending(&sclp_con_timer))
113 del_timer_sync(&sclp_con_timer);
114 while (sclp_con_queue_running) {
115 spin_unlock_irqrestore(&sclp_con_lock, flags);
116 sclp_sync_wait();
117 spin_lock_irqsave(&sclp_con_lock, flags);
118 }
119 spin_unlock_irqrestore(&sclp_con_lock, flags);
92} 120}
93 121
94/* 122/*
@@ -123,6 +151,8 @@ sclp_console_write(struct console *console, const char *message,
123 /* make sure we have a console output buffer */ 151 /* make sure we have a console output buffer */
124 if (sclp_conbuf == NULL) { 152 if (sclp_conbuf == NULL) {
125 while (list_empty(&sclp_con_pages)) { 153 while (list_empty(&sclp_con_pages)) {
154 if (sclp_con_suspended)
155 goto out;
126 spin_unlock_irqrestore(&sclp_con_lock, flags); 156 spin_unlock_irqrestore(&sclp_con_lock, flags);
127 sclp_sync_wait(); 157 sclp_sync_wait();
128 spin_lock_irqsave(&sclp_con_lock, flags); 158 spin_lock_irqsave(&sclp_con_lock, flags);
@@ -157,6 +187,7 @@ sclp_console_write(struct console *console, const char *message,
157 sclp_con_timer.expires = jiffies + HZ/10; 187 sclp_con_timer.expires = jiffies + HZ/10;
158 add_timer(&sclp_con_timer); 188 add_timer(&sclp_con_timer);
159 } 189 }
190out:
160 spin_unlock_irqrestore(&sclp_con_lock, flags); 191 spin_unlock_irqrestore(&sclp_con_lock, flags);
161} 192}
162 193
@@ -168,30 +199,43 @@ sclp_console_device(struct console *c, int *index)
168} 199}
169 200
170/* 201/*
171 * This routine is called from panic when the kernel 202 * Make sure that all buffers will be flushed to the SCLP.
172 * is going to give up. We have to make sure that all buffers
173 * will be flushed to the SCLP.
174 */ 203 */
175static void 204static void
176sclp_console_flush(void) 205sclp_console_flush(void)
177{ 206{
207 sclp_conbuf_emit();
208 sclp_console_sync_queue();
209}
210
211/*
212 * Resume console: If there are cached messages, emit them.
213 */
214static void sclp_console_resume(void)
215{
178 unsigned long flags; 216 unsigned long flags;
179 217
218 spin_lock_irqsave(&sclp_con_lock, flags);
219 sclp_con_suspended = 0;
220 spin_unlock_irqrestore(&sclp_con_lock, flags);
180 sclp_conbuf_emit(); 221 sclp_conbuf_emit();
222}
223
224/*
225 * Suspend console: Set suspend flag and flush console
226 */
227static void sclp_console_suspend(void)
228{
229 unsigned long flags;
230
181 spin_lock_irqsave(&sclp_con_lock, flags); 231 spin_lock_irqsave(&sclp_con_lock, flags);
182 if (timer_pending(&sclp_con_timer)) 232 sclp_con_suspended = 1;
183 del_timer(&sclp_con_timer);
184 while (sclp_con_buffer_count > 0) {
185 spin_unlock_irqrestore(&sclp_con_lock, flags);
186 sclp_sync_wait();
187 spin_lock_irqsave(&sclp_con_lock, flags);
188 }
189 spin_unlock_irqrestore(&sclp_con_lock, flags); 233 spin_unlock_irqrestore(&sclp_con_lock, flags);
234 sclp_console_flush();
190} 235}
191 236
192static int 237static int sclp_console_notify(struct notifier_block *self,
193sclp_console_notify(struct notifier_block *self, 238 unsigned long event, void *data)
194 unsigned long event, void *data)
195{ 239{
196 sclp_console_flush(); 240 sclp_console_flush();
197 return NOTIFY_OK; 241 return NOTIFY_OK;
@@ -199,7 +243,7 @@ sclp_console_notify(struct notifier_block *self,
199 243
200static struct notifier_block on_panic_nb = { 244static struct notifier_block on_panic_nb = {
201 .notifier_call = sclp_console_notify, 245 .notifier_call = sclp_console_notify,
202 .priority = 1, 246 .priority = SCLP_PANIC_PRIO_CLIENT,
203}; 247};
204 248
205static struct notifier_block on_reboot_nb = { 249static struct notifier_block on_reboot_nb = {
@@ -221,6 +265,22 @@ static struct console sclp_console =
221}; 265};
222 266
223/* 267/*
268 * This function is called for SCLP suspend and resume events.
269 */
270void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event)
271{
272 switch (sclp_pm_event) {
273 case SCLP_PM_EVENT_FREEZE:
274 sclp_console_suspend();
275 break;
276 case SCLP_PM_EVENT_RESTORE:
277 case SCLP_PM_EVENT_THAW:
278 sclp_console_resume();
279 break;
280 }
281}
282
283/*
224 * called by console_init() in drivers/char/tty_io.c at boot-time. 284 * called by console_init() in drivers/char/tty_io.c at boot-time.
225 */ 285 */
226static int __init 286static int __init
@@ -243,7 +303,6 @@ sclp_console_init(void)
243 } 303 }
244 INIT_LIST_HEAD(&sclp_con_outqueue); 304 INIT_LIST_HEAD(&sclp_con_outqueue);
245 spin_lock_init(&sclp_con_lock); 305 spin_lock_init(&sclp_con_lock);
246 sclp_con_buffer_count = 0;
247 sclp_conbuf = NULL; 306 sclp_conbuf = NULL;
248 init_timer(&sclp_con_timer); 307 init_timer(&sclp_con_timer);
249 308
diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c
index 710af42603f8..4be63be73445 100644
--- a/drivers/s390/char/sclp_rw.c
+++ b/drivers/s390/char/sclp_rw.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/sclp_rw.c 2 * driver: reading from and writing to system console on S/390 via SCLP
3 * driver: reading from and writing to system console on S/390 via SCLP
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 1999, 2009
6 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 *
7 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 6 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
9 */ 8 */
10 9
11#include <linux/kmod.h> 10#include <linux/kmod.h>
@@ -26,9 +25,16 @@
26 */ 25 */
27#define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer)) 26#define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer))
28 27
28static void sclp_rw_pm_event(struct sclp_register *reg,
29 enum sclp_pm_event sclp_pm_event)
30{
31 sclp_console_pm_event(sclp_pm_event);
32}
33
29/* Event type structure for write message and write priority message */ 34/* Event type structure for write message and write priority message */
30static struct sclp_register sclp_rw_event = { 35static struct sclp_register sclp_rw_event = {
31 .send_mask = EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK 36 .send_mask = EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK,
37 .pm_event_fn = sclp_rw_pm_event,
32}; 38};
33 39
34/* 40/*
diff --git a/drivers/s390/char/sclp_rw.h b/drivers/s390/char/sclp_rw.h
index 6aa7a6948bc9..85f491ea929c 100644
--- a/drivers/s390/char/sclp_rw.h
+++ b/drivers/s390/char/sclp_rw.h
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/sclp_rw.h 2 * interface to the SCLP-read/write driver
3 * interface to the SCLP-read/write driver
4 * 3 *
5 * S390 version 4 * Copyright IBM Corporation 1999, 2009
6 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 *
7 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 6 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
9 */ 8 */
10 9
11#ifndef __SCLP_RW_H__ 10#ifndef __SCLP_RW_H__
@@ -93,4 +92,5 @@ void sclp_set_columns(struct sclp_buffer *, unsigned short);
93void sclp_set_htab(struct sclp_buffer *, unsigned short); 92void sclp_set_htab(struct sclp_buffer *, unsigned short);
94int sclp_chars_in_buffer(struct sclp_buffer *); 93int sclp_chars_in_buffer(struct sclp_buffer *);
95 94
95void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event);
96#endif /* __SCLP_RW_H__ */ 96#endif /* __SCLP_RW_H__ */
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index a839aa531d7c..5518e24946aa 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -1,10 +1,9 @@
1/* 1/*
2 * drivers/s390/char/sclp_vt220.c 2 * SCLP VT220 terminal driver.
3 * SCLP VT220 terminal driver.
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 2003, 2009
6 * Copyright IBM Corp. 2003,2008 5 *
7 * Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com> 6 * Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>
8 */ 7 */
9 8
10#include <linux/module.h> 9#include <linux/module.h>
@@ -69,8 +68,11 @@ static struct list_head sclp_vt220_empty;
69/* List of pending requests */ 68/* List of pending requests */
70static struct list_head sclp_vt220_outqueue; 69static struct list_head sclp_vt220_outqueue;
71 70
72/* Number of requests in outqueue */ 71/* Suspend mode flag */
73static int sclp_vt220_outqueue_count; 72static int sclp_vt220_suspended;
73
74/* Flag that output queue is currently running */
75static int sclp_vt220_queue_running;
74 76
75/* Timer used for delaying write requests to merge subsequent messages into 77/* Timer used for delaying write requests to merge subsequent messages into
76 * a single buffer */ 78 * a single buffer */
@@ -92,6 +94,8 @@ static int __initdata sclp_vt220_init_count;
92static int sclp_vt220_flush_later; 94static int sclp_vt220_flush_later;
93 95
94static void sclp_vt220_receiver_fn(struct evbuf_header *evbuf); 96static void sclp_vt220_receiver_fn(struct evbuf_header *evbuf);
97static void sclp_vt220_pm_event_fn(struct sclp_register *reg,
98 enum sclp_pm_event sclp_pm_event);
95static int __sclp_vt220_emit(struct sclp_vt220_request *request); 99static int __sclp_vt220_emit(struct sclp_vt220_request *request);
96static void sclp_vt220_emit_current(void); 100static void sclp_vt220_emit_current(void);
97 101
@@ -100,7 +104,8 @@ static struct sclp_register sclp_vt220_register = {
100 .send_mask = EVTYP_VT220MSG_MASK, 104 .send_mask = EVTYP_VT220MSG_MASK,
101 .receive_mask = EVTYP_VT220MSG_MASK, 105 .receive_mask = EVTYP_VT220MSG_MASK,
102 .state_change_fn = NULL, 106 .state_change_fn = NULL,
103 .receiver_fn = sclp_vt220_receiver_fn 107 .receiver_fn = sclp_vt220_receiver_fn,
108 .pm_event_fn = sclp_vt220_pm_event_fn,
104}; 109};
105 110
106 111
@@ -120,15 +125,19 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request)
120 spin_lock_irqsave(&sclp_vt220_lock, flags); 125 spin_lock_irqsave(&sclp_vt220_lock, flags);
121 /* Move request from outqueue to empty queue */ 126 /* Move request from outqueue to empty queue */
122 list_del(&request->list); 127 list_del(&request->list);
123 sclp_vt220_outqueue_count--;
124 list_add_tail((struct list_head *) page, &sclp_vt220_empty); 128 list_add_tail((struct list_head *) page, &sclp_vt220_empty);
125 /* Check if there is a pending buffer on the out queue. */ 129 /* Check if there is a pending buffer on the out queue. */
126 request = NULL; 130 request = NULL;
127 if (!list_empty(&sclp_vt220_outqueue)) 131 if (!list_empty(&sclp_vt220_outqueue))
128 request = list_entry(sclp_vt220_outqueue.next, 132 request = list_entry(sclp_vt220_outqueue.next,
129 struct sclp_vt220_request, list); 133 struct sclp_vt220_request, list);
134 if (!request || sclp_vt220_suspended) {
135 sclp_vt220_queue_running = 0;
136 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
137 break;
138 }
130 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 139 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
131 } while (request && __sclp_vt220_emit(request)); 140 } while (__sclp_vt220_emit(request));
132 if (request == NULL && sclp_vt220_flush_later) 141 if (request == NULL && sclp_vt220_flush_later)
133 sclp_vt220_emit_current(); 142 sclp_vt220_emit_current();
134 /* Check if the tty needs a wake up call */ 143 /* Check if the tty needs a wake up call */
@@ -212,26 +221,7 @@ __sclp_vt220_emit(struct sclp_vt220_request *request)
212} 221}
213 222
214/* 223/*
215 * Queue and emit given request. 224 * Queue and emit current request.
216 */
217static void
218sclp_vt220_emit(struct sclp_vt220_request *request)
219{
220 unsigned long flags;
221 int count;
222
223 spin_lock_irqsave(&sclp_vt220_lock, flags);
224 list_add_tail(&request->list, &sclp_vt220_outqueue);
225 count = sclp_vt220_outqueue_count++;
226 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
227 /* Emit only the first buffer immediately - callback takes care of
228 * the rest */
229 if (count == 0 && __sclp_vt220_emit(request))
230 sclp_vt220_process_queue(request);
231}
232
233/*
234 * Queue and emit current request. Return zero on success, non-zero otherwise.
235 */ 225 */
236static void 226static void
237sclp_vt220_emit_current(void) 227sclp_vt220_emit_current(void)
@@ -241,22 +231,33 @@ sclp_vt220_emit_current(void)
241 struct sclp_vt220_sccb *sccb; 231 struct sclp_vt220_sccb *sccb;
242 232
243 spin_lock_irqsave(&sclp_vt220_lock, flags); 233 spin_lock_irqsave(&sclp_vt220_lock, flags);
244 request = NULL; 234 if (sclp_vt220_current_request) {
245 if (sclp_vt220_current_request != NULL) {
246 sccb = (struct sclp_vt220_sccb *) 235 sccb = (struct sclp_vt220_sccb *)
247 sclp_vt220_current_request->sclp_req.sccb; 236 sclp_vt220_current_request->sclp_req.sccb;
248 /* Only emit buffers with content */ 237 /* Only emit buffers with content */
249 if (sccb->header.length != sizeof(struct sclp_vt220_sccb)) { 238 if (sccb->header.length != sizeof(struct sclp_vt220_sccb)) {
250 request = sclp_vt220_current_request; 239 list_add_tail(&sclp_vt220_current_request->list,
240 &sclp_vt220_outqueue);
251 sclp_vt220_current_request = NULL; 241 sclp_vt220_current_request = NULL;
252 if (timer_pending(&sclp_vt220_timer)) 242 if (timer_pending(&sclp_vt220_timer))
253 del_timer(&sclp_vt220_timer); 243 del_timer(&sclp_vt220_timer);
254 } 244 }
255 sclp_vt220_flush_later = 0; 245 sclp_vt220_flush_later = 0;
256 } 246 }
247 if (sclp_vt220_queue_running || sclp_vt220_suspended)
248 goto out_unlock;
249 if (list_empty(&sclp_vt220_outqueue))
250 goto out_unlock;
251 request = list_first_entry(&sclp_vt220_outqueue,
252 struct sclp_vt220_request, list);
253 sclp_vt220_queue_running = 1;
254 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
255
256 if (__sclp_vt220_emit(request))
257 sclp_vt220_process_queue(request);
258 return;
259out_unlock:
257 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 260 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
258 if (request != NULL)
259 sclp_vt220_emit(request);
260} 261}
261 262
262#define SCLP_NORMAL_WRITE 0x00 263#define SCLP_NORMAL_WRITE 0x00
@@ -396,7 +397,7 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule,
396 if (sclp_vt220_current_request == NULL) { 397 if (sclp_vt220_current_request == NULL) {
397 while (list_empty(&sclp_vt220_empty)) { 398 while (list_empty(&sclp_vt220_empty)) {
398 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 399 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
399 if (may_fail) 400 if (may_fail || sclp_vt220_suspended)
400 goto out; 401 goto out;
401 else 402 else
402 sclp_sync_wait(); 403 sclp_sync_wait();
@@ -531,7 +532,7 @@ sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch)
531static void 532static void
532sclp_vt220_flush_chars(struct tty_struct *tty) 533sclp_vt220_flush_chars(struct tty_struct *tty)
533{ 534{
534 if (sclp_vt220_outqueue_count == 0) 535 if (!sclp_vt220_queue_running)
535 sclp_vt220_emit_current(); 536 sclp_vt220_emit_current();
536 else 537 else
537 sclp_vt220_flush_later = 1; 538 sclp_vt220_flush_later = 1;
@@ -635,7 +636,6 @@ static int __init __sclp_vt220_init(int num_pages)
635 init_timer(&sclp_vt220_timer); 636 init_timer(&sclp_vt220_timer);
636 sclp_vt220_current_request = NULL; 637 sclp_vt220_current_request = NULL;
637 sclp_vt220_buffered_chars = 0; 638 sclp_vt220_buffered_chars = 0;
638 sclp_vt220_outqueue_count = 0;
639 sclp_vt220_tty = NULL; 639 sclp_vt220_tty = NULL;
640 sclp_vt220_flush_later = 0; 640 sclp_vt220_flush_later = 0;
641 641
@@ -736,7 +736,7 @@ static void __sclp_vt220_flush_buffer(void)
736 spin_lock_irqsave(&sclp_vt220_lock, flags); 736 spin_lock_irqsave(&sclp_vt220_lock, flags);
737 if (timer_pending(&sclp_vt220_timer)) 737 if (timer_pending(&sclp_vt220_timer))
738 del_timer(&sclp_vt220_timer); 738 del_timer(&sclp_vt220_timer);
739 while (sclp_vt220_outqueue_count > 0) { 739 while (sclp_vt220_queue_running) {
740 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 740 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
741 sclp_sync_wait(); 741 sclp_sync_wait();
742 spin_lock_irqsave(&sclp_vt220_lock, flags); 742 spin_lock_irqsave(&sclp_vt220_lock, flags);
@@ -744,6 +744,46 @@ static void __sclp_vt220_flush_buffer(void)
744 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 744 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
745} 745}
746 746
747/*
748 * Resume console: If there are cached messages, emit them.
749 */
750static void sclp_vt220_resume(void)
751{
752 unsigned long flags;
753
754 spin_lock_irqsave(&sclp_vt220_lock, flags);
755 sclp_vt220_suspended = 0;
756 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
757 sclp_vt220_emit_current();
758}
759
760/*
761 * Suspend console: Set suspend flag and flush console
762 */
763static void sclp_vt220_suspend(void)
764{
765 unsigned long flags;
766
767 spin_lock_irqsave(&sclp_vt220_lock, flags);
768 sclp_vt220_suspended = 1;
769 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
770 __sclp_vt220_flush_buffer();
771}
772
773static void sclp_vt220_pm_event_fn(struct sclp_register *reg,
774 enum sclp_pm_event sclp_pm_event)
775{
776 switch (sclp_pm_event) {
777 case SCLP_PM_EVENT_FREEZE:
778 sclp_vt220_suspend();
779 break;
780 case SCLP_PM_EVENT_RESTORE:
781 case SCLP_PM_EVENT_THAW:
782 sclp_vt220_resume();
783 break;
784 }
785}
786
747static int 787static int
748sclp_vt220_notify(struct notifier_block *self, 788sclp_vt220_notify(struct notifier_block *self,
749 unsigned long event, void *data) 789 unsigned long event, void *data)
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index 5469e099597e..a26333774701 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -3,7 +3,7 @@
3 * tape device driver for 3480/3490E/3590 tapes. 3 * tape device driver for 3480/3490E/3590 tapes.
4 * 4 *
5 * S390 and zSeries version 5 * S390 and zSeries version
6 * Copyright IBM Corp. 2001,2006 6 * Copyright IBM Corp. 2001, 2009
7 * Author(s): Carsten Otte <cotte@de.ibm.com> 7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 8 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
9 * Martin Schwidefsky <schwidefsky@de.ibm.com> 9 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -286,6 +286,7 @@ extern void tape_state_set(struct tape_device *, enum tape_state);
286 286
287extern int tape_generic_online(struct tape_device *, struct tape_discipline *); 287extern int tape_generic_online(struct tape_device *, struct tape_discipline *);
288extern int tape_generic_offline(struct ccw_device *); 288extern int tape_generic_offline(struct ccw_device *);
289extern int tape_generic_pm_suspend(struct ccw_device *);
289 290
290/* Externals from tape_devmap.c */ 291/* Externals from tape_devmap.c */
291extern int tape_generic_probe(struct ccw_device *); 292extern int tape_generic_probe(struct ccw_device *);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 2d00a383a475..5a519fac37b7 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -2,7 +2,7 @@
2 * drivers/s390/char/tape_34xx.c 2 * drivers/s390/char/tape_34xx.c
3 * tape device discipline for 3480/3490 tapes. 3 * tape device discipline for 3480/3490 tapes.
4 * 4 *
5 * Copyright (C) IBM Corp. 2001,2006 5 * Copyright IBM Corp. 2001, 2009
6 * Author(s): Carsten Otte <cotte@de.ibm.com> 6 * Author(s): Carsten Otte <cotte@de.ibm.com>
7 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 7 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 8 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -1289,7 +1289,7 @@ static int
1289tape_34xx_online(struct ccw_device *cdev) 1289tape_34xx_online(struct ccw_device *cdev)
1290{ 1290{
1291 return tape_generic_online( 1291 return tape_generic_online(
1292 cdev->dev.driver_data, 1292 dev_get_drvdata(&cdev->dev),
1293 &tape_discipline_34xx 1293 &tape_discipline_34xx
1294 ); 1294 );
1295} 1295}
@@ -1302,6 +1302,7 @@ static struct ccw_driver tape_34xx_driver = {
1302 .remove = tape_generic_remove, 1302 .remove = tape_generic_remove,
1303 .set_online = tape_34xx_online, 1303 .set_online = tape_34xx_online,
1304 .set_offline = tape_generic_offline, 1304 .set_offline = tape_generic_offline,
1305 .freeze = tape_generic_pm_suspend,
1305}; 1306};
1306 1307
1307static int 1308static int
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index c453b2f3e9f4..418f72dd39b4 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -2,7 +2,7 @@
2 * drivers/s390/char/tape_3590.c 2 * drivers/s390/char/tape_3590.c
3 * tape device discipline for 3590 tapes. 3 * tape device discipline for 3590 tapes.
4 * 4 *
5 * Copyright IBM Corp. 2001,2006 5 * Copyright IBM Corp. 2001, 2009
6 * Author(s): Stefan Bader <shbader@de.ibm.com> 6 * Author(s): Stefan Bader <shbader@de.ibm.com>
7 * Michael Holzheu <holzheu@de.ibm.com> 7 * Michael Holzheu <holzheu@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 8 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -1703,7 +1703,7 @@ static struct ccw_device_id tape_3590_ids[] = {
1703static int 1703static int
1704tape_3590_online(struct ccw_device *cdev) 1704tape_3590_online(struct ccw_device *cdev)
1705{ 1705{
1706 return tape_generic_online(cdev->dev.driver_data, 1706 return tape_generic_online(dev_get_drvdata(&cdev->dev),
1707 &tape_discipline_3590); 1707 &tape_discipline_3590);
1708} 1708}
1709 1709
@@ -1715,6 +1715,7 @@ static struct ccw_driver tape_3590_driver = {
1715 .remove = tape_generic_remove, 1715 .remove = tape_generic_remove,
1716 .set_offline = tape_generic_offline, 1716 .set_offline = tape_generic_offline,
1717 .set_online = tape_3590_online, 1717 .set_online = tape_3590_online,
1718 .freeze = tape_generic_pm_suspend,
1718}; 1719};
1719 1720
1720/* 1721/*
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 8a109f3b69c6..595aa04cfd01 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -3,7 +3,7 @@
3 * basic function of the tape device driver 3 * basic function of the tape device driver
4 * 4 *
5 * S390 and zSeries version 5 * S390 and zSeries version
6 * Copyright IBM Corp. 2001,2006 6 * Copyright IBM Corp. 2001, 2009
7 * Author(s): Carsten Otte <cotte@de.ibm.com> 7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Michael Holzheu <holzheu@de.ibm.com> 8 * Michael Holzheu <holzheu@de.ibm.com>
9 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 9 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
@@ -92,7 +92,7 @@ tape_medium_state_show(struct device *dev, struct device_attribute *attr, char *
92{ 92{
93 struct tape_device *tdev; 93 struct tape_device *tdev;
94 94
95 tdev = (struct tape_device *) dev->driver_data; 95 tdev = dev_get_drvdata(dev);
96 return scnprintf(buf, PAGE_SIZE, "%i\n", tdev->medium_state); 96 return scnprintf(buf, PAGE_SIZE, "%i\n", tdev->medium_state);
97} 97}
98 98
@@ -104,7 +104,7 @@ tape_first_minor_show(struct device *dev, struct device_attribute *attr, char *b
104{ 104{
105 struct tape_device *tdev; 105 struct tape_device *tdev;
106 106
107 tdev = (struct tape_device *) dev->driver_data; 107 tdev = dev_get_drvdata(dev);
108 return scnprintf(buf, PAGE_SIZE, "%i\n", tdev->first_minor); 108 return scnprintf(buf, PAGE_SIZE, "%i\n", tdev->first_minor);
109} 109}
110 110
@@ -116,7 +116,7 @@ tape_state_show(struct device *dev, struct device_attribute *attr, char *buf)
116{ 116{
117 struct tape_device *tdev; 117 struct tape_device *tdev;
118 118
119 tdev = (struct tape_device *) dev->driver_data; 119 tdev = dev_get_drvdata(dev);
120 return scnprintf(buf, PAGE_SIZE, "%s\n", (tdev->first_minor < 0) ? 120 return scnprintf(buf, PAGE_SIZE, "%s\n", (tdev->first_minor < 0) ?
121 "OFFLINE" : tape_state_verbose[tdev->tape_state]); 121 "OFFLINE" : tape_state_verbose[tdev->tape_state]);
122} 122}
@@ -130,7 +130,7 @@ tape_operation_show(struct device *dev, struct device_attribute *attr, char *buf
130 struct tape_device *tdev; 130 struct tape_device *tdev;
131 ssize_t rc; 131 ssize_t rc;
132 132
133 tdev = (struct tape_device *) dev->driver_data; 133 tdev = dev_get_drvdata(dev);
134 if (tdev->first_minor < 0) 134 if (tdev->first_minor < 0)
135 return scnprintf(buf, PAGE_SIZE, "N/A\n"); 135 return scnprintf(buf, PAGE_SIZE, "N/A\n");
136 136
@@ -156,7 +156,7 @@ tape_blocksize_show(struct device *dev, struct device_attribute *attr, char *buf
156{ 156{
157 struct tape_device *tdev; 157 struct tape_device *tdev;
158 158
159 tdev = (struct tape_device *) dev->driver_data; 159 tdev = dev_get_drvdata(dev);
160 160
161 return scnprintf(buf, PAGE_SIZE, "%i\n", tdev->char_data.block_size); 161 return scnprintf(buf, PAGE_SIZE, "%i\n", tdev->char_data.block_size);
162} 162}
@@ -380,6 +380,55 @@ tape_cleanup_device(struct tape_device *device)
380} 380}
381 381
382/* 382/*
383 * Suspend device.
384 *
385 * Called by the common I/O layer if the drive should be suspended on user
386 * request. We refuse to suspend if the device is loaded or in use for the
387 * following reason:
388 * While the Linux guest is suspended, it might be logged off which causes
389 * devices to be detached. Tape devices are automatically rewound and unloaded
390 * during DETACH processing (unless the tape device was attached with the
391 * NOASSIGN or MULTIUSER option). After rewind/unload, there is no way to
392 * resume the original state of the tape device, since we would need to
393 * manually re-load the cartridge which was active at suspend time.
394 */
395int tape_generic_pm_suspend(struct ccw_device *cdev)
396{
397 struct tape_device *device;
398
399 device = cdev->dev.driver_data;
400 if (!device) {
401 return -ENODEV;
402 }
403
404 DBF_LH(3, "(%08x): tape_generic_pm_suspend(%p)\n",
405 device->cdev_id, device);
406
407 if (device->medium_state != MS_UNLOADED) {
408 pr_err("A cartridge is loaded in tape device %s, "
409 "refusing to suspend\n", dev_name(&cdev->dev));
410 return -EBUSY;
411 }
412
413 spin_lock_irq(get_ccwdev_lock(device->cdev));
414 switch (device->tape_state) {
415 case TS_INIT:
416 case TS_NOT_OPER:
417 case TS_UNUSED:
418 spin_unlock_irq(get_ccwdev_lock(device->cdev));
419 break;
420 default:
421 pr_err("Tape device %s is busy, refusing to "
422 "suspend\n", dev_name(&cdev->dev));
423 spin_unlock_irq(get_ccwdev_lock(device->cdev));
424 return -EBUSY;
425 }
426
427 DBF_LH(3, "(%08x): Drive suspended.\n", device->cdev_id);
428 return 0;
429}
430
431/*
383 * Set device offline. 432 * Set device offline.
384 * 433 *
385 * Called by the common I/O layer if the drive should set offline on user 434 * Called by the common I/O layer if the drive should set offline on user
@@ -391,7 +440,7 @@ tape_generic_offline(struct ccw_device *cdev)
391{ 440{
392 struct tape_device *device; 441 struct tape_device *device;
393 442
394 device = cdev->dev.driver_data; 443 device = dev_get_drvdata(&cdev->dev);
395 if (!device) { 444 if (!device) {
396 return -ENODEV; 445 return -ENODEV;
397 } 446 }
@@ -534,7 +583,7 @@ tape_generic_probe(struct ccw_device *cdev)
534 tape_put_device(device); 583 tape_put_device(device);
535 return ret; 584 return ret;
536 } 585 }
537 cdev->dev.driver_data = device; 586 dev_set_drvdata(&cdev->dev, device);
538 cdev->handler = __tape_do_irq; 587 cdev->handler = __tape_do_irq;
539 device->cdev = cdev; 588 device->cdev = cdev;
540 ccw_device_get_id(cdev, &dev_id); 589 ccw_device_get_id(cdev, &dev_id);
@@ -573,7 +622,7 @@ tape_generic_remove(struct ccw_device *cdev)
573{ 622{
574 struct tape_device * device; 623 struct tape_device * device;
575 624
576 device = cdev->dev.driver_data; 625 device = dev_get_drvdata(&cdev->dev);
577 if (!device) { 626 if (!device) {
578 return; 627 return;
579 } 628 }
@@ -613,9 +662,9 @@ tape_generic_remove(struct ccw_device *cdev)
613 tape_cleanup_device(device); 662 tape_cleanup_device(device);
614 } 663 }
615 664
616 if (cdev->dev.driver_data != NULL) { 665 if (!dev_get_drvdata(&cdev->dev)) {
617 sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group); 666 sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group);
618 cdev->dev.driver_data = tape_put_device(cdev->dev.driver_data); 667 dev_set_drvdata(&cdev->dev, tape_put_device(dev_get_drvdata(&cdev->dev)));
619 } 668 }
620} 669}
621 670
@@ -1011,7 +1060,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1011 struct tape_request *request; 1060 struct tape_request *request;
1012 int rc; 1061 int rc;
1013 1062
1014 device = (struct tape_device *) cdev->dev.driver_data; 1063 device = dev_get_drvdata(&cdev->dev);
1015 if (device == NULL) { 1064 if (device == NULL) {
1016 return; 1065 return;
1017 } 1066 }
@@ -1273,6 +1322,7 @@ EXPORT_SYMBOL(tape_generic_remove);
1273EXPORT_SYMBOL(tape_generic_probe); 1322EXPORT_SYMBOL(tape_generic_probe);
1274EXPORT_SYMBOL(tape_generic_online); 1323EXPORT_SYMBOL(tape_generic_online);
1275EXPORT_SYMBOL(tape_generic_offline); 1324EXPORT_SYMBOL(tape_generic_offline);
1325EXPORT_SYMBOL(tape_generic_pm_suspend);
1276EXPORT_SYMBOL(tape_put_device); 1326EXPORT_SYMBOL(tape_put_device);
1277EXPORT_SYMBOL(tape_get_device_reference); 1327EXPORT_SYMBOL(tape_get_device_reference);
1278EXPORT_SYMBOL(tape_state_verbose); 1328EXPORT_SYMBOL(tape_state_verbose);
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index a7fe6302c982..38385677c653 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -112,7 +112,7 @@ struct tty3270 {
112#define TTY_UPDATE_LIST 2 /* Update lines in tty3270->update. */ 112#define TTY_UPDATE_LIST 2 /* Update lines in tty3270->update. */
113#define TTY_UPDATE_INPUT 4 /* Update input line. */ 113#define TTY_UPDATE_INPUT 4 /* Update input line. */
114#define TTY_UPDATE_STATUS 8 /* Update status line. */ 114#define TTY_UPDATE_STATUS 8 /* Update status line. */
115#define TTY_UPDATE_ALL 15 115#define TTY_UPDATE_ALL 16 /* Recreate screen. */
116 116
117static void tty3270_update(struct tty3270 *); 117static void tty3270_update(struct tty3270 *);
118 118
@@ -121,19 +121,10 @@ static void tty3270_update(struct tty3270 *);
121 */ 121 */
122static void tty3270_set_timer(struct tty3270 *tp, int expires) 122static void tty3270_set_timer(struct tty3270 *tp, int expires)
123{ 123{
124 if (expires == 0) { 124 if (expires == 0)
125 if (timer_pending(&tp->timer) && del_timer(&tp->timer)) 125 del_timer(&tp->timer);
126 raw3270_put_view(&tp->view); 126 else
127 return; 127 mod_timer(&tp->timer, jiffies + expires);
128 }
129 if (timer_pending(&tp->timer) &&
130 mod_timer(&tp->timer, jiffies + expires))
131 return;
132 raw3270_get_view(&tp->view);
133 tp->timer.function = (void (*)(unsigned long)) tty3270_update;
134 tp->timer.data = (unsigned long) tp;
135 tp->timer.expires = jiffies + expires;
136 add_timer(&tp->timer);
137} 128}
138 129
139/* 130/*
@@ -337,7 +328,6 @@ tty3270_write_callback(struct raw3270_request *rq, void *data)
337 tp = (struct tty3270 *) rq->view; 328 tp = (struct tty3270 *) rq->view;
338 if (rq->rc != 0) { 329 if (rq->rc != 0) {
339 /* Write wasn't successfull. Refresh all. */ 330 /* Write wasn't successfull. Refresh all. */
340 tty3270_rebuild_update(tp);
341 tp->update_flags = TTY_UPDATE_ALL; 331 tp->update_flags = TTY_UPDATE_ALL;
342 tty3270_set_timer(tp, 1); 332 tty3270_set_timer(tp, 1);
343 } 333 }
@@ -366,6 +356,12 @@ tty3270_update(struct tty3270 *tp)
366 356
367 spin_lock(&tp->view.lock); 357 spin_lock(&tp->view.lock);
368 updated = 0; 358 updated = 0;
359 if (tp->update_flags & TTY_UPDATE_ALL) {
360 tty3270_rebuild_update(tp);
361 tty3270_update_status(tp);
362 tp->update_flags = TTY_UPDATE_ERASE | TTY_UPDATE_LIST |
363 TTY_UPDATE_INPUT | TTY_UPDATE_STATUS;
364 }
369 if (tp->update_flags & TTY_UPDATE_ERASE) { 365 if (tp->update_flags & TTY_UPDATE_ERASE) {
370 /* Use erase write alternate to erase display. */ 366 /* Use erase write alternate to erase display. */
371 raw3270_request_set_cmd(wrq, TC_EWRITEA); 367 raw3270_request_set_cmd(wrq, TC_EWRITEA);
@@ -425,7 +421,6 @@ tty3270_update(struct tty3270 *tp)
425 xchg(&tp->write, wrq); 421 xchg(&tp->write, wrq);
426 } 422 }
427 spin_unlock(&tp->view.lock); 423 spin_unlock(&tp->view.lock);
428 raw3270_put_view(&tp->view);
429} 424}
430 425
431/* 426/*
@@ -570,7 +565,6 @@ tty3270_read_tasklet(struct raw3270_request *rrq)
570 tty3270_set_timer(tp, 1); 565 tty3270_set_timer(tp, 1);
571 } else if (tp->input->string[0] == 0x6d) { 566 } else if (tp->input->string[0] == 0x6d) {
572 /* Display has been cleared. Redraw. */ 567 /* Display has been cleared. Redraw. */
573 tty3270_rebuild_update(tp);
574 tp->update_flags = TTY_UPDATE_ALL; 568 tp->update_flags = TTY_UPDATE_ALL;
575 tty3270_set_timer(tp, 1); 569 tty3270_set_timer(tp, 1);
576 } 570 }
@@ -641,22 +635,20 @@ static int
641tty3270_activate(struct raw3270_view *view) 635tty3270_activate(struct raw3270_view *view)
642{ 636{
643 struct tty3270 *tp; 637 struct tty3270 *tp;
644 unsigned long flags;
645 638
646 tp = (struct tty3270 *) view; 639 tp = (struct tty3270 *) view;
647 spin_lock_irqsave(&tp->view.lock, flags);
648 tp->nr_up = 0;
649 tty3270_rebuild_update(tp);
650 tty3270_update_status(tp);
651 tp->update_flags = TTY_UPDATE_ALL; 640 tp->update_flags = TTY_UPDATE_ALL;
652 tty3270_set_timer(tp, 1); 641 tty3270_set_timer(tp, 1);
653 spin_unlock_irqrestore(&tp->view.lock, flags);
654 return 0; 642 return 0;
655} 643}
656 644
657static void 645static void
658tty3270_deactivate(struct raw3270_view *view) 646tty3270_deactivate(struct raw3270_view *view)
659{ 647{
648 struct tty3270 *tp;
649
650 tp = (struct tty3270 *) view;
651 del_timer(&tp->timer);
660} 652}
661 653
662static int 654static int
@@ -743,6 +735,7 @@ tty3270_free_view(struct tty3270 *tp)
743{ 735{
744 int pages; 736 int pages;
745 737
738 del_timer_sync(&tp->timer);
746 kbd_free(tp->kbd); 739 kbd_free(tp->kbd);
747 raw3270_request_free(tp->kreset); 740 raw3270_request_free(tp->kreset);
748 raw3270_request_free(tp->read); 741 raw3270_request_free(tp->read);
@@ -889,7 +882,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
889 INIT_LIST_HEAD(&tp->update); 882 INIT_LIST_HEAD(&tp->update);
890 INIT_LIST_HEAD(&tp->rcl_lines); 883 INIT_LIST_HEAD(&tp->rcl_lines);
891 tp->rcl_max = 20; 884 tp->rcl_max = 20;
892 init_timer(&tp->timer); 885 setup_timer(&tp->timer, (void (*)(unsigned long)) tty3270_update,
886 (unsigned long) tp);
893 tasklet_init(&tp->readlet, 887 tasklet_init(&tp->readlet,
894 (void (*)(unsigned long)) tty3270_read_tasklet, 888 (void (*)(unsigned long)) tty3270_read_tasklet,
895 (unsigned long) tp->read); 889 (unsigned long) tp->read);
@@ -1754,14 +1748,6 @@ static const struct tty_operations tty3270_ops = {
1754 .set_termios = tty3270_set_termios 1748 .set_termios = tty3270_set_termios
1755}; 1749};
1756 1750
1757static void tty3270_notifier(int index, int active)
1758{
1759 if (active)
1760 tty_register_device(tty3270_driver, index, NULL);
1761 else
1762 tty_unregister_device(tty3270_driver, index);
1763}
1764
1765/* 1751/*
1766 * 3270 tty registration code called from tty_init(). 1752 * 3270 tty registration code called from tty_init().
1767 * Most kernel services (incl. kmalloc) are available at this poimt. 1753 * Most kernel services (incl. kmalloc) are available at this poimt.
@@ -1796,12 +1782,6 @@ static int __init tty3270_init(void)
1796 return ret; 1782 return ret;
1797 } 1783 }
1798 tty3270_driver = driver; 1784 tty3270_driver = driver;
1799 ret = raw3270_register_notifier(tty3270_notifier);
1800 if (ret) {
1801 put_tty_driver(driver);
1802 return ret;
1803
1804 }
1805 return 0; 1785 return 0;
1806} 1786}
1807 1787
@@ -1810,7 +1790,6 @@ tty3270_exit(void)
1810{ 1790{
1811 struct tty_driver *driver; 1791 struct tty_driver *driver;
1812 1792
1813 raw3270_unregister_notifier(tty3270_notifier);
1814 driver = tty3270_driver; 1793 driver = tty3270_driver;
1815 tty3270_driver = NULL; 1794 tty3270_driver = NULL;
1816 tty_unregister_driver(driver); 1795 tty_unregister_driver(driver);
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index d8a2289fcb69..411cfa3c7719 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -3,7 +3,7 @@
3 * character device driver for reading z/VM system service records 3 * character device driver for reading z/VM system service records
4 * 4 *
5 * 5 *
6 * Copyright 2004 IBM Corporation 6 * Copyright IBM Corp. 2004, 2009
7 * character device driver for reading z/VM system service records, 7 * character device driver for reading z/VM system service records,
8 * Version 1.0 8 * Version 1.0
9 * Author(s): Xenia Tkatschow <xenia@us.ibm.com> 9 * Author(s): Xenia Tkatschow <xenia@us.ibm.com>
@@ -504,7 +504,7 @@ static ssize_t vmlogrdr_autopurge_store(struct device * dev,
504 struct device_attribute *attr, 504 struct device_attribute *attr,
505 const char * buf, size_t count) 505 const char * buf, size_t count)
506{ 506{
507 struct vmlogrdr_priv_t *priv = dev->driver_data; 507 struct vmlogrdr_priv_t *priv = dev_get_drvdata(dev);
508 ssize_t ret = count; 508 ssize_t ret = count;
509 509
510 switch (buf[0]) { 510 switch (buf[0]) {
@@ -525,7 +525,7 @@ static ssize_t vmlogrdr_autopurge_show(struct device *dev,
525 struct device_attribute *attr, 525 struct device_attribute *attr,
526 char *buf) 526 char *buf)
527{ 527{
528 struct vmlogrdr_priv_t *priv = dev->driver_data; 528 struct vmlogrdr_priv_t *priv = dev_get_drvdata(dev);
529 return sprintf(buf, "%u\n", priv->autopurge); 529 return sprintf(buf, "%u\n", priv->autopurge);
530} 530}
531 531
@@ -541,7 +541,7 @@ static ssize_t vmlogrdr_purge_store(struct device * dev,
541 541
542 char cp_command[80]; 542 char cp_command[80];
543 char cp_response[80]; 543 char cp_response[80];
544 struct vmlogrdr_priv_t *priv = dev->driver_data; 544 struct vmlogrdr_priv_t *priv = dev_get_drvdata(dev);
545 545
546 if (buf[0] != '1') 546 if (buf[0] != '1')
547 return -EINVAL; 547 return -EINVAL;
@@ -578,7 +578,7 @@ static ssize_t vmlogrdr_autorecording_store(struct device *dev,
578 struct device_attribute *attr, 578 struct device_attribute *attr,
579 const char *buf, size_t count) 579 const char *buf, size_t count)
580{ 580{
581 struct vmlogrdr_priv_t *priv = dev->driver_data; 581 struct vmlogrdr_priv_t *priv = dev_get_drvdata(dev);
582 ssize_t ret = count; 582 ssize_t ret = count;
583 583
584 switch (buf[0]) { 584 switch (buf[0]) {
@@ -599,7 +599,7 @@ static ssize_t vmlogrdr_autorecording_show(struct device *dev,
599 struct device_attribute *attr, 599 struct device_attribute *attr,
600 char *buf) 600 char *buf)
601{ 601{
602 struct vmlogrdr_priv_t *priv = dev->driver_data; 602 struct vmlogrdr_priv_t *priv = dev_get_drvdata(dev);
603 return sprintf(buf, "%u\n", priv->autorecording); 603 return sprintf(buf, "%u\n", priv->autorecording);
604} 604}
605 605
@@ -612,7 +612,7 @@ static ssize_t vmlogrdr_recording_store(struct device * dev,
612 struct device_attribute *attr, 612 struct device_attribute *attr,
613 const char * buf, size_t count) 613 const char * buf, size_t count)
614{ 614{
615 struct vmlogrdr_priv_t *priv = dev->driver_data; 615 struct vmlogrdr_priv_t *priv = dev_get_drvdata(dev);
616 ssize_t ret; 616 ssize_t ret;
617 617
618 switch (buf[0]) { 618 switch (buf[0]) {
@@ -660,6 +660,29 @@ static struct attribute *vmlogrdr_attrs[] = {
660 NULL, 660 NULL,
661}; 661};
662 662
663static int vmlogrdr_pm_prepare(struct device *dev)
664{
665 int rc;
666 struct vmlogrdr_priv_t *priv = dev->driver_data;
667
668 rc = 0;
669 if (priv) {
670 spin_lock_bh(&priv->priv_lock);
671 if (priv->dev_in_use)
672 rc = -EBUSY;
673 spin_unlock_bh(&priv->priv_lock);
674 }
675 if (rc)
676 pr_err("vmlogrdr: device %s is busy. Refuse to suspend.\n",
677 dev_name(dev));
678 return rc;
679}
680
681
682static struct dev_pm_ops vmlogrdr_pm_ops = {
683 .prepare = vmlogrdr_pm_prepare,
684};
685
663static struct attribute_group vmlogrdr_attr_group = { 686static struct attribute_group vmlogrdr_attr_group = {
664 .attrs = vmlogrdr_attrs, 687 .attrs = vmlogrdr_attrs,
665}; 688};
@@ -668,6 +691,7 @@ static struct class *vmlogrdr_class;
668static struct device_driver vmlogrdr_driver = { 691static struct device_driver vmlogrdr_driver = {
669 .name = "vmlogrdr", 692 .name = "vmlogrdr",
670 .bus = &iucv_bus, 693 .bus = &iucv_bus,
694 .pm = &vmlogrdr_pm_ops,
671}; 695};
672 696
673 697
@@ -729,6 +753,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
729 dev->bus = &iucv_bus; 753 dev->bus = &iucv_bus;
730 dev->parent = iucv_root; 754 dev->parent = iucv_root;
731 dev->driver = &vmlogrdr_driver; 755 dev->driver = &vmlogrdr_driver;
756 dev->driver_data = priv;
732 /* 757 /*
733 * The release function could be called after the 758 * The release function could be called after the
734 * module has been unloaded. It's _only_ task is to 759 * module has been unloaded. It's _only_ task is to
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 5dcef81fc9d9..7d9e67cb6471 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -2,7 +2,7 @@
2 * Linux driver for System z and s390 unit record devices 2 * Linux driver for System z and s390 unit record devices
3 * (z/VM virtual punch, reader, printer) 3 * (z/VM virtual punch, reader, printer)
4 * 4 *
5 * Copyright IBM Corp. 2001, 2007 5 * Copyright IBM Corp. 2001, 2009
6 * Authors: Malcolm Beattie <beattiem@uk.ibm.com> 6 * Authors: Malcolm Beattie <beattiem@uk.ibm.com>
7 * Michael Holzheu <holzheu@de.ibm.com> 7 * Michael Holzheu <holzheu@de.ibm.com>
8 * Frank Munzert <munzert@de.ibm.com> 8 * Frank Munzert <munzert@de.ibm.com>
@@ -60,6 +60,7 @@ static int ur_probe(struct ccw_device *cdev);
60static void ur_remove(struct ccw_device *cdev); 60static void ur_remove(struct ccw_device *cdev);
61static int ur_set_online(struct ccw_device *cdev); 61static int ur_set_online(struct ccw_device *cdev);
62static int ur_set_offline(struct ccw_device *cdev); 62static int ur_set_offline(struct ccw_device *cdev);
63static int ur_pm_suspend(struct ccw_device *cdev);
63 64
64static struct ccw_driver ur_driver = { 65static struct ccw_driver ur_driver = {
65 .name = "vmur", 66 .name = "vmur",
@@ -69,6 +70,7 @@ static struct ccw_driver ur_driver = {
69 .remove = ur_remove, 70 .remove = ur_remove,
70 .set_online = ur_set_online, 71 .set_online = ur_set_online,
71 .set_offline = ur_set_offline, 72 .set_offline = ur_set_offline,
73 .freeze = ur_pm_suspend,
72}; 74};
73 75
74static DEFINE_MUTEX(vmur_mutex); 76static DEFINE_MUTEX(vmur_mutex);
@@ -78,11 +80,11 @@ static DEFINE_MUTEX(vmur_mutex);
78 * 80 *
79 * Each ur device (urd) contains a reference to its corresponding ccw device 81 * Each ur device (urd) contains a reference to its corresponding ccw device
80 * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the 82 * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the
81 * ur device using the cdev->dev.driver_data pointer. 83 * ur device using dev_get_drvdata(&cdev->dev) pointer.
82 * 84 *
83 * urd references: 85 * urd references:
84 * - ur_probe gets a urd reference, ur_remove drops the reference 86 * - ur_probe gets a urd reference, ur_remove drops the reference
85 * (cdev->dev.driver_data) 87 * dev_get_drvdata(&cdev->dev)
86 * - ur_open gets a urd reference, ur_relase drops the reference 88 * - ur_open gets a urd reference, ur_relase drops the reference
87 * (urf->urd) 89 * (urf->urd)
88 * 90 *
@@ -90,7 +92,7 @@ static DEFINE_MUTEX(vmur_mutex);
90 * - urdev_alloc get a cdev reference (urd->cdev) 92 * - urdev_alloc get a cdev reference (urd->cdev)
91 * - urdev_free drops the cdev reference (urd->cdev) 93 * - urdev_free drops the cdev reference (urd->cdev)
92 * 94 *
93 * Setting and clearing of cdev->dev.driver_data is protected by the ccwdev lock 95 * Setting and clearing of dev_get_drvdata(&cdev->dev) is protected by the ccwdev lock
94 */ 96 */
95static struct urdev *urdev_alloc(struct ccw_device *cdev) 97static struct urdev *urdev_alloc(struct ccw_device *cdev)
96{ 98{
@@ -129,7 +131,7 @@ static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev)
129 unsigned long flags; 131 unsigned long flags;
130 132
131 spin_lock_irqsave(get_ccwdev_lock(cdev), flags); 133 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
132 urd = cdev->dev.driver_data; 134 urd = dev_get_drvdata(&cdev->dev);
133 if (urd) 135 if (urd)
134 urdev_get(urd); 136 urdev_get(urd);
135 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); 137 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
@@ -158,6 +160,28 @@ static void urdev_put(struct urdev *urd)
158} 160}
159 161
160/* 162/*
163 * State and contents of ur devices can be changed by class D users issuing
164 * CP commands such as PURGE or TRANSFER, while the Linux guest is suspended.
165 * Also the Linux guest might be logged off, which causes all active spool
166 * files to be closed.
167 * So we cannot guarantee that spool files are still the same when the Linux
168 * guest is resumed. In order to avoid unpredictable results at resume time
169 * we simply refuse to suspend if a ur device node is open.
170 */
171static int ur_pm_suspend(struct ccw_device *cdev)
172{
173 struct urdev *urd = cdev->dev.driver_data;
174
175 TRACE("ur_pm_suspend: cdev=%p\n", cdev);
176 if (urd->open_flag) {
177 pr_err("Unit record device %s is busy, %s refusing to "
178 "suspend.\n", dev_name(&cdev->dev), ur_banner);
179 return -EBUSY;
180 }
181 return 0;
182}
183
184/*
161 * Low-level functions to do I/O to a ur device. 185 * Low-level functions to do I/O to a ur device.
162 * alloc_chan_prog 186 * alloc_chan_prog
163 * free_chan_prog 187 * free_chan_prog
@@ -286,7 +310,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
286 TRACE("ur_int_handler: unsolicited interrupt\n"); 310 TRACE("ur_int_handler: unsolicited interrupt\n");
287 return; 311 return;
288 } 312 }
289 urd = cdev->dev.driver_data; 313 urd = dev_get_drvdata(&cdev->dev);
290 BUG_ON(!urd); 314 BUG_ON(!urd);
291 /* On special conditions irb is an error pointer */ 315 /* On special conditions irb is an error pointer */
292 if (IS_ERR(irb)) 316 if (IS_ERR(irb))
@@ -832,7 +856,7 @@ static int ur_probe(struct ccw_device *cdev)
832 goto fail_remove_attr; 856 goto fail_remove_attr;
833 } 857 }
834 spin_lock_irq(get_ccwdev_lock(cdev)); 858 spin_lock_irq(get_ccwdev_lock(cdev));
835 cdev->dev.driver_data = urd; 859 dev_set_drvdata(&cdev->dev, urd);
836 spin_unlock_irq(get_ccwdev_lock(cdev)); 860 spin_unlock_irq(get_ccwdev_lock(cdev));
837 861
838 mutex_unlock(&vmur_mutex); 862 mutex_unlock(&vmur_mutex);
@@ -972,8 +996,8 @@ static void ur_remove(struct ccw_device *cdev)
972 ur_remove_attributes(&cdev->dev); 996 ur_remove_attributes(&cdev->dev);
973 997
974 spin_lock_irqsave(get_ccwdev_lock(cdev), flags); 998 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
975 urdev_put(cdev->dev.driver_data); 999 urdev_put(dev_get_drvdata(&cdev->dev));
976 cdev->dev.driver_data = NULL; 1000 dev_set_drvdata(&cdev->dev, NULL);
977 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); 1001 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
978 1002
979 mutex_unlock(&vmur_mutex); 1003 mutex_unlock(&vmur_mutex);
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index 21a2a829bf4e..cb7854c10c04 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -1,17 +1,23 @@
1/* 1/*
2 * Watchdog implementation based on z/VM Watchdog Timer API 2 * Watchdog implementation based on z/VM Watchdog Timer API
3 * 3 *
4 * Copyright IBM Corp. 2004,2009
5 *
4 * The user space watchdog daemon can use this driver as 6 * The user space watchdog daemon can use this driver as
5 * /dev/vmwatchdog to have z/VM execute the specified CP 7 * /dev/vmwatchdog to have z/VM execute the specified CP
6 * command when the timeout expires. The default command is 8 * command when the timeout expires. The default command is
7 * "IPL", which which cause an immediate reboot. 9 * "IPL", which which cause an immediate reboot.
8 */ 10 */
11#define KMSG_COMPONENT "vmwatchdog"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13
9#include <linux/init.h> 14#include <linux/init.h>
10#include <linux/fs.h> 15#include <linux/fs.h>
11#include <linux/kernel.h> 16#include <linux/kernel.h>
12#include <linux/miscdevice.h> 17#include <linux/miscdevice.h>
13#include <linux/module.h> 18#include <linux/module.h>
14#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <linux/suspend.h>
15#include <linux/watchdog.h> 21#include <linux/watchdog.h>
16#include <linux/smp_lock.h> 22#include <linux/smp_lock.h>
17 23
@@ -43,6 +49,9 @@ static unsigned int vmwdt_interval = 60;
43static unsigned long vmwdt_is_open; 49static unsigned long vmwdt_is_open;
44static int vmwdt_expect_close; 50static int vmwdt_expect_close;
45 51
52#define VMWDT_OPEN 0 /* devnode is open or suspend in progress */
53#define VMWDT_RUNNING 1 /* The watchdog is armed */
54
46enum vmwdt_func { 55enum vmwdt_func {
47 /* function codes */ 56 /* function codes */
48 wdt_init = 0, 57 wdt_init = 0,
@@ -92,6 +101,7 @@ static int vmwdt_keepalive(void)
92 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN); 101 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN);
93 102
94 func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init; 103 func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init;
104 set_bit(VMWDT_RUNNING, &vmwdt_is_open);
95 ret = __diag288(func, vmwdt_interval, ebc_cmd, len); 105 ret = __diag288(func, vmwdt_interval, ebc_cmd, len);
96 WARN_ON(ret != 0); 106 WARN_ON(ret != 0);
97 kfree(ebc_cmd); 107 kfree(ebc_cmd);
@@ -102,6 +112,7 @@ static int vmwdt_disable(void)
102{ 112{
103 int ret = __diag288(wdt_cancel, 0, "", 0); 113 int ret = __diag288(wdt_cancel, 0, "", 0);
104 WARN_ON(ret != 0); 114 WARN_ON(ret != 0);
115 clear_bit(VMWDT_RUNNING, &vmwdt_is_open);
105 return ret; 116 return ret;
106} 117}
107 118
@@ -123,13 +134,13 @@ static int vmwdt_open(struct inode *i, struct file *f)
123{ 134{
124 int ret; 135 int ret;
125 lock_kernel(); 136 lock_kernel();
126 if (test_and_set_bit(0, &vmwdt_is_open)) { 137 if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
127 unlock_kernel(); 138 unlock_kernel();
128 return -EBUSY; 139 return -EBUSY;
129 } 140 }
130 ret = vmwdt_keepalive(); 141 ret = vmwdt_keepalive();
131 if (ret) 142 if (ret)
132 clear_bit(0, &vmwdt_is_open); 143 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
133 unlock_kernel(); 144 unlock_kernel();
134 return ret ? ret : nonseekable_open(i, f); 145 return ret ? ret : nonseekable_open(i, f);
135} 146}
@@ -139,7 +150,7 @@ static int vmwdt_close(struct inode *i, struct file *f)
139 if (vmwdt_expect_close == 42) 150 if (vmwdt_expect_close == 42)
140 vmwdt_disable(); 151 vmwdt_disable();
141 vmwdt_expect_close = 0; 152 vmwdt_expect_close = 0;
142 clear_bit(0, &vmwdt_is_open); 153 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
143 return 0; 154 return 0;
144} 155}
145 156
@@ -223,6 +234,57 @@ static ssize_t vmwdt_write(struct file *f, const char __user *buf,
223 return count; 234 return count;
224} 235}
225 236
237static int vmwdt_resume(void)
238{
239 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
240 return NOTIFY_DONE;
241}
242
243/*
244 * It makes no sense to go into suspend while the watchdog is running.
245 * Depending on the memory size, the watchdog might trigger, while we
246 * are still saving the memory.
247 * We reuse the open flag to ensure that suspend and watchdog open are
248 * exclusive operations
249 */
250static int vmwdt_suspend(void)
251{
252 if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
253 pr_err("The watchdog is in use. "
254 "This prevents hibernation or suspend.\n");
255 return NOTIFY_BAD;
256 }
257 if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) {
258 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
259 pr_err("The watchdog is running. "
260 "This prevents hibernation or suspend.\n");
261 return NOTIFY_BAD;
262 }
263 return NOTIFY_DONE;
264}
265
266/*
267 * This function is called for suspend and resume.
268 */
269static int vmwdt_power_event(struct notifier_block *this, unsigned long event,
270 void *ptr)
271{
272 switch (event) {
273 case PM_POST_HIBERNATION:
274 case PM_POST_SUSPEND:
275 return vmwdt_resume();
276 case PM_HIBERNATION_PREPARE:
277 case PM_SUSPEND_PREPARE:
278 return vmwdt_suspend();
279 default:
280 return NOTIFY_DONE;
281 }
282}
283
284static struct notifier_block vmwdt_power_notifier = {
285 .notifier_call = vmwdt_power_event,
286};
287
226static const struct file_operations vmwdt_fops = { 288static const struct file_operations vmwdt_fops = {
227 .open = &vmwdt_open, 289 .open = &vmwdt_open,
228 .release = &vmwdt_close, 290 .release = &vmwdt_close,
@@ -244,12 +306,21 @@ static int __init vmwdt_init(void)
244 ret = vmwdt_probe(); 306 ret = vmwdt_probe();
245 if (ret) 307 if (ret)
246 return ret; 308 return ret;
247 return misc_register(&vmwdt_dev); 309 ret = register_pm_notifier(&vmwdt_power_notifier);
310 if (ret)
311 return ret;
312 ret = misc_register(&vmwdt_dev);
313 if (ret) {
314 unregister_pm_notifier(&vmwdt_power_notifier);
315 return ret;
316 }
317 return 0;
248} 318}
249module_init(vmwdt_init); 319module_init(vmwdt_init);
250 320
251static void __exit vmwdt_exit(void) 321static void __exit vmwdt_exit(void)
252{ 322{
253 WARN_ON(misc_deregister(&vmwdt_dev) != 0); 323 unregister_pm_notifier(&vmwdt_power_notifier);
324 misc_deregister(&vmwdt_dev);
254} 325}
255module_exit(vmwdt_exit); 326module_exit(vmwdt_exit);
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 22ce765d537e..a5a62f1f7747 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/cio/ccwgroup.c
3 * bus driver for ccwgroup 2 * bus driver for ccwgroup
4 * 3 *
5 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, 4 * Copyright IBM Corp. 2002, 2009
6 * IBM Corporation 5 *
7 * Author(s): Arnd Bergmann (arndb@de.ibm.com) 6 * Author(s): Arnd Bergmann (arndb@de.ibm.com)
8 * Cornelia Huck (cornelia.huck@de.ibm.com) 7 * Cornelia Huck (cornelia.huck@de.ibm.com)
9 */ 8 */
10#include <linux/module.h> 9#include <linux/module.h>
11#include <linux/errno.h> 10#include <linux/errno.h>
@@ -501,6 +500,74 @@ static void ccwgroup_shutdown(struct device *dev)
501 gdrv->shutdown(gdev); 500 gdrv->shutdown(gdev);
502} 501}
503 502
503static int ccwgroup_pm_prepare(struct device *dev)
504{
505 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
506 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
507
508 /* Fail while device is being set online/offline. */
509 if (atomic_read(&gdev->onoff))
510 return -EAGAIN;
511
512 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
513 return 0;
514
515 return gdrv->prepare ? gdrv->prepare(gdev) : 0;
516}
517
518static void ccwgroup_pm_complete(struct device *dev)
519{
520 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
521 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
522
523 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
524 return;
525
526 if (gdrv->complete)
527 gdrv->complete(gdev);
528}
529
530static int ccwgroup_pm_freeze(struct device *dev)
531{
532 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
533 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
534
535 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
536 return 0;
537
538 return gdrv->freeze ? gdrv->freeze(gdev) : 0;
539}
540
541static int ccwgroup_pm_thaw(struct device *dev)
542{
543 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
544 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
545
546 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
547 return 0;
548
549 return gdrv->thaw ? gdrv->thaw(gdev) : 0;
550}
551
552static int ccwgroup_pm_restore(struct device *dev)
553{
554 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
555 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
556
557 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
558 return 0;
559
560 return gdrv->restore ? gdrv->restore(gdev) : 0;
561}
562
563static struct dev_pm_ops ccwgroup_pm_ops = {
564 .prepare = ccwgroup_pm_prepare,
565 .complete = ccwgroup_pm_complete,
566 .freeze = ccwgroup_pm_freeze,
567 .thaw = ccwgroup_pm_thaw,
568 .restore = ccwgroup_pm_restore,
569};
570
504static struct bus_type ccwgroup_bus_type = { 571static struct bus_type ccwgroup_bus_type = {
505 .name = "ccwgroup", 572 .name = "ccwgroup",
506 .match = ccwgroup_bus_match, 573 .match = ccwgroup_bus_match,
@@ -508,6 +575,7 @@ static struct bus_type ccwgroup_bus_type = {
508 .probe = ccwgroup_probe, 575 .probe = ccwgroup_probe,
509 .remove = ccwgroup_remove, 576 .remove = ccwgroup_remove,
510 .shutdown = ccwgroup_shutdown, 577 .shutdown = ccwgroup_shutdown,
578 .pm = &ccwgroup_pm_ops,
511}; 579};
512 580
513 581
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 883f16f96f22..1ecd3e567648 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -549,8 +549,7 @@ cleanup:
549 return ret; 549 return ret;
550} 550}
551 551
552static int 552int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
553__chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
554{ 553{
555 struct { 554 struct {
556 struct chsc_header request; 555 struct chsc_header request;
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index ba59bceace98..425e8f89a6c5 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -90,6 +90,7 @@ extern void chsc_free_sei_area(void);
90extern int chsc_enable_facility(int); 90extern int chsc_enable_facility(int);
91struct channel_subsystem; 91struct channel_subsystem;
92extern int chsc_secm(struct channel_subsystem *, int); 92extern int chsc_secm(struct channel_subsystem *, int);
93int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page);
93 94
94int chsc_chp_vary(struct chp_id chpid, int on); 95int chsc_chp_vary(struct chp_id chpid, int on);
95int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt, 96int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt,
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 93eca1731b81..cc5144b6f9d9 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * Driver for s390 chsc subchannels 2 * Driver for s390 chsc subchannels
3 * 3 *
4 * Copyright IBM Corp. 2008 4 * Copyright IBM Corp. 2008, 2009
5 *
5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> 6 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
6 * 7 *
7 */ 8 */
@@ -112,6 +113,31 @@ static void chsc_subchannel_shutdown(struct subchannel *sch)
112 cio_disable_subchannel(sch); 113 cio_disable_subchannel(sch);
113} 114}
114 115
116static int chsc_subchannel_prepare(struct subchannel *sch)
117{
118 int cc;
119 struct schib schib;
120 /*
121 * Don't allow suspend while the subchannel is not idle
122 * since we don't have a way to clear the subchannel and
123 * cannot disable it with a request running.
124 */
125 cc = stsch(sch->schid, &schib);
126 if (!cc && scsw_stctl(&schib.scsw))
127 return -EAGAIN;
128 return 0;
129}
130
131static int chsc_subchannel_freeze(struct subchannel *sch)
132{
133 return cio_disable_subchannel(sch);
134}
135
136static int chsc_subchannel_restore(struct subchannel *sch)
137{
138 return cio_enable_subchannel(sch, (u32)(unsigned long)sch);
139}
140
115static struct css_device_id chsc_subchannel_ids[] = { 141static struct css_device_id chsc_subchannel_ids[] = {
116 { .match_flags = 0x1, .type =SUBCHANNEL_TYPE_CHSC, }, 142 { .match_flags = 0x1, .type =SUBCHANNEL_TYPE_CHSC, },
117 { /* end of list */ }, 143 { /* end of list */ },
@@ -125,6 +151,10 @@ static struct css_driver chsc_subchannel_driver = {
125 .probe = chsc_subchannel_probe, 151 .probe = chsc_subchannel_probe,
126 .remove = chsc_subchannel_remove, 152 .remove = chsc_subchannel_remove,
127 .shutdown = chsc_subchannel_shutdown, 153 .shutdown = chsc_subchannel_shutdown,
154 .prepare = chsc_subchannel_prepare,
155 .freeze = chsc_subchannel_freeze,
156 .thaw = chsc_subchannel_restore,
157 .restore = chsc_subchannel_restore,
128 .name = "chsc_subchannel", 158 .name = "chsc_subchannel",
129}; 159};
130 160
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 2aebb9823044..5ec7789bd9d8 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -12,6 +12,7 @@
12#define KMSG_COMPONENT "cio" 12#define KMSG_COMPONENT "cio"
13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
14 14
15#include <linux/ftrace.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
@@ -28,7 +29,7 @@
28#include <asm/chpid.h> 29#include <asm/chpid.h>
29#include <asm/airq.h> 30#include <asm/airq.h>
30#include <asm/isc.h> 31#include <asm/isc.h>
31#include <asm/cpu.h> 32#include <asm/cputime.h>
32#include <asm/fcx.h> 33#include <asm/fcx.h>
33#include <asm/nmi.h> 34#include <asm/nmi.h>
34#include <asm/crw.h> 35#include <asm/crw.h>
@@ -626,8 +627,7 @@ out:
626 * handlers). 627 * handlers).
627 * 628 *
628 */ 629 */
629void 630void __irq_entry do_IRQ(struct pt_regs *regs)
630do_IRQ (struct pt_regs *regs)
631{ 631{
632 struct tpi_info *tpi_info; 632 struct tpi_info *tpi_info;
633 struct subchannel *sch; 633 struct subchannel *sch;
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index dc98b2c63862..30f516111307 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -1204,6 +1204,11 @@ static ssize_t cmb_enable_store(struct device *dev,
1204 1204
1205DEVICE_ATTR(cmb_enable, 0644, cmb_enable_show, cmb_enable_store); 1205DEVICE_ATTR(cmb_enable, 0644, cmb_enable_show, cmb_enable_store);
1206 1206
1207int ccw_set_cmf(struct ccw_device *cdev, int enable)
1208{
1209 return cmbops->set(cdev, enable ? 2 : 0);
1210}
1211
1207/** 1212/**
1208 * enable_cmf() - switch on the channel measurement for a specific device 1213 * enable_cmf() - switch on the channel measurement for a specific device
1209 * @cdev: The ccw device to be enabled 1214 * @cdev: The ccw device to be enabled
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 0085d8901792..85d43c6bcb66 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * drivers/s390/cio/css.c 2 * driver for channel subsystem
3 * driver for channel subsystem
4 * 3 *
5 * Copyright IBM Corp. 2002,2008 4 * Copyright IBM Corp. 2002, 2009
6 * Author(s): Arnd Bergmann (arndb@de.ibm.com) 5 *
7 * Cornelia Huck (cornelia.huck@de.ibm.com) 6 * Author(s): Arnd Bergmann (arndb@de.ibm.com)
7 * Cornelia Huck (cornelia.huck@de.ibm.com)
8 */ 8 */
9 9
10#define KMSG_COMPONENT "cio" 10#define KMSG_COMPONENT "cio"
@@ -17,6 +17,7 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/suspend.h>
20#include <asm/isc.h> 21#include <asm/isc.h>
21#include <asm/crw.h> 22#include <asm/crw.h>
22 23
@@ -780,6 +781,79 @@ static struct notifier_block css_reboot_notifier = {
780}; 781};
781 782
782/* 783/*
784 * Since the css devices are neither on a bus nor have a class
785 * nor have a special device type, we cannot stop/restart channel
786 * path measurements via the normal suspend/resume callbacks, but have
787 * to use notifiers.
788 */
789static int css_power_event(struct notifier_block *this, unsigned long event,
790 void *ptr)
791{
792 void *secm_area;
793 int ret, i;
794
795 switch (event) {
796 case PM_HIBERNATION_PREPARE:
797 case PM_SUSPEND_PREPARE:
798 ret = NOTIFY_DONE;
799 for (i = 0; i <= __MAX_CSSID; i++) {
800 struct channel_subsystem *css;
801
802 css = channel_subsystems[i];
803 mutex_lock(&css->mutex);
804 if (!css->cm_enabled) {
805 mutex_unlock(&css->mutex);
806 continue;
807 }
808 secm_area = (void *)get_zeroed_page(GFP_KERNEL |
809 GFP_DMA);
810 if (secm_area) {
811 if (__chsc_do_secm(css, 0, secm_area))
812 ret = NOTIFY_BAD;
813 free_page((unsigned long)secm_area);
814 } else
815 ret = NOTIFY_BAD;
816
817 mutex_unlock(&css->mutex);
818 }
819 break;
820 case PM_POST_HIBERNATION:
821 case PM_POST_SUSPEND:
822 ret = NOTIFY_DONE;
823 for (i = 0; i <= __MAX_CSSID; i++) {
824 struct channel_subsystem *css;
825
826 css = channel_subsystems[i];
827 mutex_lock(&css->mutex);
828 if (!css->cm_enabled) {
829 mutex_unlock(&css->mutex);
830 continue;
831 }
832 secm_area = (void *)get_zeroed_page(GFP_KERNEL |
833 GFP_DMA);
834 if (secm_area) {
835 if (__chsc_do_secm(css, 1, secm_area))
836 ret = NOTIFY_BAD;
837 free_page((unsigned long)secm_area);
838 } else
839 ret = NOTIFY_BAD;
840
841 mutex_unlock(&css->mutex);
842 }
843 /* search for subchannels, which appeared during hibernation */
844 css_schedule_reprobe();
845 break;
846 default:
847 ret = NOTIFY_DONE;
848 }
849 return ret;
850
851}
852static struct notifier_block css_power_notifier = {
853 .notifier_call = css_power_event,
854};
855
856/*
783 * Now that the driver core is running, we can setup our channel subsystem. 857 * Now that the driver core is running, we can setup our channel subsystem.
784 * The struct subchannel's are created during probing (except for the 858 * The struct subchannel's are created during probing (except for the
785 * static console subchannel). 859 * static console subchannel).
@@ -852,6 +926,11 @@ init_channel_subsystem (void)
852 ret = register_reboot_notifier(&css_reboot_notifier); 926 ret = register_reboot_notifier(&css_reboot_notifier);
853 if (ret) 927 if (ret)
854 goto out_unregister; 928 goto out_unregister;
929 ret = register_pm_notifier(&css_power_notifier);
930 if (ret) {
931 unregister_reboot_notifier(&css_reboot_notifier);
932 goto out_unregister;
933 }
855 css_init_done = 1; 934 css_init_done = 1;
856 935
857 /* Enable default isc for I/O subchannels. */ 936 /* Enable default isc for I/O subchannels. */
@@ -953,6 +1032,73 @@ static int css_uevent(struct device *dev, struct kobj_uevent_env *env)
953 return ret; 1032 return ret;
954} 1033}
955 1034
1035static int css_pm_prepare(struct device *dev)
1036{
1037 struct subchannel *sch = to_subchannel(dev);
1038 struct css_driver *drv;
1039
1040 if (mutex_is_locked(&sch->reg_mutex))
1041 return -EAGAIN;
1042 if (!sch->dev.driver)
1043 return 0;
1044 drv = to_cssdriver(sch->dev.driver);
1045 /* Notify drivers that they may not register children. */
1046 return drv->prepare ? drv->prepare(sch) : 0;
1047}
1048
1049static void css_pm_complete(struct device *dev)
1050{
1051 struct subchannel *sch = to_subchannel(dev);
1052 struct css_driver *drv;
1053
1054 if (!sch->dev.driver)
1055 return;
1056 drv = to_cssdriver(sch->dev.driver);
1057 if (drv->complete)
1058 drv->complete(sch);
1059}
1060
1061static int css_pm_freeze(struct device *dev)
1062{
1063 struct subchannel *sch = to_subchannel(dev);
1064 struct css_driver *drv;
1065
1066 if (!sch->dev.driver)
1067 return 0;
1068 drv = to_cssdriver(sch->dev.driver);
1069 return drv->freeze ? drv->freeze(sch) : 0;
1070}
1071
1072static int css_pm_thaw(struct device *dev)
1073{
1074 struct subchannel *sch = to_subchannel(dev);
1075 struct css_driver *drv;
1076
1077 if (!sch->dev.driver)
1078 return 0;
1079 drv = to_cssdriver(sch->dev.driver);
1080 return drv->thaw ? drv->thaw(sch) : 0;
1081}
1082
1083static int css_pm_restore(struct device *dev)
1084{
1085 struct subchannel *sch = to_subchannel(dev);
1086 struct css_driver *drv;
1087
1088 if (!sch->dev.driver)
1089 return 0;
1090 drv = to_cssdriver(sch->dev.driver);
1091 return drv->restore ? drv->restore(sch) : 0;
1092}
1093
1094static struct dev_pm_ops css_pm_ops = {
1095 .prepare = css_pm_prepare,
1096 .complete = css_pm_complete,
1097 .freeze = css_pm_freeze,
1098 .thaw = css_pm_thaw,
1099 .restore = css_pm_restore,
1100};
1101
956struct bus_type css_bus_type = { 1102struct bus_type css_bus_type = {
957 .name = "css", 1103 .name = "css",
958 .match = css_bus_match, 1104 .match = css_bus_match,
@@ -960,6 +1106,7 @@ struct bus_type css_bus_type = {
960 .remove = css_remove, 1106 .remove = css_remove,
961 .shutdown = css_shutdown, 1107 .shutdown = css_shutdown,
962 .uevent = css_uevent, 1108 .uevent = css_uevent,
1109 .pm = &css_pm_ops,
963}; 1110};
964 1111
965/** 1112/**
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 57ebf120f825..9763eeec7458 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -70,6 +70,11 @@ struct chp_link;
70 * @probe: function called on probe 70 * @probe: function called on probe
71 * @remove: function called on remove 71 * @remove: function called on remove
72 * @shutdown: called at device shutdown 72 * @shutdown: called at device shutdown
73 * @prepare: prepare for pm state transition
74 * @complete: undo work done in @prepare
75 * @freeze: callback for freezing during hibernation snapshotting
76 * @thaw: undo work done in @freeze
77 * @restore: callback for restoring after hibernation
73 * @name: name of the device driver 78 * @name: name of the device driver
74 */ 79 */
75struct css_driver { 80struct css_driver {
@@ -82,6 +87,11 @@ struct css_driver {
82 int (*probe)(struct subchannel *); 87 int (*probe)(struct subchannel *);
83 int (*remove)(struct subchannel *); 88 int (*remove)(struct subchannel *);
84 void (*shutdown)(struct subchannel *); 89 void (*shutdown)(struct subchannel *);
90 int (*prepare) (struct subchannel *);
91 void (*complete) (struct subchannel *);
92 int (*freeze)(struct subchannel *);
93 int (*thaw) (struct subchannel *);
94 int (*restore)(struct subchannel *);
85 const char *name; 95 const char *name;
86}; 96};
87 97
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 35441fa16be1..3c57c1a18bb8 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -138,6 +138,19 @@ static struct css_device_id io_subchannel_ids[] = {
138}; 138};
139MODULE_DEVICE_TABLE(css, io_subchannel_ids); 139MODULE_DEVICE_TABLE(css, io_subchannel_ids);
140 140
141static int io_subchannel_prepare(struct subchannel *sch)
142{
143 struct ccw_device *cdev;
144 /*
145 * Don't allow suspend while a ccw device registration
146 * is still outstanding.
147 */
148 cdev = sch_get_cdev(sch);
149 if (cdev && !device_is_registered(&cdev->dev))
150 return -EAGAIN;
151 return 0;
152}
153
141static struct css_driver io_subchannel_driver = { 154static struct css_driver io_subchannel_driver = {
142 .owner = THIS_MODULE, 155 .owner = THIS_MODULE,
143 .subchannel_type = io_subchannel_ids, 156 .subchannel_type = io_subchannel_ids,
@@ -148,6 +161,7 @@ static struct css_driver io_subchannel_driver = {
148 .probe = io_subchannel_probe, 161 .probe = io_subchannel_probe,
149 .remove = io_subchannel_remove, 162 .remove = io_subchannel_remove,
150 .shutdown = io_subchannel_shutdown, 163 .shutdown = io_subchannel_shutdown,
164 .prepare = io_subchannel_prepare,
151}; 165};
152 166
153struct workqueue_struct *ccw_device_work; 167struct workqueue_struct *ccw_device_work;
@@ -1775,6 +1789,15 @@ ccw_device_probe_console(void)
1775 return &console_cdev; 1789 return &console_cdev;
1776} 1790}
1777 1791
1792static int ccw_device_pm_restore(struct device *dev);
1793
1794int ccw_device_force_console(void)
1795{
1796 if (!console_cdev_in_use)
1797 return -ENODEV;
1798 return ccw_device_pm_restore(&console_cdev.dev);
1799}
1800EXPORT_SYMBOL_GPL(ccw_device_force_console);
1778 1801
1779const char *cio_get_console_cdev_name(struct subchannel *sch) 1802const char *cio_get_console_cdev_name(struct subchannel *sch)
1780{ 1803{
@@ -1895,6 +1918,242 @@ static void ccw_device_shutdown(struct device *dev)
1895 disable_cmf(cdev); 1918 disable_cmf(cdev);
1896} 1919}
1897 1920
1921static int ccw_device_pm_prepare(struct device *dev)
1922{
1923 struct ccw_device *cdev = to_ccwdev(dev);
1924
1925 if (work_pending(&cdev->private->kick_work))
1926 return -EAGAIN;
1927 /* Fail while device is being set online/offline. */
1928 if (atomic_read(&cdev->private->onoff))
1929 return -EAGAIN;
1930
1931 if (cdev->online && cdev->drv && cdev->drv->prepare)
1932 return cdev->drv->prepare(cdev);
1933
1934 return 0;
1935}
1936
1937static void ccw_device_pm_complete(struct device *dev)
1938{
1939 struct ccw_device *cdev = to_ccwdev(dev);
1940
1941 if (cdev->online && cdev->drv && cdev->drv->complete)
1942 cdev->drv->complete(cdev);
1943}
1944
1945static int ccw_device_pm_freeze(struct device *dev)
1946{
1947 struct ccw_device *cdev = to_ccwdev(dev);
1948 struct subchannel *sch = to_subchannel(cdev->dev.parent);
1949 int ret, cm_enabled;
1950
1951 /* Fail suspend while device is in transistional state. */
1952 if (!dev_fsm_final_state(cdev))
1953 return -EAGAIN;
1954 if (!cdev->online)
1955 return 0;
1956 if (cdev->drv && cdev->drv->freeze) {
1957 ret = cdev->drv->freeze(cdev);
1958 if (ret)
1959 return ret;
1960 }
1961
1962 spin_lock_irq(sch->lock);
1963 cm_enabled = cdev->private->cmb != NULL;
1964 spin_unlock_irq(sch->lock);
1965 if (cm_enabled) {
1966 /* Don't have the css write on memory. */
1967 ret = ccw_set_cmf(cdev, 0);
1968 if (ret)
1969 return ret;
1970 }
1971 /* From here on, disallow device driver I/O. */
1972 spin_lock_irq(sch->lock);
1973 ret = cio_disable_subchannel(sch);
1974 spin_unlock_irq(sch->lock);
1975
1976 return ret;
1977}
1978
1979static int ccw_device_pm_thaw(struct device *dev)
1980{
1981 struct ccw_device *cdev = to_ccwdev(dev);
1982 struct subchannel *sch = to_subchannel(cdev->dev.parent);
1983 int ret, cm_enabled;
1984
1985 if (!cdev->online)
1986 return 0;
1987
1988 spin_lock_irq(sch->lock);
1989 /* Allow device driver I/O again. */
1990 ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
1991 cm_enabled = cdev->private->cmb != NULL;
1992 spin_unlock_irq(sch->lock);
1993 if (ret)
1994 return ret;
1995
1996 if (cm_enabled) {
1997 ret = ccw_set_cmf(cdev, 1);
1998 if (ret)
1999 return ret;
2000 }
2001
2002 if (cdev->drv && cdev->drv->thaw)
2003 ret = cdev->drv->thaw(cdev);
2004
2005 return ret;
2006}
2007
2008static void __ccw_device_pm_restore(struct ccw_device *cdev)
2009{
2010 struct subchannel *sch = to_subchannel(cdev->dev.parent);
2011 int ret;
2012
2013 if (cio_is_console(sch->schid))
2014 goto out;
2015 /*
2016 * While we were sleeping, devices may have gone or become
2017 * available again. Kick re-detection.
2018 */
2019 spin_lock_irq(sch->lock);
2020 cdev->private->flags.resuming = 1;
2021 ret = ccw_device_recognition(cdev);
2022 spin_unlock_irq(sch->lock);
2023 if (ret) {
2024 CIO_MSG_EVENT(0, "Couldn't start recognition for device "
2025 "%s (ret=%d)\n", dev_name(&cdev->dev), ret);
2026 spin_lock_irq(sch->lock);
2027 cdev->private->state = DEV_STATE_DISCONNECTED;
2028 spin_unlock_irq(sch->lock);
2029 /* notify driver after the resume cb */
2030 goto out;
2031 }
2032 wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev) ||
2033 cdev->private->state == DEV_STATE_DISCONNECTED);
2034
2035out:
2036 cdev->private->flags.resuming = 0;
2037}
2038
2039static int resume_handle_boxed(struct ccw_device *cdev)
2040{
2041 cdev->private->state = DEV_STATE_BOXED;
2042 if (ccw_device_notify(cdev, CIO_BOXED))
2043 return 0;
2044 ccw_device_schedule_sch_unregister(cdev);
2045 return -ENODEV;
2046}
2047
2048static int resume_handle_disc(struct ccw_device *cdev)
2049{
2050 cdev->private->state = DEV_STATE_DISCONNECTED;
2051 if (ccw_device_notify(cdev, CIO_GONE))
2052 return 0;
2053 ccw_device_schedule_sch_unregister(cdev);
2054 return -ENODEV;
2055}
2056
2057static int ccw_device_pm_restore(struct device *dev)
2058{
2059 struct ccw_device *cdev = to_ccwdev(dev);
2060 struct subchannel *sch = to_subchannel(cdev->dev.parent);
2061 int ret = 0, cm_enabled;
2062
2063 __ccw_device_pm_restore(cdev);
2064 spin_lock_irq(sch->lock);
2065 if (cio_is_console(sch->schid)) {
2066 cio_enable_subchannel(sch, (u32)(addr_t)sch);
2067 spin_unlock_irq(sch->lock);
2068 goto out_restore;
2069 }
2070 cdev->private->flags.donotify = 0;
2071 /* check recognition results */
2072 switch (cdev->private->state) {
2073 case DEV_STATE_OFFLINE:
2074 break;
2075 case DEV_STATE_BOXED:
2076 ret = resume_handle_boxed(cdev);
2077 spin_unlock_irq(sch->lock);
2078 if (ret)
2079 goto out;
2080 goto out_restore;
2081 case DEV_STATE_DISCONNECTED:
2082 goto out_disc_unlock;
2083 default:
2084 goto out_unreg_unlock;
2085 }
2086 /* check if the device id has changed */
2087 if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
2088 CIO_MSG_EVENT(0, "resume: sch %s: failed (devno changed from "
2089 "%04x to %04x)\n", dev_name(&sch->dev),
2090 cdev->private->dev_id.devno,
2091 sch->schib.pmcw.dev);
2092 goto out_unreg_unlock;
2093 }
2094 /* check if the device type has changed */
2095 if (!ccw_device_test_sense_data(cdev)) {
2096 ccw_device_update_sense_data(cdev);
2097 PREPARE_WORK(&cdev->private->kick_work,
2098 ccw_device_do_unbind_bind);
2099 queue_work(ccw_device_work, &cdev->private->kick_work);
2100 ret = -ENODEV;
2101 goto out_unlock;
2102 }
2103 if (!cdev->online) {
2104 ret = 0;
2105 goto out_unlock;
2106 }
2107 ret = ccw_device_online(cdev);
2108 if (ret)
2109 goto out_disc_unlock;
2110
2111 cm_enabled = cdev->private->cmb != NULL;
2112 spin_unlock_irq(sch->lock);
2113
2114 wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
2115 if (cdev->private->state != DEV_STATE_ONLINE) {
2116 spin_lock_irq(sch->lock);
2117 goto out_disc_unlock;
2118 }
2119 if (cm_enabled) {
2120 ret = ccw_set_cmf(cdev, 1);
2121 if (ret) {
2122 CIO_MSG_EVENT(2, "resume: cdev %s: cmf failed "
2123 "(rc=%d)\n", dev_name(&cdev->dev), ret);
2124 ret = 0;
2125 }
2126 }
2127
2128out_restore:
2129 if (cdev->online && cdev->drv && cdev->drv->restore)
2130 ret = cdev->drv->restore(cdev);
2131out:
2132 return ret;
2133
2134out_disc_unlock:
2135 ret = resume_handle_disc(cdev);
2136 spin_unlock_irq(sch->lock);
2137 if (ret)
2138 return ret;
2139 goto out_restore;
2140
2141out_unreg_unlock:
2142 ccw_device_schedule_sch_unregister(cdev);
2143 ret = -ENODEV;
2144out_unlock:
2145 spin_unlock_irq(sch->lock);
2146 return ret;
2147}
2148
2149static struct dev_pm_ops ccw_pm_ops = {
2150 .prepare = ccw_device_pm_prepare,
2151 .complete = ccw_device_pm_complete,
2152 .freeze = ccw_device_pm_freeze,
2153 .thaw = ccw_device_pm_thaw,
2154 .restore = ccw_device_pm_restore,
2155};
2156
1898struct bus_type ccw_bus_type = { 2157struct bus_type ccw_bus_type = {
1899 .name = "ccw", 2158 .name = "ccw",
1900 .match = ccw_bus_match, 2159 .match = ccw_bus_match,
@@ -1902,6 +2161,7 @@ struct bus_type ccw_bus_type = {
1902 .probe = ccw_device_probe, 2161 .probe = ccw_device_probe,
1903 .remove = ccw_device_remove, 2162 .remove = ccw_device_remove,
1904 .shutdown = ccw_device_shutdown, 2163 .shutdown = ccw_device_shutdown,
2164 .pm = &ccw_pm_ops,
1905}; 2165};
1906 2166
1907/** 2167/**
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index f1cbbd94ad4e..e3975107a578 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -87,6 +87,8 @@ int ccw_device_is_orphan(struct ccw_device *);
87int ccw_device_recognition(struct ccw_device *); 87int ccw_device_recognition(struct ccw_device *);
88int ccw_device_online(struct ccw_device *); 88int ccw_device_online(struct ccw_device *);
89int ccw_device_offline(struct ccw_device *); 89int ccw_device_offline(struct ccw_device *);
90void ccw_device_update_sense_data(struct ccw_device *);
91int ccw_device_test_sense_data(struct ccw_device *);
90void ccw_device_schedule_sch_unregister(struct ccw_device *); 92void ccw_device_schedule_sch_unregister(struct ccw_device *);
91int ccw_purge_blacklisted(void); 93int ccw_purge_blacklisted(void);
92 94
@@ -133,5 +135,6 @@ extern struct bus_type ccw_bus_type;
133void retry_set_schib(struct ccw_device *cdev); 135void retry_set_schib(struct ccw_device *cdev);
134void cmf_retry_copy_block(struct ccw_device *); 136void cmf_retry_copy_block(struct ccw_device *);
135int cmf_reenable(struct ccw_device *); 137int cmf_reenable(struct ccw_device *);
138int ccw_set_cmf(struct ccw_device *cdev, int enable);
136extern struct device_attribute dev_attr_cmb_enable; 139extern struct device_attribute dev_attr_cmb_enable;
137#endif 140#endif
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index e46049261561..3db88c52d287 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -177,29 +177,21 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev)
177 panic("Can't stop i/o on subchannel.\n"); 177 panic("Can't stop i/o on subchannel.\n");
178} 178}
179 179
180static int 180void ccw_device_update_sense_data(struct ccw_device *cdev)
181ccw_device_handle_oper(struct ccw_device *cdev)
182{ 181{
183 struct subchannel *sch; 182 memset(&cdev->id, 0, sizeof(cdev->id));
183 cdev->id.cu_type = cdev->private->senseid.cu_type;
184 cdev->id.cu_model = cdev->private->senseid.cu_model;
185 cdev->id.dev_type = cdev->private->senseid.dev_type;
186 cdev->id.dev_model = cdev->private->senseid.dev_model;
187}
184 188
185 sch = to_subchannel(cdev->dev.parent); 189int ccw_device_test_sense_data(struct ccw_device *cdev)
186 cdev->private->flags.recog_done = 1; 190{
187 /* 191 return cdev->id.cu_type == cdev->private->senseid.cu_type &&
188 * Check if cu type and device type still match. If 192 cdev->id.cu_model == cdev->private->senseid.cu_model &&
189 * not, it is certainly another device and we have to 193 cdev->id.dev_type == cdev->private->senseid.dev_type &&
190 * de- and re-register. 194 cdev->id.dev_model == cdev->private->senseid.dev_model;
191 */
192 if (cdev->id.cu_type != cdev->private->senseid.cu_type ||
193 cdev->id.cu_model != cdev->private->senseid.cu_model ||
194 cdev->id.dev_type != cdev->private->senseid.dev_type ||
195 cdev->id.dev_model != cdev->private->senseid.dev_model) {
196 PREPARE_WORK(&cdev->private->kick_work,
197 ccw_device_do_unbind_bind);
198 queue_work(ccw_device_work, &cdev->private->kick_work);
199 return 0;
200 }
201 cdev->private->flags.donotify = 1;
202 return 1;
203} 195}
204 196
205/* 197/*
@@ -233,7 +225,7 @@ static void
233ccw_device_recog_done(struct ccw_device *cdev, int state) 225ccw_device_recog_done(struct ccw_device *cdev, int state)
234{ 226{
235 struct subchannel *sch; 227 struct subchannel *sch;
236 int notify, old_lpm, same_dev; 228 int old_lpm;
237 229
238 sch = to_subchannel(cdev->dev.parent); 230 sch = to_subchannel(cdev->dev.parent);
239 231
@@ -263,8 +255,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
263 wake_up(&cdev->private->wait_q); 255 wake_up(&cdev->private->wait_q);
264 return; 256 return;
265 } 257 }
266 notify = 0; 258 if (cdev->private->flags.resuming) {
267 same_dev = 0; /* Keep the compiler quiet... */ 259 cdev->private->state = state;
260 cdev->private->flags.recog_done = 1;
261 wake_up(&cdev->private->wait_q);
262 return;
263 }
268 switch (state) { 264 switch (state) {
269 case DEV_STATE_NOT_OPER: 265 case DEV_STATE_NOT_OPER:
270 CIO_MSG_EVENT(2, "SenseID : unknown device %04x on " 266 CIO_MSG_EVENT(2, "SenseID : unknown device %04x on "
@@ -273,34 +269,31 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
273 sch->schid.ssid, sch->schid.sch_no); 269 sch->schid.ssid, sch->schid.sch_no);
274 break; 270 break;
275 case DEV_STATE_OFFLINE: 271 case DEV_STATE_OFFLINE:
276 if (cdev->online) { 272 if (!cdev->online) {
277 same_dev = ccw_device_handle_oper(cdev); 273 ccw_device_update_sense_data(cdev);
278 notify = 1; 274 /* Issue device info message. */
275 CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: "
276 "CU Type/Mod = %04X/%02X, Dev Type/Mod "
277 "= %04X/%02X\n",
278 cdev->private->dev_id.ssid,
279 cdev->private->dev_id.devno,
280 cdev->id.cu_type, cdev->id.cu_model,
281 cdev->id.dev_type, cdev->id.dev_model);
282 break;
279 } 283 }
280 /* fill out sense information */ 284 cdev->private->state = DEV_STATE_OFFLINE;
281 memset(&cdev->id, 0, sizeof(cdev->id)); 285 cdev->private->flags.recog_done = 1;
282 cdev->id.cu_type = cdev->private->senseid.cu_type; 286 if (ccw_device_test_sense_data(cdev)) {
283 cdev->id.cu_model = cdev->private->senseid.cu_model; 287 cdev->private->flags.donotify = 1;
284 cdev->id.dev_type = cdev->private->senseid.dev_type; 288 ccw_device_online(cdev);
285 cdev->id.dev_model = cdev->private->senseid.dev_model; 289 wake_up(&cdev->private->wait_q);
286 if (notify) { 290 } else {
287 cdev->private->state = DEV_STATE_OFFLINE; 291 ccw_device_update_sense_data(cdev);
288 if (same_dev) { 292 PREPARE_WORK(&cdev->private->kick_work,
289 /* Get device online again. */ 293 ccw_device_do_unbind_bind);
290 ccw_device_online(cdev); 294 queue_work(ccw_device_work, &cdev->private->kick_work);
291 wake_up(&cdev->private->wait_q);
292 }
293 return;
294 } 295 }
295 /* Issue device info message. */ 296 return;
296 CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: "
297 "CU Type/Mod = %04X/%02X, Dev Type/Mod = "
298 "%04X/%02X\n",
299 cdev->private->dev_id.ssid,
300 cdev->private->dev_id.devno,
301 cdev->id.cu_type, cdev->id.cu_model,
302 cdev->id.dev_type, cdev->id.dev_model);
303 break;
304 case DEV_STATE_BOXED: 297 case DEV_STATE_BOXED:
305 CIO_MSG_EVENT(0, "SenseID : boxed device %04x on " 298 CIO_MSG_EVENT(0, "SenseID : boxed device %04x on "
306 " subchannel 0.%x.%04x\n", 299 " subchannel 0.%x.%04x\n",
@@ -502,9 +495,6 @@ ccw_device_recognition(struct ccw_device *cdev)
502 struct subchannel *sch; 495 struct subchannel *sch;
503 int ret; 496 int ret;
504 497
505 if ((cdev->private->state != DEV_STATE_NOT_OPER) &&
506 (cdev->private->state != DEV_STATE_BOXED))
507 return -EINVAL;
508 sch = to_subchannel(cdev->dev.parent); 498 sch = to_subchannel(cdev->dev.parent);
509 ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); 499 ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
510 if (ret != 0) 500 if (ret != 0)
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 151754d54745..2d0efee8a290 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -1,10 +1,8 @@
1/* 1/*
2 * drivers/s390/cio/device_ops.c 2 * Copyright IBM Corp. 2002, 2009
3 * 3 *
4 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, 4 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
5 * IBM Corporation 5 * Cornelia Huck (cornelia.huck@de.ibm.com)
6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
7 * Cornelia Huck (cornelia.huck@de.ibm.com)
8 */ 6 */
9#include <linux/module.h> 7#include <linux/module.h>
10#include <linux/init.h> 8#include <linux/init.h>
@@ -114,16 +112,17 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
114 struct subchannel *sch; 112 struct subchannel *sch;
115 int ret; 113 int ret;
116 114
117 if (!cdev) 115 if (!cdev || !cdev->dev.parent)
118 return -ENODEV; 116 return -ENODEV;
117 sch = to_subchannel(cdev->dev.parent);
118 if (!sch->schib.pmcw.ena)
119 return -EINVAL;
119 if (cdev->private->state == DEV_STATE_NOT_OPER) 120 if (cdev->private->state == DEV_STATE_NOT_OPER)
120 return -ENODEV; 121 return -ENODEV;
121 if (cdev->private->state != DEV_STATE_ONLINE && 122 if (cdev->private->state != DEV_STATE_ONLINE &&
122 cdev->private->state != DEV_STATE_W4SENSE) 123 cdev->private->state != DEV_STATE_W4SENSE)
123 return -EINVAL; 124 return -EINVAL;
124 sch = to_subchannel(cdev->dev.parent); 125
125 if (!sch)
126 return -ENODEV;
127 ret = cio_clear(sch); 126 ret = cio_clear(sch);
128 if (ret == 0) 127 if (ret == 0)
129 cdev->private->intparm = intparm; 128 cdev->private->intparm = intparm;
@@ -161,11 +160,11 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
161 struct subchannel *sch; 160 struct subchannel *sch;
162 int ret; 161 int ret;
163 162
164 if (!cdev) 163 if (!cdev || !cdev->dev.parent)
165 return -ENODEV; 164 return -ENODEV;
166 sch = to_subchannel(cdev->dev.parent); 165 sch = to_subchannel(cdev->dev.parent);
167 if (!sch) 166 if (!sch->schib.pmcw.ena)
168 return -ENODEV; 167 return -EINVAL;
169 if (cdev->private->state == DEV_STATE_NOT_OPER) 168 if (cdev->private->state == DEV_STATE_NOT_OPER)
170 return -ENODEV; 169 return -ENODEV;
171 if (cdev->private->state == DEV_STATE_VERIFY || 170 if (cdev->private->state == DEV_STATE_VERIFY ||
@@ -339,16 +338,17 @@ int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
339 struct subchannel *sch; 338 struct subchannel *sch;
340 int ret; 339 int ret;
341 340
342 if (!cdev) 341 if (!cdev || !cdev->dev.parent)
343 return -ENODEV; 342 return -ENODEV;
343 sch = to_subchannel(cdev->dev.parent);
344 if (!sch->schib.pmcw.ena)
345 return -EINVAL;
344 if (cdev->private->state == DEV_STATE_NOT_OPER) 346 if (cdev->private->state == DEV_STATE_NOT_OPER)
345 return -ENODEV; 347 return -ENODEV;
346 if (cdev->private->state != DEV_STATE_ONLINE && 348 if (cdev->private->state != DEV_STATE_ONLINE &&
347 cdev->private->state != DEV_STATE_W4SENSE) 349 cdev->private->state != DEV_STATE_W4SENSE)
348 return -EINVAL; 350 return -EINVAL;
349 sch = to_subchannel(cdev->dev.parent); 351
350 if (!sch)
351 return -ENODEV;
352 ret = cio_halt(sch); 352 ret = cio_halt(sch);
353 if (ret == 0) 353 if (ret == 0)
354 cdev->private->intparm = intparm; 354 cdev->private->intparm = intparm;
@@ -372,11 +372,11 @@ int ccw_device_resume(struct ccw_device *cdev)
372{ 372{
373 struct subchannel *sch; 373 struct subchannel *sch;
374 374
375 if (!cdev) 375 if (!cdev || !cdev->dev.parent)
376 return -ENODEV; 376 return -ENODEV;
377 sch = to_subchannel(cdev->dev.parent); 377 sch = to_subchannel(cdev->dev.parent);
378 if (!sch) 378 if (!sch->schib.pmcw.ena)
379 return -ENODEV; 379 return -EINVAL;
380 if (cdev->private->state == DEV_STATE_NOT_OPER) 380 if (cdev->private->state == DEV_STATE_NOT_OPER)
381 return -ENODEV; 381 return -ENODEV;
382 if (cdev->private->state != DEV_STATE_ONLINE || 382 if (cdev->private->state != DEV_STATE_ONLINE ||
@@ -471,11 +471,11 @@ __u8 ccw_device_get_path_mask(struct ccw_device *cdev)
471{ 471{
472 struct subchannel *sch; 472 struct subchannel *sch;
473 473
474 sch = to_subchannel(cdev->dev.parent); 474 if (!cdev->dev.parent)
475 if (!sch)
476 return 0; 475 return 0;
477 else 476
478 return sch->lpm; 477 sch = to_subchannel(cdev->dev.parent);
478 return sch->lpm;
479} 479}
480 480
481/* 481/*
@@ -588,6 +588,8 @@ int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
588 int rc; 588 int rc;
589 589
590 sch = to_subchannel(cdev->dev.parent); 590 sch = to_subchannel(cdev->dev.parent);
591 if (!sch->schib.pmcw.ena)
592 return -EINVAL;
591 if (cdev->private->state != DEV_STATE_ONLINE) 593 if (cdev->private->state != DEV_STATE_ONLINE)
592 return -EIO; 594 return -EIO;
593 /* Adjust requested path mask to excluded varied off paths. */ 595 /* Adjust requested path mask to excluded varied off paths. */
@@ -677,6 +679,8 @@ int ccw_device_tm_intrg(struct ccw_device *cdev)
677{ 679{
678 struct subchannel *sch = to_subchannel(cdev->dev.parent); 680 struct subchannel *sch = to_subchannel(cdev->dev.parent);
679 681
682 if (!sch->schib.pmcw.ena)
683 return -EINVAL;
680 if (cdev->private->state != DEV_STATE_ONLINE) 684 if (cdev->private->state != DEV_STATE_ONLINE)
681 return -EIO; 685 return -EIO;
682 if (!scsw_is_tm(&sch->schib.scsw) || 686 if (!scsw_is_tm(&sch->schib.scsw) ||
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h
index c4f3e7c9a854..0b8f381bd20e 100644
--- a/drivers/s390/cio/io_sch.h
+++ b/drivers/s390/cio/io_sch.h
@@ -107,6 +107,7 @@ struct ccw_device_private {
107 unsigned int recog_done:1; /* dev. recog. complete */ 107 unsigned int recog_done:1; /* dev. recog. complete */
108 unsigned int fake_irb:1; /* deliver faked irb */ 108 unsigned int fake_irb:1; /* deliver faked irb */
109 unsigned int intretry:1; /* retry internal operation */ 109 unsigned int intretry:1; /* retry internal operation */
110 unsigned int resuming:1; /* recognition while resume */
110 } __attribute__((packed)) flags; 111 } __attribute__((packed)) flags;
111 unsigned long intparm; /* user interruption parameter */ 112 unsigned long intparm; /* user interruption parameter */
112 struct qdio_irq *qdio_data; 113 struct qdio_irq *qdio_data;
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index accd957454e7..d79cf5bf0e62 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -881,42 +881,26 @@ no_handler:
881 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); 881 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
882} 882}
883 883
884static int qdio_establish_check_errors(struct ccw_device *cdev, int cstat, 884static void qdio_establish_handle_irq(struct ccw_device *cdev, int cstat,
885 int dstat) 885 int dstat)
886{ 886{
887 struct qdio_irq *irq_ptr = cdev->private->qdio_data; 887 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
888 888
889 if (cstat || (dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END))) { 889 DBF_DEV_EVENT(DBF_INFO, irq_ptr, "qest irq");
890 DBF_ERROR("EQ:ck con");
891 goto error;
892 }
893 890
894 if (!(dstat & DEV_STAT_DEV_END)) { 891 if (cstat)
895 DBF_ERROR("EQ:no dev");
896 goto error; 892 goto error;
897 } 893 if (dstat & ~(DEV_STAT_DEV_END | DEV_STAT_CHN_END))
898
899 if (dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) {
900 DBF_ERROR("EQ: bad io");
901 goto error; 894 goto error;
902 } 895 if (!(dstat & DEV_STAT_DEV_END))
903 return 0; 896 goto error;
897 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ESTABLISHED);
898 return;
899
904error: 900error:
905 DBF_ERROR("%4x EQ:error", irq_ptr->schid.sch_no); 901 DBF_ERROR("%4x EQ:error", irq_ptr->schid.sch_no);
906 DBF_ERROR("ds: %2x cs:%2x", dstat, cstat); 902 DBF_ERROR("ds: %2x cs:%2x", dstat, cstat);
907
908 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); 903 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
909 return 1;
910}
911
912static void qdio_establish_handle_irq(struct ccw_device *cdev, int cstat,
913 int dstat)
914{
915 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
916
917 DBF_DEV_EVENT(DBF_INFO, irq_ptr, "qest irq");
918 if (!qdio_establish_check_errors(cdev, cstat, dstat))
919 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ESTABLISHED);
920} 904}
921 905
922/* qdio interrupt handler */ 906/* qdio interrupt handler */
@@ -946,7 +930,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
946 } 930 }
947 } 931 }
948 qdio_irq_check_sense(irq_ptr, irb); 932 qdio_irq_check_sense(irq_ptr, irb);
949
950 cstat = irb->scsw.cmd.cstat; 933 cstat = irb->scsw.cmd.cstat;
951 dstat = irb->scsw.cmd.dstat; 934 dstat = irb->scsw.cmd.dstat;
952 935
@@ -954,22 +937,19 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
954 case QDIO_IRQ_STATE_INACTIVE: 937 case QDIO_IRQ_STATE_INACTIVE:
955 qdio_establish_handle_irq(cdev, cstat, dstat); 938 qdio_establish_handle_irq(cdev, cstat, dstat);
956 break; 939 break;
957
958 case QDIO_IRQ_STATE_CLEANUP: 940 case QDIO_IRQ_STATE_CLEANUP:
959 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); 941 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
960 break; 942 break;
961
962 case QDIO_IRQ_STATE_ESTABLISHED: 943 case QDIO_IRQ_STATE_ESTABLISHED:
963 case QDIO_IRQ_STATE_ACTIVE: 944 case QDIO_IRQ_STATE_ACTIVE:
964 if (cstat & SCHN_STAT_PCI) { 945 if (cstat & SCHN_STAT_PCI) {
965 qdio_int_handler_pci(irq_ptr); 946 qdio_int_handler_pci(irq_ptr);
966 return; 947 return;
967 } 948 }
968 if ((cstat & ~SCHN_STAT_PCI) || dstat) { 949 if (cstat || dstat)
969 qdio_handle_activate_check(cdev, intparm, cstat, 950 qdio_handle_activate_check(cdev, intparm, cstat,
970 dstat); 951 dstat);
971 break; 952 break;
972 }
973 default: 953 default:
974 WARN_ON(1); 954 WARN_ON(1);
975 } 955 }
@@ -1514,7 +1494,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
1514 1494
1515 if ((bufnr > QDIO_MAX_BUFFERS_PER_Q) || 1495 if ((bufnr > QDIO_MAX_BUFFERS_PER_Q) ||
1516 (count > QDIO_MAX_BUFFERS_PER_Q) || 1496 (count > QDIO_MAX_BUFFERS_PER_Q) ||
1517 (q_nr > QDIO_MAX_QUEUES_PER_IRQ)) 1497 (q_nr >= QDIO_MAX_QUEUES_PER_IRQ))
1518 return -EINVAL; 1498 return -EINVAL;
1519 1499
1520 if (!count) 1500 if (!count)
diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c
index 136d0f0b1e93..eff943923c6f 100644
--- a/drivers/s390/cio/qdio_perf.c
+++ b/drivers/s390/cio/qdio_perf.c
@@ -25,18 +25,6 @@ struct qdio_perf_stats perf_stats;
25static struct proc_dir_entry *qdio_perf_pde; 25static struct proc_dir_entry *qdio_perf_pde;
26#endif 26#endif
27 27
28inline void qdio_perf_stat_inc(atomic_long_t *count)
29{
30 if (qdio_performance_stats)
31 atomic_long_inc(count);
32}
33
34inline void qdio_perf_stat_dec(atomic_long_t *count)
35{
36 if (qdio_performance_stats)
37 atomic_long_dec(count);
38}
39
40/* 28/*
41 * procfs functions 29 * procfs functions
42 */ 30 */
diff --git a/drivers/s390/cio/qdio_perf.h b/drivers/s390/cio/qdio_perf.h
index 7821ac4fa517..ff4504ce1e3c 100644
--- a/drivers/s390/cio/qdio_perf.h
+++ b/drivers/s390/cio/qdio_perf.h
@@ -9,7 +9,6 @@
9#define QDIO_PERF_H 9#define QDIO_PERF_H
10 10
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/device.h>
13#include <asm/atomic.h> 12#include <asm/atomic.h>
14 13
15struct qdio_perf_stats { 14struct qdio_perf_stats {
@@ -50,10 +49,13 @@ struct qdio_perf_stats {
50extern struct qdio_perf_stats perf_stats; 49extern struct qdio_perf_stats perf_stats;
51extern int qdio_performance_stats; 50extern int qdio_performance_stats;
52 51
52static inline void qdio_perf_stat_inc(atomic_long_t *count)
53{
54 if (qdio_performance_stats)
55 atomic_long_inc(count);
56}
57
53int qdio_setup_perf_stats(void); 58int qdio_setup_perf_stats(void);
54void qdio_remove_perf_stats(void); 59void qdio_remove_perf_stats(void);
55 60
56extern void qdio_perf_stat_inc(atomic_long_t *count);
57extern void qdio_perf_stat_dec(atomic_long_t *count);
58
59#endif 61#endif
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index a7745c82b4ae..cb909a5b5047 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -8,7 +8,7 @@ config LCS
8 Select this option if you want to use LCS networking on IBM System z. 8 Select this option if you want to use LCS networking on IBM System z.
9 This device driver supports Token Ring (IEEE 802.5), 9 This device driver supports Token Ring (IEEE 802.5),
10 FDDI (IEEE 802.7) and Ethernet. 10 FDDI (IEEE 802.7) and Ethernet.
11 To compile as a module, choose M. The module name is lcs.ko. 11 To compile as a module, choose M. The module name is lcs.
12 If you do not know what it is, it's safe to choose Y. 12 If you do not know what it is, it's safe to choose Y.
13 13
14config CTCM 14config CTCM
@@ -21,7 +21,7 @@ config CTCM
21 It also supports virtual CTCs when running under VM. 21 It also supports virtual CTCs when running under VM.
22 This driver also supports channel-to-channel MPC SNA devices. 22 This driver also supports channel-to-channel MPC SNA devices.
23 MPC is an SNA protocol device used by Communication Server for Linux. 23 MPC is an SNA protocol device used by Communication Server for Linux.
24 To compile as a module, choose M. The module name is ctcm.ko. 24 To compile as a module, choose M. The module name is ctcm.
25 To compile into the kernel, choose Y. 25 To compile into the kernel, choose Y.
26 If you do not need any channel-to-channel connection, choose N. 26 If you do not need any channel-to-channel connection, choose N.
27 27
@@ -34,7 +34,7 @@ config NETIUCV
34 link between VM guests. Using ifconfig a point-to-point connection 34 link between VM guests. Using ifconfig a point-to-point connection
35 can be established to the Linux on IBM System z 35 can be established to the Linux on IBM System z
36 running on the other VM guest. To compile as a module, choose M. 36 running on the other VM guest. To compile as a module, choose M.
37 The module name is netiucv.ko. If unsure, choose Y. 37 The module name is netiucv. If unsure, choose Y.
38 38
39config SMSGIUCV 39config SMSGIUCV
40 tristate "IUCV special message support (VM only)" 40 tristate "IUCV special message support (VM only)"
@@ -50,7 +50,7 @@ config CLAW
50 This driver supports channel attached CLAW devices. 50 This driver supports channel attached CLAW devices.
51 CLAW is Common Link Access for Workstation. Common devices 51 CLAW is Common Link Access for Workstation. Common devices
52 that use CLAW are RS/6000s, Cisco Routers (CIP) and 3172 devices. 52 that use CLAW are RS/6000s, Cisco Routers (CIP) and 3172 devices.
53 To compile as a module, choose M. The module name is claw.ko. 53 To compile as a module, choose M. The module name is claw.
54 To compile into the kernel, choose Y. 54 To compile into the kernel, choose Y.
55 55
56config QETH 56config QETH
@@ -65,14 +65,14 @@ config QETH
65 <http://www.ibm.com/developerworks/linux/linux390> 65 <http://www.ibm.com/developerworks/linux/linux390>
66 66
67 To compile this driver as a module, choose M. 67 To compile this driver as a module, choose M.
68 The module name is qeth.ko. 68 The module name is qeth.
69 69
70config QETH_L2 70config QETH_L2
71 tristate "qeth layer 2 device support" 71 tristate "qeth layer 2 device support"
72 depends on QETH 72 depends on QETH
73 help 73 help
74 Select this option to be able to run qeth devices in layer 2 mode. 74 Select this option to be able to run qeth devices in layer 2 mode.
75 To compile as a module, choose M. The module name is qeth_l2.ko. 75 To compile as a module, choose M. The module name is qeth_l2.
76 If unsure, choose y. 76 If unsure, choose y.
77 77
78config QETH_L3 78config QETH_L3
@@ -80,7 +80,7 @@ config QETH_L3
80 depends on QETH 80 depends on QETH
81 help 81 help
82 Select this option to be able to run qeth devices in layer 3 mode. 82 Select this option to be able to run qeth devices in layer 3 mode.
83 To compile as a module choose M. The module name is qeth_l3.ko. 83 To compile as a module choose M. The module name is qeth_l3.
84 If unsure, choose Y. 84 If unsure, choose Y.
85 85
86config QETH_IPV6 86config QETH_IPV6
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 30a43cc79e76..f370f8d460a7 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -3,12 +3,12 @@
3 * ESCON CLAW network driver 3 * ESCON CLAW network driver
4 * 4 *
5 * Linux for zSeries version 5 * Linux for zSeries version
6 * Copyright (C) 2002,2005 IBM Corporation 6 * Copyright IBM Corp. 2002, 2009
7 * Author(s) Original code written by: 7 * Author(s) Original code written by:
8 * Kazuo Iimura (iimura@jp.ibm.com) 8 * Kazuo Iimura <iimura@jp.ibm.com>
9 * Rewritten by 9 * Rewritten by
10 * Andy Richter (richtera@us.ibm.com) 10 * Andy Richter <richtera@us.ibm.com>
11 * Marc Price (mwprice@us.ibm.com) 11 * Marc Price <mwprice@us.ibm.com>
12 * 12 *
13 * sysfs parms: 13 * sysfs parms:
14 * group x.x.rrrr,x.x.wwww 14 * group x.x.rrrr,x.x.wwww
@@ -253,6 +253,11 @@ static void claw_free_wrt_buf(struct net_device *dev);
253/* Functions for unpack reads */ 253/* Functions for unpack reads */
254static void unpack_read(struct net_device *dev); 254static void unpack_read(struct net_device *dev);
255 255
256static int claw_pm_prepare(struct ccwgroup_device *gdev)
257{
258 return -EPERM;
259}
260
256/* ccwgroup table */ 261/* ccwgroup table */
257 262
258static struct ccwgroup_driver claw_group_driver = { 263static struct ccwgroup_driver claw_group_driver = {
@@ -264,6 +269,7 @@ static struct ccwgroup_driver claw_group_driver = {
264 .remove = claw_remove_device, 269 .remove = claw_remove_device,
265 .set_online = claw_new_device, 270 .set_online = claw_new_device,
266 .set_offline = claw_shutdown_device, 271 .set_offline = claw_shutdown_device,
272 .prepare = claw_pm_prepare,
267}; 273};
268 274
269/* 275/*
@@ -284,7 +290,7 @@ claw_probe(struct ccwgroup_device *cgdev)
284 if (!get_device(&cgdev->dev)) 290 if (!get_device(&cgdev->dev))
285 return -ENODEV; 291 return -ENODEV;
286 privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL); 292 privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL);
287 cgdev->dev.driver_data = privptr; 293 dev_set_drvdata(&cgdev->dev, privptr);
288 if (privptr == NULL) { 294 if (privptr == NULL) {
289 probe_error(cgdev); 295 probe_error(cgdev);
290 put_device(&cgdev->dev); 296 put_device(&cgdev->dev);
@@ -338,12 +344,6 @@ claw_tx(struct sk_buff *skb, struct net_device *dev)
338 344
339 CLAW_DBF_TEXT(4, trace, "claw_tx"); 345 CLAW_DBF_TEXT(4, trace, "claw_tx");
340 p_ch=&privptr->channel[WRITE]; 346 p_ch=&privptr->channel[WRITE];
341 if (skb == NULL) {
342 privptr->stats.tx_dropped++;
343 privptr->stats.tx_errors++;
344 CLAW_DBF_TEXT_(2, trace, "clawtx%d", -EIO);
345 return -EIO;
346 }
347 spin_lock_irqsave(get_ccwdev_lock(p_ch->cdev), saveflags); 347 spin_lock_irqsave(get_ccwdev_lock(p_ch->cdev), saveflags);
348 rc=claw_hw_tx( skb, dev, 1 ); 348 rc=claw_hw_tx( skb, dev, 1 );
349 spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags); 349 spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags);
@@ -597,14 +597,14 @@ claw_irq_handler(struct ccw_device *cdev,
597 597
598 CLAW_DBF_TEXT(4, trace, "clawirq"); 598 CLAW_DBF_TEXT(4, trace, "clawirq");
599 /* Bypass all 'unsolicited interrupts' */ 599 /* Bypass all 'unsolicited interrupts' */
600 if (!cdev->dev.driver_data) { 600 privptr = dev_get_drvdata(&cdev->dev);
601 if (!privptr) {
601 dev_warn(&cdev->dev, "An uninitialized CLAW device received an" 602 dev_warn(&cdev->dev, "An uninitialized CLAW device received an"
602 " IRQ, c-%02x d-%02x\n", 603 " IRQ, c-%02x d-%02x\n",
603 irb->scsw.cmd.cstat, irb->scsw.cmd.dstat); 604 irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
604 CLAW_DBF_TEXT(2, trace, "badirq"); 605 CLAW_DBF_TEXT(2, trace, "badirq");
605 return; 606 return;
606 } 607 }
607 privptr = (struct claw_privbk *)cdev->dev.driver_data;
608 608
609 /* Try to extract channel from driver data. */ 609 /* Try to extract channel from driver data. */
610 if (privptr->channel[READ].cdev == cdev) 610 if (privptr->channel[READ].cdev == cdev)
@@ -1986,9 +1986,9 @@ probe_error( struct ccwgroup_device *cgdev)
1986 struct claw_privbk *privptr; 1986 struct claw_privbk *privptr;
1987 1987
1988 CLAW_DBF_TEXT(4, trace, "proberr"); 1988 CLAW_DBF_TEXT(4, trace, "proberr");
1989 privptr = (struct claw_privbk *) cgdev->dev.driver_data; 1989 privptr = dev_get_drvdata(&cgdev->dev);
1990 if (privptr != NULL) { 1990 if (privptr != NULL) {
1991 cgdev->dev.driver_data = NULL; 1991 dev_set_drvdata(&cgdev->dev, NULL);
1992 kfree(privptr->p_env); 1992 kfree(privptr->p_env);
1993 kfree(privptr->p_mtc_envelope); 1993 kfree(privptr->p_mtc_envelope);
1994 kfree(privptr); 1994 kfree(privptr);
@@ -2917,9 +2917,9 @@ claw_new_device(struct ccwgroup_device *cgdev)
2917 dev_info(&cgdev->dev, "add for %s\n", 2917 dev_info(&cgdev->dev, "add for %s\n",
2918 dev_name(&cgdev->cdev[READ]->dev)); 2918 dev_name(&cgdev->cdev[READ]->dev));
2919 CLAW_DBF_TEXT(2, setup, "new_dev"); 2919 CLAW_DBF_TEXT(2, setup, "new_dev");
2920 privptr = cgdev->dev.driver_data; 2920 privptr = dev_get_drvdata(&cgdev->dev);
2921 cgdev->cdev[READ]->dev.driver_data = privptr; 2921 dev_set_drvdata(&cgdev->cdev[READ]->dev, privptr);
2922 cgdev->cdev[WRITE]->dev.driver_data = privptr; 2922 dev_set_drvdata(&cgdev->cdev[WRITE]->dev, privptr);
2923 if (!privptr) 2923 if (!privptr)
2924 return -ENODEV; 2924 return -ENODEV;
2925 p_env = privptr->p_env; 2925 p_env = privptr->p_env;
@@ -2956,9 +2956,9 @@ claw_new_device(struct ccwgroup_device *cgdev)
2956 goto out; 2956 goto out;
2957 } 2957 }
2958 dev->ml_priv = privptr; 2958 dev->ml_priv = privptr;
2959 cgdev->dev.driver_data = privptr; 2959 dev_set_drvdata(&cgdev->dev, privptr);
2960 cgdev->cdev[READ]->dev.driver_data = privptr; 2960 dev_set_drvdata(&cgdev->cdev[READ]->dev, privptr);
2961 cgdev->cdev[WRITE]->dev.driver_data = privptr; 2961 dev_set_drvdata(&cgdev->cdev[WRITE]->dev, privptr);
2962 /* sysfs magic */ 2962 /* sysfs magic */
2963 SET_NETDEV_DEV(dev, &cgdev->dev); 2963 SET_NETDEV_DEV(dev, &cgdev->dev);
2964 if (register_netdev(dev) != 0) { 2964 if (register_netdev(dev) != 0) {
@@ -3024,7 +3024,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
3024 int ret; 3024 int ret;
3025 3025
3026 CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev)); 3026 CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
3027 priv = cgdev->dev.driver_data; 3027 priv = dev_get_drvdata(&cgdev->dev);
3028 if (!priv) 3028 if (!priv)
3029 return -ENODEV; 3029 return -ENODEV;
3030 ndev = priv->channel[READ].ndev; 3030 ndev = priv->channel[READ].ndev;
@@ -3054,7 +3054,7 @@ claw_remove_device(struct ccwgroup_device *cgdev)
3054 3054
3055 BUG_ON(!cgdev); 3055 BUG_ON(!cgdev);
3056 CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev)); 3056 CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
3057 priv = cgdev->dev.driver_data; 3057 priv = dev_get_drvdata(&cgdev->dev);
3058 BUG_ON(!priv); 3058 BUG_ON(!priv);
3059 dev_info(&cgdev->dev, " will be removed.\n"); 3059 dev_info(&cgdev->dev, " will be removed.\n");
3060 if (cgdev->state == CCWGROUP_ONLINE) 3060 if (cgdev->state == CCWGROUP_ONLINE)
@@ -3069,9 +3069,9 @@ claw_remove_device(struct ccwgroup_device *cgdev)
3069 kfree(priv->channel[1].irb); 3069 kfree(priv->channel[1].irb);
3070 priv->channel[1].irb=NULL; 3070 priv->channel[1].irb=NULL;
3071 kfree(priv); 3071 kfree(priv);
3072 cgdev->dev.driver_data=NULL; 3072 dev_set_drvdata(&cgdev->dev, NULL);
3073 cgdev->cdev[READ]->dev.driver_data = NULL; 3073 dev_set_drvdata(&cgdev->cdev[READ]->dev, NULL);
3074 cgdev->cdev[WRITE]->dev.driver_data = NULL; 3074 dev_set_drvdata(&cgdev->cdev[WRITE]->dev, NULL);
3075 put_device(&cgdev->dev); 3075 put_device(&cgdev->dev);
3076 3076
3077 return; 3077 return;
@@ -3087,7 +3087,7 @@ claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf)
3087 struct claw_privbk *priv; 3087 struct claw_privbk *priv;
3088 struct claw_env * p_env; 3088 struct claw_env * p_env;
3089 3089
3090 priv = dev->driver_data; 3090 priv = dev_get_drvdata(dev);
3091 if (!priv) 3091 if (!priv)
3092 return -ENODEV; 3092 return -ENODEV;
3093 p_env = priv->p_env; 3093 p_env = priv->p_env;
@@ -3101,7 +3101,7 @@ claw_hname_write(struct device *dev, struct device_attribute *attr,
3101 struct claw_privbk *priv; 3101 struct claw_privbk *priv;
3102 struct claw_env * p_env; 3102 struct claw_env * p_env;
3103 3103
3104 priv = dev->driver_data; 3104 priv = dev_get_drvdata(dev);
3105 if (!priv) 3105 if (!priv)
3106 return -ENODEV; 3106 return -ENODEV;
3107 p_env = priv->p_env; 3107 p_env = priv->p_env;
@@ -3125,7 +3125,7 @@ claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf)
3125 struct claw_privbk *priv; 3125 struct claw_privbk *priv;
3126 struct claw_env * p_env; 3126 struct claw_env * p_env;
3127 3127
3128 priv = dev->driver_data; 3128 priv = dev_get_drvdata(dev);
3129 if (!priv) 3129 if (!priv)
3130 return -ENODEV; 3130 return -ENODEV;
3131 p_env = priv->p_env; 3131 p_env = priv->p_env;
@@ -3139,7 +3139,7 @@ claw_adname_write(struct device *dev, struct device_attribute *attr,
3139 struct claw_privbk *priv; 3139 struct claw_privbk *priv;
3140 struct claw_env * p_env; 3140 struct claw_env * p_env;
3141 3141
3142 priv = dev->driver_data; 3142 priv = dev_get_drvdata(dev);
3143 if (!priv) 3143 if (!priv)
3144 return -ENODEV; 3144 return -ENODEV;
3145 p_env = priv->p_env; 3145 p_env = priv->p_env;
@@ -3163,7 +3163,7 @@ claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf)
3163 struct claw_privbk *priv; 3163 struct claw_privbk *priv;
3164 struct claw_env * p_env; 3164 struct claw_env * p_env;
3165 3165
3166 priv = dev->driver_data; 3166 priv = dev_get_drvdata(dev);
3167 if (!priv) 3167 if (!priv)
3168 return -ENODEV; 3168 return -ENODEV;
3169 p_env = priv->p_env; 3169 p_env = priv->p_env;
@@ -3178,7 +3178,7 @@ claw_apname_write(struct device *dev, struct device_attribute *attr,
3178 struct claw_privbk *priv; 3178 struct claw_privbk *priv;
3179 struct claw_env * p_env; 3179 struct claw_env * p_env;
3180 3180
3181 priv = dev->driver_data; 3181 priv = dev_get_drvdata(dev);
3182 if (!priv) 3182 if (!priv)
3183 return -ENODEV; 3183 return -ENODEV;
3184 p_env = priv->p_env; 3184 p_env = priv->p_env;
@@ -3212,7 +3212,7 @@ claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
3212 struct claw_privbk *priv; 3212 struct claw_privbk *priv;
3213 struct claw_env * p_env; 3213 struct claw_env * p_env;
3214 3214
3215 priv = dev->driver_data; 3215 priv = dev_get_drvdata(dev);
3216 if (!priv) 3216 if (!priv)
3217 return -ENODEV; 3217 return -ENODEV;
3218 p_env = priv->p_env; 3218 p_env = priv->p_env;
@@ -3227,7 +3227,7 @@ claw_wbuff_write(struct device *dev, struct device_attribute *attr,
3227 struct claw_env * p_env; 3227 struct claw_env * p_env;
3228 int nnn,max; 3228 int nnn,max;
3229 3229
3230 priv = dev->driver_data; 3230 priv = dev_get_drvdata(dev);
3231 if (!priv) 3231 if (!priv)
3232 return -ENODEV; 3232 return -ENODEV;
3233 p_env = priv->p_env; 3233 p_env = priv->p_env;
@@ -3254,7 +3254,7 @@ claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
3254 struct claw_privbk *priv; 3254 struct claw_privbk *priv;
3255 struct claw_env * p_env; 3255 struct claw_env * p_env;
3256 3256
3257 priv = dev->driver_data; 3257 priv = dev_get_drvdata(dev);
3258 if (!priv) 3258 if (!priv)
3259 return -ENODEV; 3259 return -ENODEV;
3260 p_env = priv->p_env; 3260 p_env = priv->p_env;
@@ -3269,7 +3269,7 @@ claw_rbuff_write(struct device *dev, struct device_attribute *attr,
3269 struct claw_env *p_env; 3269 struct claw_env *p_env;
3270 int nnn,max; 3270 int nnn,max;
3271 3271
3272 priv = dev->driver_data; 3272 priv = dev_get_drvdata(dev);
3273 if (!priv) 3273 if (!priv)
3274 return -ENODEV; 3274 return -ENODEV;
3275 p_env = priv->p_env; 3275 p_env = priv->p_env;
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 77f4033a0f4f..222e47394437 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/net/ctcm_main.c 2 * drivers/s390/net/ctcm_main.c
3 * 3 *
4 * Copyright IBM Corp. 2001, 2007 4 * Copyright IBM Corp. 2001, 2009
5 * Author(s): 5 * Author(s):
6 * Original CTC driver(s): 6 * Original CTC driver(s):
7 * Fritz Elfert (felfert@millenux.com) 7 * Fritz Elfert (felfert@millenux.com)
@@ -1677,10 +1677,8 @@ static void ctcm_remove_device(struct ccwgroup_device *cgdev)
1677 BUG_ON(priv == NULL); 1677 BUG_ON(priv == NULL);
1678 1678
1679 CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, 1679 CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
1680 "removing device %s, r/w = %s/%s, proto : %d", 1680 "removing device %p, proto : %d",
1681 priv->channel[READ]->netdev->name, 1681 cgdev, priv->protocol);
1682 priv->channel[READ]->id, priv->channel[WRITE]->id,
1683 priv->protocol);
1684 1682
1685 if (cgdev->state == CCWGROUP_ONLINE) 1683 if (cgdev->state == CCWGROUP_ONLINE)
1686 ctcm_shutdown_device(cgdev); 1684 ctcm_shutdown_device(cgdev);
@@ -1690,6 +1688,38 @@ static void ctcm_remove_device(struct ccwgroup_device *cgdev)
1690 put_device(&cgdev->dev); 1688 put_device(&cgdev->dev);
1691} 1689}
1692 1690
1691static int ctcm_pm_suspend(struct ccwgroup_device *gdev)
1692{
1693 struct ctcm_priv *priv = dev_get_drvdata(&gdev->dev);
1694
1695 if (gdev->state == CCWGROUP_OFFLINE)
1696 return 0;
1697 netif_device_detach(priv->channel[READ]->netdev);
1698 ctcm_close(priv->channel[READ]->netdev);
1699 ccw_device_set_offline(gdev->cdev[1]);
1700 ccw_device_set_offline(gdev->cdev[0]);
1701 return 0;
1702}
1703
1704static int ctcm_pm_resume(struct ccwgroup_device *gdev)
1705{
1706 struct ctcm_priv *priv = dev_get_drvdata(&gdev->dev);
1707 int rc;
1708
1709 if (gdev->state == CCWGROUP_OFFLINE)
1710 return 0;
1711 rc = ccw_device_set_online(gdev->cdev[1]);
1712 if (rc)
1713 goto err_out;
1714 rc = ccw_device_set_online(gdev->cdev[0]);
1715 if (rc)
1716 goto err_out;
1717 ctcm_open(priv->channel[READ]->netdev);
1718err_out:
1719 netif_device_attach(priv->channel[READ]->netdev);
1720 return rc;
1721}
1722
1693static struct ccwgroup_driver ctcm_group_driver = { 1723static struct ccwgroup_driver ctcm_group_driver = {
1694 .owner = THIS_MODULE, 1724 .owner = THIS_MODULE,
1695 .name = CTC_DRIVER_NAME, 1725 .name = CTC_DRIVER_NAME,
@@ -1699,6 +1729,9 @@ static struct ccwgroup_driver ctcm_group_driver = {
1699 .remove = ctcm_remove_device, 1729 .remove = ctcm_remove_device,
1700 .set_online = ctcm_new_device, 1730 .set_online = ctcm_new_device,
1701 .set_offline = ctcm_shutdown_device, 1731 .set_offline = ctcm_shutdown_device,
1732 .freeze = ctcm_pm_suspend,
1733 .thaw = ctcm_pm_resume,
1734 .restore = ctcm_pm_resume,
1702}; 1735};
1703 1736
1704 1737
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index a45bc24eb5f9..8c675905448b 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -1,15 +1,12 @@
1/* 1/*
2 * linux/drivers/s390/net/lcs.c
3 *
4 * Linux for S/390 Lan Channel Station Network Driver 2 * Linux for S/390 Lan Channel Station Network Driver
5 * 3 *
6 * Copyright (C) 1999-2001 IBM Deutschland Entwicklung GmbH, 4 * Copyright IBM Corp. 1999, 2009
7 * IBM Corporation 5 * Author(s): Original Code written by
8 * Author(s): Original Code written by 6 * DJ Barrow <djbarrow@de.ibm.com,barrow_dj@yahoo.com>
9 * DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 7 * Rewritten by
10 * Rewritten by 8 * Frank Pavlic <fpavlic@de.ibm.com> and
11 * Frank Pavlic (fpavlic@de.ibm.com) and 9 * Martin Schwidefsky <schwidefsky@de.ibm.com>
12 * Martin Schwidefsky <schwidefsky@de.ibm.com>
13 * 10 *
14 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -1939,7 +1936,7 @@ lcs_portno_show (struct device *dev, struct device_attribute *attr, char *buf)
1939{ 1936{
1940 struct lcs_card *card; 1937 struct lcs_card *card;
1941 1938
1942 card = (struct lcs_card *)dev->driver_data; 1939 card = dev_get_drvdata(dev);
1943 1940
1944 if (!card) 1941 if (!card)
1945 return 0; 1942 return 0;
@@ -1956,7 +1953,7 @@ lcs_portno_store (struct device *dev, struct device_attribute *attr, const char
1956 struct lcs_card *card; 1953 struct lcs_card *card;
1957 int value; 1954 int value;
1958 1955
1959 card = (struct lcs_card *)dev->driver_data; 1956 card = dev_get_drvdata(dev);
1960 1957
1961 if (!card) 1958 if (!card)
1962 return 0; 1959 return 0;
@@ -1990,7 +1987,7 @@ lcs_timeout_show(struct device *dev, struct device_attribute *attr, char *buf)
1990{ 1987{
1991 struct lcs_card *card; 1988 struct lcs_card *card;
1992 1989
1993 card = (struct lcs_card *)dev->driver_data; 1990 card = dev_get_drvdata(dev);
1994 1991
1995 return card ? sprintf(buf, "%u\n", card->lancmd_timeout) : 0; 1992 return card ? sprintf(buf, "%u\n", card->lancmd_timeout) : 0;
1996} 1993}
@@ -2001,7 +1998,7 @@ lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char
2001 struct lcs_card *card; 1998 struct lcs_card *card;
2002 int value; 1999 int value;
2003 2000
2004 card = (struct lcs_card *)dev->driver_data; 2001 card = dev_get_drvdata(dev);
2005 2002
2006 if (!card) 2003 if (!card)
2007 return 0; 2004 return 0;
@@ -2020,7 +2017,7 @@ static ssize_t
2020lcs_dev_recover_store(struct device *dev, struct device_attribute *attr, 2017lcs_dev_recover_store(struct device *dev, struct device_attribute *attr,
2021 const char *buf, size_t count) 2018 const char *buf, size_t count)
2022{ 2019{
2023 struct lcs_card *card = dev->driver_data; 2020 struct lcs_card *card = dev_get_drvdata(dev);
2024 char *tmp; 2021 char *tmp;
2025 int i; 2022 int i;
2026 2023
@@ -2073,7 +2070,7 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev)
2073 put_device(&ccwgdev->dev); 2070 put_device(&ccwgdev->dev);
2074 return ret; 2071 return ret;
2075 } 2072 }
2076 ccwgdev->dev.driver_data = card; 2073 dev_set_drvdata(&ccwgdev->dev, card);
2077 ccwgdev->cdev[0]->handler = lcs_irq; 2074 ccwgdev->cdev[0]->handler = lcs_irq;
2078 ccwgdev->cdev[1]->handler = lcs_irq; 2075 ccwgdev->cdev[1]->handler = lcs_irq;
2079 card->gdev = ccwgdev; 2076 card->gdev = ccwgdev;
@@ -2090,7 +2087,7 @@ lcs_register_netdev(struct ccwgroup_device *ccwgdev)
2090 struct lcs_card *card; 2087 struct lcs_card *card;
2091 2088
2092 LCS_DBF_TEXT(2, setup, "regnetdv"); 2089 LCS_DBF_TEXT(2, setup, "regnetdv");
2093 card = (struct lcs_card *)ccwgdev->dev.driver_data; 2090 card = dev_get_drvdata(&ccwgdev->dev);
2094 if (card->dev->reg_state != NETREG_UNINITIALIZED) 2091 if (card->dev->reg_state != NETREG_UNINITIALIZED)
2095 return 0; 2092 return 0;
2096 SET_NETDEV_DEV(card->dev, &ccwgdev->dev); 2093 SET_NETDEV_DEV(card->dev, &ccwgdev->dev);
@@ -2123,7 +2120,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
2123 enum lcs_dev_states recover_state; 2120 enum lcs_dev_states recover_state;
2124 int rc; 2121 int rc;
2125 2122
2126 card = (struct lcs_card *)ccwgdev->dev.driver_data; 2123 card = dev_get_drvdata(&ccwgdev->dev);
2127 if (!card) 2124 if (!card)
2128 return -ENODEV; 2125 return -ENODEV;
2129 2126
@@ -2229,7 +2226,7 @@ __lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode)
2229 int ret; 2226 int ret;
2230 2227
2231 LCS_DBF_TEXT(3, setup, "shtdndev"); 2228 LCS_DBF_TEXT(3, setup, "shtdndev");
2232 card = (struct lcs_card *)ccwgdev->dev.driver_data; 2229 card = dev_get_drvdata(&ccwgdev->dev);
2233 if (!card) 2230 if (!card)
2234 return -ENODEV; 2231 return -ENODEV;
2235 if (recovery_mode == 0) { 2232 if (recovery_mode == 0) {
@@ -2296,7 +2293,7 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev)
2296{ 2293{
2297 struct lcs_card *card; 2294 struct lcs_card *card;
2298 2295
2299 card = (struct lcs_card *)ccwgdev->dev.driver_data; 2296 card = dev_get_drvdata(&ccwgdev->dev);
2300 if (!card) 2297 if (!card)
2301 return; 2298 return;
2302 2299
@@ -2313,6 +2310,60 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev)
2313 put_device(&ccwgdev->dev); 2310 put_device(&ccwgdev->dev);
2314} 2311}
2315 2312
2313static int lcs_pm_suspend(struct lcs_card *card)
2314{
2315 if (card->dev)
2316 netif_device_detach(card->dev);
2317 lcs_set_allowed_threads(card, 0);
2318 lcs_wait_for_threads(card, 0xffffffff);
2319 if (card->state != DEV_STATE_DOWN)
2320 __lcs_shutdown_device(card->gdev, 1);
2321 return 0;
2322}
2323
2324static int lcs_pm_resume(struct lcs_card *card)
2325{
2326 int rc = 0;
2327
2328 if (card->state == DEV_STATE_RECOVER)
2329 rc = lcs_new_device(card->gdev);
2330 if (card->dev)
2331 netif_device_attach(card->dev);
2332 if (rc) {
2333 dev_warn(&card->gdev->dev, "The lcs device driver "
2334 "failed to recover the device\n");
2335 }
2336 return rc;
2337}
2338
2339static int lcs_prepare(struct ccwgroup_device *gdev)
2340{
2341 return 0;
2342}
2343
2344static void lcs_complete(struct ccwgroup_device *gdev)
2345{
2346 return;
2347}
2348
2349static int lcs_freeze(struct ccwgroup_device *gdev)
2350{
2351 struct lcs_card *card = dev_get_drvdata(&gdev->dev);
2352 return lcs_pm_suspend(card);
2353}
2354
2355static int lcs_thaw(struct ccwgroup_device *gdev)
2356{
2357 struct lcs_card *card = dev_get_drvdata(&gdev->dev);
2358 return lcs_pm_resume(card);
2359}
2360
2361static int lcs_restore(struct ccwgroup_device *gdev)
2362{
2363 struct lcs_card *card = dev_get_drvdata(&gdev->dev);
2364 return lcs_pm_resume(card);
2365}
2366
2316/** 2367/**
2317 * LCS ccwgroup driver registration 2368 * LCS ccwgroup driver registration
2318 */ 2369 */
@@ -2325,6 +2376,11 @@ static struct ccwgroup_driver lcs_group_driver = {
2325 .remove = lcs_remove_device, 2376 .remove = lcs_remove_device,
2326 .set_online = lcs_new_device, 2377 .set_online = lcs_new_device,
2327 .set_offline = lcs_shutdown_device, 2378 .set_offline = lcs_shutdown_device,
2379 .prepare = lcs_prepare,
2380 .complete = lcs_complete,
2381 .freeze = lcs_freeze,
2382 .thaw = lcs_thaw,
2383 .restore = lcs_restore,
2328}; 2384};
2329 2385
2330/** 2386/**
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index d58fea52557d..6d668642af27 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -34,8 +34,8 @@ static inline int lcs_dbf_passes(debug_info_t *dbf_grp, int level)
34 * sysfs related stuff 34 * sysfs related stuff
35 */ 35 */
36#define CARD_FROM_DEV(cdev) \ 36#define CARD_FROM_DEV(cdev) \
37 (struct lcs_card *) \ 37 (struct lcs_card *) dev_get_drvdata( \
38 ((struct ccwgroup_device *)cdev->dev.driver_data)->dev.driver_data; 38 &((struct ccwgroup_device *)dev_get_drvdata(&cdev->dev))->dev);
39/** 39/**
40 * CCW commands used in this driver 40 * CCW commands used in this driver
41 */ 41 */
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index be716e45f7ac..52574ce797b2 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1,11 +1,15 @@
1/* 1/*
2 * IUCV network driver 2 * IUCV network driver
3 * 3 *
4 * Copyright 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 * Copyright IBM Corp. 2001, 2009
5 * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
6 * 5 *
7 * Sysfs integration and all bugs therein by Cornelia Huck 6 * Author(s):
8 * (cornelia.huck@de.ibm.com) 7 * Original netiucv driver:
8 * Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
9 * Sysfs integration and all bugs therein:
10 * Cornelia Huck (cornelia.huck@de.ibm.com)
11 * PM functions:
12 * Ursula Braun (ursula.braun@de.ibm.com)
9 * 13 *
10 * Documentation used: 14 * Documentation used:
11 * the source of the original IUCV driver by: 15 * the source of the original IUCV driver by:
@@ -149,10 +153,27 @@ PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
149 153
150#define PRINTK_HEADER " iucv: " /* for debugging */ 154#define PRINTK_HEADER " iucv: " /* for debugging */
151 155
156/* dummy device to make sure netiucv_pm functions are called */
157static struct device *netiucv_dev;
158
159static int netiucv_pm_prepare(struct device *);
160static void netiucv_pm_complete(struct device *);
161static int netiucv_pm_freeze(struct device *);
162static int netiucv_pm_restore_thaw(struct device *);
163
164static struct dev_pm_ops netiucv_pm_ops = {
165 .prepare = netiucv_pm_prepare,
166 .complete = netiucv_pm_complete,
167 .freeze = netiucv_pm_freeze,
168 .thaw = netiucv_pm_restore_thaw,
169 .restore = netiucv_pm_restore_thaw,
170};
171
152static struct device_driver netiucv_driver = { 172static struct device_driver netiucv_driver = {
153 .owner = THIS_MODULE, 173 .owner = THIS_MODULE,
154 .name = "netiucv", 174 .name = "netiucv",
155 .bus = &iucv_bus, 175 .bus = &iucv_bus,
176 .pm = &netiucv_pm_ops,
156}; 177};
157 178
158static int netiucv_callback_connreq(struct iucv_path *, 179static int netiucv_callback_connreq(struct iucv_path *,
@@ -233,6 +254,7 @@ struct netiucv_priv {
233 fsm_instance *fsm; 254 fsm_instance *fsm;
234 struct iucv_connection *conn; 255 struct iucv_connection *conn;
235 struct device *dev; 256 struct device *dev;
257 int pm_state;
236}; 258};
237 259
238/** 260/**
@@ -1265,6 +1287,72 @@ static int netiucv_close(struct net_device *dev)
1265 return 0; 1287 return 0;
1266} 1288}
1267 1289
1290static int netiucv_pm_prepare(struct device *dev)
1291{
1292 IUCV_DBF_TEXT(trace, 3, __func__);
1293 return 0;
1294}
1295
1296static void netiucv_pm_complete(struct device *dev)
1297{
1298 IUCV_DBF_TEXT(trace, 3, __func__);
1299 return;
1300}
1301
1302/**
1303 * netiucv_pm_freeze() - Freeze PM callback
1304 * @dev: netiucv device
1305 *
1306 * close open netiucv interfaces
1307 */
1308static int netiucv_pm_freeze(struct device *dev)
1309{
1310 struct netiucv_priv *priv = dev->driver_data;
1311 struct net_device *ndev = NULL;
1312 int rc = 0;
1313
1314 IUCV_DBF_TEXT(trace, 3, __func__);
1315 if (priv && priv->conn)
1316 ndev = priv->conn->netdev;
1317 if (!ndev)
1318 goto out;
1319 netif_device_detach(ndev);
1320 priv->pm_state = fsm_getstate(priv->fsm);
1321 rc = netiucv_close(ndev);
1322out:
1323 return rc;
1324}
1325
1326/**
1327 * netiucv_pm_restore_thaw() - Thaw and restore PM callback
1328 * @dev: netiucv device
1329 *
1330 * re-open netiucv interfaces closed during freeze
1331 */
1332static int netiucv_pm_restore_thaw(struct device *dev)
1333{
1334 struct netiucv_priv *priv = dev->driver_data;
1335 struct net_device *ndev = NULL;
1336 int rc = 0;
1337
1338 IUCV_DBF_TEXT(trace, 3, __func__);
1339 if (priv && priv->conn)
1340 ndev = priv->conn->netdev;
1341 if (!ndev)
1342 goto out;
1343 switch (priv->pm_state) {
1344 case DEV_STATE_RUNNING:
1345 case DEV_STATE_STARTWAIT:
1346 rc = netiucv_open(ndev);
1347 break;
1348 default:
1349 break;
1350 }
1351 netif_device_attach(ndev);
1352out:
1353 return rc;
1354}
1355
1268/** 1356/**
1269 * Start transmission of a packet. 1357 * Start transmission of a packet.
1270 * Called from generic network device layer. 1358 * Called from generic network device layer.
@@ -1315,9 +1403,9 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
1315 return NETDEV_TX_BUSY; 1403 return NETDEV_TX_BUSY;
1316 } 1404 }
1317 dev->trans_start = jiffies; 1405 dev->trans_start = jiffies;
1318 rc = netiucv_transmit_skb(privptr->conn, skb) != 0; 1406 rc = netiucv_transmit_skb(privptr->conn, skb);
1319 netiucv_clear_busy(dev); 1407 netiucv_clear_busy(dev);
1320 return rc; 1408 return rc ? NETDEV_TX_BUSY : NETDEV_TX_OK;
1321} 1409}
1322 1410
1323/** 1411/**
@@ -1364,7 +1452,7 @@ static int netiucv_change_mtu(struct net_device * dev, int new_mtu)
1364static ssize_t user_show(struct device *dev, struct device_attribute *attr, 1452static ssize_t user_show(struct device *dev, struct device_attribute *attr,
1365 char *buf) 1453 char *buf)
1366{ 1454{
1367 struct netiucv_priv *priv = dev->driver_data; 1455 struct netiucv_priv *priv = dev_get_drvdata(dev);
1368 1456
1369 IUCV_DBF_TEXT(trace, 5, __func__); 1457 IUCV_DBF_TEXT(trace, 5, __func__);
1370 return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid)); 1458 return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid));
@@ -1373,7 +1461,7 @@ static ssize_t user_show(struct device *dev, struct device_attribute *attr,
1373static ssize_t user_write(struct device *dev, struct device_attribute *attr, 1461static ssize_t user_write(struct device *dev, struct device_attribute *attr,
1374 const char *buf, size_t count) 1462 const char *buf, size_t count)
1375{ 1463{
1376 struct netiucv_priv *priv = dev->driver_data; 1464 struct netiucv_priv *priv = dev_get_drvdata(dev);
1377 struct net_device *ndev = priv->conn->netdev; 1465 struct net_device *ndev = priv->conn->netdev;
1378 char *p; 1466 char *p;
1379 char *tmp; 1467 char *tmp;
@@ -1430,7 +1518,8 @@ static DEVICE_ATTR(user, 0644, user_show, user_write);
1430 1518
1431static ssize_t buffer_show (struct device *dev, struct device_attribute *attr, 1519static ssize_t buffer_show (struct device *dev, struct device_attribute *attr,
1432 char *buf) 1520 char *buf)
1433{ struct netiucv_priv *priv = dev->driver_data; 1521{
1522 struct netiucv_priv *priv = dev_get_drvdata(dev);
1434 1523
1435 IUCV_DBF_TEXT(trace, 5, __func__); 1524 IUCV_DBF_TEXT(trace, 5, __func__);
1436 return sprintf(buf, "%d\n", priv->conn->max_buffsize); 1525 return sprintf(buf, "%d\n", priv->conn->max_buffsize);
@@ -1439,7 +1528,7 @@ static ssize_t buffer_show (struct device *dev, struct device_attribute *attr,
1439static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, 1528static ssize_t buffer_write (struct device *dev, struct device_attribute *attr,
1440 const char *buf, size_t count) 1529 const char *buf, size_t count)
1441{ 1530{
1442 struct netiucv_priv *priv = dev->driver_data; 1531 struct netiucv_priv *priv = dev_get_drvdata(dev);
1443 struct net_device *ndev = priv->conn->netdev; 1532 struct net_device *ndev = priv->conn->netdev;
1444 char *e; 1533 char *e;
1445 int bs1; 1534 int bs1;
@@ -1487,7 +1576,7 @@ static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
1487static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr, 1576static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr,
1488 char *buf) 1577 char *buf)
1489{ 1578{
1490 struct netiucv_priv *priv = dev->driver_data; 1579 struct netiucv_priv *priv = dev_get_drvdata(dev);
1491 1580
1492 IUCV_DBF_TEXT(trace, 5, __func__); 1581 IUCV_DBF_TEXT(trace, 5, __func__);
1493 return sprintf(buf, "%s\n", fsm_getstate_str(priv->fsm)); 1582 return sprintf(buf, "%s\n", fsm_getstate_str(priv->fsm));
@@ -1498,7 +1587,7 @@ static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL);
1498static ssize_t conn_fsm_show (struct device *dev, 1587static ssize_t conn_fsm_show (struct device *dev,
1499 struct device_attribute *attr, char *buf) 1588 struct device_attribute *attr, char *buf)
1500{ 1589{
1501 struct netiucv_priv *priv = dev->driver_data; 1590 struct netiucv_priv *priv = dev_get_drvdata(dev);
1502 1591
1503 IUCV_DBF_TEXT(trace, 5, __func__); 1592 IUCV_DBF_TEXT(trace, 5, __func__);
1504 return sprintf(buf, "%s\n", fsm_getstate_str(priv->conn->fsm)); 1593 return sprintf(buf, "%s\n", fsm_getstate_str(priv->conn->fsm));
@@ -1509,7 +1598,7 @@ static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL);
1509static ssize_t maxmulti_show (struct device *dev, 1598static ssize_t maxmulti_show (struct device *dev,
1510 struct device_attribute *attr, char *buf) 1599 struct device_attribute *attr, char *buf)
1511{ 1600{
1512 struct netiucv_priv *priv = dev->driver_data; 1601 struct netiucv_priv *priv = dev_get_drvdata(dev);
1513 1602
1514 IUCV_DBF_TEXT(trace, 5, __func__); 1603 IUCV_DBF_TEXT(trace, 5, __func__);
1515 return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti); 1604 return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti);
@@ -1519,7 +1608,7 @@ static ssize_t maxmulti_write (struct device *dev,
1519 struct device_attribute *attr, 1608 struct device_attribute *attr,
1520 const char *buf, size_t count) 1609 const char *buf, size_t count)
1521{ 1610{
1522 struct netiucv_priv *priv = dev->driver_data; 1611 struct netiucv_priv *priv = dev_get_drvdata(dev);
1523 1612
1524 IUCV_DBF_TEXT(trace, 4, __func__); 1613 IUCV_DBF_TEXT(trace, 4, __func__);
1525 priv->conn->prof.maxmulti = 0; 1614 priv->conn->prof.maxmulti = 0;
@@ -1531,7 +1620,7 @@ static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write);
1531static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr, 1620static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr,
1532 char *buf) 1621 char *buf)
1533{ 1622{
1534 struct netiucv_priv *priv = dev->driver_data; 1623 struct netiucv_priv *priv = dev_get_drvdata(dev);
1535 1624
1536 IUCV_DBF_TEXT(trace, 5, __func__); 1625 IUCV_DBF_TEXT(trace, 5, __func__);
1537 return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue); 1626 return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue);
@@ -1540,7 +1629,7 @@ static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr,
1540static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr, 1629static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr,
1541 const char *buf, size_t count) 1630 const char *buf, size_t count)
1542{ 1631{
1543 struct netiucv_priv *priv = dev->driver_data; 1632 struct netiucv_priv *priv = dev_get_drvdata(dev);
1544 1633
1545 IUCV_DBF_TEXT(trace, 4, __func__); 1634 IUCV_DBF_TEXT(trace, 4, __func__);
1546 priv->conn->prof.maxcqueue = 0; 1635 priv->conn->prof.maxcqueue = 0;
@@ -1552,7 +1641,7 @@ static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write);
1552static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr, 1641static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr,
1553 char *buf) 1642 char *buf)
1554{ 1643{
1555 struct netiucv_priv *priv = dev->driver_data; 1644 struct netiucv_priv *priv = dev_get_drvdata(dev);
1556 1645
1557 IUCV_DBF_TEXT(trace, 5, __func__); 1646 IUCV_DBF_TEXT(trace, 5, __func__);
1558 return sprintf(buf, "%ld\n", priv->conn->prof.doios_single); 1647 return sprintf(buf, "%ld\n", priv->conn->prof.doios_single);
@@ -1561,7 +1650,7 @@ static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr,
1561static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr, 1650static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr,
1562 const char *buf, size_t count) 1651 const char *buf, size_t count)
1563{ 1652{
1564 struct netiucv_priv *priv = dev->driver_data; 1653 struct netiucv_priv *priv = dev_get_drvdata(dev);
1565 1654
1566 IUCV_DBF_TEXT(trace, 4, __func__); 1655 IUCV_DBF_TEXT(trace, 4, __func__);
1567 priv->conn->prof.doios_single = 0; 1656 priv->conn->prof.doios_single = 0;
@@ -1573,7 +1662,7 @@ static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write);
1573static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr, 1662static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr,
1574 char *buf) 1663 char *buf)
1575{ 1664{
1576 struct netiucv_priv *priv = dev->driver_data; 1665 struct netiucv_priv *priv = dev_get_drvdata(dev);
1577 1666
1578 IUCV_DBF_TEXT(trace, 5, __func__); 1667 IUCV_DBF_TEXT(trace, 5, __func__);
1579 return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi); 1668 return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi);
@@ -1582,7 +1671,7 @@ static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr,
1582static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr, 1671static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr,
1583 const char *buf, size_t count) 1672 const char *buf, size_t count)
1584{ 1673{
1585 struct netiucv_priv *priv = dev->driver_data; 1674 struct netiucv_priv *priv = dev_get_drvdata(dev);
1586 1675
1587 IUCV_DBF_TEXT(trace, 5, __func__); 1676 IUCV_DBF_TEXT(trace, 5, __func__);
1588 priv->conn->prof.doios_multi = 0; 1677 priv->conn->prof.doios_multi = 0;
@@ -1594,7 +1683,7 @@ static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write);
1594static ssize_t txlen_show (struct device *dev, struct device_attribute *attr, 1683static ssize_t txlen_show (struct device *dev, struct device_attribute *attr,
1595 char *buf) 1684 char *buf)
1596{ 1685{
1597 struct netiucv_priv *priv = dev->driver_data; 1686 struct netiucv_priv *priv = dev_get_drvdata(dev);
1598 1687
1599 IUCV_DBF_TEXT(trace, 5, __func__); 1688 IUCV_DBF_TEXT(trace, 5, __func__);
1600 return sprintf(buf, "%ld\n", priv->conn->prof.txlen); 1689 return sprintf(buf, "%ld\n", priv->conn->prof.txlen);
@@ -1603,7 +1692,7 @@ static ssize_t txlen_show (struct device *dev, struct device_attribute *attr,
1603static ssize_t txlen_write (struct device *dev, struct device_attribute *attr, 1692static ssize_t txlen_write (struct device *dev, struct device_attribute *attr,
1604 const char *buf, size_t count) 1693 const char *buf, size_t count)
1605{ 1694{
1606 struct netiucv_priv *priv = dev->driver_data; 1695 struct netiucv_priv *priv = dev_get_drvdata(dev);
1607 1696
1608 IUCV_DBF_TEXT(trace, 4, __func__); 1697 IUCV_DBF_TEXT(trace, 4, __func__);
1609 priv->conn->prof.txlen = 0; 1698 priv->conn->prof.txlen = 0;
@@ -1615,7 +1704,7 @@ static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write);
1615static ssize_t txtime_show (struct device *dev, struct device_attribute *attr, 1704static ssize_t txtime_show (struct device *dev, struct device_attribute *attr,
1616 char *buf) 1705 char *buf)
1617{ 1706{
1618 struct netiucv_priv *priv = dev->driver_data; 1707 struct netiucv_priv *priv = dev_get_drvdata(dev);
1619 1708
1620 IUCV_DBF_TEXT(trace, 5, __func__); 1709 IUCV_DBF_TEXT(trace, 5, __func__);
1621 return sprintf(buf, "%ld\n", priv->conn->prof.tx_time); 1710 return sprintf(buf, "%ld\n", priv->conn->prof.tx_time);
@@ -1624,7 +1713,7 @@ static ssize_t txtime_show (struct device *dev, struct device_attribute *attr,
1624static ssize_t txtime_write (struct device *dev, struct device_attribute *attr, 1713static ssize_t txtime_write (struct device *dev, struct device_attribute *attr,
1625 const char *buf, size_t count) 1714 const char *buf, size_t count)
1626{ 1715{
1627 struct netiucv_priv *priv = dev->driver_data; 1716 struct netiucv_priv *priv = dev_get_drvdata(dev);
1628 1717
1629 IUCV_DBF_TEXT(trace, 4, __func__); 1718 IUCV_DBF_TEXT(trace, 4, __func__);
1630 priv->conn->prof.tx_time = 0; 1719 priv->conn->prof.tx_time = 0;
@@ -1636,7 +1725,7 @@ static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write);
1636static ssize_t txpend_show (struct device *dev, struct device_attribute *attr, 1725static ssize_t txpend_show (struct device *dev, struct device_attribute *attr,
1637 char *buf) 1726 char *buf)
1638{ 1727{
1639 struct netiucv_priv *priv = dev->driver_data; 1728 struct netiucv_priv *priv = dev_get_drvdata(dev);
1640 1729
1641 IUCV_DBF_TEXT(trace, 5, __func__); 1730 IUCV_DBF_TEXT(trace, 5, __func__);
1642 return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending); 1731 return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending);
@@ -1645,7 +1734,7 @@ static ssize_t txpend_show (struct device *dev, struct device_attribute *attr,
1645static ssize_t txpend_write (struct device *dev, struct device_attribute *attr, 1734static ssize_t txpend_write (struct device *dev, struct device_attribute *attr,
1646 const char *buf, size_t count) 1735 const char *buf, size_t count)
1647{ 1736{
1648 struct netiucv_priv *priv = dev->driver_data; 1737 struct netiucv_priv *priv = dev_get_drvdata(dev);
1649 1738
1650 IUCV_DBF_TEXT(trace, 4, __func__); 1739 IUCV_DBF_TEXT(trace, 4, __func__);
1651 priv->conn->prof.tx_pending = 0; 1740 priv->conn->prof.tx_pending = 0;
@@ -1657,7 +1746,7 @@ static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write);
1657static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr, 1746static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr,
1658 char *buf) 1747 char *buf)
1659{ 1748{
1660 struct netiucv_priv *priv = dev->driver_data; 1749 struct netiucv_priv *priv = dev_get_drvdata(dev);
1661 1750
1662 IUCV_DBF_TEXT(trace, 5, __func__); 1751 IUCV_DBF_TEXT(trace, 5, __func__);
1663 return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending); 1752 return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending);
@@ -1666,7 +1755,7 @@ static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr,
1666static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr, 1755static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr,
1667 const char *buf, size_t count) 1756 const char *buf, size_t count)
1668{ 1757{
1669 struct netiucv_priv *priv = dev->driver_data; 1758 struct netiucv_priv *priv = dev_get_drvdata(dev);
1670 1759
1671 IUCV_DBF_TEXT(trace, 4, __func__); 1760 IUCV_DBF_TEXT(trace, 4, __func__);
1672 priv->conn->prof.tx_max_pending = 0; 1761 priv->conn->prof.tx_max_pending = 0;
@@ -1731,7 +1820,6 @@ static int netiucv_register_device(struct net_device *ndev)
1731 struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); 1820 struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL);
1732 int ret; 1821 int ret;
1733 1822
1734
1735 IUCV_DBF_TEXT(trace, 3, __func__); 1823 IUCV_DBF_TEXT(trace, 3, __func__);
1736 1824
1737 if (dev) { 1825 if (dev) {
@@ -1758,7 +1846,7 @@ static int netiucv_register_device(struct net_device *ndev)
1758 if (ret) 1846 if (ret)
1759 goto out_unreg; 1847 goto out_unreg;
1760 priv->dev = dev; 1848 priv->dev = dev;
1761 dev->driver_data = priv; 1849 dev_set_drvdata(dev, priv);
1762 return 0; 1850 return 0;
1763 1851
1764out_unreg: 1852out_unreg:
@@ -2100,6 +2188,7 @@ static void __exit netiucv_exit(void)
2100 netiucv_unregister_device(dev); 2188 netiucv_unregister_device(dev);
2101 } 2189 }
2102 2190
2191 device_unregister(netiucv_dev);
2103 driver_unregister(&netiucv_driver); 2192 driver_unregister(&netiucv_driver);
2104 iucv_unregister(&netiucv_handler, 1); 2193 iucv_unregister(&netiucv_handler, 1);
2105 iucv_unregister_dbf_views(); 2194 iucv_unregister_dbf_views();
@@ -2125,10 +2214,25 @@ static int __init netiucv_init(void)
2125 IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc); 2214 IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc);
2126 goto out_iucv; 2215 goto out_iucv;
2127 } 2216 }
2128 2217 /* establish dummy device */
2218 netiucv_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
2219 if (!netiucv_dev) {
2220 rc = -ENOMEM;
2221 goto out_driver;
2222 }
2223 dev_set_name(netiucv_dev, "netiucv");
2224 netiucv_dev->bus = &iucv_bus;
2225 netiucv_dev->parent = iucv_root;
2226 netiucv_dev->release = (void (*)(struct device *))kfree;
2227 netiucv_dev->driver = &netiucv_driver;
2228 rc = device_register(netiucv_dev);
2229 if (rc)
2230 goto out_driver;
2129 netiucv_banner(); 2231 netiucv_banner();
2130 return rc; 2232 return rc;
2131 2233
2234out_driver:
2235 driver_unregister(&netiucv_driver);
2132out_iucv: 2236out_iucv:
2133 iucv_unregister(&netiucv_handler, 1); 2237 iucv_unregister(&netiucv_handler, 1);
2134out_dbf: 2238out_dbf:
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index c827d69b5a91..d53621c4acbb 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/net/qeth_core_main.c 2 * drivers/s390/net/qeth_core_main.c
3 * 3 *
4 * Copyright IBM Corp. 2007 4 * Copyright IBM Corp. 2007, 2009
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>, 5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>, 6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>, 7 * Thomas Spatzier <tspat@de.ibm.com>,
@@ -952,6 +952,7 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
952 buf->buffer->element[i].addr = NULL; 952 buf->buffer->element[i].addr = NULL;
953 buf->buffer->element[i].flags = 0; 953 buf->buffer->element[i].flags = 0;
954 } 954 }
955 buf->buffer->element[15].flags = 0;
955 buf->next_element_to_fill = 0; 956 buf->next_element_to_fill = 0;
956 atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY); 957 atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
957} 958}
@@ -1140,6 +1141,8 @@ static int qeth_setup_card(struct qeth_card *card)
1140 card->ipato.enabled = 0; 1141 card->ipato.enabled = 0;
1141 card->ipato.invert4 = 0; 1142 card->ipato.invert4 = 0;
1142 card->ipato.invert6 = 0; 1143 card->ipato.invert6 = 0;
1144 if (card->info.type == QETH_CARD_TYPE_IQD)
1145 card->options.checksum_type = NO_CHECKSUMMING;
1143 /* init QDIO stuff */ 1146 /* init QDIO stuff */
1144 qeth_init_qdio_info(card); 1147 qeth_init_qdio_info(card);
1145 return 0; 1148 return 0;
@@ -2934,8 +2937,8 @@ int qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
2934 if (card->info.type == QETH_CARD_TYPE_OSN) 2937 if (card->info.type == QETH_CARD_TYPE_OSN)
2935 return cast_type; 2938 return cast_type;
2936 2939
2937 if (skb->dst && skb->dst->neighbour) { 2940 if (skb_dst(skb) && skb_dst(skb)->neighbour) {
2938 cast_type = skb->dst->neighbour->type; 2941 cast_type = skb_dst(skb)->neighbour->type;
2939 if ((cast_type == RTN_BROADCAST) || 2942 if ((cast_type == RTN_BROADCAST) ||
2940 (cast_type == RTN_MULTICAST) || 2943 (cast_type == RTN_MULTICAST) ||
2941 (cast_type == RTN_ANYCAST)) 2944 (cast_type == RTN_ANYCAST))
@@ -4192,6 +4195,50 @@ static void qeth_core_shutdown(struct ccwgroup_device *gdev)
4192 card->discipline.ccwgdriver->shutdown(gdev); 4195 card->discipline.ccwgdriver->shutdown(gdev);
4193} 4196}
4194 4197
4198static int qeth_core_prepare(struct ccwgroup_device *gdev)
4199{
4200 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4201 if (card->discipline.ccwgdriver &&
4202 card->discipline.ccwgdriver->prepare)
4203 return card->discipline.ccwgdriver->prepare(gdev);
4204 return 0;
4205}
4206
4207static void qeth_core_complete(struct ccwgroup_device *gdev)
4208{
4209 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4210 if (card->discipline.ccwgdriver &&
4211 card->discipline.ccwgdriver->complete)
4212 card->discipline.ccwgdriver->complete(gdev);
4213}
4214
4215static int qeth_core_freeze(struct ccwgroup_device *gdev)
4216{
4217 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4218 if (card->discipline.ccwgdriver &&
4219 card->discipline.ccwgdriver->freeze)
4220 return card->discipline.ccwgdriver->freeze(gdev);
4221 return 0;
4222}
4223
4224static int qeth_core_thaw(struct ccwgroup_device *gdev)
4225{
4226 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4227 if (card->discipline.ccwgdriver &&
4228 card->discipline.ccwgdriver->thaw)
4229 return card->discipline.ccwgdriver->thaw(gdev);
4230 return 0;
4231}
4232
4233static int qeth_core_restore(struct ccwgroup_device *gdev)
4234{
4235 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4236 if (card->discipline.ccwgdriver &&
4237 card->discipline.ccwgdriver->restore)
4238 return card->discipline.ccwgdriver->restore(gdev);
4239 return 0;
4240}
4241
4195static struct ccwgroup_driver qeth_core_ccwgroup_driver = { 4242static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
4196 .owner = THIS_MODULE, 4243 .owner = THIS_MODULE,
4197 .name = "qeth", 4244 .name = "qeth",
@@ -4201,6 +4248,11 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
4201 .set_online = qeth_core_set_online, 4248 .set_online = qeth_core_set_online,
4202 .set_offline = qeth_core_set_offline, 4249 .set_offline = qeth_core_set_offline,
4203 .shutdown = qeth_core_shutdown, 4250 .shutdown = qeth_core_shutdown,
4251 .prepare = qeth_core_prepare,
4252 .complete = qeth_core_complete,
4253 .freeze = qeth_core_freeze,
4254 .thaw = qeth_core_thaw,
4255 .restore = qeth_core_restore,
4204}; 4256};
4205 4257
4206static ssize_t 4258static ssize_t
diff --git a/drivers/s390/net/qeth_core_mpc.c b/drivers/s390/net/qeth_core_mpc.c
index 06f4de1f0507..ec24901c802c 100644
--- a/drivers/s390/net/qeth_core_mpc.c
+++ b/drivers/s390/net/qeth_core_mpc.c
@@ -181,6 +181,8 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
181 {IPA_RC_L2_ADDR_TABLE_FULL, "Layer2 address table full"}, 181 {IPA_RC_L2_ADDR_TABLE_FULL, "Layer2 address table full"},
182 {IPA_RC_L2_DUP_LAYER3_MAC, "Duplicate with layer 3 MAC"}, 182 {IPA_RC_L2_DUP_LAYER3_MAC, "Duplicate with layer 3 MAC"},
183 {IPA_RC_L2_GMAC_NOT_FOUND, "GMAC not found"}, 183 {IPA_RC_L2_GMAC_NOT_FOUND, "GMAC not found"},
184 {IPA_RC_L2_MAC_NOT_AUTH_BY_HYP, "L2 mac not authorized by hypervisor"},
185 {IPA_RC_L2_MAC_NOT_AUTH_BY_ADP, "L2 mac not authorized by adapter"},
184 {IPA_RC_L2_MAC_NOT_FOUND, "L2 mac address not found"}, 186 {IPA_RC_L2_MAC_NOT_FOUND, "L2 mac address not found"},
185 {IPA_RC_L2_INVALID_VLAN_ID, "L2 invalid vlan id"}, 187 {IPA_RC_L2_INVALID_VLAN_ID, "L2 invalid vlan id"},
186 {IPA_RC_L2_DUP_VLAN_ID, "L2 duplicate vlan id"}, 188 {IPA_RC_L2_DUP_VLAN_ID, "L2 duplicate vlan id"},
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index 18548822e37c..eecb2ee62e85 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -168,6 +168,8 @@ enum qeth_ipa_return_codes {
168 IPA_RC_L2_ADDR_TABLE_FULL = 0x2006, 168 IPA_RC_L2_ADDR_TABLE_FULL = 0x2006,
169 IPA_RC_L2_DUP_LAYER3_MAC = 0x200a, 169 IPA_RC_L2_DUP_LAYER3_MAC = 0x200a,
170 IPA_RC_L2_GMAC_NOT_FOUND = 0x200b, 170 IPA_RC_L2_GMAC_NOT_FOUND = 0x200b,
171 IPA_RC_L2_MAC_NOT_AUTH_BY_HYP = 0x200c,
172 IPA_RC_L2_MAC_NOT_AUTH_BY_ADP = 0x200d,
171 IPA_RC_L2_MAC_NOT_FOUND = 0x2010, 173 IPA_RC_L2_MAC_NOT_FOUND = 0x2010,
172 IPA_RC_L2_INVALID_VLAN_ID = 0x2015, 174 IPA_RC_L2_INVALID_VLAN_ID = 0x2015,
173 IPA_RC_L2_DUP_VLAN_ID = 0x2016, 175 IPA_RC_L2_DUP_VLAN_ID = 0x2016,
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 172031baedc1..81d7f268418a 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/net/qeth_l2_main.c 2 * drivers/s390/net/qeth_l2_main.c
3 * 3 *
4 * Copyright IBM Corp. 2007 4 * Copyright IBM Corp. 2007, 2009
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>, 5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>, 6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>, 7 * Thomas Spatzier <tspat@de.ibm.com>,
@@ -19,6 +19,7 @@
19#include <linux/etherdevice.h> 19#include <linux/etherdevice.h>
20#include <linux/mii.h> 20#include <linux/mii.h>
21#include <linux/ip.h> 21#include <linux/ip.h>
22#include <linux/list.h>
22 23
23#include "qeth_core.h" 24#include "qeth_core.h"
24 25
@@ -130,7 +131,7 @@ static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card,
130 cmd = (struct qeth_ipa_cmd *) data; 131 cmd = (struct qeth_ipa_cmd *) data;
131 mac = &cmd->data.setdelmac.mac[0]; 132 mac = &cmd->data.setdelmac.mac[0];
132 /* MAC already registered, needed in couple/uncouple case */ 133 /* MAC already registered, needed in couple/uncouple case */
133 if (cmd->hdr.return_code == 0x2005) { 134 if (cmd->hdr.return_code == IPA_RC_L2_DUP_MAC) {
134 QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n", 135 QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n",
135 mac, QETH_CARD_IFNAME(card)); 136 mac, QETH_CARD_IFNAME(card));
136 cmd->hdr.return_code = 0; 137 cmd->hdr.return_code = 0;
@@ -502,6 +503,30 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card,
502 if (cmd->hdr.return_code) { 503 if (cmd->hdr.return_code) {
503 QETH_DBF_TEXT_(TRACE, 2, "L2er%x", cmd->hdr.return_code); 504 QETH_DBF_TEXT_(TRACE, 2, "L2er%x", cmd->hdr.return_code);
504 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; 505 card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
506 switch (cmd->hdr.return_code) {
507 case IPA_RC_L2_DUP_MAC:
508 case IPA_RC_L2_DUP_LAYER3_MAC:
509 dev_warn(&card->gdev->dev,
510 "MAC address "
511 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
512 "already exists\n",
513 card->dev->dev_addr[0], card->dev->dev_addr[1],
514 card->dev->dev_addr[2], card->dev->dev_addr[3],
515 card->dev->dev_addr[4], card->dev->dev_addr[5]);
516 break;
517 case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP:
518 case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP:
519 dev_warn(&card->gdev->dev,
520 "MAC address "
521 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
522 "is not authorized\n",
523 card->dev->dev_addr[0], card->dev->dev_addr[1],
524 card->dev->dev_addr[2], card->dev->dev_addr[3],
525 card->dev->dev_addr[4], card->dev->dev_addr[5]);
526 break;
527 default:
528 break;
529 }
505 cmd->hdr.return_code = -EIO; 530 cmd->hdr.return_code = -EIO;
506 } else { 531 } else {
507 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; 532 card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
@@ -616,6 +641,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
616{ 641{
617 struct qeth_card *card = dev->ml_priv; 642 struct qeth_card *card = dev->ml_priv;
618 struct dev_addr_list *dm; 643 struct dev_addr_list *dm;
644 struct netdev_hw_addr *ha;
619 645
620 if (card->info.type == QETH_CARD_TYPE_OSN) 646 if (card->info.type == QETH_CARD_TYPE_OSN)
621 return ; 647 return ;
@@ -629,8 +655,8 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
629 for (dm = dev->mc_list; dm; dm = dm->next) 655 for (dm = dev->mc_list; dm; dm = dm->next)
630 qeth_l2_add_mc(card, dm->da_addr, 0); 656 qeth_l2_add_mc(card, dm->da_addr, 0);
631 657
632 for (dm = dev->uc_list; dm; dm = dm->next) 658 list_for_each_entry(ha, &dev->uc_list, list)
633 qeth_l2_add_mc(card, dm->da_addr, 1); 659 qeth_l2_add_mc(card, ha->addr, 1);
634 660
635 spin_unlock_bh(&card->mclock); 661 spin_unlock_bh(&card->mclock);
636 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) 662 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
@@ -839,6 +865,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
839{ 865{
840 struct qeth_card *card = dev_get_drvdata(&cgdev->dev); 866 struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
841 867
868 qeth_set_allowed_threads(card, 0, 1);
842 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); 869 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
843 870
844 if (cgdev->state == CCWGROUP_ONLINE) { 871 if (cgdev->state == CCWGROUP_ONLINE) {
@@ -974,8 +1001,9 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
974 dev_warn(&card->gdev->dev, 1001 dev_warn(&card->gdev->dev,
975 "The LAN is offline\n"); 1002 "The LAN is offline\n");
976 card->lan_online = 0; 1003 card->lan_online = 0;
1004 return 0;
977 } 1005 }
978 return rc; 1006 goto out_remove;
979 } else 1007 } else
980 card->lan_online = 1; 1008 card->lan_online = 1;
981 1009
@@ -1113,12 +1141,62 @@ static void qeth_l2_shutdown(struct ccwgroup_device *gdev)
1113 qeth_clear_qdio_buffers(card); 1141 qeth_clear_qdio_buffers(card);
1114} 1142}
1115 1143
1144static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev)
1145{
1146 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
1147
1148 if (card->dev)
1149 netif_device_detach(card->dev);
1150 qeth_set_allowed_threads(card, 0, 1);
1151 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
1152 if (gdev->state == CCWGROUP_OFFLINE)
1153 return 0;
1154 if (card->state == CARD_STATE_UP) {
1155 card->use_hard_stop = 1;
1156 __qeth_l2_set_offline(card->gdev, 1);
1157 } else
1158 __qeth_l2_set_offline(card->gdev, 0);
1159 return 0;
1160}
1161
1162static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
1163{
1164 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
1165 int rc = 0;
1166
1167 if (gdev->state == CCWGROUP_OFFLINE)
1168 goto out;
1169
1170 if (card->state == CARD_STATE_RECOVER) {
1171 rc = __qeth_l2_set_online(card->gdev, 1);
1172 if (rc) {
1173 if (card->dev) {
1174 rtnl_lock();
1175 dev_close(card->dev);
1176 rtnl_unlock();
1177 }
1178 }
1179 } else
1180 rc = __qeth_l2_set_online(card->gdev, 0);
1181out:
1182 qeth_set_allowed_threads(card, 0xffffffff, 0);
1183 if (card->dev)
1184 netif_device_attach(card->dev);
1185 if (rc)
1186 dev_warn(&card->gdev->dev, "The qeth device driver "
1187 "failed to recover an error on the device\n");
1188 return rc;
1189}
1190
1116struct ccwgroup_driver qeth_l2_ccwgroup_driver = { 1191struct ccwgroup_driver qeth_l2_ccwgroup_driver = {
1117 .probe = qeth_l2_probe_device, 1192 .probe = qeth_l2_probe_device,
1118 .remove = qeth_l2_remove_device, 1193 .remove = qeth_l2_remove_device,
1119 .set_online = qeth_l2_set_online, 1194 .set_online = qeth_l2_set_online,
1120 .set_offline = qeth_l2_set_offline, 1195 .set_offline = qeth_l2_set_offline,
1121 .shutdown = qeth_l2_shutdown, 1196 .shutdown = qeth_l2_shutdown,
1197 .freeze = qeth_l2_pm_suspend,
1198 .thaw = qeth_l2_pm_resume,
1199 .restore = qeth_l2_pm_resume,
1122}; 1200};
1123EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver); 1201EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver);
1124 1202
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 0ba3817cb6a7..54872406864e 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/net/qeth_l3_main.c 2 * drivers/s390/net/qeth_l3_main.c
3 * 3 *
4 * Copyright IBM Corp. 2007 4 * Copyright IBM Corp. 2007, 2009
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>, 5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>, 6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>, 7 * Thomas Spatzier <tspat@de.ibm.com>,
@@ -1920,16 +1920,22 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
1920 hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]); 1920 hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
1921 } 1921 }
1922 1922
1923 skb->ip_summed = card->options.checksum_type; 1923 switch (card->options.checksum_type) {
1924 if (card->options.checksum_type == HW_CHECKSUMMING) { 1924 case SW_CHECKSUMMING:
1925 skb->ip_summed = CHECKSUM_NONE;
1926 break;
1927 case NO_CHECKSUMMING:
1928 skb->ip_summed = CHECKSUM_UNNECESSARY;
1929 break;
1930 case HW_CHECKSUMMING:
1925 if ((hdr->hdr.l3.ext_flags & 1931 if ((hdr->hdr.l3.ext_flags &
1926 (QETH_HDR_EXT_CSUM_HDR_REQ | 1932 (QETH_HDR_EXT_CSUM_HDR_REQ |
1927 QETH_HDR_EXT_CSUM_TRANSP_REQ)) == 1933 QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
1928 (QETH_HDR_EXT_CSUM_HDR_REQ | 1934 (QETH_HDR_EXT_CSUM_HDR_REQ |
1929 QETH_HDR_EXT_CSUM_TRANSP_REQ)) 1935 QETH_HDR_EXT_CSUM_TRANSP_REQ))
1930 skb->ip_summed = CHECKSUM_UNNECESSARY; 1936 skb->ip_summed = CHECKSUM_UNNECESSARY;
1931 else 1937 else
1932 skb->ip_summed = SW_CHECKSUMMING; 1938 skb->ip_summed = CHECKSUM_NONE;
1933 } 1939 }
1934 1940
1935 return vlan_id; 1941 return vlan_id;
@@ -2543,9 +2549,9 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
2543 /* IPv4 */ 2549 /* IPv4 */
2544 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type); 2550 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type);
2545 memset(hdr->hdr.l3.dest_addr, 0, 12); 2551 memset(hdr->hdr.l3.dest_addr, 0, 12);
2546 if ((skb->dst) && (skb->dst->neighbour)) { 2552 if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) {
2547 *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = 2553 *((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
2548 *((u32 *) skb->dst->neighbour->primary_key); 2554 *((u32 *) skb_dst(skb)->neighbour->primary_key);
2549 } else { 2555 } else {
2550 /* fill in destination address used in ip header */ 2556 /* fill in destination address used in ip header */
2551 *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = 2557 *((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
@@ -2556,9 +2562,9 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
2556 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type); 2562 hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type);
2557 if (card->info.type == QETH_CARD_TYPE_IQD) 2563 if (card->info.type == QETH_CARD_TYPE_IQD)
2558 hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; 2564 hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU;
2559 if ((skb->dst) && (skb->dst->neighbour)) { 2565 if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) {
2560 memcpy(hdr->hdr.l3.dest_addr, 2566 memcpy(hdr->hdr.l3.dest_addr,
2561 skb->dst->neighbour->primary_key, 16); 2567 skb_dst(skb)->neighbour->primary_key, 16);
2562 } else { 2568 } else {
2563 /* fill in destination address used in ip header */ 2569 /* fill in destination address used in ip header */
2564 memcpy(hdr->hdr.l3.dest_addr, 2570 memcpy(hdr->hdr.l3.dest_addr,
@@ -3006,6 +3012,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
3006 card->dev->features |= NETIF_F_HW_VLAN_TX | 3012 card->dev->features |= NETIF_F_HW_VLAN_TX |
3007 NETIF_F_HW_VLAN_RX | 3013 NETIF_F_HW_VLAN_RX |
3008 NETIF_F_HW_VLAN_FILTER; 3014 NETIF_F_HW_VLAN_FILTER;
3015 card->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
3009 3016
3010 SET_NETDEV_DEV(card->dev, &card->gdev->dev); 3017 SET_NETDEV_DEV(card->dev, &card->gdev->dev);
3011 return register_netdev(card->dev); 3018 return register_netdev(card->dev);
@@ -3070,6 +3077,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
3070{ 3077{
3071 struct qeth_card *card = dev_get_drvdata(&cgdev->dev); 3078 struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
3072 3079
3080 qeth_set_allowed_threads(card, 0, 1);
3073 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); 3081 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
3074 3082
3075 if (cgdev->state == CCWGROUP_ONLINE) { 3083 if (cgdev->state == CCWGROUP_ONLINE) {
@@ -3141,8 +3149,9 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
3141 dev_warn(&card->gdev->dev, 3149 dev_warn(&card->gdev->dev,
3142 "The LAN is offline\n"); 3150 "The LAN is offline\n");
3143 card->lan_online = 0; 3151 card->lan_online = 0;
3152 return 0;
3144 } 3153 }
3145 return rc; 3154 goto out_remove;
3146 } else 3155 } else
3147 card->lan_online = 1; 3156 card->lan_online = 1;
3148 qeth_set_large_send(card, card->options.large_send); 3157 qeth_set_large_send(card, card->options.large_send);
@@ -3274,12 +3283,62 @@ static void qeth_l3_shutdown(struct ccwgroup_device *gdev)
3274 qeth_clear_qdio_buffers(card); 3283 qeth_clear_qdio_buffers(card);
3275} 3284}
3276 3285
3286static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev)
3287{
3288 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
3289
3290 if (card->dev)
3291 netif_device_detach(card->dev);
3292 qeth_set_allowed_threads(card, 0, 1);
3293 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
3294 if (gdev->state == CCWGROUP_OFFLINE)
3295 return 0;
3296 if (card->state == CARD_STATE_UP) {
3297 card->use_hard_stop = 1;
3298 __qeth_l3_set_offline(card->gdev, 1);
3299 } else
3300 __qeth_l3_set_offline(card->gdev, 0);
3301 return 0;
3302}
3303
3304static int qeth_l3_pm_resume(struct ccwgroup_device *gdev)
3305{
3306 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
3307 int rc = 0;
3308
3309 if (gdev->state == CCWGROUP_OFFLINE)
3310 goto out;
3311
3312 if (card->state == CARD_STATE_RECOVER) {
3313 rc = __qeth_l3_set_online(card->gdev, 1);
3314 if (rc) {
3315 if (card->dev) {
3316 rtnl_lock();
3317 dev_close(card->dev);
3318 rtnl_unlock();
3319 }
3320 }
3321 } else
3322 rc = __qeth_l3_set_online(card->gdev, 0);
3323out:
3324 qeth_set_allowed_threads(card, 0xffffffff, 0);
3325 if (card->dev)
3326 netif_device_attach(card->dev);
3327 if (rc)
3328 dev_warn(&card->gdev->dev, "The qeth device driver "
3329 "failed to recover an error on the device\n");
3330 return rc;
3331}
3332
3277struct ccwgroup_driver qeth_l3_ccwgroup_driver = { 3333struct ccwgroup_driver qeth_l3_ccwgroup_driver = {
3278 .probe = qeth_l3_probe_device, 3334 .probe = qeth_l3_probe_device,
3279 .remove = qeth_l3_remove_device, 3335 .remove = qeth_l3_remove_device,
3280 .set_online = qeth_l3_set_online, 3336 .set_online = qeth_l3_set_online,
3281 .set_offline = qeth_l3_set_offline, 3337 .set_offline = qeth_l3_set_offline,
3282 .shutdown = qeth_l3_shutdown, 3338 .shutdown = qeth_l3_shutdown,
3339 .freeze = qeth_l3_pm_suspend,
3340 .thaw = qeth_l3_pm_resume,
3341 .restore = qeth_l3_pm_resume,
3283}; 3342};
3284EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver); 3343EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver);
3285 3344
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 164e090c2625..e76a320d373b 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * IUCV special message driver 2 * IUCV special message driver
3 * 3 *
4 * Copyright 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 * Copyright IBM Corp. 2003, 2009
5 *
5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
@@ -40,6 +41,8 @@ MODULE_AUTHOR
40MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver"); 41MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver");
41 42
42static struct iucv_path *smsg_path; 43static struct iucv_path *smsg_path;
44/* dummy device used as trigger for PM functions */
45static struct device *smsg_dev;
43 46
44static DEFINE_SPINLOCK(smsg_list_lock); 47static DEFINE_SPINLOCK(smsg_list_lock);
45static LIST_HEAD(smsg_list); 48static LIST_HEAD(smsg_list);
@@ -132,14 +135,51 @@ void smsg_unregister_callback(char *prefix,
132 kfree(cb); 135 kfree(cb);
133} 136}
134 137
138static int smsg_pm_freeze(struct device *dev)
139{
140#ifdef CONFIG_PM_DEBUG
141 printk(KERN_WARNING "smsg_pm_freeze\n");
142#endif
143 if (smsg_path)
144 iucv_path_sever(smsg_path, NULL);
145 return 0;
146}
147
148static int smsg_pm_restore_thaw(struct device *dev)
149{
150 int rc;
151
152#ifdef CONFIG_PM_DEBUG
153 printk(KERN_WARNING "smsg_pm_restore_thaw\n");
154#endif
155 if (smsg_path) {
156 memset(smsg_path, 0, sizeof(*smsg_path));
157 smsg_path->msglim = 255;
158 smsg_path->flags = 0;
159 rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ",
160 NULL, NULL, NULL);
161 printk(KERN_ERR "iucv_path_connect returned with rc %i\n", rc);
162 }
163 return 0;
164}
165
166static struct dev_pm_ops smsg_pm_ops = {
167 .freeze = smsg_pm_freeze,
168 .thaw = smsg_pm_restore_thaw,
169 .restore = smsg_pm_restore_thaw,
170};
171
135static struct device_driver smsg_driver = { 172static struct device_driver smsg_driver = {
173 .owner = THIS_MODULE,
136 .name = "SMSGIUCV", 174 .name = "SMSGIUCV",
137 .bus = &iucv_bus, 175 .bus = &iucv_bus,
176 .pm = &smsg_pm_ops,
138}; 177};
139 178
140static void __exit smsg_exit(void) 179static void __exit smsg_exit(void)
141{ 180{
142 cpcmd("SET SMSG IUCV", NULL, 0, NULL); 181 cpcmd("SET SMSG IUCV", NULL, 0, NULL);
182 device_unregister(smsg_dev);
143 iucv_unregister(&smsg_handler, 1); 183 iucv_unregister(&smsg_handler, 1);
144 driver_unregister(&smsg_driver); 184 driver_unregister(&smsg_driver);
145} 185}
@@ -166,12 +206,29 @@ static int __init smsg_init(void)
166 rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ", 206 rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ",
167 NULL, NULL, NULL); 207 NULL, NULL, NULL);
168 if (rc) 208 if (rc)
169 goto out_free; 209 goto out_free_path;
210 smsg_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
211 if (!smsg_dev) {
212 rc = -ENOMEM;
213 goto out_free_path;
214 }
215 dev_set_name(smsg_dev, "smsg_iucv");
216 smsg_dev->bus = &iucv_bus;
217 smsg_dev->parent = iucv_root;
218 smsg_dev->release = (void (*)(struct device *))kfree;
219 smsg_dev->driver = &smsg_driver;
220 rc = device_register(smsg_dev);
221 if (rc)
222 goto out_free_dev;
223
170 cpcmd("SET SMSG IUCV", NULL, 0, NULL); 224 cpcmd("SET SMSG IUCV", NULL, 0, NULL);
171 return 0; 225 return 0;
172 226
173out_free: 227out_free_dev:
228 kfree(smsg_dev);
229out_free_path:
174 iucv_path_free(smsg_path); 230 iucv_path_free(smsg_path);
231 smsg_path = NULL;
175out_register: 232out_register:
176 iucv_unregister(&smsg_handler, 1); 233 iucv_unregister(&smsg_handler, 1);
177out_driver: 234out_driver:
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index b2fe5cdbcaee..d9da5c42ccbe 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -13,6 +13,36 @@
13 13
14#define ZFCP_MODEL_PRIV 0x4 14#define ZFCP_MODEL_PRIV 0x4
15 15
16static int zfcp_ccw_suspend(struct ccw_device *cdev)
17
18{
19 struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
20
21 down(&zfcp_data.config_sema);
22
23 zfcp_erp_adapter_shutdown(adapter, 0, "ccsusp1", NULL);
24 zfcp_erp_wait(adapter);
25
26 up(&zfcp_data.config_sema);
27
28 return 0;
29}
30
31static int zfcp_ccw_activate(struct ccw_device *cdev)
32
33{
34 struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
35
36 zfcp_erp_modify_adapter_status(adapter, "ccresu1", NULL,
37 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
38 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
39 "ccresu2", NULL);
40 zfcp_erp_wait(adapter);
41 flush_work(&adapter->scan_work);
42
43 return 0;
44}
45
16static struct ccw_device_id zfcp_ccw_device_id[] = { 46static struct ccw_device_id zfcp_ccw_device_id[] = {
17 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) }, 47 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) },
18 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) }, 48 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) },
@@ -227,6 +257,9 @@ static struct ccw_driver zfcp_ccw_driver = {
227 .set_offline = zfcp_ccw_set_offline, 257 .set_offline = zfcp_ccw_set_offline,
228 .notify = zfcp_ccw_notify, 258 .notify = zfcp_ccw_notify,
229 .shutdown = zfcp_ccw_shutdown, 259 .shutdown = zfcp_ccw_shutdown,
260 .freeze = zfcp_ccw_suspend,
261 .thaw = zfcp_ccw_activate,
262 .restore = zfcp_ccw_activate,
230}; 263};
231 264
232/** 265/**
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 538c68dc7bb8..2f0705d76b72 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -116,7 +116,7 @@ static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port)
116{ 116{
117 if (atomic_dec_return(&wka_port->refcount) != 0) 117 if (atomic_dec_return(&wka_port->refcount) != 0)
118 return; 118 return;
119 /* wait 10 miliseconds, other reqs might pop in */ 119 /* wait 10 milliseconds, other reqs might pop in */
120 schedule_delayed_work(&wka_port->work, HZ / 100); 120 schedule_delayed_work(&wka_port->work, HZ / 100);
121} 121}
122 122