Hi,
Here is the patch again :) , I have made the corrections suggested by
Olivier and Luiz.
I have corrected what my email client was removing.
Please take a look at it.
Naranjo, Manuel Francisco
[EMAIL PROTECTED]

Signed-off-by: Naranjo, Manuel Francisco <[EMAIL PROTECTED]>

diff -uprN -X linux-vanilla/Documentation/dontdiff 
linux-vanilla/drivers/usb/serial/aircable.c linux/drivers/usb/serial/aircable.c
--- linux-vanilla/drivers/usb/serial/aircable.c    1969-12-31 
21:00:00.000000000 -0300
+++ linux/drivers/usb/serial/aircable.c    2006-07-09 15:06:22.000000000 -0300
@@ -0,0 +1,308 @@
+/*
+ * AIRcable USB Bluetooth dondgle Driver.
+ *
+ * Copyright (C) 2006 Manuel Francisco Naranjo ([EMAIL PROTECTED])
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This driver uses the USB Serial Core driver, to make AIRcable USB
+ * dongles work.
+ *
+ * The AIRcable USB Bluetooth Dongles has two interfaces, the first
+ * one is usless for serial working, I think it must be for firmware
+ * updating.
+ * The second interfaces has a bulk in and a bulk out, and is the one
+ * used for serial transactions.
+ * AIRcable USB Bluetooth Dongles works like an standard ACM but witj little
+ * changes, it sends data in packages of 124 bytes, and adds at the begging
+ * of each package 4 bytes for header.
+ *
+ * I have also taken some info from a Greg Kroah-Hartman article
+ * url: http://www.linuxjournal.com/article/6573
+ * And from Linux Device Driver Kit CD, which is a great work, the authors
+ * taken the work to recopile lots of information an knowladge in drivers
+ * development and made it all avaible inside a cd.
+ * URL: http://kernel.org/pub/linux/kernel/people/gregkh/ddk/
+ *
+ */
+
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#include <linux/usb.h>
+#include <../drivers/usb/serial/usb-serial.h>
+
+//#include "usb-serial.h"
+
+
+static int debug;
+
+#define AIRCABLE_VID        0x16CA    /* Vendor Id */
+#define AIRCABLE_USB_PID    0x1502    /* Product Id */
+
+/* The following defintions are required to Add/Strip HCI headers from URB sent
+   over bulk endpoints */
+#define HCI_HEADER_LENGTH    0x4
+#define HCI_HEADER_0        0x20
+#define HCI_HEADER_1        0x29
+#define MAX_HCI_FRAMESIZE    60
+#define HCI_COMPLETE_FRAME    64
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v1.0b2"
+#define DRIVER_AUTHOR "Naranjo, Manuel Francisco <[EMAIL PROTECTED]>"
+#define DRIVER_DESC "AIRcable USB Driver"
+
+/* ID table that will be registered with USB core */
+static struct usb_device_id id_table [] = {
+    { USB_DEVICE(AIRCABLE_VID, AIRCABLE_USB_PID) },
+    { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+
+
+/* Methods declaration */
+static int aircable_probe(struct usb_serial *serial,
+                        const struct usb_device_id *id);
+static int aircable_write(struct usb_serial_port *port,
+                    const unsigned char *buf, int count);
+static void aircable_read_bulk_callback(struct urb *urb, struct pt_regs *regs);
+static void aircable_write_bulk_callback(struct urb *urb, struct pt_regs 
*regs);
+
+/* All device info needed for AIRcable USB device */
+static struct usb_serial_driver aircable_device = {
+    .description =            "AIRcableUSB",
+    .id_table =             id_table,
+    .num_ports =            1,
+    .probe=                    aircable_probe,
+    .write=                    aircable_write,
+    .write_bulk_callback=    aircable_write_bulk_callback,
+    .read_bulk_callback=    aircable_read_bulk_callback,
+};
+
+static struct usb_driver aircable_driver = {
+    .name =            "AIRcableUSB",
+    .probe =        usb_serial_probe,
+    .disconnect =    usb_serial_disconnect,
+    .id_table =        id_table,
+};
+
+/* Methods implementation */
+
+/* Based on serial_probe */
+static int aircable_probe(struct usb_serial *serial,
+                        const struct usb_device_id *id)
+{
+    //This was taken from usb-serial.c probe
+    //And addapted to fit AIRcable needs
+    struct usb_host_interface *iface_desc = serial->interface->cur_altsetting;
+    struct usb_endpoint_descriptor *endpoint;
+    int num_bulk_out=0;
+    int i;
+    for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+        endpoint = &iface_desc->endpoint[i].desc;
+        if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
+            ((endpoint->bmAttributes & 3) == 0x02)) {
+            /* we found a bulk out endpoint */
+            dbg("found bulk out on endpoint %d", i);
+
+            ++num_bulk_out;
+        }
+    }
+    if (num_bulk_out == 0) {
+        dbg("Invalid interface, discarding.\n");
+        return -ENODEV;
+    }
+    return 0;
+}
+
+/*
+ * Based on Generic_write and AIRcable Windows driver
+ * Thanks Juergen Kienhoefer from AIRcable for the support, and
+ * giving me access to their Windows Driver.
+ */
+static int aircable_write(struct usb_serial_port *port,
+                                        const unsigned char *source, int count)
+{
+    struct usb_serial *serial = port->serial;
+    struct urb *urb;
+    unsigned char *buffer;
+    int result;
+    int no_headers;
+    int payload_length;
+    int length;
+    int i;
+    int offset;
+    int src_offset;
+
+
+    dbg("%s - port %d", __FUNCTION__, port->number);
+
+    if (count == 0){
+        dbg("%s - write request of 0 bytes", __FUNCTION__);
+        return 0;
+    }
+
+    no_headers = (count / MAX_HCI_FRAMESIZE) + 1;
+    payload_length = count;
+    buffer = kzalloc(count + no_headers * HCI_HEADER_LENGTH ,GFP_ATOMIC);
+    if (!buffer){
+        err("%s ran out of kernel memory for urb ...", __FUNCTION__);
+        return -ENOMEM;
+    }
+
+    urb = usb_alloc_urb(0, GFP_ATOMIC);
+    if (!urb) {
+        err("%s - no more free urbs", __FUNCTION__);
+        kfree (buffer);
+        return -ENOMEM;
+    }
+
+    for(i = 0; i < no_headers; i++) {
+        if(payload_length >= MAX_HCI_FRAMESIZE)
+            length = MAX_HCI_FRAMESIZE;
+        else
+            length = payload_length;
+        payload_length -= length;
+        offset = i * HCI_COMPLETE_FRAME;
+        src_offset = i * MAX_HCI_FRAMESIZE;
+        buffer[offset] = HCI_HEADER_0;
+        buffer[offset+1] = HCI_HEADER_1;
+        buffer[offset+2] = (unsigned char) length;
+        buffer[offset+3] = (unsigned char)(length >8);
+        memcpy(buffer + offset + HCI_HEADER_LENGTH, source + 
src_offset,length);
+    }
+
+    usb_serial_debug_data(debug, &port->dev, __FUNCTION__, length +
+                                                    HCI_HEADER_LENGTH , 
buffer);
+    usb_fill_bulk_urb (urb, serial->dev,
+        usb_sndbulkpipe (serial->dev, port->bulk_out_endpointAddress),
+        buffer, count + no_headers * HCI_HEADER_LENGTH ,
+        aircable_write_bulk_callback, port);
+
+    result = usb_submit_urb(urb, GFP_ATOMIC);
+    if (result){
+        dev_err(&port->dev, "%s - failed submitting write urb, error %d\n",
+                                                        __FUNCTION__, result);
+        kfree(buffer);
+        count = result;
+    }
+
+    usb_free_urb(urb);
+    dbg("%s write returning: %d", __FUNCTION__, count);
+
+    return count;
+}
+
+static void aircable_write_bulk_callback (struct urb *urb, struct pt_regs 
*regs)
+{
+    struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+
+    /* free up the transfer buffer, as usb_free_urb() does not do this */
+    kfree (urb->transfer_buffer);
+
+    dbg("%s - port %d", __FUNCTION__, port->number);
+
+    if (urb->status) {
+        dbg("nonzero write bulk status received: %d", urb->status);
+        return;
+    }
+    usb_serial_port_softint((void *)port);
+    schedule_work(&port->work);
+}
+
+static void aircable_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
+{
+    struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+    struct usb_serial *serial = port->serial;
+    struct tty_struct *tty;
+    unsigned char *data;
+    unsigned long no_packages;
+    unsigned long remaining, package_length;
+    unsigned long i;
+    int result;
+
+    dbg("%s - port %d", __FUNCTION__, port->number);
+
+    if (urb->status) {
+        dbg("%s - nonzero read bulk status received: %d", __FUNCTION__,
+                                                                urb->status);
+        return;
+    }
+
+    tty = port->tty;
+    if (tty && urb->actual_length) {
+        usb_serial_debug_data(debug, &port->dev, __FUNCTION__,
+                                    urb->actual_length , urb->transfer_buffer);
+        if (urb->actual_length HCI_HEADER_LENGTH){
+            remaining = urb->actual_length;
+            no_packages = urb->actual_length / (HCI_COMPLETE_FRAME);
+            if (urb->actual_length % HCI_COMPLETE_FRAME != 0)
+                no_packages+=1;
+            for (i = 0; i < no_packages ; ++i) {
+                if (remaining (HCI_COMPLETE_FRAME))
+                    package_length = HCI_COMPLETE_FRAME;
+                else
+                    package_length = remaining;
+                remaining -= package_length;
+                data = kmalloc(package_length - HCI_HEADER_LENGTH, GFP_ATOMIC);
+                if (!data){
+                    err("%s ran out of kernel memory for urb ...",
+                                                                __FUNCTION__);
+                    return -ENOMEM;
+                }
+
+                memcpy(data, urb->transfer_buffer + HCI_HEADER_LENGTH +
+                    (HCI_COMPLETE_FRAME)*(i),
+                    package_length - HCI_HEADER_LENGTH);
+                tty_buffer_request_room(tty,package_length - 
HCI_HEADER_LENGTH);
+                tty_insert_flip_string(tty,data,
+                                            package_length - 
HCI_HEADER_LENGTH);
+                tty_flip_buffer_push(tty);
+                kfree(data);
+            }
+        }
+    }
+    usb_fill_bulk_urb(port->read_urb, serial->dev,
+            usb_rcvbulkpipe(serial->dev,
+                    port->bulk_in_endpointAddress),
+            port->read_urb->transfer_buffer,
+            port->read_urb->transfer_buffer_length,
+            serial->type->read_bulk_callback, port);
+    result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+    if (result)
+        dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
+                                                        __FUNCTION__, result);
+}
+
+/* END OF Methods Implementatio */
+
+static int __init aircable_init (void)
+{
+    usb_serial_register(&aircable_device);
+    usb_register(&aircable_driver);
+    return 0;
+}
+
+static void __exit aircable_exit (void)
+{
+    usb_deregister(&aircable_driver);
+    usb_serial_deregister(&aircable_device);
+}
+
+/* Module information */
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_VERSION( DRIVER_VERSION );
+MODULE_LICENSE("GPL");
+
+
+module_init(aircable_init);
+module_exit(aircable_exit);
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff -uprN -X linux-vanilla/Documentation/dontdiff 
linux-vanilla/drivers/usb/serial/Kconfig linux/drivers/usb/serial/Kconfig
--- linux-vanilla/drivers/usb/serial/Kconfig    2006-03-20 02:53:29.000000000 
-0300
+++ linux/drivers/usb/serial/Kconfig    2006-07-08 15:09:44.000000000 -0300
@@ -484,6 +484,15 @@ config USB_SERIAL_OMNINET
        To compile this driver as a module, choose M here: the
        module will be called omninet.

