Logo Search packages:      
Sourcecode: qpxtool version File versions  Download package

test_threads.cpp

/*
 * 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 <math.h>
//#include <stdlib.h>
#define  sqr(x)    (x*x)

#include <string.h>
#include <sys/time.h>

#include <common_functions.h>
#include <qpx_transport.h>
#include <qpx_mmc.h>

//#include <qobject.h>
#include <qthread.h>
#include "test_threads.h"


#include <media_check_generic.h>

// Drive specific includes:
#include <plextor_qcheck.h>
#include <media_check_pioneer.h>
#include <media_check_nec.h>
#include <media_check_liteon.h>
#include <media_check_benq.h>
#include <media_check_benq_rom.h>

#include "scan_events.h"
#include "qpx_const.h"

#define block_dvd 16
#define block_cd  15
#define time_out  13

//#define __ENABLE_PX_POE
#define __ENABLE_POF

#ifdef __DEBUG_PI
#undef __DEBUG_PI
#endif

int   talayers;

void  ScanThread::set_drive(drive_info* drv)
{
      if (drive) delete drive;
      drive = new drive_info(drv->device);
      drivecpy(drive,drv);
}

void  ScanThread::reset_skip_flag()       { mutex.lock(); skip_flag = 0; mutex.unlock();}
void  ScanThread::skip_test()       { mutex.lock(); skip_flag = 1; mutex.unlock();}
void  ScanThread::abort_test()      { mutex.lock(); skip_flag = 2; mutex.unlock();}

int   ScanThread::skip()
{
      bool ret = 0;
      mutex.lock();
      if (skip_flag == 1) {
            skip_flag = 0;
            ret = 1;
      } else if (skip_flag == 2) {
            ret = 2;
      }
      mutex.unlock();
      return ret;
}

int   ScanThread::init_check_table(){
      scan_tbl[WR_GENERIC] = commands_generic();
      scan_tbl[WR_PLEXTOR] = commands_plextor();
      scan_tbl[WR_PIONEER] = commands_pioneer();
      scan_tbl[WR_NEC]     = commands_nec();
      scan_tbl[WR_LITEON]  = commands_liteon();
      scan_tbl[WR_BENQ]    = commands_benq();
      scan_tbl[RD_BENQ]    = commands_benq_rom();
      return 0;
}

int   ScanThread::rd_rate()
{
      block_data  block;
      block.test = TEST_RATE_RD;
      char* TEST="Transfer rate";
      char* SPINUP="Spin UP...";
      char* START="Start reading";
      post_signal(event_test_init,(void*)TEST);
      int hscale = hscaleDVD*drive->media.layers;
      int spinup_time = 4;
      char use_readcd = 0;

      block.err_total=0; block.err_max=0; block.err_cur=0; block.err_avg=0.0;
      block.lba=0; block.block = 0; block.blocks = drive->media.capacity;
      struct      timeval     blk_tbeg,blk_tend, start, finish;
      int   i,ii;
      float spd=0;
      int   r1=0,r2=0;
      printf("Starting Read Transfer Rate test on %s...\n", (drive->media.disc_type & DISC_CD) ? "CD" : "DVD");
      if (drive->media.disc_type & DISC_DVD) {
            drive->parms.read_speed_kb=-1;
            set_read_speed(drive);
            r1=drive->media.capacity/hscale;
            r2=(drive->media.capacity - hscale*r1)%75;
            printf("Blocks: %d\n",r1);
            post_signal(event_debug,(void*)SPINUP);
            wait_unit_ready(drive, time_out);
            spinup(drive, spinup_time);
            if (skip()) return 0;
            post_signal(event_debug,(void*)START);
            gettimeofday(&start, NULL); blk_tbeg = start;
            for (i=0;(i<r1) && (!skip());i++) {
                  for (ii=0;ii<(hscale/block_dvd); ii++) {
                        read(drive, block.lba, block_dvd);
                        block.lba+=block_dvd;
                  }
                  event_block_done(event_show_lba, block);
                  gettimeofday(&blk_tend, NULL);
// **********  Calculating current speed
                  block.time=(blk_tend.tv_sec - blk_tbeg.tv_sec)*1000000 + (blk_tend.tv_usec - blk_tbeg.tv_usec);
                  spd=(float)hscale*2/((float)block.time/1000000.0);
                  block.idx=i;
                  block.block = (i+1)*hscale;
                  block.speed_kb= spd;
                  block.speed_h = (int)((spd*12.5)/dvd1X);
                  block.speed_x = (float)spd/dvd1X;
                  block.time=(blk_tend.tv_sec - start.tv_sec);
                  block.pit=0;
                  event_block_done(event_block_done_rd, block);
                  printf("LBA: %7d / %7d (idx%3d) %5.2fkB/s (%3.2fx)\r",
                        block.lba, drive->media.capacity, block.idx, spd,spd/dvd1X);
                  blk_tbeg = blk_tend;
// **********  Calculating average speed
                  finish = blk_tend;
                  block.time=(finish.tv_sec - start.tv_sec)*1000000 + (finish.tv_usec - start.tv_usec);
                  spd=(float)(i+1)*hscale*2/((float)block.time/1000000);
                  block.time/=1000000;
//          block.time=(finish.tv_sec - start.tv_sec);
//          spd=(float)(block.idx+1)*hscale*2/((float)block.time);
                  block.speed_kb= spd;
                  block.speed_x = (float)spd/dvd1X;
                  block.pit=1;
                  event_block_done(event_block_done_rd, block);
            }
      } else if (drive->media.disc_type & DISC_CD) {
            if (drive->capabilities & CAP_DAE) use_readcd = 1;
            drive->parms.read_speed_kb=-1;
            set_read_speed(drive);
            r1=drive->media.capacity/hscaleCD;
            r2=(drive->media.capacity - hscaleCD*r1)%75;
            printf("Blocks: %d\n",r1);
            post_signal(event_debug,(void*)SPINUP);
            wait_unit_ready(drive, time_out);
            spinup(drive, spinup_time);
            if (skip()) return 0;
            post_signal(event_debug,(void*)START);
            gettimeofday(&start, NULL); blk_tbeg = start;
            seek(drive, 0);
            for (i=0;(i<r1) && (!skip());i++) {
                  for (ii=0;ii<(hscaleCD/block_cd); ii++) {
                        if (use_readcd)
                              read_cd(drive, block.lba, block_cd, 0xF8);
                        else
                              read(drive, block.lba, block_cd);
                        block.lba+=block_cd;
                        if (drive->err) skip_test();
                  }
                  event_block_done(event_show_lba, block);
                  gettimeofday(&blk_tend, NULL);
// **********  Calculating current speed
                  block.time=(blk_tend.tv_sec - blk_tbeg.tv_sec)*1000000 + (blk_tend.tv_usec - blk_tbeg.tv_usec);
                  spd=(float)hscaleCD*2/((float)block.time/1000000.0);
                  block.idx=i;
                  block.block = (i+1)*hscaleCD;
                  block.speed_kb= spd;
                  block.speed_h = (int)(spd*5/cd1X);
                  block.speed_x = (float)spd/cd1X;
                  block.time=(blk_tend.tv_sec - start.tv_sec);
                  block.pit=0;
                  event_block_done(event_block_done_rd, block);
                  printf("LBA: %7d / %7d (idx %3d) %5.3fkB/s (%3.2fx)\r",
                        block.lba, drive->media.capacity, block.idx, spd, spd/cd1X);
                  blk_tbeg = blk_tend;
// **********  Calculating average speed
                  finish = blk_tend;
                  block.time=(finish.tv_sec - start.tv_sec)*1000000 + (finish.tv_usec - start.tv_usec);
                  spd=(float)(i+1)*hscaleCD*2/((float)block.time/1000000);
                  block.time/=1000000;
                  block.speed_kb= spd;
                  block.speed_x = (float)spd/cd1X;
                  block.pit=1;
                  event_block_done(event_block_done_rd, block);
            }
      }
      printf("\n\n");
      return 0;
}

int ScanThread::scan_cx ()
{
      char* TEST="CD  C1/C2";
      post_signal(event_test_init,(void*)TEST);
struct timeval start, finish;

      int scan_blk = 0;
      int blocks_failed = 0;

      block_data block;
      block.test=TEST_CD_CX;
      block.err_total=0; block.err_max=0; block.err_cur=0; block.err_avg=0.0;
      block.lba = 0;
//    block.lba = 350*750;
      block.blocks = drive->media.capacity; block.idx=0;

      int BLER, block_BLER=0, block_min_BLER=0, block_max_BLER=0, total_BLER=0, max_BLER=0; // float avg_BLER=0.0;
      int E11,  block_E11=0,  block_min_E11=0,  block_max_E11=0,  total_E11=0,  max_E11=0;  // float avg_E11=0.0;
      int E21,  block_E21=0,  block_min_E21=0,  block_max_E21=0,  total_E21=0,  max_E21=0;  // float avg_E21=0.0;
      int E31,  block_E31=0,  block_min_E31=0,  block_max_E31=0,  total_E31=0,  max_E31=0;  // float avg_E31=0.0;
      int E12,  block_E12=0,  block_min_E12=0,  block_max_E12=0,  total_E12=0,  max_E12=0;  // float avg_E12=0.0;
      int E22,  block_E22=0,  block_min_E22=0,  block_max_E22=0,  total_E22=0,  max_E22=0;  // float avg_E22=0.0;
      int E32,  block_E32=0,  block_min_E32=0,  block_max_E32=0,  total_E32=0,  max_E32=0;  // float avg_E32=0.0;
      int oldidx = 0;
//    int seconds;
      int intervals;
      int i=0;
      int hscale_blk = hscaleCD/75;
      wait_unit_ready(drive, time_out);
      if (scan_tbl[drive->ven_ID].cx_start) {
            printf("\n** Starting %s C1/C2/CU scan...\n",vendor[drive->ven_ID]);
            drive->err = (scan_tbl[drive->ven_ID].cx_start)(drive);    // *****
            if (drive->err) {
                  printf("Error initializing test!\n");
                  return 2;
            }
      } else {
            printf("CX scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return 1;
      }
      block.ext = (drive->ven_ID == WR_PLEXTOR) ? 1 : 0;
      printf("Running %s CD scan\n\n",block.ext ? "Extended" : "Standart");
      gettimeofday(&start, NULL);

//    seconds = drive->media.capacity/75+!!(drive->media.capacity%75);
//    for (block.lba=0;(block.lba<drive->media.capacity) && (!skip());)

      intervals = drive->media.capacity / hscaleCD + !!(drive->media.capacity % hscaleCD);
//    intervals = drive->media.capacity / hscaleCD;
      for (block.idx = 0; (block.idx<intervals) && (!skip());)
      {
            oldidx = block.idx;
            block_BLER=0;
            block_E11=0; block_E21=0; block_E31=0;
            block_E12=0; block_E22=0; block_E32=0;
            for (i=0; i<128; i++) {
                  arr_BLER[i] = 0;
                  arr_E11[i] = 0; arr_E21[i] = 0; arr_E31[i] = 0;
                  arr_E12[i] = 0; arr_E22[i] = 0; arr_E32[i] = 0;
            }
            for (i=0;(i<128) && (block.idx == oldidx) && (block.lba<drive->media.capacity);i++) {
                  scan_blk = scan_tbl[drive->ven_ID].cx_one_interval(drive, &block.lba, &BLER, &E11, &E21, &E31, &E12, &E22, &E32);
                  switch(scan_blk) {
                        case SCAN_BLOCK_DONE: break;
                        case SCAN_BLOCK_FAIL: blocks_failed++; break;
                        case SCAN_BLOCK_LAST: block.lba = drive->media.capacity; break;
                        default: break;
                  }
//                block.idx = max(0, block.lba/hscaleCD - 1);
                  block.idx = block.lba/hscaleCD;
//                block.lba+=75;
                  if (!i) {
                        block_min_BLER = BLER; block_max_BLER = BLER;
                        block_min_E11  = E11;  block_max_E11 = E11;
                        block_min_E21  = E21;  block_max_E21 = E21;
                        block_min_E31  = E31;  block_max_E31 = E31;
                        block_min_E12  = E12;  block_max_E12 = E12;
                        block_min_E22  = E22;  block_max_E22 = E22;
                        block_min_E32  = E32;  block_max_E32 = E32;
                  } else {
                        block_min_BLER = min (block_min_BLER, BLER); block_max_BLER = max (block_max_BLER, BLER);
                        block_min_E11  = min (block_min_E11, E11);   block_max_E11  = max (block_max_E11, E11);
                        block_min_E21  = min (block_min_E21, E21);   block_max_E21  = max (block_max_E21, E21);
                        block_min_E31  = min (block_min_E31, E31);   block_max_E31  = max (block_max_E31, E31);
                        block_min_E12  = min (block_min_E12, E12);   block_max_E12  = max (block_max_E12, E12);
                        block_min_E22  = min (block_min_E22, E22);   block_max_E22  = max (block_max_E22, E22);
                        block_min_E32  = min (block_min_E32, E32);   block_max_E32  = max (block_max_E32, E32);
                  }
                  block_BLER += BLER; total_BLER += BLER; max_BLER = max(max_BLER, BLER);
                  block_E11  += E11;  total_E11  += E11;  max_E11  = max(max_E11, E11);
                  block_E21  += E21;  total_E21  += E21;  max_E21  = max(max_E21, E21);
                  block_E31  += E31;  total_E31  += E31;  max_E31  = max(max_E31, E31);
                  block_E12  += E12;  total_E12  += E12;  max_E12  = max(max_E12, E12);
                  block_E22  += E22;  total_E22  += E22;  max_E22  = max(max_E22, E22);
                  block_E32  += E32;  total_E32  += E32;  max_E32  = max(max_E32, E32);
                  arr_BLER[i] = BLER;
                  arr_E11[i] = E11; arr_E21[i] = E21; arr_E31[i] = E31;
                  arr_E12[i] = E12; arr_E22[i] = E22; arr_E32[i] = E32;
            }
            hscale_blk = i;
            block.idx=oldidx;
//          if (block.idx > (hres-1)) block.idx = oldidx+1;
//          block.idx--;
//          if (block.idx<0) block.idx
            gettimeofday(&finish, NULL);
            block.time = finish.tv_sec - start.tv_sec;

            block.block = block.lba;
// ***************
            block.err_total = total_BLER; block.err_max = max_BLER;
            block.err_cur = block_max_BLER; block.err_min = block_min_BLER;
            block.err_avg = (int)(total_BLER*100.0/(block.block/75))/100.0;
            block.err_m = block_BLER / hscale_blk;
            block.err_d = dispers (block.err_m, arr_BLER, hscale_blk);
            event_block_done(event_block_done_c1pie, block);
            if (block.ext) event_block_done(event_block_done_BLER, block);

            if (block.ext) {
                  block.err_total = total_E11; block.err_max = max_E11;
                  block.err_cur = block_max_E11; block.err_min = block_min_E11;
                  block.err_avg = (int)(total_E11*100.0/(block.block/75))/100.0;
                  block.err_m = block_E11 / hscale_blk;
                  block.err_d = dispers (block.err_m, arr_E11, hscale_blk);
                  event_block_done(event_block_done_E11, block);

                  block.err_total = total_E21; block.err_max = max_E21;
                  block.err_cur = block_max_E21; block.err_min = block_min_E21;
                  block.err_avg = (int)(total_E21*100.0/(block.block/75))/100.0;
                  block.err_m = block_E21 / hscale_blk;
                  block.err_d = dispers (block.err_m, arr_E21, hscale_blk);
                  event_block_done(event_block_done_E21, block);

                  block.err_total = total_E31; block.err_max = max_E31;
                  block.err_cur = block_max_E31;  block.err_min = block_min_E31;
                  block.err_avg = (int)(total_E31*100.0/(block.block/75))/100.0;
                  block.err_m = block_E31 / hscale_blk;
                  block.err_d = dispers (block.err_m, arr_E31, hscale_blk);
                  event_block_done(event_block_done_E31, block);

                  block.err_total = total_E12; block.err_max = max_E12;
                  block.err_cur = block_max_E12;  block.err_min = block_min_E12;
                  block.err_avg = (int)(total_E12*100.0/(block.block/75))/100.0;
                  block.err_m = block_E12 / hscale_blk;
                  block.err_d = dispers (block.err_m, arr_E12, hscale_blk);
                  event_block_done(event_block_done_E12, block);
            }

            block.err_total = total_E22; block.err_max = max_E22;
            block.err_cur = block_max_E22;  block.err_min = block_min_E22;
            block.err_avg = (int)(total_E22*100.0/(block.block/75))/100.0;
            block.err_m = block_E22 / hscale_blk;
            block.err_d = dispers (block.err_m, arr_E22, hscale_blk);
            event_block_done(event_block_done_c2pif, block);
            if (block.ext) event_block_done(event_block_done_E22, block);

            block.err_total = total_E32; block.err_max = max_E32;
            block.err_cur = block_max_E32;  block.err_min = block_min_E32;
            block.err_avg = (int)(total_E32*100.0/(block.block/75))/100.0;
            block.err_m = block_E32 / hscale_blk;
            block.err_d = dispers (block.err_m, arr_E32, hscale_blk);
            event_block_done(event_block_done_cupof, block);
            if (block.ext) event_block_done(event_block_done_E32, block);
// ***************
            block.err_m = block_BLER / hscale_blk;
            printf("Pos: (index %3d) MSF: %02d:%02d.%02d LBA: %06X :",
                  block.idx, (block.lba-75)/4500, ((block.lba-75)/75)%60, block.lba%75, block.lba);
            if (block.ext)
                  printf(" %4d BLER,%4d E11,%4d E21,%4d E31,%4d E12,%4d E22,%4d E32\n",
                        block_max_BLER, block_max_E11, block_max_E21, block_max_E31, block_max_E12, block_max_E22, block_max_E32);
            else
                  printf(" %4d C1,%4d C2,%4d CU\n",
                        block_max_BLER, block_max_E22, block_max_E32);

            block.idx++;
            oldidx = block.idx;
      }
      printf("\n\n");
      if (scan_tbl[drive->ven_ID].cx_end)
            (scan_tbl[drive->ven_ID].cx_end)(drive);       // *****
      return 0;
}

int ScanThread::scan_jb_cd()
{
      char* TEST="CD  Jitter/Beta";
      post_signal(event_test_init,(void*)TEST);
struct timeval start, finish;

      block_data block;
      block.test=TEST_CD_JB;
      block.err_total=0; block.err_max=0; block.err_cur=0; block.err_avg=0.0;
      block.lba = 0;
      int         oldidx=0;
      short int   beta=0, bo=0, b_max=0, b_min=0, blk_bmin=0, blk_bmax=0;
      int         i, jitter=0, jo=0, j_max=0, j_min=0, blk_jmin=0, blk_jmax=0;
      unsigned int      value;
      int         interval_len = 75;
      int         intervals = 0;
      int         bad = 0, bbad = 0;
      intervals = drive->media.capacity / hscaleCD + !!(drive->media.capacity % hscaleCD);
      block.blocks = intervals;
      wait_unit_ready(drive, time_out);
      if (scan_tbl[drive->ven_ID].jb_cd_start) {
            printf("\n** Starting %s CD J/B scan...\n",vendor[drive->ven_ID]);
            drive->err = (scan_tbl[drive->ven_ID].jb_cd_start)(drive);
            if (drive->err) {
                  printf("Error initializing test!\n");
                  return 2;
            }
      } else {
            printf("\nCD J/B scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return 1;
      }
      gettimeofday(&start, NULL);
//    for (block.idx = 0; (block.idx<intervals) && (!skip()); block.idx+=drive->parms.interval)
      for (block.idx = 0; (block.idx<intervals) && (!skip());)
      {
            bbad = 1;
//          for (i=0; i<(hscaleCD/interval_len); i++)
            for (i=0;oldidx == block.idx;i++)
            {
                  bo = beta; jo=jitter;
//                block.lba = block.idx*hscaleCD+i*interval_len;
                  oldidx = block.idx;
                  bad = scan_tbl[drive->ven_ID].jb_cd_one_interval(drive, &block.lba, &jitter, &beta, interval_len);
                  block.idx = block.lba / hscaleCD;
//                printf("block.idx = %d, %s\n",block.idx, bad ? "BAD" : "GOOD");
                  if (bbad && (!bad)) {
                        bo = beta;
                        jo = jitter;
                        if (!block.idx) {
                              b_max = beta;
                              b_min = beta;
                              j_max = jitter;
                              j_min = jitter;
                        } else {
                              b_max = max(b_max, beta);
                              b_min = min(b_min, beta);
                              j_max = max(j_max, jitter);
                              j_min = min(j_min, jitter);
                        }
                  }
                  event_block_done(event_show_lba, block);
//                if ((beta>1000)) beta = bo;
//                if (jitter > (jo*2)) jitter = jo;
                  value = (beta) << 16 | (jitter & 0xFFFF);
                  printf("LBA: %06X  jitter: %4d,  beta: %4d\r", block.idx*hscaleCD+i*interval_len, jitter, (int)beta);
                  if (!bad) {
                        if (i>0) {
                              blk_bmax=max(blk_bmax,beta); blk_bmin=min(blk_bmin,beta);
                              blk_jmax=max(blk_jmax,jitter); blk_jmin=min(blk_jmin,jitter);
                        } else {
                              blk_bmax=beta; blk_bmin=beta;
                              blk_jmax=jitter; blk_jmin=jitter;
                        }
                        bbad = 0;
                  }
                  gettimeofday(&finish, NULL);
                  block.time = finish.tv_sec - start.tv_sec;
            }
            if (block.idx > (hres-1)) block.idx = oldidx+1;
            if (block.idx>0) {
                  b_max=max(b_max,blk_bmax); b_min=min(b_min,blk_bmin);
                  j_max=max(j_max,blk_jmax); j_min=min(j_min,blk_jmin);
            } else {
                  b_max=blk_bmax; b_min=blk_bmin;
                  j_max=blk_jmax; j_min=blk_jmin;
            }
            oldidx = block.idx;
            block.block = (block.idx-1)*hscaleCD;
            block.idx--;
            block.pit = 0;
            block.jmax = (blk_jmax*100)/50; block.jmin = (blk_jmin*100)/50; block.bmax = blk_bmax; block.bmin = blk_bmin;
            event_block_done(event_block_done_jb, block);
            block.pit = 1;
            block.jmax = j_max/100.0; block.jmin = j_min/100.0; block.bmax = b_max/10.0; block.bmin = b_min/10.0;
            event_block_done(event_block_done_jb, block);
            block.idx++;
      }
      printf("\n\n");
      scan_tbl[drive->ven_ID].jb_cd_end(drive);
//    drive->unlock();
      return 0;
}

int ScanThread::scan_pie() {
      char* TEST="DVD PIE";
      post_signal(event_test_init,(void*)TEST);
struct timeval start, finish;

      int scan_blk = 0;
      int blocks_failed = 0;
      int hscale = hscaleDVD*drive->media.layers;

      block_data block;
      block.test=TEST_DVD_PIE;
      block.lba = 0;
      block.blocks = drive->media.capacity;

      int   oldidx=0;
      int   intervals,i;

      int   block_min_pie = 0, block_max_pie = 0, block_pie, max_pie = 0, total_pie = 0, pie;
      int   block_min_pif = 0, block_max_pif = 0, block_pif, max_pif = 0, total_pif = 0, pif;
      int   block_min_poe = 0, block_max_poe = 0, block_poe, max_poe = 0, total_poe = 0, poe;
      int   block_min_pof = 0, block_max_pof = 0, block_pof, max_pof = 0, total_pof = 0, pof;
      int   broken_pie = 0;

      int   read_pif = 0;
      int   read_poe = 0;
      int   hscale_blk = hscaleDVD/128;
      intervals = drive->media.capacity/hscale; 

// Initializing test...  PIE+POE / PIE+PIF / PIE
      wait_unit_ready(drive, time_out);
      if (scan_tbl[drive->ven_ID].pie_poe_start) {
            printf("\n** Starting %s PIE/POE/POF sum8 burst scan...\n",vendor[drive->ven_ID]);
            drive->err = (scan_tbl[drive->ven_ID].pie_poe_start)(drive);
            if (drive->err) {
                  printf("Error initializing test!\n");
                  return 2;
            }
            read_poe = 1;
      } else if ((scan_tbl[drive->ven_ID].pie_start) || (scan_tbl[drive->ven_ID].pie_pif_start)) {
            if (scan_tbl[drive->ven_ID].pif_start) {
                  drive->err = (scan_tbl[drive->ven_ID].pie_start)(drive);
                  printf("\n** Starting %s PIE sum8 scan...\n",vendor[drive->ven_ID]);
            } else {
                  drive->err = (scan_tbl[drive->ven_ID].pie_pif_start)(drive);
                  printf("\n** Starting %s PIE/PIF sum8 scan...\n",vendor[drive->ven_ID]);
                  read_pif = 1;
            }
            if (drive->err) {
                  printf("Error initializing test!\n");
                  return 2;
            }
      } else {
            printf("PIE scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return 1;
      }

      printf("Blocks: %d\n",intervals);
      gettimeofday(&start, NULL);
//    for (block.idx = 0;(block.idx<intervals) && (!skip()); block.idx+=drive->parms.interval)
      for (block.idx = 0;(block.idx<intervals) && (!skip()); ) //block.idx+=drive->parms.interval)
      {
            block_pie = 0; block_pif = 0; block_poe = 0; block_pof = 0;
//          for (i=0;i<(hscale/(128));i++){
            for (i=0; oldidx == block.idx;i++){
//                block.lba = block.idx*hscale+i*128;
                  oldidx = block.idx;
                  if (read_poe)
                        scan_blk = scan_tbl[drive->ven_ID].pie_poe_8_ecc_blocks(drive, &block.lba, &pie, &poe, &pof);
                  else if (read_pif)
                        scan_blk = scan_tbl[drive->ven_ID].pie_pif_8_ecc_blocks(drive, &block.lba, &pie, &pif, &pof);
                  else
                        scan_blk = scan_tbl[drive->ven_ID].pie_8_ecc_blocks(drive, &block.lba, &pie, &pof);
                  switch(scan_blk) {
                        case SCAN_BLOCK_DONE: break;
                        case SCAN_BLOCK_FAIL: blocks_failed++; break;
                        case SCAN_BLOCK_LAST: block.lba = drive->media.capacity; break;
                        default: break;
                  }
                  block.idx = block.lba / hscale;
//          printf("block.lba = %d; block.idx = %d\n",block.lba,block.idx);
                  event_block_done(event_show_lba, block);
                  if (pie > 280) broken_pie++;

                  arr_E11[i] = pie;
                  arr_E21[i] = pif;
                  arr_E22[i] = poe;
                  arr_E32[i] = pof;

                  if (!i) {
                        block_min_pie = pie; block_max_pie = pie;
                        block_min_pif = pif; block_max_pif = pif;
                        block_min_poe = poe; block_max_poe = poe;
                        block_min_pof = pof; block_max_pof = pof;
                  } else {
                        block_min_pie = min (block_min_pie, pie); block_max_pie = max (block_max_pie, pie);
                        block_min_pif = min (block_min_pif, pif); block_max_pif = max (block_max_pif, pif);
                        block_min_poe = min (block_min_poe, poe); block_max_poe = max (block_max_poe, poe);
                        block_min_pof = min (block_min_pof, pof); block_max_pof = max (block_max_pof, pof);
                  }

                  block_pie += pie;
                  total_pie += pie;
                  max_pie = max (max_pie, pie);
                  if (read_poe) {
                        block_poe += poe;
                        total_poe += poe;
                        max_poe = max (max_poe, poe);
                  } else if (read_pif) {
                        block_pif += pif;
                        total_pif += pif;
                        max_pif = max (max_pif, pif);
                  }
                  block_pof += pof;
                  total_pof += pof;
                  max_pof = max (max_pof, pof);
            }
            gettimeofday(&finish, NULL);
            if (block.idx > (hres-1)) block.idx = oldidx+1;
            oldidx = block.idx;
            block.block  = (block.idx-1)*hscale;
            block.time = finish.tv_sec - start.tv_sec;
            block.idx--;

            block.err_total = total_pie;
            block.err_cur   = block_max_pie;
            block.err_min   = block_min_pie;
            block.err_max   = max_pie;
            block.err_avg   = (int)(total_pie*100.0/((block.block+i*128) >> 7))/100.0;
            block.err_m = block_pie / hscale_blk;
            block.err_d = dispers (block.err_m, arr_E11, hscale_blk);
            event_block_done(event_block_done_c1pie, block);

            if (read_pif) {
                  block.err_total = total_pif;
                  block.err_cur   = block_max_pif;
                  block.err_min   = block_min_pif;
                  block.err_max   = max_pif;
                  block.err_avg   = (int)(total_pif*100.0/((block.block+i*128) >> 7))/100.0;
                  block.err_m = block_pif / hscale_blk;
                  block.err_d = dispers (block.err_m, arr_E21, hscale_blk);
                  event_block_done(event_block_done_c2pif, block);
            }
            if (read_poe) {
                  block.err_total = total_poe;
                  block.err_cur   = block_max_poe;
                  block.err_min   = block_min_poe;
                  block.err_max   = max_poe;
                  block.err_avg   = (int)(total_poe*100.0/((block.block+i*16) >> 7))/100.0;
                  block.err_m = block_poe / hscale_blk;
                  block.err_d = dispers (block.err_m, arr_E22, hscale_blk);
#ifdef __ENABLE_PX_POE
                  event_block_done(event_block_done_poe, block);
#endif
            }

            block.err_total = total_pof;
            block.err_cur   = block_max_pof;
            block.err_min   = block_min_pof;
            block.err_max   = max_pof;
            block.err_avg   = (int)(total_pof*100.0/((block.block+i*16) >> 7))/100.0;
            block.err_m = block_pof / hscale_blk;
            block.err_d = dispers (block.err_m, arr_E32, hscale_blk);
            event_block_done(event_block_done_cupof, block);

            block.idx++;
            printf("pos: %d / %d || PIE: %3d max, %3d cur, %7d tot ||",
                  block.idx*hscale+i*128, drive->media.capacity, max_pie, block_max_pie, total_pie);
            if (read_pif) printf("PIF: %3d max, %3d cur, %7d tot ||", max_pif, block_max_pif, total_pif);
#ifdef __ENABLE_PX_POE
            if (read_poe) printf("POE: %3d max, %3d cur, %7d tot ||", max_poe, block_max_poe, total_poe);
#endif
#ifdef __ENABLE_POF
            printf("POF: %3d max, %3d cur, %7d tot ||", max_pof, block_max_pof, total_pof);
#endif
//          if (read_poe) printf("");
            printf("\n");
      }
      printf("\n\n");
      if (read_poe)
            if (scan_tbl[drive->ven_ID].pie_poe_end)
                scan_tbl[drive->ven_ID].pie_poe_end(drive);
      else
            if (scan_tbl[drive->ven_ID].pie_end)
                scan_tbl[drive->ven_ID].pie_end(drive);
      block.err_avg=(int)(block.err_total*100.0/(drive->media.capacity >> 4))/100.0;
#ifdef __DEBUG_PI
      printf("\n#\n#total error count                                   : %8d         \n", block.err_total);
      printf("#average nbr of errors per sector                    : %8.2f\n", (float)block.err_total / drive->media.capacity);
      printf("#average nbr of errors per ECC block                 : %8.2f\n", (float)block.err_total / (drive->media.capacity >> 4) );
      printf("#PIsum8 max                                          : %8d\n", block.err_max);
      printf("#occurences of 8 consecutive blocks with PIsum8 > 280: %8d\n", broken_count);
#endif
//    drive->unlock();
      return 0;
};

int ScanThread::scan_pif()
{
//    drive->lock();
      char* TEST="DVD PIF";
      post_signal(event_test_init,(void*)TEST);
      int hscale = hscaleDVD*drive->media.layers;
struct timeval start, finish;

      int scan_blk = 0;
      int blocks_failed = 0;

      block_data block;
      block.test=TEST_DVD_PIF;
      block.err_total=0; block.err_max=0; block.err_min=0; block.err_cur=0; block.err_avg=0.0;
      block.lba = 0;
      block.blocks = drive->media.capacity;
      int   block_err = 0;
      int   oldidx=0;
      int   current = 0;
      int     intervals,i;
      int   broken_count = 0;
      int   hscale_blk = hscaleDVD/16;
      intervals = drive->media.capacity/hscale;
      wait_unit_ready(drive, time_out);
      if (scan_tbl[drive->ven_ID].pif_start) {
            printf("\n** Starting %s PIF sum1 scan...\n",vendor[drive->ven_ID]);
            drive->err = (scan_tbl[drive->ven_ID].pif_start)(drive);
            if (drive->err) {
                  printf("Error initializing test!\n");
                  return 2;
            }
      } else {
            printf("PIF scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return 1;
      }
      printf("Blocks: %d\n",intervals);
      gettimeofday(&start, NULL);
//    for (block.idx = 0;(block.idx<intervals) && (!skip());block.idx+=drive->parms.interval)
      for (block.idx = 0;(block.idx<intervals) && (!skip()); ) //block.idx+=drive->parms.interval)
      {
            block_err = 0;
//          for (i=0;i<(hscale/16);i++){
            for (i=0;oldidx == block.idx;i++){
//                block.lba = block.idx*hscale+i*16;
                  oldidx = block.idx;
                  scan_blk = scan_tbl[drive->ven_ID].pif_1_ecc_block(drive, &block.lba, &current);
                  switch(scan_blk) {
                        case SCAN_BLOCK_DONE: break;
                        case SCAN_BLOCK_FAIL: blocks_failed++; break;
                        case SCAN_BLOCK_LAST: block.lba = drive->media.capacity; break;
                        default: break;
                  }
                  block.idx = block.lba / hscale;
//          printf("block.lba = %d; block.idx = %d\n",block.lba,block.idx);
                  event_block_done(event_show_lba, block);
                  arr_E11[i] = current;
                  if (!i) {
                        block.err_cur = current;
                        block.err_min = current;
                  } else {
                        block.err_cur = max (block.err_cur, current);
                        block.err_min = min (block.err_min, current);
                  }
                  block_err += current;
                  block.err_total += current;
                  block.err_cur = max (block.err_cur, current);
                  if (current > 4) broken_count++;
                  block.err_max = max (block.err_cur, block.err_max);
            }
            gettimeofday(&finish, NULL);
            if (block.idx > (hres-1)) block.idx = oldidx+1;
            oldidx = block.idx;
            block.block   = (block.idx-1)*hscale;
            block.time = finish.tv_sec - start.tv_sec;
            block.idx--;

            block.err_avg=(int)(block.err_total*100.0/((block.block) >> 4))/100.0;
            block.err_m = block_err / hscale_blk;
            block.err_d = dispers (block.err_m, arr_E11, hscale_blk);
            event_block_done(event_block_done_c2pif, block);

            block.idx++;
            printf("pos: %d / %d, max: %d, curr: %d, total: %d\r", block.idx*hscale+i*16,
                  block.blocks, block.err_max, block.err_cur, block.err_total);
      }
      printf("\n\n");
      scan_tbl[drive->ven_ID].pif_end(drive);

#ifdef __DEBUG_PI
      printf("\n#\n#total error count                                   : %8d         \n", block.err_total);
      printf("#average nbr of errors per sector                 : %8.2f\n", (float)block.err_total / block.blocks);
      printf("#average nbr of errors per ECC block              : %8.2f\n", (float)block.err_total / (block.blocks >> 4) );
      printf("#PIF max                                          : %8d\n", block.err_max);
      printf("#occurences of ECC consecutive blocks with PIF > 4: %8d\n", broken_count);
#endif
//    drive->unlock();
      return 0;
}

int ScanThread::scan_jb_dvd ()
{
      char* TEST="DVD Jitter/Beta"; 
      post_signal(event_test_init,(void*)TEST);
      int hscale = hscaleDVD*drive->media.layers;
struct timeval start, finish;

      block_data block;
      block.test = TEST_DVD_JB;
      block.err_total=0; block.err_max=0; block.err_cur=0; block.err_avg=0.0;
      block.lba = 0;
      int         oldidx=0;
      short int   beta=0, bo=0, b_max=0, b_min=0, blk_bmin=0, blk_bmax=0;
      int         jitter=0, jo=0, j_max=0, j_min=0, blk_jmin=0, blk_jmax=0;
      unsigned int      value;
      int         i, intervals;
      int         bad = 0, bbad = 0;
      intervals = drive->media.capacity / hscale + !!(drive->media.capacity % hscale);
      block.blocks = intervals;
      wait_unit_ready(drive, time_out);
      if (scan_tbl[drive->ven_ID].jb_dvd_start) {
            printf("\n** Starting %s DVD J/B scan...\n",vendor[drive->ven_ID]);
            drive->err = (scan_tbl[drive->ven_ID].jb_dvd_start)(drive);
            if (drive->err) {
                  printf("Error initializing test!\n");
                  return 2;
            }
      } else {
            printf("DVD J/B scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return 1;
      }
      gettimeofday(&start, NULL);
//    for (block.idx = 0;(block.idx<intervals) && (!skip());block.idx+=drive->parms.interval)
      for (block.idx = 0;(block.idx<intervals) && (!skip());)
      {
            bbad = 1;
//          for (i=0;i<(hscale*drive->media.layers/256);i++)
            for (i=0;oldidx == block.idx;i++)
            {
                  bo = beta; jo=jitter;
//                block.lba = block.idx*hscale+i*256;
                  oldidx = block.idx;
                  bad = scan_tbl[drive->ven_ID].jb_dvd_16_ecc_blocks(drive, &block.lba, &jitter, &beta);
                  block.idx = block.lba / hscale;
                  printf("block.idx = %d\n",block.idx);
                  if (bbad && (!bad)) {
                        bo = beta;
                        jo = jitter;
                        if (!block.idx) {
                              b_max = beta;
                              b_min = beta;
                              j_max = jitter;
                              j_min = jitter;
                        } else {
                              b_max = max(b_max, beta);
                              b_min = min(b_min, beta);
                              j_max = max(j_max, jitter);
                              j_min = min(j_min, jitter);
                        }
                  }
                  event_block_done(event_show_lba, block);
                  if ((beta>1000) || (beta == 0)) beta = bo;
                  if (jitter > (jo*2)) jitter = jo;
                  value = (beta) << 16 | (jitter & 0xFFFF);
                  printf("\rLBA: %d  jitter: %4d,  beta: %4d  ", block.idx*hscale+i*256, jitter, (int)beta);
                  if (!bad) {
                        if (i>0) {
                              blk_bmax=max(blk_bmax,beta); blk_bmin=min(blk_bmin,beta);
                              blk_jmax=max(blk_jmax,jitter); blk_jmin=min(blk_jmin,jitter);
                        } else {
                              blk_bmax=beta; blk_bmin=beta;
                              blk_jmax=jitter; blk_jmin=jitter;
                        }
                        bbad = 0;
                  }
                  gettimeofday(&finish, NULL);
                  block.time = finish.tv_sec - start.tv_sec;
            }
            if (block.idx > (hres-1)) block.idx = oldidx+1;
            if (block.idx>0) {
                  b_max=max(b_max,blk_bmax); b_min=min(b_min,blk_bmin);
                  j_max=max(j_max,blk_jmax); j_min=min(j_min,blk_jmin);
            } else {
                  b_max=blk_bmax; b_min=blk_bmin;
                  j_max=blk_jmax; j_min=blk_jmin;
            }
//          block.block   = block.idx;
            oldidx = block.idx;
            block.block = (block.idx-1)*hscale;
            block.idx--;
            block.pit = 0;
            block.jmax = (blk_jmax*100)/50; block.jmin = (blk_jmin*100)/50; block.bmax = blk_bmax; block.bmin = blk_bmin;
            event_block_done(event_block_done_jb, block);
            block.pit = 1;
            block.jmax = j_max/100.0; block.jmin = j_min/100.0; block.bmax = b_max/10.0; block.bmin = b_min/10.0;
            event_block_done(event_block_done_jb, block);
            block.idx++;
      }
      printf("\n\n");
      scan_tbl[drive->ven_ID].jb_dvd_end(drive);
//    drive->unlock();
      return 0;
}

int ScanThread::scan_fete() {
      char* TEST="FE/TE";
      post_signal(event_test_init,(void*)TEST);
struct timeval start, finish;
      block_data block;
      block.test = TEST_FETE;
      block.bmax = 0; block.jmax = 0;

      printf("** Starting FE/TE test...\n");
      int rdy;
//    int i, j;
//    int adds=0;
      int offs=8;
      int fe,te;
      int tfe=0,tte=0;
      wait_unit_ready(drive, time_out);
      plextor_start_fete(drive);
      rdy = test_unit_ready(drive);
      plextor_read_fete(drive);
      gettimeofday(&start, NULL);
      for (block.idx=0; (block.idx<99) && (rdy == 0x20408) && (!skip());) {
            rdy = test_unit_ready(drive);
//          printf ("*");
            te = drive->rd_buf[offs];
            fe = drive->rd_buf[offs+1];
            while ((te>0) || (fe>0)) {
                  printf("BLK #%03d: FE=%02d, TE=%02d\r",block.idx,fe,te);
                  block.block = block.idx-1;
                  block.ofe = block.nfe;
                  block.ote = block.nte;
                  block.nfe = fe;
                  block.nte = te;
                  block.bmax = max (fe, (int)block.bmax);
                  block.jmax = max (te, (int)block.jmax);
                  tfe += fe;
                  tte += te;
                  block.bmin = tfe / (block.idx+1.0);
                  block.jmin = tte / (block.idx+1.0);
                  if (block.idx) {
                        gettimeofday(&finish, NULL);
                        block.time = finish.tv_sec - start.tv_sec;
                        event_block_done(event_block_done_fete, block);
                  }
                  offs+=2;
                  block.idx++;
                  te = drive->rd_buf[offs];
                  fe = drive->rd_buf[offs+1];
            }
            usleep(1000000);
            plextor_read_fete(drive);
      }
      printf("\n\nSend FE/TE end command...\n");
      plextor_end_fete(drive);
      return 0;
}

//*********************************//
//
//  tests' algorythms 
//
//*********************************//

