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