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 <string.h>
#include <sys/time.h>

#include <common_functions.h>
#include <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 "qpx_const.h"

//#define __EVERY_BLOCK_EVENT_TR  1 // MORE CPU usage while Transfer Rate
                              // especially on DVD, don't use on slow CPU
// #define __EVERY_BLOCK_EVENT_PI  1      // MORE CPU usage while DVD Pi/Po scan

#define block_dvd 16
#define block_cd  25

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;

      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);
            SpinUpDVD(drive);
            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;
#ifdef __EVERY_BLOCK_EVENT_TR
                        event_block_done(event_show_lba, block);
                  }
#else 
                  }
                  event_block_done(event_show_lba, block);
#endif
                  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)\n",
                        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) {
            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);
            SpinUpCD(drive);
            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<(hscaleCD/block_cd); ii++) {
//                      read_cd(drive, lba, 15);
                        read(drive, block.lba, block_cd);
                        block.lba+=block_cd;
#ifdef __EVERY_BLOCK_EVENT_TR
                        event_block_done(event_show_lba, block);
                  }
#else 
                  }
                  event_block_done(event_show_lba, block);
#endif
                  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)\n",
                        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);
            }
      }
      return 0;
}

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

      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.blocks = drive->media.capacity; block.idx=0;

      int BLER, block_BLER=0, total_BLER=0, max_BLER=0; // float avg_BLER=0.0;
      int E11,  block_E11=0,  total_E11=0,  max_E11=0;  // float avg_E11=0.0;
      int E21,  block_E21=0,  total_E21=0,  max_E21=0;  // float avg_E21=0.0;
      int E31,  block_E31=0,  total_E31=0,  max_E31=0;  // float avg_E31=0.0;
      int E12,  block_E12=0,  total_E12=0,  max_E12=0;  // float avg_E12=0.0;
      int E22,  block_E22=0,  total_E22=0,  max_E22=0;  // float avg_E22=0.0;
      int E32,  block_E32=0,  total_E32=0,  max_E32=0;  // float avg_E32=0.0;
      int oldidx=0;
      int seconds;
      seconds = drive->media.capacity/75+!!(drive->media.capacity%75);
      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;
            }
      } else {
            printf("CX scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return;
      }
      if ((drive->ven_ID == WR_PLEXTOR)) block.ext=1; else block.ext=0;
      printf("Running %s CD scan\n\n",block.ext ? "Extended" : "Standart");
      gettimeofday(&start, NULL);
      for (block.lba=0;(block.lba<drive->media.capacity) && (!skip());)
      {
            block_BLER=0; block_E11=0; block_E21=0; block_E31=0; block_E12=0; block_E22=0; block_E32=0;

            for (int i=0;(i<128) && (block.idx == oldidx) && (block.lba<drive->media.capacity);i++) {
                  scan_tbl[drive->ven_ID].cx_one_interval(drive, &block.lba, &BLER, &E11, &E21, &E31, &E12, &E22, &E32);
//                block.idx = max(0, block.lba/hscaleCD - 1);
                  block.idx = block.lba/hscaleCD;
//                block.lba+=75;

                  total_BLER += BLER; block_BLER = max(BLER, block_BLER); max_BLER = max(max_BLER, BLER);
                  total_E11 += E11; block_E11 = max(E11, block_E11); max_E11 = max(max_E11, E11);
                  total_E21 += E21; block_E21 = max(E21, block_E21); max_E21 = max(max_E21, E21);
                  total_E31 += E31; block_E31 = max(E31, block_E31); max_E31 = max(max_E31, E31);
                  total_E12 += E12; block_E12 = max(E12, block_E12); max_E12 = max(max_E12, E12);
                  total_E22 += E22; block_E22 = max(E22, block_E22); max_E22 = max(max_E22, E22);
                  total_E32 += E32; block_E32 = max(E32, block_E32); max_E32 = max(max_E32, E32);
            }
            if (block.idx > (hres-1)) block.idx = oldidx+1;
            block.idx--;
//          if (block.idx<0) block.idx
            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_BLER, block_E11, block_E21, block_E31, block_E12, block_E22, block_E32);
            else
                  printf(" %4d C1,%4d C2,%4d CU\n", block_BLER, block_E22, block_E32);
            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_BLER;
            block.err_avg = (int)(total_BLER*100.0/(block.block/75))/100.0;
            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_E11;
                  block.err_avg = (int)(total_E11*100.0/(block.block/75))/100.0;
                  event_block_done(event_block_done_E11, block);

                  block.err_total = total_E21; block.err_max = max_E21; block.err_cur = block_E21;
                  block.err_avg = (int)(total_E21*100.0/(block.block/75))/100.0;
                  event_block_done(event_block_done_E21, block);

                  block.err_total = total_E31; block.err_max = max_E31; block.err_cur = block_E31;
                  block.err_avg = (int)(total_E31*100.0/(block.block/75))/100.0;
                  event_block_done(event_block_done_E31, block);

                  block.err_total = total_E12; block.err_max = max_E12; block.err_cur = block_E12;
                  block.err_avg = (int)(total_E12*100.0/(block.block/75))/100.0;
                  event_block_done(event_block_done_E12, block);
            }

            block.err_total = total_E22; block.err_max = max_E22; block.err_cur = block_E22;
            block.err_avg = (int)(total_E22*100.0/(block.block/75))/100.0;
            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_E32;
            block.err_avg = (int)(total_E32*100.0/(block.block/75))/100.0;
            event_block_done(event_block_done_cupof, block);
            if (block.ext) event_block_done(event_block_done_E32, block);

            block.idx++;
            oldidx = block.idx;
      }
      if (scan_tbl[drive->ven_ID].cx_end)
            (scan_tbl[drive->ven_ID].cx_end)(drive);       // *****