int init_TA_response_analysis(int* dest_pit, int* dest_land, int len) {
      memset(dest_pit, 0, 4*len);
      memset(dest_land, 0, 4*len);
      return 0;
}

int build_TA_histogram_px716(unsigned char* response_data, int* dest_pit, int* dest_land, int len) {
      int* dest[] = { dest_land, dest_pit };
      int count = swap2(response_data+2);
//    printf("PX-716 Histogram... %d\n",count);
      int idx=28;
      int v, pit;
      for (int i=0;i<count;i++) {
            v = swap2u(response_data+idx);
            pit = !!(v & 0x8000);
            v &=~0x8000;
            dest[pit][min(v, len-1)]++;
            idx+=2;
      }
      return 0;
}

int build_TA_histogram_px755(unsigned char* response_data, int* dest_pit, int* dest_land, int len, int dt) { //, int spd) {
      int* dest[] = { dest_land, dest_pit };
      int count = swap2(response_data+2);
//    printf("PX-755+ Histogram... %d\n", count);
      int idx=28;
      int v, pit;
      for (int i=0;i<count;i++) {
            v = swap2u(response_data+idx);
            pit = !!(v & 0x8000);
            v &=~0x8000;
            if (dt & DISC_DVDplus)
                  dest[pit][min( (int)(v*1.45), len-1)]++; // DVD+R(W)
            else
                  dest[pit][min( (int)(v*1.21), len-1)]++; // DVD-R(W)
            idx+=2;
      }
      return 0;
}

