?? sbpcd.c
字號:
}/*==========================================================================*/static u_char byt2bcd(u_char i){ return (((i/10)<<4)+i%10);}/*==========================================================================*/static u_char bcd2bin(u_char bcd){ return ((bcd>>4)*10+(bcd&0x0F));}/*==========================================================================*/static 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_BLOCK_OFFSET; if (i<0) return (0); return (i);}/*==========================================================================*//* evaluate xx_ReadError code (still mysterious) */ static int sta2err(int sta){ if (sta<=2) return (sta); if (sta==0x05) return (-4); if (sta==0x06) return (-6); if (sta==0x0d) return (-6); if (sta==0x0e) return (-3); if (sta==0x14) return (-3); if (sta==0x0c) return (-11); if (sta==0x0f) return (-11); if (sta==0x10) return (-11); if (sta>=0x16) return (-12); DS[d].CD_changed=0xFF; if (sta==0x11) return (-15); return (-2);}/*==========================================================================*/static void clr_cmdbuf(void){ int i; for (i=0;i<7;i++) drvcmd[i]=0; cmd_type=0;}/*==========================================================================*/static void mark_timeout(void){ timed_out=1; DPRINTF((DBG_TIM,"SBPCD: timer stopped.\n"));}/*==========================================================================*/static void flush_status(void){#ifdef CDMKE int i; if (current == task[0]) for (i=maxtim02;i!=0;i--) inb(CDi_status); else { sbp_sleep(150); for (i=maxtim_data;i!=0;i--) inb(CDi_status); }#else timed_out=0; SET_TIMER(mark_timeout,150); do { } while (!timed_out); CLEAR_TIMER; inb(CDi_status);#endif CDMKE}/*==========================================================================*/static int CDi_stat_loop(void){ int i,j; u_long timeout; if (current == task[0]) for(i=maxtim16;i!=0;i--) { j=inb(CDi_status); if (!(j&s_not_data_ready)) return (j); if (!(j&s_not_result_ready)) return (j); if (!new_drive) if (j&s_attention) return (j); } else for(timeout = jiffies + 1000, i=maxtim_data; timeout > jiffies; ) { 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 (!new_drive) if (j&s_attention) return (j); } sbp_sleep(1); i = 1; } return (-1);}/*==========================================================================*/static int ResponseInfo(void){ int i,j, st=0; u_long timeout; if (current == task[0]) for (i=0;i<response_count;i++) { for (j=maxtim_8;j!=0;j--) { st=inb(CDi_status); if (!(st&s_not_result_ready)) break; } if (j==0) return (-1); infobuf[i]=inb(CDi_info); } else { for (i=0, timeout = jiffies + 100; 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 || timeout <= jiffies) break; sbp_sleep(0); j = 1; } if (timeout <= jiffies) return (-1); infobuf[i]=inb(CDi_info); } } return (0);}/*==========================================================================*/static int EvaluateStatus(int st){ if (!new_drive) { DS[d].status_byte=0; if (st&p_caddin_old) DS[d].status_byte |= p_door_closed|p_caddy_in; if (st&p_spinning) DS[d].status_byte |= p_spinning; if (st&p_check) DS[d].status_byte |= p_check; if (st&p_busy_old) DS[d].status_byte |= p_busy_new; if (st&p_disk_ok) DS[d].status_byte |= p_disk_ok; } else { DS[d].status_byte=st; st=p_success_old; /* for new drives: fake "successful" bit of old drives */ } return (st);}/*==========================================================================*/static int ResponseStatus(void){ int i,j; u_long timeout; DPRINTF((DBG_STA,"SBPCD: doing ResponseStatus...\n")); if (current == task[0]) { if (flags_cmd_out & f_respo3) j = maxtim_8; else if (flags_cmd_out&f_respo2) j=maxtim16; else j=maxtim04; for (;j!=0;j--) { i=inb(CDi_status); if (!(i&s_not_result_ready)) break; } } else { if (flags_cmd_out & f_respo3) timeout = jiffies; else if (flags_cmd_out & f_respo2) timeout = jiffies + 1600; else timeout = jiffies + 400; j=maxtim_8; do { for ( ;j!=0;j--) { i=inb(CDi_status); if (!(i&s_not_result_ready)) break; } if (j != 0 || timeout <= jiffies) break; sbp_sleep(0); j = 1; } while (1); } if (j==0) { if ((flags_cmd_out & f_respo3) == 0) DPRINTF((DBG_STA,"SBPCD: ResponseStatus: timeout.\n")); EvaluateStatus(0); return (-1); } i=inb(CDi_info); i=EvaluateStatus(i); return (i);}/*==========================================================================*/static void xx_ReadStatus(void){ int i; DPRINTF((DBG_STA,"SBPCD: giving xx_ReadStatus command\n")); if (!new_drive) OUT(CDo_command,0x81); else {#if SBPCD_DIS_IRQ cli();#endif SBPCD_DIS_IRQ OUT(CDo_command,0x05); for (i=0;i<6;i++) OUT(CDo_command,0);#if SBPCD_DIS_IRQ sti();#endif SBPCD_DIS_IRQ }}/*==========================================================================*/int xx_ReadError(void){ int cmd_out(void); int i; clr_cmdbuf(); DPRINTF((DBG_ERR,"SBPCD: giving xx_ReadError command.\n")); if (new_drive) { drvcmd[0]=0x82; response_count=8; flags_cmd_out=f_putcmd|f_ResponseStatus; } else { drvcmd[0]=0x82; response_count=6; flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus; } i=cmd_out(); DS[d].error_byte=0; DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: cmd_out(82) returns %d (%02X)\n",i,i)); if (i<0) return (i); if (new_drive) i=2; else i=1; DS[d].error_byte=infobuf[i]; DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: infobuf[%d] is %d (%02X)\n",i,DS[d].error_byte,DS[d].error_byte)); i=sta2err(infobuf[i]); return (i);}/*==========================================================================*/int cmd_out(void){ int i=0; if (flags_cmd_out&f_putcmd) { DPRINTF((DBG_CMD,"SBPCD: cmd_out: put")); for (i=0;i<7;i++) DPRINTF((DBG_CMD," %02X",drvcmd[i])); DPRINTF((DBG_CMD,"\n"));#if SBPCD_DIS_IRQ cli();#endif SBPCD_DIS_IRQ for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);#if SBPCD_DIS_IRQ sti();#endif SBPCD_DIS_IRQ } if (response_count!=0) { if (cmd_type!=0) { if (sbpro_type) OUT(CDo_sel_d_i,0x01); DPRINTF((DBG_INF,"SBPCD: misleaded to try ResponseData.\n")); if (sbpro_type) OUT(CDo_sel_d_i,0x00); } else i=ResponseInfo(); if (i<0) return (-9); } if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to CDi_stat_loop.\n")); if (flags_cmd_out&f_lopsta) { i=CDi_stat_loop(); if ((i<0)||!(i&s_attention)) return (-9); } if (!(flags_cmd_out&f_getsta)) goto LOC_229; LOC_228: if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadStatus.\n")); xx_ReadStatus();LOC_229: if (flags_cmd_out&f_ResponseStatus) { if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to ResponseStatus.\n")); i=ResponseStatus(); /* builds status_byte, returns orig. status or p_busy_new */ if (i<0) return (-9); if (flags_cmd_out&(f_bit1|f_wait_if_busy)) { if (!st_check) { if (flags_cmd_out&f_bit1) if (i&p_success_old) goto LOC_232; if (!(flags_cmd_out&f_wait_if_busy)) goto LOC_228; if (!st_busy) goto LOC_228; } } }LOC_232: if (!(flags_cmd_out&f_obey_p_check)) return (0); if (!st_check) return (0); if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadError.\n")); i=xx_ReadError(); if (DS[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to cmd_out OK.\n")); return (i);}/*==========================================================================*/static int xx_Seek(u_int pos, char f_blk_msf){ int i; clr_cmdbuf(); if (f_blk_msf>1) return (-3); if (!new_drive) { if (f_blk_msf==1) pos=msf2blk(pos); drvcmd[2]=(pos>>16)&0x00FF; drvcmd[3]=(pos>>8)&0x00FF; drvcmd[4]=pos&0x00FF; flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta | f_ResponseStatus | f_obey_p_check | f_bit1; } else { if (f_blk_msf==0) pos=blk2msf(pos); drvcmd[1]=(pos>>16)&0x00FF; drvcmd[2]=(pos>>8)&0x00FF; drvcmd[3]=pos&0x00FF; flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; } drvcmd[0]=0x01; response_count=0; i=cmd_out(); return (i);}/*==========================================================================*/static int xx_SpinUp(void){ int i; DPRINTF((DBG_SPI,"SBPCD: SpinUp.\n")); DS[d].in_SpinUp = 1; clr_cmdbuf(); if (!new_drive) { drvcmd[0]=0x05; flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1; } else { drvcmd[0]=0x02; flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; } response_count=0; i=cmd_out(); DS[d].in_SpinUp = 0; return (i);}/*==========================================================================*/static int yy_SpinDown(void){ int i; if (!new_drive) return (-3); clr_cmdbuf(); drvcmd[0]=0x06; flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; response_count=0; i=cmd_out(); return (i);}/*==========================================================================*/static int yy_SetSpeed(u_char speed, u_char x1, u_char x2){ int i; if (!new_drive) return (-3); clr_cmdbuf(); drvcmd[0]=0x09; drvcmd[1]=0x03; drvcmd[2]=speed; drvcmd[3]=x1; drvcmd[4]=x2; flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; response_count=0; i=cmd_out(); return (i);}/*==========================================================================*/static int xx_SetVolume(void){ int i; u_char channel0,channel1,volume0,volume1; u_char control0,value0,control1,value1; DS[d].diskstate_flags &= ~volume_bit; clr_cmdbuf(); channel0=DS[d].vol_chan0; volume0=DS[d].vol_ctrl0; channel1=control1=DS[d].vol_chan1; volume1=value1=DS[d].vol_ctrl1; control0=value0=0; if (((DS[d].drv_options&sax_a)!=0)&&(DS[d].drv_type>=drv_211)) { if ((volume0!=0)&&(volume1==0)) { volume1=volume0; channel1=channel0; } else if ((volume0==0)&&(volume1!=0)) { volume0=volume1; channel0=channel1; } } if (channel0>1) { channel0=0; volume0=0; } if (channel1>1) { channel1=1; volume1=0; } if (new_drive) { control0=channel0+1; control1=channel1+1; value0=(volume0>volume1)?volume0:volume1; value1=value0; if (volume0==0) control0=0; if (volume1==0) control1=0; drvcmd[0]=0x09; drvcmd[1]=0x05; drvcmd[3]=control0; drvcmd[4]=value0; drvcmd[5]=control1; drvcmd[6]=value1; flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; } else { if (DS[d].drv_type>=drv_300) { control0=volume0&0xFC; value0=volume1&0xFC; if ((volume0!=0)&&(volume0<4)) control0 |= 0x04; if ((volume1!=0)&&(volume1<4)) value0 |= 0x04; if (channel0!=0) control0 |= 0x01; if (channel1==1) value0 |= 0x01; } else { value0=(volume0>volume1)?volume0:volume1; if (DS[d].drv_type<drv_211) { if (channel0!=0) { i=channel1; channel1=channel0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -