Hello, I previously submitted a driver for Garmin GPS that used its own minor number interface. Greg suggested using the usb-serial interface instead. I thought the usb-serial interface made sense after investigating it a little. The following patch is a usb-serial interface version of the Garmin GPS driver. It was borrowed from the palm OS PDA drivers (visor.c).
Thanks, Marty cd /usr/src/linux; patch -p0 -b < patchfile Files /usr/src/linux-2.6.9_default/drivers/usb/serial/.garmin_usb_tty.h.swp and ./drivers/usb/serial/.garmin_usb_tty.h.swp differ diff -u -r -N /usr/src/linux-2.6.9_default/drivers/usb/serial/Kconfig ./drivers/usb/serial/Kconfig --- /usr/src/linux-2.6.9_default/drivers/usb/serial/Kconfig 2004-11-02 23:35:30.000000000 +0000 +++ ./drivers/usb/serial/Kconfig 2004-11-07 23:26:38.000000000 +0000 @@ -387,11 +387,22 @@ To compile this driver as a module, choose M here: the module will be called omninet. - + config USB_EZUSB bool depends on USB_SERIAL_KEYSPAN_PDA || USB_SERIAL_XIRCOM || USB_SERIAL_KEYSPAN || USB_SERIAL_WHITEHEAT default y +config USB_SERIAL_GARMIN + tristate "USB to serial conversion for Garmin GPS (EXPERIMENTAL)" + depends on USB_SERIAL && EXPERIMENTAL + help + Say Y here is you want to use an USB Garmin gps through + the serial port. + + To compile this driver as a module, choose M here: the + module will be called garmin_usb_tty. + + endmenu diff -u -r -N /usr/src/linux-2.6.9_default/drivers/usb/serial/Makefile ./drivers/usb/serial/Makefile --- /usr/src/linux-2.6.9_default/drivers/usb/serial/Makefile 2004-11-02 23:35:30.000000000 +0000 +++ ./drivers/usb/serial/Makefile 2004-11-04 22:49:01.000000000 +0000 @@ -31,4 +31,4 @@ 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_GARMIN) += garmin_usb_tty.o diff -u -r -N /usr/src/linux-2.6.9_default/drivers/usb/serial/garmin_usb_tty.c ./drivers/usb/serial/garmin_usb_tty.c --- /usr/src/linux-2.6.9_default/drivers/usb/serial/garmin_usb_tty.c 1970-01-01 00:00:00.000000000 +0000 +++ ./drivers/usb/serial/garmin_usb_tty.c 2004-11-08 00:17:07.248247352 +0000 @@ -0,0 +1,709 @@ +/* + * Garmin GPS USB to serial interface + * Copyright (C) 2004 Martin Boos <[EMAIL PROTECTED]> + * + * Based on: + * USB HandSpring garmin, Palm m50x, and Sony Clie driver + * (supports all of the Palm OS USB devices) + * + * Copyright (C) 1999 - 2004 + * Greg Kroah-Hartman ([EMAIL PROTECTED]) + * + * 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. + * + * See Documentation/usb/usb-serial.txt for more information on using this driver + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/tty.h> +#include <linux/tty_driver.h> +#include <linux/tty_flip.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/spinlock.h> +#include <asm/uaccess.h> +#include <linux/usb.h> +#include "usb-serial.h" +#include "garmin_usb_tty.h" + +/* + * Version Information + */ +#define DRIVER_VERSION "v0.01" +#define DRIVER_AUTHOR "Martin Boos <[EMAIL PROTECTED]>" +#define DRIVER_DESC "USB to serial for Garmin GPS" + +#define HEADER_SIZE sizeof( struct garmin_usb_header ) + +/* States returned from packetize() */ +enum { + ACCUMULATE_PACKET, + VALID_PACKET, + INVALID_PACKET +}; + +/* function prototypes for usb-serial device */ +static int garmin_attach (struct usb_serial *serial); +static int garmin_open (struct usb_serial_port *port, struct file *filp); +static void garmin_close (struct usb_serial_port *port, struct file *filp); +static int garmin_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count); +static int garmin_write_room (struct usb_serial_port *port); +static int garmin_chars_in_buffer (struct usb_serial_port *port); +static void garmin_throttle (struct usb_serial_port *port); +static void garmin_unthrottle (struct usb_serial_port *port); +static int garmin_probe (struct usb_serial *serial, const struct usb_device_id *id); +static int garmin_calc_num_ports(struct usb_serial *serial); +static void garmin_shutdown (struct usb_serial *serial); +static int garmin_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); +static void garmin_set_termios (struct usb_serial_port *port, struct termios *old_termios); +static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs); +static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs); + +/* local functions */ +static int packetize( char *data, int data_size, char *buffer, int buffer_size, int *buffer_count ); + +/* Parameters that may be passed into the module. */ +static int debug; + + +static struct usb_device_id id_table [] = { + { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_GPSMAP_60_ID) }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, id_table); + +static struct usb_driver garmin_driver = { + .owner = THIS_MODULE, + .name = "garmin_usb_tty", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, +}; + +/* This should work will all USB garmin gps except the PDA units */ +static struct usb_serial_device_type generic_device = { + .owner = THIS_MODULE, + .name = DRIVER_DESC, + .short_name = "garmin", + .id_table = id_table, + .num_interrupt_in = 1, + .num_bulk_in = 1, + .num_bulk_out = 1, + .num_ports = 1, + .open = garmin_open, + .close = garmin_close, + .throttle = garmin_throttle, + .unthrottle = garmin_unthrottle, + .attach = garmin_attach, + .probe = garmin_probe, + .calc_num_ports = garmin_calc_num_ports, + .shutdown = garmin_shutdown, + .ioctl = garmin_ioctl, + .set_termios = garmin_set_termios, + .write = garmin_write, + .write_room = garmin_write_room, + .chars_in_buffer = garmin_chars_in_buffer, + .write_bulk_callback = garmin_write_bulk_callback, + .read_bulk_callback = garmin_read_bulk_callback, + .read_int_callback = garmin_read_int_callback, +}; + +static int bytes_in; +static int bytes_out; + + +void inline send_tty_data( struct tty_struct * tty, unsigned char * data, int length ) +{ + int i; + for (i = 0; i < length ; ++i) { + /* if we insert more than TTY_FLIPBUF_SIZE + * characters, we drop them. + */ + if(tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty_flip_buffer_push(tty); + } + /* this doesn't actually push the data through + * unless tty->low_latency is set + */ + tty_insert_flip_char(tty, data[i], 0); + } + tty_flip_buffer_push(tty); +} + +/****************************************************************************** + * garmin specific driver functions + ******************************************************************************/ +static int garmin_open (struct usb_serial_port *port, struct file *filp) +{ + struct usb_serial *serial = port->serial; + struct garmin_serial * pd; /* private data */ + unsigned char start_session_data[] = { TRANSPORT_TYPE, 0, 0, 0, + START_SESSION_ID, 0, 0, 0, + 0, 0, 0, 0 }; + int result = -1; + int written = 0; + + dbg("%s - port %d", __FUNCTION__, port->number); + + bytes_in = 0; + bytes_out = 0; + /* + * Force low_latency on so that our tty_push actually forces the data + * through, otherwise it is scheduled, and with high data rates (like + * with OHCI) data can get lost. + */ + if (port->tty) + port->tty->low_latency = 1; + + /* allocate and setup driver private data */ + pd = ( struct garmin_serial * )kmalloc( sizeof( struct garmin_serial ), GFP_KERNEL ); + if( pd == NULL ) + goto exit; + + pd->int_buffer_count = 0; + pd->int_buffer_size = 1024 * 4; + pd->int_buffer = kmalloc( pd->int_buffer_size, GFP_KERNEL ); + if( pd->int_buffer == NULL ) + goto exit_free_pd; + + pd->bulk_buffer_count = 0; + pd->bulk_buffer_size = 1024 * 4; + pd->bulk_buffer = kmalloc( pd->bulk_buffer_size, GFP_KERNEL ); + if( pd->bulk_buffer == NULL ) + goto exit_free_int; + + pd->session_started = 0; + usb_set_serial_data( serial, pd ); + + /* Start reading from the device */ + 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, + garmin_read_bulk_callback, port); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); + if (result) { + dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", + __FUNCTION__, result); + goto exit_free_all; + } + + if (port->interrupt_in_urb) { + dbg("%s - adding interrupt input", __FUNCTION__); + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (result){ + dev_err(&port->dev, "%s - failed submitting interrupt urb, error %d\n", + __FUNCTION__, result); + goto exit_free_all; + } + } + + /* start session with device */ + written = garmin_write( port, 0, start_session_data, sizeof( start_session_data ) ); + if( written != sizeof( start_session_data ) ){ + dbg("couldn't write start session"); + result = -1; + goto exit_free_all; + } + + return 0; + +exit_free_all: + kfree( pd->bulk_buffer ); +exit_free_int: + kfree( pd->int_buffer ); +exit_free_pd: + kfree( pd ); +exit: + return result; +} + +static void garmin_close (struct usb_serial_port *port, struct file * filp) +{ + struct usb_serial *serial = port->serial; + struct garmin_serial * pd; /* private data */ + + /* shutdown our urbs */ + usb_unlink_urb (port->read_urb); + if (port->interrupt_in_urb) + usb_unlink_urb (port->interrupt_in_urb); + + /* free driver private data */ + pd = ( struct garmin_serial* )usb_get_serial_data( serial ); + if( pd ){ + kfree( pd->int_buffer ); + kfree( pd->bulk_buffer ); + kfree( pd ); + } + + /* Uncomment the following line if you want to see some statistics in your syslog */ + /* dev_info (&port->dev, "Bytes In = %d Bytes Out = %d\n", bytes_in, bytes_out); */ +} + + +static int garmin_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count) +{ + struct usb_serial *serial = port->serial; + struct urb *urb; + unsigned char *buffer; + int status; + + dbg("%s - port %d", __FUNCTION__, port->number); + + buffer = kmalloc (count, GFP_ATOMIC); + if (!buffer) { + dev_err(&port->dev, "out of memory\n"); + return -ENOMEM; + } + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + dev_err(&port->dev, "no more free urbs\n"); + kfree (buffer); + return -ENOMEM; + } + + if (from_user) { + if (copy_from_user (buffer, buf, count)) { + kfree (buffer); + usb_free_urb (urb); + return -EFAULT; + } + } else { + memcpy (buffer, buf, count); + } + + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer); + + usb_fill_bulk_urb (urb, serial->dev, + usb_sndbulkpipe (serial->dev, + port->bulk_out_endpointAddress), + buffer, count, + garmin_write_bulk_callback, port); + + /* send it down the pipe */ + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) { + dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", + __FUNCTION__, status); + count = status; + kfree (buffer); + } else { + bytes_out += count; + } + + /* we are done with this urb, so let the host driver + * really free it when it is finished with it */ + usb_free_urb (urb); + + return count; +} + + +static int garmin_write_room (struct usb_serial_port *port) +{ + dbg("%s - port %d", __FUNCTION__, port->number); + + /* + * We really can take anything the user throws at us + * but let's pick a nice big number to tell the tty + * layer that we have lots of free space + */ + return (4*1024); +} + + +static int garmin_chars_in_buffer (struct usb_serial_port *port) +{ + dbg("%s - port %d", __FUNCTION__, port->number); + + /* + * We can't really account for how much data we + * have sent out, but hasn't made it through to the + * device, so just tell the tty layer that everything + * is flushed. + */ + return 0; +} + + +static void garmin_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("%s - nonzero write bulk status received: %d", + __FUNCTION__, urb->status); + + schedule_work(&port->work); +} + + +static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs) +{ + struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct tty_struct *tty; + unsigned char *data = urb->transfer_buffer; + int result; + int state; + struct garmin_serial * pd; /* private data */ + + pd = ( struct garmin_serial* )usb_get_serial_data( port->serial ); + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (urb->status) { + dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); + return; + } + + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + + state = packetize( urb->transfer_buffer, + urb->actual_length, + pd->bulk_buffer, + pd->bulk_buffer_size, + &pd->bulk_buffer_count ); + + if( state == INVALID_PACKET ){ + pd->bulk_buffer_count = 0; + } else if( state == VALID_PACKET ){ + tty = port->tty; + if (tty) { + send_tty_data( tty, pd->bulk_buffer, pd->bulk_buffer_count ); + } + pd->bulk_buffer_count = 0; + } + bytes_in += urb->actual_length; + + /* Continue trying to always read */ + usb_fill_bulk_urb (port->read_urb, port->serial->dev, + usb_rcvbulkpipe(port->serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + garmin_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); + return; +} + +static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) +{ + struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct tty_struct *tty; + struct garmin_usb_header header; + int result; + int state; + struct garmin_serial * pd; /* private data */ + + pd = ( struct garmin_serial* )usb_get_serial_data( port->serial ); + + switch (urb->status) { + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", + __FUNCTION__, urb->status); + return; + default: + dbg("%s - nonzero urb status received: %d", + __FUNCTION__, urb->status); + goto exit; + } + + state = packetize( urb->transfer_buffer, + urb->actual_length, + pd->int_buffer, + pd->int_buffer_size, + &pd->int_buffer_count ); + + if( state == INVALID_PACKET ){ + dbg("Invalid packet interrupt in"); + pd->int_buffer_count = 0; + } else if( state == VALID_PACKET ){ + /* memcpy to avoid alignment issues */ + memcpy( &header, pd->int_buffer, HEADER_SIZE ); + switch( header.type ){ + case TRANSPORT_TYPE: + switch( header.id ){ + case BULK_DATA_READY_ID: + dbg("Bulk data ready"); + /* we are already reading bulk pipe, + so do nothing */ + break; + case SESSION_STARTED_ID: + /* received the session started reply to + the request sent in garmin_open() */ + dbg("Session started"); + pd->session_started = 1; + break; + default: + dbg("Unknown TRANSPORT_TYPE id %d", header.id ); + } /* switch( id ) */ + case APPLICATION_TYPE: + tty = port->tty; + if (tty) { + dbg("int send tty"); + send_tty_data( tty, pd->int_buffer, pd->int_buffer_count ); + } + break; + default: + dbg("Unknown Packet type %d", header.type ); + } /* switch( type ) */ + /* reset buffer count */ + pd->int_buffer_count = 0; + } + +exit: + result = usb_submit_urb (urb, GFP_ATOMIC); + if (result) + dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n", + __FUNCTION__, result); +} + + +static void garmin_throttle (struct usb_serial_port *port) +{ + //TODO: could set this so that it will drop packets instead of push them + //on the tty buffer, but for now, do nothing + dbg("%s - port %d", __FUNCTION__, port->number); +} + + +static void garmin_unthrottle (struct usb_serial_port *port) +{ + //TODO: could start accepting packets again, but since throttle does nothing, follow suit. + dbg("%s - port %d", __FUNCTION__, port->number); +} + + +static int garmin_probe (struct usb_serial *serial, const struct usb_device_id *id) +{ + int retval = 0; + return retval; +} + +static int garmin_calc_num_ports (struct usb_serial *serial) +{ + int num_ports = (int)(long)(usb_get_serial_data(serial)); + + if (num_ports) + usb_set_serial_data(serial, NULL); + + return num_ports; +} + + +static int garmin_attach (struct usb_serial *serial) +{ + dbg("%s", __FUNCTION__); + return 0; +} + +static void garmin_shutdown (struct usb_serial *serial) +{ + dbg("%s", __FUNCTION__); +} + +static int garmin_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) +{ + dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); + return -ENOIOCTLCMD; +} + + +/* This function is all nice and good, but we don't change anything based on it :) */ +static void garmin_set_termios (struct usb_serial_port *port, struct termios *old_termios) +{ + unsigned int cflag; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if ((!port->tty) || (!port->tty->termios)) { + dbg("%s - no tty structures", __FUNCTION__); + return; + } + + cflag = port->tty->termios->c_cflag; + /* check that they really want us to change something */ + if (old_termios) { + if ((cflag == old_termios->c_cflag) && + (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { + dbg("%s - nothing to change...", __FUNCTION__); + return; + } + } + + /* get the byte size */ + switch (cflag & CSIZE) { + case CS5: dbg("%s - data bits = 5", __FUNCTION__); break; + case CS6: dbg("%s - data bits = 6", __FUNCTION__); break; + case CS7: dbg("%s - data bits = 7", __FUNCTION__); break; + default: + case CS8: dbg("%s - data bits = 8", __FUNCTION__); break; + } + + /* determine the parity */ + if (cflag & PARENB) + if (cflag & PARODD) + dbg("%s - parity = odd", __FUNCTION__); + else + dbg("%s - parity = even", __FUNCTION__); + else + dbg("%s - parity = none", __FUNCTION__); + + /* figure out the stop bits requested */ + if (cflag & CSTOPB) + dbg("%s - stop bits = 2", __FUNCTION__); + else + dbg("%s - stop bits = 1", __FUNCTION__); + + + /* figure out the flow control settings */ + if (cflag & CRTSCTS) + dbg("%s - RTS/CTS is enabled", __FUNCTION__); + else + dbg("%s - RTS/CTS is disabled", __FUNCTION__); + + /* determine software flow control */ + if (I_IXOFF(port->tty)) + dbg("%s - XON/XOFF is enabled, XON = %2x, XOFF = %2x", + __FUNCTION__, START_CHAR(port->tty), STOP_CHAR(port->tty)); + else + dbg("%s - XON/XOFF is disabled", __FUNCTION__); + + /* get the baud rate wanted */ + dbg("%s - baud rate = %d", __FUNCTION__, tty_get_baud_rate(port->tty)); + + return; +} + + +/* + accumulate a full packet in buffer + return status of packet in buffer after adding data +*/ +static int packetize( char *data, int data_size, char *buffer, int buffer_size, int *buffer_count ) +{ + int new_size; + struct garmin_usb_header header; + + /* if new data will fit into buffer, copy it in */ + new_size = *buffer_count + data_size; + + if( new_size > buffer_size ){ + dbg("total data size %d bytes is bigger than buffer %d bytes", new_size, buffer_size ); + return INVALID_PACKET; + } + + memcpy( &buffer[ *buffer_count ], data, data_size); + + /* packet is large enough to have the header*/ + if( new_size >= HEADER_SIZE ){ + /* packet header sanity check */ + + /* copy the header to avoid any alignment issues */ + memcpy( &header, buffer, HEADER_SIZE ); + if( header.type != TRANSPORT_TYPE && header.type != APPLICATION_TYPE ){ + dbg("header unknown type %d", header.type ); + return INVALID_PACKET; + } + + if( header.size > (buffer_size - HEADER_SIZE ) ){ + dbg("header data size too big for buffer, %u data bytes", header.size ); + return INVALID_PACKET; + } + + if( header.res1 != 0 || + header.res2 != 0 || + header.res3 != 0 || + header.res4 != 0 ){ + dbg("header non-zero reserved area"); + return INVALID_PACKET; + } + + /* passed sanity check, buffer count is now new_size */ + *buffer_count = new_size; + + /* now check to see if all the data is received */ + /* new_size = size of data section of the packet received so far */ + new_size -= HEADER_SIZE; + if( new_size > header.size ){ + dbg("Too much data: size %d, header size %d", new_size, header.size); + return INVALID_PACKET; + } + else if( new_size == header.size ){ + return VALID_PACKET; + } + else{ + return ACCUMULATE_PACKET; + } + } + + /* not enough data for the full header, so just update + count and return accumulate */ + *buffer_count = new_size; + return ACCUMULATE_PACKET; + +} /* packetize() */ + + + +static int __init garmin_init (void) +{ + int retval; + + retval = usb_serial_register(&generic_device); + if (retval) + goto failed_serial_register; + retval = usb_register(&garmin_driver); + if (retval) + goto failed_register; + info(DRIVER_DESC " " DRIVER_VERSION); + + return 0; + +failed_serial_register: + usb_serial_deregister(&generic_device); +failed_register: + return retval; +} + + +static void __exit garmin_exit (void) +{ + usb_deregister (&garmin_driver); + usb_serial_deregister (&generic_device); +} + + +module_init(garmin_init); +module_exit(garmin_exit); + +MODULE_AUTHOR( DRIVER_AUTHOR ); +MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug enabled or not"); diff -u -r -N /usr/src/linux-2.6.9_default/drivers/usb/serial/garmin_usb_tty.h ./drivers/usb/serial/garmin_usb_tty.h --- /usr/src/linux-2.6.9_default/drivers/usb/serial/garmin_usb_tty.h 1970-01-01 00:00:00.000000000 +0000 +++ ./drivers/usb/serial/garmin_usb_tty.h 2004-11-08 00:17:25.678445536 +0000 @@ -0,0 +1,58 @@ +/* + * Garmin GPS USB to serial interface + * + * Copyright (C) 2004 Martin Boos <[EMAIL PROTECTED]> + * + * Based on: + * USB HandSpring garmin, Palm m50x, and Sony Clie driver + * (supports all of the Palm OS USB devices) + * + * Copyright (C) 1999 - 2004 + * Greg Kroah-Hartman ([EMAIL PROTECTED]) + * + * 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. + * + * See Documentation/usb/usb-serial.txt for more information on using this driver + */ + +#ifndef __LINUX_USB_SERIAL_GARMIN_H +#define __LINUX_USB_SERIAL_GARMIN_H + +#define GARMIN_VENDOR_ID 0x091E +#define GARMIN_GPSMAP_60_ID 0x0003 + +/* USB packet types */ +#define TRANSPORT_TYPE 0 +#define APPLICATION_TYPE 20 + +/* TRANSPORT_TYPE packet IDs */ +#define BULK_DATA_READY_ID 2 +#define START_SESSION_ID 5 +#define SESSION_STARTED_ID 6 + + +struct garmin_usb_header{ + __u8 type; + __u8 res1; + __u8 res2; + __u8 res3; + __u16 id; + __u16 res4; + __u32 size; +}; + +struct garmin_serial { + char * int_buffer; + int int_buffer_count; + int int_buffer_size; + char * bulk_buffer; + int bulk_buffer_count; + int bulk_buffer_size; + int session_started; +}; + +#endif + ------------------------------------------------------- This SF.Net email is sponsored by: Sybase ASE Linux Express Edition - download now for FREE LinuxWorld Reader's Choice Award Winner for best database on Linux. http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel