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, 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) \ 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, 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 } 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, 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 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, 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 } \ 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, 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 } 133 static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); 134 135 static ssize_t 136 show_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 } 143 static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); 144 145 static ssize_t 146 show_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 } 155 static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); 156 157 static ssize_t 158 show_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 } 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, 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 } \ 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, 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 } \ 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 usb_descriptor_attr (bMaxPacketSize0, "%d\n") 200 201 static struct attribute *dev_attrs[] = { 202 /* current configuration's attributes */ 203 &dev_attr_bNumInterfaces.attr, 204 &dev_attr_bConfigurationValue.attr, 205 &dev_attr_bmAttributes.attr, 206 &dev_attr_bMaxPower.attr, 207 /* device attributes */ 208 &dev_attr_idVendor.attr, 209 &dev_attr_idProduct.attr, 210 &dev_attr_bcdDevice.attr, 211 &dev_attr_bDeviceClass.attr, 212 &dev_attr_bDeviceSubClass.attr, 213 &dev_attr_bDeviceProtocol.attr, 214 &dev_attr_bNumConfigurations.attr, 215 &dev_attr_bMaxPacketSize0.attr, 216 &dev_attr_speed.attr, 217 &dev_attr_devnum.attr, 218 &dev_attr_version.attr, 219 &dev_attr_maxchild.attr, 220 NULL, 221 }; 222 static struct attribute_group dev_attr_grp = { 223 .attrs = dev_attrs, 224 }; 225 226 void usb_create_sysfs_dev_files (struct usb_device *udev) 227 { 228 struct device *dev = &udev->dev; 229 230 sysfs_create_group(&dev->kobj, &dev_attr_grp); 231 232 if (udev->manufacturer) 233 device_create_file (dev, &dev_attr_manufacturer); 234 if (udev->product) 235 device_create_file (dev, &dev_attr_product); 236 if (udev->serial) 237 device_create_file (dev, &dev_attr_serial); 238 device_create_file (dev, &dev_attr_configuration); 239 } 240 241 void usb_remove_sysfs_dev_files (struct usb_device *udev) 242 { 243 struct device *dev = &udev->dev; 244 245 sysfs_remove_group(&dev->kobj, &dev_attr_grp); 246 247 if (udev->descriptor.iManufacturer) 248 device_remove_file(dev, &dev_attr_manufacturer); 249 if (udev->descriptor.iProduct) 250 device_remove_file(dev, &dev_attr_product); 251 if (udev->descriptor.iSerialNumber) 252 device_remove_file(dev, &dev_attr_serial); 253 device_remove_file (dev, &dev_attr_configuration); 254 } 255 256 /* Interface fields */ 257 #define usb_intf_attr(field, format_string) \ 258 static ssize_t \ 259 show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ 260 { \ 261 struct usb_interface *intf = to_usb_interface (dev); \ 262 \ 263 return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \ 264 } \ 265 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); 266 267 usb_intf_attr (bInterfaceNumber, "%02x\n") 268 usb_intf_attr (bAlternateSetting, "%2d\n") 269 usb_intf_attr (bNumEndpoints, "%02x\n") 270 usb_intf_attr (bInterfaceClass, "%02x\n") 271 usb_intf_attr (bInterfaceSubClass, "%02x\n") 272 usb_intf_attr (bInterfaceProtocol, "%02x\n") 273 274 static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf) 275 { 276 struct usb_interface *intf; 277 struct usb_device *udev; 278 int len; 279 280 intf = to_usb_interface (dev); 281 udev = interface_to_usbdev (intf); 282 len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); 283 if (len < 0) 284 return 0; 285 buf[len] = '\n'; 286 buf[len+1] = 0; 287 return len+1; 288 } 289 static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); 290 291 static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) 292 { 293 struct usb_interface *intf; 294 struct usb_device *udev; 295 int len; 296 297 intf = to_usb_interface(dev); 298 udev = interface_to_usbdev(intf); 299 300 len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic", 301 le16_to_cpu(udev->descriptor.idVendor), 302 le16_to_cpu(udev->descriptor.idProduct), 303 le16_to_cpu(udev->descriptor.bcdDevice), 304 udev->descriptor.bDeviceClass, 305 udev->descriptor.bDeviceSubClass, 306 udev->descriptor.bDeviceProtocol); 307 buf += len; 308 309 if (udev->descriptor.bDeviceClass == 0) { 310 struct usb_host_interface *alt = intf->cur_altsetting; 311 312 return len + sprintf(buf, "%02Xisc%02Xip%02X\n", 313 alt->desc.bInterfaceClass, 314 alt->desc.bInterfaceSubClass, 315 alt->desc.bInterfaceProtocol); 316 } else { 317 return len + sprintf(buf, "*isc*ip*\n"); 318 } 319 } 320 static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); 321 322 static struct attribute *intf_attrs[] = { 323 &dev_attr_bInterfaceNumber.attr, 324 &dev_attr_bAlternateSetting.attr, 325 &dev_attr_bNumEndpoints.attr, 326 &dev_attr_bInterfaceClass.attr, 327 &dev_attr_bInterfaceSubClass.attr, 328 &dev_attr_bInterfaceProtocol.attr, 329 &dev_attr_modalias.attr, 330 NULL, 331 }; 332 static struct attribute_group intf_attr_grp = { 333 .attrs = intf_attrs, 334 }; 335 336 void usb_create_sysfs_intf_files (struct usb_interface *intf) 337 { 338 sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); 339 340 if (intf->cur_altsetting->string) 341 device_create_file(&intf->dev, &dev_attr_interface); 342 343 } 344 345 void usb_remove_sysfs_intf_files (struct usb_interface *intf) 346 { 347 sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); 348 349 if (intf->cur_altsetting->string) 350 device_remove_file(&intf->dev, &dev_attr_interface); 351 352 } 353