示例#1
0
void
ccw_free_request ( ccw_req_t * request )
{
        int size_needed;

	debug_text_event ( debug_area, 1, "FREE");
	debug_int_event ( debug_area, 1, (long)request);

	/* Sanity checks */
	if ( request == NULL || request->cache == NULL)
                BUG();

        dechain ( request);
	/* Free memory allocated with kmalloc
         * make the same decisions as in ccw_alloc_requets */
	size_needed = (sizeof (ccw_req_t) + 7) & -8;
	if (size_needed + request->datasize <= PAGE_SIZE)
		/* We kept the data with the request */
		size_needed += (request->datasize + 7) & -8;
	else
		kfree(request->data);
	if (size_needed + request->cplength*sizeof(ccw1_t) > PAGE_SIZE)
		/* We kept the CCWs with request */
                kfree(request->cpaddr);
        kmem_cache_free(request -> cache, request);
}
示例#2
0
void ctcm_dbf_longtext(enum ctcm_dbf_names dbf_nix, int level, char *fmt, ...)
{
	char dbf_txt_buf[64];
	va_list args;

	if (!debug_level_enabled(ctcm_dbf[dbf_nix].id, level))
		return;
	va_start(args, fmt);
	vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args);
	va_end(args);

	debug_text_event(ctcm_dbf[dbf_nix].id, level, dbf_txt_buf);
}
示例#3
0
int
ccwcache_init (void)
{
	int rc = 0;
	int cachind;

        /* initialize variables */
	spin_lock_init(&ccwchain_lock);

	/* allocate a debug area */
	debug_area = debug_register( "ccwcache", 2, 4,sizeof(void*));
	if ( debug_area == NULL )
                BUG();

        debug_register_view(debug_area,&debug_hex_ascii_view);
        debug_register_view(debug_area,&debug_raw_view);
	debug_text_event ( debug_area, 0, "INIT");

	/* First allocate the kmem caches */
	for ( cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ ) {
		int slabsize = SMALLEST_SLAB << cachind;
		debug_text_event ( debug_area, 1, "allc");
		debug_int_event ( debug_area, 1, slabsize);
		sprintf ( ccw_cache_name[cachind], 
			  "%s%d%c", ccw_name_template, slabsize, 0);
		ccw_cache[cachind] = 
			kmem_cache_create( ccw_cache_name[cachind], 
					   slabsize, 0,
					   CCW_CACHE_SLAB_TYPE,
					   NULL, NULL );
		debug_int_event ( debug_area, 1, (long)ccw_cache[cachind]);
		if (ccw_cache[cachind] == NULL)
			panic ("Allocation of CCW cache failed\n");
	}
	return rc;
}
示例#4
0
static ssize_t
vmcp_write(struct file *file, const char __user * buff, size_t count,
	   loff_t * ppos)
{
	char *cmd;
	struct vmcp_session *session;

	if (count > 240)
		return -EINVAL;
	cmd = kmalloc(count + 1, GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;
	if (copy_from_user(cmd, buff, count)) {
		kfree(cmd);
		return -EFAULT;
	}
	cmd[count] = '\0';
	session = (struct vmcp_session *)file->private_data;
	if (down_interruptible(&session->mutex)) {
		kfree(cmd);
		return -ERESTARTSYS;
	}
	if (!session->response)
		session->response = (char *)__get_free_pages(GFP_KERNEL
						| __GFP_REPEAT 	| GFP_DMA,
						get_order(session->bufsize));
	if (!session->response) {
		up(&session->mutex);
		kfree(cmd);
		return -ENOMEM;
	}
	debug_text_event(vmcp_debug, 1, cmd);
	session->resp_size = cpcmd(cmd, session->response,
				     session->bufsize,
				     &session->resp_code);
	up(&session->mutex);
	kfree(cmd);
	*ppos = 0;		/* reset the file pointer after a command */
	return count;
}
示例#5
0
/*
 * function:   	zfcp_qdio_handler_error_check
 *
 * purpose:     called by the response handler to determine error condition
 *
 * returns:	error flag
 *
 */
static inline int
zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter,
			      unsigned int status,
			      unsigned int qdio_error, unsigned int siga_error)
{
	int retval = 0;

	if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) {
		if (status & QDIO_STATUS_INBOUND_INT) {
			ZFCP_LOG_TRACE("status is"
				       " QDIO_STATUS_INBOUND_INT \n");
		}
		if (status & QDIO_STATUS_OUTBOUND_INT) {
			ZFCP_LOG_TRACE("status is"
				       " QDIO_STATUS_OUTBOUND_INT \n");
		}
	}			// if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE))
	if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) {
		retval = -EIO;

		ZFCP_LOG_FLAGS(1, "QDIO_STATUS_LOOK_FOR_ERROR \n");

		ZFCP_LOG_INFO("QDIO problem occurred (status=0x%x, "
			      "qdio_error=0x%x, siga_error=0x%x)\n",
			      status, qdio_error, siga_error);

		if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) {
			ZFCP_LOG_FLAGS(2,
				       "QDIO_STATUS_ACTIVATE_CHECK_CONDITION\n");
		}
		if (status & QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR) {
			ZFCP_LOG_FLAGS(2,
				       "QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR\n");
		}
		if (status & QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR) {
			ZFCP_LOG_FLAGS(2,
				       "QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR\n");
		}

		if (siga_error & QDIO_SIGA_ERROR_ACCESS_EXCEPTION) {
			ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_ACCESS_EXCEPTION\n");
		}

		if (siga_error & QDIO_SIGA_ERROR_B_BIT_SET) {
			ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_B_BIT_SET\n");
		}

		switch (qdio_error) {
		case 0:
			ZFCP_LOG_FLAGS(3, "QDIO_OK");
			break;
		case SLSB_P_INPUT_ERROR:
			ZFCP_LOG_FLAGS(1, "SLSB_P_INPUT_ERROR\n");
			break;
		case SLSB_P_OUTPUT_ERROR:
			ZFCP_LOG_FLAGS(1, "SLSB_P_OUTPUT_ERROR\n");
			break;
		default:
			ZFCP_LOG_NORMAL("bug: unknown QDIO error 0x%x\n",
					qdio_error);
			break;
		}
		/* Restarting IO on the failed adapter from scratch */
		debug_text_event(adapter->erp_dbf, 1, "qdio_err");
               /*
                * Since we have been using this adapter, it is save to assume
                * that it is not failed but recoverable. The card seems to
                * report link-up events by self-initiated queue shutdown.
                * That is why we need to clear the the link-down flag
                * which is set again in case we have missed by a mile.
                */
               zfcp_erp_adapter_reopen(
                       adapter, 
                       ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
                       ZFCP_STATUS_COMMON_ERP_FAILED);
	}
	return retval;
}
示例#6
0
/* 
 * ccw_req_t *ccw_alloc_request ( int cplength, int datasize )
 * allocates a ccw_req_t, that 
 * - can hold a CP of cplength CCWS
 * - can hold additional data up to datasize 
 */
