aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers/port_kern.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers/port_kern.c')
-rw-r--r--arch/um/drivers/port_kern.c82
1 files changed, 39 insertions, 43 deletions
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index d8acf7470e70..330543b3129b 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -1,24 +1,16 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/list.h" 6#include "linux/completion.h"
7#include "linux/sched.h"
8#include "linux/slab.h"
9#include "linux/interrupt.h" 7#include "linux/interrupt.h"
10#include "linux/spinlock.h" 8#include "linux/list.h"
11#include "linux/errno.h"
12#include "asm/atomic.h" 9#include "asm/atomic.h"
13#include "asm/semaphore.h"
14#include "asm/errno.h"
15#include "kern_util.h"
16#include "kern.h"
17#include "irq_user.h"
18#include "irq_kern.h"
19#include "port.h"
20#include "init.h" 10#include "init.h"
11#include "irq_kern.h"
21#include "os.h" 12#include "os.h"
13#include "port.h"
22 14
23struct port_list { 15struct port_list {
24 struct list_head list; 16 struct list_head list;
@@ -53,8 +45,8 @@ static irqreturn_t pipe_interrupt(int irq, void *data)
53 int fd; 45 int fd;
54 46
55 fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); 47 fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
56 if(fd < 0){ 48 if (fd < 0) {
57 if(fd == -EAGAIN) 49 if (fd == -EAGAIN)
58 return IRQ_NONE; 50 return IRQ_NONE;
59 51
60 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 52 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
@@ -81,18 +73,18 @@ static irqreturn_t pipe_interrupt(int irq, void *data)
81static int port_accept(struct port_list *port) 73static int port_accept(struct port_list *port)
82{ 74{
83 struct connection *conn; 75 struct connection *conn;
84 int fd, socket[2], pid, ret = 0; 76 int fd, socket[2], pid;
85 77
86 fd = port_connection(port->fd, socket, &pid); 78 fd = port_connection(port->fd, socket, &pid);
87 if(fd < 0){ 79 if (fd < 0) {
88 if(fd != -EAGAIN) 80 if (fd != -EAGAIN)
89 printk(KERN_ERR "port_accept : port_connection " 81 printk(KERN_ERR "port_accept : port_connection "
90 "returned %d\n", -fd); 82 "returned %d\n", -fd);
91 goto out; 83 goto out;
92 } 84 }
93 85
94 conn = kmalloc(sizeof(*conn), GFP_ATOMIC); 86 conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
95 if(conn == NULL){ 87 if (conn == NULL) {
96 printk(KERN_ERR "port_accept : failed to allocate " 88 printk(KERN_ERR "port_accept : failed to allocate "
97 "connection\n"); 89 "connection\n");
98 goto out_close; 90 goto out_close;
@@ -104,17 +96,17 @@ static int port_accept(struct port_list *port)
104 .telnetd_pid = pid, 96 .telnetd_pid = pid,
105 .port = port }); 97 .port = port });
106 98
107 if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, 99 if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
108 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, 100 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
109 "telnetd", conn)){ 101 "telnetd", conn)) {
110 printk(KERN_ERR "port_accept : failed to get IRQ for " 102 printk(KERN_ERR "port_accept : failed to get IRQ for "
111 "telnetd\n"); 103 "telnetd\n");
112 goto out_free; 104 goto out_free;
113 } 105 }
114 106
115 if(atomic_read(&port->wait_count) == 0){ 107 if (atomic_read(&port->wait_count) == 0) {
116 os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); 108 os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG));
117 printk("No one waiting for port\n"); 109 printk(KERN_ERR "No one waiting for port\n");
118 } 110 }
119 list_add(&conn->list, &port->pending); 111 list_add(&conn->list, &port->pending);
120 return 1; 112 return 1;
@@ -123,28 +115,29 @@ static int port_accept(struct port_list *port)
123 kfree(conn); 115 kfree(conn);
124 out_close: 116 out_close:
125 os_close_file(fd); 117 os_close_file(fd);
126 if(pid != -1) 118 os_kill_process(pid, 1);
127 os_kill_process(pid, 1);
128 out: 119 out:
129 return ret; 120 return 0;
130} 121}
131 122
132static DECLARE_MUTEX(ports_sem); 123static DECLARE_MUTEX(ports_sem);
133static LIST_HEAD(ports); 124static LIST_HEAD(ports);
134 125
135void port_work_proc(struct work_struct *unused) 126static void port_work_proc(struct work_struct *unused)
136{ 127{
137 struct port_list *port; 128 struct port_list *port;
138 struct list_head *ele; 129 struct list_head *ele;
139 unsigned long flags; 130 unsigned long flags;
140 131
141 local_irq_save(flags); 132 local_irq_save(flags);
142 list_for_each(ele, &ports){ 133 list_for_each(ele, &ports) {
143 port = list_entry(ele, struct port_list, list); 134 port = list_entry(ele, struct port_list, list);
144 if(!port->has_connection) 135 if (!port->has_connection)
145 continue; 136 continue;
137
146 reactivate_fd(port->fd, ACCEPT_IRQ); 138 reactivate_fd(port->fd, ACCEPT_IRQ);
147 while(port_accept(port)) ; 139 while (port_accept(port))
140 ;
148 port->has_connection = 0; 141 port->has_connection = 0;
149 } 142 }
150 local_irq_restore(flags); 143 local_irq_restore(flags);
@@ -169,25 +162,27 @@ void *port_data(int port_num)
169 int fd; 162 int fd;
170 163
171 down(&ports_sem); 164 down(&ports_sem);
172 list_for_each(ele, &ports){ 165 list_for_each(ele, &ports) {
173 port = list_entry(ele, struct port_list, list); 166 port = list_entry(ele, struct port_list, list);
174 if(port->port == port_num) goto found; 167 if (port->port == port_num)
168 goto found;
175 } 169 }
176 port = kmalloc(sizeof(struct port_list), GFP_KERNEL); 170 port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
177 if(port == NULL){ 171 if (port == NULL) {
178 printk(KERN_ERR "Allocation of port list failed\n"); 172 printk(KERN_ERR "Allocation of port list failed\n");
179 goto out; 173 goto out;
180 } 174 }
181 175
182 fd = port_listen_fd(port_num); 176 fd = port_listen_fd(port_num);
183 if(fd < 0){ 177 if (fd < 0) {
184 printk(KERN_ERR "binding to port %d failed, errno = %d\n", 178 printk(KERN_ERR "binding to port %d failed, errno = %d\n",
185 port_num, -fd); 179 port_num, -fd);
186 goto out_free; 180 goto out_free;
187 } 181 }
188 if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, 182
183 if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
189 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, 184 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
190 "port", port)){ 185 "port", port)) {
191 printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); 186 printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
192 goto out_close; 187 goto out_close;
193 } 188 }
@@ -206,7 +201,7 @@ void *port_data(int port_num)
206 201
207 found: 202 found:
208 dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL); 203 dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
209 if(dev == NULL){ 204 if (dev == NULL) {
210 printk(KERN_ERR "Allocation of port device entry failed\n"); 205 printk(KERN_ERR "Allocation of port device entry failed\n");
211 goto out; 206 goto out;
212 } 207 }
@@ -233,9 +228,9 @@ int port_wait(void *data)
233 int fd; 228 int fd;
234 229
235 atomic_inc(&port->wait_count); 230 atomic_inc(&port->wait_count);
236 while(1){ 231 while (1) {
237 fd = -ERESTARTSYS; 232 fd = -ERESTARTSYS;
238 if(wait_for_completion_interruptible(&port->done)) 233 if (wait_for_completion_interruptible(&port->done))
239 goto out; 234 goto out;
240 235
241 spin_lock(&port->lock); 236 spin_lock(&port->lock);
@@ -258,7 +253,8 @@ int port_wait(void *data)
258 */ 253 */
259 free_irq(TELNETD_IRQ, conn); 254 free_irq(TELNETD_IRQ, conn);
260 255
261 if(conn->fd >= 0) break; 256 if (conn->fd >= 0)
257 break;
262 os_close_file(conn->fd); 258 os_close_file(conn->fd);
263 kfree(conn); 259 kfree(conn);
264 } 260 }
@@ -276,9 +272,9 @@ void port_remove_dev(void *d)
276{ 272{
277 struct port_dev *dev = d; 273 struct port_dev *dev = d;
278 274
279 if(dev->helper_pid != -1) 275 if (dev->helper_pid != -1)
280 os_kill_process(dev->helper_pid, 0); 276 os_kill_process(dev->helper_pid, 0);
281 if(dev->telnetd_pid != -1) 277 if (dev->telnetd_pid != -1)
282 os_kill_process(dev->telnetd_pid, 1); 278 os_kill_process(dev->telnetd_pid, 1);
283 dev->helper_pid = -1; 279 dev->helper_pid = -1;
284 dev->telnetd_pid = -1; 280 dev->telnetd_pid = -1;
@@ -297,7 +293,7 @@ static void free_port(void)
297 struct list_head *ele; 293 struct list_head *ele;
298 struct port_list *port; 294 struct port_list *port;
299 295
300 list_for_each(ele, &ports){ 296 list_for_each(ele, &ports) {
301 port = list_entry(ele, struct port_list, list); 297 port = list_entry(ele, struct port_list, list);
302 free_irq_by_fd(port->fd); 298 free_irq_by_fd(port->fd);
303 os_close_file(port->fd); 299 os_close_file(port->fd);