int evaluate_histogramme(int* src_pit, int* src_land, int** peaks, int** mins) {
      int i, j1, j2;
      int local_max = 0;
      int next_peak = 0;
      int peak_found= 0;
      int* src[] = { src_pit, src_land };

      for (int k=0;k<2;k++) {
            j1=0; j2=0; local_max = 0;
            for (i=40;i<330;i++) {
                  if (src[k][i-1] <= src[k][i] && src[k][i+1] <= src[k][i] && src[k][i] > 20 && src[k][i] > local_max) {
                        peaks[k][j1] = i;
                        local_max = src[k][i];
                        next_peak = 1;
                  } else if (peak_found)
                  if (/*src[k][i-3] >= src[k][i-1] && src[k][i-2] > src[k][i-1] && */
                      src[k][i-1] > src[k][i] && src[k][i+1] >= src[k][i]) {
                        mins[k][j2] = i;
                        if (j2<13) j2++;
                        peak_found = 0;
                  }

                  if (local_max > 2*src[k][i]) {
                        local_max = 2*src[k][i];
                        if (next_peak) {
                              next_peak = 0;
                              if (j1<13) {
                                    j1++;
                                    peak_found=1;
                              //    printf("%4d",i);
                              }
                        }
                  }
            }

            int min_count = j2;
            for (i=0;i<min_count;i++) {
                  int start = (i?mins[k][i-1]:0);
                  int end   = mins[k][i];
                  int sum   = 0;
                  int partsum=0;
                  int j;
                  for (j=start;j<end;sum+=src[k][j++]);
                  for (j=start;partsum<sum/2;partsum+=src[k][j++]);
                  peaks[k][i] = (peaks[k][i] + j-1)/2;
            }
      }
      return 0;
}


