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); } }
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); }
/** * 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; }
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++; }
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); }
/* * 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; }
/** * 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; }