linux/drivers/scsi/be2iscsi/be_main.c

/*
 * This file is part of the Emulex Linux Device Driver for Enterprise iSCSI
 * Host Bus Adapters. Refer to the README file included with this package
 * for driver version and adapter compatibility.
 *
 * Copyright (c) 2018 Broadcom. All Rights Reserved.
 * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful. ALL EXPRESS
 * OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
 * OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
 * DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
 * See the GNU General Public License for more details, a copy of which
 * can be found in the file COPYING included with this package.
 *
 * Contact Information:
 * [email protected]
 *
 */

#include <linux/reboot.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/semaphore.h>
#include <linux/iscsi_boot_sysfs.h>
#include <linux/module.h>
#include <linux/bsg-lib.h>
#include <linux/irq_poll.h>

#include <scsi/libiscsi.h>
#include <scsi/scsi_bsg_iscsi.h>
#include <scsi/scsi_netlink.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.h>
#include "be_main.h"
#include "be_iscsi.h"
#include "be_mgmt.h"
#include "be_cmds.h"

static unsigned int be_iopoll_budget =;
static unsigned int be_max_phys_size =;
static unsigned int enable_msix =;

MODULE_DESCRIPTION();
MODULE_VERSION();
MODULE_AUTHOR();
MODULE_LICENSE();
module_param(be_iopoll_budget, int, 0);
module_param(enable_msix, int, 0);
module_param(be_max_phys_size, uint, S_IRUGO);
MODULE_PARM_DESC();

#define beiscsi_disp_param(_name)

#define beiscsi_change_param(_name, _minval, _maxval, _defaval)

#define beiscsi_store_param(_name)

#define beiscsi_init_param(_name, _minval, _maxval, _defval)

#define BEISCSI_RW_ATTR(_name, _minval, _maxval, _defval, _descp)

/*
 * When new log level added update MAX allowed value for log_enable
 */
BEISCSI_RW_ATTR();

static DEVICE_ATTR(beiscsi_drvr_ver, S_IRUGO, beiscsi_drvr_ver_disp, NULL);
static DEVICE_ATTR(beiscsi_adapter_family, S_IRUGO, beiscsi_adap_family_disp, NULL);
static DEVICE_ATTR(beiscsi_fw_ver, S_IRUGO, beiscsi_fw_ver_disp, NULL);
static DEVICE_ATTR(beiscsi_phys_port, S_IRUGO, beiscsi_phys_port_disp, NULL);
static DEVICE_ATTR(beiscsi_active_session_count, S_IRUGO,
		   beiscsi_active_session_disp, NULL);
static DEVICE_ATTR(beiscsi_free_session_count, S_IRUGO,
		   beiscsi_free_session_disp, NULL);

static struct attribute *beiscsi_attrs[] =;

ATTRIBUTE_GROUPS();

static char const *cqe_desc[] =;

static int beiscsi_eh_abort(struct scsi_cmnd *sc)
{}

static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
{}

/*------------------- PCI Driver operations and data ----------------- */
static const struct pci_device_id beiscsi_pci_id_table[] =;
MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);


static const struct scsi_host_template beiscsi_sht =;

static struct scsi_transport_template *beiscsi_scsi_transport;

static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
{}

static void beiscsi_unmap_pci_function(struct beiscsi_hba *phba)
{}

static int beiscsi_map_pci_bars(struct beiscsi_hba *phba,
				struct pci_dev *pcidev)
{}

static int beiscsi_enable_pci(struct pci_dev *pcidev)
{}

static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev)
{}

/**
 * beiscsi_get_params()- Set the config paramters
 * @phba: ptr  device priv structure
 **/
static void beiscsi_get_params(struct beiscsi_hba *phba)
{}

static void hwi_ring_eq_db(struct beiscsi_hba *phba,
			   unsigned int id, unsigned int clr_interrupt,
			   unsigned int num_processed,
			   unsigned char rearm, unsigned char event)
{}

/**
 * be_isr_mcc - The isr routine of the driver.
 * @irq: Not used
 * @dev_id: Pointer to host adapter structure
 */
static irqreturn_t be_isr_mcc(int irq, void *dev_id)
{}

/**
 * be_isr_msix - The isr routine of the driver.
 * @irq: Not used
 * @dev_id: Pointer to host adapter structure
 */
static irqreturn_t be_isr_msix(int irq, void *dev_id)
{}

