ips.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,776 行 · 第 1/5 页
C
1,776 行
IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK};/* * Function prototypes */int ips_detect(Scsi_Host_Template *);int ips_release(struct Scsi_Host *);int ips_eh_abort(Scsi_Cmnd *);int ips_eh_reset(Scsi_Cmnd *);int ips_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));const char *ips_info(struct Scsi_Host *);irqreturn_t do_ipsintr(int, void *, struct pt_regs *);static int ips_hainit(ips_ha_t *);static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);static int ips_send_cmd(ips_ha_t *, ips_scb_t *);static int ips_online(ips_ha_t *, ips_scb_t *);static int ips_inquiry(ips_ha_t *, ips_scb_t *);static int ips_rdcap(ips_ha_t *, ips_scb_t *);static int ips_msense(ips_ha_t *, ips_scb_t *);static int ips_reqsen(ips_ha_t *, ips_scb_t *);static int ips_deallocatescbs(ips_ha_t *, int);static int ips_allocatescbs(ips_ha_t *);static int ips_reset_copperhead(ips_ha_t *);static int ips_reset_copperhead_memio(ips_ha_t *);static int ips_reset_morpheus(ips_ha_t *);static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);static int ips_isintr_copperhead(ips_ha_t *);static int ips_isintr_copperhead_memio(ips_ha_t *);static int ips_isintr_morpheus(ips_ha_t *);static int ips_wait(ips_ha_t *, int, int);static int ips_write_driver_status(ips_ha_t *, int);static int ips_read_adapter_status(ips_ha_t *, int);static int ips_read_subsystem_parameters(ips_ha_t *, int);static int ips_read_config(ips_ha_t *, int);static int ips_clear_adapter(ips_ha_t *, int);static int ips_readwrite_page5(ips_ha_t *, int, int);static int ips_init_copperhead(ips_ha_t *);static int ips_init_copperhead_memio(ips_ha_t *);static int ips_init_morpheus(ips_ha_t *);static int ips_isinit_copperhead(ips_ha_t *);static int ips_isinit_copperhead_memio(ips_ha_t *);static int ips_isinit_morpheus(ips_ha_t *);static int ips_erase_bios(ips_ha_t *);static int ips_program_bios(ips_ha_t *, char *, uint32_t, uint32_t);static int ips_verify_bios(ips_ha_t *, char *, uint32_t, uint32_t);static int ips_erase_bios_memio(ips_ha_t *);static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);static void ips_free_flash_copperhead(ips_ha_t * ha);static void ips_get_bios_version(ips_ha_t *, int);static void ips_identify_controller(ips_ha_t *);static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);static void ips_enable_int_copperhead(ips_ha_t *);static void ips_enable_int_copperhead_memio(ips_ha_t *);static void ips_enable_int_morpheus(ips_ha_t *);static int ips_intr_copperhead(ips_ha_t *);static int ips_intr_morpheus(ips_ha_t *);static void ips_next(ips_ha_t *, int);static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);static void ipsintr_done(ips_ha_t *, struct ips_scb *);static void ips_done(ips_ha_t *, ips_scb_t *);static void ips_free(ips_ha_t *);static void ips_init_scb(ips_ha_t *, ips_scb_t *);static void ips_freescb(ips_ha_t *, ips_scb_t *);static void ips_setup_funclist(ips_ha_t *);static void ips_statinit(ips_ha_t *);static void ips_statinit_memio(ips_ha_t *);static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);static void ips_ffdc_reset(ips_ha_t *, int);static void ips_ffdc_time(ips_ha_t *);static uint32_t ips_statupd_copperhead(ips_ha_t *);static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);static uint32_t ips_statupd_morpheus(ips_ha_t *);static ips_scb_t *ips_getscb(ips_ha_t *);static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);static void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *);static void ips_putq_copp_tail(ips_copp_queue_t *, ips_copp_wait_item_t *);static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);static Scsi_Cmnd *ips_removeq_wait_head(ips_wait_queue_t *);static Scsi_Cmnd *ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *);static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);static int ips_is_passthru(Scsi_Cmnd *);static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);static void ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned int count);static void ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned int count);int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);static int ips_host_info(ips_ha_t *, char *, off_t, int);static void copy_mem_info(IPS_INFOSTR *, char *, int);static int copy_info(IPS_INFOSTR *, char *, ...);static int ips_get_version_info(ips_ha_t * ha, dma_addr_t, int intr);static void ips_version_check(ips_ha_t * ha, int intr);static int ips_abort_init(ips_ha_t * ha, int index);static int ips_init_phase2(int index);static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);static int ips_register_scsi(int index);/*--------------------------------------------------------------------------*//* Exported Functions *//*--------------------------------------------------------------------------*//****************************************************************************//* *//* Routine Name: ips_setup *//* *//* Routine Description: *//* *//* setup parameters to the driver *//* *//****************************************************************************/static intips_setup(char *ips_str){ int i; char *key; char *value; IPS_OPTION options[] = { {"noi2o", &ips_force_i2o, 0}, {"nommap", &ips_force_memio, 0}, {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE}, {"cdboot", &ips_cd_boot, 0}, {"maxcmds", &MaxLiteCmds, 32}, }; /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */ /* Search for value */ while ((key = strsep(&ips_str, ",."))) { if (!*key) continue; value = strchr(key, ':'); if (value) *value++ = '\0'; /* * We now have key/value pairs. * Update the variables */ for (i = 0; i < (sizeof (options) / sizeof (options[0])); i++) { if (strnicmp (key, options[i].option_name, strlen(options[i].option_name)) == 0) { if (value) *options[i].option_flag = simple_strtoul(value, NULL, 0); else *options[i].option_flag = options[i].option_value; break; } } } return (1);}__setup("ips=", ips_setup);/****************************************************************************//* *//* Routine Name: ips_detect *//* *//* Routine Description: *//* *//* Detect and initialize the driver *//* *//* NOTE: this routine is called under the io_request_lock spinlock *//* *//****************************************************************************/intips_detect(Scsi_Host_Template * SHT){ int i; METHOD_TRACE("ips_detect", 1);#ifdef MODULE if (ips) ips_setup(ips);#endif for (i = 0; i < ips_num_controllers; i++) { if (ips_register_scsi(i)) ips_free(ips_ha[i]); ips_released_controllers++; } ips_hotplug = 1; return (ips_num_controllers);}/****************************************************************************//* configure the function pointers to use the functions that will work *//* with the found version of the adapter *//****************************************************************************/static voidips_setup_funclist(ips_ha_t * ha){ /* * Setup Functions */ if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) { /* morpheus / marco / sebring */ ha->func.isintr = ips_isintr_morpheus; ha->func.isinit = ips_isinit_morpheus; ha->func.issue = ips_issue_i2o_memio; ha->func.init = ips_init_morpheus; ha->func.statupd = ips_statupd_morpheus; ha->func.reset = ips_reset_morpheus; ha->func.intr = ips_intr_morpheus; ha->func.enableint = ips_enable_int_morpheus; } else if (IPS_USE_MEMIO(ha)) { /* copperhead w/MEMIO */ ha->func.isintr = ips_isintr_copperhead_memio; ha->func.isinit = ips_isinit_copperhead_memio; ha->func.init = ips_init_copperhead_memio; ha->func.statupd = ips_statupd_copperhead_memio; ha->func.statinit = ips_statinit_memio; ha->func.reset = ips_reset_copperhead_memio; ha->func.intr = ips_intr_copperhead; ha->func.erasebios = ips_erase_bios_memio; ha->func.programbios = ips_program_bios_memio; ha->func.verifybios = ips_verify_bios_memio; ha->func.enableint = ips_enable_int_copperhead_memio; if (IPS_USE_I2O_DELIVER(ha)) ha->func.issue = ips_issue_i2o_memio; else ha->func.issue = ips_issue_copperhead_memio; } else { /* copperhead */ ha->func.isintr = ips_isintr_copperhead; ha->func.isinit = ips_isinit_copperhead; ha->func.init = ips_init_copperhead; ha->func.statupd = ips_statupd_copperhead; ha->func.statinit = ips_statinit; ha->func.reset = ips_reset_copperhead; ha->func.intr = ips_intr_copperhead; ha->func.erasebios = ips_erase_bios; ha->func.programbios = ips_program_bios; ha->func.verifybios = ips_verify_bios; ha->func.enableint = ips_enable_int_copperhead; if (IPS_USE_I2O_DELIVER(ha)) ha->func.issue = ips_issue_i2o; else ha->func.issue = ips_issue_copperhead; }}/****************************************************************************//* *//* Routine Name: ips_release *//* *//* Routine Description: *//* *//* Remove a driver *//* *//****************************************************************************/intips_release(struct Scsi_Host *sh){ ips_scb_t *scb; ips_ha_t *ha; int i; METHOD_TRACE("ips_release", 1); for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ; if (i == IPS_MAX_ADAPTERS) { printk(KERN_WARNING "(%s) release, invalid Scsi_Host pointer.\n", ips_name); BUG(); return (FALSE); } ha = IPS_HA(sh); if (!ha) return (FALSE); /* flush the cache on the controller */ scb = &ha->scbs[ha->max_cmds - 1]; ips_init_scb(ha, scb); scb->timeout = ips_cmd_timeout; scb->cdb[0] = IPS_CMD_FLUSH; scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH; scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.flush_cache.state = IPS_NORM_STATE; scb->cmd.flush_cache.reserved = 0; scb->cmd.flush_cache.reserved2 = 0; scb->cmd.flush_cache.reserved3 = 0; scb->cmd.flush_cache.reserved4 = 0; IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n"); /* send command */ if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE) IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?