summaryrefslogtreecommitdiff
path: root/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch
diff options
context:
space:
mode:
authorChris Larson <clarson@kergoth.com>2004-12-09 09:47:41 +0000
committerChris Larson <clarson@kergoth.com>2004-12-09 09:47:41 +0000
commit2c5b8ec6d95cf68650265941530e5ce38c8dd6d9 (patch)
treebf879bea7ef8517ba8c3d1286ef300401d3d484c /linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch
parent101e2f1623def0a355d20aacb8bd93810703e834 (diff)
Merge oe-devel@oe-devel.bkbits.net:openembedded
into hyperion.kergoth.com:/home/kergoth/code/openembedded 2004/12/09 03:39:39-06:00 kergoth.com!kergoth Break people's builds again.. this time moving the packages into a packages/ subdir to clean things up a bit. BKrev: 41b81f3dvlp3rU7_8MUXLcI8LDdDoA
Diffstat (limited to 'linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch')
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch1174
1 files changed, 0 insertions, 1174 deletions
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch
deleted file mode 100644
index c29f0d02f2..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch
+++ /dev/null
@@ -1,1174 +0,0 @@
-diff -Nur linux-orig/drivers/bluetooth/bt950_cs.c linux/drivers/bluetooth/bt950_cs.c
---- linux-orig/drivers/bluetooth/bt950_cs.c 1970-01-01 03:00:00.000000000 +0300
-+++ linux/drivers/bluetooth/bt950_cs.c 2004-02-04 09:55:04.000000000 +0300
-@@ -0,0 +1,1133 @@
-+/*
-+ *
-+ * Driver for Bluetooth cards with OXCF950 UART interface
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ * Albert Rybalkin <albertr@iral.com>
-+ *
-+ *
-+ * 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;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+
-+#ifdef CONFIG_MODVERSIONS
-+#ifndef MODVERSIONS
-+#define MODVERSIONS
-+#endif
-+#include <linux/modversions.h>
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+#include <linux/delay.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 460800
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0x86bc;
-+static int irq_list[4] = { -1 };
-+static long baud_rate = DEFAULT_BAUD_RATE;
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+MODULE_PARM(baud_rate, "l");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Albert Rybalkin <albertr@iral.com>");
-+MODULE_DESCRIPTION("BlueZ driver for Bluetooth cards with OXCF950 UART interface");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bt950_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} bt950_info_t;
-+
-+
-+static void bt950_config(dev_link_t *link);
-+static void bt950_release(u_long arg);
-+static int bt950_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bt950_cs";
-+
-+static dev_link_t *bt950_attach(void);
-+static void bt950_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+/* Special packet types */
-+#define PKT_BAUD_RATE_57600 0x80
-+#define PKT_BAUD_RATE_115200 0x81
-+#define PKT_BAUD_RATE_230400 0x82
-+#define PKT_BAUD_RATE_460800 0x83
-+
-+/* 950-specific stuff */
-+#define MAX_WAIT 0xFFFF
-+#define FIFO_SIZE 128
-+
-+#define TR_TX_INT 0x10 /* TTL: TX interrupt trigger level (0-127) */
-+#define TR_RX_INT 0x40 /* RTL: RX interrupt trigger level (1-127) */
-+#define TR_CTL_LO 0x08 /* FCL: auto flow control LOWER trigger level (0-127) */
-+#define TR_CTL_HI 0x60 /* FCH: auto flow control HIGH trigger level (1-127) */
-+
-+/* 950-specific registers and values we use. It should
-+ * eventually go to include/linux/serial_reg.h */
-+#define UART_IER_CTS 0x80 /* enable CTS interrupt */
-+#define UART_IER_RTS 0x40 /* enable RTS interrupt */
-+#define UART_IER_SLP 0x10 /* enable sleep mode */
-+#define UART_LCR_650 0xBF /* enable 650-compatible registers access */
-+#define UART_LSR_DE 0x80 /* data error */
-+#define UART_LSR_ERR (UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI|UART_LSR_DE)
-+#define UART_IIR_RXTOUT 0x0C /* RX timeout interrupt */
-+#define UART_IIR_CTSRTS 0x20 /* CTS or RTS change interrupt */
-+#define UART_IIR_RTS 0x40
-+#define UART_IIR_CTS 0x80
-+#define UART_IIR_MASK 0x3E /* interrupt mask */
-+#define UART_SRT 0x0D /* soft reset register */
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bt950_write(unsigned int iobase, int fifo_size, const unsigned char *buf, int len)
-+{
-+ int i, actual = 0;
-+
-+ /* Activate DTR and RTS */
-+ outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2, iobase + UART_MCR);
-+
-+ /* Wait for CTS flow control */
-+ for (i = MAX_WAIT; i; i--)
-+ if (inb(iobase + UART_MSR) & UART_MSR_CTS)
-+ break;
-+
-+ if (!i) {
-+ printk(KERN_WARNING "bt950_cs: Timeout waiting for CTS on write.\n");
-+ return 0;
-+ }
-+
-+ /* The TX FIFO should be empty */
-+ for (i = MAX_WAIT; i; i--)
-+ if (inb(iobase + UART_LSR) & UART_LSR_THRE)
-+ break;
-+
-+ if (!i) {
-+ printk(KERN_WARNING "bt950_cs: Timeout waiting for empty TX FIFO on write.\n");
-+ return 0;
-+ }
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void bt950_write_wakeup(bt950_info_t *info)
-+{
-+ unsigned char lcr;
-+ unsigned int divisor;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt950_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ if (skb->pkt_type & 0x80) {
-+ /* Disable RTS */
-+ outb((inb(iobase + UART_MCR) & ~UART_MCR_RTS), iobase + UART_MCR);
-+ }
-+
-+ /* Send frame */
-+ len = bt950_write(iobase, FIFO_SIZE, skb->data, skb->len);
-+
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (skb->pkt_type & 0x80) {
-+
-+ wait_queue_head_t wait;
-+
-+ switch (skb->pkt_type) {
-+
-+ case PKT_BAUD_RATE_460800:
-+ divisor = 1;
-+ break;
-+
-+ case PKT_BAUD_RATE_230400:
-+ divisor = 2;
-+ break;
-+
-+ case PKT_BAUD_RATE_115200:
-+ divisor = 4;
-+ break;
-+
-+ case PKT_BAUD_RATE_57600:
-+ /* Fall through... */
-+
-+ default:
-+ divisor = 8;
-+ break;
-+ }
-+
-+ /* Wait until the command reaches the baseband */
-+ init_waitqueue_head(&wait);
-+ interruptible_sleep_on_timeout(&wait, HZ / 10);
-+
-+ /* Set baud on baseband */
-+ /* Enable divisor latch access */
-+ lcr = inb(iobase + UART_LCR) & 0x3F;
-+ outb(lcr | UART_LCR_DLAB, iobase + UART_LCR);
-+
-+ /* Setup divisor latch */
-+ outb(divisor & 0x00FF, iobase + UART_DLL); /* divisor latch LOW byte */
-+ outb((divisor & 0xFF00) >> 8, iobase + UART_DLM); /* divisor latch HI byte */
-+
-+ /* Disable divisor latch access */
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Enable RTS */
-+ outb((inb(iobase + UART_MCR) | UART_MCR_RTS), iobase + UART_MCR);
-+
-+ /* Wait before the next HCI packet can be send */
-+ interruptible_sleep_on_timeout(&wait, HZ);
-+
-+ }
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static inline void bt950_receive(bt950_info_t *info)
-+{
-+ unsigned int iobase;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_ERR "bt950_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ /* Fixme: BUG? */
-+ inb(iobase + UART_MCR);
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_ERR "bt950_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + UART_RX);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "bt950_cs: Unknown HCI packet with type 0x%02X received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here too long */
-+ if (boguscount++ > 16)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+static void bt950_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bt950_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_ERR "bt950_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR);
-+
-+ while (!(iir & UART_IIR_NO_INT)) {
-+
-+ switch (iir & UART_IIR_ID) {
-+ case UART_IIR_RLSI:
-+ /* Clear RLSI interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+ printk(KERN_NOTICE "bt950_cs: RLSI interrupt, LSR=%#x\n", lsr);
-+ /* Fixme: we need to process errors ... */
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ bt950_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ /* Transmitter ready for data */
-+ bt950_write_wakeup(info);
-+ break;
-+ default:
-+ printk(KERN_NOTICE "bt950_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here too long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR);
-+
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+/* ======================== Device specific HCI commands ======================== */
-+
-+
-+static int bt950_hci_set_baud_rate(struct hci_dev *hdev, int baud)
-+{
-+ bt950_info_t *info = (bt950_info_t *)(hdev->driver_data);
-+ struct sk_buff *skb;
-+
-+ /* Ericsson baud rate command */
-+ unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
-+
-+ if (!(skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bt950_cs: Can't allocate mem for new packet.\n");
-+ return -1;
-+ }
-+
-+ switch (baud) {
-+ case 460800:
-+ cmd[4] = 0x00;
-+ skb->pkt_type = PKT_BAUD_RATE_460800;
-+ break;
-+ case 230400:
-+ cmd[4] = 0x01;
-+ skb->pkt_type = PKT_BAUD_RATE_230400;
-+ break;
-+ case 115200:
-+ cmd[4] = 0x02;
-+ skb->pkt_type = PKT_BAUD_RATE_115200;
-+ break;
-+ case 57600:
-+ /* Fall through... */
-+ default:
-+ baud = 57600;
-+ cmd[4] = 0x03;
-+ skb->pkt_type = PKT_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
-+
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ printk(KERN_WARNING "bt950_cs: setting baud rate: %d.\n", baud);
-+
-+ bt950_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bt950_hci_flush(struct hci_dev *hdev)
-+{
-+ bt950_info_t *info = (bt950_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bt950_hci_open(struct hci_dev *hdev)
-+{
-+ bt950_hci_set_baud_rate(hdev, baud_rate);
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int bt950_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bt950_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int bt950_hci_send_frame(struct sk_buff *skb)
-+{
-+ bt950_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_ERR "bt950_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bt950_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bt950_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void bt950_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bt950_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+static int bt950_setup_uart(bt950_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ unsigned char lcr, ier = UART_IER_RDI | UART_IER_RLSI | UART_IER_SLP;
-+ unsigned int divisor = 8; /* Fixme: divisor == 0x0c ??? */
-+ unsigned char id1, id2, id3, rev;
-+ register int i;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Disable interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Activate RTS and OUT2 */
-+ /* Fixme: is OUT2 used to enable interrupts? */
-+ outb(UART_MCR_RTS | UART_MCR_OUT2, iobase + UART_MCR);
-+
-+ /* Setup the FIFO's */
-+ outb(0, iobase + UART_FCR);
-+ inb(iobase + UART_RX);
-+ outb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
-+ UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_14, iobase + UART_FCR);
-+
-+ /* Disable divisor latch access */
-+ lcr = inb(iobase + UART_LCR) & 0x3F; /* mask out UART_LCR_DLAB and UART_LCR_SBC */
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Read up to 4 bytes from RX FIFO */
-+ for (i = 0; i < 4; i++) {
-+ inb(iobase + UART_RX);
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_DR))
-+ break;
-+ }
-+
-+ /* Wait if CTS/DSR/DCD changing */
-+ for (i = 1; i < 0x3E8; i++) {
-+ if (!(inb(iobase + UART_MSR) & UART_MSR_ANY_DELTA))
-+ break;
-+ }
-+
-+ /* Enable divisor latch access */
-+ outb(lcr | UART_LCR_DLAB, iobase + UART_LCR);
-+
-+ /* Setup divisor latch */
-+ outb(divisor & 0x00FF, iobase + UART_DLL); /* divisor latch LOW byte */
-+ outb((divisor & 0xFF00) >> 8, iobase + UART_DLM); /* divisor latch HIGH byte */
-+
-+ /* Disable divisor latch access */
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Setup interrupts, enable sleep mode */
-+ outb(ier, iobase + UART_IER); /* we don't want to handle TX interrupts */
-+
-+ /* Skip pending interrupts */
-+ for (i = 0; i < 4; i++) {
-+ if (inb(iobase + UART_IIR) & UART_IIR_NO_INT)
-+ break;
-+ }
-+
-+ /* 8N1 */
-+ lcr = UART_LCR_WLEN8;
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Setup CTS/RTS flow control and 950 enhanced mode */
-+ outb(UART_LCR_650, iobase + UART_LCR);
-+ outb(UART_EFR_CTS | UART_EFR_RTS | UART_EFR_ECB,
-+ iobase + UART_EFR);
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Read core id and revision */
-+ outb(UART_ACR, iobase + UART_EMSR);
-+ outb(UART_ACR_ICRRD, iobase + UART_LSR); /* enable ICR read access, we don't need to save the old value of ACR */
-+
-+ outb(UART_ID1, iobase + UART_EMSR);
-+ id1 = inb(iobase + UART_LSR);
-+
-+ outb(UART_ID2, iobase + UART_EMSR);
-+ id2 = inb(iobase + UART_LSR);
-+
-+ outb(UART_ID3, iobase + UART_EMSR);
-+ id3 = inb(iobase + UART_LSR);
-+
-+ outb(UART_REV, iobase + UART_EMSR);
-+ rev = inb(iobase + UART_LSR);
-+
-+ if (id1 != 0x16 || id2 != 0xC9 || id3 != 0x50) {
-+ printk(KERN_ERR "bt950_cs: Unknown UART core %02X%02X%02X found.\n", id1, id2, id3);
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+ return -ENODEV;
-+ }
-+
-+
-+ /* Init ICR registers */
-+ outb(UART_TTL, iobase + UART_EMSR);
-+ outb(TR_TX_INT, iobase + UART_LSR); /* TX interrupt trigger level (0-127) */
-+
-+ outb(UART_RTL, iobase + UART_EMSR);
-+ outb(TR_RX_INT, iobase + UART_LSR); /* RX interrupt trigger level (1-127) */
-+
-+ outb(UART_FCL, iobase + UART_EMSR);
-+ outb(TR_CTL_LO, iobase + UART_LSR); /* auto flow control LOWER trigger level (0-127) */
-+
-+ outb(UART_FCH, iobase + UART_EMSR);
-+ outb(TR_CTL_HI, iobase + UART_LSR); /* auto flow control HIGH trigger level (1-127) */
-+
-+ outb(UART_ACR, iobase + UART_EMSR);
-+ outb(UART_ACR_TLENB, iobase + UART_LSR); /* disable ICR read access, enable trigger levels */
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ return 0;
-+}
-+
-+
-+static void bt950_stop_uart(bt950_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Disable interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Set RTS and OUT2 low */
-+ outb(0, iobase + UART_MCR);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+static int bt950_open(bt950_info_t *info)
-+{
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ /* Setup hardware */
-+ if ((err = bt950_setup_uart(info)) < 0)
-+ return err;
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bt950_hci_open;
-+ hdev->close = bt950_hci_close;
-+ hdev->flush = bt950_hci_flush;
-+ hdev->send = bt950_hci_send_frame;
-+ hdev->destruct = bt950_hci_destruct;
-+ hdev->ioctl = bt950_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_ERR "bt950_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int bt950_close(bt950_info_t *info)
-+{
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ bt950_hci_close(hdev);
-+
-+ /* Stop hardware */
-+ bt950_stop_uart(info);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_ERR "bt950_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+static dev_link_t *bt950_attach(void)
-+{
-+ bt950_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bt950_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bt950_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+ link->conf.Present =
-+ PRESENT_OPTION | PRESENT_STATUS | PRESENT_PIN_REPLACE |
-+ PRESENT_COPY;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bt950_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bt950_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+static void bt950_detach(dev_link_t *link)
-+{
-+ bt950_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ bt950_release((u_long) link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+static void bt950_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[4] = { 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ bt950_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *) buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
-+ && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_ERR "bt950_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bt950_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bt950_release((u_long)link);
-+ link->state &= ~DEV_CONFIG_PENDING;
-+}
-+
-+
-+static void bt950_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *) arg;
-+ bt950_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bt950_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+static int bt950_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bt950_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bt950_close(info);
-+ link->state |= DEV_RELEASE_PENDING;
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bt950_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG) {
-+ bt950_stop_uart(info);
-+ CardServices(ReleaseConfiguration, link->handle);
-+ }
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (link->state & DEV_CONFIG) {
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ bt950_setup_uart(info);
-+ }
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bt950_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bt950_cs: Card Services release does not match!\n");
-+// return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bt950_attach, &bt950_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bt950_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bt950_detach(dev_list);
-+}
-+
-+
-+module_init(init_bt950_cs);
-+module_exit(exit_bt950_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -Nur linux-orig/drivers/bluetooth/Config.in linux/drivers/bluetooth/Config.in
---- linux-orig/drivers/bluetooth/Config.in 2004-02-16 08:45:33.000000000 +0300
-+++ linux/drivers/bluetooth/Config.in 2004-02-16 08:50:36.000000000 +0300
-@@ -21,7 +21,7 @@
-
- dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
-
--dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
-+# dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
-
- dep_tristate 'HCI BlueCard (PC Card) driver' CONFIG_BLUEZ_HCIBLUECARD $CONFIG_PCMCIA $CONFIG_BLUEZ
-
-@@ -29,5 +29,7 @@
-
- dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-
-+dep_tristate 'HCI BT950 (BT950 device) driver' CONFIG_BLUEZ_BT950 $CONFIG_BLUEZ
-+
- endmenu
-
-diff -Nur linux-orig/drivers/bluetooth/Makefile linux/drivers/bluetooth/Makefile
---- linux-orig/drivers/bluetooth/Makefile 2004-02-16 08:45:33.000000000 +0300
-+++ linux/drivers/bluetooth/Makefile 2004-02-16 08:50:47.000000000 +0300
-@@ -17,10 +17,12 @@
- obj-$(CONFIG_BLUEZ_HCIBFUSB) += bfusb.o
-
- obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o
--obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
-+# obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
- obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o
- obj-$(CONFIG_BLUEZ_HCIBTUART) += btuart_cs.o
-
-+obj-$(CONFIG_BLUEZ_BT950) += bt950_cs.o
-+
- include $(TOPDIR)/Rules.make
-
- hci_uart.o: $(uart-y)