diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-11-14 04:44:56 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-11-15 08:08:42 -0500 |
commit | 605c36986c693b811b7ee3b7a0319ec3950d485a (patch) | |
tree | 6840dd0c8d1184c14271a4fcb008ebb300797119 | |
parent | 7b50da53f6ad2048241bef232bfc22a132a40283 (diff) |
s390/scm_block: do not hide eadm subchannel dependency
Stop hiding scm_block's dependency to the eadm subchannel driver
(by using functions provided by the eadm subchannel instead of
wrappers provided by the scm bus).
This will help userspace recognizing module dependencies (e.g. for
building a ramdisk). As a side effect we can get rid of some code
reimplementing refcounting between those modules.
Reported-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/include/asm/eadm.h | 13 | ||||
-rw-r--r-- | drivers/s390/block/scm_blk.c | 24 | ||||
-rw-r--r-- | drivers/s390/block/scm_blk_cluster.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/eadm_sch.c | 10 | ||||
-rw-r--r-- | drivers/s390/cio/scm.c | 45 |
5 files changed, 10 insertions, 84 deletions
diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h index dc9200ca32ed..67026300c88e 100644 --- a/arch/s390/include/asm/eadm.h +++ b/arch/s390/include/asm/eadm.h | |||
@@ -111,18 +111,7 @@ struct scm_driver { | |||
111 | int scm_driver_register(struct scm_driver *scmdrv); | 111 | int scm_driver_register(struct scm_driver *scmdrv); |
112 | void scm_driver_unregister(struct scm_driver *scmdrv); | 112 | void scm_driver_unregister(struct scm_driver *scmdrv); |
113 | 113 | ||
114 | int scm_start_aob(struct aob *aob); | 114 | int eadm_start_aob(struct aob *aob); |
115 | void scm_irq_handler(struct aob *aob, int error); | 115 | void scm_irq_handler(struct aob *aob, int error); |
116 | 116 | ||
117 | struct eadm_ops { | ||
118 | int (*eadm_start) (struct aob *aob); | ||
119 | struct module *owner; | ||
120 | }; | ||
121 | |||
122 | int scm_get_ref(void); | ||
123 | void scm_put_ref(void); | ||
124 | |||
125 | void register_eadm_ops(struct eadm_ops *ops); | ||
126 | void unregister_eadm_ops(struct eadm_ops *ops); | ||
127 | |||
128 | #endif /* _ASM_S390_EADM_H */ | 117 | #endif /* _ASM_S390_EADM_H */ |
diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c index 548209a9c43c..d0ab5019d885 100644 --- a/drivers/s390/block/scm_blk.c +++ b/drivers/s390/block/scm_blk.c | |||
@@ -118,22 +118,6 @@ static void scm_request_done(struct scm_request *scmrq) | |||
118 | spin_unlock_irqrestore(&list_lock, flags); | 118 | spin_unlock_irqrestore(&list_lock, flags); |
119 | } | 119 | } |
120 | 120 | ||
121 | static int scm_open(struct block_device *blkdev, fmode_t mode) | ||
122 | { | ||
123 | return scm_get_ref(); | ||
124 | } | ||
125 | |||
126 | static void scm_release(struct gendisk *gendisk, fmode_t mode) | ||
127 | { | ||
128 | scm_put_ref(); | ||
129 | } | ||
130 | |||
131 | static const struct block_device_operations scm_blk_devops = { | ||
132 | .owner = THIS_MODULE, | ||
133 | .open = scm_open, | ||
134 | .release = scm_release, | ||
135 | }; | ||
136 | |||
137 | static bool scm_permit_request(struct scm_blk_dev *bdev, struct request *req) | 121 | static bool scm_permit_request(struct scm_blk_dev *bdev, struct request *req) |
138 | { | 122 | { |
139 | return rq_data_dir(req) != WRITE || bdev->state != SCM_WR_PROHIBIT; | 123 | return rq_data_dir(req) != WRITE || bdev->state != SCM_WR_PROHIBIT; |
@@ -256,7 +240,7 @@ static void scm_blk_request(struct request_queue *rq) | |||
256 | atomic_inc(&bdev->queued_reqs); | 240 | atomic_inc(&bdev->queued_reqs); |
257 | blk_start_request(req); | 241 | blk_start_request(req); |
258 | 242 | ||
259 | ret = scm_start_aob(scmrq->aob); | 243 | ret = eadm_start_aob(scmrq->aob); |
260 | if (ret) { | 244 | if (ret) { |
261 | SCM_LOG(5, "no subchannel"); | 245 | SCM_LOG(5, "no subchannel"); |
262 | scm_request_requeue(scmrq); | 246 | scm_request_requeue(scmrq); |
@@ -320,7 +304,7 @@ static void scm_blk_handle_error(struct scm_request *scmrq) | |||
320 | } | 304 | } |
321 | 305 | ||
322 | restart: | 306 | restart: |
323 | if (!scm_start_aob(scmrq->aob)) | 307 | if (!eadm_start_aob(scmrq->aob)) |
324 | return; | 308 | return; |
325 | 309 | ||
326 | requeue: | 310 | requeue: |
@@ -363,6 +347,10 @@ static void scm_blk_tasklet(struct scm_blk_dev *bdev) | |||
363 | blk_run_queue(bdev->rq); | 347 | blk_run_queue(bdev->rq); |
364 | } | 348 | } |
365 | 349 | ||
350 | static const struct block_device_operations scm_blk_devops = { | ||
351 | .owner = THIS_MODULE, | ||
352 | }; | ||
353 | |||
366 | int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev) | 354 | int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev) |
367 | { | 355 | { |
368 | struct request_queue *rq; | 356 | struct request_queue *rq; |
diff --git a/drivers/s390/block/scm_blk_cluster.c b/drivers/s390/block/scm_blk_cluster.c index c0d102e3a48b..27f930cd657f 100644 --- a/drivers/s390/block/scm_blk_cluster.c +++ b/drivers/s390/block/scm_blk_cluster.c | |||
@@ -187,7 +187,7 @@ bool scm_need_cluster_request(struct scm_request *scmrq) | |||
187 | void scm_initiate_cluster_request(struct scm_request *scmrq) | 187 | void scm_initiate_cluster_request(struct scm_request *scmrq) |
188 | { | 188 | { |
189 | scm_prepare_cluster_request(scmrq); | 189 | scm_prepare_cluster_request(scmrq); |
190 | if (scm_start_aob(scmrq->aob)) | 190 | if (eadm_start_aob(scmrq->aob)) |
191 | scm_request_requeue(scmrq); | 191 | scm_request_requeue(scmrq); |
192 | } | 192 | } |
193 | 193 | ||
diff --git a/drivers/s390/cio/eadm_sch.c b/drivers/s390/cio/eadm_sch.c index aca7bfc113aa..3a2ee4a740b4 100644 --- a/drivers/s390/cio/eadm_sch.c +++ b/drivers/s390/cio/eadm_sch.c | |||
@@ -190,7 +190,7 @@ static struct subchannel *eadm_get_idle_sch(void) | |||
190 | return NULL; | 190 | return NULL; |
191 | } | 191 | } |
192 | 192 | ||
193 | static int eadm_start_aob(struct aob *aob) | 193 | int eadm_start_aob(struct aob *aob) |
194 | { | 194 | { |
195 | struct eadm_private *private; | 195 | struct eadm_private *private; |
196 | struct subchannel *sch; | 196 | struct subchannel *sch; |
@@ -218,6 +218,7 @@ out_unlock: | |||
218 | 218 | ||
219 | return ret; | 219 | return ret; |
220 | } | 220 | } |
221 | EXPORT_SYMBOL_GPL(eadm_start_aob); | ||
221 | 222 | ||
222 | static int eadm_subchannel_probe(struct subchannel *sch) | 223 | static int eadm_subchannel_probe(struct subchannel *sch) |
223 | { | 224 | { |
@@ -380,11 +381,6 @@ static struct css_driver eadm_subchannel_driver = { | |||
380 | .restore = eadm_subchannel_restore, | 381 | .restore = eadm_subchannel_restore, |
381 | }; | 382 | }; |
382 | 383 | ||
383 | static struct eadm_ops eadm_ops = { | ||
384 | .eadm_start = eadm_start_aob, | ||
385 | .owner = THIS_MODULE, | ||
386 | }; | ||
387 | |||
388 | static int __init eadm_sch_init(void) | 384 | static int __init eadm_sch_init(void) |
389 | { | 385 | { |
390 | int ret; | 386 | int ret; |
@@ -404,7 +400,6 @@ static int __init eadm_sch_init(void) | |||
404 | if (ret) | 400 | if (ret) |
405 | goto cleanup; | 401 | goto cleanup; |
406 | 402 | ||
407 | register_eadm_ops(&eadm_ops); | ||
408 | return ret; | 403 | return ret; |
409 | 404 | ||
410 | cleanup: | 405 | cleanup: |
@@ -415,7 +410,6 @@ cleanup: | |||
415 | 410 | ||
416 | static void __exit eadm_sch_exit(void) | 411 | static void __exit eadm_sch_exit(void) |
417 | { | 412 | { |
418 | unregister_eadm_ops(&eadm_ops); | ||
419 | css_driver_unregister(&eadm_subchannel_driver); | 413 | css_driver_unregister(&eadm_subchannel_driver); |
420 | isc_unregister(EADM_SCH_ISC); | 414 | isc_unregister(EADM_SCH_ISC); |
421 | debug_unregister(eadm_debug); | 415 | debug_unregister(eadm_debug); |
diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c index 46ec25632e8b..15268edc54ae 100644 --- a/drivers/s390/cio/scm.c +++ b/drivers/s390/cio/scm.c | |||
@@ -15,8 +15,6 @@ | |||
15 | #include "chsc.h" | 15 | #include "chsc.h" |
16 | 16 | ||
17 | static struct device *scm_root; | 17 | static struct device *scm_root; |
18 | static struct eadm_ops *eadm_ops; | ||
19 | static DEFINE_MUTEX(eadm_ops_mutex); | ||
20 | 18 | ||
21 | #define to_scm_dev(n) container_of(n, struct scm_device, dev) | 19 | #define to_scm_dev(n) container_of(n, struct scm_device, dev) |
22 | #define to_scm_drv(d) container_of(d, struct scm_driver, drv) | 20 | #define to_scm_drv(d) container_of(d, struct scm_driver, drv) |
@@ -73,49 +71,6 @@ void scm_driver_unregister(struct scm_driver *scmdrv) | |||
73 | } | 71 | } |
74 | EXPORT_SYMBOL_GPL(scm_driver_unregister); | 72 | EXPORT_SYMBOL_GPL(scm_driver_unregister); |
75 | 73 | ||
76 | int scm_get_ref(void) | ||
77 | { | ||
78 | int ret = 0; | ||
79 | |||
80 | mutex_lock(&eadm_ops_mutex); | ||
81 | if (!eadm_ops || !try_module_get(eadm_ops->owner)) | ||
82 | ret = -ENOENT; | ||
83 | mutex_unlock(&eadm_ops_mutex); | ||
84 | |||
85 | return ret; | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(scm_get_ref); | ||
88 | |||
89 | void scm_put_ref(void) | ||
90 | { | ||
91 | mutex_lock(&eadm_ops_mutex); | ||
92 | module_put(eadm_ops->owner); | ||
93 | mutex_unlock(&eadm_ops_mutex); | ||
94 | } | ||
95 | EXPORT_SYMBOL_GPL(scm_put_ref); | ||
96 | |||
97 | void register_eadm_ops(struct eadm_ops *ops) | ||
98 | { | ||
99 | mutex_lock(&eadm_ops_mutex); | ||
100 | eadm_ops = ops; | ||
101 | mutex_unlock(&eadm_ops_mutex); | ||
102 | } | ||
103 | EXPORT_SYMBOL_GPL(register_eadm_ops); | ||
104 | |||
105 | void unregister_eadm_ops(struct eadm_ops *ops) | ||
106 | { | ||
107 | mutex_lock(&eadm_ops_mutex); | ||
108 | eadm_ops = NULL; | ||
109 | mutex_unlock(&eadm_ops_mutex); | ||
110 | } | ||
111 | EXPORT_SYMBOL_GPL(unregister_eadm_ops); | ||
112 | |||
113 | int scm_start_aob(struct aob *aob) | ||
114 | { | ||
115 | return eadm_ops->eadm_start(aob); | ||
116 | } | ||
117 | EXPORT_SYMBOL_GPL(scm_start_aob); | ||
118 | |||
119 | void scm_irq_handler(struct aob *aob, int error) | 74 | void scm_irq_handler(struct aob *aob, int error) |
120 | { | 75 | { |
121 | struct aob_rq_header *aobrq = (void *) aob->request.data; | 76 | struct aob_rq_header *aobrq = (void *) aob->request.data; |