📄 am53c974.c
字号:
/************ LILO overrides *************/typedef struct _override_t { int host_scsi_id; /* SCSI id of the bus controller */ int target_scsi_id; /* SCSI id of target */ int max_rate; /* max. transfer rate */ int max_offset; /* max. sync. offset, 0 = asynchronous */} override_t;#ifdef AM53C974_DEBUGstatic void AM53C974_print_phase(struct Scsi_Host *instance);static void AM53C974_print_queues(struct Scsi_Host *instance);#endif /* AM53C974_DEBUG */static void AM53C974_print(struct Scsi_Host *instance);static void AM53C974_keywait(void);static __inline__ int AM53C974_pci_detect(Scsi_Host_Template * tpnt);static int AM53C974_init(Scsi_Host_Template * tpnt, struct pci_dev *pdev);static void AM53C974_config_after_reset(struct Scsi_Host *instance);static __inline__ void initialize_SCp(Scsi_Cmnd * cmd);static __inline__ void run_main(void);static void AM53C974_main(void);static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs);static void do_AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs);static void AM53C974_intr_disconnect(struct Scsi_Host *instance);static int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg);static __inline__ void AM53C974_set_async(struct Scsi_Host *instance, int target);static __inline__ void AM53C974_set_sync(struct Scsi_Host *instance, int target);static void AM53C974_information_transfer(struct Scsi_Host *instance, unsigned char statreg, unsigned char isreg, unsigned char instreg, unsigned char cfifo, unsigned char dmastatus);static int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd * cmd, unsigned char msg);static void AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag);static void AM53C974_intr_reselect(struct Scsi_Host *instance, unsigned char statreg);static __inline__ void AM53C974_transfer_dma(struct Scsi_Host *instance, short dir, unsigned long length, char *data);static void AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus, unsigned char statreg);static void AM53C974_intr_bus_reset(struct Scsi_Host *instance);static struct Scsi_Host *first_instance;static Scsi_Host_Template *the_template;static struct Scsi_Host *first_host; /* Head of list of AMD boards */static volatile int main_running;static int commandline_current;override_t overrides[7] ={ {-1, 0, 0, 0},}; /* LILO overrides */#ifdef AM53C974_DEBUGstatic int deb_stop = 1;static struct { unsigned char value; char *name;} phases[] = { { PHASE_DATAOUT, "DATAOUT" }, { PHASE_DATAIN, "DATAIN" }, { PHASE_CMDOUT, "CMDOUT" }, { PHASE_STATIN, "STATIN" }, { PHASE_MSGOUT, "MSGOUT" }, { PHASE_MSGIN, "MSGIN" }, { PHASE_RES_0, "RESERVED 0" }, { PHASE_RES_1, "RESERVED 1" }};/************************************************************************** * Function : void AM53C974_print_phase(struct Scsi_Host *instance) * * Purpose : print the current SCSI phase for debugging purposes * * Input : instance - which AM53C974 **************************************************************************/static void AM53C974_print_phase(struct Scsi_Host *instance){ AM53C974_local_declare(); unsigned char statreg, latched; int i; AM53C974_setio(instance); latched = (AM53C974_read_8(CNTLREG2)) & CNTLREG2_ENF; statreg = AM53C974_read_8(STATREG); for (i = 0; (phases[i].value != PHASE_RES_1) && (phases[i].value != (statreg & STATREG_PHASE)); ++i); if (latched) printk("scsi%d : phase %s, latched at end of last command\n", instance->host_no, phases[i].name); else printk("scsi%d : phase %s, real time\n", instance->host_no, phases[i].name);}/************************************************************************** * Function : void AM53C974_print_queues(struct Scsi_Host *instance) * * Purpose : print commands in the various queues * * Inputs : instance - which AM53C974 **************************************************************************/static void AM53C974_print_queues(struct Scsi_Host *instance){ unsigned long flags; struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata; Scsi_Cmnd *ptr; printk("AM53C974: coroutine is%s running.\n", main_running ? "" : "n't"); save_flags(flags); cli(); if (!hostdata->connected) { printk("scsi%d: no currently connected command\n", instance->host_no); } else { print_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected); } if (!hostdata->sel_cmd) { printk("scsi%d: no currently arbitrating command\n", instance->host_no); } else { print_Scsi_Cmnd((Scsi_Cmnd *) hostdata->sel_cmd); } printk("scsi%d: issue_queue ", instance->host_no); if (!hostdata->issue_queue) printk("empty\n"); else { printk(":\n"); for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) print_Scsi_Cmnd(ptr); } printk("scsi%d: disconnected_queue ", instance->host_no); if (!hostdata->disconnected_queue) printk("empty\n"); else { printk(":\n"); for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) print_Scsi_Cmnd(ptr); } restore_flags(flags);}#endif /* AM53C974_DEBUG *//************************************************************************** * Function : void AM53C974_print(struct Scsi_Host *instance) * * Purpose : dump the chip registers for debugging purposes * * Input : instance - which AM53C974 **************************************************************************/static void AM53C974_print(struct Scsi_Host *instance){ AM53C974_local_declare(); unsigned long flags; unsigned long ctcreg, dmastc, dmaspa, dmawbc, dmawac; unsigned char cmdreg, statreg, isreg, cfireg, cntlreg[4], dmacmd, dmastatus; AM53C974_setio(instance); save_flags(flags); cli(); ctcreg = AM53C974_read_8(CTCHREG) << 16; ctcreg |= AM53C974_read_8(CTCMREG) << 8; ctcreg |= AM53C974_read_8(CTCLREG); cmdreg = AM53C974_read_8(CMDREG); statreg = AM53C974_read_8(STATREG); isreg = AM53C974_read_8(ISREG); cfireg = AM53C974_read_8(CFIREG); cntlreg[0] = AM53C974_read_8(CNTLREG1); cntlreg[1] = AM53C974_read_8(CNTLREG2); cntlreg[2] = AM53C974_read_8(CNTLREG3); cntlreg[3] = AM53C974_read_8(CNTLREG4); dmacmd = AM53C974_read_8(DMACMD); dmastc = AM53C974_read_32(DMASTC); dmaspa = AM53C974_read_32(DMASPA); dmawbc = AM53C974_read_32(DMAWBC); dmawac = AM53C974_read_32(DMAWAC); dmastatus = AM53C974_read_8(DMASTATUS); restore_flags(flags); printk("AM53C974 register dump:\n"); printk("IO base: 0x%04lx; CTCREG: 0x%04lx; CMDREG: 0x%02x; STATREG: 0x%02x; ISREG: 0x%02x\n", io_port, ctcreg, cmdreg, statreg, isreg); printk("CFIREG: 0x%02x; CNTLREG1-4: 0x%02x; 0x%02x; 0x%02x; 0x%02x\n", cfireg, cntlreg[0], cntlreg[1], cntlreg[2], cntlreg[3]); printk("DMACMD: 0x%02x; DMASTC: 0x%04lx; DMASPA: 0x%04lx\n", dmacmd, dmastc, dmaspa); printk("DMAWBC: 0x%04lx; DMAWAC: 0x%04lx; DMASTATUS: 0x%02x\n", dmawbc, dmawac, dmastatus); printk("---------------------------------------------------------\n");}/*************************************************************************** Function : void AM53C974_keywait(void)** Purpose : wait until a key is pressed, if it was the 'r' key leave singlestep mode;* this function is used for debugging only** Input : none**************************************************************************/static void AM53C974_keywait(void){ unsigned long flags;#ifdef AM53C974_DEBUG int key; if (!deb_stop) return;#endif save_flags(flags); cli(); while ((inb_p(0x64) & 0x01) != 0x01);#ifdef AM53C974_DEBUG key = inb(0x60); if (key == 0x93) deb_stop = 0; /* don't stop if 'r' was pressed */#endif restore_flags(flags);}#ifndef MODULE/*************************************************************************** Function : AM53C974_setup(char *str)** Purpose : LILO command line initialization of the overrides array,* * Input : str - parameter string.** Returns : 1.** NOTE : this function needs to be declared as an external function* in init/main.c and included there in the bootsetups list***************************************************************************/static int AM53C974_setup(char *str){ int ints[5]; get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] < 4) printk("AM53C974_setup: wrong number of parameters;\n correct syntax is: AM53C974=host-scsi-id, target-scsi-id, max-rate, max-offset\n"); else { if (commandline_current < (sizeof(overrides) / sizeof(override_t))) { if ((ints[1] < 0) || (ints[1] > 7) || (ints[2] < 0) || (ints[2] > 7) || (ints[1] == ints[2]) || (ints[3] < (DEF_CLK / MAX_PERIOD)) || (ints[3] > (DEF_CLK / MIN_PERIOD)) || (ints[4] < 0) || (ints[4] > MAX_OFFSET)) printk("AM53C974_setup: illegal parameter\n"); else { overrides[commandline_current].host_scsi_id = ints[1]; overrides[commandline_current].target_scsi_id = ints[2]; overrides[commandline_current].max_rate = ints[3]; overrides[commandline_current].max_offset = ints[4]; commandline_current++; } } else printk("AM53C974_setup: too many overrides\n"); } return 1;}__setup("AM53C974=", AM53C974_setup);#endif /* !MODULE *//*************************************************************************** Function : int AM53C974_pci_detect(Scsi_Host_Template *tpnt)** Purpose : detects and initializes AM53C974 SCSI chips with PCI Bios** Inputs : tpnt - host template* * Returns : number of host adapters detected**************************************************************************/static int __init AM53C974_pci_detect(Scsi_Host_Template * tpnt){ int count = 0; /* number of boards detected */ struct pci_dev *pdev = NULL; unsigned short command; while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SCSI, pdev))) { if (pci_enable_device(pdev)) continue; pci_read_config_word(pdev, PCI_COMMAND, &command); /* check whether device is I/O mapped -- should be */ if (!(command & PCI_COMMAND_IO)) continue; pci_set_master (pdev); /* everything seems OK now, so initialize */ if (AM53C974_init(tpnt, pdev)) count++; } return (count);}/*************************************************************************** Function : int AM53C974_init(Scsi_Host_Template *tpnt, struct pci_dev *pdev)** Purpose : initializes instance and corresponding AM53/79C974 chip,** Inputs : tpnt - template, pci_config - PCI configuration,* * Returns : 1 on success, 0 on failure.* * NOTE: If no override for the controller's SCSI id is given and AM53C974_SCSI_ID * is not defined we assume that the SCSI address of this controller is correctly* set up by the BIOS (as reflected by contents of register CNTLREG1).* This is the only BIOS assistance we need.**************************************************************************/static int __init AM53C974_init(Scsi_Host_Template * tpnt, struct pci_dev *pdev){ AM53C974_local_declare(); int i, j; struct Scsi_Host *instance, *search; struct AM53C974_hostdata *hostdata;#ifdef AM53C974_OPTION_DEBUG_PROBE_ONLY printk("AM53C974: probe only enabled, aborting initialization\n"); return 0;#endif instance = scsi_register(tpnt, sizeof(struct AM53C974_hostdata)); hostdata = (struct AM53C974_hostdata *) instance->hostdata; instance->base = 0; instance->io_port = pci_resource_start(pdev, 0); instance->irq = pdev->irq;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -