Esempio n. 1
0
/**
 * zfcp_adapter_debug_register - registers debug feature for an adapter
 * @adapter: pointer to adapter for which debug features should be registered
 * return: -ENOMEM on error, 0 otherwise
 */
int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
{
    char dbf_name[DEBUG_MAX_NAME_LEN];

    /* debug feature area which records recovery activity */
    sprintf(dbf_name, "zfcp_%s_rec", zfcp_get_busid_by_adapter(adapter));
    adapter->rec_dbf = debug_register(dbf_name, dbfsize, 1,
                      sizeof(struct zfcp_rec_dbf_record));
    if (!adapter->rec_dbf)
        goto failed;
    debug_register_view(adapter->rec_dbf, &debug_hex_ascii_view);
    debug_register_view(adapter->rec_dbf, &zfcp_rec_dbf_view);
    debug_set_level(adapter->rec_dbf, 3);

    /* debug feature area which records HBA (FSF and QDIO) conditions */
    sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
    adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,
                      sizeof(struct zfcp_hba_dbf_record));
    if (!adapter->hba_dbf)
        goto failed;
    debug_register_view(adapter->hba_dbf, &debug_hex_ascii_view);
    debug_register_view(adapter->hba_dbf, &zfcp_hba_dbf_view);
    debug_set_level(adapter->hba_dbf, 3);

    /* debug feature area which records SAN command failures and recovery */
    sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter));
    adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,
                      sizeof(struct zfcp_san_dbf_record));
    if (!adapter->san_dbf)
        goto failed;
    debug_register_view(adapter->san_dbf, &debug_hex_ascii_view);
    debug_register_view(adapter->san_dbf, &zfcp_san_dbf_view);
    debug_set_level(adapter->san_dbf, 6);

    /* debug feature area which records SCSI command failures and recovery */
    sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter));
    adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,
                       sizeof(struct zfcp_scsi_dbf_record));
    if (!adapter->scsi_dbf)
        goto failed;
    debug_register_view(adapter->scsi_dbf, &debug_hex_ascii_view);
    debug_register_view(adapter->scsi_dbf, &zfcp_scsi_dbf_view);
    debug_set_level(adapter->scsi_dbf, 3);

    return 0;

 failed:
    zfcp_adapter_debug_unregister(adapter);

    return -ENOMEM;
}
Esempio n. 2
0
int
zfcp_qdio_allocate(struct zfcp_adapter *adapter)
{
	struct qdio_initialize *init_data;

	init_data = &adapter->qdio_init_data;

	init_data->cdev = adapter->ccw_device;
	init_data->q_format = QDIO_SCSI_QFMT;
	memcpy(init_data->adapter_name, zfcp_get_busid_by_adapter(adapter), 8);
	ASCEBC(init_data->adapter_name, 8);
	init_data->qib_param_field_format = 0;
	init_data->qib_param_field = NULL;
	init_data->input_slib_elements = NULL;
	init_data->output_slib_elements = NULL;
	init_data->min_input_threshold = ZFCP_MIN_INPUT_THRESHOLD;
	init_data->max_input_threshold = ZFCP_MAX_INPUT_THRESHOLD;
	init_data->min_output_threshold = ZFCP_MIN_OUTPUT_THRESHOLD;
	init_data->max_output_threshold = ZFCP_MAX_OUTPUT_THRESHOLD;
	init_data->no_input_qs = 1;
	init_data->no_output_qs = 1;
	init_data->input_handler = zfcp_qdio_response_handler;
	init_data->output_handler = zfcp_qdio_request_handler;
	init_data->int_parm = (unsigned long) adapter;
	init_data->flags = QDIO_INBOUND_0COPY_SBALS |
	    QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS;
	init_data->input_sbal_addr_array =
	    (void **) (adapter->response_queue.buffer);
	init_data->output_sbal_addr_array =
	    (void **) (adapter->request_queue.buffer);

	return qdio_allocate(init_data);
}
Esempio n. 3
0
/**
 * zfcp_qdio_reqid_check - checks for valid reqids.
 */
