Hi Manuel,

On Sat, 8 Jul 2006 15:27:22 -0300
"Naranjo Manuel Francisco" <[EMAIL PROTECTED]> wrote:

| 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-08 15:08:36.000000000 
-0300
| @@ -0,0 +1,314 @@
| +/*
| + * 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>

  Why don't '#include "usbserial.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) //124 252 956
| +#define HCI_COMPLETE_FRAME   64
| +
| +/* Debug macro */
| +#undef dbg
| +#define dbg(format, arg...) if (debug) do { printk(KERN_DEBUG "%s: "
| format "\n", __FILE__ , ## arg); } while (0)

 We do have a debug macro in usbserial.h already.

| +
| +/*
| + * 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,
| +//   .num_interrupt_in=              0,
| +//   .num_interrupt_out=             0,
| +//   .num_bulk_in=                   82,
| +//   .num_bulk_out=                  02,
| +     .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;
| +     length = 0;
| +     result=0;

 Are you sure 'length' and 'result' must be zeroed here?

| +     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);
| +

 Blank line.

| +     if (result){
| +             dev_err(&port->dev, "%s - failed submitting write urb, error 
%d\n",
| +                                                                             
                                __FUNCTION__, result);
| +             kfree(buffer);
| +             count = result;
| +     }
| +
| +     usb_free_urb (urb);

 Remove that space please, that's also happens in other places also..

| +     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);
| +
| +     port->write_urb_busy = 0;

 Why?

| +     
| +     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);
| +                             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
| _______________________________________________
| linux-usb-devel@lists.sourceforge.net
| To unsubscribe, use the last form field at:
| https://lists.sourceforge.net/lists/listinfo/linux-usb-devel


-- 
Luiz Fernando N. Capitulino


-------------------------------------------------------------------------
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
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to