/**
 * be_isr - The isr routine of the driver.
 * @irq: Not used
 * @dev_id: Pointer to host adapter structure
 */
static irqreturn_t be_isr(int irq, void *dev_id)
{}

static void beiscsi_free_irqs(struct beiscsi_hba *phba)
{}

static int beiscsi_init_irqs(struct beiscsi_hba *phba)
{}

void hwi_ring_cq_db(struct beiscsi_hba *phba,
			   unsigned int id, unsigned int num_processed,
			   unsigned char rearm)
{}

static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba)
{}

static void
free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
{}

static inline struct wrb_handle *
beiscsi_get_wrb_handle(struct hwi_wrb_context *pwrb_context,
		       unsigned int wrbs_per_cxn)
{}

/**
 * alloc_wrb_handle - To allocate a wrb handle
 * @phba: The hba pointer
 * @cid: The cid to use for allocation
 * @pcontext: ptr to ptr to wrb context
 *
 * This happens under session_lock until submission to chip
 */
struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
				    struct hwi_wrb_context **pcontext)
{}

static inline void
beiscsi_put_wrb_handle(struct hwi_wrb_context *pwrb_context,
		       struct wrb_handle *pwrb_handle,
		       unsigned int wrbs_per_cxn)
{}

/**
 * free_wrb_handle - To free the wrb handle back to pool
 * @phba: The hba pointer
 * @pwrb_context: The context to free from
 * @pwrb_handle: The wrb_handle to free
 *
 * This happens under session_lock until submission to chip
 */
static void
free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
		struct wrb_handle *pwrb_handle)
{}

static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba)
{}

void
free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
{}

static void
be_complete_io(struct beiscsi_conn *beiscsi_conn,
		struct iscsi_task *task,
		struct common_sol_cqe *csol_cqe)
{}

static void
be_complete_logout(struct beiscsi_conn *beiscsi_conn,
		    struct iscsi_task *task,
		    struct common_sol_cqe *csol_cqe)
{}

static void
be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
		 struct iscsi_task *task,
		 struct common_sol_cqe *csol_cqe)
{}

static void
hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
		       struct beiscsi_hba *phba, struct sol_cqe *psol)
{}

static void
be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn,
			struct iscsi_task *task,
			struct common_sol_cqe *csol_cqe)
{}

static void adapter_get_sol_cqe(struct beiscsi_hba *phba,
		struct sol_cqe *psol,
		struct common_sol_cqe *csol_cqe)
{}


static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
			     struct beiscsi_hba *phba, struct sol_cqe *psol)
{}

/*
 * ASYNC PDUs include
 * a. Unsolicited NOP-In (target initiated NOP-In)
 * b. ASYNC Messages
 * c. Reject PDU
 * d. Login response
 * These headers arrive unprocessed by the EP firmware.
 * iSCSI layer processes them.
 */
static unsigned int
beiscsi_complete_pdu(struct beiscsi_conn *beiscsi_conn,
		struct pdu_base *phdr, void *pdata, unsigned int dlen)
{}

static inline void
beiscsi_hdl_put_handle(struct hd_async_context *pasync_ctx,
			 struct hd_async_handle *pasync_handle)
{}

static void
beiscsi_hdl_purge_handles(struct beiscsi_hba *phba,
			  struct hd_async_context *pasync_ctx,
			  u16 cri)
{}

static struct hd_async_handle *
beiscsi_hdl_get_handle(struct beiscsi_conn *beiscsi_conn,
		       struct hd_async_context *pasync_ctx,
		       struct i_t_dpdu_cqe *pdpdu_cqe,
		       u8 *header)
{}

static unsigned int
beiscsi_hdl_fwd_pdu(struct beiscsi_conn *beiscsi_conn,
		    struct hd_async_context *pasync_ctx,
		    u16 cri)
{}

static unsigned int
beiscsi_hdl_gather_pdu(struct beiscsi_conn *beiscsi_conn,
		       struct hd_async_context *pasync_ctx,
		       struct hd_async_handle *pasync_handle)
{}

static void
beiscsi_hdq_post_handles(struct beiscsi_hba *phba,
			 u8 header, u8 ulp_num, u16 nbuf)
{}

static void
beiscsi_hdq_process_compl(struct beiscsi_conn *beiscsi_conn,
			  struct i_t_dpdu_cqe *pdpdu_cqe)
{}

void beiscsi_process_mcc_cq(struct beiscsi_hba *phba)
{}

static void beiscsi_mcc_work(struct work_struct *work)
{}

