f_apple_mux_sim.c 23 KB

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