vfree((void *)buffer); 
vfree(buffer); 
static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi_request ** aSRpnt,						unsigned int frame, unsigned int skip, int pending){	struct scsi_request   * SRpnt = * aSRpnt;	unsigned char	      * buffer, * p;	unsigned char		cmd[MAX_COMMAND_SIZE];	int			flag, new_frame, i;	int			nframes          = STp->cur_frames;	int			blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);	int			frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)						- (nframes + pending - 1);	int			logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 						- (nframes + pending - 1) * blks_per_frame;	char		      * name             = tape_name(STp);	unsigned long		startwait        = jiffies;#if DEBUG	int			dbg              = debugging;#endif	if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)		return (-EIO);	printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",			 name, nframes, pending?" and one that was pending":"");	osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));#if DEBUG	if (pending && debugging)		printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",				name, frame_seq_number + nframes,			       	logical_blk_num + nframes * blks_per_frame,			       	p[0], p[1], p[2], p[3]);#endif	for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {		memset(cmd, 0, MAX_COMMAND_SIZE);		cmd[0] = 0x3C;		/* Buffer Read           */		cmd[1] = 6;		/* Retrieve Faulty Block */		cmd[7] = 32768 >> 8;		cmd[8] = 32768 & 0xff;		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,					    STp->timeout, MAX_RETRIES, 1);			if ((STp->buffer)->syscall_result || !SRpnt) {			printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);			vfree((void *)buffer);			*aSRpnt = SRpnt;			return (-EIO);		}		osst_copy_from_buffer(STp->buffer, p);#if DEBUG		if (debugging)			printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",					  name, frame_seq_number + i, p[0], p[1], p[2], p[3]);#endif	}	*aSRpnt = SRpnt;	osst_get_frame_position(STp, aSRpnt);#if DEBUG	printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);#endif	/* Write synchronously so we can be sure we're OK again and don't have to recover recursively */	/* In the header we don't actually re-write the frames that fail, just the ones after them */	for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {		if (flag) {			if (STp->write_type == OS_WRITE_HEADER) {				i += skip;				p += skip * OS_DATA_SIZE;			}			else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)				new_frame = 3000-i;			else				new_frame += skip;#if DEBUG			printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",						name, new_frame+i, frame_seq_number+i);#endif			osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);			osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);			osst_get_frame_position(STp, aSRpnt);			SRpnt = * aSRpnt;			if (new_frame > frame + 1000) {				printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);				vfree((void *)buffer);				return (-EIO);			}			if ( i >= nframes + pending ) break;			flag = 0;		}		osst_copy_to_buffer(STp->buffer, p);		/*		 * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!		 */		osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,			       	logical_blk_num + i*blks_per_frame,			       	ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);		memset(cmd, 0, MAX_COMMAND_SIZE);		cmd[0] = WRITE_6;		cmd[1] = 1;		cmd[4] = 1;#if DEBUG		if (debugging)			printk(OSST_DEB_MSG				"%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",				name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,				p[0], p[1], p[2], p[3]);#endif		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,					    STp->timeout, MAX_RETRIES, 1);		if (STp->buffer->syscall_result)			flag = 1;		else {			p += OS_DATA_SIZE; i++;			/* if we just sent the last frame, wait till all successfully written */			if ( i == nframes + pending ) {#if DEBUG				printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);#endif				memset(cmd, 0, MAX_COMMAND_SIZE);				cmd[0] = WRITE_FILEMARKS;				cmd[1] = 1;				SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,							    STp->timeout, MAX_RETRIES, 1);#if DEBUG				if (debugging) {					printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);					printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);					debugging = 0;				}#endif				flag = STp->buffer->syscall_result;				while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {					memset(cmd, 0, MAX_COMMAND_SIZE);					cmd[0] = TEST_UNIT_READY;					SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,												MAX_RETRIES, 1);					if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&					    (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) {						/* in the process of becoming ready */						msleep(100);						continue;					}					if (STp->buffer->syscall_result)						flag = 1;					break;				}#if DEBUG				debugging = dbg;				printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);#endif			}		}		*aSRpnt = SRpnt;		if (flag) {			if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&			     SRpnt->sr_sense_buffer[12]         ==  0 &&			     SRpnt->sr_sense_buffer[13]         ==  2) {				printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);				vfree((void *)buffer);				return (-EIO);			/* hit end of tape = fail */			}			i = ((SRpnt->sr_sense_buffer[3] << 24) |			     (SRpnt->sr_sense_buffer[4] << 16) |			     (SRpnt->sr_sense_buffer[5] <<  8) |			      SRpnt->sr_sense_buffer[6]        ) - new_frame;			p = &buffer[i * OS_DATA_SIZE];#if DEBUG			printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);#endif			osst_get_frame_position(STp, aSRpnt);#if DEBUG			printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",					  name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);#endif		}	}	if (flag) {		/* error recovery did not successfully complete */		printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,				STp->write_type == OS_WRITE_HEADER?"header":"body");	}	if (!pending)		osst_copy_to_buffer(STp->buffer, p);	/* so buffer content == at entry in all cases */	vfree((void *)buffer);	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/f9101210e7aa72daf92722d451a2f7e3af5f781f/osst.c/buggy/drivers/scsi/osst.c