ccw_req_t *
ccw_alloc_request ( char *magic, int cplength, int datasize )
{
	ccw_req_t * request = NULL;
        int size_needed;
	int data_offset, ccw_offset;
	int cachind;

	/* Sanity checks */
	if ( magic == NULL || datasize > PAGE_SIZE ||
	     cplength == 0 || (cplength*sizeof(ccw1_t)) > PAGE_SIZE)
		BUG();
	debug_text_event ( debug_area, 1, "ALLC");
	debug_text_event ( debug_area, 1, magic);
	debug_int_event ( debug_area, 1, cplength);
	debug_int_event ( debug_area, 1, datasize);

	/* We try to keep things together in memory */
	size_needed = (sizeof (ccw_req_t) + 7) & -8;
	data_offset = ccw_offset = 0;
	if (size_needed + datasize <= PAGE_SIZE) {
		/* Keep data with the request */
		data_offset = size_needed;
		size_needed += (datasize + 7) & -8;
	}
	if (size_needed + cplength*sizeof(ccw1_t) <= PAGE_SIZE) {
		/* Keep CCWs with request */
		ccw_offset = size_needed;
		size_needed += cplength*sizeof(ccw1_t);
	}

	/* determine cache index for the requested size */
	for (cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ )
	   if ( size_needed < (SMALLEST_SLAB << cachind) ) 
			break;

	/* Try to fulfill the request from a cache */
	if ( ccw_cache[cachind] == NULL )
		BUG();
	request = kmem_cache_alloc ( ccw_cache[cachind], CCW_CACHE_TYPE );
	if (request == NULL)
		return NULL;
	memset ( request, 0, (SMALLEST_SLAB << cachind));
	request->cache = ccw_cache[cachind];

	/* Allocate memory for the extra data */
	if (data_offset == 0) {
		/* Allocated memory for extra data with kmalloc */
	    request->data = (void *) kmalloc(datasize, CCW_CACHE_TYPE );
		if (request->data == NULL) {
			printk(KERN_WARNING PRINTK_HEADER 
			       "Couldn't allocate data area\n");
			kmem_cache_free(request->cache, request);
			return NULL;
		}
	} else
		/* Extra data already allocated with the request */
		request->data = (void *) ((addr_t) request + data_offset);

	/* Allocate memory for the channel program */
	if (ccw_offset == 0) {
		/* Allocated memory for the channel program with kmalloc */
		request->cpaddr = (ccw1_t *) kmalloc(cplength*sizeof(ccw1_t),
						     CCW_CACHE_TYPE);
		if (request->cpaddr == NULL) {
			printk (KERN_DEBUG PRINTK_HEADER
				"Couldn't allocate ccw area\n");
			if (data_offset == 0)
				kfree(request->data);
			kmem_cache_free(request->cache, request);
			return NULL;
		}
	} else
		/* Channel program already allocated with the request */
		request->cpaddr = (ccw1_t *) ((addr_t) request + ccw_offset);

	memset ( request->data, 0, datasize );
	memset ( request->cpaddr, 0, cplength*sizeof(ccw1_t) );
	strncpy ( (char *)(&request->magic), magic, 4);

	ASCEBC((char *)(&request->magic),4);
	request -> cplength = cplength;
	request -> datasize = datasize;
	/* enqueue request to list of allocated requests */
	enchain(request);
	debug_int_event ( debug_area, 1, (long)request);
	return request;
}