+config USB_SERIAL_AIRCABLE
+    tristate "AIRcable USB Bluetooth dongle Driver (EXPERIMENTAL)"
+    depends on USB_SERIAL && EXPERIMENTAL
+    help
+      Say Y here if you want to use an AIRcable USB Bluetooth dongle.
+
+      To compile this driver as a module, choose M here: the
+      module will be called aircable.
+
  config USB_EZUSB
      bool
      depends on USB_SERIAL_KEYSPAN_PDA || USB_SERIAL_XIRCOM || 
USB_SERIAL_KEYSPAN || USB_SERIAL_WHITEHEAT
diff -uprN -X linux-vanilla/Documentation/dontdiff 
linux-vanilla/drivers/usb/serial/Makefile linux/drivers/usb/serial/Makefile
--- linux-vanilla/drivers/usb/serial/Makefile    2006-03-20 02:53:29.000000000 
-0300
+++ linux/drivers/usb/serial/Makefile    2006-07-08 15:09:54.000000000 -0300
@@ -40,4 +40,5 @@ obj-$(CONFIG_USB_SERIAL_TI)            += ti_usb_
  obj-$(CONFIG_USB_SERIAL_VISOR)            += visor.o
  obj-$(CONFIG_USB_SERIAL_WHITEHEAT)        += whiteheat.o
  obj-$(CONFIG_USB_SERIAL_XIRCOM)            += keyspan_pda.o
+obj-$(CONFIG_USB_SERIAL_AIRCABLE)        += aircable.o


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to