diff options
author | Michael Ernst <mernst@de.ibm.com> | 2010-08-09 12:12:50 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-08-09 12:12:53 -0400 |
commit | fd0457a6ae52141718a15652fb80d867e1bf1d10 (patch) | |
tree | 5bbc54259c2ddfbf96a2be728e8d971fdb7f2039 /drivers/s390/cio/chsc.c | |
parent | 45d7f32c7a43cbb9592886d38190e379e2eb2226 (diff) |
[S390] cio: CHSC SIOSL Support
A Linux interface for the CHSC command
store-I/O-operation-status-and-initiate-logging (SIOSL).
Model-dependent logging within the channel subsystem can be invoked
via a helper function or a writable subchannel device attribute.
Signed-off-by: Michael Ernst <mernst@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/chsc.c')
-rw-r--r-- | drivers/s390/cio/chsc.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 407d0e9adfaf..4cbb1a6ca33c 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "chsc.h" | 29 | #include "chsc.h" |
30 | 30 | ||
31 | static void *sei_page; | 31 | static void *sei_page; |
32 | static DEFINE_SPINLOCK(siosl_lock); | ||
32 | static DEFINE_SPINLOCK(sda_lock); | 33 | static DEFINE_SPINLOCK(sda_lock); |
33 | 34 | ||
34 | /** | 35 | /** |
@@ -48,6 +49,7 @@ int chsc_error_from_response(int response) | |||
48 | case 0x0007: | 49 | case 0x0007: |
49 | case 0x0008: | 50 | case 0x0008: |
50 | case 0x000a: | 51 | case 0x000a: |
52 | case 0x0104: | ||
51 | return -EINVAL; | 53 | return -EINVAL; |
52 | case 0x0004: | 54 | case 0x0004: |
53 | return -EOPNOTSUPP; | 55 | return -EOPNOTSUPP; |
@@ -974,3 +976,49 @@ int chsc_sstpi(void *page, void *result, size_t size) | |||
974 | return (rr->response.code == 0x0001) ? 0 : -EIO; | 976 | return (rr->response.code == 0x0001) ? 0 : -EIO; |
975 | } | 977 | } |
976 | 978 | ||
979 | static struct { | ||
980 | struct chsc_header request; | ||
981 | u32 word1; | ||
982 | struct subchannel_id sid; | ||
983 | u32 word3; | ||
984 | struct chsc_header response; | ||
985 | u32 word[11]; | ||
986 | } __attribute__ ((packed)) siosl_area __attribute__ ((__aligned__(PAGE_SIZE))); | ||
987 | |||
988 | int chsc_siosl(struct subchannel_id schid) | ||
989 | { | ||
990 | unsigned long flags; | ||
991 | int ccode; | ||
992 | int rc; | ||
993 | |||
994 | spin_lock_irqsave(&siosl_lock, flags); | ||
995 | memset(&siosl_area, 0, sizeof(siosl_area)); | ||
996 | siosl_area.request.length = 0x0010; | ||
997 | siosl_area.request.code = 0x0046; | ||
998 | siosl_area.word1 = 0x80000000; | ||
999 | siosl_area.sid = schid; | ||
1000 | |||
1001 | ccode = chsc(&siosl_area); | ||
1002 | if (ccode > 0) { | ||
1003 | if (ccode == 3) | ||
1004 | rc = -ENODEV; | ||
1005 | else | ||
1006 | rc = -EBUSY; | ||
1007 | CIO_MSG_EVENT(2, "chsc: chsc failed for 0.%x.%04x (ccode=%d)\n", | ||
1008 | schid.ssid, schid.sch_no, ccode); | ||
1009 | goto out; | ||
1010 | } | ||
1011 | rc = chsc_error_from_response(siosl_area.response.code); | ||
1012 | if (rc) | ||
1013 | CIO_MSG_EVENT(2, "chsc: siosl failed for 0.%x.%04x (rc=%04x)\n", | ||
1014 | schid.ssid, schid.sch_no, | ||
1015 | siosl_area.response.code); | ||
1016 | else | ||
1017 | CIO_MSG_EVENT(4, "chsc: siosl succeeded for 0.%x.%04x\n", | ||
1018 | schid.ssid, schid.sch_no); | ||
1019 | out: | ||
1020 | spin_unlock_irqrestore(&siosl_lock, flags); | ||
1021 | |||
1022 | return rc; | ||
1023 | } | ||
1024 | EXPORT_SYMBOL_GPL(chsc_siosl); | ||