History

[S390] cio: Register all subchannels.

Register all valid subchannels, not only I/O subchannels. Move I/O subchannel specific initialization to io_subchannel_probe().

Cornelia Huck committed 18 years ago

Commit 0ae7a7b1 parent b4a33ac5 files · +85 −101Browse files

Unified · Split

5 files
  1. drivers/s390/cio/chp.h +1 −0
  2. drivers/s390/cio/cio.c +51 −75
  3. drivers/s390/cio/css.c +0 −19
  4. drivers/s390/cio/css.h +0 −2
  5. drivers/s390/cio/device.c +33 −5
drivers/s390/cio/chp.h+1−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <linux/device.h>
1313 #include <asm/chpid.h>
1414 #include "chsc.h"
15+#include "css.h"
1516
1617 #define CHP_STATUS_STANDBY 0
1718 #define CHP_STATUS_CONFIGURED 1
drivers/s390/cio/cio.c+51−75
@@ -2,7 +2,7 @@ · 1 unmodified line
22 * drivers/s390/cio/cio.c
33 * S/390 common I/O routines -- low level i/o calls
44 *
5− * Copyright (C) IBM Corp. 1999,2006
5+ * Copyright IBM Corp. 1999,2008
66 * Author(s): Ingo Adlung (adlung@de.ibm.com)
77 * Cornelia Huck (cornelia.huck@de.ibm.com)
88 * Arnd Bergmann (arndb@de.ibm.com)
@@ -494,27 +494,46 @@ int cio_create_sch_lock(struct subchannel *sch) · 485 unmodified lines
494494 return 0;
495495 }
496496
497−/*
498− * cio_validate_subchannel()
497+static int cio_validate_io_subchannel(struct subchannel *sch)
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
499521 *
500522 * Find out subchannel type and initialize struct subchannel.
501523 * Return codes:
502− * SUBCHANNEL_TYPE_IO for a normal io subchannel
503− * SUBCHANNEL_TYPE_CHSC for a chsc subchannel
504− * SUBCHANNEL_TYPE_MESSAGE for a messaging subchannel
505− * SUBCHANNEL_TYPE_ADM for a adm(?) subchannel
524+ * 0 on success
506525 * -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
508528 */
509−int
510−cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
529+int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
511530 {
512531 char dbf_txt[15];
513532 int ccode;
514533 int err;
515534
516− sprintf (dbf_txt, "valsch%x", schid.sch_no);
517− CIO_TRACE_EVENT (4, dbf_txt);
535+ sprintf(dbf_txt, "valsch%x", schid.sch_no);
536+ CIO_TRACE_EVENT(4, dbf_txt);
518537
519538 /* Nuke all fields. */
520539 memset(sch, 0, sizeof(struct subchannel));
@@ -545,68 +564,18 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) · 24 unmodified lines
545564 }
546565 /* Copy subchannel type from path management control word. */
547566 sch->st = sch->schib.pmcw.st;
548−
549− /*
550− * ... just being curious we check for non I/O subchannels
551− */
552− if (sch->st != 0) {
553− CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports "
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;
567+ switch (sch->st) {
568+ case SUBCHANNEL_TYPE_IO:
569+ err = cio_validate_io_subchannel(sch);
570+ break;
571+ default:
572+ err = 0;
559573 }
560−
561− /* Initialization for io subchannels. */
562− if (!css_sch_is_valid(&sch->schib)) {
563− err = -ENODEV;
574+ if (err)
564575 goto out;
565− }
566576
567− /* Devno is valid. */
568− if (is_blacklisted (sch->schid.ssid, sch->schib.pmcw.dev)) {
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;
577+ CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n",
578+ sch->schid.ssid, sch->schid.sch_no, sch->st);
610579 return 0;
611580 out:
612581 if (!cio_is_console(schid))
@@ -793,7 +762,6 @@ cio_probe_console(void) · 180 unmodified lines
793762 * enable console I/O-interrupt subclass 1
794763 */
795764 ctl_set_bit(6, 30);
796− console_subchannel.isc = 1;
797765 console_subchannel.schib.pmcw.isc = 1;
798766 console_subchannel.schib.pmcw.intparm =
799767 (u32)(addr_t)&console_subchannel;
@@ -864,7 +832,7 @@ static void udelay_reset(unsigned long usecs) · 64 unmodified lines
864832 }
865833
866834 static int
867−__clear_subchannel_easy(struct subchannel_id schid)
835+__clear_io_subchannel_easy(struct subchannel_id schid)
868836 {
869837 int retry;
870838
@@ -921,11 +889,19 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) · 50 unmodified lines
921889 case -ENODEV:
922890 break;
923891 default: /* -EBUSY */
924− if (__clear_subchannel_easy(schid))
925− break; /* give up... */
892+ switch (schib.pmcw.st) {
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+ }
926901 stsch(schid, &schib);
927902 __disable_subchannel_easy(schid, &schib);
928903 }
904+out:
929905 return 0;
930906 }
931907
drivers/s390/cio/css.c+0−19
@@ -121,25 +121,6 @@ css_alloc_subchannel(struct subchannel_id schid) · 120 unmodified lines
121121 kfree(sch);
122122 return ERR_PTR(ret);
123123 }
124−
125− if (sch->st != SUBCHANNEL_TYPE_IO) {
126− /* For now we ignore all non-io subchannels. */
127− kfree(sch);
128− return ERR_PTR(-EINVAL);
129− }
130−
131− /*
132− * Set intparm to subchannel address.
133− * This is fine even on 64bit since the subchannel is always located
134− * under 2G.
135− */
136− sch->schib.pmcw.intparm = (u32)(addr_t)sch;
137− ret = cio_modify(sch);
138− if (ret) {
139− kfree(sch->lock);
140− kfree(sch);
141− return ERR_PTR(ret);
142− }
143124 return sch;
144125 }
145126
drivers/s390/cio/css.h+0−2
@@ -60,8 +60,6 @@ struct pgid { · 59 unmodified lines
6060
6161 /*
6262 * A css driver handles all subchannels of one type.
63− * Currently, we only care about I/O subchannels (type 0), these
64− * have a ccw_device connected to them.
6563 */
6664 struct subchannel;
6765 struct css_driver {
drivers/s390/cio/device.c+33−5
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #include <asm/param.h> /* HZ */
2525 #include <asm/cmb.h>
2626
27+#include "chp.h"
2728 #include "cio.h"
2829 #include "cio_debug.h"
2930 #include "css.h"
@@ -1037,7 +1038,6 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) · 1007 unmodified lines
10371038 struct ccw_device_private *priv;
10381039
10391040 sch_set_cdev(sch, cdev);
1040− sch->driver = &io_subchannel_driver;
10411041 cdev->ccwlock = sch->lock;
10421042
10431043 /* Init private data. */
@@ -1122,8 +1122,33 @@ static void io_subchannel_irq(struct subchannel *sch) · 78 unmodified lines
11221122 dev_fsm_event(cdev, DEV_EVENT_INTERRUPT);
11231123 }
11241124
1125−static int
1126−io_subchannel_probe (struct subchannel *sch)
1125+static void io_subchannel_init_fields(struct subchannel *sch)
1126+{
1127+ if (cio_is_console(sch->schid))
1128+ sch->opm = 0xff;
1129+ else
1130+ sch->opm = chp_get_sch_opm(sch);
1131+ sch->lpm = sch->schib.pmcw.pam & sch->opm;
1132+ sch->isc = cio_is_console(sch->schid) ? 1 : 3;
1133+
1134+ CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X"
1135+ " - PIM = %02X, PAM = %02X, POM = %02X\n",
1136+ sch->schib.pmcw.dev, sch->schid.ssid,
1137+ sch->schid.sch_no, sch->schib.pmcw.pim,
1138+ sch->schib.pmcw.pam, sch->schib.pmcw.pom);
1139+ /* Initially set up some fields in the pmcw. */
1140+ sch->schib.pmcw.ena = 0;
1141+ sch->schib.pmcw.csense = 1; /* concurrent sense */
1142+ if ((sch->lpm & (sch->lpm - 1)) != 0)
1143+ sch->schib.pmcw.mp = 1; /* multipath mode */
1144+ /* clean up possible residual cmf stuff */
1145+ sch->schib.pmcw.mme = 0;
1146+ sch->schib.pmcw.mbfc = 0;
1147+ sch->schib.pmcw.mbi = 0;
1148+ sch->schib.mba = 0;
1149+}
1150+
1151+static int io_subchannel_probe(struct subchannel *sch)
11271152 {
11281153 struct ccw_device *cdev;
11291154 int rc;
@@ -1152,6 +1177,7 @@ io_subchannel_probe (struct subchannel *sch) · 22 unmodified lines
11521177 get_device(&cdev->dev);
11531178 return 0;
11541179 }
1180+ io_subchannel_init_fields(sch);
11551181 /*
11561182 * First check if a fitting device may be found amongst the
11571183 * disconnected devices or in the orphanage.
@@ -1297,14 +1323,16 @@ spinlock_t * cio_get_console_lock(void) · 139 unmodified lines
12971323 return &ccw_console_lock;
12981324 }
12991325
1300−static int
1301−ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch)
1326+static int ccw_device_console_enable(struct ccw_device *cdev,
1327+ struct subchannel *sch)
13021328 {
13031329 int rc;
13041330
13051331 /* Attach subchannel private data. */
13061332 sch->private = cio_get_console_priv();
13071333 memset(sch->private, 0, sizeof(struct io_subchannel_private));
1334+ io_subchannel_init_fields(sch);
1335+ sch->driver = &io_subchannel_driver;
13081336 /* Initialize the ccw_device structure. */
13091337 cdev->dev.parent= &sch->dev;
13101338 rc = io_subchannel_recog(cdev, sch);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t