Advertisement
Guest User

Untitled

a guest
May 7th, 2017
590
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 184.81 KB | None | 0 0
  1. diff -Naurp a/arch/arm/mach-msm/devices_htc.c b/arch/arm/mach-msm/devices_htc.c
  2. --- a/arch/arm/mach-msm/devices_htc.c 2009-12-18 21:59:45.278473602 +0100
  3. +++ b/arch/arm/mach-msm/devices_htc.c 2009-12-18 21:59:31.147476769 +0100
  4. @@ -25,8 +25,14 @@
  5. #include <mach/board.h>
  6. #include <mach/board_htc.h>
  7. #include <mach/msm_hsusb.h>
  8. +
  9. +#ifdef CONFIG_USB_FUNCTION
  10. +#include <../../../drivers/usb/function/usb_function.h>
  11. #include <linux/usb/mass_storage_function.h>
  12. +#endif
  13. +#ifdef CONFIG_USB_ANDROID
  14. #include <linux/usb/android.h>
  15. +#endif
  16.  
  17. #include <asm/mach/flash.h>
  18. #include <asm/setup.h>
  19. @@ -87,30 +93,121 @@ static int hsusb_phy_init_seq[] = { 0x40
  20.  
  21. #ifdef CONFIG_USB_FUNCTION
  22. static char *usb_functions[] = {
  23. +#if defined(CONFIG_USB_FUNCTION_RNDIS_WCEIS)
  24. + /* ether *MUST* be first for Windows to detect it using Compatible IDs */
  25. + "ether",
  26. +#endif
  27. #if defined(CONFIG_USB_FUNCTION_MASS_STORAGE) || defined(CONFIG_USB_FUNCTION_UMS)
  28. "usb_mass_storage",
  29. #endif
  30. #ifdef CONFIG_USB_FUNCTION_ADB
  31. "adb",
  32. #endif
  33. +#if defined(CONFIG_USB_FUNCTION_FSYNC)
  34. + "fsync",
  35. +#endif
  36. +#if defined(CONFIG_USB_FUNCTION_DIAG)
  37. + "diag",
  38. +#endif
  39. +#if defined(CONFIG_USB_FUNCTION_SERIAL)
  40. + "fserial",
  41. +#endif
  42. +#if defined(CONFIG_USB_FUNCTION_PROJECTOR)
  43. + "projector",
  44. +#endif
  45. +#if defined(CONFIG_USB_FUNCTION_MTP_TUNNEL)
  46. + "mtp_tunnel",
  47. +#endif
  48. +#if defined(CONFIG_USB_FUNCTION_ETHER) && !defined(CONFIG_USB_FUNCTION_RNDIS_WCEIS)
  49. + "ether",
  50. +#endif
  51. };
  52.  
  53. +/* The first product_id with all the functions required for the current setup
  54. + * will be used, so be careful about your ordering.
  55. + */
  56. static struct msm_hsusb_product usb_products[] = {
  57. +#if defined(CONFIG_USB_FUNCTION_MASS_STORAGE) || defined(CONFIG_USB_FUNCTION_UMS)
  58. {
  59. .product_id = 0x0c01,
  60. - .functions = 0x00000001, /* usb_mass_storage */
  61. + .functions = BIT(USB_FUNCTION_MASS_STORAGE_NUM),
  62. },
  63. +#endif
  64. +#if defined(CONFIG_USB_FUNCTION_ADB)
  65. {
  66. .product_id = 0x0c02,
  67. - .functions = 0x00000003, /* usb_mass_storage + adb */
  68. + .functions = BIT(USB_FUNCTION_MASS_STORAGE_NUM)
  69. + | BIT(USB_FUNCTION_ADB_NUM)
  70. + },
  71. +#endif
  72. +#if defined(CONFIG_USB_FUNCTION_FSERIAL)
  73. + {
  74. + .product_id = 0x0c03,
  75. + .functions = BIT(USB_FUNCTION_MASS_STORAGE_NUM)
  76. + | BIT(USB_FUNCTION_FSERIAL_NUM)
  77. + },
  78. +#endif
  79. +#if defined(CONFIG_USB_FUNCTION_PROJECTOR)
  80. + {
  81. + .product_id = 0x0c05,
  82. + .functions = BIT(USB_FUNCTION_MASS_STORAGE_NUM)
  83. + | BIT(USB_FUNCTION_PROJECTOR_NUM)
  84. },
  85. +#endif
  86. +#if defined(CONFIG_USB_FUNCTION_DIAG)
  87. + {
  88. + .product_id = 0x0c08,
  89. + .functions = BIT(USB_FUNCTION_MASS_STORAGE_NUM)
  90. + | BIT(USB_FUNCTION_DIAG_NUM)
  91. + },
  92. +#endif
  93. +#if defined(CONFIG_USB_FUNCTION_FSERIAL) && defined(CONFIG_USB_FUNCTION_ADB)
  94. + {
  95. + .product_id = 0x0c04,
  96. + .functions = BIT(USB_FUNCTION_MASS_STORAGE_NUM)
  97. + | BIT(USB_FUNCTION_ADB_NUM)
  98. + | BIT(USB_FUNCTION_FSERIAL_NUM)
  99. + },
  100. +#endif
  101. +#if defined(CONFIG_USB_FUNCTION_PROJECTOR) && defined(CONFIG_USB_FUNCTION_ADB)
  102. + {
  103. + .product_id = 0x0c06,
  104. + .functions = BIT(USB_FUNCTION_MASS_STORAGE_NUM)
  105. + | BIT(USB_FUNCTION_ADB_NUM)
  106. + | BIT(USB_FUNCTION_PROJECTOR_NUM)
  107. + },
  108. +#endif
  109. +#if defined(CONFIG_USB_FUNCTION_DIAG) && defined(CONFIG_USB_FUNCTION_ADB)
  110. + {
  111. + .product_id = 0x0c07,
  112. + .functions = BIT(USB_FUNCTION_MASS_STORAGE_NUM)
  113. + | BIT(USB_FUNCTION_ADB_NUM)
  114. + | BIT(USB_FUNCTION_DIAG_NUM)
  115. + },
  116. +#endif
  117. +#if defined(CONFIG_USB_FUNCTION_ETHER)
  118. + {
  119. + .product_id = 0x0FFE,
  120. + .functions = BIT(USB_FUNCTION_INTERNET_SHARING_NUM)
  121. + },
  122. +#endif
  123. +#if defined(CONFIG_USB_FUNCTION_ETHER) && defined(CONFIG_USB_FUNCTION_RNDIS_WCEIS)
  124. + {
  125. + .product_id = 0x0FFE,
  126. + .functions = BIT(USB_FUNCTION_MASS_STORAGE_NUM)
  127. + | BIT(USB_FUNCTION_ADB_NUM)
  128. + | BIT(USB_FUNCTION_INTERNET_SHARING_NUM)
  129. + },
  130. +#endif
  131. };
  132. #endif
  133.  
  134. struct msm_hsusb_platform_data msm_hsusb_pdata = {
  135. .phy_reset = internal_phy_reset,
  136. .phy_init_seq = hsusb_phy_init_seq,
  137. +#ifdef CONFIG_TROUT_BATTCHG
  138. .usb_connected = notify_usb_connected,
  139. +#endif
  140. #ifdef CONFIG_USB_FUNCTION
  141. .vendor_id = 0x0bb4,
  142. .product_id = 0x0c02,
  143. diff -Naurp a/drivers/usb/function/adb.c b/drivers/usb/function/adb.c
  144. --- a/drivers/usb/function/adb.c 2009-12-18 22:07:48.387475809 +0100
  145. +++ b/drivers/usb/function/adb.c 2009-12-18 22:07:57.603472988 +0100
  146. @@ -481,6 +481,7 @@ static struct usb_function usb_func_adb
  147. .ifc_ept_type = { EPT_BULK_OUT, EPT_BULK_IN },
  148.  
  149. /* the adb function is only enabled when its driver file is open */
  150. + .position_bit = USB_FUNCTION_ADB_NUM,
  151. .disabled = 1,
  152. };
  153.  
  154. diff -Naurp a/drivers/usb/function/diag.c b/drivers/usb/function/diag.c
  155. --- a/drivers/usb/function/diag.c 2009-12-18 22:08:17.379477528 +0100
  156. +++ b/drivers/usb/function/diag.c 2009-12-18 22:08:24.579489302 +0100
  157. @@ -231,6 +231,8 @@ static struct usb_function usb_func_diag
  158.  
  159. .ifc_ept_count = 2,
  160. .ifc_ept_type = { EPT_BULK_OUT, EPT_BULK_IN },
  161. +
  162. + .position_bit = USB_FUNCTION_DIAG_NUM,
  163. };
  164.  
  165. static int msm_diag_probe(struct platform_device *pdev)
  166. diff -Naurp a/drivers/usb/function/ether.c b/drivers/usb/function/ether.c
  167. --- a/drivers/usb/function/ether.c 2009-12-18 22:08:40.803488056 +0100
  168. +++ b/drivers/usb/function/ether.c 2009-12-18 22:08:46.615475831 +0100
  169. @@ -1,69 +1,396 @@
  170. /* drivers/usb/function/ether.c
  171. *
  172. - * Simple Ethernet Function Device
  173. + * RNDIS function device
  174. *
  175. - * Copyright (C) 2008 Google, Inc.
  176. - * Author: Brian Swetland <swetland@google.com>
  177. + * Copyright (C) 2008 htc, Inc.
  178. + * Author: Arec Kao <arec_kao@htc.com>
  179. *
  180. - * This software is licensed under the terms of the GNU General Public
  181. - * License version 2, as published by the Free Software Foundation, and
  182. - * may be copied, distributed, and modified under those terms.
  183. - *
  184. - * This program is distributed in the hope that it will be useful,
  185. - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  186. - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  187. - * GNU General Public License for more details.
  188. - *
  189. - * Implements the "cdc_subset" bulk-only protocol supported by Linux.
  190. + * Based heavily on the function ethernet and gadget ethernet driver in
  191. + * android/drivers/usb/function/ether.c
  192. + * linux/drivers/usb/gadget/ether.c
  193. *
  194. */
  195.  
  196. #include <linux/init.h>
  197. #include <linux/module.h>
  198. #include <linux/kernel.h>
  199. +#include <linux/platform_device.h>
  200.  
  201. #include <linux/netdevice.h>
  202. #include <linux/etherdevice.h>
  203. #include <linux/skbuff.h>
  204. +#include <linux/usb/ch9.h>
  205. +#include <linux/usb/cdc.h>
  206.  
  207. #include "usb_function.h"
  208. +#include "rndis.h"
  209.  
  210. /* Ethernet frame is 1514 + FCS, but round up to 512 * 3 so we
  211. * always queue a multiple of the USB max packet size (64 or 512)
  212. */
  213. -#define USB_MTU 1536
  214. +/* daniel, enlarget the size to 1600 to receive big size packet.
  215. + * should the size change to 2048(512*4)? need to confirm with USB team
  216. + */
  217. +#define USB_MTU 1600//1536
  218.  
  219. #define MAX_TX 8
  220. #define MAX_RX 8
  221. +#define MAX_INTR_TX 4
  222. +#define MAX_EP0_RX 2
  223. +
  224. +#define DEBUG
  225. +#ifdef DEBUG
  226. +#define DBG(fmt,args...) \
  227. + printk(KERN_DEBUG fmt, ## args)
  228. +#else
  229. +#define DBG(fmt,args...) \
  230. + do { } while (0)
  231. +#endif /* DEBUG */
  232. +
  233. +#define ETHER_FUNCTION_NAME "ether"
  234. +
  235. +static char manufacturer [10] = "HTC";
  236. +
  237. +#define STATUS_INTERVAL_MSEC 9 /* 2^8*125us = 32ms */
  238. +
  239. +#define HS_BPS (13 * 512 * 8 * 1000 * 8)
  240. +
  241. +static struct usb_interface_descriptor
  242. +control_intf = {
  243. + .bLength = USB_DT_INTERFACE_SIZE,
  244. + .bDescriptorType = USB_DT_INTERFACE,
  245. + //.bInterfaceNumber = 0,
  246. + .bAlternateSetting = 0,
  247. + .bNumEndpoints = 1,
  248. +#ifdef CONFIG_USB_FUNCTION_RNDIS_WCEIS
  249. + /* "Wireless" RNDIS; auto-detected by Windows */
  250. + .bInterfaceClass = USB_CLASS_WIRELESS_CONTROLLER,
  251. + .bInterfaceSubClass = 1,
  252. + .bInterfaceProtocol = 3,
  253. +#else
  254. + /* Standard, but not auto-detected by any Microsoft operating system. */
  255. + .bInterfaceClass = USB_CLASS_COMM,
  256. + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
  257. + .bInterfaceProtocol = USB_CDC_ACM_PROTO_VENDOR,
  258. +#endif
  259. + .iInterface = STRING_ES,
  260. +};
  261. +
  262. +static struct usb_cdc_header_desc header_desc = {
  263. + .bLength = sizeof header_desc,
  264. + .bDescriptorType = USB_DT_CS_INTERFACE,
  265. + .bDescriptorSubType = USB_CDC_HEADER_TYPE,
  266. +
  267. + .bcdCDC = 0x0110,
  268. +};
  269. +
  270. +static struct usb_cdc_call_mgmt_descriptor call_mgmt_desc = {
  271. + .bLength = sizeof call_mgmt_desc,
  272. + .bDescriptorType = USB_DT_CS_INTERFACE,
  273. + .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
  274. +
  275. + .bmCapabilities = 0x00,
  276. + //.bDataInterface = 0x01,
  277. +};
  278. +
  279. +static struct usb_cdc_acm_descriptor acm_desc = {
  280. + .bLength = sizeof acm_desc,
  281. + .bDescriptorType = USB_DT_CS_INTERFACE,
  282. + .bDescriptorSubType = USB_CDC_ACM_TYPE,
  283. +
  284. + .bmCapabilities = 0x00,
  285. +};
  286. +
  287. +static struct usb_cdc_union_desc union_desc = {
  288. + .bLength = sizeof union_desc,
  289. + .bDescriptorType = USB_DT_CS_INTERFACE,
  290. + .bDescriptorSubType = USB_CDC_UNION_TYPE,
  291. +
  292. + //.bMasterInterface0 = 0, /* index of control interface */
  293. + //.bSlaveInterface0 = 1, /* index of DATA interface */
  294. +};
  295. +
  296. +static struct usb_endpoint_descriptor
  297. +status_desc = {
  298. + .bLength = USB_DT_ENDPOINT_SIZE,
  299. + .bDescriptorType = USB_DT_ENDPOINT,
  300. + //.bEndpointAddress = 0x81,
  301. + .bmAttributes = USB_ENDPOINT_XFER_INT,
  302. + .wMaxPacketSize = 64,
  303. + .bInterval = STATUS_INTERVAL_MSEC,
  304. +};
  305. +
  306. +static struct usb_interface_descriptor
  307. +data_intf = {
  308. + .bLength = sizeof data_intf,
  309. + .bDescriptorType = USB_DT_INTERFACE,
  310. +
  311. + //.bInterfaceNumber = 1,
  312. + .bAlternateSetting = 0,
  313. + .bNumEndpoints = 2,
  314. + .bInterfaceClass = USB_CLASS_CDC_DATA,
  315. + .bInterfaceSubClass = 0,
  316. + .bInterfaceProtocol = 0,
  317. + .iInterface = STRING_ES,
  318. +};
  319. +
  320. +//OUT
  321. +static struct usb_endpoint_descriptor
  322. +sink_desc = {
  323. + .bLength = USB_DT_ENDPOINT_SIZE,
  324. + .bDescriptorType = USB_DT_ENDPOINT,
  325. + //.bEndpointAddress = 0x01,
  326. + .bmAttributes = USB_ENDPOINT_XFER_BULK,
  327. + .wMaxPacketSize = 512,
  328. +};
  329. +
  330. +//IN
  331. +static struct usb_endpoint_descriptor
  332. +source_desc = {
  333. + .bLength = USB_DT_ENDPOINT_SIZE,
  334. + .bDescriptorType = USB_DT_ENDPOINT,
  335. + //.bEndpointAddress = 0x82,
  336. + .bmAttributes = USB_ENDPOINT_XFER_BULK,
  337. + .wMaxPacketSize = 512,
  338. +};
  339. +
  340. +static struct usb_descriptor_header *rndis_desc [] = {
  341. + (struct usb_descriptor_header *) &control_intf,
  342. + (struct usb_descriptor_header *) &header_desc,
  343. + (struct usb_descriptor_header *) &call_mgmt_desc,
  344. + (struct usb_descriptor_header *) &acm_desc,
  345. + (struct usb_descriptor_header *) &union_desc,
  346. + (struct usb_descriptor_header *) &status_desc,
  347. + (struct usb_descriptor_header *) &data_intf,
  348. + (struct usb_descriptor_header *) &sink_desc,
  349. + (struct usb_descriptor_header *) &source_desc,
  350. + NULL,
  351. +};
  352.  
  353. struct ether_context {
  354. spinlock_t lock;
  355. struct net_device *dev;
  356. +
  357. + struct usb_endpoint *intr_in;
  358. struct usb_endpoint *out;
  359. struct usb_endpoint *in;
  360. + struct usb_endpoint *ep0in;
  361. + struct usb_endpoint *ep0out;
  362. +
  363.  
  364. struct list_head rx_reqs;
  365. struct list_head tx_reqs;
  366. + struct list_head tx_intr_reqs;
  367. + struct list_head rx_cmd_reqs;
  368.  
  369. struct net_device_stats stats;
  370. + u8 host_mac [ETH_ALEN];
  371. + int rndis_config;
  372. + u16 cdc_filter;
  373. + int registered;
  374. + int online;
  375. };
  376.  
  377. +static void receive_rndis_command (struct usb_endpoint *ep, struct usb_request *req);
  378. +
  379. static int ether_queue_out(struct ether_context *ctxt,
  380. struct usb_request *req);
  381. static void ether_in_complete(struct usb_endpoint *ept,
  382. struct usb_request *req);
  383. static void ether_out_complete(struct usb_endpoint *ept,
  384. struct usb_request *req);
  385. +static void eth_bind(struct usb_endpoint **ept,
  386. + void *_ctxt);
  387. +static void eth_unbind(void *_ctxt);
  388. +
  389. +static void eth_configure(int configured, void *_ctxt);
  390. +
  391. +static int eth_setup(struct usb_ctrlrequest *ctrl, void *buf,
  392. + int len, void *_ctxt);
  393. +
  394. +static void eth_start (struct ether_context *ctxt, gfp_t gfp_flags);
  395. +
  396. +static void rx_fill(struct ether_context *ctxt);
  397. +
  398. +static size_t rndis_desc_copy(char *buf, size_t buf_len, int ifc_number);
  399. +
  400. +static struct usb_function usb_func_ether = {
  401. + .bind = eth_bind,
  402. + .unbind = eth_unbind,
  403. + .configure = eth_configure,
  404. + .setup = eth_setup,
  405. +
  406. + .name = ETHER_FUNCTION_NAME,
  407. +
  408. + .ifc_class = 0x02,
  409. + .ifc_subclass = 0x02,
  410. + .ifc_protocol = 0xff,
  411. +
  412. + .ifc_name = "ether",
  413. +
  414. + .ifc_num = 2,
  415. + .ifc_ept_count = 3,
  416. + .ifc_ept_type = { EPT_INT_IN, EPT_BULK_OUT, EPT_BULK_IN },
  417. +
  418. + .ifc_copy = rndis_desc_copy,
  419. +
  420. + .position_bit = USB_FUNCTION_INTERNET_SHARING_NUM,
  421. + .disabled = 1,
  422. +};
  423. +
  424. +/* remove a request from the head of a list */
  425. +
  426. +static struct usb_request *req_get(struct ether_context *ctxt, struct list_head *head)
  427. +{
  428. + unsigned long flags;
  429. + struct usb_request *req;
  430. +
  431. + spin_lock_irqsave(&ctxt->lock, flags);
  432. + if (list_empty(head)) {
  433. + req = 0;
  434. + } else {
  435. + req = list_first_entry(head, struct usb_request, list);
  436. + list_del(&req->list);
  437. + }
  438. + spin_unlock_irqrestore(&ctxt->lock, flags);
  439. + return req;
  440. +}
  441. +
  442. +static void
  443. +rndis_control_ack_complete (struct usb_endpoint *ept, struct usb_request *req)
  444. +{
  445. + struct ether_context *ctxt = req->context;
  446. + unsigned long flags;
  447. +
  448. + //DBG("rndis_control_ack_complete\n");
  449. + if (req->status || req->actual != req->length)
  450. + printk(KERN_ERR "rndis control ack complete --> %d, %d/%d\n",
  451. + req->status, req->actual, req->length);
  452. + req->context = NULL;
  453. + spin_lock_irqsave(&ctxt->lock, flags);
  454. + list_add_tail(&req->list, &ctxt->tx_intr_reqs);
  455. + spin_unlock_irqrestore(&ctxt->lock, flags);
  456. +
  457. +}
  458. +
  459. +static int rndis_control_ack (struct net_device *net)
  460. +{
  461. + struct ether_context *ctxt = netdev_priv(net);
  462. + struct usb_request *resp = req_get(ctxt, &ctxt->tx_intr_reqs);
  463. + if (!resp) {
  464. + printk(KERN_ERR "rndis_control_ack: get request fial\n");
  465. + return -1;
  466. + }
  467. + resp->length = 8;
  468. + resp->context = ctxt;
  469. +
  470. + *((__le32 *) resp->buf) = __constant_cpu_to_le32 (1);
  471. + *((__le32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
  472. +
  473. + if (usb_ept_queue_xfer(ctxt->intr_in, resp)) {
  474. + resp->status = 0;
  475. + rndis_control_ack_complete (ctxt->intr_in, resp);
  476. + }
  477. +
  478. + return 0;
  479. +}
  480. +
  481. +static ssize_t store_enable(struct device *dev, struct device_attribute *attr,
  482. + const char *buf, size_t count)
  483. +{
  484. + unsigned long ul;
  485. + if (count > 2 || (buf[0] != '0' && buf[0] != '1')) {
  486. + printk(KERN_ERR "Can't enable/disable ether %s\n", buf);
  487. + return -EINVAL;
  488. + }
  489. + ul = simple_strtoul(buf, NULL, 10);
  490. + usb_function_enable(ETHER_FUNCTION_NAME, ul);
  491. +
  492. + return count;
  493. +}
  494. +
  495. +static ssize_t show_enable(struct device *dev, struct device_attribute *attr,
  496. + char *buf)
  497. +{
  498. + if (return_usb_function_enabled(ETHER_FUNCTION_NAME) > 0) {
  499. + buf[0] = '1';
  500. + buf[1] = '\n';
  501. + }
  502. + else {
  503. + buf[0] = '0';
  504. + buf[1] = '\n';
  505. + }
  506. + return 2;
  507. +
  508. +}
  509. +
  510. +static DEVICE_ATTR(enable, 0644, show_enable, store_enable);
  511.  
  512. -static void ether_bind(struct usb_endpoint **ept, void *_ctxt)
  513. +static void eth_unbind(void *_ctxt)
  514. +{
  515. + struct ether_context *ctxt = _ctxt;
  516. + struct usb_request *req;
  517. +
  518. + while ((req = req_get(ctxt, &ctxt->tx_intr_reqs))) {
  519. + usb_ept_free_req(ctxt->intr_in, req);
  520. + }
  521. + while ((req = req_get(ctxt, &ctxt->rx_cmd_reqs))) {
  522. + usb_ept_free_req(ctxt->ep0out, req);
  523. + }
  524. + while ((req = req_get(ctxt, &ctxt->rx_reqs))) {
  525. + usb_ept_free_req(ctxt->out, req);
  526. + }
  527. + while ((req = req_get(ctxt, &ctxt->tx_reqs))) {
  528. + usb_ept_free_req(ctxt->in, req);
  529. + }
  530. + if (ctxt->registered == 1) {
  531. + device_remove_file(&ctxt->dev->dev, &dev_attr_enable);
  532. + ctxt->registered = 0;
  533. + }
  534. + rndis_deregister (ctxt->rndis_config);
  535. + //rndis_exit ();
  536. + //unregister_netdev (ctxt->dev);
  537. + //free_netdev(ctxt->dev);
  538. +}
  539. +
  540. +static void eth_bind(struct usb_endpoint **ept, void *_ctxt)
  541. {
  542. struct ether_context *ctxt = _ctxt;
  543. struct usb_request *req;
  544. unsigned long flags;
  545. int n;
  546. + int status = -ENOMEM;
  547. + struct usb_fi_ept *ept_info;
  548. +
  549. + u32 vendorID = 0x0bb4;
  550. +
  551. + ctxt->registered = 0;
  552. +
  553. + ctxt->intr_in = ept[0];
  554. + ctxt->out = ept[1];
  555. + ctxt->in = ept[2];
  556. + ctxt->ep0in = ept[3];
  557. + ctxt->ep0out = ept[4];
  558.  
  559. - ctxt->out = ept[0];
  560. - ctxt->in = ept[1];
  561. + for (n = 0; n < MAX_INTR_TX; n++) {
  562. + req = usb_ept_alloc_req(ctxt->intr_in, 8);
  563. + if (!req)
  564. + break;
  565. + req->complete = rndis_control_ack_complete;
  566. + spin_lock_irqsave(&ctxt->lock, flags);
  567. + list_add_tail(&req->list, &ctxt->tx_intr_reqs);
  568. + spin_unlock_irqrestore(&ctxt->lock, flags);
  569. + }
  570. +
  571. + for (n = 0; n < MAX_EP0_RX; n++) {
  572. + req = usb_ept_alloc_req(ctxt->ep0out, 4096);
  573. + if (!req)
  574. + break;
  575. + req->complete = receive_rndis_command;
  576. + spin_lock_irqsave(&ctxt->lock, flags);
  577. + list_add_tail(&req->list, &ctxt->rx_cmd_reqs);
  578. + spin_unlock_irqrestore(&ctxt->lock, flags);
  579. + }
  580.  
  581. for (n = 0; n < MAX_RX; n++) {
  582. req = usb_ept_alloc_req(ctxt->out, 0);
  583. @@ -83,6 +410,81 @@ static void ether_bind(struct usb_endpoi
  584. list_add_tail(&req->list, &ctxt->tx_reqs);
  585. spin_unlock_irqrestore(&ctxt->lock, flags);
  586. }
  587. +
  588. + ept_info = get_ept_info(ETHER_FUNCTION_NAME);
  589. + if (!ept_info)
  590. + goto fail;
  591. +
  592. + status_desc.bEndpointAddress = ept_info[0].desc.bEndpointAddress;
  593. + sink_desc.bEndpointAddress = ept_info[1].desc.bEndpointAddress;
  594. + source_desc.bEndpointAddress = ept_info[2].desc.bEndpointAddress;
  595. +
  596. + status = device_create_file(&ctxt->dev->dev, &dev_attr_enable);
  597. + if (status != 0) {
  598. + printk(KERN_ERR "ether device_create_file failed: %d\n", status);
  599. + goto fail;
  600. + }
  601. + ctxt->registered = 1;
  602. + ctxt->online = 0;
  603. + status = rndis_init();
  604. + if (status < 0) {
  605. + printk(KERN_ERR "can't init RNDIS, %d\n", status);
  606. + goto fail;
  607. + }
  608. +
  609. + netif_stop_queue (ctxt->dev);
  610. + netif_carrier_off (ctxt->dev);
  611. +
  612. + ctxt->rndis_config = rndis_register (rndis_control_ack);
  613. + if (ctxt->rndis_config < 0) {
  614. + printk(KERN_ERR "ether bind: rndis_register fial, %d\n", ctxt->rndis_config);
  615. + //unregister_netdev (ctxt->dev);
  616. + goto fail;
  617. + }
  618. +
  619. + rndis_set_host_mac (ctxt->rndis_config, ctxt->host_mac);
  620. + if (rndis_set_param_dev (ctxt->rndis_config, ctxt->dev,
  621. + &ctxt->stats, &ctxt->cdc_filter))
  622. + goto fail;
  623. + if (rndis_set_param_vendor(ctxt->rndis_config, vendorID,
  624. + manufacturer))
  625. + goto fail;
  626. + if (rndis_set_param_medium(ctxt->rndis_config,
  627. + NDIS_MEDIUM_802_3, 0))
  628. + goto fail;
  629. +
  630. + return;
  631. +
  632. +fail:
  633. + eth_unbind (ctxt);
  634. + return;
  635. +}
  636. +
  637. +static size_t rndis_desc_copy(char *buf, size_t buf_len, int ifc_number)
  638. +{
  639. + char *ptr = buf;
  640. + struct usb_descriptor_header **src = rndis_desc;
  641. +
  642. + control_intf.bInterfaceNumber = ifc_number;
  643. + data_intf.bInterfaceNumber = ifc_number + 1;
  644. +
  645. + call_mgmt_desc.bDataInterface = data_intf.bInterfaceNumber;
  646. + union_desc.bMasterInterface0 = control_intf.bInterfaceNumber;
  647. + union_desc.bSlaveInterface0 = data_intf.bInterfaceNumber;
  648. +
  649. + for (; NULL != *src; src++) {
  650. + unsigned len = (*src)->bLength;
  651. + if (unlikely(buf_len < (ptr - buf + len)))
  652. + goto bad_setup_size;
  653. + memcpy(ptr, *src, len);
  654. + ptr += len;
  655. + }
  656. +
  657. + return ptr - buf;
  658. +
  659. +bad_setup_size:
  660. + printk(KERN_ERR "ether: Increase SETUP_BUF_SIZE\n");
  661. + return 0;
  662. }
  663.  
  664. static void ether_in_complete(struct usb_endpoint *ept,
  665. @@ -113,14 +515,24 @@ static void ether_out_complete(struct us
  666. {
  667. struct sk_buff *skb = req->context;
  668. struct ether_context *ctxt = *((void **) skb->cb);
  669. + int status = req->status;
  670.  
  671. - if (req->status == 0) {
  672. + if (status == 0) {
  673. skb_put(skb, req->actual);
  674. + status = rndis_rm_hdr (skb);
  675. + if (status < 0
  676. + || ETH_HLEN > skb->len
  677. + || skb->len > ETH_FRAME_LEN) {
  678. + ctxt->stats.rx_length_errors++;
  679. + printk(KERN_ERR "rx length %d\n", skb->len);
  680. + goto error;
  681. + }
  682. skb->protocol = eth_type_trans(skb, ctxt->dev);
  683. ctxt->stats.rx_packets++;
  684. ctxt->stats.rx_bytes += req->actual;
  685. netif_rx(skb);
  686. } else {
  687. +error:
  688. dev_kfree_skb_any(skb);
  689. ctxt->stats.rx_errors++;
  690. }
  691. @@ -169,52 +581,148 @@ fail:
  692. return ret;
  693. }
  694.  
  695. -static void ether_configure(int configured, void *_ctxt)
  696. +static void rx_fill(struct ether_context *ctxt)
  697. {
  698. - unsigned long flags;
  699. - struct ether_context *ctxt = _ctxt;
  700. struct usb_request *req;
  701. + /* we're online -- get all rx requests queued */
  702. + for (;;) {
  703. + req = req_get(ctxt, &ctxt->rx_reqs);
  704. + if (!req)
  705. + break;
  706. + if (ether_queue_out(ctxt, req))
  707. + break;
  708. + }
  709. +}
  710.  
  711. - pr_info("ether_configure() %d\n", configured);
  712. +static void eth_configure(int configured, void *_ctxt)
  713. +{
  714. + struct ether_context *ctxt = _ctxt;
  715. + netif_stop_queue(ctxt->dev);
  716. + netif_carrier_off(ctxt->dev);
  717. + ctxt->online = 0;
  718.  
  719. if (configured) {
  720. - /* we're online -- get all rx requests queued */
  721. - for (;;) {
  722. - spin_lock_irqsave(&ctxt->lock, flags);
  723. - if (list_empty(&ctxt->rx_reqs)) {
  724. - req = 0;
  725. - } else {
  726. - req = list_first_entry(&ctxt->rx_reqs,
  727. - struct usb_request,
  728. - list);
  729. - list_del(&req->list);
  730. - }
  731. - spin_unlock_irqrestore(&ctxt->lock, flags);
  732. - if (!req)
  733. - break;
  734. - if (ether_queue_out(ctxt, req))
  735. - break;
  736. - }
  737. + ctxt->online = 1;
  738. + rx_fill(ctxt);
  739. + netif_carrier_on(ctxt->dev);
  740. + if (netif_running(ctxt->dev))
  741. + eth_start(ctxt, GFP_KERNEL);
  742. } else {
  743. + rndis_uninit(ctxt->rndis_config);
  744. /* all pending requests will be canceled */
  745. }
  746. }
  747.  
  748. -static struct usb_function usb_func_ether = {
  749. - .bind = ether_bind,
  750. - .configure = ether_configure,
  751. +/*
  752. +static void queue_command_request(struct usb_endpoint *ep, struct usb_request *req)
  753. +{
  754. + struct ether_context *ctxt = usb_func_ether.context;
  755. + unsigned long flags;
  756.  
  757. - .name = "ether",
  758. + req->complete = 0;
  759. + spin_lock_irqsave(&ctxt->lock, flags);
  760. + list_add_tail(&req->list, &ctxt->rx_cmd_reqs);
  761. + spin_unlock_irqrestore(&ctxt->lock, flags);
  762. +}
  763. +*/
  764.  
  765. - .ifc_class = 0x02,
  766. - .ifc_subclass = 0x0a,
  767. - .ifc_protocol = 0x00,
  768. +static void rndis_command_complete(struct usb_endpoint *ep, struct usb_request *req)
  769. +{
  770. + struct ether_context *ctxt = usb_func_ether.context;
  771. + unsigned long flags;
  772. + req->length = 0;
  773. + //req->complete = queue_command_request;
  774. + //usb_ept_queue_xfer(ctxt->ep0out, req);
  775. + req->complete = 0;
  776. + spin_lock_irqsave(&ctxt->lock, flags);
  777. + list_add_tail(&req->list, &ctxt->rx_cmd_reqs);
  778. + spin_unlock_irqrestore(&ctxt->lock, flags);
  779.  
  780. - .ifc_name = "ether",
  781. +}
  782.  
  783. - .ifc_ept_count = 2,
  784. - .ifc_ept_type = { EPT_BULK_OUT, EPT_BULK_IN },
  785. -};
  786. +static void receive_rndis_command (struct usb_endpoint *ep, struct usb_request *req)
  787. +{
  788. + struct ether_context *ctxt = usb_func_ether.context;
  789. + int status;
  790. +/*
  791. + DBG("receive_rndis_command: data %02x %02x %02x, actual length %d, req status %d\n", \
  792. + *((char *)(req->buf)), \
  793. + *((char *)(req->buf + 1)), \
  794. + *((char *)(req->buf + 2)), \
  795. + req->actual, \
  796. + req->status);
  797. +*/
  798. + /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
  799. + spin_lock(&ctxt->lock);
  800. + status = rndis_msg_parser (ctxt->rndis_config, (u8 *) req->buf);
  801. + if (status < 0)
  802. + printk(KERN_ERR "%s: rndis parse error %d\n", __FUNCTION__, status);
  803. + spin_unlock(&ctxt->lock);
  804. + req->length = 0;
  805. + req->complete = rndis_command_complete;
  806. + usb_ept_queue_xfer(ctxt->ep0in, req);
  807. +}
  808. +
  809. +
  810. +static int eth_setup(struct usb_ctrlrequest *ctrl, void *buf,
  811. + int len, void *_ctxt)
  812. +{
  813. + struct ether_context *ctxt = _ctxt;
  814. + int value = -EOPNOTSUPP;
  815. + u16 w_index = le16_to_cpu(ctrl->wIndex);
  816. + u16 w_value = le16_to_cpu(ctrl->wValue);
  817. + u16 w_length = le16_to_cpu(ctrl->wLength);
  818. +
  819. + if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) {
  820. + switch (ctrl->bRequest) {
  821. + case USB_CDC_SEND_ENCAPSULATED_COMMAND:
  822. + {
  823. + struct usb_request *req;
  824. + if ( w_value || control_intf.bInterfaceNumber != w_index)
  825. + break;
  826. + req = req_get(ctxt, &ctxt->rx_cmd_reqs);
  827. + if (!req) {
  828. + printk(KERN_ERR "%s: could not obtain tx request\n", __FUNCTION__);
  829. + value = -ENOMEM;
  830. + break;
  831. + }
  832. + value = w_length;
  833. + req->length = w_length;
  834. + req->complete = receive_rndis_command;
  835. + usb_ept_queue_xfer(ctxt->ep0out, req);
  836. + break;
  837. + }
  838. + case USB_CDC_GET_ENCAPSULATED_RESPONSE:
  839. + if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)
  840. + == ctrl->bRequestType
  841. + && !w_value
  842. + && control_intf.bInterfaceNumber == w_index) {
  843. + u8 *tmp;
  844. + u32 n;
  845. +
  846. + /* return the result */
  847. + tmp = rndis_get_next_response(ctxt->rndis_config, &n);
  848. + if (tmp) {
  849. + memcpy(buf, tmp, n);
  850. + //req->complete = rndis_response_complete;
  851. + rndis_free_response(ctxt->rndis_config, tmp);
  852. + value = n;
  853. + }
  854. + /* else stalls ... spec says to avoid that */
  855. + }
  856. + break;
  857. + }
  858. + }
  859. +
  860. + if (value == -EOPNOTSUPP)
  861. + printk(KERN_ERR
  862. + "unknown class-specific control req "
  863. + "%02x.%02x v%04x i%04x l%u\n",
  864. + ctrl->bRequestType, ctrl->bRequest,
  865. + le16_to_cpu(ctrl->wValue), w_index, w_length);
  866. +
  867. + return value;
  868. +}
  869.  
  870. static int usb_ether_xmit(struct sk_buff *skb, struct net_device *dev)
  871. {
  872. @@ -222,23 +730,26 @@ static int usb_ether_xmit(struct sk_buff
  873. struct usb_request *req;
  874. unsigned long flags;
  875. unsigned len;
  876. + struct sk_buff *skb_rndis;
  877.  
  878. - spin_lock_irqsave(&ctxt->lock, flags);
  879. - if (list_empty(&ctxt->tx_reqs)) {
  880. - req = 0;
  881. - } else {
  882. - req = list_first_entry(&ctxt->tx_reqs,
  883. - struct usb_request, list);
  884. - list_del(&req->list);
  885. - if (list_empty(&ctxt->tx_reqs))
  886. - netif_stop_queue(dev);
  887. - }
  888. - spin_unlock_irqrestore(&ctxt->lock, flags);
  889. -
  890. + req = req_get(ctxt, &ctxt->tx_reqs);
  891. if (!req) {
  892. pr_err("usb_ether_xmit: could not obtain tx request\n");
  893. return 1;
  894. }
  895. + spin_lock_irqsave(&ctxt->lock, flags);
  896. + if (list_empty(&ctxt->tx_reqs))
  897. + netif_stop_queue(dev);
  898. + spin_unlock_irqrestore(&ctxt->lock, flags);
  899. +
  900. + skb_rndis = skb_realloc_headroom (skb,
  901. + sizeof (struct rndis_packet_msg_type));
  902. + if (!skb_rndis)
  903. + goto drop;
  904. +
  905. + dev_kfree_skb_any (skb);
  906. + skb = skb_rndis;
  907. + rndis_add_hdr (skb);
  908.  
  909. /* ensure that we end with a short packet */
  910. len = skb->len;
  911. @@ -251,11 +762,12 @@ static int usb_ether_xmit(struct sk_buff
  912. req->length = len;
  913.  
  914. if (usb_ept_queue_xfer(ctxt->in, req)) {
  915. +drop:
  916. spin_lock_irqsave(&ctxt->lock, flags);
  917. list_add_tail(&req->list, &ctxt->tx_reqs);
  918. - netif_start_queue(dev);
  919. + if (list_empty(&ctxt->tx_reqs))
  920. + netif_start_queue(dev);
  921. spin_unlock_irqrestore(&ctxt->lock, flags);
  922. -
  923. dev_kfree_skb_any(skb);
  924. ctxt->stats.tx_dropped++;
  925.  
  926. @@ -265,13 +777,39 @@ static int usb_ether_xmit(struct sk_buff
  927. return 0;
  928. }
  929.  
  930. +static void eth_start (struct ether_context *ctxt, gfp_t gfp_flags)
  931. +{
  932. +
  933. + /* fill the rx queue */
  934. + rx_fill (ctxt);
  935. +
  936. + /* and open the tx floodgates */
  937. + netif_wake_queue (ctxt->dev);
  938. + if (ctxt->online) {
  939. + rndis_set_param_medium (ctxt->rndis_config, NDIS_MEDIUM_802_3,
  940. + HS_BPS/100);
  941. + (void) rndis_signal_connect (ctxt->rndis_config);
  942. + }
  943. +}
  944. +
  945. static int usb_ether_open(struct net_device *dev)
  946. {
  947. + struct ether_context *ctxt = netdev_priv(dev);
  948. + DBG("usb_ether_open\n");
  949. + if (netif_carrier_ok (ctxt->dev))
  950. + eth_start (ctxt, GFP_KERNEL);
  951. return 0;
  952. }
  953.  
  954. static int usb_ether_stop(struct net_device *dev)
  955. {
  956. + struct ether_context *ctxt = netdev_priv(dev);
  957. + DBG("usb_ether_stop\n");
  958. + netif_stop_queue (dev);
  959. + if (ctxt->online) {
  960. + rndis_set_param_medium(ctxt->rndis_config, NDIS_MEDIUM_802_3, 0);
  961. + (void) rndis_signal_disconnect (ctxt->rndis_config);
  962. + }
  963. return 0;
  964. }
  965.  
  966. @@ -285,10 +823,10 @@ static void __init usb_ether_setup(struc
  967. {
  968. struct ether_context *ctxt = netdev_priv(dev);
  969.  
  970. - pr_info("usb_ether_setup()\n");
  971. -
  972. INIT_LIST_HEAD(&ctxt->rx_reqs);
  973. INIT_LIST_HEAD(&ctxt->tx_reqs);
  974. + INIT_LIST_HEAD(&ctxt->tx_intr_reqs);
  975. + INIT_LIST_HEAD(&ctxt->rx_cmd_reqs);
  976. spin_lock_init(&ctxt->lock);
  977. ctxt->dev = dev;
  978.  
  979. @@ -301,11 +839,13 @@ static void __init usb_ether_setup(struc
  980. ether_setup(dev);
  981.  
  982. random_ether_addr(dev->dev_addr);
  983. + random_ether_addr(ctxt->host_mac);
  984. }
  985.  
  986. static int __init ether_init(void)
  987. {
  988. struct net_device *dev;
  989. + struct ether_context *ctxt;
  990. int ret;
  991.  
  992. dev = alloc_netdev(sizeof(struct ether_context),
  993. @@ -314,14 +854,23 @@ static int __init ether_init(void)
  994. return -ENOMEM;
  995.  
  996. ret = register_netdev(dev);
  997. - if (ret) {
  998. - free_netdev(dev);
  999. - } else {
  1000. - struct ether_context *ctxt = netdev_priv(dev);
  1001. - usb_func_ether.context = ctxt;
  1002. - usb_function_register(&usb_func_ether);
  1003. - }
  1004. + if (ret)
  1005. + goto err_register_netdev;
  1006. +
  1007. + ctxt = netdev_priv(dev);
  1008. + usb_func_ether.context = ctxt;
  1009. + ret = usb_function_register(&usb_func_ether);
  1010. + if (ret < 0)
  1011. + goto err_register_function;
  1012. + return ret;
  1013. +
  1014. +err_register_function:
  1015. + unregister_netdev(dev);
  1016. +err_register_netdev:
  1017. + free_netdev(dev);
  1018. +
  1019. return ret;
  1020. +
  1021. }
  1022.  
  1023. module_init(ether_init);
  1024. diff -Naurp a/drivers/usb/function/fserial.c b/drivers/usb/function/fserial.c
  1025. --- a/drivers/usb/function/fserial.c 1970-01-01 01:00:00.000000000 +0100
  1026. +++ b/drivers/usb/function/fserial.c 2009-12-18 23:15:40.959185975 +0100
  1027. @@ -0,0 +1,1666 @@
  1028. +/* drivers/usb/function/fserial.c
  1029. + *
  1030. + * Function Driver for USB Serial
  1031. + *
  1032. + * Copyright (C) 2008 htc, Inc.
  1033. + * Author: Arec Kao <arec_kao@htc.com>
  1034. + *
  1035. + * Based heavily on the serial gadget driver in
  1036. + * drivers/usb/gadget/serial.c
  1037. + *
  1038. + */
  1039. +
  1040. +#include <linux/kernel.h>
  1041. +#include <linux/utsname.h>
  1042. +#include <linux/device.h>
  1043. +#include <linux/tty.h>
  1044. +#include <linux/tty_flip.h>
  1045. +#include <linux/platform_device.h>
  1046. +
  1047. +#include <linux/spinlock.h>
  1048. +#include <linux/wait.h>
  1049. +#include <linux/list.h>
  1050. +
  1051. +#include <linux/usb/ch9.h>
  1052. +#include <linux/usb/cdc.h>
  1053. +#include <linux/usb_usual.h>
  1054. +
  1055. +#include "usb_function.h"
  1056. +
  1057. +/* Defines */
  1058. +
  1059. +#define FS_VERSION_STR "v2.2"
  1060. +#define FS_LONG_NAME "HTC Function Serial Interface"
  1061. +
  1062. +#define FS_SHORT_NAME "fserial"
  1063. +
  1064. +#define FS_MAJOR 127
  1065. +#define FS_MINOR_START 0
  1066. +
  1067. +#define FS_NUM_PORTS 16
  1068. +#define FS_NO_CONFIG_ID 0
  1069. +
  1070. +#define FS_MAX_DESC_LEN 256
  1071. +
  1072. +#define FS_DEFAULT_READ_Q_SIZE 32
  1073. +#define FS_DEFAULT_WRITE_Q_SIZE 32
  1074. +
  1075. +#define FS_DEFAULT_WRITE_BUF_SIZE 8192
  1076. +
  1077. +#define FS_CLOSE_TIMEOUT 15
  1078. +
  1079. +#ifdef CONFIG_BUILD_CIQ
  1080. + #define FS_DEFAULT_DTE_RATE 115200
  1081. +#else
  1082. + #define FS_DEFAULT_DTE_RATE 9600
  1083. +#endif
  1084. +#define FS_DEFAULT_DATA_BITS 8
  1085. +#define FS_DEFAULT_PARITY USB_CDC_NO_PARITY
  1086. +#define FS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS
  1087. +#define MAX_PKT 512
  1088. +
  1089. +/* debug settings */
  1090. +#ifdef DEBUG
  1091. +static int debug = 1;
  1092. +#else
  1093. +#define debug 0
  1094. +#endif
  1095. +
  1096. +#define fs_debug(format, arg...) \
  1097. + do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0)
  1098. +#define fs_debug_level(level, format, arg...) \
  1099. + do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0)
  1100. +
  1101. +
  1102. +/* Structures */
  1103. +
  1104. +struct userial_context;
  1105. +
  1106. +/* circular buffer */
  1107. +struct fs_buf {
  1108. + unsigned int buf_size;
  1109. + char *buf_buf;
  1110. + char *buf_get;
  1111. + char *buf_put;
  1112. +};
  1113. +
  1114. +
  1115. +/* the port structure holds info for each port, one for each minor number */
  1116. +struct fs_port {
  1117. + struct userial_context *port_dev; /* pointer to device struct */
  1118. + struct tty_struct *port_tty; /* pointer to tty struct */
  1119. + spinlock_t port_lock;
  1120. + int port_num;
  1121. + int port_open_count;
  1122. + int port_in_use; /* open/close in progress */
  1123. + wait_queue_head_t port_write_wait;/* waiting to write */
  1124. + struct fs_buf *port_write_buf;
  1125. + struct usb_cdc_line_coding port_line_coding;
  1126. + u16 port_handshake_bits;
  1127. +};
  1128. +
  1129. +struct userial_context{
  1130. +
  1131. + spinlock_t dev_lock;
  1132. + int dev_config; /* configuration number */
  1133. + struct usb_endpoint *dev_out_ep;
  1134. + struct usb_endpoint *dev_in_ep;
  1135. +
  1136. + struct list_head dev_write_list; /* list of write requests */
  1137. + struct list_head dev_read_list;
  1138. +
  1139. + struct fs_port *dev_port[FS_NUM_PORTS]; /* the ports */
  1140. + struct platform_device *pdev;
  1141. + int registered;
  1142. +};
  1143. +static struct userial_context _context;
  1144. +struct device fserial_dev;
  1145. +
  1146. +/* Functions */
  1147. +
  1148. +/* module */
  1149. +static int __init fs_module_init(void);
  1150. +static void __exit fs_module_exit(void);
  1151. +
  1152. +/* tty driver */
  1153. +static int fs_open(struct tty_struct *tty, struct file *file);
  1154. +static void fs_close(struct tty_struct *tty, struct file *file);
  1155. +static int fs_write(struct tty_struct *tty,
  1156. + const unsigned char *buf, int count);
  1157. +static int fs_put_char(struct tty_struct *tty, unsigned char ch);
  1158. +static void fs_flush_chars(struct tty_struct *tty);
  1159. +static int fs_write_room(struct tty_struct *tty);
  1160. +static int fs_chars_in_buffer(struct tty_struct *tty);
  1161. +static void fs_throttle(struct tty_struct * tty);
  1162. +static void fs_unthrottle(struct tty_struct * tty);
  1163. +static int fs_break(struct tty_struct *tty, int break_state);
  1164. +static int fs_ioctl(struct tty_struct *tty, struct file *file,
  1165. + unsigned int cmd, unsigned long arg);
  1166. +static void fs_set_termios(struct tty_struct *tty, struct ktermios *old);
  1167. +
  1168. +static int fs_send(void);
  1169. +static int fs_send_packet(struct userial_context *dev, char *packet, unsigned int size);
  1170. +static int fs_recv_packet(struct userial_context *dev, char *packet, unsigned int size);
  1171. +static void fs_read_complete(struct usb_endpoint *ep, struct usb_request *req);
  1172. +static void fs_write_complete(struct usb_endpoint *ep, struct usb_request *req);
  1173. +
  1174. +/* gadget driver */
  1175. +static void fs_bind(struct usb_endpoint **ept, void *_ctxt);
  1176. +static void fs_unbind(void *_ctxt);
  1177. +static int fs_setup( struct usb_ctrlrequest *ctrl, void* buf, int len, void *_ctxt);
  1178. +//static void fs_setup_complete(struct usb_endpoint *ep, struct usb_request *req);
  1179. +//static void fs_setup_complete_set_line_coding(struct usb_endpoint *ep,
  1180. +// struct usb_request *req);
  1181. +//static void fs_disconnect(struct usb_gadget *gadget);
  1182. +
  1183. +static void fs_configure(int configure, void *context);
  1184. +//static void fs_reset_config(struct userial_context* dev);
  1185. +
  1186. +static int fs_alloc_ports(struct userial_context *ctxt, gfp_t kmalloc_flags);
  1187. +static void fs_free_ports(struct userial_context *ctxt);
  1188. +
  1189. +/* circular buffer */
  1190. +static struct fs_buf *fs_buf_alloc(unsigned int size, gfp_t kmalloc_flags);
  1191. +static void fs_buf_free(struct fs_buf *gb);
  1192. +static void fs_buf_clear(struct fs_buf *gb);
  1193. +static unsigned int fs_buf_data_avail(struct fs_buf *gb);
  1194. +static unsigned int fs_buf_space_avail(struct fs_buf *gb);
  1195. +static unsigned int fs_buf_put(struct fs_buf *gb, const char *buf,
  1196. + unsigned int count);
  1197. +static unsigned int fs_buf_get(struct fs_buf *gb, char *buf,
  1198. + unsigned int count);
  1199. +
  1200. +/* external functions */
  1201. +
  1202. +/* Globals */
  1203. +
  1204. +static struct mutex fs_open_close_lock[FS_NUM_PORTS];
  1205. +
  1206. +static unsigned int read_q_size = FS_DEFAULT_READ_Q_SIZE;
  1207. +static unsigned int write_q_size = FS_DEFAULT_WRITE_Q_SIZE;
  1208. +
  1209. +static unsigned int write_buf_size = FS_DEFAULT_WRITE_BUF_SIZE;
  1210. +
  1211. +
  1212. +/* tty driver struct */
  1213. +static const struct tty_operations fs_tty_ops = {
  1214. + .open = fs_open,
  1215. + .close = fs_close,
  1216. + .write = fs_write,
  1217. + .put_char = fs_put_char,
  1218. + .flush_chars = fs_flush_chars,
  1219. + .write_room = fs_write_room,
  1220. + .ioctl = fs_ioctl,
  1221. + .set_termios = fs_set_termios,
  1222. + .throttle = fs_throttle,
  1223. + .unthrottle = fs_unthrottle,
  1224. + .break_ctl = fs_break,
  1225. + .chars_in_buffer = fs_chars_in_buffer,
  1226. +};
  1227. +static struct tty_driver *fs_tty_driver;
  1228. +
  1229. +/* function driver struct */
  1230. +static struct usb_function usb_func_userial = {
  1231. +
  1232. + .bind = fs_bind,
  1233. + .unbind = fs_unbind,
  1234. + .configure = fs_configure,
  1235. + .setup = fs_setup,
  1236. +
  1237. + .name = FS_SHORT_NAME,
  1238. + .context = &_context,
  1239. +
  1240. + .ifc_class = USB_CLASS_CDC_DATA,
  1241. + .ifc_subclass = 0,
  1242. + .ifc_protocol = 0,
  1243. +
  1244. + .ifc_name = FS_SHORT_NAME,
  1245. +
  1246. + .ifc_ept_count = 2,
  1247. + .ifc_ept_type = { EPT_BULK_OUT, EPT_BULK_IN },
  1248. +
  1249. + .disabled = 1,
  1250. + .position_bit = USB_FUNCTION_FSERIAL_NUM,
  1251. + .ifc_num = 1,
  1252. +};
  1253. +
  1254. +
  1255. +/* Module */
  1256. +
  1257. +#ifdef DEBUG
  1258. +module_param(debug, int, S_IRUGO|S_IWUSR);
  1259. +MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on");
  1260. +#endif
  1261. +
  1262. +module_param(read_q_size, uint, S_IRUGO);
  1263. +MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32");
  1264. +
  1265. +module_param(write_q_size, uint, S_IRUGO);
  1266. +MODULE_PARM_DESC(write_q_size, "Write request queue size, default=32");
  1267. +
  1268. +module_param(write_buf_size, uint, S_IRUGO);
  1269. +MODULE_PARM_DESC(write_buf_size, "Write buffer size, default=8192");
  1270. +
  1271. +
  1272. +module_init(fs_module_init);
  1273. +module_exit(fs_module_exit);
  1274. +
  1275. +static void fserial_dev_release (struct device *dev) {}
  1276. +
  1277. +static int fserial_probe (struct platform_device *pdev)
  1278. +{
  1279. + struct userial_context *ctxt = &_context;
  1280. + ctxt->pdev = pdev;
  1281. + return 0;
  1282. +}
  1283. +
  1284. +static struct platform_driver fserial_driver = {
  1285. + .probe = fserial_probe,
  1286. + .driver = { .name = FS_SHORT_NAME, },
  1287. +};
  1288. +
  1289. +static void fserial_release (struct device *dev) {}
  1290. +
  1291. +static struct platform_device fserial_device = {
  1292. + .name = FS_SHORT_NAME,
  1293. + .id = -1,
  1294. + .dev = {
  1295. + .release = fserial_release,
  1296. + },
  1297. +};
  1298. +
  1299. +static ssize_t store_fserial_enable(struct device *dev, struct device_attribute *attr,
  1300. + const char *buf, size_t count)
  1301. +{
  1302. + unsigned long ul;
  1303. + if ((buf[0] != '0' && buf[0] != '1') && buf[1] != '\n')
  1304. + {
  1305. + printk(KERN_WARNING "Can't enable/disable fserial %s\n", buf);
  1306. + return -EINVAL;
  1307. + }
  1308. + ul = simple_strtoul(buf, NULL, 10);
  1309. + usb_function_enable(FS_SHORT_NAME, ul);
  1310. + return count;
  1311. +}
  1312. +
  1313. +static ssize_t show_fserial_enable(struct device *dev, struct device_attribute *attr,
  1314. + char *buf)
  1315. +{
  1316. + int rc;
  1317. + rc = sprintf(buf, "%d", return_usb_function_enabled(FS_SHORT_NAME));
  1318. + return rc;
  1319. +
  1320. +}
  1321. +static DEVICE_ATTR(fserial_enable, 0644, show_fserial_enable, store_fserial_enable);
  1322. +
  1323. +
  1324. +/*
  1325. +* fs_module_init
  1326. +*
  1327. +* Register as a USB gadget driver and a tty driver.
  1328. +*/
  1329. +static int __init fs_module_init(void)
  1330. +{
  1331. + int i;
  1332. + int retval;
  1333. + retval = usb_function_register(&usb_func_userial);
  1334. + if (retval) {
  1335. + printk(KERN_ERR "fs_module_init: cannot register function driver, ret=%d\n", retval);
  1336. + return retval;
  1337. + }
  1338. +
  1339. + fs_tty_driver = alloc_tty_driver(FS_NUM_PORTS);
  1340. + if (!fs_tty_driver)
  1341. + return -ENOMEM;
  1342. + fs_tty_driver->owner = THIS_MODULE;
  1343. + fs_tty_driver->driver_name = FS_SHORT_NAME;
  1344. + fs_tty_driver->name = "ttyfs";
  1345. + fs_tty_driver->major = FS_MAJOR;
  1346. + fs_tty_driver->minor_start = FS_MINOR_START;
  1347. + fs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
  1348. + fs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
  1349. + fs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
  1350. + fs_tty_driver->init_termios = tty_std_termios;
  1351. + fs_tty_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
  1352. +#ifdef CONFIG_BUILD_CIQ
  1353. + fs_tty_driver->init_termios.c_lflag = 0; // Disable ALL for CIQ CADeT
  1354. + fs_tty_driver->init_termios.c_iflag = 0; // Disable ALL for CIQ CADeT
  1355. + fs_tty_driver->init_termios.c_oflag = 0; // Disable ALL for CIQ CADeT
  1356. +#endif
  1357. +
  1358. + tty_set_operations(fs_tty_driver, &fs_tty_ops);
  1359. +
  1360. + for (i=0; i < FS_NUM_PORTS; i++)
  1361. + mutex_init(&fs_open_close_lock[i]);
  1362. +
  1363. + retval = tty_register_driver(fs_tty_driver);
  1364. + if (retval) {
  1365. + put_tty_driver(fs_tty_driver);
  1366. + printk(KERN_ERR "fs_module_init: cannot register tty driver, ret=%d\n", retval);
  1367. + return retval;
  1368. + }
  1369. +
  1370. + retval = platform_driver_register (&fserial_driver);
  1371. + if (retval < 0)
  1372. + return retval;
  1373. + retval = platform_device_register (&fserial_device);
  1374. + if (retval < 0)
  1375. + goto err_register_device;
  1376. +
  1377. + return 0;
  1378. +
  1379. +err_register_device:
  1380. + platform_driver_unregister(&fserial_driver);
  1381. + return retval;
  1382. +
  1383. +}
  1384. +
  1385. +/*
  1386. +* fs_module_exit
  1387. +*
  1388. +* Unregister as a tty driver.
  1389. +*/
  1390. +static void __exit fs_module_exit(void)
  1391. +{
  1392. + tty_unregister_driver(fs_tty_driver);
  1393. + put_tty_driver(fs_tty_driver);
  1394. +}
  1395. +
  1396. +/* TTY Driver */
  1397. +
  1398. +/*
  1399. + * fs_open
  1400. + */
  1401. +static int fs_open(struct tty_struct *tty, struct file *file)
  1402. +{
  1403. + int port_num;
  1404. + unsigned long flags;
  1405. + struct fs_port *port;
  1406. + struct userial_context *ctxt;
  1407. + struct fs_buf *buf;
  1408. + struct mutex *mtx;
  1409. + int ret;
  1410. +
  1411. + port_num = tty->index;
  1412. +
  1413. + fs_debug("fs_open: (%d,%p,%p)\n", port_num, tty, file);
  1414. +
  1415. + if (port_num < 0 || port_num >= FS_NUM_PORTS) {
  1416. + printk(KERN_ERR "fs_open: (%d,%p,%p) invalid port number\n",
  1417. + port_num, tty, file);
  1418. + return -ENODEV;
  1419. + }
  1420. +
  1421. + ctxt = &_context;
  1422. +
  1423. + if (ctxt == NULL) {
  1424. + printk(KERN_ERR "fs_open: (%d,%p,%p) NULL device pointer\n",
  1425. + port_num, tty, file);
  1426. + return -ENODEV;
  1427. + }
  1428. +
  1429. + mtx = &fs_open_close_lock[port_num];
  1430. + if (mutex_lock_interruptible(mtx)) {
  1431. + printk(KERN_ERR
  1432. + "fs_open: (%d,%p,%p) interrupted waiting for mutex\n",
  1433. + port_num, tty, file);
  1434. + return -ERESTARTSYS;
  1435. + }
  1436. +
  1437. + spin_lock_irqsave(&ctxt->dev_lock, flags);
  1438. +
  1439. + /*if (ctxt->dev_config == FS_NO_CONFIG_ID) {
  1440. + printk(KERN_ERR
  1441. + "fs_open: (%d,%p,%p) device is not connected\n",
  1442. + port_num, tty, file);
  1443. + ret = -ENODEV;
  1444. + goto exit_unlock_dev;
  1445. + }*/
  1446. +
  1447. + port = ctxt->dev_port[port_num];
  1448. +
  1449. + if (port == NULL) {
  1450. + printk(KERN_ERR "fs_open: (%d,%p,%p) NULL port pointer\n",
  1451. + port_num, tty, file);
  1452. + ret = -ENODEV;
  1453. + goto exit_unlock_dev;
  1454. + }
  1455. +
  1456. + spin_lock(&port->port_lock);
  1457. + spin_unlock(&ctxt->dev_lock);
  1458. +
  1459. + if (port->port_dev == NULL) {
  1460. + printk(KERN_ERR "fs_open: (%d,%p,%p) port disconnected (1)\n",
  1461. + port_num, tty, file);
  1462. + ret = -EIO;
  1463. + goto exit_unlock_port;
  1464. + }
  1465. +
  1466. + if (port->port_open_count > 0) {
  1467. + ++port->port_open_count;
  1468. + fs_debug("fs_open: (%d,%p,%p) already open\n",
  1469. + port_num, tty, file);
  1470. + ret = 0;
  1471. + goto exit_unlock_port;
  1472. + }
  1473. +
  1474. + tty->driver_data = NULL;
  1475. +
  1476. + /* mark port as in use, we can drop port lock and sleep if necessary */
  1477. + port->port_in_use = 1;
  1478. +
  1479. + /* allocate write buffer on first open */
  1480. + if (port->port_write_buf == NULL) {
  1481. + spin_unlock_irqrestore(&port->port_lock, flags);
  1482. + buf = fs_buf_alloc(write_buf_size, GFP_KERNEL);
  1483. + spin_lock_irqsave(&port->port_lock, flags);
  1484. +
  1485. + /* might have been disconnected while asleep, check */
  1486. + if (port->port_dev == NULL) {
  1487. + printk(KERN_ERR
  1488. + "fs_open: (%d,%p,%p) port disconnected (2)\n",
  1489. + port_num, tty, file);
  1490. + port->port_in_use = 0;
  1491. + ret = -EIO;
  1492. + goto exit_unlock_port;
  1493. + }
  1494. +
  1495. + if ((port->port_write_buf=buf) == NULL) {
  1496. + printk(KERN_ERR "fs_open: (%d,%p,%p) cannot allocate port write buffer\n",
  1497. + port_num, tty, file);
  1498. + port->port_in_use = 0;
  1499. + ret = -ENOMEM;
  1500. + goto exit_unlock_port;
  1501. + }
  1502. +
  1503. + }
  1504. +
  1505. + /* wait for carrier detect (not implemented) */
  1506. +
  1507. + /* might have been disconnected while asleep, check */
  1508. + if (port->port_dev == NULL) {
  1509. + printk(KERN_ERR "fs_open: (%d,%p,%p) port disconnected (3)\n",
  1510. + port_num, tty, file);
  1511. + port->port_in_use = 0;
  1512. + ret = -EIO;
  1513. + goto exit_unlock_port;
  1514. + }
  1515. +
  1516. + tty->driver_data = port;
  1517. + port->port_tty = tty;
  1518. + port->port_open_count = 1;
  1519. + port->port_in_use = 0;
  1520. +
  1521. + fs_debug("fs_open: (%d,%p,%p) completed\n", port_num, tty, file);
  1522. +
  1523. + ret = 0;
  1524. +
  1525. +exit_unlock_port:
  1526. + spin_unlock_irqrestore(&port->port_lock, flags);
  1527. + mutex_unlock(mtx);
  1528. + return ret;
  1529. +
  1530. +exit_unlock_dev:
  1531. + spin_unlock_irqrestore(&ctxt->dev_lock, flags);
  1532. + mutex_unlock(mtx);
  1533. + return ret;
  1534. +
  1535. +}
  1536. +
  1537. +/*
  1538. + * fs_close
  1539. + */
  1540. +
  1541. +#define FS_WRITE_FINISHED_EVENT_SAFELY(p) \
  1542. +({ \
  1543. + int cond; \
  1544. + \
  1545. + spin_lock_irq(&(p)->port_lock); \
  1546. + cond = !(p)->port_dev || !fs_buf_data_avail((p)->port_write_buf); \
  1547. + spin_unlock_irq(&(p)->port_lock); \
  1548. + cond; \
  1549. +})
  1550. +
  1551. +static void fs_close(struct tty_struct *tty, struct file *file)
  1552. +{
  1553. + struct fs_port *port = tty->driver_data;
  1554. + struct mutex *mtx;
  1555. +
  1556. + if (port == NULL) {
  1557. + printk(KERN_ERR "fs_close: NULL port pointer\n");
  1558. + return;
  1559. + }
  1560. +
  1561. + fs_debug("fs_close: (%d,%p,%p)\n", port->port_num, tty, file);
  1562. +
  1563. + mtx = &fs_open_close_lock[port->port_num];
  1564. + mutex_lock(mtx);
  1565. +
  1566. + spin_lock_irq(&port->port_lock);
  1567. +
  1568. + if (port->port_open_count == 0) {
  1569. + printk(KERN_ERR
  1570. + "fs_close: (%d,%p,%p) port is already closed\n",
  1571. + port->port_num, tty, file);
  1572. + goto exit;
  1573. + }
  1574. +
  1575. + if (port->port_open_count > 1) {
  1576. + --port->port_open_count;
  1577. + goto exit;
  1578. + }
  1579. +
  1580. + /* free disconnected port on final close */
  1581. + if (port->port_dev == NULL) {
  1582. + kfree(port);
  1583. + goto exit;
  1584. + }
  1585. +
  1586. + /* mark port as closed but in use, we can drop port lock */
  1587. + /* and sleep if necessary */
  1588. + port->port_in_use = 1;
  1589. + port->port_open_count = 0;
  1590. +
  1591. + /* wait for write buffer to drain, or */
  1592. + /* at most FS_CLOSE_TIMEOUT seconds */
  1593. + if (fs_buf_data_avail(port->port_write_buf) > 0) {
  1594. + spin_unlock_irq(&port->port_lock);
  1595. + wait_event_interruptible_timeout(port->port_write_wait,
  1596. + FS_WRITE_FINISHED_EVENT_SAFELY(port),
  1597. + FS_CLOSE_TIMEOUT * HZ);
  1598. + spin_lock_irq(&port->port_lock);
  1599. + }
  1600. +
  1601. + /* free disconnected port on final close */
  1602. + /* (might have happened during the above sleep) */
  1603. + if (port->port_dev == NULL) {
  1604. + kfree(port);
  1605. + goto exit;
  1606. + }
  1607. +
  1608. + fs_buf_clear(port->port_write_buf);
  1609. +
  1610. + tty->driver_data = NULL;
  1611. + port->port_tty = NULL;
  1612. + port->port_in_use = 0;
  1613. +
  1614. + fs_debug("fs_close: (%d,%p,%p) completed\n",
  1615. + port->port_num, tty, file);
  1616. +
  1617. +exit:
  1618. + spin_unlock_irq(&port->port_lock);
  1619. + mutex_unlock(mtx);
  1620. +}
  1621. +
  1622. +/*
  1623. + * fs_write
  1624. + */
  1625. +static int fs_write(struct tty_struct *tty, const unsigned char *buf, int count)
  1626. +{
  1627. + unsigned long flags;
  1628. + struct fs_port *port = tty->driver_data;
  1629. + int ret;
  1630. +
  1631. + if (port == NULL) {
  1632. + printk(KERN_ERR "fs_write: NULL port pointer\n");
  1633. + return -EIO;
  1634. + }
  1635. +
  1636. + fs_debug("fs_write: (%d,%p) writing %d bytes\n", port->port_num, tty,
  1637. + count);
  1638. +
  1639. + if (count == 0)
  1640. + return 0;
  1641. +
  1642. + spin_lock_irqsave(&port->port_lock, flags);
  1643. +
  1644. + if (port->port_dev == NULL) {
  1645. + printk(KERN_ERR "fs_write: (%d,%p) port is not connected\n",
  1646. + port->port_num, tty);
  1647. + ret = -EIO;
  1648. + goto exit;
  1649. + }
  1650. +
  1651. + if (port->port_open_count == 0) {
  1652. + printk(KERN_ERR "fs_write: (%d,%p) port is closed\n",
  1653. + port->port_num, tty);
  1654. + ret = -EBADF;
  1655. + goto exit;
  1656. + }
  1657. +
  1658. + count = fs_buf_put(port->port_write_buf, buf, count);
  1659. +
  1660. + spin_unlock_irqrestore(&port->port_lock, flags);
  1661. +
  1662. + fs_send();
  1663. +
  1664. + fs_debug("fs_write: (%d,%p) wrote %d bytes\n", port->port_num, tty,
  1665. + count);
  1666. +
  1667. + return count;
  1668. +
  1669. +exit:
  1670. + spin_unlock_irqrestore(&port->port_lock, flags);
  1671. + return ret;
  1672. +}
  1673. +
  1674. +/*
  1675. + * fs_put_char
  1676. + */
  1677. +static int fs_put_char(struct tty_struct *tty, unsigned char ch)
  1678. +{
  1679. + unsigned long flags;
  1680. + int retval = 1;
  1681. + struct fs_port *port = tty->driver_data;
  1682. +
  1683. + if (port == NULL) {
  1684. + printk(KERN_ERR "fs_put_char: NULL port pointer\n");
  1685. + return 0;
  1686. + }
  1687. +
  1688. + fs_debug("fs_put_char: (%d,%p) char=0x%x, called from %p\n",
  1689. + port->port_num, tty, ch, __builtin_return_address(0));
  1690. +
  1691. + spin_lock_irqsave(&port->port_lock, flags);
  1692. +
  1693. + if (port->port_dev == NULL) {
  1694. + printk(KERN_ERR "fs_put_char: (%d,%p) port is not connected\n",
  1695. + port->port_num, tty);
  1696. + retval = 0;
  1697. + goto exit;
  1698. + }
  1699. +
  1700. + if (port->port_open_count == 0) {
  1701. + printk(KERN_ERR "fs_put_char: (%d,%p) port is closed\n",
  1702. + port->port_num, tty);
  1703. + retval = 0;
  1704. + goto exit;
  1705. + }
  1706. +
  1707. + fs_buf_put(port->port_write_buf, &ch, 1);
  1708. +
  1709. +exit:
  1710. + spin_unlock_irqrestore(&port->port_lock, flags);
  1711. + return retval;
  1712. +}
  1713. +
  1714. +/*
  1715. + * fs_flush_chars
  1716. + */
  1717. +static void fs_flush_chars(struct tty_struct *tty)
  1718. +{
  1719. + unsigned long flags;
  1720. + struct fs_port *port = tty->driver_data;
  1721. +
  1722. + if (port == NULL) {
  1723. + printk(KERN_ERR "fs_flush_chars: NULL port pointer\n");
  1724. + return;
  1725. + }
  1726. +
  1727. + fs_debug("fs_flush_chars: (%d,%p)\n", port->port_num, tty);
  1728. +
  1729. + spin_lock_irqsave(&port->port_lock, flags);
  1730. +
  1731. + if (port->port_dev == NULL) {
  1732. + printk(KERN_ERR
  1733. + "fs_flush_chars: (%d,%p) port is not connected\n",
  1734. + port->port_num, tty);
  1735. + goto exit;
  1736. + }
  1737. +
  1738. + if (port->port_open_count == 0) {
  1739. + printk(KERN_ERR "fs_flush_chars: (%d,%p) port is closed\n",
  1740. + port->port_num, tty);
  1741. + goto exit;
  1742. + }
  1743. +
  1744. + spin_unlock_irqrestore(&port->port_lock, flags);
  1745. +
  1746. + fs_send();
  1747. +
  1748. + return;
  1749. +
  1750. +exit:
  1751. + spin_unlock_irqrestore(&port->port_lock, flags);
  1752. +}
  1753. +
  1754. +/*
  1755. + * fs_write_room
  1756. + */
  1757. +static int fs_write_room(struct tty_struct *tty)
  1758. +{
  1759. +
  1760. + int room = 0;
  1761. + unsigned long flags;
  1762. + struct fs_port *port = tty->driver_data;
  1763. +
  1764. +
  1765. + if (port == NULL)
  1766. + return 0;
  1767. +
  1768. + spin_lock_irqsave(&port->port_lock, flags);
  1769. +
  1770. + if (port->port_dev != NULL && port->port_open_count > 0
  1771. + && port->port_write_buf != NULL)
  1772. + room = fs_buf_space_avail(port->port_write_buf);
  1773. +
  1774. + spin_unlock_irqrestore(&port->port_lock, flags);
  1775. +
  1776. + fs_debug("fs_write_room: (%d,%p) room=%d\n",
  1777. + port->port_num, tty, room);
  1778. +
  1779. + return room;
  1780. +}
  1781. +
  1782. +/*
  1783. + * fs_chars_in_buffer
  1784. + */
  1785. +static int fs_chars_in_buffer(struct tty_struct *tty)
  1786. +{
  1787. + int chars = 0;
  1788. + unsigned long flags;
  1789. + struct fs_port *port = tty->driver_data;
  1790. +
  1791. + if (port == NULL)
  1792. + return 0;
  1793. +
  1794. + spin_lock_irqsave(&port->port_lock, flags);
  1795. +
  1796. + if (port->port_dev != NULL && port->port_open_count > 0
  1797. + && port->port_write_buf != NULL)
  1798. + chars = fs_buf_data_avail(port->port_write_buf);
  1799. +
  1800. + spin_unlock_irqrestore(&port->port_lock, flags);
  1801. +
  1802. + fs_debug("fs_chars_in_buffer: (%d,%p) chars=%d\n",
  1803. + port->port_num, tty, chars);
  1804. +
  1805. + return chars;
  1806. +}
  1807. +
  1808. +/*
  1809. + * fs_throttle
  1810. + */
  1811. +static void fs_throttle(struct tty_struct *tty)
  1812. +{
  1813. +}
  1814. +
  1815. +/*
  1816. + * fs_unthrottle
  1817. + */
  1818. +static void fs_unthrottle(struct tty_struct *tty)
  1819. +{
  1820. +}
  1821. +
  1822. +/*
  1823. + * fs_break
  1824. + */
  1825. +static int fs_break(struct tty_struct *tty, int break_state)
  1826. +{
  1827. + return 0;
  1828. +}
  1829. +
  1830. +/*
  1831. + * fs_ioctl
  1832. + */
  1833. +static int fs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
  1834. +{
  1835. + struct fs_port *port = tty->driver_data;
  1836. +
  1837. + if (port == NULL) {
  1838. + printk(KERN_ERR "fs_ioctl: NULL port pointer\n");
  1839. + return -EIO;
  1840. + }
  1841. +
  1842. + fs_debug("fs_ioctl: (%d,%p,%p) cmd=0x%4.4x, arg=%lu\n",
  1843. + port->port_num, tty, file, cmd, arg);
  1844. +
  1845. + /* handle ioctls */
  1846. +
  1847. + /* could not handle ioctl */
  1848. + return -ENOIOCTLCMD;
  1849. +}
  1850. +
  1851. +/*
  1852. + * fs_set_termios
  1853. + */
  1854. +static void fs_set_termios(struct tty_struct *tty, struct ktermios *old)
  1855. +{
  1856. +}
  1857. +
  1858. +/*
  1859. +* fs_send
  1860. +*
  1861. +* This function finds available write requests, calls
  1862. +* fs_send_packet to fill these packets with data, and
  1863. +* continues until either there are no more write requests
  1864. +* available or no more data to send. This function is
  1865. +* run whenever data arrives or write requests are available.
  1866. +*/
  1867. +static int fs_send(void)
  1868. +{
  1869. + int ret,len;
  1870. + unsigned long flags;
  1871. + struct usb_endpoint *ep;
  1872. + struct usb_request *req;
  1873. + struct userial_context *ctxt = &_context;
  1874. +
  1875. + if (ctxt == NULL) {
  1876. + printk(KERN_ERR "fs_send: NULL device pointer\n");
  1877. + return -ENODEV;
  1878. + }
  1879. +
  1880. + spin_lock_irqsave(&ctxt->dev_lock, flags);
  1881. +
  1882. + ep = ctxt->dev_in_ep;
  1883. +
  1884. + while(!list_empty(&ctxt->dev_write_list)) {
  1885. +
  1886. + req = list_first_entry(&ctxt->dev_write_list,
  1887. + struct usb_request, list);
  1888. + len = fs_send_packet(ctxt, req->buf, MAX_PKT);
  1889. +
  1890. + if (len > 0) {
  1891. + fs_debug_level(3, "fs_send: len=%d, 0x%2.2x "
  1892. + "0x%2.2x 0x%2.2x ...\n", len,
  1893. + *((unsigned char *)req->buf),
  1894. + *((unsigned char *)req->buf+1),
  1895. + *((unsigned char *)req->buf+2));
  1896. + list_del(&req->list);
  1897. + req->length = len;
  1898. + spin_unlock_irqrestore(&ctxt->dev_lock, flags);
  1899. + if ((ret=usb_ept_queue_xfer(ep, req))<0) {
  1900. + printk(KERN_ERR
  1901. + "fs_send: cannot queue read request, ret=%d\n",
  1902. + ret);
  1903. + spin_lock_irqsave(&ctxt->dev_lock, flags);
  1904. + break;
  1905. + }
  1906. + spin_lock_irqsave(&ctxt->dev_lock, flags);
  1907. + } else {
  1908. + break;
  1909. + }
  1910. +
  1911. + }
  1912. +
  1913. + spin_unlock_irqrestore(&ctxt->dev_lock, flags);
  1914. +
  1915. + return 0;
  1916. +}
  1917. +
  1918. +/*
  1919. + * fs_send_packet
  1920. + *
  1921. + * If there is data to send, a packet is built in the given
  1922. + * buffer and the size is returned. If there is no data to
  1923. + * send, 0 is returned. If there is any error a negative
  1924. + * error number is returned.
  1925. + *
  1926. + * Called during USB completion routine, on interrupt time.
  1927. + *
  1928. + * We assume that disconnect will not happen until all completion
  1929. + * routines have completed, so we can assume that the dev_port
  1930. + * array does not change during the lifetime of this function.
  1931. + */
  1932. +static int fs_send_packet(struct userial_context *ctxt, char *packet, unsigned int size)
  1933. +{
  1934. + unsigned int len;
  1935. + struct fs_port *port;
  1936. +
  1937. + /* TEMPORARY -- only port 0 is supported right now */
  1938. + port = ctxt->dev_port[0];
  1939. +
  1940. + if (port == NULL) {
  1941. + printk(KERN_ERR
  1942. + "fs_send_packet: port=%d, NULL port pointer\n",
  1943. + 0);
  1944. + return -EIO;
  1945. + }
  1946. +
  1947. + spin_lock(&port->port_lock);
  1948. +
  1949. + len = fs_buf_data_avail(port->port_write_buf);
  1950. + if (len < size)
  1951. + size = len;
  1952. +
  1953. + if (size == 0)
  1954. + goto exit;
  1955. +
  1956. + size = fs_buf_get(port->port_write_buf, packet, size);
  1957. +
  1958. + if (port->port_tty)
  1959. + wake_up_interruptible(&port->port_tty->write_wait);
  1960. +
  1961. +exit:
  1962. + spin_unlock(&port->port_lock);
  1963. + return size;
  1964. +}
  1965. +
  1966. +/*
  1967. + * fs_recv_packet
  1968. + *
  1969. + * Called for each USB packet received. Reads the packet
  1970. + * header and stuffs the data in the appropriate tty buffer.
  1971. + * Returns 0 if successful, or a negative error number.
  1972. + *
  1973. + * Called during USB completion routine, on interrupt time.
  1974. + *
  1975. + * We assume that disconnect will not happen until all completion
  1976. + * routines have completed, so we can assume that the dev_port
  1977. + * array does not change during the lifetime of this function.
  1978. + */
  1979. +static int fs_recv_packet(struct userial_context *ctxt, char *packet, unsigned int size)
  1980. +{
  1981. + unsigned int len;
  1982. + struct fs_port *port;
  1983. + int ret;
  1984. + struct tty_struct *tty;
  1985. +
  1986. + /* TEMPORARY -- only port 0 is supported right now */
  1987. + port = ctxt->dev_port[0];
  1988. +
  1989. + if (port == NULL) {
  1990. + printk(KERN_ERR "fs_recv_packet: port=%d, NULL port pointer\n",
  1991. + port->port_num);
  1992. + return -EIO;
  1993. + }
  1994. +
  1995. + spin_lock(&port->port_lock);
  1996. +
  1997. + if (port->port_open_count == 0) {
  1998. + printk(KERN_ERR "fs_recv_packet: port=%d, port is closed\n",
  1999. + port->port_num);
  2000. + ret = -EIO;
  2001. + goto exit;
  2002. + }
  2003. +
  2004. +
  2005. + tty = port->port_tty;
  2006. +
  2007. + if (tty == NULL) {
  2008. + printk(KERN_ERR "fs_recv_packet: port=%d, NULL tty pointer\n",
  2009. + port->port_num);
  2010. + ret = -EIO;
  2011. + goto exit;
  2012. + }
  2013. +
  2014. + if (port->port_tty->magic != TTY_MAGIC) {
  2015. + printk(KERN_ERR "fs_recv_packet: port=%d, bad tty magic\n",
  2016. + port->port_num);
  2017. + ret = -EIO;
  2018. + goto exit;
  2019. + }
  2020. +
  2021. + len = tty_buffer_request_room(tty, size);
  2022. + if (len > 0) {
  2023. + tty_insert_flip_string(tty, packet, len);
  2024. + tty_flip_buffer_push(port->port_tty);
  2025. + wake_up_interruptible(&port->port_tty->read_wait);
  2026. + }
  2027. + ret = 0;
  2028. +exit:
  2029. + spin_unlock(&port->port_lock);
  2030. + return ret;
  2031. +}
  2032. +
  2033. +/*
  2034. +* fs_read_complete
  2035. +*/
  2036. +static void fs_read_complete(struct usb_endpoint *ep, struct usb_request *req)
  2037. +{
  2038. + int ret;
  2039. + struct userial_context *ctxt = &_context;
  2040. + fs_debug_level(3, "fs_read complete data:%c %c %c.... len= %u\n", *((char *)req->buf),
  2041. + *((char *)req->buf+1),
  2042. + *((char *)req->buf+2),
  2043. + req->actual);
  2044. +
  2045. + if (ctxt == NULL) {
  2046. + printk(KERN_ERR "fs_read_complete: NULL device pointer\n");
  2047. + return;
  2048. + }
  2049. +
  2050. + switch(req->status) {
  2051. + case 0:
  2052. + /* normal completion */
  2053. + fs_recv_packet(ctxt, req->buf, req->actual);
  2054. +requeue:
  2055. + req->length = MAX_PKT;
  2056. + if ((ret=usb_ept_queue_xfer(ctxt->dev_out_ep, req))<0) {
  2057. + printk(KERN_ERR
  2058. + "fs_read_complete: cannot queue read request, ret=%d\n",
  2059. + ret);
  2060. + }
  2061. + break;
  2062. +
  2063. + case -ESHUTDOWN:
  2064. + /* disconnect */
  2065. + fs_debug("fs_read_complete: shutdown\n");
  2066. + //fs_free_req(ep, req);
  2067. + usb_ept_free_req(ep, req);
  2068. + break;
  2069. + case -ENODEV:
  2070. + {
  2071. + unsigned long flags;
  2072. + fs_debug_level(3, "fs_read_complete: nodev\n");
  2073. + spin_lock_irqsave(&ctxt->dev_lock, flags);
  2074. + list_add_tail(&req->list, &ctxt->dev_read_list);
  2075. + spin_unlock_irqrestore(&ctxt->dev_lock, flags);
  2076. + break;
  2077. + }
  2078. + default:
  2079. + /* unexpected */
  2080. + printk(KERN_ERR
  2081. + "fs_read_complete: unexpected status error, status=%d\n",
  2082. + req->status);
  2083. + goto requeue;
  2084. + break;
  2085. + }
  2086. +}
  2087. +
  2088. +/*
  2089. +* fs_write_complete
  2090. +*/
  2091. +static void fs_write_complete(struct usb_endpoint *ep, struct usb_request *req)
  2092. +{
  2093. + struct userial_context *ctxt = &_context;
  2094. + fs_debug_level(3, "fs_write_complete:%c %c %c len:%u\n", *((char *)req->buf),
  2095. + *((char *)req->buf+1),
  2096. + *((char *)req->buf+2),
  2097. + req->actual);
  2098. + if (ctxt == NULL) {
  2099. + printk(KERN_ERR "fs_write_complete: NULL device pointer\n");
  2100. + return;
  2101. + }
  2102. +
  2103. + switch(req->status) {
  2104. + case 0:
  2105. + /* normal completion */
  2106. +requeue:
  2107. + if (req == NULL) {
  2108. + printk(KERN_ERR
  2109. + "fs_write_complete: NULL request pointer\n");
  2110. + return;
  2111. + }
  2112. +
  2113. + spin_lock(&ctxt->dev_lock);
  2114. + list_add_tail(&req->list, &ctxt->dev_write_list);
  2115. + spin_unlock(&ctxt->dev_lock);
  2116. +
  2117. + fs_send();
  2118. +
  2119. + break;
  2120. +
  2121. + case -ESHUTDOWN:
  2122. + /* disconnect */
  2123. + fs_debug("fs_write_complete: shutdown\n");
  2124. + usb_ept_free_req(ep, req);
  2125. + break;
  2126. +
  2127. + default:
  2128. + printk(KERN_ERR
  2129. + "fs_write_complete: unexpected status error, status=%d\n",
  2130. + req->status);
  2131. + goto requeue;
  2132. + break;
  2133. + }
  2134. +}
  2135. +
  2136. +/* Function Driver */
  2137. +
  2138. +/*
  2139. + * fs_bind
  2140. + *
  2141. + * Called on module load. Allocates and initializes the device
  2142. + * structure and a control request.
  2143. + */
  2144. +static void fs_bind(struct usb_endpoint **ept, void *_ctxt)
  2145. +{
  2146. +
  2147. + struct userial_context *ctxt = _ctxt;
  2148. + struct usb_endpoint *ep;
  2149. + struct usb_request *req;
  2150. + int i, ret;
  2151. +
  2152. + ctxt->registered = 0;
  2153. + ctxt->dev_out_ep = ept[0];
  2154. + ctxt->dev_in_ep = ept[1];
  2155. + spin_lock_init(&ctxt->dev_lock);
  2156. + INIT_LIST_HEAD(&ctxt->dev_write_list);
  2157. + INIT_LIST_HEAD(&ctxt->dev_read_list);
  2158. + if (fs_alloc_ports(ctxt, GFP_KERNEL) != 0) {
  2159. + printk(KERN_ERR "fs_bind: cannot allocate ports\n");
  2160. + fs_unbind(ctxt);
  2161. + goto fail;
  2162. + }
  2163. +
  2164. + ep = ctxt->dev_out_ep;
  2165. + for (i=0; i<read_q_size ; i++) {
  2166. + if ((req=usb_ept_alloc_req(ep, 4096))) {
  2167. + req->complete = fs_read_complete;
  2168. + req->context = ctxt;
  2169. + list_add_tail(&req->list, &ctxt->dev_read_list);
  2170. + } else {
  2171. + printk(KERN_ERR "fs_bind: cannot allocate read requests\n");
  2172. + goto fail;
  2173. + }
  2174. + }
  2175. +
  2176. + /* allocate write requests, and put on free list */
  2177. + ep = ctxt->dev_in_ep;
  2178. + for (i=0; i<write_q_size; i++) {
  2179. + if ((req=usb_ept_alloc_req(ep, 4096))) {
  2180. + req->complete = fs_write_complete;
  2181. + req->context = ctxt;
  2182. + list_add_tail(&req->list, &ctxt->dev_write_list);
  2183. + } else {
  2184. + printk(KERN_ERR "fs_bind: cannot allocate write requests\n");
  2185. + goto fail;
  2186. + }
  2187. + }
  2188. +
  2189. + fserial_dev.release = fserial_dev_release;
  2190. + fserial_dev.parent = &ctxt->pdev->dev;
  2191. + strcpy(fserial_dev.bus_id, "interface");
  2192. +
  2193. + ret = device_register(&fserial_dev);
  2194. + if (ret != 0) {
  2195. + printk(KERN_WARNING "fserial_dev failed to register device: %d\n", ret);
  2196. + goto fail;
  2197. + }
  2198. + ret = device_create_file(&fserial_dev, &dev_attr_fserial_enable);
  2199. + if (ret != 0) {
  2200. + printk(KERN_WARNING "fserial_dev device_create_file failed: %d\n", ret);
  2201. + device_unregister(&fserial_dev);
  2202. + goto fail;
  2203. + }
  2204. + ctxt->registered = 1;
  2205. +
  2206. + return;
  2207. +
  2208. +fail:
  2209. + printk(KERN_ERR "fs_bind() could not allocate requests\n");
  2210. +}
  2211. +
  2212. +/*
  2213. + * fs_unbind
  2214. + *
  2215. + * Called on module unload. Frees the control request and device
  2216. + * structure.
  2217. + */
  2218. +static void fs_unbind(void *_ctxt)
  2219. +{
  2220. +
  2221. + struct userial_context *ctxt = _ctxt;
  2222. + /* read/write requests already freed, only control request remains */
  2223. + if (ctxt != NULL){
  2224. +
  2225. + fs_free_ports(ctxt);
  2226. + /* if (dev->dev_in_ep)
  2227. + usb_ep_disable(dev->dev_in_ep);
  2228. + if (dev->dev_out_ep)
  2229. + usb_ep_disable(dev->dev_out_ep);
  2230. + */
  2231. + if (ctxt->registered) {
  2232. + device_remove_file(&fserial_dev, &dev_attr_fserial_enable);
  2233. + device_unregister(&fserial_dev);
  2234. + ctxt->registered = 0;
  2235. + }
  2236. + }
  2237. +}
  2238. +
  2239. +
  2240. +
  2241. +
  2242. +
  2243. +/*
  2244. + * fs_setup
  2245. + *
  2246. + * Implements all the control endpoint functionality that's not
  2247. + * handled in hardware or the hardware driver.
  2248. + *
  2249. + * Returns the size of the data sent to the host, or a negative
  2250. + * error number.
  2251. + */
  2252. +static int fs_setup(struct usb_ctrlrequest *ctrl, void *buf, int len, void *_ctxt)
  2253. +{
  2254. + int ret = -EOPNOTSUPP;
  2255. + struct userial_context * ctxt = _ctxt;
  2256. + struct fs_port *port = ctxt->dev_port[0];
  2257. + printk(KERN_ERR "fs_setup\n");
  2258. +
  2259. + if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) {
  2260. + if (ctrl->wIndex != 2)
  2261. + return -1;
  2262. + switch (ctrl->bRequest) {
  2263. + case USB_CDC_REQ_SET_LINE_CODING:
  2264. + //if (ctrl->wLength != sizeof(struct usb_cdc_line_coding))
  2265. + // break;
  2266. + //ret = ctrl->wLength;
  2267. + //req->complete = fs_setup_complete_set_line_coding;//???????????????
  2268. + printk(KERN_WARNING "fs_setup: set_line_coding unuspported\n");
  2269. + break;
  2270. +
  2271. + case USB_CDC_REQ_GET_LINE_CODING:
  2272. + ret = min(ctrl->wLength, (u16)sizeof(struct usb_cdc_line_coding));
  2273. + if (port) {
  2274. + spin_lock(&port->port_lock);
  2275. + memcpy(buf, &port->port_line_coding, ret);
  2276. + spin_unlock(&port->port_lock);
  2277. + }
  2278. + break;
  2279. +
  2280. + case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
  2281. + if (ctrl->wLength != 0)
  2282. + break;
  2283. + ret = 0;
  2284. + if (port) {
  2285. + /* REVISIT: we currently just remember this data.
  2286. + * If we change that, update whatever hardware needs
  2287. + * updating.
  2288. + */
  2289. + spin_lock(&port->port_lock);
  2290. + port->port_handshake_bits = ctrl->wValue;
  2291. + spin_unlock(&port->port_lock);
  2292. + }
  2293. + break;
  2294. +
  2295. + default:
  2296. + printk(KERN_ERR "fs_setup: unknown class request, "
  2297. + "type=%02x, request=%02x, value=%04x, "
  2298. + "index=%04x, length=%d\n",
  2299. + ctrl->bRequestType, ctrl->bRequest,
  2300. + ctrl->wValue, ctrl->wIndex, ctrl->wLength);
  2301. + break;
  2302. + }
  2303. + }
  2304. + else
  2305. + printk(KERN_ERR "fs_setup: unknown request, "
  2306. + "type=%02x, request=%02x, value=%04x, "
  2307. + "index=%04x, length=%d\n",
  2308. + ctrl->bRequestType, ctrl->bRequest,
  2309. + ctrl->wValue, ctrl->wIndex, ctrl->wLength);
  2310. + return ret;
  2311. +
  2312. +}
  2313. +
  2314. +#if 0
  2315. +static void fs_setup_complete_set_line_coding(struct usb_endpoint *ep,
  2316. + struct usb_request *req)
  2317. +{
  2318. + struct fs_port *port = _context.dev_port[0]; /* ACM only has one port */
  2319. +
  2320. + switch (req->status) {
  2321. + case 0:
  2322. + /* normal completion */
  2323. + if (req->actual != sizeof(port->port_line_coding))
  2324. +// usb_ep_set_halt(ep); ???????????????????
  2325. +// ep0_stall();
  2326. + printk(KERN_ERR "set_complete_set_line_coding error");
  2327. + else if (port) {
  2328. + struct usb_cdc_line_coding *value = req->buf;
  2329. +
  2330. + /* REVISIT: we currently just remember this data.
  2331. + * If we change that, (a) validate it first, then
  2332. + * (b) update whatever hardware needs updating.
  2333. + */
  2334. + spin_lock(&port->port_lock);
  2335. + port->port_line_coding = *value;
  2336. + spin_unlock(&port->port_lock);
  2337. + }
  2338. + break;
  2339. +
  2340. + case -ESHUTDOWN:
  2341. + /* disconnect */
  2342. + usb_ept_free_req(ep, req);
  2343. + break;
  2344. +
  2345. + default:
  2346. + /* unexpected */
  2347. + break;
  2348. + }
  2349. + return;
  2350. +}
  2351. +#endif
  2352. +
  2353. +
  2354. +/*
  2355. + * fs_disconnect
  2356. + *
  2357. + * Called when the device is disconnected. Frees the closed
  2358. + * ports and disconnects open ports. Open ports will be freed
  2359. + * on close. Then reallocates the ports for the next connection.
  2360. + */
  2361. +
  2362. +
  2363. +//move disconnect function to fs_close??????
  2364. +static void fs_disconnect(struct userial_context *ctxt)
  2365. +{
  2366. + unsigned long flags;
  2367. +
  2368. + spin_lock_irqsave(&ctxt->dev_lock, flags);
  2369. +
  2370. + //fs_reset_config(ctxt);
  2371. +
  2372. + /* free closed ports and disconnect open ports */
  2373. + /* (open ports will be freed when closed) */
  2374. + fs_free_ports(ctxt);
  2375. +
  2376. + /* re-allocate ports for the next connection */
  2377. + if (fs_alloc_ports(ctxt, GFP_ATOMIC) != 0)
  2378. + printk(KERN_ERR "fs_disconnect: cannot re-allocate ports\n");
  2379. +
  2380. + spin_unlock_irqrestore(&ctxt->dev_lock, flags);
  2381. +
  2382. + //printk(KERN_INFO "fs_disconnect: %s disconnected\n", FS_LONG_NAME);
  2383. +}
  2384. +
  2385. +
  2386. +static void fs_configure(int configured, void *context)
  2387. +{
  2388. + struct userial_context * ctxt = context;
  2389. + struct usb_endpoint *ep;
  2390. + struct usb_request *req, *temp;
  2391. + int i = 0;
  2392. + fs_debug_level(3,"fs_configure:configure %d\n", configured);
  2393. + if (configured){
  2394. + ep = ctxt->dev_out_ep;
  2395. + list_for_each_entry_safe(req, temp, &ctxt->dev_read_list, list){
  2396. + list_del(&req->list);
  2397. + req->length = MAX_PKT;
  2398. + i++;
  2399. + if (usb_ept_queue_xfer(ep, req)<0) {
  2400. + printk(KERN_ERR "fs_configure: cannot queue read request\n");
  2401. + }
  2402. + }
  2403. + printk(KERN_ERR "fs_configure queue %d request in read list\n", i);
  2404. + }
  2405. + else{
  2406. + fs_disconnect(ctxt);
  2407. + }
  2408. +
  2409. +}
  2410. +
  2411. +/*
  2412. + * fs_reset_config
  2413. + *
  2414. + * Mark the device as not configured, disable all endpoints,
  2415. + * which forces completion of pending I/O and frees queued
  2416. + * requests, and free the remaining write requests on the
  2417. + * free list.
  2418. + *
  2419. + * The device lock must be held when calling this function.
  2420. + */
  2421. +#if 0
  2422. +static void fs_reset_config(struct userial_context* dev)
  2423. +{
  2424. + struct usb_request *req;
  2425. + printk(KERN_ERR "in the fs_reset_config\n");
  2426. + if (dev == NULL) {
  2427. + printk(KERN_ERR "fs_reset_config: NULL device pointer\n");
  2428. + return;
  2429. + }
  2430. +
  2431. + /* free write requests on the free list */
  2432. + while(!list_empty(&dev->dev_write_list)) {
  2433. + req = list_entry(dev->dev_write_list.next, struct usb_request, list);
  2434. + list_del(&req->list);
  2435. + usb_ept_free_req(dev->dev_in_ep, req);
  2436. + }
  2437. +
  2438. + /* disable endpoints, forcing completion of pending i/o; */
  2439. + /* completion handlers free their requests in this case */
  2440. + //if (dev->dev_in_ep) {
  2441. + // usb_ep_disable(dev->dev_in_ep);
  2442. + // dev->dev_in_ep = NULL;
  2443. + //}
  2444. + //if (dev->dev_out_ep) {
  2445. + // usb_ep_disable(dev->dev_out_ep);
  2446. + // dev->dev_out_ep = NULL;
  2447. + //}
  2448. +}
  2449. +#endif
  2450. +
  2451. +/*
  2452. + * fs_alloc_ports
  2453. + *
  2454. + * Allocate all ports and set the fs_dev struct to point to them.
  2455. + * Return 0 if successful, or a negative error number.
  2456. + *
  2457. + * The device lock is normally held when calling this function.
  2458. + */
  2459. +static int fs_alloc_ports(struct userial_context *ctxt, gfp_t kmalloc_flags)
  2460. +{
  2461. + int i;
  2462. + struct fs_port *port;
  2463. +
  2464. + if (ctxt == NULL)
  2465. + return -EIO;
  2466. +
  2467. + for (i=0; i<FS_NUM_PORTS; i++) {
  2468. + if ((port=kzalloc(sizeof(struct fs_port), kmalloc_flags)) == NULL)
  2469. + return -ENOMEM;
  2470. +
  2471. + port->port_dev = ctxt;
  2472. + port->port_num = i;
  2473. + port->port_line_coding.dwDTERate = cpu_to_le32(FS_DEFAULT_DTE_RATE);
  2474. + port->port_line_coding.bCharFormat = FS_DEFAULT_CHAR_FORMAT;
  2475. + port->port_line_coding.bParityType = FS_DEFAULT_PARITY;
  2476. + port->port_line_coding.bDataBits = FS_DEFAULT_DATA_BITS;
  2477. + spin_lock_init(&port->port_lock);
  2478. + init_waitqueue_head(&port->port_write_wait);
  2479. +
  2480. + ctxt->dev_port[i] = port;
  2481. + }
  2482. +
  2483. + return 0;
  2484. +}
  2485. +
  2486. +/*
  2487. + * fs_free_ports
  2488. + *
  2489. + * Free all closed ports. Open ports are disconnected by
  2490. + * freeing their write buffers, setting their device pointers
  2491. + * and the pointers to them in the device to NULL. These
  2492. + * ports will be freed when closed.
  2493. + *
  2494. + * The device lock is normally held when calling this function.
  2495. +*/
  2496. +
  2497. + static void fs_free_ports(struct userial_context * ctxt)
  2498. +{
  2499. + int i;
  2500. + unsigned long flags;
  2501. + struct fs_port *port;
  2502. +
  2503. + if (ctxt == NULL)
  2504. + return;
  2505. +
  2506. + for (i=0; i<FS_NUM_PORTS; i++) {
  2507. + if ((port=ctxt->dev_port[i]) != NULL) {
  2508. + ctxt->dev_port[i] = NULL;
  2509. +
  2510. + spin_lock_irqsave(&port->port_lock, flags);
  2511. +
  2512. + if (port->port_write_buf != NULL) {
  2513. + fs_buf_free(port->port_write_buf);
  2514. + port->port_write_buf = NULL;
  2515. + }
  2516. +
  2517. + if (port->port_open_count > 0 || port->port_in_use) {
  2518. + port->port_dev = NULL;
  2519. + wake_up_interruptible(&port->port_write_wait);
  2520. + if (port->port_tty) {
  2521. + wake_up_interruptible(&port->port_tty->read_wait);
  2522. + wake_up_interruptible(&port->port_tty->write_wait);
  2523. + }
  2524. + spin_unlock_irqrestore(&port->port_lock, flags);
  2525. + } else {
  2526. + spin_unlock_irqrestore(&port->port_lock, flags);
  2527. + kfree(port);
  2528. + }
  2529. +
  2530. + }
  2531. + }
  2532. +}
  2533. +
  2534. +/* Circular Buffer */
  2535. +
  2536. +/*
  2537. + * fs_buf_alloc
  2538. + *
  2539. + * Allocate a circular buffer and all associated memory.
  2540. + */
  2541. +static struct fs_buf *fs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
  2542. +{
  2543. + struct fs_buf *gb;
  2544. +
  2545. + if (size == 0)
  2546. + return NULL;
  2547. +
  2548. + gb = kmalloc(sizeof(struct fs_buf), kmalloc_flags);
  2549. + if (gb == NULL)
  2550. + return NULL;
  2551. +
  2552. + gb->buf_buf = kmalloc(size, kmalloc_flags);
  2553. + if (gb->buf_buf == NULL) {
  2554. + kfree(gb);
  2555. + return NULL;
  2556. + }
  2557. +
  2558. + gb->buf_size = size;
  2559. + gb->buf_get = gb->buf_put = gb->buf_buf;
  2560. +
  2561. + return gb;
  2562. +}
  2563. +
  2564. +/*
  2565. + * fs_buf_free
  2566. + *
  2567. + * Free the buffer and all associated memory.
  2568. + */
  2569. +static void fs_buf_free(struct fs_buf *gb)
  2570. +{
  2571. + if (gb) {
  2572. + kfree(gb->buf_buf);
  2573. + kfree(gb);
  2574. + }
  2575. +}
  2576. +
  2577. +/*
  2578. + * fs_buf_clear
  2579. + *
  2580. + * Clear out all data in the circular buffer.
  2581. + */
  2582. +static void fs_buf_clear(struct fs_buf *gb)
  2583. +{
  2584. + if (gb != NULL)
  2585. + gb->buf_get = gb->buf_put;
  2586. + /* equivalent to a get of all data available */
  2587. +}
  2588. +
  2589. +/*
  2590. + * fs_buf_data_avail
  2591. + *
  2592. + * Return the number of bytes of data available in the circular
  2593. + * buffer.
  2594. + */
  2595. +static unsigned int fs_buf_data_avail(struct fs_buf *gb)
  2596. +{
  2597. + if (gb != NULL)
  2598. + return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size;
  2599. + else
  2600. + return 0;
  2601. +}
  2602. +
  2603. +/*
  2604. + * fs_buf_space_avail
  2605. + *
  2606. + * Return the number of bytes of space available in the circular
  2607. + * buffer.
  2608. + */
  2609. +static unsigned int fs_buf_space_avail(struct fs_buf *gb)
  2610. +{
  2611. + if (gb != NULL)
  2612. + return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size;
  2613. + else
  2614. + return 0;
  2615. +}
  2616. +
  2617. +/*
  2618. + * fs_buf_put
  2619. + *
  2620. + * Copy data data from a user buffer and put it into the circular buffer.
  2621. + * Restrict to the amount of space available.
  2622. + *
  2623. + * Return the number of bytes copied.
  2624. + */
  2625. +static unsigned int
  2626. +fs_buf_put(struct fs_buf *gb, const char *buf, unsigned int count)
  2627. +{
  2628. + unsigned int len;
  2629. +
  2630. + if (gb == NULL)
  2631. + return 0;
  2632. +
  2633. + len = fs_buf_space_avail(gb);
  2634. + if (count > len)
  2635. + count = len;
  2636. +
  2637. + if (count == 0)
  2638. + return 0;
  2639. +
  2640. + len = gb->buf_buf + gb->buf_size - gb->buf_put;
  2641. + if (count > len) {
  2642. + memcpy(gb->buf_put, buf, len);
  2643. + memcpy(gb->buf_buf, buf+len, count - len);
  2644. + gb->buf_put = gb->buf_buf + count - len;
  2645. + } else {
  2646. + memcpy(gb->buf_put, buf, count);
  2647. + if (count < len)
  2648. + gb->buf_put += count;
  2649. + else /* count == len */
  2650. + gb->buf_put = gb->buf_buf;
  2651. + }
  2652. +
  2653. + return count;
  2654. +}
  2655. +
  2656. +/*
  2657. + * fs_buf_get
  2658. + *
  2659. + * Get data from the circular buffer and copy to the given buffer.
  2660. + * Restrict to the amount of data available.
  2661. + *
  2662. + * Return the number of bytes copied.
  2663. + */
  2664. +static unsigned int
  2665. +fs_buf_get(struct fs_buf *gb, char *buf, unsigned int count)
  2666. +{
  2667. + unsigned int len;
  2668. +
  2669. + if (gb == NULL)
  2670. + return 0;
  2671. +
  2672. + len = fs_buf_data_avail(gb);
  2673. + if (count > len)
  2674. + count = len;
  2675. +
  2676. + if (count == 0)
  2677. + return 0;
  2678. +
  2679. + len = gb->buf_buf + gb->buf_size - gb->buf_get;
  2680. + if (count > len) {
  2681. + memcpy(buf, gb->buf_get, len);
  2682. + memcpy(buf+len, gb->buf_buf, count - len);
  2683. + gb->buf_get = gb->buf_buf + count - len;
  2684. + } else {
  2685. + memcpy(buf, gb->buf_get, count);
  2686. + if (count < len)
  2687. + gb->buf_get += count;
  2688. + else /* count == len */
  2689. + gb->buf_get = gb->buf_buf;
  2690. + }
  2691. +
  2692. + return count;
  2693. +}
  2694. diff -Naurp a/drivers/usb/function/fsync.c b/drivers/usb/function/fsync.c
  2695. --- a/drivers/usb/function/fsync.c 1970-01-01 01:00:00.000000000 +0100
  2696. +++ b/drivers/usb/function/fsync.c 2009-12-18 23:15:51.919779912 +0100
  2697. @@ -0,0 +1,677 @@
  2698. +/* drivers/usb/function/fsync.c
  2699. + *
  2700. + * Function Device for the Android ADB Protocol
  2701. + *
  2702. + * Copyright (C) 2007 Google, Inc.
  2703. + * Author: Brian Swetland <swetland@google.com>
  2704. + *
  2705. + * This software is licensed under the terms of the GNU General Public
  2706. + * License version 2, as published by the Free Software Foundation, and
  2707. + * may be copied, distributed, and modified under those terms.
  2708. + *
  2709. + * This program is distributed in the hope that it will be useful,
  2710. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2711. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  2712. + * GNU General Public License for more details.
  2713. + *
  2714. + * base on adb, modify to fsync
  2715. + * Author: Anthony_Chang@htc.com
  2716. + */
  2717. +
  2718. +#include <linux/init.h>
  2719. +#include <linux/module.h>
  2720. +#include <linux/kernel.h>
  2721. +#include <linux/miscdevice.h>
  2722. +#include <linux/fs.h>
  2723. +#include <linux/platform_device.h>
  2724. +#include <linux/sched.h>
  2725. +
  2726. +#include <linux/wait.h>
  2727. +#include <linux/list.h>
  2728. +
  2729. +#include <asm/atomic.h>
  2730. +#include <asm/uaccess.h>
  2731. +
  2732. +#include "usb_function.h"
  2733. +
  2734. +#if 1
  2735. +#define DBG(x...) do {} while (0)
  2736. +#else
  2737. +#define DBG(x...) printk(x)
  2738. +#endif
  2739. +
  2740. +/* allocate buffer size to: 16384 byte */
  2741. +//#define ALLOCATE_16K_BUFF
  2742. +
  2743. +#ifdef ALLOCATE_16K_BUFF
  2744. +#define TXN_MAX 16384
  2745. +#else
  2746. +#define TXN_MAX 4096
  2747. +
  2748. +/* number of rx and tx requests to allocate */
  2749. +#define RX_REQ_MAX 4
  2750. +#define TX_REQ_MAX 4
  2751. +#endif
  2752. +
  2753. +#define FSYNC_FUNCTION_NAME "fsync"
  2754. +
  2755. +/* fsync_status in /sys
  2756. + * #define USB_FSYNC_ADD_ATTR_FILE
  2757. + */
  2758. +#ifdef USB_FSYNC_ADD_ATTR_FILE
  2759. +static char fsync_status_tmp[32] = { 0 };
  2760. +#endif
  2761. +struct device fsync_dev;
  2762. +static void fsync_bind(struct usb_endpoint **ept, void *_ctxt);
  2763. +static void fsync_unbind(void *_ctxt);
  2764. +static void fsync_configure(int configured, void *_ctxt);
  2765. +
  2766. +struct fsync_context
  2767. +{
  2768. + int online;
  2769. + int error;
  2770. +
  2771. + atomic_t read_excl;
  2772. + atomic_t write_excl;
  2773. + atomic_t open_excl;
  2774. + atomic_t enable_excl;
  2775. + spinlock_t lock;
  2776. +
  2777. + struct usb_endpoint *out;
  2778. + struct usb_endpoint *in;
  2779. +
  2780. + struct list_head tx_idle;
  2781. + struct list_head rx_idle;
  2782. + struct list_head rx_done;
  2783. +
  2784. + wait_queue_head_t read_wq;
  2785. + wait_queue_head_t write_wq;
  2786. +
  2787. + /* the request we're currently reading from */
  2788. + struct usb_request *read_req;
  2789. + unsigned char *read_buf;
  2790. + unsigned read_count;
  2791. + struct platform_device *pdev;
  2792. + int registered;
  2793. +};
  2794. +
  2795. +static struct fsync_context _context;
  2796. +
  2797. +static struct usb_function usb_func_fsync = {
  2798. + .bind = fsync_bind,
  2799. + .unbind = fsync_unbind,
  2800. + .configure = fsync_configure,
  2801. +
  2802. + .name = FSYNC_FUNCTION_NAME,
  2803. + .context = &_context,
  2804. +
  2805. + .ifc_class = 0xff,
  2806. + .ifc_subclass = 0x43,
  2807. + .ifc_protocol = 0x01,
  2808. +
  2809. + .ifc_name = "fsync",
  2810. +
  2811. + .ifc_ept_count = 2,
  2812. + .position_bit = USB_FUNCTION_FSYNC_NUM,
  2813. + .ifc_ept_type = { EPT_BULK_OUT, EPT_BULK_IN },
  2814. +
  2815. + /* the fsync function is only enabled when its driver file is open */
  2816. + .disabled = 1,
  2817. + .ifc_num = 1,
  2818. +};
  2819. +
  2820. +static inline int _lock(atomic_t *excl)
  2821. +{
  2822. + if (atomic_inc_return(excl) == 1) {
  2823. + return 0;
  2824. + } else {
  2825. + atomic_dec(excl);
  2826. + return -1;
  2827. + }
  2828. +}
  2829. +
  2830. +static inline void _unlock(atomic_t *excl)
  2831. +{
  2832. + atomic_dec(excl);
  2833. +}
  2834. +
  2835. +/* add a request to the tail of a list */
  2836. +static void req_put(struct fsync_context *ctxt, struct list_head *head, struct usb_request *req)
  2837. +{
  2838. + unsigned long flags;
  2839. +
  2840. + spin_lock_irqsave(&ctxt->lock, flags);
  2841. + list_add_tail(&req->list, head);
  2842. + spin_unlock_irqrestore(&ctxt->lock, flags);
  2843. +}
  2844. +
  2845. +/* remove a request from the head of a list */
  2846. +static struct usb_request *req_get(struct fsync_context *ctxt, struct list_head *head)
  2847. +{
  2848. + unsigned long flags;
  2849. + struct usb_request *req;
  2850. +
  2851. + spin_lock_irqsave(&ctxt->lock, flags);
  2852. + if (list_empty(head)) {
  2853. + req = 0;
  2854. + } else {
  2855. + req = list_first_entry(head, struct usb_request, list);
  2856. + list_del(&req->list);
  2857. + }
  2858. + spin_unlock_irqrestore(&ctxt->lock, flags);
  2859. + return req;
  2860. +}
  2861. +
  2862. +static void fsync_complete_in(struct usb_endpoint *ept, struct usb_request *req)
  2863. +{
  2864. + struct fsync_context *ctxt = req->context;
  2865. +
  2866. + if (req->status != 0)
  2867. + ctxt->error = 1;
  2868. +
  2869. + req_put(ctxt, &ctxt->tx_idle, req);
  2870. +
  2871. + wake_up(&ctxt->write_wq);
  2872. +}
  2873. +
  2874. +static void fsync_complete_out(struct usb_endpoint *ept, struct usb_request *req)
  2875. +{
  2876. + struct fsync_context *ctxt = req->context;
  2877. +
  2878. + if (req->status != 0) {
  2879. + ctxt->error = 1;
  2880. + req_put(ctxt, &ctxt->rx_idle, req);
  2881. + } else {
  2882. + req_put(ctxt, &ctxt->rx_done, req);
  2883. + }
  2884. +
  2885. + wake_up(&ctxt->read_wq);
  2886. +}
  2887. +
  2888. +static ssize_t fsync_read(struct file *fp, char __user *buf,
  2889. + size_t count, loff_t *pos)
  2890. +{
  2891. + struct fsync_context *ctxt = &_context;
  2892. + struct usb_request *req;
  2893. + int r = count, xfer;
  2894. + int ret;
  2895. +
  2896. + DBG("%s(%d)\n", __func__, count);
  2897. +
  2898. + if (_lock(&ctxt->read_excl))
  2899. + return -EBUSY;
  2900. +
  2901. + /* we will block until we're online */
  2902. + while (!(ctxt->online || ctxt->error)) {
  2903. + DBG("%s: waiting for online state\n", __func__);
  2904. + ret = wait_event_interruptible(ctxt->read_wq, (ctxt->online || ctxt->error));
  2905. + if (ret < 0) {
  2906. + _unlock(&ctxt->read_excl);
  2907. + return ret;
  2908. + }
  2909. + }
  2910. +
  2911. + while (count > 0) {
  2912. + if (ctxt->error) {
  2913. + r = -EIO;
  2914. + break;
  2915. + }
  2916. +
  2917. + /* if we have idle read requests, get them queued */
  2918. + while ((req = req_get(ctxt, &ctxt->rx_idle))) {
  2919. +requeue_req:
  2920. + req->length = TXN_MAX;
  2921. + ret = usb_ept_queue_xfer(ctxt->out, req);
  2922. + if (ret < 0) {
  2923. + DBG("%s: failed to queue req %p (%d)\n", __func__, req, ret);
  2924. + r = -EIO;
  2925. + ctxt->error = 1;
  2926. + req_put(ctxt, &ctxt->rx_idle, req);
  2927. + goto fail;
  2928. + } else {
  2929. + DBG("%s: rx %p queue\n", __func__, req);
  2930. + }
  2931. + }
  2932. +
  2933. + /* if we have data pending, give it to userspace */
  2934. + if (ctxt->read_count > 0) {
  2935. + xfer = (ctxt->read_count < count) ? ctxt->read_count : count;
  2936. +
  2937. + if (copy_to_user(buf, ctxt->read_buf, xfer)) {
  2938. + r = -EFAULT;
  2939. + break;
  2940. + }
  2941. + ctxt->read_buf += xfer;
  2942. + ctxt->read_count -= xfer;
  2943. + buf += xfer;
  2944. + count -= xfer;
  2945. +
  2946. + /* if we've emptied the buffer, release the request */
  2947. + if (ctxt->read_count == 0) {
  2948. + req_put(ctxt, &ctxt->rx_idle, ctxt->read_req);
  2949. + ctxt->read_req = 0;
  2950. + }
  2951. + continue;
  2952. + }
  2953. +
  2954. + /* wait for a request to complete */
  2955. + req = 0;
  2956. + ret = wait_event_interruptible(ctxt->read_wq,
  2957. + ((req = req_get(ctxt, &ctxt->rx_done)) || ctxt->error));
  2958. +
  2959. + if (req != 0) {
  2960. + /* if we got a 0-len one we need to put it back into
  2961. + ** service. if we made it the current read req we'd
  2962. + ** be stuck forever
  2963. + */
  2964. + if (req->actual == 0)
  2965. + goto requeue_req;
  2966. +
  2967. + ctxt->read_req = req;
  2968. + ctxt->read_count = req->actual;
  2969. + ctxt->read_buf = req->buf;
  2970. + DBG("rx %p %d\n", req, req->actual);
  2971. + }
  2972. +
  2973. + if (ret < 0) {
  2974. + r = ret;
  2975. + break;
  2976. + }
  2977. + }
  2978. +
  2979. +fail:
  2980. + _unlock(&ctxt->read_excl);
  2981. + return r;
  2982. +}
  2983. +
  2984. +static ssize_t fsync_write(struct file *fp, const char __user *buf,
  2985. + size_t count, loff_t *pos)
  2986. +{
  2987. + struct fsync_context *ctxt = &_context;
  2988. + struct usb_request *req = 0;
  2989. + int r = count, xfer;
  2990. + int ret;
  2991. +
  2992. + DBG("%s(%d)\n", __func__, count);
  2993. +
  2994. + if (_lock(&ctxt->write_excl))
  2995. + return -EBUSY;
  2996. +
  2997. + while (count > 0) {
  2998. + if (ctxt->error) {
  2999. + r = -EIO;
  3000. + break;
  3001. + }
  3002. +
  3003. + /* get an idle tx request to use */
  3004. + req = 0;
  3005. + ret = wait_event_interruptible(ctxt->write_wq,
  3006. + ((req = req_get(ctxt, &ctxt->tx_idle)) || ctxt->error));
  3007. +
  3008. + if (ret < 0) {
  3009. + r = ret;
  3010. + break;
  3011. + }
  3012. +
  3013. + if (req != 0) {
  3014. + xfer = count > TXN_MAX ? TXN_MAX : count;
  3015. + if (copy_from_user(req->buf, buf, xfer)) {
  3016. + r = -EFAULT;
  3017. + break;
  3018. + }
  3019. +
  3020. + req->length = xfer;
  3021. + ret = usb_ept_queue_xfer(ctxt->in, req);
  3022. + if (ret < 0) {
  3023. + DBG("%s: xfer error %d\n", __func__, ret);
  3024. + ctxt->error = 1;
  3025. + r = -EIO;
  3026. + break;
  3027. + }
  3028. +
  3029. + buf += xfer;
  3030. + count -= xfer;
  3031. +
  3032. + /* zero this so we don't try to free it on error exit */
  3033. + req = 0;
  3034. + }
  3035. + }
  3036. +
  3037. +
  3038. + if (req)
  3039. + req_put(ctxt, &ctxt->tx_idle, req);
  3040. +
  3041. + _unlock(&ctxt->write_excl);
  3042. + return r;
  3043. +}
  3044. +
  3045. +static int fsync_open(struct inode *ip, struct file *fp)
  3046. +{
  3047. + struct fsync_context *ctxt = &_context;
  3048. +
  3049. + if (_lock(&ctxt->open_excl))
  3050. + return -EBUSY;
  3051. +
  3052. + /* clear the error latch */
  3053. + ctxt->error = 0;
  3054. +
  3055. + return 0;
  3056. +}
  3057. +
  3058. +static int fsync_release(struct inode *ip, struct file *fp)
  3059. +{
  3060. + struct fsync_context *ctxt = &_context;
  3061. +
  3062. + _unlock(&ctxt->open_excl);
  3063. + return 0;
  3064. +}
  3065. +
  3066. +static struct file_operations fsync_fops = {
  3067. + .owner = THIS_MODULE,
  3068. + .read = fsync_read,
  3069. + .write = fsync_write,
  3070. + .open = fsync_open,
  3071. + .release = fsync_release,
  3072. +};
  3073. +
  3074. +static struct miscdevice fsync_device = {
  3075. + .minor = MISC_DYNAMIC_MINOR,
  3076. + .name = "android_fsync",
  3077. + .fops = &fsync_fops,
  3078. +};
  3079. +
  3080. +static int fsync_enable_open(struct inode *ip, struct file *fp)
  3081. +{
  3082. + struct fsync_context *ctxt = &_context;
  3083. +
  3084. + if (_lock(&ctxt->enable_excl))
  3085. + return -EBUSY;
  3086. +
  3087. + printk(KERN_INFO "%s: enabling fsync function\n", __func__);
  3088. + usb_function_enable(FSYNC_FUNCTION_NAME, 1);
  3089. + /* clear the error latch */
  3090. + ctxt->error = 0;
  3091. +
  3092. + return 0;
  3093. +}
  3094. +
  3095. +static int fsync_enable_release(struct inode *ip, struct file *fp)
  3096. +{
  3097. + struct fsync_context *ctxt = &_context;
  3098. +
  3099. + printk(KERN_INFO "%s: disabling fsync function\n", __func__);
  3100. + usb_function_enable(FSYNC_FUNCTION_NAME, 0);
  3101. + _unlock(&ctxt->enable_excl);
  3102. + return 0;
  3103. +}
  3104. +
  3105. +static struct file_operations fsync_enable_fops = {
  3106. + .owner = THIS_MODULE,
  3107. + .open = fsync_enable_open,
  3108. + .release = fsync_enable_release,
  3109. +};
  3110. +
  3111. +static struct miscdevice fsync_enable_device = {
  3112. + .minor = MISC_DYNAMIC_MINOR,
  3113. + .name = "android_fsync_en",
  3114. + .fops = &fsync_enable_fops,
  3115. +};
  3116. +
  3117. +#ifdef USB_FSYNC_ADD_ATTR_FILE
  3118. +static ssize_t show_fsync_status(struct device *dev, struct device_attribute *attr,
  3119. + char *buf)
  3120. +{
  3121. + unsigned length;
  3122. + //struct msm_hsusb_platform_data *pdata = dev->platform_data;
  3123. +
  3124. + if(strlen(fsync_status_tmp))
  3125. + length = sprintf(buf, "%s", fsync_status_tmp); /* dummy */
  3126. + else
  3127. + length = 0;
  3128. + return length;
  3129. +}
  3130. +
  3131. +static ssize_t store_fsync_status(struct device *dev, struct device_attribute *attr,
  3132. + const char *buf, size_t count)
  3133. +{
  3134. + //struct usb_info *ui = the_usb_info;
  3135. + int data_buff_size = (sizeof(fsync_status_tmp)>strlen(buf))?
  3136. + strlen(buf):sizeof(fsync_status_tmp);
  3137. + int loop_i;
  3138. +
  3139. + /* avoid overflow, fsync_status_tmp[32] always is 0x0 */
  3140. + if(data_buff_size == 32)
  3141. + data_buff_size--;
  3142. +
  3143. + for(loop_i = 0; loop_i < data_buff_size; loop_i++) {
  3144. + if(buf[loop_i] >= 0x30 && buf[loop_i] <= 0x39) /* 0-9 */
  3145. + continue;
  3146. + else
  3147. + if(buf[loop_i] >= 0x41 && buf[loop_i] <= 0x5A) /* A-Z */
  3148. + continue;
  3149. + else
  3150. + if(buf[loop_i] >= 0x61 && buf[loop_i] <= 0x7A) /* a-z */
  3151. + continue;
  3152. + else
  3153. + if(buf[loop_i] == 0x0A) /* Line Feed */
  3154. + continue;
  3155. + else
  3156. + {
  3157. + printk(KERN_WARNING "%s(): get invaild char (0x%2.2X)\n", __func__, buf[loop_i]);
  3158. + return -EINVAL;
  3159. + }
  3160. + }
  3161. +
  3162. + memset(fsync_status_tmp, 0x0, sizeof(fsync_status_tmp));
  3163. + strncpy(fsync_status_tmp, buf, data_buff_size);
  3164. +
  3165. + return count;
  3166. +}
  3167. +
  3168. +static DEVICE_ATTR(fsync_status, 0644,
  3169. + show_fsync_status, store_fsync_status);
  3170. +#endif
  3171. +
  3172. +static int fsync_probe_reg (struct platform_device *pdev)
  3173. +{
  3174. + struct fsync_context *ctxt = &_context;
  3175. + ctxt->pdev = pdev;
  3176. + return 0;
  3177. +}
  3178. +
  3179. +static struct platform_driver fsync_driver_reg = {
  3180. + .probe = fsync_probe_reg,
  3181. + .driver = { .name = FSYNC_FUNCTION_NAME, },
  3182. +};
  3183. +
  3184. +static void fsync_release_reg (struct device *dev) {}
  3185. +
  3186. +static struct platform_device fsync_device_reg = {
  3187. + .name = FSYNC_FUNCTION_NAME,
  3188. + .id = -1,
  3189. + .dev = {
  3190. + .release = fsync_release_reg,
  3191. + },
  3192. +};
  3193. +
  3194. +static void fsync_dev_release (struct device *dev) {}
  3195. +
  3196. +static void fsync_unbind(void *_ctxt)
  3197. +{
  3198. + struct fsync_context *ctxt = _ctxt;
  3199. + struct usb_request *req;
  3200. +
  3201. + printk(KERN_INFO "%s()\n", __func__);
  3202. +
  3203. + while ((req = req_get(ctxt, &ctxt->rx_idle))) {
  3204. + usb_ept_free_req(ctxt->out, req);
  3205. + }
  3206. + while ((req = req_get(ctxt, &ctxt->tx_idle))) {
  3207. + usb_ept_free_req(ctxt->in, req);
  3208. + }
  3209. + if (ctxt->registered) {
  3210. +#ifdef USB_FSYNC_ADD_ATTR_FILE
  3211. + device_remove_file(&fsync_dev, &dev_attr_fsync_status);
  3212. +#endif
  3213. + device_unregister(&fsync_dev);
  3214. + ctxt->registered = 0;
  3215. + }
  3216. +
  3217. + ctxt->online = 0;
  3218. + ctxt->error = 1;
  3219. +
  3220. + /* readers may be blocked waiting for us to go online */
  3221. + wake_up(&ctxt->read_wq);
  3222. +}
  3223. +
  3224. +static void fsync_bind(struct usb_endpoint **ept, void *_ctxt)
  3225. +{
  3226. + struct fsync_context *ctxt = _ctxt;
  3227. + struct usb_request *req;
  3228. + int ret;
  3229. +#ifndef ALLOCATE_16K_BUFF
  3230. + int n;
  3231. +#endif
  3232. +
  3233. + ctxt->out = ept[0];
  3234. + ctxt->in = ept[1];
  3235. + ctxt->registered = 0;
  3236. + printk(KERN_INFO "%s() %p, %p\n", __func__, ctxt->out, ctxt->in);
  3237. +
  3238. +#ifndef ALLOCATE_16K_BUFF
  3239. + for (n = 0; n < RX_REQ_MAX; n++) {
  3240. +#else
  3241. + {
  3242. +#endif
  3243. +
  3244. + req = usb_ept_alloc_req(ctxt->out, TXN_MAX);
  3245. + if (req == 0) goto fail;
  3246. + req->context = ctxt;
  3247. + req->complete = fsync_complete_out;
  3248. + req_put(ctxt, &ctxt->rx_idle, req);
  3249. + }
  3250. +
  3251. +
  3252. +#ifndef ALLOCATE_16K_BUFF
  3253. + for (n = 0; n < TX_REQ_MAX; n++) {
  3254. +#else
  3255. + {
  3256. +#endif
  3257. + req = usb_ept_alloc_req(ctxt->in, TXN_MAX);
  3258. + if (req == 0) goto fail;
  3259. + req->context = ctxt;
  3260. + req->complete = fsync_complete_in;
  3261. + req_put(ctxt, &ctxt->tx_idle, req);
  3262. + }
  3263. +
  3264. +#ifndef ALLOCATE_16K_BUFF
  3265. + printk(KERN_INFO
  3266. + "%s() allocated %d rx and %d tx requests\n",
  3267. + __func__, RX_REQ_MAX, TX_REQ_MAX);
  3268. +#else
  3269. + printk(KERN_INFO
  3270. + "%s(): allocated buffer: %d\n", __func__, TXN_MAX);
  3271. +#endif
  3272. +
  3273. + misc_register(&fsync_device);
  3274. + misc_register(&fsync_enable_device);
  3275. +
  3276. + fsync_dev.release = fsync_dev_release;
  3277. + fsync_dev.parent = &ctxt->pdev->dev;
  3278. + strcpy(fsync_dev.bus_id, "interface");
  3279. +
  3280. + ret = device_register(&fsync_dev);
  3281. + if (ret != 0) {
  3282. + printk(KERN_WARNING "fsync_dev failed to register device: %d\n", ret);
  3283. + goto fail;
  3284. + }
  3285. +#ifdef USB_FSYNC_ADD_ATTR_FILE
  3286. + ret = device_create_file(&fsync_dev, &dev_attr_fsync_status);
  3287. + if (ret != 0) {
  3288. + printk(KERN_WARNING "fsync_dev device_create_file failed: %d\n", ret);
  3289. + device_unregister(&fsync_dev);
  3290. + goto fail;
  3291. + }
  3292. +#endif
  3293. + ctxt->registered = 1;
  3294. +
  3295. + return;
  3296. +
  3297. +fail:
  3298. + printk(KERN_ERR "%s() could not allocate requests\n", __func__);
  3299. + fsync_unbind(ctxt);
  3300. +}
  3301. +
  3302. +static void fsync_configure(int configured, void *_ctxt)
  3303. +{
  3304. + struct fsync_context *ctxt = _ctxt;
  3305. + struct usb_request *req;
  3306. +
  3307. + DBG("%s(): %s\n", __func__, (configured)?"success":"failure");
  3308. +
  3309. + if (configured) {
  3310. + ctxt->online = 1;
  3311. +
  3312. + /* if we have a stale request being read, recycle it */
  3313. + ctxt->read_buf = 0;
  3314. + ctxt->read_count = 0;
  3315. + if (ctxt->read_req) {
  3316. + req_put(ctxt, &ctxt->rx_idle, ctxt->read_req);
  3317. + ctxt->read_req = 0;
  3318. + }
  3319. +
  3320. + /* retire any completed rx requests from previous session */
  3321. + while ((req = req_get(ctxt, &ctxt->rx_done)))
  3322. + req_put(ctxt, &ctxt->rx_idle, req);
  3323. +
  3324. + } else {
  3325. + ctxt->online = 0;
  3326. + ctxt->error = 1;
  3327. + }
  3328. +
  3329. + /* readers may be blocked waiting for us to go online */
  3330. + wake_up(&ctxt->read_wq);
  3331. +}
  3332. +
  3333. +static int __init fsync_init(void)
  3334. +{
  3335. + struct fsync_context *ctxt = &_context;
  3336. + int retval = 0;
  3337. + DBG("%s()\n", __func__);
  3338. +
  3339. + init_waitqueue_head(&ctxt->read_wq);
  3340. + init_waitqueue_head(&ctxt->write_wq);
  3341. +
  3342. + atomic_set(&ctxt->open_excl, 0);
  3343. + atomic_set(&ctxt->read_excl, 0);
  3344. + atomic_set(&ctxt->write_excl, 0);
  3345. + atomic_set(&ctxt->enable_excl, 0);
  3346. +
  3347. + spin_lock_init(&ctxt->lock);
  3348. +
  3349. + INIT_LIST_HEAD(&ctxt->rx_idle);
  3350. + INIT_LIST_HEAD(&ctxt->rx_done);
  3351. + INIT_LIST_HEAD(&ctxt->tx_idle);
  3352. +
  3353. + retval = platform_driver_register (&fsync_driver_reg);
  3354. + if (retval < 0)
  3355. + return retval;
  3356. + retval = platform_device_register (&fsync_device_reg);
  3357. + if (retval < 0)
  3358. + goto err_register_device_1;
  3359. +
  3360. + retval = usb_function_register(&usb_func_fsync);
  3361. + if (retval < 0)
  3362. + goto err_register_device_2;
  3363. +
  3364. + return retval;
  3365. +
  3366. +err_register_device_2:
  3367. + platform_device_unregister(&fsync_device_reg);
  3368. +err_register_device_1:
  3369. + platform_driver_unregister(&fsync_driver_reg);
  3370. + return retval;
  3371. +
  3372. +}
  3373. +
  3374. +module_init(fsync_init);
  3375. diff -Naurp a/drivers/usb/function/Kconfig b/drivers/usb/function/Kconfig
  3376. --- a/drivers/usb/function/Kconfig 2009-12-18 22:01:12.191477285 +0100
  3377. +++ b/drivers/usb/function/Kconfig 2009-12-18 22:01:22.015489838 +0100
  3378. @@ -50,4 +50,32 @@ config USB_FUNCTION_ETHER
  3379. boolean "USB Ethernet Function"
  3380. depends on USB_FUNCTION
  3381.  
  3382. +config USB_FUNCTION_RNDIS
  3383. + boolean "USB RNDIS support"
  3384. + depends on USB_FUNCTION_ETHER
  3385. + default y
  3386. +
  3387. +config USB_FUNCTION_RNDIS_WCEIS
  3388. + boolean "Use Windows Internet Sharing Class/SubClass/Protocol"
  3389. + depends on USB_FUNCTION_RNDIS
  3390. + default y
  3391. + help
  3392. + Causes the driver to look like a Windows-compatible Internet
  3393. + Sharing device, so Windows auto-detects it.
  3394. +
  3395. + If you enable this option, the device is no longer CDC ethernet
  3396. + compatible.
  3397. +
  3398. +config USB_FUNCTION_FSYNC
  3399. + boolean "USB MSM7K FSYNC Function"
  3400. + depends on USB_FUNCTION
  3401. +
  3402. +config USB_FUNCTION_SERIAL
  3403. + boolean "USB SERIAL Function"
  3404. + depends on USB_FUNCTION
  3405. +
  3406. +config USB_FUNCTION_MTP_TUNNEL
  3407. + boolean "MTP Tunnel Transport Function"
  3408. + depends on USB_FUNCTION
  3409. +
  3410. endmenu
  3411. diff -Naurp a/drivers/usb/function/loopback.c b/drivers/usb/function/loopback.c
  3412. --- a/drivers/usb/function/loopback.c 2009-12-18 22:09:33.031478757 +0100
  3413. +++ b/drivers/usb/function/loopback.c 2009-12-18 22:09:40.823480975 +0100
  3414. @@ -117,6 +117,8 @@ static struct usb_function usb_func_loop
  3415.  
  3416. .ifc_ept_count = 2,
  3417. .ifc_ept_type = { EPT_BULK_OUT, EPT_BULK_IN },
  3418. +
  3419. + .position_bit = USB_FUNCTION_LOOPBACK_NUM,
  3420. };
  3421.  
  3422. static int __init loopback_init(void)
  3423. diff -Naurp a/drivers/usb/function/Makefile b/drivers/usb/function/Makefile
  3424. --- a/drivers/usb/function/Makefile 2009-12-18 22:04:21.175484872 +0100
  3425. +++ b/drivers/usb/function/Makefile 2009-12-18 22:04:33.815493233 +0100
  3426. @@ -1,10 +1,14 @@
  3427.  
  3428. obj-$(CONFIG_USB_FUNCTION_MSM_HSUSB) += msm_hsusb.o
  3429. obj-$(CONFIG_USB_FUNCTION_NULL) += null.o
  3430. -obj-$(CONFIG_USB_FUNCTION_NULL) += zero.o
  3431. +obj-$(CONFIG_USB_FUNCTION_ZERO) += zero.o
  3432. obj-$(CONFIG_USB_FUNCTION_LOOPBACK) += loopback.o
  3433. obj-$(CONFIG_USB_FUNCTION_ADB) += adb.o
  3434. obj-$(CONFIG_USB_FUNCTION_UMS) += ums.o
  3435. obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += mass_storage.o
  3436. obj-$(CONFIG_USB_FUNCTION_DIAG) += diag.o
  3437. obj-$(CONFIG_USB_FUNCTION_ETHER) += ether.o
  3438. +obj-$(CONFIG_USB_FUNCTION_RNDIS) += rndis.o
  3439. +obj-$(CONFIG_USB_FUNCTION_SERIAL) += fserial.o
  3440. +obj-$(CONFIG_USB_FUNCTION_FSYNC) += fsync.o
  3441. +obj-$(CONFIG_USB_FUNCTION_MTP_TUNNEL) += mtp_tunnel.o
  3442. diff -Naurp a/drivers/usb/function/mass_storage.c b/drivers/usb/function/mass_storage.c
  3443. --- a/drivers/usb/function/mass_storage.c 2009-12-18 22:09:54.103459621 +0100
  3444. +++ b/drivers/usb/function/mass_storage.c 2009-12-18 22:10:01.175483175 +0100
  3445. @@ -2449,9 +2449,39 @@ static ssize_t store_file(struct device
  3446. return (rc < 0 ? rc : count);
  3447. }
  3448.  
  3449. -
  3450. static DEVICE_ATTR(file, 0444, show_file, store_file);
  3451.  
  3452. +static ssize_t store_enable(struct device *dev, struct device_attribute *attr,
  3453. + const char *buf, size_t count)
  3454. +{
  3455. + unsigned long ul;
  3456. + if (count > 2 || (buf[0] != '0' && buf[0] != '1')) {
  3457. + printk(KERN_ERR "Can't enable/disable %s %s\n", DRIVER_NAME, buf);
  3458. + return -EINVAL;
  3459. + }
  3460. + ul = simple_strtoul(buf, NULL, 10);
  3461. + usb_function_enable(DRIVER_NAME, ul);
  3462. +
  3463. + return count;
  3464. +}
  3465. +
  3466. +static ssize_t show_enable(struct device *dev, struct device_attribute *attr,
  3467. + char *buf)
  3468. +{
  3469. + if (return_usb_function_enabled(DRIVER_NAME) > 0) {
  3470. + buf[0] = '1';
  3471. + buf[1] = '\n';
  3472. + }
  3473. + else {
  3474. + buf[0] = '0';
  3475. + buf[1] = '\n';
  3476. + }
  3477. +
  3478. + return 2;
  3479. +}
  3480. +
  3481. +static DEVICE_ATTR(enable, 0644, show_enable, store_enable);
  3482. +
  3483. /*-------------------------------------------------------------------------*/
  3484.  
  3485. static void fsg_release(struct kref *ref)
  3486. @@ -2483,6 +2513,7 @@ static void /* __init_or_exit */ fsg_unb
  3487. curlun = &fsg->luns[i];
  3488. if (curlun->registered) {
  3489. device_remove_file(&curlun->dev, &dev_attr_file);
  3490. + device_remove_file(&curlun->dev, &dev_attr_enable);
  3491. device_unregister(&curlun->dev);
  3492. curlun->registered = 0;
  3493. }
  3494. @@ -2554,6 +2585,12 @@ static void fsg_bind(struct usb_endpoint
  3495. device_unregister(&curlun->dev);
  3496. goto out;
  3497. }
  3498. + rc = device_create_file(&curlun->dev, &dev_attr_enable);
  3499. + if (rc != 0) {
  3500. + ERROR(fsg, "device_create_file failed: %d\n", rc);
  3501. + device_unregister(&curlun->dev);
  3502. + goto out;
  3503. + }
  3504. curlun->registered = 1;
  3505. kref_get(&fsg->ref);
  3506. }
  3507. @@ -2622,6 +2659,8 @@ static void fsg_configure(int configured
  3508.  
  3509. /*-------------------------------------------------------------------------*/
  3510.  
  3511. +/*-------------------------------------------------------------------------*/
  3512. +
  3513. static struct usb_function fsg_function = {
  3514. .bind = fsg_bind,
  3515. .unbind = fsg_unbind,
  3516. @@ -2638,6 +2677,8 @@ static struct usb_function fsg_function
  3517.  
  3518. .ifc_ept_count = 2,
  3519. .ifc_ept_type = { EPT_BULK_OUT, EPT_BULK_IN },
  3520. +
  3521. + .position_bit = USB_FUNCTION_MASS_STORAGE_NUM,
  3522. };
  3523.  
  3524.  
  3525. diff -Naurp a/drivers/usb/function/msm_hsusb.c b/drivers/usb/function/msm_hsusb.c
  3526. --- a/drivers/usb/function/msm_hsusb.c 2009-12-18 22:10:20.027483557 +0100
  3527. +++ b/drivers/usb/function/msm_hsusb.c 2009-12-18 22:10:26.539476376 +0100
  3528. @@ -53,18 +53,14 @@
  3529. #define STRING_SERIAL 1
  3530. #define STRING_PRODUCT 2
  3531. #define STRING_MANUFACTURER 3
  3532. +#define STRING_ENABLED_START 4
  3533. +#define STRING_DISABLED_START (STRING_ENABLED_START + 32)
  3534.  
  3535. #define LANGUAGE_ID 0x0409 /* en-US */
  3536.  
  3537. /* current state of VBUS */
  3538. static int vbus;
  3539.  
  3540. -struct usb_fi_ept
  3541. -{
  3542. - struct usb_endpoint *ept;
  3543. - struct usb_endpoint_descriptor desc;
  3544. -};
  3545. -
  3546. struct usb_function_info
  3547. {
  3548. struct list_head list;
  3549. @@ -110,6 +106,8 @@ struct usb_endpoint
  3550. unsigned char bit;
  3551. unsigned char num;
  3552.  
  3553. + unsigned char type;
  3554. +
  3555. unsigned short max_pkt;
  3556.  
  3557. /* pointers to DMA transfer list area */
  3558. @@ -162,7 +160,13 @@ struct usb_info
  3559.  
  3560. /* used for allocation */
  3561. unsigned next_item;
  3562. - unsigned next_ifc_num;
  3563. +
  3564. + uint32_t enabled_functions;
  3565. + uint32_t included_functions;
  3566. +
  3567. + unsigned ifc_num;
  3568. + unsigned ifc_map_to_host[32];
  3569. + unsigned ifc_map_to_driver[64];
  3570.  
  3571. /* endpoints are ordered based on their status bits,
  3572. ** so they are OUT0, OUT1, ... OUT15, IN0, IN1, ... IN15
  3573. @@ -192,7 +196,7 @@ struct usb_device_descriptor desc_device
  3574. .bLength = USB_DT_DEVICE_SIZE,
  3575. .bDescriptorType = USB_DT_DEVICE,
  3576.  
  3577. - .bcdUSB = 0x0102,
  3578. + .bcdUSB = 0x0200,
  3579. .bDeviceClass = 0,
  3580. .bDeviceSubClass = 0,
  3581. .bDeviceProtocol = 0,
  3582. @@ -207,8 +211,6 @@ struct usb_device_descriptor desc_device
  3583. .bNumConfigurations = 1,
  3584. };
  3585.  
  3586. -static uint32_t enabled_functions = 0;
  3587. -
  3588. static void flush_endpoint(struct usb_endpoint *ept);
  3589.  
  3590. #if 0
  3591. @@ -290,7 +292,7 @@ static void configure_endpoints(struct u
  3592. unsigned n;
  3593. unsigned cfg;
  3594.  
  3595. - for (n = 0; n < 31; n++) {
  3596. + for (n = 0; n < 32; n++) {
  3597. struct usb_endpoint *ept = ui->ept + n;
  3598.  
  3599. cfg = CONFIG_MAX_PKT(ept->max_pkt) | CONFIG_ZLT;
  3600. @@ -315,7 +317,7 @@ static struct usb_endpoint *alloc_endpoi
  3601. unsigned kind)
  3602. {
  3603. unsigned n;
  3604. - for (n = 0; n < 31; n++) {
  3605. + for (n = 0; n < 32; n++) {
  3606. struct usb_endpoint *ept = ui->ept + n;
  3607. if (ept->num == 0)
  3608. continue;
  3609. @@ -327,12 +329,20 @@ static struct usb_endpoint *alloc_endpoi
  3610. ept->max_pkt = 512;
  3611. ept->owner = owner;
  3612. return ept;
  3613. + } else if (kind == EPT_INT_IN) {
  3614. + ept->max_pkt = 64;
  3615. + ept->owner = owner;
  3616. + return ept;
  3617. }
  3618. } else {
  3619. if (kind == EPT_BULK_OUT) {
  3620. ept->max_pkt = 512;
  3621. ept->owner = owner;
  3622. return ept;
  3623. + } else if (kind == EPT_INT_OUT) {
  3624. + ept->max_pkt = 64;
  3625. + ept->owner = owner;
  3626. + return ept;
  3627. }
  3628. }
  3629. }
  3630. @@ -343,7 +353,7 @@ static struct usb_endpoint *alloc_endpoi
  3631. static void free_endpoints(struct usb_info *ui, struct usb_function_info *owner)
  3632. {
  3633. unsigned n;
  3634. - for (n = 0; n < 31; n++) {
  3635. + for (n = 0; n < 32; n++) {
  3636. struct usb_endpoint *ept = ui->ept + n;
  3637. if (ept->owner == owner) {
  3638. ept->owner = 0;
  3639. @@ -413,26 +423,38 @@ static void usb_ept_enable(struct usb_en
  3640. {
  3641. struct usb_info *ui = ept->ui;
  3642. int in = ept->flags & EPT_FLAG_IN;
  3643. + unsigned char type = ept->type;
  3644. unsigned n;
  3645.  
  3646. if (yes) {
  3647. - if (ui->speed == USB_SPEED_HIGH)
  3648. - ept->max_pkt = 512;
  3649. - else
  3650. + if (ui->speed == USB_SPEED_HIGH) {
  3651. + if (type == EPT_BULK_IN || type == EPT_BULK_OUT) {
  3652. + ept->max_pkt = 512;
  3653. + } else {
  3654. + ept->max_pkt = 64;
  3655. + }
  3656. + } else {
  3657. ept->max_pkt = 64;
  3658. + }
  3659. }
  3660.  
  3661. n = readl(USB_ENDPTCTRL(ept->num));
  3662.  
  3663. if (in) {
  3664. - n = (n & (~CTRL_TXT_MASK)) | CTRL_TXT_BULK;
  3665. + if (type == EPT_BULK_IN)
  3666. + n = (n & (~CTRL_TXT_MASK)) | CTRL_TXT_BULK;
  3667. + else if (type == EPT_INT_IN)
  3668. + n = (n & (~CTRL_TXT_MASK)) | CTRL_TXT_INT;
  3669. if (yes) {
  3670. n |= CTRL_TXE | CTRL_TXR;
  3671. } else {
  3672. n &= (~CTRL_TXE);
  3673. }
  3674. } else {
  3675. - n = (n & (~CTRL_RXT_MASK)) | CTRL_RXT_BULK;
  3676. + if (type == EPT_BULK_OUT)
  3677. + n = (n & (~CTRL_RXT_MASK)) | CTRL_RXT_BULK;
  3678. + else if (type == EPT_INT_OUT)
  3679. + n = (n & (~CTRL_RXT_MASK)) | CTRL_RXT_INT;
  3680. if (yes) {
  3681. n |= CTRL_RXE | CTRL_RXR;
  3682. } else {
  3683. @@ -715,37 +737,39 @@ static void handle_setup(struct usb_info
  3684. if ((ctl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) {
  3685. /* let functions handle vendor and class requests */
  3686.  
  3687. - int i;
  3688. - for (i = 0; i < ui->num_funcs; i++) {
  3689. + if (/*ctl.wIndex >= 0 &&*/ ctl.wIndex < ui->ifc_num) {
  3690. + int i = ui->ifc_map_to_driver[ctl.wIndex];
  3691. struct usb_function_info *fi = ui->func[i];
  3692.  
  3693. - if (fi->func->setup) {
  3694. - if (ctl.bRequestType & USB_DIR_IN) {
  3695. - /* IN request */
  3696. - struct usb_request *req = ui->setup_req;
  3697. -
  3698. - int ret = fi->func->setup(&ctl,
  3699. - req->buf,
  3700. - SETUP_BUF_SIZE,
  3701. - fi->func->context);
  3702. - if (ret >= 0) {
  3703. - req->length = ret;
  3704. - ep0_setup_send(ui, ctl.wLength);
  3705. - return;
  3706. - }
  3707. - } else {
  3708. - /* OUT request */
  3709. - /* FIXME - support reading setup
  3710. - * data from host.
  3711. - */
  3712. - int ret = fi->func->setup(&ctl, NULL, 0,
  3713. - fi->func->context);
  3714. - if (ret >= 0) goto ack;
  3715. + if (!fi->enabled)
  3716. + goto bad_setup_request;
  3717. +
  3718. + if (ctl.bRequestType & USB_DIR_IN) {
  3719. + /* IN request */
  3720. + struct usb_request *req = ui->setup_req;
  3721. +
  3722. + int ret = fi->func->setup(&ctl,
  3723. + req->buf,
  3724. + SETUP_BUF_SIZE,
  3725. + fi->func->context);
  3726. + if (ret >= 0) {
  3727. + req->length = ret;
  3728. + ep0_setup_send(ui, ctl.wLength);
  3729. + return;
  3730. }
  3731. + } else {
  3732. + /* OUT request */
  3733. + /* FIXME - support reading setup
  3734. + * data from host.
  3735. + */
  3736. + int ret = fi->func->setup(&ctl, NULL, 0,
  3737. + fi->func->context);
  3738. + if (ret >= 0) goto ack;
  3739. }
  3740. }
  3741. }
  3742.  
  3743. +bad_setup_request:
  3744. ep0_setup_stall(ui);
  3745. return;
  3746.  
  3747. @@ -968,7 +992,9 @@ static void usb_prepare(struct usb_info
  3748. /* only important for reset/reinit */
  3749. memset(ui->ept, 0, sizeof(ui->ept));
  3750. ui->next_item = 0;
  3751. - ui->next_ifc_num = 0;
  3752. + ui->ifc_num = 0;
  3753. + ui->enabled_functions = 0;
  3754. + ui->included_functions = 0;
  3755.  
  3756. init_endpoints(ui);
  3757.  
  3758. @@ -996,7 +1022,7 @@ static void usb_bind_driver(struct usb_i
  3759. {
  3760. struct usb_endpoint *ept;
  3761. struct usb_endpoint_descriptor *ed;
  3762. - struct usb_endpoint *elist[8];
  3763. + struct usb_endpoint *elist[10];
  3764. struct usb_function *func = fi->func;
  3765. unsigned n, count;
  3766.  
  3767. @@ -1009,12 +1035,14 @@ static void usb_bind_driver(struct usb_i
  3768.  
  3769. fi->ifc.bLength = USB_DT_INTERFACE_SIZE;
  3770. fi->ifc.bDescriptorType = USB_DT_INTERFACE;
  3771. + /* Set while building the descriptor - see usb_find_descriptor */
  3772. + fi->ifc.bInterfaceNumber = 0;
  3773. fi->ifc.bAlternateSetting = 0;
  3774. - fi->ifc.bNumEndpoints = count;
  3775. + fi->ifc.bNumEndpoints = count != 2 ? 1 : count;
  3776. fi->ifc.bInterfaceClass = func->ifc_class;
  3777. fi->ifc.bInterfaceSubClass = func->ifc_subclass;
  3778. fi->ifc.bInterfaceProtocol = func->ifc_protocol;
  3779. - fi->ifc.iInterface = 0;
  3780. + fi->ifc.iInterface = func->ifc_name ? (STRING_ENABLED_START + func->position_bit) : 0;
  3781.  
  3782. for (n = 0; n < count; n++) {
  3783. ept = alloc_endpoint(ui, fi, func->ifc_ept_type[n]);
  3784. @@ -1029,14 +1057,19 @@ static void usb_bind_driver(struct usb_i
  3785. ed->bLength = USB_DT_ENDPOINT_SIZE;
  3786. ed->bDescriptorType = USB_DT_ENDPOINT;
  3787. ed->bEndpointAddress = ept->num | ((ept->flags & EPT_FLAG_IN) ? 0x80 : 0);
  3788. - ed->bmAttributes = 0x02; /* XXX hardcoded bulk */
  3789. + ed->bmAttributes =
  3790. + (func->ifc_ept_type[n] ==
  3791. + EPT_INT_IN || func->ifc_ept_type[n] ==
  3792. + EPT_INT_OUT) ? 0x03 : 0x02;
  3793. ed->bInterval = 0; /* XXX hardcoded bulk */
  3794.  
  3795. elist[n] = ept;
  3796. + ept->type = func->ifc_ept_type[n];
  3797. fi->ept[n].ept = ept;
  3798. }
  3799.  
  3800. - fi->ifc.bInterfaceNumber = ui->next_ifc_num++;
  3801. + elist[count] = &ui->ep0in;
  3802. + elist[count + 1] = &ui->ep0out;
  3803.  
  3804. fi->endpoints = count;
  3805.  
  3806. @@ -1058,6 +1091,12 @@ static void usb_reset(struct usb_info *u
  3807. msleep(2);
  3808. #endif
  3809.  
  3810. + /* disable usb interrupts */
  3811. + writel(0, USB_USBINTR);
  3812. +
  3813. + /* wait for a while after enable usb clk*/
  3814. + msleep(5);
  3815. +
  3816. /* RESET */
  3817. writel(2, USB_USBCMD);
  3818. msleep(10);
  3819. @@ -1066,7 +1105,8 @@ static void usb_reset(struct usb_info *u
  3820. ui->phy_reset();
  3821.  
  3822. /* INCR4 BURST mode */
  3823. - writel(0x01, USB_SBUSCFG);
  3824. + /*boost performance to fix CRC error.*/
  3825. + writel(0x02, USB_SBUSCFG);
  3826.  
  3827. /* select DEVICE mode */
  3828. writel(0x12, USB_USBMODE);
  3829. @@ -1145,6 +1185,14 @@ static struct usb_function_info *usb_fin
  3830. return NULL;
  3831. }
  3832.  
  3833. +struct usb_fi_ept *get_ept_info(const char *function)
  3834. +{
  3835. + struct usb_function_info *fi = usb_find_function(function);
  3836. + if (!fi)
  3837. + return NULL;
  3838. + return &fi->ept[0];
  3839. +}
  3840. +
  3841. static void usb_try_to_bind(void)
  3842. {
  3843. struct usb_info *ui = the_usb_info;
  3844. @@ -1197,7 +1245,15 @@ int usb_function_register(struct usb_fun
  3845.  
  3846. fail:
  3847. mutex_unlock(&usb_function_list_lock);
  3848. - return 0;
  3849. + return ret;
  3850. +}
  3851. +
  3852. +int return_usb_function_enabled(const char *function)
  3853. +{
  3854. + struct usb_function_info *fi = usb_find_function(function);
  3855. + if (!fi)
  3856. + return -EINVAL;
  3857. + return fi->enabled;
  3858. }
  3859.  
  3860. void usb_function_enable(const char *function, int enable)
  3861. @@ -1585,7 +1641,7 @@ static int __init usb_init(void)
  3862.  
  3863. module_init(usb_init);
  3864.  
  3865. -static void copy_string_descriptor(char *string, char *buffer)
  3866. +static void copy_string_descriptor(const char *string, char *buffer)
  3867. {
  3868. int length, i;
  3869.  
  3870. @@ -1600,10 +1656,84 @@ static void copy_string_descriptor(char
  3871. }
  3872. }
  3873.  
  3874. +static const char string_descriptor_disabled[] = " \0(\0d\0i\0s\0a\0b\0l\0e\0d\0)\0\0";
  3875. +static void string_descriptor_append_disabled(char *buffer)
  3876. +{
  3877. + if (buffer[0] < 2) {
  3878. + buffer[0] = 2;
  3879. + buffer[1] = USB_DT_STRING;
  3880. + buffer[2] = 0;
  3881. + buffer[3] = 0;
  3882. + }
  3883. +
  3884. + memcpy(buffer + buffer[0], string_descriptor_disabled, sizeof(string_descriptor_disabled));
  3885. + buffer[0] += sizeof(string_descriptor_disabled) - 2;
  3886. +}
  3887. +
  3888. +static char *copy_ifc_descriptors(char *buf, size_t len, struct usb_info *ui, int i)
  3889. +{
  3890. + struct usb_function_info *fi = ui->func[i];
  3891. + int j, n;
  3892. + char *ptr = buf;
  3893. +
  3894. + /* check to see if the function was enabled when we
  3895. + ** received the USB_DT_DEVICE request to make ensure
  3896. + ** that the interfaces we return here match the
  3897. + ** product ID we returned in the USB_DT_DEVICE.
  3898. + */
  3899. + if (ui->included_functions & BIT(fi->func->position_bit)) {
  3900. + if (!(ui->enabled_functions & BIT(fi->func->position_bit))) {
  3901. + for (j = 0; j < fi->func->ifc_num || j < 1; j++) {
  3902. + /* Copy a disabled interface */
  3903. + struct usb_interface_descriptor *ifc = (struct usb_interface_descriptor *)ptr;
  3904. +
  3905. + if (unlikely(len < (ptr - buf + USB_DT_INTERFACE_SIZE)))
  3906. + return buf;
  3907. +
  3908. + ifc->bLength = USB_DT_INTERFACE_SIZE;
  3909. + ifc->bDescriptorType = USB_DT_INTERFACE;
  3910. + ifc->bInterfaceNumber = ui->ifc_map_to_host[i];
  3911. + ifc->bAlternateSetting = 0;
  3912. + ifc->bNumEndpoints = 0;
  3913. + ifc->bInterfaceClass = 0;
  3914. + ifc->bInterfaceSubClass = 0;
  3915. + ifc->bInterfaceProtocol = 0;
  3916. + ifc->iInterface = fi->func->ifc_name ? (STRING_DISABLED_START + fi->func->position_bit) : 0;
  3917. +
  3918. + ptr += ifc->bLength;
  3919. + }
  3920. + } else {
  3921. + /* Copy the real interface */
  3922. + if (fi->func->ifc_copy) {
  3923. + ptr += fi->func->ifc_copy(ptr, len - (ptr - buf), ui->ifc_map_to_host[i]);
  3924. + } else {
  3925. + if (unlikely(len < (ptr - buf + fi->ifc.bLength)))
  3926. + return buf;
  3927. +
  3928. + memcpy(ptr, &fi->ifc, fi->ifc.bLength);
  3929. +
  3930. + /* Fixup interface number */
  3931. + ptr[2/*bInterfaceNumber*/] = ui->ifc_map_to_host[i];
  3932. +
  3933. + ptr += fi->ifc.bLength;
  3934. +
  3935. + for (n = 0; n < fi->endpoints; n++) {
  3936. + /* XXX hardcoded bulk */
  3937. + fi->ept[n].desc.wMaxPacketSize = fi->ept[n].ept->max_pkt;
  3938. + memcpy(ptr, &(fi->ept[n].desc), fi->ept[n].desc.bLength);
  3939. + ptr += fi->ept[n].desc.bLength;
  3940. + }
  3941. + }
  3942. + }
  3943. + }
  3944. +
  3945. + return ptr;
  3946. +}
  3947. +
  3948. static int usb_find_descriptor(struct usb_info *ui, unsigned id, struct usb_request *req)
  3949. {
  3950. struct msm_hsusb_platform_data *pdata = ui->pdev->dev.platform_data;
  3951. - int i;
  3952. + int i, j;
  3953. unsigned type = id >> 8;
  3954. id &= 0xff;
  3955.  
  3956. @@ -1616,24 +1746,57 @@ static int usb_find_descriptor(struct us
  3957. ** USB_DT_DEVICE matches the list of interfaces we
  3958. ** return for USB_DT_CONFIG.
  3959. */
  3960. - enabled_functions = 0;
  3961. + ui->enabled_functions = 0;
  3962. + ui->included_functions = (uint32_t)-1;
  3963. for (i = 0; i < ui->num_funcs; i++) {
  3964. struct usb_function_info *fi = ui->func[i];
  3965. if (fi->enabled)
  3966. - enabled_functions |= (1 << i);
  3967. + ui->enabled_functions |= (1 << fi->func->position_bit);
  3968. + }
  3969. +
  3970. + if (ui->enabled_functions & BIT(USB_FUNCTION_INTERNET_SHARING_NUM)) {
  3971. +#ifdef CONFIG_USB_FUNCTION_RNDIS_WCEIS
  3972. + desc_device.bDeviceClass = USB_CLASS_WIRELESS_CONTROLLER;
  3973. + desc_device.bDeviceSubClass = 1;
  3974. + desc_device.bDeviceProtocol = 3;
  3975. +#else
  3976. + desc_device.bDeviceClass = USB_CLASS_COMM;
  3977. + desc_device.bDeviceSubClass = 0;
  3978. + desc_device.bDeviceProtocol = 0;
  3979. +#endif
  3980. + } else {
  3981. + desc_device.bDeviceClass = 0;
  3982. + desc_device.bDeviceSubClass = 0;
  3983. + desc_device.bDeviceProtocol = 0;
  3984. }
  3985.  
  3986. /* default product ID */
  3987. desc_device.idProduct = pdata->product_id;
  3988. +
  3989. /* set idProduct based on which functions are enabled */
  3990. for (i = 0; i < pdata->num_products; i++) {
  3991. -
  3992. - if (pdata->products[i].functions == enabled_functions) {
  3993. + if ((pdata->products[i].functions & ui->enabled_functions) == ui->enabled_functions) {
  3994. struct msm_hsusb_product *product =
  3995. &pdata->products[i];
  3996. - if (product->functions == enabled_functions)
  3997. - desc_device.idProduct =
  3998. - product->product_id;
  3999. + desc_device.idProduct =
  4000. + product->product_id;
  4001. + ui->included_functions = pdata->products[i].functions;
  4002. + break;
  4003. + }
  4004. + }
  4005. +
  4006. + if (ui->included_functions != ui->enabled_functions)
  4007. + printk(KERN_WARNING "msm_hsusb: No exact match for %x, using product id %04x with %x\n", ui->enabled_functions, desc_device.idProduct, ui->included_functions);
  4008. +
  4009. + /* Build a host->driver interface number map
  4010. + and driver function number->host interface number map */
  4011. + ui->ifc_num = 0;
  4012. + for (i = 0; i < ui->num_funcs; i++) {
  4013. + struct usb_function_info *fi = ui->func[i];
  4014. + if (ui->included_functions & BIT(fi->func->position_bit)) {
  4015. + ui->ifc_map_to_host[i] = ui->ifc_num;
  4016. + for (j = 0; j < fi->func->ifc_num || j < 1; j++)
  4017. + ui->ifc_map_to_driver[ui->ifc_num++] = i;
  4018. }
  4019. }
  4020.  
  4021. @@ -1645,38 +1808,15 @@ static int usb_find_descriptor(struct us
  4022. if ((type == USB_DT_CONFIG) && (id == 0)) {
  4023. struct usb_config_descriptor cfg;
  4024. unsigned ifc_count = 0;
  4025. - unsigned n;
  4026. char *ptr, *start;
  4027. - int max_packet;
  4028.  
  4029. - if (ui->speed == USB_SPEED_HIGH)
  4030. - max_packet = 512;
  4031. - else
  4032. - max_packet = 64;
  4033. start = req->buf;
  4034. ptr = start + USB_DT_CONFIG_SIZE;
  4035.  
  4036. for (i = 0; i < ui->num_funcs; i++) {
  4037. struct usb_function_info *fi = ui->func[i];
  4038. -
  4039. - /* check to see if the function was enabled when we
  4040. - ** received the USB_DT_DEVICE request to make ensure
  4041. - ** that the interfaces we return here match the
  4042. - ** product ID we returned in the USB_DT_DEVICE.
  4043. - */
  4044. - if (enabled_functions & (1 << i)) {
  4045. - ifc_count++;
  4046. -
  4047. - memcpy(ptr, &fi->ifc, fi->ifc.bLength);
  4048. - ptr += fi->ifc.bLength;
  4049. -
  4050. - for (n = 0; n < fi->endpoints; n++) {
  4051. - /* XXX hardcoded bulk */
  4052. - fi->ept[n].desc.wMaxPacketSize = max_packet;
  4053. - memcpy(ptr, &(fi->ept[n].desc), fi->ept[n].desc.bLength);
  4054. - ptr += fi->ept[n].desc.bLength;
  4055. - }
  4056. - }
  4057. + ptr = copy_ifc_descriptors(ptr, SETUP_BUF_SIZE - (ptr - start), ui, i);
  4058. + ifc_count += fi->func->ifc_num ? fi->func->ifc_num : 1;
  4059. }
  4060.  
  4061. cfg.bLength = USB_DT_CONFIG_SIZE;
  4062. @@ -1703,7 +1843,7 @@ static int usb_find_descriptor(struct us
  4063. /* return language ID */
  4064. buffer[0] = 4;
  4065. buffer[1] = USB_DT_STRING;
  4066. - buffer[2] = LANGUAGE_ID;
  4067. + buffer[2] = LANGUAGE_ID & 0xff;
  4068. buffer[3] = LANGUAGE_ID >> 8;
  4069. break;
  4070. case STRING_SERIAL:
  4071. @@ -1715,6 +1855,27 @@ static int usb_find_descriptor(struct us
  4072. case STRING_MANUFACTURER:
  4073. copy_string_descriptor(pdata->manufacturer_name, buffer);
  4074. break;
  4075. + default: {
  4076. + int disabled = 0;
  4077. + if (id >= STRING_DISABLED_START) {
  4078. + id = id - STRING_DISABLED_START + STRING_ENABLED_START;
  4079. + disabled = 1;
  4080. + }
  4081. +
  4082. + if (id >= STRING_ENABLED_START) {
  4083. + for (i = 0; i < ui->num_funcs; i++) {
  4084. + struct usb_function_info *fi = ui->func[i];
  4085. + if ((id - STRING_ENABLED_START) == fi->func->position_bit && fi->func->ifc_name) {
  4086. + copy_string_descriptor(fi->func->ifc_name, buffer);
  4087. + if (disabled) string_descriptor_append_disabled(buffer);
  4088. + break;
  4089. + }
  4090. + }
  4091. + break;
  4092. + }
  4093. +
  4094. + break;
  4095. + }
  4096. }
  4097.  
  4098. if (buffer[0]) {
  4099. diff -Naurp a/drivers/usb/function/mtp_tunnel.c b/drivers/usb/function/mtp_tunnel.c
  4100. --- a/drivers/usb/function/mtp_tunnel.c 1970-01-01 01:00:00.000000000 +0100
  4101. +++ b/drivers/usb/function/mtp_tunnel.c 2009-12-18 23:16:10.748280575 +0100
  4102. @@ -0,0 +1,862 @@
  4103. +/* drivers/usb/function/mtp_tunnel.c
  4104. + *
  4105. + * Function Device for the Android ADB Protocol
  4106. + *
  4107. + * Copyright (C) 2007 Google, Inc.
  4108. + * Author: Brian Swetland <swetland@google.com>
  4109. + *
  4110. + * This software is licensed under the terms of the GNU General Public
  4111. + * License version 2, as published by the Free Software Foundation, and
  4112. + * may be copied, distributed, and modified under those terms.
  4113. + *
  4114. + * This program is distributed in the hope that it will be useful,
  4115. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4116. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4117. + * GNU General Public License for more details.
  4118. + *
  4119. + * base on ADB function, modify to MTP tunnel function
  4120. + * by Anthony_Chang <anthony_chang@htc.com>
  4121. + */
  4122. +
  4123. +#include <linux/init.h>
  4124. +#include <linux/module.h>
  4125. +#include <linux/kernel.h>
  4126. +#include <linux/miscdevice.h>
  4127. +#include <linux/fs.h>
  4128. +#include <linux/device.h>
  4129. +#include <linux/platform_device.h>
  4130. +#include <linux/sched.h>
  4131. +
  4132. +#include <linux/wait.h>
  4133. +#include <linux/list.h>
  4134. +
  4135. +#include <asm/atomic.h>
  4136. +#include <asm/uaccess.h>
  4137. +#include <mach/msm_hsusb.h>
  4138. +
  4139. +#include "usb_function.h"
  4140. +#include <linux/usb/cdc.h>
  4141. +
  4142. +/* please refer: Documentation/ioctl-number.txt and Documentation/ioctl/
  4143. + * and choice magic-number */
  4144. +#define USB_MTP_IOC_MAGIC 0xFF
  4145. +
  4146. +#define USB_MTP_FUNC_IOC_CANCEL_REQUEST_SET _IOW(USB_MTP_IOC_MAGIC, 0x20, int)
  4147. +#define USB_MTP_FUNC_IOC_CANCEL_REQUEST_GET _IOW(USB_MTP_IOC_MAGIC, 0x21, int)
  4148. +#define USB_MTP_FUNC_IOC_GET_EXTENDED_EVENT_DATA_SET _IOW(USB_MTP_IOC_MAGIC, 0x22, int)
  4149. +#define USB_MTP_FUNC_IOC_GET_EXTENDED_EVENT_DATA_GET _IOW(USB_MTP_IOC_MAGIC, 0x23, int)
  4150. +#define USB_MTP_FUNC_IOC_DEVICE_RESET_REQUEST_SET _IOW(USB_MTP_IOC_MAGIC, 0x24, int)
  4151. +#define USB_MTP_FUNC_IOC_DEVICE_RESET_REQUEST_GET _IOW(USB_MTP_IOC_MAGIC, 0x25, int)
  4152. +#define USB_MTP_FUNC_IOC_GET_DEVICE_STATUS_SET _IOW(USB_MTP_IOC_MAGIC, 0x26, int)
  4153. +#define USB_MTP_FUNC_IOC_GET_DEVICE_STATUS_GET _IOW(USB_MTP_IOC_MAGIC, 0x27, int)
  4154. +
  4155. +/* base on Annex. D in PIMA15740-2000 spec */
  4156. +#define PIMA15740_CANCEL_REQUEST 0x64
  4157. +#define PIMA15740_GET_EXTENDED_EVENT_DATA 0x65
  4158. +#define PIMA15740_DEVICE_RESET_REQUEST 0x66
  4159. +#define PIMA15740_GET_DEVICE_STATUS 0x67
  4160. +
  4161. +static u16 mtp_tunnel_status = 0xFF;
  4162. +
  4163. +#if 1
  4164. +#define DBG(x...) do {} while (0)
  4165. +#else
  4166. +#define DBG(x...) printk(KERN_INFO x)
  4167. +#endif
  4168. +
  4169. +/* allocate buffer size to: 16384 byte */
  4170. +#define ALLOCATE_16K_BUFF
  4171. +
  4172. +#ifdef ALLOCATE_16K_BUFF
  4173. +#define TXN_MAX 16384
  4174. +#else
  4175. +#define TXN_MAX 4096
  4176. +
  4177. +/* number of rx and tx requests to allocate */
  4178. +#define RX_REQ_MAX 4
  4179. +#define TX_REQ_MAX 4
  4180. +#endif
  4181. +
  4182. +#define MTP_TUNNEL_FUNCTION_NAME "mtp_tunnel"
  4183. +
  4184. +struct device mtp_tunnel_dev;
  4185. +
  4186. +struct mtp_tunnel_context
  4187. +{
  4188. + int online;
  4189. + int error;
  4190. +
  4191. + atomic_t read_excl;
  4192. + atomic_t write_excl;
  4193. + atomic_t open_excl;
  4194. + atomic_t enable_open_excl;
  4195. + atomic_t enable_read_excl;
  4196. + atomic_t enable_ioctl_excl;
  4197. + spinlock_t lock;
  4198. +
  4199. + struct usb_endpoint *out;
  4200. + struct usb_endpoint *in;
  4201. +
  4202. + struct list_head tx_idle;
  4203. + struct list_head rx_idle;
  4204. + struct list_head rx_done;
  4205. +
  4206. + wait_queue_head_t read_wq;
  4207. + wait_queue_head_t write_wq;
  4208. +
  4209. + /* the request we're currently reading from */
  4210. + struct usb_request *read_req;
  4211. + unsigned char *read_buf;
  4212. + unsigned read_count;
  4213. + int registered;
  4214. + struct platform_device *pdev;
  4215. + u8 ioctl_tmp[2];
  4216. +};
  4217. +
  4218. +static struct mtp_tunnel_context _context;
  4219. +
  4220. +struct _mtp_specific_request {
  4221. + //unsigned char request_specific_sequence;
  4222. + unsigned char request_specific_num;
  4223. + const char *request_specific_string;
  4224. +};
  4225. +/*
  4226. +static struct _mtp_specific_request mtp_specific_request[] = {
  4227. + { PIMA15740_CANCEL_REQUEST, "Cancel_Request" },
  4228. + { PIMA15740_GET_EXTENDED_EVENT_DATA, "Get_Extented_Event_Data" },
  4229. + { PIMA15740_DEVICE_RESET_REQUEST, "Device_Reset_Request" },
  4230. + { PIMA15740_GET_DEVICE_STATUS, "Get_Device_Status" },
  4231. + { 0xFF, NULL }
  4232. +};
  4233. +*/
  4234. +static inline int _lock(atomic_t *excl)
  4235. +{
  4236. + if (atomic_inc_return(excl) == 1) {
  4237. + return 0;
  4238. + } else {
  4239. + atomic_dec(excl);
  4240. + return -1;
  4241. + }
  4242. +}
  4243. +
  4244. +static inline void _unlock(atomic_t *excl)
  4245. +{
  4246. + atomic_dec(excl);
  4247. +}
  4248. +
  4249. +/* add a request to the tail of a list */
  4250. +void static req_put(struct mtp_tunnel_context *ctxt, struct list_head *head, struct usb_request *req)
  4251. +{
  4252. + unsigned long flags;
  4253. +
  4254. + spin_lock_irqsave(&ctxt->lock, flags);
  4255. + list_add_tail(&req->list, head);
  4256. + spin_unlock_irqrestore(&ctxt->lock, flags);
  4257. +}
  4258. +
  4259. +/* remove a request from the head of a list */
  4260. +static struct usb_request *req_get(struct mtp_tunnel_context *ctxt, struct list_head *head)
  4261. +{
  4262. + unsigned long flags;
  4263. + struct usb_request *req;
  4264. +
  4265. + spin_lock_irqsave(&ctxt->lock, flags);
  4266. + if (list_empty(head)) {
  4267. + req = 0;
  4268. + } else {
  4269. + req = list_first_entry(head, struct usb_request, list);
  4270. + list_del(&req->list);
  4271. + }
  4272. + spin_unlock_irqrestore(&ctxt->lock, flags);
  4273. + return req;
  4274. +}
  4275. +
  4276. +static void mtp_tunnel_complete_in(struct usb_endpoint *ept, struct usb_request *req)
  4277. +{
  4278. + struct mtp_tunnel_context *ctxt = req->context;
  4279. +
  4280. + if (req->status != 0)
  4281. + ctxt->error = 1;
  4282. +
  4283. + req_put(ctxt, &ctxt->tx_idle, req);
  4284. +
  4285. + wake_up(&ctxt->write_wq);
  4286. +}
  4287. +
  4288. +static void mtp_tunnel_complete_out(struct usb_endpoint *ept, struct usb_request *req)
  4289. +{
  4290. + struct mtp_tunnel_context *ctxt = req->context;
  4291. +
  4292. + if (req->status != 0) {
  4293. + ctxt->error = 1;
  4294. + req_put(ctxt, &ctxt->rx_idle, req);
  4295. + } else {
  4296. + req_put(ctxt, &ctxt->rx_done, req);
  4297. + }
  4298. +
  4299. + wake_up(&ctxt->read_wq);
  4300. +}
  4301. +
  4302. +static ssize_t mtp_tunnel_read(struct file *fp, char __user *buf,
  4303. + size_t count, loff_t *pos)
  4304. +{
  4305. + struct mtp_tunnel_context *ctxt = &_context;
  4306. + struct usb_request *req;
  4307. + int r = count, xfer;
  4308. + int ret;
  4309. +
  4310. + DBG("mtp_tunnel_read(%d)\n", count);
  4311. +
  4312. + if (_lock(&ctxt->read_excl))
  4313. + return -EBUSY;
  4314. +
  4315. + /* we will block until we're online */
  4316. + while (!(ctxt->online || ctxt->error)) {
  4317. + DBG("mtp_tunnel_read: waiting for online state\n");
  4318. + ret = wait_event_interruptible(ctxt->read_wq, (ctxt->online || ctxt->error));
  4319. + if (ret < 0) {
  4320. + _unlock(&ctxt->read_excl);
  4321. + return ret;
  4322. + }
  4323. + }
  4324. +
  4325. + while (count > 0) {
  4326. + if (ctxt->error) {
  4327. + r = -EIO;
  4328. + break;
  4329. + }
  4330. +
  4331. + /* if we have idle read requests, get them queued */
  4332. + while ((req = req_get(ctxt, &ctxt->rx_idle))) {
  4333. +requeue_req:
  4334. + req->length = TXN_MAX;
  4335. + ret = usb_ept_queue_xfer(ctxt->out, req);
  4336. + if (ret < 0) {
  4337. + DBG("mtp_tunnel_read: failed to queue req %p (%d)\n", req, ret);
  4338. + r = -EIO;
  4339. + ctxt->error = 1;
  4340. + req_put(ctxt, &ctxt->rx_idle, req);
  4341. + goto fail;
  4342. + } else {
  4343. + DBG("%s(): rx %p queue\n", __func__, req);
  4344. + }
  4345. + }
  4346. +
  4347. + /* if we have data pending, give it to userspace */
  4348. + if (ctxt->read_count > 0) {
  4349. + xfer = (ctxt->read_count < count) ? ctxt->read_count : count;
  4350. +
  4351. + if (copy_to_user(buf, ctxt->read_buf, xfer)) {
  4352. + r = -EFAULT;
  4353. + break;
  4354. + }
  4355. + ctxt->read_buf += xfer;
  4356. + ctxt->read_count -= xfer;
  4357. + buf += xfer;
  4358. + count -= xfer;
  4359. +
  4360. + /* if we've emptied the buffer, release the request */
  4361. + if (ctxt->read_count == 0) {
  4362. + req_put(ctxt, &ctxt->rx_idle, ctxt->read_req);
  4363. + ctxt->read_req = 0;
  4364. + }
  4365. + continue;
  4366. + }
  4367. +
  4368. + /* wait for a request to complete */
  4369. + req = 0;
  4370. + ret = wait_event_interruptible(ctxt->read_wq,
  4371. + ((req = req_get(ctxt, &ctxt->rx_done)) || ctxt->error));
  4372. +
  4373. + if (req != 0) {
  4374. + /* if we got a 0-len one we need to put it back into
  4375. + ** service. if we made it the current read req we'd
  4376. + ** be stuck forever
  4377. + */
  4378. + if (req->actual == 0)
  4379. + goto requeue_req;
  4380. +
  4381. + ctxt->read_req = req;
  4382. + ctxt->read_count = req->actual;
  4383. + ctxt->read_buf = req->buf;
  4384. + DBG("%s(): rx %p %d\n", __func__, req, req->actual);
  4385. + }
  4386. +
  4387. + if (ret < 0) {
  4388. + r = ret;
  4389. + break;
  4390. + }
  4391. + }
  4392. +
  4393. +fail:
  4394. + _unlock(&ctxt->read_excl);
  4395. + return r;
  4396. +}
  4397. +
  4398. +static ssize_t mtp_tunnel_write(struct file *fp, const char __user *buf,
  4399. + size_t count, loff_t *pos)
  4400. +{
  4401. + struct mtp_tunnel_context *ctxt = &_context;
  4402. + struct usb_request *req = 0;
  4403. + int r = count, xfer;
  4404. + int ret;
  4405. +
  4406. + DBG("mtp_tunnel_write(%d)\n", count);
  4407. +
  4408. + if (_lock(&ctxt->write_excl))
  4409. + return -EBUSY;
  4410. +
  4411. + while (count > 0) {
  4412. + if (ctxt->error) {
  4413. + r = -EIO;
  4414. + break;
  4415. + }
  4416. +
  4417. + /* get an idle tx request to use */
  4418. + req = 0;
  4419. + ret = wait_event_interruptible(ctxt->write_wq,
  4420. + ((req = req_get(ctxt, &ctxt->tx_idle)) || ctxt->error));
  4421. +
  4422. + if (ret < 0) {
  4423. + r = ret;
  4424. + break;
  4425. + }
  4426. +
  4427. + if (req != 0) {
  4428. + xfer = count > TXN_MAX ? TXN_MAX : count;
  4429. + if (copy_from_user(req->buf, buf, xfer)) {
  4430. + r = -EFAULT;
  4431. + break;
  4432. + }
  4433. +
  4434. + req->length = xfer;
  4435. + ret = usb_ept_queue_xfer(ctxt->in, req);
  4436. + if (ret < 0) {
  4437. + DBG("mtp_tunnel_write: xfer error %d\n", ret);
  4438. + ctxt->error = 1;
  4439. + r = -EIO;
  4440. + break;
  4441. + }
  4442. +
  4443. + buf += xfer;
  4444. + count -= xfer;
  4445. +
  4446. + /* zero this so we don't try to free it on error exit */
  4447. + req = 0;
  4448. + }
  4449. + }
  4450. +
  4451. +
  4452. + if (req)
  4453. + req_put(ctxt, &ctxt->tx_idle, req);
  4454. +
  4455. + _unlock(&ctxt->write_excl);
  4456. + return r;
  4457. +}
  4458. +
  4459. +static int mtp_tunnel_open(struct inode *ip, struct file *fp)
  4460. +{
  4461. + struct mtp_tunnel_context *ctxt = &_context;
  4462. +
  4463. + if (_lock(&ctxt->open_excl))
  4464. + return -EBUSY;
  4465. +
  4466. + /* clear the error latch */
  4467. + ctxt->error = 0;
  4468. +
  4469. + return 0;
  4470. +}
  4471. +
  4472. +static int mtp_tunnel_release(struct inode *ip, struct file *fp)
  4473. +{
  4474. + struct mtp_tunnel_context *ctxt = &_context;
  4475. +
  4476. + _unlock(&ctxt->open_excl);
  4477. + return 0;
  4478. +}
  4479. +
  4480. +static struct file_operations mtp_tunnel_fops = {
  4481. + .owner = THIS_MODULE,
  4482. + .read = mtp_tunnel_read,
  4483. + .write = mtp_tunnel_write,
  4484. + .open = mtp_tunnel_open,
  4485. + .release = mtp_tunnel_release,
  4486. +};
  4487. +
  4488. +static struct miscdevice mtp_tunnel_device = {
  4489. + .minor = MISC_DYNAMIC_MINOR,
  4490. + .name = "android_mtp_tunnel",
  4491. + .fops = &mtp_tunnel_fops,
  4492. +};
  4493. +
  4494. +static DECLARE_WAIT_QUEUE_HEAD(mtp_tunnel_enable_read_wait);
  4495. +#if 0
  4496. +static ssize_t mtp_tunnel_enable_read(struct file *fp, char __user *buf,
  4497. + size_t count, loff_t *pos)
  4498. +{
  4499. + struct mtp_tunnel_context *ctxt = &_context;
  4500. + int r = 0;
  4501. + int loop_i;
  4502. +
  4503. + DBG("mtp_tunnel_read(%d)\n", count);
  4504. +
  4505. + if (_lock(&ctxt->enable_read_excl))
  4506. + return -EBUSY;
  4507. +/*
  4508. + while(mtp_tunnel_status == 0xFF) {
  4509. + _unlock(&ctxt->enable_read_excl);
  4510. + if(fp->f_flags & O_NONBLOCK) {
  4511. + _unlock(&ctxt->enable_read_excl);
  4512. + r = -EAGAIN;
  4513. + goto fail;
  4514. + }
  4515. + if(wait_event_interruptible(mtp_tunnel_enable_read_wait,
  4516. + mtp_tunnel_status != 0xFF)) {
  4517. + r = -ERESTARTSYS;
  4518. + goto fail;
  4519. + }
  4520. + if (_lock(&ctxt->enable_read_excl))
  4521. + return -EBUSY;
  4522. + }
  4523. +*/
  4524. + for(loop_i = 0; loop_i < ARRAY_SIZE(mtp_specific_request); loop_i++) {
  4525. + if(mtp_tunnel_status == mtp_specific_request[loop_i].request_specific_sequence) {
  4526. + if(mtp_specific_request[loop_i].request_specific_string != NULL)
  4527. + r = strlen(mtp_specific_request[loop_i].request_specific_string);
  4528. + if(r)
  4529. + if(copy_to_user(buf,
  4530. + mtp_specific_request[loop_i].request_specific_string,
  4531. + r))
  4532. + r = -EFAULT;
  4533. + break;
  4534. + }
  4535. + }
  4536. + count -= r;
  4537. + *pos += r;
  4538. +fail:
  4539. + _unlock(&ctxt->enable_read_excl);
  4540. + return r;
  4541. +}
  4542. +#endif
  4543. +static int
  4544. +mtp_tunnel_enable_ioctl(struct inode *inode, struct file *file,
  4545. + unsigned int cmd, unsigned long arg)
  4546. +{
  4547. + struct mtp_tunnel_context *ctxt = &_context;
  4548. + void __user *argp = (void __user *)arg;
  4549. + int tmp_value;
  4550. +
  4551. + if (_lock(&ctxt->enable_ioctl_excl))
  4552. + return -EBUSY;
  4553. +
  4554. + if(_IOC_TYPE(cmd) != USB_MTP_IOC_MAGIC) {
  4555. + printk(KERN_NOTICE "_IOC_TYPE(cmd) != USB_MTP_IOC_MAGIC, return -ENOTTY\n");
  4556. + _unlock(&ctxt->enable_ioctl_excl);
  4557. + return -ENOTTY;
  4558. + }
  4559. +
  4560. + switch(cmd) {
  4561. + case USB_MTP_FUNC_IOC_CANCEL_REQUEST_SET:
  4562. + printk(KERN_NOTICE "%s: USB_MTP_FUNC_IOC_CANCEL_REQUEST_SET\n", __func__);
  4563. + mtp_tunnel_status = 0xFF;
  4564. + break;
  4565. + case USB_MTP_FUNC_IOC_GET_DEVICE_STATUS_SET:
  4566. + printk(KERN_NOTICE "%s: USB_MTP_FUNC_IOC_GET_DEVICE_STATUS_SET\n", __func__);
  4567. + if (copy_from_user(&tmp_value, argp, sizeof(int)))
  4568. + return -EFAULT;
  4569. + ctxt->ioctl_tmp[0] = 0xFF & tmp_value;
  4570. + ctxt->ioctl_tmp[1] = 0xFF & (tmp_value >> 8);
  4571. + printk(KERN_INFO "%s: data_0: 0x%X, data_1: 0x%X #\n\n\n",
  4572. + __func__, ctxt->ioctl_tmp[0], ctxt->ioctl_tmp[1]);
  4573. + mtp_tunnel_status = 0xFF;
  4574. + break;
  4575. + case USB_MTP_FUNC_IOC_GET_DEVICE_STATUS_GET:
  4576. + printk(KERN_NOTICE "%s: USB_MTP_FUNC_IOC_GET_DEVICE_STATUS_GET\n", __func__);
  4577. + break;
  4578. +#if 0
  4579. +/* Needless, return -ENOTTY */
  4580. + case USB_MTP_FUNC_IOC_CANCEL_REQUEST_GET:
  4581. + printk(KERN_NOTICE "%s: USB_MTP_FUNC_IOC_CANCEL_REQUEST_GET\n", __func__);
  4582. + return -ENOTTY;
  4583. + break;
  4584. + case USB_MTP_FUNC_IOC_GET_EXTENDED_EVENT_DATA_SET:
  4585. + printk(KERN_NOTICE "%s: USB_MTP_FUNC_IOC_GET_EXTENDED_EVENT_DATA_SET\n", __func__);
  4586. + return -ENOTTY;
  4587. + break;
  4588. + case USB_MTP_FUNC_IOC_GET_EXTENDED_EVENT_DATA_GET:
  4589. + printk(KERN_NOTICE "%s: USB_MTP_FUNC_IOC_GET_EXTENDED_EVENT_DATA_GET\n", __func__);
  4590. + return -ENOTTY;
  4591. + break;
  4592. + case USB_MTP_FUNC_IOC_DEVICE_RESET_REQUEST_SET:
  4593. + printk(KERN_NOTICE "%s: USB_MTP_FUNC_IOC_DEVICE_RESET_REQUEST_SET\n", __func__);
  4594. + return -ENOTTY;
  4595. + break;
  4596. + case USB_MTP_FUNC_IOC_DEVICE_RESET_REQUEST_GET:
  4597. + printk(KERN_NOTICE "%s: USB_MTP_FUNC_IOC_DEVICE_RESET_REQUEST_GET\n", __func__);
  4598. + return -ENOTTY;
  4599. + break;
  4600. +#endif
  4601. + default:
  4602. + printk(KERN_NOTICE "%s: default, will return -ENOTTY\n", __func__);
  4603. + return -ENOTTY;
  4604. + break;
  4605. + }
  4606. + _unlock(&ctxt->enable_ioctl_excl);
  4607. + return 0;
  4608. +}
  4609. +
  4610. +static int mtp_tunnel_enable_open(struct inode *ip, struct file *fp)
  4611. +{
  4612. + struct mtp_tunnel_context *ctxt = &_context;
  4613. +
  4614. + if (_lock(&ctxt->enable_open_excl))
  4615. + return -EBUSY;
  4616. +
  4617. + DBG("%s(): Enabling %s function ###\n", __func__, MTP_TUNNEL_FUNCTION_NAME);
  4618. + usb_function_enable(MTP_TUNNEL_FUNCTION_NAME, 1);
  4619. + /* clear the error latch */
  4620. + ctxt->error = 0;
  4621. +
  4622. + return 0;
  4623. +}
  4624. +
  4625. +static int mtp_tunnel_enable_release(struct inode *ip, struct file *fp)
  4626. +{
  4627. + struct mtp_tunnel_context *ctxt = &_context;
  4628. +
  4629. + DBG("%s(): Disabling %s function ###\n", __func__, MTP_TUNNEL_FUNCTION_NAME);
  4630. + usb_function_enable(MTP_TUNNEL_FUNCTION_NAME, 0);
  4631. + _unlock(&ctxt->enable_open_excl);
  4632. + return 0;
  4633. +}
  4634. +
  4635. +
  4636. +static struct file_operations mtp_tunnel_fops_enable = {
  4637. + .owner = THIS_MODULE,
  4638. + //.read = mtp_tunnel_enable_read,
  4639. + .open = mtp_tunnel_enable_open,
  4640. + .ioctl = mtp_tunnel_enable_ioctl,
  4641. + .release = mtp_tunnel_enable_release,
  4642. +};
  4643. +
  4644. +static struct miscdevice mtp_tunnel_enable_device = {
  4645. + .minor = MISC_DYNAMIC_MINOR,
  4646. + .name = "android_mtp_enable",
  4647. + .fops = &mtp_tunnel_fops_enable,
  4648. +};
  4649. +
  4650. +static ssize_t store_mtp_tunnel_status(struct device *dev,
  4651. + struct device_attribute *attr,
  4652. + const char *buf, size_t count)
  4653. +{
  4654. + u32 ul;
  4655. + struct mtp_tunnel_context *ctxt = &_context;
  4656. +
  4657. + ul = simple_strtoul(buf, NULL, 10);
  4658. + if(ul != PIMA15740_CANCEL_REQUEST && ul != PIMA15740_GET_DEVICE_STATUS) {
  4659. + printk(KERN_WARNING "Unknown mtp_tunnel status: 0x%2.2X\n", ul);
  4660. + return -EINVAL;
  4661. + }
  4662. + mtp_tunnel_status = ul;
  4663. + kobject_uevent(&ctxt->pdev->dev.kobj, KOBJ_CHANGE);
  4664. +
  4665. + return count;
  4666. +}
  4667. +
  4668. +static ssize_t show_mtp_tunnel_status(struct device *dev,
  4669. + struct device_attribute *attr,
  4670. + char *buf)
  4671. +{
  4672. + int rc = 0;
  4673. +
  4674. + switch(mtp_tunnel_status) {
  4675. + case PIMA15740_CANCEL_REQUEST:
  4676. + rc += sprintf(buf, "Cancel_Request\n");
  4677. + break;
  4678. + case PIMA15740_GET_DEVICE_STATUS:
  4679. + rc += sprintf(buf, "Get_Device_Status\n");
  4680. + break;
  4681. + }
  4682. + return rc;
  4683. +}
  4684. +
  4685. +static DEVICE_ATTR(mtp_tunnel_status, 0644, show_mtp_tunnel_status, store_mtp_tunnel_status);
  4686. +
  4687. +static void mtp_tunnel_dev_release (struct device *dev) {}
  4688. +
  4689. +static int mtp_tunnel_probe_register (struct platform_device *pdev)
  4690. +{
  4691. + struct mtp_tunnel_context *ctxt = &_context;
  4692. + ctxt->pdev = pdev;
  4693. + return 0;
  4694. +}
  4695. +
  4696. +static struct platform_driver mtp_tunnel_driver = {
  4697. + .probe = mtp_tunnel_probe_register,
  4698. + .driver = { .name = MTP_TUNNEL_FUNCTION_NAME, },
  4699. +};
  4700. +
  4701. +static void mtp_tunnel_release_register (struct device *dev) {}
  4702. +
  4703. +static struct platform_device mtp_tunnel_device_register = {
  4704. + .name = MTP_TUNNEL_FUNCTION_NAME,
  4705. + .id = -1,
  4706. + .dev = {
  4707. + .release = mtp_tunnel_release_register,
  4708. + },
  4709. +};
  4710. +
  4711. +static void mtp_tunnel_unbind(void *_ctxt)
  4712. +{
  4713. + struct mtp_tunnel_context *ctxt = _ctxt;
  4714. + struct usb_request *req;
  4715. +
  4716. + printk(KERN_DEBUG "mtp_tunnel_unbind()\n");
  4717. +
  4718. + while ((req = req_get(ctxt, &ctxt->rx_idle))) {
  4719. + usb_ept_free_req(ctxt->out, req);
  4720. + }
  4721. + while ((req = req_get(ctxt, &ctxt->tx_idle))) {
  4722. + usb_ept_free_req(ctxt->in, req);
  4723. + }
  4724. +
  4725. + ctxt->online = 0;
  4726. + ctxt->error = 1;
  4727. +
  4728. + if (ctxt->registered) {
  4729. + device_remove_file(&mtp_tunnel_dev, &dev_attr_mtp_tunnel_status);
  4730. + device_unregister(&mtp_tunnel_dev);
  4731. + ctxt->registered = 0;
  4732. + }
  4733. +
  4734. + /* readers may be blocked waiting for us to go online */
  4735. + wake_up(&ctxt->read_wq);
  4736. +}
  4737. +
  4738. +static void mtp_tunnel_bind(struct usb_endpoint **ept, void *_ctxt)
  4739. +{
  4740. + struct mtp_tunnel_context *ctxt = _ctxt;
  4741. + struct usb_request *req;
  4742. + int ret;
  4743. +#ifndef ALLOCATE_16K_BUFF
  4744. + int n;
  4745. +#endif
  4746. + ctxt->registered = 0;
  4747. + ctxt->out = ept[0];
  4748. + ctxt->in = ept[1];
  4749. +
  4750. + printk(KERN_DEBUG "mtp_tunnel_bind() %p, %p\n", ctxt->out, ctxt->in);
  4751. +
  4752. +#ifndef ALLOCATE_16K_BUFF
  4753. + for (n = 0; n < RX_REQ_MAX; n++)
  4754. +#endif
  4755. + {
  4756. + req = usb_ept_alloc_req(ctxt->out, TXN_MAX);
  4757. + if (req == 0) goto fail;
  4758. + req->context = ctxt;
  4759. + req->complete = mtp_tunnel_complete_out;
  4760. + req_put(ctxt, &ctxt->rx_idle, req);
  4761. + }
  4762. +
  4763. +
  4764. +#ifndef ALLOCATE_16K_BUFF
  4765. + for (n = 0; n < TX_REQ_MAX; n++)
  4766. +#endif
  4767. + {
  4768. + req = usb_ept_alloc_req(ctxt->in, TXN_MAX);
  4769. + if (req == 0) goto fail;
  4770. + req->context = ctxt;
  4771. + req->complete = mtp_tunnel_complete_in;
  4772. + req_put(ctxt, &ctxt->tx_idle, req);
  4773. + }
  4774. +
  4775. +#ifndef ALLOCATE_16K_BUFF
  4776. + printk(KERN_DEBUG
  4777. + "mtp_tunnel_bind() allocated %d rx and %d tx requests\n",
  4778. + RX_REQ_MAX, TX_REQ_MAX);
  4779. +#else
  4780. + printk(KERN_DEBUG
  4781. + "%s(): allocated buffer: %d\n", __func__, TXN_MAX);
  4782. +#endif
  4783. +
  4784. + misc_register(&mtp_tunnel_device);
  4785. + misc_register(&mtp_tunnel_enable_device);
  4786. +
  4787. + mtp_tunnel_dev.release = mtp_tunnel_dev_release;
  4788. + mtp_tunnel_dev.parent = &ctxt->pdev->dev;
  4789. + strcpy(mtp_tunnel_dev.bus_id, "interface");
  4790. +
  4791. + ret = device_register(&mtp_tunnel_dev);
  4792. + if (ret != 0) {
  4793. + printk(KERN_WARNING "mtp_tunnel_dev failed to register device: %d\n", ret);
  4794. + goto fail_dev_register_fail;
  4795. + }
  4796. + ret = device_create_file(&mtp_tunnel_dev, &dev_attr_mtp_tunnel_status);
  4797. + if (ret != 0) {
  4798. + printk(KERN_WARNING "mtp_tunnel_dev device_create_file failed: %d\n", ret);
  4799. + device_unregister(&mtp_tunnel_dev);
  4800. + goto fail_dev_register_fail;
  4801. + }
  4802. + ctxt->registered = 1;
  4803. + return;
  4804. +
  4805. +fail_dev_register_fail:
  4806. + printk(KERN_ERR "%s() could not allocate requests\n", __func__);
  4807. +
  4808. +fail:
  4809. + printk(KERN_WARNING "mtp_tunnel_bind() could not allocate requests\n");
  4810. + mtp_tunnel_unbind(ctxt);
  4811. +}
  4812. +
  4813. +static void mtp_tunnel_configure(int configured, void *_ctxt)
  4814. +{
  4815. + struct mtp_tunnel_context *ctxt = _ctxt;
  4816. + struct usb_request *req;
  4817. +
  4818. + DBG("mtp_tunnel_configure() %d\n", configured);
  4819. +
  4820. + if (configured) {
  4821. + ctxt->online = 1;
  4822. +
  4823. + /* if we have a stale request being read, recycle it */
  4824. + ctxt->read_buf = 0;
  4825. + ctxt->read_count = 0;
  4826. + if (ctxt->read_req) {
  4827. + req_put(ctxt, &ctxt->rx_idle, ctxt->read_req);
  4828. + ctxt->read_req = 0;
  4829. + }
  4830. +
  4831. + /* retire any completed rx requests from previous session */
  4832. + while ((req = req_get(ctxt, &ctxt->rx_done)))
  4833. + req_put(ctxt, &ctxt->rx_idle, req);
  4834. +
  4835. + } else {
  4836. + ctxt->online = 0;
  4837. + ctxt->error = 1;
  4838. + }
  4839. +
  4840. + /* readers may be blocked waiting for us to go online */
  4841. + wake_up(&ctxt->read_wq);
  4842. +}
  4843. +
  4844. +static int mtp_tunnel_setup(struct usb_ctrlrequest *ctrl, void *buf,
  4845. + int len, void *_ctxt)
  4846. +{
  4847. + struct mtp_tunnel_context *ctxt = _ctxt;
  4848. + int value = -EOPNOTSUPP;
  4849. + u16 w_index = le16_to_cpu(ctrl->wIndex);
  4850. + //u16 w_value = le16_to_cpu(ctrl->wValue);
  4851. + u16 w_length = le16_to_cpu(ctrl->wLength);
  4852. +
  4853. + switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
  4854. + case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  4855. + | USB_CDC_REQ_SET_CONTROL_LINE_STATE:
  4856. + printk(KERN_DEBUG "%s(): USB_CDC_REQ_SET_CONTROL_LINE_STATE\n", __func__);
  4857. + value = 1;
  4858. + break;
  4859. + case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  4860. + | PIMA15740_CANCEL_REQUEST:
  4861. + printk(KERN_DEBUG "%s(): PIMA15740_CANCEL_REQUEST\n", __func__);
  4862. + if(w_length != 6)
  4863. + break;
  4864. + mtp_tunnel_status = PIMA15740_CANCEL_REQUEST;
  4865. + kobject_uevent(&ctxt->pdev->dev.kobj, KOBJ_CHANGE);
  4866. + // wake_up_interruptible(&mtp_tunnel_enable_read_wait);
  4867. + if(wait_event_interruptible_timeout(mtp_tunnel_enable_read_wait,
  4868. + mtp_tunnel_status == 0xFF, HZ * 5))
  4869. + value = -ERESTARTSYS;
  4870. + value = 0;
  4871. + break;
  4872. + case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
  4873. + | PIMA15740_GET_DEVICE_STATUS:
  4874. + printk(KERN_DEBUG "%s(): PIMA15740_GET_DEVICE_STATUS(%d)\n", __func__, w_length);
  4875. + value = w_length;
  4876. + mtp_tunnel_status = PIMA15740_GET_DEVICE_STATUS;
  4877. + kobject_uevent(&ctxt->pdev->dev.kobj, KOBJ_CHANGE);
  4878. + //wake_up_interruptible(&mtp_tunnel_enable_read_wait);
  4879. + if(wait_event_interruptible_timeout(mtp_tunnel_enable_read_wait,
  4880. + mtp_tunnel_status == 0xFF, HZ * 5)) {
  4881. + value = -ERESTARTSYS;
  4882. + } else {
  4883. + printk(KERN_INFO "%s: prepare data for send back to PC\n", __func__);
  4884. + *(u8 *)buf = ctxt->ioctl_tmp[0];
  4885. + *(u8 *)(buf+1) = ctxt->ioctl_tmp[1];
  4886. + value = 2;
  4887. + }
  4888. + break;
  4889. +
  4890. + }
  4891. + if (value == -EOPNOTSUPP)
  4892. + printk(KERN_ERR
  4893. + "%s: unknown class-specific control req "
  4894. + "%02x.%02x v%04x i%04x l%u\n", __func__,
  4895. + ctrl->bRequestType, ctrl->bRequest,
  4896. + le16_to_cpu(ctrl->wValue), w_index, w_length);
  4897. +
  4898. + if (value == -ERESTARTSYS)
  4899. + printk(KERN_ERR
  4900. + "%s: wain_event_interruptible fail...(0x%X)\n", __func__, ctrl->bRequest);
  4901. + return value;
  4902. +}
  4903. +
  4904. +static struct usb_function usb_func_mtp_tunnel = {
  4905. + .bind = mtp_tunnel_bind,
  4906. + .unbind = mtp_tunnel_unbind,
  4907. + .configure = mtp_tunnel_configure,
  4908. + .setup = mtp_tunnel_setup,
  4909. +
  4910. + .name = MTP_TUNNEL_FUNCTION_NAME,
  4911. + .context = &_context,
  4912. +
  4913. + .ifc_class = 0xFF,
  4914. + .ifc_subclass = 0xFF,
  4915. + .ifc_protocol = 0xFF,
  4916. +
  4917. + .ifc_name = MTP_TUNNEL_FUNCTION_NAME,
  4918. +
  4919. + .ifc_ept_count = 2,
  4920. + .ifc_ept_type = { EPT_BULK_OUT, EPT_BULK_IN },
  4921. +
  4922. + /* the mtp_tunnel function is only enabled when its driver file is open */
  4923. + .disabled = 1,
  4924. + .position_bit = USB_FUNCTION_MTP_TUNNEL_NUM,
  4925. + .ifc_num = 1,
  4926. +};
  4927. +
  4928. +static int __init mtp_tunnel_init(void)
  4929. +{
  4930. + struct mtp_tunnel_context *ctxt = &_context;
  4931. + int retval;
  4932. + DBG("mtp_tunnel_init()\n");
  4933. +
  4934. + init_waitqueue_head(&ctxt->read_wq);
  4935. + init_waitqueue_head(&ctxt->write_wq);
  4936. +
  4937. + atomic_set(&ctxt->open_excl, 0);
  4938. + atomic_set(&ctxt->read_excl, 0);
  4939. + atomic_set(&ctxt->write_excl, 0);
  4940. +
  4941. + atomic_set(&ctxt->enable_open_excl, 0);
  4942. + atomic_set(&ctxt->enable_read_excl, 0);
  4943. + atomic_set(&ctxt->enable_ioctl_excl, 0);
  4944. +
  4945. + spin_lock_init(&ctxt->lock);
  4946. +
  4947. + INIT_LIST_HEAD(&ctxt->rx_idle);
  4948. + INIT_LIST_HEAD(&ctxt->rx_done);
  4949. + INIT_LIST_HEAD(&ctxt->tx_idle);
  4950. + retval = platform_driver_register (&mtp_tunnel_driver);
  4951. + if (retval < 0)
  4952. + return retval;
  4953. + retval = platform_device_register (&mtp_tunnel_device_register);
  4954. + if (retval < 0)
  4955. + goto err_register_device;
  4956. +
  4957. + return usb_function_register(&usb_func_mtp_tunnel);
  4958. +
  4959. +err_register_device:
  4960. + platform_driver_unregister(&mtp_tunnel_driver);
  4961. + return retval;
  4962. +}
  4963. +
  4964. +module_init(mtp_tunnel_init);
  4965. diff -Naurp a/drivers/usb/function/ndis.h b/drivers/usb/function/ndis.h
  4966. --- a/drivers/usb/function/ndis.h 1970-01-01 01:00:00.000000000 +0100
  4967. +++ b/drivers/usb/function/ndis.h 2009-12-18 23:16:35.274489178 +0100
  4968. @@ -0,0 +1,217 @@
  4969. +/*
  4970. + * ndis.h
  4971. + *
  4972. + * ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de>
  4973. + *
  4974. + * Thanks to the cygwin development team,
  4975. + * espacially to Casper S. Hornstrup <chorns@users.sourceforge.net>
  4976. + *
  4977. + * THIS SOFTWARE IS NOT COPYRIGHTED
  4978. + *
  4979. + * This source code is offered for use in the public domain. You may
  4980. + * use, modify or distribute it freely.
  4981. + *
  4982. + * This code is distributed in the hope that it will be useful but
  4983. + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
  4984. + * DISCLAIMED. This includes but is not limited to warranties of
  4985. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  4986. + *
  4987. + */
  4988. +
  4989. +#ifndef _LINUX_NDIS_H
  4990. +#define _LINUX_NDIS_H
  4991. +
  4992. +
  4993. +#define NDIS_STATUS_MULTICAST_FULL 0xC0010009
  4994. +#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A
  4995. +#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B
  4996. +
  4997. +enum NDIS_DEVICE_POWER_STATE {
  4998. + NdisDeviceStateUnspecified = 0,
  4999. + NdisDeviceStateD0,
  5000. + NdisDeviceStateD1,
  5001. + NdisDeviceStateD2,
  5002. + NdisDeviceStateD3,
  5003. + NdisDeviceStateMaximum
  5004. +};
  5005. +
  5006. +struct NDIS_PM_WAKE_UP_CAPABILITIES {
  5007. + enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp;
  5008. + enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp;
  5009. + enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp;
  5010. +};
  5011. +
  5012. +/* NDIS_PNP_CAPABILITIES.Flags constants */
  5013. +#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001
  5014. +#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002
  5015. +#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004
  5016. +
  5017. +struct NDIS_PNP_CAPABILITIES {
  5018. + __le32 Flags;
  5019. + struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities;
  5020. +};
  5021. +
  5022. +struct NDIS_PM_PACKET_PATTERN {
  5023. + __le32 Priority;
  5024. + __le32 Reserved;
  5025. + __le32 MaskSize;
  5026. + __le32 PatternOffset;
  5027. + __le32 PatternSize;
  5028. + __le32 PatternFlags;
  5029. +};
  5030. +
  5031. +
  5032. +/* Required Object IDs (OIDs) */
  5033. +#define OID_GEN_SUPPORTED_LIST 0x00010101
  5034. +#define OID_GEN_HARDWARE_STATUS 0x00010102
  5035. +#define OID_GEN_MEDIA_SUPPORTED 0x00010103
  5036. +#define OID_GEN_MEDIA_IN_USE 0x00010104
  5037. +#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105
  5038. +#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106
  5039. +#define OID_GEN_LINK_SPEED 0x00010107
  5040. +#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108
  5041. +#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109
  5042. +#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A
  5043. +#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B
  5044. +#define OID_GEN_VENDOR_ID 0x0001010C
  5045. +#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D
  5046. +#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E
  5047. +#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F
  5048. +#define OID_GEN_DRIVER_VERSION 0x00010110
  5049. +#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111
  5050. +#define OID_GEN_PROTOCOL_OPTIONS 0x00010112
  5051. +#define OID_GEN_MAC_OPTIONS 0x00010113
  5052. +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
  5053. +#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115
  5054. +#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116
  5055. +#define OID_GEN_SUPPORTED_GUIDS 0x00010117
  5056. +#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118
  5057. +#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119
  5058. +#define OID_GEN_MACHINE_NAME 0x0001021A
  5059. +#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B
  5060. +#define OID_GEN_VLAN_ID 0x0001021C
  5061. +
  5062. +/* Optional OIDs */
  5063. +#define OID_GEN_MEDIA_CAPABILITIES 0x00010201
  5064. +#define OID_GEN_PHYSICAL_MEDIUM 0x00010202
  5065. +
  5066. +/* Required statistics OIDs */
  5067. +#define OID_GEN_XMIT_OK 0x00020101
  5068. +#define OID_GEN_RCV_OK 0x00020102
  5069. +#define OID_GEN_XMIT_ERROR 0x00020103
  5070. +#define OID_GEN_RCV_ERROR 0x00020104
  5071. +#define OID_GEN_RCV_NO_BUFFER 0x00020105
  5072. +
  5073. +/* Optional statistics OIDs */
  5074. +#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201
  5075. +#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
  5076. +#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203
  5077. +#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
  5078. +#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205
  5079. +#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
  5080. +#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207
  5081. +#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
  5082. +#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209
  5083. +#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
  5084. +#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B
  5085. +#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
  5086. +#define OID_GEN_RCV_CRC_ERROR 0x0002020D
  5087. +#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
  5088. +#define OID_GEN_GET_TIME_CAPS 0x0002020F
  5089. +#define OID_GEN_GET_NETCARD_TIME 0x00020210
  5090. +#define OID_GEN_NETCARD_LOAD 0x00020211
  5091. +#define OID_GEN_DEVICE_PROFILE 0x00020212
  5092. +#define OID_GEN_INIT_TIME_MS 0x00020213
  5093. +#define OID_GEN_RESET_COUNTS 0x00020214
  5094. +#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215
  5095. +#define OID_GEN_FRIENDLY_NAME 0x00020216
  5096. +#define OID_GEN_MINIPORT_INFO 0x00020217
  5097. +#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218
  5098. +
  5099. +/* IEEE 802.3 (Ethernet) OIDs */
  5100. +#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001
  5101. +
  5102. +#define OID_802_3_PERMANENT_ADDRESS 0x01010101
  5103. +#define OID_802_3_CURRENT_ADDRESS 0x01010102
  5104. +#define OID_802_3_MULTICAST_LIST 0x01010103
  5105. +#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104
  5106. +#define OID_802_3_MAC_OPTIONS 0x01010105
  5107. +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
  5108. +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
  5109. +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
  5110. +#define OID_802_3_XMIT_DEFERRED 0x01020201
  5111. +#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
  5112. +#define OID_802_3_RCV_OVERRUN 0x01020203
  5113. +#define OID_802_3_XMIT_UNDERRUN 0x01020204
  5114. +#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205
  5115. +#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
  5116. +#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
  5117. +
  5118. +/* OID_GEN_MINIPORT_INFO constants */
  5119. +#define NDIS_MINIPORT_BUS_MASTER 0x00000001
  5120. +#define NDIS_MINIPORT_WDM_DRIVER 0x00000002
  5121. +#define NDIS_MINIPORT_SG_LIST 0x00000004
  5122. +#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008
  5123. +#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010
  5124. +#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020
  5125. +#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040
  5126. +#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080
  5127. +#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100
  5128. +#define NDIS_MINIPORT_IS_NDIS_5 0x00000200
  5129. +#define NDIS_MINIPORT_IS_CO 0x00000400
  5130. +#define NDIS_MINIPORT_DESERIALIZE 0x00000800
  5131. +#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000
  5132. +#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000
  5133. +#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000
  5134. +#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000
  5135. +#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000
  5136. +#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000
  5137. +#define NDIS_MINIPORT_HIDDEN 0x00040000
  5138. +#define NDIS_MINIPORT_SWENUM 0x00080000
  5139. +#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000
  5140. +#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000
  5141. +#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000
  5142. +#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000
  5143. +#define NDIS_MINIPORT_64BITS_DMA 0x01000000
  5144. +
  5145. +#define NDIS_MEDIUM_802_3 0x00000000
  5146. +#define NDIS_MEDIUM_802_5 0x00000001
  5147. +#define NDIS_MEDIUM_FDDI 0x00000002
  5148. +#define NDIS_MEDIUM_WAN 0x00000003
  5149. +#define NDIS_MEDIUM_LOCAL_TALK 0x00000004
  5150. +#define NDIS_MEDIUM_DIX 0x00000005
  5151. +#define NDIS_MEDIUM_ARCENT_RAW 0x00000006
  5152. +#define NDIS_MEDIUM_ARCENT_878_2 0x00000007
  5153. +#define NDIS_MEDIUM_ATM 0x00000008
  5154. +#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009
  5155. +#define NDIS_MEDIUM_IRDA 0x0000000A
  5156. +#define NDIS_MEDIUM_BPC 0x0000000B
  5157. +#define NDIS_MEDIUM_CO_WAN 0x0000000C
  5158. +#define NDIS_MEDIUM_1394 0x0000000D
  5159. +
  5160. +#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
  5161. +#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
  5162. +#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
  5163. +#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
  5164. +#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
  5165. +#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
  5166. +#define NDIS_PACKET_TYPE_SMT 0x00000040
  5167. +#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
  5168. +#define NDIS_PACKET_TYPE_GROUP 0x00000100
  5169. +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200
  5170. +#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400
  5171. +#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800
  5172. +
  5173. +#define NDIS_MEDIA_STATE_CONNECTED 0x00000000
  5174. +#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001
  5175. +
  5176. +#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001
  5177. +#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002
  5178. +#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004
  5179. +#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008
  5180. +#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010
  5181. +#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020
  5182. +#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040
  5183. +#define NDIS_MAC_OPTION_RESERVED 0x80000000
  5184. +
  5185. +#endif /* _LINUX_NDIS_H */
  5186. diff -Naurp a/drivers/usb/function/null.c b/drivers/usb/function/null.c
  5187. --- a/drivers/usb/function/null.c 2009-12-18 22:10:56.331465000 +0100
  5188. +++ b/drivers/usb/function/null.c 2009-12-18 22:11:02.699472440 +0100
  5189. @@ -106,6 +106,8 @@ static struct usb_function usb_func_null
  5190.  
  5191. .ifc_ept_count = 1,
  5192. .ifc_ept_type = { EPT_BULK_OUT },
  5193. +
  5194. + .position_bit = USB_FUNCTION_NULL_NUM,
  5195. };
  5196.  
  5197. static int __init null_init(void)
  5198. diff -Naurp a/drivers/usb/function/rndis.c b/drivers/usb/function/rndis.c
  5199. --- a/drivers/usb/function/rndis.c 1970-01-01 01:00:00.000000000 +0100
  5200. +++ b/drivers/usb/function/rndis.c 2009-12-18 23:16:54.619476954 +0100
  5201. @@ -0,0 +1,1455 @@
  5202. +/*
  5203. + * RNDIS MSG parser
  5204. + *
  5205. + * Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $
  5206. + *
  5207. + * Authors: Benedikt Spranger, Pengutronix
  5208. + * Robert Schwebel, Pengutronix
  5209. + *
  5210. + * This program is free software; you can redistribute it and/or
  5211. + * modify it under the terms of the GNU General Public License
  5212. + * version 2, as published by the Free Software Foundation.
  5213. + *
  5214. + * This software was originally developed in conformance with
  5215. + * Microsoft's Remote NDIS Specification License Agreement.
  5216. + *
  5217. + * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
  5218. + * Fixed message length bug in init_response
  5219. + *
  5220. + * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
  5221. + * Fixed rndis_rm_hdr length bug.
  5222. + *
  5223. + * Copyright (C) 2004 by David Brownell
  5224. + * updates to merge with Linux 2.6, better match RNDIS spec
  5225. + */
  5226. +
  5227. +#include <linux/module.h>
  5228. +#include <linux/moduleparam.h>
  5229. +#include <linux/kernel.h>
  5230. +#include <linux/errno.h>
  5231. +#include <linux/init.h>
  5232. +#include <linux/list.h>
  5233. +#include <linux/proc_fs.h>
  5234. +#include <linux/netdevice.h>
  5235. +
  5236. +#include <asm/io.h>
  5237. +#include <asm/byteorder.h>
  5238. +#include <asm/system.h>
  5239. +#include <asm/unaligned.h>
  5240. +
  5241. +
  5242. +#undef RNDIS_PM
  5243. +#undef RNDIS_WAKEUP
  5244. +#undef VERBOSE
  5245. +
  5246. +#include "rndis.h"
  5247. +
  5248. +
  5249. +/* The driver for your USB chip needs to support ep0 OUT to work with
  5250. + * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
  5251. + *
  5252. + * Windows hosts need an INF file like Documentation/usb/linux.inf
  5253. + * and will be happier if you provide the host_addr module parameter.
  5254. + */
  5255. +
  5256. +#if 0
  5257. +static int rndis_debug = 0;
  5258. +module_param (rndis_debug, int, 0);
  5259. +MODULE_PARM_DESC (rndis_debug, "enable debugging");
  5260. +#else
  5261. +#define rndis_debug 0
  5262. +#endif
  5263. +
  5264. +#define DBG(str,args...) do { \
  5265. + if (rndis_debug) \
  5266. + pr_debug(str , ## args); \
  5267. + } while (0)
  5268. +
  5269. +#define RNDIS_MAX_CONFIGS 1
  5270. +
  5271. +
  5272. +static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
  5273. +
  5274. +/* Driver Version */
  5275. +static const __le32 rndis_driver_version = __constant_cpu_to_le32 (1);
  5276. +
  5277. +/* Function Prototypes */
  5278. +static rndis_resp_t *rndis_add_response (int configNr, u32 length);
  5279. +
  5280. +
  5281. +/* supported OIDs */
  5282. +static const u32 oid_supported_list [] =
  5283. +{
  5284. + /* the general stuff */
  5285. + OID_GEN_SUPPORTED_LIST,
  5286. + OID_GEN_HARDWARE_STATUS,
  5287. + OID_GEN_MEDIA_SUPPORTED,
  5288. + OID_GEN_MEDIA_IN_USE,
  5289. + OID_GEN_MAXIMUM_FRAME_SIZE,
  5290. + OID_GEN_LINK_SPEED,
  5291. + OID_GEN_TRANSMIT_BLOCK_SIZE,
  5292. + OID_GEN_RECEIVE_BLOCK_SIZE,
  5293. + OID_GEN_VENDOR_ID,
  5294. + OID_GEN_VENDOR_DESCRIPTION,
  5295. + OID_GEN_VENDOR_DRIVER_VERSION,
  5296. + OID_GEN_CURRENT_PACKET_FILTER,
  5297. + OID_GEN_MAXIMUM_TOTAL_SIZE,
  5298. + OID_GEN_MEDIA_CONNECT_STATUS,
  5299. + OID_GEN_PHYSICAL_MEDIUM,
  5300. +#if 0
  5301. + OID_GEN_RNDIS_CONFIG_PARAMETER,
  5302. +#endif
  5303. +
  5304. + /* the statistical stuff */
  5305. + OID_GEN_XMIT_OK,
  5306. + OID_GEN_RCV_OK,
  5307. + OID_GEN_XMIT_ERROR,
  5308. + OID_GEN_RCV_ERROR,
  5309. + OID_GEN_RCV_NO_BUFFER,
  5310. +#ifdef RNDIS_OPTIONAL_STATS
  5311. + OID_GEN_DIRECTED_BYTES_XMIT,
  5312. + OID_GEN_DIRECTED_FRAMES_XMIT,
  5313. + OID_GEN_MULTICAST_BYTES_XMIT,
  5314. + OID_GEN_MULTICAST_FRAMES_XMIT,
  5315. + OID_GEN_BROADCAST_BYTES_XMIT,
  5316. + OID_GEN_BROADCAST_FRAMES_XMIT,
  5317. + OID_GEN_DIRECTED_BYTES_RCV,
  5318. + OID_GEN_DIRECTED_FRAMES_RCV,
  5319. + OID_GEN_MULTICAST_BYTES_RCV,
  5320. + OID_GEN_MULTICAST_FRAMES_RCV,
  5321. + OID_GEN_BROADCAST_BYTES_RCV,
  5322. + OID_GEN_BROADCAST_FRAMES_RCV,
  5323. + OID_GEN_RCV_CRC_ERROR,
  5324. + OID_GEN_TRANSMIT_QUEUE_LENGTH,
  5325. +#endif /* RNDIS_OPTIONAL_STATS */
  5326. +
  5327. + /* mandatory 802.3 */
  5328. + /* the general stuff */
  5329. + OID_802_3_PERMANENT_ADDRESS,
  5330. + OID_802_3_CURRENT_ADDRESS,
  5331. + OID_802_3_MULTICAST_LIST,
  5332. + OID_802_3_MAC_OPTIONS,
  5333. + OID_802_3_MAXIMUM_LIST_SIZE,
  5334. +
  5335. + /* the statistical stuff */
  5336. + OID_802_3_RCV_ERROR_ALIGNMENT,
  5337. + OID_802_3_XMIT_ONE_COLLISION,
  5338. + OID_802_3_XMIT_MORE_COLLISIONS,
  5339. +#ifdef RNDIS_OPTIONAL_STATS
  5340. + OID_802_3_XMIT_DEFERRED,
  5341. + OID_802_3_XMIT_MAX_COLLISIONS,
  5342. + OID_802_3_RCV_OVERRUN,
  5343. + OID_802_3_XMIT_UNDERRUN,
  5344. + OID_802_3_XMIT_HEARTBEAT_FAILURE,
  5345. + OID_802_3_XMIT_TIMES_CRS_LOST,
  5346. + OID_802_3_XMIT_LATE_COLLISIONS,
  5347. +#endif /* RNDIS_OPTIONAL_STATS */
  5348. +
  5349. +#ifdef RNDIS_PM
  5350. + /* PM and wakeup are mandatory for USB: */
  5351. +
  5352. + /* power management */
  5353. + OID_PNP_CAPABILITIES,
  5354. + OID_PNP_QUERY_POWER,
  5355. + OID_PNP_SET_POWER,
  5356. +
  5357. +#ifdef RNDIS_WAKEUP
  5358. + /* wake up host */
  5359. + OID_PNP_ENABLE_WAKE_UP,
  5360. + OID_PNP_ADD_WAKE_UP_PATTERN,
  5361. + OID_PNP_REMOVE_WAKE_UP_PATTERN,
  5362. +#endif /* RNDIS_WAKEUP */
  5363. +#endif /* RNDIS_PM */
  5364. +};
  5365. +
  5366. +
  5367. +/* NDIS Functions */
  5368. +static int
  5369. +gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
  5370. + rndis_resp_t *r)
  5371. +{
  5372. + int retval = -ENOTSUPP;
  5373. + u32 length = 4; /* usually */
  5374. + __le32 *outbuf;
  5375. + int i, count;
  5376. + rndis_query_cmplt_type *resp;
  5377. +
  5378. + if (!r) return -ENOMEM;
  5379. + resp = (rndis_query_cmplt_type *) r->buf;
  5380. +
  5381. + if (!resp) return -ENOMEM;
  5382. +
  5383. + if (buf_len && rndis_debug > 1) {
  5384. + DBG("query OID %08x value, len %d:\n", OID, buf_len);
  5385. + for (i = 0; i < buf_len; i += 16) {
  5386. + DBG("%03d: %08x %08x %08x %08x\n", i,
  5387. + le32_to_cpu(get_unaligned((__le32 *)
  5388. + &buf[i])),
  5389. + le32_to_cpu(get_unaligned((__le32 *)
  5390. + &buf[i + 4])),
  5391. + le32_to_cpu(get_unaligned((__le32 *)
  5392. + &buf[i + 8])),
  5393. + le32_to_cpu(get_unaligned((__le32 *)
  5394. + &buf[i + 12])));
  5395. + }
  5396. + }
  5397. +
  5398. + /* response goes here, right after the header */
  5399. + outbuf = (__le32 *) &resp[1];
  5400. + resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
  5401. +
  5402. + switch (OID) {
  5403. +
  5404. + /* general oids (table 4-1) */
  5405. +
  5406. + /* mandatory */
  5407. + case OID_GEN_SUPPORTED_LIST:
  5408. + DBG("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
  5409. + length = sizeof (oid_supported_list);
  5410. + count = length / sizeof (u32);
  5411. + for (i = 0; i < count; i++)
  5412. + outbuf[i] = cpu_to_le32 (oid_supported_list[i]);
  5413. + retval = 0;
  5414. + break;
  5415. +
  5416. + /* mandatory */
  5417. + case OID_GEN_HARDWARE_STATUS:
  5418. + DBG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
  5419. + /* Bogus question!
  5420. + * Hardware must be ready to receive high level protocols.
  5421. + * BTW:
  5422. + * reddite ergo quae sunt Caesaris Caesari
  5423. + * et quae sunt Dei Deo!
  5424. + */
  5425. + *outbuf = __constant_cpu_to_le32 (0);
  5426. + retval = 0;
  5427. + break;
  5428. +
  5429. + /* mandatory */
  5430. + case OID_GEN_MEDIA_SUPPORTED:
  5431. + DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
  5432. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
  5433. + retval = 0;
  5434. + break;
  5435. +
  5436. + /* mandatory */
  5437. + case OID_GEN_MEDIA_IN_USE:
  5438. + DBG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
  5439. + /* one medium, one transport... (maybe you do it better) */
  5440. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
  5441. + retval = 0;
  5442. + break;
  5443. +
  5444. + /* mandatory */
  5445. + case OID_GEN_MAXIMUM_FRAME_SIZE:
  5446. + DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
  5447. + if (rndis_per_dev_params [configNr].dev) {
  5448. + *outbuf = cpu_to_le32 (
  5449. + rndis_per_dev_params [configNr].dev->mtu);
  5450. + retval = 0;
  5451. + }
  5452. + break;
  5453. +
  5454. + /* mandatory */
  5455. + case OID_GEN_LINK_SPEED:
  5456. + if (rndis_debug > 1)
  5457. + DBG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
  5458. + if (rndis_per_dev_params [configNr].media_state
  5459. + == NDIS_MEDIA_STATE_DISCONNECTED)
  5460. + *outbuf = __constant_cpu_to_le32 (0);
  5461. + else
  5462. + *outbuf = cpu_to_le32 (
  5463. + rndis_per_dev_params [configNr].speed);
  5464. + retval = 0;
  5465. + break;
  5466. +
  5467. + /* mandatory */
  5468. + case OID_GEN_TRANSMIT_BLOCK_SIZE:
  5469. + DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
  5470. + if (rndis_per_dev_params [configNr].dev) {
  5471. + *outbuf = cpu_to_le32 (
  5472. + rndis_per_dev_params [configNr].dev->mtu);
  5473. + retval = 0;
  5474. + }
  5475. + break;
  5476. +
  5477. + /* mandatory */
  5478. + case OID_GEN_RECEIVE_BLOCK_SIZE:
  5479. + DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
  5480. + if (rndis_per_dev_params [configNr].dev) {
  5481. + *outbuf = cpu_to_le32 (
  5482. + rndis_per_dev_params [configNr].dev->mtu);
  5483. + retval = 0;
  5484. + }
  5485. + break;
  5486. +
  5487. + /* mandatory */
  5488. + case OID_GEN_VENDOR_ID:
  5489. + DBG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
  5490. + *outbuf = cpu_to_le32 (
  5491. + rndis_per_dev_params [configNr].vendorID);
  5492. + retval = 0;
  5493. + break;
  5494. +
  5495. + /* mandatory */
  5496. + case OID_GEN_VENDOR_DESCRIPTION:
  5497. + DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
  5498. + length = strlen (rndis_per_dev_params [configNr].vendorDescr);
  5499. + memcpy (outbuf,
  5500. + rndis_per_dev_params [configNr].vendorDescr, length);
  5501. + retval = 0;
  5502. + break;
  5503. +
  5504. + case OID_GEN_VENDOR_DRIVER_VERSION:
  5505. + DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
  5506. + /* Created as LE */
  5507. + *outbuf = rndis_driver_version;
  5508. + retval = 0;
  5509. + break;
  5510. +
  5511. + /* mandatory */
  5512. + case OID_GEN_CURRENT_PACKET_FILTER:
  5513. + DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
  5514. + *outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
  5515. + retval = 0;
  5516. + break;
  5517. +
  5518. + /* mandatory */
  5519. + case OID_GEN_MAXIMUM_TOTAL_SIZE:
  5520. + DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
  5521. + *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
  5522. + retval = 0;
  5523. + break;
  5524. +
  5525. + /* mandatory */
  5526. + case OID_GEN_MEDIA_CONNECT_STATUS:
  5527. + if (rndis_debug > 1)
  5528. + DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
  5529. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5530. + .media_state);
  5531. + retval = 0;
  5532. + break;
  5533. +
  5534. + case OID_GEN_PHYSICAL_MEDIUM:
  5535. + DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
  5536. + *outbuf = __constant_cpu_to_le32 (0);
  5537. + retval = 0;
  5538. + break;
  5539. +
  5540. + /* The RNDIS specification is incomplete/wrong. Some versions
  5541. + * of MS-Windows expect OIDs that aren't specified there. Other
  5542. + * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
  5543. + */
  5544. + case OID_GEN_MAC_OPTIONS: /* from WinME */
  5545. + DBG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
  5546. + *outbuf = __constant_cpu_to_le32(
  5547. + NDIS_MAC_OPTION_RECEIVE_SERIALIZED
  5548. + | NDIS_MAC_OPTION_FULL_DUPLEX);
  5549. + retval = 0;
  5550. + break;
  5551. +
  5552. + /* statistics OIDs (table 4-2) */
  5553. +
  5554. + /* mandatory */
  5555. + case OID_GEN_XMIT_OK:
  5556. + if (rndis_debug > 1)
  5557. + DBG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
  5558. + if (rndis_per_dev_params [configNr].stats) {
  5559. + *outbuf = cpu_to_le32 (
  5560. + rndis_per_dev_params [configNr].stats->tx_packets -
  5561. + rndis_per_dev_params [configNr].stats->tx_errors -
  5562. + rndis_per_dev_params [configNr].stats->tx_dropped);
  5563. + retval = 0;
  5564. + }
  5565. + break;
  5566. +
  5567. + /* mandatory */
  5568. + case OID_GEN_RCV_OK:
  5569. + if (rndis_debug > 1)
  5570. + DBG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
  5571. + if (rndis_per_dev_params [configNr].stats) {
  5572. + *outbuf = cpu_to_le32 (
  5573. + rndis_per_dev_params [configNr].stats->rx_packets -
  5574. + rndis_per_dev_params [configNr].stats->rx_errors -
  5575. + rndis_per_dev_params [configNr].stats->rx_dropped);
  5576. + retval = 0;
  5577. + }
  5578. + break;
  5579. +
  5580. + /* mandatory */
  5581. + case OID_GEN_XMIT_ERROR:
  5582. + if (rndis_debug > 1)
  5583. + DBG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
  5584. + if (rndis_per_dev_params [configNr].stats) {
  5585. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5586. + .stats->tx_errors);
  5587. + retval = 0;
  5588. + }
  5589. + break;
  5590. +
  5591. + /* mandatory */
  5592. + case OID_GEN_RCV_ERROR:
  5593. + if (rndis_debug > 1)
  5594. + DBG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
  5595. + if (rndis_per_dev_params [configNr].stats) {
  5596. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5597. + .stats->rx_errors);
  5598. + retval = 0;
  5599. + }
  5600. + break;
  5601. +
  5602. + /* mandatory */
  5603. + case OID_GEN_RCV_NO_BUFFER:
  5604. + DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
  5605. + if (rndis_per_dev_params [configNr].stats) {
  5606. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5607. + .stats->rx_dropped);
  5608. + retval = 0;
  5609. + }
  5610. + break;
  5611. +
  5612. +#ifdef RNDIS_OPTIONAL_STATS
  5613. + case OID_GEN_DIRECTED_BYTES_XMIT:
  5614. + DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
  5615. + /*
  5616. + * Aunt Tilly's size of shoes
  5617. + * minus antarctica count of penguins
  5618. + * divided by weight of Alpha Centauri
  5619. + */
  5620. + if (rndis_per_dev_params [configNr].stats) {
  5621. + *outbuf = cpu_to_le32 (
  5622. + (rndis_per_dev_params [configNr]
  5623. + .stats->tx_packets -
  5624. + rndis_per_dev_params [configNr]
  5625. + .stats->tx_errors -
  5626. + rndis_per_dev_params [configNr]
  5627. + .stats->tx_dropped)
  5628. + * 123);
  5629. + retval = 0;
  5630. + }
  5631. + break;
  5632. +
  5633. + case OID_GEN_DIRECTED_FRAMES_XMIT:
  5634. + DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
  5635. + /* dito */
  5636. + if (rndis_per_dev_params [configNr].stats) {
  5637. + *outbuf = cpu_to_le32 (
  5638. + (rndis_per_dev_params [configNr]
  5639. + .stats->tx_packets -
  5640. + rndis_per_dev_params [configNr]
  5641. + .stats->tx_errors -
  5642. + rndis_per_dev_params [configNr]
  5643. + .stats->tx_dropped)
  5644. + / 123);
  5645. + retval = 0;
  5646. + }
  5647. + break;
  5648. +
  5649. + case OID_GEN_MULTICAST_BYTES_XMIT:
  5650. + DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
  5651. + if (rndis_per_dev_params [configNr].stats) {
  5652. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5653. + .stats->multicast*1234);
  5654. + retval = 0;
  5655. + }
  5656. + break;
  5657. +
  5658. + case OID_GEN_MULTICAST_FRAMES_XMIT:
  5659. + DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
  5660. + if (rndis_per_dev_params [configNr].stats) {
  5661. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5662. + .stats->multicast);
  5663. + retval = 0;
  5664. + }
  5665. + break;
  5666. +
  5667. + case OID_GEN_BROADCAST_BYTES_XMIT:
  5668. + DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
  5669. + if (rndis_per_dev_params [configNr].stats) {
  5670. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5671. + .stats->tx_packets/42*255);
  5672. + retval = 0;
  5673. + }
  5674. + break;
  5675. +
  5676. + case OID_GEN_BROADCAST_FRAMES_XMIT:
  5677. + DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
  5678. + if (rndis_per_dev_params [configNr].stats) {
  5679. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5680. + .stats->tx_packets/42);
  5681. + retval = 0;
  5682. + }
  5683. + break;
  5684. +
  5685. + case OID_GEN_DIRECTED_BYTES_RCV:
  5686. + DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
  5687. + *outbuf = __constant_cpu_to_le32 (0);
  5688. + retval = 0;
  5689. + break;
  5690. +
  5691. + case OID_GEN_DIRECTED_FRAMES_RCV:
  5692. + DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
  5693. + *outbuf = __constant_cpu_to_le32 (0);
  5694. + retval = 0;
  5695. + break;
  5696. +
  5697. + case OID_GEN_MULTICAST_BYTES_RCV:
  5698. + DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
  5699. + if (rndis_per_dev_params [configNr].stats) {
  5700. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5701. + .stats->multicast * 1111);
  5702. + retval = 0;
  5703. + }
  5704. + break;
  5705. +
  5706. + case OID_GEN_MULTICAST_FRAMES_RCV:
  5707. + DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
  5708. + if (rndis_per_dev_params [configNr].stats) {
  5709. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5710. + .stats->multicast);
  5711. + retval = 0;
  5712. + }
  5713. + break;
  5714. +
  5715. + case OID_GEN_BROADCAST_BYTES_RCV:
  5716. + DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
  5717. + if (rndis_per_dev_params [configNr].stats) {
  5718. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5719. + .stats->rx_packets/42*255);
  5720. + retval = 0;
  5721. + }
  5722. + break;
  5723. +
  5724. + case OID_GEN_BROADCAST_FRAMES_RCV:
  5725. + DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
  5726. + if (rndis_per_dev_params [configNr].stats) {
  5727. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5728. + .stats->rx_packets/42);
  5729. + retval = 0;
  5730. + }
  5731. + break;
  5732. +
  5733. + case OID_GEN_RCV_CRC_ERROR:
  5734. + DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
  5735. + if (rndis_per_dev_params [configNr].stats) {
  5736. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5737. + .stats->rx_crc_errors);
  5738. + retval = 0;
  5739. + }
  5740. + break;
  5741. +
  5742. + case OID_GEN_TRANSMIT_QUEUE_LENGTH:
  5743. + DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
  5744. + *outbuf = __constant_cpu_to_le32 (0);
  5745. + retval = 0;
  5746. + break;
  5747. +#endif /* RNDIS_OPTIONAL_STATS */
  5748. +
  5749. + /* ieee802.3 OIDs (table 4-3) */
  5750. +
  5751. + /* mandatory */
  5752. + case OID_802_3_PERMANENT_ADDRESS:
  5753. + DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
  5754. + if (rndis_per_dev_params [configNr].dev) {
  5755. + length = ETH_ALEN;
  5756. + memcpy (outbuf,
  5757. + rndis_per_dev_params [configNr].host_mac,
  5758. + length);
  5759. + retval = 0;
  5760. + }
  5761. + break;
  5762. +
  5763. + /* mandatory */
  5764. + case OID_802_3_CURRENT_ADDRESS:
  5765. + DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
  5766. + if (rndis_per_dev_params [configNr].dev) {
  5767. + length = ETH_ALEN;
  5768. + memcpy (outbuf,
  5769. + rndis_per_dev_params [configNr].host_mac,
  5770. + length);
  5771. + retval = 0;
  5772. + }
  5773. + break;
  5774. +
  5775. + /* mandatory */
  5776. + case OID_802_3_MULTICAST_LIST:
  5777. + DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
  5778. + /* Multicast base address only */
  5779. + *outbuf = __constant_cpu_to_le32 (0xE0000000);
  5780. + retval = 0;
  5781. + break;
  5782. +
  5783. + /* mandatory */
  5784. + case OID_802_3_MAXIMUM_LIST_SIZE:
  5785. + DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
  5786. + /* Multicast base address only */
  5787. + *outbuf = __constant_cpu_to_le32 (1);
  5788. + retval = 0;
  5789. + break;
  5790. +
  5791. + case OID_802_3_MAC_OPTIONS:
  5792. + DBG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
  5793. + break;
  5794. +
  5795. + /* ieee802.3 statistics OIDs (table 4-4) */
  5796. +
  5797. + /* mandatory */
  5798. + case OID_802_3_RCV_ERROR_ALIGNMENT:
  5799. + DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
  5800. + if (rndis_per_dev_params [configNr].stats) {
  5801. + *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
  5802. + .stats->rx_frame_errors);
  5803. + retval = 0;
  5804. + }
  5805. + break;
  5806. +
  5807. + /* mandatory */
  5808. + case OID_802_3_XMIT_ONE_COLLISION:
  5809. + DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
  5810. + *outbuf = __constant_cpu_to_le32 (0);
  5811. + retval = 0;
  5812. + break;
  5813. +
  5814. + /* mandatory */
  5815. + case OID_802_3_XMIT_MORE_COLLISIONS:
  5816. + DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
  5817. + *outbuf = __constant_cpu_to_le32 (0);
  5818. + retval = 0;
  5819. + break;
  5820. +
  5821. +#ifdef RNDIS_OPTIONAL_STATS
  5822. + case OID_802_3_XMIT_DEFERRED:
  5823. + DBG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
  5824. + /* TODO */
  5825. + break;
  5826. +
  5827. + case OID_802_3_XMIT_MAX_COLLISIONS:
  5828. + DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__);
  5829. + /* TODO */
  5830. + break;
  5831. +
  5832. + case OID_802_3_RCV_OVERRUN:
  5833. + DBG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__);
  5834. + /* TODO */
  5835. + break;
  5836. +
  5837. + case OID_802_3_XMIT_UNDERRUN:
  5838. + DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__);
  5839. + /* TODO */
  5840. + break;
  5841. +
  5842. + case OID_802_3_XMIT_HEARTBEAT_FAILURE:
  5843. + DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__);
  5844. + /* TODO */
  5845. + break;
  5846. +
  5847. + case OID_802_3_XMIT_TIMES_CRS_LOST:
  5848. + DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__);
  5849. + /* TODO */
  5850. + break;
  5851. +
  5852. + case OID_802_3_XMIT_LATE_COLLISIONS:
  5853. + DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
  5854. + /* TODO */
  5855. + break;
  5856. +#endif /* RNDIS_OPTIONAL_STATS */
  5857. +
  5858. +#ifdef RNDIS_PM
  5859. + /* power management OIDs (table 4-5) */
  5860. + case OID_PNP_CAPABILITIES:
  5861. + DBG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__);
  5862. +
  5863. + /* for now, no wakeup capabilities */
  5864. + length = sizeof (struct NDIS_PNP_CAPABILITIES);
  5865. + memset(outbuf, 0, length);
  5866. + retval = 0;
  5867. + break;
  5868. + case OID_PNP_QUERY_POWER:
  5869. + DBG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__,
  5870. + le32_to_cpu(get_unaligned((__le32 *)buf)) - 1);
  5871. + /* only suspend is a real power state, and
  5872. + * it can't be entered by OID_PNP_SET_POWER...
  5873. + */
  5874. + length = 0;
  5875. + retval = 0;
  5876. + break;
  5877. +#endif
  5878. +
  5879. + default:
  5880. + pr_warning("%s: query unknown OID 0x%08X\n",
  5881. + __FUNCTION__, OID);
  5882. + }
  5883. + if (retval < 0)
  5884. + length = 0;
  5885. +
  5886. + resp->InformationBufferLength = cpu_to_le32 (length);
  5887. + r->length = length + sizeof *resp;
  5888. + resp->MessageLength = cpu_to_le32 (r->length);
  5889. + return retval;
  5890. +}
  5891. +
  5892. +static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
  5893. + rndis_resp_t *r)
  5894. +{
  5895. + rndis_set_cmplt_type *resp;
  5896. + int i, retval = -ENOTSUPP;
  5897. + struct rndis_params *params;
  5898. +
  5899. + if (!r)
  5900. + return -ENOMEM;
  5901. + resp = (rndis_set_cmplt_type *) r->buf;
  5902. + if (!resp)
  5903. + return -ENOMEM;
  5904. +
  5905. + if (buf_len && rndis_debug > 1) {
  5906. + DBG("set OID %08x value, len %d:\n", OID, buf_len);
  5907. + for (i = 0; i < buf_len; i += 16) {
  5908. + DBG("%03d: %08x %08x %08x %08x\n", i,
  5909. + le32_to_cpu(get_unaligned((__le32 *)
  5910. + &buf[i])),
  5911. + le32_to_cpu(get_unaligned((__le32 *)
  5912. + &buf[i + 4])),
  5913. + le32_to_cpu(get_unaligned((__le32 *)
  5914. + &buf[i + 8])),
  5915. + le32_to_cpu(get_unaligned((__le32 *)
  5916. + &buf[i + 12])));
  5917. + }
  5918. + }
  5919. +
  5920. + params = &rndis_per_dev_params [configNr];
  5921. + switch (OID) {
  5922. + case OID_GEN_CURRENT_PACKET_FILTER:
  5923. +
  5924. + /* these NDIS_PACKET_TYPE_* bitflags are shared with
  5925. + * cdc_filter; it's not RNDIS-specific
  5926. + * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
  5927. + * PROMISCUOUS, DIRECTED,
  5928. + * MULTICAST, ALL_MULTICAST, BROADCAST
  5929. + */
  5930. + *params->filter = (u16) le32_to_cpu(get_unaligned(
  5931. + (__le32 *)buf));
  5932. + DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
  5933. + __FUNCTION__, *params->filter);
  5934. +
  5935. + /* this call has a significant side effect: it's
  5936. + * what makes the packet flow start and stop, like
  5937. + * activating the CDC Ethernet altsetting.
  5938. + */
  5939. +#ifdef RNDIS_PM
  5940. +update_linkstate:
  5941. +#endif
  5942. + retval = 0;
  5943. + if (*params->filter) {
  5944. + params->state = RNDIS_DATA_INITIALIZED;
  5945. + netif_carrier_on(params->dev);
  5946. + if (netif_running(params->dev))
  5947. + netif_wake_queue (params->dev);
  5948. + } else {
  5949. + params->state = RNDIS_INITIALIZED;
  5950. + netif_carrier_off (params->dev);
  5951. + netif_stop_queue (params->dev);
  5952. + }
  5953. + break;
  5954. +
  5955. + case OID_802_3_MULTICAST_LIST:
  5956. + /* I think we can ignore this */
  5957. + DBG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
  5958. + retval = 0;
  5959. + break;
  5960. +#if 0
  5961. + case OID_GEN_RNDIS_CONFIG_PARAMETER:
  5962. + {
  5963. + struct rndis_config_parameter *param;
  5964. + param = (struct rndis_config_parameter *) buf;
  5965. + DBG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
  5966. + __FUNCTION__,
  5967. + min(cpu_to_le32(param->ParameterNameLength),80),
  5968. + buf + param->ParameterNameOffset);
  5969. + retval = 0;
  5970. + }
  5971. + break;
  5972. +#endif
  5973. +
  5974. +#ifdef RNDIS_PM
  5975. + case OID_PNP_SET_POWER:
  5976. + /* The only real power state is USB suspend, and RNDIS requests
  5977. + * can't enter it; this one isn't really about power. After
  5978. + * resuming, Windows forces a reset, and then SET_POWER D0.
  5979. + * FIXME ... then things go batty; Windows wedges itself.
  5980. + */
  5981. + i = le32_to_cpu(get_unaligned((__le32 *)buf));
  5982. + DBG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1);
  5983. + switch (i) {
  5984. + case NdisDeviceStateD0:
  5985. + *params->filter = params->saved_filter;
  5986. + goto update_linkstate;
  5987. + case NdisDeviceStateD3:
  5988. + case NdisDeviceStateD2:
  5989. + case NdisDeviceStateD1:
  5990. + params->saved_filter = *params->filter;
  5991. + retval = 0;
  5992. + break;
  5993. + }
  5994. + break;
  5995. +
  5996. +#ifdef RNDIS_WAKEUP
  5997. + // no wakeup support advertised, so wakeup OIDs always fail:
  5998. + // - OID_PNP_ENABLE_WAKE_UP
  5999. + // - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN
  6000. +#endif
  6001. +
  6002. +#endif /* RNDIS_PM */
  6003. +
  6004. + default:
  6005. + pr_warning("%s: set unknown OID 0x%08X, size %d\n",
  6006. + __FUNCTION__, OID, buf_len);
  6007. + }
  6008. +
  6009. + return retval;
  6010. +}
  6011. +
  6012. +/*
  6013. + * Response Functions
  6014. + */
  6015. +
  6016. +static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
  6017. +{
  6018. + rndis_init_cmplt_type *resp;
  6019. + rndis_resp_t *r;
  6020. +
  6021. + if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
  6022. +
  6023. + r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
  6024. + if (!r)
  6025. + return -ENOMEM;
  6026. + resp = (rndis_init_cmplt_type *) r->buf;
  6027. +
  6028. + resp->MessageType = __constant_cpu_to_le32 (
  6029. + REMOTE_NDIS_INITIALIZE_CMPLT);
  6030. + resp->MessageLength = __constant_cpu_to_le32 (52);
  6031. + resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
  6032. + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
  6033. + resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION);
  6034. + resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION);
  6035. + resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);
  6036. + resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3);
  6037. + resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1);
  6038. + resp->MaxTransferSize = cpu_to_le32 (
  6039. + rndis_per_dev_params [configNr].dev->mtu
  6040. + + sizeof (struct ethhdr)
  6041. + + sizeof (struct rndis_packet_msg_type)
  6042. + + 22);
  6043. + resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0);
  6044. + resp->AFListOffset = __constant_cpu_to_le32 (0);
  6045. + resp->AFListSize = __constant_cpu_to_le32 (0);
  6046. +
  6047. + if (rndis_per_dev_params [configNr].ack)
  6048. + rndis_per_dev_params [configNr].ack (
  6049. + rndis_per_dev_params [configNr].dev);
  6050. +
  6051. + return 0;
  6052. +}
  6053. +
  6054. +static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
  6055. +{
  6056. + rndis_query_cmplt_type *resp;
  6057. + rndis_resp_t *r;
  6058. +
  6059. + // DBG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
  6060. + if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
  6061. +
  6062. + /*
  6063. + * we need more memory:
  6064. + * gen_ndis_query_resp expects enough space for
  6065. + * rndis_query_cmplt_type followed by data.
  6066. + * oid_supported_list is the largest data reply
  6067. + */
  6068. + r = rndis_add_response (configNr,
  6069. + sizeof (oid_supported_list) + sizeof(rndis_query_cmplt_type));
  6070. + if (!r)
  6071. + return -ENOMEM;
  6072. + resp = (rndis_query_cmplt_type *) r->buf;
  6073. +
  6074. + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
  6075. + resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
  6076. +
  6077. + if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID),
  6078. + le32_to_cpu(buf->InformationBufferOffset)
  6079. + + 8 + (u8 *) buf,
  6080. + le32_to_cpu(buf->InformationBufferLength),
  6081. + r)) {
  6082. + /* OID not supported */
  6083. + resp->Status = __constant_cpu_to_le32 (
  6084. + RNDIS_STATUS_NOT_SUPPORTED);
  6085. + resp->MessageLength = __constant_cpu_to_le32 (sizeof *resp);
  6086. + resp->InformationBufferLength = __constant_cpu_to_le32 (0);
  6087. + resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
  6088. + } else
  6089. + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
  6090. +
  6091. + if (rndis_per_dev_params [configNr].ack)
  6092. + rndis_per_dev_params [configNr].ack (
  6093. + rndis_per_dev_params [configNr].dev);
  6094. + return 0;
  6095. +}
  6096. +
  6097. +static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
  6098. +{
  6099. + u32 BufLength, BufOffset;
  6100. + rndis_set_cmplt_type *resp;
  6101. + rndis_resp_t *r;
  6102. +
  6103. + r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
  6104. + if (!r)
  6105. + return -ENOMEM;
  6106. + resp = (rndis_set_cmplt_type *) r->buf;
  6107. +
  6108. + BufLength = le32_to_cpu (buf->InformationBufferLength);
  6109. + BufOffset = le32_to_cpu (buf->InformationBufferOffset);
  6110. +
  6111. +#ifdef VERBOSE
  6112. + DBG("%s: Length: %d\n", __FUNCTION__, BufLength);
  6113. + DBG("%s: Offset: %d\n", __FUNCTION__, BufOffset);
  6114. + DBG("%s: InfoBuffer: ", __FUNCTION__);
  6115. +
  6116. + for (i = 0; i < BufLength; i++) {
  6117. + DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
  6118. + }
  6119. +
  6120. + DBG("\n");
  6121. +#endif
  6122. +
  6123. + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
  6124. + resp->MessageLength = __constant_cpu_to_le32 (16);
  6125. + resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
  6126. + if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID),
  6127. + ((u8 *) buf) + 8 + BufOffset, BufLength, r))
  6128. + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
  6129. + else
  6130. + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
  6131. +
  6132. + if (rndis_per_dev_params [configNr].ack)
  6133. + rndis_per_dev_params [configNr].ack (
  6134. + rndis_per_dev_params [configNr].dev);
  6135. +
  6136. + return 0;
  6137. +}
  6138. +
  6139. +static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
  6140. +{
  6141. + rndis_reset_cmplt_type *resp;
  6142. + rndis_resp_t *r;
  6143. +
  6144. + r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
  6145. + if (!r)
  6146. + return -ENOMEM;
  6147. + resp = (rndis_reset_cmplt_type *) r->buf;
  6148. +
  6149. + resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
  6150. + resp->MessageLength = __constant_cpu_to_le32 (16);
  6151. + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
  6152. + /* resent information */
  6153. + resp->AddressingReset = __constant_cpu_to_le32 (1);
  6154. +
  6155. + if (rndis_per_dev_params [configNr].ack)
  6156. + rndis_per_dev_params [configNr].ack (
  6157. + rndis_per_dev_params [configNr].dev);
  6158. +
  6159. + return 0;
  6160. +}
  6161. +
  6162. +static int rndis_keepalive_response (int configNr,
  6163. + rndis_keepalive_msg_type *buf)
  6164. +{
  6165. + rndis_keepalive_cmplt_type *resp;
  6166. + rndis_resp_t *r;
  6167. +
  6168. + /* host "should" check only in RNDIS_DATA_INITIALIZED state */
  6169. +
  6170. + r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
  6171. + if (!r)
  6172. + return -ENOMEM;
  6173. + resp = (rndis_keepalive_cmplt_type *) r->buf;
  6174. +
  6175. + resp->MessageType = __constant_cpu_to_le32 (
  6176. + REMOTE_NDIS_KEEPALIVE_CMPLT);
  6177. + resp->MessageLength = __constant_cpu_to_le32 (16);
  6178. + resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
  6179. + resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
  6180. +
  6181. + if (rndis_per_dev_params [configNr].ack)
  6182. + rndis_per_dev_params [configNr].ack (
  6183. + rndis_per_dev_params [configNr].dev);
  6184. +
  6185. + return 0;
  6186. +}
  6187. +
  6188. +
  6189. +/*
  6190. + * Device to Host Comunication
  6191. + */
  6192. +static int rndis_indicate_status_msg (int configNr, u32 status)
  6193. +{
  6194. + rndis_indicate_status_msg_type *resp;
  6195. + rndis_resp_t *r;
  6196. +
  6197. + if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED)
  6198. + return -ENOTSUPP;
  6199. +
  6200. + r = rndis_add_response (configNr,
  6201. + sizeof (rndis_indicate_status_msg_type));
  6202. + if (!r)
  6203. + return -ENOMEM;
  6204. + resp = (rndis_indicate_status_msg_type *) r->buf;
  6205. +
  6206. + resp->MessageType = __constant_cpu_to_le32 (
  6207. + REMOTE_NDIS_INDICATE_STATUS_MSG);
  6208. + resp->MessageLength = __constant_cpu_to_le32 (20);
  6209. + resp->Status = cpu_to_le32 (status);
  6210. + resp->StatusBufferLength = __constant_cpu_to_le32 (0);
  6211. + resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
  6212. +
  6213. + if (rndis_per_dev_params [configNr].ack)
  6214. + rndis_per_dev_params [configNr].ack (
  6215. + rndis_per_dev_params [configNr].dev);
  6216. + return 0;
  6217. +}
  6218. +
  6219. +int rndis_signal_connect (int configNr)
  6220. +{
  6221. + rndis_per_dev_params [configNr].media_state
  6222. + = NDIS_MEDIA_STATE_CONNECTED;
  6223. + return rndis_indicate_status_msg (configNr,
  6224. + RNDIS_STATUS_MEDIA_CONNECT);
  6225. +}
  6226. +
  6227. +int rndis_signal_disconnect (int configNr)
  6228. +{
  6229. + rndis_per_dev_params [configNr].media_state
  6230. + = NDIS_MEDIA_STATE_DISCONNECTED;
  6231. + return rndis_indicate_status_msg (configNr,
  6232. + RNDIS_STATUS_MEDIA_DISCONNECT);
  6233. +}
  6234. +
  6235. +void rndis_uninit (int configNr)
  6236. +{
  6237. + u8 *buf;
  6238. + u32 length;
  6239. +
  6240. + if (configNr >= RNDIS_MAX_CONFIGS)
  6241. + return;
  6242. + rndis_per_dev_params [configNr].used = 0;
  6243. + rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;
  6244. +
  6245. + /* drain the response queue */
  6246. + while ((buf = rndis_get_next_response(configNr, &length)))
  6247. + rndis_free_response(configNr, buf);
  6248. +}
  6249. +
  6250. +void rndis_set_host_mac (int configNr, const u8 *addr)
  6251. +{
  6252. + rndis_per_dev_params [configNr].host_mac = addr;
  6253. +}
  6254. +
  6255. +/*
  6256. + * Message Parser
  6257. + */
  6258. +int rndis_msg_parser (u8 configNr, u8 *buf)
  6259. +{
  6260. + u32 MsgType, MsgLength;
  6261. + __le32 *tmp;
  6262. + struct rndis_params *params;
  6263. +
  6264. + if (!buf)
  6265. + return -ENOMEM;
  6266. +
  6267. + tmp = (__le32 *) buf;
  6268. + MsgType = le32_to_cpu(get_unaligned(tmp++));
  6269. + MsgLength = le32_to_cpu(get_unaligned(tmp++));
  6270. +
  6271. + if (configNr >= RNDIS_MAX_CONFIGS)
  6272. + return -ENOTSUPP;
  6273. + params = &rndis_per_dev_params [configNr];
  6274. +
  6275. + /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
  6276. + * rx/tx statistics and link status, in addition to KEEPALIVE traffic
  6277. + * and normal HC level polling to see if there's any IN traffic.
  6278. + */
  6279. +
  6280. + /* For USB: responses may take up to 10 seconds */
  6281. + switch (MsgType) {
  6282. + case REMOTE_NDIS_INITIALIZE_MSG:
  6283. + DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
  6284. + __FUNCTION__ );
  6285. + params->state = RNDIS_INITIALIZED;
  6286. + return rndis_init_response (configNr,
  6287. + (rndis_init_msg_type *) buf);
  6288. +
  6289. + case REMOTE_NDIS_HALT_MSG:
  6290. + DBG("%s: REMOTE_NDIS_HALT_MSG\n",
  6291. + __FUNCTION__ );
  6292. + params->state = RNDIS_UNINITIALIZED;
  6293. + if (params->dev) {
  6294. + netif_carrier_off (params->dev);
  6295. + netif_stop_queue (params->dev);
  6296. + }
  6297. + return 0;
  6298. +
  6299. + case REMOTE_NDIS_QUERY_MSG:
  6300. + return rndis_query_response (configNr,
  6301. + (rndis_query_msg_type *) buf);
  6302. +
  6303. + case REMOTE_NDIS_SET_MSG:
  6304. + return rndis_set_response (configNr,
  6305. + (rndis_set_msg_type *) buf);
  6306. +
  6307. + case REMOTE_NDIS_RESET_MSG:
  6308. + DBG("%s: REMOTE_NDIS_RESET_MSG\n",
  6309. + __FUNCTION__ );
  6310. + return rndis_reset_response (configNr,
  6311. + (rndis_reset_msg_type *) buf);
  6312. +
  6313. + case REMOTE_NDIS_KEEPALIVE_MSG:
  6314. + /* For USB: host does this every 5 seconds */
  6315. + if (rndis_debug > 1)
  6316. + DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
  6317. + __FUNCTION__ );
  6318. + return rndis_keepalive_response (configNr,
  6319. + (rndis_keepalive_msg_type *)
  6320. + buf);
  6321. +
  6322. + default:
  6323. + /* At least Windows XP emits some undefined RNDIS messages.
  6324. + * In one case those messages seemed to relate to the host
  6325. + * suspending itself.
  6326. + */
  6327. + pr_warning("%s: unknown RNDIS message 0x%08X len %d\n",
  6328. + __FUNCTION__ , MsgType, MsgLength);
  6329. + {
  6330. + unsigned i;
  6331. + for (i = 0; i < MsgLength; i += 16) {
  6332. + DBG("%03d: "
  6333. + " %02x %02x %02x %02x"
  6334. + " %02x %02x %02x %02x"
  6335. + " %02x %02x %02x %02x"
  6336. + " %02x %02x %02x %02x"
  6337. + "\n",
  6338. + i,
  6339. + buf[i], buf [i+1],
  6340. + buf[i+2], buf[i+3],
  6341. + buf[i+4], buf [i+5],
  6342. + buf[i+6], buf[i+7],
  6343. + buf[i+8], buf [i+9],
  6344. + buf[i+10], buf[i+11],
  6345. + buf[i+12], buf [i+13],
  6346. + buf[i+14], buf[i+15]);
  6347. + }
  6348. + }
  6349. + break;
  6350. + }
  6351. +
  6352. + return -ENOTSUPP;
  6353. +}
  6354. +
  6355. +int rndis_register (int (* rndis_control_ack) (struct net_device *))
  6356. +{
  6357. + u8 i;
  6358. +
  6359. + for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
  6360. + if (!rndis_per_dev_params [i].used) {
  6361. + rndis_per_dev_params [i].used = 1;
  6362. + rndis_per_dev_params [i].ack = rndis_control_ack;
  6363. + DBG("%s: configNr = %d\n", __FUNCTION__, i);
  6364. + return i;
  6365. + }
  6366. + }
  6367. + DBG("failed\n");
  6368. +
  6369. + return -1;
  6370. +}
  6371. +
  6372. +void rndis_deregister (int configNr)
  6373. +{
  6374. + DBG("%s: \n", __FUNCTION__ );
  6375. +
  6376. + if (configNr >= RNDIS_MAX_CONFIGS) return;
  6377. + rndis_per_dev_params [configNr].used = 0;
  6378. +
  6379. + return;
  6380. +}
  6381. +
  6382. +int rndis_set_param_dev (u8 configNr, struct net_device *dev,
  6383. + struct net_device_stats *stats,
  6384. + u16 *cdc_filter)
  6385. +{
  6386. + DBG("%s:\n", __FUNCTION__ );
  6387. + if (!dev || !stats) return -1;
  6388. + if (configNr >= RNDIS_MAX_CONFIGS) return -1;
  6389. +
  6390. + rndis_per_dev_params [configNr].dev = dev;
  6391. + rndis_per_dev_params [configNr].stats = stats;
  6392. + rndis_per_dev_params [configNr].filter = cdc_filter;
  6393. +
  6394. + return 0;
  6395. +}
  6396. +
  6397. +int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
  6398. +{
  6399. + DBG("%s:\n", __FUNCTION__ );
  6400. + if (!vendorDescr) return -1;
  6401. + if (configNr >= RNDIS_MAX_CONFIGS) return -1;
  6402. +
  6403. + rndis_per_dev_params [configNr].vendorID = vendorID;
  6404. + rndis_per_dev_params [configNr].vendorDescr = vendorDescr;
  6405. +
  6406. + return 0;
  6407. +}
  6408. +
  6409. +int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
  6410. +{
  6411. + DBG("%s: %u %u\n", __FUNCTION__, medium, speed);
  6412. + if (configNr >= RNDIS_MAX_CONFIGS) return -1;
  6413. +
  6414. + rndis_per_dev_params [configNr].medium = medium;
  6415. + rndis_per_dev_params [configNr].speed = speed;
  6416. +
  6417. + return 0;
  6418. +}
  6419. +
  6420. +void rndis_add_hdr (struct sk_buff *skb)
  6421. +{
  6422. + struct rndis_packet_msg_type *header;
  6423. +
  6424. + if (!skb)
  6425. + return;
  6426. + header = (void *) skb_push (skb, sizeof *header);
  6427. + memset (header, 0, sizeof *header);
  6428. + header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
  6429. + header->MessageLength = cpu_to_le32(skb->len);
  6430. + header->DataOffset = __constant_cpu_to_le32 (36);
  6431. + header->DataLength = cpu_to_le32(skb->len - sizeof *header);
  6432. +}
  6433. +
  6434. +void rndis_free_response (int configNr, u8 *buf)
  6435. +{
  6436. + rndis_resp_t *r;
  6437. + struct list_head *act, *tmp;
  6438. +
  6439. + list_for_each_safe (act, tmp,
  6440. + &(rndis_per_dev_params [configNr].resp_queue))
  6441. + {
  6442. + r = list_entry (act, rndis_resp_t, list);
  6443. + if (r && r->buf == buf) {
  6444. + list_del (&r->list);
  6445. + kfree (r);
  6446. + }
  6447. + }
  6448. +}
  6449. +
  6450. +u8 *rndis_get_next_response (int configNr, u32 *length)
  6451. +{
  6452. + rndis_resp_t *r;
  6453. + struct list_head *act, *tmp;
  6454. +
  6455. + if (!length) return NULL;
  6456. +
  6457. + list_for_each_safe (act, tmp,
  6458. + &(rndis_per_dev_params [configNr].resp_queue))
  6459. + {
  6460. + r = list_entry (act, rndis_resp_t, list);
  6461. + if (!r->send) {
  6462. + r->send = 1;
  6463. + *length = r->length;
  6464. + return r->buf;
  6465. + }
  6466. + }
  6467. +
  6468. + return NULL;
  6469. +}
  6470. +
  6471. +static rndis_resp_t *rndis_add_response (int configNr, u32 length)
  6472. +{
  6473. + rndis_resp_t *r;
  6474. +
  6475. + /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */
  6476. + r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);
  6477. + if (!r) return NULL;
  6478. +
  6479. + r->buf = (u8 *) (r + 1);
  6480. + r->length = length;
  6481. + r->send = 0;
  6482. +
  6483. + list_add_tail (&r->list,
  6484. + &(rndis_per_dev_params [configNr].resp_queue));
  6485. + return r;
  6486. +}
  6487. +
  6488. +int rndis_rm_hdr(struct sk_buff *skb)
  6489. +{
  6490. + /* tmp points to a struct rndis_packet_msg_type */
  6491. + __le32 *tmp = (void *) skb->data;
  6492. +
  6493. + /* MessageType, MessageLength */
  6494. + if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
  6495. + != get_unaligned(tmp++))
  6496. + return -EINVAL;
  6497. + tmp++;
  6498. +
  6499. + /* DataOffset, DataLength */
  6500. + if (!skb_pull(skb, le32_to_cpu(get_unaligned(tmp++))
  6501. + + 8 /* offset of DataOffset */))
  6502. + return -EOVERFLOW;
  6503. + skb_trim(skb, le32_to_cpu(get_unaligned(tmp++)));
  6504. +
  6505. + return 0;
  6506. +}
  6507. +
  6508. +#ifdef CONFIG_USB_GADGET_DEBUG_FILES
  6509. +
  6510. +static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
  6511. + void *data)
  6512. +{
  6513. + char *out = page;
  6514. + int len;
  6515. + rndis_params *param = (rndis_params *) data;
  6516. +
  6517. + out += snprintf (out, count,
  6518. + "Config Nr. %d\n"
  6519. + "used : %s\n"
  6520. + "state : %s\n"
  6521. + "medium : 0x%08X\n"
  6522. + "speed : %d\n"
  6523. + "cable : %s\n"
  6524. + "vendor ID : 0x%08X\n"
  6525. + "vendor : %s\n",
  6526. + param->confignr, (param->used) ? "y" : "n",
  6527. + ({ char *s = "?";
  6528. + switch (param->state) {
  6529. + case RNDIS_UNINITIALIZED:
  6530. + s = "RNDIS_UNINITIALIZED"; break;
  6531. + case RNDIS_INITIALIZED:
  6532. + s = "RNDIS_INITIALIZED"; break;
  6533. + case RNDIS_DATA_INITIALIZED:
  6534. + s = "RNDIS_DATA_INITIALIZED"; break;
  6535. + }; s; }),
  6536. + param->medium,
  6537. + (param->media_state) ? 0 : param->speed*100,
  6538. + (param->media_state) ? "disconnected" : "connected",
  6539. + param->vendorID, param->vendorDescr);
  6540. +
  6541. + len = out - page;
  6542. + len -= off;
  6543. +
  6544. + if (len < count) {
  6545. + *eof = 1;
  6546. + if (len <= 0)
  6547. + return 0;
  6548. + } else
  6549. + len = count;
  6550. +
  6551. + *start = page + off;
  6552. + return len;
  6553. +}
  6554. +
  6555. +static int rndis_proc_write (struct file *file, const char __user *buffer,
  6556. + unsigned long count, void *data)
  6557. +{
  6558. + rndis_params *p = data;
  6559. + u32 speed = 0;
  6560. + int i, fl_speed = 0;
  6561. +
  6562. + for (i = 0; i < count; i++) {
  6563. + char c;
  6564. + if (get_user(c, buffer))
  6565. + return -EFAULT;
  6566. + switch (c) {
  6567. + case '0':
  6568. + case '1':
  6569. + case '2':
  6570. + case '3':
  6571. + case '4':
  6572. + case '5':
  6573. + case '6':
  6574. + case '7':
  6575. + case '8':
  6576. + case '9':
  6577. + fl_speed = 1;
  6578. + speed = speed*10 + c - '0';
  6579. + break;
  6580. + case 'C':
  6581. + case 'c':
  6582. + rndis_signal_connect (p->confignr);
  6583. + break;
  6584. + case 'D':
  6585. + case 'd':
  6586. + rndis_signal_disconnect(p->confignr);
  6587. + break;
  6588. + default:
  6589. + if (fl_speed) p->speed = speed;
  6590. + else DBG("%c is not valid\n", c);
  6591. + break;
  6592. + }
  6593. +
  6594. + buffer++;
  6595. + }
  6596. +
  6597. + return count;
  6598. +}
  6599. +
  6600. +#define NAME_TEMPLATE "driver/rndis-%03d"
  6601. +
  6602. +static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
  6603. +
  6604. +#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
  6605. +
  6606. +
  6607. +int __devinit rndis_init (void)
  6608. +{
  6609. + u8 i;
  6610. +
  6611. + for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
  6612. +#ifdef CONFIG_USB_GADGET_DEBUG_FILES
  6613. + char name [20];
  6614. +
  6615. + sprintf (name, NAME_TEMPLATE, i);
  6616. + if (!(rndis_connect_state [i]
  6617. + = create_proc_entry (name, 0660, NULL)))
  6618. + {
  6619. + DBG("%s :remove entries", __FUNCTION__);
  6620. + while (i) {
  6621. + sprintf (name, NAME_TEMPLATE, --i);
  6622. + remove_proc_entry (name, NULL);
  6623. + }
  6624. + DBG("\n");
  6625. + return -EIO;
  6626. + }
  6627. +
  6628. + rndis_connect_state [i]->write_proc = rndis_proc_write;
  6629. + rndis_connect_state [i]->read_proc = rndis_proc_read;
  6630. + rndis_connect_state [i]->data = (void *)
  6631. + (rndis_per_dev_params + i);
  6632. +#endif
  6633. + rndis_per_dev_params [i].confignr = i;
  6634. + rndis_per_dev_params [i].used = 0;
  6635. + rndis_per_dev_params [i].state = RNDIS_UNINITIALIZED;
  6636. + rndis_per_dev_params [i].media_state
  6637. + = NDIS_MEDIA_STATE_DISCONNECTED;
  6638. + INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue));
  6639. + }
  6640. +
  6641. + return 0;
  6642. +}
  6643. +
  6644. +void rndis_exit (void)
  6645. +{
  6646. +#ifdef CONFIG_USB_GADGET_DEBUG_FILES
  6647. + u8 i;
  6648. + char name [20];
  6649. +
  6650. + for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
  6651. + sprintf (name, NAME_TEMPLATE, i);
  6652. + remove_proc_entry (name, NULL);
  6653. + }
  6654. +#endif
  6655. +}
  6656. +
  6657. diff -Naurp a/drivers/usb/function/rndis.h b/drivers/usb/function/rndis.h
  6658. --- a/drivers/usb/function/rndis.h 1970-01-01 01:00:00.000000000 +0100
  6659. +++ b/drivers/usb/function/rndis.h 2009-12-18 23:16:54.619476954 +0100
  6660. @@ -0,0 +1,270 @@
  6661. +/*
  6662. + * RNDIS Definitions for Remote NDIS
  6663. + *
  6664. + * Version: $Id: rndis.h,v 1.15 2004/03/25 21:33:46 robert Exp $
  6665. + *
  6666. + * Authors: Benedikt Spranger, Pengutronix
  6667. + * Robert Schwebel, Pengutronix
  6668. + *
  6669. + * This program is free software; you can redistribute it and/or
  6670. + * modify it under the terms of the GNU General Public License
  6671. + * version 2, as published by the Free Software Foundation.
  6672. + *
  6673. + * This software was originally developed in conformance with
  6674. + * Microsoft's Remote NDIS Specification License Agreement.
  6675. + */
  6676. +
  6677. +#ifndef _LINUX_RNDIS_H
  6678. +#define _LINUX_RNDIS_H
  6679. +
  6680. +#include "ndis.h"
  6681. +
  6682. +#define RNDIS_MAXIMUM_FRAME_SIZE 1518
  6683. +#define RNDIS_MAX_TOTAL_SIZE 1558
  6684. +
  6685. +/* Remote NDIS Versions */
  6686. +#define RNDIS_MAJOR_VERSION 1
  6687. +#define RNDIS_MINOR_VERSION 0
  6688. +
  6689. +/* Status Values */
  6690. +#define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */
  6691. +#define RNDIS_STATUS_FAILURE 0xC0000001U /* Unspecified error */
  6692. +#define RNDIS_STATUS_INVALID_DATA 0xC0010015U /* Invalid data */
  6693. +#define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBU /* Unsupported request */
  6694. +#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */
  6695. +#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */
  6696. +/* For all not specified status messages:
  6697. + * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx
  6698. + */
  6699. +
  6700. +/* Message Set for Connectionless (802.3) Devices */
  6701. +#define REMOTE_NDIS_PACKET_MSG 0x00000001U
  6702. +#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002U /* Initialize device */
  6703. +#define REMOTE_NDIS_HALT_MSG 0x00000003U
  6704. +#define REMOTE_NDIS_QUERY_MSG 0x00000004U
  6705. +#define REMOTE_NDIS_SET_MSG 0x00000005U
  6706. +#define REMOTE_NDIS_RESET_MSG 0x00000006U
  6707. +#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007U
  6708. +#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008U
  6709. +
  6710. +/* Message completion */
  6711. +#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002U
  6712. +#define REMOTE_NDIS_QUERY_CMPLT 0x80000004U
  6713. +#define REMOTE_NDIS_SET_CMPLT 0x80000005U
  6714. +#define REMOTE_NDIS_RESET_CMPLT 0x80000006U
  6715. +#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008U
  6716. +
  6717. +/* Device Flags */
  6718. +#define RNDIS_DF_CONNECTIONLESS 0x00000001U
  6719. +#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002U
  6720. +
  6721. +#define RNDIS_MEDIUM_802_3 0x00000000U
  6722. +
  6723. +/* from drivers/net/sk98lin/h/skgepnmi.h */
  6724. +#define OID_PNP_CAPABILITIES 0xFD010100
  6725. +#define OID_PNP_SET_POWER 0xFD010101
  6726. +#define OID_PNP_QUERY_POWER 0xFD010102
  6727. +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103
  6728. +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
  6729. +#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
  6730. +
  6731. +
  6732. +typedef struct rndis_init_msg_type
  6733. +{
  6734. + __le32 MessageType;
  6735. + __le32 MessageLength;
  6736. + __le32 RequestID;
  6737. + __le32 MajorVersion;
  6738. + __le32 MinorVersion;
  6739. + __le32 MaxTransferSize;
  6740. +} rndis_init_msg_type;
  6741. +
  6742. +typedef struct rndis_init_cmplt_type
  6743. +{
  6744. + __le32 MessageType;
  6745. + __le32 MessageLength;
  6746. + __le32 RequestID;
  6747. + __le32 Status;
  6748. + __le32 MajorVersion;
  6749. + __le32 MinorVersion;
  6750. + __le32 DeviceFlags;
  6751. + __le32 Medium;
  6752. + __le32 MaxPacketsPerTransfer;
  6753. + __le32 MaxTransferSize;
  6754. + __le32 PacketAlignmentFactor;
  6755. + __le32 AFListOffset;
  6756. + __le32 AFListSize;
  6757. +} rndis_init_cmplt_type;
  6758. +
  6759. +typedef struct rndis_halt_msg_type
  6760. +{
  6761. + __le32 MessageType;
  6762. + __le32 MessageLength;
  6763. + __le32 RequestID;
  6764. +} rndis_halt_msg_type;
  6765. +
  6766. +typedef struct rndis_query_msg_type
  6767. +{
  6768. + __le32 MessageType;
  6769. + __le32 MessageLength;
  6770. + __le32 RequestID;
  6771. + __le32 OID;
  6772. + __le32 InformationBufferLength;
  6773. + __le32 InformationBufferOffset;
  6774. + __le32 DeviceVcHandle;
  6775. +} rndis_query_msg_type;
  6776. +
  6777. +typedef struct rndis_query_cmplt_type
  6778. +{
  6779. + __le32 MessageType;
  6780. + __le32 MessageLength;
  6781. + __le32 RequestID;
  6782. + __le32 Status;
  6783. + __le32 InformationBufferLength;
  6784. + __le32 InformationBufferOffset;
  6785. +} rndis_query_cmplt_type;
  6786. +
  6787. +typedef struct rndis_set_msg_type
  6788. +{
  6789. + __le32 MessageType;
  6790. + __le32 MessageLength;
  6791. + __le32 RequestID;
  6792. + __le32 OID;
  6793. + __le32 InformationBufferLength;
  6794. + __le32 InformationBufferOffset;
  6795. + __le32 DeviceVcHandle;
  6796. +} rndis_set_msg_type;
  6797. +
  6798. +typedef struct rndis_set_cmplt_type
  6799. +{
  6800. + __le32 MessageType;
  6801. + __le32 MessageLength;
  6802. + __le32 RequestID;
  6803. + __le32 Status;
  6804. +} rndis_set_cmplt_type;
  6805. +
  6806. +typedef struct rndis_reset_msg_type
  6807. +{
  6808. + __le32 MessageType;
  6809. + __le32 MessageLength;
  6810. + __le32 Reserved;
  6811. +} rndis_reset_msg_type;
  6812. +
  6813. +typedef struct rndis_reset_cmplt_type
  6814. +{
  6815. + __le32 MessageType;
  6816. + __le32 MessageLength;
  6817. + __le32 Status;
  6818. + __le32 AddressingReset;
  6819. +} rndis_reset_cmplt_type;
  6820. +
  6821. +typedef struct rndis_indicate_status_msg_type
  6822. +{
  6823. + __le32 MessageType;
  6824. + __le32 MessageLength;
  6825. + __le32 Status;
  6826. + __le32 StatusBufferLength;
  6827. + __le32 StatusBufferOffset;
  6828. +} rndis_indicate_status_msg_type;
  6829. +
  6830. +typedef struct rndis_keepalive_msg_type
  6831. +{
  6832. + __le32 MessageType;
  6833. + __le32 MessageLength;
  6834. + __le32 RequestID;
  6835. +} rndis_keepalive_msg_type;
  6836. +
  6837. +typedef struct rndis_keepalive_cmplt_type
  6838. +{
  6839. + __le32 MessageType;
  6840. + __le32 MessageLength;
  6841. + __le32 RequestID;
  6842. + __le32 Status;
  6843. +} rndis_keepalive_cmplt_type;
  6844. +
  6845. +struct rndis_packet_msg_type
  6846. +{
  6847. + __le32 MessageType;
  6848. + __le32 MessageLength;
  6849. + __le32 DataOffset;
  6850. + __le32 DataLength;
  6851. + __le32 OOBDataOffset;
  6852. + __le32 OOBDataLength;
  6853. + __le32 NumOOBDataElements;
  6854. + __le32 PerPacketInfoOffset;
  6855. + __le32 PerPacketInfoLength;
  6856. + __le32 VcHandle;
  6857. + __le32 Reserved;
  6858. +} __attribute__ ((packed));
  6859. +
  6860. +struct rndis_config_parameter
  6861. +{
  6862. + __le32 ParameterNameOffset;
  6863. + __le32 ParameterNameLength;
  6864. + __le32 ParameterType;
  6865. + __le32 ParameterValueOffset;
  6866. + __le32 ParameterValueLength;
  6867. +};
  6868. +
  6869. +/* implementation specific */
  6870. +enum rndis_state
  6871. +{
  6872. + RNDIS_UNINITIALIZED,
  6873. + RNDIS_INITIALIZED,
  6874. + RNDIS_DATA_INITIALIZED,
  6875. +};
  6876. +
  6877. +typedef struct rndis_resp_t
  6878. +{
  6879. + struct list_head list;
  6880. + u8 *buf;
  6881. + u32 length;
  6882. + int send;
  6883. +} rndis_resp_t;
  6884. +
  6885. +typedef struct rndis_params
  6886. +{
  6887. + u8 confignr;
  6888. + u8 used;
  6889. + u16 saved_filter;
  6890. + enum rndis_state state;
  6891. + u32 medium;
  6892. + u32 speed;
  6893. + u32 media_state;
  6894. +
  6895. + const u8 *host_mac;
  6896. + u16 *filter;
  6897. + struct net_device *dev;
  6898. + struct net_device_stats *stats;
  6899. +
  6900. + u32 vendorID;
  6901. + const char *vendorDescr;
  6902. + int (*ack) (struct net_device *);
  6903. + struct list_head resp_queue;
  6904. +} rndis_params;
  6905. +
  6906. +/* RNDIS Message parser and other useless functions */
  6907. +int rndis_msg_parser (u8 configNr, u8 *buf);
  6908. +int rndis_register (int (*rndis_control_ack) (struct net_device *));
  6909. +void rndis_deregister (int configNr);
  6910. +int rndis_set_param_dev (u8 configNr, struct net_device *dev,
  6911. + struct net_device_stats *stats,
  6912. + u16 *cdc_filter);
  6913. +int rndis_set_param_vendor (u8 configNr, u32 vendorID,
  6914. + const char *vendorDescr);
  6915. +int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed);
  6916. +void rndis_add_hdr (struct sk_buff *skb);
  6917. +int rndis_rm_hdr (struct sk_buff *skb);
  6918. +u8 *rndis_get_next_response (int configNr, u32 *length);
  6919. +void rndis_free_response (int configNr, u8 *buf);
  6920. +
  6921. +void rndis_uninit (int configNr);
  6922. +int rndis_signal_connect (int configNr);
  6923. +int rndis_signal_disconnect (int configNr);
  6924. +int rndis_state (int configNr);
  6925. +extern void rndis_set_host_mac (int configNr, const u8 *addr);
  6926. +
  6927. +int __devinit rndis_init (void);
  6928. +void rndis_exit (void);
  6929. +
  6930. +#endif /* _LINUX_RNDIS_H */
  6931. diff -Naurp a/drivers/usb/function/ums.c b/drivers/usb/function/ums.c
  6932. --- a/drivers/usb/function/ums.c 2009-12-18 22:11:24.603494666 +0100
  6933. +++ b/drivers/usb/function/ums.c 2009-12-18 22:11:33.935477884 +0100
  6934. @@ -443,6 +443,8 @@ static struct usb_function usb_func_ums
  6935.  
  6936. .ifc_ept_count = 2,
  6937. .ifc_ept_type = { EPT_BULK_OUT, EPT_BULK_IN },
  6938. +
  6939. + .position_bit = USB_FUNCTION_MASS_STORAGE_NUM,
  6940. };
  6941.  
  6942. static int __init ums_init(void)
  6943. diff -Naurp a/drivers/usb/function/usb_function.h b/drivers/usb/function/usb_function.h
  6944. --- a/drivers/usb/function/usb_function.h 2009-12-18 22:11:51.183482910 +0100
  6945. +++ b/drivers/usb/function/usb_function.h 2009-12-18 22:11:58.127481466 +0100
  6946. @@ -24,6 +24,30 @@
  6947.  
  6948. #define EPT_BULK_IN 1
  6949. #define EPT_BULK_OUT 2
  6950. +#define EPT_INT_IN 3
  6951. +#define EPT_INT_OUT 4
  6952. +
  6953. +#define STRING_UMS 4
  6954. +#define STRING_ADB 5
  6955. +#define STRING_ES 6
  6956. +#define STRING_DIAG 7
  6957. +#define STRING_FSERIAL 8
  6958. +#define STRING_PROJECTOR 9
  6959. +#define STRING_FSYNC 10
  6960. +#define STRING_MTP 11
  6961. +
  6962. +typedef enum {
  6963. + USB_FUNCTION_MASS_STORAGE_NUM = 0, /* default, don't change position */
  6964. + USB_FUNCTION_ADB_NUM,
  6965. + USB_FUNCTION_INTERNET_SHARING_NUM,
  6966. + USB_FUNCTION_DIAG_NUM,
  6967. + USB_FUNCTION_FSERIAL_NUM,
  6968. + USB_FUNCTION_PROJECTOR_NUM,
  6969. + USB_FUNCTION_FSYNC_NUM,
  6970. + USB_FUNCTION_MTP_TUNNEL_NUM,
  6971. + USB_FUNCTION_ZERO_NUM,
  6972. + USB_FUNCTION_LOOPBACK_NUM,
  6973. +} usb_function_position;
  6974.  
  6975. struct usb_endpoint;
  6976.  
  6977. @@ -40,6 +64,12 @@ struct usb_request
  6978. struct list_head list;
  6979. };
  6980.  
  6981. +struct usb_fi_ept
  6982. +{
  6983. + struct usb_endpoint *ept;
  6984. + struct usb_endpoint_descriptor desc;
  6985. +};
  6986. +
  6987. struct usb_function
  6988. {
  6989. /* bind() is called once when the function has had its endpoints
  6990. @@ -83,6 +113,9 @@ struct usb_function
  6991. const char *name;
  6992. void *context;
  6993.  
  6994. + /* number of interfaces */
  6995. + unsigned char ifc_num;
  6996. +
  6997. /* interface class/subclass/protocol for descriptor */
  6998. unsigned char ifc_class;
  6999. unsigned char ifc_subclass;
  7000. @@ -99,12 +132,23 @@ struct usb_function
  7001. ** included in the configuration descriptor
  7002. */
  7003. unsigned char disabled;
  7004. +
  7005. + /* static bit position for product id */
  7006. + usb_function_position position_bit;
  7007. +
  7008. + /* to copy non-standard or multiple interfaces to the descriptor */
  7009. + /* return the number of bytes copied */
  7010. + size_t (*ifc_copy)(char *buf, size_t len, int ifc_number);
  7011. };
  7012.  
  7013. int usb_function_register(struct usb_function *driver);
  7014.  
  7015. void usb_function_enable(const char *function, int enable);
  7016.  
  7017. +int return_usb_function_enabled(const char *function);
  7018. +
  7019. +struct usb_fi_ept *get_ept_info(const char *function);
  7020. +
  7021. /* Allocate a USB request.
  7022. ** Must be called from a context that can sleep.
  7023. ** If bufsize is nonzero, req->buf will be allocated for
  7024. diff -Naurp a/drivers/usb/function/zero.c b/drivers/usb/function/zero.c
  7025. --- a/drivers/usb/function/zero.c 2009-12-18 22:12:13.391498743 +0100
  7026. +++ b/drivers/usb/function/zero.c 2009-12-18 22:12:19.359477295 +0100
  7027. @@ -108,6 +108,8 @@ static struct usb_function usb_func_zero
  7028.  
  7029. .ifc_ept_count = 1,
  7030. .ifc_ept_type = { EPT_BULK_IN },
  7031. +
  7032. + .position_bit = USB_FUNCTION_ZERO_NUM,
  7033. };
  7034.  
  7035. static int __init zero_init(void)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement