aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/cio/cio.c29
-rw-r--r--drivers/s390/cio/cio.h1
-rw-r--r--drivers/s390/cio/css.c36
3 files changed, 32 insertions, 34 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 3ab99d883888..af5fd716449f 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -471,15 +471,6 @@ int cio_disable_subchannel(struct subchannel *sch)
471} 471}
472EXPORT_SYMBOL_GPL(cio_disable_subchannel); 472EXPORT_SYMBOL_GPL(cio_disable_subchannel);
473 473
474int cio_create_sch_lock(struct subchannel *sch)
475{
476 sch->lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
477 if (!sch->lock)
478 return -ENOMEM;
479 spin_lock_init(sch->lock);
480 return 0;
481}
482
483static int cio_check_devno_blacklisted(struct subchannel *sch) 474static int cio_check_devno_blacklisted(struct subchannel *sch)
484{ 475{
485 if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) { 476 if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) {
@@ -536,28 +527,19 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
536 sprintf(dbf_txt, "valsch%x", schid.sch_no); 527 sprintf(dbf_txt, "valsch%x", schid.sch_no);
537 CIO_TRACE_EVENT(4, dbf_txt); 528 CIO_TRACE_EVENT(4, dbf_txt);
538 529
539 /* Nuke all fields. */
540 memset(sch, 0, sizeof(struct subchannel));
541
542 sch->schid = schid;
543 err = cio_create_sch_lock(sch);
544 if (err)
545 goto out;
546 mutex_init(&sch->reg_mutex);
547
548 /* 530 /*
549 * The first subchannel that is not-operational (ccode==3) 531 * The first subchannel that is not-operational (ccode==3)
550 * indicates that there aren't any more devices available. 532 * indicates that there aren't any more devices available.
551 * If stsch gets an exception, it means the current subchannel set 533 * If stsch gets an exception, it means the current subchannel set
552 * is not valid. 534 * is not valid.
553 */ 535 */
554 ccode = stsch_err (schid, &sch->schib); 536 ccode = stsch_err(schid, &sch->schib);
555 if (ccode) { 537 if (ccode) {
556 err = (ccode == 3) ? -ENXIO : ccode; 538 err = (ccode == 3) ? -ENXIO : ccode;
557 goto out; 539 goto out;
558 } 540 }
559 /* Copy subchannel type from path management control word. */
560 sch->st = sch->schib.pmcw.st; 541 sch->st = sch->schib.pmcw.st;
542 sch->schid = schid;
561 543
562 switch (sch->st) { 544 switch (sch->st) {
563 case SUBCHANNEL_TYPE_IO: 545 case SUBCHANNEL_TYPE_IO:
@@ -574,10 +556,7 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
574 556
575 CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n", 557 CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n",
576 sch->schid.ssid, sch->schid.sch_no, sch->st); 558 sch->schid.ssid, sch->schid.sch_no, sch->st);
577 return 0;
578out: 559out:
579 kfree(sch->lock);
580 sch->lock = NULL;
581 return err; 560 return err;
582} 561}
583 562
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index 57b41ec2ed40..d62f5e7f3cf1 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -121,7 +121,6 @@ extern int cio_commit_config(struct subchannel *sch);
121int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key); 121int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key);
122int cio_tm_intrg(struct subchannel *sch); 122int cio_tm_intrg(struct subchannel *sch);
123 123
124int cio_create_sch_lock(struct subchannel *);
125void do_adapter_IO(u8 isc); 124void do_adapter_IO(u8 isc);
126void do_IRQ(struct pt_regs *); 125void do_IRQ(struct pt_regs *);
127 126
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 054fb428531f..1ebe5d3ddebb 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -137,6 +137,18 @@ out:
137 137
138static void css_sch_todo(struct work_struct *work); 138static void css_sch_todo(struct work_struct *work);
139 139
140static int css_sch_create_locks(struct subchannel *sch)
141{
142 sch->lock = kmalloc(sizeof(*sch->lock), GFP_KERNEL);
143 if (!sch->lock)
144 return -ENOMEM;
145
146 spin_lock_init(sch->lock);
147 mutex_init(&sch->reg_mutex);
148
149 return 0;
150}
151
140static void css_subchannel_release(struct device *dev) 152static void css_subchannel_release(struct device *dev)
141{ 153{
142 struct subchannel *sch = to_subchannel(dev); 154 struct subchannel *sch = to_subchannel(dev);
@@ -152,18 +164,26 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid)
152 struct subchannel *sch; 164 struct subchannel *sch;
153 int ret; 165 int ret;
154 166
155 sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA); 167 sch = kzalloc(sizeof(*sch), GFP_KERNEL | GFP_DMA);
156 if (sch == NULL) 168 if (!sch)
157 return ERR_PTR(-ENOMEM); 169 return ERR_PTR(-ENOMEM);
158 ret = cio_validate_subchannel (sch, schid); 170
159 if (ret < 0) { 171 ret = cio_validate_subchannel(sch, schid);
160 kfree(sch); 172 if (ret < 0)
161 return ERR_PTR(ret); 173 goto err;
162 } 174
175 ret = css_sch_create_locks(sch);
176 if (ret)
177 goto err;
178
163 INIT_WORK(&sch->todo_work, css_sch_todo); 179 INIT_WORK(&sch->todo_work, css_sch_todo);
164 sch->dev.release = &css_subchannel_release; 180 sch->dev.release = &css_subchannel_release;
165 device_initialize(&sch->dev); 181 device_initialize(&sch->dev);
166 return sch; 182 return sch;
183
184err:
185 kfree(sch);
186 return ERR_PTR(ret);
167} 187}
168 188
169static int css_sch_device_register(struct subchannel *sch) 189static int css_sch_device_register(struct subchannel *sch)
@@ -756,7 +776,7 @@ static int __init setup_css(int nr)
756 css->pseudo_subchannel->dev.release = css_subchannel_release; 776 css->pseudo_subchannel->dev.release = css_subchannel_release;
757 dev_set_name(&css->pseudo_subchannel->dev, "defunct"); 777 dev_set_name(&css->pseudo_subchannel->dev, "defunct");
758 mutex_init(&css->pseudo_subchannel->reg_mutex); 778 mutex_init(&css->pseudo_subchannel->reg_mutex);
759 ret = cio_create_sch_lock(css->pseudo_subchannel); 779 ret = css_sch_create_locks(css->pseudo_subchannel);
760 if (ret) { 780 if (ret) {
761 kfree(css->pseudo_subchannel); 781 kfree(css->pseudo_subchannel);
762 return ret; 782 return ret;