11#include "acata_internal.h"
14static int ata_dma_xfer(
acDmaT dma,
int intr, acDmaOp op);
15static void ata_dma_done(
acDmaT dma);
16static void ata_dma_error(
acDmaT dma,
int intr, acDmaState state,
int result);
17static int ata_ops_command(
struct ac_ata_h *atah,
int cmdpri,
int pri);
18static void ata_ops_done(
struct ac_ata_h *atah,
int result);
20static acDmaOpsData ops_8 = {&ata_dma_xfer, &ata_dma_done, &ata_dma_error};
21static struct ac_ata_ops ops_37 = {&ata_ops_command, &ata_ops_done, NULL};
23static int ata_dma_xfer(
acDmaT dma,
int intr, acDmaOp op)
29 if ( dmatmp->ad_state == 31 )
31 dmatmp->ad_result = dmatmp->ad_ata->ac_h.a_size;
32 return op(dma, (
void *)0xB6000000, dmatmp->ad_ata->ac_h.a_buf, dmatmp->ad_ata->ac_h.a_size);
34 thid = dmatmp->ad_thid;
43static void ata_dma_done(
acDmaT dma)
50 thid = dmatmp->ad_thid;
51 dmatmp->ad_state = 127;
56static void ata_dma_error(
acDmaT dma,
int intr, acDmaState state,
int result)
62 thid = dmatmp->ad_thid;
63 dmatmp->ad_state = 1023;
64 dmatmp->ad_result = result;
72 Kprintf(
"acata:A:dma_error: state=%d ret=%d\n", state, result);
75static int ata_ops_command(
struct ac_ata_h *atah,
int cmdpri,
int pri)
79 const acAtaCommandData *cmd;
86 acAtaCommandData *cmd_v36;
94 if ( atah->a_state >= 0x1FFu )
99 if ( (flag & 1) != 0 )
104 dma = acDmaSetup(&dma_data.ad_dma, &ops_8, 4, 8, flag & 4);
105 dma_data.ad_result = 0;
107 dma_data.ad_thid = GetThreadId();
109 dma_data.ad_ata = ata;
110 dma_data.ad_state = 0;
111 ret_v3 = acDmaRequest(dma);
114 printf(
"acata:A:dma_wait: error %d\n", ret_v3);
121 ret_v5 = dma_data.ad_state;
124 if ( (
int)ret_v5 <= 0 )
126 printf(
"acata:A:dma_wait: TIMEDOUT %d\n", ret_v5);
127 acDmaCancel(&dma_data.ad_dma, -116);
142 ChangeThreadPriority(0, cmdpri);
143 cmd = ata->ac_command;
145 flag_v8 = atah->a_flag;
146 *((
volatile acUint16 *)0xB6060000) = flag_v8 & 0x10;
147 *((
volatile acUint16 *)0xB6160000) = (flag_v8 & 2) ^ 2;
148 *((
volatile acUint16 *)0xB6010000) = 0;
154 *(acUint16 *)(((2 * ((data >> 8) & 8) + ((data >> 8) & 7)) << 16) + 0xB6000000) = data & 0xFF;
156 if ( ((data >> 8) & 0xF) == 7 )
161 ChangeThreadPriority(0, pri);
163 if ( atah->a_state >= 0x1FFu )
170 if ( (flag_v8 & 1) != 0 )
172 dma_data.ad_state = 31;
173 acDmaRequest(&dma_data.ad_dma);
174 printf(
"acata:dma start\n");
180 a_buf = (acUint16 *)atah->a_buf;
181 if ( (flag_v8 & 4) != 0 )
185 a_size = atah->a_size;
186 while ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_BUSY) != 0 )
200 xlen_v15 = (
unsigned int)xlen >> 1;
201 xlen_v16 = xlen_v15 - 1;
202 while ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_DRQ) != 0 )
212 *((
volatile acUint16 *)0xB6000000) = ret_v17;
215 if ( (flag_v8 & 2) != 0 )
217 sr = *((
volatile acUint16 *)0xB6160000);
219 while ( (ret_v20 & 0x80) != 0 )
222 if ( SleepThread() != 0 )
224 ret_v20 = *((
volatile acUint16 *)0xB6160000);
229 ret_v20 = *((
volatile acUint16 *)0xB6070000);
230 while ( (ret_v20 & ATA_STAT_BUSY) != 0 )
232 sr = *((
volatile acUint16 *)0xB6070000);
238 if ( (ret_v20 & 8) == 0 )
247 buf_v23 = (acUint16 *)atah->a_buf;
257 if ( (flag_v8 & 2) != 0 )
259 sr_v25 = *((
volatile acUint16 *)0xB6160000);
260 sr_v25 = sr_v25 & 0xFF;
261 while ( (sr_v25 & 0x80) != 0 )
266 sr_v25 = *((
volatile acUint16 *)0xB6160000);
271 sr_v25 = *((
volatile acUint16 *)0xB6070000);
272 while ( (sr_v25 & ATA_STAT_BUSY) != 0 )
274 sr_v25 = *((
volatile acUint16 *)0xB6070000);
275 sr_v25 = sr_v25 & 0xFF;
284 xlen_v28 = (
unsigned int)xlen_v27 >> 1;
285 if ( (sr_v25 & 1) != 0 )
287 (void)(*((
volatile acUint16 *)0xB6070000) & ATA_STAT_BUSY);
288 xlen_v30 = xlen_v28 - 1;
289 while ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_DRQ) != 0 )
293 *buf_v23 = *((
volatile acUint16 *)0xB6000000);
298 ret_v29 = *((
volatile acUint16 *)0xB6070000) & ATA_STAT_BUSY;
306 ret_v22 = flag_v8 & 1;
316 v38 = *((
volatile acUint16 *)0xB6160000) & 1;
317 if ( v38 || state >= 511 )
320 "acata:A:dma_iowait: TIMEDOUT %04x:%02x:%02x\n",
322 *((
volatile acUint16 *)0xB6160000),
323 *((
volatile acUint16 *)0xB6010000));
325 acDmaCancel(&dma_data.ad_dma, -116);
331 state = dma_data.ad_state;
332 if ( (*((
volatile acUint16 *)0xB6160000) & 0x80) == 0 && (
int)dma_data.ad_state >= 64 )
334 ret = dma_data.ad_result;
340 if ( dma_data.ad_state == 31 )
350 while ( (*((
volatile acUint16 *)0xB6160000) & (ATA_STAT_BUSY|ATA_STAT_ERR)) == ATA_STAT_BUSY )
364 while ( (*((
volatile acUint16 *)0xB6070000) & (ATA_STAT_BUSY|ATA_STAT_ERR)) == ATA_STAT_BUSY )
376 printf(
"acata:C:io_done: TIMEDOUT\n");
383 sr_v34 = *((
volatile acUint16 *)0xB6070000);
384 if ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_ERR) != 0 )
385 return -((sr_v34 << 8) + *((
volatile acUint16 *)0xB6010000));
386 if ( atah->a_state < 0x1FFu )
395 cmd_v36 = ata->ac_command;
398 return -((sr_v34 << 8) + *((
volatile acUint16 *)0xB6010000));
400 for ( rest_v37 = 6; rest_v37 > 0; --rest_v37 )
402 if ( (((
int)*cmd_v36 >> 12) & 0xF) == 0 )
405 ((((int)*cmd_v36 >> 12) & 0xF) << 12)
406 | ((*(acUint16 *)(((2 * (((
int)*cmd_v36 >> 12) & 8) + (((
int)*cmd_v36 >> 12) & 7)) << 16) + 0xB6000000)) & 0xFF);
412static void ata_ops_done(
struct ac_ata_h *atah,
int result)
418 ac_done = ata->ac_done;
420 ac_done(ata, atah->a_arg, result);
423acAtaT acAtaSetup(
acAtaData *ata, acAtaDone done,
void *arg,
unsigned int tmout)
427 ata->ac_h.a_ops = &ops_37;
428 ata->ac_h.a_arg = arg;
429 ata->ac_h.a_tmout = tmout;
430 ata->ac_h.a_state = 0;
431 ata->ac_h.a_flag = 0;
437acAtaCommandData *acAtaReply(
acAtaT ata)
441 return ata->ac_command;
444int acAtaRequest(
acAtaT ata,
int flag, acAtaCommandData *cmd,
int item,
void *buf,
int size)
447 const acAtaCommandData *v8;
450 flag = (flag | 8) ^ 8;
455 if ( (
unsigned int)item >= 7 )
460 ata->ac_h.a_flag = flag;
462 v9 = (
char *)ata + 2 * v7;
466 *((acUint16 *)v9 + 18) = *v8--;
469 ata->ac_h.a_buf = buf;
470 ata->ac_h.a_size = size;
471 return ata_request(&ata->ac_h, WakeupThread);
474int acAtaRequestI(
acAtaT ata,
int flag, acAtaCommandData *cmd,
int item,
void *buf,
int size)
477 const acAtaCommandData *v8;
480 flag = (flag | 8) ^ 8;
485 if ( (
unsigned int)item >= 7 )
490 ata->ac_h.a_flag = flag;
492 v9 = (
char *)ata + 2 * v7;
496 *((acUint16 *)v9 + 18) = *v8--;
499 ata->ac_h.a_buf = buf;
500 ata->ac_h.a_size = size;
501 return ata_request(&ata->ac_h, iWakeupThread);
504int acAtaStatus(
acAtaT ata)
512 state = ata->ac_h.a_state;
513 if ( (
unsigned int)(state - 1) >= 0x7E )
u32 count
start sector of fragmented bd/file