filename | src/gdrom/ide.c |
changeset | 142:2f631c3a3946 |
prev | 140:d26f4899898d |
next | 143:9446fb6df0c5 |
author | nkeynes |
date | Tue May 02 14:09:11 2006 +0000 (17 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 +00001.2 +++ b/src/gdrom/ide.c Tue May 02 14:09:11 2006 +00001.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 implementation1.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.16 #define MAX_WRITE_BUF 40961.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.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 parsing1.37 + * the command buffers (12 bytes), and generating the appropriate responses,1.38 + * although the actual implementation is mostly delegated to gdrom.c1.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.121 void ide_write_buffer( unsigned char *data, int datalen ) {
.