#include "qla_def.h"
#include <linux/bitfield.h>
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/kobject.h>
#include <linux/slab.h>
#include <linux/blk-mq-pci.h>
#include <linux/refcount.h>
#include <linux/crash_dump.h>
#include <linux/trace_events.h>
#include <linux/trace.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>
#include "qla_target.h"
char qla2x00_version_str[40];
static int apidev_major;
struct kmem_cache *srb_cachep;
static struct trace_array *qla_trc_array;
int ql2xfulldump_on_mpifail;
module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xenforce_iocb_limit = …;
module_param(ql2xenforce_iocb_limit, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(…) …;
static struct kmem_cache *ctx_cachep;
uint ql_errlev = …;
int ql2xsecenable;
module_param(ql2xsecenable, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
static int ql2xenableclass2;
module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(…) …;
int ql2xlogintimeout = …;
module_param(ql2xlogintimeout, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int qlport_down_retry;
module_param(qlport_down_retry, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xplogiabsentdevice;
module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xloginretrycount;
module_param(ql2xloginretrycount, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xallocfwdump = …;
module_param(ql2xallocfwdump, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xextended_error_logging;
module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR);
module_param_named(logging, ql2xextended_error_logging, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xextended_error_logging_ktrace = …;
module_param(ql2xextended_error_logging_ktrace, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xshiftctondsd = …;
module_param(ql2xshiftctondsd, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xfdmienable = …;
module_param(ql2xfdmienable, int, S_IRUGO|S_IWUSR);
module_param_named(fdmi, ql2xfdmienable, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
#define MAX_Q_DEPTH …
static int ql2xmaxqdepth = …;
module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xenabledif = …;
module_param(ql2xenabledif, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
#if (IS_ENABLED(CONFIG_NVME_FC))
int ql2xnvmeenable = …;
#else
int ql2xnvmeenable;
#endif
module_param(ql2xnvmeenable, int, 0644);
MODULE_PARM_DESC(…) …;
int ql2xenablehba_err_chk = …;
module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xiidmaenable = …;
module_param(ql2xiidmaenable, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xmqsupport = …;
module_param(ql2xmqsupport, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xfwloadbin;
module_param(ql2xfwloadbin, int, S_IRUGO|S_IWUSR);
module_param_named(fwload, ql2xfwloadbin, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xetsenable;
module_param(ql2xetsenable, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xdbwr = …;
module_param(ql2xdbwr, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xgffidenable;
module_param(ql2xgffidenable, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xasynctmfenable = …;
module_param(ql2xasynctmfenable, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xdontresethba;
module_param(ql2xdontresethba, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
uint64_t ql2xmaxlun = …;
module_param(ql2xmaxlun, ullong, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xmdcapmask = …;
module_param(ql2xmdcapmask, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xmdenable = …;
module_param(ql2xmdenable, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xexlogins;
module_param(ql2xexlogins, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xexchoffld = …;
module_param(ql2xexchoffld, uint, 0644);
MODULE_PARM_DESC(…) …;
int ql2xiniexchg = …;
module_param(ql2xiniexchg, uint, 0644);
MODULE_PARM_DESC(…) …;
int ql2xfwholdabts;
module_param(ql2xfwholdabts, int, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xmvasynctoatio = …;
module_param(ql2xmvasynctoatio, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(…) …;
int ql2xautodetectsfp = …;
module_param(ql2xautodetectsfp, int, 0444);
MODULE_PARM_DESC(…) …;
int ql2xenablemsix = …;
module_param(ql2xenablemsix, int, 0444);
MODULE_PARM_DESC(…) …;
int qla2xuseresexchforels;
module_param(qla2xuseresexchforels, int, 0444);
MODULE_PARM_DESC(…) …;
static int ql2xprotmask;
module_param(ql2xprotmask, int, 0644);
MODULE_PARM_DESC(…) …;
static int ql2xprotguard;
module_param(ql2xprotguard, int, 0644);
MODULE_PARM_DESC(…) …;
int ql2xdifbundlinginternalbuffers;
module_param(ql2xdifbundlinginternalbuffers, int, 0644);
MODULE_PARM_DESC(…) …;
int ql2xsmartsan;
module_param(ql2xsmartsan, int, 0444);
module_param_named(smartsan, ql2xsmartsan, int, 0444);
MODULE_PARM_DESC(…) …;
int ql2xrdpenable;
module_param(ql2xrdpenable, int, 0444);
module_param_named(rdpenable, ql2xrdpenable, int, 0444);
MODULE_PARM_DESC(…) …;
int ql2xabts_wait_nvme = …;
module_param(ql2xabts_wait_nvme, int, 0444);
MODULE_PARM_DESC(…) …;
static u32 ql2xdelay_before_pci_error_handling = …;
module_param(ql2xdelay_before_pci_error_handling, uint, 0644);
MODULE_PARM_DESC(…) …;
static void qla2x00_clear_drv_active(struct qla_hw_data *);
static void qla2x00_free_device(scsi_qla_host_t *);
static void qla2xxx_map_queues(struct Scsi_Host *shost);
static void qla2x00_destroy_deferred_work(struct qla_hw_data *);
u32 ql2xnvme_queues = …;
module_param(ql2xnvme_queues, uint, S_IRUGO);
MODULE_PARM_DESC(…) …;
int ql2xfc2target = …;
module_param(ql2xfc2target, int, 0444);
MODULE_PARM_DESC(…) …;
static struct scsi_transport_template *qla2xxx_transport_template = …;
struct scsi_transport_template *qla2xxx_transport_vport_template = …;
__inline__ void
qla2x00_start_timer(scsi_qla_host_t *vha, unsigned long interval)
{ … }
static inline void
qla2x00_restart_timer(scsi_qla_host_t *vha, unsigned long interval)
{ … }
static __inline__ void
qla2x00_stop_timer(scsi_qla_host_t *vha)
{ … }
static int qla2x00_do_dpc(void *data);
static void qla2x00_rst_aen(scsi_qla_host_t *);
static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t,
struct req_que **, struct rsp_que **);
static void qla2x00_free_fw_dump(struct qla_hw_data *);
static void qla2x00_mem_free(struct qla_hw_data *);
int qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
struct qla_qpair *qpair);
static void qla_init_base_qpair(struct scsi_qla_host *vha, struct req_que *req,
struct rsp_que *rsp)
{ … }
static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
struct rsp_que *rsp)
{ … }
static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req)
{ … }
static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp)
{ … }
static void qla2x00_free_queues(struct qla_hw_data *ha)
{ … }
static char *
qla2x00_pci_info_str(struct scsi_qla_host *vha, char *str, size_t str_len)
{ … }
static char *
qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str, size_t str_len)
{ … }
static char *
qla2x00_fw_version_str(struct scsi_qla_host *vha, char *str, size_t size)
{ … }
static char *
qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str, size_t size)
{ … }
void qla2x00_sp_free_dma(srb_t *sp)
{ … }
void qla2x00_sp_compl(srb_t *sp, int res)
{ … }
void qla2xxx_qpair_sp_free_dma(srb_t *sp)
{ … }
void qla2xxx_qpair_sp_compl(srb_t *sp, int res)
{ … }
static int
qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
{ … }
int
qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
struct qla_qpair *qpair)
{ … }
int
qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
{ … }
static inline int test_fcport_count(scsi_qla_host_t *vha)
{ … }
void
qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha)
{ … }
static void
qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha)
{ … }
int
qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
{ … }
static int
qla2xxx_eh_abort(struct scsi_cmnd *cmd)
{ … }
#define ABORT_POLLING_PERIOD …
#define ABORT_WAIT_ITER …
static int
__qla2x00_eh_wait_for_pending_commands(struct qla_qpair *qpair, unsigned int t,
uint64_t l, enum nexus_wait_type type)
{ … }
int
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
uint64_t l, enum nexus_wait_type type)
{ … }
static char *reset_errors[] = …;
static int
qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
{ … }
static int
qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
{ … }
static int
qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
{ … }
static int
qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
{ … }
int
qla2x00_loop_reset(scsi_qla_host_t *vha)
{ … }
static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
unsigned long *flags)
__releases(qp->qp_lock_ptr)
__acquires(qp->qp_lock_ptr)
{ … }
static void
__qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
{ … }
void
qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
{ … }
static int
qla2xxx_slave_alloc(struct scsi_device *sdev)
{ … }
static int
qla2xxx_slave_configure(struct scsi_device *sdev)
{ … }
static void
qla2xxx_slave_destroy(struct scsi_device *sdev)
{ … }
static void
qla2x00_config_dma_addressing(struct qla_hw_data *ha)
{ … }
static void
qla2x00_enable_intrs(struct qla_hw_data *ha)
{ … }
static void
qla2x00_disable_intrs(struct qla_hw_data *ha)
{ … }
static void
qla24xx_enable_intrs(struct qla_hw_data *ha)
{ … }
static void
qla24xx_disable_intrs(struct qla_hw_data *ha)
{ … }
static int
qla2x00_iospace_config(struct qla_hw_data *ha)
{ … }
static int
qla83xx_iospace_config(struct qla_hw_data *ha)
{ … }
static struct isp_operations qla2100_isp_ops = …;
static struct isp_operations qla2300_isp_ops = …;
static struct isp_operations qla24xx_isp_ops = …;
static struct isp_operations qla25xx_isp_ops = …;
static struct isp_operations qla81xx_isp_ops = …;
static struct isp_operations qla82xx_isp_ops = …;
static struct isp_operations qla8044_isp_ops = …;
static struct isp_operations qla83xx_isp_ops = …;
static struct isp_operations qlafx00_isp_ops = …;
static struct isp_operations qla27xx_isp_ops = …;
static inline void
qla2x00_set_isp_flags(struct qla_hw_data *ha)
{ … }
static void
qla2xxx_scan_start(struct Scsi_Host *shost)
{ … }
static int
qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time)
{ … }
static void qla_heartbeat_work_fn(struct work_struct *work)
{ … }
static void qla2x00_iocb_work_fn(struct work_struct *work)
{ … }
static void
qla_trace_init(void)
{ … }
static void
qla_trace_uninit(void)
{ … }
static int
qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{ … }
static void __qla_set_remove_flag(scsi_qla_host_t *base_vha)
{ … }
static void
qla2x00_shutdown(struct pci_dev *pdev)
{ … }
static void
qla2x00_delete_all_vps(struct qla_hw_data *ha, scsi_qla_host_t *base_vha)
{ … }
static void
qla2x00_destroy_deferred_work(struct qla_hw_data *ha)
{ … }
static void
qla2x00_unmap_iobases(struct qla_hw_data *ha)
{ … }
static void
qla2x00_clear_drv_active(struct qla_hw_data *ha)
{ … }
static void
qla2x00_remove_one(struct pci_dev *pdev)
{ … }
static inline void
qla24xx_free_purex_list(struct purex_list *list)
{ … }
static void
qla2x00_free_device(scsi_qla_host_t *vha)
{ … }
void qla2x00_free_fcports(struct scsi_qla_host *vha)
{ … }
static inline void
qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport)
{ … }
void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
int do_login)
{ … }
void
qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha)
{ … }
static void qla2x00_set_reserved_loop_ids(struct qla_hw_data *ha)
{ … }
static int
qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
struct req_que **req, struct rsp_que **rsp)
{ … }
int
qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha)
{ … }
void
qla2x00_free_exlogin_buffer(struct qla_hw_data *ha)
{ … }
static void
qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 *ret_cnt, u16 max_cnt)
{ … }
int
qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
{ … }
void
qla2x00_free_exchoffld_buffer(struct qla_hw_data *ha)
{ … }
static void
qla2x00_free_fw_dump(struct qla_hw_data *ha)
{ … }
static void
qla2x00_mem_free(struct qla_hw_data *ha)
{ … }
struct scsi_qla_host *qla2x00_create_host(const struct scsi_host_template *sht,
struct qla_hw_data *ha)
{ … }
struct qla_work_evt *
qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type)
{ … }
int
qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e)
{ … }
int
qla2x00_post_aen_work(struct scsi_qla_host *vha, enum fc_host_event_code code,
u32 data)
{ … }
int
qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb)
{ … }
#define qla2x00_post_async_work(name, type) …
qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN);
qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC);
qla2x00_post_async_work(prlo, QLA_EVT_ASYNC_PRLO);
qla2x00_post_async_work(prlo_done, QLA_EVT_ASYNC_PRLO_DONE);
int
qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code)
{ … }
static void
qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code)
{ … }
int
qlafx00_post_aenfx_work(struct scsi_qla_host *vha, uint32_t evtcode,
uint32_t *data, int cnt)
{ … }
void qla24xx_sched_upd_fcport(fc_port_t *fcport)
{ … }
static
void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
{ … }
static void qla_sp_retry(struct scsi_qla_host *vha, struct qla_work_evt *e)
{ … }
void
qla2x00_do_work(struct scsi_qla_host *vha)
{ … }
int qla24xx_post_relogin_work(struct scsi_qla_host *vha)
{ … }
void qla2x00_relogin(struct scsi_qla_host *vha)
{ … }
void
qla83xx_schedule_work(scsi_qla_host_t *base_vha, int work_code)
{ … }
void
qla83xx_nic_core_unrecoverable_work(struct work_struct *work)
{ … }
void
qla83xx_idc_state_handler_work(struct work_struct *work)
{ … }
static int
qla83xx_check_nic_core_fw_alive(scsi_qla_host_t *base_vha)
{ … }
void
qla83xx_nic_core_reset_work(struct work_struct *work)
{ … }
void
qla83xx_service_idc_aen(struct work_struct *work)
{ … }
#define QLA83XX_WAIT_LOGIC_MS …
static int
qla83xx_force_lock_recovery(scsi_qla_host_t *base_vha)
{ … }
static int
qla83xx_idc_lock_recovery(scsi_qla_host_t *base_vha)
{ … }
void
qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
{ … }
static bool
qla25xx_rdp_rsp_reduce_size(struct scsi_qla_host *vha,
struct purex_entry_24xx *purex)
{ … }
void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
struct purex_item *item)
{ … }
void
qla24xx_free_purex_item(struct purex_item *item)
{ … }
void qla24xx_process_purex_list(struct purex_list *list)
{ … }
void
qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
{ … }
int
__qla83xx_set_drv_presence(scsi_qla_host_t *vha)
{ … }
int
qla83xx_set_drv_presence(scsi_qla_host_t *vha)
{ … }
int
__qla83xx_clear_drv_presence(scsi_qla_host_t *vha)
{ … }
int
qla83xx_clear_drv_presence(scsi_qla_host_t *vha)
{ … }
static void
qla83xx_need_reset_handler(scsi_qla_host_t *vha)
{ … }
static int
qla83xx_device_bootstrap(scsi_qla_host_t *vha)
{ … }
int
qla83xx_idc_state_handler(scsi_qla_host_t *base_vha)
{ … }
void
qla2x00_disable_board_on_pci_error(struct work_struct *work)
{ … }
static int
qla2x00_do_dpc(void *data)
{ … }
void
qla2xxx_wake_dpc(struct scsi_qla_host *vha)
{ … }
static void
qla2x00_rst_aen(scsi_qla_host_t *vha)
{ … }
static bool qla_do_heartbeat(struct scsi_qla_host *vha)
{ … }
static void qla_heart_beat(struct scsi_qla_host *vha, u16 dpc_started)
{ … }
static void qla_wind_down_chip(scsi_qla_host_t *vha)
{ … }
void
qla2x00_timer(struct timer_list *t)
{ … }
#define FW_ISP21XX …
#define FW_ISP22XX …
#define FW_ISP2300 …
#define FW_ISP2322 …
#define FW_ISP24XX …
#define FW_ISP25XX …
#define FW_ISP81XX …
#define FW_ISP82XX …
#define FW_ISP2031 …
#define FW_ISP8031 …
#define FW_ISP27XX …
#define FW_ISP28XX …
#define FW_FILE_ISP21XX …
#define FW_FILE_ISP22XX …
#define FW_FILE_ISP2300 …
#define FW_FILE_ISP2322 …
#define FW_FILE_ISP24XX …
#define FW_FILE_ISP25XX …
#define FW_FILE_ISP81XX …
#define FW_FILE_ISP82XX …
#define FW_FILE_ISP2031 …
#define FW_FILE_ISP8031 …
#define FW_FILE_ISP27XX …
#define FW_FILE_ISP28XX …
static DEFINE_MUTEX(qla_fw_lock);
static struct fw_blob qla_fw_blobs[] = …;
struct fw_blob *
qla2x00_request_firmware(scsi_qla_host_t *vha)
{ … }
static void
qla2x00_release_firmware(void)
{ … }
static void qla_pci_error_cleanup(scsi_qla_host_t *vha)
{ … }
static pci_ers_result_t
qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
{ … }
static pci_ers_result_t
qla2xxx_pci_mmio_enabled(struct pci_dev *pdev)
{ … }
static pci_ers_result_t
qla2xxx_pci_slot_reset(struct pci_dev *pdev)
{ … }
static void
qla2xxx_pci_resume(struct pci_dev *pdev)
{ … }
void qla_pci_set_eeh_busy(struct scsi_qla_host *vha)
{ … }
void qla_schedule_eeh_work(struct scsi_qla_host *vha)
{ … }
static void
qla_pci_reset_prepare(struct pci_dev *pdev)
{ … }
static void
qla_pci_reset_done(struct pci_dev *pdev)
{ … }
static void qla2xxx_map_queues(struct Scsi_Host *shost)
{ … }
struct scsi_host_template qla2xxx_driver_template = …;
static const struct pci_error_handlers qla2xxx_err_handler = …;
static struct pci_device_id qla2xxx_pci_tbl[] = …;
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
static struct pci_driver qla2xxx_pci_driver = …;
static const struct file_operations apidev_fops = …;
static int __init
qla2x00_module_init(void)
{ … }
static void __exit
qla2x00_module_exit(void)
{ … }
module_init(…) …;
module_exit(qla2x00_module_exit);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_FIRMWARE(…);
MODULE_FIRMWARE(…);
MODULE_FIRMWARE(…);
MODULE_FIRMWARE(…);
MODULE_FIRMWARE(…);
MODULE_FIRMWARE(…);