summaryrefslogtreecommitdiff
path: root/hald/linux/class_device.h
blob: 681c0794f05b7f43c9ee2cc200a56d0536e6a78a (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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/***************************************************************************
 * CVSID: $Id$
 *
 * linux_class_generic.h : Generic methods for class devices
 *
 * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
 *
 * Licensed under the Academic Free License version 2.0
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 **************************************************************************/

#ifndef CLASS_DEVICE_H
#define CLASS_DEVICE_H

#include "libsysfs/libsysfs.h"

/* fwd decl */
struct ClassDeviceHandler_s;
typedef struct ClassDeviceHandler_s ClassDeviceHandler;

/** Method and property table for ClassDeviceHandler */
struct ClassDeviceHandler_s {
	/** Called when the HAL daemon is starting up 
	 *
	 *  @param  self        Pointer to class members
	 */
	void (*init) (ClassDeviceHandler* self);

	/** Called when all device detection (on bootstrap) is done 
	 *
	 *  @param  self        Pointer to class members
	 */
	void (*detection_done) (ClassDeviceHandler* self);

	/** Called just before the HAL daemon is shutting down 
	 *
	 *  @param  self        Pointer to class members
	 */
	void (*shutdown) (ClassDeviceHandler* self);

	/** Called regulary (every two seconds) for polling etc. 
	 *
	 *  @param  self        Pointer to class members
	 */
	void (*tick) (ClassDeviceHandler* self);

	/** Called when a new instance of a class device is detected either
	 *  through hotplug or through initial detection.
	 *
	 *  This function should create a HalDevice object if we are interested
	 *  in the class device (e.g. if it maps to a particular hardware 
	 *  device). If a HalDevice object is created and we need to wait for
	 *  an udev event, then the string property 
	 *
	 *    .udev.sysfs_path 
	 *
	 *  must be set to the sysfs_path given and the string property
	 *
	 *    .udev.class_name
	 *
	 *  need to carry the appropriate class device name (e.g. from 
	 *  /sys/class such as input, net).
	 *  
	 *
	 *  @param  self          Pointer to class members
	 *  @param  sysfs_path    The path in sysfs (including mount point) of
	 *                        the class device in sysfs
	 *  @param  class_device  Libsysfs object representing new class device
	 *                        instance
	 *  @param  is_probing    Set to TRUE only initial detection
	 */
	void (*visit) (ClassDeviceHandler* self,
		       const char *sysfs_path,
		       struct sysfs_class_device *class_device,
		       dbus_bool_t is_probing);

	/** Called when the class device instance have been removed
	 *
	 *  @param  self          Pointer to class members
	 *  @param  sysfs_path    The path in sysfs (including mount point) of
	 *                        the class device in sysfs
	 *  @param  d             The HalDevice object of the instance of
	 *                        this device class
	 */
	void (*removed) (ClassDeviceHandler* self, 
			 const char *sysfs_path, 
			 HalDevice *d);

	/** Called when the device file (e.g. a file in /dev) have
	 *  been created for a particual instance of this class device
	 *
	 *  @param  self          Pointer to class members
	 *  @param  d             The HalDevice object of the instance of
	 *                        this device class
	 *  @param  dev_file      Device file, e.g. /udev/input/event4
	 */
	void (*udev_event) (ClassDeviceHandler* self,
			    HalDevice *d, char *dev_file);

	/** Get the name of that the property that the device file should
	 *  be put in
	 *
	 *  @param  self          Pointer to class members
	 *  @param  d             The HalDevice object of the instance of
	 *                        this device class
	 *  @param  sysfs_path    The path in sysfs (including mount point) of
	 *                        the class device in sysfs
	 *  @param  class_device  Libsysfs object representing class device
	 *                        instance
	 *  @param  dev_file_prop Device file property name (out)
	 *  @param  dev_file_prop_len  Maximum length of string
	 */
	void (*get_device_file_target) (ClassDeviceHandler* self,
					HalDevice *d, 
					const char *sysfs_path,
					struct sysfs_class_device *class_device,
					char* dev_file_prop,
					int dev_file_prop_len);

	/** This method is called just before the device is either merged
	 *  onto the sysdevice or added to the GDL (cf. merge_or_add). 
	 *  This is useful for extracting more information about the device
	 *  through e.g. ioctl's using the device file property and also
	 *  for setting info.category|capability.
	 *
	 *  @param  self          Pointer to class members
	 *  @param  d             The HalDevice object of the instance of
	 *                        this device class
	 *  @param  sysfs_path    The path in sysfs (including mount point) of
	 *                        the class device in sysfs
	 *  @param  class_device  Libsysfs object representing class device
	 *                        instance
	 */
	void (*post_process) (ClassDeviceHandler* self,
			      HalDevice *d,
			      const char *sysfs_path,
			      struct sysfs_class_device *class_device);	

	/** This function will compute the device udi based on other properties
	 *  of the device. 
	 *
	 *  It only makes sense to implement this method if, and only if,
	 *  merge_or_add==FALSE
	 *
	 *  Requirements for udi:
	 *   - do not rely on bus, port etc.; we want this id to be as 
	 *     unique for the device as we can
	 *   - make sure it doesn't rely on properties that cannot be obtained
	 *     from the minimal information we can obtain on an unplug event
	 *
	 *  @param  d                   HalDevice object
	 *  @param  append_num          Number to append to name if not -1
	 *  @return                     New unique device id; only good until
	 *                              the next invocation of this function
	 */
	char* (*compute_udi) (HalDevice *d, int append_num);


	/** name of device class the instance handles (name mentioned 
	 *  in /sys/class */
	const char *sysfs_class_name;

	/** hal class name - if merge_or_add==FALSE then info.bus will have
	 *  this name */
	const char* hal_class_name;

	/** TRUE if the class device should get the device file from
	 *  udev (using udevinfo on probing / waiting for dbus signal
	 *  on hotplug). FALSE if there is no special device file for
	 *  the device class (such as net devices).
	 *
	 *  If set to TRUE then class_device_target_property must be 
	 *  implemented.
	 */
	dbus_bool_t require_device_file;

	/** TRUE if the class device should be merged onto the sysdevice;
	 *  if FALSE the class device will be added as a child to the 
	 *  parent of the sysdevice */
	dbus_bool_t merge_or_add;
};

void class_device_visit (ClassDeviceHandler *self,
			 const char *path,
			 struct sysfs_class_device *class_device,
			 dbus_bool_t is_probing);

void class_device_removed (ClassDeviceHandler* self, 
			   const char *sysfs_path, 
			   HalDevice *d);

void class_device_udev_event (ClassDeviceHandler *self,
			      HalDevice *d, char *dev_file);

void class_device_init (ClassDeviceHandler *self);

void class_device_detection_done (ClassDeviceHandler *self);

void class_device_shutdown (ClassDeviceHandler *self);

void class_device_post_process (ClassDeviceHandler *self,
				HalDevice *d,
				const char *sysfs_path,
				struct sysfs_class_device *class_device);

void class_device_tick (ClassDeviceHandler *self);

void class_device_get_device_file_target (ClassDeviceHandler *self,
					  HalDevice *d,
					  const char *sysfs_path,
					  struct sysfs_class_device *class_device,
					  char* dev_file_prop,
					  int dev_file_prop_len);

void class_device_got_sysdevice (HalDeviceStore *store, 
				 HalDevice *sysdevice, 
				 gpointer user_data);

void class_device_got_parent_device (HalDeviceStore *store, 
				     HalDevice *parent, 
				     gpointer user_data);


#endif /* CLASS_DEVICE_H */