ks959-sir.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  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. * Following is my most current (2007-07-17) understanding of how the Kingsun
  28. * KS-959 dongle is supposed to work. This information was deduced by
  29. * reverse-engineering and examining the USB traffic captured with USBSnoopy
  30. * from the WinXP driver. Feel free to update here as more of the dongle is
  31. * known.
  32. *
  33. * My most sincere thanks must go to Domen Puncer <domen@coderock.org> for
  34. * invaluable help in cracking the obfuscation and padding required for this
  35. * dongle.
  36. *
  37. * General: This dongle exposes one interface with one interrupt IN endpoint.
  38. * However, the interrupt endpoint is NOT used at all for this dongle. Instead,
  39. * this dongle uses control transfers for everything, including sending and
  40. * receiving the IrDA frame data. Apparently the interrupt endpoint is just a
  41. * dummy to ensure the dongle has a valid interface to present to the PC.And I
  42. * thought the DonShine dongle was weird... In addition, this dongle uses
  43. * obfuscation (?!?!), applied at the USB level, to hide the traffic, both sent
  44. * and received, from the dongle. I call it obfuscation because the XOR keying
  45. * and padding required to produce an USB traffic acceptable for the dongle can
  46. * not be explained by any other technical requirement.
  47. *
  48. * Transmission: To transmit an IrDA frame, the driver must prepare a control
  49. * URB with the following as a setup packet:
  50. * bRequestType USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
  51. * bRequest 0x09
  52. * wValue <length of valid data before padding, little endian>
  53. * wIndex 0x0000
  54. * wLength <length of padded data>
  55. * The payload packet must be manually wrapped and escaped (as in stir4200.c),
  56. * then padded and obfuscated before being sent. Both padding and obfuscation
  57. * are implemented in the procedure obfuscate_tx_buffer(). Suffice to say, the
  58. * designer/programmer of the dongle used his name as a source for the
  59. * obfuscation. WTF?!
  60. * Apparently the dongle cannot handle payloads larger than 256 bytes. The
  61. * driver has to perform fragmentation in order to send anything larger than
  62. * this limit.
  63. *
  64. * Reception: To receive data, the driver must poll the dongle regularly (like
  65. * kingsun-sir.c) with control URBs and the following as a setup packet:
  66. * bRequestType USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE
  67. * bRequest 0x01
  68. * wValue 0x0200
  69. * wIndex 0x0000
  70. * wLength 0x0800 (size of available buffer)
  71. * If there is data to be read, it will be returned as the response payload.
  72. * This data is (apparently) not padded, but it is obfuscated. To de-obfuscate
  73. * it, the driver must XOR every byte, in sequence, with a value that starts at
  74. * 1 and is incremented with each byte processed, and then with 0x55. The value
  75. * incremented with each byte processed overflows as an unsigned char. The
  76. * resulting bytes form a wrapped SIR frame that is unwrapped and unescaped
  77. * as in stir4200.c The incremented value is NOT reset with each frame, but is
  78. * kept across the entire session with the dongle. Also, the dongle inserts an
  79. * extra garbage byte with value 0x95 (after decoding) every 0xff bytes, which
  80. * must be skipped.
  81. *
  82. * Speed change: To change the speed of the dongle, the driver prepares a
  83. * control URB with the following as a setup packet:
  84. * bRequestType USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
  85. * bRequest 0x09
  86. * wValue 0x0200
  87. * wIndex 0x0001
  88. * wLength 0x0008 (length of the payload)
  89. * The payload is a 8-byte record, apparently identical to the one used in
  90. * drivers/usb/serial/cypress_m8.c to change speed:
  91. * __u32 baudSpeed;
  92. * unsigned int dataBits : 2; // 0 - 5 bits 3 - 8 bits
  93. * unsigned int : 1;
  94. * unsigned int stopBits : 1;
  95. * unsigned int parityEnable : 1;
  96. * unsigned int parityType : 1;
  97. * unsigned int : 1;
  98. * unsigned int reset : 1;
  99. * unsigned char reserved[3]; // set to 0
  100. *
  101. * For now only SIR speeds have been observed with this dongle. Therefore,
  102. * nothing is known on what changes (if any) must be done to frame wrapping /
  103. * unwrapping for higher than SIR speeds. This driver assumes no change is
  104. * necessary and announces support for all the way to 57600 bps. Although the
  105. * package announces support for up to 4MBps, tests with a Sony Ericcson K300
  106. * phone show corruption when receiving large frames at 115200 bps, the highest
  107. * speed announced by the phone. However, transmission at 115200 bps is OK. Go
  108. * figure. Since I don't know whether the phone or the dongle is at fault, max
  109. * announced speed is 57600 bps until someone produces a device that can run
  110. * at higher speeds with this dongle.
  111. */
  112. #include <linux/module.h>
  113. #include <linux/moduleparam.h>
  114. #include <linux/kernel.h>
  115. #include <linux/types.h>
  116. #include <linux/errno.h>
  117. #include <linux/slab.h>
  118. #include <linux/usb.h>
  119. #include <linux/device.h>
  120. #include <linux/crc32.h>
  121. #include <asm/unaligned.h>
  122. #include <asm/byteorder.h>
  123. #include <asm/uaccess.h>
  124. #include <net/irda/irda.h>
  125. #include <net/irda/wrapper.h>
  126. #include <net/irda/crc.h>
  127. #define KS959_VENDOR_ID 0x07d0
  128. #define KS959_PRODUCT_ID 0x4959
  129. /* These are the currently known USB ids */
  130. static struct usb_device_id dongles[] = {
  131. /* KingSun Co,Ltd IrDA/USB Bridge */
  132. {USB_DEVICE(KS959_VENDOR_ID, KS959_PRODUCT_ID)},
  133. {}
  134. };
  135. MODULE_DEVICE_TABLE(usb, dongles);
  136. #define KINGSUN_MTT 0x07
  137. #define KINGSUN_REQ_RECV 0x01
  138. #define KINGSUN_REQ_SEND 0x09
  139. #define KINGSUN_RCV_FIFO_SIZE 2048 /* Max length we can receive */
  140. #define KINGSUN_SND_FIFO_SIZE 2048 /* Max packet we can send */
  141. #define KINGSUN_SND_PACKET_SIZE 256 /* Max packet dongle can handle */
  142. struct ks959_speedparams {
  143. __le32 baudrate; /* baud rate, little endian */
  144. __u8 flags;
  145. __u8 reserved[3];
  146. } __packed;
  147. #define KS_DATA_5_BITS 0x00
  148. #define KS_DATA_6_BITS 0x01
  149. #define KS_DATA_7_BITS 0x02
  150. #define KS_DATA_8_BITS 0x03
  151. #define KS_STOP_BITS_1 0x00
  152. #define KS_STOP_BITS_2 0x08
  153. #define KS_PAR_DISABLE 0x00
  154. #define KS_PAR_EVEN 0x10
  155. #define KS_PAR_ODD 0x30
  156. #define KS_RESET 0x80
  157. struct ks959_cb {
  158. struct usb_device *usbdev; /* init: probe_irda */
  159. struct net_device *netdev; /* network layer */
  160. struct irlap_cb *irlap; /* The link layer we are binded to */
  161. struct qos_info qos;
  162. struct usb_ctrlrequest *tx_setuprequest;
  163. struct urb *tx_urb;
  164. __u8 *tx_buf_clear;
  165. unsigned int tx_buf_clear_used;
  166. unsigned int tx_buf_clear_sent;
  167. __u8 *tx_buf_xored;
  168. struct usb_ctrlrequest *rx_setuprequest;
  169. struct urb *rx_urb;
  170. __u8 *rx_buf;
  171. __u8 rx_variable_xormask;
  172. iobuff_t rx_unwrap_buff;
  173. struct usb_ctrlrequest *speed_setuprequest;
  174. struct urb *speed_urb;
  175. struct ks959_speedparams speedparams;
  176. unsigned int new_speed;
  177. spinlock_t lock;
  178. int receiving;
  179. };
  180. /* Procedure to perform the obfuscation/padding expected by the dongle
  181. *
  182. * buf_cleartext (IN) Cleartext version of the IrDA frame to transmit
  183. * len_cleartext (IN) Length of the cleartext version of IrDA frame
  184. * buf_xoredtext (OUT) Obfuscated version of frame built by proc
  185. * len_maxbuf (OUT) Maximum space available at buf_xoredtext
  186. *
  187. * (return) length of obfuscated frame with padding
  188. *
  189. * If not enough space (as indicated by len_maxbuf vs. required padding),
  190. * zero is returned
  191. *
  192. * The value of lookup_string is actually a required portion of the algorithm.
  193. * Seems the designer of the dongle wanted to state who exactly is responsible
  194. * for implementing obfuscation. Send your best (or other) wishes to him ]:-)
  195. */
  196. static unsigned int obfuscate_tx_buffer(const __u8 * buf_cleartext,
  197. unsigned int len_cleartext,
  198. __u8 * buf_xoredtext,
  199. unsigned int len_maxbuf)
  200. {
  201. unsigned int len_xoredtext;
  202. /* Calculate required length with padding, check for necessary space */
  203. len_xoredtext = ((len_cleartext + 7) & ~0x7) + 0x10;
  204. if (len_xoredtext <= len_maxbuf) {
  205. static const __u8 lookup_string[] = "wangshuofei19710";
  206. __u8 xor_mask;
  207. /* Unlike the WinXP driver, we *do* clear out the padding */
  208. memset(buf_xoredtext, 0, len_xoredtext);
  209. xor_mask = lookup_string[(len_cleartext & 0x0f) ^ 0x06] ^ 0x55;
  210. while (len_cleartext-- > 0) {
  211. *buf_xoredtext++ = *buf_cleartext++ ^ xor_mask;
  212. }
  213. } else {
  214. len_xoredtext = 0;
  215. }
  216. return len_xoredtext;
  217. }
  218. /* Callback transmission routine */
  219. static void ks959_speed_irq(struct urb *urb)
  220. {
  221. /* unlink, shutdown, unplug, other nasties */
  222. if (urb->status != 0) {
  223. dev_err(&urb->dev->dev,
  224. "ks959_speed_irq: urb asynchronously failed - %d\n",
  225. urb->status);
  226. }
  227. }
  228. /* Send a control request to change speed of the dongle */
  229. static int ks959_change_speed(struct ks959_cb *kingsun, unsigned speed)
  230. {
  231. static unsigned int supported_speeds[] = { 2400, 9600, 19200, 38400,
  232. 57600, 115200, 576000, 1152000, 4000000, 0
  233. };
  234. int err;
  235. unsigned int i;
  236. if (kingsun->speed_setuprequest == NULL || kingsun->speed_urb == NULL)
  237. return -ENOMEM;
  238. /* Check that requested speed is among the supported ones */
  239. for (i = 0; supported_speeds[i] && supported_speeds[i] != speed; i++) ;
  240. if (supported_speeds[i] == 0)
  241. return -EOPNOTSUPP;
  242. memset(&(kingsun->speedparams), 0, sizeof(struct ks959_speedparams));
  243. kingsun->speedparams.baudrate = cpu_to_le32(speed);
  244. kingsun->speedparams.flags = KS_DATA_8_BITS;
  245. /* speed_setuprequest pre-filled in ks959_probe */
  246. usb_fill_control_urb(kingsun->speed_urb, kingsun->usbdev,
  247. usb_sndctrlpipe(kingsun->usbdev, 0),
  248. (unsigned char *)kingsun->speed_setuprequest,
  249. &(kingsun->speedparams),
  250. sizeof(struct ks959_speedparams), ks959_speed_irq,
  251. kingsun);
  252. kingsun->speed_urb->status = 0;
  253. err = usb_submit_urb(kingsun->speed_urb, GFP_ATOMIC);
  254. return err;
  255. }
  256. /* Submit one fragment of an IrDA frame to the dongle */
  257. static void ks959_send_irq(struct urb *urb);
  258. static int ks959_submit_tx_fragment(struct ks959_cb *kingsun)
  259. {
  260. unsigned int padlen;
  261. unsigned int wraplen;
  262. int ret;
  263. /* Check whether current plaintext can produce a padded buffer that fits
  264. within the range handled by the dongle */
  265. wraplen = (KINGSUN_SND_PACKET_SIZE & ~0x7) - 0x10;
  266. if (wraplen > kingsun->tx_buf_clear_used)
  267. wraplen = kingsun->tx_buf_clear_used;
  268. /* Perform dongle obfuscation. Also remove the portion of the frame that
  269. was just obfuscated and will now be sent to the dongle. */
  270. padlen = obfuscate_tx_buffer(kingsun->tx_buf_clear, wraplen,
  271. kingsun->tx_buf_xored,
  272. KINGSUN_SND_PACKET_SIZE);
  273. /* Calculate how much data can be transmitted in this urb */
  274. kingsun->tx_setuprequest->wValue = cpu_to_le16(wraplen);
  275. kingsun->tx_setuprequest->wLength = cpu_to_le16(padlen);
  276. /* Rest of the fields were filled in ks959_probe */
  277. usb_fill_control_urb(kingsun->tx_urb, kingsun->usbdev,
  278. usb_sndctrlpipe(kingsun->usbdev, 0),
  279. (unsigned char *)kingsun->tx_setuprequest,
  280. kingsun->tx_buf_xored, padlen,
  281. ks959_send_irq, kingsun);
  282. kingsun->tx_urb->status = 0;
  283. ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC);
  284. /* Remember how much data was sent, in order to update at callback */
  285. kingsun->tx_buf_clear_sent = (ret == 0) ? wraplen : 0;
  286. return ret;
  287. }
  288. /* Callback transmission routine */
  289. static void ks959_send_irq(struct urb *urb)
  290. {
  291. struct ks959_cb *kingsun = urb->context;
  292. struct net_device *netdev = kingsun->netdev;
  293. int ret = 0;
  294. /* in process of stopping, just drop data */
  295. if (!netif_running(kingsun->netdev)) {
  296. dev_err(&kingsun->usbdev->dev,
  297. "ks959_send_irq: Network not running!\n");
  298. return;
  299. }
  300. /* unlink, shutdown, unplug, other nasties */
  301. if (urb->status != 0) {
  302. dev_err(&kingsun->usbdev->dev,
  303. "ks959_send_irq: urb asynchronously failed - %d\n",
  304. urb->status);
  305. return;
  306. }
  307. if (kingsun->tx_buf_clear_used > 0) {
  308. /* Update data remaining to be sent */
  309. if (kingsun->tx_buf_clear_sent < kingsun->tx_buf_clear_used) {
  310. memmove(kingsun->tx_buf_clear,
  311. kingsun->tx_buf_clear +
  312. kingsun->tx_buf_clear_sent,
  313. kingsun->tx_buf_clear_used -
  314. kingsun->tx_buf_clear_sent);
  315. }
  316. kingsun->tx_buf_clear_used -= kingsun->tx_buf_clear_sent;
  317. kingsun->tx_buf_clear_sent = 0;
  318. if (kingsun->tx_buf_clear_used > 0) {
  319. /* There is more data to be sent */
  320. if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
  321. dev_err(&kingsun->usbdev->dev,
  322. "ks959_send_irq: failed tx_urb submit: %d\n",
  323. ret);
  324. switch (ret) {
  325. case -ENODEV:
  326. case -EPIPE:
  327. break;
  328. default:
  329. netdev->stats.tx_errors++;
  330. netif_start_queue(netdev);
  331. }
  332. }
  333. } else {
  334. /* All data sent, send next speed && wake network queue */
  335. if (kingsun->new_speed != -1 &&
  336. cpu_to_le32(kingsun->new_speed) !=
  337. kingsun->speedparams.baudrate)
  338. ks959_change_speed(kingsun, kingsun->new_speed);
  339. netif_wake_queue(netdev);
  340. }
  341. }
  342. }
  343. /*
  344. * Called from net/core when new frame is available.
  345. */
  346. static netdev_tx_t ks959_hard_xmit(struct sk_buff *skb,
  347. struct net_device *netdev)
  348. {
  349. struct ks959_cb *kingsun;
  350. unsigned int wraplen;
  351. int ret = 0;
  352. netif_stop_queue(netdev);
  353. /* the IRDA wrapping routines don't deal with non linear skb */
  354. SKB_LINEAR_ASSERT(skb);
  355. kingsun = netdev_priv(netdev);
  356. spin_lock(&kingsun->lock);
  357. kingsun->new_speed = irda_get_next_speed(skb);
  358. /* Append data to the end of whatever data remains to be transmitted */
  359. wraplen =
  360. async_wrap_skb(skb, kingsun->tx_buf_clear, KINGSUN_SND_FIFO_SIZE);
  361. kingsun->tx_buf_clear_used = wraplen;
  362. if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
  363. dev_err(&kingsun->usbdev->dev,
  364. "ks959_hard_xmit: failed tx_urb submit: %d\n", ret);
  365. switch (ret) {
  366. case -ENODEV:
  367. case -EPIPE:
  368. break;
  369. default:
  370. netdev->stats.tx_errors++;
  371. netif_start_queue(netdev);
  372. }
  373. } else {
  374. netdev->stats.tx_packets++;
  375. netdev->stats.tx_bytes += skb->len;
  376. }
  377. dev_kfree_skb(skb);
  378. spin_unlock(&kingsun->lock);
  379. return NETDEV_TX_OK;
  380. }
  381. /* Receive callback function */
  382. static void ks959_rcv_irq(struct urb *urb)
  383. {
  384. struct ks959_cb *kingsun = urb->context;
  385. int ret;
  386. /* in process of stopping, just drop data */
  387. if (!netif_running(kingsun->netdev)) {
  388. kingsun->receiving = 0;
  389. return;
  390. }
  391. /* unlink, shutdown, unplug, other nasties */
  392. if (urb->status != 0) {
  393. dev_err(&kingsun->usbdev->dev,
  394. "kingsun_rcv_irq: urb asynchronously failed - %d\n",
  395. urb->status);
  396. kingsun->receiving = 0;
  397. return;
  398. }
  399. if (urb->actual_length > 0) {
  400. __u8 *bytes = urb->transfer_buffer;
  401. unsigned int i;
  402. for (i = 0; i < urb->actual_length; i++) {
  403. /* De-obfuscation implemented here: variable portion of
  404. xormask is incremented, and then used with the encoded
  405. byte for the XOR. The result of the operation is used
  406. to unwrap the SIR frame. */
  407. kingsun->rx_variable_xormask++;
  408. bytes[i] =
  409. bytes[i] ^ kingsun->rx_variable_xormask ^ 0x55u;
  410. /* rx_variable_xormask doubles as an index counter so we
  411. can skip the byte at 0xff (wrapped around to 0).
  412. */
  413. if (kingsun->rx_variable_xormask != 0) {
  414. async_unwrap_char(kingsun->netdev,
  415. &kingsun->netdev->stats,
  416. &kingsun->rx_unwrap_buff,
  417. bytes[i]);
  418. }
  419. }
  420. kingsun->receiving =
  421. (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0;
  422. }
  423. /* This urb has already been filled in kingsun_net_open. Setup
  424. packet must be re-filled, but it is assumed that urb keeps the
  425. pointer to the initial setup packet, as well as the payload buffer.
  426. Setup packet is already pre-filled at ks959_probe.
  427. */
  428. urb->status = 0;
  429. ret = usb_submit_urb(urb, GFP_ATOMIC);
  430. }
  431. /*
  432. * Function kingsun_net_open (dev)
  433. *
  434. * Network device is taken up. Usually this is done by "ifconfig irda0 up"
  435. */
  436. static int ks959_net_open(struct net_device *netdev)
  437. {
  438. struct ks959_cb *kingsun = netdev_priv(netdev);
  439. int err = -ENOMEM;
  440. char hwname[16];
  441. /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */
  442. kingsun->receiving = 0;
  443. /* Initialize for SIR to copy data directly into skb. */
  444. kingsun->rx_unwrap_buff.in_frame = FALSE;
  445. kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
  446. kingsun->rx_unwrap_buff.truesize = IRDA_SKB_MAX_MTU;
  447. kingsun->rx_unwrap_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
  448. if (!kingsun->rx_unwrap_buff.skb)
  449. goto free_mem;
  450. skb_reserve(kingsun->rx_unwrap_buff.skb, 1);
  451. kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data;
  452. kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
  453. if (!kingsun->rx_urb)
  454. goto free_mem;
  455. kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
  456. if (!kingsun->tx_urb)
  457. goto free_mem;
  458. kingsun->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
  459. if (!kingsun->speed_urb)
  460. goto free_mem;
  461. /* Initialize speed for dongle */
  462. kingsun->new_speed = 9600;
  463. err = ks959_change_speed(kingsun, 9600);
  464. if (err < 0)
  465. goto free_mem;
  466. /*
  467. * Now that everything should be initialized properly,
  468. * Open new IrLAP layer instance to take care of us...
  469. */
  470. sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
  471. kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
  472. if (!kingsun->irlap) {
  473. err = -ENOMEM;
  474. dev_err(&kingsun->usbdev->dev, "irlap_open failed\n");
  475. goto free_mem;
  476. }
  477. /* Start reception. Setup request already pre-filled in ks959_probe */
  478. usb_fill_control_urb(kingsun->rx_urb, kingsun->usbdev,
  479. usb_rcvctrlpipe(kingsun->usbdev, 0),
  480. (unsigned char *)kingsun->rx_setuprequest,
  481. kingsun->rx_buf, KINGSUN_RCV_FIFO_SIZE,
  482. ks959_rcv_irq, kingsun);
  483. kingsun->rx_urb->status = 0;
  484. err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
  485. if (err) {
  486. dev_err(&kingsun->usbdev->dev,
  487. "first urb-submit failed: %d\n", err);
  488. goto close_irlap;
  489. }
  490. netif_start_queue(netdev);
  491. /* Situation at this point:
  492. - all work buffers allocated
  493. - urbs allocated and ready to fill
  494. - max rx packet known (in max_rx)
  495. - unwrap state machine initialized, in state outside of any frame
  496. - receive request in progress
  497. - IrLAP layer started, about to hand over packets to send
  498. */
  499. return 0;
  500. close_irlap:
  501. irlap_close(kingsun->irlap);
  502. free_mem:
  503. usb_free_urb(kingsun->speed_urb);
  504. kingsun->speed_urb = NULL;
  505. usb_free_urb(kingsun->tx_urb);
  506. kingsun->tx_urb = NULL;
  507. usb_free_urb(kingsun->rx_urb);
  508. kingsun->rx_urb = NULL;
  509. if (kingsun->rx_unwrap_buff.skb) {
  510. kfree_skb(kingsun->rx_unwrap_buff.skb);
  511. kingsun->rx_unwrap_buff.skb = NULL;
  512. kingsun->rx_unwrap_buff.head = NULL;
  513. }
  514. return err;
  515. }
  516. /*
  517. * Function kingsun_net_close (kingsun)
  518. *
  519. * Network device is taken down. Usually this is done by
  520. * "ifconfig irda0 down"
  521. */
  522. static int ks959_net_close(struct net_device *netdev)
  523. {
  524. struct ks959_cb *kingsun = netdev_priv(netdev);
  525. /* Stop transmit processing */
  526. netif_stop_queue(netdev);
  527. /* Mop up receive && transmit urb's */
  528. usb_kill_urb(kingsun->tx_urb);
  529. usb_free_urb(kingsun->tx_urb);
  530. kingsun->tx_urb = NULL;
  531. usb_kill_urb(kingsun->speed_urb);
  532. usb_free_urb(kingsun->speed_urb);
  533. kingsun->speed_urb = NULL;
  534. usb_kill_urb(kingsun->rx_urb);
  535. usb_free_urb(kingsun->rx_urb);
  536. kingsun->rx_urb = NULL;
  537. kfree_skb(kingsun->rx_unwrap_buff.skb);
  538. kingsun->rx_unwrap_buff.skb = NULL;
  539. kingsun->rx_unwrap_buff.head = NULL;
  540. kingsun->rx_unwrap_buff.in_frame = FALSE;
  541. kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
  542. kingsun->receiving = 0;
  543. /* Stop and remove instance of IrLAP */
  544. if (kingsun->irlap)
  545. irlap_close(kingsun->irlap);
  546. kingsun->irlap = NULL;
  547. return 0;
  548. }
  549. /*
  550. * IOCTLs : Extra out-of-band network commands...
  551. */
  552. static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
  553. {
  554. struct if_irda_req *irq = (struct if_irda_req *)rq;
  555. struct ks959_cb *kingsun = netdev_priv(netdev);
  556. int ret = 0;
  557. switch (cmd) {
  558. case SIOCSBANDWIDTH: /* Set bandwidth */
  559. if (!capable(CAP_NET_ADMIN))
  560. return -EPERM;
  561. /* Check if the device is still there */
  562. if (netif_device_present(kingsun->netdev))
  563. return ks959_change_speed(kingsun, irq->ifr_baudrate);
  564. break;
  565. case SIOCSMEDIABUSY: /* Set media busy */
  566. if (!capable(CAP_NET_ADMIN))
  567. return -EPERM;
  568. /* Check if the IrDA stack is still there */
  569. if (netif_running(kingsun->netdev))
  570. irda_device_set_media_busy(kingsun->netdev, TRUE);
  571. break;
  572. case SIOCGRECEIVING:
  573. /* Only approximately true */
  574. irq->ifr_receiving = kingsun->receiving;
  575. break;
  576. default:
  577. ret = -EOPNOTSUPP;
  578. }
  579. return ret;
  580. }
  581. static const struct net_device_ops ks959_ops = {
  582. .ndo_start_xmit = ks959_hard_xmit,
  583. .ndo_open = ks959_net_open,
  584. .ndo_stop = ks959_net_close,
  585. .ndo_do_ioctl = ks959_net_ioctl,
  586. };
  587. /*
  588. * This routine is called by the USB subsystem for each new device
  589. * in the system. We need to check if the device is ours, and in
  590. * this case start handling it.
  591. */
  592. static int ks959_probe(struct usb_interface *intf,
  593. const struct usb_device_id *id)
  594. {
  595. struct usb_device *dev = interface_to_usbdev(intf);
  596. struct ks959_cb *kingsun = NULL;
  597. struct net_device *net = NULL;
  598. int ret = -ENOMEM;
  599. /* Allocate network device container. */
  600. net = alloc_irdadev(sizeof(*kingsun));
  601. if (!net)
  602. goto err_out1;
  603. SET_NETDEV_DEV(net, &intf->dev);
  604. kingsun = netdev_priv(net);
  605. kingsun->netdev = net;
  606. kingsun->usbdev = dev;
  607. kingsun->irlap = NULL;
  608. kingsun->tx_setuprequest = NULL;
  609. kingsun->tx_urb = NULL;
  610. kingsun->tx_buf_clear = NULL;
  611. kingsun->tx_buf_xored = NULL;
  612. kingsun->tx_buf_clear_used = 0;
  613. kingsun->tx_buf_clear_sent = 0;
  614. kingsun->rx_setuprequest = NULL;
  615. kingsun->rx_urb = NULL;
  616. kingsun->rx_buf = NULL;
  617. kingsun->rx_variable_xormask = 0;
  618. kingsun->rx_unwrap_buff.in_frame = FALSE;
  619. kingsun->rx_unwrap_buff.state = OUTSIDE_FRAME;
  620. kingsun->rx_unwrap_buff.skb = NULL;
  621. kingsun->receiving = 0;
  622. spin_lock_init(&kingsun->lock);
  623. kingsun->speed_setuprequest = NULL;
  624. kingsun->speed_urb = NULL;
  625. kingsun->speedparams.baudrate = 0;
  626. /* Allocate input buffer */
  627. kingsun->rx_buf = kmalloc(KINGSUN_RCV_FIFO_SIZE, GFP_KERNEL);
  628. if (!kingsun->rx_buf)
  629. goto free_mem;
  630. /* Allocate input setup packet */
  631. kingsun->rx_setuprequest =
  632. kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
  633. if (!kingsun->rx_setuprequest)
  634. goto free_mem;
  635. kingsun->rx_setuprequest->bRequestType =
  636. USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
  637. kingsun->rx_setuprequest->bRequest = KINGSUN_REQ_RECV;
  638. kingsun->rx_setuprequest->wValue = cpu_to_le16(0x0200);
  639. kingsun->rx_setuprequest->wIndex = 0;
  640. kingsun->rx_setuprequest->wLength = cpu_to_le16(KINGSUN_RCV_FIFO_SIZE);
  641. /* Allocate output buffer */
  642. kingsun->tx_buf_clear = kmalloc(KINGSUN_SND_FIFO_SIZE, GFP_KERNEL);
  643. if (!kingsun->tx_buf_clear)
  644. goto free_mem;
  645. kingsun->tx_buf_xored = kmalloc(KINGSUN_SND_PACKET_SIZE, GFP_KERNEL);
  646. if (!kingsun->tx_buf_xored)
  647. goto free_mem;
  648. /* Allocate and initialize output setup packet */
  649. kingsun->tx_setuprequest =
  650. kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
  651. if (!kingsun->tx_setuprequest)
  652. goto free_mem;
  653. kingsun->tx_setuprequest->bRequestType =
  654. USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
  655. kingsun->tx_setuprequest->bRequest = KINGSUN_REQ_SEND;
  656. kingsun->tx_setuprequest->wValue = 0;
  657. kingsun->tx_setuprequest->wIndex = 0;
  658. kingsun->tx_setuprequest->wLength = 0;
  659. /* Allocate and initialize speed setup packet */
  660. kingsun->speed_setuprequest =
  661. kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
  662. if (!kingsun->speed_setuprequest)
  663. goto free_mem;
  664. kingsun->speed_setuprequest->bRequestType =
  665. USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
  666. kingsun->speed_setuprequest->bRequest = KINGSUN_REQ_SEND;
  667. kingsun->speed_setuprequest->wValue = cpu_to_le16(0x0200);
  668. kingsun->speed_setuprequest->wIndex = cpu_to_le16(0x0001);
  669. kingsun->speed_setuprequest->wLength =
  670. cpu_to_le16(sizeof(struct ks959_speedparams));
  671. printk(KERN_INFO "KingSun KS-959 IRDA/USB found at address %d, "
  672. "Vendor: %x, Product: %x\n",
  673. dev->devnum, le16_to_cpu(dev->descriptor.idVendor),
  674. le16_to_cpu(dev->descriptor.idProduct));
  675. /* Initialize QoS for this device */
  676. irda_init_max_qos_capabilies(&kingsun->qos);
  677. /* Baud rates known to be supported. Please uncomment if devices (other
  678. than a SonyEriccson K300 phone) can be shown to support higher speed
  679. with this dongle.
  680. */
  681. kingsun->qos.baud_rate.bits =
  682. IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600;
  683. kingsun->qos.min_turn_time.bits &= KINGSUN_MTT;
  684. irda_qos_bits_to_value(&kingsun->qos);
  685. /* Override the network functions we need to use */
  686. net->netdev_ops = &ks959_ops;
  687. ret = register_netdev(net);
  688. if (ret != 0)
  689. goto free_mem;
  690. dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n",
  691. net->name);
  692. usb_set_intfdata(intf, kingsun);
  693. /* Situation at this point:
  694. - all work buffers allocated
  695. - setup requests pre-filled
  696. - urbs not allocated, set to NULL
  697. - max rx packet known (is KINGSUN_FIFO_SIZE)
  698. - unwrap state machine (partially) initialized, but skb == NULL
  699. */
  700. return 0;
  701. free_mem:
  702. kfree(kingsun->speed_setuprequest);
  703. kfree(kingsun->tx_setuprequest);
  704. kfree(kingsun->tx_buf_xored);
  705. kfree(kingsun->tx_buf_clear);
  706. kfree(kingsun->rx_setuprequest);
  707. kfree(kingsun->rx_buf);
  708. free_netdev(net);
  709. err_out1:
  710. return ret;
  711. }
  712. /*
  713. * The current device is removed, the USB layer tell us to shut it down...
  714. */
  715. static void ks959_disconnect(struct usb_interface *intf)
  716. {
  717. struct ks959_cb *kingsun = usb_get_intfdata(intf);
  718. if (!kingsun)
  719. return;
  720. unregister_netdev(kingsun->netdev);
  721. /* Mop up receive && transmit urb's */
  722. if (kingsun->speed_urb != NULL) {
  723. usb_kill_urb(kingsun->speed_urb);
  724. usb_free_urb(kingsun->speed_urb);
  725. kingsun->speed_urb = NULL;
  726. }
  727. if (kingsun->tx_urb != NULL) {
  728. usb_kill_urb(kingsun->tx_urb);
  729. usb_free_urb(kingsun->tx_urb);
  730. kingsun->tx_urb = NULL;
  731. }
  732. if (kingsun->rx_urb != NULL) {
  733. usb_kill_urb(kingsun->rx_urb);
  734. usb_free_urb(kingsun->rx_urb);
  735. kingsun->rx_urb = NULL;
  736. }
  737. kfree(kingsun->speed_setuprequest);
  738. kfree(kingsun->tx_setuprequest);
  739. kfree(kingsun->tx_buf_xored);
  740. kfree(kingsun->tx_buf_clear);
  741. kfree(kingsun->rx_setuprequest);
  742. kfree(kingsun->rx_buf);
  743. free_netdev(kingsun->netdev);
  744. usb_set_intfdata(intf, NULL);
  745. }
  746. #ifdef CONFIG_PM
  747. /* USB suspend, so power off the transmitter/receiver */
  748. static int ks959_suspend(struct usb_interface *intf, pm_message_t message)
  749. {
  750. struct ks959_cb *kingsun = usb_get_intfdata(intf);
  751. netif_device_detach(kingsun->netdev);
  752. if (kingsun->speed_urb != NULL)
  753. usb_kill_urb(kingsun->speed_urb);
  754. if (kingsun->tx_urb != NULL)
  755. usb_kill_urb(kingsun->tx_urb);
  756. if (kingsun->rx_urb != NULL)
  757. usb_kill_urb(kingsun->rx_urb);
  758. return 0;
  759. }
  760. /* Coming out of suspend, so reset hardware */
  761. static int ks959_resume(struct usb_interface *intf)
  762. {
  763. struct ks959_cb *kingsun = usb_get_intfdata(intf);
  764. if (kingsun->rx_urb != NULL) {
  765. /* Setup request already filled in ks959_probe */
  766. usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
  767. }
  768. netif_device_attach(kingsun->netdev);
  769. return 0;
  770. }
  771. #endif
  772. /*
  773. * USB device callbacks
  774. */
  775. static struct usb_driver irda_driver = {
  776. .name = "ks959-sir",
  777. .probe = ks959_probe,
  778. .disconnect = ks959_disconnect,
  779. .id_table = dongles,
  780. #ifdef CONFIG_PM
  781. .suspend = ks959_suspend,
  782. .resume = ks959_resume,
  783. #endif
  784. };
  785. module_usb_driver(irda_driver);
  786. MODULE_AUTHOR("Alex Villacís Lasso <a_villacis@palosanto.com>");
  787. MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun KS-959");
  788. MODULE_LICENSE("GPL");