summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/Documentation/sysfs-bus-greybus
blob: 17b1a2919ef9215e12d766893a91123d0b053fea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
What:		/sys/bus/greybus/device/greybusN
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		The "root" greybus device for the Greybus device tree, or bus,
		where N is a dynamically assigned 1-based id.

What:		/sys/bus/greybus/device/N-I
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		An Interface I on the bus N, where I is the 1-byte interface
		ID.

What:		/sys/bus/greybus/device/N-I/ddbl1_manufacturer_id
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Unipro Device Descriptor Block Level 1 manufacturer ID for the
		greybus Interface.

What:		/sys/bus/greybus/device/N-I/ddbl1_product_id
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Unipro Device Descriptor Block Level 1 product ID for the
		greybus Interface.

What:		/sys/bus/greybus/device/N-I/interface_id
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		The ID of a Greybus interface.

What:		/sys/bus/greybus/device/N-I/serial_number
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Serial Number of the Greybus interface, represented by a 64 bit
		hexadecimal number.

What:		/sys/bus/greybus/device/N-I/product_id
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Product ID of a Greybus interface.

What:		/sys/bus/greybus/device/N-I/product_string
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Product ID string of a Greybus interface.

What:		/sys/bus/greybus/device/N-I/vendor_id
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Vendor ID of a Greybus interface.

What:		/sys/bus/greybus/device/N-I/vendor_string
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Vendor ID string of a Greybus interface block.

What:		/sys/bus/greybus/device/N-I/version
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Interface version represented as <16 bit major number>.<16 bit
		minor number>.

What:		/sys/bus/greybus/device/N-I.B
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		A bundle B on the Interface I, B is replaced by a 1-byte
		number representing the bundle.

What:		/sys/bus/greybus/device/N-I.B/bundle_class
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		The greybus class of the bundle B.

What:		/sys/bus/greybus/device/N-I.B/bundle_id
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		The interface-unique id of the bundle B.

What:		/sys/bus/greybus/device/N-I.B/state
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		A bundle has a state that is managed by the userspace
		Endo process.  This file allows that Endo to signal
		other Android HALs that the state of the bundle has
		changed to a specific value.  When written to, any
		process watching the file will be woken up, and the new
		value can be read. It's a "poor-man's IPC", yes, but
		simplifies the Android userspace code immensely.

What:		/sys/bus/greybus/device/N-svc
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		The singleton SVC device of bus N.

What:		/sys/bus/greybus/device/N-svc/ap_intf_id
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		The AP interface ID, a 1-byte non-zero integer which
		defines the position of the AP module on the frame.
		The interface positions are defined in the ARA
		Module Developer Kit.

What:		/sys/bus/greybus/device/N-svc/endo_id
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		The Endo ID, which is a 2-byte hexadecimal value
		defined by the Endo layout scheme, documented in
		the ARA Module Developer Kit.

What:		/sys/bus/greybus/device/N-svc/intf_eject
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		Write the number of the interface that you wish to
		forcibly eject from the system.

What:		/sys/bus/greybus/device/N-svc/version
Date:		October 2015
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		The version number of the firmware in the SVC device.

What:		/sys/bus/greybus/device/N-svc/watchdog
Date:		October 2016
KernelVersion:	4.XX
Contact:	Greg Kroah-Hartman <greg@kroah.com>
Description:
		If the SVC watchdog is enabled or not.  Writing 0 to this
		file will disable the watchdog, writing 1 will enable it.
nt-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 * Copyright (c) 2010 Patrick McHardy <kaber@trash.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_CT.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_timeout.h>
#include <net/netfilter/nf_conntrack_zones.h>

static inline int xt_ct_target(struct sk_buff *skb, struct nf_conn *ct)
{
	/* Previously seen (loopback)? Ignore. */
	if (skb->nfct != NULL)
		return XT_CONTINUE;

	/* special case the untracked ct : we want the percpu object */
	if (!ct)
		ct = nf_ct_untracked_get();
	atomic_inc(&ct->ct_general.use);
	skb->nfct = &ct->ct_general;
	skb->nfctinfo = IP_CT_NEW;

	return XT_CONTINUE;
}

static unsigned int xt_ct_target_v0(struct sk_buff *skb,
				    const struct xt_action_param *par)
{
	const struct xt_ct_target_info *info = par->targinfo;
	struct nf_conn *ct = info->ct;

	return xt_ct_target(skb, ct);
}

static unsigned int xt_ct_target_v1(struct sk_buff *skb,
				    const struct xt_action_param *par)
{
	const struct xt_ct_target_info_v1 *info = par->targinfo;
	struct nf_conn *ct = info->ct;

	return xt_ct_target(skb, ct);
}

static u8 xt_ct_find_proto(const struct xt_tgchk_param *par)
{
	if (par->family == NFPROTO_IPV4) {
		const struct ipt_entry *e = par->entryinfo;

		if (e->ip.invflags & IPT_INV_PROTO)
			return 0;
		return e->ip.proto;
	} else if (par->family == NFPROTO_IPV6) {
		const struct ip6t_entry *e = par->entryinfo;

		if (e->ipv6.invflags & IP6T_INV_PROTO)
			return 0;
		return e->ipv6.proto;
	} else
		return 0;
}

