diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2008-07-14 03:58:46 -0400 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-07-14 04:02:06 -0400 |
commit | c11561897ab57a3c11e0a284ba17795d580589ab (patch) | |
tree | 53224c4e8062a85b1794a3cabe81a86317538dfa /drivers/s390/cio/chsc.c | |
parent | c820de39bd083222f5be2563181c87493e436f7c (diff) |
[S390] cio: Cleanup crw interface.
Eliminate the need for the machine check handler to call into
the common I/O layer directly by introducing an interface to
register handlers for crws per rsc.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/chsc.c')
-rw-r--r-- | drivers/s390/cio/chsc.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 1c0f5db94c7b..cb36f7929786 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/cio.h> | 16 | #include <asm/cio.h> |
17 | #include <asm/chpid.h> | 17 | #include <asm/chpid.h> |
18 | 18 | ||
19 | #include "../s390mach.h" | ||
19 | #include "css.h" | 20 | #include "css.h" |
20 | #include "cio.h" | 21 | #include "cio.h" |
21 | #include "cio_debug.h" | 22 | #include "cio_debug.h" |
@@ -372,17 +373,25 @@ static void chsc_process_sei(struct chsc_sei_area *sei_area) | |||
372 | } | 373 | } |
373 | } | 374 | } |
374 | 375 | ||
375 | void chsc_process_crw(void) | 376 | static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) |
376 | { | 377 | { |
377 | struct chsc_sei_area *sei_area; | 378 | struct chsc_sei_area *sei_area; |
378 | 379 | ||
380 | if (overflow) { | ||
381 | css_schedule_eval_all(); | ||
382 | return; | ||
383 | } | ||
384 | CIO_CRW_EVENT(2, "CRW reports slct=%d, oflw=%d, " | ||
385 | "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", | ||
386 | crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc, | ||
387 | crw0->erc, crw0->rsid); | ||
379 | if (!sei_page) | 388 | if (!sei_page) |
380 | return; | 389 | return; |
381 | /* Access to sei_page is serialized through machine check handler | 390 | /* Access to sei_page is serialized through machine check handler |
382 | * thread, so no need for locking. */ | 391 | * thread, so no need for locking. */ |
383 | sei_area = sei_page; | 392 | sei_area = sei_page; |
384 | 393 | ||
385 | CIO_TRACE_EVENT( 2, "prcss"); | 394 | CIO_TRACE_EVENT(2, "prcss"); |
386 | do { | 395 | do { |
387 | memset(sei_area, 0, sizeof(*sei_area)); | 396 | memset(sei_area, 0, sizeof(*sei_area)); |
388 | sei_area->request.length = 0x0010; | 397 | sei_area->request.length = 0x0010; |
@@ -751,15 +760,23 @@ out: | |||
751 | 760 | ||
752 | int __init chsc_alloc_sei_area(void) | 761 | int __init chsc_alloc_sei_area(void) |
753 | { | 762 | { |
763 | int ret; | ||
764 | |||
754 | sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | 765 | sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); |
755 | if (!sei_page) | 766 | if (!sei_page) { |
756 | CIO_MSG_EVENT(0, "Can't allocate page for processing of " | 767 | CIO_MSG_EVENT(0, "Can't allocate page for processing of " |
757 | "chsc machine checks!\n"); | 768 | "chsc machine checks!\n"); |
758 | return (sei_page ? 0 : -ENOMEM); | 769 | return -ENOMEM; |
770 | } | ||
771 | ret = s390_register_crw_handler(CRW_RSC_CSS, chsc_process_crw); | ||
772 | if (ret) | ||
773 | kfree(sei_page); | ||
774 | return ret; | ||
759 | } | 775 | } |
760 | 776 | ||
761 | void __init chsc_free_sei_area(void) | 777 | void __init chsc_free_sei_area(void) |
762 | { | 778 | { |
779 | s390_unregister_crw_handler(CRW_RSC_CSS); | ||
763 | kfree(sei_page); | 780 | kfree(sei_page); |
764 | } | 781 | } |
765 | 782 | ||