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

📄 sbpcd.c

📁 cdrom device drive for linux.
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif /* DISTRIBUTION */

	char buf[256];
	va_list args;
	
	if (!(sbpcd_debug&(1<<level))) return;
	
	msgnum++;
	if (msgnum>99) msgnum=0;
	sprintf(buf, MSG_LEVEL "%s-%d [%02d]:  ", major_name, d, msgnum);
	va_start(args, fmt);
	vsprintf(&buf[18], fmt, args);
	va_end(args);
	printk(buf);
#if KLOGD_PAUSE
	sbp_sleep(KLOGD_PAUSE); /* else messages get lost */
#endif /* KLOGD_PAUSE */ 
	return;
}
/*==========================================================================*/
/*
 * DDI interface: runtime trace bit pattern maintenance
 */
static int sbpcd_dbg_ioctl(unsigned long arg, int level)
{
	switch(arg)
	{
	case 0:	/* OFF */
		sbpcd_debug = DBG_INF;
		break;
		
	default:
		if (arg>=128) sbpcd_debug &= ~(1<<(arg-128));
		else sbpcd_debug |= (1<<arg);
	}
	return (arg);
}
/*==========================================================================*/
static void mark_timeout_delay(u_long i)
{
	timed_out_delay=1;
#if 0
	msg(DBG_TIM,"delay timer expired.\n");
#endif
}
/*==========================================================================*/
static void mark_timeout_data(u_long i)
{
	timed_out_data=1;
#if 0
	msg(DBG_TIM,"data timer expired.\n");
#endif
}
/*==========================================================================*/
#if 0
static void mark_timeout_audio(u_long i)
{
	timed_out_audio=1;
#if 0
	msg(DBG_TIM,"audio timer expired.\n");
#endif
}
#endif
/*==========================================================================*/
/*
 * Wait a little while (used for polling the drive).
 */
static void sbp_sleep(u_int time)
{
	sti();
	current->state = TASK_INTERRUPTIBLE;
	schedule_timeout(time);
	sti();
}
/*==========================================================================*/
#define RETURN_UP(rc) {up(&ioctl_read_sem); return(rc);}
/*==========================================================================*/
/*
 *  convert logical_block_address to m-s-f_number (3 bytes only)
 */
static INLINE void lba2msf(int lba, u_char *msf)
{
	lba += CD_MSF_OFFSET;
	msf[0] = lba / (CD_SECS*CD_FRAMES);
	lba %= CD_SECS*CD_FRAMES;
	msf[1] = lba / CD_FRAMES;
	msf[2] = lba % CD_FRAMES;
}
/*==========================================================================*/
/*==========================================================================*/
/*
 *  convert msf-bin to msf-bcd
 */
static INLINE void bin2bcdx(u_char *p)  /* must work only up to 75 or 99 */
{
	*p=((*p/10)<<4)|(*p%10);
}
/*==========================================================================*/
static INLINE u_int blk2msf(u_int blk)
{
	MSF msf;
	u_int mm;
	
	msf.c[3] = 0;
	msf.c[2] = (blk + CD_MSF_OFFSET) / (CD_SECS * CD_FRAMES);
	mm = (blk + CD_MSF_OFFSET) % (CD_SECS * CD_FRAMES);
	msf.c[1] = mm / CD_FRAMES;
	msf.c[0] = mm % CD_FRAMES;
	return (msf.n);
}
/*==========================================================================*/
static INLINE u_int make16(u_char rh, u_char rl)
{
	return ((rh<<8)|rl);
}
/*==========================================================================*/
static INLINE u_int make32(u_int rh, u_int rl)
{
	return ((rh<<16)|rl);
}
/*==========================================================================*/
static INLINE u_char swap_nibbles(u_char i)
{
	return ((i<<4)|(i>>4));
}
/*==========================================================================*/
static INLINE u_char byt2bcd(u_char i)
{
	return (((i/10)<<4)+i%10);
}
/*==========================================================================*/
static INLINE u_char bcd2bin(u_char bcd)
{
	return ((bcd>>4)*10+(bcd&0x0F));
}
/*==========================================================================*/
static INLINE int msf2blk(int msfx)
{
	MSF msf;
	int i;
	
	msf.n=msfx;
	i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_MSF_OFFSET;
	if (i<0) return (0);
	return (i);
}
/*==========================================================================*/
/*
 *  convert m-s-f_number (3 bytes only) to logical_block_address 
 */
