PS2SDK
PS2 Homebrew Libraries
acatad.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 <atad.h>
12 #include <atahw.h>
13 #include <irx_imports.h>
14 
15 #define MODNAME "ARCADE_ATAD_driver"
16 IRX_ID(MODNAME, 1, 80);
17 // Text section hash:
18 // 7320ef1d104cc8a53b66846111f81621
19 
20 extern struct irx_export_table _exp_atad;
21 
23 {
24  int thid;
25  int ret;
26 };
27 
28 #define sceAtaEntry _start
29 
30 static ata_devinfo_t g_devinfo;
31 static u16 g_sectorbuf[256];
32 
33 void on_request_done(acAtaT ata, struct acatad_request_data *arg, int ret)
34 {
35  int thid;
36 
37  (void)ata;
38  thid = arg->thid;
39  arg->ret = ret;
40  arg->thid = 0;
41  if ( thid )
42  WakeupThread(thid);
43 }
44 
45 int do_request(int flag, acAtaCommandData *cmd, int item, void *buf, int size)
46 {
47  acAtaData *ata_ptr;
48  int result;
49  acAtaData ata;
50  struct acatad_request_data reqd;
51 
52  ata_ptr = acAtaSetup(&ata, (acAtaDone)on_request_done, &reqd, 5000000u);
53  reqd.ret = 0;
54  reqd.thid = GetThreadId();
55  result = acAtaRequest(ata_ptr, flag, cmd, item, buf, size);
56  if ( result < 0 )
57  {
58  return result;
59  }
60  while ( reqd.thid )
61  SleepThread();
62  return reqd.ret;
63 }
64 
65 int do_identify(int device, u32 *total_sectors)
66 {
67  int devident;
68  int err;
69  int model_no_i;
70  acAtaCommandData cmd[4];
71 
72  devident = (device != 0) << 4;
73  memset(g_sectorbuf, 0, sizeof(g_sectorbuf));
74  cmd[0] = devident | 0x600;
75  cmd[1] = ATA_C_IDENTIFY_DEVICE | 0x700;
76  err = do_request(devident | 2, cmd, 2, g_sectorbuf, 512);
77  model_no_i = 27;
78  if ( err < 0 )
79  {
80  if ( err != -6 )
81  {
82  printf("%d:identify: unexpected error %d\n", device, err);
83  return err;
84  }
85  return 0;
86  }
87  while ( model_no_i < 47 )
88  {
89  g_sectorbuf[model_no_i] = ((g_sectorbuf[model_no_i] & 0xFF00) >> 8) | (g_sectorbuf[model_no_i] << 8);
90  model_no_i += 1;
91  }
92  g_sectorbuf[47] = 0;
93  *total_sectors = g_sectorbuf[60] + (g_sectorbuf[61] << 16);
94  printf("%d:identify:%d: %s\n", device, err, (const char *)&g_sectorbuf[27]);
95  return 1;
96 }
97 
98 int do_setfeatures(int device, u8 features)
99 {
100  int err;
101  acAtaCommandData cmd[4];
102 
103  cmd[0] = features | 0x200;
104  cmd[1] = 0x03 | 0x100; // Set transfer mode
105  cmd[2] = ATA_C_SET_FEATURES | 0x700;
106  err = do_request(((device != 0) << 4) | 0x42, cmd, 3, 0, 0);
107  if ( err < 0 )
108  {
109  if ( err != -6 )
110  {
111  printf("%d:setfeatures: unexpected error %d\n", device, err);
112  return err;
113  }
114  return 0;
115  }
116  return 1;
117 }
118 
119 int do_dma_xfer_read(int device, u32 lba, void *buf, u32 nsectors)
120 {
121  int devident;
122  int err;
123  int busywait_tmp;
124  acAtaCommandData cmd[8];
125 
126  devident = (device != 0) << 4;
127  cmd[0] = (nsectors & 0xFF) | 0x200;
128  cmd[1] = (lba & 0xFF) | 0x300;
129  cmd[2] = ((lba & 0xFF00) >> 8) | 0x400;
130  cmd[3] = ((lba & 0xFF0000) >> 16) | 0x500;
131  cmd[4] = devident | 0x40 | ((lba & 0xFF000000) >> 24) | 0x600;
132  cmd[5] = ATA_C_READ_DMA_WITHOUT_RETRIES | 0x700;
133  err = do_request(devident | 0x43, cmd, 6, buf, nsectors << 9);
134  if ( err < 0 )
135  {
136  if ( err != -6 )
137  {
138  printf("%d:read: unexpected error %d\n", device, err);
139  return err;
140  }
141  return 0;
142  }
143  busywait_tmp = 0;
144  while ( busywait_tmp++ < (int)(nsectors + 32) )
145  ;
146  return 1;
147 }
148 
149 int do_dma_xfer_write(int device, u32 lba, void *buf, u32 nsectors)
150 {
151  int devident;
152  int err;
153  int busywait_tmp;
154  acAtaCommandData cmd[8];
155 
156  devident = (device != 0) << 4;
157  cmd[0] = (nsectors & 0xFF) | 0x200;
158  cmd[1] = (lba & 0xFF) | 0x300;
159  cmd[2] = ((lba & 0xFF00) >> 8) | 0x400;
160  cmd[3] = ((lba & 0xFF0000) >> 16) | 0x500;
161  cmd[4] = devident | 0x40 | ((lba & 0xFF000000) >> 24) | 0x600;
162  cmd[5] = ATA_C_WRITE_DMA | 0x700;
163  err = do_request(devident | 0x47, cmd, 6, buf, nsectors << 9);
164  if ( err < 0 )
165  {
166  if ( err != -6 )
167  {
168  printf("%d:read: unexpected error %d\n", device, err);
169  return err;
170  }
171  return 0;
172  }
173  busywait_tmp = 0;
174  while ( busywait_tmp++ < (int)(nsectors + 32) )
175  ;
176  return 1;
177 }
178 
179 int do_flushcache(int device)
180 {
181  int err;
182  acAtaCommandData cmd[4];
183 
184  cmd[0] = 0x200;
185  cmd[1] = 0x103;
186  cmd[2] = ATA_C_FLUSH_CACHE | 0x700;
187  err = do_request(((device != 0) << 4) | 0x42, cmd, 3, 0, 0);
188  if ( err < 0 )
189  {
190  if ( err != -6 )
191  {
192  printf("%d:flushcache: unexpected error %d\n", device, err);
193  return err;
194  }
195  return 0;
196  }
197  return 1;
198 }
199 
200 ata_devinfo_t *sceAtaInit(int device)
201 {
202  int probe_res;
203  int ident_err;
204  u32 total_sectors[2];
205 
206  probe_res = ata_probe((acAtaReg)0xB6000000);
207  g_devinfo.has_packet = 0;
208  g_devinfo.exists = device == probe_res - 1;
209  if ( device != probe_res - 1 )
210  {
211  g_devinfo.total_sectors = 0;
212  return &g_devinfo;
213  }
214  ident_err = do_identify(device, total_sectors);
215  if ( ident_err < 0 )
216  {
217  printf("identify error %d\n", ident_err);
218  return 0;
219  }
220  do_setfeatures(device, 0x22 /* MDMA2 */);
221  g_devinfo.security_status = 255;
222  g_devinfo.total_sectors = total_sectors[0];
223  printf("sceAtaInit %x %x %x\n", device, (unsigned int)g_devinfo.exists, (unsigned int)total_sectors[0]);
224  return &g_devinfo;
225 }
226 
227 int sceAtaSoftReset(void)
228 {
229  printf("sceAtaSoftReset\n");
230  while ( 1 )
231  ;
232 }
233 
234 int sceAtaExecCmd(
235  void *buf, u32 blkcount, u16 feature, u16 nsector, u16 sector, u16 lcyl, u16 hcyl, u16 select, u16 command)
236 {
237  (void)buf;
238  (void)blkcount;
239  (void)feature;
240  (void)nsector;
241  (void)sector;
242  (void)lcyl;
243  (void)hcyl;
244  (void)select;
245  (void)command;
246  printf("sceAtaExecCmd\n");
247  while ( 1 )
248  ;
249 }
250 
251 int sceAtaWaitResult(void)
252 {
253  printf("sceAtaWaitResult\n");
254  while ( 1 )
255  ;
256 }
257 
258 int sceAtaGetError(void)
259 {
260  printf("sceAtaGetError\n");
261  while ( 1 )
262  ;
263 }
264 
265 int sceAtaDmaTransfer(int device, void *buf, u32 lba, u32 nsectors, int dir)
266 {
267  int err;
268 
269  if ( dir == 1 )
270  err = do_dma_xfer_write(device, lba, buf, nsectors);
271  else
272  err = do_dma_xfer_read(device, lba, buf, nsectors);
273  if ( err != 1 )
274  {
275  printf("dma error\n");
276  while ( 1 )
277  ;
278  }
279  return 0;
280 }
281 
282 int sceAtaSecuritySetPassword(int device, void *password)
283 {
284  (void)device;
285  (void)password;
286 
287  printf("sceAtaSecuritySetPassword\n");
288  while ( 1 )
289  ;
290 }
291 
292 int sceAtaSecurityUnLock(int device, void *password)
293 {
294  (void)device;
295  (void)password;
296 
297  printf("sceAtaSecurityUnLock\n");
298  return 0;
299 }
300 
301 int sceAtaSecurityEraseUnit(int device)
302 {
303  (void)device;
304 
305  printf("sceAtaSecurityEraseUnit\n");
306  while ( 1 )
307  ;
308 }
309 
310 int sceAtaIdle(int device, int period)
311 {
312  (void)device;
313  (void)period;
314 
315  printf("sceAtaIdle\n");
316  while ( 1 )
317  ;
318 }
319 
320 int sceAtaGetSceId(int device, void *data)
321 {
322  (void)device;
323  (void)data;
324 
325  printf("sceAtaGetSceId\n");
326  while ( 1 )
327  ;
328 }
329 
330 int sceAtaSmartReturnStatus(int device)
331 {
332  (void)device;
333 
334  printf("sceAtaSmartReturnStatus\n");
335  while ( 1 )
336  ;
337 }
338 
339 int sceAtaSmartSaveAttr(int device)
340 {
341  (void)device;
342 
343  printf("sceAtaSmartSaveAttr\n");
344  while ( 1 )
345  ;
346 }
347 
348 int sceAtaFlushCache(int device)
349 {
350  do_flushcache(device);
351  return 0;
352 }
353 
354 int sceAtaIdleImmediate(int device)
355 {
356  (void)device;
357 
358  printf("sceAtaIdleImmediate\n");
359  while ( 1 )
360  ;
361 }
362 
363 int sceAtaEntry()
364 {
365  if ( RegisterLibraryEntries(&_exp_atad) )
366  printf("atad: module already loaded\n");
367  printf("sceAtaEntry\n");
368  return 0;
369 }
370 
371 int sceAtaTerminate()
372 {
373  printf(" sceAtaTerminate\n");
374  return 0;
375 }
_ata_devinfo::has_packet
s32 has_packet
Definition: xatapi.c:43
_ata_devinfo
Definition: xatapi.c:40
atad.h
_ata_devinfo::security_status
u32 security_status
Definition: xatapi.c:45
_ata_devinfo::exists
s32 exists
Definition: xatapi.c:42
irx_export_table
Definition: irx.h:90
acatad_request_data
Definition: acatad.c:22
_ata_devinfo::total_sectors
u32 total_sectors
Definition: xatapi.c:44
atahw.h
ac_ata
Definition: acata.h:45