2 * $Id: ide.c,v 1.17 2006-12-15 10:18:39 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;
139 static void ide_save_state( FILE *f )
141 fwrite( &idereg, sizeof(idereg), 1, f );
142 fwrite( &data_buffer_len, sizeof(data_buffer_len), 1, f );
143 fwrite( data_buffer, MAX_SECTOR_SIZE, data_buffer_len, f );
146 static int ide_load_state( FILE *f )
149 fread( &idereg, sizeof(idereg), 1, f );
150 fread( &length, sizeof(uint32_t), 1, f );
151 if( length > data_buffer_len ) {
152 if( data_buffer != NULL )
154 data_buffer = malloc( MAX_SECTOR_SIZE * length );
155 assert( data_buffer != NULL );
156 data_buffer_len = length;
158 fread( data_buffer, MAX_SECTOR_SIZE, length, f );
162 /************************ State transitions *************************/
164 void ide_set_packet_result( uint16_t result )
166 idereg.gdrom_sense[0] = 0xf0;
167 idereg.gdrom_sense[2] = result & 0xFF;
168 idereg.gdrom_sense[8] = (result >> 8) & 0xFF;
169 idereg.error = (result & 0x0F) << 4;
171 idereg.status = 0x51;
172 ide_raise_interrupt();
174 idereg.status = idereg.status & ~(IDE_STATUS_BSY|IDE_STATUS_CHK);
179 * Begin command packet write to the device. This is always 12 bytes of PIO data
181 static void ide_start_command_packet_write( )
183 idereg.state = IDE_STATE_CMD_WRITE;
184 idereg.status = IDE_STATUS_DRDY | IDE_STATUS_DRQ;
185 idereg.error = idereg.feature & 0x03; /* Copy values of OVL/DMA */
186 idereg.count = IDE_COUNT_CD;
187 idereg.data_offset = 0;
188 idereg.data_length = 12;
192 * Begin PIO read from the device. The data is assumed to already be
193 * in the buffer at this point.
195 static void ide_start_read( int length, int blocksize, gboolean dma )
197 idereg.count = IDE_COUNT_IO;
198 idereg.data_length = length;
199 idereg.data_offset = 0;
201 idereg.state = IDE_STATE_DMA_READ;
202 idereg.status = 0xD0;
204 idereg.state = IDE_STATE_PIO_READ;
205 idereg.status = IDE_STATUS_DRDY | IDE_STATUS_DRQ;
206 idereg.lba1 = length & 0xFF;
207 idereg.lba2 = (length >> 8) & 0xFF;
208 // idereg.lba1 = blocksize & 0xFF;
209 // idereg.lba2 = blocksize >> 8;
210 idereg.block_length = blocksize;
211 idereg.block_left = blocksize;
212 ide_raise_interrupt( );
216 static void ide_start_packet_read( int length, int blocksize )
218 ide_set_packet_result( PKT_ERR_OK );
219 ide_start_read( length, blocksize, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );
222 static void ide_raise_interrupt( void )
224 if( idereg.intrq_pending == 0 ) {
225 idereg.intrq_pending = 1;
226 if( IS_IDE_IRQ_ENABLED() )
227 asic_event( EVENT_IDE );
231 static void ide_clear_interrupt( void )
233 if( idereg.intrq_pending != 0 ) {
234 idereg.intrq_pending = 0;
235 if( IS_IDE_IRQ_ENABLED() )
236 asic_clear_event( EVENT_IDE );
240 static void ide_set_error( int error_code )
242 idereg.status = 0x51;
243 idereg.error = error_code;
246 uint8_t ide_read_status( void )
248 if( (idereg.status & IDE_STATUS_BSY) == 0 )
249 ide_clear_interrupt();
250 return idereg.status;
253 uint16_t ide_read_data_pio( void ) {
254 if( idereg.state == IDE_STATE_PIO_READ ) {
255 uint16_t rv = READ_BUFFER();
256 idereg.data_offset += 2;
257 idereg.block_left -= 2;
258 if( idereg.data_offset >= idereg.data_length ) {
259 idereg.state = IDE_STATE_IDLE;
260 idereg.status &= ~IDE_STATUS_DRQ;
261 idereg.data_offset = -1;
262 ide_raise_interrupt();
263 } else if( idereg.block_left <= 0 ) {
264 idereg.block_left = idereg.block_length;
265 ide_raise_interrupt();
277 * This method is called from the ASIC side when a DMA read request is
278 * initiated. If there is a pending DMA transfer already, we copy the
279 * data immediately, otherwise we record the DMA buffer for use when we
280 * get to actually doing the transfer.
281 * @return number of bytes transfered
283 uint32_t ide_read_data_dma( uint32_t addr, uint32_t length )
285 if( idereg.state == IDE_STATE_DMA_READ ) {
286 int xferlen = length;
287 int remaining = idereg.data_length - idereg.data_offset;
288 if( xferlen > remaining )
290 mem_copy_to_sh4( addr, data_buffer + idereg.data_offset, xferlen );
291 idereg.data_offset += xferlen;
292 if( idereg.data_offset >= idereg.data_length ) {
293 idereg.data_offset = -1;
294 idereg.state = IDE_STATE_IDLE;
295 idereg.status = 0x50;
296 ide_raise_interrupt();
297 asic_event( EVENT_IDE_DMA );
304 void ide_write_data_pio( uint16_t val ) {
305 if( idereg.state == IDE_STATE_CMD_WRITE ) {
307 idereg.data_offset+=2;
308 if( idereg.data_offset >= idereg.data_length ) {
309 idereg.state = IDE_STATE_BUSY;
310 idereg.status = (idereg.status & ~IDE_STATUS_DRQ) | IDE_STATUS_BSY;
311 idereg.data_offset = -1;
312 ide_packet_command(data_buffer);
314 } else if( idereg.state == IDE_STATE_PIO_WRITE ) {
316 if( idereg.data_offset >= idereg.data_length ) {
317 idereg.state = IDE_STATE_BUSY;
318 idereg.data_offset = -1;
319 idereg.status = (idereg.status & ~IDE_STATUS_DRQ) | IDE_STATUS_BSY;
320 /* ??? - no data writes yet anyway */
325 void ide_write_control( uint8_t val ) {
326 if( IS_IDE_IRQ_ENABLED() ) {
327 if( (val & 0x02) != 0 && idereg.intrq_pending != 0 )
328 asic_clear_event( EVENT_IDE );
330 if( (val & 0x02) == 0 && idereg.intrq_pending != 0 )
331 asic_event( EVENT_IDE );
333 idereg.control = val;
336 void ide_write_command( uint8_t val ) {
337 ide_clear_interrupt();
338 idereg.command = val;
340 case IDE_CMD_NOP: /* Effectively an "abort" */
341 idereg.state = IDE_STATE_IDLE;
342 idereg.status = 0x51;
344 idereg.data_offset = -1;
345 ide_raise_interrupt();
347 case IDE_CMD_RESET_DEVICE:
351 ide_start_command_packet_write();
353 case IDE_CMD_SET_FEATURE:
354 switch( idereg.feature ) {
355 case IDE_FEAT_SET_TRANSFER_MODE:
356 switch( idereg.count & 0xF8 ) {
358 INFO( "Set PIO default mode: %d", idereg.count&0x07 );
360 case IDE_XFER_PIO_FLOW:
361 INFO( "Set PIO Flow-control mode: %d", idereg.count&0x07 );
363 case IDE_XFER_MULTI_DMA:
364 INFO( "Set Multiword DMA mode: %d", idereg.count&0x07 );
366 case IDE_XFER_ULTRA_DMA:
367 INFO( "Set Ultra DMA mode: %d", idereg.count&0x07 );
370 INFO( "Setting unknown transfer mode: %02X", idereg.count );
375 WARN( "IDE: unimplemented feature: %02X", idereg.feature );
377 ide_raise_interrupt( );
380 WARN( "IDE: Unimplemented command: %02X", val );
382 idereg.status = (idereg.status | IDE_STATUS_DRDY | IDE_STATUS_SERV) & (~IDE_STATUS_CHK);
386 * Execute a packet command. This particular method is responsible for parsing
387 * the command buffers (12 bytes), and generating the appropriate responses,
388 * although the actual implementation is mostly delegated to gdrom.c
390 void ide_packet_command( unsigned char *cmd )
392 uint32_t length, datalen;
393 uint32_t lba, status;
395 int blocksize = idereg.lba1 + (idereg.lba2<<8);
397 /* Okay we have the packet in the command buffer */
398 INFO( "ATAPI packet: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
399 cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7],
400 cmd[8], cmd[9], cmd[10], cmd[11] );
402 case PKT_CMD_TEST_READY:
403 if( !gdrom_is_mounted() ) {
404 ide_set_packet_result( PKT_ERR_NODISC );
406 ide_set_packet_result( 0 );
407 ide_raise_interrupt();
408 idereg.status = 0x50;
411 case PKT_CMD_IDENTIFY:
413 if( lba >= sizeof(gdrom_ident) ) {
414 ide_set_error(PKT_ERR_BADFIELD);
417 if( lba+length > sizeof(gdrom_ident) )
418 length = sizeof(gdrom_ident) - lba;
419 memcpy( data_buffer, gdrom_ident + lba, length );
420 ide_start_packet_read( length, blocksize );
427 memcpy( data_buffer, idereg.gdrom_sense, length );
428 ide_start_packet_read( length, blocksize );
430 case PKT_CMD_READ_TOC:
431 length = (cmd[3]<<8) | cmd[4];
432 if( length > sizeof(struct gdrom_toc) )
433 length = sizeof(struct gdrom_toc);
435 status = gdrom_get_toc( data_buffer );
436 if( status != PKT_ERR_OK ) {
437 ide_set_packet_result( status );
439 ide_start_packet_read( length, blocksize );
442 case PKT_CMD_SESSION_INFO:
446 status = gdrom_get_info( data_buffer, cmd[2] );
447 if( status != PKT_ERR_OK ) {
448 ide_set_packet_result( status );
450 ide_start_packet_read( length, blocksize );
453 case PKT_CMD_READ_SECTOR:
454 lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];
455 length = cmd[8] << 16 | cmd[9] << 8 | cmd[10]; /* blocks */
457 case 0x20: mode = GDROM_MODE1; break;
458 case 0x24: mode = GDROM_GD; break;
459 case 0x28: mode = GDROM_MODE1; break; /* ??? */
460 case 0x30: mode = GDROM_RAW; break;
462 ERROR( "Unrecognized read mode '%02X' in GD-Rom read request", cmd[1] );
463 ide_set_packet_result( PKT_ERR_BADFIELD );
467 if( length > data_buffer_len ) {
469 data_buffer_len = data_buffer_len << 1;
470 } while( data_buffer_len < length );
471 data_buffer = realloc( data_buffer, MAX_SECTOR_SIZE * data_buffer_len );
474 datalen = data_buffer_len;
475 status = gdrom_read_sectors( lba, length, mode, data_buffer, &datalen );
477 ide_set_packet_result( status );
478 idereg.gdrom_sense[5] = (lba >> 16) & 0xFF;
479 idereg.gdrom_sense[6] = (lba >> 8) & 0xFF;
480 idereg.gdrom_sense[7] = lba & 0xFF;
482 ide_start_packet_read( datalen, blocksize );
485 case PKT_CMD_SPIN_UP:
487 ide_set_packet_result( PKT_ERR_OK );
488 ide_raise_interrupt();
491 /* This is a weird one. As far as I can tell it returns random garbage
492 * (and not even the same length each time, never mind the same data).
493 * For sake of something to do, it returns the results from a test dump
495 memcpy( data_buffer, gdrom_71, sizeof(gdrom_71) );
496 ide_start_packet_read( sizeof(gdrom_71), blocksize );
499 ide_set_packet_result( PKT_ERR_BADCMD ); /* Invalid command */
.