/**
 * beiscsi_process_cq()- Process the Completion Queue
 * @pbe_eq: Event Q on which the Completion has come
 * @budget: Max number of events to processed
 *
 * return
 *     Number of Completion Entries processed.
 **/
unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq, int budget)
{}

static int be_iopoll(struct irq_poll *iop, int budget)
{}

static void
hwi_write_sgl_v2(struct iscsi_wrb *pwrb, struct scatterlist *sg,
		  unsigned int num_sg, struct beiscsi_io_task *io_task)
{}

static void
hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
	      unsigned int num_sg, struct beiscsi_io_task *io_task)
{}

/**
 * hwi_write_buffer()- Populate the WRB with task info
 * @pwrb: ptr to the WRB entry
 * @task: iscsi task which is to be executed
 **/
static int hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
{}

/**
 * beiscsi_find_mem_req()- Find mem needed
 * @phba: ptr to HBA struct
 **/
static void beiscsi_find_mem_req(struct beiscsi_hba *phba)
{}

static int beiscsi_alloc_mem(struct beiscsi_hba *phba)
{}

static int beiscsi_get_memory(struct beiscsi_hba *phba)
{}

static void iscsi_init_global_templates(struct beiscsi_hba *phba)
{}

static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
{}

static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
{}

static int
be_sgl_create_contiguous(void *virtual_address,
			 u64 physical_address, u32 length,
			 struct be_dma_mem *sgl)
{}

static void be_sgl_destroy_contiguous(struct be_dma_mem *sgl)
{}

static void
hwi_build_be_sgl_arr(struct beiscsi_hba *phba,
		     struct mem_array *pmem, struct be_dma_mem *sgl)
{}

static void
hwi_build_be_sgl_by_offset(struct beiscsi_hba *phba,
			   struct mem_array *pmem, struct be_dma_mem *sgl)
{}

static int be_fill_queue(struct be_queue_info *q,
		u16 len, u16 entry_size, void *vaddress)
{}

static int beiscsi_create_eqs(struct beiscsi_hba *phba,
			     struct hwi_context_memory *phwi_context)
{}

static int beiscsi_create_cqs(struct beiscsi_hba *phba,
			     struct hwi_context_memory *phwi_context)
{}

static int
beiscsi_create_def_hdr(struct beiscsi_hba *phba,
		       struct hwi_context_memory *phwi_context,
		       struct hwi_controller *phwi_ctrlr,
		       unsigned int def_pdu_ring_sz, uint8_t ulp_num)
{}

static int
beiscsi_create_def_data(struct beiscsi_hba *phba,
			struct hwi_context_memory *phwi_context,
			struct hwi_controller *phwi_ctrlr,
			unsigned int def_pdu_ring_sz, uint8_t ulp_num)
{}


static int
beiscsi_post_template_hdr(struct beiscsi_hba *phba)
{}

static int
beiscsi_post_pages(struct beiscsi_hba *phba)
{}

static void be_queue_free(struct beiscsi_hba *phba, struct be_queue_info *q)
{}

static int be_queue_alloc(struct beiscsi_hba *phba, struct be_queue_info *q,
		u16 len, u16 entry_size)
{}

static int
beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
			 struct hwi_context_memory *phwi_context,
			 struct hwi_controller *phwi_ctrlr)
{}

static void free_wrb_handles(struct beiscsi_hba *phba)
{}

static void be_mcc_queues_destroy(struct beiscsi_hba *phba)
{}

static int be_mcc_queues_create(struct beiscsi_hba *phba,
				struct hwi_context_memory *phwi_context)
{}

static void be2iscsi_enable_msix(struct beiscsi_hba *phba)
{}

static void hwi_purge_eq(struct beiscsi_hba *phba)
{}

static void hwi_cleanup_port(struct beiscsi_hba *phba)
{}

static int hwi_init_port(struct beiscsi_hba *phba)
{}

static int hwi_init_controller(struct beiscsi_hba *phba)
{}

static void beiscsi_free_mem(struct beiscsi_hba *phba)
{}

static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
{}

static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
{}

static void hwi_enable_intr(struct beiscsi_hba *phba)
{}

static void hwi_disable_intr(struct beiscsi_hba *phba)
{}

static int beiscsi_init_port(struct beiscsi_hba *phba)
{}

static void beiscsi_cleanup_port(struct beiscsi_hba *phba)
{}

