1 /*****************************************************************************
 
   5 * Description:   Irda KingSun Dazzle USB Dongle
 
   7 * Author:        Alex Villacís Lasso <a_villacis@palosanto.com>
 
   9 *    Based on stir4200, mcs7780, kingsun-sir drivers.
 
  11 *    This program is free software; you can redistribute it and/or modify
 
  12 *    it under the terms of the GNU General Public License as published by
 
  13 *    the Free Software Foundation; either version 2 of the License.
 
  15 *    This program is distributed in the hope that it will be useful,
 
  16 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  17 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  18 *    GNU General Public License for more details.
 
  20 *    You should have received a copy of the GNU General Public License
 
  21 *    along with this program; if not, write to the Free Software
 
  22 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
  24 *****************************************************************************/
 
  27  * Following is my most current (2007-07-26) understanding of how the Kingsun
 
  28  * 07D0:4100 dongle (sometimes known as the MA-660) is supposed to work. This
 
  29  * information was deduced by examining the USB traffic captured with USBSnoopy
 
  30  * from the WinXP driver. Feel free to update here as more of the dongle is
 
  33  * General: This dongle exposes one interface with two interrupt endpoints, one
 
  34  * IN and one OUT. In this regard, it is similar to what the Kingsun/Donshine
 
  35  * dongle (07c0:4200) exposes. Traffic is raw and needs to be wrapped and
 
  36  * unwrapped manually as in stir4200, kingsun-sir, and ks959-sir.
 
  38  * Transmission: To transmit an IrDA frame, it is necessary to wrap it, then
 
  39  * split it into multiple segments of up to 7 bytes each, and transmit each in
 
  40  * sequence. It seems that sending a single big block (like kingsun-sir does)
 
  41  * won't work with this dongle. Each segment needs to be prefixed with a value
 
  42  * equal to (unsigned char)0xF8 + <number of bytes in segment>, inside a payload
 
  43  * of exactly 8 bytes. For example, a segment of 1 byte gets prefixed by 0xF9,
 
  44  * and one of 7 bytes gets prefixed by 0xFF. The bytes at the end of the
 
  45  * payload, not considered by the prefix, are ignored (set to 0 by this
 
  48  * Reception: To receive data, the driver must poll the dongle regularly (like
 
  49  * kingsun-sir.c) with interrupt URBs. If data is available, it will be returned
 
  50  * in payloads from 0 to 8 bytes long. When concatenated, these payloads form
 
  51  * a raw IrDA stream that needs to be unwrapped as in stir4200 and kingsun-sir
 
  53  * Speed change: To change the speed of the dongle, the driver prepares a
 
  54  * control URB with the following as a setup packet:
 
  55  *    bRequestType    USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
 
  59  *    wLength         0x0008 (length of the payload)
 
  60  * The payload is a 8-byte record, apparently identical to the one used in
 
  61  * drivers/usb/serial/cypress_m8.c to change speed:
 
  63  *    unsigned int dataBits : 2;    // 0 - 5 bits 3 - 8 bits
 
  65  *    unsigned int stopBits : 1;
 
  66  *    unsigned int parityEnable : 1;
 
  67  *    unsigned int parityType : 1;
 
  69  *    unsigned int reset : 1;
 
  70  *    unsigned char reserved[3];    // set to 0
 
  72  * For now only SIR speeds have been observed with this dongle. Therefore,
 
  73  * nothing is known on what changes (if any) must be done to frame wrapping /
 
  74  * unwrapping for higher than SIR speeds. This driver assumes no change is
 
  75  * necessary and announces support for all the way to 115200 bps.
 
  78 #include <linux/module.h>
 
  79 #include <linux/moduleparam.h>
 
  80 #include <linux/kernel.h>
 
  81 #include <linux/types.h>
 
  82 #include <linux/errno.h>
 
  83 #include <linux/init.h>
 
  84 #include <linux/slab.h>
 
  85 #include <linux/module.h>
 
  86 #include <linux/kref.h>
 
  87 #include <linux/usb.h>
 
  88 #include <linux/device.h>
 
  89 #include <linux/crc32.h>
 
  91 #include <asm/unaligned.h>
 
  92 #include <asm/byteorder.h>
 
  93 #include <asm/uaccess.h>
 
  95 #include <net/irda/irda.h>
 
  96 #include <net/irda/wrapper.h>
 
  97 #include <net/irda/crc.h>
 
  99 #define KSDAZZLE_VENDOR_ID 0x07d0
 
 100 #define KSDAZZLE_PRODUCT_ID 0x4100
 
 102 /* These are the currently known USB ids */
 
 103 static struct usb_device_id dongles[] = {
 
 104         /* KingSun Co,Ltd  IrDA/USB Bridge */
 
 105         {USB_DEVICE(KSDAZZLE_VENDOR_ID, KSDAZZLE_PRODUCT_ID)},
 
 109 MODULE_DEVICE_TABLE(usb, dongles);
 
 111 #define KINGSUN_MTT 0x07
 
 112 #define KINGSUN_REQ_RECV 0x01
 
 113 #define KINGSUN_REQ_SEND 0x09
 
 115 #define KINGSUN_SND_FIFO_SIZE    2048   /* Max packet we can send */
 
 116 #define KINGSUN_RCV_MAX 2048    /* Max transfer we can receive */
 
 118 struct ksdazzle_speedparams {
 
 119         __le32 baudrate;        /* baud rate, little endian */
 
 122 } __attribute__ ((packed));
 
 124 #define KS_DATA_5_BITS 0x00
 
 125 #define KS_DATA_6_BITS 0x01
 
 126 #define KS_DATA_7_BITS 0x02
 
 127 #define KS_DATA_8_BITS 0x03
 
 129 #define KS_STOP_BITS_1 0x00
 
 130 #define KS_STOP_BITS_2 0x08
 
 132 #define KS_PAR_DISABLE    0x00
 
 133 #define KS_PAR_EVEN    0x10
 
 134 #define KS_PAR_ODD    0x30
 
 135 #define KS_RESET    0x80
 
 137 #define KINGSUN_EP_IN                   0
 
 138 #define KINGSUN_EP_OUT                  1
 
 141         struct usb_device *usbdev;      /* init: probe_irda */
 
 142         struct net_device *netdev;      /* network layer */
 
 143         struct irlap_cb *irlap; /* The link layer we are binded to */
 
 144         struct net_device_stats stats;  /* network statistics */
 
 149         unsigned int tx_buf_clear_used;
 
 150         unsigned int tx_buf_clear_sent;
 
 155         iobuff_t rx_unwrap_buff;
 
 157         struct usb_ctrlrequest *speed_setuprequest;
 
 158         struct urb *speed_urb;
 
 159         struct ksdazzle_speedparams speedparams;
 
 160         unsigned int new_speed;
 
 169 /* Callback transmission routine */
 
 170 static void ksdazzle_speed_irq(struct urb *urb)
 
 172         /* unlink, shutdown, unplug, other nasties */
 
 173         if (urb->status != 0) {
 
 174                 err("ksdazzle_speed_irq: urb asynchronously failed - %d",
 
 179 /* Send a control request to change speed of the dongle */
 
 180 static int ksdazzle_change_speed(struct ksdazzle_cb *kingsun, unsigned speed)
 
 182         static unsigned int supported_speeds[] = { 2400, 9600, 19200, 38400,
 
 183                 57600, 115200, 576000, 1152000, 4000000, 0
 
 188         if (kingsun->speed_setuprequest == NULL || kingsun->speed_urb == NULL)
 
 191         /* Check that requested speed is among the supported ones */
 
 192         for (i = 0; supported_speeds[i] && supported_speeds[i] != speed; i++) ;
 
 193         if (supported_speeds[i] == 0)
 
 196         memset(&(kingsun->speedparams), 0, sizeof(struct ksdazzle_speedparams));
 
 197         kingsun->speedparams.baudrate = cpu_to_le32(speed);
 
 198         kingsun->speedparams.flags = KS_DATA_8_BITS;
 
 200         /* speed_setuprequest pre-filled in ksdazzle_probe */
 
 201         usb_fill_control_urb(kingsun->speed_urb, kingsun->usbdev,
 
 202                              usb_sndctrlpipe(kingsun->usbdev, 0),
 
 203                              (unsigned char *)kingsun->speed_setuprequest,
 
 204                              &(kingsun->speedparams),
 
 205                              sizeof(struct ksdazzle_speedparams),
 
 206                              ksdazzle_speed_irq, kingsun);
 
 207         kingsun->speed_urb->status = 0;
 
 208         err = usb_submit_urb(kingsun->speed_urb, GFP_ATOMIC);
 
 213 /* Submit one fragment of an IrDA frame to the dongle */
 
 214 static void ksdazzle_send_irq(struct urb *urb);
 
 215 static int ksdazzle_submit_tx_fragment(struct ksdazzle_cb *kingsun)
 
 217         unsigned int wraplen;
 
 220         /* We can send at most 7 bytes of payload at a time */
 
 222         if (wraplen > kingsun->tx_buf_clear_used)
 
 223                 wraplen = kingsun->tx_buf_clear_used;
 
 225         /* Prepare payload prefix with used length */
 
 226         memset(kingsun->tx_payload, 0, 8);
 
 227         kingsun->tx_payload[0] = (unsigned char)0xf8 + wraplen;
 
 228         memcpy(kingsun->tx_payload + 1, kingsun->tx_buf_clear, wraplen);
 
 230         usb_fill_int_urb(kingsun->tx_urb, kingsun->usbdev,
 
 231                          usb_sndintpipe(kingsun->usbdev, kingsun->ep_out),
 
 232                          kingsun->tx_payload, 8, ksdazzle_send_irq, kingsun, 1);
 
 233         kingsun->tx_urb->status = 0;
 
 234         ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC);
 
 236         /* Remember how much data was sent, in order to update at callback */
 
 237         kingsun->tx_buf_clear_sent = (ret == 0) ? wraplen : 0;
 
 241 /* Callback transmission routine */
 
 242 static void ksdazzle_send_irq(struct urb *urb)
 
 244         struct ksdazzle_cb *kingsun = urb->context;
 
 245         struct net_device *netdev = kingsun->netdev;
 
 248         /* in process of stopping, just drop data */
 
 249         if (!netif_running(kingsun->netdev)) {
 
 250                 err("ksdazzle_send_irq: Network not running!");
 
 254         /* unlink, shutdown, unplug, other nasties */
 
 255         if (urb->status != 0) {
 
 256                 err("ksdazzle_send_irq: urb asynchronously failed - %d",
 
 261         if (kingsun->tx_buf_clear_used > 0) {
 
 262                 /* Update data remaining to be sent */
 
 263                 if (kingsun->tx_buf_clear_sent < kingsun->tx_buf_clear_used) {
 
 264                         memmove(kingsun->tx_buf_clear,
 
 265                                 kingsun->tx_buf_clear +
 
 266                                 kingsun->tx_buf_clear_sent,
 
 267                                 kingsun->tx_buf_clear_used -
 
 268                                 kingsun->tx_buf_clear_sent);
 
 270                 kingsun->tx_buf_clear_used -= kingsun->tx_buf_clear_sent;
 
 271                 kingsun->tx_buf_clear_sent = 0;
 
 273                 if (kingsun->tx_buf_clear_used > 0) {
 
 274                         /* There is more data to be sent */
 
 275                         if ((ret = ksdazzle_submit_tx_fragment(kingsun)) != 0) {
 
 276                                 err("ksdazzle_send_irq: failed tx_urb submit: %d", ret);
 
 282                                         kingsun->stats.tx_errors++;
 
 283                                         netif_start_queue(netdev);
 
 287                         /* All data sent, send next speed && wake network queue */
 
 288                         if (kingsun->new_speed != -1 &&
 
 289                             cpu_to_le32(kingsun->new_speed) !=
 
 290                             kingsun->speedparams.baudrate)
 
 291                                 ksdazzle_change_speed(kingsun,
 
 294                         netif_wake_queue(netdev);
 
 300  * Called from net/core when new frame is available.
 
 302 static int ksdazzle_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 304         struct ksdazzle_cb *kingsun;
 
 305         unsigned int wraplen;
 
 308         if (skb == NULL || netdev == NULL)
 
 311         netif_stop_queue(netdev);
 
 313         /* the IRDA wrapping routines don't deal with non linear skb */
 
 314         SKB_LINEAR_ASSERT(skb);
 
 316         kingsun = netdev_priv(netdev);
 
 318         spin_lock(&kingsun->lock);
 
 319         kingsun->new_speed = irda_get_next_speed(skb);
 
 321         /* Append data to the end of whatever data remains to be transmitted */
 
 323             async_wrap_skb(skb, kingsun->tx_buf_clear, KINGSUN_SND_FIFO_SIZE);
 
 324         kingsun->tx_buf_clear_used = wraplen;
 
 326         if ((ret = ksdazzle_submit_tx_fragment(kingsun)) != 0) {
 
 327                 err("ksdazzle_hard_xmit: failed tx_urb submit: %d", ret);
 
 333                         kingsun->stats.tx_errors++;
 
 334                         netif_start_queue(netdev);
 
 337                 kingsun->stats.tx_packets++;
 
 338                 kingsun->stats.tx_bytes += skb->len;
 
 343         spin_unlock(&kingsun->lock);
 
 348 /* Receive callback function */
 
 349 static void ksdazzle_rcv_irq(struct urb *urb)
 
 351         struct ksdazzle_cb *kingsun = urb->context;
 
 353         /* in process of stopping, just drop data */
 
 354         if (!netif_running(kingsun->netdev)) {
 
 355                 kingsun->receiving = 0;
 
 359         /* unlink, shutdown, unplug, other nasties */
 
 360         if (urb->status != 0) {
 
 361                 err("ksdazzle_rcv_irq: urb asynchronously failed - %d",
 
 363                 kingsun->receiving = 0;
 
 367         if (urb->actual_length > 0) {
 
 368                 __u8 *bytes = urb->transfer_buffer;
 
 371                 for (i = 0; i < urb->actual_length; i++) {
 
 372                         async_unwrap_char(kingsun->netdev, &kingsun->stats,
 
 373                                           &kingsun->rx_unwrap_buff, bytes[i]);
 
 375                 kingsun->netdev->last_rx = jiffies;
 
 377                     (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0;
 
 380         /* This urb has already been filled in ksdazzle_net_open. It is assumed that
 
 381            urb keeps the pointer to the payload buffer.
 
 384         usb_submit_urb(urb, GFP_ATOMIC);
 
 388  * Function ksdazzle_net_open (dev)
 
 390  *    Network device is taken up. Usually this is done by "ifconfig irda0 up"
 
 392 static int ksdazzle_net_open(struct net_device *netdev)
 
 394         struct ksdazzle_cb *kingsun = netdev_priv(netdev);
 
 398         /* At this point, urbs are NULL, and skb is NULL (see ksdazzle_probe) */
 
 399         kingsun->receiving = 0;
 
 401         /* Initialize for SIR to copy data directly into skb.  */
 
 402         kingsun->rx_unwrap_buff.in_frame = FALSE;
 
 403         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
 
 404         kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU;
 
 405         kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
 
 406         if (!kingsun->rx_unwrap_buff.skb)
 
 409         skb_reserve(kingsun->rx_unwrap_buff.skb, 1);
 
 410         kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data;
 
 412         kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
 
 413         if (!kingsun->rx_urb)
 
 416         kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
 
 417         if (!kingsun->tx_urb)
 
 420         kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
 
 421         if (!kingsun->speed_urb)
 
 424         /* Initialize speed for dongle */
 
 425         kingsun->new_speed = 9600;
 
 426         err = ksdazzle_change_speed(kingsun, 9600);
 
 431          * Now that everything should be initialized properly,
 
 432          * Open new IrLAP layer instance to take care of us...
 
 434         sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
 
 435         kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
 
 436         if (!kingsun->irlap) {
 
 437                 err("ksdazzle-sir: irlap_open failed");
 
 441         /* Start reception. */
 
 442         usb_fill_int_urb(kingsun->rx_urb, kingsun->usbdev,
 
 443                          usb_rcvintpipe(kingsun->usbdev, kingsun->ep_in),
 
 444                          kingsun->rx_buf, KINGSUN_RCV_MAX, ksdazzle_rcv_irq,
 
 446         kingsun->rx_urb->status = 0;
 
 447         err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
 
 449                 err("ksdazzle-sir: first urb-submit failed: %d", err);
 
 453         netif_start_queue(netdev);
 
 455         /* Situation at this point:
 
 456            - all work buffers allocated
 
 457            - urbs allocated and ready to fill
 
 458            - max rx packet known (in max_rx)
 
 459            - unwrap state machine initialized, in state outside of any frame
 
 460            - receive request in progress
 
 461            - IrLAP layer started, about to hand over packets to send
 
 467         irlap_close(kingsun->irlap);
 
 469         usb_free_urb(kingsun->speed_urb);
 
 470         kingsun->speed_urb = NULL;
 
 471         usb_free_urb(kingsun->tx_urb);
 
 472         kingsun->tx_urb = NULL;
 
 473         usb_free_urb(kingsun->rx_urb);
 
 474         kingsun->rx_urb = NULL;
 
 475         if (kingsun->rx_unwrap_buff.skb) {
 
 476                 kfree_skb(kingsun->rx_unwrap_buff.skb);
 
 477                 kingsun->rx_unwrap_buff.skb = NULL;
 
 478                 kingsun->rx_unwrap_buff.head = NULL;
 
 484  * Function ksdazzle_net_close (dev)
 
 486  *    Network device is taken down. Usually this is done by
 
 487  *    "ifconfig irda0 down"
 
 489 static int ksdazzle_net_close(struct net_device *netdev)
 
 491         struct ksdazzle_cb *kingsun = netdev_priv(netdev);
 
 493         /* Stop transmit processing */
 
 494         netif_stop_queue(netdev);
 
 496         /* Mop up receive && transmit urb's */
 
 497         usb_kill_urb(kingsun->tx_urb);
 
 498         usb_free_urb(kingsun->tx_urb);
 
 499         kingsun->tx_urb = NULL;
 
 501         usb_kill_urb(kingsun->speed_urb);
 
 502         usb_free_urb(kingsun->speed_urb);
 
 503         kingsun->speed_urb = NULL;
 
 505         usb_kill_urb(kingsun->rx_urb);
 
 506         usb_free_urb(kingsun->rx_urb);
 
 507         kingsun->rx_urb = NULL;
 
 509         kfree_skb(kingsun->rx_unwrap_buff.skb);
 
 510         kingsun->rx_unwrap_buff.skb = NULL;
 
 511         kingsun->rx_unwrap_buff.head = NULL;
 
 512         kingsun->rx_unwrap_buff.in_frame = FALSE;
 
 513         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
 
 514         kingsun->receiving = 0;
 
 516         /* Stop and remove instance of IrLAP */
 
 517         irlap_close(kingsun->irlap);
 
 519         kingsun->irlap = NULL;
 
 525  * IOCTLs : Extra out-of-band network commands...
 
 527 static int ksdazzle_net_ioctl(struct net_device *netdev, struct ifreq *rq,
 
 530         struct if_irda_req *irq = (struct if_irda_req *)rq;
 
 531         struct ksdazzle_cb *kingsun = netdev_priv(netdev);
 
 535         case SIOCSBANDWIDTH:    /* Set bandwidth */
 
 536                 if (!capable(CAP_NET_ADMIN))
 
 539                 /* Check if the device is still there */
 
 540                 if (netif_device_present(kingsun->netdev))
 
 541                         return ksdazzle_change_speed(kingsun,
 
 545         case SIOCSMEDIABUSY:    /* Set media busy */
 
 546                 if (!capable(CAP_NET_ADMIN))
 
 549                 /* Check if the IrDA stack is still there */
 
 550                 if (netif_running(kingsun->netdev))
 
 551                         irda_device_set_media_busy(kingsun->netdev, TRUE);
 
 555                 /* Only approximately true */
 
 556                 irq->ifr_receiving = kingsun->receiving;
 
 567  * Get device stats (for /proc/net/dev and ifconfig)
 
 569 static struct net_device_stats *ksdazzle_net_get_stats(struct net_device
 
 572         struct ksdazzle_cb *kingsun = netdev_priv(netdev);
 
 573         return &kingsun->stats;
 
 577  * This routine is called by the USB subsystem for each new device
 
 578  * in the system. We need to check if the device is ours, and in
 
 579  * this case start handling it.
 
 581 static int ksdazzle_probe(struct usb_interface *intf,
 
 582                           const struct usb_device_id *id)
 
 584         struct usb_host_interface *interface;
 
 585         struct usb_endpoint_descriptor *endpoint;
 
 587         struct usb_device *dev = interface_to_usbdev(intf);
 
 588         struct ksdazzle_cb *kingsun = NULL;
 
 589         struct net_device *net = NULL;
 
 591         int pipe, maxp_in, maxp_out;
 
 595         /* Check that there really are two interrupt endpoints. Check based on the
 
 596            one in drivers/usb/input/usbmouse.c
 
 598         interface = intf->cur_altsetting;
 
 599         if (interface->desc.bNumEndpoints != 2) {
 
 600                 err("ksdazzle: expected 2 endpoints, found %d",
 
 601                     interface->desc.bNumEndpoints);
 
 604         endpoint = &interface->endpoint[KINGSUN_EP_IN].desc;
 
 605         if (!usb_endpoint_is_int_in(endpoint)) {
 
 606                 err("ksdazzle: endpoint 0 is not interrupt IN");
 
 610         ep_in = endpoint->bEndpointAddress;
 
 611         pipe = usb_rcvintpipe(dev, ep_in);
 
 612         maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
 613         if (maxp_in > 255 || maxp_in <= 1) {
 
 614                 err("ksdazzle: endpoint 0 has max packet size %d not in range [2..255]", maxp_in);
 
 618         endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc;
 
 619         if (!usb_endpoint_is_int_out(endpoint)) {
 
 620                 err("ksdazzle: endpoint 1 is not interrupt OUT");
 
 624         ep_out = endpoint->bEndpointAddress;
 
 625         pipe = usb_sndintpipe(dev, ep_out);
 
 626         maxp_out = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
 628         /* Allocate network device container. */
 
 629         net = alloc_irdadev(sizeof(*kingsun));
 
 633         SET_NETDEV_DEV(net, &intf->dev);
 
 634         kingsun = netdev_priv(net);
 
 635         kingsun->netdev = net;
 
 636         kingsun->usbdev = dev;
 
 637         kingsun->ep_in = ep_in;
 
 638         kingsun->ep_out = ep_out;
 
 639         kingsun->irlap = NULL;
 
 640         kingsun->tx_urb = NULL;
 
 641         kingsun->tx_buf_clear = NULL;
 
 642         kingsun->tx_buf_clear_used = 0;
 
 643         kingsun->tx_buf_clear_sent = 0;
 
 645         kingsun->rx_urb = NULL;
 
 646         kingsun->rx_buf = NULL;
 
 647         kingsun->rx_unwrap_buff.in_frame = FALSE;
 
 648         kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
 
 649         kingsun->rx_unwrap_buff.skb = NULL;
 
 650         kingsun->receiving = 0;
 
 651         spin_lock_init(&kingsun->lock);
 
 653         kingsun->speed_setuprequest = NULL;
 
 654         kingsun->speed_urb = NULL;
 
 655         kingsun->speedparams.baudrate = 0;
 
 657         /* Allocate input buffer */
 
 658         kingsun->rx_buf = kmalloc(KINGSUN_RCV_MAX, GFP_KERNEL);
 
 659         if (!kingsun->rx_buf)
 
 662         /* Allocate output buffer */
 
 663         kingsun->tx_buf_clear = kmalloc(KINGSUN_SND_FIFO_SIZE, GFP_KERNEL);
 
 664         if (!kingsun->tx_buf_clear)
 
 667         /* Allocate and initialize speed setup packet */
 
 668         kingsun->speed_setuprequest =
 
 669             kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
 
 670         if (!kingsun->speed_setuprequest)
 
 672         kingsun->speed_setuprequest->bRequestType =
 
 673             USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
 
 674         kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND;
 
 675         kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200);
 
 676         kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001);
 
 677         kingsun->speed_setuprequest->wLength =
 
 678             cpu_to_le16(sizeof(struct ksdazzle_speedparams));
 
 680         printk(KERN_INFO "KingSun/Dazzle IRDA/USB found at address %d, "
 
 681                "Vendor: %x, Product: %x\n",
 
 682                dev->devnum, le16_to_cpu(dev->descriptor.idVendor),
 
 683                le16_to_cpu(dev->descriptor.idProduct));
 
 685         /* Initialize QoS for this device */
 
 686         irda_init_max_qos_capabilies(&kingsun->qos);
 
 688         /* Baud rates known to be supported. Please uncomment if devices (other
 
 689            than a SonyEriccson K300 phone) can be shown to support higher speeds
 
 692         kingsun->qos.baud_rate.bits =
 
 693             IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200;
 
 694         kingsun->qos.min_turn_time.bits &= KINGSUN_MTT;
 
 695         irda_qos_bits_to_value(&kingsun->qos);
 
 697         /* Override the network functions we need to use */
 
 698         net->hard_start_xmit = ksdazzle_hard_xmit;
 
 699         net->open = ksdazzle_net_open;
 
 700         net->stop = ksdazzle_net_close;
 
 701         net->get_stats = ksdazzle_net_get_stats;
 
 702         net->do_ioctl = ksdazzle_net_ioctl;
 
 704         ret = register_netdev(net);
 
 708         info("IrDA: Registered KingSun/Dazzle device %s", net->name);
 
 710         usb_set_intfdata(intf, kingsun);
 
 712         /* Situation at this point:
 
 713            - all work buffers allocated
 
 714            - setup requests pre-filled
 
 715            - urbs not allocated, set to NULL
 
 716            - max rx packet known (is KINGSUN_FIFO_SIZE)
 
 717            - unwrap state machine (partially) initialized, but skb == NULL
 
 723         kfree(kingsun->speed_setuprequest);
 
 724         kfree(kingsun->tx_buf_clear);
 
 725         kfree(kingsun->rx_buf);
 
 732  * The current device is removed, the USB layer tell us to shut it down...
 
 734 static void ksdazzle_disconnect(struct usb_interface *intf)
 
 736         struct ksdazzle_cb *kingsun = usb_get_intfdata(intf);
 
 741         unregister_netdev(kingsun->netdev);
 
 743         /* Mop up receive && transmit urb's */
 
 744         usb_kill_urb(kingsun->speed_urb);
 
 745         usb_free_urb(kingsun->speed_urb);
 
 746         kingsun->speed_urb = NULL;
 
 748         usb_kill_urb(kingsun->tx_urb);
 
 749         usb_free_urb(kingsun->tx_urb);
 
 750         kingsun->tx_urb = NULL;
 
 752         usb_kill_urb(kingsun->rx_urb);
 
 753         usb_free_urb(kingsun->rx_urb);
 
 754         kingsun->rx_urb = NULL;
 
 756         kfree(kingsun->speed_setuprequest);
 
 757         kfree(kingsun->tx_buf_clear);
 
 758         kfree(kingsun->rx_buf);
 
 759         free_netdev(kingsun->netdev);
 
 761         usb_set_intfdata(intf, NULL);
 
 765 /* USB suspend, so power off the transmitter/receiver */
 
 766 static int ksdazzle_suspend(struct usb_interface *intf, pm_message_t message)
 
 768         struct ksdazzle_cb *kingsun = usb_get_intfdata(intf);
 
 770         netif_device_detach(kingsun->netdev);
 
 771         if (kingsun->speed_urb != NULL)
 
 772                 usb_kill_urb(kingsun->speed_urb);
 
 773         if (kingsun->tx_urb != NULL)
 
 774                 usb_kill_urb(kingsun->tx_urb);
 
 775         if (kingsun->rx_urb != NULL)
 
 776                 usb_kill_urb(kingsun->rx_urb);
 
 780 /* Coming out of suspend, so reset hardware */
 
 781 static int ksdazzle_resume(struct usb_interface *intf)
 
 783         struct ksdazzle_cb *kingsun = usb_get_intfdata(intf);
 
 785         if (kingsun->rx_urb != NULL) {
 
 786                 /* Setup request already filled in ksdazzle_probe */
 
 787                 usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
 
 789         netif_device_attach(kingsun->netdev);
 
 796  * USB device callbacks
 
 798 static struct usb_driver irda_driver = {
 
 799         .name = "ksdazzle-sir",
 
 800         .probe = ksdazzle_probe,
 
 801         .disconnect = ksdazzle_disconnect,
 
 804         .suspend = ksdazzle_suspend,
 
 805         .resume = ksdazzle_resume,
 
 812 static int __init ksdazzle_init(void)
 
 814         return usb_register(&irda_driver);
 
 817 module_init(ksdazzle_init);
 
 822 static void __exit ksdazzle_cleanup(void)
 
 824         /* Deregister the driver and remove all pending instances */
 
 825         usb_deregister(&irda_driver);
 
 828 module_exit(ksdazzle_cleanup);
 
 830 MODULE_AUTHOR("Alex Villacís Lasso <a_villacis@palosanto.com>");
 
 831 MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun Dazzle");
 
 832 MODULE_LICENSE("GPL");