diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index d3398a9..e2343f2 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2012.10.25.173408" +#define Cdrskin_timestamP "2012.11.18.184006" diff --git a/libburn/libburn.h b/libburn/libburn.h index 8c8394e..ec4a4b9 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -3996,4 +3996,19 @@ BURN_END_DECLS #define Libburn_dummy_probe_write_modeS 1 +/* Early experimental: + Do not define Libburn_develop_quality_scaN unless you want to work + towards a usable implementation. + If it gets enabled, then the call must be published in libburn/libburn.ver +*/ +#ifdef Libburn_develop_quality_scaN + +/* B21108 ts */ +/* Experiments mit quality scan command F3 on Optiarc drive */ +int burn_nec_optiarc_rep_err_rate(struct burn_drive *d, + int start_lba, int rate_period, int flag); + +#endif /* Libburn_develop_quality_scaN */ + + #endif /*LIBBURN_H*/ diff --git a/libburn/mmc.c b/libburn/mmc.c index 34b9b3c..ea350a2 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -4243,6 +4243,77 @@ int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf) } +#ifdef Libburn_develop_quality_scaN + +/* B21108 ts : Vendor specific command REPORT ERROR RATE, see + http://liggydee.cdfreaks.com/ddl/errorcheck.pdf +*/ +int mmc_nec_optiarc_f3(struct burn_drive *d, int sub_op, + int start_lba, int rate_period, + int *ret_lba, int *error_rate1, int *error_rate2) +{ + struct buffer *buf = NULL; + struct command *c; + char *msg = NULL; + int key, asc, ascq, ret; + static unsigned char MMC_NEC_OPTIARC_F3[] = + { 0xF3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + BURN_ALLOC_MEM(buf, struct buffer, 1); + BURN_ALLOC_MEM(c, struct command, 1); + mmc_start_if_needed(d, 0); + if (mmc_function_spy(d, "mmc_nec_optiarc_f3") <= 0) + return -1; + + scsi_init_command(c, MMC_NEC_OPTIARC_F3, sizeof(MMC_NEC_OPTIARC_F3)); + if (sub_op == 3) { + c->dxfer_len = 8; + c->dir = FROM_DRIVE; + } else { + c->dxfer_len = 0; + c->dir = NO_TRANSFER; + } + c->retry = 0; + c->opcode[1] = sub_op; + mmc_int_to_four_char(c->opcode + 2, start_lba); + c->opcode[8] = rate_period; + c->page = buf; + c->page->bytes = 0; + c->page->sectors = 0; + d->issue_command(d, c); + if (c->error) { + msg = calloc(1, 256); + if (msg != NULL) { + sprintf(msg, + "SCSI error on nec_optiarc_f3(%d, %d, %d): ", + sub_op, start_lba, rate_period); + scsi_error_msg(d, c->sense, 14, msg + strlen(msg), + &key, &asc, &ascq); + libdax_msgs_submit(libdax_messenger, + d->global_index, 0x00020144, + LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, + msg, 0, 0); + free(msg); + } + return BE_CANCELLED; + } + + if (sub_op == 3) { + *ret_lba = mmc_four_char_to_int(c->page->data); + *error_rate1 = c->page->data[4] * 256 + c->page->data[5]; + *error_rate2 = c->page->data[6] * 256 + c->page->data[7]; + } + + ret = 1; +ex:; + BURN_FREE_MEM(c); + BURN_FREE_MEM(buf); + return ret; +} + +#endif /* Libburn_develop_quality_scaN */ + + /* ts A81210 : Determine the upper limit of readable data size */ int mmc_read_capacity(struct burn_drive *d) { diff --git a/libburn/mmc.h b/libburn/mmc.h index b0f2240..6b1274f 100644 --- a/libburn/mmc.h +++ b/libburn/mmc.h @@ -128,4 +128,11 @@ int mmc_get_leadin_text(struct burn_drive *d, unsigned char **text_packs, int *num_packs, int flag); +#ifdef Libburn_develop_quality_scaN +/* B21108 ts */ +int mmc_nec_optiarc_f3(struct burn_drive *d, int sub_op, + int start_lba, int rate_period, + int *eba, int *error_rate1, int *error_rate2); +#endif + #endif /*__MMC*/ diff --git a/libburn/read.c b/libburn/read.c index 29bfea4..b5cbc52 100644 --- a/libburn/read.c +++ b/libburn/read.c @@ -36,6 +36,7 @@ #include "init.h" #include "toc.h" #include "util.h" +#include "mmc.h" #include "sg.h" #include "read.h" #include "options.h" @@ -535,3 +536,42 @@ ex:; d->busy = BURN_DRIVE_IDLE; return ret; } + + +#ifdef Libburn_develop_quality_scaN + +/* B21108 ts */ +int burn_nec_optiarc_rep_err_rate(struct burn_drive *d, + int start_lba, int rate_period, int flag) +{ + int ret, lba = 0, error_rate1 = 0, error_rate2 = 0, enabled = 0, dret; + + /* Sub Operation Code 1 : Enable Error Rate reporting function */ + ret = mmc_nec_optiarc_f3(d, 1, start_lba, rate_period, + &lba, &error_rate1, &error_rate2); + if (ret <= 0) + goto ex; + enabled = 1; + + /* >>> Sub Operation Code 2 : Seek to starting address + start_lba , rate_period + */; + + /* >>> Loop with Sub Operation Code 3 : Send Error Rate information + reply: 4-byte LBA , 2-byte C1/PIE , 2-byte C2/PIF + */; + + ret = 1; +ex:; + if (enabled) { + /* Code F : Disable Error Rate reporting function */ + dret = mmc_nec_optiarc_f3(d, 0xf, 0, 0, + &lba, &error_rate1, &error_rate2); + if (dret < ret) + ret = dret; + } + return ret; +} + +#endif /* Libburn_develop_quality_scaN */ + diff --git a/libburn/spc.c b/libburn/spc.c index c0645b5..7d63df3 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -1466,6 +1466,14 @@ static char *scsi_command_name(unsigned int c, int flag) return "SET CD SPEED"; case 0xbe: return "READ CD"; + +#ifdef Libburn_develop_quality_scaN + + case 0xf3: + return "NEC/OPTIARC REPORT ERROR RATE"; + +#endif /* Libburn_develop_quality_scaN */ + } return "(NOT IN LIBBURN COMMAND LIST)"; }