📄 sbpcd.c
字号:
DS[d].diskstate_flags &= ~multisession_bit; DS[d].f_multisession=0; clr_cmdbuf(); if (new_drive) { drvcmd[0]=0x8D; response_count=6; flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; i=cmd_out(); if (i<0) return (i); if ((infobuf[0]&0x80)!=0) { DPRINTF((DBG_MUL,"SBPCD: MultiSession CD detected: %02X %02X %02X %02X %02X %02X\n", infobuf[0], infobuf[1], infobuf[2], infobuf[3], infobuf[4], infobuf[5])); DS[d].f_multisession=1; DS[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]), make16(infobuf[2],infobuf[3]))); } } DS[d].diskstate_flags |= multisession_bit; return (0);}/*==========================================================================*/static void check_datarate(void){#ifdef CDMKE int i=0; timed_out=0; datarate=0; /* set a timer to make (timed_out!=0) after 1.1 seconds */ DPRINTF((DBG_TIM,"SBPCD: timer started (110).\n")); sti(); /* to avoid possible "printf" bug */ SET_TIMER(mark_timeout,110); do { i=inb(CDi_status); datarate++;#if 00000 if (datarate>0x0FFFFFFF) break;#endif 00000 } while (!timed_out); /* originally looping for 1.1 seconds */ CLEAR_TIMER; DPRINTF((DBG_TIM,"SBPCD: datarate: %d\n", datarate)); if (datarate<65536) datarate=65536; maxtim16=datarate*16; maxtim04=datarate*4; maxtim02=datarate*2; maxtim_8=datarate/32;#if MANY_SESSION maxtim_data=datarate/100;#else maxtim_data=datarate/300;#endif MANY_SESSION DPRINTF((DBG_TIM,"SBPCD: maxtim_8 %d, maxtim_data %d.\n", maxtim_8, maxtim_data));#endif CDMKE}/*==========================================================================*/static int check_version(void){ int i, j; /* clear any pending error state */ clr_cmdbuf(); drvcmd[0]=0x82; response_count=9; flags_cmd_out=f_putcmd; cmd_out(); /* read drive version */ clr_cmdbuf(); for (i=0;i<12;i++) infobuf[i]=0; drvcmd[0]=0x83; response_count=12; flags_cmd_out=f_putcmd; i=cmd_out(); if (i<0) DPRINTF((DBG_INI,"SBPCD: cmd_83 returns %d\n",i)); DPRINTF((DBG_INI,"SBPCD: infobuf = \"")); for (i=0;i<12;i++) DPRINTF((DBG_INI,"%c",infobuf[i])); DPRINTF((DBG_INI,"\"\n")); for (i=0;i<4;i++) if (infobuf[i]!=drive_family[i]) break; if (i==4) { DS[d].drive_model[0]=infobuf[i++]; DS[d].drive_model[1]=infobuf[i++]; DS[d].drive_model[2]='-'; DS[d].drive_model[3]='x'; DS[d].drv_type=drv_new; } else { for (i=0;i<8;i++) if (infobuf[i]!=drive_vendor[i]) break; if (i!=8) return (-1); DS[d].drive_model[0]='2'; DS[d].drive_model[1]='x'; DS[d].drive_model[2]='-'; DS[d].drive_model[3]='x'; DS[d].drv_type=drv_old; } for (j=0;j<4;j++) DS[d].firmware_version[j]=infobuf[i+j]; j = (DS[d].firmware_version[0] & 0x0F) * 100 + (DS[d].firmware_version[2] & 0x0F) *10 + (DS[d].firmware_version[3] & 0x0F); if (new_drive) { if (j<100) DS[d].drv_type=drv_099; else DS[d].drv_type=drv_100; } else if (j<200) DS[d].drv_type=drv_199; else if (j<201) DS[d].drv_type=drv_200; else if (j<210) DS[d].drv_type=drv_201; else if (j<211) DS[d].drv_type=drv_210; else if (j<300) DS[d].drv_type=drv_211; else DS[d].drv_type=drv_300; return (0);}/*==========================================================================*/static int switch_drive(int num){ int i; d=num; i=num; if (sbpro_type) i=(i&0x01)<<1|(i&0x02)>>1; OUT(CDo_enable,i); DPRINTF((DBG_DID,"SBPCD: switch_drive: drive %d activated.\n",DS[d].drv_minor)); return (0);}/*==========================================================================*//* * probe for the presence of drives on the selected controller */static int check_drives(void){ int i, j; char *printk_header=""; DPRINTF((DBG_INI,"SBPCD: check_drives entered.\n")); ndrives=0; for (j=0;j<NR_SBPCD;j++) { DS[j].drv_minor=j; switch_drive(j); DPRINTF((DBG_ID,"SBPCD: check_drives: drive %d activated.\n",j)); i=check_version(); DPRINTF((DBG_ID,"SBPCD: check_version returns %d.\n",i)); if (i>=0) { ndrives++; DS[d].drv_options=drv_pattern[j]; if (!new_drive) DS[d].drv_options&=~(speed_auto|speed_300|speed_150); printk("%sDrive %d: %s%.4s (%.4s)\n", printk_header, DS[d].drv_minor, drive_family, DS[d].drive_model, DS[d].firmware_version); printk_header=" - "; } else DS[d].drv_minor=-1; } if (ndrives==0) return (-1); return (0);}/*==========================================================================*/#if 000static void timewait(void){ int i; for (i=0; i<65500; i++);}#endif 000/*==========================================================================*/#if FUTURE/* * obtain if requested service disturbs current audio state */ static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc){ switch (audio_state) /* audio status from controller */ { case aud_11: /* "audio play in progress" */ case audx11: switch (func) /* DOS command code */ { case cmd_07: /* input flush */ case cmd_0d: /* open device */ case cmd_0e: /* close device */ case cmd_0c: /* ioctl output */ return (1); case cmd_03: /* ioctl input */ switch (subfunc) /* DOS ioctl input subfunction */ { case cxi_00: case cxi_06: case cxi_09: return (1); default: return (ERROR15); } return (1); default: return (ERROR15); } return (1); case aud_12: /* "audio play paused" */ case audx12: return (1); default: return (2); }}#endif FUTURE/*==========================================================================*//* allowed is only * ioctl_o, flush_input, open_device, close_device, * tell_address, tell_volume, tell_capabiliti, * tell_framesize, tell_CD_changed, tell_audio_posi */static int check_allowed1(u_char func1, u_char func2){#if 000 if (func1==ioctl_o) return (0); if (func1==read_long) return (-1); if (func1==read_long_prefetch) return (-1); if (func1==seek) return (-1); if (func1==audio_play) return (-1); if (func1==audio_pause) return (-1); if (func1==audio_resume) return (-1); if (func1!=ioctl_i) return (0); if (func2==tell_SubQ_run_tot) return (-1); if (func2==tell_cdsize) return (-1); if (func2==tell_TocDescrip) return (-1); if (func2==tell_TocEntry) return (-1); if (func2==tell_subQ_info) return (-1); if (new_drive) if (func2==tell_SubChanInfo) return (-1); if (func2==tell_UPC) return (-1);#else return (0);#endif 000}/*==========================================================================*/static int check_allowed2(u_char func1, u_char func2){#if 000 if (func1==read_long) return (-1); if (func1==read_long_prefetch) return (-1); if (func1==seek) return (-1); if (func1==audio_play) return (-1); if (func1!=ioctl_o) return (0); if (new_drive) { if (func2==EjectDisk) return (-1); if (func2==CloseTray) return (-1); }#else return (0);#endif 000}/*==========================================================================*/static int check_allowed3(u_char func1, u_char func2){#if 000 if (func1==ioctl_i) { if (func2==tell_address) return (0); if (func2==tell_capabiliti) return (0); if (func2==tell_CD_changed) return (0); if (!new_drive) if (func2==tell_SubChanInfo) return (0); return (-1); } if (func1==ioctl_o) { if (func2==DriveReset) return (0); if (!new_drive) { if (func2==EjectDisk) return (0); if (func2==LockDoor) return (0); if (func2==CloseTray) return (0); } return (-1); } if (func1==flush_input) return (-1); if (func1==read_long) return (-1); if (func1==read_long_prefetch) return (-1); if (func1==seek) return (-1); if (func1==audio_play) return (-1); if (func1==audio_pause) return (-1); if (func1==audio_resume) return (-1);#else return (0);#endif 000}/*==========================================================================*/static int seek_pos_audio_end(void){ int i; i=msf2blk(DS[d].pos_audio_end)-1; if (i<0) return (-1); i=xx_Seek(i,0); return (i);}/*==========================================================================*/static int ReadToC(void){ int i, j; DS[d].diskstate_flags &= ~toc_bit; DS[d].ored_ctl_adr=0; for (j=DS[d].n_first_track;j<=DS[d].n_last_track;j++) { i=xx_ReadTocEntry(j); if (i<0) return (i); DS[d].TocBuffer[j].nixbyte=DS[d].TocEnt_nixbyte; DS[d].TocBuffer[j].ctl_adr=DS[d].TocEnt_ctl_adr; DS[d].TocBuffer[j].number=DS[d].TocEnt_number; DS[d].TocBuffer[j].format=DS[d].TocEnt_format; DS[d].TocBuffer[j].address=DS[d].TocEnt_address; DS[d].ored_ctl_adr |= DS[d].TocEnt_ctl_adr; }/* fake entry for LeadOut Track */ DS[d].TocBuffer[j].nixbyte=0; DS[d].TocBuffer[j].ctl_adr=0; DS[d].TocBuffer[j].number=0; DS[d].TocBuffer[j].format=0; DS[d].TocBuffer[j].address=DS[d].size_msf; DS[d].diskstate_flags |= toc_bit; return (0);}/*==========================================================================*/static int DiskInfo(void){ int i; i=SetSpeed(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: first SetSpeed returns %d\n", i)); i=SetSpeed(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: second SetSpeed returns %d\n", i)); return (i); } } i=xx_ModeSense(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: first xx_ModeSense returns %d\n", i)); i=xx_ModeSense(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: second xx_ModeSense returns %d\n", i)); return (i); } return (i); } i=xx_ReadCapacity(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: first ReadCapacity returns %d\n", i)); i=xx_ReadCapacity(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: second ReadCapacity returns %d\n", i)); return (i); } return (i); } i=xx_ReadTocDescr(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadTocDescr returns %d\n", i)); return (i); } i=ReadToC(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadToC returns %d\n", i)); return (i); } i=yy_CheckMultiSession(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: yy_CheckMultiSession returns %d\n", i)); return (i); } i=xx_ReadTocEntry(DS[d].n_first_track); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadTocEntry(1) returns %d\n", i)); return (i); } i=xx_ReadUPC(); if (i<0) { DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadUPC returns %d\n", i)); return (i); } return (0);}/*==========================================================================*//* * called always if driver gets entered * returns 0 or ERROR2 or ERROR15 */static int prepare(u_char func, u_char subfunc){ int i; if (!new_drive) { i=inb(CDi_status); if (i&s_attention) GetStatus(); } else GetStatus(); if (DS[d].CD_changed==0xFF) {#if MANY_SESSION#else DS[d].diskstate_flags=0;#endif MANY_SESSION DS[d].audio_state=0; if (!st_diskok) { i=check_allowed1(func,subfunc); if (i<0) return (-2); } else { i=check_allowed3(func,subfunc); if (i<0) { DS[d].CD_changed=1; return (-15); } } } else { if (!st_diskok) {#if MANY_SESSION#else DS[d].diskstate_flags=0;#endif MANY_SESSION DS[d].audio_state=0; i=check_allowed1(func,subfunc); if (i<0) return (-2); } else { if (st_busy) { if (DS[d].audio_state!=audio_pausing) { i=check_allowed2(func,subfunc); if (i<0) return (-2); } } else { if (DS[d].audio_state==audio_playing) seek_pos_audio_end(); DS[d].audio_state=0; } if (!frame_size_valid) { i=DiskInfo(); if (i<0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -