Skip to content

Commit

Permalink
PTP: introduce new versions of IOCTLs
Browse files Browse the repository at this point in the history
The current version of the IOCTL have a small problem which prevents us
from extending the API by making use of reserved fields. In these new
IOCTLs, we are now making sure that flags and rsv fields are zero which
will allow us to extend the API in the future.

Reviewed-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Felipe Balbi authored and davem330 committed Sep 13, 2019
1 parent 6cd476d commit 4156065
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 1 deletion.
63 changes: 63 additions & 0 deletions drivers/ptp/ptp_chardev.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
switch (cmd) {

case PTP_CLOCK_GETCAPS:
case PTP_CLOCK_GETCAPS2:
memset(&caps, 0, sizeof(caps));

caps.max_adj = ptp->info->max_adj;
caps.n_alarm = ptp->info->n_alarm;
caps.n_ext_ts = ptp->info->n_ext_ts;
Expand All @@ -139,11 +141,24 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;

case PTP_EXTTS_REQUEST:
case PTP_EXTTS_REQUEST2:
memset(&req, 0, sizeof(req));

if (copy_from_user(&req.extts, (void __user *)arg,
sizeof(req.extts))) {
err = -EFAULT;
break;
}
if (((req.extts.flags & ~PTP_EXTTS_VALID_FLAGS) ||
req.extts.rsv[0] || req.extts.rsv[1]) &&
cmd == PTP_EXTTS_REQUEST2) {
err = -EINVAL;
break;
} else if (cmd == PTP_EXTTS_REQUEST) {
req.extts.flags &= ~PTP_EXTTS_VALID_FLAGS;
req.extts.rsv[0] = 0;
req.extts.rsv[1] = 0;
}
if (req.extts.index >= ops->n_ext_ts) {
err = -EINVAL;
break;
Expand All @@ -154,11 +169,27 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;

case PTP_PEROUT_REQUEST:
case PTP_PEROUT_REQUEST2:
memset(&req, 0, sizeof(req));

if (copy_from_user(&req.perout, (void __user *)arg,
sizeof(req.perout))) {
err = -EFAULT;
break;
}
if (((req.perout.flags & ~PTP_PEROUT_VALID_FLAGS) ||
req.perout.rsv[0] || req.perout.rsv[1] ||
req.perout.rsv[2] || req.perout.rsv[3]) &&
cmd == PTP_PEROUT_REQUEST2) {
err = -EINVAL;
break;
} else if (cmd == PTP_PEROUT_REQUEST) {
req.perout.flags &= ~PTP_PEROUT_VALID_FLAGS;
req.perout.rsv[0] = 0;
req.perout.rsv[1] = 0;
req.perout.rsv[2] = 0;
req.perout.rsv[3] = 0;
}
if (req.perout.index >= ops->n_per_out) {
err = -EINVAL;
break;
Expand All @@ -169,6 +200,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;

case PTP_ENABLE_PPS:
case PTP_ENABLE_PPS2:
memset(&req, 0, sizeof(req));

if (!capable(CAP_SYS_TIME))
return -EPERM;
req.type = PTP_CLK_REQ_PPS;
Expand All @@ -177,6 +211,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;

case PTP_SYS_OFFSET_PRECISE:
case PTP_SYS_OFFSET_PRECISE2:
if (!ptp->info->getcrosststamp) {
err = -EOPNOTSUPP;
break;
Expand All @@ -201,6 +236,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;

case PTP_SYS_OFFSET_EXTENDED:
case PTP_SYS_OFFSET_EXTENDED2:
if (!ptp->info->gettimex64) {
err = -EOPNOTSUPP;
break;
Expand Down Expand Up @@ -232,6 +268,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;

case PTP_SYS_OFFSET:
case PTP_SYS_OFFSET2:
sysoff = memdup_user((void __user *)arg, sizeof(*sysoff));
if (IS_ERR(sysoff)) {
err = PTR_ERR(sysoff);
Expand Down Expand Up @@ -266,10 +303,23 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;

case PTP_PIN_GETFUNC:
case PTP_PIN_GETFUNC2:
if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
err = -EFAULT;
break;
}
if ((pd.rsv[0] || pd.rsv[1] || pd.rsv[2]
|| pd.rsv[3] || pd.rsv[4])
&& cmd == PTP_PIN_GETFUNC2) {
err = -EINVAL;
break;
} else if (cmd == PTP_PIN_GETFUNC) {
pd.rsv[0] = 0;
pd.rsv[1] = 0;
pd.rsv[2] = 0;
pd.rsv[3] = 0;
pd.rsv[4] = 0;
}
pin_index = pd.index;
if (pin_index >= ops->n_pins) {
err = -EINVAL;
Expand All @@ -285,10 +335,23 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;

case PTP_PIN_SETFUNC:
case PTP_PIN_SETFUNC2:
if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
err = -EFAULT;
break;
}
if ((pd.rsv[0] || pd.rsv[1] || pd.rsv[2]
|| pd.rsv[3] || pd.rsv[4])
&& cmd == PTP_PIN_SETFUNC2) {
err = -EINVAL;
break;
} else if (cmd == PTP_PIN_SETFUNC) {
pd.rsv[0] = 0;
pd.rsv[1] = 0;
pd.rsv[2] = 0;
pd.rsv[3] = 0;
pd.rsv[4] = 0;
}
pin_index = pd.index;
if (pin_index >= ops->n_pins) {
err = -EINVAL;
Expand Down
24 changes: 23 additions & 1 deletion include/uapi/linux/ptp_clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,20 @@
#include <linux/ioctl.h>
#include <linux/types.h>

/* PTP_xxx bits, for the flags field within the request structures. */
/*
* Bits of the ptp_extts_request.flags field:
*/
#define PTP_ENABLE_FEATURE (1<<0)
#define PTP_RISING_EDGE (1<<1)
#define PTP_FALLING_EDGE (1<<2)
#define PTP_EXTTS_VALID_FLAGS (PTP_ENABLE_FEATURE | \
PTP_RISING_EDGE | \
PTP_FALLING_EDGE)

/*
* Bits of the ptp_perout_request.flags field:
*/
#define PTP_PEROUT_VALID_FLAGS (0)

/*
* struct ptp_clock_time - represents a time value
Expand Down Expand Up @@ -149,6 +159,18 @@ struct ptp_pin_desc {
#define PTP_SYS_OFFSET_EXTENDED \
_IOWR(PTP_CLK_MAGIC, 9, struct ptp_sys_offset_extended)

#define PTP_CLOCK_GETCAPS2 _IOR(PTP_CLK_MAGIC, 10, struct ptp_clock_caps)
#define PTP_EXTTS_REQUEST2 _IOW(PTP_CLK_MAGIC, 11, struct ptp_extts_request)
#define PTP_PEROUT_REQUEST2 _IOW(PTP_CLK_MAGIC, 12, struct ptp_perout_request)
#define PTP_ENABLE_PPS2 _IOW(PTP_CLK_MAGIC, 13, int)
#define PTP_SYS_OFFSET2 _IOW(PTP_CLK_MAGIC, 14, struct ptp_sys_offset)
#define PTP_PIN_GETFUNC2 _IOWR(PTP_CLK_MAGIC, 15, struct ptp_pin_desc)
#define PTP_PIN_SETFUNC2 _IOW(PTP_CLK_MAGIC, 16, struct ptp_pin_desc)
#define PTP_SYS_OFFSET_PRECISE2 \
_IOWR(PTP_CLK_MAGIC, 17, struct ptp_sys_offset_precise)
#define PTP_SYS_OFFSET_EXTENDED2 \
_IOWR(PTP_CLK_MAGIC, 18, struct ptp_sys_offset_extended)

struct ptp_extts_event {
struct ptp_clock_time t; /* Time event occured. */
unsigned int index; /* Which channel produced the event. */
Expand Down

0 comments on commit 4156065

Please sign in to comment.