^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * A driver for Nokia Connectivity Card DTL-1 devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * it under the terms of the GNU General Public License version 2 as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * published by the Free Software Foundation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Software distributed under the License is distributed on an "AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * implied. See the License for the specific language governing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * rights and limitations under the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * The initial developer of the original code is David A. Hinds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/serial_reg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <pcmcia/cistpl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <pcmcia/ciscode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <pcmcia/ds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <pcmcia/cisreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <net/bluetooth/bluetooth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <net/bluetooth/hci_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* ======================== Module parameters ======================== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) MODULE_DESCRIPTION("Bluetooth driver for Nokia Connectivity Card DTL-1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* ======================== Local structures ======================== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct dtl1_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct pcmcia_device *p_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct hci_dev *hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) spinlock_t lock; /* For serializing operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned long flowmask; /* HCI flow mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int ri_latch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct sk_buff_head txq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned long tx_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned long rx_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned long rx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct sk_buff *rx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static int dtl1_config(struct pcmcia_device *link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Transmit states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define XMIT_SENDING 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define XMIT_WAKEUP 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define XMIT_WAITING 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Receiver States */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define RECV_WAIT_NSH 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define RECV_WAIT_DATA 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct nsh {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) u8 zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) } __packed; /* Nokia Specific Header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define NSHL 4 /* Nokia Specific Header Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* ======================== Interrupt handling ======================== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int actual = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Tx FIFO should be empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Fill FIFO with current frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) while ((fifo_size-- > 0) && (actual < len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Transmit next byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) outb(buf[actual], iobase + UART_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) actual++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return actual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void dtl1_write_wakeup(struct dtl1_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) BT_ERR("Unknown device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (test_bit(XMIT_WAITING, &(info->tx_state))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) set_bit(XMIT_WAKEUP, &(info->tx_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) set_bit(XMIT_WAKEUP, &(info->tx_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned int iobase = info->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) register struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) clear_bit(XMIT_WAKEUP, &(info->tx_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (!pcmcia_dev_present(info->p_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) skb = skb_dequeue(&(info->txq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Send frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) len = dtl1_write(iobase, 32, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (len == skb->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) set_bit(XMIT_WAITING, &(info->tx_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) skb_pull(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) skb_queue_head(&(info->txq), skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) info->hdev->stat.byte_tx += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) clear_bit(XMIT_SENDING, &(info->tx_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static void dtl1_control(struct dtl1_info *info, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u8 flowmask = *(u8 *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) printk(KERN_INFO "Bluetooth: Nokia control data =");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) for (i = 0; i < skb->len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) printk(" %02x", skb->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* transition to active state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) clear_bit(XMIT_WAITING, &(info->tx_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dtl1_write_wakeup(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) info->flowmask = flowmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static void dtl1_receive(struct dtl1_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned int iobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct nsh *nsh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int boguscount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) BT_ERR("Unknown device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) iobase = info->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) info->hdev->stat.byte_rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* Allocate packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (info->rx_skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!info->rx_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) BT_ERR("Can't allocate mem for new packet");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) info->rx_state = RECV_WAIT_NSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) info->rx_count = NSHL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) skb_put_u8(info->rx_skb, inb(iobase + UART_RX));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) nsh = (struct nsh *)info->rx_skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) info->rx_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (info->rx_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) switch (info->rx_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case RECV_WAIT_NSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) info->rx_state = RECV_WAIT_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) info->rx_count = nsh->len + (nsh->len & 0x0001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case RECV_WAIT_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) hci_skb_pkt_type(info->rx_skb) = nsh->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* remove PAD byte if it exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (nsh->len & 0x0001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) info->rx_skb->tail--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) info->rx_skb->len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* remove NSH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) skb_pull(info->rx_skb, NSHL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) switch (hci_skb_pkt_type(info->rx_skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case 0x80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* control data for the Nokia Card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) dtl1_control(info, info->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case 0x82:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case 0x83:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case 0x84:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* send frame to the HCI layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) hci_skb_pkt_type(info->rx_skb) &= 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) hci_recv_frame(info->hdev, info->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* unknown packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) BT_ERR("Unknown HCI packet with type 0x%02x received",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) hci_skb_pkt_type(info->rx_skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) kfree_skb(info->rx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) info->rx_state = RECV_WAIT_NSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) info->rx_count = NSHL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) info->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* Make sure we don't stay here too long */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (boguscount++ > 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) } while (inb(iobase + UART_LSR) & UART_LSR_DR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct dtl1_info *info = dev_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned int iobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) unsigned char msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int boguscount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int iir, lsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) irqreturn_t r = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (!info || !info->hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* our irq handler is shared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) iobase = info->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) spin_lock(&(info->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) iir = inb(iobase + UART_IIR) & UART_IIR_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) while (iir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) r = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Clear interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) lsr = inb(iobase + UART_LSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) switch (iir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) case UART_IIR_RLSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) BT_ERR("RLSI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case UART_IIR_RDI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* Receive interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) dtl1_receive(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) case UART_IIR_THRI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (lsr & UART_LSR_THRE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* Transmitter ready for data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) dtl1_write_wakeup(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) BT_ERR("Unhandled IIR=%#x", iir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* Make sure we don't stay here too long */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (boguscount++ > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) iir = inb(iobase + UART_IIR) & UART_IIR_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) msr = inb(iobase + UART_MSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (info->ri_latch ^ (msr & UART_MSR_RI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) info->ri_latch = msr & UART_MSR_RI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) clear_bit(XMIT_WAITING, &(info->tx_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dtl1_write_wakeup(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) r = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) spin_unlock(&(info->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* ======================== HCI interface ======================== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int dtl1_hci_open(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int dtl1_hci_flush(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct dtl1_info *info = hci_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* Drop TX queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) skb_queue_purge(&(info->txq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static int dtl1_hci_close(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) dtl1_hci_flush(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct dtl1_info *info = hci_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct sk_buff *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct nsh nsh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) switch (hci_skb_pkt_type(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) case HCI_COMMAND_PKT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) hdev->stat.cmd_tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) nsh.type = 0x81;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) case HCI_ACLDATA_PKT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) hdev->stat.acl_tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) nsh.type = 0x82;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) case HCI_SCODATA_PKT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) hdev->stat.sco_tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) nsh.type = 0x83;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) nsh.zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) nsh.len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) s = bt_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) skb_reserve(s, NSHL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) skb_copy_from_linear_data(skb, skb_put(s, skb->len), skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (skb->len & 0x0001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) skb_put_u8(s, 0); /* PAD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* Prepend skb with Nokia frame header and queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) memcpy(skb_push(s, NSHL), &nsh, NSHL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) skb_queue_tail(&(info->txq), s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) dtl1_write_wakeup(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* ======================== Card services HCI interaction ======================== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static int dtl1_open(struct dtl1_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) unsigned int iobase = info->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct hci_dev *hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) spin_lock_init(&(info->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) skb_queue_head_init(&(info->txq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) info->rx_state = RECV_WAIT_NSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) info->rx_count = NSHL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) info->rx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) set_bit(XMIT_WAITING, &(info->tx_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* Initialize HCI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) hdev = hci_alloc_dev();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (!hdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) BT_ERR("Can't allocate HCI device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) info->hdev = hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) hdev->bus = HCI_PCCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) hci_set_drvdata(hdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) hdev->open = dtl1_hci_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) hdev->close = dtl1_hci_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) hdev->flush = dtl1_hci_flush;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) hdev->send = dtl1_hci_send_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) spin_lock_irqsave(&(info->lock), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* Reset UART */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) outb(0, iobase + UART_MCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* Turn off interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) outb(0, iobase + UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* Initialize UART */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) info->ri_latch = inb(info->p_dev->resource[0]->start + UART_MSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) & UART_MSR_RI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* Turn on interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) spin_unlock_irqrestore(&(info->lock), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* Timeout before it is safe to send the first HCI packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) msleep(2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* Register HCI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (hci_register_dev(hdev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) BT_ERR("Can't register HCI device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) info->hdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) hci_free_dev(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static int dtl1_close(struct dtl1_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned int iobase = info->p_dev->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct hci_dev *hdev = info->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (!hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) dtl1_hci_close(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) spin_lock_irqsave(&(info->lock), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* Reset UART */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) outb(0, iobase + UART_MCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* Turn off interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) outb(0, iobase + UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) spin_unlock_irqrestore(&(info->lock), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) hci_unregister_dev(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) hci_free_dev(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int dtl1_probe(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct dtl1_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Create new info device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) info->p_dev = link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) link->priv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return dtl1_config(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static void dtl1_detach(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct dtl1_info *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) dtl1_close(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) pcmcia_disable_device(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if ((p_dev->resource[1]->end) || (p_dev->resource[1]->end < 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return pcmcia_request_io(p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static int dtl1_config(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct dtl1_info *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* Look for a generic full-sized window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) link->resource[0]->end = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) ret = pcmcia_loop_config(link, dtl1_confcheck, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ret = pcmcia_request_irq(link, dtl1_interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ret = pcmcia_enable_device(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) ret = dtl1_open(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) dtl1_detach(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static const struct pcmcia_device_id dtl1_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) PCMCIA_DEVICE_NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static struct pcmcia_driver dtl1_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) .name = "dtl1_cs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .probe = dtl1_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) .remove = dtl1_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) .id_table = dtl1_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) module_pcmcia_driver(dtl1_driver);