aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btuart_cs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/bluetooth/btuart_cs.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/bluetooth/btuart_cs.c')
-rw-r--r--drivers/bluetooth/btuart_cs.c880
1 files changed, 880 insertions, 0 deletions
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
new file mode 100644
index 000000000000..ad8d972444a5
--- /dev/null
+++ b/drivers/bluetooth/btuart_cs.c
@@ -0,0 +1,880 @@
1/*
2 *
3 * Driver for Bluetooth PCMCIA cards with HCI UART interface
4 *
5 * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
6 *
7 *
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;
11 *
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.
16 *
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.
20 *
21 */
22
23#include <linux/config.h>
24#include <linux/module.h>
25
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>
36#include <linux/moduleparam.h>
37
38#include <linux/skbuff.h>
39#include <linux/string.h>
40#include <linux/serial.h>
41#include <linux/serial_reg.h>
42#include <linux/bitops.h>
43#include <asm/system.h>
44#include <asm/io.h>
45
46#include <pcmcia/version.h>
47#include <pcmcia/cs_types.h>
48#include <pcmcia/cs.h>
49#include <pcmcia/cistpl.h>
50#include <pcmcia/ciscode.h>
51#include <pcmcia/ds.h>
52#include <pcmcia/cisreg.h>
53
54#include <net/bluetooth/bluetooth.h>
55#include <net/bluetooth/hci_core.h>
56
57
58
59/* ======================== Module parameters ======================== */
60
61
62MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
63MODULE_DESCRIPTION("Bluetooth driver for Bluetooth PCMCIA cards with HCI UART interface");
64MODULE_LICENSE("GPL");
65
66
67
68/* ======================== Local structures ======================== */
69
70
71typedef struct btuart_info_t {
72 dev_link_t link;
73 dev_node_t node;
74
75 struct hci_dev *hdev;
76
77 spinlock_t lock; /* For serializing operations */
78
79 struct sk_buff_head txq;
80 unsigned long tx_state;
81
82 unsigned long rx_state;
83 unsigned long rx_count;
84 struct sk_buff *rx_skb;
85} btuart_info_t;
86
87
88static void btuart_config(dev_link_t *link);
89static void btuart_release(dev_link_t *link);
90static int btuart_event(event_t event, int priority, event_callback_args_t *args);
91
92static dev_info_t dev_info = "btuart_cs";
93
94static dev_link_t *btuart_attach(void);
95static void btuart_detach(dev_link_t *);
96
97static dev_link_t *dev_list = NULL;
98
99
100/* Maximum baud rate */
101#define SPEED_MAX 115200
102
103/* Default baud rate: 57600, 115200, 230400 or 460800 */
104#define DEFAULT_BAUD_RATE 115200
105
106
107/* Transmit states */
108#define XMIT_SENDING 1
109#define XMIT_WAKEUP 2
110#define XMIT_WAITING 8
111
112/* Receiver states */
113#define RECV_WAIT_PACKET_TYPE 0
114#define RECV_WAIT_EVENT_HEADER 1
115#define RECV_WAIT_ACL_HEADER 2
116#define RECV_WAIT_SCO_HEADER 3
117#define RECV_WAIT_DATA 4
118
119
120
121/* ======================== Interrupt handling ======================== */
122
123
124static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
125{
126 int actual = 0;
127
128 /* Tx FIFO should be empty */
129 if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
130 return 0;
131
132 /* Fill FIFO with current frame */
133 while ((fifo_size-- > 0) && (actual < len)) {
134 /* Transmit next byte */
135 outb(buf[actual], iobase + UART_TX);
136 actual++;
137 }
138
139 return actual;
140}
141
142
143static void btuart_write_wakeup(btuart_info_t *info)
144{
145 if (!info) {
146 BT_ERR("Unknown device");
147 return;
148 }
149
150 if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
151 set_bit(XMIT_WAKEUP, &(info->tx_state));
152 return;
153 }
154
155 do {
156 register unsigned int iobase = info->link.io.BasePort1;
157 register struct sk_buff *skb;
158 register int len;
159
160 clear_bit(XMIT_WAKEUP, &(info->tx_state));
161
162 if (!(info->link.state & DEV_PRESENT))
163 return;
164
165 if (!(skb = skb_dequeue(&(info->txq))))
166 break;
167
168 /* Send frame */
169 len = btuart_write(iobase, 16, skb->data, skb->len);
170 set_bit(XMIT_WAKEUP, &(info->tx_state));
171
172 if (len == skb->len) {
173 kfree_skb(skb);
174 } else {
175 skb_pull(skb, len);
176 skb_queue_head(&(info->txq), skb);
177 }
178
179 info->hdev->stat.byte_tx += len;
180
181 } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
182
183 clear_bit(XMIT_SENDING, &(info->tx_state));
184}
185
186
187static void btuart_receive(btuart_info_t *info)
188{
189 unsigned int iobase;
190 int boguscount = 0;
191
192 if (!info) {
193 BT_ERR("Unknown device");
194 return;
195 }
196
197 iobase = info->link.io.BasePort1;
198
199 do {
200 info->hdev->stat.byte_rx++;
201
202 /* Allocate packet */
203 if (info->rx_skb == NULL) {
204 info->rx_state = RECV_WAIT_PACKET_TYPE;
205 info->rx_count = 0;
206 if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
207 BT_ERR("Can't allocate mem for new packet");
208 return;
209 }
210 }
211
212 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
213
214 info->rx_skb->dev = (void *) info->hdev;
215 info->rx_skb->pkt_type = inb(iobase + UART_RX);
216
217 switch (info->rx_skb->pkt_type) {
218
219 case HCI_EVENT_PKT:
220 info->rx_state = RECV_WAIT_EVENT_HEADER;
221 info->rx_count = HCI_EVENT_HDR_SIZE;
222 break;
223
224 case HCI_ACLDATA_PKT:
225 info->rx_state = RECV_WAIT_ACL_HEADER;
226 info->rx_count = HCI_ACL_HDR_SIZE;
227 break;
228
229 case HCI_SCODATA_PKT:
230 info->rx_state = RECV_WAIT_SCO_HEADER;
231 info->rx_count = HCI_SCO_HDR_SIZE;
232 break;
233
234 default:
235 /* Unknown packet */
236 BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type);
237 info->hdev->stat.err_rx++;
238 clear_bit(HCI_RUNNING, &(info->hdev->flags));
239
240 kfree_skb(info->rx_skb);
241 info->rx_skb = NULL;
242 break;
243
244 }
245
246 } else {
247
248 *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
249 info->rx_count--;
250
251 if (info->rx_count == 0) {
252
253 int dlen;
254 struct hci_event_hdr *eh;
255 struct hci_acl_hdr *ah;
256 struct hci_sco_hdr *sh;
257
258
259 switch (info->rx_state) {
260
261 case RECV_WAIT_EVENT_HEADER:
262 eh = (struct hci_event_hdr *)(info->rx_skb->data);
263 info->rx_state = RECV_WAIT_DATA;
264 info->rx_count = eh->plen;
265 break;
266
267 case RECV_WAIT_ACL_HEADER:
268 ah = (struct hci_acl_hdr *)(info->rx_skb->data);
269 dlen = __le16_to_cpu(ah->dlen);
270 info->rx_state = RECV_WAIT_DATA;
271 info->rx_count = dlen;
272 break;
273
274 case RECV_WAIT_SCO_HEADER:
275 sh = (struct hci_sco_hdr *)(info->rx_skb->data);
276 info->rx_state = RECV_WAIT_DATA;
277 info->rx_count = sh->dlen;
278 break;
279
280 case RECV_WAIT_DATA:
281 hci_recv_frame(info->rx_skb);
282 info->rx_skb = NULL;
283 break;
284
285 }
286
287 }
288
289 }
290
291 /* Make sure we don't stay here too long */
292 if (boguscount++ > 16)
293 break;
294
295 } while (inb(iobase + UART_LSR) & UART_LSR_DR);
296}
297
298
299static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
300{
301 btuart_info_t *info = dev_inst;
302 unsigned int iobase;
303 int boguscount = 0;
304 int iir, lsr;
305
306 if (!info || !info->hdev) {
307 BT_ERR("Call of irq %d for unknown device", irq);
308 return IRQ_NONE;
309 }
310
311 iobase = info->link.io.BasePort1;
312
313 spin_lock(&(info->lock));
314
315 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
316 while (iir) {
317
318 /* Clear interrupt */
319 lsr = inb(iobase + UART_LSR);
320
321 switch (iir) {
322 case UART_IIR_RLSI:
323 BT_ERR("RLSI");
324 break;
325 case UART_IIR_RDI:
326 /* Receive interrupt */
327 btuart_receive(info);
328 break;
329 case UART_IIR_THRI:
330 if (lsr & UART_LSR_THRE) {
331 /* Transmitter ready for data */
332 btuart_write_wakeup(info);
333 }
334 break;
335 default:
336 BT_ERR("Unhandled IIR=%#x", iir);
337 break;
338 }
339
340 /* Make sure we don't stay here too long */
341 if (boguscount++ > 100)
342 break;
343
344 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
345
346 }
347
348 spin_unlock(&(info->lock));
349
350 return IRQ_HANDLED;
351}
352
353
354static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
355{
356 unsigned long flags;
357 unsigned int iobase;
358 int fcr; /* FIFO control reg */
359 int lcr; /* Line control reg */
360 int divisor;
361
362 if (!info) {
363 BT_ERR("Unknown device");
364 return;
365 }
366
367 iobase = info->link.io.BasePort1;
368
369 spin_lock_irqsave(&(info->lock), flags);
370
371 /* Turn off interrupts */
372 outb(0, iobase + UART_IER);
373
374 divisor = SPEED_MAX / speed;
375
376 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
377
378 /*
379 * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
380 * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
381 * about this timeout since it will always be fast enough.
382 */
383
384 if (speed < 38400)
385 fcr |= UART_FCR_TRIGGER_1;
386 else
387 fcr |= UART_FCR_TRIGGER_14;
388
389 /* Bluetooth cards use 8N1 */
390 lcr = UART_LCR_WLEN8;
391
392 outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */
393 outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */
394 outb(divisor >> 8, iobase + UART_DLM);
395 outb(lcr, iobase + UART_LCR); /* Set 8N1 */
396 outb(fcr, iobase + UART_FCR); /* Enable FIFO's */
397
398 /* Turn on interrups */
399 outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
400
401 spin_unlock_irqrestore(&(info->lock), flags);
402}
403
404
405
406/* ======================== HCI interface ======================== */
407
408
409static int btuart_hci_flush(struct hci_dev *hdev)
410{
411 btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
412
413 /* Drop TX queue */
414 skb_queue_purge(&(info->txq));
415
416 return 0;
417}
418
419
420static int btuart_hci_open(struct hci_dev *hdev)
421{
422 set_bit(HCI_RUNNING, &(hdev->flags));
423
424 return 0;
425}
426
427
428static int btuart_hci_close(struct hci_dev *hdev)
429{
430 if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
431 return 0;
432
433 btuart_hci_flush(hdev);
434
435 return 0;
436}
437
438
439static int btuart_hci_send_frame(struct sk_buff *skb)
440{
441 btuart_info_t *info;
442 struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
443
444 if (!hdev) {
445 BT_ERR("Frame for unknown HCI device (hdev=NULL)");
446 return -ENODEV;
447 }
448
449 info = (btuart_info_t *)(hdev->driver_data);
450
451 switch (skb->pkt_type) {
452 case HCI_COMMAND_PKT:
453 hdev->stat.cmd_tx++;
454 break;
455 case HCI_ACLDATA_PKT:
456 hdev->stat.acl_tx++;
457 break;
458 case HCI_SCODATA_PKT:
459 hdev->stat.sco_tx++;
460 break;
461 };
462
463 /* Prepend skb with frame type */
464 memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
465 skb_queue_tail(&(info->txq), skb);
466
467 btuart_write_wakeup(info);
468
469 return 0;
470}
471
472
473static void btuart_hci_destruct(struct hci_dev *hdev)
474{
475}
476
477
478static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
479{
480 return -ENOIOCTLCMD;
481}
482
483
484
485/* ======================== Card services HCI interaction ======================== */
486
487
488static int btuart_open(btuart_info_t *info)
489{
490 unsigned long flags;
491 unsigned int iobase = info->link.io.BasePort1;
492 struct hci_dev *hdev;
493
494 spin_lock_init(&(info->lock));
495
496 skb_queue_head_init(&(info->txq));
497
498 info->rx_state = RECV_WAIT_PACKET_TYPE;
499 info->rx_count = 0;
500 info->rx_skb = NULL;
501
502 /* Initialize HCI device */
503 hdev = hci_alloc_dev();
504 if (!hdev) {
505 BT_ERR("Can't allocate HCI device");
506 return -ENOMEM;
507 }
508
509 info->hdev = hdev;
510
511 hdev->type = HCI_PCCARD;
512 hdev->driver_data = info;
513
514 hdev->open = btuart_hci_open;
515 hdev->close = btuart_hci_close;
516 hdev->flush = btuart_hci_flush;
517 hdev->send = btuart_hci_send_frame;
518 hdev->destruct = btuart_hci_destruct;
519 hdev->ioctl = btuart_hci_ioctl;
520
521 hdev->owner = THIS_MODULE;
522
523 spin_lock_irqsave(&(info->lock), flags);
524
525 /* Reset UART */
526 outb(0, iobase + UART_MCR);
527
528 /* Turn off interrupts */
529 outb(0, iobase + UART_IER);
530
531 /* Initialize UART */
532 outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
533 outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
534
535 /* Turn on interrupts */
536 // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
537
538 spin_unlock_irqrestore(&(info->lock), flags);
539
540 btuart_change_speed(info, DEFAULT_BAUD_RATE);
541
542 /* Timeout before it is safe to send the first HCI packet */
543 msleep(1000);
544
545 /* Register HCI device */
546 if (hci_register_dev(hdev) < 0) {
547 BT_ERR("Can't register HCI device");
548 info->hdev = NULL;
549 hci_free_dev(hdev);
550 return -ENODEV;
551 }
552
553 return 0;
554}
555
556
557static int btuart_close(btuart_info_t *info)
558{
559 unsigned long flags;
560 unsigned int iobase = info->link.io.BasePort1;
561 struct hci_dev *hdev = info->hdev;
562
563 if (!hdev)
564 return -ENODEV;
565
566 btuart_hci_close(hdev);
567
568 spin_lock_irqsave(&(info->lock), flags);
569
570 /* Reset UART */
571 outb(0, iobase + UART_MCR);
572
573 /* Turn off interrupts */
574 outb(0, iobase + UART_IER);
575
576 spin_unlock_irqrestore(&(info->lock), flags);
577
578 if (hci_unregister_dev(hdev) < 0)
579 BT_ERR("Can't unregister HCI device %s", hdev->name);
580
581 hci_free_dev(hdev);
582
583 return 0;
584}
585
586static dev_link_t *btuart_attach(void)
587{
588 btuart_info_t *info;
589 client_reg_t client_reg;
590 dev_link_t *link;
591 int ret;
592
593 /* Create new info device */
594 info = kmalloc(sizeof(*info), GFP_KERNEL);
595 if (!info)
596 return NULL;
597 memset(info, 0, sizeof(*info));
598
599 link = &info->link;
600 link->priv = info;
601
602 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
603 link->io.NumPorts1 = 8;
604 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
605 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
606
607 link->irq.Handler = btuart_interrupt;
608 link->irq.Instance = info;
609
610 link->conf.Attributes = CONF_ENABLE_IRQ;
611 link->conf.Vcc = 50;
612 link->conf.IntType = INT_MEMORY_AND_IO;
613
614 /* Register with Card Services */
615 link->next = dev_list;
616 dev_list = link;
617 client_reg.dev_info = &dev_info;
618 client_reg.EventMask =
619 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
620 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
621 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
622 client_reg.event_handler = &btuart_event;
623 client_reg.Version = 0x0210;
624 client_reg.event_callback_args.client_data = link;
625
626 ret = pcmcia_register_client(&link->handle, &client_reg);
627 if (ret != CS_SUCCESS) {
628 cs_error(link->handle, RegisterClient, ret);
629 btuart_detach(link);
630 return NULL;
631 }
632
633 return link;
634}
635
636
637static void btuart_detach(dev_link_t *link)
638{
639 btuart_info_t *info = link->priv;
640 dev_link_t **linkp;
641 int ret;
642
643 /* Locate device structure */
644 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
645 if (*linkp == link)
646 break;
647
648 if (*linkp == NULL)
649 return;
650
651 if (link->state & DEV_CONFIG)
652 btuart_release(link);
653
654 if (link->handle) {
655 ret = pcmcia_deregister_client(link->handle);
656 if (ret != CS_SUCCESS)
657 cs_error(link->handle, DeregisterClient, ret);
658 }
659
660 /* Unlink device structure, free bits */
661 *linkp = link->next;
662
663 kfree(info);
664}
665
666static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
667{
668 int i;
669
670 i = pcmcia_get_tuple_data(handle, tuple);
671 if (i != CS_SUCCESS)
672 return i;
673
674 return pcmcia_parse_tuple(handle, tuple, parse);
675}
676
677static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
678{
679 if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
680 return CS_NO_MORE_ITEMS;
681 return get_tuple(handle, tuple, parse);
682}
683
684static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
685{
686 if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
687 return CS_NO_MORE_ITEMS;
688 return get_tuple(handle, tuple, parse);
689}
690
691static void btuart_config(dev_link_t *link)
692{
693 static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
694 client_handle_t handle = link->handle;
695 btuart_info_t *info = link->priv;
696 tuple_t tuple;
697 u_short buf[256];
698 cisparse_t parse;
699 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
700 config_info_t config;
701 int i, j, try, last_ret, last_fn;
702
703 tuple.TupleData = (cisdata_t *)buf;
704 tuple.TupleOffset = 0;
705 tuple.TupleDataMax = 255;
706 tuple.Attributes = 0;
707
708 /* Get configuration register information */
709 tuple.DesiredTuple = CISTPL_CONFIG;
710 last_ret = first_tuple(handle, &tuple, &parse);
711 if (last_ret != CS_SUCCESS) {
712 last_fn = ParseTuple;
713 goto cs_failed;
714 }
715 link->conf.ConfigBase = parse.config.base;
716 link->conf.Present = parse.config.rmask[0];
717
718 /* Configure card */
719 link->state |= DEV_CONFIG;
720 i = pcmcia_get_configuration_info(handle, &config);
721 link->conf.Vcc = config.Vcc;
722
723 /* First pass: look for a config entry that looks normal. */
724 tuple.TupleData = (cisdata_t *) buf;
725 tuple.TupleOffset = 0;
726 tuple.TupleDataMax = 255;
727 tuple.Attributes = 0;
728 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
729 /* Two tries: without IO aliases, then with aliases */
730 for (try = 0; try < 2; try++) {
731 i = first_tuple(handle, &tuple, &parse);
732 while (i != CS_NO_MORE_ITEMS) {
733 if (i != CS_SUCCESS)
734 goto next_entry;
735 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
736 link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
737 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
738 link->conf.ConfigIndex = cf->index;
739 link->io.BasePort1 = cf->io.win[0].base;
740 link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
741 i = pcmcia_request_io(link->handle, &link->io);
742 if (i == CS_SUCCESS)
743 goto found_port;
744 }
745next_entry:
746 i = next_tuple(handle, &tuple, &parse);
747 }
748 }
749
750 /* Second pass: try to find an entry that isn't picky about
751 its base address, then try to grab any standard serial port
752 address, and finally try to get any free port. */
753 i = first_tuple(handle, &tuple, &parse);
754 while (i != CS_NO_MORE_ITEMS) {
755 if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
756 && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
757 link->conf.ConfigIndex = cf->index;
758 for (j = 0; j < 5; j++) {
759 link->io.BasePort1 = base[j];
760 link->io.IOAddrLines = base[j] ? 16 : 3;
761 i = pcmcia_request_io(link->handle, &link->io);
762 if (i == CS_SUCCESS)
763 goto found_port;
764 }
765 }
766 i = next_tuple(handle, &tuple, &parse);
767 }
768
769found_port:
770 if (i != CS_SUCCESS) {
771 BT_ERR("No usable port range found");
772 cs_error(link->handle, RequestIO, i);
773 goto failed;
774 }
775
776 i = pcmcia_request_irq(link->handle, &link->irq);
777 if (i != CS_SUCCESS) {
778 cs_error(link->handle, RequestIRQ, i);
779 link->irq.AssignedIRQ = 0;
780 }
781
782 i = pcmcia_request_configuration(link->handle, &link->conf);
783 if (i != CS_SUCCESS) {
784 cs_error(link->handle, RequestConfiguration, i);
785 goto failed;
786 }
787
788 if (btuart_open(info) != 0)
789 goto failed;
790
791 strcpy(info->node.dev_name, info->hdev->name);
792 link->dev = &info->node;
793 link->state &= ~DEV_CONFIG_PENDING;
794
795 return;
796
797cs_failed:
798 cs_error(link->handle, last_fn, last_ret);
799
800failed:
801 btuart_release(link);
802}
803
804
805static void btuart_release(dev_link_t *link)
806{
807 btuart_info_t *info = link->priv;
808
809 if (link->state & DEV_PRESENT)
810 btuart_close(info);
811
812 link->dev = NULL;
813
814 pcmcia_release_configuration(link->handle);
815 pcmcia_release_io(link->handle, &link->io);
816 pcmcia_release_irq(link->handle, &link->irq);
817
818 link->state &= ~DEV_CONFIG;
819}
820
821
822static int btuart_event(event_t event, int priority, event_callback_args_t *args)
823{
824 dev_link_t *link = args->client_data;
825 btuart_info_t *info = link->priv;
826
827 switch (event) {
828 case CS_EVENT_CARD_REMOVAL:
829 link->state &= ~DEV_PRESENT;
830 if (link->state & DEV_CONFIG) {
831 btuart_close(info);
832 btuart_release(link);
833 }
834 break;
835 case CS_EVENT_CARD_INSERTION:
836 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
837 btuart_config(link);
838 break;
839 case CS_EVENT_PM_SUSPEND:
840 link->state |= DEV_SUSPEND;
841 /* Fall through... */
842 case CS_EVENT_RESET_PHYSICAL:
843 if (link->state & DEV_CONFIG)
844 pcmcia_release_configuration(link->handle);
845 break;
846 case CS_EVENT_PM_RESUME:
847 link->state &= ~DEV_SUSPEND;
848 /* Fall through... */
849 case CS_EVENT_CARD_RESET:
850 if (DEV_OK(link))
851 pcmcia_request_configuration(link->handle, &link->conf);
852 break;
853 }
854
855 return 0;
856}
857
858static struct pcmcia_driver btuart_driver = {
859 .owner = THIS_MODULE,
860 .drv = {
861 .name = "btuart_cs",
862 },
863 .attach = btuart_attach,
864 .detach = btuart_detach,
865};
866
867static int __init init_btuart_cs(void)
868{
869 return pcmcia_register_driver(&btuart_driver);
870}
871
872
873static void __exit exit_btuart_cs(void)
874{
875 pcmcia_unregister_driver(&btuart_driver);
876 BUG_ON(dev_list != NULL);
877}
878
879module_init(init_btuart_cs);
880module_exit(exit_btuart_cs);