예제 #1
0
파일: fill.cpp 프로젝트: adam-nielsen/xlnt
fill fill::pattern(pattern_fill::type pattern_type)
{
    fill f;
    f.type_ = type::pattern;
    f.pattern_ = pattern_fill(pattern_type);
    return f;
}
예제 #2
0
void game_init(){
	int8u no;
	int8u count;
	
	display_off();
	pattern_fill(0x3800, 0, (BG_HIGH + BG_PAL1 + BG_TOP), 32 * 28 * 2);

	actors_clear();

	scene_wait = 0;
	player_create(0);
	alive_players = 1;
	smoke_wait = 0;
	scene_type = SCENE_GAME_PLAYING;

	vram_store(0x3000, fopen("bmp/font.ptn"), 0x0800);

	/*  load pattern */
	switch(stage){
	case 0:
		vram_store(0x2000, fopen("bmp/castle.ptn"), 0x1000);
		vram_store(0x0000, fopen("bmp/sp_castle.ptn"), 0x2000);
		break;
	case 1:
		vram_store(0x2000, fopen("bmp/summer.ptn"), 0x1000);
		vram_store(0x0000, fopen("bmp/sp_summer.ptn"), 0x2000);
		break;
	case 2:
		vram_store(0x2000, fopen("bmp/jungle.ptn"), 0x1000);
		vram_store(0x0000, fopen("bmp/sp_castle.ptn"), 0x2000);
		break;
	default:
		vram_store(0x2000, fopen("bmp/winter.ptn"), 0x1000);
		vram_store(0x0000, fopen("bmp/sp_castle.ptn"), 0x2000);
		break;
	}
	
	/* load palette */
	load_palette(stage, 0);

	/* set enemy */
	enemies_rotation_count = level << 3;
	for(count = stage; count != 0; count--){
		/* 8 charactors * 3 levels * stage 2 */
		enemies_rotation_count += 8 * 3;
	}
	enemies_rotation_limit = enemies_rotation_count + 8;

	enemies_count = ACTORS_INITINAL_COUNT;
	enemies_alive = 0;
	enemies_left = 6 + stage;
	for(count = 0; count < enemies_count; count++){
		no = actors_get_null();
		actor_create_random(no);
	}

	display_on();
}
예제 #3
0
/* ----------------------------------------------------------------------------------- */
void gameover_main(char *message){
	int8u c;

	display_off();

	palette_store( 0, fopen("bmp/title.pal"), 16);
	palette_store(16, fopen("bmp/sp_castle.pal"), 16);

	vram_store(0x0000, fopen("bmp/sp_castle.ptn"), 0x2000);
	vram_store(0x2000, fopen("bmp/title.ptn"), 0x1000);
	vram_store(0x3000, fopen("bmp/font.ptn"), 0x800);
	pattern_fill(0x3800, 0, BG_HIGH, 32 * 24 * 2);

	print_init();
	store_pattern_name_buffer(10);
	print(message, 10);
	store_pattern_name_buffer(9);

	print("1P SCORE XXXX0 ", 8);
	pattern_name_buffer[17 << 1] = VRAM_NUMBER + score_ints[3];
	pattern_name_buffer[18 << 1] = VRAM_NUMBER + score_ints[2];
	pattern_name_buffer[19 << 1] = VRAM_NUMBER + score_ints[1];
	pattern_name_buffer[20 << 1] = VRAM_NUMBER + score_ints[0];
	store_pattern_name_buffer(11);

	if(players_count == 2){
		print("2P SCORE XXXX0 ", 8);
		pattern_name_buffer[17 << 1] = VRAM_NUMBER + score_ints[7];
		pattern_name_buffer[18 << 1] = VRAM_NUMBER + score_ints[6];
		pattern_name_buffer[19 << 1] = VRAM_NUMBER + score_ints[5];
		pattern_name_buffer[20 << 1] = VRAM_NUMBER + score_ints[4];
		store_pattern_name_buffer(13);
	}

	actors_clear();
	scroll_y = 0;
	print_init();
	display_on();
	psg_set_bgm(fopen("sound/over.sn7"), FALSE);
	
	for(c = 6; c != 0; c--){
		for(frame_count = 0; frame_count < 60; frame_count++){
			sprites_clear();
			vsync_wait();
			sprites_store();
			scroll_store();
			psg_play();
		}
	}
	psg_stop();
}
예제 #4
0
파일: badblocks.c 프로젝트: hanji/rufus
static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size, blk_t first_block,
	size_t blocks_at_once, int nb_passes)
{
	unsigned char *buffer = NULL, *read_buffer;
	const unsigned int pattern[] = {0xaa, 0x55, 0xff, 0x00};
	int i, pat_idx;
	unsigned int bb_count = 0;
	blk_t got, tryout, recover_block = ~0, *blk_id;
	size_t id_offset;

	if ((nb_passes < 1) || (nb_passes > 4)) {
		uprintf("%sInvalid number of passes\n", bb_prefix);
		cancel_ops = -1;
		return 0;
	}

	buffer = allocate_buffer(2 * blocks_at_once * block_size);
	read_buffer = buffer + blocks_at_once * block_size;

	if (!buffer) {
		uprintf("%sError while allocating buffers\n", bb_prefix);
		cancel_ops = -1;
		return 0;
	}

	uprintf("%sChecking from block %lu to %lu\n", bb_prefix,
		(unsigned long) first_block, (unsigned long) last_block - 1);
	nr_pattern = nb_passes;
	cur_pattern = 0;

	for (pat_idx = 0; pat_idx < nb_passes; pat_idx++) {
		if (cancel_ops) goto out;
		srand((unsigned int)GetTickCount());
		id_offset = rand()* (block_size-sizeof(blk_t)) / RAND_MAX;
		pattern_fill(buffer, pattern[pat_idx], blocks_at_once * block_size);
		uprintf("%sBlock ID at offset: %d\n", bb_prefix, id_offset);
		num_blocks = last_block - 1;
		currently_testing = first_block;
		if (s_flag | v_flag)
			uprintf("%sWriting test pattern 0x%02X\n", bb_prefix, pattern[pat_idx]);
		cur_op = OP_WRITE;
		tryout = blocks_at_once;
		while (currently_testing < last_block) {
			if (cancel_ops) goto out;
			if (max_bb && bb_count >= max_bb) {
				if (s_flag || v_flag) {
					uprintf(abort_msg);
					fprintf(log_fd, abort_msg);
					fflush(log_fd);
				}
				cancel_ops = -1;
				goto out;
			}
			if (currently_testing + tryout > last_block)
				tryout = last_block - currently_testing;
			if (detect_fakes) {
				/* Add the block number at a fixed (random) offset during each pass to
				   allow for the detection of 'fake' media (eg. 2GB USB masquerading as 16GB) */
				for (i=0; i<(int)blocks_at_once; i++) {
					blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size);
					*blk_id = (blk_t)(currently_testing + i);
				}
			}
			got = do_write(hDrive, buffer, tryout, block_size, currently_testing);
			if (v_flag > 1)
				print_status();

			if (got == 0 && tryout == 1)
				bb_count += bb_output(currently_testing++, WRITE_ERROR);
			currently_testing += got;
			if (got != tryout) {
				tryout = 1;
				if (recover_block == ~0)
					recover_block = currently_testing -
						got + blocks_at_once;
				continue;
			} else if (currently_testing == recover_block) {
				tryout = blocks_at_once;
				recover_block = ~0;
			}
		}

		num_blocks = 0;
		if (s_flag | v_flag)
			uprintf("%sReading and comparing\n", bb_prefix);
		cur_op = OP_READ;
		num_blocks = last_block;
		currently_testing = first_block;

		tryout = blocks_at_once;
		while (currently_testing < last_block) {
			if (cancel_ops) goto out;
			if (max_bb && bb_count >= max_bb) {
				if (s_flag || v_flag) {
					uprintf(abort_msg);
					fprintf(log_fd, abort_msg);
					fflush(log_fd);
				}
				cancel_ops = -1;
				goto out;
			}
			if (currently_testing + tryout > last_block)
				tryout = last_block - currently_testing;
			if (detect_fakes) {
				for (i=0; i<(int)blocks_at_once; i++) {
					blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size);
					*blk_id = (blk_t)(currently_testing + i);
				}
			}
			got = do_read(hDrive, read_buffer, tryout, block_size,
				       currently_testing);
			if (got == 0 && tryout == 1)
				bb_count += bb_output(currently_testing++, READ_ERROR);
			currently_testing += got;
			if (got != tryout) {
				tryout = 1;
				if (recover_block == ~0)
					recover_block = currently_testing -
						got + blocks_at_once;
				continue;
			} else if (currently_testing == recover_block) {
				tryout = blocks_at_once;
				recover_block = ~0;
			}
			for (i=0; i < got; i++) {
				if (memcmp(read_buffer + i * block_size,
					   buffer + i * block_size,
					   block_size))
					bb_count += bb_output(currently_testing+i-got, CORRUPTION_ERROR);
			}
			if (v_flag > 1)
				print_status();
		}

		num_blocks = 0;
	}
