Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[pandora-kernel.git] / drivers / usb / gadget / ncm.c
1 /*
2  * ncm.c -- NCM gadget driver
3  *
4  * Copyright (C) 2010 Nokia Corporation
5  * Contact: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
6  *
7  * The driver borrows from ether.c which is:
8  *
9  * Copyright (C) 2003-2005,2008 David Brownell
10  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
11  * Copyright (C) 2008 Nokia Corporation
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28 /* #define DEBUG */
29 /* #define VERBOSE_DEBUG */
30
31 #include <linux/kernel.h>
32 #include <linux/utsname.h>
33
34
35 #include "u_ether.h"
36
37 #define DRIVER_DESC             "NCM Gadget"
38
39 /*-------------------------------------------------------------------------*/
40
41 /*
42  * Kbuild is not very cooperative with respect to linking separately
43  * compiled library objects into one module.  So for now we won't use
44  * separate compilation ... ensuring init/exit sections work to shrink
45  * the runtime footprint, and giving us at least some parts of what
46  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
47  */
48 #include "composite.c"
49 #include "usbstring.c"
50 #include "config.c"
51 #include "epautoconf.c"
52
53 #include "f_ncm.c"
54 #include "u_ether.c"
55
56 /*-------------------------------------------------------------------------*/
57
58 /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
59  * Instead:  allocate your own, using normal USB-IF procedures.
60  */
61
62 /* Thanks to NetChip Technologies for donating this product ID.
63  * It's for devices with only CDC Ethernet configurations.
64  */
65 #define CDC_VENDOR_NUM          0x0525  /* NetChip */
66 #define CDC_PRODUCT_NUM         0xa4a1  /* Linux-USB Ethernet Gadget */
67
68 /*-------------------------------------------------------------------------*/
69
70 static struct usb_device_descriptor device_desc = {
71         .bLength =              sizeof device_desc,
72         .bDescriptorType =      USB_DT_DEVICE,
73
74         .bcdUSB =               cpu_to_le16 (0x0200),
75
76         .bDeviceClass =         USB_CLASS_COMM,
77         .bDeviceSubClass =      0,
78         .bDeviceProtocol =      0,
79         /* .bMaxPacketSize0 = f(hardware) */
80
81         /* Vendor and product id defaults change according to what configs
82          * we support.  (As does bNumConfigurations.)  These values can
83          * also be overridden by module parameters.
84          */
85         .idVendor =             cpu_to_le16 (CDC_VENDOR_NUM),
86         .idProduct =            cpu_to_le16 (CDC_PRODUCT_NUM),
87         /* .bcdDevice = f(hardware) */
88         /* .iManufacturer = DYNAMIC */
89         /* .iProduct = DYNAMIC */
90         /* NO SERIAL NUMBER */
91         .bNumConfigurations =   1,
92 };
93
94 static struct usb_otg_descriptor otg_descriptor = {
95         .bLength =              sizeof otg_descriptor,
96         .bDescriptorType =      USB_DT_OTG,
97
98         /* REVISIT SRP-only hardware is possible, although
99          * it would not be called "OTG" ...
100          */
101         .bmAttributes =         USB_OTG_SRP | USB_OTG_HNP,
102 };
103
104 static const struct usb_descriptor_header *otg_desc[] = {
105         (struct usb_descriptor_header *) &otg_descriptor,
106         NULL,
107 };
108
109
110 /* string IDs are assigned dynamically */
111
112 #define STRING_MANUFACTURER_IDX         0
113 #define STRING_PRODUCT_IDX              1
114
115 static char manufacturer[50];
116
117 static struct usb_string strings_dev[] = {
118         [STRING_MANUFACTURER_IDX].s = manufacturer,
119         [STRING_PRODUCT_IDX].s = DRIVER_DESC,
120         {  } /* end of list */
121 };
122
123 static struct usb_gadget_strings stringtab_dev = {
124         .language       = 0x0409,       /* en-us */
125         .strings        = strings_dev,
126 };
127
128 static struct usb_gadget_strings *dev_strings[] = {
129         &stringtab_dev,
130         NULL,
131 };
132
133 static u8 hostaddr[ETH_ALEN];
134
135 /*-------------------------------------------------------------------------*/
136
137 static int __init ncm_do_config(struct usb_configuration *c)
138 {
139         /* FIXME alloc iConfiguration string, set it in c->strings */
140
141         if (gadget_is_otg(c->cdev->gadget)) {
142                 c->descriptors = otg_desc;
143                 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
144         }
145
146         return ncm_bind_config(c, hostaddr);
147 }
148
149 static struct usb_configuration ncm_config_driver = {
150         /* .label = f(hardware) */
151         .label                  = "CDC Ethernet (NCM)",
152         .bConfigurationValue    = 1,
153         /* .iConfiguration = DYNAMIC */
154         .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
155 };
156
157 /*-------------------------------------------------------------------------*/
158
159 static int __init gncm_bind(struct usb_composite_dev *cdev)
160 {
161         int                     gcnum;
162         struct usb_gadget       *gadget = cdev->gadget;
163         int                     status;
164
165         /* set up network link layer */
166         status = gether_setup(cdev->gadget, hostaddr);
167         if (status < 0)
168                 return status;
169
170         gcnum = usb_gadget_controller_number(gadget);
171         if (gcnum >= 0)
172                 device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
173         else {
174                 /* We assume that can_support_ecm() tells the truth;
175                  * but if the controller isn't recognized at all then
176                  * that assumption is a bit more likely to be wrong.
177                  */
178                 dev_warn(&gadget->dev,
179                          "controller '%s' not recognized; trying %s\n",
180                          gadget->name,
181                          ncm_config_driver.label);
182                 device_desc.bcdDevice =
183                         cpu_to_le16(0x0300 | 0x0099);
184         }
185
186
187         /* Allocate string descriptor numbers ... note that string
188          * contents can be overridden by the composite_dev glue.
189          */
190
191         /* device descriptor strings: manufacturer, product */
192         snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
193                 init_utsname()->sysname, init_utsname()->release,
194                 gadget->name);
195         status = usb_string_id(cdev);
196         if (status < 0)
197                 goto fail;
198         strings_dev[STRING_MANUFACTURER_IDX].id = status;
199         device_desc.iManufacturer = status;
200
201         status = usb_string_id(cdev);
202         if (status < 0)
203                 goto fail;
204         strings_dev[STRING_PRODUCT_IDX].id = status;
205         device_desc.iProduct = status;
206
207         status = usb_add_config(cdev, &ncm_config_driver,
208                                 ncm_do_config);
209         if (status < 0)
210                 goto fail;
211
212         dev_info(&gadget->dev, "%s\n", DRIVER_DESC);
213
214         return 0;
215
216 fail:
217         gether_cleanup();
218         return status;
219 }
220
221 static int __exit gncm_unbind(struct usb_composite_dev *cdev)
222 {
223         gether_cleanup();
224         return 0;
225 }
226
227 static struct usb_composite_driver ncm_driver = {
228         .name           = "g_ncm",
229         .dev            = &device_desc,
230         .strings        = dev_strings,
231         .max_speed      = USB_SPEED_HIGH,
232         .unbind         = __exit_p(gncm_unbind),
233 };
234
235 MODULE_DESCRIPTION(DRIVER_DESC);
236 MODULE_AUTHOR("Yauheni Kaliuta");
237 MODULE_LICENSE("GPL");
238
239 static int __init init(void)
240 {
241         return usb_composite_probe(&ncm_driver, gncm_bind);
242 }
243 module_init(init);
244
245 static void __exit cleanup(void)
246 {
247         usb_composite_unregister(&ncm_driver);
248 }
249 module_exit(cleanup);