Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
846 | giacomo | 1 | /* |
2 | * drivers/usb/core/driverfs.c |
||
3 | * |
||
4 | * (C) Copyright 2002 David Brownell |
||
5 | * (C) Copyright 2002 Greg Kroah-Hartman |
||
6 | * (C) Copyright 2002 IBM Corp. |
||
7 | * |
||
8 | * All of the driverfs file attributes for usb devices and interfaces. |
||
9 | * |
||
10 | */ |
||
11 | |||
12 | |||
13 | #include <linuxcomp.h> |
||
14 | |||
15 | #include <linux/config.h> |
||
16 | #include <linux/kernel.h> |
||
17 | |||
18 | #ifdef CONFIG_USB_DEBUG |
||
19 | #define DEBUG |
||
20 | #else |
||
21 | #undef DEBUG |
||
22 | #endif |
||
23 | #include <linux/usb.h> |
||
24 | |||
25 | #include "usb.h" |
||
26 | |||
27 | /* Active configuration fields */ |
||
28 | #define usb_actconfig_show(field, format_string) \ |
||
29 | static ssize_t \ |
||
30 | show_##field (struct device *dev, char *buf) \ |
||
31 | { \ |
||
32 | struct usb_device *udev; \ |
||
33 | \ |
||
34 | udev = to_usb_device (dev); \ |
||
35 | if (udev->actconfig) \ |
||
36 | return sprintf26 (buf, format_string, udev->actconfig->desc.field); \ |
||
37 | else return 0; \ |
||
38 | } \ |
||
39 | |||
40 | #define usb_actconfig_attr(field, format_string) \ |
||
41 | usb_actconfig_show(field,format_string) \ |
||
42 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
||
43 | |||
44 | usb_actconfig_attr (bNumInterfaces, "%2d\n") |
||
45 | usb_actconfig_attr (bmAttributes, "%2x\n") |
||
46 | usb_actconfig_attr (bMaxPower, "%3dmA\n") |
||
47 | |||
48 | /* configuration value is always present, and r/w */ |
||
49 | usb_actconfig_show(bConfigurationValue,"%u\n"); |
||
50 | |||
51 | static ssize_t |
||
52 | set_bConfigurationValue (struct device *dev, const char *buf, size_t count) |
||
53 | { |
||
54 | struct usb_device *udev = udev = to_usb_device (dev); |
||
55 | int config, value; |
||
56 | |||
57 | if (sscanf26(buf, "%u", &config) != 1 || config > 255) |
||
58 | return -EINVAL; |
||
59 | value = usb_set_configuration (udev, config); |
||
60 | return (value < 0) ? value : count; |
||
61 | } |
||
62 | |||
63 | static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, |
||
64 | show_bConfigurationValue, set_bConfigurationValue); |
||
65 | |||
66 | /* String fields */ |
||
67 | static ssize_t show_product (struct device *dev, char *buf) |
||
68 | { |
||
69 | struct usb_device *udev; |
||
70 | int len; |
||
71 | |||
72 | udev = to_usb_device (dev); |
||
73 | |||
74 | len = usb_string(udev, udev->descriptor.iProduct, buf, PAGE_SIZE); |
||
75 | if (len < 0) |
||
76 | return 0; |
||
77 | buf[len] = '\n'; |
||
78 | buf[len+1] = 0; |
||
79 | return len+1; |
||
80 | } |
||
81 | static DEVICE_ATTR(product,S_IRUGO,show_product,NULL); |
||
82 | |||
83 | static ssize_t |
||
84 | show_manufacturer (struct device *dev, char *buf) |
||
85 | { |
||
86 | struct usb_device *udev; |
||
87 | int len; |
||
88 | |||
89 | udev = to_usb_device (dev); |
||
90 | |||
91 | len = usb_string(udev, udev->descriptor.iManufacturer, buf, PAGE_SIZE); |
||
92 | if (len < 0) |
||
93 | return 0; |
||
94 | buf[len] = '\n'; |
||
95 | buf[len+1] = 0; |
||
96 | return len+1; |
||
97 | } |
||
98 | static DEVICE_ATTR(manufacturer,S_IRUGO,show_manufacturer,NULL); |
||
99 | |||
100 | static ssize_t |
||
101 | show_serial (struct device *dev, char *buf) |
||
102 | { |
||
103 | struct usb_device *udev; |
||
104 | int len; |
||
105 | |||
106 | udev = to_usb_device (dev); |
||
107 | |||
108 | len = usb_string(udev, udev->descriptor.iSerialNumber, buf, PAGE_SIZE); |
||
109 | if (len < 0) |
||
110 | return 0; |
||
111 | buf[len] = '\n'; |
||
112 | buf[len+1] = 0; |
||
113 | return len+1; |
||
114 | } |
||
115 | static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL); |
||
116 | |||
117 | static ssize_t |
||
118 | show_speed (struct device *dev, char *buf) |
||
119 | { |
||
120 | struct usb_device *udev; |
||
121 | char *speed; |
||
122 | |||
123 | udev = to_usb_device (dev); |
||
124 | |||
125 | switch (udev->speed) { |
||
126 | case USB_SPEED_LOW: |
||
127 | speed = "1.5"; |
||
128 | break; |
||
129 | case USB_SPEED_UNKNOWN: |
||
130 | case USB_SPEED_FULL: |
||
131 | speed = "12"; |
||
132 | break; |
||
133 | case USB_SPEED_HIGH: |
||
134 | speed = "480"; |
||
135 | break; |
||
136 | default: |
||
137 | speed = "unknown"; |
||
138 | } |
||
139 | return sprintf26 (buf, "%s\n", speed); |
||
140 | } |
||
141 | static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); |
||
142 | |||
143 | /* Descriptor fields */ |
||
144 | #define usb_descriptor_attr(field, format_string) \ |
||
145 | static ssize_t \ |
||
146 | show_##field (struct device *dev, char *buf) \ |
||
147 | { \ |
||
148 | struct usb_device *udev; \ |
||
149 | \ |
||
150 | udev = to_usb_device (dev); \ |
||
151 | return sprintf26 (buf, format_string, udev->descriptor.field); \ |
||
152 | } \ |
||
153 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
||
154 | |||
155 | usb_descriptor_attr (idVendor, "%04x\n") |
||
156 | usb_descriptor_attr (idProduct, "%04x\n") |
||
157 | usb_descriptor_attr (bcdDevice, "%04x\n") |
||
158 | usb_descriptor_attr (bDeviceClass, "%02x\n") |
||
159 | usb_descriptor_attr (bDeviceSubClass, "%02x\n") |
||
160 | usb_descriptor_attr (bDeviceProtocol, "%02x\n") |
||
161 | usb_descriptor_attr (bNumConfigurations, "%d\n") |
||
162 | |||
163 | |||
164 | void usb_create_driverfs_dev_files (struct usb_device *udev) |
||
165 | { |
||
166 | struct device *dev = &udev->dev; |
||
167 | |||
168 | /* current configuration's attributes */ |
||
169 | device_create_file (dev, &dev_attr_bNumInterfaces); |
||
170 | device_create_file (dev, &dev_attr_bConfigurationValue); |
||
171 | device_create_file (dev, &dev_attr_bmAttributes); |
||
172 | device_create_file (dev, &dev_attr_bMaxPower); |
||
173 | |||
174 | /* device attributes */ |
||
175 | device_create_file (dev, &dev_attr_idVendor); |
||
176 | device_create_file (dev, &dev_attr_idProduct); |
||
177 | device_create_file (dev, &dev_attr_bcdDevice); |
||
178 | device_create_file (dev, &dev_attr_bDeviceClass); |
||
179 | device_create_file (dev, &dev_attr_bDeviceSubClass); |
||
180 | device_create_file (dev, &dev_attr_bDeviceProtocol); |
||
181 | device_create_file (dev, &dev_attr_bNumConfigurations); |
||
182 | |||
183 | /* speed varies depending on how you connect the device */ |
||
184 | device_create_file (dev, &dev_attr_speed); |
||
185 | // FIXME iff there are other speed configs, show how many |
||
186 | |||
187 | if (udev->descriptor.iManufacturer) |
||
188 | device_create_file (dev, &dev_attr_manufacturer); |
||
189 | if (udev->descriptor.iProduct) |
||
190 | device_create_file (dev, &dev_attr_product); |
||
191 | if (udev->descriptor.iSerialNumber) |
||
192 | device_create_file (dev, &dev_attr_serial); |
||
193 | } |
||
194 | |||
195 | /* Interface fields */ |
||
196 | #define usb_intf_attr(field, format_string) \ |
||
197 | static ssize_t \ |
||
198 | show_##field (struct device *dev, char *buf) \ |
||
199 | { \ |
||
200 | struct usb_interface *intf; \ |
||
201 | int alt; \ |
||
202 | \ |
||
203 | intf = to_usb_interface (dev); \ |
||
204 | alt = intf->act_altsetting; \ |
||
205 | \ |
||
206 | return sprintf26 (buf, format_string, intf->altsetting[alt].desc.field); \ |
||
207 | } \ |
||
208 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
||
209 | |||
210 | usb_intf_attr (bInterfaceNumber, "%02x\n") |
||
211 | usb_intf_attr (bAlternateSetting, "%2d\n") |
||
212 | usb_intf_attr (bNumEndpoints, "%02x\n") |
||
213 | usb_intf_attr (bInterfaceClass, "%02x\n") |
||
214 | usb_intf_attr (bInterfaceSubClass, "%02x\n") |
||
215 | usb_intf_attr (bInterfaceProtocol, "%02x\n") |
||
216 | usb_intf_attr (iInterface, "%02x\n") |
||
217 | |||
218 | void usb_create_driverfs_intf_files (struct usb_interface *intf) |
||
219 | { |
||
220 | device_create_file (&intf->dev, &dev_attr_bInterfaceNumber); |
||
221 | device_create_file (&intf->dev, &dev_attr_bAlternateSetting); |
||
222 | device_create_file (&intf->dev, &dev_attr_bNumEndpoints); |
||
223 | device_create_file (&intf->dev, &dev_attr_bInterfaceClass); |
||
224 | device_create_file (&intf->dev, &dev_attr_bInterfaceSubClass); |
||
225 | device_create_file (&intf->dev, &dev_attr_bInterfaceProtocol); |
||
226 | device_create_file (&intf->dev, &dev_attr_iInterface); |
||
227 | } |