diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/usb/core/sysfs.c |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/usb/core/sysfs.c')
-rw-r--r-- | drivers/usb/core/sysfs.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c new file mode 100644 index 000000000000..ec9b3bde8ae5 --- /dev/null +++ b/drivers/usb/core/sysfs.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* | ||
2 | * drivers/usb/core/sysfs.c | ||
3 | * | ||
4 | * (C) Copyright 2002 David Brownell | ||
5 | * (C) Copyright 2002,2004 Greg Kroah-Hartman | ||
6 | * (C) Copyright 2002,2004 IBM Corp. | ||
7 | * | ||
8 | * All of the sysfs file attributes for usb devices and interfaces. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | |||
13 | #include <linux/config.h> | ||
14 | #include <linux/kernel.h> | ||
15 | |||
16 | #ifdef CONFIG_USB_DEBUG | ||
17 | #define DEBUG | ||
18 | #else | ||
19 | #undef DEBUG | ||
20 | #endif | ||
21 | #include <linux/usb.h> | ||
22 | |||
23 | #include "usb.h" | ||
24 | |||
25 | /* Active configuration fields */ | ||
26 | #define usb_actconfig_show(field, multiplier, format_string) \ | ||
27 | static ssize_t show_##field (struct device *dev, char *buf) \ | ||
28 | { \ | ||
29 | struct usb_device *udev; \ | ||
30 | struct usb_host_config *actconfig; \ | ||
31 | \ | ||
32 | udev = to_usb_device (dev); \ | ||
33 | actconfig = udev->actconfig; \ | ||
34 | if (actconfig) \ | ||
35 | return sprintf (buf, format_string, \ | ||
36 | actconfig->desc.field * multiplier); \ | ||
37 | else \ | ||
38 | return 0; \ | ||
39 | } \ | ||
40 | |||
41 | #define usb_actconfig_attr(field, multiplier, format_string) \ | ||
42 | usb_actconfig_show(field, multiplier, format_string) \ | ||
43 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | ||
44 | |||
45 | usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") | ||
46 | usb_actconfig_attr (bmAttributes, 1, "%2x\n") | ||
47 | usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") | ||
48 | |||
49 | static ssize_t show_configuration_string(struct device *dev, char *buf) | ||
50 | { | ||
51 | struct usb_device *udev; | ||
52 | struct usb_host_config *actconfig; | ||
53 | int len; | ||
54 | |||
55 | udev = to_usb_device (dev); | ||
56 | actconfig = udev->actconfig; | ||
57 | if ((!actconfig) || (!actconfig->string)) | ||
58 | return 0; | ||
59 | len = sprintf(buf, actconfig->string, PAGE_SIZE); | ||
60 | if (len < 0) | ||
61 | return 0; | ||
62 | buf[len] = '\n'; | ||
63 | buf[len+1] = 0; | ||
64 | return len+1; | ||
65 | } | ||
66 | static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); | ||
67 | |||
68 | /* configuration value is always present, and r/w */ | ||
69 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); | ||
70 | |||
71 | static ssize_t | ||
72 | set_bConfigurationValue (struct device *dev, const char *buf, size_t count) | ||
73 | { | ||
74 | struct usb_device *udev = udev = to_usb_device (dev); | ||
75 | int config, value; | ||
76 | |||
77 | if (sscanf (buf, "%u", &config) != 1 || config > 255) | ||
78 | return -EINVAL; | ||
79 | usb_lock_device(udev); | ||
80 | value = usb_set_configuration (udev, config); | ||
81 | usb_unlock_device(udev); | ||
82 | return (value < 0) ? value : count; | ||
83 | } | ||
84 | |||
85 | static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, | ||
86 | show_bConfigurationValue, set_bConfigurationValue); | ||
87 | |||
88 | /* String fields */ | ||
89 | #define usb_string_attr(name) \ | ||
90 | static ssize_t show_##name(struct device *dev, char *buf) \ | ||
91 | { \ | ||
92 | struct usb_device *udev; \ | ||
93 | int len; \ | ||
94 | \ | ||
95 | udev = to_usb_device (dev); \ | ||
96 | len = snprintf(buf, 256, "%s", udev->name); \ | ||
97 | if (len < 0) \ | ||
98 | return 0; \ | ||
99 | buf[len] = '\n'; \ | ||
100 | buf[len+1] = 0; \ | ||
101 | return len+1; \ | ||
102 | } \ | ||
103 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); | ||
104 | |||
105 | usb_string_attr(product); | ||
106 | usb_string_attr(manufacturer); | ||
107 | usb_string_attr(serial); | ||
108 | |||
109 | static ssize_t | ||
110 | show_speed (struct device *dev, char *buf) | ||
111 | { | ||
112 | struct usb_device *udev; | ||
113 | char *speed; | ||
114 | |||
115 | udev = to_usb_device (dev); | ||
116 | |||
117 | switch (udev->speed) { | ||
118 | case USB_SPEED_LOW: | ||
119 | speed = "1.5"; | ||
120 | break; | ||
121 | case USB_SPEED_UNKNOWN: | ||
122 | case USB_SPEED_FULL: | ||
123 | speed = "12"; | ||
124 | break; | ||
125 | case USB_SPEED_HIGH: | ||
126 | speed = "480"; | ||
127 | break; | ||
128 | default: | ||
129 | speed = "unknown"; | ||
130 | } | ||
131 | return sprintf (buf, "%s\n", speed); | ||
132 | } | ||
133 | static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); | ||
134 | |||
135 | static ssize_t | ||
136 | show_devnum (struct device *dev, char *buf) | ||
137 | { | ||
138 | struct usb_device *udev; | ||
139 | |||
140 | udev = to_usb_device (dev); | ||
141 | return sprintf (buf, "%d\n", udev->devnum); | ||
142 | } | ||
143 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); | ||
144 | |||
145 | static ssize_t | ||
146 | show_version (struct device *dev, char *buf) | ||
147 | { | ||
148 | struct usb_device *udev; | ||
149 | u16 bcdUSB; | ||
150 | |||
151 | udev = to_usb_device(dev); | ||
152 | bcdUSB = le16_to_cpu(udev->descriptor.bcdUSB); | ||
153 | return sprintf(buf, "%2x.%02x\n", bcdUSB >> 8, bcdUSB & 0xff); | ||
154 | } | ||
155 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); | ||
156 | |||
157 | static ssize_t | ||
158 | show_maxchild (struct device *dev, char *buf) | ||
159 | { | ||
160 | struct usb_device *udev; | ||
161 | |||
162 | udev = to_usb_device (dev); | ||
163 | return sprintf (buf, "%d\n", udev->maxchild); | ||
164 | } | ||
165 | static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); | ||
166 | |||
167 | /* Descriptor fields */ | ||
168 | #define usb_descriptor_attr_le16(field, format_string) \ | ||
169 | static ssize_t \ | ||
170 | show_##field (struct device *dev, char *buf) \ | ||
171 | { \ | ||
172 | struct usb_device *udev; \ | ||
173 | \ | ||
174 | udev = to_usb_device (dev); \ | ||
175 | return sprintf (buf, format_string, \ | ||
176 | le16_to_cpu(udev->descriptor.field)); \ | ||
177 | } \ | ||
178 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | ||
179 | |||
180 | usb_descriptor_attr_le16(idVendor, "%04x\n") | ||
181 | usb_descriptor_attr_le16(idProduct, "%04x\n") | ||
182 | usb_descriptor_attr_le16(bcdDevice, "%04x\n") | ||
183 | |||
184 | #define usb_descriptor_attr(field, format_string) \ | ||
185 | static ssize_t \ | ||
186 | show_##field (struct device *dev, char *buf) \ | ||
187 | { \ | ||
188 | struct usb_device *udev; \ | ||
189 | \ | ||
190 | udev = to_usb_device (dev); \ | ||
191 | return sprintf (buf, format_string, udev->descriptor.field); \ | ||
192 | } \ | ||
193 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | ||
194 | |||
195 | usb_descriptor_attr (bDeviceClass, "%02x\n") | ||
196 | usb_descriptor_attr (bDeviceSubClass, "%02x\n") | ||
197 | usb_descriptor_attr (bDeviceProtocol, "%02x\n") | ||
198 | usb_descriptor_attr (bNumConfigurations, "%d\n") | ||
199 | |||
200 | static struct attribute *dev_attrs[] = { | ||
201 | /* current configuration's attributes */ | ||
202 | &dev_attr_bNumInterfaces.attr, | ||
203 | &dev_attr_bConfigurationValue.attr, | ||
204 | &dev_attr_bmAttributes.attr, | ||
205 | &dev_attr_bMaxPower.attr, | ||
206 | /* device attributes */ | ||
207 | &dev_attr_idVendor.attr, | ||
208 | &dev_attr_idProduct.attr, | ||
209 | &dev_attr_bcdDevice.attr, | ||
210 | &dev_attr_bDeviceClass.attr, | ||
211 | &dev_attr_bDeviceSubClass.attr, | ||
212 | &dev_attr_bDeviceProtocol.attr, | ||
213 | &dev_attr_bNumConfigurations.attr, | ||
214 | &dev_attr_speed.attr, | ||
215 | &dev_attr_devnum.attr, | ||
216 | &dev_attr_version.attr, | ||
217 | &dev_attr_maxchild.attr, | ||
218 | NULL, | ||
219 | }; | ||
220 | static struct attribute_group dev_attr_grp = { | ||
221 | .attrs = dev_attrs, | ||
222 | }; | ||
223 | |||
224 | void usb_create_sysfs_dev_files (struct usb_device *udev) | ||
225 | { | ||
226 | struct device *dev = &udev->dev; | ||
227 | |||
228 | sysfs_create_group(&dev->kobj, &dev_attr_grp); | ||
229 | |||
230 | if (udev->manufacturer) | ||
231 | device_create_file (dev, &dev_attr_manufacturer); | ||
232 | if (udev->product) | ||
233 | device_create_file (dev, &dev_attr_product); | ||
234 | if (udev->serial) | ||
235 | device_create_file (dev, &dev_attr_serial); | ||
236 | device_create_file (dev, &dev_attr_configuration); | ||
237 | } | ||
238 | |||
239 | void usb_remove_sysfs_dev_files (struct usb_device *udev) | ||
240 | { | ||
241 | struct device *dev = &udev->dev; | ||
242 | |||
243 | sysfs_remove_group(&dev->kobj, &dev_attr_grp); | ||
244 | |||
245 | if (udev->descriptor.iManufacturer) | ||
246 | device_remove_file(dev, &dev_attr_manufacturer); | ||
247 | if (udev->descriptor.iProduct) | ||
248 | device_remove_file(dev, &dev_attr_product); | ||
249 | if (udev->descriptor.iSerialNumber) | ||
250 | device_remove_file(dev, &dev_attr_serial); | ||
251 | device_remove_file (dev, &dev_attr_configuration); | ||
252 | } | ||
253 | |||
254 | /* Interface fields */ | ||
255 | #define usb_intf_attr(field, format_string) \ | ||
256 | static ssize_t \ | ||
257 | show_##field (struct device *dev, char *buf) \ | ||
258 | { \ | ||
259 | struct usb_interface *intf = to_usb_interface (dev); \ | ||
260 | \ | ||
261 | return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \ | ||
262 | } \ | ||
263 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | ||
264 | |||
265 | usb_intf_attr (bInterfaceNumber, "%02x\n") | ||
266 | usb_intf_attr (bAlternateSetting, "%2d\n") | ||
267 | usb_intf_attr (bNumEndpoints, "%02x\n") | ||
268 | usb_intf_attr (bInterfaceClass, "%02x\n") | ||
269 | usb_intf_attr (bInterfaceSubClass, "%02x\n") | ||
270 | usb_intf_attr (bInterfaceProtocol, "%02x\n") | ||
271 | |||
272 | static ssize_t show_interface_string(struct device *dev, char *buf) | ||
273 | { | ||
274 | struct usb_interface *intf; | ||
275 | struct usb_device *udev; | ||
276 | int len; | ||
277 | |||
278 | intf = to_usb_interface (dev); | ||
279 | udev = interface_to_usbdev (intf); | ||
280 | len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); | ||
281 | if (len < 0) | ||
282 | return 0; | ||
283 | buf[len] = '\n'; | ||
284 | buf[len+1] = 0; | ||
285 | return len+1; | ||
286 | } | ||
287 | static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); | ||
288 | |||
289 | static struct attribute *intf_attrs[] = { | ||
290 | &dev_attr_bInterfaceNumber.attr, | ||
291 | &dev_attr_bAlternateSetting.attr, | ||
292 | &dev_attr_bNumEndpoints.attr, | ||
293 | &dev_attr_bInterfaceClass.attr, | ||
294 | &dev_attr_bInterfaceSubClass.attr, | ||
295 | &dev_attr_bInterfaceProtocol.attr, | ||
296 | NULL, | ||
297 | }; | ||
298 | static struct attribute_group intf_attr_grp = { | ||
299 | .attrs = intf_attrs, | ||
300 | }; | ||
301 | |||
302 | void usb_create_sysfs_intf_files (struct usb_interface *intf) | ||
303 | { | ||
304 | sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); | ||
305 | |||
306 | if (intf->cur_altsetting->string) | ||
307 | device_create_file(&intf->dev, &dev_attr_interface); | ||
308 | |||
309 | } | ||
310 | |||
311 | void usb_remove_sysfs_intf_files (struct usb_interface *intf) | ||
312 | { | ||
313 | sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); | ||
314 | |||
315 | if (intf->cur_altsetting->string) | ||
316 | device_remove_file(&intf->dev, &dev_attr_interface); | ||
317 | |||
318 | } | ||