diff options
Diffstat (limited to 'drivers/block/viodasd.c')
-rw-r--r-- | drivers/block/viodasd.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index 5663d3c284c8..f651e51a3319 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/string.h> | 43 | #include <linux/string.h> |
44 | #include <linux/smp_lock.h> | ||
44 | #include <linux/dma-mapping.h> | 45 | #include <linux/dma-mapping.h> |
45 | #include <linux/completion.h> | 46 | #include <linux/completion.h> |
46 | #include <linux/device.h> | 47 | #include <linux/device.h> |
@@ -175,6 +176,18 @@ static int viodasd_open(struct block_device *bdev, fmode_t mode) | |||
175 | return 0; | 176 | return 0; |
176 | } | 177 | } |
177 | 178 | ||
179 | static int viodasd_unlocked_open(struct block_device *bdev, fmode_t mode) | ||
180 | { | ||
181 | int ret; | ||
182 | |||
183 | lock_kernel(); | ||
184 | ret = viodasd_open(bdev, mode); | ||
185 | unlock_kernel(); | ||
186 | |||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | |||
178 | /* | 191 | /* |
179 | * External release entry point. | 192 | * External release entry point. |
180 | */ | 193 | */ |
@@ -183,6 +196,7 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode) | |||
183 | struct viodasd_device *d = disk->private_data; | 196 | struct viodasd_device *d = disk->private_data; |
184 | HvLpEvent_Rc hvrc; | 197 | HvLpEvent_Rc hvrc; |
185 | 198 | ||
199 | lock_kernel(); | ||
186 | /* Send the event to OS/400. We DON'T expect a response */ | 200 | /* Send the event to OS/400. We DON'T expect a response */ |
187 | hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, | 201 | hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, |
188 | HvLpEvent_Type_VirtualIo, | 202 | HvLpEvent_Type_VirtualIo, |
@@ -195,6 +209,9 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode) | |||
195 | 0, 0, 0); | 209 | 0, 0, 0); |
196 | if (hvrc != 0) | 210 | if (hvrc != 0) |
197 | pr_warning("HV close call failed %d\n", (int)hvrc); | 211 | pr_warning("HV close call failed %d\n", (int)hvrc); |
212 | |||
213 | unlock_kernel(); | ||
214 | |||
198 | return 0; | 215 | return 0; |
199 | } | 216 | } |
200 | 217 | ||
@@ -219,7 +236,7 @@ static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
219 | */ | 236 | */ |
220 | static const struct block_device_operations viodasd_fops = { | 237 | static const struct block_device_operations viodasd_fops = { |
221 | .owner = THIS_MODULE, | 238 | .owner = THIS_MODULE, |
222 | .open = viodasd_open, | 239 | .open = viodasd_unlocked_open, |
223 | .release = viodasd_release, | 240 | .release = viodasd_release, |
224 | .getgeo = viodasd_getgeo, | 241 | .getgeo = viodasd_getgeo, |
225 | }; | 242 | }; |