aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/chp.c
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2008-07-14 03:58:46 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2008-07-14 04:02:06 -0400
commitc11561897ab57a3c11e0a284ba17795d580589ab (patch)
tree53224c4e8062a85b1794a3cabe81a86317538dfa /drivers/s390/cio/chp.c
parentc820de39bd083222f5be2563181c87493e436f7c (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.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 297f1653b52..672d9731c52 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 */
485void chp_process_crw(int id, int status) 487static 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
499int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct res_acc_data *data) 528int chp_ssd_get_mask(struct chsc_ssd_info *ssd, struct res_acc_data *data)
@@ -674,10 +703,16 @@ static int cfg_wait_idle(void)
674static int __init chp_init(void) 703static 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())