]> git.neil.brown.name Git - history.git/commitdiff
Import 2.2.10pre2 2.2.10pre2
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:19:02 +0000 (15:19 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:19:02 +0000 (15:19 -0500)
77 files changed:
README
arch/i386/lib/checksum.S
arch/sparc64/kernel/setup.c
drivers/block/loop.c
drivers/block/ns87415.c
drivers/char/bttv.c
drivers/char/bttv.h
drivers/misc/parport_pc.c
drivers/net/cosa.c
drivers/net/eexpress.c
drivers/net/irda/Config.in
drivers/net/irda/Makefile
drivers/net/irda/actisys.c
drivers/net/irda/esi.c
drivers/net/irda/girbil.c
drivers/net/irda/irport.c
drivers/net/irda/irtty.c
drivers/net/irda/litelink.c [new file with mode: 0644]
drivers/net/irda/pc87108.c
drivers/net/irda/tekram.c
drivers/net/irda/toshoboe.c [new file with mode: 0644]
drivers/net/irda/uircc.c
drivers/net/irda/w83977af_ir.c
drivers/net/sunhme.c
drivers/video/cgsixfb.c
fs/ext2/file.c
fs/smbfs/inode.c
include/net/irda/crc.h
include/net/irda/dongle.h
include/net/irda/ircomm_common.h
include/net/irda/irda.h
include/net/irda/irda_device.h
include/net/irda/iriap.h
include/net/irda/irlan_common.h
include/net/irda/irlan_provider.h
include/net/irda/irlap.h
include/net/irda/irlmp.h
include/net/irda/irlpt_common.h
include/net/irda/irport.h
include/net/irda/irttp.h
include/net/irda/irtty.h
include/net/irda/toshoboe.h [new file with mode: 0644]
include/net/irda/w83977af_ir.h
include/net/irda/wrapper.h
net/ipv4/ip_options.c
net/ipv6/icmp.c
net/irda/af_irda.c
net/irda/crc.c
net/irda/discovery.c
net/irda/ircomm/ircomm_common.c
net/irda/ircomm/irvtd_driver.c
net/irda/irda_device.c
net/irda/iriap.c
net/irda/iriap_event.c
net/irda/irlan/irlan_client.c
net/irda/irlan/irlan_client_event.c
net/irda/irlan/irlan_common.c
net/irda/irlan/irlan_eth.c
net/irda/irlan/irlan_event.c
net/irda/irlan/irlan_filter.c
net/irda/irlan/irlan_provider.c
net/irda/irlan/irlan_provider_event.c
net/irda/irlap_comp.c
net/irda/irlap_event.c
net/irda/irlap_frame.c
net/irda/irlmp.c
net/irda/irlmp_frame.c
net/irda/irlpt/irlpt_cli.c
net/irda/irlpt/irlpt_cli_fsm.c
net/irda/irlpt/irlpt_common.c
net/irda/irlpt/irlpt_srvr.c
net/irda/irmod.c
net/irda/irproc.c
net/irda/irsysctl.c
net/irda/irttp.c
net/irda/qos.c
net/irda/wrapper.c

diff --git a/README b/README
index b1bac81558f52408d07247ef4a82dec59188aad6..2bd186f4db139936f41d0a1ddc03a06eee87f560 100644 (file)
--- a/README
+++ b/README
@@ -32,11 +32,11 @@ DOCUMENTATION:
  - There is a lot of documentation available both in electronic form on
    the Internet and in books, both Linux-specific and pertaining to
    general UNIX questions.  I'd recommend looking into the documentation
-   subdirectories on any Linux ftp site for the LDP (Linux Documentation
+   subdirectories on any Linux FTP site for the LDP (Linux Documentation
    Project) books.  This README is not meant to be documentation on the
    system: there are much better sources available.
 
- - There are various readme's in the kernel Documentation/ subdirectory:
+ - There are various README files in the Documentation/ subdirectory:
    these typically contain kernel-specific installation notes for some 
    drivers for example. See ./Documentation/00-INDEX for a list of what
    is contained in each file.  Please read the Changes file, as it
@@ -219,7 +219,7 @@ IF SOMETHING GOES WRONG:
    isn't anyone listed there, then the second best thing is to mail
    them to me (torvalds@transmeta.com), and possibly to any other
    relevant mailing-list or to the newsgroup.  The mailing-lists are
-   useful especially for SCSI and NETworking problems, as I can't test
+   useful especially for SCSI and networking problems, as I can't test
    either of those personally anyway. 
 
  - In all bug-reports, *please* tell what kernel you are talking about,
index 46527a85de12bd50462aa6bcf4e94f573bcb8e55..af10dc7c9ce5a492616471845e922a58a286bbd3 100644 (file)
@@ -369,7 +369,7 @@ DST(        movb %cl, (%edi)        )
 
 #define ROUND1(x) \
        SRC(movl x(%esi), %ebx  )       ;       \
-       addl %ebx, %eax\n               ;       \
+       addl %ebx, %eax                 ;       \
        DST(movl %ebx, x(%edi)  )       ; 
 
 #define ROUND(x) \
index caa1d99ef100ddd9a96e9f09f8c7b8ac5a665fad..b09df057641349ab6f12da1815f312b716194370 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.43 1999/04/12 08:08:24 davem Exp $
+/*  $Id: setup.c,v 1.43.2.1 1999/05/28 02:18:13 davem Exp $
  *  linux/arch/sparc64/kernel/setup.c
  *
  *  Copyright (C) 1995,1996  David S. Miller (davem@caip.rutgers.edu)
@@ -550,7 +550,9 @@ __initfunc(void setup_arch(char **cmdline_p,
                        ic_servaddr = sv;
                        if (gw)
                                ic_gateway = gw;
+#if defined(CONFIG_IP_PNP_BOOTP) || defined(CONFIG_IP_PNP_RARP)
                        ic_proto_enabled = 0;
+#endif
                }
        }
 #endif
index 56cf5fb13a54a728b94cac8ae52bd54d71d00abe..26ffb26cac3da1a72a13d98d4b8e704d645de509 100644 (file)
@@ -504,6 +504,8 @@ static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
        if ((unsigned int) info.lo_encrypt_key_size > LO_KEY_SIZE)
                return -EINVAL;
        type = info.lo_encrypt_type; 
+       if (info.lo_encrypt_key_size == 0 && type == LO_CRYPT_XOR)
+               return -EINVAL;
        if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)
                return -EINVAL;
        err = loop_release_xfer(lo);
index 3275c017132d8c04b895cd9ae40b3ff77cebe618..a89b0e9c5e1f08ec03ee57564dcfbeede34d26d0 100644 (file)
@@ -49,8 +49,25 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
        new = use_dma ? ((new & ~other) | bit) : (new & ~bit);
 
        if (new != *old) {
+               unsigned char stat;
+
+               /*
+                * Don't change DMA engine settings while Write Buffers
+                * are busy.
+                */
+               (void) pci_read_config_byte(dev, 0x43, &stat);
+               while (stat & 0x03) {
+                       udelay(1);
+                       (void) pci_read_config_byte(dev, 0x43, &stat);
+               }
+
                *old = new;
                (void) pci_write_config_dword(dev, 0x40, new);
+
+               /*
+                * And let things settle...
+                */
+               udelay(10);
        }
 
        __restore_flags(flags); /* local CPU only */
index 12ac86673fce14e62833f0bb75fc39c284f23601..a3292e409c86457f6674f798846e95d798482bda 100644 (file)
@@ -543,6 +543,8 @@ static struct tvcard tvcards[] =
         { 3, 1, 0, 2,15, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0}},
         /* Pixelview PlayTV (bt878) */
         { 3, 4, 0, 2, 0x01e000, { 2, 0, 1, 1}, {0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }},
+        /* "Leadtek WinView 601", */
+        { 3, 1, 0, 2, 0x8300f8, { 2, 3, 1, 1,0}, {0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}},
 };
 #define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
 
@@ -2036,6 +2038,41 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                I2CWrite(&(btv->i2c), I2C_TDA9850,
                                        TDA9850_CON3, con3, 1);
                        }
+                  
+                      /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
+                       if (btv->type == BTTV_WINVIEW_601) { 
+                          int bits_out, loops, vol, data;
+
+                          /* 32 levels logarithmic */
+                          vol = 32 - ((v.volume>>11));
+                          /* units */
+                           bits_out = (PT2254_DBS_IN_2>>(vol%5));
+                          /* tens */
+                           bits_out |= (PT2254_DBS_IN_10>>(vol/5));
+                          bits_out |= PT2254_L_CHANEL | PT2254_R_CHANEL;
+                          data = btread(BT848_GPIO_DATA);
+                          data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
+                                     WINVIEW_PT2254_STROBE);
+                          for (loops = 17; loops >= 0 ; loops--) {
+                               if (bits_out & (1<<loops))
+                                  data |=  WINVIEW_PT2254_DATA;
+                               else
+                                  data &= ~WINVIEW_PT2254_DATA;
+                              btwrite(data, BT848_GPIO_DATA);
+                              udelay(5);
+                              data |= WINVIEW_PT2254_CLK;
+                              btwrite(data, BT848_GPIO_DATA);
+                              udelay(5);
+                              data &= ~WINVIEW_PT2254_CLK;
+                              btwrite(data, BT848_GPIO_DATA);
+                          }
+                          data |=  WINVIEW_PT2254_STROBE;
+                          data &= ~WINVIEW_PT2254_DATA;
+                          btwrite(data, BT848_GPIO_DATA);
+                          udelay(10);                     
+                          data &= ~WINVIEW_PT2254_STROBE;
+                          btwrite(data, BT848_GPIO_DATA);
+                       }
                        if (btv->have_msp3400) 
                        {
                                 i2c_control_device(&(btv->i2c),
@@ -3033,6 +3070,9 @@ static void idcard(int i)
                case BTTV_VHX:
                        strcpy(btv->video_dev.name,"BT848(Aimslab-VHX)");
                        break;
+               case BTTV_WINVIEW_601:
+                       strcpy(btv->video_dev.name,"BT848(Leadtek WinView 601)");
+                       break;     
        }
        printk("%s\n",btv->video_dev.name);
        audio(btv, AUDIO_MUTE);
index 479384783b486cea00dd9891a68388614761ca70..41024d7aad17a532a7e959bef4434aff394f3ab9 100644 (file)
@@ -210,6 +210,7 @@ struct bttv
 #define BTTV_VHX           0x0e
 #define BTTV_ZOLTRIX       0x0f
 #define BTTV_PIXVIEWPLAYTV 0x10
+#define BTTV_WINVIEW_601   0x11
 
 #define AUDIO_TUNER        0x00
 #define AUDIO_RADIO        0x01
@@ -260,4 +261,12 @@ struct bttv
 #define TEA6300_FA         0x04                /* fader control */
 #define TEA6300_SW         0x05                /* mute and source switch */
 
+#define PT2254_L_CHANEL 0x10
+#define PT2254_R_CHANEL 0x08
+#define PT2254_DBS_IN_2 0x400
+#define PT2254_DBS_IN_10 0x20000
+#define WINVIEW_PT2254_CLK  0x40
+#define WINVIEW_PT2254_DATA 0x20
+#define WINVIEW_PT2254_STROBE 0x80
+
 #endif
index 33f873e7d2dece26016b5edf51981b5abfc118b6..f73b1c44490e94041032004fc07dc1fbe5f2988a 100644 (file)
@@ -371,12 +371,12 @@ static int parport_SPP_supported(struct parport *pb)
         * copy. Some ports _do_ allow reads, so bypass the software
         * copy here.  In addition, some bits aren't writable. */
        r = inb (pb->base+CONTROL);
-       if ((r & 0x3f) == w) {
+       if ((r & 0xf) == w) {
                w = 0xe;
                parport_pc_write_control (pb, w);
                r = inb (pb->base+CONTROL);
                parport_pc_write_control (pb, 0xc);
-               if ((r & 0x3f) == w)
+               if ((r & 0xf) == w)
                        return PARPORT_MODE_PCSPP;
        }
 
index 69f8bb0d840648612dc581a300d49e6a5bb89836..bc4084f8611f3a2983a822279c87a2b0f13c98e5 100644 (file)
@@ -2,6 +2,9 @@
 
 /*
  *  Copyright (C) 1995-1997  Jan "Yenya" Kasprzak <kas@fi.muni.cz>
+ * 
+ *     5/25/1999 : Marcelo Tosatti <marcelo@conectiva.com.br>
+ *             fixed a deadlock in cosa_sppp_open 
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -598,6 +601,7 @@ static int cosa_sppp_open(struct device *d)
        if (chan->usage != 0) {
                printk(KERN_WARNING "%s: sppp_open called with usage count %d\n",
                        chan->name, chan->usage);
+               spin_unlock_irqrestore(&chan->cosa->lock, flags);
                return -EBUSY;
        }
        chan->setup_rx = sppp_setup_rx;
index d94e0efd6e6acf036a7c469b42db75fc71943f17..51af63aa4f2f7314b9468dc01532ad392a5acc25 100644 (file)
  * ftp's, which is significantly better than I get in DOS, so the overhead of
  * stopping and restarting the CU with each transmit is not prohibitive in
  * practice.
+ *
+ * Update by David Woodhouse 11/5/99:
+ *
+ * I've seen "CU wedged" messages in 16-bit mode, on the Alpha architecture.
+ * I assume that this is because 16-bit accesses are actually handled as two
+ * 8-bit accesses.
  */
+
+#ifdef __alpha__
+#define LOCKUP16 1
+#endif
+#ifndef LOCKUP16
+#define LOCKUP16 0
+#endif
   
 #include <linux/config.h>
 #include <linux/module.h>
@@ -297,7 +310,7 @@ static inline void clear_loopback(struct device *dev)
        outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config);
 }
 
-static inline short int SHADOW(short int addr)
+static inline unsigned short int SHADOW(short int addr)
 {
        addr &= 0x1f;
        if (addr > 0xf) addr += 0x3ff0;
@@ -400,7 +413,10 @@ static int eexp_close(struct device *dev)
        outb(0,ioaddr+SIGNAL_CA);
        free_irq(irq,dev);
        outb(i586_RST,ioaddr+EEPROM_Ctrl);
-       release_region(ioaddr,16);
+       release_region(ioaddr, EEXP_IO_EXTENT);
+       release_region(ioaddr+0x4000, 16);
+       release_region(ioaddr+0x8000, 16);
+       release_region(ioaddr+0xc000, 16);
 
        MOD_DEC_USE_COUNT;
        return 0;
@@ -887,7 +903,7 @@ static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
        struct net_local *lp = (struct net_local *)dev->priv;
        unsigned short ioaddr = dev->base_addr;
 
-       if (lp->width) {
+       if (LOCKUP16 || lp->width) {
                /* Stop the CU so that there is no chance that it
                   jumps off to a bogus address while we are writing the
                   pointer to the next transmit packet in 8-bit mode -- 
@@ -927,7 +943,7 @@ static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
        if (lp->tx_head != lp->tx_reap)
                dev->tbusy = 0;
 
-       if (lp->width) {
+       if (LOCKUP16 || lp->width) {
                /* Restart the CU so that the packet can actually
                   be transmitted. (Zoltan Szilagyi 10-12-96) */
                scb_command(dev, SCB_CUresume);
index 64f6c327e911199898977ef186b39307afdd744e..1a7831e83506f26f7cd55d62798cce846788fad6 100644 (file)
@@ -1,18 +1,24 @@
 mainmenu_option next_comment
 comment 'Infrared-port device drivers'
 
-dep_tristate 'IrTTY (uses serial driver)' CONFIG_IRTTY_SIR $CONFIG_IRDA
-if [ "$CONFIG_IRTTY_SIR" != "n" ]; then
-  comment '   Dongle support' 
-  bool '   Serial dongle support' CONFIG_DONGLE
-  if [ "$CONFIG_DONGLE" != "n" ]; then
-    dep_tristate '   ESI JetEye PC dongle' CONFIG_ESI_DONGLE $CONFIG_IRTTY_SIR
-    dep_tristate '   ACTiSYS IR-220L and IR220L+ dongle' CONFIG_ACTISYS_DONGLE $CONFIG_IRTTY_SIR
-    dep_tristate '   Tekram IrMate 210B dongle' CONFIG_TEKRAM_DONGLE $CONFIG_IRTTY_SIR
-    dep_tristate '   Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRTTY_SIR
-  fi
+comment 'SIR device drivers'
+dep_tristate 'IrTTY (uses Linux serial driver)' CONFIG_IRTTY_SIR $CONFIG_IRDA
+dep_tristate 'IrPORT (IrDA serial driver)' CONFIG_IRPORT_SIR $CONFIG_IRDA
+
+comment 'FIR device drivers'
+dep_tristate 'NSC PC87108' CONFIG_NSC_FIR  $CONFIG_IRDA
+dep_tristate 'Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
+dep_tristate 'Sharp UIRCC' CONFIG_SHARP_FIR $CONFIG_IRDA
+dep_tristate 'Toshiba Type-O IR Port' CONFIG_TOSHIBA_FIR $CONFIG_IRDA
+
+comment 'Dongle support' 
+bool 'Serial dongle support' CONFIG_DONGLE
+if [ "$CONFIG_DONGLE" != "n" ]; then
+  dep_tristate '   ESI JetEye PC dongle' CONFIG_ESI_DONGLE $CONFIG_IRDA
+  dep_tristate '   ACTiSYS IR-220L and IR220L+ dongle' CONFIG_ACTISYS_DONGLE $CONFIG_IRDA
+  dep_tristate '   Tekram IrMate 210B dongle' CONFIG_TEKRAM_DONGLE $CONFIG_IRDA
+  dep_tristate '   Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRDA
+  dep_tristate '   Parallax LiteLink dongle' CONFIG_LITELINK_DONGLE $CONFIG_IRDA
 fi
-dep_tristate '  NSC PC87108' CONFIG_NSC_FIR  $CONFIG_IRDA
-dep_tristate '  Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
-dep_tristate '  Sharp UIRCC' CONFIG_SHARP_FIR $CONFIG_IRDA
+
 endmenu
index 6a7920a6e1c56695e466ea104825cb5cc82d21ba..bd691dcae7fc0c830c8fd058257546edcd27d9f3 100644 (file)
@@ -20,6 +20,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_IRPORT_SIR),y)
+L_OBJS += irport.o
+else
+  ifeq ($(CONFIG_IRPORT_SIR),m)
+  M_OBJS += irport.o
+  endif
+endif
+
 ifeq ($(CONFIG_NSC_FIR),y)
 L_OBJS += pc87108.o
 else
@@ -44,6 +52,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_TOSHIBA_FIR),y)
+L_OBJS += toshoboe.o
+else
+  ifeq ($(CONFIG_TOSHIBA_FIR),m)
+  M_OBJS += toshoboe.o
+  endif
+endif
+
 ifeq ($(CONFIG_ESI_DONGLE),y)
 L_OBJS += esi.o
 else
@@ -76,6 +92,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_LITELINK_DONGLE),y)
+L_OBJS += litelink.o
+else
+  ifeq ($(CONFIG_LITELINK_DONGLE),m)
+  M_OBJS += litelink.o
+  endif
+endif
+
 include $(TOPDIR)/Rules.make
 
 clean:
index 46ce2badfb85d66119ce98b04386141683913097..11fde80062e4f08392671622696d31a33fbccc48 100644 (file)
@@ -1,16 +1,16 @@
 /*********************************************************************
  *                
  * Filename:      actisys.c
- * Version:       0.5
+ * Version:       0.8
  * Description:   Implementation for the ACTiSYS IR-220L and IR-220L+ 
  *                dongles
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Wed Oct 21 20:02:35 1998
- * Modified at:   Mon Apr 12 11:56:35 1999
+ * Modified at:   Mon May 10 15:12:54 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
 #include <net/irda/irda_device.h>
-#include <net/irda/irtty.h>
 #include <net/irda/dongle.h>
 
-static void actisys_reset( struct irda_device *dev, int unused);
-static void actisys_open( struct irda_device *idev, int type);
-static void actisys_close( struct irda_device *dev);
+static void actisys_reset(struct irda_device *dev, int unused);
+static void actisys_open(struct irda_device *idev, int type);
+static void actisys_close(struct irda_device *dev);
 static void actisys_change_speed( struct irda_device *dev, int baudrate);
-static void actisys_reset( struct irda_device *dev, int unused);
-static void actisys_init_qos( struct irda_device *idev, struct qos_info *qos);
+static void actisys_reset(struct irda_device *dev, int unused);
+static void actisys_init_qos(struct irda_device *idev, struct qos_info *qos);
 
 /* These are the baudrates supported */
 static int baud_rates[] = { 9600, 19200, 57600, 115200, 38400};
@@ -58,17 +57,37 @@ static struct dongle dongle = {
        actisys_init_qos,
 };
 
-__initfunc(void actisys_init(void))
+static struct dongle dongle_plus = {
+       ACTISYS_PLUS_DONGLE,
+       actisys_open,
+       actisys_close,
+       actisys_reset,
+       actisys_change_speed,
+       actisys_init_qos,
+};
+
+__initfunc(int actisys_init(void))
 {
-       irtty_register_dongle(&dongle);
+       int ret;
+
+       ret = irda_device_register_dongle(&dongle);
+       if (ret < 0)
+               return ret;
+       ret = irda_device_register_dongle(&dongle_plus);
+       if (ret < 0) {
+               irda_device_unregister_dongle(&dongle);
+               return ret;
+       }       
+       return 0;
 }
 
 void actisys_cleanup(void)
 {
-       irtty_unregister_dongle(&dongle);
+       irda_device_unregister_dongle(&dongle);
+       irda_device_unregister_dongle(&dongle_plus);
 }
 
-static void actisys_open( struct irda_device *idev, int type)
+static void actisys_open(struct irda_device *idev, int type)
 {
        strcat(idev->description, " <-> actisys");
 
@@ -78,8 +97,11 @@ static void actisys_open( struct irda_device *idev, int type)
        MOD_INC_USE_COUNT;
 }
 
-static void actisys_close( struct irda_device *dev)
+static void actisys_close(struct irda_device *idev)
 {
+       /* Power off dongle */
+       irda_device_set_dtr_rts(idev, FALSE, FALSE);
+
        MOD_DEC_USE_COUNT;
 }
 
@@ -90,25 +112,16 @@ static void actisys_close( struct irda_device *dev)
  *    To cycle through the available baud rates, pulse RTS low for a few
  *    ms.  
  */
-static void actisys_change_speed( struct irda_device *idev, int baudrate)
+static void actisys_change_speed(struct irda_device *idev, int baudrate)
 {
-        struct irtty_cb *self;
-        struct tty_struct *tty;
-        struct termios old_termios;
-       int cflag;
         int current_baudrate;
         int index = 0;
        
-       DEBUG( 4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
 
-       ASSERT( idev != NULL, return;);
-       ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
-       
-       self = (struct irtty_cb *) idev->priv;
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
        
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == IRTTY_MAGIC, return;);
-
        current_baudrate = idev->qos.baud_rate.value;
 
        /* Find the correct baudrate index for the currently used baudrate */
@@ -117,69 +130,34 @@ static void actisys_change_speed( struct irda_device *idev, int baudrate)
 
         DEBUG( 4, __FUNCTION__ "(), index=%d\n", index);
 
-       if ( !self->tty)
-               return;
-
-       tty = self->tty;
-
        /* Cycle through avaiable baudrates until we reach the correct one */
-        while ( current_baudrate != baudrate) {        
-                DEBUG( 4, __FUNCTION__ "(), current baudrate = %d\n",
-                       baud_rates[index]);
+        while (current_baudrate != baudrate) { 
+                DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n",
+                     baud_rates[index]);
                
                /* Set DTR, clear RTS */
-               irtty_set_dtr_rts(tty, TRUE, FALSE);
+               irda_device_set_dtr_rts(idev, TRUE, FALSE);
                
                /* Wait at a few ms */
                current->state = TASK_INTERRUPTIBLE;
                schedule_timeout(2);
 
                /* Set DTR, Set RTS */
-               irtty_set_dtr_rts(tty, TRUE, TRUE);
+               irda_device_set_dtr_rts(idev, TRUE, TRUE);
                
                /* Wait at a few ms again */
                current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout( 2);
+               schedule_timeout(2);
 
                 /* Go to next baudrate */
-               if ( idev->io.dongle_id == ACTISYS_DONGLE)
+               if (idev->io.dongle_id == ACTISYS_DONGLE)
                         index = (index+1) % 4; /* IR-220L */
                else
                         index = (index+1) % 5; /* IR-220L+ */
 
                 current_baudrate = baud_rates[index];
         }
-       DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", 
-             baud_rates[index]);
-
-       /* Now change the speed of the serial port */
-       old_termios = *(tty->termios);
-       cflag = tty->termios->c_cflag;
-
-       cflag &= ~CBAUD;
-
-        switch ( baudrate) {
-        case 9600:
-        default:
-               cflag |= B9600;
-               break;
-       case 19200:
-               cflag |= B19200;
-               break;
-       case 38400:
-               cflag |= B38400;
-               break;
-       case 57600:
-               cflag |= B57600;
-               break;
-       case 115200:
-               cflag |= B115200;
-               break;
-       }
-
-       /* Change speed of serial port */
-       tty->termios->c_cflag = cflag;
-       tty->driver.set_termios( tty, &old_termios);
+       DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n",baud_rates[index]);
 }
 
 /*
@@ -191,32 +169,20 @@ static void actisys_change_speed( struct irda_device *idev, int baudrate)
  *     1. Clear DTR for a few ms.
  *
  */
-static void actisys_reset( struct irda_device *idev, int unused)
+static void actisys_reset(struct irda_device *idev, int unused)
 {
-       struct irtty_cb *self;
-        struct tty_struct *tty;
-
-       ASSERT( idev != NULL, return;);
-       ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
-       
-       self = (struct irtty_cb *) idev->priv;
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
        
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == IRTTY_MAGIC, return;);
-
-       tty = self->tty;
-       if ( !tty)
-               return;
-
        /* Clear DTR */
-       irtty_set_dtr_rts(tty, FALSE, TRUE);
+       irda_device_set_dtr_rts(idev, FALSE, TRUE);
 
        /* Sleep 10-20 ms*/
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout(2);
        
        /* Go back to normal mode */
-       irtty_set_dtr_rts(tty, TRUE, TRUE);
+       irda_device_set_dtr_rts(idev, TRUE, TRUE);
        
        idev->qos.baud_rate.value = 9600;
 }
@@ -227,12 +193,12 @@ static void actisys_reset( struct irda_device *idev, int unused)
  *    Initialize QoS capabilities
  *
  */
-static void actisys_init_qos( struct irda_device *idev, struct qos_info *qos)
+static void actisys_init_qos(struct irda_device *idev, struct qos_info *qos)
 {
        qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
 
        /* Remove support for 38400 if this is not a 220L+ dongle */
-       if ( idev->io.dongle_id == ACTISYS_DONGLE)
+       if (idev->io.dongle_id == ACTISYS_DONGLE)
                qos->baud_rate.bits &= ~IR_38400;
        
        qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */
@@ -251,8 +217,7 @@ MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver");
  */
 int init_module(void)
 {
-       actisys_init();
-       return(0);
+       return actisys_init();
 }
 
 /*
index 5395d2829688943e9797fe29c3092d69e83b8c85..b12885846bc74870a99673eabeaae4148005721b 100644 (file)
@@ -1,17 +1,17 @@
 /*********************************************************************
  *                
  * Filename:      esi.c
- * Version:       1.2
+ * Version:       1.4
  * Description:   Driver for the Extended Systems JetEye PC dongle
  * Status:        Experimental.
  * Author:        Thomas Davis, <ratbert@radiks.net>
  * Created at:    Sat Feb 21 18:54:38 1998
- * Modified at:   Mon Apr 12 11:55:30 1999
+ * Modified at:   Mon May 10 15:13:12 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:      esi.c
  *
+ *     Copyright (c) 1998-1999, Dag Brattli, <dagb@cs.uit.no>
  *     Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>,
- *     Copyright (c) 1998, Dag Brattli,  <dagb@cs.uit.no>
  *     All Rights Reserved.
  *
  *     This program is free software; you can redistribute it and/or
 #include <net/irda/irtty.h>
 #include <net/irda/dongle.h>
 
-static void esi_open( struct irda_device *idev, int type);
-static void esi_close( struct irda_device *driver);
-static void esi_change_speed( struct irda_device *idev, int baud);
-static void esi_reset( struct irda_device *idev, int unused);
-static void esi_qos_init( struct irda_device *idev, struct qos_info *qos);
+static void esi_open(struct irda_device *idev, int type);
+static void esi_close(struct irda_device *driver);
+static void esi_change_speed(struct irda_device *idev, int baud);
+static void esi_reset(struct irda_device *idev, int unused);
+static void esi_qos_init(struct irda_device *idev, struct qos_info *qos);
 
 static struct dongle dongle = {
        ESI_DONGLE,
@@ -58,17 +58,17 @@ static struct dongle dongle = {
 
 __initfunc(int esi_init(void))
 {
-       return irtty_register_dongle(&dongle);
+       return irda_device_register_dongle(&dongle);
 }
 
 void esi_cleanup(void)
 {
-       irtty_unregister_dongle( &dongle);
+       irda_device_unregister_dongle(&dongle);
 }
 
-static void esi_open( struct irda_device *idev, int type)
+static void esi_open(struct irda_device *idev, int type)
 {
-       strcat( idev->description, " <-> esi");
+       strcat(idev->description, " <-> esi");
 
        idev->io.dongle_id = type;
        idev->flags |= IFF_DONGLE;
@@ -76,8 +76,11 @@ static void esi_open( struct irda_device *idev, int type)
        MOD_INC_USE_COUNT;
 }
 
-static void esi_close( struct irda_device *driver)
-{
+static void esi_close(struct irda_device *idev)
+{              
+       /* Power off dongle */
+       irda_device_set_dtr_rts(idev, FALSE, FALSE);
+
        MOD_DEC_USE_COUNT;
 }
 
@@ -87,54 +90,30 @@ static void esi_close( struct irda_device *driver)
  *    Set the speed for the Extended Systems JetEye PC ESI-9680 type dongle
  *
  */
-static void esi_change_speed( struct irda_device *idev, int baud)
+static void esi_change_speed(struct irda_device *idev, int baud)
 {
-       struct irtty_cb *self;
-       struct tty_struct *tty;
        int dtr, rts;
-        struct termios old_termios;
-       int cflag;
-       
-       ASSERT( idev != NULL, return;);
-       ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
        
-       self = (struct irtty_cb *) idev->priv;
-       
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == IRTTY_MAGIC, return;);
-
-       if ( !self->tty)
-               return;
-
-       tty = self->tty;
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
        
-       old_termios = *(tty->termios);
-       cflag = tty->termios->c_cflag;
-
-       cflag &= ~CBAUD;
-
        switch (baud) {
        case 19200:
-               cflag |= B19200;
                dtr = TRUE;
                rts = FALSE;
                break;
        case 115200:
-               cflag |= B115200;
                dtr = rts = TRUE;
                break;
        case 9600:
        default:
-               cflag |= B9600;
                dtr = FALSE;
                rts = TRUE;
                break;
        }
-       /* Change speed of serial driver */
-       tty->termios->c_cflag = cflag;
-       tty->driver.set_termios(tty, &old_termios);
 
-       irtty_set_dtr_rts(tty, dtr, rts);
+       /* Change speed of dongle */
+       irda_device_set_dtr_rts(idev, dtr, rts);
 }
 
 static void esi_reset( struct irda_device *idev, int unused)
@@ -148,14 +127,17 @@ static void esi_reset( struct irda_device *idev, int unused)
  *    Init QoS capabilities for the dongle
  *
  */
-static void esi_qos_init( struct irda_device *idev, struct qos_info *qos)
+static void esi_qos_init(struct irda_device *idev, struct qos_info *qos)
 {
        qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200;
        qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */
 }
 
 #ifdef MODULE
-               
+
+MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
+MODULE_DESCRIPTION("Extended Systems JetEye PC dongle driver");
+
 /*
  * Function init_module (void)
  *
index 128b32a23e22d209800394063c55cb60f9423fcb..3b06f3838ad7dd925ca47aa42cda21e21d6700c7 100644 (file)
@@ -1,12 +1,12 @@
 /*********************************************************************
  *                
  * Filename:      girbil.c
- * Version:       1.0
+ * Version:       1.1
  * Description:   Implementation for the Greenwich GIrBIL dongle
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Feb  6 21:02:33 1999
- * Modified at:   Sat Apr 10 19:53:12 1999
+ * Modified at:   Mon May 10 16:01:33 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -80,19 +80,19 @@ static struct dongle dongle = {
        girbil_init_qos,
 };
 
-__initfunc(void girbil_init(void))
+__initfunc(int girbil_init(void))
 {
-       irtty_register_dongle(&dongle);
+       return irda_device_register_dongle(&dongle);
 }
 
 void girbil_cleanup(void)
 {
-       irtty_unregister_dongle(&dongle);
+       irda_device_unregister_dongle(&dongle);
 }
 
 static void girbil_open(struct irda_device *idev, int type)
 {
-       strcat( idev->description, " <-> girbil");
+       strcat(idev->description, " <-> girbil");
 
        idev->io.dongle_id = type;
        idev->flags |= IFF_DONGLE;
@@ -100,8 +100,11 @@ static void girbil_open(struct irda_device *idev, int type)
        MOD_INC_USE_COUNT;
 }
 
-static void girbil_close(struct irda_device *dev)
+static void girbil_close(struct irda_device *idev)
 {
+       /* Power off dongle */
+       irda_device_set_dtr_rts(idev, FALSE, FALSE);
+
        MOD_DEC_USE_COUNT;
 }
 
@@ -114,71 +117,42 @@ static void girbil_close(struct irda_device *dev)
  */
 static void girbil_change_speed(struct irda_device *idev, int speed)
 {
-       struct irtty_cb *self;
-       struct tty_struct *tty;
-       struct termios old_termios;
-       int cflag;
        __u8 control[2];
        
        ASSERT(idev != NULL, return;);
        ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
        
-       self = (struct irtty_cb *) idev->priv;
-       
-       ASSERT(self != NULL, return;); 
-       ASSERT(self->magic == IRTTY_MAGIC, return;);
-       
-       if (!self->tty)
-               return;
-
-       tty = self->tty;
-       
-       old_termios = *(tty->termios);
-       cflag = tty->termios->c_cflag;
-
-       cflag &= ~CBAUD;
-
        switch (speed) {
        case 9600:
        default:
-               cflag |= B9600;
                control[0] = GIRBIL_9600;
                break;
        case 19200:
-               cflag |= B19200;
                control[0] = GIRBIL_19200;
                break;
        case 34800:
-               cflag |= B38400;
                control[0] = GIRBIL_38400;
                break;
        case 57600:
-               cflag |= B57600;
                control[0] = GIRBIL_57600;
                break;
        case 115200:
-               cflag |= B115200;
                control[0] = GIRBIL_115200;
                break;
        }
        control[1] = GIRBIL_LOAD;
 
        /* Set DTR and Clear RTS to enter command mode */
-       irtty_set_dtr_rts(tty, FALSE, TRUE);
+       irda_device_set_dtr_rts(idev, FALSE, TRUE);
 
        /* Write control bytes */
-       if (tty->driver.write)
-               tty->driver.write(self->tty, 0, control, 2);
+       irda_device_raw_write(idev, control, 2);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout(2);
        
        /* Go back to normal mode */
-       irtty_set_dtr_rts(tty, TRUE, TRUE);
-
-       /* Now change the speed of the serial port */
-       tty->termios->c_cflag = cflag;
-       tty->driver.set_termios(tty, &old_termios);     
+       irda_device_set_dtr_rts(idev, TRUE, TRUE);
 }
 
 /*
@@ -193,44 +167,32 @@ static void girbil_change_speed(struct irda_device *idev, int speed)
  */
 void girbil_reset(struct irda_device *idev, int unused)
 {
-       struct irtty_cb *self;
-       struct tty_struct *tty;
        __u8 control = GIRBIL_TXEN | GIRBIL_RXEN;
 
        ASSERT(idev != NULL, return;);
        ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
        
-       self = (struct irtty_cb *) idev->priv;
-       
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRTTY_MAGIC, return;);
-
-       tty = self->tty;
-       if (!tty)
-               return;
-
        /* Reset dongle */
-       irtty_set_dtr_rts(tty, TRUE, FALSE);
+       irda_device_set_dtr_rts(idev, TRUE, FALSE);
 
        /* Sleep at least 5 ms */
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout(2);
        
        /* Set DTR and clear RTS to enter command mode */
-       irtty_set_dtr_rts(tty, FALSE, TRUE);
+       irda_device_set_dtr_rts(idev, FALSE, TRUE);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout(2);
 
        /* Write control byte */
-       if (tty->driver.write)
-               tty->driver.write(self->tty, 0, &control, 1);
+       irda_device_raw_write(idev, &control, 1);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout(2);
 
        /* Go back to normal mode */
-       irtty_set_dtr_rts(tty, TRUE, TRUE);
+       irda_device_set_dtr_rts(idev, TRUE, TRUE);
 }
 
 /*
@@ -258,8 +220,7 @@ MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver");
  */
 int init_module(void)
 {
-       girbil_init();
-       return(0);
+       return girbil_init();
 }
 
 /*
index 5ea6dba738a0c0cdbef075191914c9cf5ad4d456..7c8864f5d79ef04cfb9d2525445b5e4545ca6bb3 100644 (file)
 
 #define IO_EXTENT 8
 
-/* static unsigned int io[]  = { 0x3e8, ~0, ~0, ~0 }; */
-/* static unsigned int irq[] = { 11, 0, 0, 0 }; */
+/* 
+ * Currently you'll need to set these values using insmod like this:
+ * insmod irport io=0x3e8 irq=11
+ */
+static unsigned int io[]  = { ~0, ~0, ~0, ~0 };
+static unsigned int irq[] = { 0, 0, 0, 0 };
+
+static unsigned int qos_mtt_bits = 0x03;
+
+static struct irda_device *dev_self[] = { NULL, NULL, NULL, NULL};
+static char *driver_name = "irport";
+
+static int irport_open(int i, unsigned int iobase, unsigned int irq);
+static int irport_close(struct irda_device *idev);
 
 static void irport_write_wakeup(struct irda_device *idev);
 static int  irport_write(int iobase, int fifo_size, __u8 *buf, int len);
 static void irport_receive(struct irda_device *idev);
 
+static int  irport_net_init(struct device *dev);
+static int  irport_net_open(struct device *dev);
+static int  irport_net_close(struct device *dev);
+static void irport_wait_until_sent(struct irda_device *idev);
+static int  irport_is_receiving(struct irda_device *idev);
+static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts);
+static int  irport_raw_write(struct irda_device *idev, __u8 *buf, int len);
+
 __initfunc(int irport_init(void))
 {
-/*     int i; */
-
-/*     for ( i=0; (io[i] < 2000) && (i < 4); i++) { */
-/*             int ioaddr = io[i]; */
-/*             if (check_region(ioaddr, IO_EXTENT)) */
-/*                     continue; */
-/*             if (irport_open( i, io[i], io2[i], irq[i], dma[i]) == 0) */
-/*                     return 0; */
-/*     } */
-/*     return -ENODEV; */
-       return 0;
+       int i;
+
+       for (i=0; (io[i] < 2000) && (i < 4); i++) {
+               int ioaddr = io[i];
+               if (check_region(ioaddr, IO_EXTENT))
+                       continue;
+               if (irport_open(i, io[i], irq[i]) == 0)
+                       return 0;
+       }
+       /* 
+        * Maybe something failed, but we can still be usable for FIR drivers 
+        */
+       return 0;
 }
 
 /*
- * Function pc87108_cleanup ()
+ * Function irport_cleanup ()
  *
- *    Close all configured chips
+ *    Close all configured ports
  *
  */
 #ifdef MODULE
 static void irport_cleanup(void)
 {
-/*     int i; */
+       int i;
 
         DEBUG( 4, __FUNCTION__ "()\n");
 
-       /* for ( i=0; i < 4; i++) { */
-/*             if ( dev_self[i]) */
-/*                     irport_close( &(dev_self[i]->idev)); */
-/*     } */
+       for (i=0; i < 4; i++) {
+               if (dev_self[i])
+                       irport_close(dev_self[i]);
+       }
 }
 #endif /* MODULE */
 
-/*
- * Function irport_open (void)
- *
- *    Start IO port 
- *
- */
-int irport_open(int iobase)
+static int irport_open(int i, unsigned int iobase, unsigned int irq)
 {
-       DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
+       struct irda_device *idev;
+       int ret;
+
+       DEBUG( 0, __FUNCTION__ "()\n");
+
+/*     if (irport_probe(iobase, irq) == -1) */
+/*             return -1; */
+
+       /*
+        *  Allocate new instance of the driver
+        */
+       idev = kmalloc(sizeof(struct irda_device), GFP_KERNEL);
+       if (idev == NULL) {
+               printk( KERN_ERR "IrDA: Can't allocate memory for "
+                       "IrDA control block!\n");
+               return -ENOMEM;
+       }
+       memset(idev, 0, sizeof(struct irda_device));
+   
+       /* Need to store self somewhere */
+       dev_self[i] = idev;
+
+       /* Initialize IO */
+       idev->io.iobase2   = iobase;
+        idev->io.irq2      = irq;
+        idev->io.io_ext    = IO_EXTENT;
+        idev->io.fifo_size = 16;
+
+       /* Lock the port that we need */
+       ret = check_region(idev->io.iobase2, idev->io.io_ext);
+       if (ret < 0) { 
+               DEBUG( 0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+                      idev->io.iobase2);
+               /* w83977af_cleanup( self->idev);  */
+               return -ENODEV;
+       }
+       request_region(idev->io.iobase2, idev->io.io_ext, idev->name);
+
+       /* Initialize QoS for this device */
+       irda_init_max_qos_capabilies(&idev->qos);
+       
+       idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+               IR_115200;
+
+       idev->qos.min_turn_time.bits = qos_mtt_bits;
+       irda_qos_bits_to_value(&idev->qos);
+       
+       idev->flags = IFF_SIR|IFF_PIO;
+
+       /* Specify which buffer allocation policy we need */
+       idev->rx_buff.flags = GFP_KERNEL;
+       idev->tx_buff.flags = GFP_KERNEL;
+
+       idev->rx_buff.truesize = 4000; 
+       idev->tx_buff.truesize = 4000;
+       
+       /* Initialize callbacks */
+       idev->change_speed    = irport_change_speed;
+       idev->wait_until_sent = irport_wait_until_sent;
+        idev->is_receiving    = irport_is_receiving;
+       idev->set_dtr_rts     = irport_set_dtr_rts;
+       idev->raw_write       = irport_raw_write;
+
+       /* Override the network functions we need to use */
+       idev->netdev.init            = irport_net_init;
+       idev->netdev.hard_start_xmit = irport_hard_xmit;
+       idev->netdev.open            = irport_net_open;
+       idev->netdev.stop            = irport_net_close;
+
+       /* Open the IrDA device */
+       irda_device_open(idev, driver_name, NULL);
+       
+       return 0;
+}
+
+static int irport_close(struct irda_device *idev)
+{
+       DEBUG(0, __FUNCTION__ "()\n");
+
+       ASSERT(idev != NULL, return -1;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+       /* Release the PORT that this driver is using */
+       DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", 
+             idev->io.iobase2);
+       release_region(idev->io.iobase2, idev->io.io_ext);
+
+       irda_device_close(idev);
+
+       kfree(idev);
+
+       return 0;
+}
 
+void irport_start(int iobase)
+{
        /* Initialize UART */
        outb(UART_LCR_WLEN8, iobase+UART_LCR);  /* Reset DLAB */
        outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
@@ -123,24 +233,29 @@ int irport_open(int iobase)
        /* Turn on interrups */
        outb((UART_IER_RLSI | UART_IER_RDI), iobase+UART_IER);
 
-       return 0;
+}
+
+void irport_stop(int iobase)
+{
+       /* Reset UART */
+       outb(0, iobase+UART_MCR);
+       
+       /* Turn off interrupts */
+       outb(0, iobase+UART_IER);
 }
 
 /*
- * Function irport_cleanup ()
+ * Function irport_probe (void)
  *
- *    Stop IO port
+ *    Start IO port 
  *
  */
-void irport_close(int iobase) 
+int irport_probe(int iobase)
 {
-       DEBUG(4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
 
-       /* Reset UART */
-       outb(0, iobase+UART_MCR);
 
-       /* Turn off interrupts */
-       outb(0, iobase+UART_IER);
+       return 0;
 }
 
 /*
@@ -149,14 +264,23 @@ void irport_close(int iobase)
  *    Set speed of port to specified baudrate
  *
  */
-void irport_change_speed( int iobase, int speed) 
+void irport_change_speed(struct irda_device *idev, int speed)
 {
+       int iobase; 
        int fcr;    /* FIFO control reg */
        int lcr;    /* Line control reg */
        int divisor;
 
        DEBUG( 0, __FUNCTION__ "(), Setting speed to: %d\n", speed);
 
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+       iobase = idev->io.iobase2;
+       
+       /* Update accounting for new speed */
+       idev->io.baudrate = speed;
+
        /* Turn off interrupts */
        outb(0, iobase+UART_IER); 
 
@@ -373,8 +497,145 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        idev->netdev.interrupt = 0;
 }
 
+static int irport_net_init(struct device *dev)
+{
+       /* Set up to be a normal IrDA network device driver */
+       irda_device_setup(dev);
+
+       /* Insert overrides below this line! */
+
+       return 0;
+}
+
+/*
+ * Function irport_net_open (dev)
+ *
+ *    
+ *
+ */
+static int irport_net_open(struct device *dev)
+{
+       struct irda_device *idev;
+       int iobase;
+
+       ASSERT(dev != NULL, return -1;);
+       idev = (struct irda_device *) dev->priv;
+
+       iobase = idev->io.iobase2;
+
+       if (request_irq(idev->io.irq2, irport_interrupt, 0, idev->name, 
+                       (void *) idev)) {
+               return -EAGAIN;
+       }
+
+       /* Ready to play! */
+       dev->tbusy = 0;
+       dev->interrupt = 0;
+       dev->start = 1;
+
+       MOD_INC_USE_COUNT;
+
+       irport_start(iobase);
+
+       return 0;
+}
+
+/*
+ * Function irport_net_close (idev)
+ *
+ *    
+ *
+ */
+static int irport_net_close(struct device *dev)
+{
+       struct irda_device *idev;
+       int iobase;
+
+       ASSERT(dev != NULL, return -1;);
+       idev = (struct irda_device *) dev->priv;
+
+       DEBUG(4, __FUNCTION__ "()\n");
+
+       iobase = idev->io.iobase2;
+
+       irport_stop(iobase);
+
+       /* Stop device */
+       dev->tbusy = 1;
+       dev->start = 0;
+
+       free_irq(idev->io.irq2, idev);
+
+       MOD_DEC_USE_COUNT;
+
+       return 0;
+}
+
+static void irport_wait_until_sent(struct irda_device *idev)
+{
+       current->state = TASK_INTERRUPTIBLE;
+       schedule_timeout(60*HZ/1000);
+}
+
+static int irport_is_receiving(struct irda_device *idev)
+{
+       return (idev->rx_buff.state != OUTSIDE_FRAME);
+}
+
+/*
+ * Function irtty_set_dtr_rts (tty, dtr, rts)
+ *
+ *    This function can be used by dongles etc. to set or reset the status
+ *    of the dtr and rts lines
+ */
+static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts)
+{
+       int iobase;
+
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+       iobase = idev->io.iobase2;
+
+       if (dtr)
+               dtr = UART_MCR_DTR;
+       if (rts)
+               rts = UART_MCR_RTS;
+
+       outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR);
+}
+
+static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len)
+{
+       int iobase;
+       int actual = 0;
+
+       ASSERT(idev != NULL, return -1;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+       iobase = idev->io.iobase2;
+
+       /* Tx FIFO should be empty! */
+       if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
+               DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
+               return -1;
+       }
+        
+       /* Fill FIFO with current frame */
+       while (actual < len) {
+               /* Transmit next byte */
+               outb(buf[actual], iobase+UART_TX);
+               actual++;
+       }
+
+       return actual;
+}
+
 #ifdef MODULE
 
+MODULE_PARM(io, "1-4i");
+MODULE_PARM(irq, "1-4i");
+
 /*
  * Function cleanup_module (void)
  *
@@ -393,11 +654,7 @@ void cleanup_module(void)
  */
 int init_module(void)
 {
-       if (irport_init() < 0) {
-               cleanup_module();
-               return 1;
-       }
-       return(0);
+       return irport_init();
 }
 
 #endif /* MODULE */
index cc7ab91a4c498c5016ac2accec3c6acd02774e3b..ad8d2dc0ef10483589e733ac54afa96033a54c02 100644 (file)
@@ -6,12 +6,12 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:18:38 1997
- * Modified at:   Thu Apr 22 09:20:24 1999
+ * Modified at:   Mon May 10 15:45:50 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
 #include <net/irda/irlap.h>
 #include <net/irda/timer.h>
 #include <net/irda/irda_device.h>
-#include <linux/kmod.h>
 
 static hashbin_t *irtty = NULL;
-static hashbin_t *dongles = NULL;
 
 static struct tty_ldisc irda_ldisc;
 
-static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev);
+static int qos_mtt_bits = 0x03;      /* 5 ms or more */
+
+static int  irtty_hard_xmit(struct sk_buff *skb, struct device *dev);
 static void irtty_wait_until_sent(struct irda_device *driver);
-static int irtty_is_receiving(struct irda_device *idev);
-static int irtty_net_init(struct device *dev);
-static int irtty_net_open(struct device *dev);
-static int irtty_net_close(struct device *dev);
+static int  irtty_is_receiving(struct irda_device *idev);
+static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts);
+static int  irtty_raw_write(struct irda_device *idev, __u8 *buf, int len);
+static int  irtty_net_init(struct device *dev);
+static int  irtty_net_open(struct device *dev);
+static int  irtty_net_close(struct device *dev);
 
 static int  irtty_open(struct tty_struct *tty);
 static void irtty_close(struct tty_struct *tty);
@@ -73,13 +75,6 @@ __initfunc(int irtty_init(void))
                return -ENOMEM;
        }
 
-       dongles = hashbin_new(HB_LOCAL);
-       if (dongles == NULL) {
-               printk(KERN_WARNING 
-                      "IrDA: Can't allocate dongles hashbin!\n");
-               return -ENOMEM;
-       }
-
        /* Fill in our line protocol discipline, and register it */
        memset(&irda_ldisc, 0, sizeof( irda_ldisc));
 
@@ -132,7 +127,6 @@ static void irtty_cleanup(void)
         *  function to hashbin_destroy().
         */
        hashbin_delete(irtty, NULL);
-       hashbin_delete(dongles, NULL);
 }
 #endif /* MODULE */
 
@@ -201,7 +195,7 @@ static int irtty_open(struct tty_struct *tty)
        /* The only value we must override it the baudrate */
        self->idev.qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
                IR_115200;
-       self->idev.qos.min_turn_time.bits = 0x0f;
+       self->idev.qos.min_turn_time.bits = qos_mtt_bits;
        self->idev.flags = IFF_SIR | IFF_PIO;
        irda_qos_bits_to_value(&self->idev.qos);
 
@@ -216,7 +210,8 @@ static int irtty_open(struct tty_struct *tty)
        /* Initialize callbacks */
        self->idev.change_speed    = irtty_change_speed;
        self->idev.is_receiving    = irtty_is_receiving;
-       /* self->idev.is_tbusy        = irtty_is_tbusy; */
+       self->idev.set_dtr_rts     = irtty_set_dtr_rts;
+       self->idev.raw_write       = irtty_raw_write;
        self->idev.wait_until_sent = irtty_wait_until_sent;
 
        /* Override the network functions we need to use */
@@ -248,10 +243,6 @@ static void irtty_close(struct tty_struct *tty)
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRTTY_MAGIC, return;);
 
-       /* We are not using any dongle anymore! */
-       if (self->dongle_q)
-               self->dongle_q->dongle->close(&self->idev);
-
        /* Remove driver */
        irda_device_close(&self->idev);
 
@@ -358,68 +349,6 @@ static void irtty_change_speed(struct irda_device *idev, int baud)
        self->tty->driver.set_termios(self->tty, &old_termios);
 }
 
-/*
- * Function irtty_init_dongle (self, type)
- *
- *    Initialize attached dongle. Warning, must be called with a process
- *    context!
- */
-static void irtty_init_dongle(struct irtty_cb *self, int type)
-{
-       struct dongle_q *node;
-
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRTTY_MAGIC, return;);
-
-#ifdef CONFIG_KMOD
-       /* Try to load the module needed */
-       switch( type) {
-       case ESI_DONGLE:
-               MESSAGE("IrDA: Trying to initialize ESI dongle!\n");
-               request_module("esi");
-               break;
-       case TEKRAM_DONGLE:
-               MESSAGE("IrDA: Trying to initialize Tekram dongle!\n");
-               request_module("tekram");
-               break;
-       case ACTISYS_DONGLE:     /* FALLTHROUGH */
-       case ACTISYS_PLUS_DONGLE:
-               MESSAGE("IrDA: Trying to initialize ACTiSYS dongle!\n");
-               request_module("actisys");
-               break;
-       case GIRBIL_DONGLE:
-               MESSAGE("IrDA: Trying to initialize GIrBIL dongle!\n");
-               request_module("girbil");
-               break;
-       default:
-               ERROR("Unknown dongle type!\n");
-               return;
-       }
-#endif /* CONFIG_KMOD */
-
-       node = hashbin_find(dongles, type, NULL);
-       if ( !node) {
-               ERROR("Unable to find requested dongle\n");
-               return;
-       }
-       self->dongle_q = node;
-
-       /* Use this change speed function instead of the default */
-       self->idev.change_speed = node->dongle->change_speed;
-
-       /*
-        * Now initialize the dongle!
-        */
-       node->dongle->open(&self->idev, type);
-       node->dongle->qos_init(&self->idev, &self->idev.qos);
-       
-       /* Reset dongle */
-       node->dongle->reset(&self->idev, 0);
-
-       /* Set to default baudrate */
-       node->dongle->change_speed(&self->idev, 9600);
-}
-
 /*
  * Function irtty_ioctl (tty, file, cmd, arg)
  *
@@ -452,7 +381,7 @@ static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
                break;
        case IRTTY_IOCTDONGLE:
                /* Initialize dongle */
-               irtty_init_dongle(self, (int) arg);
+               irda_device_init_dongle(&self->idev, (int) arg);
                break;
        default:
                return -ENOIOCTLCMD;
@@ -645,54 +574,23 @@ static void irtty_wait_until_sent(struct irda_device *idev)
        tty_wait_until_sent(self->tty, 0);
 }
 
-int irtty_register_dongle(struct dongle *dongle)
-{
-       struct dongle_q *new;
-       
-       /* Check if this compressor has been registred before */
-       if ( hashbin_find ( dongles, dongle->type, NULL)) {
-               DEBUG( 0, __FUNCTION__ "(), Dongle already registered\n");
-                return 0;
-        }
-       
-       /* Make new IrDA dongle */
-        new = (struct dongle_q *) kmalloc(sizeof(struct dongle_q), GFP_KERNEL);
-        if (new == NULL)
-                return -1;
-               
-       memset(new, 0, sizeof( struct dongle_q));
-        new->dongle = dongle;
-
-       /* Insert IrDA dongle into hashbin */
-       hashbin_insert(dongles, (QUEUE *) new, dongle->type, NULL);
-       
-        return 0;
-}
-
-void irtty_unregister_dongle(struct dongle *dongle)
-{
-       struct dongle_q *node;
-
-       node = hashbin_remove(dongles, dongle->type, NULL);
-       if (!node) {
-               ERROR(__FUNCTION__ "(), dongle not found!\n");
-               return;
-       }
-       kfree(node);
-}
-
-
 /*
  * Function irtty_set_dtr_rts (tty, dtr, rts)
  *
  *    This function can be used by dongles etc. to set or reset the status
  *    of the dtr and rts lines
  */
-void irtty_set_dtr_rts(struct tty_struct *tty, int dtr, int rts)
+static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts)
 {
+       struct tty_struct *tty;
+       struct irtty_cb *self;
        mm_segment_t fs;
        int arg = 0;
 
+       self = (struct irtty_cb *) idev->priv;
+
+       tty = self->tty;
+
 #ifdef TIOCM_OUT2 /* Not defined for ARM */
        arg = TIOCM_OUT2;
 #endif
@@ -718,6 +616,25 @@ void irtty_set_dtr_rts(struct tty_struct *tty, int dtr, int rts)
        set_fs(fs);
 }
 
+static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len)
+{
+       struct irtty_cb *self;
+       int actual = 0;
+
+       ASSERT(idev != NULL, return 0;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+       
+       self = (struct irtty_cb *) idev->priv;
+
+       ASSERT(self != NULL, return 0;);
+       ASSERT(self->magic == IRTTY_MAGIC, return 0;);
+
+       if (self->tty->driver.write)
+               actual = self->tty->driver.write(self->tty, 0, buf, len);
+
+       return actual;
+}
+
 static int irtty_net_init(struct device *dev)
 {
        /* Set up to be a normal IrDA network device driver */
@@ -760,6 +677,8 @@ static int irtty_net_close(struct device *dev)
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("IrDA TTY device driver");
 
+MODULE_PARM(qos_mtt_bits, "i");
+
 /*
  * Function init_module (void)
  *
diff --git a/drivers/net/irda/litelink.c b/drivers/net/irda/litelink.c
new file mode 100644 (file)
index 0000000..e27bab1
--- /dev/null
@@ -0,0 +1,209 @@
+/*********************************************************************
+ *                
+ * Filename:      litelink.c
+ * Version:       1.0
+ * Description:   Driver for the Parallax LiteLink dongle
+ * Status:        Stable
+ * Author:        Dag Brattli <dagb@cs.uit.no>
+ * Created at:    Fri May  7 12:50:33 1999
+ * Modified at:   Mon May 10 15:12:18 1999
+ * Modified by:   Dag Brattli <dagb@cs.uit.no>
+ * 
+ *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
+ *     
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version.
+ * 
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License 
+ *     along with this program; if not, write to the Free Software 
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ *     MA 02111-1307 USA
+ *     
+ ********************************************************************/
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <asm/ioctls.h>
+#include <asm/uaccess.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/irda_device.h>
+#include <net/irda/dongle.h>
+
+static void litelink_reset(struct irda_device *dev, int unused);
+static void litelink_open(struct irda_device *idev, int type);
+static void litelink_close(struct irda_device *dev);
+static void litelink_change_speed( struct irda_device *dev, int baudrate);
+static void litelink_reset(struct irda_device *dev, int unused);
+static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos);
+
+/* These are the baudrates supported */
+static int baud_rates[] = { 115200, 57600, 38400, 19200, 9600 };
+
+static struct dongle dongle = {
+       LITELINK_DONGLE,
+       litelink_open,
+       litelink_close,
+       litelink_reset,
+       litelink_change_speed,
+       litelink_init_qos,
+};
+
+__initfunc(int litelink_init(void))
+{
+       return irda_device_register_dongle(&dongle);
+}
+
+void litelink_cleanup(void)
+{
+       irda_device_unregister_dongle(&dongle);
+}
+
+static void litelink_open(struct irda_device *idev, int type)
+{
+       strcat(idev->description, " <-> litelink");
+
+        idev->io.dongle_id = type;
+       idev->flags |= IFF_DONGLE;
+
+       MOD_INC_USE_COUNT;
+}
+
+static void litelink_close(struct irda_device *idev)
+{
+       /* Power off dongle */
+       irda_device_set_dtr_rts(idev, FALSE, FALSE);
+
+       MOD_DEC_USE_COUNT;
+}
+
+/*
+ * Function litelink_change_speed (tty, baud)
+ *
+ *    Change speed of the Litelink dongle. To cycle through the available 
+ *    baud rates, pulse RTS low for a few ms.  
+ */
+static void litelink_change_speed(struct irda_device *idev, int baudrate)
+{
+        int i;
+       
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+       
+       /* Clear RTS to reset dongle */
+       irda_device_set_dtr_rts(idev, TRUE, FALSE);
+
+       /* Sleep a minimum of 15 us */
+       udelay(15);
+
+       /* Go back to normal mode */
+       irda_device_set_dtr_rts(idev, TRUE, TRUE);
+       
+       /* Sleep a minimum of 15 us */
+       udelay(15);
+       
+       /* Cycle through avaiable baudrates until we reach the correct one */
+       for (i=0; i<5 && baud_rates[i] != baudrate; i++) {
+
+               /* Set DTR, clear RTS */
+               irda_device_set_dtr_rts(idev, FALSE, TRUE);
+               
+               /* Sleep a minimum of 15 us */
+               udelay(15);
+               
+               /* Set DTR, Set RTS */
+               irda_device_set_dtr_rts(idev, TRUE, TRUE);
+               
+               /* Sleep a minimum of 15 us */
+               udelay(15);
+        }
+}
+
+/*
+ * Function litelink_reset (dev)
+ *
+ *      Reset the Litelink type dongle. Warning, this function must only be
+ *      called with a process context!
+ *
+ */
+static void litelink_reset(struct irda_device *idev, int unused)
+{
+       struct irtty_cb *self;
+        struct tty_struct *tty;
+
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+       
+       /* Power on dongle */
+       irda_device_set_dtr_rts(idev, TRUE, TRUE);
+
+       /* Sleep a minimum of 15 us */
+       udelay(15);
+
+       /* Clear RTS to reset dongle */
+       irda_device_set_dtr_rts(idev, TRUE, FALSE);
+
+       /* Sleep a minimum of 15 us */
+       udelay(15);
+
+       /* Go back to normal mode */
+       irda_device_set_dtr_rts(idev, TRUE, TRUE);
+       
+       /* Sleep a minimum of 15 us */
+       udelay(15);
+
+       /* This dongles speed defaults to 115200 bps */
+       idev->qos.baud_rate.value = 115200;
+}
+
+/*
+ * Function litelink_init_qos (qos)
+ *
+ *    Initialize QoS capabilities
+ *
+ */
+static void litelink_init_qos( struct irda_device *idev, struct qos_info *qos)
+{
+       qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+       qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
+MODULE_DESCRIPTION("Parallax Litelink dongle driver"); 
+               
+/*
+ * Function init_module (void)
+ *
+ *    Initialize Litelink module
+ *
+ */
+int init_module(void)
+{
+       return litelink_init();
+}
+
+/*
+ * Function cleanup_module (void)
+ *
+ *    Cleanup Litelink module
+ *
+ */
+void cleanup_module(void)
+{
+       litelink_cleanup();
+}
+
+#endif
index 878b2e33a84654498563b2fddba46e3acf0e8443..340f836e7b9c402e0b36d07b9ac69c92a00eaba3 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Nov  7 21:43:15 1998
- * Modified at:   Tue Apr 20 11:11:39 1999
+ * Modified at:   Sun May  9 12:57:46 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
  *     Copyright (c) 1998 Lichen Wang, <lwang@actisys.com>
  *     Copyright (c) 1998 Actisys Corp., www.actisys.com
  *     All Rights Reserved
@@ -67,6 +67,7 @@
 #define BROKEN_DONGLE_ID
 
 static char *driver_name = "pc87108";
+static int qos_mtt_bits = 0x07;  /* 1 ms or more */
 
 #define CHIP_IO_EXTENT 8
 
@@ -219,7 +220,7 @@ static int pc87108_open( int i, unsigned int iobase, unsigned int board_addr,
        idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
                IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
        
-       idev->qos.min_turn_time.bits = 0x07;
+       idev->qos.min_turn_time.bits = qos_mtt_bits;
        irda_qos_bits_to_value( &idev->qos);
        
        idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE;
@@ -259,8 +260,9 @@ static int pc87108_open( int i, unsigned int iobase, unsigned int board_addr,
  *    Close driver instance
  *
  */
-static int pc87108_close( struct irda_device *idev)
+static int pc87108_close(struct irda_device *idev)
 {
+       struct pc87108 *self;
        int iobase;
 
        DEBUG( 4, __FUNCTION__ "()\n");
@@ -269,13 +271,16 @@ static int pc87108_close( struct irda_device *idev)
        ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
 
         iobase = idev->io.iobase;
+       self = (struct pc87108 *) idev->priv;
 
        /* Release the PORT that this driver is using */
        DEBUG( 4, __FUNCTION__ "(), Releasing Region %03x\n", 
               idev->io.iobase);
-       release_region( idev->io.iobase, idev->io.io_ext);
+       release_region(idev->io.iobase, idev->io.io_ext);
+
+       irda_device_close(idev);
 
-       irda_device_close( idev);
+       kfree(self);
 
        return 0;
 }
@@ -805,7 +810,6 @@ static void pc87108_dma_write( struct irda_device *idev, int iobase)
        setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len, 
                  DMA_MODE_WRITE);
        
-       /* idev->media_busy = TRUE; */
        idev->io.direction = IO_XMIT;
        
        /* Choose transmit DMA channel  */ 
@@ -973,7 +977,7 @@ static int pc87108_dma_receive(struct irda_device *idev)
  *
  *    
  */
-static int pc87108_dma_receive_complete( struct irda_device *idev, int iobase)
+static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase)
 {
        struct sk_buff *skb;
        struct pc87108 *self;
@@ -988,8 +992,6 @@ static int pc87108_dma_receive_complete( struct irda_device *idev, int iobase)
        /* Save current bank */
        bank = inb( iobase+BSR);
        
-       iobase = idev->io.iobase;
-
        /* Read status FIFO */
        switch_bank(iobase, BANK5);
        while (( status = inb( iobase+FRM_ST)) & FRM_ST_VLD) {
@@ -1003,18 +1005,18 @@ static int pc87108_dma_receive_complete( struct irda_device *idev, int iobase)
        }
        
        /* Try to process all entries in status FIFO */
-       switch_bank( iobase, BANK0);
-       while ( st_fifo->len) {
+       switch_bank(iobase, BANK0);
+       while (st_fifo->len) {
       
                /* Get first entry */
-               status = st_fifo->entries[ st_fifo->head].status;
-               len    = st_fifo->entries[ st_fifo->head].len;
+               status = st_fifo->entries[st_fifo->head].status;
+               len    = st_fifo->entries[st_fifo->head].len;
                st_fifo->head++;
                st_fifo->len--;
 
                /* Check for errors */
-               if ( status & FRM_ST_ERR_MSK) {
-                       if ( status & FRM_ST_LOST_FR) {
+               if (status & FRM_ST_ERR_MSK) {
+                       if (status & FRM_ST_LOST_FR) {
                                /* Add number of lost frames to stats */
                                idev->stats.rx_errors += len;   
                        } else {
@@ -1188,8 +1190,8 @@ static __u8 pc87108_fir_interrupt( struct irda_device *idev, int iobase,
        bank = inb( iobase+BSR);
        
        /* Status event, or end of frame detected in FIFO */
-       if ( eir & (EIR_SFIF_EV|EIR_LS_EV)) {
-               if ( pc87108_dma_receive_complete( idev, iobase)) {
+       if (eir & (EIR_SFIF_EV|EIR_LS_EV)) {
+               if (pc87108_dma_receive_complete( idev, iobase)) {
 
                        /* Wait for next status FIFO interrupt */
                        new_ier |= IER_SFIF_IE;
@@ -1460,6 +1462,11 @@ static int pc87108_net_close(struct device *dev)
 
 #ifdef MODULE
 
+MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
+MODULE_DESCRIPTION("NSC PC87108 IrDA Device Driver");
+
+MODULE_PARM(qos_mtt_bits, "i");
+
 /*
  * Function init_module (void)
  *
index de1a553a4aaf1605a2e3caab085840627839f298..e99cb0d445018121fe718d74e9c8644e7050ab8a 100644 (file)
@@ -1,15 +1,15 @@
 /*********************************************************************
  *                
  * Filename:      tekram.c
- * Version:       1.0
+ * Version:       1.1
  * Description:   Implementation of the Tekram IrMate IR-210B dongle
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Wed Oct 21 20:02:35 1998
- * Modified at:   Tue Apr 13 16:33:54 1999
+ * Modified at:   Mon May 10 16:10:17 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -62,15 +62,15 @@ static struct dongle dongle = {
 
 __initfunc(int tekram_init(void))
 {
-       return irtty_register_dongle(&dongle);
+       return irda_device_register_dongle(&dongle);
 }
 
 void tekram_cleanup(void)
 {
-       irtty_unregister_dongle( &dongle);
+       irda_device_unregister_dongle(&dongle);
 }
 
-static void tekram_open( struct irda_device *idev, int type)
+static void tekram_open(struct irda_device *idev, int type)
 {
        strcat(idev->description, " <-> tekram");
 
@@ -80,8 +80,11 @@ static void tekram_open( struct irda_device *idev, int type)
        MOD_INC_USE_COUNT;
 }
 
-static void tekram_close( struct irda_device *dev)
-{
+static void tekram_close(struct irda_device *idev)
+{              
+       /* Power off dongle */
+       irda_device_set_dtr_rts(idev, FALSE, FALSE);
+
        MOD_DEC_USE_COUNT;
 }
 
@@ -101,79 +104,49 @@ static void tekram_close( struct irda_device *dev)
  *    6. wait at least 50 us, new setting (baud rate, etc) takes effect here 
  *       after
  */
-static void tekram_change_speed( struct irda_device *dev, int baud)
+static void tekram_change_speed(struct irda_device *idev, int baud)
 {
-       struct irtty_cb *self;
-       struct tty_struct *tty;
-       struct termios old_termios;
-       int cflag;
        __u8 byte;
        
        DEBUG(4, __FUNCTION__ "()\n");
 
-       ASSERT(dev != NULL, return;);
-       ASSERT(dev->magic == IRDA_DEVICE_MAGIC, return;);
-       
-       self = (struct irtty_cb *) dev->priv;
-       
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRTTY_MAGIC, return;);
-       
-       if (!self->tty)
-               return;
-
-       tty = self->tty;
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
        
-       old_termios = *(tty->termios);
-       cflag = tty->termios->c_cflag;
-
-       cflag &= ~CBAUD;
-
        switch (baud) {
        default:
-               /* FALLTHROUGH */
        case 9600:
-               cflag |= B9600;
                byte = TEKRAM_PW|TEKRAM_9600;
                break;
        case 19200:
-               cflag |= B19200;
                byte = TEKRAM_PW|TEKRAM_19200;
                break;
        case 34800:
-               cflag |= B38400;
                byte = TEKRAM_PW|TEKRAM_38400;
                break;
        case 57600:
-               cflag |= B57600;
                byte = TEKRAM_PW|TEKRAM_57600;
                break;
        case 115200:
-               cflag |= B115200;
                byte = TEKRAM_PW|TEKRAM_115200;
                break;
        }
 
        /* Set DTR, Clear RTS */
-       irtty_set_dtr_rts(tty, TRUE, FALSE);
+       irda_device_set_dtr_rts(idev, TRUE, FALSE);
        
        /* Wait at least 7us */
        udelay(7);
 
        /* Write control byte */
-       if (tty->driver.write)
-               tty->driver.write(self->tty, 0, &byte, 1);
+       irda_device_raw_write(idev, &byte, 1);
        
        /* Wait at least 100 ms */
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout(MSECS_TO_JIFFIES(100));
         
        /* Set DTR, Set RTS */
-       irtty_set_dtr_rts(tty, TRUE, TRUE);
-
-       /* Now change the speed of the serial port */
-       tty->termios->c_cflag = cflag;
-       tty->driver.set_termios(tty, &old_termios);     
+       irda_device_set_dtr_rts(idev, TRUE, TRUE);
 }
 
 /*
@@ -189,41 +162,27 @@ static void tekram_change_speed( struct irda_device *dev, int baud)
  *        3. clear DTR to SPACE state, wait at least 50 us for further 
  *         operation
  */
-void tekram_reset(struct irda_device *dev, int unused)
+void tekram_reset(struct irda_device *idev, int unused)
 {
-       struct irtty_cb *self;
-       struct tty_struct *tty;
-
-       DEBUG(4, __FUNCTION__ "()\n");
-
-       ASSERT(dev != NULL, return;);
-       ASSERT(dev->magic == IRDA_DEVICE_MAGIC, return;);
-       
-       self = (struct irtty_cb *) dev->priv;
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
        
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRTTY_MAGIC, return;);
-
-       tty = self->tty;
-       if (!tty)
-               return;
-
        /* Power off dongle */
-       irtty_set_dtr_rts(tty, FALSE, FALSE);
+       irda_device_set_dtr_rts(idev, FALSE, FALSE);
 
        /* Sleep 50 ms */
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout(MSECS_TO_JIFFIES(50));
 
        /* Clear DTR, Set RTS */
-       irtty_set_dtr_rts(tty, FALSE, TRUE); 
+       irda_device_set_dtr_rts(idev, FALSE, TRUE); 
 
        /* Should sleep 1 ms, but 10-20 should not do any harm */
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout(MSECS_TO_JIFFIES(20));
 
        /* Set DTR, Set RTS */
-       irtty_set_dtr_rts(tty, TRUE, TRUE);
+       irda_device_set_dtr_rts(idev, TRUE, TRUE);
        
        udelay(50);
 
diff --git a/drivers/net/irda/toshoboe.c b/drivers/net/irda/toshoboe.c
new file mode 100644 (file)
index 0000000..c7ef984
--- /dev/null
@@ -0,0 +1,901 @@
+/*********************************************************************
+ *                
+ * Filename:      toshoboe.c
+ * Version:       0.1
+ * Description:   Driver for the Toshiba OBOE (or type-O or 700 or 701)
+ *                FIR Chipset. 
+ * Status:        Experimental.
+ * Author:        James McKenzie <james@fishsoup.dhs.org>
+ * Created at:    Sat May 8  12:35:27 1999
+ * 
+ *     Copyright (c) 1999 James McKenzie, All Rights Reserved.
+ *      
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version.
+ *  
+ *     Neither James McKenzie nor Cambridge University admit liability nor
+ *     provide warranty for any of this software. This material is 
+ *     provided "AS-IS" and at no charge.
+ *
+ *     Applicable Models : Libretto 100CT. and many more
+ *     Toshiba refers to this chip as the type-O IR port.
+ *
+ ********************************************************************/
+
+/* This driver is experimental, I have only three ir devices */
+/* an olivetti notebook which doesn't have FIR, a toshiba libretto, and */
+/* an hp printer, this works fine at 4MBPS with my HP printer */
+
+static char *rcsid = "$Id: toshoboe.c,v 1.5 1999/05/12 12:24:39 root Exp root $";
+
+/* 
+ * $Log: toshoboe.c,v $
+ * Revision 1.5  1999/05/12 12:24:39  root
+ * *** empty log message ***
+ *
+ * Revision 1.4  1999/05/12 11:55:08  root
+ * *** empty log message ***
+ *
+ * Revision 1.3  1999/05/09 01:33:12  root
+ * *** empty log message ***
+ *
+ * Revision 1.2  1999/05/09 01:30:38  root
+ * *** empty log message ***
+ *
+ * Revision 1.1  1999/05/09 01:25:04  root
+ * Initial revision
+ * 
+ */
+
+/* Define this to have only one frame in the XMIT or RECV queue */
+/* Toshiba's drivers do this, but it disables back to back tansfers */
+/* I think that the chip may have some problems certainly, I have */
+/* seen it jump over tasks in the taskfile->xmit with this turned on */
+#define ONETASK
+
+/* To adjust the number of tasks in use edit toshoboe.h */
+
+/* Define this to enable FIR and MIR support */
+#define ENABLE_FAST
+
+/* Number of ports this driver can support, you also need to edit dev_self below */
+#define NSELFS 4
+
+/* Size of IO window */
+#define CHIP_IO_EXTENT 0x1f
+
+/* Transmit and receive buffer sizes, adjust at your peril */
+#define RX_BUF_SZ      4196
+#define TX_BUF_SZ      4196
+
+/* No user servicable parts below here */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include <net/irda/wrapper.h>
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/irlap_frame.h>
+#include <net/irda/irda_device.h>
+
+#include <net/irda/toshoboe.h>
+
+static char *driver_name = "toshoboe";
+
+static struct toshoboe_cb *dev_self[NSELFS + 1] =
+{NULL, NULL, NULL, NULL, NULL};
+
+/* Shutdown the chip and point the taskfile reg somewhere else */
+static void 
+toshoboe_stopchip (struct toshoboe_cb *self)
+{
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  outb_p (0x0e, OBOE_REG_11);
+
+  outb_p (0x00, OBOE_RST);
+  outb_p (0x3f, OBOE_TFP2);     /*Write the taskfile address */
+  outb_p (0xff, OBOE_TFP1);
+  outb_p (0xff, OBOE_TFP0);
+  outb_p (0x0f, OBOE_REG_1B);
+  outb_p (0xff, OBOE_REG_1A);
+  outb_p (0x00, OBOE_ISR);      /*FIXME: should i do this to disbale ints */
+  outb_p (0x80, OBOE_RST);
+  outb_p (0xe, OBOE_LOCK);
+}
+
+/*Set the baud rate */
+static void 
+toshoboe_setbaud (struct toshoboe_cb *self, int baud)
+{
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  printk (KERN_WARNING "ToshOboe: seting baud to %d\n", baud);
+
+  cli ();
+  switch (baud)
+    {
+    case 2400:
+      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
+      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
+      outb_p (0xbf, OBOE_UDIV);
+      break;
+    case 4800:
+      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
+      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
+      outb_p (0x5f, OBOE_UDIV);
+      break;
+    case 9600:
+      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
+      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
+      outb_p (0x2f, OBOE_UDIV);
+      break;
+    case 19200:
+      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
+      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
+      outb_p (0x17, OBOE_UDIV);
+      break;
+    case 38400:
+      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
+      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
+      outb_p (0xb, OBOE_UDIV);
+      break;
+    case 57600:
+      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
+      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
+      outb_p (0x7, OBOE_UDIV);
+      break;
+    case 115200:
+      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
+      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
+      outb_p (0x3, OBOE_UDIV);
+      break;
+    case 1152000:
+      outb_p (OBOE_PMDL_MIR, OBOE_PMDL);
+      outb_p (OBOE_SMDL_MIR, OBOE_SMDL);
+      outb_p (0x1, OBOE_UDIV);
+      break;
+    case 4000000:
+      outb_p (OBOE_PMDL_FIR, OBOE_PMDL);
+      outb_p (OBOE_SMDL_FIR, OBOE_SMDL);
+      outb_p (0x0, OBOE_UDIV);
+      break;
+    }
+
+  sti ();
+
+  outb_p (0x00, OBOE_RST);
+  outb_p (0x80, OBOE_RST);
+  outb_p (0x01, OBOE_REG_9);
+
+}
+
+/* Wake the chip up and get it looking at the taskfile */
+static void 
+toshoboe_startchip (struct toshoboe_cb *self)
+{
+  __u32 physaddr;
+
+  DEBUG (4, __FUNCTION__ "()\n");
+
+
+  outb_p (0, OBOE_LOCK);
+  outb_p (0, OBOE_RST);
+  outb_p (OBOE_NTR_VAL, OBOE_NTR);
+  outb_p (0xf0, OBOE_REG_D);
+  outb_p (0xff, OBOE_ISR);
+  outb_p (0x0f, OBOE_REG_1A);
+  outb_p (0xff, OBOE_REG_1B);
+
+
+  physaddr = virt_to_bus (self->taskfile);
+
+  outb_p ((physaddr >> 0x0a) & 0xff, OBOE_TFP0);
+  outb_p ((physaddr >> 0x12) & 0xff, OBOE_TFP1);
+  outb_p ((physaddr >> 0x1a) & 0x3f, OBOE_TFP2);
+
+  outb_p (0x0e, OBOE_REG_11);
+  outb_p (0x80, OBOE_RST);
+
+  toshoboe_setbaud (self, 9600);
+
+}
+
+/*Let the chip look at memory */
+static void 
+toshoboe_enablebm (struct toshoboe_cb *self)
+{
+  DEBUG (4, __FUNCTION__ "()\n");
+  pci_set_master (self->pdev);
+}
+
+/*Don't let the chip look at memory */
+static void 
+toshoboe_disablebm (struct toshoboe_cb *self)
+{
+  __u8 command;
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  pci_read_config_byte (self->pdev, PCI_COMMAND, &command);
+  command &= ~PCI_COMMAND_MASTER;
+  pci_write_config_byte (self->pdev, PCI_COMMAND, command);
+
+}
+
+/*setup the taskfile */
+static void 
+toshoboe_initbuffs (struct toshoboe_cb *self)
+{
+  int i;
+
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  cli ();
+
+  for (i = 0; i < TX_SLOTS; ++i)
+    {
+      self->taskfile->xmit[i].len = 0;
+      self->taskfile->xmit[i].control = 0x00;
+      self->taskfile->xmit[i].buffer = virt_to_bus (self->xmit_bufs[i]);
+    }
+
+  for (i = 0; i < RX_SLOTS; ++i)
+    {
+      self->taskfile->recv[i].len = 0;
+      self->taskfile->recv[i].control = 0x83;
+      self->taskfile->recv[i].buffer = virt_to_bus (self->recv_bufs[i]);
+    }
+
+  sti ();
+}
+
+
+/*Transmit something */
+static int 
+toshoboe_hard_xmit (struct sk_buff *skb, struct device *dev)
+{
+  struct irda_device *idev;
+  struct toshoboe_cb *self;
+  int mtt, len;
+
+  idev = (struct irda_device *) dev->priv;
+  ASSERT (idev != NULL, return 0;);
+  ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+
+  self = idev->priv;
+  ASSERT (self != NULL, return 0;);
+
+
+#ifdef ONETASK
+  if (self->txpending)
+    return -EBUSY;
+
+  self->txs = inb_p (OBOE_XMTT) - OBOE_XMTT_OFFSET;
+
+  self->txs &= 0x3f;
+
+#endif
+
+  if (self->taskfile->xmit[self->txs].control)
+    return -EBUSY;
+
+
+  if (inb_p (OBOE_RST) & OBOE_RST_WRAP)
+    {
+      len = async_wrap_skb (skb, self->xmit_bufs[self->txs], TX_BUF_SZ);
+    }
+  else
+    {
+      len = skb->len;
+      memcpy (self->xmit_bufs[self->txs], skb->data, len);
+    }
+  self->taskfile->xmit[self->txs].len = len & 0x0fff;
+
+
+
+  outb_p (0, OBOE_RST);
+  outb_p (0x1e, OBOE_REG_11);
+
+  self->taskfile->xmit[self->txs].control = 0x84;
+
+  mtt = irda_get_mtt (skb);
+  if (mtt)
+    udelay (mtt);
+
+  self->txpending++;
+
+  /*FIXME: ask about tbusy,media_busy stuff, for the moment */
+  /*tbusy means can't queue any more */
+#ifndef ONETASK
+  if (self->txpending == TX_SLOTS)
+    {
+#else
+  {
+#endif
+    if (irda_lock ((void *) &dev->tbusy) == FALSE)
+      return -EBUSY;
+  }
+
+  outb_p (0x80, OBOE_RST);
+  outb_p (1, OBOE_REG_9);
+
+  self->txs++;
+  self->txs %= TX_SLOTS;
+
+  dev_kfree_skb (skb);
+
+  return 0;
+}
+
+/*interrupt handler */
+static void 
+toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+{
+  struct irda_device *idev = (struct irda_device *) dev_id;
+  struct toshoboe_cb *self;
+  __u8 irqstat;
+  struct sk_buff *skb;
+
+  if (idev == NULL)
+    {
+      printk (KERN_WARNING "%s: irq %d for unknown device.\n",
+              driver_name, irq);
+      return;
+    }
+
+  self = idev->priv;
+
+  if (!self)
+    return;
+
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  irqstat = inb_p (OBOE_ISR);
+
+/* woz it us */
+  if (!(irqstat & 0xf8))
+    return;
+
+  outb_p (irqstat, OBOE_ISR);   /*Acknologede it */
+
+
+/* Txdone */
+  if (irqstat & OBOE_ISR_TXDONE)
+    {
+      self->txpending--;
+
+      idev->stats.tx_packets++;
+
+      idev->media_busy = FALSE;
+      idev->netdev.tbusy = 0;
+
+      mark_bh (NET_BH);
+    }
+
+  if (irqstat & OBOE_ISR_RXDONE)
+    {
+
+#ifdef ONETASK
+      self->rxs = inb_p (OBOE_RCVT);
+      self->rxs += (RX_SLOTS - 1);
+      self->rxs %= RX_SLOTS;
+#else
+      while (self->taskfile->recv[self->rxs].control == 0)
+#endif
+        {
+          int len = self->taskfile->recv[self->rxs].len;
+       
+         if (len>2) len-=2;
+
+          skb = dev_alloc_skb (len + 1);
+          if (skb)
+            {
+              skb_reserve (skb, 1);
+
+              skb_put (skb, len);
+              memcpy (skb->data, self->recv_bufs[self->rxs], len);
+
+              idev->stats.rx_packets++;
+              skb->dev = &idev->netdev;
+              skb->mac.raw = skb->data;
+              skb->protocol = htons (ETH_P_IRDA);
+            }
+          else
+            {
+              printk (KERN_INFO __FUNCTION__
+                      "(), memory squeeze, dropping frame.\n");
+            }
+
+
+
+          self->taskfile->recv[self->rxs].control = 0x83;
+          self->taskfile->recv[self->rxs].len = 0x0;
+
+          self->rxs++;
+          self->rxs %= RX_SLOTS;
+
+          if (skb)
+            netif_rx (skb);
+
+        }
+
+    }
+
+  if (irqstat & OBOE_ISR_20)
+    {
+      printk (KERN_WARNING "Oboe_irq: 20\n");
+    }
+  if (irqstat & OBOE_ISR_10)
+    {
+      printk (KERN_WARNING "Oboe_irq: 10\n");
+    }
+  if (irqstat & 0x8)
+    {
+      /*FIXME: I think this is a TX or RX error of some sort */
+
+      idev->stats.tx_errors++;
+      idev->stats.rx_errors++;
+
+    }
+
+
+}
+
+
+
+/* Change the baud rate */
+static void 
+toshoboe_change_speed (struct irda_device *idev, int speed)
+{
+  struct toshoboe_cb *self;
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  ASSERT (idev != NULL, return;);
+  ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+  self = idev->priv;
+  ASSERT (self != NULL, return;);
+
+  idev->io.baudrate = speed;
+
+  toshoboe_setbaud (self, speed);
+
+}
+
+
+/* Check all xmit_tasks finished */
+static void 
+toshoboe_wait_until_sent (struct irda_device *idev)
+{
+  struct toshoboe_cb *self;
+  int i;
+
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  ASSERT (idev != NULL, return;);
+  ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+  self = idev->priv;
+  ASSERT (self != NULL, return;);
+
+  for (i = 0; i < TX_SLOTS; ++i)
+    {
+      while (self->taskfile->xmit[i].control)
+        {
+          current->state = TASK_INTERRUPTIBLE;
+          schedule_timeout (6);
+        }
+    }
+
+}
+
+static int 
+toshoboe_is_receiving (struct irda_device *idev)
+{
+  DEBUG (4, __FUNCTION__ "()\n");
+
+/*FIXME Can't tell! */
+  return (FALSE);
+}
+
+
+static int 
+toshoboe_net_init (struct device *dev)
+{
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  /* Setup to be a normal IrDA network device driver */
+  irda_device_setup (dev);
+
+  /* Insert overrides below this line! */
+  return 0;
+}
+
+
+
+
+static int 
+toshoboe_net_open (struct device *dev)
+{
+  struct irda_device *idev;
+  struct toshoboe_cb *self;
+
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  ASSERT (dev != NULL, return -1;);
+  idev = (struct irda_device *) dev->priv;
+
+  ASSERT (idev != NULL, return 0;);
+  ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+
+  self = idev->priv;
+  ASSERT (self != NULL, return 0;);
+
+  if (request_irq (idev->io.irq, toshoboe_interrupt,
+                   SA_SHIRQ | SA_INTERRUPT, idev->name, (void *) idev))
+    {
+
+      return -EAGAIN;
+    }
+
+  toshoboe_initbuffs (self);
+  toshoboe_enablebm (self);
+  toshoboe_startchip (self);
+
+
+  cli ();
+
+  /*FIXME: need to test this carefully to check which one */
+  /*of the two possible startup logics the chip uses */
+  /*although it won't make any difference if no-one xmits durining init */
+  /*and none what soever if using ONETASK */
+
+  self->rxs = inb_p (OBOE_RCVT);
+  self->txs = inb_p (OBOE_XMTT) - OBOE_XMTT_OFFSET;
+
+#ifdef 0
+  self->rxs = 0;
+  self->txs = 0;
+#endif
+#ifdef 0
+  self->rxs = RX_SLOTS - 1;
+  self->txs = 0;
+#endif
+
+
+  self->txpending = 0;
+
+  sti ();
+
+
+  dev->tbusy = 0;
+  dev->interrupt = 0;
+  dev->start = 1;
+
+  MOD_INC_USE_COUNT;
+
+  return 0;
+
+}
+
+static int 
+toshoboe_net_close (struct device *dev)
+{
+  struct irda_device *idev;
+  struct toshoboe_cb *self;
+
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  ASSERT (dev != NULL, return -1;);
+  idev = (struct irda_device *) dev->priv;
+
+  ASSERT (idev != NULL, return 0;);
+  ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+
+  dev->tbusy = 1;
+  dev->start = 0;
+
+
+  self = idev->priv;
+
+  ASSERT (self != NULL, return 0;);
+
+  free_irq (idev->io.irq, (void *) idev);
+
+  toshoboe_stopchip (self);
+  toshoboe_disablebm (self);
+
+  MOD_DEC_USE_COUNT;
+
+  return 0;
+
+}
+
+
+
+#ifdef MODULE
+
+static int 
+toshoboe_close (struct irda_device *idev)
+{
+  struct toshoboe_cb *self;
+  int i;
+
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  ASSERT (idev != NULL, return -1;);
+  ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+  self = idev->priv;
+
+  ASSERT (self != NULL, return -1;);
+
+  toshoboe_stopchip (self);
+
+  release_region (idev->io.iobase, idev->io.io_ext);
+
+
+  for (i = 0; i < TX_SLOTS; ++i)
+    {
+      kfree (self->xmit_bufs[i]);
+      self->xmit_bufs[i] = NULL;
+    }
+
+  for (i = 0; i < RX_SLOTS; ++i)
+    {
+      kfree (self->recv_bufs[i]);
+      self->recv_bufs[i] = NULL;
+    }
+
+
+  kfree (self->taskfilebuf);
+  self->taskfilebuf = NULL;
+  self->taskfile = NULL;
+
+
+  irda_device_close (idev);
+
+  return (0);
+
+}
+
+#endif
+
+
+
+static int 
+toshoboe_open (struct pci_dev *pci_dev)
+{
+  struct toshoboe_cb *self;
+  struct irda_device *idev;
+  int i = 0;
+  int ok=0;
+
+
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  while (dev_self[i])
+    i++;
+
+  if (i == NSELFS)
+    {
+      printk (KERN_ERR "Oboe: No more instances available");
+      return -ENOMEM;
+    }
+
+  self = kmalloc (sizeof (struct toshoboe_cb), GFP_KERNEL);
+
+  if (self == NULL)
+    {
+      printk (KERN_ERR "IrDA: Can't allocate memory for "
+              "IrDA control block!\n");
+      return -ENOMEM;
+    }
+
+  memset (self, 0, sizeof (struct toshoboe_cb));
+
+
+  dev_self[i] = self;
+
+  self->pdev = pci_dev;
+  self->base = pci_dev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
+
+  idev = &self->idev;
+
+  /*Setup idev */
+
+  idev->io.iobase = self->base;
+  idev->io.irq = pci_dev->irq;
+  idev->io.io_ext = CHIP_IO_EXTENT;
+
+  /* Lock the port that we need */
+  i = check_region (idev->io.iobase, idev->io.io_ext);
+  if (i < 0)
+    {
+      DEBUG (0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+             idev->io.iobase);
+
+      dev_self[i] = NULL;
+      kfree (self);
+
+      return -ENODEV;
+    }
+
+  request_region (idev->io.iobase, idev->io.io_ext, driver_name);
+
+  irda_init_max_qos_capabilies (&idev->qos);
+
+  idev->qos.baud_rate.bits = IR_2400 | /*IR_4800 | */ IR_9600 | IR_19200 |
+    IR_115200;
+#ifdef ENABLE_FAST
+ idev->qos.baud_rate.bits|= IR_576000 | IR_1152000 | (IR_4000000 << 8);
+#endif
+
+  idev->qos.min_turn_time.bits = 0xff;  /*FIXME: what does this do? */
+
+  irda_qos_bits_to_value (&idev->qos);
+
+  idev->flags = IFF_SIR | IFF_DMA | IFF_PIO;
+
+#ifdef ENABLE_FAST
+  idev->flags |= IFF_FIR;
+#endif
+
+  /* These aren't much use as we need to have a whole panoply of
+   * buffers running */
+
+  idev->rx_buff.flags = 0;
+  idev->tx_buff.flags = 0;
+  idev->rx_buff.truesize = 0;
+  idev->rx_buff.truesize = 0;
+
+  idev->change_speed = toshoboe_change_speed;
+  idev->wait_until_sent = toshoboe_wait_until_sent;
+  idev->is_receiving = toshoboe_is_receiving;
+
+  idev->netdev.init = toshoboe_net_init;
+  idev->netdev.hard_start_xmit = toshoboe_hard_xmit;
+  idev->netdev.open = toshoboe_net_open;
+  idev->netdev.stop = toshoboe_net_close;
+
+
+  /* Now setup the endless buffers we need */
+
+  self->txs = 0;
+  self->rxs = 0;
+
+  self->taskfilebuf = kmalloc (OBOE_TASK_BUF_LEN, GFP_KERNEL | GFP_DMA);
+  if (!self->taskfilebuf) {
+       printk(KERN_ERR "toshoboe: kmalloc for DMA failed()\n");
+       kfree(self);
+       return -ENOMEM;
+  }
+
+
+  memset (self->taskfilebuf, 0, OBOE_TASK_BUF_LEN);
+
+  /*We need to align the taskfile on a taskfile size boundary */
+  {
+    __u32 addr;
+
+    addr = (__u32) self->taskfilebuf;
+    addr &= ~(sizeof (struct OboeTaskFile) - 1);
+    addr += sizeof (struct OboeTaskFile);
+
+    self->taskfile = (struct OboeTaskFile *) addr;
+  }
+
+  for (i = 0; i < TX_SLOTS; ++i)
+    {
+      self->xmit_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);
+      if (self->xmit_bufs[i]) ok++;
+    }
+
+  for (i = 0; i < RX_SLOTS; ++i)
+    {
+      self->recv_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);
+      if (self->recv_bufs[i]) ok++;
+    }
+
+  if (ok!=RX_SLOTS+TX_SLOTS) {
+       printk(KERN_ERR  "toshoboe: kmalloc for buffers failed()\n");
+
+
+  for (i = 0; i < TX_SLOTS; ++i) if (self->xmit_bufs[i]) kfree(self->xmit_bufs[i]);
+  for (i = 0; i < RX_SLOTS; ++i) if (self->recv_bufs[i]) kfree(self->recv_bufs[i]);
+
+       kfree(self);
+       return -ENOMEM;
+
+  }
+
+
+  irda_device_open (idev, driver_name, self);
+
+  printk (KERN_WARNING "ToshOboe: Using ");
+#ifdef ONETASK
+  printk ("single");
+#else
+  printk ("multiple");
+#endif
+  printk (" tasks, version %s\n", rcsid);
+
+  return (0);
+}
+
+__initfunc (int toshoboe_init (void))
+{
+  struct pci_dev *pci_dev = NULL;
+  int found = 0;
+
+  do
+    {
+      pci_dev = pci_find_device (PCI_VENDOR_ID_TOSHIBA,
+                                 PCI_DEVICE_ID_FIR701, pci_dev);
+      if (pci_dev)
+        {
+          printk (KERN_WARNING "ToshOboe: Found 701 chip at 0x%0lx irq %d\n",
+                  pci_dev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK,
+                  pci_dev->irq);
+
+          if (!toshoboe_open (pci_dev))
+            found++;
+        }
+
+    }
+  while (pci_dev);
+
+  if (found)
+    return 0;
+
+  return -ENODEV;
+}
+
+#ifdef MODULE
+
+static void 
+toshoboe_cleanup (void)
+{
+  int i;
+
+  DEBUG (4, __FUNCTION__ "()\n");
+
+  for (i = 0; i < 4; i++)
+    {
+      if (dev_self[i])
+        toshoboe_close (&(dev_self[i]->idev));
+    }
+}
+
+
+
+int 
+init_module (void)
+{
+  return toshoboe_init ();
+}
+
+
+void 
+cleanup_module (void)
+{
+  toshoboe_cleanup ();
+}
+
+
+#endif
index 60c8e024a0d1fec5c56b44e05c48cf494d69c972..f3454c531d94e92d66f0888b423e8ac3adc39fa4 100644 (file)
@@ -7,10 +7,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Dec 26 10:59:03 1998
- * Modified at:   Tue Apr 20 11:15:52 1999
+ * Modified at:   Mon May 10 22:11:09 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -216,7 +216,7 @@ static int uircc_open(int i, unsigned int iobase, unsigned int iobase2,
        idev->netdev.open            = uircc_net_open;
        idev->netdev.stop            = uircc_net_close;
 
-       irport_open(iobase2);
+       irport_start(iobase2);
 
        /* Open the IrDA device */
        irda_device_open(idev, driver_name, self);
@@ -233,6 +233,7 @@ static int uircc_open(int i, unsigned int iobase, unsigned int iobase2,
 #ifdef MODULE
 static int uircc_close(struct irda_device *idev)
 {
+       struct uircc_cb *self;
        int iobase;
        int status;
 
@@ -242,6 +243,7 @@ static int uircc_close(struct irda_device *idev)
        ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
 
         iobase = idev->io.iobase;
+       self = (struct uircc_cb *) idev->priv;
 
        /* Some magic to disable FIR and enable SIR */
        uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0000);
@@ -249,7 +251,7 @@ static int uircc_close(struct irda_device *idev)
        /* Disable modem */
        outb(0x00, iobase+UIRCC_CR10);
 
-       irport_close(idev->io.iobase2);
+       irport_stop(idev->io.iobase2);
 
        /* Release the PORT that this driver is using */
        DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase);
@@ -262,6 +264,8 @@ static int uircc_close(struct irda_device *idev)
        }
        irda_device_close(idev);
 
+       kfree(self);
+
        return 0;
 }
 #endif /* MODULE */
@@ -346,8 +350,8 @@ static void uircc_change_speed(struct irda_device *idev, int speed)
        case 37600:
        case 57600:
        case 115200:
-               irport_open(idev->io.iobase2);
-               irport_change_speed( idev->io.iobase2, speed);
+               irport_start(idev->io.iobase2);
+               irport_change_speed(idev, speed);
 
                /* Some magic to disable FIR and enable SIR */
                uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0000);
@@ -363,7 +367,7 @@ static void uircc_change_speed(struct irda_device *idev, int speed)
                DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
                break;
        case 4000000:
-               irport_close(idev->io.iobase2);
+               irport_stop(idev->io.iobase2);
 
                /* Some magic to disable SIR and enable FIR */
                uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0001);
index 9234c4a82022b5f2d96d60916379aba661f05114..f773172153e2dd3f0e19c9158d18d967a348a5a4 100644 (file)
@@ -1,16 +1,16 @@
 /*********************************************************************
  *                
  * Filename:      w83977af_ir.c
- * Version:       0.8
- * Description:   FIR/MIR driver for the Winbond W83977AF Super I/O chip
+ * Version:       1.0
+ * Description:   FIR driver for the Winbond W83977AF Super I/O chip
  * Status:        Experimental.
  * Author:        Paul VanderSpek
  * Created at:    Wed Nov  4 11:46:16 1998
- * Modified at:   Tue Apr 20 11:15:00 1999
+ * Modified at:   Thu May 13 08:03:27 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
  *     Copyright (c) 1998 Corel Computer Corp.
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -40,7 +40,7 @@
  ********************************************************************/
 
 #include <linux/module.h>
-
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/skbuff.h>
 #include <net/irda/w83977af.h>
 #include <net/irda/w83977af_ir.h>
 
-#define NETWINDER
+#define CONFIG_NETWINDER                 /* Adjust to NetWinder differences */
+#undef  CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */
+#define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */
+#undef  CONFIG_USE_INTERNAL_TIMER        /* Just cannot make that timer work */
+#define CONFIG_USE_W977_PNP              /* Currently needed */
+#define PIO_MAX_SPEED       115200 
 
 static char *driver_name = "w83977af_ir";
+static int  qos_mtt_bits = 0x07;           /* 1 ms or more */
 
 #define CHIP_IO_EXTENT 8
 
 static unsigned int io[] = { 0x180, ~0, ~0, ~0 };
 static unsigned int irq[] = { 6, 0, 0, 0 };
-static unsigned int dma[] = { 0, 0, 0, 0 };
-
-static struct irda_device *dev_self[] = { NULL, NULL, NULL, NULL};
+static unsigned int dma[] = 
+{ 1, 0, 0, 0 };
 
-/* For storing entries in the status FIFO */
-struct st_fifo_entry {
-       int status;
-       int len;
-};
+static struct w83977af_ir *dev_self[] = { NULL, NULL, NULL, NULL};
 
 static struct st_fifo_entry prev;
 
 /* Some prototypes */
-static int  w83977af_open( int i, unsigned int iobase, unsigned int irq, 
-                          unsigned int dma);
-static int  w83977af_close( struct irda_device *idev);
-static int  w83977af_probe( int iobase, int irq, int dma);
+static int  w83977af_open(int i, unsigned int iobase, unsigned int irq, 
+                          unsigned int dma);
+static int  w83977af_close(struct irda_device *idev);
+static int  w83977af_probe(int iobase, int irq, int dma);
 static int  w83977af_dma_receive(struct irda_device *idev); 
 static int  w83977af_dma_receive_complete(struct irda_device *idev);
-static int  w83977af_hard_xmit( struct sk_buff *skb, struct device *dev);
-static int  w83977af_pio_write( int iobase, __u8 *buf, int len, int fifo_size);
-static void w83977af_dma_write( struct irda_device *idev, int iobase);
-static void w83977af_change_speed( struct irda_device *idev, int baud);
+static int  w83977af_hard_xmit(struct sk_buff *skb, struct device *dev);
+static int  w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size);
+static void w83977af_dma_write(struct irda_device *idev, int iobase);
+static void w83977af_change_speed(struct irda_device *idev, int baud);
 static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void w83977af_wait_until_sent( struct irda_device *idev);
-static int w83977af_is_receiving( struct irda_device *idev);
+static void w83977af_wait_until_sent(struct irda_device *idev);
+static int  w83977af_is_receiving(struct irda_device *idev);
 
-static int w83977af_net_init( struct device *dev);
-static int w83977af_net_open( struct device *dev);
-static int w83977af_net_close( struct device *dev);
+static int  w83977af_net_init(struct device *dev);
+static int  w83977af_net_open(struct device *dev);
+static int  w83977af_net_close(struct device *dev);
 
 /*
  * Function w83977af_init ()
@@ -108,13 +109,13 @@ static int w83977af_net_close( struct device *dev);
  */
 __initfunc(int w83977af_init(void))
 {
-       int i;
+        int i;
 
-       DEBUG( 0, __FUNCTION__ "()\n");
+       DEBUG(0, __FUNCTION__ "()\n");
 
        prev.status = 0;
 
-       for ( i=0; (io[i] < 2000) && (i < 4); i++) {
+       for (i=0; (io[i] < 2000) && (i < 4); i++) { 
                int ioaddr = io[i];
                if (check_region(ioaddr, CHIP_IO_EXTENT) < 0)
                        continue;
@@ -135,11 +136,11 @@ void w83977af_cleanup(void)
 {
        int i;
 
-        DEBUG( 4, __FUNCTION__ "()\n");
+        DEBUG(4, __FUNCTION__ "()\n");
 
-       for ( i=0; i < 4; i++) {
-               if ( dev_self[i])
-                       w83977af_close( dev_self[i]);
+       for (i=0; i < 4; i++) {
+               if (dev_self[i])
+                       w83977af_close(&(dev_self[i]->idev));
        }
 }
 #endif /* MODULE */
@@ -154,26 +155,29 @@ int w83977af_open( int i, unsigned int iobase, unsigned int irq,
                   unsigned int dma)
 {
        struct irda_device *idev;
+        struct w83977af_ir *self;
        int ret;
 
        DEBUG( 0, __FUNCTION__ "()\n");
 
-       if ( w83977af_probe( iobase, irq, dma) == -1)
+       if (w83977af_probe(iobase, irq, dma) == -1)
                return -1;
 
        /*
         *  Allocate new instance of the driver
         */
-       idev = kmalloc( sizeof(struct irda_device), GFP_KERNEL);
-       if ( idev == NULL) {
+       self = kmalloc(sizeof(struct w83977af_ir), GFP_KERNEL);
+       if (self == NULL) {
                printk( KERN_ERR "IrDA: Can't allocate memory for "
                        "IrDA control block!\n");
                return -ENOMEM;
        }
-       memset( idev, 0, sizeof(struct irda_device));
+       memset(self, 0, sizeof(struct w83977af_ir));
    
        /* Need to store self somewhere */
-       dev_self[i] = idev;
+       dev_self[i] = self;
+
+       idev = &self->idev;
 
        /* Initialize IO */
        idev->io.iobase    = iobase;
@@ -183,17 +187,17 @@ int w83977af_open( int i, unsigned int iobase, unsigned int irq,
         idev->io.fifo_size = 32;
 
        /* Lock the port that we need */
-       ret = check_region( idev->io.iobase, idev->io.io_ext);
-       if ( ret < 0) { 
+       ret = check_region(idev->io.iobase, idev->io.io_ext);
+       if (ret < 0) { 
                DEBUG( 0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
                       idev->io.iobase);
                /* w83977af_cleanup( self->idev);  */
                return -ENODEV;
        }
-       request_region( idev->io.iobase, idev->io.io_ext, idev->name);
+       request_region(idev->io.iobase, idev->io.io_ext, idev->name);
 
        /* Initialize QoS for this device */
-       irda_init_max_qos_capabilies( &idev->qos);
+       irda_init_max_qos_capabilies(&idev->qos);
        
        /* The only value we must override it the baudrate */
 
@@ -202,8 +206,8 @@ int w83977af_open( int i, unsigned int iobase, unsigned int irq,
                IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
 
        /* The HP HDLS-1100 needs 1 ms according to the specs */
-       idev->qos.min_turn_time.bits = 0x03; /* 1ms and more */
-       irda_qos_bits_to_value( &idev->qos);
+       idev->qos.min_turn_time.bits = qos_mtt_bits;
+       irda_qos_bits_to_value(&idev->qos);
        
        idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO;
 
@@ -221,13 +225,13 @@ int w83977af_open( int i, unsigned int iobase, unsigned int irq,
         idev->is_receiving    = w83977af_is_receiving;
 
        /* Override the network functions we need to use */
-       idev->netdev.init = w83977af_net_init;
+       idev->netdev.init            = w83977af_net_init;
        idev->netdev.hard_start_xmit = w83977af_hard_xmit;
-       idev->netdev.open = w83977af_net_open;
-       idev->netdev.stop = w83977af_net_close;
+       idev->netdev.open            = w83977af_net_open;
+       idev->netdev.stop            = w83977af_net_close;
 
        /* Open the IrDA device */
-       irda_device_open( idev, driver_name, NULL);
+       irda_device_open(idev, driver_name, self);
        
        return 0;
 }
@@ -240,15 +244,18 @@ int w83977af_open( int i, unsigned int iobase, unsigned int irq,
  */
 static int w83977af_close( struct irda_device *idev)
 {
+       struct w83977af_ir *self;
        int iobase;
 
-       DEBUG( 0, __FUNCTION__ "()\n");
+       DEBUG(0, __FUNCTION__ "()\n");
 
-       ASSERT( idev != NULL, return -1;);
-       ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+       ASSERT(idev != NULL, return -1;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
 
         iobase = idev->io.iobase;
+       self = (struct w83977af_ir *) idev->priv;
 
+#ifdef CONFIG_USE_W977_PNP
        /* enter PnP configuration mode */
        w977_efm_enter();
 
@@ -258,13 +265,15 @@ static int w83977af_close( struct irda_device *idev)
        w977_write_reg(0x30, 0x00);
 
        w977_efm_exit();
-
+#endif /* CONFIG_USE_W977_PNP */
        /* Release the PORT that this driver is using */
        DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", 
              idev->io.iobase);
-       release_region( idev->io.iobase, idev->io.io_ext);
+       release_region(idev->io.iobase, idev->io.io_ext);
+
+       irda_device_close(idev);
 
-       irda_device_close( idev);
+       kfree(self);
 
        return 0;
 }
@@ -280,7 +289,7 @@ int w83977af_probe( int iobase, int irq, int dma)
        int version;
        
        DEBUG( 0, __FUNCTION__ "()\n");
-
+#ifdef CONFIG_USE_W977_PNP
        /* Enter PnP configuration mode */
        w977_efm_enter();
 
@@ -289,14 +298,14 @@ int w83977af_probe( int iobase, int irq, int dma)
        /* Configure PnP port, IRQ, and DMA channel */
        w977_write_reg(0x60, (iobase >> 8) & 0xff);
        w977_write_reg(0x61, (iobase) & 0xff);
-       /* w977_write_reg(0x70, 0x06); */
+
        w977_write_reg(0x70, irq);
-#ifdef NETWINDER
-       w977_write_reg(0x74, dma+1); /* Netwinder uses one higher than Linux */
+#ifdef CONFIG_NETWINDER
+       w977_write_reg(0x74, dma+1); /* Netwinder uses 1 higher than Linux */
 #else
        w977_write_reg(0x74, dma);   
 #endif
-       w977_write_reg(0x75, dma);   /* Disable Tx DMA */
+       w977_write_reg(0x75, 0x04);  /* Disable Tx DMA */
        
        /* Set append hardware CRC, enable IR bank selection */ 
        w977_write_reg(0xf0, APEDCRC|ENBNKSEL);
@@ -305,26 +314,26 @@ int w83977af_probe( int iobase, int irq, int dma)
        w977_write_reg(0x30, 0x01);
 
        w977_efm_exit();
-
+#endif
        /* Disable Advanced mode */
-       switch_bank( iobase, SET2);
+       switch_bank(iobase, SET2);
        outb(iobase+2, 0x00);  
 
        /* Turn on UART (global) interrupts */
-       switch_bank( iobase, SET0);
-       outb( HCR_EN_IRQ, iobase+HCR);
+       switch_bank(iobase, SET0);
+       outb(HCR_EN_IRQ, iobase+HCR);
        
        /* Switch to advanced mode */
-       switch_bank( iobase, SET2);
-       outb( inb( iobase+ADCR1) | ADCR1_ADV_SL, iobase+ADCR1);
+       switch_bank(iobase, SET2);
+       outb(inb(iobase+ADCR1) | ADCR1_ADV_SL, iobase+ADCR1);
 
        /* Set default IR-mode */
-       switch_bank( iobase, SET0);
-       outb( HCR_SIR, iobase+HCR);
+       switch_bank(iobase, SET0);
+       outb(HCR_SIR, iobase+HCR);
 
        /* Read the Advanced IR ID */
        switch_bank(iobase, SET3);
-       version =  inb( iobase+AUID);
+       version = inb(iobase+AUID);
        
        /* Should be 0x1? */
        if (0x10 != (version & 0xf0)) {
@@ -333,18 +342,17 @@ int w83977af_probe( int iobase, int irq, int dma)
        }
        
        /* Set FIFO size to 32 */
-       switch_bank( iobase, SET2);
-       outb( ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2); 
+       switch_bank(iobase, SET2);
+       outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);  
        
        /* Set FIFO threshold to TX17, RX16 */
        switch_bank(iobase, SET0);      
        outb(UFR_RXTL|UFR_TXTL|UFR_TXF_RST|UFR_RXF_RST|UFR_EN_FIFO,iobase+UFR);
-/*     outb( 0xa7, iobase+UFR); */
 
        /* Receiver frame length */
-       switch_bank( iobase, SET4);
-       outb( 2048 & 0xff, iobase+6);
-       outb(( 2048 >> 8) & 0x1f, iobase+7);
+       switch_bank(iobase, SET4);
+       outb(2048 & 0xff, iobase+6);
+       outb((2048 >> 8) & 0x1f, iobase+7);
 
        /* 
         * Init HP HSDL-1100 transceiver. 
@@ -358,8 +366,8 @@ int w83977af_probe( int iobase, int irq, int dma)
         *   FIRRX pin 39 connected to receiver      (IRSL0) 
         *   CIRRX pin 40 connected to pin 37
         */
-       switch_bank( iobase, SET7);
-       outb( 0x40, iobase+7);
+       switch_bank(iobase, SET7);
+       outb(0x40, iobase+7);
                
        DEBUG(0, "W83977AF (IR) driver loaded. Version: 0x%02x\n", version);
        
@@ -372,16 +380,14 @@ int w83977af_probe( int iobase, int irq, int dma)
  *    Change the speed of the device
  *
  */
-void w83977af_change_speed( struct irda_device *idev, int speed)
+void w83977af_change_speed(struct irda_device *idev, int speed)
 {
        int ir_mode = HCR_SIR;
        int iobase; 
        __u8 set;
 
-       DEBUG( 0, __FUNCTION__ "()\n");
-
-       ASSERT( idev != NULL, return;);
-       ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+       ASSERT(idev != NULL, return;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
 
        iobase = idev->io.iobase;
 
@@ -389,22 +395,22 @@ void w83977af_change_speed( struct irda_device *idev, int speed)
        idev->io.baudrate = speed;
 
        /* Save current bank */
-       set = inb( iobase+SSR);
+       set = inb(iobase+SSR);
 
        /* Disable interrupts */
-       switch_bank( iobase, SET0);
-       outb( 0, iobase+ICR);
+       switch_bank(iobase, SET0);
+       outb(0, iobase+ICR);
 
        /* Select Set 2 */
-       switch_bank( iobase, SET2);
-
-       outb( 0x00, iobase+ABHL);
-       switch ( speed) {
-       case 9600:   outb( 0x0c, iobase+ABLL); break;
-       case 19200:  outb( 0x06, iobase+ABLL); break;
-       case 37600:  outb( 0x03, iobase+ABLL); break;
-       case 57600:  outb( 0x02, iobase+ABLL); break;
-       case 115200: outb( 0x01, iobase+ABLL); break;
+       switch_bank(iobase, SET2);
+       outb(0x00, iobase+ABHL);
+
+       switch (speed) {
+       case 9600:   outb(0x0c, iobase+ABLL); break;
+       case 19200:  outb(0x06, iobase+ABLL); break;
+       case 37600:  outb(0x03, iobase+ABLL); break;
+       case 57600:  outb(0x02, iobase+ABLL); break;
+       case 115200: outb(0x01, iobase+ABLL); break;
        case 576000:
                ir_mode = HCR_MIR_576;
                DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
@@ -419,34 +425,37 @@ void w83977af_change_speed( struct irda_device *idev, int speed)
                break;
        default:
                ir_mode = HCR_FIR;
-               DEBUG( 0, __FUNCTION__ "(), unknown baud rate of %d\n", speed);
+               DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", speed);
                break;
        }
 
        /* Set speed mode */
        switch_bank(iobase, SET0);
-       outb( ir_mode, iobase+HCR);
+       outb(ir_mode, iobase+HCR);
 
        /* set FIFO size to 32 */
-       switch_bank( iobase, SET2);
-       outb( ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2); 
+       switch_bank(iobase, SET2);
+       outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);  
        
        /* set FIFO threshold to TX17, RX16 */
        switch_bank(iobase, SET0);
-       outb(UFR_RXTL|UFR_TXTL|UFR_TXF_RST|UFR_RXF_RST|UFR_EN_FIFO, iobase+UFR);
-       
+
+       outb(0x00, iobase+UFR);        /* Reset */
+       outb(UFR_EN_FIFO, iobase+UFR); /* First we must enable FIFO */
+       outb(0xa7, iobase+UFR);
+
        idev->netdev.tbusy = 0;
        
        /* Enable some interrupts so we can receive frames */
        switch_bank(iobase, SET0);
-       if ( speed > 115200) {
-               outb( ICR_EFSFI, iobase+ICR);
-               w83977af_dma_receive( idev);
+       if (speed > PIO_MAX_SPEED) {
+               outb(ICR_EFSFI, iobase+ICR);
+               w83977af_dma_receive(idev);
        } else
-               outb( ICR_ERBRI, iobase+ICR);
+               outb(ICR_ERBRI, iobase+ICR);
        
        /* Restore SSR */
-       outb( set, iobase+SSR);
+       outb(set, iobase+SSR);
 }
 
 /*
@@ -455,7 +464,7 @@ void w83977af_change_speed( struct irda_device *idev, int speed)
  *    Sets up a DMA transfer to send the current frame.
  *
  */
-int w83977af_hard_xmit( struct sk_buff *skb, struct device *dev)
+int w83977af_hard_xmit(struct sk_buff *skb, struct device *dev)
 {
        struct irda_device *idev;
        int iobase;
@@ -474,20 +483,21 @@ int w83977af_hard_xmit( struct sk_buff *skb, struct device *dev)
        /* Lock transmit buffer */
        if (irda_lock((void *) &dev->tbusy) == FALSE)
                return -EBUSY;
-       
+
        /* Save current set */
        set = inb(iobase+SSR);
        
        /* Decide if we should use PIO or DMA transfer */
-       if (idev->io.baudrate > 115200) {
+       if (idev->io.baudrate > PIO_MAX_SPEED) {
+               idev->tx_buff.data = idev->tx_buff.head;
                memcpy(idev->tx_buff.data, skb->data, skb->len);
                idev->tx_buff.len = skb->len;
-               idev->tx_buff.data = idev->tx_buff.head;
                
                mtt = irda_get_mtt(skb);
+#ifdef CONFIG_USE_INTERNAL_TIMER
                if (mtt > 50) {
                        /* Adjust for timer resolution */
-                       mtt = mtt / 1000 + 1;
+                       mtt /= 1000+1;
 
                        /* Setup timer */
                        switch_bank(iobase, SET4);
@@ -502,6 +512,8 @@ int w83977af_hard_xmit( struct sk_buff *skb, struct device *dev)
                        switch_bank(iobase, SET0);
                        outb(ICR_ETMRI, iobase+ICR);
                } else {
+#endif
+                       DEBUG(4,__FUNCTION__ "(%ld), mtt=%d\n", jiffies, mtt);
                        if (mtt)
                                udelay(mtt);
 
@@ -509,7 +521,9 @@ int w83977af_hard_xmit( struct sk_buff *skb, struct device *dev)
                        switch_bank(iobase, SET0);
                        outb(ICR_EDMAI, iobase+ICR);
                        w83977af_dma_write(idev, iobase);
+#ifdef CONFIG_USE_INTERNAL_TIMER
                }
+#endif
        } else {
                idev->tx_buff.data = idev->tx_buff.head;
                idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, 
@@ -527,41 +541,57 @@ int w83977af_hard_xmit( struct sk_buff *skb, struct device *dev)
        return 0;
 }
 
-
 /*
  * Function w83977af_dma_write (idev, iobase)
  *
- *    
+ *    Send frame using DMA
  *
  */
-static void w83977af_dma_write( struct irda_device *idev, int iobase)
+static void w83977af_dma_write(struct irda_device *idev, int iobase)
 {
        __u8 set;
-
-        DEBUG( 4, __FUNCTION__ "()\n");
+#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
+       unsigned long flags;
+       __u8 hcr;
+#endif
+        DEBUG(4, __FUNCTION__ "(), len=%d\n", idev->tx_buff.len);
 
        /* Save current set */
-       set = inb( iobase+SSR);
+       set = inb(iobase+SSR);
 
        /* Disable DMA */
        switch_bank(iobase, SET0);
-       outb( inb( iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
-       
-       setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len, 
-                 DMA_MODE_WRITE);
-       
-       /* idev->media_busy = TRUE; */
-       idev->io.direction = IO_XMIT;
-       
+       outb(inb(iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
+
        /* Choose transmit DMA channel  */ 
        switch_bank(iobase, SET2);
-       outb(inb(iobase+ADCR1) | ADCR1_D_CHSW|ADCR1_DMA_F|ADCR1_ADV_SL, 
-            iobase+ADCR1);
+       outb(ADCR1_D_CHSW|/*ADCR1_DMA_F|*/ADCR1_ADV_SL, iobase+ADCR1);
+#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
+       save_flags(flags);
+       cli();
+
+       disable_dma(idev->io.dma);
+       clear_dma_ff(idev->io.dma);
+       set_dma_mode(idev->io.dma, DMA_MODE_READ);
+       set_dma_addr(idev->io.dma, virt_to_bus(idev->tx_buff.data));
+       set_dma_count(idev->io.dma, idev->tx_buff.len);
+#else
+       setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len, 
+                 DMA_MODE_WRITE);      
+#endif
+       idev->io.direction = IO_XMIT;
        
        /* Enable DMA */
        switch_bank(iobase, SET0);
-       outb(inb(iobase+HCR) | HCR_EN_DMA, iobase+HCR);
-       
+#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
+       hcr = inb(iobase+HCR);
+       outb(hcr | HCR_EN_DMA, iobase+HCR);
+       enable_dma(idev->io.dma);
+       restore_flags(flags);
+#else  
+       outb(inb(iobase+HCR) | HCR_EN_DMA | HCR_TX_WT, iobase+HCR);
+#endif
+
        /* Restore set register */
        outb(set, iobase+SSR);
 }
@@ -577,17 +607,17 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
        int actual = 0;
        __u8 set;
        
-       DEBUG( 4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
 
        /* Save current bank */
-       set = inb( iobase+SSR);
+       set = inb(iobase+SSR);
 
-       switch_bank( iobase, SET0);
+       switch_bank(iobase, SET0);
        if (!(inb_p(iobase+USR) & USR_TSRE)) {
-               DEBUG( 4, __FUNCTION__ "(), warning, FIFO not empty yet!\n");
+               DEBUG(4, __FUNCTION__ "(), warning, FIFO not empty yet!\n");
 
                fifo_size -= 17;
-               DEBUG( 4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size);
+               DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size);
        }
 
        /* Fill FIFO with current frame */
@@ -597,7 +627,7 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
        }
         
        DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", 
-             fifo_size, actual, len);
+              fifo_size, actual, len);
 
        /* Restore bank */
        outb(set, iobase+SSR);
@@ -617,7 +647,7 @@ void w83977af_dma_xmit_complete(struct irda_device *idev)
        int iobase;
        __u8 set;
 
-       DEBUG(4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "(%ld)\n", jiffies);
 
        ASSERT(idev != NULL, return;);
        ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
@@ -663,9 +693,10 @@ void w83977af_dma_xmit_complete(struct irda_device *idev)
  */
 int w83977af_dma_receive(struct irda_device *idev) 
 {
+       struct w83977af_ir *self;
        int iobase;
        __u8 set;
-#ifdef NETWINDER
+#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
        unsigned long flags;
        __u8 hcr;
 #endif
@@ -673,62 +704,60 @@ int w83977af_dma_receive(struct irda_device *idev)
        ASSERT(idev != NULL, return -1;);
        ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
 
-       DEBUG(0, __FUNCTION__ "\n");
+       DEBUG(4, __FUNCTION__ "\n");
 
+       self = idev->priv;
        iobase= idev->io.iobase;
 
        /* Save current set */
-       set = inb( iobase+SSR);
+       set = inb(iobase+SSR);
 
        /* Disable DMA */
-       switch_bank( iobase, SET0);
-       outb( inb( iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
+       switch_bank(iobase, SET0);
+       outb(inb(iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
 
-#ifdef NETWINDER
+       /* Choose DMA Rx, DMA Fairness, and Advanced mode */
+       switch_bank(iobase, SET2);
+       outb((inb(iobase+ADCR1) & ~ADCR1_D_CHSW)/*|ADCR1_DMA_F*/|ADCR1_ADV_SL,
+            iobase+ADCR1);
+
+       idev->io.direction = IO_RECV;
+       idev->rx_buff.data = idev->rx_buff.head;
+
+#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
        save_flags(flags);
        cli();
 
-       disable_dma( idev->io.dma);
-       clear_dma_ff( idev->io.dma);
-       set_dma_mode( idev->io.dma, DMA_MODE_READ);
-       set_dma_addr( idev->io.dma, virt_to_bus(idev->rx_buff.data));
-       set_dma_count( idev->io.dma, idev->rx_buff.truesize);
+       disable_dma(idev->io.dma);
+       clear_dma_ff(idev->io.dma);
+       set_dma_mode(idev->io.dma, DMA_MODE_READ);
+       set_dma_addr(idev->io.dma, virt_to_bus(idev->rx_buff.data));
+       set_dma_count(idev->io.dma, idev->rx_buff.truesize);
 #else
-       setup_dma(idev->io.dma, idev->rx_buff.data, 
-                 idev->rx_buff.truesize, DMA_MODE_READ);
+       setup_dma(idev->io.dma, idev->rx_buff.data, idev->rx_buff.truesize, 
+                 DMA_MODE_READ);
 #endif
-       /* driver->media_busy = FALSE; */
-       idev->io.direction = IO_RECV;
-       idev->rx_buff.data = idev->rx_buff.head;
-
        /* 
         * Reset Rx FIFO. This will also flush the ST_FIFO, it's very 
         * important that we don't reset the Tx FIFO since it might not
         * be finished transmitting yet
         */
-       outb( UFR_RXTL|UFR_TXTL|UFR_RXF_RST|UFR_EN_FIFO, iobase+UFR);
-       prev.status = 0;
-
-       /* Choose DMA Rx, DMA Fairness, and Advanced mode */
-       switch_bank(iobase, SET2);
-       outb(( inb( iobase+ADCR1) & ~ADCR1_D_CHSW)|ADCR1_DMA_F|ADCR1_ADV_SL,
-            iobase+ADCR1);
+       switch_bank(iobase, SET0);
+       outb(UFR_RXTL|UFR_TXTL|UFR_RXF_RST|UFR_EN_FIFO, iobase+UFR);
+       self->st_fifo.len = self->st_fifo.tail = self->st_fifo.head = 0;
        
        /* Enable DMA */
        switch_bank(iobase, SET0);
-#ifdef NETWINDER
-       hcr = inb( iobase+HCR);
-       enable_dma( idev->io.dma);
-       outb( hcr | HCR_EN_DMA, iobase+HCR);
+#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
+       hcr = inb(iobase+HCR);
+       outb(hcr | HCR_EN_DMA, iobase+HCR);
+       enable_dma(idev->io.dma);
        restore_flags(flags);
 #else  
-       outb( inb( iobase+HCR) | HCR_EN_DMA, iobase+HCR);
+       outb(inb(iobase+HCR) | HCR_EN_DMA, iobase+HCR);
 #endif
-       
        /* Restore set */
-       outb( set, iobase+SSR);
-
-       DEBUG( 4, __FUNCTION__ "(), done!\n");  
+       outb(set, iobase+SSR);
 
        return 0;
 }
@@ -742,12 +771,17 @@ int w83977af_dma_receive(struct irda_device *idev)
 int w83977af_dma_receive_complete(struct irda_device *idev)
 {
        struct sk_buff *skb;
+       struct w83977af_ir *self;
+       struct st_fifo *st_fifo;
        int len;
        int iobase;
        __u8 set;
        __u8 status;
 
-       DEBUG(0, __FUNCTION__ "\n");
+       DEBUG(4, __FUNCTION__ "\n");
+
+       self = idev->priv;
+       st_fifo = &self->st_fifo;
 
        iobase = idev->io.iobase;
 
@@ -756,22 +790,28 @@ int w83977af_dma_receive_complete(struct irda_device *idev)
        
        iobase = idev->io.iobase;
 
+       /* Read status FIFO */
        switch_bank(iobase, SET5);
-       if (prev.status & FS_FO_FSFDR) {
-               status = prev.status;
-               len = prev.len;
+       while ((status = inb(iobase+FS_FO)) & FS_FO_FSFDR) {
+               st_fifo->entries[st_fifo->tail].status = status;
                
-               prev.status = 0;
-       } else {
-               status = inb(iobase+FS_FO);
-               len = inb(iobase+RFLFL);
-               len |= inb(iobase+RFLFH) << 8;
+               st_fifo->entries[st_fifo->tail].len  = inb(iobase+RFLFL);
+               st_fifo->entries[st_fifo->tail].len |= inb(iobase+RFLFH) << 8;
+               
+               st_fifo->tail++;
+               st_fifo->len++;
        }
+       
+       while (st_fifo->len) {
+               /* Get first entry */
+               status = st_fifo->entries[st_fifo->head].status;
+               len    = st_fifo->entries[st_fifo->head].len;
+               st_fifo->head++;
+               st_fifo->len--;
 
-       while (status & FS_FO_FSFDR) {
                /* Check for errors */
                if (status & FS_FO_ERR_MSK) {
-                       if ( status & FS_FO_LST_FR) {
+                       if (status & FS_FO_LST_FR) {
                                /* Add number of lost frames to stats */
                                idev->stats.rx_errors += len;   
                        } else {
@@ -800,14 +840,20 @@ int w83977af_dma_receive_complete(struct irda_device *idev)
                        /* Check if we have transfered all data to memory */
                        switch_bank(iobase, SET0);
                        if (inb(iobase+USR) & USR_RDR) {
+#ifdef CONFIG_USE_INTERNAL_TIMER
                                /* Put this entry back in fifo */
-                               prev.status = status;
-                               prev.len = len;
-
+                               st_fifo->head--;
+                               st_fifo->len++;
+                               st_fifo->entries[st_fifo->head].status = status;
+                               st_fifo->entries[st_fifo->head].len = len;
+                               
                                /* Restore set register */
-                               outb( set, iobase+SSR);
+                               outb(set, iobase+SSR);
                        
                                return FALSE;   /* I'll be back! */
+#else
+                               udelay(80); /* Should be enough!? */
+#endif
                        }
                                                
                        skb = dev_alloc_skb(len+1);
@@ -824,28 +870,23 @@ int w83977af_dma_receive_complete(struct irda_device *idev)
                        skb_reserve(skb, 1); 
                        
                        /* Copy frame without CRC */
-                       if ( idev->io.baudrate < 4000000) {
-                               skb_put( skb, len-2);
-                               memcpy( skb->data, idev->rx_buff.data, len-2);
+                       if (idev->io.baudrate < 4000000) {
+                               skb_put(skb, len-2);
+                               memcpy(skb->data, idev->rx_buff.data, len-2);
                        } else {
-                               skb_put( skb, len-4);
-                               memcpy( skb->data, idev->rx_buff.data, len-4);
+                               skb_put(skb, len-4);
+                               memcpy(skb->data, idev->rx_buff.data, len-4);
                        }
 
                        /* Move to next frame */
                        idev->rx_buff.data += len;
+                       idev->stats.rx_packets++;
                        
                        skb->dev = &idev->netdev;
                        skb->mac.raw  = skb->data;
                        skb->protocol = htons(ETH_P_IRDA);
-                       netif_rx( skb);
-                       idev->stats.rx_packets++;
+                       netif_rx(skb);
                }
-               /* Read next entry in ST_FIFO */
-               switch_bank(iobase, SET5);
-               status = inb( iobase+FS_FO);
-               len = inb( iobase+RFLFL);
-               len |= inb( iobase+RFLFH) << 8;
        }
        /* Restore set register */
        outb(set, iobase+SSR);
@@ -875,7 +916,6 @@ static void w83977af_pio_receive(struct irda_device *idev)
        do {
                byte = inb(iobase+RBR);
                async_unwrap_char(idev, byte);
-
        } while (inb(iobase+USR) & USR_RDR); /* Data available */       
 }
 
@@ -889,9 +929,12 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr)
 {
        int actual;
        __u8 new_icr = 0;
+       __u8 set;
+       int iobase;
 
        DEBUG(4, __FUNCTION__ "(), isr=%#x\n", isr);
        
+       iobase = idev->io.iobase;
        /* Transmit FIFO low on data */
        if (isr & ISR_TXTH_I) {
                /* Write data left in transmit buffer */
@@ -899,16 +942,21 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr)
                                            idev->tx_buff.data, 
                                            idev->tx_buff.len, 
                                            idev->io.fifo_size);
+
                idev->tx_buff.data += actual;
                idev->tx_buff.len  -= actual;
                
                idev->io.direction = IO_XMIT;
 
                /* Check if finished */
-               if (idev->tx_buff.len > 0)
+               if (idev->tx_buff.len > 0) {
                        new_icr |= ICR_ETXTHI;
-               else { 
-                       DEBUG( 4, __FUNCTION__ "(), finished with frame!\n");
+               } else {
+                       set = inb(iobase+SSR);
+                       switch_bank(iobase, SET0);
+                       outb(AUDR_SFEND, iobase+AUDR);
+                       outb(set, iobase+SSR); 
+
                        idev->netdev.tbusy = 0; /* Unlock */
                        idev->stats.tx_packets++;
 
@@ -917,7 +965,6 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr)
 
                        new_icr |= ICR_ETBREI;
                }
-               
        }
        /* Check if transmission has completed */
        if (isr & ISR_TXEMP_I) {
@@ -943,22 +990,20 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr)
  *    Handle MIR/FIR interrupt
  *
  */
-static __u8 w83977af_fir_interrupt( struct irda_device *idev, int isr)
+static __u8 w83977af_fir_interrupt(struct irda_device *idev, int isr)
 {
        __u8 new_icr = 0;
        __u8 set;
        int iobase;
 
-       DEBUG( 4, __FUNCTION__ "(), isr=%#x\n", isr);
-
        iobase = idev->io.iobase;
-
        set = inb(iobase+SSR);
        
        /* End of frame detected in FIFO */
        if (isr & (ISR_FEND_I|ISR_FSF_I)) {
                if (w83977af_dma_receive_complete(idev)) {
                        
+                       /* Wait for next status FIFO interrupt */
                        new_icr |= ICR_EFSFI;
                } else {
                        /* DMA not finished yet */
@@ -982,7 +1027,7 @@ static __u8 w83977af_fir_interrupt( struct irda_device *idev, int isr)
 
                /* Clear timer event */
                /* switch_bank(iobase, SET0); */
-/*             outb( ASCR_CTE, iobase+ASCR); */
+/*             outb(ASCR_CTE, iobase+ASCR); */
 
                /* Check if this is a TX timer interrupt */
                if (idev->io.direction == IO_XMIT) {
@@ -998,15 +1043,18 @@ static __u8 w83977af_fir_interrupt( struct irda_device *idev, int isr)
        }       
        /* Finished with DMA */
        if (isr & ISR_DMA_I) {
-               w83977af_dma_xmit_complete( idev);
-               
+               w83977af_dma_xmit_complete(idev);
+
                /* Check if there are more frames to be transmitted */
-               if (irda_device_txqueue_empty( idev)) {
+               /* if (irda_device_txqueue_empty(idev)) { */
                
-                       /* Prepare for receive */
-                       w83977af_dma_receive(idev);
-                       new_icr = ICR_EFSFI;
-               }
+               /* Prepare for receive 
+                * 
+                * ** Netwinder Tx DMA likes that we do this anyway **
+                */
+               w83977af_dma_receive(idev);
+               new_icr = ICR_EFSFI;
+              /* } */
        }
        
        /* Restore set */
@@ -1030,7 +1078,7 @@ static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        if (idev == NULL) {
                printk(KERN_WARNING "%s: irq %d for unknown device.\n", 
-                      driver_name, irq);
+                       driver_name, irq);
                return;
        }
 
@@ -1049,7 +1097,7 @@ static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        
        if (isr) {
                /* Dispatch interrupt handler for the current speed */
-               if ( idev->io.baudrate > 115200)
+               if (idev->io.baudrate > PIO_MAX_SPEED )
                        icr = w83977af_fir_interrupt(idev, isr);
                else
                        icr = w83977af_sir_interrupt(idev, isr);
@@ -1070,7 +1118,7 @@ static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static void w83977af_wait_until_sent(struct irda_device *idev)
 {
        current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout(6);
+       schedule_timeout(60*HZ/1000);
 }
 
 /*
@@ -1085,16 +1133,16 @@ static int w83977af_is_receiving(struct irda_device *idev)
        int iobase;
        __u8 set;
 
-       ASSERT( idev != NULL, return FALSE;);
-       ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return FALSE;);
+       ASSERT(idev != NULL, return FALSE;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return FALSE;);
 
-       if ( idev->io.baudrate > 115200) {
+       if (idev->io.baudrate > 115200) {
                iobase = idev->io.iobase;
 
                /* Check if rx FIFO is not empty */
                set = inb(iobase+SSR);
-               switch_bank( iobase, SET2);
-               if (( inb( iobase+RXFDTH) & 0x3f) != 0) {
+               switch_bank(iobase, SET2);
+               if ((inb(iobase+RXFDTH) & 0x3f) != 0) {
                        /* We are receiving something */
                        status =  TRUE;
                }
@@ -1111,12 +1159,12 @@ static int w83977af_is_receiving(struct irda_device *idev)
  *    
  *
  */
-static int w83977af_net_init( struct device *dev)
+static int w83977af_net_init(struct device *dev)
 {
        DEBUG(0, __FUNCTION__ "()\n");
 
        /* Set up to be a normal IrDA network device driver */
-       irda_device_setup( dev);
+       irda_device_setup(dev);
 
        /* Insert overrides below this line! */
 
@@ -1130,7 +1178,7 @@ static int w83977af_net_init( struct device *dev)
  *    Start the device
  *
  */
-static int w83977af_net_open( struct device *dev)
+static int w83977af_net_open(struct device *dev)
 {
        struct irda_device *idev;
        int iobase;
@@ -1147,7 +1195,7 @@ static int w83977af_net_open( struct device *dev)
        iobase = idev->io.iobase;
 
        if (request_irq(idev->io.irq, w83977af_interrupt, 0, idev->name, 
-                       (void *) idev)) {
+                        (void *) idev)) {
                return -EAGAIN;
        }
        /*
@@ -1170,13 +1218,13 @@ static int w83977af_net_open( struct device *dev)
        /* Enable some interrupts so we can receive frames again */
        switch_bank(iobase, SET0);
        if (idev->io.baudrate > 115200) {
-               outb( ICR_EFSFI, iobase+ICR);
-               w83977af_dma_receive( idev);
+               outb(ICR_EFSFI, iobase+ICR);
+               w83977af_dma_receive(idev);
        } else
-               outb( ICR_ERBRI, iobase+ICR);
+               outb(ICR_ERBRI, iobase+ICR);
 
        /* Restore bank register */
-       outb( set, iobase+SSR);
+       outb(set, iobase+SSR);
 
        MOD_INC_USE_COUNT;
 
@@ -1195,34 +1243,34 @@ static int w83977af_net_close(struct device *dev)
        int iobase;
        __u8 set;
 
-       DEBUG( 0, __FUNCTION__ "()\n");
+       DEBUG(0, __FUNCTION__ "()\n");
        
        /* Stop device */
        dev->tbusy = 1;
        dev->start = 0;
 
-       ASSERT( dev != NULL, return -1;);
+       ASSERT(dev != NULL, return -1;);
        idev = (struct irda_device *) dev->priv;
        
-       ASSERT( idev != NULL, return 0;);
-       ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+       ASSERT(idev != NULL, return 0;);
+       ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;);
        
        iobase = idev->io.iobase;
 
-       disable_dma( idev->io.dma);
+       disable_dma(idev->io.dma);
 
        /* Save current set */
-       set = inb( iobase+SSR);
+       set = inb(iobase+SSR);
        
        /* Disable interrupts */
-       switch_bank( iobase, SET0);
-       outb( 0, iobase+ICR); 
+       switch_bank(iobase, SET0);
+       outb(0, iobase+ICR); 
 
-       free_irq( idev->io.irq, idev);
-       free_dma( idev->io.dma);
+       free_irq(idev->io.irq, idev);
+       free_dma(idev->io.dma);
 
        /* Restore bank register */
-       outb( set, iobase+SSR);
+       outb(set, iobase+SSR);
 
        MOD_DEC_USE_COUNT;
 
@@ -1231,6 +1279,11 @@ static int w83977af_net_close(struct device *dev)
 
 #ifdef MODULE
 
+MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
+MODULE_DESCRIPTION("Winbond W83977AF IrDA Device Driver");
+
+MODULE_PARM(qos_mtt_bits, "i");
+
 /*
  * Function init_module (void)
  *
index 580fb2dcad9b33e3f7c7ee471ff46ae482c36a1a..f618fd5fb08bf08a72b483853a42adcd5bca8ef5 100644 (file)
@@ -1834,7 +1834,7 @@ static inline void sun4c_happy_meal_tx(struct happy_meal *hp)
 #define RXD(x)
 #endif
 
-/* Originally I use to handle the allocation failure by just giving back just
+/* Originally I used to handle the allocation failure by just giving back just
  * that one ring buffer to the happy meal.  Problem is that usually when that
  * condition is triggered, the happy meal expects you to do something reasonable
  * with all of the packets it has DMA'd in.  So now I just drop the entire
index a62fd12adc1da0209042fdc50b55dc76ee550b01..e1a692e164e29d4f97a89776fbd601b5f2a13cb6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgsixfb.c,v 1.16 1999/03/09 14:01:49 davem Exp $
+/* $Id: cgsixfb.c,v 1.16.2.1 1999/05/25 00:59:35 davem Exp $
  * cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
  *
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -588,7 +588,7 @@ static void cg6_margins (struct fb_info_sbusfb *fb, struct display *p, int x_mar
        p->screen_base += (y_margin - fb->y_margin) * p->line_length + (x_margin - fb->x_margin);
 }
 
-static char idstring[60] __initdata = { 0 };
+static char idstring[70] __initdata = { 0 };
 
 __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
 {
@@ -599,6 +599,7 @@ __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
        unsigned long phys = fb->sbdp->reg_addrs[0].phys_addr;
        u32 conf;
        char *p;
+       char *cardtype;
        struct bt_regs *bt;
 
        strcpy(fb->info.modename, "CGsix");
@@ -656,15 +657,29 @@ __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
        case CG6_FHC_CPU_68020: p = "68020"; break;
        default: p = "i386"; break;
        }
+
+       if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) {
+               if (fix->smem_len <= 0x100000) {
+                       cardtype = "TurboGX";
+               } else {
+                       cardtype = "TurboGX+";
+               }
+       } else {
+               if (fix->smem_len <= 0x100000) {
+                       cardtype = "GX";
+               } else {
+                       cardtype = "GX+";
+               }
+       }
                                                                                
        sprintf(idstring, 
 #ifdef __sparc_v9__
-                   "cgsix at %016lx TEC Rev %x CPU %s Rev %x", phys, 
+                   "cgsix at %016lx TEC Rev %x CPU %s Rev %x [%s]", phys, 
 #else  
-                   "cgsix at %x.%08lx TEC Rev %x CPU %s Rev %x", fb->iospace, phys, 
+                   "cgsix at %x.%08lx TEC Rev %x CPU %s Rev %x [%s]", fb->iospace, phys, 
 #endif
                    (fb->s.cg6.thc->thc_misc >> CG6_THC_MISC_REV_SHIFT) & CG6_THC_MISC_REV_MASK,
-                   p, conf >> CG6_FHC_REV_SHIFT & CG6_FHC_REV_MASK);
+                   p, conf >> CG6_FHC_REV_SHIFT & CG6_FHC_REV_MASK, cardtype);
                    
        cg6_reset(fb);
                    
index 2e4d2812cf0458957aaa1ea3d2218e1b5c85caf7..4e75eede0e70b07bdd4c09e1387b39479dcfcf28 100644 (file)
@@ -162,7 +162,7 @@ static ssize_t ext2_file_write (struct file * filp, const char * buf,
        struct buffer_head * bh, *bufferlist[NBUF];
        struct super_block * sb;
        int err;
-       int i,buffercount,write_error;
+       int i,buffercount,write_error, new_buffer;
 
        /* POSIX: mtime/ctime may not change for 0 count */
        if (!count)
@@ -247,30 +247,59 @@ static ssize_t ext2_file_write (struct file * filp, const char * buf,
                }
                if (c > count)
                        c = count;
-               if (c != sb->s_blocksize && !buffer_uptodate(bh)) {
-                       ll_rw_block (READ, 1, &bh);
-                       wait_on_buffer (bh);
-                       if (!buffer_uptodate(bh)) {
-                               brelse (bh);
+
+               /* Tricky: what happens if we are writing the complete
+                * contents of a block which is not currently
+                * initialised?  We have to obey the same
+                * synchronisation rules as the IO code, to prevent some
+                * other process from stomping on the buffer contents by
+                * refreshing them from disk while we are setting up the
+                * buffer.  The copy_from_user() can page fault, after
+                * all.  We also have to throw away partially successful
+                * copy_from_users to such buffers, since we can't trust
+                * the rest of the buffer_head in that case.  --sct */
+
+               new_buffer = (!buffer_uptodate(bh) && !buffer_locked(bh) &&
+                             c == sb->s_blocksize);
+
+               if (new_buffer) {
+                       set_bit(BH_Lock, &bh->b_state);
+                       c -= copy_from_user (bh->b_data + offset, buf, c);
+                       if (c != sb->s_blocksize) {
+                               c = 0;
+                               unlock_buffer(bh);
+                               brelse(bh);
                                if (!written)
-                                       written = -EIO;
+                                       written = -EFAULT;
                                break;
                        }
+                       mark_buffer_uptodate(bh, 1);
+                       unlock_buffer(bh);
+               } else {
+                       if (!buffer_uptodate(bh)) {
+                               ll_rw_block (READ, 1, &bh);
+                               wait_on_buffer (bh);
+                               if (!buffer_uptodate(bh)) {
+                                       brelse (bh);
+                                       if (!written)
+                                               written = -EIO;
+                                       break;
+                               }
+                       }
+                       c -= copy_from_user (bh->b_data + offset, buf, c);
                }
-               c -= copy_from_user (bh->b_data + offset, buf, c);
                if (!c) {
                        brelse(bh);
                        if (!written)
                                written = -EFAULT;
                        break;
                }
+               mark_buffer_dirty(bh, 0);
                update_vm_cache(inode, pos, bh->b_data + offset, c);
                pos += c;
                written += c;
                buf += c;
                count -= c;
-               mark_buffer_uptodate(bh, 1);
-               mark_buffer_dirty(bh, 0);
 
                if (filp->f_flags & O_SYNC)
                        bufferlist[buffercount++] = bh;
index f93de5ffbacfed7618b90e34d34bb21d060cf840..cfdf49f6e2f51ea86c09c8adb8d772ba69dcfc7d 100644 (file)
@@ -601,8 +601,6 @@ init_module(void)
        smb_current_vmalloced = 0;
 #endif
 
-       read_semaphore = MUTEX;
-
        return init_smb_fs();
 }
 
index d4ee011e4ef5203d308b0e1ab92193e186361d4a..61a5a648864d5bd0e0f8a1b7d391f7f929fd6d08 100644 (file)
@@ -6,25 +6,28 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Tue Dec 15 22:18:53 1998
+ * Modified at:   Sun May  2 20:25:23 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  ********************************************************************/
 
-#ifndef IR_CRC_H
-#define IR_CRC_H
+#ifndef IRDA_CRC_H
+#define IRDA_CRC_H
 
 #include <linux/types.h>
 
 #define INIT_FCS  0xffff   /* Initial FCS value */
 #define GOOD_FCS  0xf0b8   /* Good final FCS value */
 
+extern __u16 const irda_crc16_table[];
+
 /* Recompute the FCS with one more character appended. */
-#define IR_FCS(fcs, c) (((fcs) >> 8) ^ irda_crc16_table[((fcs) ^ (c)) & 0xff])
+static inline __u16 irda_fcs(__u16 fcs, __u8 c)
+{
+       return (((fcs) >> 8) ^ irda_crc16_table[((fcs) ^ (c)) & 0xff]);
+}
 
 /* Recompute the FCS with len bytes appended. */
 unsigned short crc_calc( __u16 fcs, __u8 const *buf, size_t len);
 
-extern __u16 const irda_crc16_table[];
-
 #endif
index d8983c009d2c0d1791478918368bbeba7ba7ff8d..64496d67191e7fb7c21e470338d6498fb413194b 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Wed Oct 21 22:47:12 1998
- * Modified at:   Sat Feb  6 07:37:49 1999
+ * Modified at:   Mon May 10 14:51:06 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -26,7 +26,6 @@
 #define DONGLE_H
 
 #include <net/irda/qos.h>
-#include <net/irda/irda_device.h>
 
 /* These are the currently known dongles */
 typedef enum {
@@ -35,8 +34,11 @@ typedef enum {
        ACTISYS_DONGLE,
        ACTISYS_PLUS_DONGLE,
        GIRBIL_DONGLE,
+       LITELINK_DONGLE,
 } DONGLE_T;
 
+struct irda_device;
+
 struct dongle {
        DONGLE_T type;
        void (*open)(struct irda_device *, int type);
index cd1c41f86818ec711db4395d1f634bf4a5e49f01..2319017ccefcbed737754bc6e7d0c68f6f72e957 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Takahide Higuchi <thiguchi@pluto.dti.ne.jp>
  *
- *     Copyright (c) 1998, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
+ *     Copyright (c) 1998-1999, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
  *     All Rights Reserved.
  *
  *     This program is free software; you can redistribute it and/or
@@ -78,7 +78,7 @@ typedef enum {
 #define IRCOMM_MAGIC            0x434f4d4d
 #define COMM_INIT_CTRL_PARAM    3          /* length of initial control parameters */
 #define COMM_HEADER             1          /* length of clen field */
-#define COMM_HEADER_SIZE        (LAP_HEADER+LMP_HEADER+TTP_HEADER+COMM_HEADER)
+#define COMM_HEADER_SIZE        (TTP_MAX_HEADER+COMM_HEADER)
 #define COMM_DEFAULT_DATA_SIZE  64
 #define IRCOMM_MAX_CONNECTION   1          /* Don't change for now */
 
@@ -167,7 +167,7 @@ typedef enum {
 #define LSR_BI     0x01    /* Break interrupt indicator */
 
 
-struct ircomm_cb{
+struct ircomm_cb {
        int magic;
        int state;          /* Current state of IrCOMM layer: 
                             *  DISCOVERY,COMM_IDLE, COMM_WAITR,
@@ -178,7 +178,8 @@ struct ircomm_cb{
        int ttp_stop;
 
        int max_txbuff_size;          
-       __u32 maxsdusize;
+       __u32 max_sdu_size;
+       __u8 max_header_size;
 
        __u32 daddr;        /* Device address of the peer device */ 
        __u32 saddr;
@@ -211,8 +212,6 @@ struct ircomm_cb{
        int                 pending_control_tuples;
        int                 ignored_control_tuples;
 
-
-
        __u8 pi ;            /* instruction of control channel*/ 
 
        __u8 port_type;
@@ -253,8 +252,6 @@ struct ircomm_cb{
        int port_name_critical;
 };
 
-
-
 void ircomm_connect_request(struct ircomm_cb *self, __u8 servicetype);
 void ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata,
                             __u32 maxsdusize);
index 35c15fadc27237a1f57f641d4650501f40abc567..61f9352b2d2ddd87268ddcb957b9b7be1424f69a 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:13:12 1997
- * Modified at:   Wed Apr 21 17:49:00 1999
+ * Modified at:   Mon May 10 09:51:13 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -109,6 +109,8 @@ struct irda_sock {
        
        __u32 max_sdu_size_rx;
        __u32 max_sdu_size_tx;
+       __u32 max_data_size;
+       __u8  max_header_size;
        struct qos_info qos_tx;
 
        __u16 mask;           /* Hint bits mask */
@@ -225,10 +227,10 @@ struct notify_t {
        int (*udata_indication)(void *priv, void *sap, struct sk_buff *skb);
        void (*connect_confirm)(void *instance, void *sap, 
                                struct qos_info *qos, __u32 max_sdu_size,
-                               struct sk_buff *skb);
+                               __u8 max_header_size, struct sk_buff *skb);
        void (*connect_indication)(void *instance, void *sap, 
                                   struct qos_info *qos, __u32 max_sdu_size,
-                                  struct sk_buff *skb);
+                                  __u8 max_header_size, struct sk_buff *skb);
        void (*disconnect_indication)(void *instance, void *sap, 
                                      LM_REASON reason, struct sk_buff *);
        void (*flow_indication)(void *instance, void *sap, LOCAL_FLOW flow);
index a3dcf2d6e78ffb15886d92cb7705f123177a8bd4..21b12e4ff4e70441ffd6a2d7f8bb4f9f5a387685 100644 (file)
@@ -4,24 +4,29 @@
  * Version:       
  * Description:   
  * Status:        Experimental.
- * Author:        Haris Zukanovic <haris@stud.cs.uit.no>
+ * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Apr 14 12:41:42 1998
- * Modified at:   Tue Apr 20 11:06:28 1999
+ * Modified at:   Mon May 10 15:46:02 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Haris Zukanovic, <haris@stud.cs.uit.no>
- *     Copyright (c) 1998 Dag Brattli, <dagb@cs.uit.no>
+ *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
  *     Copyright (c) 1998 Thomas Davis, <ratbert@radiks.net>,
- *     All Rights Reserved.
- *      
+ *     Copyright (c) 1998 Haris Zukanovic, <haris@stud.cs.uit.no>
+ *
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
- *  
- *     Neither Haris Zukanovic nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
+ * 
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License 
+ *     along with this program; if not, write to the Free Software 
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ *     MA 02111-1307 USA
  *     
  ********************************************************************/
 
@@ -35,6 +40,7 @@
 
 #include <net/irda/irda.h>
 #include <net/irda/qos.h>
+#include <net/irda/dongle.h>
 #include <net/irda/irqueue.h>
 #include <net/irda/irlap_frame.h>
 
 #define IO_XMIT 0x01
 #define IO_RECV 0x02
 
+struct dongle_q {
+       QUEUE q;
+       struct dongle *dongle;
+};
+
 /* Chip specific info */
 struct chipio_t {
         int iobase, iobase2;  /* IO base */
@@ -111,6 +122,8 @@ struct irda_device {
        struct iobuff_t tx_buff;
        struct iobuff_t rx_buff;
 
+       struct dongle *dongle; /* Dongle driver */
+
        /* spinlock_t lock; */ /* For serializing operations */
        
        /* Media busy stuff */
@@ -120,7 +133,8 @@ struct irda_device {
        /* Callbacks for driver specific implementation */
         void (*change_speed)(struct irda_device *driver, int baud);
        int  (*is_receiving)(struct irda_device *);    /* receiving? */
-       /* int (*is_tbusy)(struct irda_device *); */   /* transmitting? */
+       void (*set_dtr_rts)(struct irda_device *idev, int dtr, int rts);
+       int  (*raw_write)(struct irda_device *idev, __u8 *buf, int len);
        void (*wait_until_sent)(struct irda_device *);
        void (*set_caddr)(struct irda_device *);      /* Set connection addr */
 };
@@ -142,6 +156,9 @@ inline void irda_device_change_speed(struct irda_device *, int);
 
 inline struct qos_info *irda_device_get_qos(struct irda_device *self);
 int irda_device_txqueue_empty(struct irda_device *self);
+void irda_device_init_dongle(struct irda_device *self, int type);
+void irda_device_unregister_dongle(struct dongle *dongle);
+int irda_device_register_dongle(struct dongle *dongle);
 
 int irda_device_setup(struct device *dev);
 
@@ -153,7 +170,7 @@ void setup_dma(int channel, char *buffer, int count, int mode);
  *    Utility function for getting the minimum turnaround time out of 
  *    the skb, where it has been hidden in the cb field.
  */
-inline static __u16 irda_get_mtt(struct sk_buff *skb)
+extern inline __u16 irda_get_mtt(struct sk_buff *skb)
 {
        __u16 mtt;
 
@@ -167,6 +184,23 @@ inline static __u16 irda_get_mtt(struct sk_buff *skb)
        return mtt;
 }
 
+extern inline void irda_device_set_dtr_rts(struct irda_device *self, int dtr,
+                                          int rts)
+{
+       if (self->set_dtr_rts)
+               self->set_dtr_rts(self, dtr, rts);
+}
+
+extern inline int irda_device_raw_write(struct irda_device *self, __u8 *buf,
+                                       int len)
+{
+       int ret = -1;
+
+       if (self->raw_write)
+               ret = self->raw_write(self, buf, len);
+       return ret;
+}
+
 #endif
 
 
index 071ed8561b0c4ea225e0e12f03d20686f9fca716..355751afa05746a8131edc46eef0c798d45c6ebf 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Wed Apr 21 16:37:21 1999
+ * Modified at:   Sun May  9 10:56:57 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -81,6 +81,8 @@ struct iriap_cb {
        CONFIRM_CALLBACK confirm;
        void *priv;
 
+       __u8 max_header_size;
+       
        struct timer_list watchdog_timer;
 };
 
@@ -92,8 +94,6 @@ void iriap_getvaluebyclass_request( char *name, char *attr,
 void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb);
 
 void iriap_send_ack( struct iriap_cb *self);
-void iriap_connect_confirm(void *instance, void *sap, struct qos_info *qos, 
-                          __u32 max_sdu_size, struct sk_buff *skb);
 void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb);
 
 void iriap_register_server(void);
index 35d83096faf55907a468b02fc6b0da13727373ab..131e3f9235a0010c36a5c6fda14518dbed891536 100644 (file)
@@ -6,10 +6,11 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Apr 22 14:30:37 1999
+ * Modified at:   Sun May  9 11:45:33 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -98,7 +99,7 @@
 #define IRLAN_SHORT  1
 #define IRLAN_ARRAY  2
 
-#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_HEADER)
+#define IRLAN_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_MAX_HEADER)
 
 /*
  *  IrLAN client
@@ -109,7 +110,10 @@ struct irlan_client_cb {
        int open_retries;
 
        struct tsap_cb *tsap_ctrl;
+       __u32 max_sdu_size;
+       __u8  max_header_size;
        
+       int access_type;         /* Access type of provider */
        __u8 reconnect_key[255];
        __u8 key_len;
        
@@ -130,6 +134,8 @@ struct irlan_provider_cb {
        int state;
        
        struct tsap_cb *tsap_ctrl;
+       __u32 max_sdu_size;
+       __u8  max_header_size;
 
        /*
         *  Store some values here which are used by the provider to parse
@@ -140,42 +146,45 @@ struct irlan_provider_cb {
        int filter_mode;
        int filter_operation;
        int filter_entry;
-
+       int access_type;     /* Access type */
        __u16 send_arb_val;
 
        __u8 mac_address[6]; /* Generated MAC address for peer device */
 };
 
 /*
- *  IrLAN
+ *  IrLAN control block
  */
 struct irlan_cb {
        QUEUE queue; /* Must be first */
 
        int    magic;
        char   ifname[9];
-       struct device dev;  /* Ethernet device structure*/
+       struct device dev;        /* Ethernet device structure*/
        struct enet_statistics stats;
 
-       __u32 saddr;        /* Source devcie address */
-       __u32 daddr;        /* Destination device address */
+       __u32 saddr;              /* Source devcie address */
+       __u32 daddr;              /* Destination device address */
        int   netdev_registered;
        int   notify_irmanager;
        
-       int media;          /* Media type */
-       int access_type;    /* Currently used access type */
-       __u8 version[2];    /* IrLAN version */
+       int media;                /* Media type */
+       __u8 version[2];          /* IrLAN version */
        
        struct tsap_cb *tsap_data;
 
-       int  use_udata;  /* Use Unit Data transfers */
+       int  master;              /* Master instance? */
+       int  use_udata;           /* Use Unit Data transfers */
 
-       __u8 stsap_sel_data; /* Source data TSAP selector */
-       __u8 dtsap_sel_data; /* Destination data TSAP selector */
-       __u8 dtsap_sel_ctrl; /* Destination ctrl TSAP selector */
+       __u8 stsap_sel_data;      /* Source data TSAP selector */
+       __u8 dtsap_sel_data;      /* Destination data TSAP selector */
+       __u8 dtsap_sel_ctrl;      /* Destination ctrl TSAP selector */
 
-       struct irlan_client_cb client;     /* Client specific fields */
+       struct irlan_client_cb   client;   /* Client specific fields */
        struct irlan_provider_cb provider; /* Provider specific fields */
+
+       __u32 max_sdu_size;
+       __u8  max_header_size;
        
        struct timer_list watchdog_timer;
 };
index aafbf9141245192ae45f5522e268c12bf05c3c99..ca51d5b7c999871e8acbd222f8ee15e74c4f9d28 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Apr 22 14:29:16 1999
+ * Modified at:   Sun May  9 12:26:11 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -36,13 +36,7 @@ void irlan_provider_ctrl_disconnect_indication(void *instance, void *sap,
                                               LM_REASON reason, 
                                               struct sk_buff *skb);
 
-void irlan_provider_ctrl_data_indication(void *instance, void *sap,
-                                        struct sk_buff *skb);
 
-void irlan_provider_connect_indication(void *instance, void *sap, 
-                                      struct qos_info *qos, 
-                                      __u32 max_sdu_size,
-                                      struct sk_buff *skb);
 void irlan_provider_connect_response(struct irlan_cb *, struct tsap_cb *);
 
 int irlan_parse_open_data_cmd(struct irlan_cb *self, struct sk_buff *skb);
index f3b26110f646efbc3114ab7128c13548a0575540..c5767397ea8c76a4114e41eb9d06914acf79f038 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Fri Apr 23 09:51:15 1999
+ * Modified at:   Sun May  9 11:38:18 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
 #define LAP_COMP_HEADER 1  /* IrLAP Compression Header */
 
 #ifdef CONFIG_IRDA_COMPRESSION
-#  define LAP_HEADER  (LAP_ADDR_HEADER + LAP_CTRL_HEADER + LAP_COMP_HEADER)
+#  define LAP_MAX_HEADER  (LAP_ADDR_HEADER + LAP_CTRL_HEADER + LAP_COMP_HEADER)
 #  define IRDA_COMPRESSED 1
 #  define IRDA_NORMAL     0
 #else
-#define LAP_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER)
+#define LAP_MAX_HEADER (LAP_ADDR_HEADER + LAP_CTRL_HEADER)
 #endif
 
 #define BROADCAST  0xffffffff /* Broadcast device address */
@@ -138,7 +138,7 @@ struct irlap_cb {
 
        __u8    vs;           /* Next frame to be sent */
        __u8    vr;           /* Next frame to be received */
-       int     tmp;
+/*     int     tmp; */
        __u8    va;           /* Last frame acked */
        int     window;       /* Nr of I-frames allowed to send */
        int     window_size;  /* Current negotiated window size */
@@ -155,8 +155,7 @@ struct irlap_cb {
        __u8    s;           /* Current slot */
        int     frame_sent;  /* Have we sent reply? */
 
-       int discovery_count;
-       hashbin_t *discovery_log;
+       hashbin_t   *discovery_log;
        discovery_t *discovery_cmd;
 
        struct qos_info qos_tx;    /* QoS requested by peer */
@@ -227,4 +226,9 @@ void irlap_init_qos_capabilities(struct irlap_cb *, struct qos_info *);
 void irlap_apply_default_connection_parameters(struct irlap_cb *self);
 void irlap_apply_connection_parameters(struct irlap_cb *, struct qos_info *);
 
+extern inline __u8 irlap_get_header_size(struct irlap_cb *self)
+{
+       return 2;
+}
+
 #endif
index 31785883a584b6c92947f9c749403e46bb64a2d8..e879c6b9413c2df034a20f6c16b7bb4223867942 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 17 20:54:32 1997
- * Modified at:   Fri Apr 23 09:15:07 1999
+ * Modified at:   Sun May  9 11:01:34 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -52,7 +52,7 @@
 
 #define LMP_HEADER          2    /* Dest LSAP + Source LSAP */
 #define LMP_CONTROL_HEADER  4
-#define LMP_MAX_HEADER      (LAP_HEADER+LMP_HEADER)
+#define LMP_MAX_HEADER      (LMP_CONTROL_HEADER+LAP_MAX_HEADER)
 
 #define LM_MAX_CONNECTIONS  10
 
index 83a9c307cc8fc0ca5b8bc6368c7ff6aba0f7e057..688466b5f2cf03a0af4eb72069c1f3275c7ee722 100644 (file)
@@ -158,7 +158,8 @@ struct irlpt_cb {
        struct miscdevice ir_dev; /* used to register the misc device. */
 
        int count;                /* open count */
-       int irlap_data_size;    /* max frame size we can send */
+       int max_data_size;      /* max frame size we can send */
+       int max_header_size;    /* how much header space is needed */
        int pkt_count;          /* how many packets are queued up */
 
        struct wait_queue *read_wait;   /* wait queues */
index c4a036a4d91f992154573eedc402401280d1da87..81981273b97096255c7e1b6edf264fd015df1a57 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug  3 13:49:59 1997
- * Modified at:   Thu Jan  7 14:17:31 1999
+ * Modified at:   Mon May 10 22:12:56 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997, 1998 Dag Brattli <dagb@cs.uit.no>
+ *     Copyright (c) 1997, 1998-1999 Dag Brattli <dagb@cs.uit.no>
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
 
 #define FRAME_MAX_SIZE 2048
 
-void irport_close( int iobase);
-int  irport_open( int iobase);
-int  irport_detect(struct irda_device *idev);
+void irport_start(int iobase);
+void irport_stop(int iobase);
+int  irport_probe(int iobase);
 
-void irport_change_speed( int iobase, int speed);
+void irport_change_speed(struct irda_device *idev, int speed);
 void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
-int  irport_hard_xmit( struct sk_buff *skb, struct device *dev);
+int  irport_hard_xmit(struct sk_buff *skb, struct device *dev);
 
 #endif
index aec1d57dc15738e09be0a111bbf7158a2ec255d0..3e6511ceae5bcd73951e9c1875422a35a5fa7092 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:31 1997
- * Modified at:   Sat Apr 10 10:19:56 1999
+ * Modified at:   Mon May 10 19:14:51 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -36,7 +36,8 @@
 
 #define TTP_MAX_CONNECTIONS    LM_MAX_CONNECTIONS
 #define TTP_HEADER             1
-#define TTP_HEADER_WITH_SAR    6
+#define TTP_MAX_HEADER         (TTP_HEADER + LMP_MAX_HEADER)
+#define TTP_SAR_HEADER         5
 #define TTP_PARAMETERS         0x80
 #define TTP_MORE               0x80
 
@@ -61,8 +62,6 @@ struct tsap_cb {
        QUEUE queue;          /* For linking it into the hashbin */
        int  magic;           /* Just in case */
 
-       int max_seg_size;     /* Max data that fit into an IrLAP frame */
-
        __u8 stsap_sel;       /* Source TSAP */
        __u8 dtsap_sel;       /* Destination TSAP */
 
@@ -88,6 +87,9 @@ struct tsap_cb {
        struct irda_statistics stats;
        struct timer_list todo_timer; 
        
+       __u32 max_seg_size;     /* Max data that fit into an IrLAP frame */
+       __u8  max_header_size;
+
        int   rx_sdu_busy;     /* RxSdu.busy */
        __u32 rx_sdu_size;     /* Current size of a partially received frame */
        __u32 rx_max_sdu_size; /* Max receive user data size */
@@ -120,8 +122,6 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
                          __u32 saddr, __u32 daddr,
                          struct qos_info *qos, __u32 max_sdu_size, 
                          struct sk_buff *userdata);
-void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos, 
-                          __u32 max_sdu_size, struct sk_buff *skb);
 void irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, 
                            struct sk_buff *userdata);
 struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance);
index 920909600e54f3051d68b095c92d096beece9051..38b5c4d81cd7c6cea37b0136af0c9e5ea9d2afb3 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:13:12 1997
- * Modified at:   Sun Feb  7 01:57:33 1999
+ * Modified at:   Mon May 10 13:22:23 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  *  
- *     Copyright (c) 1997 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -33,8 +33,6 @@
 #include <net/irda/irqueue.h>
 #include <net/irda/irda_device.h>
 
-#include <net/irda/dongle.h>
-
 #define IRTTY_IOC_MAGIC 'e'
 #define IRTTY_IOCTDONGLE  _IO(IRTTY_IOC_MAGIC, 1)
 #define IRTTY_IOC_MAXNR   1
 #define N_IRDA         11   /* This one should go in </asm/termio.h> */
 #endif
 
-struct dongle_q {
-       QUEUE q;
-
-       struct dongle *dongle;
-};
-
 struct irtty_cb {
        QUEUE q; /* Must be first */
 
-/*     char name[16]; */
-
        int     magic;
        
        struct  tty_struct  *tty;  /* Ptr to TTY structure */
        struct  irda_device idev;
-
-       struct dongle_q *dongle_q; /* Has this tty got a dongle attached? */
 };
  
-int irtty_register_dongle( struct dongle *dongle);
-void irtty_unregister_dongle( struct dongle *dongle);
-
-void irtty_set_dtr_rts(struct tty_struct *tty, int dtr, int rts);
+int irtty_register_dongle(struct dongle *dongle);
+void irtty_unregister_dongle(struct dongle *dongle);
 
 #endif
+
+
+
+
+
diff --git a/include/net/irda/toshoboe.h b/include/net/irda/toshoboe.h
new file mode 100644 (file)
index 0000000..b2f5b95
--- /dev/null
@@ -0,0 +1,165 @@
+/*********************************************************************
+ *                
+ * Filename:      toshoboe.h
+ * Version:       0.1
+ * Description:   Driver for the Toshiba OBOE (or type-O)
+ *                FIR Chipset. 
+ * Status:        Experimental.
+ * Author:        James McKenzie <james@fishsoup.dhs.org>
+ * Created at:    Sat May 8  12:35:27 1999
+ * 
+ *     Copyright (c) 1999 James McKenzie, All Rights Reserved.
+ *      
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version.
+ *  
+ *     Neither James McKenzie nor Cambridge University admit liability nor
+ *     provide warranty for any of this software. This material is 
+ *     provided "AS-IS" and at no charge.
+ *
+ *     Applicable Models : Libretto 100CT. and many more
+ *
+ ********************************************************************/
+
+/*
+ * $Log: toshoboe.h,v $
+ * Revision 1.2  1999/05/09 01:43:08  root
+ * *** empty log message ***
+ *
+ * Revision 1.1  1999/05/09 01:25:58  root
+ * Initial revision
+ *
+ */
+
+#ifndef TOSHOBOE_H
+#define TOSHOBOE_H
+
+/* Registers */
+/*Receive and transmit task registers (read only) */
+#define OBOE_RCVT      (0x00+(self->base))
+#define OBOE_XMTT      (0x01+(self->base))
+#define OBOE_XMTT_OFFSET       0x40
+
+/*Page pointers to the TaskFile structure */
+#define OBOE_TFP2      (0x02+(self->base))
+#define OBOE_TFP0      (0x04+(self->base))
+#define OBOE_TFP1      (0x05+(self->base))
+
+/*Dunno */
+#define OBOE_REG_3     (0x03+(self->base))
+
+/*Number of tasks to use in Xmit and Recv queues */
+#define OBOE_NTR       (0x07+(self->base))
+#define OBOE_NTR_XMIT4 0x00
+#define OBOE_NTR_XMIT8 0x10
+#define OBOE_NTR_XMIT16        0x30
+#define OBOE_NTR_XMIT32        0x70
+#define OBOE_NTR_XMIT64        0xf0
+#define OBOE_NTR_RECV4 0x00
+#define OBOE_NTR_RECV8 0x01
+#define OBOE_NTR_RECV6 0x03
+#define OBOE_NTR_RECV32        0x07
+#define OBOE_NTR_RECV64        0x0f
+
+/* Dunno */
+#define OBOE_REG_9     (0x09+(self->base))
+
+/* Interrupt Status Register */
+#define OBOE_ISR       (0x0c+(self->base))
+#define OBOE_ISR_TXDONE        0x80
+#define OBOE_ISR_RXDONE        0x40
+#define OBOE_ISR_20    0x20
+#define OBOE_ISR_10    0x10
+#define OBOE_ISR_8     0x08         /*This is collision or parity or something */
+#define OBOE_ISR_4     0x08
+#define OBOE_ISR_2     0x08
+#define OBOE_ISR_1     0x08
+
+/*Dunno */
+#define OBOE_REG_D     (0x0d+(self->base))
+
+/*Register Lock Register */
+#define OBOE_LOCK      ((self->base)+0x0e)
+
+
+
+/*Speed control registers */
+#define OBOE_PMDL      (0x10+(self->base))
+#define OBOE_PMDL_SIR  0x18
+#define OBOE_PMDL_MIR  0xa0
+#define OBOE_PMDL_FIR  0x40
+
+#define OBOE_SMDL      (0x18+(self->base))
+#define OBOE_SMDL_SIR  0x20
+#define OBOE_SMDL_MIR  0x01
+#define OBOE_SMDL_FIR  0x0f
+
+#define OBOE_UDIV      (0x19+(self->base))
+
+/*Dunno */
+#define OBOE_REG_11    (0x11+(self->base))
+
+/*Chip Reset Register */
+#define OBOE_RST       (0x15+(self->base))
+#define OBOE_RST_WRAP  0x8
+
+/*Dunno */
+#define OBOE_REG_1A    (0x1a+(self->base))
+#define OBOE_REG_1B    (0x1b+(self->base))
+
+/* The PCI ID of the OBOE chip */
+#ifndef PCI_DEVICE_ID_FIR701
+#define PCI_DEVICE_ID_FIR701   0x0701
+#endif
+
+typedef unsigned int dword;
+typedef unsigned short int word;
+typedef unsigned char byte;
+typedef dword Paddr;
+
+struct OboeTask
+  {
+    __u16 len;
+    __u8 unused;
+    __u8 control;
+    __u32 buffer;
+  };
+
+#define OBOE_NTASKS 64
+
+struct OboeTaskFile
+  {
+    struct OboeTask recv[OBOE_NTASKS];
+    struct OboeTask xmit[OBOE_NTASKS];
+  };
+
+#define OBOE_TASK_BUF_LEN (sizeof(struct OboeTaskFile) << 1)
+
+/*These set the number of slots in use */
+#define TX_SLOTS       4
+#define RX_SLOTS       4
+
+/* You need also to change this, toshiba uses 4,8 and 4,4 */
+/* It makes no difference if you are only going to use ONETASK mode */
+/* remember each buffer use XX_BUF_SZ more _PHYSICAL_ memory */
+#define OBOE_NTR_VAL   (OBOE_NTR_XMIT4 | OBOE_NTR_RECV4)
+
+struct toshoboe_cb
+  {
+    struct irda_device idev;    /*IRDA device */
+    struct pci_dev *pdev;       /*PCI device */
+    int base;                   /*IO base */
+    int txpending;              /*how many tx's are pending */
+    int txs, rxs;               /*Which slots are we at  */
+    void *taskfilebuf;          /*The unaligned taskfile buffer */
+    struct OboeTaskFile *taskfile;  /*The taskfile   */
+    void *xmit_bufs[TX_SLOTS];  /*The buffers   */
+    void *recv_bufs[RX_SLOTS];
+  };
+
+
+#endif
+
+
index 3e3200b2de3fc847a482836fcfb61f344267a34d..d86456ada55291df7b2b867ffe3c3644f0073242 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Paul VanderSpek
  * Created at:    Thu Nov 19 13:55:34 1998
- * Modified at:   Thu Dec 10 14:06:18 1998
+ * Modified at:   Mon May  3 12:07:25 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
 #define IRM_CR_IRX_MSL 0x40
 #define IRM_CR_AF_MNT   0x80 /* Automatic format */
 
+/* For storing entries in the status FIFO */
+struct st_fifo_entry {
+       int status;
+       int len;
+};
+
+struct st_fifo {
+       struct st_fifo_entry entries[10];
+       int head;
+       int tail;
+       int len;
+};
+
+/* Private data for each instance */
+struct w83977af_ir {
+       struct st_fifo st_fifo;
+
+       int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */
+       int tx_len;          /* Number of frames in tx_buff */
+
+       struct irda_device idev;
+};
+
 static inline void switch_bank( int iobase, int set)
 {
        outb( set, iobase+SSR);
index ca21ebec51234808ab4cfa4f4db81920973a852a..fa7ceb25c2216abca70a7c5188b4407a3fde9528 100644 (file)
@@ -1,15 +1,16 @@
 /*********************************************************************
  *                
  * Filename:      wrapper.h
- * Version:       1.0
- * Description:   IrDA Wrapper layer
+ * Version:       1.2
+ * Description:   IrDA SIR async wrapper layer
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Fri Jan 29 10:15:46 1999
+ * Modified at:   Mon May  3 09:02:36 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
 #define STA BOF  /* Start flag */
 #define STO EOF  /* End flag */
 
-#define IR_TRANS 0x20    /* Asynchronous transparency modifier */       
+#define IRDA_TRANS 0x20    /* Asynchronous transparency modifier */       
 
+/* States for receving a frame in async mode */
 enum {
-       OUTSIDE_FRAME = 1
+       OUTSIDE_FRAME, 
        BEGIN_FRAME, 
        LINK_ESCAPE, 
        INSIDE_FRAME
 };
 
 /* Proto definitions */
-int  async_wrap_skb( struct sk_buff *skb, __u8 *tx_buff, int buffsize);
-void async_unwrap_char( struct irda_device *, __u8 byte);
+int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize);
+inline void async_unwrap_char(struct irda_device *idev, __u8 byte);
 
 #endif
index fae22cbe7deb3a112f048dc05b56f6628c91020c..39f4b9e7b4fd53136d9b382b481392b00124bf20 100644 (file)
@@ -452,7 +452,6 @@ eol:
 error:
        if (skb) {
                icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl((pp_ptr-iph)<<24));
-               kfree_skb(skb);
        }
        return -EINVAL;
 }
index 3760be8eb996220b883ddd73821fe115bbea88e4..f50a9cbf17f8c407281e364ee9346c82354c9a67 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>
  *
- *     $Id: icmp.c,v 1.21 1999/03/21 05:22:51 davem Exp $
+ *     $Id: icmp.c,v 1.21.2.1 1999/05/19 22:07:36 davem Exp $
  *
  *     Based on net/ipv4/icmp.c
  *
@@ -315,6 +315,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        fl.nl_u.ip6_u.daddr = &hdr->saddr;
        fl.nl_u.ip6_u.saddr = saddr;
        fl.oif = iif;
+       fl.fl6_flowlabel = 0;
        fl.uli_u.icmpt.type = type;
        fl.uli_u.icmpt.code = code;
 
@@ -388,6 +389,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        fl.nl_u.ip6_u.daddr = &hdr->saddr;
        fl.nl_u.ip6_u.saddr = saddr;
        fl.oif = skb->dev->ifindex;
+       fl.fl6_flowlabel = 0;
        fl.uli_u.icmpt.type = ICMPV6_ECHO_REPLY;
        fl.uli_u.icmpt.code = 0;
 
index 6dd1180248717c7ff94630836889f02927f400bc..385805ff219b800661753d14f194bdc65f8b8140 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun May 31 10:12:43 1998
- * Modified at:   Thu Apr 22 12:08:04 1999
+ * Modified at:   Tue May 11 12:42:26 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
  * 
@@ -30,6 +30,7 @@
 #include <linux/if_arp.h>
 #include <linux/net.h>
 #include <linux/irda.h>
+#include <linux/poll.h>
 
 #include <asm/uaccess.h>
 
@@ -46,11 +47,12 @@ extern void irda_cleanup(void);
 extern int  irlap_driver_rcv(struct sk_buff *, struct device *, 
                             struct packet_type *);
 
-static struct proto_ops irda_proto_ops;
+static struct proto_ops irda_stream_ops;
+static struct proto_ops irda_dgram_ops;
 static hashbin_t *cachelog = NULL;
 static struct wait_queue *discovery_wait; /* Wait for discovery */
 
-#define IRDA_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_HEADER)
+#define IRDA_MAX_HEADER (TTP_MAX_HEADER)
 
 /*
  * Function irda_data_indication (instance, sap, skb)
@@ -121,7 +123,8 @@ static void irda_disconnect_indication(void *instance, void *sap,
  */
 static void irda_connect_confirm(void *instance, void *sap, 
                                 struct qos_info *qos,
-                                __u32 max_sdu_size, struct sk_buff *skb)
+                                __u32 max_sdu_size, __u8 max_header_size, 
+                                struct sk_buff *skb)
 {
        struct irda_sock *self;
        struct sock *sk;
@@ -130,13 +133,28 @@ static void irda_connect_confirm(void *instance, void *sap,
 
        self = (struct irda_sock *) instance;
 
+       /* How much header space do we need to reserve */
+       self->max_header_size = max_header_size;
+
+       /* IrTTP max SDU size in transmit direction */
        self->max_sdu_size_tx = max_sdu_size;
+
+       /* Find out what the largest chunk of data that we can transmit is */
+       if (max_sdu_size == SAR_DISABLE)
+               self->max_data_size = qos->data_size.value - max_header_size;
+       else
+               self->max_data_size = max_sdu_size;
+
+       DEBUG(0, __FUNCTION__ "(), max_data_size=%d\n", self->max_data_size);
+
        memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
 
        sk = self->sk;
        if (sk == NULL)
                return;
 
+       skb_queue_tail(&sk->receive_queue, skb);
+
        /* We are now connected! */
        sk->state = TCP_ESTABLISHED;
        sk->state_change(sk);
@@ -150,7 +168,7 @@ static void irda_connect_confirm(void *instance, void *sap,
  */
 static void irda_connect_indication(void *instance, void *sap, 
                                    struct qos_info *qos, __u32 max_sdu_size,
-                                   struct sk_buff *skb)
+                                   __u8 max_header_size, struct sk_buff *skb)
 {
        struct irda_sock *self;
        struct sock *sk;
@@ -158,8 +176,21 @@ static void irda_connect_indication(void *instance, void *sap,
        DEBUG(1, __FUNCTION__ "()\n");
 
        self = (struct irda_sock *) instance;
-       
-       self->max_sdu_size_tx = max_sdu_size;
+
+       /* How much header space do we need to reserve */
+       self->max_header_size = max_header_size;
+
+       /* IrTTP max SDU size in transmit direction */
+       self->max_sdu_size_tx = max_sdu_size;   
+
+       /* Find out what the largest chunk of data that we can transmit is */
+       if (max_sdu_size == SAR_DISABLE)
+               self->max_data_size = qos->data_size.value - max_header_size;
+       else
+               self->max_data_size = max_sdu_size;
+
+       DEBUG(0, __FUNCTION__ "(), max_data_size=%d\n", self->max_data_size);
+
        memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
 
        sk = self->sk;
@@ -187,12 +218,12 @@ void irda_connect_response(struct irda_sock *self)
 
        skb = dev_alloc_skb(64);
        if (skb == NULL) {
-               DEBUG( 0, __FUNCTION__ "() Could not allocate sk_buff!\n");
+               DEBUG(0, __FUNCTION__ "() Unable to allocate sk_buff!\n");
                return;
        }
 
        /* Reserve space for MUX_CONTROL and LAP header */
-       skb_reserve(skb, TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER);
+       skb_reserve(skb, IRDA_MAX_HEADER);
 
        irttp_connect_response(self->tsap, self->max_sdu_size_rx, skb);
 }
@@ -514,10 +545,13 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
        new->stsap_sel = new->tsap->stsap_sel;
        new->dtsap_sel = new->tsap->dtsap_sel;
        new->saddr = irttp_get_saddr(new->tsap);
-       new->saddr = irttp_get_saddr(new->tsap);
+       new->daddr = irttp_get_daddr(new->tsap);
 
        new->max_sdu_size_tx = self->max_sdu_size_tx;
        new->max_sdu_size_rx = self->max_sdu_size_rx;
+       new->max_data_size   = self->max_data_size;
+       new->max_header_size = self->max_header_size;
+
        memcpy(&new->qos_tx, &self->qos_tx, sizeof(struct qos_info));
 
        /* Clean up the original one to keep it in listen state */
@@ -669,7 +703,7 @@ static int irda_create(struct socket *sock, int protocol)
 
        sock_init_data(sock, sk);
 
-       sock->ops    = &irda_proto_ops;
+       sock->ops    = &irda_stream_ops;
        sk->protocol = protocol;
 
        /* Register as a client with IrLMP */
@@ -786,12 +820,20 @@ static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len,
                        return -ENOTCONN;
        }
 
-       skb = sock_alloc_send_skb(sk, len + IRDA_MAX_HEADER, 0, 
+       /* Check that we don't send out to big frames */
+       if (len > self->max_data_size) {
+               DEBUG(0, __FUNCTION__ "(), Warning to much data! "
+                     "Chopping frame from %d to %d bytes!\n", len, 
+                     self->max_data_size);
+               len = self->max_data_size;
+       }
+
+       skb = sock_alloc_send_skb(sk, len + self->max_header_size, 0, 
                                  msg->msg_flags & MSG_DONTWAIT, &err);
        if (!skb)
                return -ENOBUFS;
 
-       skb_reserve(skb, IRDA_MAX_HEADER);
+       skb_reserve(skb, self->max_header_size);
        
        DEBUG(4, __FUNCTION__ "(), appending user data\n");
        asmptr = skb->h.raw = skb_put(skb, len);
@@ -815,8 +857,8 @@ static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len,
  *    Try to receive message and copy it to user
  *
  */
-static int irda_recvmsg(struct socket *sock, struct msghdr *msg, int size,
-                       int flags, struct scm_cookie *scm)
+static int irda_recvmsg_dgram(struct socket *sock, struct msghdr *msg, 
+                             int size, int flags, struct scm_cookie *scm)
 {
        struct irda_sock *self;
        struct sock *sk = sock->sk;
@@ -861,6 +903,161 @@ static int irda_recvmsg(struct socket *sock, struct msghdr *msg, int size,
        return copied;
 }
 
+/*
+ * Function irda_data_wait (sk)
+ *
+ *    Sleep until data has arrive. But check for races..
+ *
+ */
+static void irda_data_wait(struct sock *sk)
+{
+       if (!skb_peek(&sk->receive_queue)) {
+               sk->socket->flags |= SO_WAITDATA;
+               interruptible_sleep_on(sk->sleep);
+               sk->socket->flags &= ~SO_WAITDATA;
+       }
+}
+
+/*
+ * Function irda_recvmsg_stream (sock, msg, size, flags, scm)
+ *
+ *    
+ *
+ */
+static int irda_recvmsg_stream(struct socket *sock, struct msghdr *msg, 
+                              int size, int flags, struct scm_cookie *scm)
+{
+       struct irda_sock *self;
+       struct sock *sk = sock->sk;
+       int noblock = flags & MSG_DONTWAIT;
+       int copied = 0;
+       int target = 1;
+
+       DEBUG(3, __FUNCTION__ "()\n");
+
+       self = sk->protinfo.irda;
+       ASSERT(self != NULL, return -1;);
+
+       if (sock->flags & SO_ACCEPTCON) 
+               return(-EINVAL);
+
+       if (flags & MSG_OOB)
+               return -EOPNOTSUPP;
+
+       if (flags & MSG_WAITALL)
+               target = size;
+               
+               
+       msg->msg_namelen = 0;
+
+       /* Lock the socket to prevent queue disordering
+        * while sleeps in memcpy_tomsg
+        */
+/*     down(&self->readsem); */
+
+       do {
+               int chunk;
+               struct sk_buff *skb;
+
+               skb=skb_dequeue(&sk->receive_queue);
+               if (skb==NULL) {
+                       if (copied >= target)
+                               break;
+                       
+                       /*
+                        *      POSIX 1003.1g mandates this order.
+                        */
+                       
+                       if (sk->err) {
+                               /* up(&self->readsem); */
+                               return sock_error(sk);
+                       }
+
+                       if (sk->shutdown & RCV_SHUTDOWN)
+                               break;
+
+               /*      up(&self->readsem); */
+
+                       if (noblock)
+                               return -EAGAIN;
+                       irda_data_wait(sk);
+                       if (signal_pending(current))
+                               return -ERESTARTSYS;
+               /*      down(&self->readsem); */
+                       continue;
+               }
+
+               /* Never glue messages from different writers */
+/*             if (check_creds && */
+/*                 memcmp(UNIXCREDS(skb), &scm->creds, sizeof(scm->creds)) != 0) */
+/*             { */
+/*                     skb_queue_head(&sk->receive_queue, skb); */
+/*                     break; */
+/*             } */
+
+               chunk = min(skb->len, size);
+               if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+                       skb_queue_head(&sk->receive_queue, skb);
+                       if (copied == 0)
+                               copied = -EFAULT;
+                       break;
+               }
+               copied += chunk;
+               size -= chunk;
+
+               /* Copy credentials */
+/*             scm->creds = *UNIXCREDS(skb); */
+/*             check_creds = 1; */
+
+               /* Mark read part of skb as used */
+               if (!(flags & MSG_PEEK)) {
+                       skb_pull(skb, chunk);
+
+/*                     if (UNIXCB(skb).fp) */
+/*                             unix_detach_fds(scm, skb); */
+
+                       /* put the skb back if we didn't use it up.. */
+                       if (skb->len) {
+                               DEBUG(1, __FUNCTION__ "(), back on q!\n");
+                               skb_queue_head(&sk->receive_queue, skb);
+                               break;
+                       }
+
+                       kfree_skb(skb);
+                       
+/*                     if (scm->fp) */
+/*                             break; */
+               } else {
+                       DEBUG(0, __FUNCTION__ "() questionable!?\n");
+                       /* It is questionable, see note in unix_dgram_recvmsg. */
+/*                     if (UNIXCB(skb).fp) */
+/*                             scm->fp = scm_fp_dup(UNIXCB(skb).fp); */
+
+                       /* put message back and return */
+                       skb_queue_head(&sk->receive_queue, skb);
+                       break;
+               }
+       } while (size);
+
+       /*
+        *  Check if we have previously stopped IrTTP and we know
+        *  have more free space in our rx_queue. If so tell IrTTP
+        *  to start delivering frames again before our rx_queue gets
+        *  empty
+        */
+       if (self->rx_flow == FLOW_STOP) {
+               if ((atomic_read(&sk->rmem_alloc) << 2) <= sk->rcvbuf) {
+                       DEBUG(2, __FUNCTION__ "(), Starting IrTTP\n");
+                       self->rx_flow = FLOW_START;
+                       irttp_flow_request(self->tsap, FLOW_START);
+               }
+       }
+
+       /* up(&self->readsem); */
+
+       return copied;
+}
+
 /*
  * Function irda_shutdown (sk, how)
  *
@@ -875,19 +1072,45 @@ static int irda_shutdown( struct socket *sk, int how)
         return -EOPNOTSUPP;
 }
 
-
 /*
  * Function irda_poll (file, sock, wait)
  *
  *    
  *
  */
-unsigned int irda_poll(struct file *file, struct socket *sock, 
-                      struct poll_table_struct *wait)
+static unsigned int irda_poll(struct file * file, struct socket *sock, 
+                             poll_table *wait)
 {
-       DEBUG(0, __FUNCTION__ "()\n");
+       struct sock *sk = sock->sk;
+       unsigned int mask;
 
-       return 0;
+       DEBUG(1, __FUNCTION__ "()\n");
+
+       poll_wait(file, sk->sleep, wait);
+       mask = 0;
+
+       /* exceptional events? */
+       if (sk->err)
+               mask |= POLLERR;
+       if (sk->shutdown & RCV_SHUTDOWN)
+               mask |= POLLHUP;
+
+       /* readable? */
+       if (!skb_queue_empty(&sk->receive_queue))
+               mask |= POLLIN | POLLRDNORM;
+
+       /* Connection-based need to check for termination and startup */
+       if (sk->type == SOCK_STREAM && sk->state==TCP_CLOSE)
+               mask |= POLLHUP;
+
+       /*
+        * we set writable also when the other side has shut down the
+        * connection. This prevents stuck sockets.
+        */
+       if (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= MIN_WRITE_SPACE)
+                       mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+
+       return mask;
 }
 
 /*
@@ -947,6 +1170,7 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                return -EINVAL;
                
        default:
+               DEBUG(0, __FUNCTION__ "(), doing device ioctl!\n");
                return dev_ioctl(cmd, (void *) arg);
        }
 
@@ -1082,13 +1306,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
                        return -EFAULT;
                break;
        case IRTTP_MAX_SDU_SIZE:
-               if (self->max_sdu_size_tx != SAR_DISABLE)
-                       val = self->max_sdu_size_tx;
-               else
-                       /* SAR is disabled, so use the IrLAP data size
-                        * instead */
-                       val = self->qos_tx.data_size.value - IRDA_MAX_HEADER;
-
+               val = self->max_data_size;
                DEBUG(0, __FUNCTION__ "(), getting max_sdu_size = %d\n", val);
                len = sizeof(int);
                if (put_user(len, optlen))
@@ -1110,7 +1328,7 @@ static struct net_proto_family irda_family_ops =
        irda_create
 };
 
-static struct proto_ops irda_proto_ops = {
+static struct proto_ops irda_stream_ops = {
        PF_IRDA,
        
        sock_no_dup,
@@ -1128,7 +1346,28 @@ static struct proto_ops irda_proto_ops = {
        irda_getsockopt,
        sock_no_fcntl,
        irda_sendmsg,
-       irda_recvmsg
+       irda_recvmsg_stream
+};
+
+static struct proto_ops irda_dgram_ops = {
+       PF_IRDA,
+       
+       sock_no_dup,
+       irda_release,
+       irda_bind,
+       irda_connect,
+       sock_no_socketpair,
+       irda_accept,
+       irda_getname,
+       datagram_poll,
+       irda_ioctl,
+       irda_listen,
+       irda_shutdown,
+       irda_setsockopt,
+       irda_getsockopt,
+       sock_no_fcntl,
+       irda_sendmsg,
+       irda_recvmsg_dgram
 };
 
 /*
@@ -1215,7 +1454,7 @@ void irda_proto_cleanup(void)
        irda_packet_type.type = htons(ETH_P_IRDA);
         dev_remove_pack(&irda_packet_type);
 
-        unregister_netdevice_notifier( &irda_dev_notifier);
+        unregister_netdevice_notifier(&irda_dev_notifier);
        
        sock_unregister(PF_IRDA);
        irda_cleanup();
index 9a6f3021fa0595aa12877a9114123eb95cc78e18..b3019d5c209573896a71dfec11d9738651e3c6a5 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Sat Dec 12 09:56:35 1998
+ * Modified at:   Sun May  2 20:28:08 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       ppp.c by Michael Callahan <callahan@maths.ox.ac.uk>
  *                Al Longyear <longyear@netcom.com>
@@ -59,7 +59,7 @@ __u16 const irda_crc16_table[256] =
 
 unsigned short crc_calc( __u16 fcs, __u8 const *buf, size_t len) 
 {
-    while ( len--)
-               fcs = IR_FCS(fcs, *buf++);
-    return fcs;
+       while (len--)
+                fcs = irda_fcs(fcs, *buf++);
+       return fcs;
 }
index 22def3a1e89cf10f781dca998435988ce0e7de04..41fc4d20a5e80ef3b674c96de4a5fd41e38f1a97 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Apr  6 15:33:50 1999
- * Modified at:   Sun Apr 11 00:41:58 1999
+ * Modified at:   Sun May  9 22:40:43 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
 /*
  * Function irlmp_add_discovery (cachelog, discovery)
  *
- *    
- *
+ *    Add a new discovery to the cachelog, and remove any old discoveries
+ *    from the same device
  */
-void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *discovery)
+void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new)
 {
-       discovery_t *old;
+       discovery_t *discovery, *node;
+       unsigned long flags;
 
-       DEBUG(4, __FUNCTION__ "()\n");
+       spin_lock_irqsave(&irlmp->lock, flags);
+
+       /* 
+        * Remove all discoveries of devices that has previously been 
+        * discovered on the same link with the same name (info), or the 
+        * same daddr. We do this since some devices (mostly PDAs) change
+        * their device address between every discovery.
+        */
+       discovery = (discovery_t *) hashbin_get_first(cachelog);
+       while (discovery != NULL ) {
+                       node = discovery;
+
+                       /* Be sure to stay one item ahead */
+                       discovery = (discovery_t *) hashbin_get_next(cachelog);
+                       
+                       if ((node->daddr == new->daddr) || 
+                           (strcmp(node->info, new->info) == 0))
+                       {
+                               /* This discovery is a previous discovery 
+                                * from the same device, so just remove it
+                                */
+                               hashbin_remove(cachelog, node->daddr, NULL);
+                               kfree(node);
+                       }
+               }
 
-       /* Check if we have discovered this device before */
-       old = hashbin_remove(cachelog, discovery->daddr, NULL);
-       if (old)
-               kfree(old);
 
        /* Insert the new and updated version */
-       hashbin_insert(cachelog, (QUEUE *) discovery, discovery->daddr, NULL);
+       hashbin_insert(cachelog, (QUEUE *) new, new->daddr, NULL);
+
+       spin_unlock_irqrestore(&irlmp->lock, flags);
 }
 
 /*
  * Function irlmp_add_discovery_log (cachelog, log)
  *
- *    
+ *    Merge a disovery log into the cachlog.
  *
  */
 void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log)
index bc8758e1eff540c2808615890bcc9cf7ad9a5257..97fc3cf279d266bd4d47d0e903ca3e9eaa4b33d3 100644 (file)
@@ -8,7 +8,7 @@
  * Author:        Takahide Higuchi <thiguchi@pluto.dti.ne.jp>
  * Source:        irlpt_event.c
  *
- *     Copyright (c) 1998, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
+ *     Copyright (c) 1998-1999, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
  *     All Rights Reserved.
  *
  *     This program is free software; you can redistribute it and/or
 static char *revision_date = "Sun Apr 18 00:40:19 1999";
 
 
-static void ircomm_state_idle( struct ircomm_cb *self, IRCOMM_EVENT event, 
-                              struct sk_buff *skb );
-
-static void ircomm_state_discoverywait( struct ircomm_cb *self, IRCOMM_EVENT event, 
+static void ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event, 
+                             struct sk_buff *skb );
+static void ircomm_state_discoverywait(struct ircomm_cb *self, 
+                                      IRCOMM_EVENT event, 
+                                      struct sk_buff *skb );
+static void ircomm_state_queryparamwait(struct ircomm_cb *self, 
+                                       IRCOMM_EVENT event, 
                                        struct sk_buff *skb );
-
-static void ircomm_state_queryparamwait( struct ircomm_cb *self, IRCOMM_EVENT event, 
-                                        struct sk_buff *skb );
-
-static void ircomm_state_querylsapwait( struct ircomm_cb *self, IRCOMM_EVENT event, 
-                                       struct sk_buff *skb );
-
+static void ircomm_state_querylsapwait(struct ircomm_cb *self, 
+                                      IRCOMM_EVENT event, 
+                                      struct sk_buff *skb );
 static void ircomm_state_waiti( struct ircomm_cb *self, IRCOMM_EVENT event, 
                                struct sk_buff *skb );
 static void ircomm_state_waitr( struct ircomm_cb *self, IRCOMM_EVENT event, 
@@ -207,7 +206,7 @@ __initfunc(int ircomm_init(void))
                ircomm[i]->ack_char = 0x06;  
 
                ircomm[i]->max_txbuff_size = COMM_DEFAULT_DATA_SIZE;   /* 64 */
-               ircomm[i]->maxsdusize = SAR_DISABLE;  
+               ircomm[i]->max_sdu_size = SAR_DISABLE;  
                ircomm[i]->ctrl_skb = dev_alloc_skb(COMM_DEFAULT_DATA_SIZE);
                if (ircomm[i]->ctrl_skb == NULL){
                        DEBUG(0,"ircomm:init_module:alloc_skb failed!\n");
@@ -226,7 +225,6 @@ __initfunc(int ircomm_init(void))
        create_proc_entry("ircomm", 0, proc_irda)->get_info = ircomm_proc_read;
 #endif /* CONFIG_PROC_FS */
 
-
        discovering_instance = NULL;
        return 0;
 }
@@ -275,51 +273,53 @@ void ircomm_cleanup(void)
 static int ircomm_accept_data_indication(void *instance, void *sap, 
                                         struct sk_buff *skb)
 {
-       
-       struct ircomm_cb *self = (struct ircomm_cb *)instance;
+       struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
-       ASSERT( self != NULL, return -1;);
-       ASSERT( self->magic == IRCOMM_MAGIC, return -1;);
-       ASSERT( skb != NULL, return -1;);
+       ASSERT(self != NULL, return -1;);
+       ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
+       ASSERT(skb != NULL, return -1;);
        
        DEBUG(4,__FUNCTION__"():\n");
-       ircomm_do_event( self, TTP_DATA_INDICATION, skb);
+       ircomm_do_event(self, TTP_DATA_INDICATION, skb);
        self->rx_packets++;
        
        return 0;
 }
 
 static void ircomm_accept_connect_confirm(void *instance, void *sap,
-                                  struct qos_info *qos, 
-                                  __u32 maxsdusize, struct sk_buff *skb)
+                                         struct qos_info *qos, 
+                                         __u32 max_sdu_size, 
+                                         __u8 max_header_size,
+                                         struct sk_buff *skb)
 {
+       struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
-       struct ircomm_cb *self = (struct ircomm_cb *)instance;
-
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == IRCOMM_MAGIC, return;);
-       ASSERT( skb != NULL, return;);
-       ASSERT( qos != NULL, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IRCOMM_MAGIC, return;);
+       ASSERT(skb != NULL, return;);
+       ASSERT(qos != NULL, return;);
 
        DEBUG(0,__FUNCTION__"(): got connected!\n");
 
-       if(maxsdusize == SAR_DISABLE)
-               self->max_txbuff_size = qos->data_size.value
+       if (max_sdu_size == SAR_DISABLE)
+               self->max_txbuff_size = qos->data_size.value - max_header_size;
        else {
-               ASSERT(maxsdusize >= COMM_DEFAULT_DATA_SIZE, return;);
-               self->max_txbuff_size = maxsdusize; /* use fragmentation */
+               ASSERT(max_sdu_size >= COMM_DEFAULT_DATA_SIZE, return;);
+               self->max_txbuff_size = max_sdu_size; /* use fragmentation */
        }
 
        self->qos = qos;
-       self->null_modem_mode = 0;              /* disable null modem emulation */
+       self->max_header_size = max_header_size;
+       self->null_modem_mode = 0;         /* disable null modem emulation */
 
-       ircomm_do_event( self, TTP_CONNECT_CONFIRM, skb);
+       ircomm_do_event(self, TTP_CONNECT_CONFIRM, skb);
 }
 
 static void ircomm_accept_connect_indication(void *instance, void *sap,
-                                     struct qos_info *qos,
-                                     __u32 maxsdusize,
-                                     struct sk_buff *skb )
+                                            struct qos_info *qos,
+                                            __u32 max_sdu_size,
+                                            __u8 max_header_size,
+                                            struct sk_buff *skb)
 {
        struct ircomm_cb *self = (struct ircomm_cb *)instance;
 
@@ -330,12 +330,14 @@ static void ircomm_accept_connect_indication(void *instance, void *sap,
 
        DEBUG(0,__FUNCTION__"()\n");
 
-       if(maxsdusize == SAR_DISABLE)
-               self->max_txbuff_size = qos->data_size.value;
+       if (max_sdu_size == SAR_DISABLE)
+               self->max_txbuff_size = qos->data_size.value - max_header_size;
        else
-               self->max_txbuff_size = maxsdusize;
+               self->max_txbuff_size = max_sdu_size;
 
        self->qos = qos;
+       self->max_header_size = max_header_size;
+
        ircomm_do_event( self, TTP_CONNECT_INDICATION, skb);
 
        /* stop connecting */
@@ -556,7 +558,7 @@ static void issue_connect_request(struct ircomm_cb *self,
 
                irttp_connect_request(self->tsap, self->dlsap, 
                                      self->saddr, self->daddr, 
-                                     NULL, self->maxsdusize, userdata); 
+                                     NULL, self->max_sdu_size, userdata); 
                break;
 
        default:
@@ -588,9 +590,9 @@ static void connect_indication(struct ircomm_cb *self, struct qos_info *qos,
 /*     if( !ircomm_parse_controlchannel( self, data)) */
 /*             self->servicetype = DEFAULT;     TODOD:fix this! TH */
 
-       if(self->notify.connect_indication)
+       if (self->notify.connect_indication)
                self->notify.connect_indication(self->notify.instance, self, 
-                                               qos, 0, skb);
+                                               qos, 0, 0, skb);
 }
     
 #if 0
@@ -602,28 +604,26 @@ static void connect_indication_three_wire_raw(void)
 #endif 
 
 
-static void connect_confirmation(struct ircomm_cb *self, struct sk_buff *skb)
+static void connect_confirm(struct ircomm_cb *self, struct sk_buff *skb)
 {
        DEBUG(4 ,__FUNCTION__"()\n");
 
        /* give a connect_confirm to the client */
        if( self->notify.connect_confirm )
                self->notify.connect_confirm(self->notify.instance,
-                                            self, NULL, SAR_DISABLE, skb);
+                                            self, NULL, SAR_DISABLE, 0, skb);
 }
 
 static void issue_connect_response(struct ircomm_cb *self,
                                   struct sk_buff *skb)
 {
-
        DEBUG(0,__FUNCTION__"()\n");
        
        if( self->servicetype == THREE_WIRE_RAW){
                DEBUG(0,__FUNCTION__"():THREE_WIRE_RAW is not implemented yet\n");
                /* irlmp_connect_rsp(); */
-       } else {
-               irttp_connect_response(self->tsap, self->maxsdusize, skb);
-       }
+       } else
+               irttp_connect_response(self->tsap, self->max_sdu_size, skb);
 }
 
 static void issue_disconnect_request(struct ircomm_cb *self,
@@ -642,30 +642,29 @@ static void issue_data_request(struct ircomm_cb *self,
 {
        int err;
 
-       if(self->servicetype == THREE_WIRE_RAW){
+       if (self->servicetype == THREE_WIRE_RAW){
                /* irlmp_data_request(self->lmhandle,userdata); */
                DEBUG(0,__FUNCTION__"():not implemented!");
                return;
        }
 
        DEBUG(4,__FUNCTION__"():sending frame\n");
-       err = irttp_data_request(self->tsap , userdata  );
-       if(err){
+       err = irttp_data_request(self->tsap, userdata);
+       if (err){
                printk(KERN_ERR __FUNCTION__":ttp_data_request failed\n");
-               if(userdata)
+               if (userdata)
                        dev_kfree_skb( userdata);
        }
        self->tx_packets++;
 }
 
 static void issue_control_request(struct ircomm_cb *self,
-                                 struct sk_buff *userdata )
+                                 struct sk_buff *userdata)
 {
        int err;
 
        DEBUG(4,__FUNCTION__"()\n"); 
-       if(self->servicetype == THREE_WIRE_RAW)
-       {
+       if (self->servicetype == THREE_WIRE_RAW) {
                DEBUG(0,__FUNCTION__"():THREE_WIRE_RAW is not implemented\n");
                
        }
@@ -676,7 +675,7 @@ static void issue_control_request(struct ircomm_cb *self,
                {
                        printk( __FUNCTION__"():ttp_data_request failed\n");
                        if(userdata)
-                               dev_kfree_skb( userdata);
+                               dev_kfree_skb(userdata);
                }
                else
                        self->tx_controls++;
@@ -701,7 +700,7 @@ static void process_data(struct ircomm_cb *self, struct sk_buff *skb )
 
        /* ircomm_parse_control(self, skb, CONTROL_CHANNEL); */
 
-       if(self->notify.data_indication && skb->len)
+       if (self->notify.data_indication && skb->len)
                self->notify.data_indication(self->notify.instance, self,
                                             skb);
 }
@@ -728,7 +727,7 @@ static void ircomm_do_event( struct ircomm_cb *self, IRCOMM_EVENT event,
        
        DEBUG( 4, __FUNCTION__": STATE = %s, EVENT = %s\n",
               ircommstate[self->state], ircommevent[event]);
-       (*state[ self->state ]) ( self, event, skb);
+       (*state[self->state])(self, event, skb);
 }
 
 static void ircomm_next_state( struct ircomm_cb *self, IRCOMM_STATE state) 
@@ -747,7 +746,7 @@ static void ircomm_next_state( struct ircomm_cb *self, IRCOMM_STATE state)
 static void ircomm_state_idle( struct ircomm_cb *self, IRCOMM_EVENT event, 
                               struct sk_buff *skb )
 {
-       switch(event){
+       switch (event){
        case IRCOMM_CONNECT_REQUEST:
 
                /* ircomm_next_state(self, COMM_WAITI); */
@@ -779,7 +778,8 @@ static void ircomm_state_idle( struct ircomm_cb *self, IRCOMM_EVENT event,
 /*
  * ircomm_state_discoverywait
  */
-static void ircomm_state_discoverywait(struct ircomm_cb *self, IRCOMM_EVENT event, 
+static void ircomm_state_discoverywait(struct ircomm_cb *self, 
+                                      IRCOMM_EVENT event, 
                                       struct sk_buff *skb )
 {
        switch(event){
@@ -817,11 +817,11 @@ static void ircomm_state_discoverywait(struct ircomm_cb *self, IRCOMM_EVENT even
  * ircomm_state_queryparamwait
  */
 
-static void ircomm_state_queryparamwait(struct ircomm_cb *self, IRCOMM_EVENT event, 
-                                       struct sk_buff *skb )
+static void ircomm_state_queryparamwait(struct ircomm_cb *self, 
+                                       IRCOMM_EVENT event, 
+                                       struct sk_buff *skb)
 {
-       switch(event){
-
+       switch (event) {
        case TTP_CONNECT_INDICATION:
 
                ircomm_next_state(self, COMM_WAITR);
@@ -855,10 +855,11 @@ static void ircomm_state_queryparamwait(struct ircomm_cb *self, IRCOMM_EVENT eve
  * ircomm_state_querylsapwait
  */
 
-static void ircomm_state_querylsapwait(struct ircomm_cb *self, IRCOMM_EVENT event, 
+static void ircomm_state_querylsapwait(struct ircomm_cb *self, 
+                                      IRCOMM_EVENT event, 
                                       struct sk_buff *skb )
 {
-       switch(event){
+       switch (event) {
 
        case TTP_CONNECT_INDICATION:
 
@@ -898,10 +899,10 @@ static void ircomm_state_querylsapwait(struct ircomm_cb *self, IRCOMM_EVENT even
 static void ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event, 
                          struct sk_buff *skb )
 {
-       switch(event){
+       switch (event) {
        case TTP_CONNECT_CONFIRM:
                ircomm_next_state(self, COMM_CONN);
-               connect_confirmation( self, skb );
+               connect_confirm(self, skb );
                break;
        case TTP_DISCONNECT_INDICATION:
                ircomm_next_state(self, COMM_IDLE);
@@ -921,21 +922,18 @@ static void ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event,
        }
 }
 
-
-
 /*
  * ircomm_state_waitr
  */
 static void ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event, 
-                         struct sk_buff *skb ) 
+                              struct sk_buff *skb ) 
 {
-       
-       switch(event){
+       switch (event) {
        case IRCOMM_CONNECT_RESPONSE:
 
                /* issue_connect_response */
                
-               if(self->servicetype==THREE_WIRE_RAW){
+               if (self->servicetype==THREE_WIRE_RAW) {
                        DEBUG(0,__FUNCTION__"():3WIRE_RAW is not implemented\n");
                        /* irlmp_connect_response(Vpeersap,
                         *                         ACCEPT,null);
@@ -987,7 +985,7 @@ static void ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
 static void ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event, 
                              struct sk_buff *skb )
 {
-       switch(event){
+       switch (event) {
        case TTP_DATA_INDICATION:
                process_data(self, skb);
                break;
@@ -1033,8 +1031,6 @@ static void ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
        }
 }
 
-
-
 /*
  *  ----------------------------------------------------------------------
  *  IrCOMM service interfaces and supporting functions
@@ -1042,12 +1038,12 @@ static void ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
  *  ----------------------------------------------------------------------
  */
 
-/* 
- * start_discovering()
+/*
+ * Function start_discovering (self)
+ *
+ *    Start discovering and enter DISCOVERY_WAIT state
  *
- * start discovering and enter DISCOVERY_WAIT state
  */
-
 static void start_discovering(struct ircomm_cb *self)
 {
        __u16  hints; 
@@ -1092,19 +1088,26 @@ static void start_discovering(struct ircomm_cb *self)
 /*
  * queryias_done(self)
  *
- * called when discovery process got wrong results, completed, or terminated.
+ * 
  */
 
+/*
+ * Function queryias_done (self)
+ *
+ *    Called when discovery process got wrong results, completed, or
+ *    terminated.
+ * 
+ */
 static void queryias_done(struct ircomm_cb *self)
 {
        DEBUG(0, __FUNCTION__"():\n");
-       if(self->queryias_lock){
+       if (self->queryias_lock){
                self->queryias_lock = 0;
                discovering_instance = NULL;
                MOD_DEC_USE_COUNT;
                irlmp_unregister_client(self->ckey);
        }
-       if(ircomm_cs != 1)
+       if (ircomm_cs != 1)
                irlmp_unregister_service(self->skey);
        return;
 }
@@ -1120,7 +1123,6 @@ static void query_parameters(struct ircomm_cb *self)
                                       ircomm_getvalue_confirm, self );
 }
 
-
 static void query_lsapsel(struct ircomm_cb * self)
 {
        DEBUG(0, __FUNCTION__"():querying IAS: Lsapsel...\n");
@@ -1135,13 +1137,13 @@ static void query_lsapsel(struct ircomm_cb * self)
        }
 }
 
-/* 
- * ircomm_connect_request()
- * Impl. of this function is differ from one of the reference.
- * This functin does discovery as well as sending connect request
+/*
+ * Function ircomm_connect_request (self, servicetype)
+ *
+ *    Impl. of this function is differ from one of the reference. This
+ *    function does discovery as well as sending connect request
+ * 
  */
-
-
 void ircomm_connect_request(struct ircomm_cb *self, __u8 servicetype)
 {
        /*
@@ -1158,12 +1160,12 @@ void ircomm_connect_request(struct ircomm_cb *self, __u8 servicetype)
        self->servicetype= servicetype;
        /* ircomm_control_request(self, SERVICETYPE); */ /*servictype*/
 
-       self->maxsdusize = SAR_DISABLE;
-       ircomm_do_event( self, IRCOMM_CONNECT_REQUEST, NULL);
+       self->max_sdu_size = SAR_DISABLE;
+       ircomm_do_event(self, IRCOMM_CONNECT_REQUEST, NULL);
 }
 
 void ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata,
-                            __u32 maxsdusize)
+                            __u32 max_sdu_size)
 {
 
        ASSERT( self != NULL, return;);
@@ -1177,10 +1179,11 @@ void ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata,
         * and send it with connect_response
         */
 
-       if(!userdata){
+       if (!userdata){
                /* FIXME: check for errors and initialize? DB */
                userdata = dev_alloc_skb(COMM_DEFAULT_DATA_SIZE);
-               ASSERT(userdata != NULL, return;);
+               if (userdata == NULL)
+                       return;
 
                skb_reserve(userdata,COMM_HEADER_SIZE);
        }
@@ -1188,9 +1191,10 @@ void ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata,
        /* enable null-modem emulation (i.e. server mode )*/
        self->null_modem_mode = 1;
 
-       self->maxsdusize = maxsdusize;
-       if(maxsdusize != SAR_DISABLE)
-               self->max_txbuff_size = maxsdusize;
+       self->max_sdu_size = max_sdu_size;
+       if (max_sdu_size != SAR_DISABLE)
+               self->max_txbuff_size = max_sdu_size;
+
        ircomm_do_event(self, IRCOMM_CONNECT_RESPONSE, userdata);
 }      
 
@@ -1341,14 +1345,13 @@ static void append_tuple(struct ircomm_cb *self, __u8 instruction, __u8 pl ,
        self->control_ch_pending = 1;
 }
 
-
-
 /*
- * ircomm_control_request();
- * this function is exported as a request to send some control-channel tuples
- * to peer device
+ * Function ircomm_control_request (self, instruction)
+ *
+ *    This function is exported as a request to send some control-channel
+ *    tuples * to peer device
+ * 
  */
-
 void ircomm_control_request(struct ircomm_cb *self,  __u8 instruction)
 {
 
index 2df2fdd6015d98d8a4c176289b3667f50e9f2ed6..356913ff4cf84c982d746c927f02111cc1ef8bb5 100644 (file)
@@ -8,7 +8,7 @@
  * Source:        serial.c by Linus Torvalds
  *                isdn_tty.c by Fritz Elfert
  *
- *     Copyright (c) 1998, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
+ *     Copyright (c) 1998-1999, Takahide Higuchi, <thiguchi@pluto.dti.ne.jp>,
  *     All Rights Reserved.
  *
  *     This program is free software; you can redistribute it and/or
@@ -341,15 +341,15 @@ static void irvtd_send_data_request(struct irvtd_cb *driver)
  ***********************************************************************
  */
 
-
 /*
  * Function irvtd_connect_confirm (instance, sap, qos, max_sdu_size, skb)
  *
- *    ircomm_connect_request which we have send have succeed!
+ *    ircomm_connect_request which we have send, has succeeded!
  *
  */
 void irvtd_connect_confirm(void *instance, void *sap, struct qos_info *qos,
-                          __u32 max_sdu_size, struct sk_buff *skb)
+                          __u32 max_sdu_size, __u8 max_header_size, 
+                          struct sk_buff *skb)
 {
        struct irvtd_cb *driver = (struct irvtd_cb *)instance;
        ASSERT(driver != NULL, return;);
@@ -364,7 +364,7 @@ void irvtd_connect_confirm(void *instance, void *sap, struct qos_info *qos,
        /*
         * sending initial control parameters here
         */
-       if(driver->comm->servicetype == THREE_WIRE_RAW)
+       if (driver->comm->servicetype ==        THREE_WIRE_RAW)
                return;                /* do nothing */
 
        driver->comm->dte |= (MCR_DTR | MCR_RTS | DELTA_DTR | DELTA_RTS);
@@ -376,7 +376,7 @@ void irvtd_connect_confirm(void *instance, void *sap, struct qos_info *qos,
        ircomm_control_request(driver->comm, XON_XOFF_CHAR);
        /* ircomm_control_request(driver->comm, ENQ_ACK_CHAR); */
 
-       switch(driver->comm->servicetype){
+       switch (driver->comm->servicetype) {
        case CENTRONICS:
                break;
 
@@ -397,17 +397,18 @@ void irvtd_connect_confirm(void *instance, void *sap, struct qos_info *qos,
  *
  */
 void irvtd_connect_indication(void *instance, void *sap, struct qos_info *qos,
-                             __u32 max_sdu_size, struct sk_buff *skb)
+                             __u32 max_sdu_size, __u8 max_header_size, 
+                             struct sk_buff *skb)
 {
-
        struct irvtd_cb *driver = (struct irvtd_cb *)instance;
        struct ircomm_cb *comm = (struct ircomm_cb *)sap;
+
        ASSERT(driver != NULL, return;);
        ASSERT(driver->magic == IRVTD_MAGIC, return;);
        ASSERT(comm != NULL, return;);
        ASSERT(comm->magic == IRCOMM_MAGIC, return;);
 
-       DEBUG(4,"irvtd_connect_indication:sending connect_response...\n");
+       DEBUG(4, __FUNCTION__ "():sending connect_response...\n");
 
        ircomm_connect_response(comm, NULL, SAR_DISABLE );
 
@@ -416,7 +417,7 @@ void irvtd_connect_indication(void *instance, void *sap, struct qos_info *qos,
        /*
         * send initial control parameters
         */
-       if(driver->comm->servicetype == THREE_WIRE_RAW)
+       if (driver->comm->servicetype == THREE_WIRE_RAW)
                return;                /* do nothing */
 
        driver->comm->dte |= (MCR_DTR | MCR_RTS | DELTA_DTR | DELTA_RTS);
@@ -426,6 +427,7 @@ void irvtd_connect_indication(void *instance, void *sap, struct qos_info *qos,
                ircomm_control_request(driver->comm, DTELINE_STATE);
                break;
        default:
+               DEBUG(0, __FUNCTION__ "(), not implemented!\n");
        }
 
 
@@ -576,6 +578,7 @@ void irvtd_control_indication(void *instance, void *sap, IRCOMM_CMD cmd)
        case DATA_RATE:
        case XON_XOFF_CHAR:
        case DTELINE_STATE:
+       case ENQ_ACK_CHAR:      /* got this from win95 */
                /* (maybe) nothing to do  */
                break;
        default:
@@ -778,7 +781,7 @@ static int irvtd_startup(struct irvtd_cb *driver)
        skb_queue_head_init(&driver->rxbuff);
        driver->txbuff = dev_alloc_skb(COMM_DEFAULT_DATA_SIZE); 
        if (!driver->txbuff){
-               DEBUG(0,__FUNCTION__"():alloc_skb failed!\n");
+               DEBUG(0,__FUNCTION__"()alloc_skb failed!\n");
                return -ENOMEM;
        }
        skb_reserve(driver->txbuff, COMM_HEADER_SIZE);
@@ -793,9 +796,8 @@ static int irvtd_startup(struct irvtd_cb *driver)
        irvtd_notify.instance = driver;
 
        driver->comm = ircomm_open_instance(irvtd_notify);
-       if(!driver->comm){
+       if (!driver->comm)
                return -ENODEV;
-       }
 
 
        /* 
index cf9e6ea3441d90b0aac6640e28816a5b82567b65..d6452769fa7b581c2e155b6ea2b40cf0602b7a7d 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Wed Sep  2 20:22:08 1998
- * Modified at:   Wed Apr 21 09:48:19 1999
+ * Modified at:   Mon May 10 23:02:47 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -31,6 +31,8 @@
 #include <linux/netdevice.h>
 #include <linux/init.h>
 #include <linux/tty.h>
+#include <linux/kmod.h>
+#include <linux/wireless.h>
 
 #include <asm/ioctls.h>
 #include <asm/segment.h>
@@ -53,7 +55,8 @@ extern int tekram_init(void);
 extern int actisys_init(void);
 extern int girbil_init(void);
 
-hashbin_t *irda_device = NULL;
+static hashbin_t *irda_device = NULL;
+static hashbin_t *dongles = NULL;
 
 /* Netdevice functions */
 static int irda_device_net_rebuild_header(struct sk_buff *skb);
@@ -61,9 +64,9 @@ static int irda_device_net_hard_header(struct sk_buff *skb,
                                       struct device *dev,
                                       unsigned short type, void *daddr, 
                                       void *saddr, unsigned len);
-static int irda_device_net_set_config( struct device *dev, struct ifmap *map);
-static int irda_device_net_change_mtu( struct device *dev, int new_mtu);
-
+static int irda_device_net_set_config(struct device *dev, struct ifmap *map);
+static int irda_device_net_change_mtu(struct device *dev, int new_mtu);
+static int irda_device_net_ioctl(struct device *dev, struct ifreq *rq,int cmd);
 #ifdef CONFIG_PROC_FS
 int irda_device_proc_read( char *buf, char **start, off_t offset, int len, 
                           int unused);
@@ -74,8 +77,15 @@ __initfunc(int irda_device_init( void))
 {
        /* Allocate master array */
        irda_device = hashbin_new( HB_LOCAL);
-       if ( irda_device == NULL) {
-               printk( KERN_WARNING "IrDA: Can't allocate irda_device hashbin!\n");
+       if (irda_device == NULL) {
+               WARNING("IrDA: Can't allocate irda_device hashbin!\n");
+               return -ENOMEM;
+       }
+
+       dongles = hashbin_new(HB_LOCAL);
+       if (dongles == NULL) {
+               printk(KERN_WARNING 
+                      "IrDA: Can't allocate dongles hashbin!\n");
                return -ENOMEM;
        }
 
@@ -113,6 +123,7 @@ void irda_device_cleanup(void)
 
        ASSERT(irda_device != NULL, return;);
 
+       hashbin_delete(dongles, NULL);
        hashbin_delete(irda_device, (FREE_FUNC) irda_device_close);
 }
 
@@ -238,7 +249,7 @@ void __irda_device_close(struct irda_device *self)
 /*
  * Function irda_device_close (self)
  *
- *    
+ *    Close the device
  *
  */
 void irda_device_close(struct irda_device *self)
@@ -248,6 +259,10 @@ void irda_device_close(struct irda_device *self)
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;);
 
+       /* We are not using any dongle anymore! */
+       if (self->dongle)
+               self->dongle->close(self);
+
        /* Stop and remove instance of IrLAP */
        if (self->irlap)
                irlap_close(self->irlap);
@@ -298,15 +313,19 @@ static void __irda_device_change_speed(struct irda_device *self, int speed)
         */
        if (self->wait_until_sent) {
                self->wait_until_sent(self);
+               
+               if (self->dongle)
+                       self->dongle->change_speed(self, speed);
+               
                if (self->change_speed) {
                        self->change_speed(self, speed);
-
+                       
                        /* Update the QoS value only */
                        self->qos.baud_rate.value = speed;
                }
        } else {
-               printk(KERN_WARNING "wait_until_sent() "
-                      "has not implemented by the IrDA device driver!\n");
+               WARNING("IrDA: wait_until_sent() "
+                       "has not implemented by the IrDA device driver!\n");
        }
 }
 
@@ -386,6 +405,7 @@ int irda_device_setup(struct device *dev)
        dev->set_config      = irda_device_net_set_config;
        dev->change_mtu      = irda_device_net_change_mtu;
 /*     dev->hard_header     = irda_device_net_hard_header; */
+       dev->do_ioctl        = irda_device_net_ioctl;
         dev->hard_header_len = 0;
         dev->addr_len        = 0;
 
@@ -444,6 +464,125 @@ static int irda_device_net_change_mtu( struct device *dev, int new_mtu)
      return 0;  
 }
 
+static int irda_device_net_ioctl(struct device *dev, /* ioctl device */
+                                struct ifreq *rq,   /* Data passed */
+                                int    cmd)         /* Ioctl number */
+{
+       unsigned long flags;
+       int                     ret = 0;
+#ifdef WIRELESS_EXT
+       struct iwreq *wrq = (struct iwreq *) rq;
+#endif
+       struct irda_device *self;
+
+       DEBUG(4, __FUNCTION__ "()\n");
+
+       ASSERT(dev != NULL, return -1;);
+
+       self = (struct irda_device *) dev->priv;
+
+       ASSERT(self != NULL, return -1;);
+       ASSERT(self->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+       DEBUG(0, "%s: ->irda_device_net_ioctl(cmd=0x%X)\n", dev->name, cmd);
+       
+       /* Disable interrupts & save flags */
+       save_flags(flags);
+       cli();
+       
+       /* Look what is the request */
+       switch (cmd) {
+#ifdef WIRELESS_EXT
+       case SIOCGIWNAME:
+               /* Get name */
+               strcpy(wrq->u.name, self->name);
+               break;
+       case SIOCSIWNWID:
+               /* Set domain */
+               if (wrq->u.nwid.on) {
+                       
+               } break;
+       case SIOCGIWNWID:
+               /* Read domain*/
+/*             wrq->u.nwid.nwid = domain; */
+/*             wrq->u.nwid.on = 1; */
+               break;
+       case SIOCGIWENCODE:
+               /* Get scramble key */
+               /*      wrq->u.encoding.code = scramble_key; */
+/*             wrq->u.encoding.method = 1; */
+               break;
+       case SIOCSIWENCODE:
+               /* Set  scramble key */
+               /* scramble_key = wrq->u.encoding.code; */
+               break;
+       case SIOCGIWRANGE:
+               /* Basic checking... */
+               if(wrq->u.data.pointer != (caddr_t) 0) {
+                       struct iw_range range;
+                       
+                       /* Verify the user buffer */
+                       ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,
+                                         sizeof(struct iw_range));
+                       if(ret)
+                               break;
+                       
+                       /* Set the length (useless : its constant...) */
+                       wrq->u.data.length = sizeof(struct iw_range);
+                       
+                       /* Set information in the range struct */
+                       range.throughput = 1.6 * 1024 * 1024;   /* don't argue on this ! */
+                       range.min_nwid = 0x0000;
+                       range.max_nwid = 0x01FF;
+                       
+                       range.num_channels = range.num_frequency = 0;
+                       
+                       range.sensitivity = 0x3F;
+                       range.max_qual.qual = 255;
+                       range.max_qual.level = 255;
+                       range.max_qual.noise = 0;
+                       
+                       /* Copy structure to the user buffer */
+                       copy_to_user(wrq->u.data.pointer, &range,
+                                    sizeof(struct iw_range));
+               }
+               break;
+       case SIOCGIWPRIV:
+               /* Basic checking... */
+#if 0
+               if (wrq->u.data.pointer != (caddr_t) 0) {
+                       struct iw_priv_args     priv[] =
+                       {       /* cmd,         set_args,       get_args,       name */
+                               { SIOCGIPSNAP, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 0, 
+                                 sizeof(struct site_survey), 
+                                 "getsitesurvey" },
+                       };
+                       
+                       /* Verify the user buffer */
+                       ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,
+                                         sizeof(priv));
+                       if (ret)
+                               break;
+                       
+                       /* Set the number of ioctl available */
+                       wrq->u.data.length = 1;
+                       
+                       /* Copy structure to the user buffer */
+                       copy_to_user(wrq->u.data.pointer, (u_char *) priv,
+                                    sizeof(priv));
+               }
+#endif 
+               break;
+#endif
+       default:
+               ret = -EOPNOTSUPP;
+       }
+       
+       restore_flags(flags);
+       
+       return ret;
+}
+
 /*
  * Function irda_device_transmit_finished (void)
  *
@@ -451,7 +590,7 @@ static int irda_device_net_change_mtu( struct device *dev, int new_mtu)
  *    device. Maybe we should use: q->q.qlen == 0.
  *
  */
-int irda_device_txqueue_empty( struct irda_device *self)
+int irda_device_txqueue_empty(struct irda_device *self)
 {
        ASSERT(self != NULL, return -1;);
        ASSERT(self->magic == IRDA_DEVICE_MAGIC, return -1;);   
@@ -462,6 +601,117 @@ int irda_device_txqueue_empty( struct irda_device *self)
        return TRUE;
 }
 
+/*
+ * Function irda_device_init_dongle (self, type)
+ *
+ *    Initialize attached dongle. Warning, must be called with a process
+ *    context!
+ */
+void irda_device_init_dongle(struct irda_device *self, int type)
+{
+       struct dongle_q *node;
+
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;);
+
+#ifdef CONFIG_KMOD
+       /* Try to load the module needed */
+       switch (type) {
+       case ESI_DONGLE:
+               MESSAGE("IrDA: Initializing ESI dongle!\n");
+               request_module("esi");
+               break;
+       case TEKRAM_DONGLE:
+               MESSAGE("IrDA: Initializing Tekram dongle!\n");
+               request_module("tekram");
+               break;
+       case ACTISYS_DONGLE:     /* FALLTHROUGH */
+       case ACTISYS_PLUS_DONGLE:
+               MESSAGE("IrDA: Initializing ACTiSYS dongle!\n");
+               request_module("actisys");
+               break;
+       case GIRBIL_DONGLE:
+               MESSAGE("IrDA: Initializing GIrBIL dongle!\n");
+               request_module("girbil");
+               break;
+       case LITELINK_DONGLE:
+               MESSAGE("IrDA: Initializing Litelink dongle!\n");
+               request_module("litelink");
+               break;
+       default:
+               ERROR("Unknown dongle type!\n");
+               return;
+       }
+#endif /* CONFIG_KMOD */
+
+       node = hashbin_find(dongles, type, NULL);
+       if (!node) {
+               ERROR("IrDA: Unable to find requested dongle\n");
+               return;
+       }
+
+       /* Set the dongle to be used by this driver */
+       self->dongle = node->dongle;
+
+       /* Now initialize the dongle!  */
+       node->dongle->open(self, type);
+       node->dongle->qos_init(self, &self->qos);
+       
+       /* Reset dongle */
+       node->dongle->reset(self, 0);
+
+       /* Set to default baudrate */
+       irda_device_change_speed(self, 9600);
+}
+
+/*
+ * Function irda_device_register_dongle (dongle)
+ *
+ *    
+ *
+ */
+int irda_device_register_dongle(struct dongle *dongle)
+{
+       struct dongle_q *new;
+       
+       /* Check if this dongle has been registred before */
+       if (hashbin_find(dongles, dongle->type, NULL)) {
+               MESSAGE(__FUNCTION__ "(), Dongle already registered\n");
+                return 0;
+        }
+       
+       /* Make new IrDA dongle */
+        new = (struct dongle_q *) kmalloc(sizeof(struct dongle_q), GFP_KERNEL);
+        if (new == NULL)
+                return -1;
+               
+       memset(new, 0, sizeof( struct dongle_q));
+        new->dongle = dongle;
+
+       /* Insert IrDA dongle into hashbin */
+       hashbin_insert(dongles, (QUEUE *) new, dongle->type, NULL);
+       
+        return 0;
+}
+
+/*
+ * Function irda_device_unregister_dongle (dongle)
+ *
+ *    
+ *
+ */
+void irda_device_unregister_dongle(struct dongle *dongle)
+{
+       struct dongle_q *node;
+
+       node = hashbin_remove(dongles, dongle->type, NULL);
+       if (!node) {
+               ERROR(__FUNCTION__ "(), dongle not found!\n");
+               return;
+       }
+       kfree(node);
+}
+
 /*
  * Function setup_dma (idev, buffer, count, mode)
  *
@@ -536,7 +786,7 @@ int irda_device_proc_read(char *buf, char **start, off_t offset, int len,
 
        self = (struct irda_device *) hashbin_get_first(irda_device);
        while ( self != NULL) {
-               len += sprintf(buf+len, "%s,", self->name);
+               len += sprintf(buf+len, "\n%s,", self->name);
                len += sprintf(buf+len, "\tbinding: %s\n", 
                               self->description);
                
index b87ccbd028143fb861c6c4a0e4d88461ce2f2f4d..f3b752eb05fda9319cc367db11910907ad027c3c 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Fri Apr 23 09:57:12 1999
+ * Modified at:   Sun May  9 15:59:05 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, 
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -62,12 +62,17 @@ static __u32 service_handle;
 extern char *lmp_reasons[];
 
 static struct iriap_cb *iriap_open( __u8 slsap, int mode);
-static void __iriap_close( struct iriap_cb *self);
+static void __iriap_close(struct iriap_cb *self);
 static void iriap_disconnect_indication(void *instance, void *sap, 
                                        LM_REASON reason, struct sk_buff *skb);
 static void iriap_connect_indication(void *instance, void *sap, 
                                     struct qos_info *qos, __u32 max_sdu_size,
+                                    __u8 max_header_size, 
                                     struct sk_buff *skb);
+static void iriap_connect_confirm(void *instance, void *sap, 
+                                 struct qos_info *qos, 
+                                 __u32 max_sdu_size, __u8 max_header_size,
+                                 struct sk_buff *skb);
 static int iriap_data_indication(void *instance, void *sap, 
                                 struct sk_buff *skb);
 
@@ -181,7 +186,7 @@ struct iriap_cb *iriap_open( __u8 slsap_sel, int mode)
        self->slsap_sel = slsap_sel;
        self->mode = mode;
 
-       init_timer( &self->watchdog_timer);
+       init_timer(&self->watchdog_timer);
 
        hashbin_insert( iriap, (QUEUE*) self, slsap_sel, NULL);
        
@@ -206,7 +211,7 @@ static void __iriap_close( struct iriap_cb *self)
        ASSERT( self != NULL, return;);
        ASSERT( self->magic == IAS_MAGIC, return;);
 
-       del_timer( &self->watchdog_timer);
+       del_timer(&self->watchdog_timer);
 
        self->magic = 0;
 
@@ -260,7 +265,7 @@ static void iriap_disconnect_indication( void *instance, void *sap,
 
        ASSERT( iriap != NULL, return;);
 
-       del_timer( &self->watchdog_timer);
+       del_timer(&self->watchdog_timer);
 
        if ( self->mode == IAS_CLIENT) {
                DEBUG( 4, __FUNCTION__ "(), disconnect as client\n");
@@ -284,9 +289,8 @@ static void iriap_disconnect_indication( void *instance, void *sap,
                                       NULL);
        }
 
-       if ( userdata) {
+       if (userdata)
                dev_kfree_skb( userdata);
-       }
 }
 
 /*
@@ -295,28 +299,28 @@ static void iriap_disconnect_indication( void *instance, void *sap,
  *    
  *
  */
-void iriap_disconnect_request( struct iriap_cb *self)
+void iriap_disconnect_request(struct iriap_cb *self)
 {
        struct sk_buff *skb;
 
-       DEBUG( 4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
 
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == IAS_MAGIC, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IAS_MAGIC, return;);
 
-       skb = dev_alloc_skb( 64);
+       skb = dev_alloc_skb(64);
        if (skb == NULL) {
-               DEBUG( 0, __FUNCTION__
-                      "(), Could not allocate an sk_buff of length %d\n", 64);
+               DEBUG(0, __FUNCTION__
+                     "(), Could not allocate an sk_buff of length %d\n", 64);
                return;
        }
 
        /* 
-        *  Reserve space for MUX and LAP header 
+        *  Reserve space for MUX control and LAP header 
         */
-       skb_reserve( skb, LMP_CONTROL_HEADER+LAP_HEADER);
+       skb_reserve(skb, LMP_MAX_HEADER);
 
-       irlmp_disconnect_request( self->lsap, skb);
+       irlmp_disconnect_request(self->lsap, skb);
 }
 
 void iriap_getinfobasedetails_request(void) 
@@ -381,7 +385,7 @@ void iriap_getvaluebyclass_request(char *name, char *attr,
        /* Give ourselves 10 secs to finish this operation */
        iriap_start_watchdog_timer(self, 10*HZ);
        
-       skb = dev_alloc_skb( 64);
+       skb = dev_alloc_skb(64);
        if (!skb)
                return;
 
@@ -389,7 +393,7 @@ void iriap_getvaluebyclass_request(char *name, char *attr,
        attr_len = strlen(attr);
 
        /* Reserve space for MUX and LAP header */
-       skb_reserve(skb, LMP_CONTROL_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->max_header_size);
        skb_put(skb, 3+name_len+attr_len);
        frame = skb->data;
 
@@ -535,13 +539,13 @@ void iriap_getvaluebyclass_response(struct iriap_cb *self, __u16 obj_id,
         *  value. We add 9 bytes because of the 6 bytes for the frame and
         *  max 3 bytes for the value coding.
         */
-       skb = dev_alloc_skb(value->len + LMP_HEADER + LAP_HEADER + 9);
+       skb = dev_alloc_skb(value->len + self->max_header_size + 9);
        if (!skb)
                return;
 
        /* Reserve space for MUX and LAP header */
-       skb_reserve( skb, LMP_HEADER+LAP_HEADER);
-       skb_put( skb, 6);
+       skb_reserve(skb, self->max_header_size);
+       skb_put(skb, 6);
        
        fp = skb->data;
 
@@ -666,7 +670,7 @@ void iriap_getvaluebyclass_indication(struct iriap_cb *self,
 /*
  * Function iriap_send_ack (void)
  *
- *    
+ *    Currently not used
  *
  */
 void iriap_send_ack( struct iriap_cb *self) 
@@ -679,13 +683,13 @@ void iriap_send_ack( struct iriap_cb *self)
        ASSERT( self != NULL, return;);
        ASSERT( self->magic == IAS_MAGIC, return;);
 
-       skb = dev_alloc_skb( 64);
+       skb = dev_alloc_skb(64);
        if (!skb)
                return;
 
        /* Reserve space for MUX and LAP header */
-       skb_reserve( skb, 4);
-       skb_put( skb, 3);
+       skb_reserve(skb, self->max_header_size);
+       skb_put(skb, 1);
        frame = skb->data;
 
        /* Build frame */
@@ -698,8 +702,10 @@ void iriap_send_ack( struct iriap_cb *self)
  *    LSAP connection confirmed!
  *
  */
-void iriap_connect_confirm(void *instance, void *sap, struct qos_info *qos, 
-                          __u32 max_sdu_size, struct sk_buff *userdata)
+static void iriap_connect_confirm(void *instance, void *sap, 
+                                 struct qos_info *qos, 
+                                 __u32 max_sdu_size, __u8 header_size, 
+                                 struct sk_buff *userdata)
 {
        struct iriap_cb *self;
        
@@ -711,7 +717,7 @@ void iriap_connect_confirm(void *instance, void *sap, struct qos_info *qos,
        
        DEBUG(4, __FUNCTION__ "()\n");
        
-       /* del_timer( &self->watchdog_timer); */
+       del_timer(&self->watchdog_timer);
 
        iriap_do_client_event(self, IAP_LM_CONNECT_CONFIRM, userdata);
 }
@@ -724,19 +730,17 @@ void iriap_connect_confirm(void *instance, void *sap, struct qos_info *qos,
  */
 static void iriap_connect_indication(void *instance, void *sap, 
                                     struct qos_info *qos, __u32 max_sdu_size,
+                                    __u8 header_size, 
                                     struct sk_buff *userdata)
 {
        struct iriap_cb *self;
 
-       DEBUG( 4, __FUNCTION__ "()\n");
-
-       self = ( struct iriap_cb *) instance;
+       self = (struct iriap_cb *) instance;
 
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == IAS_MAGIC, return;);
-       ASSERT( self->mode == IAS_SERVER, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IAS_MAGIC, return;);
 
-       iriap_do_server_event( self, IAP_LM_CONNECT_INDICATION, userdata);
+       iriap_do_server_event(self, IAP_LM_CONNECT_INDICATION, userdata);
 }
  
 /*
@@ -856,7 +860,7 @@ void iriap_call_indication( struct iriap_cb *self, struct sk_buff *skb)
        }
        opcode &= 0x7f; /* Mask away LST bit */
        
-       switchopcode) {
+       switch (opcode) {
        case GET_INFO_BASE:
                DEBUG( 0, "IrLMP GetInfoBaseDetails not implemented!\n");
                break;
index ccba78ecefc2d65d87640f1483324cc6066a730e..18a70fec3e6a1f546afaeb64a3337d0624ecca28 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Tue Jan 26 12:29:36 1999
+ * Modified at:   Sun May  9 11:01:47 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -387,9 +387,9 @@ static void state_r_disconnect( struct iriap_cb *self, IRIAP_EVENT event,
                }
 
                /* Reserve space for MUX_CONTROL and LAP header */
-               skb_reserve( tx_skb, LMP_CONTROL_HEADER+LAP_HEADER);
+               skb_reserve(tx_skb, LMP_MAX_HEADER);
                
-               irlmp_connect_response( self->lsap, tx_skb);
+               irlmp_connect_response(self->lsap, tx_skb);
                /*LM_Idle_request(idle); */
                
                iriap_next_server_state( self, R_CALL);
index f2f8271cf5a0c465503251e08ccb0a4c391c940a..66b94eec8092e251ff0e68e52cb15bb77fd47624 100644 (file)
@@ -6,13 +6,14 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Apr 22 23:03:55 1999
+ * Modified at:   Tue May 11 00:22:39 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
  *                slip.c by Laurence Culhane, <loz@holmes.demon.co.uk>
  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -61,6 +62,7 @@ static int irlan_client_ctrl_data_indication(void *instance, void *sap,
 static void irlan_client_ctrl_connect_confirm(void *instance, void *sap, 
                                              struct qos_info *qos, 
                                              __u32 max_sdu_size,
+                                             __u8 max_header_size,
                                              struct sk_buff *);
 static void irlan_check_response_param(struct irlan_cb *self, char *param, 
                                       char *value, int val_len);
@@ -79,7 +81,7 @@ static void irlan_client_kick_timer_expired(unsigned long data)
         * indication it needs to make progress. If the client is still in 
         * IDLE state, we must kick it to, but only if the provider is not IDLE
         */
-       if ((self->access_type == ACCESS_PEER) && 
+       if ((self->provider.access_type == ACCESS_PEER) && 
            (self->client.state == IRLAN_IDLE) &&
            (self->provider.state != IRLAN_IDLE)) {
                irlan_client_wakeup(self, self->saddr, self->daddr);
@@ -105,23 +107,29 @@ void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr)
 {
        struct irmanager_event mgr_event;
 
-       DEBUG(0, __FUNCTION__ "()\n");
+       DEBUG(1, __FUNCTION__ "()\n");
 
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-       /* Check if we are already awake */
-       if (self->client.state != IRLAN_IDLE)
+       /* 
+        * Check if we are already awake, or if we are a provider in direct
+        * mode (in that case we must leave the client idle
+        */
+       if ((self->client.state != IRLAN_IDLE) || 
+           (self->provider.access_type == ACCESS_DIRECT))
                return;
 
        /* saddr may have changed! */
        self->saddr = saddr;
        
-       /* Check if network device is up */
+       /* Before we try to connect, we check if network device is up. If it
+        * is up, that means that the "user" really wants to connect. If not
+        * we notify the user about the possibility of an IrLAN connection
+        */
        if (self->dev.start) {
                /* Open TSAPs */
                irlan_client_open_ctrl_tsap(self);
-               irlan_provider_open_ctrl_tsap(self);
                irlan_open_data_tsap(self);
                
                irlan_do_client_event(self, IRLAN_DISCOVERY_INDICATION, NULL);
@@ -161,7 +169,7 @@ void irlan_client_discovery_indication(discovery_t *discovery)
        struct irlan_cb *self, *entry;
        __u32 saddr, daddr;
        
-       DEBUG(0, __FUNCTION__"()\n");
+       DEBUG(1, __FUNCTION__"()\n");
 
        ASSERT(irlan != NULL, return;);
        ASSERT(discovery != NULL, return;);
@@ -176,7 +184,8 @@ void irlan_client_discovery_indication(discovery_t *discovery)
        if (self) {
                ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-               DEBUG(2, __FUNCTION__ "(), Found instance!\n");
+               DEBUG(1, __FUNCTION__ "(), Found instance (%08x)!\n",
+                     daddr);
                
                irlan_client_wakeup(self, saddr, daddr);
 
@@ -184,30 +193,13 @@ void irlan_client_discovery_indication(discovery_t *discovery)
        }
        
        /* 
-        * We have no instance for daddr, so try and find an unused one
+        * We have no instance for daddr, so start a new one
         */
-       self = hashbin_find(irlan, DEV_ADDR_ANY, NULL);
-       if (self) {
-               DEBUG(0, __FUNCTION__ "(), Found instance with DEV_ADDR_ANY!\n");
-               /*
-                * Rehash instance, now we have a client (daddr) to serve.
-                */
-               entry = hashbin_remove(irlan, self->daddr, NULL);
-               ASSERT(entry == self, return;);
-
-               self->daddr = daddr;
-               self->saddr = saddr;
+       DEBUG(1, __FUNCTION__ "(), starting new instance!\n");
+       self = irlan_open(saddr, daddr, TRUE);
 
-               DEBUG(0, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
-               hashbin_insert(irlan, (QUEUE*) self, self->daddr, NULL);
-               
-               /* Check if network device has been registered */
-               if (!self->netdev_registered)
-                       irlan_register_netdev(self);
-               
-               /* Restart watchdog timer */
-               irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
-       }
+       /* Restart watchdog timer */
+       irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
 }
        
 /*
@@ -302,6 +294,7 @@ void irlan_client_open_ctrl_tsap(struct irlan_cb *self)
 static void irlan_client_ctrl_connect_confirm(void *instance, void *sap, 
                                              struct qos_info *qos, 
                                              __u32 max_sdu_size,
+                                             __u8 max_header_size,
                                              struct sk_buff *skb) 
 {
        struct irlan_cb *self;
@@ -313,6 +306,9 @@ static void irlan_client_ctrl_connect_confirm(void *instance, void *sap,
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRLAN_MAGIC, return;);
 
+       self->client.max_sdu_size = max_sdu_size;
+       self->client.max_header_size = max_header_size;
+
        /* TODO: we could set the MTU depending on the max_sdu_size */
 
        irlan_do_client_event(self, IRLAN_CONNECT_COMPLETE, NULL);
@@ -339,7 +335,7 @@ void irlan_client_reconnect_data_channel(struct irlan_cb *self)
                return;
 
        /* Reserve space for TTP, LMP, and LAP header */
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->max_header_size);
        skb_put(skb, 2);
        
        frame = skb->data;
@@ -410,11 +406,11 @@ void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb)
        /* For all parameters */
        for (i=0; i<count;i++) {
                ret = irlan_extract_param(ptr, name, value, &val_len);
-               if (ret == -1) {
+               if (ret < 0) {
                        DEBUG(2, __FUNCTION__ "(), IrLAN, Error!\n");
                        break;
                }
-               ptr+=ret;
+               ptr += ret;
                irlan_check_response_param(self, name, value, val_len);
        }
        /* Cleanup */
@@ -423,9 +419,9 @@ void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb)
 }
 
 /*
- * Function check_param (param, value)
+ * Function irlan_check_response_param (self, param, value, val_len)
  *
- *    Check which parameter is received and update local variables
+ *     Check which parameter is received and update local variables
  *
  */
 static void irlan_check_response_param(struct irlan_cb *self, char *param, 
@@ -469,11 +465,11 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param,
        }
        if (strcmp(param, "ACCESS_TYPE") == 0) {
                if (strcmp(value, "DIRECT") == 0)
-                       self->access_type = ACCESS_DIRECT;
+                       self->client.access_type = ACCESS_DIRECT;
                else if (strcmp(value, "PEER") == 0)
-                       self->access_type = ACCESS_PEER;
+                       self->client.access_type = ACCESS_PEER;
                else if (strcmp(value, "HOSTED") == 0)
-                       self->access_type = ACCESS_HOSTED;
+                       self->client.access_type = ACCESS_HOSTED;
                else {
                        DEBUG(2, __FUNCTION__ "(), unknown access type!\n");
                }
index 1544c093e14dc7560b55dc364f078092e94fc7b0..682cda8540e9e647bd362f74c06d53e43275a503 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Apr 22 12:23:22 1999
+ * Modified at:   Thu May  6 13:42:38 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, 
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -97,7 +97,7 @@ static int irlan_client_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
        ASSERT(self != NULL, return -1;);
        ASSERT(self->magic == IRLAN_MAGIC, return -1;);
        
-       switch(event) {
+       switch (event) {
        case IRLAN_DISCOVERY_INDICATION:
                /* Get some values from peer IAS */
                iriap_getvaluebyclass_request(
@@ -152,7 +152,7 @@ static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event,
                irlan_next_client_state(self, IRLAN_IDLE);
 
                /* Give the client a kick! */
-               if ((self->access_type == ACCESS_PEER) && 
+               if ((self->provider.access_type == ACCESS_PEER) && 
                    (self->provider.state != IRLAN_IDLE))
                        irlan_client_wakeup(self, self->saddr, self->daddr);
                break;
@@ -222,7 +222,7 @@ static int irlan_client_state_info(struct irlan_cb *self, IRLAN_EVENT event,
 
        ASSERT(self != NULL, return -1;);
        
-       switch(event) {
+       switch (event) {
        case IRLAN_DATA_INDICATION:
                ASSERT(skb != NULL, return -1;);
        
@@ -314,7 +314,7 @@ static int irlan_client_state_open(struct irlan_cb *self, IRLAN_EVENT event,
                ASSERT(self->dtsap_sel_data != 0, return -1;);
 
                /* Check which access type we are dealing with */
-               switch(self->access_type) {
+               switch (self->client.access_type) {
                case ACCESS_PEER:
                    if (self->provider.state == IRLAN_OPEN) {
                            
index 6a30574ca765951ffa3aa58d4079a02899a5f6b8..1284d561a7fa8ccef075b182fa998db85892acc3 100644 (file)
@@ -6,10 +6,11 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Apr 22 23:13:47 1999
+ * Modified at:   Sun May  9 11:48:49 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -93,19 +94,25 @@ static void __irlan_close(struct irlan_cb *self);
 static int __irlan_insert_param(struct sk_buff *skb, char *param, int type, 
                                __u8 value_byte, __u16 value_short, 
                                __u8 *value_array, __u16 value_len);
-static void irlan_close_tsaps(struct irlan_cb *self);
+void irlan_close_tsaps(struct irlan_cb *self);
 
 #ifdef CONFIG_PROC_FS
 static int irlan_proc_read(char *buf, char **start, off_t offset, int len, 
                           int unused);
 
 extern struct proc_dir_entry *proc_irda;
-#endif
+#endif /* CONFIG_PROC_FS */
 
+/*
+ * Function irlan_watchdog_timer_expired (data)
+ *
+ *    
+ *
+ */
 void irlan_watchdog_timer_expired(unsigned long data)
 {
        struct irmanager_event mgr_event;
-       struct irlan_cb *self, *entry;
+       struct irlan_cb *self;
        
        DEBUG(0, __FUNCTION__ "()\n");
 
@@ -116,6 +123,7 @@ void irlan_watchdog_timer_expired(unsigned long data)
 
        /* Check if device still configured */
        if (self->dev.start) {
+               DEBUG(0, __FUNCTION__ "(), notifying irmanager to stop irlan!\n");
                mgr_event.event = EVENT_IRLAN_STOP;
                sprintf(mgr_event.devname, "%s", self->ifname);
                irmanager_notify(&mgr_event);
@@ -128,22 +136,13 @@ void irlan_watchdog_timer_expired(unsigned long data)
                 */
                self->notify_irmanager = FALSE;
        } else {
-               DEBUG(0, __FUNCTION__ "(), recycling instance!\n");
+               DEBUG(0, __FUNCTION__ "(), closing instance!\n");
                if (self->netdev_registered) {
                        DEBUG(0, __FUNCTION__ "(), removing netdev!\n");
                        unregister_netdev(&self->dev);
                        self->netdev_registered = FALSE;
                }
-
-               /* Unbind from daddr */
-               entry = hashbin_remove(irlan, self->daddr, NULL);
-               ASSERT(entry == self, return;);
-
-               self->daddr = DEV_ADDR_ANY;
-               self->saddr = DEV_ADDR_ANY;
-
-               DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
-               hashbin_insert(irlan, (QUEUE*) self, self->daddr, NULL);
+               irlan_close(self);
        }
 }
 
@@ -195,12 +194,12 @@ __initfunc(int irlan_init(void))
        /* Register with IrLMP as a service */
        skey = irlmp_register_service(hints);
 
-       /* Start the first IrLAN instance */
+       /* Start the master IrLAN instance */
        new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY, FALSE);
 
-       irlan_open_data_tsap(new);
-       irlan_client_open_ctrl_tsap(new);
+       /* The master will only open its (listen) control TSAP */
        irlan_provider_open_ctrl_tsap(new);
+       new->master = TRUE;
 
        /* Do some fast discovery! */
        irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
@@ -293,7 +292,7 @@ struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr, int netdev)
        self->daddr = daddr;
 
        /* Provider access can only be PEER, DIRECT, or HOSTED */
-       self->access_type = access;
+       self->provider.access_type = access;
        self->media = MEDIA_802_3;
 
        self->notify_irmanager = TRUE;
@@ -359,8 +358,11 @@ void irlan_close(struct irlan_cb *self)
 
        /* Check if device is still configured */
        if (self->dev.start) {
-               DEBUG(2, __FUNCTION__ 
+               DEBUG(0, __FUNCTION__ 
                       "(), Device still configured, closing later!\n");
+
+               /* Give it a chance to reconnect */
+               irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
                return;
        }
        DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
@@ -371,8 +373,15 @@ void irlan_close(struct irlan_cb *self)
         __irlan_close(self);
 }
 
+/*
+ * Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb)
+ *
+ *    Here we receive the connect indication for the data channel
+ *
+ */
 void irlan_connect_indication(void *instance, void *sap, struct qos_info *qos,
-                             __u32 max_sdu_size, struct sk_buff *skb)
+                             __u32 max_sdu_size, __u8 max_header_size, 
+                             struct sk_buff *skb)
 {
        struct irlan_cb *self;
        struct tsap_cb *tsap;
@@ -386,13 +395,17 @@ void irlan_connect_indication(void *instance, void *sap, struct qos_info *qos,
        ASSERT(self->magic == IRLAN_MAGIC, return;);
        ASSERT(tsap == self->tsap_data,return;);
 
-       DEBUG(2, "IrLAN, We are now connected!\n");
+       self->max_sdu_size = max_sdu_size;
+       self->max_header_size = max_header_size;
+
+       DEBUG(0, "IrLAN, We are now connected!\n");
+
        del_timer(&self->watchdog_timer);
 
        irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, skb);
        irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, skb);
 
-       if (self->access_type == ACCESS_PEER) {
+       if (self->provider.access_type == ACCESS_PEER) {
                /* 
                 * Data channel is open, so we are now allowed to
                 * configure the remote filter 
@@ -400,12 +413,13 @@ void irlan_connect_indication(void *instance, void *sap, struct qos_info *qos,
                irlan_get_unicast_addr(self);
                irlan_open_unicast_addr(self);
        }
-       /* Ready to transfer Ethernet frames */
+       /* Ready to transfer Ethernet frames (at last) */
        self->dev.tbusy = 0;
 }
 
 void irlan_connect_confirm(void *instance, void *sap, struct qos_info *qos, 
-                          __u32 max_sdu_size, struct sk_buff *skb) 
+                          __u32 max_sdu_size, __u8 max_header_size, 
+                          struct sk_buff *skb) 
 {
        struct irlan_cb *self;
 
@@ -416,6 +430,9 @@ void irlan_connect_confirm(void *instance, void *sap, struct qos_info *qos,
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRLAN_MAGIC, return;);
 
+       self->max_sdu_size = max_sdu_size;
+       self->max_header_size = max_header_size;
+
        /* TODO: we could set the MTU depending on the max_sdu_size */
 
        DEBUG(2, "IrLAN, We are now connected!\n");
@@ -444,7 +461,7 @@ void irlan_disconnect_indication(void *instance, void *sap, LM_REASON reason,
        struct irlan_cb *self;
        struct tsap_cb *tsap;
 
-       DEBUG(2, __FUNCTION__ "(), reason=%d\n", reason);
+       DEBUG(0, __FUNCTION__ "(), reason=%d\n", reason);
        
        self = (struct irlan_cb *) instance;
        tsap = (struct tsap_cb *) sap;
@@ -460,7 +477,7 @@ void irlan_disconnect_indication(void *instance, void *sap, LM_REASON reason,
 
        switch(reason) {
        case LM_USER_REQUEST: /* User request */
-               //irlan_close(self);
+               irlan_close(self);
                break;
        case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
                irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
@@ -490,7 +507,7 @@ void irlan_open_data_tsap(struct irlan_cb *self)
        struct notify_t notify;
        struct tsap_cb *tsap;
 
-       DEBUG(4, __FUNCTION__ "()\n");
+       DEBUG(0, __FUNCTION__ "()\n");
 
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -500,7 +517,7 @@ void irlan_open_data_tsap(struct irlan_cb *self)
                return;
 
        irda_notify_init(&notify);
-
+       
        notify.data_indication       = irlan_eth_receive;
        notify.udata_indication      = irlan_eth_receive;
        notify.connect_indication    = irlan_connect_indication;
@@ -620,7 +637,7 @@ void irlan_get_provider_info(struct irlan_cb *self)
                return;
 
        /* Reserve space for TTP, LMP, and LAP header */
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->client.max_header_size);
        skb_put(skb, 2);
        
        frame = skb->data;
@@ -651,7 +668,7 @@ void irlan_open_data_channel(struct irlan_cb *self)
        if (!skb)
                return;
 
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->client.max_header_size);
        skb_put(skb, 2);
        
        frame = skb->data;
@@ -683,7 +700,7 @@ void irlan_close_data_channel(struct irlan_cb *self)
        if (!skb)
                return;
 
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->client.max_header_size);
        skb_put(skb, 2);
        
        frame = skb->data;
@@ -719,7 +736,7 @@ void irlan_open_unicast_addr(struct irlan_cb *self)
                return;
 
        /* Reserve space for TTP, LMP, and LAP header */
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->max_header_size);
        skb_put(skb, 2);
        
        frame = skb->data;
@@ -757,7 +774,7 @@ void irlan_set_broadcast_filter(struct irlan_cb *self, int status)
                return;
 
        /* Reserve space for TTP, LMP, and LAP header */
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->client.max_header_size);
        skb_put(skb, 2);
        
        frame = skb->data;
@@ -796,7 +813,7 @@ void irlan_set_multicast_filter(struct irlan_cb *self, int status)
                return;
        
        /* Reserve space for TTP, LMP, and LAP header */
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->client.max_header_size);
        skb_put(skb, 2);
        
        frame = skb->data;
@@ -836,7 +853,7 @@ void irlan_get_unicast_addr(struct irlan_cb *self)
                return;
 
        /* Reserve space for TTP, LMP, and LAP header */
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->client.max_header_size);
        skb_put(skb, 2);
        
        frame = skb->data;
@@ -871,7 +888,7 @@ void irlan_get_media_char(struct irlan_cb *self)
                return;
 
        /* Reserve space for TTP, LMP, and LAP header */
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->client.max_header_size);
        skb_put(skb, 2);
        
        frame = skb->data;
@@ -1033,7 +1050,7 @@ int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
        
        /* get parameter name */
        memcpy(name, buf+n, name_len);
-       name[ name_len] = '\0';
+       name[name_len] = '\0';
        n+=name_len;
        
        /*  
@@ -1051,7 +1068,7 @@ int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
 
        /* get parameter value */
        memcpy(value, buf+n, val_len);
-       value[ val_len] = '\0';
+       value[val_len] = '\0';
        n+=val_len;
        
        DEBUG(4, "Parameter: %s ", name); 
@@ -1085,31 +1102,35 @@ static int irlan_proc_read(char *buf, char **start, off_t offset, int len,
        while (self != NULL) {
                ASSERT(self->magic == IRLAN_MAGIC, return len;);
                
-               len += sprintf(buf+len, "ifname: %s,\n",
-                              self->ifname);
-               len += sprintf(buf+len, "client state: %s, ",
-                              irlan_state[ self->client.state]);
-               len += sprintf(buf+len, "provider state: %s,\n",
-                              irlan_state[ self->provider.state]);
-               len += sprintf(buf+len, "saddr: %#08x, ",
-                              self->saddr);
-               len += sprintf(buf+len, "daddr: %#08x\n",
-                              self->daddr);
-               len += sprintf(buf+len, "version: %d.%d,\n",
-                              self->version[1], self->version[0]);
-               len += sprintf(buf+len, "access type: %s\n", 
-                              irlan_access[ self->access_type]);
-               len += sprintf(buf+len, "media: %s\n", 
-                              irlan_media[ self->media]);
-
-               len += sprintf(buf+len, "local filter:\n");
-               len += sprintf(buf+len, "remote filter: ");
-               len += irlan_print_filter(self->client.filter_type, buf+len);
-
-               len += sprintf(buf+len, "tx busy: %s\n", self->dev.tbusy ? 
-                              "TRUE" : "FALSE");
-
-               len += sprintf(buf+len, "\n");
+               /* Don't display the master server */
+               if (self->master == 0) {
+                       len += sprintf(buf+len, "ifname: %s,\n",
+                                      self->ifname);
+                       len += sprintf(buf+len, "client state: %s, ",
+                                      irlan_state[ self->client.state]);
+                       len += sprintf(buf+len, "provider state: %s,\n",
+                                      irlan_state[ self->provider.state]);
+                       len += sprintf(buf+len, "saddr: %#08x, ",
+                                      self->saddr);
+                       len += sprintf(buf+len, "daddr: %#08x\n",
+                                      self->daddr);
+                       len += sprintf(buf+len, "version: %d.%d,\n",
+                                      self->version[1], self->version[0]);
+                       len += sprintf(buf+len, "access type: %s\n", 
+                                      irlan_access[self->client.access_type]);
+                       len += sprintf(buf+len, "media: %s\n", 
+                                      irlan_media[self->media]);
+                       
+                       len += sprintf(buf+len, "local filter:\n");
+                       len += sprintf(buf+len, "remote filter: ");
+                       len += irlan_print_filter(self->client.filter_type, 
+                                                 buf+len);
+                       
+                       len += sprintf(buf+len, "tx busy: %s\n", 
+                                      self->dev.tbusy ? "TRUE" : "FALSE");
+                       
+                       len += sprintf(buf+len, "\n");
+               }
 
                self = (struct irlan_cb *) hashbin_get_next(irlan);
        } 
index c1965a11714fdd69cecec8f6531634829a330f41..26b16a196dcd277e8390888c090d8528e630612b 100644 (file)
@@ -6,13 +6,13 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Oct 15 08:37:58 1998
- * Modified at:   Thu Apr 22 14:26:39 1999
+ * Modified at:   Mon May 10 20:23:49 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
  *                slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -29,6 +29,7 @@
 #include <linux/etherdevice.h>
 #include <linux/inetdevice.h>
 #include <linux/if_arp.h>
+#include <linux/random.h>
 #include <net/arp.h>
 
 #include <net/irda/irda.h>
@@ -67,19 +68,19 @@ int irlan_eth_init(struct device *dev)
        
        dev->tx_queue_len = TTP_MAX_QUEUE;
 
-#if 0
-       /*  
-        *  OK, since we are emulating an IrLAN sever we will have to give
-        *  ourself an ethernet address!
-        *  FIXME: this must be more dynamically
-        */
-       dev->dev_addr[0] = 0x40;
-       dev->dev_addr[1] = 0x00;
-       dev->dev_addr[2] = 0x00;
-       dev->dev_addr[3] = 0x00;
-       dev->dev_addr[4] = 0x23;
-       dev->dev_addr[5] = 0x45;
-#endif
+       if (self->provider.access_type == ACCESS_DIRECT) {
+               /*  
+                * Since we are emulating an IrLAN sever we will have to
+                * give ourself an ethernet address!  
+                */
+               dev->dev_addr[0] = 0x40;
+               dev->dev_addr[1] = 0x00;
+               dev->dev_addr[2] = 0x00;
+               dev->dev_addr[3] = 0x00;
+               get_random_bytes(dev->dev_addr+4, 1);
+               get_random_bytes(dev->dev_addr+5, 1);
+       }
+
        /* 
         * Network device has now been registered, so tell irmanager about
         * it, so it can be configured with network parameters
@@ -180,8 +181,6 @@ int irlan_eth_xmit(struct sk_buff *skb, struct device *dev)
 {
        struct irlan_cb *self;
 
-       DEBUG(4, __FUNCTION__ "()\n");
-       
        self = (struct irlan_cb *) dev->priv;
 
        ASSERT(self != NULL, return 0;);
@@ -202,19 +201,19 @@ int irlan_eth_xmit(struct sk_buff *skb, struct device *dev)
                dev->trans_start = jiffies;
        }
        
-       DEBUG(4, "Room left at head: %d\n", skb_headroom(skb));
-       DEBUG(4, "Room left at tail: %d\n", skb_tailroom(skb));
-       DEBUG(4, "Required room: %d\n", IRLAN_MAX_HEADER);
-       
-       /* skb headroom large enough to contain IR-headers? */
-       if ((skb_headroom(skb) < IRLAN_MAX_HEADER) || (skb_shared(skb))) {
+       /* skb headroom large enough to contain all IrDA-headers? */
+       if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) {
                struct sk_buff *new_skb = 
-                       skb_realloc_headroom(skb, IRLAN_MAX_HEADER);
-               ASSERT(new_skb != NULL, return 0;);
-               ASSERT(skb_headroom(new_skb) >= IRLAN_MAX_HEADER, return 0;);
+                       skb_realloc_headroom(skb, self->max_header_size);
 
-               /*  Free original skb, and use the new one */
+               /*  We have to free the original skb anyway */
                dev_kfree_skb(skb);
+
+               /* Did the realloc succeed? */
+               if (new_skb == NULL)
+                       return 0;
+
+               /* Use the new skb instead */
                skb = new_skb;
        } 
 
@@ -222,31 +221,26 @@ int irlan_eth_xmit(struct sk_buff *skb, struct device *dev)
        self->stats.tx_packets++;
        self->stats.tx_bytes += skb->len; 
 
-       /*
-        *  Now queue the packet in the transport layer
-        *  FIXME: clean up the code below! DB
-        */
-       if (self->use_udata) {
+       /* Now queue the packet in the transport layer */
+       if (self->use_udata)
                irttp_udata_request(self->tsap_data, skb);
-               dev->tbusy = 0;
-       
-               return 0;
-       }
-
-       if (irttp_data_request(self->tsap_data, skb) == -1) {
-               /*  
-                *  IrTTPs tx queue is full, so we just have to drop the
-                *  frame! You might think that we should just return -1
-                *  and don't deallocate the frame, but that is dangerous
-                *  since it's possible that we have replaced the original
-                *  skb with a new one with larger headroom, and that would
-                *  really confuse do_dev_queue_xmit() in dev.c! I have
-                *  tried :-) DB
-                */
-               dev_kfree_skb(skb);
-               ++self->stats.tx_dropped;
+       else {
+               if (irttp_data_request(self->tsap_data, skb) < 0) {
+                       /*   
+                        * IrTTPs tx queue is full, so we just have to
+                        * drop the frame! You might think that we should
+                        * just return -1 and don't deallocate the frame,
+                        * but that is dangerous since it's possible that
+                        * we have replaced the original skb with a new
+                        * one with larger headroom, and that would really
+                        * confuse do_dev_queue_xmit() in dev.c! I have
+                        * tried :-) DB 
+                        */
+                       dev_kfree_skb(skb);
+                       ++self->stats.tx_dropped;
                
-               return 0;
+                       return 0;
+               }
        }
        dev->tbusy = 0; /* Finished! */
        
@@ -314,26 +308,16 @@ void irlan_eth_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
        
        switch (flow) {
        case FLOW_STOP:
-               DEBUG(4, "IrLAN, stopping Ethernet layer\n");
-
                dev->tbusy = 1;
                break;
        case FLOW_START:
-               /* 
-                *  Tell upper layers that its time to transmit frames again
-                */
-               DEBUG(4, "IrLAN, starting Ethernet layer\n");
-
+       default:
+               /* Tell upper layers that its time to transmit frames again */
                dev->tbusy = 0;
 
-               /* 
-                *  Ready to receive more frames, so schedule the network
-                *  layer
-                */
+               /* Schedule network layer */
                mark_bh(NET_BH);                
                break;
-       default:
-               DEBUG(0, __FUNCTION__ "(), Unknown flow command!\n");
        }
 }
 
@@ -373,7 +357,7 @@ void irlan_etc_send_gratuitous_arp(struct device *dev)
        in_dev = dev->ip_ptr;
        arp_send(ARPOP_REQUEST, ETH_P_ARP, 
                 in_dev->ifa_list->ifa_address,
-                &dev, 
+                dev, 
                 in_dev->ifa_list->ifa_address,
                 NULL, dev->dev_addr, NULL);
 }
index d54e7cc122c06ff4e7e41d53d5c18d002d6bdf67..93d7c4efe10d6a6d024dd1298cb54585a92d1a08 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Oct 20 09:10:16 1998
- * Modified at:   Wed Feb  3 21:42:27 1999
+ * Modified at:   Sun May  9 21:17:44 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -38,22 +38,22 @@ char *irlan_state[] = {
        "IRLAN_SYNC",
 };
 
-void irlan_next_client_state( struct irlan_cb *self, IRLAN_STATE state) 
+void irlan_next_client_state(struct irlan_cb *self, IRLAN_STATE state) 
 {
        DEBUG(2, __FUNCTION__"(), %s\n", irlan_state[state]);
 
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == IRLAN_MAGIC, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IRLAN_MAGIC, return;);
 
        self->client.state = state;
 }
 
-void irlan_next_provider_state( struct irlan_cb *self, IRLAN_STATE state) 
+void irlan_next_provider_state(struct irlan_cb *self, IRLAN_STATE state) 
 {
        DEBUG(2, __FUNCTION__"(), %s\n", irlan_state[state]);
 
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == IRLAN_MAGIC, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IRLAN_MAGIC, return;);
 
        self->provider.state = state;
 }
index c4c1079dde7b327e48863ad72159faec4c9d9bb6..4f199e4ee74fc477dfe66c2bcdd9e6a862eaaf2b 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Fri Jan 29 11:16:38 1999
- * Modified at:   Thu Feb 25 15:10:54 1999
+ * Modified at:   Sat May  8 15:25:23 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -41,29 +41,29 @@ void handle_filter_request(struct irlan_cb *self, struct sk_buff *skb)
            (self->provider.filter_operation == DYNAMIC))
        {
                DEBUG(0, "Giving peer a dynamic Ethernet address\n");
-
                self->provider.mac_address[0] = 0x40;
                self->provider.mac_address[1] = 0x00;
                self->provider.mac_address[2] = 0x00;
                self->provider.mac_address[3] = 0x00;
                
                /* Use arbitration value to generate MAC address */
-               if (self->access_type == ACCESS_PEER) {
+               if (self->provider.access_type == ACCESS_PEER) {
                        self->provider.mac_address[4] = 
                                self->provider.send_arb_val & 0xff;
                        self->provider.mac_address[5] = 
                                (self->provider.send_arb_val >> 8) & 0xff;;
                } else {
                        /* Just generate something for now */
-                       self->provider.mac_address[4] = jiffies & 0xff;
-                       self->provider.mac_address[5] = (jiffies >> 8) & 0xff;
+                       get_random_bytes(self->provider.mac_address+4, 1);
+                       get_random_bytes(self->provider.mac_address+5, 1);
                }
 
                skb->data[0] = 0x00; /* Success */
                skb->data[1] = 0x03;
                irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
                irlan_insert_short_param(skb, "MAX_ENTRY", 0x0001);
-               irlan_insert_array_param(skb, "FILTER_ENTRY", self->provider.mac_address, 6);
+               irlan_insert_array_param(skb, "FILTER_ENTRY", 
+                                        self->provider.mac_address, 6);
                return;
        }
        
@@ -138,8 +138,7 @@ void handle_filter_request(struct irlan_cb *self, struct sk_buff *skb)
  *    Check parameters in request from peer device
  *
  */
-void irlan_check_command_param(struct irlan_cb *self, char *param, 
-                              char *value)
+void irlan_check_command_param(struct irlan_cb *self, char *param, char *value)
 {
        __u8 *bytes;
 
@@ -210,6 +209,12 @@ void irlan_check_command_param(struct irlan_cb *self, char *param,
        }
 }
 
+/*
+ * Function irlan_print_filter (filter_type, buf)
+ *
+ *    Print status of filter. Used by /proc file system
+ *
+ */
 int irlan_print_filter(int filter_type, char *buf)
 {
        int len = 0;
index 8e2c3c25ab89ceb8c094387f843e6ed6528a3088..9471418724948b0d99b8d5730bcdef684e35944f 100644 (file)
@@ -6,13 +6,14 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Apr 22 14:28:52 1999
+ * Modified at:   Sun May  9 12:22:56 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
  *                slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -31,6 +32,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
+#include <linux/random.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <net/irda/irlan_filter.h>
 #include <net/irda/irlan_client.h>
 
+static void irlan_provider_connect_indication(void *instance, void *sap, 
+                                             struct qos_info *qos, 
+                                             __u32 max_sdu_size,
+                                             __u8 max_header_size,
+                                             struct sk_buff *skb);
+
 /*
  * Function irlan_provider_control_data_indication (handle, skb)
  *
  *    This function gets the data that is received on the control channel
  *
  */
-int irlan_provider_data_indication(void *instance, void *sap, 
-                                  struct sk_buff *skb) 
+static int irlan_provider_data_indication(void *instance, void *sap, 
+                                         struct sk_buff *skb) 
 {
        struct irlan_cb *self;
        __u8 code;
@@ -111,14 +119,17 @@ int irlan_provider_data_indication(void *instance, void *sap,
  *    Got connection from peer IrLAN layer
  *
  */
-void irlan_provider_connect_indication(void *instance, void *sap, 
-                                      struct qos_info *qos,
-                                      __u32 max_sdu_size, struct sk_buff *skb)
+static void irlan_provider_connect_indication(void *instance, void *sap, 
+                                             struct qos_info *qos,
+                                             __u32 max_sdu_size, 
+                                             __u8 max_header_size,
+                                              struct sk_buff *skb)
 {
-       struct irlan_cb *self, *entry, *new;
+       struct irlan_cb *self, *new;
        struct tsap_cb *tsap;
+       __u32 saddr, daddr;
 
-       DEBUG(2, __FUNCTION__ "()\n");
+       DEBUG(0, __FUNCTION__ "()\n");
        
        self = (struct irlan_cb *) instance;
        tsap = (struct tsap_cb *) sap;
@@ -126,34 +137,69 @@ void irlan_provider_connect_indication(void *instance, void *sap,
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRLAN_MAGIC, return;);
        
+       self->provider.max_sdu_size = max_sdu_size;
+       self->provider.max_header_size = max_header_size;
+
        ASSERT(tsap == self->provider.tsap_ctrl,return;);
        ASSERT(self->provider.state == IRLAN_IDLE, return;);
 
-       /* Check if this provider is currently unused */
-       if (self->daddr == DEV_ADDR_ANY) {
-               /*
-                * Rehash instance, now we have a client (daddr) to serve.
-                */
-               entry = hashbin_remove(irlan, self->daddr, NULL);
-               ASSERT( entry == self, return;);
-               
-               self->daddr = irttp_get_daddr(tsap);
-               DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
-               hashbin_insert(irlan, (QUEUE*) self, self->daddr, NULL);
+       daddr = irttp_get_daddr(tsap);
+       saddr = irttp_get_saddr(tsap);
+
+       /* Check if we already dealing with this client or peer */
+       new = (struct irlan_cb *) hashbin_find(irlan, daddr, NULL);
+       if (new) {
+               ASSERT(new->magic == IRLAN_MAGIC, return;);
+               DEBUG(0, __FUNCTION__ "(), found instance!\n");
+
+               /* Update saddr, since client may have moved to a new link */
+               new->saddr = saddr;
+               DEBUG(2, __FUNCTION__ "(), saddr=%08x\n", new->saddr);
+
+               /* Make sure that any old provider control TSAP is removed */
+               if ((new != self) && new->provider.tsap_ctrl) {
+                       irttp_disconnect_request(new->provider.tsap_ctrl, 
+                                                NULL, P_NORMAL);
+                       irttp_close_tsap(new->provider.tsap_ctrl);
+                       new->provider.tsap_ctrl = NULL;
+               }
        } else {
-               /*
-                * If we already have the daddr set, this means that the
-                * client must already have started (peer mode). We must
-                * make sure that this connection attempt is from the same
-                * device as the client is dealing with!  
+               /* This must be the master instance, so start a new instance */
+               DEBUG(0, __FUNCTION__ "(), starting new provider!\n");
+
+               new = irlan_open(saddr, daddr, TRUE); 
+       }
+
+       /*  
+        * Check if the connection came in on the master server, or the
+        * slave server. If it came on the slave, then everything is
+        * really, OK (reconnect), if not we need to dup the connection and
+        * hand it over to the slave.  
+        */
+       if (new != self) {
+                               
+               /* Now attach up the new "socket" */
+               new->provider.tsap_ctrl = irttp_dup(self->provider.tsap_ctrl, 
+                                                   new);
+               if (!new->provider.tsap_ctrl) {
+                       DEBUG(0, __FUNCTION__ "(), dup failed!\n");
+                       return;
+               }
+               
+               /* new->stsap_sel = new->tsap->stsap_sel; */
+               new->dtsap_sel_ctrl = new->provider.tsap_ctrl->dtsap_sel;
+
+               /* Clean up the original one to keep it in listen state */
+               self->provider.tsap_ctrl->dtsap_sel = LSAP_ANY;
+               self->provider.tsap_ctrl->lsap->dlsap_sel = LSAP_ANY;
+               self->provider.tsap_ctrl->lsap->lsap_state = LSAP_DISCONNECTED;
+               
+               /* 
+                * Use the new instance from here instead of the master
+                * struct! 
                 */
-               ASSERT(self->daddr == irttp_get_daddr(tsap), return;);
+               self = new;
        }
-       
-       /* Update saddr, since client may have moved to a new link */
-       self->saddr = irttp_get_saddr(tsap);
-       DEBUG(2, __FUNCTION__ "(), saddr=%08x\n", self->saddr);
-       
        /* Check if network device has been registered */
        if (!self->netdev_registered)
                irlan_register_netdev(self);
@@ -165,9 +211,10 @@ void irlan_provider_connect_indication(void *instance, void *sap,
         * indication it needs to make progress. If the client is still in 
         * IDLE state, we must kick it to 
         */
-       if ((self->access_type == ACCESS_PEER) && 
-           (self->client.state == IRLAN_IDLE))
+       if ((self->provider.access_type == ACCESS_PEER) && 
+           (self->client.state == IRLAN_IDLE)) {
                irlan_client_wakeup(self, self->saddr, self->daddr);
+       }
 }
 
 /*
@@ -225,6 +272,9 @@ int irlan_parse_open_data_cmd(struct irlan_cb *self, struct sk_buff *skb)
        
        ret = irlan_provider_parse_command(self, CMD_OPEN_DATA_CHANNEL, skb);
 
+       /* Open data channel */
+       irlan_open_data_tsap(self);
+
        return ret;
 }
 
@@ -314,7 +364,7 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command,
                return;
 
        /* Reserve space for TTP, LMP, and LAP header */
-       skb_reserve(skb, TTP_HEADER+LMP_HEADER+LAP_HEADER);
+       skb_reserve(skb, self->provider.max_header_size);
        skb_put(skb, 2);
        
        switch (command) {
@@ -334,6 +384,7 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command,
                }
                irlan_insert_short_param(skb, "IRLAN_VER", 0x0101);
                break;
+
        case CMD_GET_MEDIA_CHAR:
                skb->data[0] = 0x00; /* Success */
                skb->data[1] = 0x05; /* 5 parameters */
@@ -341,7 +392,7 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command,
                irlan_insert_string_param(skb, "FILTER_TYPE", "BROADCAST");
                irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST");
 
-               switch(self->access_type) {
+               switch (self->provider.access_type) {
                case ACCESS_DIRECT:
                        irlan_insert_string_param(skb, "ACCESS_TYPE", "DIRECT");
                        break;
index 6bdf503f1075a2e3d8060bdae14a4d619f7da597..29e660fa72dc3e8f58d0f058e8beba2c07a85ec0 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Apr 22 10:46:28 1999
+ * Modified at:   Fri May  7 10:53:58 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -108,7 +108,7 @@ static int irlan_provider_state_info(struct irlan_cb *self, IRLAN_EVENT event,
        switch(event) {
        case IRLAN_GET_INFO_CMD:
                /* Be sure to use 802.3 in case of peer mode */
-               if (self->access_type == ACCESS_PEER) {
+               if (self->provider.access_type == ACCESS_PEER) {
                        self->media = MEDIA_802_3;
                        
                        /* Check if client has started yet */
@@ -129,7 +129,7 @@ static int irlan_provider_state_info(struct irlan_cb *self, IRLAN_EVENT event,
                break;          
        case IRLAN_OPEN_DATA_CMD:
                ret = irlan_parse_open_data_cmd(self, skb);
-               if (self->access_type == ACCESS_PEER) {
+               if (self->provider.access_type == ACCESS_PEER) {
                        /* FIXME: make use of random functions! */
                        self->provider.send_arb_val = (jiffies & 0xffff);
                }
@@ -205,8 +205,6 @@ static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event,
 static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event, 
                                     struct sk_buff *skb) 
 {
-       struct irmanager_event mgr_event;
-
        DEBUG(4, __FUNCTION__ "()\n");
 
        ASSERT(self != NULL, return -1;);
@@ -220,10 +218,6 @@ static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event,
                break;
        case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
        case IRLAN_LAP_DISCONNECT:
-               mgr_event.event = EVENT_IRLAN_STOP;
-               sprintf(mgr_event.devname, "%s", self->ifname);
-               irmanager_notify(&mgr_event);
-
                irlan_next_provider_state(self, IRLAN_IDLE);
                break;
        default:
index 9959b64bc14e7d4a445752652d130f9ea9839df0..57a6b420bebc4f7dfa6a241c6978cb95869cef65 100644 (file)
@@ -6,11 +6,11 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Fri Oct  9 09:18:07 1998
- * Modified at:   Mon Feb  8 01:23:52 1999
+ * Modified at:   Sun May  9 11:37:06 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       ppp.c, isdn_ppp.c
  * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -255,11 +255,11 @@ struct sk_buff *irlap_compress_frame( struct irlap_cb *self,
        }
 
        /* FIXME: Find out what is the max overhead (not 10) */
-       new_skb = dev_alloc_skb( skb->len+LAP_HEADER+10);
+       new_skb = dev_alloc_skb( skb->len+LAP_MAX_HEADER+10);
        if(!new_skb)
                return skb;
 
-       skb_reserve( new_skb, LAP_HEADER);
+       skb_reserve( new_skb, LAP_MAX_HEADER);
        skb_put( new_skb, skb->len+10);
        
        count = (self->compressor.cp->compress)( self->compressor.state, 
index a2fbadf65045d951b1c915e3d7d5bd70f8737b68..936401339cfd4c70d64ac429e3f278037136edd3 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Aug 16 00:59:29 1997
- * Modified at:   Fri Apr 23 11:55:12 1999
+ * Modified at:   Sun May  9 22:44:32 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>,
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
  *                        Thomas Davis <ratbert@radiks.net>
  *     All Rights Reserved.
  *     
@@ -274,22 +274,22 @@ void irlap_do_event( struct irlap_cb *self, IRLAP_EVENT event,
  *    Switches state and provides debug information
  *
  */
-void irlap_next_state( struct irlap_cb *self, IRLAP_STATE state) 
+void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state) 
 {      
-       if ( !self || self->magic != LAP_MAGIC)
+       if (!self || self->magic != LAP_MAGIC)
                return;
        
-       DEBUG( 4, "next LAP state = %s\n", irlap_state[ state]);
+       DEBUG(4, "next LAP state = %s\n", irlap_state[ state]);
 
        self->state = state;
 
        /*
         *  If we are swithing away from a XMIT state then we are allowed to 
         *  transmit a maximum number of bytes again when we enter the XMIT 
-        *  state again. Since its possible to "switch" from XMIT to XMIT and
+        *  state again. Since its possible to "switch" from XMIT to XMIT,
         *  we cannot do this when swithing into the XMIT state :-)
         */
-       if (( state != LAP_XMIT_P) && ( state != LAP_XMIT_S))
+       if ((state != LAP_XMIT_P) && (state != LAP_XMIT_S))
                self->bytes_left = self->window_bytes;
 }
 
@@ -310,7 +310,7 @@ static int irlap_state_ndm( struct irlap_cb *self, IRLAP_EVENT event,
        ASSERT( self != NULL, return -1;);
        ASSERT( self->magic == LAP_MAGIC, return -1;);
 
-       switch( event) {
+       switch(event) {
        case CONNECT_REQUEST:
                ASSERT( self->irdev != NULL, return -1;);
 
@@ -393,7 +393,6 @@ static int irlap_state_ndm( struct irlap_cb *self, IRLAP_EVENT event,
                        irlap_start_query_timer( self, QUERY_TIMEOUT);
                        irlap_next_state( self, LAP_REPLY);
                }
-
                dev_kfree_skb(skb);
                break;
 
@@ -530,7 +529,7 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event,
                        irlap_send_discovery_xid_frame(self, info->S,
                                                       self->slot, FALSE,
                                                       discovery_rsp);
-
+                       
                        self->frame_sent = TRUE;
                        irlap_next_state(self, LAP_REPLY);
                }
@@ -568,27 +567,28 @@ static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event,
 
        switch (event) {
        case CONNECT_RESPONSE:
-               skb_pull( skb, 11);
+               /* skb_pull(skb, 11); */
+               skb_pull(skb, sizeof(struct snrm_frame));
 
-               ASSERT( self->irdev != NULL, return -1;);
-               irda_qos_negotiate( &self->qos_rx, &self->qos_tx, skb);
+               ASSERT(self->irdev != NULL, return -1;);
+               irda_qos_negotiate(&self->qos_rx, &self->qos_tx, skb);
 
                irlap_initiate_connection_state( self);
 
                /*
                 * We are allowed to send two frames!
                 */
-               irlap_send_ua_response_frame( self, &self->qos_rx);
-               irlap_send_ua_response_frame( self, &self->qos_rx);
+               irlap_send_ua_response_frame(self, &self->qos_rx);
+               irlap_send_ua_response_frame(self, &self->qos_rx);
                
-               irlap_apply_connection_parameters( self, &self->qos_tx);
+               irlap_apply_connection_parameters(self, &self->qos_tx);
 
                /*
                 *  The WD-timer could be set to the duration of the P-timer 
-                *  for this case, but it is recommomended to use twice the 
+                *  for this case, but it is recommended to use twice the 
                 *  value (note 3 IrLAP p. 60). 
                 */
-               irlap_start_wd_timer( self, self->wd_timeout);
+               irlap_start_wd_timer(self, self->wd_timeout);
                irlap_next_state( self, LAP_NRM_S);
                break;
 
@@ -669,28 +669,30 @@ static int irlap_state_setup( struct irlap_cb *self, IRLAP_EVENT event,
                 *  The device with the largest device address wins the battle
                 *  (both have sent a SNRM command!)
                 */
-               if ( info->daddr > self->saddr) {
-                       del_timer( &self->final_timer);
-                       irlap_initiate_connection_state( self);
+               if (info->daddr > self->saddr) {
+                       del_timer(&self->final_timer);
+                       irlap_initiate_connection_state(self);
 
-                       ASSERT( self->irdev != NULL, return -1;);
-                       irda_qos_negotiate( &self->qos_rx, &self->qos_tx, skb);
+                       ASSERT(self->irdev != NULL, return -1;);
+                       /* skb_pull(skb, 11); */
+                       skb_pull(skb, sizeof(struct snrm_frame));
+                       irda_qos_negotiate(&self->qos_rx, &self->qos_tx, skb);
                        
                        irlap_send_ua_response_frame(self, &self->qos_rx);
-                       irlap_apply_connection_parameters( self, &self->qos_tx);
-                       irlap_connect_confirm( self, skb);
+                       irlap_apply_connection_parameters(self, &self->qos_tx);
+                       irlap_connect_confirm(self, skb);
                        
                        /* 
                         *  The WD-timer could be set to the duration of the
-                        *  P-timer for this case, but it is recommomended
+                        *  P-timer for this case, but it is recommended
                         *  to use twice the value (note 3 IrLAP p. 60).  
                         */
-                       irlap_start_wd_timer( self, self->wd_timeout);
+                       irlap_start_wd_timer(self, self->wd_timeout);
                        
-                       irlap_next_state( self, LAP_NRM_S);
+                       irlap_next_state(self, LAP_NRM_S);
                } else {
                        /* We just ignore the other device! */
-                       irlap_next_state( self, LAP_SETUP);
+                       irlap_next_state(self, LAP_SETUP);
                }
                break;
        case RECV_UA_RSP:
@@ -702,9 +704,10 @@ static int irlap_state_setup( struct irlap_cb *self, IRLAP_EVENT event,
 
                /* Negotiate connection parameters */
                ASSERT( skb->len > 10, return -1;);
-               skb_pull( skb, 10);
+               /* skb_pull(skb, 10); */
+               skb_pull(skb, sizeof(struct ua_frame));
 
-               ASSERT( self->irdev != NULL, return -1;);
+               ASSERT(self->irdev != NULL, return -1;);
                irda_qos_negotiate( &self->qos_rx, &self->qos_tx, skb);
 
                irlap_apply_connection_parameters( self, &self->qos_tx); 
@@ -1570,7 +1573,7 @@ static int irlap_state_nrm_s( struct irlap_cb *self, IRLAP_EVENT event,
                        /* 
                         *  poll bit cleared?
                         */
-                       if ( !info->pf) {
+                       if (!info->pf) {
                                self->vr = (self->vr + 1) % 8;
                                
                                /* Update Nr received */
@@ -1600,27 +1603,32 @@ static int irlap_state_nrm_s( struct irlap_cb *self, IRLAP_EVENT event,
                                 *  also before changing to XMIT_S
                                 *  state. (note 1, IrLAP p. 82) 
                                 */
-                               irlap_wait_min_turn_around( self, &self->qos_tx);
-                               /*
-                                *  Any pending data requests?
+                               irlap_wait_min_turn_around(self, &self->qos_tx);
+
+                               /*  
+                                * Give higher layers a chance to
+                                * immediately reply with some data before
+                                * we decide if we should send a RR frame
+                                * or not
                                 */
-                               if (( skb_queue_len( &self->tx_list) > 0) && 
-                                   ( self->window > 0)) 
+                               irlap_data_indication(self, skb);
+
+                               /* Any pending data requests?  */
+                               if ((skb_queue_len(&self->tx_list) > 0) && 
+                                   (self->window > 0)) 
                                {
                                        self->ack_required = TRUE;
                                        
-                                       del_timer( &self->wd_timer);
+                                       del_timer(&self->wd_timer);
                                        
-                                       irlap_next_state( self, LAP_XMIT_S);
+                                       irlap_next_state(self, LAP_XMIT_S);
                                } else {
-                                       irlap_send_rr_frame( self, RSP_FRAME);
-                                       irlap_start_wd_timer( self, self->wd_timeout);
+                                       irlap_send_rr_frame(self, RSP_FRAME);
+                                       irlap_start_wd_timer(self, self->wd_timeout);
 
                                        /* Keep the state */
-                                       irlap_next_state( self, LAP_NRM_S);
+                                       irlap_next_state(self, LAP_NRM_S);
                                }
-                               irlap_data_indication( self, skb);
-
                                break;
                        }
                }
index cda78e7f1d536ffb9462de13a53ffbcad4c1fe66..8ffd26a6e051807f10ad8d906ceda709cf0edafe 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Aug 19 10:27:26 1997
- * Modified at:   Fri Apr 23 09:30:42 1999
+ * Modified at:   Sun May  9 22:55:11 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Resrved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Resrved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -1056,8 +1056,8 @@ static inline void irlap_recv_i_frame(struct irlap_cb *self,
  *    Receive and parse an Unnumbered Information (UI) frame
  *
  */
-static void irlap_recv_ui_frame( struct irlap_cb *self, struct sk_buff *skb, 
-                                struct irlap_info *info)
+static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb, 
+                               struct irlap_info *info)
 {
        __u8 *frame;
 
@@ -1254,7 +1254,7 @@ int irlap_driver_rcv(struct sk_buff *skb, struct device *dev,
                 *  Received S(upervisory) frame, check which frame type it is
                 *  only the first nibble is of interest
                 */
-               switch(control & 0x0f) {
+               switch (control & 0x0f) {
                case RR:
                        irlap_recv_rr_frame( self, skb, &info, command);
                        self->stats.rx_packets++;
@@ -1279,7 +1279,7 @@ int irlap_driver_rcv(struct sk_buff *skb, struct device *dev,
        /* 
         *  This must be a C(ontrol) frame 
         */
-       switch(control) {
+       switch (control) {
        case XID_RSP:
                irlap_recv_discovery_xid_rsp(self, skb, &info);
                break;
index d76661b6cf1ed47474f1364689ff40e2b094e187..f4d4608cb9dc9e6469ec8e9d74ca9c51d810bfcd 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Stable.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 17 20:54:32 1997
- * Modified at:   Fri Apr 23 09:13:24 1999
+ * Modified at:   Sun May  9 22:45:06 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, 
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -197,7 +197,7 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, struct notify_t *notify)
 }
 
 /*
- * Function irlmp_close_lsap (self)
+ * Function __irlmp_close_lsap (self)
  *
  *    Remove an instance of LSAP
  */
@@ -369,11 +369,11 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
                if (!skb)
                        return -ENOMEM;
 
-               skb_reserve(skb, LMP_CONTROL_HEADER+LAP_HEADER);
+               skb_reserve(skb, LMP_MAX_HEADER);
        } else
                skb = userdata;
        
-       /* Make room for MUX control header ( 3 bytes) */
+       /* Make room for MUX control header (3 bytes) */
        ASSERT(skb_headroom(skb) >= LMP_CONTROL_HEADER, return -1;);
        skb_push(skb, LMP_CONTROL_HEADER);
 
@@ -443,25 +443,36 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
 void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb) 
 {
        int max_seg_size;
-
-       DEBUG(3, __FUNCTION__ "()\n");
+       int lap_header_size;
+       int max_header_size;
        
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
        ASSERT(skb != NULL, return;);
        ASSERT(self->lap != NULL, return;);
 
+       DEBUG(0, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
+             self->slsap_sel, self->dlsap_sel);
+
        self->qos = *self->lap->qos;
 
-       max_seg_size = self->lap->qos->data_size.value;
-       DEBUG(4, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size);
+       lap_header_size = irlap_get_header_size(self->lap->irlap);
+
+       max_seg_size = self->lap->qos->data_size.value-LMP_HEADER-
+               lap_header_size;
+       DEBUG(2, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size);
        
+       max_header_size = LMP_HEADER + lap_header_size;
+
+       DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n", max_header_size);
+
        /* Hide LMP_CONTROL_HEADER header from layer above */
        skb_pull(skb, LMP_CONTROL_HEADER);
 
        if (self->notify.connect_indication)
                self->notify.connect_indication(self->notify.instance, self, 
-                                               &self->qos, max_seg_size, skb);
+                                               &self->qos, max_seg_size, 
+                                               max_header_size, skb);
 }
 
 /*
@@ -470,24 +481,22 @@ void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb)
  *    Service user is accepting connection
  *
  */
-void irlmp_connect_response( struct lsap_cb *self, struct sk_buff *userdata) 
+void irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata) 
 {
-       DEBUG(3, __FUNCTION__ "()\n");
-       
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
-       ASSERT( userdata != NULL, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
+       ASSERT(userdata != NULL, return;);
 
        self->connected = TRUE;
 
-       DEBUG( 4, "irlmp_connect_response: slsap_sel=%02x, dlsap_sel=%02x\n", 
-              self->slsap_sel, self->dlsap_sel);
+       DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
+             self->slsap_sel, self->dlsap_sel);
 
        /* Make room for MUX control header ( 3 bytes) */
-       ASSERT( skb_headroom( userdata) >= LMP_CONTROL_HEADER, return;);
-       skb_push( userdata, LMP_CONTROL_HEADER);
+       ASSERT(skb_headroom(userdata) >= LMP_CONTROL_HEADER, return;);
+       skb_push(userdata, LMP_CONTROL_HEADER);
        
-       irlmp_do_lsap_event( self, LM_CONNECT_RESPONSE, userdata);
+       irlmp_do_lsap_event(self, LM_CONNECT_RESPONSE, userdata);
 }
 
 /*
@@ -498,25 +507,35 @@ void irlmp_connect_response( struct lsap_cb *self, struct sk_buff *userdata)
 void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb) 
 {
        int max_seg_size;
+       int max_header_size;
+       int lap_header_size;
 
        DEBUG(3, __FUNCTION__ "()\n");
        
-       ASSERT( skb != NULL, return;);
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
+       ASSERT(skb != NULL, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
        
-       ASSERT( self->lap != NULL, return;);
+       ASSERT(self->lap != NULL, return;);
        self->qos = *self->lap->qos;
 
-       max_seg_size = self->qos.data_size.value;
-       DEBUG( 4, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size);
+       lap_header_size = irlap_get_header_size(self->lap->irlap);
+
+       max_seg_size = self->lap->qos->data_size.value-LMP_HEADER-
+               lap_header_size;
+       DEBUG(2, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size);
        
+       max_header_size = LMP_HEADER + lap_header_size;
+
+       DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n", max_header_size);
+
        /* Hide LMP_CONTROL_HEADER header from layer above */
-       skb_pull( skb, LMP_CONTROL_HEADER);
+       skb_pull(skb, LMP_CONTROL_HEADER);
 
-       if ( self->notify.connect_confirm) {
-               self->notify.connect_confirm( self->notify.instance, self,
-                                             &self->qos, max_seg_size, skb);
+       if (self->notify.connect_confirm) {
+               self->notify.connect_confirm(self->notify.instance, self,
+                                            &self->qos, max_seg_size, 
+                                            max_header_size, skb);
        }
 }
 
@@ -620,8 +639,8 @@ void irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata)
  *
  *    LSAP is being closed!
  */
-void irlmp_disconnect_indication( struct lsap_cb *self, LM_REASON reason, 
-                                 struct sk_buff *userdata) 
+void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, 
+                                struct sk_buff *userdata) 
 {
        struct lsap_cb *lsap;
 
@@ -637,6 +656,10 @@ void irlmp_disconnect_indication( struct lsap_cb *self, LM_REASON reason,
        self->connected = FALSE;
        self->dlsap_sel = LSAP_ANY;
 
+#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
+       irlmp->cache.valid = FALSE;
+#endif
+
        /* 
         *  Remove association between this LSAP and the link it used 
         */
@@ -975,7 +998,7 @@ void irlmp_status_request(void)
        DEBUG( 1, "irlmp_status_request(), Not implemented\n");
 }
 
-void irlmp_status_indication( LINK_STATUS link, LOCK_STATUS lock) 
+void irlmp_status_indication(LINK_STATUS link, LOCK_STATUS lock) 
 {
        DEBUG( 4, "irlmp_status_indication(), Not implemented\n");
 }
@@ -1418,14 +1441,14 @@ __u32 irlmp_get_daddr(struct lsap_cb *self)
  *    Give some info to the /proc file system
  *
  */
-int irlmp_proc_read( char *buf, char **start, off_t offset, int len, 
-                    int unused)
+int irlmp_proc_read(char *buf, char **start, off_t offset, int len, 
+                   int unused)
 {
        struct lsap_cb *self;
        struct lap_cb *lap;
        unsigned long flags;
 
-       ASSERT( irlmp != NULL, return 0;);
+       ASSERT(irlmp != NULL, return 0;);
        
        save_flags( flags);
        cli();
@@ -1449,35 +1472,34 @@ int irlmp_proc_read( char *buf, char **start, off_t offset, int len,
        } 
 
        len += sprintf( buf+len, "\nRegistred Link Layers:\n");
-       lap = (struct lap_cb *) hashbin_get_first( irlmp->links);
-       while ( lap != NULL) {
-               ASSERT( lap->magic == LMP_LAP_MAGIC, return 0;);
 
-               len += sprintf( buf+len, "lap state: %s, ", 
-                               irlmp_state[ lap->lap_state]);
+       lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
+       while (lap != NULL) {
+               len += sprintf(buf+len, "lap state: %s, ", 
+                              irlmp_state[lap->lap_state]);
 
-               len += sprintf( buf+len, "saddr: %#08x, daddr: %#08x, ",
-                               lap->saddr, lap->daddr); 
-               len += sprintf( buf+len, "\n");
+               len += sprintf(buf+len, "saddr: %#08x, daddr: %#08x, ",
+                              lap->saddr, lap->daddr); 
+               len += sprintf(buf+len, "\n");
 
                len += sprintf( buf+len, "\nConnected LSAPs:\n");
                self = (struct lsap_cb *) hashbin_get_first( lap->lsaps);
-               while ( self != NULL) {
-                       ASSERT( self->magic == LMP_LSAP_MAGIC, return 0;);
-                       len += sprintf( buf+len, "lsap state: %s, ", 
-                                       irlsap_state[ self->lsap_state]);
-                       len += sprintf( buf+len, 
-                                       "slsap_sel: %#02x, dlsap_sel: %#02x, ",
-                                       self->slsap_sel, self->dlsap_sel);
-                       len += sprintf( buf+len, "(%s)", self->notify.name);
-                       len += sprintf( buf+len, "\n");
+               while (self != NULL) {
+                       ASSERT(self->magic == LMP_LSAP_MAGIC, return 0;);
+                       len += sprintf(buf+len, "lsap state: %s, ", 
+                                      irlsap_state[ self->lsap_state]);
+                       len += sprintf(buf+len, 
+                                      "slsap_sel: %#02x, dlsap_sel: %#02x, ",
+                                      self->slsap_sel, self->dlsap_sel);
+                       len += sprintf(buf+len, "(%s)", self->notify.name);
+                       len += sprintf(buf+len, "\n");
                        
-                       self = ( struct lsap_cb *) hashbin_get_next( 
+                       self = (struct lsap_cb *) hashbin_get_next( 
                                lap->lsaps);
                } 
+               len += sprintf(buf+len, "\n");
 
-               lap = ( struct lap_cb *) hashbin_get_next( 
-                       irlmp->links);
+               lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
        } 
 
        restore_flags( flags);
index bf1bab31ecf7a602c4c2faaf7aca624979247d42..ff396c4ff7bdcddd0adceab3ad84f4691793a1b3 100644 (file)
@@ -1,15 +1,15 @@
 /*********************************************************************
  *                
  * Filename:      irlmp_frame.c
- * Version:       0.8
+ * Version:       0.9
  * Description:   IrLMP frame implementation
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Aug 19 02:09:59 1997
- * Modified at:   Fri Apr 23 09:12:23 1999
+ * Modified at:   Sun May  9 21:00:05 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -59,16 +59,16 @@ inline void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
  *
  *    Send Link Control Frame to IrLAP
  */
-void irlmp_send_lcf_pdu( struct lap_cb *self, __u8 dlsap, __u8 slsap,
-                        __u8 opcode, struct sk_buff *skb) 
+void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
+                       __u8 opcode, struct sk_buff *skb) 
 {
        __u8 *frame;
        
-       DEBUG( 4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
        
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LMP_LAP_MAGIC, return;);
-       ASSERT( skb != NULL, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LMP_LAP_MAGIC, return;);
+       ASSERT(skb != NULL, return;);
        
        frame = skb->data;
        
@@ -82,8 +82,8 @@ void irlmp_send_lcf_pdu( struct lap_cb *self, __u8 dlsap, __u8 slsap,
        else
                frame[3] = 0x00; /* rsvd */
 
-       ASSERT( self->irlap != NULL, return;);
-       irlap_data_request( self->irlap, skb, TRUE);
+       ASSERT(self->irlap != NULL, return;);
+       irlap_data_request(self->irlap, skb, TRUE);
 }
 
 /*
@@ -112,7 +112,7 @@ void irlmp_link_data_indication(struct lap_cb *self, int reliable,
         */
        slsap_sel = fp[0] & LSAP_MASK; 
        dlsap_sel = fp[1];
-       
+
        /*
         *  Check if this is an incoming connection, since we must deal with
         *  it in a different way than other established connections.
@@ -224,11 +224,11 @@ void irlmp_link_disconnect_indication(struct lap_cb *lap,
  *    Incoming LAP connection!
  *
  */
-void irlmp_link_connect_indication( struct lap_cb *self, __u32 saddr, 
-                                   __u32 daddr, struct qos_info *qos,
-                                   struct sk_buff *skb) 
+void irlmp_link_connect_indication(struct lap_cb *self, __u32 saddr, 
+                                  __u32 daddr, struct qos_info *qos,
+                                  struct sk_buff *skb) 
 {
-       DEBUG( 4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
 
        /* Copy QoS settings for this session */
        self->qos = qos;
@@ -237,7 +237,7 @@ void irlmp_link_connect_indication( struct lap_cb *self, __u32 saddr,
        self->daddr = daddr;
        ASSERT(self->saddr == saddr, return;);
 
-       irlmp_do_lap_event( self, LM_LAP_CONNECT_INDICATION, skb);
+       irlmp_do_lap_event(self, LM_LAP_CONNECT_INDICATION, skb);
 }
 
 /*
@@ -246,19 +246,19 @@ void irlmp_link_connect_indication( struct lap_cb *self, __u32 saddr,
  *    LAP connection confirmed!
  *
  */
-void irlmp_link_connect_confirm( struct lap_cb *self, struct qos_info *qos, 
-                                struct sk_buff *userdata)
+void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos, 
+                               struct sk_buff *userdata)
 {
-       DEBUG( 4, "irlmp_link_connect_confirm()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
 
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LMP_LAP_MAGIC, return;);
-       ASSERT( qos != NULL, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LMP_LAP_MAGIC, return;);
+       ASSERT(qos != NULL, return;);
 
        /* Copy QoS settings for this session */
        self->qos = qos;
 
-       irlmp_do_lap_event( self, LM_LAP_CONNECT_CONFIRM, NULL);
+       irlmp_do_lap_event(self, LM_LAP_CONNECT_CONFIRM, NULL);
 }
 
 /*
@@ -276,7 +276,9 @@ void irlmp_link_discovery_indication(struct lap_cb *self,
        irlmp_add_discovery(irlmp->cachelog, discovery);
 
        /* Just handle it the same way as a discovery confirm */
+#if 0
        irlmp_do_lap_event(self, LM_LAP_DISCOVERY_CONFIRM, NULL);
+#endif
 }
 
 /*
@@ -365,7 +367,7 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
 #endif
                        return lsap;
                }
-               lsap = ( struct lsap_cb *) hashbin_get_next(queue);
+               lsap = (struct lsap_cb *) hashbin_get_next(queue);
        }
 
        /* Sorry not found! */
index a0fbe23d678986188405048e1e86c923caa74477..9e02465ccae90c50673d8afe241c1f0d9024c8a3 100644 (file)
@@ -51,10 +51,11 @@ static void irlpt_client_discovery_indication(discovery_t *);
 static void irlpt_client_connect_confirm(void *instance, void *sap, 
                                         struct qos_info *qos, 
                                         __u32 max_seg_size, 
+                                        __u8 max_header_size,
                                         struct sk_buff *skb);
-static void irlpt_client_disconnect_indication( void *instance, void *sap, 
-                                               LM_REASON reason,
-                                               struct sk_buff *userdata);
+static void irlpt_client_disconnect_indication(void *instance, void *sap, 
+                                              LM_REASON reason,
+                                              struct sk_buff *userdata);
 static void irlpt_client_expired(unsigned long data);
 
 #if 0
@@ -187,7 +188,7 @@ __initfunc(int irlpt_client_init(void))
 
 #ifdef CONFIG_PROC_FS
        create_proc_entry("irlpt_client", 0, proc_irda)->get_info
-                       = irlpt_client_proc_read;
+               = irlpt_client_proc_read;
 #endif /* CONFIG_PROC_FS */
 
        DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
@@ -215,7 +216,6 @@ static void irlpt_client_cleanup(void)
 #ifdef CONFIG_PROC_FS
        remove_proc_entry("irlpt_client", proc_irda);
 #endif
-
        DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
 }
 #endif /* MODULE */
@@ -403,9 +403,8 @@ static void irlpt_client_disconnect_indication( void *instance,
 
        irlpt_client_do_event( self, LMP_DISCONNECT, NULL, NULL);
 
-       if (skb) {
+       if (skb)
                dev_kfree_skb( skb);
-       }
 
        DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
 }
@@ -417,7 +416,8 @@ static void irlpt_client_disconnect_indication( void *instance,
  */
 static void irlpt_client_connect_confirm(void *instance, void *sap, 
                                         struct qos_info *qos, 
-                                        __u32 max_sdu_size,
+                                        __u32 max_seg_size,
+                                        __u8 max_header_size,
                                         struct sk_buff *skb)
 {
        struct irlpt_info info;
@@ -443,14 +443,14 @@ static void irlpt_client_connect_confirm(void *instance, void *sap,
        }
 #endif
 
-       self->irlap_data_size = (qos->data_size.value - IRLPT_MAX_HEADER);
+       self->max_data_size = max_seg_size;
+       self->max_header_size = max_header_size;
        self->connected = TRUE;
        
        irlpt_client_do_event( self, LMP_CONNECT, NULL, NULL);
 
-       if (skb) {
+       if (skb)
                dev_kfree_skb( skb);
-       }
 
        DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
 }
@@ -603,7 +603,7 @@ static void irlpt_client_expired(unsigned long data)
                        return;
                }
 
-               skb_reserve( skb, LMP_CONTROL_HEADER+LAP_HEADER);
+               skb_reserve(skb, LMP_MAX_HEADER);
                irlmp_disconnect_request(self->lsap, skb);
                DEBUG(irlpt_client_debug, __FUNCTION__
                      ": irlmp_close_slap(self->lsap)\n");
index 75598742aa88538a6de2d9f9d69363c1e2a55702..83a2e69915d5aaea3ecb356a6bb182aa69cf1b96 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Jan 12 11:06:00 1999
- * Modified at:   Tue Jan 26 12:02:31 1999
+ * Modified at:   Sun May  9 13:36:13 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>
+ *     Copyright (c) 1998-1999, Thomas Davis, <ratbert@radiks.net>
  *     Copyright (c) 1998, Dag Brattli, <dagb@cs.uit.no>
  *     All Rights Reserved.
  *      
@@ -43,10 +43,10 @@ static int irlpt_client_state_query ( struct irlpt_cb *self,
                                      IRLPT_EVENT event,
                                      struct sk_buff *skb, 
                                      struct irlpt_info *info);
-static int irlpt_client_state_ready  ( struct irlpt_cb *self, 
-                                      IRLPT_EVENT event, 
-                                      struct sk_buff *skb, 
-                                      struct irlpt_info *info);
+static int irlpt_client_state_ready ( struct irlpt_cb *self, 
+                                     IRLPT_EVENT event, 
+                                     struct sk_buff *skb, 
+                                     struct irlpt_info *info);
 static int irlpt_client_state_waiti ( struct irlpt_cb *self, 
                                      IRLPT_EVENT event,
                                      struct sk_buff *skb, 
index b4512736a6da0fe07782b9f7547c1f3cddade6c4..c6401416bb38f25f2e33694b5202392f3d61e844 100644 (file)
@@ -251,18 +251,18 @@ ssize_t irlpt_write(struct file *file, const char *buffer,
        }
 
        DEBUG( irlpt_common_debug, __FUNCTION__ 
-              ": count = %d, irlap_data_size = %d, IRLPT_MAX_HEADER = %d\n",
-               count, self->irlap_data_size, IRLPT_MAX_HEADER);
+              ": count = %d, max_data_size = %d, IRLPT_MAX_HEADER = %d\n",
+               count, self->max_data_size, IRLPT_MAX_HEADER);
 
-       if (count > (self->irlap_data_size - IRLPT_MAX_HEADER)) {
-               count = (self->irlap_data_size - IRLPT_MAX_HEADER);
+       if (count > self->max_data_size) {
+               count = self->max_data_size;
                DEBUG(irlpt_common_debug, __FUNCTION__ 
                      ": setting count to %d\n", count);
        }
 
        DEBUG( irlpt_common_debug, __FUNCTION__ ": count = %d\n", count);
 
-       skb = dev_alloc_skb(count + IRLPT_MAX_HEADER);
+       skb = dev_alloc_skb(count + self->max_header_size);
        if ( skb == NULL) {
                printk( KERN_INFO 
                        __FUNCTION__ ": couldn't allocate skbuff!\n");
@@ -417,7 +417,7 @@ int irlpt_close(struct inode *inode,
                        return 0;
                }
 
-               skb_reserve( skb, LMP_CONTROL_HEADER+LAP_HEADER);
+               skb_reserve( skb, LMP_MAX_HEADER);
                irlmp_disconnect_request(self->lsap, skb);
                DEBUG(irlpt_common_debug, __FUNCTION__
                      ": irlmp_close_slap(self->lsap)\n");
index a1362d0dc600b6a556cbd5988d5fe3e66640810b..12e5867a54344b0a54183eefdd7665685b19b089 100644 (file)
@@ -51,15 +51,21 @@ int irlpt_server_init(void);
 static void irlpt_server_disconnect_indication(void *instance, void *sap, 
                                                LM_REASON reason,
                                                struct sk_buff *skb);
+
+#if 0
 static void irlpt_server_connect_confirm(void *instance, void *sap, 
                                         struct qos_info *qos,  
                                         __u32 max_seg_size,
+                                        __u8 max_header_size,
                                         struct sk_buff *skb);
 static void irlpt_server_connect_indication(void *instance, 
                                            void *sap, 
                                            struct qos_info *qos, 
                                            __u32 max_seg_size,
+                                           __u8 max_header_size,
                                            struct sk_buff *skb);
+#endif
+
 static int irlpt_server_data_indication(void *instance, void *sap, 
                                        struct sk_buff *skb);
 static void register_irlpt_server(void);
@@ -161,7 +167,6 @@ static int irlpt_server_proc_read(char *buf, char **start, off_t offset,
 }
 
 extern struct proc_dir_entry *proc_irda;
-
 #endif /* CONFIG_PROC_FS */
 
 /*
@@ -171,9 +176,9 @@ extern struct proc_dir_entry *proc_irda;
  *
  */
 
-/*int irlpt_init( struct device *dev) {*/
 __initfunc(int irlpt_server_init(void))
 {
+       struct irmanager_event mgr_event;
        __u16 hints;
 
        DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
@@ -212,6 +217,10 @@ __initfunc(int irlpt_server_init(void))
                = irlpt_server_proc_read;
 #endif /* CONFIG_PROC_FS */
 
+       mgr_event.event = EVENT_IRLPT_START;
+        sprintf(mgr_event.devname, "%s", irlpt_server->ifname);
+        irmanager_notify(&mgr_event);
+
        DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
 
        return 0;
@@ -225,6 +234,7 @@ __initfunc(int irlpt_server_init(void))
  */
 static void irlpt_server_cleanup(void)
 {
+       struct irmanager_event mgr_event;
        struct sk_buff *skb;
 
        DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
@@ -245,6 +255,10 @@ static void irlpt_server_cleanup(void)
        remove_proc_entry("irlpt_server", proc_irda);
 #endif
 
+        mgr_event.event = EVENT_IRLPT_STOP;
+        sprintf( mgr_event.devname, "%s", irlpt_server->ifname);
+        irmanager_notify( &mgr_event);
        DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
 }
 
@@ -304,6 +318,7 @@ static void irlpt_server_connect_confirm(void *instance,
                                         void *sap, 
                                         struct qos_info *qos,
                                         __u32 max_seg_size,
+                                        __u8 max_header_size,
                                         struct sk_buff *skb)
 {
        struct irlpt_cb *self;
@@ -314,6 +329,9 @@ static void irlpt_server_connect_confirm(void *instance,
        ASSERT( self != NULL, return;);
        ASSERT( self->magic == IRLPT_MAGIC, return;);
 
+       self->max_data_size = max_seg_size;
+       self->max_header_size = max_header_size;
+
        self->connected = TRUE;
 
        irlpt_server_do_event( self, LMP_CONNECT, NULL, NULL);
@@ -329,6 +347,7 @@ static void irlpt_server_connect_indication(void *instance,
                                            void *sap, 
                                            struct qos_info *qos, 
                                            __u32 max_seg_size,
+                                           __u8 max_header_size,
                                            struct sk_buff *skb)
 {
        struct irlpt_cb *self;
@@ -343,14 +362,16 @@ static void irlpt_server_connect_indication(void *instance,
        ASSERT( self != NULL, return;);
        ASSERT( self->magic == IRLPT_MAGIC, return;);
 
+       self->max_data_size = max_seg_size;
+       self->max_header_size = max_header_size;
+
        self->connected = IRLPT_CONNECTED;
        self->eof = FALSE;
 
        irlpt_server_do_event( self, LMP_CONNECT, NULL, &info);
 
-       if (skb) {
+       if (skb)
                dev_kfree_skb( skb);
-       }
 
        DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
 }
index 88d61c2cd62bca7850d4e7be3a6e28f0078fc29f..445a645a052b71d850ec44ea0ac31f48764b3b0a 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Dec 15 13:55:39 1997
- * Modified at:   Mon Apr 12 11:31:01 1999
+ * Modified at:   Mon May 10 15:28:49 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -110,6 +110,7 @@ EXPORT_SYMBOL(irttp_disconnect_request);
 EXPORT_SYMBOL(irttp_flow_request);
 EXPORT_SYMBOL(irttp_connect_request);
 EXPORT_SYMBOL(irttp_udata_request);
+EXPORT_SYMBOL(irttp_dup);
 
 /* Main IrDA module */
 #ifdef CONFIG_IRDA_DEBUG
@@ -151,6 +152,7 @@ EXPORT_SYMBOL(irlmp_connect_response);
 EXPORT_SYMBOL(irlmp_disconnect_request);
 EXPORT_SYMBOL(irlmp_get_daddr);
 EXPORT_SYMBOL(irlmp_get_saddr);
+EXPORT_SYMBOL(irlmp_dup);
 EXPORT_SYMBOL(lmp_reasons);
 
 /* Queue */
@@ -174,10 +176,15 @@ EXPORT_SYMBOL(irda_device_close);
 EXPORT_SYMBOL(irda_device_setup);
 EXPORT_SYMBOL(irda_device_set_media_busy);
 EXPORT_SYMBOL(irda_device_txqueue_empty);
+
+EXPORT_SYMBOL(irda_device_init_dongle);
+EXPORT_SYMBOL(irda_device_register_dongle);
+EXPORT_SYMBOL(irda_device_unregister_dongle);
+
 EXPORT_SYMBOL(async_wrap_skb);
 EXPORT_SYMBOL(async_unwrap_char);
 EXPORT_SYMBOL(irda_start_timer);
-EXPORT_SYMBOL(irda_get_mtt);
+/* EXPORT_SYMBOL(irda_get_mtt); */
 EXPORT_SYMBOL(setup_dma);
 
 #ifdef CONFIG_IRTTY
@@ -505,19 +512,28 @@ void irda_mod_dec_use_count(void)
 #endif
 }
 
-#ifdef MODULE
-#ifdef CONFIG_PROC_FS
+/*
+ * Function irda_proc_modcount (inode, fill)
+ *
+ *    Use by the proc file system functions to prevent the irda module
+ *    being removed while the use is standing in the net/irda directory
+ */
 void irda_proc_modcount(struct inode *inode, int fill)
 {
+#ifdef MODULE
+#ifdef CONFIG_PROC_FS
        if (fill)
                MOD_INC_USE_COUNT;
        else
                MOD_DEC_USE_COUNT;
-}
 #endif /* CONFIG_PROC_FS */
+#endif /* MODULE */
+}
+
+#ifdef MODULE
 
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
-MODULE_DESCRIPTION("The Linux IrDA protocol subsystem"); 
+MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem"); 
 MODULE_PARM(irda_debug, "1l");
 
 /*
index f3b710b95324e2955a35d5435b457c6fb5e14ca5..a04951694167e52d978dd26cc92999d5f53e1165 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Thomas Davis, <ratbert@radiks.net>
  * Created at:    Sat Feb 21 21:33:24 1998
- * Modified at:   Tue Apr  6 19:07:06 1999
+ * Modified at:   Fri May  7 08:06:49 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>, 
+ *     Copyright (c) 1998-1999, Thomas Davis, <ratbert@radiks.net>, 
  *     All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
@@ -20,8 +20,6 @@
  *     I, Thomas Davis, provide no warranty for any of this software. 
  *     This material is provided "AS-IS" and at no charge. 
  *     
- *     Portions lifted from the linux/fs/procfs/ files.
- *
  ********************************************************************/
 
 #include <linux/miscdevice.h>
@@ -44,28 +42,27 @@ extern int irias_proc_read(char *buf, char **start, off_t offset, int len,
                           int unused);
 extern int discovery_proc_read(char *buf, char **start, off_t offset, int len, 
                               int unused);
+static int proc_discovery_read(char *buf, char **start, off_t offset, int len,
+                              int unused);
 
-enum irda_directory_inos {
-       PROC_IRDA_LAP = 1,
-       PROC_IRDA_LMP,
-       PROC_IRDA_TTP,
-       PROC_IRDA_LPT,
-       PROC_IRDA_COMM,
-       PROC_IRDA_IRDA_DEVICE,
-       PROC_IRDA_IRIAS
-};
+/* enum irda_directory_inos { */
+/*     PROC_IRDA_LAP = 1, */
+/*     PROC_IRDA_LMP, */
+/*     PROC_IRDA_TTP, */
+/*     PROC_IRDA_LPT, */
+/*     PROC_IRDA_COMM, */
+/*     PROC_IRDA_IRDA_DEVICE, */
+/*     PROC_IRDA_IRIAS */
+/* }; */
 
 struct irda_entry {
        char *name;
-       int (*fn)(char*,char**,off_t,int,int);
+       int (*fn)(char*, char**, off_t, int, int);
 };
 
 struct proc_dir_entry *proc_irda;
-
 static struct irda_entry dir[] = {
-#if 0 
-       {"lpt", irlpt_proc_read},
-#endif
        {"discovery",   discovery_proc_read},
        {"irda_device", irda_device_proc_read},
        {"irttp",       irttp_proc_read},
@@ -75,19 +72,22 @@ static struct irda_entry dir[] = {
 };
 
 #define IRDA_ENTRIES_NUM (sizeof(dir)/sizeof(dir[0]))
-
 /*
  * Function irda_proc_register (void)
  *
  *    Register irda entry in /proc file system
  *
  */
-void irda_proc_register(void) {
+void irda_proc_register(void) 
+{
        int i;
+
        proc_irda = create_proc_entry("net/irda", S_IFDIR, NULL);
 #ifdef MODULE
        proc_irda->fill_inode = &irda_proc_modcount;
 #endif /* MODULE */
+
        for (i=0;i<IRDA_ENTRIES_NUM;i++)
                create_proc_entry(dir[i].name,0,proc_irda)->get_info=dir[i].fn;
 }
@@ -98,9 +98,14 @@ void irda_proc_register(void) {
  *    Unregister irda entry in /proc file system
  *
  */
-void irda_proc_unregister(void) {
+void irda_proc_unregister(void) 
+{
        int i;
+
        for (i=0;i<IRDA_ENTRIES_NUM;i++)
                remove_proc_entry(dir[i].name, proc_irda);
+
        remove_proc_entry("net/irda", NULL);
 }
+
+
index 0b9a4f1893cff23505927f58ea842c17fe011604..e82c2edd3c768606209803e64faed85e37e82c11 100644 (file)
@@ -1,15 +1,15 @@
 /*********************************************************************
  *                
  * Filename:      irsysctl.c
- * Version:       
- * Description:   
+ * Version:       1.0
+ * Description:   Sysctl interface for IrDA
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun May 24 22:12:06 1998
- * Modified at:   Fri Apr 23 09:46:38 1999
+ * Modified at:   Thu May  6 21:32:46 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
index bf0624eee0f926cfa2dd0984b5a568225b82da50..23b2a256e94553d5a54b6e6444eb61ef8ccffca3 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:31 1997
- * Modified at:   Sat Apr 10 10:32:21 1999
+ * Modified at:   Mon May 10 17:12:53 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, 
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -48,8 +48,10 @@ static void irttp_disconnect_indication(void *instance, void *sap,
                                        struct sk_buff *);
 static void irttp_connect_indication(void *instance, void *sap, 
                                     struct qos_info *qos, __u32 max_sdu_size,
-                                    struct sk_buff *skb);
-
+                                    __u8 header_size, struct sk_buff *skb);
+static void irttp_connect_confirm(void *instance, void *sap, 
+                                 struct qos_info *qos, __u32 max_sdu_size, 
+                                 __u8 header_size, struct sk_buff *skb);
 static void irttp_run_tx_queue(struct tsap_cb *self);
 static void irttp_run_rx_queue(struct tsap_cb *self);
 
@@ -337,6 +339,7 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb)
        /* Queue frame, or queue frame segments */
        if ((self->tx_max_sdu_size == 0) || (skb->len < self->max_seg_size)) {
                /* Queue frame */
+               ASSERT(skb_headroom(skb) >= TTP_HEADER, return -1;);
                frame = skb_push(skb, TTP_HEADER);
                frame[0] = 0x00; /* Clear more bit */
                
@@ -360,8 +363,8 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb)
                self->tx_sdu_busy = TRUE;
                
                if (self->notify.flow_indication) {
-                       self->notify.flow_indication(
-                               self->notify.instance, self, FLOW_STOP);
+                       self->notify.flow_indication(self->notify.instance, 
+                                                    self, FLOW_STOP);
                }
        }
        
@@ -472,7 +475,7 @@ void irttp_give_credit(struct tsap_cb *self)
                return;
 
        /* Reserve space for LMP, and LAP header */
-       skb_reserve(tx_skb, LMP_HEADER+LAP_HEADER);
+       skb_reserve(tx_skb, self->max_header_size);
 
        /*
         *  Since we can transmit and receive frames concurrently, 
@@ -655,15 +658,14 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
                        return -ENOMEM;
                
                /* Reserve space for MUX_CONTROL and LAP header */
-               skb_reserve(skb, (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER));
+               skb_reserve(skb, TTP_MAX_HEADER);
        } else {
                skb = userdata;
                /*  
                 *  Check that the client has reserved enough space for 
                 *  headers
                 */
-               ASSERT(skb_headroom(userdata) >= 
-                      (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER), return -1;);
+               ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER, return -1;);
        }
 
        /* Initialize connection parameters */
@@ -691,12 +693,11 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
 
        /* SAR enabled? */
        if (max_sdu_size > 0) {
-               ASSERT(skb_headroom(skb) >= 
-                       (TTP_HEADER_WITH_SAR+LMP_CONTROL_HEADER+LAP_HEADER), 
-                       return -1;);
+               ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER), 
+                      return -1;);
 
                /* Insert SAR parameters */
-               frame = skb_push(skb, TTP_HEADER_WITH_SAR);
+               frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER);
                
                frame[0] = TTP_PARAMETERS | n; 
                frame[1] = 0x04; /* Length */
@@ -724,8 +725,10 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
  *    Sevice user confirms TSAP connection with peer. 
  *
  */
-void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos,
-                          __u32 max_seg_size, struct sk_buff *skb) 
+static void irttp_connect_confirm(void *instance, void *sap, 
+                                 struct qos_info *qos,
+                                 __u32 max_seg_size, __u8 max_header_size,
+                                 struct sk_buff *skb) 
 {
        struct tsap_cb *self;
        int parameters;
@@ -741,7 +744,8 @@ void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos,
        ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
        ASSERT(skb != NULL, return;);
 
-       self->max_seg_size = max_seg_size-LMP_HEADER-LAP_HEADER;
+       self->max_seg_size = max_seg_size;
+       self->max_header_size = max_header_size + TTP_HEADER;
 
        /*
         *  Check if we have got some QoS parameters back! This should be the
@@ -797,9 +801,9 @@ void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos,
        skb_pull(skb, TTP_HEADER);
 
        if (self->notify.connect_confirm) {
-               self->notify.connect_confirm(self->notify.instance, self, 
-                                            qos, self->tx_max_sdu_size, 
-                                            skb);
+               self->notify.connect_confirm(self->notify.instance, self, qos,
+                                            self->tx_max_sdu_size, 
+                                            self->max_header_size, skb);
        }
 }
 
@@ -809,8 +813,8 @@ void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos,
  *    Some other device is connecting to this TSAP
  *
  */
-void irttp_connect_indication(void *instance, void *sap, 
-                             struct qos_info *qos, __u32 max_seg_size, 
+void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos,
+                             __u32 max_seg_size,  __u8 max_header_size, 
                              struct sk_buff *skb) 
 {
        struct tsap_cb *self;
@@ -828,7 +832,9 @@ void irttp_connect_indication(void *instance, void *sap,
 
        lsap = (struct lsap_cb *) sap;
 
-       self->max_seg_size = max_seg_size-LMP_HEADER-LAP_HEADER;
+       self->max_seg_size = max_seg_size;
+
+       self->max_header_size = max_header_size+TTP_HEADER;
 
        DEBUG(4, __FUNCTION__ "(), TSAP sel=%02x\n", self->stsap_sel);
 
@@ -850,7 +856,7 @@ void irttp_connect_indication(void *instance, void *sap,
 
                switch (pl) {
                case 1:
-                       self->tx_max_sdu_size = *(frame+4);
+                       self->tx_max_sdu_size = frame[4];
                        break;
                case 2:
                        self->tx_max_sdu_size = 
@@ -878,7 +884,7 @@ void irttp_connect_indication(void *instance, void *sap,
        if (self->notify.connect_indication) {
                self->notify.connect_indication(self->notify.instance, self, 
                                                qos, self->rx_max_sdu_size, 
-                                               skb);
+                                               self->max_header_size, skb);
        }
 }
 
@@ -909,15 +915,14 @@ void irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
                        return;
 
                /* Reserve space for MUX_CONTROL and LAP header */
-               skb_reserve(skb, (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER));
+               skb_reserve(skb, TTP_MAX_HEADER);
        } else {
                skb = userdata;
                /*  
                 *  Check that the client has reserved enough space for 
                 *  headers
                 */
-               ASSERT(skb_headroom(skb) >= 
-                       (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER), return;);
+               ASSERT(skb_headroom(skb) >= TTP_MAX_HEADER, return;);
        }
        
        self->avail_credit = 0;
@@ -939,12 +944,11 @@ void irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
 
        /* SAR enabled? */
        if (max_sdu_size > 0) {
-               ASSERT(skb_headroom(skb) >= 
-                      (TTP_HEADER_WITH_SAR+LMP_CONTROL_HEADER+LAP_HEADER), 
+               ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER+TTP_SAR_HEADER), 
                       return;);
                
                /* Insert TTP header with SAR parameters */
-               frame = skb_push(skb, TTP_HEADER_WITH_SAR);
+               frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER);
                
                frame[0] = TTP_PARAMETERS | n;
                frame[1] = 0x04; /* Length */
@@ -1079,7 +1083,7 @@ void irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata,
                /* 
                 *  Reserve space for MUX and LAP header 
                 */
-               skb_reserve(skb, LMP_CONTROL_HEADER+LAP_HEADER);
+               skb_reserve(skb, TTP_MAX_HEADER);
                
                userdata = skb;
        }
@@ -1357,13 +1361,11 @@ static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb)
                }
                
                /* Make new segment */
-               frag = dev_alloc_skb(self->max_seg_size+
-                                     TTP_HEADER+LMP_HEADER+
-                                     LAP_HEADER);
+               frag = dev_alloc_skb(self->max_seg_size+self->max_header_size);
                if (!frag)
                        return;
 
-               skb_reserve(frag, LMP_HEADER+LAP_HEADER);
+               skb_reserve(frag, self->max_header_size);
 
                /*
                 *  Copy data from the original skb into this fragment. We
index 7b226dfa6481dad5710d39b39395ca62909d4968..82f7fc28a70d9a4ad9d4e2d07ae0f8adaa08619f 100644 (file)
@@ -6,10 +6,11 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Sep  9 00:00:26 1997
- * Modified at:   Mon Apr 12 11:49:24 1999
+ * Modified at:   Mon May  3 21:15:08 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -52,10 +53,10 @@ int compression[] = { CI_BZIP2, CI_DEFLATE, CI_DEFLATE_DRAFT };
  *    Compute the intersection of the old QoS capabilites with new ones
  *
  */
-void irda_qos_compute_intersection( struct qos_info *qos, struct qos_info *new)
+void irda_qos_compute_intersection(struct qos_info *qos, struct qos_info *new)
 {
-       ASSERT( qos != NULL, return;);
-       ASSERT( new != NULL, return;);
+       ASSERT(qos != NULL, return;);
+       ASSERT(new != NULL, return;);
 
        /* Apply */
        qos->baud_rate.bits       &= new->baud_rate.bits;
index c4822e2c6e8655bb9531ff4066678bcc4130b921..b78368bc0e69c17d7da206ce9576c063fa75467f 100644 (file)
@@ -1,15 +1,15 @@
 /*********************************************************************
  *                
  * Filename:      wrapper.c
- * Version:       1.1
- * Description:   SIR wrapper layer
+ * Version:       1.2
+ * Description:   IrDA SIR async wrapper layer
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Wed Apr 21 12:45:55 1999
+ * Modified at:   Sun May  2 21:58:00 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, 
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
 #include <net/irda/irlap_frame.h>
 #include <net/irda/irda_device.h>
 
-inline static int stuff_byte(__u8 byte, __u8 *buf);
+static inline int stuff_byte(__u8 byte, __u8 *buf);
+
+static void state_outside_frame(struct irda_device *idev, __u8 byte);
+static void state_begin_frame(struct irda_device *idev, __u8 byte);
+static void state_link_escape(struct irda_device *idev, __u8 byte);
+static void state_inside_frame(struct irda_device *idev, __u8 byte);
+
+static void (*state[])(struct irda_device *idev, __u8 byte) = 
+{ 
+       state_outside_frame,
+       state_begin_frame,
+       state_link_escape,
+       state_inside_frame,
+};
 
 /*
  * Function async_wrap (skb, *tx_buff)
@@ -52,8 +65,6 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
                __u8 bytes[2];
        } fcs;
 
-       ASSERT(skb != NULL, return 0;);
-
        /* Initialize variables */
        fcs.value = INIT_FCS;
        n = 0;
@@ -74,13 +85,9 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
        } else
                xbofs = ((struct irlap_skb_cb *)(skb->cb))->xbofs;
 
-#if 0
-       for (i=0; i<xbofs; i++)
-               tx_buff[n++] = XBOF;
-#else
        memset(tx_buff+n, XBOF, xbofs);
        n += xbofs;
-#endif
+
        /* Start of packet character BOF */
        tx_buff[n++] = BOF;
 
@@ -94,7 +101,7 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
                ASSERT(n < (buffsize-5), return n;);
 
                n += stuff_byte(skb->data[i], tx_buff+n);
-               fcs.value = IR_FCS(fcs.value, skb->data[i]);
+               fcs.value = irda_fcs(fcs.value, skb->data[i]);
        }
        
        /* Insert CRC in little endian format (LSB first) */
@@ -108,15 +115,6 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
 #endif
        tx_buff[n++] = EOF;
 
-#if 0
-       {
-               int i;
-               
-               for (i=0;i<n;i++)
-                       printk("%02x", tx_buff[i]);
-               printk("\n");
-       }
-#endif
        return n;
 }
 
@@ -154,140 +152,6 @@ static inline void async_bump(struct irda_device *idev, __u8 *buf, int len)
        idev->stats.rx_bytes += skb->len;       
 }
 
-/*
- * Function async_unwrap (skb)
- *
- *    Parse and de-stuff frame received from the IR-port
- *
- */
-void async_unwrap_char(struct irda_device *idev, __u8 byte) 
-{
-       /* State machine for receiving frames */           
-       switch (idev->rx_buff.state) {
-       case OUTSIDE_FRAME:
-               switch(byte) {
-               case BOF:
-                       idev->rx_buff.state = BEGIN_FRAME;
-                       idev->rx_buff.in_frame = TRUE;
-                       break;
-               case XBOF:
-                       /* idev->xbofs++; */
-                       break;
-               case EOF:
-                       irda_device_set_media_busy( idev, TRUE);
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case BEGIN_FRAME:
-               switch (byte) {
-               case BOF:
-                       /* Continue */
-                       break;
-               case CE:
-                       /* Stuffed byte */
-                       idev->rx_buff.state = LINK_ESCAPE;
-                       break;
-               case EOF:
-                       /* Abort frame */
-                       idev->rx_buff.state = OUTSIDE_FRAME;
-
-                       idev->stats.rx_errors++;
-                       idev->stats.rx_frame_errors++;
-                       break;
-               default:
-                       /* Got first byte of frame */
-                       idev->rx_buff.data = idev->rx_buff.head;
-                       idev->rx_buff.len = 0;
-
-                       idev->rx_buff.data[idev->rx_buff.len++] = byte;
-                       
-                       idev->rx_buff.fcs = IR_FCS(INIT_FCS, byte);
-                       idev->rx_buff.state = INSIDE_FRAME;
-                       break;
-               }
-               break;
-       case LINK_ESCAPE:
-               switch (byte) {
-               case BOF:
-                       /* New frame? */
-                       idev->rx_buff.state = BEGIN_FRAME;
-                       irda_device_set_media_busy(idev, TRUE);
-                       break;
-               case CE:
-                       DEBUG(4, "WARNING: State not defined\n");
-                       break;
-               case EOF:
-                       /* Abort frame */
-                       idev->rx_buff.state = OUTSIDE_FRAME;
-                       break;
-               default:
-                       /* 
-                        *  Stuffed char, complement bit 5 of byte 
-                        *  following CE, IrLAP p.114 
-                        */
-                       byte ^= IR_TRANS;
-                       if (idev->rx_buff.len < idev->rx_buff.truesize)  {
-                               idev->rx_buff.data[idev->rx_buff.len++] = byte;
-                               idev->rx_buff.fcs = IR_FCS(idev->rx_buff.fcs,
-                                                          byte);
-                               idev->rx_buff.state = INSIDE_FRAME;
-                       } else {
-                               DEBUG(1, __FUNCTION__ 
-                                      "(), Rx buffer overflow, aborting\n");
-                               idev->rx_buff.state = OUTSIDE_FRAME;
-                       }
-                       break;
-               }
-               break;
-       case INSIDE_FRAME:
-               switch (byte) {
-               case BOF:
-                       /* New frame? */
-                       idev->rx_buff.state = BEGIN_FRAME;
-                       irda_device_set_media_busy(idev, TRUE);
-                       break;
-               case CE:
-                       /* Stuffed char */
-                       idev->rx_buff.state = LINK_ESCAPE;
-                       break;
-               case EOF:
-                       /* End of frame */
-                       idev->rx_buff.state = OUTSIDE_FRAME;
-                       idev->rx_buff.in_frame = FALSE;
-                       
-                       /* 
-                        *  Test FCS and deliver frame if it's good
-                        */                     
-                       if (idev->rx_buff.fcs == GOOD_FCS) {
-                               async_bump(idev, idev->rx_buff.data, 
-                                          idev->rx_buff.len);
-                       } else {
-                               /* Wrong CRC, discard frame!  */
-                               irda_device_set_media_busy(idev, TRUE); 
-
-                               idev->stats.rx_errors++;
-                               idev->stats.rx_crc_errors++;
-                       }                       
-                       break;
-               default:
-                       /* Next byte of frame */
-                       if (idev->rx_buff.len < idev->rx_buff.truesize)  {
-                               idev->rx_buff.data[idev->rx_buff.len++] = byte;
-                               idev->rx_buff.fcs = IR_FCS(idev->rx_buff.fcs,
-                                                          byte);
-                       } else {
-                               DEBUG(1, __FUNCTION__ 
-                                     "(), Rx buffer overflow, aborting\n");
-                               idev->rx_buff.state = OUTSIDE_FRAME;
-                       }
-                       break;
-               }
-               break;
-       }
-}
 /*
  * Function stuff_byte (byte, buf)
  *
@@ -295,7 +159,7 @@ void async_unwrap_char(struct irda_device *idev, __u8 byte)
  *    buf. The buffer must at all times be able to have two bytes inserted.
  * 
  */
-inline static int stuff_byte(__u8 byte, __u8 *buf) 
+static inline int stuff_byte(__u8 byte, __u8 *buf) 
 {
        switch (byte) {
        case BOF: /* FALLTHROUGH */
@@ -303,7 +167,7 @@ inline static int stuff_byte(__u8 byte, __u8 *buf)
        case CE:
                /* Insert transparently coded */
                buf[0] = CE;               /* Send link escape */
-               buf[1] = byte^IR_TRANS;    /* Complement bit 5 */
+               buf[1] = byte^IRDA_TRANS;    /* Complement bit 5 */
                return 2;
                /* break; */
        default:
@@ -313,7 +177,159 @@ inline static int stuff_byte(__u8 byte, __u8 *buf)
                /* break; */
        }
 }
+
+/*
+ * Function async_unwrap (skb)
+ *
+ *    Parse and de-stuff frame received from the IrDA-port
+ *
+ */
+inline void async_unwrap_char(struct irda_device *idev, __u8 byte)
+{
+       (*state[idev->rx_buff.state]) (idev, byte);
+}
         
+/*
+ * Function state_outside_frame (idev, byte)
+ *
+ *    
+ *
+ */
+static void state_outside_frame(struct irda_device *idev, __u8 byte)
+{
+       switch (byte) {
+       case BOF:
+               idev->rx_buff.state = BEGIN_FRAME;
+               idev->rx_buff.in_frame = TRUE;
+               break;
+       case XBOF:
+               /* idev->xbofs++; */
+               break;
+       case EOF:
+               irda_device_set_media_busy( idev, TRUE);
+               break;
+       default:
+               break;
+       }
+}
 
+/*
+ * Function state_begin_frame (idev, byte)
+ *
+ *    
+ *
+ */
+static void state_begin_frame(struct irda_device *idev, __u8 byte)
+{
+       switch (byte) {
+       case BOF:
+               /* Continue */
+               break;
+       case CE:
+               /* Stuffed byte */
+               idev->rx_buff.state = LINK_ESCAPE;
+               break;
+       case EOF:
+               /* Abort frame */
+               idev->rx_buff.state = OUTSIDE_FRAME;
+               
+               idev->stats.rx_errors++;
+               idev->stats.rx_frame_errors++;
+               break;
+       default:
+               /* Got first byte of frame */
+               idev->rx_buff.data = idev->rx_buff.head;
+               idev->rx_buff.len = 0;
+               
+               idev->rx_buff.data[idev->rx_buff.len++] = byte;
+               
+               idev->rx_buff.fcs = irda_fcs(INIT_FCS, byte);
+               idev->rx_buff.state = INSIDE_FRAME;
+               break;
+       }
+}
+
+/*
+ * Function state_link_escape (idev, byte)
+ *
+ *    
+ *
+ */
+static void state_link_escape(struct irda_device *idev, __u8 byte)
+{
+       switch (byte) {
+       case BOF: /* New frame? */
+               idev->rx_buff.state = BEGIN_FRAME;
+               irda_device_set_media_busy(idev, TRUE);
+               break;
+       case CE:
+               DEBUG(4, "WARNING: State not defined\n");
+               break;
+       case EOF: /* Abort frame */
+               idev->rx_buff.state = OUTSIDE_FRAME;
+               break;
+       default:
+               /* 
+                *  Stuffed char, complement bit 5 of byte 
+                *  following CE, IrLAP p.114 
+                */
+               byte ^= IRDA_TRANS;
+               if (idev->rx_buff.len < idev->rx_buff.truesize)  {
+                       idev->rx_buff.data[idev->rx_buff.len++] = byte;
+                       idev->rx_buff.fcs = irda_fcs(idev->rx_buff.fcs, byte);
+                       idev->rx_buff.state = INSIDE_FRAME;
+               } else {
+                       DEBUG(1, __FUNCTION__ 
+                             "(), Rx buffer overflow, aborting\n");
+                       idev->rx_buff.state = OUTSIDE_FRAME;
+               }
+               break;
+       }
+}
+
+/*
+ * Function state_inside_frame (idev, byte)
+ *
+ *    
+ *
+ */
+static void state_inside_frame(struct irda_device *idev, __u8 byte)
+{
+       switch (byte) {
+       case BOF: /* New frame? */
+               idev->rx_buff.state = BEGIN_FRAME;
+               irda_device_set_media_busy(idev, TRUE);
+               break;
+       case CE: /* Stuffed char */
+               idev->rx_buff.state = LINK_ESCAPE;
+               break;
+       case EOF: /* End of frame */
+               idev->rx_buff.state = OUTSIDE_FRAME;
+               idev->rx_buff.in_frame = FALSE;
+               
+               /* Test FCS and deliver frame if it's good */
+               if (idev->rx_buff.fcs == GOOD_FCS) {
+                       async_bump(idev, idev->rx_buff.data, 
+                                  idev->rx_buff.len);
+               } else {
+                       /* Wrong CRC, discard frame!  */
+                       irda_device_set_media_busy(idev, TRUE); 
+                       
+                       idev->stats.rx_errors++;
+                       idev->stats.rx_crc_errors++;
+               }                       
+               break;
+       default: /* Must be the next byte of the frame */
+               if (idev->rx_buff.len < idev->rx_buff.truesize)  {
+                       idev->rx_buff.data[idev->rx_buff.len++] = byte;
+                       idev->rx_buff.fcs = irda_fcs(idev->rx_buff.fcs, byte);
+               } else {
+                       DEBUG(1, __FUNCTION__ 
+                             "(), Rx buffer overflow, aborting\n");
+                       idev->rx_buff.state = OUTSIDE_FRAME;
+               }
+               break;
+       }
+}