static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
				  unsigned long req_id)
{
	struct zfcp_fsf_req *fsf_req;
	unsigned long flags;

	debug_long_event(adapter->erp_dbf, 4, req_id);

	spin_lock_irqsave(&adapter->req_list_lock, flags);
	fsf_req = zfcp_reqlist_find(adapter, req_id);

	if (!fsf_req)
		/*
		 * Unknown request means that we have potentially memory
		 * corruption and must stop the machine immediatly.
		 */
		panic("error: unknown request id (%ld) on adapter %s.\n",
		      req_id, zfcp_get_busid_by_adapter(adapter));

	zfcp_reqlist_remove(adapter, fsf_req);
	atomic_dec(&adapter->reqs_active);
	spin_unlock_irqrestore(&adapter->req_list_lock, flags);

	/* finish the FSF request */
	zfcp_fsf_req_complete(fsf_req);
}
Esempio n. 4
0
/**
 * zfcp_qdio_allocate - allocate queue memory and initialize QDIO data
 * @adapter: pointer to struct zfcp_adapter
 * Returns: -ENOMEM on memory allocation error or return value from
 *          qdio_allocate
 */
int zfcp_qdio_allocate(struct zfcp_adapter *adapter)
{
	struct qdio_initialize *init_data;

	if (zfcp_qdio_buffers_enqueue(adapter->req_q.sbal) ||
		   zfcp_qdio_buffers_enqueue(adapter->resp_q.sbal))
		return -ENOMEM;

	init_data = &adapter->qdio_init_data;

	init_data->cdev = adapter->ccw_device;
	init_data->q_format = QDIO_ZFCP_QFMT;
	memcpy(init_data->adapter_name, zfcp_get_busid_by_adapter(adapter), 8);
	ASCEBC(init_data->adapter_name, 8);
	init_data->qib_param_field_format = 0;
	init_data->qib_param_field = NULL;
	init_data->input_slib_elements = NULL;
	init_data->output_slib_elements = NULL;
	init_data->no_input_qs = 1;
	init_data->no_output_qs = 1;
	init_data->input_handler = zfcp_qdio_int_resp;
	init_data->output_handler = zfcp_qdio_int_req;
	init_data->int_parm = (unsigned long) adapter;
	init_data->flags = QDIO_INBOUND_0COPY_SBALS |
			QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS;
	init_data->input_sbal_addr_array =
			(void **) (adapter->resp_q.sbal);
	init_data->output_sbal_addr_array =
			(void **) (adapter->req_q.sbal);

	return qdio_allocate(init_data);
}
Esempio n. 5
0
/*
 * function:    zfcp_qdio_request_handler
 *
 * purpose:	is called by QDIO layer for completed SBALs in request queue
 *
 * returns:	(void)
 */
static void
zfcp_qdio_request_handler(struct ccw_device *ccw_device,
			  unsigned int status,
			  unsigned int qdio_error,
			  unsigned int siga_error,
			  unsigned int queue_number,
			  int first_element,
			  int elements_processed,
			  unsigned long int_parm)
{
	struct zfcp_adapter *adapter;
	struct zfcp_qdio_queue *queue;

	adapter = (struct zfcp_adapter *) int_parm;
	queue = &adapter->request_queue;

	ZFCP_LOG_DEBUG("adapter %s, first=%d, elements_processed=%d\n",
		       zfcp_get_busid_by_adapter(adapter),
		       first_element, elements_processed);

	if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,
						   siga_error, first_element,
						   elements_processed)))
		goto out;
	/*
	 * we stored address of struct zfcp_adapter  data structure
	 * associated with irq in int_parm
	 */

	/* cleanup all SBALs being program-owned now */
	zfcp_qdio_zero_sbals(queue->buffer, first_element, elements_processed);

	/* increase free space in outbound queue */
	atomic_add(elements_processed, &queue->free_count);
	ZFCP_LOG_DEBUG("free_count=%d\n", atomic_read(&queue->free_count));
	wake_up(&adapter->request_wq);
	ZFCP_LOG_DEBUG("elements_processed=%d, free count=%d\n",
		       elements_processed, atomic_read(&queue->free_count));
 out:
	return;
}
Esempio n. 6
0
static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
				  unsigned long req_id, int sbal_idx)
{
	struct zfcp_fsf_req *fsf_req;
	unsigned long flags;

	spin_lock_irqsave(&adapter->req_list_lock, flags);
	fsf_req = zfcp_reqlist_find(adapter, req_id);

	if (!fsf_req)
		/*
		 * Unknown request means that we have potentially memory
		 * corruption and must stop the machine immediatly.
		 */
		panic("error: unknown request id (%lx) on adapter %s.\n",
		      req_id, zfcp_get_busid_by_adapter(adapter));

	zfcp_reqlist_remove(adapter, fsf_req);
	spin_unlock_irqrestore(&adapter->req_list_lock, flags);

	fsf_req->sbal_response = sbal_idx;
	fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
	zfcp_fsf_req_complete(fsf_req);
}
Esempio n. 7
0
/*
 * function:   	zfcp_qdio_response_handler
 *
 * purpose:	is called by QDIO layer for completed SBALs in response queue
 *
 * returns:	(void)
 */
