at v2.6.13-rc2 350 lines 9.8 kB view raw
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) \ 27static ssize_t show_##field (struct device *dev, struct device_attribute *attr, 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) \ 42usb_actconfig_show(field, multiplier, format_string) \ 43static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 44 45usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") 46usb_actconfig_attr (bmAttributes, 1, "%2x\n") 47usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") 48 49static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, 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} 66static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); 67 68/* configuration value is always present, and r/w */ 69usb_actconfig_show(bConfigurationValue, 1, "%u\n"); 70 71static ssize_t 72set_bConfigurationValue (struct device *dev, struct device_attribute *attr, 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 85static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, 86 show_bConfigurationValue, set_bConfigurationValue); 87 88/* String fields */ 89#define usb_string_attr(name) \ 90static ssize_t show_##name(struct device *dev, struct device_attribute *attr, 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} \ 103static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); 104 105usb_string_attr(product); 106usb_string_attr(manufacturer); 107usb_string_attr(serial); 108 109static ssize_t 110show_speed (struct device *dev, struct device_attribute *attr, 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} 133static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); 134 135static ssize_t 136show_devnum (struct device *dev, struct device_attribute *attr, char *buf) 137{ 138 struct usb_device *udev; 139 140 udev = to_usb_device (dev); 141 return sprintf (buf, "%d\n", udev->devnum); 142} 143static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); 144 145static ssize_t 146show_version (struct device *dev, struct device_attribute *attr, 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} 155static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); 156 157static ssize_t 158show_maxchild (struct device *dev, struct device_attribute *attr, char *buf) 159{ 160 struct usb_device *udev; 161 162 udev = to_usb_device (dev); 163 return sprintf (buf, "%d\n", udev->maxchild); 164} 165static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); 166 167/* Descriptor fields */ 168#define usb_descriptor_attr_le16(field, format_string) \ 169static ssize_t \ 170show_##field (struct device *dev, struct device_attribute *attr, 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} \ 178static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 179 180usb_descriptor_attr_le16(idVendor, "%04x\n") 181usb_descriptor_attr_le16(idProduct, "%04x\n") 182usb_descriptor_attr_le16(bcdDevice, "%04x\n") 183 184#define usb_descriptor_attr(field, format_string) \ 185static ssize_t \ 186show_##field (struct device *dev, struct device_attribute *attr, 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} \ 193static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 194 195usb_descriptor_attr (bDeviceClass, "%02x\n") 196usb_descriptor_attr (bDeviceSubClass, "%02x\n") 197usb_descriptor_attr (bDeviceProtocol, "%02x\n") 198usb_descriptor_attr (bNumConfigurations, "%d\n") 199 200static 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}; 220static struct attribute_group dev_attr_grp = { 221 .attrs = dev_attrs, 222}; 223 224void 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 239void 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) \ 256static ssize_t \ 257show_##field (struct device *dev, struct device_attribute *attr, 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} \ 263static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 264 265usb_intf_attr (bInterfaceNumber, "%02x\n") 266usb_intf_attr (bAlternateSetting, "%2d\n") 267usb_intf_attr (bNumEndpoints, "%02x\n") 268usb_intf_attr (bInterfaceClass, "%02x\n") 269usb_intf_attr (bInterfaceSubClass, "%02x\n") 270usb_intf_attr (bInterfaceProtocol, "%02x\n") 271 272static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, 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} 287static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); 288 289static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) 290{ 291 struct usb_interface *intf; 292 struct usb_device *udev; 293 int len; 294 295 intf = to_usb_interface(dev); 296 udev = interface_to_usbdev(intf); 297 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); 305 buf += len; 306 307 if (udev->descriptor.bDeviceClass == 0) { 308 struct usb_host_interface *alt = intf->cur_altsetting; 309 310 return len + sprintf(buf, "%02Xisc%02Xip%02X\n", 311 alt->desc.bInterfaceClass, 312 alt->desc.bInterfaceSubClass, 313 alt->desc.bInterfaceProtocol); 314 } else { 315 return len + sprintf(buf, "*isc*ip*\n"); 316 } 317} 318static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); 319 320static 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, 328 NULL, 329}; 330static struct attribute_group intf_attr_grp = { 331 .attrs = intf_attrs, 332}; 333 334void usb_create_sysfs_intf_files (struct usb_interface *intf) 335{ 336 sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); 337 338 if (intf->cur_altsetting->string) 339 device_create_file(&intf->dev, &dev_attr_interface); 340 341} 342 343void usb_remove_sysfs_intf_files (struct usb_interface *intf) 344{ 345 sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); 346 347 if (intf->cur_altsetting->string) 348 device_remove_file(&intf->dev, &dev_attr_interface); 349 350}