1 /*********************************************************************
2 *
3 * Filename: irttp.c
4 * Version: 1.2
5 * Description: Tiny Transport Protocol (TTP) implementation
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:31 1997
9 * Modified at: Wed Jan 5 11:31:27 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * Neither Dag Brattli nor University of Tromsų admit liability nor
21 * provide warranty for any of this software. This material is
22 * provided "AS-IS" and at no charge.
23 *
24 ********************************************************************/
25
26 #include <linux/config.h>
27 #include <linux/skbuff.h>
28 #include <linux/init.h>
29
30 #include <asm/byteorder.h>
31 #include <asm/unaligned.h>
32
33 #include <net/irda/irda.h>
34 #include <net/irda/irmod.h>
35 #include <net/irda/irlap.h>
36 #include <net/irda/irlmp.h>
37 #include <net/irda/parameters.h>
38 #include <net/irda/irttp.h>
39
40 static struct irttp_cb *irttp = NULL;
41
42 static void __irttp_close_tsap(struct tsap_cb *self);
43
44 static int irttp_data_indication(void *instance, void *sap,
45 struct sk_buff *skb);
46 static int irttp_udata_indication(void *instance, void *sap,
47 struct sk_buff *skb);
48 static void irttp_disconnect_indication(void *instance, void *sap,
49 LM_REASON reason, struct sk_buff *);
50 static void irttp_connect_indication(void *instance, void *sap,
51 struct qos_info *qos, __u32 max_sdu_size,
52 __u8 header_size, struct sk_buff *skb);
53 static void irttp_connect_confirm(void *instance, void *sap,
54 struct qos_info *qos, __u32 max_sdu_size,
55 __u8 header_size, struct sk_buff *skb);
56 static void irttp_run_tx_queue(struct tsap_cb *self);
57 static void irttp_run_rx_queue(struct tsap_cb *self);
58
59 static void irttp_flush_queues(struct tsap_cb *self);
60 static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb);
61 static void irttp_start_todo_timer(struct tsap_cb *self, int timeout);
62 static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self);
63 static int irttp_param_max_sdu_size(void *instance, irda_param_t *param,
64 int get);
65
66 /* Information for parsing parameters in IrTTP */
67 static pi_minor_info_t pi_minor_call_table[] = {
68 { NULL, 0 }, /* 0x00 */
69 { irttp_param_max_sdu_size, PV_INTEGER | PV_BIG_ENDIAN } /* 0x01 */
70 };
71 static pi_major_info_t pi_major_call_table[] = {{ pi_minor_call_table, 2 }};
72 static pi_param_info_t param_info = { pi_major_call_table, 1, 0x0f, 4 };
73
74 /*
75 * Function irttp_init (void)
76 *
77 * Initialize the IrTTP layer. Called by module initialization code
78 *
79 */
80 int __init irttp_init(void)
81 {
82 /* Initialize the irttp structure. */
83 if (irttp == NULL) {
84 irttp = kmalloc(sizeof(struct irttp_cb), GFP_KERNEL);
85 if (irttp == NULL)
86 return -ENOMEM;
87 }
88 memset(irttp, 0, sizeof(struct irttp_cb));
89
90 irttp->magic = TTP_MAGIC;
91
92 irttp->tsaps = hashbin_new(HB_LOCAL);
93 if (!irttp->tsaps) {
94 ERROR(__FUNCTION__ "(), can't allocate IrTTP hashbin!\n");
95 return -ENOMEM;
96 }
97
98 return 0;
99 }
100
101 /*
102 * Function irttp_cleanup (void)
103 *
104 * Called by module destruction/cleanup code
105 *
106 */
107 #ifdef MODULE
108 void irttp_cleanup(void)
109 {
110 /* Check for main structure */
111 ASSERT(irttp != NULL, return;);
112 ASSERT(irttp->magic == TTP_MAGIC, return;);
113
114 /*
115 * Delete hashbin and close all TSAP instances in it
116 */
117 hashbin_delete(irttp->tsaps, (FREE_FUNC) __irttp_close_tsap);
118
119 irttp->magic = 0;
120
121 /* De-allocate main structure */
122 kfree(irttp);
123
124 irttp = NULL;
125 }
126 #endif
127
128 /*
129 * Function irttp_open_tsap (stsap, notify)
130 *
131 * Create TSAP connection endpoint,
132 */
133 struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
134 {
135 struct tsap_cb *self;
136 struct lsap_cb *lsap;
137 notify_t ttp_notify;
138
139 ASSERT(irttp != NULL, return NULL;);
140 ASSERT(irttp->magic == TTP_MAGIC, return NULL;);
141
142 self = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
143 if (self == NULL) {
144 IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc!\n");
145 return NULL;
146 }
147 memset(self, 0, sizeof(struct tsap_cb));
148 spin_lock_init(&self->lock);
149
150 init_timer(&self->todo_timer);
151
152 /* Initialize callbacks for IrLMP to use */
153 irda_notify_init(&ttp_notify);
154 ttp_notify.connect_confirm = irttp_connect_confirm;
155 ttp_notify.connect_indication = irttp_connect_indication;
156 ttp_notify.disconnect_indication = irttp_disconnect_indication;
157 ttp_notify.data_indication = irttp_data_indication;
158 ttp_notify.udata_indication = irttp_udata_indication;
159 if(notify->status_indication != NULL)
160 ttp_notify.status_indication = irttp_status_indication;
161 ttp_notify.instance = self;
162 strncpy(ttp_notify.name, notify->name, NOTIFY_MAX_NAME);
163
164 self->magic = TTP_TSAP_MAGIC;
165 self->connected = FALSE;
166
167 skb_queue_head_init(&self->rx_queue);
168 skb_queue_head_init(&self->tx_queue);
169 skb_queue_head_init(&self->rx_fragments);
170 /*
171 * Create LSAP at IrLMP layer
172 */
173 lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0);
174 if (lsap == NULL) {
175 WARNING(__FUNCTION__ "(), unable to allocate LSAP!!\n");
176 return NULL;
177 }
178
179 /*
180 * If user specified LSAP_ANY as source TSAP selector, then IrLMP
181 * will replace it with whatever source selector which is free, so
182 * the stsap_sel we have might not be valid anymore
183 */
184 self->stsap_sel = lsap->slsap_sel;
185 IRDA_DEBUG(4, __FUNCTION__ "(), stsap_sel=%02x\n", self->stsap_sel);
186
187 self->notify = *notify;
188 self->lsap = lsap;
189
190 hashbin_insert(irttp->tsaps, (irda_queue_t *) self, (int) self, NULL);
191
192 if (credit > TTP_MAX_QUEUE)
193 self->initial_credit = TTP_MAX_QUEUE;
194 else
195 self->initial_credit = credit;
196
197 return self;
198 }
199
200 /*
201 * Function irttp_close (handle)
202 *
203 * Remove an instance of a TSAP. This function should only deal with the
204 * deallocation of the TSAP, and resetting of the TSAPs values;
205 *
206 */
207 static void __irttp_close_tsap(struct tsap_cb *self)
208 {
209 /* First make sure we're connected. */
210 ASSERT(self != NULL, return;);
211 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
212
213 irttp_flush_queues(self);
214
215 del_timer(&self->todo_timer);
216
217 self->connected = FALSE;
218 self->magic = ~TTP_TSAP_MAGIC;
219
220 kfree(self);
221 }
222
223 /*
224 * Function irttp_close (self)
225 *
226 * Remove TSAP from list of all TSAPs and then deallocate all resources
227 * associated with this TSAP
228 *
229 */
230 int irttp_close_tsap(struct tsap_cb *self)
231 {
232 struct tsap_cb *tsap;
233
234 IRDA_DEBUG(4, __FUNCTION__ "()\n");
235
236 ASSERT(self != NULL, return -1;);
237 ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
238
239 /* Make sure tsap has been disconnected */
240 if (self->connected) {
241 /* Check if disconnect is not pending */
242 if (!self->disconnect_pend) {
243 IRDA_DEBUG(0, __FUNCTION__ "(), TSAP still connected!\n");
244 irttp_disconnect_request(self, NULL, P_NORMAL);
245 }
246 self->close_pend = TRUE;
247 irttp_start_todo_timer(self, 1*HZ);
248
249 return 0; /* Will be back! */
250 }
251
252 tsap = hashbin_remove(irttp->tsaps, (int) self, NULL);
253
254 ASSERT(tsap == self, return -1;);
255
256 /* Close corresponding LSAP */
257 if (self->lsap) {
258 irlmp_close_lsap(self->lsap);
259 self->lsap = NULL;
260 }
261
262 __irttp_close_tsap(self);
263
264 return 0;
265 }
266
267 /*
268 * Function irttp_udata_request (self, skb)
269 *
270 * Send unreliable data on this TSAP
271 *
272 */
273 int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb)
274 {
275 ASSERT(self != NULL, return -1;);
276 ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
277 ASSERT(skb != NULL, return -1;);
278
279 IRDA_DEBUG(4, __FUNCTION__ "()\n");
280
281 /* Check that nothing bad happens */
282 if ((skb->len == 0) || (!self->connected)) {
283 IRDA_DEBUG(1, __FUNCTION__ "(), No data, or not connected\n");
284 return -1;
285 }
286
287 if (skb->len > self->max_seg_size) {
288 IRDA_DEBUG(1, __FUNCTION__ "(), UData is to large for IrLAP!\n");
289 return -1;
290 }
291
292 irlmp_udata_request(self->lsap, skb);
293 self->stats.tx_packets++;
294
295 return 0;
296 }
297
298 /*
299 * Function irttp_data_request (handle, skb)
300 *
301 * Queue frame for transmission. If SAR is enabled, fragement the frame
302 * and queue the fragments for transmission
303 */
304 int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb)
305 {
306 __u8 *frame;
307
308 ASSERT(self != NULL, return -1;);
309 ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
310 ASSERT(skb != NULL, return -1;);
311
312 /* Check that nothing bad happens */
313 if ((skb->len == 0) || (!self->connected)) {
314 WARNING(__FUNCTION__ "(), No data, or not connected\n");
315 return -ENOTCONN;
316 }
317
318 /*
319 * Check if SAR is disabled, and the frame is larger than what fits
320 * inside an IrLAP frame
321 */
322 if ((self->tx_max_sdu_size == 0) && (skb->len > self->max_seg_size)) {
323 ERROR(__FUNCTION__
324 "(), SAR disabled, and data is to large for IrLAP!\n");
325 return -EMSGSIZE;
326 }
327
328 /*
329 * Check if SAR is enabled, and the frame is larger than the
330 * TxMaxSduSize
331 */
332 if ((self->tx_max_sdu_size != 0) &&
333 (self->tx_max_sdu_size != TTP_SAR_UNBOUND) &&
334 (skb->len > self->tx_max_sdu_size))
335 {
336 ERROR(__FUNCTION__ "(), SAR enabled, "
337 "but data is larger than TxMaxSduSize!\n");
338 return -EMSGSIZE;
339 }
340 /*
341 * Check if transmit queue is full
342 */
343 if (skb_queue_len(&self->tx_queue) >= TTP_MAX_QUEUE) {
344 /*
345 * Give it a chance to empty itself
346 */
347 irttp_run_tx_queue(self);
348
349 return -ENOBUFS;
350 }
351
352 /* Queue frame, or queue frame segments */
353 if ((self->tx_max_sdu_size == 0) || (skb->len < self->max_seg_size)) {
354 /* Queue frame */
355 ASSERT(skb_headroom(skb) >= TTP_HEADER, return -1;);
356 frame = skb_push(skb, TTP_HEADER);
357 frame[0] = 0x00; /* Clear more bit */
358
359 skb_queue_tail(&self->tx_queue, skb);
360 } else {
361 /*
362 * Fragment the frame, this function will also queue the
363 * fragments, we don't care about the fact the the transmit
364 * queue may be overfilled by all the segments for a little
365 * while
366 */
367 irttp_fragment_skb(self, skb);
368 }
369
370 /* Check if we can accept more data from client */
371 if ((!self->tx_sdu_busy) &&
372 (skb_queue_len(&self->tx_queue) > TTP_HIGH_THRESHOLD)) {
373
374 /* Tx queue filling up, so stop client */
375 self->tx_sdu_busy = TRUE;
376
377 if (self->notify.flow_indication) {
378 self->notify.flow_indication(self->notify.instance,
379 self, FLOW_STOP);
380 }
381 }
382
383 /* Try to make some progress */
384 irttp_run_tx_queue(self);
385
386 return 0;
387 }
388
389 /*
390 * Function irttp_run_tx_queue (self)
391 *
392 * Transmit packets queued for transmission (if possible)
393 *
394 */
395 static void irttp_run_tx_queue(struct tsap_cb *self)
396 {
397 struct sk_buff *skb;
398 unsigned long flags;
399 int n;
400
401 if (irda_lock(&self->tx_queue_lock) == FALSE)
402 return;
403
404 /* Try to send out frames as long as we have credits */
405 while ((self->send_credit > 0) &&
406 (skb = skb_dequeue(&self->tx_queue)))
407 {
408 /*
409 * Make sure we don't flood IrLAP with frames just because
410 * the remote device has given us a lot of credits
411 */
412 if (irlmp_get_lap_tx_queue_len(self->lsap) > LAP_MAX_QUEUE) {
413 /* Re-queue packet */
414 skb_queue_head(&self->tx_queue, skb);
415
416 /* Try later. Would be better if IrLAP could notify us */
417 irttp_start_todo_timer(self, MSECS_TO_JIFFIES(10));
418
419 break;
420 }
421
422 /*
423 * Since we can transmit and receive frames concurrently,
424 * the code below is a critical region and we must assure that
425 * nobody messes with the credits while we update them.
426 */
427 spin_lock_irqsave(&self->lock, flags);
428
429 n = self->avail_credit;
430 self->avail_credit = 0;
431
432 /* Only room for 127 credits in frame */
433 if (n > 127) {
434 self->avail_credit = n-127;
435 n = 127;
436 }
437 self->remote_credit += n;
438 self->send_credit--;
439
440 spin_unlock_irqrestore(&self->lock, flags);
441
442 /*
443 * More bit must be set by the data_request() or fragment()
444 * functions
445 */
446 skb->data[0] |= (n & 0x7f);
447
448 irlmp_data_request(self->lsap, skb);
449 self->stats.tx_packets++;
450
451 /* Check if we can accept more frames from client */
452 if ((self->tx_sdu_busy) &&
453 (skb_queue_len(&self->tx_queue) < TTP_LOW_THRESHOLD))
454 {
455 self->tx_sdu_busy = FALSE;
456
457 if (self->notify.flow_indication)
458 self->notify.flow_indication(
459 self->notify.instance, self,
460 FLOW_START);
461 }
462 }
463
464 /* Reset lock */
465 self->tx_queue_lock = 0;
466 }
467
468 /*
469 * Function irttp_give_credit (self)
470 *
471 * Send a dataless flowdata TTP-PDU and give available credit to peer
472 * TSAP
473 */
474 void irttp_give_credit(struct tsap_cb *self)
475 {
476 struct sk_buff *tx_skb = NULL;
477 unsigned long flags;
478 int n;
479
480 ASSERT(self != NULL, return;);
481 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
482
483 IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
484 self->send_credit, self->avail_credit, self->remote_credit);
485
486 /* Give credit to peer */
487 tx_skb = dev_alloc_skb(64);
488 if (!tx_skb)
489 return;
490
491 /* Reserve space for LMP, and LAP header */
492 skb_reserve(tx_skb, self->max_header_size);
493
494 /*
495 * Since we can transmit and receive frames concurrently,
496 * the code below is a critical region and we must assure that
497 * nobody messes with the credits while we update them.
498 */
499 spin_lock_irqsave(&self->lock, flags);
500
501 n = self->avail_credit;
502 self->avail_credit = 0;
503
504 /* Only space for 127 credits in frame */
505 if (n > 127) {
506 self->avail_credit = n - 127;
507 n = 127;
508 }
509 self->remote_credit += n;
510
511 spin_unlock_irqrestore(&self->lock, flags);
512
513 skb_put(tx_skb, 1);
514 tx_skb->data[0] = (__u8) (n & 0x7f);
515
516 irlmp_data_request(self->lsap, tx_skb);
517 self->stats.tx_packets++;
518 }
519
520 /*
521 * Function irttp_udata_indication (instance, sap, skb)
522 *
523 * Received some unit-data (unreliable)
524 *
525 */
526 static int irttp_udata_indication(void *instance, void *sap,
527 struct sk_buff *skb)
528 {
529 struct tsap_cb *self;
530
531 IRDA_DEBUG(4, __FUNCTION__ "()\n");
532
533 self = (struct tsap_cb *) instance;
534
535 ASSERT(self != NULL, return -1;);
536 ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
537 ASSERT(skb != NULL, return -1;);
538
539 /* Just pass data to layer above */
540 if (self->notify.udata_indication)
541 self->notify.udata_indication(self->notify.instance, self,skb);
542 else
543 dev_kfree_skb(skb);
544
545 self->stats.rx_packets++;
546
547 return 0;
548 }
549
550 /*
551 * Function irttp_data_indication (instance, sap, skb)
552 *
553 * Receive segment from IrLMP.
554 *
555 */
556 static int irttp_data_indication(void *instance, void *sap,
557 struct sk_buff *skb)
558 {
559 struct tsap_cb *self;
560 int n;
561
562 self = (struct tsap_cb *) instance;
563
564 n = skb->data[0] & 0x7f; /* Extract the credits */
565
566 self->stats.rx_packets++;
567
568 /*
569 * Data or dataless packet? Dataless frames contains only the
570 * TTP_HEADER.
571 */
572 if (skb->len > 1) {
573 /* Deal with inbound credit */
574 self->send_credit += n;
575 self->remote_credit--;
576
577 /*
578 * We don't remove the TTP header, since we must preserve the
579 * more bit, so the defragment routing knows what to do
580 */
581 skb_queue_tail(&self->rx_queue, skb);
582 } else {
583 self->send_credit += n; /* Dataless flowdata TTP-PDU */
584 dev_kfree_skb(skb);
585 }
586
587 irttp_run_rx_queue(self);
588
589 /*
590 * Give avay some credits to peer?
591 */
592 if ((skb_queue_empty(&self->tx_queue)) &&
593 (self->remote_credit < TTP_LOW_THRESHOLD) &&
594 (self->avail_credit > 0))
595 {
596 /* Schedule to start immediately after this thread */
597 irttp_start_todo_timer(self, 0);
598 /*irttp_give_credit(self);*/
599 }
600
601 /*
602 * If the peer device has given us some credits and we didn't have
603 * anyone from before, the we need to shedule the tx queue?
604 */
605 if (self->send_credit == n) {
606 /*irttp_run_tx_queue(self);*/
607 irttp_start_todo_timer(self, 0);
608 }
609 return 0;
610 }
611
612 /*
613 * Function irttp_status_indication (self, reason)
614 *
615 * Status_indication, just pass to the higher layer...
616 *
617 */
618 void irttp_status_indication(void *instance,
619 LINK_STATUS link, LOCK_STATUS lock)
620 {
621 struct tsap_cb *self;
622
623 IRDA_DEBUG(4, __FUNCTION__ "()\n");
624
625 self = (struct tsap_cb *) instance;
626
627 ASSERT(self != NULL, return;);
628 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
629
630 /*
631 * Inform service user if he has requested it
632 */
633 if (self->notify.status_indication != NULL)
634 self->notify.status_indication(self->notify.instance,
635 link, lock);
636 else
637 IRDA_DEBUG(2, __FUNCTION__ "(), no handler\n");
638 }
639
640 /*
641 * Function irttp_flow_request (self, command)
642 *
643 * This funtion could be used by the upper layers to tell IrTTP to stop
644 * delivering frames if the receive queues are starting to get full, or
645 * to tell IrTTP to start delivering frames again.
646 */
647 void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow)
648 {
649 IRDA_DEBUG(1, __FUNCTION__ "()\n");
650
651 ASSERT(self != NULL, return;);
652 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
653
654 switch (flow) {
655 case FLOW_STOP:
656 IRDA_DEBUG(1, __FUNCTION__ "(), flow stop\n");
657 self->rx_sdu_busy = TRUE;
658 break;
659 case FLOW_START:
660 IRDA_DEBUG(1, __FUNCTION__ "(), flow start\n");
661 self->rx_sdu_busy = FALSE;
662
663 irttp_run_rx_queue(self);
664 break;
665 default:
666 IRDA_DEBUG(1, __FUNCTION__ "(), Unknown flow command!\n");
667 }
668 }
669
670 /*
671 * Function irttp_connect_request (self, dtsap_sel, daddr, qos)
672 *
673 * Try to connect to remote destination TSAP selector
674 *
675 */
676 int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
677 __u32 saddr, __u32 daddr,
678 struct qos_info *qos, __u32 max_sdu_size,
679 struct sk_buff *userdata)
680 {
681 struct sk_buff *skb;
682 __u8 *frame;
683 __u8 n;
684
685 IRDA_DEBUG(4, __FUNCTION__ "(), max_sdu_size=%d\n", max_sdu_size);
686
687 ASSERT(self != NULL, return -EBADR;);
688 ASSERT(self->magic == TTP_TSAP_MAGIC, return -EBADR;);
689
690 if (self->connected)
691 return -EISCONN;
692
693 /* Any userdata supplied? */
694 if (userdata == NULL) {
695 skb = dev_alloc_skb(64);
696 if (!skb)
697 return -ENOMEM;
698
699 /* Reserve space for MUX_CONTROL and LAP header */
700 skb_reserve(skb, TTP_MAX_HEADER);
701 } else {
702 skb = userdata;
703 /*
704 * Check that the client has reserved enough space for
705 * headers
706 */
707 ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER, return -1;);
708 }
709
710 /* Initialize connection parameters */
711 self->connected = FALSE;
712 self->avail_credit = 0;
713 self->rx_max_sdu_size = max_sdu_size;
714 self->rx_sdu_size = 0;
715 self->rx_sdu_busy = FALSE;
716 self->dtsap_sel = dtsap_sel;
717
718 n = self->initial_credit;
719
720 self->remote_credit = 0;
721 self->send_credit = 0;
722
723 /*
724 * Give away max 127 credits for now
725 */
726 if (n > 127) {
727 self->avail_credit=n-127;
728 n = 127;
729 }
730
731 self->remote_credit = n;
732
733 /* SAR enabled? */
734 if (max_sdu_size > 0) {
735 ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER),
736 return -1;);
737
738 /* Insert SAR parameters */
739 frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER);
740
741 frame[0] = TTP_PARAMETERS | n;
742 frame[1] = 0x04; /* Length */
743 frame[2] = 0x01; /* MaxSduSize */
744 frame[3] = 0x02; /* Value length */
745
746 put_unaligned(cpu_to_be16((__u16) max_sdu_size),
747 (__u16 *)(frame+4));
748 } else {
749 /* Insert plain TTP header */
750 frame = skb_push(skb, TTP_HEADER);
751
752 /* Insert initial credit in frame */
753 frame[0] = n & 0x7f;
754 }
755
756 /* Connect with IrLMP. No QoS parameters for now */
757 return irlmp_connect_request(self->lsap, dtsap_sel, saddr, daddr, qos,
758 skb);
759 }
760
761 /*
762 * Function irttp_connect_confirm (handle, qos, skb)
763 *
764 * Sevice user confirms TSAP connection with peer.
765 *
766 */
767 static void irttp_connect_confirm(void *instance, void *sap,
768 struct qos_info *qos, __u32 max_seg_size,
769 __u8 max_header_size, struct sk_buff *skb)
770 {
771 struct tsap_cb *self;
772 int parameters;
773 int ret;
774 __u8 plen;
775 __u8 n;
776
777 IRDA_DEBUG(4, __FUNCTION__ "()\n");
778
779 self = (struct tsap_cb *) instance;
780
781 ASSERT(self != NULL, return;);
782 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
783 ASSERT(skb != NULL, return;);
784
785 self->max_seg_size = max_seg_size - TTP_HEADER;
786 self->max_header_size = max_header_size + TTP_HEADER;
787
788 /*
789 * Check if we have got some QoS parameters back! This should be the
790 * negotiated QoS for the link.
791 */
792 if (qos) {
793 IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %02x\n",
794 qos->baud_rate.bits);
795 IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %d bps.\n",
796 qos->baud_rate.value);
797 }
798
799 n = skb->data[0] & 0x7f;
800
801 IRDA_DEBUG(4, __FUNCTION__ "(), Initial send_credit=%d\n", n);
802
803 self->send_credit = n;
804 self->tx_max_sdu_size = 0;
805 self->connected = TRUE;
806
807 parameters = skb->data[0] & 0x80;
808
809 ASSERT(skb->len >= TTP_HEADER, return;);
810 skb_pull(skb, TTP_HEADER);
811
812 if (parameters) {
813 plen = skb->data[0];
814
815 ret = irda_param_extract_all(self, skb->data+1,
816 IRDA_MIN(skb->len-1, plen),
817 ¶m_info);
818
819 /* Any errors in the parameter list? */
820 if (ret < 0) {
821 WARNING(__FUNCTION__
822 "(), error extracting parameters\n");
823 dev_kfree_skb(skb);
824
825 /* Do not accept this connection attempt */
826 return;
827 }
828 /* Remove parameters */
829 skb_pull(skb, IRDA_MIN(skb->len, plen+1));
830 }
831
832 IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
833 self->send_credit, self->avail_credit, self->remote_credit);
834
835 IRDA_DEBUG(2, __FUNCTION__ "(), MaxSduSize=%d\n", self->tx_max_sdu_size);
836
837 if (self->notify.connect_confirm) {
838 self->notify.connect_confirm(self->notify.instance, self, qos,
839 self->tx_max_sdu_size,
840 self->max_header_size, skb);
841 }
842 }
843
844 /*
845 * Function irttp_connect_indication (handle, skb)
846 *
847 * Some other device is connecting to this TSAP
848 *
849 */
850 void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos,
851 __u32 max_seg_size, __u8 max_header_size,
852 struct sk_buff *skb)
853 {
854 struct tsap_cb *self;
855 struct lsap_cb *lsap;
856 int parameters;
857 int ret;
858 __u8 plen;
859 __u8 n;
860
861 self = (struct tsap_cb *) instance;
862
863 ASSERT(self != NULL, return;);
864 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
865 ASSERT(skb != NULL, return;);
866
867 lsap = (struct lsap_cb *) sap;
868
869 self->max_seg_size = max_seg_size - TTP_HEADER;;
870 self->max_header_size = max_header_size+TTP_HEADER;
871
872 IRDA_DEBUG(4, __FUNCTION__ "(), TSAP sel=%02x\n", self->stsap_sel);
873
874 /* Need to update dtsap_sel if its equal to LSAP_ANY */
875 self->dtsap_sel = lsap->dlsap_sel;
876
877 n = skb->data[0] & 0x7f;
878
879 self->send_credit = n;
880 self->tx_max_sdu_size = 0;
881
882 parameters = skb->data[0] & 0x80;
883
884 ASSERT(skb->len >= TTP_HEADER, return;);
885 skb_pull(skb, TTP_HEADER);
886
887 if (parameters) {
888 plen = skb->data[0];
889
890 ret = irda_param_extract_all(self, skb->data+1,
891 IRDA_MIN(skb->len-1, plen),
892 ¶m_info);
893
894 /* Any errors in the parameter list? */
895 if (ret < 0) {
896 WARNING(__FUNCTION__
897 "(), error extracting parameters\n");
898 dev_kfree_skb(skb);
899
900 /* Do not accept this connection attempt */
901 return;
902 }
903
904 /* Remove parameters */
905 skb_pull(skb, IRDA_MIN(skb->len, plen+1));
906 }
907
908 if (self->notify.connect_indication) {
909 self->notify.connect_indication(self->notify.instance, self,
910 qos, self->tx_max_sdu_size,
911 self->max_header_size, skb);
912 } else
913 dev_kfree_skb(skb);
914 }
915
916 /*
917 * Function irttp_connect_response (handle, userdata)
918 *
919 * Service user is accepting the connection, just pass it down to
920 * IrLMP!
921 *
922 */
923 int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
924 struct sk_buff *userdata)
925 {
926 struct sk_buff *skb;
927 __u8 *frame;
928 int ret;
929 __u8 n;
930
931 ASSERT(self != NULL, return -1;);
932 ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
933
934 IRDA_DEBUG(4, __FUNCTION__ "(), Source TSAP selector=%02x\n",
935 self->stsap_sel);
936
937 /* Any userdata supplied? */
938 if (userdata == NULL) {
939 skb = dev_alloc_skb(64);
940 if (!skb)
941 return -ENOMEM;
942
943 /* Reserve space for MUX_CONTROL and LAP header */
944 skb_reserve(skb, TTP_MAX_HEADER);
945 } else {
946 skb = userdata;
947 /*
948 * Check that the client has reserved enough space for
949 * headers
950 */
951 ASSERT(skb_headroom(skb) >= TTP_MAX_HEADER, return -1;);
952 }
953
954 self->avail_credit = 0;
955 self->remote_credit = 0;
956 self->rx_max_sdu_size = max_sdu_size;
957 self->rx_sdu_size = 0;
958 self->rx_sdu_busy = FALSE;
959
960 n = self->initial_credit;
961
962 /* Frame has only space for max 127 credits (7 bits) */
963 if (n > 127) {
964 self->avail_credit = n - 127;
965 n = 127;
966 }
967
968 self->remote_credit = n;
969 self->connected = TRUE;
970
971 /* SAR enabled? */
972 if (max_sdu_size > 0) {
973 ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER+TTP_SAR_HEADER),
974 return -1;);
975
976 /* Insert TTP header with SAR parameters */
977 frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER);
978
979 frame[0] = TTP_PARAMETERS | n;
980 frame[1] = 0x04; /* Length */
981
982 /* irda_param_insert(self, IRTTP_MAX_SDU_SIZE, frame+1, */
983 /* TTP_SAR_HEADER, ¶m_info) */
984
985 frame[2] = 0x01; /* MaxSduSize */
986 frame[3] = 0x02; /* Value length */
987
988 put_unaligned(cpu_to_be16((__u16) max_sdu_size),
989 (__u16 *)(frame+4));
990 } else {
991 /* Insert TTP header */
992 frame = skb_push(skb, TTP_HEADER);
993
994 frame[0] = n & 0x7f;
995 }
996
997 ret = irlmp_connect_response(self->lsap, skb);
998
999 return ret;
1000 }
1001
1002 /*
1003 * Function irttp_dup (self, instance)
1004 *
1005 * Duplicate TSAP, can be used by servers to confirm a connection on a
1006 * new TSAP so it can keep listening on the old one.
1007 */
1008 struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance)
1009 {
1010 struct tsap_cb *new;
1011
1012 IRDA_DEBUG(1, __FUNCTION__ "()\n");
1013
1014 if (!hashbin_find(irttp->tsaps, (int) orig, NULL)) {
1015 IRDA_DEBUG(0, __FUNCTION__ "(), unable to find TSAP\n");
1016 return NULL;
1017 }
1018 new = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
1019 if (!new) {
1020 IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc\n");
1021 return NULL;
1022 }
1023 /* Dup */
1024 memcpy(new, orig, sizeof(struct tsap_cb));
1025 new->notify.instance = instance;
1026 new->lsap = irlmp_dup(orig->lsap, new);
1027
1028 /* Not everything should be copied */
1029 init_timer(&new->todo_timer);
1030
1031 skb_queue_head_init(&new->rx_queue);
1032 skb_queue_head_init(&new->tx_queue);
1033 skb_queue_head_init(&new->rx_fragments);
1034
1035 hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (int) new, NULL);
1036
1037 return new;
1038 }
1039
1040 /*
1041 * Function irttp_disconnect_request (self)
1042 *
1043 * Close this connection please! If priority is high, the queued data
1044 * segments, if any, will be deallocated first
1045 *
1046 */
1047 int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata,
1048 int priority)
1049 {
1050 struct sk_buff *skb;
1051 int ret;
1052
1053 ASSERT(self != NULL, return -1;);
1054 ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
1055
1056 /* Already disconnected? */
1057 if (!self->connected) {
1058 IRDA_DEBUG(4, __FUNCTION__ "(), already disconnected!\n");
1059 return -1;
1060 }
1061
1062 /* Disconnect already pending? */
1063 if (self->disconnect_pend) {
1064 IRDA_DEBUG(1, __FUNCTION__ "(), disconnect already pending\n");
1065 if (userdata) {
1066 dev_kfree_skb(userdata);
1067 }
1068
1069 /* Try to make some progress */
1070 irttp_run_rx_queue(self);
1071 return -1;
1072 }
1073
1074 /*
1075 * Check if there is still data segments in the transmit queue
1076 */
1077 if (skb_queue_len(&self->tx_queue) > 0) {
1078 if (priority == P_HIGH) {
1079 IRDA_DEBUG(1, __FUNCTION__ "High priority!!()\n" );
1080
1081 /*
1082 * No need to send the queued data, if we are
1083 * disconnecting right now since the data will
1084 * not have any usable connection to be sent on
1085 */
1086 irttp_flush_queues(self);
1087 } else if (priority == P_NORMAL) {
1088 /*
1089 * Must delay disconnect til after all data segments
1090 * have been sent an the tx_queue is empty
1091 */
1092 if (userdata)
1093 self->disconnect_skb = userdata;
1094 else
1095 self->disconnect_skb = NULL;
1096
1097 self->disconnect_pend = TRUE;
1098
1099 irttp_run_tx_queue(self);
1100
1101 irttp_start_todo_timer(self, MSECS_TO_JIFFIES(1000));
1102 return -1;
1103 }
1104 }
1105 IRDA_DEBUG(1, __FUNCTION__ "(), Disconnecting ...\n");
1106
1107 self->connected = FALSE;
1108
1109 if (!userdata) {
1110 skb = dev_alloc_skb(64);
1111 if (!skb)
1112 return -ENOMEM;
1113
1114 /*
1115 * Reserve space for MUX and LAP header
1116 */
1117 skb_reserve(skb, TTP_MAX_HEADER);
1118
1119 userdata = skb;
1120 }
1121 ret = irlmp_disconnect_request(self->lsap, userdata);
1122
1123 return ret;
1124 }
1125
1126 /*
1127 * Function irttp_disconnect_indication (self, reason)
1128 *
1129 * Disconnect indication, TSAP disconnected by peer?
1130 *
1131 */
1132 void irttp_disconnect_indication(void *instance, void *sap, LM_REASON reason,
1133 struct sk_buff *skb)
1134 {
1135 struct tsap_cb *self;
1136
1137 IRDA_DEBUG(4, __FUNCTION__ "()\n");
1138
1139 self = (struct tsap_cb *) instance;
1140
1141 ASSERT(self != NULL, return;);
1142 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
1143
1144 self->connected = FALSE;
1145
1146 /* Check if client has already tried to close the TSAP */
1147 if (self->close_pend) {
1148 irttp_close_tsap(self);
1149 return;
1150 }
1151
1152 /* No need to notify the client if has already tried to disconnect */
1153 if (self->disconnect_pend)
1154 return;
1155
1156 if (self->notify.disconnect_indication)
1157 self->notify.disconnect_indication(self->notify.instance, self,
1158 reason, skb);
1159 else
1160 if (skb)
1161 dev_kfree_skb(skb);
1162 }
1163
1164 /*
1165 * Function irttp_do_data_indication (self, skb)
1166 *
1167 * Try to deliver reassebled skb to layer above, and requeue it if that
1168 * for some reason should fail. We mark rx sdu as busy to apply back
1169 * pressure is necessary.
1170 */
1171 void irttp_do_data_indication(struct tsap_cb *self, struct sk_buff *skb)
1172 {
1173 int err;
1174
1175 /* Check if client has already tried to close the TSAP */
1176 if (self->close_pend || self->disconnect_pend) {
1177 dev_kfree_skb(skb);
1178 return;
1179 }
1180
1181 err = self->notify.data_indication(self->notify.instance, self, skb);
1182
1183 /* Usually the layer above will notify that it's input queue is
1184 * starting to get filled by using the flow request, but this may
1185 * be difficult, so it can instead just refuse to eat it and just
1186 * give an error back
1187 */
1188 if (err == -ENOMEM) {
1189 IRDA_DEBUG(0, __FUNCTION__ "() requeueing skb!\n");
1190
1191 /* Make sure we take a break */
1192 self->rx_sdu_busy = TRUE;
1193
1194 /* Need to push the header in again */
1195 skb_push(skb, TTP_HEADER);
1196 skb->data[0] = 0x00; /* Make sure MORE bit is cleared */
1197
1198 /* Put skb back on queue */
1199 skb_queue_head(&self->rx_queue, skb);
1200 }
1201 }
1202
1203 /*
1204 * Function irttp_run_rx_queue (self)
1205 *
1206 * Check if we have any frames to be transmitted, or if we have any
1207 * available credit to give away.
1208 */
1209 void irttp_run_rx_queue(struct tsap_cb *self)
1210 {
1211 struct sk_buff *skb;
1212 int more = 0;
1213
1214 IRDA_DEBUG(2, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
1215 self->send_credit, self->avail_credit, self->remote_credit);
1216
1217 if (irda_lock(&self->rx_queue_lock) == FALSE)
1218 return;
1219
1220 /*
1221 * Reassemble all frames in receive queue and deliver them
1222 */
1223 while (!self->rx_sdu_busy && (skb = skb_dequeue(&self->rx_queue))) {
1224 self->avail_credit++;
1225
1226 more = skb->data[0] & 0x80;
1227
1228 /* Remove TTP header */
1229 skb_pull(skb, TTP_HEADER);
1230
1231 /* Add the length of the remaining data */
1232 self->rx_sdu_size += skb->len;
1233
1234 /*
1235 * If SAR is disabled, or user has requested no reassembly
1236 * of received fragements then we just deliver them
1237 * immediately. This can be requested by clients that
1238 * implements byte streams without any message boundaries
1239 */
1240 if (self->rx_max_sdu_size == TTP_SAR_DISABLE) {
1241 irttp_do_data_indication(self, skb);
1242 self->rx_sdu_size = 0;
1243
1244 continue;
1245 }
1246
1247 /* Check if this is a fragment, and not the last fragment */
1248 if (more) {
1249 /*
1250 * Queue the fragment if we still are within the
1251 * limits of the maximum size of the rx_sdu
1252 */
1253 if (self->rx_sdu_size <= self->rx_max_sdu_size) {
1254 IRDA_DEBUG(4, __FUNCTION__ "(), queueing frag\n");
1255 skb_queue_tail(&self->rx_fragments, skb);
1256 } else {
1257 /* Free the part of the SDU that is too big */
1258 dev_kfree_skb(skb);
1259 }
1260 continue;
1261 }
1262 /*
1263 * This is the last fragment, so time to reassemble!
1264 */
1265 if ((self->rx_sdu_size <= self->rx_max_sdu_size) ||
1266 (self->rx_max_sdu_size == TTP_SAR_UNBOUND))
1267 {
1268 /*
1269 * A little optimizing. Only queue the fragment if
1270 * there are other fragments. Since if this is the
1271 * last and only fragment, there is no need to
1272 * reassemble :-)
1273 */
1274 if (!skb_queue_empty(&self->rx_fragments)) {
1275 skb_queue_tail(&self->rx_fragments,
1276 skb);
1277
1278 skb = irttp_reassemble_skb(self);
1279 }
1280
1281 /* Now we can deliver the reassembled skb */
1282 irttp_do_data_indication(self, skb);
1283 } else {
1284 IRDA_DEBUG(1, __FUNCTION__ "(), Truncated frame\n");
1285
1286 /* Free the part of the SDU that is too big */
1287 dev_kfree_skb(skb);
1288
1289 /* Deliver only the valid but truncated part of SDU */
1290 skb = irttp_reassemble_skb(self);
1291
1292 irttp_do_data_indication(self, skb);
1293 }
1294 self->rx_sdu_size = 0;
1295 }
1296 /* Reset lock */
1297 self->rx_queue_lock = 0;
1298 }
1299
1300 /*
1301 * Function irttp_flush_queues (self)
1302 *
1303 * Flushes (removes all frames) in transitt-buffer (tx_list)
1304 */
1305 void irttp_flush_queues(struct tsap_cb *self)
1306 {
1307 struct sk_buff* skb;
1308
1309 IRDA_DEBUG(4, __FUNCTION__ "()\n");
1310
1311 ASSERT(self != NULL, return;);
1312 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
1313
1314 /* Deallocate frames waiting to be sent */
1315 while ((skb = skb_dequeue(&self->tx_queue)) != NULL)
1316 dev_kfree_skb(skb);
1317
1318 /* Deallocate received frames */
1319 while ((skb = skb_dequeue(&self->rx_queue)) != NULL)
1320 dev_kfree_skb(skb);
1321
1322 /* Deallocate received fragments */
1323 while ((skb = skb_dequeue(&self->rx_fragments)) != NULL)
1324 dev_kfree_skb(skb);
1325 }
1326
1327 /*
1328 * Function irttp_reasseble (self)
1329 *
1330 * Makes a new (continuous) skb of all the fragments in the fragment
1331 * queue
1332 *
1333 */
1334 static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self)
1335 {
1336 struct sk_buff *skb, *frag;
1337 int n = 0; /* Fragment index */
1338
1339 ASSERT(self != NULL, return NULL;);
1340 ASSERT(self->magic == TTP_TSAP_MAGIC, return NULL;);
1341
1342 IRDA_DEBUG(2, __FUNCTION__ "(), self->rx_sdu_size=%d\n",
1343 self->rx_sdu_size);
1344
1345 skb = dev_alloc_skb(TTP_HEADER + self->rx_sdu_size);
1346 if (!skb)
1347 return NULL;
1348
1349 /*
1350 * Need to reserve space for TTP header in case this skb needs to
1351 * be requeued in case delivery failes
1352 */
1353 skb_reserve(skb, TTP_HEADER);
1354 skb_put(skb, self->rx_sdu_size);
1355
1356 /*
1357 * Copy all fragments to a new buffer
1358 */
1359 while ((frag = skb_dequeue(&self->rx_fragments)) != NULL) {
1360 memcpy(skb->data+n, frag->data, frag->len);
1361 n += frag->len;
1362
1363 dev_kfree_skb(frag);
1364 }
1365 IRDA_DEBUG(2, __FUNCTION__ "(), frame len=%d\n", n);
1366
1367 IRDA_DEBUG(2, __FUNCTION__ "(), rx_sdu_size=%d\n", self->rx_sdu_size);
1368 ASSERT(n <= self->rx_sdu_size, return NULL;);
1369
1370 /* Set the new length */
1371 skb_trim(skb, n);
1372
1373 self->rx_sdu_size = 0;
1374
1375 return skb;
1376 }
1377
1378 /*
1379 * Function irttp_fragment_skb (skb)
1380 *
1381 * Fragments a frame and queues all the fragments for transmission
1382 *
1383 */
1384 static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb)
1385 {
1386 struct sk_buff *frag;
1387 __u8 *frame;
1388
1389 IRDA_DEBUG(2, __FUNCTION__ "()\n");
1390
1391 ASSERT(self != NULL, return;);
1392 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
1393 ASSERT(skb != NULL, return;);
1394
1395 /*
1396 * Split frame into a number of segments
1397 */
1398 while (skb->len > self->max_seg_size) {
1399 IRDA_DEBUG(2, __FUNCTION__ "(), fragmenting ...\n");
1400
1401 /* Make new segment */
1402 frag = dev_alloc_skb(self->max_seg_size+self->max_header_size);
1403 if (!frag)
1404 return;
1405
1406 skb_reserve(frag, self->max_header_size);
1407
1408 /* Copy data from the original skb into this fragment. */
1409 memcpy(skb_put(frag, self->max_seg_size), skb->data,
1410 self->max_seg_size);
1411
1412 /* Insert TTP header, with the more bit set */
1413 frame = skb_push(frag, TTP_HEADER);
1414 frame[0] = TTP_MORE;
1415
1416 /* Hide the copied data from the original skb */
1417 skb_pull(skb, self->max_seg_size);
1418
1419 /* Queue fragment */
1420 skb_queue_tail(&self->tx_queue, frag);
1421 }
1422 /* Queue what is left of the original skb */
1423 IRDA_DEBUG(2, __FUNCTION__ "(), queuing last segment\n");
1424
1425 frame = skb_push(skb, TTP_HEADER);
1426 frame[0] = 0x00; /* Clear more bit */
1427
1428 /* Queue fragment */
1429 skb_queue_tail(&self->tx_queue, skb);
1430 }
1431
1432 /*
1433 * Function irttp_param_max_sdu_size (self, param)
1434 *
1435 * Handle the MaxSduSize parameter in the connect frames, this function
1436 * will be called both when this parameter needs to be inserted into, and
1437 * extracted from the connect frames
1438 */
1439 static int irttp_param_max_sdu_size(void *instance, irda_param_t *param,
1440 int get)
1441 {
1442 struct tsap_cb *self;
1443
1444 self = (struct tsap_cb *) instance;
1445
1446 ASSERT(self != NULL, return -1;);
1447 ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
1448
1449 if (get)
1450 param->pv.i = self->tx_max_sdu_size;
1451 else
1452 self->tx_max_sdu_size = param->pv.i;
1453
1454 IRDA_DEBUG(0, __FUNCTION__ "(), MaxSduSize=%d\n", param->pv.i);
1455
1456 return 0;
1457 }
1458
1459 /*
1460 * Function irttp_todo_expired (data)
1461 *
1462 * Todo timer has expired!
1463 *
1464 */
1465 static void irttp_todo_expired(unsigned long data)
1466 {
1467 struct tsap_cb *self = (struct tsap_cb *) data;
1468
1469 /* Check that we still exist */
1470 if (!self || self->magic != TTP_TSAP_MAGIC)
1471 return;
1472
1473 irttp_run_rx_queue(self);
1474 irttp_run_tx_queue(self);
1475
1476 /* Give avay some credits to peer? */
1477 if ((self->remote_credit < TTP_LOW_THRESHOLD) &&
1478 (self->avail_credit > 0) && (skb_queue_empty(&self->tx_queue)))
1479 {
1480 irttp_give_credit(self);
1481 }
1482
1483 /* Check if time for disconnect */
1484 if (self->disconnect_pend) {
1485 /* Check if it's possible to disconnect yet */
1486 if (skb_queue_empty(&self->tx_queue)) {
1487
1488 /* Make sure disconnect is not pending anymore */
1489 self->disconnect_pend = FALSE;
1490 if (self->disconnect_skb) {
1491 irttp_disconnect_request(
1492 self, self->disconnect_skb, P_NORMAL);
1493 self->disconnect_skb = NULL;
1494 } else
1495 irttp_disconnect_request(self, NULL, P_NORMAL);
1496 } else {
1497 /* Try again later */
1498 irttp_start_todo_timer(self, 1*HZ);
1499
1500 /* No reason to try and close now */
1501 return;
1502 }
1503 }
1504
1505 /* Check if it's closing time */
1506 if (self->close_pend)
1507 irttp_close_tsap(self);
1508 }
1509
1510 /*
1511 * Function irttp_start_todo_timer (self, timeout)
1512 *
1513 * Start todo timer.
1514 *
1515 */
1516 static void irttp_start_todo_timer(struct tsap_cb *self, int timeout)
1517 {
1518 ASSERT(self != NULL, return;);
1519 ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
1520
1521 del_timer(&self->todo_timer);
1522
1523 self->todo_timer.data = (unsigned long) self;
1524 self->todo_timer.function = &irttp_todo_expired;
1525 self->todo_timer.expires = jiffies + timeout;
1526
1527 add_timer(&self->todo_timer);
1528 }
1529
1530 #ifdef CONFIG_PROC_FS
1531 /*
1532 * Function irttp_proc_read (buf, start, offset, len, unused)
1533 *
1534 * Give some info to the /proc file system
1535 */
1536 int irttp_proc_read(char *buf, char **start, off_t offset, int len)
1537 {
1538 struct tsap_cb *self;
1539 unsigned long flags;
1540 int i = 0;
1541
1542 ASSERT(irttp != NULL, return 0;);
1543
1544 len = 0;
1545
1546 save_flags(flags);
1547 cli();
1548
1549 self = (struct tsap_cb *) hashbin_get_first(irttp->tsaps);
1550 while (self != NULL) {
1551 if (!self || self->magic != TTP_TSAP_MAGIC)
1552 return len;
1553
1554 len += sprintf(buf+len, "TSAP %d, ", i++);
1555 len += sprintf(buf+len, "stsap_sel: %02x, ",
1556 self->stsap_sel);
1557 len += sprintf(buf+len, "dtsap_sel: %02x\n",
1558 self->dtsap_sel);
1559 len += sprintf(buf+len, " connected: %s, ",
1560 self->connected? "TRUE":"FALSE");
1561 len += sprintf(buf+len, "avail credit: %d, ",
1562 self->avail_credit);
1563 len += sprintf(buf+len, "remote credit: %d, ",
1564 self->remote_credit);
1565 len += sprintf(buf+len, "send credit: %d\n",
1566 self->send_credit);
1567 len += sprintf(buf+len, " tx packets: %d, ",
1568 self->stats.tx_packets);
1569 len += sprintf(buf+len, "rx packets: %d, ",
1570 self->stats.rx_packets);
1571 len += sprintf(buf+len, "tx_queue len: %d ",
1572 skb_queue_len(&self->tx_queue));
1573 len += sprintf(buf+len, "rx_queue len: %d\n",
1574 skb_queue_len(&self->rx_queue));
1575 len += sprintf(buf+len, " tx_sdu_busy: %s, ",
1576 self->tx_sdu_busy? "TRUE":"FALSE");
1577 len += sprintf(buf+len, "rx_sdu_busy: %s\n",
1578 self->rx_sdu_busy? "TRUE":"FALSE");
1579 len += sprintf(buf+len, " max_seg_size: %d, ",
1580 self->max_seg_size);
1581 len += sprintf(buf+len, "tx_max_sdu_size: %d, ",
1582 self->tx_max_sdu_size);
1583 len += sprintf(buf+len, "rx_max_sdu_size: %d\n",
1584 self->rx_max_sdu_size);
1585
1586 len += sprintf(buf+len, " Used by (%s)\n",
1587 self->notify.name);
1588
1589 len += sprintf(buf+len, "\n");
1590
1591 self = (struct tsap_cb *) hashbin_get_next(irttp->tsaps);
1592 }
1593 restore_flags(flags);
1594
1595 return len;
1596 }
1597
1598 #endif /* PROC_FS */
1599
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.