[PATCH] CREDITS update
[linux-2.6/history.git] / drivers / bluetooth / btuart_cs.c
bloba18be62b0387f28daf3b2c483e95704329b64927
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/errno.h>
32 #include <linux/ptrace.h>
33 #include <linux/ioport.h>
34 #include <linux/spinlock.h>
36 #include <linux/skbuff.h>
37 #include <linux/string.h>
38 #include <linux/serial.h>
39 #include <linux/serial_reg.h>
40 #include <asm/system.h>
41 #include <asm/bitops.h>
42 #include <asm/io.h>
44 #include <pcmcia/version.h>
45 #include <pcmcia/cs_types.h>
46 #include <pcmcia/cs.h>
47 #include <pcmcia/cistpl.h>
48 #include <pcmcia/ciscode.h>
49 #include <pcmcia/ds.h>
50 #include <pcmcia/cisreg.h>
52 #include <net/bluetooth/bluetooth.h>
53 #include <net/bluetooth/hci_core.h>
57 /* ======================== Module parameters ======================== */
60 /* Bit map of interrupts to choose from */
61 static u_int irq_mask = 0xffff;
62 static int irq_list[4] = { -1 };
64 MODULE_PARM(irq_mask, "i");
65 MODULE_PARM(irq_list, "1-4i");
67 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
68 MODULE_DESCRIPTION("Bluetooth driver for Bluetooth PCMCIA cards with HCI UART interface");
69 MODULE_LICENSE("GPL");
73 /* ======================== Local structures ======================== */
76 typedef struct btuart_info_t {
77 dev_link_t link;
78 dev_node_t node;
80 struct hci_dev *hdev;
82 spinlock_t lock; /* For serializing operations */
84 struct sk_buff_head txq;
85 unsigned long tx_state;
87 unsigned long rx_state;
88 unsigned long rx_count;
89 struct sk_buff *rx_skb;
90 } btuart_info_t;
93 void btuart_config(dev_link_t *link);
94 void btuart_release(dev_link_t *link);
95 int btuart_event(event_t event, int priority, event_callback_args_t *args);
97 static dev_info_t dev_info = "btuart_cs";
99 dev_link_t *btuart_attach(void);
100 void btuart_detach(dev_link_t *);
102 static dev_link_t *dev_list = NULL;
105 /* Maximum baud rate */
106 #define SPEED_MAX 115200
108 /* Default baud rate: 57600, 115200, 230400 or 460800 */
109 #define DEFAULT_BAUD_RATE 115200
112 /* Transmit states */
113 #define XMIT_SENDING 1
114 #define XMIT_WAKEUP 2
115 #define XMIT_WAITING 8
117 /* Receiver states */
118 #define RECV_WAIT_PACKET_TYPE 0
119 #define RECV_WAIT_EVENT_HEADER 1
120 #define RECV_WAIT_ACL_HEADER 2
121 #define RECV_WAIT_SCO_HEADER 3
122 #define RECV_WAIT_DATA 4
126 /* ======================== Interrupt handling ======================== */
129 static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
131 int actual = 0;
133 /* Tx FIFO should be empty */
134 if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
135 return 0;
137 /* Fill FIFO with current frame */
138 while ((fifo_size-- > 0) && (actual < len)) {
139 /* Transmit next byte */
140 outb(buf[actual], iobase + UART_TX);
141 actual++;
144 return actual;
148 static void btuart_write_wakeup(btuart_info_t *info)
150 if (!info) {
151 BT_ERR("Unknown device");
152 return;
155 if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
156 set_bit(XMIT_WAKEUP, &(info->tx_state));
157 return;
160 do {
161 register unsigned int iobase = info->link.io.BasePort1;
162 register struct sk_buff *skb;
163 register int len;
165 clear_bit(XMIT_WAKEUP, &(info->tx_state));
167 if (!(info->link.state & DEV_PRESENT))
168 return;
170 if (!(skb = skb_dequeue(&(info->txq))))
171 break;
173 /* Send frame */
174 len = btuart_write(iobase, 16, skb->data, skb->len);
175 set_bit(XMIT_WAKEUP, &(info->tx_state));
177 if (len == skb->len) {
178 kfree_skb(skb);
179 } else {
180 skb_pull(skb, len);
181 skb_queue_head(&(info->txq), skb);
184 info->hdev->stat.byte_tx += len;
186 } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
188 clear_bit(XMIT_SENDING, &(info->tx_state));
192 static void btuart_receive(btuart_info_t *info)
194 unsigned int iobase;
195 int boguscount = 0;
197 if (!info) {
198 BT_ERR("Unknown device");
199 return;
202 iobase = info->link.io.BasePort1;
204 do {
205 info->hdev->stat.byte_rx++;
207 /* Allocate packet */
208 if (info->rx_skb == NULL) {
209 info->rx_state = RECV_WAIT_PACKET_TYPE;
210 info->rx_count = 0;
211 if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
212 BT_ERR("Can't allocate mem for new packet");
213 return;
217 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
219 info->rx_skb->dev = (void *) info->hdev;
220 info->rx_skb->pkt_type = inb(iobase + UART_RX);
222 switch (info->rx_skb->pkt_type) {
224 case HCI_EVENT_PKT:
225 info->rx_state = RECV_WAIT_EVENT_HEADER;
226 info->rx_count = HCI_EVENT_HDR_SIZE;
227 break;
229 case HCI_ACLDATA_PKT:
230 info->rx_state = RECV_WAIT_ACL_HEADER;
231 info->rx_count = HCI_ACL_HDR_SIZE;
232 break;
234 case HCI_SCODATA_PKT:
235 info->rx_state = RECV_WAIT_SCO_HEADER;
236 info->rx_count = HCI_SCO_HDR_SIZE;
237 break;
239 default:
240 /* Unknown packet */
241 BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type);
242 info->hdev->stat.err_rx++;
243 clear_bit(HCI_RUNNING, &(info->hdev->flags));
245 kfree_skb(info->rx_skb);
246 info->rx_skb = NULL;
247 break;
251 } else {
253 *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
254 info->rx_count--;
256 if (info->rx_count == 0) {
258 int dlen;
259 struct hci_event_hdr *eh;
260 struct hci_acl_hdr *ah;
261 struct hci_sco_hdr *sh;
264 switch (info->rx_state) {
266 case RECV_WAIT_EVENT_HEADER:
267 eh = (struct hci_event_hdr *)(info->rx_skb->data);
268 info->rx_state = RECV_WAIT_DATA;
269 info->rx_count = eh->plen;
270 break;
272 case RECV_WAIT_ACL_HEADER:
273 ah = (struct hci_acl_hdr *)(info->rx_skb->data);
274 dlen = __le16_to_cpu(ah->dlen);
275 info->rx_state = RECV_WAIT_DATA;
276 info->rx_count = dlen;
277 break;
279 case RECV_WAIT_SCO_HEADER:
280 sh = (struct hci_sco_hdr *)(info->rx_skb->data);
281 info->rx_state = RECV_WAIT_DATA;
282 info->rx_count = sh->dlen;
283 break;
285 case RECV_WAIT_DATA:
286 hci_recv_frame(info->rx_skb);
287 info->rx_skb = NULL;
288 break;
296 /* Make sure we don't stay here too long */
297 if (boguscount++ > 16)
298 break;
300 } while (inb(iobase + UART_LSR) & UART_LSR_DR);
304 static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
306 btuart_info_t *info = dev_inst;
307 unsigned int iobase;
308 int boguscount = 0;
309 int iir, lsr;
311 if (!info || !info->hdev) {
312 BT_ERR("Call of irq %d for unknown device", irq);
313 return IRQ_NONE;
316 iobase = info->link.io.BasePort1;
318 spin_lock(&(info->lock));
320 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
321 while (iir) {
323 /* Clear interrupt */
324 lsr = inb(iobase + UART_LSR);
326 switch (iir) {
327 case UART_IIR_RLSI:
328 BT_ERR("RLSI");
329 break;
330 case UART_IIR_RDI:
331 /* Receive interrupt */
332 btuart_receive(info);
333 break;
334 case UART_IIR_THRI:
335 if (lsr & UART_LSR_THRE) {
336 /* Transmitter ready for data */
337 btuart_write_wakeup(info);
339 break;
340 default:
341 BT_ERR("Unhandled IIR=%#x", iir);
342 break;
345 /* Make sure we don't stay here too long */
346 if (boguscount++ > 100)
347 break;
349 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
353 spin_unlock(&(info->lock));
355 return IRQ_HANDLED;
359 static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
361 unsigned long flags;
362 unsigned int iobase;
363 int fcr; /* FIFO control reg */
364 int lcr; /* Line control reg */
365 int divisor;
367 if (!info) {
368 BT_ERR("Unknown device");
369 return;
372 iobase = info->link.io.BasePort1;
374 spin_lock_irqsave(&(info->lock), flags);
376 /* Turn off interrupts */
377 outb(0, iobase + UART_IER);
379 divisor = SPEED_MAX / speed;
381 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
384 * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
385 * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
386 * about this timeout since it will always be fast enough.
389 if (speed < 38400)
390 fcr |= UART_FCR_TRIGGER_1;
391 else
392 fcr |= UART_FCR_TRIGGER_14;
394 /* Bluetooth cards use 8N1 */
395 lcr = UART_LCR_WLEN8;
397 outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */
398 outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */
399 outb(divisor >> 8, iobase + UART_DLM);
400 outb(lcr, iobase + UART_LCR); /* Set 8N1 */
401 outb(fcr, iobase + UART_FCR); /* Enable FIFO's */
403 /* Turn on interrups */
404 outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
406 spin_unlock_irqrestore(&(info->lock), flags);
411 /* ======================== HCI interface ======================== */
414 static int btuart_hci_flush(struct hci_dev *hdev)
416 btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
418 /* Drop TX queue */
419 skb_queue_purge(&(info->txq));
421 return 0;
425 static int btuart_hci_open(struct hci_dev *hdev)
427 set_bit(HCI_RUNNING, &(hdev->flags));
429 return 0;
433 static int btuart_hci_close(struct hci_dev *hdev)
435 if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
436 return 0;
438 btuart_hci_flush(hdev);
440 return 0;
444 static int btuart_hci_send_frame(struct sk_buff *skb)
446 btuart_info_t *info;
447 struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
449 if (!hdev) {
450 BT_ERR("Frame for unknown HCI device (hdev=NULL)");
451 return -ENODEV;
454 info = (btuart_info_t *)(hdev->driver_data);
456 switch (skb->pkt_type) {
457 case HCI_COMMAND_PKT:
458 hdev->stat.cmd_tx++;
459 break;
460 case HCI_ACLDATA_PKT:
461 hdev->stat.acl_tx++;
462 break;
463 case HCI_SCODATA_PKT:
464 hdev->stat.sco_tx++;
465 break;
468 /* Prepend skb with frame type */
469 memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
470 skb_queue_tail(&(info->txq), skb);
472 btuart_write_wakeup(info);
474 return 0;
478 static void btuart_hci_destruct(struct hci_dev *hdev)
483 static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
485 return -ENOIOCTLCMD;
490 /* ======================== Card services HCI interaction ======================== */
493 int btuart_open(btuart_info_t *info)
495 unsigned long flags;
496 unsigned int iobase = info->link.io.BasePort1;
497 struct hci_dev *hdev;
499 spin_lock_init(&(info->lock));
501 skb_queue_head_init(&(info->txq));
503 info->rx_state = RECV_WAIT_PACKET_TYPE;
504 info->rx_count = 0;
505 info->rx_skb = NULL;
507 /* Initialize HCI device */
508 hdev = hci_alloc_dev();
509 if (!hdev) {
510 BT_ERR("Can't allocate HCI device");
511 return -ENOMEM;
514 info->hdev = hdev;
516 hdev->type = HCI_PCCARD;
517 hdev->driver_data = info;
519 hdev->open = btuart_hci_open;
520 hdev->close = btuart_hci_close;
521 hdev->flush = btuart_hci_flush;
522 hdev->send = btuart_hci_send_frame;
523 hdev->destruct = btuart_hci_destruct;
524 hdev->ioctl = btuart_hci_ioctl;
526 hdev->owner = THIS_MODULE;
528 spin_lock_irqsave(&(info->lock), flags);
530 /* Reset UART */
531 outb(0, iobase + UART_MCR);
533 /* Turn off interrupts */
534 outb(0, iobase + UART_IER);
536 /* Initialize UART */
537 outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
538 outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
540 /* Turn on interrupts */
541 // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
543 spin_unlock_irqrestore(&(info->lock), flags);
545 btuart_change_speed(info, DEFAULT_BAUD_RATE);
547 /* Timeout before it is safe to send the first HCI packet */
548 set_current_state(TASK_INTERRUPTIBLE);
549 schedule_timeout(HZ);
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);