114 #include <linux/module.h>
116 #include <linux/kernel.h>
117 #include <linux/types.h>
118 #include <linux/errno.h>
120 #include <linux/slab.h>
122 #include <linux/device.h>
125 #include <asm/unaligned.h>
126 #include <asm/byteorder.h>
127 #include <asm/uaccess.h>
133 #define KS959_VENDOR_ID 0x07d0
134 #define KS959_PRODUCT_ID 0x4959
145 #define KINGSUN_MTT 0x07
146 #define KINGSUN_REQ_RECV 0x01
147 #define KINGSUN_REQ_SEND 0x09
149 #define KINGSUN_RCV_FIFO_SIZE 2048
150 #define KINGSUN_SND_FIFO_SIZE 2048
151 #define KINGSUN_SND_PACKET_SIZE 256
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
164 #define KS_STOP_BITS_1 0x00
165 #define KS_STOP_BITS_2 0x08
167 #define KS_PAR_DISABLE 0x00
168 #define KS_PAR_EVEN 0x10
169 #define KS_PAR_ODD 0x30
170 #define KS_RESET 0x80
218 static unsigned int obfuscate_tx_buffer(
const __u8 * buf_cleartext,
219 unsigned int len_cleartext,
220 __u8 * buf_xoredtext,
221 unsigned int len_maxbuf)
223 unsigned int len_xoredtext;
226 len_xoredtext = ((len_cleartext + 7) & ~0x7) + 0x10;
227 if (len_xoredtext <= len_maxbuf) {
228 static const __u8 lookup_string[] =
"wangshuofei19710";
232 memset(buf_xoredtext, 0, len_xoredtext);
234 xor_mask = lookup_string[(len_cleartext & 0x0f) ^ 0x06] ^ 0x55;
236 while (len_cleartext-- > 0) {
237 *buf_xoredtext++ = *buf_cleartext++ ^ xor_mask;
242 return len_xoredtext;
246 static void ks959_speed_irq(
struct urb *
urb)
249 if (urb->status != 0) {
251 "ks959_speed_irq: urb asynchronously failed - %d\n",
257 static int ks959_change_speed(
struct ks959_cb *kingsun,
unsigned speed)
259 static unsigned int supported_speeds[] = { 2400, 9600, 19200, 38400,
260 57600, 115200, 576000, 1152000, 4000000, 0
269 for (i = 0; supported_speeds[
i] && supported_speeds[
i] != speed; i++) ;
270 if (supported_speeds[i] == 0)
279 usb_sndctrlpipe(kingsun->
usbdev, 0),
291 static void ks959_send_irq(
struct urb *urb);
292 static int ks959_submit_tx_fragment(
struct ks959_cb *kingsun)
295 unsigned int wraplen;
306 padlen = obfuscate_tx_buffer(kingsun->
tx_buf_clear, wraplen,
315 usb_sndctrlpipe(kingsun->
usbdev, 0),
318 ks959_send_irq, kingsun);
319 kingsun->
tx_urb->status = 0;
328 static void ks959_send_irq(
struct urb *urb)
330 struct ks959_cb *kingsun = urb->context;
335 if (!netif_running(kingsun->
netdev)) {
337 "ks959_send_irq: Network not running!\n");
342 if (urb->status != 0) {
344 "ks959_send_irq: urb asynchronously failed - %d\n",
363 if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
365 "ks959_send_irq: failed tx_urb submit: %d\n",
372 netdev->
stats.tx_errors++;
373 netif_start_queue(netdev);
381 ks959_change_speed(kingsun, kingsun->
new_speed);
383 netif_wake_queue(netdev);
395 unsigned int wraplen;
398 netif_stop_queue(netdev);
401 SKB_LINEAR_ASSERT(skb);
403 kingsun = netdev_priv(netdev);
405 spin_lock(&kingsun->
lock);
406 kingsun->
new_speed = irda_get_next_speed(skb);
413 if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
415 "ks959_hard_xmit: failed tx_urb submit: %d\n", ret);
421 netdev->
stats.tx_errors++;
422 netif_start_queue(netdev);
425 netdev->
stats.tx_packets++;
431 spin_unlock(&kingsun->
lock);
437 static void ks959_rcv_irq(
struct urb *urb)
439 struct ks959_cb *kingsun = urb->context;
443 if (!netif_running(kingsun->
netdev)) {
449 if (urb->status != 0) {
451 "kingsun_rcv_irq: urb asynchronously failed - %d\n",
457 if (urb->actual_length > 0) {
461 for (i = 0; i < urb->actual_length; i++) {
499 static int ks959_net_open(
struct net_device *netdev)
501 struct ks959_cb *kingsun = netdev_priv(netdev);
534 err = ks959_change_speed(kingsun, 9600);
544 if (!kingsun->
irlap) {
552 usb_rcvctrlpipe(kingsun->
usbdev, 0),
555 ks959_rcv_irq, kingsun);
556 kingsun->
rx_urb->status = 0;
560 "first urb-submit failed: %d\n", err);
564 netif_start_queue(netdev);
600 static int ks959_net_close(
struct net_device *netdev)
602 struct ks959_cb *kingsun = netdev_priv(netdev);
605 netif_stop_queue(netdev);
642 struct ks959_cb *kingsun = netdev_priv(netdev);
651 if (netif_device_present(kingsun->
netdev))
652 return ks959_change_speed(kingsun, irq->ifr_baudrate);
660 if (netif_running(kingsun->
netdev))
677 .ndo_start_xmit = ks959_hard_xmit,
678 .ndo_open = ks959_net_open,
679 .ndo_stop = ks959_net_close,
680 .ndo_do_ioctl = ks959_net_ioctl,
690 struct usb_device *
dev = interface_to_usbdev(intf);
701 kingsun = netdev_priv(net);
777 "Vendor: %x, Product: %x\n",
778 dev->devnum,
le16_to_cpu(dev->descriptor.idVendor),
788 kingsun->
qos.baud_rate.bits =
800 dev_info(&net->
dev,
"IrDA: Registered KingSun KS-959 device %s\n",
803 usb_set_intfdata(intf, kingsun);
832 struct ks959_cb *kingsun = usb_get_intfdata(intf);
864 usb_set_intfdata(intf,
NULL);
871 struct ks959_cb *kingsun = usb_get_intfdata(intf);
886 struct ks959_cb *kingsun = usb_get_intfdata(intf);
901 static struct usb_driver irda_driver = {
903 .probe = ks959_probe,
904 .disconnect = ks959_disconnect,
907 .suspend = ks959_suspend,
908 .resume = ks959_resume,