diff options
| -rw-r--r-- | arch/s390/include/asm/eadm.h | 2 | ||||
| -rw-r--r-- | drivers/s390/block/scm_drv.c | 7 | ||||
| -rw-r--r-- | drivers/s390/cio/chsc.c | 17 | ||||
| -rw-r--r-- | drivers/s390/cio/chsc.h | 2 | ||||
| -rw-r--r-- | drivers/s390/cio/scm.c | 16 |
5 files changed, 43 insertions, 1 deletions
diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h index 78141be88b3d..dc9200ca32ed 100644 --- a/arch/s390/include/asm/eadm.h +++ b/arch/s390/include/asm/eadm.h | |||
| @@ -98,7 +98,7 @@ struct scm_device { | |||
| 98 | #define OP_STATE_TEMP_ERR 2 | 98 | #define OP_STATE_TEMP_ERR 2 |
| 99 | #define OP_STATE_PERM_ERR 3 | 99 | #define OP_STATE_PERM_ERR 3 |
| 100 | 100 | ||
| 101 | enum scm_event {SCM_CHANGE}; | 101 | enum scm_event {SCM_CHANGE, SCM_AVAIL}; |
| 102 | 102 | ||
| 103 | struct scm_driver { | 103 | struct scm_driver { |
| 104 | struct device_driver drv; | 104 | struct device_driver drv; |
diff --git a/drivers/s390/block/scm_drv.c b/drivers/s390/block/scm_drv.c index ff8558c4fe25..5f6180d6ff08 100644 --- a/drivers/s390/block/scm_drv.c +++ b/drivers/s390/block/scm_drv.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | 15 | ||
| 16 | static void scm_notify(struct scm_device *scmdev, enum scm_event event) | 16 | static void scm_notify(struct scm_device *scmdev, enum scm_event event) |
| 17 | { | 17 | { |
| 18 | struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev); | ||
| 19 | |||
| 18 | switch (event) { | 20 | switch (event) { |
| 19 | case SCM_CHANGE: | 21 | case SCM_CHANGE: |
| 20 | pr_info("%lu: The capabilities of the SCM increment changed\n", | 22 | pr_info("%lu: The capabilities of the SCM increment changed\n", |
| @@ -22,6 +24,11 @@ static void scm_notify(struct scm_device *scmdev, enum scm_event event) | |||
| 22 | SCM_LOG(2, "State changed"); | 24 | SCM_LOG(2, "State changed"); |
| 23 | SCM_LOG_STATE(2, scmdev); | 25 | SCM_LOG_STATE(2, scmdev); |
| 24 | break; | 26 | break; |
| 27 | case SCM_AVAIL: | ||
| 28 | SCM_LOG(2, "Increment available"); | ||
| 29 | SCM_LOG_STATE(2, scmdev); | ||
| 30 | scm_blk_set_available(bdev); | ||
| 31 | break; | ||
| 25 | } | 32 | } |
| 26 | } | 33 | } |
| 27 | 34 | ||
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 31ceef1beb8b..e16c553f6556 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
| @@ -433,6 +433,20 @@ static void chsc_process_sei_scm_change(struct chsc_sei_nt0_area *sei_area) | |||
| 433 | " failed (rc=%d).\n", ret); | 433 | " failed (rc=%d).\n", ret); |
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | static void chsc_process_sei_scm_avail(struct chsc_sei_nt0_area *sei_area) | ||
| 437 | { | ||
| 438 | int ret; | ||
| 439 | |||
| 440 | CIO_CRW_EVENT(4, "chsc: scm available information\n"); | ||
| 441 | if (sei_area->rs != 7) | ||
| 442 | return; | ||
| 443 | |||
| 444 | ret = scm_process_availability_information(); | ||
| 445 | if (ret) | ||
| 446 | CIO_CRW_EVENT(0, "chsc: process availability information" | ||
| 447 | " failed (rc=%d).\n", ret); | ||
| 448 | } | ||
| 449 | |||
| 436 | static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area) | 450 | static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area) |
| 437 | { | 451 | { |
| 438 | switch (sei_area->cc) { | 452 | switch (sei_area->cc) { |
| @@ -468,6 +482,9 @@ static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area) | |||
| 468 | case 12: /* scm change notification */ | 482 | case 12: /* scm change notification */ |
| 469 | chsc_process_sei_scm_change(sei_area); | 483 | chsc_process_sei_scm_change(sei_area); |
| 470 | break; | 484 | break; |
| 485 | case 14: /* scm available notification */ | ||
| 486 | chsc_process_sei_scm_avail(sei_area); | ||
| 487 | break; | ||
| 471 | default: /* other stuff */ | 488 | default: /* other stuff */ |
| 472 | CIO_CRW_EVENT(2, "chsc: sei nt0 unhandled cc=%d\n", | 489 | CIO_CRW_EVENT(2, "chsc: sei nt0 unhandled cc=%d\n", |
| 473 | sei_area->cc); | 490 | sei_area->cc); |
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index 227e05f674b3..349d5fc47196 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h | |||
| @@ -156,8 +156,10 @@ int chsc_scm_info(struct chsc_scm_info *scm_area, u64 token); | |||
| 156 | 156 | ||
| 157 | #ifdef CONFIG_SCM_BUS | 157 | #ifdef CONFIG_SCM_BUS |
| 158 | int scm_update_information(void); | 158 | int scm_update_information(void); |
| 159 | int scm_process_availability_information(void); | ||
| 159 | #else /* CONFIG_SCM_BUS */ | 160 | #else /* CONFIG_SCM_BUS */ |
| 160 | static inline int scm_update_information(void) { return 0; } | 161 | static inline int scm_update_information(void) { return 0; } |
| 162 | static inline int scm_process_availability_information(void) { return 0; } | ||
| 161 | #endif /* CONFIG_SCM_BUS */ | 163 | #endif /* CONFIG_SCM_BUS */ |
| 162 | 164 | ||
| 163 | 165 | ||
diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c index 31ac26499979..46ec25632e8b 100644 --- a/drivers/s390/cio/scm.c +++ b/drivers/s390/cio/scm.c | |||
| @@ -297,6 +297,22 @@ int scm_update_information(void) | |||
| 297 | return ret; | 297 | return ret; |
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | static int scm_dev_avail(struct device *dev, void *unused) | ||
| 301 | { | ||
| 302 | struct scm_driver *scmdrv = to_scm_drv(dev->driver); | ||
| 303 | struct scm_device *scmdev = to_scm_dev(dev); | ||
| 304 | |||
| 305 | if (dev->driver && scmdrv->notify) | ||
| 306 | scmdrv->notify(scmdev, SCM_AVAIL); | ||
| 307 | |||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | int scm_process_availability_information(void) | ||
| 312 | { | ||
| 313 | return bus_for_each_dev(&scm_bus_type, NULL, NULL, scm_dev_avail); | ||
| 314 | } | ||
| 315 | |||
| 300 | static int __init scm_init(void) | 316 | static int __init scm_init(void) |
| 301 | { | 317 | { |
| 302 | int ret; | 318 | int ret; |
