📄 sbpcd.c
字号:
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 + -