diff options
Diffstat (limited to 'drivers/misc/mic/scif/scif_fd.c')
-rw-r--r-- | drivers/misc/mic/scif/scif_fd.c | 178 |
1 files changed, 173 insertions, 5 deletions
diff --git a/drivers/misc/mic/scif/scif_fd.c b/drivers/misc/mic/scif/scif_fd.c index eccf7e7135f9..f7e826142a72 100644 --- a/drivers/misc/mic/scif/scif_fd.c +++ b/drivers/misc/mic/scif/scif_fd.c | |||
@@ -34,6 +34,20 @@ static int scif_fdclose(struct inode *inode, struct file *f) | |||
34 | return scif_close(priv); | 34 | return scif_close(priv); |
35 | } | 35 | } |
36 | 36 | ||
37 | static int scif_fdmmap(struct file *f, struct vm_area_struct *vma) | ||
38 | { | ||
39 | struct scif_endpt *priv = f->private_data; | ||
40 | |||
41 | return scif_mmap(vma, priv); | ||
42 | } | ||
43 | |||
44 | static unsigned int scif_fdpoll(struct file *f, poll_table *wait) | ||
45 | { | ||
46 | struct scif_endpt *priv = f->private_data; | ||
47 | |||
48 | return __scif_pollfd(f, wait, priv); | ||
49 | } | ||
50 | |||
37 | static int scif_fdflush(struct file *f, fl_owner_t id) | 51 | static int scif_fdflush(struct file *f, fl_owner_t id) |
38 | { | 52 | { |
39 | struct scif_endpt *ep = f->private_data; | 53 | struct scif_endpt *ep = f->private_data; |
@@ -140,12 +154,12 @@ static long scif_fdioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
140 | * Add to the list of user mode eps where the second half | 154 | * Add to the list of user mode eps where the second half |
141 | * of the accept is not yet completed. | 155 | * of the accept is not yet completed. |
142 | */ | 156 | */ |
143 | spin_lock(&scif_info.eplock); | 157 | mutex_lock(&scif_info.eplock); |
144 | list_add_tail(&((*ep)->miacceptlist), &scif_info.uaccept); | 158 | list_add_tail(&((*ep)->miacceptlist), &scif_info.uaccept); |
145 | list_add_tail(&((*ep)->liacceptlist), &priv->li_accept); | 159 | list_add_tail(&((*ep)->liacceptlist), &priv->li_accept); |
146 | (*ep)->listenep = priv; | 160 | (*ep)->listenep = priv; |
147 | priv->acceptcnt++; | 161 | priv->acceptcnt++; |
148 | spin_unlock(&scif_info.eplock); | 162 | mutex_unlock(&scif_info.eplock); |
149 | 163 | ||
150 | return 0; | 164 | return 0; |
151 | } | 165 | } |
@@ -163,7 +177,7 @@ static long scif_fdioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
163 | return -EFAULT; | 177 | return -EFAULT; |
164 | 178 | ||
165 | /* Remove form the user accept queue */ | 179 | /* Remove form the user accept queue */ |
166 | spin_lock(&scif_info.eplock); | 180 | mutex_lock(&scif_info.eplock); |
167 | list_for_each_safe(pos, tmpq, &scif_info.uaccept) { | 181 | list_for_each_safe(pos, tmpq, &scif_info.uaccept) { |
168 | tmpep = list_entry(pos, | 182 | tmpep = list_entry(pos, |
169 | struct scif_endpt, miacceptlist); | 183 | struct scif_endpt, miacceptlist); |
@@ -175,7 +189,7 @@ static long scif_fdioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
175 | } | 189 | } |
176 | 190 | ||
177 | if (!fep) { | 191 | if (!fep) { |
178 | spin_unlock(&scif_info.eplock); | 192 | mutex_unlock(&scif_info.eplock); |
179 | return -ENOENT; | 193 | return -ENOENT; |
180 | } | 194 | } |
181 | 195 | ||
@@ -190,9 +204,10 @@ static long scif_fdioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
190 | } | 204 | } |
191 | } | 205 | } |
192 | 206 | ||
193 | spin_unlock(&scif_info.eplock); | 207 | mutex_unlock(&scif_info.eplock); |
194 | 208 | ||
195 | /* Free the resources automatically created from the open. */ | 209 | /* Free the resources automatically created from the open. */ |
210 | scif_anon_inode_fput(priv); | ||
196 | scif_teardown_ep(priv); | 211 | scif_teardown_ep(priv); |
197 | scif_add_epd_to_zombie_list(priv, !SCIF_EPLOCK_HELD); | 212 | scif_add_epd_to_zombie_list(priv, !SCIF_EPLOCK_HELD); |
198 | f->private_data = newep; | 213 | f->private_data = newep; |
@@ -290,6 +305,157 @@ getnodes_err1: | |||
290 | getnodes_err2: | 305 | getnodes_err2: |
291 | return err; | 306 | return err; |
292 | } | 307 | } |
308 | case SCIF_REG: | ||
309 | { | ||
310 | struct scif_endpt *priv = f->private_data; | ||
311 | struct scifioctl_reg reg; | ||
312 | off_t ret; | ||
313 | |||
314 | if (copy_from_user(®, argp, sizeof(reg))) { | ||
315 | err = -EFAULT; | ||
316 | goto reg_err; | ||
317 | } | ||
318 | if (reg.flags & SCIF_MAP_KERNEL) { | ||
319 | err = -EINVAL; | ||
320 | goto reg_err; | ||
321 | } | ||
322 | ret = scif_register(priv, (void *)reg.addr, reg.len, | ||
323 | reg.offset, reg.prot, reg.flags); | ||
324 | if (ret < 0) { | ||
325 | err = (int)ret; | ||
326 | goto reg_err; | ||
327 | } | ||
328 | |||
329 | if (copy_to_user(&((struct scifioctl_reg __user *)argp) | ||
330 | ->out_offset, &ret, sizeof(reg.out_offset))) { | ||
331 | err = -EFAULT; | ||
332 | goto reg_err; | ||
333 | } | ||
334 | err = 0; | ||
335 | reg_err: | ||
336 | scif_err_debug(err, "scif_register"); | ||
337 | return err; | ||
338 | } | ||
339 | case SCIF_UNREG: | ||
340 | { | ||
341 | struct scif_endpt *priv = f->private_data; | ||
342 | struct scifioctl_unreg unreg; | ||
343 | |||
344 | if (copy_from_user(&unreg, argp, sizeof(unreg))) { | ||
345 | err = -EFAULT; | ||
346 | goto unreg_err; | ||
347 | } | ||
348 | err = scif_unregister(priv, unreg.offset, unreg.len); | ||
349 | unreg_err: | ||
350 | scif_err_debug(err, "scif_unregister"); | ||
351 | return err; | ||
352 | } | ||
353 | case SCIF_READFROM: | ||
354 | { | ||
355 | struct scif_endpt *priv = f->private_data; | ||
356 | struct scifioctl_copy copy; | ||
357 | |||
358 | if (copy_from_user(©, argp, sizeof(copy))) { | ||
359 | err = -EFAULT; | ||
360 | goto readfrom_err; | ||
361 | } | ||
362 | err = scif_readfrom(priv, copy.loffset, copy.len, copy.roffset, | ||
363 | copy.flags); | ||
364 | readfrom_err: | ||
365 | scif_err_debug(err, "scif_readfrom"); | ||
366 | return err; | ||
367 | } | ||
368 | case SCIF_WRITETO: | ||
369 | { | ||
370 | struct scif_endpt *priv = f->private_data; | ||
371 | struct scifioctl_copy copy; | ||
372 | |||
373 | if (copy_from_user(©, argp, sizeof(copy))) { | ||
374 | err = -EFAULT; | ||
375 | goto writeto_err; | ||
376 | } | ||
377 | err = scif_writeto(priv, copy.loffset, copy.len, copy.roffset, | ||
378 | copy.flags); | ||
379 | writeto_err: | ||
380 | scif_err_debug(err, "scif_writeto"); | ||
381 | return err; | ||
382 | } | ||
383 | case SCIF_VREADFROM: | ||
384 | { | ||
385 | struct scif_endpt *priv = f->private_data; | ||
386 | struct scifioctl_copy copy; | ||
387 | |||
388 | if (copy_from_user(©, argp, sizeof(copy))) { | ||
389 | err = -EFAULT; | ||
390 | goto vreadfrom_err; | ||
391 | } | ||
392 | err = scif_vreadfrom(priv, (void __force *)copy.addr, copy.len, | ||
393 | copy.roffset, copy.flags); | ||
394 | vreadfrom_err: | ||
395 | scif_err_debug(err, "scif_vreadfrom"); | ||
396 | return err; | ||
397 | } | ||
398 | case SCIF_VWRITETO: | ||
399 | { | ||
400 | struct scif_endpt *priv = f->private_data; | ||
401 | struct scifioctl_copy copy; | ||
402 | |||
403 | if (copy_from_user(©, argp, sizeof(copy))) { | ||
404 | err = -EFAULT; | ||
405 | goto vwriteto_err; | ||
406 | } | ||
407 | err = scif_vwriteto(priv, (void __force *)copy.addr, copy.len, | ||
408 | copy.roffset, copy.flags); | ||
409 | vwriteto_err: | ||
410 | scif_err_debug(err, "scif_vwriteto"); | ||
411 | return err; | ||
412 | } | ||
413 | case SCIF_FENCE_MARK: | ||
414 | { | ||
415 | struct scif_endpt *priv = f->private_data; | ||
416 | struct scifioctl_fence_mark mark; | ||
417 | int tmp_mark = 0; | ||
418 | |||
419 | if (copy_from_user(&mark, argp, sizeof(mark))) { | ||
420 | err = -EFAULT; | ||
421 | goto fence_mark_err; | ||
422 | } | ||
423 | err = scif_fence_mark(priv, mark.flags, &tmp_mark); | ||
424 | if (err) | ||
425 | goto fence_mark_err; | ||
426 | if (copy_to_user((void __user *)mark.mark, &tmp_mark, | ||
427 | sizeof(tmp_mark))) { | ||
428 | err = -EFAULT; | ||
429 | goto fence_mark_err; | ||
430 | } | ||
431 | fence_mark_err: | ||
432 | scif_err_debug(err, "scif_fence_mark"); | ||
433 | return err; | ||
434 | } | ||
435 | case SCIF_FENCE_WAIT: | ||
436 | { | ||
437 | struct scif_endpt *priv = f->private_data; | ||
438 | |||
439 | err = scif_fence_wait(priv, arg); | ||
440 | scif_err_debug(err, "scif_fence_wait"); | ||
441 | return err; | ||
442 | } | ||
443 | case SCIF_FENCE_SIGNAL: | ||
444 | { | ||
445 | struct scif_endpt *priv = f->private_data; | ||
446 | struct scifioctl_fence_signal signal; | ||
447 | |||
448 | if (copy_from_user(&signal, argp, sizeof(signal))) { | ||
449 | err = -EFAULT; | ||
450 | goto fence_signal_err; | ||
451 | } | ||
452 | |||
453 | err = scif_fence_signal(priv, signal.loff, signal.lval, | ||
454 | signal.roff, signal.rval, signal.flags); | ||
455 | fence_signal_err: | ||
456 | scif_err_debug(err, "scif_fence_signal"); | ||
457 | return err; | ||
458 | } | ||
293 | } | 459 | } |
294 | return -EINVAL; | 460 | return -EINVAL; |
295 | } | 461 | } |
@@ -298,6 +464,8 @@ const struct file_operations scif_fops = { | |||
298 | .open = scif_fdopen, | 464 | .open = scif_fdopen, |
299 | .release = scif_fdclose, | 465 | .release = scif_fdclose, |
300 | .unlocked_ioctl = scif_fdioctl, | 466 | .unlocked_ioctl = scif_fdioctl, |
467 | .mmap = scif_fdmmap, | ||
468 | .poll = scif_fdpoll, | ||
301 | .flush = scif_fdflush, | 469 | .flush = scif_fdflush, |
302 | .owner = THIS_MODULE, | 470 | .owner = THIS_MODULE, |
303 | }; | 471 | }; |