PS2SDK
PS2 Homebrew Libraries
acd.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 <atahw.h>
12 #include "accdvd_internal.h"
13 
14 static struct acd_softc Acdc;
15 
16 static void acd_done(struct acd *acd, struct acd_softc *arg, int ret)
17 {
18  acInt32 tmout;
19  int thid;
20  int tmout_v2;
21  acd_done_t done;
22  acSpl state;
23 
24  CpuSuspendIntr(&state);
25  tmout = arg->active;
26  arg->sense = ret;
27  tmout--;
28  arg->active = tmout;
29  if ( tmout < 0 )
30  arg->active = 0;
31  CpuResumeIntr(state);
32  thid = acd->c_thid;
33  tmout_v2 = acd->c_tmout;
34  done = acd->c_done;
35  acd->c_thid = ret;
36  if ( !tmout_v2 )
37  acd->c_tmout = 1;
38  if ( done )
39  done(acd, acd->c_arg, ret);
40  if ( thid )
41  WakeupThread(thid);
42 }
43 
44 static void acd_atapi_done(acAtapiT atapi, void *arg, int ret)
45 {
46  struct acd_softc *argt;
47 
48  argt = (struct acd_softc *)arg;
49  acd_done((struct acd *)atapi, argt, ret);
50 }
51 
52 static int
53 acd_request_in(struct acd *acd, int flag, acAtapiPacketT packet, void *buffer, int size, acAtapiDone done, char *name)
54 {
55  int status;
56  int ret;
57  int ret_v10;
58  int tmout;
59  int v16;
60  int ret_v13;
61  int ret_v15;
62  int state;
63  int state_2;
64 
65  (void)name;
66  if ( (Acdc.status & 1) == 0 )
67  return -6;
68  ret = acd->c_tmout;
69  if ( ret <= 0 )
70  {
71  acd->c_thid = 0;
72  ret = -ret;
73  }
74  else
75  {
76  acd->c_thid = GetThreadId();
77  }
78  acAtapiSetup(&acd->c_atapi, done ? done : acd_atapi_done, &Acdc, ret);
79  CpuSuspendIntr(&state);
80  ret_v10 = Acdc.drive;
81  ++Acdc.active;
82  CpuResumeIntr(state);
83  status = ret_v10;
84  if ( status < 0 )
85  {
86  return status;
87  }
88  tmout = acd->c_tmout;
89  v16 = flag | ret_v10;
90  if ( tmout > 0 )
91  acd->c_tmout = 0;
92  status = acAtapiRequest(&acd->c_atapi, v16, packet, buffer, size);
93  ret_v13 = status;
94  if ( status < 0 )
95  {
96  CpuSuspendIntr(&state_2);
97  Acdc.active--;
98  if ( Acdc.active < 0 )
99  Acdc.active = 0;
100  CpuResumeIntr(state_2);
101  return ret_v13;
102  }
103  if ( tmout <= 0 )
104  {
105  return status;
106  }
107  while ( 1 )
108  {
109  int status_v14;
110 
111  status_v14 = SleepThread();
112  if ( status_v14 == -418 )
113  {
114  ret_v15 = -116;
115  break;
116  }
117  if ( status_v14 )
118  {
119  ret_v15 = -5;
120  break;
121  }
122  if ( acd->c_tmout )
123  {
124  ret_v15 = acd->c_thid;
125  acd->c_tmout = tmout;
126  return ret_v15;
127  }
128  }
129  acd->c_tmout = tmout;
130  return ret_v15;
131 }
132 
133 static void acd_read_done(acAtapiT atapi, struct acd_softc *arg, int ret)
134 {
135  if ( ret >= 0 )
136  ret >>= 11;
137  acd_done((struct acd *)atapi, arg, ret);
138 }
139 
140 int acd_read(struct acd *acd, acd_lsn_t lsn, void *buf, int sectors)
141 {
142  int flag;
143  union
144  {
145  struct
146  {
147  acUint8 opcode;
148  acUint8 lun;
149  acUint8 lba[4];
150  // cppcheck-suppress unusedStructMember
151  acUint8 padding;
152  acUint8 len[2];
153  // cppcheck-suppress unusedStructMember
154  acUint8 padding2[3];
155  };
156  acAtapiPacketData pkt;
157  } u;
158 
159  if ( !acd || !buf )
160  return -22;
161  if ( sectors == 0 )
162  {
163  return 0;
164  }
165  memset(&u, 0, sizeof(u));
166  flag = 2;
167  if ( Acdc.dma )
168  flag = 3;
169  u.opcode = 40;
170  u.lun = 0;
171  u.lba[0] = (lsn & 0xFF000000) >> 24;
172  u.lba[1] = (lsn & 0xFF0000) >> 16;
173  u.lba[2] = (lsn & 0xFF00) >> 8;
174  u.lba[3] = lsn;
175  u.len[0] = (sectors & 0xFF00) >> 8;
176  u.len[1] = sectors & 0xFF;
177  return acd_request_in(acd, flag, &u.pkt, buf, sectors << 11, (acAtapiDone)acd_read_done, "read");
178 }
179 
180 int acd_readtoc(struct acd *acd, void *buf, int size)
181 {
183 
184  if ( !acd || !buf )
185  return -22;
186  if ( !size )
187  return 0;
188  memset(&v4, 0, sizeof(v4));
189  v4.u_h[2] = 0;
190  v4.u_w[0] = 579;
191  v4.u_b[7] = (size & 0xFF00) >> 8;
192  v4.u_b[6] = 0;
193  v4.u_w[2] = size & 0xFF;
194  return acd_request_in(acd, 2, &v4, buf, size, 0, "readtoc");
195 }
196 
197 int acd_seek(struct acd *acd, acd_lsn_t lsn)
198 {
200 
201  if ( !acd )
202  return -22;
203  memset(&v3, 0, sizeof(v3));
204  v3.u_h[0] = 40;
205  v3.u_b[2] = (lsn & 0xFF000000) >> 24;
206  v3.u_b[3] = (lsn & 0xFF0000) >> 16;
207  v3.u_w[1] = (lsn & 0xFF00) >> 8;
208  v3.u_w[2] = 0;
209  v3.u_b[5] = lsn;
210  return acd_request_in(acd, 2, &v3, 0, 0, 0, "seek");
211 }
212 
213 static void acd_opentray_done(acAtapiT atapi, struct acd_softc *arg, int ret)
214 {
215  acSpl state;
216 
217  if ( ret >= 0 )
218  {
219  CpuSuspendIntr(&state);
220  arg->status = (arg->status | 6) ^ 4;
221  CpuResumeIntr(state);
222  }
223  acd_done((struct acd *)atapi, arg, ret);
224 }
225 
226 static void acd_closetray_done(acAtapiT atapi, struct acd_softc *arg, int ret)
227 {
228  acSpl state;
229 
230  if ( ret >= 0 )
231  {
232  CpuSuspendIntr(&state);
233  arg->status = (arg->status | 6) ^ 2;
234  CpuResumeIntr(state);
235  }
236  acd_done((struct acd *)atapi, arg, ret);
237 }
238 
239 int acd_ioctl(struct acd *acd, int cmd)
240 {
241  acAtapiDone done;
242  char *name;
243  union
244  {
245  struct
246  {
247  acUint8 opcode;
248  acUint8 imm;
249  // cppcheck-suppress unusedStructMember
250  acUint8 padding3[2];
251  acUint8 op;
252  // cppcheck-suppress unusedStructMember
253  acUint8 padding4[7];
254  };
255  acAtapiPacketData pkt;
256  } u;
257 
258  if ( !acd )
259  return -22;
260  memset(&u, 0, sizeof(u));
261  done = 0;
262  if ( cmd == 17 )
263  {
264  u.opcode = 40;
265  name = "ioctl:seek+start";
266  }
267  else if ( (cmd & 5) != 0 )
268  {
269  u.opcode = 27;
270  u.imm = (cmd & 0x80) != 0;
271  u.op = cmd & 3;
272  if ( (cmd & 2) != 0 )
273  {
274  done = (acAtapiDone)acd_opentray_done;
275  if ( (cmd & 1) != 0 )
276  done = (acAtapiDone)acd_closetray_done;
277  }
278  name = "ioctl:startstop";
279  }
280  else
281  {
282  return -22;
283  }
284  return acd_request_in(acd, 2, &u.pkt, 0, 0, done, name);
285 }
286 
287 static int acd_mode_sense(struct acd *acd, int pgcode, void *buffer, int size, acAtapiDone done, char *name)
288 {
290 
291  memset(&v7, 0, sizeof(v7));
292  v7.u_b[0] = 0x5A;
293  v7.u_b[2] = pgcode;
294  v7.u_b[7] = (size & 0xFF00) >> 8;
295  v7.u_w[2] = size & 0xFF;
296  return acd_request_in(acd, 2, &v7, buffer, size, done, name);
297 }
298 
299 static int acd_mode_select(struct acd *acd, void *buffer, int size, acAtapiDone done, char *name)
300 {
302 
303  memset(&v6, 0, sizeof(v6));
304  v6.u_b[0] = 0x55;
305  v6.u_b[1] = 0x10;
306  v6.u_b[7] = (size & 0xFF00) >> 8;
307  v6.u_w[2] = size & 0xFF;
308  return acd_request_in(acd, 6, &v6, buffer, size, done, name);
309 }
310 
311 static void acd_getmedium_done(acAtapiT atapi, struct acd_softc *arg, int ret)
312 {
313  int h_mtype;
314  acSpl state;
315 
316  h_mtype = ret;
317  if ( ret >= 0 )
318  {
319  acUint32 status;
320  int v7;
321 
322  CpuSuspendIntr(&state);
323  h_mtype = arg->retry.me_h.h_mtype;
324  status = arg->status | 6;
325  arg->medium = h_mtype;
326  if ( h_mtype == 113 )
327  v7 = status ^ 4;
328  else
329  v7 = status ^ 2;
330  arg->status = v7 | 0xA00;
331  CpuResumeIntr(state);
332  }
333  acd_done((struct acd *)atapi, arg, h_mtype);
334 }
335 
336 int acd_getmedium(struct acd *acd)
337 {
338  int ret;
339  acSpl state;
340 
341  if ( acd )
342  return acd_mode_sense(acd, 1, &Acdc.retry, 20, (acAtapiDone)acd_getmedium_done, "getmedium");
343  CpuSuspendIntr(&state);
344  ret = -61;
345  if ( (Acdc.status & 0x800) != 0 )
346  ret = Acdc.medium;
347  CpuResumeIntr(state);
348  return ret;
349 }
350 
351 static void acd_retry_done(acAtapiT atapi, struct acd_softc *arg, int ret)
352 {
353  int me_rretry;
354  acSpl state;
355 
356  me_rretry = ret;
357  if ( ret >= 0 )
358  {
359  acCdvdsifId h_mtype;
360  acUint32 status;
361  int v8;
362 
363  CpuSuspendIntr(&state);
364  h_mtype = arg->retry.me_h.h_mtype;
365  status = arg->status | 6;
366  arg->medium = h_mtype;
367  if ( h_mtype == 113 )
368  v8 = status ^ 4;
369  else
370  v8 = status ^ 2;
371  arg->status = v8 | 0xA00;
372  me_rretry = arg->retry.me_rretry;
373  CpuResumeIntr(state);
374  }
375  acd_done((struct acd *)atapi, arg, me_rretry);
376 }
377 
378 int acd_getretry(struct acd *acd)
379 {
380  if ( !acd )
381  return -22;
382  return acd_mode_sense(acd, 1, &Acdc.retry, 20, (acAtapiDone)acd_retry_done, "getretry");
383 }
384 
385 int acd_setretry(struct acd *acd, int rretry)
386 {
387  int size;
388  acSpl state;
389 
390  if ( acd == 0 )
391  {
392  return -22;
393  }
394  if ( (Acdc.status & 0x200) == 0 )
395  {
396  return -61;
397  }
398  CpuSuspendIntr(&state);
399  size = 0;
400  if ( rretry != Acdc.retry.me_rretry )
401  {
402  Acdc.retry.me_rretry = rretry;
403  size = (Acdc.retry.me_h.h_len[0] << 8) + Acdc.retry.me_h.h_len[1] + 2;
404  }
405  CpuResumeIntr(state);
406  if ( !size )
407  return rretry;
408  return acd_mode_select(acd, &Acdc.retry, size, (acAtapiDone)acd_retry_done, "setretry");
409 }
410 
411 static void acd_getspeed_done(acAtapiT atapi, struct acd_softc *arg, int ret)
412 {
413  int v4;
414  acSpl state;
415 
416  v4 = ret;
417  if ( ret >= 0 )
418  {
419  acCdvdsifId speed;
420  acUint32 status;
421  int v8;
422 
423  CpuSuspendIntr(&state);
424  speed = arg->speed.mc_h.h_mtype;
425  v4 = (arg->speed.mc_speed[0] << 8) + arg->speed.mc_speed[1];
426  status = arg->status | 6;
427  arg->medium = speed;
428  if ( speed == 113 )
429  v8 = status ^ 4;
430  else
431  v8 = status ^ 2;
432  arg->status = v8 | 0xC00;
433  CpuResumeIntr(state);
434  }
435  acd_done((struct acd *)atapi, arg, v4);
436 }
437 
438 static void acd_getmaxspeed_done(acAtapiT atapi, struct acd_softc *arg, int ret)
439 {
440  int v4;
441  acSpl state;
442 
443  v4 = ret;
444  if ( ret >= 0 )
445  {
446  acCdvdsifId speed;
447  acUint32 status;
448  int v8;
449 
450  CpuSuspendIntr(&state);
451  speed = arg->speed.mc_h.h_mtype;
452  v4 = (arg->speed.mc_maxspeed[0] << 8) + arg->speed.mc_maxspeed[1];
453  status = arg->status | 6;
454  arg->medium = speed;
455  if ( speed == 113 )
456  v8 = status ^ 4;
457  else
458  v8 = status ^ 2;
459  arg->status = v8 | 0xC00;
460  CpuResumeIntr(state);
461  }
462  acd_done((struct acd *)atapi, arg, v4);
463 }
464 
465 int acd_getspeed(struct acd *acd, int maxspeed)
466 {
467  acAtapiDone done;
468 
469  if ( acd == 0 )
470  {
471  return -22;
472  }
473  done = (acAtapiDone)acd_getspeed_done;
474  if ( maxspeed )
475  done = (acAtapiDone)acd_getmaxspeed_done;
476  return acd_mode_sense(acd, 42, &Acdc.speed, 28, done, "getspeed");
477 }
478 
479 int acd_setspeed(struct acd *acd, int speed)
480 {
481  int v3;
482  int ospeed;
483  union
484  {
485  struct
486  {
487  acUint8 opcode;
488  acUint8 lun;
489  acUint8 speed[2];
490  // cppcheck-suppress unusedStructMember
491  acUint8 padding[8];
492  };
493  acAtapiPacketData pkt;
494  } u;
495  acSpl state;
496 
497  v3 = speed;
498  if ( speed < 0 )
499  return -22;
500  CpuSuspendIntr(&state);
501  if ( (Acdc.status & 0x400) != 0 )
502  ospeed = (Acdc.speed.mc_speed[0] << 8) + Acdc.speed.mc_speed[1];
503  else
504  ospeed = -1;
505  CpuResumeIntr(state);
506  if ( v3 > 0xFFFF )
507  v3 = 0xFFFF;
508  if ( v3 == ospeed )
509  return 0;
510  memset(&u, 0, sizeof(u));
511  u.opcode = 0xbb;
512  u.lun = 0;
513  u.speed[0] = (v3 & 0xFF00) >> 8;
514  u.speed[1] = v3;
515  return acd_request_in(acd, 2, &u.pkt, 0, 0, 0, "setspeed");
516 }
517 
518 static void acd_timer_done(acAtapiT atapi, struct acd_softc *arg, int ret)
519 {
520  int v4;
521  acSpl state;
522 
523  v4 = ret;
524  if ( ret >= 0 )
525  {
526  acCdvdsifId h_mtype;
527  acUint32 status;
528  int status_v3;
529 
530  CpuSuspendIntr(&state);
531  h_mtype = arg->timer.md_h.h_mtype;
532  status = arg->status | 6;
533  arg->medium = h_mtype;
534  if ( h_mtype == 113 )
535  status_v3 = status ^ 4;
536  else
537  status_v3 = status ^ 2;
538  arg->status = status_v3 | 0x900;
539  v4 = arg->timer.md_timer & 0xF;
540  CpuResumeIntr(state);
541  }
542  acd_done((struct acd *)atapi, arg, v4);
543 }
544 
545 int acd_gettimer(struct acd *acd)
546 {
547  if ( !acd )
548  return -22;
549  return acd_mode_sense(acd, 13, &Acdc.timer, 16, (acAtapiDone)acd_timer_done, "gettimer");
550 }
551 
552 int acd_settimer(struct acd *acd, int time)
553 {
554  char v3;
555  int acdc;
556  int state;
557 
558  v3 = time;
559  if ( acd == 0 )
560  {
561  return -22;
562  }
563  if ( (Acdc.status & 0x100) == 0 )
564  {
565  return -61;
566  }
567  CpuSuspendIntr(&state);
568  Acdc.timer.md_timer = v3 & 0xF;
569  acdc = ((Acdc.timer.md_h.h_len[0] << 8) + Acdc.timer.md_h.h_len[1] + 2);
570  CpuResumeIntr(state);
571  return acd_mode_select(acd, &Acdc.timer, acdc, (acAtapiDone)acd_timer_done, "settimer");
572 }
573 
574 int acd_ready(struct acd *acd)
575 {
577 
578  if ( !acd )
579  return -22;
580  memset(&v2, 0, sizeof(v2));
581  return acd_request_in(acd, 2, &v2, 0, 0, 0, "ready");
582 }
583 
584 int acd_readcapacity()
585 {
586  int ret;
587  struct acd acd_data;
588  struct atapi_read_capacity capacity;
589  union
590  {
591  struct
592  {
593  acUint8 opcode;
594  acUint8 lun;
595  // cppcheck-suppress unusedStructMember
596  acUint8 padding1[10];
597  };
598  acAtapiPacketData pkt;
599  } u;
600 
601  acd_setup(&acd_data, 0, 0, 5000000);
602  memset(&u, 0, sizeof(u));
603  u.opcode = 0x25;
604  u.lun = 0;
605  ret = acd_request_in(&acd_data, 2, &u.pkt, &capacity, 8, 0, "readcapacity");
606  if ( ret >= 0 )
607  {
608  unsigned int val;
609 
610  val = *(unsigned int *)capacity.lba;
611  return (val << 24) + ((val & 0xFF00) << 8) + ((val >> 8) & 0xFF00) + ((val >> 24) & 0xFF);
612  }
613  return ret;
614 }
615 
616 int acd_delay()
617 {
618  iop_sys_clock_t t;
619  u32 s;
620  u32 us;
621 
622  GetSystemTime(&t);
623  SysClock2USec(&t, &s, &us);
624  if ( s >= 0xD )
625  return 0;
626  return 1000000 * (13 - s) - us;
627 }
628 
629 int acd_getsense()
630 {
631  return Acdc.sense;
632 }
633 
634 acCdvdsifId acd_gettray()
635 {
636  if ( (Acdc.status & 8) != 0 )
637  return 3;
638  if ( (Acdc.status & 2) != 0 )
639  return 1;
640  return (Acdc.status >> 1) & 2;
641 }
642 
643 struct acd *acd_setup(struct acd *acd, acd_done_t done, void *arg, int tmout)
644 {
645  if ( acd )
646  {
647  acd->c_done = done;
648  acd->c_arg = arg;
649  acd->c_thid = 0;
650  acd->c_tmout = tmout;
651  if ( !tmout )
652  acd->c_tmout = 5000000;
653  }
654  return acd;
655 }
656 
657 int acd_sync(struct acd *acd, int nblocking, int *resultp)
658 {
659  int ret;
660  acSpl state;
661 
662  CpuSuspendIntr(&state);
663  ret = -11;
664  if ( !acd->c_thid )
665  {
666  int v7;
667 
668  v7 = acAtapiStatus(&acd->c_atapi);
669  ret = v7;
670  if ( v7 > 0 )
671  {
672  ret = 0;
673  acd->c_thid = GetThreadId();
674  }
675  else if ( v7 == 0 )
676  {
677  ret = 1;
678  }
679  }
680  CpuResumeIntr(state);
681  if ( !(ret | nblocking) )
682  {
683  ret = 1;
684  SleepThread();
685  }
686  if ( ret > 0 && resultp )
687  {
688  *resultp = acd->c_thid;
689  }
690  return ret;
691 }
692 
693 static void acd_ata_done(acAtaT ata, void *arg, int ret)
694 {
695  int thid;
696  struct acd_ata *acdata;
697 
698  (void)arg;
699  acdata = (struct acd_ata *)ata;
700  thid = acdata->a_thid;
701  acdata->a_result = ret;
702  if ( thid )
703  WakeupThread(thid);
704 }
705 
706 int acd_ata_request(int flag, acAtaCommandT cmd, int items, acAtaDone done, char *name)
707 {
708  int ret;
709  struct acd_ata acdata;
710 
711  (void)name;
712  acAtaSetup(&acdata.a_ata, done ? done : acd_ata_done, 0, 0x4C4B40u);
713  // cppcheck-suppress unreadVariable
714  acdata.a_thid = GetThreadId();
715  acdata.a_result = 0;
716  ret = acAtaRequest(&acdata.a_ata, flag, cmd, items, 0, 0);
717  if ( ret < 0 )
718  {
719  return ret;
720  }
721  SleepThread();
722  return acdata.a_result;
723 }
724 
725 static void acd_getstatus_done(acAtaT ata, void *arg, int ret)
726 {
727  int thid;
728  struct acd_ata *acdata;
729  (void)arg;
730  acdata = (struct acd_ata *)ata;
731  if ( ret >= 0 )
732  ret = *(acUint8 *)acAtaReply(&acdata->a_ata);
733  thid = acdata->a_thid;
734  acdata->a_result = ret;
735  if ( thid )
736  WakeupThread(thid);
737 }
738 
739 int acd_getstatus()
740 {
741  acAtaCommandData v1[4];
742 
743  v1[1] = ATA_C_CHECK_POWER_MODE | 0x700;
744  v1[0] = (Acdc.drive & 0xFF) | 0x2600;
745  return acd_ata_request(Acdc.drive | 2, v1, 2, acd_getstatus_done, "getstatus");
746 }
747 
748 static int acd_setfeatures(int feature, int value)
749 {
750  acAtaCommandData v3[4];
751 
752  v3[2] = (value & 0xFF) | 0x200;
753  v3[1] = (feature & 0xFF) | 0x100;
754  v3[3] = 2031;
755  v3[0] = (Acdc.drive & 0xFF) | 0x600;
756  return acd_ata_request(Acdc.drive | 2, v3, 4, 0, "setfeatures");
757 }
758 
759 int acd_setdma(acCdvdsifId dma)
760 {
761  acCdvdsifId v1;
762  int mode;
763  int ret;
764  int ret_v3;
765 
766  v1 = dma;
767  mode = dma;
768  if ( !dma )
769  {
770  Acdc.dma = AC_CDVDSIF_ID_NOP;
771  return 0;
772  }
773  if ( dma == 32 )
774  {
775  mode = 18;
776  ret_v3 = 0x40000;
777  while ( mode >= 0 )
778  {
779  if ( (Acdc.dmamap & ret_v3) != 0 )
780  break;
781  mode--;
782  ret_v3 = 1 << mode;
783  }
784  v1 = mode;
785  if ( mode < 0 )
786  return -134;
787  }
788  if ( (Acdc.dmamap & (1 << v1)) == 0 )
789  {
790  return -134;
791  }
792  if ( (unsigned int)v1 < AC_CDVDSIF_ID_PAUSES )
793  {
794  if ( (unsigned int)v1 < AC_CDVDSIF_ID_STOP )
795  {
796  if ( (unsigned int)v1 >= AC_CDVDSIF_ID_PAUSE )
797  mode = v1 + 8;
798  }
799  else
800  {
801  mode = v1 + 16;
802  }
803  }
804  else
805  {
806  mode = v1 + 40;
807  }
808  ret = acd_setfeatures(3, mode);
809  if ( ret < 0 )
810  {
811  return ret;
812  }
813  ret = acd_setfeatures(102, 0);
814  if ( ret < 0 )
815  {
816  return ret;
817  }
818  Acdc.dma = v1;
819  return v1;
820 }
821 
822 acCdvdsifId acd_getdma()
823 {
824  return Acdc.dma;
825 }
826 
827 static int acd_identify(int drive)
828 {
829  int flag;
830  int ret;
831  acUint16 ident[256];
832  struct acd_ata acdata;
833  acAtaCommandData cmd[2];
834 
835  flag = 16 * (drive != 0);
836  cmd[0] = flag | 0x600;
837  cmd[1] = ATA_C_IDENTIFY_PACKET_DEVICE | 0x700;
838  acAtaSetup(&acdata.a_ata, acd_ata_done, 0, 0x4C4B40u);
839  // cppcheck-suppress unreadVariable
840  acdata.a_thid = GetThreadId();
841  acdata.a_result = 0;
842  ret = acAtaRequest(&acdata.a_ata, flag | 2, cmd, 2, ident, 512);
843  if ( ret >= 0 )
844  {
845  SleepThread();
846  ret = acdata.a_result;
847  }
848  if ( ret < 0 )
849  {
850  return ret;
851  }
852  if ( (ident[0] & 0xFF00) != 0x8500 )
853  return -6;
854  return ((ident[62] & 0xFF) << 8) | ((ident[63] & 0xFF) << 16) | ((ident[88] & 0xFF) << 24);
855 }
856 
857 static int acd_softreset(int drive)
858 {
859  (void)drive;
860 
861  return 0;
862 }
863 
864 int acd_module_status()
865 {
866  int ret;
867  int state;
868 
869  CpuSuspendIntr(&state);
870  ret = 0;
871  if ( (Acdc.status & 1) != 0 )
872  {
873  ret = 1;
874  if ( Acdc.active > 0 )
875  ret = 2;
876  }
877  CpuResumeIntr(state);
878  return ret;
879 }
880 
881 int acd_module_start(int argc, char **argv)
882 {
883  int ret;
884  int drive;
885  int ret_v2;
886 
887  (void)argc;
888  (void)argv;
889  ret = acd_module_status();
890  drive = 0;
891  if ( ret )
892  {
893  return ret;
894  }
895  while ( 1 )
896  {
897  acd_softreset(drive);
898  ret_v2 = acd_identify(drive);
899  if ( ret_v2 >= 0 )
900  break;
901  ++drive;
902  ret = -6;
903  if ( drive >= 2 )
904  return ret;
905  }
906  if ( drive )
907  Acdc.drive = 16;
908  else
909  Acdc.drive = 0;
910  Acdc.status = 1;
911  Acdc.medium = -1;
912  Acdc.dmamap = ret_v2;
913  acd_setdma((acCdvdsifId)32);
914  return 0;
915 }
916 
917 int acd_module_stop()
918 {
919  int ret;
920 
921  ret = acd_module_status();
922  if ( ret )
923  {
924  return ret;
925  }
926  Acdc.status = 0;
927  return 0;
928 }
929 
930 int acd_module_restart(int argc, char **argv)
931 {
932  (void)argc;
933  (void)argv;
934 
935  return -88;
936 }
acd_softc
Definition: accdvd_internal.h:274
acd
Definition: accdvd_internal.h:24
ac_atapi_pkt
Definition: acata.h:57
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
ac_atapi
Definition: acata.h:67
atapi_read_capacity
Definition: accdvd_internal.h:267
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
atahw.h
acd_ata
Definition: accdvd_internal.h:336
ac_ata
Definition: acata.h:45
_iop_sys_clock
Definition: thbase.h:87