Re: [PATCH 09/12] be2iscsi: Add support for iscsi boot

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



_____  
From: Mike Christie [mailto:michaelc@xxxxxxxxxxx]
To: Jayamohan Kalickal [mailto:jayamohank@xxxxxxxxxxxxxxxxx]
Cc: linux-scsi@xxxxxxxxxxxxxxx, James.Bottomley@xxxxxxx, Konrad Rzeszutek [mailto:konrad@xxxxxxxxxx]
Sent: Sun, 04 Jul 2010 13:16:32 -0700
Subject: Re: [PATCH 09/12] be2iscsi: Add support for iscsi boot

ccing Konrad to give him some heads up that there is going to be another 
user of the boot lib.


On 06/29/2010 07:02 PM, Jayamohan Kallickal wrote:
> +static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf)
> +{
> +	struct beiscsi_hba *phba = data;
> +	char *str = buf;
> +	int rc;
> +
> +	printk(KERN_ERR " In beiscsi_show_boot_tgt_info type=%d\n", type);
> +	switch (type) {
> +	case ISCSI_BOOT_TGT_NAME:
> +		rc = sprintf(buf, "%.*s\n",
> +				(int)strlen(phba->boot_sess.target_name),

Did you get a compile warning if you did not cast this to a int?Yes, I did get a compile warning for this.

Will submit another set of patches with the changes required   


> +				(char *)&phba->boot_sess.target_name);
> +		break;
> +	case ISCSI_BOOT_TGT_IP_ADDR:
> +		if (phba->boot_sess.conn_list[0].dest_ipaddr.ip_type == 0x1)
> +			rc = sprintf(buf, "%pI4\n",
> +				(char *)&phba->boot_sess.conn_list[0].
> +				dest_ipaddr.ip_address);
> +		else
> +			rc = sprintf(str, "%pI6\n",
> +				(char *)&phba->boot_sess.conn_list[0].
> +				dest_ipaddr.ip_address);
> +		break;
> +	case ISCSI_BOOT_TGT_PORT:
> +		rc = sprintf(str, "%d\n", phba->boot_sess.conn_list[0].
> +				  dest_port);
> +		break;
> +
> +	case ISCSI_BOOT_TGT_CHAP_NAME:
> +		rc = sprintf(str,  "%.*s\n",
> +				      phba->boot_sess.conn_list[0].
> +				      negotiated_login_options.auth_data.chap.
> +				      target_chap_name_length,
> +				      (char *)&phba->boot_sess.conn_list[0].
> +				      negotiated_login_options.auth_data.chap.
> +				      target_chap_name);
> +		break;
> +	case ISCSI_BOOT_TGT_CHAP_SECRET:
> +		rc = sprintf(str,  "%.*s\n",
> +				      phba->boot_sess.conn_list[0].
> +				      negotiated_login_options.auth_data.chap.
> +				      target_secret_length,
> +				      (char *)&phba->boot_sess.conn_list[0].
> +				      negotiated_login_options.auth_data.chap.
> +				      target_secret);
> +
> +		break;
> +	case ISCSI_BOOT_TGT_REV_CHAP_NAME:
> +		rc = sprintf(str,  "%.*s\n",
> +				      phba->boot_sess.conn_list[0].
> +				      negotiated_login_options.auth_data.chap.
> +				      intr_chap_name_length,
> +				      (char *)&phba->boot_sess.conn_list[0].
> +				      negotiated_login_options.auth_data.chap.
> +				      intr_chap_name);
> +
> +		break;
> +	case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
> +			rc = sprintf(str,  "%.*s\n",
> +				      phba->boot_sess.conn_list[0].
> +				      negotiated_login_options.auth_data.chap.
> +				      intr_secret_length,
> +				      (char *)&phba->boot_sess.conn_list[0].
> +				      negotiated_login_options.auth_data.chap.
> +				      intr_secret);
> +		break;
> +	case ISCSI_BOOT_TGT_FLAGS:
> +			rc = sprintf(str, "2\n");
> +		break;
> +	case ISCSI_BOOT_TGT_NIC_ASSOC:
> +			rc = sprintf(str, "0\n");
> +		break;
> +	default:
> +		rc = -ENOSYS;
> +		break;
> +	}
> +	return rc;
> +}
> +
> +static ssize_t beiscsi_show_boot_ini_info(void *data, int type, char *buf)
> +{
> +	struct beiscsi_hba *phba = data;
> +	char *str = buf;
> +	int rc;
> +
> +	printk(KERN_ERR " In beiscsi_show_boot_ini_info type=%d\n", type);
> +	switch (type) {
> +	case ISCSI_BOOT_INI_INITIATOR_NAME:
> +		rc = sprintf(str, "%s\n", phba->boot_sess.initiator_iscsiname);
> +		break;
> +	default:
> +		rc = -ENOSYS;
> +		break;
> +	}
> +	return rc;
> +}
> +
> +static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
> +{
> +	struct beiscsi_hba *phba = data;
> +	char *str = buf;
> +	int rc;
> +
> +	printk(KERN_ERR " In beiscsi_show_boot_eth_info type = %d\n", type);
> +	switch (type) {
> +	case ISCSI_BOOT_ETH_FLAGS:
> +			rc = sprintf(str, "2\n");
> +		break;
> +	case ISCSI_BOOT_ETH_INDEX:
> +			rc = sprintf(str, "0\n");
> +		break;
> +	case ISCSI_BOOT_ETH_MAC:
> +	{
> +	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;


That chunk above should have some tabs I think.

> +
> +		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, "Failed to get be_cmd_get_mac_addr"
> +					    " 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);
> +			rc = sysfs_format_mac(buf, phba->mac_address,
> +					       ETH_ALEN);
> +		}

Can't you get this info in the host setup functions and then use the 
cached version? Or if it changes can you update the cached info?

This also looks like the same code in beiscsi_get_host_param so it 
should at least be a function.



> +	}
> +
> +	break;
> +	default:
> +		rc = -ENOSYS;
> +		break;
> +	}
> +	return rc;
> +}
> +
> +
> +static mode_t beiscsi_tgt_get_attr_visibility(void *data, int type)
> +{
> +	int rc;
> +
> +	switch (type) {
> +	case ISCSI_BOOT_TGT_NAME:
> +	case ISCSI_BOOT_TGT_IP_ADDR:
> +	case ISCSI_BOOT_TGT_PORT:
> +	case ISCSI_BOOT_TGT_CHAP_NAME:
> +	case ISCSI_BOOT_TGT_CHAP_SECRET:
> +	case ISCSI_BOOT_TGT_REV_CHAP_NAME:
> +	case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
> +	case ISCSI_BOOT_TGT_NIC_ASSOC:
> +	case ISCSI_BOOT_TGT_FLAGS:
> +		rc = S_IRUGO;
> +		break;
> +	default:
> +		rc = 0;
> +		break;
> +	}
> +	return rc;
> +}
> +
> +static mode_t beiscsi_ini_get_attr_visibility(void *data, int type)
> +{
> +	int rc;
> +
> +	switch (type) {
> +	case ISCSI_BOOT_INI_INITIATOR_NAME:
> +		rc = S_IRUGO;
> +		break;
> +	default:
> +		rc = 0;
> +		break;
> +	}
> +	return rc;
> +}
> +
> +
> +static mode_t beiscsi_eth_get_attr_visibility(void *data, int type)
> +{
> +	int rc;
> +
> +	switch (type) {
> +	case ISCSI_BOOT_ETH_FLAGS:
> +	case ISCSI_BOOT_ETH_MAC:
> +	case ISCSI_BOOT_ETH_INDEX:
> +		rc = S_IRUGO;
> +		break;
> +	default:
> +		rc = 0;
> +		break;
> +	}
> +	return rc;
> +}
> +
> +static int beiscsi_setup_boot_info(struct beiscsi_hba *phba)
> +{
> +	struct iscsi_boot_kobj *boot_kobj;
> +	char *set_name;
> +
> +	set_name = kasprintf(GFP_KERNEL, "iscsi_boot%u", phba->shost->host_no);
> +	if (!set_name)
> +		return -ENOMEM;
> +
> +	phba->boot_kset = iscsi_boot_create_kset(set_name);
> +	if (!phba->boot_kset) {
> +		kfree(set_name);
> +		return -ENOMEM;
> +	}
> +
> +	/* get boot info using mgmt cmd */
> +	boot_kobj = iscsi_boot_create_target(phba->boot_kset, 0, phba,
> +					     beiscsi_show_boot_tgt_info,
> +					     beiscsi_tgt_get_attr_visibility);
> +	if (!boot_kobj)
> +		goto free_kset;
> +
> +	boot_kobj = iscsi_boot_create_initiator(phba->boot_kset, 0, phba,
> +					     beiscsi_show_boot_ini_info,
> +					     beiscsi_ini_get_attr_visibility);
> +	if (!boot_kobj)
> +		goto free_kset;
> +
> +	boot_kobj = iscsi_boot_create_ethernet(phba->boot_kset, 0, phba,
> +					     beiscsi_show_boot_eth_info,
> +					     beiscsi_eth_get_attr_visibility);
> +	if (!boot_kobj)
> +		goto free_kset;
> +	return 0;
> +
> +free_kset:
> +	kfree(set_name);
> +	iscsi_boot_destroy_kset(phba->boot_kset);
> +	return -ENOMEM;
> +}
> +
>   /*------------------- PCI Driver operations and data ----------------- */
>   static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
>   	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
> @@ -270,6 +523,15 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
>
>   	if (iscsi_host_add(shost,&phba->pcidev->dev))
>   		goto free_devices;
> +
> +	if (beiscsi_setup_boot_info(phba))
> +		/*
> +		 * log error but continue, because we may not be using
> +		 * iscsi boot.
> +		 */
> +		shost_printk(KERN_ERR, phba->shost, "Could not set up "
> +		"iSCSI boot info.");
> +
>   	return phba;
>
>   free_devices:
> @@ -3263,6 +3525,89 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
>   			     "In hwi_disable_intr, Already Disabled\n");
>   }
>
> +static char beiscsi_get_boot_info(struct beiscsi_hba *phba)
> +{
> +	struct be_cmd_resp_get_boot_target *boot_resp;
> +	struct be_cmd_resp_geta_session *session_resp;
> +	struct be_mcc_wrb *wrb;
> +	struct be_dma_mem nonemb_cmd;
> +	unsigned int tag, wrb_num;
> +	unsigned short status, extd_status;
> +	struct be_queue_info *mccq =&phba->ctrl.mcc_obj.q;
> +
> +	tag = beiscsi_get_boot_target(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;
> +	}
> +	wrb = queue_get_wrb(mccq, wrb_num);
> +	free_mcc_tag(&phba->ctrl, tag);
> +	boot_resp = embedded_payload(wrb);
> +
> +	if (boot_resp->boot_session_handle>= 0) {
> +

extra newline.

You also probably can change this up to be

if (boot_resp->boot_session_handle < 0) {
	printk(KERN_ERR "No Boot Session for this pci_func,"
		"session Hndl = %d\n", boot_resp->boot_session_handle);
	return 0;
}


nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
				sizeof(*session_resp),
				&nonemb_cmd.dma);

.......


tag = beiscsi_geta_session_info(phba,
		boot_resp->boot_session_handle,&nonemb_cmd);
if (!tag)
	goto free_nonemb;

....

if (something else fails)
	goto free_nonemb;

.....

free_nonemb:
	pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size
	return 0;

> +		nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
> +					sizeof(*session_resp),
> +					&nonemb_cmd.dma);
> +		if (nonemb_cmd.va == NULL) {
> +			SE_DEBUG(DBG_LVL_1,
> +				 "Failed to allocate memory for"
> +				 "beiscsi_geta_session_info\n");
> +			return -1;
> +		}
> +
> +		memset(nonemb_cmd.va, 0, sizeof(*session_resp));
> +		tag = beiscsi_geta_session_info(phba,
> +			boot_resp->boot_session_handle,&nonemb_cmd);
> +		if (!tag) {
> +			SE_DEBUG(DBG_LVL_1, "beiscsi_geta_session_info"
> +				" Failed\n");
> +			pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> +			    nonemb_cmd.va, nonemb_cmd.dma);
> +			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, "beiscsi_geta_session_info 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);
> +			return -1;
> +		}
> +		wrb = queue_get_wrb(mccq, wrb_num);
> +		free_mcc_tag(&phba->ctrl, tag);
> +		session_resp = nonemb_cmd.va ;
> +		memcpy(&phba->boot_sess,&session_resp->session_info,
> +		       sizeof(struct mgmt_session_info));
> +		pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
> +			    nonemb_cmd.va, nonemb_cmd.dma);
> +	} else {
> +		printk(KERN_ERR "No Boot Session for this pci_func,"
> +			"session Hndl = %d\n", boot_resp->boot_session_handle);
> +	}
> +		return 0;
> +}
> +
>   static int beiscsi_init_port(struct beiscsi_hba *phba)
>   {
>   	int ret;
> @@ -3825,6 +4170,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
>   	iscsi_host_remove(phba->shost);
>   	pci_dev_put(phba->pcidev);
>   	iscsi_host_free(phba->shost);
> +	iscsi_boot_destroy_kset(phba->boot_kset);
>   }
>
>   static void beiscsi_msix_enable(struct beiscsi_hba *phba)
> @@ -3985,6 +4331,13 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
>   			     "Failed to hwi_enable_intr\n");
>   		goto free_intr;
>   	}
> +	ret = beiscsi_get_boot_info(phba);


