Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.14-rc3 915 lines 28 kB view raw
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/slab.h> 120#include <linux/usb.h> 121#include <linux/device.h> 122#include <linux/crc32.h> 123 124#include <asm/unaligned.h> 125#include <asm/byteorder.h> 126#include <asm/uaccess.h> 127 128#include <net/irda/irda.h> 129#include <net/irda/wrapper.h> 130#include <net/irda/crc.h> 131 132#define KS959_VENDOR_ID 0x07d0 133#define KS959_PRODUCT_ID 0x4959 134 135/* These are the currently known USB ids */ 136static struct usb_device_id dongles[] = { 137 /* KingSun Co,Ltd IrDA/USB Bridge */ 138 {USB_DEVICE(KS959_VENDOR_ID, KS959_PRODUCT_ID)}, 139 {} 140}; 141 142MODULE_DEVICE_TABLE(usb, dongles); 143 144#define KINGSUN_MTT 0x07 145#define KINGSUN_REQ_RECV 0x01 146#define KINGSUN_REQ_SEND 0x09 147 148#define KINGSUN_RCV_FIFO_SIZE 2048 /* Max length we can receive */ 149#define KINGSUN_SND_FIFO_SIZE 2048 /* Max packet we can send */ 150#define KINGSUN_SND_PACKET_SIZE 256 /* Max packet dongle can handle */ 151 152struct ks959_speedparams { 153 __le32 baudrate; /* baud rate, little endian */ 154 __u8 flags; 155 __u8 reserved[3]; 156} __packed; 157 158#define KS_DATA_5_BITS 0x00 159#define KS_DATA_6_BITS 0x01 160#define KS_DATA_7_BITS 0x02 161#define KS_DATA_8_BITS 0x03 162 163#define KS_STOP_BITS_1 0x00 164#define KS_STOP_BITS_2 0x08 165 166#define KS_PAR_DISABLE 0x00 167#define KS_PAR_EVEN 0x10 168#define KS_PAR_ODD 0x30 169#define KS_RESET 0x80 170 171struct ks959_cb { 172 struct usb_device *usbdev; /* init: probe_irda */ 173 struct net_device *netdev; /* network layer */ 174 struct irlap_cb *irlap; /* The link layer we are binded to */ 175 176 struct qos_info qos; 177 178 struct usb_ctrlrequest *tx_setuprequest; 179 struct urb *tx_urb; 180 __u8 *tx_buf_clear; 181 unsigned int tx_buf_clear_used; 182 unsigned int tx_buf_clear_sent; 183 __u8 *tx_buf_xored; 184 185 struct usb_ctrlrequest *rx_setuprequest; 186 struct urb *rx_urb; 187 __u8 *rx_buf; 188 __u8 rx_variable_xormask; 189 iobuff_t rx_unwrap_buff; 190 struct timeval rx_time; 191 192 struct usb_ctrlrequest *speed_setuprequest; 193 struct urb *speed_urb; 194 struct ks959_speedparams speedparams; 195 unsigned int new_speed; 196 197 spinlock_t lock; 198 int receiving; 199}; 200 201/* Procedure to perform the obfuscation/padding expected by the dongle 202 * 203 * buf_cleartext (IN) Cleartext version of the IrDA frame to transmit 204 * len_cleartext (IN) Length of the cleartext version of IrDA frame 205 * buf_xoredtext (OUT) Obfuscated version of frame built by proc 206 * len_maxbuf (OUT) Maximum space available at buf_xoredtext 207 * 208 * (return) length of obfuscated frame with padding 209 * 210 * If not enough space (as indicated by len_maxbuf vs. required padding), 211 * zero is returned 212 * 213 * The value of lookup_string is actually a required portion of the algorithm. 214 * Seems the designer of the dongle wanted to state who exactly is responsible 215 * for implementing obfuscation. Send your best (or other) wishes to him ]:-) 216 */ 217static unsigned int obfuscate_tx_buffer(const __u8 * buf_cleartext, 218 unsigned int len_cleartext, 219 __u8 * buf_xoredtext, 220 unsigned int len_maxbuf) 221{ 222 unsigned int len_xoredtext; 223 224 /* Calculate required length with padding, check for necessary space */ 225 len_xoredtext = ((len_cleartext + 7) & ~0x7) + 0x10; 226 if (len_xoredtext <= len_maxbuf) { 227 static const __u8 lookup_string[] = "wangshuofei19710"; 228 __u8 xor_mask; 229 230 /* Unlike the WinXP driver, we *do* clear out the padding */ 231 memset(buf_xoredtext, 0, len_xoredtext); 232 233 xor_mask = lookup_string[(len_cleartext & 0x0f) ^ 0x06] ^ 0x55; 234 235 while (len_cleartext-- > 0) { 236 *buf_xoredtext++ = *buf_cleartext++ ^ xor_mask; 237 } 238 } else { 239 len_xoredtext = 0; 240 } 241 return len_xoredtext; 242} 243 244/* Callback transmission routine */ 245static void ks959_speed_irq(struct urb *urb) 246{ 247 /* unlink, shutdown, unplug, other nasties */ 248 if (urb->status != 0) { 249 dev_err(&urb->dev->dev, 250 "ks959_speed_irq: urb asynchronously failed - %d\n", 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 dev_err(&kingsun->usbdev->dev, 336 "ks959_send_irq: Network not running!\n"); 337 return; 338 } 339 340 /* unlink, shutdown, unplug, other nasties */ 341 if (urb->status != 0) { 342 dev_err(&kingsun->usbdev->dev, 343 "ks959_send_irq: urb asynchronously failed - %d\n", 344 urb->status); 345 return; 346 } 347 348 if (kingsun->tx_buf_clear_used > 0) { 349 /* Update data remaining to be sent */ 350 if (kingsun->tx_buf_clear_sent < kingsun->tx_buf_clear_used) { 351 memmove(kingsun->tx_buf_clear, 352 kingsun->tx_buf_clear + 353 kingsun->tx_buf_clear_sent, 354 kingsun->tx_buf_clear_used - 355 kingsun->tx_buf_clear_sent); 356 } 357 kingsun->tx_buf_clear_used -= kingsun->tx_buf_clear_sent; 358 kingsun->tx_buf_clear_sent = 0; 359 360 if (kingsun->tx_buf_clear_used > 0) { 361 /* There is more data to be sent */ 362 if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) { 363 dev_err(&kingsun->usbdev->dev, 364 "ks959_send_irq: failed tx_urb submit: %d\n", 365 ret); 366 switch (ret) { 367 case -ENODEV: 368 case -EPIPE: 369 break; 370 default: 371 netdev->stats.tx_errors++; 372 netif_start_queue(netdev); 373 } 374 } 375 } else { 376 /* All data sent, send next speed && wake network queue */ 377 if (kingsun->new_speed != -1 && 378 cpu_to_le32(kingsun->new_speed) != 379 kingsun->speedparams.baudrate) 380 ks959_change_speed(kingsun, kingsun->new_speed); 381 382 netif_wake_queue(netdev); 383 } 384 } 385} 386 387/* 388 * Called from net/core when new frame is available. 389 */ 390static netdev_tx_t ks959_hard_xmit(struct sk_buff *skb, 391 struct net_device *netdev) 392{ 393 struct ks959_cb *kingsun; 394 unsigned int wraplen; 395 int ret = 0; 396 397 netif_stop_queue(netdev); 398 399 /* the IRDA wrapping routines don't deal with non linear skb */ 400 SKB_LINEAR_ASSERT(skb); 401 402 kingsun = netdev_priv(netdev); 403 404 spin_lock(&kingsun->lock); 405 kingsun->new_speed = irda_get_next_speed(skb); 406 407 /* Append data to the end of whatever data remains to be transmitted */ 408 wraplen = 409 async_wrap_skb(skb, kingsun->tx_buf_clear, KINGSUN_SND_FIFO_SIZE); 410 kingsun->tx_buf_clear_used = wraplen; 411 412 if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) { 413 dev_err(&kingsun->usbdev->dev, 414 "ks959_hard_xmit: failed tx_urb submit: %d\n", ret); 415 switch (ret) { 416 case -ENODEV: 417 case -EPIPE: 418 break; 419 default: 420 netdev->stats.tx_errors++; 421 netif_start_queue(netdev); 422 } 423 } else { 424 netdev->stats.tx_packets++; 425 netdev->stats.tx_bytes += skb->len; 426 427 } 428 429 dev_kfree_skb(skb); 430 spin_unlock(&kingsun->lock); 431 432 return NETDEV_TX_OK; 433} 434 435/* Receive callback function */ 436static void ks959_rcv_irq(struct urb *urb) 437{ 438 struct ks959_cb *kingsun = urb->context; 439 int ret; 440 441 /* in process of stopping, just drop data */ 442 if (!netif_running(kingsun->netdev)) { 443 kingsun->receiving = 0; 444 return; 445 } 446 447 /* unlink, shutdown, unplug, other nasties */ 448 if (urb->status != 0) { 449 dev_err(&kingsun->usbdev->dev, 450 "kingsun_rcv_irq: urb asynchronously failed - %d\n", 451 urb->status); 452 kingsun->receiving = 0; 453 return; 454 } 455 456 if (urb->actual_length > 0) { 457 __u8 *bytes = urb->transfer_buffer; 458 unsigned int i; 459 460 for (i = 0; i < urb->actual_length; i++) { 461 /* De-obfuscation implemented here: variable portion of 462 xormask is incremented, and then used with the encoded 463 byte for the XOR. The result of the operation is used 464 to unwrap the SIR frame. */ 465 kingsun->rx_variable_xormask++; 466 bytes[i] = 467 bytes[i] ^ kingsun->rx_variable_xormask ^ 0x55u; 468 469 /* rx_variable_xormask doubles as an index counter so we 470 can skip the byte at 0xff (wrapped around to 0). 471 */ 472 if (kingsun->rx_variable_xormask != 0) { 473 async_unwrap_char(kingsun->netdev, 474 &kingsun->netdev->stats, 475 &kingsun->rx_unwrap_buff, 476 bytes[i]); 477 } 478 } 479 do_gettimeofday(&kingsun->rx_time); 480 kingsun->receiving = 481 (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0; 482 } 483 484 /* This urb has already been filled in kingsun_net_open. Setup 485 packet must be re-filled, but it is assumed that urb keeps the 486 pointer to the initial setup packet, as well as the payload buffer. 487 Setup packet is already pre-filled at ks959_probe. 488 */ 489 urb->status = 0; 490 ret = usb_submit_urb(urb, GFP_ATOMIC); 491} 492 493/* 494 * Function kingsun_net_open (dev) 495 * 496 * Network device is taken up. Usually this is done by "ifconfig irda0 up" 497 */ 498static int ks959_net_open(struct net_device *netdev) 499{ 500 struct ks959_cb *kingsun = netdev_priv(netdev); 501 int err = -ENOMEM; 502 char hwname[16]; 503 504 /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */ 505 kingsun->receiving = 0; 506 507 /* Initialize for SIR to copy data directly into skb. */ 508 kingsun->rx_unwrap_buff.in_frame = FALSE; 509 kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; 510 kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU; 511 kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU); 512 if (!kingsun->rx_unwrap_buff.skb) 513 goto free_mem; 514 515 skb_reserve(kingsun->rx_unwrap_buff.skb, 1); 516 kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data; 517 do_gettimeofday(&kingsun->rx_time); 518 519 kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL); 520 if (!kingsun->rx_urb) 521 goto free_mem; 522 523 kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL); 524 if (!kingsun->tx_urb) 525 goto free_mem; 526 527 kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL); 528 if (!kingsun->speed_urb) 529 goto free_mem; 530 531 /* Initialize speed for dongle */ 532 kingsun->new_speed = 9600; 533 err = ks959_change_speed(kingsun, 9600); 534 if (err < 0) 535 goto free_mem; 536 537 /* 538 * Now that everything should be initialized properly, 539 * Open new IrLAP layer instance to take care of us... 540 */ 541 sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); 542 kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); 543 if (!kingsun->irlap) { 544 err = -ENOMEM; 545 dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); 546 goto free_mem; 547 } 548 549 /* Start reception. Setup request already pre-filled in ks959_probe */ 550 usb_fill_control_urb(kingsun->rx_urb, kingsun->usbdev, 551 usb_rcvctrlpipe(kingsun->usbdev, 0), 552 (unsigned char *)kingsun->rx_setuprequest, 553 kingsun->rx_buf, KINGSUN_RCV_FIFO_SIZE, 554 ks959_rcv_irq, kingsun); 555 kingsun->rx_urb->status = 0; 556 err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); 557 if (err) { 558 dev_err(&kingsun->usbdev->dev, 559 "first urb-submit failed: %d\n", err); 560 goto close_irlap; 561 } 562 563 netif_start_queue(netdev); 564 565 /* Situation at this point: 566 - all work buffers allocated 567 - urbs allocated and ready to fill 568 - max rx packet known (in max_rx) 569 - unwrap state machine initialized, in state outside of any frame 570 - receive request in progress 571 - IrLAP layer started, about to hand over packets to send 572 */ 573 574 return 0; 575 576 close_irlap: 577 irlap_close(kingsun->irlap); 578 free_mem: 579 usb_free_urb(kingsun->speed_urb); 580 kingsun->speed_urb = NULL; 581 usb_free_urb(kingsun->tx_urb); 582 kingsun->tx_urb = NULL; 583 usb_free_urb(kingsun->rx_urb); 584 kingsun->rx_urb = NULL; 585 if (kingsun->rx_unwrap_buff.skb) { 586 kfree_skb(kingsun->rx_unwrap_buff.skb); 587 kingsun->rx_unwrap_buff.skb = NULL; 588 kingsun->rx_unwrap_buff.head = NULL; 589 } 590 return err; 591} 592 593/* 594 * Function kingsun_net_close (kingsun) 595 * 596 * Network device is taken down. Usually this is done by 597 * "ifconfig irda0 down" 598 */ 599static int ks959_net_close(struct net_device *netdev) 600{ 601 struct ks959_cb *kingsun = netdev_priv(netdev); 602 603 /* Stop transmit processing */ 604 netif_stop_queue(netdev); 605 606 /* Mop up receive && transmit urb's */ 607 usb_kill_urb(kingsun->tx_urb); 608 usb_free_urb(kingsun->tx_urb); 609 kingsun->tx_urb = NULL; 610 611 usb_kill_urb(kingsun->speed_urb); 612 usb_free_urb(kingsun->speed_urb); 613 kingsun->speed_urb = NULL; 614 615 usb_kill_urb(kingsun->rx_urb); 616 usb_free_urb(kingsun->rx_urb); 617 kingsun->rx_urb = NULL; 618 619 kfree_skb(kingsun->rx_unwrap_buff.skb); 620 kingsun->rx_unwrap_buff.skb = NULL; 621 kingsun->rx_unwrap_buff.head = NULL; 622 kingsun->rx_unwrap_buff.in_frame = FALSE; 623 kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; 624 kingsun->receiving = 0; 625 626 /* Stop and remove instance of IrLAP */ 627 if (kingsun->irlap) 628 irlap_close(kingsun->irlap); 629 630 kingsun->irlap = NULL; 631 632 return 0; 633} 634 635/* 636 * IOCTLs : Extra out-of-band network commands... 637 */ 638static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) 639{ 640 struct if_irda_req *irq = (struct if_irda_req *)rq; 641 struct ks959_cb *kingsun = netdev_priv(netdev); 642 int ret = 0; 643 644 switch (cmd) { 645 case SIOCSBANDWIDTH: /* Set bandwidth */ 646 if (!capable(CAP_NET_ADMIN)) 647 return -EPERM; 648 649 /* Check if the device is still there */ 650 if (netif_device_present(kingsun->netdev)) 651 return ks959_change_speed(kingsun, irq->ifr_baudrate); 652 break; 653 654 case SIOCSMEDIABUSY: /* Set media busy */ 655 if (!capable(CAP_NET_ADMIN)) 656 return -EPERM; 657 658 /* Check if the IrDA stack is still there */ 659 if (netif_running(kingsun->netdev)) 660 irda_device_set_media_busy(kingsun->netdev, TRUE); 661 break; 662 663 case SIOCGRECEIVING: 664 /* Only approximately true */ 665 irq->ifr_receiving = kingsun->receiving; 666 break; 667 668 default: 669 ret = -EOPNOTSUPP; 670 } 671 672 return ret; 673} 674 675static const struct net_device_ops ks959_ops = { 676 .ndo_start_xmit = ks959_hard_xmit, 677 .ndo_open = ks959_net_open, 678 .ndo_stop = ks959_net_close, 679 .ndo_do_ioctl = ks959_net_ioctl, 680}; 681/* 682 * This routine is called by the USB subsystem for each new device 683 * in the system. We need to check if the device is ours, and in 684 * this case start handling it. 685 */ 686static int ks959_probe(struct usb_interface *intf, 687 const struct usb_device_id *id) 688{ 689 struct usb_device *dev = interface_to_usbdev(intf); 690 struct ks959_cb *kingsun = NULL; 691 struct net_device *net = NULL; 692 int ret = -ENOMEM; 693 694 /* Allocate network device container. */ 695 net = alloc_irdadev(sizeof(*kingsun)); 696 if (!net) 697 goto err_out1; 698 699 SET_NETDEV_DEV(net, &intf->dev); 700 kingsun = netdev_priv(net); 701 kingsun->netdev = net; 702 kingsun->usbdev = dev; 703 kingsun->irlap = NULL; 704 kingsun->tx_setuprequest = NULL; 705 kingsun->tx_urb = NULL; 706 kingsun->tx_buf_clear = NULL; 707 kingsun->tx_buf_xored = NULL; 708 kingsun->tx_buf_clear_used = 0; 709 kingsun->tx_buf_clear_sent = 0; 710 711 kingsun->rx_setuprequest = NULL; 712 kingsun->rx_urb = NULL; 713 kingsun->rx_buf = NULL; 714 kingsun->rx_variable_xormask = 0; 715 kingsun->rx_unwrap_buff.in_frame = FALSE; 716 kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME; 717 kingsun->rx_unwrap_buff.skb = NULL; 718 kingsun->receiving = 0; 719 spin_lock_init(&kingsun->lock); 720 721 kingsun->speed_setuprequest = NULL; 722 kingsun->speed_urb = NULL; 723 kingsun->speedparams.baudrate = 0; 724 725 /* Allocate input buffer */ 726 kingsun->rx_buf = kmalloc(KINGSUN_RCV_FIFO_SIZE, GFP_KERNEL); 727 if (!kingsun->rx_buf) 728 goto free_mem; 729 730 /* Allocate input setup packet */ 731 kingsun->rx_setuprequest = 732 kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); 733 if (!kingsun->rx_setuprequest) 734 goto free_mem; 735 kingsun->rx_setuprequest->bRequestType = 736 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 737 kingsun->rx_setuprequest->bRequest = KINGSUN_REQ_RECV; 738 kingsun->rx_setuprequest->wValue = cpu_to_le16(0x0200); 739 kingsun->rx_setuprequest->wIndex = 0; 740 kingsun->rx_setuprequest->wLength = cpu_to_le16(KINGSUN_RCV_FIFO_SIZE); 741 742 /* Allocate output buffer */ 743 kingsun->tx_buf_clear = kmalloc(KINGSUN_SND_FIFO_SIZE, GFP_KERNEL); 744 if (!kingsun->tx_buf_clear) 745 goto free_mem; 746 kingsun->tx_buf_xored = kmalloc(KINGSUN_SND_PACKET_SIZE, GFP_KERNEL); 747 if (!kingsun->tx_buf_xored) 748 goto free_mem; 749 750 /* Allocate and initialize output setup packet */ 751 kingsun->tx_setuprequest = 752 kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); 753 if (!kingsun->tx_setuprequest) 754 goto free_mem; 755 kingsun->tx_setuprequest->bRequestType = 756 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 757 kingsun->tx_setuprequest->bRequest = KINGSUN_REQ_SEND; 758 kingsun->tx_setuprequest->wValue = 0; 759 kingsun->tx_setuprequest->wIndex = 0; 760 kingsun->tx_setuprequest->wLength = 0; 761 762 /* Allocate and initialize speed setup packet */ 763 kingsun->speed_setuprequest = 764 kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); 765 if (!kingsun->speed_setuprequest) 766 goto free_mem; 767 kingsun->speed_setuprequest->bRequestType = 768 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 769 kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND; 770 kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200); 771 kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001); 772 kingsun->speed_setuprequest->wLength = 773 cpu_to_le16(sizeof(struct ks959_speedparams)); 774 775 printk(KERN_INFO "KingSun KS-959 IRDA/USB found at address %d, " 776 "Vendor: %x, Product: %x\n", 777 dev->devnum, le16_to_cpu(dev->descriptor.idVendor), 778 le16_to_cpu(dev->descriptor.idProduct)); 779 780 /* Initialize QoS for this device */ 781 irda_init_max_qos_capabilies(&kingsun->qos); 782 783 /* Baud rates known to be supported. Please uncomment if devices (other 784 than a SonyEriccson K300 phone) can be shown to support higher speed 785 with this dongle. 786 */ 787 kingsun->qos.baud_rate.bits = 788 IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600; 789 kingsun->qos.min_turn_time.bits &= KINGSUN_MTT; 790 irda_qos_bits_to_value(&kingsun->qos); 791 792 /* Override the network functions we need to use */ 793 net->netdev_ops = &ks959_ops; 794 795 ret = register_netdev(net); 796 if (ret != 0) 797 goto free_mem; 798 799 dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n", 800 net->name); 801 802 usb_set_intfdata(intf, kingsun); 803 804 /* Situation at this point: 805 - all work buffers allocated 806 - setup requests pre-filled 807 - urbs not allocated, set to NULL 808 - max rx packet known (is KINGSUN_FIFO_SIZE) 809 - unwrap state machine (partially) initialized, but skb == NULL 810 */ 811 812 return 0; 813 814 free_mem: 815 kfree(kingsun->speed_setuprequest); 816 kfree(kingsun->tx_setuprequest); 817 kfree(kingsun->tx_buf_xored); 818 kfree(kingsun->tx_buf_clear); 819 kfree(kingsun->rx_setuprequest); 820 kfree(kingsun->rx_buf); 821 free_netdev(net); 822 err_out1: 823 return ret; 824} 825 826/* 827 * The current device is removed, the USB layer tell us to shut it down... 828 */ 829static void ks959_disconnect(struct usb_interface *intf) 830{ 831 struct ks959_cb *kingsun = usb_get_intfdata(intf); 832 833 if (!kingsun) 834 return; 835 836 unregister_netdev(kingsun->netdev); 837 838 /* Mop up receive && transmit urb's */ 839 if (kingsun->speed_urb != NULL) { 840 usb_kill_urb(kingsun->speed_urb); 841 usb_free_urb(kingsun->speed_urb); 842 kingsun->speed_urb = NULL; 843 } 844 if (kingsun->tx_urb != NULL) { 845 usb_kill_urb(kingsun->tx_urb); 846 usb_free_urb(kingsun->tx_urb); 847 kingsun->tx_urb = NULL; 848 } 849 if (kingsun->rx_urb != NULL) { 850 usb_kill_urb(kingsun->rx_urb); 851 usb_free_urb(kingsun->rx_urb); 852 kingsun->rx_urb = NULL; 853 } 854 855 kfree(kingsun->speed_setuprequest); 856 kfree(kingsun->tx_setuprequest); 857 kfree(kingsun->tx_buf_xored); 858 kfree(kingsun->tx_buf_clear); 859 kfree(kingsun->rx_setuprequest); 860 kfree(kingsun->rx_buf); 861 free_netdev(kingsun->netdev); 862 863 usb_set_intfdata(intf, NULL); 864} 865 866#ifdef CONFIG_PM 867/* USB suspend, so power off the transmitter/receiver */ 868static int ks959_suspend(struct usb_interface *intf, pm_message_t message) 869{ 870 struct ks959_cb *kingsun = usb_get_intfdata(intf); 871 872 netif_device_detach(kingsun->netdev); 873 if (kingsun->speed_urb != NULL) 874 usb_kill_urb(kingsun->speed_urb); 875 if (kingsun->tx_urb != NULL) 876 usb_kill_urb(kingsun->tx_urb); 877 if (kingsun->rx_urb != NULL) 878 usb_kill_urb(kingsun->rx_urb); 879 return 0; 880} 881 882/* Coming out of suspend, so reset hardware */ 883static int ks959_resume(struct usb_interface *intf) 884{ 885 struct ks959_cb *kingsun = usb_get_intfdata(intf); 886 887 if (kingsun->rx_urb != NULL) { 888 /* Setup request already filled in ks959_probe */ 889 usb_submit_urb(kingsun->rx_urb, GFP_KERNEL); 890 } 891 netif_device_attach(kingsun->netdev); 892 893 return 0; 894} 895#endif 896 897/* 898 * USB device callbacks 899 */ 900static struct usb_driver irda_driver = { 901 .name = "ks959-sir", 902 .probe = ks959_probe, 903 .disconnect = ks959_disconnect, 904 .id_table = dongles, 905#ifdef CONFIG_PM 906 .suspend = ks959_suspend, 907 .resume = ks959_resume, 908#endif 909}; 910 911module_usb_driver(irda_driver); 912 913MODULE_AUTHOR("Alex Villacís Lasso <a_villacis@palosanto.com>"); 914MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun KS-959"); 915MODULE_LICENSE("GPL");