3 * Driver for the 3Com Bluetooth PCMCIA card
5 * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
6 * Jose Orlando Pereira <jop@di.uminho.pt>
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;
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.
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.
24 #include <linux/config.h>
25 #include <linux/module.h>
27 #include <linux/kernel.h>
28 #include <linux/kmod.h>
29 #include <linux/init.h>
30 #include <linux/slab.h>
31 #include <linux/types.h>
32 #include <linux/sched.h>
33 #include <linux/delay.h>
34 #include <linux/timer.h>
35 #include <linux/errno.h>
36 #include <linux/unistd.h>
37 #include <linux/ptrace.h>
38 #include <linux/ioport.h>
39 #include <linux/spinlock.h>
41 #include <linux/skbuff.h>
42 #include <linux/string.h>
43 #include <linux/serial.h>
44 #include <linux/serial_reg.h>
45 #include <asm/system.h>
46 #include <asm/bitops.h>
49 #include <linux/firmware.h>
51 #include <pcmcia/version.h>
52 #include <pcmcia/cs_types.h>
53 #include <pcmcia/cs.h>
54 #include <pcmcia/cistpl.h>
55 #include <pcmcia/ciscode.h>
56 #include <pcmcia/ds.h>
57 #include <pcmcia/cisreg.h>
59 #include <net/bluetooth/bluetooth.h>
60 #include <net/bluetooth/hci_core.h>
64 /* ======================== Module parameters ======================== */
67 /* Bit map of interrupts to choose from */
68 static u_int irq_mask = 0xffff;
69 static int irq_list[4] = { -1 };
71 MODULE_PARM(irq_mask, "i");
72 MODULE_PARM(irq_list, "1-4i");
74 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
75 MODULE_DESCRIPTION("BlueZ driver for the 3Com Bluetooth PCMCIA card");
76 MODULE_LICENSE("GPL");
80 /* ======================== Local structures ======================== */
83 typedef struct bt3c_info_t {
89 spinlock_t lock; /* For serializing operations */
91 struct sk_buff_head txq;
92 unsigned long tx_state;
94 unsigned long rx_state;
95 unsigned long rx_count;
96 struct sk_buff *rx_skb;
100 void bt3c_config(dev_link_t *link);
101 void bt3c_release(u_long arg);
102 int bt3c_event(event_t event, int priority, event_callback_args_t *args);
104 static dev_info_t dev_info = "bt3c_cs";
106 dev_link_t *bt3c_attach(void);
107 void bt3c_detach(dev_link_t *);
109 static dev_link_t *dev_list = NULL;
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 /* ======================== Special I/O functions ======================== */
136 inline void bt3c_address(unsigned int iobase, unsigned short addr)
138 outb(addr & 0xff, iobase + ADDR_L);
139 outb((addr >> 8) & 0xff, iobase + ADDR_H);
143 inline void bt3c_put(unsigned int iobase, unsigned short value)
145 outb(value & 0xff, iobase + DATA_L);
146 outb((value >> 8) & 0xff, iobase + DATA_H);
150 inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
152 bt3c_address(iobase, addr);
153 bt3c_put(iobase, value);
157 inline unsigned short bt3c_get(unsigned int iobase)
159 unsigned short value = inb(iobase + DATA_L);
161 value |= inb(iobase + DATA_H) << 8;
167 inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
169 bt3c_address(iobase, addr);
171 return bt3c_get(iobase);
176 /* ======================== Interrupt handling ======================== */
179 static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
183 bt3c_address(iobase, 0x7080);
185 /* Fill FIFO with current frame */
186 while (actual < len) {
187 /* Transmit next byte */
188 bt3c_put(iobase, buf[actual]);
192 bt3c_io_write(iobase, 0x7005, actual);
198 static void bt3c_write_wakeup(bt3c_info_t *info, int from)
203 printk(KERN_WARNING "bt3c_cs: Call of write_wakeup for unknown device.\n");
207 if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
210 spin_lock_irqsave(&(info->lock), flags);
213 register unsigned int iobase = info->link.io.BasePort1;
214 register struct sk_buff *skb;
217 if (!(info->link.state & DEV_PRESENT))
221 if (!(skb = skb_dequeue(&(info->txq)))) {
222 clear_bit(XMIT_SENDING, &(info->tx_state));
227 len = bt3c_write(iobase, 256, skb->data, skb->len);
229 if (len != skb->len) {
230 printk(KERN_WARNING "bt3c_cs: very strange\n");
235 info->hdev.stat.byte_tx += len;
239 spin_unlock_irqrestore(&(info->lock), flags);
243 static void bt3c_receive(bt3c_info_t *info)
249 printk(KERN_WARNING "bt3c_cs: Call of receive for unknown device.\n");
253 iobase = info->link.io.BasePort1;
255 avail = bt3c_read(iobase, 0x7006);
256 //printk("bt3c_cs: receiving %d bytes\n", avail);
258 bt3c_address(iobase, 0x7480);
259 while (size < avail) {
261 info->hdev.stat.byte_rx++;
263 /* Allocate packet */
264 if (info->rx_skb == NULL) {
265 info->rx_state = RECV_WAIT_PACKET_TYPE;
267 if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
268 printk(KERN_WARNING "bt3c_cs: Can't allocate mem for new packet.\n");
274 if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
276 info->rx_skb->dev = (void *)&(info->hdev);
277 info->rx_skb->pkt_type = inb(iobase + DATA_L);
278 inb(iobase + DATA_H);
279 //printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type);
281 switch (info->rx_skb->pkt_type) {
284 info->rx_state = RECV_WAIT_EVENT_HEADER;
285 info->rx_count = HCI_EVENT_HDR_SIZE;
288 case HCI_ACLDATA_PKT:
289 info->rx_state = RECV_WAIT_ACL_HEADER;
290 info->rx_count = HCI_ACL_HDR_SIZE;
293 case HCI_SCODATA_PKT:
294 info->rx_state = RECV_WAIT_SCO_HEADER;
295 info->rx_count = HCI_SCO_HDR_SIZE;
300 printk(KERN_WARNING "bt3c_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
301 info->hdev.stat.err_rx++;
302 clear_bit(HCI_RUNNING, &(info->hdev.flags));
304 kfree_skb(info->rx_skb);
312 __u8 x = inb(iobase + DATA_L);
314 *skb_put(info->rx_skb, 1) = x;
315 inb(iobase + DATA_H);
318 if (info->rx_count == 0) {
325 switch (info->rx_state) {
327 case RECV_WAIT_EVENT_HEADER:
328 eh = (hci_event_hdr *)(info->rx_skb->data);
329 info->rx_state = RECV_WAIT_DATA;
330 info->rx_count = eh->plen;
333 case RECV_WAIT_ACL_HEADER:
334 ah = (hci_acl_hdr *)(info->rx_skb->data);
335 dlen = __le16_to_cpu(ah->dlen);
336 info->rx_state = RECV_WAIT_DATA;
337 info->rx_count = dlen;
340 case RECV_WAIT_SCO_HEADER:
341 sh = (hci_sco_hdr *)(info->rx_skb->data);
342 info->rx_state = RECV_WAIT_DATA;
343 info->rx_count = sh->dlen;
347 hci_recv_frame(info->rx_skb);
359 bt3c_io_write(iobase, 0x7006, 0x0000);
363 void bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
365 bt3c_info_t *info = dev_inst;
370 printk(KERN_WARNING "bt3c_cs: Call of irq %d for unknown device.\n", irq);
374 iobase = info->link.io.BasePort1;
376 spin_lock(&(info->lock));
378 iir = inb(iobase + CONTROL);
380 int stat = bt3c_read(iobase, 0x7001);
382 if ((stat & 0xff) == 0x7f) {
383 printk(KERN_WARNING "bt3c_cs: STRANGE stat=%04x\n", stat);
384 } else if ((stat & 0xff) != 0xff) {
386 int stat = bt3c_read(iobase, 0x7002) & 0x10;
387 printk(KERN_WARNING "bt3c_cs: antena %s\n", stat ? "OUT" : "IN");
392 //printk("bt3c_cs: ACK %04x\n", stat);
393 clear_bit(XMIT_SENDING, &(info->tx_state));
394 bt3c_write_wakeup(info, 1);
397 bt3c_io_write(iobase, 0x7001, 0x0000);
399 outb(iir, iobase + CONTROL);
403 spin_unlock(&(info->lock));
409 /* ======================== HCI interface ======================== */
412 static int bt3c_hci_flush(struct hci_dev *hdev)
414 bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
417 skb_queue_purge(&(info->txq));
423 static int bt3c_hci_open(struct hci_dev *hdev)
425 set_bit(HCI_RUNNING, &(hdev->flags));
431 static int bt3c_hci_close(struct hci_dev *hdev)
433 if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
436 bt3c_hci_flush(hdev);
442 static int bt3c_hci_send_frame(struct sk_buff *skb)
445 struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
448 printk(KERN_WARNING "bt3c_cs: Frame for unknown HCI device (hdev=NULL).");
452 info = (bt3c_info_t *) (hdev->driver_data);
454 switch (skb->pkt_type) {
455 case HCI_COMMAND_PKT:
458 case HCI_ACLDATA_PKT:
461 case HCI_SCODATA_PKT:
466 /* Prepend skb with frame type */
467 memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
468 skb_queue_tail(&(info->txq), skb);
470 bt3c_write_wakeup(info, 0);
476 static void bt3c_hci_destruct(struct hci_dev *hdev)
481 static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
488 /* ======================== Card services HCI interaction ======================== */
491 static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count)
493 char *ptr = (char *) firmware;
495 unsigned int iobase, size, addr, fcs, tmp;
498 iobase = info->link.io.BasePort1;
502 bt3c_io_write(iobase, 0x8040, 0x0404);
503 bt3c_io_write(iobase, 0x8040, 0x0400);
507 bt3c_io_write(iobase, 0x8040, 0x0404);
515 printk(KERN_WARNING "bt3c_cs: Bad address in firmware.\n");
520 memset(b, 0, sizeof(b));
521 memcpy(b, ptr + 2, 2);
522 size = simple_strtol(b, NULL, 16);
524 memset(b, 0, sizeof(b));
525 memcpy(b, ptr + 4, 8);
526 addr = simple_strtol(b, NULL, 16);
528 memset(b, 0, sizeof(b));
529 memcpy(b, ptr + (size * 2) + 2, 2);
530 fcs = simple_strtol(b, NULL, 16);
532 memset(b, 0, sizeof(b));
533 for (tmp = 0, i = 0; i < size; i++) {
534 memcpy(b, ptr + (i * 2) + 2, 2);
535 tmp += simple_strtol(b, NULL, 16);
538 if (((tmp + fcs) & 0xff) != 0xff) {
539 printk(KERN_WARNING "bt3c_cs: Checksum error in firmware.\n");
545 bt3c_address(iobase, addr);
547 memset(b, 0, sizeof(b));
548 for (i = 0; i < (size - 4) / 2; i++) {
549 memcpy(b, ptr + (i * 4) + 12, 4);
550 tmp = simple_strtol(b, NULL, 16);
551 bt3c_put(iobase, tmp);
555 ptr += (size * 2) + 6;
556 count -= (size * 2) + 6;
563 bt3c_address(iobase, 0x3000);
564 outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL);
571 bt3c_io_write(iobase, 0x7006, 0x0000);
572 bt3c_io_write(iobase, 0x7005, 0x0000);
573 bt3c_io_write(iobase, 0x7001, 0x0000);
579 int bt3c_open(bt3c_info_t *info)
581 const struct firmware *firmware;
583 struct hci_dev *hdev;
586 spin_lock_init(&(info->lock));
588 skb_queue_head_init(&(info->txq));
590 info->rx_state = RECV_WAIT_PACKET_TYPE;
596 snprintf(device, sizeof(device), "bt3c%4.4x", info->link.io.BasePort1);
598 err = request_firmware(&firmware, "BT3CPCC.bin", device);
600 printk(KERN_WARNING "bt3c_cs: Firmware request failed.\n");
604 err = bt3c_load_firmware(info, firmware->data, firmware->size);
606 release_firmware(firmware);
609 printk(KERN_WARNING "bt3c_cs: Firmware loading failed.\n");
613 /* Timeout before it is safe to send the first HCI packet */
615 set_current_state(TASK_INTERRUPTIBLE);
616 schedule_timeout(HZ);
619 /* Initialize and register HCI device */
621 hdev = &(info->hdev);
623 hdev->type = HCI_PCCARD;
624 hdev->driver_data = info;
626 hdev->open = bt3c_hci_open;
627 hdev->close = bt3c_hci_close;
628 hdev->flush = bt3c_hci_flush;
629 hdev->send = bt3c_hci_send_frame;
630 hdev->destruct = bt3c_hci_destruct;
631 hdev->ioctl = bt3c_hci_ioctl;
633 if (hci_register_dev(hdev) < 0) {
634 printk(KERN_WARNING "bt3c_cs: Can't register HCI device %s.\n", hdev->name);
642 int bt3c_close(bt3c_info_t *info)
644 struct hci_dev *hdev = &(info->hdev);
646 if (info->link.state & DEV_CONFIG_PENDING)
649 bt3c_hci_close(hdev);
651 if (hci_unregister_dev(hdev) < 0)
652 printk(KERN_WARNING "bt3c_cs: Can't unregister HCI device %s.\n", hdev->name);
659 /* ======================== Card services ======================== */
662 static void cs_error(client_handle_t handle, int func, int ret)
664 error_info_t err = { func, ret };
666 CardServices(ReportError, handle, &err);
670 dev_link_t *bt3c_attach(void)
673 client_reg_t client_reg;
677 /* Create new info device */
678 info = kmalloc(sizeof(*info), GFP_KERNEL);
681 memset(info, 0, sizeof(*info));
686 link->release.function = &bt3c_release;
687 link->release.data = (u_long)link;
688 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
689 link->io.NumPorts1 = 8;
690 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
691 link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
693 if (irq_list[0] == -1)
694 link->irq.IRQInfo2 = irq_mask;
696 for (i = 0; i < 4; i++)
697 link->irq.IRQInfo2 |= 1 << irq_list[i];
699 link->irq.Handler = bt3c_interrupt;
700 link->irq.Instance = info;
702 link->conf.Attributes = CONF_ENABLE_IRQ;
704 link->conf.IntType = INT_MEMORY_AND_IO;
706 /* Register with Card Services */
707 link->next = dev_list;
709 client_reg.dev_info = &dev_info;
710 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
711 client_reg.EventMask =
712 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
713 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
714 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
715 client_reg.event_handler = &bt3c_event;
716 client_reg.Version = 0x0210;
717 client_reg.event_callback_args.client_data = link;
719 ret = CardServices(RegisterClient, &link->handle, &client_reg);
720 if (ret != CS_SUCCESS) {
721 cs_error(link->handle, RegisterClient, ret);
730 void bt3c_detach(dev_link_t *link)
732 bt3c_info_t *info = link->priv;
736 /* Locate device structure */
737 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
744 del_timer(&link->release);
746 if (link->state & DEV_CONFIG)
747 bt3c_release((u_long)link);
750 ret = CardServices(DeregisterClient, link->handle);
751 if (ret != CS_SUCCESS)
752 cs_error(link->handle, DeregisterClient, ret);
755 /* Unlink device structure, free bits */
762 static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
766 i = CardServices(fn, handle, tuple);
768 return CS_NO_MORE_ITEMS;
770 i = CardServices(GetTupleData, handle, tuple);
774 return CardServices(ParseTuple, handle, tuple, parse);
778 #define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
779 #define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
781 void bt3c_config(dev_link_t *link)
783 static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
784 client_handle_t handle = link->handle;
785 bt3c_info_t *info = link->priv;
789 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
790 config_info_t config;
791 int i, j, try, last_ret, last_fn;
793 tuple.TupleData = (cisdata_t *)buf;
794 tuple.TupleOffset = 0;
795 tuple.TupleDataMax = 255;
796 tuple.Attributes = 0;
798 /* Get configuration register information */
799 tuple.DesiredTuple = CISTPL_CONFIG;
800 last_ret = first_tuple(handle, &tuple, &parse);
801 if (last_ret != CS_SUCCESS) {
802 last_fn = ParseTuple;
805 link->conf.ConfigBase = parse.config.base;
806 link->conf.Present = parse.config.rmask[0];
809 link->state |= DEV_CONFIG;
810 i = CardServices(GetConfigurationInfo, handle, &config);
811 link->conf.Vcc = config.Vcc;
813 /* First pass: look for a config entry that looks normal. */
814 tuple.TupleData = (cisdata_t *)buf;
815 tuple.TupleOffset = 0;
816 tuple.TupleDataMax = 255;
817 tuple.Attributes = 0;
818 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
819 /* Two tries: without IO aliases, then with aliases */
820 for (try = 0; try < 2; try++) {
821 i = first_tuple(handle, &tuple, &parse);
822 while (i != CS_NO_MORE_ITEMS) {
825 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
826 link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
827 if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
828 link->conf.ConfigIndex = cf->index;
829 link->io.BasePort1 = cf->io.win[0].base;
830 link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
831 i = CardServices(RequestIO, link->handle, &link->io);
836 i = next_tuple(handle, &tuple, &parse);
840 /* Second pass: try to find an entry that isn't picky about
841 its base address, then try to grab any standard serial port
842 address, and finally try to get any free port. */
843 i = first_tuple(handle, &tuple, &parse);
844 while (i != CS_NO_MORE_ITEMS) {
845 if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
846 link->conf.ConfigIndex = cf->index;
847 for (j = 0; j < 5; j++) {
848 link->io.BasePort1 = base[j];
849 link->io.IOAddrLines = base[j] ? 16 : 3;
850 i = CardServices(RequestIO, link->handle, &link->io);
855 i = next_tuple(handle, &tuple, &parse);
859 if (i != CS_SUCCESS) {
860 printk(KERN_NOTICE "bt3c_cs: No usable port range found. Giving up.\n");
861 cs_error(link->handle, RequestIO, i);
865 i = CardServices(RequestIRQ, link->handle, &link->irq);
866 if (i != CS_SUCCESS) {
867 cs_error(link->handle, RequestIRQ, i);
868 link->irq.AssignedIRQ = 0;
871 i = CardServices(RequestConfiguration, link->handle, &link->conf);
872 if (i != CS_SUCCESS) {
873 cs_error(link->handle, RequestConfiguration, i);
879 if (bt3c_open(info) != 0)
882 strcpy(info->node.dev_name, info->hdev.name);
883 link->dev = &info->node;
884 link->state &= ~DEV_CONFIG_PENDING;
889 cs_error(link->handle, last_fn, last_ret);
892 bt3c_release((u_long)link);
896 void bt3c_release(u_long arg)
898 dev_link_t *link = (dev_link_t *)arg;
899 bt3c_info_t *info = link->priv;
901 if (link->state & DEV_PRESENT)
908 CardServices(ReleaseConfiguration, link->handle);
909 CardServices(ReleaseIO, link->handle, &link->io);
910 CardServices(ReleaseIRQ, link->handle, &link->irq);
912 link->state &= ~DEV_CONFIG;
916 int bt3c_event(event_t event, int priority, event_callback_args_t *args)
918 dev_link_t *link = args->client_data;
919 bt3c_info_t *info = link->priv;
922 case CS_EVENT_CARD_REMOVAL:
923 link->state &= ~DEV_PRESENT;
924 if (link->state & DEV_CONFIG) {
926 mod_timer(&link->release, jiffies + HZ / 20);
929 case CS_EVENT_CARD_INSERTION:
930 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
933 case CS_EVENT_PM_SUSPEND:
934 link->state |= DEV_SUSPEND;
935 /* Fall through... */
936 case CS_EVENT_RESET_PHYSICAL:
937 if (link->state & DEV_CONFIG)
938 CardServices(ReleaseConfiguration, link->handle);
940 case CS_EVENT_PM_RESUME:
941 link->state &= ~DEV_SUSPEND;
942 /* Fall through... */
943 case CS_EVENT_CARD_RESET:
945 CardServices(RequestConfiguration, link->handle, &link->conf);
954 /* ======================== Module initialization ======================== */
957 int __init init_bt3c_cs(void)
962 CardServices(GetCardServicesInfo, &serv);
963 if (serv.Revision != CS_RELEASE_CODE) {
964 printk(KERN_NOTICE "bt3c_cs: Card Services release does not match!\n");
968 err = register_pccard_driver(&dev_info, &bt3c_attach, &bt3c_detach);
974 void __exit exit_bt3c_cs(void)
976 unregister_pccard_driver(&dev_info);
978 while (dev_list != NULL)
979 bt3c_detach(dev_list);
983 module_init(init_bt3c_cs);
984 module_exit(exit_bt3c_cs);