You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (166 commits)
[SCSI] ibmvscsi: convert to use the data buffer accessors
[SCSI] dc395x: convert to use the data buffer accessors
[SCSI] ncr53c8xx: convert to use the data buffer accessors
[SCSI] sym53c8xx: convert to use the data buffer accessors
[SCSI] ppa: coding police and printk levels
[SCSI] aic7xxx_old: remove redundant GFP_ATOMIC from kmalloc
[SCSI] i2o: remove redundant GFP_ATOMIC from kmalloc from device.c
[SCSI] remove the dead CYBERSTORMIII_SCSI option
[SCSI] don't build scsi_dma_{map,unmap} for !HAS_DMA
[SCSI] Clean up scsi_add_lun a bit
[SCSI] 53c700: Remove printk, which triggers because of low scsi clock on SNI RMs
[SCSI] sni_53c710: Cleanup
[SCSI] qla4xxx: Fix underrun/overrun conditions
[SCSI] megaraid_mbox: use mutex instead of semaphore
[SCSI] aacraid: add 51245, 51645 and 52245 adapters to documentation.
[SCSI] qla2xxx: update version to 8.02.00-k1.
[SCSI] qla2xxx: add support for NPIV
[SCSI] stex: use resid for xfer len information
[SCSI] Add Brownie 1200U3P to blacklist
[SCSI] scsi.c: convert to use the data buffer accessors
...
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#/*******************************************************************
|
||||
# * This file is part of the Emulex Linux Device Driver for *
|
||||
# * Fibre Channel Host Bus Adapters. *
|
||||
# * Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
||||
# * Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||
# * EMULEX and SLI are trademarks of Emulex. *
|
||||
# * www.emulex.com *
|
||||
# * *
|
||||
@@ -27,4 +27,5 @@ endif
|
||||
obj-$(CONFIG_SCSI_LPFC) := lpfc.o
|
||||
|
||||
lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o lpfc_hbadisc.o \
|
||||
lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o lpfc_scsi.o lpfc_attr.o
|
||||
lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o lpfc_scsi.o lpfc_attr.o \
|
||||
lpfc_vport.o lpfc_debugfs.o
|
||||
|
||||
+286
-104
@@ -19,8 +19,9 @@
|
||||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
struct lpfc_sli2_slim;
|
||||
#include <scsi/scsi_host.h>
|
||||
|
||||
struct lpfc_sli2_slim;
|
||||
|
||||
#define LPFC_MAX_TARGET 256 /* max number of targets supported */
|
||||
#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els
|
||||
@@ -32,6 +33,20 @@ struct lpfc_sli2_slim;
|
||||
#define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */
|
||||
#define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */
|
||||
|
||||
/*
|
||||
* Following time intervals are used of adjusting SCSI device
|
||||
* queue depths when there are driver resource error or Firmware
|
||||
* resource error.
|
||||
*/
|
||||
#define QUEUE_RAMP_DOWN_INTERVAL (1 * HZ) /* 1 Second */
|
||||
#define QUEUE_RAMP_UP_INTERVAL (300 * HZ) /* 5 minutes */
|
||||
|
||||
/* Number of exchanges reserved for discovery to complete */
|
||||
#define LPFC_DISC_IOCB_BUFF_COUNT 20
|
||||
|
||||
#define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */
|
||||
#define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */
|
||||
|
||||
/* Define macros for 64 bit support */
|
||||
#define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr)))
|
||||
#define putPaddrHigh(addr) ((uint32_t) (0xffffffff & (((u64)(addr))>>32)))
|
||||
@@ -61,6 +76,11 @@ struct lpfc_dma_pool {
|
||||
uint32_t current_count;
|
||||
};
|
||||
|
||||
struct hbq_dmabuf {
|
||||
struct lpfc_dmabuf dbuf;
|
||||
uint32_t tag;
|
||||
};
|
||||
|
||||
/* Priority bit. Set value to exceed low water mark in lpfc_mem. */
|
||||
#define MEM_PRI 0x100
|
||||
|
||||
@@ -90,6 +110,29 @@ typedef struct lpfc_vpd {
|
||||
uint32_t sli2FwRev;
|
||||
uint8_t sli2FwName[16];
|
||||
} rev;
|
||||
struct {
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
uint32_t rsvd2 :24; /* Reserved */
|
||||
uint32_t cmv : 1; /* Configure Max VPIs */
|
||||
uint32_t ccrp : 1; /* Config Command Ring Polling */
|
||||
uint32_t csah : 1; /* Configure Synchronous Abort Handling */
|
||||
uint32_t chbs : 1; /* Cofigure Host Backing store */
|
||||
uint32_t cinb : 1; /* Enable Interrupt Notification Block */
|
||||
uint32_t cerbm : 1; /* Configure Enhanced Receive Buf Mgmt */
|
||||
uint32_t cmx : 1; /* Configure Max XRIs */
|
||||
uint32_t cmr : 1; /* Configure Max RPIs */
|
||||
#else /* __LITTLE_ENDIAN */
|
||||
uint32_t cmr : 1; /* Configure Max RPIs */
|
||||
uint32_t cmx : 1; /* Configure Max XRIs */
|
||||
uint32_t cerbm : 1; /* Configure Enhanced Receive Buf Mgmt */
|
||||
uint32_t cinb : 1; /* Enable Interrupt Notification Block */
|
||||
uint32_t chbs : 1; /* Cofigure Host Backing store */
|
||||
uint32_t csah : 1; /* Configure Synchronous Abort Handling */
|
||||
uint32_t ccrp : 1; /* Config Command Ring Polling */
|
||||
uint32_t cmv : 1; /* Configure Max VPIs */
|
||||
uint32_t rsvd2 :24; /* Reserved */
|
||||
#endif
|
||||
} sli3Feat;
|
||||
} lpfc_vpd_t;
|
||||
|
||||
struct lpfc_scsi_buf;
|
||||
@@ -122,6 +165,7 @@ struct lpfc_stats {
|
||||
uint32_t elsRcvRPS;
|
||||
uint32_t elsRcvRPL;
|
||||
uint32_t elsXmitFLOGI;
|
||||
uint32_t elsXmitFDISC;
|
||||
uint32_t elsXmitPLOGI;
|
||||
uint32_t elsXmitPRLI;
|
||||
uint32_t elsXmitADISC;
|
||||
@@ -165,96 +209,71 @@ struct lpfc_sysfs_mbox {
|
||||
struct lpfcMboxq * mbox;
|
||||
};
|
||||
|
||||
struct lpfc_hba {
|
||||
struct lpfc_sli sli;
|
||||
struct lpfc_sli2_slim *slim2p;
|
||||
dma_addr_t slim2p_mapping;
|
||||
uint16_t pci_cfg_value;
|
||||
struct lpfc_hba;
|
||||
|
||||
int32_t hba_state;
|
||||
|
||||
#define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */
|
||||
#define LPFC_WARM_START 1 /* HBA state after selective reset */
|
||||
#define LPFC_INIT_START 2 /* Initial state after board reset */
|
||||
#define LPFC_INIT_MBX_CMDS 3 /* Initialize HBA with mbox commands */
|
||||
#define LPFC_LINK_DOWN 4 /* HBA initialized, link is down */
|
||||
#define LPFC_LINK_UP 5 /* Link is up - issue READ_LA */
|
||||
#define LPFC_LOCAL_CFG_LINK 6 /* local NPORT Id configured */
|
||||
#define LPFC_FLOGI 7 /* FLOGI sent to Fabric */
|
||||
#define LPFC_FABRIC_CFG_LINK 8 /* Fabric assigned NPORT Id
|
||||
configured */
|
||||
#define LPFC_NS_REG 9 /* Register with NameServer */
|
||||
#define LPFC_NS_QRY 10 /* Query NameServer for NPort ID list */
|
||||
#define LPFC_BUILD_DISC_LIST 11 /* Build ADISC and PLOGI lists for
|
||||
* device authentication / discovery */
|
||||
#define LPFC_DISC_AUTH 12 /* Processing ADISC list */
|
||||
#define LPFC_CLEAR_LA 13 /* authentication cmplt - issue
|
||||
CLEAR_LA */
|
||||
#define LPFC_HBA_READY 32
|
||||
#define LPFC_HBA_ERROR -1
|
||||
enum discovery_state {
|
||||
LPFC_VPORT_UNKNOWN = 0, /* vport state is unknown */
|
||||
LPFC_VPORT_FAILED = 1, /* vport has failed */
|
||||
LPFC_LOCAL_CFG_LINK = 6, /* local NPORT Id configured */
|
||||
LPFC_FLOGI = 7, /* FLOGI sent to Fabric */
|
||||
LPFC_FDISC = 8, /* FDISC sent for vport */
|
||||
LPFC_FABRIC_CFG_LINK = 9, /* Fabric assigned NPORT Id
|
||||
* configured */
|
||||
LPFC_NS_REG = 10, /* Register with NameServer */
|
||||
LPFC_NS_QRY = 11, /* Query NameServer for NPort ID list */
|
||||
LPFC_BUILD_DISC_LIST = 12, /* Build ADISC and PLOGI lists for
|
||||
* device authentication / discovery */
|
||||
LPFC_DISC_AUTH = 13, /* Processing ADISC list */
|
||||
LPFC_VPORT_READY = 32,
|
||||
};
|
||||
|
||||
int32_t stopped; /* HBA has not been restarted since last ERATT */
|
||||
uint8_t fc_linkspeed; /* Link speed after last READ_LA */
|
||||
enum hba_state {
|
||||
LPFC_LINK_UNKNOWN = 0, /* HBA state is unknown */
|
||||
LPFC_WARM_START = 1, /* HBA state after selective reset */
|
||||
LPFC_INIT_START = 2, /* Initial state after board reset */
|
||||
LPFC_INIT_MBX_CMDS = 3, /* Initialize HBA with mbox commands */
|
||||
LPFC_LINK_DOWN = 4, /* HBA initialized, link is down */
|
||||
LPFC_LINK_UP = 5, /* Link is up - issue READ_LA */
|
||||
LPFC_CLEAR_LA = 6, /* authentication cmplt - issue
|
||||
* CLEAR_LA */
|
||||
LPFC_HBA_READY = 32,
|
||||
LPFC_HBA_ERROR = -1
|
||||
};
|
||||
|
||||
uint32_t fc_eventTag; /* event tag for link attention */
|
||||
uint32_t fc_prli_sent; /* cntr for outstanding PRLIs */
|
||||
struct lpfc_vport {
|
||||
struct list_head listentry;
|
||||
struct lpfc_hba *phba;
|
||||
uint8_t port_type;
|
||||
#define LPFC_PHYSICAL_PORT 1
|
||||
#define LPFC_NPIV_PORT 2
|
||||
#define LPFC_FABRIC_PORT 3
|
||||
enum discovery_state port_state;
|
||||
|
||||
uint32_t num_disc_nodes; /*in addition to hba_state */
|
||||
uint16_t vpi;
|
||||
|
||||
struct timer_list fc_estabtmo; /* link establishment timer */
|
||||
struct timer_list fc_disctmo; /* Discovery rescue timer */
|
||||
struct timer_list fc_fdmitmo; /* fdmi timer */
|
||||
/* These fields used to be binfo */
|
||||
struct lpfc_name fc_nodename; /* fc nodename */
|
||||
struct lpfc_name fc_portname; /* fc portname */
|
||||
uint32_t fc_pref_DID; /* preferred D_ID */
|
||||
uint8_t fc_pref_ALPA; /* preferred AL_PA */
|
||||
uint32_t fc_edtov; /* E_D_TOV timer value */
|
||||
uint32_t fc_arbtov; /* ARB_TOV timer value */
|
||||
uint32_t fc_ratov; /* R_A_TOV timer value */
|
||||
uint32_t fc_rttov; /* R_T_TOV timer value */
|
||||
uint32_t fc_altov; /* AL_TOV timer value */
|
||||
uint32_t fc_crtov; /* C_R_TOV timer value */
|
||||
uint32_t fc_citov; /* C_I_TOV timer value */
|
||||
uint32_t fc_myDID; /* fibre channel S_ID */
|
||||
uint32_t fc_prevDID; /* previous fibre channel S_ID */
|
||||
|
||||
struct serv_parm fc_sparam; /* buffer for our service parameters */
|
||||
struct serv_parm fc_fabparam; /* fabric service parameters buffer */
|
||||
uint8_t alpa_map[128]; /* AL_PA map from READ_LA */
|
||||
|
||||
uint8_t fc_ns_retry; /* retries for fabric nameserver */
|
||||
uint32_t fc_nlp_cnt; /* outstanding NODELIST requests */
|
||||
uint32_t fc_rscn_id_cnt; /* count of RSCNs payloads in list */
|
||||
struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN];
|
||||
uint32_t lmt;
|
||||
uint32_t fc_flag; /* FC flags */
|
||||
#define FC_PT2PT 0x1 /* pt2pt with no fabric */
|
||||
#define FC_PT2PT_PLOGI 0x2 /* pt2pt initiate PLOGI */
|
||||
#define FC_DISC_TMO 0x4 /* Discovery timer running */
|
||||
#define FC_PUBLIC_LOOP 0x8 /* Public loop */
|
||||
#define FC_LBIT 0x10 /* LOGIN bit in loopinit set */
|
||||
#define FC_RSCN_MODE 0x20 /* RSCN cmd rcv'ed */
|
||||
#define FC_NLP_MORE 0x40 /* More node to process in node tbl */
|
||||
#define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */
|
||||
#define FC_FABRIC 0x100 /* We are fabric attached */
|
||||
#define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */
|
||||
#define FC_RSCN_DISCOVERY 0x400 /* Authenticate all devices after RSCN*/
|
||||
#define FC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */
|
||||
#define FC_LOADING 0x1000 /* HBA in process of loading drvr */
|
||||
#define FC_UNLOADING 0x2000 /* HBA in process of unloading drvr */
|
||||
#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */
|
||||
#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
|
||||
#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */
|
||||
#define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */
|
||||
#define FC_LOOPBACK_MODE 0x40000 /* NPort is in Loopback mode */
|
||||
/* This flag is set while issuing */
|
||||
/* INIT_LINK mailbox command */
|
||||
#define FC_IGNORE_ERATT 0x80000 /* intr handler should ignore ERATT */
|
||||
|
||||
uint32_t fc_topology; /* link topology, from LINK INIT */
|
||||
|
||||
struct lpfc_stats fc_stat;
|
||||
/* Several of these flags are HBA centric and should be moved to
|
||||
* phba->link_flag (e.g. FC_PTP, FC_PUBLIC_LOOP)
|
||||
*/
|
||||
#define FC_PT2PT 0x1 /* pt2pt with no fabric */
|
||||
#define FC_PT2PT_PLOGI 0x2 /* pt2pt initiate PLOGI */
|
||||
#define FC_DISC_TMO 0x4 /* Discovery timer running */
|
||||
#define FC_PUBLIC_LOOP 0x8 /* Public loop */
|
||||
#define FC_LBIT 0x10 /* LOGIN bit in loopinit set */
|
||||
#define FC_RSCN_MODE 0x20 /* RSCN cmd rcv'ed */
|
||||
#define FC_NLP_MORE 0x40 /* More node to process in node tbl */
|
||||
#define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */
|
||||
#define FC_FABRIC 0x100 /* We are fabric attached */
|
||||
#define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */
|
||||
#define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */
|
||||
#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */
|
||||
#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
|
||||
#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */
|
||||
#define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */
|
||||
#define FC_RFF_NOT_SUPPORTED 0x40000 /* RFF_ID was rejected by switch */
|
||||
#define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */
|
||||
#define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */
|
||||
|
||||
struct list_head fc_nodes;
|
||||
|
||||
@@ -267,10 +286,131 @@ struct lpfc_hba {
|
||||
uint16_t fc_map_cnt;
|
||||
uint16_t fc_npr_cnt;
|
||||
uint16_t fc_unused_cnt;
|
||||
struct serv_parm fc_sparam; /* buffer for our service parameters */
|
||||
|
||||
uint32_t fc_myDID; /* fibre channel S_ID */
|
||||
uint32_t fc_prevDID; /* previous fibre channel S_ID */
|
||||
|
||||
int32_t stopped; /* HBA has not been restarted since last ERATT */
|
||||
uint8_t fc_linkspeed; /* Link speed after last READ_LA */
|
||||
|
||||
uint32_t num_disc_nodes; /*in addition to hba_state */
|
||||
|
||||
uint32_t fc_nlp_cnt; /* outstanding NODELIST requests */
|
||||
uint32_t fc_rscn_id_cnt; /* count of RSCNs payloads in list */
|
||||
struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN];
|
||||
struct lpfc_name fc_nodename; /* fc nodename */
|
||||
struct lpfc_name fc_portname; /* fc portname */
|
||||
|
||||
struct lpfc_work_evt disc_timeout_evt;
|
||||
|
||||
struct timer_list fc_disctmo; /* Discovery rescue timer */
|
||||
uint8_t fc_ns_retry; /* retries for fabric nameserver */
|
||||
uint32_t fc_prli_sent; /* cntr for outstanding PRLIs */
|
||||
|
||||
spinlock_t work_port_lock;
|
||||
uint32_t work_port_events; /* Timeout to be handled */
|
||||
#define WORKER_DISC_TMO 0x1 /* vport: Discovery timeout */
|
||||
#define WORKER_ELS_TMO 0x2 /* vport: ELS timeout */
|
||||
#define WORKER_FDMI_TMO 0x4 /* vport: FDMI timeout */
|
||||
|
||||
#define WORKER_MBOX_TMO 0x100 /* hba: MBOX timeout */
|
||||
#define WORKER_HB_TMO 0x200 /* hba: Heart beat timeout */
|
||||
#define WORKER_FABRIC_BLOCK_TMO 0x400 /* hba: fabric block timout */
|
||||
#define WORKER_RAMP_DOWN_QUEUE 0x800 /* hba: Decrease Q depth */
|
||||
#define WORKER_RAMP_UP_QUEUE 0x1000 /* hba: Increase Q depth */
|
||||
|
||||
struct timer_list fc_fdmitmo;
|
||||
struct timer_list els_tmofunc;
|
||||
|
||||
int unreg_vpi_cmpl;
|
||||
|
||||
uint8_t load_flag;
|
||||
#define FC_LOADING 0x1 /* HBA in process of loading drvr */
|
||||
#define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */
|
||||
char *vname; /* Application assigned name */
|
||||
struct fc_vport *fc_vport;
|
||||
|
||||
#ifdef CONFIG_LPFC_DEBUG_FS
|
||||
struct dentry *debug_disc_trc;
|
||||
struct dentry *debug_nodelist;
|
||||
struct dentry *vport_debugfs_root;
|
||||
struct lpfc_disc_trc *disc_trc;
|
||||
atomic_t disc_trc_cnt;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct hbq_s {
|
||||
uint16_t entry_count; /* Current number of HBQ slots */
|
||||
uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */
|
||||
uint32_t hbqPutIdx; /* HBQ slot to use */
|
||||
uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */
|
||||
};
|
||||
|
||||
#define LPFC_MAX_HBQS 16
|
||||
/* this matches the possition in the lpfc_hbq_defs array */
|
||||
#define LPFC_ELS_HBQ 0
|
||||
|
||||
struct lpfc_hba {
|
||||
struct lpfc_sli sli;
|
||||
uint32_t sli_rev; /* SLI2 or SLI3 */
|
||||
uint32_t sli3_options; /* Mask of enabled SLI3 options */
|
||||
#define LPFC_SLI3_ENABLED 0x01
|
||||
#define LPFC_SLI3_HBQ_ENABLED 0x02
|
||||
#define LPFC_SLI3_NPIV_ENABLED 0x04
|
||||
#define LPFC_SLI3_VPORT_TEARDOWN 0x08
|
||||
uint32_t iocb_cmd_size;
|
||||
uint32_t iocb_rsp_size;
|
||||
|
||||
enum hba_state link_state;
|
||||
uint32_t link_flag; /* link state flags */
|
||||
#define LS_LOOPBACK_MODE 0x1 /* NPort is in Loopback mode */
|
||||
/* This flag is set while issuing */
|
||||
/* INIT_LINK mailbox command */
|
||||
#define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */
|
||||
#define LS_IGNORE_ERATT 0x3 /* intr handler should ignore ERATT */
|
||||
|
||||
struct lpfc_sli2_slim *slim2p;
|
||||
struct lpfc_dmabuf hbqslimp;
|
||||
|
||||
dma_addr_t slim2p_mapping;
|
||||
|
||||
uint16_t pci_cfg_value;
|
||||
|
||||
uint8_t work_found;
|
||||
#define LPFC_MAX_WORKER_ITERATION 4
|
||||
|
||||
uint8_t fc_linkspeed; /* Link speed after last READ_LA */
|
||||
|
||||
uint32_t fc_eventTag; /* event tag for link attention */
|
||||
|
||||
|
||||
struct timer_list fc_estabtmo; /* link establishment timer */
|
||||
/* These fields used to be binfo */
|
||||
uint32_t fc_pref_DID; /* preferred D_ID */
|
||||
uint8_t fc_pref_ALPA; /* preferred AL_PA */
|
||||
uint32_t fc_edtov; /* E_D_TOV timer value */
|
||||
uint32_t fc_arbtov; /* ARB_TOV timer value */
|
||||
uint32_t fc_ratov; /* R_A_TOV timer value */
|
||||
uint32_t fc_rttov; /* R_T_TOV timer value */
|
||||
uint32_t fc_altov; /* AL_TOV timer value */
|
||||
uint32_t fc_crtov; /* C_R_TOV timer value */
|
||||
uint32_t fc_citov; /* C_I_TOV timer value */
|
||||
|
||||
struct serv_parm fc_fabparam; /* fabric service parameters buffer */
|
||||
uint8_t alpa_map[128]; /* AL_PA map from READ_LA */
|
||||
|
||||
uint32_t lmt;
|
||||
|
||||
uint32_t fc_topology; /* link topology, from LINK INIT */
|
||||
|
||||
struct lpfc_stats fc_stat;
|
||||
|
||||
struct lpfc_nodelist fc_fcpnodev; /* nodelist entry for no device */
|
||||
uint32_t nport_event_cnt; /* timestamp for nlplist entry */
|
||||
|
||||
uint32_t wwnn[2];
|
||||
uint8_t wwnn[8];
|
||||
uint8_t wwpn[8];
|
||||
uint32_t RandomData[7];
|
||||
|
||||
uint32_t cfg_log_verbose;
|
||||
@@ -278,6 +418,9 @@ struct lpfc_hba {
|
||||
uint32_t cfg_nodev_tmo;
|
||||
uint32_t cfg_devloss_tmo;
|
||||
uint32_t cfg_hba_queue_depth;
|
||||
uint32_t cfg_peer_port_login;
|
||||
uint32_t cfg_vport_restrict_login;
|
||||
uint32_t cfg_npiv_enable;
|
||||
uint32_t cfg_fcp_class;
|
||||
uint32_t cfg_use_adisc;
|
||||
uint32_t cfg_ack0;
|
||||
@@ -304,22 +447,20 @@ struct lpfc_hba {
|
||||
|
||||
lpfc_vpd_t vpd; /* vital product data */
|
||||
|
||||
struct Scsi_Host *host;
|
||||
struct pci_dev *pcidev;
|
||||
struct list_head work_list;
|
||||
uint32_t work_ha; /* Host Attention Bits for WT */
|
||||
uint32_t work_ha_mask; /* HA Bits owned by WT */
|
||||
uint32_t work_hs; /* HS stored in case of ERRAT */
|
||||
uint32_t work_status[2]; /* Extra status from SLIM */
|
||||
uint32_t work_hba_events; /* Timeout to be handled */
|
||||
#define WORKER_DISC_TMO 0x1 /* Discovery timeout */
|
||||
#define WORKER_ELS_TMO 0x2 /* ELS timeout */
|
||||
#define WORKER_MBOX_TMO 0x4 /* MBOX timeout */
|
||||
#define WORKER_FDMI_TMO 0x8 /* FDMI timeout */
|
||||
|
||||
wait_queue_head_t *work_wait;
|
||||
struct task_struct *worker_thread;
|
||||
|
||||
struct list_head hbq_buffer_list;
|
||||
uint32_t hbq_count; /* Count of configured HBQs */
|
||||
struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */
|
||||
|
||||
unsigned long pci_bar0_map; /* Physical address for PCI BAR0 */
|
||||
unsigned long pci_bar2_map; /* Physical address for PCI BAR2 */
|
||||
void __iomem *slim_memmap_p; /* Kernel memory mapped address for
|
||||
@@ -334,6 +475,10 @@ struct lpfc_hba {
|
||||
reg */
|
||||
void __iomem *HCregaddr; /* virtual address for host ctl reg */
|
||||
|
||||
struct lpfc_hgp __iomem *host_gp; /* Host side get/put pointers */
|
||||
uint32_t __iomem *hbq_put; /* Address in SLIM to HBQ put ptrs */
|
||||
uint32_t *hbq_get; /* Host mem address of HBQ get ptrs */
|
||||
|
||||
int brd_no; /* FC board number */
|
||||
|
||||
char SerialNumber[32]; /* adapter Serial Number */
|
||||
@@ -353,7 +498,6 @@ struct lpfc_hba {
|
||||
uint8_t soft_wwn_enable;
|
||||
|
||||
struct timer_list fcp_poll_timer;
|
||||
struct timer_list els_tmofunc;
|
||||
|
||||
/*
|
||||
* stat counters
|
||||
@@ -370,31 +514,69 @@ struct lpfc_hba {
|
||||
uint32_t total_scsi_bufs;
|
||||
struct list_head lpfc_iocb_list;
|
||||
uint32_t total_iocbq_bufs;
|
||||
spinlock_t hbalock;
|
||||
|
||||
/* pci_mem_pools */
|
||||
struct pci_pool *lpfc_scsi_dma_buf_pool;
|
||||
struct pci_pool *lpfc_mbuf_pool;
|
||||
struct pci_pool *lpfc_hbq_pool;
|
||||
struct lpfc_dma_pool lpfc_mbuf_safety_pool;
|
||||
|
||||
mempool_t *mbox_mem_pool;
|
||||
mempool_t *nlp_mem_pool;
|
||||
|
||||
struct fc_host_statistics link_stats;
|
||||
|
||||
struct list_head port_list;
|
||||
struct lpfc_vport *pport; /* physical lpfc_vport pointer */
|
||||
uint16_t max_vpi; /* Maximum virtual nports */
|
||||
#define LPFC_MAX_VPI 100 /* Max number of VPorts supported */
|
||||
unsigned long *vpi_bmask; /* vpi allocation table */
|
||||
|
||||
/* Data structure used by fabric iocb scheduler */
|
||||
struct list_head fabric_iocb_list;
|
||||
atomic_t fabric_iocb_count;
|
||||
struct timer_list fabric_block_timer;
|
||||
unsigned long bit_flags;
|
||||
#define FABRIC_COMANDS_BLOCKED 0
|
||||
atomic_t num_rsrc_err;
|
||||
atomic_t num_cmd_success;
|
||||
unsigned long last_rsrc_error_time;
|
||||
unsigned long last_ramp_down_time;
|
||||
unsigned long last_ramp_up_time;
|
||||
#ifdef CONFIG_LPFC_DEBUG_FS
|
||||
struct dentry *hba_debugfs_root;
|
||||
atomic_t debugfs_vport_count;
|
||||
#endif
|
||||
|
||||
/* Fields used for heart beat. */
|
||||
unsigned long last_completion_time;
|
||||
struct timer_list hb_tmofunc;
|
||||
uint8_t hb_outstanding;
|
||||
};
|
||||
|
||||
static inline void
|
||||
lpfc_set_loopback_flag(struct lpfc_hba *phba) {
|
||||
if (phba->cfg_topology == FLAGS_LOCAL_LB)
|
||||
phba->fc_flag |= FC_LOOPBACK_MODE;
|
||||
else
|
||||
phba->fc_flag &= ~FC_LOOPBACK_MODE;
|
||||
static inline struct Scsi_Host *
|
||||
lpfc_shost_from_vport(struct lpfc_vport *vport)
|
||||
{
|
||||
return container_of((void *) vport, struct Scsi_Host, hostdata[0]);
|
||||
}
|
||||
|
||||
struct rnidrsp {
|
||||
void *buf;
|
||||
uint32_t uniqueid;
|
||||
struct list_head list;
|
||||
uint32_t data;
|
||||
};
|
||||
static inline void
|
||||
lpfc_set_loopback_flag(struct lpfc_hba *phba)
|
||||
{
|
||||
if (phba->cfg_topology == FLAGS_LOCAL_LB)
|
||||
phba->link_flag |= LS_LOOPBACK_MODE;
|
||||
else
|
||||
phba->link_flag &= ~LS_LOOPBACK_MODE;
|
||||
}
|
||||
|
||||
static inline int
|
||||
lpfc_is_link_up(struct lpfc_hba *phba)
|
||||
{
|
||||
return phba->link_state == LPFC_LINK_UP ||
|
||||
phba->link_state == LPFC_CLEAR_LA ||
|
||||
phba->link_state == LPFC_HBA_READY;
|
||||
}
|
||||
|
||||
#define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */
|
||||
|
||||
|
||||
+547
-213
File diff suppressed because it is too large
Load Diff
+129
-59
@@ -23,92 +23,114 @@ typedef int (*node_filter)(struct lpfc_nodelist *ndlp, void *param);
|
||||
struct fc_rport;
|
||||
void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
|
||||
void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
|
||||
struct lpfc_dmabuf *mp);
|
||||
void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport);
|
||||
void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *, int);
|
||||
void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *,
|
||||
uint32_t);
|
||||
void lpfc_unreg_login(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *);
|
||||
void lpfc_unreg_did(struct lpfc_hba *, uint32_t, LPFC_MBOXQ_t *);
|
||||
int lpfc_reg_login(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *,
|
||||
LPFC_MBOXQ_t *, uint32_t);
|
||||
void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
|
||||
void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
|
||||
void lpfc_reg_vpi(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
|
||||
void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
|
||||
void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
|
||||
|
||||
|
||||
void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove);
|
||||
int lpfc_linkdown(struct lpfc_hba *);
|
||||
void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
|
||||
void lpfc_mbx_cmpl_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_dequeue_node(struct lpfc_hba *, struct lpfc_nodelist *);
|
||||
void lpfc_nlp_set_state(struct lpfc_hba *, struct lpfc_nodelist *, int);
|
||||
void lpfc_drop_node(struct lpfc_hba *, struct lpfc_nodelist *);
|
||||
void lpfc_set_disctmo(struct lpfc_hba *);
|
||||
int lpfc_can_disctmo(struct lpfc_hba *);
|
||||
int lpfc_unreg_rpi(struct lpfc_hba *, struct lpfc_nodelist *);
|
||||
void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *);
|
||||
void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int);
|
||||
void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *);
|
||||
void lpfc_set_disctmo(struct lpfc_vport *);
|
||||
int lpfc_can_disctmo(struct lpfc_vport *);
|
||||
int lpfc_unreg_rpi(struct lpfc_vport *, struct lpfc_nodelist *);
|
||||
void lpfc_unreg_all_rpis(struct lpfc_vport *);
|
||||
void lpfc_unreg_default_rpis(struct lpfc_vport *);
|
||||
void lpfc_issue_reg_vpi(struct lpfc_hba *, struct lpfc_vport *);
|
||||
|
||||
int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||
struct lpfc_iocbq *, struct lpfc_nodelist *);
|
||||
void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t);
|
||||
struct lpfc_iocbq *, struct lpfc_nodelist *);
|
||||
void lpfc_nlp_init(struct lpfc_vport *, struct lpfc_nodelist *, uint32_t);
|
||||
struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *);
|
||||
int lpfc_nlp_put(struct lpfc_nodelist *);
|
||||
struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t);
|
||||
void lpfc_disc_list_loopmap(struct lpfc_hba *);
|
||||
void lpfc_disc_start(struct lpfc_hba *);
|
||||
void lpfc_disc_flush_list(struct lpfc_hba *);
|
||||
struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_vport *, uint32_t);
|
||||
void lpfc_disc_list_loopmap(struct lpfc_vport *);
|
||||
void lpfc_disc_start(struct lpfc_vport *);
|
||||
void lpfc_disc_flush_list(struct lpfc_vport *);
|
||||
void lpfc_cleanup_discovery_resources(struct lpfc_vport *);
|
||||
void lpfc_disc_timeout(unsigned long);
|
||||
|
||||
struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
|
||||
struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi);
|
||||
struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
|
||||
struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
|
||||
|
||||
void lpfc_worker_wake_up(struct lpfc_hba *);
|
||||
int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
|
||||
int lpfc_do_work(void *);
|
||||
int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *,
|
||||
int lpfc_disc_state_machine(struct lpfc_vport *, struct lpfc_nodelist *, void *,
|
||||
uint32_t);
|
||||
|
||||
int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *,
|
||||
struct serv_parm *, uint32_t);
|
||||
int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp);
|
||||
int lpfc_els_abort_flogi(struct lpfc_hba *);
|
||||
int lpfc_initial_flogi(struct lpfc_hba *);
|
||||
int lpfc_issue_els_plogi(struct lpfc_hba *, uint32_t, uint8_t);
|
||||
int lpfc_issue_els_prli(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
||||
int lpfc_issue_els_adisc(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
||||
int lpfc_issue_els_logo(struct lpfc_hba *, struct lpfc_nodelist *, uint8_t);
|
||||
int lpfc_issue_els_scr(struct lpfc_hba *, uint32_t, uint8_t);
|
||||
int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
|
||||
int lpfc_els_rsp_acc(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *,
|
||||
struct lpfc_nodelist *, LPFC_MBOXQ_t *, uint8_t);
|
||||
int lpfc_els_rsp_reject(struct lpfc_hba *, uint32_t, struct lpfc_iocbq *,
|
||||
void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *,
|
||||
struct lpfc_nodelist *);
|
||||
int lpfc_els_rsp_adisc_acc(struct lpfc_hba *, struct lpfc_iocbq *,
|
||||
void lpfc_do_scr_ns_plogi(struct lpfc_hba *, struct lpfc_vport *);
|
||||
int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *,
|
||||
struct serv_parm *, uint32_t);
|
||||
int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *);
|
||||
int lpfc_els_chk_latt(struct lpfc_vport *);
|
||||
int lpfc_els_abort_flogi(struct lpfc_hba *);
|
||||
int lpfc_initial_flogi(struct lpfc_vport *);
|
||||
int lpfc_initial_fdisc(struct lpfc_vport *);
|
||||
int lpfc_issue_els_fdisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
|
||||
int lpfc_issue_els_plogi(struct lpfc_vport *, uint32_t, uint8_t);
|
||||
int lpfc_issue_els_prli(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
|
||||
int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
|
||||
int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
|
||||
int lpfc_issue_els_npiv_logo(struct lpfc_vport *, struct lpfc_nodelist *);
|
||||
int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t);
|
||||
int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
|
||||
int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
|
||||
int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *,
|
||||
struct lpfc_nodelist *, LPFC_MBOXQ_t *, uint8_t);
|
||||
int lpfc_els_rsp_reject(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *,
|
||||
struct lpfc_nodelist *, LPFC_MBOXQ_t *);
|
||||
int lpfc_els_rsp_adisc_acc(struct lpfc_vport *, struct lpfc_iocbq *,
|
||||
struct lpfc_nodelist *);
|
||||
int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *,
|
||||
int lpfc_els_rsp_prli_acc(struct lpfc_vport *, struct lpfc_iocbq *,
|
||||
struct lpfc_nodelist *);
|
||||
void lpfc_cancel_retry_delay_tmo(struct lpfc_hba *, struct lpfc_nodelist *);
|
||||
void lpfc_cancel_retry_delay_tmo(struct lpfc_vport *, struct lpfc_nodelist *);
|
||||
void lpfc_els_retry_delay(unsigned long);
|
||||
void lpfc_els_retry_delay_handler(struct lpfc_nodelist *);
|
||||
void lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *);
|
||||
void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||
struct lpfc_iocbq *);
|
||||
int lpfc_els_handle_rscn(struct lpfc_hba *);
|
||||
int lpfc_els_flush_rscn(struct lpfc_hba *);
|
||||
int lpfc_rscn_payload_check(struct lpfc_hba *, uint32_t);
|
||||
void lpfc_els_flush_cmd(struct lpfc_hba *);
|
||||
int lpfc_els_disc_adisc(struct lpfc_hba *);
|
||||
int lpfc_els_disc_plogi(struct lpfc_hba *);
|
||||
int lpfc_els_handle_rscn(struct lpfc_vport *);
|
||||
void lpfc_els_flush_rscn(struct lpfc_vport *);
|
||||
int lpfc_rscn_payload_check(struct lpfc_vport *, uint32_t);
|
||||
void lpfc_els_flush_cmd(struct lpfc_vport *);
|
||||
int lpfc_els_disc_adisc(struct lpfc_vport *);
|
||||
int lpfc_els_disc_plogi(struct lpfc_vport *);
|
||||
void lpfc_els_timeout(unsigned long);
|
||||
void lpfc_els_timeout_handler(struct lpfc_hba *);
|
||||
void lpfc_els_timeout_handler(struct lpfc_vport *);
|
||||
void lpfc_hb_timeout(unsigned long);
|
||||
void lpfc_hb_timeout_handler(struct lpfc_hba *);
|
||||
|
||||
void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||
struct lpfc_iocbq *);
|
||||
int lpfc_ns_cmd(struct lpfc_hba *, struct lpfc_nodelist *, int);
|
||||
int lpfc_fdmi_cmd(struct lpfc_hba *, struct lpfc_nodelist *, int);
|
||||
int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t);
|
||||
int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int);
|
||||
void lpfc_fdmi_tmo(unsigned long);
|
||||
void lpfc_fdmi_tmo_handler(struct lpfc_hba *);
|
||||
void lpfc_fdmi_timeout_handler(struct lpfc_vport *vport);
|
||||
|
||||
int lpfc_config_port_prep(struct lpfc_hba *);
|
||||
int lpfc_config_port_post(struct lpfc_hba *);
|
||||
@@ -136,16 +158,23 @@ void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_kill_board(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *);
|
||||
void lpfc_mbox_cmpl_put(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
int lpfc_mbox_tmo_val(struct lpfc_hba *, int);
|
||||
|
||||
void lpfc_config_hbq(struct lpfc_hba *, struct lpfc_hbq_init *, uint32_t ,
|
||||
LPFC_MBOXQ_t *);
|
||||
struct lpfc_hbq_entry * lpfc_sli_next_hbq_slot(struct lpfc_hba *, uint32_t);
|
||||
|
||||
int lpfc_mem_alloc(struct lpfc_hba *);
|
||||
void lpfc_mem_free(struct lpfc_hba *);
|
||||
void lpfc_stop_vport_timers(struct lpfc_vport *);
|
||||
|
||||
void lpfc_poll_timeout(unsigned long ptr);
|
||||
void lpfc_poll_start_timer(struct lpfc_hba * phba);
|
||||
void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba);
|
||||
struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
|
||||
void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
|
||||
void __lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
|
||||
uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
|
||||
|
||||
void lpfc_reset_barrier(struct lpfc_hba * phba);
|
||||
@@ -154,6 +183,7 @@ int lpfc_sli_brdkill(struct lpfc_hba *);
|
||||
int lpfc_sli_brdreset(struct lpfc_hba *);
|
||||
int lpfc_sli_brdrestart(struct lpfc_hba *);
|
||||
int lpfc_sli_hba_setup(struct lpfc_hba *);
|
||||
int lpfc_sli_host_down(struct lpfc_vport *);
|
||||
int lpfc_sli_hba_down(struct lpfc_hba *);
|
||||
int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
|
||||
int lpfc_sli_handle_mb_event(struct lpfc_hba *);
|
||||
@@ -164,27 +194,36 @@ void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
int lpfc_sli_issue_iocb(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||
struct lpfc_iocbq *, uint32_t);
|
||||
void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t);
|
||||
int lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *);
|
||||
void lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *);
|
||||
int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||
struct lpfc_dmabuf *);
|
||||
struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *,
|
||||
struct lpfc_sli_ring *,
|
||||
dma_addr_t);
|
||||
int lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *, uint32_t);
|
||||
int lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *, uint32_t);
|
||||
void lpfc_sli_hbqbuf_free_all(struct lpfc_hba *);
|
||||
struct hbq_dmabuf *lpfc_sli_hbqbuf_find(struct lpfc_hba *, uint32_t);
|
||||
int lpfc_sli_hbq_size(void);
|
||||
int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *,
|
||||
struct lpfc_iocbq *);
|
||||
int lpfc_sli_sum_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
|
||||
uint64_t, lpfc_ctx_cmd);
|
||||
uint64_t, lpfc_ctx_cmd);
|
||||
int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
|
||||
uint64_t, uint32_t, lpfc_ctx_cmd);
|
||||
uint64_t, uint32_t, lpfc_ctx_cmd);
|
||||
|
||||
void lpfc_mbox_timeout(unsigned long);
|
||||
void lpfc_mbox_timeout_handler(struct lpfc_hba *);
|
||||
|
||||
struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t);
|
||||
struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, struct lpfc_name *);
|
||||
struct lpfc_nodelist *__lpfc_find_node(struct lpfc_vport *, node_filter,
|
||||
void *);
|
||||
struct lpfc_nodelist *lpfc_find_node(struct lpfc_vport *, node_filter, void *);
|
||||
struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t);
|
||||
struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *,
|
||||
struct lpfc_name *);
|
||||
|
||||
int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
|
||||
uint32_t timeout);
|
||||
uint32_t timeout);
|
||||
|
||||
int lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
|
||||
struct lpfc_sli_ring * pring,
|
||||
@@ -195,25 +234,56 @@ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
|
||||
struct lpfc_iocbq * cmdiocb,
|
||||
struct lpfc_iocbq * rspiocb);
|
||||
|
||||
void *lpfc_hbq_alloc(struct lpfc_hba *, int, dma_addr_t *);
|
||||
void lpfc_hbq_free(struct lpfc_hba *, void *, dma_addr_t);
|
||||
void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *);
|
||||
|
||||
void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *);
|
||||
void __lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
|
||||
void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
|
||||
|
||||
void lpfc_in_buf_free(struct lpfc_hba *, struct lpfc_dmabuf *);
|
||||
/* Function prototypes. */
|
||||
const char* lpfc_info(struct Scsi_Host *);
|
||||
void lpfc_scan_start(struct Scsi_Host *);
|
||||
int lpfc_scan_finished(struct Scsi_Host *, unsigned long);
|
||||
|
||||
void lpfc_get_cfgparam(struct lpfc_hba *);
|
||||
int lpfc_alloc_sysfs_attr(struct lpfc_hba *);
|
||||
void lpfc_free_sysfs_attr(struct lpfc_hba *);
|
||||
extern struct class_device_attribute *lpfc_host_attrs[];
|
||||
int lpfc_alloc_sysfs_attr(struct lpfc_vport *);
|
||||
void lpfc_free_sysfs_attr(struct lpfc_vport *);
|
||||
extern struct class_device_attribute *lpfc_hba_attrs[];
|
||||
extern struct scsi_host_template lpfc_template;
|
||||
extern struct fc_function_template lpfc_transport_functions;
|
||||
extern struct fc_function_template lpfc_vport_transport_functions;
|
||||
extern int lpfc_sli_mode;
|
||||
|
||||
void lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp);
|
||||
int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t);
|
||||
void lpfc_terminate_rport_io(struct fc_rport *);
|
||||
void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport);
|
||||
|
||||
struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct fc_vport *);
|
||||
int lpfc_vport_disable(struct fc_vport *fc_vport, bool disable);
|
||||
void lpfc_mbx_unreg_vpi(struct lpfc_vport *);
|
||||
void destroy_port(struct lpfc_vport *);
|
||||
int lpfc_get_instance(void);
|
||||
void lpfc_host_attrib_init(struct Scsi_Host *);
|
||||
|
||||
extern void lpfc_debugfs_initialize(struct lpfc_vport *);
|
||||
extern void lpfc_debugfs_terminate(struct lpfc_vport *);
|
||||
extern void lpfc_debugfs_disc_trc(struct lpfc_vport *, int, char *, uint32_t,
|
||||
uint32_t, uint32_t);
|
||||
|
||||
/* Interface exported by fabric iocb scheduler */
|
||||
int lpfc_issue_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
|
||||
void lpfc_fabric_abort_vport(struct lpfc_vport *);
|
||||
void lpfc_fabric_abort_nport(struct lpfc_nodelist *);
|
||||
void lpfc_fabric_abort_hba(struct lpfc_hba *);
|
||||
void lpfc_fabric_abort_flogi(struct lpfc_hba *);
|
||||
void lpfc_fabric_block_timeout(unsigned long);
|
||||
void lpfc_unblock_fabric_iocbs(struct lpfc_hba *);
|
||||
void lpfc_adjust_queue_depth(struct lpfc_hba *);
|
||||
void lpfc_ramp_down_queue_handler(struct lpfc_hba *);
|
||||
void lpfc_ramp_up_queue_handler(struct lpfc_hba *);
|
||||
|
||||
#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
|
||||
#define HBA_EVENT_RSCN 5
|
||||
#define HBA_EVENT_LINK_UP 2
|
||||
|
||||
+676
-297
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
* Copyright (C) 2007 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
* www.emulex.com *
|
||||
* *
|
||||
* 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. *
|
||||
*******************************************************************/
|
||||
|
||||
#ifndef _H_LPFC_DEBUG_FS
|
||||
#define _H_LPFC_DEBUG_FS
|
||||
|
||||
#ifdef CONFIG_LPFC_DEBUG_FS
|
||||
struct lpfc_disc_trc {
|
||||
char *fmt;
|
||||
uint32_t data1;
|
||||
uint32_t data2;
|
||||
uint32_t data3;
|
||||
uint32_t seq_cnt;
|
||||
unsigned long jif;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Mask for discovery_trace */
|
||||
#define LPFC_DISC_TRC_ELS_CMD 0x1 /* Trace ELS commands */
|
||||
#define LPFC_DISC_TRC_ELS_RSP 0x2 /* Trace ELS response */
|
||||
#define LPFC_DISC_TRC_ELS_UNSOL 0x4 /* Trace ELS rcv'ed */
|
||||
#define LPFC_DISC_TRC_ELS_ALL 0x7 /* Trace ELS */
|
||||
#define LPFC_DISC_TRC_MBOX_VPORT 0x8 /* Trace vport MBOXs */
|
||||
#define LPFC_DISC_TRC_MBOX 0x10 /* Trace other MBOXs */
|
||||
#define LPFC_DISC_TRC_MBOX_ALL 0x18 /* Trace all MBOXs */
|
||||
#define LPFC_DISC_TRC_CT 0x20 /* Trace disc CT requests */
|
||||
#define LPFC_DISC_TRC_DSM 0x40 /* Trace DSM events */
|
||||
#define LPFC_DISC_TRC_RPORT 0x80 /* Trace rport events */
|
||||
#define LPFC_DISC_TRC_NODE 0x100 /* Trace ndlp state changes */
|
||||
|
||||
#define LPFC_DISC_TRC_DISCOVERY 0xef /* common mask for general
|
||||
* discovery */
|
||||
#endif /* H_LPFC_DEBUG_FS */
|
||||
@@ -36,21 +36,23 @@ enum lpfc_work_type {
|
||||
LPFC_EVT_WARM_START,
|
||||
LPFC_EVT_KILL,
|
||||
LPFC_EVT_ELS_RETRY,
|
||||
LPFC_EVT_DEV_LOSS_DELAY,
|
||||
LPFC_EVT_DEV_LOSS,
|
||||
};
|
||||
|
||||
/* structure used to queue event to the discovery tasklet */
|
||||
struct lpfc_work_evt {
|
||||
struct list_head evt_listp;
|
||||
void * evt_arg1;
|
||||
void * evt_arg2;
|
||||
void *evt_arg1;
|
||||
void *evt_arg2;
|
||||
enum lpfc_work_type evt;
|
||||
};
|
||||
|
||||
|
||||
struct lpfc_nodelist {
|
||||
struct list_head nlp_listp;
|
||||
struct lpfc_name nlp_portname; /* port name */
|
||||
struct lpfc_name nlp_nodename; /* node name */
|
||||
struct lpfc_name nlp_portname;
|
||||
struct lpfc_name nlp_nodename;
|
||||
uint32_t nlp_flag; /* entry flags */
|
||||
uint32_t nlp_DID; /* FC D_ID of entry */
|
||||
uint32_t nlp_last_elscmd; /* Last ELS cmd sent */
|
||||
@@ -75,8 +77,9 @@ struct lpfc_nodelist {
|
||||
struct timer_list nlp_delayfunc; /* Used for delayed ELS cmds */
|
||||
struct fc_rport *rport; /* Corresponding FC transport
|
||||
port structure */
|
||||
struct lpfc_hba *nlp_phba;
|
||||
struct lpfc_vport *vport;
|
||||
struct lpfc_work_evt els_retry_evt;
|
||||
struct lpfc_work_evt dev_loss_evt;
|
||||
unsigned long last_ramp_up_time; /* jiffy of last ramp up */
|
||||
unsigned long last_q_full_time; /* jiffy of last queue full */
|
||||
struct kref kref;
|
||||
@@ -98,7 +101,9 @@ struct lpfc_nodelist {
|
||||
ACC */
|
||||
#define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from
|
||||
NPR list */
|
||||
#define NLP_RM_DFLT_RPI 0x4000000 /* need to remove leftover dflt RPI */
|
||||
#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */
|
||||
#define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */
|
||||
|
||||
/* There are 4 different double linked lists nodelist entries can reside on.
|
||||
* The Port Login (PLOGI) list and Address Discovery (ADISC) list are used
|
||||
|
||||
+2277
-1102
File diff suppressed because it is too large
Load Diff
+1409
-869
File diff suppressed because it is too large
Load Diff
+489
-69
File diff suppressed because it is too large
Load Diff
+624
-328
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,7 @@
|
||||
#define LOG_SLI 0x800 /* SLI events */
|
||||
#define LOG_FCP_ERROR 0x1000 /* log errors, not underruns */
|
||||
#define LOG_LIBDFC 0x2000 /* Libdfc events */
|
||||
#define LOG_VPORT 0x4000 /* NPIV events */
|
||||
#define LOG_ALL_MSG 0xffff /* LOG all messages */
|
||||
|
||||
#define lpfc_printf_log(phba, level, mask, fmt, arg...) \
|
||||
|
||||
+260
-46
@@ -81,6 +81,22 @@ lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
return;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
/* lpfc_heart_beat Issue a HEART_BEAT */
|
||||
/* mailbox command */
|
||||
/**********************************************/
|
||||
void
|
||||
lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
{
|
||||
MAILBOX_t *mb;
|
||||
|
||||
mb = &pmb->mb;
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
mb->mbxCommand = MBX_HEARTBEAT;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
return;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
/* lpfc_read_la Issue a READ LA */
|
||||
/* mailbox command */
|
||||
@@ -134,6 +150,7 @@ lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
void
|
||||
lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
{
|
||||
struct lpfc_vport *vport = phba->pport;
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
|
||||
@@ -147,7 +164,7 @@ lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
mb->un.varCfgLnk.cr_count = phba->cfg_cr_count;
|
||||
}
|
||||
|
||||
mb->un.varCfgLnk.myId = phba->fc_myDID;
|
||||
mb->un.varCfgLnk.myId = vport->fc_myDID;
|
||||
mb->un.varCfgLnk.edtov = phba->fc_edtov;
|
||||
mb->un.varCfgLnk.arbtov = phba->fc_arbtov;
|
||||
mb->un.varCfgLnk.ratov = phba->fc_ratov;
|
||||
@@ -239,7 +256,7 @@ lpfc_init_link(struct lpfc_hba * phba,
|
||||
/* mailbox command */
|
||||
/**********************************************/
|
||||
int
|
||||
lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
|
||||
{
|
||||
struct lpfc_dmabuf *mp;
|
||||
MAILBOX_t *mb;
|
||||
@@ -270,6 +287,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
|
||||
mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
|
||||
mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
|
||||
mb->un.varRdSparm.vpi = vpi;
|
||||
|
||||
/* save address for completion */
|
||||
pmb->context1 = mp;
|
||||
@@ -282,7 +300,8 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
/* mailbox command */
|
||||
/********************************************/
|
||||
void
|
||||
lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb)
|
||||
lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
|
||||
LPFC_MBOXQ_t * pmb)
|
||||
{
|
||||
MAILBOX_t *mb;
|
||||
|
||||
@@ -290,6 +309,7 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb)
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
|
||||
mb->un.varUnregDID.did = did;
|
||||
mb->un.varUnregDID.vpi = vpi;
|
||||
|
||||
mb->mbxCommand = MBX_UNREG_D_ID;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
@@ -335,19 +355,17 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
/* mailbox command */
|
||||
/********************************************/
|
||||
int
|
||||
lpfc_reg_login(struct lpfc_hba * phba,
|
||||
uint32_t did, uint8_t * param, LPFC_MBOXQ_t * pmb, uint32_t flag)
|
||||
lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
|
||||
uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
|
||||
{
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
uint8_t *sparam;
|
||||
struct lpfc_dmabuf *mp;
|
||||
MAILBOX_t *mb;
|
||||
struct lpfc_sli *psli;
|
||||
|
||||
psli = &phba->sli;
|
||||
mb = &pmb->mb;
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
|
||||
mb->un.varRegLogin.rpi = 0;
|
||||
mb->un.varRegLogin.vpi = vpi;
|
||||
mb->un.varRegLogin.did = did;
|
||||
mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */
|
||||
|
||||
@@ -359,12 +377,10 @@ lpfc_reg_login(struct lpfc_hba * phba,
|
||||
kfree(mp);
|
||||
mb->mbxCommand = MBX_REG_LOGIN64;
|
||||
/* REG_LOGIN: no buffers */
|
||||
lpfc_printf_log(phba,
|
||||
KERN_WARNING,
|
||||
LOG_MBOX,
|
||||
"%d:0302 REG_LOGIN: no buffers Data x%x x%x\n",
|
||||
phba->brd_no,
|
||||
(uint32_t) did, (uint32_t) flag);
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
|
||||
"%d (%d):0302 REG_LOGIN: no buffers, DID x%x, "
|
||||
"flag x%x\n",
|
||||
phba->brd_no, vpi, did, flag);
|
||||
return (1);
|
||||
}
|
||||
INIT_LIST_HEAD(&mp->list);
|
||||
@@ -389,7 +405,8 @@ lpfc_reg_login(struct lpfc_hba * phba,
|
||||
/* mailbox command */
|
||||
/**********************************************/
|
||||
void
|
||||
lpfc_unreg_login(struct lpfc_hba * phba, uint32_t rpi, LPFC_MBOXQ_t * pmb)
|
||||
lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
|
||||
LPFC_MBOXQ_t * pmb)
|
||||
{
|
||||
MAILBOX_t *mb;
|
||||
|
||||
@@ -398,12 +415,52 @@ lpfc_unreg_login(struct lpfc_hba * phba, uint32_t rpi, LPFC_MBOXQ_t * pmb)
|
||||
|
||||
mb->un.varUnregLogin.rpi = (uint16_t) rpi;
|
||||
mb->un.varUnregLogin.rsvd1 = 0;
|
||||
mb->un.varUnregLogin.vpi = vpi;
|
||||
|
||||
mb->mbxCommand = MBX_UNREG_LOGIN;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
return;
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
/* lpfc_reg_vpi Issue a REG_VPI */
|
||||
/* mailbox command */
|
||||
/**************************************************/
|
||||
void
|
||||
lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid,
|
||||
LPFC_MBOXQ_t *pmb)
|
||||
{
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
|
||||
mb->un.varRegVpi.vpi = vpi;
|
||||
mb->un.varRegVpi.sid = sid;
|
||||
|
||||
mb->mbxCommand = MBX_REG_VPI;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
/* lpfc_unreg_vpi Issue a UNREG_VNPI */
|
||||
/* mailbox command */
|
||||
/**************************************************/
|
||||
void
|
||||
lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
|
||||
{
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
|
||||
mb->un.varUnregVpi.vpi = vpi;
|
||||
|
||||
mb->mbxCommand = MBX_UNREG_VPI;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_config_pcb_setup(struct lpfc_hba * phba)
|
||||
{
|
||||
@@ -412,14 +469,18 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
|
||||
PCB_t *pcbp = &phba->slim2p->pcb;
|
||||
dma_addr_t pdma_addr;
|
||||
uint32_t offset;
|
||||
uint32_t iocbCnt;
|
||||
uint32_t iocbCnt = 0;
|
||||
int i;
|
||||
|
||||
pcbp->maxRing = (psli->num_rings - 1);
|
||||
|
||||
iocbCnt = 0;
|
||||
for (i = 0; i < psli->num_rings; i++) {
|
||||
pring = &psli->ring[i];
|
||||
|
||||
pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE:
|
||||
SLI2_IOCB_CMD_SIZE;
|
||||
pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE:
|
||||
SLI2_IOCB_RSP_SIZE;
|
||||
/* A ring MUST have both cmd and rsp entries defined to be
|
||||
valid */
|
||||
if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
|
||||
@@ -434,20 +495,18 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
|
||||
continue;
|
||||
}
|
||||
/* Command ring setup for ring */
|
||||
pring->cmdringaddr =
|
||||
(void *)&phba->slim2p->IOCBs[iocbCnt];
|
||||
pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
|
||||
pcbp->rdsc[i].cmdEntries = pring->numCiocb;
|
||||
|
||||
offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
|
||||
(uint8_t *)phba->slim2p;
|
||||
offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] -
|
||||
(uint8_t *) phba->slim2p;
|
||||
pdma_addr = phba->slim2p_mapping + offset;
|
||||
pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
|
||||
pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
|
||||
iocbCnt += pring->numCiocb;
|
||||
|
||||
/* Response ring setup for ring */
|
||||
pring->rspringaddr =
|
||||
(void *)&phba->slim2p->IOCBs[iocbCnt];
|
||||
pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
|
||||
|
||||
pcbp->rdsc[i].rspEntries = pring->numRiocb;
|
||||
offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
|
||||
@@ -462,16 +521,108 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
|
||||
void
|
||||
lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
{
|
||||
MAILBOX_t *mb;
|
||||
|
||||
mb = &pmb->mb;
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
mb->un.varRdRev.cv = 1;
|
||||
mb->un.varRdRev.v3req = 1; /* Request SLI3 info */
|
||||
mb->mbxCommand = MBX_READ_REV;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb,
|
||||
struct lpfc_hbq_init *hbq_desc)
|
||||
{
|
||||
hbqmb->profiles.profile2.seqlenbcnt = hbq_desc->seqlenbcnt;
|
||||
hbqmb->profiles.profile2.maxlen = hbq_desc->maxlen;
|
||||
hbqmb->profiles.profile2.seqlenoff = hbq_desc->seqlenoff;
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb,
|
||||
struct lpfc_hbq_init *hbq_desc)
|
||||
{
|
||||
hbqmb->profiles.profile3.seqlenbcnt = hbq_desc->seqlenbcnt;
|
||||
hbqmb->profiles.profile3.maxlen = hbq_desc->maxlen;
|
||||
hbqmb->profiles.profile3.cmdcodeoff = hbq_desc->cmdcodeoff;
|
||||
hbqmb->profiles.profile3.seqlenoff = hbq_desc->seqlenoff;
|
||||
memcpy(&hbqmb->profiles.profile3.cmdmatch, hbq_desc->cmdmatch,
|
||||
sizeof(hbqmb->profiles.profile3.cmdmatch));
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb,
|
||||
struct lpfc_hbq_init *hbq_desc)
|
||||
{
|
||||
hbqmb->profiles.profile5.seqlenbcnt = hbq_desc->seqlenbcnt;
|
||||
hbqmb->profiles.profile5.maxlen = hbq_desc->maxlen;
|
||||
hbqmb->profiles.profile5.cmdcodeoff = hbq_desc->cmdcodeoff;
|
||||
hbqmb->profiles.profile5.seqlenoff = hbq_desc->seqlenoff;
|
||||
memcpy(&hbqmb->profiles.profile5.cmdmatch, hbq_desc->cmdmatch,
|
||||
sizeof(hbqmb->profiles.profile5.cmdmatch));
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc,
|
||||
uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb)
|
||||
{
|
||||
int i;
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
struct config_hbq_var *hbqmb = &mb->un.varCfgHbq;
|
||||
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
hbqmb->entry_count = hbq_desc->entry_count; /* # entries in HBQ */
|
||||
hbqmb->recvNotify = hbq_desc->rn; /* Receive
|
||||
* Notification */
|
||||
hbqmb->numMask = hbq_desc->mask_count; /* # R_CTL/TYPE masks
|
||||
* # in words 0-19 */
|
||||
hbqmb->profile = hbq_desc->profile; /* Selection profile:
|
||||
* 0 = all,
|
||||
* 7 = logentry */
|
||||
hbqmb->ringMask = hbq_desc->ring_mask; /* Binds HBQ to a ring
|
||||
* e.g. Ring0=b0001,
|
||||
* ring2=b0100 */
|
||||
hbqmb->headerLen = hbq_desc->headerLen; /* 0 if not profile 4
|
||||
* or 5 */
|
||||
hbqmb->logEntry = hbq_desc->logEntry; /* Set to 1 if this
|
||||
* HBQ will be used
|
||||
* for LogEntry
|
||||
* buffers */
|
||||
hbqmb->hbqaddrLow = putPaddrLow(phba->hbqslimp.phys) +
|
||||
hbq_entry_index * sizeof(struct lpfc_hbq_entry);
|
||||
hbqmb->hbqaddrHigh = putPaddrHigh(phba->hbqslimp.phys);
|
||||
|
||||
mb->mbxCommand = MBX_CONFIG_HBQ;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
|
||||
/* Copy info for profiles 2,3,5. Other
|
||||
* profiles this area is reserved
|
||||
*/
|
||||
if (hbq_desc->profile == 2)
|
||||
lpfc_build_hbq_profile2(hbqmb, hbq_desc);
|
||||
else if (hbq_desc->profile == 3)
|
||||
lpfc_build_hbq_profile3(hbqmb, hbq_desc);
|
||||
else if (hbq_desc->profile == 5)
|
||||
lpfc_build_hbq_profile5(hbqmb, hbq_desc);
|
||||
|
||||
/* Return if no rctl / type masks for this HBQ */
|
||||
if (!hbq_desc->mask_count)
|
||||
return;
|
||||
|
||||
/* Otherwise we setup specific rctl / type masks for this HBQ */
|
||||
for (i = 0; i < hbq_desc->mask_count; i++) {
|
||||
hbqmb->hbqMasks[i].tmatch = hbq_desc->hbqMasks[i].tmatch;
|
||||
hbqmb->hbqMasks[i].tmask = hbq_desc->hbqMasks[i].tmask;
|
||||
hbqmb->hbqMasks[i].rctlmatch = hbq_desc->hbqMasks[i].rctlmatch;
|
||||
hbqmb->hbqMasks[i].rctlmask = hbq_desc->hbqMasks[i].rctlmask;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
|
||||
{
|
||||
@@ -514,15 +665,16 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
{
|
||||
MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr;
|
||||
MAILBOX_t *mb = &pmb->mb;
|
||||
dma_addr_t pdma_addr;
|
||||
uint32_t bar_low, bar_high;
|
||||
size_t offset;
|
||||
struct lpfc_hgp hgp;
|
||||
void __iomem *to_slim;
|
||||
int i;
|
||||
uint32_t pgp_offset;
|
||||
|
||||
memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
|
||||
mb->mbxCommand = MBX_CONFIG_PORT;
|
||||
@@ -535,12 +687,29 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
|
||||
mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
|
||||
|
||||
/* If HBA supports SLI=3 ask for it */
|
||||
|
||||
if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
|
||||
mb->un.varCfgPort.cerbm = 1; /* Request HBQs */
|
||||
mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */
|
||||
if (phba->max_vpi && phba->cfg_npiv_enable &&
|
||||
phba->vpd.sli3Feat.cmv) {
|
||||
mb->un.varCfgPort.max_vpi = phba->max_vpi;
|
||||
mb->un.varCfgPort.cmv = 1;
|
||||
phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
|
||||
} else
|
||||
mb->un.varCfgPort.max_vpi = phba->max_vpi = 0;
|
||||
} else
|
||||
phba->sli_rev = 2;
|
||||
mb->un.varCfgPort.sli_mode = phba->sli_rev;
|
||||
|
||||
/* Now setup pcb */
|
||||
phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;
|
||||
phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2;
|
||||
|
||||
/* Setup Mailbox pointers */
|
||||
phba->slim2p->pcb.mailBoxSize = sizeof(MAILBOX_t);
|
||||
phba->slim2p->pcb.mailBoxSize = offsetof(MAILBOX_t, us) +
|
||||
sizeof(struct sli2_desc);
|
||||
offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p;
|
||||
pdma_addr = phba->slim2p_mapping + offset;
|
||||
phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr);
|
||||
@@ -568,29 +737,70 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low);
|
||||
pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high);
|
||||
|
||||
/*
|
||||
* Set up HGP - Port Memory
|
||||
*
|
||||
* The port expects the host get/put pointers to reside in memory
|
||||
* following the "non-diagnostic" mode mailbox (32 words, 0x80 bytes)
|
||||
* area of SLIM. In SLI-2 mode, there's an additional 16 reserved
|
||||
* words (0x40 bytes). This area is not reserved if HBQs are
|
||||
* configured in SLI-3.
|
||||
*
|
||||
* CR0Put - SLI2(no HBQs) = 0xc0, With HBQs = 0x80
|
||||
* RR0Get 0xc4 0x84
|
||||
* CR1Put 0xc8 0x88
|
||||
* RR1Get 0xcc 0x8c
|
||||
* CR2Put 0xd0 0x90
|
||||
* RR2Get 0xd4 0x94
|
||||
* CR3Put 0xd8 0x98
|
||||
* RR3Get 0xdc 0x9c
|
||||
*
|
||||
* Reserved 0xa0-0xbf
|
||||
* If HBQs configured:
|
||||
* HBQ 0 Put ptr 0xc0
|
||||
* HBQ 1 Put ptr 0xc4
|
||||
* HBQ 2 Put ptr 0xc8
|
||||
* ......
|
||||
* HBQ(M-1)Put Pointer 0xc0+(M-1)*4
|
||||
*
|
||||
*/
|
||||
|
||||
if (phba->sli_rev == 3) {
|
||||
phba->host_gp = &mb_slim->us.s3.host[0];
|
||||
phba->hbq_put = &mb_slim->us.s3.hbq_put[0];
|
||||
} else {
|
||||
phba->host_gp = &mb_slim->us.s2.host[0];
|
||||
phba->hbq_put = NULL;
|
||||
}
|
||||
|
||||
/* mask off BAR0's flag bits 0 - 3 */
|
||||
phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
|
||||
(SLIMOFF*sizeof(uint32_t));
|
||||
(void __iomem *) phba->host_gp -
|
||||
(void __iomem *)phba->MBslimaddr;
|
||||
if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)
|
||||
phba->slim2p->pcb.hgpAddrHigh = bar_high;
|
||||
else
|
||||
phba->slim2p->pcb.hgpAddrHigh = 0;
|
||||
/* write HGP data to SLIM at the required longword offset */
|
||||
memset(&hgp, 0, sizeof(struct lpfc_hgp));
|
||||
to_slim = phba->MBslimaddr + (SLIMOFF*sizeof (uint32_t));
|
||||
|
||||
for (i=0; i < phba->sli.num_rings; i++) {
|
||||
lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp));
|
||||
to_slim += sizeof (struct lpfc_hgp);
|
||||
lpfc_memcpy_to_slim(phba->host_gp + i, &hgp,
|
||||
sizeof(*phba->host_gp));
|
||||
}
|
||||
|
||||
/* Setup Port Group ring pointer */
|
||||
offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
|
||||
(uint8_t *)phba->slim2p;
|
||||
pdma_addr = phba->slim2p_mapping + offset;
|
||||
if (phba->sli_rev == 3)
|
||||
pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s3_pgp.port -
|
||||
(uint8_t *)phba->slim2p;
|
||||
else
|
||||
pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
|
||||
(uint8_t *)phba->slim2p;
|
||||
|
||||
pdma_addr = phba->slim2p_mapping + pgp_offset;
|
||||
phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr);
|
||||
phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr);
|
||||
phba->hbq_get = &phba->slim2p->mbx.us.s3_pgp.hbq_get[0];
|
||||
|
||||
/* Use callback routine to setp rings in the pcb */
|
||||
lpfc_config_pcb_setup(phba);
|
||||
@@ -606,11 +816,7 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
|
||||
|
||||
/* Swap PCB if needed */
|
||||
lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,
|
||||
sizeof (PCB_t));
|
||||
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
"%d:0405 Service Level Interface (SLI) 2 selected\n",
|
||||
phba->brd_no);
|
||||
sizeof(PCB_t));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -644,15 +850,23 @@ lpfc_mbox_get(struct lpfc_hba * phba)
|
||||
LPFC_MBOXQ_t *mbq = NULL;
|
||||
struct lpfc_sli *psli = &phba->sli;
|
||||
|
||||
list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t,
|
||||
list);
|
||||
if (mbq) {
|
||||
list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list);
|
||||
if (mbq)
|
||||
psli->mboxq_cnt--;
|
||||
}
|
||||
|
||||
return mbq;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
|
||||
{
|
||||
/* This function expects to be called from interupt context */
|
||||
spin_lock(&phba->hbalock);
|
||||
list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl);
|
||||
spin_unlock(&phba->hbalock);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
||||
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
* www.emulex.com *
|
||||
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
|
||||
@@ -38,10 +38,13 @@
|
||||
#define LPFC_MBUF_POOL_SIZE 64 /* max elements in MBUF safety pool */
|
||||
#define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */
|
||||
|
||||
|
||||
|
||||
int
|
||||
lpfc_mem_alloc(struct lpfc_hba * phba)
|
||||
{
|
||||
struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
|
||||
int longs;
|
||||
int i;
|
||||
|
||||
phba->lpfc_scsi_dma_buf_pool = pci_pool_create("lpfc_scsi_dma_buf_pool",
|
||||
@@ -80,10 +83,27 @@ lpfc_mem_alloc(struct lpfc_hba * phba)
|
||||
if (!phba->nlp_mem_pool)
|
||||
goto fail_free_mbox_pool;
|
||||
|
||||
phba->lpfc_hbq_pool = pci_pool_create("lpfc_hbq_pool",phba->pcidev,
|
||||
LPFC_BPL_SIZE, 8, 0);
|
||||
if (!phba->lpfc_hbq_pool)
|
||||
goto fail_free_nlp_mem_pool;
|
||||
|
||||
/* vpi zero is reserved for the physical port so add 1 to max */
|
||||
longs = ((phba->max_vpi + 1) + BITS_PER_LONG - 1) / BITS_PER_LONG;
|
||||
phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL);
|
||||
if (!phba->vpi_bmask)
|
||||
goto fail_free_hbq_pool;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_free_hbq_pool:
|
||||
lpfc_sli_hbqbuf_free_all(phba);
|
||||
fail_free_nlp_mem_pool:
|
||||
mempool_destroy(phba->nlp_mem_pool);
|
||||
phba->nlp_mem_pool = NULL;
|
||||
fail_free_mbox_pool:
|
||||
mempool_destroy(phba->mbox_mem_pool);
|
||||
phba->mbox_mem_pool = NULL;
|
||||
fail_free_mbuf_pool:
|
||||
while (i--)
|
||||
pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
|
||||
@@ -91,8 +111,10 @@ lpfc_mem_alloc(struct lpfc_hba * phba)
|
||||
kfree(pool->elements);
|
||||
fail_free_lpfc_mbuf_pool:
|
||||
pci_pool_destroy(phba->lpfc_mbuf_pool);
|
||||
phba->lpfc_mbuf_pool = NULL;
|
||||
fail_free_dma_buf_pool:
|
||||
pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
|
||||
phba->lpfc_scsi_dma_buf_pool = NULL;
|
||||
fail:
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -106,6 +128,9 @@ lpfc_mem_free(struct lpfc_hba * phba)
|
||||
struct lpfc_dmabuf *mp;
|
||||
int i;
|
||||
|
||||
kfree(phba->vpi_bmask);
|
||||
lpfc_sli_hbqbuf_free_all(phba);
|
||||
|
||||
list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq, list) {
|
||||
mp = (struct lpfc_dmabuf *) (mbox->context1);
|
||||
if (mp) {
|
||||
@@ -115,6 +140,15 @@ lpfc_mem_free(struct lpfc_hba * phba)
|
||||
list_del(&mbox->list);
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
}
|
||||
list_for_each_entry_safe(mbox, next_mbox, &psli->mboxq_cmpl, list) {
|
||||
mp = (struct lpfc_dmabuf *) (mbox->context1);
|
||||
if (mp) {
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
}
|
||||
list_del(&mbox->list);
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
}
|
||||
|
||||
psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||
if (psli->mbox_active) {
|
||||
@@ -132,13 +166,21 @@ lpfc_mem_free(struct lpfc_hba * phba)
|
||||
pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt,
|
||||
pool->elements[i].phys);
|
||||
kfree(pool->elements);
|
||||
|
||||
pci_pool_destroy(phba->lpfc_hbq_pool);
|
||||
mempool_destroy(phba->nlp_mem_pool);
|
||||
mempool_destroy(phba->mbox_mem_pool);
|
||||
|
||||
pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool);
|
||||
pci_pool_destroy(phba->lpfc_mbuf_pool);
|
||||
|
||||
/* Free the iocb lookup array */
|
||||
phba->lpfc_hbq_pool = NULL;
|
||||
phba->nlp_mem_pool = NULL;
|
||||
phba->mbox_mem_pool = NULL;
|
||||
phba->lpfc_scsi_dma_buf_pool = NULL;
|
||||
phba->lpfc_mbuf_pool = NULL;
|
||||
|
||||
/* Free the iocb lookup array */
|
||||
kfree(psli->iocbq_lookup);
|
||||
psli->iocbq_lookup = NULL;
|
||||
|
||||
@@ -148,20 +190,23 @@ void *
|
||||
lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
|
||||
{
|
||||
struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
|
||||
unsigned long iflags;
|
||||
void *ret;
|
||||
|
||||
ret = pci_pool_alloc(phba->lpfc_mbuf_pool, GFP_KERNEL, handle);
|
||||
|
||||
if (!ret && ( mem_flags & MEM_PRI) && pool->current_count) {
|
||||
spin_lock_irqsave(&phba->hbalock, iflags);
|
||||
if (!ret && (mem_flags & MEM_PRI) && pool->current_count) {
|
||||
pool->current_count--;
|
||||
ret = pool->elements[pool->current_count].virt;
|
||||
*handle = pool->elements[pool->current_count].phys;
|
||||
}
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
|
||||
__lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
|
||||
{
|
||||
struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
|
||||
|
||||
@@ -174,3 +219,51 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
|
||||
{
|
||||
unsigned long iflags;
|
||||
|
||||
spin_lock_irqsave(&phba->hbalock, iflags);
|
||||
__lpfc_mbuf_free(phba, virt, dma);
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
return;
|
||||
}
|
||||
|
||||
void *
|
||||
lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
|
||||
{
|
||||
void *ret;
|
||||
ret = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_ATOMIC, handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_hbq_free(struct lpfc_hba *phba, void *virt, dma_addr_t dma)
|
||||
{
|
||||
pci_pool_free(phba->lpfc_hbq_pool, virt, dma);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
|
||||
{
|
||||
struct hbq_dmabuf *hbq_entry;
|
||||
|
||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||
hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf);
|
||||
if (hbq_entry->tag == -1) {
|
||||
lpfc_hbq_free(phba, hbq_entry->dbuf.virt,
|
||||
hbq_entry->dbuf.phys);
|
||||
kfree(hbq_entry);
|
||||
} else {
|
||||
lpfc_sli_free_hbq(phba, hbq_entry);
|
||||
}
|
||||
} else {
|
||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||
kfree(mp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+750
-617
File diff suppressed because it is too large
Load Diff
+342
-215
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************
|
||||
* This file is part of the Emulex Linux Device Driver for *
|
||||
* Fibre Channel Host Bus Adapters. *
|
||||
* Copyright (C) 2004-2005 Emulex. All rights reserved. *
|
||||
* Copyright (C) 2004-2006 Emulex. All rights reserved. *
|
||||
* EMULEX and SLI are trademarks of Emulex. *
|
||||
* www.emulex.com *
|
||||
* *
|
||||
@@ -110,7 +110,6 @@ struct fcp_cmnd {
|
||||
struct lpfc_scsi_buf {
|
||||
struct list_head list;
|
||||
struct scsi_cmnd *pCmd;
|
||||
struct lpfc_hba *scsi_hba;
|
||||
struct lpfc_rport_data *rdata;
|
||||
|
||||
uint32_t timeout;
|
||||
|
||||
+1373
-682
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,7 @@
|
||||
|
||||
/* forward declaration for LPFC_IOCB_t's use */
|
||||
struct lpfc_hba;
|
||||
struct lpfc_vport;
|
||||
|
||||
/* Define the context types that SLI handles for abort and sums. */
|
||||
typedef enum _lpfc_ctx_cmd {
|
||||
@@ -43,10 +44,12 @@ struct lpfc_iocbq {
|
||||
#define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */
|
||||
#define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */
|
||||
#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */
|
||||
#define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */
|
||||
|
||||
uint8_t abort_count;
|
||||
uint8_t rsvd2;
|
||||
uint32_t drvrTimeout; /* driver timeout in seconds */
|
||||
struct lpfc_vport *vport;/* virtual port pointer */
|
||||
void *context1; /* caller context information */
|
||||
void *context2; /* caller context information */
|
||||
void *context3; /* caller context information */
|
||||
@@ -56,6 +59,8 @@ struct lpfc_iocbq {
|
||||
struct lpfcMboxq *mbox;
|
||||
} context_un;
|
||||
|
||||
void (*fabric_iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
|
||||
struct lpfc_iocbq *);
|
||||
void (*iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
|
||||
struct lpfc_iocbq *);
|
||||
|
||||
@@ -68,12 +73,14 @@ struct lpfc_iocbq {
|
||||
#define IOCB_ERROR 2
|
||||
#define IOCB_TIMEDOUT 3
|
||||
|
||||
#define LPFC_MBX_WAKE 1
|
||||
#define LPFC_MBX_WAKE 1
|
||||
#define LPFC_MBX_IMED_UNREG 2
|
||||
|
||||
typedef struct lpfcMboxq {
|
||||
/* MBOXQs are used in single linked lists */
|
||||
struct list_head list; /* ptr to next mailbox command */
|
||||
MAILBOX_t mb; /* Mailbox cmd */
|
||||
struct lpfc_vport *vport;/* virutal port pointer */
|
||||
void *context1; /* caller context information */
|
||||
void *context2; /* caller context information */
|
||||
|
||||
@@ -135,6 +142,8 @@ struct lpfc_sli_ring {
|
||||
uint8_t ringno; /* ring number */
|
||||
uint16_t numCiocb; /* number of command iocb's per ring */
|
||||
uint16_t numRiocb; /* number of rsp iocb's per ring */
|
||||
uint16_t sizeCiocb; /* Size of command iocb's in this ring */
|
||||
uint16_t sizeRiocb; /* Size of response iocb's in this ring */
|
||||
|
||||
uint32_t fast_iotag; /* max fastlookup based iotag */
|
||||
uint32_t iotag_ctr; /* keeps track of the next iotag to use */
|
||||
@@ -165,6 +174,34 @@ struct lpfc_sli_ring {
|
||||
struct lpfc_sli_ring *);
|
||||
};
|
||||
|
||||
/* Structure used for configuring rings to a specific profile or rctl / type */
|
||||
struct lpfc_hbq_init {
|
||||
uint32_t rn; /* Receive buffer notification */
|
||||
uint32_t entry_count; /* max # of entries in HBQ */
|
||||
uint32_t headerLen; /* 0 if not profile 4 or 5 */
|
||||
uint32_t logEntry; /* Set to 1 if this HBQ used for LogEntry */
|
||||
uint32_t profile; /* Selection profile 0=all, 7=logentry */
|
||||
uint32_t ring_mask; /* Binds HBQ to a ring e.g. Ring0=b0001,
|
||||
* ring2=b0100 */
|
||||
uint32_t hbq_index; /* index of this hbq in ring .HBQs[] */
|
||||
|
||||
uint32_t seqlenoff;
|
||||
uint32_t maxlen;
|
||||
uint32_t seqlenbcnt;
|
||||
uint32_t cmdcodeoff;
|
||||
uint32_t cmdmatch[8];
|
||||
uint32_t mask_count; /* number of mask entries in prt array */
|
||||
struct hbq_mask hbqMasks[6];
|
||||
|
||||
/* Non-config rings fields to keep track of buffer allocations */
|
||||
uint32_t buffer_count; /* number of buffers allocated */
|
||||
uint32_t init_count; /* number to allocate when initialized */
|
||||
uint32_t add_count; /* number to allocate when starved */
|
||||
} ;
|
||||
|
||||
#define LPFC_MAX_HBQ 16
|
||||
|
||||
|
||||
/* Structure used to hold SLI statistical counters and info */
|
||||
struct lpfc_sli_stat {
|
||||
uint64_t mbox_stat_err; /* Mbox cmds completed status error */
|
||||
@@ -197,6 +234,7 @@ struct lpfc_sli {
|
||||
#define LPFC_SLI_MBOX_ACTIVE 0x100 /* HBA mailbox is currently active */
|
||||
#define LPFC_SLI2_ACTIVE 0x200 /* SLI2 overlay in firmware is active */
|
||||
#define LPFC_PROCESS_LA 0x400 /* Able to process link attention */
|
||||
#define LPFC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */
|
||||
|
||||
struct lpfc_sli_ring ring[LPFC_MAX_RING];
|
||||
int fcp_ring; /* ring used for FCP initiator commands */
|
||||
@@ -209,6 +247,7 @@ struct lpfc_sli {
|
||||
uint16_t mboxq_cnt; /* current length of queue */
|
||||
uint16_t mboxq_max; /* max length */
|
||||
LPFC_MBOXQ_t *mbox_active; /* active mboxq information */
|
||||
struct list_head mboxq_cmpl;
|
||||
|
||||
struct timer_list mbox_tmo; /* Hold clk to timeout active mbox
|
||||
cmd */
|
||||
@@ -221,12 +260,6 @@ struct lpfc_sli {
|
||||
struct lpfc_lnk_stat lnk_stat_offsets;
|
||||
};
|
||||
|
||||
/* Given a pointer to the start of the ring, and the slot number of
|
||||
* the desired iocb entry, calc a pointer to that entry.
|
||||
* (assume iocb entry size is 32 bytes, or 8 words)
|
||||
*/
|
||||
#define IOCB_ENTRY(ring,slot) ((IOCB_t *)(((char *)(ring)) + ((slot) * 32)))
|
||||
|
||||
#define LPFC_MBOX_TMO 30 /* Sec tmo for outstanding mbox
|
||||
command */
|
||||
#define LPFC_MBOX_TMO_FLASH_CMD 300 /* Sec tmo for outstanding FLASH write
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user