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

📄 aic7xxx_old.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
  while ((p = strsep(&s, ",.")) != NULL)  {    for (i = 0; i < ARRAY_SIZE(options); i++)    {      n = strlen(options[i].name);      if (!strncmp(options[i].name, p, n))      {        if (!strncmp(p, "tag_info", n))        {          if (p[n] == ':')          {            char *base;            char *tok, *tok_end, *tok_end2;            char tok_list[] = { '.', ',', '{', '}', '\0' };            int i, instance = -1, device = -1;            unsigned char done = FALSE;            base = p;            tok = base + n + 1;  /* Forward us just past the ':' */            tok_end = strchr(tok, '\0');            if (tok_end < end)              *tok_end = ',';            while(!done)            {              switch(*tok)              {                case '{':                  if (instance == -1)                    instance = 0;                  else if (device == -1)                    device = 0;                  tok++;                  break;                case '}':                  if (device != -1)                    device = -1;                  else if (instance != -1)                    instance = -1;                  tok++;                  break;                case ',':                case '.':                  if (instance == -1)                    done = TRUE;                  else if (device >= 0)                    device++;                  else if (instance >= 0)                    instance++;                  if ( (device >= MAX_TARGETS) ||                        (instance >= ARRAY_SIZE(aic7xxx_tag_info)) )                    done = TRUE;                  tok++;                  if (!done)                  {                    base = tok;                  }                  break;                case '\0':                  done = TRUE;                  break;                default:                  done = TRUE;                  tok_end = strchr(tok, '\0');                  for(i=0; tok_list[i]; i++)                  {                    tok_end2 = strchr(tok, tok_list[i]);                    if ( (tok_end2) && (tok_end2 < tok_end) )                    {                      tok_end = tok_end2;                      done = FALSE;                    }                  }                  if ( (instance >= 0) && (device >= 0) &&                       (instance < ARRAY_SIZE(aic7xxx_tag_info)) &&                       (device < MAX_TARGETS) )                    aic7xxx_tag_info[instance].tag_commands[device] =                      simple_strtoul(tok, NULL, 0) & 0xff;                  tok = tok_end;                  break;              }            }            while((p != base) && (p != NULL))              p = strsep(&s, ",.");          }        }        else if (p[n] == ':')        {          *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);          if(!strncmp(p, "seltime", n))          {            *(options[i].flag) = (*(options[i].flag) % 4) << 3;          }        }        else if (!strncmp(p, "verbose", n))        {          *(options[i].flag) = 0xff29;        }        else        {          *(options[i].flag) = ~(*(options[i].flag));          if(!strncmp(p, "seltime", n))          {            *(options[i].flag) = (*(options[i].flag) % 4) << 3;          }        }      }    }  }  return 1;}__setup("aic7xxx=", aic7xxx_setup);/*+F************************************************************************* * Function: *   pause_sequencer * * Description: *   Pause the sequencer and wait for it to actually stop - this *   is important since the sequencer can disable pausing for critical *   sections. *-F*************************************************************************/static voidpause_sequencer(struct aic7xxx_host *p){  aic_outb(p, p->pause, HCNTRL);  while ((aic_inb(p, HCNTRL) & PAUSE) == 0)  {    ;  }  if(p->features & AHC_ULTRA2)  {    aic_inb(p, CCSCBCTL);  }}/*+F************************************************************************* * Function: *   unpause_sequencer * * Description: *   Unpause the sequencer. Unremarkable, yet done often enough to *   warrant an easy way to do it. *-F*************************************************************************/static voidunpause_sequencer(struct aic7xxx_host *p, int unpause_always){  if (unpause_always ||      ( !(aic_inb(p, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) &&        !(p->flags & AHC_HANDLING_REQINITS) ) )  {    aic_outb(p, p->unpause, HCNTRL);  }}/*+F************************************************************************* * Function: *   restart_sequencer * * Description: *   Restart the sequencer program from address zero.  This assumes *   that the sequencer is already paused. *-F*************************************************************************/static voidrestart_sequencer(struct aic7xxx_host *p){  aic_outb(p, 0, SEQADDR0);  aic_outb(p, 0, SEQADDR1);  aic_outb(p, FASTMODE, SEQCTL);}/* * We include the aic7xxx_seq.c file here so that the other defines have * already been made, and so that it comes before the code that actually * downloads the instructions (since we don't typically use function * prototype, our code has to be ordered that way, it's a left-over from * the original driver days.....I should fix it some time DL). */#include "aic7xxx_old/aic7xxx_seq.c"/*+F************************************************************************* * Function: *   aic7xxx_check_patch * * Description: *   See if the next patch to download should be downloaded. *-F*************************************************************************/static intaic7xxx_check_patch(struct aic7xxx_host *p,  struct sequencer_patch **start_patch, int start_instr, int *skip_addr){  struct sequencer_patch *cur_patch;  struct sequencer_patch *last_patch;  int num_patches;  num_patches = sizeof(sequencer_patches)/sizeof(struct sequencer_patch);  last_patch = &sequencer_patches[num_patches];  cur_patch = *start_patch;  while ((cur_patch < last_patch) && (start_instr == cur_patch->begin))  {    if (cur_patch->patch_func(p) == 0)    {      /*       * Start rejecting code.       */      *skip_addr = start_instr + cur_patch->skip_instr;      cur_patch += cur_patch->skip_patch;    }    else    {      /*       * Found an OK patch.  Advance the patch pointer to the next patch       * and wait for our instruction pointer to get here.       */      cur_patch++;    }  }  *start_patch = cur_patch;  if (start_instr < *skip_addr)    /*     * Still skipping     */    return (0);  return(1);}/*+F************************************************************************* * Function: *   aic7xxx_download_instr * * Description: *   Find the next patch to download. *-F*************************************************************************/static voidaic7xxx_download_instr(struct aic7xxx_host *p, int instrptr,  unsigned char *dconsts){  union ins_formats instr;  struct ins_format1 *fmt1_ins;  struct ins_format3 *fmt3_ins;  unsigned char opcode;  instr = *(union ins_formats*) &seqprog[instrptr * 4];  instr.integer = le32_to_cpu(instr.integer);    fmt1_ins = &instr.format1;  fmt3_ins = NULL;  /* Pull the opcode */  opcode = instr.format1.opcode;  switch (opcode)  {    case AIC_OP_JMP:    case AIC_OP_JC:    case AIC_OP_JNC:    case AIC_OP_CALL:    case AIC_OP_JNE:    case AIC_OP_JNZ:    case AIC_OP_JE:    case AIC_OP_JZ:    {      struct sequencer_patch *cur_patch;      int address_offset;      unsigned int address;      int skip_addr;      int i;      fmt3_ins = &instr.format3;      address_offset = 0;      address = fmt3_ins->address;      cur_patch = sequencer_patches;      skip_addr = 0;      for (i = 0; i < address;)      {        aic7xxx_check_patch(p, &cur_patch, i, &skip_addr);        if (skip_addr > i)        {          int end_addr;          end_addr = min_t(int, address, skip_addr);          address_offset += end_addr - i;          i = skip_addr;        }        else        {          i++;        }      }      address -= address_offset;      fmt3_ins->address = address;      /* Fall Through to the next code section */    }    case AIC_OP_OR:    case AIC_OP_AND:    case AIC_OP_XOR:    case AIC_OP_ADD:    case AIC_OP_ADC:    case AIC_OP_BMOV:      if (fmt1_ins->parity != 0)      {        fmt1_ins->immediate = dconsts[fmt1_ins->immediate];      }      fmt1_ins->parity = 0;      /* Fall Through to the next code section */    case AIC_OP_ROL:      if ((p->features & AHC_ULTRA2) != 0)      {        int i, count;        /* Calculate odd parity for the instruction */        for ( i=0, count=0; i < 31; i++)        {          unsigned int mask;          mask = 0x01 << i;          if ((instr.integer & mask) != 0)            count++;        }        if (!(count & 0x01))          instr.format1.parity = 1;      }      else      {        if (fmt3_ins != NULL)        {          instr.integer =  fmt3_ins->immediate |                          (fmt3_ins->source << 8) |                          (fmt3_ins->address << 16) |                          (fmt3_ins->opcode << 25);        }        else        {          instr.integer =

⌨️ 快捷键说明

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