diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-04-13 07:08:01 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-04-17 08:07:34 -0400 |
commit | e5dcf0025d7af58f525590ac86ac27cb44714e8d (patch) | |
tree | bfe935769fcb4c647a3add3587c088b9f835cac7 /drivers/s390 | |
parent | 0ad8f714a135cf993606c21fc1ed0e303ef17c0d (diff) |
s390/css: move subchannel lock allocation
cio_validate_subchannel is used to do some basic checks to find out
if it's worth to further investigate a subchannel. Move the allocation
and initialization of the subchannels locks to css_alloc_subchannel.
Clean up the functions involved while at it.
Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/cio/cio.c | 29 | ||||
-rw-r--r-- | drivers/s390/cio/cio.h | 1 | ||||
-rw-r--r-- | drivers/s390/cio/css.c | 36 |
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 | } |
472 | EXPORT_SYMBOL_GPL(cio_disable_subchannel); | 472 | EXPORT_SYMBOL_GPL(cio_disable_subchannel); |
473 | 473 | ||
474 | int 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 | |||
483 | static int cio_check_devno_blacklisted(struct subchannel *sch) | 474 | static 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; | ||
578 | out: | 559 | out: |
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); | |||
121 | int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key); | 121 | int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key); |
122 | int cio_tm_intrg(struct subchannel *sch); | 122 | int cio_tm_intrg(struct subchannel *sch); |
123 | 123 | ||
124 | int cio_create_sch_lock(struct subchannel *); | ||
125 | void do_adapter_IO(u8 isc); | 124 | void do_adapter_IO(u8 isc); |
126 | void do_IRQ(struct pt_regs *); | 125 | void 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 | ||
138 | static void css_sch_todo(struct work_struct *work); | 138 | static void css_sch_todo(struct work_struct *work); |
139 | 139 | ||
140 | static 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 | |||
140 | static void css_subchannel_release(struct device *dev) | 152 | static 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 | |||
184 | err: | ||
185 | kfree(sch); | ||
186 | return ERR_PTR(ret); | ||
167 | } | 187 | } |
168 | 188 | ||
169 | static int css_sch_device_register(struct subchannel *sch) | 189 | static 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; |