Exemplo n.º 1
0
static void qla4xxx_build_scsi_iocbs(struct srb *srb,
				     struct command_t3_entry *cmd_entry,
				     uint16_t tot_dsds)
{
	struct scsi_qla_host *ha;
	uint16_t avail_dsds;
	struct data_seg_a64 *cur_dsd;
	struct scsi_cmnd *cmd;

	cmd = srb->cmd;
	ha = srb->ha;

	if (cmd->request_bufflen == 0 || cmd->sc_data_direction == DMA_NONE) {
		/* No data being transferred */
		cmd_entry->ttlByteCnt = __constant_cpu_to_le32(0);
		return;
	}

	avail_dsds = COMMAND_SEG;
	cur_dsd = (struct data_seg_a64 *) & (cmd_entry->dataseg[0]);

	/* Load data segments */
	if (cmd->use_sg) {
		struct scatterlist *cur_seg;
		struct scatterlist *end_seg;

		cur_seg = (struct scatterlist *)cmd->request_buffer;
		end_seg = cur_seg + tot_dsds;
		while (cur_seg < end_seg) {
			dma_addr_t sle_dma;

			/* Allocate additional continuation packets? */
			if (avail_dsds == 0) {
				struct continuation_t1_entry *cont_entry;

				cont_entry = qla4xxx_alloc_cont_entry(ha);
				cur_dsd =
					(struct data_seg_a64 *)
					&cont_entry->dataseg[0];
				avail_dsds = CONTINUE_SEG;
			}

			sle_dma = sg_dma_address(cur_seg);
			cur_dsd->base.addrLow = cpu_to_le32(LSDW(sle_dma));
			cur_dsd->base.addrHigh = cpu_to_le32(MSDW(sle_dma));
			cur_dsd->count = cpu_to_le32(sg_dma_len(cur_seg));
			avail_dsds--;

			cur_dsd++;
			cur_seg++;
		}
	} else {
		cur_dsd->base.addrLow = cpu_to_le32(LSDW(srb->dma_handle));
		cur_dsd->base.addrHigh = cpu_to_le32(MSDW(srb->dma_handle));
		cur_dsd->count = cpu_to_le32(cmd->request_bufflen);
	}
}
Exemplo n.º 2
0
uint8_t
qla4xxx_set_ifcb(scsi_qla_host_t *ha, uint32_t *mbox_cmd, uint32_t *mbox_sts,
		 dma_addr_t init_fw_cb_dma)
{
	memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
	memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
	mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
	mbox_cmd[1] = 0;
	mbox_cmd[2] = LSDW(init_fw_cb_dma);
	mbox_cmd[3] = MSDW(init_fw_cb_dma);
	if (ha->ifcb_size > LEGACY_IFCB_SIZE){
		mbox_cmd[4] = ha->ifcb_size;
		mbox_cmd[5] = (IFCB_VER_MAX << 8) | IFCB_VER_MIN;
	}
	if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts)
	    != QLA_SUCCESS) {
		QL4PRINT(QLP2, printk("scsi%d: %s: "
		    "MBOX_CMD_INITIALIZE_FIRMWARE failed w/ status %04X\n",
		    ha->host_no, __func__, mbox_sts[0]));
		{
			int i;
			for (i=0; i<MBOX_REG_COUNT; i++) {
                                QL4PRINT(QLP2, printk("mbox_cmd[%d] = %08x,     "
                                       "mbox_sts[%d] = %08x\n",
                                       i, mbox_cmd[i], i, mbox_sts[i]));
			}
		}
		return (QLA_ERROR);
	}
	return (QLA_SUCCESS);
}
Exemplo n.º 3
0
/**
 * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP
 * @ha: Pointer to host adapter structure.
 **/