static INLINE int msf2lba(u_char *msf)
{
	int i;
	
	i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_MSF_OFFSET;
	if (i<0) return (0);
	return (i);
}
/*==========================================================================*/
/* evaluate cc_ReadError code */ 
static int sta2err(int sta)
{
	if (famT_drive)
	{
		if (sta==0x00) return (0);
		if (sta==0x01) return (-604); /* CRC error */
		if (sta==0x02) return (-602); /* drive not ready */
		if (sta==0x03) return (-607); /* unknown media */
		if (sta==0x04) return (-612); /* general failure */
		if (sta==0x05) return (0);
		if (sta==0x06) return (-ERR_DISKCHANGE); /* disk change */
		if (sta==0x0b) return (-612); /* general failure */
		if (sta==0xff) return (-612); /* general failure */
		return (0);
	}
	else
	{
		if (sta<=2) return (sta);
		if (sta==0x05) return (-604); /* CRC error */
		if (sta==0x06) return (-606); /* seek error */
		if (sta==0x0d) return (-606); /* seek error */
		if (sta==0x0e) return (-603); /* unknown command */
		if (sta==0x14) return (-603); /* unknown command */
		if (sta==0x0c) return (-611); /* read fault */
		if (sta==0x0f) return (-611); /* read fault */
		if (sta==0x10) return (-611); /* read fault */
		if (sta>=0x16) return (-612); /* general failure */
		if (sta==0x11) return (-ERR_DISKCHANGE); /* disk change (LCS: removed) */
		if (famL_drive)
			if (sta==0x12) return (-ERR_DISKCHANGE); /* disk change (inserted) */
		return (-602); /* drive not ready */
	}
}
/*==========================================================================*/
static INLINE void clr_cmdbuf(void)
{
	int i;
	
	for (i=0;i<10;i++) drvcmd[i]=0;
	cmd_type=0;
}
/*==========================================================================*/
static void flush_status(void)
{
	int i;
	
	sbp_sleep(15*HZ/10);
	for (i=maxtim_data;i!=0;i--) inb(CDi_status);
}
/*====================================================================*/
/*
 * CDi status loop for Teac CD-55A (Rob Riggs)
 *
 * This is needed because for some strange reason
 * the CD-55A can take a real long time to give a
 * status response. This seems to happen after we
 * issue a READ command where a long seek is involved.
 *
 * I tried to ensure that we get max throughput with
 * minimal busy waiting. We busy wait at first, then
 * "switch gears" and start sleeping. We sleep for
 * longer periods of time the longer we wait.
 *
 */
