⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftape-eof.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *      Copyright (C) 1994-1995 Bas Laarhoven. 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, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING.  If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. $Source: /usr/local/cvsroot/AplioTRIO/linux/drivers/char/ftape/ftape-eof.c,v $ $Author: vadim $ * $Revision: 1.1.1.1 $ $Date: 1999/11/15 13:41:57 $ $State: Exp $ * *      This file contains the eof mark handling code *      for the QIC-40/80 floppy-tape driver for Linux. */#include <linux/ftape.h>#include <linux/string.h>#include <linux/errno.h>#include "tracing.h"#include "ftape-eof.h"#include "ftape-write.h"#include "ftape-read.h"#include "ftape-rw.h"#include "ftape-ctl.h"#include "ftape-bsm.h"/*      Global vars. */int failed_sector_log_changed = 0;int eof_mark = 0;/*      Local vars. */static struct failed_sector_entry {	unsigned short segment;	unsigned short sector;} *eof_mark_ptr;typedef union {	struct failed_sector_entry mark;	unsigned long entry;} eof_mark_union;/*  a copy of the failed sector log from the header segment. */static eof_mark_union eof_map[(2048 - 256) / 4];/*  index into eof_map table pointing to last found eof mark. */static int eof_index;/*  number of eof marks (entries in bad sector log) on tape. */static int nr_of_eof_marks = -1;static char linux_tape_label[] = "Linux raw format V";enum {	min_fmt_version = 1, max_fmt_version = 2};static unsigned ftape_fmt_version = 0;/*  Ftape (mis)uses the bad sector log to record end-of-file marks. *  Initially (when the tape is erased) all entries in the bad sector *  log are added to the tape's bad sector map. The bad sector log *  then is cleared. * *  The bad sector log normally contains entries of the form: *  even 16-bit word: segment number of bad sector *   odd 16-bit word: encoded date *  There can be a total of 448 entries (1792 bytes). * *  My guess is that no program is using this bad sector log (the *  format seems useless as there is no indication of the bad sector *  itself, only the segment) *  However, if any program does use the bad sector log, the format *  used by ftape will let the program think there are some bad sectors *  and no harm is done. *   *  The eof mark entries that ftape stores in the bad sector log: *  even 16-bit word: segment number of eof mark *   odd 16-bit word: sector number of eof mark [1..32] *   *  The eof_map as maintained is a sorted list of eof mark entries. * * *  The tape name field in the header segments is used to store a *  linux tape identification string and a version number. *  This way the tape can be recognized as a Linux raw format *  tape when using tools under other OS's. * *  'Wide' QIC tapes (format code 4) don't have a failed sector list *  anymore. That space is used for the (longer) bad sector map that *  now is a variable length list too. *  We now store our end-of-file marker list after the bad-sector-map *  on tape. The list is delimited by a (long) 0 entry. */int ftape_validate_label(char *label){	TRACE_FUN(8, "ftape_validate_label");	int result = 0;	TRACEx1(4, "tape  label = `%s'", label);	ftape_fmt_version = 0;	if (memcmp(label, linux_tape_label, strlen(linux_tape_label)) == 0) {		int pos = strlen(linux_tape_label);		while (label[pos] >= '0' && label[pos] <= '9') {			ftape_fmt_version *= 10;			ftape_fmt_version = label[pos++] - '0';		}		result = (ftape_fmt_version >= min_fmt_version &&			  ftape_fmt_version <= max_fmt_version);	}	TRACEx1(4, "format version = %d", ftape_fmt_version);	TRACE_EXIT;	return result;}static byte * find_end_of_eof_list(byte * ptr, byte * limit){	while (ptr + 3 < limit) {		if (*(unsigned long *) ptr) {			++(unsigned long *) ptr;		} else {			return ptr;		}	}	return NULL;}void reset_eof_list(void){	TRACE_FUN(8, "reset_eof_list");	eof_mark_ptr = &eof_map[0].mark;	eof_index = 0;	eof_mark = 0;	TRACE_EXIT;}/*  Test if `segment' has an eof mark set (optimized for sequential access). *  return 0 if not eof mark or sector number (> 0) if eof mark set. */int check_for_eof(unsigned segment){	TRACE_FUN(8, "check_for_eof");	static unsigned last_reference = INT_MAX;	int result;	if (segment < last_reference) {		reset_eof_list();	}	last_reference = segment;	while (eof_index < nr_of_eof_marks && segment > eof_mark_ptr->segment) {		++eof_mark_ptr;		++eof_index;	}	if (eof_index < nr_of_eof_marks && segment == eof_mark_ptr->segment) {		TRACEx3(5, "hit mark %d/%d at index %d",			eof_map[eof_index].mark.segment, eof_map[eof_index].mark.sector,			eof_index);		if (eof_mark_ptr->sector >= SECTORS_PER_SEGMENT) {			TRACEx2(-1, "Bad file mark detected: %d/%d",			    eof_mark_ptr->segment, eof_mark_ptr->sector);			result = 0;	/* return bogus (but valid) value */		} else {			result = eof_mark_ptr->sector;		}	} else {		result = 0;	}	TRACE_EXIT;	return result;}void clear_eof_mark_if_set(unsigned segment, unsigned byte_count){	TRACE_FUN(5, "clear_eof_mark_if_set");	if (ftape_fmt_version != 0 &&	    check_for_eof(segment) > 0 &&	    byte_count >= eof_mark_ptr->sector * SECTOR_SIZE) {		TRACEx3(5, "clearing mark %d/%d at index %d",		 eof_mark_ptr->segment, eof_mark_ptr->sector, eof_index);		memmove(&eof_map[eof_index], &eof_map[eof_index + 1],			(nr_of_eof_marks - eof_index) * sizeof(*eof_map));		--nr_of_eof_marks;		failed_sector_log_changed = 1;	}	TRACE_EXIT;}void put_file_mark_in_map(unsigned segment, unsigned sector){	TRACE_FUN(8, "put_file_mark_in_map");	eof_mark_union new;	int index;	eof_mark_union *ptr;	if (ftape_fmt_version != 0) {		new.mark.segment = segment;		new.mark.sector = sector;		for (index = 0, ptr = &eof_map[0];		  index < nr_of_eof_marks && ptr->mark.segment < segment;		     ++index, ++ptr) {		}		if (index < nr_of_eof_marks) {			if (ptr->mark.segment == segment) {				/* overwrite */				if (ptr->mark.sector == sector) {					TRACEx2(5, "mark %d/%d already exists",						new.mark.segment, new.mark.sector);				} else {					TRACEx5(5, "overwriting %d/%d at index %d with %d/%d",						ptr->mark.segment, ptr->mark.sector, index,						new.mark.segment, new.mark.sector);					ptr->entry = new.entry;					failed_sector_log_changed = 1;				}			} else {				/* insert */				TRACEx5(5, "inserting %d/%d at index %d before %d/%d",				new.mark.segment, new.mark.sector, index,				    ptr->mark.segment, ptr->mark.sector);				memmove(ptr + 1, ptr, (nr_of_eof_marks - index) * sizeof(*eof_map));				ptr->entry = new.entry;				++nr_of_eof_marks;				failed_sector_log_changed = 1;			}		} else {			/* append */			TRACEx3(5, "appending %d/%d at index %d",				new.mark.segment, new.mark.sector, index);			ptr->entry = new.entry;			++nr_of_eof_marks;			failed_sector_log_changed = 1;		}	}	TRACE_EXIT;}/*  Write count file marks to tape starting at first non-bad *  sector following the given segment and sector. *  sector = base 1 ! */int ftape_weof(unsigned count, unsigned segment, unsigned sector){	TRACE_FUN(5, "ftape_weof");	int result = 0;	unsigned long mask = get_bad_sector_entry(segment);	unsigned sector_nr = 0;	if (ftape_fmt_version != 0) {		if (sector < 1 || sector > 29 ||		    segment + count >= ftape_last_segment.id) {			TRACEx3(5, "parameter out of range: %d, %d, %d", count, segment, sector);			result = -EIO;		} else {			while (count-- > 0) {				do {	/* count logical sectors */					do {	/* skip until good sector */						while (mask & 1) {	/* skip bad sectors */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -