📄 wd33c93.c
字号:
instance->host_no, cmd->pid); printk("returning ABORT_SNOOZE. "); enable_irq(cmd->host->irq); return SCSI_ABORT_SNOOZE; } tmp = (Scsi_Cmnd *)tmp->host_scribble; }/* * Case 4 : If we reached this point, the command was not found in any of * the queues. * * We probably reached this point because of an unlikely race condition * between the command completing successfully and the abortion code, * so we won't panic, but we will notify the user in case something really * broke. *//* sti();*/ wd33c93_execute (instance); enable_irq(cmd->host->irq); printk("scsi%d: warning : SCSI command probably completed successfully" " before abortion. ", instance->host_no); return SCSI_ABORT_NOT_RUNNING;}#define MAX_WD33C93_HOSTS 4#define MAX_SETUP_ARGS ((int)(sizeof(setup_args) / sizeof(char *)))#define SETUP_BUFFER_SIZE 200static char setup_buffer[SETUP_BUFFER_SIZE];static char setup_used[MAX_SETUP_ARGS];static int done_setup = 0;int wd33c93_setup (char *str){ int i; char *p1,*p2; /* The kernel does some processing of the command-line before calling * this function: If it begins with any decimal or hex number arguments, * ints[0] = how many numbers found and ints[1] through [n] are the values * themselves. str points to where the non-numeric arguments (if any) * start: We do our own parsing of those. We construct synthetic 'nosync' * keywords out of numeric args (to maintain compatibility with older * versions) and then add the rest of the arguments. */ p1 = setup_buffer; *p1 = '\0';#if 0/* * Old style command line arguments are now dead */ if (ints[0]) { for (i=0; i<ints[0]; i++) { x = vsprintf(p1,"nosync:0x%02x,",&(ints[i+1])); p1 += x; } }#endif if (str) strncpy(p1, str, SETUP_BUFFER_SIZE - strlen(setup_buffer)); setup_buffer[SETUP_BUFFER_SIZE - 1] = '\0'; p1 = setup_buffer; i = 0; while (*p1 && (i < MAX_SETUP_ARGS)) { p2 = strchr(p1, ','); if (p2) { *p2 = '\0'; if (p1 != p2) setup_args[i] = p1; p1 = p2 + 1; i++; } else { setup_args[i] = p1; break; } } for (i=0; i<MAX_SETUP_ARGS; i++) setup_used[i] = 0; done_setup = 1; return 1;}__setup("wd33c93", wd33c93_setup);/* check_setup_args() returns index if key found, 0 if not */static int check_setup_args(char *key, int *flags, int *val, char *buf){int x;char *cp; for (x=0; x<MAX_SETUP_ARGS; x++) { if (setup_used[x]) continue; if (!strncmp(setup_args[x], key, strlen(key))) break; if (!strncmp(setup_args[x], "next", strlen("next"))) return 0; } if (x == MAX_SETUP_ARGS) return 0; setup_used[x] = 1; cp = setup_args[x] + strlen(key); *val = -1; if (*cp != ':') return ++x; cp++; if ((*cp >= '0') && (*cp <= '9')) { *val = simple_strtoul(cp,NULL,0); } return ++x;}void wd33c93_init(struct Scsi_Host *instance, const wd33c93_regs regs, dma_setup_t setup, dma_stop_t stop, int clock_freq){struct WD33C93_hostdata *hostdata;int i;int flags;int val;char buf[32]; if (!done_setup && setup_strings) wd33c93_setup(setup_strings); hostdata = (struct WD33C93_hostdata *)instance->hostdata; hostdata->regs = regs; hostdata->clock_freq = clock_freq; hostdata->dma_setup = setup; hostdata->dma_stop = stop; hostdata->dma_bounce_buffer = NULL; hostdata->dma_bounce_len = 0; for (i = 0; i < 8; i++) { hostdata->busy[i] = 0; hostdata->sync_xfer[i] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF); hostdata->sync_stat[i] = SS_UNSET; /* using default sync values */#ifdef PROC_STATISTICS hostdata->cmd_cnt[i] = 0; hostdata->disc_allowed_cnt[i] = 0; hostdata->disc_done_cnt[i] = 0;#endif } hostdata->input_Q = NULL; hostdata->selecting = NULL; hostdata->connected = NULL; hostdata->disconnected_Q = NULL; hostdata->state = S_UNCONNECTED; hostdata->dma = D_DMA_OFF; hostdata->level2 = L2_BASIC; hostdata->disconnect = DIS_ADAPTIVE; hostdata->args = DEBUG_DEFAULTS; hostdata->incoming_ptr = 0; hostdata->outgoing_len = 0; hostdata->default_sx_per = DEFAULT_SX_PER; hostdata->no_sync = 0xff; /* sync defaults to off */ hostdata->no_dma = 0; /* default is DMA enabled */#ifdef PROC_INTERFACE hostdata->proc = PR_VERSION|PR_INFO|PR_STATISTICS| PR_CONNECTED|PR_INPUTQ|PR_DISCQ| PR_STOP;#ifdef PROC_STATISTICS hostdata->dma_cnt = 0; hostdata->pio_cnt = 0; hostdata->int_cnt = 0;#endif#endif if (check_setup_args("nosync",&flags,&val,buf)) hostdata->no_sync = val; if (check_setup_args("nodma",&flags,&val,buf)) hostdata->no_dma = (val == -1) ? 1 : val; if (check_setup_args("period",&flags,&val,buf)) hostdata->default_sx_per = sx_table[round_period((unsigned int)val)].period_ns; if (check_setup_args("disconnect",&flags,&val,buf)) { if ((val >= DIS_NEVER) && (val <= DIS_ALWAYS)) hostdata->disconnect = val; else hostdata->disconnect = DIS_ADAPTIVE; } if (check_setup_args("level2",&flags,&val,buf)) hostdata->level2 = val; if (check_setup_args("debug",&flags,&val,buf)) hostdata->args = val & DB_MASK; if (check_setup_args("clock",&flags,&val,buf)) { if (val>7 && val<11) val = WD33C93_FS_8_10; else if (val>11 && val<16) val = WD33C93_FS_12_15; else if (val>15 && val<21) val = WD33C93_FS_16_20; else val = WD33C93_FS_8_10; hostdata->clock_freq = val; } if ((i = check_setup_args("next",&flags,&val,buf))) { while (i) setup_used[--i] = 1; }#ifdef PROC_INTERFACE if (check_setup_args("proc",&flags,&val,buf)) hostdata->proc = val;#endif { unsigned long flags; save_flags(flags); cli(); reset_wd33c93(instance); restore_flags(flags); } printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d",instance->host_no, (hostdata->chip==C_WD33C93)?"WD33c93": (hostdata->chip==C_WD33C93A)?"WD33c93A": (hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown", hostdata->microcode,hostdata->no_sync,hostdata->no_dma);#ifdef DEBUGGING_ON printk(" debug_flags=0x%02x\n",hostdata->args);#else printk(" debugging=OFF\n");#endif printk(" setup_args="); for (i=0; i<MAX_SETUP_ARGS; i++) printk("%s,",setup_args[i]); printk("\n"); printk(" Version %s - %s, Compiled %s at %s\n", WD33C93_VERSION,WD33C93_DATE,__DATE__,__TIME__); MOD_INC_USE_COUNT;}int wd33c93_proc_info(char *buf, char **start, off_t off, int len, int hn, int in){#ifdef PROC_INTERFACEchar *bp;char tbuf[128];unsigned long flags;struct Scsi_Host *instance;struct WD33C93_hostdata *hd;Scsi_Cmnd *cmd;int x,i;static int stop = 0; for (instance=scsi_hostlist; instance; instance=instance->next) { if (instance->host_no == hn) break; } if (!instance) { printk("*** Hmm... Can't find host #%d!\n",hn); return (-ESRCH); } hd = (struct WD33C93_hostdata *)instance->hostdata;/* If 'in' is TRUE we need to _read_ the proc file. We accept the following * keywords (same format as command-line, but only ONE per read): * debug * disconnect * period * resync * proc * nodma */ if (in) { buf[len] = '\0'; bp = buf; if (!strncmp(bp,"debug:",6)) { bp += 6; hd->args = simple_strtoul(bp,NULL,0) & DB_MASK; } else if (!strncmp(bp,"disconnect:",11)) { bp += 11; x = simple_strtoul(bp,NULL,0); if (x < DIS_NEVER || x > DIS_ALWAYS) x = DIS_ADAPTIVE; hd->disconnect = x; } else if (!strncmp(bp,"period:",7)) { bp += 7; x = simple_strtoul(bp,NULL,0); hd->default_sx_per = sx_table[round_period((unsigned int)x)].period_ns; } else if (!strncmp(bp,"resync:",7)) { bp += 7; x = simple_strtoul(bp,NULL,0); for (i=0; i<7; i++) if (x & (1<<i)) hd->sync_stat[i] = SS_UNSET; } else if (!strncmp(bp,"proc:",5)) { bp += 5; hd->proc = simple_strtoul(bp,NULL,0); } else if (!strncmp(bp,"nodma:",6)) { bp += 6; hd->no_dma = simple_strtoul(bp,NULL,0); } else if (!strncmp(bp,"level2:",7)) { bp += 7; hd->level2 = simple_strtoul(bp,NULL,0); } return len; } save_flags(flags); cli(); bp = buf; *bp = '\0'; if (hd->proc & PR_VERSION) { sprintf(tbuf,"\nVersion %s - %s. Compiled %s %s", WD33C93_VERSION,WD33C93_DATE,__DATE__,__TIME__); strcat(bp,tbuf); } if (hd->proc & PR_INFO) { sprintf(tbuf,"\nclock_freq=%02x no_sync=%02x no_dma=%d", hd->clock_freq,hd->no_sync,hd->no_dma); strcat(bp,tbuf); strcat(bp,"\nsync_xfer[] = "); for (x=0; x<7; x++) { sprintf(tbuf,"\t%02x",hd->sync_xfer[x]); strcat(bp,tbuf); } strcat(bp,"\nsync_stat[] = "); for (x=0; x<7; x++) { sprintf(tbuf,"\t%02x",hd->sync_stat[x]); strcat(bp,tbuf); } }#ifdef PROC_STATISTICS if (hd->proc & PR_STATISTICS) { strcat(bp,"\ncommands issued: "); for (x=0; x<7; x++) { sprintf(tbuf,"\t%ld",hd->cmd_cnt[x]); strcat(bp,tbuf); } strcat(bp,"\ndisconnects allowed:"); for (x=0; x<7; x++) { sprintf(tbuf,"\t%ld",hd->disc_allowed_cnt[x]); strcat(bp,tbuf); } strcat(bp,"\ndisconnects done: "); for (x=0; x<7; x++) { sprintf(tbuf,"\t%ld",hd->disc_done_cnt[x]); strcat(bp,tbuf); } sprintf(tbuf,"\ninterrupts: %ld, DATA_PHASE ints: %ld DMA, %ld PIO", hd->int_cnt,hd->dma_cnt,hd->pio_cnt); strcat(bp,tbuf); }#endif if (hd->proc & PR_CONNECTED) { strcat(bp,"\nconnected: "); if (hd->connected) { cmd = (Scsi_Cmnd *)hd->connected; sprintf(tbuf," %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]); strcat(bp,tbuf); } } if (hd->proc & PR_INPUTQ) { strcat(bp,"\ninput_Q: "); cmd = (Scsi_Cmnd *)hd->input_Q; while (cmd) { sprintf(tbuf," %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]); strcat(bp,tbuf); cmd = (Scsi_Cmnd *)cmd->host_scribble; } } if (hd->proc & PR_DISCQ) { strcat(bp,"\ndisconnected_Q:"); cmd = (Scsi_Cmnd *)hd->disconnected_Q; while (cmd) { sprintf(tbuf,"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -