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

📄 zfcp_aux.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
		return -ENOMEM;	adapter->pool.data_gid_pn =		mempool_create(ZFCP_POOL_DATA_GID_PN_NR,			       zfcp_mempool_alloc, zfcp_mempool_free, (void *)			       sizeof(struct zfcp_gid_pn_data));	if (NULL == adapter->pool.data_gid_pn)		return -ENOMEM;	return 0;}/** * zfcp_free_low_mem_buffers - free memory pools of an adapter * @adapter: pointer to zfcp_adapter for which memory pools should be freed * locking:  zfcp_data.config_sema must be held */static voidzfcp_free_low_mem_buffers(struct zfcp_adapter *adapter){	if (adapter->pool.fsf_req_erp)		mempool_destroy(adapter->pool.fsf_req_erp);	if (adapter->pool.fsf_req_scsi)		mempool_destroy(adapter->pool.fsf_req_scsi);	if (adapter->pool.fsf_req_abort)		mempool_destroy(adapter->pool.fsf_req_abort);	if (adapter->pool.fsf_req_status_read)		mempool_destroy(adapter->pool.fsf_req_status_read);	if (adapter->pool.data_status_read)		mempool_destroy(adapter->pool.data_status_read);	if (adapter->pool.data_gid_pn)		mempool_destroy(adapter->pool.data_gid_pn);}voidzfcp_dummy_release(struct device *dev){	return;}/* * Enqueues an adapter at the end of the adapter list in the driver data. * All adapter internal structures are set up. * Proc-fs entries are also created. * * returns:	0             if a new adapter was successfully enqueued *              ZFCP_KNOWN    if an adapter with this devno was already present *		-ENOMEM       if alloc failed * locks:	config_sema must be held to serialise changes to the adapter list */struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device){	int retval = 0;	struct zfcp_adapter *adapter;	/*	 * Note: It is safe to release the list_lock, as any list changes 	 * are protected by the config_sema, which must be held to get here	 */	/* try to allocate new adapter data structure (zeroed) */	adapter = kmalloc(sizeof (struct zfcp_adapter), GFP_KERNEL);	if (!adapter) {		ZFCP_LOG_INFO("error: allocation of base adapter "			      "structure failed\n");		goto out;	}	memset(adapter, 0, sizeof (struct zfcp_adapter));	ccw_device->handler = NULL;	/* save ccw_device pointer */	adapter->ccw_device = ccw_device;	retval = zfcp_qdio_allocate_queues(adapter);	if (retval)		goto queues_alloc_failed;	retval = zfcp_qdio_allocate(adapter);	if (retval)		goto qdio_allocate_failed;	retval = zfcp_allocate_low_mem_buffers(adapter);	if (retval) {		ZFCP_LOG_INFO("error: pool allocation failed\n");		goto failed_low_mem_buffers;	}	/* initialise reference count stuff */	atomic_set(&adapter->refcount, 0);	init_waitqueue_head(&adapter->remove_wq);	/* initialise list of ports */	INIT_LIST_HEAD(&adapter->port_list_head);	/* initialise list of ports to be removed */	INIT_LIST_HEAD(&adapter->port_remove_lh);	/* initialize list of fsf requests */	spin_lock_init(&adapter->fsf_req_list_lock);	INIT_LIST_HEAD(&adapter->fsf_req_list_head);	/* initialize debug locks */	spin_lock_init(&adapter->erp_dbf_lock);	spin_lock_init(&adapter->hba_dbf_lock);	spin_lock_init(&adapter->san_dbf_lock);	spin_lock_init(&adapter->scsi_dbf_lock);	/* initialize error recovery stuff */	rwlock_init(&adapter->erp_lock);	sema_init(&adapter->erp_ready_sem, 0);	INIT_LIST_HEAD(&adapter->erp_ready_head);	INIT_LIST_HEAD(&adapter->erp_running_head);	/* initialize abort lock */	rwlock_init(&adapter->abort_lock);	/* initialise some erp stuff */	init_waitqueue_head(&adapter->erp_thread_wqh);	init_waitqueue_head(&adapter->erp_done_wqh);	/* initialize lock of associated request queue */	rwlock_init(&adapter->request_queue.queue_lock);	/* intitialise SCSI ER timer */	init_timer(&adapter->scsi_er_timer);	/* set FC service class used per default */	adapter->fc_service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT;	sprintf(adapter->name, "%s", zfcp_get_busid_by_adapter(adapter));	ASCEBC(adapter->name, strlen(adapter->name));	/* mark adapter unusable as long as sysfs registration is not complete */	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);	adapter->ccw_device = ccw_device;	dev_set_drvdata(&ccw_device->dev, adapter);	if (zfcp_sysfs_adapter_create_files(&ccw_device->dev))		goto sysfs_failed;	adapter->generic_services.parent = &adapter->ccw_device->dev;	adapter->generic_services.release = zfcp_dummy_release;	snprintf(adapter->generic_services.bus_id, BUS_ID_SIZE,		 "generic_services");	if (device_register(&adapter->generic_services))		goto generic_services_failed;	/* put allocated adapter at list tail */	write_lock_irq(&zfcp_data.config_lock);	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);	list_add_tail(&adapter->list, &zfcp_data.adapter_list_head);	write_unlock_irq(&zfcp_data.config_lock);	zfcp_data.adapters++;	goto out; generic_services_failed:	zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); sysfs_failed:	dev_set_drvdata(&ccw_device->dev, NULL); failed_low_mem_buffers:	zfcp_free_low_mem_buffers(adapter);	if (qdio_free(ccw_device) != 0)		ZFCP_LOG_NORMAL("bug: qdio_free for adapter %s failed\n",				zfcp_get_busid_by_adapter(adapter)); qdio_allocate_failed:	zfcp_qdio_free_queues(adapter); queues_alloc_failed:	kfree(adapter);	adapter = NULL; out:	return adapter;}/* * returns:	0 - struct zfcp_adapter  data structure successfully removed *		!0 - struct zfcp_adapter  data structure could not be removed *			(e.g. still used) * locks:	adapter list write lock is assumed to be held by caller *              adapter->fsf_req_list_lock is taken and released within this  *              function and must not be held on entry */voidzfcp_adapter_dequeue(struct zfcp_adapter *adapter){	int retval = 0;	unsigned long flags;	device_unregister(&adapter->generic_services);	zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);	dev_set_drvdata(&adapter->ccw_device->dev, NULL);	/* sanity check: no pending FSF requests */	spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);	retval = !list_empty(&adapter->fsf_req_list_head);	spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);	if (retval) {		ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, "				"%i requests outstanding\n",				zfcp_get_busid_by_adapter(adapter), adapter,				atomic_read(&adapter->fsf_reqs_active));		retval = -EBUSY;		goto out;	}	/* remove specified adapter data structure from list */	write_lock_irq(&zfcp_data.config_lock);	list_del(&adapter->list);	write_unlock_irq(&zfcp_data.config_lock);	/* decrease number of adapters in list */	zfcp_data.adapters--;	ZFCP_LOG_TRACE("adapter %s (%p) removed from list, "		       "%i adapters still in list\n",		       zfcp_get_busid_by_adapter(adapter),		       adapter, zfcp_data.adapters);	retval = qdio_free(adapter->ccw_device);	if (retval)		ZFCP_LOG_NORMAL("bug: qdio_free for adapter %s failed\n",				zfcp_get_busid_by_adapter(adapter));	zfcp_free_low_mem_buffers(adapter);	/* free memory of adapter data structure and queues */	zfcp_qdio_free_queues(adapter);	ZFCP_LOG_TRACE("freeing adapter structure\n");	kfree(adapter); out:	return;}/** * zfcp_port_enqueue - enqueue port to port list of adapter * @adapter: adapter where remote port is added * @wwpn: WWPN of the remote port to be enqueued * @status: initial status for the port * @d_id: destination id of the remote port to be enqueued * Return: pointer to enqueued port on success, NULL on error * Locks: config_sema must be held to serialize changes to the port list * * All port internal structures are set up and the sysfs entry is generated. * d_id is used to enqueue ports with a well known address like the Directory * Service for nameserver lookup. */struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status,		  u32 d_id){	struct zfcp_port *port;	int check_wwpn;	check_wwpn = !(status & ZFCP_STATUS_PORT_NO_WWPN);	/*	 * check that there is no port with this WWPN already in list	 */	if (check_wwpn) {		read_lock_irq(&zfcp_data.config_lock);		port = zfcp_get_port_by_wwpn(adapter, wwpn);		read_unlock_irq(&zfcp_data.config_lock);		if (port)			return NULL;	}	port = kmalloc(sizeof (struct zfcp_port), GFP_KERNEL);	if (!port)		return NULL;	memset(port, 0, sizeof (struct zfcp_port));	/* initialise reference count stuff */	atomic_set(&port->refcount, 0);	init_waitqueue_head(&port->remove_wq);	INIT_LIST_HEAD(&port->unit_list_head);	INIT_LIST_HEAD(&port->unit_remove_lh);	port->adapter = adapter;	if (check_wwpn)		port->wwpn = wwpn;	atomic_set_mask(status, &port->status);	/* setup for sysfs registration */	if (status & ZFCP_STATUS_PORT_WKA) {		switch (d_id) {		case ZFCP_DID_DIRECTORY_SERVICE:			snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,				 "directory");			break;		case ZFCP_DID_MANAGEMENT_SERVICE:			snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,				 "management");			break;		case ZFCP_DID_KEY_DISTRIBUTION_SERVICE:			snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,				 "key_distribution");			break;		case ZFCP_DID_ALIAS_SERVICE:			snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,				 "alias");			break;		case ZFCP_DID_TIME_SERVICE:			snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,				 "time");			break;		default:			kfree(port);			return NULL;		}		port->d_id = d_id;		port->sysfs_device.parent = &adapter->generic_services;	} else {		snprintf(port->sysfs_device.bus_id,			 BUS_ID_SIZE, "0x%016llx", wwpn);		port->sysfs_device.parent = &adapter->ccw_device->dev;	}	port->sysfs_device.release = zfcp_sysfs_port_release;	dev_set_drvdata(&port->sysfs_device, port);	/* mark port unusable as long as sysfs registration is not complete */	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);	if (device_register(&port->sysfs_device)) {		kfree(port);		return NULL;	}	if (zfcp_sysfs_port_create_files(&port->sysfs_device, status)) {		device_unregister(&port->sysfs_device);		return NULL;	}	zfcp_port_get(port);	write_lock_irq(&zfcp_data.config_lock);	list_add_tail(&port->list, &adapter->port_list_head);	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);	if (d_id == ZFCP_DID_DIRECTORY_SERVICE)		if (!adapter->nameserver_port)			adapter->nameserver_port = port;	adapter->ports++;	write_unlock_irq(&zfcp_data.config_lock);	zfcp_adapter_get(adapter);	return port;}voidzfcp_port_dequeue(struct zfcp_port *port){	zfcp_port_wait(port);	write_lock_irq(&zfcp_data.config_lock);	list_del(&port->list);	port->adapter->ports--;	write_unlock_irq(&zfcp_data.config_lock);	if (port->rport)		fc_remote_port_delete(port->rport);	port->rport = NULL;	zfcp_adapter_put(port->adapter);	zfcp_sysfs_port_remove_files(&port->sysfs_device,				     atomic_read(&port->status));	device_unregister(&port->sysfs_device);}/* Enqueues a nameserver port */intzfcp_nameserver_enqueue(struct zfcp_adapter *adapter){	struct zfcp_port *port;	port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA,				 ZFCP_DID_DIRECTORY_SERVICE);	if (!port) {		ZFCP_LOG_INFO("error: enqueue of nameserver port for "			      "adapter %s failed\n",			      zfcp_get_busid_by_adapter(adapter));		return -ENXIO;	}	zfcp_port_put(port);	return 0;}#undef ZFCP_LOG_AREA/****************************************************************//******* Fibre Channel Standard related Functions  **************//****************************************************************/#define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_FCvoidzfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,			   struct fsf_status_read_buffer *status_buffer){	struct fcp_rscn_head *fcp_rscn_head;	struct fcp_rscn_element *fcp_rscn_element;	struct zfcp_port *port;	u16 i;	u16 no_entries;	u32 range_mask;	unsigned long flags;	fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload;	fcp_rscn_element = (struct fcp_rscn_element *) status_buffer->payload;	/* see FC-FS */	no_entries = (fcp_rscn_head->payload_len / 4);	for (i = 1; i < no_entries; i++) {		/* skip head and start with 1st element */		fcp_rscn_element++;		switch (fcp_rscn_element->addr_format) {		case ZFCP_PORT_ADDRESS:			range_mask = ZFCP_PORTS_RANGE_PORT;			break;		case ZFCP_AREA_ADDRESS:			range_mask = ZFCP_PORTS_RANGE_AREA;			break;		case ZFCP_DOMAIN_ADDRESS:			range_mask = ZFCP_PORTS_RANGE_DOMAIN;			break;		case ZFCP_FABRIC_ADDRESS:			range_mask = ZFCP_PORTS_RANGE_FABRIC;			break;		default:			ZFCP_LOG_INFO("incoming RSCN with unknown "				      "address format\n");			continue;		}		read_lock_irqsave(&zfcp_data.config_lock, flags);		list_for_each_entry(port, &adapter->port_list_head, list) {			if (atomic_test_mask			    (ZFCP_STATUS_PORT_WKA, &port->status))				continue;			/* Do we know this port? If not skip it. */			if (!atomic_test_mask

⌨️ 快捷键说明

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