ide: multi-profile DVD-ROM support v2
RFC 1/1 ide: multi-profile DVD-ROM support v2
The following patch re-implements the "GET CONFIGURATION" MMC-6 command to match the published SPEC.
This is a re-write of the original patch series published but including the feedback received :
http://lists.gnu.org/archive/html/qemu-devel/2007-11/msg00849.html
Important changes from the previous patch :
* Use a 99min CD size as the bigger possible sector count for CD profile
* Don't recalculate the number of sectors
* Use an inline helper function to set the profiles in a cleaner way
* Avoid extra computations from constants while reducing the use of magic numbers and using defines when possible.
Carlo
---
Index: hw/ide.c
===================================================================
RCS file: /sources/qemu/qemu/hw/ide.c,v
retrieving revision 1.79
ide.c +89 -15
@@ -1,5 +1,5 @@/* -* QEMU IDE disk and CD-ROM Emulator +* QEMU IDE disk and CD/DVD-ROM Emulator * * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2006 Openedhand Ltd.
@@ -284,6 +284,44 @@* of MODE_SENSE_POWER_PAGE */ #define GPMODE_CDROM_PAGE 0x0d +/* Some generally useful CD-ROM information */ +#define CD_MINS 99/* max. minutes per CD */ +#define CD_SECS 60/* seconds per minute */ +#define CD_FRAMES 75/* frames per second */ +#define CD_FRAMESIZE 2048/* bytes per frame, "cooked" mode */ +#define CD_MAX_BYTES 912384000/* multiply all of the above */ +#define CD_MAX_SECTORS 1782000/* divide by 512 */ + +/* Profile list from MMC-6 revision 1 table 91 */ +#define MMC_PROFILE_NONE 0x0000 +#define MMC_PROFILE_CD_ROM 0x0008 +#define MMC_PROFILE_CD_R 0x0009 +#define MMC_PROFILE_CD_RW 0x000A +#define MMC_PROFILE_DVD_ROM 0x0010 +#define MMC_PROFILE_DVD_R_SR 0x0011 +#define MMC_PROFILE_DVD_RAM 0x0012 +#define MMC_PROFILE_DVD_RW_RO 0x0013 +#define MMC_PROFILE_DVD_RW_SR 0x0014 +#define MMC_PROFILE_DVD_R_DL_SR 0x0015 +#define MMC_PROFILE_DVD_R_DL_JR 0x0016 +#define MMC_PROFILE_DVD_RW_DL 0x0017 +#define MMC_PROFILE_DVD_DDR 0x0018 +#define MMC_PROFILE_DVD_PLUS_RW 0x001A +#define MMC_PROFILE_DVD_PLUS_R 0x001B +#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A +#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B +#define MMC_PROFILE_BD_ROM 0x0040 +#define MMC_PROFILE_BD_R_SRM 0x0041 +#define MMC_PROFILE_BD_R_RRM 0x0042 +#define MMC_PROFILE_BD_RE 0x0043 +#define MMC_PROFILE_HDDVD_ROM 0x0050 +#define MMC_PROFILE_HDDVD_R 0x0051 +#define MMC_PROFILE_HDDVD_RAM 0x0052 +#define MMC_PROFILE_HDDVD_RW 0x0053 +#define MMC_PROFILE_HDDVD_R_DL 0x0058 +#define MMC_PROFILE_HDDVD_RW_DL 0x005A +#define MMC_PROFILE_INVALID 0xFFFF +#define ATAPI_INT_REASON_CD 0x01/* 0 = data transfer */ #define ATAPI_INT_REASON_IO 0x02/* 1 = transfer to the host */ #define ATAPI_INT_REASON_REL 0x04
@@ -540,7 +578,7 @@ static void ide_atapi_identify(IDEStateput_le16 (p +21 ,512 );/* cache size in sectors */ put_le16 (p +22 ,4 );/* ecc bytes */ padstr ((char *)(p +23 ),QEMU_VERSION ,8 );/* firmware version */ -padstr ((char *)(p +27 ),"QEMU CD-ROM" ,40 );/* model */ +padstr ((char *)(p +27 ),"QEMU DVD-ROM" ,40 );/* model */ put_le16 (p +48 ,1 );/* dword I/O (XXX: should not be set on CDROM) */ #ifdef USE_DMA_CDROM put_le16 (p +49 ,1 <<9 |1 <<8 );/* DMA and LBA supported */
@@ -1290,6 +1328,22 @@ static void ide_atapi_cmd_read(IDEState } } +static inline uint8_t ide_atapi_set_profile (uint8_t *buf,uint8_t *index, +uint16_t profile) +{ +uint8_t *buf_profile = buf +12 ;/* start of profiles */ + + buf_profile += ((*index) *4 );/* start of indexed profile */ +cpu_to_ube16 (buf_profile, profile); + buf_profile[2 ] = ((buf_profile[0 ] == buf[6 ]) && (buf_profile[1 ] == buf[7 ])); + +/* each profile adds 4 bytes to the response */ + (*index)++; + buf[11 ] +=4 ;/* Additional Length */ + +return 4 ; +} +static void ide_atapi_cmd (IDEState *s) {const uint8_t *packet;
@@ -1634,13 +1688,13 @@ static void ide_atapi_cmd(IDEState *s) buf[6 ] =0 ;/* reserved */ buf[7 ] =0 ;/* reserved */ padstr8 (buf +8 ,8 ,"QEMU" ); -padstr8 (buf +16 ,16 ,"QEMU CD-ROM" ); +padstr8 (buf +16 ,16 ,"QEMU DVD-ROM" );padstr8 (buf +32 ,4 ,QEMU_VERSION );ide_atapi_cmd_reply (s,36 , max_len);break ;case GPCMD_GET_CONFIGURATION : { -uint64_t total_sectors; +uint32_t len;/* only feature 0 is supported */ if (packet[2 ] !=0 || packet[3 ] !=0 ) {
@@ -1648,17 +1702,37 @@ static void ide_atapi_cmd(IDEState *s) ASC_INV_FIELD_IN_CMD_PACKET);break ; } -memset (buf,0 ,32 ); -bdrv_get_geometry (s->bs, &total_sectors); - buf[3 ] =16 ; - buf[7 ] = total_sectors <=1433600 ?0x08 :0x10 ;/* current profile */ - buf[10 ] =0x10 |0x1 ; - buf[11 ] =0x08 ;/* size of profile list */ - buf[13 ] =0x10 ;/* DVD-ROM profile */ - buf[14 ] = buf[7 ] ==0x10 ;/* (in)active */ - buf[17 ] =0x08 ;/* CD-ROM profile */ - buf[18 ] = buf[7 ] ==0x08 ;/* (in)active */ -ide_atapi_cmd_reply (s,32 ,32 ); + max_len =ube16_to_cpu (packet +7 ); + +/* XXX: avoid overflow for io_buffer if max_len is too big */ +if (max_len >512 ) + max_len =512 ; + +memset (buf,0 , max_len); + +/* +* the number of sectors from the media tells us which profile +* to use as current. 0 means there is no media +*/ +if ((s -> nb_sectors)) { +if ((s -> nb_sectors >CD_MAX_SECTORS )) +cpu_to_ube16 (buf +6 ,MMC_PROFILE_DVD_ROM ); +else +cpu_to_ube16 (buf +6 ,MMC_PROFILE_CD_ROM ); + } + + len =8 ;/* header completed */ +if (max_len > len) { +uint8_t index =0 ; + + buf[10 ] =0x02 |0x01 ;/* persistent and current */ + len +=4 ;/* header */ + len +=ide_atapi_set_profile (buf, &index,MMC_PROFILE_DVD_ROM ); + len +=ide_atapi_set_profile (buf, &index,MMC_PROFILE_CD_ROM ); + } +cpu_to_ube32 (buf, len -4 );/* data length */ + +ide_atapi_cmd_reply (s, len, max_len);break ; }default :
Quoted 7 lines
ide.c +5
-0+/* Some generally useful CD-ROM information */ +#define CD_MINS 99/* max. minutes per CD */ +#define CD_SECS 60/* seconds per minute */ +#define CD_FRAMES 75/* frames per second */ +#define CD_FRAMESIZE 2048/* bytes per frame, "cooked" mode */ +#define
CD_MAX_BYTES912384000 /* multiply all of the above
*/ +#defineCD_MAX_SECTORS1782000 /* divide by 512 */
The last two should be calculated from the first, not hardcoded values.
Paul
RFC 1/1 ide: multi-profile DVD-ROM support v2.1
This is version 2.1 of the patch to re-implement the "GET CONFIGURATION" MMC-6 command as used by the IDE emulation to match the published SPEC and that was originally published in :
http://lists.gnu.org/archive/html/qemu-devel/2007-11/msg00849.html
Important changes from the previous patches :
* Use a 99min CD size as the bigger possible sector count for CD profile
* Don't recalculate the number of sectors
* Use an inline helper function to set the profiles in a cleaner way
* Avoid extra computations from constants except for #define values
* Reduce the use of magic numbers and use defines when possible
Remaining issues that will need to be addressed in future versions :
* MMC-6 also applies to SCSI devices and so the definitions might need to be moved to a common header when that code is developed.
* The use of the buffer might not be safe for unaligned access in some architectures, but the same applies to all other commands that are currently using the io_buffer directly as the hardware does.
* The heuristic used tries to guess the kind of media from the size of it and is not that reliable for really small DVDs that could fit in a CD.
* The response uses the io_buffer and is therefore limited to the size of it (not really a problem now when the maximum response size will be 20 bytes) but could be a problem when more features/profiles are implemented.
* When using the host_device driver media changes could go unnoticed and result in the wrong profile being selected due to limitations in the current implementation of the ide emulation.
Testing is appreciated
Carlo
---
Index: hw/ide.c
===================================================================
RCS file: /sources/qemu/qemu/hw/ide.c,v
retrieving revision 1.79
ide.c +89 -15
@@ -1,5 +1,5 @@/* -* QEMU IDE disk and CD-ROM Emulator +* QEMU IDE disk and CD/DVD-ROM Emulator * * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2006 Openedhand Ltd.
@@ -284,6 +284,44 @@* of MODE_SENSE_POWER_PAGE */ #define GPMODE_CDROM_PAGE 0x0d +/* Some generally useful CD-ROM information */ +#define CD_MINS 99/* max. minutes per CD */ +#define CD_SECS 60/* seconds per minute */ +#define CD_FRAMES 75/* frames per second */ +#define CD_FRAMESIZE 2048/* bytes per frame, "cooked" mode */ +#define CD_MAX_BYTES (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE) +#define CD_MAX_SECTORS (CD_MAX_BYTES / 512) + +/* Profile list from MMC-6 revision 1 table 91 */ +#define MMC_PROFILE_NONE 0x0000 +#define MMC_PROFILE_CD_ROM 0x0008 +#define MMC_PROFILE_CD_R 0x0009 +#define MMC_PROFILE_CD_RW 0x000A +#define MMC_PROFILE_DVD_ROM 0x0010 +#define MMC_PROFILE_DVD_R_SR 0x0011 +#define MMC_PROFILE_DVD_RAM 0x0012 +#define MMC_PROFILE_DVD_RW_RO 0x0013 +#define MMC_PROFILE_DVD_RW_SR 0x0014 +#define MMC_PROFILE_DVD_R_DL_SR 0x0015 +#define MMC_PROFILE_DVD_R_DL_JR 0x0016 +#define MMC_PROFILE_DVD_RW_DL 0x0017 +#define MMC_PROFILE_DVD_DDR 0x0018 +#define MMC_PROFILE_DVD_PLUS_RW 0x001A +#define MMC_PROFILE_DVD_PLUS_R 0x001B +#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A +#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B +#define MMC_PROFILE_BD_ROM 0x0040 +#define MMC_PROFILE_BD_R_SRM 0x0041 +#define MMC_PROFILE_BD_R_RRM 0x0042 +#define MMC_PROFILE_BD_RE 0x0043 +#define MMC_PROFILE_HDDVD_ROM 0x0050 +#define MMC_PROFILE_HDDVD_R 0x0051 +#define MMC_PROFILE_HDDVD_RAM 0x0052 +#define MMC_PROFILE_HDDVD_RW 0x0053 +#define MMC_PROFILE_HDDVD_R_DL 0x0058 +#define MMC_PROFILE_HDDVD_RW_DL 0x005A +#define MMC_PROFILE_INVALID 0xFFFF +#define ATAPI_INT_REASON_CD 0x01/* 0 = data transfer */ #define ATAPI_INT_REASON_IO 0x02/* 1 = transfer to the host */ #define ATAPI_INT_REASON_REL 0x04
@@ -540,7 +578,7 @@ static void ide_atapi_identify(IDEStateput_le16 (p +21 ,512 );/* cache size in sectors */ put_le16 (p +22 ,4 );/* ecc bytes */ padstr ((char *)(p +23 ),QEMU_VERSION ,8 );/* firmware version */ -padstr ((char *)(p +27 ),"QEMU CD-ROM" ,40 );/* model */ +padstr ((char *)(p +27 ),"QEMU DVD-ROM" ,40 );/* model */ put_le16 (p +48 ,1 );/* dword I/O (XXX: should not be set on CDROM) */ #ifdef USE_DMA_CDROM put_le16 (p +49 ,1 <<9 |1 <<8 );/* DMA and LBA supported */
@@ -1290,6 +1328,22 @@ static void ide_atapi_cmd_read(IDEState } } +static inline uint8_t ide_atapi_set_profile (uint8_t *buf,uint8_t *index, +uint16_t profile) +{ +uint8_t *buf_profile = buf +12 ;/* start of profiles */ + + buf_profile += ((*index) *4 );/* start of indexed profile */ +cpu_to_ube16 (buf_profile, profile); + buf_profile[2 ] = ((buf_profile[0 ] == buf[6 ]) && (buf_profile[1 ] == buf[7 ])); + +/* each profile adds 4 bytes to the response */ + (*index)++; + buf[11 ] +=4 ;/* Additional Length */ + +return 4 ; +} +static void ide_atapi_cmd (IDEState *s) {const uint8_t *packet;
@@ -1634,13 +1688,13 @@ static void ide_atapi_cmd(IDEState *s) buf[6 ] =0 ;/* reserved */ buf[7 ] =0 ;/* reserved */ padstr8 (buf +8 ,8 ,"QEMU" ); -padstr8 (buf +16 ,16 ,"QEMU CD-ROM" ); +padstr8 (buf +16 ,16 ,"QEMU DVD-ROM" );padstr8 (buf +32 ,4 ,QEMU_VERSION );ide_atapi_cmd_reply (s,36 , max_len);break ;case GPCMD_GET_CONFIGURATION : { -uint64_t total_sectors; +uint32_t len;/* only feature 0 is supported */ if (packet[2 ] !=0 || packet[3 ] !=0 ) {
@@ -1648,17 +1702,37 @@ static void ide_atapi_cmd(IDEState *s) ASC_INV_FIELD_IN_CMD_PACKET);break ; } -memset (buf,0 ,32 ); -bdrv_get_geometry (s->bs, &total_sectors); - buf[3 ] =16 ; - buf[7 ] = total_sectors <=1433600 ?0x08 :0x10 ;/* current profile */ - buf[10 ] =0x10 |0x1 ; - buf[11 ] =0x08 ;/* size of profile list */ - buf[13 ] =0x10 ;/* DVD-ROM profile */ - buf[14 ] = buf[7 ] ==0x10 ;/* (in)active */ - buf[17 ] =0x08 ;/* CD-ROM profile */ - buf[18 ] = buf[7 ] ==0x08 ;/* (in)active */ -ide_atapi_cmd_reply (s,32 ,32 ); + max_len =ube16_to_cpu (packet +7 ); + +/* XXX: avoid overflow for io_buffer if max_len is too big */ +if (max_len >512 ) + max_len =512 ; + +memset (buf,0 , max_len); + +/* +* the number of sectors from the media tells us which profile +* to use as current. 0 means there is no media +*/ +if ((s -> nb_sectors)) { +if ((s -> nb_sectors >CD_MAX_SECTORS )) +cpu_to_ube16 (buf +6 ,MMC_PROFILE_DVD_ROM ); +else +cpu_to_ube16 (buf +6 ,MMC_PROFILE_CD_ROM ); + } + + len =8 ;/* header completed */ +if (max_len > len) { +uint8_t index =0 ; + + buf[10 ] =0x02 |0x01 ;/* persistent and current */ + len +=4 ;/* header */ + len +=ide_atapi_set_profile (buf, &index,MMC_PROFILE_DVD_ROM ); + len +=ide_atapi_set_profile (buf, &index,MMC_PROFILE_CD_ROM ); + } +cpu_to_ube32 (buf, len -4 );/* data length */ + +ide_atapi_cmd_reply (s, len, max_len);break ; }default :
Re: [Qemu-devel] [RFC] ide: multi-profile DVD-ROM support v2.1
Quoted 16 lines · Carlo Marcelo Arenas Belon
This is version 2.1 of the patch to re-implement the "GET CONFIGURATION" MMC-6 command as used by the IDE emulation to match the published SPEC and that was originally published in :
http://lists.gnu.org/archive/html/qemu-devel/2007-11/msg00849.html
Important changes from the previous patches :
* Use a 99min CD size as the bigger possible sector count for CD profile
* Don't recalculate the number of sectors
* Use an inline helper function to set the profiles in a cleaner way
* Avoid extra computations from constants except for #define values
* Reduce the use of magic numbers and use defines when possibleRemaining issues that will need to be addressed in future versions :
Quoted 15 lines
* MMC-6 also applies to SCSI devices and so the definitions might need to be moved to a common header when that code is developed.
* The use of the buffer might not be safe for unaligned access in some architectures, but the same applies to all other commands that are currently using theio_bufferdirectly as the hardware does.
* The heuristic used tries to guess the kind of media from the size of it and is not that reliable for really small DVDs that could fit in a CD.
* The response uses theio_bufferand is therefore limited to the size of it (not really a problem now when the maximum response size will be 20 bytes) but could be a problem when more features/profiles are implemented.
* When using thehost_devicedriver media changes could go unnoticed and result in the wrong profile being selected due to limitations in the current implementation of the ide emulation.
Please add those caveats as comments to the source code.
Thiemo
PATCH 1/1 ide: multi-profile DVD-ROM support v2.2
This is version 2.2 of the patch to re-implement the "GET CONFIGURATION" MMC-6 command as used by the IDE emulation to match the published SPEC and that was originally published in :
http://lists.gnu.org/archive/html/qemu-devel/2007-11/msg00849.html
Important changes from the previous patches :
* Use a 80min size as the bigger orange book compatible sector count for CD profile
* Don't recalculate the number of sectors
* Use an inline helper function to set the profiles
Carlo
---
Index: hw/ide.c
===================================================================
RCS file: /sources/qemu/qemu/hw/ide.c,v
retrieving revision 1.79
ide.c +112 -15
@@ -1,5 +1,5 @@/* -* QEMU IDE disk and CD-ROM Emulator +* QEMU IDE disk and CD/DVD-ROM Emulator * * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2006 Openedhand Ltd.
@@ -284,6 +284,58 @@* of MODE_SENSE_POWER_PAGE */ #define GPMODE_CDROM_PAGE 0x0d +/* +* Based on values from <linux/cdrom.h> but extending CD_MINS +* to the maximum common size allowed by the Orange's Book ATIP +* +* 90 and 99 min CDs are also available but using them as the +* upper limit reduces the effectiveness of the heuristic to +* detect DVDs burned to less than 25% of their maximum capacity +*/ + +/* Some generally useful CD-ROM information */ +#define CD_MINS 80/* max. minutes per CD */ +#define CD_SECS 60/* seconds per minute */ +#define CD_FRAMES 75/* frames per second */ +#define CD_FRAMESIZE 2048/* bytes per frame, "cooked" mode */ +#define CD_MAX_BYTES (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE) +#define CD_MAX_SECTORS (CD_MAX_BYTES / 512) + +/* +* The MMC values are not IDE specific and might need to be moved +* to a common header if they are also needed for the SCSI emulation +*/ + +/* Profile list from MMC-6 revision 1 table 91 */ +#define MMC_PROFILE_NONE 0x0000 +#define MMC_PROFILE_CD_ROM 0x0008 +#define MMC_PROFILE_CD_R 0x0009 +#define MMC_PROFILE_CD_RW 0x000A +#define MMC_PROFILE_DVD_ROM 0x0010 +#define MMC_PROFILE_DVD_R_SR 0x0011 +#define MMC_PROFILE_DVD_RAM 0x0012 +#define MMC_PROFILE_DVD_RW_RO 0x0013 +#define MMC_PROFILE_DVD_RW_SR 0x0014 +#define MMC_PROFILE_DVD_R_DL_SR 0x0015 +#define MMC_PROFILE_DVD_R_DL_JR 0x0016 +#define MMC_PROFILE_DVD_RW_DL 0x0017 +#define MMC_PROFILE_DVD_DDR 0x0018 +#define MMC_PROFILE_DVD_PLUS_RW 0x001A +#define MMC_PROFILE_DVD_PLUS_R 0x001B +#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A +#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B +#define MMC_PROFILE_BD_ROM 0x0040 +#define MMC_PROFILE_BD_R_SRM 0x0041 +#define MMC_PROFILE_BD_R_RRM 0x0042 +#define MMC_PROFILE_BD_RE 0x0043 +#define MMC_PROFILE_HDDVD_ROM 0x0050 +#define MMC_PROFILE_HDDVD_R 0x0051 +#define MMC_PROFILE_HDDVD_RAM 0x0052 +#define MMC_PROFILE_HDDVD_RW 0x0053 +#define MMC_PROFILE_HDDVD_R_DL 0x0058 +#define MMC_PROFILE_HDDVD_RW_DL 0x005A +#define MMC_PROFILE_INVALID 0xFFFF +#define ATAPI_INT_REASON_CD 0x01/* 0 = data transfer */ #define ATAPI_INT_REASON_IO 0x02/* 1 = transfer to the host */ #define ATAPI_INT_REASON_REL 0x04
@@ -540,7 +592,7 @@put_le16 (p +21 ,512 );/* cache size in sectors */ put_le16 (p +22 ,4 );/* ecc bytes */ padstr ((char *)(p +23 ),QEMU_VERSION ,8 );/* firmware version */ -padstr ((char *)(p +27 ),"QEMU CD-ROM" ,40 );/* model */ +padstr ((char *)(p +27 ),"QEMU DVD-ROM" ,40 );/* model */ put_le16 (p +48 ,1 );/* dword I/O (XXX: should not be set on CDROM) */ #ifdef USE_DMA_CDROM put_le16 (p +49 ,1 <<9 |1 <<8 );/* DMA and LBA supported */
@@ -1290,6 +1342,22 @@ } } +static inline uint8_t ide_atapi_set_profile (uint8_t *buf,uint8_t *index, +uint16_t profile) +{ +uint8_t *buf_profile = buf +12 ;/* start of profiles */ + + buf_profile += ((*index) *4 );/* start of indexed profile */ +cpu_to_ube16 (buf_profile, profile); + buf_profile[2 ] = ((buf_profile[0 ] == buf[6 ]) && (buf_profile[1 ] == buf[7 ])); + +/* each profile adds 4 bytes to the response */ + (*index)++; + buf[11 ] +=4 ;/* Additional Length */ + +return 4 ; +} +static void ide_atapi_cmd (IDEState *s) {const uint8_t *packet;
@@ -1634,13 +1702,13 @@ buf[6 ] =0 ;/* reserved */ buf[7 ] =0 ;/* reserved */ padstr8 (buf +8 ,8 ,"QEMU" ); -padstr8 (buf +16 ,16 ,"QEMU CD-ROM" ); +padstr8 (buf +16 ,16 ,"QEMU DVD-ROM" );padstr8 (buf +32 ,4 ,QEMU_VERSION );ide_atapi_cmd_reply (s,36 , max_len);break ;case GPCMD_GET_CONFIGURATION : { -uint64_t total_sectors; +uint32_t len;/* only feature 0 is supported */ if (packet[2 ] !=0 || packet[3 ] !=0 ) {
@@ -1648,17 +1716,46 @@ ASC_INV_FIELD_IN_CMD_PACKET);break ; } -memset (buf,0 ,32 ); -bdrv_get_geometry (s->bs, &total_sectors); - buf[3 ] =16 ; - buf[7 ] = total_sectors <=1433600 ?0x08 :0x10 ;/* current profile */ - buf[10 ] =0x10 |0x1 ; - buf[11 ] =0x08 ;/* size of profile list */ - buf[13 ] =0x10 ;/* DVD-ROM profile */ - buf[14 ] = buf[7 ] ==0x10 ;/* (in)active */ - buf[17 ] =0x08 ;/* CD-ROM profile */ - buf[18 ] = buf[7 ] ==0x08 ;/* (in)active */ -ide_atapi_cmd_reply (s,32 ,32 ); + +/* XXX: could result in alignment problems in some architectures */ + max_len =ube16_to_cpu (packet +7 ); +/* +* XXX: avoid overflow for io_buffer if max_len is bigger than the +* size of that buffer (dimensioned to max number of sectors +* to transfer at once) +* +* Only a problem if the feature/profiles grow exponentially. +*/ +if (max_len >512 )/* XXX: assume 1 sector */ + max_len =512 ; + +memset (buf,0 , max_len); +/* +* the number of sectors from the media tells us which profile +* to use as current. 0 means there is no media +* +* XXX: fails to detect correctly DVDs with less data burned +* than what a CD can hold +*/ +if ((s -> nb_sectors)) { +if ((s -> nb_sectors >CD_MAX_SECTORS )) +cpu_to_ube16 (buf +6 ,MMC_PROFILE_DVD_ROM ); +else +cpu_to_ube16 (buf +6 ,MMC_PROFILE_CD_ROM ); + } + + len =8 ;/* header completed */ +if (max_len > len) { +uint8_t index =0 ; + + buf[10 ] =0x02 |0x01 ;/* persistent and current */ + len +=4 ;/* header */ + len +=ide_atapi_set_profile (buf, &index,MMC_PROFILE_DVD_ROM ); + len +=ide_atapi_set_profile (buf, &index,MMC_PROFILE_CD_ROM ); + } +cpu_to_ube32 (buf, len -4 );/* data length */ + +ide_atapi_cmd_reply (s, len, max_len);break ; }default :