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