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/chp.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/chp.c')
-rw-r--r-- | drivers/s390/cio/chp.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 297f1653b52b..672d9731c525 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/chpid.h> | 18 | #include <asm/chpid.h> |
19 | #include <asm/sclp.h> | 19 | #include <asm/sclp.h> |
20 | 20 | ||
21 | #include "../s390mach.h" | ||
21 | #include "cio.h" | 22 | #include "cio.h" |
22 | #include "css.h" | 23 | #include "css.h" |
23 | #include "ioasm.h" | 24 | #include "ioasm.h" |
@@ -476,24 +477,52 @@ void *chp_get_chp_desc(struct chp_id chpid) | |||
476 | 477 | ||
477 | /** | 478 | /** |
478 | * chp_process_crw - process channel-path status change | 479 | * chp_process_crw - process channel-path status change |
479 | * @id: channel-path ID number | 480 | * @crw0: channel report-word to handler |
480 | * @status: non-zero if channel-path has become available, zero otherwise | 481 | * @crw1: second channel-report word (always NULL) |
482 | * @overflow: crw overflow indication | ||
481 | * | 483 | * |
482 | * Handle channel-report-words indicating that the status of a channel-path | 484 | * Handle channel-report-words indicating that the status of a channel-path |
483 | * has changed. | 485 | * has changed. |
484 | */ | 486 | */ |
485 | void chp_process_crw(int id, int status) | 487 | static void chp_process_crw(struct crw *crw0, struct crw *crw1, |
488 | int overflow) | ||
486 | { | 489 | { |
487 | struct chp_id chpid; | 490 | struct chp_id chpid; |
488 | 491 | ||
492 | if (overflow) { | ||
493 | css_schedule_eval_all(); | ||
494 | return; | ||
495 | } | ||
496 | CIO_CRW_EVENT(2, "CRW reports slct=%d, oflw=%d, " | ||
497 | "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", | ||
498 | crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc, | ||
499 | crw0->erc, crw0->rsid); | ||
500 | /* | ||
501 | * Check for solicited machine checks. These are | ||
502 | * created by reset channel path and need not be | ||
503 | * handled here. | ||
504 | */ | ||
505 | if (crw0->slct) { | ||
506 | CIO_CRW_EVENT(2, "solicited machine check for " | ||
507 | "channel path %02X\n", crw0->rsid); | ||
508 | return; | ||
509 | } | ||
489 | chp_id_init(&chpid); | 510 | chp_id_init(&chpid); |
490 | chpid.id = id; | 511 | chpid.id = crw0->rsid; |
491 | if (status) { | 512 | switch (crw0->erc) { |
513 | case CRW_ERC_IPARM: /* Path has come. */ | ||
492 | if (!chp_is_registered(chpid)) | 514 | if (!chp_is_registered(chpid)) |
493 | chp_new(chpid); | 515 | chp_new(chpid); |
494 | chsc_chp_online(chpid); | 516 | chsc_chp_online(chpid); |
495 | } else | 517 | break; |
518 | case CRW_ERC_PERRI: /* Path has gone. */ | ||
519 | case CRW_ERC_PERRN: | ||
496 | chsc_chp_offline(chpid); | 520 | chsc_chp_offline(chpid); |
521 | break; | ||
522 | default: | ||
523 | CIO_CRW_EVENT(2, "Don't know how to handle erc=%x\n", | ||
524 | crw0->erc); | ||
525 | } | ||
497 | } | 526 | } |
498 | 527 | ||
499 | int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct res_acc_data *data) | 528 | int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct res_acc_data *data) |
@@ -674,10 +703,16 @@ static int cfg_wait_idle(void) | |||
674 | static int __init chp_init(void) | 703 | static int __init chp_init(void) |
675 | { | 704 | { |
676 | struct chp_id chpid; | 705 | struct chp_id chpid; |
706 | int ret; | ||
677 | 707 | ||
708 | ret = s390_register_crw_handler(CRW_RSC_CPATH, chp_process_crw); | ||
709 | if (ret) | ||
710 | return ret; | ||
678 | chp_wq = create_singlethread_workqueue("cio_chp"); | 711 | chp_wq = create_singlethread_workqueue("cio_chp"); |
679 | if (!chp_wq) | 712 | if (!chp_wq) { |
713 | s390_unregister_crw_handler(CRW_RSC_CPATH); | ||
680 | return -ENOMEM; | 714 | return -ENOMEM; |
715 | } | ||
681 | INIT_WORK(&cfg_work, cfg_func); | 716 | INIT_WORK(&cfg_work, cfg_func); |
682 | init_waitqueue_head(&cfg_wait_queue); | 717 | init_waitqueue_head(&cfg_wait_queue); |
683 | if (info_update()) | 718 | if (info_update()) |