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

📄 sbpcd.c

📁 LINUX 1.0 内核c源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  msf.c[3] = 0;
  msf.c[2] = (blk + CD_BLOCK_OFFSET) / (CD_SECS * CD_FRAMES);
  mm = (blk + CD_BLOCK_OFFSET) % (CD_SECS * CD_FRAMES);
  msf.c[1] = mm / CD_FRAMES;
  msf.c[0] = mm % CD_FRAMES;
  return (msf.n);
}
/*==========================================================================*/
static u_int make16(u_char rh, u_char rl)
{
  return ((rh<<8)|rl);
}
/*==========================================================================*/
static u_int make32(u_int rh, u_int rl)
{
  return ((rh<<16)|rl);
}
/*==========================================================================*/
static u_char swap_nibbles(u_char i)
{
  return ((i<<4)|(i>>4));
}
/*==========================================================================*/
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;
    }

⌨️ 快捷键说明

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