Fix return value. Should be returning -Exyx code like the code does/should.


> +	if (ret<  0) {
> +		shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
> +			     "Failed to hwi_enable_intr\n");
> +		goto free_intr;
> +	}
> +
>   	SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n");
>   	return 0;
>
> diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
> index 08996d0..978a57d 100644
> --- a/drivers/scsi/be2iscsi/be_main.h
> +++ b/drivers/scsi/be2iscsi/be_main.h
> @@ -311,6 +311,7 @@ struct beiscsi_hba {
>   	struct list_head hba_queue;
>   	unsigned short *cid_array;
>   	struct iscsi_endpoint **ep_array;
> +	struct iscsi_boot_kset *boot_kset;
>   	struct Scsi_Host *shost;
>   	struct {
>   		/**
> @@ -341,6 +342,7 @@ struct beiscsi_hba {
>   	struct work_struct work_cqs;	/* The work being queued */
>   	struct be_ctrl_info ctrl;
>   	unsigned int generation;
> +	struct mgmt_session_info boot_sess;
>   	struct invalidate_command_table inv_tbl[128];
>
>   };
> diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
> index c33aa3c..ee85898 100644
> --- a/drivers/scsi/be2iscsi/be_mgmt.c
> +++ b/drivers/scsi/be2iscsi/be_mgmt.c
> @@ -20,6 +20,77 @@
>
>   #include "be_mgmt.h"
>   #include "be_iscsi.h"
> +#include<scsi/scsi_transport_iscsi.h>
> +
> +unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba)
> +{
> +	struct be_ctrl_info *ctrl =&phba->ctrl;
> +	struct be_mcc_wrb *wrb;
> +	struct be_cmd_req_get_mac_addr *req;
> +	unsigned int tag = 0;
> +
> +	SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n");
> +	spin_lock(&ctrl->mbox_lock);
> +	tag = alloc_mcc_tag(phba);
> +	if (!tag) {
> +		spin_unlock(&ctrl->mbox_lock);
> +		return tag;
> +	}
> +
> +	wrb = wrb_from_mccq(phba);
> +	req = embedded_payload(wrb);
> +	wrb->tag0 |= tag;
> +	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
> +	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
> +			   OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
> +			   sizeof(*req));
> +
> +	be_mcc_notify(phba);
> +	spin_unlock(&ctrl->mbox_lock);
> +	return tag;
> +}
> +
> +unsigned int beiscsi_geta_session_info(struct beiscsi_hba *phba,

Probably just wanted to name this beiscsi_get_session_info



> +				  u32 boot_session_handle,
> +				  struct be_dma_mem *nonemb_cmd)
> +{
> +	struct be_ctrl_info *ctrl =&phba->ctrl;
> +	struct be_mcc_wrb *wrb;
> +	unsigned int tag = 0;
> +	struct  be_cmd_req_geta_session *req;
> +	struct be_cmd_resp_geta_session *resp;
> +	struct be_sge *sge;
> +
> +	SE_DEBUG(DBG_LVL_8, "In beiscsi_geta_session_info\n");
> +	spin_lock(&ctrl->mbox_lock);
> +	tag = alloc_mcc_tag(phba);
> +	if (!tag) {
> +		spin_unlock(&ctrl->mbox_lock);
> +		return tag;
> +	}
> +
> +	nonemb_cmd->size = sizeof(*resp);
> +	req = nonemb_cmd->va;
> +	memset(req, 0, sizeof(*req));
> +	wrb = wrb_from_mccq(phba);
> +	sge = nonembedded_sgl(wrb);
> +	wrb->tag0 |= tag;
> +
> +
> +	wrb->tag0 |= tag;
> +	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
> +	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
> +			   OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
> +			   sizeof(*resp));
> +	req->session_handle = boot_session_handle;
> +	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
> +	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma&  0xFFFFFFFF);
> +	sge->len = cpu_to_le32(nonemb_cmd->size);
> +
> +	be_mcc_notify(phba);
> +	spin_unlock(&ctrl->mbox_lock);
> +	return tag;
> +}
>
>   unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
>   				struct beiscsi_hba *phba)

___________________________________________________________________________________
This message, together with any attachment(s), contains confidential and proprietary information of
ServerEngines Corporation and is intended only for the designated recipient(s) named above. Any unauthorized
review, printing, retention, copying, disclosure or distribution is strictly prohibited.  If you are not the
intended recipient of this message, please immediately advise the sender by reply email message and
delete all copies of this message and any attachment(s). Thank you.

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux