smscoreapi.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329
  1. /*
  2. * Siano core API module
  3. *
  4. * This file contains implementation for the interface to sms core component
  5. *
  6. * author: Anatoly Greenblat
  7. *
  8. * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation;
  13. *
  14. * Software distributed under the License is distributed on an "AS IS"
  15. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  16. *
  17. * See the GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. */
  23. #include <linux/kernel.h>
  24. #include <linux/init.h>
  25. #include <linux/module.h>
  26. #include <linux/moduleparam.h>
  27. #include <linux/dma-mapping.h>
  28. #include <linux/delay.h>
  29. #include <linux/io.h>
  30. #include <linux/firmware.h>
  31. #include "smscoreapi.h"
  32. #include "sms-cards.h"
  33. int sms_debug;
  34. module_param_named(debug, sms_debug, int, 0644);
  35. MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
  36. struct smscore_device_notifyee_t {
  37. struct list_head entry;
  38. hotplug_t hotplug;
  39. };
  40. struct smscore_idlist_t {
  41. struct list_head entry;
  42. int id;
  43. int data_type;
  44. };
  45. struct smscore_client_t {
  46. struct list_head entry;
  47. struct smscore_device_t *coredev;
  48. void *context;
  49. struct list_head idlist;
  50. onresponse_t onresponse_handler;
  51. onremove_t onremove_handler;
  52. };
  53. struct smscore_device_t {
  54. struct list_head entry;
  55. struct list_head clients;
  56. struct list_head subclients;
  57. spinlock_t clientslock;
  58. struct list_head buffers;
  59. spinlock_t bufferslock;
  60. int num_buffers;
  61. void *common_buffer;
  62. int common_buffer_size;
  63. dma_addr_t common_buffer_phys;
  64. void *context;
  65. struct device *device;
  66. char devpath[32];
  67. unsigned long device_flags;
  68. setmode_t setmode_handler;
  69. detectmode_t detectmode_handler;
  70. sendrequest_t sendrequest_handler;
  71. preload_t preload_handler;
  72. postload_t postload_handler;
  73. int mode, modes_supported;
  74. struct completion version_ex_done, data_download_done, trigger_done;
  75. struct completion init_device_done, reload_start_done, resume_done;
  76. int board_id;
  77. int led_state;
  78. };
  79. void smscore_set_board_id(struct smscore_device_t *core, int id)
  80. {
  81. core->board_id = id;
  82. }
  83. int smscore_led_state(struct smscore_device_t *core, int led)
  84. {
  85. if (led >= 0)
  86. core->led_state = led;
  87. return core->led_state;
  88. }
  89. int smscore_get_board_id(struct smscore_device_t *core)
  90. {
  91. return core->board_id;
  92. }
  93. struct smscore_registry_entry_t {
  94. struct list_head entry;
  95. char devpath[32];
  96. int mode;
  97. enum sms_device_type_st type;
  98. };
  99. static struct list_head g_smscore_notifyees;
  100. static struct list_head g_smscore_devices;
  101. static struct mutex g_smscore_deviceslock;
  102. static struct list_head g_smscore_registry;
  103. static struct mutex g_smscore_registrylock;
  104. static int default_mode = 4;
  105. module_param(default_mode, int, 0644);
  106. MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
  107. static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
  108. {
  109. struct smscore_registry_entry_t *entry;
  110. struct list_head *next;
  111. kmutex_lock(&g_smscore_registrylock);
  112. for (next = g_smscore_registry.next;
  113. next != &g_smscore_registry;
  114. next = next->next) {
  115. entry = (struct smscore_registry_entry_t *) next;
  116. if (!strcmp(entry->devpath, devpath)) {
  117. kmutex_unlock(&g_smscore_registrylock);
  118. return entry;
  119. }
  120. }
  121. entry = (struct smscore_registry_entry_t *)
  122. kmalloc(sizeof(struct smscore_registry_entry_t),
  123. GFP_KERNEL);
  124. if (entry) {
  125. entry->mode = default_mode;
  126. strcpy(entry->devpath, devpath);
  127. list_add(&entry->entry, &g_smscore_registry);
  128. } else
  129. sms_err("failed to create smscore_registry.");
  130. kmutex_unlock(&g_smscore_registrylock);
  131. return entry;
  132. }
  133. int smscore_registry_getmode(char *devpath)
  134. {
  135. struct smscore_registry_entry_t *entry;
  136. entry = smscore_find_registry(devpath);
  137. if (entry)
  138. return entry->mode;
  139. else
  140. sms_err("No registry found.");
  141. return default_mode;
  142. }
  143. static enum sms_device_type_st smscore_registry_gettype(char *devpath)
  144. {
  145. struct smscore_registry_entry_t *entry;
  146. entry = smscore_find_registry(devpath);
  147. if (entry)
  148. return entry->type;
  149. else
  150. sms_err("No registry found.");
  151. return -1;
  152. }
  153. void smscore_registry_setmode(char *devpath, int mode)
  154. {
  155. struct smscore_registry_entry_t *entry;
  156. entry = smscore_find_registry(devpath);
  157. if (entry)
  158. entry->mode = mode;
  159. else
  160. sms_err("No registry found.");
  161. }
  162. static void smscore_registry_settype(char *devpath,
  163. enum sms_device_type_st type)
  164. {
  165. struct smscore_registry_entry_t *entry;
  166. entry = smscore_find_registry(devpath);
  167. if (entry)
  168. entry->type = type;
  169. else
  170. sms_err("No registry found.");
  171. }
  172. static void list_add_locked(struct list_head *new, struct list_head *head,
  173. spinlock_t *lock)
  174. {
  175. unsigned long flags;
  176. spin_lock_irqsave(lock, flags);
  177. list_add(new, head);
  178. spin_unlock_irqrestore(lock, flags);
  179. }
  180. /**
  181. * register a client callback that called when device plugged in/unplugged
  182. * NOTE: if devices exist callback is called immediately for each device
  183. *
  184. * @param hotplug callback
  185. *
  186. * @return 0 on success, <0 on error.
  187. */
  188. int smscore_register_hotplug(hotplug_t hotplug)
  189. {
  190. struct smscore_device_notifyee_t *notifyee;
  191. struct list_head *next, *first;
  192. int rc = 0;
  193. kmutex_lock(&g_smscore_deviceslock);
  194. notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
  195. GFP_KERNEL);
  196. if (notifyee) {
  197. /* now notify callback about existing devices */
  198. first = &g_smscore_devices;
  199. for (next = first->next;
  200. next != first && !rc;
  201. next = next->next) {
  202. struct smscore_device_t *coredev =
  203. (struct smscore_device_t *) next;
  204. rc = hotplug(coredev, coredev->device, 1);
  205. }
  206. if (rc >= 0) {
  207. notifyee->hotplug = hotplug;
  208. list_add(&notifyee->entry, &g_smscore_notifyees);
  209. } else
  210. kfree(notifyee);
  211. } else
  212. rc = -ENOMEM;
  213. kmutex_unlock(&g_smscore_deviceslock);
  214. return rc;
  215. }
  216. /**
  217. * unregister a client callback that called when device plugged in/unplugged
  218. *
  219. * @param hotplug callback
  220. *
  221. */
  222. void smscore_unregister_hotplug(hotplug_t hotplug)
  223. {
  224. struct list_head *next, *first;
  225. kmutex_lock(&g_smscore_deviceslock);
  226. first = &g_smscore_notifyees;
  227. for (next = first->next; next != first;) {
  228. struct smscore_device_notifyee_t *notifyee =
  229. (struct smscore_device_notifyee_t *) next;
  230. next = next->next;
  231. if (notifyee->hotplug == hotplug) {
  232. list_del(&notifyee->entry);
  233. kfree(notifyee);
  234. }
  235. }
  236. kmutex_unlock(&g_smscore_deviceslock);
  237. }
  238. static void smscore_notify_clients(struct smscore_device_t *coredev)
  239. {
  240. struct smscore_client_t *client;
  241. /* the client must call smscore_unregister_client from remove handler */
  242. while (!list_empty(&coredev->clients)) {
  243. client = (struct smscore_client_t *) coredev->clients.next;
  244. client->onremove_handler(client->context);
  245. }
  246. }
  247. static int smscore_notify_callbacks(struct smscore_device_t *coredev,
  248. struct device *device, int arrival)
  249. {
  250. struct list_head *next, *first;
  251. int rc = 0;
  252. /* note: must be called under g_deviceslock */
  253. first = &g_smscore_notifyees;
  254. for (next = first->next; next != first; next = next->next) {
  255. rc = ((struct smscore_device_notifyee_t *) next)->
  256. hotplug(coredev, device, arrival);
  257. if (rc < 0)
  258. break;
  259. }
  260. return rc;
  261. }
  262. static struct
  263. smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
  264. dma_addr_t common_buffer_phys)
  265. {
  266. struct smscore_buffer_t *cb =
  267. kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
  268. if (!cb) {
  269. sms_info("kmalloc(...) failed");
  270. return NULL;
  271. }
  272. cb->p = buffer;
  273. cb->offset_in_common = buffer - (u8 *) common_buffer;
  274. cb->phys = common_buffer_phys + cb->offset_in_common;
  275. return cb;
  276. }
  277. /**
  278. * creates coredev object for a device, prepares buffers,
  279. * creates buffer mappings, notifies registered hotplugs about new device.
  280. *
  281. * @param params device pointer to struct with device specific parameters
  282. * and handlers
  283. * @param coredev pointer to a value that receives created coredev object
  284. *
  285. * @return 0 on success, <0 on error.
  286. */
  287. int smscore_register_device(struct smsdevice_params_t *params,
  288. struct smscore_device_t **coredev)
  289. {
  290. struct smscore_device_t *dev;
  291. u8 *buffer;
  292. dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
  293. if (!dev) {
  294. sms_info("kzalloc(...) failed");
  295. return -ENOMEM;
  296. }
  297. /* init list entry so it could be safe in smscore_unregister_device */
  298. INIT_LIST_HEAD(&dev->entry);
  299. /* init queues */
  300. INIT_LIST_HEAD(&dev->clients);
  301. INIT_LIST_HEAD(&dev->buffers);
  302. /* init locks */
  303. spin_lock_init(&dev->clientslock);
  304. spin_lock_init(&dev->bufferslock);
  305. /* init completion events */
  306. init_completion(&dev->version_ex_done);
  307. init_completion(&dev->data_download_done);
  308. init_completion(&dev->trigger_done);
  309. init_completion(&dev->init_device_done);
  310. init_completion(&dev->reload_start_done);
  311. init_completion(&dev->resume_done);
  312. /* alloc common buffer */
  313. dev->common_buffer_size = params->buffer_size * params->num_buffers;
  314. dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
  315. &dev->common_buffer_phys,
  316. GFP_KERNEL | GFP_DMA);
  317. if (!dev->common_buffer) {
  318. smscore_unregister_device(dev);
  319. return -ENOMEM;
  320. }
  321. /* prepare dma buffers */
  322. for (buffer = dev->common_buffer;
  323. dev->num_buffers < params->num_buffers;
  324. dev->num_buffers++, buffer += params->buffer_size) {
  325. struct smscore_buffer_t *cb =
  326. smscore_createbuffer(buffer, dev->common_buffer,
  327. dev->common_buffer_phys);
  328. if (!cb) {
  329. smscore_unregister_device(dev);
  330. return -ENOMEM;
  331. }
  332. smscore_putbuffer(dev, cb);
  333. }
  334. sms_info("allocated %d buffers", dev->num_buffers);
  335. dev->mode = DEVICE_MODE_NONE;
  336. dev->context = params->context;
  337. dev->device = params->device;
  338. dev->setmode_handler = params->setmode_handler;
  339. dev->detectmode_handler = params->detectmode_handler;
  340. dev->sendrequest_handler = params->sendrequest_handler;
  341. dev->preload_handler = params->preload_handler;
  342. dev->postload_handler = params->postload_handler;
  343. dev->device_flags = params->flags;
  344. strcpy(dev->devpath, params->devpath);
  345. smscore_registry_settype(dev->devpath, params->device_type);
  346. /* add device to devices list */
  347. kmutex_lock(&g_smscore_deviceslock);
  348. list_add(&dev->entry, &g_smscore_devices);
  349. kmutex_unlock(&g_smscore_deviceslock);
  350. *coredev = dev;
  351. sms_info("device %p created", dev);
  352. return 0;
  353. }
  354. /**
  355. * sets initial device mode and notifies client hotplugs that device is ready
  356. *
  357. * @param coredev pointer to a coredev object returned by
  358. * smscore_register_device
  359. *
  360. * @return 0 on success, <0 on error.
  361. */
  362. int smscore_start_device(struct smscore_device_t *coredev)
  363. {
  364. int rc = smscore_set_device_mode(
  365. coredev, smscore_registry_getmode(coredev->devpath));
  366. if (rc < 0) {
  367. sms_info("set device mode faile , rc %d", rc);
  368. return rc;
  369. }
  370. kmutex_lock(&g_smscore_deviceslock);
  371. rc = smscore_notify_callbacks(coredev, coredev->device, 1);
  372. sms_info("device %p started, rc %d", coredev, rc);
  373. kmutex_unlock(&g_smscore_deviceslock);
  374. return rc;
  375. }
  376. static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
  377. void *buffer, size_t size,
  378. struct completion *completion)
  379. {
  380. int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
  381. if (rc < 0) {
  382. sms_info("sendrequest returned error %d", rc);
  383. return rc;
  384. }
  385. return wait_for_completion_timeout(completion,
  386. msecs_to_jiffies(10000)) ?
  387. 0 : -ETIME;
  388. }
  389. static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
  390. void *buffer, size_t size)
  391. {
  392. struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
  393. struct SmsMsgHdr_ST *msg;
  394. u32 mem_address = firmware->StartAddress;
  395. u8 *payload = firmware->Payload;
  396. int rc = 0;
  397. sms_info("loading FW to addr 0x%x size %d",
  398. mem_address, firmware->Length);
  399. if (coredev->preload_handler) {
  400. rc = coredev->preload_handler(coredev->context);
  401. if (rc < 0)
  402. return rc;
  403. }
  404. /* PAGE_SIZE buffer shall be enough and dma aligned */
  405. msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
  406. if (!msg)
  407. return -ENOMEM;
  408. if (coredev->mode != DEVICE_MODE_NONE) {
  409. sms_debug("sending reload command.");
  410. SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
  411. sizeof(struct SmsMsgHdr_ST));
  412. rc = smscore_sendrequest_and_wait(coredev, msg,
  413. msg->msgLength,
  414. &coredev->reload_start_done);
  415. mem_address = *(u32 *) &payload[20];
  416. }
  417. while (size && rc >= 0) {
  418. struct SmsDataDownload_ST *DataMsg =
  419. (struct SmsDataDownload_ST *) msg;
  420. int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
  421. SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
  422. (u16)(sizeof(struct SmsMsgHdr_ST) +
  423. sizeof(u32) + payload_size));
  424. DataMsg->MemAddr = mem_address;
  425. memcpy(DataMsg->Payload, payload, payload_size);
  426. if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
  427. (coredev->mode == DEVICE_MODE_NONE))
  428. rc = coredev->sendrequest_handler(
  429. coredev->context, DataMsg,
  430. DataMsg->xMsgHeader.msgLength);
  431. else
  432. rc = smscore_sendrequest_and_wait(
  433. coredev, DataMsg,
  434. DataMsg->xMsgHeader.msgLength,
  435. &coredev->data_download_done);
  436. payload += payload_size;
  437. size -= payload_size;
  438. mem_address += payload_size;
  439. }
  440. if (rc >= 0) {
  441. if (coredev->mode == DEVICE_MODE_NONE) {
  442. struct SmsMsgData_ST *TriggerMsg =
  443. (struct SmsMsgData_ST *) msg;
  444. SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
  445. sizeof(struct SmsMsgHdr_ST) +
  446. sizeof(u32) * 5);
  447. TriggerMsg->msgData[0] = firmware->StartAddress;
  448. /* Entry point */
  449. TriggerMsg->msgData[1] = 5; /* Priority */
  450. TriggerMsg->msgData[2] = 0x200; /* Stack size */
  451. TriggerMsg->msgData[3] = 0; /* Parameter */
  452. TriggerMsg->msgData[4] = 4; /* Task ID */
  453. if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
  454. rc = coredev->sendrequest_handler(
  455. coredev->context, TriggerMsg,
  456. TriggerMsg->xMsgHeader.msgLength);
  457. msleep(100);
  458. } else
  459. rc = smscore_sendrequest_and_wait(
  460. coredev, TriggerMsg,
  461. TriggerMsg->xMsgHeader.msgLength,
  462. &coredev->trigger_done);
  463. } else {
  464. SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
  465. sizeof(struct SmsMsgHdr_ST));
  466. rc = coredev->sendrequest_handler(coredev->context,
  467. msg, msg->msgLength);
  468. }
  469. msleep(500);
  470. }
  471. sms_debug("rc=%d, postload=%p ", rc,
  472. coredev->postload_handler);
  473. kfree(msg);
  474. return ((rc >= 0) && coredev->postload_handler) ?
  475. coredev->postload_handler(coredev->context) :
  476. rc;
  477. }
  478. /**
  479. * loads specified firmware into a buffer and calls device loadfirmware_handler
  480. *
  481. * @param coredev pointer to a coredev object returned by
  482. * smscore_register_device
  483. * @param filename null-terminated string specifies firmware file name
  484. * @param loadfirmware_handler device handler that loads firmware
  485. *
  486. * @return 0 on success, <0 on error.
  487. */
  488. static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
  489. char *filename,
  490. loadfirmware_t loadfirmware_handler)
  491. {
  492. int rc = -ENOENT;
  493. const struct firmware *fw;
  494. u8 *fw_buffer;
  495. if (loadfirmware_handler == NULL && !(coredev->device_flags &
  496. SMS_DEVICE_FAMILY2))
  497. return -EINVAL;
  498. rc = request_firmware(&fw, filename, coredev->device);
  499. if (rc < 0) {
  500. sms_info("failed to open \"%s\"", filename);
  501. return rc;
  502. }
  503. sms_info("read FW %s, size=%zd", filename, fw->size);
  504. fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
  505. GFP_KERNEL | GFP_DMA);
  506. if (fw_buffer) {
  507. memcpy(fw_buffer, fw->data, fw->size);
  508. rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
  509. smscore_load_firmware_family2(coredev,
  510. fw_buffer,
  511. fw->size) :
  512. loadfirmware_handler(coredev->context,
  513. fw_buffer, fw->size);
  514. kfree(fw_buffer);
  515. } else {
  516. sms_info("failed to allocate firmware buffer");
  517. rc = -ENOMEM;
  518. }
  519. release_firmware(fw);
  520. return rc;
  521. }
  522. /**
  523. * notifies all clients registered with the device, notifies hotplugs,
  524. * frees all buffers and coredev object
  525. *
  526. * @param coredev pointer to a coredev object returned by
  527. * smscore_register_device
  528. *
  529. * @return 0 on success, <0 on error.
  530. */
  531. void smscore_unregister_device(struct smscore_device_t *coredev)
  532. {
  533. struct smscore_buffer_t *cb;
  534. int num_buffers = 0;
  535. int retry = 0;
  536. kmutex_lock(&g_smscore_deviceslock);
  537. smscore_notify_clients(coredev);
  538. smscore_notify_callbacks(coredev, NULL, 0);
  539. /* at this point all buffers should be back
  540. * onresponse must no longer be called */
  541. while (1) {
  542. while ((cb = smscore_getbuffer(coredev))) {
  543. kfree(cb);
  544. num_buffers++;
  545. }
  546. if (num_buffers == coredev->num_buffers)
  547. break;
  548. if (++retry > 10) {
  549. sms_info("exiting although "
  550. "not all buffers released.");
  551. break;
  552. }
  553. sms_info("waiting for %d buffer(s)",
  554. coredev->num_buffers - num_buffers);
  555. msleep(100);
  556. }
  557. sms_info("freed %d buffers", num_buffers);
  558. if (coredev->common_buffer)
  559. dma_free_coherent(NULL, coredev->common_buffer_size,
  560. coredev->common_buffer,
  561. coredev->common_buffer_phys);
  562. list_del(&coredev->entry);
  563. kfree(coredev);
  564. kmutex_unlock(&g_smscore_deviceslock);
  565. sms_info("device %p destroyed", coredev);
  566. }
  567. static int smscore_detect_mode(struct smscore_device_t *coredev)
  568. {
  569. void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
  570. GFP_KERNEL | GFP_DMA);
  571. struct SmsMsgHdr_ST *msg =
  572. (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
  573. int rc;
  574. if (!buffer)
  575. return -ENOMEM;
  576. SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
  577. sizeof(struct SmsMsgHdr_ST));
  578. rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
  579. &coredev->version_ex_done);
  580. if (rc == -ETIME) {
  581. sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
  582. if (wait_for_completion_timeout(&coredev->resume_done,
  583. msecs_to_jiffies(5000))) {
  584. rc = smscore_sendrequest_and_wait(
  585. coredev, msg, msg->msgLength,
  586. &coredev->version_ex_done);
  587. if (rc < 0)
  588. sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
  589. "second try, rc %d", rc);
  590. } else
  591. rc = -ETIME;
  592. }
  593. kfree(buffer);
  594. return rc;
  595. }
  596. static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
  597. /*Stellar NOVA A0 Nova B0 VEGA*/
  598. /*DVBT*/
  599. {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
  600. /*DVBH*/
  601. {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
  602. /*TDMB*/
  603. {"none", "tdmb_nova_12mhz.inp", "none", "none"},
  604. /*DABIP*/
  605. {"none", "none", "none", "none"},
  606. /*BDA*/
  607. {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
  608. /*ISDBT*/
  609. {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"},
  610. /*ISDBTBDA*/
  611. {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
  612. /*CMMB*/
  613. {"none", "none", "none", "cmmb_vega_12mhz.inp"}
  614. };
  615. static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
  616. int mode, enum sms_device_type_st type)
  617. {
  618. char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
  619. return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
  620. }
  621. /**
  622. * calls device handler to change mode of operation
  623. * NOTE: stellar/usb may disconnect when changing mode
  624. *
  625. * @param coredev pointer to a coredev object returned by
  626. * smscore_register_device
  627. * @param mode requested mode of operation
  628. *
  629. * @return 0 on success, <0 on error.
  630. */
  631. int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
  632. {
  633. void *buffer;
  634. int rc = 0;
  635. enum sms_device_type_st type;
  636. sms_debug("set device mode to %d", mode);
  637. if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
  638. if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) {
  639. sms_err("invalid mode specified %d", mode);
  640. return -EINVAL;
  641. }
  642. smscore_registry_setmode(coredev->devpath, mode);
  643. if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
  644. rc = smscore_detect_mode(coredev);
  645. if (rc < 0) {
  646. sms_err("mode detect failed %d", rc);
  647. return rc;
  648. }
  649. }
  650. if (coredev->mode == mode) {
  651. sms_info("device mode %d already set", mode);
  652. return 0;
  653. }
  654. if (!(coredev->modes_supported & (1 << mode))) {
  655. char *fw_filename;
  656. type = smscore_registry_gettype(coredev->devpath);
  657. fw_filename = sms_get_fw_name(coredev, mode, type);
  658. rc = smscore_load_firmware_from_file(coredev,
  659. fw_filename, NULL);
  660. if (rc < 0) {
  661. sms_warn("error %d loading firmware: %s, "
  662. "trying again with default firmware",
  663. rc, fw_filename);
  664. /* try again with the default firmware */
  665. fw_filename = smscore_fw_lkup[mode][type];
  666. rc = smscore_load_firmware_from_file(coredev,
  667. fw_filename, NULL);
  668. if (rc < 0) {
  669. sms_warn("error %d loading "
  670. "firmware: %s", rc,
  671. fw_filename);
  672. return rc;
  673. }
  674. }
  675. sms_log("firmware download success: %s", fw_filename);
  676. } else
  677. sms_info("mode %d supported by running "
  678. "firmware", mode);
  679. buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
  680. SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
  681. if (buffer) {
  682. struct SmsMsgData_ST *msg =
  683. (struct SmsMsgData_ST *)
  684. SMS_ALIGN_ADDRESS(buffer);
  685. SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
  686. sizeof(struct SmsMsgData_ST));
  687. msg->msgData[0] = mode;
  688. rc = smscore_sendrequest_and_wait(
  689. coredev, msg, msg->xMsgHeader.msgLength,
  690. &coredev->init_device_done);
  691. kfree(buffer);
  692. } else {
  693. sms_err("Could not allocate buffer for "
  694. "init device message.");
  695. rc = -ENOMEM;
  696. }
  697. } else {
  698. if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
  699. sms_err("invalid mode specified %d", mode);
  700. return -EINVAL;
  701. }
  702. smscore_registry_setmode(coredev->devpath, mode);
  703. if (coredev->detectmode_handler)
  704. coredev->detectmode_handler(coredev->context,
  705. &coredev->mode);
  706. if (coredev->mode != mode && coredev->setmode_handler)
  707. rc = coredev->setmode_handler(coredev->context, mode);
  708. }
  709. if (rc >= 0) {
  710. coredev->mode = mode;
  711. coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
  712. }
  713. if (rc != 0)
  714. sms_err("return error code %d.", rc);
  715. return rc;
  716. }
  717. /**
  718. * calls device handler to get current mode of operation
  719. *
  720. * @param coredev pointer to a coredev object returned by
  721. * smscore_register_device
  722. *
  723. * @return current mode
  724. */
  725. int smscore_get_device_mode(struct smscore_device_t *coredev)
  726. {
  727. return coredev->mode;
  728. }
  729. /**
  730. * find client by response id & type within the clients list.
  731. * return client handle or NULL.
  732. *
  733. * @param coredev pointer to a coredev object returned by
  734. * smscore_register_device
  735. * @param data_type client data type (SMS_DONT_CARE for all types)
  736. * @param id client id (SMS_DONT_CARE for all id)
  737. *
  738. */
  739. static struct
  740. smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
  741. int data_type, int id)
  742. {
  743. struct smscore_client_t *client = NULL;
  744. struct list_head *next, *first;
  745. unsigned long flags;
  746. struct list_head *firstid, *nextid;
  747. spin_lock_irqsave(&coredev->clientslock, flags);
  748. first = &coredev->clients;
  749. for (next = first->next;
  750. (next != first) && !client;
  751. next = next->next) {
  752. firstid = &((struct smscore_client_t *)next)->idlist;
  753. for (nextid = firstid->next;
  754. nextid != firstid;
  755. nextid = nextid->next) {
  756. if ((((struct smscore_idlist_t *)nextid)->id == id) &&
  757. (((struct smscore_idlist_t *)nextid)->data_type == data_type ||
  758. (((struct smscore_idlist_t *)nextid)->data_type == 0))) {
  759. client = (struct smscore_client_t *) next;
  760. break;
  761. }
  762. }
  763. }
  764. spin_unlock_irqrestore(&coredev->clientslock, flags);
  765. return client;
  766. }
  767. /**
  768. * find client by response id/type, call clients onresponse handler
  769. * return buffer to pool on error
  770. *
  771. * @param coredev pointer to a coredev object returned by
  772. * smscore_register_device
  773. * @param cb pointer to response buffer descriptor
  774. *
  775. */
  776. void smscore_onresponse(struct smscore_device_t *coredev,
  777. struct smscore_buffer_t *cb)
  778. {
  779. struct SmsMsgHdr_ST *phdr =
  780. (struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset);
  781. struct smscore_client_t *client =
  782. smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
  783. int rc = -EBUSY;
  784. static unsigned long last_sample_time; /* = 0; */
  785. static int data_total; /* = 0; */
  786. unsigned long time_now = jiffies_to_msecs(jiffies);
  787. if (!last_sample_time)
  788. last_sample_time = time_now;
  789. if (time_now - last_sample_time > 10000) {
  790. sms_debug("\ndata rate %d bytes/secs",
  791. (int)((data_total * 1000) /
  792. (time_now - last_sample_time)));
  793. last_sample_time = time_now;
  794. data_total = 0;
  795. }
  796. data_total += cb->size;
  797. /* If no client registered for type & id,
  798. * check for control client where type is not registered */
  799. if (client)
  800. rc = client->onresponse_handler(client->context, cb);
  801. if (rc < 0) {
  802. switch (phdr->msgType) {
  803. case MSG_SMS_GET_VERSION_EX_RES:
  804. {
  805. struct SmsVersionRes_ST *ver =
  806. (struct SmsVersionRes_ST *) phdr;
  807. sms_debug("MSG_SMS_GET_VERSION_EX_RES "
  808. "id %d prots 0x%x ver %d.%d",
  809. ver->FirmwareId, ver->SupportedProtocols,
  810. ver->RomVersionMajor, ver->RomVersionMinor);
  811. coredev->mode = ver->FirmwareId == 255 ?
  812. DEVICE_MODE_NONE : ver->FirmwareId;
  813. coredev->modes_supported = ver->SupportedProtocols;
  814. complete(&coredev->version_ex_done);
  815. break;
  816. }
  817. case MSG_SMS_INIT_DEVICE_RES:
  818. sms_debug("MSG_SMS_INIT_DEVICE_RES");
  819. complete(&coredev->init_device_done);
  820. break;
  821. case MSG_SW_RELOAD_START_RES:
  822. sms_debug("MSG_SW_RELOAD_START_RES");
  823. complete(&coredev->reload_start_done);
  824. break;
  825. case MSG_SMS_DATA_DOWNLOAD_RES:
  826. complete(&coredev->data_download_done);
  827. break;
  828. case MSG_SW_RELOAD_EXEC_RES:
  829. sms_debug("MSG_SW_RELOAD_EXEC_RES");
  830. break;
  831. case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
  832. sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
  833. complete(&coredev->trigger_done);
  834. break;
  835. case MSG_SMS_SLEEP_RESUME_COMP_IND:
  836. complete(&coredev->resume_done);
  837. break;
  838. default:
  839. break;
  840. }
  841. smscore_putbuffer(coredev, cb);
  842. }
  843. }
  844. /**
  845. * return pointer to next free buffer descriptor from core pool
  846. *
  847. * @param coredev pointer to a coredev object returned by
  848. * smscore_register_device
  849. *
  850. * @return pointer to descriptor on success, NULL on error.
  851. */
  852. struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
  853. {
  854. struct smscore_buffer_t *cb = NULL;
  855. unsigned long flags;
  856. spin_lock_irqsave(&coredev->bufferslock, flags);
  857. if (!list_empty(&coredev->buffers)) {
  858. cb = (struct smscore_buffer_t *) coredev->buffers.next;
  859. list_del(&cb->entry);
  860. }
  861. spin_unlock_irqrestore(&coredev->bufferslock, flags);
  862. return cb;
  863. }
  864. /**
  865. * return buffer descriptor to a pool
  866. *
  867. * @param coredev pointer to a coredev object returned by
  868. * smscore_register_device
  869. * @param cb pointer buffer descriptor
  870. *
  871. */
  872. void smscore_putbuffer(struct smscore_device_t *coredev,
  873. struct smscore_buffer_t *cb)
  874. {
  875. list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
  876. }
  877. static int smscore_validate_client(struct smscore_device_t *coredev,
  878. struct smscore_client_t *client,
  879. int data_type, int id)
  880. {
  881. struct smscore_idlist_t *listentry;
  882. struct smscore_client_t *registered_client;
  883. if (!client) {
  884. sms_err("bad parameter.");
  885. return -EFAULT;
  886. }
  887. registered_client = smscore_find_client(coredev, data_type, id);
  888. if (registered_client == client)
  889. return 0;
  890. if (registered_client) {
  891. sms_err("The msg ID already registered to another client.");
  892. return -EEXIST;
  893. }
  894. listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
  895. if (!listentry) {
  896. sms_err("Can't allocate memory for client id.");
  897. return -ENOMEM;
  898. }
  899. listentry->id = id;
  900. listentry->data_type = data_type;
  901. list_add_locked(&listentry->entry, &client->idlist,
  902. &coredev->clientslock);
  903. return 0;
  904. }
  905. /**
  906. * creates smsclient object, check that id is taken by another client
  907. *
  908. * @param coredev pointer to a coredev object from clients hotplug
  909. * @param initial_id all messages with this id would be sent to this client
  910. * @param data_type all messages of this type would be sent to this client
  911. * @param onresponse_handler client handler that is called to
  912. * process incoming messages
  913. * @param onremove_handler client handler that is called when device is removed
  914. * @param context client-specific context
  915. * @param client pointer to a value that receives created smsclient object
  916. *
  917. * @return 0 on success, <0 on error.
  918. */
  919. int smscore_register_client(struct smscore_device_t *coredev,
  920. struct smsclient_params_t *params,
  921. struct smscore_client_t **client)
  922. {
  923. struct smscore_client_t *newclient;
  924. /* check that no other channel with same parameters exists */
  925. if (smscore_find_client(coredev, params->data_type,
  926. params->initial_id)) {
  927. sms_err("Client already exist.");
  928. return -EEXIST;
  929. }
  930. newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
  931. if (!newclient) {
  932. sms_err("Failed to allocate memory for client.");
  933. return -ENOMEM;
  934. }
  935. INIT_LIST_HEAD(&newclient->idlist);
  936. newclient->coredev = coredev;
  937. newclient->onresponse_handler = params->onresponse_handler;
  938. newclient->onremove_handler = params->onremove_handler;
  939. newclient->context = params->context;
  940. list_add_locked(&newclient->entry, &coredev->clients,
  941. &coredev->clientslock);
  942. smscore_validate_client(coredev, newclient, params->data_type,
  943. params->initial_id);
  944. *client = newclient;
  945. sms_debug("%p %d %d", params->context, params->data_type,
  946. params->initial_id);
  947. return 0;
  948. }
  949. /**
  950. * frees smsclient object and all subclients associated with it
  951. *
  952. * @param client pointer to smsclient object returned by
  953. * smscore_register_client
  954. *
  955. */
  956. void smscore_unregister_client(struct smscore_client_t *client)
  957. {
  958. struct smscore_device_t *coredev = client->coredev;
  959. unsigned long flags;
  960. spin_lock_irqsave(&coredev->clientslock, flags);
  961. while (!list_empty(&client->idlist)) {
  962. struct smscore_idlist_t *identry =
  963. (struct smscore_idlist_t *) client->idlist.next;
  964. list_del(&identry->entry);
  965. kfree(identry);
  966. }
  967. sms_info("%p", client->context);
  968. list_del(&client->entry);
  969. kfree(client);
  970. spin_unlock_irqrestore(&coredev->clientslock, flags);
  971. }
  972. /**
  973. * verifies that source id is not taken by another client,
  974. * calls device handler to send requests to the device
  975. *
  976. * @param client pointer to smsclient object returned by
  977. * smscore_register_client
  978. * @param buffer pointer to a request buffer
  979. * @param size size (in bytes) of request buffer
  980. *
  981. * @return 0 on success, <0 on error.
  982. */
  983. int smsclient_sendrequest(struct smscore_client_t *client,
  984. void *buffer, size_t size)
  985. {
  986. struct smscore_device_t *coredev;
  987. struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
  988. int rc;
  989. if (client == NULL) {
  990. sms_err("Got NULL client");
  991. return -EINVAL;
  992. }
  993. coredev = client->coredev;
  994. /* check that no other channel with same id exists */
  995. if (coredev == NULL) {
  996. sms_err("Got NULL coredev");
  997. return -EINVAL;
  998. }
  999. rc = smscore_validate_client(client->coredev, client, 0,
  1000. phdr->msgSrcId);
  1001. if (rc < 0)
  1002. return rc;
  1003. return coredev->sendrequest_handler(coredev->context, buffer, size);
  1004. }
  1005. int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
  1006. struct smscore_gpio_config *pinconfig)
  1007. {
  1008. struct {
  1009. struct SmsMsgHdr_ST hdr;
  1010. u32 data[6];
  1011. } msg;
  1012. if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
  1013. msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
  1014. msg.hdr.msgDstId = HIF_TASK;
  1015. msg.hdr.msgFlags = 0;
  1016. msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
  1017. msg.hdr.msgLength = sizeof(msg);
  1018. msg.data[0] = pin;
  1019. msg.data[1] = pinconfig->pullupdown;
  1020. /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
  1021. msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
  1022. switch (pinconfig->outputdriving) {
  1023. case SMS_GPIO_OUTPUTDRIVING_16mA:
  1024. msg.data[3] = 7; /* Nova - 16mA */
  1025. break;
  1026. case SMS_GPIO_OUTPUTDRIVING_12mA:
  1027. msg.data[3] = 5; /* Nova - 11mA */
  1028. break;
  1029. case SMS_GPIO_OUTPUTDRIVING_8mA:
  1030. msg.data[3] = 3; /* Nova - 7mA */
  1031. break;
  1032. case SMS_GPIO_OUTPUTDRIVING_4mA:
  1033. default:
  1034. msg.data[3] = 2; /* Nova - 4mA */
  1035. break;
  1036. }
  1037. msg.data[4] = pinconfig->direction;
  1038. msg.data[5] = 0;
  1039. } else /* TODO: SMS_DEVICE_FAMILY1 */
  1040. return -EINVAL;
  1041. return coredev->sendrequest_handler(coredev->context,
  1042. &msg, sizeof(msg));
  1043. }
  1044. int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
  1045. {
  1046. struct {
  1047. struct SmsMsgHdr_ST hdr;
  1048. u32 data[3];
  1049. } msg;
  1050. if (pin > MAX_GPIO_PIN_NUMBER)
  1051. return -EINVAL;
  1052. msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
  1053. msg.hdr.msgDstId = HIF_TASK;
  1054. msg.hdr.msgFlags = 0;
  1055. msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
  1056. msg.hdr.msgLength = sizeof(msg);
  1057. msg.data[0] = pin;
  1058. msg.data[1] = level ? 1 : 0;
  1059. msg.data[2] = 0;
  1060. return coredev->sendrequest_handler(coredev->context,
  1061. &msg, sizeof(msg));
  1062. }
  1063. static int __init smscore_module_init(void)
  1064. {
  1065. int rc = 0;
  1066. INIT_LIST_HEAD(&g_smscore_notifyees);
  1067. INIT_LIST_HEAD(&g_smscore_devices);
  1068. kmutex_init(&g_smscore_deviceslock);
  1069. INIT_LIST_HEAD(&g_smscore_registry);
  1070. kmutex_init(&g_smscore_registrylock);
  1071. /* USB Register */
  1072. rc = smsusb_register();
  1073. /* DVB Register */
  1074. rc = smsdvb_register();
  1075. sms_debug("rc %d", rc);
  1076. return rc;
  1077. }
  1078. static void __exit smscore_module_exit(void)
  1079. {
  1080. kmutex_lock(&g_smscore_deviceslock);
  1081. while (!list_empty(&g_smscore_notifyees)) {
  1082. struct smscore_device_notifyee_t *notifyee =
  1083. (struct smscore_device_notifyee_t *)
  1084. g_smscore_notifyees.next;
  1085. list_del(&notifyee->entry);
  1086. kfree(notifyee);
  1087. }
  1088. kmutex_unlock(&g_smscore_deviceslock);
  1089. kmutex_lock(&g_smscore_registrylock);
  1090. while (!list_empty(&g_smscore_registry)) {
  1091. struct smscore_registry_entry_t *entry =
  1092. (struct smscore_registry_entry_t *)
  1093. g_smscore_registry.next;
  1094. list_del(&entry->entry);
  1095. kfree(entry);
  1096. }
  1097. kmutex_unlock(&g_smscore_registrylock);
  1098. /* DVB UnRegister */
  1099. smsdvb_unregister();
  1100. /* Unregister USB */
  1101. smsusb_unregister();
  1102. sms_debug("");
  1103. }
  1104. module_init(smscore_module_init);
  1105. module_exit(smscore_module_exit);
  1106. MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
  1107. MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)");
  1108. MODULE_LICENSE("GPL");