linux/drivers/bluetooth/bt3c_cs.c
<<
>>
Prefs
   1/*
   2 *
   3 *  Driver for the 3Com Bluetooth PCMCIA card
   4 *
   5K/optio4option value="v2.6.17.14"
	  >td(C) 2001-2002  Marcel Holtmann <marcel@holtmann.org>
   6K/optio4option value="v2.6.17..........................Jose Orlando Pereira <jop@di.uminho.pt>
   7 *
   8 *
   9K/optio4option value="v2.6.17.This program is free software; you can redistribute it and/or modify
  10  11.17.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
  15K/optio4option value="v2.6.17.implied. See the License for the specific language governing
  16K/optio4option value="v2.6.17.	  >ts and limitations under the License.
  17 *
  18 *7.The initial developer of the o	  inal code is David A. Hinds
  19K/optio4option value="v2.6.17.<dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  20td(C) 1999 David A. Hinds.  All R  >ts Reserved.
  21.1
  22 */
  23
  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/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/io.h>
  43
  44#include <linux/device.h>
  45#include <linux/firmware.h>
  46
  47#include <pcmcia/cistpl.h>
  48#include <pcmcia/ciscode.h>
  49#include <pcmcia/ds.h>
  50#include <pcmcia/cisreg.h>
  51
  52#include <net/bluetooth/bluetooth.h>
  53#include <net/bluetooth/hci_core.h>
  54
  55
  56
  57/* ======================== Module parameters ======================== */
  58
  59
  60MODULE_AUTHOR"Marcel Holtmann <marcel@holtmann.org>");
  61MODULE_DESCRIPTION"Bluetooth driver for the 3Com Bluetooth PCMCIA card");
  62MODULE_LICENSE"GPL");
  63MODULE_FIRMWARE"BT3CPCC.bin");
  64
  65
  66
  67/* ======================== Local structures ======================== */
  68
  69
  70bt3c_info_t  71pcmcia_devicep_dev  72
  73hci_devhdev  74
  75spinlock_tlock/* For serializing operations */
  76
  77sk_buff_headtxq  78tx_state  79
  80rx_state  81rx_count  82sk_buffrx_skb  83bt3c_info_t  84
  85
  86static int ta href="+code=bt3c_config" class="sref">bt3c_configpcmcia_devicelink  87static void ta href="+code=bt3c_release" class="sref">bt3c_releasepcmcia_devicelink  88
  89static void ta href="+code=bt3c_detach" class="sref">bt3c_detachpcmcia_devicep_dev  90
  91
  92/* Transmit states  */
  93#define ta href="+code=XMIT_SENDING" class="sref">XMIT_SENDING  94#define ta href="+code=XMIT_WAKEUP" class="sref">XMIT_WAKEUP  95#define ta href="+code=XMIT_WAITING" class="sref">XMIT_WAITING  96
  97/* Receiver states */
  98#define ta href="+code=RECV_WAIT_PACKET_TYPE" class="sref">RECV_WAIT_PACKET_TYPE  99#define ta href="+code=RECV_WAIT_EVENT_HEADER" class="sref">RECV_WAIT_EVENT_HEADER 100#define ta href="+code=RECV_WAIT_ACL_HEADER" class="sref">RECV_WAIT_ACL_HEADER 101#define ta href="+code=RECV_WAIT_SCO_HEADER" class="sref">RECV_WAIT_SCO_HEADER 102#define ta href="+code=RECV_WAIT_DATA" class="sref">RECV_WAIT_DATA 103
 104
 105
 106K/optio4option value="v2.6/* ======================== Special I/O functions ======================== */
 107
 108
 109#define ta href="+code=DATA_L" class="sref">DATA_L 110#define ta href="+code=DATA_H" class="sref">DATA_H 111#define ta href="+code=ADDR_L" class="sref">ADDR_L 112#define ta href="+code=ADDR_H" class="sref">ADDR_H 113#define ta href="+code=CONTROL" class="sref">CONTROL 114
 115
 116static ta href="+code=inline" class="sref">inlinebt3c_addressiobaseaddr 117{
 118outbaddriobaseADDR_L 119K/op........ta href="+code=outb" class="sref">outbaddriobaseADDR_H 120 121
 122
 123static ta href="+code=inline" class="sref">inlinebt3c_putiobasevalue 124{
 125outbvalueiobaseDATA_L 126........ta href="+code=outb" class="sref">outbvalueiobaseDATA_H 127}
 128
 129
 130static ta href="+code=inline" class="sref">inlinebt3c_io_writeiobaseaddrvalue 131{
 132........ta href="+code=bt3c_address" class="sref">bt3c_addressiobaseaddr 133........ta href="+code=bt3c_put" class="sref">bt3c_putiobasevalue 134}
 135
 136
 137static ta href="+code=inline" class="sref">inlinebt3c_getiobase 138{
 139K/op........unsigned short ta href="+code=value" class="sref">valueinbiobaseDATA_L 140
 141........ta href="+code=value" class="sref">valueinbiobaseDATA_H 142
 143........return ta href="+code=value" class="sref">value 144}
 145
 146
 147static ta href="+code=inline" class="sref">inlinebt3c_readiobaseaddr 148{
 149K/op........ta href="+code=bt3c_address" class="sref">bt3c_addressiobaseaddr 150
 151........return ta href="+code=bt3c_get" class="sref">bt3c_getiobase 152}
 153
 154
 155
 156K/optio4option value="v2.6/* ======================== Interrupt handling ======================== */
 157
 158
 159static int ta href="+code=bt3c_write" class="sref">bt3c_writeiobasefifo_size__u8.*ta href="+code=buf" class="sref">buflen 160 161........int ta href="+code=actual" class="sref">actual 162
 163........ta href="+code=bt3c_address" class="sref">bt3c_addressiobase 164
 165/* Fill FIFO with current frame */
 166........while (actuallen 167/* Transmit next byte */
 168bt3c_putiobasebufactual 169actual 170 171
 172........ta href="+code=bt3c_io_write" class="sref">bt3c_io_writeiobaseactual 173
 174........return ta href="+code=actual" class="sref">actual 175 176
 177
 178bt3c_write_wakeupbt3c_info_tinfo 179{
 180info 181BT_ERR"Unknown device");
 182 183 184
 185test_and_set_bitXMIT_SENDINGinfotx_state 186 187
 188 189iobaseinfop_devresourcestart 190sk_buffskb 191len 192
 193pcmcia_dev_presentinfop_dev 194 195
 196
 197skbskb_dequeueinfotxq 198clear_bitXMIT_SENDINGinfotx_state 199 200 201
 202/* Send frame */
 203lenbt3c_writeiobaseskbdataskblen 204
 205lenskblen 206BT_ERR"Very strange");
 207 208
 209kfree_skbskb 210
 211infohdevstatbyte_txlen 212
 213 214}
 215
 216
 217static void ta href="+code=bt3c_receive" class="sref">bt3c_receivebt3c_info_tinfo 218{
 219K/op........unsigned int ta href="+code=iobase" class="sref">iobase 220sizeavail 221
 222info 223BT_ERR"Unknown device");
 224 225 226
 227iobaseinfop_devresourcestart 228
 229K/op........ta href="+code=avail" class="sref">availbt3c_readiobase 230//printk("bt3c_cs: receiving %d bytes\n", avail);
 231
 232........ta href="+code=bt3c_address" class="sref">bt3c_addressiobase 233........while (sizeavail 234size 235infohdevstatbyte_rx 236
 237/* Allocate packet */
 238inforx_skbNULL 239inforx_stateRECV_WAIT_PACKET_TYPE 240inforx_count 241inforx_skbbt_skb_allocHCI_MAX_FRAME_SIZEGFP_ATOMIC 242BT_ERR"Can't allocate mem for new packet");
 243 244 245 246
 247
 248inforx_stateRECV_WAIT_PACKET_TYPE 249
 250inforx_skbdevinfohdev 251bt_cbinforx_skbpkt_typeinbiobaseDATA_L 252inbiobaseDATA_H 253//printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
 254
 255bt_cbinforx_skbpkt_type 256
 257HCI_EVENT_PKT 258inforx_stateRECV_WAIT_EVENT_HEADER 259inforx_countHCI_EVENT_HDR_SIZE 260 261
 262HCI_ACLDATA_PKT 263inforx_stateRECV_WAIT_ACL_HEADER 264inforx_countHCI_ACL_HDR_SIZE 265 266
 267HCI_SCODATA_PKT 268inforx_stateRECV_WAIT_SCO_HEADER 269inforx_countHCI_SCO_HDR_SIZE 270 271
 272 273/* Unknown packet */
 274BT_ERR"Unknown HCI packet with type 0x%02x received",.ta href="+code=bt_cb" class="sref">bt_cbinforx_skbpkt_type 275infohdevstaterr_rx 276clear_bitHCI_RUNNINGinfohdevflags 277
 278kfree_skbinforx_skb 279inforx_skbNULL 280 281
 282 283
 284 285
 286__u8.ta href="+code=x" class="sref">xinbiobaseDATA_L 287
 288skb_putinforx_skbx 289inbiobaseDATA_H 290inforx_count 291
 292inforx_count 293
 294dlen 295hci_event_hdreh 296hci_acl_hdrah 297hci_sco_hdrsh 298
 299inforx_state 300
 301RECV_WAIT_EVENT_HEADER 302ehhci_event_hdrinforx_skb 303inforx_stateRECV_WAIT_DATA 304inforx_countehplen 305 306
 307RECV_WAIT_ACL_HEADER 308ahhci_acl_hdrinforx_skb 309dlen__le16_to_cpuahdlen 310inforx_stateRECV_WAIT_DATA 311inforx_countdlen 312 313
 314RECV_WAIT_SCO_HEADER 315shhci_sco_hdrinforx_skb 316inforx_stateRECV_WAIT_DATA 317inforx_countshdlen 318 319
 320RECV_WAIT_DATA 321hci_recv_frameinforx_skb 322inforx_skbNULL 323 324
 325 326
 327 328
 329 330
 331 332
 333........ta href="+code=bt3c_io_write" class="sref">bt3c_io_writeiobase 334}
 335
 336
 337static ta href="+code=irqreturn_t" class="sref">irqreturn_t.ta href="+code=bt3c_interrupt" class="sref">bt3c_interruptirqdev_inst 338{
 339K/op........ta href="+code=bt3c_info_t" class="sref">bt3c_info_tinfodev_inst 340iobase 341........int ta href="+code=iir" class="sref">iir 342irqreturn_t.ta href="+code=r" class="sref">rIRQ_NONE 343
 344infoinfohdev 345/* our irq handler is shared */
 346IRQ_NONE 347
 348iobaseinfop_devresourcestart 349
 350spin_lockinfolock 351
 352iirinbiobaseCONTROL 353iir 354statbt3c_readiobase 355
 356stat 357BT_ERR"Very strange (stat=0x%04x)",.ta href="+code=stat" class="sref">stat 358stat 359stat 360statusbt3c_readiobase 361BT_INFO"%s: Antenna %s",.ta href="+code=info" class="sref">infohdevname 362status"out" : tspan class="string">"in");
 363 364stat 365bt3c_receiveinfo 366stat 367//BT_ERR("Ack (stat=0x%04x)", stat);
 368clear_bitXMIT_SENDINGinfotx_state 369bt3c_write_wakeupinfo 370 371
 372bt3c_io_writeiobase 373
 374outbiiriobaseCONTROL 375 376rIRQ_HANDLED 377 378
 379K/op........ta href="+code=spin_unlock" class="sref">spin_unlockinfolock 380
 381r 382 383
 384
 385
 386/* ======================== HCI interface ======================== */
 387
 388
 389bt3c_hci_flushhci_devhdev 390 391K/op........ta href="+code=bt3c_info_t" class="sref">bt3c_info_tinfohci_get_drvdatahdev 392
 393........tspan class="comment">/* Drop TX queue */
 394skb_queue_purgeinfotxq 395
 396 397 398
 399
 400static int ta href="+code=bt3c_hci_open" class="sref">bt3c_hci_openhci_devhdev 401 402set_bitHCI_RUNNINGhdevflags 403
 404 405 406
 407
 408bt3c_hci_closehci_devhdev 409 410test_and_clear_bitHCI_RUNNINGhdevflags 411 412
 413........ta href="+code=bt3c_hci_flush" class="sref">bt3c_hci_flushhdev 414
 415 416 417
 418
 419bt3c_hci_send_framesk_buffskb 420 421K/op........ta href="+code=bt3c_info_t" class="sref">bt3c_info_tinfo 422hci_devhdevhci_devskbdev 423flags 424
 425hdev 426BT_ERR"Frame for unknown HCI device (hdev=NULL)");
 427ENODEV 428 429
 430infohci_get_drvdatahdev 431
 432bt_cbskbpkt_type 433........case ta href="+code=HCI_COMMAND_PKT" class="sref">HCI_COMMAND_PKT:
 434hdevstatcmd_tx 435 436........case ta href="+code=HCI_ACLDATA_PKT" class="sref">HCI_ACLDATA_PKT 437hdevstatacl_tx 438 439K/op........case ta href="+code=HCI_SCODATA_PKT" class="sref">HCI_SCODATA_PKT 440hdevstatsco_tx 441 442 443
 444/* Prepend skb with frame type */
 445memcpyskb_pushskbbt_cbskbpkt_type 446skb_queue_tailinfotxqskb 447
 448spin_lock_irqsaveinfolockflags 449
 450bt3c_write_wakeupinfo 451
 452spin_unlock_irqrestoreinfolockflags 453
 454 455 456
 457
 458bt3c_hci_ioctlhci_devhdevcmdarg 459 460ENOIOCTLCMD 461 462
 463
 464
 465/* ======================== Card services HCI interaction ======================== */
 466
 467
 468bt3c_load_firmwarebt3c_info_tinfofirmware 469count 470 471ptrfirmware 472b 473iobasesizeaddrfcstmp 474ierr 475
 476iobaseinfop_devresourcestart 477
 478/* Reset */
 479K/op........ta href="+code=bt3c_io_write" class="sref">bt3c_io_writeiobase 480bt3c_io_writeiobase 481
 482udelay 483
 484bt3c_io_writeiobase 485
 486udelay 487
 488/* Load */
 489K/op........while (ta href="+code=count" class="sref">count 490ptr'S') {
 491BT_ERR"Bad address.in firmware");
 492errEFAULT 493error 494 495
 496memsetbb 497memcpybptr 498sizesimple_strtoulbNULL 499
 500memsetbb 501memcpybptr 502addrsimple_strtoulbNULL 503
 504memsetbb 505memcpybptrsize 506fcssimple_strtoulbNULL 507
 508memsetbb 509tmpiisizei 510memcpybptri 511tmpsimple_strtolbNULL 512 513
 514tmpfcs 515BT_ERR"Checksum error.in firmware");
 516errEILSEQ 517error 518 519
 520ptr'3') {
 521bt3c_addressiobaseaddr 522
 523memsetbb 524iisizei 525memcpybptri 526tmpsimple_strtoulbNULL 527bt3c_putiobasetmp 528 529 530
 531ptrsize 532countsize 533........}
 534
 535udelay 536
 537/* Boot */
 538bt3c_addressiobase 539K/op........ta href="+code=outb" class="sref">outbinbiobaseCONTROLiobaseCONTROL 540
 541error 542udelay 543
 544/* Clear */
 545bt3c_io_writeiobase 546bt3c_io_writeiobase 547bt3c_io_writeiobase 548
 549K/op........return ta href="+code=err" class="sref">err 550 551
 552
 553static int ta href="+code=bt3c_open" class="sref">bt3c_openbt3c_info_tinfo 554 555firmwarefirmware 556hci_devhdev 557err 558
 559K/op........ta href="+code=spin_lock_init" class="sref">spin_lock_initinfolock 560
 561K/op........ta href="+code=skb_queue_head_init" class="sref">skb_queue_head_initinfotxq 562
 563........ta href="+code=info" class="sref">inforx_stateRECV_WAIT_PACKET_TYPE 564inforx_count 565inforx_skbNULL 566
 567/* Initialize HCI device */
 568hdevhci_alloc_dev 569hdev 570BT_ERR"Can't allocate HCI device");
 571ENOMEM 572 573
 574infohdevhdev 575
 576hdevbusHCI_PCCARD 577hci_set_drvdatahdevinfo 578SET_HCIDEV_DEVhdevinfop_devdev 579
 580hdevopenbt3c_hci_open 581K/op........ta href="+code=hdev" class="sref">hdevclosebt3c_hci_close 582hdevflushbt3c_hci_flush 583........ta href="+code=hdev" class="sref">hdevsendbt3c_hci_send_frame 584hdevioctlbt3c_hci_ioctl 585
 586/* Load firmware */
 587errrequest_firmwarefirmware"BT3CPCC.bin",.&ta href="+code=info" class="sref">infop_devdev 588err 589BT_ERR"Firmware request failed");
 590error 591 592
 593........ta href="+code=err" class="sref">errbt3c_load_firmwareinfofirmwaredatafirmwaresize 594
 595release_firmwarefirmware 596
 597err 598BT_ERR"Firmware loading failed");
 599error 600 601
 602/* Timeout before it is safe to.send the first HCI packet */
 603........ta href="+code=msleep" class="sref">msleep 604
 605/* Register HCI device */
 606errhci_register_devhdev 607err 608BT_ERR"Can't register HCI device");
 609error 610 611
 612 613
 614error 615infohdevNULL 616hci_free_devhdev 617err 618 619
 620
 621bt3c_closebt3c_info_tinfo 622{
 623hci_devhdevinfohdev 624
 625hdev 626ENODEV 627
 628bt3c_hci_closehdev 629
 630hci_unregister_devhdev 631K/op........ta href="+code=hci_free_dev" class="sref">hci_free_devhdev 632
 633........return 0;
 634}
 635
 636static int ta href="+code=bt3c_probe" class="sref">bt3c_probepcmcia_devicelink 637 638bt3c_info_tinfo 639
 640/* Create new info device */
 641K/op........ta href="+code=info" class="sref">infodevm_kzalloclinkdevinfoGFP_KERNEL 642info 643ENOMEM 644
 645infop_devlink 646linkprivinfo 647
 648linkconfig_flagsCONF_ENABLE_IRQCONF_AUTO_SET_VPP 649CONF_AUTO_SET_IO 650
 651K/op........return ta href="+code=bt3c_config" class="sref">bt3c_configlink 652}
 653
 654
 655bt3c_detachpcmcia_devicelink 656 657bt3c_releaselink 658 659
 660static int ta href="+code=bt3c_check_config" class="sref">bt3c_check_configpcmcia_devicep_devpriv_data 661K/op{
 662trypriv_data 663
 664try 665p_devio_lines 666
 667p_devresourceendp_devresourcestart 668EINVAL 669
 670p_devresourceend 671K/op........ta href="+code=p_dev" class="sref">p_devresourceflagsIO_DATA_PATH_WIDTH 672p_devresourceflagsIO_DATA_PATH_WIDTH_8 673
 674pcmcia_request_iop_dev 675}
 676
 677bt3c_check_config_notpickypcmcia_devicep_dev 678priv_data 679{
 680base 681K/op........int ta href="+code=j" class="sref">j 682
 683........if (ta href="+code=p_dev" class="sref">p_devio_lines 684ENODEV 685
 686p_devresourceflagsIO_DATA_PATH_WIDTH 687p_devresourceflagsIO_DATA_PATH_WIDTH_8 688p_devresourceend 689
 690jjj 691p_devresourcestartbasej 692p_devio_linesbasej 693pcmcia_request_iop_dev 694 695 696ENODEV 697 698
 699bt3c_configpcmcia_devicelink 700 701K/op........ta href="+code=bt3c_info_t" class="sref">bt3c_info_tinfolinkpriv 702i 703........unsigned long.ta href="+code=try" class="sref">try 704
 705/* First pass: look.for a config entry that looks normal.
 706...........Two tries: without IO aliases, then with aliases */
 707trytrytry 708pcmcia_loop_configlinkbt3c_check_configtry 709found_port 710
 711/* Second pass: try to find an entry that isn't picky about
 712...........its base address, then try to grab any.standard serial port
 713tspan class="comment">...........address, and finally try to get any.free port. */
 714pcmcia_loop_configlinkbt3c_check_config_notpickyNULL 715found_port 716
 717BT_ERR"No usable port range found");
 718failed 719
 720ta href="+code=found_port" class="sref">found_port 721K/op........ta href="+code=i" class="sref">ipcmcia_request_irqlinkbt3c_interrupt 722i 723failed 724
 725ipcmcia_enable_devicelink 726i 727failed 728
 729bt3c_openinfo 730failed 731
 732 733
 734failed 735bt3c_releaselink 736ENODEV 737 738
 739
 740static void ta href="+code=bt3c_release" class="sref">bt3c_releasepcmcia_devicelink 741K/op{
 742bt3c_info_tinfolinkpriv 743
 744bt3c_closeinfo 745
 746pcmcia_disable_devicelink 747 748
 749
 750static const.struct ta href="+code=pcmcia_device_id" class="sref">pcmcia_device_idbt3c_ids 751K/op........ta href="+code=PCMCIA_DEVICE_PROD_ID13" class="sref">PCMCIA_DEVICE_PROD_ID13"3COM",.tspan class="string">"Bluetooth PC Card",.0xefce0a31,.0xd4ce9b02),
 752PCMCIA_DEVICE_NULL
 753};
 754MODULE_DEVICE_TABLEpcmciabt3c_ids 755
 756static struct ta href="+code=pcmcia_driver" class="sref">pcmcia_driverbt3c_driver 757ownerTHIS_MODULE 758name"bt3c_cs",
 759probebt3c_probe 760removebt3c_detach 761id_tablebt3c_ids 762 763
 764__initinit_bt3c_cs 765 766pcmcia_register_driverbt3c_driver 767 768
 769
 770static void ta href="+code=__exit" class="sref">__exitexit_bt3c_cs 771K/op{
 772pcmcia_unregister_driverbt3c_driver 773}
 774
 775ta href="+code=module_init" class="sref">module_initinit_bt3c_cs 776ta href="+code=module_exit" class="sref">module_exitexit_bt3c_cs 777