Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);