aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/metro-usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/metro-usb.c')
-rw-r--r--drivers/usb/serial/metro-usb.c65
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
194static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) 191static 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
274static void metrousb_shutdown(struct usb_serial *serial) 271static 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
294static int metrousb_startup(struct usb_serial *serial) 286static 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,