📄 aic7xxx_old.c
字号:
#define VERBOSE_MINOR_ERROR 0x0040#define VERBOSE_TRACING 0x0080#define VERBOSE_ABORT 0x0f00#define VERBOSE_ABORT_MID 0x0100#define VERBOSE_ABORT_FIND 0x0200#define VERBOSE_ABORT_PROCESS 0x0400#define VERBOSE_ABORT_RETURN 0x0800#define VERBOSE_RESET 0xf000#define VERBOSE_RESET_MID 0x1000#define VERBOSE_RESET_FIND 0x2000#define VERBOSE_RESET_PROCESS 0x4000#define VERBOSE_RESET_RETURN 0x8000static int aic7xxx_verbose = VERBOSE_NORMAL | VERBOSE_NEGOTIATION | VERBOSE_PROBE; /* verbose messages *//**************************************************************************** * * We're going to start putting in function declarations so that order of * functions is no longer important. As needed, they are added here. * ***************************************************************************/static void aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd);static void aic7xxx_print_card(struct aic7xxx_host *p);static void aic7xxx_print_scratch_ram(struct aic7xxx_host *p);static void aic7xxx_print_sequencer(struct aic7xxx_host *p, int downloaded);#ifdef AIC7XXX_VERBOSE_DEBUGGINGstatic void aic7xxx_check_scbs(struct aic7xxx_host *p, char *buffer);#endif/**************************************************************************** * * These functions are now used. They happen to be wrapped in useless * inb/outb port read/writes around the real reads and writes because it * seems that certain very fast CPUs have a problem dealing with us when * going at full speed. * ***************************************************************************/static inline unsigned charaic_inb(struct aic7xxx_host *p, long port){#ifdef MMAPIO unsigned char x; if(p->maddr) { x = readb(p->maddr + port); } else { x = inb(p->base + port); } return(x);#else return(inb(p->base + port));#endif}static inline voidaic_outb(struct aic7xxx_host *p, unsigned char val, long port){#ifdef MMAPIO if(p->maddr) { writeb(val, p->maddr + port); mb(); /* locked operation in order to force CPU ordering */ readb(p->maddr + HCNTRL); /* dummy read to flush the PCI write */ } else { outb(val, p->base + port); mb(); /* locked operation in order to force CPU ordering */ }#else outb(val, p->base + port); mb(); /* locked operation in order to force CPU ordering */#endif}/*+F************************************************************************* * Function: * aic7xxx_setup * * Description: * Handle Linux boot parameters. This routine allows for assigning a value * to a parameter with a ':' between the parameter and the value. * ie. aic7xxx=unpause:0x0A,extended *-F*************************************************************************/static intaic7xxx_setup(char *s){ int i, n; char *p; char *end; static struct { const char *name; unsigned int *flag; } options[] = { { "extended", &aic7xxx_extended }, { "no_reset", &aic7xxx_no_reset }, { "irq_trigger", &aic7xxx_irq_trigger }, { "verbose", &aic7xxx_verbose }, { "reverse_scan",&aic7xxx_reverse_scan }, { "override_term", &aic7xxx_override_term }, { "stpwlev", &aic7xxx_stpwlev }, { "no_probe", &aic7xxx_no_probe }, { "panic_on_abort", &aic7xxx_panic_on_abort }, { "pci_parity", &aic7xxx_pci_parity }, { "dump_card", &aic7xxx_dump_card }, { "dump_sequencer", &aic7xxx_dump_sequencer }, { "scbram", &aic7xxx_scbram }, { "seltime", &aic7xxx_seltime }, { "tag_info", NULL } }; end = strchr(s, '\0'); for (p = strtok(s, ",."); p; p = strtok(NULL, ",.")) { for (i = 0; i < NUMBER(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 >= NUMBER(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 < NUMBER(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 = strtok(NULL, ",."); } } 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 h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -