f_apple_vsc_sim.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. /*
  2. * f_apple_vsc_sim.c - USB peripheral apple_vsc_sim configuration driver
  3. *
  4. * Copyright (C) 2020 Arkmicro Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. */
  11. /* #define VERBOSE_DEBUG */
  12. #include <linux/slab.h>
  13. #include <linux/kernel.h>
  14. #include <linux/device.h>
  15. #include <linux/module.h>
  16. #include <net/sock.h>
  17. #include <linux/netlink.h>
  18. #include <linux/usb/composite.h>
  19. #include <linux/usb/functionfs.h>
  20. #include <linux/miscdevice.h>
  21. #include "f_apple_common.h"
  22. #define SD_BULK_BUFFER_SIZE 16384
  23. #define SD_TX_REQ_MAX 4
  24. struct f_apple_vsc_sim {
  25. struct usb_function function;
  26. struct usb_composite_dev *cdev;
  27. spinlock_t lock;
  28. struct usb_ep *ep_in;
  29. struct usb_ep *ep_out;
  30. int online;
  31. int error;
  32. atomic_t read_excl;
  33. atomic_t write_excl;
  34. atomic_t open_excl;
  35. struct list_head tx_idle;
  36. struct list_head rx_idle;
  37. struct list_head rx_used;
  38. wait_queue_head_t read_wq;
  39. wait_queue_head_t write_wq;
  40. int rx_done;
  41. int cur_read_pos;
  42. struct miscdevice device;
  43. struct list_head node;
  44. char *name;
  45. };
  46. struct f_apple_vsc_sim_opts {
  47. struct usb_function_instance func_inst;
  48. struct mutex lock;
  49. int refcnt;
  50. unsigned iso_qlen;
  51. };
  52. static DEFINE_MUTEX(apple_vsc_mutex);
  53. static LIST_HEAD(apple_vsc_list);
  54. static int apple_vsc_setup(struct f_apple_vsc_sim *dev, int intc, int intf);
  55. static void apple_vsc_cleanup(struct f_apple_vsc_sim *dev);
  56. int usb_dev_ready_notify(int is_ready);
  57. static inline struct f_apple_vsc_sim *func_to_apple_vsc_sim(struct usb_function *f)
  58. {
  59. return container_of(f, struct f_apple_vsc_sim, function);
  60. }
  61. static struct usb_interface_descriptor apple_vsc_sim = {
  62. .bLength = sizeof apple_vsc_sim,
  63. .bDescriptorType = USB_DT_INTERFACE,
  64. .bAlternateSetting = 0,
  65. .bNumEndpoints = 0,
  66. .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
  67. .bInterfaceSubClass = 0xFD,
  68. .bInterfaceProtocol = 1,
  69. /* .iInterface = DYNAMIC */
  70. };
  71. static struct usb_interface_descriptor apple_vsc_sim_intf0 = {
  72. .bLength = sizeof apple_vsc_sim_intf0,
  73. .bDescriptorType = USB_DT_INTERFACE,
  74. .bAlternateSetting = 1,
  75. .bNumEndpoints = 2,
  76. .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
  77. .bInterfaceSubClass = 0xFD,
  78. .bInterfaceProtocol = 1,
  79. /* .iInterface = DYNAMIC */
  80. };
  81. static struct usb_interface_descriptor apple_vsc_sim_intf1 = {
  82. .bLength = sizeof apple_vsc_sim_intf1,
  83. .bDescriptorType = USB_DT_INTERFACE,
  84. .bAlternateSetting = 2,
  85. .bNumEndpoints = 2,
  86. .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
  87. .bInterfaceSubClass = 0xFD,
  88. .bInterfaceProtocol = 1,
  89. /* .iInterface = DYNAMIC */
  90. };
  91. /* full speed support: */
  92. static struct usb_endpoint_descriptor fs_apple_vsc_sim_source_desc = {
  93. .bLength = USB_DT_ENDPOINT_SIZE,
  94. .bDescriptorType = USB_DT_ENDPOINT,
  95. .bEndpointAddress = USB_DIR_IN,
  96. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  97. };
  98. static struct usb_endpoint_descriptor fs_apple_vsc_sim_sink_desc = {
  99. .bLength = USB_DT_ENDPOINT_SIZE,
  100. .bDescriptorType = USB_DT_ENDPOINT,
  101. .bEndpointAddress = USB_DIR_OUT,
  102. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  103. };
  104. static struct usb_descriptor_header *fs_apple_vsc_sim_descs[] = {
  105. (struct usb_descriptor_header *) &apple_vsc_sim,
  106. (struct usb_descriptor_header *) &apple_vsc_sim_intf0,
  107. (struct usb_descriptor_header *) &fs_apple_vsc_sim_sink_desc,
  108. (struct usb_descriptor_header *) &fs_apple_vsc_sim_source_desc,
  109. (struct usb_descriptor_header *) &apple_vsc_sim_intf1,
  110. (struct usb_descriptor_header *) &fs_apple_vsc_sim_sink_desc,
  111. (struct usb_descriptor_header *) &fs_apple_vsc_sim_source_desc,
  112. NULL,
  113. };
  114. /* high speed support: */
  115. static struct usb_endpoint_descriptor hs_apple_vsc_sim_source_desc = {
  116. .bLength = USB_DT_ENDPOINT_SIZE,
  117. .bDescriptorType = USB_DT_ENDPOINT,
  118. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  119. .wMaxPacketSize = cpu_to_le16(512),
  120. };
  121. static struct usb_endpoint_descriptor hs_apple_vsc_sim_sink_desc = {
  122. .bLength = USB_DT_ENDPOINT_SIZE,
  123. .bDescriptorType = USB_DT_ENDPOINT,
  124. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  125. .wMaxPacketSize = cpu_to_le16(512),
  126. };
  127. static struct usb_descriptor_header *hs_apple_vsc_sim_descs[] = {
  128. (struct usb_descriptor_header *) &apple_vsc_sim,
  129. (struct usb_descriptor_header *) &apple_vsc_sim_intf0,
  130. (struct usb_descriptor_header *) &hs_apple_vsc_sim_source_desc,
  131. (struct usb_descriptor_header *) &hs_apple_vsc_sim_sink_desc,
  132. (struct usb_descriptor_header *) &apple_vsc_sim_intf1,
  133. (struct usb_descriptor_header *) &hs_apple_vsc_sim_source_desc,
  134. (struct usb_descriptor_header *) &hs_apple_vsc_sim_sink_desc,
  135. NULL,
  136. };
  137. /* super speed support: */
  138. static struct usb_endpoint_descriptor ss_apple_vsc_sim_source_desc = {
  139. .bLength = USB_DT_ENDPOINT_SIZE,
  140. .bDescriptorType = USB_DT_ENDPOINT,
  141. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  142. .wMaxPacketSize = cpu_to_le16(1024),
  143. };
  144. static struct usb_ss_ep_comp_descriptor ss_apple_vsc_sim_source_comp_desc = {
  145. .bLength = USB_DT_SS_EP_COMP_SIZE,
  146. .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
  147. .bMaxBurst = 0,
  148. .bmAttributes = 0,
  149. .wBytesPerInterval = 0,
  150. };
  151. static struct usb_endpoint_descriptor ss_apple_vsc_sim_sink_desc = {
  152. .bLength = USB_DT_ENDPOINT_SIZE,
  153. .bDescriptorType = USB_DT_ENDPOINT,
  154. .bmAttributes = USB_ENDPOINT_XFER_BULK,
  155. .wMaxPacketSize = cpu_to_le16(1024),
  156. };
  157. static struct usb_ss_ep_comp_descriptor ss_apple_vsc_sim_sink_comp_desc = {
  158. .bLength = USB_DT_SS_EP_COMP_SIZE,
  159. .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
  160. .bMaxBurst = 0,
  161. .bmAttributes = 0,
  162. .wBytesPerInterval = 0,
  163. };
  164. static struct usb_descriptor_header *ss_apple_vsc_sim_descs[] = {
  165. (struct usb_descriptor_header *) &apple_vsc_sim,
  166. (struct usb_descriptor_header *) &apple_vsc_sim_intf0,
  167. (struct usb_descriptor_header *) &ss_apple_vsc_sim_sink_desc,
  168. (struct usb_descriptor_header *) &ss_apple_vsc_sim_sink_comp_desc,
  169. (struct usb_descriptor_header *) &ss_apple_vsc_sim_source_desc,
  170. (struct usb_descriptor_header *) &ss_apple_vsc_sim_source_comp_desc,
  171. (struct usb_descriptor_header *) &apple_vsc_sim_intf1,
  172. (struct usb_descriptor_header *) &ss_apple_vsc_sim_sink_desc,
  173. (struct usb_descriptor_header *) &ss_apple_vsc_sim_sink_comp_desc,
  174. (struct usb_descriptor_header *) &ss_apple_vsc_sim_source_desc,
  175. (struct usb_descriptor_header *) &ss_apple_vsc_sim_source_comp_desc,
  176. NULL,
  177. };
  178. #if 0
  179. #define FUNC_VSC_IDX 0
  180. static struct usb_string apple_vsc_sim_string_defs[] = {
  181. [FUNC_VSC_IDX].s = "PTP",
  182. {},
  183. };
  184. static struct usb_gadget_strings apple_vsc_sim_string_table = {
  185. .language = 0x0409, /* en-US */
  186. .strings = apple_vsc_sim_string_defs,
  187. };
  188. static struct usb_gadget_strings *apple_vsc_sim_strings[] = {
  189. &apple_vsc_sim_string_table,
  190. NULL,
  191. };
  192. #endif
  193. static struct usb_request *apple_vsc_request_new(struct usb_ep *ep, int buffer_size)
  194. {
  195. struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL);
  196. if (!req)
  197. return NULL;
  198. req->buf = kmalloc(buffer_size, GFP_KERNEL);
  199. if (!req->buf) {
  200. usb_ep_free_request(ep, req);
  201. return NULL;
  202. }
  203. return req;
  204. }
  205. static void apple_vsc_request_free(struct usb_request *req, struct usb_ep *ep)
  206. {
  207. if (req) {
  208. kfree(req->buf);
  209. usb_ep_free_request(ep, req);
  210. }
  211. }
  212. static inline int apple_vsc_lock(atomic_t *excl)
  213. {
  214. if (atomic_inc_return(excl) == 1) {
  215. return 0;
  216. } else {
  217. atomic_dec(excl);
  218. return -1;
  219. }
  220. }
  221. static inline void apple_vsc_unlock(atomic_t *excl)
  222. {
  223. atomic_dec(excl);
  224. }
  225. void apple_vsc_req_put(struct f_apple_vsc_sim *dev, struct list_head *head,
  226. struct usb_request *req)
  227. {
  228. unsigned long flags;
  229. spin_lock_irqsave(&dev->lock, flags);
  230. list_add_tail(&req->list, head);
  231. spin_unlock_irqrestore(&dev->lock, flags);
  232. }
  233. /* remove a request from the head of a list */
  234. struct usb_request *apple_vsc_req_get(struct f_apple_vsc_sim *dev, struct list_head *head)
  235. {
  236. unsigned long flags;
  237. struct usb_request *req;
  238. spin_lock_irqsave(&dev->lock, flags);
  239. if (list_empty(head)) {
  240. req = 0;
  241. } else {
  242. req = list_first_entry(head, struct usb_request, list);
  243. list_del(&req->list);
  244. }
  245. spin_unlock_irqrestore(&dev->lock, flags);
  246. return req;
  247. }
  248. static void apple_vsc_complete_in(struct usb_ep *ep, struct usb_request *req)
  249. {
  250. struct f_apple_vsc_sim *dev = (struct f_apple_vsc_sim *)(req->context);
  251. if (req->status != 0){//printk("+++%s:%d+++req->status=%d\n", __func__, __LINE__, req->status);
  252. dev->error = 1;
  253. }
  254. apple_vsc_req_put(dev, &dev->tx_idle, req);
  255. wake_up(&dev->write_wq);
  256. }
  257. static void apple_vsc_complete_out(struct usb_ep *ep, struct usb_request *req)
  258. {
  259. struct f_apple_vsc_sim *dev = (struct f_apple_vsc_sim *)(req->context);
  260. //unsigned long flags;
  261. dev->rx_done = 1;
  262. if (req) {
  263. if (req->status != 0){//printk("+++%s:%d+++req->status=%d\n", __func__, __LINE__, req->status);
  264. apple_vsc_req_put(dev, &dev->rx_idle, req);
  265. dev->error = 1;
  266. } else {
  267. apple_vsc_req_put(dev, &dev->rx_used, req);
  268. }
  269. }
  270. wake_up(&dev->read_wq);
  271. }
  272. struct usb_ep *usb_ep_autoconfig_ex(
  273. struct usb_gadget *gadget,
  274. struct usb_endpoint_descriptor *desc,
  275. uint8_t pre_ep_num
  276. );
  277. static int apple_vsc_create_bulk_endpoints(struct f_apple_vsc_sim *dev,
  278. struct usb_endpoint_descriptor *in_desc,
  279. uint8_t assigned_ep_in,
  280. struct usb_endpoint_descriptor *out_desc, uint8_t assigned_ep_out)
  281. {
  282. struct usb_composite_dev *cdev = dev->cdev;
  283. struct usb_request *req;
  284. struct usb_ep *ep;
  285. int i;
  286. DBG(cdev, "create_bulk_endpoints dev: %p\n", dev);
  287. ep = usb_ep_autoconfig_ex(cdev->gadget, in_desc, assigned_ep_in);
  288. if (!ep) {
  289. DBG(cdev, "usb_ep_autoconfig for ep_in failed\n");
  290. return -ENODEV;
  291. }
  292. DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name);
  293. ep->driver_data = dev;
  294. ep->desc = in_desc;
  295. dev->ep_in = ep;
  296. ep = usb_ep_autoconfig_ex(cdev->gadget, out_desc, assigned_ep_out);
  297. if (!ep) {
  298. DBG(cdev, "usb_ep_autoconfig for ep_out failed\n");
  299. return -ENODEV;
  300. }
  301. DBG(cdev, "usb_ep_autoconfig for iap2 ep_out got %s\n", ep->name);
  302. ep->driver_data = dev;
  303. ep->desc = out_desc;
  304. dev->ep_out = ep;
  305. for (i = 0; i < SD_TX_REQ_MAX; i++) {
  306. req = apple_vsc_request_new(dev->ep_out, SD_BULK_BUFFER_SIZE);
  307. if (!req)
  308. goto fail;
  309. req->complete = apple_vsc_complete_out;
  310. req->context = (void *)dev;
  311. apple_vsc_req_put(dev, &dev->rx_idle, req);
  312. }
  313. for (i = 0; i < SD_TX_REQ_MAX; i++) {
  314. req = apple_vsc_request_new(dev->ep_in, SD_BULK_BUFFER_SIZE);
  315. if (!req)
  316. goto fail;
  317. req->complete = apple_vsc_complete_in;
  318. req->context = (void *)dev;
  319. apple_vsc_req_put(dev, &dev->tx_idle, req);
  320. }
  321. return 0;
  322. fail:
  323. printk(KERN_ERR "apple_vsc_bind() could not allocate requests\n");
  324. return -1;
  325. }
  326. static int apple_vsc_rx_submit(struct f_apple_vsc_sim *dev, struct usb_request *req)
  327. {
  328. int ret, r;
  329. dev->rx_done = 0;
  330. ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC);
  331. if (ret < 0) {
  332. pr_debug("apple_vsc_read: failed to queue req %p (%d)\n", req, ret);
  333. r = -EIO;
  334. dev->error = 1;
  335. goto done;
  336. } else {
  337. pr_debug("rx %p queue\n", req);
  338. }
  339. done:
  340. pr_debug("apple_vsc_read returning %d\n", r);
  341. return r;
  342. }
  343. static ssize_t apple_vsc_read(struct file *fp, char __user *buf,
  344. size_t count, loff_t *pos)
  345. {
  346. struct f_apple_vsc_sim *dev = fp->private_data;
  347. struct usb_request *req = NULL;
  348. int r = 0, xfer, cur_actual = 0;
  349. int ret;
  350. //static int cur_pos = 0;
  351. unsigned long flags;
  352. pr_debug("apple_vsc_read(%d) n", (int)count);
  353. if (!dev)
  354. return -ENODEV;
  355. if (count <= 0)
  356. return 0;
  357. if (apple_vsc_lock(&dev->read_excl))
  358. return -EBUSY;
  359. if (dev->error || dev->online == 0) {
  360. r = -EIO;
  361. goto done;
  362. }
  363. req = NULL;
  364. ret = wait_event_interruptible(dev->read_wq, (req = apple_vsc_req_get(dev, &dev->rx_used)) != NULL);
  365. if (ret < 0) {
  366. r = ret;
  367. usb_ep_dequeue(dev->ep_out, req);
  368. goto done;
  369. }
  370. if (!dev->error && req) {
  371. if (req->actual > dev->cur_read_pos) {
  372. cur_actual = req->actual - dev->cur_read_pos;
  373. xfer = (cur_actual <= count) ? cur_actual : count;
  374. r = xfer;
  375. if (copy_to_user(buf, (req->buf + dev->cur_read_pos), xfer))
  376. r = -EFAULT;
  377. }
  378. if (count >= cur_actual) {
  379. apple_vsc_rx_submit(dev, req);//the req is read completely, return to the usb core
  380. dev->cur_read_pos = 0;
  381. } else {
  382. dev->cur_read_pos += count;
  383. spin_lock_irqsave(&dev->lock, flags);//the request buffer isn't completely read ,return the req to the head of the list of rx_used
  384. list_add(&req->list, &dev->rx_used);
  385. spin_unlock_irqrestore(&dev->lock, flags);
  386. }
  387. } else {// IO error
  388. if (dev->error)
  389. r = -EIO;
  390. if (dev->online == 0)
  391. r = -ENODEV;
  392. if (req) {
  393. spin_lock_irqsave(&dev->lock, flags);
  394. list_add(&req->list, &dev->rx_used);
  395. spin_unlock_irqrestore(&dev->lock, flags);
  396. }
  397. }
  398. done:
  399. apple_vsc_unlock(&dev->read_excl);
  400. pr_debug("apple_vsc_read returning %d\n", r);
  401. return r;
  402. }
  403. static ssize_t apple_vsc_write(struct file *fp, const char __user *buf,
  404. size_t count, loff_t *pos)
  405. {
  406. struct f_apple_vsc_sim *dev = fp->private_data;
  407. struct usb_request *req = 0;
  408. int r = count, xfer;
  409. int ret;
  410. if (!dev)
  411. return -ENODEV;
  412. pr_debug("apple_vsc_write(%d)\n", (int)count);
  413. if (apple_vsc_lock(&dev->write_excl))
  414. return -EBUSY;
  415. while (count > 0) {
  416. if (dev->error) {
  417. pr_debug("apple_vsc_write dev->error\n");
  418. r = -EIO;
  419. break;
  420. }
  421. if (dev->online == 0) {
  422. pr_debug("apple_vsc_write dev->online == 0\n");
  423. r = -ENODEV;
  424. break;
  425. }
  426. req = 0;
  427. ret = wait_event_interruptible_timeout(dev->write_wq,
  428. ((req = apple_vsc_req_get(dev, &dev->tx_idle)) || (dev->error) || (dev->online == 0)), msecs_to_jiffies(1000));
  429. if (ret <= 0) {
  430. r = ret;
  431. break;
  432. }
  433. if (req != 0) {
  434. if (count > SD_BULK_BUFFER_SIZE)
  435. xfer = SD_BULK_BUFFER_SIZE;
  436. else
  437. xfer = count;
  438. if (copy_from_user(req->buf, buf, xfer)) {
  439. r = -EFAULT;
  440. break;
  441. }
  442. req->length = xfer;
  443. ret = usb_ep_queue(dev->ep_in, req, GFP_ATOMIC);
  444. if (ret < 0) {
  445. pr_debug("apple_vsc_write: xfer error %d\n", ret);
  446. dev->error = 1;
  447. r = -EIO;
  448. break;
  449. }
  450. buf += xfer;
  451. count -= xfer;
  452. req = 0;
  453. }
  454. }
  455. if (req)
  456. apple_vsc_req_put(dev, &dev->tx_idle, req);
  457. //done:
  458. apple_vsc_unlock(&dev->write_excl);
  459. pr_debug("apple_vsc_write returning %d\n", r);
  460. return r;
  461. }
  462. static struct f_apple_vsc_sim *apple_vsc_locate(int minor)
  463. {
  464. struct f_apple_vsc_sim *pctx;
  465. list_for_each_entry(pctx, &apple_vsc_list, node) {
  466. if (pctx->device.minor == minor)
  467. return pctx;
  468. }
  469. return NULL;
  470. }
  471. static int apple_vsc_open(struct inode *ip, struct file *fp)
  472. {
  473. int retval = -1;
  474. struct f_apple_vsc_sim *pctx;
  475. retval = mutex_lock_interruptible(&apple_vsc_mutex);
  476. if (retval)
  477. return retval;
  478. pctx = apple_vsc_locate(iminor(ip));
  479. if (!pctx) {
  480. retval = -ENODEV;
  481. goto out;
  482. }
  483. if (apple_vsc_lock(&pctx->open_excl))
  484. return -EBUSY;
  485. fp->private_data = pctx;
  486. pctx->error = 0;
  487. pctx->rx_done = 0;
  488. //printk(KERN_INFO "apple_mux_open\n", g_apple_mux_dev->online);
  489. retval = 0;
  490. out:
  491. mutex_unlock(&apple_vsc_mutex);
  492. return retval;
  493. }
  494. static int apple_vsc_release(struct inode *ip, struct file *fp)
  495. {
  496. struct f_apple_vsc_sim *dev = fp->private_data;
  497. //printk(KERN_INFO "apple_mux_release\n");
  498. apple_vsc_unlock(&dev->open_excl);
  499. return 0;
  500. }
  501. static unsigned int apple_vsc_poll(struct file *fp, struct poll_table_struct *wait)
  502. {
  503. struct f_apple_vsc_sim *dev = fp->private_data;
  504. unsigned int mask = 0;
  505. //printk("dev->online = %d, dev->error = %d dev->rx_done = %d \n", dev->online, dev->error, dev->rx_done);
  506. poll_wait(fp, &dev->write_wq, wait);
  507. poll_wait(fp, &dev->read_wq, wait);
  508. if (fp->f_mode & FMODE_READ && dev->online && (!dev->error) && (!list_empty_careful(&dev->rx_used)))
  509. mask |= POLLIN| POLLRDNORM;
  510. if (fp->f_mode & FMODE_WRITE && dev->online && (!dev->error) && (!list_empty_careful(&dev->tx_idle)))
  511. mask |= POLLOUT | POLLWRNORM;
  512. return mask;
  513. }
  514. #define MUX_IOCTL_BASE 0xb7
  515. #define MUX_GET_ONLINE_STATE _IOW(MUX_IOCTL_BASE, 0, unsigned long)
  516. static long apple_vsc_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
  517. {
  518. struct f_apple_vsc_sim *dev = fp->private_data;
  519. long res = 0;
  520. int online = 0;
  521. switch(cmd) {
  522. case MUX_GET_ONLINE_STATE:
  523. //printk("dev->online = %d\n", dev->online);
  524. online = dev->online;
  525. if (copy_to_user((void*)arg, &online, sizeof(online))) {
  526. return -EFAULT;
  527. }
  528. break;
  529. }
  530. return res;
  531. }
  532. /* file operations for iap2 device /dev/iap2 */
  533. static struct file_operations apple_vsc_fops = {
  534. .owner = THIS_MODULE,
  535. .read = apple_vsc_read,
  536. .write = apple_vsc_write,
  537. .unlocked_ioctl = apple_vsc_ioctl,
  538. .open = apple_vsc_open,
  539. .poll = apple_vsc_poll,
  540. .release = apple_vsc_release,
  541. };
  542. static int apple_vsc_setup(struct f_apple_vsc_sim *dev, int intc, int intf)
  543. {
  544. int ret = -1;
  545. if (dev == NULL)
  546. return -1;
  547. spin_lock_init(&dev->lock);
  548. init_waitqueue_head(&dev->read_wq);
  549. init_waitqueue_head(&dev->write_wq);
  550. atomic_set(&dev->open_excl, 0);
  551. atomic_set(&dev->read_excl, 0);
  552. atomic_set(&dev->write_excl, 0);
  553. INIT_LIST_HEAD(&dev->tx_idle);
  554. INIT_LIST_HEAD(&dev->rx_idle);
  555. INIT_LIST_HEAD(&dev->rx_used);
  556. mutex_lock(&apple_vsc_mutex);
  557. list_add_tail(&dev->node, &apple_vsc_list);
  558. mutex_unlock(&apple_vsc_mutex);
  559. dev->name = (char *)kzalloc(32, GFP_KERNEL);
  560. if (dev->name == NULL) {
  561. ret = -ENOMEM;
  562. goto err;
  563. }
  564. sprintf(dev->name, "apple_vsc_c%d_i%d", intc, intf);
  565. dev->device.name = dev->name;
  566. dev->device.parent = &dev->cdev->gadget->dev;
  567. dev->device.minor = MISC_DYNAMIC_MINOR;
  568. dev->device.fops = &apple_vsc_fops;
  569. ret = misc_register(&dev->device);
  570. if (ret)
  571. goto err;
  572. return ret;
  573. err:
  574. if (dev->name)
  575. kfree(dev->name);
  576. printk(KERN_ERR "iap2 gadget driver failed to initialize\n");
  577. return ret;
  578. }
  579. static void apple_vsc_cleanup(struct f_apple_vsc_sim *dev)
  580. {
  581. if (dev->name) {
  582. kfree(dev->name);
  583. dev->name = NULL;
  584. }
  585. misc_deregister(&dev->device);
  586. mutex_lock(&apple_vsc_mutex);
  587. list_del(&dev->node);
  588. mutex_unlock(&apple_vsc_mutex);
  589. }
  590. static int apple_vsc_sim_bind(struct usb_configuration *c, struct usb_function *f)
  591. {
  592. // struct usb_composite_dev *cdev = c->cdev;
  593. int id;
  594. // struct usb_ep *ep_in = NULL, *ep_out = NULL;
  595. struct f_apple_vsc_sim *dev = func_to_apple_vsc_sim(f);
  596. printk("%s:%d\n", __func__, __LINE__);
  597. #if 0
  598. struct usb_string *us;
  599. /* maybe allocate device-global string IDs, and patch descriptors */
  600. us = usb_gstrings_attach(c->cdev, apple_vsc_sim_strings,
  601. ARRAY_SIZE(apple_vsc_sim_string_defs));
  602. if (IS_ERR(us))
  603. return PTR_ERR(us);
  604. apple_vsc_sim_intf0.iInterface = us[FUNC_VSC_IDX].id;
  605. apple_vsc_sim_intf0.iInterface = us[FUNC_VSC_IDX].id;
  606. #endif
  607. /* allocate interface ID(s) */
  608. id = usb_interface_id(c, f);
  609. if (id < 0)
  610. return id;
  611. apple_vsc_sim.bInterfaceNumber = id;
  612. apple_vsc_sim_intf0.bInterfaceNumber = id;
  613. apple_vsc_sim_intf1.bInterfaceNumber = id;
  614. dev->cdev = c->cdev;
  615. //ep_in = usb_ep_autoconfig(cdev->gadget, &fs_apple_vsc_sim_source_desc);
  616. //ep_out = usb_ep_autoconfig(cdev->gadget, &fs_apple_vsc_sim_sink_desc);
  617. fs_apple_vsc_sim_source_desc.bEndpointAddress = 0x86;
  618. fs_apple_vsc_sim_sink_desc.bEndpointAddress = 0x05;
  619. /* support high speed hardware */
  620. if (gadget_is_dualspeed(c->cdev->gadget)) {
  621. hs_apple_vsc_sim_source_desc.bEndpointAddress = fs_apple_vsc_sim_source_desc.bEndpointAddress;
  622. hs_apple_vsc_sim_sink_desc.bEndpointAddress = fs_apple_vsc_sim_sink_desc.bEndpointAddress;
  623. f->hs_descriptors = hs_apple_vsc_sim_descs;
  624. }
  625. /* support super speed hardware */
  626. if (gadget_is_superspeed(c->cdev->gadget)) {
  627. ss_apple_vsc_sim_source_desc.bEndpointAddress =
  628. fs_apple_vsc_sim_source_desc.bEndpointAddress;
  629. ss_apple_vsc_sim_sink_desc.bEndpointAddress =
  630. fs_apple_vsc_sim_sink_desc.bEndpointAddress;
  631. f->ss_descriptors = ss_apple_vsc_sim_descs;
  632. }
  633. if (apple_vsc_setup(dev, c->bConfigurationValue, id)) {
  634. return -1;
  635. }
  636. return 0;
  637. }
  638. static void apple_vsc_sim_unbind(struct usb_configuration *c, struct usb_function *f)
  639. {
  640. struct f_apple_vsc_sim *dev = func_to_apple_vsc_sim(f);
  641. struct usb_request *req = NULL;
  642. (void)c;
  643. printk("%s:%d\n", __func__, __LINE__);
  644. dev->online = 0;
  645. dev->error = 1;
  646. wake_up(&dev->read_wq);
  647. wake_up(&dev->write_wq);
  648. while ((req = apple_vsc_req_get(dev, &dev->rx_idle)))
  649. apple_vsc_request_free(req, dev->ep_out);
  650. req = NULL;
  651. while ((req = apple_vsc_req_get(dev, &dev->rx_used)))
  652. apple_vsc_request_free(req, dev->ep_out);
  653. req = NULL;
  654. while ((req = apple_vsc_req_get(dev, &dev->tx_idle)))
  655. apple_vsc_request_free(req, dev->ep_in);
  656. dev->cur_read_pos = 0;
  657. apple_vsc_cleanup(dev);
  658. }
  659. static int apple_vsc_sim_set_alt(struct usb_function *f,
  660. unsigned intf, unsigned alt)
  661. {printk("%s:%d\n", __func__, __LINE__);
  662. (void)f;
  663. (void)intf;
  664. (void)alt;
  665. return 0;
  666. }
  667. static void apple_vsc_sim_disable(struct usb_function *f)
  668. {
  669. (void)f;
  670. }
  671. static int apple_vsc_sim_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
  672. {
  673. struct usb_composite_dev *cdev = f->config->cdev;
  674. struct usb_request *req = cdev->req;
  675. int value = -EOPNOTSUPP;
  676. u16 w_index = le16_to_cpu(ctrl->wIndex);
  677. u16 w_value = le16_to_cpu(ctrl->wValue);
  678. u16 w_length = le16_to_cpu(ctrl->wLength);
  679. char result[4] = {0x01, 0x00, 0x00, 0x00};
  680. printk("%s-->bRequestType=%02x bRequest=%02x\n", __func__, ctrl->bRequestType, ctrl->bRequest);
  681. switch (ctrl->bRequestType) {
  682. case 0x40 :
  683. printk("%s %x-->receive switch ctrl\n", __func__, ctrl->bRequest);
  684. if (ctrl->bRequest != 0x51)
  685. break;
  686. value = 0;
  687. usb_dev_ready_notify(1);
  688. break;
  689. case 0xc0 :
  690. printk("%s %x-->receive query ctrl\n", __func__, ctrl->bRequest);
  691. if (ctrl->bRequest != 0x53)
  692. break;
  693. value = 4;
  694. memcpy(req->buf, result, value);
  695. break;
  696. default:
  697. value = 0;
  698. DBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
  699. ctrl->bRequestType, ctrl->bRequest,
  700. w_value, w_index, w_length);
  701. }
  702. if (value >= 0) {
  703. req->zero = 0;
  704. req->length = value;
  705. value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
  706. if (value < 0)
  707. ERROR(cdev, "ncm req %02x.%02x response err %d\n",
  708. ctrl->bRequestType, ctrl->bRequest,
  709. value);
  710. }
  711. return value;
  712. }
  713. static void apple_vsc_sim_free_func(struct usb_function *f)
  714. {
  715. struct f_apple_vsc_sim *dev;
  716. struct f_apple_vsc_sim_opts *opts;
  717. printk("%s:%d\n", __func__, __LINE__);
  718. dev = func_to_apple_vsc_sim(f);
  719. opts = container_of(f->fi, struct f_apple_vsc_sim_opts, func_inst);
  720. apple_vsc_cleanup(dev);
  721. kfree(dev);
  722. mutex_lock(&opts->lock);
  723. opts->refcnt--;
  724. mutex_unlock(&opts->lock);printk("%s:%d\n", __func__, __LINE__);
  725. }
  726. static inline struct f_apple_vsc_sim_opts *to_f_apple_vsc_sim_opts(struct config_item *item)
  727. {
  728. return container_of(to_config_group(item), struct f_apple_vsc_sim_opts,
  729. func_inst.group);
  730. }
  731. static ssize_t f_apple_vsc_sim_opts_iso_qlen_show(struct config_item *item, char *page)
  732. {
  733. struct f_apple_vsc_sim_opts *opts = to_f_apple_vsc_sim_opts(item);
  734. int result;
  735. mutex_lock(&opts->lock);
  736. result = sprintf(page, "%u\n", opts->iso_qlen);
  737. mutex_unlock(&opts->lock);
  738. return result;
  739. }
  740. static ssize_t f_apple_vsc_sim_opts_iso_qlen_store(struct config_item *item,
  741. const char *page, size_t len)
  742. {
  743. struct f_apple_vsc_sim_opts *opts = to_f_apple_vsc_sim_opts(item);
  744. int ret;
  745. u32 num;
  746. mutex_lock(&opts->lock);
  747. if (opts->refcnt) {
  748. ret = -EBUSY;
  749. goto end;
  750. }
  751. ret = kstrtou32(page, 0, &num);
  752. if (ret)
  753. goto end;
  754. opts->iso_qlen = num;
  755. ret = len;
  756. end:
  757. mutex_unlock(&opts->lock);
  758. return ret;
  759. }
  760. static void apple_vsc_sim_attr_release(struct config_item *item)
  761. {
  762. struct f_apple_vsc_sim_opts *ss_opts = to_f_apple_vsc_sim_opts(item);
  763. usb_put_function_instance(&ss_opts->func_inst);
  764. }
  765. static struct configfs_item_operations apple_vsc_sim_item_ops = {
  766. .release = apple_vsc_sim_attr_release,
  767. };
  768. CONFIGFS_ATTR(f_apple_vsc_sim_opts_, iso_qlen);
  769. static struct configfs_attribute *apple_vsc_sim_attrs[] = {
  770. &f_apple_vsc_sim_opts_attr_iso_qlen,
  771. NULL,
  772. };
  773. static struct config_item_type apple_vsc_sim_func_type = {
  774. .ct_item_ops = &apple_vsc_sim_item_ops,
  775. .ct_attrs = apple_vsc_sim_attrs,
  776. .ct_owner = THIS_MODULE,
  777. };
  778. static void apple_vsc_sim_free_inst(struct usb_function_instance *f)
  779. {
  780. struct f_apple_vsc_sim_opts *opts;
  781. opts = container_of(f, struct f_apple_vsc_sim_opts, func_inst);
  782. printk("%s:%d\n", __func__, __LINE__);
  783. kfree(opts);
  784. }
  785. static struct usb_function_instance *apple_vsc_sim_alloc_inst(void)
  786. {
  787. struct f_apple_vsc_sim_opts *opts = NULL;
  788. opts = kzalloc(sizeof(*opts), GFP_KERNEL);
  789. if (!opts)
  790. return ERR_PTR(-ENOMEM);
  791. mutex_init(&opts->lock);
  792. opts->func_inst.free_func_inst = apple_vsc_sim_free_inst;
  793. config_group_init_type_name(&opts->func_inst.group, "", &apple_vsc_sim_func_type);
  794. printk("%s:%d\n", __func__, __LINE__);
  795. return &opts->func_inst;
  796. }
  797. static struct usb_function *apple_vsc_sim_alloc(struct usb_function_instance *fi)
  798. {
  799. struct f_apple_vsc_sim *pctx = NULL;
  800. struct f_apple_vsc_sim_opts *opts = NULL;
  801. printk("%s:%d\n", __func__, __LINE__);
  802. pctx = kzalloc(sizeof *pctx, GFP_KERNEL);
  803. if (!pctx)
  804. return NULL;
  805. opts = container_of(fi, struct f_apple_vsc_sim_opts, func_inst);
  806. mutex_lock(&opts->lock);
  807. opts->refcnt++;
  808. mutex_unlock(&opts->lock);
  809. pctx->function.name = "vsc";
  810. pctx->function.fs_descriptors = fs_apple_vsc_sim_descs;
  811. pctx->function.bind = apple_vsc_sim_bind;
  812. pctx->function.unbind = apple_vsc_sim_unbind;
  813. pctx->function.set_alt = apple_vsc_sim_set_alt;
  814. pctx->function.disable = apple_vsc_sim_disable;
  815. pctx->function.setup = apple_vsc_sim_setup;
  816. pctx->function.free_func = apple_vsc_sim_free_func;
  817. printk("%s:%d\n", __func__, __LINE__);
  818. return &pctx->function;
  819. }
  820. DECLARE_USB_FUNCTION_INIT(vsc, apple_vsc_sim_alloc_inst, apple_vsc_sim_alloc);
  821. MODULE_LICENSE("GPL");
  822. MODULE_AUTHOR("art");