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

📄 osst.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Onstream specific Routines *//* * Initialize the OnStream AUX */static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_number,					 int logical_blk_num, int blk_sz, int blk_cnt){	os_aux_t       *aux = STp->buffer->aux;	os_partition_t *par = &aux->partition;	os_dat_t       *dat = &aux->dat;	if (STp->raw) return;	memset(aux, 0, sizeof(*aux));	aux->format_id = htonl(0);	memcpy(aux->application_sig, "LIN4", 4);	aux->hdwr = htonl(0);	aux->frame_type = frame_type;	switch (frame_type) {	  case	OS_FRAME_TYPE_HEADER:		aux->update_frame_cntr    = htonl(STp->update_frame_cntr);		par->partition_num        = OS_CONFIG_PARTITION;		par->par_desc_ver         = OS_PARTITION_VERSION;		par->wrt_pass_cntr        = htons(0xffff);		/* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */		par->first_frame_ppos     = htonl(0);		par->last_frame_ppos      = htonl(0xbb7);		aux->frame_seq_num        = htonl(0);		aux->logical_blk_num_high = htonl(0);		aux->logical_blk_num      = htonl(0);		aux->next_mark_ppos       = htonl(STp->first_mark_ppos);		break;	  case	OS_FRAME_TYPE_DATA:	  case	OS_FRAME_TYPE_MARKER:		dat->dat_sz = 8;		dat->reserved1 = 0;		dat->entry_cnt = 1;		dat->reserved3 = 0;		dat->dat_list[0].blk_sz   = htonl(blk_sz);		dat->dat_list[0].blk_cnt  = htons(blk_cnt);		dat->dat_list[0].flags    = frame_type==OS_FRAME_TYPE_MARKER?							OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;		dat->dat_list[0].reserved = 0;	  case	OS_FRAME_TYPE_EOD:		aux->update_frame_cntr    = htonl(0);		par->partition_num        = OS_DATA_PARTITION;		par->par_desc_ver         = OS_PARTITION_VERSION;		par->wrt_pass_cntr        = htons(STp->wrt_pass_cntr);		par->first_frame_ppos     = htonl(STp->first_data_ppos);		par->last_frame_ppos      = htonl(STp->capacity);		aux->frame_seq_num        = htonl(frame_seq_number);		aux->logical_blk_num_high = htonl(0);		aux->logical_blk_num      = htonl(logical_blk_num);		break;	  default: ; /* probably FILL */	}	aux->filemark_cnt = ntohl(STp->filemark_cnt);	aux->phys_fm = ntohl(0xffffffff);	aux->last_mark_ppos = ntohl(STp->last_mark_ppos);	aux->last_mark_lbn  = ntohl(STp->last_mark_lbn);}/* * Verify that we have the correct tape frame */static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet){	os_aux_t       * aux  = STp->buffer->aux;	os_partition_t * par  = &(aux->partition);	ST_partstat    * STps = &(STp->ps[STp->partition]);	int		 dev  = TAPE_NR(STp->devt);	int		 blk_cnt, blk_sz, i;	if (STp->raw) {		if (STp->buffer->syscall_result) {			for (i=0; i < STp->buffer->sg_segs; i++)				memset(STp->buffer->sg[i].address, 0, STp->buffer->sg[i].length);			strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");                } else			STp->buffer->buffer_bytes = OS_FRAME_SIZE;		return 1;	}	if (STp->buffer->syscall_result) {#if DEBUG		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, read error\n", dev);#endif		return 0;	}	if (ntohl(aux->format_id) != 0) {#if DEBUG		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, format_id %u\n", dev, ntohl(aux->format_id));#endif		goto err_out;	}	if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&	    (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {#if DEBUG		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, incorrect application signature\n", dev);#endif		goto err_out;	}	if (par->partition_num != OS_DATA_PARTITION) {		if (!STp->linux_media || STp->linux_media_version != 2) {#if DEBUG			printk(OSST_DEB_MSG "osst%d:D: Skipping frame, partition num %d\n",					    dev, par->partition_num);#endif			goto err_out;		}	}	if (par->par_desc_ver != OS_PARTITION_VERSION) {#if DEBUG		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, partition version %d\n", dev, par->par_desc_ver);#endif		goto err_out;	}	if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {#if DEBUG		printk(OSST_DEB_MSG "osst%d:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 				    dev, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);#endif		goto err_out;	}	if (aux->frame_type != OS_FRAME_TYPE_DATA &&	    aux->frame_type != OS_FRAME_TYPE_EOD &&	    aux->frame_type != OS_FRAME_TYPE_MARKER) {		if (!quiet)#if DEBUG			printk(OSST_DEB_MSG "osst%d:D: Skipping frame, frame type %x\n", dev, aux->frame_type);#endif		goto err_out;	}	if (aux->frame_type == OS_FRAME_TYPE_EOD &&	    STp->first_frame_position < STp->eod_frame_ppos) {		printk(KERN_INFO "osst%d:I: Skipping premature EOD frame %d\n", dev,				 STp->first_frame_position);		goto err_out;	}	STp->frame_in_buffer = 1;        if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {		if (!quiet)#if DEBUG			printk(OSST_DEB_MSG "osst%d:D: Skipping frame, sequence number %u (expected %d)\n", 					    dev, ntohl(aux->frame_seq_num), frame_seq_number);#endif		goto err_out;	}	if (aux->frame_type == OS_FRAME_TYPE_MARKER) {		STps->eof = ST_FM_HIT;		i = ntohl(aux->filemark_cnt);		if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||		    STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {#if DEBUG			printk(OSST_DEB_MSG "osst%d:D: %s filemark %d at frame pos %d\n", dev,				  STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",				  i, STp->first_frame_position - 1);#endif			STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);			if (i >= STp->filemark_cnt)				 STp->filemark_cnt = i+1;		}	}	if (aux->frame_type == OS_FRAME_TYPE_EOD) {		STps->eof = ST_EOD_1;	}	if (aux->frame_type == OS_FRAME_TYPE_DATA) {                blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);		blk_sz  = ntohl(aux->dat.dat_list[0].blk_sz);		STp->buffer->buffer_bytes = blk_cnt * blk_sz;		STp->buffer->read_pointer = 0;		/* See what block size was used to write file */		if (STp->block_size != blk_sz && blk_sz > 0) {			printk(KERN_INFO	    	"osst%d:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",       				dev, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',				STp->block_size<1024?STp->block_size:STp->block_size/1024,				STp->block_size<1024?'b':'k');			STp->block_size            = blk_sz;			STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;		}		STps->eof = ST_NOEOF;	}        STp->frame_seq_number = ntohl(aux->frame_seq_num);	STp->logical_blk_num  = ntohl(aux->logical_blk_num);	return 1;err_out:	if (STp->read_error_frame == 0)		STp->read_error_frame = STp->first_frame_position - 1;	return 0;}/* * Wait for the unit to become Ready */static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout){	unsigned char	cmd[MAX_COMMAND_SIZE];	Scsi_Request  * SRpnt;	long		startwait = jiffies;#if DEBUG	int		dbg = debugging;	int		dev  = TAPE_NR(STp->devt);	printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait ready\n", dev);#endif	memset(cmd, 0, MAX_COMMAND_SIZE);	cmd[0] = TEST_UNIT_READY;	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);	*aSRpnt = SRpnt;	if (!SRpnt) return (-EBUSY);	while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&	       (( SRpnt->sr_sense_buffer[2]  == 2 && SRpnt->sr_sense_buffer[12] == 4    &&		 (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)    ) ||		( SRpnt->sr_sense_buffer[2]  == 6 && SRpnt->sr_sense_buffer[12] == 0x28 &&		  SRpnt->sr_sense_buffer[13] == 0                                        )  )) {#if DEBUG	    if (debugging) {		printk(OSST_DEB_MSG "osst%d:D: Sleeping in onstream wait ready\n", dev);		printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);		debugging = 0;	    }#endif	    set_current_state(TASK_INTERRUPTIBLE);	    schedule_timeout(HZ / 10);	    memset(cmd, 0, MAX_COMMAND_SIZE);	    cmd[0] = TEST_UNIT_READY;	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);	}	*aSRpnt = SRpnt;#if DEBUG	debugging = dbg;#endif	if ( STp->buffer->syscall_result &&	     osst_write_error_recovery(STp, aSRpnt, 0) ) {#if DEBUG	    printk(OSST_DEB_MSG "osst%d:D: Abnormal exit from onstream wait ready\n", dev);	    printk(OSST_DEB_MSG "osst%d:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", dev,			STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],			SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);#endif	    return (-EIO);	}#if DEBUG	printk(OSST_DEB_MSG "osst%d:D: Normal exit from onstream wait ready\n", dev);#endif	return 0;}/* * Wait for a tape to be inserted in the unit */static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout){	unsigned char	cmd[MAX_COMMAND_SIZE];	Scsi_Request  * SRpnt;	long		startwait = jiffies;#if DEBUG	int		dbg = debugging;	int		dev  = TAPE_NR(STp->devt);	printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait for medium\n", dev);#endif	memset(cmd, 0, MAX_COMMAND_SIZE);	cmd[0] = TEST_UNIT_READY;	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);	*aSRpnt = SRpnt;	if (!SRpnt) return (-EBUSY);	while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&		SRpnt->sr_sense_buffer[2]  == 2 && SRpnt->sr_sense_buffer[12] == 0x3a       &&	        SRpnt->sr_sense_buffer[13] == 0                                             ) {#if DEBUG	    if (debugging) {		printk(OSST_DEB_MSG "osst%d:D: Sleeping in onstream wait medium\n", dev);		printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);		debugging = 0;	    }#endif	    set_current_state(TASK_INTERRUPTIBLE);	    schedule_timeout(HZ / 10);	    memset(cmd, 0, MAX_COMMAND_SIZE);	    cmd[0] = TEST_UNIT_READY;	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);	}	*aSRpnt = SRpnt;#if DEBUG	debugging = dbg;#endif	if ( STp->buffer->syscall_result     && SRpnt->sr_sense_buffer[2]  != 2 &&	     SRpnt->sr_sense_buffer[12] != 4 && SRpnt->sr_sense_buffer[13] == 1) {#if DEBUG	    printk(OSST_DEB_MSG "osst%d:D: Abnormal exit from onstream wait medium\n", dev);	    printk(OSST_DEB_MSG "osst%d:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", dev,			STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],			SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);#endif	    return 0;	}#if DEBUG	printk(OSST_DEB_MSG "osst%d:D: Normal exit from onstream wait medium\n", dev);#endif	return 1;}static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame){	int	retval;	osst_wait_ready(STp, aSRpnt, 15 * 60);			/* TODO - can this catch a write error? */	retval = osst_set_frame_position(STp, aSRpnt, frame, 0);	if (retval) return (retval);	osst_wait_ready(STp, aSRpnt, 15 * 60);	return (osst_get_frame_position(STp, aSRpnt));}/* * Wait for write(s) to complete */static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt){	unsigned char	cmd[MAX_COMMAND_SIZE];	Scsi_Request  * SRpnt;	int             result = 0;#if DEBUG	int		dev  = TAPE_NR(STp->devt);	printk(OSST_DEB_MSG "osst%d:D: Reached onstream flush drive buffer (write filemark)\n", dev);#endif	memset(cmd, 0, MAX_COMMAND_SIZE);	cmd[0] = WRITE_FILEMARKS;	cmd[1] = 1;	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE);	*aSRpnt = SRpnt;	if (!SRpnt) return (-EBUSY);	if ((STp->buffer)->syscall_result)		result = osst_write_error_recovery(STp, aSRpnt, 0);	result |= osst_wait_ready(STp, aSRpnt, 5 * 60);	STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;	return (result);}#define OSST_POLL_PER_SEC 10static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, int minlast, int to){	long	startwait     = jiffies;	int	dev	      = TAPE_NR(STp->devt);#if DEBUG	char	notyetprinted = 1;#endif	if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)		printk(KERN_ERR "osst%i:A: Waiting for frame without having initialized read!\n", dev);	while (time_before (jiffies, startwait + to*HZ))	{ 		int result;		result = osst_get_frame_position (STp, aSRpnt);		if (result == -EIO)			if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)				return 0;	/* successful recovery leaves drive ready for frame */		if (result < 0) break;		if (STp->first_frame_position == curr &&		    ((minlast < 0 &&		      (signed)STp->last_frame_position > (signed)curr + minlast) ||		     (minlast >= 0 && STp->cur_frames > minlast)		    ) && result >= 0)		{#if DEBUG						if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)				printk (OSST_DEB_MSG					"osst%d:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",					dev, curr, curr+minlast, STp->first_frame_position,					STp->last_frame_position, STp->cur_frames,					result, (jiffies-startwait)/HZ, 					(((jiffies-startwait)%HZ)*10)/HZ);#endif			return 0;		}

⌨️ 快捷键说明

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