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

📄 zfcp_aux.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (sg_list != NULL) {		zfcp_sg_list_free(sg_list);		kfree(sg_list);	}	kfree(sense_data);	return retval;}/** * zfcp_sg_list_alloc - create a scatter-gather list of the specified size * @sg_list: structure describing a scatter gather list * @size: size of scatter-gather list * Return: 0 on success, else -ENOMEM * * In sg_list->sg a pointer to the created scatter-gather list is returned, * or NULL if we run out of memory. sg_list->count specifies the number of * elements of the scatter-gather list. The maximum size of a single element * in the scatter-gather list is PAGE_SIZE. */static inline intzfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size){	struct scatterlist *sg;	unsigned int i;	int retval = 0;	void *address;	BUG_ON(sg_list == NULL);	sg_list->count = size >> PAGE_SHIFT;	if (size & ~PAGE_MASK)		sg_list->count++;	sg_list->sg = kmalloc(sg_list->count * sizeof(struct scatterlist),			      GFP_KERNEL);	if (sg_list->sg == NULL) {		sg_list->count = 0;		retval = -ENOMEM;		goto out;	}	memset(sg_list->sg, 0, sg_list->count * sizeof(struct scatterlist));	for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) {		sg->length = min(size, PAGE_SIZE);		sg->offset = 0;		address = (void *) get_zeroed_page(GFP_KERNEL);		if (address == NULL) {			sg_list->count = i;			zfcp_sg_list_free(sg_list);			retval = -ENOMEM;			goto out;		}		zfcp_address_to_sg(address, sg);		size -= sg->length;	} out:	return retval;}/** * zfcp_sg_list_free - free memory of a scatter-gather list * @sg_list: structure describing a scatter-gather list * * Memory for each element in the scatter-gather list is freed. * Finally sg_list->sg is freed itself and sg_list->count is reset. */static inline voidzfcp_sg_list_free(struct zfcp_sg_list *sg_list){	struct scatterlist *sg;	unsigned int i;	BUG_ON(sg_list == NULL);	for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++)		free_page((unsigned long) zfcp_sg_to_address(sg));	sg_list->count = 0;	kfree(sg_list->sg);}/** * zfcp_sg_size - determine size of a scatter-gather list * @sg: array of (struct scatterlist) * @sg_count: elements in array * Return: size of entire scatter-gather list */size_tzfcp_sg_size(struct scatterlist *sg, unsigned int sg_count){	unsigned int i;	struct scatterlist *p;	size_t size;	size = 0;	for (i = 0, p = sg; i < sg_count; i++, p++) {		BUG_ON(p == NULL);		size += p->length;	}	return size;}/** * zfcp_sg_list_copy_from_user -copy data from user space to scatter-gather list * @sg_list: structure describing a scatter-gather list * @user_buffer: pointer to buffer in user space * @size: number of bytes to be copied * Return: 0 on success, -EFAULT if copy_from_user fails. */static inline intzfcp_sg_list_copy_from_user(struct zfcp_sg_list *sg_list,			    void __user *user_buffer,                            size_t size){	struct scatterlist *sg;	unsigned int length;	void *zfcp_buffer;	int retval = 0;	BUG_ON(sg_list == NULL);	if (zfcp_sg_size(sg_list->sg, sg_list->count) < size)		return -EFAULT;	for (sg = sg_list->sg; size > 0; sg++) {		length = min((unsigned int)size, sg->length);		zfcp_buffer = zfcp_sg_to_address(sg);		if (copy_from_user(zfcp_buffer, user_buffer, length)) {			retval = -EFAULT;			goto out;		}		user_buffer += length;		size -= length;	} out:	return retval;}/** * zfcp_sg_list_copy_to_user - copy data from scatter-gather list to user space * @user_buffer: pointer to buffer in user space * @sg_list: structure describing a scatter-gather list * @size: number of bytes to be copied * Return: 0 on success, -EFAULT if copy_to_user fails */static inline intzfcp_sg_list_copy_to_user(void __user  *user_buffer,			  struct zfcp_sg_list *sg_list,                          size_t size){	struct scatterlist *sg;	unsigned int length;	void *zfcp_buffer;	int retval = 0;	BUG_ON(sg_list == NULL);	if (zfcp_sg_size(sg_list->sg, sg_list->count) < size)		return -EFAULT;	for (sg = sg_list->sg; size > 0; sg++) {		length = min((unsigned int) size, sg->length);		zfcp_buffer = zfcp_sg_to_address(sg);		if (copy_to_user(user_buffer, zfcp_buffer, length)) {			retval = -EFAULT;			goto out;		}		user_buffer += length;		size -= length;	} out:	return retval;}#undef ZFCP_LOG_AREA/****************************************************************//****** Functions for configuration/set-up of structures ********//****************************************************************/#define ZFCP_LOG_AREA			ZFCP_LOG_AREA_CONFIG/** * zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN * @port: pointer to port to search for unit * @fcp_lun: FCP LUN to search for * Traverse list of all units of a port and return pointer to a unit * with the given FCP LUN. */struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, fcp_lun_t fcp_lun){	struct zfcp_unit *unit;	int found = 0;	list_for_each_entry(unit, &port->unit_list_head, list) {		if ((unit->fcp_lun == fcp_lun) &&		    !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status))		{			found = 1;			break;		}	}	return found ? unit : NULL;}/** * zfcp_get_port_by_wwpn - find port in port list of adapter by wwpn * @adapter: pointer to adapter to search for port * @wwpn: wwpn to search for * Traverse list of all ports of an adapter and return pointer to a port * with the given wwpn. */struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter, wwn_t wwpn){	struct zfcp_port *port;	int found = 0;	list_for_each_entry(port, &adapter->port_list_head, list) {		if ((port->wwpn == wwpn) &&		    !(atomic_read(&port->status) &		      (ZFCP_STATUS_PORT_NO_WWPN | ZFCP_STATUS_COMMON_REMOVE))) {			found = 1;			break;		}	}	return found ? port : NULL;}/** * zfcp_get_port_by_did - find port in port list of adapter by d_id * @adapter: pointer to adapter to search for port * @d_id: d_id to search for * Traverse list of all ports of an adapter and return pointer to a port * with the given d_id. */struct zfcp_port *zfcp_get_port_by_did(struct zfcp_adapter *adapter, u32 d_id){	struct zfcp_port *port;	int found = 0;	list_for_each_entry(port, &adapter->port_list_head, list) {		if ((port->d_id == d_id) &&		    !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status))		{			found = 1;			break;		}	}	return found ? port : NULL;}/** * zfcp_get_adapter_by_busid - find adpater in adapter list by bus_id * @bus_id: bus_id to search for * Traverse list of all adapters and return pointer to an adapter * with the given bus_id. */struct zfcp_adapter *zfcp_get_adapter_by_busid(char *bus_id){	struct zfcp_adapter *adapter;	int found = 0;	list_for_each_entry(adapter, &zfcp_data.adapter_list_head, list) {		if ((strncmp(bus_id, zfcp_get_busid_by_adapter(adapter),			     BUS_ID_SIZE) == 0) &&		    !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE,				      &adapter->status)){			found = 1;			break;		}	}	return found ? adapter : NULL;}/** * zfcp_unit_enqueue - enqueue unit to unit list of a port. * @port: pointer to port where unit is added * @fcp_lun: FCP LUN of unit to be enqueued * Return: pointer to enqueued unit on success, NULL on error * Locks: config_sema must be held to serialize changes to the unit list * * Sets up some unit internal structures and creates sysfs entry. */struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun){	struct zfcp_unit *unit, *tmp_unit;	scsi_lun_t scsi_lun;	int found;	/*	 * check that there is no unit with this FCP_LUN already in list	 * and enqueue it.	 * Note: Unlike for the adapter and the port, this is an error	 */	read_lock_irq(&zfcp_data.config_lock);	unit = zfcp_get_unit_by_lun(port, fcp_lun);	read_unlock_irq(&zfcp_data.config_lock);	if (unit)		return NULL;	unit = kmalloc(sizeof (struct zfcp_unit), GFP_KERNEL);	if (!unit)		return NULL;	memset(unit, 0, sizeof (struct zfcp_unit));	/* initialise reference count stuff */	atomic_set(&unit->refcount, 0);	init_waitqueue_head(&unit->remove_wq);	unit->port = port;	unit->fcp_lun = fcp_lun;	/* setup for sysfs registration */	snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", fcp_lun);	unit->sysfs_device.parent = &port->sysfs_device;	unit->sysfs_device.release = zfcp_sysfs_unit_release;	dev_set_drvdata(&unit->sysfs_device, unit);	/* mark unit unusable as long as sysfs registration is not complete */	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);	if (device_register(&unit->sysfs_device)) {		kfree(unit);		return NULL;	}	if (zfcp_sysfs_unit_create_files(&unit->sysfs_device)) {		device_unregister(&unit->sysfs_device);		return NULL;	}	zfcp_unit_get(unit);	scsi_lun = 0;	found = 0;	write_lock_irq(&zfcp_data.config_lock);	list_for_each_entry(tmp_unit, &port->unit_list_head, list) {		if (tmp_unit->scsi_lun != scsi_lun) {			found = 1;			break;		}		scsi_lun++;	}	unit->scsi_lun = scsi_lun;	if (found)		list_add_tail(&unit->list, &tmp_unit->list);	else		list_add_tail(&unit->list, &port->unit_list_head);	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);	write_unlock_irq(&zfcp_data.config_lock);	port->units++;	zfcp_port_get(port);	return unit;}voidzfcp_unit_dequeue(struct zfcp_unit *unit){	zfcp_unit_wait(unit);	write_lock_irq(&zfcp_data.config_lock);	list_del(&unit->list);	write_unlock_irq(&zfcp_data.config_lock);	unit->port->units--;	zfcp_port_put(unit->port);	zfcp_sysfs_unit_remove_files(&unit->sysfs_device);	device_unregister(&unit->sysfs_device);}static void *zfcp_mempool_alloc(gfp_t gfp_mask, void *size){	return kmalloc((size_t) size, gfp_mask);}static voidzfcp_mempool_free(void *element, void *size){	kfree(element);}/* * Allocates a combined QTCB/fsf_req buffer for erp actions and fcp/SCSI * commands. * It also genrates fcp-nameserver request/response buffer and unsolicited  * status read fsf_req buffers. * * locks:       must only be called with zfcp_data.config_sema taken */static intzfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter){	adapter->pool.fsf_req_erp =		mempool_create(ZFCP_POOL_FSF_REQ_ERP_NR,			       zfcp_mempool_alloc, zfcp_mempool_free, (void *)			       sizeof(struct zfcp_fsf_req_pool_element));	if (NULL == adapter->pool.fsf_req_erp)		return -ENOMEM;	adapter->pool.fsf_req_scsi =		mempool_create(ZFCP_POOL_FSF_REQ_SCSI_NR,			       zfcp_mempool_alloc, zfcp_mempool_free, (void *)			       sizeof(struct zfcp_fsf_req_pool_element));	if (NULL == adapter->pool.fsf_req_scsi)		return -ENOMEM;	adapter->pool.fsf_req_abort =		mempool_create(ZFCP_POOL_FSF_REQ_ABORT_NR,			       zfcp_mempool_alloc, zfcp_mempool_free, (void *)			       sizeof(struct zfcp_fsf_req_pool_element));	if (NULL == adapter->pool.fsf_req_abort)		return -ENOMEM;	adapter->pool.fsf_req_status_read =		mempool_create(ZFCP_POOL_STATUS_READ_NR,			       zfcp_mempool_alloc, zfcp_mempool_free,			       (void *) sizeof(struct zfcp_fsf_req));	if (NULL == adapter->pool.fsf_req_status_read)		return -ENOMEM;	adapter->pool.data_status_read =		mempool_create(ZFCP_POOL_STATUS_READ_NR,			       zfcp_mempool_alloc, zfcp_mempool_free,			       (void *) sizeof(struct fsf_status_read_buffer));	if (NULL == adapter->pool.data_status_read)

⌨️ 快捷键说明

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