aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2013-01-15 13:04:39 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-02-14 09:55:05 -0500
commit9a17e972529e07d6e2531e6b6712bf29687df8a6 (patch)
tree4e5668c9830d043541028647617b080028f962f0 /drivers/s390
parent5c8d0983fcd1a57acae15f717a67127f97d06780 (diff)
s390/chsc: cleanup SEI helper functions
Cleanup the functions used to call SEI. Also provide !CONFIG_PCI dummys for pci error handling. Reviewed-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/chsc.c68
1 files changed, 32 insertions, 36 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 10729bbceced..31ceef1beb8b 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -435,7 +435,6 @@ static void chsc_process_sei_scm_change(struct chsc_sei_nt0_area *sei_area)
435 435
436static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area) 436static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area)
437{ 437{
438#ifdef CONFIG_PCI
439 switch (sei_area->cc) { 438 switch (sei_area->cc) {
440 case 1: 439 case 1:
441 zpci_event_error(sei_area->ccdf); 440 zpci_event_error(sei_area->ccdf);
@@ -444,11 +443,10 @@ static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area)
444 zpci_event_availability(sei_area->ccdf); 443 zpci_event_availability(sei_area->ccdf);
445 break; 444 break;
446 default: 445 default:
447 CIO_CRW_EVENT(2, "chsc: unhandled sei content code %d\n", 446 CIO_CRW_EVENT(2, "chsc: sei nt2 unhandled cc=%d\n",
448 sei_area->cc); 447 sei_area->cc);
449 break; 448 break;
450 } 449 }
451#endif
452} 450}
453 451
454static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area) 452static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area)
@@ -471,13 +469,19 @@ static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area)
471 chsc_process_sei_scm_change(sei_area); 469 chsc_process_sei_scm_change(sei_area);
472 break; 470 break;
473 default: /* other stuff */ 471 default: /* other stuff */
474 CIO_CRW_EVENT(4, "chsc: unhandled sei content code %d\n", 472 CIO_CRW_EVENT(2, "chsc: sei nt0 unhandled cc=%d\n",
475 sei_area->cc); 473 sei_area->cc);
476 break; 474 break;
477 } 475 }
476
477 /* Check if we might have lost some information. */
478 if (sei_area->flags & 0x40) {
479 CIO_CRW_EVENT(2, "chsc: event overflow\n");
480 css_schedule_eval_all();
481 }
478} 482}
479 483
480static int __chsc_process_crw(struct chsc_sei *sei, u64 ntsm) 484static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm)
481{ 485{
482 do { 486 do {
483 memset(sei, 0, sizeof(*sei)); 487 memset(sei, 0, sizeof(*sei));
@@ -488,40 +492,37 @@ static int __chsc_process_crw(struct chsc_sei *sei, u64 ntsm)
488 if (chsc(sei)) 492 if (chsc(sei))
489 break; 493 break;
490 494
491 if (sei->response.code == 0x0001) { 495 if (sei->response.code != 0x0001) {
492 CIO_CRW_EVENT(2, "chsc: sei successful\n");
493
494 /* Check if we might have lost some information. */
495 if (sei->u.nt0_area.flags & 0x40) {
496 CIO_CRW_EVENT(2, "chsc: event overflow\n");
497 css_schedule_eval_all();
498 }
499
500 switch (sei->nt) {
501 case 0:
502 chsc_process_sei_nt0(&sei->u.nt0_area);
503 break;
504 case 2:
505 chsc_process_sei_nt2(&sei->u.nt2_area);
506 break;
507 default:
508 CIO_CRW_EVENT(2, "chsc: unhandled nt=%d\n",
509 sei->nt);
510 break;
511 }
512 } else {
513 CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", 496 CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n",
514 sei->response.code); 497 sei->response.code);
515 break; 498 break;
516 } 499 }
517 } while (sei->u.nt0_area.flags & 0x80);
518 500
519 return 0; 501 CIO_CRW_EVENT(2, "chsc: sei successful (nt=%d)\n", sei->nt);
502 switch (sei->nt) {
503 case 0:
504 chsc_process_sei_nt0(&sei->u.nt0_area);
505 break;
506 case 2:
507 chsc_process_sei_nt2(&sei->u.nt2_area);
508 break;
509 default:
510 CIO_CRW_EVENT(2, "chsc: unhandled nt: %d\n", sei->nt);
511 break;
512 }
513 } while (sei->u.nt0_area.flags & 0x80);
520} 514}
521 515
516/*
517 * Handle channel subsystem related CRWs.
518 * Use store event information to find out what's going on.
519 *
520 * Note: Access to sei_page is serialized through machine check handler
521 * thread, so no need for locking.
522 */
522static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) 523static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
523{ 524{
524 struct chsc_sei *sei; 525 struct chsc_sei *sei = sei_page;
525 526
526 if (overflow) { 527 if (overflow) {
527 css_schedule_eval_all(); 528 css_schedule_eval_all();
@@ -531,14 +532,9 @@ static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
531 "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", 532 "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
532 crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc, 533 crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc,
533 crw0->erc, crw0->rsid); 534 crw0->erc, crw0->rsid);
534 if (!sei_page)
535 return;
536 /* Access to sei_page is serialized through machine check handler
537 * thread, so no need for locking. */
538 sei = sei_page;
539 535
540 CIO_TRACE_EVENT(2, "prcss"); 536 CIO_TRACE_EVENT(2, "prcss");
541 __chsc_process_crw(sei, CHSC_SEI_NT0 | CHSC_SEI_NT2); 537 chsc_process_event_information(sei, CHSC_SEI_NT0 | CHSC_SEI_NT2);
542} 538}
543 539
544void chsc_chp_online(struct chp_id chpid) 540void chsc_chp_online(struct chp_id chpid)