aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/chsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/chsc.c')
-rw-r--r--drivers/s390/cio/chsc.c130
1 files changed, 33 insertions, 97 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 02615eb43984..89a130a62654 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -195,12 +195,8 @@ static void terminate_internal_io(struct subchannel *sch)
195 if (cio_clear(sch)) { 195 if (cio_clear(sch)) {
196 /* Recheck device in case clear failed. */ 196 /* Recheck device in case clear failed. */
197 sch->lpm = 0; 197 sch->lpm = 0;
198 if (device_trigger_verify(sch) != 0) { 198 if (device_trigger_verify(sch) != 0)
199 if(css_enqueue_subchannel_slow(sch->schid)) { 199 css_schedule_eval(sch->schid);
200 css_clear_subchannel_slow_list();
201 need_rescan = 1;
202 }
203 }
204 return; 200 return;
205 } 201 }
206 /* Request retry of internal operation. */ 202 /* Request retry of internal operation. */
@@ -262,11 +258,8 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
262 258
263out_unreg: 259out_unreg:
264 sch->lpm = 0; 260 sch->lpm = 0;
265 if (css_enqueue_subchannel_slow(sch->schid)) {
266 css_clear_subchannel_slow_list();
267 need_rescan = 1;
268 }
269 spin_unlock_irq(sch->lock); 261 spin_unlock_irq(sch->lock);
262 css_schedule_eval(sch->schid);
270 return 0; 263 return 0;
271} 264}
272 265
@@ -281,9 +274,6 @@ void chsc_chp_offline(struct chp_id chpid)
281 return; 274 return;
282 bus_for_each_dev(&css_bus_type, NULL, &chpid, 275 bus_for_each_dev(&css_bus_type, NULL, &chpid,
283 s390_subchannel_remove_chpid); 276 s390_subchannel_remove_chpid);
284
285 if (need_rescan || css_slow_subchannels_exist())
286 queue_work(slow_path_wq, &slow_path_work);
287} 277}
288 278
289struct res_acc_data { 279struct res_acc_data {
@@ -331,7 +321,6 @@ static int
331s390_process_res_acc_new_sch(struct subchannel_id schid) 321s390_process_res_acc_new_sch(struct subchannel_id schid)
332{ 322{
333 struct schib schib; 323 struct schib schib;
334 int ret;
335 /* 324 /*
336 * We don't know the device yet, but since a path 325 * We don't know the device yet, but since a path
337 * may be available now to the device we'll have 326 * may be available now to the device we'll have
@@ -342,15 +331,10 @@ s390_process_res_acc_new_sch(struct subchannel_id schid)
342 */ 331 */
343 if (stsch_err(schid, &schib)) 332 if (stsch_err(schid, &schib))
344 /* We're through */ 333 /* We're through */
345 return need_rescan ? -EAGAIN : -ENXIO; 334 return -ENXIO;
346 335
347 /* Put it on the slow path. */ 336 /* Put it on the slow path. */
348 ret = css_enqueue_subchannel_slow(schid); 337 css_schedule_eval(schid);
349 if (ret) {
350 css_clear_subchannel_slow_list();
351 need_rescan = 1;
352 return -EAGAIN;
353 }
354 return 0; 338 return 0;
355} 339}
356 340
@@ -392,10 +376,8 @@ __s390_process_res_acc(struct subchannel_id schid, void *data)
392} 376}
393 377
394 378
395static int 379static void s390_process_res_acc (struct res_acc_data *res_data)
396s390_process_res_acc (struct res_acc_data *res_data)
397{ 380{
398 int rc;
399 char dbf_txt[15]; 381 char dbf_txt[15];
400 382
401 sprintf(dbf_txt, "accpr%x.%02x", res_data->chpid.cssid, 383 sprintf(dbf_txt, "accpr%x.%02x", res_data->chpid.cssid,
@@ -413,12 +395,7 @@ s390_process_res_acc (struct res_acc_data *res_data)
413 * The more information we have (info), the less scanning 395 * The more information we have (info), the less scanning
414 * will we have to do. 396 * will we have to do.
415 */ 397 */
416 rc = for_each_subchannel(__s390_process_res_acc, res_data); 398 for_each_subchannel(__s390_process_res_acc, res_data);
417 if (css_slow_subchannels_exist())
418 rc = -EAGAIN;
419 else if (rc != -EAGAIN)
420 rc = 0;
421 return rc;
422} 399}
423 400
424static int 401static int
@@ -470,7 +447,7 @@ struct chsc_sei_area {
470 /* ccdf has to be big enough for a link-incident record */ 447 /* ccdf has to be big enough for a link-incident record */
471} __attribute__ ((packed)); 448} __attribute__ ((packed));
472 449
473static int chsc_process_sei_link_incident(struct chsc_sei_area *sei_area) 450static void chsc_process_sei_link_incident(struct chsc_sei_area *sei_area)
474{ 451{
475 struct chp_id chpid; 452 struct chp_id chpid;
476 int id; 453 int id;
@@ -478,7 +455,7 @@ static int chsc_process_sei_link_incident(struct chsc_sei_area *sei_area)
478 CIO_CRW_EVENT(4, "chsc: link incident (rs=%02x, rs_id=%04x)\n", 455 CIO_CRW_EVENT(4, "chsc: link incident (rs=%02x, rs_id=%04x)\n",
479 sei_area->rs, sei_area->rsid); 456 sei_area->rs, sei_area->rsid);
480 if (sei_area->rs != 4) 457 if (sei_area->rs != 4)
481 return 0; 458 return;
482 id = __get_chpid_from_lir(sei_area->ccdf); 459 id = __get_chpid_from_lir(sei_area->ccdf);
483 if (id < 0) 460 if (id < 0)
484 CIO_CRW_EVENT(4, "chsc: link incident - invalid LIR\n"); 461 CIO_CRW_EVENT(4, "chsc: link incident - invalid LIR\n");
@@ -487,21 +464,18 @@ static int chsc_process_sei_link_incident(struct chsc_sei_area *sei_area)
487 chpid.id = id; 464 chpid.id = id;
488 chsc_chp_offline(chpid); 465 chsc_chp_offline(chpid);
489 } 466 }
490
491 return 0;
492} 467}
493 468
494static int chsc_process_sei_res_acc(struct chsc_sei_area *sei_area) 469static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area)
495{ 470{
496 struct res_acc_data res_data; 471 struct res_acc_data res_data;
497 struct chp_id chpid; 472 struct chp_id chpid;
498 int status; 473 int status;
499 int rc;
500 474
501 CIO_CRW_EVENT(4, "chsc: resource accessibility event (rs=%02x, " 475 CIO_CRW_EVENT(4, "chsc: resource accessibility event (rs=%02x, "
502 "rs_id=%04x)\n", sei_area->rs, sei_area->rsid); 476 "rs_id=%04x)\n", sei_area->rs, sei_area->rsid);
503 if (sei_area->rs != 4) 477 if (sei_area->rs != 4)
504 return 0; 478 return;
505 chp_id_init(&chpid); 479 chp_id_init(&chpid);
506 chpid.id = sei_area->rsid; 480 chpid.id = sei_area->rsid;
507 /* allocate a new channel path structure, if needed */ 481 /* allocate a new channel path structure, if needed */
@@ -509,7 +483,7 @@ static int chsc_process_sei_res_acc(struct chsc_sei_area *sei_area)
509 if (status < 0) 483 if (status < 0)
510 chp_new(chpid); 484 chp_new(chpid);
511 else if (!status) 485 else if (!status)
512 return 0; 486 return;
513 memset(&res_data, 0, sizeof(struct res_acc_data)); 487 memset(&res_data, 0, sizeof(struct res_acc_data));
514 res_data.chpid = chpid; 488 res_data.chpid = chpid;
515 if ((sei_area->vf & 0xc0) != 0) { 489 if ((sei_area->vf & 0xc0) != 0) {
@@ -521,9 +495,7 @@ static int chsc_process_sei_res_acc(struct chsc_sei_area *sei_area)
521 /* link address */ 495 /* link address */
522 res_data.fla_mask = 0xff00; 496 res_data.fla_mask = 0xff00;
523 } 497 }
524 rc = s390_process_res_acc(&res_data); 498 s390_process_res_acc(&res_data);
525
526 return rc;
527} 499}
528 500
529struct chp_config_data { 501struct chp_config_data {
@@ -532,7 +504,7 @@ struct chp_config_data {
532 u8 pc; 504 u8 pc;
533}; 505};
534 506
535static int chsc_process_sei_chp_config(struct chsc_sei_area *sei_area) 507static void chsc_process_sei_chp_config(struct chsc_sei_area *sei_area)
536{ 508{
537 struct chp_config_data *data; 509 struct chp_config_data *data;
538 struct chp_id chpid; 510 struct chp_id chpid;
@@ -540,7 +512,7 @@ static int chsc_process_sei_chp_config(struct chsc_sei_area *sei_area)
540 512
541 CIO_CRW_EVENT(4, "chsc: channel-path-configuration notification\n"); 513 CIO_CRW_EVENT(4, "chsc: channel-path-configuration notification\n");
542 if (sei_area->rs != 0) 514 if (sei_area->rs != 0)
543 return 0; 515 return;
544 data = (struct chp_config_data *) &(sei_area->ccdf); 516 data = (struct chp_config_data *) &(sei_area->ccdf);
545 chp_id_init(&chpid); 517 chp_id_init(&chpid);
546 for (num = 0; num <= __MAX_CHPID; num++) { 518 for (num = 0; num <= __MAX_CHPID; num++) {
@@ -561,52 +533,44 @@ static int chsc_process_sei_chp_config(struct chsc_sei_area *sei_area)
561 break; 533 break;
562 } 534 }
563 } 535 }
564
565 return 0;
566} 536}
567 537
568static int chsc_process_sei(struct chsc_sei_area *sei_area) 538static void chsc_process_sei(struct chsc_sei_area *sei_area)
569{ 539{
570 int rc;
571
572 /* Check if we might have lost some information. */ 540 /* Check if we might have lost some information. */
573 if (sei_area->flags & 0x40) 541 if (sei_area->flags & 0x40) {
574 CIO_CRW_EVENT(2, "chsc: event overflow\n"); 542 CIO_CRW_EVENT(2, "chsc: event overflow\n");
543 css_schedule_eval_all();
544 }
575 /* which kind of information was stored? */ 545 /* which kind of information was stored? */
576 rc = 0;
577 switch (sei_area->cc) { 546 switch (sei_area->cc) {
578 case 1: /* link incident*/ 547 case 1: /* link incident*/
579 rc = chsc_process_sei_link_incident(sei_area); 548 chsc_process_sei_link_incident(sei_area);
580 break; 549 break;
581 case 2: /* i/o resource accessibiliy */ 550 case 2: /* i/o resource accessibiliy */
582 rc = chsc_process_sei_res_acc(sei_area); 551 chsc_process_sei_res_acc(sei_area);
583 break; 552 break;
584 case 8: /* channel-path-configuration notification */ 553 case 8: /* channel-path-configuration notification */
585 rc = chsc_process_sei_chp_config(sei_area); 554 chsc_process_sei_chp_config(sei_area);
586 break; 555 break;
587 default: /* other stuff */ 556 default: /* other stuff */
588 CIO_CRW_EVENT(4, "chsc: unhandled sei content code %d\n", 557 CIO_CRW_EVENT(4, "chsc: unhandled sei content code %d\n",
589 sei_area->cc); 558 sei_area->cc);
590 break; 559 break;
591 } 560 }
592
593 return rc;
594} 561}
595 562
596int chsc_process_crw(void) 563void chsc_process_crw(void)
597{ 564{
598 struct chsc_sei_area *sei_area; 565 struct chsc_sei_area *sei_area;
599 int ret;
600 int rc;
601 566
602 if (!sei_page) 567 if (!sei_page)
603 return 0; 568 return;
604 /* Access to sei_page is serialized through machine check handler 569 /* Access to sei_page is serialized through machine check handler
605 * thread, so no need for locking. */ 570 * thread, so no need for locking. */
606 sei_area = sei_page; 571 sei_area = sei_page;
607 572
608 CIO_TRACE_EVENT( 2, "prcss"); 573 CIO_TRACE_EVENT( 2, "prcss");
609 ret = 0;
610 do { 574 do {
611 memset(sei_area, 0, sizeof(*sei_area)); 575 memset(sei_area, 0, sizeof(*sei_area));
612 sei_area->request.length = 0x0010; 576 sei_area->request.length = 0x0010;
@@ -616,37 +580,26 @@ int chsc_process_crw(void)
616 580
617 if (sei_area->response.code == 0x0001) { 581 if (sei_area->response.code == 0x0001) {
618 CIO_CRW_EVENT(4, "chsc: sei successful\n"); 582 CIO_CRW_EVENT(4, "chsc: sei successful\n");
619 rc = chsc_process_sei(sei_area); 583 chsc_process_sei(sei_area);
620 if (rc)
621 ret = rc;
622 } else { 584 } else {
623 CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", 585 CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n",
624 sei_area->response.code); 586 sei_area->response.code);
625 ret = 0;
626 break; 587 break;
627 } 588 }
628 } while (sei_area->flags & 0x80); 589 } while (sei_area->flags & 0x80);
629
630 return ret;
631} 590}
632 591
633static int 592static int
634__chp_add_new_sch(struct subchannel_id schid) 593__chp_add_new_sch(struct subchannel_id schid)
635{ 594{
636 struct schib schib; 595 struct schib schib;
637 int ret;
638 596
639 if (stsch_err(schid, &schib)) 597 if (stsch_err(schid, &schib))
640 /* We're through */ 598 /* We're through */
641 return need_rescan ? -EAGAIN : -ENXIO; 599 return -ENXIO;
642 600
643 /* Put it on the slow path. */ 601 /* Put it on the slow path. */
644 ret = css_enqueue_subchannel_slow(schid); 602 css_schedule_eval(schid);
645 if (ret) {
646 css_clear_subchannel_slow_list();
647 need_rescan = 1;
648 return -EAGAIN;
649 }
650 return 0; 603 return 0;
651} 604}
652 605
@@ -693,22 +646,15 @@ __chp_add(struct subchannel_id schid, void *data)
693 return 0; 646 return 0;
694} 647}
695 648
696int chsc_chp_online(struct chp_id chpid) 649void chsc_chp_online(struct chp_id chpid)
697{ 650{
698 int rc;
699 char dbf_txt[15]; 651 char dbf_txt[15];
700 652
701 sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); 653 sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id);
702 CIO_TRACE_EVENT(2, dbf_txt); 654 CIO_TRACE_EVENT(2, dbf_txt);
703 655
704 if (chp_get_status(chpid) == 0) 656 if (chp_get_status(chpid) != 0)
705 return 0; 657 for_each_subchannel(__chp_add, &chpid);
706 rc = for_each_subchannel(__chp_add, &chpid);
707 if (css_slow_subchannels_exist())
708 rc = -EAGAIN;
709 if (rc != -EAGAIN)
710 rc = 0;
711 return rc;
712} 658}
713 659
714static void __s390_subchannel_vary_chpid(struct subchannel *sch, 660static void __s390_subchannel_vary_chpid(struct subchannel *sch,
@@ -749,12 +695,8 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch,
749 sch->driver->verify(&sch->dev); 695 sch->driver->verify(&sch->dev);
750 } 696 }
751 } else if (!sch->lpm) { 697 } else if (!sch->lpm) {
752 if (device_trigger_verify(sch) != 0) { 698 if (device_trigger_verify(sch) != 0)
753 if (css_enqueue_subchannel_slow(sch->schid)) { 699 css_schedule_eval(sch->schid);
754 css_clear_subchannel_slow_list();
755 need_rescan = 1;
756 }
757 }
758 } else if (sch->driver && sch->driver->verify) 700 } else if (sch->driver && sch->driver->verify)
759 sch->driver->verify(&sch->dev); 701 sch->driver->verify(&sch->dev);
760 break; 702 break;
@@ -801,11 +743,7 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data)
801 /* We're through */ 743 /* We're through */
802 return -ENXIO; 744 return -ENXIO;
803 /* Put it on the slow path. */ 745 /* Put it on the slow path. */
804 if (css_enqueue_subchannel_slow(schid)) { 746 css_schedule_eval(schid);
805 css_clear_subchannel_slow_list();
806 need_rescan = 1;
807 return -EAGAIN;
808 }
809 return 0; 747 return 0;
810} 748}
811 749
@@ -826,8 +764,6 @@ int chsc_chp_vary(struct chp_id chpid, int on)
826 if (on) 764 if (on)
827 /* Scan for new devices on varied on path. */ 765 /* Scan for new devices on varied on path. */
828 for_each_subchannel(__s390_vary_chpid_on, NULL); 766 for_each_subchannel(__s390_vary_chpid_on, NULL);
829 if (need_rescan || css_slow_subchannels_exist())
830 queue_work(slow_path_wq, &slow_path_work);
831 return 0; 767 return 0;
832} 768}
833 769