diff options
Diffstat (limited to 'drivers/usb/serial/metro-usb.c')
-rw-r--r-- | drivers/usb/serial/metro-usb.c | 65 |
1 files changed, 19 insertions, 46 deletions
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 0b257ddffbdb..6f29c74eb769 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c | |||
@@ -179,16 +179,13 @@ static void metrousb_cleanup(struct usb_serial_port *port) | |||
179 | { | 179 | { |
180 | dev_dbg(&port->dev, "%s\n", __func__); | 180 | dev_dbg(&port->dev, "%s\n", __func__); |
181 | 181 | ||
182 | if (port->serial->dev) { | 182 | usb_unlink_urb(port->interrupt_in_urb); |
183 | /* Shutdown any interrupt in urbs. */ | 183 | usb_kill_urb(port->interrupt_in_urb); |
184 | if (port->interrupt_in_urb) { | 184 | |
185 | usb_unlink_urb(port->interrupt_in_urb); | 185 | mutex_lock(&port->serial->disc_mutex); |
186 | usb_kill_urb(port->interrupt_in_urb); | 186 | if (!port->serial->disconnected) |
187 | } | ||
188 | |||
189 | /* Send deactivate cmd to device */ | ||
190 | metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); | 187 | metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); |
191 | } | 188 | mutex_unlock(&port->serial->disc_mutex); |
192 | } | 189 | } |
193 | 190 | ||
194 | static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) | 191 | static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) |
@@ -271,51 +268,27 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr | |||
271 | return retval; | 268 | return retval; |
272 | } | 269 | } |
273 | 270 | ||
274 | static void metrousb_shutdown(struct usb_serial *serial) | 271 | static int metrousb_port_probe(struct usb_serial_port *port) |
275 | { | 272 | { |
276 | int i = 0; | 273 | struct metrousb_private *metro_priv; |
277 | 274 | ||
278 | dev_dbg(&serial->dev->dev, "%s\n", __func__); | 275 | metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); |
276 | if (!metro_priv) | ||
277 | return -ENOMEM; | ||
279 | 278 | ||
280 | /* Stop reading and writing on all ports. */ | 279 | spin_lock_init(&metro_priv->lock); |
281 | for (i = 0; i < serial->num_ports; ++i) { | ||
282 | /* Close any open urbs. */ | ||
283 | metrousb_cleanup(serial->port[i]); | ||
284 | 280 | ||
285 | /* Free memory. */ | 281 | usb_set_serial_port_data(port, metro_priv); |
286 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
287 | usb_set_serial_port_data(serial->port[i], NULL); | ||
288 | 282 | ||
289 | dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n", | 283 | return 0; |
290 | __func__, serial->port[i]->number); | ||
291 | } | ||
292 | } | 284 | } |
293 | 285 | ||
294 | static int metrousb_startup(struct usb_serial *serial) | 286 | static int metrousb_port_remove(struct usb_serial_port *port) |
295 | { | 287 | { |
296 | struct metrousb_private *metro_priv; | 288 | struct metrousb_private *metro_priv; |
297 | struct usb_serial_port *port; | ||
298 | int i = 0; | ||
299 | 289 | ||
300 | dev_dbg(&serial->dev->dev, "%s\n", __func__); | 290 | metro_priv = usb_get_serial_port_data(port); |
301 | 291 | kfree(metro_priv); | |
302 | /* Loop through the serial ports setting up the private structures. | ||
303 | * Currently we only use one port. */ | ||
304 | for (i = 0; i < serial->num_ports; ++i) { | ||
305 | port = serial->port[i]; | ||
306 | |||
307 | /* Declare memory. */ | ||
308 | metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); | ||
309 | if (!metro_priv) | ||
310 | return -ENOMEM; | ||
311 | |||
312 | /* Initialize memory. */ | ||
313 | spin_lock_init(&metro_priv->lock); | ||
314 | usb_set_serial_port_data(port, metro_priv); | ||
315 | |||
316 | dev_dbg(&serial->dev->dev, "%s - port number=%d\n ", | ||
317 | __func__, port->number); | ||
318 | } | ||
319 | 292 | ||
320 | return 0; | 293 | return 0; |
321 | } | 294 | } |
@@ -414,8 +387,8 @@ static struct usb_serial_driver metrousb_device = { | |||
414 | .close = metrousb_cleanup, | 387 | .close = metrousb_cleanup, |
415 | .read_int_callback = metrousb_read_int_callback, | 388 | .read_int_callback = metrousb_read_int_callback, |
416 | .write_int_callback = metrousb_write_int_callback, | 389 | .write_int_callback = metrousb_write_int_callback, |
417 | .attach = metrousb_startup, | 390 | .port_probe = metrousb_port_probe, |
418 | .release = metrousb_shutdown, | 391 | .port_remove = metrousb_port_remove, |
419 | .throttle = metrousb_throttle, | 392 | .throttle = metrousb_throttle, |
420 | .unthrottle = metrousb_unthrottle, | 393 | .unthrottle = metrousb_unthrottle, |
421 | .tiocmget = metrousb_tiocmget, | 394 | .tiocmget = metrousb_tiocmget, |