out:
	free_buffer(buffer);
	return bb_count;
}
예제 #5
0
static void general_test (NANDDriver *nandp, size_t first,
                                      size_t last, size_t read_rounds){

  size_t block, page, round;
  bool status;
  uint8_t op_status;
  uint32_t recc, wecc;

  red_led_on();

  /* initialize time measurement units */
  chTMObjectInit(&tmu_erase);
  chTMObjectInit(&tmu_write_data);
  chTMObjectInit(&tmu_write_spare);
  chTMObjectInit(&tmu_read_data);
  chTMObjectInit(&tmu_read_spare);

  /* perform basic checks */
  for (block=first; block<last; block++){
    if (!nandIsBad(nandp, block)){
      if (!is_erased(nandp, block)){
        op_status = nandErase(nandp, block);
        osalDbgCheck(0 == (op_status & 1)); /* operation failed */
      }
    }
  }

  /* write block with pattern, read it back and compare */
  for (block=first; block<last; block++){
    if (!nandIsBad(nandp, block)){
      for (page=0; page<nandp->config->pages_per_block; page++){
        pattern_fill();

        chTMStartMeasurementX(&tmu_write_data);
        op_status = nandWritePageData(nandp, block, page,
                      nand_buf, nandp->config->page_data_size, &wecc);
        chTMStopMeasurementX(&tmu_write_data);
        osalDbgCheck(0 == (op_status & 1)); /* operation failed */

        chTMStartMeasurementX(&tmu_write_spare);
        op_status = nandWritePageSpare(nandp, block, page,
                      nand_buf + nandp->config->page_data_size,
                      nandp->config->page_spare_size);
        chTMStopMeasurementX(&tmu_write_spare);
        osalDbgCheck(0 == (op_status & 1)); /* operation failed */

        /* read back and compare */
        for (round=0; round<read_rounds; round++){
          memset(nand_buf, 0, NAND_PAGE_SIZE);

          chTMStartMeasurementX(&tmu_read_data);
          nandReadPageData(nandp, block, page,
                      nand_buf, nandp->config->page_data_size, &recc);
          chTMStopMeasurementX(&tmu_read_data);
          osalDbgCheck(0 == (recc ^ wecc)); /* ECC error detected */

          chTMStartMeasurementX(&tmu_read_spare);
          nandReadPageSpare(nandp, block, page,
                      nand_buf + nandp->config->page_data_size,
                      nandp->config->page_spare_size);
          chTMStopMeasurementX(&tmu_read_spare);

          osalDbgCheck(0 == memcmp(ref_buf, nand_buf, NAND_PAGE_SIZE)); /* Read back failed */
        }
      }

      /* make clean */
      chTMStartMeasurementX(&tmu_erase);
      op_status = nandErase(nandp, block);
      chTMStopMeasurementX(&tmu_erase);
      osalDbgCheck(0 == (op_status & 1)); /* operation failed */

      status = is_erased(nandp, block);
      osalDbgCheck(true == status); /* blocks was not erased successfully */
    }/* if (!nandIsBad(nandp, block)){ */
  }
  red_led_off();
}
예제 #6
0
static void ecc_test(NANDDriver *nandp, uint32_t block){

  uint32_t corrupted;
  uint32_t byte, bit;
  const uint32_t ecclen = 28;
  uint32_t ecc_ref, ecc_broken;
  uint8_t op_status;
  ecc_result_t ecc_result = ECC_NO_ERROR;

  /* This test requires good block.*/
  osalDbgCheck(!nandIsBad(nandp, block));
  if (!is_erased(nandp, block))
    nandErase(&NAND, block);

  pattern_fill();

  /*** Correctable errors ***/
  op_status = nandWritePageData(nandp, block, 0,
                nand_buf, nandp->config->page_data_size, &ecc_ref);
  osalDbgCheck(0 == (op_status & 1)); /* operation failed */
  nandReadPageData(nandp, block, 0,
                  nand_buf, nandp->config->page_data_size, &ecc_broken);
  ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted);
  osalDbgCheck(ECC_NO_ERROR == ecc_result); /* unexpected error */

  /**/
  byte = 0;
  bit = 7;
  invert_bit(nand_buf, byte, bit);
  op_status = nandWritePageData(nandp, block, 1,
                nand_buf, nandp->config->page_data_size, &ecc_broken);
  osalDbgCheck(0 == (op_status & 1)); /* operation failed */
  invert_bit(nand_buf, byte, bit);
  ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted);
  osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */
  osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */

  /**/
  byte = 2047;
  bit = 0;
  invert_bit(nand_buf, byte, bit);
  op_status = nandWritePageData(nandp, block, 2,
                nand_buf, nandp->config->page_data_size, &ecc_broken);
  osalDbgCheck(0 == (op_status & 1)); /* operation failed */
  invert_bit(nand_buf, byte, bit);
  ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted);
  osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */
  osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */

  /**/
  byte = 1027;
  bit = 3;
  invert_bit(nand_buf, byte, bit);
  op_status = nandWritePageData(nandp, block, 3,
                nand_buf, nandp->config->page_data_size, &ecc_broken);
  osalDbgCheck(0 == (op_status & 1)); /* operation failed */
  invert_bit(nand_buf, byte, bit);
  ecc_result = parse_ecc(ecclen, ecc_ref, ecc_broken, &corrupted);
  osalDbgCheck(ECC_CORRECTABLE_ERROR == ecc_result); /* this error must be correctable */
  osalDbgCheck(corrupted == (byte * 8 + bit)); /* wrong correction code */

  /*** Uncorrectable error ***/
  byte = 1027;
  invert_bit(nand_buf, byte, 3);
  invert_bit(nand_buf, byte, 4);
  op_status = nandWritePageData(nandp, block, 4,
                nand_buf, nandp->config->page_data_size, &ecc_broken);
  osalDbgCheck(0 == (op_status & 1)); /* operation failed */
  invert_bit(nand_buf, byte, 3);
  invert_bit(nand_buf, byte, 4);
  ecc_result = parse_ecc(28, ecc_ref, ecc_broken, &corrupted);
  osalDbgCheck(ECC_UNCORRECTABLE_ERROR == ecc_result); /* This error must be NOT correctable */

  /*** make clean ***/
  nandErase(&NAND, block);
}
예제 #7
0
msg_t EepromTestThread(void *sdp){
  chRegSetThreadName("EepromTst");

  cli_println("basic tests");
  cli_println("--------------------------------------------------------------");
  cli_print("mount aligned file sized to whole test area");
  ocfg.barrier_low  = TEST_AREA_START;
  ocfg.barrier_hi   = TEST_AREA_END;
  EepromFileOpen(&ofile, &ocfg);
  OK();
  printfileinfo(sdp, &ofile);
  cli_print("test fill with 0xFF");
  pattern_fill(&ofile, 0xFF);
  if (chThdShouldTerminate()){goto END;}
  OK();
  cli_print("test fill with 0xAA");
  pattern_fill(&ofile, 0xAA);
  if (chThdShouldTerminate()){goto END;}
  OK();
  cli_print("test fill with 0x55");
  pattern_fill(&ofile, 0x55);
  if (chThdShouldTerminate()){goto END;}
  OK();
  cli_print("test fill with 0x00");
  pattern_fill(&ofile, 0x00);
  if (chThdShouldTerminate()){goto END;}
  OK();
  cli_print("Closing file");
  chFileStreamClose(&ofile);
  OK();


  uint32_t b1, b2, b3, b4, istart, ilen;
  uint8_t pattern = 0x55;
  b1 = TEST_AREA_START;
  b2 = TEST_AREA_START + EEPROM_PAGE_SIZE;
  b3 = TEST_AREA_END - EEPROM_PAGE_SIZE;
  b4 = TEST_AREA_END;
  istart = 0;
  ilen = b3-b2;

  cli_println("    Linear barriers testing.");
  chThdSleepMilliseconds(20);
  overflow_check( b1, b2, b3, b4, istart, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2, b3, b4, istart + 1, ilen - 1, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2, b3, b4, istart + 1, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2, b3, b4, istart + 1, ilen + 23, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 - 1, b3 + 1, b4, istart, ilen, pattern,  FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 - 2, b3 + 2, b4, istart + 2, ilen, pattern,  FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 - 1, b3 + 1, b4, istart + 1, ilen + 23, pattern,  FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 - 2, b3 + 2, b4, istart + 1, ilen + 23, pattern,  FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 + 2, b3 - 3, b4, istart + 2, ilen, pattern, FALSE,  sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;


  overflow_check( b1, b2, b2 + 1, b4, istart, ilen, pattern,  FALSE,  sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2, b2 + 2, b4, istart, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2, b2 + 3, b4, istart, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;


  overflow_check( b1, b2 + 1, b2 + 2, b4, istart, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 + 1, b2 + 3, b4, istart, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 + 1, b2 + 4, b4, istart, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;

  overflow_check( b1, b2 - 1, b2,     b4, istart, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 - 1, b2 + 1, b4, istart, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 - 1, b2 + 2, b4, istart, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;

  overflow_check( b1, b2 - 1, b2 + 1, b4, istart + 1, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 - 1, b2 + 2, b4, istart + 1, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;
  overflow_check( b1, b2 - 1, b2 + 3, b4, istart + 1, ilen, pattern, FALSE, sdp);
  if (chThdShouldTerminate()){goto END;}
  pattern++;

  cli_println("    Basic API testing.");
  chThdSleepMilliseconds(20);

  ocfg.barrier_low  = TEST_AREA_START;
  ocfg.barrier_hi   = TEST_AREA_END;
  EepromFileOpen(&ofile, &ocfg);
  chFileStreamSeek(&ofile, 0);
  EepromWriteByte(&ofile, 0x11);
  EepromWriteHalfword(&ofile, 0x2222);
  EepromWriteWord(&ofile, 0x33333333);
  chFileStreamSeek(&ofile, 0);
  if(EepromReadByte(&ofile) != 0x11)
    chDbgPanic("");
  if(EepromReadHalfword(&ofile) != 0x2222)
    chDbgPanic("");
  if(EepromReadWord(&ofile) != 0x33333333)
    chDbgPanic("");
  chFileStreamClose(&ofile);
  OK();

  cli_println("All tests passed successfully.");
END:
  chThdExit(0);
  return 0;
}
예제 #8
0
/**
 * Create overlapped files like this:
 *
 *       |<--------- outer file ------------>|
 *       |                                   |
 * ======b1==b2========================b3===b4======
 * |         |                          |          |
 * |         |<------ inner file ------>|          |
 * |<----------------- EEPROM -------------------->|
 */
static void overflow_check(uint32_t b1, uint32_t b2, uint32_t b3, uint32_t b4,
                          uint32_t istart, uint32_t ilen,
                          uint8_t pattern, bool_t pat_autoinc,
                          BaseSequentialStream *sdp){
  uint32_t status, i, n;

  chDbgCheck(ilen < (b4-b1),"sequences more than length of outer file can not be verified");

  chprintf(sdp, "b1=%u, b2=%u, b3=%u, b4=%u, istart=%u, ilen=%u, ",
            b1, b2, b3, b4, istart, ilen);
  cli_print("autoinc=");
  if (pat_autoinc)    cli_print("TRUE");
  else                cli_print("FALSE");
  chThdSleepMilliseconds(50);

  /* open outer file and clear it */
  ocfg.barrier_low  = b1;
  ocfg.barrier_hi   = b4;
  EepromFileOpen(&ofile, &ocfg);
  pattern_fill(&ofile, 0x00);

  /* open inner file */
  icfg.barrier_low  = b2;
  icfg.barrier_hi   = b3;
  EepromFileOpen(&ifile, &icfg);

  /* reference buffer */
  memset(referencebuf, 0x00, b4-b1);
  n = b2 - b1 + istart;
  if ((ilen + istart) > (b3-b2))
    i = b3 - b2 - istart;
  else
    i = ilen;
  while (i > 0){
    referencebuf[n] = pattern;
    n++;
    i--;
    if (pat_autoinc)
      pattern++;
    }

  /* check buffer */
  n = 0;
  while (n < ilen){
    checkbuf[n] = pattern;
    n++;
    if (pat_autoinc)
      pattern++;
  }

  /* now write check buffer content into inner file */
  chThdSleepMilliseconds(20);
  chFileStreamSeek(&ifile, istart);
  status = chFileStreamWrite(&ifile, checkbuf, ilen);

  if ((istart + ilen) > (b3 - b2)){ /* data must be clamped */
    if (status != (b3 - b2 - istart))
      chDbgPanic("not all data written or overflow ocrred");
  }
  else{/* data fitted in file */
    if (status != ilen)
      chDbgPanic("not all data written or overflow ocrred");
  }

  /* read outer file and compare content with reference buffer */
  memset(checkbuf, 0x00, b4-b1);
  chFileStreamSeek(&ofile, 0);
  status = chFileStreamRead(&ofile, checkbuf, b4-b1);
  if (status != (b4-b1))
    chDbgPanic("reading back failed");
  if (memcmp(referencebuf, checkbuf, b4-b1) != 0)
    chDbgPanic("veryfication failed");

  chFileStreamClose(&ofile);
  chFileStreamClose(&ifile);
  OK();
}
예제 #9
0
static unsigned int test_rw(HANDLE hDrive, blk64_t last_block, size_t block_size, blk64_t first_block,
							size_t blocks_at_once, int pattern_type, int nb_passes)
{
	const unsigned int pattern[BADLOCKS_PATTERN_TYPES][BADBLOCK_PATTERN_COUNT] =
		{ BADBLOCK_PATTERN_SLC, BADCLOCK_PATTERN_MLC, BADBLOCK_PATTERN_TLC };
	unsigned char *buffer = NULL, *read_buffer;
	int i, pat_idx;
	unsigned int bb_count = 0;
	blk64_t got, tryout, recover_block = ~0, *blk_id;
	size_t id_offset = 0;

	if ((pattern_type < 0) || (pattern_type >= BADLOCKS_PATTERN_TYPES)) {
		uprintf("%sInvalid pattern type\n", bb_prefix);
		cancel_ops = -1;
		return 0;
	}
	if ((nb_passes < 1) || (nb_passes > BADBLOCK_PATTERN_COUNT)) {
		uprintf("%sInvalid number of passes\n", bb_prefix);
		cancel_ops = -1;
		return 0;
	}

	buffer = allocate_buffer(2 * blocks_at_once * block_size);
	read_buffer = buffer + blocks_at_once * block_size;

	if (!buffer) {
		uprintf("%sError while allocating buffers\n", bb_prefix);
		cancel_ops = -1;
		return 0;
	}

	uprintf("%sChecking from block %lu to %lu (1 block = %s)\n", bb_prefix,
		(unsigned long) first_block, (unsigned long) last_block - 1,
		SizeToHumanReadable(BADBLOCK_BLOCK_SIZE, FALSE, FALSE));
	nr_pattern = nb_passes;
	cur_pattern = 0;

	for (pat_idx = 0; pat_idx < nb_passes; pat_idx++) {
		if (cancel_ops)
			goto out;
		if (detect_fakes && (pat_idx == 0)) {
			srand((unsigned int)GetTickCount64());
			id_offset = rand() * (block_size - sizeof(blk64_t)) / RAND_MAX;
			uprintf("%sUsing offset %d for fake device check\n", bb_prefix, id_offset);
		}
		// coverity[dont_call]
		pattern_fill(buffer, pattern[pattern_type][pat_idx], blocks_at_once * block_size);
		num_blocks = last_block - 1;
		currently_testing = first_block;
		if (s_flag | v_flag)
			uprintf("%sWriting test pattern 0x%02X\n", bb_prefix, pattern[pattern_type][pat_idx]);
		cur_op = OP_WRITE;
		tryout = blocks_at_once;
		while (currently_testing < last_block) {
			if (cancel_ops)
				goto out;
			if (max_bb && bb_count >= max_bb) {
				if (s_flag || v_flag) {
					uprintf(abort_msg);
					fprintf(log_fd, abort_msg);
					fflush(log_fd);
				}
				cancel_ops = -1;
				goto out;
			}
			if (currently_testing + tryout > last_block)
				tryout = last_block - currently_testing;
			if (detect_fakes && (pat_idx == 0)) {
				/* Add the block number at a fixed (random) offset during each pass to
				   allow for the detection of 'fake' media (eg. 2GB USB masquerading as 16GB) */
				for (i=0; i<(int)blocks_at_once; i++) {
					blk_id = (blk64_t*)(intptr_t)(buffer + id_offset+ i*block_size);
					*blk_id = (blk64_t)(currently_testing + i);
				}
			}
			got = do_write(hDrive, buffer, tryout, block_size, currently_testing);
			if (v_flag > 1)
				print_status();

			if (got == 0 && tryout == 1)
				bb_count += bb_output(currently_testing++, WRITE_ERROR);
			currently_testing += got;
			if (got != tryout) {
				tryout = 1;
				if (recover_block == ~0)
					recover_block = currently_testing -
						got + blocks_at_once;
				continue;
			} else if (currently_testing == recover_block) {
				tryout = blocks_at_once;
				recover_block = ~0;
			}
		}

		num_blocks = 0;
		if (s_flag | v_flag)
			uprintf("%sReading and comparing\n", bb_prefix);
		cur_op = OP_READ;
		num_blocks = last_block;
		currently_testing = first_block;

		tryout = blocks_at_once;
		while (currently_testing < last_block) {
			if (cancel_ops) goto out;
			if (max_bb && bb_count >= max_bb) {
				if (s_flag || v_flag) {
					uprintf(abort_msg);
					fprintf(log_fd, abort_msg);
					fflush(log_fd);
				}
				cancel_ops = -1;
				goto out;
			}
			if (currently_testing + tryout > last_block)
				tryout = last_block - currently_testing;
			if (detect_fakes && (pat_idx == 0)) {
				for (i=0; i<(int)blocks_at_once; i++) {
					blk_id = (blk64_t*)(intptr_t)(buffer + id_offset+ i*block_size);
					*blk_id = (blk64_t)(currently_testing + i);
				}
			}
			got = do_read(hDrive, read_buffer, tryout, block_size,
				       currently_testing);
			if (got == 0 && tryout == 1)
				bb_count += bb_output(currently_testing++, READ_ERROR);
			currently_testing += got;
			if (got != tryout) {
				tryout = 1;
				if (recover_block == ~0)
					recover_block = currently_testing -
						got + blocks_at_once;
				continue;
			} else if (currently_testing == recover_block) {
				tryout = blocks_at_once;
				recover_block = ~0;
			}
			for (i=0; i < got; i++) {
				if (memcmp(read_buffer + i * block_size,
					   buffer + i * block_size,
					   block_size))
					bb_count += bb_output(currently_testing+i-got, CORRUPTION_ERROR);
			}
			if (v_flag > 1)
				print_status();
		}

		num_blocks = 0;
	}
out:
	free_buffer(buffer);
	return bb_count;
}