Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / atm / atmtcp.c
blob17f607a73eadf94749897f7899d7c08cafdab46a
1 /* drivers/atm/atmtcp.c - ATM over TCP "device" driver */
3 /* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */
6 #include <linux/module.h>
7 #include <linux/wait.h>
8 #include <linux/atmdev.h>
9 #include <linux/atm_tcp.h>
10 #include <linux/bitops.h>
11 #include <asm/uaccess.h>
12 #include <asm/atomic.h>
15 extern int atm_init_aal5(struct atm_vcc *vcc); /* "raw" AAL5 transport */
18 #define PRIV(dev) ((struct atmtcp_dev_data *) ((dev)->dev_data))
21 struct atmtcp_dev_data {
22 struct atm_vcc *vcc; /* control VCC; NULL if detached */
23 int persist; /* non-zero if persistent */
27 #define DEV_LABEL "atmtcp"
29 #define MAX_VPI_BITS 8 /* simplifies life */
30 #define MAX_VCI_BITS 16
34 * Hairy code ahead: the control VCC may be closed while we're still
35 * waiting for an answer, so we need to re-validate out_vcc every once
36 * in a while.
40 static int atmtcp_send_control(struct atm_vcc *vcc,int type,
41 const struct atmtcp_control *msg,int flag)
43 DECLARE_WAITQUEUE(wait,current);
44 struct atm_vcc *out_vcc;
45 struct sk_buff *skb;
46 struct atmtcp_control *new_msg;
47 int old_test;
48 int error = 0;
50 out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
51 if (!out_vcc) return -EUNATCH;
52 skb = alloc_skb(sizeof(*msg),GFP_KERNEL);
53 if (!skb) return -ENOMEM;
54 mb();
55 out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
56 if (!out_vcc) {
57 dev_kfree_skb(skb);
58 return -EUNATCH;
60 atm_force_charge(out_vcc,skb->truesize);
61 new_msg = (struct atmtcp_control *) skb_put(skb,sizeof(*new_msg));
62 *new_msg = *msg;
63 new_msg->hdr.length = ATMTCP_HDR_MAGIC;
64 new_msg->type = type;
65 memset(&new_msg->vcc,0,sizeof(atm_kptr_t));
66 *(struct atm_vcc **) &new_msg->vcc = vcc;
67 old_test = test_bit(flag,&vcc->flags);
68 out_vcc->push(out_vcc,skb);
69 add_wait_queue(&vcc->sleep,&wait);
70 while (test_bit(flag,&vcc->flags) == old_test) {
71 mb();
72 out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
73 if (!out_vcc) {
74 error = -EUNATCH;
75 break;
77 set_current_state(TASK_UNINTERRUPTIBLE);
78 schedule();
80 current->state = TASK_RUNNING;
81 remove_wait_queue(&vcc->sleep,&wait);
82 return error;
86 static int atmtcp_recv_control(const struct atmtcp_control *msg)
88 struct atm_vcc *vcc = *(struct atm_vcc **) &msg->vcc;
90 vcc->vpi = msg->addr.sap_addr.vpi;
91 vcc->vci = msg->addr.sap_addr.vci;
92 vcc->qos = msg->qos;
93 vcc->reply = msg->result;
94 switch (msg->type) {
95 case ATMTCP_CTRL_OPEN:
96 change_bit(ATM_VF_READY,&vcc->flags);
97 break;
98 case ATMTCP_CTRL_CLOSE:
99 change_bit(ATM_VF_ADDR,&vcc->flags);
100 break;
101 default:
102 printk(KERN_ERR "atmtcp_recv_control: unknown type %d\n",
103 msg->type);
104 return -EINVAL;
106 wake_up(&vcc->sleep);
107 return 0;
111 static void atmtcp_v_dev_close(struct atm_dev *dev)
113 /* Nothing.... Isn't this simple :-) -- REW */
117 static int atmtcp_v_open(struct atm_vcc *vcc,short vpi,int vci)
119 struct atmtcp_control msg;
120 int error;
122 memset(&msg,0,sizeof(msg));
123 msg.addr.sap_family = AF_ATMPVC;
124 msg.hdr.vpi = htons(vpi);
125 msg.addr.sap_addr.vpi = vpi;
126 msg.hdr.vci = htons(vci);
127 msg.addr.sap_addr.vci = vci;
128 error = atm_find_ci(vcc,&msg.addr.sap_addr.vpi,&msg.addr.sap_addr.vci);
129 if (error) return error;
130 if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) return 0;
131 msg.type = ATMTCP_CTRL_OPEN;
132 msg.qos = vcc->qos;
133 set_bit(ATM_VF_ADDR,&vcc->flags);
134 clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
135 error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
136 if (error) return error;
137 return vcc->reply;
141 static void atmtcp_v_close(struct atm_vcc *vcc)
143 struct atmtcp_control msg;
145 memset(&msg,0,sizeof(msg));
146 msg.addr.sap_family = AF_ATMPVC;
147 msg.addr.sap_addr.vpi = vcc->vpi;
148 msg.addr.sap_addr.vci = vcc->vci;
149 clear_bit(ATM_VF_READY,&vcc->flags);
150 (void) atmtcp_send_control(vcc,ATMTCP_CTRL_CLOSE,&msg,ATM_VF_ADDR);
154 static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
156 struct atm_cirange ci;
157 struct atm_vcc *vcc;
159 if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
160 if (copy_from_user(&ci,(void *) arg,sizeof(ci))) return -EFAULT;
161 if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS;
162 if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS;
163 if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
164 ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL;
165 for (vcc = dev->vccs; vcc; vcc = vcc->next)
166 if ((vcc->vpi >> ci.vpi_bits) ||
167 (vcc->vci >> ci.vci_bits)) return -EBUSY;
168 dev->ci_range = ci;
169 return 0;
173 static int atmtcp_v_send(struct atm_vcc *vcc,struct sk_buff *skb)
175 struct atmtcp_dev_data *dev_data;
176 struct atm_vcc *out_vcc;
177 struct sk_buff *new_skb;
178 struct atmtcp_hdr *hdr;
179 int size;
181 if (vcc->qos.txtp.traffic_class == ATM_NONE) {
182 if (vcc->pop) vcc->pop(vcc,skb);
183 else dev_kfree_skb(skb);
184 return -EINVAL;
186 dev_data = PRIV(vcc->dev);
187 if (dev_data) out_vcc = dev_data->vcc;
188 if (!dev_data || !out_vcc) {
189 if (vcc->pop) vcc->pop(vcc,skb);
190 else dev_kfree_skb(skb);
191 if (dev_data) return 0;
192 atomic_inc(&vcc->stats->tx_err);
193 return -ENOLINK;
195 size = skb->len+sizeof(struct atmtcp_hdr);
196 new_skb = atm_alloc_charge(out_vcc,size,GFP_ATOMIC);
197 if (!new_skb) {
198 if (vcc->pop) vcc->pop(vcc,skb);
199 else dev_kfree_skb(skb);
200 atomic_inc(&vcc->stats->tx_err);
201 return -ENOBUFS;
203 hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
204 hdr->vpi = htons(vcc->vpi);
205 hdr->vci = htons(vcc->vci);
206 hdr->length = htonl(skb->len);
207 memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
208 if (vcc->pop) vcc->pop(vcc,skb);
209 else dev_kfree_skb(skb);
210 out_vcc->push(out_vcc,new_skb);
211 atomic_inc(&vcc->stats->tx);
212 atomic_inc(&out_vcc->stats->rx);
213 return 0;
217 static int atmtcp_v_proc(struct atm_dev *dev,loff_t *pos,char *page)
219 struct atmtcp_dev_data *dev_data = PRIV(dev);
221 if (*pos) return 0;
222 if (!dev_data->persist) return sprintf(page,"ephemeral\n");
223 return sprintf(page,"persistent, %sconnected\n",
224 dev_data->vcc ? "" : "dis");
228 static void atmtcp_c_close(struct atm_vcc *vcc)
230 struct atm_dev *atmtcp_dev;
231 struct atmtcp_dev_data *dev_data;
232 struct atm_vcc *walk;
234 atmtcp_dev = (struct atm_dev *) vcc->dev_data;
235 dev_data = PRIV(atmtcp_dev);
236 dev_data->vcc = NULL;
237 if (dev_data->persist) return;
238 PRIV(atmtcp_dev) = NULL;
239 kfree(dev_data);
240 shutdown_atm_dev(atmtcp_dev);
241 vcc->dev_data = NULL;
242 for (walk = atmtcp_dev->vccs; walk; walk = walk->next)
243 wake_up(&walk->sleep);
247 static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
249 struct atm_dev *dev;
250 struct atmtcp_hdr *hdr;
251 struct atm_vcc *out_vcc;
252 struct sk_buff *new_skb;
253 int result = 0;
255 if (!skb->len) return 0;
256 dev = vcc->dev_data;
257 hdr = (struct atmtcp_hdr *) skb->data;
258 if (hdr->length == ATMTCP_HDR_MAGIC) {
259 result = atmtcp_recv_control(
260 (struct atmtcp_control *) skb->data);
261 goto done;
263 for (out_vcc = dev->vccs; out_vcc; out_vcc = out_vcc->next)
264 if (out_vcc->vpi == ntohs(hdr->vpi) &&
265 out_vcc->vci == ntohs(hdr->vci) &&
266 out_vcc->qos.rxtp.traffic_class != ATM_NONE)
267 break;
268 if (!out_vcc) {
269 atomic_inc(&vcc->stats->tx_err);
270 goto done;
272 skb_pull(skb,sizeof(struct atmtcp_hdr));
273 new_skb = atm_alloc_charge(out_vcc,skb->len,GFP_KERNEL);
274 if (!new_skb) {
275 result = -ENOBUFS;
276 goto done;
278 new_skb->stamp = xtime;
279 memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
280 out_vcc->push(out_vcc,new_skb);
281 atomic_inc(&vcc->stats->tx);
282 atomic_inc(&out_vcc->stats->rx);
283 done:
284 if (vcc->pop) vcc->pop(vcc,skb);
285 else dev_kfree_skb(skb);
286 return result;
291 * Device operations for the virtual ATM devices created by ATMTCP.
295 static struct atmdev_ops atmtcp_v_dev_ops = {
296 dev_close: atmtcp_v_dev_close,
297 open: atmtcp_v_open,
298 close: atmtcp_v_close,
299 ioctl: atmtcp_v_ioctl,
300 send: atmtcp_v_send,
301 proc_read: atmtcp_v_proc,
302 owner: THIS_MODULE
307 * Device operations for the ATMTCP control device.
311 static struct atmdev_ops atmtcp_c_dev_ops = {
312 close: atmtcp_c_close,
313 send: atmtcp_c_send
317 static struct atm_dev atmtcp_control_dev = {
318 &atmtcp_c_dev_ops,
319 NULL, /* no PHY */
320 "atmtcp", /* type */
321 999, /* dummy device number */
322 NULL,NULL, /* pretend not to have any VCCs */
323 NULL,NULL, /* no data */
324 { 0 }, /* no flags */
325 NULL, /* no local address */
326 { 0 } /* no ESI, no statistics */
330 static int atmtcp_create(int itf,int persist,struct atm_dev **result)
332 struct atmtcp_dev_data *dev_data;
333 struct atm_dev *dev;
335 dev_data = kmalloc(sizeof(*dev_data),GFP_KERNEL);
336 if (!dev_data)
337 return -ENOMEM;
339 dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
340 if (!dev) {
341 kfree(dev_data);
342 return itf == -1 ? -ENOMEM : -EBUSY;
344 dev->ci_range.vpi_bits = MAX_VPI_BITS;
345 dev->ci_range.vci_bits = MAX_VCI_BITS;
346 PRIV(dev) = dev_data;
347 PRIV(dev)->vcc = NULL;
348 PRIV(dev)->persist = persist;
349 if (result) *result = dev;
350 return 0;
354 int atmtcp_attach(struct atm_vcc *vcc,int itf)
356 struct atm_dev *dev;
358 dev = NULL;
359 if (itf != -1) dev = atm_find_dev(itf);
360 if (dev) {
361 if (dev->ops != &atmtcp_v_dev_ops) return -EMEDIUMTYPE;
362 if (PRIV(dev)->vcc) return -EBUSY;
364 else {
365 int error;
367 error = atmtcp_create(itf,0,&dev);
368 if (error) return error;
370 PRIV(dev)->vcc = vcc;
371 bind_vcc(vcc,&atmtcp_control_dev);
372 set_bit(ATM_VF_META,&vcc->flags);
373 set_bit(ATM_VF_READY,&vcc->flags);
374 vcc->dev_data = dev;
375 (void) atm_init_aal5(vcc); /* @@@ losing AAL in transit ... */
376 vcc->stats = &atmtcp_control_dev.stats.aal5;
377 return dev->number;
381 int atmtcp_create_persistent(int itf)
383 return atmtcp_create(itf,1,NULL);
387 int atmtcp_remove_persistent(int itf)
389 struct atm_dev *dev;
390 struct atmtcp_dev_data *dev_data;
392 dev = atm_find_dev(itf);
393 if (!dev) return -ENODEV;
394 if (dev->ops != &atmtcp_v_dev_ops) return -EMEDIUMTYPE;
395 dev_data = PRIV(dev);
396 if (!dev_data->persist) return 0;
397 dev_data->persist = 0;
398 if (PRIV(dev)->vcc) return 0;
399 kfree(dev_data);
400 shutdown_atm_dev(dev);
401 return 0;
405 #ifdef MODULE
407 int init_module(void)
409 atm_tcp_ops.attach = atmtcp_attach;
410 atm_tcp_ops.create_persistent = atmtcp_create_persistent;
411 atm_tcp_ops.remove_persistent = atmtcp_remove_persistent;
412 return 0;
416 void cleanup_module(void)
418 atm_tcp_ops.attach = NULL;
419 atm_tcp_ops.create_persistent = NULL;
420 atm_tcp_ops.remove_persistent = NULL;
423 #else
425 struct atm_tcp_ops atm_tcp_ops = {
426 atmtcp_attach, /* attach */
427 atmtcp_create_persistent, /* create_persistent */
428 atmtcp_remove_persistent /* remove_persistent */
431 #endif