// Send info about last block

      block.err_total = total_BLER; block.err_max = max_BLER; block.err_cur = block_BLER;
      block.err_avg = (int)(total_BLER*100.0/(block.block/75))/100.0;
      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_E11;
            block.err_avg = (int)(total_E11*100.0/(block.block/75))/100.0;
            event_block_done(event_block_done_E11, block);

            block.err_total = total_E21; block.err_max = max_E21; block.err_cur = block_E21;
            block.err_avg = (int)(total_E21*100.0/(block.block/75))/100.0;
            event_block_done(event_block_done_E21, block);

            block.err_total = total_E31; block.err_max = max_E31; block.err_cur = block_E31;
            block.err_avg = (int)(total_E31*100.0/(block.block/75))/100.0;
            event_block_done(event_block_done_E31, block);

            block.err_total = total_E12; block.err_max = max_E12; block.err_cur = block_E12;
            block.err_avg = (int)(total_E12*100.0/(block.block/75))/100.0;
            event_block_done(event_block_done_E12, block);
      }

      block.err_total = total_E22; block.err_max = max_E22; block.err_cur = block_E22;
      block.err_avg = (int)(total_E22*100.0/(block.block/75))/100.0;
      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_E32;
      block.err_avg = (int)(total_E32*100.0/(block.block/75))/100.0;
      event_block_done(event_block_done_cupof, block);
      if (block.ext) event_block_done(event_block_done_E32, block);
}

void 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;
      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;
            }
      } else {
            printf("\nCD J/B scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return;
      }
      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;
                        b_max = beta;
                        b_min = beta;
                        jo = jitter;
                        j_max=jitter;
                        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("\rLBA: %06X  jitter: %4d,  beta: %4d", 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");
      scan_tbl[drive->ven_ID].jb_cd_end(drive);
//    drive->unlock();
}

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

      block_data block;
      block.test=TEST_DVD_PIE;
      block.err_total=0; block.err_max=0; block.err_cur=0; block.err_avg=0.0;
      block.lba = 0;
      block.blocks = drive->media.capacity;
      int   oldidx=0;
      int   intervals,i;
      int   current = 0;
      int   broken_count = 0;
      intervals = drive->media.capacity/hscale;
      if (scan_tbl[drive->ven_ID].pie_start) {
            printf("\n** Starting %s PIE sum8 scan...\n",vendor[drive->ven_ID]);
            drive->err = (scan_tbl[drive->ven_ID].pie_start)(drive);
            if (drive->err) {
                  printf("Error initializing test!\n");
                  return;
            }
      } else {
            printf("PIE scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return;
      }
      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_cur = 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;
                  scan_tbl[drive->ven_ID].pie_8_ecc_blocks(drive, &block.lba, &current);
                  block.idx = block.lba / hscale;
//          printf("block.lba = %d; block.idx = %d\n",block.lba,block.idx);
                  event_block_done(event_show_lba, block);
                  block.err_total += current;
                  block.err_cur = max (block.err_cur, current);
                  if (block.err_cur > 280) broken_count++;

                  block.err_max = max (block.err_cur, block.err_max);
                  block.err_avg=(int)(block.err_total*100.0/((block.block+(i+1)*128) >> 7))/100.0;
#ifndef __EVERY_BLOCK_EVENT_PI
            }
#endif
            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--;
            event_block_done(event_block_done_c1pie, block);
            block.idx++;
#ifdef __EVERY_BLOCK_EVENT_PI
            }
#endif
            printf("\rpos: %d / %d, max: %d, curr: %d, total: %d", block.idx*hscale+i*128,
                  drive->media.capacity, block.err_max, block.err_cur, block.err_total);
            printf("\n");
      }
      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
      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();
};

void 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;

      block_data block;
      block.test=TEST_DVD_PIF;
      block.err_total=0; block.err_max=0; block.err_cur=0; block.err_avg=0.0;
      block.lba = 0;
      block.blocks = drive->media.capacity;
      int   oldidx=0;
      int   current = 0;
      int         intervals,i;
      int   broken_count = 0;
      intervals = drive->media.capacity/hscale;
      if (scan_tbl[drive->ven_ID].pif_start) {
            printf("\n** Starting %s PIF 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;
            }
      } else {
            printf("PIF scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return;
      }
      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_cur = 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_tbl[drive->ven_ID].pif_1_ecc_block(drive, &block.lba, &current);
                  block.idx = block.lba / hscale;
//          printf("block.lba = %d; block.idx = %d\n",block.lba,block.idx);
                  event_block_done(event_show_lba, block);
                  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);
                  block.err_avg=(int)(block.err_total*100.0/((block.block+(i+1)*16) >> 4))/100.0;
#ifndef __EVERY_BLOCK_EVENT_PI
            }
#endif
            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--;
            event_block_done(event_block_done_c2pif, block);
            block.idx++;
#ifdef __EVERY_BLOCK_EVENT_PI
            }
#endif
            printf("\rpos: %d / %d, max: %d, curr: %d, total: %d", block.idx*hscale+i*16,
                  block.blocks, block.err_max, block.err_cur, block.err_total);
            printf("\n");
      }
      scan_tbl[drive->ven_ID].pif_end(drive);

#ifdef DEBUG
      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();
}

void 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;
      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;
            }
      } else {
            printf("DVD J/B scan not implemented on %s drives!\n",vendor[drive->ven_ID]);
            return;
      }
      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;
                        b_max = beta;
                        b_min = beta;
                        jo = jitter;
                        j_max=jitter;
                        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();
}

void 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;
      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\n",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("\nSend FE/TE end command...\n");
      plextor_end_fete(drive);
}

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

Generated by  Doxygen 1.6.0   Back to index