linux/drivers/bluetooth/btuart_cs.c
<<
>>
Prefs
   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/module.h>
  24
  25#include <linux/kernel.h>
  26#include <linux/init.h>
  27#include <linux/slab.h>
  28#include <linux/types.h>
  29#include <linux/delay.h>
  30#include <linux/errno.h>
  31#include <linux/ptrace.h>
  32#include <linux/ioport.h>
  33#include <linux/spinlock.h>
  34#include <linux/moduleparam.h>
  35
  36#include <linux/skbuff.h>
  37#include <linux/string.h>
  38#include <linux/serial.h>
  39#include <linux/serial_reg.h>
  40#include <linux/bitops.h>
  41#include <asm/io.h>
  42
  43#include <pcmcia/cistpl.h>
  44#include <pcmcia/ciscode.h>
  45#include <pcmcia/ds.h>
  46#include <pcmcia/cisreg.h>
  47
  48#include <net/bluetooth/bluetooth.h>
  49#include <net/bluetooth/hci_core.h>
  50
  51
  52
  53/* ======================== Module parameters ======================== */
  54
  55
  56MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
  57MODULE_DESCRIPTION("Bluetooth driver for Bluetooth PCMCIA cards with HCI UART interface");
  58MODULE_LICENSE("GPL");
  59
  60
  61
  62/* ======================== Local structures ======================== */
  63
  64
  65typedef struct btuart_info_t {
  66        struct pcmcia_device *p_dev;
  67
  68        struct hci_dev *hdev;
  69
  70        spinlock_t lock;        /* For serializing operations */
  71
  72        struct sk_buff_head txq;
  73        unsigned long tx_state;
  74
  75        unsigned long rx_state;
  76        unsigned long rx_count;
  77        struct sk_buff *rx_skb;
  78} btuart_info_t;
  79
  80
  81static int btuart_config(struct pcmcia_device *link);
  82static void btuart_release(struct pcmcia_device *link);
  83
  84static void btuart_detach(struct pcmcia_device *p_dev);
  85
  86
  87/* Maximum baud rate */
  88#define SPEED_MAX  115200
  89
  90/* Default baud rate: 57600, 115200, 230400 or 460800 */
  91#define DEFAULT_BAUD_RATE  115200
  92
  93
  94/* Transmit states  */
  95#define XMIT_SENDING    1
  96#define XMIT_WAKEUP     2
  97#define XMIT_WAITING    8
  98
  99/* Receiver states */
 100#define RECV_WAIT_PACKET_TYPE   0
 101#define RECV_WAIT_EVENT_HEADER  1
 102#define RECV_WAIT_ACL_HEADER    2
 103#define RECV_WAIT_SCO_HEADER    3
 104#define RECV_WAIT_DATA          4
 105
 106
 107
 108/* ======================== Interrupt handling ======================== */
 109
 110
 111static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
 112{
 113        int actual = 0;
 114
 115        /* Tx FIFO should be empty */
 116        if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
 117                return 0;
 118
 119        /* Fill FIFO with current frame */
 120        while ((fifo_size-- > 0) && (actual < len)) {
 121                /* Transmit next byte */
 122                outb(buf[actual], iobase + UART_TX);
 123                actual++;
 124        }
 125
 126        return actual;
 127}
 128
 129
 130static void btuart_write_wakeup(btuart_info_t *info)
 131{
 132        if (!info) {
 133                BT_ERR("Unknown device");
 134                return;
 135        }
 136
 137        if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
 138                set_bit(XMIT_WAKEUP, &(info->tx_state));
 139                return;
 140        }
 141
 142        do {
 143                unsigned int iobase = info->p_dev->resource[0]->start;
 144                register struct sk_buff *skb;
 145                int len;
 146
 147                clear_bit(XMIT_WAKEUP, &(info->tx_state));
 148
 149                if (!pcmcia_dev_present(info->p_dev))
 150                        return;
 151
 152                if (!(skb = skb_dequeue(&(info->txq))))
 153                        break;
 154
 155                /* Send frame */
 156                len = btuart_write(iobase, 16, skb->data, skb->len);
 157                set_bit(XMIT_WAKEUP, &(info->tx_state));
 158
 159                if (len == skb->len) {
 160                        kfree_skb(skb);
 161                } else {
 162                        skb_pull(skb, len);
 163                        skb_queue_head(&(info->txq), skb);
 164                }
 165
 166                info->hdev->stat.byte_tx += len;
 167
 168        } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
 169
 170        clear_bit(XMIT_SENDING, &(info->tx_state));
 171}
 172
 173
 174static void btuart_receive(btuart_info_t *info)
 175{
 176        unsigned int iobase;
 177        int boguscount = 0;
 178
 179        if (!info) {
 180                BT_ERR("Unknown device");
 181                return;
 182        }
 183
 184        iobase = info->p_dev->resource[0]->start;
 185
 186        do {
 187                info->hdev->stat.byte_rx++;
 188
 189                /* Allocate packet */
 190                if (info->rx_skb == NULL) {
 191                        info->rx_state = RECV_WAIT_PACKET_TYPE;
 192                        info->rx_count = 0;
 193                        if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
 194                                BT_ERR("Can't allocate mem for new packet");
 195                                return;
 196                        }
 197                }
 198
 199                if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
 200
 201                        info->rx_skb->dev = (void *) info->hdev;
 202                        bt_cb(info->rx_skb)->pkt_type = inb(iobase + UART_RX);
 203
 204                        switch (bt_cb(info->rx_skb)->pkt_type) {
 205
 206                        case HCI_EVENT_PKT:
 207                                info->rx_state = RECV_WAIT_EVENT_HEADER;
 208                                info->rx_count = HCI_EVENT_HDR_SIZE;
 209                                break;
 210
 211                        case HCI_ACLDATA_PKT:
 212                                info->rx_state = RECV_WAIT_ACL_HEADER;
 213                                info->rx_count = HCI_ACL_HDR_SIZE;
 214                                break;
 215
 216                        case HCI_SCODATA_PKT:
 217                                info->rx_state = RECV_WAIT_SCO_HEADER;
 218                                info->rx_count = HCI_SCO_HDR_SIZE;
 219                                break;
 220
 221                        default:
 222                                /* Unknown packet */
 223                                BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
 224                                info->hdev->stat.err_rx++;
 225                                clear_bit(HCI_RUNNING, &(info->hdev->flags));
 226
 227                                kfree_skb(info->rx_skb);
 228                                info->rx_skb = NULL;
 229                                break;
 230
 231                        }
 232
 233                } else {
 234
 235                        *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
 236                        info->rx_count--;
 237
 238                        if (info->rx_count == 0) {
 239
 240                                int dlen;
 241                                struct hci_event_hdr *eh;
 242                                struct hci_acl_hdr *ah;
 243                                struct hci_sco_hdr *sh;
 244
 245
 246                                switch (info->rx_state) {
 247
 248                                case RECV_WAIT_EVENT_HEADER:
 249                                        eh = hci_event_hdr(info->rx_skb);
 250                                        info->rx_state = RECV_WAIT_DATA;
 251                                        info->rx_count = eh->plen;
 252                                        break;
 253
 254                                case RECV_WAIT_ACL_HEADER:
 255                                        ah = hci_acl_hdr(info->rx_skb);
 256                                        dlen = __le16_to_cpu(ah->dlen);
 257                                        info->rx_state = RECV_WAIT_DATA;
 258                                        info->rx_count = dlen;
 259                                        break;
 260
 261                                case RECV_WAIT_SCO_HEADER:
 262                                        sh = hci_sco_hdr(info->rx_skb);
 263                                        info->rx_state = RECV_WAIT_DATA;
 264                                        info->rx_count = sh->dlen;
 265                                        break;
 266
 267                                case RECV_WAIT_DATA:
 268                                        hci_recv_frame(info->rx_skb);
 269                                        info->rx_skb = NULL;
 270                                        break;
 271
 272                                }
 273
 274                        }
 275
 276                }
 277
 278                /* Make sure we don't stay here too long */
 279                if (boguscount++ > 16)
 280                        break;
 281
 282        } while (inb(iobase + UART_LSR) & UART_LSR_DR);
 283}
 284
 285
 286static irqreturn_t btuart_interrupt(int irq, void *dev_inst)
 287{
 288        btuart_info_t *info = dev_inst;
 289        unsigned int iobase;
 290        int boguscount = 0;
 291        int iir, lsr;
 292        irqreturn_t r = IRQ_NONE;
 293
 294        if (!info || !info->hdev)
 295                /* our irq handler is shared */
 296                return IRQ_NONE;
 297
 298        iobase = info->p_dev->resource[0]->start;
 299
 300        spin_lock(&(info->lock));
 301
 302        iir = inb(iobase + UART_IIR) & UART_IIR_ID;
 303        while (iir) {
 304                r = IRQ_HANDLED;
 305
 306                /* Clear interrupt */
 307                lsr = inb(iobase + UART_LSR);
 308
 309                switch (iir) {
 310                case UART_IIR_RLSI:
 311                        BT_ERR("RLSI");
 312                        break;
 313                case UART_IIR_RDI:
 314                        /* Receive interrupt */
 315                        btuart_receive(info);
 316                        break;
 317                case UART_IIR_THRI:
 318                        if (lsr & UART_LSR_THRE) {
 319                                /* Transmitter ready for data */
 320                                btuart_write_wakeup(info);
 321                        }
 322                        break;
 323                default:
 324                        BT_ERR("Unhandled IIR=%#x", iir);
 325                        break;
 326                }
 327
 328                /* Make sure we don't stay here too long */
 329                if (boguscount++ > 100)
 330                        break;
 331
 332                iir = inb(iobase + UART_IIR) & UART_IIR_ID;
 333
 334        }
 335
 336        spin_unlock(&(info->lock));
 337
 338        return r;
 339}
 340
 341
 342static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
 343{
 344        unsigned long flags;
 345        unsigned int iobase;
 346        int fcr;                /* FIFO control reg */
 347        int lcr;                /* Line control reg */
 348        int divisor;
 349
 350        if (!info) {
 351                BT_ERR("Unknown device");
 352                return;
 353        }
 354
 355        iobase = info->p_dev->resource[0]->start;
 356
 357        spin_lock_irqsave(&(info->lock), flags);
 358
 359        /* Turn off interrupts */
 360        outb(0, iobase + UART_IER);
 361
 362        divisor = SPEED_MAX / speed;
 363
 364        fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
 365
 366        /* 
 367         * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
 368         * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
 369         * about this timeout since it will always be fast enough. 
 370         */
 371
 372        if (speed < 38400)
 373                fcr |= UART_FCR_TRIGGER_1;
 374        else
 375                fcr |= UART_FCR_TRIGGER_14;
 376
 377        /* Bluetooth cards use 8N1 */
 378        lcr = UART_LCR_WLEN8;
 379
 380        outb(UART_LCR_DLAB | lcr, iobase + UART_LCR);   /* Set DLAB */
 381        outb(divisor & 0xff, iobase + UART_DLL);        /* Set speed */
 382        outb(divisor >> 8, iobase + UART_DLM);
 383        outb(lcr, iobase + UART_LCR);   /* Set 8N1  */
 384        outb(fcr, iobase + UART_FCR);   /* Enable FIFO's */
 385
 386        /* Turn on interrupts */
 387        outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
 388
 389        spin_unlock_irqrestore(&(info->lock), flags);
 390}
 391
 392
 393
 394/* ======================== HCI interface ======================== */
 395
 396
 397static int btuart_hci_flush(struct hci_dev *hdev)
 398{
 399        btuart_info_t *info = hci_get_drvdata(hdev);
 400
 401        /* Drop TX queue */
 402        skb_queue_purge(&(info->txq));
 403
 404        return 0;
 405}
 406
 407
 408static int btuart_hci_open(struct hci_dev *hdev)
 409{
 410        set_bit(HCI_RUNNING, &(hdev->flags));
 411
 412        return 0;
 413}
 414
 415
 416static int btuart_hci_close(struct hci_dev *hdev)
 417{
 418        if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
 419                return 0;
 420
 421        btuart_hci_flush(hdev);
 422
 423        return 0;
 424}
 425
 426
 427static int btuart_hci_send_frame(struct sk_buff *skb)
 428{
 429        btuart_info_t *info;
 430        struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
 431
 432        if (!hdev) {
 433                BT_ERR("Frame for unknown HCI device (hdev=NULL)");
 434                return -ENODEV;
 435        }
 436
 437        info = hci_get_drvdata(hdev);
 438
 439        switch (bt_cb(skb)->pkt_type) {
 440        case HCI_COMMAND_PKT:
 441                hdev->stat.cmd_tx++;
 442                break;
 443        case HCI_ACLDATA_PKT:
 444                hdev->stat.acl_tx++;
 445                break;
 446        case HCI_SCODATA_PKT:
 447                hdev->stat.sco_tx++;
 448                break;
 449        };
 450
 451        /* Prepend skb with frame type */
 452        memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
 453        skb_queue_tail(&(info->txq), skb);
 454
 455        btuart_write_wakeup(info);
 456
 457        return 0;
 458}
 459
 460
 461static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
 462{
 463        return -ENOIOCTLCMD;
 464}
 465
 466
 467
 468/* ======================== Card services HCI interaction ======================== */
 469
 470
 471static int btuart_open(btuart_info_t *info)
 472{
 473        unsigned long flags;
 474        unsigned int iobase = info->p_dev->resource[0]->start;
 475        struct hci_dev *hdev;
 476
 477        spin_lock_init(&(info->lock));
 478
 479        skb_queue_head_init(&(info->txq));
 480
 481        info->rx_state = RECV_WAIT_PACKET_TYPE;
 482        info->rx_count = 0;
 483        info->rx_skb = NULL;
 484
 485        /* Initialize HCI device */
 486        hdev = hci_alloc_dev();
 487        if (!hdev) {
 488                BT_ERR("Can't allocate HCI device");
 489                return -ENOMEM;
 490        }
 491
 492        info->hdev = hdev;
 493
 494        hdev->bus = HCI_PCCARD;
 495        hci_set_drvdata(hdev, info);
 496        SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
 497
 498        hdev->open     = btuart_hci_open;
 499        hdev->close    = btuart_hci_close;
 500        hdev->flush    = btuart_hci_flush;
 501        hdev->send     = btuart_hci_send_frame;
 502        hdev->ioctl    = btuart_hci_ioctl;
 503
 504        spin_lock_irqsave(&(info->lock), flags);
 505
 506        /* Reset UART */
 507        outb(0, iobase + UART_MCR);
 508
 509        /* Turn off interrupts */
 510        outb(0, iobase + UART_IER);
 511
 512        /* Initialize UART */
 513        outb(UART_LCR_WLEN8, iobase + UART_LCR);        /* Reset DLAB */
 514        outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
 515
 516        /* Turn on interrupts */
 517        // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
 518
 519        spin_unlock_irqrestore(&(info->lock), flags);
 520
 521        btuart_change_speed(info, DEFAULT_BAUD_RATE);
 522
 523        /* Timeout before it is safe to send the first HCI packet */
 524        msleep(1000);
 525
 526        /* Register HCI device */
 527        if (hci_register_dev(hdev) < 0) {
 528                BT_ERR("Can't register HCI device");
 529                info->hdev = NULL;
 530                hci_free_dev(hdev);
 531                return -ENODEV;
 532        }
 533
 534        return 0;
 535}
 536
 537
 538static int btuart_close(btuart_info_t *info)
 539{
 540        unsigned long flags;
 541        unsigned int iobase = info->p_dev->resource[0]->start;
 542        struct hci_dev *hdev = info->hdev;
 543
 544        if (!hdev)
 545                return -ENODEV;
 546
 547        btuart_hci_close(hdev);
 548
 549        spin_lock_irqsave(&(info->lock), flags);
 550
 551        /* Reset UART */
 552        outb(0, iobase + UART_MCR);
 553
 554        /* Turn off interrupts */
 555        outb(0, iobase + UART_IER);
 556
 557        spin_unlock_irqrestore(&(info->lock), flags);
 558
 559        hci_unregister_dev(hdev);
 560        hci_free_dev(hdev);
 561
 562        return 0;
 563}
 564
 565static int btuart_probe(struct pcmcia_device *link)
 566{
 567        btuart_info_t *info;
 568
 569        /* Create new info device */
 570        info = kzalloc(sizeof(*info), GFP_KERNEL);
 571        if (!info)
 572                return -ENOMEM;
 573
 574        info->p_dev = link;
 575        link->priv = info;
 576
 577        link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
 578                CONF_AUTO_SET_IO;
 579
 580        return btuart_config(link);
 581}
 582
 583
 584static void btuart_detach(struct pcmcia_device *link)
 585{
 586        btuart_info_t *info = link->priv;
 587
 588        btuart_release(link);
 589        kfree(info);
 590}
 591
 592static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data)
 593{
 594        int *try = priv_data;
 595
 596        if (!try)
 597                p_dev->io_lines = 16;
 598
 599        if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))
 600                return -EINVAL;
 601
 602        p_dev->resource[0]->end = 8;
 603        p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
 604        p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
 605
 606        return pcmcia_request_io(p_dev);
 607}
 608
 609static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
 610                                        void *priv_data)
 611{
 612        static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
 613        int j;
 614
 615        if (p_dev->io_lines > 3)
 616                return -ENODEV;
 617
 618        p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
 619        p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
 620        p_dev->resource[0]->end = 8;
 621
 622        for (j = 0; j < 5; j++) {
 623                p_dev->resource[0]->start = base[j];
 624                p_dev->io_lines = base[j] ? 16 : 3;
 625                if (!pcmcia_request_io(p_dev))
 626                        return 0;
 627        }
 628        return -ENODEV;
 629}
 630
 631static int btuart_config(struct pcmcia_device *link)
 632{
 633        btuart_info_t *info = link->priv;
 634        int i;
 635        int try;
 636
 637        /* First pass: look for a config entry that looks normal.
 638           Two tries: without IO aliases, then with aliases */
 639        for (try = 0; try < 2; try++)
 640                if (!pcmcia_loop_config(link, btuart_check_config, &try))
 641                        goto found_port;
 642
 643        /* Second pass: try to find an entry that isn't picky about
 644           its base address, then try to grab any standard serial port
 645           address, and finally try to get any free port. */
 646        if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
 647                goto found_port;
 648
 649        BT_ERR("No usable port range found");
 650        goto failed;
 651
 652found_port:
 653        i = pcmcia_request_irq(link, btuart_interrupt);
 654        if (i != 0)
 655                goto failed;
 656
 657        i = pcmcia_enable_device(link);
 658        if (i != 0)
 659                goto failed;
 660
 661        if (btuart_open(info) != 0)
 662                goto failed;
 663
 664        return 0;
 665
 666failed:
 667        btuart_release(link);
 668        return -ENODEV;
 669}
 670
 671
 672static void btuart_release(struct pcmcia_device *link)
 673{
 674        btuart_info_t *info = link->priv;
 675
 676        btuart_close(info);
 677
 678        pcmcia_disable_device(link);
 679}
 680
 681static const struct pcmcia_device_id btuart_ids[] = {
 682        /* don't use this driver. Use serial_cs + hci_uart instead */
 683        PCMCIA_DEVICE_NULL
 684};
 685MODULE_DEVICE_TABLE(pcmcia, btuart_ids);
 686
 687static struct pcmcia_driver btuart_driver = {
 688        .owner          = THIS_MODULE,
 689        .name           = "btuart_cs",
 690        .probe          = btuart_probe,
 691        .remove         = btuart_detach,
 692        .id_table       = btuart_ids,
 693};
 694
 695static int __init init_btuart_cs(void)
 696{
 697        return pcmcia_register_driver(&btuart_driver);
 698}
 699
 700
 701static void __exit exit_btuart_cs(void)
 702{
 703        pcmcia_unregister_driver(&btuart_driver);
 704}
 705
 706module_init(init_btuart_cs);
 707module_exit(exit_btuart_cs);
 708
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.