1/***************************************************************************** 2* 3* Filename: ks959-sir.c 4* Version: 0.1.2 5* Description: Irda KingSun KS-959 USB Dongle 6* Status: Experimental 7* Author: Alex Villac��s Lasso <a_villacis@palosanto.com> 8* with help from Domen Puncer <domen@coderock.org> 9* 10* Based on stir4200, mcs7780, kingsun-sir drivers. 11* 12* This program is free software; you can redistribute it and/or modify 13* it under the terms of the GNU General Public License as published by 14* the Free Software Foundation; either version 2 of the License. 15* 16* This program is distributed in the hope that it will be useful, 17* but WITHOUT ANY WARRANTY; without even the implied warranty of 18* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19* GNU General Public License for more details. 20* 21* You should have received a copy of the GNU General Public License 22* along with this program; if not, write to the Free Software 23* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24* 25*****************************************************************************/ 26 27/* 28 * Following is my most current (2007-07-17) understanding of how the Kingsun 29 * KS-959 dongle is supposed to work. This information was deduced by 30 * reverse-engineering and examining the USB traffic captured with USBSnoopy 31 * from the WinXP driver. Feel free to update here as more of the dongle is 32 * known. 33 * 34 * My most sincere thanks must go to Domen Puncer <domen@coderock.org> for 35 * invaluable help in cracking the obfuscation and padding required for this 36 * dongle. 37 * 38 * General: This dongle exposes one interface with one interrupt IN endpoint. 39 * However, the interrupt endpoint is NOT used at all for this dongle. Instead, 40 * this dongle uses control transfers for everything, including sending and 41 * receiving the IrDA frame data. Apparently the interrupt endpoint is just a 42 * dummy to ensure the dongle has a valid interface to present to the PC.And I 43 * thought the DonShine dongle was weird... In addition, this dongle uses 44 * obfuscation (?!?!), applied at the USB level, to hide the traffic, both sent 45 * and received, from the dongle. I call it obfuscation because the XOR keying 46 * and padding required to produce an USB traffic acceptable for the dongle can 47 * not be explained by any other technical requirement. 48 * 49 * Transmission: To transmit an IrDA frame, the driver must prepare a control 50 * URB with the following as a setup packet: 51 * bRequestType USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE 52 * bRequest 0x09 53 * wValue <length of valid data before padding, little endian> 54 * wIndex 0x0000 55 * wLength <length of padded data> 56 * The payload packet must be manually wrapped and escaped (as in stir4200.c), 57 * then padded and obfuscated before being sent. Both padding and obfuscation 58 * are implemented in the procedure obfuscate_tx_buffer(). Suffice to say, the 59 * designer/programmer of the dongle used his name as a source for the 60 * obfuscation. WTF?! 61 * Apparently the dongle cannot handle payloads larger than 256 bytes. The 62 * driver has to perform fragmentation in order to send anything larger than 63 * this limit. 64 * 65 * Reception: To receive data, the driver must poll the dongle regularly (like 66 * kingsun-sir.c) with control URBs and the following as a setup packet: 67 * bRequestType USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE 68 * bRequest 0x01 69 * wValue 0x0200 70 * wIndex 0x0000 71 * wLength 0x0800 (size of available buffer) 72 * If there is data to be read, it will be returned as the response payload. 73 * This data is (apparently) not padded, but it is obfuscated. To de-obfuscate 74 * it, the driver must XOR every byte, in sequence, with a value that starts at 75 * 1 and is incremented with each byte processed, and then with 0x55. The value 76 * incremented with each byte processed overflows as an unsigned char. The 77 * resulting bytes form a wrapped SIR frame that is unwrapped and unescaped 78 * as in stir4200.c The incremented value is NOT reset with each frame, but is 79 * kept across the entire session with the dongle. Also, the dongle inserts an 80 * extra garbage byte with value 0x95 (after decoding) every 0xff bytes, which 81 * must be skipped. 82 * 83 * Speed change: To change the speed of the dongle, the driver prepares a 84 * control URB with the following as a setup packet: 85 * bRequestType USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE 86 * bRequest 0x09 87 * wValue 0x0200 88 * wIndex 0x0001 89 * wLength 0x0008 (length of the payload) 90 * The payload is a 8-byte record, apparently identical to the one used in 91 * drivers/usb/serial/cypress_m8.c to change speed: 92 * __u32 baudSpeed; 93 * unsigned int dataBits : 2; // 0 - 5 bits 3 - 8 bits 94 * unsigned int : 1; 95 * unsigned int stopBits : 1; 96 * unsigned int parityEnable : 1; 97 * unsigned int parityType : 1; 98 * unsigned int : 1; 99 * unsigned int reset : 1; 100 * unsigned char reserved[3]; // set to 0 101 * 102 * For now only SIR speeds have been observed with this dongle. Therefore, 103 * nothing is known on what changes (if any) must be done to frame wrapping / 104 * unwrapping for higher than SIR speeds. This driver assumes no change is 105 * necessary and announces support for all the way to 57600 bps. Although the 106 * package announces support for up to 4MBps, tests with a Sony Ericcson K300 107 * phone show corruption when receiving large frames at 115200 bps, the highest 108 * speed announced by the phone. However, transmission at 115200 bps is OK. Go 109 * figure. Since I don't know whether the phone or the dongle is at fault, max 110 * announced speed is 57600 bps until someone produces a device that can run 111 * at higher speeds with this dongle. 112 */ 113 114#include <linux/module.h> 115#include <linux/moduleparam.h> 116#include <linux/kernel.h> 117#include <linux/types.h> 118#include <linux/errno.h> 119#include <linux/init.h> 120#include <linux/slab.h> 121#include <linux/usb.h> 122#include <linux/device.h> 123#include <linux/crc32.h> 124 125#include <asm/unaligned.h> 126#include <asm/byteorder.h> 127#include <asm/uaccess.h> 128 129#include <net/irda/irda.h> 130#include <net/irda/wrapper.h> 131#include <net/irda/crc.h> 132 133#define KS959_VENDOR_ID 0x07d0 134#define KS959_PRODUCT_ID 0x4959 135 136/* These are the currently known USB ids */ 137static struct usb_device_id dongles[] = { 138 /* KingSun Co,Ltd IrDA/USB Bridge */ 139 {USB_DEVICE(KS959_VENDOR_ID, KS959_PRODUCT_ID)}, 140 {} 141}; 142 143MODULE_DEVICE_TABLE(usb, dongles); 144 145#define KINGSUN_MTT 0x07 146#define KINGSUN_REQ_RECV 0x01 147#define KINGSUN_REQ_SEND 0x09 148 149#define KINGSUN_RCV_FIFO_SIZE 2048 /* Max length we can receive */ 150#define KINGSUN_SND_FIFO_SIZE 2048 /* Max packet we can send */ 151#define KINGSUN_SND_PACKET_SIZE 256 /* Max packet dongle can handle */ 152 153struct ks959_speedparams { 154 __le32 baudrate; /* baud rate, little endian */ 155 __u8 flags; 156 __u8 reserved[3]; 157} __packed; 158 159#define KS_DATA_5_BITS 0x00 160#define KS_DATA_6_BITS 0x01 161#define KS_DATA_7_BITS 0x02 162#define KS_DATA_8_BITS 0x03 163 164#define KS_STOP_BITS_1 0x00 165#define KS_STOP_BITS_2 0x08 166 167#define KS_PAR_DISABLE 0x00 168#define KS_PAR_EVEN 0x10 169#define KS_PAR_ODD 0x30 170#define KS_RESET 0x80 171 172struct ks959_cb { 173 struct usb_device *usbdev; /* init: probe_irda */ 174 struct net_device *netdev; /* network layer */ 175 struct irlap_cb *irlap; /* The link layer we are binded to */ 176 177 struct qos_info qos; 178 179 struct usb_ctrlrequest *tx_setuprequest; 180 struct urb *tx_urb; 181 __u8 *tx_buf_clear; 182 unsigned int tx_buf_clear_used; 183 unsigned int tx_buf_clear_sent; 184 __u8 *tx_buf_xored; 185 186 struct usb_ctrlrequest *rx_setuprequest; 187 struct urb *rx_urb; 188 __u8 *rx_buf; 189 __u8 rx_variable_xormask; 190 iobuff_t rx_unwrap_buff; 191 struct timeval rx_time; 192 193 struct usb_ctrlrequest *speed_setuprequest; 194 struct urb *speed_urb; 195 struct ks959_speedparams speedparams; 196 unsigned int new_speed; 197 198 spinlock_t lock; 199 int receiving; 200}; 201 202/* Procedure to perform the obfuscation/padding expected by the dongle 203 * 204 * buf_cleartext (IN) Cleartext version of the IrDA frame to transmit 205 * len_cleartext (IN) Length of the cleartext version of IrDA frame 206 * buf_xoredtext (OUT) Obfuscated version of frame built by proc 207 * len_maxbuf (OUT) Maximum space available at buf_xoredtext 208 * 209 * (return) length of obfuscated frame with padding 210 * 211 * If not enough space (as indicated by len_maxbuf vs. required padding), 212 * zero is returned 213 * 214 * The value of lookup_string is actually a required portion of the algorithm. 215 * Seems the designer of the dongle wanted to state who exactly is responsible 216 * for implementing obfuscation. Send your best (or other) wishes to him ]:-) 217 */ 218static unsigned int obfuscate_tx_buffer(const __u8 * buf_cleartext, 219 unsigned int len_cleartext, 220 __u8 * buf_xoredtext, 221 unsigned int len_maxbuf) 222{ 223 unsigned int len_xoredtext; 224 225 /* Calculate required length with padding, check for necessary space */ 226 len_xoredtext = ((len_cleartext + 7) & ~0x7) + 0x10; 227 if (len_xoredtext <= len_maxbuf) { 228 static const __u8 lookup_string[] = "wangshuofei19710"; 229 __u8 xor_mask; 230 231 /* Unlike the WinXP driver, we *do* clear out the padding */ 232 memset(buf_xoredtext, 0, len_xoredtext); 233 234 xor_mask = lookup_string[(len_cleartext & 0x0f) ^ 0x06] ^ 0x55; 235 236 while (len_cleartext-- > 0) { 237 *buf_xoredtext++ = *buf_cleartext++ ^ xor_mask; 238 } 239 } else { 240 len_xoredtext = 0; 241 } 242 return len_xoredtext; 243} 244 245/* Callback transmission routine */ 246static void ks959_speed_irq(struct urb *urb) 247{ 248 /* unlink, shutdown, unplug, other nasties */ 249 if (urb->status != 0) { 250 err("ks959_speed_irq: urb asynchronously failed - %d", 251 urb->status); 252 } 253} 254 255/* Send a control request to change speed of the dongle */ 256static int ks959_change_speed(struct ks959_cb *kingsun, unsigned speed) 257{ 258 static unsigned int supported_speeds[] = { 2400, 9600, 19200, 38400, 259 57600, 115200, 576000, 1152000, 4000000, 0 260 }; 261 int err; 262 unsigned int i; 263 264 if (kingsun->speed_setuprequest == NULL || kingsun->speed_urb == NULL) 265 return -ENOMEM; 266 267 /* Check that requested speed is among the supported ones */ 268 for (i = 0; supported_speeds[i] && supported_speeds[i] != speed; i++) ; 269 if (supported_speeds[i] == 0) 270 return -EOPNOTSUPP; 271 272 memset(&(kingsun->speedparams), 0, sizeof(struct ks959_speedparams)); 273 kingsun->speedparams.baudrate = cpu_to_le32(speed); 274 kingsun->speedparams.flags = KS_DATA_8_BITS; 275 276 /* speed_setuprequest pre-filled in ks959_probe */ 277 usb_fill_control_urb(kingsun->speed_urb, kingsun->usbdev, 278 usb_sndctrlpipe(kingsun->usbdev, 0), 279 (unsigned char *)kingsun->speed_setuprequest, 280 &(kingsun->speedparams), 281 sizeof(struct ks959_speedparams), ks959_speed_irq, 282 kingsun); 283 kingsun->speed_urb->status = 0; 284 err = usb_submit_urb(kingsun->speed_urb, GFP_ATOMIC); 285 286 return err; 287} 288 289/* Submit one fragment of an IrDA frame to the dongle */ 290static void ks959_send_irq(struct urb *urb); 291static int ks959_submit_tx_fragment(struct ks959_cb *kingsun) 292{ 293 unsigned int padlen; 294 unsigned int wraplen; 295 int ret; 296 297 /* Check whether current plaintext can produce a padded buffer that fits 298 within the range handled by the dongle */ 299 wraplen = (KINGSUN_SND_PACKET_SIZE & ~0x7) - 0x10; 300 if (wraplen > kingsun->tx_buf_clear_used) 301 wraplen = kingsun->tx_buf_clear_used; 302 303 /* Perform dongle obfuscation. Also remove the portion of the frame that 304 was just obfuscated and will now be sent to the dongle. */ 305 padlen = obfuscate_tx_buffer(kingsun->tx_buf_clear, wraplen, 306 kingsun->tx_buf_xored, 307 KINGSUN_SND_PACKET_SIZE); 308 309 /* Calculate how much data can be transmitted in this urb */ 310 kingsun->tx_setuprequest->wValue = cpu_to_le16(wraplen); 311 kingsun->tx_setuprequest->wLength = cpu_to_le16(padlen); 312 /* Rest of the fields were filled in ks959_probe */ 313 usb_fill_control_urb(kingsun->tx_urb, kingsun->usbdev, 314 usb_sndctrlpipe(kingsun->usbdev, 0), 315 (unsigned char *)kingsun->tx_setuprequest, 316 kingsun->tx_buf_xored, padlen, 317 ks959_send_irq, kingsun); 318 kingsun->tx_urb->status = 0; 319 ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC); 320 321 /* Remember how much data was sent, in order to update at callback */ 322 kingsun->tx_buf_clear_sent = (ret == 0) ? wraplen : 0; 323 return ret; 324} 325 326/* Callback transmission routine */ 327static void ks959_send_irq(struct urb *urb) 328{ 329 struct ks959_cb *kingsun = urb->context; 330 struct net_device *netdev = kingsun->netdev; 331 int ret = 0; 332 333 /* in process of stopping, just drop data */ 334 if (!netif_running(kingsun->netdev)) { 335 err("ks959_send_irq: Network not running!"); 336 return; 337 } 338 339 /* unlink, shutdown, unplug, other nasties */ 340 if (urb->status != 0) { 341 err("ks959_send_irq: urb asynchronously failed - %d", 342 urb->status); 343 return; 344 } 345 346 if (kingsun->tx_buf_clear_used > 0) { 347 /* Update data remaining to be sent */ 348 if (kingsun->tx_buf_clear_sent < kingsun->tx_buf_clear_used) { 349 memmove(kingsun->tx_buf_clear, 350 kingsun->tx_buf_clear + 351 kingsun->tx_buf_clear_sent, 352 kingsun->tx_buf_clear_used - 353 kingsun->tx_buf_clear_sent); 354 } 355 kingsun->tx_buf_clear_used -= kingsun->tx_buf_clear_sent; 356 kingsun->tx_buf_clear_sent = 0; 357 358 if (kingsun->tx_buf_clear_used > 0) { 359 /* There is more data to be sent */ 360 if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) { 361 err("ks959_send_irq: failed tx_urb submit: %d", 362 ret); 363 switch (ret) { 364 case -ENODEV: 365 case -EPIPE: 366 break; 367 default: 368 netdev->stats.tx_errors++; 369 netif_start_queue(netdev); 370 } 371 } 372 } else { 373 /* All data sent, send next speed && wake network queue */ 374 if (kingsun->new_speed != -1 && 375 cpu_to_le32(kingsun->new_speed) != 376 kingsun->speedparams.baudrate) 377 ks959_change_speed(kingsun, kingsun->new_speed); 378 379 netif_wake_queue(netdev); 380 } 381 } 382} 383 384/* 385 * Called from net/core when new frame is available. 386 */ 387static netdev_tx_t ks959_hard_xmit(struct sk_buff *skb, 388 struct net_device *netdev) 389{ 390 struct ks959_cb *kingsun; 391 unsigned int wraplen; 392 int ret = 0; 393 394 netif_stop_queue(netdev); 395 396 /* the IRDA wrapping routines don't deal with non linear skb */ 397 SKB_LINEAR_ASSERT(skb); 398 399 kingsun = netdev_priv(netdev); 400 401 spin_lock(&kingsun->lock); 402 kingsun->new_speed = irda_get_next_speed(skb); 403 404 /* Append data to the end of whatever data remains to be transmitted */ 405 wraplen = 406 async_wrap_skb(skb, kingsun->tx_buf_clear, KINGSUN_SND_FIFO_SIZE); 407 kingsun->tx_buf_clear_used = wraplen; 408 409 if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) { 410 err("ks959_hard_xmit: failed tx_urb submit: %d", ret); 411 switch (ret) { 412 case -ENODEV: 413 case -EPIPE: 414 break; 415 default: 416 netdev->stats.tx_errors++; 417 netif_start_queue(netdev); 418 } 419 } else { 420 netdev->stats.tx_packets++; 421 netdev->stats.tx_bytes += skb->len; 422 423 } 424 425 dev_kfree_skb(skb); 426 spin_unlock(&kingsun->lock); 427 428 return NETDEV_TX_OK; 429} 430 431/* Receive callback function */ 432static void ks959_rcv_irq(struct urb *urb) 433{ 434 struct ks959_cb *kingsun = urb->context; 435 int ret; 436 437 /* in process of stopping, just drop data */ 438 if (!netif_running(kingsun->netdev)) { 439 kingsun->receiving = 0; 440 return; 441 } 442 443 /* unlink, shutdown, unplug, other nasties */ 444 if (urb->status != 0) { 445 err("kingsun_rcv_irq: urb asynchronously failed - %d", 446 urb->status); 447 kingsun->receiving = 0; 448 return; 449 } 450 451 if (urb->actual_length > 0) { 452 __u8 *bytes = urb->transfer_buffer; 453 unsigned int i; 454 455 for (i = 0; i < urb->actual_length; i++) { 456 /* De-obfuscation implemented here: variable portion of 457 xormask is incremented, and then used with the encoded 458 byte for the XOR. The result of the operation is used 459 to unwrap the SIR frame. */ 460 kingsun->rx_variable_xormask++; 461 bytes[i] = 462 bytes[i] ^ kingsun->rx_variable_xormask ^ 0x55u; 463 464 /* rx_variable_xormask doubles as an index counter so we 465 can skip the byte at 0xff (wrapped around to 0). 466 */ 467 if (kingsun->rx_variable_xormask != 0) { 468 async_unwrap_char(kingsun->netdev, 469 &kingsun->netdev->stats, 470 &kingsun->rx_unwrap_buff, 471 bytes[i]); 472 } 473 } 474 do_gettimeofday(&kingsun->rx_time); 475 kingsun->receiving = 476 (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0; 477 } 478 479 /* This urb has already been filled in kingsun_net_open. Setup 480 packet must be re-filled, but it is assumed that urb keeps the 481 pointer to the initial setup packet, as well as the payload buffer. 482 Setup packet is already pre-filled at ks959_probe. 483 */ 484 urb->status = 0; 485 ret = usb_submit_urb(urb, GFP_ATOMIC); 486} 487 488/* 489 * Function kingsun_net_open (dev) 490 * 491 * Network device is taken up. Usually this is done by "ifconfig irda0 up" 492 */ 493static int ks959_net_open(struct net_device *netdev) 494{ 495 struct ks959_cb *kingsun = netdev_priv(netdev); 496 int err = -ENOMEM; 497 char hwname[16]; 498 499 /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */ 500 kingsun->receiving = 0; 501 502 /* Initialize for SIR to copy data directly into skb. */ 503 kingsun->rx_unwrap_buff.in_frame = FALSE; 504 kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; 505 kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU; 506 kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU); 507 if (!kingsun->rx_unwrap_buff.skb) 508 goto free_mem; 509 510 skb_reserve(kingsun->rx_unwrap_buff.skb, 1); 511 kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data; 512 do_gettimeofday(&kingsun->rx_time); 513 514 kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL); 515 if (!kingsun->rx_urb) 516 goto free_mem; 517 518 kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL); 519 if (!kingsun->tx_urb) 520 goto free_mem; 521 522 kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL); 523 if (!kingsun->speed_urb) 524 goto free_mem; 525 526 /* Initialize speed for dongle */ 527 kingsun->new_speed = 9600; 528 err = ks959_change_speed(kingsun, 9600); 529 if (err < 0) 530 goto free_mem; 531 532 /* 533 * Now that everything should be initialized properly, 534 * Open new IrLAP layer instance to take care of us... 535 */ 536 sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); 537 kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); 538 if (!kingsun->irlap) { 539 err("ks959-sir: irlap_open failed"); 540 goto free_mem; 541 } 542 543 /* Start reception. Setup request already pre-filled in ks959_probe */ 544 usb_fill_control_urb(kingsun->rx_urb, kingsun->usbdev, 545 usb_rcvctrlpipe(kingsun->usbdev, 0), 546 (unsigned char *)kingsun->rx_setuprequest, 547 kingsun->rx_buf, KINGSUN_RCV_FIFO_SIZE, 548 ks959_rcv_irq, kingsun); 549 kingsun->rx_urb->status = 0; 550 err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); 551 if (err) { 552 err("ks959-sir: first urb-submit failed: %d", err); 553 goto close_irlap; 554 } 555 556 netif_start_queue(netdev); 557 558 /* Situation at this point: 559 - all work buffers allocated 560 - urbs allocated and ready to fill 561 - max rx packet known (in max_rx) 562 - unwrap state machine initialized, in state outside of any frame 563 - receive request in progress 564 - IrLAP layer started, about to hand over packets to send 565 */ 566 567 return 0; 568 569 close_irlap: 570 irlap_close(kingsun->irlap); 571 free_mem: 572 usb_free_urb(kingsun->speed_urb); 573 kingsun->speed_urb = NULL; 574 usb_free_urb(kingsun->tx_urb); 575 kingsun->tx_urb = NULL; 576 usb_free_urb(kingsun->rx_urb); 577 kingsun->rx_urb = NULL; 578 if (kingsun->rx_unwrap_buff.skb) { 579 kfree_skb(kingsun->rx_unwrap_buff.skb); 580 kingsun->rx_unwrap_buff.skb = NULL; 581 kingsun->rx_unwrap_buff.head = NULL; 582 } 583 return err; 584} 585 586/* 587 * Function kingsun_net_close (kingsun) 588 * 589 * Network device is taken down. Usually this is done by 590 * "ifconfig irda0 down" 591 */ 592static int ks959_net_close(struct net_device *netdev) 593{ 594 struct ks959_cb *kingsun = netdev_priv(netdev); 595 596 /* Stop transmit processing */ 597 netif_stop_queue(netdev); 598 599 /* Mop up receive && transmit urb's */ 600 usb_kill_urb(kingsun->tx_urb); 601 usb_free_urb(kingsun->tx_urb); 602 kingsun->tx_urb = NULL; 603 604 usb_kill_urb(kingsun->speed_urb); 605 usb_free_urb(kingsun->speed_urb); 606 kingsun->speed_urb = NULL; 607 608 usb_kill_urb(kingsun->rx_urb); 609 usb_free_urb(kingsun->rx_urb); 610 kingsun->rx_urb = NULL; 611 612 kfree_skb(kingsun->rx_unwrap_buff.skb); 613 kingsun->rx_unwrap_buff.skb = NULL; 614 kingsun->rx_unwrap_buff.head = NULL; 615 kingsun->rx_unwrap_buff.in_frame = FALSE; 616 kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; 617 kingsun->receiving = 0; 618 619 /* Stop and remove instance of IrLAP */ 620 if (kingsun->irlap) 621 irlap_close(kingsun->irlap); 622 623 kingsun->irlap = NULL; 624 625 return 0; 626} 627 628/* 629 * IOCTLs : Extra out-of-band network commands... 630 */ 631static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) 632{ 633 struct if_irda_req *irq = (struct if_irda_req *)rq; 634 struct ks959_cb *kingsun = netdev_priv(netdev); 635 int ret = 0; 636 637 switch (cmd) { 638 case SIOCSBANDWIDTH: /* Set bandwidth */ 639 if (!capable(CAP_NET_ADMIN)) 640 return -EPERM; 641 642 /* Check if the device is still there */ 643 if (netif_device_present(kingsun->netdev)) 644 return ks959_change_speed(kingsun, irq->ifr_baudrate); 645 break; 646 647 case SIOCSMEDIABUSY: /* Set media busy */ 648 if (!capable(CAP_NET_ADMIN)) 649 return -EPERM; 650 651 /* Check if the IrDA stack is still there */ 652 if (netif_running(kingsun->netdev)) 653 irda_device_set_media_busy(kingsun->netdev, TRUE); 654 break; 655 656 case SIOCGRECEIVING: 657 /* Only approximately true */ 658 irq->ifr_receiving = kingsun->receiving; 659 break; 660 661 default: 662 ret = -EOPNOTSUPP; 663 } 664 665 return ret; 666} 667 668static const struct net_device_ops ks959_ops = { 669 .ndo_start_xmit = ks959_hard_xmit, 670 .ndo_open = ks959_net_open, 671 .ndo_stop = ks959_net_close, 672 .ndo_do_ioctl = ks959_net_ioctl, 673}; 674/* 675 * This routine is called by the USB subsystem for each new device 676 * in the system. We need to check if the device is ours, and in 677 * this case start handling it. 678 */ 679static int ks959_probe(struct usb_interface *intf, 680 const struct usb_device_id *id) 681{ 682 struct usb_device *dev = interface_to_usbdev(intf); 683 struct ks959_cb *kingsun = NULL; 684 struct net_device *net = NULL; 685 int ret = -ENOMEM; 686 687 /* Allocate network device container. */ 688 net = alloc_irdadev(sizeof(*kingsun)); 689 if (!net) 690 goto err_out1; 691 692 SET_NETDEV_DEV(net, &intf->dev); 693 kingsun = netdev_priv(net); 694 kingsun->netdev = net; 695 kingsun->usbdev = dev; 696 kingsun->irlap = NULL; 697 kingsun->tx_setuprequest = NULL; 698 kingsun->tx_urb = NULL; 699 kingsun->tx_buf_clear = NULL; 700 kingsun->tx_buf_xored = NULL; 701 kingsun->tx_buf_clear_used = 0; 702 kingsun->tx_buf_clear_sent = 0; 703 704 kingsun->rx_setuprequest = NULL; 705 kingsun->rx_urb = NULL; 706 kingsun->rx_buf = NULL; 707 kingsun->rx_variable_xormask = 0; 708 kingsun->rx_unwrap_buff.in_frame = FALSE; 709 kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; 710 kingsun->rx_unwrap_buff.skb = NULL; 711 kingsun->receiving = 0; 712 spin_lock_init(&kingsun->lock); 713 714 kingsun->speed_setuprequest = NULL; 715 kingsun->speed_urb = NULL; 716 kingsun->speedparams.baudrate = 0; 717 718 /* Allocate input buffer */ 719 kingsun->rx_buf = kmalloc(KINGSUN_RCV_FIFO_SIZE, GFP_KERNEL); 720 if (!kingsun->rx_buf) 721 goto free_mem; 722 723 /* Allocate input setup packet */ 724 kingsun->rx_setuprequest = 725 kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); 726 if (!kingsun->rx_setuprequest) 727 goto free_mem; 728 kingsun->rx_setuprequest->bRequestType = 729 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 730 kingsun->rx_setuprequest->bRequest = KINGSUN_REQ_RECV; 731 kingsun->rx_setuprequest->wValue = cpu_to_le16(0x0200); 732 kingsun->rx_setuprequest->wIndex = 0; 733 kingsun->rx_setuprequest->wLength = cpu_to_le16(KINGSUN_RCV_FIFO_SIZE); 734 735 /* Allocate output buffer */ 736 kingsun->tx_buf_clear = kmalloc(KINGSUN_SND_FIFO_SIZE, GFP_KERNEL); 737 if (!kingsun->tx_buf_clear) 738 goto free_mem; 739 kingsun->tx_buf_xored = kmalloc(KINGSUN_SND_PACKET_SIZE, GFP_KERNEL); 740 if (!kingsun->tx_buf_xored) 741 goto free_mem; 742 743 /* Allocate and initialize output setup packet */ 744 kingsun->tx_setuprequest = 745 kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); 746 if (!kingsun->tx_setuprequest) 747 goto free_mem; 748 kingsun->tx_setuprequest->bRequestType = 749 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 750 kingsun->tx_setuprequest->bRequest = KINGSUN_REQ_SEND; 751 kingsun->tx_setuprequest->wValue = 0; 752 kingsun->tx_setuprequest->wIndex = 0; 753 kingsun->tx_setuprequest->wLength = 0; 754 755 /* Allocate and initialize speed setup packet */ 756 kingsun->speed_setuprequest = 757 kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); 758 if (!kingsun->speed_setuprequest) 759 goto free_mem; 760 kingsun->speed_setuprequest->bRequestType = 761 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 762 kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND; 763 kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200); 764 kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001); 765 kingsun->speed_setuprequest->wLength = 766 cpu_to_le16(sizeof(struct ks959_speedparams)); 767 768 printk(KERN_INFO "KingSun KS-959 IRDA/USB found at address %d, " 769 "Vendor: %x, Product: %x\n", 770 dev->devnum, le16_to_cpu(dev->descriptor.idVendor), 771 le16_to_cpu(dev->descriptor.idProduct)); 772 773 /* Initialize QoS for this device */ 774 irda_init_max_qos_capabilies(&kingsun->qos); 775 776 /* Baud rates known to be supported. Please uncomment if devices (other 777 than a SonyEriccson K300 phone) can be shown to support higher speed 778 with this dongle. 779 */ 780 kingsun->qos.baud_rate.bits = 781 IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600; 782 kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; 783 irda_qos_bits_to_value(&kingsun->qos); 784 785 /* Override the network functions we need to use */ 786 net->netdev_ops = &ks959_ops; 787 788 ret = register_netdev(net); 789 if (ret != 0) 790 goto free_mem; 791 792 dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n", 793 net->name); 794 795 usb_set_intfdata(intf, kingsun); 796 797 /* Situation at this point: 798 - all work buffers allocated 799 - setup requests pre-filled 800 - urbs not allocated, set to NULL 801 - max rx packet known (is KINGSUN_FIFO_SIZE) 802 - unwrap state machine (partially) initialized, but skb == NULL 803 */ 804 805 return 0; 806 807 free_mem: 808 kfree(kingsun->speed_setuprequest); 809 kfree(kingsun->tx_setuprequest); 810 kfree(kingsun->tx_buf_xored); 811 kfree(kingsun->tx_buf_clear); 812 kfree(kingsun->rx_setuprequest); 813 kfree(kingsun->rx_buf); 814 free_netdev(net); 815 err_out1: 816 return ret; 817} 818 819/* 820 * The current device is removed, the USB layer tell us to shut it down... 821 */ 822static void ks959_disconnect(struct usb_interface *intf) 823{ 824 struct ks959_cb *kingsun = usb_get_intfdata(intf); 825 826 if (!kingsun) 827 return; 828 829 unregister_netdev(kingsun->netdev); 830 831 /* Mop up receive && transmit urb's */ 832 if (kingsun->speed_urb != NULL) { 833 usb_kill_urb(kingsun->speed_urb); 834 usb_free_urb(kingsun->speed_urb); 835 kingsun->speed_urb = NULL; 836 } 837 if (kingsun->tx_urb != NULL) { 838 usb_kill_urb(kingsun->tx_urb); 839 usb_free_urb(kingsun->tx_urb); 840 kingsun->tx_urb = NULL; 841 } 842 if (kingsun->rx_urb != NULL) { 843 usb_kill_urb(kingsun->rx_urb); 844 usb_free_urb(kingsun->rx_urb); 845 kingsun->rx_urb = NULL; 846 } 847 848 kfree(kingsun->speed_setuprequest); 849 kfree(kingsun->tx_setuprequest); 850 kfree(kingsun->tx_buf_xored); 851 kfree(kingsun->tx_buf_clear); 852 kfree(kingsun->rx_setuprequest); 853 kfree(kingsun->rx_buf); 854 free_netdev(kingsun->netdev); 855 856 usb_set_intfdata(intf, NULL); 857} 858 859#ifdef CONFIG_PM 860/* USB suspend, so power off the transmitter/receiver */ 861static int ks959_suspend(struct usb_interface *intf, pm_message_t message) 862{ 863 struct ks959_cb *kingsun = usb_get_intfdata(intf); 864 865 netif_device_detach(kingsun->netdev); 866 if (kingsun->speed_urb != NULL) 867 usb_kill_urb(kingsun->speed_urb); 868 if (kingsun->tx_urb != NULL) 869 usb_kill_urb(kingsun->tx_urb); 870 if (kingsun->rx_urb != NULL) 871 usb_kill_urb(kingsun->rx_urb); 872 return 0; 873} 874 875/* Coming out of suspend, so reset hardware */ 876static int ks959_resume(struct usb_interface *intf) 877{ 878 struct ks959_cb *kingsun = usb_get_intfdata(intf); 879 880 if (kingsun->rx_urb != NULL) { 881 /* Setup request already filled in ks959_probe */ 882 usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); 883 } 884 netif_device_attach(kingsun->netdev); 885 886 return 0; 887} 888#endif 889 890/* 891 * USB device callbacks 892 */ 893static struct usb_driver irda_driver = { 894 .name = "ks959-sir", 895 .probe = ks959_probe, 896 .disconnect = ks959_disconnect, 897 .id_table = dongles, 898#ifdef CONFIG_PM 899 .suspend = ks959_suspend, 900 .resume = ks959_resume, 901#endif 902}; 903 904/* 905 * Module insertion 906 */ 907static int __init ks959_init(void) 908{ 909 return usb_register(&irda_driver); 910} 911 912module_init(ks959_init); 913 914/* 915 * Module removal 916 */ 917static void __exit ks959_cleanup(void) 918{ 919 /* Deregister the driver and remove all pending instances */ 920 usb_deregister(&irda_driver); 921} 922 923module_exit(ks959_cleanup); 924 925MODULE_AUTHOR("Alex Villac��s Lasso <a_villacis@palosanto.com>"); 926MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun KS-959"); 927MODULE_LICENSE("GPL"); 928