static void
zfcp_qdio_response_handler(struct ccw_device *ccw_device,
			   unsigned int status,
			   unsigned int qdio_error,
			   unsigned int siga_error,
			   unsigned int queue_number,
			   int first_element,
			   int elements_processed,
			   unsigned long int_parm)
{
	struct zfcp_adapter *adapter;
	struct zfcp_qdio_queue *queue;
	int buffer_index;
	int i;
	struct qdio_buffer *buffer;
	int retval = 0;
	u8 count;
	u8 start;
	volatile struct qdio_buffer_element *buffere = NULL;
	int buffere_index;

	adapter = (struct zfcp_adapter *) int_parm;
	queue = &adapter->response_queue;

	if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,
					           siga_error)))
		goto out;

	/*
	 * we stored address of struct zfcp_adapter  data structure
	 * associated with irq in int_parm
	 */

	buffere = &(queue->buffer[first_element]->element[0]);
	ZFCP_LOG_DEBUG("first BUFFERE flags=0x%x\n", buffere->flags);
	/*
	 * go through all SBALs from input queue currently
	 * returned by QDIO layer
	 */

	for (i = 0; i < elements_processed; i++) {

		buffer_index = first_element + i;
		buffer_index %= QDIO_MAX_BUFFERS_PER_Q;
		buffer = queue->buffer[buffer_index];

		/* go through all SBALEs of SBAL */
		for (buffere_index = 0;
		     buffere_index < QDIO_MAX_ELEMENTS_PER_BUFFER;
		     buffere_index++) {

			/* look for QDIO request identifiers in SB */
			buffere = &buffer->element[buffere_index];
			retval = zfcp_qdio_reqid_check(adapter,
						       (void *) buffere->addr);

			if (retval) {
				ZFCP_LOG_NORMAL("bug: unexpected inbound "
						"packet on adapter %s "
						"(reqid=0x%lx, "
						"first_element=%d, "
						"elements_processed=%d)\n",
						zfcp_get_busid_by_adapter(adapter),
						(unsigned long) buffere->addr,
						first_element,
						elements_processed);
				ZFCP_LOG_NORMAL("hex dump of inbound buffer "
						"at address %p "
						"(buffer_index=%d, "
						"buffere_index=%d)\n", buffer,
						buffer_index, buffere_index);
				ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
					      (char *) buffer, SBAL_SIZE);
			}
			/*
			 * A single used SBALE per inbound SBALE has been
			 * implemented by QDIO so far. Hope they will
			 * do some optimisation. Will need to change to
			 * unlikely() then.
			 */
			if (likely(buffere->flags & SBAL_FLAGS_LAST_ENTRY))
				break;
		};

		if (unlikely(!(buffere->flags & SBAL_FLAGS_LAST_ENTRY))) {
			ZFCP_LOG_NORMAL("bug: End of inbound data "
					"not marked!\n");
		}
	}

	/*
	 * put range of SBALs back to response queue
	 * (including SBALs which have already been free before)
	 */
	count = atomic_read(&queue->free_count) + elements_processed;
	start = queue->free_index;

	ZFCP_LOG_TRACE("calling do_QDIO on adapter %s (flags=0x%x, "
		       "queue_no=%i, index_in_queue=%i, count=%i, "
		       "buffers=0x%lx\n",
		       zfcp_get_busid_by_adapter(adapter),
		       QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT,
		       0, start, count, (unsigned long) &queue->buffer[start]);

	retval = do_QDIO(ccw_device,
			 QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT,
			 0, start, count, NULL);

	if (unlikely(retval)) {
		atomic_set(&queue->free_count, count);
		ZFCP_LOG_DEBUG("clearing of inbound data regions failed, "
			       "queues may be down "
			       "(count=%d, start=%d, retval=%d)\n",
			       count, start, retval);
	} else {
		queue->free_index += count;
		queue->free_index %= QDIO_MAX_BUFFERS_PER_Q;
		atomic_set(&queue->free_count, 0);
		ZFCP_LOG_TRACE("%i buffers enqueued to response "
			       "queue at position %i\n", count, start);
	}
 out:
	return;
}