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.c168
1 files changed, 94 insertions, 74 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 185bc73c3ecd..7376bc87206d 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/cio/cio.c 2 * drivers/s390/cio/cio.c
3 * S/390 common I/O routines -- low level i/o calls 3 * S/390 common I/O routines -- low level i/o calls
4 * $Revision: 1.135 $ 4 * $Revision: 1.138 $
5 * 5 *
6 * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, 6 * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
7 * IBM Corporation 7 * IBM Corporation
@@ -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,11 @@ 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 0.%x.%04x!\n", sch->schid.ssid,
170 sch->schid.sch_no);
170 sprintf(dbf_text, "no%s", sch->dev.bus_id); 171 sprintf(dbf_text, "no%s", sch->dev.bus_id);
171 CIO_TRACE_EVENT(0, dbf_text); 172 CIO_TRACE_EVENT(0, dbf_text);
172 CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib)); 173 CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib));
@@ -194,7 +195,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
194 sch->orb.spnd = sch->options.suspend; 195 sch->orb.spnd = sch->options.suspend;
195 sch->orb.ssic = sch->options.suspend && sch->options.inter; 196 sch->orb.ssic = sch->options.suspend && sch->options.inter;
196 sch->orb.lpm = (lpm != 0) ? (lpm & sch->opm) : sch->lpm; 197 sch->orb.lpm = (lpm != 0) ? (lpm & sch->opm) : sch->lpm;
197#ifdef CONFIG_ARCH_S390X 198#ifdef CONFIG_64BIT
198 /* 199 /*
199 * for 64 bit we always support 64 bit IDAWs with 4k page size only 200 * for 64 bit we always support 64 bit IDAWs with 4k page size only
200 */ 201 */
@@ -204,7 +205,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
204 sch->orb.key = key >> 4; 205 sch->orb.key = key >> 4;
205 /* issue "Start Subchannel" */ 206 /* issue "Start Subchannel" */
206 sch->orb.cpa = (__u32) __pa (cpa); 207 sch->orb.cpa = (__u32) __pa (cpa);
207 ccode = ssch (sch->irq, &sch->orb); 208 ccode = ssch (sch->schid, &sch->orb);
208 209
209 /* process condition code */ 210 /* process condition code */
210 sprintf (dbf_txt, "ccode:%d", ccode); 211 sprintf (dbf_txt, "ccode:%d", ccode);
@@ -243,7 +244,7 @@ cio_resume (struct subchannel *sch)
243 CIO_TRACE_EVENT (4, "resIO"); 244 CIO_TRACE_EVENT (4, "resIO");
244 CIO_TRACE_EVENT (4, sch->dev.bus_id); 245 CIO_TRACE_EVENT (4, sch->dev.bus_id);
245 246
246 ccode = rsch (sch->irq); 247 ccode = rsch (sch->schid);
247 248
248 sprintf (dbf_txt, "ccode:%d", ccode); 249 sprintf (dbf_txt, "ccode:%d", ccode);
249 CIO_TRACE_EVENT (4, dbf_txt); 250 CIO_TRACE_EVENT (4, dbf_txt);
@@ -283,7 +284,7 @@ cio_halt(struct subchannel *sch)
283 /* 284 /*
284 * Issue "Halt subchannel" and process condition code 285 * Issue "Halt subchannel" and process condition code
285 */ 286 */
286 ccode = hsch (sch->irq); 287 ccode = hsch (sch->schid);
287 288
288 sprintf (dbf_txt, "ccode:%d", ccode); 289 sprintf (dbf_txt, "ccode:%d", ccode);
289 CIO_TRACE_EVENT (2, dbf_txt); 290 CIO_TRACE_EVENT (2, dbf_txt);
@@ -318,7 +319,7 @@ cio_clear(struct subchannel *sch)
318 /* 319 /*
319 * Issue "Clear subchannel" and process condition code 320 * Issue "Clear subchannel" and process condition code
320 */ 321 */
321 ccode = csch (sch->irq); 322 ccode = csch (sch->schid);
322 323
323 sprintf (dbf_txt, "ccode:%d", ccode); 324 sprintf (dbf_txt, "ccode:%d", ccode);
324 CIO_TRACE_EVENT (2, dbf_txt); 325 CIO_TRACE_EVENT (2, dbf_txt);
@@ -351,7 +352,7 @@ cio_cancel (struct subchannel *sch)
351 CIO_TRACE_EVENT (2, "cancelIO"); 352 CIO_TRACE_EVENT (2, "cancelIO");
352 CIO_TRACE_EVENT (2, sch->dev.bus_id); 353 CIO_TRACE_EVENT (2, sch->dev.bus_id);
353 354
354 ccode = xsch (sch->irq); 355 ccode = xsch (sch->schid);
355 356
356 sprintf (dbf_txt, "ccode:%d", ccode); 357 sprintf (dbf_txt, "ccode:%d", ccode);
357 CIO_TRACE_EVENT (2, dbf_txt); 358 CIO_TRACE_EVENT (2, dbf_txt);
@@ -359,7 +360,7 @@ cio_cancel (struct subchannel *sch)
359 switch (ccode) { 360 switch (ccode) {
360 case 0: /* success */ 361 case 0: /* success */
361 /* Update information in scsw. */ 362 /* Update information in scsw. */
362 stsch (sch->irq, &sch->schib); 363 stsch (sch->schid, &sch->schib);
363 return 0; 364 return 0;
364 case 1: /* status pending */ 365 case 1: /* status pending */
365 return -EBUSY; 366 return -EBUSY;
@@ -381,7 +382,7 @@ cio_modify (struct subchannel *sch)
381 382
382 ret = 0; 383 ret = 0;
383 for (retry = 0; retry < 5; retry++) { 384 for (retry = 0; retry < 5; retry++) {
384 ccode = msch_err (sch->irq, &sch->schib); 385 ccode = msch_err (sch->schid, &sch->schib);
385 if (ccode < 0) /* -EIO if msch gets a program check. */ 386 if (ccode < 0) /* -EIO if msch gets a program check. */
386 return ccode; 387 return ccode;
387 switch (ccode) { 388 switch (ccode) {
@@ -414,7 +415,7 @@ cio_enable_subchannel (struct subchannel *sch, unsigned int isc)
414 CIO_TRACE_EVENT (2, "ensch"); 415 CIO_TRACE_EVENT (2, "ensch");
415 CIO_TRACE_EVENT (2, sch->dev.bus_id); 416 CIO_TRACE_EVENT (2, sch->dev.bus_id);
416 417
417 ccode = stsch (sch->irq, &sch->schib); 418 ccode = stsch (sch->schid, &sch->schib);
418 if (ccode) 419 if (ccode)
419 return -ENODEV; 420 return -ENODEV;
420 421
@@ -432,13 +433,13 @@ cio_enable_subchannel (struct subchannel *sch, unsigned int isc)
432 */ 433 */
433 sch->schib.pmcw.csense = 0; 434 sch->schib.pmcw.csense = 0;
434 if (ret == 0) { 435 if (ret == 0) {
435 stsch (sch->irq, &sch->schib); 436 stsch (sch->schid, &sch->schib);
436 if (sch->schib.pmcw.ena) 437 if (sch->schib.pmcw.ena)
437 break; 438 break;
438 } 439 }
439 if (ret == -EBUSY) { 440 if (ret == -EBUSY) {
440 struct irb irb; 441 struct irb irb;
441 if (tsch(sch->irq, &irb) != 0) 442 if (tsch(sch->schid, &irb) != 0)
442 break; 443 break;
443 } 444 }
444 } 445 }
@@ -461,7 +462,7 @@ cio_disable_subchannel (struct subchannel *sch)
461 CIO_TRACE_EVENT (2, "dissch"); 462 CIO_TRACE_EVENT (2, "dissch");
462 CIO_TRACE_EVENT (2, sch->dev.bus_id); 463 CIO_TRACE_EVENT (2, sch->dev.bus_id);
463 464
464 ccode = stsch (sch->irq, &sch->schib); 465 ccode = stsch (sch->schid, &sch->schib);
465 if (ccode == 3) /* Not operational. */ 466 if (ccode == 3) /* Not operational. */
466 return -ENODEV; 467 return -ENODEV;
467 468
@@ -485,7 +486,7 @@ cio_disable_subchannel (struct subchannel *sch)
485 */ 486 */
486 break; 487 break;
487 if (ret == 0) { 488 if (ret == 0) {
488 stsch (sch->irq, &sch->schib); 489 stsch (sch->schid, &sch->schib);
489 if (!sch->schib.pmcw.ena) 490 if (!sch->schib.pmcw.ena)
490 break; 491 break;
491 } 492 }
@@ -508,12 +509,12 @@ cio_disable_subchannel (struct subchannel *sch)
508 * -ENODEV for subchannels with invalid device number or blacklisted devices 509 * -ENODEV for subchannels with invalid device number or blacklisted devices
509 */ 510 */
510int 511int
511cio_validate_subchannel (struct subchannel *sch, unsigned int irq) 512cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
512{ 513{
513 char dbf_txt[15]; 514 char dbf_txt[15];
514 int ccode; 515 int ccode;
515 516
516 sprintf (dbf_txt, "valsch%x", irq); 517 sprintf (dbf_txt, "valsch%x", schid.sch_no);
517 CIO_TRACE_EVENT (4, dbf_txt); 518 CIO_TRACE_EVENT (4, dbf_txt);
518 519
519 /* Nuke all fields. */ 520 /* Nuke all fields. */
@@ -522,17 +523,20 @@ cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
522 spin_lock_init(&sch->lock); 523 spin_lock_init(&sch->lock);
523 524
524 /* Set a name for the subchannel */ 525 /* Set a name for the subchannel */
525 snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.0.%04x", irq); 526 snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", schid.ssid,
527 schid.sch_no);
526 528
527 /* 529 /*
528 * The first subchannel that is not-operational (ccode==3) 530 * The first subchannel that is not-operational (ccode==3)
529 * indicates that there aren't any more devices available. 531 * indicates that there aren't any more devices available.
532 * If stsch gets an exception, it means the current subchannel set
533 * is not valid.
530 */ 534 */
531 sch->irq = irq; 535 ccode = stsch_err (schid, &sch->schib);
532 ccode = stsch (irq, &sch->schib);
533 if (ccode) 536 if (ccode)
534 return -ENXIO; 537 return (ccode == 3) ? -ENXIO : ccode;
535 538
539 sch->schid = schid;
536 /* Copy subchannel type from path management control word. */ 540 /* Copy subchannel type from path management control word. */
537 sch->st = sch->schib.pmcw.st; 541 sch->st = sch->schib.pmcw.st;
538 542
@@ -541,9 +545,9 @@ cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
541 */ 545 */
542 if (sch->st != 0) { 546 if (sch->st != 0) {
543 CIO_DEBUG(KERN_INFO, 0, 547 CIO_DEBUG(KERN_INFO, 0,
544 "Subchannel %04X reports " 548 "Subchannel 0.%x.%04x reports "
545 "non-I/O subchannel type %04X\n", 549 "non-I/O subchannel type %04X\n",
546 sch->irq, sch->st); 550 sch->schid.ssid, sch->schid.sch_no, sch->st);
547 /* We stop here for non-io subchannels. */ 551 /* We stop here for non-io subchannels. */
548 return sch->st; 552 return sch->st;
549 } 553 }
@@ -554,26 +558,29 @@ cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
554 return -ENODEV; 558 return -ENODEV;
555 559
556 /* Devno is valid. */ 560 /* Devno is valid. */
557 if (is_blacklisted (sch->schib.pmcw.dev)) { 561 if (is_blacklisted (sch->schid.ssid, sch->schib.pmcw.dev)) {
558 /* 562 /*
559 * This device must not be known to Linux. So we simply 563 * This device must not be known to Linux. So we simply
560 * say that there is no device and return ENODEV. 564 * say that there is no device and return ENODEV.
561 */ 565 */
562 CIO_MSG_EVENT(0, "Blacklisted device detected " 566 CIO_MSG_EVENT(0, "Blacklisted device detected "
563 "at devno %04X\n", sch->schib.pmcw.dev); 567 "at devno %04X, subchannel set %x\n",
568 sch->schib.pmcw.dev, sch->schid.ssid);
564 return -ENODEV; 569 return -ENODEV;
565 } 570 }
566 sch->opm = 0xff; 571 sch->opm = 0xff;
567 chsc_validate_chpids(sch); 572 if (!cio_is_console(sch->schid))
573 chsc_validate_chpids(sch);
568 sch->lpm = sch->schib.pmcw.pim & 574 sch->lpm = sch->schib.pmcw.pim &
569 sch->schib.pmcw.pam & 575 sch->schib.pmcw.pam &
570 sch->schib.pmcw.pom & 576 sch->schib.pmcw.pom &
571 sch->opm; 577 sch->opm;
572 578
573 CIO_DEBUG(KERN_INFO, 0, 579 CIO_DEBUG(KERN_INFO, 0,
574 "Detected device %04X on subchannel %04X" 580 "Detected device %04x on subchannel 0.%x.%04X"
575 " - PIM = %02X, PAM = %02X, POM = %02X\n", 581 " - PIM = %02X, PAM = %02X, POM = %02X\n",
576 sch->schib.pmcw.dev, sch->irq, sch->schib.pmcw.pim, 582 sch->schib.pmcw.dev, sch->schid.ssid,
583 sch->schid.sch_no, sch->schib.pmcw.pim,
577 sch->schib.pmcw.pam, sch->schib.pmcw.pom); 584 sch->schib.pmcw.pam, sch->schib.pmcw.pom);
578 585
579 /* 586 /*
@@ -632,7 +639,7 @@ do_IRQ (struct pt_regs *regs)
632 if (sch) 639 if (sch)
633 spin_lock(&sch->lock); 640 spin_lock(&sch->lock);
634 /* Store interrupt response block to lowcore. */ 641 /* Store interrupt response block to lowcore. */
635 if (tsch (tpi_info->irq, irb) == 0 && sch) { 642 if (tsch (tpi_info->schid, irb) == 0 && sch) {
636 /* Keep subchannel information word up to date. */ 643 /* Keep subchannel information word up to date. */
637 memcpy (&sch->schib.scsw, &irb->scsw, 644 memcpy (&sch->schib.scsw, &irb->scsw,
638 sizeof (irb->scsw)); 645 sizeof (irb->scsw));
@@ -691,28 +698,36 @@ wait_cons_dev (void)
691} 698}
692 699
693static int 700static int
694cio_console_irq(void) 701cio_test_for_console(struct subchannel_id schid, void *data)
695{ 702{
696 int irq; 703 if (stsch_err(schid, &console_subchannel.schib) != 0)
704 return -ENXIO;
705 if (console_subchannel.schib.pmcw.dnv &&
706 console_subchannel.schib.pmcw.dev ==
707 console_devno) {
708 console_irq = schid.sch_no;
709 return 1; /* found */
710 }
711 return 0;
712}
713
714
715static int
716cio_get_console_sch_no(void)
717{
718 struct subchannel_id schid;
697 719
720 init_subchannel_id(&schid);
698 if (console_irq != -1) { 721 if (console_irq != -1) {
699 /* VM provided us with the irq number of the console. */ 722 /* VM provided us with the irq number of the console. */
700 if (stsch(console_irq, &console_subchannel.schib) != 0 || 723 schid.sch_no = console_irq;
724 if (stsch(schid, &console_subchannel.schib) != 0 ||
701 !console_subchannel.schib.pmcw.dnv) 725 !console_subchannel.schib.pmcw.dnv)
702 return -1; 726 return -1;
703 console_devno = console_subchannel.schib.pmcw.dev; 727 console_devno = console_subchannel.schib.pmcw.dev;
704 } else if (console_devno != -1) { 728 } else if (console_devno != -1) {
705 /* At least the console device number is known. */ 729 /* At least the console device number is known. */
706 for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) { 730 for_each_subchannel(cio_test_for_console, NULL);
707 if (stsch(irq, &console_subchannel.schib) != 0)
708 break;
709 if (console_subchannel.schib.pmcw.dnv &&
710 console_subchannel.schib.pmcw.dev ==
711 console_devno) {
712 console_irq = irq;
713 break;
714 }
715 }
716 if (console_irq == -1) 731 if (console_irq == -1)
717 return -1; 732 return -1;
718 } else { 733 } else {
@@ -728,17 +743,20 @@ cio_console_irq(void)
728struct subchannel * 743struct subchannel *
729cio_probe_console(void) 744cio_probe_console(void)
730{ 745{
731 int irq, ret; 746 int sch_no, ret;
747 struct subchannel_id schid;
732 748
733 if (xchg(&console_subchannel_in_use, 1) != 0) 749 if (xchg(&console_subchannel_in_use, 1) != 0)
734 return ERR_PTR(-EBUSY); 750 return ERR_PTR(-EBUSY);
735 irq = cio_console_irq(); 751 sch_no = cio_get_console_sch_no();
736 if (irq == -1) { 752 if (sch_no == -1) {
737 console_subchannel_in_use = 0; 753 console_subchannel_in_use = 0;
738 return ERR_PTR(-ENODEV); 754 return ERR_PTR(-ENODEV);
739 } 755 }
740 memset(&console_subchannel, 0, sizeof(struct subchannel)); 756 memset(&console_subchannel, 0, sizeof(struct subchannel));
741 ret = cio_validate_subchannel(&console_subchannel, irq); 757 init_subchannel_id(&schid);
758 schid.sch_no = sch_no;
759 ret = cio_validate_subchannel(&console_subchannel, schid);
742 if (ret) { 760 if (ret) {
743 console_subchannel_in_use = 0; 761 console_subchannel_in_use = 0;
744 return ERR_PTR(-ENODEV); 762 return ERR_PTR(-ENODEV);
@@ -770,11 +788,11 @@ cio_release_console(void)
770 788
771/* Bah... hack to catch console special sausages. */ 789/* Bah... hack to catch console special sausages. */
772int 790int
773cio_is_console(int irq) 791cio_is_console(struct subchannel_id schid)
774{ 792{
775 if (!console_subchannel_in_use) 793 if (!console_subchannel_in_use)
776 return 0; 794 return 0;
777 return (irq == console_subchannel.irq); 795 return schid_equal(&schid, &console_subchannel.schid);
778} 796}
779 797
780struct subchannel * 798struct subchannel *
@@ -787,7 +805,7 @@ cio_get_console_subchannel(void)
787 805
788#endif 806#endif
789static inline int 807static inline int
790__disable_subchannel_easy(unsigned int schid, struct schib *schib) 808__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
791{ 809{
792 int retry, cc; 810 int retry, cc;
793 811
@@ -805,7 +823,7 @@ __disable_subchannel_easy(unsigned int schid, struct schib *schib)
805} 823}
806 824
807static inline int 825static inline int
808__clear_subchannel_easy(unsigned int schid) 826__clear_subchannel_easy(struct subchannel_id schid)
809{ 827{
810 int retry; 828 int retry;
811 829
@@ -815,8 +833,8 @@ __clear_subchannel_easy(unsigned int schid)
815 struct tpi_info ti; 833 struct tpi_info ti;
816 834
817 if (tpi(&ti)) { 835 if (tpi(&ti)) {
818 tsch(ti.irq, (struct irb *)__LC_IRB); 836 tsch(ti.schid, (struct irb *)__LC_IRB);
819 if (ti.irq == schid) 837 if (schid_equal(&ti.schid, &schid))
820 return 0; 838 return 0;
821 } 839 }
822 udelay(100); 840 udelay(100);
@@ -825,31 +843,33 @@ __clear_subchannel_easy(unsigned int schid)
825} 843}
826 844
827extern void do_reipl(unsigned long devno); 845extern void do_reipl(unsigned long devno);
846static int
847__shutdown_subchannel_easy(struct subchannel_id schid, void *data)
848{
849 struct schib schib;
850
851 if (stsch_err(schid, &schib))
852 return -ENXIO;
853 if (!schib.pmcw.ena)
854 return 0;
855 switch(__disable_subchannel_easy(schid, &schib)) {
856 case 0:
857 case -ENODEV:
858 break;
859 default: /* -EBUSY */
860 if (__clear_subchannel_easy(schid))
861 break; /* give up... */
862 stsch(schid, &schib);
863 __disable_subchannel_easy(schid, &schib);
864 }
865 return 0;
866}
828 867
829/* Clear all subchannels. */
830void 868void
831clear_all_subchannels(void) 869clear_all_subchannels(void)
832{ 870{
833 unsigned int schid;
834
835 local_irq_disable(); 871 local_irq_disable();
836 for (schid=0;schid<=highest_subchannel;schid++) { 872 for_each_subchannel(__shutdown_subchannel_easy, NULL);
837 struct schib schib;
838 if (stsch(schid, &schib))
839 break; /* break out of the loop */
840 if (!schib.pmcw.ena)
841 continue;
842 switch(__disable_subchannel_easy(schid, &schib)) {
843 case 0:
844 case -ENODEV:
845 break;
846 default: /* -EBUSY */
847 if (__clear_subchannel_easy(schid))
848 break; /* give up... jump out of switch */
849 stsch(schid, &schib);
850 __disable_subchannel_easy(schid, &schib);
851 }
852 }
853} 873}
854 874
855/* Make sure all subchannels are quiet before we re-ipl an lpar. */ 875/* Make sure all subchannels are quiet before we re-ipl an lpar. */