static int
xt_ct_set_helper(struct nf_conn *ct, const char *helper_name,
		 const struct xt_tgchk_param *par)
{
	struct nf_conntrack_helper *helper;
	struct nf_conn_help *help;
	u8 proto;

	proto = xt_ct_find_proto(par);
	if (!proto) {
		pr_info("You must specify a L4 protocol, and not use "
			"inversions on it.\n");
		return -ENOENT;
	}

	helper = nf_conntrack_helper_try_module_get(helper_name, par->family,
						    proto);
	if (helper == NULL) {
		pr_info("No such helper \"%s\"\n", helper_name);
		return -ENOENT;
	}

	help = nf_ct_helper_ext_add(ct, helper, GFP_KERNEL);
	if (help == NULL) {
		module_put(helper->me);
		return -ENOMEM;
	}

	help->helper = helper;
	return 0;
}

#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout)
{
	typeof(nf_ct_timeout_put_hook) timeout_put;

	timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
	if (timeout_put)
		timeout_put(timeout);
}
#endif

static int
xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par,
		  const char *timeout_name)
{
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
	typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
	struct ctnl_timeout *timeout;
	struct nf_conn_timeout *timeout_ext;
	struct nf_conntrack_l4proto *l4proto;
	int ret = 0;
	u8 proto;

	rcu_read_lock();
	timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook);
	if (timeout_find_get == NULL) {
		ret = -ENOENT;
		pr_info("Timeout policy base is empty\n");
		goto out;
	}

	proto = xt_ct_find_proto(par);
	if (!proto) {
		ret = -EINVAL;
		pr_info("You must specify a L4 protocol, and not use "
			"inversions on it.\n");
		goto out;
	}

	timeout = timeout_find_get(par->net, timeout_name);
	if (timeout == NULL) {
		ret = -ENOENT;
		pr_info("No such timeout policy \"%s\"\n", timeout_name);
		goto out;
	}

	if (timeout->l3num != par->family) {
		ret = -EINVAL;
		pr_info("Timeout policy `%s' can only be used by L3 protocol "
			"number %d\n", timeout_name, timeout->l3num);
		goto err_put_timeout;
	}
	/* Make sure the timeout policy matches any existing protocol tracker,
	 * otherwise default to generic.
	 */
	l4proto = __nf_ct_l4proto_find(par->family, proto);
	if (timeout->l4proto->l4proto != l4proto->l4proto) {
		ret = -EINVAL;
		pr_info("Timeout policy `%s' can only be used by L4 protocol "
			"number %d\n",
			timeout_name, timeout->l4proto->l4proto);
		goto err_put_timeout;
	}
	timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC);
	if (timeout_ext == NULL)
		ret = -ENOMEM;

	rcu_read_unlock();
	return ret;

err_put_timeout:
	__xt_ct_tg_timeout_put(timeout);
out:
	rcu_read_unlock();
	return ret;
#else
	return -EOPNOTSUPP;
#endif
}

static u16 xt_ct_flags_to_dir(const struct xt_ct_target_info_v1 *info)
{
	switch (info->flags & (XT_CT_ZONE_DIR_ORIG |
			       XT_CT_ZONE_DIR_REPL)) {
	case XT_CT_ZONE_DIR_ORIG:
		return NF_CT_ZONE_DIR_ORIG;
	case XT_CT_ZONE_DIR_REPL:
		return NF_CT_ZONE_DIR_REPL;
	default:
		return NF_CT_DEFAULT_ZONE_DIR;
	}
}

static int xt_ct_tg_check(const struct xt_tgchk_param *par,
			  struct xt_ct_target_info_v1 *info)
{
	struct nf_conntrack_zone zone;
	struct nf_conn *ct;
	int ret = -EOPNOTSUPP;

	if (info->flags & XT_CT_NOTRACK) {
		ct = NULL;
		goto out;
	}

#ifndef CONFIG_NF_CONNTRACK_ZONES
	if (info->zone || info->flags & (XT_CT_ZONE_DIR_ORIG |
					 XT_CT_ZONE_DIR_REPL |
					 XT_CT_ZONE_MARK))
		goto err1;
#endif

	ret = nf_ct_l3proto_try_module_get(par->family);
	if (ret < 0)
		goto err1;

	memset(&zone, 0, sizeof(zone));
	zone.id = info->zone;
	zone.dir = xt_ct_flags_to_dir(info);
	if (info->flags & XT_CT_ZONE_MARK)
		zone.flags |= NF_CT_FLAG_MARK;

	ct = nf_ct_tmpl_alloc(par->net, &zone, GFP_KERNEL);
	if (!ct) {
		ret = -ENOMEM;
		goto err2;
	}

	ret = 0;
	if ((info->ct_events || info->exp_events) &&
	    !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events,
				  GFP_KERNEL)) {
		ret = -EINVAL;
		goto err3;
	}

	if (info->helper[0]) {
		ret = xt_ct_set_helper(ct, info->helper, par);
		if (ret < 0)
			goto err3;
	}

	if (info->timeout[0]) {
		ret = xt_ct_set_timeout(ct, par, </