/**
* Copyright (C) 2005 - 2011 Emulex
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation. The full GNU General
* Public License is included in this distribution in the file called COPYING.
*
* Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
*
* Contact Information:
* linux-drivers@emulex.com
*
* Emulex
* 3333 Susan Street
* Costa Mesa, CA 92626
*/
#include <scsi/libiscsi.h>
#include <scsi/scsi_transport_iscsi.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_netlink.h>
#include <net/netlink.h>
#include <scsi/scsi.h>
#include "be_iscsi.h"
extern struct iscsi_transport beiscsi_iscsi_transport;
/**
* beiscsi_session_create - creates a new iscsi session
* @cmds_max: max commands supported
* @qdepth: max queue depth supported
* @initial_cmdsn: initial iscsi CMDSN
*/
struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
u16 cmds_max,
u16 qdepth,
u32 initial_cmdsn)
{
struct Scsi_Host *shost;
struct beiscsi_endpoint *beiscsi_ep;
struct iscsi_cls_session *cls_session;
struct beiscsi_hba *phba;
struct iscsi_session *sess;
struct beiscsi_session *beiscsi_sess;
struct beiscsi_io_task *io_task;
SE_DEBUG(DBG_LVL_8, "In beiscsi_session_create\n");
if (!ep) {
SE_DEBUG(DBG_LVL_1, "beiscsi_session_create: invalid ep\n");
return NULL;
}
beiscsi_ep = ep->dd_data;
phba = beiscsi_ep->phba;
shost = phba->shost;
if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
shost_printk(KERN_ERR, shost, "Cannot handle %d cmds."
"Max cmds per session supported is %d. Using %d. "
"\n", cmds_max,
beiscsi_ep->phba->params.wrbs_per_cxn,
beiscsi_ep->phba->params.wrbs_per_cxn);
cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
}
cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
shost, cmds_max,
sizeof(*beiscsi_sess),
sizeof(*io_task),
initial_cmdsn, ISCSI_MAX_TARGET);
if (!cls_session)
return NULL;
sess = cls_session->dd_data;
beiscsi_sess = sess->dd_data;
beiscsi_sess->bhs_pool = pci_pool_create("beiscsi_bhs_pool",
phba->pcidev,
sizeof(struct be_cmd_bhs),
64, 0);
if (!beiscsi_sess->bhs_pool)
goto destroy_sess;
return cls_session;
destroy_sess:
iscsi_session_teardown(cls_session);
return NULL;
}
/**
* beiscsi_session_destroy - destroys iscsi session
* @cls_session: pointer to iscsi cls session
*
* Destroys iSCSI session instance and releases
* resources allocated for it.
*/
void beiscsi_session_destroy(struct iscsi_cls_session *cls_session)
{
struct iscsi_session *sess = cls_session->dd_data;
struct beiscsi_session *beiscsi_sess = sess->dd_data;
SE_DEBUG(DBG_LVL_8, "In beiscsi_session_destroy\n");
pci_pool_destroy(beiscsi_sess->bhs_pool);
iscsi_session_teardown(cls_session);
}
/**
* beiscsi_conn_create - create an instance of iscsi connection
* @cls_session: ptr to iscsi_cls_session
* @cid: iscsi cid
*/
struct iscsi_cls_conn *
beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid)
{
struct beiscsi_hba *