예제 #1
0
/**
 * beiscsi_open_conn - Ask FW to open a TCP connection
 * @ep:	endpoint to be used
 * @src_addr: The source IP address
 * @dst_addr: The Destination  IP address
 *
 * Asks the FW to open a TCP connection
 */
static int beiscsi_open_conn(struct iscsi_endpoint *ep,
			     struct sockaddr *src_addr,
			     struct sockaddr *dst_addr, int non_blocking)
{
	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
	struct beiscsi_hba *phba = beiscsi_ep->phba;
	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
	struct be_mcc_wrb *wrb;
	struct tcp_connect_and_offload_out *ptcpcnct_out;
	unsigned short status, extd_status;
	unsigned int tag, wrb_num;
	int ret = -1;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n");
	beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
	if (beiscsi_ep->ep_cid == 0xFFFF) {
		SE_DEBUG(DBG_LVL_1, "No free cid available\n");
		return ret;
	}
	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ",
		 beiscsi_ep->ep_cid);
	phba->ep_array[beiscsi_ep->ep_cid -
		       phba->fw_config.iscsi_cid_start] = ep;
	if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
				  phba->params.cxns_per_ctrl * 2)) {
		SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
		return ret;
	}

	beiscsi_ep->cid_vld = 0;
	tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
	if (!tag) {
		SE_DEBUG(DBG_LVL_1,
			 "mgmt_open_connection Failed for cid=%d \n",
			 beiscsi_ep->ep_cid);
	} else {
		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
					 phba->ctrl.mcc_numtag[tag]);
	}
	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
	if (status || extd_status) {
		SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed"
				    " status = %d extd_status = %d \n",
				    status, extd_status);
		free_mcc_tag(&phba->ctrl, tag);
		return -1;
	} else {
		wrb = queue_get_wrb(mccq, wrb_num);
		free_mcc_tag(&phba->ctrl, tag);

		ptcpcnct_out = 	embedded_payload(wrb);
		beiscsi_ep = ep->dd_data;
		beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
		beiscsi_ep->cid_vld = 1;
		SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
	}
	return 0;
}
예제 #2
0
/**
 * beiscsi_get_host_param - get the iscsi parameter
 * @shost: pointer to scsi_host structure
 * @param: parameter type identifier
 * @buf: buffer pointer
 *
 * returns host parameter
 */
int beiscsi_get_host_param(struct Scsi_Host *shost,
			   enum iscsi_host_param param, char *buf)
{
	struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost);
	struct be_cmd_resp_get_mac_addr *resp;
	struct be_mcc_wrb *wrb;
	unsigned int tag, wrb_num;
	int len = 0;
	unsigned short status, extd_status;
	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param);
	switch (param) {
	case ISCSI_HOST_PARAM_HWADDRESS:
		tag = be_cmd_get_mac_addr(phba);
		if (!tag) {
			SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed \n");
			return -1;
		} else
			wait_event_interruptible(phba->ctrl.mcc_wait[tag],
						 phba->ctrl.mcc_numtag[tag]);

		wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
		extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
		status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
		if (status || extd_status) {
			SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
					    " status = %d extd_status = %d \n",
					    status, extd_status);
			free_mcc_tag(&phba->ctrl, tag);
			return -1;
		} else {
			wrb = queue_get_wrb(mccq, wrb_num);
			free_mcc_tag(&phba->ctrl, tag);
			resp = embedded_payload(wrb);
			memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
			len = frmt_macaddr(buf, PAGE_SIZE, (const unsigned char *)phba->mac_address, ETH_ALEN);
		}
		break;
	default:
		return iscsi2_host_get_param(shost, param, buf);
	}
	return len;
}
예제 #3
0
int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
{
	struct be_cmd_resp_get_mac_addr *resp;
	struct be_mcc_wrb *wrb;
	unsigned int tag, wrb_num;
	unsigned short status, extd_status;
	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
	int rc;

	if (phba->read_mac_address)
		return sysfs_format_mac(buf, phba->mac_address,
					ETH_ALEN);

	tag = be_cmd_get_mac_addr(phba);
	if (!tag) {
		SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
		return -EBUSY;
	} else
		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
					 phba->ctrl.mcc_numtag[tag]);

	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
	if (status || extd_status) {
		SE_DEBUG(DBG_LVL_1, "Failed to get be_cmd_get_mac_addr"
				    " status = %d extd_status = %d\n",
				    status, extd_status);
		free_mcc_tag(&phba->ctrl, tag);
		return -EAGAIN;
	}
	wrb = queue_get_wrb(mccq, wrb_num);
	free_mcc_tag(&phba->ctrl, tag);
	resp = embedded_payload(wrb);
	memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
	rc = sysfs_format_mac(buf, phba->mac_address,
			       ETH_ALEN);
	phba->read_mac_address = 1;
	return rc;
}
예제 #4
0
/**
 * beiscsi_open_conn - Ask FW to open a TCP connection
 * @ep:	endpoint to be used
 * @src_addr: The source IP address
 * @dst_addr: The Destination  IP address
 *
 * Asks the FW to open a TCP connection
 */
