diff options
| author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2008-07-14 03:58:43 -0400 |
|---|---|---|
| committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-07-14 04:02:05 -0400 |
| commit | 0ae7a7b250bdf7ee87c8346164ef3c47fb79dfbd (patch) | |
| tree | 95da6f03f135cf1a754eba262117a2ae8fd072a5 | |
| parent | b4a33acb690525c5ca37e177f5cd26c62d3ef976 (diff) | |
[S390] cio: Register all subchannels.
Register all valid subchannels, not only I/O subchannels.
Move I/O subchannel specific initialization to io_subchannel_probe().
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
| -rw-r--r-- | drivers/s390/cio/chp.h | 1 | ||||
| -rw-r--r-- | drivers/s390/cio/cio.c | 126 | ||||
| -rw-r--r-- | drivers/s390/cio/css.c | 19 | ||||
| -rw-r--r-- | drivers/s390/cio/css.h | 2 | ||||
| -rw-r--r-- | drivers/s390/cio/device.c | 38 |
5 files changed, 85 insertions, 101 deletions
diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h index 65286563c592..59c2fc069d9e 100644 --- a/drivers/s390/cio/chp.h +++ b/drivers/s390/cio/chp.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| 13 | #include <asm/chpid.h> | 13 | #include <asm/chpid.h> |
| 14 | #include "chsc.h" | 14 | #include "chsc.h" |
| 15 | #include "css.h" | ||
| 15 | 16 | ||
| 16 | #define CHP_STATUS_STANDBY 0 | 17 | #define CHP_STATUS_STANDBY 0 |
| 17 | #define CHP_STATUS_CONFIGURED 1 | 18 | #define CHP_STATUS_CONFIGURED 1 |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 7b5969ed05cd..903e23ae8ed5 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
| @@ -2,7 +2,7 @@ | |||
| 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) | |||
| 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) | |||
| 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) | |||
| 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) | |||
| 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) | |||
