| @@ -2,7 +2,7 @@ · 1 unmodified line |
| 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 | * | 4 | * |
| 5 | * Copyright (C) IBM Corp. 1999,2006 | 5 | * Copyright IBM Corp. 1999,2008 |
| 6 | * Author(s): Ingo Adlung (adlung@de.ibm.com) | 6 | * Author(s): Ingo Adlung (adlung@de.ibm.com) |
| 7 | * Cornelia Huck (cornelia.huck@de.ibm.com) | 7 | * Cornelia Huck (cornelia.huck@de.ibm.com) |
| 8 | * Arnd Bergmann (arndb@de.ibm.com) | 8 | * Arnd Bergmann (arndb@de.ibm.com) |
| @@ -494,27 +494,46 @@ int cio_create_sch_lock(struct subchannel *sch) · 485 unmodified lines |
| 494 | return 0; | 494 | return 0; |
| 495 | } | 495 | } |
| 496 | | 496 | |
| 497 | /* | 497 | static int cio_validate_io_subchannel(struct subchannel *sch) |
| 498 | * cio_validate_subchannel() | 498 | { |
| | 499 | /* Initialization for io subchannels. */ |
| | 500 | if (!css_sch_is_valid(&sch->schib)) |
| | 501 | return -ENODEV; |
| | 502 | |
| | 503 | /* Devno is valid. */ |
| | 504 | if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) { |
| | 505 | /* |
| | 506 | * This device must not be known to Linux. So we simply |
| | 507 | * say that there is no device and return ENODEV. |
| | 508 | */ |
| | 509 | CIO_MSG_EVENT(6, "Blacklisted device detected " |
| | 510 | "at devno %04X, subchannel set %x\n", |
| | 511 | sch->schib.pmcw.dev, sch->schid.ssid); |
| | 512 | return -ENODEV; |
| | 513 | } |
| | 514 | return 0; |
| | 515 | } |
| | 516 | |
| | 517 | /** |
| | 518 | * cio_validate_subchannel - basic validation of subchannel |
| | 519 | * @sch: subchannel structure to be filled out |
| | 520 | * @schid: subchannel id |
| 499 | * | 521 | * |
| 500 | * Find out subchannel type and initialize struct subchannel. | 522 | * Find out subchannel type and initialize struct subchannel. |
| 501 | * Return codes: | 523 | * Return codes: |
| 502 | * SUBCHANNEL_TYPE_IO for a normal io subchannel | 524 | * 0 on success |
| 503 | * SUBCHANNEL_TYPE_CHSC for a chsc subchannel | | |
| 504 | * SUBCHANNEL_TYPE_MESSAGE for a messaging subchannel | | |
| 505 | * SUBCHANNEL_TYPE_ADM for a adm(?) subchannel | | |
| 506 | * -ENXIO for non-defined subchannels | 525 | * -ENXIO for non-defined subchannels |
| 507 | * -ENODEV for subchannels with invalid device number or blacklisted devices | 526 | * -ENODEV for invalid subchannels or blacklisted devices |
| | 527 | * -EIO for subchannels in an invalid subchannel set |
| 508 | */ | 528 | */ |
| 509 | int | 529 | int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) |
| 510 | cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | | |
| 511 | { | 530 | { |
| 512 | char dbf_txt[15]; | 531 | char dbf_txt[15]; |
| 513 | int ccode; | 532 | int ccode; |
| 514 | int err; | 533 | int err; |
| 515 | | 534 | |
| 516 | sprintf (dbf_txt, "valsch%x", schid.sch_no); | 535 | sprintf(dbf_txt, "valsch%x", schid.sch_no); |
| 517 | CIO_TRACE_EVENT (4, dbf_txt); | 536 | CIO_TRACE_EVENT(4, dbf_txt); |
| 518 | | 537 | |
| 519 | /* Nuke all fields. */ | 538 | /* Nuke all fields. */ |
| 520 | memset(sch, 0, sizeof(struct subchannel)); | 539 | memset(sch, 0, sizeof(struct subchannel)); |
| @@ -545,68 +564,18 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) · 24 unmodified lines |
| 545 | } | 564 | } |
| 546 | /* Copy subchannel type from path management control word. */ | 565 | /* Copy subchannel type from path management control word. */ |
| 547 | sch->st = sch->schib.pmcw.st; | 566 | sch->st = sch->schib.pmcw.st; |
| 548 | | 567 | switch (sch->st) { |
| 549 | /* | 568 | case SUBCHANNEL_TYPE_IO: |
| 550 | * ... just being curious we check for non I/O subchannels | 569 | err = cio_validate_io_subchannel(sch); |
| 551 | */ | 570 | break; |
| 552 | if (sch->st != 0) { | 571 | default: |
| 553 | CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports " | 572 | err = 0; |
| 554 | "non-I/O subchannel type %04X\n", | | |
| 555 | sch->schid.ssid, sch->schid.sch_no, sch->st); | | |
| 556 | /* We stop here for non-io subchannels. */ | | |
| 557 | err = sch->st; | | |
| 558 | goto out; | | |
| 559 | } | 573 | } |
| 560 | | 574 | if (err) |
| 561 | /* Initialization for io subchannels. */ | | |
| 562 | if (!css_sch_is_valid(&sch->schib)) { | | |
| 563 | err = -ENODEV; | | |
| 564 | goto out; | 575 | goto out; |
| 565 | } | | |
| 566 | | 576 | |
| 567 | /* Devno is valid. */ | 577 | CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n", |
| 568 | if (is_blacklisted (sch->schid.ssid, sch->schib.pmcw.dev)) { | 578 | sch->schid.ssid, sch->schid.sch_no, sch->st); |
| 569 | /* | | |
| 570 | * This device must not be known to Linux. So we simply | | |
| 571 | * say that there is no device and return ENODEV. | | |
| 572 | */ | | |
| 573 | CIO_MSG_EVENT(6, "Blacklisted device detected " | | |
| 574 | "at devno %04X, subchannel set %x\n", | | |
| 575 | sch->schib.pmcw.dev, sch->schid.ssid); | | |
| 576 | err = -ENODEV; | | |
| 577 | goto out; | | |
| 578 | } | | |
| 579 | if (cio_is_console(sch->schid)) { | | |
| 580 | sch->opm = 0xff; | | |
| 581 | sch->isc = 1; | | |
| 582 | } else { | | |
| 583 | sch->opm = chp_get_sch_opm(sch); | | |
| 584 | sch->isc = 3; | | |
| 585 | } | | |
| 586 | sch->lpm = sch->schib.pmcw.pam & sch->opm; | | |
| 587 | | | |
| 588 | CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X " | | |
| 589 | "- PIM = %02X, PAM = %02X, POM = %02X\n", | | |
| 590 | sch->schib.pmcw.dev, sch->schid.ssid, | | |
| 591 | sch->schid.sch_no, sch->schib.pmcw.pim, | | |
| 592 | sch->schib.pmcw.pam, sch->schib.pmcw.pom); | | |
| 593 | | | |
| 594 | /* | | |
| 595 | * We now have to initially ... | | |
| 596 | * ... enable "concurrent sense" | | |
| 597 | * ... enable "multipath mode" if more than one | | |
| 598 | * CHPID is available. This is done regardless | | |
| 599 | * whether multiple paths are available for us. | | |
| 600 | */ | | |
| 601 | sch->schib.pmcw.csense = 1; /* concurrent sense */ | | |
| 602 | sch->schib.pmcw.ena = 0; | | |
| 603 | if ((sch->lpm & (sch->lpm - 1)) != 0) | | |
| 604 | sch->schib.pmcw.mp = 1; /* multipath mode */ | | |
| 605 | /* clean up possible residual cmf stuff */ | | |
| 606 | sch->schib.pmcw.mme = 0; | | |
| 607 | sch->schib.pmcw.mbfc = 0; | | |
| 608 | sch->schib.pmcw.mbi = 0; | | |
| 609 | sch->schib.mba = 0; | | |
| 610 | return 0; | 579 | return 0; |
| 611 | out: | 580 | out: |
| 612 | if (!cio_is_console(schid)) | 581 | if (!cio_is_console(schid)) |
| @@ -793,7 +762,6 @@ cio_probe_console(void) · 180 unmodified lines |
| 793 | * enable console I/O-interrupt subclass 1 | 762 | * enable console I/O-interrupt subclass 1 |
| 794 | */ | 763 | */ |
| 795 | ctl_set_bit(6, 30); | 764 | ctl_set_bit(6, 30); |
| 796 | console_subchannel.isc = 1; | | |
| 797 | console_subchannel.schib.pmcw.isc = 1; | 765 | console_subchannel.schib.pmcw.isc = 1; |
| 798 | console_subchannel.schib.pmcw.intparm = | 766 | console_subchannel.schib.pmcw.intparm = |
| 799 | (u32)(addr_t)&console_subchannel; | 767 | (u32)(addr_t)&console_subchannel; |
| @@ -864,7 +832,7 @@ static void udelay_reset(unsigned long usecs) · 64 unmodified lines |
| 864 | } | 832 | } |
| 865 | | 833 | |
| 866 | static int | 834 | static int |
| 867 | __clear_subchannel_easy(struct subchannel_id schid) | 835 | __clear_io_subchannel_easy(struct subchannel_id schid) |
| 868 | { | 836 | { |
| 869 | int retry; | 837 | int retry; |
| 870 | | 838 | |
| @@ -921,11 +889,19 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) · 50 unmodified lines |
| 921 | case -ENODEV: | 889 | case -ENODEV: |
| 922 | break; | 890 | break; |
| 923 | default: /* -EBUSY */ | 891 | default: /* -EBUSY */ |
| 924 | if (__clear_subchannel_easy(schid)) | 892 | switch (schib.pmcw.st) { |
| 925 | break; /* give up... */ | 893 | case SUBCHANNEL_TYPE_IO: |
| | 894 | if (__clear_io_subchannel_easy(schid)) |
| | 895 | goto out; /* give up... */ |
| | 896 | break; |
| | 897 | default: |
| | 898 | /* No default clear strategy */ |
| | 899 | break; |
| | 900 | } |
| 926 | stsch(schid, &schib); | 901 | stsch(schid, &schib); |
| 927 | __disable_subchannel_easy(schid, &schib); | 902 | __disable_subchannel_easy(schid, &schib); |
| 928 | } | 903 | } |
| | 904 | out: |
| 929 | return 0; | 905 | return 0; |
| 930 | } | 906 | } |
| 931 | | 907 | |