/*
* This file is part of the QPxTool project.
* Copyright (C) 2005-2006 Gennady "ShultZ" Kozlov <qpxtool@mail.ru>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* See the file "COPYING" for the exact licensing terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//#include <sys/time.h>
#include <qpx_transport.h>
#include <qpx_mmc.h>
#include <common_functions.h>
#include "media_check_benq.h"
//#define _BENQ_DEBUG 1
#define _BENQ_DEBUG2 1
// ************* Scan init commands *********
int benq_init_scan_cd(drive_info* drive) {
int i;
drive->cmd_clear();
drive->cmd[0] = 0xFD;
drive->cmd[1] = 0xF1;
drive->cmd[2] = 0x42;
drive->cmd[3] = 0x45;
drive->cmd[4] = 0x4E;
drive->cmd[5] = 0x51;
#ifdef _BENQ_DEBUG
printf("benq_init_cx_scan_0\n");
#endif
if ((drive->err=drive->cmd.transport(NONE,NULL,0))){
sperror ("benq_init_cx_scan_0",drive->err);
return drive->err;
}
// ************
drive->rd_buf[0] = 0xD2;
drive->rd_buf[1] = 0x0A;
drive->rd_buf[2] = 0x00;
drive->rd_buf[3] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x04;
#ifdef _BENQ_DEBUG
printf("benq_init_cx_scan_1\n");
#endif
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,4))){
sperror ("benq_init_cx_scan_1",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
#ifdef _BENQ_DEBUG
printf("benq_init_cx_scan_2\n");
#endif
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_init_cx_scan_2",drive->err);
return drive->err;
}
// ************
drive->rd_buf[0] = 0xC8;
drive->rd_buf[1] = 0x99;
drive->rd_buf[2] = 0x79;
for (i=3; i<10; i++)
drive->rd_buf[i] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x0A;
#ifdef _BENQ_DEBUG
printf("benq_init_cx_scan_3\n");
#endif
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,10))){
sperror ("benq_init_cx_scan_3",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
#ifdef _BENQ_DEBUG
printf("benq_init_cx_scan_4\n");
#endif
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_init_cx_scan_4",drive->err);
return drive->err;
}
// ************
drive->rd_buf[0] = 0xD4;
drive->rd_buf[1] = 0x91;
drive->rd_buf[2] = 0x00;
drive->rd_buf[3] = 0x00;
drive->rd_buf[4] = 0x00;
drive->rd_buf[5] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x06;
#ifdef _BENQ_DEBUG
printf("benq_init_cx_scan_5\n");
#endif
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,6))){
sperror ("benq_init_cx_scan_5",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
#ifdef _BENQ_DEBUG
printf("benq_init_cx_scan_6\n");
#endif
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_init_cx_scan_6",drive->err);
return drive->err;
}
// cnt=0;
return 0;
}
int benq_init_scan_dvd(drive_info* drive) {
int i;
drive->cmd_clear();
drive->cmd[0] = 0xFD;
drive->cmd[1] = 0xF1;
drive->cmd[2] = 0x42;
drive->cmd[3] = 0x45;
drive->cmd[4] = 0x4E;
drive->cmd[5] = 0x51;
#ifdef _BENQ_DEBUG
printf("benq_init_pi_scan_0\n");
#endif
if ((drive->err=drive->cmd.transport(NONE,NULL,0))){
sperror ("benq_init_pi_scan_0",drive->err);
return drive->err;
}
// ************
drive->rd_buf[0] = 0xD2;
drive->rd_buf[1] = 0x0A;
drive->rd_buf[2] = 0x05;
drive->rd_buf[3] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x04;
#ifdef _BENQ_DEBUG
printf("benq_init_pi_scan_1\n");
#endif
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,4))){
sperror ("benq_init_pi_scan_1",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
#ifdef _BENQ_DEBUG
printf("benq_init_pi_scan_2\n");
#endif
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_init_pi_scan_2",drive->err);
return drive->err;
}
// ************
drive->rd_buf[0] = 0xC8;
drive->rd_buf[1] = 0x99;
drive->rd_buf[2] = 0x79;
for (i=3; i<10; i++)
drive->rd_buf[i] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x0A;
#ifdef _BENQ_DEBUG
printf("benq_init_pi_scan_3\n");
#endif
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,10))){
sperror ("benq_init_pi_scan_3",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
#ifdef _BENQ_DEBUG
printf("benq_init_pi_scan_4\n");
#endif
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_init_pi_scan_4",drive->err);
return drive->err;
}
// ************
drive->rd_buf[0] = 0xD4;
drive->rd_buf[1] = 0x91;
drive->rd_buf[2] = 0x03;
drive->rd_buf[3] = 0x00;
drive->rd_buf[4] = 0x00;
drive->rd_buf[5] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x06;
#ifdef _BENQ_DEBUG
printf("benq_init_pi_scan_5\n");
#endif
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,6))){
sperror ("benq_init_pi_scan_5",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
#ifdef _BENQ_DEBUG
printf("benq_init_pi_scan_6\n");
#endif
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_init_pi_scan_6",drive->err);
return drive->err;
}
// cnt=0;
return 0;
}
// ************ Scan commands ***********
int benq_scan_block(drive_info* drive){
drive->rd_buf[0] = 0xC1;
drive->rd_buf[1] = 0x9A;
drive->rd_buf[2] = 0x00;
drive->rd_buf[3] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x04;
#ifdef _BENQ_DEBUG
printf("benq_scan_block\n");
#endif
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,4))){
sperror ("benq_scan_block",drive->err);
return drive->err;
}
return 0;
}
int benq_read_err(drive_info* drive){
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[7] = 0x01;
drive->cmd[8] = 0x02;
#ifdef _BENQ_DEBUG
printf("benq_read_err\n");
#endif
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,258))){
sperror ("benq_read_err",drive->err);
return drive->err;
}
return 0;
}
// ***********
// CD tests
// ***********
int benq_cx_do_one_interval(drive_info* drive, int* lba, int* BLER,
int* E11, int* E21, int* E31, int* E12, int* E22, int* E32)
{
int i,m,s,f;
#ifdef _BENQ_DEBUG
printf("benq_cx_do_one_interval. LBA=%d\n",*lba);
#endif
int found=0;
int cnt=128;
while ((!found) && (cnt)) {
benq_scan_block(drive);
benq_read_err(drive);
if ((!drive->rd_buf[0]) && (drive->rd_buf[1] == 0x63) && (drive->rd_buf[2] == 0x64) && (drive->rd_buf[3] == 0x6E)) {
printf("\nData block found...\n");
found = 1;
} else {
printf(".");
// return 0;
}
usleep(1000);
cnt--;
}
if (!cnt) return 1;
#ifdef _BENQ_DEBUG2
for (i=0; i<32; i++) {
if (!(i%8)) printf("| ");
printf("%02X ", drive->rd_buf[i] & 0xFF);
}
printf("|\n");
#endif
*BLER = swap2(drive->rd_buf+12); // C1
*E11 = 0;
*E21 = 0;
*E31 = 0;
*E12 = 0;
*E22 = swap2(drive->rd_buf+18); // C2
*E32 = 0; // CU
// *lba+=75;
// cnt++;
m = ((drive->rd_buf[7] >> 4) & 0x0F)*10 + (drive->rd_buf[7] & 0x0F);
s = ((drive->rd_buf[8] >> 4) & 0x0F)*10 + (drive->rd_buf[8] & 0x0F);
f = ((drive->rd_buf[9] >> 4) & 0x0F)*10 + (drive->rd_buf[9] & 0x0F);
*lba = (m*60 + s)*75 + f;
printf("MSF: %02d:%02d.00 ; LBA: %d; C1:%4d; C2:%4d\n",m,s,*lba,*BLER,*E22);
return 0;
}
int benq_jitter_CD_do_one_interval(drive_info* drive, int* lba, int* jitter, short int* beta, int blklen)
{
benq_scan_block(drive);
benq_read_err(drive);
*jitter = 0;
*beta = 0;
// *lba=((int)drive->rd_buf[0] * 4500 + (int)drive->rd_buf[3] * 75 + (int)drive->rd_buf[2]);
*lba = (((drive->rd_buf[7] & 0xF0)*10 + (drive->rd_buf[7] & 0x0F))*60 + (drive->rd_buf[7] & 0xF0))*10 + (drive->rd_buf[7] & 0x0F);
return 0;
}
// ***********
// DVD tests
// ***********
int benq_pie_pif_do_one_interval(drive_info* drive, int* lba, int* pie, int* pif, int* pof)
{
int i;
// int pif;
#ifdef _BENQ_DEBUG
printf("benq_pie_pif_do_one_interval. LBA=%d\n",*lba);
#endif
int found=0;
int cnt=256;
while ((!found) && (cnt)) {
benq_scan_block(drive);
benq_read_err(drive);
if ((!drive->rd_buf[0]) && (drive->rd_buf[1] == 0x64) && (drive->rd_buf[2] == 0x76) && (drive->rd_buf[3] == 0x64)) {
printf("\nData block found...\n");
found = 1;
} else {
printf(".");
// return 0;
}
usleep(1000);
cnt--;
}
if (!cnt) return 1;
#ifdef _BENQ_DEBUG2
for (i=0; i<32; i++) {
if (!(i%8)) printf("| ");
printf("%02X ", drive->rd_buf[i] & 0xFF);
}
printf("|\n");
#endif
*pie = max (swap2(drive->rd_buf+10),swap2(drive->rd_buf+12));
*pif = swap2(drive->rd_buf+16) + swap2(drive->rd_buf+18);
*pof = 0;
*lba = (((drive->rd_buf[7]-3) << 16 )& 0xFF0000) + ((drive->rd_buf[8] << 8)&0xFF00 ) + (drive->rd_buf[9] & 0xFF);
printf("LBA: %d; PIE:%4d; PIF:%4d\n",*lba,*pie, *pif);
return 0;
}
int benq_jitter_DVD_do_16_ecc(drive_info* drive, int* lba, int* jitter, short int* beta)
{
benq_scan_block(drive);
benq_read_err(drive);
*jitter = 0;
*beta = 0;
// *lba=((int)drive->rd_buf[0] * 4500 + (int)drive->rd_buf[3] * 75 + (int)drive->rd_buf[2]);
*lba+= 0x400;
return 0;
}
// ************* END SCAN COMMAND *********
int benq_end_scan_cd(drive_info* drive) {
int i;
drive->rd_buf[0] = 0xD4;
drive->rd_buf[1] = 0x91;
for (i=2; i<10; i++)
drive->rd_buf[i] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x0A;
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,10))){
sperror ("benq_end_scan_0",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_end_scan_1",drive->err);
return drive->err;
}
// ************
drive->rd_buf[0] = 0xD4;
drive->rd_buf[1] = 0x91;
drive->rd_buf[2] = 0x00;
drive->rd_buf[3] = 0x02;
drive->rd_buf[4] = 0x00;
drive->rd_buf[5] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x06;
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,6))){
sperror ("benq_end_scan_2",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_end_scan_3",drive->err);
return drive->err;
}
// ************
drive->cmd_clear();
drive->cmd[0] = 0xFD;
drive->cmd[1] = 0xF2;
drive->cmd[2] = 0x42;
drive->cmd[3] = 0x45;
drive->cmd[4] = 0x4E;
drive->cmd[5] = 0x51;
if ((drive->err=drive->cmd.transport(NONE,NULL,0))){
sperror ("benq_end_scan_4",drive->err);
return drive->err;
}
return 0;
}
int benq_end_scan_dvd(drive_info* drive) {
int i;
drive->rd_buf[0] = 0xD4;
drive->rd_buf[1] = 0x91;
for (i=2; i<10; i++)
drive->rd_buf[i] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x0A;
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,10))){
sperror ("benq_end_scan_0",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_end_scan_1",drive->err);
return drive->err;
}
// ************
drive->rd_buf[0] = 0xD4;
drive->rd_buf[1] = 0x91;
drive->rd_buf[2] = 0x03;
drive->rd_buf[3] = 0x00;
drive->rd_buf[4] = 0x00;
drive->rd_buf[5] = 0x00;
drive->cmd_clear();
drive->cmd[0] = 0xF9;
drive->cmd[8] = 0x06;
if ((drive->err=drive->cmd.transport(WRITE,drive->rd_buf,6))){
sperror ("benq_end_scan_2",drive->err);
return drive->err;
}
drive->cmd_clear();
drive->cmd[0] = 0xF8;
drive->cmd[8] = 0x02;
if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,2))){
sperror ("benq_end_scan_3",drive->err);
return drive->err;
}
// ************
drive->cmd_clear();
drive->cmd[0] = 0xFD;
drive->cmd[1] = 0xF2;
drive->cmd[2] = 0x42;
drive->cmd[3] = 0x45;
drive->cmd[4] = 0x4E;
drive->cmd[5] = 0x51;
if ((drive->err=drive->cmd.transport(NONE,NULL,0))){
sperror ("benq_end_scan_4",drive->err);
return drive->err;
}
return 0;
}
scan_commands commands_list_benq = {
benq_init_scan_cd, benq_cx_do_one_interval, benq_end_scan_cd,
NULL, benq_jitter_CD_do_one_interval, benq_end_scan_cd,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
benq_init_scan_dvd, benq_pie_pif_do_one_interval, benq_end_scan_dvd,
NULL, benq_jitter_DVD_do_16_ecc, benq_end_scan_dvd,
};
scan_commands commands_benq() { return commands_list_benq; }
syntax highlighted by Code2HTML, v. 0.9.1