aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-17 13:10:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-17 13:10:49 -0400
commit31598e8713ef501c8f6aad2e2ec8a9457e8877c1 (patch)
tree255d16a18cbfa78d15486eba07e03b222ddb5f77 /drivers/s390
parent241eb95600be194f6b59b85c0bf41194694ebdf1 (diff)
parent6966727db1389f4926c6fa6e87a600112a5658b9 (diff)
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: [S390] kexec: Disable ftrace during kexec [S390] support XZ compressed kernel [S390] css_bus_type: make it static [S390] css_driver: remove duplicate members [S390] css: remove subchannel private [S390] css: move chsc_private to drv_data [S390] css: move io_private to drv_data [S390] cio: move cdev pointer to io_subchannel_private [S390] cio: move options to io_sch_private [S390] cio: move asms to generic header [S390] cio: move orb definitions to separate header [S390] Write protect module text and RO data [S390] dasd: get rid of compile warning [S390] remove superfluous check from do_IRQ [S390] remove redundant stack check option
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd_eckd.c1
-rw-r--r--drivers/s390/cio/chsc_sch.c17
-rw-r--r--drivers/s390/cio/cio.c43
-rw-r--r--drivers/s390/cio/cio.h11
-rw-r--r--drivers/s390/cio/css.c6
-rw-r--r--drivers/s390/cio/css.h10
-rw-r--r--drivers/s390/cio/device.c23
-rw-r--r--drivers/s390/cio/io_sch.h114
-rw-r--r--drivers/s390/cio/ioasm.h34
-rw-r--r--drivers/s390/cio/orb.h67
10 files changed, 166 insertions, 160 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index a9fe23d5bd0f..379d8592bc6e 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2648,6 +2648,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2648 dasd_sfree_request(cqr, startdev); 2648 dasd_sfree_request(cqr, startdev);
2649 return ERR_PTR(-EAGAIN); 2649 return ERR_PTR(-EAGAIN);
2650 } 2650 }
2651 len_to_track_end = 0;
2651 /* 2652 /*
2652 * A tidaw can address 4k of memory, but must not cross page boundaries 2653 * A tidaw can address 4k of memory, but must not cross page boundaries
2653 * We can let the block layer handle this by setting 2654 * We can let the block layer handle this by setting
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 3c3f3ffe2179..e950f1ad4dd1 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -50,7 +50,7 @@ MODULE_LICENSE("GPL");
50 50
51static void chsc_subchannel_irq(struct subchannel *sch) 51static void chsc_subchannel_irq(struct subchannel *sch)
52{ 52{
53 struct chsc_private *private = sch->private; 53 struct chsc_private *private = dev_get_drvdata(&sch->dev);
54 struct chsc_request *request = private->request; 54 struct chsc_request *request = private->request;
55 struct irb *irb = (struct irb *)&S390_lowcore.irb; 55 struct irb *irb = (struct irb *)&S390_lowcore.irb;
56 56
@@ -80,13 +80,14 @@ static int chsc_subchannel_probe(struct subchannel *sch)
80 private = kzalloc(sizeof(*private), GFP_KERNEL); 80 private = kzalloc(sizeof(*private), GFP_KERNEL);
81 if (!private) 81 if (!private)
82 return -ENOMEM; 82 return -ENOMEM;
83 dev_set_drvdata(&sch->dev, private);
83 ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); 84 ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
84 if (ret) { 85 if (ret) {
85 CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n", 86 CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n",
86 sch->schid.ssid, sch->schid.sch_no, ret); 87 sch->schid.ssid, sch->schid.sch_no, ret);
88 dev_set_drvdata(&sch->dev, NULL);
87 kfree(private); 89 kfree(private);
88 } else { 90 } else {
89 sch->private = private;
90 if (dev_get_uevent_suppress(&sch->dev)) { 91 if (dev_get_uevent_suppress(&sch->dev)) {
91 dev_set_uevent_suppress(&sch->dev, 0); 92 dev_set_uevent_suppress(&sch->dev, 0);
92 kobject_uevent(&sch->dev.kobj, KOBJ_ADD); 93 kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
@@ -100,8 +101,8 @@ static int chsc_subchannel_remove(struct subchannel *sch)
100 struct chsc_private *private; 101 struct chsc_private *private;
101 102
102 cio_disable_subchannel(sch); 103 cio_disable_subchannel(sch);
103 private = sch->private; 104 private = dev_get_drvdata(&sch->dev);
104 sch->private = NULL; 105 dev_set_drvdata(&sch->dev, NULL);
105 if (private->request) { 106 if (private->request) {
106 complete(&private->request->completion); 107 complete(&private->request->completion);
107 put_device(&sch->dev); 108 put_device(&sch->dev);
@@ -147,7 +148,10 @@ static struct css_device_id chsc_subchannel_ids[] = {
147MODULE_DEVICE_TABLE(css, chsc_subchannel_ids); 148MODULE_DEVICE_TABLE(css, chsc_subchannel_ids);
148 149
149static struct css_driver chsc_subchannel_driver = { 150static struct css_driver chsc_subchannel_driver = {
150 .owner = THIS_MODULE, 151 .drv = {
152 .owner = THIS_MODULE,
153 .name = "chsc_subchannel",
154 },
151 .subchannel_type = chsc_subchannel_ids, 155 .subchannel_type = chsc_subchannel_ids,
152 .irq = chsc_subchannel_irq, 156 .irq = chsc_subchannel_irq,
153 .probe = chsc_subchannel_probe, 157 .probe = chsc_subchannel_probe,
@@ -157,7 +161,6 @@ static struct css_driver chsc_subchannel_driver = {
157 .freeze = chsc_subchannel_freeze, 161 .freeze = chsc_subchannel_freeze,
158 .thaw = chsc_subchannel_restore, 162 .thaw = chsc_subchannel_restore,
159 .restore = chsc_subchannel_restore, 163 .restore = chsc_subchannel_restore,
160 .name = "chsc_subchannel",
161}; 164};
162 165
163static int __init chsc_init_dbfs(void) 166static int __init chsc_init_dbfs(void)
@@ -241,7 +244,7 @@ static int chsc_async(struct chsc_async_area *chsc_area,
241 chsc_area->header.key = PAGE_DEFAULT_KEY >> 4; 244 chsc_area->header.key = PAGE_DEFAULT_KEY >> 4;
242 while ((sch = chsc_get_next_subchannel(sch))) { 245 while ((sch = chsc_get_next_subchannel(sch))) {
243 spin_lock(sch->lock); 246 spin_lock(sch->lock);
244 private = sch->private; 247 private = dev_get_drvdata(&sch->dev);
245 if (private->request) { 248 if (private->request) {
246 spin_unlock(sch->lock); 249 spin_unlock(sch->lock);
247 ret = -EBUSY; 250 ret = -EBUSY;
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 430f875006f2..cbde448f9947 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -84,29 +84,14 @@ out_unregister:
84 84
85arch_initcall (cio_debug_init); 85arch_initcall (cio_debug_init);
86 86
87int 87int cio_set_options(struct subchannel *sch, int flags)
88cio_set_options (struct subchannel *sch, int flags)
89{ 88{
90 sch->options.suspend = (flags & DOIO_ALLOW_SUSPEND) != 0; 89 struct io_subchannel_private *priv = to_io_private(sch);
91 sch->options.prefetch = (flags & DOIO_DENY_PREFETCH) != 0;
92 sch->options.inter = (flags & DOIO_SUPPRESS_INTER) != 0;
93 return 0;
94}
95 90
96/* FIXME: who wants to use this? */ 91 priv->options.suspend = (flags & DOIO_ALLOW_SUSPEND) != 0;
97int 92 priv->options.prefetch = (flags & DOIO_DENY_PREFETCH) != 0;
98cio_get_options (struct subchannel *sch) 93 priv->options.inter = (flags & DOIO_SUPPRESS_INTER) != 0;
99{ 94 return 0;
100 int flags;
101
102 flags = 0;
103 if (sch->options.suspend)
104 flags |= DOIO_ALLOW_SUSPEND;
105 if (sch->options.prefetch)
106 flags |= DOIO_DENY_PREFETCH;
107 if (sch->options.inter)
108 flags |= DOIO_SUPPRESS_INTER;
109 return flags;
110} 95}
111 96
112static int 97static int
@@ -139,21 +124,21 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
139 __u8 lpm, /* logical path mask */ 124 __u8 lpm, /* logical path mask */
140 __u8 key) /* storage key */ 125 __u8 key) /* storage key */
141{ 126{
127 struct io_subchannel_private *priv = to_io_private(sch);
128 union orb *orb = &priv->orb;
142 int ccode; 129 int ccode;
143 union orb *orb;
144 130
145 CIO_TRACE_EVENT(5, "stIO"); 131 CIO_TRACE_EVENT(5, "stIO");
146 CIO_TRACE_EVENT(5, dev_name(&sch->dev)); 132 CIO_TRACE_EVENT(5, dev_name(&sch->dev));
147 133
148 orb = &to_io_private(sch)->orb;
149 memset(orb, 0, sizeof(union orb)); 134 memset(orb, 0, sizeof(union orb));
150 /* sch is always under 2G. */ 135 /* sch is always under 2G. */
151 orb->cmd.intparm = (u32)(addr_t)sch; 136 orb->cmd.intparm = (u32)(addr_t)sch;
152 orb->cmd.fmt = 1; 137 orb->cmd.fmt = 1;
153 138
154 orb->cmd.pfch = sch->options.prefetch == 0; 139 orb->cmd.pfch = priv->options.prefetch == 0;
155 orb->cmd.spnd = sch->options.suspend; 140 orb->cmd.spnd = priv->options.suspend;
156 orb->cmd.ssic = sch->options.suspend && sch->options.inter; 141 orb->cmd.ssic = priv->options.suspend && priv->options.inter;
157 orb->cmd.lpm = (lpm != 0) ? lpm : sch->lpm; 142 orb->cmd.lpm = (lpm != 0) ? lpm : sch->lpm;
158#ifdef CONFIG_64BIT 143#ifdef CONFIG_64BIT
159 /* 144 /*
@@ -630,11 +615,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
630 irb = (struct irb *)&S390_lowcore.irb; 615 irb = (struct irb *)&S390_lowcore.irb;
631 do { 616 do {
632 kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++; 617 kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++;
633 /* 618 if (tpi_info->adapter_IO) {
634 * Non I/O-subchannel thin interrupts are processed differently
635 */
636 if (tpi_info->adapter_IO == 1 &&
637 tpi_info->int_type == IO_INTERRUPT_TYPE) {
638 do_adapter_IO(tpi_info->isc); 619 do_adapter_IO(tpi_info->isc);
639 continue; 620 continue;
640 } 621 }
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index bf7f80f5a330..155a82bcb9e5 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -84,13 +84,6 @@ struct subchannel {
84 SUBCHANNEL_TYPE_MSG = 2, 84 SUBCHANNEL_TYPE_MSG = 2,
85 SUBCHANNEL_TYPE_ADM = 3, 85 SUBCHANNEL_TYPE_ADM = 3,
86 } st; /* subchannel type */ 86 } st; /* subchannel type */
87
88 struct {
89 unsigned int suspend:1; /* allow suspend */
90 unsigned int prefetch:1;/* deny prefetch */
91 unsigned int inter:1; /* suppress intermediate interrupts */
92 } __attribute__ ((packed)) options;
93
94 __u8 vpm; /* verified path mask */ 87 __u8 vpm; /* verified path mask */
95 __u8 lpm; /* logical path mask */ 88 __u8 lpm; /* logical path mask */
96 __u8 opm; /* operational path mask */ 89 __u8 opm; /* operational path mask */
@@ -99,14 +92,11 @@ struct subchannel {
99 struct chsc_ssd_info ssd_info; /* subchannel description */ 92 struct chsc_ssd_info ssd_info; /* subchannel description */
100 struct device dev; /* entry in device tree */ 93 struct device dev; /* entry in device tree */
101 struct css_driver *driver; 94 struct css_driver *driver;
102 void *private; /* private per subchannel type data */
103 enum sch_todo todo; 95 enum sch_todo todo;
104 struct work_struct todo_work; 96 struct work_struct todo_work;
105 struct schib_config config; 97 struct schib_config config;
106} __attribute__ ((aligned(8))); 98} __attribute__ ((aligned(8)));
107 99
108#define IO_INTERRUPT_TYPE 0 /* I/O interrupt type */
109
110#define to_subchannel(n) container_of(n, struct subchannel, dev) 100#define to_subchannel(n) container_of(n, struct subchannel, dev)
111 101
112extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id); 102extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id);
@@ -120,7 +110,6 @@ extern int cio_start (struct subchannel *, struct ccw1 *, __u8);
120extern int cio_start_key (struct subchannel *, struct ccw1 *, __u8, __u8); 110extern int cio_start_key (struct subchannel *, struct ccw1 *, __u8, __u8);
121extern int cio_cancel (struct subchannel *); 111extern int cio_cancel (struct subchannel *);
122extern int cio_set_options (struct subchannel *, int); 112extern int cio_set_options (struct subchannel *, int);
123extern int cio_get_options (struct subchannel *);
124extern int cio_update_schib(struct subchannel *sch); 113extern int cio_update_schib(struct subchannel *sch);
125extern int cio_commit_config(struct subchannel *sch); 114extern int cio_commit_config(struct subchannel *sch);
126 115
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 24d8e97355b9..c47b25fd3f43 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -35,6 +35,7 @@ int css_init_done = 0;
35int max_ssid; 35int max_ssid;
36 36
37struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1]; 37struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1];
38static struct bus_type css_bus_type;
38 39
39int 40int
40for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) 41for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data)
@@ -1214,7 +1215,7 @@ static const struct dev_pm_ops css_pm_ops = {
1214 .restore = css_pm_restore, 1215 .restore = css_pm_restore,
1215}; 1216};
1216 1217
1217struct bus_type css_bus_type = { 1218static struct bus_type css_bus_type = {
1218 .name = "css", 1219 .name = "css",
1219 .match = css_bus_match, 1220 .match = css_bus_match,
1220 .probe = css_probe, 1221 .probe = css_probe,
@@ -1233,9 +1234,7 @@ struct bus_type css_bus_type = {
1233 */ 1234 */
1234int css_driver_register(struct css_driver *cdrv) 1235int css_driver_register(struct css_driver *cdrv)
1235{ 1236{
1236 cdrv->drv.name = cdrv->name;
1237 cdrv->drv.bus = &css_bus_type; 1237 cdrv->drv.bus = &css_bus_type;
1238 cdrv->drv.owner = cdrv->owner;
1239 return driver_register(&cdrv->drv); 1238 return driver_register(&cdrv->drv);
1240} 1239}
1241EXPORT_SYMBOL_GPL(css_driver_register); 1240EXPORT_SYMBOL_GPL(css_driver_register);
@@ -1253,4 +1252,3 @@ void css_driver_unregister(struct css_driver *cdrv)
1253EXPORT_SYMBOL_GPL(css_driver_unregister); 1252EXPORT_SYMBOL_GPL(css_driver_unregister);
1254 1253
1255MODULE_LICENSE("GPL"); 1254MODULE_LICENSE("GPL");
1256EXPORT_SYMBOL(css_bus_type);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 7e37886de231..80ebdddf7747 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -63,7 +63,6 @@ struct subchannel;
63struct chp_link; 63struct chp_link;
64/** 64/**
65 * struct css_driver - device driver for subchannels 65 * struct css_driver - device driver for subchannels
66 * @owner: owning module
67 * @subchannel_type: subchannel type supported by this driver 66 * @subchannel_type: subchannel type supported by this driver
68 * @drv: embedded device driver structure 67 * @drv: embedded device driver structure
69 * @irq: called on interrupts 68 * @irq: called on interrupts
@@ -78,10 +77,8 @@ struct chp_link;
78 * @thaw: undo work done in @freeze 77 * @thaw: undo work done in @freeze
79 * @restore: callback for restoring after hibernation 78 * @restore: callback for restoring after hibernation
80 * @settle: wait for asynchronous work to finish 79 * @settle: wait for asynchronous work to finish
81 * @name: name of the device driver
82 */ 80 */
83struct css_driver { 81struct css_driver {
84 struct module *owner;
85 struct css_device_id *subchannel_type; 82 struct css_device_id *subchannel_type;
86 struct device_driver drv; 83 struct device_driver drv;
87 void (*irq)(struct subchannel *); 84 void (*irq)(struct subchannel *);
@@ -96,16 +93,10 @@ struct css_driver {
96 int (*thaw) (struct subchannel *); 93 int (*thaw) (struct subchannel *);
97 int (*restore)(struct subchannel *); 94 int (*restore)(struct subchannel *);
98 int (*settle)(void); 95 int (*settle)(void);
99 const char *name;
100}; 96};
101 97
102#define to_cssdriver(n) container_of(n, struct css_driver, drv) 98#define to_cssdriver(n) container_of(n, struct css_driver, drv)
103 99
104/*
105 * all css_drivers have the css_bus_type
106 */
107extern struct bus_type css_bus_type;
108
109extern int css_driver_register(struct css_driver *); 100extern int css_driver_register(struct css_driver *);
110extern void css_driver_unregister(struct css_driver *); 101extern void css_driver_unregister(struct css_driver *);
111 102
@@ -140,7 +131,6 @@ struct channel_subsystem {
140}; 131};
141#define to_css(dev) container_of(dev, struct channel_subsystem, device) 132#define to_css(dev) container_of(dev, struct channel_subsystem, device)
142 133
143extern struct bus_type css_bus_type;
144extern struct channel_subsystem *channel_subsystems[]; 134extern struct channel_subsystem *channel_subsystems[];
145 135
146/* Helper functions to build lists for the slow path. */ 136/* Helper functions to build lists for the slow path. */
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index b7eaff9ca19e..e50b12163afe 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -172,9 +172,11 @@ static int io_subchannel_settle(void)
172} 172}
173 173
174static struct css_driver io_subchannel_driver = { 174static struct css_driver io_subchannel_driver = {
175 .owner = THIS_MODULE, 175 .drv = {
176 .owner = THIS_MODULE,
177 .name = "io_subchannel",
178 },
176 .subchannel_type = io_subchannel_ids, 179 .subchannel_type = io_subchannel_ids,
177 .name = "io_subchannel",
178 .irq = io_subchannel_irq, 180 .irq = io_subchannel_irq,
179 .sch_event = io_subchannel_sch_event, 181 .sch_event = io_subchannel_sch_event,
180 .chp_event = io_subchannel_chp_event, 182 .chp_event = io_subchannel_chp_event,
@@ -1030,6 +1032,7 @@ static void io_subchannel_init_fields(struct subchannel *sch)
1030 */ 1032 */
1031static int io_subchannel_probe(struct subchannel *sch) 1033static int io_subchannel_probe(struct subchannel *sch)
1032{ 1034{
1035 struct io_subchannel_private *io_priv;
1033 struct ccw_device *cdev; 1036 struct ccw_device *cdev;
1034 int rc; 1037 int rc;
1035 1038
@@ -1073,10 +1076,11 @@ static int io_subchannel_probe(struct subchannel *sch)
1073 if (rc) 1076 if (rc)
1074 goto out_schedule; 1077 goto out_schedule;
1075 /* Allocate I/O subchannel private data. */ 1078 /* Allocate I/O subchannel private data. */
1076 sch->private = kzalloc(sizeof(struct io_subchannel_private), 1079 io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA);
1077 GFP_KERNEL | GFP_DMA); 1080 if (!io_priv)
1078 if (!sch->private)
1079 goto out_schedule; 1081 goto out_schedule;
1082
1083 set_io_private(sch, io_priv);
1080 css_schedule_eval(sch->schid); 1084 css_schedule_eval(sch->schid);
1081 return 0; 1085 return 0;
1082 1086
@@ -1090,6 +1094,7 @@ out_schedule:
1090static int 1094static int
1091io_subchannel_remove (struct subchannel *sch) 1095io_subchannel_remove (struct subchannel *sch)
1092{ 1096{
1097 struct io_subchannel_private *io_priv = to_io_private(sch);
1093 struct ccw_device *cdev; 1098 struct ccw_device *cdev;
1094 1099
1095 cdev = sch_get_cdev(sch); 1100 cdev = sch_get_cdev(sch);
@@ -1099,11 +1104,12 @@ io_subchannel_remove (struct subchannel *sch)
1099 /* Set ccw device to not operational and drop reference. */ 1104 /* Set ccw device to not operational and drop reference. */
1100 spin_lock_irq(cdev->ccwlock); 1105 spin_lock_irq(cdev->ccwlock);
1101 sch_set_cdev(sch, NULL); 1106 sch_set_cdev(sch, NULL);
1107 set_io_private(sch, NULL);
1102 cdev->private->state = DEV_STATE_NOT_OPER; 1108 cdev->private->state = DEV_STATE_NOT_OPER;
1103 spin_unlock_irq(cdev->ccwlock); 1109 spin_unlock_irq(cdev->ccwlock);
1104 ccw_device_unregister(cdev); 1110 ccw_device_unregister(cdev);
1105out_free: 1111out_free:
1106 kfree(sch->private); 1112 kfree(io_priv);
1107 sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group); 1113 sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
1108 return 0; 1114 return 0;
1109} 1115}
@@ -1553,11 +1559,12 @@ spinlock_t * cio_get_console_lock(void)
1553static int ccw_device_console_enable(struct ccw_device *cdev, 1559static int ccw_device_console_enable(struct ccw_device *cdev,
1554 struct subchannel *sch) 1560 struct subchannel *sch)
1555{ 1561{
1562 struct io_subchannel_private *io_priv = cio_get_console_priv();
1556 int rc; 1563 int rc;
1557 1564
1558 /* Attach subchannel private data. */ 1565 /* Attach subchannel private data. */
1559 sch->private = cio_get_console_priv(); 1566 memset(io_priv, 0, sizeof(*io_priv));
1560 memset(sch->private, 0, sizeof(struct io_subchannel_private)); 1567 set_io_private(sch, io_priv);
1561 io_subchannel_init_fields(sch); 1568 io_subchannel_init_fields(sch);
1562 rc = cio_commit_config(sch); 1569 rc = cio_commit_config(sch);
1563 if (rc) 1570 if (rc)
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h
index d024d2c21897..ba31ad88f4f7 100644
--- a/drivers/s390/cio/io_sch.h
+++ b/drivers/s390/cio/io_sch.h
@@ -5,68 +5,36 @@
5#include <asm/schid.h> 5#include <asm/schid.h>
6#include <asm/ccwdev.h> 6#include <asm/ccwdev.h>
7#include "css.h" 7#include "css.h"
8 8#include "orb.h"
9/*
10 * command-mode operation request block
11 */
12struct cmd_orb {
13 u32 intparm; /* interruption parameter */
14 u32 key : 4; /* flags, like key, suspend control, etc. */
15 u32 spnd : 1; /* suspend control */
16 u32 res1 : 1; /* reserved */
17 u32 mod : 1; /* modification control */
18 u32 sync : 1; /* synchronize control */
19 u32 fmt : 1; /* format control */
20 u32 pfch : 1; /* prefetch control */
21 u32 isic : 1; /* initial-status-interruption control */
22 u32 alcc : 1; /* address-limit-checking control */
23 u32 ssic : 1; /* suppress-suspended-interr. control */
24 u32 res2 : 1; /* reserved */
25 u32 c64 : 1; /* IDAW/QDIO 64 bit control */
26 u32 i2k : 1; /* IDAW 2/4kB block size control */
27 u32 lpm : 8; /* logical path mask */
28 u32 ils : 1; /* incorrect length */
29 u32 zero : 6; /* reserved zeros */
30 u32 orbx : 1; /* ORB extension control */
31 u32 cpa; /* channel program address */
32} __attribute__ ((packed, aligned(4)));
33
34/*
35 * transport-mode operation request block
36 */
37struct tm_orb {
38 u32 intparm;
39 u32 key:4;
40 u32 :9;
41 u32 b:1;
42 u32 :2;
43 u32 lpm:8;
44 u32 :7;
45 u32 x:1;
46 u32 tcw;
47 u32 prio:8;
48 u32 :8;
49 u32 rsvpgm:8;
50 u32 :8;
51 u32 :32;
52 u32 :32;
53 u32 :32;
54 u32 :32;
55} __attribute__ ((packed, aligned(4)));
56
57union orb {
58 struct cmd_orb cmd;
59 struct tm_orb tm;
60} __attribute__ ((packed, aligned(4)));
61 9
62struct io_subchannel_private { 10struct io_subchannel_private {
63 union orb orb; /* operation request block */ 11 union orb orb; /* operation request block */
64 struct ccw1 sense_ccw; /* static ccw for sense command */ 12 struct ccw1 sense_ccw; /* static ccw for sense command */
65} __attribute__ ((aligned(8))); 13 struct ccw_device *cdev;/* pointer to the child ccw device */
14 struct {
15 unsigned int suspend:1; /* allow suspend */
16 unsigned int prefetch:1;/* deny prefetch */
17 unsigned int inter:1; /* suppress intermediate interrupts */
18 } __packed options;
19} __aligned(8);
66 20
67#define to_io_private(n) ((struct io_subchannel_private *)n->private) 21#define to_io_private(n) ((struct io_subchannel_private *) \
68#define sch_get_cdev(n) (dev_get_drvdata(&n->dev)) 22 dev_get_drvdata(&(n)->dev))
69#define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c)) 23#define set_io_private(n, p) (dev_set_drvdata(&(n)->dev, p))
24
25static inline struct ccw_device *sch_get_cdev(struct subchannel *sch)
26{
27 struct io_subchannel_private *priv = to_io_private(sch);
28 return priv ? priv->cdev : NULL;
29}
30
31static inline void sch_set_cdev(struct subchannel *sch,
32 struct ccw_device *cdev)
33{
34 struct io_subchannel_private *priv = to_io_private(sch);
35 if (priv)
36 priv->cdev = cdev;
37}
70 38
71#define MAX_CIWS 8 39#define MAX_CIWS 8
72 40
@@ -191,23 +159,6 @@ struct ccw_device_private {
191 void *cmb_wait; /* deferred cmb enable/disable */ 159 void *cmb_wait; /* deferred cmb enable/disable */
192}; 160};
193 161
194static inline int ssch(struct subchannel_id schid, union orb *addr)
195{
196 register struct subchannel_id reg1 asm("1") = schid;
197 int ccode = -EIO;
198
199 asm volatile(
200 " ssch 0(%2)\n"
201 "0: ipm %0\n"
202 " srl %0,28\n"
203 "1:\n"
204 EX_TABLE(0b, 1b)
205 : "+d" (ccode)
206 : "d" (reg1), "a" (addr), "m" (*addr)
207 : "cc", "memory");
208 return ccode;
209}
210
211static inline int rsch(struct subchannel_id schid) 162static inline int rsch(struct subchannel_id schid)
212{ 163{
213 register struct subchannel_id reg1 asm("1") = schid; 164 register struct subchannel_id reg1 asm("1") = schid;
@@ -223,21 +174,6 @@ static inline int rsch(struct subchannel_id schid)
223 return ccode; 174 return ccode;
224} 175}
225 176
226static inline int csch(struct subchannel_id schid)
227{
228 register struct subchannel_id reg1 asm("1") = schid;
229 int ccode;
230
231 asm volatile(
232 " csch\n"
233 " ipm %0\n"
234 " srl %0,28"
235 : "=d" (ccode)
236 : "d" (reg1)
237 : "cc");
238 return ccode;
239}
240
241static inline int hsch(struct subchannel_id schid) 177static inline int hsch(struct subchannel_id schid)
242{ 178{
243 register struct subchannel_id reg1 asm("1") = schid; 179 register struct subchannel_id reg1 asm("1") = schid;
diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h
index fac06155773f..4d80fc67a06b 100644
--- a/drivers/s390/cio/ioasm.h
+++ b/drivers/s390/cio/ioasm.h
@@ -3,6 +3,8 @@
3 3
4#include <asm/chpid.h> 4#include <asm/chpid.h>
5#include <asm/schid.h> 5#include <asm/schid.h>
6#include "orb.h"
7#include "cio.h"
6 8
7/* 9/*
8 * TPI info structure 10 * TPI info structure
@@ -87,6 +89,38 @@ static inline int tsch(struct subchannel_id schid, struct irb *addr)
87 return ccode; 89 return ccode;
88} 90}
89 91
92static inline int ssch(struct subchannel_id schid, union orb *addr)
93{
94 register struct subchannel_id reg1 asm("1") = schid;
95 int ccode = -EIO;
96
97 asm volatile(
98 " ssch 0(%2)\n"
99 "0: ipm %0\n"
100 " srl %0,28\n"
101 "1:\n"
102 EX_TABLE(0b, 1b)
103 : "+d" (ccode)
104 : "d" (reg1), "a" (addr), "m" (*addr)
105 : "cc", "memory");
106 return ccode;
107}
108
109static inline int csch(struct subchannel_id schid)
110{
111 register struct subchannel_id reg1 asm("1") = schid;
112 int ccode;
113
114 asm volatile(
115 " csch\n"
116 " ipm %0\n"
117 " srl %0,28"
118 : "=d" (ccode)
119 : "d" (reg1)
120 : "cc");
121 return ccode;
122}
123
90static inline int tpi(struct tpi_info *addr) 124static inline int tpi(struct tpi_info *addr)
91{ 125{
92 int ccode; 126 int ccode;
diff --git a/drivers/s390/cio/orb.h b/drivers/s390/cio/orb.h
new file mode 100644
index 000000000000..45a9865c2b36
--- /dev/null
+++ b/drivers/s390/cio/orb.h
@@ -0,0 +1,67 @@
1/*
2 * Orb related data structures.
3 *
4 * Copyright IBM Corp. 2007, 2011
5 *
6 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
7 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
8 * Sebastian Ott <sebott@linux.vnet.ibm.com>
9 */
10
11#ifndef S390_ORB_H
12#define S390_ORB_H
13
14/*
15 * Command-mode operation request block
16 */
17struct cmd_orb {
18 u32 intparm; /* interruption parameter */
19 u32 key:4; /* flags, like key, suspend control, etc. */
20 u32 spnd:1; /* suspend control */
21 u32 res1:1; /* reserved */
22 u32 mod:1; /* modification control */
23 u32 sync:1; /* synchronize control */
24 u32 fmt:1; /* format control */
25 u32 pfch:1; /* prefetch control */
26 u32 isic:1; /* initial-status-interruption control */
27 u32 alcc:1; /* address-limit-checking control */
28 u32 ssic:1; /* suppress-suspended-interr. control */
29 u32 res2:1; /* reserved */
30 u32 c64:1; /* IDAW/QDIO 64 bit control */
31 u32 i2k:1; /* IDAW 2/4kB block size control */
32 u32 lpm:8; /* logical path mask */
33 u32 ils:1; /* incorrect length */
34 u32 zero:6; /* reserved zeros */
35 u32 orbx:1; /* ORB extension control */
36 u32 cpa; /* channel program address */
37} __packed __aligned(4);
38
39/*
40 * Transport-mode operation request block
41 */
42struct tm_orb {
43 u32 intparm;
44 u32 key:4;
45 u32:9;
46 u32 b:1;
47 u32:2;
48 u32 lpm:8;
49 u32:7;
50 u32 x:1;
51 u32 tcw;
52 u32 prio:8;
53 u32:8;
54 u32 rsvpgm:8;
55 u32:8;
56 u32:32;
57 u32:32;
58 u32:32;
59 u32:32;
60} __packed __aligned(4);
61
62union orb {
63 struct cmd_orb cmd;
64 struct tm_orb tm;
65} __packed __aligned(4);
66
67#endif /* S390_ORB_H */