int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
{
	struct init_fw_ctrl_blk *init_fw_cb;
	dma_addr_t init_fw_cb_dma;
	uint32_t mbox_cmd[MBOX_REG_COUNT];
	uint32_t mbox_sts[MBOX_REG_COUNT];

	init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
					sizeof(struct init_fw_ctrl_blk),
					&init_fw_cb_dma, GFP_KERNEL);
	if (init_fw_cb == NULL) {
		printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no,
		       __func__);
		return 10;
	}

	/* Get Initialize Firmware Control Block. */
	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
	memset(&mbox_sts, 0, sizeof(mbox_sts));

	memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk));
	mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
	mbox_cmd[2] = LSDW(init_fw_cb_dma);
	mbox_cmd[3] = MSDW(init_fw_cb_dma);
	mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk);

	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
	    QLA_SUCCESS) {
		DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
			      ha->host_no, __func__));
		dma_free_coherent(&ha->pdev->dev,
				  sizeof(struct init_fw_ctrl_blk),
				  init_fw_cb, init_fw_cb_dma);
		return QLA_ERROR;
	}

	/* Save IP Address. */
	memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr,
	       min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr)));
	memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet,
	       min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet)));
	memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr,
	       min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr)));

	dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk),
			  init_fw_cb, init_fw_cb_dma);

	return QLA_SUCCESS;
}
Exemplo n.º 4
0
static void qla4xxx_build_scsi_iocbs(struct srb *srb,
                                     struct command_t3_entry *cmd_entry,
                                     uint16_t tot_dsds)
{
    struct scsi_qla_host *ha;
    uint16_t avail_dsds;
    struct data_seg_a64 *cur_dsd;
    struct scsi_cmnd *cmd;
    struct scatterlist *sg;
    int i;

    cmd = srb->cmd;
    ha = srb->ha;

    if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
        /* No data being transferred */
        cmd_entry->ttlByteCnt = __constant_cpu_to_le32(0);
        return;
    }

    avail_dsds = COMMAND_SEG;
    cur_dsd = (struct data_seg_a64 *) & (cmd_entry->dataseg[0]);

    scsi_for_each_sg(cmd, sg, tot_dsds, i) {
        dma_addr_t sle_dma;

        /* Allocate additional continuation packets? */
        if (avail_dsds == 0) {
            struct continuation_t1_entry *cont_entry;

            cont_entry = qla4xxx_alloc_cont_entry(ha);
            cur_dsd =
                (struct data_seg_a64 *)
                &cont_entry->dataseg[0];
            avail_dsds = CONTINUE_SEG;
        }

        sle_dma = sg_dma_address(sg);
        cur_dsd->base.addrLow = cpu_to_le32(LSDW(sle_dma));
        cur_dsd->base.addrHigh = cpu_to_le32(MSDW(sle_dma));
        cur_dsd->count = cpu_to_le32(sg_dma_len(sg));
        avail_dsds--;

        cur_dsd++;
    }
Exemplo n.º 5
0
uint8_t
qla4xxx_get_ifcb(scsi_qla_host_t *ha, uint32_t *mbox_cmd, uint32_t *mbox_sts,
		 dma_addr_t init_fw_cb_dma)
{
	memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
	memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
	mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
	mbox_cmd[2] = LSDW(init_fw_cb_dma);
	mbox_cmd[3] = MSDW(init_fw_cb_dma);
	if (init_fw_cb_dma != 0 && ha->ifcb_size > LEGACY_IFCB_SIZE){
		mbox_cmd[4] = ha->ifcb_size;
	}

	if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts)
	    != QLA_SUCCESS) {

		if (init_fw_cb_dma == 0 &&
		    mbox_sts[0] == MBOX_STS_COMMAND_PARAMETER_ERROR)
		{
			/* Other valid info returned in mailbox status registers */
			return (QLA_SUCCESS);
		}

		QL4PRINT(QLP2, printk("scsi%d: %s: "
                        "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK failed w/ status %04X\n",
                        ha->host_no, __func__, mbox_sts[0]));
		{
			int i;
			for (i=0; i<MBOX_REG_COUNT; i++) {
                                QL4PRINT(QLP2, printk("mbox_cmd[%d] = %08x,     "
                                       "mbox_sts[%d] = %08x\n",
                                       i, mbox_cmd[i], i, mbox_sts[i]));
			}
		}
		return (QLA_ERROR);
	}
	return (QLA_SUCCESS);
}
Exemplo n.º 6
0
/*
 * qla4xxx_issue_iocb
 *	Issue IOCB using mailbox command
 *
 * Input:
 *	ha = adapter state pointer.
 *	buffer = buffer pointer.
 *	phys_addr = physical address of buffer.
 *	size = size of buffer.
 *	TARGET_QUEUE_LOCK must be released.
 *	ADAPTER_STATE_LOCK must be released.
 *
 * Returns:
 *	qla2x00 local function return status code.
 *
 * Context:
 *	Kernel context.
 */
uint8_t
qla4xxx_issue_iocb(scsi_qla_host_t *ha, uint32_t cmpl_sts_offset,
		   dma_addr_t phys_addr)
{
	uint32_t   mbox_cmd[MBOX_REG_COUNT];
	uint32_t   mbox_sts[MBOX_REG_COUNT];
	uint8_t	   status;

	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
	memset(&mbox_sts, 0, sizeof(mbox_sts));
	mbox_cmd[0] = MBOX_CMD_EXECUTE_IOCB_A64;
	mbox_cmd[1] = cmpl_sts_offset;
	mbox_cmd[2] = LSDW(phys_addr);
	mbox_cmd[3] = MSDW(phys_addr);
	status = qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]);

	if (status != QLA_SUCCESS) {
		/*EMPTY*/
		QL4PRINT(QLP2, printk("qla4xxx_issue_iocb(%d): failed statis 0x%x",
		    ha->host_no, status));
	}

	return status;
}
Exemplo n.º 7
0
/**
 * qla4xxx_initialize_fw_cb - initializes firmware control block.
 * @ha: Pointer to host adapter structure.
 **/
