aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mic/scif/scif_fd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mic/scif/scif_fd.c')
-rw-r--r--drivers/misc/mic/scif/scif_fd.c178
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
37static 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
44static 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
37static int scif_fdflush(struct file *f, fl_owner_t id) 51static 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:
290getnodes_err2: 305getnodes_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(&reg, 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;
335reg_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);
349unreg_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(&copy, 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);
364readfrom_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(&copy, 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);
379writeto_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(&copy, 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);
394vreadfrom_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(&copy, 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);
409vwriteto_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 }
431fence_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);
455fence_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};