11#include "acata_internal.h"
15static int atapi_dma_xfer(
acDmaT dma,
int intr, acDmaOp op);
16static void atapi_dma_done(
acDmaT dma);
17static void atapi_dma_error(
acDmaT dma,
int intr, acDmaState state,
int result);
18static int atapi_ops_command(
struct ac_ata_h *atah,
int cmdpri,
int pri);
19static void atapi_ops_done(
struct ac_ata_h *atah,
int result);
20static int atapi_ops_error(
struct ac_ata_h *atah,
int ret);
22static acDmaOpsData ops_8_0 = {&atapi_dma_xfer, &atapi_dma_done, &atapi_dma_error};
23static struct ac_ata_ops ops_48 = {&atapi_ops_command, &atapi_ops_done, &atapi_ops_error};
25static int atapi_dma_xfer(
acDmaT dma,
int intr, acDmaOp op)
31 if ( dmatmp->ad_state == 31 )
33 dmatmp->ad_result = dmatmp->ad_atapi->ap_h.a_size;
34 return op(dma, (
void *)0xB6000000, dmatmp->ad_atapi->ap_h.a_buf, dmatmp->ad_atapi->ap_h.a_size);
36 thid = dmatmp->ad_thid;
45static void atapi_dma_done(
acDmaT dma)
51 thid = dmatmp->ad_thid;
52 dmatmp->ad_state = 127;
57static void atapi_dma_error(
acDmaT dma,
int intr, acDmaState state,
int result)
63 thid = dmatmp->ad_thid;
64 dmatmp->ad_state = 1023;
65 dmatmp->ad_result = result;
73 Kprintf(
"acata:P:dma_error: state=%d ret=%d\n", state, result);
84 *((
volatile acUint16 *)0xB6050000) = 0;
85 *((
volatile acUint16 *)0xB6040000) = 64;
86 *((
volatile acUint16 *)0xB6060000) = flag & 0x10;
87 *((
volatile acUint16 *)0xB6160000) = (flag & 2) ^ 2;
88 *((
volatile acUint16 *)0xB6010000) = flag & 1;
89 *((
volatile acUint16 *)0xB6070000) = 160;
93 while ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_BUSY) != 0 )
97 printf(
"acata:P:wait: TIMEDOUT\n");
106 printf(
"acata:P:packet_send: TIMEDOUT\n");
110 while ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_DRQ) != 0 )
115 *((
volatile acUint16 *)0xB6000000) = pkt->u_h[0];
121static int atapi_pio_read(acAtaReg atareg, acUint16 *buf,
int count,
int flag)
143 sr_v5 = *((
volatile acUint16 *)0xB6070000);
144 while ( (sr_v5 & ATA_STAT_BUSY) != 0 )
146 xlen = *((
volatile acUint16 *)0xB6070000);
152 xlen = *((
volatile acUint16 *)0xB6160000);
154 while ( (sr_v5 & 0x80) != 0 )
157 if ( SleepThread() != 0 )
159 sr_v5 = *((
volatile acUint16 *)0xB6160000);
164 if ( (sr_v5 & 8) == 0 )
166 xlen_v6 = (*((
volatile acUint16 *)0xB6050000) << 8) + *((
volatile acUint16 *)0xB6040000);
167 drop = xlen_v6 - rest;
168 if ( rest >= xlen_v6 )
173 xlen_v8 = (xlen_v6 + 1) / 2 - 1;
174 while ( xlen_v8 >= 0 )
177 *buf++ = *((
volatile acUint16 *)0xB6000000);
180 for ( drop_v10 = sr_v9 / 2 - 1; drop_v10 >= 0; --drop_v10 )
183 if ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_BUSY) == 0 )
191static int atapi_ops_command(
struct ac_ata_h *atah,
int cmdpri,
int pri)
201 if ( (flag & 1) == 0 )
211 dma = acDmaSetup(&dma_data.ad_dma, &ops_8_0, 4, 64, flag & 4);
212 dma_data.ad_result = 0;
214 dma_data.ad_thid = GetThreadId();
216 dma_data.ad_atapi = atapi;
217 dma_data.ad_state = 0;
218 v8 = acDmaRequest(dma);
222 printf(
"acata:P:dma_wait: error %d\n", v8);
232 ret_v5 = dma_data.ad_state;
235 if ( (
int)ret_v5 > 0 )
242 if ( flg == 0 && SleepThread() )
246 printf(
"acata:P:dma_wait: TIMEDOUT %d\n", ret_v5);
247 acDmaCancel(&dma_data.ad_dma, -116);
259 ChangeThreadPriority(0, cmdpri);
260 ret_v5 = atapi_packet_send((acAtaReg)0xB6000000, &atapi->ap_packet, flag);
264 if ( atah->a_state < 0x1FFu )
278 a_buf = (acUint16 *)atah->a_buf;
283 else if ( (flag & 1) != 0 )
285 dma_data.ad_state = 31;
286 ret_v5 = acDmaRequest(&dma_data.ad_dma);
294 v15 = (acUint16 *)atah->a_buf;
295 if ( (flag & 4) == 0 )
297 ret_v5 = atapi_pio_read((acAtaReg)0xB6000000, a_buf, atah->a_size, flag);
304 a_size = atah->a_size;
318 xlen = *((
volatile acUint16 *)0xB6160000);
319 sr_v14 = xlen & 0xFF;
320 while ( (sr_v14 & 0x80) != 0 )
323 if ( SleepThread() != 0 )
325 sr_v14 = *((
volatile acUint16 *)0xB6160000);
330 sr_v14 = *((
volatile acUint16 *)0xB6070000);
331 while ( (sr_v14 & ATA_STAT_BUSY) != 0 )
333 xlen = *((
volatile acUint16 *)0xB6070000);
334 sr_v14 = xlen & 0xFF;
340 if ( (sr_v14 & 8) == 0 )
342 ret_v5 = size - a_size;
345 xlen_v15 = (*((
volatile acUint16 *)0xB6050000) << 8) + *((
volatile acUint16 *)0xB6040000);
346 drop = xlen_v15 - a_size;
347 if ( a_size >= xlen_v15 )
352 xlen_v17 = (xlen_v15 + 1) / 2 - 1;
353 for ( sr_v18 = drop + 1; xlen_v17 >= 0; sr_v18 = drop + 1 )
355 *((
volatile acUint16 *)0xB6000000) = *v15;
359 for ( drop_v20 = sr_v18 / 2 - 1; drop_v20 >= 0; --drop_v20 )
360 *((
volatile acUint16 *)0xB6000000) = 0;
362 if ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_BUSY) == 0 )
364 ret_v5 = size - a_size;
372 ChangeThreadPriority(0, pri);
375 if ( atah->a_state < 0x1FFu )
386 if ( (flag & 1) == 0 )
391 if ( (flag & 2) != 0 )
393 while ( (*((
volatile acUint16 *)0xB6160000) & (ATA_STAT_BUSY|ATA_STAT_ERR)) == ATA_STAT_BUSY )
407 while ( (*((
volatile acUint16 *)0xB6070000) & (ATA_STAT_BUSY|ATA_STAT_ERR)) == ATA_STAT_BUSY )
419 printf(
"acata:C:io_done: TIMEDOUT\n");
433 v30 = *((
volatile acUint16 *)0xB6160000) & 1;
434 if ( v30 || ret_v23 >= 511 )
437 "acata:P:dma_iowait: TIMEDOUT %04x:%02x:%02x\n",
439 *((
volatile acUint16 *)0xB6160000),
440 *((
volatile acUint16 *)0xB6010000));
441 if ( ret_v23 < 1023 )
442 acDmaCancel(&dma_data.ad_dma, -116);
448 ret_v23 = dma_data.ad_state;
449 if ( (*((
volatile acUint16 *)0xB6160000) & 0x80) == 0 && (
int)dma_data.ad_state >= 64 )
451 ad_result = dma_data.ad_result;
457 if ( dma_data.ad_state == 31 )
465 if ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_ERR) != 0 )
466 return -((*((
volatile acUint16 *)0xB6070000) << 8) + *((
volatile acUint16 *)0xB6010000));
467 if ( atah->a_state >= 0x1FFu )
475static void atapi_ops_done(
struct ac_ata_h *atah,
int result)
481 ap_done = atapi->ap_done;
483 ap_done(atapi, atah->a_arg, result);
486static int atapi_ops_error(
struct ac_ata_h *atah,
int ret)
508 if ( (*((
volatile acUint16 *)0xB6070000) & ATA_STAT_ERR) == 0 )
510 memset(&sense, 0,
sizeof(sense));
511 memset(&u, 0,
sizeof(u));
515 u.lun = atapi->ap_packet.u_b[1];
516 *((
volatile acUint16 *)0xB6160000) = (flag & 2) ^ 2;
517 *((
volatile acUint16 *)0xB6010000) = 0;
518 v3 = atapi_packet_send((acAtaReg)0xB6000000, &u.pkt, flag);
528 v4 = atapi_pio_read((acAtaReg)0xB6000000, (acUint16 *)&sense,
sizeof(sense), flag);
535 if ( (flag & 2) != 0 )
537 while ( (*((
volatile acUint16 *)0xB6160000) & 0x81) == ATA_STAT_BUSY )
551 while ( (*((
volatile acUint16 *)0xB6070000) & 0x81) == ATA_STAT_BUSY )
563 printf(
"acata:C:io_done: TIMEDOUT\n");
582 return -((sense.s_key << 16) | (sense.s_asc << 8) | sense.s_ascq);
592 atapi->ap_h.a_ops = &ops_48;
593 atapi->ap_h.a_arg = arg;
594 atapi->ap_h.a_tmout = tmout;
595 atapi->ap_h.a_state = 0;
596 atapi->ap_h.a_flag = 0;
597 atapi->ap_done = done;
605 if ( !atapi || !pkt )
609 atapi->ap_h.a_flag = flag;
610 atapi->ap_packet.u_w[0] = pkt->u_w[0];
611 atapi->ap_packet.u_w[1] = pkt->u_w[1];
612 atapi->ap_packet.u_w[2] = pkt->u_w[2];
613 atapi->ap_h.a_buf = buf;
614 atapi->ap_h.a_size = size;
615 return ata_request(&atapi->ap_h, WakeupThread);
621 if ( !atapi || !pkt )
625 atapi->ap_h.a_flag = flag;
626 atapi->ap_packet.u_w[0] = pkt->u_w[0];
627 atapi->ap_packet.u_w[1] = pkt->u_w[1];
628 atapi->ap_packet.u_w[2] = pkt->u_w[2];
629 atapi->ap_h.a_buf = buf;
630 atapi->ap_h.a_size = size;
631 return ata_request(&atapi->ap_h, iWakeupThread);
642 state = atapi->ap_h.a_state;
643 if ( (
unsigned int)(state - 1) >= 0x7E )
u32 count
start sector of fragmented bd/file