Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzi...
[deliverable/linux.git] / drivers / bluetooth / bt3c_cs.c
CommitLineData
1da177e4
LT
1/*
2 *
3 * Driver for the 3Com Bluetooth PCMCIA card
4 *
5 * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
6 * Jose Orlando Pereira <jop@di.uminho.pt>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation;
12 *
13 * Software distributed under the License is distributed on an "AS
14 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
15 * implied. See the License for the specific language governing
16 * rights and limitations under the License.
17 *
18 * The initial developer of the original code is David A. Hinds
19 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
20 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
21 *
22 */
23
1da177e4
LT
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>
1da177e4
LT
30#include <linux/delay.h>
31#include <linux/errno.h>
32#include <linux/ptrace.h>
33#include <linux/ioport.h>
34#include <linux/spinlock.h>
35#include <linux/moduleparam.h>
36
37#include <linux/skbuff.h>
38#include <linux/string.h>
39#include <linux/serial.h>
40#include <linux/serial_reg.h>
41#include <linux/bitops.h>
42#include <asm/system.h>
43#include <asm/io.h>
44
45#include <linux/device.h>
46#include <linux/firmware.h>
47
1da177e4
LT
48#include <pcmcia/cs_types.h>
49#include <pcmcia/cs.h>
50#include <pcmcia/cistpl.h>
51#include <pcmcia/ciscode.h>
52#include <pcmcia/ds.h>
53#include <pcmcia/cisreg.h>
54
55#include <net/bluetooth/bluetooth.h>
56#include <net/bluetooth/hci_core.h>
57
58
59
60/* ======================== Module parameters ======================== */
61
62
63fbd24e 63MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
1da177e4
LT
64MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
65MODULE_LICENSE("GPL");
2312119a 66MODULE_FIRMWARE("BT3CPCC.bin");
1da177e4
LT
67
68
69
70/* ======================== Local structures ======================== */
71
72
73typedef struct bt3c_info_t {
fd238232 74 struct pcmcia_device *p_dev;
1da177e4
LT
75
76 struct hci_dev *hdev;
77
78 spinlock_t lock; /* For serializing operations */
79
80 struct sk_buff_head txq;
81 unsigned long tx_state;
82
83 unsigned long rx_state;
84 unsigned long rx_count;
85 struct sk_buff *rx_skb;
86} bt3c_info_t;
87
88
15b99ac1 89static int bt3c_config(struct pcmcia_device *link);
fba395ee 90static void bt3c_release(struct pcmcia_device *link);
1da177e4 91
cc3b4866 92static void bt3c_detach(struct pcmcia_device *p_dev);
1da177e4 93
1da177e4
LT
94
95/* Transmit states */
96#define XMIT_SENDING 1
97#define XMIT_WAKEUP 2
98#define XMIT_WAITING 8
99
100/* Receiver states */
101#define RECV_WAIT_PACKET_TYPE 0
102#define RECV_WAIT_EVENT_HEADER 1
103#define RECV_WAIT_ACL_HEADER 2
104#define RECV_WAIT_SCO_HEADER 3
105#define RECV_WAIT_DATA 4
106
107
108
109/* ======================== Special I/O functions ======================== */
110
111
112#define DATA_L 0
113#define DATA_H 1
114#define ADDR_L 2
115#define ADDR_H 3
116#define CONTROL 4
117
118
119static inline void bt3c_address(unsigned int iobase, unsigned short addr)
120{
121 outb(addr & 0xff, iobase + ADDR_L);
122 outb((addr >> 8) & 0xff, iobase + ADDR_H);
123}
124
125
126static inline void bt3c_put(unsigned int iobase, unsigned short value)
127{
128 outb(value & 0xff, iobase + DATA_L);
129 outb((value >> 8) & 0xff, iobase + DATA_H);
130}
131
132
133static inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
134{
135 bt3c_address(iobase, addr);
136 bt3c_put(iobase, value);
137}
138
139
140static inline unsigned short bt3c_get(unsigned int iobase)
141{
142 unsigned short value = inb(iobase + DATA_L);
143
144 value |= inb(iobase + DATA_H) << 8;
145
146 return value;
147}
148
149
150static inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
151{
152 bt3c_address(iobase, addr);
153
154 return bt3c_get(iobase);
155}
156
157
158
159/* ======================== Interrupt handling ======================== */
160
161
162static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
163{
164 int actual = 0;
165
166 bt3c_address(iobase, 0x7080);
167
168 /* Fill FIFO with current frame */
169 while (actual < len) {
170 /* Transmit next byte */
171 bt3c_put(iobase, buf[actual]);
172 actual++;
173 }
174
175 bt3c_io_write(iobase, 0x7005, actual);
176
177 return actual;
178}
179
180
181static void bt3c_write_wakeup(bt3c_info_t *info)
182{
183 if (!info) {
184 BT_ERR("Unknown device");
185 return;
186 }
187
188 if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
189 return;
190
191 do {
fd238232 192 register unsigned int iobase = info->p_dev->io.BasePort1;
1da177e4
LT
193 register struct sk_buff *skb;
194 register int len;
195
e2d40963 196 if (!pcmcia_dev_present(info->p_dev))
1da177e4
LT
197 break;
198
199
200 if (!(skb = skb_dequeue(&(info->txq)))) {
201 clear_bit(XMIT_SENDING, &(info->tx_state));
202 break;
203 }
204
205 /* Send frame */
206 len = bt3c_write(iobase, 256, skb->data, skb->len);
207
208 if (len != skb->len) {
209 BT_ERR("Very strange");
210 }
211
212 kfree_skb(skb);
213
214 info->hdev->stat.byte_tx += len;
215
216 } while (0);
217}
218
219
220static void bt3c_receive(bt3c_info_t *info)
221{
222 unsigned int iobase;
223 int size = 0, avail;
224
225 if (!info) {
226 BT_ERR("Unknown device");
227 return;
228 }
229
fd238232 230 iobase = info->p_dev->io.BasePort1;
1da177e4
LT
231
232 avail = bt3c_read(iobase, 0x7006);
233 //printk("bt3c_cs: receiving %d bytes\n", avail);
234
235 bt3c_address(iobase, 0x7480);
236 while (size < avail) {
237 size++;
238 info->hdev->stat.byte_rx++;
239
240 /* Allocate packet */
241 if (info->rx_skb == NULL) {
242 info->rx_state = RECV_WAIT_PACKET_TYPE;
243 info->rx_count = 0;
244 if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
245 BT_ERR("Can't allocate mem for new packet");
246 return;
247 }
248 }
249
250
251 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
252
253 info->rx_skb->dev = (void *) info->hdev;
0d48d939 254 bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L);
1da177e4 255 inb(iobase + DATA_H);
0d48d939 256 //printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
1da177e4 257
0d48d939 258 switch (bt_cb(info->rx_skb)->pkt_type) {
1da177e4
LT
259
260 case HCI_EVENT_PKT:
261 info->rx_state = RECV_WAIT_EVENT_HEADER;
262 info->rx_count = HCI_EVENT_HDR_SIZE;
263 break;
264
265 case HCI_ACLDATA_PKT:
266 info->rx_state = RECV_WAIT_ACL_HEADER;
267 info->rx_count = HCI_ACL_HDR_SIZE;
268 break;
269
270 case HCI_SCODATA_PKT:
271 info->rx_state = RECV_WAIT_SCO_HEADER;
272 info->rx_count = HCI_SCO_HDR_SIZE;
273 break;
274
275 default:
276 /* Unknown packet */
0d48d939 277 BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
1da177e4
LT
278 info->hdev->stat.err_rx++;
279 clear_bit(HCI_RUNNING, &(info->hdev->flags));
280
281 kfree_skb(info->rx_skb);
282 info->rx_skb = NULL;
283 break;
284
285 }
286
287 } else {
288
289 __u8 x = inb(iobase + DATA_L);
290
291 *skb_put(info->rx_skb, 1) = x;
292 inb(iobase + DATA_H);
293 info->rx_count--;
294
295 if (info->rx_count == 0) {
296
297 int dlen;
298 struct hci_event_hdr *eh;
299 struct hci_acl_hdr *ah;
300 struct hci_sco_hdr *sh;
301
302 switch (info->rx_state) {
303
304 case RECV_WAIT_EVENT_HEADER:
2a123b86 305 eh = hci_event_hdr(info->rx_skb);
1da177e4
LT
306 info->rx_state = RECV_WAIT_DATA;
307 info->rx_count = eh->plen;
308 break;
309
310 case RECV_WAIT_ACL_HEADER:
2a123b86 311 ah = hci_acl_hdr(info->rx_skb);
1da177e4
LT
312 dlen = __le16_to_cpu(ah->dlen);
313 info->rx_state = RECV_WAIT_DATA;
314 info->rx_count = dlen;
315 break;
316
317 case RECV_WAIT_SCO_HEADER:
2a123b86 318 sh = hci_sco_hdr(info->rx_skb);
1da177e4
LT
319 info->rx_state = RECV_WAIT_DATA;
320 info->rx_count = sh->dlen;
321 break;
322
323 case RECV_WAIT_DATA:
324 hci_recv_frame(info->rx_skb);
325 info->rx_skb = NULL;
326 break;
327
328 }
329
330 }
331
332 }
333
334 }
335
336 bt3c_io_write(iobase, 0x7006, 0x0000);
337}
338
339
7d12e780 340static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
1da177e4
LT
341{
342 bt3c_info_t *info = dev_inst;
343 unsigned int iobase;
344 int iir;
aafcf998 345 irqreturn_t r = IRQ_NONE;
1da177e4 346
7427847d
MF
347 if (!info || !info->hdev)
348 /* our irq handler is shared */
349 return IRQ_NONE;
1da177e4 350
fd238232 351 iobase = info->p_dev->io.BasePort1;
1da177e4
LT
352
353 spin_lock(&(info->lock));
354
355 iir = inb(iobase + CONTROL);
356 if (iir & 0x80) {
357 int stat = bt3c_read(iobase, 0x7001);
358
359 if ((stat & 0xff) == 0x7f) {
360 BT_ERR("Very strange (stat=0x%04x)", stat);
361 } else if ((stat & 0xff) != 0xff) {
362 if (stat & 0x0020) {
34a55eda 363 int status = bt3c_read(iobase, 0x7002) & 0x10;
1da177e4 364 BT_INFO("%s: Antenna %s", info->hdev->name,
34a55eda 365 status ? "out" : "in");
1da177e4
LT
366 }
367 if (stat & 0x0001)
368 bt3c_receive(info);
369 if (stat & 0x0002) {
370 //BT_ERR("Ack (stat=0x%04x)", stat);
371 clear_bit(XMIT_SENDING, &(info->tx_state));
372 bt3c_write_wakeup(info);
373 }
374
375 bt3c_io_write(iobase, 0x7001, 0x0000);
376
377 outb(iir, iobase + CONTROL);
378 }
aafcf998 379 r = IRQ_HANDLED;
1da177e4
LT
380 }
381
382 spin_unlock(&(info->lock));
383
aafcf998 384 return r;
1da177e4
LT
385}
386
387
388
389/* ======================== HCI interface ======================== */
390
391
392static int bt3c_hci_flush(struct hci_dev *hdev)
393{
394 bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
395
396 /* Drop TX queue */
397 skb_queue_purge(&(info->txq));
398
399 return 0;
400}
401
402
403static int bt3c_hci_open(struct hci_dev *hdev)
404{
405 set_bit(HCI_RUNNING, &(hdev->flags));
406
407 return 0;
408}
409
410
411static int bt3c_hci_close(struct hci_dev *hdev)
412{
413 if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
414 return 0;
415
416 bt3c_hci_flush(hdev);
417
418 return 0;
419}
420
421
422static int bt3c_hci_send_frame(struct sk_buff *skb)
423{
424 bt3c_info_t *info;
425 struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
426 unsigned long flags;
427
428 if (!hdev) {
429 BT_ERR("Frame for unknown HCI device (hdev=NULL)");
430 return -ENODEV;
431 }
432
433 info = (bt3c_info_t *) (hdev->driver_data);
434
0d48d939 435 switch (bt_cb(skb)->pkt_type) {
1da177e4
LT
436 case HCI_COMMAND_PKT:
437 hdev->stat.cmd_tx++;
438 break;
439 case HCI_ACLDATA_PKT:
440 hdev->stat.acl_tx++;
441 break;
442 case HCI_SCODATA_PKT:
443 hdev->stat.sco_tx++;
444 break;
445 };
446
447 /* Prepend skb with frame type */
0d48d939 448 memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
1da177e4
LT
449 skb_queue_tail(&(info->txq), skb);
450
451 spin_lock_irqsave(&(info->lock), flags);
452
453 bt3c_write_wakeup(info);
454
455 spin_unlock_irqrestore(&(info->lock), flags);
456
457 return 0;
458}
459
460
461static void bt3c_hci_destruct(struct hci_dev *hdev)
462{
463}
464
465
466static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
467{
468 return -ENOIOCTLCMD;
469}
470
471
472
473/* ======================== Card services HCI interaction ======================== */
474
475
8187b4fb
DW
476static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware,
477 int count)
1da177e4
LT
478{
479 char *ptr = (char *) firmware;
480 char b[9];
481 unsigned int iobase, size, addr, fcs, tmp;
482 int i, err = 0;
483
fd238232 484 iobase = info->p_dev->io.BasePort1;
1da177e4
LT
485
486 /* Reset */
487 bt3c_io_write(iobase, 0x8040, 0x0404);
488 bt3c_io_write(iobase, 0x8040, 0x0400);
489
490 udelay(1);
491
492 bt3c_io_write(iobase, 0x8040, 0x0404);
493
494 udelay(17);
495
496 /* Load */
497 while (count) {
498 if (ptr[0] != 'S') {
499 BT_ERR("Bad address in firmware");
500 err = -EFAULT;
501 goto error;
502 }
503
504 memset(b, 0, sizeof(b));
505 memcpy(b, ptr + 2, 2);
51a6fbc8 506 size = simple_strtoul(b, NULL, 16);
1da177e4
LT
507
508 memset(b, 0, sizeof(b));
509 memcpy(b, ptr + 4, 8);
51a6fbc8 510 addr = simple_strtoul(b, NULL, 16);
1da177e4
LT
511
512 memset(b, 0, sizeof(b));
513 memcpy(b, ptr + (size * 2) + 2, 2);
51a6fbc8 514 fcs = simple_strtoul(b, NULL, 16);
1da177e4
LT
515
516 memset(b, 0, sizeof(b));
517 for (tmp = 0, i = 0; i < size; i++) {
518 memcpy(b, ptr + (i * 2) + 2, 2);
519 tmp += simple_strtol(b, NULL, 16);
520 }
521
522 if (((tmp + fcs) & 0xff) != 0xff) {
523 BT_ERR("Checksum error in firmware");
524 err = -EILSEQ;
525 goto error;
526 }
527
528 if (ptr[1] == '3') {
529 bt3c_address(iobase, addr);
530
531 memset(b, 0, sizeof(b));
532 for (i = 0; i < (size - 4) / 2; i++) {
533 memcpy(b, ptr + (i * 4) + 12, 4);
51a6fbc8 534 tmp = simple_strtoul(b, NULL, 16);
1da177e4
LT
535 bt3c_put(iobase, tmp);
536 }
537 }
538
539 ptr += (size * 2) + 6;
540 count -= (size * 2) + 6;
541 }
542
543 udelay(17);
544
545 /* Boot */
546 bt3c_address(iobase, 0x3000);
547 outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL);
548
549error:
550 udelay(17);
551
552 /* Clear */
553 bt3c_io_write(iobase, 0x7006, 0x0000);
554 bt3c_io_write(iobase, 0x7005, 0x0000);
555 bt3c_io_write(iobase, 0x7001, 0x0000);
556
557 return err;
558}
559
560
561static int bt3c_open(bt3c_info_t *info)
562{
563 const struct firmware *firmware;
564 struct hci_dev *hdev;
565 int err;
566
567 spin_lock_init(&(info->lock));
568
569 skb_queue_head_init(&(info->txq));
570
571 info->rx_state = RECV_WAIT_PACKET_TYPE;
572 info->rx_count = 0;
573 info->rx_skb = NULL;
574
575 /* Initialize HCI device */
576 hdev = hci_alloc_dev();
577 if (!hdev) {
578 BT_ERR("Can't allocate HCI device");
579 return -ENOMEM;
580 }
581
582 info->hdev = hdev;
583
c13854ce 584 hdev->bus = HCI_PCCARD;
1da177e4 585 hdev->driver_data = info;
27d35284 586 SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
1da177e4
LT
587
588 hdev->open = bt3c_hci_open;
589 hdev->close = bt3c_hci_close;
590 hdev->flush = bt3c_hci_flush;
591 hdev->send = bt3c_hci_send_frame;
592 hdev->destruct = bt3c_hci_destruct;
593 hdev->ioctl = bt3c_hci_ioctl;
594
595 hdev->owner = THIS_MODULE;
596
597 /* Load firmware */
fd238232 598 err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
1da177e4
LT
599 if (err < 0) {
600 BT_ERR("Firmware request failed");
601 goto error;
602 }
603
604 err = bt3c_load_firmware(info, firmware->data, firmware->size);
605
606 release_firmware(firmware);
607
608 if (err < 0) {
609 BT_ERR("Firmware loading failed");
610 goto error;
611 }
612
613 /* Timeout before it is safe to send the first HCI packet */
614 msleep(1000);
615
616 /* Register HCI device */
617 err = hci_register_dev(hdev);
618 if (err < 0) {
619 BT_ERR("Can't register HCI device");
620 goto error;
621 }
622
623 return 0;
624
625error:
626 info->hdev = NULL;
627 hci_free_dev(hdev);
628 return err;
629}
630
631
632static int bt3c_close(bt3c_info_t *info)
633{
634 struct hci_dev *hdev = info->hdev;
635
636 if (!hdev)
637 return -ENODEV;
638
639 bt3c_hci_close(hdev);
640
641 if (hci_unregister_dev(hdev) < 0)
642 BT_ERR("Can't unregister HCI device %s", hdev->name);
643
644 hci_free_dev(hdev);
645
646 return 0;
647}
648
15b99ac1 649static int bt3c_probe(struct pcmcia_device *link)
1da177e4
LT
650{
651 bt3c_info_t *info;
1da177e4
LT
652
653 /* Create new info device */
089b1dbb 654 info = kzalloc(sizeof(*info), GFP_KERNEL);
1da177e4 655 if (!info)
f8cfa618 656 return -ENOMEM;
1da177e4 657
fba395ee 658 info->p_dev = link;
1da177e4
LT
659 link->priv = info;
660
661 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
662 link->io.NumPorts1 = 8;
1da177e4
LT
663
664 link->conf.Attributes = CONF_ENABLE_IRQ;
1da177e4
LT
665 link->conf.IntType = INT_MEMORY_AND_IO;
666
15b99ac1 667 return bt3c_config(link);
1da177e4
LT
668}
669
670
fba395ee 671static void bt3c_detach(struct pcmcia_device *link)
1da177e4
LT
672{
673 bt3c_info_t *info = link->priv;
1da177e4 674
e2d40963 675 bt3c_release(link);
1da177e4
LT
676 kfree(info);
677}
678
ed58872a
DB
679static int bt3c_check_config(struct pcmcia_device *p_dev,
680 cistpl_cftable_entry_t *cf,
8e2fc39d 681 cistpl_cftable_entry_t *dflt,
ad913c11 682 unsigned int vcc,
ed58872a 683 void *priv_data)
1da177e4 684{
ed58872a
DB
685 unsigned long try = (unsigned long) priv_data;
686
687 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
688 p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
689 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
690 (cf->io.win[0].base != 0)) {
ed58872a
DB
691 p_dev->io.BasePort1 = cf->io.win[0].base;
692 p_dev->io.IOAddrLines = (try == 0) ? 16 :
693 cf->io.flags & CISTPL_IO_LINES_MASK;
694 if (!pcmcia_request_io(p_dev, &p_dev->io))
695 return 0;
696 }
697 return -ENODEV;
1da177e4
LT
698}
699
ed58872a
DB
700static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
701 cistpl_cftable_entry_t *cf,
8e2fc39d 702 cistpl_cftable_entry_t *dflt,
ad913c11 703 unsigned int vcc,
ed58872a 704 void *priv_data)
1da177e4 705{
ed58872a
DB
706 static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
707 int j;
708
709 if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
ed58872a
DB
710 for (j = 0; j < 5; j++) {
711 p_dev->io.BasePort1 = base[j];
712 p_dev->io.IOAddrLines = base[j] ? 16 : 3;
713 if (!pcmcia_request_io(p_dev, &p_dev->io))
714 return 0;
715 }
716 }
717 return -ENODEV;
1da177e4
LT
718}
719
15b99ac1 720static int bt3c_config(struct pcmcia_device *link)
1da177e4 721{
1da177e4 722 bt3c_info_t *info = link->priv;
ed58872a
DB
723 int i;
724 unsigned long try;
725
726 /* First pass: look for a config entry that looks normal.
727 Two tries: without IO aliases, then with aliases */
728 for (try = 0; try < 2; try++)
729 if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
730 goto found_port;
1da177e4
LT
731
732 /* Second pass: try to find an entry that isn't picky about
733 its base address, then try to grab any standard serial port
734 address, and finally try to get any free port. */
ed58872a
DB
735 if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
736 goto found_port;
1da177e4 737
ed58872a 738 BT_ERR("No usable port range found");
ed58872a 739 goto failed;
1da177e4 740
ed58872a 741found_port:
eb14120f 742 i = pcmcia_request_irq(link, &bt3c_interrupt);
9ac3e58c 743 if (i != 0)
eb14120f 744 goto failed;
1da177e4 745
fba395ee 746 i = pcmcia_request_configuration(link, &link->conf);
9ac3e58c 747 if (i != 0)
1da177e4 748 goto failed;
1da177e4
LT
749
750 if (bt3c_open(info) != 0)
751 goto failed;
752
15b99ac1 753 return 0;
1da177e4 754
1da177e4
LT
755failed:
756 bt3c_release(link);
15b99ac1 757 return -ENODEV;
1da177e4
LT
758}
759
760
fba395ee 761static void bt3c_release(struct pcmcia_device *link)
1da177e4
LT
762{
763 bt3c_info_t *info = link->priv;
764
e2d40963 765 bt3c_close(info);
1da177e4 766
fba395ee 767 pcmcia_disable_device(link);
1da177e4
LT
768}
769
1da177e4 770
a01c3ed4
DB
771static struct pcmcia_device_id bt3c_ids[] = {
772 PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
773 PCMCIA_DEVICE_NULL
774};
775MODULE_DEVICE_TABLE(pcmcia, bt3c_ids);
776
1da177e4
LT
777static struct pcmcia_driver bt3c_driver = {
778 .owner = THIS_MODULE,
779 .drv = {
780 .name = "bt3c_cs",
781 },
15b99ac1 782 .probe = bt3c_probe,
cc3b4866 783 .remove = bt3c_detach,
a01c3ed4 784 .id_table = bt3c_ids,
1da177e4
LT
785};
786
787static int __init init_bt3c_cs(void)
788{
789 return pcmcia_register_driver(&bt3c_driver);
790}
791
792
793static void __exit exit_bt3c_cs(void)
794{
795 pcmcia_unregister_driver(&bt3c_driver);
1da177e4
LT
796}
797
798module_init(init_bt3c_cs);
799module_exit(exit_bt3c_cs);
This page took 1.062666 seconds and 5 git commands to generate.