/* * This file is part of the QPxTool project. * Copyright (C) 2005-2006 Gennady "ShultZ" Kozlov * * * Some Plextor commands got from PxScan and CDVDlib (C) Alexander Noe` * * * 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 #include #include #include //#include #include #include //#include "test_threads.h" #include "plextor_qcheck.h" //#include "qpx_const.h" #define DEBUG 1 //#define _debug_cx //#define _debug_pi //#define _debug_jb //*********************************// // // commands to start tests // //*********************************// const char PLEX_QCHECK_START = 0x15; const char PLEX_QCHECK_READOUT = 0x16; const char PLEX_QCHECK_END = 0x17; int plextor_start_cx(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_START; //0x15; drive->cmd[2] = 0x00; drive->cmd[3] = 0x01; if ((drive->err=drive->cmd.transport(NONE, NULL, 0) )) {sperror ("PLEXTOR_START_CX",drive->err); return drive->err;} #ifdef _debug_cx printf("00 18 01 01 00 4B | LBA | BLER E31 E21 E11 ??? E32 E22 E12 | C1| C2| CU\n"); #endif return 0; } int plextor_start_pie(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_START; //0x15; drive->cmd[2] = 0x00; drive->cmd[3] = 0x00; drive->cmd[8] = 0x08; // scan interval (ECC blocks) drive->cmd[9] = 0x10; if ((drive->err=drive->cmd.transport(NONE, NULL, 0))) {sperror ("PLEXTOR_START_PISUM8",drive->err);return drive->err;} return 0; } int plextor_start_pie_poe(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_START; //0x15; drive->cmd[2] = 0x00; drive->cmd[3] = 0x00; drive->cmd[8] = 0x08; // scan interval (ECC blocks) drive->cmd[9] = 0x11; if ((drive->err=drive->cmd.transport(NONE, NULL, 0))) {sperror ("PLEXTOR_START_PISUM8_POE",drive->err);return drive->err;} return 0; } int plextor_start_pif(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_START; //0x15; drive->cmd[2] = 0x00; drive->cmd[3] = 0x00; drive->cmd[8] = 0x01; // scan interval (ECC blocks) drive->cmd[9] = 0x12; if ((drive->err=drive->cmd.transport(NONE, NULL, 0))) {sperror ("PLEXTOR_START_PIF",drive->err); return drive->err;} return 0; } int plextor_start_jb_DVD(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_START; //0x15; drive->cmd[2] = 0x10; drive->cmd[3] = 0x00; // DVD drive->cmd[8] = 0x10; // scan interval (ECC blocks) if ((drive->err=drive->cmd.transport(NONE, NULL, 0))) {sperror ("PLEXTOR_START_JB_DVD",drive->err);return drive->err;} return 0; } int plextor_start_jb_CD(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_START; //0x15; drive->cmd[2] = 0x10; drive->cmd[3] = 0x01; // CD if ((drive->err=drive->cmd.transport(NONE, NULL, 0))) {sperror ("PLEXTOR_START_JB_CD",drive->err);return drive->err;} return 0; } int plextor_start_fete(drive_info* drive) { drive->cmd[0] = CMD_PLEX_SCAN_TA_FETE; // 0xF3; drive->cmd[1] = 0x1F; drive->cmd[2] = 0x03; drive->cmd[3] = 0x01; if (drive->media.disc_type & DISC_CD) { int sect; msf sect_msf; // start address drive->cmd[4] = 0x00; drive->cmd[5] = 0x00; drive->cmd[6] = 0x00; // end address sect = drive->media.capacity_total-1; lba2msf(§,§_msf); drive->cmd[7] = sect_msf.m; drive->cmd[8] = sect_msf.s; drive->cmd[9] = sect_msf.f; } else { // start address drive->cmd[4] = 0x00; drive->cmd[5] = 0x00; drive->cmd[6] = 0x00; // end address drive->cmd[7] = ((drive->media.capacity_total-1) >> 16) & 0xFF; drive->cmd[8] = ((drive->media.capacity_total-1) >> 8) & 0xFF; drive->cmd[9] = (drive->media.capacity_total-1) & 0xFF; } if ((drive->err=drive->cmd.transport(NONE, NULL, 0))) {sperror ("PLEXTOR_START_FETE",drive->err);return drive->err;} return 0; } //*********************************// // // end scan commands // //*********************************// int plextor_end_scan(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_END; //0x17; if ((drive->err=drive->cmd.transport(NONE, NULL, 0))) {sperror ("PLEXTOR_END_SCAN",drive->err); return drive->err;} return 0; } int plextor_end_fete(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMD_PLEX_SCAN_TA_FETE; // 0xF3; drive->cmd[1] = 0x1F; drive->cmd[2] = 0x04; if ((drive->err=drive->cmd.transport(NONE, NULL, 0))) {sperror ("PLEXTOR_END_FETE",drive->err); return drive->err;} return 0; } //*********************************// // // test data readout commands // //*********************************// int plextor_read_cd_error_info(drive_info* drive, int* BLER, int* E11, int* E21, int* E31, int* E12, int* E22, int* E32) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_READOUT; // 0x16; drive->cmd[2] = 0x01; drive->cmd[10]= 0x1A; if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0x1A))) {sperror ("PLEXTOR_READ_CD_ERROR_INFO", drive->err);return drive->err;} // int E11, E21, E31, E12, E22, E32, BLER; *BLER = swap2(drive->rd_buf+10); *E31 = swap2(drive->rd_buf+12); *E21 = swap2(drive->rd_buf+14); *E11 = swap2(drive->rd_buf+16); // ??? swap2(drive->rd_buf+18); *E32 = swap2(drive->rd_buf+20); *E22 = swap2(drive->rd_buf+22); *E12 = swap2(drive->rd_buf+24); int C1,C2,CU; C1 = *BLER; C2 = *E22; CU = *E32; #ifdef _debug_cx int i; for (i=0x00; i<0x06; i++) printf("%02X ", drive->rd_buf[i] & 0xFF); printf("| "); for (i=0x06; i<0x0A; i++) printf("%02X ", drive->rd_buf[i] & 0xFF); printf("| "); for (i=0x0A; i<0x1A; i+=2) { if (swap2(drive->rd_buf+i)) printf("%5d ", swap2(drive->rd_buf+i)); else printf("_____ "); } printf("| "); printf("%3d C1| %3d C2| %3d CU\n", C1, C2, CU); #endif return 0; } int plextor_read_pi_info(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_READOUT; // 0x16; drive->cmd[2] = 0x00; drive->cmd[10]= 0x34; if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0x34))) {sperror ("PLEXTOR_READ_PI",drive->err); return drive->err;} /* printf("READ PI:"); for (int i=0; i<0x34; i++) { if (!(i%0x10)) printf("\n"); printf(" %02X",drive->rd_buf[i] & 0xFF); } printf("\n"); */ #ifdef _debug_pi int i; /* // printf("\n| "); for (i=0x00; i<0x34; i++) { if (!(i%0x20))printf("\n| "); printf("%02X ", drive->rd_buf[i] & 0xFF); } */ for (i=0x00; i<0x06; i++) printf("%02X ", drive->rd_buf[i] & 0xFF); printf("|"); printf(" %6X |", swap4(drive->rd_buf+0x06) - 0x030000); printf(" %4X |", swap2(drive->rd_buf+0x0A)); printf(" %4X", swap2(drive->rd_buf+0x0C)); for (i=0x20; i<0x34; i+=4) { if (!(i%0x10))printf(" |"); if (swap4(drive->rd_buf+i)) printf(" %8d", swap4(drive->rd_buf+i)); else printf(" ________"); } // printf("\n"); #endif return 0; } int plextor_read_jb_info(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMP_PLEX_QCHECK; //0xEA; drive->cmd[1] = PLEX_QCHECK_READOUT; // 0x16; drive->cmd[2] = 0x10; drive->cmd[10] = 0x10; if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0x10))) {sperror ("PLEXTOR_READ_JB",drive->err); return drive->err;} #ifdef _debug_jb int i; printf("\n| J/B data: | "); for (i=0x00; i<0x10; i++) printf("%02X ", drive->rd_buf[i] & 0xFF); printf("|\n"); #endif return 0; } int plextor_cx_do_one_interval(drive_info* drive, int* lba, int* BLER, int* E11, int* E21, int* E31, int* E12, int* E22, int* E32) { for (int i=0; (i<5) && *lbamedia.capacity; i++) { if (*lba + 15 < drive->media.capacity) read_cd(drive, *lba, 15, 0xFA); else read_cd(drive, *lba, drive->media.capacity - *lba, 0xFA); *lba+=15; } plextor_read_cd_error_info(drive, BLER, E11, E21, E31, E12, E22, E32); // *lba = return 0; } int plextor_pif_do_one_ecc_block(drive_info* drive, int* lba, int* pif) { read_one_ecc_block(drive, *lba); *lba+= 0x10; plextor_read_pi_info(drive); // *lba = swap4(drive->rd_buf+0x06) - 0x00030000; *pif = swap4(drive->rd_buf+0x24); #ifdef _debug_pi printf(" * %4d\n", *pif); #endif return 0; } int plextor_pisum8_do_eight_ecc_blocks(drive_info* drive, int* lba, int* pie, int* pof) { for (int i=0;i<8;i++) { if ((drive->err = read_one_ecc_block(drive, *lba)));// i = 8; *lba+= 0x10; } plextor_read_pi_info(drive); // *lba = swap4(drive->rd_buf+0x06) - 0x00030000; *pie = swap4(drive->rd_buf+0x24); *pof = swap4(drive->rd_buf+0x10); // *poe = swap4(drive->rd_buf+0x28); // *pif = 0; #ifdef _debug_pi printf(" * %4d\n", *pie); #endif return 0; } int plextor_burst_do_eight_ecc_blocks(drive_info* drive, int* lba, int* pie, int* poe, int* pof) { for (int i=0;i<8;i++) { if ((drive->err = read_one_ecc_block(drive, *lba)));// i = 8; *lba+= 0x10; } plextor_read_pi_info(drive); // *lba = swap4(drive->rd_buf+0x06) - 0x00030000; *pie = swap4(drive->rd_buf+0x24); //* if (swap2(drive->rd_buf+0x0C) > swap2(drive->rd_buf+0x0A)) *poe = swap4(drive->rd_buf+0x28) >> 1; else *poe = 0; *pof = swap4(drive->rd_buf+0x10); #ifdef _debug_pi printf(" * %4d * %4d\n", *pie, *poe); #endif return 0; } int plextor_jitterbeta_DVD_do_16_ecc_blocks(drive_info* drive, int* lba, int* jitter, short int* beta) { short int* i16_beta; char c; for (int i=0;i<16;i++) { int j = read_one_ecc_block(drive, *lba); if (j == COMMAND_FAILED) i=16; *lba+= 0x10; } plextor_read_jb_info(drive); c = drive->rd_buf[10]; drive->rd_buf[10] = drive->rd_buf[11]; drive->rd_buf[11] = c; i16_beta = (short int*)(drive->rd_buf+10); if (drive->dev_ID > PLEXTOR_716) { *beta = *i16_beta; *jitter = 3200 - 2*swap2(drive->rd_buf+12); } else { *beta = *i16_beta; // *jitter = 3000 - 2*swap2(drive->rd_buf+12); *jitter = 3200 - (int)(2.4*swap2(drive->rd_buf+12)); } return (!(drive->rd_buf[2])); } int plextor_jitterbeta_do_one_cd_interval(drive_info* drive, int* lba, int* jitter, short int* beta, int int_len) { short int* i16_beta; char c; int blocks = int_len / 15; int rest = int_len % 15; for (int i=0;ird_buf[10]; drive->rd_buf[10] = drive->rd_buf[11]; drive->rd_buf[11] = c; i16_beta = (short int*)(drive->rd_buf+10); if (drive->dev_ID > PLEXTOR_716) { *beta = *i16_beta; *jitter = 4800 - 2*swap2(drive->rd_buf+12); } else { *beta = *i16_beta; // *jitter = 3200 - 2*swap2(drive->rd_buf+12); *jitter = 3600 - (int)(2.4*swap2(drive->rd_buf+12)); } return (!(drive->rd_buf[2])); } int plextor_read_fete(drive_info* drive) { drive->cmd_clear(); drive->cmd[0] = CMD_PLEX_FETE_READOUT; // 0xF5; drive->cmd[3] = 0x0C; drive->cmd[9] = 0xCE; if ((drive->err=drive->cmd.transport(READ,drive->rd_buf,0xCE))) {sperror ("PLEXTOR_FETE_READOUT",drive->err); return drive->err;} /* for (int i=0; i<0xCE; i++) { if (!(i % 0x20)) printf("\n"); printf("%02X ",drive->rd_buf[i] & 0xFF); } printf("\n"); */ return 0; } scan_commands commands_plextor_list = { plextor_start_cx, plextor_cx_do_one_interval, plextor_end_scan, plextor_start_jb_CD, plextor_jitterbeta_do_one_cd_interval, plextor_end_scan, plextor_start_pie, plextor_pisum8_do_eight_ecc_blocks, plextor_end_scan, plextor_start_pif, plextor_pif_do_one_ecc_block, plextor_end_scan, plextor_start_pie_poe, plextor_burst_do_eight_ecc_blocks, plextor_end_scan, NULL, NULL, NULL, plextor_start_jb_DVD, plextor_jitterbeta_DVD_do_16_ecc_blocks, plextor_end_scan, }; scan_commands commands_plextor() { return commands_plextor_list; }