int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
{
	struct init_fw_ctrl_blk *init_fw_cb;
	dma_addr_t init_fw_cb_dma;
	uint32_t mbox_cmd[MBOX_REG_COUNT];
	uint32_t mbox_sts[MBOX_REG_COUNT];
	int status = QLA_ERROR;

	init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
					sizeof(struct init_fw_ctrl_blk),
					&init_fw_cb_dma, GFP_KERNEL);
	if (init_fw_cb == NULL) {
		DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n",
			      ha->host_no, __func__));
		return 10;
	}
	memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk));

	/* Get Initialize Firmware Control Block. */
	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
	memset(&mbox_sts, 0, sizeof(mbox_sts));

	mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
	mbox_cmd[2] = LSDW(init_fw_cb_dma);
	mbox_cmd[3] = MSDW(init_fw_cb_dma);
	mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk);

	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
	    QLA_SUCCESS) {
		dma_free_coherent(&ha->pdev->dev,
				  sizeof(struct init_fw_ctrl_blk),
				  init_fw_cb, init_fw_cb_dma);
		return status;
	}

	/* Initialize request and response queues. */
	qla4xxx_init_rings(ha);

	/* Fill in the request and response queue information. */
	init_fw_cb->pri.rqq_consumer_idx = cpu_to_le16(ha->request_out);
	init_fw_cb->pri.compq_producer_idx = cpu_to_le16(ha->response_in);
	init_fw_cb->pri.rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
	init_fw_cb->pri.compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
	init_fw_cb->pri.rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma));
	init_fw_cb->pri.rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma));
	init_fw_cb->pri.compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma));
	init_fw_cb->pri.compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma));
	init_fw_cb->pri.shdwreg_addr_lo =
		cpu_to_le32(LSDW(ha->shadow_regs_dma));
	init_fw_cb->pri.shdwreg_addr_hi =
		cpu_to_le32(MSDW(ha->shadow_regs_dma));

	/* Set up required options. */
	init_fw_cb->pri.fw_options |=
		__constant_cpu_to_le16(FWOPT_SESSION_MODE |
				       FWOPT_INITIATOR_MODE);
	init_fw_cb->pri.fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);

	/* Save some info in adapter structure. */
	ha->firmware_options = le16_to_cpu(init_fw_cb->pri.fw_options);
	ha->tcp_options = le16_to_cpu(init_fw_cb->pri.ipv4_tcp_opts);
	ha->heartbeat_interval = init_fw_cb->pri.hb_interval;
	memcpy(ha->ip_address, init_fw_cb->pri.ipv4_addr,
	       min(sizeof(ha->ip_address), sizeof(init_fw_cb->pri.ipv4_addr)));
	memcpy(ha->subnet_mask, init_fw_cb->pri.ipv4_subnet,
	       min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->pri.ipv4_subnet)));
	memcpy(ha->gateway, init_fw_cb->pri.ipv4_gw_addr,
	       min(sizeof(ha->gateway), sizeof(init_fw_cb->pri.ipv4_gw_addr)));
	memcpy(ha->name_string, init_fw_cb->pri.iscsi_name,
	       min(sizeof(ha->name_string),
		   sizeof(init_fw_cb->pri.iscsi_name)));
	/*memcpy(ha->alias, init_fw_cb->Alias,
	       min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/

	/* Save Command Line Paramater info */
	ha->port_down_retry_count = le16_to_cpu(init_fw_cb->pri.conn_ka_timeout);
	ha->discovery_wait = ql4xdiscoverywait;

	/* Send Initialize Firmware Control Block. */
	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
	memset(&mbox_sts, 0, sizeof(mbox_sts));

	mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
	mbox_cmd[1] = 0;
	mbox_cmd[2] = LSDW(init_fw_cb_dma);
	mbox_cmd[3] = MSDW(init_fw_cb_dma);
	mbox_cmd[4] = sizeof(struct init_fw_ctrl_blk);

	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) ==
	    QLA_SUCCESS)
		status = QLA_SUCCESS;
	 else {
		DEBUG2(printk("scsi%ld: %s: MBOX_CMD_INITIALIZE_FIRMWARE "
			      "failed w/ status %04X\n", ha->host_no, __func__,
			      mbox_sts[0]));
	}
	dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk),
			  init_fw_cb, init_fw_cb_dma);

	return status;
}