PS2SDK
PS2 Homebrew Libraries
dvr.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 2021-2021, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
11 #include <stdbool.h>
12 #include "iomanX.h"
13 #include "loadcore.h"
14 #include "pvrdrv.h"
15 #include "stdio.h"
16 #include "sysclib.h"
17 #include "thbase.h"
18 #include "thsemap.h"
19 #include "speedregs.h"
20 #include "errno.h"
21 
22 #define MODNAME "DVR"
23 #ifdef DEBUG
24 #define DPRINTF(x...) printf(MODNAME ": " x)
25 #else
26 #define DPRINTF(x...)
27 #endif
28 
29 extern int module_start(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi);
30 extern int module_stop(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi);
31 extern int dvr_df_init(iomanX_iop_device_t *dev);
32 extern int dvr_df_exit(iomanX_iop_device_t *dev);
33 extern int dvr_df_ioctl(iomanX_iop_file_t *f, int cmd, void *param);
34 extern int dvr_df_devctl(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
35 extern int dvr_df_ioctl2(iomanX_iop_file_t *f, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
36 extern int dvrioctl2_rec_start(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
37 extern int dvrioctl2_rec_pause(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
38 extern int dvrioctl2_rec_stop(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
39 extern int dvrioctl2_set_rec_end_time(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
40 extern int dvrioctl2_get_rec_info(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
41 extern int dvrioctl2_get_rec_time(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
42 extern int dvrioctl2_read_resfile(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
43 extern int dvrioctl2_clear_resfile_flag(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
44 extern int dvrioctl2_rec_prohibit(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
45 extern int dvrioctl2_get_status_register(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
46 extern int dvrioctl2_get_ifo_time_entry(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
47 extern int dvrioctl2_get_ifo_vobu_entry(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
48 extern int dvrioctl2_epg_test(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
49 extern int dvrioctl2_send_timer_event(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
50 extern int dvrioctl2_epg_cancel(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
51 extern int dvrioctl2_tevent_buf_clr(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
52 extern int dvrioctl2_tevent_buf_send(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
53 extern int dvrioctl2_tevent_buf_trans_dvrp(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
54 extern int dvrioctl2_start_hdd_test(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
55 extern int dvrioctl2_stop_hdd_test(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
56 extern int dvrioctl2_get_hdd_test_stat(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
57 extern int dvrioctl2_pre_update_a(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
58 extern int dvrioctl2_pre_update_b(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
59 extern int dvrioctl2_get_rec_vro_pckn(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
60 extern int dvrioctl2_enc_dec_test(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
61 extern int dvrioctl2_tevent_buf_recv_first(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
62 extern int dvrioctl2_tevent_buf_recv_next(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
63 extern int dvrioctl2_finish_auto_process(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
64 extern int dvrioctl2_make_menu(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
65 extern int dvrioctl2_re_enc_start(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
66 extern int dvrioctl2_rec_pictclip(iomanX_iop_file_t *a1, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
67 extern int dvrpAuthEnc(u16 in_word);
68 
69 // The following has been excluded.
70 unsigned char dvrpAuth_tbl[256] = {0x00};
71 
72 struct DevctlCmdTbl_t
73 {
74  u16 cmd;
75  int (*fn)(iomanX_iop_file_t *f, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
76 } DevctlCmdTbl[31] =
77  {
78  {0x5663, &dvrioctl2_get_status_register},
79  {0x5638, &dvrioctl2_get_ifo_time_entry},
80  {0x5639, &dvrioctl2_get_ifo_vobu_entry},
81  {0x5632, &dvrioctl2_rec_start},
82  {0x5633, &dvrioctl2_rec_pause},
83  {0x5634, &dvrioctl2_rec_stop},
84  {0x5635, &dvrioctl2_set_rec_end_time},
85  {0x5636, &dvrioctl2_get_rec_info},
86  {0x5637, &dvrioctl2_get_rec_time},
87  {0x563A, &dvrioctl2_read_resfile},
88  {0x563B, &dvrioctl2_clear_resfile_flag},
89  {0x563F, &dvrioctl2_rec_prohibit},
90  {0x5640, &dvrioctl2_epg_test},
91  {0x5641, &dvrioctl2_send_timer_event},
92  {0x5642, &dvrioctl2_epg_cancel},
93  {0x565A, &dvrioctl2_tevent_buf_clr},
94  {0x565B, &dvrioctl2_tevent_buf_send},
95  {0x565C, &dvrioctl2_tevent_buf_trans_dvrp},
96  {0x5643, &dvrioctl2_start_hdd_test},
97  {0x5644, &dvrioctl2_stop_hdd_test},
98  {0x5645, &dvrioctl2_get_hdd_test_stat},
99  {0x5646, &dvrioctl2_pre_update_a},
100  {0x5647, &dvrioctl2_pre_update_b},
101  {0x5648, &dvrioctl2_get_rec_vro_pckn},
102  {0x5649, &dvrioctl2_enc_dec_test},
103  {0x565D, &dvrioctl2_tevent_buf_recv_first},
104  {0x565E, &dvrioctl2_tevent_buf_recv_next},
105  {0x5651, &dvrioctl2_finish_auto_process},
106  {0x564A, &dvrioctl2_make_menu},
107  {0x564B, &dvrioctl2_re_enc_start},
108  {0x5650, &dvrioctl2_rec_pictclip},
109 };
110 
111 IOMANX_RETURN_VALUE_IMPL(EUNSUP);
112 
113 static iomanX_iop_device_ops_t DvrFuncTbl =
114  {
115  &dvr_df_init, // init
116  &dvr_df_exit, // deinit
117  IOMANX_RETURN_VALUE(EUNSUP), // format
118  IOMANX_RETURN_VALUE(EUNSUP), // open
119  IOMANX_RETURN_VALUE(EUNSUP), // close
120  IOMANX_RETURN_VALUE(EUNSUP), // read
121  IOMANX_RETURN_VALUE(EUNSUP), // write
122  IOMANX_RETURN_VALUE(EUNSUP), // lseek
123  &dvr_df_ioctl, // ioctl
124  IOMANX_RETURN_VALUE(EUNSUP), // remove
125  IOMANX_RETURN_VALUE(EUNSUP), // mkdir
126  IOMANX_RETURN_VALUE(EUNSUP), // rmdir
127  IOMANX_RETURN_VALUE(EUNSUP), // dopen
128  IOMANX_RETURN_VALUE(EUNSUP), // dclose
129  IOMANX_RETURN_VALUE(EUNSUP), // dread
130  IOMANX_RETURN_VALUE(EUNSUP), // getstat
131  IOMANX_RETURN_VALUE(EUNSUP), // chstat
132  IOMANX_RETURN_VALUE(EUNSUP), // rename
133  IOMANX_RETURN_VALUE(EUNSUP), // chdir
134  IOMANX_RETURN_VALUE(EUNSUP), // sync
135  IOMANX_RETURN_VALUE(EUNSUP), // mount
136  IOMANX_RETURN_VALUE(EUNSUP), // umount
137  IOMANX_RETURN_VALUE_S64(EUNSUP), // lseek64
138  &dvr_df_devctl, // devctl
139  IOMANX_RETURN_VALUE(EUNSUP), // symlink
140  IOMANX_RETURN_VALUE(EUNSUP), // readlink
141  &dvr_df_ioctl2, // ioctl2
142  };
143 char TEVENT_BUF[6144];
144 char *tevent_p;
145 int tevent_data_sz;
146 static iomanX_iop_device_t DVR = {
147  .name = "dvr",
148  .desc = "Digital Video Recorder DVR task",
149  .type = (IOP_DT_FS | IOP_DT_FSEXT),
150  .ops = &DvrFuncTbl,
151 };
152 s32 sema_id;
153 
154 // Based off of DESR / PSX DVR system software version 1.31.
155 // Added additional functions from DESR / PSX DVR system software version 2.11.
156 IRX_ID(MODNAME, 1, 1);
157 
158 int _start(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi)
159 {
160  if (argc >= 0)
161  return module_start(argc, argv, startaddr, mi);
162  else
163  return module_stop(argc, argv, startaddr, mi);
164 }
165 
166 int module_start(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi)
167 {
168  int i;
169 
170  (void)argc;
171  (void)argv;
172  (void)startaddr;
173 
174  for (i = 0; i < 30000; ++i) {
175  if (((*((vu32 *)0xB0004230)) & 0x10) != 0)
176  break;
177  DelayThread(1000);
178  }
179  if (i == 30000) {
180  DPRINTF("DVR task of DVRP is not running...\n");
181  return MODULE_NO_RESIDENT_END;
182  } else {
183  if (iomanX_AddDrv(&DVR) != 0)
184  return MODULE_NO_RESIDENT_END;
185  }
186 #if 0
187  return MODULE_REMOVABLE_END;
188 #else
189  if (mi && ((mi->newflags & 2) != 0))
190  mi->newflags |= 0x10;
191  return MODULE_RESIDENT_END;
192 #endif
193 }
194 
195 int module_stop(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi)
196 {
197  (void)argc;
198  (void)argv;
199  (void)startaddr;
200  (void)mi;
201 
202  if (iomanX_DelDrv(DVR.name) != 0)
203  return MODULE_REMOVABLE_END;
204  return MODULE_NO_RESIDENT_END;
205 }
206 
207 int dvr_df_init(iomanX_iop_device_t *dev)
208 {
209  int v1;
210  iop_sema_t v3;
211 
212  (void)dev;
213 
214  v3.attr = 0;
215  v3.initial = 1;
216  v3.max = 1;
217  v3.option = 0;
218  v1 = CreateSema(&v3);
219  if (v1 < 0)
220  return -1;
221  sema_id = v1;
222  return 0;
223 }
224 
225 int dvr_df_exit(iomanX_iop_device_t *dev)
226 {
227  (void)dev;
228 
229  if (DeleteSema(sema_id) != 0)
230  return -1;
231  return 0;
232 }
233 
234 int dvr_df_ioctl(iomanX_iop_file_t *f, int cmd, void *param)
235 {
236  (void)f;
237  (void)cmd;
238  (void)param;
239 
240  WaitSema(sema_id);
241  SignalSema(sema_id);
242  return -EINVAL;
243 }
244 
245 int dvr_df_devctl(
246  iomanX_iop_file_t *a1,
247  const char *name,
248  int cmd,
249  void *arg,
250  unsigned int arglen,
251  void *buf,
252  unsigned int buflen)
253 {
254  int v11;
255  unsigned int v12;
256  unsigned int v13;
257 
258  v11 = 0;
259  v12 = 0;
260  WaitSema(sema_id);
261  v13 = 0;
262  while (DevctlCmdTbl[v13].cmd != cmd) {
263  v13 = ++v12;
264  if (v12 >= sizeof(DevctlCmdTbl) / sizeof(DevctlCmdTbl[0]))
265  goto LABEL_5;
266  }
267  v11 = DevctlCmdTbl[v13].fn(a1, name, cmd, arg, arglen, buf, buflen);
268 LABEL_5:
269  if (v12 == sizeof(DevctlCmdTbl) / sizeof(DevctlCmdTbl[0]))
270  v11 = -EINVAL;
271  SignalSema(sema_id);
272  return v11;
273 }
274 
275 int dvr_df_ioctl2(iomanX_iop_file_t *f, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
276 {
277  (void)f;
278  (void)cmd;
279  (void)arg;
280  (void)arglen;
281  (void)buf;
282  (void)buflen;
283 
284  WaitSema(sema_id);
285  SignalSema(sema_id);
286  return -EINVAL;
287 }
288 
289 int dvrioctl2_rec_start(
290  iomanX_iop_file_t *a1,
291  const char *name,
292  int cmd,
293  void *arg,
294  unsigned int arglen,
295  void *buf,
296  unsigned int buflen)
297 {
298  int busywait;
299  int cmdackerr;
300 #ifdef DEBUG
301  int err;
302 #endif
303  drvdrv_exec_cmd_ack cmdack;
304 
305  (void)a1;
306  (void)name;
307  (void)cmd;
308  (void)arglen;
309  (void)buf;
310  (void)buflen;
311 
312  cmdack.command = 0x2101;
313  cmdack.input_word[0] = *((u16 *)arg + 1);
314  cmdack.input_word[1] = *(u16 *)arg;
315  cmdack.input_word[2] = *((u16 *)arg + 3);
316  cmdack.input_word[3] = *((u16 *)arg + 2);
317  cmdack.input_word[4] = *((u16 *)arg + 4);
318  cmdack.input_word[5] = *((u16 *)arg + 5);
319  cmdack.input_word[6] = *((u16 *)arg + 6);
320  busywait = 0x4;
321  while (busywait-- >= 0)
322  ;
323  cmdack.input_word_count = 7;
324  cmdack.timeout = 5000000;
325  cmdackerr = DvrdrvExecCmdAckComp(&cmdack);
326  if (cmdackerr) {
327  DPRINTF("dvrioctl2_rec_start -> Handshake error!,%d\n", cmdackerr);
328  return -EIO;
329  }
330 #ifdef DEBUG
331  err = cmdack.ack_status_ack;
332 #endif
333  if (!cmdack.ack_status_ack) {
334  if (!cmdack.comp_status)
335  return 0;
336 #ifdef DEBUG
337  err = cmdack.comp_status;
338 #endif
339  }
340  DPRINTF("dvrioctl2_rec_start -> Status error!,%04X\n", err);
341  return -EADV;
342 }
343 
344 int dvrioctl2_rec_pause(
345  iomanX_iop_file_t *a1,
346  const char *name,
347  int cmd,
348  void *arg,
349  unsigned int arglen,
350  void *buf,
351  unsigned int buflen)
352 {
353  int v7;
354  drvdrv_exec_cmd_ack *p_cmdack;
355  int cmdackerr;
356  drvdrv_exec_cmd_ack cmdack;
357 
358  (void)a1;
359  (void)name;
360  (void)cmd;
361  (void)arglen;
362  (void)buf;
363  (void)buflen;
364 
365  v7 = 0;
366  p_cmdack = &cmdack;
367  cmdack.command = 0x2102;
368  do {
369  ++v7;
370  p_cmdack->input_word[0] = *(u16 *)arg;
371  arg = (char *)arg + 2;
372  p_cmdack = (drvdrv_exec_cmd_ack *)((char *)p_cmdack + 2);
373  } while (v7 <= 0);
374  cmdack.input_word_count = 1;
375  cmdackerr = DvrdrvExecCmdAck(&cmdack);
376  if (cmdackerr) {
377  DPRINTF("dvrioctl2_rec_pause -> Handshake error!,%d\n", cmdackerr);
378  return -EIO;
379  } else {
380  if (cmdack.ack_status_ack) {
381  DPRINTF("dvrioctl2_rec_pause -> Status error!,%04X\n", cmdack.ack_status_ack);
382  return -EADV;
383  }
384  }
385  return 0;
386 }
387 
388 int dvrioctl2_rec_stop(
389  iomanX_iop_file_t *a1,
390  const char *name,
391  int cmd,
392  void *arg,
393  unsigned int arglen,
394  void *buf,
395  unsigned int buflen)
396 {
397  int cmdackerr;
398  drvdrv_exec_cmd_ack cmdack;
399 
400  (void)a1;
401  (void)name;
402  (void)cmd;
403  (void)arg;
404  (void)arglen;
405  (void)buf;
406  (void)buflen;
407 
408  cmdack.command = 0x2103;
409  cmdack.input_word_count = 0;
410  cmdack.timeout = 5000000;
411  cmdackerr = DvrdrvExecCmdAckComp(&cmdack);
412  if (cmdackerr) {
413  DPRINTF("dvrioctl2_rec_stop -> Handshake error!,%d\n", cmdackerr);
414  return -EIO;
415  }
416  if (cmdack.ack_status_ack) {
417  DPRINTF("dvrioctl2_rec_stop -> Status error!,%04X\n", cmdack.ack_status_ack);
418  } else {
419  if (!cmdack.comp_status)
420  return 0;
421  DPRINTF("dvrioctl2_rec_start -> Status error!,%04X\n", cmdack.comp_status);
422  }
423  return -EADV;
424 }
425 
426 int dvrioctl2_set_rec_end_time(
427  iomanX_iop_file_t *a1,
428  const char *name,
429  int cmd,
430  void *arg,
431  unsigned int arglen,
432  void *buf,
433  unsigned int buflen)
434 {
435  int cmdackerr;
436  drvdrv_exec_cmd_ack cmdack;
437 
438  (void)a1;
439  (void)name;
440  (void)cmd;
441  (void)arglen;
442  (void)buf;
443  (void)buflen;
444 
445  cmdack.command = 0x2104;
446  cmdack.input_word[0] = (*(u32 *)arg) >> 16;
447  cmdack.input_word_count = 2;
448  cmdack.input_word[1] = *(u16 *)arg;
449  cmdackerr = DvrdrvExecCmdAck(&cmdack);
450  if (cmdackerr) {
451  DPRINTF("dvrioctl2_rec_end_time -> Handshake error!,%d\n", cmdackerr);
452  return -EIO;
453  } else {
454  if (cmdack.ack_status_ack) {
455  DPRINTF("dvrioctl2_rec_end_time -> Status error!,%04X\n", cmdack.ack_status_ack);
456  return -EADV;
457  }
458  }
459  return 0;
460 }
461 
462 int dvrioctl2_get_rec_info(
463  iomanX_iop_file_t *a1,
464  const char *name,
465  int cmd,
466  void *arg,
467  unsigned int arglen,
468  void *buf,
469  unsigned int buflen)
470 {
471  (void)a1;
472  (void)name;
473  (void)cmd;
474  (void)arg;
475  (void)arglen;
476 
477  if (buflen >= 0x15) {
478  int cmdackerr;
479  drvdrv_exec_cmd_ack cmdack;
480  cmdack.command = 0x2105;
481  cmdack.input_word_count = 0;
482  cmdackerr = DvrdrvExecCmdAck(&cmdack);
483  if (cmdackerr) {
484  DPRINTF("dvrioctl2_get_rec_info -> Handshake error!,%d\n", cmdackerr);
485  return -EIO;
486  } else {
487  int v9;
488  v9 = 0;
489  if (cmdack.ack_status_ack) {
490  DPRINTF("dvrioctl2_get_rec_info -> Status error!,%04X\n", cmdack.ack_status_ack);
491  return -EADV;
492  } else {
493  int v10;
494  *(u16 *)buf = 0;
495  v10 = 0;
496  do {
497  u16 *v11;
498  v9 += 1;
499  v11 = &cmdack.output_word[v9];
500  *((u8 *)buf + v10 + 3) = (*v11 & 0xFF00) >> 8;
501  *((u8 *)buf + v10 + 2) = (*v11 & 0x00FF);
502  v10 = 2 * v9;
503  } while (v9 < 10);
504  *((u8 *)buf + 22) = 0;
505  return 0;
506  }
507  }
508  } else {
509  DPRINTF("dvrioctl2_get_rec_info -> buflen is smaller than 21.\n");
510  return -EINVAL;
511  }
512 }
513 
514 int dvrioctl2_get_rec_time(
515  iomanX_iop_file_t *a1,
516  const char *name,
517  int cmd,
518  void *arg,
519  unsigned int arglen,
520  void *buf,
521  unsigned int buflen)
522 {
523  int cmdackerr;
524  drvdrv_exec_cmd_ack cmdack;
525 
526  (void)a1;
527  (void)name;
528  (void)cmd;
529  (void)arg;
530  (void)arglen;
531  (void)buflen;
532 
533  cmdack.command = 0x2106;
534  cmdack.input_word_count = 0;
535  cmdackerr = DvrdrvExecCmdAck(&cmdack);
536  if (cmdackerr) {
537  DPRINTF("dvrioctl2_get_rec_time -> Handshake error!,%d\n", cmdackerr);
538  return -EIO;
539  } else {
540  if (cmdack.ack_status_ack) {
541  DPRINTF("dvrioctl2_get_rec_time -> Status error!,%04X\n", cmdack.ack_status_ack);
542  return -EADV;
543  } else {
544  *(u16 *)buf = 0;
545  *((u32 *)buf + 1) = (cmdack.output_word[0] << 16) + cmdack.output_word[1];
546  }
547  }
548  return 0;
549 }
550 
551 int dvrioctl2_get_ifo_time_entry(
552  iomanX_iop_file_t *a1,
553  const char *name,
554  int cmd,
555  void *arg,
556  unsigned int arglen,
557  void *buf,
558  unsigned int buflen)
559 {
560  int cmdackerr;
561  drvdrv_exec_cmd_ack cmdack;
562 
563  (void)a1;
564  (void)name;
565  (void)cmd;
566  (void)arg;
567  (void)arglen;
568  (void)buflen;
569 
570  cmdack.command = 0x2107;
571  cmdack.input_word_count = 0;
572  cmdackerr = DvrdrvExecCmdAck(&cmdack);
573  if (cmdackerr) {
574  DPRINTF("dvrioctl2_get_ifo_time_entry -> Handshake error!,%d\n", cmdackerr);
575  return -EIO;
576  } else if (cmdack.ack_status_ack) {
577  DPRINTF("dvrioctl2_get_ifo_time_entry -> Status error!,%04X\n", cmdack.ack_status_ack);
578  return -EADV;
579  } else {
580  *(u16 *)buf = 0;
581  *((u16 *)buf + 1) = cmdack.output_word[0];
582  *((u16 *)buf + 2) = cmdack.output_word[1];
583  *((u16 *)buf + 3) = cmdack.output_word[2];
584  *((u32 *)buf + 2) = (cmdack.output_word[3] << 16) + cmdack.output_word[4];
585  }
586  return 0;
587 }
588 
589 int dvrioctl2_get_ifo_vobu_entry(
590  iomanX_iop_file_t *a1,
591  const char *name,
592  int cmd,
593  void *arg,
594  unsigned int arglen,
595  void *buf,
596  unsigned int buflen)
597 {
598  int cmdackerr;
599  drvdrv_exec_cmd_ack cmdack;
600 
601  (void)a1;
602  (void)name;
603  (void)cmd;
604  (void)arg;
605  (void)arglen;
606  (void)buflen;
607 
608  cmdack.command = 0x2108;
609  cmdack.input_word_count = 0;
610  cmdackerr = DvrdrvExecCmdAck(&cmdack);
611  if (cmdackerr) {
612  DPRINTF("dvrioctl2_get_ifo_vobu_entry -> Handshake error!,%d\n", cmdackerr);
613  return -EIO;
614  } else if (cmdack.ack_status_ack) {
615  DPRINTF("dvrioctl2_get_ifo_vobu_entry -> Status error!,%04X\n", cmdack.ack_status_ack);
616  return -EADV;
617  } else {
618  *(u16 *)buf = 0;
619  *((u16 *)buf + 1) = cmdack.output_word[0];
620  *((u16 *)buf + 2) = cmdack.output_word[1];
621  *((u16 *)buf + 3) = cmdack.output_word[2];
622  }
623  return 0;
624 }
625 
626 int dvrioctl2_read_resfile(
627  iomanX_iop_file_t *a1,
628  const char *name,
629  int cmd,
630  void *arg,
631  unsigned int arglen,
632  void *buf,
633  unsigned int buflen)
634 {
635  int cmdackerr;
636  drvdrv_exec_cmd_ack cmdack;
637 
638  (void)a1;
639  (void)name;
640  (void)cmd;
641  (void)arg;
642  (void)arglen;
643  (void)buf;
644  (void)buflen;
645 
646  cmdack.command = 0x2109;
647  cmdack.input_word_count = 0;
648  cmdackerr = DvrdrvExecCmdAck(&cmdack);
649  if (cmdackerr) {
650  DPRINTF("dvrioctl2_read_resfile -> Handshake error!,%d\n", cmdackerr);
651  return -EIO;
652  } else {
653  if (cmdack.ack_status_ack) {
654  DPRINTF("dvrioctl2_read_resfile -> Status error!,%04X\n", cmdack.ack_status_ack);
655  return -EADV;
656  }
657  }
658  return 0;
659 }
660 
661 int dvrioctl2_clear_resfile_flag(
662  iomanX_iop_file_t *a1,
663  const char *name,
664  int cmd,
665  void *arg,
666  unsigned int arglen,
667  void *buf,
668  unsigned int buflen)
669 {
670  int cmdackerr;
671  drvdrv_exec_cmd_ack cmdack;
672 
673  (void)a1;
674  (void)name;
675  (void)cmd;
676  (void)arg;
677  (void)arglen;
678  (void)buf;
679  (void)buflen;
680 
681  cmdack.command = 0x210A;
682  cmdack.input_word_count = 0;
683  cmdackerr = DvrdrvExecCmdAck(&cmdack);
684  if (cmdackerr) {
685  DPRINTF("dvrioctl2_clear_resfile_flag -> Handshake error!,%d\n", cmdackerr);
686  return -EIO;
687  } else {
688  if (cmdack.ack_status_ack) {
689  DPRINTF("dvrioctl2_clear_resfile_flag -> Status error!,%04X\n", cmdack.ack_status_ack);
690  return -EADV;
691  }
692  }
693  return 0;
694 }
695 
696 int dvrioctl2_rec_prohibit(
697  iomanX_iop_file_t *a1,
698  const char *name,
699  int cmd,
700  void *arg,
701  unsigned int arglen,
702  void *buf,
703  unsigned int buflen)
704 {
705  int cmdackerr;
706  drvdrv_exec_cmd_ack cmdack;
707 
708  (void)a1;
709  (void)name;
710  (void)cmd;
711  (void)arglen;
712  (void)buf;
713  (void)buflen;
714 
715  cmdack.command = 0x210E;
716  cmdack.input_word_count = 1;
717  cmdack.input_word[0] = *(u16 *)arg;
718  cmdackerr = DvrdrvExecCmdAck(&cmdack);
719  if (cmdackerr) {
720  DPRINTF("dvrioctl2_rec_prohibit -> Handshake error!,%d\n", cmdackerr);
721  return -EIO;
722  } else {
723  if (cmdack.ack_status_ack) {
724  DPRINTF("dvrioctl2_rec_prohibit -> Status error!,%04X\n", cmdack.ack_status_ack);
725  return -EADV;
726  }
727  }
728  return 0;
729 }
730 
731 int dvrioctl2_epg_test(
732  iomanX_iop_file_t *a1,
733  const char *name,
734  int cmd,
735  void *arg,
736  unsigned int arglen,
737  void *buf,
738  unsigned int buflen)
739 {
740  int cmdackerr;
741  drvdrv_exec_cmd_ack cmdack;
742 
743  (void)a1;
744  (void)name;
745  (void)cmd;
746  (void)arglen;
747  (void)buf;
748  (void)buflen;
749 
750  cmdack.command = 0x210F;
751  cmdack.input_word_count = 1;
752  cmdack.input_word[0] = *(u16 *)arg;
753  cmdackerr = DvrdrvExecCmdAck(&cmdack);
754  if (cmdackerr) {
755  DPRINTF("dvrioctl2_epg_test -> Handshake error!,%d\n", cmdackerr);
756  return -EIO;
757  } else {
758  if (cmdack.ack_status_ack) {
759  DPRINTF("dvrioctl2_epg_test -> Status error!,%04X\n", cmdack.ack_status_ack);
760  return -EADV;
761  }
762  }
763  return 0;
764 }
765 
766 int dvrioctl2_send_timer_event(
767  iomanX_iop_file_t *a1,
768  const char *name,
769  int cmd,
770  void *arg,
771  unsigned int arglen,
772  void *buf,
773  unsigned int buflen)
774 {
775  drvdrv_exec_cmd_ack cmdack;
776 
777  (void)a1;
778  (void)name;
779  (void)cmd;
780  (void)buf;
781  (void)buflen;
782 
783  cmdack.command = 0x2110;
784  cmdack.input_word_count = 0;
785  cmdack.input_buffer = arg;
786  cmdack.timeout = 10000000;
787  cmdack.input_buffer_length = arglen;
788  if (DvrdrvExecCmdAckDmaSendComp(&cmdack)) {
789  DPRINTF("dvrioctl2_send_timer_event -> IO error (phase %d)\n", cmdack.phase);
790  return -EIO;
791  } else {
792  if (cmdack.comp_status) {
793  DPRINTF(
794  "dvrioctl2_send_timer_event -> Complete parameter (%04X) error (phase %d)\n",
795  cmdack.comp_status,
796  cmdack.phase);
797  return -EIO;
798  }
799  }
800  return 0;
801 }
802 
803 int dvrioctl2_epg_cancel(
804  iomanX_iop_file_t *a1,
805  const char *name,
806  int cmd,
807  void *arg,
808  unsigned int arglen,
809  void *buf,
810  unsigned int buflen)
811 {
812  int cmdackerr;
813  drvdrv_exec_cmd_ack cmdack;
814 
815  (void)a1;
816  (void)name;
817  (void)cmd;
818  (void)arglen;
819  (void)buf;
820  (void)buflen;
821 
822  cmdack.command = 0x2111;
823  cmdack.input_word_count = 0;
824  cmdack.input_word[0] = *(u16 *)arg;
825  cmdackerr = DvrdrvExecCmdAck(&cmdack);
826  if (cmdackerr) {
827  DPRINTF("dvrioctl2_epg_cancel -> Handshake error!,%d\n", cmdackerr);
828  return -EIO;
829  } else {
830  if (cmdack.ack_status_ack) {
831  DPRINTF("dvrioctl2_epg_cancel -> Status error!,%04X\n", cmdack.ack_status_ack);
832  return -EADV;
833  }
834  }
835  return 0;
836 }
837 
838 int dvrioctl2_get_status_register(
839  iomanX_iop_file_t *a1,
840  const char *name,
841  int cmd,
842  void *arg,
843  unsigned int arglen,
844  void *buf,
845  unsigned int buflen)
846 {
847  (void)a1;
848  (void)name;
849  (void)cmd;
850  (void)arg;
851  (void)arglen;
852  (void)buflen;
853 
854  *(u16 *)buf = (*((vu32 *)0xB0004230));
855  *((u16 *)buf + 1) = (*((vu32 *)0xB0004234));
856  *((u16 *)buf + 2) = (*((vu32 *)0xB0004238));
857  *((u16 *)buf + 3) = (*((vu32 *)0xB000423C));
858  return 0;
859 }
860 
861 int dvrioctl2_tevent_buf_clr(
862  iomanX_iop_file_t *a1,
863  const char *name,
864  int cmd,
865  void *arg,
866  unsigned int arglen,
867  void *buf,
868  unsigned int buflen)
869 {
870  int v7;
871  char *v8;
872 
873  (void)a1;
874  (void)name;
875  (void)cmd;
876  (void)arg;
877  (void)arglen;
878  (void)buf;
879  (void)buflen;
880 
881  v7 = 6143;
882  v8 = &TEVENT_BUF[6143];
883  do {
884  *v8 = 0;
885  --v7;
886  --v8;
887  } while (v7 >= 0);
888  tevent_p = TEVENT_BUF;
889  tevent_data_sz = 0;
890  return 0;
891 }
892 
893 int dvrioctl2_tevent_buf_send(
894  iomanX_iop_file_t *a1,
895  const char *name,
896  int cmd,
897  void *arg,
898  unsigned int arglen,
899  void *buf,
900  unsigned int buflen)
901 {
902  (void)a1;
903  (void)name;
904  (void)cmd;
905  (void)buf;
906  (void)buflen;
907 
908  if ((int)(tevent_data_sz + arglen) < 0x1801) {
909  signed int i;
910  for (i = 0; i < (int)arglen; arg = (char *)arg + 1) {
911  ++i;
912  *tevent_p = *(u8 *)arg;
913  tevent_p += 1;
914  }
915  tevent_data_sz += arglen;
916  }
917  return 0;
918 }
919 
920 int dvrioctl2_tevent_buf_trans_dvrp(
921  iomanX_iop_file_t *a1,
922  const char *name,
923  int cmd,
924  void *arg,
925  unsigned int arglen,
926  void *buf,
927  unsigned int buflen)
928 {
929  drvdrv_exec_cmd_ack cmdack;
930 
931  (void)a1;
932  (void)name;
933  (void)cmd;
934  (void)arg;
935  (void)arglen;
936  (void)buf;
937  (void)buflen;
938 
939  cmdack.command = 0x2110;
940  cmdack.input_word_count = 0;
941  cmdack.input_buffer = TEVENT_BUF;
942  cmdack.timeout = 10000000;
943  cmdack.input_buffer_length = tevent_data_sz;
944  if (DvrdrvExecCmdAckDmaSendComp(&cmdack)) {
945  DPRINTF("dvrioctl2_tevent_buf_trans_dvrp -> IO error (phase %d)\n", cmdack.phase);
946  return -EIO;
947  } else {
948  if (cmdack.comp_status) {
949  DPRINTF(
950  "dvrioctl2_tevent_buf_trans_dvrp -> Complete parameter (%04X) error (phase %d)\n",
951  cmdack.comp_status,
952  cmdack.phase);
953  return -EIO;
954  }
955  }
956  return 0;
957 }
958 
959 int dvrioctl2_start_hdd_test(
960  iomanX_iop_file_t *a1,
961  const char *name,
962  int cmd,
963  void *arg,
964  unsigned int arglen,
965  void *buf,
966  unsigned int buflen)
967 {
968  int cmdackerr;
969 #ifdef DEBUG
970  int ack_status_ack;
971 #endif
972  drvdrv_exec_cmd_ack cmdack;
973 
974  (void)a1;
975  (void)name;
976  (void)cmd;
977  (void)arglen;
978  (void)buf;
979  (void)buflen;
980 
981  cmdack.command = 0x2112;
982  cmdack.input_word[0] = *(u16 *)arg;
983  cmdack.input_word[1] = *((u16 *)arg + 3);
984  cmdack.input_word[2] = *((u16 *)arg + 2);
985  cmdack.input_word[3] = *((u16 *)arg + 5);
986  cmdack.input_word[4] = *((u16 *)arg + 4);
987  cmdack.input_word[5] = *((u16 *)arg + 6);
988  cmdack.input_word[6] = *((u16 *)arg + 7);
989  cmdack.input_word[7] = *((u16 *)arg + 8);
990  cmdack.input_word_count = 8;
991  cmdack.timeout = 1000000 * (*((u16 *)arg + 8) + 30);
992  cmdackerr = DvrdrvExecCmdAckComp(&cmdack);
993  if (cmdackerr) {
994  DPRINTF("dvrioctl2_start_hdd_test -> Handshake error!,%d\n", cmdackerr);
995  return -EIO;
996  }
997 #ifdef DEBUG
998  ack_status_ack = cmdack.ack_status_ack;
999 #endif
1000  if (!cmdack.ack_status_ack) {
1001  if (!cmdack.comp_status)
1002  return 0;
1003 #ifdef DEBUG
1004  ack_status_ack = cmdack.comp_status;
1005 #endif
1006  }
1007  DPRINTF("dvrioctl2_start_hdd_test -> Status error!,%04X\n", ack_status_ack);
1008  return -EADV;
1009 }
1010 
1011 int dvrioctl2_stop_hdd_test(
1012  iomanX_iop_file_t *a1,
1013  const char *name,
1014  int cmd,
1015  void *arg,
1016  unsigned int arglen,
1017  void *buf,
1018  unsigned int buflen)
1019 {
1020  int cmdackerr;
1021 #ifdef DEBUG
1022  int ack_status_ack;
1023 #endif
1024  drvdrv_exec_cmd_ack cmdack;
1025 
1026  (void)a1;
1027  (void)name;
1028  (void)cmd;
1029  (void)arg;
1030  (void)arglen;
1031  (void)buf;
1032  (void)buflen;
1033 
1034  cmdack.command = 0x2113;
1035  cmdack.input_word_count = 0;
1036  cmdack.timeout = 30000000;
1037  cmdackerr = DvrdrvExecCmdAckComp(&cmdack);
1038  if (cmdackerr) {
1039  DPRINTF("dvrioctl2_stop_hdd_test -> Handshake error!,%d\n", cmdackerr);
1040  return -EIO;
1041  }
1042 #ifdef DEBUG
1043  ack_status_ack = cmdack.ack_status_ack;
1044 #endif
1045  if (!cmdack.ack_status_ack) {
1046  if (!cmdack.comp_status)
1047  return 0;
1048 #ifdef DEBUG
1049  ack_status_ack = cmdack.comp_status;
1050 #endif
1051  }
1052 #ifdef DEBUG
1053  DPRINTF("dvrioctl2_stop_hdd_test -> Status error!,%04X\n", ack_status_ack);
1054 #endif
1055  return -EADV;
1056 }
1057 
1058 int dvrioctl2_get_hdd_test_stat(
1059  iomanX_iop_file_t *a1,
1060  const char *name,
1061  int cmd,
1062  void *arg,
1063  unsigned int arglen,
1064  void *buf,
1065  unsigned int buflen)
1066 {
1067  int cmdackerr;
1068  drvdrv_exec_cmd_ack cmdack;
1069 
1070  (void)a1;
1071  (void)name;
1072  (void)cmd;
1073  (void)arg;
1074  (void)arglen;
1075  (void)buflen;
1076 
1077  cmdack.command = 0x2114;
1078  cmdack.input_word_count = 0;
1079  cmdackerr = DvrdrvExecCmdAck(&cmdack);
1080  if (cmdackerr) {
1081  DPRINTF("dvrioctl2_get_hdd_test_stat -> Handshake error!,%d\n", cmdackerr);
1082  return -EIO;
1083  } else if (cmdack.ack_status_ack) {
1084  DPRINTF("dvrioctl2_get_hdd_test_stat -> Status error!,%04X\n", cmdack.ack_status_ack);
1085  return -EADV;
1086  } else {
1087  *(u16 *)buf = cmdack.output_word[0];
1088  *((u32 *)buf + 1) = (cmdack.output_word[1] << 16) + cmdack.output_word[2];
1089  *((u32 *)buf + 2) = (cmdack.output_word[3] << 16) + cmdack.output_word[4];
1090  *((u16 *)buf + 6) = cmdack.output_word[5];
1091  *((u16 *)buf + 7) = cmdack.output_word[6];
1092  *((u16 *)buf + 8) = cmdack.output_word[7];
1093  }
1094  return 0;
1095 }
1096 
1097 int dvrioctl2_pre_update_a(
1098  iomanX_iop_file_t *a1,
1099  const char *name,
1100  int cmd,
1101  void *arg,
1102  unsigned int arglen,
1103  void *buf,
1104  unsigned int buflen)
1105 {
1106  int cmdackerr;
1107  drvdrv_exec_cmd_ack cmdack;
1108 
1109  (void)a1;
1110  (void)name;
1111  (void)cmd;
1112  (void)buflen;
1113 
1114  // Unofficial: fill in dvrpAuth_tbl if provided by argument
1115  if (arglen >= sizeof(dvrpAuth_tbl)) {
1116  memcpy(&dvrpAuth_tbl, arg, sizeof(dvrpAuth_tbl));
1117  }
1118  cmdack.command = 0x2115;
1119  cmdack.input_word_count = 0;
1120  cmdackerr = DvrdrvExecCmdAck(&cmdack);
1121  if (cmdackerr) {
1122  DPRINTF("dvrioctl2_pre_update_a -> Handshake error!,%d\n", cmdackerr);
1123  return -EIO;
1124  } else if (cmdack.ack_status_ack) {
1125  DPRINTF("dvrioctl2_pre_update_a -> Status error!,%04X\n", cmdack.ack_status_ack);
1126  return -EADV;
1127  } else {
1128  *(u16 *)buf = dvrpAuthEnc(cmdack.output_word[0]);
1129  return 0;
1130  }
1131 }
1132 
1133 int dvrioctl2_pre_update_b(
1134  iomanX_iop_file_t *a1,
1135  const char *name,
1136  int cmd,
1137  void *arg,
1138  unsigned int arglen,
1139  void *buf,
1140  unsigned int buflen)
1141 {
1142  int cmdackerr;
1143 #ifdef DEBUG
1144  int ack_status_ack;
1145 #endif
1146  drvdrv_exec_cmd_ack cmdack;
1147 
1148  (void)a1;
1149  (void)name;
1150  (void)cmd;
1151  (void)arglen;
1152  (void)buf;
1153  (void)buflen;
1154 
1155  cmdack.command = 0x2116;
1156  cmdack.input_word_count = 1;
1157  cmdack.timeout = 10000000;
1158  cmdack.input_word[0] = *(u16 *)arg;
1159  cmdackerr = DvrdrvExecCmdAckComp(&cmdack);
1160  if (cmdackerr) {
1161  DPRINTF("dvrioctl2_pre_update_b -> Handshake error!,%d\n", cmdackerr);
1162  return -EIO;
1163  }
1164 #ifdef DEBUG
1165  ack_status_ack = cmdack.ack_status_ack;
1166 #endif
1167  if (!cmdack.ack_status_ack) {
1168  if (!cmdack.comp_status)
1169  return 0;
1170 #ifdef DEBUG
1171  ack_status_ack = cmdack.comp_status;
1172 #endif
1173  }
1174 #ifdef DEBUG
1175  DPRINTF("dvrioctl2_pre_update_b -> Status error!,%04X\n", ack_status_ack);
1176 #endif
1177  return -EADV;
1178 }
1179 
1180 int dvrioctl2_get_rec_vro_pckn(
1181  iomanX_iop_file_t *a1,
1182  const char *name,
1183  int cmd,
1184  void *arg,
1185  unsigned int arglen,
1186  void *buf,
1187  unsigned int buflen)
1188 {
1189  int cmdackerr;
1190  drvdrv_exec_cmd_ack cmdack;
1191 
1192  (void)a1;
1193  (void)name;
1194  (void)cmd;
1195  (void)arg;
1196  (void)arglen;
1197  (void)buflen;
1198 
1199  cmdack.command = 0x2117;
1200  cmdack.input_word_count = 0;
1201  cmdackerr = DvrdrvExecCmdAck(&cmdack);
1202  if (cmdackerr) {
1203  DPRINTF("dvrioctl2_get_rec_vro_pckn -> Handshake error!,%d\n", cmdackerr);
1204  return -EIO;
1205  }
1206  if (cmdack.ack_status_ack == 0xFFFE) {
1207  DPRINTF("dvrioctl2_get_rec_vro_pckn -> Mode error!,%04X\n", 0xFFFE);
1208  } else {
1209  if (!cmdack.ack_status_ack) {
1210  *(u32 *)buf = (cmdack.output_word[0] << 16) + cmdack.output_word[1];
1211  return 0;
1212  }
1213  DPRINTF("dvrioctl2_get_rec_vro_pckn -> Status error!,%04X\n", cmdack.ack_status_ack);
1214  }
1215  return -EADV;
1216 }
1217 
1218 int dvrioctl2_enc_dec_test(
1219  iomanX_iop_file_t *a1,
1220  const char *name,
1221  int cmd,
1222  void *arg,
1223  unsigned int arglen,
1224  void *buf,
1225  unsigned int buflen)
1226 {
1227  int cmdackerr;
1228  drvdrv_exec_cmd_ack cmdack;
1229 
1230  (void)a1;
1231  (void)name;
1232  (void)cmd;
1233  (void)arglen;
1234  (void)buf;
1235  (void)buflen;
1236 
1237  cmdack.command = 0x2118;
1238  cmdack.input_word_count = 1;
1239  cmdack.timeout = 10000000;
1240  cmdack.input_word[0] = *(u16 *)arg;
1241  cmdackerr = DvrdrvExecCmdAckComp(&cmdack);
1242  if (cmdackerr) {
1243  DPRINTF("dvrioctl2_enc_dec_test -> ACK Handshake error!,%d\n", cmdackerr);
1244  return -EIO;
1245  }
1246  if (cmdack.ack_status_ack) {
1247  DPRINTF("dvrioctl2_enc_dec_test -> ACK Status error!,%04X\n", cmdack.ack_status_ack);
1248  } else {
1249  if (!cmdack.comp_status)
1250  return 0;
1251  DPRINTF("dvrioctl2_enc_dec_test -> COMP Status error!,%04X\n", cmdack.comp_status);
1252  }
1253  return -EADV;
1254 }
1255 
1256 int dvrioctl2_make_menu(
1257  iomanX_iop_file_t *a1,
1258  const char *name,
1259  int cmd,
1260  void *arg,
1261  unsigned int arglen,
1262  void *buf,
1263  unsigned int buflen)
1264 {
1265  int v7;
1266  int v8;
1267  int v9;
1268  u16 *v11;
1269  int cmdackerr;
1270  int v16;
1271  int v17;
1272  u16 *input_word;
1273  int v19;
1274  int busywait;
1275  drvdrv_exec_cmd_ack cmdack;
1276 
1277  (void)a1;
1278  (void)name;
1279  (void)cmd;
1280  (void)arglen;
1281  (void)buflen;
1282 
1283  cmdack.command = 0x2119;
1284  cmdack.input_word[0] = *((u16 *)arg + 1);
1285  cmdack.input_word[1] = *(u16 *)arg;
1286  cmdack.input_word[2] = *((u16 *)arg + 3);
1287  cmdack.input_word[3] = *((u16 *)arg + 2);
1288  cmdack.input_word[4] = *((u16 *)arg + 4);
1289  cmdack.input_word[5] = 0;
1290  v7 = 6;
1291  v8 = 1;
1292  v9 = 0;
1293  v11 = &cmdack.input_word[5];
1294  do {
1295  char *v12;
1296  char *v13;
1297  v12 = (char *)arg + v8;
1298  v8 += 2;
1299  v13 = (char *)arg + v9;
1300  v9 += 2;
1301  ++v7;
1302  v11[1] = v13[10] + ((u8)v12[10] << 8);
1303  ++v11;
1304  } while (v7 < 16);
1305  cmdack.input_word_count = 16;
1306  cmdack.timeout = 30000000;
1307  cmdackerr = DvrdrvExecCmdAckComp(&cmdack);
1308  *(u16 *)buf = cmdack.comp_status;
1309  if (cmdackerr) {
1310  DPRINTF("dvrioctl2_make_menu -> ACK Handshake error!,%d\n", cmdackerr);
1311  return -EIO;
1312  }
1313  if (cmdack.ack_status_ack) {
1314  DPRINTF("dvrioctl2_make_menu -> ACK Status error!,%04X\n", cmdack.ack_status_ack);
1315  return -EADV;
1316  }
1317  v16 = 1;
1318  if (cmdack.comp_status) {
1319  DPRINTF("dvrioctl2_make_menu -> COMP Status error!,%04X\n", cmdack.comp_status);
1320  return -EADV;
1321  }
1322  v17 = 1;
1323  input_word = cmdack.return_result_word;
1324  v19 = 0;
1325  do {
1326  char *v20;
1327  char *v21;
1328  v20 = (char *)buf + v17;
1329  v21 = (char *)buf + v19;
1330  v17 += 2;
1331  v19 += 2;
1332  v16 += 1;
1333  v21[2] = (*input_word & 0x00FF);
1334  v20[2] = (*input_word & 0xFF00) >> 8;
1335  input_word += 1;
1336  } while (v16 < 11);
1337  *((u8 *)buf + 22) = 0;
1338  busywait = 0x14;
1339  while (busywait-- >= 0)
1340  ;
1341  return 0;
1342 }
1343 
1344 int dvrioctl2_re_enc_start(
1345  iomanX_iop_file_t *a1,
1346  const char *name,
1347  int cmd,
1348  void *arg,
1349  unsigned int arglen,
1350  void *buf,
1351  unsigned int buflen)
1352 {
1353  int v7;
1354  int v8;
1355  int v9;
1356  u16 *v10;
1357  int v13;
1358  int v14;
1359  int v15;
1360  u16 *v16;
1361  int busywait;
1362  int cmdackerr;
1363  int v24;
1364  int v25;
1365  u16 *v26;
1366  int v27;
1367  drvdrv_exec_cmd_ack cmdack;
1368 
1369  (void)a1;
1370  (void)name;
1371  (void)cmd;
1372  (void)arglen;
1373  (void)buflen;
1374 
1375  cmdack.command = 0x211A;
1376  cmdack.input_word[0] = *((u16 *)arg + 1);
1377  cmdack.input_word[1] = *(u16 *)arg;
1378  cmdack.input_word[2] = *((u16 *)arg + 3);
1379  cmdack.input_word[3] = *((u16 *)arg + 2);
1380  cmdack.input_word[4] = *((u16 *)arg + 4);
1381  cmdack.input_word[5] = *((u16 *)arg + 5);
1382  cmdack.input_word[6] = *((u16 *)arg + 6);
1383  v7 = 7;
1384  v8 = 1;
1385  v9 = 0;
1386  v10 = &cmdack.input_word[6];
1387  do {
1388  u8 *v11;
1389  u8 *v12;
1390  v11 = (u8 *)arg + v8;
1391  v12 = (u8 *)arg + v9;
1392  v10[1] = v12[14] + ((u8)v11[14] << 8);
1393  v8 += 2;
1394  v9 += 2;
1395  v7 += 1;
1396  v10 += 1;
1397  } while (v7 < 17);
1398  cmdack.input_word[17] = 0;
1399  v13 = 18;
1400  v14 = 1;
1401  v15 = 0;
1402  v16 = &cmdack.input_word[17];
1403  do {
1404  u8 *v17;
1405  u8 *v18;
1406  v17 = (u8 *)arg + v14;
1407  v18 = (u8 *)arg + v15;
1408  v16[1] = v18[35] + ((u8)v17[35] << 8);
1409  v14 += 2;
1410  v15 += 2;
1411  v13 += 1;
1412  v16 += 1;
1413  } while (v13 < 28);
1414  cmdack.input_word[26] = 0;
1415  cmdack.input_word[27] = 0;
1416  cmdack.input_word[28] = *((u16 *)arg + 28);
1417  cmdack.input_word[29] = *((u16 *)arg + 29);
1418  cmdack.input_word[30] = *((u16 *)arg + 30);
1419  cmdack.input_word[31] = *((u16 *)arg + 31);
1420  cmdack.input_word[32] = 0;
1421  busywait = 0x1f;
1422  while (busywait-- >= 0)
1423  ;
1424  cmdack.input_word_count = 33;
1425  cmdack.timeout = 30000000;
1426  cmdackerr = DvrdrvExecCmdAckComp(&cmdack);
1427  *(u16 *)buf = cmdack.comp_status;
1428  if (cmdackerr) {
1429  DPRINTF("dvrioctl2_re_enc_start -> ACK Handshake error!,%d\n", cmdackerr);
1430  return -EIO;
1431  }
1432  if (cmdack.ack_status_ack) {
1433  DPRINTF("dvrioctl2_re_enc_start -> ACK Status error!,%04X\n", cmdack.ack_status_ack);
1434  return -EADV;
1435  }
1436  v24 = 2;
1437  if (cmdack.comp_status) {
1438  DPRINTF("dvrioctl2_re_enc_start -> COMP Status error!,%04X\n", cmdack.comp_status);
1439  return -EADV;
1440  }
1441  v25 = 1;
1442  v26 = &cmdack.input_word[1];
1443  v27 = 0;
1444  do {
1445  u8 *v28;
1446  u8 *v29;
1447  v28 = (u8 *)buf + v25;
1448  v29 = (u8 *)buf + v27;
1449  v29[2] = *((u8 *)v26 + 274);
1450  v28[2] = v26[137] >> 8;
1451  v25 += 2;
1452  v27 += 2;
1453  v24 += 1;
1454  v26 += 1;
1455  } while (v24 < 12);
1456  *((u8 *)buf + 22) = 0;
1457  return 0;
1458 }
1459 
1460 int dvrpAuthEnc(u16 in_word)
1461 {
1462  return (u8)dvrpAuth_tbl[(u8)in_word] | ((u8)dvrpAuth_tbl[in_word >> 8] << 8);
1463 }
1464 
1465 int dvr_recv_dma(iomanX_iop_file_t *a1, u8 *buf, int buflen)
1466 {
1467  drvdrv_exec_cmd_ack cmdack;
1468 
1469  DPRINTF("------------------- 2 ------------------ dvr_recv_dma(io=%p, buf=%p, buflen=%d)\n", a1, buf, buflen);
1470  if (((u32)buf & 3) != 0) {
1471  DPRINTF("dvr_recv_dma : Address is not a multiple of 4.\n");
1472  return -EFAULT;
1473  } else {
1474  u8 *buf_tmp;
1475  int buflen_tmp;
1476  int ack_status_ack2;
1477  int err;
1478  buf_tmp = buf;
1479  if ((buflen & 0x7F) != 0)
1480  DPRINTF("buflen is not a multiple of 128.\n");
1481  buflen_tmp = buflen;
1482  while (buflen_tmp > 0) {
1483  cmdack.command = 0x211B;
1484  cmdack.input_word[0] = 0;
1485  cmdack.input_word[1] = 0;
1486  cmdack.input_word[2] = 0;
1487  cmdack.input_word[3] = 6144;
1488  cmdack.input_word_count = 4;
1489  cmdack.output_buffer = buf_tmp;
1490  cmdack.timeout = 0x10000;
1491  if (DvrdrvExecCmdAckDmaRecvComp(&cmdack)) {
1492  err = -EIO;
1493  DPRINTF("dvr_recv_dma : IO error (phase %d)\n", cmdack.phase);
1494  goto finish;
1495  }
1496  if (cmdack.comp_status) {
1497  err = -EIO;
1498  DPRINTF("dvr_recv_dma : Complete parameter error (phase %d), %04X\n", cmdack.phase, cmdack.comp_status);
1499  goto finish;
1500  }
1501  ack_status_ack2 = cmdack.ack_status_ack2;
1502  DPRINTF("rsize : %d / %d \n", cmdack.ack_status_ack2, 6144);
1503  if (ack_status_ack2 <= 0)
1504  break;
1505  buflen_tmp -= ack_status_ack2;
1506  if (ack_status_ack2 < 0x1801)
1507  break;
1508  buf_tmp += ack_status_ack2;
1509  }
1510  err = cmdack.ack_status_ack2;
1511  finish:
1512  DPRINTF("dvr_recv_dma: ret = %d\n", err);
1513  return err;
1514  }
1515 }
1516 
1517 u8 TELTEXT_BUF[0x1800];
1518 unsigned int TELTEXT_ACTLEN;
1519 unsigned int TELTEXT_BUFOFFSET;
1520 
1521 int dvrioctl2_tevent_buf_recv_first(
1522  iomanX_iop_file_t *a1,
1523  const char *name,
1524  int cmd,
1525  void *arg,
1526  unsigned int arglen,
1527  void *buf,
1528  unsigned int buflen)
1529 {
1530  (void)name;
1531  (void)arg;
1532  (void)arglen;
1533 
1534  TELTEXT_BUFOFFSET = 0;
1535  TELTEXT_ACTLEN = 0;
1536  DPRINTF("dvr_tevent_buf_recv_first(io=%p, cmd=%d buf=%p, nbyte=%u)\n", a1, cmd, buf, buflen);
1537  TELTEXT_ACTLEN = dvr_recv_dma(a1, TELTEXT_BUF, sizeof(TELTEXT_BUF));
1538  if ((TELTEXT_ACTLEN & 0x80000000) == 0) {
1539  if (buflen == 1024) {
1540  memcpy(buf, (u8 *)TELTEXT_BUF + TELTEXT_BUFOFFSET, 1024);
1541  TELTEXT_BUFOFFSET += 1024;
1542  if (TELTEXT_ACTLEN <= 0x400) {
1543  DPRINTF("tevent_buf_recv_first: actlen:%u request-buflen:%d return 0 < DMA EOT >\n", TELTEXT_ACTLEN, 1024);
1544  return 0;
1545  } else {
1546  DPRINTF("tevent_buf_recv_first: return <DMA_REMAIND>\n");
1547  return 0xFFE5;
1548  }
1549  } else {
1550  DPRINTF("tevent_buf_recv_first: bufflen error! return 0 < EOT > .\n");
1551  return 0;
1552  }
1553  } else {
1554  DPRINTF("tevent_buf_recv_first: dma error! return 0 < EOT >.\n");
1555  return 0;
1556  }
1557 }
1558 
1559 int dvrioctl2_tevent_buf_recv_next(
1560  iomanX_iop_file_t *a1,
1561  const char *name,
1562  int cmd,
1563  void *arg,
1564  unsigned int arglen,
1565  void *buf,
1566  unsigned int buflen)
1567 {
1568  (void)name;
1569  (void)arg;
1570  (void)arglen;
1571 
1572  DPRINTF("dvr_tevent_buf_recv_next(io=%p, cmd=%d buf=%p, nbyte=%u)\n", a1, cmd, buf, buflen);
1573  if (buflen == 1024) {
1574  if (TELTEXT_BUFOFFSET + 1024 < sizeof(TELTEXT_BUF)) {
1575  memcpy(buf, TELTEXT_BUF + TELTEXT_BUFOFFSET, 1024);
1576  TELTEXT_BUFOFFSET += 1024;
1577  if ((int)TELTEXT_BUFOFFSET < (int)TELTEXT_ACTLEN) {
1578  DPRINTF("tevent_buf_recv_next: return <DMA_REMAIND>\n");
1579  return 65509;
1580  }
1581  DPRINTF("tevent_buf_recv_next: return 0 < DMA EOT >!\n");
1582  } else {
1583  DPRINTF("tevent_buf_recv_next: bufflen error!\n");
1584  }
1585  } else {
1586  DPRINTF("tevent_buf_recv_next: bufflen error!\n");
1587  }
1588  return 0;
1589 }
1590 
1591 int dvrioctl2_finish_auto_process(
1592  iomanX_iop_file_t *a1,
1593  const char *name,
1594  int cmd,
1595  void *arg,
1596  unsigned int arglen,
1597  void *buf,
1598  unsigned int buflen)
1599 {
1600  int cmdackerr;
1601  drvdrv_exec_cmd_ack cmdack;
1602 
1603  (void)a1;
1604  (void)name;
1605  (void)cmd;
1606  (void)arglen;
1607  (void)buflen;
1608 
1609  cmdack.command = 0x211C;
1610  cmdack.input_word_count = 1;
1611  cmdack.timeout = 5000000;
1612  cmdack.input_word[0] = *(u16 *)arg;
1613  cmdackerr = DvrdrvExecCmdAck(&cmdack);
1614  if (cmdackerr) {
1615  DPRINTF("dvrioctl2_finish_auto_process -> Handshake error!,%d\n", cmdackerr);
1616  return -EIO;
1617  }
1618  if (cmdack.ack_status_ack == 0xFFFE) {
1619  DPRINTF("dvrioctl2_finish_auto_process -> Mode error!,%04X\n", 0xFFFE);
1620  } else {
1621  if (!cmdack.ack_status_ack) {
1622  *(u32 *)buf = (cmdack.output_word[0] << 16) + cmdack.output_word[1];
1623  return 0;
1624  }
1625  DPRINTF("dvrioctl2_finish_auto_process -> Status error!,%04X\n", cmdack.ack_status_ack);
1626  }
1627  return -EADV;
1628 }
1629 
1630 int dvrioctl2_rec_pictclip(
1631  iomanX_iop_file_t *a1,
1632  const char *name,
1633  int cmd,
1634  void *arg,
1635  unsigned int arglen,
1636  void *buf,
1637  unsigned int buflen)
1638 {
1639  int busywait;
1640  int cmdackerr;
1641  drvdrv_exec_cmd_ack cmdack;
1642 
1643  (void)a1;
1644  (void)name;
1645  (void)cmd;
1646  (void)arglen;
1647  (void)buf;
1648  (void)buflen;
1649 
1650  cmdack.command = 0x211D;
1651  cmdack.input_word[0] = *((u16 *)arg + 1);
1652  cmdack.input_word[1] = *((u16 *)arg + 0);
1653  cmdack.input_word[2] = *((u16 *)arg + 3);
1654  cmdack.input_word[3] = *((u16 *)arg + 2);
1655  cmdack.input_word[4] = *((u16 *)arg + 4);
1656  cmdack.input_word[5] = *((u16 *)arg + 5);
1657  cmdack.input_word[6] = *((u16 *)arg + 6);
1658  busywait = 4;
1659  while (busywait-- >= 0)
1660  ;
1661  cmdack.input_word_count = 7;
1662  cmdack.timeout = 30000000;
1663  cmdackerr = DvrdrvExecCmdAckComp(&cmdack);
1664  if (cmdackerr) {
1665  DPRINTF("dvrioctl2_re_enc_start -> ACK Handshake error!,%d\n", cmdackerr);
1666  return -EIO;
1667  }
1668  if (cmdack.ack_status_ack) {
1669  DPRINTF("dvrioctl2_re_enc_start -> ACK Status error!,%04X\n", cmdack.ack_status_ack);
1670  } else {
1671  if (!cmdack.comp_status)
1672  return 0;
1673  DPRINTF("dvrioctl2_re_enc_start -> COMP Status error!,%04X\n", cmdack.comp_status);
1674  }
1675  return -EADV;
1676 }
iomanX.h
_ModuleInfo::newflags
u16 newflags
Definition: loadcore.h:36
speedregs.h
IOP_DT_FSEXT
#define IOP_DT_FSEXT
Definition: iomanX.h:66
EUNSUP
#define EUNSUP
Definition: errno.h:117
thbase.h
iop_sema_t
Definition: thsemap.h:38
_iomanX_iop_file
Definition: iomanX.h:70
sysclib.h
EADV
#define EADV
Definition: errno.h:151
EIO
#define EIO
Definition: errno.h:29
loadcore.h
pvrdrv.h
_iomanX_iop_device_ops
Definition: iomanX.h:95
thsemap.h
_iomanX_iop_device
Definition: iomanX.h:81
stdio.h
EINVAL
#define EINVAL
Definition: errno.h:63
DevctlCmdTbl_t
Definition: xesdrv.c:198
EFAULT
#define EFAULT
Definition: errno.h:47
_ModuleInfo
Definition: loadcore.h:31
errno.h