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 + -
显示快捷键?