aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/hso.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/hso.c')
-rw-r--r--drivers/net/usb/hso.c106
1 files changed, 49 insertions, 57 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 9c5aa922a9f4..6b8efcabb816 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -58,7 +58,6 @@
58#include <linux/module.h> 58#include <linux/module.h>
59#include <linux/ethtool.h> 59#include <linux/ethtool.h>
60#include <linux/usb.h> 60#include <linux/usb.h>
61#include <linux/timer.h>
62#include <linux/tty.h> 61#include <linux/tty.h>
63#include <linux/tty_driver.h> 62#include <linux/tty_driver.h>
64#include <linux/tty_flip.h> 63#include <linux/tty_flip.h>
@@ -154,6 +153,7 @@ struct hso_net {
154 struct hso_device *parent; 153 struct hso_device *parent;
155 struct net_device *net; 154 struct net_device *net;
156 struct rfkill *rfkill; 155 struct rfkill *rfkill;
156 char name[24];
157 157
158 struct usb_endpoint_descriptor *in_endp; 158 struct usb_endpoint_descriptor *in_endp;
159 struct usb_endpoint_descriptor *out_endp; 159 struct usb_endpoint_descriptor *out_endp;
@@ -274,7 +274,6 @@ struct hso_device {
274 u8 usb_gone; 274 u8 usb_gone;
275 struct work_struct async_get_intf; 275 struct work_struct async_get_intf;
276 struct work_struct async_put_intf; 276 struct work_struct async_put_intf;
277 struct work_struct reset_device;
278 277
279 struct usb_device *usb; 278 struct usb_device *usb;
280 struct usb_interface *interface; 279 struct usb_interface *interface;
@@ -340,7 +339,6 @@ static void async_put_intf(struct work_struct *data);
340static int hso_put_activity(struct hso_device *hso_dev); 339static int hso_put_activity(struct hso_device *hso_dev);
341static int hso_get_activity(struct hso_device *hso_dev); 340static int hso_get_activity(struct hso_device *hso_dev);
342static void tiocmget_intr_callback(struct urb *urb); 341static void tiocmget_intr_callback(struct urb *urb);
343static void reset_device(struct work_struct *data);
344/*****************************************************************************/ 342/*****************************************************************************/
345/* Helping functions */ 343/* Helping functions */
346/*****************************************************************************/ 344/*****************************************************************************/
@@ -533,6 +531,13 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev,
533} 531}
534static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL); 532static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL);
535 533
534static struct attribute *hso_serial_dev_attrs[] = {
535 &dev_attr_hsotype.attr,
536 NULL
537};
538
539ATTRIBUTE_GROUPS(hso_serial_dev);
540
536static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb) 541static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb)
537{ 542{
538 int idx; 543 int idx;
@@ -696,7 +701,7 @@ static void handle_usb_error(int status, const char *function,
696 case -ETIMEDOUT: 701 case -ETIMEDOUT:
697 explanation = "protocol error"; 702 explanation = "protocol error";
698 if (hso_dev) 703 if (hso_dev)
699 schedule_work(&hso_dev->reset_device); 704 usb_queue_reset_device(hso_dev->interface);
700 break; 705 break;
701 default: 706 default:
702 explanation = "unknown status"; 707 explanation = "unknown status";
@@ -1271,7 +1276,6 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
1271 goto err_out; 1276 goto err_out;
1272 1277
1273 D1("Opening %d", serial->minor); 1278 D1("Opening %d", serial->minor);
1274 kref_get(&serial->parent->ref);
1275 1279
1276 /* setup */ 1280 /* setup */
1277 tty->driver_data = serial; 1281 tty->driver_data = serial;
@@ -1290,7 +1294,8 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
1290 if (result) { 1294 if (result) {
1291 hso_stop_serial_device(serial->parent); 1295 hso_stop_serial_device(serial->parent);
1292 serial->port.count--; 1296 serial->port.count--;
1293 kref_put(&serial->parent->ref, hso_serial_ref_free); 1297 } else {
1298 kref_get(&serial->parent->ref);
1294 } 1299 }
1295 } else { 1300 } else {
1296 D1("Port was already open"); 1301 D1("Port was already open");
@@ -1340,8 +1345,6 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
1340 usb_autopm_put_interface(serial->parent->interface); 1345 usb_autopm_put_interface(serial->parent->interface);
1341 1346
1342 mutex_unlock(&serial->parent->mutex); 1347 mutex_unlock(&serial->parent->mutex);
1343
1344 kref_put(&serial->parent->ref, hso_serial_ref_free);
1345} 1348}
1346 1349
1347/* close the requested serial port */ 1350/* close the requested serial port */
@@ -1392,6 +1395,16 @@ static int hso_serial_write_room(struct tty_struct *tty)
1392 return room; 1395 return room;
1393} 1396}
1394 1397
1398static void hso_serial_cleanup(struct tty_struct *tty)
1399{
1400 struct hso_serial *serial = tty->driver_data;
1401
1402 if (!serial)
1403 return;
1404
1405 kref_put(&serial->parent->ref, hso_serial_ref_free);
1406}
1407
1395/* setup the term */ 1408/* setup the term */
1396static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) 1409static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
1397{ 1410{
@@ -2198,8 +2211,8 @@ static int hso_stop_serial_device(struct hso_device *hso_dev)
2198 2211
2199 for (i = 0; i < serial->num_rx_urbs; i++) { 2212 for (i = 0; i < serial->num_rx_urbs; i++) {
2200 if (serial->rx_urb[i]) { 2213 if (serial->rx_urb[i]) {
2201 usb_kill_urb(serial->rx_urb[i]); 2214 usb_kill_urb(serial->rx_urb[i]);
2202 serial->rx_urb_filled[i] = 0; 2215 serial->rx_urb_filled[i] = 0;
2203 } 2216 }
2204 } 2217 }
2205 serial->curr_rx_urb_idx = 0; 2218 serial->curr_rx_urb_idx = 0;
@@ -2228,15 +2241,15 @@ static int hso_stop_serial_device(struct hso_device *hso_dev)
2228 return 0; 2241 return 0;
2229} 2242}
2230 2243
2244static void hso_serial_tty_unregister(struct hso_serial *serial)
2245{
2246 tty_unregister_device(tty_drv, serial->minor);
2247}
2248
2231static void hso_serial_common_free(struct hso_serial *serial) 2249static void hso_serial_common_free(struct hso_serial *serial)
2232{ 2250{
2233 int i; 2251 int i;
2234 2252
2235 if (serial->parent->dev)
2236 device_remove_file(serial->parent->dev, &dev_attr_hsotype);
2237
2238 tty_unregister_device(tty_drv, serial->minor);
2239
2240 for (i = 0; i < serial->num_rx_urbs; i++) { 2253 for (i = 0; i < serial->num_rx_urbs; i++) {
2241 /* unlink and free RX URB */ 2254 /* unlink and free RX URB */
2242 usb_free_urb(serial->rx_urb[i]); 2255 usb_free_urb(serial->rx_urb[i]);
@@ -2246,6 +2259,7 @@ static void hso_serial_common_free(struct hso_serial *serial)
2246 2259
2247 /* unlink and free TX URB */ 2260 /* unlink and free TX URB */
2248 usb_free_urb(serial->tx_urb); 2261 usb_free_urb(serial->tx_urb);
2262 kfree(serial->tx_buffer);
2249 kfree(serial->tx_data); 2263 kfree(serial->tx_data);
2250 tty_port_destroy(&serial->port); 2264 tty_port_destroy(&serial->port);
2251} 2265}
@@ -2264,11 +2278,10 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
2264 goto exit; 2278 goto exit;
2265 2279
2266 /* register our minor number */ 2280 /* register our minor number */
2267 serial->parent->dev = tty_port_register_device(&serial->port, tty_drv, 2281 serial->parent->dev = tty_port_register_device_attr(&serial->port,
2268 minor, &serial->parent->interface->dev); 2282 tty_drv, minor, &serial->parent->interface->dev,
2283 serial->parent, hso_serial_dev_groups);
2269 dev = serial->parent->dev; 2284 dev = serial->parent->dev;
2270 dev_set_drvdata(dev, serial->parent);
2271 i = device_create_file(dev, &dev_attr_hsotype);
2272 2285
2273 /* fill in specific data for later use */ 2286 /* fill in specific data for later use */
2274 serial->minor = minor; 2287 serial->minor = minor;
@@ -2316,6 +2329,7 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
2316 2329
2317 return 0; 2330 return 0;
2318exit: 2331exit:
2332 hso_serial_tty_unregister(serial);
2319 hso_serial_common_free(serial); 2333 hso_serial_common_free(serial);
2320 return -1; 2334 return -1;
2321} 2335}
@@ -2338,7 +2352,6 @@ static struct hso_device *hso_create_device(struct usb_interface *intf,
2338 2352
2339 INIT_WORK(&hso_dev->async_get_intf, async_get_intf); 2353 INIT_WORK(&hso_dev->async_get_intf, async_get_intf);
2340 INIT_WORK(&hso_dev->async_put_intf, async_put_intf); 2354 INIT_WORK(&hso_dev->async_put_intf, async_put_intf);
2341 INIT_WORK(&hso_dev->reset_device, reset_device);
2342 2355
2343 return hso_dev; 2356 return hso_dev;
2344} 2357}
@@ -2459,27 +2472,21 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
2459{ 2472{
2460 struct hso_net *hso_net = dev2net(hso_dev); 2473 struct hso_net *hso_net = dev2net(hso_dev);
2461 struct device *dev = &hso_net->net->dev; 2474 struct device *dev = &hso_net->net->dev;
2462 char *rfkn; 2475 static u32 rfkill_counter;
2463 2476
2464 rfkn = kzalloc(20, GFP_KERNEL); 2477 snprintf(hso_net->name, sizeof(hso_net->name), "hso-%d",
2465 if (!rfkn) 2478 rfkill_counter++);
2466 dev_err(dev, "%s - Out of memory\n", __func__);
2467
2468 snprintf(rfkn, 20, "hso-%d",
2469 interface->altsetting->desc.bInterfaceNumber);
2470 2479
2471 hso_net->rfkill = rfkill_alloc(rfkn, 2480 hso_net->rfkill = rfkill_alloc(hso_net->name,
2472 &interface_to_usbdev(interface)->dev, 2481 &interface_to_usbdev(interface)->dev,
2473 RFKILL_TYPE_WWAN, 2482 RFKILL_TYPE_WWAN,
2474 &hso_rfkill_ops, hso_dev); 2483 &hso_rfkill_ops, hso_dev);
2475 if (!hso_net->rfkill) { 2484 if (!hso_net->rfkill) {
2476 dev_err(dev, "%s - Out of memory\n", __func__); 2485 dev_err(dev, "%s - Out of memory\n", __func__);
2477 kfree(rfkn);
2478 return; 2486 return;
2479 } 2487 }
2480 if (rfkill_register(hso_net->rfkill) < 0) { 2488 if (rfkill_register(hso_net->rfkill) < 0) {
2481 rfkill_destroy(hso_net->rfkill); 2489 rfkill_destroy(hso_net->rfkill);
2482 kfree(rfkn);
2483 hso_net->rfkill = NULL; 2490 hso_net->rfkill = NULL;
2484 dev_err(dev, "%s - Failed to register rfkill\n", __func__); 2491 dev_err(dev, "%s - Failed to register rfkill\n", __func__);
2485 return; 2492 return;
@@ -2594,7 +2601,6 @@ static void hso_free_serial_device(struct hso_device *hso_dev)
2594 2601
2595 if (!serial) 2602 if (!serial)
2596 return; 2603 return;
2597 set_serial_by_index(serial->minor, NULL);
2598 2604
2599 hso_serial_common_free(serial); 2605 hso_serial_common_free(serial);
2600 2606
@@ -2684,6 +2690,7 @@ static struct hso_device *hso_create_bulk_serial_device(
2684 return hso_dev; 2690 return hso_dev;
2685 2691
2686exit2: 2692exit2:
2693 hso_serial_tty_unregister(serial);
2687 hso_serial_common_free(serial); 2694 hso_serial_common_free(serial);
2688exit: 2695exit:
2689 hso_free_tiomget(serial); 2696 hso_free_tiomget(serial);
@@ -3083,26 +3090,6 @@ out:
3083 return result; 3090 return result;
3084} 3091}
3085 3092
3086static void reset_device(struct work_struct *data)
3087{
3088 struct hso_device *hso_dev =
3089 container_of(data, struct hso_device, reset_device);
3090 struct usb_device *usb = hso_dev->usb;
3091 int result;
3092
3093 if (hso_dev->usb_gone) {
3094 D1("No reset during disconnect\n");
3095 } else {
3096 result = usb_lock_device_for_reset(usb, hso_dev->interface);
3097 if (result < 0)
3098 D1("unable to lock device for reset: %d\n", result);
3099 else {
3100 usb_reset_device(usb);
3101 usb_unlock_device(usb);
3102 }
3103 }
3104}
3105
3106static void hso_serial_ref_free(struct kref *ref) 3093static void hso_serial_ref_free(struct kref *ref)
3107{ 3094{
3108 struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); 3095 struct hso_device *hso_dev = container_of(ref, struct hso_device, ref);
@@ -3112,18 +3099,22 @@ static void hso_serial_ref_free(struct kref *ref)
3112 3099
3113static void hso_free_interface(struct usb_interface *interface) 3100static void hso_free_interface(struct usb_interface *interface)
3114{ 3101{
3115 struct hso_serial *hso_dev; 3102 struct hso_serial *serial;
3116 int i; 3103 int i;
3117 3104
3118 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { 3105 for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
3119 if (serial_table[i] && 3106 if (serial_table[i] &&
3120 (serial_table[i]->interface == interface)) { 3107 (serial_table[i]->interface == interface)) {
3121 hso_dev = dev2ser(serial_table[i]); 3108 serial = dev2ser(serial_table[i]);
3122 tty_port_tty_hangup(&hso_dev->port, false); 3109 tty_port_tty_hangup(&serial->port, false);
3123 mutex_lock(&hso_dev->parent->mutex); 3110 mutex_lock(&serial->parent->mutex);
3124 hso_dev->parent->usb_gone = 1; 3111 serial->parent->usb_gone = 1;
3125 mutex_unlock(&hso_dev->parent->mutex); 3112 mutex_unlock(&serial->parent->mutex);
3113 cancel_work_sync(&serial_table[i]->async_put_intf);
3114 cancel_work_sync(&serial_table[i]->async_get_intf);
3115 hso_serial_tty_unregister(serial);
3126 kref_put(&serial_table[i]->ref, hso_serial_ref_free); 3116 kref_put(&serial_table[i]->ref, hso_serial_ref_free);
3117 set_serial_by_index(i, NULL);
3127 } 3118 }
3128 } 3119 }
3129 3120
@@ -3215,6 +3206,7 @@ static const struct tty_operations hso_serial_ops = {
3215 .close = hso_serial_close, 3206 .close = hso_serial_close,
3216 .write = hso_serial_write, 3207 .write = hso_serial_write,
3217 .write_room = hso_serial_write_room, 3208 .write_room = hso_serial_write_room,
3209 .cleanup = hso_serial_cleanup,
3218 .ioctl = hso_serial_ioctl, 3210 .ioctl = hso_serial_ioctl,
3219 .set_termios = hso_serial_set_termios, 3211 .set_termios = hso_serial_set_termios,
3220 .chars_in_buffer = hso_serial_chars_in_buffer, 3212 .chars_in_buffer = hso_serial_chars_in_buffer,