diff options
Diffstat (limited to 'drivers/usb/serial/qcserial.c')
-rw-r--r-- | drivers/usb/serial/qcserial.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 8858201eb1d3..54a9dab1f33b 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -111,7 +111,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
111 | ifnum = intf->desc.bInterfaceNumber; | 111 | ifnum = intf->desc.bInterfaceNumber; |
112 | dbg("This Interface = %d", ifnum); | 112 | dbg("This Interface = %d", ifnum); |
113 | 113 | ||
114 | data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), | 114 | data = kzalloc(sizeof(struct usb_wwan_intf_private), |
115 | GFP_KERNEL); | 115 | GFP_KERNEL); |
116 | if (!data) | 116 | if (!data) |
117 | return -ENOMEM; | 117 | return -ENOMEM; |
@@ -134,8 +134,10 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
134 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { | 134 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { |
135 | dbg("QDL port found"); | 135 | dbg("QDL port found"); |
136 | 136 | ||
137 | if (serial->interface->num_altsetting == 1) | 137 | if (serial->interface->num_altsetting == 1) { |
138 | return 0; | 138 | retval = 0; /* Success */ |
139 | break; | ||
140 | } | ||
139 | 141 | ||
140 | retval = usb_set_interface(serial->dev, ifnum, 1); | 142 | retval = usb_set_interface(serial->dev, ifnum, 1); |
141 | if (retval < 0) { | 143 | if (retval < 0) { |
@@ -145,7 +147,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
145 | retval = -ENODEV; | 147 | retval = -ENODEV; |
146 | kfree(data); | 148 | kfree(data); |
147 | } | 149 | } |
148 | return retval; | ||
149 | } | 150 | } |
150 | break; | 151 | break; |
151 | 152 | ||
@@ -166,6 +167,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
166 | "Could not set interface, error %d\n", | 167 | "Could not set interface, error %d\n", |
167 | retval); | 168 | retval); |
168 | retval = -ENODEV; | 169 | retval = -ENODEV; |
170 | kfree(data); | ||
169 | } | 171 | } |
170 | } else if (ifnum == 2) { | 172 | } else if (ifnum == 2) { |
171 | dbg("Modem port found"); | 173 | dbg("Modem port found"); |
@@ -177,7 +179,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
177 | retval = -ENODEV; | 179 | retval = -ENODEV; |
178 | kfree(data); | 180 | kfree(data); |
179 | } | 181 | } |
180 | return retval; | ||
181 | } else if (ifnum==3) { | 182 | } else if (ifnum==3) { |
182 | /* | 183 | /* |
183 | * NMEA (serial line 9600 8N1) | 184 | * NMEA (serial line 9600 8N1) |
@@ -191,6 +192,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
191 | "Could not set interface, error %d\n", | 192 | "Could not set interface, error %d\n", |
192 | retval); | 193 | retval); |
193 | retval = -ENODEV; | 194 | retval = -ENODEV; |
195 | kfree(data); | ||
194 | } | 196 | } |
195 | } | 197 | } |
196 | break; | 198 | break; |
@@ -199,12 +201,27 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
199 | dev_err(&serial->dev->dev, | 201 | dev_err(&serial->dev->dev, |
200 | "unknown number of interfaces: %d\n", nintf); | 202 | "unknown number of interfaces: %d\n", nintf); |
201 | kfree(data); | 203 | kfree(data); |
202 | return -ENODEV; | 204 | retval = -ENODEV; |
203 | } | 205 | } |
204 | 206 | ||
207 | /* Set serial->private if not returning -ENODEV */ | ||
208 | if (retval != -ENODEV) | ||
209 | usb_set_serial_data(serial, data); | ||
205 | return retval; | 210 | return retval; |
206 | } | 211 | } |
207 | 212 | ||
213 | static void qc_release(struct usb_serial *serial) | ||
214 | { | ||
215 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); | ||
216 | |||
217 | dbg("%s", __func__); | ||
218 | |||
219 | /* Call usb_wwan release & free the private data allocated in qcprobe */ | ||
220 | usb_wwan_release(serial); | ||
221 | usb_set_serial_data(serial, NULL); | ||
222 | kfree(priv); | ||
223 | } | ||
224 | |||
208 | static struct usb_serial_driver qcdevice = { | 225 | static struct usb_serial_driver qcdevice = { |
209 | .driver = { | 226 | .driver = { |
210 | .owner = THIS_MODULE, | 227 | .owner = THIS_MODULE, |
@@ -222,7 +239,7 @@ static struct usb_serial_driver qcdevice = { | |||
222 | .chars_in_buffer = usb_wwan_chars_in_buffer, | 239 | .chars_in_buffer = usb_wwan_chars_in_buffer, |
223 | .attach = usb_wwan_startup, | 240 | .attach = usb_wwan_startup, |
224 | .disconnect = usb_wwan_disconnect, | 241 | .disconnect = usb_wwan_disconnect, |
225 | .release = usb_wwan_release, | 242 | .release = qc_release, |
226 | #ifdef CONFIG_PM | 243 | #ifdef CONFIG_PM |
227 | .suspend = usb_wwan_suspend, | 244 | .suspend = usb_wwan_suspend, |
228 | .resume = usb_wwan_resume, | 245 | .resume = usb_wwan_resume, |