aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDennis Dalessandro <dennis.dalessandro@intel.com>2016-05-19 08:26:31 -0400
committerDoug Ledford <dledford@redhat.com>2016-05-26 11:35:13 -0400
commit380fb942888e7afc3420ce195a5188ff73b5a782 (patch)
tree337040fcbbe73690947f73ccf32f3e96e9d03103
parent8d970cf991a6c38a5566572979487b906d643740 (diff)
IB/hfi1: Remove write(), use ioctl() for user cmds
Remove the write() handler for user space commands now that ioctl handling is available. User apps will need to change to use ioctl from this point forward. Reviewed-by: Mitko Haralanov <mitko.haralanov@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/staging/rdma/hfi1/file_ops.c226
-rw-r--r--include/uapi/rdma/hfi/hfi1_user.h8
2 files changed, 1 insertions, 233 deletions
diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c
index a338238bef92..c46eadadf3bf 100644
--- a/drivers/staging/rdma/hfi1/file_ops.c
+++ b/drivers/staging/rdma/hfi1/file_ops.c
@@ -72,8 +72,6 @@
72 */ 72 */
73static int hfi1_file_open(struct inode *, struct file *); 73static int hfi1_file_open(struct inode *, struct file *);
74static int hfi1_file_close(struct inode *, struct file *); 74static int hfi1_file_close(struct inode *, struct file *);
75static ssize_t hfi1_file_write(struct file *, const char __user *,
76 size_t, loff_t *);
77static ssize_t hfi1_write_iter(struct kiocb *, struct iov_iter *); 75static ssize_t hfi1_write_iter(struct kiocb *, struct iov_iter *);
78static unsigned int hfi1_poll(struct file *, struct poll_table_struct *); 76static unsigned int hfi1_poll(struct file *, struct poll_table_struct *);
79static int hfi1_file_mmap(struct file *, struct vm_area_struct *); 77static int hfi1_file_mmap(struct file *, struct vm_area_struct *);
@@ -101,7 +99,6 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
101 99
102static const struct file_operations hfi1_file_ops = { 100static const struct file_operations hfi1_file_ops = {
103 .owner = THIS_MODULE, 101 .owner = THIS_MODULE,
104 .write = hfi1_file_write,
105 .write_iter = hfi1_write_iter, 102 .write_iter = hfi1_write_iter,
106 .open = hfi1_file_open, 103 .open = hfi1_file_open,
107 .release = hfi1_file_close, 104 .release = hfi1_file_close,
@@ -379,229 +376,6 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
379 return ret; 376 return ret;
380} 377}
381 378
382static ssize_t hfi1_file_write(struct file *fp, const char __user *data,
383 size_t count, loff_t *offset)
384{
385 const struct hfi1_cmd __user *ucmd;
386 struct hfi1_filedata *fd = fp->private_data;
387 struct hfi1_ctxtdata *uctxt = fd->uctxt;
388 struct hfi1_cmd cmd;
389 struct hfi1_user_info uinfo;
390 struct hfi1_tid_info tinfo;
391 unsigned long addr;
392 ssize_t consumed = 0, copy = 0, ret = 0;
393 void *dest = NULL;
394 __u64 user_val = 0;
395 int uctxt_required = 1;
396
397 /* FIXME: This interface cannot continue out of staging */
398 if (WARN_ON_ONCE(!ib_safe_file_access(fp)))
399 return -EACCES;
400
401 if (count < sizeof(cmd)) {
402 ret = -EINVAL;
403 goto bail;
404 }
405
406 ucmd = (const struct hfi1_cmd __user *)data;
407 if (copy_from_user(&cmd, ucmd, sizeof(cmd))) {
408 ret = -EFAULT;
409 goto bail;
410 }
411
412 consumed = sizeof(cmd);
413
414 switch (cmd.type) {
415 case HFI1_CMD_ASSIGN_CTXT:
416 uctxt_required = 0; /* assigned user context not required */
417 copy = sizeof(uinfo);
418 dest = &uinfo;
419 break;
420 case HFI1_CMD_CREDIT_UPD:
421 copy = 0;
422 break;
423 case HFI1_CMD_TID_UPDATE:
424 case HFI1_CMD_TID_FREE:
425 case HFI1_CMD_TID_INVAL_READ:
426 copy = sizeof(tinfo);
427 dest = &tinfo;
428 break;
429 case HFI1_CMD_USER_INFO:
430 case HFI1_CMD_RECV_CTRL:
431 case HFI1_CMD_POLL_TYPE:
432 case HFI1_CMD_ACK_EVENT:
433 case HFI1_CMD_CTXT_INFO:
434 case HFI1_CMD_SET_PKEY:
435 case HFI1_CMD_CTXT_RESET:
436 copy = 0;
437 user_val = cmd.addr;
438 break;
439 default:
440 ret = -EINVAL;
441 goto bail;
442 }
443
444 /* If the command comes with user data, copy it. */
445 if (copy) {
446 if (copy_from_user(dest, (void __user *)cmd.addr, copy)) {
447 ret = -EFAULT;
448 goto bail;
449 }
450 consumed += copy;
451 }
452
453 /*
454 * Make sure there is a uctxt when needed.
455 */
456 if (uctxt_required && !uctxt) {
457 ret = -EINVAL;
458 goto bail;
459 }
460
461 switch (cmd.type) {
462 case HFI1_CMD_ASSIGN_CTXT:
463 ret = assign_ctxt(fp, &uinfo);
464 if (ret < 0)
465 goto bail;
466 ret = setup_ctxt(fp);
467 if (ret)
468 goto bail;
469 ret = user_init(fp);
470 break;
471 case HFI1_CMD_CTXT_INFO:
472 ret = get_ctxt_info(fp, (void __user *)(unsigned long)
473 user_val, cmd.len);
474 break;
475 case HFI1_CMD_USER_INFO:
476 ret = get_base_info(fp, (void __user *)(unsigned long)
477 user_val, cmd.len);
478 break;
479 case HFI1_CMD_CREDIT_UPD:
480 if (uctxt && uctxt->sc)
481 sc_return_credits(uctxt->sc);
482 break;
483 case HFI1_CMD_TID_UPDATE:
484 ret = hfi1_user_exp_rcv_setup(fp, &tinfo);
485 if (!ret) {
486 /*
487 * Copy the number of tidlist entries we used
488 * and the length of the buffer we registered.
489 * These fields are adjacent in the structure so
490 * we can copy them at the same time.
491 */
492 addr = (unsigned long)cmd.addr +
493 offsetof(struct hfi1_tid_info, tidcnt);
494 if (copy_to_user((void __user *)addr, &tinfo.tidcnt,
495 sizeof(tinfo.tidcnt) +
496 sizeof(tinfo.length)))
497 ret = -EFAULT;
498 }
499 break;
500 case HFI1_CMD_TID_INVAL_READ:
501 ret = hfi1_user_exp_rcv_invalid(fp, &tinfo);
502 if (ret)
503 break;
504 addr = (unsigned long)cmd.addr +
505 offsetof(struct hfi1_tid_info, tidcnt);
506 if (copy_to_user((void __user *)addr, &tinfo.tidcnt,
507 sizeof(tinfo.tidcnt)))
508 ret = -EFAULT;
509 break;
510 case HFI1_CMD_TID_FREE:
511 ret = hfi1_user_exp_rcv_clear(fp, &tinfo);
512 if (ret)
513 break;
514 addr = (unsigned long)cmd.addr +
515 offsetof(struct hfi1_tid_info, tidcnt);
516 if (copy_to_user((void __user *)addr, &tinfo.tidcnt,
517 sizeof(tinfo.tidcnt)))
518 ret = -EFAULT;
519 break;
520 case HFI1_CMD_RECV_CTRL:
521 ret = manage_rcvq(uctxt, fd->subctxt, (int)user_val);
522 break;
523 case HFI1_CMD_POLL_TYPE:
524 uctxt->poll_type = (typeof(uctxt->poll_type))user_val;
525 break;
526 case HFI1_CMD_ACK_EVENT:
527 ret = user_event_ack(uctxt, fd->subctxt, user_val);
528 break;
529 case HFI1_CMD_SET_PKEY:
530 if (HFI1_CAP_IS_USET(PKEY_CHECK))
531 ret = set_ctxt_pkey(uctxt, fd->subctxt, user_val);
532 else
533 ret = -EPERM;
534 break;
535 case HFI1_CMD_CTXT_RESET: {
536 struct send_context *sc;
537 struct hfi1_devdata *dd;
538
539 if (!uctxt || !uctxt->dd || !uctxt->sc) {
540 ret = -EINVAL;
541 break;
542 }
543 /*
544 * There is no protection here. User level has to
545 * guarantee that no one will be writing to the send
546 * context while it is being re-initialized.
547 * If user level breaks that guarantee, it will break
548 * it's own context and no one else's.
549 */
550 dd = uctxt->dd;
551 sc = uctxt->sc;
552 /*
553 * Wait until the interrupt handler has marked the
554 * context as halted or frozen. Report error if we time
555 * out.
556 */
557 wait_event_interruptible_timeout(
558 sc->halt_wait, (sc->flags & SCF_HALTED),
559 msecs_to_jiffies(SEND_CTXT_HALT_TIMEOUT));
560 if (!(sc->flags & SCF_HALTED)) {
561 ret = -ENOLCK;
562 break;
563 }
564 /*
565 * If the send context was halted due to a Freeze,
566 * wait until the device has been "unfrozen" before
567 * resetting the context.
568 */
569 if (sc->flags & SCF_FROZEN) {
570 wait_event_interruptible_timeout(
571 dd->event_queue,
572 !(ACCESS_ONCE(dd->flags) & HFI1_FROZEN),
573 msecs_to_jiffies(SEND_CTXT_HALT_TIMEOUT));
574 if (dd->flags & HFI1_FROZEN) {
575 ret = -ENOLCK;
576 break;
577 }
578 if (dd->flags & HFI1_FORCED_FREEZE) {
579 /*
580 * Don't allow context reset if we are into
581 * forced freeze
582 */
583 ret = -ENODEV;
584 break;
585 }
586 sc_disable(sc);
587 ret = sc_enable(sc);
588 hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_ENB,
589 uctxt->ctxt);
590 } else {
591 ret = sc_restart(sc);
592 }
593 if (!ret)
594 sc_return_credits(sc);
595 break;
596 }
597 }
598
599 if (ret >= 0)
600 ret = consumed;
601bail:
602 return ret;
603}
604
605static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from) 379static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from)
606{ 380{
607 struct hfi1_filedata *fd = kiocb->ki_filp->private_data; 381 struct hfi1_filedata *fd = kiocb->ki_filp->private_data;
diff --git a/include/uapi/rdma/hfi/hfi1_user.h b/include/uapi/rdma/hfi/hfi1_user.h
index 9784159c9d52..98bebf8bef55 100644
--- a/include/uapi/rdma/hfi/hfi1_user.h
+++ b/include/uapi/rdma/hfi/hfi1_user.h
@@ -66,7 +66,7 @@
66 * The major version changes when data structures change in an incompatible 66 * The major version changes when data structures change in an incompatible
67 * way. The driver must be the same for initialization to succeed. 67 * way. The driver must be the same for initialization to succeed.
68 */ 68 */
69#define HFI1_USER_SWMAJOR 5 69#define HFI1_USER_SWMAJOR 6
70 70
71/* 71/*
72 * Minor version differences are always compatible 72 * Minor version differences are always compatible
@@ -265,12 +265,6 @@ struct hfi1_tid_info {
265 __u32 length; 265 __u32 length;
266}; 266};
267 267
268struct hfi1_cmd {
269 __u32 type; /* command type */
270 __u32 len; /* length of struct pointed to by add */
271 __u64 addr; /* pointer to user structure */
272};
273
274enum hfi1_sdma_comp_state { 268enum hfi1_sdma_comp_state {
275 FREE = 0, 269 FREE = 0,
276 QUEUED, 270 QUEUED,