aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/cio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/cio.c')
-rw-r--r--drivers/s390/cio/cio.c84
1 files changed, 45 insertions, 39 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 185bc73c3ecd..396bada65f86 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -135,7 +135,7 @@ cio_tpi(void)
135 return 0; 135 return 0;
136 irb = (struct irb *) __LC_IRB; 136 irb = (struct irb *) __LC_IRB;
137 /* Store interrupt response block to lowcore. */ 137 /* Store interrupt response block to lowcore. */
138 if (tsch (tpi_info->irq, irb) != 0) 138 if (tsch (tpi_info->schid, irb) != 0)
139 /* Not status pending or not operational. */ 139 /* Not status pending or not operational. */
140 return 1; 140 return 1;
141 sch = (struct subchannel *)(unsigned long)tpi_info->intparm; 141 sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
@@ -163,10 +163,10 @@ cio_start_handle_notoper(struct subchannel *sch, __u8 lpm)
163 else 163 else
164 sch->lpm = 0; 164 sch->lpm = 0;
165 165
166 stsch (sch->irq, &sch->schib); 166 stsch (sch->schid, &sch->schib);
167 167
168 CIO_MSG_EVENT(0, "cio_start: 'not oper' status for " 168 CIO_MSG_EVENT(0, "cio_start: 'not oper' status for "
169 "subchannel %04x!\n", sch->irq); 169 "subchannel %04x!\n", sch->schid.sch_no);
170 sprintf(dbf_text, "no%s", sch->dev.bus_id); 170 sprintf(dbf_text, "no%s", sch->dev.bus_id);
171 CIO_TRACE_EVENT(0, dbf_text); 171 CIO_TRACE_EVENT(0, dbf_text);
172 CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib)); 172 CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib));
@@ -204,7 +204,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
204 sch->orb.key = key >> 4; 204 sch->orb.key = key >> 4;
205 /* issue "Start Subchannel" */ 205 /* issue "Start Subchannel" */
206 sch->orb.cpa = (__u32) __pa (cpa); 206 sch->orb.cpa = (__u32) __pa (cpa);
207 ccode = ssch (sch->irq, &sch->orb); 207 ccode = ssch (sch->schid, &sch->orb);
208 208
209 /* process condition code */ 209 /* process condition code */
210 sprintf (dbf_txt, "ccode:%d", ccode); 210 sprintf (dbf_txt, "ccode:%d", ccode);
@@ -243,7 +243,7 @@ cio_resume (struct subchannel *sch)
243 CIO_TRACE_EVENT (4, "resIO"); 243 CIO_TRACE_EVENT (4, "resIO");
244 CIO_TRACE_EVENT (4, sch->dev.bus_id); 244 CIO_TRACE_EVENT (4, sch->dev.bus_id);
245 245
246 ccode = rsch (sch->irq); 246 ccode = rsch (sch->schid);
247 247
248 sprintf (dbf_txt, "ccode:%d", ccode); 248 sprintf (dbf_txt, "ccode:%d", ccode);
249 CIO_TRACE_EVENT (4, dbf_txt); 249 CIO_TRACE_EVENT (4, dbf_txt);
@@ -283,7 +283,7 @@ cio_halt(struct subchannel *sch)
283 /* 283 /*
284 * Issue "Halt subchannel" and process condition code 284 * Issue "Halt subchannel" and process condition code
285 */ 285 */
286 ccode = hsch (sch->irq); 286 ccode = hsch (sch->schid);
287 287
288 sprintf (dbf_txt, "ccode:%d", ccode); 288 sprintf (dbf_txt, "ccode:%d", ccode);
289 CIO_TRACE_EVENT (2, dbf_txt); 289 CIO_TRACE_EVENT (2, dbf_txt);
@@ -318,7 +318,7 @@ cio_clear(struct subchannel *sch)
318 /* 318 /*
319 * Issue "Clear subchannel" and process condition code 319 * Issue "Clear subchannel" and process condition code
320 */ 320 */
321 ccode = csch (sch->irq); 321 ccode = csch (sch->schid);
322 322
323 sprintf (dbf_txt, "ccode:%d", ccode); 323 sprintf (dbf_txt, "ccode:%d", ccode);
324 CIO_TRACE_EVENT (2, dbf_txt); 324 CIO_TRACE_EVENT (2, dbf_txt);
@@ -351,7 +351,7 @@ cio_cancel (struct subchannel *sch)
351 CIO_TRACE_EVENT (2, "cancelIO"); 351 CIO_TRACE_EVENT (2, "cancelIO");
352 CIO_TRACE_EVENT (2, sch->dev.bus_id); 352 CIO_TRACE_EVENT (2, sch->dev.bus_id);
353 353
354 ccode = xsch (sch->irq); 354 ccode = xsch (sch->schid);
355 355
356 sprintf (dbf_txt, "ccode:%d", ccode); 356 sprintf (dbf_txt, "ccode:%d", ccode);
357 CIO_TRACE_EVENT (2, dbf_txt); 357 CIO_TRACE_EVENT (2, dbf_txt);
@@ -359,7 +359,7 @@ cio_cancel (struct subchannel *sch)
359 switch (ccode) { 359 switch (ccode) {
360 case 0: /* success */ 360 case 0: /* success */
361 /* Update information in scsw. */ 361 /* Update information in scsw. */
362 stsch (sch->irq, &sch->schib); 362 stsch (sch->schid, &sch->schib);
363 return 0; 363 return 0;
364 case 1: /* status pending */ 364 case 1: /* status pending */
365 return -EBUSY; 365 return -EBUSY;
@@ -381,7 +381,7 @@ cio_modify (struct subchannel *sch)
381 381
382 ret = 0; 382 ret = 0;
383 for (retry = 0; retry < 5; retry++) { 383 for (retry = 0; retry < 5; retry++) {
384 ccode = msch_err (sch->irq, &sch->schib); 384 ccode = msch_err (sch->schid, &sch->schib);
385 if (ccode < 0) /* -EIO if msch gets a program check. */ 385 if (ccode < 0) /* -EIO if msch gets a program check. */
386 return ccode; 386 return ccode;
387 switch (ccode) { 387 switch (ccode) {
@@ -414,7 +414,7 @@ cio_enable_subchannel (struct subchannel *sch, unsigned int isc)
414 CIO_TRACE_EVENT (2, "ensch"); 414 CIO_TRACE_EVENT (2, "ensch");
415 CIO_TRACE_EVENT (2, sch->dev.bus_id); 415 CIO_TRACE_EVENT (2, sch->dev.bus_id);
416 416
417 ccode = stsch (sch->irq, &sch->schib); 417 ccode = stsch (sch->schid, &sch->schib);
418 if (ccode) 418 if (ccode)
419 return -ENODEV; 419 return -ENODEV;
420 420
@@ -432,13 +432,13 @@ cio_enable_subchannel (struct subchannel *sch, unsigned int isc)
432 */ 432 */
433 sch->schib.pmcw.csense = 0; 433 sch->schib.pmcw.csense = 0;
434 if (ret == 0) { 434 if (ret == 0) {
435 stsch (sch->irq, &sch->schib); 435 stsch (sch->schid, &sch->schib);
436 if (sch->schib.pmcw.ena) 436 if (sch->schib.pmcw.ena)
437 break; 437 break;
438 } 438 }
439 if (ret == -EBUSY) { 439 if (ret == -EBUSY) {
440 struct irb irb; 440 struct irb irb;
441 if (tsch(sch->irq, &irb) != 0) 441 if (tsch(sch->schid, &irb) != 0)
442 break; 442 break;
443 } 443 }
444 } 444 }
@@ -461,7 +461,7 @@ cio_disable_subchannel (struct subchannel *sch)
461 CIO_TRACE_EVENT (2, "dissch"); 461 CIO_TRACE_EVENT (2, "dissch");
462 CIO_TRACE_EVENT (2, sch->dev.bus_id); 462 CIO_TRACE_EVENT (2, sch->dev.bus_id);
463 463
464 ccode = stsch (sch->irq, &sch->schib); 464 ccode = stsch (sch->schid, &sch->schib);
465 if (ccode == 3) /* Not operational. */ 465 if (ccode == 3) /* Not operational. */
466 return -ENODEV; 466 return -ENODEV;
467 467
@@ -485,7 +485,7 @@ cio_disable_subchannel (struct subchannel *sch)
485 */ 485 */
486 break; 486 break;
487 if (ret == 0) { 487 if (ret == 0) {
488 stsch (sch->irq, &sch->schib); 488 stsch (sch->schid, &sch->schib);
489 if (!sch->schib.pmcw.ena) 489 if (!sch->schib.pmcw.ena)
490 break; 490 break;
491 } 491 }
@@ -508,12 +508,12 @@ cio_disable_subchannel (struct subchannel *sch)
508 * -ENODEV for subchannels with invalid device number or blacklisted devices 508 * -ENODEV for subchannels with invalid device number or blacklisted devices
509 */ 509 */
510int 510int
511cio_validate_subchannel (struct subchannel *sch, unsigned int irq) 511cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
512{ 512{
513 char dbf_txt[15]; 513 char dbf_txt[15];
514 int ccode; 514 int ccode;
515 515
516 sprintf (dbf_txt, "valsch%x", irq); 516 sprintf (dbf_txt, "valsch%x", schid.sch_no);
517 CIO_TRACE_EVENT (4, dbf_txt); 517 CIO_TRACE_EVENT (4, dbf_txt);
518 518
519 /* Nuke all fields. */ 519 /* Nuke all fields. */
@@ -522,17 +522,17 @@ cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
522 spin_lock_init(&sch->lock); 522 spin_lock_init(&sch->lock);
523 523
524 /* Set a name for the subchannel */ 524 /* Set a name for the subchannel */
525 snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.0.%04x", irq); 525 snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.0.%04x", schid.sch_no);
526 526
527 /* 527 /*
528 * The first subchannel that is not-operational (ccode==3) 528 * The first subchannel that is not-operational (ccode==3)
529 * indicates that there aren't any more devices available. 529 * indicates that there aren't any more devices available.
530 */ 530 */
531 sch->irq = irq; 531 ccode = stsch (schid, &sch->schib);
532 ccode = stsch (irq, &sch->schib);
533 if (ccode) 532 if (ccode)
534 return -ENXIO; 533 return -ENXIO;
535 534
535 sch->schid = schid;
536 /* Copy subchannel type from path management control word. */ 536 /* Copy subchannel type from path management control word. */
537 sch->st = sch->schib.pmcw.st; 537 sch->st = sch->schib.pmcw.st;
538 538
@@ -543,7 +543,7 @@ cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
543 CIO_DEBUG(KERN_INFO, 0, 543 CIO_DEBUG(KERN_INFO, 0,
544 "Subchannel %04X reports " 544 "Subchannel %04X reports "
545 "non-I/O subchannel type %04X\n", 545 "non-I/O subchannel type %04X\n",
546 sch->irq, sch->st); 546 sch->schid.sch_no, sch->st);
547 /* We stop here for non-io subchannels. */ 547 /* We stop here for non-io subchannels. */
548 return sch->st; 548 return sch->st;
549 } 549 }
@@ -573,7 +573,7 @@ cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
573 CIO_DEBUG(KERN_INFO, 0, 573 CIO_DEBUG(KERN_INFO, 0,
574 "Detected device %04X on subchannel %04X" 574 "Detected device %04X on subchannel %04X"
575 " - PIM = %02X, PAM = %02X, POM = %02X\n", 575 " - PIM = %02X, PAM = %02X, POM = %02X\n",
576 sch->schib.pmcw.dev, sch->irq, sch->schib.pmcw.pim, 576 sch->schib.pmcw.dev, sch->schid.sch_no, sch->schib.pmcw.pim,
577 sch->schib.pmcw.pam, sch->schib.pmcw.pom); 577 sch->schib.pmcw.pam, sch->schib.pmcw.pom);
578 578
579 /* 579 /*
@@ -632,7 +632,7 @@ do_IRQ (struct pt_regs *regs)
632 if (sch) 632 if (sch)
633 spin_lock(&sch->lock); 633 spin_lock(&sch->lock);
634 /* Store interrupt response block to lowcore. */ 634 /* Store interrupt response block to lowcore. */
635 if (tsch (tpi_info->irq, irb) == 0 && sch) { 635 if (tsch (tpi_info->schid, irb) == 0 && sch) {
636 /* Keep subchannel information word up to date. */ 636 /* Keep subchannel information word up to date. */
637 memcpy (&sch->schib.scsw, &irb->scsw, 637 memcpy (&sch->schib.scsw, &irb->scsw,
638 sizeof (irb->scsw)); 638 sizeof (irb->scsw));
@@ -693,26 +693,28 @@ wait_cons_dev (void)
693static int 693static int
694cio_console_irq(void) 694cio_console_irq(void)
695{ 695{
696 int irq; 696 struct subchannel_id schid;
697 697
698 init_subchannel_id(&schid);
698 if (console_irq != -1) { 699 if (console_irq != -1) {
699 /* VM provided us with the irq number of the console. */ 700 /* VM provided us with the irq number of the console. */
700 if (stsch(console_irq, &console_subchannel.schib) != 0 || 701 schid.sch_no = console_irq;
702 if (stsch(schid, &console_subchannel.schib) != 0 ||
701 !console_subchannel.schib.pmcw.dnv) 703 !console_subchannel.schib.pmcw.dnv)
702 return -1; 704 return -1;
703 console_devno = console_subchannel.schib.pmcw.dev; 705 console_devno = console_subchannel.schib.pmcw.dev;
704 } else if (console_devno != -1) { 706 } else if (console_devno != -1) {
705 /* At least the console device number is known. */ 707 /* At least the console device number is known. */
706 for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) { 708 do {
707 if (stsch(irq, &console_subchannel.schib) != 0) 709 if (stsch(schid, &console_subchannel.schib) != 0)
708 break; 710 break;
709 if (console_subchannel.schib.pmcw.dnv && 711 if (console_subchannel.schib.pmcw.dnv &&
710 console_subchannel.schib.pmcw.dev == 712 console_subchannel.schib.pmcw.dev ==
711 console_devno) { 713 console_devno) {
712 console_irq = irq; 714 console_irq = schid.sch_no;
713 break; 715 break;
714 } 716 }
715 } 717 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
716 if (console_irq == -1) 718 if (console_irq == -1)
717 return -1; 719 return -1;
718 } else { 720 } else {
@@ -729,6 +731,7 @@ struct subchannel *
729cio_probe_console(void) 731cio_probe_console(void)
730{ 732{
731 int irq, ret; 733 int irq, ret;
734 struct subchannel_id schid;
732 735
733 if (xchg(&console_subchannel_in_use, 1) != 0) 736 if (xchg(&console_subchannel_in_use, 1) != 0)
734 return ERR_PTR(-EBUSY); 737 return ERR_PTR(-EBUSY);
@@ -738,7 +741,9 @@ cio_probe_console(void)
738 return ERR_PTR(-ENODEV); 741 return ERR_PTR(-ENODEV);
739 } 742 }
740 memset(&console_subchannel, 0, sizeof(struct subchannel)); 743 memset(&console_subchannel, 0, sizeof(struct subchannel));
741 ret = cio_validate_subchannel(&console_subchannel, irq); 744 init_subchannel_id(&schid);
745 schid.sch_no = irq;
746 ret = cio_validate_subchannel(&console_subchannel, schid);
742 if (ret) { 747 if (ret) {
743 console_subchannel_in_use = 0; 748 console_subchannel_in_use = 0;
744 return ERR_PTR(-ENODEV); 749 return ERR_PTR(-ENODEV);
@@ -770,11 +775,11 @@ cio_release_console(void)
770 775
771/* Bah... hack to catch console special sausages. */ 776/* Bah... hack to catch console special sausages. */
772int 777int
773cio_is_console(int irq) 778cio_is_console(struct subchannel_id schid)
774{ 779{
775 if (!console_subchannel_in_use) 780 if (!console_subchannel_in_use)
776 return 0; 781 return 0;
777 return (irq == console_subchannel.irq); 782 return schid_equal(&schid, &console_subchannel.schid);
778} 783}
779 784
780struct subchannel * 785struct subchannel *
@@ -787,7 +792,7 @@ cio_get_console_subchannel(void)
787 792
788#endif 793#endif
789static inline int 794static inline int
790__disable_subchannel_easy(unsigned int schid, struct schib *schib) 795__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
791{ 796{
792 int retry, cc; 797 int retry, cc;
793 798
@@ -805,7 +810,7 @@ __disable_subchannel_easy(unsigned int schid, struct schib *schib)
805} 810}
806 811
807static inline int 812static inline int
808__clear_subchannel_easy(unsigned int schid) 813__clear_subchannel_easy(struct subchannel_id schid)
809{ 814{
810 int retry; 815 int retry;
811 816
@@ -815,8 +820,8 @@ __clear_subchannel_easy(unsigned int schid)
815 struct tpi_info ti; 820 struct tpi_info ti;
816 821
817 if (tpi(&ti)) { 822 if (tpi(&ti)) {
818 tsch(ti.irq, (struct irb *)__LC_IRB); 823 tsch(ti.schid, (struct irb *)__LC_IRB);
819 if (ti.irq == schid) 824 if (schid_equal(&ti.schid, &schid))
820 return 0; 825 return 0;
821 } 826 }
822 udelay(100); 827 udelay(100);
@@ -830,10 +835,11 @@ extern void do_reipl(unsigned long devno);
830void 835void
831clear_all_subchannels(void) 836clear_all_subchannels(void)
832{ 837{
833 unsigned int schid; 838 struct subchannel_id schid;
834 839
835 local_irq_disable(); 840 local_irq_disable();
836 for (schid=0;schid<=highest_subchannel;schid++) { 841 init_subchannel_id(&schid);
842 do {
837 struct schib schib; 843 struct schib schib;
838 if (stsch(schid, &schib)) 844 if (stsch(schid, &schib))
839 break; /* break out of the loop */ 845 break; /* break out of the loop */
@@ -849,7 +855,7 @@ clear_all_subchannels(void)
849 stsch(schid, &schib); 855 stsch(schid, &schib);
850 __disable_subchannel_easy(schid, &schib); 856 __disable_subchannel_easy(schid, &schib);
851 } 857 }
852 } 858 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
853} 859}
854 860
855/* Make sure all subchannels are quiet before we re-ipl an lpar. */ 861/* Make sure all subchannels are quiet before we re-ipl an lpar. */