smux_ctl.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088
  1. /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. /*
  13. * Serial Mux Control Driver -- Provides a binary serial muxed control
  14. * port interface.
  15. */
  16. #define DEBUG
  17. #include <linux/cdev.h>
  18. #include <linux/types.h>
  19. #include <linux/module.h>
  20. #include <linux/fs.h>
  21. #include <linux/device.h>
  22. #include <linux/delay.h>
  23. #include <linux/sched.h>
  24. #include <linux/spinlock.h>
  25. #include <linux/mutex.h>
  26. #include <linux/uaccess.h>
  27. #include <linux/workqueue.h>
  28. #include <linux/atomic.h>
  29. #include <linux/platform_device.h>
  30. #include <linux/smux.h>
  31. #include <linux/slab.h>
  32. #include <linux/debugfs.h>
  33. #include <linux/poll.h>
  34. #include <asm/ioctls.h>
  35. #define MAX_WRITE_RETRY 5
  36. #define MAGIC_NO_V1 0x33FC
  37. #define DEVICE_NAME "smuxctl"
  38. #define SMUX_CTL_MAX_BUF_SIZE 2048
  39. #define SMUX_CTL_MODULE_NAME "smux_ctl"
  40. #define DEBUG
  41. static int msm_smux_ctl_debug_mask;
  42. module_param_named(debug_mask, msm_smux_ctl_debug_mask,
  43. int, S_IRUGO | S_IWUSR | S_IWGRP);
  44. static uint32_t smux_ctl_ch_id[] = {
  45. SMUX_DATA_CTL_0,
  46. SMUX_DATA_CTL_1,
  47. };
  48. #define SMUX_CTL_NUM_CHANNELS ARRAY_SIZE(smux_ctl_ch_id)
  49. #define DEFAULT_OPEN_TIMEOUT 5
  50. struct smux_ctl_dev {
  51. int id;
  52. char name[10];
  53. struct cdev cdev;
  54. struct device *devicep;
  55. struct mutex dev_lock;
  56. atomic_t ref_count;
  57. int state;
  58. int is_channel_reset;
  59. int is_high_wm;
  60. int write_pending;
  61. unsigned open_timeout_val;
  62. struct mutex rx_lock;
  63. uint32_t read_avail;
  64. struct list_head rx_list;
  65. int abort_wait;
  66. wait_queue_head_t read_wait_queue;
  67. wait_queue_head_t write_wait_queue;
  68. struct {
  69. uint32_t bytes_tx;
  70. uint32_t bytes_rx;
  71. uint32_t pkts_tx;
  72. uint32_t pkts_rx;
  73. uint32_t cnt_ssr;
  74. uint32_t cnt_read_fail;
  75. uint32_t cnt_write_fail;
  76. uint32_t cnt_high_wm_hit;
  77. } stats;
  78. } *smux_ctl_devp[SMUX_CTL_NUM_CHANNELS];
  79. struct smux_ctl_pkt {
  80. int data_size;
  81. void *data;
  82. };
  83. struct smux_ctl_list_elem {
  84. struct list_head list;
  85. struct smux_ctl_pkt ctl_pkt;
  86. };
  87. struct class *smux_ctl_classp;
  88. static dev_t smux_ctl_number;
  89. static uint32_t smux_ctl_inited;
  90. enum {
  91. MSM_SMUX_CTL_DEBUG = 1U << 0,
  92. MSM_SMUX_CTL_DUMP_BUFFER = 1U << 1,
  93. };
  94. #if defined(DEBUG)
  95. static const char *smux_ctl_event_str[] = {
  96. "SMUX_CONNECTED",
  97. "SMUX_DISCONNECTED",
  98. "SMUX_READ_DONE",
  99. "SMUX_READ_FAIL",
  100. "SMUX_WRITE_DONE",
  101. "SMUX_WRITE_FAIL",
  102. "SMUX_TIOCM_UPDATE",
  103. "SMUX_LOW_WM_HIT",
  104. "SMUX_HIGH_WM_HIT",
  105. };
  106. #define SMUXCTL_DUMP_BUFFER(prestr, cnt, buf) \
  107. do { \
  108. if (msm_smux_ctl_debug_mask & MSM_SMUX_CTL_DUMP_BUFFER) { \
  109. int i; \
  110. pr_err("%s", prestr); \
  111. for (i = 0; i < cnt; i++) \
  112. pr_err("%.2x", buf[i]); \
  113. pr_err("\n"); \
  114. } \
  115. } while (0)
  116. #define SMUXCTL_DBG(x...) \
  117. do { \
  118. if (msm_smux_ctl_debug_mask & MSM_SMUX_CTL_DEBUG) \
  119. pr_err(x); \
  120. } while (0)
  121. #else
  122. #define SMUXCTL_DUMP_BUFFER(prestr, cnt, buf) do {} while (0)
  123. #define SMUXCTL_DBG(x...) do {} while (0)
  124. #endif
  125. #if defined(DEBUG_LOOPBACK)
  126. #define SMUXCTL_SET_LOOPBACK(lcid) \
  127. msm_smux_set_ch_option(lcid, SMUX_CH_OPTION_LOCAL_LOOPBACK, 0)
  128. #else
  129. #define SMUXCTL_SET_LOOPBACK(lcid) do {} while (0)
  130. #endif
  131. static ssize_t open_timeout_store(struct device *d,
  132. struct device_attribute *attr,
  133. const char *buf,
  134. size_t n)
  135. {
  136. int i;
  137. unsigned long tmp;
  138. for (i = 0; i < SMUX_CTL_NUM_CHANNELS; ++i) {
  139. if (smux_ctl_devp[i]->devicep == d)
  140. break;
  141. }
  142. if (i >= SMUX_CTL_NUM_CHANNELS) {
  143. pr_err("%s: unable to match device to valid smux ctl port\n",
  144. __func__);
  145. return -EINVAL;
  146. }
  147. if (!kstrtoul(buf, 10, &tmp)) {
  148. smux_ctl_devp[i]->open_timeout_val = tmp;
  149. return n;
  150. } else {
  151. pr_err("%s: unable to convert: %s to an int\n", __func__,
  152. buf);
  153. return -EINVAL;
  154. }
  155. }
  156. static ssize_t open_timeout_show(struct device *d,
  157. struct device_attribute *attr,
  158. char *buf)
  159. {
  160. int i;
  161. for (i = 0; i < SMUX_CTL_NUM_CHANNELS; ++i) {
  162. if (smux_ctl_devp[i]->devicep == d)
  163. break;
  164. }
  165. if (i >= SMUX_CTL_NUM_CHANNELS) {
  166. pr_err("%s: unable to match device to valid smux ctl port\n",
  167. __func__);
  168. return -EINVAL;
  169. }
  170. return snprintf(buf, PAGE_SIZE, "%d\n",
  171. smux_ctl_devp[i]->open_timeout_val);
  172. }
  173. static DEVICE_ATTR(open_timeout, 0664, open_timeout_show, open_timeout_store);
  174. static int get_ctl_dev_index(int id)
  175. {
  176. int dev_index;
  177. for (dev_index = 0; dev_index < SMUX_CTL_NUM_CHANNELS; dev_index++) {
  178. if (smux_ctl_ch_id[dev_index] == id)
  179. return dev_index;
  180. }
  181. return -ENODEV;
  182. }
  183. static int smux_ctl_get_rx_buf_cb(void *priv, void **pkt_priv,
  184. void **buffer, int size)
  185. {
  186. void *buf = NULL;
  187. int id = ((struct smux_ctl_dev *)(priv))->id;
  188. int dev_index;
  189. if (id < 0 || id > smux_ctl_ch_id[SMUX_CTL_NUM_CHANNELS - 1])
  190. return -ENODEV;
  191. if (!buffer || 0 >= size)
  192. return -EINVAL;
  193. dev_index = get_ctl_dev_index(id);
  194. if (dev_index < 0) {
  195. pr_err(SMUX_CTL_MODULE_NAME ": %s: Ch%d is not "
  196. "exported to user-space\n",
  197. __func__, id);
  198. return -ENODEV;
  199. }
  200. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s: Allocating Rx buf size %d "
  201. "for ch%d\n",
  202. __func__, size, smux_ctl_devp[dev_index]->id);
  203. buf = kmalloc(size, GFP_KERNEL);
  204. if (!buf) {
  205. pr_err(SMUX_CTL_MODULE_NAME ": %s: buffer allocation failed: "
  206. "Ch%d, size %d ", __func__, id, size);
  207. return -ENOMEM;
  208. }
  209. *buffer = buf;
  210. *pkt_priv = NULL;
  211. return 0;
  212. }
  213. void smux_ctl_notify_cb(void *priv, int event_type, const void *metadata)
  214. {
  215. int id = ((struct smux_ctl_dev *)(priv))->id;
  216. struct smux_ctl_list_elem *list_elem = NULL;
  217. int dev_index;
  218. void *data;
  219. int len;
  220. if (id < 0 || id > smux_ctl_ch_id[SMUX_CTL_NUM_CHANNELS - 1])
  221. return;
  222. dev_index = get_ctl_dev_index(id);
  223. if (dev_index < 0) {
  224. pr_err(SMUX_CTL_MODULE_NAME ": %s: Ch%d is not exported "
  225. "to user-space\n", __func__, id);
  226. return;
  227. }
  228. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s: Ch%d, Event %d (%s)\n",
  229. __func__, smux_ctl_devp[dev_index]->id,
  230. event_type, smux_ctl_event_str[event_type]);
  231. switch (event_type) {
  232. case SMUX_CONNECTED:
  233. mutex_lock(&smux_ctl_devp[dev_index]->dev_lock);
  234. smux_ctl_devp[dev_index]->state = SMUX_CONNECTED;
  235. smux_ctl_devp[dev_index]->is_high_wm = 0;
  236. smux_ctl_devp[dev_index]->is_channel_reset = 0;
  237. smux_ctl_devp[dev_index]->read_avail = 0;
  238. mutex_unlock(&smux_ctl_devp[dev_index]->dev_lock);
  239. wake_up(&smux_ctl_devp[dev_index]->write_wait_queue);
  240. break;
  241. case SMUX_DISCONNECTED:
  242. mutex_lock(&smux_ctl_devp[dev_index]->dev_lock);
  243. smux_ctl_devp[dev_index]->state = SMUX_DISCONNECTED;
  244. smux_ctl_devp[dev_index]->is_channel_reset =
  245. ((struct smux_meta_disconnected *)metadata)->is_ssr;
  246. if (smux_ctl_devp[dev_index]->is_channel_reset)
  247. smux_ctl_devp[dev_index]->stats.cnt_ssr++;
  248. mutex_unlock(&smux_ctl_devp[dev_index]->dev_lock);
  249. wake_up(&smux_ctl_devp[dev_index]->write_wait_queue);
  250. wake_up(&smux_ctl_devp[dev_index]->read_wait_queue);
  251. break;
  252. case SMUX_READ_FAIL:
  253. data = ((struct smux_meta_read *)metadata)->buffer;
  254. kfree(data);
  255. mutex_lock(&smux_ctl_devp[dev_index]->dev_lock);
  256. smux_ctl_devp[dev_index]->stats.cnt_read_fail++;
  257. mutex_unlock(&smux_ctl_devp[dev_index]->dev_lock);
  258. wake_up(&smux_ctl_devp[dev_index]->read_wait_queue);
  259. break;
  260. case SMUX_READ_DONE:
  261. data = ((struct smux_meta_read *)metadata)->buffer;
  262. len = ((struct smux_meta_read *)metadata)->len;
  263. if (data && len > 0) {
  264. list_elem = kmalloc(sizeof(struct smux_ctl_list_elem),
  265. GFP_KERNEL);
  266. if (list_elem) {
  267. list_elem->ctl_pkt.data = data;
  268. list_elem->ctl_pkt.data_size = len;
  269. mutex_lock(&smux_ctl_devp[dev_index]->rx_lock);
  270. list_add_tail(&list_elem->list,
  271. &smux_ctl_devp[dev_index]->rx_list);
  272. smux_ctl_devp[dev_index]->read_avail += len;
  273. mutex_unlock(
  274. &smux_ctl_devp[dev_index]->rx_lock);
  275. } else {
  276. kfree(data);
  277. }
  278. }
  279. wake_up(&smux_ctl_devp[dev_index]->read_wait_queue);
  280. break;
  281. case SMUX_WRITE_DONE:
  282. mutex_lock(&smux_ctl_devp[dev_index]->dev_lock);
  283. smux_ctl_devp[dev_index]->write_pending = 0;
  284. mutex_unlock(&smux_ctl_devp[dev_index]->dev_lock);
  285. data = ((struct smux_meta_write *)metadata)->buffer;
  286. kfree(data);
  287. wake_up(&smux_ctl_devp[dev_index]->write_wait_queue);
  288. break;
  289. case SMUX_WRITE_FAIL:
  290. data = ((struct smux_meta_write *)metadata)->buffer;
  291. kfree(data);
  292. mutex_lock(&smux_ctl_devp[dev_index]->dev_lock);
  293. smux_ctl_devp[dev_index]->stats.cnt_write_fail++;
  294. mutex_unlock(&smux_ctl_devp[dev_index]->dev_lock);
  295. wake_up(&smux_ctl_devp[dev_index]->write_wait_queue);
  296. break;
  297. case SMUX_LOW_WM_HIT:
  298. mutex_lock(&smux_ctl_devp[dev_index]->dev_lock);
  299. smux_ctl_devp[dev_index]->is_high_wm = 0;
  300. mutex_unlock(&smux_ctl_devp[dev_index]->dev_lock);
  301. wake_up(&smux_ctl_devp[dev_index]->write_wait_queue);
  302. break;
  303. case SMUX_HIGH_WM_HIT:
  304. mutex_lock(&smux_ctl_devp[dev_index]->dev_lock);
  305. smux_ctl_devp[dev_index]->is_high_wm = 1;
  306. smux_ctl_devp[dev_index]->stats.cnt_high_wm_hit++;
  307. mutex_unlock(&smux_ctl_devp[dev_index]->dev_lock);
  308. break;
  309. case SMUX_TIOCM_UPDATE:
  310. default:
  311. pr_err(SMUX_CTL_MODULE_NAME ": %s: Event %d not supported\n",
  312. __func__, event_type);
  313. break;
  314. }
  315. }
  316. int smux_ctl_open(struct inode *inode, struct file *file)
  317. {
  318. int r = 0;
  319. struct smux_ctl_dev *devp;
  320. unsigned wait_time = DEFAULT_OPEN_TIMEOUT * HZ;
  321. if (!smux_ctl_inited)
  322. return -EIO;
  323. devp = container_of(inode->i_cdev, struct smux_ctl_dev, cdev);
  324. if (!devp)
  325. return -ENODEV;
  326. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s called on smuxctl%d device\n",
  327. __func__, devp->id);
  328. if (1 == atomic_add_return(1, &devp->ref_count)) {
  329. SMUXCTL_SET_LOOPBACK(devp->id);
  330. r = msm_smux_open(devp->id,
  331. devp,
  332. smux_ctl_notify_cb,
  333. smux_ctl_get_rx_buf_cb);
  334. if (r < 0) {
  335. pr_err(SMUX_CTL_MODULE_NAME ": %s: smux_open failed "
  336. "for smuxctl%d with rc %d\n",
  337. __func__, devp->id, r);
  338. atomic_dec(&devp->ref_count);
  339. return r;
  340. }
  341. if (devp->open_timeout_val)
  342. wait_time = devp->open_timeout_val * HZ;
  343. r = wait_event_interruptible_timeout(
  344. devp->write_wait_queue,
  345. (devp->state == SMUX_CONNECTED ||
  346. devp->abort_wait),
  347. wait_time);
  348. if (r == 0)
  349. r = -ETIMEDOUT;
  350. if (r < 0) {
  351. pr_err(SMUX_CTL_MODULE_NAME ": %s: "
  352. "SMUX open timed out: %d, LCID %d\n",
  353. __func__, r, devp->id);
  354. atomic_dec(&devp->ref_count);
  355. msm_smux_close(devp->id);
  356. return r;
  357. } else if (devp->abort_wait) {
  358. pr_err("%s: %s: Open command aborted\n",
  359. SMUX_CTL_MODULE_NAME, __func__);
  360. r = -EIO;
  361. atomic_dec(&devp->ref_count);
  362. msm_smux_close(devp->id);
  363. return r;
  364. } else if (devp->state != SMUX_CONNECTED) {
  365. pr_err(SMUX_CTL_MODULE_NAME ": %s: "
  366. "Invalid open notification\n", __func__);
  367. r = -ENODEV;
  368. atomic_dec(&devp->ref_count);
  369. msm_smux_close(devp->id);
  370. return r;
  371. }
  372. }
  373. file->private_data = devp;
  374. return 0;
  375. }
  376. int smux_ctl_release(struct inode *inode, struct file *file)
  377. {
  378. struct smux_ctl_dev *devp;
  379. struct smux_ctl_list_elem *list_elem = NULL;
  380. devp = file->private_data;
  381. if (!devp)
  382. return -EINVAL;
  383. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s called on smuxctl%d device\n",
  384. __func__, devp->id);
  385. mutex_lock(&devp->dev_lock);
  386. if (atomic_dec_and_test(&devp->ref_count)) {
  387. mutex_lock(&devp->rx_lock);
  388. while (!list_empty(&devp->rx_list)) {
  389. list_elem = list_first_entry(
  390. &devp->rx_list,
  391. struct smux_ctl_list_elem,
  392. list);
  393. list_del(&list_elem->list);
  394. kfree(list_elem->ctl_pkt.data);
  395. kfree(list_elem);
  396. }
  397. devp->read_avail = 0;
  398. mutex_unlock(&devp->rx_lock);
  399. msm_smux_close(devp->id);
  400. }
  401. mutex_unlock(&devp->dev_lock);
  402. file->private_data = NULL;
  403. return 0;
  404. }
  405. static int smux_ctl_readable(int id)
  406. {
  407. int r;
  408. int dev_index;
  409. if (id < 0 || id > smux_ctl_ch_id[SMUX_CTL_NUM_CHANNELS - 1])
  410. return -ENODEV;
  411. dev_index = get_ctl_dev_index(id);
  412. if (dev_index < 0) {
  413. pr_err(SMUX_CTL_MODULE_NAME ": %s: Ch%d "
  414. "is not exported to user-space\n",
  415. __func__, id);
  416. return -ENODEV;
  417. }
  418. mutex_lock(&smux_ctl_devp[dev_index]->dev_lock);
  419. if (signal_pending(current))
  420. r = -ERESTARTSYS;
  421. else if (smux_ctl_devp[dev_index]->abort_wait)
  422. r = -ENETRESET;
  423. else if (smux_ctl_devp[dev_index]->state == SMUX_DISCONNECTED &&
  424. smux_ctl_devp[dev_index]->is_channel_reset != 0)
  425. r = -ENETRESET;
  426. else if (smux_ctl_devp[dev_index]->state != SMUX_CONNECTED)
  427. r = -ENODEV;
  428. else
  429. r = smux_ctl_devp[dev_index]->read_avail;
  430. mutex_unlock(&smux_ctl_devp[dev_index]->dev_lock);
  431. return r;
  432. }
  433. ssize_t smux_ctl_read(struct file *file,
  434. char __user *buf,
  435. size_t count,
  436. loff_t *ppos)
  437. {
  438. int r = 0, id, bytes_to_read, read_err;
  439. struct smux_ctl_dev *devp;
  440. struct smux_ctl_list_elem *list_elem = NULL;
  441. devp = file->private_data;
  442. if (!devp)
  443. return -ENODEV;
  444. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s: read from ch%d\n",
  445. __func__, devp->id);
  446. id = devp->id;
  447. mutex_lock(&devp->rx_lock);
  448. while (devp->read_avail <= 0) {
  449. mutex_unlock(&devp->rx_lock);
  450. r = wait_event_interruptible(devp->read_wait_queue,
  451. 0 != (read_err = smux_ctl_readable(id)));
  452. if (r < 0) {
  453. pr_err(SMUX_CTL_MODULE_NAME ": %s:"
  454. "wait_event_interruptible "
  455. "ret %i\n", __func__, r);
  456. return r;
  457. }
  458. if (read_err < 0) {
  459. pr_err(SMUX_CTL_MODULE_NAME ": %s:"
  460. " Read block failed for Ch%d, err %d\n",
  461. __func__, devp->id, read_err);
  462. return read_err;
  463. }
  464. mutex_lock(&devp->rx_lock);
  465. }
  466. if (list_empty(&devp->rx_list)) {
  467. mutex_unlock(&devp->rx_lock);
  468. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s: "
  469. "Nothing in ch%d's rx_list\n", __func__,
  470. devp->id);
  471. return -EAGAIN;
  472. }
  473. list_elem = list_first_entry(&devp->rx_list,
  474. struct smux_ctl_list_elem, list);
  475. bytes_to_read = (uint32_t)(list_elem->ctl_pkt.data_size);
  476. if (bytes_to_read > count) {
  477. mutex_unlock(&devp->rx_lock);
  478. pr_err(SMUX_CTL_MODULE_NAME ": %s: "
  479. "Packet size %d > buf size %d\n", __func__,
  480. bytes_to_read, count);
  481. return -ENOMEM;
  482. }
  483. if (copy_to_user(buf, list_elem->ctl_pkt.data, bytes_to_read)) {
  484. mutex_unlock(&devp->rx_lock);
  485. pr_err(SMUX_CTL_MODULE_NAME ": %s: "
  486. "copy_to_user failed for ch%d\n", __func__,
  487. devp->id);
  488. return -EFAULT;
  489. }
  490. devp->read_avail -= bytes_to_read;
  491. list_del(&list_elem->list);
  492. kfree(list_elem->ctl_pkt.data);
  493. kfree(list_elem);
  494. devp->stats.pkts_rx++;
  495. devp->stats.bytes_rx += bytes_to_read;
  496. mutex_unlock(&devp->rx_lock);
  497. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s: "
  498. "Returning %d bytes to ch%d\n", __func__,
  499. bytes_to_read, devp->id);
  500. return bytes_to_read;
  501. }
  502. static int smux_ctl_writeable(int id)
  503. {
  504. int r;
  505. int dev_index;
  506. if (id < 0 || id > smux_ctl_ch_id[SMUX_CTL_NUM_CHANNELS - 1])
  507. return -ENODEV;
  508. dev_index = get_ctl_dev_index(id);
  509. if (dev_index < 0) {
  510. pr_err(SMUX_CTL_MODULE_NAME ": %s: "
  511. "Ch%d is not exported to user-space\n",
  512. __func__, id);
  513. return -ENODEV;
  514. }
  515. mutex_lock(&smux_ctl_devp[dev_index]->dev_lock);
  516. if (signal_pending(current))
  517. r = -ERESTARTSYS;
  518. else if (smux_ctl_devp[dev_index]->abort_wait)
  519. r = -ENETRESET;
  520. else if (smux_ctl_devp[dev_index]->state == SMUX_DISCONNECTED &&
  521. smux_ctl_devp[dev_index]->is_channel_reset != 0)
  522. r = -ENETRESET;
  523. else if (smux_ctl_devp[dev_index]->state != SMUX_CONNECTED)
  524. r = -ENODEV;
  525. else if (smux_ctl_devp[dev_index]->is_high_wm ||
  526. smux_ctl_devp[dev_index]->write_pending)
  527. r = 0;
  528. else
  529. r = SMUX_CTL_MAX_BUF_SIZE;
  530. mutex_unlock(&smux_ctl_devp[dev_index]->dev_lock);
  531. return r;
  532. }
  533. ssize_t smux_ctl_write(struct file *file,
  534. const char __user *buf,
  535. size_t count,
  536. loff_t *ppos)
  537. {
  538. int r = 0, id, write_err;
  539. char *temp_buf;
  540. struct smux_ctl_dev *devp;
  541. if (count <= 0)
  542. return -EINVAL;
  543. devp = file->private_data;
  544. if (!devp)
  545. return -ENODEV;
  546. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s: writing %i bytes on ch%d\n",
  547. __func__, count, devp->id);
  548. id = devp->id;
  549. r = wait_event_interruptible(devp->write_wait_queue,
  550. 0 != (write_err = smux_ctl_writeable(id)));
  551. if (r < 0) {
  552. pr_err(SMUX_CTL_MODULE_NAME
  553. ": %s: wait_event_interruptible "
  554. "ret %i\n", __func__, r);
  555. return r;
  556. }
  557. if (write_err < 0) {
  558. pr_err(SMUX_CTL_MODULE_NAME ": %s:"
  559. "Write block failed for Ch%d, err %d\n",
  560. __func__, devp->id, write_err);
  561. return write_err;
  562. }
  563. temp_buf = kmalloc(count, GFP_KERNEL);
  564. if (!temp_buf) {
  565. pr_err(SMUX_CTL_MODULE_NAME
  566. ": %s: temp_buf alloc failed\n", __func__);
  567. return -ENOMEM;
  568. }
  569. if (copy_from_user(temp_buf, buf, count)) {
  570. pr_err(SMUX_CTL_MODULE_NAME
  571. ": %s: copy_from_user failed\n", __func__);
  572. kfree(temp_buf);
  573. return -EFAULT;
  574. }
  575. mutex_lock(&devp->dev_lock);
  576. devp->write_pending = 1;
  577. mutex_unlock(&devp->dev_lock);
  578. r = msm_smux_write(id, NULL, (void *)temp_buf, count);
  579. if (r < 0) {
  580. pr_err(SMUX_CTL_MODULE_NAME
  581. ": %s: smux_write on Ch%dfailed, err %d\n",
  582. __func__, id, r);
  583. mutex_lock(&devp->dev_lock);
  584. devp->write_pending = 0;
  585. mutex_unlock(&devp->dev_lock);
  586. return r;
  587. }
  588. r = wait_event_interruptible(devp->write_wait_queue,
  589. 0 != (write_err = smux_ctl_writeable(id)));
  590. if (-EIO == r) {
  591. pr_err("%s: %s: wait_event_interruptible ret %i\n",
  592. SMUX_CTL_MODULE_NAME, __func__, r);
  593. return -EIO;
  594. }
  595. if (r < 0) {
  596. pr_err(SMUX_CTL_MODULE_NAME " :%s: wait_event_interruptible "
  597. "ret %i\n", __func__, r);
  598. mutex_lock(&devp->dev_lock);
  599. devp->write_pending = 0;
  600. mutex_unlock(&devp->dev_lock);
  601. return r;
  602. }
  603. mutex_lock(&devp->dev_lock);
  604. devp->write_pending = 0;
  605. devp->stats.pkts_tx++;
  606. devp->stats.bytes_tx += count;
  607. mutex_unlock(&devp->dev_lock);
  608. return count;
  609. }
  610. static long smux_ctl_ioctl(struct file *file, unsigned int cmd,
  611. unsigned long arg)
  612. {
  613. int ret;
  614. struct smux_ctl_dev *devp;
  615. devp = file->private_data;
  616. if (!devp)
  617. return -ENODEV;
  618. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s called on smuxctl%d device\n",
  619. __func__, devp->id);
  620. switch (cmd) {
  621. case TIOCMGET:
  622. ret = msm_smux_tiocm_get(devp->id);
  623. break;
  624. case TIOCMSET:
  625. ret = msm_smux_tiocm_set(devp->id, arg, ~arg);
  626. break;
  627. default:
  628. ret = -EINVAL;
  629. break;
  630. }
  631. return ret;
  632. }
  633. static unsigned int smux_ctl_poll(struct file *file, poll_table *wait)
  634. {
  635. struct smux_ctl_dev *devp;
  636. unsigned int mask = 0;
  637. int readable;
  638. devp = file->private_data;
  639. if (!devp)
  640. return -ENODEV;
  641. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s called on smuxctl%d\n",
  642. __func__, devp->id);
  643. poll_wait(file, &devp->read_wait_queue, wait);
  644. readable = smux_ctl_readable(devp->id);
  645. if (readable > 0) {
  646. mask = POLLIN | POLLRDNORM;
  647. } else if ((readable < 0) && (readable != -ERESTARTSYS)) {
  648. /* error case (non-signal) received */
  649. pr_err(SMUX_CTL_MODULE_NAME ": %s err%d during poll for smuxctl%d\n",
  650. __func__, readable, devp->id);
  651. mask = POLLERR;
  652. }
  653. return mask;
  654. }
  655. static const struct file_operations smux_ctl_fops = {
  656. .owner = THIS_MODULE,
  657. .open = smux_ctl_open,
  658. .release = smux_ctl_release,
  659. .read = smux_ctl_read,
  660. .write = smux_ctl_write,
  661. .unlocked_ioctl = smux_ctl_ioctl,
  662. .poll = smux_ctl_poll,
  663. };
  664. static void smux_ctl_reset_channel(struct smux_ctl_dev *devp)
  665. {
  666. devp->is_high_wm = 0;
  667. devp->write_pending = 0;
  668. devp->is_channel_reset = 0;
  669. devp->state = SMUX_DISCONNECTED;
  670. devp->read_avail = 0;
  671. devp->stats.bytes_tx = 0;
  672. devp->stats.bytes_rx = 0;
  673. devp->stats.pkts_tx = 0;
  674. devp->stats.pkts_rx = 0;
  675. devp->stats.cnt_ssr = 0;
  676. devp->stats.cnt_read_fail = 0;
  677. devp->stats.cnt_write_fail = 0;
  678. devp->stats.cnt_high_wm_hit = 0;
  679. devp->abort_wait = 0;
  680. }
  681. static int smux_ctl_probe(struct platform_device *pdev)
  682. {
  683. int i;
  684. int r;
  685. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s Begins\n", __func__);
  686. if (smux_ctl_inited) {
  687. /* Already loaded once - reinitialize channels */
  688. for (i = 0; i < SMUX_CTL_NUM_CHANNELS; ++i) {
  689. struct smux_ctl_dev *devp = smux_ctl_devp[i];
  690. smux_ctl_reset_channel(devp);
  691. if (atomic_read(&devp->ref_count)) {
  692. r = msm_smux_open(devp->id,
  693. devp,
  694. smux_ctl_notify_cb,
  695. smux_ctl_get_rx_buf_cb);
  696. if (r)
  697. pr_err("%s: unable to reopen ch %d, ret %d\n",
  698. __func__, devp->id, r);
  699. }
  700. }
  701. return 0;
  702. }
  703. /* Create character devices */
  704. for (i = 0; i < SMUX_CTL_NUM_CHANNELS; ++i) {
  705. smux_ctl_devp[i] = kzalloc(sizeof(struct smux_ctl_dev),
  706. GFP_KERNEL);
  707. if (IS_ERR(smux_ctl_devp[i])) {
  708. pr_err(SMUX_CTL_MODULE_NAME
  709. ": %s kmalloc() ENOMEM\n", __func__);
  710. r = -ENOMEM;
  711. goto error0;
  712. }
  713. smux_ctl_devp[i]->id = smux_ctl_ch_id[i];
  714. atomic_set(&smux_ctl_devp[i]->ref_count, 0);
  715. mutex_init(&smux_ctl_devp[i]->dev_lock);
  716. init_waitqueue_head(&smux_ctl_devp[i]->read_wait_queue);
  717. init_waitqueue_head(&smux_ctl_devp[i]->write_wait_queue);
  718. mutex_init(&smux_ctl_devp[i]->rx_lock);
  719. INIT_LIST_HEAD(&smux_ctl_devp[i]->rx_list);
  720. smux_ctl_reset_channel(smux_ctl_devp[i]);
  721. }
  722. r = alloc_chrdev_region(&smux_ctl_number, 0, SMUX_CTL_NUM_CHANNELS,
  723. DEVICE_NAME);
  724. if (IS_ERR_VALUE(r)) {
  725. pr_err(SMUX_CTL_MODULE_NAME ": %s: "
  726. "alloc_chrdev_region() ret %i.\n",
  727. __func__, r);
  728. goto error0;
  729. }
  730. smux_ctl_classp = class_create(THIS_MODULE, DEVICE_NAME);
  731. if (IS_ERR(smux_ctl_classp)) {
  732. pr_err(SMUX_CTL_MODULE_NAME ": %s: "
  733. "class_create() ENOMEM\n", __func__);
  734. r = -ENOMEM;
  735. goto error1;
  736. }
  737. for (i = 0; i < SMUX_CTL_NUM_CHANNELS; ++i) {
  738. cdev_init(&smux_ctl_devp[i]->cdev, &smux_ctl_fops);
  739. smux_ctl_devp[i]->cdev.owner = THIS_MODULE;
  740. r = cdev_add(&smux_ctl_devp[i]->cdev,
  741. (smux_ctl_number + i), 1);
  742. if (IS_ERR_VALUE(r)) {
  743. pr_err(SMUX_CTL_MODULE_NAME ": %s: "
  744. "cdev_add() ret %i\n", __func__, r);
  745. kfree(smux_ctl_devp[i]);
  746. goto error2;
  747. }
  748. smux_ctl_devp[i]->devicep =
  749. device_create(smux_ctl_classp, NULL,
  750. (smux_ctl_number + i), NULL,
  751. DEVICE_NAME "%d", smux_ctl_ch_id[i]);
  752. if (IS_ERR(smux_ctl_devp[i]->devicep)) {
  753. pr_err(SMUX_CTL_MODULE_NAME ": %s: "
  754. "device_create() ENOMEM\n", __func__);
  755. r = -ENOMEM;
  756. cdev_del(&smux_ctl_devp[i]->cdev);
  757. kfree(smux_ctl_devp[i]);
  758. goto error2;
  759. }
  760. if (device_create_file(smux_ctl_devp[i]->devicep,
  761. &dev_attr_open_timeout))
  762. pr_err("%s: unable to create device attr for" \
  763. " smux ctl dev id:%d\n", __func__, i);
  764. }
  765. smux_ctl_inited = 1;
  766. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s: "
  767. "SMUX Control Port Driver Initialized.\n", __func__);
  768. return 0;
  769. error2:
  770. while (--i >= 0) {
  771. cdev_del(&smux_ctl_devp[i]->cdev);
  772. device_destroy(smux_ctl_classp,
  773. MKDEV(MAJOR(smux_ctl_number), i));
  774. }
  775. class_destroy(smux_ctl_classp);
  776. i = SMUX_CTL_NUM_CHANNELS;
  777. error1:
  778. unregister_chrdev_region(MAJOR(smux_ctl_number),
  779. SMUX_CTL_NUM_CHANNELS);
  780. error0:
  781. while (--i >= 0)
  782. kfree(smux_ctl_devp[i]);
  783. return r;
  784. }
  785. static int smux_ctl_remove(struct platform_device *pdev)
  786. {
  787. int i;
  788. int ret;
  789. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s Begins\n", __func__);
  790. for (i = 0; i < SMUX_CTL_NUM_CHANNELS; ++i) {
  791. struct smux_ctl_dev *devp = smux_ctl_devp[i];
  792. mutex_lock(&devp->dev_lock);
  793. devp->abort_wait = 1;
  794. wake_up(&devp->write_wait_queue);
  795. wake_up(&devp->read_wait_queue);
  796. if (atomic_read(&devp->ref_count)) {
  797. ret = msm_smux_close(devp->id);
  798. if (ret)
  799. pr_err("%s: unable to close ch %d, ret %d\n",
  800. __func__, devp->id, ret);
  801. }
  802. mutex_unlock(&devp->dev_lock);
  803. /* Empty RX queue */
  804. mutex_lock(&devp->rx_lock);
  805. while (!list_empty(&devp->rx_list)) {
  806. struct smux_ctl_list_elem *list_elem;
  807. list_elem = list_first_entry(
  808. &devp->rx_list,
  809. struct smux_ctl_list_elem,
  810. list);
  811. list_del(&list_elem->list);
  812. kfree(list_elem->ctl_pkt.data);
  813. kfree(list_elem);
  814. }
  815. devp->read_avail = 0;
  816. mutex_unlock(&devp->rx_lock);
  817. }
  818. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s Ends\n", __func__);
  819. return 0;
  820. }
  821. static struct platform_driver smux_ctl_driver = {
  822. .probe = smux_ctl_probe,
  823. .remove = smux_ctl_remove,
  824. .driver = {
  825. .name = "SMUX_CTL",
  826. .owner = THIS_MODULE,
  827. },
  828. };
  829. static int __init smux_ctl_init(void)
  830. {
  831. SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s Begins\n", __func__);
  832. return platform_driver_register(&smux_ctl_driver);
  833. }
  834. #if defined(CONFIG_DEBUG_FS)
  835. #define DEBUG_BUFMAX 4096
  836. static char debug_buffer[DEBUG_BUFMAX];
  837. static ssize_t debug_read(struct file *file, char __user *buf,
  838. size_t count, loff_t *ppos)
  839. {
  840. int bsize = 0;
  841. int i;
  842. if (!smux_ctl_inited) {
  843. pr_err(SMUX_CTL_MODULE_NAME ": %s: SMUX_CTL not yet inited\n",
  844. __func__);
  845. return -EIO;
  846. }
  847. bsize += scnprintf(debug_buffer + bsize, DEBUG_BUFMAX - bsize,
  848. "SMUX_CTL Channel States:\n");
  849. for (i = 0; i < SMUX_CTL_NUM_CHANNELS; ++i) {
  850. bsize += scnprintf(debug_buffer + bsize, DEBUG_BUFMAX - bsize,
  851. "Ch%02d %s RefCnt=%01d State=%02d "
  852. "SSR=%02d HighWM=%02d ReadAvail=%04d WritePending=%02d\n",
  853. smux_ctl_devp[i]->id,
  854. smux_ctl_devp[i]->name,
  855. atomic_read(&smux_ctl_devp[i]->ref_count),
  856. smux_ctl_devp[i]->state,
  857. smux_ctl_devp[i]->is_channel_reset,
  858. smux_ctl_devp[i]->is_high_wm,
  859. smux_ctl_devp[i]->read_avail,
  860. smux_ctl_devp[i]->write_pending);
  861. }
  862. bsize += scnprintf(debug_buffer + bsize, DEBUG_BUFMAX - bsize,
  863. "\nSMUX_CTL Channel Statistics:\n");
  864. for (i = 0; i < SMUX_CTL_NUM_CHANNELS; ++i) {
  865. bsize += scnprintf(debug_buffer + bsize, DEBUG_BUFMAX - bsize,
  866. "Ch%02d %s BytesTX=%08d "
  867. "BytesRx=%08d PktsTx=%04d PktsRx=%04d"
  868. "CntSSR=%02d CntHighWM=%02d "
  869. "CntReadFail%02d CntWriteFailed=%02d\n",
  870. smux_ctl_devp[i]->id,
  871. smux_ctl_devp[i]->name,
  872. smux_ctl_devp[i]->stats.bytes_tx,
  873. smux_ctl_devp[i]->stats.bytes_rx,
  874. smux_ctl_devp[i]->stats.pkts_tx,
  875. smux_ctl_devp[i]->stats.pkts_rx,
  876. smux_ctl_devp[i]->stats.cnt_ssr,
  877. smux_ctl_devp[i]->stats.cnt_high_wm_hit,
  878. smux_ctl_devp[i]->stats.cnt_read_fail,
  879. smux_ctl_devp[i]->stats.cnt_write_fail);
  880. }
  881. return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
  882. }
  883. static int debug_open(struct inode *inode, struct file *file)
  884. {
  885. file->private_data = inode->i_private;
  886. return 0;
  887. }
  888. static const struct file_operations debug_ops = {
  889. .read = debug_read,
  890. .open = debug_open,
  891. };
  892. static int __init smux_debugfs_init(void)
  893. {
  894. struct dentry *dent;
  895. dent = debugfs_create_dir("smux_ctl", 0);
  896. if (!IS_ERR(dent))
  897. debugfs_create_file("smux_ctl_state", 0444, dent,
  898. NULL, &debug_ops);
  899. return 0;
  900. }
  901. late_initcall(smux_debugfs_init);
  902. #endif
  903. module_init(smux_ctl_init);
  904. MODULE_DESCRIPTION("MSM SMUX Control Port");
  905. MODULE_LICENSE("GPL v2");