/**
 * beiscsi_free_mgmt_task_handles()- Free driver CXN resources
 * @beiscsi_conn: ptr to the conn to be cleaned up
 * @task: ptr to iscsi_task resource to be freed.
 *
 * Free driver mgmt resources binded to CXN.
 **/
void
beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn,
				struct iscsi_task *task)
{}

/**
 * beiscsi_cleanup_task()- Free driver resources of the task
 * @task: ptr to the iscsi task
 *
 **/
static void beiscsi_cleanup_task(struct iscsi_task *task)
{}

void
beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
			   struct beiscsi_offload_params *params)
{}

static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt,
			      int *index, int *age)
{}

/**
 * beiscsi_alloc_pdu - allocates pdu and related resources
 * @task: libiscsi task
 * @opcode: opcode of pdu for task
 *
 * This is called with the session lock held. It will allocate
 * the wrb and sgl if needed for the command. And it will prep
 * the pdu's itt. beiscsi_parse_pdu will later translate
 * the pdu itt to the libiscsi task itt.
 */
static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
{}
static int beiscsi_iotask_v2(struct iscsi_task *task, struct scatterlist *sg,
		       unsigned int num_sg, unsigned int xferlen,
		       unsigned int writedir)
{}

static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
			  unsigned int num_sg, unsigned int xferlen,
			  unsigned int writedir)
{}

static int beiscsi_mtask(struct iscsi_task *task)
{}

static int beiscsi_task_xmit(struct iscsi_task *task)
{}

/**
 * beiscsi_bsg_request - handle bsg request from ISCSI transport
 * @job: job to handle
 */
static int beiscsi_bsg_request(struct bsg_job *job)
{}

static void beiscsi_hba_attrs_init(struct beiscsi_hba *phba)
{}

void beiscsi_start_boot_work(struct beiscsi_hba *phba, unsigned int s_handle)
{}

#define BEISCSI_SYSFS_ISCSI_BOOT_FLAGS
/*
 * beiscsi_show_boot_tgt_info()
 * Boot flag info for iscsi-utilities
 * Bit 0 Block valid flag
 * Bit 1 Firmware booting selected
 */
static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf)
{}

static ssize_t beiscsi_show_boot_ini_info(void *data, int type, char *buf)
{}

static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
{}

static umode_t beiscsi_tgt_get_attr_visibility(void *data, int type)
{}

static umode_t beiscsi_ini_get_attr_visibility(void *data, int type)
{}

static umode_t beiscsi_eth_get_attr_visibility(void *data, int type)
{}

static void beiscsi_boot_kobj_release(void *data)
{}

static int beiscsi_boot_create_kset(struct beiscsi_hba *phba)
{}

static void beiscsi_boot_work(struct work_struct *work)
{}

static void beiscsi_eqd_update_work(struct work_struct *work)
{}

static void beiscsi_hw_tpe_check(struct timer_list *t)
{}

static void beiscsi_hw_health_check(struct timer_list *t)
{}

/*
 * beiscsi_enable_port()- Enables the disabled port.
 * Only port resources freed in disable function are reallocated.
 * This is called in HBA error handling path.
 *
 * @phba: Instance of driver private structure
 *
 **/
static int beiscsi_enable_port(struct beiscsi_hba *phba)
{}

/*
 * beiscsi_disable_port()- Disable port and cleanup driver resources.
 * This is called in HBA error handling and driver removal.
 * @phba: Instance Priv structure
 * @unload: indicate driver is unloading
 *
 * Free the OS and HW resources held by the driver
 **/
static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload)
{}

static void beiscsi_sess_work(struct work_struct *work)
{}

static void beiscsi_recover_port(struct work_struct *work)
{}

static pci_ers_result_t beiscsi_eeh_err_detected(struct pci_dev *pdev,
		pci_channel_state_t state)
{}

static pci_ers_result_t beiscsi_eeh_reset(struct pci_dev *pdev)
{}

static void beiscsi_eeh_resume(struct pci_dev *pdev)
{}

static int beiscsi_dev_probe(struct pci_dev *pcidev,
			     const struct pci_device_id *id)
{}

static void beiscsi_remove(struct pci_dev *pcidev)
{}


static struct pci_error_handlers beiscsi_eeh_handlers =;

struct iscsi_transport beiscsi_iscsi_transport =;

static struct pci_driver beiscsi_pci_driver =;

static int __init beiscsi_module_init(void)
{}

static void __exit beiscsi_module_exit(void)
{}

module_init();
module_exit(beiscsi_module_exit);