11#include "acata_internal.h"
13static int atapi_dma_xfer(
acDmaT dma,
int intr, acDmaOp op);
14static void atapi_dma_done(
acDmaT dma);
15static void atapi_dma_error(
acDmaT dma,
int intr, acDmaState state,
int result);
16static int atapi_ops_command(
struct ac_ata_h *atah,
int cmdpri,
int pri);
17static void atapi_ops_done(
struct ac_ata_h *atah,
int result);
18static int atapi_ops_error(
struct ac_ata_h *atah,
int ret);
20static acDmaOpsData ops_8_0 = {&atapi_dma_xfer, &atapi_dma_done, &atapi_dma_error};
21static struct ac_ata_ops ops_48 = {&atapi_ops_command, &atapi_ops_done, &atapi_ops_error};
23static int atapi_dma_xfer(
acDmaT dma,
int intr, acDmaOp op)
29 if ( dmatmp->ad_state == 31 )
31 dmatmp->ad_result = dmatmp->ad_atapi->ap_h.a_size;
32 return op(dma, (
void *)0xB6000000, dmatmp->ad_atapi->ap_h.a_buf, dmatmp->ad_atapi->ap_h.a_size);
34 thid = dmatmp->ad_thid;
43static void atapi_dma_done(
acDmaT dma)
49 thid = dmatmp->ad_thid;
50 dmatmp->ad_state = 127;
55static void atapi_dma_error(
acDmaT dma,
int intr, acDmaState state,
int result)
61 thid = dmatmp->ad_thid;
62 dmatmp->ad_state = 1023;
63 dmatmp->ad_result = result;
71 Kprintf(
"acata:P:dma_error: state=%d ret=%d\n", state, result);
82 *((
volatile acUint16 *)0xB6050000) = 0;
83 *((
volatile acUint16 *)0xB6040000) = 64;
84 *((
volatile acUint16 *)0xB6060000) = flag & 0x10;
85 *((
volatile acUint16 *)0xB6160000) = (flag & 2) ^ 2;
86 *((
volatile acUint16 *)0xB6010000) = flag & 1;
87 *((
volatile acUint16 *)0xB6070000) = 160;
91 while ( (*((
volatile acUint16 *)0xB6070000) & 0x80) != 0 )
95 printf(
"acata:P:wait: TIMEDOUT\n");
104 printf(
"acata:P:packet_send: TIMEDOUT\n");
108 while ( (*((
volatile acUint16 *)0xB6070000) & 8) != 0 )
113 *((
volatile acUint16 *)0xB6000000) = pkt->u_h[0];
119static int atapi_pio_read(acAtaReg atareg, acUint16 *buf,
int count,
int flag)
141 sr_v5 = *((
volatile acUint16 *)0xB6070000);
142 while ( (sr_v5 & 0x80) != 0 )
144 xlen = *((
volatile acUint16 *)0xB6070000);
150 xlen = *((
volatile acUint16 *)0xB6160000);
152 while ( (sr_v5 & 0x80) != 0 )
155 if ( SleepThread() != 0 )
157 sr_v5 = *((
volatile acUint16 *)0xB6160000);
162 if ( (sr_v5 & 8) == 0 )
164 xlen_v6 = (*((
volatile acUint16 *)0xB6050000) << 8) + *((
volatile acUint16 *)0xB6040000);
165 drop = xlen_v6 - rest;
166 if ( rest >= xlen_v6 )
171 xlen_v8 = (xlen_v6 + 1) / 2 - 1;
172 while ( xlen_v8 >= 0 )
175 *buf++ = *((
volatile acUint16 *)0xB6000000);
178 for ( drop_v10 = sr_v9 / 2 - 1; drop_v10 >= 0; --drop_v10 )
181 if ( (*((
volatile acUint16 *)0xB6070000) & 0x80) == 0 )
189static int atapi_ops_command(
struct ac_ata_h *atah,
int cmdpri,
int pri)
199 if ( (flag & 1) == 0 )
209 dma = acDmaSetup(&dma_data.ad_dma, &ops_8_0, 4, 64, flag & 4);
210 dma_data.ad_result = 0;
212 dma_data.ad_thid = GetThreadId();
214 dma_data.ad_atapi = atapi;
215 dma_data.ad_state = 0;
216 v8 = acDmaRequest(dma);
220 printf(
"acata:P:dma_wait: error %d\n", v8);
230 ret_v5 = dma_data.ad_state;
233 if ( (
int)ret_v5 > 0 )
240 if ( flg == 0 && SleepThread() )
244 printf(
"acata:P:dma_wait: TIMEDOUT %d\n", ret_v5);
245 acDmaCancel(&dma_data.ad_dma, -116);
257 ChangeThreadPriority(0, cmdpri);
258 ret_v5 = atapi_packet_send((acAtaReg)0xB6000000, &atapi->ap_packet, flag);
262 if ( atah->a_state < 0x1FFu )
276 a_buf = (acUint16 *)atah->a_buf;
281 else if ( (flag & 1) != 0 )
283 dma_data.ad_state = 31;
284 ret_v5 = acDmaRequest(&dma_data.ad_dma);
292 v15 = (acUint16 *)atah->a_buf;
293 if ( (flag & 4) == 0 )
295 ret_v5 = atapi_pio_read((acAtaReg)0xB6000000, a_buf, atah->a_size, flag);
302 a_size = atah->a_size;
316 xlen = *((
volatile acUint16 *)0xB6160000);
317 sr_v14 = xlen & 0xFF;
318 while ( (sr_v14 & 0x80) != 0 )
321 if ( SleepThread() != 0 )
323 sr_v14 = *((
volatile acUint16 *)0xB6160000);
328 sr_v14 = *((
volatile acUint16 *)0xB6070000);
329 while ( (sr_v14 & 0x80) != 0 )
331 xlen = *((
volatile acUint16 *)0xB6070000);
332 sr_v14 = xlen & 0xFF;
338 if ( (sr_v14 & 8) == 0 )
340 ret_v5 = size - a_size;
343 xlen_v15 = (*((
volatile acUint16 *)0xB6050000) << 8) + *((
volatile acUint16 *)0xB6040000);
344 drop = xlen_v15 - a_size;
345 if ( a_size >= xlen_v15 )
350 xlen_v17 = (xlen_v15 + 1) / 2 - 1;
351 for ( sr_v18 = drop + 1; xlen_v17 >= 0; sr_v18 = drop + 1 )
353 *((
volatile acUint16 *)0xB6000000) = *v15;
357 for ( drop_v20 = sr_v18 / 2 - 1; drop_v20 >= 0; --drop_v20 )
358 *((
volatile acUint16 *)0xB6000000) = 0;
360 if ( (*((
volatile acUint16 *)0xB6070000) & 0x80) == 0 )
362 ret_v5 = size - a_size;
370 ChangeThreadPriority(0, pri);
373 if ( atah->a_state < 0x1FFu )
384 if ( (flag & 1) == 0 )
389 if ( (flag & 2) != 0 )
391 while ( (*((
volatile acUint16 *)0xB6160000) & 0x81) == 128 )
405 while ( (*((
volatile acUint16 *)0xB6070000) & 0x81) == 128 )
417 printf(
"acata:C:io_done: TIMEDOUT\n");
431 v30 = *((
volatile acUint16 *)0xB6160000) & 1;
432 if ( v30 || ret_v23 >= 511 )
435 "acata:P:dma_iowait: TIMEDOUT %04x:%02x:%02x\n",
437 *((
volatile acUint16 *)0xB6160000),
438 *((
volatile acUint16 *)0xB6010000));
439 if ( ret_v23 < 1023 )
440 acDmaCancel(&dma_data.ad_dma, -116);
446 ret_v23 = dma_data.ad_state;
447 if ( (*((
volatile acUint16 *)0xB6160000) & 0x80) == 0 && (
int)dma_data.ad_state >= 64 )
449 ad_result = dma_data.ad_result;
455 if ( dma_data.ad_state == 31 )
463 if ( (*((
volatile acUint16 *)0xB6070000) & 1) != 0 )
464 return -((*((
volatile acUint16 *)0xB6070000) << 8) + *((
volatile acUint16 *)0xB6010000));
465 if ( atah->a_state >= 0x1FFu )
473static void atapi_ops_done(
struct ac_ata_h *atah,
int result)
479 ap_done = atapi->ap_done;
481 ap_done(atapi, atah->a_arg, result);
484static int atapi_ops_error(
struct ac_ata_h *atah,
int ret)
506 if ( (*((
volatile acUint16 *)0xB6070000) & 1) == 0 )
508 memset(&sense, 0,
sizeof(sense));
509 memset(&u, 0,
sizeof(u));
513 u.lun = atapi->ap_packet.u_b[1];
514 *((
volatile acUint16 *)0xB6160000) = (flag & 2) ^ 2;
515 *((
volatile acUint16 *)0xB6010000) = 0;
516 v3 = atapi_packet_send((acAtaReg)0xB6000000, &u.pkt, flag);
526 v4 = atapi_pio_read((acAtaReg)0xB6000000, (acUint16 *)&sense,
sizeof(sense), flag);
533 if ( (flag & 2) != 0 )
535 while ( (*((
volatile acUint16 *)0xB6160000) & 0x81) == 128 )
549 while ( (*((
volatile acUint16 *)0xB6070000) & 0x81) == 128 )
561 printf(
"acata:C:io_done: TIMEDOUT\n");
580 return -((sense.s_key << 16) | (sense.s_asc << 8) | sense.s_ascq);
590 atapi->ap_h.a_ops = &ops_48;
591 atapi->ap_h.a_arg = arg;
592 atapi->ap_h.a_tmout = tmout;
593 atapi->ap_h.a_state = 0;
594 atapi->ap_h.a_flag = 0;
595 atapi->ap_done = done;
603 if ( !atapi || !pkt )
607 atapi->ap_h.a_flag = flag;
608 atapi->ap_packet.u_w[0] = pkt->u_w[0];
609 atapi->ap_packet.u_w[1] = pkt->u_w[1];
610 atapi->ap_packet.u_w[2] = pkt->u_w[2];
611 atapi->ap_h.a_buf = buf;
612 atapi->ap_h.a_size = size;
613 return ata_request(&atapi->ap_h, WakeupThread);
619 if ( !atapi || !pkt )
623 atapi->ap_h.a_flag = flag;
624 atapi->ap_packet.u_w[0] = pkt->u_w[0];
625 atapi->ap_packet.u_w[1] = pkt->u_w[1];
626 atapi->ap_packet.u_w[2] = pkt->u_w[2];
627 atapi->ap_h.a_buf = buf;
628 atapi->ap_h.a_size = size;
629 return ata_request(&atapi->ap_h, iWakeupThread);
640 state = atapi->ap_h.a_state;
641 if ( (
unsigned int)(state - 1) >= 0x7E )
u32 count
start sector of fragmented bd/file