MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / bluetooth / btuart_cs.c
blobb44fa7dd38c350b07f533a2d3b549e4af2eca9d3
1 /*
3 * Driver for Bluetooth PCMCIA cards with HCI UART interface
5 * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation;
12 * Software distributed under the License is distributed on an "AS
13 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * rights and limitations under the License.
17 * The initial developer of the original code is David A. Hinds
18 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
23 #include <linux/config.h>
24 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/init.h>
28 #include <linux/slab.h>
29 #include <linux/types.h>
30 #include <linux/sched.h>
31 #include <linux/delay.h>
32 #include <linux/errno.h>
33 #include <linux/ptrace.h>
34 #include <linux/ioport.h>
35 #include <linux/spinlock.h>
37 #include <linux/skbuff.h>
38 #include <linux/string.h>
39 #include <linux/serial.h>
40 #include <linux/serial_reg.h>
41 #include <asm/system.h>
42 #include <asm/bitops.h>
43 #include <asm/io.h>
45 #include <pcmcia/version.h>
46 #include <pcmcia/cs_types.h>
47 #include <pcmcia/cs.h>
48 #include <pcmcia/cistpl.h>
49 #include <pcmcia/ciscode.h>
50 #include <pcmcia/ds.h>
51 #include <pcmcia/cisreg.h>
53 #include <net/bluetooth/bluetooth.h>
54 #include <net/bluetooth/hci_core.h>
58 /* ======================== Module parameters ======================== */
61 /* Bit map of interrupts to choose from */
62 static u_int irq_mask = 0xffff;
63 static int irq_list[4] = { -1 };
65 MODULE_PARM(irq_mask, "i");
66 MODULE_PARM(irq_list, "1-4i");
68 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
69 MODULE_DESCRIPTION("Bluetooth driver for Bluetooth PCMCIA cards with HCI UART interface");
70 MODULE_LICENSE("GPL");
74 /* ======================== Local structures ======================== */
77 typedef struct btuart_info_t {
78 dev_link_t link;
79 dev_node_t node;
81 struct hci_dev *hdev;
83 spinlock_t lock; /* For serializing operations */
85 struct sk_buff_head txq;
86 unsigned long tx_state;
88 unsigned long rx_state;
89 unsigned long rx_count;
90 struct sk_buff *rx_skb;
91 } btuart_info_t;
94 void btuart_config(dev_link_t *link);
95 void btuart_release(dev_link_t *link);
96 int btuart_event(event_t event, int priority, event_callback_args_t *args);
98 static dev_info_t dev_info = "btuart_cs";
100 dev_link_t *btuart_attach(void);
101 void btuart_detach(dev_link_t *);
103 static dev_link_t *dev_list = NULL;
106 /* Maximum baud rate */
107 #define SPEED_MAX 115200
109 /* Default baud rate: 57600, 115200, 230400 or 460800 */
110 #define DEFAULT_BAUD_RATE 115200
113 /* Transmit states */
114 #define XMIT_SENDING 1
115 #define XMIT_WAKEUP 2
116 #define XMIT_WAITING 8
118 /* Receiver states */
119 #define RECV_WAIT_PACKET_TYPE 0
120 #define RECV_WAIT_EVENT_HEADER 1
121 #define RECV_WAIT_ACL_HEADER 2
122 #define RECV_WAIT_SCO_HEADER 3
123 #define RECV_WAIT_DATA 4
127 /* ======================== Interrupt handling ======================== */
130 static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
132 int actual = 0;
134 /* Tx FIFO should be empty */
135 if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
136 return 0;
138 /* Fill FIFO with current frame */
139 while ((fifo_size-- > 0) && (actual < len)) {
140 /* Transmit next byte */
141 outb(buf[actual], iobase + UART_TX);
142 actual++;
145 return actual;
149 static void btuart_write_wakeup(btuart_info_t *info)
151 if (!info) {
152 BT_ERR("Unknown device");
153 return;
156 if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
157 set_bit(XMIT_WAKEUP, &(info->tx_state));
158 return;
161 do {
162 register unsigned int iobase = info->link.io.BasePort1;
163 register struct sk_buff *skb;
164 register int len;
166 clear_bit(XMIT_WAKEUP, &(info->tx_state));
168 if (!(info->link.state & DEV_PRESENT))
169 return;
171 if (!(skb = skb_dequeue(&(info->txq))))
172 break;
174 /* Send frame */
175 len = btuart_write(iobase, 16, skb->data, skb->len);
176 set_bit(XMIT_WAKEUP, &(info->tx_state));
178 if (len == skb->len) {
179 kfree_skb(skb);
180 } else {
181 skb_pull(skb, len);
182 skb_queue_head(&(info->txq), skb);
185 info->hdev->stat.byte_tx += len;
187 } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
189 clear_bit(XMIT_SENDING, &(info->tx_state));
193 static void btuart_receive(btuart_info_t *info)
195 unsigned int iobase;
196 int boguscount = 0;
198 if (!info) {
199 BT_ERR("Unknown device");
200 return;
203 iobase = info->link.io.BasePort1;
205 do {
206 info->hdev->stat.byte_rx++;
208 /* Allocate packet */
209 if (info->rx_skb == NULL) {
210 info->rx_state = RECV_WAIT_PACKET_TYPE;
211 info->rx_count = 0;
212 if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
213 BT_ERR("Can't allocate mem for new packet");
214 return;
218 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
220 info->rx_skb->dev = (void *) info->hdev;
221 info->rx_skb->pkt_type = inb(iobase + UART_RX);
223 switch (info->rx_skb->pkt_type) {
225 case HCI_EVENT_PKT:
226 info->rx_state = RECV_WAIT_EVENT_HEADER;
227 info->rx_count = HCI_EVENT_HDR_SIZE;
228 break;
230 case HCI_ACLDATA_PKT:
231 info->rx_state = RECV_WAIT_ACL_HEADER;
232 info->rx_count = HCI_ACL_HDR_SIZE;
233 break;
235 case HCI_SCODATA_PKT:
236 info->rx_state = RECV_WAIT_SCO_HEADER;
237 info->rx_count = HCI_SCO_HDR_SIZE;
238 break;
240 default:
241 /* Unknown packet */
242 BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type);
243 info->hdev->stat.err_rx++;
244 clear_bit(HCI_RUNNING, &(info->hdev->flags));
246 kfree_skb(info->rx_skb);
247 info->rx_skb = NULL;
248 break;
252 } else {
254 *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
255 info->rx_count--;
257 if (info->rx_count == 0) {
259 int dlen;
260 struct hci_event_hdr *eh;
261 struct hci_acl_hdr *ah;
262 struct hci_sco_hdr *sh;
265 switch (info->rx_state) {
267 case RECV_WAIT_EVENT_HEADER:
268 eh = (struct hci_event_hdr *)(info->rx_skb->data);
269 info->rx_state = RECV_WAIT_DATA;
270 info->rx_count = eh->plen;
271 break;
273 case RECV_WAIT_ACL_HEADER:
274 ah = (struct hci_acl_hdr *)(info->rx_skb->data);
275 dlen = __le16_to_cpu(ah->dlen);
276 info->rx_state = RECV_WAIT_DATA;
277 info->rx_count = dlen;
278 break;
280 case RECV_WAIT_SCO_HEADER:
281 sh = (struct hci_sco_hdr *)(info->rx_skb->data);
282 info->rx_state = RECV_WAIT_DATA;
283 info->rx_count = sh->dlen;
284 break;
286 case RECV_WAIT_DATA:
287 hci_recv_frame(info->rx_skb);
288 info->rx_skb = NULL;
289 break;
297 /* Make sure we don't stay here too long */
298 if (boguscount++ > 16)
299 break;
301 } while (inb(iobase + UART_LSR) & UART_LSR_DR);
305 static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
307 btuart_info_t *info = dev_inst;
308 unsigned int iobase;
309 int boguscount = 0;
310 int iir, lsr;
312 if (!info || !info->hdev) {
313 BT_ERR("Call of irq %d for unknown device", irq);
314 return IRQ_NONE;
317 iobase = info->link.io.BasePort1;
319 spin_lock(&(info->lock));
321 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
322 while (iir) {
324 /* Clear interrupt */
325 lsr = inb(iobase + UART_LSR);
327 switch (iir) {
328 case UART_IIR_RLSI:
329 BT_ERR("RLSI");
330 break;
331 case UART_IIR_RDI:
332 /* Receive interrupt */
333 btuart_receive(info);
334 break;
335 case UART_IIR_THRI:
336 if (lsr & UART_LSR_THRE) {
337 /* Transmitter ready for data */
338 btuart_write_wakeup(info);
340 break;
341 default:
342 BT_ERR("Unhandled IIR=%#x", iir);
343 break;
346 /* Make sure we don't stay here too long */
347 if (boguscount++ > 100)
348 break;
350 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
354 spin_unlock(&(info->lock));
356 return IRQ_HANDLED;
360 static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
362 unsigned long flags;
363 unsigned int iobase;
364 int fcr; /* FIFO control reg */
365 int lcr; /* Line control reg */
366 int divisor;
368 if (!info) {
369 BT_ERR("Unknown device");
370 return;
373 iobase = info->link.io.BasePort1;
375 spin_lock_irqsave(&(info->lock), flags);
377 /* Turn off interrupts */
378 outb(0, iobase + UART_IER);
380 divisor = SPEED_MAX / speed;
382 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
385 * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
386 * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
387 * about this timeout since it will always be fast enough.
390 if (speed < 38400)
391 fcr |= UART_FCR_TRIGGER_1;
392 else
393 fcr |= UART_FCR_TRIGGER_14;
395 /* Bluetooth cards use 8N1 */
396 lcr = UART_LCR_WLEN8;
398 outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */
399 outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */
400 outb(divisor >> 8, iobase + UART_DLM);
401 outb(lcr, iobase + UART_LCR); /* Set 8N1 */
402 outb(fcr, iobase + UART_FCR); /* Enable FIFO's */
404 /* Turn on interrups */
405 outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
407 spin_unlock_irqrestore(&(info->lock), flags);
412 /* ======================== HCI interface ======================== */
415 static int btuart_hci_flush(struct hci_dev *hdev)
417 btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
419 /* Drop TX queue */
420 skb_queue_purge(&(info->txq));
422 return 0;
426 static int btuart_hci_open(struct hci_dev *hdev)
428 set_bit(HCI_RUNNING, &(hdev->flags));
430 return 0;
434 static int btuart_hci_close(struct hci_dev *hdev)
436 if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
437 return 0;
439 btuart_hci_flush(hdev);
441 return 0;
445 static int btuart_hci_send_frame(struct sk_buff *skb)
447 btuart_info_t *info;
448 struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
450 if (!hdev) {
451 BT_ERR("Frame for unknown HCI device (hdev=NULL)");
452 return -ENODEV;
455 info = (btuart_info_t *)(hdev->driver_data);
457 switch (skb->pkt_type) {
458 case HCI_COMMAND_PKT:
459 hdev->stat.cmd_tx++;
460 break;
461 case HCI_ACLDATA_PKT:
462 hdev->stat.acl_tx++;
463 break;
464 case HCI_SCODATA_PKT:
465 hdev->stat.sco_tx++;
466 break;
469 /* Prepend skb with frame type */
470 memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
471 skb_queue_tail(&(info->txq), skb);
473 btuart_write_wakeup(info);
475 return 0;
479 static void btuart_hci_destruct(struct hci_dev *hdev)
484 static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
486 return -ENOIOCTLCMD;
491 /* ======================== Card services HCI interaction ======================== */
494 int btuart_open(btuart_info_t *info)
496 unsigned long flags;
497 unsigned int iobase = info->link.io.BasePort1;
498 struct hci_dev *hdev;
500 spin_lock_init(&(info->lock));
502 skb_queue_head_init(&(info->txq));
504 info->rx_state = RECV_WAIT_PACKET_TYPE;
505 info->rx_count = 0;
506 info->rx_skb = NULL;
508 /* Initialize HCI device */
509 hdev = hci_alloc_dev();
510 if (!hdev) {
511 BT_ERR("Can't allocate HCI device");
512 return -ENOMEM;
515 info->hdev = hdev;
517 hdev->type = HCI_PCCARD;
518 hdev->driver_data = info;
520 hdev->open = btuart_hci_open;
521 hdev->close = btuart_hci_close;
522 hdev->flush = btuart_hci_flush;
523 hdev->send = btuart_hci_send_frame;
524 hdev->destruct = btuart_hci_destruct;
525 hdev->ioctl = btuart_hci_ioctl;
527 hdev->owner = THIS_MODULE;
529 spin_lock_irqsave(&(info->lock), flags);
531 /* Reset UART */
532 outb(0, iobase + UART_MCR);
534 /* Turn off interrupts */
535 outb(0, iobase + UART_IER);
537 /* Initialize UART */
538 outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
539 outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
541 /* Turn on interrupts */
542 // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
544 spin_unlock_irqrestore(&(info->lock), flags);
546 btuart_change_speed(info, DEFAULT_BAUD_RATE);
548 /* Timeout before it is safe to send the first HCI packet */
549 msleep(1000);
551 /* Register HCI device */
552 if (hci_register_dev(hdev) < 0) {
553 BT_ERR("Can't register HCI device");
554 info->hdev = NULL;
555 hci_free_dev(hdev);
556 return -ENODEV;
559 return 0;
563 int btuart_close(btuart_info_t *info)
565 unsigned long flags;
566 unsigned int iobase = info->link.io.BasePort1;
567 struct hci_dev *hdev = info->hdev;
569 if (!hdev)
570 return -ENODEV;
572 btuart_hci_close(hdev);
574 spin_lock_irqsave(&(info->lock), flags);
576 /* Reset UART */
577 outb(0, iobase + UART_MCR);
579 /* Turn off interrupts */
580 outb(0, iobase + UART_IER);
582 spin_unlock_irqrestore(&(info->lock), flags);
584 if (hci_unregister_dev(hdev) < 0)
585 BT_ERR("Can't unregister HCI device %s", hdev->name);
587 hci_free_dev(hdev);
589 return 0;
592 dev_link_t *btuart_attach(void)
594 btuart_info_t *info;
595 client_reg_t client_reg;
596 dev_link_t *link;
597 int i, ret;
599 /* Create new info device */
600 info = kmalloc(sizeof(*info), GFP_KERNEL);
601 if (!info)
602 return NULL;
603 memset(info, 0, sizeof(*info));
605 link = &info->link;
606 link->priv = info;
608 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
609 link->io.NumPorts1 = 8;
610 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
611 link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
613 if (irq_list[0] == -1)
614 link->irq.IRQInfo2 = irq_mask;
615 else
616 for (i = 0; i < 4; i++)
617 link->irq.IRQInfo2 |= 1 << irq_list[i];
619 link->irq.Handler = btuart_interrupt;
620 link->irq.Instance = info;
622 link->conf.Attributes = CONF_ENABLE_IRQ;
623 link->conf.Vcc = 50;
624 link->conf.IntType = INT_MEMORY_AND_IO;
626 /* Register with Card Services */
627 link->next = dev_list;
628 dev_list = link;
629 client_reg.dev_info = &dev_info;
630 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
631 client_reg.EventMask =
632 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
633 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
634 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
635 client_reg.event_handler = &btuart_event;
636 client_reg.Version = 0x0210;
637 client_reg.event_callback_args.client_data = link;
639 ret = pcmcia_register_client(&link->handle, &client_reg);
640 if (ret != CS_SUCCESS) {
641 cs_error(link->handle, RegisterClient, ret);
642 btuart_detach(link);
643 return NULL;
646 return link;
650 void btuart_detach(dev_link_t *link)
652 btuart_info_t *info = link->priv;
653 dev_link_t **linkp;
654 int ret;
656 /* Locate device structure */
657 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
658 if (*linkp == link)
659 break;
661 if (*linkp == NULL)
662 return;
664 if (link->state & DEV_CONFIG)
665 btuart_release(link);
667 if (link->handle) {
668 ret = pcmcia_deregister_client(link->handle);
669 if (ret != CS_SUCCESS)
670 cs_error(link->handle, DeregisterClient, ret);
673 /* Unlink device structure, free bits */
674 *linkp = link->next;
676 kfree(info);
679 static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
681 int i;
683 i = pcmcia_get_tuple_data(handle, tuple);
684 if (i != CS_SUCCESS)
685 return i;
687 return pcmcia_parse_tuple(handle, tuple, parse);
690 static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
692 if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
693 return CS_NO_MORE_ITEMS;
694 return get_tuple(handle, tuple, parse);
697 static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
699 if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
700 return CS_NO_MORE_ITEMS;
701 return get_tuple(handle, tuple, parse);
704 void btuart_config(dev_link_t *link)
706 static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
707 client_handle_t handle = link->handle;
708 btuart_info_t *info = link->priv;
709 tuple_t tuple;
710 u_short buf[256];
711 cisparse_t parse;
712 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
713 config_info_t config;
714 int i, j, try, last_ret, last_fn;
716 tuple.TupleData = (cisdata_t *)buf;
717 tuple.TupleOffset = 0;
718 tuple.TupleDataMax = 255;
719 tuple.Attributes = 0;
721 /* Get configuration register information */
722 tuple.DesiredTuple = CISTPL_CONFIG;
723 last_ret = first_tuple(handle, &tuple, &parse);
724 if (last_ret != CS_SUCCESS) {
725 last_fn = ParseTuple;
726 goto cs_failed;
728 link->conf.ConfigBase = parse.config.base;
729 link->conf.Present = parse.config.rmask[0];
731 /* Configure card */
732 link->state |= DEV_CONFIG;
733 i = pcmcia_get_configuration_info(handle, &config);
734 link->conf.Vcc = config.Vcc;
736 /* First pass: look for a config entry that looks normal. */
737 tuple.TupleData = (cisdata_t *) buf;
738 tuple.TupleOffset = 0;
739 tuple.TupleDataMax = 255;
740 tuple.Attributes = 0;
741 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
742 /* Two tries: without IO aliases, then with aliases */
743 for (try = 0; try < 2; try++) {
744 i = first_tuple(handle, &tuple, &parse);
745 while (i != CS_NO_MORE_ITEMS) {
746 if (i != CS_SUCCESS)
747 goto next_entry;
748 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
749 link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
750 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
751 link->conf.ConfigIndex = cf->index;
752 link->io.BasePort1 = cf->io.win[0].base;
753 link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
754 i = pcmcia_request_io(link->handle, &link->io);
755 if (i == CS_SUCCESS)
756 goto found_port;
758 next_entry:
759 i = next_tuple(handle, &tuple, &parse);
763 /* Second pass: try to find an entry that isn't picky about
764 its base address, then try to grab any standard serial port
765 address, and finally try to get any free port. */
766 i = first_tuple(handle, &tuple, &parse);
767 while (i != CS_NO_MORE_ITEMS) {
768 if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
769 && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
770 link->conf.ConfigIndex = cf->index;
771 for (j = 0; j < 5; j++) {
772 link->io.BasePort1 = base[j];
773 link->io.IOAddrLines = base[j] ? 16 : 3;
774 i = pcmcia_request_io(link->handle, &link->io);
775 if (i == CS_SUCCESS)
776 goto found_port;
779 i = next_tuple(handle, &tuple, &parse);
782 found_port:
783 if (i != CS_SUCCESS) {
784 BT_ERR("No usable port range found");
785 cs_error(link->handle, RequestIO, i);
786 goto failed;
789 i = pcmcia_request_irq(link->handle, &link->irq);
790 if (i != CS_SUCCESS) {
791 cs_error(link->handle, RequestIRQ, i);
792 link->irq.AssignedIRQ = 0;
795 i = pcmcia_request_configuration(link->handle, &link->conf);
796 if (i != CS_SUCCESS) {
797 cs_error(link->handle, RequestConfiguration, i);
798 goto failed;
801 if (btuart_open(info) != 0)
802 goto failed;
804 strcpy(info->node.dev_name, info->hdev->name);
805 link->dev = &info->node;
806 link->state &= ~DEV_CONFIG_PENDING;
808 return;
810 cs_failed:
811 cs_error(link->handle, last_fn, last_ret);
813 failed:
814 btuart_release(link);
818 void btuart_release(dev_link_t *link)
820 btuart_info_t *info = link->priv;
822 if (link->state & DEV_PRESENT)
823 btuart_close(info);
825 link->dev = NULL;
827 pcmcia_release_configuration(link->handle);
828 pcmcia_release_io(link->handle, &link->io);
829 pcmcia_release_irq(link->handle, &link->irq);
831 link->state &= ~DEV_CONFIG;
835 int btuart_event(event_t event, int priority, event_callback_args_t *args)
837 dev_link_t *link = args->client_data;
838 btuart_info_t *info = link->priv;
840 switch (event) {
841 case CS_EVENT_CARD_REMOVAL:
842 link->state &= ~DEV_PRESENT;
843 if (link->state & DEV_CONFIG) {
844 btuart_close(info);
845 btuart_release(link);
847 break;
848 case CS_EVENT_CARD_INSERTION:
849 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
850 btuart_config(link);
851 break;
852 case CS_EVENT_PM_SUSPEND:
853 link->state |= DEV_SUSPEND;
854 /* Fall through... */
855 case CS_EVENT_RESET_PHYSICAL:
856 if (link->state & DEV_CONFIG)
857 pcmcia_release_configuration(link->handle);
858 break;
859 case CS_EVENT_PM_RESUME:
860 link->state &= ~DEV_SUSPEND;
861 /* Fall through... */
862 case CS_EVENT_CARD_RESET:
863 if (DEV_OK(link))
864 pcmcia_request_configuration(link->handle, &link->conf);
865 break;
868 return 0;
871 static struct pcmcia_driver btuart_driver = {
872 .owner = THIS_MODULE,
873 .drv = {
874 .name = "btuart_cs",
876 .attach = btuart_attach,
877 .detach = btuart_detach,
880 static int __init init_btuart_cs(void)
882 return pcmcia_register_driver(&btuart_driver);
886 static void __exit exit_btuart_cs(void)
888 pcmcia_unregister_driver(&btuart_driver);
890 /* XXX: this really needs to move into generic code.. */
891 while (dev_list != NULL)
892 btuart_detach(dev_list);
895 module_init(init_btuart_cs);
896 module_exit(exit_btuart_cs);