linux/drivers/net/irda/ks959-sir.c
<<
>>
Prefs
   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} __attribute__ ((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