~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/irda/irttp.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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                                              &param_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                                              &param_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, &param_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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.