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 } 319