/*
* bluetty.c Version 0.13
*
* Copyright (C) 2000, 2001 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2000 Mark Douglas Corner <mcorner@umich.edu>
*
* USB Bluetooth TTY driver, based on the Bluetooth Spec version 1.0B
*
* (2001/11/30) Version 0.13 gkh
* - added locking patch from Masoodur Rahman <rmasoodu@in.ibm.com>
* - removed active variable, as open_count will do.
*
* (2001/07/09) Version 0.12 gkh
* - removed in_interrupt() call, as it doesn't make sense to do
* that anymore.
*
* (2001/06/05) Version 0.11 gkh
* - Fixed problem with read urb status saying that we have shutdown,
* and that we shouldn't resubmit the urb. Patch from unknown.
*
* (2001/05/28) Version 0.10 gkh
* - Fixed problem with using data from userspace in the bluetooth_write
* function as found by the CHECKER project.
* - Added a buffer to the write_urb_pool which reduces the number of
* buffers being created and destroyed for ever write. Also cleans
* up the logic a bit.
* - Added a buffer to the control_urb_pool which fixes a memory leak
* when the device is removed from the system.
*
* (2001/05/28) Version 0.9 gkh
* Fixed problem with bluetooth==NULL for bluetooth_read_bulk_callback
* which was found by both the CHECKER project and Mikko Rahkonen.
*
* (08/04/2001) gb
* Identify version on module load.
*
* (2001/03/10) Version 0.8 gkh
* Fixed problem with not unlinking interrupt urb on device close
* and resubmitting the read urb on error with bluetooth struct.
* Thanks to Narayan Mohanram <narayan@RovingNetworks.com> for the
* fixes.
*
* (11/29/2000) Version 0.7 gkh
* Fixed problem with overrunning the tty flip buffer.
* Removed unneeded NULL pointer initialization.
*
* (10/05/2000) Version 0.6 gkh
* Fixed bug with urb->dev not being set properly, now that the usb
* core needs it.
* Got a real major id number and name.
*
* (08/06/2000) Version 0.5 gkh
* Fixed problem of not resubmitting the bulk read urb if there is
* an error in the callback. Ericsson devices seem to need this.
*
* (07/11/2000) Version 0.4 gkh
* Fixed bug in disconnect for when we call tty_hangup
* Fixed bug in bluetooth_ctrl_msg where the bluetooth struct was not
* getting attached to the control urb properly.
* Fixed bug in bluetooth_write where we pay attention to the result
* of bluetooth_ctrl_msg.
*
* (08/03/2000) Version 0.3 gkh mdc
* Merged in Mark's changes to make the driver play nice with the Axis
* stack.
* Made the write bulk use an urb pool to enable larger transfers with
* fewer calls to the driver.
* Fixed off by one bug in acl pkt receive
* Made packet counters specific to each bluetooth device
* Added checks for zero length callbacks
* Added buffers for int and bulk packets. Had to do this otherwise
* packet types could intermingle.
* Made a control urb pool for the control messages.
*
* (07/11/2000) Version 0.2 gkh
* Fixed a small bug found by Nils Faerber in the usb_bluetooth_probe
* function.
*
* (07/09/2000) Version 0.1 gkh
* Initial release. Has support for sending ACL data (which is really just
* a HCI frame.) Raw HCI commands and HCI events are not supported.
* A ioctl will probably be needed for the HCI commands and events in the
* future. All isoch endpoints are ignored at this time also.
* This driver should work for all currently shipping USB Bluetooth
* devices at this time :)
*
*/
/*
* 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/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 <asm/uaccess.h>
#define DEBUG
#include <linux/usb.h>
/*
* Version Information
*/
#define DRIVER_VERSION "v0.13"
#define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner"
#define DRIVER_DESC "USB Bluetooth tty driver"
/* define this if you have hardware that is not good */
/*#define BTBUGGYHARDWARE */
/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
#define WIRELESS_CLASS_CODE 0xe0
#define RF_SUBCLASS_CODE 0x01
#define BLUETOOTH_PROGRAMMING_PROTOCOL_CODE 0x01
#define BLUETOOTH_TTY_MAJOR 216 /* real device node major id */
#define BLUETOOTH_TTY_MINORS 256 /* whole lotta bluetooth devices */
#define USB_BLUETOOTH_MAGIC 0x6d02 /* magic number for bluetooth struct */
#define BLUETOOTH_CONTROL_REQUEST_TYPE 0x20
/* Bluetooth packet types */
#define CMD_PKT 0x01
#define ACL_PKT 0x02
#define SCO_PKT 0x03
#define EVENT_PKT 0x04
#define ERROR_PKT 0x05
#define NEG_PKT 0x06
/* Message sizes */
#define MAX_EVENT_SIZE 0xFF
#define EVENT_HDR_SIZE 3 /* 2 for the header + 1 for the type indicator */
#define EVENT_BUFFER_SIZE (MAX_EVENT_SIZE + EVENT_HDR_SIZE)
#define MAX_ACL_SIZE 0xFFFF
#define ACL_HDR_SIZE 5 /* 4 for the header + 1 for the type indicator */
#define ACL_BUFFER_SIZE (MAX_ACL_SIZE + ACL_HDR_SIZE)
/* parity check flag */
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
#define CHAR2INT16(c1,c0) (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff))
#define NUM_BULK_URBS 24
#define NUM_CONTROL_URBS 16
struct usb_bluetooth {
int magic;
struct usb_device * dev;
struct tty_driver * tty_driver; /* the tty_driver for this device */
struct tty_struct * tty; /* the corresponding tty for this port */
unsigned char minor; /* the starting minor number for this device */
int throttle; /* throttled by tty layer */
int open_count;
__u8 control_out_bInterfaceNum;
struct urb * control_urb_pool[NUM_CONTROL_URBS];
struct usb_ctrlrequest dr[NUM_CONTROL_URBS];
unsigned