Search
lxdream.org :: lxdream/src/gdrom/ide.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/ide.c
changeset 142:2f631c3a3946
prev140:d26f4899898d
next143:9446fb6df0c5
author nkeynes
date Tue May 02 14:09:11 2006 +0000 (14 years ago)
permissions -rw-r--r--
last change Add packet.h
Implement read toc, request sense, test ready commands.
Fix failure to clear error status on new command
file annotate diff log raw
1.1 --- a/src/gdrom/ide.c Sun Apr 30 12:22:31 2006 +0000
1.2 +++ b/src/gdrom/ide.c Tue May 02 14:09:11 2006 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: ide.c,v 1.10 2006-04-30 12:22:31 nkeynes Exp $
1.6 + * $Id: ide.c,v 1.11 2006-05-02 14:09:11 nkeynes Exp $
1.7 *
1.8 * IDE interface implementation
1.9 *
1.10 @@ -24,6 +24,7 @@
1.11 #include "asic.h"
1.12 #include "gdrom/ide.h"
1.13 #include "gdrom/gdrom.h"
1.14 +#include "gdrom/packet.h"
1.15
1.16 #define MAX_WRITE_BUF 4096
1.17 #define MAX_SECTOR_SIZE 2352 /* Audio sector */
1.18 @@ -216,9 +217,23 @@
1.19 default:
1.20 WARN( "IDE: Unimplemented command: %02X", val );
1.21 }
1.22 - idereg.status |= IDE_ST_READY | IDE_ST_SERV;
1.23 + idereg.status = (idereg.status | IDE_ST_READY | IDE_ST_SERV) & (~IDE_ST_ERROR);
1.24 }
1.25
1.26 +void ide_set_packet_error( uint16_t error )
1.27 +{
1.28 + idereg.gdrom_error = error;
1.29 + if( error != 0 ) {
1.30 + idereg.error = (error & 0x0F) << 4;
1.31 + idereg.status = 0x51;
1.32 + }
1.33 +}
1.34 +
1.35 +/**
1.36 + * Execute a packet command. This particular method is responsible for parsing
1.37 + * the command buffers (12 bytes), and generating the appropriate responses,
1.38 + * although the actual implementation is mostly delegated to gdrom.c
1.39 + */
1.40 void ide_packet_command( unsigned char *cmd )
1.41 {
1.42 uint32_t length, datalen;
1.43 @@ -230,13 +245,19 @@
1.44 WARN( "ATAPI: Received Packet command: %02X", cmd[0] );
1.45 fwrite_dump( (unsigned char *)cmd, 12, stderr );
1.46 switch( cmd[0] ) {
1.47 + case PKT_CMD_TEST_READY:
1.48 + if( !gdrom_is_mounted() ) {
1.49 + ide_set_packet_error( PKT_ERR_NODISC );
1.50 + return;
1.51 + }
1.52 + ide_set_packet_error( 0 );
1.53 + idereg.status = 0x50;
1.54 + return;
1.55 + break;
1.56 case PKT_CMD_IDENTIFY:
1.57 - /* NB: Bios sets cmd[4] = 0x08, no idea what this is for;
1.58 - * different values here appear to have no effect.
1.59 - */
1.60 lba = cmd[2];
1.61 if( lba >= sizeof(gdrom_ident) ) {
1.62 - ide_set_error(0x50);
1.63 + ide_set_error(PKT_ERR_BADFIELD);
1.64 return;
1.65 }
1.66 length = cmd[4];
1.67 @@ -244,12 +265,25 @@
1.68 length = sizeof(gdrom_ident) - lba;
1.69 ide_set_read_buffer(gdrom_ident + lba, length, blocksize);
1.70 break;
1.71 + case PKT_CMD_SENSE:
1.72 + memset( data_buffer, 0, 10 );
1.73 + length = cmd[4];
1.74 + if( length > 10 )
1.75 + length = 10;
1.76 + data_buffer[0] = 0xf0;
1.77 + data_buffer[2] = idereg.gdrom_error & 0xFF;
1.78 + data_buffer[8] = (idereg.gdrom_error >> 8) & 0xFF;
1.79 + ide_set_read_buffer( data_buffer, length , blocksize );
1.80 + break;
1.81 case PKT_CMD_READ_TOC:
1.82 if( !gdrom_get_toc( data_buffer ) ) {
1.83 - ide_set_error( 0x50 );
1.84 + ide_set_packet_error( PKT_ERR_NODISC ); /* No disc in drive */
1.85 return;
1.86 }
1.87 - ide_set_read_buffer( data_buffer, sizeof( struct gdrom_toc ), blocksize );
1.88 + length = (cmd[3]<<8) | cmd[4];
1.89 + if( length > sizeof(struct gdrom_toc) )
1.90 + length = sizeof(struct gdrom_toc);
1.91 + ide_set_read_buffer( data_buffer, length, blocksize );
1.92 break;
1.93 case PKT_CMD_READ_SECTOR:
1.94 lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];
1.95 @@ -260,15 +294,24 @@
1.96 } while( data_buffer_len < length );
1.97 data_buffer = realloc( data_buffer, data_buffer_len );
1.98 }
1.99 -
1.100 +
1.101 + if( !gdrom_is_mounted() ) {
1.102 + ide_set_packet_error( PKT_ERR_NODISC );
1.103 + return;
1.104 + }
1.105 +
1.106 datalen = gdrom_read_sectors( lba, length, data_buffer );
1.107 if( datalen == 0 ) {
1.108 - ide_set_error( 0x50 );
1.109 + ide_set_packet_error( 0x05 );
1.110 return;
1.111 }
1.112 ide_set_read_buffer( data_buffer, datalen, blocksize );
1.113 break;
1.114 + default:
1.115 + ide_set_packet_error( PKT_ERR_BADCMD ); /* Invalid command */
1.116 + return;
1.117 }
1.118 + ide_set_packet_error( PKT_ERR_OK );
1.119 }
1.120
1.121 void ide_write_buffer( unsigned char *data, int datalen ) {
.