int ScanThread::plextor_scan_TA () {
      char* TEST="DVD TA";
      post_signal(event_test_init,(void*)TEST);

      block_data block;
      block.test=TEST_DVD_TA;
      block.err_total=0; block.err_max=0; block.err_cur=0; block.err_avg=0.0;
      block.blocks = drive->media.capacity; block.idx=0;

      talayers = drive->media.layers;
      printf("Start PLEXTOR TA test on %d layers\n",drive->media.layers);
      int i, r, m,j;
      float sum;
      unsigned char scan_cmd[6][2] = {
            { 0x04, 0x00 }, { 0x10, 0x00 }, { 0x20, 0x00 },
            { 0xFA, 0x28 }, { 0xEA, 0x28 }, { 0xDE, 0x28 }};
      char* scan_txt[] = {
            "#running TA on L0 inner zone ", "#running TA on L0 middle zone", "#running TA on L0 outer zone ",
            "#running TA on L1 inner zone ", "#running TA on L1 middle zone", "#running TA on L1 outer zone "
      };
      int ta_response_pit[6][512]; int ta_response_land[6][512];
      int peaks_lands[15], peaks_pits[15]; int mins_lands[15], mins_pits[15];
      int* peaks[] = { peaks_pits, peaks_lands };
      int* mins[]  = { mins_pits+1, mins_lands+1 };


      wait_unit_ready(drive, time_out);
      for (int pass=0;(pass<3*drive->media.layers) && (!skip());pass++) {
            printf(scan_txt[pass]);
            init_TA_response_analysis(ta_response_pit[pass], ta_response_land[pass], 512);
            for (i=0;i<9;i++) {
                  drive->cmd_clear();
                  drive->cmd[0] = CMD_PLEX_SCAN_TA_FETE; // 0xF3;
                  drive->cmd[1] = 0x1F;
                  drive->cmd[2] = 0x23;
                  drive->cmd[3] = 0x00;
                  drive->cmd[4] = 0x00;
                  drive->cmd[5] = scan_cmd[pass][0];
                  drive->cmd[6] = scan_cmd[pass][1];
                  drive->cmd[7] = i<<4;
                  drive->cmd[8] = 0xFF;
                  drive->cmd[9] = 0xFE;
                  drive->cmd[10] = 0x04*!i;
                  drive->cmd[11] = 0x00;
                  drive->cmd.transport(READ, drive->rd_buf, 65534);
                  printf(".");
                  if (drive->dev_ID == PLEXTOR_716)
                        build_TA_histogram_px716(drive->rd_buf, ta_response_pit[pass], ta_response_land[pass], 512);
                  else
                        build_TA_histogram_px755(drive->rd_buf, ta_response_pit[pass], ta_response_land[pass], 512, drive->media.disc_type);
                        // drive->parms.scan_speed_dvd);
            }  //////
            printf("#\n");
            mins_lands[0] = 0; mins_pits[0]=0;

            int p0,p1;
            int l0,l1;
            for  (j=0;j<400;j++) {
                  block.block=pass;
                  block.idx=j;
                  if ((j>40) && (j<360)) {
                        p0=ta_response_pit[pass][j-1]; p1=ta_response_pit[pass][j+1];
                        l0=ta_response_land[pass][j-1]; l1=ta_response_land[pass][j+1];
                        if ( ta_response_pit[pass][j] == 0 )
                              if ((p0>0) && (p1>0)) ta_response_pit[pass][j] = (p0+p1)/2;
                        if ( ta_response_land[pass][j] == 0 )
                              if ((l0>0) && (l1>0)) ta_response_land[pass][j] = (l0+l1)/2;
                  }
                  block.pit=ta_response_pit[pass][j];
                  block.land=ta_response_land[pass][j];
                  event_block_done(event_block_done_ta, block);
            }

//          }  /////

            evaluate_histogramme(ta_response_pit[pass], ta_response_land[pass], peaks, mins);

            printf("#\n#  peak shift pits : ");
            sum=0;
            for (m=0;m<10;m++) {
                  r = (int)((float)peaks_pits[m] - 21.5454 * ((m<9)?m:11) - 64); sum+=sqrt(abs(r));
                  printf("%4d", r);
            }
            printf("# sum %f \n",sum);
            printf("#  peak shift lands: ");

            sum=0;
            for (m=0;m<10;m++) {
                  r = (int)((float)peaks_lands[m] - 21.5454 * ((m<9)?m:11) - 64); sum+=sqrt(abs(r));
                  printf("%4d", r);
            }
            printf("# sum %f \n",sum);
      }
      printf("TA test finished\n");
        plextor_end_scan(drive);
      return 0;
}

