pvrusb2-ioread.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. *
  4. * Copyright (C) 2005 Mike Isely <[email protected]>
  5. */
  6. #include "pvrusb2-ioread.h"
  7. #include "pvrusb2-debug.h"
  8. #include <linux/errno.h>
  9. #include <linux/string.h>
  10. #include <linux/mm.h>
  11. #include <linux/slab.h>
  12. #include <linux/mutex.h>
  13. #include <linux/uaccess.h>
  14. #define BUFFER_COUNT 32
  15. #define BUFFER_SIZE PAGE_ALIGN(0x4000)
  16. struct pvr2_ioread {
  17. struct pvr2_stream *stream;
  18. char *buffer_storage[BUFFER_COUNT];
  19. char *sync_key_ptr;
  20. unsigned int sync_key_len;
  21. unsigned int sync_buf_offs;
  22. unsigned int sync_state;
  23. unsigned int sync_trashed_count;
  24. int enabled; // Streaming is on
  25. int spigot_open; // OK to pass data to client
  26. int stream_running; // Passing data to client now
  27. /* State relevant to current buffer being read */
  28. struct pvr2_buffer *c_buf;
  29. char *c_data_ptr;
  30. unsigned int c_data_len;
  31. unsigned int c_data_offs;
  32. struct mutex mutex;
  33. };
  34. static int pvr2_ioread_init(struct pvr2_ioread *cp)
  35. {
  36. unsigned int idx;
  37. cp->stream = NULL;
  38. mutex_init(&cp->mutex);
  39. for (idx = 0; idx < BUFFER_COUNT; idx++) {
  40. cp->buffer_storage[idx] = kmalloc(BUFFER_SIZE,GFP_KERNEL);
  41. if (!(cp->buffer_storage[idx])) break;
  42. }
  43. if (idx < BUFFER_COUNT) {
  44. // An allocation appears to have failed
  45. for (idx = 0; idx < BUFFER_COUNT; idx++) {
  46. if (!(cp->buffer_storage[idx])) continue;
  47. kfree(cp->buffer_storage[idx]);
  48. }
  49. return -ENOMEM;
  50. }
  51. return 0;
  52. }
  53. static void pvr2_ioread_done(struct pvr2_ioread *cp)
  54. {
  55. unsigned int idx;
  56. pvr2_ioread_setup(cp,NULL);
  57. for (idx = 0; idx < BUFFER_COUNT; idx++) {
  58. if (!(cp->buffer_storage[idx])) continue;
  59. kfree(cp->buffer_storage[idx]);
  60. }
  61. }
  62. struct pvr2_ioread *pvr2_ioread_create(void)
  63. {
  64. struct pvr2_ioread *cp;
  65. cp = kzalloc(sizeof(*cp),GFP_KERNEL);
  66. if (!cp) return NULL;
  67. pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp);
  68. if (pvr2_ioread_init(cp) < 0) {
  69. kfree(cp);
  70. return NULL;
  71. }
  72. return cp;
  73. }
  74. void pvr2_ioread_destroy(struct pvr2_ioread *cp)
  75. {
  76. if (!cp) return;
  77. pvr2_ioread_done(cp);
  78. pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_destroy id=%p",cp);
  79. if (cp->sync_key_ptr) {
  80. kfree(cp->sync_key_ptr);
  81. cp->sync_key_ptr = NULL;
  82. }
  83. kfree(cp);
  84. }
  85. void pvr2_ioread_set_sync_key(struct pvr2_ioread *cp,
  86. const char *sync_key_ptr,
  87. unsigned int sync_key_len)
  88. {
  89. if (!cp) return;
  90. if (!sync_key_ptr) sync_key_len = 0;
  91. if ((sync_key_len == cp->sync_key_len) &&
  92. ((!sync_key_len) ||
  93. (!memcmp(sync_key_ptr,cp->sync_key_ptr,sync_key_len)))) return;
  94. if (sync_key_len != cp->sync_key_len) {
  95. if (cp->sync_key_ptr) {
  96. kfree(cp->sync_key_ptr);
  97. cp->sync_key_ptr = NULL;
  98. }
  99. cp->sync_key_len = 0;
  100. if (sync_key_len) {
  101. cp->sync_key_ptr = kmalloc(sync_key_len,GFP_KERNEL);
  102. if (cp->sync_key_ptr) {
  103. cp->sync_key_len = sync_key_len;
  104. }
  105. }
  106. }
  107. if (!cp->sync_key_len) return;
  108. memcpy(cp->sync_key_ptr,sync_key_ptr,cp->sync_key_len);
  109. }
  110. static void pvr2_ioread_stop(struct pvr2_ioread *cp)
  111. {
  112. if (!(cp->enabled)) return;
  113. pvr2_trace(PVR2_TRACE_START_STOP,
  114. "/*---TRACE_READ---*/ pvr2_ioread_stop id=%p",cp);
  115. pvr2_stream_kill(cp->stream);
  116. cp->c_buf = NULL;
  117. cp->c_data_ptr = NULL;
  118. cp->c_data_len = 0;
  119. cp->c_data_offs = 0;
  120. cp->enabled = 0;
  121. cp->stream_running = 0;
  122. cp->spigot_open = 0;
  123. if (cp->sync_state) {
  124. pvr2_trace(PVR2_TRACE_DATA_FLOW,
  125. "/*---TRACE_READ---*/ sync_state <== 0");
  126. cp->sync_state = 0;
  127. }
  128. }
  129. static int pvr2_ioread_start(struct pvr2_ioread *cp)
  130. {
  131. int stat;
  132. struct pvr2_buffer *bp;
  133. if (cp->enabled) return 0;
  134. if (!(cp->stream)) return 0;
  135. pvr2_trace(PVR2_TRACE_START_STOP,
  136. "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp);
  137. while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != NULL) {
  138. stat = pvr2_buffer_queue(bp);
  139. if (stat < 0) {
  140. pvr2_trace(PVR2_TRACE_DATA_FLOW,
  141. "/*---TRACE_READ---*/ pvr2_ioread_start id=%p error=%d",
  142. cp,stat);
  143. pvr2_ioread_stop(cp);
  144. return stat;
  145. }
  146. }
  147. cp->enabled = !0;
  148. cp->c_buf = NULL;
  149. cp->c_data_ptr = NULL;
  150. cp->c_data_len = 0;
  151. cp->c_data_offs = 0;
  152. cp->stream_running = 0;
  153. if (cp->sync_key_len) {
  154. pvr2_trace(PVR2_TRACE_DATA_FLOW,
  155. "/*---TRACE_READ---*/ sync_state <== 1");
  156. cp->sync_state = 1;
  157. cp->sync_trashed_count = 0;
  158. cp->sync_buf_offs = 0;
  159. }
  160. cp->spigot_open = 0;
  161. return 0;
  162. }
  163. struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *cp)
  164. {
  165. return cp->stream;
  166. }
  167. int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp)
  168. {
  169. int ret;
  170. unsigned int idx;
  171. struct pvr2_buffer *bp;
  172. mutex_lock(&cp->mutex);
  173. do {
  174. if (cp->stream) {
  175. pvr2_trace(PVR2_TRACE_START_STOP,
  176. "/*---TRACE_READ---*/ pvr2_ioread_setup (tear-down) id=%p",
  177. cp);
  178. pvr2_ioread_stop(cp);
  179. pvr2_stream_kill(cp->stream);
  180. if (pvr2_stream_get_buffer_count(cp->stream)) {
  181. pvr2_stream_set_buffer_count(cp->stream,0);
  182. }
  183. cp->stream = NULL;
  184. }
  185. if (sp) {
  186. pvr2_trace(PVR2_TRACE_START_STOP,
  187. "/*---TRACE_READ---*/ pvr2_ioread_setup (setup) id=%p",
  188. cp);
  189. pvr2_stream_kill(sp);
  190. ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT);
  191. if (ret < 0) {
  192. mutex_unlock(&cp->mutex);
  193. return ret;
  194. }
  195. for (idx = 0; idx < BUFFER_COUNT; idx++) {
  196. bp = pvr2_stream_get_buffer(sp,idx);
  197. pvr2_buffer_set_buffer(bp,
  198. cp->buffer_storage[idx],
  199. BUFFER_SIZE);
  200. }
  201. cp->stream = sp;
  202. }
  203. } while (0);
  204. mutex_unlock(&cp->mutex);
  205. return 0;
  206. }
  207. int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl)
  208. {
  209. int ret = 0;
  210. if ((!fl) == (!(cp->enabled))) return ret;
  211. mutex_lock(&cp->mutex);
  212. do {
  213. if (fl) {
  214. ret = pvr2_ioread_start(cp);
  215. } else {
  216. pvr2_ioread_stop(cp);
  217. }
  218. } while (0);
  219. mutex_unlock(&cp->mutex);
  220. return ret;
  221. }
  222. static int pvr2_ioread_get_buffer(struct pvr2_ioread *cp)
  223. {
  224. int stat;
  225. while (cp->c_data_len <= cp->c_data_offs) {
  226. if (cp->c_buf) {
  227. // Flush out current buffer first.
  228. stat = pvr2_buffer_queue(cp->c_buf);
  229. if (stat < 0) {
  230. // Streaming error...
  231. pvr2_trace(PVR2_TRACE_DATA_FLOW,
  232. "/*---TRACE_READ---*/ pvr2_ioread_read id=%p queue_error=%d",
  233. cp,stat);
  234. pvr2_ioread_stop(cp);
  235. return 0;
  236. }
  237. cp->c_buf = NULL;
  238. cp->c_data_ptr = NULL;
  239. cp->c_data_len = 0;
  240. cp->c_data_offs = 0;
  241. }
  242. // Now get a freshly filled buffer.
  243. cp->c_buf = pvr2_stream_get_ready_buffer(cp->stream);
  244. if (!cp->c_buf) break; // Nothing ready; done.
  245. cp->c_data_len = pvr2_buffer_get_count(cp->c_buf);
  246. if (!cp->c_data_len) {
  247. // Nothing transferred. Was there an error?
  248. stat = pvr2_buffer_get_status(cp->c_buf);
  249. if (stat < 0) {
  250. // Streaming error...
  251. pvr2_trace(PVR2_TRACE_DATA_FLOW,
  252. "/*---TRACE_READ---*/ pvr2_ioread_read id=%p buffer_error=%d",
  253. cp,stat);
  254. pvr2_ioread_stop(cp);
  255. // Give up.
  256. return 0;
  257. }
  258. // Start over...
  259. continue;
  260. }
  261. cp->c_data_offs = 0;
  262. cp->c_data_ptr = cp->buffer_storage[
  263. pvr2_buffer_get_id(cp->c_buf)];
  264. }
  265. return !0;
  266. }
  267. static void pvr2_ioread_filter(struct pvr2_ioread *cp)
  268. {
  269. unsigned int idx;
  270. if (!cp->enabled) return;
  271. if (cp->sync_state != 1) return;
  272. // Search the stream for our synchronization key. This is made
  273. // complicated by the fact that in order to be honest with
  274. // ourselves here we must search across buffer boundaries...
  275. mutex_lock(&cp->mutex);
  276. while (1) {
  277. // Ensure we have a buffer
  278. if (!pvr2_ioread_get_buffer(cp)) break;
  279. if (!cp->c_data_len) break;
  280. // Now walk the buffer contents until we match the key or
  281. // run out of buffer data.
  282. for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) {
  283. if (cp->sync_buf_offs >= cp->sync_key_len) break;
  284. if (cp->c_data_ptr[idx] ==
  285. cp->sync_key_ptr[cp->sync_buf_offs]) {
  286. // Found the next key byte
  287. (cp->sync_buf_offs)++;
  288. } else {
  289. // Whoops, mismatched. Start key over...
  290. cp->sync_buf_offs = 0;
  291. }
  292. }
  293. // Consume what we've walked through
  294. cp->c_data_offs += idx;
  295. cp->sync_trashed_count += idx;
  296. // If we've found the key, then update state and get out.
  297. if (cp->sync_buf_offs >= cp->sync_key_len) {
  298. cp->sync_trashed_count -= cp->sync_key_len;
  299. pvr2_trace(PVR2_TRACE_DATA_FLOW,
  300. "/*---TRACE_READ---*/ sync_state <== 2 (skipped %u bytes)",
  301. cp->sync_trashed_count);
  302. cp->sync_state = 2;
  303. cp->sync_buf_offs = 0;
  304. break;
  305. }
  306. if (cp->c_data_offs < cp->c_data_len) {
  307. // Sanity check - should NEVER get here
  308. pvr2_trace(PVR2_TRACE_ERROR_LEGS,
  309. "ERROR: pvr2_ioread filter sync problem len=%u offs=%u",
  310. cp->c_data_len,cp->c_data_offs);
  311. // Get out so we don't get stuck in an infinite
  312. // loop.
  313. break;
  314. }
  315. continue; // (for clarity)
  316. }
  317. mutex_unlock(&cp->mutex);
  318. }
  319. int pvr2_ioread_avail(struct pvr2_ioread *cp)
  320. {
  321. int ret;
  322. if (!(cp->enabled)) {
  323. // Stream is not enabled; so this is an I/O error
  324. return -EIO;
  325. }
  326. if (cp->sync_state == 1) {
  327. pvr2_ioread_filter(cp);
  328. if (cp->sync_state == 1) return -EAGAIN;
  329. }
  330. ret = 0;
  331. if (cp->stream_running) {
  332. if (!pvr2_stream_get_ready_count(cp->stream)) {
  333. // No data available at all right now.
  334. ret = -EAGAIN;
  335. }
  336. } else {
  337. if (pvr2_stream_get_ready_count(cp->stream) < BUFFER_COUNT/2) {
  338. // Haven't buffered up enough yet; try again later
  339. ret = -EAGAIN;
  340. }
  341. }
  342. if ((!(cp->spigot_open)) != (!(ret == 0))) {
  343. cp->spigot_open = (ret == 0);
  344. pvr2_trace(PVR2_TRACE_DATA_FLOW,
  345. "/*---TRACE_READ---*/ data is %s",
  346. cp->spigot_open ? "available" : "pending");
  347. }
  348. return ret;
  349. }
  350. int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt)
  351. {
  352. unsigned int copied_cnt;
  353. unsigned int bcnt;
  354. const char *src;
  355. int stat;
  356. int ret = 0;
  357. unsigned int req_cnt = cnt;
  358. if (!cnt) {
  359. pvr2_trace(PVR2_TRACE_TRAP,
  360. "/*---TRACE_READ---*/ pvr2_ioread_read id=%p ZERO Request? Returning zero.",
  361. cp);
  362. return 0;
  363. }
  364. stat = pvr2_ioread_avail(cp);
  365. if (stat < 0) return stat;
  366. cp->stream_running = !0;
  367. mutex_lock(&cp->mutex);
  368. do {
  369. // Suck data out of the buffers and copy to the user
  370. copied_cnt = 0;
  371. if (!buf) cnt = 0;
  372. while (1) {
  373. if (!pvr2_ioread_get_buffer(cp)) {
  374. ret = -EIO;
  375. break;
  376. }
  377. if (!cnt) break;
  378. if (cp->sync_state == 2) {
  379. // We're repeating the sync key data into
  380. // the stream.
  381. src = cp->sync_key_ptr + cp->sync_buf_offs;
  382. bcnt = cp->sync_key_len - cp->sync_buf_offs;
  383. } else {
  384. // Normal buffer copy
  385. src = cp->c_data_ptr + cp->c_data_offs;
  386. bcnt = cp->c_data_len - cp->c_data_offs;
  387. }
  388. if (!bcnt) break;
  389. // Don't run past user's buffer
  390. if (bcnt > cnt) bcnt = cnt;
  391. if (copy_to_user(buf,src,bcnt)) {
  392. // User supplied a bad pointer?
  393. // Give up - this *will* cause data
  394. // to be lost.
  395. ret = -EFAULT;
  396. break;
  397. }
  398. cnt -= bcnt;
  399. buf += bcnt;
  400. copied_cnt += bcnt;
  401. if (cp->sync_state == 2) {
  402. // Update offset inside sync key that we're
  403. // repeating back out.
  404. cp->sync_buf_offs += bcnt;
  405. if (cp->sync_buf_offs >= cp->sync_key_len) {
  406. // Consumed entire key; switch mode
  407. // to normal.
  408. pvr2_trace(PVR2_TRACE_DATA_FLOW,
  409. "/*---TRACE_READ---*/ sync_state <== 0");
  410. cp->sync_state = 0;
  411. }
  412. } else {
  413. // Update buffer offset.
  414. cp->c_data_offs += bcnt;
  415. }
  416. }
  417. } while (0);
  418. mutex_unlock(&cp->mutex);
  419. if (!ret) {
  420. if (copied_cnt) {
  421. // If anything was copied, return that count
  422. ret = copied_cnt;
  423. } else {
  424. // Nothing copied; suggest to caller that another
  425. // attempt should be tried again later
  426. ret = -EAGAIN;
  427. }
  428. }
  429. pvr2_trace(PVR2_TRACE_DATA_FLOW,
  430. "/*---TRACE_READ---*/ pvr2_ioread_read id=%p request=%d result=%d",
  431. cp,req_cnt,ret);
  432. return ret;
  433. }