/******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.broadcom.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * * * * 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. * *******************************************************************/ #include <linux/blkdev.h> #include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/idr.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux/kthread.h> #include <linux/pci.h> #include <linux/spinlock.h> #include <linux/sched/clock.h> #include <linux/ctype.h> #include <linux/slab.h> #include <linux/firmware.h> #include <linux/miscdevice.h> #include <linux/percpu.h> #include <linux/irq.h> #include <linux/bitops.h> #include <linux/crash_dump.h> #include <linux/cpu.h> #include <linux/cpuhotplug.h> #include <scsi/scsi.h> #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi_transport_fc.h> #include <scsi/scsi_tcq.h> #include <scsi/fc/fc_fs.h> #include "lpfc_hw4.h" #include "lpfc_hw.h" #include "lpfc_sli.h" #include "lpfc_sli4.h" #include "lpfc_nl.h" #include "lpfc_disc.h" #include "lpfc.h" #include "lpfc_scsi.h" #include "lpfc_nvme.h" #include "lpfc_logmsg.h" #include "lpfc_crtn.h" #include "lpfc_vport.h" #include "lpfc_version.h" #include "lpfc_ids.h" static enum cpuhp_state lpfc_cpuhp_state; /* Used when mapping IRQ vectors in a driver centric manner */ static uint32_t lpfc_present_cpu; static bool lpfc_pldv_detect; static void __lpfc_cpuhp_remove(struct lpfc_hba *phba); static void lpfc_cpuhp_remove(struct lpfc_hba *phba); static void lpfc_cpuhp_add(struct lpfc_hba *phba); static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); static int lpfc_post_rcv_buf(struct lpfc_hba *); static int lpfc_sli4_queue_verify(struct lpfc_hba *); static int lpfc_create_bootstrap_mbox(struct lpfc_hba *); static int lpfc_setup_endian_order(struct lpfc_hba *); static void lpfc_destroy_bootstrap_mbox(struct lpfc_hba *); static void lpfc_free_els_sgl_list(struct lpfc_hba *); static void lpfc_free_nvmet_sgl_list(struct lpfc_hba *); static void lpfc_init_sgl_list(struct lpfc_hba *); static int lpfc_init_active_sgl_array(struct lpfc_hba *); static void lpfc_free_active_sgl(struct lpfc_hba *); static int lpfc_hba_down_post_s3(struct lpfc_hba *phba); static int lpfc_hba_down_post_s4(struct lpfc_hba *phba); static int lpfc_sli4_cq_event_pool_create(struct lpfc_hba *); static void lpfc_sli4_cq_event_pool_destroy(struct lpfc_hba *); static void lpfc_sli4_cq_event_release_all(struct lpfc_hba *); static void lpfc_sli4_disable_intr(struct lpfc_hba *); static uint32_t lpfc_sli4_enable_intr(struct lpfc_hba *, uint32_t); static void lpfc_sli4_oas_verify(struct lpfc_hba *phba); static uint16_t lpfc_find_cpu_handle(struct lpfc_hba *, uint16_t, int); static void lpfc_setup_bg(struct lpfc_hba *, struct Scsi_Host *); static int lpfc_sli4_cgn_parm_chg_evt(struct lpfc_hba *); static void lpfc_sli4_async_cmstat_evt(struct lpfc_hba *phba); static void lpfc_sli4_prep_dev_for_reset(struct lpfc_hba *phba); static struct scsi_transport_template *lpfc_transport_template = …; static struct scsi_transport_template *lpfc_vport_transport_template = …; static DEFINE_IDR(lpfc_hba_index); #define LPFC_NVMET_BUF_POST … static int lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport); static void lpfc_cgn_update_tstamp(struct lpfc_hba *phba, struct lpfc_cgn_ts *ts); /** * lpfc_config_port_prep - Perform lpfc initialization prior to config port * @phba: pointer to lpfc hba data structure. * * This routine will do LPFC initialization prior to issuing the CONFIG_PORT * mailbox command. It retrieves the revision information from the HBA and * collects the Vital Product Data (VPD) about the HBA for preparing the * configuration of the HBA. * * Return codes: * 0 - success. * -ERESTART - requests the SLI layer to reset the HBA and try again. * Any other value - indicates an error. **/ int lpfc_config_port_prep(struct lpfc_hba *phba) { … } /** * lpfc_config_async_cmpl - Completion handler for config async event mbox cmd * @phba: pointer to lpfc hba data structure. * @pmboxq: pointer to the driver internal queue element for mailbox command. * * This is the completion handler for driver's configuring asynchronous event * mailbox command to the device. If the mailbox command returns successfully, * it will set internal async event support flag to 1; otherwise, it will * set internal async event support flag to 0. **/ static void lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) { … } /** * lpfc_dump_wakeup_param_cmpl - dump memory mailbox command completion handler * @phba: pointer to lpfc hba data structure. * @pmboxq: pointer to the driver internal queue element for mailbox command. * * This is the completion handler for dump mailbox command for getting * wake up parameters. When this command complete, the response contain * Option rom version of the HBA. This function translate the version number * into a human readable string and store it in OptionROMVersion. **/ static void lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) { … } /** * lpfc_update_vport_wwn - Updates the fc_nodename, fc_portname, * @vport: pointer to lpfc vport data structure. * * * Return codes * None. **/ void lpfc_update_vport_wwn(struct lpfc_vport *vport) { … } /** * lpfc_config_port_post - Perform lpfc initialization after config port * @phba: pointer to lpfc hba data structure. * * This routine will do LPFC initialization after the CONFIG_PORT mailbox * command call. It performs all internal resource and state setups on the * port: post IOCB buffers, enable appropriate host interrupt attentions, * ELS ring timers, etc. * * Return codes * 0 - success. * Any other value - error. **/ int lpfc_config_port_post(struct lpfc_hba *phba) { … } /** * lpfc_sli4_refresh_params - update driver copy of params. * @phba: Pointer to HBA context object. * * This is called to refresh driver copy of dynamic fields from the * common_get_sli4_parameters descriptor. **/ int lpfc_sli4_refresh_params(struct lpfc_hba *phba) { … } /** * lpfc_hba_init_link - Initialize the FC link * @phba: pointer to lpfc hba data structure. * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT * * This routine will issue the INIT_LINK mailbox command call. * It is available to other drivers through the lpfc_hba data * structure for use as a delayed link up mechanism with the * module parameter lpfc_suppress_link_up. * * Return code * 0 - success * Any other value - error **/ static int lpfc_hba_init_link(struct lpfc_hba *phba, uint32_t flag) { … } /** * lpfc_hba_init_link_fc_topology - Initialize FC link with desired topology * @phba: pointer to lpfc hba data structure. * @fc_topology: desired fc topology. * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT * * This routine will issue the INIT_LINK mailbox command call. * It is available to other drivers through the lpfc_hba data * structure for use as a delayed link up mechanism with the * module parameter lpfc_suppress_link_up. * * Return code * 0 - success * Any other value - error **/ int lpfc_hba_init_link_fc_topology(struct lpfc_hba *phba, uint32_t fc_topology, uint32_t flag) { … } /** * lpfc_hba_down_link - this routine downs the FC link * @phba: pointer to lpfc hba data structure. * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT * * This routine will issue the DOWN_LINK mailbox command call. * It is available to other drivers through the lpfc_hba data * structure for use to stop the link. * * Return code * 0 - success * Any other value - error **/ static int lpfc_hba_down_link(struct lpfc_hba *phba, uint32_t flag) { … } /** * lpfc_hba_down_prep - Perform lpfc uninitialization prior to HBA reset * @phba: pointer to lpfc HBA data structure. * * This routine will do LPFC uninitialization before the HBA is reset when * bringing down the SLI Layer. * * Return codes * 0 - success. * Any other value - error. **/ int lpfc_hba_down_prep(struct lpfc_hba *phba) { … } /** * lpfc_sli4_free_sp_events - Cleanup sp_queue_events to free * rspiocb which got deferred * * @phba: pointer to lpfc HBA data structure. * * This routine will cleanup completed slow path events after HBA is reset * when bringing down the SLI Layer. * * * Return codes * void. **/ static void lpfc_sli4_free_sp_events(struct lpfc_hba *phba) { … } /** * lpfc_hba_free_post_buf - Perform lpfc uninitialization after HBA reset * @phba: pointer to lpfc HBA data structure. * * This routine will cleanup posted ELS buffers after the HBA is reset * when bringing down the SLI Layer. * * * Return codes * void. **/ static void lpfc_hba_free_post_buf(struct lpfc_hba *phba) { … } /** * lpfc_hba_clean_txcmplq - Perform lpfc uninitialization after HBA reset * @phba: pointer to lpfc HBA data structure. * * This routine will cleanup the txcmplq after the HBA is reset when bringing * down the SLI Layer. * * Return codes * void **/ static void lpfc_hba_clean_txcmplq(struct lpfc_hba *phba) { … } /** * lpfc_hba_down_post_s3 - Perform lpfc uninitialization after HBA reset * @phba: pointer to lpfc HBA data structure. * * This routine will do uninitialization after the HBA is reset when bring * down the SLI Layer. * * Return codes * 0 - success. * Any other value - error. **/ static int lpfc_hba_down_post_s3(struct lpfc_hba *phba) { … } /** * lpfc_hba_down_post_s4 - Perform lpfc uninitialization after HBA reset * @phba: pointer to lpfc HBA data structure. * * This routine will do uninitialization after the HBA is reset when bring * down the SLI Layer. * * Return codes * 0 - success. * Any other value - error. **/ static int lpfc_hba_down_post_s4(struct lpfc_hba *phba) { … } /** * lpfc_hba_down_post - Wrapper func for hba down post routine * @phba: pointer to lpfc HBA data structure. * * This routine wraps the actual SLI3 or SLI4 routine for performing * uninitialization after the HBA is reset when bring down the SLI Layer. * * Return codes * 0 - success. * Any other value - error. **/ int lpfc_hba_down_post(struct lpfc_hba *phba) { … } /** * lpfc_hb_timeout - The HBA-timer timeout handler * @t: timer context used to obtain the pointer to lpfc hba data structure. * * This is the HBA-timer timeout handler registered to the lpfc driver. When * this timer fires, a HBA timeout event shall be posted to the lpfc driver * work-port-events bitmap and the worker thread is notified. This timeout * event will be used by the worker thread to invoke the actual timeout * handler routine, lpfc_hb_timeout_handler. Any periodical operations will * be performed in the timeout handler and the HBA timeout event bit shall * be cleared by the worker thread after it has taken the event bitmap out. **/ static void lpfc_hb_timeout(struct timer_list *t) { … } /** * lpfc_rrq_timeout - The RRQ-timer timeout handler * @t: timer context used to obtain the pointer to lpfc hba data structure. * * This is the RRQ-timer timeout handler registered to the lpfc driver. When * this timer fires, a RRQ timeout event shall be posted to the lpfc driver * work-port-events bitmap and the worker thread is notified. This timeout * event will be used by the worker thread to invoke the actual timeout * handler routine, lpfc_rrq_handler. Any periodical operations will * be performed in the timeout handler and the RRQ timeout event bit shall * be cleared by the worker thread after it has taken the event bitmap out. **/ static void lpfc_rrq_timeout(struct timer_list *t) { … } /** * lpfc_hb_mbox_cmpl - The lpfc heart-beat mailbox command callback function * @phba: pointer to lpfc hba data structure. * @pmboxq: pointer to the driver internal queue element for mailbox command. * * This is the callback function to the lpfc heart-beat mailbox command. * If configured, the lpfc driver issues the heart-beat mailbox command to * the HBA every LPFC_HB_MBOX_INTERVAL (current 5) seconds. At the time the * heart-beat mailbox command is issued, the driver shall set up heart-beat * timeout timer to LPFC_HB_MBOX_TIMEOUT (current 30) seconds and marks * heart-beat outstanding state. Once the mailbox command comes back and * no error conditions detected, the heart-beat mailbox command timer is * reset to LPFC_HB_MBOX_INTERVAL seconds and the heart-beat outstanding * state is cleared for the next heart-beat. If the timer expired with the * heart-beat outstanding state set, the driver will put the HBA offline. **/ static void lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) { … } /* * lpfc_idle_stat_delay_work - idle_stat tracking * * This routine tracks per-eq idle_stat and determines polling decisions. * * Return codes: * None **/ static void lpfc_idle_stat_delay_work(struct work_struct *work) { … } static void lpfc_hb_eq_delay_work(struct work_struct *work) { … } /** * lpfc_hb_mxp_handler - Multi-XRI pools handler to adjust XRI distribution * @phba: pointer to lpfc hba data structure. * * For each heartbeat, this routine does some heuristic methods to adjust * XRI distribution. The goal is to fully utilize free XRIs. **/ static void lpfc_hb_mxp_handler(struct lpfc_hba *phba) { … } /** * lpfc_issue_hb_mbox - Issues heart-beat mailbox command * @phba: pointer to lpfc hba data structure. * * If a HB mbox is not already in progrees, this routine will allocate * a LPFC_MBOXQ_t, populate it with a MBX_HEARTBEAT (0x31) command, * and issue it. The HBA_HBEAT_INP flag means the command is in progress. **/ int lpfc_issue_hb_mbox(struct lpfc_hba *phba) { … } /** * lpfc_issue_hb_tmo - Signals heartbeat timer to issue mbox command * @phba: pointer to lpfc hba data structure. * * The heartbeat timer (every 5 sec) will fire. If the HBA_HBEAT_TMO * flag is set, it will force a MBX_HEARTBEAT mbox command, regardless * of the value of lpfc_enable_hba_heartbeat. * If lpfc_enable_hba_heartbeat is set, the timeout routine will always * try to issue a MBX_HEARTBEAT mbox command. **/ void lpfc_issue_hb_tmo(struct lpfc_hba *phba) { … } /** * lpfc_hb_timeout_handler - The HBA-timer timeout handler * @phba: pointer to lpfc hba data structure. * * This is the actual HBA-timer timeout handler to be invoked by the worker * thread whenever the HBA timer fired and HBA-timeout event posted. This * handler performs any periodic operations needed for the device. If such * periodic event has already been attended to either in the interrupt handler * or by processing slow-ring or fast-ring events within the HBA-timer * timeout window (LPFC_HB_MBOX_INTERVAL), this handler just simply resets * the timer for the next timeout period. If lpfc heart-beat mailbox command * is configured and there is no heart-beat mailbox command outstanding, a * heart-beat mailbox is issued and timer set properly. Otherwise, if there * has been a heart-beat mailbox command outstanding, the HBA shall be put * to offline. **/ void lpfc_hb_timeout_handler(struct lpfc_hba *phba) { … } /** * lpfc_offline_eratt - Bring lpfc offline on hardware error attention * @phba: pointer to lpfc hba data structure. * * This routine is called to bring the HBA offline when HBA hardware error * other than Port Error 6 has been detected. **/ static void lpfc_offline_eratt(struct lpfc_hba *phba) { … } /** * lpfc_sli4_offline_eratt - Bring lpfc offline on SLI4 hardware error attention * @phba: pointer to lpfc hba data structure. * * This routine is called to bring a SLI4 HBA offline when HBA hardware error * other than Port Error 6 has been detected. **/ void lpfc_sli4_offline_eratt(struct lpfc_hba *phba) { … } /** * lpfc_handle_deferred_eratt - The HBA hardware deferred error handler * @phba: pointer to lpfc hba data structure. * * This routine is invoked to handle the deferred HBA hardware error * conditions. This type of error is indicated by HBA by setting ER1 * and another ER bit in the host status register. The driver will * wait until the ER1 bit clears before handling the error condition. **/ static void lpfc_handle_deferred_eratt(struct lpfc_hba *phba) { … } static void lpfc_board_errevt_to_mgmt(struct lpfc_hba *phba) { … } /** * lpfc_handle_eratt_s3 - The SLI3 HBA hardware error handler * @phba: pointer to lpfc hba data structure. * * This routine is invoked to handle the following HBA hardware error * conditions: * 1 - HBA error attention interrupt * 2 - DMA ring index out of range * 3 - Mailbox command came back as unknown **/ static void lpfc_handle_eratt_s3(struct lpfc_hba *phba) { … } /** * lpfc_sli4_port_sta_fn_reset - The SLI4 function reset due to port status reg * @phba: pointer to lpfc hba data structure. * @mbx_action: flag for mailbox shutdown action. * @en_rn_msg: send reset/port recovery message. * This routine is invoked to perform an SLI4 port PCI function reset in * response to port status register polling attention. It waits for port * status register (ERR, RDY, RN) bits before proceeding with function reset. * During this process, interrupt vectors are freed and later requested * for handling possible port resource change. **/ static int lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action, bool en_rn_msg) { … } /** * lpfc_handle_eratt_s4 - The SLI4 HBA hardware error handler * @phba: pointer to lpfc hba data structure. * * This routine is invoked to handle the SLI4 HBA hardware error attention * conditions. **/ static void lpfc_handle_eratt_s4(struct lpfc_hba *phba) { … } /** * lpfc_handle_eratt - Wrapper func for handling hba error attention * @phba: pointer to lpfc HBA data structure. * * This routine wraps the actual SLI3 or SLI4 hba error attention handling * routine from the API jump table function pointer from the lpfc_hba struct. * * Return codes * 0 - success. * Any other value - error. **/ void lpfc_handle_eratt(struct lpfc_hba *phba) { … } /** * lpfc_handle_latt - The HBA link event handler * @phba: pointer to lpfc hba data structure. * * This routine is invoked from the worker thread to handle a HBA host * attention link event. SLI3 only. **/ void lpfc_handle_latt(struct lpfc_hba *phba) { … } static void lpfc_fill_vpd(struct lpfc_hba *phba, uint8_t *vpd, int length, int *pindex) { … } /** * lpfc_parse_vpd - Parse VPD (Vital Product Data) * @phba: pointer to lpfc hba data structure. * @vpd: pointer to the vital product data. * @len: length of the vital product data in bytes. * * This routine parses the Vital Product Data (VPD). The VPD is treated as * an array of characters. In this routine, the ModelName, ProgramType, and * ModelDesc, etc. fields of the phba data structure will be populated. * * Return codes * 0 - pointer to the VPD passed in is NULL * 1 - success **/ int lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len) { … } /** * lpfc_get_atto_model_desc - Retrieve ATTO HBA device model name and description * @phba: pointer to lpfc hba data structure. * @mdp: pointer to the data structure to hold the derived model name. * @descp: pointer to the data structure to hold the derived description. * * This routine retrieves HBA's description based on its registered PCI device * ID. The @descp passed into this function points to an array of 256 chars. It * shall be returned with the model name, maximum speed, and the host bus type. * The @mdp passed into this function points to an array of 80 chars. When the * function returns, the @mdp will be filled with the model name. **/ static void lpfc_get_atto_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) { … } /** * lpfc_get_hba_model_desc - Retrieve HBA device model name and description * @phba: pointer to lpfc hba data structure. * @mdp: pointer to the data structure to hold the derived model name. * @descp: pointer to the data structure to hold the derived description. * * This routine retrieves HBA's description based on its registered PCI device * ID. The @descp passed into this function points to an array of 256 chars. It * shall be returned with the model name, maximum speed, and the host bus type. * The @mdp passed into this function points to an array of 80 chars. When the * function returns, the @mdp will be filled with the model name. **/ static void lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) { … } /** * lpfc_sli3_post_buffer - Post IOCB(s) with DMA buffer descriptor(s) to a IOCB ring * @phba: pointer to lpfc hba data structure. * @pring: pointer to a IOCB ring. * @cnt: the number of IOCBs to be posted to the IOCB ring. * * This routine posts a given number of IOCBs with the associated DMA buffer * descriptors specified by the cnt argument to the given IOCB ring. * * Return codes * The number of IOCBs NOT able to be posted to the IOCB ring. **/ int lpfc_sli3_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt) { … } /** * lpfc_post_rcv_buf - Post the initial receive IOCB buffers to ELS ring * @phba: pointer to lpfc hba data structure. * * This routine posts initial receive IOCB buffers to the ELS ring. The * current number of initial IOCB buffers specified by LPFC_BUF_RING0 is * set to 64 IOCBs. SLI3 only. * * Return codes * 0 - success (currently always success) **/ static int lpfc_post_rcv_buf(struct lpfc_hba *phba) { … } #define S(N,V) … /** * lpfc_sha_init - Set up initial array of hash table entries * @HashResultPointer: pointer to an array as hash table. * * This routine sets up the initial values to the array of hash table entries * for the LC HBAs. **/ static void lpfc_sha_init(uint32_t * HashResultPointer) { … } /** * lpfc_sha_iterate - Iterate initial hash table with the working hash table * @HashResultPointer: pointer to an initial/result hash table. * @HashWorkingPointer: pointer to an working hash table. * * This routine iterates an initial hash table pointed by @HashResultPointer * with the values from the working hash table pointeed by @HashWorkingPointer. * The results are putting back to the initial hash table, returned through * the @HashResultPointer as the result hash table. **/ static void lpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer) { … } /** * lpfc_challenge_key - Create challenge key based on WWPN of the HBA * @RandomChallenge: pointer to the entry of host challenge random number array. * @HashWorking: pointer to the entry of the working hash array. * * This routine calculates the working hash array referred by @HashWorking * from the challenge random numbers associated with the host, referred by * @RandomChallenge. The result is put into the entry of the working hash * array and returned by reference through @HashWorking. **/ static void lpfc_challenge_key(uint32_t * RandomChallenge, uint32_t * HashWorking) { … } /** * lpfc_hba_init - Perform special handling for LC HBA initialization * @phba: pointer to lpfc hba data structure. * @hbainit: pointer to an array of unsigned 32-bit integers. * * This routine performs the special handling for LC HBA initialization. **/ void lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) { … } /** * lpfc_cleanup - Performs vport cleanups before deleting a vport * @vport: pointer to a virtual N_Port data structure. * * This routine performs the necessary cleanups before deleting the @vport. * It invokes the discovery state machine to perform necessary state * transitions and to release the ndlps associated with the @vport. Note, * the physical port is treated as @vport 0. **/ void lpfc_cleanup(struct lpfc_vport *vport) { … } /** * lpfc_stop_vport_timers - Stop all the timers associated with a vport * @vport: pointer to a virtual N_Port data structure. * * This routine stops all the timers associated with a @vport. This function * is invoked before disabling or deleting a @vport. Note that the physical * port is treated as @vport 0. **/ void lpfc_stop_vport_timers(struct lpfc_vport *vport) { … } /** * __lpfc_sli4_stop_fcf_redisc_wait_timer - Stop FCF rediscovery wait timer * @phba: pointer to lpfc hba data structure. * * This routine stops the SLI4 FCF rediscover wait timer if it's on. The * caller of this routine should already hold the host lock. **/ void __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) { … } /** * lpfc_sli4_stop_fcf_redisc_wait_timer - Stop FCF rediscovery wait timer * @phba: pointer to lpfc hba data structure. * * This routine stops the SLI4 FCF rediscover wait timer if it's on. It * checks whether the FCF rediscovery wait timer is pending with the host * lock held before proceeding with disabling the timer and clearing the * wait timer pendig flag. **/ void lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) { … } /** * lpfc_cmf_stop - Stop CMF processing * @phba: pointer to lpfc hba data structure. * * This is called when the link goes down or if CMF mode is turned OFF. * It is also called when going offline or unloaded just before the * congestion info buffer is unregistered. **/ void lpfc_cmf_stop(struct lpfc_hba *phba) { … } static inline uint64_t lpfc_get_max_line_rate(struct lpfc_hba *phba) { … } void lpfc_cmf_signal_init(struct lpfc_hba *phba) { … } /** * lpfc_cmf_start - Start CMF processing * @phba: pointer to lpfc hba data structure. * * This is called when the link comes up or if CMF mode is turned OFF * to Monitor or Managed. **/ void lpfc_cmf_start(struct lpfc_hba *phba) { … } /** * lpfc_stop_hba_timers - Stop all the timers associated with an HBA * @phba: pointer to lpfc hba data structure. * * This routine stops all the timers associated with a HBA. This function is * invoked before either putting a HBA offline or unloading the driver. **/ void lpfc_stop_hba_timers(struct lpfc_hba *phba) { … } /** * lpfc_block_mgmt_io - Mark a HBA's management interface as blocked * @phba: pointer to lpfc hba data structure. * @mbx_action: flag for mailbox no wait action. * * This routine marks a HBA's management interface as blocked. Once the HBA's * management interface is marked as blocked, all the user space access to * the HBA, whether they are from sysfs interface or libdfc interface will * all be blocked. The HBA is set to block the management interface when the * driver prepares the HBA interface for online or offline. **/ static void lpfc_block_mgmt_io(struct lpfc_hba *phba, int mbx_action) { … } /** * lpfc_sli4_node_prep - Assign RPIs for active nodes. * @phba: pointer to lpfc hba data structure. * * Allocate RPIs for all active remote nodes. This is needed whenever * an SLI4 adapter is reset and the driver is not unloading. Its purpose * is to fixup the temporary rpi assignments. **/ void lpfc_sli4_node_prep(struct lpfc_hba *phba) { … } /** * lpfc_create_expedite_pool - create expedite pool * @phba: pointer to lpfc hba data structure. * * This routine moves a batch of XRIs from lpfc_io_buf_list_put of HWQ 0 * to expedite pool. Mark them as expedite. **/ static void lpfc_create_expedite_pool(struct lpfc_hba *phba) { … } /** * lpfc_destroy_expedite_pool - destroy expedite pool * @phba: pointer to lpfc hba data structure. * * This routine returns XRIs from expedite pool to lpfc_io_buf_list_put * of HWQ 0. Clear the mark. **/ static void lpfc_destroy_expedite_pool(struct lpfc_hba *phba) { … } /** * lpfc_create_multixri_pools - create multi-XRI pools * @phba: pointer to lpfc hba data structure. * * This routine initialize public, private per HWQ. Then, move XRIs from * lpfc_io_buf_list_put to public pool. High and low watermark are also * Initialized. **/ void lpfc_create_multixri_pools(struct lpfc_hba *phba) { … } /** * lpfc_destroy_multixri_pools - destroy multi-XRI pools * @phba: pointer to lpfc hba data structure. * * This routine returns XRIs from public/private to lpfc_io_buf_list_put. **/ static void lpfc_destroy_multixri_pools(struct lpfc_hba *phba) { … } /** * lpfc_online - Initialize and bring a HBA online * @phba: pointer to lpfc hba data structure. * * This routine initializes the HBA and brings a HBA online. During this * process, the management interface is blocked to prevent user space access * to the HBA interfering with the driver initialization. * * Return codes * 0 - successful * 1 - failed **/ int lpfc_online(struct lpfc_hba *phba) { … } /** * lpfc_unblock_mgmt_io - Mark a HBA's management interface to be not blocked * @phba: pointer to lpfc hba data structure. * * This routine marks a HBA's management interface as not blocked. Once the * HBA's management interface is marked as not blocked, all the user space * access to the HBA, whether they are from sysfs interface or libdfc * interface will be allowed. The HBA is set to block the management interface * when the driver prepares the HBA interface for online or offline and then * set to unblock the management interface afterwards. **/ void lpfc_unblock_mgmt_io(struct lpfc_hba * phba) { … } /** * lpfc_offline_prep - Prepare a HBA to be brought offline * @phba: pointer to lpfc hba data structure. * @mbx_action: flag for mailbox shutdown action. * * This routine is invoked to prepare a HBA to be brought offline. It performs * unregistration login to all the nodes on all vports and flushes the mailbox * queue to make it ready to be brought offline. **/ void lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) { … } /** * lpfc_offline - Bring a HBA offline * @phba: pointer to lpfc hba data structure. * * This routine actually brings a HBA offline. It stops all the timers * associated with the HBA, brings down the SLI layer, and eventually * marks the HBA as in offline state for the upper layer protocol. **/ void lpfc_offline(struct lpfc_hba *phba) { … } /** * lpfc_scsi_free - Free all the SCSI buffers and IOCBs from driver lists * @phba: pointer to lpfc hba data structure. * * This routine is to free all the SCSI buffers and IOCBs from the driver * list back to kernel. It is called from lpfc_pci_remove_one to free * the internal resources before the device is removed from the system. **/ static void lpfc_scsi_free(struct lpfc_hba *phba) { … } /** * lpfc_io_free - Free all the IO buffers and IOCBs from driver lists * @phba: pointer to lpfc hba data structure. * * This routine is to free all the IO buffers and IOCBs from the driver * list back to kernel. It is called from lpfc_pci_remove_one to free * the internal resources before the device is removed from the system. **/ void lpfc_io_free(struct lpfc_hba *phba) { … } /** * lpfc_sli4_els_sgl_update - update ELS xri-sgl sizing and mapping * @phba: pointer to lpfc hba data structure. * * This routine first calculates the sizes of the current els and allocated * scsi sgl lists, and then goes through all sgls to updates the physical * XRIs assigned due to port function reset. During port initialization, the * current els and allocated scsi sgl lists are 0s. * * Return codes * 0 - successful (for now, it always returns 0) **/ int lpfc_sli4_els_sgl_update(struct lpfc_hba *phba) { … } /** * lpfc_sli4_nvmet_sgl_update - update xri-sgl sizing and mapping * @phba: pointer to lpfc hba data structure. * * This routine first calculates the sizes of the current els and allocated * scsi sgl lists, and then goes through all sgls to updates the physical * XRIs assigned due to port function reset. During port initialization, the * current els and allocated scsi sgl lists are 0s. * * Return codes * 0 - successful (for now, it always returns 0) **/ int lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba) { … } int lpfc_io_buf_flush(struct lpfc_hba *phba, struct list_head *cbuf) { … } int lpfc_io_buf_replenish(struct lpfc_hba *phba, struct list_head *cbuf) { … } /** * lpfc_sli4_io_sgl_update - update xri-sgl sizing and mapping * @phba: pointer to lpfc hba data structure. * * This routine first calculates the sizes of the current els and allocated * scsi sgl lists, and then goes through all sgls to updates the physical * XRIs assigned due to port function reset. During port initialization, the * current els and allocated scsi sgl lists are 0s. * * Return codes * 0 - successful (for now, it always returns 0) **/ int lpfc_sli4_io_sgl_update(struct lpfc_hba *phba) { … } /** * lpfc_new_io_buf - IO buffer allocator for HBA with SLI4 IF spec * @phba: Pointer to lpfc hba data structure. * @num_to_alloc: The requested number of buffers to allocate. * * This routine allocates nvme buffers for device with SLI-4 interface spec, * the nvme buffer contains all the necessary information needed to initiate * an I/O. After allocating up to @num_to_allocate IO buffers and put * them on a list, it post them to the port by using SGL block post. * * Return codes: * int - number of IO buffers that were allocated and posted. * 0 = failure, less than num_to_alloc is a partial failure. **/ int lpfc_new_io_buf(struct lpfc_hba *phba, int num_to_alloc) { … } static uint64_t lpfc_get_wwpn(struct lpfc_hba *phba) { … } static unsigned short lpfc_get_sg_tablesize(struct lpfc_hba *phba) { … } /** * lpfc_vmid_res_alloc - Allocates resources for VMID * @phba: pointer to lpfc hba data structure. * @vport: pointer to vport data structure * * This routine allocated the resources needed for the VMID. * * Return codes * 0 on Success * Non-0 on Failure */ static int lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport) { … } /** * lpfc_create_port - Create an FC port * @phba: pointer to lpfc hba data structure. * @instance: a unique integer ID to this FC port. * @dev: pointer to the device data structure. * * This routine creates a FC port for the upper layer protocol. The FC port * can be created on top of either a physical port or a virtual port provided * by the HBA. This routine also allocates a SCSI host data structure (shost) * and associates the FC port created before adding the shost into the SCSI * layer. * * Return codes * @vport - pointer to the virtual N_Port data structure. * NULL - port create failed. **/ struct lpfc_vport * lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) { … } /** * destroy_port - destroy an FC port * @vport: pointer to an lpfc virtual N_Port data structure. * * This routine destroys a FC port from the upper layer protocol. All the * resources associated with the port are released. **/ void destroy_port(struct lpfc_vport *vport) { … } /** * lpfc_get_instance - Get a unique integer ID * * This routine allocates a unique integer ID from lpfc_hba_index pool. It * uses the kernel idr facility to perform the task. * * Return codes: * instance - a unique integer ID allocated as the new instance. * -1 - lpfc get instance failed. **/ int lpfc_get_instance(void) { … } /** * lpfc_scan_finished - method for SCSI layer to detect whether scan is done * @shost: pointer to SCSI host data structure. * @time: elapsed time of the scan in jiffies. * * This routine is called by the SCSI layer with a SCSI host to determine * whether the scan host is finished. * * Note: there is no scan_start function as adapter initialization will have * asynchronously kicked off the link initialization. * * Return codes * 0 - SCSI host scan is not over yet. * 1 - SCSI host scan is over. **/ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) { … } static void lpfc_host_supported_speeds_set(struct Scsi_Host *shost) { … } /** * lpfc_host_attrib_init - Initialize SCSI host attributes on a FC port * @shost: pointer to SCSI host data structure. * * This routine initializes a given SCSI host attributes on a FC port. The * SCSI host can be either on top of a physical port or a virtual port. **/ void lpfc_host_attrib_init(struct Scsi_Host *shost) { … } /** * lpfc_stop_port_s3 - Stop SLI3 device port * @phba: pointer to lpfc hba data structure. * * This routine is invoked to stop an SLI3 device port, it stops the device * from generating interrupts and stops the device driver's timers for the * device. **/ static void lpfc_stop_port_s3(struct lpfc_hba *phba) { … } /** * lpfc_stop_port_s4 - Stop SLI4 device port * @phba: pointer to lpfc hba data structure. * * This routine is invoked to stop an SLI4 device port, it stops the device * from generating interrupts and stops the device driver's timers for the * device. **/ static void lpfc_stop_port_s4(struct lpfc_hba *phba) { … } /** * lpfc_stop_port - Wrapper function for stopping hba port * @phba: Pointer to HBA context object. * * This routine wraps the actual SLI3 or SLI4 hba stop port routine from * the API jump table function pointer from the lpfc_hba struct. **/ void lpfc_stop_port(struct lpfc_hba *phba) { … } /** * lpfc_fcf_redisc_wait_start_timer - Start fcf rediscover wait timer * @phba: Pointer to hba for which this call is being executed. * * This routine starts the timer waiting for the FCF rediscovery to complete. **/ void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *phba) { … } /** * lpfc_sli4_fcf_redisc_wait_tmo - FCF table rediscover wait timeout * @t: Timer context used to obtain the pointer to lpfc hba data structure. * * This routine is invoked when waiting for FCF table rediscover has been * timed out. If new FCF record(s) has (have) been discovered during the * wait period, a new FCF event shall be added to the FCOE async event * list, and then worker thread shall be waked up for processing from the * worker thread context. **/ static void lpfc_sli4_fcf_redisc_wait_tmo(struct timer_list *t) { … } /** * lpfc_vmid_poll - VMID timeout detection * @t: Timer context used to obtain the pointer to lpfc hba data structure. * * This routine is invoked when there is no I/O on by a VM for the specified * amount of time. When this situation is detected, the VMID has to be * deregistered from the switch and all the local resources freed. The VMID * will be reassigned to the VM once the I/O begins. **/ static void lpfc_vmid_poll(struct timer_list *t) { … } /** * lpfc_sli4_parse_latt_fault - Parse sli4 link-attention link fault code * @phba: pointer to lpfc hba data structure. * @acqe_link: pointer to the async link completion queue entry. * * This routine is to parse the SLI4 link-attention link fault code. **/ static void lpfc_sli4_parse_latt_fault(struct lpfc_hba *phba, struct lpfc_acqe_link *acqe_link) { … } /** * lpfc_sli4_parse_latt_type - Parse sli4 link attention type * @phba: pointer to lpfc hba data structure. * @acqe_link: pointer to the async link completion queue entry. * * This routine is to parse the SLI4 link attention type and translate it * into the base driver's link attention type coding. * * Return: Link attention type in terms of base driver's coding. **/ static uint8_t lpfc_sli4_parse_latt_type(struct lpfc_hba *phba, struct lpfc_acqe_link *acqe_link) { … } /** * lpfc_sli_port_speed_get - Get sli3 link speed code to link speed * @phba: pointer to lpfc hba data structure. * * This routine is to get an SLI3 FC port's link speed in Mbps. * * Return: link speed in terms of Mbps. **/ uint32_t lpfc_sli_port_speed_get(struct lpfc_hba *phba) { … } /** * lpfc_sli4_port_speed_parse - Parse async evt link speed code to link speed * @phba: pointer to lpfc hba data structure. * @evt_code: asynchronous event code. * @speed_code: asynchronous event link speed code. * * This routine is to parse the giving SLI4 async event link speed code into * value of Mbps for the link speed. * * Return: link speed in terms of Mbps. **/ static uint32_t lpfc_sli4_port_speed_parse(struct lpfc_hba *phba, uint32_t evt_code, uint8_t speed_code) { … } /** * lpfc_sli4_async_link_evt - Process the asynchronous FCoE link event * @phba: pointer to lpfc hba data structure. * @acqe_link: pointer to the async link completion queue entry. * * This routine is to handle the SLI4 asynchronous FCoE link event. **/ static void lpfc_sli4_async_link_evt(struct lpfc_hba *phba, struct lpfc_acqe_link *acqe_link) { … } /** * lpfc_async_link_speed_to_read_top - Parse async evt link speed code to read * topology. * @phba: pointer to lpfc hba data structure. * @speed_code: asynchronous event link speed code. * * This routine is to parse the giving SLI4 async event link speed code into * value of Read topology link speed. * * Return: link speed in terms of Read topology. **/ static uint8_t lpfc_async_link_speed_to_read_top(struct lpfc_hba *phba, uint8_t speed_code) { … } void lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba) { … } /** * lpfc_cgn_update_stat - Save data into congestion stats buffer * @phba: pointer to lpfc hba data structure. * @dtag: FPIN descriptor received * * Increment the FPIN received counter/time when it happens. */ void lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag) { … } /** * lpfc_cgn_update_tstamp - Update cmf timestamp * @phba: pointer to lpfc hba data structure. * @ts: structure to write the timestamp to. */ void lpfc_cgn_update_tstamp(struct lpfc_hba *phba, struct lpfc_cgn_ts *ts) { … } /** * lpfc_cmf_stats_timer - Save data into registered congestion buffer * @timer: Timer cookie to access lpfc private data * * Save the congestion event data every minute. * On the hour collapse all the minute data into hour data. Every day * collapse all the hour data into daily data. Separate driver * and fabrc congestion event counters that will be saved out * to the registered congestion buffer every minute. */ static enum hrtimer_restart lpfc_cmf_stats_timer(struct hrtimer *timer) { … } /** * lpfc_calc_cmf_latency - latency from start of rxate timer interval * @phba: The Hba for which this call is being executed. * * The routine calculates the latency from the beginning of the CMF timer * interval to the current point in time. It is called from IO completion * when we exceed our Bandwidth limitation for the time interval. */ uint32_t lpfc_calc_cmf_latency(struct lpfc_hba *phba) { … } /** * lpfc_cmf_timer - This is the timer function for one congestion * rate interval. * @timer: Pointer to the high resolution timer that expired */ static enum hrtimer_restart lpfc_cmf_timer(struct hrtimer *timer) { … } #define trunk_link_status(__idx) … /* Did port __idx reported an error */ #define trunk_port_fault(__idx) … static void lpfc_update_trunk_link_status(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) { … } /** * lpfc_sli4_async_fc_evt - Process the asynchronous FC link event * @phba: pointer to lpfc hba data structure. * @acqe_fc: pointer to the async fc completion queue entry. * * This routine is to handle the SLI4 asynchronous FC event. It will simply log * that the event was received and then issue a read_topology mailbox command so * that the rest of the driver will treat it the same as SLI3. **/ static void lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) { … } /** * lpfc_sli4_async_sli_evt - Process the asynchronous SLI link event * @phba: pointer to lpfc hba data structure. * @acqe_sli: pointer to the async SLI completion queue entry. * * This routine is to handle the SLI4 asynchronous SLI events. **/ static void lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) { … } /** * lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport * @vport: pointer to vport data structure. * * This routine is to perform Clear Virtual Link (CVL) on a vport in * response to a CVL event. * * Return the pointer to the ndlp with the vport if successful, otherwise * return NULL. **/ static struct lpfc_nodelist * lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport) { … } /** * lpfc_sli4_perform_all_vport_cvl - Perform clear virtual link on all vports * @phba: pointer to lpfc hba data structure. * * This routine is to perform Clear Virtual Link (CVL) on all vports in * response to a FCF dead event. **/ static void lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba) { … } /** * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event * @phba: pointer to lpfc hba data structure. * @acqe_fip: pointer to the async fcoe completion queue entry. * * This routine is to handle the SLI4 asynchronous fcoe event. **/ static void lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, struct lpfc_acqe_fip *acqe_fip) { … } /** * lpfc_sli4_async_dcbx_evt - Process the asynchronous dcbx event * @phba: pointer to lpfc hba data structure. * @acqe_dcbx: pointer to the async dcbx completion queue entry. * * This routine is to handle the SLI4 asynchronous dcbx event. **/ static void lpfc_sli4_async_dcbx_evt(struct lpfc_hba *phba, struct lpfc_acqe_dcbx *acqe_dcbx) { … } /** * lpfc_sli4_async_grp5_evt - Process the asynchronous group5 event * @phba: pointer to lpfc hba data structure. * @acqe_grp5: pointer to the async grp5 completion queue entry. * * This routine is to handle the SLI4 asynchronous grp5 event. A grp5 event * is an asynchronous notified of a logical link speed change. The Port * reports the logical link speed in units of 10Mbps. **/ static void lpfc_sli4_async_grp5_evt(struct lpfc_hba *phba, struct lpfc_acqe_grp5 *acqe_grp5) { … } /** * lpfc_sli4_async_cmstat_evt - Process the asynchronous cmstat event * @phba: pointer to lpfc hba data structure. * * This routine is to handle the SLI4 asynchronous cmstat event. A cmstat event * is an asynchronous notification of a request to reset CM stats. **/ static void lpfc_sli4_async_cmstat_evt(struct lpfc_hba *phba) { … } /** * lpfc_cgn_params_val - Validate FW congestion parameters. * @phba: pointer to lpfc hba data structure. * @p_cfg_param: pointer to FW provided congestion parameters. * * This routine validates the congestion parameters passed * by the FW to the driver via an ACQE event. **/ static void lpfc_cgn_params_val(struct lpfc_hba *phba, struct lpfc_cgn_param *p_cfg_param) { … } static const char * const lpfc_cmf_mode_to_str[] = …; /** * lpfc_cgn_params_parse - Process a FW cong parm change event * @phba: pointer to lpfc hba data structure. * @p_cgn_param: pointer to a data buffer with the FW cong params. * @len: the size of pdata in bytes. * * This routine validates the congestion management buffer signature * from the FW, validates the contents and makes corrections for * valid, in-range values. If the signature magic is correct and * after parameter validation, the contents are copied to the driver's * @phba structure. If the magic is incorrect, an error message is * logged. **/ static void lpfc_cgn_params_parse(struct lpfc_hba *phba, struct lpfc_cgn_param *p_cgn_param, uint32_t len) { … } /** * lpfc_sli4_cgn_params_read - Read and Validate FW congestion parameters. * @phba: pointer to lpfc hba data structure. * * This routine issues a read_object mailbox command to * get the congestion management parameters from the FW * parses it and updates the driver maintained values. * * Returns * 0 if the object was empty * -Eval if an error was encountered * Count if bytes were read from object **/ int lpfc_sli4_cgn_params_read(struct lpfc_hba *phba) { … } /** * lpfc_sli4_cgn_parm_chg_evt - Process a FW congestion param change event * @phba: pointer to lpfc hba data structure. * * The FW generated Async ACQE SLI event calls this routine when * the event type is an SLI Internal Port Event and the Event Code * indicates a change to the FW maintained congestion parameters. * * This routine executes a Read_Object mailbox call to obtain the * current congestion parameters maintained in FW and corrects * the driver's active congestion parameters. * * The acqe event is not passed because there is no further data * required. * * Returns nonzero error if event processing encountered an error. * Zero otherwise for success. **/ static int lpfc_sli4_cgn_parm_chg_evt(struct lpfc_hba *phba) { … } /** * lpfc_sli4_async_event_proc - Process all the pending asynchronous event * @phba: pointer to lpfc hba data structure. * * This routine is invoked by the worker thread to process all the pending * SLI4 asynchronous events. **/ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba) { … } /** * lpfc_sli4_fcf_redisc_event_proc - Process fcf table rediscovery event * @phba: pointer to lpfc hba data structure. * * This routine is invoked by the worker thread to process FCF table * rediscovery pending completion event. **/ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba) { … } /** * lpfc_api_table_setup - Set up per hba pci-device group func api jump table * @phba: pointer to lpfc hba data structure. * @dev_grp: The HBA PCI-Device group number. * * This routine is invoked to set up the per HBA PCI-Device group function * API jump table entries. * * Return: 0 if success, otherwise -ENODEV **/ int lpfc_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) { … } /** * lpfc_log_intr_mode - Log the active interrupt mode * @phba: pointer to lpfc hba data structure. * @intr_mode: active interrupt mode adopted. * * This routine it invoked to log the currently used active interrupt mode * to the device. **/ static void lpfc_log_intr_mode(struct lpfc_hba *phba, uint32_t intr_mode) { … } /** * lpfc_enable_pci_dev - Enable a generic PCI device. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to enable the PCI device that is common to all * PCI devices. * * Return codes * 0 - successful * other values - error **/ static int lpfc_enable_pci_dev(struct lpfc_hba *phba) { … } /** * lpfc_disable_pci_dev - Disable a generic PCI device. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to disable the PCI device that is common to all * PCI devices. **/ static void lpfc_disable_pci_dev(struct lpfc_hba *phba) { … } /** * lpfc_reset_hba - Reset a hba * @phba: pointer to lpfc hba data structure. * * This routine is invoked to reset a hba device. It brings the HBA * offline, performs a board restart, and then brings the board back * online. The lpfc_offline calls lpfc_sli_hba_down which will clean up * on outstanding mailbox commands. **/ void lpfc_reset_hba(struct lpfc_hba *phba) { … } /** * lpfc_sli_sriov_nr_virtfn_get - Get the number of sr-iov virtual functions * @phba: pointer to lpfc hba data structure. * * This function enables the PCI SR-IOV virtual functions to a physical * function. It invokes the PCI SR-IOV api with the @nr_vfn provided to * enable the number of virtual functions to the physical function. As * not all devices support SR-IOV, the return code from the pci_enable_sriov() * API call does not considered as an error condition for most of the device. **/ uint16_t lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *phba) { … } /** * lpfc_sli_probe_sriov_nr_virtfn - Enable a number of sr-iov virtual functions * @phba: pointer to lpfc hba data structure. * @nr_vfn: number of virtual functions to be enabled. * * This function enables the PCI SR-IOV virtual functions to a physical * function. It invokes the PCI SR-IOV api with the @nr_vfn provided to * enable the number of virtual functions to the physical function. As * not all devices support SR-IOV, the return code from the pci_enable_sriov() * API call does not considered as an error condition for most of the device. **/ int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *phba, int nr_vfn) { … } static void lpfc_unblock_requests_work(struct work_struct *work) { … } /** * lpfc_setup_driver_resource_phase1 - Phase1 etup driver internal resources. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to set up the driver internal resources before the * device specific resource setup to support the HBA device it attached to. * * Return codes * 0 - successful * other values - error **/ static int lpfc_setup_driver_resource_phase1(struct lpfc_hba *phba) { … } /** * lpfc_sli_driver_resource_setup - Setup driver internal resources for SLI3 dev * @phba: pointer to lpfc hba data structure. * * This routine is invoked to set up the driver internal resources specific to * support the SLI-3 HBA device it attached to. * * Return codes * 0 - successful * other values - error **/ static int lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) { … } /** * lpfc_sli_driver_resource_unset - Unset drvr internal resources for SLI3 dev * @phba: pointer to lpfc hba data structure. * * This routine is invoked to unset the driver internal resources set up * specific for supporting the SLI-3 HBA device it attached to. **/ static void lpfc_sli_driver_resource_unset(struct lpfc_hba *phba) { … } /** * lpfc_sli4_driver_resource_setup - Setup drvr internal resources for SLI4 dev * @phba: pointer to lpfc hba data structure. * * This routine is invoked to set up the driver internal resources specific to * support the SLI-4 HBA device it attached to. * * Return codes * 0 - successful * other values - error **/ static int lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) { … } /** * lpfc_sli4_driver_resource_unset - Unset drvr internal resources for SLI4 dev * @phba: pointer to lpfc hba data structure. * * This routine is invoked to unset the driver internal resources set up * specific for supporting the SLI-4 HBA device it attached to. **/ static void lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba) { … } /** * lpfc_init_api_table_setup - Set up init api function jump table * @phba: The hba struct for which this call is being executed. * @dev_grp: The HBA PCI-Device group number. * * This routine sets up the device INIT interface API function jump table * in @phba struct. * * Returns: 0 - success, -ENODEV - failure. **/ int lpfc_init_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) { … } /** * lpfc_setup_driver_resource_phase2 - Phase2 setup driver internal resources. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to set up the driver internal resources after the * device specific resource setup to support the HBA device it attached to. * * Return codes * 0 - successful * other values - error **/ static int lpfc_setup_driver_resource_phase2(struct lpfc_hba *phba) { … } /** * lpfc_unset_driver_resource_phase2 - Phase2 unset driver internal resources. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to unset the driver internal resources set up after * the device specific resource setup for supporting the HBA device it * attached to. **/ static void lpfc_unset_driver_resource_phase2(struct lpfc_hba *phba) { … } /** * lpfc_free_iocb_list - Free iocb list. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to free the driver's IOCB list and memory. **/ void lpfc_free_iocb_list(struct lpfc_hba *phba) { … } /** * lpfc_init_iocb_list - Allocate and initialize iocb list. * @phba: pointer to lpfc hba data structure. * @iocb_count: number of requested iocbs * * This routine is invoked to allocate and initizlize the driver's IOCB * list and set up the IOCB tag array accordingly. * * Return codes * 0 - successful * other values - error **/ int lpfc_init_iocb_list(struct lpfc_hba *phba, int iocb_count) { … } /** * lpfc_free_sgl_list - Free a given sgl list. * @phba: pointer to lpfc hba data structure. * @sglq_list: pointer to the head of sgl list. * * This routine is invoked to free a give sgl list and memory. **/ void lpfc_free_sgl_list(struct lpfc_hba *phba, struct list_head *sglq_list) { … } /** * lpfc_free_els_sgl_list - Free els sgl list. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to free the driver's els sgl list and memory. **/ static void lpfc_free_els_sgl_list(struct lpfc_hba *phba) { … } /** * lpfc_free_nvmet_sgl_list - Free nvmet sgl list. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to free the driver's nvmet sgl list and memory. **/ static void lpfc_free_nvmet_sgl_list(struct lpfc_hba *phba) { … } /** * lpfc_init_active_sgl_array - Allocate the buf to track active ELS XRIs. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to allocate the driver's active sgl memory. * This array will hold the sglq_entry's for active IOs. **/ static int lpfc_init_active_sgl_array(struct lpfc_hba *phba) { … } /** * lpfc_free_active_sgl - Free the buf that tracks active ELS XRIs. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to walk through the array of active sglq entries * and free all of the resources. * This is just a place holder for now. **/ static void lpfc_free_active_sgl(struct lpfc_hba *phba) { … } /** * lpfc_init_sgl_list - Allocate and initialize sgl list. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to allocate and initizlize the driver's sgl * list and set up the sgl xritag tag array accordingly. * **/ static void lpfc_init_sgl_list(struct lpfc_hba *phba) { … } /** * lpfc_sli4_init_rpi_hdrs - Post the rpi header memory region to the port * @phba: pointer to lpfc hba data structure. * * This routine is invoked to post rpi header templates to the * port for those SLI4 ports that do not support extents. This routine * posts a PAGE_SIZE memory region to the port to hold up to * PAGE_SIZE modulo 64 rpi context headers. This is an initialization routine * and should be called only when interrupts are disabled. * * Return codes * 0 - successful * -ERROR - otherwise. **/ int lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba) { … } /** * lpfc_sli4_create_rpi_hdr - Allocate an rpi header memory region * @phba: pointer to lpfc hba data structure. * * This routine is invoked to allocate a single 4KB memory region to * support rpis and stores them in the phba. This single region * provides support for up to 64 rpis. The region is used globally * by the device. * * Returns: * A valid rpi hdr on success. * A NULL pointer on any failure. **/ struct lpfc_rpi_hdr * lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) { … } /** * lpfc_sli4_remove_rpi_hdrs - Remove all rpi header memory regions * @phba: pointer to lpfc hba data structure. * * This routine is invoked to remove all memory resources allocated * to support rpis for SLI4 ports not supporting extents. This routine * presumes the caller has released all rpis consumed by fabric or port * logins and is prepared to have the header pages removed. **/ void lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba) { … } /** * lpfc_hba_alloc - Allocate driver hba data structure for a device. * @pdev: pointer to pci device data structure. * * This routine is invoked to allocate the driver hba data structure for an * HBA device. If the allocation is successful, the phba reference to the * PCI device data structure is set. * * Return codes * pointer to @phba - successful * NULL - error **/ static struct lpfc_hba * lpfc_hba_alloc(struct pci_dev *pdev) { … } /** * lpfc_hba_free - Free driver hba data structure with a device. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to free the driver hba data structure with an * HBA device. **/ static void lpfc_hba_free(struct lpfc_hba *phba) { … } /** * lpfc_setup_fdmi_mask - Setup initial FDMI mask for HBA and Port attributes * @vport: pointer to lpfc vport data structure. * * This routine is will setup initial FDMI attribute masks for * FDMI2 or SmartSAN depending on module parameters. The driver will attempt * to get these attributes first before falling back, the attribute * fallback hierarchy is SmartSAN -> FDMI2 -> FMDI1 **/ void lpfc_setup_fdmi_mask(struct lpfc_vport *vport) { … } /** * lpfc_create_shost - Create hba physical port with associated scsi host. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to create HBA physical port and associate a SCSI * host with it. * * Return codes * 0 - successful * other values - error **/ static int lpfc_create_shost(struct lpfc_hba *phba) { … } /** * lpfc_destroy_shost - Destroy hba physical port with associated scsi host. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to destroy HBA physical port and the associated * SCSI host. **/ static void lpfc_destroy_shost(struct lpfc_hba *phba) { … } /** * lpfc_setup_bg - Setup Block guard structures and debug areas. * @phba: pointer to lpfc hba data structure. * @shost: the shost to be used to detect Block guard settings. * * This routine sets up the local Block guard protocol settings for @shost. * This routine also allocates memory for debugging bg buffers. **/ static void lpfc_setup_bg(struct lpfc_hba *phba, struct Scsi_Host *shost) { … } /** * lpfc_post_init_setup - Perform necessary device post initialization setup. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to perform all the necessary post initialization * setup for the device. **/ static void lpfc_post_init_setup(struct lpfc_hba *phba) { … } /** * lpfc_sli_pci_mem_setup - Setup SLI3 HBA PCI memory space. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to set up the PCI device memory space for device * with SLI-3 interface spec. * * Return codes * 0 - successful * other values - error **/ static int lpfc_sli_pci_mem_setup(struct lpfc_hba *phba) { … } /** * lpfc_sli_pci_mem_unset - Unset SLI3 HBA PCI memory space. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to unset the PCI device memory space for device * with SLI-3 interface spec. **/ static void lpfc_sli_pci_mem_unset(struct lpfc_hba *phba) { … } /** * lpfc_sli4_post_status_check - Wait for SLI4 POST done and check status * @phba: pointer to lpfc hba data structure. * * This routine is invoked to wait for SLI4 device Power On Self Test (POST) * done and check status. * * Return 0 if successful, otherwise -ENODEV. **/ int lpfc_sli4_post_status_check(struct lpfc_hba *phba) { … } /** * lpfc_sli4_bar0_register_memmap - Set up SLI4 BAR0 register memory map. * @phba: pointer to lpfc hba data structure. * @if_type: The SLI4 interface type getting configured. * * This routine is invoked to set up SLI4 BAR0 PCI config space register * memory map. **/ static void lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type) { … } /** * lpfc_sli4_bar1_register_memmap - Set up SLI4 BAR1 register memory map. * @phba: pointer to lpfc hba data structure. * @if_type: sli if type to operate on. * * This routine is invoked to set up SLI4 BAR1 register memory map. **/ static void lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba, uint32_t if_type) { … } /** * lpfc_sli4_bar2_register_memmap - Set up SLI4 BAR2 register memory map. * @phba: pointer to lpfc hba data structure. * @vf: virtual function number * * This routine is invoked to set up SLI4 BAR2 doorbell register memory map * based on the given viftual function number, @vf. * * Return 0 if successful, otherwise -ENODEV. **/ static int lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, uint32_t vf) { … } /** * lpfc_create_bootstrap_mbox - Create the bootstrap mailbox * @phba: pointer to lpfc hba data structure. * * This routine is invoked to create the bootstrap mailbox * region consistent with the SLI-4 interface spec. This * routine allocates all memory necessary to communicate * mailbox commands to the port and sets up all alignment * needs. No locks are expected to be held when calling * this routine. * * Return codes * 0 - successful * -ENOMEM - could not allocated memory. **/ static int lpfc_create_bootstrap_mbox(struct lpfc_hba *phba) { … } /** * lpfc_destroy_bootstrap_mbox - Destroy all bootstrap mailbox resources * @phba: pointer to lpfc hba data structure. * * This routine is invoked to teardown the bootstrap mailbox * region and release all host resources. This routine requires * the caller to ensure all mailbox commands recovered, no * additional mailbox comands are sent, and interrupts are disabled * before calling this routine. * **/ static void lpfc_destroy_bootstrap_mbox(struct lpfc_hba *phba) { … } static const char * const lpfc_topo_to_str[] = …; #define LINK_FLAGS_DEF … #define LINK_FLAGS_P2P … #define LINK_FLAGS_LOOP … /** * lpfc_map_topology - Map the topology read from READ_CONFIG * @phba: pointer to lpfc hba data structure. * @rd_config: pointer to read config data * * This routine is invoked to map the topology values as read * from the read config mailbox command. If the persistent * topology feature is supported, the firmware will provide the * saved topology information to be used in INIT_LINK **/ static void lpfc_map_topology(struct lpfc_hba *phba, struct lpfc_mbx_read_config *rd_config) { … } /** * lpfc_sli4_read_config - Get the config parameters. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to read the configuration parameters from the HBA. * The configuration parameters are used to set the base and maximum values * for RPI's XRI's VPI's VFI's and FCFIs. These values also affect the resource * allocation for the port. * * Return codes * 0 - successful * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ int lpfc_sli4_read_config(struct lpfc_hba *phba) { … } /** * lpfc_setup_endian_order - Write endian order to an SLI4 if_type 0 port. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to setup the port-side endian order when * the port if_type is 0. This routine has no function for other * if_types. * * Return codes * 0 - successful * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ static int lpfc_setup_endian_order(struct lpfc_hba *phba) { … } /** * lpfc_sli4_queue_verify - Verify and update EQ counts * @phba: pointer to lpfc hba data structure. * * This routine is invoked to check the user settable queue counts for EQs. * After this routine is called the counts will be set to valid values that * adhere to the constraints of the system's interrupt vectors and the port's * queue resources. * * Return codes * 0 - successful * -ENOMEM - No available memory **/ static int lpfc_sli4_queue_verify(struct lpfc_hba *phba) { … } static int lpfc_alloc_io_wq_cq(struct lpfc_hba *phba, int idx) { … } /** * lpfc_sli4_queue_create - Create all the SLI4 queues * @phba: pointer to lpfc hba data structure. * * This routine is invoked to allocate all the SLI4 queues for the FCoE HBA * operation. For each SLI4 queue type, the parameters such as queue entry * count (queue depth) shall be taken from the module parameter. For now, * we just use some constant number as place holder. * * Return codes * 0 - successful * -ENOMEM - No availble memory * -EIO - The mailbox failed to complete successfully. **/ int lpfc_sli4_queue_create(struct lpfc_hba *phba) { … } static inline void __lpfc_sli4_release_queue(struct lpfc_queue **qp) { … } static inline void lpfc_sli4_release_queues(struct lpfc_queue ***qs, int max) { … } static inline void lpfc_sli4_release_hdwq(struct lpfc_hba *phba) { … } /** * lpfc_sli4_queue_destroy - Destroy all the SLI4 queues * @phba: pointer to lpfc hba data structure. * * This routine is invoked to release all the SLI4 queues with the FCoE HBA * operation. * * Return codes * 0 - successful * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ void lpfc_sli4_queue_destroy(struct lpfc_hba *phba) { … } int lpfc_free_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *rq) { … } static int lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq, struct lpfc_queue *cq, struct lpfc_queue *wq, uint16_t *cq_map, int qidx, uint32_t qtype) { … } /** * lpfc_setup_cq_lookup - Setup the CQ lookup table * @phba: pointer to lpfc hba data structure. * * This routine will populate the cq_lookup table by all * available CQ queue_id's. **/ static void lpfc_setup_cq_lookup(struct lpfc_hba *phba) { … } /** * lpfc_sli4_queue_setup - Set up all the SLI4 queues * @phba: pointer to lpfc hba data structure. * * This routine is invoked to set up all the SLI4 queues for the FCoE HBA * operation. * * Return codes * 0 - successful * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ int lpfc_sli4_queue_setup(struct lpfc_hba *phba) { … } /** * lpfc_sli4_queue_unset - Unset all the SLI4 queues * @phba: pointer to lpfc hba data structure. * * This routine is invoked to unset all the SLI4 queues with the FCoE HBA * operation. * * Return codes * 0 - successful * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ void lpfc_sli4_queue_unset(struct lpfc_hba *phba) { … } /** * lpfc_sli4_cq_event_pool_create - Create completion-queue event free pool * @phba: pointer to lpfc hba data structure. * * This routine is invoked to allocate and set up a pool of completion queue * events. The body of the completion queue event is a completion queue entry * CQE. For now, this pool is used for the interrupt service routine to queue * the following HBA completion queue events for the worker thread to process: * - Mailbox asynchronous events * - Receive queue completion unsolicited events * Later, this can be used for all the slow-path events. * * Return codes * 0 - successful * -ENOMEM - No available memory **/ static int lpfc_sli4_cq_event_pool_create(struct lpfc_hba *phba) { … } /** * lpfc_sli4_cq_event_pool_destroy - Free completion-queue event free pool * @phba: pointer to lpfc hba data structure. * * This routine is invoked to free the pool of completion queue events at * driver unload time. Note that, it is the responsibility of the driver * cleanup routine to free all the outstanding completion-queue events * allocated from this pool back into the pool before invoking this routine * to destroy the pool. **/ static void lpfc_sli4_cq_event_pool_destroy(struct lpfc_hba *phba) { … } /** * __lpfc_sli4_cq_event_alloc - Allocate a completion-queue event from free pool * @phba: pointer to lpfc hba data structure. * * This routine is the lock free version of the API invoked to allocate a * completion-queue event from the free pool. * * Return: Pointer to the newly allocated completion-queue event if successful * NULL otherwise. **/ struct lpfc_cq_event * __lpfc_sli4_cq_event_alloc(struct lpfc_hba *phba) { … } /** * lpfc_sli4_cq_event_alloc - Allocate a completion-queue event from free pool * @phba: pointer to lpfc hba data structure. * * This routine is the lock version of the API invoked to allocate a * completion-queue event from the free pool. * * Return: Pointer to the newly allocated completion-queue event if successful * NULL otherwise. **/ struct lpfc_cq_event * lpfc_sli4_cq_event_alloc(struct lpfc_hba *phba) { … } /** * __lpfc_sli4_cq_event_release - Release a completion-queue event to free pool * @phba: pointer to lpfc hba data structure. * @cq_event: pointer to the completion queue event to be freed. * * This routine is the lock free version of the API invoked to release a * completion-queue event back into the free pool. **/ void __lpfc_sli4_cq_event_release(struct lpfc_hba *phba, struct lpfc_cq_event *cq_event) { … } /** * lpfc_sli4_cq_event_release - Release a completion-queue event to free pool * @phba: pointer to lpfc hba data structure. * @cq_event: pointer to the completion queue event to be freed. * * This routine is the lock version of the API invoked to release a * completion-queue event back into the free pool. **/ void lpfc_sli4_cq_event_release(struct lpfc_hba *phba, struct lpfc_cq_event *cq_event) { … } /** * lpfc_sli4_cq_event_release_all - Release all cq events to the free pool * @phba: pointer to lpfc hba data structure. * * This routine is to free all the pending completion-queue events to the * back into the free pool for device reset. **/ static void lpfc_sli4_cq_event_release_all(struct lpfc_hba *phba) { … } /** * lpfc_pci_function_reset - Reset pci function. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to request a PCI function reset. It will destroys * all resources assigned to the PCI function which originates this request. * * Return codes * 0 - successful * -ENOMEM - No available memory * -EIO - The mailbox failed to complete successfully. **/ int lpfc_pci_function_reset(struct lpfc_hba *phba) { … } /** * lpfc_sli4_pci_mem_setup - Setup SLI4 HBA PCI memory space. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to set up the PCI device memory space for device * with SLI-4 interface spec. * * Return codes * 0 - successful * other values - error **/ static int lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) { … } /** * lpfc_sli4_pci_mem_unset - Unset SLI4 HBA PCI memory space. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to unset the PCI device memory space for device * with SLI-4 interface spec. **/ static void lpfc_sli4_pci_mem_unset(struct lpfc_hba *phba) { … } /** * lpfc_sli_enable_msix - Enable MSI-X interrupt mode on SLI-3 device * @phba: pointer to lpfc hba data structure. * * This routine is invoked to enable the MSI-X interrupt vectors to device * with SLI-3 interface specs. * * Return codes * 0 - successful * other values - error **/ static int lpfc_sli_enable_msix(struct lpfc_hba *phba) { … } /** * lpfc_sli_enable_msi - Enable MSI interrupt mode on SLI-3 device. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to enable the MSI interrupt mode to device with * SLI-3 interface spec. The kernel function pci_enable_msi() is called to * enable the MSI vector. The device driver is responsible for calling the * request_irq() to register MSI vector with a interrupt the handler, which * is done in this function. * * Return codes * 0 - successful * other values - error */ static int lpfc_sli_enable_msi(struct lpfc_hba *phba) { … } /** * lpfc_sli_enable_intr - Enable device interrupt to SLI-3 device. * @phba: pointer to lpfc hba data structure. * @cfg_mode: Interrupt configuration mode (INTx, MSI or MSI-X). * * This routine is invoked to enable device interrupt and associate driver's * interrupt handler(s) to interrupt vector(s) to device with SLI-3 interface * spec. Depends on the interrupt mode configured to the driver, the driver * will try to fallback from the configured interrupt mode to an interrupt * mode which is supported by the platform, kernel, and device in the order * of: * MSI-X -> MSI -> IRQ. * * Return codes * 0 - successful * other values - error **/ static uint32_t lpfc_sli_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) { … } /** * lpfc_sli_disable_intr - Disable device interrupt to SLI-3 device. * @phba: pointer to lpfc hba data structure. * * This routine is invoked to disable device interrupt and disassociate the * driver's interrupt handler(s) from interrupt vector(s) to device with * SLI-3 interface spec. Depending on the interrupt mode, the driver will * release the interrupt vector(s) for the message signaled interrupt. **/ static void lpfc_sli_disable_intr(struct lpfc_hba *phba) { … } /** * lpfc_find_cpu_handle - Find the CPU that corresponds to the specified Queue * @phba: pointer to lpfc hba data structure. * @id: EQ vector index or Hardware Queue index * @match: LPFC_FIND_BY_EQ = match by EQ * LPFC_FIND_BY_HDWQ = match by Hardware Queue * Return the CPU that matches the selection criteria */ static uint16_t lpfc_find_cpu_handle(struct lpfc_hba *phba, uint16_t id, int match) { … } #ifdef CONFIG_X86 /** * lpfc_find_hyper - Determine if the CPU map entry is hyper-threaded * @phba: pointer to lpfc hba data structure. * @cpu: CPU map index * @phys_id: CPU package physical id * @core_id: CPU core id */ static int lpfc_find_hyper(struct lpfc_hba *phba, int cpu, uint16_t phys_id, uint16_t core_id) { … } #endif /* * lpfc_assign_eq_map_info - Assigns eq for vector_map structure * @phba: pointer to lpfc hba data structure. * @eqidx: index for eq and irq vector * @flag: flags to set for vector_map structure * @cpu: cpu used to index vector_map structure * * The routine assigns eq info into vector_map structure */ static inline void lpfc_assign_eq_map_info(struct lpfc_hba *phba, uint16_t eqidx, uint16_t flag, unsigned int cpu) { … } /** * lpfc_cpu_map_array_init - Initialize cpu_map structure * @phba: pointer to lpfc hba data structure. * * The routine initializes the cpu_map array structure */ static void lpfc_cpu_map_array_init(struct lpfc_hba *phba) { … } /** * lpfc_hba_eq_hdl_array_init - Initialize hba_eq_hdl structure * @phba: pointer to lpfc hba data structure. * * The routine initializes the hba_eq_hdl array structure */ static void lpfc_hba_eq_hdl_array_init(struct lpfc_hba *phba) { … } /** * lpfc_cpu_affinity_check - Check vector CPU affinity mappings * @phba: pointer to lpfc hba data structure. * @vectors: number of msix vectors allocated. * * The routine will figure out the CPU affinity assignment for every * MSI-X vector allocated for the HBA. * In addition, the CPU to IO channel mapping will be calculated * and the phba->sli4_hba.cpu_map array will reflect this. */ static void lpfc_cpu_affinity_check(struct lpfc_hba *phba, int vectors) { … } /** * lpfc_cpuhp_get_eq * * @phba: pointer to lpfc hba data structure. * @cpu: cpu going offline * @eqlist: eq list to append to */ static int lpfc_cpuhp_get_eq(struct lpfc_hba *phba, unsigned int cpu, struct list_head *eqlist) { … } static void __lpfc_cpuhp_remove(struct lpfc_hba *phba) { … } static void lpfc_cpuhp_remove(struct lpfc_hba *phba) { … } static void lpfc_cpuhp_add(struct lpfc_hba *phba) { … } static int __lpfc_cpuhp_checks(struct lpfc_hba *phba, int *retval) { … } /** * lpfc_irq_set_aff - set IRQ affinity * @eqhdl: EQ handle * @cpu: cpu to set affinity * **/ static inline void lpfc_irq_set_aff(struct lpfc_hba_eq_hdl *eqhdl, unsigned int cpu) { … } /** * lpfc_irq_clear_aff - clear IRQ affinity * @eqhdl: EQ handle * **/ static inline void lpfc_irq_clear_aff(struct lpfc_hba_eq_hdl *eqhdl) { … } /** * lpfc_irq_rebalance - rebalances IRQ affinity according to cpuhp event * @phba: pointer to HBA context object. * @cpu: cpu going offline/online * @offline: true, cpu is going offline. false, cpu is coming online. * * If cpu is going offline, we'll try our best effort to find the next * online cpu on the phba's original_mask and migrate all offlining IRQ * affinities. * * If cpu is coming online, reaffinitize the IRQ back to the onlining cpu. * * Note: Call only if NUMA or NHT mode is enabled, otherwise rely on * PCI_IRQ_AFFINITY to auto-manage IRQ affinity. * **/ static void lpfc_irq_rebalance(struct lpfc_hba *phba, unsigned int cpu, bool offline) { … } static int lpfc_cpu_offline(unsigned int cpu, struct hlist_node *node) { … } static int lpfc_cpu_online(unsigned int cpu, struct hlist_node *node) { … } /** * lpfc_sli4_enable_msix - Enable MSI-X interrupt mode to SLI-4 device * @phba: pointer to lpfc hba data structure. * * This routine is invoked to enable the MSI-X interrupt vectors to device * with SLI-4 interface spec. It also allocates MSI-X vectors and maps them * to cpus on the system. * * When cfg_irq_numa is enabled, the adapter will only allocate vectors for * the number of cpus on the same numa node as this adapter. The vectors are * allocated without requesting OS affinity mapping. A vector will be * allocated and assigned to each online and offline cpu. If the cpu is * online, then affinity will be set to that cpu. If the cpu is offline, then * affinity will be set to the nearest peer cpu within the numa node that is * online. If there are no online cpus within the numa node, affinity is not * assigned and the OS may do as it pleases. Note: cpu vector affinity mapping * is consistent with the way cpu online/offline is handled when cfg_irq_numa is * configured. * * If numa mode is not enabled and there is more than 1 vector allocated, then * the driver relies on the managed irq interface where the OS assigns vector to * cpu affinity. The driver will then use that affinity mapping to setup its * cpu mapping table. * * Return codes * 0 - successful * other values - error **/ static int lpfc_sli4_enable_msix(struct lpfc_hba *phba) { … } /** * lpfc_sli4_enable_msi - Enable MSI interrupt mode to SLI-4 device * @phba: pointer to lpfc hba data structure. * * This routine is invoked to enable the MSI interrupt mode to device with * SLI-4 interface spec. The kernel function pci_alloc_irq_vectors() is * called to enable the MSI vector. The device driver is responsible for * calling the request_irq() to register MSI vector with a interrupt the * handler, which is done in this function. * * Return codes * 0 - successful * other values - error **/ static int lpfc_sli4_enable_msi(struct lpfc_hba *phba) { … } /** * lpfc_sli4_enable_intr - Enable device interrupt to SLI-4 device * @phba: pointer to lpfc hba data structure. * @cfg_mode: Interrupt configuration mode (INTx, MSI or MSI-X). * * This routine is invoked to enable device interrupt and associate driver's * interrupt handler(s) to interrupt vector(s) to device with SLI-4 * interface spec. Depends on the interrupt mode configured to the driver, * the driver will try to fallback from the configured interrupt mode to an * interrupt mode which is supported by the platform, kernel, and device in * the order of: * MSI-X -> MSI -> IRQ. * * Return codes * Interrupt mode (2, 1, 0) - successful * LPFC_INTR_ERROR - error **/ static uint32_t lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) { … } /** * lpfc_sli4_disable_intr - Disable device interrupt to SLI-4 device * @phba: pointer to lpfc hba data structure. * * This routine is invoked to disable device interrupt and disassociate * the driver's interrupt handler(s) from interrupt vector(s) to device * with SLI-4 interface spec. Depending on the interrupt mode, the driver * will release the interrupt vector(s) for the message signaled interrupt. **/ static void lpfc_sli4_disable_intr(struct lpfc_hba *phba) { … } /** * lpfc_unset_hba - Unset SLI3 hba device initialization * @phba: pointer to lpfc hba data structure. * * This routine is invoked to unset the HBA device initialization steps to * a device with SLI-3 interface spec. **/ static void lpfc_unset_hba(struct lpfc_hba *phba) { … } /** * lpfc_sli4_xri_exchange_busy_wait - Wait for device XRI exchange busy * @phba: Pointer to HBA context object. * * This function is called in the SLI4 code path to wait for completion * of device's XRIs exchange busy. It will check the XRI exchange busy * on outstanding FCP and ELS I/Os every 10ms for up to 10 seconds; after * that, it will check the XRI exchange busy on outstanding FCP and ELS * I/Os every 30 seconds, log error message, and wait forever. Only when * all XRI exchange busy complete, the driver unload shall proceed with * invoking the function reset ioctl mailbox command to the CNA and the * the rest of the driver unload resource release. **/ static void lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba) { … } /** * lpfc_sli4_hba_unset - Unset the fcoe hba * @phba: Pointer to HBA context object. * * This function is called in the SLI4 code path to reset the HBA's FCoE * function. The caller is not required to hold any lock. This routine * issues PCI function reset mailbox command to reset the FCoE function. * At the end of the function, it calls lpfc_hba_down_post function to * free any pending commands. **/ static void lpfc_sli4_hba_unset(struct lpfc_hba *phba) { … } static uint32_t lpfc_cgn_crc32(uint32_t crc, u8 byte) { … } static uint32_t lpfc_cgn_reverse_bits(uint32_t wd) { … } /* * The routine corresponds with the algorithm the HBA firmware * uses to validate the data integrity. */ uint32_t lpfc_cgn_calc_crc32(void *ptr, uint32_t byteLen, uint32_t crc) { … } void lpfc_init_congestion_buf(struct lpfc_hba *phba) { … } void lpfc_init_congestion_stat(struct lpfc_hba *phba) { … } /** * __lpfc_reg_congestion_buf - register congestion info buffer with HBA * @phba: Pointer to hba context object. * @reg: flag to determine register or unregister. */ static int __lpfc_reg_congestion_buf(struct lpfc_hba *phba, int reg) { … } int lpfc_unreg_congestion_buf(struct lpfc_hba *phba) { … } int lpfc_reg_congestion_buf(struct lpfc_hba *phba) { … } /** * lpfc_get_sli4_parameters - Get the SLI4 Config PARAMETERS. * @phba: Pointer to HBA context object. * @mboxq: Pointer to the mailboxq memory for the mailbox command response. * * This function is called in the SLI4 code path to read the port's * sli4 capabilities. * * This function may be be called from any context that can block-wait * for the completion. The expectation is that this routine is called * typically from probe_one or from the online routine. **/ int lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) { … } /** * lpfc_pci_probe_one_s3 - PCI probe func to reg SLI-3 device to PCI subsystem. * @pdev: pointer to PCI device * @pid: pointer to PCI device identifier * * This routine is to be called to attach a device with SLI-3 interface spec * to the PCI subsystem. When an Emulex HBA with SLI-3 interface spec is * presented on PCI bus, the kernel PCI subsystem looks at PCI device-specific * information of the device and driver to see if the driver state that it can * support this kind of device. If the match is successful, the driver core * invokes this routine. If this routine determines it can claim the HBA, it * does all the initialization that it needs to do to handle the HBA properly. * * Return code * 0 - driver can claim the device * negative value - driver can not claim the device **/ static int lpfc_pci_probe_one_s3(struct pci_dev *pdev, const struct pci_device_id *pid) { … } /** * lpfc_pci_remove_one_s3 - PCI func to unreg SLI-3 device from PCI subsystem. * @pdev: pointer to PCI device * * This routine is to be called to disattach a device with SLI-3 interface * spec from PCI subsystem. When an Emulex HBA with SLI-3 interface spec is * removed from PCI bus, it performs all the necessary cleanup for the HBA * device to be removed from the PCI subsystem properly. **/ static void lpfc_pci_remove_one_s3(struct pci_dev *pdev) { … } /** * lpfc_pci_suspend_one_s3 - PCI func to suspend SLI-3 device for power mgmnt * @dev_d: pointer to device * * This routine is to be called from the kernel's PCI subsystem to support * system Power Management (PM) to device with SLI-3 interface spec. When * PM invokes this method, it quiesces the device by stopping the driver's * worker thread for the device, turning off device's interrupt and DMA, * and bring the device offline. Note that as the driver implements the * minimum PM requirements to a power-aware driver's PM support for the * suspend/resume -- all the possible PM messages (SUSPEND, HIBERNATE, FREEZE) * to the suspend() method call will be treated as SUSPEND and the driver will * fully reinitialize its device during resume() method call, the driver will * set device to PCI_D3hot state in PCI config space instead of setting it * according to the @msg provided by the PM. * * Return code * 0 - driver suspended the device * Error otherwise **/ static int __maybe_unused lpfc_pci_suspend_one_s3(struct device *dev_d) { … } /** * lpfc_pci_resume_one_s3 - PCI func to resume SLI-3 device for power mgmnt * @dev_d: pointer to device * * This routine is to be called from the kernel's PCI subsystem to support * system Power Management (PM) to device with SLI-3 interface spec. When PM * invokes this method, it restores the device's PCI config space state and * fully reinitializes the device and brings it online. Note that as the * driver implements the minimum PM requirements to a power-aware driver's * PM for suspend/resume -- all the possible PM messages (SUSPEND, HIBERNATE, * FREEZE) to the suspend() method call will be treated as SUSPEND and the * driver will fully reinitialize its device during resume() method call, * the device will be set to PCI_D0 directly in PCI config space before * restoring the state. * * Return code * 0 - driver suspended the device * Error otherwise **/ static int __maybe_unused lpfc_pci_resume_one_s3(struct device *dev_d) { … } /** * lpfc_sli_prep_dev_for_recover - Prepare SLI3 device for pci slot recover * @phba: pointer to lpfc hba data structure. * * This routine is called to prepare the SLI3 device for PCI slot recover. It * aborts all the outstanding SCSI I/Os to the pci device. **/ static void lpfc_sli_prep_dev_for_recover(struct lpfc_hba *phba) { … } /** * lpfc_sli_prep_dev_for_reset - Prepare SLI3 device for pci slot reset * @phba: pointer to lpfc hba data structure. * * This routine is called to prepare the SLI3 device for PCI slot reset. It * disables the device interrupt and pci device, and aborts the internal FCP * pending I/Os. **/ static void lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) { … } /** * lpfc_sli_prep_dev_for_perm_failure - Prepare SLI3 dev for pci slot disable * @phba: pointer to lpfc hba data structure. * * This routine is called to prepare the SLI3 device for PCI slot permanently * disabling. It blocks the SCSI transport layer traffic and flushes the FCP * pending I/Os. **/ static void lpfc_sli_prep_dev_for_perm_failure(struct lpfc_hba *phba) { … } /** * lpfc_io_error_detected_s3 - Method for handling SLI-3 device PCI I/O error * @pdev: pointer to PCI device. * @state: the current PCI connection state. * * This routine is called from the PCI subsystem for I/O error handling to * device with SLI-3 interface spec. This function is called by the PCI * subsystem after a PCI bus error affecting this device has been detected. * When this function is invoked, it will need to stop all the I/Os and * interrupt(s) to the device. Once that is done, it will return * PCI_ERS_RESULT_NEED_RESET for the PCI subsystem to perform proper recovery * as desired. * * Return codes * PCI_ERS_RESULT_CAN_RECOVER - can be recovered with reset_link * PCI_ERS_RESULT_NEED_RESET - need to reset before recovery * PCI_ERS_RESULT_DISCONNECT - device could not be recovered **/ static pci_ers_result_t lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state) { … } /** * lpfc_io_slot_reset_s3 - Method for restarting PCI SLI-3 device from scratch. * @pdev: pointer to PCI device. * * This routine is called from the PCI subsystem for error handling to * device with SLI-3 interface spec. This is called after PCI bus has been * reset to restart the PCI card from scratch, as if from a cold-boot. * During the PCI subsystem error recovery, after driver returns * PCI_ERS_RESULT_NEED_RESET, the PCI subsystem will perform proper error * recovery and then call this routine before calling the .resume method * to recover the device. This function will initialize the HBA device, * enable the interrupt, but it will just put the HBA to offline state * without passing any I/O traffic. * * Return codes * PCI_ERS_RESULT_RECOVERED - the device has been recovered * PCI_ERS_RESULT_DISCONNECT - device could not be recovered */ static pci_ers_result_t lpfc_io_slot_reset_s3(struct pci_dev *pdev) { … } /** * lpfc_io_resume_s3 - Method for resuming PCI I/O operation on SLI-3 device. * @pdev: pointer to PCI device * * This routine is called from the PCI subsystem for error handling to device * with SLI-3 interface spec. It is called when kernel error recovery tells * the lpfc driver that it is ok to resume normal PCI operation after PCI bus * error recovery. After this call, traffic can start to flow from this device * again. */ static void lpfc_io_resume_s3(struct pci_dev *pdev) { … } /** * lpfc_sli4_get_els_iocb_cnt - Calculate the # of ELS IOCBs to reserve * @phba: pointer to lpfc hba data structure. * * returns the number of ELS/CT IOCBs to reserve **/ int lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba) { … } /** * lpfc_sli4_get_iocb_cnt - Calculate the # of total IOCBs to reserve * @phba: pointer to lpfc hba data structure. * * returns the number of ELS/CT + NVMET IOCBs to reserve **/ int lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba) { … } static int lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset, uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize, const struct firmware *fw) { … } /** * lpfc_write_firmware - attempt to write a firmware image to the port * @fw: pointer to firmware image returned from request_firmware. * @context: pointer to firmware image returned from request_firmware. * **/ static void lpfc_write_firmware(const struct firmware *fw, void *context) { … } /** * lpfc_sli4_request_firmware_update - Request linux generic firmware upgrade * @phba: pointer to lpfc hba data structure. * @fw_upgrade: which firmware to update. * * This routine is called to perform Linux generic firmware upgrade on device * that supports such feature. **/ int lpfc_sli4_request_firmware_update(struct lpfc_hba *phba, uint8_t fw_upgrade) { … } /** * lpfc_pci_probe_one_s4 - PCI probe func to reg SLI-4 device to PCI subsys * @pdev: pointer to PCI device * @pid: pointer to PCI device identifier * * This routine is called from the kernel's PCI subsystem to device with * SLI-4 interface spec. When an Emulex HBA with SLI-4 interface spec is * presented on PCI bus, the kernel PCI subsystem looks at PCI device-specific * information of the device and driver to see if the driver state that it * can support this kind of device. If the match is successful, the driver * core invokes this routine. If this routine determines it can claim the HBA, * it does all the initialization that it needs to do to handle the HBA * properly. * * Return code * 0 - driver can claim the device * negative value - driver can not claim the device **/ static int lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) { … } /** * lpfc_pci_remove_one_s4 - PCI func to unreg SLI-4 device from PCI subsystem * @pdev: pointer to PCI device * * This routine is called from the kernel's PCI subsystem to device with * SLI-4 interface spec. When an Emulex HBA with SLI-4 interface spec is * removed from PCI bus, it performs all the necessary cleanup for the HBA * device to be removed from the PCI subsystem properly. **/ static void lpfc_pci_remove_one_s4(struct pci_dev *pdev) { … } /** * lpfc_pci_suspend_one_s4 - PCI func to suspend SLI-4 device for power mgmnt * @dev_d: pointer to device * * This routine is called from the kernel's PCI subsystem to support system * Power Management (PM) to device with SLI-4 interface spec. When PM invokes * this method, it quiesces the device by stopping the driver's worker * thread for the device, turning off device's interrupt and DMA, and bring * the device offline. Note that as the driver implements the minimum PM * requirements to a power-aware driver's PM support for suspend/resume -- all * the possible PM messages (SUSPEND, HIBERNATE, FREEZE) to the suspend() * method call will be treated as SUSPEND and the driver will fully * reinitialize its device during resume() method call, the driver will set * device to PCI_D3hot state in PCI config space instead of setting it * according to the @msg provided by the PM. * * Return code * 0 - driver suspended the device * Error otherwise **/ static int __maybe_unused lpfc_pci_suspend_one_s4(struct device *dev_d) { … } /** * lpfc_pci_resume_one_s4 - PCI func to resume SLI-4 device for power mgmnt * @dev_d: pointer to device * * This routine is called from the kernel's PCI subsystem to support system * Power Management (PM) to device with SLI-4 interface spac. When PM invokes * this method, it restores the device's PCI config space state and fully * reinitializes the device and brings it online. Note that as the driver * implements the minimum PM requirements to a power-aware driver's PM for * suspend/resume -- all the possible PM messages (SUSPEND, HIBERNATE, FREEZE) * to the suspend() method call will be treated as SUSPEND and the driver * will fully reinitialize its device during resume() method call, the device * will be set to PCI_D0 directly in PCI config space before restoring the * state. * * Return code * 0 - driver suspended the device * Error otherwise **/ static int __maybe_unused lpfc_pci_resume_one_s4(struct device *dev_d) { … } /** * lpfc_sli4_prep_dev_for_recover - Prepare SLI4 device for pci slot recover * @phba: pointer to lpfc hba data structure. * * This routine is called to prepare the SLI4 device for PCI slot recover. It * aborts all the outstanding SCSI I/Os to the pci device. **/ static void lpfc_sli4_prep_dev_for_recover(struct lpfc_hba *phba) { … } /** * lpfc_sli4_prep_dev_for_reset - Prepare SLI4 device for pci slot reset * @phba: pointer to lpfc hba data structure. * * This routine is called to prepare the SLI4 device for PCI slot reset. It * disables the device interrupt and pci device, and aborts the internal FCP * pending I/Os. **/ static void lpfc_sli4_prep_dev_for_reset(struct lpfc_hba *phba) { … } /** * lpfc_sli4_prep_dev_for_perm_failure - Prepare SLI4 dev for pci slot disable * @phba: pointer to lpfc hba data structure. * * This routine is called to prepare the SLI4 device for PCI slot permanently * disabling. It blocks the SCSI transport layer traffic and flushes the FCP * pending I/Os. **/ static void lpfc_sli4_prep_dev_for_perm_failure(struct lpfc_hba *phba) { … } /** * lpfc_io_error_detected_s4 - Method for handling PCI I/O error to SLI-4 device * @pdev: pointer to PCI device. * @state: the current PCI connection state. * * This routine is called from the PCI subsystem for error handling to device * with SLI-4 interface spec. This function is called by the PCI subsystem * after a PCI bus error affecting this device has been detected. When this * function is invoked, it will need to stop all the I/Os and interrupt(s) * to the device. Once that is done, it will return PCI_ERS_RESULT_NEED_RESET * for the PCI subsystem to perform proper recovery as desired. * * Return codes * PCI_ERS_RESULT_NEED_RESET - need to reset before recovery * PCI_ERS_RESULT_DISCONNECT - device could not be recovered **/ static pci_ers_result_t lpfc_io_error_detected_s4(struct pci_dev *pdev, pci_channel_state_t state) { … } /** * lpfc_io_slot_reset_s4 - Method for restart PCI SLI-4 device from scratch * @pdev: pointer to PCI device. * * This routine is called from the PCI subsystem for error handling to device * with SLI-4 interface spec. It is called after PCI bus has been reset to * restart the PCI card from scratch, as if from a cold-boot. During the * PCI subsystem error recovery, after the driver returns * PCI_ERS_RESULT_NEED_RESET, the PCI subsystem will perform proper error * recovery and then call this routine before calling the .resume method to * recover the device. This function will initialize the HBA device, enable * the interrupt, but it will just put the HBA to offline state without * passing any I/O traffic. * * Return codes * PCI_ERS_RESULT_RECOVERED - the device has been recovered * PCI_ERS_RESULT_DISCONNECT - device could not be recovered */ static pci_ers_result_t lpfc_io_slot_reset_s4(struct pci_dev *pdev) { … } /** * lpfc_io_resume_s4 - Method for resuming PCI I/O operation to SLI-4 device * @pdev: pointer to PCI device * * This routine is called from the PCI subsystem for error handling to device * with SLI-4 interface spec. It is called when kernel error recovery tells * the lpfc driver that it is ok to resume normal PCI operation after PCI bus * error recovery. After this call, traffic can start to flow from this device * again. **/ static void lpfc_io_resume_s4(struct pci_dev *pdev) { … } /** * lpfc_pci_probe_one - lpfc PCI probe func to reg dev to PCI subsystem * @pdev: pointer to PCI device * @pid: pointer to PCI device identifier * * This routine is to be registered to the kernel's PCI subsystem. When an * Emulex HBA device is presented on PCI bus, the kernel PCI subsystem looks * at PCI device-specific information of the device and driver to see if the * driver state that it can support this kind of device. If the match is * successful, the driver core invokes this routine. This routine dispatches * the action to the proper SLI-3 or SLI-4 device probing routine, which will * do all the initialization that it needs to do to handle the HBA device * properly. * * Return code * 0 - driver can claim the device * negative value - driver can not claim the device **/ static int lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) { … } /** * lpfc_pci_remove_one - lpfc PCI func to unreg dev from PCI subsystem * @pdev: pointer to PCI device * * This routine is to be registered to the kernel's PCI subsystem. When an * Emulex HBA is removed from PCI bus, the driver core invokes this routine. * This routine dispatches the action to the proper SLI-3 or SLI-4 device * remove routine, which will perform all the necessary cleanup for the * device to be removed from the PCI subsystem properly. **/ static void lpfc_pci_remove_one(struct pci_dev *pdev) { … } /** * lpfc_pci_suspend_one - lpfc PCI func to suspend dev for power management * @dev: pointer to device * * This routine is to be registered to the kernel's PCI subsystem to support * system Power Management (PM). When PM invokes this method, it dispatches * the action to the proper SLI-3 or SLI-4 device suspend routine, which will * suspend the device. * * Return code * 0 - driver suspended the device * Error otherwise **/ static int __maybe_unused lpfc_pci_suspend_one(struct device *dev) { … } /** * lpfc_pci_resume_one - lpfc PCI func to resume dev for power management * @dev: pointer to device * * This routine is to be registered to the kernel's PCI subsystem to support * system Power Management (PM). When PM invokes this method, it dispatches * the action to the proper SLI-3 or SLI-4 device resume routine, which will * resume the device. * * Return code * 0 - driver suspended the device * Error otherwise **/ static int __maybe_unused lpfc_pci_resume_one(struct device *dev) { … } /** * lpfc_io_error_detected - lpfc method for handling PCI I/O error * @pdev: pointer to PCI device. * @state: the current PCI connection state. * * This routine is registered to the PCI subsystem for error handling. This * function is called by the PCI subsystem after a PCI bus error affecting * this device has been detected. When this routine is invoked, it dispatches * the action to the proper SLI-3 or SLI-4 device error detected handling * routine, which will perform the proper error detected operation. * * Return codes * PCI_ERS_RESULT_NEED_RESET - need to reset before recovery * PCI_ERS_RESULT_DISCONNECT - device could not be recovered **/ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { … } /** * lpfc_io_slot_reset - lpfc method for restart PCI dev from scratch * @pdev: pointer to PCI device. * * This routine is registered to the PCI subsystem for error handling. This * function is called after PCI bus has been reset to restart the PCI card * from scratch, as if from a cold-boot. When this routine is invoked, it * dispatches the action to the proper SLI-3 or SLI-4 device reset handling * routine, which will perform the proper device reset. * * Return codes * PCI_ERS_RESULT_RECOVERED - the device has been recovered * PCI_ERS_RESULT_DISCONNECT - device could not be recovered **/ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) { … } /** * lpfc_io_resume - lpfc method for resuming PCI I/O operation * @pdev: pointer to PCI device * * This routine is registered to the PCI subsystem for error handling. It * is called when kernel error recovery tells the lpfc driver that it is * OK to resume normal PCI operation after PCI bus error recovery. When * this routine is invoked, it dispatches the action to the proper SLI-3 * or SLI-4 device io_resume routine, which will resume the device operation. **/ static void lpfc_io_resume(struct pci_dev *pdev) { … } /** * lpfc_sli4_oas_verify - Verify OAS is supported by this adapter * @phba: pointer to lpfc hba data structure. * * This routine checks to see if OAS is supported for this adapter. If * supported, the configure Flash Optimized Fabric flag is set. Otherwise, * the enable oas flag is cleared and the pool created for OAS device data * is destroyed. * **/ static void lpfc_sli4_oas_verify(struct lpfc_hba *phba) { … } /** * lpfc_sli4_ras_init - Verify RAS-FW log is supported by this adapter * @phba: pointer to lpfc hba data structure. * * This routine checks to see if RAS is supported by the adapter. Check the * function through which RAS support enablement is to be done. **/ void lpfc_sli4_ras_init(struct lpfc_hba *phba) { … } MODULE_DEVICE_TABLE(pci, lpfc_id_table); static const struct pci_error_handlers lpfc_err_handler = …; static SIMPLE_DEV_PM_OPS(lpfc_pci_pm_ops_one, lpfc_pci_suspend_one, lpfc_pci_resume_one); static struct pci_driver lpfc_driver = …; static const struct file_operations lpfc_mgmt_fop = …; static struct miscdevice lpfc_mgmt_dev = …; /** * lpfc_init - lpfc module initialization routine * * This routine is to be invoked when the lpfc module is loaded into the * kernel. The special kernel macro module_init() is used to indicate the * role of this routine to the kernel as lpfc module entry point. * * Return codes * 0 - successful * -ENOMEM - FC attach transport failed * all others - failed */ static int __init lpfc_init(void) { … } void lpfc_dmp_dbg(struct lpfc_hba *phba) { … } __printf(2, 3) void lpfc_dbg_print(struct lpfc_hba *phba, const char *fmt, ...) { … } /** * lpfc_exit - lpfc module removal routine * * This routine is invoked when the lpfc module is removed from the kernel. * The special kernel macro module_exit() is used to indicate the role of * this routine to the kernel as lpfc module exit point. */ static void __exit lpfc_exit(void) { … } module_init(…) …; module_exit(lpfc_exit); MODULE_LICENSE(…) …; MODULE_DESCRIPTION(…); MODULE_AUTHOR(…) …; MODULE_VERSION(…) …;