PS2SDK
PS2 Homebrew Libraries
cdc.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 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 "accdvd_internal.h"
12 
13 static struct cdc_module mods_120[3] = {
14  {&acAtaModuleStart, &acAtaModuleStop, &acAtaModuleStatus},
15  {&acd_module_start, &acd_module_stop, &acd_module_status},
16  {&cdfs_module_start, &cdfs_module_stop, &cdfs_module_status}};
17 static struct cdc_softc Cdcc;
18 
19 static int cdc_errno_set(struct cdc_softc *cdcc, int ret)
20 {
21  if ( ret )
22  {
23  if ( ret >= 256 )
24  {
25  if ( ret >> 16 == 6 )
26  {
27  cdfs_umount();
28  ret = 49;
29  }
30  else
31  {
32  int asc;
33 
34  asc = ret & 0xFFFF;
35  ret = 48;
36  if ( asc == 8448 )
37  ret = 50;
38  }
39  }
40  else
41  {
42  switch ( ret )
43  {
44  case 14:
45  ret = 32;
46  break;
47  case 16:
48  ret = 19;
49  break;
50  case 22:
51  ret = 33;
52  break;
53  case 34:
54  ret = 50;
55  break;
56  default:
57  ret = 48;
58  break;
59  }
60  }
61  }
62  cdcc->error = ret;
63  return ret;
64 }
65 
66 static int cdc_eve_alloc()
67 {
68  int ret;
69  iop_event_t param;
70 
71  param.attr = 2;
72  param.bits = 0;
73  param.option = 0;
74  ret = CreateEventFlag(&param);
75  if ( ret <= 0 )
76  {
77  printf("accdvd:cdc:eve_alloc: error %d\n", ret);
78  }
79  return ret;
80 }
81 
82 static int cdc_sem_alloc()
83 {
84  int ret;
85  iop_sema_t param;
86 
87  param.attr = 0;
88  param.initial = 1;
89  param.max = 1;
90  param.option = 0;
91  ret = CreateSema(&param);
92  if ( ret <= 0 )
93  {
94  printf("accdvd:cdc:sem_alloc: error %d\n", ret);
95  }
96  return ret;
97 }
98 
99 static int cdc_unlock(struct cdc_softc *cdcc, int ret, acCdvdsifId fno)
100 {
101  int lockid;
102  unsigned int v8;
103 
104  lockid = cdcc->lockid;
105  if ( fno )
106  {
107  int v6;
108  int eveid;
109 
110  v6 = 0;
111  if ( ret < 0 )
112  v6 = -ret;
113  cdc_errno_set(cdcc, v6);
114  eveid = cdcc->syncid;
115  cdcc->stat = 0;
116  cdcc->fno = AC_CDVDSIF_ID_NOP;
117  if ( eveid > 0 )
118  SetEventFlag(eveid, 3u);
119  }
120  if ( lockid > 0 )
121  {
122  SignalSema(lockid);
123  }
124  v8 = ~ret;
125  return v8 >> 31;
126 }
127 
128 int cdc_getfno()
129 {
130  return Cdcc.fno;
131 }
132 
133 int cdc_geterrno()
134 {
135  return Cdcc.error;
136 }
137 
138 int cdc_seterrno(int ret)
139 {
140  Cdcc.error = ret;
141  return 0;
142 }
143 
144 static void cdc_done(struct acd *acd, struct cdc_softc *arg, int ret)
145 {
146  int v3;
147  cdc_done_t done;
148  int eveid;
149 
150  (void)acd;
151  v3 = 0;
152  if ( ret < 0 )
153  v3 = -ret;
154  cdc_errno_set(arg, v3);
155  done = arg->done;
156  arg->done = 0;
157  if ( done )
158  {
159  int type;
160 
161  switch ( arg->fno )
162  {
163  case AC_CDVDSIF_ID_PAUSE:
164  type = 7;
165  break;
166  case AC_CDVDSIF_ID_READ:
167  type = 1;
168  break;
169  case AC_CDVDSIF_ID_SEEK:
170  type = 4;
171  break;
172  case AC_CDVDSIF_ID_STANDBY:
173  type = 5;
174  break;
175  case AC_CDVDSIF_ID_STOP:
176  type = 6;
177  break;
178  default:
179  type = 0;
180  break;
181  }
182  done(type);
183  }
184  eveid = arg->syncid;
185  arg->stat = 0;
186  arg->fno = AC_CDVDSIF_ID_NOP;
187  if ( eveid > 0 )
188  SetEventFlag(eveid, 3u);
189 }
190 
191 int cdc_sync(int nonblocking)
192 {
193  u32 bits;
194 
195  if ( !Cdcc.fno )
196  {
197  return 0;
198  }
199  if ( nonblocking > 0 )
200  {
201  return 1;
202  }
203  bits = 1;
204  if ( nonblocking < 0 )
205  bits = 3;
206  if ( Cdcc.syncid > 0 )
207  WaitEventFlag(Cdcc.syncid, bits, 1, &bits);
208  return ((bits & 0xFF) ^ 1) & 1;
209 }
210 
211 int cdc_ready(int nonblocking)
212 {
213  struct acd *acd;
214  int ret;
215  int v4;
216  int asc;
217  struct acd acd_data;
218  struct acd acd_data_v8;
219 
220  acd = acd_setup(&acd_data, 0, 0, 5000000);
221  Cdcc.error = 0;
222  ret = -1;
223  while ( ret < 0 )
224  {
225  int delay;
226 
227  ret = acd_ready(acd);
228  delay = -1;
229  if ( ret >= 0 )
230  {
231  v4 = acd_readcapacity();
232  if ( v4 < 0 )
233  v4 = 0;
234  Cdcc.cdsize = v4;
235  ret = 2;
236  }
237  else if ( ret < -255 )
238  {
239  asc = (acUint16) - (ret & 0xFFFF);
240  if ( -ret >> 16 != 6 )
241  {
242  if ( asc != 0x401 )
243  {
244  if ( asc == 0x3A00 )
245  {
246  Cdcc.cdsize = 0;
247  ret = 2;
248  }
249  }
250  else
251  {
252  delay = 1000000;
253  }
254  }
255  else
256  {
257  delay = 0;
258  if ( asc == 10496 )
259  delay = acd_delay();
260  }
261  }
262  else
263  {
264  if ( ret == -116 )
265  {
266  delay = 1000000;
267  }
268  else
269  {
270  ret = 6;
271  }
272  }
273  if ( nonblocking )
274  break;
275  if ( delay > 0 )
276  DelayThread(delay);
277  }
278  if ( ret == 2 )
279  {
280  acd_getmedium(acd_setup(&acd_data_v8, 0, 0, 5000000));
281  Cdcc.tray = acd_gettray();
282  }
283  return ret;
284 }
285 
286 int cdc_medium()
287 {
288  struct acd *v0;
289  int v1;
290  int ret;
291  int v3;
292  struct acd acd_data;
293 
294  v0 = acd_setup(&acd_data, 0, 0, 5000000);
295  v1 = acd_getmedium(v0);
296  ret = v1;
297  v3 = 0;
298  if ( v1 < 0 )
299  v3 = -v1;
300  cdc_errno_set(&Cdcc, v3);
301  switch ( ret )
302  {
303  case 1:
304  case 5:
305  case 33:
306  case 37:
307  return 18;
308  case 2:
309  case 6:
310  case 34:
311  case 38:
312  return 253;
313  case 3:
314  case 7:
315  case 35:
316  case 39:
317  return 19;
318  case 65:
319  case 69:
320  return 20;
321  case 112:
322  case 113:
323  return 0;
324  default:
325  return 255;
326  }
327 }
328 
329 int cdc_error()
330 {
331  return Cdcc.error;
332 }
333 
334 int cdc_stat()
335 {
336  int ret;
337  int v2;
338  struct acd acd_data;
339 
340  ret = acd_getmedium(0);
341  acd_setup(&acd_data, 0, 0, 5000000);
342  if ( ret == -61 )
343  ret = acd_getmedium(&acd_data);
344  if ( ret == 113 )
345  {
346  return 1;
347  }
348  if ( Cdcc.stat )
349  {
350  return Cdcc.stat;
351  }
352  v2 = acd_getstatus();
353  if ( v2 < 0 )
354  return 32;
355  return (v2 != 0) ? 2 : 0;
356 }
357 
358 int cdc_readtoc(unsigned char *toc, cdc_xfer_t xfer)
359 {
360  acInt32 ret;
361  int v7;
362  int ret_v3;
363 
364  if ( Cdcc.lockid )
365  {
366  ret = 0;
367  if ( WaitSema(Cdcc.lockid) )
368  ret = 19;
369  }
370  else
371  {
372  ret = 17;
373  }
374  if ( ret )
375  {
376  Cdcc.error = ret;
377  return 0;
378  }
379  v7 = -16;
380  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
381  {
382  v7 = 6;
383  Cdcc.fno = AC_CDVDSIF_ID_READTOC;
384  Cdcc.stat = 6;
385  if ( Cdcc.syncid > 0 )
386  ClearEventFlag(Cdcc.syncid, 0);
387  }
388  ret_v3 = v7;
389  if ( v7 > 0 )
390  {
391  ret_v3 = acd_readtoc(acd_setup(&Cdcc.acd, 0, 0, 5000000), Cdcc.buf, 1024);
392  if ( ret_v3 > 0 )
393  {
394  if ( ret_v3 < 1024 )
395  memset(&Cdcc.buf[ret_v3], 0, 1024 - ret_v3);
396  ret_v3 = xfer(toc, Cdcc.buf, 1024, CDC_XFER_OUT);
397  }
398  }
399  return cdc_unlock(&Cdcc, ret_v3, AC_CDVDSIF_ID_READTOC);
400 }
401 
402 int cdc_lookup(sceCdlFILE *fp, const char *name, int namlen, cdc_xfer_t xfer)
403 {
404  acInt32 ret;
405  int ret_v2;
406  int ret_v3;
407  struct cdfs_dirent dirent;
408 
409  if ( Cdcc.lockid )
410  {
411  ret = 0;
412  if ( WaitSema(Cdcc.lockid) )
413  ret = 19;
414  }
415  else
416  {
417  ret = 17;
418  }
419  if ( ret )
420  {
421  Cdcc.error = ret;
422  return 0;
423  }
424  ret_v2 = -16;
425  if ( Cdcc.fno )
426  {
427  ret_v3 = ret_v2;
428  }
429  else
430  {
431  ret_v2 = 12;
432  ret_v3 = 12;
433  Cdcc.fno = AC_CDVDSIF_ID_LOOKUP;
434  Cdcc.stat = 0;
435  if ( Cdcc.syncid > 0 )
436  {
437  ClearEventFlag(Cdcc.syncid, 0);
438  ret_v3 = ret_v2;
439  }
440  }
441  if ( ret_v3 > 0 )
442  {
443  ret_v3 = 0;
444  if ( xfer )
445  {
446  ret_v3 = xfer(
447  Cdcc.buf,
448  (void *)((uiptr)name - ((uiptr)name & 0xF)),
449  (((uiptr)name & 0xF) + namlen + 0xF) & 0xFFFFFFF0,
450  CDC_XFER_IN);
451  name = (char *)&Cdcc.buf[(uiptr)name & 0xF];
452  }
453  while ( ret_v3 > 0 )
454  {
455  int ret_v4;
456 
457  ret_v4 = cdfs_lookup(&dirent, name, namlen);
458  if ( ret_v4 >= 0 )
459  {
460  int d_namlen;
461 
462  *(acUint32 *)fp->date = *(acUint32 *)&dirent.d_time.t_padding;
463  *(acUint32 *)&fp->date[4] = *(acUint32 *)&dirent.d_time.t_day;
464  d_namlen = dirent.d_namlen;
465  fp->lsn = dirent.d_lsn;
466  fp->size = dirent.d_size;
467  fp->name[d_namlen] = 59;
468  fp->name[d_namlen + 1] = (dirent.d_vol & 0xFF) + 48;
469  fp->name[d_namlen + 2] = 0;
470  memcpy(fp->name, dirent.d_name, d_namlen);
471  ret_v3 = 0;
472  }
473  else
474  {
475  ret_v3 = cdfs_recover(ret_v4);
476  }
477  }
478  }
479  return cdc_unlock(&Cdcc, ret_v3, AC_CDVDSIF_ID_LOOKUP);
480 }
481 
482 int cdc_seek(unsigned int lsn, cdc_done_t done)
483 {
484  acCdvdsifId fno;
485  acInt32 v5;
486  int v8;
487  int ret_v4;
488 
489  fno = AC_CDVDSIF_ID_SEEK;
490  if ( Cdcc.lockid )
491  {
492  v5 = 0;
493  if ( WaitSema(Cdcc.lockid) )
494  v5 = 19;
495  }
496  else
497  {
498  v5 = 17;
499  }
500  if ( v5 )
501  {
502  Cdcc.error = v5;
503  return 0;
504  }
505  v8 = -16;
506  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
507  {
508  v8 = 13;
509  Cdcc.fno = AC_CDVDSIF_ID_SEEK;
510  Cdcc.stat = 18;
511  if ( Cdcc.syncid > 0 )
512  ClearEventFlag(Cdcc.syncid, 0);
513  }
514  ret_v4 = v8;
515  if ( v8 <= 0 )
516  {
517  fno = AC_CDVDSIF_ID_NOP;
518  }
519  else if ( lsn < Cdcc.cdsize )
520  {
521  Cdcc.done = done;
522  ret_v4 = acd_seek(acd_setup(&Cdcc.acd, (acd_done_t)cdc_done, &Cdcc, -5000000), lsn);
523  if ( ret_v4 >= 0 )
524  fno = AC_CDVDSIF_ID_NOP;
525  }
526  else
527  {
528  ret_v4 = 0;
529  }
530  return cdc_unlock(&Cdcc, ret_v4, fno);
531 }
532 
533 static int cdc_ioctl(acCdvdsifId fno, int state, int tmout, cdc_done_t done)
534 {
535  acInt32 ret;
536  int ret_v2;
537  acCdvdsifId v12;
538  int ret_v4;
539 
540  if ( Cdcc.lockid )
541  {
542  ret = 0;
543  if ( WaitSema(Cdcc.lockid) )
544  ret = 19;
545  }
546  else
547  {
548  ret = 17;
549  }
550  if ( ret )
551  {
552  Cdcc.error = ret;
553  return 0;
554  }
555  if ( state == 4 )
556  {
557  ret_v2 = 0;
558  }
559  else if ( state >= 5 )
560  {
561  if ( state == 6 )
562  {
563  ret_v2 = 1;
564  }
565  else
566  {
567  ret_v2 = 10;
568  if ( state == 16 )
569  ret_v2 = 18;
570  }
571  }
572  else
573  {
574  ret_v2 = 10;
575  if ( state == 1 )
576  ret_v2 = 2;
577  }
578  if ( fno )
579  {
580  v12 = -16;
581  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
582  {
583  v12 = fno;
584  Cdcc.fno = fno;
585  Cdcc.stat = ret_v2;
586  if ( Cdcc.syncid > 0 )
587  ClearEventFlag(Cdcc.syncid, 0);
588  }
589  }
590  else
591  {
592  Cdcc.stat = 0;
593  Cdcc.fno = AC_CDVDSIF_ID_NOP;
594  if ( Cdcc.syncid > 0 )
595  SetEventFlag(Cdcc.syncid, 3u);
596  v12 = AC_CDVDSIF_ID_NOP;
597  }
598  ret_v4 = v12;
599  if ( v12 < AC_CDVDSIF_ID_NOP )
600  {
601  fno = AC_CDVDSIF_ID_NOP;
602  }
603  else
604  {
605  Cdcc.done = done;
606  ret_v4 = acd_ioctl(acd_setup(&Cdcc.acd, (acd_done_t)cdc_done, &Cdcc, tmout), state);
607  if ( ret_v4 >= 0 )
608  {
609  fno = AC_CDVDSIF_ID_NOP;
610  }
611  }
612  return cdc_unlock(&Cdcc, ret_v4, fno);
613 }
614 
615 int cdc_pause(cdc_done_t done)
616 {
617  return cdc_ioctl(AC_CDVDSIF_ID_PAUSE, 1, -5000000, done);
618 }
619 
620 int cdc_standby(cdc_done_t done)
621 {
622  return cdc_ioctl(AC_CDVDSIF_ID_STANDBY, 17, -5000000, done);
623 }
624 
625 int cdc_stop(cdc_done_t done)
626 {
627  return cdc_ioctl(AC_CDVDSIF_ID_STOP, 4, -5000000, done);
628 }
629 
630 int cdc_tray(int mode, u32 *traycnt)
631 {
632  acCdvdsifId tray;
633  int v5;
634  acCdvdsifId v8;
635  struct acd v10;
636 
637  tray = Cdcc.tray;
638  v5 = 1;
639  if ( mode == 2 )
640  {
641  acd_getmedium(acd_setup(&v10, 0, 0, 5000000));
642  }
643  else
644  {
645  int ret;
646 
647  ret = 134;
648  if ( mode )
649  ret = 131;
650  v5 = cdc_ioctl(AC_CDVDSIF_ID_TRAY, ret, 5000000, 0);
651  }
652  v8 = acd_gettray();
653  Cdcc.tray = v8;
654  *traycnt = tray != v8;
655  return v5;
656 }
657 
658 int cdc_getpos()
659 {
660  acInt32 v0;
661  int ret;
662 
663  v0 = 17;
664  if ( Cdcc.lockid )
665  {
666  v0 = 0;
667  if ( WaitSema(Cdcc.lockid) )
668  v0 = 19;
669  }
670  if ( v0 )
671  {
672  Cdcc.error = v0;
673  return 0;
674  }
675  if ( Cdcc.fno )
676  {
677  if ( Cdcc.fno == AC_CDVDSIF_ID_READ )
678  {
679  ret = Cdcc.rd.pos << 11;
680  }
681  else
682  {
683  Cdcc.error = 19;
684  ret = 0;
685  }
686  }
687  else
688  {
689  ret = 0;
690  }
691  if ( Cdcc.lockid > 0 )
692  {
693  SignalSema(Cdcc.lockid);
694  }
695  return ret;
696 }
697 
698 static int cdc_rmode(struct cdc_softc *cdcc, const sceCdRMode *mode)
699 {
700  int spindlctrl;
701  struct acd *v5;
702  int speed;
703  struct acd *acd;
704  int v8;
705  int trycount;
706  struct acd *acd_v7;
707 
708  spindlctrl = mode->spindlctrl;
709  v5 = acd_setup(&cdcc->acd, 0, 0, 5000000);
710  speed = cdcc->rd.maxspeed;
711  acd = v5;
712  v8 = 0;
713  if ( !cdcc->rd.maxspeed )
714  {
715  v8 = acd_getspeed(v5, 1);
716  speed = v8;
717  }
718  if ( v8 >= 0 )
719  {
720  cdcc->rd.maxspeed = v8;
721  if ( spindlctrl == 1 )
722  {
723  int v9;
724 
725  v9 = 3 * (speed - 1);
726  speed = v9 >> 2;
727  if ( v9 < 0 )
728  speed = (v9 + 3) >> 2;
729  }
730  if ( acd_setspeed(acd, speed) >= 0 )
731  cdcc->rd.spindle = spindlctrl;
732  }
733  trycount = mode->trycount - 1;
734  acd_v7 = acd_setup(&cdcc->acd, 0, 0, 5000000);
735  if ( trycount < 0 )
736  trycount = 254;
737  while ( acd_setretry(acd_v7, trycount) == -61 && acd_getretry(acd_v7) >= 0 )
738  ;
739  return 0;
740 }
741 
742 static void cdc_read_done(struct acd *acd, struct cdc_softc *arg, int ret)
743 {
744  cdc_xfer_t xfer;
745  acInt32 npos;
746  unsigned char *buf;
747  int rlen;
748  unsigned char *buf_v9;
749  unsigned char *src;
750 
751  if ( ret >= 0 )
752  {
753  acInt32 cpos;
754  acInt32 size;
755  acInt32 xlen;
756  acInt32 bsize;
757 
758  cpos = arg->rd.pos;
759  size = arg->rd.size;
760  xfer = arg->rd.xfer;
761  npos = cpos + ret;
762  xlen = size - cpos;
763  buf = &arg->rd.buf[2048 * cpos];
764  bsize = arg->rd.bsize;
765  rlen = size - (cpos + ret);
766  if ( size < cpos + ret )
767  npos = arg->rd.size;
768  if ( bsize < rlen )
769  rlen = arg->rd.bsize;
770  if ( bsize < xlen )
771  xlen = arg->rd.bsize;
772  arg->rd.pos = npos;
773  if ( xfer )
774  {
775  unsigned char *size_v10;
776  acInt32 cpos_v11;
777  acInt32 bsize_v13;
778 
779  size_v10 = buf;
780  cpos_v11 = bsize << 11;
781  src = arg->buf;
782  bsize_v13 = arg->rd.bank;
783  buf_v9 = &src[cpos_v11];
784  if ( bsize_v13 )
785  {
786  src += cpos_v11;
787  buf_v9 = arg->buf;
788  }
789  arg->rd.bank = bsize_v13 ^ 1;
790  ret = xfer(size_v10, src, xlen << 11, CDC_XFER_OUT);
791  }
792  else
793  {
794  buf_v9 = &buf[2048 * ret];
795  }
796  }
797  if ( ret >= 0 )
798  {
799  ret = npos;
800  if ( rlen )
801  {
802  int size_v14;
803 
804  size_v14 = arg->syncid;
805  if ( size_v14 > 0 )
806  SetEventFlag(size_v14, 2u);
807  ret = acd_read(acd, arg->rd.lsn + npos, buf_v9, rlen);
808  }
809  }
810  if ( ret >= 0 )
811  {
812  if ( rlen )
813  {
814  int size_v15;
815 
816  size_v15 = arg->syncid;
817  if ( size_v15 > 0 )
818  ClearEventFlag(size_v15, 0xFFFFFFFD);
819  return;
820  }
821  }
822  cdc_done(acd, arg, ret);
823 }
824 
825 int cdc_read(unsigned int lsn, void *buf, int sectors, const sceCdRMode *mode, cdc_xfer_t xfer, cdc_done_t done)
826 {
827  acCdvdsifId fno;
828  acInt32 v11;
829  int v14;
830  int ret_v4;
831  unsigned int n;
832 
833  fno = AC_CDVDSIF_ID_READ;
834  if ( Cdcc.lockid )
835  {
836  v11 = 0;
837  if ( WaitSema(Cdcc.lockid) )
838  v11 = 19;
839  }
840  else
841  {
842  v11 = 17;
843  }
844  if ( v11 )
845  {
846  Cdcc.error = v11;
847  return 0;
848  }
849  v14 = -16;
850  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
851  {
852  v14 = 9;
853  Cdcc.fno = AC_CDVDSIF_ID_READ;
854  Cdcc.stat = 6;
855  if ( Cdcc.syncid > 0 )
856  ClearEventFlag(Cdcc.syncid, 0);
857  }
858  ret_v4 = v14;
859  if ( v14 <= 0 )
860  {
861  fno = AC_CDVDSIF_ID_NOP;
862  return cdc_unlock(&Cdcc, ret_v4, fno);
863  }
864  n = 16;
865  if ( lsn >= Cdcc.cdsize )
866  {
867  ret_v4 = -34;
868  }
869  else
870  {
871  if ( lsn + sectors >= Cdcc.cdsize )
872  sectors = Cdcc.cdsize - lsn;
873  Cdcc.rd.buf = (acUint8 *)buf;
874  Cdcc.done = done;
875  Cdcc.rd.size = sectors;
876  Cdcc.rd.bsize = 16;
877  Cdcc.rd.lsn = lsn;
878  Cdcc.rd.xfer = xfer;
879  Cdcc.rd.pos = 0;
880  Cdcc.rd.bank = 0;
881  if ( xfer )
882  buf = Cdcc.buf;
883  if ( (unsigned int)sectors < 0x10 )
884  n = sectors;
885  ret_v4 = cdc_rmode(&Cdcc, mode);
886  // cppcheck-suppress knownConditionTrueFalse
887  if ( ret_v4 < 0 )
888  return cdc_unlock(&Cdcc, ret_v4, fno);
889  ret_v4 = acd_read(acd_setup(&Cdcc.acd, (acd_done_t)cdc_read_done, &Cdcc, -5000000), lsn, buf, n);
890  if ( ret_v4 >= 0 )
891  {
892  fno = AC_CDVDSIF_ID_NOP;
893  }
894  }
895  return cdc_unlock(&Cdcc, ret_v4, fno);
896 }
897 
898 int cdc_xfer(void *dst, void *src, int len, enum cdc_xfer_dir dir)
899 {
900  if ( dir )
901  memcpy(dst, src, len);
902  return len;
903 }
904 
905 static int cdc_unlocks(struct cdc_softc *cdcc, int ret, acCdvdsifId fno)
906 {
907  int lockid;
908 
909  lockid = cdcc->lockid;
910  if ( ret < 0 )
911  cdc_errno_set(cdcc, -ret);
912  if ( cdcc->fno == fno )
913  {
914  int eveid;
915 
916  eveid = cdcc->syncid;
917  cdcc->fno = AC_CDVDSIF_ID_NOP;
918  if ( eveid > 0 )
919  SetEventFlag(eveid, 3u);
920  }
921  if ( lockid > 0 )
922  {
923  SignalSema(lockid);
924  }
925  return ret >= 0;
926 }
927 
928 static void cdc_stream_done(struct acd *acd, struct cdc_softc *arg, int ret)
929 {
930  int v4;
931  int v21;
932  acSpl state;
933  int flg;
934 
935  flg = 0;
936  v4 = ret;
937  if ( ret <= 0 )
938  {
939  arg->st.flag = 0;
940  arg->fno = AC_CDVDSIF_ID_NOP;
941  v21 = 0;
942  flg = 1;
943  }
944  else
945  {
946  unsigned int flag;
947  acInt32 tail;
948  acInt32 size;
949  acInt32 bsize;
950  unsigned int cdsize;
951  acInt32 head;
952  unsigned int lsn;
953  int xlen;
954  unsigned int v15;
955  unsigned char *buf;
956  unsigned int size_v12;
957 
958  CpuSuspendIntr(&state);
959  flag = arg->st.flag;
960  tail = arg->st.tail;
961  size = arg->st.size;
962  bsize = arg->st.bsize;
963  cdsize = arg->cdsize;
964  head = arg->st.head + v4;
965  if ( head >= size )
966  head = 0;
967  lsn = arg->st.lsn + v4;
968  if ( (flag & 0x10) != 0 )
969  {
970  head = 0;
971  tail = 0;
972  lsn = arg->st.reqlsn;
973  flag = (flag | 0x14) ^ 0x14;
974  arg->st.tail = 0;
975  }
976  else
977  {
978  if ( head == tail )
979  {
980  flag = (flag | 6) ^ 2;
981  }
982  }
983  xlen = tail - head;
984  if ( head >= tail )
985  xlen = size - head;
986  v15 = lsn + xlen;
987  if ( bsize < xlen )
988  {
989  xlen = bsize;
990  v15 = lsn + bsize;
991  }
992  if ( v15 >= cdsize )
993  xlen = cdsize - lsn;
994  buf = &arg->st.buf[2048 * head];
995  size_v12 = flag & 0x28;
996  if ( size_v12 == 32 )
997  {
998  arg->st.flag = flag & 0xFFFFFFFD;
999  }
1000  else
1001  {
1002  if ( ((flag & 0x28) >= 0x21) ? (size_v12 != 40) : (size_v12 != 8) )
1003  {
1004  arg->st.flag = flag;
1005  }
1006  else
1007  {
1008  arg->st.flag = flag & 4;
1009  }
1010  }
1011  arg->st.head = head;
1012  arg->st.lsn = lsn;
1013  CpuResumeIntr(state);
1014  if ( (flag & 8) != 0 )
1015  {
1016  arg->fno = AC_CDVDSIF_ID_NOP;
1017  v4 = 0;
1018  v21 = 0;
1019  flg = 1;
1020  }
1021  else
1022  {
1023  v4 = 0;
1024  if ( (flag & 0x20) != 0 )
1025  {
1026  v21 = 0;
1027  flg = 1;
1028  }
1029  else
1030  {
1031  v4 = -34;
1032  if ( !xlen )
1033  {
1034  v21 = 0;
1035  flg = 1;
1036  }
1037  else
1038  {
1039  int eveid;
1040  eveid = arg->syncid;
1041  if ( eveid > 0 )
1042  SetEventFlag(arg->syncid, 3u);
1043  if ( (flag & 4) == 0 )
1044  {
1045  if ( eveid > 0 )
1046  ClearEventFlag(eveid, 0);
1047  v4 = acd_read(acd, lsn, buf, xlen);
1048  if ( v4 < 0 )
1049  {
1050  v21 = 0;
1051  flg = 1;
1052  }
1053  }
1054  }
1055  }
1056  }
1057  }
1058  if ( flg )
1059  {
1060  int eveid_v17;
1061 
1062  if ( v4 < 0 )
1063  v21 = -v4;
1064  cdc_errno_set(arg, v21);
1065  eveid_v17 = arg->syncid;
1066  if ( eveid_v17 > 0 )
1067  SetEventFlag(eveid_v17, 3u);
1068  }
1069 }
1070 
1071 static int cdc_stream(struct cdc_softc *cdcc)
1072 {
1073  int ret;
1074  int head;
1075  int tail;
1076  int xlen;
1077  int flag;
1078  unsigned char *buf;
1079  unsigned int lsn;
1080  int tail_v9;
1081  struct acd *ret_v10;
1082  acSpl state;
1083 
1084  if ( cdcc->fno != AC_CDVDSIF_ID_STREAM )
1085  {
1086  return -16;
1087  }
1088  CpuSuspendIntr(&state);
1089  head = cdcc->st.head;
1090  tail = cdcc->st.tail;
1091  xlen = tail - head;
1092  if ( head >= tail )
1093  xlen = cdcc->st.size - head;
1094  flag = cdcc->st.flag;
1095  if ( cdcc->st.bsize < xlen )
1096  xlen = cdcc->st.bsize;
1097  buf = &cdcc->st.buf[2048 * head];
1098  if ( (flag & 6) != 0 || (flag & 0x28) != 0 || (flag & 1) == 0 )
1099  xlen = 0;
1100  lsn = 0;
1101  if ( xlen )
1102  {
1103  unsigned int head_v7;
1104 
1105  flag |= 2u;
1106  head_v7 = cdcc->cdsize;
1107  if ( (flag & 0x10) != 0 )
1108  {
1109  lsn = cdcc->st.reqlsn;
1110  flag ^= 0x10u;
1111  cdcc->st.tail = 0;
1112  cdcc->st.head = 0;
1113  cdcc->st.lsn = lsn;
1114  }
1115  else
1116  {
1117  lsn = cdcc->st.lsn;
1118  }
1119  if ( lsn + xlen >= head_v7 )
1120  {
1121  xlen = head_v7 - lsn;
1122  if ( head_v7 == lsn )
1123  flag ^= 2u;
1124  }
1125  }
1126  cdcc->st.flag = flag;
1127  CpuResumeIntr(state);
1128  if ( !xlen )
1129  {
1130  return 0;
1131  }
1132  tail_v9 = cdcc->syncid;
1133  if ( tail_v9 > 0 )
1134  ClearEventFlag(tail_v9, 0);
1135  ret_v10 = acd_setup(&cdcc->acd, (acd_done_t)cdc_stream_done, cdcc, -5000000);
1136  ret = acd_read(ret_v10, lsn, buf, xlen);
1137  if ( ret < 0 )
1138  cdcc->st.flag = 0;
1139  return ret;
1140 }
1141 
1142 int cdc_reads(void *buf, int sectors, int mode, int *errp, cdc_xfer_t xfer)
1143 {
1144  int v5;
1145  int v7;
1146  unsigned char *v11;
1147  acInt32 rlen;
1148  int ret_v8;
1149  acInt32 head;
1150  int rlen_v10;
1151  int v17;
1152  int rlen_v13;
1153  int xlen;
1154  unsigned char *tmp;
1155  int v21;
1156  acInt32 ret_v17;
1157  int xlen_v20;
1158  int ret_v21;
1159  int rlen_v22;
1160  int rlen_v23;
1161  acSpl state;
1162  int state_2;
1163  int state_3;
1164  int v33;
1165  unsigned char *dst;
1166  u32 *resbits;
1167 
1168  v5 = sectors;
1169  dst = (unsigned char *)buf;
1170  resbits = (u32 *)&v33;
1171  while ( v5 > 0 )
1172  {
1173  acInt32 v6;
1174  acInt32 ret;
1175  int len;
1176 
1177  v6 = 17;
1178  if ( Cdcc.lockid )
1179  {
1180  v7 = WaitSema(Cdcc.lockid);
1181  v6 = 0;
1182  if ( v7 )
1183  v6 = 19;
1184  }
1185  if ( v6 )
1186  {
1187  Cdcc.error = v6;
1188  break;
1189  }
1190  ret = 27;
1191  if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1192  {
1193  ret = -16;
1194  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1195  {
1196  ret = 19;
1197  Cdcc.fno = AC_CDVDSIF_ID_READS;
1198  if ( Cdcc.syncid > 0 )
1199  ClearEventFlag(Cdcc.syncid, 0);
1200  }
1201  }
1202  len = v5;
1203  if ( ret <= 0 )
1204  {
1205  rlen_v23 = 0;
1206  printf("accdvd:cdc:reads: ACTIVE\n");
1207  }
1208  else
1209  {
1210  v11 = dst;
1211  CpuSuspendIntr(&state);
1212  rlen = Cdcc.st.tail;
1213  ret_v8 = Cdcc.st.flag;
1214  head = Cdcc.st.head;
1215  rlen_v10 = Cdcc.st.lsn >= Cdcc.cdsize;
1216  CpuResumeIntr(state);
1217  if ( (ret_v8 & 0x10) != 0 )
1218  {
1219  ret = 0;
1220  }
1221  if ( ((ret_v8 & 4) == 0) && (head == rlen) )
1222  {
1223  v17 = 0;
1224  if ( rlen_v10 )
1225  v17 = -34;
1226  ret = v17;
1227  }
1228  else
1229  {
1230  int flg;
1231 
1232  flg = 1;
1233  rlen_v13 = 0;
1234  if ( rlen >= head )
1235  {
1236  xlen = Cdcc.st.size - rlen;
1237  tmp = v11;
1238  if ( v5 < Cdcc.st.size - rlen )
1239  xlen = v5;
1240  len = v5 - xlen;
1241  v11 += 2048 * xlen;
1242  rlen_v13 = xlen;
1243  v21 = xlen;
1244  if ( xlen )
1245  {
1246  v21 = xfer(tmp, &Cdcc.st.buf[2048 * rlen], xlen * 2048, CDC_XFER_OUT);
1247  if ( v21 >= 0 )
1248  {
1249  CpuSuspendIntr(&state_2);
1250  ret_v17 = rlen + rlen_v13;
1251  if ( rlen + rlen_v13 >= Cdcc.st.size )
1252  ret_v17 = 0;
1253  Cdcc.st.tail = ret_v17;
1254  Cdcc.st.flag &= ~4u;
1255  CpuResumeIntr(state_2);
1256  v21 = ret_v17;
1257  }
1258  }
1259  rlen = v21;
1260  if ( rlen < 0 )
1261  {
1262  ret = rlen;
1263  flg = 0;
1264  }
1265  }
1266  if ( rlen < head )
1267  {
1268  xlen_v20 = head - rlen;
1269  ret = head - rlen;
1270  if ( len < head - rlen )
1271  {
1272  xlen_v20 = len;
1273  ret = len;
1274  }
1275  rlen_v13 += xlen_v20;
1276  rlen_v22 = 0;
1277  if ( ret )
1278  {
1279  ret_v21 = xfer(v11, &Cdcc.st.buf[2048 * rlen], ret << 11, CDC_XFER_OUT);
1280  if ( ret_v21 >= 0 )
1281  {
1282  CpuSuspendIntr(&state_3);
1283  ret += rlen;
1284  if ( ret >= Cdcc.st.size )
1285  ret = 0;
1286  Cdcc.st.tail = ret;
1287  Cdcc.st.flag &= ~4u;
1288  CpuResumeIntr(state_3);
1289  rlen_v22 = ret;
1290  }
1291  ret = ret_v21;
1292  }
1293  else
1294  {
1295  rlen_v22 = ret;
1296  }
1297  if ( rlen_v22 < 0 )
1298  flg = 0;
1299  }
1300  if ( flg )
1301  {
1302  ret = rlen_v13;
1303  if ( rlen_v13 > 0 && xfer )
1304  {
1305  xfer(0, 0, 0, CDC_XFER_SYNC);
1306  }
1307  }
1308  }
1309  rlen_v23 = ret;
1310  if ( ret < 0 )
1311  {
1312  rlen_v23 = 0;
1313  printf("accdvd:cdc:reads: READ\n");
1314  }
1315  else
1316  {
1317  v5 -= ret;
1318  dst += 2048 * ret;
1319  ret = cdc_stream(&Cdcc);
1320  }
1321  }
1322  cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_READS);
1323  if ( ret < 0 )
1324  break;
1325  if ( rlen_v23 <= 0 )
1326  {
1327  if ( !mode )
1328  break;
1329  v33 = 1;
1330  if ( Cdcc.syncid > 0 )
1331  WaitEventFlag(Cdcc.syncid, 1u, 1, resbits);
1332  }
1333  }
1334  *errp = Cdcc.error;
1335  return sectors - v5;
1336 }
1337 
1338 int cdc_starts(unsigned int lsn, const sceCdRMode *mode)
1339 {
1340  acInt32 v4;
1341  int v7;
1342  int ret;
1343  acSpl state;
1344 
1345  if ( Cdcc.lockid )
1346  {
1347  v4 = 0;
1348  if ( WaitSema(Cdcc.lockid) )
1349  v4 = 19;
1350  }
1351  else
1352  {
1353  v4 = 17;
1354  }
1355  if ( v4 )
1356  {
1357  Cdcc.error = v4;
1358  return 0;
1359  }
1360  v7 = 27;
1361  if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1362  {
1363  v7 = -16;
1364  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1365  {
1366  v7 = 21;
1367  Cdcc.fno = AC_CDVDSIF_ID_STARTS;
1368  if ( Cdcc.syncid > 0 )
1369  ClearEventFlag(Cdcc.syncid, 0);
1370  }
1371  }
1372  ret = v7;
1373  if ( v7 > 0 )
1374  {
1375  acInt32 flag;
1376 
1377  CpuSuspendIntr(&state);
1378  flag = Cdcc.st.flag;
1379  if ( (Cdcc.st.flag & 2) != 0 )
1380  {
1381  Cdcc.st.reqlsn = lsn;
1382  Cdcc.st.flag |= 0x10u;
1383  }
1384  else
1385  {
1386  flag = 0;
1387  Cdcc.st.flag = 1;
1388  Cdcc.st.lsn = lsn;
1389  }
1390  CpuResumeIntr(state);
1391  if ( !flag )
1392  {
1393  acCdvdsifId flag_v5;
1394 
1395  flag_v5 = Cdcc.fno;
1396  Cdcc.fno = AC_CDVDSIF_ID_STREAM;
1397  ret = cdc_rmode(&Cdcc, mode);
1398  // cppcheck-suppress knownConditionTrueFalse
1399  if ( ret < 0 || (ret = cdc_stream(&Cdcc), ret < 0) )
1400  Cdcc.fno = flag_v5;
1401  }
1402  }
1403  return cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_STARTS);
1404 }
1405 
1406 int cdc_stops()
1407 {
1408  acInt32 v0;
1409  int sync;
1410  int ret;
1411  int sync_v5;
1412  int ret_v6;
1413  int state;
1414  u32 pattern;
1415 
1416  v0 = 17;
1417  if ( Cdcc.lockid )
1418  {
1419  v0 = 0;
1420  if ( WaitSema(Cdcc.lockid) )
1421  v0 = 19;
1422  }
1423  if ( v0 )
1424  {
1425  Cdcc.error = v0;
1426  return 0;
1427  }
1428  sync = 27;
1429  if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1430  {
1431  sync = -16;
1432  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1433  {
1434  sync = 23;
1435  Cdcc.fno = AC_CDVDSIF_ID_STOPS;
1436  if ( Cdcc.syncid > 0 )
1437  ClearEventFlag(Cdcc.syncid, 0);
1438  }
1439  }
1440  ret = sync;
1441  sync_v5 = 0;
1442  if ( sync > 0 )
1443  {
1444  CpuSuspendIntr(&state);
1445  sync_v5 = Cdcc.st.flag | 8;
1446  if ( (Cdcc.st.flag & 2) == 0 )
1447  {
1448  Cdcc.fno = AC_CDVDSIF_ID_STOPS;
1449  sync_v5 = 0;
1450  }
1451  Cdcc.st.flag = sync_v5;
1452  CpuResumeIntr(state);
1453  }
1454  ret_v6 = cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_STOPS);
1455  if ( sync_v5 )
1456  {
1457  pattern = 1;
1458  if ( Cdcc.syncid > 0 )
1459  WaitEventFlag(Cdcc.syncid, 1u, 1, &pattern);
1460  }
1461  return ret_v6;
1462 }
1463 
1464 int cdc_pauses()
1465 {
1466  acInt32 v0;
1467  int sync;
1468  int ret;
1469  int sync_v5;
1470  int ret_v7;
1471  int state;
1472  u32 pattern;
1473 
1474  v0 = 17;
1475  if ( Cdcc.lockid )
1476  {
1477  v0 = 0;
1478  if ( WaitSema(Cdcc.lockid) )
1479  v0 = 19;
1480  }
1481  if ( v0 )
1482  {
1483  Cdcc.error = v0;
1484  return 0;
1485  }
1486  sync = 27;
1487  if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1488  {
1489  sync = -16;
1490  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1491  {
1492  sync = 24;
1493  Cdcc.fno = AC_CDVDSIF_ID_PAUSES;
1494  if ( Cdcc.syncid > 0 )
1495  ClearEventFlag(Cdcc.syncid, 0);
1496  }
1497  }
1498  ret = sync;
1499  sync_v5 = 0;
1500  if ( sync > 0 )
1501  {
1502  int sync_v6;
1503 
1504  CpuSuspendIntr(&state);
1505  sync_v6 = Cdcc.st.flag;
1506  if ( (Cdcc.st.flag & 2) != 0 )
1507  {
1508  sync_v6 = Cdcc.st.flag | 0x20;
1509  Cdcc.st.flag |= 0x20u;
1510  }
1511  sync_v5 = sync_v6 & 2;
1512  CpuResumeIntr(state);
1513  }
1514  ret_v7 = cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_PAUSES);
1515  if ( sync_v5 )
1516  {
1517  pattern = 1;
1518  if ( Cdcc.syncid > 0 )
1519  WaitEventFlag(Cdcc.syncid, 1u, 1, &pattern);
1520  }
1521  return ret_v7;
1522 }
1523 
1524 int cdc_resumes()
1525 {
1526  acInt32 v0;
1527  int ret_v2;
1528  int ret_v3;
1529  acSpl state;
1530 
1531  v0 = 17;
1532  if ( Cdcc.lockid )
1533  {
1534  v0 = 0;
1535  if ( WaitSema(Cdcc.lockid) )
1536  v0 = 19;
1537  }
1538  if ( v0 )
1539  {
1540  Cdcc.error = v0;
1541  return 0;
1542  }
1543  ret_v2 = 27;
1544  if ( Cdcc.fno == AC_CDVDSIF_ID_STREAM )
1545  {
1546  ret_v3 = ret_v2;
1547  }
1548  else
1549  {
1550  ret_v2 = -16;
1551  if ( Cdcc.fno )
1552  {
1553  ret_v3 = ret_v2;
1554  }
1555  else
1556  {
1557  ret_v2 = 25;
1558  ret_v3 = 25;
1559  Cdcc.fno = AC_CDVDSIF_ID_RESUMES;
1560  if ( Cdcc.syncid > 0 )
1561  {
1562  ClearEventFlag(Cdcc.syncid, 0);
1563  ret_v3 = ret_v2;
1564  }
1565  }
1566  }
1567  if ( ret_v3 > 0 )
1568  {
1569  int flag;
1570 
1571  CpuSuspendIntr(&state);
1572  flag = Cdcc.st.flag;
1573  if ( (Cdcc.st.flag & 2) == 0 && (Cdcc.st.flag & 0x20) != 0 )
1574  Cdcc.st.flag ^= 0x20u;
1575  CpuResumeIntr(state);
1576  ret_v3 = 0;
1577  if ( (flag & 0x20) != 0 )
1578  ret_v3 = cdc_stream(&Cdcc);
1579  }
1580  return cdc_unlocks(&Cdcc, ret_v3, AC_CDVDSIF_ID_RESUMES);
1581 }
1582 
1583 int cdc_inits(void *buf, unsigned int size, unsigned int bsize)
1584 {
1585  acInt32 ret;
1586  int v9;
1587  int ret_v3;
1588 
1589  if ( Cdcc.lockid )
1590  {
1591  ret = 0;
1592  if ( WaitSema(Cdcc.lockid) )
1593  ret = 19;
1594  }
1595  else
1596  {
1597  ret = 17;
1598  }
1599  if ( ret )
1600  {
1601  Cdcc.error = ret;
1602  return 0;
1603  }
1604  v9 = -16;
1605  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1606  {
1607  v9 = 18;
1608  Cdcc.fno = AC_CDVDSIF_ID_INITS;
1609  Cdcc.stat = 0;
1610  if ( Cdcc.syncid > 0 )
1611  ClearEventFlag(Cdcc.syncid, 0);
1612  }
1613  ret_v3 = v9;
1614  if ( v9 > 0 )
1615  {
1616  ret_v3 = 1;
1617  Cdcc.st.buf = (acUint8 *)buf;
1618  Cdcc.st.size = size;
1619  Cdcc.st.bsize = bsize;
1620  Cdcc.st.head = 0;
1621  Cdcc.st.tail = 0;
1622  Cdcc.st.lsn = 0;
1623  Cdcc.st.reqlsn = 0;
1624  Cdcc.st.flag = 0;
1625  }
1626  return cdc_unlock(&Cdcc, ret_v3, AC_CDVDSIF_ID_INITS);
1627 }
1628 
1629 int cdc_seeks(unsigned int lsn)
1630 {
1631  acInt32 v2;
1632  int v5;
1633  int ret;
1634  acSpl state;
1635 
1636  v2 = 17;
1637  if ( Cdcc.lockid )
1638  {
1639  v2 = 0;
1640  if ( WaitSema(Cdcc.lockid) )
1641  v2 = 19;
1642  }
1643  if ( v2 )
1644  {
1645  Cdcc.error = v2;
1646  return 0;
1647  }
1648  v5 = 27;
1649  if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1650  {
1651  v5 = -16;
1652  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1653  {
1654  v5 = 20;
1655  Cdcc.fno = AC_CDVDSIF_ID_SEEKS;
1656  if ( Cdcc.syncid > 0 )
1657  ClearEventFlag(Cdcc.syncid, 0);
1658  }
1659  }
1660  ret = v5;
1661  if ( v5 > 0 )
1662  {
1663  CpuSuspendIntr(&state);
1664  Cdcc.st.reqlsn = lsn;
1665  Cdcc.st.flag |= 0x10u;
1666  CpuResumeIntr(state);
1667  ret = 1;
1668  }
1669  return cdc_unlocks(&Cdcc, ret, AC_CDVDSIF_ID_SEEKS);
1670 }
1671 
1672 int cdc_stats()
1673 {
1674  acInt32 v0;
1675  int ret;
1676  acSpl state;
1677 
1678  v0 = 17;
1679  if ( Cdcc.lockid )
1680  {
1681  v0 = 0;
1682  if ( WaitSema(Cdcc.lockid) )
1683  v0 = 19;
1684  }
1685  if ( v0 )
1686  {
1687  Cdcc.error = v0;
1688  return 0;
1689  }
1690  ret = 27;
1691  if ( Cdcc.fno != AC_CDVDSIF_ID_STREAM )
1692  {
1693  ret = -16;
1694  if ( Cdcc.fno == AC_CDVDSIF_ID_NOP )
1695  {
1696  ret = 22;
1697  Cdcc.fno = AC_CDVDSIF_ID_STATS;
1698  if ( Cdcc.syncid > 0 )
1699  ClearEventFlag(Cdcc.syncid, 0);
1700  }
1701  }
1702  if ( ret > 0 )
1703  {
1704  CpuSuspendIntr(&state);
1705  ret = Cdcc.st.size;
1706  if ( Cdcc.st.head == Cdcc.st.tail )
1707  {
1708  if ( (Cdcc.st.flag & 4) == 0 )
1709  ret = 0;
1710  }
1711  else if ( Cdcc.st.head < Cdcc.st.tail )
1712  {
1713  ret = Cdcc.st.size + Cdcc.st.head - Cdcc.st.tail;
1714  }
1715  else
1716  {
1717  ret = Cdcc.st.head - Cdcc.st.tail;
1718  }
1719  CpuResumeIntr(state);
1720  }
1721  if ( Cdcc.fno == AC_CDVDSIF_ID_STATS )
1722  {
1723  Cdcc.fno = AC_CDVDSIF_ID_NOP;
1724  if ( Cdcc.syncid > 0 )
1725  SetEventFlag(Cdcc.syncid, 3u);
1726  }
1727  if ( Cdcc.lockid > 0 )
1728  {
1729  SignalSema(Cdcc.lockid);
1730  }
1731  if ( ret < 0 )
1732  return 0;
1733  return ret;
1734 }
1735 
1736 int cdc_module_status()
1737 {
1738  int ret;
1739  int state;
1740 
1741  CpuSuspendIntr(&state);
1742  if ( Cdcc.fno )
1743  ret = 2;
1744  else
1745  ret = Cdcc.lockid > 0;
1746  CpuResumeIntr(state);
1747  return ret;
1748 }
1749 
1750 int cdc_module_start(int argc, char **argv)
1751 {
1752  int ret;
1753  int index;
1754  int v6;
1755  int ret_v4;
1756  int ret_v5;
1757  int lockid;
1758  acUint8 *buf_v7;
1759  int syncid;
1760  acUint8 *buf;
1761 
1762  (void)argc;
1763  (void)argv;
1764  ret = cdc_module_status();
1765  index = 0;
1766  if ( ret )
1767  {
1768  return ret;
1769  }
1770  v6 = 0;
1771  ret_v4 = 0;
1772  while ( (unsigned int)index < 3 )
1773  {
1774  int ret_v3;
1775 
1776  ret_v3 = mods_120[v6].status();
1777  ret_v4 = ret_v3;
1778  if ( ret_v3 <= 0 )
1779  {
1780  if ( !ret_v3 )
1781  ret_v4 = mods_120[v6].start(argc, argv);
1782  }
1783  else
1784  {
1785  ret_v4 = 0;
1786  }
1787  if ( ret_v4 < 0 )
1788  {
1789  printf("cdc:init_modules:S:%d: error %d\n", index, ret_v4);
1790  break;
1791  }
1792  ++index;
1793  ++v6;
1794  }
1795  ret_v5 = ret_v4;
1796  if ( ret_v5 <= 0 )
1797  {
1798  return ret_v5;
1799  }
1800  lockid = cdc_sem_alloc();
1801  syncid = cdc_eve_alloc();
1802  buf_v7 = (acUint8 *)AllocSysMemory(0, 0x10000, 0);
1803  buf = buf_v7;
1804  if ( lockid > 0 )
1805  {
1806  if ( buf_v7 )
1807  {
1808  memset(&Cdcc, 0, sizeof(Cdcc));
1809  Cdcc.syncid = syncid;
1810  Cdcc.lockid = lockid;
1811  Cdcc.buf = buf;
1812  Cdcc.cdsize = 0;
1813  Cdcc.rd.spindle = -1;
1814  Cdcc.rd.maxspeed = 0;
1815  if ( syncid > 0 )
1816  SetEventFlag(syncid, 3u);
1817  return ret_v5;
1818  }
1819  DeleteSema(lockid);
1820  }
1821  if ( syncid > 0 )
1822  DeleteEventFlag(syncid);
1823  if ( buf )
1824  {
1825  FreeSysMemory(buf);
1826  }
1827  return -6;
1828 }
1829 
1830 int cdc_module_stop()
1831 {
1832  int ret;
1833  int lockid;
1834  int i;
1835  int lockid_v6;
1836  u32 pattern;
1837 
1838  ret = cdc_module_status();
1839  if ( ret == 0 )
1840  {
1841  return 0;
1842  }
1843  lockid = Cdcc.lockid;
1844  if ( Cdcc.lockid <= 0 )
1845  return 0;
1846  cdc_stops();
1847  WaitSema(lockid);
1848  pattern = 1;
1849  if ( Cdcc.syncid > 0 )
1850  WaitEventFlag(Cdcc.syncid, 1u, 1, &pattern);
1851  if ( Cdcc.syncid > 0 )
1852  DeleteEventFlag(Cdcc.syncid);
1853  if ( Cdcc.buf )
1854  FreeSysMemory(Cdcc.buf);
1855  memset(&Cdcc, 0, sizeof(Cdcc));
1856  SignalSema(lockid);
1857  DeleteSema(lockid);
1858  for ( i = 2;; --i )
1859  {
1860  int ret_v5;
1861 
1862  ret_v5 = mods_120[i].status();
1863  lockid_v6 = ret_v5;
1864  if ( ret_v5 < 0 )
1865  {
1866  lockid_v6 = 0;
1867  }
1868  if ( ret_v5 > 0 )
1869  {
1870  lockid_v6 = mods_120[i].stop();
1871  if ( lockid_v6 < 0 )
1872  {
1873  printf("cdc:init_modules:E:%d: error %d\n", i, lockid_v6);
1874  return lockid_v6;
1875  }
1876  }
1877  }
1878  return lockid_v6;
1879 }
1880 
1881 int cdc_module_restart(int argc, char **argv)
1882 {
1883  (void)argc;
1884  (void)argv;
1885 
1886  return -88;
1887 }
acd
Definition: accdvd_internal.h:24
iop_sema_t
Definition: thsemap.h:38
toc
static cdda_toc toc
Definition: cdrom.c:52
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
sceCdlFILE
Definition: libcdvd-common.h:208
cdc_module
Definition: accdvd_internal.h:329
cdfs_dirent
Definition: accdvd_internal.h:300
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
sceCdRMode
Definition: libcdvd-common.h:233
cdc_softc
Definition: accdvd_internal.h:60
iop_event_t
Definition: thevent.h:37