void ScanThread::run()
{
const char* DVD_ROM_TA = "** TA not supported DVD-ROM **";
const char* NO_TESTS = "** No media - No tests **";
// struct   timeval     start, finish;
// long     dur;
      reset_skip_flag();
      read_capacity(drive);
//    printf("\n== Starting tests...\n");
      if ( drive->media.disc_type & DISC_DVD ) {
//          printf("\n== Transfer rate...\n");
            if ((drive->parms.tests & TEST_RATE_RD) && (!skip())) {
                  rd_rate();
            }
//          printf("\n== Transfer rate done\n");
            printf("** scan speed: %dx\n",drive->parms.scan_speed_dvd);
            drive->parms.read_speed_kb = drive->parms.scan_speed_dvd*dvd1X;
            set_read_speed(drive);
            if ((drive->parms.tests & TEST_DVD_PIE) && (!skip())) {
//                if ((drive->ven_ID == WR_PLEXTOR))
//                      plextor_scan_pisum8();
//                else
//                      scan_pie_pif();
                  if (drive->chk_features & CHK_PIE)
                        scan_pie();
            }
            if ((drive->parms.tests & TEST_DVD_PIF) && (!skip())) {
//                if ((drive->ven_ID == WR_PLEXTOR))
                  if (drive->chk_features & CHK_PIF)
                        scan_pif();
            }
            if ((drive->parms.tests & TEST_DVD_JB) && (!skip())) {
                  if (drive->chk_features &  CHK_JB_DVD)
                        scan_jb_dvd();
            }
            if ((drive->parms.tests & TEST_DVD_TA) && (!skip())) {
                  if (drive->media.disc_type == DISC_DVDROM) {
                        post_signal(event_debug, (void*)DVD_ROM_TA);
                  } else {
                        if (drive->chk_features & CHK_TA) {
                              drive->parms.read_speed_kb = 2*dvd1X;
                              set_read_speed(drive);
                              plextor_scan_TA();
                        }
                  }
            }

            if ((drive->parms.tests & TEST_FETE) && (!skip())) {
//                drive->parms.read_speed_kb = -1;
//                set_read_speed(drive);
                  scan_fete();
            }
            drive->parms.read_speed_kb = drive->parms.read_speed_dvd*dvd1X;
            set_read_speed(drive);
      } else
      if ( drive->media.disc_type & DISC_CD )
      {
            if ((drive->parms.tests & TEST_RATE_RD) && (!skip())) {
                  rd_rate();
            }
            printf("** scan speed: %dx\n",drive->parms.scan_speed_cd);
            drive->parms.read_speed_kb = drive->parms.scan_speed_cd*(cd1Xraw+1);
            set_read_speed(drive);
            if ((drive->parms.tests & TEST_CD_CX) && (!skip())) {
                  if (drive->chk_features & CHK_CX)
                        scan_cx();
            }
            if ((drive->parms.tests & TEST_CD_JB) && (!skip())) {
                  if (drive->chk_features & CHK_JB_CD)
                        scan_jb_cd();
            }
            drive->parms.read_speed_kb = drive->parms.read_speed_cd*(cd1Xraw+1);
            set_read_speed(drive);

            if ((drive->parms.tests & TEST_FETE) && (!skip())) {
//                drive->parms.read_speed_kb = -1;
//                set_read_speed(drive);
                  scan_fete();
            }
      } else {
            post_signal(event_debug,(void*)NO_TESTS);
      }
      if (skip())
            post_signal(event_tests_aborted, NULL);
      else
            post_signal(event_all_tests_done, NULL);
      reset_skip_flag();
      return;
}

#ifndef __USE_QTHREAD

ScanThread* THREAD;

void *scan(void* arg)
{
      THREAD = (ScanThread*)arg;
      THREAD->run();
}
#endif

void ScanTimer::run() {
      while (1) {
            msleep(250);
            post_signal(event_1sec);
      }
}

Generated by  Doxygen 1.6.0   Back to index