nkeynes@185 | 1 | #include <assert.h>
|
nkeynes@185 | 2 | #include <stdlib.h>
|
nkeynes@185 | 3 | #include "ide.h"
|
nkeynes@185 | 4 | #include "lib.h"
|
nkeynes@185 | 5 |
|
nkeynes@185 | 6 | #define IDE_BASE 0xA05F7000
|
nkeynes@185 | 7 |
|
nkeynes@185 | 8 | #define IDE_ALTSTATUS IDE_BASE+0x018
|
nkeynes@185 | 9 | #define IDE_UNKNOWN IDE_BASE+0x01C
|
nkeynes@185 | 10 | #define IDE_DATA IDE_BASE+0x080 /* 16 bits */
|
nkeynes@185 | 11 | #define IDE_FEATURE IDE_BASE+0x084
|
nkeynes@185 | 12 | #define IDE_COUNT IDE_BASE+0x088
|
nkeynes@185 | 13 | #define IDE_LBA0 IDE_BASE+0x08C
|
nkeynes@185 | 14 | #define IDE_LBA1 IDE_BASE+0x090
|
nkeynes@185 | 15 | #define IDE_LBA2 IDE_BASE+0x094
|
nkeynes@185 | 16 | #define IDE_DEVICE IDE_BASE+0x098
|
nkeynes@185 | 17 | #define IDE_COMMAND IDE_BASE+0x09C
|
nkeynes@185 | 18 | #define IDE_ACTIVATE IDE_BASE+0x4E4
|
nkeynes@185 | 19 |
|
nkeynes@185 | 20 | #define IDE_DEVCONTROL IDE_ALTSTATUS
|
nkeynes@185 | 21 | #define IDE_ERROR IDE_FEATURE
|
nkeynes@185 | 22 | #define IDE_STATUS IDE_COMMAND
|
nkeynes@185 | 23 |
|
nkeynes@185 | 24 | #define IDE_DMA_ADDR IDE_BASE+0x404
|
nkeynes@185 | 25 | #define IDE_DMA_SIZE IDE_BASE+0x408
|
nkeynes@185 | 26 | #define IDE_DMA_DIR IDE_BASE+0x40C
|
nkeynes@185 | 27 | #define IDE_DMA_CTL1 IDE_BASE+0x414
|
nkeynes@185 | 28 | #define IDE_DMA_CTL2 IDE_BASE+0x418
|
nkeynes@185 | 29 | #define IDE_DMA_MAGIC IDE_BASE+0x4B8
|
nkeynes@185 | 30 | #define IDE_DMA_STATUS IDE_BASE+0x4F8
|
nkeynes@185 | 31 |
|
nkeynes@185 | 32 | #define DMA_BASE 0xFFA00000
|
nkeynes@185 | 33 | #define DMA_SAR1 DMA_BASE+0x010
|
nkeynes@185 | 34 | #define DMA_DAR1 DMA_BASE+0x014
|
nkeynes@185 | 35 | #define DMA_TCR1 DMA_BASE+0x018
|
nkeynes@185 | 36 | #define DMA_CHCR1 DMA_BASE+0x01C
|
nkeynes@185 | 37 | #define DMA_SAR2 DMA_BASE+0x020
|
nkeynes@185 | 38 | #define DMA_DAR2 DMA_BASE+0x024
|
nkeynes@185 | 39 | #define DMA_TCR2 DMA_BASE+0x028
|
nkeynes@185 | 40 | #define DMA_CHCR2 DMA_BASE+0x02C
|
nkeynes@185 | 41 | #define DMA_SAR3 DMA_BASE+0x030
|
nkeynes@185 | 42 | #define DMA_DAR3 DMA_BASE+0x034
|
nkeynes@185 | 43 | #define DMA_TCR3 DMA_BASE+0x038
|
nkeynes@185 | 44 | #define DMA_CHCR3 DMA_BASE+0x03C
|
nkeynes@185 | 45 | #define DMA_DMAOR DMA_BASE+0x040
|
nkeynes@185 | 46 | #define QUEUECR0 0xFF000038
|
nkeynes@185 | 47 | #define QUEUECR1 0xFF00003C
|
nkeynes@185 | 48 |
|
nkeynes@185 | 49 | #define IDE_CMD_RESET 0x08
|
nkeynes@185 | 50 | #define IDE_CMD_PACKET 0xA0
|
nkeynes@185 | 51 | #define IDE_CMD_IDENTIFY_PACKET_DEVICE 0xA1
|
nkeynes@185 | 52 | #define IDE_CMD_IDENTIFY_DEVICE 0xEC
|
nkeynes@185 | 53 |
|
nkeynes@185 | 54 | #define MMC_CMD_GET_CONFIGURATION 0x46
|
nkeynes@185 | 55 | #define GD_CMD_IDENTIFY 0x11 /* guessing */
|
nkeynes@185 | 56 |
|
nkeynes@185 | 57 |
|
nkeynes@185 | 58 | #define IDE_DMA_MAGIC_VALUE 0x8843407F
|
nkeynes@185 | 59 |
|
nkeynes@185 | 60 |
|
nkeynes@185 | 61 | #define MAX_WAIT 10000000
|
nkeynes@185 | 62 | #define MAX_IRQ_WAIT 1000000000
|
nkeynes@185 | 63 |
|
nkeynes@185 | 64 | /**
|
nkeynes@185 | 65 | * Dump all ide registers to stdout.
|
nkeynes@185 | 66 | */
|
nkeynes@185 | 67 | void ide_dump_registers() {
|
nkeynes@185 | 68 | int i,j;
|
nkeynes@185 | 69 | printf( "IDE registers:\n");
|
nkeynes@185 | 70 | printf( "Stats: %02X ", byte_read(IDE_ALTSTATUS) );
|
nkeynes@185 | 71 | printf( "Error: %02X ", byte_read(IDE_ERROR) );
|
nkeynes@185 | 72 | printf( "Count: %02X ", byte_read(IDE_COUNT) );
|
nkeynes@185 | 73 | printf( "Dvice: %02X ", byte_read(IDE_DEVICE) );
|
nkeynes@185 | 74 | if( long_read(ASIC_STATUS1)&1 ) {
|
nkeynes@185 | 75 | printf( "INTRQ! " );
|
nkeynes@185 | 76 | }
|
nkeynes@185 | 77 | if( (long_read(ASIC_STATUS0)>>14)&1 ) {
|
nkeynes@185 | 78 | printf( "DMARQ! " );
|
nkeynes@185 | 79 | }
|
nkeynes@185 | 80 | printf( "\nLBA 0: %02X ", byte_read(IDE_LBA0) );
|
nkeynes@185 | 81 | printf( "LBA 1: %02X ", byte_read(IDE_LBA1) );
|
nkeynes@185 | 82 | printf( "LBA 2: %02X ", byte_read(IDE_LBA2) );
|
nkeynes@185 | 83 | printf( "0x01C: %02X\n", byte_read(IDE_UNKNOWN) );
|
nkeynes@185 | 84 | printf( "DAddr: %08X ", long_read(IDE_DMA_ADDR) );
|
nkeynes@185 | 85 | printf( "DSize: %08X ", long_read(IDE_DMA_SIZE) );
|
nkeynes@185 | 86 | printf( "DDir : %08X ", long_read(IDE_DMA_DIR) );
|
nkeynes@185 | 87 | printf( "DCtl1: %08X ", long_read(IDE_DMA_CTL1) );
|
nkeynes@185 | 88 | printf( "DCtl2: %08X\n", long_read(IDE_DMA_CTL2) );
|
nkeynes@185 | 89 | printf( "DStat: %08X\n", long_read(IDE_DMA_STATUS) );
|
nkeynes@185 | 90 | printf( "ASIC: " );
|
nkeynes@185 | 91 | for( i=0; i<12; i+=4 ) {
|
nkeynes@185 | 92 | unsigned int val = long_read(ASIC_STATUS0+i);
|
nkeynes@185 | 93 | for( j=0; j<32; j++ ) {
|
nkeynes@185 | 94 | if( val & (1<<j) ) {
|
nkeynes@185 | 95 | printf( "%d ", j );
|
nkeynes@185 | 96 | }
|
nkeynes@185 | 97 | }
|
nkeynes@185 | 98 | printf( "| " );
|
nkeynes@185 | 99 | }
|
nkeynes@185 | 100 | printf( "\n" );
|
nkeynes@185 | 101 | }
|
nkeynes@185 | 102 |
|
nkeynes@185 | 103 | /**
|
nkeynes@185 | 104 | * Wait for the IDE INTRQ line to go active (bit 0 of the second word)
|
nkeynes@185 | 105 | * @return 0 on success, non-zero on timeout
|
nkeynes@185 | 106 | */
|
nkeynes@185 | 107 | int ide_wait_irq() {
|
nkeynes@185 | 108 | unsigned int status;
|
nkeynes@185 | 109 | int i;
|
nkeynes@185 | 110 | for( i=0; i<MAX_WAIT; i++ ) {
|
nkeynes@185 | 111 | status = long_read( ASIC_STATUS1 );
|
nkeynes@185 | 112 | if( (status&1) != 0 )
|
nkeynes@185 | 113 | return 0;
|
nkeynes@185 | 114 | }
|
nkeynes@185 | 115 | return 1;
|
nkeynes@185 | 116 | }
|
nkeynes@185 | 117 |
|
nkeynes@185 | 118 | /**
|
nkeynes@185 | 119 | * Wait for the IDE BSY flag to be de-asserted.
|
nkeynes@185 | 120 | * @return 0 on success, non-zero on timeout
|
nkeynes@185 | 121 | */
|
nkeynes@185 | 122 | int ide_wait_ready() {
|
nkeynes@185 | 123 | unsigned char status;
|
nkeynes@185 | 124 | int i;
|
nkeynes@185 | 125 | for( i=0; i<MAX_WAIT; i++ ) {
|
nkeynes@185 | 126 | status = byte_read(IDE_ALTSTATUS);
|
nkeynes@251 | 127 | if( (status & 0x80) == 0 )
|
nkeynes@185 | 128 | return 0;
|
nkeynes@185 | 129 | }
|
nkeynes@251 | 130 | printf( "Timeout waiting for IDE to become ready (status = 0x%02X)\n", status );
|
nkeynes@185 | 131 | ide_dump_registers();
|
nkeynes@185 | 132 | return 1;
|
nkeynes@185 | 133 | }
|
nkeynes@185 | 134 |
|
nkeynes@185 | 135 | int ide_wait_dma() {
|
nkeynes@185 | 136 | unsigned int status;
|
nkeynes@185 | 137 | int i;
|
nkeynes@185 | 138 | for( i=0; i<MAX_WAIT; i++ ) {
|
nkeynes@185 | 139 | status = long_read(IDE_DMA_CTL2);
|
nkeynes@185 | 140 | if( (status & 1) == 0 )
|
nkeynes@185 | 141 | return 0;
|
nkeynes@185 | 142 | }
|
nkeynes@185 | 143 | printf( "[IDE] Timeout waiting for DMA to become ready\n" );
|
nkeynes@185 | 144 | return 1;
|
nkeynes@185 | 145 | }
|
nkeynes@185 | 146 |
|
nkeynes@185 | 147 | /**
|
nkeynes@185 | 148 | * Write the command packet out to the interface.
|
nkeynes@185 | 149 | * @param cmd 12 byte ATAPI command packet
|
nkeynes@185 | 150 | * @param dma 1 = dma mode, 0 = pio mode
|
nkeynes@185 | 151 | */
|
nkeynes@185 | 152 | int ide_write_command_packet( char *cmd, int dma )
|
nkeynes@185 | 153 | {
|
nkeynes@185 | 154 | int i, status;
|
nkeynes@185 | 155 | unsigned short *spkt = (unsigned short *)cmd;
|
nkeynes@185 | 156 | unsigned short length = 8;
|
nkeynes@185 | 157 | if( ide_wait_ready() )
|
nkeynes@185 | 158 | return 1;
|
nkeynes@185 | 159 | byte_write( IDE_FEATURE, dma );
|
nkeynes@185 | 160 | byte_write( IDE_COUNT, 0 );
|
nkeynes@185 | 161 | byte_write( IDE_LBA0, 0 );
|
nkeynes@185 | 162 | byte_write( IDE_LBA1, (length&0xFF) );
|
nkeynes@185 | 163 | byte_write( IDE_LBA2, (length>>8)&0xFF );
|
nkeynes@185 | 164 | byte_write( IDE_DEVICE, 0 );
|
nkeynes@185 | 165 | byte_write( IDE_COMMAND, IDE_CMD_PACKET );
|
nkeynes@185 | 166 | status = byte_read(IDE_ALTSTATUS); /* delay 1 PIO cycle as per spec */
|
nkeynes@185 | 167 | /* Wait until device is ready to accept command */
|
nkeynes@185 | 168 | if( ide_wait_ready() )
|
nkeynes@185 | 169 | return 1;
|
nkeynes@185 | 170 |
|
nkeynes@185 | 171 | /* Write the command */
|
nkeynes@185 | 172 | for( i=0; i<6; i++ ) {
|
nkeynes@185 | 173 | word_write( IDE_DATA, spkt[i] );
|
nkeynes@185 | 174 | }
|
nkeynes@185 | 175 | }
|
nkeynes@185 | 176 |
|
nkeynes@185 | 177 | int ide_read_pio( char *buf, int buflen ) {
|
nkeynes@185 | 178 | int i;
|
nkeynes@185 | 179 | unsigned short *bufptr = (unsigned short *)buf;
|
nkeynes@185 | 180 | unsigned int length = 0, avail;
|
nkeynes@185 | 181 | int status;
|
nkeynes@185 | 182 |
|
nkeynes@185 | 183 | while(1) {
|
nkeynes@185 | 184 | if( ide_wait_ready() )
|
nkeynes@185 | 185 | return -1;
|
nkeynes@185 | 186 | status = byte_read( IDE_STATUS );
|
nkeynes@185 | 187 | if( (status & 0xE9) == 0x48 ) {
|
nkeynes@185 | 188 | /* Bytes available */
|
nkeynes@185 | 189 | avail = (byte_read( IDE_LBA1 )) | (byte_read(IDE_LBA2)<<8);
|
nkeynes@185 | 190 | for( i=0; i<avail; i+=2 ) {
|
nkeynes@185 | 191 | if( buflen > 0 ) {
|
nkeynes@185 | 192 | *bufptr++ = word_read(IDE_DATA);
|
nkeynes@185 | 193 | buflen-=2;
|
nkeynes@185 | 194 | }
|
nkeynes@185 | 195 | }
|
nkeynes@185 | 196 | length += avail;
|
nkeynes@185 | 197 | if( avail == 0 ) {
|
nkeynes@185 | 198 | /* Should never happen */
|
nkeynes@185 | 199 | printf( "[IDE] Unexpected read length 0\n" );
|
nkeynes@185 | 200 | return -1;
|
nkeynes@185 | 201 | }
|
nkeynes@185 | 202 | } else {
|
nkeynes@185 | 203 | if( status&0x01 ) {
|
nkeynes@185 | 204 | printf( "[IDE] ERROR! (%02X)\n", status );
|
nkeynes@243 | 205 | return -1;
|
nkeynes@185 | 206 | } else if( (status&0x08) == 0 ) {
|
nkeynes@185 | 207 | /* No more data */
|
nkeynes@185 | 208 | return length;
|
nkeynes@185 | 209 | } else {
|
nkeynes@185 | 210 | printf( "[IDE] Unexpected status result: %02X\n", status );
|
nkeynes@185 | 211 | return -1;
|
nkeynes@185 | 212 | }
|
nkeynes@185 | 213 | }
|
nkeynes@185 | 214 | }
|
nkeynes@185 | 215 | }
|
nkeynes@185 | 216 |
|
nkeynes@185 | 217 | int ide_read_dma( char *buf, int buflen )
|
nkeynes@185 | 218 | {
|
nkeynes@185 | 219 | int status;
|
nkeynes@185 | 220 |
|
nkeynes@185 | 221 | long_write( IDE_DMA_CTL1, 1 );
|
nkeynes@185 | 222 | long_write( IDE_DMA_CTL2, 1 );
|
nkeynes@185 | 223 |
|
nkeynes@185 | 224 | printf( "Started DMA\n" );
|
nkeynes@185 | 225 | ide_dump_registers();
|
nkeynes@185 | 226 |
|
nkeynes@185 | 227 | ide_wait_irq();
|
nkeynes@185 | 228 | printf( "After IRQ\n" );
|
nkeynes@185 | 229 | ide_dump_registers();
|
nkeynes@185 | 230 | long_write( IDE_DMA_CTL1, 0 );
|
nkeynes@185 | 231 | status = ide_wait_dma();
|
nkeynes@185 | 232 | printf( "After DMA finished\n");
|
nkeynes@185 | 233 | ide_dump_registers();
|
nkeynes@185 | 234 | if( status != 0 ) {
|
nkeynes@185 | 235 | return -1;
|
nkeynes@185 | 236 | }
|
nkeynes@185 | 237 | status = long_read(ASIC_STATUS0);
|
nkeynes@185 | 238 | if( (status & (1<<14)) == 0 ) {
|
nkeynes@185 | 239 | printf( "DMARQ cleared already\n");
|
nkeynes@185 | 240 | } else {
|
nkeynes@185 | 241 | /*
|
nkeynes@185 | 242 | status &= ~(1<<14);
|
nkeynes@185 | 243 | long_write(ASIC_STATUS0, status);
|
nkeynes@185 | 244 | status = long_read(ASIC_STATUS0);
|
nkeynes@185 | 245 | */
|
nkeynes@185 | 246 | byte_read(IDE_STATUS );
|
nkeynes@185 | 247 | if( (status & (1<<14)) == 0 ) {
|
nkeynes@185 | 248 | printf( "DMARQ cleared successfully\n" );
|
nkeynes@185 | 249 | } else {
|
nkeynes@185 | 250 | printf( "DMARQ not cleared: %08X\n", long_read(ASIC_STATUS0) );
|
nkeynes@185 | 251 | }
|
nkeynes@185 | 252 | }
|
nkeynes@185 | 253 | status = ide_wait_ready();
|
nkeynes@185 | 254 | printf( "After IDE ready\n");
|
nkeynes@185 | 255 | ide_dump_registers();
|
nkeynes@185 | 256 | if( status != 0 ) {
|
nkeynes@185 | 257 | return -1;
|
nkeynes@185 | 258 | }
|
nkeynes@185 | 259 | return long_read( IDE_DMA_STATUS );
|
nkeynes@185 | 260 | }
|
nkeynes@185 | 261 |
|
nkeynes@185 | 262 | int ide_do_packet_command_pio( char *cmd, char *buf, int length )
|
nkeynes@185 | 263 | {
|
nkeynes@185 | 264 | ide_write_command_packet( cmd, 0 );
|
nkeynes@185 | 265 | length = ide_read_pio( buf, length );
|
nkeynes@185 | 266 | return length;
|
nkeynes@185 | 267 | }
|
nkeynes@185 | 268 |
|
nkeynes@185 | 269 | int ide_do_packet_command_dma( char *cmd, char *buf, int length )
|
nkeynes@185 | 270 | {
|
nkeynes@185 | 271 | long_write( QUEUECR0, 0x10 );
|
nkeynes@185 | 272 | long_write( QUEUECR1, 0x10 );
|
nkeynes@185 | 273 | long_write( IDE_DMA_MAGIC, IDE_DMA_MAGIC_VALUE );
|
nkeynes@185 | 274 | long_write( IDE_DMA_ADDR, (unsigned int)buf );
|
nkeynes@185 | 275 | long_write( IDE_DMA_SIZE, length );
|
nkeynes@185 | 276 | long_write( IDE_DMA_DIR, 1 );
|
nkeynes@185 | 277 | ide_write_command_packet( cmd, 1 );
|
nkeynes@185 | 278 | length = ide_read_dma( buf, length );
|
nkeynes@185 | 279 | return length;
|
nkeynes@185 | 280 | }
|
nkeynes@185 | 281 |
|
nkeynes@243 | 282 | void ide_activate() {
|
nkeynes@243 | 283 | register unsigned long p, x;
|
nkeynes@243 | 284 |
|
nkeynes@243 | 285 | /* Reactivate GD-ROM drive */
|
nkeynes@243 | 286 |
|
nkeynes@243 | 287 | *((volatile unsigned long *)0xa05f74e4) = 0x1fffff;
|
nkeynes@243 | 288 | for(p=0; p<0x200000/4; p++)
|
nkeynes@243 | 289 | x = ((volatile unsigned long *)0xa0000000)[p];
|
nkeynes@243 | 290 | }
|
nkeynes@243 | 291 |
|
nkeynes@243 | 292 |
|
nkeynes@185 | 293 | int ide_init()
|
nkeynes@185 | 294 | {
|
nkeynes@243 | 295 | ide_activate();
|
nkeynes@243 | 296 |
|
nkeynes@185 | 297 | if( ide_wait_ready() )
|
nkeynes@185 | 298 | return -1;
|
nkeynes@185 | 299 |
|
nkeynes@185 | 300 | /** Set Default PIO mode */
|
nkeynes@185 | 301 | byte_write( IDE_FEATURE, 0x03 );
|
nkeynes@185 | 302 | byte_write( IDE_COUNT, 0x0B );
|
nkeynes@185 | 303 | byte_write( IDE_COMMAND, 0xEF );
|
nkeynes@185 | 304 |
|
nkeynes@185 | 305 | if( ide_wait_ready() )
|
nkeynes@185 | 306 | return -1;
|
nkeynes@185 | 307 |
|
nkeynes@185 | 308 | /** Set Multi-word DMA mode 2 */
|
nkeynes@185 | 309 | long_write( 0xA05F7490, 0x222 );
|
nkeynes@185 | 310 | long_write( 0xA05F7494, 0x222 );
|
nkeynes@185 | 311 | byte_write( IDE_FEATURE, 0x03 );
|
nkeynes@185 | 312 | byte_write( IDE_COUNT, 0x22 );
|
nkeynes@185 | 313 | byte_write( IDE_COMMAND, 0xEF );
|
nkeynes@185 | 314 | if( ide_wait_ready() )
|
nkeynes@185 | 315 | return -1;
|
nkeynes@185 | 316 |
|
nkeynes@185 | 317 | word_write( 0xA05F7480, 0x400 );
|
nkeynes@185 | 318 | long_write( 0xA05F7488, 0x200 );
|
nkeynes@185 | 319 | long_write( 0xA05F748C, 0x200 );
|
nkeynes@185 | 320 | long_write( 0xA05F74A0, 0x2001 );
|
nkeynes@185 | 321 | long_write( 0xA05F74A4, 0x2001 );
|
nkeynes@185 | 322 | long_write( 0xA05F74B4, 0x0001 );
|
nkeynes@185 | 323 | }
|
nkeynes@185 | 324 |
|
nkeynes@185 | 325 | int ide_sense_error( char *buf )
|
nkeynes@185 | 326 | {
|
nkeynes@185 | 327 | char cmd[12] = { 0x13,0,0,0, 10,0,0,0, 0,0,0,0 };
|
nkeynes@185 | 328 | return ide_do_packet_command_pio( cmd, buf, 10 );
|
nkeynes@185 | 329 | }
|
nkeynes@185 | 330 |
|
nkeynes@251 | 331 | int ide_get_sense_code()
|
nkeynes@251 | 332 | {
|
nkeynes@251 | 333 | char buf[10];
|
nkeynes@251 | 334 | int len = ide_sense_error( buf );
|
nkeynes@251 | 335 | if( len != 10 ) {
|
nkeynes@251 | 336 | printf( "ERROR: Sense request failed!\n" );
|
nkeynes@251 | 337 | return -1;
|
nkeynes@251 | 338 | }
|
nkeynes@251 | 339 | return ((int)buf[8] << 8) | buf[2];
|
nkeynes@251 | 340 | }
|
nkeynes@251 | 341 |
|
nkeynes@185 | 342 | void ide_print_sense_error()
|
nkeynes@185 | 343 | {
|
nkeynes@185 | 344 | char buf[10];
|
nkeynes@185 | 345 | if( ide_sense_error(buf) != 10 ) {
|
nkeynes@185 | 346 | printf( "ERROR - Sense error failed!\n" );
|
nkeynes@185 | 347 | return;
|
nkeynes@185 | 348 | }
|
nkeynes@185 | 349 | int major = buf[2] & 0xFF;
|
nkeynes@185 | 350 | int minor = buf[8] & 0xFF;
|
nkeynes@185 | 351 | printf( "[IDE] Error code %02X,%02X\n", major, minor );
|
nkeynes@185 | 352 | }
|
nkeynes@185 | 353 |
|
nkeynes@185 | 354 | int ide_test_ready()
|
nkeynes@185 | 355 | {
|
nkeynes@185 | 356 | char cmd[12] = { 0,0,0,0, 0,0,0,0, 0,0,0,0 };
|
nkeynes@185 | 357 | int length = ide_do_packet_command_pio( cmd, NULL, 0 );
|
nkeynes@185 | 358 | return length;
|
nkeynes@185 | 359 | }
|
nkeynes@185 | 360 |
|
nkeynes@185 | 361 | int ide_read_toc( char *buf, int length )
|
nkeynes@185 | 362 | {
|
nkeynes@185 | 363 | char cmd[12] = { 0x14,0,0,0, 0x98,0,0,0, 0,0,0,0 };
|
nkeynes@185 | 364 | return ide_do_packet_command_pio( cmd, buf, length );
|
nkeynes@185 | 365 | }
|
nkeynes@185 | 366 |
|
nkeynes@185 | 367 | int ide_get_session( int session, struct gdrom_session *session_data )
|
nkeynes@185 | 368 | {
|
nkeynes@185 | 369 | char cmd[12] = {0x15, 0, session, 0, 6,0,0,0, 0,0,0,0 };
|
nkeynes@185 | 370 | char buf[6];
|
nkeynes@185 | 371 | int length = ide_do_packet_command_pio( cmd, buf, sizeof(buf) );
|
nkeynes@185 | 372 | if( length < 0 )
|
nkeynes@185 | 373 | return length;
|
nkeynes@185 | 374 | if( length != 6 )
|
nkeynes@185 | 375 | return -1;
|
nkeynes@185 | 376 | assert(length == 6);
|
nkeynes@185 | 377 | session_data->track = ((int)buf[2])&0xFF;
|
nkeynes@185 | 378 | session_data->lba = (((int)buf[3])&0xFF) << 16 |
|
nkeynes@185 | 379 | (((int)buf[4])&0xFF) << 8 |
|
nkeynes@185 | 380 | (((int)buf[5])&0xFF);
|
nkeynes@185 | 381 | return 0;
|
nkeynes@185 | 382 | }
|
nkeynes@185 | 383 |
|
nkeynes@185 | 384 | int ide_spinup( )
|
nkeynes@185 | 385 | {
|
nkeynes@185 | 386 | char cmd[12] = {0x70,0x1F,0,0, 0,0,0,0, 0,0,0,0};
|
nkeynes@185 | 387 | int length = ide_do_packet_command_pio( cmd, NULL, 0 );
|
nkeynes@185 | 388 | return length;
|
nkeynes@185 | 389 | }
|
nkeynes@185 | 390 |
|
nkeynes@185 | 391 | int ide_unknown71( char *buf, int length )
|
nkeynes@185 | 392 | {
|
nkeynes@185 | 393 | char cmd[12] = {0x71,0,0,0, 0,0,0,0, 0,0,0,0};
|
nkeynes@185 | 394 | return ide_do_packet_command_pio( cmd, buf, length );
|
nkeynes@185 | 395 | }
|
nkeynes@185 | 396 |
|
nkeynes@185 | 397 | int ide_read_sector_pio( uint32_t sector, uint32_t count, int mode,
|
nkeynes@185 | 398 | char *buf, int length )
|
nkeynes@185 | 399 | {
|
nkeynes@185 | 400 | char cmd[12] = { 0x30,0,0,0, 0,0,0,0, 0,0,0,0 };
|
nkeynes@185 | 401 |
|
nkeynes@185 | 402 | cmd[1] = mode;
|
nkeynes@185 | 403 | cmd[2] = (sector>>16)&0xFF;
|
nkeynes@185 | 404 | cmd[3] = (sector>>8)&0xFF;
|
nkeynes@185 | 405 | cmd[4] = sector&0xFF;
|
nkeynes@185 | 406 | cmd[8] = (count>>16)&0xFF;
|
nkeynes@185 | 407 | cmd[9] = (count>>8)&0xFF;
|
nkeynes@185 | 408 | cmd[10] = count&0xFF;
|
nkeynes@185 | 409 | return ide_do_packet_command_pio( cmd, buf, length );
|
nkeynes@185 | 410 | }
|
nkeynes@185 | 411 |
|
nkeynes@185 | 412 |
|
nkeynes@185 | 413 | int ide_read_sector_dma( uint32_t sector, uint32_t count, int mode,
|
nkeynes@185 | 414 | char *buf, int length )
|
nkeynes@185 | 415 | {
|
nkeynes@185 | 416 | char cmd[12] = { 0x30,0,0,0, 0,0,0,0, 0,0,0,0 };
|
nkeynes@185 | 417 |
|
nkeynes@185 | 418 | cmd[1] = mode;
|
nkeynes@185 | 419 | cmd[2] = (sector>>16)&0xFF;
|
nkeynes@185 | 420 | cmd[3] = (sector>>8)&0xFF;
|
nkeynes@185 | 421 | cmd[4] = sector&0xFF;
|
nkeynes@185 | 422 | cmd[8] = (count>>16)&0xFF;
|
nkeynes@185 | 423 | cmd[9] = (count>>8)&0xFF;
|
nkeynes@185 | 424 | cmd[10] = count&0xFF;
|
nkeynes@185 | 425 | return ide_do_packet_command_dma( cmd, buf, length );
|
nkeynes@185 | 426 | }
|
nkeynes@185 | 427 |
|
nkeynes@185 | 428 | int ide_read_something( )
|
nkeynes@185 | 429 | {
|
nkeynes@185 | 430 | char cmd[12] = { 0x12,0,0,0, 0x0a,0,0,0, 0,0,0,0 };
|
nkeynes@185 | 431 | char result[10];
|
nkeynes@185 | 432 | ide_do_packet_command_pio( cmd, result, 10 );
|
nkeynes@185 | 433 | return 0;
|
nkeynes@243 | 434 | }
|
nkeynes@243 | 435 |
|
nkeynes@251 | 436 | int ide_read_status( char *buf, int length, int type )
|
nkeynes@243 | 437 | {
|
nkeynes@243 | 438 | char cmd[12] = { 0x40,0,0,0, 0xFF,0,0,0, 0,0,0,0 };
|
nkeynes@243 | 439 |
|
nkeynes@251 | 440 | cmd[1] = type;
|
nkeynes@243 | 441 | return ide_do_packet_command_pio( cmd, buf, length );
|
nkeynes@243 | 442 | }
|
nkeynes@243 | 443 |
|
nkeynes@243 | 444 | int ide_play_cd( char *buf, int length )
|
nkeynes@243 | 445 | {
|
nkeynes@243 | 446 | char cmd[12] = { 0x21, 0x04,0,0, 0,0,0,0, 0,0,0,0 };
|
nkeynes@243 | 447 | return ide_do_packet_command_pio( cmd, buf, length );
|
nkeynes@243 | 448 | }
|