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

📄 osst.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	return;}/* Onstream specific Routines *//* * Initialize the OnStream AUX */static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int logical_blk_num){	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(frame_type==OS_FRAME_TYPE_DATA?STp->block_size:0);		dat->dat_list[0].blk_cnt  = htons(1);		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(logical_blk_num);		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);        /* FIXME -- violates ADR spec */	aux->phys_fm = ntohl(0xffffffff);	aux->last_mark_ppos = ntohl(STp->last_mark_ppos);}/* * Verify that we have the correct tape frame */static int osst_verify_frame(OS_Scsi_Tape * STp, int logical_blk_num, int quiet){	os_aux_t       * aux  = STp->buffer->aux;	os_partition_t * par  = &(aux->partition);	ST_partstat    * STps = &(STp->ps[STp->partition]);	int              i;	int		 dev  = TAPE_NR(STp->devt);	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");		}		return 1;	}	if (STp->buffer->syscall_result) {		printk(KERN_INFO "osst%d: Skipping frame, read error\n", dev);		return 0;	}	if (ntohl(aux->format_id) != 0) {		printk(KERN_INFO "osst%d: Skipping frame, format_id %u\n", dev, ntohl(aux->format_id));		return 0;	}	if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&	    (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {		printk(KERN_INFO "osst%d: Skipping frame, incorrect application signature\n", dev);		return 0;	}	if (par->partition_num != OS_DATA_PARTITION) {		if (!STp->linux_media || STp->linux_media_version != 2) {			printk(KERN_INFO "osst%d: Skipping frame, partition num %d\n", dev, par->partition_num);              		    return 0;		}	}	if (par->par_desc_ver != OS_PARTITION_VERSION) {		printk(KERN_INFO "osst%d: Skipping frame, partition version %d\n", dev, par->par_desc_ver);		return 0;	}	if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {		printk(KERN_INFO "osst%d: Skipping frame, wrt_pass_cntr %d (expected %d)\n", 				 dev, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);		return 0;	}	if (aux->frame_seq_num != aux->logical_blk_num) {		printk(KERN_INFO "osst%d: Skipping frame, seq != logical\n", dev);		return 0;	}	if (aux->frame_type != OS_FRAME_TYPE_DATA &&	    aux->frame_type != OS_FRAME_TYPE_EOD &&	    aux->frame_type != OS_FRAME_TYPE_MARKER) {		if (!quiet)			printk(KERN_INFO "osst%d: Skipping frame, frame type %x\n", dev, aux->frame_type);		return 0;	}	if (aux->frame_type == OS_FRAME_TYPE_EOD &&	    STp->first_frame_position < STp->eod_frame_ppos) {		printk(KERN_INFO "osst%d: Skipping premature EOD frame %d\n", dev, STp->first_frame_position);		return 0;	}	STp->logical_blk_in_buffer = 1;	if (logical_blk_num != -1 && ntohl(aux->logical_blk_num) != logical_blk_num) {		if (!quiet)			printk(KERN_INFO "osst%d: Skipping frame, logical_blk_num %u (expected %d)\n", 					 dev, ntohl(aux->logical_blk_num), logical_blk_num);		return 0;	}	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 1 //DEBUG			printk(OSST_DEB_MSG "osst%i: %s filemark %d at frame %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) {		STps->eof = ST_NOEOF;	}	return 1;}/* * 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: 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)         ) {#if DEBUG	    if (debugging) {		printk(OSST_DEB_MSG "osst%d: Sleeping in onstream wait ready\n", dev);		printk(OSST_DEB_MSG "osst%d: Turning off debugging for a while\n", dev);		debugging = 0;	    }#endif	    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: Abnormal exit from onstream wait ready\n", dev);printk(OSST_DEB_MSG "osst%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: Normal exit from onstream wait ready\n", dev);#endif	return 0;}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: 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 = ST_IDLE;	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) ||	    (minlast <  0 && STp->ps[STp->partition].rw != ST_WRITING) )		printk(KERN_ERR "osst%i: waiting for frame without having initialized %s!\n",			       	dev, minlast<0?"write":"read");	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;	/* successfull 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%i: 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;		}#if DEBUG		if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)		{			printk (OSST_DEB_MSG "osst%i: Wait for frame %i (>%i): %i-%i %i (%i)\n",				dev, curr, curr+minlast, STp->first_frame_position,				STp->last_frame_position, STp->cur_frames, result);			notyetprinted--;		}#endif		current->state = TASK_INTERRUPTIBLE;		schedule_timeout (HZ / OSST_POLL_PER_SEC);	}#if DEBUG	printk (OSST_DEB_MSG "osst%i: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",		dev, curr, curr+minlast, STp->first_frame_position,		STp->last_frame_position, STp->cur_frames,		(jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);#endif		return -EBUSY;}/* * Read the next OnStream tape block at the current location */static int osst_read_block(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout){	unsigned char	cmd[MAX_COMMAND_SIZE];	Scsi_Request  * SRpnt;	int		retval = 0;#if DEBUG	os_aux_t      * aux    = STp->buffer->aux;	int		dev    = TAPE_NR(STp->devt);#endif	/* TODO: Error handling */	if (STp->poll)		retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout);#if 0// DEBUG	printk ("osst_read: wait for frame returned %i\n", retval);#endif		memset(cmd, 0, MAX_COMMAND_SIZE);	cmd[0] = READ_6;	cmd[1] = 1;	cmd[4] = 1;#if DEBUG	if (debugging)	    printk(OSST_DEB_MSG "osst%i: Reading block from OnStream tape\n", dev);#endif	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,				      STp->timeout, MAX_RETRIES, TRUE);	*aSRpnt = SRpnt;	if (!SRpnt)	    return (-EBUSY);	if ((STp->buffer)->syscall_result) {	    retval = 1;	    if (STp->read_error_frame == 0) {		STp->read_error_frame = STp->first_frame_position;		printk(OSST_DEB_MSG "osst: recording read error at %d\n", STp->read_error_frame);/*FIXME*/	    }#if DEBUG	    if (debugging)		printk(OSST_DEB_MSG "osst%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",		   dev,		   SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],		   SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],		   SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],		   SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]);#endif	}	else	    STp->first_frame_position++;#if DEBUG	if (debugging) {	   printk(OSST_DEB_MSG "osst%i: AUX: %c%c%c%c UpdFrCt#%d %s FrSeq#%d LogBlk#%d\n", dev,			aux->application_sig[0], aux->application_sig[1],			aux->application_sig[2], aux->application_sig[3], ntohl(aux->update_frame_cntr),			aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":			aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", 			ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num) );	   if (aux->frame_type==2)		printk(OSST_DEB_MSG "osst%i: mark_cnt=%d, last_mark=%d, next_mark=%d\n", dev,			ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->next_mark_ppos));	   printk(OSST_DEB_MSG "osst%i: Exit read block from OnStream tape with code %d\n", dev, retval);	}#endif	return (retval);}static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt){	ST_partstat   * STps   = &(STp->ps[STp->partition]);	Scsi_Request  * SRpnt  ;	unsigned char	cmd[MAX_COMMAND_SIZE];	int		retval = 0;#if DEBUG	int		dev    = TAPE_NR(STp->devt);#endif

⌨️ 快捷键说明

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