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>
15 #include <linux/usb.h>
20 struct usb_endpoint_descriptor
*desc
;
21 struct usb_device
*udev
;
24 #define to_ep_object(_kobj) \
25 container_of(_kobj, struct ep_object, kobj)
28 struct attribute attr
;
29 ssize_t (*show
)(struct usb_device
*,
30 struct usb_endpoint_descriptor
*, char *);
32 #define to_ep_attribute(_attr) \
33 container_of(_attr, struct ep_attribute, attr)
35 #define EP_ATTR(_name) \
36 struct ep_attribute ep_##_name = { \
37 .attr = {.name = #_name, .owner = THIS_MODULE, \
39 .show = show_ep_##_name}
41 #define usb_ep_attr(field, format_string) \
42 static ssize_t show_ep_##field(struct usb_device *udev, \
43 struct usb_endpoint_descriptor *desc, \
46 return sprintf(buf, format_string, desc->field); \
48 static EP_ATTR(field);
50 usb_ep_attr(bLength
, "%02x\n")
51 usb_ep_attr(bEndpointAddress
, "%02x\n")
52 usb_ep_attr(bmAttributes
, "%02x\n")
53 usb_ep_attr(bInterval
, "%02x\n")
55 static ssize_t
show_ep_wMaxPacketSize(struct usb_device
*udev
,
56 struct usb_endpoint_descriptor
*desc
, char *buf
)
58 return sprintf(buf
, "%04x\n",
59 le16_to_cpu(desc
->wMaxPacketSize
) & 0x07ff);
61 static EP_ATTR(wMaxPacketSize
);
63 static ssize_t
show_ep_type(struct usb_device
*udev
,
64 struct usb_endpoint_descriptor
*desc
, char *buf
)
66 char *type
= "unknown";
68 switch (desc
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) {
69 case USB_ENDPOINT_XFER_CONTROL
:
72 case USB_ENDPOINT_XFER_ISOC
:
75 case USB_ENDPOINT_XFER_BULK
:
78 case USB_ENDPOINT_XFER_INT
:
82 return sprintf(buf
, "%s\n", type
);
86 static ssize_t
show_ep_interval(struct usb_device
*udev
,
87 struct usb_endpoint_descriptor
*desc
, char *buf
)
90 unsigned interval
= 0;
93 in
= (desc
->bEndpointAddress
& USB_DIR_IN
);
95 switch (desc
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) {
96 case USB_ENDPOINT_XFER_CONTROL
:
97 if (udev
->speed
== USB_SPEED_HIGH
) /* uframes per NAK */
98 interval
= desc
->bInterval
;
100 case USB_ENDPOINT_XFER_ISOC
:
101 interval
= 1 << (desc
->bInterval
- 1);
103 case USB_ENDPOINT_XFER_BULK
:
104 if (udev
->speed
== USB_SPEED_HIGH
&& !in
) /* uframes per NAK */
105 interval
= desc
->bInterval
;
107 case USB_ENDPOINT_XFER_INT
:
108 if (udev
->speed
== USB_SPEED_HIGH
)
109 interval
= 1 << (desc
->bInterval
- 1);
111 interval
= desc
->bInterval
;
114 interval
*= (udev
->speed
== USB_SPEED_HIGH
) ? 125 : 1000;
122 return sprintf(buf
, "%d%cs\n", interval
, unit
);
124 static EP_ATTR(interval
);
126 static ssize_t
show_ep_direction(struct usb_device
*udev
,
127 struct usb_endpoint_descriptor
*desc
, char *buf
)
131 if ((desc
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) ==
132 USB_ENDPOINT_XFER_CONTROL
)
134 else if (desc
->bEndpointAddress
& USB_DIR_IN
)
138 return sprintf(buf
, "%s\n", direction
);
140 static EP_ATTR(direction
);
142 static struct attribute
*ep_attrs
[] = {
144 &ep_bEndpointAddress
.attr
,
145 &ep_bmAttributes
.attr
,
147 &ep_wMaxPacketSize
.attr
,
154 static void ep_object_release(struct kobject
*kobj
)
156 kfree(to_ep_object(kobj
));
159 static ssize_t
ep_object_show(struct kobject
*kobj
, struct attribute
*attr
,
162 struct ep_object
*ep_obj
= to_ep_object(kobj
);
163 struct ep_attribute
*ep_attr
= to_ep_attribute(attr
);
165 return (ep_attr
->show
)(ep_obj
->udev
, ep_obj
->desc
, buf
);
168 static struct sysfs_ops ep_object_sysfs_ops
= {
169 .show
= ep_object_show
,
172 static struct kobj_type ep_object_ktype
= {
173 .release
= ep_object_release
,
174 .sysfs_ops
= &ep_object_sysfs_ops
,
175 .default_attrs
= ep_attrs
,
178 static void usb_create_ep_files(struct kobject
*parent
,
179 struct usb_host_endpoint
*endpoint
,
180 struct usb_device
*udev
)
182 struct ep_object
*ep_obj
;
183 struct kobject
*kobj
;
185 ep_obj
= kzalloc(sizeof(struct ep_object
), GFP_KERNEL
);
189 ep_obj
->desc
= &endpoint
->desc
;
192 kobj
= &ep_obj
->kobj
;
193 kobject_set_name(kobj
, "ep_%02x", endpoint
->desc
.bEndpointAddress
);
194 kobj
->parent
= parent
;
195 kobj
->ktype
= &ep_object_ktype
;
197 /* Don't use kobject_register, because it generates a hotplug event */
199 if (kobject_add(kobj
) == 0)
200 endpoint
->kobj
= kobj
;
205 static void usb_remove_ep_files(struct usb_host_endpoint
*endpoint
)
208 if (endpoint
->kobj
) {
209 kobject_del(endpoint
->kobj
);
210 kobject_put(endpoint
->kobj
);
211 endpoint
->kobj
= NULL
;
215 /* Active configuration fields */
216 #define usb_actconfig_show(field, multiplier, format_string) \
217 static ssize_t show_##field (struct device *dev, \
218 struct device_attribute *attr, char *buf) \
220 struct usb_device *udev; \
221 struct usb_host_config *actconfig; \
223 udev = to_usb_device (dev); \
224 actconfig = udev->actconfig; \
226 return sprintf (buf, format_string, \
227 actconfig->desc.field * multiplier); \
232 #define usb_actconfig_attr(field, multiplier, format_string) \
233 usb_actconfig_show(field, multiplier, format_string) \
234 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
236 usb_actconfig_attr (bNumInterfaces
, 1, "%2d\n")
237 usb_actconfig_attr (bmAttributes
, 1, "%2x\n")
238 usb_actconfig_attr (bMaxPower
, 2, "%3dmA\n")
240 static ssize_t
show_configuration_string(struct device
*dev
,
241 struct device_attribute
*attr
, char *buf
)
243 struct usb_device
*udev
;
244 struct usb_host_config
*actconfig
;
246 udev
= to_usb_device (dev
);
247 actconfig
= udev
->actconfig
;
248 if ((!actconfig
) || (!actconfig
->string
))
250 return sprintf(buf
, "%s\n", actconfig
->string
);
252 static DEVICE_ATTR(configuration
, S_IRUGO
, show_configuration_string
, NULL
);
254 /* configuration value is always present, and r/w */
255 usb_actconfig_show(bConfigurationValue
, 1, "%u\n");
258 set_bConfigurationValue (struct device
*dev
, struct device_attribute
*attr
,
259 const char *buf
, size_t count
)
261 struct usb_device
*udev
= udev
= to_usb_device (dev
);
264 if (sscanf (buf
, "%u", &config
) != 1 || config
> 255)
266 usb_lock_device(udev
);
267 value
= usb_set_configuration (udev
, config
);
268 usb_unlock_device(udev
);
269 return (value
< 0) ? value
: count
;
272 static DEVICE_ATTR(bConfigurationValue
, S_IRUGO
| S_IWUSR
,
273 show_bConfigurationValue
, set_bConfigurationValue
);
276 #define usb_string_attr(name) \
277 static ssize_t show_##name(struct device *dev, \
278 struct device_attribute *attr, char *buf) \
280 struct usb_device *udev; \
282 udev = to_usb_device (dev); \
283 return sprintf(buf, "%s\n", udev->name); \
285 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
287 usb_string_attr(product
);
288 usb_string_attr(manufacturer
);
289 usb_string_attr(serial
);
292 show_speed (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
294 struct usb_device
*udev
;
297 udev
= to_usb_device (dev
);
299 switch (udev
->speed
) {
303 case USB_SPEED_UNKNOWN
:
313 return sprintf (buf
, "%s\n", speed
);
315 static DEVICE_ATTR(speed
, S_IRUGO
, show_speed
, NULL
);
318 show_devnum (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
320 struct usb_device
*udev
;
322 udev
= to_usb_device (dev
);
323 return sprintf (buf
, "%d\n", udev
->devnum
);
325 static DEVICE_ATTR(devnum
, S_IRUGO
, show_devnum
, NULL
);
328 show_version (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
330 struct usb_device
*udev
;
333 udev
= to_usb_device(dev
);
334 bcdUSB
= le16_to_cpu(udev
->descriptor
.bcdUSB
);
335 return sprintf(buf
, "%2x.%02x\n", bcdUSB
>> 8, bcdUSB
& 0xff);
337 static DEVICE_ATTR(version
, S_IRUGO
, show_version
, NULL
);
340 show_maxchild (struct device
*dev
, struct device_attribute
*attr
, char *buf
)
342 struct usb_device
*udev
;
344 udev
= to_usb_device (dev
);
345 return sprintf (buf
, "%d\n", udev
->maxchild
);
347 static DEVICE_ATTR(maxchild
, S_IRUGO
, show_maxchild
, NULL
);
349 /* Descriptor fields */
350 #define usb_descriptor_attr_le16(field, format_string) \
352 show_##field (struct device *dev, struct device_attribute *attr, \
355 struct usb_device *udev; \
357 udev = to_usb_device (dev); \
358 return sprintf (buf, format_string, \
359 le16_to_cpu(udev->descriptor.field)); \
361 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
363 usb_descriptor_attr_le16(idVendor
, "%04x\n")
364 usb_descriptor_attr_le16(idProduct
, "%04x\n")
365 usb_descriptor_attr_le16(bcdDevice
, "%04x\n")
367 #define usb_descriptor_attr(field, format_string) \
369 show_##field (struct device *dev, struct device_attribute *attr, \
372 struct usb_device *udev; \
374 udev = to_usb_device (dev); \
375 return sprintf (buf, format_string, udev->descriptor.field); \
377 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
379 usb_descriptor_attr (bDeviceClass
, "%02x\n")
380 usb_descriptor_attr (bDeviceSubClass
, "%02x\n")
381 usb_descriptor_attr (bDeviceProtocol
, "%02x\n")
382 usb_descriptor_attr (bNumConfigurations
, "%d\n")
383 usb_descriptor_attr (bMaxPacketSize0
, "%d\n")
385 static struct attribute
*dev_attrs
[] = {
386 /* current configuration's attributes */
387 &dev_attr_bNumInterfaces
.attr
,
388 &dev_attr_bConfigurationValue
.attr
,
389 &dev_attr_bmAttributes
.attr
,
390 &dev_attr_bMaxPower
.attr
,
391 /* device attributes */
392 &dev_attr_idVendor
.attr
,
393 &dev_attr_idProduct
.attr
,
394 &dev_attr_bcdDevice
.attr
,
395 &dev_attr_bDeviceClass
.attr
,
396 &dev_attr_bDeviceSubClass
.attr
,
397 &dev_attr_bDeviceProtocol
.attr
,
398 &dev_attr_bNumConfigurations
.attr
,
399 &dev_attr_bMaxPacketSize0
.attr
,
400 &dev_attr_speed
.attr
,
401 &dev_attr_devnum
.attr
,
402 &dev_attr_version
.attr
,
403 &dev_attr_maxchild
.attr
,
406 static struct attribute_group dev_attr_grp
= {
410 void usb_create_sysfs_dev_files (struct usb_device
*udev
)
412 struct device
*dev
= &udev
->dev
;
414 sysfs_create_group(&dev
->kobj
, &dev_attr_grp
);
416 if (udev
->manufacturer
)
417 device_create_file (dev
, &dev_attr_manufacturer
);
419 device_create_file (dev
, &dev_attr_product
);
421 device_create_file (dev
, &dev_attr_serial
);
422 device_create_file (dev
, &dev_attr_configuration
);
423 usb_create_ep_files(&dev
->kobj
, &udev
->ep0
, udev
);
426 void usb_remove_sysfs_dev_files (struct usb_device
*udev
)
428 struct device
*dev
= &udev
->dev
;
430 usb_remove_ep_files(&udev
->ep0
);
431 sysfs_remove_group(&dev
->kobj
, &dev_attr_grp
);
433 if (udev
->manufacturer
)
434 device_remove_file(dev
, &dev_attr_manufacturer
);
436 device_remove_file(dev
, &dev_attr_product
);
438 device_remove_file(dev
, &dev_attr_serial
);
439 device_remove_file (dev
, &dev_attr_configuration
);
442 /* Interface fields */
443 #define usb_intf_attr(field, format_string) \
445 show_##field (struct device *dev, struct device_attribute *attr, \
448 struct usb_interface *intf = to_usb_interface (dev); \
450 return sprintf (buf, format_string, \
451 intf->cur_altsetting->desc.field); \
453 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
455 usb_intf_attr (bInterfaceNumber
, "%02x\n")
456 usb_intf_attr (bAlternateSetting
, "%2d\n")
457 usb_intf_attr (bNumEndpoints
, "%02x\n")
458 usb_intf_attr (bInterfaceClass
, "%02x\n")
459 usb_intf_attr (bInterfaceSubClass
, "%02x\n")
460 usb_intf_attr (bInterfaceProtocol
, "%02x\n")
462 static ssize_t
show_interface_string(struct device
*dev
,
463 struct device_attribute
*attr
, char *buf
)
465 struct usb_interface
*intf
;
466 struct usb_device
*udev
;
469 intf
= to_usb_interface (dev
);
470 udev
= interface_to_usbdev (intf
);
471 len
= snprintf(buf
, 256, "%s", intf
->cur_altsetting
->string
);
478 static DEVICE_ATTR(interface
, S_IRUGO
, show_interface_string
, NULL
);
480 static ssize_t
show_modalias(struct device
*dev
,
481 struct device_attribute
*attr
, char *buf
)
483 struct usb_interface
*intf
;
484 struct usb_device
*udev
;
485 struct usb_host_interface
*alt
;
487 intf
= to_usb_interface(dev
);
488 udev
= interface_to_usbdev(intf
);
489 alt
= intf
->cur_altsetting
;
491 return sprintf(buf
, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X"
492 "ic%02Xisc%02Xip%02X\n",
493 le16_to_cpu(udev
->descriptor
.idVendor
),
494 le16_to_cpu(udev
->descriptor
.idProduct
),
495 le16_to_cpu(udev
->descriptor
.bcdDevice
),
496 udev
->descriptor
.bDeviceClass
,
497 udev
->descriptor
.bDeviceSubClass
,
498 udev
->descriptor
.bDeviceProtocol
,
499 alt
->desc
.bInterfaceClass
,
500 alt
->desc
.bInterfaceSubClass
,
501 alt
->desc
.bInterfaceProtocol
);
503 static DEVICE_ATTR(modalias
, S_IRUGO
, show_modalias
, NULL
);
505 static struct attribute
*intf_attrs
[] = {
506 &dev_attr_bInterfaceNumber
.attr
,
507 &dev_attr_bAlternateSetting
.attr
,
508 &dev_attr_bNumEndpoints
.attr
,
509 &dev_attr_bInterfaceClass
.attr
,
510 &dev_attr_bInterfaceSubClass
.attr
,
511 &dev_attr_bInterfaceProtocol
.attr
,
512 &dev_attr_modalias
.attr
,
515 static struct attribute_group intf_attr_grp
= {
519 static inline void usb_create_intf_ep_files(struct usb_interface
*intf
,
520 struct usb_device
*udev
)
522 struct usb_host_interface
*iface_desc
;
525 iface_desc
= intf
->cur_altsetting
;
526 for (i
= 0; i
< iface_desc
->desc
.bNumEndpoints
; ++i
)
527 usb_create_ep_files(&intf
->dev
.kobj
, &iface_desc
->endpoint
[i
],
531 static inline void usb_remove_intf_ep_files(struct usb_interface
*intf
)
533 struct usb_host_interface
*iface_desc
;
536 iface_desc
= intf
->cur_altsetting
;
537 for (i
= 0; i
< iface_desc
->desc
.bNumEndpoints
; ++i
)
538 usb_remove_ep_files(&iface_desc
->endpoint
[i
]);
541 void usb_create_sysfs_intf_files (struct usb_interface
*intf
)
543 struct usb_device
*udev
= interface_to_usbdev(intf
);
544 struct usb_host_interface
*alt
= intf
->cur_altsetting
;
546 sysfs_create_group(&intf
->dev
.kobj
, &intf_attr_grp
);
548 if (alt
->string
== NULL
)
549 alt
->string
= usb_cache_string(udev
, alt
->desc
.iInterface
);
551 device_create_file(&intf
->dev
, &dev_attr_interface
);
552 usb_create_intf_ep_files(intf
, udev
);
555 void usb_remove_sysfs_intf_files (struct usb_interface
*intf
)
557 usb_remove_intf_ep_files(intf
);
558 sysfs_remove_group(&intf
->dev
.kobj
, &intf_attr_grp
);
560 if (intf
->cur_altsetting
->string
)
561 device_remove_file(&intf
->dev
, &dev_attr_interface
);