static int beiscsi_open_conn(struct iscsi_endpoint *ep,
			     struct sockaddr *src_addr,
			     struct sockaddr *dst_addr, int non_blocking)
{
	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
	struct beiscsi_hba *phba = beiscsi_ep->phba;
	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
	struct be_mcc_wrb *wrb;
	struct tcp_connect_and_offload_out *ptcpcnct_out;
	unsigned short status, extd_status;
	struct be_dma_mem nonemb_cmd;
	unsigned int tag, wrb_num;
	int ret = -ENOMEM;

	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n");
	beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
	if (beiscsi_ep->ep_cid == 0xFFFF) {
		SE_DEBUG(DBG_LVL_1, "No free cid available\n");
		return ret;
	}
	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d\n",
		 beiscsi_ep->ep_cid);
	phba->ep_array[beiscsi_ep->ep_cid -
		       phba->fw_config.iscsi_cid_start] = ep;
	if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
				  phba->params.cxns_per_ctrl * 2)) {
		SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
		goto free_ep;
	}

	beiscsi_ep->cid_vld = 0;
	nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
				sizeof(struct tcp_connect_and_offload_in),
				&nonemb_cmd.dma);
	if (nonemb_cmd.va == NULL) {
		SE_DEBUG(DBG_LVL_1,
			 "Failed to allocate memory for mgmt_open_connection"
			 "\n");
		beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
		return -ENOMEM;
	}
	nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in);
	memset(nonemb_cmd.va, 0, nonemb_cmd.size);
	tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
	if (!tag) {
		SE_DEBUG(DBG_LVL_1,
			 "mgmt_open_connection Failed for cid=%d\n",
			 beiscsi_ep->ep_cid);
		beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
		pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
				    nonemb_cmd.va, nonemb_cmd.dma);
		return -EAGAIN;
	} else {
		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
					 phba->ctrl.mcc_numtag[tag]);
	}
	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
	if (status || extd_status) {
		SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed"
				    " status = %d extd_status = %d\n",
				    status, extd_status);
		free_mcc_tag(&phba->ctrl, tag);
		pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
			    nonemb_cmd.va, nonemb_cmd.dma);
		goto free_ep;
	} else {
		wrb = queue_get_wrb(mccq, wrb_num);
		free_mcc_tag(&phba->ctrl, tag);

		ptcpcnct_out = embedded_payload(wrb);
		beiscsi_ep = ep->dd_data;
		beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
		beiscsi_ep->cid_vld = 1;
		SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
	}
	pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
			    nonemb_cmd.va, nonemb_cmd.dma);
	return 0;

free_ep:
	beiscsi_free_ep(beiscsi_ep);
	return -EBUSY;
}