dvb-usb-urb.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /* dvb-usb-urb.c is part of the DVB USB library.
  2. *
  3. * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  4. * see dvb-usb-init.c for copyright information.
  5. *
  6. * This file contains functions for initializing and handling the
  7. * USB and URB stuff.
  8. */
  9. #include "dvb-usb-common.h"
  10. int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
  11. u16 rlen, int delay_ms)
  12. {
  13. int actlen,ret = -ENOMEM;
  14. if (d->props.generic_bulk_ctrl_endpoint == 0) {
  15. err("endpoint for generic control not specified.");
  16. return -EINVAL;
  17. }
  18. if (wbuf == NULL || wlen == 0)
  19. return -EINVAL;
  20. if ((ret = down_interruptible(&d->usb_sem)))
  21. return ret;
  22. deb_xfer(">>> ");
  23. debug_dump(wbuf,wlen,deb_xfer);
  24. ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
  25. d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
  26. 2000);
  27. if (ret)
  28. err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
  29. else
  30. ret = actlen != wlen ? -1 : 0;
  31. /* an answer is expected, and no error before */
  32. if (!ret && rbuf && rlen) {
  33. if (delay_ms)
  34. msleep(delay_ms);
  35. ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
  36. d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
  37. 2000);
  38. if (ret)
  39. err("recv bulk message failed: %d",ret);
  40. else {
  41. deb_xfer("<<< ");
  42. debug_dump(rbuf,actlen,deb_xfer);
  43. }
  44. }
  45. up(&d->usb_sem);
  46. return ret;
  47. }
  48. EXPORT_SYMBOL(dvb_usb_generic_rw);
  49. int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
  50. {
  51. return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
  52. }
  53. EXPORT_SYMBOL(dvb_usb_generic_write);
  54. /* URB stuff for streaming */
  55. static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
  56. {
  57. struct dvb_usb_device *d = urb->context;
  58. int ptype = usb_pipetype(urb->pipe);
  59. int i;
  60. u8 *b;
  61. deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
  62. ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount,
  63. urb->status,urb->actual_length,urb->transfer_buffer_length,
  64. urb->number_of_packets,urb->error_count);
  65. switch (urb->status) {
  66. case 0: /* success */
  67. case -ETIMEDOUT: /* NAK */
  68. break;
  69. case -ECONNRESET: /* kill */
  70. case -ENOENT:
  71. case -ESHUTDOWN:
  72. return;
  73. default: /* error */
  74. deb_ts("urb completition error %d.", urb->status);
  75. break;
  76. }
  77. if (d->feedcount > 0) {
  78. if (d->state & DVB_USB_STATE_DVB) {
  79. switch (ptype) {
  80. case PIPE_ISOCHRONOUS:
  81. b = (u8 *) urb->transfer_buffer;
  82. for (i = 0; i < urb->number_of_packets; i++) {
  83. if (urb->iso_frame_desc[i].status != 0)
  84. deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
  85. else if (urb->iso_frame_desc[i].actual_length > 0) {
  86. dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset,
  87. urb->iso_frame_desc[i].actual_length);
  88. }
  89. urb->iso_frame_desc[i].status = 0;
  90. urb->iso_frame_desc[i].actual_length = 0;
  91. }
  92. debug_dump(b,20,deb_ts);
  93. break;
  94. case PIPE_BULK:
  95. if (urb->actual_length > 0)
  96. dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length);
  97. break;
  98. default:
  99. err("unkown endpoint type in completition handler.");
  100. return;
  101. }
  102. }
  103. }
  104. usb_submit_urb(urb,GFP_ATOMIC);
  105. }
  106. int dvb_usb_urb_kill(struct dvb_usb_device *d)
  107. {
  108. int i;
  109. for (i = 0; i < d->urbs_submitted; i++) {
  110. deb_ts("killing URB no. %d.\n",i);
  111. /* stop the URB */
  112. usb_kill_urb(d->urb_list[i]);
  113. }
  114. d->urbs_submitted = 0;
  115. return 0;
  116. }
  117. int dvb_usb_urb_submit(struct dvb_usb_device *d)
  118. {
  119. int i,ret;
  120. for (i = 0; i < d->urbs_initialized; i++) {
  121. deb_ts("submitting URB no. %d\n",i);
  122. if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
  123. err("could not submit URB no. %d - get them all back",i);
  124. dvb_usb_urb_kill(d);
  125. return ret;
  126. }
  127. d->urbs_submitted++;
  128. }
  129. return 0;
  130. }
  131. static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d)
  132. {
  133. if (d->state & DVB_USB_STATE_URB_BUF) {
  134. while (d->buf_num) {
  135. d->buf_num--;
  136. deb_mem("freeing buffer %d\n",d->buf_num);
  137. usb_buffer_free(d->udev, d->buf_size,
  138. d->buf_list[d->buf_num], d->dma_addr[d->buf_num]);
  139. }
  140. kfree(d->buf_list);
  141. kfree(d->dma_addr);
  142. }
  143. d->state &= ~DVB_USB_STATE_URB_BUF;
  144. return 0;
  145. }
  146. static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size)
  147. {
  148. d->buf_num = 0;
  149. d->buf_size = size;
  150. deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
  151. if ((d->buf_list = kmalloc(num*sizeof(u8 *), GFP_ATOMIC)) == NULL)
  152. return -ENOMEM;
  153. if ((d->dma_addr = kmalloc(num*sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) {
  154. kfree(d->buf_list);
  155. return -ENOMEM;
  156. }
  157. memset(d->buf_list,0,num*sizeof(u8 *));
  158. memset(d->dma_addr,0,num*sizeof(dma_addr_t));
  159. d->state |= DVB_USB_STATE_URB_BUF;
  160. for (d->buf_num = 0; d->buf_num < num; d->buf_num++) {
  161. deb_mem("allocating buffer %d\n",d->buf_num);
  162. if (( d->buf_list[d->buf_num] =
  163. usb_buffer_alloc(d->udev, size, SLAB_ATOMIC,
  164. &d->dma_addr[d->buf_num]) ) == NULL) {
  165. deb_mem("not enough memory for urb-buffer allocation.\n");
  166. dvb_usb_free_stream_buffers(d);
  167. return -ENOMEM;
  168. }
  169. deb_mem("buffer %d: %p (dma: %llu)\n",
  170. d->buf_num, d->buf_list[d->buf_num],
  171. (unsigned long long)d->dma_addr[d->buf_num]);
  172. memset(d->buf_list[d->buf_num],0,size);
  173. }
  174. deb_mem("allocation successful\n");
  175. return 0;
  176. }
  177. static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
  178. {
  179. int i;
  180. if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
  181. d->props.urb.u.bulk.buffersize)) < 0)
  182. return i;
  183. /* allocate the URBs */
  184. for (i = 0; i < d->props.urb.count; i++) {
  185. if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
  186. return -ENOMEM;
  187. usb_fill_bulk_urb( d->urb_list[i], d->udev,
  188. usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
  189. d->buf_list[i],
  190. d->props.urb.u.bulk.buffersize,
  191. dvb_usb_urb_complete, d);
  192. d->urb_list[i]->transfer_flags = 0;
  193. d->urbs_initialized++;
  194. }
  195. return 0;
  196. }
  197. static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d)
  198. {
  199. int i,j;
  200. if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
  201. d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0)
  202. return i;
  203. /* allocate the URBs */
  204. for (i = 0; i < d->props.urb.count; i++) {
  205. struct urb *urb;
  206. int frame_offset = 0;
  207. if ((d->urb_list[i] =
  208. usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
  209. return -ENOMEM;
  210. urb = d->urb_list[i];
  211. urb->dev = d->udev;
  212. urb->context = d;
  213. urb->complete = dvb_usb_urb_complete;
  214. urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint);
  215. urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
  216. urb->interval = d->props.urb.u.isoc.interval;
  217. urb->number_of_packets = d->props.urb.u.isoc.framesperurb;
  218. urb->transfer_buffer_length = d->buf_size;
  219. urb->transfer_buffer = d->buf_list[i];
  220. urb->transfer_dma = d->dma_addr[i];
  221. for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) {
  222. urb->iso_frame_desc[j].offset = frame_offset;
  223. urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize;
  224. frame_offset += d->props.urb.u.isoc.framesize;
  225. }
  226. d->urbs_initialized++;
  227. }
  228. return 0;
  229. }
  230. int dvb_usb_urb_init(struct dvb_usb_device *d)
  231. {
  232. /*
  233. * when reloading the driver w/o replugging the device
  234. * sometimes a timeout occures, this helps
  235. */
  236. if (d->props.generic_bulk_ctrl_endpoint != 0) {
  237. usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
  238. usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
  239. }
  240. usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint));
  241. /* allocate the array for the data transfer URBs */
  242. d->urb_list = kmalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL);
  243. if (d->urb_list == NULL)
  244. return -ENOMEM;
  245. memset(d->urb_list,0,d->props.urb.count * sizeof(struct urb *));
  246. d->state |= DVB_USB_STATE_URB_LIST;
  247. switch (d->props.urb.type) {
  248. case DVB_USB_BULK:
  249. return dvb_usb_bulk_urb_init(d);
  250. case DVB_USB_ISOC:
  251. return dvb_usb_isoc_urb_init(d);
  252. default:
  253. err("unkown URB-type for data transfer.");
  254. return -EINVAL;
  255. }
  256. }
  257. int dvb_usb_urb_exit(struct dvb_usb_device *d)
  258. {
  259. int i;
  260. dvb_usb_urb_kill(d);
  261. if (d->state & DVB_USB_STATE_URB_LIST) {
  262. for (i = 0; i < d->urbs_initialized; i++) {
  263. if (d->urb_list[i] != NULL) {
  264. deb_mem("freeing URB no. %d.\n",i);
  265. /* free the URBs */
  266. usb_free_urb(d->urb_list[i]);
  267. }
  268. }
  269. d->urbs_initialized = 0;
  270. /* free the urb array */
  271. kfree(d->urb_list);
  272. d->state &= ~DVB_USB_STATE_URB_LIST;
  273. }
  274. dvb_usb_free_stream_buffers(d);
  275. return 0;
  276. }