2 * drivers/usb/core/sysfs.c
4 * (C) Copyright 2002 David Brownell
5 * (C) Copyright 2002,2004 Greg Kroah-Hartman
6 * (C) Copyright 2002,2004 IBM Corp.
8 * All of the sysfs file attributes for usb devices and interfaces.
13 #include <linux/config.h>
14 #include <linux/kernel.h>
16 #ifdef CONFIG_USB_DEBUG
21 #include <linux/usb.h>
25 /* Active configuration fields */
26 #define usb_actconfig_show(field, multiplier, format_string) \
27 static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
29 struct usb_device *udev; \
30 struct usb_host_config *actconfig; \
32 udev = to_usb_device (dev); \
33 actconfig = udev->actconfig; \
35 return sprintf (buf, format_string, \
36 actconfig->desc.field * multiplier); \
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);
45 usb_actconfig_attr (bNumInterfaces
, 1, "%2d\n")
46 usb_actconfig_attr (bmAttributes
, 1, "%2x\n")
47 usb_actconfig_attr (bMaxPower
, 2, "%3dmA\n")
49 static ssize_t
show_configuration_string(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
51 struct usb_device
*udev
;
52 struct usb_host_config
*actconfig
;
55 udev
= to_usb_device (dev
);
56 actconfig
= udev
->actconfig
;
57 if ((!actconfig
) || (!actconfig
->string
))
59 len
= sprintf(buf
, actconfig
->string
, PAGE_SIZE
);
66 static DEVICE_ATTR(configuration
, S_IRUGO
, show_configuration_string
, NULL
);
68 /* configuration value is always present, and r/w */
69 usb_actconfig_show(bConfigurationValue
, 1, "%u\n");
72 set_bConfigurationValue (struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
74 struct usb_device
*udev
= udev
= to_usb_device (dev
);
77 if (sscanf (buf
, "%u", &config
) != 1 || config
> 255)
79 usb_lock_device(udev
);
80 value
= usb_set_configuration (udev
, config
);
81 usb_unlock_device(udev
);
82 return (value
< 0) ? value
: count
;
85 static DEVICE_ATTR(bConfigurationValue
, S_IRUGO
| S_IWUSR
,
86 show_bConfigurationValue
, set_bConfigurationValue
);
89 #define usb_string_attr(name) \
90 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
92 struct usb_device *udev; \
95 udev = to_usb_device (dev); \
96 len = snprintf(buf, 256, "%s", udev->name); \
103 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
105 usb_string_attr(product
);
106 usb_string_attr(manufacturer
);
107 usb_string_attr(serial
);
110 show_speed (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
112 struct usb_device
*udev
;
115 udev
= to_usb_device (dev
);
117 switch (udev
->speed
) {
121 case USB_SPEED_UNKNOWN
:
131 return sprintf (buf
, "%s\n", speed
);
133 static DEVICE_ATTR(speed
, S_IRUGO
, show_speed
, NULL
);
136 show_devnum (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
138 struct usb_device
*udev
;
140 udev
= to_usb_device (dev
);
141 return sprintf (buf
, "%d\n", udev
->devnum
);
143 static DEVICE_ATTR(devnum
, S_IRUGO
, show_devnum
, NULL
);
146 show_version (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
148 struct usb_device
*udev
;
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);
155 static DEVICE_ATTR(version
, S_IRUGO
, show_version
, NULL
);
158 show_maxchild (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
160 struct usb_device
*udev
;
162 udev
= to_usb_device (dev
);
163 return sprintf (buf
, "%d\n", udev
->maxchild
);
165 static DEVICE_ATTR(maxchild
, S_IRUGO
, show_maxchild
, NULL
);
167 /* Descriptor fields */
168 #define usb_descriptor_attr_le16(field, format_string) \
170 show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
172 struct usb_device *udev; \
174 udev = to_usb_device (dev); \
175 return sprintf (buf, format_string, \
176 le16_to_cpu(udev->descriptor.field)); \
178 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
180 usb_descriptor_attr_le16(idVendor
, "%04x\n")
181 usb_descriptor_attr_le16(idProduct
, "%04x\n")
182 usb_descriptor_attr_le16(bcdDevice
, "%04x\n")
184 #define usb_descriptor_attr(field, format_string) \
186 show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
188 struct usb_device *udev; \
190 udev = to_usb_device (dev); \
191 return sprintf (buf, format_string, udev->descriptor.field); \
193 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
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")
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
,
220 static struct attribute_group dev_attr_grp
= {
224 void usb_create_sysfs_dev_files (struct usb_device
*udev
)
226 struct device
*dev
= &udev
->dev
;
228 sysfs_create_group(&dev
->kobj
, &dev_attr_grp
);
230 if (udev
->manufacturer
)
231 device_create_file (dev
, &dev_attr_manufacturer
);
233 device_create_file (dev
, &dev_attr_product
);
235 device_create_file (dev
, &dev_attr_serial
);
236 device_create_file (dev
, &dev_attr_configuration
);
239 void usb_remove_sysfs_dev_files (struct usb_device
*udev
)
241 struct device
*dev
= &udev
->dev
;
243 sysfs_remove_group(&dev
->kobj
, &dev_attr_grp
);
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
);
254 /* Interface fields */
255 #define usb_intf_attr(field, format_string) \
257 show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
259 struct usb_interface *intf = to_usb_interface (dev); \
261 return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \
263 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
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")
272 static ssize_t
show_interface_string(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
274 struct usb_interface
*intf
;
275 struct usb_device
*udev
;
278 intf
= to_usb_interface (dev
);
279 udev
= interface_to_usbdev (intf
);
280 len
= snprintf(buf
, 256, "%s", intf
->cur_altsetting
->string
);
287 static DEVICE_ATTR(interface
, S_IRUGO
, show_interface_string
, NULL
);
289 static ssize_t
show_modalias(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
291 struct usb_interface
*intf
;
292 struct usb_device
*udev
;
295 intf
= to_usb_interface(dev
);
296 udev
= interface_to_usbdev(intf
);
298 len
= sprintf(buf
, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic",
299 le16_to_cpu(udev
->descriptor
.idVendor
),
300 le16_to_cpu(udev
->descriptor
.idProduct
),
301 le16_to_cpu(udev
->descriptor
.bcdDevice
),
302 udev
->descriptor
.bDeviceClass
,
303 udev
->descriptor
.bDeviceSubClass
,
304 udev
->descriptor
.bDeviceProtocol
);
307 if (udev
->descriptor
.bDeviceClass
== 0) {
308 struct usb_host_interface
*alt
= intf
->cur_altsetting
;
310 return len
+ sprintf(buf
, "%02Xisc%02Xip%02X\n",
311 alt
->desc
.bInterfaceClass
,
312 alt
->desc
.bInterfaceSubClass
,
313 alt
->desc
.bInterfaceProtocol
);
315 return len
+ sprintf(buf
, "*isc*ip*\n");
318 static DEVICE_ATTR(modalias
, S_IRUGO
, show_modalias
, NULL
);
320 static struct attribute
*intf_attrs
[] = {
321 &dev_attr_bInterfaceNumber
.attr
,
322 &dev_attr_bAlternateSetting
.attr
,
323 &dev_attr_bNumEndpoints
.attr
,
324 &dev_attr_bInterfaceClass
.attr
,
325 &dev_attr_bInterfaceSubClass
.attr
,
326 &dev_attr_bInterfaceProtocol
.attr
,
327 &dev_attr_modalias
.attr
,
330 static struct attribute_group intf_attr_grp
= {
334 void usb_create_sysfs_intf_files (struct usb_interface
*intf
)
336 sysfs_create_group(&intf
->dev
.kobj
, &intf_attr_grp
);
338 if (intf
->cur_altsetting
->string
)
339 device_create_file(&intf
->dev
, &dev_attr_interface
);
343 void usb_remove_sysfs_intf_files (struct usb_interface
*intf
)
345 sysfs_remove_group(&intf
->dev
.kobj
, &intf_attr_grp
);
347 if (intf
->cur_altsetting
->string
)
348 device_remove_file(&intf
->dev
, &dev_attr_interface
);