diff --git a/include/cdio/mmc.h b/include/cdio/mmc.h index d0121b72..07639f19 100644 --- a/include/cdio/mmc.h +++ b/include/cdio/mmc.h @@ -1,5 +1,5 @@ /* - $Id: mmc.h,v 1.9 2005/02/12 15:27:22 rocky Exp $ + $Id: mmc.h,v 1.10 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -358,10 +358,10 @@ typedef enum scsi_mmc_direction { #define CDIO_MMC_SET_READ_LENGTH8(cdb, len) \ cdb[8] = (len ) & 0xff -#define CDIO_MMC_MCSB_ALL_HEADERS 0x78 +#define CDIO_MMC_MCSB_ALL_HEADERS 0xf #define CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb, val) \ - cdb[9] = val; + cdb[9] = val << 3; /*! * Eject using MMC commands. @@ -490,12 +490,137 @@ int mmc_mode_sense_10( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size, int mmc_mode_sense_6( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size, int page); +/*! Issue a MMC READ_CD command. -/*! Packet driver to read mode2 sectors. - Can read only up to 25 blocks. + @param p_cdio object to read from + + @param p_buf Place to store data. The caller should ensure that + p_buf can hold at least i_blocksize * i_blocks bytes. + + @param i_lsn sector to read + + @param expected_sector_type restricts reading to a specific CD + sector type. Only 3 bits with values 1-5 are used: + 0 all sector types + 1 CD-DA sectors only + 2 Mode 1 sectors only + 3 Mode 2 formless sectors only. Note in contrast to all other + values an MMC CD-ROM is not required to support this mode. + 4 Mode 2 Form 1 sectors only + 5 Mode 2 Form 2 sectors only + + @param b_digital_audio_play Control error concealment when the + data being read is CD-DA. If the data being read is not CD-DA, + this parameter is ignored. If the data being read is CD-DA and + DAP is false zero, then the user data returned should not be + modified by flaw obscuring mechanisms such as audio data mute and + interpolate. If the data being read is CD-DA and DAP is true, + then the user data returned should be modified by flaw obscuring + mechanisms such as audio data mute and interpolate. + + b_sync_header return the sync header (which will probably have + the same value as CDIO_SECTOR_SYNC_HEADER of size + CDIO_CD_SYNC_SIZE). + + @param header_codes Header Codes refer to the sector header and + the sub-header that is present in mode 2 formed sectors: + + 0 No header information is returned. + 1 The 4-byte sector header of data sectors is be returned, + 2 The 8-byte sector sub-header of mode 2 formed sectors is + returned. + 3 Both sector header and sub-header (12 bytes) is returned. + The Header preceeds the rest of the bytes (e.g. user-data bytes) + that might get returned. + + @param b_user_data Return user data if true. + + For CD-DA, the User Data is CDIO_CD_FRAMESIZE_RAW bytes. + + For Mode 1, The User Data is ISO_BLOCKSIZE bytes beginning at + offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE. + + For Mode 2 formless, The User Data is M2RAW_SECTOR_SIZE bytes + beginning at offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE. + + For data Mode 2, form 1, User Data is ISO_BLOCKSIZE bytes beginning at + offset CDIO_CD_XA_SYNC_HEADER. + + For data Mode 2, form 2, User Data is 2 324 bytes beginning at + offset CDIO_CD_XA_SYNC_HEADER. + + @param b_edc_ecc, Return EDC/ECC error detection/correction bits. + + The presence and size of EDC redundancy or ECC parity is defined + according to sector type: + + CD-DA sectors have neither EDC redundancy nor ECC parity. + + Data Mode 1 sectors have 288 bytes of EDC redundancy, Pad, and + ECC parity beginning at offset 2064. + + Data Mode 2 formless sectors have neither EDC redundancy nor ECC + parity + + Data Mode 2 form 1 sectors have 280 bytes of EDC redundancy and + ECC parity beginning at offset 2072 + + Data Mode 2 form 2 sectors optionally have 4 bytes of EDC + redundancy beginning at offset 2348. + + + @param c2_error_information If true associate a bit with each + sector for C2 error The resulting bit field is ordered exactly as + the main channel bytes. Each 8-bit boundary defines a byte of + flag bits. + + @param subchannel_selection subchannel-selection bits + + 0 No Sub-channel data shall be returned. (0 bytes) + 1 RAW P-W Sub-channel data shall be returned. (96 byte) + 2 Formatted Q sub-channel data shall be transferred (16 bytes) + 3 Reserved + 4 Corrected and de-interleaved R-W sub-channel (96 bytes) + 5-7 Reserved + + @param i_blocksize size of the a block expected to be returned + + @param i_blocks number of blocks expected to be returned. + */ -int mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, lba_t lba, - int sector_type, unsigned int i_blocks); +driver_return_code_t +mmc_read_cd ( const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, + int expected_sector_type, bool b_digital_audio_play, + bool b_sync, uint8_t header_codes, bool b_user_data, + bool b_edc_ecc, uint8_t c2_error_information, + uint8_t subchannel_selection, uint16_t i_blocksize, + uint32_t i_blocks ); + +/*! Read just the user data part of some sort of data sector (via + mmc_read_cd). + + @param p_cdio object to read from + + @param p_buf place to read data into. The caller should make sure + this location can store at least CDIO_CD_FRAMESIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending on + the kind of sector getting read. If you don't know + whether you have a Mode 1/2, Form 1/ Form 2/Formless + sector best to reserve space for the maximum, + M2RAW_SECTOR_SIZE. + + @param i_lsn sector to read + +*/ +driver_return_code_t mmc_read_data_sector ( CdIo_t *p_cdio, void *p_buf, + lsn_t i_lsn, + uint16_t i_blocksize ); + +/*! issue a MMC read mode2 sectors. - depricated. +*/ +driver_return_code_t mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, + lsn_t i_lsn, int read_sector_type, + uint32_t i_blocks); /*! Run an MMC command. @@ -520,7 +645,7 @@ int mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms, Set the block size for subsequest read requests, via MMC. */ driver_return_code_t mmc_set_blocksize ( const CdIo_t *p_cdio, - unsigned int i_bsize); + uint16_t i_blocksize); /*! Set the drive speed. diff --git a/include/cdio/read.h b/include/cdio/read.h index f6261e4b..59f0d9cd 100644 --- a/include/cdio/read.h +++ b/include/cdio/read.h @@ -1,5 +1,5 @@ /* -*- c -*- - $Id: read.h,v 1.3 2005/01/23 19:16:58 rocky Exp $ + $Id: read.h,v 1.4 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2005 Rocky Bernstein @@ -49,7 +49,8 @@ extern "C" { Similar to (if not the same as) libc's read() @param p_cdio object to read from - @param p_buf place to read data into + @param p_buf place to read data into. The caller should make sure + this location can store at least i_size bytes. @param i_size number of bytes to read @return (ssize_t) -1 on error. @@ -60,7 +61,9 @@ extern "C" { Read an audio sector @param p_cdio object to read from - @param p_buf place to read data into + @param p_buf place to read data into. The caller should make sure + this location can store at least CDIO_FRAMESIZE_RAW + bytes. @param i_lsn sector to read */ driver_return_code_t cdio_read_audio_sector (const CdIo_t *p_cdio, @@ -70,19 +73,41 @@ extern "C" { Reads audio sectors @param p_cdio object to read from - @param p_buf place to read data into + @param p_buf place to read data into. The caller should make sure + this location can store at least CDIO_FRAMESIZE_RAW + * i_blocks bytes. @param i_lsn sector to read - @param i_sectors number of sectors to read + @param i_blocks number of sectors to read */ driver_return_code_t cdio_read_audio_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, - unsigned int i_sectors); + uint32_t i_blocks); + + /*! + Read a data sector + + @param p_cdio object to read from + @param p_buf place to read data into. The caller should make sure + this location can store at least ISO_BLOCKSIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending + on the kind of sector getting read. If you don't + know whether you have a Mode 1/2, Form 1/ Form 2/Formless + sector best to reserve space for the maximum, + M2RAW_SECTOR_SIZE. + @param i_lsn sector to read + @param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf. + */ + driver_return_code_t cdio_read_data_sector (const CdIo_t *p_cdio, + void *p_buf, lsn_t i_lsn, + uint16_t i_blocksize + ); /*! Reads a mode 1 sector @param p_cdio object to read from - @param p_buf place to read data into + @param p_buf place to read data into. @param i_lsn sector to read @param b_form2 true for reading mode 1 form 2 sectors or false for mode 1 form 1 sectors. @@ -99,18 +124,21 @@ extern "C" { @param i_lsn sector to read @param b_form2 true for reading mode 1 form 2 sectors or false for mode 1 form 1 sectors. - @param i_sectors number of sectors to read + @param i_blocks number of sectors to read */ driver_return_code_t cdio_read_mode1_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, bool b_form2, - unsigned int i_sectors); + uint32_t i_blocks); /*! Reads a mode 2 sector @param p_cdio object to read from - @param p_buf place to read data into + @param p_buf place to read data into. The caller should make sure + this location can store at least + M2RAW_SECTOR_SIZE (for form 1) or CDIO_CD_FRAMESIZE (for + form 2) bytes. @param i_lsn sector to read @param b_form2 true for reading mode 2 form 2 sectors or false for mode 2 form 1 sectors. @@ -125,18 +153,21 @@ extern "C" { Reads mode 2 sectors @param p_cdio object to read from - @param p_buf place to read data into + @param p_buf place to read data into. The caller should make sure + this location can store at least + M2RAW_SECTOR_SIZE (for form 1) or CDIO_CD_FRAMESIZE (for + form 2) * i_blocks bytes. @param i_lsn sector to read @param b_form2 true for reading mode2 form 2 sectors or false for mode 2 form 1 sectors. - @param i_sectors number of sectors to read + @param i_blocks number of sectors to read @return 0 if no error, nonzero otherwise. */ driver_return_code_t cdio_read_mode2_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, bool b_form2, - unsigned int i_sectors); + uint32_t i_blocks); #ifdef __cplusplus } diff --git a/lib/driver/FreeBSD/freebsd.c b/lib/driver/FreeBSD/freebsd.c index f21bf8f8..a24c6f5b 100644 --- a/lib/driver/FreeBSD/freebsd.c +++ b/lib/driver/FreeBSD/freebsd.c @@ -1,5 +1,5 @@ /* - $Id: freebsd.c,v 1.17 2005/02/06 13:05:42 rocky Exp $ + $Id: freebsd.c,v 1.18 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -27,7 +27,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: freebsd.c,v 1.17 2005/02/06 13:05:42 rocky Exp $"; +static const char _rcsid[] = "$Id: freebsd.c,v 1.18 2005/02/17 04:57:21 rocky Exp $"; #include "freebsd.h" @@ -130,7 +130,7 @@ _read_mode2_sectors_freebsd (void *user_data, void *data, lsn_t lsn, return read_mode2_sectors_freebsd_cam(env, data, lsn, nblocks); } else { unsigned int i; - unsigned int i_blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE; + uint16_t i_blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE; /* For each frame, pick out the data part we need */ for (i = 0; i < nblocks; i++) { diff --git a/lib/driver/_cdio_generic.c b/lib/driver/_cdio_generic.c index 6ea10126..903fc7f0 100644 --- a/lib/driver/_cdio_generic.c +++ b/lib/driver/_cdio_generic.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_generic.c,v 1.15 2005/02/06 11:13:37 rocky Exp $ + $Id: _cdio_generic.c,v 1.16 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -25,7 +25,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.15 2005/02/06 11:13:37 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.16 2005/02/17 04:57:21 rocky Exp $"; #include #include @@ -63,7 +63,8 @@ cdio_generic_unimplemented_eject_media (void *p_user_data) { Set the blocksize for subsequent reads. */ int -cdio_generic_unimplemented_set_blocksize (void *p_user_data, int i_blocksize) { +cdio_generic_unimplemented_set_blocksize (void *p_user_data, + uint16_t i_blocksize) { /* Sort of a stub here. Perhaps log a message? */ return DRIVER_OP_UNSUPPORTED; } diff --git a/lib/driver/_cdio_linux.c b/lib/driver/_cdio_linux.c index 6fd12b4f..2637cf47 100644 --- a/lib/driver/_cdio_linux.c +++ b/lib/driver/_cdio_linux.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_linux.c,v 1.24 2005/02/07 04:16:19 rocky Exp $ + $Id: _cdio_linux.c,v 1.25 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein @@ -27,7 +27,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.24 2005/02/07 04:16:19 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.25 2005/02/17 04:57:21 rocky Exp $"; #include @@ -576,11 +576,11 @@ is_cdrom_linux(const char *drive, char *mnttype) */ static driver_return_code_t _read_audio_sectors_linux (void *p_user_data, void *buf, lsn_t lsn, - unsigned int nblocks) + uint32_t i_blocks) { _img_private_t *p_env = p_user_data; return mmc_read_sectors( p_env->gen.cdio, buf, lsn, CDIO_MMC_READ_TYPE_CDDA, - nblocks); + i_blocks); } /* Packet driver to read mode2 sectors. @@ -588,7 +588,7 @@ _read_audio_sectors_linux (void *p_user_data, void *buf, lsn_t lsn, */ static driver_return_code_t _read_mode2_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba, - unsigned int nblocks, bool b_read_10) + uint32_t i_blocks, bool b_read_10) { scsi_mmc_cdb_t cdb = {{0, }}; @@ -598,7 +598,7 @@ _read_mode2_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba, int retval; CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_10); - CDIO_MMC_SET_READ_LENGTH16(cdb.field, nblocks); + CDIO_MMC_SET_READ_LENGTH16(cdb.field, i_blocks); if ((retval = mmc_set_blocksize (p_env->gen.cdio, M2RAW_SECTOR_SIZE))) return retval; @@ -607,7 +607,7 @@ _read_mode2_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba, mmc_get_cmd_len(cdb.field[0]), &cdb, SCSI_MMC_DATA_READ, - M2RAW_SECTOR_SIZE * nblocks, + M2RAW_SECTOR_SIZE * i_blocks, p_buf))) { mmc_set_blocksize (p_env->gen.cdio, CDIO_CD_FRAMESIZE); @@ -623,35 +623,35 @@ _read_mode2_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba, cdb.field[9] = 0x58; /* 2336 mode2 */ CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD); - CDIO_MMC_SET_READ_LENGTH24(cdb.field, nblocks); + CDIO_MMC_SET_READ_LENGTH24(cdb.field, i_blocks); return run_mmc_cmd_linux (p_env, 0, mmc_get_cmd_len(cdb.field[0]), &cdb, SCSI_MMC_DATA_READ, - M2RAW_SECTOR_SIZE * nblocks, p_buf); + M2RAW_SECTOR_SIZE * i_blocks, p_buf); } } static driver_return_code_t _read_mode2_sectors (_img_private_t *p_env, void *p_buf, lba_t lba, - unsigned int nblocks, bool b_read_10) + uint32_t i_blocks, bool b_read_10) { unsigned int l = 0; int retval = 0; - while (nblocks > 0) + while (i_blocks > 0) { - const unsigned nblocks2 = (nblocks > 25) ? 25 : nblocks; + const unsigned i_blocks2 = (i_blocks > 25) ? 25 : i_blocks; void *p_buf2 = ((char *)p_buf ) + (l * M2RAW_SECTOR_SIZE); retval |= _read_mode2_sectors_mmc (p_env, p_buf2, lba + l, - nblocks2, b_read_10); + i_blocks2, b_read_10); if (retval) break; - nblocks -= nblocks2; - l += nblocks2; + i_blocks -= i_blocks2; + l += i_blocks2; } return retval; @@ -666,7 +666,7 @@ _read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn, bool b_form2) { -#if FIXED +#if 0 char buf[M2RAW_SECTOR_SIZE] = { 0, }; struct cdrom_msf *p_msf = (struct cdrom_msf *) &buf; msf_t _msf; @@ -674,9 +674,9 @@ _read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn, _img_private_t *p_env = p_user_data; cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf); - msf->cdmsf_min0 = cdio_from_bcd8(_msf.m); - msf->cdmsf_sec0 = cdio_from_bcd8(_msf.s); - msf->cdmsf_frame0 = cdio_from_bcd8(_msf.f); + p_msf->cdmsf_min0 = cdio_from_bcd8(_msf.m); + p_msf->cdmsf_sec0 = cdio_from_bcd8(_msf.s); + p_msf->cdmsf_frame0 = cdio_from_bcd8(_msf.f); retry: switch (p_env->access_mode) @@ -697,8 +697,8 @@ _read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn, case _AM_READ_CD: case _AM_READ_10: - if (_read_mode2_sectors (p_env->gen.fd, buf, lsn, 1, - (p_env->access_mode == _AM_READ_10))) + if (_read_mode2_sectors (p_env, buf, lsn, 1, + (p_env->access_mode == _AM_READ_10))) { perror ("ioctl()"); if (p_env->access_mode == _AM_READ_CD) @@ -718,7 +718,7 @@ _read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn, break; } - memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE, + memcpy (p_data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE, b_form2 ? M2RAW_SECTOR_SIZE: CDIO_CD_FRAMESIZE); #else @@ -728,20 +728,20 @@ _read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn, } /*! - Reads nblocks of mode2 sectors from cd device into data starting + Reads i_blocks of mode2 sectors from cd device into data starting from lsn. Returns 0 if no error. */ static driver_return_code_t _read_mode1_sectors_linux (void *p_user_data, void *p_data, lsn_t lsn, - bool b_form2, unsigned int nblocks) + bool b_form2, uint32_t i_blocks) { _img_private_t *p_env = p_user_data; unsigned int i; int retval; unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE; - for (i = 0; i < nblocks; i++) { + for (i = 0; i < i_blocks; i++) { if ( (retval = _read_mode1_sector_linux (p_env, ((char *)p_data) + (blocksize*i), lsn + i, b_form2)) ) @@ -818,20 +818,20 @@ _read_mode2_sector_linux (void *p_user_data, void *p_data, lsn_t lsn, } /*! - Reads nblocks of mode2 sectors from cd device into data starting + Reads i_blocks of mode2 sectors from cd device into data starting from lsn. Returns 0 if no error. */ static driver_return_code_t _read_mode2_sectors_linux (void *p_user_data, void *data, lsn_t lsn, - bool b_form2, unsigned int nblocks) + bool b_form2, uint32_t i_blocks) { _img_private_t *p_env = p_user_data; unsigned int i; - unsigned int i_blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE; + uint16_t i_blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE; /* For each frame, pick out the data part we need */ - for (i = 0; i < nblocks; i++) { + for (i = 0; i < i_blocks; i++) { int retval; if ( (retval = _read_mode2_sector_linux (p_env, ((char *)data) + (i_blocksize*i), @@ -1189,6 +1189,7 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode) .lseek = cdio_generic_lseek, .read = cdio_generic_read, .read_audio_sectors = _read_audio_sectors_linux, + .read_data_sector = read_data_sector_mmc, .read_mode1_sector = _read_mode1_sector_linux, .read_mode1_sectors = _read_mode1_sectors_linux, .read_mode2_sector = _read_mode2_sector_linux, diff --git a/lib/driver/cdio_private.h b/lib/driver/cdio_private.h index 8c0b5a63..0cd5e50c 100644 --- a/lib/driver/cdio_private.h +++ b/lib/driver/cdio_private.h @@ -1,5 +1,5 @@ /* - $Id: cdio_private.h,v 1.14 2005/02/06 11:32:22 rocky Exp $ + $Id: cdio_private.h,v 1.15 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -228,20 +228,41 @@ extern "C" { Returns -1 on error. Similar to libc's read() */ - ssize_t (*read) (void *p_env, void *p_buf, size_t size); + ssize_t (*read) (void *p_env, void *p_buf, size_t i_size); /*! Reads a single mode2 sector from cd device into buf starting from lsn. Returns 0 if no error. */ - int (*read_audio_sectors) (void *p_env, void *p_buf, lsn_t lsn, + int (*read_audio_sectors) (void *p_env, void *p_buf, lsn_t i_lsn, unsigned int i_blocks); + /*! + Read a data sector + + @param p_env environment to read from + + @param p_buf place to read data into. The caller should make sure + this location can store at least CDIO_CD_FRAMESIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending + on the kind of sector getting read. If you don't + know whether you have a Mode 1/2, Form 1/ Form 2/Formless + sector best to reserve space for the maximum, + M2RAW_SECTOR_SIZE. + + @param i_lsn sector to read + @param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf. + */ + driver_return_code_t (*read_data_sector) (void *p_env, void *p_buf, + lsn_t i_lsn, + uint16_t i_blocksize); + /*! Reads a single mode2 sector from cd device into buf starting from lsn. Returns 0 if no error. */ - int (*read_mode2_sector) (void *p_env, void *p_buf, lsn_t lsn, + int (*read_mode2_sector) (void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2); /*! @@ -249,14 +270,14 @@ extern "C" { from lsn. Returns 0 if no error. */ - int (*read_mode2_sectors) (void *p_env, void *p_buf, lsn_t lsn, + int (*read_mode2_sectors) (void *p_env, void *p_buf, lsn_t i_lsn, bool b_mode2_form2, unsigned int i_blocks); /*! Reads a single mode1 sector from cd device into buf starting from lsn. Returns 0 if no error. */ - int (*read_mode1_sector) (void *p_env, void *p_buf, lsn_t lsn, + int (*read_mode1_sector) (void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2); /*! @@ -264,7 +285,7 @@ extern "C" { from lsn. Returns 0 if no error. */ - int (*read_mode1_sectors) (void *p_env, void *p_buf, lsn_t lsn, + int (*read_mode1_sectors) (void *p_env, void *p_buf, lsn_t i_lsn, bool mode1_form2, unsigned int i_blocks); bool (*read_toc) ( void *p_env ) ; @@ -295,7 +316,8 @@ extern "C" { /*! Set the blocksize for subsequent reads. */ - driver_return_code_t (*set_blocksize) ( void *p_env, int i_blocksize ); + driver_return_code_t (*set_blocksize) ( void *p_env, + uint16_t i_blocksize ); /*! Set the drive speed. @@ -362,7 +384,7 @@ extern "C" { Add/allocate a drive to the end of drives. Use cdio_free_device_list() to free this device_list. */ - void cdio_add_device_list(char **device_list[], const char *drive, + void cdio_add_device_list(char **device_list[], const char *psz_drive, unsigned int *i_drives); #ifdef __cplusplus diff --git a/lib/driver/generic.h b/lib/driver/generic.h index 99c1df2f..bcf065b7 100644 --- a/lib/driver/generic.h +++ b/lib/driver/generic.h @@ -1,5 +1,5 @@ /* - $Id: generic.h,v 1.11 2005/01/27 03:10:06 rocky Exp $ + $Id: generic.h,v 1.12 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -83,7 +83,7 @@ extern "C" { */ driver_return_code_t cdio_generic_unimplemented_set_blocksize (void *p_user_data, - int i_blocksize); + uint16_t i_blocksize); /*! Set the drive speed. diff --git a/lib/driver/image.h b/lib/driver/image.h index 826c5535..30d976db 100644 --- a/lib/driver/image.h +++ b/lib/driver/image.h @@ -1,5 +1,5 @@ /* - $Id: image.h,v 1.6 2005/01/22 23:57:10 rocky Exp $ + $Id: image.h,v 1.7 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -69,7 +69,7 @@ typedef struct { trackmode_t mode; uint16_t datasize; /**< How much is in the portion we return back? */ - long int datastart; /**< Offset from begining of fraem + uint16_t datastart; /**< Offset from begining of frame that data starts */ uint16_t endsize; /**< How much stuff at the end to skip over. This stuff may have error correction diff --git a/lib/driver/image/bincue.c b/lib/driver/image/bincue.c index d3485192..c26dbb4c 100644 --- a/lib/driver/image/bincue.c +++ b/lib/driver/image/bincue.c @@ -1,5 +1,5 @@ /* - $Id: bincue.c,v 1.13 2005/02/11 01:34:12 rocky Exp $ + $Id: bincue.c,v 1.14 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein Copyright (C) 2001 Herbert Valerio Riedel @@ -26,7 +26,7 @@ (*.cue). */ -static const char _rcsid[] = "$Id: bincue.c,v 1.13 2005/02/11 01:34:12 rocky Exp $"; +static const char _rcsid[] = "$Id: bincue.c,v 1.14 2005/02/17 04:57:21 rocky Exp $"; #include "image.h" #include "cdio_assert.h" @@ -1159,6 +1159,7 @@ cdio_open_cue (const char *psz_cue_name) _funcs.lseek = _lseek_bincue; _funcs.read = _read_bincue; _funcs.read_audio_sectors = _read_audio_sectors_bincue; + _funcs.read_data_sector = read_data_sector_image; _funcs.read_mode1_sector = _read_mode1_sector_bincue; _funcs.read_mode1_sectors = _read_mode1_sectors_bincue; _funcs.read_mode2_sector = _read_mode2_sector_bincue; diff --git a/lib/driver/image/cdrdao.c b/lib/driver/image/cdrdao.c index 51f736e2..ac3ea27c 100644 --- a/lib/driver/image/cdrdao.c +++ b/lib/driver/image/cdrdao.c @@ -1,5 +1,5 @@ /* - $Id: cdrdao.c,v 1.14 2005/02/11 01:34:12 rocky Exp $ + $Id: cdrdao.c,v 1.15 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein toc reading routine adapted from cuetools @@ -25,7 +25,7 @@ (*.cue). */ -static const char _rcsid[] = "$Id: cdrdao.c,v 1.14 2005/02/11 01:34:12 rocky Exp $"; +static const char _rcsid[] = "$Id: cdrdao.c,v 1.15 2005/02/17 04:57:21 rocky Exp $"; #include "image.h" #include "cdio_assert.h" @@ -73,12 +73,12 @@ static bool parse_tocfile (_img_private_t *cd, const char *p_toc_name); static bool check_track_is_blocksize_multiple(const char *psz_fname, track_t i_track, long i_size, - long i_blocksize) + uint16_t i_blocksize) { if (i_size % i_blocksize) { cdio_info ("image %s track %d size (%ld) not a multiple" " of the blocksize (%ld)", psz_fname, i_track, i_size, - i_blocksize); + (long int) i_blocksize); if (i_size % M2RAW_SECTOR_SIZE == 0) cdio_info ("this may be a 2336-type disc image"); else if (i_size % CDIO_CD_FRAMESIZE_RAW == 0) @@ -236,7 +236,7 @@ get_disc_last_lsn_cdrdao (void *p_user_data) { _img_private_t *p_env = p_user_data; track_t i_leadout = p_env->gen.i_tracks; - long i_blocksize = p_env->tocent[i_leadout-1].blocksize; + uint16_t i_blocksize = p_env->tocent[i_leadout-1].blocksize; long i_size; if (p_env->tocent[i_leadout-1].sec_count) { @@ -787,7 +787,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name) /* No start-msf. */ if (cd) { if (i) { - long i_blocksize = cd->tocent[i-1].blocksize; + uint16_t i_blocksize = cd->tocent[i-1].blocksize; long i_size = cdio_stream_stat(cd->tocent[i-1].data_source); @@ -1286,6 +1286,7 @@ cdio_open_cdrdao (const char *psz_cue_name) _funcs.lseek = _lseek_cdrdao; _funcs.read = _read_cdrdao; _funcs.read_audio_sectors = _read_audio_sectors_cdrdao; + _funcs.read_data_sector = read_data_sector_image; _funcs.read_mode1_sector = _read_mode1_sector_cdrdao; _funcs.read_mode1_sectors = _read_mode1_sectors_cdrdao; _funcs.read_mode2_sector = _read_mode2_sector_cdrdao; diff --git a/lib/driver/image/nrg.c b/lib/driver/image/nrg.c index 3d5d42c5..c6d433a5 100644 --- a/lib/driver/image/nrg.c +++ b/lib/driver/image/nrg.c @@ -1,5 +1,5 @@ /* - $Id: nrg.c,v 1.13 2005/02/11 01:34:12 rocky Exp $ + $Id: nrg.c,v 1.14 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein Copyright (C) 2001, 2003 Herbert Valerio Riedel @@ -46,7 +46,7 @@ #include "_cdio_stdio.h" #include "nrg.h" -static const char _rcsid[] = "$Id: nrg.c,v 1.13 2005/02/11 01:34:12 rocky Exp $"; +static const char _rcsid[] = "$Id: nrg.c,v 1.14 2005/02/17 04:57:21 rocky Exp $"; /* reader */ @@ -1239,6 +1239,7 @@ cdio_open_nrg (const char *psz_source) _funcs.lseek = _lseek_nrg; _funcs.read = _read_nrg; _funcs.read_audio_sectors = _read_audio_sectors_nrg; + _funcs.read_data_sector = read_data_sector_image; _funcs.read_mode1_sector = _read_mode1_sector_nrg; _funcs.read_mode1_sectors = _read_mode1_sectors_nrg; _funcs.read_mode2_sector = _read_mode2_sector_nrg; diff --git a/lib/driver/image_common.c b/lib/driver/image_common.c index 31414650..1a251642 100644 --- a/lib/driver/image_common.c +++ b/lib/driver/image_common.c @@ -1,5 +1,5 @@ /* - $Id: image_common.c,v 1.10 2005/02/11 01:34:12 rocky Exp $ + $Id: image_common.c,v 1.11 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -246,6 +246,52 @@ get_track_preemphasis_image(const void *p_user_data, track_t i_track) & PRE_EMPHASIS ) ? CDIO_TRACK_FLAG_TRUE : CDIO_TRACK_FLAG_FALSE; } +/*! + Read a data sector + + @param p_cdio object to read from + + @param p_buf place to read data into. The caller should make sure + this location can store at least ISO_BLOCKSIZE, M2RAW_SECTOR_SIZE, + or M2F2_SECTOR_SIZE depending on the kind of sector getting read. If + you don't know whether you have a Mode 1/2, Form 1/ Form 2/Formless + sector best to reserve space for the maximum, M2RAW_SECTOR_SIZE. + + @param i_lsn sector to read + + @param i_blocksize size of block. Should be either ISO_BLOCKSIZE + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under + p_buf. + */ +driver_return_code_t +read_data_sector_image ( void *p_user_data, void *p_buf, + lsn_t i_lsn, uint16_t i_blocksize ) +{ + const _img_private_t *p_env = p_user_data; + + if (!p_env || !p_env->gen.cdio) return DRIVER_OP_UNINIT; + + { + CdIo_t *p_cdio = p_env->gen.cdio; + track_t i_track = cdio_get_track(p_cdio, i_lsn); + track_format_t e_track_format = cdio_get_track_format(p_cdio, i_track); + + switch(e_track_format) { + case TRACK_FORMAT_PSX: + case TRACK_FORMAT_AUDIO: + case TRACK_FORMAT_ERROR: + return DRIVER_OP_ERROR; + case TRACK_FORMAT_CDI: + case TRACK_FORMAT_DATA: + return cdio_read_mode1_sector (p_cdio, p_buf, i_lsn, false); + case TRACK_FORMAT_XA: + return cdio_read_mode2_sector (p_cdio, p_buf, i_lsn, false); + } + } + return DRIVER_OP_ERROR; +} + + /*! Set the arg "key" with "value" in the source device. Currently "source" to set the source device in I/O operations diff --git a/lib/driver/image_common.h b/lib/driver/image_common.h index 26b08f61..106790a2 100644 --- a/lib/driver/image_common.h +++ b/lib/driver/image_common.h @@ -1,5 +1,5 @@ /* - $Id: image_common.h,v 1.8 2005/02/06 11:32:22 rocky Exp $ + $Id: image_common.h,v 1.9 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -150,6 +150,27 @@ track_flag_t get_track_copy_permit_image(void *p_user_data, track_t i_track); */ track_flag_t get_track_preemphasis_image(const void *p_user_data, track_t i_track); +/*! + Read a data sector + + @param p_cdio object to read from + + @param p_buf place to read data into. The caller should make sure + this location can store at least ISO_BLOCKSIZE, M2RAW_SECTOR_SIZE, + or M2F2_SECTOR_SIZE depending on the kind of sector getting read. If + you don't know whether you have a Mode 1/2, Form 1/ Form 2/Formless + sector best to reserve space for the maximum, M2RAW_SECTOR_SIZE. + + @param i_lsn sector to read + + @param i_blocksize size of block. Should be either ISO_BLOCKSIZE + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under + p_buf. + */ +driver_return_code_t +read_data_sector_image ( void *p_user_data, void *p_buf, + lsn_t i_lsn, uint16_t i_blocksize ); + /*! Set the arg "key" with "value" in the source device. Currently "source" to set the source device in I/O operations diff --git a/lib/driver/libcdio.sym b/lib/driver/libcdio.sym index 49452310..251e6014 100644 --- a/lib/driver/libcdio.sym +++ b/lib/driver/libcdio.sym @@ -164,6 +164,7 @@ mmc_have_interface mmc_mode_sense mmc_mode_sense_10 mmc_mode_sense_6 +mmc_read_cd mmc_read_sectors mmc_run_cmd mmc_set_blocksize diff --git a/lib/driver/mmc.c b/lib/driver/mmc.c index a976f371..6aedca74 100644 --- a/lib/driver/mmc.c +++ b/lib/driver/mmc.c @@ -1,6 +1,6 @@ /* Common Multimedia Command (MMC) routines. - $Id: mmc.c,v 1.12 2005/02/14 01:07:29 rocky Exp $ + $Id: mmc.c,v 1.13 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -109,9 +109,20 @@ get_mcn_mmc (const void *p_user_data) return mmc_get_mcn( p_env->cdio ); } +/*! Read sectors using SCSI-MMC GPCMD_READ_CD. + Can read only up to 25 blocks. +*/ +driver_return_code_t +read_data_sector_mmc ( void *p_user_data, void *p_buf, + lba_t i_lba, uint16_t i_blocksize ) +{ + const generic_img_private_t *p_env = p_user_data; + return mmc_read_data_sector( p_env->cdio, p_buf, i_lba, i_blocksize ); +} + /* Set read blocksize (via MMC) */ driver_return_code_t -set_blocksize_mmc (void *p_user_data, int i_blocksize) +set_blocksize_mmc (void *p_user_data, uint16_t i_blocksize) { generic_img_private_t *p_env = p_user_data; if (!p_env) return DRIVER_OP_UNINIT; @@ -400,7 +411,7 @@ mmc_init_cdtext_private ( void *p_user_data, driver_return_code_t mmc_set_blocksize_private ( void *p_env, const mmc_run_cmd_fn_t run_mmc_cmd, - unsigned int i_bsize) + uint16_t i_blocksize) { scsi_mmc_cdb_t cdb = {{0, }}; @@ -425,9 +436,9 @@ mmc_set_blocksize_private ( void *p_env, memset (&mh, 0, sizeof (mh)); mh.block_desc_length = 0x08; - mh.block_length_hi = (i_bsize >> 16) & 0xff; - mh.block_length_med = (i_bsize >> 8) & 0xff; - mh.block_length_lo = (i_bsize >> 0) & 0xff; + mh.block_length_hi = (i_blocksize >> 16) & 0xff; + mh.block_length_med = (i_blocksize >> 8) & 0xff; + mh.block_length_lo = (i_blocksize >> 0) & 0xff; CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SELECT_6); @@ -990,12 +1001,81 @@ mmc_have_interface( CdIo_t *p_cdio, mmc_feature_interface_t e_interface ) return dunno; } +/*! issue a MMC READ_CD command. +*/ +driver_return_code_t +mmc_read_cd ( const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, + int read_sector_type, bool b_digital_audio_play, + bool b_sync, uint8_t header_codes, bool b_user_data, + bool b_edc_ecc, uint8_t c2_error_information, + uint8_t subchannel_selection, uint16_t i_blocksize, + uint32_t i_blocks ) +{ + scsi_mmc_cdb_t cdb = {{0, }}; + + mmc_run_cmd_fn_t run_mmc_cmd; + uint8_t i_read_type = 0; + uint8_t cdb9 = 0; + + + if (!p_cdio) return DRIVER_OP_UNINIT; + if (!p_cdio->op.run_mmc_cmd ) return DRIVER_OP_UNSUPPORTED; + + run_mmc_cmd = p_cdio->op.run_mmc_cmd; + + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD); + + i_read_type = read_sector_type << 2; + if (b_digital_audio_play) i_read_type |= 0x2; + + CDIO_MMC_SET_READ_TYPE (cdb.field, i_read_type); + CDIO_MMC_SET_READ_LBA (cdb.field, i_lsn); + CDIO_MMC_SET_READ_LENGTH24(cdb.field, i_blocks); + + + if (b_sync) cdb9 |= 128; + if (b_user_data) cdb9 |= 16; + if (b_edc_ecc) cdb9 |= 8; + cdb9 |= (header_codes & 3) << 5; + cdb9 |= (c2_error_information & 3) << 1; + cdb.field[9] = cdb9; + cdb.field[10] = (subchannel_selection & 7); + + return run_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS, + mmc_get_cmd_len(cdb.field[0]), &cdb, + SCSI_MMC_DATA_READ, + i_blocksize * i_blocks, + p_buf); +} + +/*! Read sectors using SCSI-MMC GPCMD_READ_CD. +*/ +driver_return_code_t +mmc_read_data_sector ( CdIo_t *p_cdio, void *p_buf, + lsn_t i_lsn, uint16_t i_blocksize ) +{ + return mmc_read_cd(p_cdio, + p_buf, /* place to store data */ + i_lsn, /* lsn */ + 0, /* read_sector_type */ + false, /* digital audio play */ + false, /* return sync header */ + 0, /* header codes */ + true, /* return user data */ + false, /* return EDC ECC */ + false, /* return C2 Error information */ + 0, /* suchannel selection bits */ + ISO_BLOCKSIZE, /* blocksize*/ + 1 /* Number of blocks. */); + +} + /*! Read sectors using SCSI-MMC GPCMD_READ_CD. Can read only up to 25 blocks. */ driver_return_code_t -mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, lba_t lba, - int sector_type, unsigned int i_blocks ) +mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, + int sector_type, uint32_t i_blocks ) { scsi_mmc_cdb_t cdb = {{0, }}; @@ -1008,7 +1088,7 @@ mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, lba_t lba, CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD); CDIO_MMC_SET_READ_TYPE (cdb.field, sector_type); - CDIO_MMC_SET_READ_LBA (cdb.field, lba); + CDIO_MMC_SET_READ_LBA (cdb.field, i_lsn); CDIO_MMC_SET_READ_LENGTH24(cdb.field, i_blocks); CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb.field, CDIO_MMC_MCSB_ALL_HEADERS); @@ -1021,7 +1101,7 @@ mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, lba_t lba, } driver_return_code_t -mmc_set_blocksize ( const CdIo_t *p_cdio, unsigned int i_blocksize) +mmc_set_blocksize ( const CdIo_t *p_cdio, uint16_t i_blocksize) { if ( ! p_cdio ) return DRIVER_OP_UNINIT; return diff --git a/lib/driver/mmc_private.h b/lib/driver/mmc_private.h index 14c4ac47..29be6517 100644 --- a/lib/driver/mmc_private.h +++ b/lib/driver/mmc_private.h @@ -1,6 +1,6 @@ /* private MMC helper routines. - $Id: mmc_private.h,v 1.4 2005/02/09 02:50:47 rocky Exp $ + $Id: mmc_private.h,v 1.5 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -59,8 +59,32 @@ int get_media_changed_mmc (const void *p_user_data); char *get_mcn_mmc (const void *p_user_data); +/*! Read just the user data part of some sort of data sector (via + mmc_read_cd). + + @param p_user_data object to read from + + @param p_buf place to read data into. The caller should make sure + this location can store at least CDIO_CD_FRAMESIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE depending on + the kind of sector getting read. If you don't know + whether you have a Mode 1/2, Form 1/ Form 2/Formless + sector best to reserve space for the maximum, + M2RAW_SECTOR_SIZE. + + @param i_lsn sector to read + @param i_blocksize size of block. Should be either CDIO_CD_FRAMESIZE, + M2RAW_SECTOR_SIZE, or M2F2_SECTOR_SIZE. See comment above under p_buf. + +*/ +driver_return_code_t read_data_sector_mmc ( void *p_user_data, + void *p_buf, lsn_t i_lsn, + uint16_t i_blocksize ); +char *get_mcn_mmc (const void *p_user_data); + /* Set read blocksize (via MMC) */ -driver_return_code_t set_blocksize_mmc (void *p_user_data, int i_blocksize); +driver_return_code_t set_blocksize_mmc (void *p_user_data, + uint16_t i_blocksize); /* Set CD-ROM drive speed (via MMC) */ driver_return_code_t set_speed_mmc (void *p_user_data, int i_speed); @@ -80,7 +104,7 @@ typedef driver_return_code_t (*mmc_run_cmd_fn_t) int mmc_set_blocksize_mmc_private ( const void *p_env, const mmc_run_cmd_fn_t run_mmc_cmd, - unsigned int bsize ); + uint16_t i_blocksize ); /*! Get the DVD type associated with cd object. @@ -113,4 +137,4 @@ void mmc_get_drive_cap_buf(const uint8_t *p, driver_return_code_t mmc_set_blocksize_private ( void *p_env, const mmc_run_cmd_fn_t run_mmc_cmd, - unsigned int i_bsize); + uint16_t i_blocksize); diff --git a/lib/driver/read.c b/lib/driver/read.c index 12260e26..8641bd2c 100644 --- a/lib/driver/read.c +++ b/lib/driver/read.c @@ -1,5 +1,5 @@ /* - $Id: read.c,v 1.4 2005/02/05 04:25:14 rocky Exp $ + $Id: read.c,v 1.5 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2005 Rocky Bernstein @@ -70,8 +70,6 @@ } \ } - - /*! lseek - reposition read/write file offset Returns (off_t) -1 on error. @@ -93,12 +91,12 @@ cdio_lseek (const CdIo_t *p_cdio, off_t offset, int whence) Similar to (if not the same as) libc's read() */ ssize_t -cdio_read (const CdIo_t *p_cdio, void *p_buf, size_t size) +cdio_read (const CdIo_t *p_cdio, void *p_buf, size_t i_size) { if (!p_cdio) return DRIVER_OP_UNINIT; if (p_cdio->op.read) - return p_cdio->op.read (p_cdio->env, p_buf, size); + return p_cdio->op.read (p_cdio->env, p_buf, i_size); return DRIVER_OP_UNSUPPORTED; } @@ -110,7 +108,7 @@ driver_return_code_t cdio_read_audio_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn) { check_lsn(i_lsn); - if (p_cdio->op.read_audio_sectors != NULL) + if (p_cdio->op.read_audio_sectors) return p_cdio->op.read_audio_sectors (p_cdio->env, p_buf, i_lsn, 1); return DRIVER_OP_UNSUPPORTED; } @@ -121,13 +119,28 @@ cdio_read_audio_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn) */ driver_return_code_t cdio_read_audio_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, - unsigned int i_blocks) + uint32_t i_blocks) { check_lsn_blocks(i_lsn, i_blocks); - if (p_cdio->op.read_audio_sectors != NULL) + if (p_cdio->op.read_audio_sectors) return p_cdio->op.read_audio_sectors (p_cdio->env, p_buf, i_lsn, i_blocks); return DRIVER_OP_UNSUPPORTED; } +/*! + Reads an audio sector from cd device into data starting + from lsn. Returns DRIVER_OP_SUCCESS if no error. +*/ +driver_return_code_t +cdio_read_data_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, + uint16_t i_blocksize) +{ + check_lsn(i_lsn); + if (p_cdio->op.read_data_sector) + return p_cdio->op.read_data_sector (p_cdio->env, p_buf, i_lsn, + i_blocksize); + return DRIVER_OP_UNSUPPORTED; +} + #ifndef SEEK_SET #define SEEK_SET 0 @@ -167,11 +180,11 @@ cdio_read_mode1_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, @param lsn sector to read @param b_form2 true for reading mode 1 form 2 sectors or false for mode 1 form 1 sectors. - @param i_sectors number of sectors to read + @param i_blocks number of sectors to read */ driver_return_code_t cdio_read_mode1_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, - bool b_form2, unsigned int i_blocks) + bool b_form2, uint32_t i_blocks) { check_lsn_blocks(i_lsn, i_blocks); if (p_cdio->op.read_mode1_sectors) @@ -211,11 +224,11 @@ cdio_read_mode2_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, @param lsn sector to read @param b_form2 true for reading mode2 form 2 sectors or false for mode 2 form 1 sectors. - @param i_sectors number of sectors to read + @param i_blocks number of sectors to read */ driver_return_code_t cdio_read_mode2_sectors (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, - bool b_form2, unsigned int i_blocks) + bool b_form2, uint32_t i_blocks) { check_lsn_blocks(i_lsn, i_blocks); if (p_cdio->op.read_mode2_sectors) diff --git a/lib/iso9660/iso9660_fs.c b/lib/iso9660/iso9660_fs.c index 78d5c325..c659251a 100644 --- a/lib/iso9660/iso9660_fs.c +++ b/lib/iso9660/iso9660_fs.c @@ -1,5 +1,5 @@ /* - $Id: iso9660_fs.c,v 1.14 2005/02/14 07:49:46 rocky Exp $ + $Id: iso9660_fs.c,v 1.15 2005/02/17 04:57:21 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -52,7 +52,7 @@ #include -static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.14 2005/02/14 07:49:46 rocky Exp $"; +static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.15 2005/02/17 04:57:21 rocky Exp $"; /* Implementation of iso9660_t type */ struct _iso9660_s { @@ -672,31 +672,13 @@ bool iso9660_fs_read_pvd(const CdIo_t *p_cdio, /*out*/ iso9660_pvd_t *p_pvd) { /* A bit of a hack, we'll assume track 1 contains ISO_PVD_SECTOR.*/ - bool b_mode2; char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, }; - int i_rc; + driver_return_code_t driver_return = + cdio_read_data_sector (p_cdio, buf, ISO_PVD_SECTOR, ISO_BLOCKSIZE); - switch(cdio_get_track_format(p_cdio, 1)) { - case TRACK_FORMAT_CDI: - case TRACK_FORMAT_XA: - b_mode2 = true; - break; - case TRACK_FORMAT_DATA: - b_mode2 = false; - break; - case TRACK_FORMAT_AUDIO: - case TRACK_FORMAT_PSX: - case TRACK_FORMAT_ERROR: - default: - return false; - } - - i_rc = b_mode2 - ? cdio_read_mode2_sector (p_cdio, buf, ISO_PVD_SECTOR, false) - : cdio_read_mode1_sector (p_cdio, buf, ISO_PVD_SECTOR, false); - - if (i_rc) { - cdio_warn ("error reading PVD sector (%d)", ISO_PVD_SECTOR); + if (DRIVER_OP_SUCCESS != driver_return) { + cdio_warn ("error reading PVD sector (%d) error %d", ISO_PVD_SECTOR, + driver_return); return false; } @@ -727,35 +709,18 @@ iso9660_fs_read_superblock (CdIo_t *p_cdio, iso9660_pvd_t *p_pvd = &(p_env->pvd); iso9660_svd_t *p_svd = &(p_env->svd); char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, }; - bool b_mode2; - int i_rc; + driver_return_code_t driver_return = + cdio_read_data_sector (p_cdio, buf, ISO_PVD_SECTOR, ISO_BLOCKSIZE); - /* A bit of a hack, we'll assume track 1 contains ISO_PVD_SECTOR.*/ - switch(cdio_get_track_format(p_cdio, 1)) { - case TRACK_FORMAT_CDI: - case TRACK_FORMAT_XA: - b_mode2 = true; - break; - case TRACK_FORMAT_DATA: - b_mode2 = false; - break; - case TRACK_FORMAT_AUDIO: - case TRACK_FORMAT_PSX: - case TRACK_FORMAT_ERROR: - default: - return false; - } - if ( !iso9660_fs_read_pvd(p_cdio, p_pvd) ) return false; p_env->i_joliet_level = 0; - i_rc = (b_mode2) - ? cdio_read_mode2_sector (p_cdio, buf, ISO_PVD_SECTOR+1, false) - : cdio_read_mode1_sector (p_cdio, buf, ISO_PVD_SECTOR+1, false); + driver_return = + cdio_read_data_sector (p_cdio, buf, ISO_PVD_SECTOR+1, ISO_BLOCKSIZE); - if (0 == i_rc) { + if (DRIVER_OP_SUCCESS == driver_return) { /* The size of a PVD or SVD is smaller than a sector. So we allocated a bigger block above (buf) and now we'll copy just the part we need to save.