diff options
Diffstat (limited to 'drivers/usb/gadget/acm_ms.c')
-rw-r--r-- | drivers/usb/gadget/acm_ms.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 5a7f289805ff..8f2b0e391534 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c | |||
@@ -40,9 +40,6 @@ | |||
40 | * the runtime footprint, and giving us at least some parts of what | 40 | * the runtime footprint, and giving us at least some parts of what |
41 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | 41 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. |
42 | */ | 42 | */ |
43 | |||
44 | #include "u_serial.c" | ||
45 | #include "f_acm.c" | ||
46 | #include "f_mass_storage.c" | 43 | #include "f_mass_storage.c" |
47 | 44 | ||
48 | /*-------------------------------------------------------------------------*/ | 45 | /*-------------------------------------------------------------------------*/ |
@@ -112,12 +109,15 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); | |||
112 | static struct fsg_common fsg_common; | 109 | static struct fsg_common fsg_common; |
113 | 110 | ||
114 | /*-------------------------------------------------------------------------*/ | 111 | /*-------------------------------------------------------------------------*/ |
115 | 112 | static unsigned char tty_line; | |
113 | static struct usb_function *f_acm; | ||
114 | static struct usb_function_instance *f_acm_inst; | ||
116 | /* | 115 | /* |
117 | * We _always_ have both ACM and mass storage functions. | 116 | * We _always_ have both ACM and mass storage functions. |
118 | */ | 117 | */ |
119 | static int __init acm_ms_do_config(struct usb_configuration *c) | 118 | static int __init acm_ms_do_config(struct usb_configuration *c) |
120 | { | 119 | { |
120 | struct f_serial_opts *opts; | ||
121 | int status; | 121 | int status; |
122 | 122 | ||
123 | if (gadget_is_otg(c->cdev->gadget)) { | 123 | if (gadget_is_otg(c->cdev->gadget)) { |
@@ -125,16 +125,35 @@ static int __init acm_ms_do_config(struct usb_configuration *c) | |||
125 | c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 125 | c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
126 | } | 126 | } |
127 | 127 | ||
128 | f_acm_inst = usb_get_function_instance("acm"); | ||
129 | if (IS_ERR(f_acm_inst)) | ||
130 | return PTR_ERR(f_acm_inst); | ||
131 | |||
132 | opts = container_of(f_acm_inst, struct f_serial_opts, func_inst); | ||
133 | opts->port_num = tty_line; | ||
134 | |||
135 | f_acm = usb_get_function(f_acm_inst); | ||
136 | if (IS_ERR(f_acm)) { | ||
137 | status = PTR_ERR(f_acm); | ||
138 | goto err_func; | ||
139 | } | ||
128 | 140 | ||
129 | status = acm_bind_config(c, 0); | 141 | status = usb_add_function(c, f_acm); |
130 | if (status < 0) | 142 | if (status < 0) |
131 | return status; | 143 | goto err_conf; |
132 | 144 | ||
133 | status = fsg_bind_config(c->cdev, c, &fsg_common); | 145 | status = fsg_bind_config(c->cdev, c, &fsg_common); |
134 | if (status < 0) | 146 | if (status < 0) |
135 | return status; | 147 | goto err_fsg; |
136 | 148 | ||
137 | return 0; | 149 | return 0; |
150 | err_fsg: | ||
151 | usb_remove_function(c, f_acm); | ||
152 | err_conf: | ||
153 | usb_put_function(f_acm); | ||
154 | err_func: | ||
155 | usb_put_function_instance(f_acm_inst); | ||
156 | return status; | ||
138 | } | 157 | } |
139 | 158 | ||
140 | static struct usb_configuration acm_ms_config_driver = { | 159 | static struct usb_configuration acm_ms_config_driver = { |
@@ -153,7 +172,7 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) | |||
153 | void *retp; | 172 | void *retp; |
154 | 173 | ||
155 | /* set up serial link layer */ | 174 | /* set up serial link layer */ |
156 | status = gserial_setup(cdev->gadget, 1); | 175 | status = gserial_alloc_line(&tty_line); |
157 | if (status < 0) | 176 | if (status < 0) |
158 | return status; | 177 | return status; |
159 | 178 | ||
@@ -189,14 +208,15 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) | |||
189 | fail1: | 208 | fail1: |
190 | fsg_common_put(&fsg_common); | 209 | fsg_common_put(&fsg_common); |
191 | fail0: | 210 | fail0: |
192 | gserial_cleanup(); | 211 | gserial_free_line(tty_line); |
193 | return status; | 212 | return status; |
194 | } | 213 | } |
195 | 214 | ||
196 | static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) | 215 | static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) |
197 | { | 216 | { |
198 | gserial_cleanup(); | 217 | usb_put_function(f_acm); |
199 | 218 | usb_put_function_instance(f_acm_inst); | |
219 | gserial_free_line(tty_line); | ||
200 | return 0; | 220 | return 0; |
201 | } | 221 | } |
202 | 222 | ||