xproto.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /*
  2. * Written by Oron Peled <oron@actcom.co.il>
  3. * Copyright (C) 2004-2006, Xorcom
  4. *
  5. * All rights reserved.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. *
  21. */
  22. #include "xpd.h"
  23. #include "xproto.h"
  24. #include "xpp_dahdi.h"
  25. #include "xbus-core.h"
  26. #include "dahdi_debug.h"
  27. #include <linux/module.h>
  28. #include <linux/delay.h>
  29. static const char rcsid[] = "$Id$";
  30. extern int debug;
  31. static const xproto_table_t *xprotocol_tables[XPD_TYPE_NOMODULE];
  32. #if MAX_UNIT*MAX_SUBUNIT > MAX_XPDS
  33. #error MAX_XPDS is too small
  34. #endif
  35. bool valid_xpd_addr(const struct xpd_addr *addr)
  36. {
  37. return ((addr->subunit & ~BITMASK(SUBUNIT_BITS)) == 0) && ((addr->unit & ~BITMASK(UNIT_BITS)) == 0);
  38. }
  39. /*---------------- General Protocol Management ----------------------------*/
  40. const xproto_entry_t *xproto_card_entry(const xproto_table_t *table, byte opcode)
  41. {
  42. const xproto_entry_t *xe;
  43. //DBG(GENERAL, "\n");
  44. xe = &table->entries[opcode];
  45. return (xe->handler != NULL) ? xe : NULL;
  46. }
  47. const xproto_entry_t *xproto_global_entry(byte opcode)
  48. {
  49. const xproto_entry_t *xe;
  50. xe = xproto_card_entry(&PROTO_TABLE(GLOBAL), opcode);
  51. //DBG(GENERAL, "opcode=0x%X xe=%p\n", opcode, xe);
  52. return xe;
  53. }
  54. xproto_handler_t xproto_global_handler(byte opcode)
  55. {
  56. return xproto_card_handler(&PROTO_TABLE(GLOBAL), opcode);
  57. }
  58. static const xproto_table_t *xproto_table(xpd_type_t cardtype)
  59. {
  60. if(cardtype >= XPD_TYPE_NOMODULE)
  61. return NULL;
  62. return xprotocol_tables[cardtype];
  63. }
  64. #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
  65. #define MODULE_REFCOUNT_FORMAT "%s refcount was %d\n"
  66. #else
  67. #define MODULE_REFCOUNT_FORMAT "%s refcount was %lu\n"
  68. #endif
  69. const xproto_table_t *xproto_get(xpd_type_t cardtype)
  70. {
  71. const xproto_table_t *xtable;
  72. if(cardtype >= XPD_TYPE_NOMODULE)
  73. return NULL;
  74. xtable = xprotocol_tables[cardtype];
  75. if(!xtable) { /* Try to load the relevant module */
  76. int ret = request_module(XPD_TYPE_PREFIX "%d", cardtype);
  77. if(ret != 0) {
  78. NOTICE("%s: Failed to load module for type=%d. exit status=%d.\n",
  79. __FUNCTION__, cardtype, ret);
  80. /* Drop through: we may be lucky... */
  81. }
  82. xtable = xprotocol_tables[cardtype];
  83. }
  84. if(xtable) {
  85. BUG_ON(!xtable->owner);
  86. #ifdef CONFIG_MODULE_UNLOAD
  87. DBG(GENERAL, MODULE_REFCOUNT_FORMAT, xtable->name,
  88. module_refcount(xtable->owner));
  89. #endif
  90. if(!try_module_get(xtable->owner)) {
  91. ERR("%s: try_module_get for %s failed.\n", __FUNCTION__, xtable->name);
  92. return NULL;
  93. }
  94. }
  95. return xtable;
  96. }
  97. void xproto_put(const xproto_table_t *xtable)
  98. {
  99. BUG_ON(!xtable);
  100. #ifdef CONFIG_MODULE_UNLOAD
  101. DBG(GENERAL, MODULE_REFCOUNT_FORMAT, xtable->name,
  102. module_refcount(xtable->owner));
  103. BUG_ON(module_refcount(xtable->owner) <= 0);
  104. #endif
  105. module_put(xtable->owner);
  106. }
  107. xproto_handler_t xproto_card_handler(const xproto_table_t *table, byte opcode)
  108. {
  109. const xproto_entry_t *xe;
  110. //DBG(GENERAL, "\n");
  111. xe = xproto_card_entry(table, opcode);
  112. return xe->handler;
  113. }
  114. void notify_bad_xpd(const char *funcname, xbus_t *xbus, const struct xpd_addr addr, const char *msg)
  115. {
  116. XBUS_NOTICE(xbus, "%s: non-existing address (%1d%1d): %s\n",
  117. funcname, addr.unit, addr.subunit, msg);
  118. }
  119. static int packet_process(xbus_t *xbus, xpacket_t *pack)
  120. {
  121. byte op;
  122. const xproto_entry_t *xe;
  123. xproto_handler_t handler;
  124. xproto_table_t *table;
  125. xpd_t *xpd;
  126. int ret = -EPROTO;
  127. BUG_ON(!pack);
  128. if(!valid_xpd_addr(&XPACKET_ADDR(pack))) {
  129. if(printk_ratelimit()) {
  130. XBUS_NOTICE(xbus, "%s: from %d%d: bad address.\n",
  131. __FUNCTION__,
  132. XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
  133. dump_packet("packet_process -- bad address", pack, debug);
  134. }
  135. goto out;
  136. }
  137. op = XPACKET_OP(pack);
  138. xpd = xpd_byaddr(xbus, XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
  139. /* XPD may be NULL (e.g: during bus polling */
  140. xe = xproto_global_entry(op);
  141. /*-------- Validations -----------*/
  142. if(!xe) {
  143. const xproto_table_t *xtable;
  144. if(!xpd) {
  145. if(printk_ratelimit()) {
  146. XBUS_NOTICE(xbus, "%s: from %d%d opcode=0x%02X: no such global command.\n",
  147. __FUNCTION__,
  148. XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack), op);
  149. dump_packet("packet_process -- no such global command", pack, 1);
  150. }
  151. goto out;
  152. }
  153. xtable = xproto_table(xpd->type);
  154. if(!xtable) {
  155. if(printk_ratelimit())
  156. XPD_ERR(xpd, "%s: no protocol table (type=%d)\n",
  157. __FUNCTION__,
  158. xpd->type);
  159. goto out;
  160. }
  161. xe = xproto_card_entry(xtable, op);
  162. if(!xe) {
  163. if(printk_ratelimit()) {
  164. XPD_NOTICE(xpd, "%s: bad command (type=%d,opcode=0x%x)\n",
  165. __FUNCTION__,
  166. xpd->type, op);
  167. dump_packet("packet_process -- bad command", pack, 1);
  168. }
  169. goto out;
  170. }
  171. }
  172. table = xe->table;
  173. BUG_ON(!table);
  174. if(!table->packet_is_valid(pack)) {
  175. if(printk_ratelimit()) {
  176. ERR("xpp: %s: wrong size %d for opcode=0x%02X\n",
  177. __FUNCTION__, XPACKET_LEN(pack), op);
  178. dump_packet("packet_process -- wrong size", pack, debug);
  179. }
  180. goto out;
  181. }
  182. ret = 0; /* All well */
  183. handler = xe->handler;
  184. BUG_ON(!handler);
  185. XBUS_COUNTER(xbus, RX_BYTES) += XPACKET_LEN(pack);
  186. handler(xbus, xpd, xe, pack);
  187. out:
  188. return ret;
  189. }
  190. static int xframe_receive_cmd(xbus_t *xbus, xframe_t *xframe)
  191. {
  192. byte *xframe_end;
  193. xpacket_t *pack;
  194. byte *p;
  195. int len;
  196. int ret;
  197. if(debug & DBG_COMMANDS)
  198. dump_xframe("RX-CMD", xbus, xframe, DBG_ANY);
  199. p = xframe->packets;
  200. xframe_end = p + XFRAME_LEN(xframe);
  201. do {
  202. pack = (xpacket_t *)p;
  203. len = XPACKET_LEN(pack);
  204. /* Sanity checks */
  205. if(unlikely(XPACKET_OP(pack) == XPROTO_NAME(GLOBAL,PCM_READ))) {
  206. static int rate_limit;
  207. if((rate_limit++ % 1003) == 0) {
  208. XBUS_DBG(GENERAL, xbus, "A PCM packet within a Non-PCM xframe\n");
  209. dump_xframe("In Non-PCM xframe", xbus, xframe, debug);
  210. }
  211. ret = -EPROTO;
  212. goto out;
  213. }
  214. p += len;
  215. if(p > xframe_end || len < RPACKET_HEADERSIZE) {
  216. static int rate_limit;
  217. if((rate_limit++ % 1003) == 0) {
  218. XBUS_NOTICE(xbus, "Invalid packet length %d\n", len);
  219. dump_xframe("BAD LENGTH", xbus, xframe, debug);
  220. }
  221. ret = -EPROTO;
  222. goto out;
  223. }
  224. ret = packet_process(xbus, pack);
  225. if(unlikely(ret < 0))
  226. break;
  227. } while(p < xframe_end);
  228. out:
  229. FREE_RECV_XFRAME(xbus, xframe);
  230. return ret;
  231. }
  232. int xframe_receive(xbus_t *xbus, xframe_t *xframe)
  233. {
  234. int ret = 0;
  235. struct timeval now;
  236. struct timeval tv_received;
  237. int usec;
  238. if(XFRAME_LEN(xframe) < RPACKET_HEADERSIZE) {
  239. static int rate_limit;
  240. if((rate_limit++ % 1003) == 0) {
  241. XBUS_NOTICE(xbus, "short xframe\n");
  242. dump_xframe("short xframe", xbus, xframe, debug);
  243. }
  244. FREE_RECV_XFRAME(xbus, xframe);
  245. return -EPROTO;
  246. }
  247. if(!XBUS_FLAGS(xbus, CONNECTED)) {
  248. XBUS_DBG(GENERAL, xbus, "Dropped xframe. Is shutting down.\n");
  249. return -ENODEV;
  250. }
  251. tv_received = xframe->tv_received;
  252. /*
  253. * We want to check that xframes do not mix PCM and other commands
  254. */
  255. if(XPACKET_IS_PCM((xpacket_t *)xframe->packets)) {
  256. if(!XBUS_IS(xbus, READY))
  257. FREE_RECV_XFRAME(xbus, xframe);
  258. else
  259. xframe_receive_pcm(xbus, xframe);
  260. } else {
  261. XBUS_COUNTER(xbus, RX_CMD)++;
  262. ret = xframe_receive_cmd(xbus, xframe);
  263. }
  264. /* Calculate total processing time */
  265. do_gettimeofday(&now);
  266. usec = (now.tv_sec - tv_received.tv_sec) * 1000000 +
  267. now.tv_usec - tv_received.tv_usec;
  268. if(usec > xbus->max_rx_process)
  269. xbus->max_rx_process = usec;
  270. return ret;
  271. }
  272. #define VERBOSE_DEBUG 1
  273. #define ERR_REPORT_LIMIT 20
  274. void dump_packet(const char *msg, const xpacket_t *packet, bool debug)
  275. {
  276. byte op = XPACKET_OP(packet);
  277. byte *addr = (byte *)&XPACKET_ADDR(packet);
  278. if(!debug)
  279. return;
  280. printk(KERN_DEBUG "%s: XPD=%1X-%1X%c (0x%X) OP=0x%02X LEN=%d",
  281. msg,
  282. XPACKET_ADDR_UNIT(packet),
  283. XPACKET_ADDR_SUBUNIT(packet),
  284. (XPACKET_ADDR_SYNC(packet))?'+':' ',
  285. *addr,
  286. op,
  287. XPACKET_LEN(packet));
  288. #if VERBOSE_DEBUG
  289. {
  290. int i;
  291. byte *p = (byte *)packet;
  292. printk(" BYTES: ");
  293. for(i = 0; i < XPACKET_LEN(packet); i++) {
  294. static int limiter = 0;
  295. if(i >= sizeof(xpacket_t)) {
  296. if(limiter < ERR_REPORT_LIMIT) {
  297. ERR("%s: length overflow i=%d > sizeof(xpacket_t)=%lu\n",
  298. __FUNCTION__, i+1, (long)sizeof(xpacket_t));
  299. } else if(limiter == ERR_REPORT_LIMIT) {
  300. ERR("%s: error packet #%d... squelsh reports.\n",
  301. __FUNCTION__, limiter);
  302. }
  303. limiter++;
  304. break;
  305. }
  306. if (debug)
  307. printk("%02X ", p[i]);
  308. }
  309. }
  310. #endif
  311. printk("\n");
  312. }
  313. void dump_reg_cmd(const char msg[], bool writing, xbus_t *xbus,
  314. byte unit, xportno_t port, const reg_cmd_t *regcmd)
  315. {
  316. char action;
  317. char modifier;
  318. char port_buf[MAX_PROC_WRITE];
  319. char reg_buf[MAX_PROC_WRITE];
  320. char data_buf[MAX_PROC_WRITE];
  321. if(regcmd->bytes > sizeof(*regcmd) - 1) { /* The size byte is not included */
  322. PORT_NOTICE(xbus, unit, port, "%s: %s: Too long: regcmd->bytes = %d\n",
  323. __FUNCTION__, msg, regcmd->bytes);
  324. return;
  325. }
  326. if(regcmd->is_multibyte) {
  327. char buf[MAX_PROC_WRITE + 1];
  328. int i;
  329. int n = 0;
  330. size_t len = regcmd->bytes;
  331. const byte *p = REG_XDATA(regcmd);
  332. buf[0] = '\0';
  333. for(i = 0; i < len && n < MAX_PROC_WRITE; i++)
  334. n += snprintf(&buf[n], MAX_PROC_WRITE - n, "%02X ", p[i]);
  335. PORT_DBG(REGS, xbus, unit, port,
  336. "UNIT-%d PORT-%d: Multibyte(eoframe=%d) %s[0..%zd]: %s%s\n",
  337. unit, port, regcmd->eoframe,
  338. msg, len-1, buf, (n >= MAX_PROC_WRITE)?"...":"");
  339. return;
  340. }
  341. if(regcmd->bytes != sizeof(*regcmd) - 1) { /* The size byte is not included */
  342. PORT_NOTICE(xbus, unit, port, "%s: %s: Wrong size: regcmd->bytes = %d\n",
  343. __FUNCTION__, msg, regcmd->bytes);
  344. return;
  345. }
  346. snprintf(port_buf, MAX_PROC_WRITE, "%d%s",
  347. regcmd->portnum,
  348. (REG_FIELD(regcmd, all_ports_broadcast)) ? "*" : "");
  349. action = (REG_FIELD(regcmd, read_request)) ? 'R' : 'W';
  350. modifier = 'D';
  351. if(REG_FIELD(regcmd, do_subreg)) {
  352. snprintf(reg_buf, MAX_PROC_WRITE, "%02X %02X",
  353. REG_FIELD(regcmd, regnum),
  354. REG_FIELD(regcmd, subreg));
  355. modifier = 'S';
  356. } else {
  357. snprintf(reg_buf, MAX_PROC_WRITE, "%02X",
  358. REG_FIELD(regcmd, regnum));
  359. }
  360. if(REG_FIELD(regcmd, read_request)) {
  361. data_buf[0] = '\0';
  362. } else if(REG_FIELD(regcmd, do_datah)) {
  363. snprintf(data_buf, MAX_PROC_WRITE, "%02X %02X",
  364. REG_FIELD(regcmd, data_low),
  365. REG_FIELD(regcmd, data_high));
  366. modifier = 'I';
  367. } else {
  368. snprintf(data_buf, MAX_PROC_WRITE, "%02X",
  369. REG_FIELD(regcmd, data_low));
  370. }
  371. PORT_DBG(REGS, xbus, unit, port, "%s: %s %c%c %s %s\n",
  372. msg, port_buf, action, modifier,
  373. reg_buf, data_buf);
  374. }
  375. const char *xproto_name(xpd_type_t xpd_type)
  376. {
  377. const xproto_table_t *proto_table;
  378. BUG_ON(xpd_type >= XPD_TYPE_NOMODULE);
  379. proto_table = xprotocol_tables[xpd_type];
  380. if(!proto_table)
  381. return NULL;
  382. return proto_table->name;
  383. }
  384. #define CHECK_XOP(f) \
  385. if(!(xops)->f) { \
  386. ERR("%s: missing xmethod %s [%s (%d)]\n", __FUNCTION__, #f, name, type); \
  387. return -EINVAL; \
  388. }
  389. int xproto_register(const xproto_table_t *proto_table)
  390. {
  391. int type;
  392. const char *name;
  393. const xops_t *xops;
  394. BUG_ON(!proto_table);
  395. type = proto_table->type;
  396. name = proto_table->name;
  397. if(type >= XPD_TYPE_NOMODULE) {
  398. NOTICE("%s: Bad xproto type %d\n", __FUNCTION__, type);
  399. return -EINVAL;
  400. }
  401. DBG(GENERAL, "%s (%d)\n", name, type);
  402. if(xprotocol_tables[type])
  403. NOTICE("%s: overriding registration of %s (%d)\n", __FUNCTION__, name, type);
  404. xops = &proto_table->xops;
  405. CHECK_XOP(card_new);
  406. CHECK_XOP(card_init);
  407. CHECK_XOP(card_remove);
  408. CHECK_XOP(card_tick);
  409. CHECK_XOP(card_pcm_recompute);
  410. CHECK_XOP(card_pcm_fromspan);
  411. CHECK_XOP(card_pcm_tospan);
  412. CHECK_XOP(card_dahdi_preregistration);
  413. CHECK_XOP(card_dahdi_postregistration);
  414. // CHECK_XOP(card_ioctl); // optional method -- call after testing
  415. CHECK_XOP(card_register_reply);
  416. CHECK_XOP(XPD_STATE);
  417. xprotocol_tables[type] = proto_table;
  418. return 0;
  419. }
  420. void xproto_unregister(const xproto_table_t *proto_table)
  421. {
  422. int type;
  423. const char *name;
  424. BUG_ON(!proto_table);
  425. type = proto_table->type;
  426. name = proto_table->name;
  427. DBG(GENERAL, "%s (%d)\n", name, type);
  428. if(type >= XPD_TYPE_NOMODULE) {
  429. NOTICE("%s: Bad xproto type %s (%d)\n", __FUNCTION__, name, type);
  430. return;
  431. }
  432. if(!xprotocol_tables[type])
  433. NOTICE("%s: xproto type %s (%d) is already unregistered\n", __FUNCTION__, name, type);
  434. xprotocol_tables[type] = NULL;
  435. }
  436. EXPORT_SYMBOL(dump_packet);
  437. EXPORT_SYMBOL(dump_reg_cmd);
  438. EXPORT_SYMBOL(xframe_receive);
  439. EXPORT_SYMBOL(notify_bad_xpd);
  440. EXPORT_SYMBOL(valid_xpd_addr);
  441. EXPORT_SYMBOL(xproto_global_entry);
  442. EXPORT_SYMBOL(xproto_card_entry);
  443. EXPORT_SYMBOL(xproto_name);
  444. EXPORT_SYMBOL(xproto_register);
  445. EXPORT_SYMBOL(xproto_unregister);