static int CDi_stat_loop_T(void)
{
	int	i, gear=1;
	u_long  timeout_1, timeout_2, timeout_3, timeout_4;

	timeout_1 = jiffies + HZ / 50;  /* sbp_sleep(0) for a short period */
	timeout_2 = jiffies + HZ / 5;	/* nap for no more than 200ms */
	timeout_3 = jiffies + 5 * HZ;	/* sleep for up to 5s */
	timeout_4 = jiffies + 45 * HZ;	/* long sleep for up to 45s. */
	do
          {
            i = inb(CDi_status);
            if (!(i&s_not_data_ready)) return (i);
            if (!(i&s_not_result_ready)) return (i);
            switch(gear)
              {
              case 4:
                sbp_sleep(HZ);
                if (time_after(jiffies, timeout_4)) gear++;
                msg(DBG_TEA, "CDi_stat_loop_T: long sleep active.\n");
                break;
              case 3:
                sbp_sleep(HZ/10);
                if (time_after(jiffies, timeout_3)) gear++;
                break;
              case 2:
                sbp_sleep(HZ/100);
                if (time_after(jiffies, timeout_2)) gear++;
                break;
              case 1:
                sbp_sleep(0);
                if (time_after(jiffies, timeout_1)) gear++;
              }
          } while (gear < 5);
	return -1;
}
/*==========================================================================*/
static int CDi_stat_loop(void)
{
	int i,j;
	
	for(timeout = jiffies + 10*HZ, i=maxtim_data; time_before(jiffies, timeout); )
	{
		for ( ;i!=0;i--)
		{
			j=inb(CDi_status);
			if (!(j&s_not_data_ready)) return (j);
			if (!(j&s_not_result_ready)) return (j);
			if (fam0L_drive) if (j&s_attention) return (j);
		}
		sbp_sleep(1);
		i = 1;
	}
	msg(DBG_LCS,"CDi_stat_loop failed in line %d\n", __LINE__);
	return (-1);
}
/*==========================================================================*/
#if 00000
/*==========================================================================*/
static int tst_DataReady(void)
{
	int i;
	
	i=inb(CDi_status);
	if (i&s_not_data_ready) return (0);
	return (1);
}
/*==========================================================================*/
static int tst_ResultReady(void)
{
	int i;
	
	i=inb(CDi_status);
	if (i&s_not_result_ready) return (0);
	return (1);
}
/*==========================================================================*/
static int tst_Attention(void)
{
	int i;
	
	i=inb(CDi_status);
	if (i&s_attention) return (1);
	return (0);
}
/*==========================================================================*/
#endif
/*==========================================================================*/
static int ResponseInfo(void)
{
	int i,j,st=0;
	u_long timeout;
	
	for (i=0,timeout=jiffies+HZ;i<response_count;i++) 
	{
		for (j=maxtim_data; ; )
		{
			for ( ;j!=0;j-- )
			{
				st=inb(CDi_status);
				if (!(st&s_not_result_ready)) break;
			}
			if ((j!=0)||time_after_eq(jiffies, timeout)) break;
			sbp_sleep(1);
			j = 1;
		}
		if (time_after_eq(jiffies, timeout)) break;
		infobuf[i]=inb(CDi_info);
	}
#if 000
	while (!(inb(CDi_status)&s_not_result_ready))
	{
		infobuf[i++]=inb(CDi_info);
	}
	j=i-response_count;
	if (j>0) msg(DBG_INF,"ResponseInfo: got %d trailing bytes.\n",j);
#endif /* 000 */
	for (j=0;j<i;j++)
		sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
	msgbuf[j*3]=0;
	msg(DBG_CMD,"ResponseInfo:%s (%d,%d)\n",msgbuf,response_count,i);
	j=response_count-i;
	if (j>0) return (-j);
	else return (i);
}
/*==========================================================================*/
static void EvaluateStatus(int st)
{
	D_S[d].status_bits=0;
	if (fam1_drive) D_S[d].status_bits=st|p_success;
	else if (fam0_drive)
	{
		if (st&p_caddin_old) D_S[d].status_bits |= p_door_closed|p_caddy_in;
		if (st&p_spinning) D_S[d].status_bits |= p_spinning;
		if (st&p_check) D_S[d].status_bits |= p_check;
 		if (st&p_success_old) D_S[d].status_bits |= p_success;
 		if (st&p_busy_old) D_S[d].status_bits |= p_busy_new;
		if (st&p_disk_ok) D_S[d].status_bits |= p_disk_ok;
	}
	else if (famLV_drive)
	{
 		D_S[d].status_bits |= p_success;
		if (st&p_caddin_old) D_S[d].status_bits |= p_disk_ok|p_caddy_in;
		if (st&p_spinning) D_S[d].status_bits |= p_spinning;
		if (st&p_check) D_S[d].status_bits |= p_check;
		if (st&p_busy_old) D_S[d].status_bits |= p_busy_new;
		if (st&p_lcs_door_closed) D_S[d].status_bits |= p_door_closed;
		if (st&p_lcs_door_locked) D_S[d].status_bits |= p_door_locked;
	}
	else if (fam2_drive)
	{
 		D_S[d].status_bits |= p_success;
		if (st&p2_check) D_S[d].status_bits |= p1_check;
		if (st&p2_door_closed) D_S[d].status_bits |= p1_door_closed;
		if (st&p2_disk_in) D_S[d].status_bits |= p1_disk_in;
		if (st&p2_busy1) D_S[d].status_bits |= p1_busy;
		if (st&p2_busy2) D_S[d].status_bits |= p1_busy;
		if (st&p2_spinning) D_S[d].status_bits |= p1_spinning;
		if (st&p2_door_locked) D_S[d].status_bits |= p1_door_locked;
		if (st&p2_disk_ok) D_S[d].status_bits |= p1_disk_ok;
	}
	else if (famT_drive)
	{
		return; /* still needs to get coded */
 		D_S[d].status_bits |= p_success;
		if (st&p2_check) D_S[d].status_bits |= p1_check;
		if (st&p2_door_closed) D_S[d].status_bits |= p1_door_closed;
		if (st&p2_disk_in) D_S[d].status_bits |= p1_disk_in;
		if (st&p2_busy1) D_S[d].status_bits |= p1_busy;
		if (st&p2_busy2) D_S[d].status_bits |= p1_busy;
		if (st&p2_spinning) D_S[d].status_bits |= p1_spinning;
		if (st&p2_door_locked) D_S[d].status_bits |= p1_door_locked;
		if (st&p2_disk_ok) D_S[d].status_bits |= p1_disk_ok;
	}
	return;
}
/*==========================================================================*/
static int get_state_T(void)
{
	int i;
	

⌨️ 快捷键说明

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