smsusb.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. #include <linux/kernel.h>
  2. #include <linux/init.h>
  3. #include <linux/usb.h>
  4. #include <linux/firmware.h>
  5. #include "smscoreapi.h"
  6. #define USB_VID_SIANO 0x187f
  7. #define USB_PID_0010 0x0010
  8. #define USB_PID_0100 0x0100
  9. #define USB_PID_0200 0x0200
  10. #define USB1_BUFFER_SIZE 0x1000
  11. #define USB2_BUFFER_SIZE 0x4000
  12. #define MAX_BUFFERS 50
  13. #define MAX_URBS 10
  14. typedef struct _smsusb_device smsusb_device_t;
  15. typedef struct _smsusb_urb
  16. {
  17. smscore_buffer_t *cb;
  18. smsusb_device_t *dev;
  19. struct urb urb;
  20. } smsusb_urb_t;
  21. typedef struct _smsusb_device
  22. {
  23. struct usb_device* udev;
  24. smscore_device_t *coredev;
  25. smsusb_urb_t surbs[MAX_URBS];
  26. int response_alignment;
  27. int buffer_size;
  28. } *psmsusb_device_t;
  29. static struct usb_device_id smsusb_id_table [] = {
  30. { USB_DEVICE(USB_VID_SIANO, USB_PID_0010) },
  31. { USB_DEVICE(USB_VID_SIANO, USB_PID_0100) },
  32. { USB_DEVICE(USB_VID_SIANO, USB_PID_0200) },
  33. { } /* Terminating entry */
  34. };
  35. MODULE_DEVICE_TABLE (usb, smsusb_id_table);
  36. int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb);
  37. void smsusb_onresponse(struct urb *urb)
  38. {
  39. smsusb_urb_t *surb = (smsusb_urb_t *) urb->context;
  40. smsusb_device_t *dev = surb->dev;
  41. if (urb->status < 0)
  42. {
  43. printk(KERN_INFO "%s error, urb status %d, %d bytes\n", __FUNCTION__, urb->status, urb->actual_length);
  44. return;
  45. }
  46. if (urb->actual_length > 0)
  47. {
  48. SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) surb->cb->p;
  49. if (urb->actual_length >= phdr->msgLength)
  50. {
  51. surb->cb->size = phdr->msgLength;
  52. if (dev->response_alignment && (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG))
  53. {
  54. surb->cb->offset = dev->response_alignment + ((phdr->msgFlags >> 8) & 3);
  55. // sanity check
  56. if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length)
  57. {
  58. printk("%s: invalid response msglen %d offset %d size %d\n", __FUNCTION__, phdr->msgLength, surb->cb->offset, urb->actual_length);
  59. goto exit_and_resubmit;
  60. }
  61. // move buffer pointer and copy header to its new location
  62. memcpy((char*) phdr + surb->cb->offset, phdr, sizeof(SmsMsgHdr_ST));
  63. }
  64. else
  65. surb->cb->offset = 0;
  66. smscore_onresponse(dev->coredev, surb->cb);
  67. surb->cb = NULL;
  68. }
  69. else
  70. {
  71. printk("%s invalid response msglen %d actual %d\n", __FUNCTION__, phdr->msgLength, urb->actual_length);
  72. }
  73. }
  74. exit_and_resubmit:
  75. smsusb_submit_urb(dev, surb);
  76. }
  77. int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb)
  78. {
  79. if (!surb->cb)
  80. {
  81. surb->cb = smscore_getbuffer(dev->coredev);
  82. if (!surb->cb)
  83. {
  84. printk(KERN_INFO "%s smscore_getbuffer(...) returned NULL\n", __FUNCTION__);
  85. return -ENOMEM;
  86. }
  87. }
  88. usb_fill_bulk_urb(
  89. &surb->urb,
  90. dev->udev,
  91. usb_rcvbulkpipe(dev->udev, 0x81),
  92. surb->cb->p,
  93. dev->buffer_size,
  94. smsusb_onresponse,
  95. surb
  96. );
  97. surb->urb.transfer_dma = surb->cb->phys;
  98. surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
  99. return usb_submit_urb(&surb->urb, GFP_ATOMIC);
  100. }
  101. void smsusb_stop_streaming(smsusb_device_t* dev)
  102. {
  103. int i;
  104. for (i = 0; i < MAX_URBS; i ++)
  105. {
  106. usb_kill_urb(&dev->surbs[i].urb);
  107. if (dev->surbs[i].cb)
  108. {
  109. smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
  110. dev->surbs[i].cb = NULL;
  111. }
  112. }
  113. }
  114. int smsusb_start_streaming(smsusb_device_t* dev)
  115. {
  116. int i, rc;
  117. for (i = 0; i < MAX_URBS; i ++)
  118. {
  119. rc = smsusb_submit_urb(dev, &dev->surbs[i]);
  120. if (rc < 0)
  121. {
  122. printk(KERN_INFO "%s smsusb_submit_urb(...) failed\n", __FUNCTION__);
  123. smsusb_stop_streaming(dev);
  124. break;
  125. }
  126. }
  127. return rc;
  128. }
  129. int smsusb_sendrequest(void *context, void *buffer, size_t size)
  130. {
  131. smsusb_device_t* dev = (smsusb_device_t*) context;
  132. int dummy;
  133. return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000);
  134. }
  135. char *smsusb1_fw_lkup[] =
  136. {
  137. "dvbt_stellar_usb.inp",
  138. "dvbh_stellar_usb.inp",
  139. "tdmb_stellar_usb.inp",
  140. "none",
  141. "dvbt_bda_stellar_usb.inp",
  142. };
  143. int smsusb1_load_firmware(struct usb_device *udev, int id)
  144. {
  145. const struct firmware *fw;
  146. u8* fw_buffer;
  147. int rc, dummy;
  148. if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA)
  149. {
  150. printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, id);
  151. return -EINVAL;
  152. }
  153. rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev);
  154. if (rc < 0)
  155. {
  156. printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", __FUNCTION__, smsusb1_fw_lkup[id], id);
  157. return rc;
  158. }
  159. fw_buffer = kmalloc(fw->size, GFP_KERNEL);
  160. if (fw_buffer)
  161. {
  162. memcpy(fw_buffer, fw->data, fw->size);
  163. rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000);
  164. printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", __FUNCTION__, fw->size, dummy, rc);
  165. kfree(fw_buffer);
  166. }
  167. else
  168. {
  169. printk(KERN_INFO "failed to allocate firmware buffer\n");
  170. rc = -ENOMEM;
  171. }
  172. release_firmware(fw);
  173. return rc;
  174. }
  175. void smsusb1_detectmode(void *context, int *mode)
  176. {
  177. char *product_string = ((smsusb_device_t *) context)->udev->product;
  178. *mode = DEVICE_MODE_NONE;
  179. if (!product_string)
  180. {
  181. product_string = "none";
  182. printk("%s product string not found\n", __FUNCTION__);
  183. }
  184. else
  185. {
  186. if (strstr(product_string, "DVBH"))
  187. *mode = 1;
  188. else if (strstr(product_string, "BDA"))
  189. *mode = 4;
  190. else if (strstr(product_string, "DVBT"))
  191. *mode = 0;
  192. else if (strstr(product_string, "TDMB"))
  193. *mode = 2;
  194. }
  195. printk("%s: %d \"%s\"\n", __FUNCTION__, *mode, product_string);
  196. }
  197. int smsusb1_setmode(void *context, int mode)
  198. {
  199. SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 };
  200. if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA)
  201. {
  202. printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, mode);
  203. return -EINVAL;
  204. }
  205. return smsusb_sendrequest(context, &Msg, sizeof(Msg));
  206. }
  207. void smsusb_term_device(struct usb_interface *intf)
  208. {
  209. smsusb_device_t *dev = (smsusb_device_t*) usb_get_intfdata(intf);
  210. if (dev)
  211. {
  212. smsusb_stop_streaming(dev);
  213. // unregister from smscore
  214. if (dev->coredev)
  215. smscore_unregister_device(dev->coredev);
  216. kfree(dev);
  217. printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, dev);
  218. }
  219. usb_set_intfdata(intf, NULL);
  220. }
  221. int smsusb_init_device(struct usb_interface *intf)
  222. {
  223. smsdevice_params_t params;
  224. smsusb_device_t* dev;
  225. int i, rc;
  226. // create device object
  227. dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL);
  228. if (!dev)
  229. {
  230. printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", __FUNCTION__);
  231. return -ENOMEM;
  232. }
  233. memset(&params, 0, sizeof(params));
  234. usb_set_intfdata(intf, dev);
  235. dev->udev = interface_to_usbdev(intf);
  236. switch (dev->udev->descriptor.idProduct)
  237. {
  238. case USB_PID_0100:
  239. dev->buffer_size = USB1_BUFFER_SIZE;
  240. params.setmode_handler = smsusb1_setmode;
  241. params.detectmode_handler = smsusb1_detectmode;
  242. break;
  243. default:
  244. dev->buffer_size = USB2_BUFFER_SIZE;
  245. dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - sizeof(SmsMsgHdr_ST);
  246. params.flags |= SMS_DEVICE_FAMILY2;
  247. break;
  248. }
  249. params.device = &dev->udev->dev;
  250. params.buffer_size = dev->buffer_size;
  251. params.num_buffers = MAX_BUFFERS;
  252. params.sendrequest_handler = smsusb_sendrequest;
  253. params.context = dev;
  254. snprintf(params.devpath, sizeof(params.devpath), "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath);
  255. // register in smscore
  256. rc = smscore_register_device(&params, &dev->coredev);
  257. if (rc < 0)
  258. {
  259. printk(KERN_INFO "%s smscore_register_device(...) failed, rc %d\n", __FUNCTION__, rc);
  260. smsusb_term_device(intf);
  261. return rc;
  262. }
  263. // initialize urbs
  264. for (i = 0; i < MAX_URBS; i ++)
  265. {
  266. dev->surbs[i].dev = dev;
  267. usb_init_urb(&dev->surbs[i].urb);
  268. }
  269. rc = smsusb_start_streaming(dev);
  270. if (rc < 0)
  271. {
  272. printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", __FUNCTION__);
  273. smsusb_term_device(intf);
  274. return rc;
  275. }
  276. rc = smscore_start_device(dev->coredev);
  277. if (rc < 0)
  278. {
  279. printk(KERN_INFO "%s smscore_start_device(...) failed\n", __FUNCTION__);
  280. smsusb_term_device(intf);
  281. return rc;
  282. }
  283. printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev);
  284. return rc;
  285. }
  286. int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
  287. {
  288. struct usb_device *udev = interface_to_usbdev(intf);
  289. char devpath[32];
  290. int i, rc;
  291. if (intf->num_altsetting > 0)
  292. {
  293. rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0);
  294. if (rc < 0)
  295. {
  296. printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", __FUNCTION__, rc);
  297. return rc;
  298. }
  299. }
  300. printk(KERN_INFO "smsusb_probe %d\n", intf->cur_altsetting->desc.bInterfaceNumber);
  301. for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++)
  302. printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
  303. if (udev->actconfig->desc.bNumInterfaces == 2 && intf->cur_altsetting->desc.bInterfaceNumber == 0)
  304. {
  305. printk(KERN_INFO "rom interface 0 is not used\n");
  306. return -ENODEV;
  307. }
  308. if (intf->cur_altsetting->desc.bInterfaceNumber == 1)
  309. {
  310. snprintf(devpath, 32, "%d:%s", udev->bus->busnum, udev->devpath);
  311. return smsusb1_load_firmware(udev, smscore_registry_getmode(devpath));
  312. }
  313. return smsusb_init_device(intf);
  314. }
  315. void smsusb_disconnect(struct usb_interface *intf)
  316. {
  317. smsusb_term_device(intf);
  318. }
  319. static struct usb_driver smsusb_driver = {
  320. .name = "smsusb",
  321. .probe = smsusb_probe,
  322. .disconnect = smsusb_disconnect,
  323. .id_table = smsusb_id_table,
  324. };
  325. int smsusb_register(void)
  326. {
  327. int rc = usb_register(&smsusb_driver);
  328. if (rc)
  329. printk(KERN_INFO "usb_register failed. Error number %d\n", rc);
  330. printk(KERN_INFO "%s\n", __FUNCTION__);
  331. return rc;
  332. }
  333. void smsusb_unregister(void)
  334. {
  335. /* Regular USB Cleanup */
  336. usb_deregister(&smsusb_driver);
  337. printk(KERN_INFO "%s\n", __FUNCTION__);
  338. }