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/kernel.h> 14 #include <linux/usb.h> 15 #include "usb.h" 16 17 /* Active configuration fields */ 18 #define usb_actconfig_show(field, multiplier, format_string) \ 19 static ssize_t show_##field(struct device *dev, \ 20 struct device_attribute *attr, char *buf) \ 21 { \ 22 struct usb_device *udev; \ 23 struct usb_host_config *actconfig; \ 24 \ 25 udev = to_usb_device(dev); \ 26 actconfig = udev->actconfig; \ 27 if (actconfig) \ 28 return sprintf(buf, format_string, \ 29 actconfig->desc.field * multiplier); \ 30 else \ 31 return 0; \ 32 } \ 33 34 #define usb_actconfig_attr(field, multiplier, format_string) \ 35 usb_actconfig_show(field, multiplier, format_string) \ 36 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 37 38 usb_actconfig_attr(bNumInterfaces, 1, "%2d\n") 39 usb_actconfig_attr(bmAttributes, 1, "%2x\n") 40 usb_actconfig_attr(bMaxPower, 2, "%3dmA\n") 41 42 static ssize_t show_configuration_string(struct device *dev, 43 struct device_attribute *attr, char *buf) 44 { 45 struct usb_device *udev; 46 struct usb_host_config *actconfig; 47 48 udev = to_usb_device(dev); 49 actconfig = udev->actconfig; 50 if ((!actconfig) || (!actconfig->string)) 51 return 0; 52 return sprintf(buf, "%s\n", actconfig->string); 53 } 54 static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); 55 56 /* configuration value is always present, and r/w */ 57 usb_actconfig_show(bConfigurationValue, 1, "%u\n"); 58 59 static ssize_t 60 set_bConfigurationValue(struct device *dev, struct device_attribute *attr, 61 const char *buf, size_t count) 62 { 63 struct usb_device *udev = to_usb_device(dev); 64 int config, value; 65 66 if (sscanf(buf, "%d", &config) != 1 || config < -1 || config > 255) 67 return -EINVAL; 68 usb_lock_device(udev); 69 value = usb_set_configuration(udev, config); 70 usb_unlock_device(udev); 71 return (value < 0) ? value : count; 72 } 73 74 static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, 75 show_bConfigurationValue, set_bConfigurationValue); 76 77 /* String fields */ 78 #define usb_string_attr(name) \ 79 static ssize_t show_##name(struct device *dev, \ 80 struct device_attribute *attr, char *buf) \ 81 { \ 82 struct usb_device *udev; \ 83 \ 84 udev = to_usb_device(dev); \ 85 return sprintf(buf, "%s\n", udev->name); \ 86 } \ 87 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); 88 89 usb_string_attr(product); 90 usb_string_attr(manufacturer); 91 usb_string_attr(serial); 92 93 static ssize_t 94 show_speed(struct device *dev, struct device_attribute *attr, char *buf) 95 { 96 struct usb_device *udev; 97 char *speed; 98 99 udev = to_usb_device(dev); 100 101 switch (udev->speed) { 102 case USB_SPEED_LOW: 103 speed = "1.5"; 104 break; 105 case USB_SPEED_UNKNOWN: 106 case USB_SPEED_FULL: 107 speed = "12"; 108 break; 109 case USB_SPEED_HIGH: 110 speed = "480"; 111 break; 112 default: 113 speed = "unknown"; 114 } 115 return sprintf(buf, "%s\n", speed); 116 } 117 static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); 118 119 static ssize_t 120 show_devnum(struct device *dev, struct device_attribute *attr, char *buf) 121 { 122 struct usb_device *udev; 123 124 udev = to_usb_device(dev); 125 return sprintf(buf, "%d\n", udev->devnum); 126 } 127 static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); 128 129 static ssize_t 130 show_version(struct device *dev, struct device_attribute *attr, char *buf) 131 { 132 struct usb_device *udev; 133 u16 bcdUSB; 134 135 udev = to_usb_device(dev); 136 bcdUSB = le16_to_cpu(udev->descriptor.bcdUSB); 137 return sprintf(buf, "%2x.%02x\n", bcdUSB >> 8, bcdUSB & 0xff); 138 } 139 static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); 140 141 static ssize_t 142 show_maxchild(struct device *dev, struct device_attribute *attr, char *buf) 143 { 144 struct usb_device *udev; 145 146 udev = to_usb_device(dev); 147 return sprintf(buf, "%d\n", udev->maxchild); 148 } 149 static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); 150 151 static ssize_t 152 show_quirks(struct device *dev, struct device_attribute *attr, char *buf) 153 { 154 struct usb_device *udev; 155 156 udev = to_usb_device(dev); 157 return sprintf(buf, "0x%x\n", udev->quirks); 158 } 159 static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); 160 161 #ifdef CONFIG_USB_SUSPEND 162 163 static ssize_t 164 show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf) 165 { 166 struct usb_device *udev = to_usb_device(dev); 167 168 return sprintf(buf, "%u\n", udev->autosuspend_delay / HZ); 169 } 170 171 static ssize_t 172 set_autosuspend(struct device *dev, struct device_attribute *attr, 173 const char *buf, size_t count) 174 { 175 struct usb_device *udev = to_usb_device(dev); 176 unsigned value, old; 177 178 if (sscanf(buf, "%u", &value) != 1 || value >= INT_MAX/HZ) 179 return -EINVAL; 180 value *= HZ; 181 182 old = udev->autosuspend_delay; 183 udev->autosuspend_delay = value; 184 if (value > 0 && old == 0) 185 usb_try_autosuspend_device(udev); 186 187 return count; 188 } 189 190 static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR, 191 show_autosuspend, set_autosuspend); 192 193 static char power_group[] = "power"; 194 195 static int add_power_attributes(struct device *dev) 196 { 197 int rc = 0; 198 199 if (is_usb_device(dev)) 200 rc = sysfs_add_file_to_group(&dev->kobj, 201 &dev_attr_autosuspend.attr, 202 power_group); 203 return rc; 204 } 205 206 static void remove_power_attributes(struct device *dev) 207 { 208 sysfs_remove_file_from_group(&dev->kobj, 209 &dev_attr_autosuspend.attr, 210 power_group); 211 } 212 213 #else 214 215 #define add_power_attributes(dev) 0 216 #define remove_power_attributes(dev) do {} while (0) 217 218 #endif /* CONFIG_USB_SUSPEND */ 219 220 /* Descriptor fields */ 221 #define usb_descriptor_attr_le16(field, format_string) \ 222 static ssize_t \ 223 show_##field(struct device *dev, struct device_attribute *attr, \ 224 char *buf) \ 225 { \ 226 struct usb_device *udev; \ 227 \ 228 udev = to_usb_device(dev); \ 229 return sprintf(buf, format_string, \ 230 le16_to_cpu(udev->descriptor.field)); \ 231 } \ 232 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 233 234 usb_descriptor_attr_le16(idVendor, "%04x\n") 235 usb_descriptor_attr_le16(idProduct, "%04x\n") 236 usb_descriptor_attr_le16(bcdDevice, "%04x\n") 237 238 #define usb_descriptor_attr(field, format_string) \ 239 static ssize_t \ 240 show_##field(struct device *dev, struct device_attribute *attr, \ 241 char *buf) \ 242 { \ 243 struct usb_device *udev; \ 244 \ 245 udev = to_usb_device(dev); \ 246 return sprintf(buf, format_string, udev->descriptor.field); \ 247 } \ 248 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 249 250 usb_descriptor_attr(bDeviceClass, "%02x\n") 251 usb_descriptor_attr(bDeviceSubClass, "%02x\n") 252 usb_descriptor_attr(bDeviceProtocol, "%02x\n") 253 usb_descriptor_attr(bNumConfigurations, "%d\n") 254 usb_descriptor_attr(bMaxPacketSize0, "%d\n") 255 256 static struct attribute *dev_attrs[] = { 257 /* current configuration's attributes */ 258 &dev_attr_configuration.attr, 259 &dev_attr_bNumInterfaces.attr, 260 &dev_attr_bConfigurationValue.attr, 261 &dev_attr_bmAttributes.attr, 262 &dev_attr_bMaxPower.attr, 263 /* device attributes */ 264 &dev_attr_idVendor.attr, 265 &dev_attr_idProduct.attr, 266 &dev_attr_bcdDevice.attr, 267 &dev_attr_bDeviceClass.attr, 268 &dev_attr_bDeviceSubClass.attr, 269 &dev_attr_bDeviceProtocol.attr, 270 &dev_attr_bNumConfigurations.attr, 271 &dev_attr_bMaxPacketSize0.attr, 272 &dev_attr_speed.attr, 273 &dev_attr_devnum.attr, 274 &dev_attr_version.attr, 275 &dev_attr_maxchild.attr, 276 &dev_attr_quirks.attr, 277 NULL, 278 }; 279 static struct attribute_group dev_attr_grp = { 280 .attrs = dev_attrs, 281 }; 282 283 int usb_create_sysfs_dev_files(struct usb_device *udev) 284 { 285 struct device *dev = &udev->dev; 286 int retval; 287 288 retval = sysfs_create_group(&dev->kobj, &dev_attr_grp); 289 if (retval) 290 return retval; 291 292 retval = add_power_attributes(dev); 293 if (retval) 294 goto error; 295 296 if (udev->manufacturer) { 297 retval = device_create_file(dev, &dev_attr_manufacturer); 298 if (retval) 299 goto error; 300 } 301 if (udev->product) { 302 retval = device_create_file(dev, &dev_attr_product); 303 if (retval) 304 goto error; 305 } 306 if (udev->serial) { 307 retval = device_create_file(dev, &dev_attr_serial); 308 if (retval) 309 goto error; 310 } 311 retval = usb_create_ep_files(dev, &udev->ep0, udev); 312 if (retval) 313 goto error; 314 return 0; 315 error: 316 usb_remove_sysfs_dev_files(udev); 317 return retval; 318 } 319 320 void usb_remove_sysfs_dev_files(struct usb_device *udev) 321 { 322 struct device *dev = &udev->dev; 323 324 usb_remove_ep_files(&udev->ep0); 325 device_remove_file(dev, &dev_attr_manufacturer); 326 device_remove_file(dev, &dev_attr_product); 327 device_remove_file(dev, &dev_attr_serial); 328 remove_power_attributes(dev); 329 sysfs_remove_group(&dev->kobj, &dev_attr_grp); 330 } 331 332 /* Interface fields */ 333 #define usb_intf_attr(field, format_string) \ 334 static ssize_t \ 335 show_##field(struct device *dev, struct device_attribute *attr, \ 336 char *buf) \ 337 { \ 338 struct usb_interface *intf = to_usb_interface(dev); \ 339 \ 340 return sprintf(buf, format_string, \ 341 intf->cur_altsetting->desc.field); \ 342 } \ 343 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 344 345 usb_intf_attr(bInterfaceNumber, "%02x\n") 346 usb_intf_attr(bAlternateSetting, "%2d\n") 347 usb_intf_attr(bNumEndpoints, "%02x\n") 348 usb_intf_attr(bInterfaceClass, "%02x\n") 349 usb_intf_attr(bInterfaceSubClass, "%02x\n") 350 usb_intf_attr(bInterfaceProtocol, "%02x\n") 351 352 static ssize_t show_interface_string(struct device *dev, 353 struct device_attribute *attr, char *buf) 354 { 355 struct usb_interface *intf; 356 struct usb_device *udev; 357 int len; 358 359 intf = to_usb_interface(dev); 360 udev = interface_to_usbdev(intf); 361 len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); 362 if (len < 0) 363 return 0; 364 buf[len] = '\n'; 365 buf[len+1] = 0; 366 return len+1; 367 } 368 static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); 369 370 static ssize_t show_modalias(struct device *dev, 371 struct device_attribute *attr, char *buf) 372 { 373 struct usb_interface *intf; 374 struct usb_device *udev; 375 struct usb_host_interface *alt; 376 377 intf = to_usb_interface(dev); 378 udev = interface_to_usbdev(intf); 379 alt = intf->cur_altsetting; 380 381 return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X" 382 "ic%02Xisc%02Xip%02X\n", 383 le16_to_cpu(udev->descriptor.idVendor), 384 le16_to_cpu(udev->descriptor.idProduct), 385 le16_to_cpu(udev->descriptor.bcdDevice), 386 udev->descriptor.bDeviceClass, 387 udev->descriptor.bDeviceSubClass, 388 udev->descriptor.bDeviceProtocol, 389 alt->desc.bInterfaceClass, 390 alt->desc.bInterfaceSubClass, 391 alt->desc.bInterfaceProtocol); 392 } 393 static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); 394 395 static struct attribute *intf_attrs[] = { 396 &dev_attr_bInterfaceNumber.attr, 397 &dev_attr_bAlternateSetting.attr, 398 &dev_attr_bNumEndpoints.attr, 399 &dev_attr_bInterfaceClass.attr, 400 &dev_attr_bInterfaceSubClass.attr, 401 &dev_attr_bInterfaceProtocol.attr, 402 &dev_attr_modalias.attr, 403 NULL, 404 }; 405 static struct attribute_group intf_attr_grp = { 406 .attrs = intf_attrs, 407 }; 408 409 static inline void usb_create_intf_ep_files(struct usb_interface *intf, 410 struct usb_device *udev) 411 { 412 struct usb_host_interface *iface_desc; 413 int i; 414 415 iface_desc = intf->cur_altsetting; 416 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) 417 usb_create_ep_files(&intf->dev, &iface_desc->endpoint[i], 418 udev); 419 } 420 421 static inline void usb_remove_intf_ep_files(struct usb_interface *intf) 422 { 423 struct usb_host_interface *iface_desc; 424 int i; 425 426 iface_desc = intf->cur_altsetting; 427 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) 428 usb_remove_ep_files(&iface_desc->endpoint[i]); 429 } 430 431 int usb_create_sysfs_intf_files(struct usb_interface *intf) 432 { 433 struct device *dev = &intf->dev; 434 struct usb_device *udev = interface_to_usbdev(intf); 435 struct usb_host_interface *alt = intf->cur_altsetting; 436 int retval; 437 438 retval = sysfs_create_group(&dev->kobj, &intf_attr_grp); 439 if (retval) 440 return retval; 441 442 if (alt->string == NULL) 443 alt->string = usb_cache_string(udev, alt->desc.iInterface); 444 if (alt->string) 445 retval = device_create_file(dev, &dev_attr_interface); 446 usb_create_intf_ep_files(intf, udev); 447 return 0; 448 } 449 450 void usb_remove_sysfs_intf_files(struct usb_interface *intf) 451 { 452 struct device *dev = &intf->dev; 453 454 usb_remove_intf_ep_files(intf); 455 device_remove_file(dev, &dev_attr_interface); 456 sysfs_remove_group(&dev->kobj, &intf_attr_grp); 457 } 458