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
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 017#define CHP_STATUS_STANDBY 0
17#define CHP_STATUS_CONFIGURED 118#define CHP_STATUS_CONFIGURED 1
drivers/s390/cio/cio.c+51−75
@@ -2,7 +2,7 @@ · 1 unmodified line
2 * drivers/s390/cio/cio.c2 * drivers/s390/cio/cio.c
3 * S/390 common I/O routines -- low level i/o calls3 * S/390 common I/O routines -- low level i/o calls
4 *4 *
5 * Copyright (C) IBM Corp. 1999,20065 * 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/*497static 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 subchannel524 * 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 subchannels525 * -ENXIO for non-defined subchannels
507 * -ENODEV for subchannels with invalid device number or blacklisted devices526 * -ENODEV for invalid subchannels or blacklisted devices
527 * -EIO for subchannels in an invalid subchannel set
508 */528 */
509int529int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
510cio_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 subchannels569 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;
611out:580out:
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 1762 * 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
866static int834static 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 }
904out:
929 return 0;905 return 0;
930}906}
931 907
drivers/s390/cio/css.c+0−19
@@ -121,25 +121,6 @@ css_alloc_subchannel(struct subchannel_id schid) · 120 unmodified lines
121 kfree(sch);121 kfree(sch);
122 return ERR_PTR(ret);122 return ERR_PTR(ret);
123 }123 }
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 }
143 return sch;124 return sch;
144}125}
145 126
drivers/s390/cio/css.h+0−2
@@ -60,8 +60,6 @@ struct pgid { · 59 unmodified lines
60 60
61/*61/*
62 * A css driver handles all subchannels of one type.62 * 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.
65 */63 */
66struct subchannel;64struct subchannel;
67struct css_driver {65struct css_driver {
drivers/s390/cio/device.c+33−5
@@ -24,6 +24,7 @@ · 23 unmodified lines
24#include <asm/param.h> /* HZ */24#include <asm/param.h> /* HZ */
25#include <asm/cmb.h>25#include <asm/cmb.h>
26 26
27#include "chp.h"
27#include "cio.h"28#include "cio.h"
28#include "cio_debug.h"29#include "cio_debug.h"
29#include "css.h"30#include "css.h"
@@ -1037,7 +1038,6 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) · 1007 unmodified lines
1037 struct ccw_device_private *priv;1038 struct ccw_device_private *priv;
1038 1039
1039 sch_set_cdev(sch, cdev);1040 sch_set_cdev(sch, cdev);
1040 sch->driver = &io_subchannel_driver;
1041 cdev->ccwlock = sch->lock;1041 cdev->ccwlock = sch->lock;
1042 1042
1043 /* Init private data. */1043 /* Init private data. */
@@ -1122,8 +1122,33 @@ static void io_subchannel_irq(struct subchannel *sch) · 78 unmodified lines
1122 dev_fsm_event(cdev, DEV_EVENT_INTERRUPT);1122 dev_fsm_event(cdev, DEV_EVENT_INTERRUPT);
1123}1123}
1124 1124
1125static int1125static void io_subchannel_init_fields(struct subchannel *sch)
1126io_subchannel_probe (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
1151static int io_subchannel_probe(struct subchannel *sch)
1127{1152{
1128 struct ccw_device *cdev;1153 struct ccw_device *cdev;
1129 int rc;1154 int rc;
@@ -1152,6 +1177,7 @@ io_subchannel_probe (struct subchannel *sch) · 22 unmodified lines
1152 get_device(&cdev->dev);1177 get_device(&cdev->dev);
1153 return 0;1178 return 0;
1154 }1179 }
1180 io_subchannel_init_fields(sch);
1155 /*1181 /*
1156 * First check if a fitting device may be found amongst the1182 * First check if a fitting device may be found amongst the
1157 * disconnected devices or in the orphanage.1183 * disconnected devices or in the orphanage.
@@ -1297,14 +1323,16 @@ spinlock_t * cio_get_console_lock(void) · 139 unmodified lines
1297 return &ccw_console_lock;1323 return &ccw_console_lock;
1298}1324}
1299 1325
1300static int1326static int ccw_device_console_enable(struct ccw_device *cdev,
1301ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch)1327 struct subchannel *sch)
1302{1328{
1303 int rc;1329 int rc;
1304 1330
1305 /* Attach subchannel private data. */1331 /* Attach subchannel private data. */
1306 sch->private = cio_get_console_priv();1332 sch->private = cio_get_console_priv();
1307 memset(sch->private, 0, sizeof(struct io_subchannel_private));1333 memset(sch->private, 0, sizeof(struct io_subchannel_private));
1334 io_subchannel_init_fields(sch);
1335 sch->driver = &io_subchannel_driver;
1308 /* Initialize the ccw_device structure. */1336 /* Initialize the ccw_device structure. */
1309 cdev->dev.parent= &sch->dev;1337 cdev->dev.parent= &sch->dev;
1310 rc = io_subchannel_recog(cdev, sch);1338 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