if (current_drive->sbp_audsiz>0) vfree(current_drive->aud_buf); 
if (current_drive->sbp_audsiz>0) vfree(current_drive->aud_buf); 
static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,		      u_long arg){	struct sbpcd_drive *p = cdi->handle;	int i;		msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);	if (p->drv_id==-1) {		msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);		return (-ENXIO);             /* no such drive */	}	down(&ioctl_read_sem);	if (p != current_drive)		switch_drive(p);		msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);	switch (cmd) 		/* Sun-compatible */	{	case DDIOCSDBG:		/* DDI Debug */		if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);		i=sbpcd_dbg_ioctl(arg,1);		RETURN_UP(i);	case CDROMRESET:      /* hard reset the drive */		msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");		i=DriveReset();		current_drive->audio_state=0;		RETURN_UP(i);			case CDROMREADMODE1:		msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");#ifdef SAFE_MIXED		if (current_drive->has_data>1) RETURN_UP(-EBUSY);#endif /* SAFE_MIXED */		cc_ModeSelect(CD_FRAMESIZE);		cc_ModeSense();		current_drive->mode=READ_M1;		RETURN_UP(0);			case CDROMREADMODE2: /* not usable at the moment */		msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");#ifdef SAFE_MIXED		if (current_drive->has_data>1) RETURN_UP(-EBUSY);#endif /* SAFE_MIXED */		cc_ModeSelect(CD_FRAMESIZE_RAW1);		cc_ModeSense();		current_drive->mode=READ_M2;		RETURN_UP(0);			case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */		msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");		if (current_drive->sbp_audsiz>0) vfree(current_drive->aud_buf);		current_drive->aud_buf=NULL;		current_drive->sbp_audsiz=arg;				if (current_drive->sbp_audsiz>16)		{			current_drive->sbp_audsiz = 0;			RETURN_UP(current_drive->sbp_audsiz);		}			if (current_drive->sbp_audsiz>0)		{			current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);			if (current_drive->aud_buf==NULL)			{				msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);				current_drive->sbp_audsiz=0;			}			else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);		}		RETURN_UP(current_drive->sbp_audsiz);	case CDROMREADAUDIO:	{ /* start of CDROMREADAUDIO */		int i=0, j=0, frame, block=0;		u_int try=0;		u_long timeout;		u_char *p;		u_int data_tries = 0;		u_int data_waits = 0;		u_int data_retrying = 0;		int status_tries;		int error_flag;				msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");		if (fam0_drive) RETURN_UP(-EINVAL);		if (famL_drive) RETURN_UP(-EINVAL);		if (famV_drive) RETURN_UP(-EINVAL);		if (famT_drive) RETURN_UP(-EINVAL);#ifdef SAFE_MIXED		if (current_drive->has_data>1) RETURN_UP(-EBUSY);#endif /* SAFE_MIXED */ 		if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);		if (copy_from_user(&read_audio, (void __user *)arg,				   sizeof(struct cdrom_read_audio)))			RETURN_UP(-EFAULT);		if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);		if (!access_ok(VERIFY_WRITE, read_audio.buf,			      read_audio.nframes*CD_FRAMESIZE_RAW))                	RETURN_UP(-EFAULT);				if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */			block=msf2lba(&read_audio.addr.msf.minute);		else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */			block=read_audio.addr.lba;		else RETURN_UP(-EINVAL);#if 000		i=cc_SetSpeed(speed_150,0,0);		if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);#endif		msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",		    block, blk2msf(block));		msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");#if OLD_BUSY		while (busy_data) sbp_sleep(HZ/10); /* wait a bit */		busy_audio=1;#endif /* OLD_BUSY */ 		error_flag=0;		for (data_tries=5; data_tries>0; data_tries--)		{			msg(DBG_AUD,"data_tries=%d ...\n", data_tries);			current_drive->mode=READ_AU;			cc_ModeSelect(CD_FRAMESIZE_RAW);			cc_ModeSense();			for (status_tries=3; status_tries > 0; status_tries--)			{				flags_cmd_out |= f_respo3;				cc_ReadStatus();				if (sbp_status() != 0) break;				if (st_check) cc_ReadError();				sbp_sleep(1);    /* wait a bit, try again */			}			if (status_tries == 0)			{				msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);				continue;			}			msg(DBG_AUD,"read_audio: sbp_status: ok.\n");						flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;			if (fam0L_drive)			{				flags_cmd_out |= f_lopsta | f_getsta | f_bit1;				cmd_type=READ_M2;				drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */				drvcmd[1]=(block>>16)&0x000000ff;				drvcmd[2]=(block>>8)&0x000000ff;				drvcmd[3]=block&0x000000ff;				drvcmd[4]=0;				drvcmd[5]=read_audio.nframes; /* # of frames */				drvcmd[6]=0;			}			else if (fam1_drive)			{				drvcmd[0]=CMD1_READ; /* "read frames", new drives */				lba2msf(block,&drvcmd[1]); /* msf-bin format required */				drvcmd[4]=0;				drvcmd[5]=0;				drvcmd[6]=read_audio.nframes; /* # of frames */			}			else if (fam2_drive)			{				drvcmd[0]=CMD2_READ_XA2;				lba2msf(block,&drvcmd[1]); /* msf-bin format required */				drvcmd[4]=0;				drvcmd[5]=read_audio.nframes; /* # of frames */				drvcmd[6]=0x11; /* raw mode */			}			else if (famT_drive) /* CD-55A: not tested yet */			{			}			msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");			flags_cmd_out=f_putcmd;			response_count=0;			i=cmd_out();			if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);			sbp_sleep(0);			msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");			for (frame=1;frame<2 && !error_flag; frame++)			{				try=maxtim_data;				for (timeout=jiffies+9*HZ; ; )				{					for ( ; try!=0;try--)					{						j=inb(CDi_status);						if (!(j&s_not_data_ready)) break;						if (!(j&s_not_result_ready)) break;						if (fam0L_drive) if (j&s_attention) break;					}					if (try != 0 || time_after_eq(jiffies, timeout)) break;					if (data_retrying == 0) data_waits++;					data_retrying = 1;					sbp_sleep(1);					try = 1;				}				if (try==0)				{					msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");					error_flag++;					break;				}				msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");				if (j&s_not_data_ready)				{					msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");					error_flag++;					break;				}				msg(DBG_AUD,"read_audio: before reading data.\n");				error_flag=0;				p = current_drive->aud_buf;				if (sbpro_type==1) OUT(CDo_sel_i_d,1);				if (do_16bit)				{					u_short *p2 = (u_short *) p;					for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)				  	{						if ((inb_p(CDi_status)&s_not_data_ready)) continue;						/* get one sample */						*p2++ = inw_p(CDi_data);						*p2++ = inw_p(CDi_data);					}				} else {					for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)				  	{						if ((inb_p(CDi_status)&s_not_data_ready)) continue;						/* get one sample */						*p++ = inb_p(CDi_data);						*p++ = inb_p(CDi_data);						*p++ = inb_p(CDi_data);						*p++ = inb_p(CDi_data);					}				}				if (sbpro_type==1) OUT(CDo_sel_i_d,0);				data_retrying = 0;			}			msg(DBG_AUD,"read_audio: after reading data.\n");			if (error_flag)    /* must have been spurious D_RDY or (ATTN&&!D_RDY) */			{				msg(DBG_AUD,"read_audio: read aborted by drive\n");#if 0000				i=cc_DriveReset();                /* ugly fix to prevent a hang */#else				i=cc_ReadError();#endif				continue;			}			if (fam0L_drive)			{				i=maxtim_data;				for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)				{					for ( ;i!=0;i--)					{						j=inb(CDi_status);						if (!(j&s_not_data_ready)) break;						if (!(j&s_not_result_ready)) break;						if (j&s_attention) break;					}					if (i != 0 || time_after_eq(jiffies, timeout)) break;					sbp_sleep(0);					i = 1;				}				if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");				if (!(j&s_attention))				{					msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");					i=cc_DriveReset();  /* ugly fix to prevent a hang */					continue;				}			}			do			{				if (fam0L_drive) cc_ReadStatus();				i=ResponseStatus();  /* builds status_bits, returns orig. status (old) or faked p_success (new) */				if (i<0) { msg(DBG_AUD,					       "read_audio: cc_ReadStatus error after read: %02X\n",					       current_drive->status_bits);					   continue; /* FIXME */				   }			}			while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));			if (st_check)			{				i=cc_ReadError();				msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);				continue;			}			if (copy_to_user(read_audio.buf,					 current_drive->aud_buf,					 read_audio.nframes * CD_FRAMESIZE_RAW))				RETURN_UP(-EFAULT);			msg(DBG_AUD,"read_audio: copy_to_user done.\n");			break;		}		cc_ModeSelect(CD_FRAMESIZE);		cc_ModeSense();		current_drive->mode=READ_M1;#if OLD_BUSY		busy_audio=0;#endif /* OLD_BUSY */ 		if (data_tries == 0)		{			msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);			RETURN_UP(-EIO);		}		msg(DBG_AUD,"read_audio: successful return.\n");		RETURN_UP(0);	} /* end of CDROMREADAUDIO */			default:		msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);		RETURN_UP(-EINVAL);	} /* end switch(cmd) */}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/f9101210e7aa72daf92722d451a2f7e3af5f781f/sbpcd.c/clean/drivers/cdrom/sbpcd.c