diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/tty/ipwireless | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/tty/ipwireless')
-rw-r--r-- | drivers/tty/ipwireless/hardware.c | 2 | ||||
-rw-r--r-- | drivers/tty/ipwireless/network.c | 18 | ||||
-rw-r--r-- | drivers/tty/ipwireless/setup_protocol.h | 2 | ||||
-rw-r--r-- | drivers/tty/ipwireless/tty.c | 119 |
4 files changed, 77 insertions, 64 deletions
diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c index b4ba0670dc5..0aeb5a38d29 100644 --- a/drivers/tty/ipwireless/hardware.c +++ b/drivers/tty/ipwireless/hardware.c | |||
@@ -1729,7 +1729,7 @@ void ipwireless_hardware_free(struct ipw_hardware *hw) | |||
1729 | 1729 | ||
1730 | ipwireless_stop_interrupts(hw); | 1730 | ipwireless_stop_interrupts(hw); |
1731 | 1731 | ||
1732 | flush_work(&hw->work_rx); | 1732 | flush_work_sync(&hw->work_rx); |
1733 | 1733 | ||
1734 | for (i = 0; i < NL_NUM_OF_ADDRESSES; i++) | 1734 | for (i = 0; i < NL_NUM_OF_ADDRESSES; i++) |
1735 | if (hw->packet_assembler[i] != NULL) | 1735 | if (hw->packet_assembler[i] != NULL) |
diff --git a/drivers/tty/ipwireless/network.c b/drivers/tty/ipwireless/network.c index c0dfb642383..f7daeea598e 100644 --- a/drivers/tty/ipwireless/network.c +++ b/drivers/tty/ipwireless/network.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/ppp_channel.h> | 22 | #include <linux/ppp_channel.h> |
23 | #include <linux/ppp_defs.h> | 23 | #include <linux/ppp_defs.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/ppp-ioctl.h> | 25 | #include <linux/if_ppp.h> |
26 | #include <linux/skbuff.h> | 26 | #include <linux/skbuff.h> |
27 | 27 | ||
28 | #include "network.h" | 28 | #include "network.h" |
@@ -274,12 +274,7 @@ static void do_go_online(struct work_struct *work_go_online) | |||
274 | network->xaccm[0] = ~0U; | 274 | network->xaccm[0] = ~0U; |
275 | network->xaccm[3] = 0x60000000U; | 275 | network->xaccm[3] = 0x60000000U; |
276 | network->raccm = ~0U; | 276 | network->raccm = ~0U; |
277 | if (ppp_register_channel(channel) < 0) { | 277 | ppp_register_channel(channel); |
278 | printk(KERN_ERR IPWIRELESS_PCCARD_NAME | ||
279 | ": unable to register PPP channel\n"); | ||
280 | kfree(channel); | ||
281 | return; | ||
282 | } | ||
283 | spin_lock_irqsave(&network->lock, flags); | 278 | spin_lock_irqsave(&network->lock, flags); |
284 | network->ppp_channel = channel; | 279 | network->ppp_channel = channel; |
285 | } | 280 | } |
@@ -352,8 +347,6 @@ static struct sk_buff *ipw_packet_received_skb(unsigned char *data, | |||
352 | } | 347 | } |
353 | 348 | ||
354 | skb = dev_alloc_skb(length + 4); | 349 | skb = dev_alloc_skb(length + 4); |
355 | if (skb == NULL) | ||
356 | return NULL; | ||
357 | skb_reserve(skb, 2); | 350 | skb_reserve(skb, 2); |
358 | memcpy(skb_put(skb, length), data, length); | 351 | memcpy(skb_put(skb, length), data, length); |
359 | 352 | ||
@@ -399,8 +392,7 @@ void ipwireless_network_packet_received(struct ipw_network *network, | |||
399 | 392 | ||
400 | /* Send the data to the ppp_generic module. */ | 393 | /* Send the data to the ppp_generic module. */ |
401 | skb = ipw_packet_received_skb(data, length); | 394 | skb = ipw_packet_received_skb(data, length); |
402 | if (skb) | 395 | ppp_input(network->ppp_channel, skb); |
403 | ppp_input(network->ppp_channel, skb); | ||
404 | } else | 396 | } else |
405 | spin_unlock_irqrestore(&network->lock, | 397 | spin_unlock_irqrestore(&network->lock, |
406 | flags); | 398 | flags); |
@@ -438,8 +430,8 @@ void ipwireless_network_free(struct ipw_network *network) | |||
438 | network->shutting_down = 1; | 430 | network->shutting_down = 1; |
439 | 431 | ||
440 | ipwireless_ppp_close(network); | 432 | ipwireless_ppp_close(network); |
441 | flush_work(&network->work_go_online); | 433 | flush_work_sync(&network->work_go_online); |
442 | flush_work(&network->work_go_offline); | 434 | flush_work_sync(&network->work_go_offline); |
443 | 435 | ||
444 | ipwireless_stop_interrupts(network->hardware); | 436 | ipwireless_stop_interrupts(network->hardware); |
445 | ipwireless_associate_network(network->hardware, NULL); | 437 | ipwireless_associate_network(network->hardware, NULL); |
diff --git a/drivers/tty/ipwireless/setup_protocol.h b/drivers/tty/ipwireless/setup_protocol.h index 002c34e7252..9d6bcc77c73 100644 --- a/drivers/tty/ipwireless/setup_protocol.h +++ b/drivers/tty/ipwireless/setup_protocol.h | |||
@@ -59,7 +59,7 @@ struct tl_setup_config_done_msg { | |||
59 | unsigned char sig_no; /* TL_SETUP_SIGNO_CONFIG_DONE_MSG */ | 59 | unsigned char sig_no; /* TL_SETUP_SIGNO_CONFIG_DONE_MSG */ |
60 | } __attribute__ ((__packed__)); | 60 | } __attribute__ ((__packed__)); |
61 | 61 | ||
62 | /* Asynchronous messages */ | 62 | /* Asyncronous messages */ |
63 | struct tl_setup_open_msg { | 63 | struct tl_setup_open_msg { |
64 | unsigned char sig_no; /* TL_SETUP_SIGNO_OPEN_MSG */ | 64 | unsigned char sig_no; /* TL_SETUP_SIGNO_OPEN_MSG */ |
65 | unsigned char port_no; | 65 | unsigned char port_no; |
diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 2cde13ddf9f..ef92869502a 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/ppp_defs.h> | 22 | #include <linux/ppp_defs.h> |
23 | #include <linux/if.h> | 23 | #include <linux/if.h> |
24 | #include <linux/ppp-ioctl.h> | 24 | #include <linux/if_ppp.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/serial.h> | 26 | #include <linux/serial.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
@@ -44,13 +44,14 @@ | |||
44 | #define TTYTYPE_RAS_RAW (2) | 44 | #define TTYTYPE_RAS_RAW (2) |
45 | 45 | ||
46 | struct ipw_tty { | 46 | struct ipw_tty { |
47 | struct tty_port port; | ||
48 | int index; | 47 | int index; |
49 | struct ipw_hardware *hardware; | 48 | struct ipw_hardware *hardware; |
50 | unsigned int channel_idx; | 49 | unsigned int channel_idx; |
51 | unsigned int secondary_channel_idx; | 50 | unsigned int secondary_channel_idx; |
52 | int tty_type; | 51 | int tty_type; |
53 | struct ipw_network *network; | 52 | struct ipw_network *network; |
53 | struct tty_struct *linux_tty; | ||
54 | int open_count; | ||
54 | unsigned int control_lines; | 55 | unsigned int control_lines; |
55 | struct mutex ipw_tty_mutex; | 56 | struct mutex ipw_tty_mutex; |
56 | int tx_bytes_queued; | 57 | int tx_bytes_queued; |
@@ -72,23 +73,50 @@ static char *tty_type_name(int tty_type) | |||
72 | return channel_names[tty_type]; | 73 | return channel_names[tty_type]; |
73 | } | 74 | } |
74 | 75 | ||
75 | static struct ipw_tty *get_tty(int index) | 76 | static void report_registering(struct ipw_tty *tty) |
76 | { | 77 | { |
77 | /* | 78 | char *iftype = tty_type_name(tty->tty_type); |
78 | * The 'ras_raw' channel is only available when 'loopback' mode | 79 | |
79 | * is enabled. | 80 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME |
80 | * Number of minor starts with 16 (_RANGE * _RAS_RAW). | 81 | ": registering %s device ttyIPWp%d\n", iftype, tty->index); |
81 | */ | 82 | } |
82 | if (!ipwireless_loopback && index >= | 83 | |
83 | IPWIRELESS_PCMCIA_MINOR_RANGE * TTYTYPE_RAS_RAW) | 84 | static void report_deregistering(struct ipw_tty *tty) |
84 | return NULL; | 85 | { |
86 | char *iftype = tty_type_name(tty->tty_type); | ||
85 | 87 | ||
86 | return ttys[index]; | 88 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME |
89 | ": deregistering %s device ttyIPWp%d\n", iftype, | ||
90 | tty->index); | ||
91 | } | ||
92 | |||
93 | static struct ipw_tty *get_tty(int minor) | ||
94 | { | ||
95 | if (minor < ipw_tty_driver->minor_start | ||
96 | || minor >= ipw_tty_driver->minor_start + | ||
97 | IPWIRELESS_PCMCIA_MINORS) | ||
98 | return NULL; | ||
99 | else { | ||
100 | int minor_offset = minor - ipw_tty_driver->minor_start; | ||
101 | |||
102 | /* | ||
103 | * The 'ras_raw' channel is only available when 'loopback' mode | ||
104 | * is enabled. | ||
105 | * Number of minor starts with 16 (_RANGE * _RAS_RAW). | ||
106 | */ | ||
107 | if (!ipwireless_loopback && | ||
108 | minor_offset >= | ||
109 | IPWIRELESS_PCMCIA_MINOR_RANGE * TTYTYPE_RAS_RAW) | ||
110 | return NULL; | ||
111 | |||
112 | return ttys[minor_offset]; | ||
113 | } | ||
87 | } | 114 | } |
88 | 115 | ||
89 | static int ipw_open(struct tty_struct *linux_tty, struct file *filp) | 116 | static int ipw_open(struct tty_struct *linux_tty, struct file *filp) |
90 | { | 117 | { |
91 | struct ipw_tty *tty = get_tty(linux_tty->index); | 118 | int minor = linux_tty->index; |
119 | struct ipw_tty *tty = get_tty(minor); | ||
92 | 120 | ||
93 | if (!tty) | 121 | if (!tty) |
94 | return -ENODEV; | 122 | return -ENODEV; |
@@ -99,12 +127,12 @@ static int ipw_open(struct tty_struct *linux_tty, struct file *filp) | |||
99 | mutex_unlock(&tty->ipw_tty_mutex); | 127 | mutex_unlock(&tty->ipw_tty_mutex); |
100 | return -ENODEV; | 128 | return -ENODEV; |
101 | } | 129 | } |
102 | if (tty->port.count == 0) | 130 | if (tty->open_count == 0) |
103 | tty->tx_bytes_queued = 0; | 131 | tty->tx_bytes_queued = 0; |
104 | 132 | ||
105 | tty->port.count++; | 133 | tty->open_count++; |
106 | 134 | ||
107 | tty->port.tty = linux_tty; | 135 | tty->linux_tty = linux_tty; |
108 | linux_tty->driver_data = tty; | 136 | linux_tty->driver_data = tty; |
109 | linux_tty->low_latency = 1; | 137 | linux_tty->low_latency = 1; |
110 | 138 | ||
@@ -118,13 +146,13 @@ static int ipw_open(struct tty_struct *linux_tty, struct file *filp) | |||
118 | 146 | ||
119 | static void do_ipw_close(struct ipw_tty *tty) | 147 | static void do_ipw_close(struct ipw_tty *tty) |
120 | { | 148 | { |
121 | tty->port.count--; | 149 | tty->open_count--; |
122 | 150 | ||
123 | if (tty->port.count == 0) { | 151 | if (tty->open_count == 0) { |
124 | struct tty_struct *linux_tty = tty->port.tty; | 152 | struct tty_struct *linux_tty = tty->linux_tty; |
125 | 153 | ||
126 | if (linux_tty != NULL) { | 154 | if (linux_tty != NULL) { |
127 | tty->port.tty = NULL; | 155 | tty->linux_tty = NULL; |
128 | linux_tty->driver_data = NULL; | 156 | linux_tty->driver_data = NULL; |
129 | 157 | ||
130 | if (tty->tty_type == TTYTYPE_MODEM) | 158 | if (tty->tty_type == TTYTYPE_MODEM) |
@@ -141,7 +169,7 @@ static void ipw_hangup(struct tty_struct *linux_tty) | |||
141 | return; | 169 | return; |
142 | 170 | ||
143 | mutex_lock(&tty->ipw_tty_mutex); | 171 | mutex_lock(&tty->ipw_tty_mutex); |
144 | if (tty->port.count == 0) { | 172 | if (tty->open_count == 0) { |
145 | mutex_unlock(&tty->ipw_tty_mutex); | 173 | mutex_unlock(&tty->ipw_tty_mutex); |
146 | return; | 174 | return; |
147 | } | 175 | } |
@@ -164,13 +192,13 @@ void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, | |||
164 | int work = 0; | 192 | int work = 0; |
165 | 193 | ||
166 | mutex_lock(&tty->ipw_tty_mutex); | 194 | mutex_lock(&tty->ipw_tty_mutex); |
167 | linux_tty = tty->port.tty; | 195 | linux_tty = tty->linux_tty; |
168 | if (linux_tty == NULL) { | 196 | if (linux_tty == NULL) { |
169 | mutex_unlock(&tty->ipw_tty_mutex); | 197 | mutex_unlock(&tty->ipw_tty_mutex); |
170 | return; | 198 | return; |
171 | } | 199 | } |
172 | 200 | ||
173 | if (!tty->port.count) { | 201 | if (!tty->open_count) { |
174 | mutex_unlock(&tty->ipw_tty_mutex); | 202 | mutex_unlock(&tty->ipw_tty_mutex); |
175 | return; | 203 | return; |
176 | } | 204 | } |
@@ -212,7 +240,7 @@ static int ipw_write(struct tty_struct *linux_tty, | |||
212 | return -ENODEV; | 240 | return -ENODEV; |
213 | 241 | ||
214 | mutex_lock(&tty->ipw_tty_mutex); | 242 | mutex_lock(&tty->ipw_tty_mutex); |
215 | if (!tty->port.count) { | 243 | if (!tty->open_count) { |
216 | mutex_unlock(&tty->ipw_tty_mutex); | 244 | mutex_unlock(&tty->ipw_tty_mutex); |
217 | return -EINVAL; | 245 | return -EINVAL; |
218 | } | 246 | } |
@@ -252,7 +280,7 @@ static int ipw_write_room(struct tty_struct *linux_tty) | |||
252 | if (!tty) | 280 | if (!tty) |
253 | return -ENODEV; | 281 | return -ENODEV; |
254 | 282 | ||
255 | if (!tty->port.count) | 283 | if (!tty->open_count) |
256 | return -EINVAL; | 284 | return -EINVAL; |
257 | 285 | ||
258 | room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued; | 286 | room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued; |
@@ -294,7 +322,7 @@ static int ipw_chars_in_buffer(struct tty_struct *linux_tty) | |||
294 | if (!tty) | 322 | if (!tty) |
295 | return 0; | 323 | return 0; |
296 | 324 | ||
297 | if (!tty->port.count) | 325 | if (!tty->open_count) |
298 | return 0; | 326 | return 0; |
299 | 327 | ||
300 | return tty->tx_bytes_queued; | 328 | return tty->tx_bytes_queued; |
@@ -375,7 +403,7 @@ static int ipw_tiocmget(struct tty_struct *linux_tty) | |||
375 | if (!tty) | 403 | if (!tty) |
376 | return -ENODEV; | 404 | return -ENODEV; |
377 | 405 | ||
378 | if (!tty->port.count) | 406 | if (!tty->open_count) |
379 | return -EINVAL; | 407 | return -EINVAL; |
380 | 408 | ||
381 | return get_control_lines(tty); | 409 | return get_control_lines(tty); |
@@ -391,7 +419,7 @@ ipw_tiocmset(struct tty_struct *linux_tty, | |||
391 | if (!tty) | 419 | if (!tty) |
392 | return -ENODEV; | 420 | return -ENODEV; |
393 | 421 | ||
394 | if (!tty->port.count) | 422 | if (!tty->open_count) |
395 | return -EINVAL; | 423 | return -EINVAL; |
396 | 424 | ||
397 | return set_control_lines(tty, set, clear); | 425 | return set_control_lines(tty, set, clear); |
@@ -405,7 +433,7 @@ static int ipw_ioctl(struct tty_struct *linux_tty, | |||
405 | if (!tty) | 433 | if (!tty) |
406 | return -ENODEV; | 434 | return -ENODEV; |
407 | 435 | ||
408 | if (!tty->port.count) | 436 | if (!tty->open_count) |
409 | return -EINVAL; | 437 | return -EINVAL; |
410 | 438 | ||
411 | /* FIXME: Exactly how is the tty object locked here .. */ | 439 | /* FIXME: Exactly how is the tty object locked here .. */ |
@@ -474,21 +502,16 @@ static int add_tty(int j, | |||
474 | ttys[j]->network = network; | 502 | ttys[j]->network = network; |
475 | ttys[j]->tty_type = tty_type; | 503 | ttys[j]->tty_type = tty_type; |
476 | mutex_init(&ttys[j]->ipw_tty_mutex); | 504 | mutex_init(&ttys[j]->ipw_tty_mutex); |
477 | tty_port_init(&ttys[j]->port); | ||
478 | 505 | ||
479 | tty_port_register_device(&ttys[j]->port, ipw_tty_driver, j, NULL); | 506 | tty_register_device(ipw_tty_driver, j, NULL); |
480 | ipwireless_associate_network_tty(network, channel_idx, ttys[j]); | 507 | ipwireless_associate_network_tty(network, channel_idx, ttys[j]); |
481 | 508 | ||
482 | if (secondary_channel_idx != -1) | 509 | if (secondary_channel_idx != -1) |
483 | ipwireless_associate_network_tty(network, | 510 | ipwireless_associate_network_tty(network, |
484 | secondary_channel_idx, | 511 | secondary_channel_idx, |
485 | ttys[j]); | 512 | ttys[j]); |
486 | /* check if we provide raw device (if loopback is enabled) */ | 513 | if (get_tty(j + ipw_tty_driver->minor_start) == ttys[j]) |
487 | if (get_tty(j)) | 514 | report_registering(ttys[j]); |
488 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | ||
489 | ": registering %s device ttyIPWp%d\n", | ||
490 | tty_type_name(tty_type), j); | ||
491 | |||
492 | return 0; | 515 | return 0; |
493 | } | 516 | } |
494 | 517 | ||
@@ -547,26 +570,23 @@ void ipwireless_tty_free(struct ipw_tty *tty) | |||
547 | 570 | ||
548 | if (ttyj) { | 571 | if (ttyj) { |
549 | mutex_lock(&ttyj->ipw_tty_mutex); | 572 | mutex_lock(&ttyj->ipw_tty_mutex); |
550 | if (get_tty(j)) | 573 | if (get_tty(j + ipw_tty_driver->minor_start) == ttyj) |
551 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME | 574 | report_deregistering(ttyj); |
552 | ": deregistering %s device ttyIPWp%d\n", | ||
553 | tty_type_name(ttyj->tty_type), j); | ||
554 | ttyj->closing = 1; | 575 | ttyj->closing = 1; |
555 | if (ttyj->port.tty != NULL) { | 576 | if (ttyj->linux_tty != NULL) { |
556 | mutex_unlock(&ttyj->ipw_tty_mutex); | 577 | mutex_unlock(&ttyj->ipw_tty_mutex); |
557 | tty_vhangup(ttyj->port.tty); | 578 | tty_hangup(ttyj->linux_tty); |
579 | /* Wait till the tty_hangup has completed */ | ||
580 | flush_work_sync(&ttyj->linux_tty->hangup_work); | ||
558 | /* FIXME: Exactly how is the tty object locked here | 581 | /* FIXME: Exactly how is the tty object locked here |
559 | against a parallel ioctl etc */ | 582 | against a parallel ioctl etc */ |
560 | /* FIXME2: hangup does not mean all processes | ||
561 | * are gone */ | ||
562 | mutex_lock(&ttyj->ipw_tty_mutex); | 583 | mutex_lock(&ttyj->ipw_tty_mutex); |
563 | } | 584 | } |
564 | while (ttyj->port.count) | 585 | while (ttyj->open_count) |
565 | do_ipw_close(ttyj); | 586 | do_ipw_close(ttyj); |
566 | ipwireless_disassociate_network_ttys(network, | 587 | ipwireless_disassociate_network_ttys(network, |
567 | ttyj->channel_idx); | 588 | ttyj->channel_idx); |
568 | tty_unregister_device(ipw_tty_driver, j); | 589 | tty_unregister_device(ipw_tty_driver, j); |
569 | tty_port_destroy(&ttyj->port); | ||
570 | ttys[j] = NULL; | 590 | ttys[j] = NULL; |
571 | mutex_unlock(&ttyj->ipw_tty_mutex); | 591 | mutex_unlock(&ttyj->ipw_tty_mutex); |
572 | kfree(ttyj); | 592 | kfree(ttyj); |
@@ -594,6 +614,7 @@ int ipwireless_tty_init(void) | |||
594 | if (!ipw_tty_driver) | 614 | if (!ipw_tty_driver) |
595 | return -ENOMEM; | 615 | return -ENOMEM; |
596 | 616 | ||
617 | ipw_tty_driver->owner = THIS_MODULE; | ||
597 | ipw_tty_driver->driver_name = IPWIRELESS_PCCARD_NAME; | 618 | ipw_tty_driver->driver_name = IPWIRELESS_PCCARD_NAME; |
598 | ipw_tty_driver->name = "ttyIPWp"; | 619 | ipw_tty_driver->name = "ttyIPWp"; |
599 | ipw_tty_driver->major = 0; | 620 | ipw_tty_driver->major = 0; |
@@ -651,8 +672,8 @@ ipwireless_tty_notify_control_line_change(struct ipw_tty *tty, | |||
651 | */ | 672 | */ |
652 | if ((old_control_lines & IPW_CONTROL_LINE_DCD) | 673 | if ((old_control_lines & IPW_CONTROL_LINE_DCD) |
653 | && !(tty->control_lines & IPW_CONTROL_LINE_DCD) | 674 | && !(tty->control_lines & IPW_CONTROL_LINE_DCD) |
654 | && tty->port.tty) { | 675 | && tty->linux_tty) { |
655 | tty_hangup(tty->port.tty); | 676 | tty_hangup(tty->linux_tty); |
656 | } | 677 | } |
657 | } | 678 | } |
658 | 679 | ||