1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * transport_class.h - a generic container for all transport classes
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #ifndef _TRANSPORT_CLASS_H_
9*4882a593Smuzhiyun #define _TRANSPORT_CLASS_H_
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/device.h>
12*4882a593Smuzhiyun #include <linux/bug.h>
13*4882a593Smuzhiyun #include <linux/attribute_container.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun struct transport_container;
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun struct transport_class {
18*4882a593Smuzhiyun struct class class;
19*4882a593Smuzhiyun int (*setup)(struct transport_container *, struct device *,
20*4882a593Smuzhiyun struct device *);
21*4882a593Smuzhiyun int (*configure)(struct transport_container *, struct device *,
22*4882a593Smuzhiyun struct device *);
23*4882a593Smuzhiyun int (*remove)(struct transport_container *, struct device *,
24*4882a593Smuzhiyun struct device *);
25*4882a593Smuzhiyun };
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define DECLARE_TRANSPORT_CLASS(cls, nm, su, rm, cfg) \
28*4882a593Smuzhiyun struct transport_class cls = { \
29*4882a593Smuzhiyun .class = { \
30*4882a593Smuzhiyun .name = nm, \
31*4882a593Smuzhiyun }, \
32*4882a593Smuzhiyun .setup = su, \
33*4882a593Smuzhiyun .remove = rm, \
34*4882a593Smuzhiyun .configure = cfg, \
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun struct anon_transport_class {
39*4882a593Smuzhiyun struct transport_class tclass;
40*4882a593Smuzhiyun struct attribute_container container;
41*4882a593Smuzhiyun };
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #define DECLARE_ANON_TRANSPORT_CLASS(cls, mtch, cfg) \
44*4882a593Smuzhiyun struct anon_transport_class cls = { \
45*4882a593Smuzhiyun .tclass = { \
46*4882a593Smuzhiyun .configure = cfg, \
47*4882a593Smuzhiyun }, \
48*4882a593Smuzhiyun . container = { \
49*4882a593Smuzhiyun .match = mtch, \
50*4882a593Smuzhiyun }, \
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun #define class_to_transport_class(x) \
54*4882a593Smuzhiyun container_of(x, struct transport_class, class)
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun struct transport_container {
57*4882a593Smuzhiyun struct attribute_container ac;
58*4882a593Smuzhiyun const struct attribute_group *statistics;
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun #define attribute_container_to_transport_container(x) \
62*4882a593Smuzhiyun container_of(x, struct transport_container, ac)
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun void transport_remove_device(struct device *);
65*4882a593Smuzhiyun int transport_add_device(struct device *);
66*4882a593Smuzhiyun void transport_setup_device(struct device *);
67*4882a593Smuzhiyun void transport_configure_device(struct device *);
68*4882a593Smuzhiyun void transport_destroy_device(struct device *);
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun static inline int
transport_register_device(struct device * dev)71*4882a593Smuzhiyun transport_register_device(struct device *dev)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun transport_setup_device(dev);
74*4882a593Smuzhiyun return transport_add_device(dev);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun static inline void
transport_unregister_device(struct device * dev)78*4882a593Smuzhiyun transport_unregister_device(struct device *dev)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun transport_remove_device(dev);
81*4882a593Smuzhiyun transport_destroy_device(dev);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
transport_container_register(struct transport_container * tc)84*4882a593Smuzhiyun static inline int transport_container_register(struct transport_container *tc)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun return attribute_container_register(&tc->ac);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
transport_container_unregister(struct transport_container * tc)89*4882a593Smuzhiyun static inline void transport_container_unregister(struct transport_container *tc)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun if (unlikely(attribute_container_unregister(&tc->ac)))
92*4882a593Smuzhiyun BUG();
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun int transport_class_register(struct transport_class *);
96*4882a593Smuzhiyun int anon_transport_class_register(struct anon_transport_class *);
97*4882a593Smuzhiyun void transport_class_unregister(struct transport_class *);
98*4882a593Smuzhiyun void anon_transport_class_unregister(struct anon_transport_class *);
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun #endif
102