2005-04-17 02:20:36 +04:00
/*
* drivers / usb / core / sysfs . c
*
* ( C ) Copyright 2002 David Brownell
* ( C ) Copyright 2002 , 2004 Greg Kroah - Hartman
* ( C ) Copyright 2002 , 2004 IBM Corp .
*
* All of the sysfs file attributes for usb devices and interfaces .
*
*/
# include <linux/kernel.h>
2007-03-20 21:59:39 +03:00
# include <linux/string.h>
2005-04-17 02:20:36 +04:00
# include <linux/usb.h>
# include "usb.h"
/* Active configuration fields */
# define usb_actconfig_show(field, multiplier, format_string) \
2007-01-23 23:55:28 +03:00
static ssize_t show_ # # field ( struct device * dev , \
2005-10-24 23:36:00 +04:00
struct device_attribute * attr , char * buf ) \
2005-04-17 02:20:36 +04:00
{ \
struct usb_device * udev ; \
struct usb_host_config * actconfig ; \
\
2007-01-23 23:55:28 +03:00
udev = to_usb_device ( dev ) ; \
2005-04-17 02:20:36 +04:00
actconfig = udev - > actconfig ; \
if ( actconfig ) \
2007-01-23 23:55:28 +03:00
return sprintf ( buf , format_string , \
2005-04-17 02:20:36 +04:00
actconfig - > desc . field * multiplier ) ; \
else \
return 0 ; \
} \
# define usb_actconfig_attr(field, multiplier, format_string) \
usb_actconfig_show ( field , multiplier , format_string ) \
static DEVICE_ATTR ( field , S_IRUGO , show_ # # field , NULL ) ;
2007-01-23 23:55:28 +03:00
usb_actconfig_attr ( bNumInterfaces , 1 , " %2d \n " )
usb_actconfig_attr ( bmAttributes , 1 , " %2x \n " )
usb_actconfig_attr ( bMaxPower , 2 , " %3dmA \n " )
2005-04-17 02:20:36 +04:00
2005-10-24 23:36:00 +04:00
static ssize_t show_configuration_string ( struct device * dev ,
struct device_attribute * attr , char * buf )
2005-04-17 02:20:36 +04:00
{
struct usb_device * udev ;
struct usb_host_config * actconfig ;
2007-01-23 23:55:28 +03:00
udev = to_usb_device ( dev ) ;
2005-04-17 02:20:36 +04:00
actconfig = udev - > actconfig ;
if ( ( ! actconfig ) | | ( ! actconfig - > string ) )
return 0 ;
2005-10-25 00:24:14 +04:00
return sprintf ( buf , " %s \n " , actconfig - > string ) ;
2005-04-17 02:20:36 +04:00
}
static DEVICE_ATTR ( configuration , S_IRUGO , show_configuration_string , NULL ) ;
/* configuration value is always present, and r/w */
usb_actconfig_show ( bConfigurationValue , 1 , " %u \n " ) ;
static ssize_t
2007-01-23 23:55:28 +03:00
set_bConfigurationValue ( struct device * dev , struct device_attribute * attr ,
2005-10-24 23:36:00 +04:00
const char * buf , size_t count )
2005-04-17 02:20:36 +04:00
{
2007-01-23 23:55:28 +03:00
struct usb_device * udev = to_usb_device ( dev ) ;
2005-04-17 02:20:36 +04:00
int config , value ;
2007-02-09 00:40:43 +03:00
if ( sscanf ( buf , " %d " , & config ) ! = 1 | | config < - 1 | | config > 255 )
2005-04-17 02:20:36 +04:00
return - EINVAL ;
usb_lock_device ( udev ) ;
2007-01-23 23:55:28 +03:00
value = usb_set_configuration ( udev , config ) ;
2005-04-17 02:20:36 +04:00
usb_unlock_device ( udev ) ;
return ( value < 0 ) ? value : count ;
}
static DEVICE_ATTR ( bConfigurationValue , S_IRUGO | S_IWUSR ,
show_bConfigurationValue , set_bConfigurationValue ) ;
/* String fields */
# define usb_string_attr(name) \
2005-10-24 23:36:00 +04:00
static ssize_t show_ # # name ( struct device * dev , \
struct device_attribute * attr , char * buf ) \
2005-04-17 02:20:36 +04:00
{ \
struct usb_device * udev ; \
\
2007-01-23 23:55:28 +03:00
udev = to_usb_device ( dev ) ; \
2005-10-25 00:24:14 +04:00
return sprintf ( buf , " %s \n " , udev - > name ) ; \
2005-04-17 02:20:36 +04:00
} \
static DEVICE_ATTR ( name , S_IRUGO , show_ # # name , NULL ) ;
usb_string_attr ( product ) ;
usb_string_attr ( manufacturer ) ;
usb_string_attr ( serial ) ;
static ssize_t
2007-01-23 23:55:28 +03:00
show_speed ( struct device * dev , struct device_attribute * attr , char * buf )
2005-04-17 02:20:36 +04:00
{
struct usb_device * udev ;
char * speed ;
2007-01-23 23:55:28 +03:00
udev = to_usb_device ( dev ) ;
2005-04-17 02:20:36 +04:00
switch ( udev - > speed ) {
case USB_SPEED_LOW :
speed = " 1.5 " ;
break ;
case USB_SPEED_UNKNOWN :
case USB_SPEED_FULL :
speed = " 12 " ;
break ;
case USB_SPEED_HIGH :
speed = " 480 " ;
break ;
default :
speed = " unknown " ;
}
2007-01-23 23:55:28 +03:00
return sprintf ( buf , " %s \n " , speed ) ;
2005-04-17 02:20:36 +04:00
}
static DEVICE_ATTR ( speed , S_IRUGO , show_speed , NULL ) ;
static ssize_t
2007-01-23 23:55:28 +03:00
show_devnum ( struct device * dev , struct device_attribute * attr , char * buf )
2005-04-17 02:20:36 +04:00
{
struct usb_device * udev ;
2007-01-23 23:55:28 +03:00
udev = to_usb_device ( dev ) ;
return sprintf ( buf , " %d \n " , udev - > devnum ) ;
2005-04-17 02:20:36 +04:00
}
static DEVICE_ATTR ( devnum , S_IRUGO , show_devnum , NULL ) ;
static ssize_t
2007-01-23 23:55:28 +03:00
show_version ( struct device * dev , struct device_attribute * attr , char * buf )
2005-04-17 02:20:36 +04:00
{
struct usb_device * udev ;
u16 bcdUSB ;
udev = to_usb_device ( dev ) ;
bcdUSB = le16_to_cpu ( udev - > descriptor . bcdUSB ) ;
return sprintf ( buf , " %2x.%02x \n " , bcdUSB > > 8 , bcdUSB & 0xff ) ;
}
static DEVICE_ATTR ( version , S_IRUGO , show_version , NULL ) ;
static ssize_t
2007-01-23 23:55:28 +03:00
show_maxchild ( struct device * dev , struct device_attribute * attr , char * buf )
2005-04-17 02:20:36 +04:00
{
struct usb_device * udev ;
2007-01-23 23:55:28 +03:00
udev = to_usb_device ( dev ) ;
return sprintf ( buf , " %d \n " , udev - > maxchild ) ;
2005-04-17 02:20:36 +04:00
}
static DEVICE_ATTR ( maxchild , S_IRUGO , show_maxchild , NULL ) ;
2007-01-26 16:26:21 +03:00
static ssize_t
show_quirks ( struct device * dev , struct device_attribute * attr , char * buf )
{
struct usb_device * udev ;
udev = to_usb_device ( dev ) ;
return sprintf ( buf , " 0x%x \n " , udev - > quirks ) ;
}
static DEVICE_ATTR ( quirks , S_IRUGO , show_quirks , NULL ) ;
2007-02-20 23:03:32 +03:00
# ifdef CONFIG_USB_SUSPEND
static ssize_t
show_autosuspend ( struct device * dev , struct device_attribute * attr , char * buf )
{
struct usb_device * udev = to_usb_device ( dev ) ;
2007-03-13 23:39:15 +03:00
return sprintf ( buf , " %d \n " , udev - > autosuspend_delay / HZ ) ;
2007-02-20 23:03:32 +03:00
}
static ssize_t
set_autosuspend ( struct device * dev , struct device_attribute * attr ,
const char * buf , size_t count )
{
struct usb_device * udev = to_usb_device ( dev ) ;
2007-03-13 23:39:15 +03:00
int value ;
2007-02-20 23:03:32 +03:00
2007-03-13 23:39:15 +03:00
if ( sscanf ( buf , " %d " , & value ) ! = 1 | | value > = INT_MAX / HZ | |
value < = - INT_MAX / HZ )
2007-02-20 23:03:32 +03:00
return - EINVAL ;
value * = HZ ;
udev - > autosuspend_delay = value ;
2007-03-13 23:39:15 +03:00
if ( value > = 0 )
2007-02-20 23:03:32 +03:00
usb_try_autosuspend_device ( udev ) ;
2007-03-13 23:39:15 +03:00
else {
2007-03-20 21:59:39 +03:00
if ( usb_autoresume_device ( udev ) = = 0 )
usb_autosuspend_device ( udev ) ;
2007-03-13 23:39:15 +03:00
}
2007-02-20 23:03:32 +03:00
return count ;
}
static DEVICE_ATTR ( autosuspend , S_IRUGO | S_IWUSR ,
show_autosuspend , set_autosuspend ) ;
2007-03-20 21:59:39 +03:00
static const char on_string [ ] = " on " ;
static const char auto_string [ ] = " auto " ;
static const char suspend_string [ ] = " suspend " ;
static ssize_t
show_level ( struct device * dev , struct device_attribute * attr , char * buf )
{
struct usb_device * udev = to_usb_device ( dev ) ;
const char * p = auto_string ;
if ( udev - > state = = USB_STATE_SUSPENDED ) {
if ( udev - > autoresume_disabled )
p = suspend_string ;
} else {
if ( udev - > autosuspend_disabled )
p = on_string ;
}
return sprintf ( buf , " %s \n " , p ) ;
}
static ssize_t
set_level ( struct device * dev , struct device_attribute * attr ,
const char * buf , size_t count )
{
struct usb_device * udev = to_usb_device ( dev ) ;
int len = count ;
char * cp ;
int rc = 0 ;
cp = memchr ( buf , ' \n ' , count ) ;
if ( cp )
len = cp - buf ;
usb_lock_device ( udev ) ;
/* Setting the flags without calling usb_pm_lock is a subject to
* races , but who cares . . .
*/
if ( len = = sizeof on_string - 1 & &
strncmp ( buf , on_string , len ) = = 0 ) {
udev - > autosuspend_disabled = 1 ;
udev - > autoresume_disabled = 0 ;
rc = usb_external_resume_device ( udev ) ;
} else if ( len = = sizeof auto_string - 1 & &
strncmp ( buf , auto_string , len ) = = 0 ) {
udev - > autosuspend_disabled = 0 ;
udev - > autoresume_disabled = 0 ;
rc = usb_external_resume_device ( udev ) ;
} else if ( len = = sizeof suspend_string - 1 & &
strncmp ( buf , suspend_string , len ) = = 0 ) {
udev - > autosuspend_disabled = 0 ;
udev - > autoresume_disabled = 1 ;
rc = usb_external_suspend_device ( udev , PMSG_SUSPEND ) ;
} else
rc = - EINVAL ;
usb_unlock_device ( udev ) ;
return ( rc < 0 ? rc : count ) ;
}
static DEVICE_ATTR ( level , S_IRUGO | S_IWUSR , show_level , set_level ) ;
2007-02-20 23:03:32 +03:00
static char power_group [ ] = " power " ;
static int add_power_attributes ( struct device * dev )
{
int rc = 0 ;
2007-03-20 21:59:39 +03:00
if ( is_usb_device ( dev ) ) {
2007-02-20 23:03:32 +03:00
rc = sysfs_add_file_to_group ( & dev - > kobj ,
& dev_attr_autosuspend . attr ,
power_group ) ;
2007-03-20 21:59:39 +03:00
if ( rc = = 0 )
rc = sysfs_add_file_to_group ( & dev - > kobj ,
& dev_attr_level . attr ,
power_group ) ;
}
2007-02-20 23:03:32 +03:00
return rc ;
}
static void remove_power_attributes ( struct device * dev )
{
2007-03-20 21:59:39 +03:00
sysfs_remove_file_from_group ( & dev - > kobj ,
& dev_attr_level . attr ,
power_group ) ;
2007-02-20 23:03:32 +03:00
sysfs_remove_file_from_group ( & dev - > kobj ,
& dev_attr_autosuspend . attr ,
power_group ) ;
}
# else
# define add_power_attributes(dev) 0
# define remove_power_attributes(dev) do {} while (0)
# endif /* CONFIG_USB_SUSPEND */
2005-04-17 02:20:36 +04:00
/* Descriptor fields */
# define usb_descriptor_attr_le16(field, format_string) \
static ssize_t \
2007-01-23 23:55:28 +03:00
show_ # # field ( struct device * dev , struct device_attribute * attr , \
2005-10-24 23:36:00 +04:00
char * buf ) \
2005-04-17 02:20:36 +04:00
{ \
struct usb_device * udev ; \
\
2007-01-23 23:55:28 +03:00
udev = to_usb_device ( dev ) ; \
return sprintf ( buf , format_string , \
2005-04-17 02:20:36 +04:00
le16_to_cpu ( udev - > descriptor . field ) ) ; \
} \
static DEVICE_ATTR ( field , S_IRUGO , show_ # # field , NULL ) ;
usb_descriptor_attr_le16 ( idVendor , " %04x \n " )
usb_descriptor_attr_le16 ( idProduct , " %04x \n " )
usb_descriptor_attr_le16 ( bcdDevice , " %04x \n " )
# define usb_descriptor_attr(field, format_string) \
static ssize_t \
2007-01-23 23:55:28 +03:00
show_ # # field ( struct device * dev , struct device_attribute * attr , \
2005-10-24 23:36:00 +04:00
char * buf ) \
2005-04-17 02:20:36 +04:00
{ \
struct usb_device * udev ; \
\
2007-01-23 23:55:28 +03:00
udev = to_usb_device ( dev ) ; \
return sprintf ( buf , format_string , udev - > descriptor . field ) ; \
2005-04-17 02:20:36 +04:00
} \
static DEVICE_ATTR ( field , S_IRUGO , show_ # # field , NULL ) ;
2007-01-23 23:55:28 +03:00
usb_descriptor_attr ( bDeviceClass , " %02x \n " )
usb_descriptor_attr ( bDeviceSubClass , " %02x \n " )
usb_descriptor_attr ( bDeviceProtocol , " %02x \n " )
usb_descriptor_attr ( bNumConfigurations , " %d \n " )
usb_descriptor_attr ( bMaxPacketSize0 , " %d \n " )
2005-04-17 02:20:36 +04:00
static struct attribute * dev_attrs [ ] = {
/* current configuration's attributes */
2006-07-06 23:37:42 +04:00
& dev_attr_configuration . attr ,
2005-04-17 02:20:36 +04:00
& dev_attr_bNumInterfaces . attr ,
& dev_attr_bConfigurationValue . attr ,
& dev_attr_bmAttributes . attr ,
& dev_attr_bMaxPower . attr ,
/* device attributes */
& dev_attr_idVendor . attr ,
& dev_attr_idProduct . attr ,
& dev_attr_bcdDevice . attr ,
& dev_attr_bDeviceClass . attr ,
& dev_attr_bDeviceSubClass . attr ,
& dev_attr_bDeviceProtocol . attr ,
& dev_attr_bNumConfigurations . attr ,
2005-06-30 03:53:29 +04:00
& dev_attr_bMaxPacketSize0 . attr ,
2005-04-17 02:20:36 +04:00
& dev_attr_speed . attr ,
& dev_attr_devnum . attr ,
& dev_attr_version . attr ,
& dev_attr_maxchild . attr ,
2007-01-26 16:26:21 +03:00
& dev_attr_quirks . attr ,
2005-04-17 02:20:36 +04:00
NULL ,
} ;
static struct attribute_group dev_attr_grp = {
. attrs = dev_attrs ,
} ;
2006-08-28 22:43:25 +04:00
int usb_create_sysfs_dev_files ( struct usb_device * udev )
2005-04-17 02:20:36 +04:00
{
struct device * dev = & udev - > dev ;
2006-08-28 22:43:25 +04:00
int retval ;
2005-04-17 02:20:36 +04:00
2006-08-28 22:43:25 +04:00
retval = sysfs_create_group ( & dev - > kobj , & dev_attr_grp ) ;
if ( retval )
return retval ;
2005-04-17 02:20:36 +04:00
2007-02-20 23:03:32 +03:00
retval = add_power_attributes ( dev ) ;
if ( retval )
goto error ;
2006-08-28 22:43:25 +04:00
if ( udev - > manufacturer ) {
2007-01-23 23:55:28 +03:00
retval = device_create_file ( dev , & dev_attr_manufacturer ) ;
2006-08-28 22:43:25 +04:00
if ( retval )
goto error ;
}
if ( udev - > product ) {
2007-01-23 23:55:28 +03:00
retval = device_create_file ( dev , & dev_attr_product ) ;
2006-08-28 22:43:25 +04:00
if ( retval )
goto error ;
}
if ( udev - > serial ) {
2007-01-23 23:55:28 +03:00
retval = device_create_file ( dev , & dev_attr_serial ) ;
2006-08-28 22:43:25 +04:00
if ( retval )
goto error ;
}
retval = usb_create_ep_files ( dev , & udev - > ep0 , udev ) ;
if ( retval )
goto error ;
return 0 ;
error :
2007-02-20 22:59:59 +03:00
usb_remove_sysfs_dev_files ( udev ) ;
2006-08-28 22:43:25 +04:00
return retval ;
2005-04-17 02:20:36 +04:00
}
2007-01-23 23:55:28 +03:00
void usb_remove_sysfs_dev_files ( struct usb_device * udev )
2005-04-17 02:20:36 +04:00
{
struct device * dev = & udev - > dev ;
2005-10-25 23:56:06 +04:00
usb_remove_ep_files ( & udev - > ep0 ) ;
2007-02-20 22:59:59 +03:00
device_remove_file ( dev , & dev_attr_manufacturer ) ;
device_remove_file ( dev , & dev_attr_product ) ;
device_remove_file ( dev , & dev_attr_serial ) ;
2007-02-20 23:03:32 +03:00
remove_power_attributes ( dev ) ;
2005-04-17 02:20:36 +04:00
sysfs_remove_group ( & dev - > kobj , & dev_attr_grp ) ;
}
/* Interface fields */
# define usb_intf_attr(field, format_string) \
static ssize_t \
2007-01-23 23:55:28 +03:00
show_ # # field ( struct device * dev , struct device_attribute * attr , \
2005-10-24 23:36:00 +04:00
char * buf ) \
2005-04-17 02:20:36 +04:00
{ \
2007-01-23 23:55:28 +03:00
struct usb_interface * intf = to_usb_interface ( dev ) ; \
2005-04-17 02:20:36 +04:00
\
2007-01-23 23:55:28 +03:00
return sprintf ( buf , format_string , \
2005-10-24 23:36:00 +04:00
intf - > cur_altsetting - > desc . field ) ; \
2005-04-17 02:20:36 +04:00
} \
static DEVICE_ATTR ( field , S_IRUGO , show_ # # field , NULL ) ;
2007-01-23 23:55:28 +03:00
usb_intf_attr ( bInterfaceNumber , " %02x \n " )
usb_intf_attr ( bAlternateSetting , " %2d \n " )
usb_intf_attr ( bNumEndpoints , " %02x \n " )
usb_intf_attr ( bInterfaceClass , " %02x \n " )
usb_intf_attr ( bInterfaceSubClass , " %02x \n " )
usb_intf_attr ( bInterfaceProtocol , " %02x \n " )
2005-04-17 02:20:36 +04:00
2005-10-24 23:36:00 +04:00
static ssize_t show_interface_string ( struct device * dev ,
struct device_attribute * attr , char * buf )
2005-04-17 02:20:36 +04:00
{
struct usb_interface * intf ;
struct usb_device * udev ;
int len ;
2007-01-23 23:55:28 +03:00
intf = to_usb_interface ( dev ) ;
udev = interface_to_usbdev ( intf ) ;
2005-04-17 02:20:36 +04:00
len = snprintf ( buf , 256 , " %s " , intf - > cur_altsetting - > string ) ;
if ( len < 0 )
return 0 ;
buf [ len ] = ' \n ' ;
buf [ len + 1 ] = 0 ;
return len + 1 ;
}
static DEVICE_ATTR ( interface , S_IRUGO , show_interface_string , NULL ) ;
2005-10-24 23:36:00 +04:00
static ssize_t show_modalias ( struct device * dev ,
struct device_attribute * attr , char * buf )
2005-05-10 17:45:10 +04:00
{
struct usb_interface * intf ;
struct usb_device * udev ;
2005-06-21 08:15:16 +04:00
struct usb_host_interface * alt ;
2005-05-10 17:45:10 +04:00
intf = to_usb_interface ( dev ) ;
udev = interface_to_usbdev ( intf ) ;
2005-06-21 08:15:16 +04:00
alt = intf - > cur_altsetting ;
return sprintf ( buf , " usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X "
" ic%02Xisc%02Xip%02X \n " ,
le16_to_cpu ( udev - > descriptor . idVendor ) ,
le16_to_cpu ( udev - > descriptor . idProduct ) ,
le16_to_cpu ( udev - > descriptor . bcdDevice ) ,
udev - > descriptor . bDeviceClass ,
udev - > descriptor . bDeviceSubClass ,
udev - > descriptor . bDeviceProtocol ,
alt - > desc . bInterfaceClass ,
alt - > desc . bInterfaceSubClass ,
alt - > desc . bInterfaceProtocol ) ;
2005-05-10 17:45:10 +04:00
}
static DEVICE_ATTR ( modalias , S_IRUGO , show_modalias , NULL ) ;
2005-04-17 02:20:36 +04:00
static struct attribute * intf_attrs [ ] = {
& dev_attr_bInterfaceNumber . attr ,
& dev_attr_bAlternateSetting . attr ,
& dev_attr_bNumEndpoints . attr ,
& dev_attr_bInterfaceClass . attr ,
& dev_attr_bInterfaceSubClass . attr ,
& dev_attr_bInterfaceProtocol . attr ,
2005-05-10 17:45:10 +04:00
& dev_attr_modalias . attr ,
2005-04-17 02:20:36 +04:00
NULL ,
} ;
static struct attribute_group intf_attr_grp = {
. attrs = intf_attrs ,
} ;
2005-10-25 00:24:14 +04:00
static inline void usb_create_intf_ep_files ( struct usb_interface * intf ,
struct usb_device * udev )
2005-06-21 08:15:16 +04:00
{
struct usb_host_interface * iface_desc ;
int i ;
iface_desc = intf - > cur_altsetting ;
for ( i = 0 ; i < iface_desc - > desc . bNumEndpoints ; + + i )
2006-06-14 23:14:34 +04:00
usb_create_ep_files ( & intf - > dev , & iface_desc - > endpoint [ i ] ,
2005-10-25 00:24:14 +04:00
udev ) ;
2005-06-21 08:15:16 +04:00
}
2005-10-25 23:56:06 +04:00
static inline void usb_remove_intf_ep_files ( struct usb_interface * intf )
2005-06-21 08:15:16 +04:00
{
struct usb_host_interface * iface_desc ;
int i ;
iface_desc = intf - > cur_altsetting ;
for ( i = 0 ; i < iface_desc - > desc . bNumEndpoints ; + + i )
2005-10-25 23:56:06 +04:00
usb_remove_ep_files ( & iface_desc - > endpoint [ i ] ) ;
2005-06-21 08:15:16 +04:00
}
2006-08-28 22:43:25 +04:00
int usb_create_sysfs_intf_files ( struct usb_interface * intf )
2005-04-17 02:20:36 +04:00
{
2007-02-20 22:59:59 +03:00
struct device * dev = & intf - > dev ;
2005-10-25 00:24:14 +04:00
struct usb_device * udev = interface_to_usbdev ( intf ) ;
struct usb_host_interface * alt = intf - > cur_altsetting ;
2006-08-28 22:43:25 +04:00
int retval ;
2005-10-25 00:24:14 +04:00
2007-02-20 22:59:59 +03:00
retval = sysfs_create_group ( & dev - > kobj , & intf_attr_grp ) ;
2006-08-28 22:43:25 +04:00
if ( retval )
2007-02-20 22:59:59 +03:00
return retval ;
2005-04-17 02:20:36 +04:00
2005-10-25 00:24:14 +04:00
if ( alt - > string = = NULL )
alt - > string = usb_cache_string ( udev , alt - > desc . iInterface ) ;
if ( alt - > string )
2007-02-20 22:59:59 +03:00
retval = device_create_file ( dev , & dev_attr_interface ) ;
2005-10-25 00:24:14 +04:00
usb_create_intf_ep_files ( intf , udev ) ;
2006-08-28 22:43:25 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2007-01-23 23:55:28 +03:00
void usb_remove_sysfs_intf_files ( struct usb_interface * intf )
2005-04-17 02:20:36 +04:00
{
2007-02-20 22:59:59 +03:00
struct device * dev = & intf - > dev ;
2005-04-17 02:20:36 +04:00
2007-02-20 22:59:59 +03:00
usb_remove_intf_ep_files ( intf ) ;
device_remove_file ( dev , & dev_attr_interface ) ;
sysfs_remove_group ( & dev - > kobj , & intf_attr_grp ) ;
2005-04-17 02:20:36 +04:00
}