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

📄 ftape-read.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
			ftape_setup_new_segment(head, segment_id, -1);			if (read_mode == FT_RD_SINGLE) {				/* disable read-ahead */				head->next_segment = 0;			}			ftape_calc_next_cluster(head);			if (ft_runner_status == idle) {				result = ftape_start_tape(segment_id,							  head->sector_offset);				if (result < 0) {					TRACE_ABORT(result, ft_t_err, "Error: "						    "segment %d unreachable",						    segment_id);				}			}			head->status = reading;			fdc_setup_read_write(head, FDC_READ);		}	}	/* not reached */	TRACE_EXIT -EIO;}int ftape_read_header_segment(__u8 *address){	int result;	int header_segment;	int first_failed = 0;	int status;	TRACE_FUN(ft_t_flow);	ft_used_header_segment = -1;	TRACE_CATCH(ftape_report_drive_status(&status),);	TRACE(ft_t_flow, "reading...");	/*  We're looking for the first header segment.	 *  A header segment cannot contain bad sectors, therefor at the	 *  tape start, segments with bad sectors are (according to QIC-40/80)	 *  written with deleted data marks and must be skipped.	 */	memset(address, '\0', (FT_SECTORS_PER_SEGMENT - 3) * FT_SECTOR_SIZE); 	result = 0;#define HEADER_SEGMENT_BOUNDARY 68  /* why not 42? */	for (header_segment = 0;	     header_segment < HEADER_SEGMENT_BOUNDARY && result == 0;	     ++header_segment) {		/*  Set no read-ahead, the isr will force read-ahead whenever		 *  it encounters deleted data !		 */		result = ftape_read_segment(header_segment,					    address,					    FT_RD_SINGLE);		if (result < 0 && !first_failed) {			TRACE(ft_t_err, "header segment damaged, trying backup");			first_failed = 1;			result = 0;	/* force read of next (backup) segment */		}	}	if (result < 0 || header_segment >= HEADER_SEGMENT_BOUNDARY) {		TRACE_ABORT(-EIO, ft_t_err,			    "no readable header segment found");	}	TRACE_CATCH(ftape_abort_operation(),);	ft_used_header_segment = header_segment;	result = ftape_decode_header_segment(address); 	TRACE_EXIT result;}int ftape_decode_header_segment(__u8 *address){	unsigned int max_floppy_side;	unsigned int max_floppy_track;	unsigned int max_floppy_sector;	unsigned int new_tape_len;	TRACE_FUN(ft_t_flow);	if (GET4(address, FT_SIGNATURE) == FT_D2G_MAGIC) {		/* Ditto 2GB header segment. They encrypt the bad sector map.		 * We decrypt it and store them in normal format.		 * I hope this is correct.		 */		int i;		TRACE(ft_t_warn,		      "Found Ditto 2GB tape, "		      "trying to decrypt bad sector map");		for (i=256; i < 29 * FT_SECTOR_SIZE; i++) {			address[i] = ~(address[i] - (i&0xff));		}		PUT4(address, 0,FT_HSEG_MAGIC);	} else if (GET4(address, FT_SIGNATURE) != FT_HSEG_MAGIC) {		TRACE_ABORT(-EIO, ft_t_err,			    "wrong signature in header segment");	}	ft_format_code = (ft_format_type) address[FT_FMT_CODE];	if (ft_format_code != fmt_big) {		ft_header_segment_1   = GET2(address, FT_HSEG_1);		ft_header_segment_2   = GET2(address, FT_HSEG_2);		ft_first_data_segment = GET2(address, FT_FRST_SEG);		ft_last_data_segment  = GET2(address, FT_LAST_SEG);	} else {		ft_header_segment_1   = GET4(address, FT_6_HSEG_1);		ft_header_segment_2   = GET4(address, FT_6_HSEG_2);		ft_first_data_segment = GET4(address, FT_6_FRST_SEG);		ft_last_data_segment  = GET4(address, FT_6_LAST_SEG);	}	TRACE(ft_t_noise, "first data segment: %d", ft_first_data_segment);	TRACE(ft_t_noise, "last  data segment: %d", ft_last_data_segment);	TRACE(ft_t_noise, "header segments are %d and %d",	      ft_header_segment_1, ft_header_segment_2);	/*    Verify tape parameters...	 *    QIC-40/80 spec:                 tape_parameters:	 *	 *    segments-per-track              segments_per_track	 *    tracks-per-cartridge            tracks_per_tape	 *    max-floppy-side                 (segments_per_track *	 *                                    tracks_per_tape - 1) /	 *                                    ftape_segments_per_head	 *    max-floppy-track                ftape_segments_per_head /	 *                                    ftape_segments_per_cylinder - 1	 *    max-floppy-sector               ftape_segments_per_cylinder *	 *                                    FT_SECTORS_PER_SEGMENT	 */	ft_segments_per_track = GET2(address, FT_SPT);	ft_tracks_per_tape    = address[FT_TPC];	max_floppy_side       = address[FT_FHM];	max_floppy_track      = address[FT_FTM];	max_floppy_sector     = address[FT_FSM];	TRACE(ft_t_noise, "(fmt/spt/tpc/fhm/ftm/fsm) = %d/%d/%d/%d/%d/%d",	      ft_format_code, ft_segments_per_track, ft_tracks_per_tape,	      max_floppy_side, max_floppy_track, max_floppy_sector);	new_tape_len = ftape_tape_len;	switch (ft_format_code) {	case fmt_425ft:		new_tape_len = 425;		break;	case fmt_normal:		if (ftape_tape_len == 0) {	/* otherwise 307 ft */			new_tape_len = 205;		}		break;	case fmt_1100ft:		new_tape_len = 1100;		break;	case fmt_var:{			int segments_per_1000_inch = 1;		/* non-zero default for switch */			switch (ft_qic_std) {			case QIC_TAPE_QIC40:				segments_per_1000_inch = 332;				break;			case QIC_TAPE_QIC80:				segments_per_1000_inch = 488;				break;			case QIC_TAPE_QIC3010:				segments_per_1000_inch = 730;				break;			case QIC_TAPE_QIC3020:				segments_per_1000_inch = 1430;				break;			}			new_tape_len = (1000 * ft_segments_per_track +					(segments_per_1000_inch - 1)) / segments_per_1000_inch;			break;		}	case fmt_big:{			int segments_per_1000_inch = 1;		/* non-zero default for switch */			switch (ft_qic_std) {			case QIC_TAPE_QIC40:				segments_per_1000_inch = 332;				break;			case QIC_TAPE_QIC80:				segments_per_1000_inch = 488;				break;			case QIC_TAPE_QIC3010:				segments_per_1000_inch = 730;				break;			case QIC_TAPE_QIC3020:				segments_per_1000_inch = 1430;				break;			default:				TRACE_ABORT(-EIO, ft_t_bug,			"%x QIC-standard with fmt-code %d, please report",					    ft_qic_std, ft_format_code);			}			new_tape_len = ((1000 * ft_segments_per_track +					 (segments_per_1000_inch - 1)) / 					segments_per_1000_inch);			break;		}	default:		TRACE_ABORT(-EIO, ft_t_err,			    "unknown tape format, please report !");	}	if (new_tape_len != ftape_tape_len) {		ftape_tape_len = new_tape_len;		TRACE(ft_t_info, "calculated tape length is %d ft",		      ftape_tape_len);		ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len);	}	if (ft_segments_per_track == 0 && ft_tracks_per_tape == 0 &&	    max_floppy_side == 0 && max_floppy_track == 0 &&	    max_floppy_sector == 0) {		/*  QIC-40 Rev E and earlier has no values in the header.		 */		ft_segments_per_track = 68;		ft_tracks_per_tape = 20;		max_floppy_side = 1;		max_floppy_track = 169;		max_floppy_sector = 128;	}	/*  This test will compensate for the wrong parameter on tapes	 *  formatted by Conner software.	 */	if (ft_segments_per_track == 150 &&	    ft_tracks_per_tape == 28 &&	    max_floppy_side == 7 &&	    max_floppy_track == 149 &&	    max_floppy_sector == 128) {TRACE(ft_t_info, "the famous CONNER bug: max_floppy_side off by one !");		max_floppy_side = 6;	}	/*  These tests will compensate for the wrong parameter on tapes	 *  formatted by ComByte Windows software.	 *	 *  First, for 205 foot tapes	 */	if (ft_segments_per_track == 100 &&	    ft_tracks_per_tape == 28 &&	    max_floppy_side == 9 &&	    max_floppy_track == 149 &&	    max_floppy_sector == 128) {TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!");		max_floppy_side = 4;	}	/* Next, for 307 foot tapes. */	if (ft_segments_per_track == 150 &&	    ft_tracks_per_tape == 28 &&	    max_floppy_side == 9 &&	    max_floppy_track == 149 &&	    max_floppy_sector == 128) {TRACE(ft_t_info, "the ComByte bug: max_floppy_side incorrect!");		max_floppy_side = 6;	}	/*  This test will compensate for the wrong parameter on tapes	 *  formatted by Colorado Windows software.	 */	if (ft_segments_per_track == 150 &&	    ft_tracks_per_tape == 28 &&	    max_floppy_side == 6 &&	    max_floppy_track == 150 &&	    max_floppy_sector == 128) {TRACE(ft_t_info, "the famous Colorado bug: max_floppy_track off by one !");		max_floppy_track = 149;	}	ftape_segments_per_head = ((max_floppy_sector/FT_SECTORS_PER_SEGMENT) *				   (max_floppy_track + 1));	/*  This test will compensate for some bug reported by Dima	 *  Brodsky.  Seems to be a Colorado bug, either. (freebee	 *  Imation tape shipped together with Colorado T3000	 */	if ((ft_format_code == fmt_var || ft_format_code == fmt_big) &&	    ft_tracks_per_tape == 50 &&	    max_floppy_side == 54 &&	    max_floppy_track == 255 &&	    max_floppy_sector == 128) {TRACE(ft_t_info, "the famous ??? bug: max_floppy_track off by one !");		max_floppy_track = 254;	}	/*	 *    Verify drive_configuration with tape parameters	 */	if (ftape_segments_per_head == 0 || ftape_segments_per_cylinder == 0 ||	  ((ft_segments_per_track * ft_tracks_per_tape - 1) / ftape_segments_per_head	   != max_floppy_side) ||	    (ftape_segments_per_head / ftape_segments_per_cylinder - 1 != max_floppy_track) ||	(ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT != max_floppy_sector)#ifdef TESTING	    || ((ft_format_code == fmt_var || ft_format_code == fmt_big) && 		(max_floppy_track != 254 || max_floppy_sector != 128))#endif	   ) {		char segperheadz = ftape_segments_per_head ? ' ' : '?';		char segpercylz  = ftape_segments_per_cylinder ? ' ' : '?';		TRACE(ft_t_err,"Tape parameters inconsistency, please report");		TRACE(ft_t_err, "reported = %d/%d/%d/%d/%d/%d",		      ft_format_code,		      ft_segments_per_track,		      ft_tracks_per_tape,		      max_floppy_side,		      max_floppy_track,		      max_floppy_sector);		TRACE(ft_t_err, "required = %d/%d/%d/%d%c/%d%c/%d",		      ft_format_code,		      ft_segments_per_track,		      ft_tracks_per_tape,		      ftape_segments_per_head ?		      ((ft_segments_per_track * ft_tracks_per_tape -1) / 		       ftape_segments_per_head ) :			(ft_segments_per_track * ft_tracks_per_tape -1),			segperheadz,		      ftape_segments_per_cylinder ?		      (ftape_segments_per_head / 		       ftape_segments_per_cylinder - 1 ) :			ftape_segments_per_head - 1,			segpercylz,		      (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT));		TRACE_EXIT -EIO;	}	ftape_extract_bad_sector_map(address); 	TRACE_EXIT 0;}

⌨️ 快捷键说明

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