diff options
Diffstat (limited to 'drivers/s390/char/vmcp.c')
-rw-r--r-- | drivers/s390/char/vmcp.c | 37 |
1 files changed, 13 insertions, 24 deletions
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 2f419b0ea628..401ea84b3059 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c | |||
@@ -61,30 +61,24 @@ static int vmcp_release(struct inode *inode, struct file *file) | |||
61 | static ssize_t | 61 | static ssize_t |
62 | vmcp_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) | 62 | vmcp_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) |
63 | { | 63 | { |
64 | size_t tocopy; | 64 | ssize_t ret; |
65 | size_t size; | ||
65 | struct vmcp_session *session; | 66 | struct vmcp_session *session; |
66 | 67 | ||
67 | session = (struct vmcp_session *)file->private_data; | 68 | session = file->private_data; |
68 | if (mutex_lock_interruptible(&session->mutex)) | 69 | if (mutex_lock_interruptible(&session->mutex)) |
69 | return -ERESTARTSYS; | 70 | return -ERESTARTSYS; |
70 | if (!session->response) { | 71 | if (!session->response) { |
71 | mutex_unlock(&session->mutex); | 72 | mutex_unlock(&session->mutex); |
72 | return 0; | 73 | return 0; |
73 | } | 74 | } |
74 | if (*ppos > session->resp_size) { | 75 | size = min_t(size_t, session->resp_size, session->bufsize); |
75 | mutex_unlock(&session->mutex); | 76 | ret = simple_read_from_buffer(buff, count, ppos, |
76 | return 0; | 77 | session->response, size); |
77 | } | ||
78 | tocopy = min(session->resp_size - (size_t) (*ppos), count); | ||
79 | tocopy = min(tocopy, session->bufsize - (size_t) (*ppos)); | ||
80 | 78 | ||
81 | if (copy_to_user(buff, session->response + (*ppos), tocopy)) { | ||
82 | mutex_unlock(&session->mutex); | ||
83 | return -EFAULT; | ||
84 | } | ||
85 | mutex_unlock(&session->mutex); | 79 | mutex_unlock(&session->mutex); |
86 | *ppos += tocopy; | 80 | |
87 | return tocopy; | 81 | return ret; |
88 | } | 82 | } |
89 | 83 | ||
90 | static ssize_t | 84 | static ssize_t |
@@ -198,27 +192,23 @@ static int __init vmcp_init(void) | |||
198 | PRINT_WARN("z/VM CP interface is only available under z/VM\n"); | 192 | PRINT_WARN("z/VM CP interface is only available under z/VM\n"); |
199 | return -ENODEV; | 193 | return -ENODEV; |
200 | } | 194 | } |
195 | |||
201 | vmcp_debug = debug_register("vmcp", 1, 1, 240); | 196 | vmcp_debug = debug_register("vmcp", 1, 1, 240); |
202 | if (!vmcp_debug) { | 197 | if (!vmcp_debug) |
203 | PRINT_ERR("z/VM CP interface not loaded. Could not register " | ||
204 | "debug feature\n"); | ||
205 | return -ENOMEM; | 198 | return -ENOMEM; |
206 | } | 199 | |
207 | ret = debug_register_view(vmcp_debug, &debug_hex_ascii_view); | 200 | ret = debug_register_view(vmcp_debug, &debug_hex_ascii_view); |
208 | if (ret) { | 201 | if (ret) { |
209 | PRINT_ERR("z/VM CP interface not loaded. Could not register " | ||
210 | "debug feature view. Error code: %d\n", ret); | ||
211 | debug_unregister(vmcp_debug); | 202 | debug_unregister(vmcp_debug); |
212 | return ret; | 203 | return ret; |
213 | } | 204 | } |
205 | |||
214 | ret = misc_register(&vmcp_dev); | 206 | ret = misc_register(&vmcp_dev); |
215 | if (ret) { | 207 | if (ret) { |
216 | PRINT_ERR("z/VM CP interface not loaded. Could not register " | ||
217 | "misc device. Error code: %d\n", ret); | ||
218 | debug_unregister(vmcp_debug); | 208 | debug_unregister(vmcp_debug); |
219 | return ret; | 209 | return ret; |
220 | } | 210 | } |
221 | PRINT_INFO("z/VM CP interface loaded\n"); | 211 | |
222 | return 0; | 212 | return 0; |
223 | } | 213 | } |
224 | 214 | ||
@@ -226,7 +216,6 @@ static void __exit vmcp_exit(void) | |||
226 | { | 216 | { |
227 | misc_deregister(&vmcp_dev); | 217 | misc_deregister(&vmcp_dev); |
228 | debug_unregister(vmcp_debug); | 218 | debug_unregister(vmcp_debug); |
229 | PRINT_INFO("z/VM CP interface unloaded.\n"); | ||
230 | } | 219 | } |
231 | 220 | ||
232 | module_init(vmcp_init); | 221 | module_init(vmcp_init); |