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

📄 sbpcd.c

📁 cdrom device drive for linux.
💻 C
📖 第 1 页 / 共 5 页
字号:
	static int cmd_out_T(void);

	clr_cmdbuf();
	D_S[d].n_bytes=1;
	drvcmd[0]=CMDT_STATUS;
	i=cmd_out_T();
	if (i>=0) i=infobuf[0];
	else
	{
		msg(DBG_TEA,"get_state_T error %d\n", i);
		return (i);
	}
	if (i>=0)
		/* 2: closed, disk in */
		D_S[d].status_bits=p1_door_closed|p1_disk_in|p1_spinning|p1_disk_ok;
	else if (D_S[d].error_state==6)
	{
		/* 3: closed, disk in, changed ("06 xx xx") */
		D_S[d].status_bits=p1_door_closed|p1_disk_in;
		D_S[d].CD_changed=0xFF;
		D_S[d].diskstate_flags &= ~toc_bit;
	}
	else if ((D_S[d].error_state!=2)||(D_S[d].b3!=0x3A)||(D_S[d].b4==0x00))
	{
		/* 1: closed, no disk ("xx yy zz"or "02 3A 00") */
		D_S[d].status_bits=p1_door_closed;
		D_S[d].open_count=0;
	}
	else if (D_S[d].b4==0x01)
	{
		/* 0: open ("02 3A 01") */
		D_S[d].status_bits=0;
		D_S[d].open_count=0;
	}
	else
	{
		/* 1: closed, no disk ("02 3A xx") */
		D_S[d].status_bits=p1_door_closed;
		D_S[d].open_count=0;
	}
	return (D_S[d].status_bits);
}
/*==========================================================================*/
static int ResponseStatus(void)
{
	int i,j;
	u_long timeout;
	
	msg(DBG_STA,"doing ResponseStatus...\n");
	if (famT_drive) return (get_state_T());
	if (flags_cmd_out & f_respo3) timeout = jiffies;
	else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
	else timeout = jiffies + 4*HZ;
	j=maxtim_8;
	do
	{
		for ( ;j!=0;j--)
		{ 
			i=inb(CDi_status);
			if (!(i&s_not_result_ready)) break;
		}
		if ((j!=0)||time_after(jiffies, timeout)) break;
		sbp_sleep(1);
		j = 1;
	}
	while (1);
	if (j==0) 
	{
		if ((flags_cmd_out & f_respo3) == 0)
			msg(DBG_STA,"ResponseStatus: timeout.\n");
		D_S[d].status_bits=0;
		return (-401);
	}
	i=inb(CDi_info);
	msg(DBG_STA,"ResponseStatus: response %02X.\n", i);
	EvaluateStatus(i);
	msg(DBG_STA,"status_bits=%02X, i=%02X\n",D_S[d].status_bits,i);
	return (D_S[d].status_bits);
}
/*==========================================================================*/
static void cc_ReadStatus(void)
{
	int i;
	
	msg(DBG_STA,"giving cc_ReadStatus command\n");
	if (famT_drive) return;
	SBPCD_CLI;
	if (fam0LV_drive) OUT(CDo_command,CMD0_STATUS);
	else if (fam1_drive) OUT(CDo_command,CMD1_STATUS);
	else if (fam2_drive) OUT(CDo_command,CMD2_STATUS);
	if (!fam0LV_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
	SBPCD_STI;
}
/*==========================================================================*/
static int cc_ReadError(void)
{
	int i;

	clr_cmdbuf();
	msg(DBG_ERR,"giving cc_ReadError command.\n");
	if (fam1_drive)
	{
		drvcmd[0]=CMD1_READ_ERR;
		response_count=8;
		flags_cmd_out=f_putcmd|f_ResponseStatus;
	}
	else if (fam0LV_drive)
	{
		drvcmd[0]=CMD0_READ_ERR;
		response_count=6;
		if (famLV_drive)
			flags_cmd_out=f_putcmd;
		else
			flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
	}
	else if (fam2_drive)
	{
		drvcmd[0]=CMD2_READ_ERR;
		response_count=6;
		flags_cmd_out=f_putcmd;
	}
	else if (famT_drive)
	{
		response_count=5;
		drvcmd[0]=CMDT_READ_ERR;
	}
	i=cmd_out();
	D_S[d].error_byte=0;
	msg(DBG_ERR,"cc_ReadError: cmd_out(CMDx_READ_ERR) returns %d (%02X)\n",i,i);
	if (i<0) return (i);
	if (fam0V_drive) i=1;
	else i=2;
	D_S[d].error_byte=infobuf[i];
	msg(DBG_ERR,"cc_ReadError: infobuf[%d] is %d (%02X)\n",i,D_S[d].error_byte,D_S[d].error_byte);
	i=sta2err(infobuf[i]);
        if (i==-ERR_DISKCHANGE)
        {
                D_S[d].CD_changed=0xFF;
                D_S[d].diskstate_flags &= ~toc_bit;
        }
	return (i);
}
/*==========================================================================*/
static int cmd_out_T(void)
{
#undef CMDT_TRIES
#define CMDT_TRIES 1000
#define TEST_FALSE_FF 1
	
	static int cc_DriveReset(void);
	int i, j, l=0, m, ntries;
	long flags;

	D_S[d].error_state=0;
	D_S[d].b3=0;
	D_S[d].b4=0;
	D_S[d].f_drv_error=0;
	for (i=0;i<10;i++) sprintf(&msgbuf[i*3]," %02X",drvcmd[i]);
	msgbuf[i*3]=0;
	msg(DBG_CMD,"cmd_out_T:%s\n",msgbuf);

	OUT(CDo_sel_i_d,0);
	OUT(CDo_enable,D_S[d].drv_sel);
	i=inb(CDi_status);
	do_16bit=0;
	if ((f_16bit)&&(!(i&0x80)))
	{
		do_16bit=1;
		msg(DBG_TEA,"cmd_out_T: do_16bit set.\n");
	}
	if (!(i&s_not_result_ready))
	do
	{
		j=inb(CDi_info);
		i=inb(CDi_status);
		sbp_sleep(0);
		msg(DBG_TEA,"cmd_out_T: spurious !s_not_result_ready. (%02X)\n", j);
	}
	while (!(i&s_not_result_ready));
	save_flags(flags); cli();
	for (i=0;i<10;i++) OUT(CDo_command,drvcmd[i]);
	restore_flags(flags);
	for (ntries=CMDT_TRIES;ntries>0;ntries--)
	{
		if (drvcmd[0]==CMDT_READ_VER) sbp_sleep(HZ); /* fixme */
#if 01
		OUT(CDo_sel_i_d,1);
#endif /* 01 */
		if (teac==2)
                  {
                    if ((i=CDi_stat_loop_T()) == -1) break;
                  }
		else
                  {
#if 0
                    OUT(CDo_sel_i_d,1);
#endif /* 0 */ 
                    i=inb(CDi_status);
                  }
		if (!(i&s_not_data_ready)) /* f.e. CMDT_DISKINFO */
		{
			OUT(CDo_sel_i_d,1);
			if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
			if (drvcmd[0]==CMDT_DISKINFO)
			{
				l=0;
				do
                                {
                                        if (do_16bit)
                                        {
                                                i=inw(CDi_data);
                                                infobuf[l++]=i&0x0ff;
                                                infobuf[l++]=i>>8;
#if TEST_FALSE_FF
                                                if ((l==2)&&(infobuf[0]==0x0ff))
                                                {
                                                        infobuf[0]=infobuf[1];
                                                        l=1;
                                                        msg(DBG_TEA,"cmd_out_T: do_16bit: false first byte!\n");
                                                }
#endif /* TEST_FALSE_FF */ 
                                        }
                                        else infobuf[l++]=inb(CDi_data);
                                        i=inb(CDi_status);
                                }
				while (!(i&s_not_data_ready));
				for (j=0;j<l;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
				msgbuf[j*3]=0;
				msg(DBG_CMD,"cmd_out_T data response:%s\n", msgbuf);
			}
			else
			{
				msg(DBG_TEA,"cmd_out_T: data response with cmd_%02X!\n",
                                    drvcmd[0]);
				j=0;
				do
				{
                                        if (do_16bit) i=inw(CDi_data);
                                        else i=inb(CDi_data);
                                        j++;
                                        i=inb(CDi_status);
				}
				while (!(i&s_not_data_ready));
				msg(DBG_TEA,"cmd_out_T: data response: discarded %d bytes/words.\n", j);
				fatal_err++;
			}
		}
		i=inb(CDi_status);
		if (!(i&s_not_result_ready))
		{
			OUT(CDo_sel_i_d,0);
			if (drvcmd[0]==CMDT_DISKINFO) m=l;
			else m=0;
			do
			{
				infobuf[m++]=inb(CDi_info);
				i=inb(CDi_status);
			}
			while (!(i&s_not_result_ready));
			for (j=0;j<m;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
			msgbuf[j*3]=0;
			msg(DBG_CMD,"cmd_out_T info response:%s\n", msgbuf);
			if (drvcmd[0]==CMDT_DISKINFO)
                        {
                                infobuf[0]=infobuf[l];
                                if (infobuf[0]!=0x02) return (l); /* data length */
                        }
			else if (infobuf[0]!=0x02) return (m); /* info length */
			do
			{
				++recursion;
				if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (%02X): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", drvcmd[0], recursion);
				clr_cmdbuf();
				drvcmd[0]=CMDT_READ_ERR;
				j=cmd_out_T(); /* !!! recursive here !!! */
				--recursion;
				sbp_sleep(1);
			}
			while (j<0);
			D_S[d].error_state=infobuf[2];
			D_S[d].b3=infobuf[3];
			D_S[d].b4=infobuf[4];
			if (D_S[d].f_drv_error)
			{
				D_S[d].f_drv_error=0;
				cc_DriveReset();
				D_S[d].error_state=2;
			}
			return (-D_S[d].error_state-400);
		}
		if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
		if ((teac==0)||(ntries<(CMDT_TRIES-5))) sbp_sleep(HZ/10);
		else sbp_sleep(HZ/100);
		if (ntries>(CMDT_TRIES-50)) continue;
		msg(DBG_TEA,"cmd_out_T: next CMDT_TRIES (%02X): %d.\n", drvcmd[0], ntries-1);
	}
	D_S[d].f_drv_error=1;
	cc_DriveReset();
	D_S[d].error_state=2;
	return (-99);
}
/*==========================================================================*/
static int cmd_out(void)
{
	int i=0;
	
	if (famT_drive) return(cmd_out_T());
	
	if (flags_cmd_out&f_putcmd)
	{ 
		unsigned long flags;
		for (i=0;i<7;i++)
			sprintf(&msgbuf[i*3], " %02X", drvcmd[i]);
		msgbuf[i*3]=0;
		msg(DBG_CMD,"cmd_out:%s\n", msgbuf);
		save_flags(flags); cli();
		for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
		restore_flags(flags);
	}
	if (response_count!=0)
	{
		if (cmd_type!=0)
		{
			if (sbpro_type==1) OUT(CDo_sel_i_d,1);
			msg(DBG_INF,"misleaded to try ResponseData.\n");
			if (sbpro_type==1) OUT(CDo_sel_i_d,0);
			return (-22);
		}
		else i=ResponseInfo();
		if (i<0) return (i);
	}
	if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to CDi_stat_loop.\n");
	if (flags_cmd_out&f_lopsta)
	{
		i=CDi_stat_loop();
		if ((i<0)||!(i&s_attention)) return (-8);
	}
	if (!(flags_cmd_out&f_getsta)) goto LOC_229;
	
 LOC_228:
	if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadStatus.\n");
	cc_ReadStatus();
	
 LOC_229:
	if (flags_cmd_out&f_ResponseStatus) 
	{
		if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n");
		i=ResponseStatus();
		/* builds status_bits, returns orig. status or p_busy_new */
		if (i<0) return (i);
		if (flags_cmd_out&(f_bit1|f_wait_if_busy))
		{
			if (!st_check)
			{
				if ((flags_cmd_out&f_bit1)&&(i&p_success)) goto LOC_232;
				if ((!(flags_cmd_out&f_wait_if_busy))||(!st_busy)) goto LOC_228;
			}
		}
	}
 LOC_232:
	if (!(flags_cmd_out&f_obey_p_check)) return (0);
	if (!st_check) return (0);
	if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadError.\n");
	i=cc_ReadError();
	if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cmd_out OK.\n");
	msg(DBG_000,"cmd_out: cc_ReadError=%d\n", i);
	return (i);
}
/*==========================================================================*/
static int cc_Seek(u_int pos, char f_blk_msf)
{
	int i;
	
  clr_cmdbuf();
	if (f_blk_msf>1) return (-3);
	if (fam0V_drive)
	{
		drvcmd[0]=CMD0_SEEK;
		if (f_blk_msf==1) pos=msf2blk(pos);
		drvcmd[2]=(pos>>16)&0x00FF;
		drvcmd[3]=(pos>>8)&0x00FF;
		drvcmd[4]=pos&0x00FF;
		if (fam0_drive)
		  flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
			f_ResponseStatus | f_obey_p_check | f_bit1;
		else
		  flags_cmd_out = f_putcmd;
	}
	else if (fam1L_drive)
	{
		drvcmd[0]=CMD1_SEEK; /* same as CMD1_ and CMDL_ */
		if (f_blk_msf==0) pos=blk2msf(pos);
		drvcmd[1]=(pos>>16)&0x00FF;
		drvcmd[2]=(pos>>8)&0x00FF;
		drvcmd[3]=pos&0x00FF;
		if (famL_drive)
			flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
		else
			flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
	}
	else if (fam2_drive)
	{
		drvcmd[0]=CMD2_SEEK;
		if (f_blk_msf==0) pos=blk2msf(pos);
		drvcmd[2]=(pos>>24)&0x00FF;

⌨️ 快捷键说明

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