Linus,
Please apply this patch to your latest Linux-2.4.2 source. Changes:
o IrDA-USB dongle support [new feature]
-- Dag
diff -urpN linux-2.4.2/Documentation/Configure.help linux-2.4.2-irda-patch/Documentation/Configure.help
--- linux-2.4.2/Documentation/Configure.help Tue Feb 27 08:59:00 2001
+++ linux-2.4.2-irda-patch/Documentation/Configure.help Tue Feb 27 08:59:08 2001
@@ -16739,8 +16739,7 @@ CONFIG_IRDA
infrared communication and is supported by most laptops and PDA's.
To use Linux support for the IrDA (tm) protocols, you will also need
- some user-space utilities like the irmanager and probably irattach
- as well. For more information, see the file
+ some user-space utilities like irattach. For more information, see the file
Documentation/networking/irda.txt. You also want to read the
IR-HOWTO, available at http://www.linuxdoc.org/docs.html#howto .
@@ -16849,6 +16848,19 @@ CONFIG_IRPORT_SIR
115200 bps.
If unsure, say Y.
+
+USB IrDA FIR Dongle Device Driver
+CONFIG_USB_IRDA
+ Say Y here if you want to build support for the USB IrDA FIR Dongle
+ device driver. If you want to compile it as a module (irda-usb.o),
+ say M here and read Documentation/modules.txt. IrDA-USB support the
+ various IrDA USB dongles available and most of their pecularities.
+ Those dongles plug in the USB port of your computer, are plug and
+ play, and support SIR and FIR (4Mbps) speeds. On the other hand,
+ those dongles tend to be less efficient than a FIR chipset.
+
+ Please note that the driver is still experimental. And of course,
+ you will need both USB and IrDA support in your kernel...
Winbond W83977AF IrDA Device Driver
CONFIG_WINBOND_FIR
diff -urpN linux-2.4.2/drivers/net/irda/Config.in linux-2.4.2-irda-patch/drivers/net/irda/Config.in
--- linux-2.4.2/drivers/net/irda/Config.in Tue Feb 27 08:59:00 2001
+++ linux-2.4.2-irda-patch/drivers/net/irda/Config.in Tue Feb 27 08:57:44 2001
@@ -5,14 +5,6 @@ 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/PC87338' CONFIG_NSC_FIR $CONFIG_IRDA
-dep_tristate 'Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
-dep_tristate 'Toshiba Type-O IR Port' CONFIG_TOSHIBA_FIR $CONFIG_IRDA
-if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
-dep_tristate 'SMC IrCC (Experimental)' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA
-fi
-
comment 'Dongle support'
bool 'Serial dongle support' CONFIG_DONGLE
if [ "$CONFIG_DONGLE" != "n" ]; then
@@ -22,6 +14,15 @@ if [ "$CONFIG_DONGLE" != "n" ]; then
dep_tristate ' Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRDA
dep_tristate ' Parallax LiteLink dongle' CONFIG_LITELINK_DONGLE $CONFIG_IRDA
dep_tristate ' Old Belkin dongle' CONFIG_OLD_BELKIN_DONGLE $CONFIG_IRDA
+fi
+
+comment 'FIR device drivers'
+dep_tristate 'IrDA USB dongles (Experimental)' CONFIG_USB_IRDA $CONFIG_IRDA $CONFIG_USB $CONFIG_EXPERIMENTAL
+dep_tristate 'NSC PC87108/PC87338' CONFIG_NSC_FIR $CONFIG_IRDA
+dep_tristate 'Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
+dep_tristate 'Toshiba Type-O IR Port' CONFIG_TOSHIBA_FIR $CONFIG_IRDA
+if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
+dep_tristate 'SMC IrCC (Experimental)' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA
fi
endmenu
diff -urpN linux-2.4.2/drivers/net/irda/Makefile linux-2.4.2-irda-patch/drivers/net/irda/Makefile
--- linux-2.4.2/drivers/net/irda/Makefile Tue Feb 27 08:59:00 2001
+++ linux-2.4.2-irda-patch/drivers/net/irda/Makefile Tue Feb 27 08:57:44 2001
@@ -12,6 +12,7 @@ export-objs = irport.o
obj-$(CONFIG_IRTTY_SIR) += irtty.o read more »
obj-$(CONFIG_IRPORT_SIR) += irport.o
+obj-$(CONFIG_USB_IRDA) += irda-usb.o
obj-$(CONFIG_NSC_FIR) += nsc-ircc.o
obj-$(CONFIG_WINBOND_FIR) += w83977af_ir.o
obj-$(CONFIG_TOSHIBA_FIR) += toshoboe.o
diff -urpN linux-2.4.2/drivers/net/irda/irda-usb.c linux-2.4.2-irda-patch/drivers/net/irda/irda-usb.c
--- linux-2.4.2/drivers/net/irda/irda-usb.c Thu Jan 1 01:00:00 1970
+++ linux-2.4.2-irda-patch/drivers/net/irda/irda-usb.c Tue Feb 27 08:57:44 2001
@@ -0,0 +1,1158 @@
+/*************************************************************************
+ *
+ * Filename: irda-usb.c
+ * Version: 0.8
+ * Description: IrDA-USB Driver
+ * Status: Experimental
+ * Author: Dag Brattli <d...@brattli.net>
+ *
+ * Copyright (C) 2001, Dag Brattli <d...@brattli.net>
+ * Copyright (C) 2001, Jean Tourrilhes <j...@hpl.hp.com>
+ * Copyright (C) 2000, Roman Weissgaerber <wei...@vienna.at>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ***************************************************************************
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/malloc.h>
+#include <linux/rtnetlink.h>
+#include <linux/usb.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irlap.h>
+#include <net/irda/irda_device.h>
+#include <net/irda/wrapper.h>
+
+#include <net/irda/irda-usb.h>
+
+static u32 min_turn_times[] = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
+static int qos_mtt_bits = 0;
+
+static void irda_usb_dump_class_desc(struct irda_class_desc *desc);
+static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum);
+static void irda_usb_disconnect(struct usb_device *dev, void *ptr);
+static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self);
+static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev);
+static int irda_usb_open(struct irda_usb_cb *self);
+static int irda_usb_close(struct irda_usb_cb *self);
+static void irda_usb_write_bulk(struct irda_usb_cb *self, purb_t purb);
+static void write_bulk_callback(purb_t purb);
+static void irda_usb_receive(purb_t purb);
+static int irda_usb_net_init(struct net_device *dev);
+static int irda_usb_net_open(struct net_device *dev);
+static int irda_usb_net_close(struct net_device *dev);
+static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static void irda_usb_net_timeout(struct net_device *dev);
+static struct net_device_stats *irda_usb_net_get_stats(struct net_device *dev);
+
+/* Master instance for each hardware found */
+#define NIRUSB 4 /* Max number of USB-IrDA dongles */
+static struct irda_usb_cb irda_instance[NIRUSB];
+
+/* These are the currently known IrDA USB dongles. Add new dongles here */
+struct irda_usb_dongle dongles[] = { /* idVendor, idProduct, idCapability */
+ /* ACTiSYS Corp, ACT-IR2000U FIR-USB Adapter */
+ { 0x9c4, 0x011, IUC_SPEED_BUG | IUC_NO_WINDOW },
+ /* KC Technology Inc., KC-180 USB IrDA Device */
+ { 0x50f, 0x180, IUC_SPEED_BUG | IUC_NO_WINDOW },
+ /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */
+ { 0x8e9, 0x100, IUC_SPEED_BUG | IUC_NO_WINDOW },
+ { 0, 0, 0 }, /* The end */
+};
+
+/*
+ * This routine is called by the USB subsystem for each new device
+ * in the system. We need to check if the device is ours, and in
+ * this case start handling it.
+ * Note : it might be worth protecting this function by a global
+ * spinlock...
+ */
+static void *irda_usb_probe(struct usb_device *dev, unsigned int ifnum,
+ const struct usb_device_id *id)
+{
+ struct irda_usb_cb *self = NULL;
+ struct usb_interface_descriptor *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct irda_class_desc *irda_desc;
+ struct irda_usb_dongle *dongle;
+ int class, subclass;
+ int found;
+ int capability = IUC_DEFAULT;
+ int ret;
+ int ep;
+ int i;
+
+ IRDA_DEBUG(0, "Vendor: %x, Product: %x\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
+
+ /* Check for all known IrDA-USB dongles */
+ found = 0;
+ for (dongle=dongles;dongle->idVendor;dongle++) {
+ if ((dev->descriptor.idVendor == dongle->idVendor) &&
+ (dev->descriptor.idProduct == dongle->idProduct))
+ {
+ found = TRUE;
+ capability = dongle->idCapability;
+ break;
+ }
+ }
+ if (!found) {
+ /* Accept all dongles with IrDA-USB class/subclass */
+ class = dev->actconfig->interface[ifnum].altsetting[0].bInterfaceClass;
+ subclass = dev->actconfig->interface[ifnum].altsetting[0].bInterfaceSubClass;
+ IRDA_DEBUG(0, "Class: %x, Subclass: %x\n", class, subclass);
+
+ if ((class != USB_CLASS_APP_SPEC) || (subclass != USB_CLASS_IRDA))
+ return NULL;
+ }
+
+ MESSAGE("IRDA-USB found at address %d\n", dev->devnum);
+
+ /* Try to cleanup all instance that have a pending disconnect
+ * Instance will be in this state is the disconnect() occurs
+ * before the net_close().
+ * Jean II */
+ for (i = 0; i < NIRUSB; i++) {
+ struct irda_usb_cb *irda = &irda_instance[i];
+ if ((irda->usbdev != NULL) &&
+ (irda->present == 0) &&
+ (irda->netopen == 0)) {
+ IRDA_DEBUG(0, __FUNCTION__ "(), found a zombie instance !!!\n");
+ irda_usb_disconnect(irda->usbdev, (void *) irda);
+ }
+ }
+
+ /* Find an free instance to handle this new device... */
+ self = NULL;
+ for (i = 0; i < NIRUSB; i++) {
+ if(irda_instance[i].usbdev == NULL) {
+ self = &irda_instance[i];
+ break;
+ }
+ }
+ if (self == NULL) {
+ IRDA_DEBUG(0, "Too many USB IrDA devices !!! (max = %d)\n",
+ NIRUSB);
...