blob: 3f13fb678dcc44427a994ffa25813c36a2456fa4 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * f_serial.c - generic USB serial function driver
4 *
5 * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
6 * Copyright (C) 2008 by David Brownell
7 * Copyright (C) 2008 by Nokia Corporation
8 */
9
10#include <linux/slab.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/device.h>
14
15#include "u_serial.h"
16#include "gadget_chips.h"
17
18
19/*
20 * This function packages a simple "generic serial" port with no real
21 * control mechanisms, just raw data transfer over two bulk endpoints.
22 *
23 * Because it's not standardized, this isn't as interoperable as the
24 * CDC ACM driver. However, for many purposes it's just as functional
25 * if you can arrange appropriate host side drivers.
26 */
27
28struct f_gser {
29 struct gserial port;
30 u8 data_id;
31 u8 port_num;
32};
33
34static inline struct f_gser *func_to_gser(struct usb_function *f)
35{
36 return container_of(f, struct f_gser, port.func);
37}
38
39/*-------------------------------------------------------------------------*/
40
41/* interface descriptor: */
42
43static struct usb_interface_descriptor gser_interface_desc = {
44 .bLength = USB_DT_INTERFACE_SIZE,
45 .bDescriptorType = USB_DT_INTERFACE,
46 /* .bInterfaceNumber = DYNAMIC */
47 .bNumEndpoints = 2,
48 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
49 .bInterfaceSubClass = 0,
50 .bInterfaceProtocol = 0,
51 /* .iInterface = DYNAMIC */
52};
53
54/* full speed support: */
55
56static struct usb_endpoint_descriptor gser_fs_in_desc = {
57 .bLength = USB_DT_ENDPOINT_SIZE,
58 .bDescriptorType = USB_DT_ENDPOINT,
59 .bEndpointAddress = USB_DIR_IN,
60 .bmAttributes = USB_ENDPOINT_XFER_BULK,
61};
62
63static struct usb_endpoint_descriptor gser_fs_out_desc = {
64 .bLength = USB_DT_ENDPOINT_SIZE,
65 .bDescriptorType = USB_DT_ENDPOINT,
66 .bEndpointAddress = USB_DIR_OUT,
67 .bmAttributes = USB_ENDPOINT_XFER_BULK,
68};
69
70static struct usb_descriptor_header *gser_fs_function[] = {
71 (struct usb_descriptor_header *) &gser_interface_desc,
72 (struct usb_descriptor_header *) &gser_fs_in_desc,
73 (struct usb_descriptor_header *) &gser_fs_out_desc,
74 NULL,
75};
76
77/* high speed support: */
78
79static struct usb_endpoint_descriptor gser_hs_in_desc = {
80 .bLength = USB_DT_ENDPOINT_SIZE,
81 .bDescriptorType = USB_DT_ENDPOINT,
82 .bmAttributes = USB_ENDPOINT_XFER_BULK,
83 .wMaxPacketSize = cpu_to_le16(512),
84};
85
86static struct usb_endpoint_descriptor gser_hs_out_desc = {
87 .bLength = USB_DT_ENDPOINT_SIZE,
88 .bDescriptorType = USB_DT_ENDPOINT,
89 .bmAttributes = USB_ENDPOINT_XFER_BULK,
90 .wMaxPacketSize = cpu_to_le16(512),
91};
92
93static struct usb_descriptor_header *gser_hs_function[] = {
94 (struct usb_descriptor_header *) &gser_interface_desc,
95 (struct usb_descriptor_header *) &gser_hs_in_desc,
96 (struct usb_descriptor_header *) &gser_hs_out_desc,
97 NULL,
98};
99
100static struct usb_endpoint_descriptor gser_ss_in_desc = {
101 .bLength = USB_DT_ENDPOINT_SIZE,
102 .bDescriptorType = USB_DT_ENDPOINT,
103 .bmAttributes = USB_ENDPOINT_XFER_BULK,
104 .wMaxPacketSize = cpu_to_le16(1024),
105};
106
107static struct usb_endpoint_descriptor gser_ss_out_desc = {
108 .bLength = USB_DT_ENDPOINT_SIZE,
109 .bDescriptorType = USB_DT_ENDPOINT,
110 .bmAttributes = USB_ENDPOINT_XFER_BULK,
111 .wMaxPacketSize = cpu_to_le16(1024),
112};
113
114static struct usb_ss_ep_comp_descriptor gser_ss_bulk_comp_desc = {
115 .bLength = sizeof gser_ss_bulk_comp_desc,
116 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
117};
118
119static struct usb_descriptor_header *gser_ss_function[] = {
120 (struct usb_descriptor_header *) &gser_interface_desc,
121 (struct usb_descriptor_header *) &gser_ss_in_desc,
122 (struct usb_descriptor_header *) &gser_ss_bulk_comp_desc,
123 (struct usb_descriptor_header *) &gser_ss_out_desc,
124 (struct usb_descriptor_header *) &gser_ss_bulk_comp_desc,
125 NULL,
126};
127
128/* string descriptors: */
129
130static struct usb_string gser_string_defs[] = {
131 [0].s = "Generic Serial",
132 { } /* end of list */
133};
134
135static struct usb_gadget_strings gser_string_table = {
136 .language = 0x0409, /* en-us */
137 .strings = gser_string_defs,
138};
139
140static struct usb_gadget_strings *gser_strings[] = {
141 &gser_string_table,
142 NULL,
143};
144
145/*-------------------------------------------------------------------------*/
146
147static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
148{
149 struct f_gser *gser = func_to_gser(f);
150 struct usb_composite_dev *cdev = f->config->cdev;
151
152 /* we know alt == 0, so this is an activation or a reset */
153
154 if (gser->port.in->enabled) {
155 dev_info(&cdev->gadget->dev,
156 "reset generic ttyGS%d\n", gser->port_num);
157 gserial_disconnect(&gser->port);
158 }
159 if (!gser->port.in->desc || !gser->port.out->desc) {
160 dev_info(&cdev->gadget->dev,
161 "activate generic ttyGS%d\n", gser->port_num);
162 if (config_ep_by_speed(cdev->gadget, f, gser->port.in) ||
163 config_ep_by_speed(cdev->gadget, f, gser->port.out)) {
164 gser->port.in->desc = NULL;
165 gser->port.out->desc = NULL;
166 return -EINVAL;
167 }
168 }
169 gserial_connect(&gser->port, gser->port_num);
170 return 0;
171}
172
173static void gser_disable(struct usb_function *f)
174{
175 struct f_gser *gser = func_to_gser(f);
176 struct usb_composite_dev *cdev = f->config->cdev;
177
178 dev_info(&cdev->gadget->dev,
179 "generic ttyGS%d deactivated\n", gser->port_num);
180 gserial_disconnect(&gser->port);
181}
182
183/*-------------------------------------------------------------------------*/
184
185/* serial function driver setup/binding */
186
187static int gser_bind(struct usb_configuration *c, struct usb_function *f)
188{
189 struct usb_composite_dev *cdev = c->cdev;
190 struct f_gser *gser = func_to_gser(f);
191 int status;
192 struct usb_ep *ep;
193
194 /* REVISIT might want instance-specific strings to help
195 * distinguish instances ...
196 */
197
198 /* maybe allocate device-global string ID */
199 if (gser_string_defs[0].id == 0) {
200 status = usb_string_id(c->cdev);
201 if (status < 0) {
202 dev_info(&cdev->gadget->dev, "usb_string_id error %d\n", status);
203 return status;
204 }
205 gser_string_defs[0].id = status;
206 }
207
208 /* allocate instance-specific interface IDs */
209 status = usb_interface_id(c, f);
210 if (status < 0) {
211 dev_info(&cdev->gadget->dev, "gser usb_interface_id error %d\n", status);
212 goto fail;
213 }
214 gser->data_id = status;
215 gser_interface_desc.bInterfaceNumber = status;
216
217 status = -ENODEV;
218
219 /* allocate instance-specific endpoints */
220 ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_in_desc);
221 if (!ep) {
222 dev_info(&cdev->gadget->dev, "gser usb_ep_autoconfig in error\n");
223 goto fail;
224 }
225 gser->port.in = ep;
226
227 ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc);
228 if (!ep) {
229 dev_info(&cdev->gadget->dev, "gser usb_ep_autoconfig out error\n");
230 goto fail;
231 }
232
233 gser->port.out = ep;
234
235 /* support all relevant hardware speeds... we expect that when
236 * hardware is dual speed, all bulk-capable endpoints work at
237 * both speeds
238 */
239 gser_hs_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress;
240 gser_hs_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress;
241
242 gser_ss_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress;
243 gser_ss_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress;
244
245 status = usb_assign_descriptors(f, gser_fs_function, gser_hs_function,
246 gser_ss_function, gser_ss_function);
247 if (status) {
248 dev_info(&cdev->gadget->dev, "gser usb_assign_descriptors error %d\n", status);
249 goto fail;
250 }
251
252 dev_info(&cdev->gadget->dev, "generic ttyGSER%d: %s speed IN/%s OUT/%s\n",
253 gser->port_num,
254 gadget_is_superspeed(c->cdev->gadget) ? "super" :
255 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
256 gser->port.in->name, gser->port.out->name);
257 return 0;
258
259fail:
260 ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
261
262 return status;
263}
264
265static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item)
266{
267 return container_of(to_config_group(item), struct f_serial_opts,
268 func_inst.group);
269}
270
271static void serial_attr_release(struct config_item *item)
272{
273 struct f_serial_opts *opts = to_f_serial_opts(item);
274
275 usb_put_function_instance(&opts->func_inst);
276}
277
278static struct configfs_item_operations serial_item_ops = {
279 .release = serial_attr_release,
280};
281
282static ssize_t f_serial_port_num_show(struct config_item *item, char *page)
283{
284 return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
285}
286
287CONFIGFS_ATTR_RO(f_serial_, port_num);
288
289static struct configfs_attribute *acm_attrs[] = {
290 &f_serial_attr_port_num,
291 NULL,
292};
293
294static const struct config_item_type serial_func_type = {
295 .ct_item_ops = &serial_item_ops,
296 .ct_attrs = acm_attrs,
297 .ct_owner = THIS_MODULE,
298};
299
300static void gser_free_inst(struct usb_function_instance *f)
301{
302 struct f_serial_opts *opts;
303
304 opts = container_of(f, struct f_serial_opts, func_inst);
305 gserial_free_line(opts->port_num);
306 kfree(opts);
307}
308
309static struct usb_function_instance *gser_alloc_inst(void)
310{
311 struct f_serial_opts *opts;
312 int ret;
313
314 opts = kzalloc(sizeof(*opts), GFP_KERNEL);
315 if (!opts)
316 return ERR_PTR(-ENOMEM);
317
318 opts->func_inst.free_func_inst = gser_free_inst;
319 ret = gserial_alloc_line(&opts->port_num);
320 if (ret) {
321 kfree(opts);
322 return ERR_PTR(ret);
323 }
324 config_group_init_type_name(&opts->func_inst.group, "",
325 &serial_func_type);
326
327 return &opts->func_inst;
328}
329
330static void gser_free(struct usb_function *f)
331{
332 struct f_gser *serial;
333
334 serial = func_to_gser(f);
335 kfree(serial);
336}
337
338static void gser_unbind(struct usb_configuration *c, struct usb_function *f)
339{
340 usb_free_all_descriptors(f);
341
342#if defined(CONFIG_CPU_ASR18XX) && defined(CONFIG_USB_MVC2)
343 if (gadget_current_is_dualspeed(c->cdev->gadget))
344 gser_string_defs[0].id = 0;
345#endif
346}
347
348static struct usb_function *gser_alloc(struct usb_function_instance *fi)
349{
350 struct f_gser *gser;
351 struct f_serial_opts *opts;
352
353 /* allocate and initialize one new instance */
354 gser = kzalloc(sizeof(*gser), GFP_KERNEL);
355 if (!gser)
356 return ERR_PTR(-ENOMEM);
357
358 opts = container_of(fi, struct f_serial_opts, func_inst);
359
360 gser->port_num = opts->port_num;
361
362 gser->port.func.name = "gser";
363 gser->port.func.strings = gser_strings;
364 gser->port.func.bind = gser_bind;
365 gser->port.func.unbind = gser_unbind;
366 gser->port.func.set_alt = gser_set_alt;
367 gser->port.func.disable = gser_disable;
368 gser->port.func.free_func = gser_free;
369
370 return &gser->port.func;
371}
372
373DECLARE_USB_FUNCTION_INIT(gser, gser_alloc_inst, gser_alloc);
374MODULE_LICENSE("GPL");
375MODULE_AUTHOR("Al Borchers");
376MODULE_AUTHOR("David Brownell");