2 * $Id: ide.c,v 1.18 2006-12-19 09:52:56 nkeynes Exp $
4 * IDE interface implementation
7 * Note: All references to read/write are from the host's point of view.
10 * Copyright (c) 2005 Nathan Keynes.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
23 #define MODULE ide_module
29 #include "gdrom/ide.h"
30 #include "gdrom/gdrom.h"
31 #include "gdrom/packet.h"
33 #define MAX_WRITE_BUF 4096
34 #define MAX_SECTOR_SIZE 2352 /* Audio sector */
35 #define DEFAULT_DATA_SECTORS 8
37 static void ide_init( void );
38 static void ide_reset( void );
39 static void ide_save_state( FILE *f );
40 static int ide_load_state( FILE *f );
41 static void ide_raise_interrupt( void );
42 static void ide_clear_interrupt( void );
43 static void ide_packet_command( unsigned char *data );
45 struct dreamcast_module ide_module = { "IDE", ide_init, ide_reset, NULL, NULL,
46 NULL, ide_save_state, ide_load_state };
48 struct ide_registers idereg;
49 unsigned char *data_buffer = NULL;
50 uint32_t data_buffer_len = 0;
52 #define WRITE_BUFFER(x16) *((uint16_t *)(data_buffer + idereg.data_offset)) = x16
53 #define READ_BUFFER() *((uint16_t *)(data_buffer + idereg.data_offset))
55 /* "\0\0\0\0\xb4\x19\0\0\x08SE REV 6.42990316" */
56 unsigned char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00,
57 0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20,
58 0x20, 0x20, 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e,
59 0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
61 unsigned char gdrom_71[] = { 0x3E, 0x0F, 0x90, 0xBE, 0x1D, 0xD9, 0x89, 0x04, 0x28, 0x3A, 0x8E, 0x26, 0x5C, 0x95, 0x10, 0x5A,
62 0x0A, 0x99, 0xEE, 0xFB, 0x69, 0xCE, 0xD9, 0x63, 0x00, 0xF5, 0x0A, 0xBC, 0x2C, 0x0D, 0xF8, 0xE2,
63 0x05, 0x02, 0x00, 0x7C, 0x03, 0x00, 0x3D, 0x08, 0xD8, 0x8D, 0x08, 0x7A, 0x6D, 0x00, 0x35, 0x06,
64 0xBA, 0x66, 0x10, 0x00, 0x91, 0x08, 0x10, 0x29, 0xD0, 0x45, 0xDA, 0x00, 0x2D, 0x05, 0x69, 0x09,
65 0x00, 0x5E, 0x0F, 0x70, 0x86, 0x12, 0x6C, 0x77, 0x5A, 0xFB, 0xCD, 0x56, 0xFB, 0xF7, 0xB7, 0x00,
66 0x5D, 0x07, 0x19, 0x99, 0xF2, 0xAF, 0x00, 0x63, 0x03, 0x00, 0xF0, 0x10, 0xBE, 0xD7, 0xA0, 0x63,
67 0xFA, 0x84, 0xA7, 0x74, 0x94, 0xEF, 0xAD, 0xC2, 0xAC, 0x00, 0x78, 0x07, 0x9F, 0x57, 0x0B, 0x62,
68 0x00, 0xFE, 0x08, 0x08, 0x5D, 0x5A, 0x6A, 0x54, 0x00, 0xE2, 0x09, 0x93, 0x7E, 0x62, 0x2A, 0x5E,
69 0xDA, 0x00, 0x7E, 0x0F, 0xF0, 0x07, 0x01, 0x6D, 0x50, 0x86, 0xDD, 0x4A, 0x15, 0x54, 0xC7, 0xEC,
70 0x00, 0xF2, 0x0B, 0x07, 0xF8, 0x1A, 0xB0, 0x99, 0x3B, 0xF1, 0x36, 0x00, 0x94, 0x07, 0x34, 0xE3,
71 0xBC, 0x6E, 0x00, 0x34, 0x0D, 0x6F, 0xDA, 0xBD, 0xEE, 0xF7, 0xCC, 0xCE, 0x39, 0x7E, 0xE3, 0x00,
72 0x14, 0x08, 0xDC, 0xD2, 0xB9, 0xF9, 0x31, 0x00, 0xB0, 0x0C, 0x10, 0xA3, 0x45, 0x12, 0xC7, 0xCD,
73 0xBF, 0x05, 0x37, 0x00, 0xC4, 0x0D, 0x5F, 0xE0, 0x59, 0xBB, 0x01, 0x59, 0x03, 0xD6, 0x29, 0x9C,
74 0x00, 0x01, 0x0A, 0x09, 0xAA, 0xA8, 0xA8, 0x24, 0x0B, 0x66, 0x00, 0x5C, 0x05, 0xA5, 0xCE, 0x00,
75 0xC1, 0x0B, 0xB7, 0xA0, 0x6F, 0xE9, 0x2B, 0xCC, 0xB5, 0xFC, 0x00, 0x8D, 0x05, 0xF4, 0xAC, 0x00,
76 0x57, 0x04, 0xB6, 0x00, 0xFC, 0x03, 0x00, 0xC3, 0x10, 0x43, 0x3B, 0xBE, 0xA2, 0x96, 0xC3, 0x65,
77 0x9F, 0x9A, 0x88, 0xD5, 0x49, 0x68, 0x00, 0xDC, 0x11, 0x56, 0x23, 0x2D, 0xF9, 0xFC, 0xF5, 0x8B,
78 0x1B, 0xB1, 0xB7, 0x10, 0x21, 0x1C, 0x12, 0x00, 0x0D, 0x0D, 0xEB, 0x86, 0xA2, 0x49, 0x8D, 0x8D,
79 0xBE, 0xA1, 0x6D, 0x53, 0x00, 0xE1, 0x0A, 0x8E, 0x67, 0xAA, 0x16, 0x79, 0x39, 0x59, 0x00, 0x36,
80 0x0B, 0x2A, 0x4E, 0xAE, 0x51, 0x4B, 0xD0, 0x66, 0x33, 0x00, 0x8A, 0x07, 0xCD, 0x6F, 0xBA, 0x92,
81 0x00, 0x1A, 0x0E, 0xDF, 0x4A, 0xB3, 0x77, 0x1F, 0xA5, 0x90, 0x19, 0xFA, 0x59, 0xD7, 0x00, 0x04,
82 0x0F, 0xAC, 0xCA, 0x9F, 0xA4, 0xFC, 0x6D, 0x90, 0x86, 0x9E, 0x1F, 0x44, 0x40, 0x00, 0x9F, 0x04,
83 0x56, 0x00, 0x22, 0x03, 0x00, 0xB8, 0x10, 0x2C, 0x7A, 0x53, 0xA4, 0xBF, 0xA3, 0x90, 0x90, 0x14,
84 0x9D, 0x46, 0x6C, 0x96, 0x00, 0xC6, 0x0B, 0x9B, 0xBB, 0xB0, 0xAE, 0x60, 0x92, 0x8E, 0x0C, 0x00,
85 0x14, 0x06, 0x4B, 0xAE, 0x7F, 0x00, 0x5C, 0x0B, 0x23, 0xFA, 0xE7, 0x51, 0xDA, 0x61, 0x49, 0x5E,
86 0x00, 0xD7, 0x0B, 0x01, 0xFC, 0x55, 0x31, 0x84, 0xC5, 0x0C, 0x98, 0x00, 0x97, 0x50, 0x6E, 0xF9,
87 0xEE, 0x75, 0x92, 0x53, 0xD3, 0x66, 0xA4, 0xAF, 0x3B, 0xFE, 0x7B, 0x27, 0x30, 0xBB, 0xB6, 0xF2,
88 0x76, 0x22, 0x45, 0x42, 0xCA, 0xF9, 0xF0, 0xDE, 0x9F, 0x45, 0x16, 0x68, 0x22, 0xB9, 0x84, 0x28,
89 0x8F, 0x2B, 0xB5, 0x5C, 0xD2, 0xF5, 0x45, 0x36, 0x3E, 0x76, 0xC6, 0xBF, 0x32, 0x5C, 0x41, 0xA6,
90 0x26, 0xC7, 0x82, 0x2F, 0x2E, 0xB5, 0x75, 0xC6, 0xE6, 0x67, 0x9E, 0x77, 0x94, 0xAF, 0x6A, 0x05,
91 0xC0, 0x05, 0x61, 0x71, 0x89, 0x5A, 0xB1, 0xD0, 0xFC, 0x7E, 0xC0, 0x9B, 0xCB, 0x3B, 0x69, 0xD9,
92 0x5F, 0xAF, 0xCA, 0xAB, 0x25, 0xD5, 0xBE, 0x8A, 0x6B, 0xB0, 0xFB, 0x61, 0x6C, 0xEB, 0x85, 0x6E,
93 0x7A, 0x48, 0xFF, 0x97, 0x91, 0x06, 0x3D, 0x4D, 0x68, 0xD3, 0x65, 0x83, 0x90, 0xA0, 0x08, 0x5C,
94 0xFC, 0xEE, 0x7C, 0x33, 0x43, 0x7F, 0x80, 0x52, 0x8B, 0x19, 0x72, 0xF2, 0xC9, 0xAB, 0x93, 0xAF,
95 0x16, 0xED, 0x36, 0x48, 0xAB, 0xC9, 0xD1, 0x03, 0xB3, 0xDC, 0x2F, 0xF2, 0x92, 0x3F, 0x0A, 0x19,
96 0x25, 0xE2, 0xEF, 0x7A, 0x22, 0xDA, 0xDB, 0xCB, 0x32, 0x12, 0x61, 0x49, 0x5B, 0x74, 0x7C, 0x65,
97 0x20, 0x89, 0x54, 0x9E, 0x0E, 0xC9, 0x52, 0xE3, 0xC9, 0x9A, 0x44, 0xC9, 0x5D, 0xA6, 0x77, 0xC0,
98 0xE7, 0x60, 0x91, 0x80, 0x50, 0x1F, 0x33, 0xB1, 0xCD, 0xAD, 0xF4, 0x0D, 0xBB, 0x08, 0xB1, 0xD0,
99 0x13, 0x95, 0xAE, 0xC9, 0xE2, 0x64, 0xA2, 0x65, 0xFB, 0x8F, 0xE9, 0xA2, 0x8A, 0xBC, 0x98, 0x81,
100 0x45, 0xB4, 0x55, 0x4E, 0xB9, 0x74, 0xB4, 0x50, 0x76, 0xBF, 0xF0, 0x45, 0xE7, 0xEE, 0x41, 0x64,
101 0x9F, 0xB5, 0xE0, 0xBB, 0x1C, 0xBB, 0x28, 0x66, 0x1B, 0xDD, 0x2B, 0x02, 0x66, 0xBF, 0xFD, 0x7D,
102 0x37, 0x35, 0x1D, 0x76, 0x21, 0xC3, 0x8F, 0xAF, 0xF6, 0xF9, 0xE9, 0x27, 0x48, 0xE7, 0x3D, 0x95,
103 0x74, 0x0C, 0x77, 0x88, 0x56, 0xD9, 0x84, 0xC8, 0x7D, 0x20, 0x31, 0x43, 0x53, 0xF1, 0xC1, 0xC7,
104 0xC9, 0xF7, 0x5C, 0xC0, 0xA6, 0x5A, 0x27, 0x0A, 0x41, 0xD4, 0x44, 0x94, 0x65, 0x4F, 0xE2, 0x53,
105 0x60, 0x0B, 0xD1, 0x23, 0x6C, 0x0C, 0xBC, 0x70, 0x6C, 0x26, 0x1A, 0x61, 0x1D, 0x35, 0x88, 0xEC,
106 0xB8, 0x15, 0xE3, 0xB4, 0x82, 0xEE, 0xB3, 0x21, 0xAC, 0x6C, 0xB7, 0x33, 0x6D, 0x78, 0x0C, 0x0D,
107 0xB4, 0x0B, 0x29, 0xF2, 0xD4, 0x8C, 0x3F, 0xDD, 0x3F, 0x47, 0xDD, 0xF2, 0xD8, 0x39, 0x57, 0x20,
108 0x28, 0xD8, 0xDD, 0x32, 0xE2, 0x6A, 0x47, 0x53, 0x57, 0xC6, 0xFA, 0x7A, 0x38, 0x30, 0x31, 0x8F,
109 0xE7, 0xD3, 0x84, 0x2B, 0x5D, 0x4F, 0x95, 0x98, 0xED, 0x0B, 0xD7, 0x50, 0x0C, 0x49, 0xDA, 0x59,
110 0x15, 0xF1, 0x39, 0xF3, 0x40, 0xDC, 0xDC, 0x25, 0x24, 0x56, 0x6E, 0xA9, 0x2F, 0xF0, 0x00, 0x00 };
113 static void ide_init( void )
116 data_buffer_len = DEFAULT_DATA_SECTORS;
117 data_buffer = malloc( MAX_SECTOR_SIZE * data_buffer_len );
118 assert( data_buffer != NULL );
121 static void ide_reset( void )
123 ide_clear_interrupt();
126 idereg.lba0 = /* 0x21; */ 0x81;
129 idereg.feature = 0; /* Indeterminate really */
130 idereg.status = 0x50;
131 idereg.device = 0x00;
132 idereg.disc = gdrom_is_mounted() ? (IDE_DISC_CDROM|IDE_DISC_READY) : IDE_DISC_NONE;
133 idereg.state = IDE_STATE_IDLE;
134 memset( idereg.gdrom_sense, '\0', 10 );
135 idereg.data_offset = -1;
136 idereg.data_length = -1;
137 idereg.last_read_track = 1;
138 idereg.last_read_lba = 150;
139 idereg.last_read_count = 0;
142 static void ide_save_state( FILE *f )
144 fwrite( &idereg, sizeof(idereg), 1, f );
145 fwrite( &data_buffer_len, sizeof(data_buffer_len), 1, f );
146 fwrite( data_buffer, MAX_SECTOR_SIZE, data_buffer_len, f );
149 static int ide_load_state( FILE *f )
152 fread( &idereg, sizeof(idereg), 1, f );
153 fread( &length, sizeof(uint32_t), 1, f );
154 if( length > data_buffer_len ) {
155 if( data_buffer != NULL )
157 data_buffer = malloc( MAX_SECTOR_SIZE * length );
158 assert( data_buffer != NULL );
159 data_buffer_len = length;
161 fread( data_buffer, MAX_SECTOR_SIZE, length, f );
165 /************************ State transitions *************************/
167 void ide_set_packet_result( uint16_t result )
169 idereg.gdrom_sense[0] = 0xf0;
170 idereg.gdrom_sense[2] = result & 0xFF;
171 idereg.gdrom_sense[8] = (result >> 8) & 0xFF;
172 idereg.error = (result & 0x0F) << 4;
174 idereg.status = 0x51;
175 ide_raise_interrupt();
177 idereg.status = idereg.status & ~(IDE_STATUS_BSY|IDE_STATUS_CHK);
182 * Begin command packet write to the device. This is always 12 bytes of PIO data
184 static void ide_start_command_packet_write( )
186 idereg.state = IDE_STATE_CMD_WRITE;
187 idereg.status = IDE_STATUS_DRDY | IDE_STATUS_DRQ;
188 idereg.error = idereg.feature & 0x03; /* Copy values of OVL/DMA */
189 idereg.count = IDE_COUNT_CD;
190 idereg.data_offset = 0;
191 idereg.data_length = 12;
195 * Begin PIO read from the device. The data is assumed to already be
196 * in the buffer at this point.
198 static void ide_start_read( int length, int blocksize, gboolean dma )
200 idereg.count = IDE_COUNT_IO;
201 idereg.data_length = length;
202 idereg.data_offset = 0;
204 idereg.state = IDE_STATE_DMA_READ;
205 idereg.status = 0xD0;
207 idereg.state = IDE_STATE_PIO_READ;
208 idereg.status = IDE_STATUS_DRDY | IDE_STATUS_DRQ;
209 idereg.lba1 = length & 0xFF;
210 idereg.lba2 = (length >> 8) & 0xFF;
211 // idereg.lba1 = blocksize & 0xFF;
212 // idereg.lba2 = blocksize >> 8;
213 idereg.block_length = blocksize;
214 idereg.block_left = blocksize;
215 ide_raise_interrupt( );
219 static void ide_start_packet_read( int length, int blocksize )
221 ide_set_packet_result( PKT_ERR_OK );
222 ide_start_read( length, blocksize, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );
225 static void ide_raise_interrupt( void )
227 if( idereg.intrq_pending == 0 ) {
228 idereg.intrq_pending = 1;
229 if( IS_IDE_IRQ_ENABLED() )
230 asic_event( EVENT_IDE );
234 static void ide_clear_interrupt( void )
236 if( idereg.intrq_pending != 0 ) {
237 idereg.intrq_pending = 0;
238 if( IS_IDE_IRQ_ENABLED() )
239 asic_clear_event( EVENT_IDE );
243 static void ide_set_error( int error_code )
245 idereg.status = 0x51;
246 idereg.error = error_code;
249 uint8_t ide_read_status( void )
251 if( (idereg.status & IDE_STATUS_BSY) == 0 )
252 ide_clear_interrupt();
253 return idereg.status;
256 uint16_t ide_read_data_pio( void ) {
257 if( idereg.state == IDE_STATE_PIO_READ ) {
258 uint16_t rv = READ_BUFFER();
259 idereg.data_offset += 2;
260 idereg.block_left -= 2;
261 if( idereg.data_offset >= idereg.data_length ) {
262 idereg.state = IDE_STATE_IDLE;
263 idereg.status &= ~IDE_STATUS_DRQ;
264 idereg.data_offset = -1;
265 ide_raise_interrupt();
266 } else if( idereg.block_left <= 0 ) {
267 idereg.block_left = idereg.block_length;
268 ide_raise_interrupt();
280 * This method is called from the ASIC side when a DMA read request is
281 * initiated. If there is a pending DMA transfer already, we copy the
282 * data immediately, otherwise we record the DMA buffer for use when we
283 * get to actually doing the transfer.
284 * @return number of bytes transfered
286 uint32_t ide_read_data_dma( uint32_t addr, uint32_t length )
288 if( idereg.state == IDE_STATE_DMA_READ ) {
289 int xferlen = length;
290 int remaining = idereg.data_length - idereg.data_offset;
291 if( xferlen > remaining )
293 mem_copy_to_sh4( addr, data_buffer + idereg.data_offset, xferlen );
294 idereg.data_offset += xferlen;
295 if( idereg.data_offset >= idereg.data_length ) {
296 idereg.data_offset = -1;
297 idereg.state = IDE_STATE_IDLE;
298 idereg.status = 0x50;
299 ide_raise_interrupt();
300 asic_event( EVENT_IDE_DMA );
307 void ide_write_data_pio( uint16_t val ) {
308 if( idereg.state == IDE_STATE_CMD_WRITE ) {
310 idereg.data_offset+=2;
311 if( idereg.data_offset >= idereg.data_length ) {
312 idereg.state = IDE_STATE_BUSY;
313 idereg.status = (idereg.status & ~IDE_STATUS_DRQ) | IDE_STATUS_BSY;
314 idereg.data_offset = -1;
315 ide_packet_command(data_buffer);
317 } else if( idereg.state == IDE_STATE_PIO_WRITE ) {
319 if( idereg.data_offset >= idereg.data_length ) {
320 idereg.state = IDE_STATE_BUSY;
321 idereg.data_offset = -1;
322 idereg.status = (idereg.status & ~IDE_STATUS_DRQ) | IDE_STATUS_BSY;
323 /* ??? - no data writes yet anyway */
328 void ide_write_control( uint8_t val ) {
329 if( IS_IDE_IRQ_ENABLED() ) {
330 if( (val & 0x02) != 0 && idereg.intrq_pending != 0 )
331 asic_clear_event( EVENT_IDE );
333 if( (val & 0x02) == 0 && idereg.intrq_pending != 0 )
334 asic_event( EVENT_IDE );
336 idereg.control = val;
339 void ide_write_command( uint8_t val ) {
340 ide_clear_interrupt();
341 idereg.command = val;
343 case IDE_CMD_NOP: /* Effectively an "abort" */
344 idereg.state = IDE_STATE_IDLE;
345 idereg.status = 0x51;
347 idereg.data_offset = -1;
348 ide_raise_interrupt();
350 case IDE_CMD_RESET_DEVICE:
354 ide_start_command_packet_write();
356 case IDE_CMD_SET_FEATURE:
357 switch( idereg.feature ) {
358 case IDE_FEAT_SET_TRANSFER_MODE:
359 switch( idereg.count & 0xF8 ) {
361 INFO( "Set PIO default mode: %d", idereg.count&0x07 );
363 case IDE_XFER_PIO_FLOW:
364 INFO( "Set PIO Flow-control mode: %d", idereg.count&0x07 );
366 case IDE_XFER_MULTI_DMA:
367 INFO( "Set Multiword DMA mode: %d", idereg.count&0x07 );
369 case IDE_XFER_ULTRA_DMA:
370 INFO( "Set Ultra DMA mode: %d", idereg.count&0x07 );
373 INFO( "Setting unknown transfer mode: %02X", idereg.count );
378 WARN( "IDE: unimplemented feature: %02X", idereg.feature );
380 ide_raise_interrupt( );
383 WARN( "IDE: Unimplemented command: %02X", val );
385 idereg.status = (idereg.status | IDE_STATUS_DRDY | IDE_STATUS_SERV) & (~IDE_STATUS_CHK);
389 * Execute a packet command. This particular method is responsible for parsing
390 * the command buffers (12 bytes), and generating the appropriate responses,
391 * although the actual implementation is mostly delegated to gdrom.c
393 void ide_packet_command( unsigned char *cmd )
395 uint32_t length, datalen;
396 uint32_t lba, status;
398 int blocksize = idereg.lba1 + (idereg.lba2<<8);
400 /* Okay we have the packet in the command buffer */
401 INFO( "ATAPI packet: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
402 cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7],
403 cmd[8], cmd[9], cmd[10], cmd[11] );
405 case PKT_CMD_TEST_READY:
406 if( !gdrom_is_mounted() ) {
407 ide_set_packet_result( PKT_ERR_NODISC );
409 ide_set_packet_result( 0 );
410 ide_raise_interrupt();
411 idereg.status = 0x50;
414 case PKT_CMD_IDENTIFY:
416 if( lba >= sizeof(gdrom_ident) ) {
417 ide_set_error(PKT_ERR_BADFIELD);
420 if( lba+length > sizeof(gdrom_ident) )
421 length = sizeof(gdrom_ident) - lba;
422 memcpy( data_buffer, gdrom_ident + lba, length );
423 ide_start_packet_read( length, blocksize );
430 memcpy( data_buffer, idereg.gdrom_sense, length );
431 ide_start_packet_read( length, blocksize );
433 case PKT_CMD_READ_TOC:
434 length = (cmd[3]<<8) | cmd[4];
435 if( length > sizeof(struct gdrom_toc) )
436 length = sizeof(struct gdrom_toc);
438 status = gdrom_get_toc( data_buffer );
439 if( status != PKT_ERR_OK ) {
440 ide_set_packet_result( status );
442 ide_start_packet_read( length, blocksize );
445 case PKT_CMD_SESSION_INFO:
449 status = gdrom_get_info( data_buffer, cmd[2] );
450 if( status != PKT_ERR_OK ) {
451 ide_set_packet_result( status );
453 ide_start_packet_read( length, blocksize );
456 case PKT_CMD_READ_SECTOR:
457 lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];
458 length = cmd[8] << 16 | cmd[9] << 8 | cmd[10]; /* blocks */
460 case 0x20: mode = GDROM_MODE1; break; /* TODO - might be unchecked? */
461 case 0x24: mode = GDROM_GD; break;
462 case 0x28: mode = GDROM_MODE2_XA1; break; /* ??? */
463 case 0x30: mode = GDROM_RAW; break;
465 ERROR( "Unrecognized read mode '%02X' in GD-Rom read request", cmd[1] );
466 ide_set_packet_result( PKT_ERR_BADFIELD );
470 if( length > data_buffer_len ) {
472 data_buffer_len = data_buffer_len << 1;
473 } while( data_buffer_len < length );
474 data_buffer = realloc( data_buffer, MAX_SECTOR_SIZE * data_buffer_len );
477 datalen = data_buffer_len;
478 status = gdrom_read_sectors( lba, length, mode, data_buffer, &datalen );
480 ide_set_packet_result( status );
481 idereg.gdrom_sense[5] = (lba >> 16) & 0xFF;
482 idereg.gdrom_sense[6] = (lba >> 8) & 0xFF;
483 idereg.gdrom_sense[7] = lba & 0xFF;
485 idereg.last_read_count += length;
486 idereg.last_read_lba = lba + length;
487 idereg.last_read_track = gdrom_get_track_no_by_lba( idereg.last_read_lba );
488 ide_start_packet_read( datalen, blocksize );
491 case PKT_CMD_SPIN_UP:
493 ide_set_packet_result( PKT_ERR_OK );
494 ide_raise_interrupt();
498 if( !gdrom_is_mounted() ) {
499 ide_set_packet_result( PKT_ERR_NODISC );
508 data_buffer[0] = 0x00;
509 data_buffer[1] = 0x15; /* ??? */
510 data_buffer[2] = 0x00;
511 data_buffer[3] = 0x0E;
512 data_buffer[4] = gdrom_get_track(idereg.last_read_track)->flags;
513 data_buffer[5] = idereg.last_read_track;
514 data_buffer[6] = 0x01; /* ?? */
515 data_buffer[7] = (idereg.last_read_count >> 16) & 0xFF;
516 data_buffer[8] = (idereg.last_read_count >> 8) & 0xFF;
517 data_buffer[9] = idereg.last_read_count & 0xFF;
518 data_buffer[10] = (idereg.last_read_lba >> 24) & 0xFF;
519 data_buffer[11] = (idereg.last_read_lba >> 16) & 0xFF;
520 data_buffer[12] = (idereg.last_read_lba >> 8) & 0xFF;
521 data_buffer[13] = idereg.last_read_lba & 0xFF;
522 data_buffer[14] = 0x00;
523 data_buffer[15] = 0x00;
524 ide_start_packet_read( length, blocksize );
530 /* This is a weird one. As far as I can tell it returns random garbage
531 * (and not even the same length each time, never mind the same data).
532 * For sake of something to do, it returns the results from a test dump
534 memcpy( data_buffer, gdrom_71, sizeof(gdrom_71) );
535 ide_start_packet_read( sizeof(gdrom_71), blocksize );
538 ide_set_packet_result( PKT_ERR_BADCMD ); /* Invalid command */
.