dvb-usb-urb.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  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 = mutex_lock_interruptible(&d->usb_mutex)))
  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. mutex_unlock(&d->usb_mutex);
  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. break;
  68. case -ECONNRESET: /* kill */
  69. case -ENOENT:
  70. case -ESHUTDOWN:
  71. return;
  72. default: /* error */
  73. deb_ts("urb completition error %d.", urb->status);
  74. break;
  75. }
  76. if (d->feedcount > 0) {
  77. if (d->state & DVB_USB_STATE_DVB) {
  78. switch (ptype) {
  79. case PIPE_ISOCHRONOUS:
  80. b = (u8 *) urb->transfer_buffer;
  81. for (i = 0; i < urb->number_of_packets; i++) {
  82. if (urb->iso_frame_desc[i].status != 0)
  83. deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
  84. else if (urb->iso_frame_desc[i].actual_length > 0) {
  85. dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset,
  86. urb->iso_frame_desc[i].actual_length);
  87. }
  88. urb->iso_frame_desc[i].status = 0;
  89. urb->iso_frame_desc[i].actual_length = 0;
  90. }
  91. debug_dump(b,20,deb_ts);
  92. break;
  93. case PIPE_BULK:
  94. if (urb->actual_length > 0)
  95. dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length);
  96. break;
  97. default:
  98. err("unkown endpoint type in completition handler.");
  99. return;
  100. }
  101. }
  102. }
  103. usb_submit_urb(urb,GFP_ATOMIC);
  104. }
  105. int dvb_usb_urb_kill(struct dvb_usb_device *d)
  106. {
  107. int i;
  108. for (i = 0; i < d->urbs_submitted; i++) {
  109. deb_ts("killing URB no. %d.\n",i);
  110. /* stop the URB */
  111. usb_kill_urb(d->urb_list[i]);
  112. }
  113. d->urbs_submitted = 0;
  114. return 0;
  115. }
  116. int dvb_usb_urb_submit(struct dvb_usb_device *d)
  117. {
  118. int i,ret;
  119. for (i = 0; i < d->urbs_initialized; i++) {
  120. deb_ts("submitting URB no. %d\n",i);
  121. if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
  122. err("could not submit URB no. %d - get them all back",i);
  123. dvb_usb_urb_kill(d);
  124. return ret;
  125. }
  126. d->urbs_submitted++;
  127. }
  128. return 0;
  129. }
  130. static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d)
  131. {
  132. if (d->state & DVB_USB_STATE_URB_BUF) {
  133. while (d->buf_num) {
  134. d->buf_num--;
  135. deb_mem("freeing buffer %d\n",d->buf_num);
  136. usb_buffer_free(d->udev, d->buf_size,
  137. d->buf_list[d->buf_num], d->dma_addr[d->buf_num]);
  138. }
  139. kfree(d->buf_list);
  140. kfree(d->dma_addr);
  141. }
  142. d->state &= ~DVB_USB_STATE_URB_BUF;
  143. return 0;
  144. }
  145. static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size)
  146. {
  147. d->buf_num = 0;
  148. d->buf_size = size;
  149. deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
  150. if ((d->buf_list = kcalloc(num, sizeof(u8 *), GFP_ATOMIC)) == NULL)
  151. return -ENOMEM;
  152. if ((d->dma_addr = kcalloc(num, sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) {
  153. kfree(d->buf_list);
  154. return -ENOMEM;
  155. }
  156. d->state |= DVB_USB_STATE_URB_BUF;
  157. for (d->buf_num = 0; d->buf_num < num; d->buf_num++) {
  158. deb_mem("allocating buffer %d\n",d->buf_num);
  159. if (( d->buf_list[d->buf_num] =
  160. usb_buffer_alloc(d->udev, size, SLAB_ATOMIC,
  161. &d->dma_addr[d->buf_num]) ) == NULL) {
  162. deb_mem("not enough memory for urb-buffer allocation.\n");
  163. dvb_usb_free_stream_buffers(d);
  164. return -ENOMEM;
  165. }
  166. deb_mem("buffer %d: %p (dma: %llu)\n",
  167. d->buf_num, d->buf_list[d->buf_num],
  168. (unsigned long long)d->dma_addr[d->buf_num]);
  169. memset(d->buf_list[d->buf_num],0,size);
  170. }
  171. deb_mem("allocation successful\n");
  172. return 0;
  173. }
  174. static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
  175. {
  176. int i;
  177. if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
  178. d->props.urb.u.bulk.buffersize)) < 0)
  179. return i;
  180. /* allocate the URBs */
  181. for (i = 0; i < d->props.urb.count; i++) {
  182. if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
  183. return -ENOMEM;
  184. usb_fill_bulk_urb( d->urb_list[i], d->udev,
  185. usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
  186. d->buf_list[i],
  187. d->props.urb.u.bulk.buffersize,
  188. dvb_usb_urb_complete, d);
  189. d->urb_list[i]->transfer_flags = 0;
  190. d->urbs_initialized++;
  191. }
  192. return 0;
  193. }
  194. static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d)
  195. {
  196. int i,j;
  197. if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
  198. d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0)
  199. return i;
  200. /* allocate the URBs */
  201. for (i = 0; i < d->props.urb.count; i++) {
  202. struct urb *urb;
  203. int frame_offset = 0;
  204. if ((d->urb_list[i] =
  205. usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
  206. return -ENOMEM;
  207. urb = d->urb_list[i];
  208. urb->dev = d->udev;
  209. urb->context = d;
  210. urb->complete = dvb_usb_urb_complete;
  211. urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint);
  212. urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
  213. urb->interval = d->props.urb.u.isoc.interval;
  214. urb->number_of_packets = d->props.urb.u.isoc.framesperurb;
  215. urb->transfer_buffer_length = d->buf_size;
  216. urb->transfer_buffer = d->buf_list[i];
  217. urb->transfer_dma = d->dma_addr[i];
  218. for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) {
  219. urb->iso_frame_desc[j].offset = frame_offset;
  220. urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize;
  221. frame_offset += d->props.urb.u.isoc.framesize;
  222. }
  223. d->urbs_initialized++;
  224. }
  225. return 0;
  226. }
  227. int dvb_usb_urb_init(struct dvb_usb_device *d)
  228. {
  229. /*
  230. * when reloading the driver w/o replugging the device
  231. * sometimes a timeout occures, this helps
  232. */
  233. if (d->props.generic_bulk_ctrl_endpoint != 0) {
  234. usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
  235. usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
  236. }
  237. usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint));
  238. /* allocate the array for the data transfer URBs */
  239. d->urb_list = kzalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL);
  240. if (d->urb_list == NULL)
  241. return -ENOMEM;
  242. d->state |= DVB_USB_STATE_URB_LIST;
  243. switch (d->props.urb.type) {
  244. case DVB_USB_BULK:
  245. return dvb_usb_bulk_urb_init(d);
  246. case DVB_USB_ISOC:
  247. return dvb_usb_isoc_urb_init(d);
  248. default:
  249. err("unkown URB-type for data transfer.");
  250. return -EINVAL;
  251. }
  252. }
  253. int dvb_usb_urb_exit(struct dvb_usb_device *d)
  254. {
  255. int i;
  256. dvb_usb_urb_kill(d);
  257. if (d->state & DVB_USB_STATE_URB_LIST) {
  258. for (i = 0; i < d->urbs_initialized; i++) {
  259. if (d->urb_list[i] != NULL) {
  260. deb_mem("freeing URB no. %d.\n",i);
  261. /* free the URBs */
  262. usb_free_urb(d->urb_list[i]);
  263. }
  264. }
  265. d->urbs_initialized = 0;
  266. /* free the urb array */
  267. kfree(d->urb_list);
  268. d->state &= ~DVB_USB_STATE_URB_LIST;
  269. }
  270. dvb_usb_free_stream_buffers(d);
  271. return 0;
  272. }