⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qla_cfg.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************** *                  QLOGIC LINUX SOFTWARE * * QLogic ISP2x00 device driver for Linux 2.4.x * Copyright (C) 2002 Qlogic Corporation * (www.qlogic.com) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * ******************************************************************************//* * QLogic ISP2x00 Multi-path LUN Support Driver * */#include "qlfo.h"#include "qla_cfg.h"#include "qla_gbl.h"#if defined(LINUX)#include "qla_cfgln.c"#endif/* *  Local Function Prototypes. */static mp_path_t * qla2x00_select_next_path(mp_host_t *host, mp_device_t *dp, uint8_t);static uint32_t qla2x00_add_portname_to_mp_dev(mp_device_t *, uint8_t *);static mp_device_t * qla2x00_allocate_mp_dev(uint8_t *, uint8_t *);static mp_path_t * qla2x00_allocate_path(mp_host_t *host, uint16_t path_id,                fc_port_t *port, uint16_t dev_id);static mp_host_t * qla2x00_find_host_by_name(uint8_t *);static mp_device_t * qla2x00_find_or_allocate_mp_dev (mp_host_t *, uint16_t,                fc_port_t *);static mp_path_t  * qla2x00_find_or_allocate_path(mp_host_t *, mp_device_t *,                uint16_t, fc_port_t	*);static uint32_t qla2x00_send_failover_notify(mp_device_t *, uint8_t lun,                mp_path_t *new_path, mp_path_t *old_path);static BOOL qla2x00_update_mp_host( mp_host_t  *);static uint32_t qla2x00_update_mp_tree (void);static fc_lun_t *qla2x00_find_matching_lun(uint8_t , mp_path_t *);static mp_path_t *qla2x00_find_path_by_id(mp_device_t *, uint8_t );static mp_device_t  *qla2x00_find_mp_dev_by_id(mp_host_t *, uint8_t );static mp_device_t  *qla2x00_find_mp_dev_by_name(mp_host_t *, uint8_t *);static BOOL qla2x00_is_ww_name_zero(uint8_t *);static void qla2x00_add_path(mp_path_list_t *, mp_path_t *);static BOOL qla2x00_is_portname_in_device(mp_device_t *, uint8_t *);static void qla2x00_failback_luns( mp_host_t  *);static void qla2x00_failback_single_lun( mp_device_t *dp, uint8_t lun, uint8_t new);static void qla2x00_setup_new_path( mp_device_t *, mp_path_t *);static void qla2x00_map_os_targets(mp_host_t *);static void qla2x00_map_os_luns(mp_host_t *, mp_device_t *, uint16_t );mp_host_t * qla2x00_cfg_find_host(scsi_qla_host_t *ha);static mp_path_list_t * qla2x00_allocate_path_list( void );static uint32_tqla2x00_cfg_register_failover_lun(mp_device_t *,srb_t *, fc_lun_t *);static voidqla2x00_map_a_oslun(mp_host_t *, mp_device_t *, uint16_t , uint16_t );static mp_path_t *qla2x00_get_visible_path(mp_device_t 	*dp);/* * Global data items */mp_host_t  *mp_hosts_base = NULL;BOOL   mp_config_required = FALSE;static int    mp_num_hosts = 0;static BOOL   mp_initialized = FALSE;/* * ENTRY ROUTINES *//* * qla2x00_cfg_init *      Initialize configuration structures to handle an instance of *      an HBA, QLA2x000 card. * * Input: *      ha = adapter state pointer. * * Returns: *      qla2x00 local function return status code. * * Context: *      Kernel context. */intqla2x00_cfg_init(scsi_qla_host_t *ha){	int	rval;	ENTER("qla2x00_cfg_init");	set_bit(CFG_ACTIVE, &ha->cfg_flags);	if (!mp_initialized) {		/* First HBA, initialize the failover global properties */		qla2x00_fo_init_params(ha);		/* If the user specified a device configuration then		 * it is use as the configuration. Otherwise, we wait		 * for path discovery.		 */		if ( mp_config_required )			qla2x00_cfg_build_path_tree(ha);	}	rval = qla2x00_cfg_path_discovery(ha);	clear_bit(CFG_ACTIVE, &ha->cfg_flags);	LEAVE("qla2x00_cfg_init");	return rval;}/* * qla2x00_cfg_path_discovery *      Discover the path configuration from the device configuration *      for the specified host adapter and build the path search tree. *      This function is called after the lower level driver has *      completed its port and lun discovery. * * Input: *      ha = adapter state pointer. * * Returns: *      qla2x00 local function return status code. * * Context: *      Kernel context. */intqla2x00_cfg_path_discovery(scsi_qla_host_t *ha){	int		rval = QLA2X00_SUCCESS;	mp_host_t	*host;	uint8_t		*name;	ENTER("qla2x00_cfg_path_discovery");	name = 	&ha->init_cb->node_name[0];	set_bit(CFG_ACTIVE, &ha->cfg_flags);	/* Initialize the path tree for this adapter */	host = qla2x00_find_host_by_name(name);	if ( mp_config_required ) {		if (host == NULL ) {			DEBUG4(printk("cfg_path_discovery: host not found, "				"node name = "				"%02x%02x%02x%02x%02x%02x%02x%02x\n",				name[0], name[1], name[2], name[3],				name[4], name[5], name[6], name[7]);)			rval = QLA2X00_FUNCTION_FAILED;		} else if (ha->instance != host->instance) {			DEBUG4(printk("cfg_path_discovery: host instance "				"don't match - instance=%ld.\n",				ha->instance);)			rval = QLA2X00_FUNCTION_FAILED;		}	} else if ( host == NULL ) {		/* New host adapter so allocate it */		if ( (host = qla2x00_alloc_host(ha)) == NULL ) {			printk(KERN_INFO				"qla2x00(%d): Couldn't allocate "				"host - ha = %p.\n",				(int)ha->instance, ha);			rval = QLA2X00_FUNCTION_FAILED;		}	}	/* Fill in information about host */	if (host != NULL ) {		host->flags |= MP_HOST_FLAG_NEEDS_UPDATE;		host->fcport = ha->fcport;		/* Check if multipath is enabled */		if (!qla2x00_update_mp_host(host)) {			rval = QLA2X00_FUNCTION_FAILED;		}	}	if (rval != QLA2X00_SUCCESS) {		/* EMPTY */		DEBUG4(printk("qla2x00_path_discovery: Exiting FAILED\n");)	} else {		LEAVE("qla2x00_cfg_path_discovery");	}	clear_bit(CFG_ACTIVE, &ha->cfg_flags);	return rval;}/* * qla2x00_cfg_event_notifiy *      Callback for host driver to notify us of configuration changes. * * Input: *      ha = adapter state pointer. *      i_type = event type * * Returns: * * Context: *      Kernel context. */intqla2x00_cfg_event_notify(scsi_qla_host_t *ha, uint32_t i_type){	mp_host_t	*host;			/* host adapter pointer */	ENTER("qla2x00_cfg_event_notify");	set_bit(CFG_ACTIVE, &ha->cfg_flags);	switch (i_type) {		case MP_NOTIFY_RESET_DETECTED:			DEBUG(printk("scsi%ld: MP_NOTIFY_RESET_DETECTED "					"- no action\n",					ha->host_no);)				break;		case MP_NOTIFY_PWR_LOSS:			DEBUG(printk("scsi%ld: MP_NOTIFY_PWR_LOSS - "					"update tree\n",					ha->host_no);)			/*			 * Update our path tree in case we are			 * losing the adapter			 */			qla2x00_update_mp_tree();			/* Free our resources for adapter */			break;		case MP_NOTIFY_LOOP_UP:			DEBUG(printk("scsi%ld: MP_NOTIFY_LOOP_UP - "					"update host tree\n",					ha->host_no);)			/* Adapter is back up with new configuration */			if ((host = qla2x00_cfg_find_host(ha)) != NULL) {				host->flags |= MP_HOST_FLAG_NEEDS_UPDATE;				host->fcport = ha->fcport;				qla2x00_update_mp_tree();			}			break;		case MP_NOTIFY_LOOP_DOWN:		case MP_NOTIFY_BUS_RESET:			DEBUG(printk("scsi%ld: MP_NOTIFY_OTHERS - "					"no action\n",					ha->host_no);)			break;		default:			break;	}	clear_bit(CFG_ACTIVE, &ha->cfg_flags);	LEAVE("qla2x00_cfg_event_notify");	return QLA2X00_SUCCESS;}/* * qla2x00_cfg_failover *      A problem has been detected with the current path for this *      lun.  Select the next available path as the current path *      for this device. * * Inputs: *      ha = pointer to host adapter *      fp - pointer to failed fc_lun (failback lun) *      tgt - pointer to target * * Returns: *      pointer to new fc_lun_t, or NULL if failover fails. */fc_lun_t	*qla2x00_cfg_failover(scsi_qla_host_t *ha, fc_lun_t *fp,                     os_tgt_t *tgt, srb_t *sp){	mp_host_t	*host;			/* host adapter pointer */	mp_device_t	*dp;			/* virtual device pointer */	mp_path_t	*new_path;		/* new path pointer */	fc_lun_t	*new_fp = NULL;	ENTER("qla2x00_cfg_failover");	set_bit(CFG_ACTIVE, &ha->cfg_flags);	if ((host = qla2x00_cfg_find_host(ha)) != NULL) {		if ((dp = qla2x00_find_mp_dev_by_name(					host, tgt->fc_name)) != NULL ) {			DEBUG3(printk("qla2x00_cfg_failover: dp = %p\n", dp);)			/*			 * Point at the next path in the path list if there is			 * one, and if it hasn't already been failed over by			 * another I/O. If there is only one path continuer			 * to point at it.			 */			new_path = qla2x00_select_next_path(host, dp, fp->lun);			DEBUG3(printk("cfg_failover: new path @ %p\n",						new_path);)			new_fp = qla2x00_find_matching_lun(fp->lun, new_path);			DEBUG3(printk("cfg_failover: new fp lun @ %p\n",						new_fp);)			qla2x00_cfg_register_failover_lun(dp, sp, new_fp);		} else {			printk(KERN_INFO				"qla2x00(%d): Couldn't find device "				"to failover\n",				host->instance);		}	}	clear_bit(CFG_ACTIVE, &ha->cfg_flags);	LEAVE("qla2x00_cfg_failover");	return new_fp;}/* * IOCTL support */#define CFG_IOCTL#if defined(CFG_IOCTL)/* * qla2x00_cfg_get_paths *      Get list of paths EXT_FO_GET_PATHS. * * Input: *      ha = pointer to adapter *      bp = pointer to buffer *      cmd = Pointer to kernel copy of EXT_IOCTL. * * Return; *      0 on success or errno. * * Context: *      Kernel context. */uint32_tqla2x00_cfg_get_paths(EXT_IOCTL *cmd, FO_GET_PATHS *bp, int mode){	FO_PATHS_INFO	*paths,	*u_paths;	FO_PATH_ENTRY	*entry;	EXT_DEST_ADDR   *sap = &bp->HbaAddr;	mp_host_t	*host;		/* host adapter pointer */	mp_device_t	*dp;		/* virtual device pointer */	mp_path_t	*path;		/* path pointer */	mp_path_list_t	*path_list;	/* path list pointer */	int	cnt;	uint32_t	rval = 0;	scsi_qla_host_t *ha;	u_paths = (FO_PATHS_INFO *) cmd->ResponseAdr;	ha = qla2x00_get_hba((int)bp->HbaInstance);	if ((host = qla2x00_cfg_find_host(ha)) == NULL) {		cmd->Status = EXT_STATUS_DEV_NOT_FOUND;		cmd->DetailStatus = EXT_DSTATUS_HBA_INST;		DEBUG4(printk("qla2x00_get_paths: cannot find target (%ld)\n",				ha->instance);)		return ENODEV;	}	if ((paths = (FO_PATHS_INFO *)kmem_zalloc(sizeof(FO_PATHS_INFO),					GFP_ATOMIC,20)) == NULL) {		DEBUG4(printk("qla_cfg_get_paths: failed to allocate memory "				"of size (%d)\n",				(int)sizeof(FO_PATHS_INFO));)		return 1;	}	/* Scan for mp_dev by nodename *ONLY* */	if (sap->DestType != EXT_DEF_DESTTYPE_WWNN) {		cmd->Status = EXT_STATUS_INVALID_PARAM;		cmd->DetailStatus = EXT_DSTATUS_TARGET;		rval = ENODEV;		DEBUG4(printk("qla2x00_cfg_get_paths: target ca be accessed "					"by NodeName only.");)	} else if ((dp = qla2x00_find_mp_dev_by_name(host,					sap->DestAddr.WWNN)) != NULL) {		path_list = dp->path_list;		paths->HbaInstance = bp->HbaInstance;		paths->PathCount           = path_list->path_cnt;		paths->VisiblePathIndex    = path_list->visible;		/* copy current paths */		memcpy(paths->CurrentPathIndex,				path_list->current_path,				sizeof(paths->CurrentPathIndex));		path = path_list->last;		for (cnt = 0; cnt < path_list->path_cnt; cnt++) {			entry = &(paths->PathEntry[path->id]);			entry->Visible    = (path->id == path_list->visible);			entry->HbaInstance = path->host->instance;			memcpy(entry->PortName,					path->portname,					EXT_DEF_WWP_NAME_SIZE);			path = path->next;		}		/* copy data to user */		copy_to_user(&u_paths->PathCount, &paths->PathCount, 4);		copy_to_user(&u_paths->CurrentPathIndex,				&paths->CurrentPathIndex,				sizeof(paths->CurrentPathIndex));		copy_to_user(&u_paths->PathEntry,				&paths->PathEntry,				sizeof(paths->PathEntry));	} else {		cmd->Status = EXT_STATUS_DEV_NOT_FOUND;		cmd->DetailStatus = EXT_DSTATUS_TARGET;		DEBUG4(printk("qla2x00_cfg_get_paths: cannot find device "				"(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n.",				sap->DestAddr.WWNN[0],				sap->DestAddr.WWNN[1],				sap->DestAddr.WWNN[2],				sap->DestAddr.WWNN[3],				sap->DestAddr.WWNN[4],				sap->DestAddr.WWNN[5],				sap->DestAddr.WWNN[6],				sap->DestAddr.WWNN[7]);)		rval = ENODEV;	}	KMEM_FREE(paths, sizeof(paths));	return rval;}/* * qla2x00_cfg_set_current_path *      Set the current failover path EXT_FO_GET_PATHS IOCTL call. * * Input: *      ha = pointer to adapter *      bp = pointer to buffer *      cmd = Pointer to kernel copy of EXT_IOCTL. * * Return; *      0 on success or errno. * * Context: *      Kernel context. */intqla2x00_cfg_set_current_path(EXT_IOCTL *cmd, FO_SET_CURRENT_PATH *bp, int mode ){	uint8_t         orig_id, new_id;	mp_host_t       *host, *new_host;	mp_device_t     *dp;	mp_path_list_t  *path_list;	EXT_DEST_ADDR   *sap = &bp->HbaAddr;	uint32_t        rval = 0;	scsi_qla_host_t *ha;	mp_path_t       *new_path, *old_path;	/* First find the adapter with the instance number. */	ha = qla2x00_get_hba((int)bp->HbaInstance);	if ((host = qla2x00_cfg_find_host(ha)) != NULL) {		set_bit(CFG_ACTIVE, &ha->cfg_flags);		sap = &bp->HbaAddr;		/* Scan for mp_dev by nodename *ONLY* */		if (sap->DestType != EXT_DEF_DESTTYPE_WWNN) {			cmd->Status = EXT_STATUS_DEV_NOT_FOUND;			cmd->DetailStatus = EXT_DSTATUS_TARGET;			rval = ENODEV;			DEBUG4(printk("qla2x00_cfg_set_current_path: "					"target ca be accessed by "					"NodeName only.");)		} else if ((dp = qla2x00_find_mp_dev_by_name(					host, sap->DestAddr.WWNN)) != NULL) {			path_list = dp->path_list;			if (bp->NewCurrentPathIndex < MAX_PATHS_PER_DEVICE &&				sap->Lun < MAX_LUNS &&				bp->NewCurrentPathIndex < path_list->path_cnt) {				orig_id = path_list->current_path[sap->Lun];				DEBUG(printk("qla2x00_set_current_path: "					"dev no  %d, lun %d, "					"newindex %d, oldindex %d "					"nn=%02x%02x%02x%02x%02x%02x%02x%02x\n",					dp->dev_id, sap->Lun,					bp->NewCurrentPathIndex, orig_id,					host->nodename[0], host->nodename[1],					host->nodename[2], host->nodename[3],					host->nodename[4], host->nodename[5],					host->nodename[6], host->nodename[7]);)				if (bp->NewCurrentPathIndex != orig_id) {					/* Acquire the update spinlock. */					/* Set the new current path. */					new_id = path_list->

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -