ips.c
来自「linux 内核源代码」· C语言 代码 · 共 1,758 行 · 第 1/5 页
C
1,758 行
static int ips_cmd_timeout = 60;static int ips_reset_timeout = 60 * 5;static int ips_force_memio = 1; /* Always use Memory Mapped I/O */static int ips_force_i2o = 1; /* Always use I2O command delivery */static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */static int ips_cd_boot; /* Booting from Manager CD */static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */static dma_addr_t ips_flashbusaddr;static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */static struct scsi_host_template ips_driver_template = { .detect = ips_detect, .release = ips_release, .info = ips_info, .queuecommand = ips_queue, .eh_abort_handler = ips_eh_abort, .eh_host_reset_handler = ips_eh_reset, .proc_name = "ips", .proc_info = ips_proc_info, .slave_configure = ips_slave_configure, .bios_param = ips_biosparam, .this_id = -1, .sg_tablesize = IPS_MAX_SG, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING,};/* This table describes all ServeRAID Adapters */static struct pci_device_id ips_pci_table[] = { { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0, }};MODULE_DEVICE_TABLE( pci, ips_pci_table );static char ips_hot_plug_name[] = "ips"; static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);static void __devexit ips_remove_device(struct pci_dev *pci_dev); static struct pci_driver ips_pci_driver = { .name = ips_hot_plug_name, .id_table = ips_pci_table, .probe = ips_insert_device, .remove = __devexit_p(ips_remove_device),}; /* * Necessary forward function protoypes */static int ips_halt(struct notifier_block *nb, ulong event, void *buf);#define MAX_ADAPTER_NAME 15static char ips_adapter_name[][30] = { "ServeRAID", "ServeRAID II", "ServeRAID on motherboard", "ServeRAID on motherboard", "ServeRAID 3H", "ServeRAID 3L", "ServeRAID 4H", "ServeRAID 4M", "ServeRAID 4L", "ServeRAID 4Mx", "ServeRAID 4Lx", "ServeRAID 5i", "ServeRAID 5i", "ServeRAID 6M", "ServeRAID 6i", "ServeRAID 7t", "ServeRAID 7k", "ServeRAID 7M"};static struct notifier_block ips_notifier = { ips_halt, NULL, 0};/* * Direction table */static char ips_command_direction[] = { IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, 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};/****************************************************************************//* *//* 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 < ARRAY_SIZE(options); 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 *//* *//****************************************************************************/static intips_detect(struct 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 *//* *//****************************************************************************/static intips_release(struct Scsi_Host *sh){ ips_scb_t *scb; ips_ha_t *ha; int i; METHOD_TRACE("ips_release", 1); scsi_remove_host(sh); 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"); IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n"); ips_sh[i] = NULL; ips_ha[i] = NULL; /* free extra memory */ ips_free(ha);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?