/******************************************************************* * 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/ctype.h> #include <linux/delay.h> #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux/aer.h> #include <linux/gfp.h> #include <linux/kernel.h> #include <scsi/scsi.h> #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi_tcq.h> #include <scsi/scsi_transport_fc.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_version.h" #include "lpfc_compat.h" #include "lpfc_crtn.h" #include "lpfc_vport.h" #include "lpfc_attr.h" #define LPFC_DEF_DEVLOSS_TMO … #define LPFC_MIN_DEVLOSS_TMO … #define LPFC_MAX_DEVLOSS_TMO … #define LPFC_MAX_INFO_TMP_LEN … #define LPFC_INFO_MORE_STR … /* * Write key size should be multiple of 4. If write key is changed * make sure that library write key is also changed. */ #define LPFC_REG_WRITE_KEY_SIZE … #define LPFC_REG_WRITE_KEY … const char *const trunk_errmsg[] = …; /** * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules * @incr: integer to convert. * @hdw: ascii string holding converted integer plus a string terminator. * * Description: * JEDEC Joint Electron Device Engineering Council. * Convert a 32 bit integer composed of 8 nibbles into an 8 byte ascii * character string. The string is then terminated with a NULL in byte 9. * Hex 0-9 becomes ascii '0' to '9'. * Hex a-f becomes ascii '=' to 'B' capital B. * * Notes: * Coded for 32 bit integers only. **/ static void lpfc_jedec_to_ascii(int incr, char hdw[]) { … } static ssize_t lpfc_cmf_info_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_drvr_version_show - Return the Emulex driver string with version number * @dev: class unused variable. * @attr: device attribute, not used. * @buf: on return contains the module description text. * * Returns: size of formatted string. **/ static ssize_t lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_enable_fip_show - Return the fip mode of the HBA * @dev: class unused variable. * @attr: device attribute, not used. * @buf: on return contains the module description text. * * Returns: size of formatted string. **/ static ssize_t lpfc_enable_fip_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static ssize_t lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static ssize_t lpfc_scsi_stat_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static ssize_t lpfc_bg_info_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static ssize_t lpfc_bg_guard_err_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static ssize_t lpfc_bg_apptag_err_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static ssize_t lpfc_bg_reftag_err_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_info_show - Return some pci info about the host in ascii * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the formatted text from lpfc_info(). * * Returns: size of formatted string. **/ static ssize_t lpfc_info_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_serialnum_show - Return the hba serial number in ascii * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the formatted text serial number. * * Returns: size of formatted string. **/ static ssize_t lpfc_serialnum_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_temp_sensor_show - Return the temperature sensor level * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the formatted support level. * * Description: * Returns a number indicating the temperature sensor level currently * supported, zero or one in ascii. * * Returns: size of formatted string. **/ static ssize_t lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_modeldesc_show - Return the model description of the hba * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the scsi vpd model description. * * Returns: size of formatted string. **/ static ssize_t lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_modelname_show - Return the model name of the hba * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the scsi vpd model name. * * Returns: size of formatted string. **/ static ssize_t lpfc_modelname_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_programtype_show - Return the program type of the hba * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the scsi vpd program type. * * Returns: size of formatted string. **/ static ssize_t lpfc_programtype_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_vportnum_show - Return the port number in ascii of the hba * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains scsi vpd program type. * * Returns: size of formatted string. **/ static ssize_t lpfc_vportnum_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_fwrev_show - Return the firmware rev running in the hba * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the scsi vpd program type. * * Returns: size of formatted string. **/ static ssize_t lpfc_fwrev_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_hdw_show - Return the jedec information about the hba * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the scsi vpd program type. * * Returns: size of formatted string. **/ static ssize_t lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_option_rom_version_show - Return the adapter ROM FCode version * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the ROM and FCode ascii strings. * * Returns: size of formatted string. **/ static ssize_t lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_link_state_show - Return the link state of the port * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains text describing the state of the link. * * Notes: * The switch statement has no default so zero will be returned. * * Returns: size of formatted string. **/ static ssize_t lpfc_link_state_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_sli4_protocol_show - Return the fip mode of the HBA * @dev: class unused variable. * @attr: device attribute, not used. * @buf: on return contains the module description text. * * Returns: size of formatted string. **/ static ssize_t lpfc_sli4_protocol_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_oas_supported_show - Return whether or not Optimized Access Storage * (OAS) is supported. * @dev: class unused variable. * @attr: device attribute, not used. * @buf: on return contains the module description text. * * Returns: size of formatted string. **/ static ssize_t lpfc_oas_supported_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_link_state_store - Transition the link_state on an HBA port * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: one or more lpfc_polling_flags values. * @count: not used. * * Returns: * -EINVAL if the buffer is not "up" or "down" * return from link state change function if non-zero * length of the buf on success **/ static ssize_t lpfc_link_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } /** * lpfc_num_discovered_ports_show - Return sum of mapped and unmapped vports * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the sum of fc mapped and unmapped. * * Description: * Returns the ascii text number of the sum of the fc mapped and unmapped * vport counts. * * Returns: size of formatted string. **/ static ssize_t lpfc_num_discovered_ports_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_issue_lip - Misnomer, name carried over from long ago * @shost: Scsi_Host pointer. * * Description: * Bring the link down gracefully then re-init the link. The firmware will * re-init the fiber channel interface as required. Does not issue a LIP. * * Returns: * -EPERM port offline or management commands are being blocked * -ENOMEM cannot allocate memory for the mailbox command * -EIO error sending the mailbox command * zero for success **/ static int lpfc_issue_lip(struct Scsi_Host *shost) { … } int lpfc_emptyq_wait(struct lpfc_hba *phba, struct list_head *q, spinlock_t *lock) { … } /** * lpfc_do_offline - Issues a mailbox command to bring the link down * @phba: lpfc_hba pointer. * @type: LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL. * * Notes: * Assumes any error from lpfc_do_offline() will be negative. * Can wait up to 5 seconds for the port ring buffers count * to reach zero, prints a warning if it is not zero and continues. * lpfc_workq_post_event() returns a non-zero return code if call fails. * * Returns: * -EIO error posting the event * zero for success **/ static int lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) { … } /** * lpfc_reset_pci_bus - resets PCI bridge controller's secondary bus of an HBA * @phba: lpfc_hba pointer. * * Description: * Issues a PCI secondary bus reset for the phba->pcidev. * * Notes: * First walks the bus_list to ensure only PCI devices with Emulex * vendor id, device ids that support hot reset, only one occurrence * of function 0, and all ports on the bus are in offline mode to ensure the * hot reset only affects one valid HBA. * * Returns: * -ENOTSUPP, cfg_enable_hba_reset must be of value 2 * -ENODEV, NULL ptr to pcidev * -EBADSLT, detected invalid device * -EBUSY, port is not in offline state * 0, successful */ static int lpfc_reset_pci_bus(struct lpfc_hba *phba) { … } /** * lpfc_selective_reset - Offline then onlines the port * @phba: lpfc_hba pointer. * * Description: * If the port is configured to allow a reset then the hba is brought * offline then online. * * Notes: * Assumes any error from lpfc_do_offline() will be negative. * Do not make this function static. * * Returns: * lpfc_do_offline() return code if not zero * -EIO reset not configured or error posting the event * zero for success **/ int lpfc_selective_reset(struct lpfc_hba *phba) { … } /** * lpfc_issue_reset - Selectively resets an adapter * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: containing the string "selective". * @count: unused variable. * * Description: * If the buf contains the string "selective" then lpfc_selective_reset() * is called to perform the reset. * * Notes: * Assumes any error from lpfc_selective_reset() will be negative. * If lpfc_selective_reset() returns zero then the length of the buffer * is returned which indicates success * * Returns: * -EINVAL if the buffer does not contain the string "selective" * length of buf if lpfc-selective_reset() if the call succeeds * return value of lpfc_selective_reset() if the call fails **/ static ssize_t lpfc_issue_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } /** * lpfc_sli4_pdev_status_reg_wait - Wait for pdev status register for readyness * @phba: lpfc_hba pointer. * * Description: * SLI4 interface type-2 device to wait on the sliport status register for * the readyness after performing a firmware reset. * * Returns: * zero for success, -EPERM when port does not have privilege to perform the * reset, -EIO when port timeout from recovering from the reset. * * Note: * As the caller will interpret the return code by value, be careful in making * change or addition to return codes. **/ int lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) { … } /** * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc * @phba: lpfc_hba pointer. * @opcode: The sli4 config command opcode. * * Description: * Request SLI4 interface type-2 device to perform a physical register set * access. * * Returns: * zero for success **/ static ssize_t lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) { … } /** * lpfc_nport_evt_cnt_show - Return the number of nport events * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the ascii number of nport events. * * Returns: size of formatted string. **/ static ssize_t lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static int lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out) { … } static ssize_t lpfc_xcvr_data_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_board_mode_show - Return the state of the board * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the state of the adapter. * * Returns: size of formatted string. **/ static ssize_t lpfc_board_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_board_mode_store - Puts the hba in online, offline, warm or error state * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: containing one of the strings "online", "offline", "warm" or "error". * @count: unused variable. * * Returns: * -EACCES if enable hba reset not enabled * -EINVAL if the buffer does not contain a valid string (see above) * -EIO if lpfc_workq_post_event() or lpfc_do_offline() fails * buf length greater than zero indicates success **/ static ssize_t lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } /** * lpfc_get_hba_info - Return various bits of informaton about the adapter * @phba: pointer to the adapter structure. * @mxri: max xri count. * @axri: available xri count. * @mrpi: max rpi count. * @arpi: available rpi count. * @mvpi: max vpi count. * @avpi: available vpi count. * * Description: * If an integer pointer for an count is not null then the value for the * count is returned. * * Returns: * zero on error * one for success **/ static int lpfc_get_hba_info(struct lpfc_hba *phba, uint32_t *mxri, uint32_t *axri, uint32_t *mrpi, uint32_t *arpi, uint32_t *mvpi, uint32_t *avpi) { … } /** * lpfc_max_rpi_show - Return maximum rpi * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the maximum rpi count in decimal or "Unknown". * * Description: * Calls lpfc_get_hba_info() asking for just the mrpi count. * If lpfc_get_hba_info() returns zero (failure) the buffer text is set * to "Unknown" and the buffer length is returned, therefore the caller * must check for "Unknown" in the buffer to detect a failure. * * Returns: size of formatted string. **/ static ssize_t lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_used_rpi_show - Return maximum rpi minus available rpi * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: containing the used rpi count in decimal or "Unknown". * * Description: * Calls lpfc_get_hba_info() asking for just the mrpi and arpi counts. * If lpfc_get_hba_info() returns zero (failure) the buffer text is set * to "Unknown" and the buffer length is returned, therefore the caller * must check for "Unknown" in the buffer to detect a failure. * * Returns: size of formatted string. **/ static ssize_t lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_max_xri_show - Return maximum xri * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the maximum xri count in decimal or "Unknown". * * Description: * Calls lpfc_get_hba_info() asking for just the mrpi count. * If lpfc_get_hba_info() returns zero (failure) the buffer text is set * to "Unknown" and the buffer length is returned, therefore the caller * must check for "Unknown" in the buffer to detect a failure. * * Returns: size of formatted string. **/ static ssize_t lpfc_max_xri_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_used_xri_show - Return maximum xpi minus the available xpi * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the used xri count in decimal or "Unknown". * * Description: * Calls lpfc_get_hba_info() asking for just the mxri and axri counts. * If lpfc_get_hba_info() returns zero (failure) the buffer text is set * to "Unknown" and the buffer length is returned, therefore the caller * must check for "Unknown" in the buffer to detect a failure. * * Returns: size of formatted string. **/ static ssize_t lpfc_used_xri_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_max_vpi_show - Return maximum vpi * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the maximum vpi count in decimal or "Unknown". * * Description: * Calls lpfc_get_hba_info() asking for just the mvpi count. * If lpfc_get_hba_info() returns zero (failure) the buffer text is set * to "Unknown" and the buffer length is returned, therefore the caller * must check for "Unknown" in the buffer to detect a failure. * * Returns: size of formatted string. **/ static ssize_t lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_used_vpi_show - Return maximum vpi minus the available vpi * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the used vpi count in decimal or "Unknown". * * Description: * Calls lpfc_get_hba_info() asking for just the mvpi and avpi counts. * If lpfc_get_hba_info() returns zero (failure) the buffer text is set * to "Unknown" and the buffer length is returned, therefore the caller * must check for "Unknown" in the buffer to detect a failure. * * Returns: size of formatted string. **/ static ssize_t lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_npiv_info_show - Return text about NPIV support for the adapter * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: text that must be interpreted to determine if npiv is supported. * * Description: * Buffer will contain text indicating npiv is not suppoerted on the port, * the port is an NPIV physical port, or it is an npiv virtual port with * the id of the vport. * * Returns: size of formatted string. **/ static ssize_t lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_poll_show - Return text about poll support for the adapter * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the cfg_poll in hex. * * Notes: * cfg_poll should be a lpfc_polling_flags type. * * Returns: size of formatted string. **/ static ssize_t lpfc_poll_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_poll_store - Set the value of cfg_poll for the adapter * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: one or more lpfc_polling_flags values. * @count: not used. * * Notes: * buf contents converted to integer and checked for a valid value. * * Returns: * -EINVAL if the buffer connot be converted or is out of range * length of the buf on success **/ static ssize_t lpfc_poll_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } /** * lpfc_sriov_hw_max_virtfn_show - Return maximum number of virtual functions * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the formatted support level. * * Description: * Returns the maximum number of virtual functions a physical function can * support, 0 will be returned if called on virtual function. * * Returns: size of formatted string. **/ static ssize_t lpfc_sriov_hw_max_virtfn_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_enable_bbcr_set: Sets an attribute value. * @phba: pointer to the adapter structure. * @val: integer attribute value. * * Description: * Validates the min and max values then sets the * adapter config field if in the valid range. prints error message * and does not set the parameter if invalid. * * Returns: * zero on success * -EINVAL if val is invalid */ static ssize_t lpfc_enable_bbcr_set(struct lpfc_hba *phba, uint val) { … } /* * lpfc_param_show - Return a cfg attribute value in decimal * * Description: * Macro that given an attr e.g. hba_queue_depth expands * into a function with the name lpfc_hba_queue_depth_show. * * lpfc_##attr##_show: Return the decimal value of an adapters cfg_xxx field. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the attribute value in decimal. * * Returns: size of formatted string. **/ #define lpfc_param_show(attr) … /* * lpfc_param_hex_show - Return a cfg attribute value in hex * * Description: * Macro that given an attr e.g. hba_queue_depth expands * into a function with the name lpfc_hba_queue_depth_show * * lpfc_##attr##_show: Return the hex value of an adapters cfg_xxx field. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the attribute value in hexadecimal. * * Returns: size of formatted string. **/ #define lpfc_param_hex_show(attr) … /* * lpfc_param_init - Initializes a cfg attribute * * Description: * Macro that given an attr e.g. hba_queue_depth expands * into a function with the name lpfc_hba_queue_depth_init. The macro also * takes a default argument, a minimum and maximum argument. * * lpfc_##attr##_init: Initializes an attribute. * @phba: pointer to the adapter structure. * @val: integer attribute value. * * Validates the min and max values then sets the adapter config field * accordingly, or uses the default if out of range and prints an error message. * * Returns: * zero on success * -EINVAL if default used **/ #define lpfc_param_init(attr, default, minval, maxval) … /* * lpfc_param_set - Set a cfg attribute value * * Description: * Macro that given an attr e.g. hba_queue_depth expands * into a function with the name lpfc_hba_queue_depth_set * * lpfc_##attr##_set: Sets an attribute value. * @phba: pointer to the adapter structure. * @val: integer attribute value. * * Description: * Validates the min and max values then sets the * adapter config field if in the valid range. prints error message * and does not set the parameter if invalid. * * Returns: * zero on success * -EINVAL if val is invalid **/ #define lpfc_param_set(attr, default, minval, maxval) … /* * lpfc_param_store - Set a vport attribute value * * Description: * Macro that given an attr e.g. hba_queue_depth expands * into a function with the name lpfc_hba_queue_depth_store. * * lpfc_##attr##_store: Set an sttribute value. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: contains the attribute value in ascii. * @count: not used. * * Description: * Convert the ascii text number to an integer, then * use the lpfc_##attr##_set function to set the value. * * Returns: * -EINVAL if val is invalid or lpfc_##attr##_set() fails * length of buffer upon success. **/ #define lpfc_param_store(attr) … /* * lpfc_vport_param_show - Return decimal formatted cfg attribute value * * Description: * Macro that given an attr e.g. hba_queue_depth expands * into a function with the name lpfc_hba_queue_depth_show * * lpfc_##attr##_show: prints the attribute value in decimal. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the attribute value in decimal. * * Returns: length of formatted string. **/ #define lpfc_vport_param_show(attr) … /* * lpfc_vport_param_hex_show - Return hex formatted attribute value * * Description: * Macro that given an attr e.g. * hba_queue_depth expands into a function with the name * lpfc_hba_queue_depth_show * * lpfc_##attr##_show: prints the attribute value in hexadecimal. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: on return contains the attribute value in hexadecimal. * * Returns: length of formatted string. **/ #define lpfc_vport_param_hex_show(attr) … /* * lpfc_vport_param_init - Initialize a vport cfg attribute * * Description: * Macro that given an attr e.g. hba_queue_depth expands * into a function with the name lpfc_hba_queue_depth_init. The macro also * takes a default argument, a minimum and maximum argument. * * lpfc_##attr##_init: validates the min and max values then sets the * adapter config field accordingly, or uses the default if out of range * and prints an error message. * @phba: pointer to the adapter structure. * @val: integer attribute value. * * Returns: * zero on success * -EINVAL if default used **/ #define lpfc_vport_param_init(attr, default, minval, maxval) … /* * lpfc_vport_param_set - Set a vport cfg attribute * * Description: * Macro that given an attr e.g. hba_queue_depth expands * into a function with the name lpfc_hba_queue_depth_set * * lpfc_##attr##_set: validates the min and max values then sets the * adapter config field if in the valid range. prints error message * and does not set the parameter if invalid. * @phba: pointer to the adapter structure. * @val: integer attribute value. * * Returns: * zero on success * -EINVAL if val is invalid **/ #define lpfc_vport_param_set(attr, default, minval, maxval) … /* * lpfc_vport_param_store - Set a vport attribute * * Description: * Macro that given an attr e.g. hba_queue_depth * expands into a function with the name lpfc_hba_queue_depth_store * * lpfc_##attr##_store: convert the ascii text number to an integer, then * use the lpfc_##attr##_set function to set the value. * @cdev: class device that is converted into a Scsi_host. * @buf: contains the attribute value in decimal. * @count: not used. * * Returns: * -EINVAL if val is invalid or lpfc_##attr##_set() fails * length of buffer upon success. **/ #define lpfc_vport_param_store(attr) … static DEVICE_ATTR(nvme_info, 0444, lpfc_nvme_info_show, NULL); static DEVICE_ATTR(scsi_stat, 0444, lpfc_scsi_stat_show, NULL); static DEVICE_ATTR(bg_info, S_IRUGO, lpfc_bg_info_show, NULL); static DEVICE_ATTR(bg_guard_err, S_IRUGO, lpfc_bg_guard_err_show, NULL); static DEVICE_ATTR(bg_apptag_err, S_IRUGO, lpfc_bg_apptag_err_show, NULL); static DEVICE_ATTR(bg_reftag_err, S_IRUGO, lpfc_bg_reftag_err_show, NULL); static DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL); static DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL); static DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL); static DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL); static DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL); static DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL); static DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL); static DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL); static DEVICE_ATTR(link_state, S_IRUGO | S_IWUSR, lpfc_link_state_show, lpfc_link_state_store); static DEVICE_ATTR(option_rom_version, S_IRUGO, lpfc_option_rom_version_show, NULL); static DEVICE_ATTR(num_discovered_ports, S_IRUGO, lpfc_num_discovered_ports_show, NULL); static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL); static DEVICE_ATTR_RO(lpfc_drvr_version); static DEVICE_ATTR_RO(lpfc_enable_fip); static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, lpfc_board_mode_show, lpfc_board_mode_store); static DEVICE_ATTR_RO(lpfc_xcvr_data); static DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); static DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL); static DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL); static DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL); static DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL); static DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL); static DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL); static DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL); static DEVICE_ATTR_RO(lpfc_temp_sensor); static DEVICE_ATTR_RO(lpfc_sriov_hw_max_virtfn); static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL); static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show, NULL); static DEVICE_ATTR(cmf_info, 0444, lpfc_cmf_info_show, NULL); #define WWN_SZ … /** * lpfc_wwn_set - Convert string to the 8 byte WWN value. * @buf: WWN string. * @cnt: Length of string. * @wwn: Array to receive converted wwn value. * * Returns: * -EINVAL if the buffer does not contain a valid wwn * 0 success **/ static size_t lpfc_wwn_set(const char *buf, size_t cnt, char wwn[]) { … } /** * lpfc_oas_tgt_show - Return wwpn of target whose luns maybe enabled for * Optimized Access Storage (OAS) operations. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * * Returns: * value of count **/ static ssize_t lpfc_oas_tgt_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_oas_tgt_store - Store wwpn of target whose luns maybe enabled for * Optimized Access Storage (OAS) operations. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * @count: Size of the data buffer. * * Returns: * -EINVAL count is invalid, invalid wwpn byte invalid * -EPERM oas is not supported by hba * value of count on success **/ static ssize_t lpfc_oas_tgt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR(lpfc_xlane_tgt, S_IRUGO | S_IWUSR, lpfc_oas_tgt_show, lpfc_oas_tgt_store); /** * lpfc_oas_priority_show - Return wwpn of target whose luns maybe enabled for * Optimized Access Storage (OAS) operations. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * * Returns: * value of count **/ static ssize_t lpfc_oas_priority_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_oas_priority_store - Store wwpn of target whose luns maybe enabled for * Optimized Access Storage (OAS) operations. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * @count: Size of the data buffer. * * Returns: * -EINVAL count is invalid, invalid wwpn byte invalid * -EPERM oas is not supported by hba * value of count on success **/ static ssize_t lpfc_oas_priority_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR(lpfc_xlane_priority, S_IRUGO | S_IWUSR, lpfc_oas_priority_show, lpfc_oas_priority_store); /** * lpfc_oas_vpt_show - Return wwpn of vport whose targets maybe enabled * for Optimized Access Storage (OAS) operations. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * * Returns: * value of count on success **/ static ssize_t lpfc_oas_vpt_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_oas_vpt_store - Store wwpn of vport whose targets maybe enabled * for Optimized Access Storage (OAS) operations. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * @count: Size of the data buffer. * * Returns: * -EINVAL count is invalid, invalid wwpn byte invalid * -EPERM oas is not supported by hba * value of count on success **/ static ssize_t lpfc_oas_vpt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR(lpfc_xlane_vpt, S_IRUGO | S_IWUSR, lpfc_oas_vpt_show, lpfc_oas_vpt_store); /** * lpfc_oas_lun_state_show - Return the current state (enabled or disabled) * of whether luns will be enabled or disabled * for Optimized Access Storage (OAS) operations. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * * Returns: * size of formatted string. **/ static ssize_t lpfc_oas_lun_state_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_oas_lun_state_store - Store the state (enabled or disabled) * of whether luns will be enabled or disabled * for Optimized Access Storage (OAS) operations. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * @count: Size of the data buffer. * * Returns: * -EINVAL count is invalid, invalid wwpn byte invalid * -EPERM oas is not supported by hba * value of count on success **/ static ssize_t lpfc_oas_lun_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR(lpfc_xlane_lun_state, S_IRUGO | S_IWUSR, lpfc_oas_lun_state_show, lpfc_oas_lun_state_store); /** * lpfc_oas_lun_status_show - Return the status of the Optimized Access * Storage (OAS) lun returned by the * lpfc_oas_lun_show function. * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * * Returns: * size of formatted string. **/ static ssize_t lpfc_oas_lun_status_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR(lpfc_xlane_lun_status, S_IRUGO, lpfc_oas_lun_status_show, NULL); /** * lpfc_oas_lun_state_set - enable or disable a lun for Optimized Access Storage * (OAS) operations. * @phba: lpfc_hba pointer. * @vpt_wwpn: wwpn of the vport associated with the returned lun * @tgt_wwpn: wwpn of the target associated with the returned lun * @lun: the fc lun for setting oas state. * @oas_state: the oas state to be set to the lun. * @pri: priority * * Returns: * SUCCESS : 0 * -EPERM OAS is not enabled or not supported by this port. * */ static size_t lpfc_oas_lun_state_set(struct lpfc_hba *phba, uint8_t vpt_wwpn[], uint8_t tgt_wwpn[], uint64_t lun, uint32_t oas_state, uint8_t pri) { … } /** * lpfc_oas_lun_get_next - get the next lun that has been enabled for Optimized * Access Storage (OAS) operations. * @phba: lpfc_hba pointer. * @vpt_wwpn: wwpn of the vport associated with the returned lun * @tgt_wwpn: wwpn of the target associated with the returned lun * @lun_status: status of the lun returned lun * @lun_pri: priority of the lun returned lun * * Returns the first or next lun enabled for OAS operations for the vport/target * specified. If a lun is found, its vport wwpn, target wwpn and status is * returned. If the lun is not found, NOT_OAS_ENABLED_LUN is returned. * * Return: * lun that is OAS enabled for the vport/target * NOT_OAS_ENABLED_LUN when no oas enabled lun found. */ static uint64_t lpfc_oas_lun_get_next(struct lpfc_hba *phba, uint8_t vpt_wwpn[], uint8_t tgt_wwpn[], uint32_t *lun_status, uint32_t *lun_pri) { … } /** * lpfc_oas_lun_state_change - enable/disable a lun for OAS operations * @phba: lpfc_hba pointer. * @vpt_wwpn: vport wwpn by reference. * @tgt_wwpn: target wwpn by reference. * @lun: the fc lun for setting oas state. * @oas_state: the oas state to be set to the oas_lun. * @pri: priority * * This routine enables (OAS_LUN_ENABLE) or disables (OAS_LUN_DISABLE) * a lun for OAS operations. * * Return: * SUCCESS: 0 * -ENOMEM: failed to enable an lun for OAS operations * -EPERM: OAS is not enabled */ static ssize_t lpfc_oas_lun_state_change(struct lpfc_hba *phba, uint8_t vpt_wwpn[], uint8_t tgt_wwpn[], uint64_t lun, uint32_t oas_state, uint8_t pri) { … } /** * lpfc_oas_lun_show - Return oas enabled luns from a chosen target * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * * This routine returns a lun enabled for OAS each time the function * is called. * * Returns: * SUCCESS: size of formatted string. * -EFAULT: target or vport wwpn was not set properly. * -EPERM: oas is not enabled. **/ static ssize_t lpfc_oas_lun_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_oas_lun_store - Sets the OAS state for lun * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: buffer for passing information. * @count: size of the formatting string * * This function sets the OAS state for lun. Before this function is called, * the vport wwpn, target wwpn, and oas state need to be set. * * Returns: * SUCCESS: size of formatted string. * -EFAULT: target or vport wwpn was not set properly. * -EPERM: oas is not enabled. * size of formatted string. **/ static ssize_t lpfc_oas_lun_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR(lpfc_xlane_lun, S_IRUGO | S_IWUSR, lpfc_oas_lun_show, lpfc_oas_lun_store); int lpfc_enable_nvmet_cnt; unsigned long long lpfc_enable_nvmet[LPFC_NVMET_MAX_PORTS] = …; module_param_array(…); MODULE_PARM_DESC(…) …; static int lpfc_poll = …; module_param(lpfc_poll, int, S_IRUGO); MODULE_PARM_DESC(…) …; static DEVICE_ATTR_RW(lpfc_poll); int lpfc_no_hba_reset_cnt; unsigned long lpfc_no_hba_reset[MAX_HBAS_NO_RESET] = …; module_param_array(…); MODULE_PARM_DESC(…) …; LPFC_ATTR(sli_mode, 3, 3, 3, "SLI mode selector: 3 - select SLI-3"); LPFC_ATTR_R(…) …; LPFC_ATTR_R(…) …; /* * lpfc_fcp_wait_abts_rsp: Modifies criteria for reporting completion of * aborted IO. * The range is [0,1]. Default value is 0 * 0, IO completes after ABTS issued (default). * 1, IO completes after receipt of ABTS response or timeout. */ LPFC_ATTR_R(…) …; /* # lpfc_enable_rrq: Track XRI/OXID reuse after IO failures # 0x0 = disabled, XRI/OXID use not tracked. # 0x1 = XRI/OXID reuse is timed with ratov, RRQ sent. # 0x2 = XRI/OXID reuse is timed with ratov, No RRQ sent. */ LPFC_ATTR_R(…) …; /* # lpfc_suppress_link_up: Bring link up at initialization # 0x0 = bring link up (issue MBX_INIT_LINK) # 0x1 = do NOT bring link up at initialization(MBX_INIT_LINK) # 0x2 = never bring up link # Default value is 0. */ LPFC_ATTR_R(…) …; static ssize_t lpfc_pls_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR(pls, 0444, lpfc_pls_show, NULL); static ssize_t lpfc_pt_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR(pt, 0444, lpfc_pt_show, NULL); /* # lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS # 1 - (1024) # 2 - (2048) # 3 - (3072) # 4 - (4096) # 5 - (5120) */ static ssize_t lpfc_iocb_hw_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR(iocb_hw, S_IRUGO, lpfc_iocb_hw_show, NULL); static ssize_t lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR(txq_hw, S_IRUGO, lpfc_txq_hw_show, NULL); static ssize_t lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR(txcmplq_hw, S_IRUGO, lpfc_txcmplq_hw_show, NULL); /* # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear # until the timer expires. Value range is [0,255]. Default value is 30. */ static int lpfc_nodev_tmo = …; static int lpfc_devloss_tmo = …; module_param(lpfc_nodev_tmo, int, 0); MODULE_PARM_DESC(…) …; /** * lpfc_nodev_tmo_show - Return the hba dev loss timeout value * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains the dev loss timeout in decimal. * * Returns: size of formatted string. **/ static ssize_t lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_nodev_tmo_init - Set the hba nodev timeout value * @vport: lpfc vport structure pointer. * @val: contains the nodev timeout value. * * Description: * If the devloss tmo is already set then nodev tmo is set to devloss tmo, * a kernel error message is printed and zero is returned. * Else if val is in range then nodev tmo and devloss tmo are set to val. * Otherwise nodev tmo is set to the default value. * * Returns: * zero if already set or if val is in range * -EINVAL val out of range **/ static int lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val) { … } /** * lpfc_update_rport_devloss_tmo - Update dev loss tmo value * @vport: lpfc vport structure pointer. * * Description: * Update all the ndlp's dev loss tmo with the vport devloss tmo value. **/ static void lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport) { … } /** * lpfc_nodev_tmo_set - Set the vport nodev tmo and devloss tmo values * @vport: lpfc vport structure pointer. * @val: contains the tmo value. * * Description: * If the devloss tmo is already set or the vport dev loss tmo has changed * then a kernel error message is printed and zero is returned. * Else if val is in range then nodev tmo and devloss tmo are set to val. * Otherwise nodev tmo is set to the default value. * * Returns: * zero if already set or if val is in range * -EINVAL val out of range **/ static int lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val) { … } lpfc_vport_param_store(…) static DEVICE_ATTR_RW(lpfc_nodev_tmo); /* # lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that # disappear until the timer expires. Value range is [0,255]. Default # value is 30. */ module_param(lpfc_devloss_tmo, int, S_IRUGO); MODULE_PARM_DESC(…) …; lpfc_vport_param_init(…) … lpfc_vport_param_show(…) /** * lpfc_devloss_tmo_set - Sets vport nodev tmo, devloss tmo values, changed bit * @vport: lpfc vport structure pointer. * @val: contains the tmo value. * * Description: * If val is in a valid range then set the vport nodev tmo, * devloss tmo, also set the vport dev loss tmo changed flag. * Else a kernel error message is printed. * * Returns: * zero if val is in range * -EINVAL val out of range **/ static int lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val) { … } lpfc_vport_param_store(…) static DEVICE_ATTR_RW(lpfc_devloss_tmo); /* * lpfc_suppress_rsp: Enable suppress rsp feature is firmware supports it * lpfc_suppress_rsp = 0 Disable * lpfc_suppress_rsp = 1 Enable (default) * */ LPFC_ATTR_R(…) …; /* * lpfc_nvmet_mrq: Specify number of RQ pairs for processing NVMET cmds * lpfc_nvmet_mrq = 0 driver will calcualte optimal number of RQ pairs * lpfc_nvmet_mrq = 1 use a single RQ pair * lpfc_nvmet_mrq >= 2 use specified RQ pairs for MRQ * */ LPFC_ATTR_R(…) …; /* * lpfc_nvmet_mrq_post: Specify number of RQ buffer to initially post * to each NVMET RQ. Range 64 to 2048, default is 512. */ LPFC_ATTR_R(…) …; /* * lpfc_enable_fc4_type: Defines what FC4 types are supported. * Supported Values: 1 - register just FCP * 3 - register both FCP and NVME * Supported values are [1,3]. Default value is 3 */ LPFC_ATTR_R(…) …; /* # lpfc_log_verbose: Only turn this flag on if you are willing to risk being # deluged with LOTS of information. # You can set a bit mask to record specific types of verbose messages: # See lpfc_logmsh.h for definitions. */ LPFC_VPORT_ATTR_HEX_RW(…) …; /* # lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters # objects that have been registered with the nameserver after login. */ LPFC_VPORT_ATTR_R(…) …; /* # lun_queue_depth: This parameter is used to limit the number of outstanding # commands per FCP LUN. */ LPFC_VPORT_ATTR_R(…) …; /* # tgt_queue_depth: This parameter is used to limit the number of outstanding # commands per target port. Value range is [10,65535]. Default value is 65535. */ static uint lpfc_tgt_queue_depth = …; module_param(lpfc_tgt_queue_depth, uint, 0444); MODULE_PARM_DESC(…) …; lpfc_vport_param_show(tgt_queue_depth); lpfc_vport_param_init(tgt_queue_depth, LPFC_MAX_TGT_QDEPTH, LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH); /** * lpfc_tgt_queue_depth_set: Sets an attribute value. * @vport: lpfc vport structure pointer. * @val: integer attribute value. * * Description: Sets the parameter to the new value. * * Returns: * zero on success * -EINVAL if val is invalid */ static int lpfc_tgt_queue_depth_set(struct lpfc_vport *vport, uint val) { … } lpfc_vport_param_store(tgt_queue_depth); static DEVICE_ATTR_RW(lpfc_tgt_queue_depth); /* # hba_queue_depth: This parameter is used to limit the number of outstanding # commands per lpfc HBA. Value range is [32,8192]. If this parameter # value is greater than the maximum number of exchanges supported by the HBA, # then maximum number of exchanges supported by the HBA is used to determine # the hba_queue_depth. */ LPFC_ATTR_R(…) …; /* # peer_port_login: This parameter allows/prevents logins # between peer ports hosted on the same physical port. # When this parameter is set 0 peer ports of same physical port # are not allowed to login to each other. # When this parameter is set 1 peer ports of same physical port # are allowed to login to each other. # Default value of this parameter is 0. */ LPFC_VPORT_ATTR_R(…) …; /* # restrict_login: This parameter allows/prevents logins # between Virtual Ports and remote initiators. # When this parameter is not set (0) Virtual Ports will accept PLOGIs from # other initiators and will attempt to PLOGI all remote ports. # When this parameter is set (1) Virtual Ports will reject PLOGIs from # remote ports and will not attempt to PLOGI to other initiators. # This parameter does not restrict to the physical port. # This parameter does not restrict logins to Fabric resident remote ports. # Default value of this parameter is 1. */ static int lpfc_restrict_login = …; module_param(lpfc_restrict_login, int, S_IRUGO); MODULE_PARM_DESC(…) …; lpfc_vport_param_show(restrict_login); /** * lpfc_restrict_login_init - Set the vport restrict login flag * @vport: lpfc vport structure pointer. * @val: contains the restrict login value. * * Description: * If val is not in a valid range then log a kernel error message and set * the vport restrict login to one. * If the port type is physical clear the restrict login flag and return. * Else set the restrict login flag to val. * * Returns: * zero if val is in range * -EINVAL val out of range **/ static int lpfc_restrict_login_init(struct lpfc_vport *vport, int val) { … } /** * lpfc_restrict_login_set - Set the vport restrict login flag * @vport: lpfc vport structure pointer. * @val: contains the restrict login value. * * Description: * If val is not in a valid range then log a kernel error message and set * the vport restrict login to one. * If the port type is physical and the val is not zero log a kernel * error message, clear the restrict login flag and return zero. * Else set the restrict login flag to val. * * Returns: * zero if val is in range * -EINVAL val out of range **/ static int lpfc_restrict_login_set(struct lpfc_vport *vport, int val) { … } lpfc_vport_param_store(restrict_login); static DEVICE_ATTR_RW(lpfc_restrict_login); /* # Some disk devices have a "select ID" or "select Target" capability. # From a protocol standpoint "select ID" usually means select the # Fibre channel "ALPA". In the FC-AL Profile there is an "informative # annex" which contains a table that maps a "select ID" (a number # between 0 and 7F) to an ALPA. By default, for compatibility with # older drivers, the lpfc driver scans this table from low ALPA to high # ALPA. # # Turning on the scan-down variable (on = 1, off = 0) will # cause the lpfc driver to use an inverted table, effectively # scanning ALPAs from high to low. Value range is [0,1]. Default value is 1. # # (Note: This "select ID" functionality is a LOOP ONLY characteristic # and will not work across a fabric. Also this parameter will take # effect only in the case when ALPA map is not available.) */ LPFC_VPORT_ATTR_R(…) …; /* # lpfc_topology: link topology for init link # 0x0 = attempt loop mode then point-to-point # 0x01 = internal loopback mode # 0x02 = attempt point-to-point mode only # 0x04 = attempt loop mode only # 0x06 = attempt point-to-point mode then loop # Set point-to-point mode if you want to run as an N_Port. # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6]. # Default value is 0. */ LPFC_ATTR(topology, 0, 0, 6, "Select Fibre Channel topology"); /** * lpfc_topology_store - Set the adapters topology field * @dev: class device that is converted into a scsi_host. * @attr:device attribute, not used. * @buf: buffer for passing information. * @count: size of the data buffer. * * Description: * If val is in a valid range then set the adapter's topology field and * issue a lip; if the lip fails reset the topology to the old value. * * If the value is not in range log a kernel error message and return an error. * * Returns: * zero if val is in range and lip okay * non-zero return value from lpfc_issue_lip() * -EINVAL val out of range **/ static ssize_t lpfc_topology_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } lpfc_param_show(…) static DEVICE_ATTR_RW(lpfc_topology); /** * lpfc_static_vport_show: Read callback function for * lpfc_static_vport sysfs file. * @dev: Pointer to class device object. * @attr: device attribute structure. * @buf: Data buffer. * * This function is the read call back function for * lpfc_static_vport sysfs file. The lpfc_static_vport * sysfs file report the mageability of the vport. **/ static ssize_t lpfc_static_vport_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /* * Sysfs attribute to control the statistical data collection. */ static DEVICE_ATTR_RO(lpfc_static_vport); /* # lpfc_link_speed: Link speed selection for initializing the Fibre Channel # connection. # Value range is [0,16]. Default value is 0. */ /** * lpfc_link_speed_store - Set the adapters link speed * @dev: Pointer to class device. * @attr: Unused. * @buf: Data buffer. * @count: Size of the data buffer. * * Description: * If val is in a valid range then set the adapter's link speed field and * issue a lip; if the lip fails reset the link speed to the old value. * * Notes: * If the value is not in range log a kernel error message and return an error. * * Returns: * zero if val is in range and lip okay. * non-zero return value from lpfc_issue_lip() * -EINVAL val out of range **/ static ssize_t lpfc_link_speed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static int lpfc_link_speed = …; module_param(lpfc_link_speed, int, S_IRUGO); MODULE_PARM_DESC(…) …; lpfc_param_show(…) /** * lpfc_link_speed_init - Set the adapters link speed * @phba: lpfc_hba pointer. * @val: link speed value. * * Description: * If val is in a valid range then set the adapter's link speed field. * * Notes: * If the value is not in range log a kernel error message, clear the link * speed and return an error. * * Returns: * zero if val saved. * -EINVAL val out of range **/ static int lpfc_link_speed_init(struct lpfc_hba *phba, int val) { … } static DEVICE_ATTR_RW(lpfc_link_speed); /* # lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER) # 1 = aer supported and enabled (default) # PCIe error reporting is always enabled by the PCI core, so this always # shows 1. # # N.B. Parts of LPFC_ATTR open-coded since some of the underlying # infrastructure (phba->cfg_aer_support) is gone. */ static uint lpfc_aer_support = …; module_param(lpfc_aer_support, uint, S_IRUGO); MODULE_PARM_DESC(…) …; static ssize_t lpfc_aer_support_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_aer_support_store - Set the adapter for aer support * * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: containing enable or disable aer flag. * @count: unused variable. * * Description: * PCIe error reporting is enabled by the PCI core, so drivers don't need * to do anything. Retain this interface for backwards compatibility, * but do nothing. * * Returns: * length of the buf on success * -EINVAL if val out of range **/ static ssize_t lpfc_aer_support_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(lpfc_aer_support); /** * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: containing flag 1 for aer cleanup state. * @count: unused variable. * * Description: * If the @buf contains 1, invokes the kernel AER helper routine * pci_aer_clear_nonfatal_status() to clean up the uncorrectable * error status register. * * Notes: * * Returns: * -EINVAL if the buf does not contain 1 * -EPERM if the OS cannot clear AER error status, i.e., when platform * firmware owns the AER Capability **/ static ssize_t lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL, lpfc_aer_cleanup_state); /** * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions * * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: containing the string the number of vfs to be enabled. * @count: unused variable. * * Description: * When this api is called either through user sysfs, the driver shall * try to enable or disable SR-IOV virtual functions according to the * following: * * If zero virtual function has been enabled to the physical function, * the driver shall invoke the pci enable virtual function api trying * to enable the virtual functions. If the nr_vfn provided is greater * than the maximum supported, the maximum virtual function number will * be used for invoking the api; otherwise, the nr_vfn provided shall * be used for invoking the api. If the api call returned success, the * actual number of virtual functions enabled will be set to the driver * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver * cfg_sriov_nr_virtfn remains zero. * * If none-zero virtual functions have already been enabled to the * physical function, as reflected by the driver's cfg_sriov_nr_virtfn, * -EINVAL will be returned and the driver does nothing; * * If the nr_vfn provided is zero and none-zero virtual functions have * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the * disabling virtual function api shall be invoded to disable all the * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to * zero. Otherwise, if zero virtual function has been enabled, do * nothing. * * Returns: * length of the buf on success if val is in range the intended mode * is supported. * -EINVAL if val out of range or intended mode is not supported. **/ static ssize_t lpfc_sriov_nr_virtfn_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } LPFC_ATTR(sriov_nr_virtfn, LPFC_DEF_VFN_PER_PFN, 0, LPFC_MAX_VFN_PER_PFN, "Enable PCIe device SR-IOV virtual fn"); lpfc_param_show(…) static DEVICE_ATTR_RW(lpfc_sriov_nr_virtfn); /** * lpfc_request_firmware_upgrade_store - Request for Linux generic firmware upgrade * * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: containing the string the number of vfs to be enabled. * @count: unused variable. * * Description: * * Returns: * length of the buf on success if val is in range the intended mode * is supported. * -EINVAL if val out of range or intended mode is not supported. **/ static ssize_t lpfc_request_firmware_upgrade_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static int lpfc_req_fw_upgrade; module_param(lpfc_req_fw_upgrade, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(…) …; lpfc_param_show(…) /** * lpfc_request_firmware_upgrade_init - Enable initial linux generic fw upgrade * @phba: lpfc_hba pointer. * @val: 0 or 1. * * Description: * Set the initial Linux generic firmware upgrade enable or disable flag. * * Returns: * zero if val saved. * -EINVAL val out of range **/ static int lpfc_request_firmware_upgrade_init(struct lpfc_hba *phba, int val) { … } static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR, lpfc_request_firmware_upgrade_show, lpfc_request_firmware_upgrade_store); /** * lpfc_force_rscn_store * * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: unused string * @count: unused variable. * * Description: * Force the switch to send a RSCN to all other NPorts in our zone * If we are direct connect pt2pt, build the RSCN command ourself * and send to the other NPort. Not supported for private loop. * * Returns: * 0 - on success * -EIO - if command is not sent **/ static ssize_t lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } /* * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts * connected to the HBA. * * Value range is any ascii value */ static int lpfc_force_rscn; module_param(lpfc_force_rscn, int, 0644); MODULE_PARM_DESC(…) …; lpfc_param_show(…) /** * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts * @phba: lpfc_hba pointer. * @val: unused value. * * Returns: * zero if val saved. **/ static int lpfc_force_rscn_init(struct lpfc_hba *phba, int val) { … } static DEVICE_ATTR_RW(lpfc_force_rscn); /** * lpfc_fcp_imax_store * * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: string with the number of fast-path FCP interrupts per second. * @count: unused variable. * * Description: * If val is in a valid range [636,651042], then set the adapter's * maximum number of fast-path FCP interrupts per second. * * Returns: * length of the buf on success if val is in range the intended mode * is supported. * -EINVAL if val out of range or intended mode is not supported. **/ static ssize_t lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } /* # lpfc_fcp_imax: The maximum number of fast-path FCP interrupts per second # for the HBA. # # Value range is [5,000 to 5,000,000]. Default value is 50,000. */ static int lpfc_fcp_imax = …; module_param(lpfc_fcp_imax, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(…) …; lpfc_param_show(…) /** * lpfc_fcp_imax_init - Set the initial sr-iov virtual function enable * @phba: lpfc_hba pointer. * @val: link speed value. * * Description: * If val is in a valid range [636,651042], then initialize the adapter's * maximum number of fast-path FCP interrupts per second. * * Returns: * zero if val saved. * -EINVAL val out of range **/ static int lpfc_fcp_imax_init(struct lpfc_hba *phba, int val) { … } static DEVICE_ATTR_RW(lpfc_fcp_imax); /** * lpfc_cq_max_proc_limit_store * * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: string with the cq max processing limit of cqes * @count: unused variable. * * Description: * If val is in a valid range, then set value on each cq * * Returns: * The length of the buf: if successful * -ERANGE: if val is not in the valid range * -EINVAL: if bad value format or intended mode is not supported. **/ static ssize_t lpfc_cq_max_proc_limit_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } /* * lpfc_cq_max_proc_limit: The maximum number CQE entries processed in an * itteration of CQ processing. */ static int lpfc_cq_max_proc_limit = …; module_param(lpfc_cq_max_proc_limit, int, 0644); MODULE_PARM_DESC(…) …; lpfc_param_show(…) /* * lpfc_cq_poll_threshold: Set the threshold of CQE completions in a * single handler call which should request a polled completion rather * than re-enabling interrupts. */ LPFC_ATTR_RW(…) …; /** * lpfc_cq_max_proc_limit_init - Set the initial cq max_proc_limit * @phba: lpfc_hba pointer. * @val: entry limit * * Description: * If val is in a valid range, then initialize the adapter's maximum * value. * * Returns: * Always returns 0 for success, even if value not always set to * requested value. If value out of range or not supported, will fall * back to default. **/ static int lpfc_cq_max_proc_limit_init(struct lpfc_hba *phba, int val) { … } static DEVICE_ATTR_RW(lpfc_cq_max_proc_limit); /** * lpfc_fcp_cpu_map_show - Display current driver CPU affinity * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains text describing the state of the link. * * Returns: size of formatted string. **/ static ssize_t lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * lpfc_fcp_cpu_map_store - Change CPU affinity of driver vectors * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. * @buf: one or more lpfc_polling_flags values. * @count: not used. * * Returns: * -EINVAL - Not implemented yet. **/ static ssize_t lpfc_fcp_cpu_map_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } /* # lpfc_fcp_cpu_map: Defines how to map CPUs to IRQ vectors # for the HBA. # # Value range is [0 to 1]. Default value is LPFC_HBA_CPU_MAP (1). # 0 - Do not affinitze IRQ vectors # 1 - Affintize HBA vectors with respect to each HBA # (start with CPU0 for each HBA) # This also defines how Hardware Queues are mapped to specific CPUs. */ static int lpfc_fcp_cpu_map = …; module_param(lpfc_fcp_cpu_map, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(…) …; /** * lpfc_fcp_cpu_map_init - Set the initial sr-iov virtual function enable * @phba: lpfc_hba pointer. * @val: link speed value. * * Description: * If val is in a valid range [0-2], then affinitze the adapter's * MSIX vectors. * * Returns: * zero if val saved. * -EINVAL val out of range **/ static int lpfc_fcp_cpu_map_init(struct lpfc_hba *phba, int val) { … } static DEVICE_ATTR_RW(lpfc_fcp_cpu_map); /* # lpfc_fcp_class: Determines FC class to use for the FCP protocol. # Value range is [2,3]. Default value is 3. */ LPFC_VPORT_ATTR_R(…) …; /* # lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range # is [0,1]. Default value is 1. */ LPFC_VPORT_ATTR_RW(…) …; /* # lpfc_first_burst_size: First burst size to use on the NPorts # that support first burst. # Value range is [0,65536]. Default value is 0. */ LPFC_VPORT_ATTR_RW(…) …; /* * lpfc_nvmet_fb_size: NVME Target mode supported first burst size. * When the driver is configured as an NVME target, this value is * communicated to the NVME initiator in the PRLI response. It is * used only when the lpfc_nvme_enable_fb and lpfc_nvmet_support * parameters are set and the target is sending the PRLI RSP. * Parameter supported on physical port only - no NPIV support. * Value range is [0,65536]. Default value is 0. */ LPFC_ATTR_RW(…) …; /* * lpfc_nvme_enable_fb: Enable NVME first burst on I and T functions. * For the Initiator (I), enabling this parameter means that an NVMET * PRLI response with FBA enabled and an FB_SIZE set to a nonzero value will be * processed by the initiator for subsequent NVME FCP IO. * Currently, this feature is not supported on the NVME target * Value range is [0,1]. Default value is 0 (disabled). */ LPFC_ATTR_RW(…) …; /* # lpfc_max_scsicmpl_time: Use scsi command completion time to control I/O queue # depth. Default value is 0. When the value of this parameter is zero the # SCSI command completion time is not used for controlling I/O queue depth. When # the parameter is set to a non-zero value, the I/O queue depth is controlled # to limit the I/O completion time to the parameter value. # The value is set in milliseconds. */ LPFC_VPORT_ATTR(max_scsicmpl_time, 0, 0, 60000, "Use command completion time to control queue depth"); lpfc_vport_param_show(max_scsicmpl_time); static int lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val) { … } lpfc_vport_param_store(max_scsicmpl_time); static DEVICE_ATTR_RW(lpfc_max_scsicmpl_time); /* # lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value # range is [0,1]. Default value is 0. */ LPFC_ATTR_R(…) …; /* # lpfc_xri_rebalancing: enable or disable XRI rebalancing feature # range is [0,1]. Default value is 1. */ LPFC_ATTR_R(…) …; /* * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds * range is [0,1]. Default value is 0. * For [0], FCP commands are issued to Work Queues based on upper layer * hardware queue index. * For [1], FCP commands are issued to a Work Queue associated with the * current CPU. * * LPFC_FCP_SCHED_BY_HDWQ == 0 * LPFC_FCP_SCHED_BY_CPU == 1 * * The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu * affinity for FCP/NVME I/Os through Work Queues associated with the current * CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os * through WQs will be used. */ LPFC_ATTR_RW(…) …; /* * lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN * range is [0,1]. Default value is 0. * For [0], GID_FT is used for NameServer queries after RSCN (default) * For [1], GID_PT is used for NameServer queries after RSCN * */ LPFC_ATTR_RW(…) …; /* # lpfc_fcp2_no_tgt_reset: Determine bus reset behavior # range is [0,1]. Default value is 0. # For [0], bus reset issues target reset to ALL devices # For [1], bus reset issues target reset to non-FCP2 devices */ LPFC_ATTR_RW(…) …; /* # lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing # cr_delay (msec) or cr_count outstanding commands. cr_delay can take # value [0,63]. cr_count can take value [1,255]. Default value of cr_delay # is 0. Default value of cr_count is 1. The cr_count feature is disabled if # cr_delay is set to 0. */ LPFC_ATTR_RW(…) …; LPFC_ATTR_RW(…) …; /* # lpfc_multi_ring_support: Determines how many rings to spread available # cmd/rsp IOCB entries across. # Value range is [1,2]. Default value is 1. */ LPFC_ATTR_R(…) …; /* # lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this # identifies what rctl value to configure the additional ring for. # Value range is [1,0xff]. Default value is 4 (Unsolicated Data). */ LPFC_ATTR_R(…) …; /* # lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this # identifies what type value to configure the additional ring for. # Value range is [1,0xff]. Default value is 5 (LLC/SNAP). */ LPFC_ATTR_R(…) …; /* # lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN # 0 = SmartSAN functionality disabled (default) # 1 = SmartSAN functionality enabled # This parameter will override the value of lpfc_fdmi_on module parameter. # Value range is [0,1]. Default value is 0. */ LPFC_ATTR_R(…) …; /* # lpfc_fdmi_on: Controls FDMI support. # 0 No FDMI support # 1 Traditional FDMI support (default) # Traditional FDMI support means the driver will assume FDMI-2 support; # however, if that fails, it will fallback to FDMI-1. # If lpfc_enable_SmartSAN is set to 1, the driver ignores lpfc_fdmi_on. # If lpfc_enable_SmartSAN is set 0, the driver uses the current value of # lpfc_fdmi_on. # Value range [0,1]. Default value is 1. */ LPFC_ATTR_R(…) …; /* # Specifies the maximum number of ELS cmds we can have outstanding (for # discovery). Value range is [1,64]. Default value = 32. */ LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " "during discovery"); /* # lpfc_max_luns: maximum allowed LUN ID. This is the highest LUN ID that # will be scanned by the SCSI midlayer when sequential scanning is # used; and is also the highest LUN ID allowed when the SCSI midlayer # parses REPORT_LUN responses. The lpfc driver has no LUN count or # LUN ID limit, but the SCSI midlayer requires this field for the uses # above. The lpfc driver limits the default value to 255 for two reasons. # As it bounds the sequential scan loop, scanning for thousands of luns # on a target can take minutes of wall clock time. Additionally, # there are FC targets, such as JBODs, that only recognize 8-bits of # LUN ID. When they receive a value greater than 8 bits, they chop off # the high order bits. In other words, they see LUN IDs 0, 256, 512, # and so on all as LUN ID 0. This causes the linux kernel, which sees # valid responses at each of the LUN IDs, to believe there are multiple # devices present, when in fact, there is only 1. # A customer that is aware of their target behaviors, and the results as # indicated above, is welcome to increase the lpfc_max_luns value. # As mentioned, this value is not used by the lpfc driver, only the # SCSI midlayer. # Value range is [0,65535]. Default value is 255. # NOTE: The SCSI layer might probe all allowed LUN on some old targets. */ LPFC_VPORT_ULL_ATTR_R(…) …; /* # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring. # Value range is [1,255], default value is 10. */ LPFC_ATTR_RW(…) …; /* # lpfc_task_mgmt_tmo: Maximum time to wait for task management commands # to complete in seconds. Value range is [5,180], default value is 60. */ LPFC_ATTR_RW(…) …; /* # lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that # support this feature # 0 = MSI disabled # 1 = MSI enabled # 2 = MSI-X enabled (default) # Value range is [0,2]. Default value is 2. */ LPFC_ATTR_R(…) …; /* * lpfc_nvme_oas: Use the oas bit when sending NVME/NVMET IOs * * 0 = NVME OAS disabled * 1 = NVME OAS enabled * * Value range is [0,1]. Default value is 0. */ LPFC_ATTR_RW(…) …; /* * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs * * 0 = Put NVME Command in SGL * 1 = Embed NVME Command in WQE (unless G7) * 2 = Embed NVME Command in WQE (force) * * Value range is [0,2]. Default value is 1. */ LPFC_ATTR_RW(…) …; /* * lpfc_fcp_mq_threshold: Set the maximum number of Hardware Queues * the driver will advertise it supports to the SCSI layer. * * 0 = Set nr_hw_queues by the number of CPUs or HW queues. * 1,256 = Manually specify nr_hw_queue value to be advertised, * * Value range is [0,256]. Default value is 8. */ LPFC_ATTR_R(…) …; /* * lpfc_hdw_queue: Set the number of Hardware Queues the driver * will advertise it supports to the NVME and SCSI layers. This also * will map to the number of CQ/WQ pairs the driver will create. * * The NVME Layer will try to create this many, plus 1 administrative * hardware queue. The administrative queue will always map to WQ 0 * A hardware IO queue maps (qidx) to a specific driver CQ/WQ. * * 0 = Configure the number of hdw queues to the number of active CPUs. * 1,256 = Manually specify how many hdw queues to use. * * Value range is [0,256]. Default value is 0. */ LPFC_ATTR_R(…) …; #if IS_ENABLED(CONFIG_X86) /** * lpfc_cpumask_irq_mode_init - initalizes cpumask of phba based on * irq_chann_mode * @phba: Pointer to HBA context object. **/ static void lpfc_cpumask_irq_mode_init(struct lpfc_hba *phba) { … } #endif static void lpfc_assign_default_irq_chann(struct lpfc_hba *phba) { … } /* * lpfc_irq_chann: Set the number of IRQ vectors that are available * for Hardware Queues to utilize. This also will map to the number * of EQ / MSI-X vectors the driver will create. This should never be * more than the number of Hardware Queues * * 0 = Configure number of IRQ Channels to: * if AMD architecture, number of CPUs on HBA's NUMA node * if Intel architecture, number of physical CPUs. * otherwise, number of active CPUs. * [1,256] = Manually specify how many IRQ Channels to use. * * Value range is [0,256]. Default value is [0]. */ static uint lpfc_irq_chann = …; module_param(lpfc_irq_chann, uint, 0444); MODULE_PARM_DESC(…) …; /* lpfc_irq_chann_init - Set the hba irq_chann initial value * @phba: lpfc_hba pointer. * @val: contains the initial value * * Description: * Validates the initial value is within range and assigns it to the * adapter. If not in range, an error message is posted and the * default value is assigned. * * Returns: * zero if value is in range and is set * -EINVAL if value was out of range **/ static int lpfc_irq_chann_init(struct lpfc_hba *phba, uint32_t val) { … } /** * lpfc_irq_chann_show - Display value of irq_chann * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains a string with the list sizes * * Returns: size of formatted string. **/ static ssize_t lpfc_irq_chann_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(lpfc_irq_chann); /* # lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware. # 0 = HBA resets disabled # 1 = HBA resets enabled (default) # 2 = HBA reset via PCI bus reset enabled # Value range is [0,2]. Default value is 1. */ LPFC_ATTR_RW(…) …; /* # lpfc_enable_hba_heartbeat: Disable HBA heartbeat timer.. # 0 = HBA Heartbeat disabled # 1 = HBA Heartbeat enabled (default) # Value range is [0,1]. Default value is 1. */ LPFC_ATTR_R(…) …; /* # lpfc_EnableXLane: Enable Express Lane Feature # 0x0 Express Lane Feature disabled # 0x1 Express Lane Feature enabled # Value range is [0,1]. Default value is 0. */ LPFC_ATTR_R(…) …; /* # lpfc_XLanePriority: Define CS_CTL priority for Express Lane Feature # 0x0 - 0x7f = CS_CTL field in FC header (high 7 bits) # Value range is [0x0,0x7f]. Default value is 0 */ LPFC_ATTR_RW(…) …; /* # lpfc_enable_bg: Enable BlockGuard (Emulex's Implementation of T10-DIF) # 0 = BlockGuard disabled (default) # 1 = BlockGuard enabled # Value range is [0,1]. Default value is 0. */ LPFC_ATTR_R(…) …; /* # lpfc_prot_mask: # - Bit mask of host protection capabilities used to register with the # SCSI mid-layer # - Only meaningful if BG is turned on (lpfc_enable_bg=1). # - Allows you to ultimately specify which profiles to use # - Default will result in registering capabilities for all profiles. # - SHOST_DIF_TYPE1_PROTECTION 1 # HBA supports T10 DIF Type 1: HBA to Target Type 1 Protection # - SHOST_DIX_TYPE0_PROTECTION 8 # HBA supports DIX Type 0: Host to HBA protection only # - SHOST_DIX_TYPE1_PROTECTION 16 # HBA supports DIX Type 1: Host to HBA Type 1 protection # */ LPFC_ATTR(prot_mask, (SHOST_DIF_TYPE1_PROTECTION | SHOST_DIX_TYPE0_PROTECTION | SHOST_DIX_TYPE1_PROTECTION), 0, (SHOST_DIF_TYPE1_PROTECTION | SHOST_DIX_TYPE0_PROTECTION | SHOST_DIX_TYPE1_PROTECTION), "T10-DIF host protection capabilities mask"); /* # lpfc_prot_guard: # - Bit mask of protection guard types to register with the SCSI mid-layer # - Guard types are currently either 1) T10-DIF CRC 2) IP checksum # - Allows you to ultimately specify which profiles to use # - Default will result in registering capabilities for all guard types # */ LPFC_ATTR(prot_guard, SHOST_DIX_GUARD_IP, SHOST_DIX_GUARD_CRC, SHOST_DIX_GUARD_IP, "T10-DIF host protection guard type"); /* * Delay initial NPort discovery when Clean Address bit is cleared in * FLOGI/FDISC accept and FCID/Fabric name/Fabric portname is changed. * This parameter can have value 0 or 1. * When this parameter is set to 0, no delay is added to the initial * discovery. * When this parameter is set to non-zero value, initial Nport discovery is * delayed by ra_tov seconds when Clean Address bit is cleared in FLOGI/FDISC * accept and FCID/Fabric name/Fabric portname is changed. * Driver always delay Nport discovery for subsequent FLOGI/FDISC completion * when Clean Address bit is cleared in FLOGI/FDISC * accept and FCID/Fabric name/Fabric portname is changed. * Default value is 0. */ LPFC_ATTR(delay_discovery, 0, 0, 1, "Delay NPort discovery when Clean Address bit is cleared."); /* * lpfc_sg_seg_cnt - Initial Maximum DMA Segment Count * This value can be set to values between 64 and 4096. The default value * is 64, but may be increased to allow for larger Max I/O sizes. The scsi * and nvme layers will allow I/O sizes up to (MAX_SEG_COUNT * SEG_SIZE). * Because of the additional overhead involved in setting up T10-DIF, * this parameter will be limited to 128 if BlockGuard is enabled under SLI4 * and will be limited to 512 if BlockGuard is enabled under SLI3. */ static uint lpfc_sg_seg_cnt = …; module_param(lpfc_sg_seg_cnt, uint, 0444); MODULE_PARM_DESC(…) …; /** * lpfc_sg_seg_cnt_show - Display the scatter/gather list sizes * configured for the adapter * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains a string with the list sizes * * Returns: size of formatted string. **/ static ssize_t lpfc_sg_seg_cnt_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(lpfc_sg_seg_cnt); /** * lpfc_sg_seg_cnt_init - Set the hba sg_seg_cnt initial value * @phba: lpfc_hba pointer. * @val: contains the initial value * * Description: * Validates the initial value is within range and assigns it to the * adapter. If not in range, an error message is posted and the * default value is assigned. * * Returns: * zero if value is in range and is set * -EINVAL if value was out of range **/ static int lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val) { … } /* * lpfc_enable_mds_diags: Enable MDS Diagnostics * 0 = MDS Diagnostics disabled (default) * 1 = MDS Diagnostics enabled * Value range is [0,1]. Default value is 0. */ LPFC_ATTR_RW(…) …; /* * lpfc_ras_fwlog_buffsize: Firmware logging host buffer size * 0 = Disable firmware logging (default) * [1-4] = Multiple of 1/4th Mb of host memory for FW logging * Value range [0..4]. Default value is 0 */ LPFC_ATTR(ras_fwlog_buffsize, 0, 0, 4, "Host memory for FW logging"); lpfc_param_show(ras_fwlog_buffsize); static ssize_t lpfc_ras_fwlog_buffsize_set(struct lpfc_hba *phba, uint val) { … } lpfc_param_store(ras_fwlog_buffsize); static DEVICE_ATTR_RW(lpfc_ras_fwlog_buffsize); /* * lpfc_ras_fwlog_level: Firmware logging verbosity level * Valid only if firmware logging is enabled * 0(Least Verbosity) 4 (most verbosity) * Value range is [0..4]. Default value is 0 */ LPFC_ATTR_RW(…) …; /* * lpfc_ras_fwlog_func: Firmware logging enabled on function number * Default function which has RAS support : 0 * Value Range is [0..3]. * FW logging is a global action and enablement is via a specific * port. */ LPFC_ATTR_RW(…) …; /* * lpfc_enable_bbcr: Enable BB Credit Recovery * 0 = BB Credit Recovery disabled * 1 = BB Credit Recovery enabled (default) * Value range is [0,1]. Default value is 1. */ LPFC_BBCR_ATTR_RW(…) …; /* Signaling module parameters */ int lpfc_fabric_cgn_frequency = …; /* 100 ms default */ module_param(lpfc_fabric_cgn_frequency, int, 0444); MODULE_PARM_DESC(…) …; unsigned char lpfc_acqe_cgn_frequency = …; /* 10 sec default */ module_param(lpfc_acqe_cgn_frequency, byte, 0444); MODULE_PARM_DESC(…) …; int lpfc_use_cgn_signal = …; /* 0 - only use FPINs, 1 - Use signals if avail */ module_param(lpfc_use_cgn_signal, int, 0444); MODULE_PARM_DESC(…) …; /* * lpfc_enable_dpp: Enable DPP on G7 * 0 = DPP on G7 disabled * 1 = DPP on G7 enabled (default) * Value range is [0,1]. Default value is 1. */ LPFC_ATTR_RW(…) …; /* * lpfc_enable_mi: Enable FDMI MIB * 0 = disabled * 1 = enabled (default) * Value range is [0,1]. */ LPFC_ATTR_R(…) …; /* * lpfc_max_vmid: Maximum number of VMs to be tagged. This is valid only if * either vmid_app_header or vmid_priority_tagging is enabled. * 4 - 255 = vmid support enabled for 4-255 VMs * Value range is [4,255]. */ LPFC_ATTR_R(…) …; /* * lpfc_vmid_inactivity_timeout: Inactivity timeout duration in hours * 0 = Timeout is disabled * Value range is [0,24]. */ LPFC_ATTR_R(…) …; /* * lpfc_vmid_app_header: Enable App Header VMID support * 0 = Support is disabled (default) * 1 = Support is enabled * Value range is [0,1]. */ LPFC_ATTR_R(…) …; /* * lpfc_vmid_priority_tagging: Enable Priority Tagging VMID support * 0 = Support is disabled (default) * 1 = Allow supported targets only * 2 = Allow all targets * Value range is [0,2]. */ LPFC_ATTR_R(…) …; static struct attribute *lpfc_hba_attrs[] = …; static const struct attribute_group lpfc_hba_attr_group = …; const struct attribute_group *lpfc_hba_groups[] = …; static struct attribute *lpfc_vport_attrs[] = …; static const struct attribute_group lpfc_vport_attr_group = …; const struct attribute_group *lpfc_vport_groups[] = …; /** * sysfs_ctlreg_write - Write method for writing to ctlreg * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: contains the data to be written to the adapter IOREG space. * @off: offset into buffer to beginning of data. * @count: bytes to transfer. * * Description: * Accessed via /sys/class/scsi_host/hostxxx/ctlreg. * Uses the adapter io control registers to send buf contents to the adapter. * * Returns: * -ERANGE off and count combo out of range * -EINVAL off, count or buff address invalid * -EPERM adapter is offline * value of count, buf contents written **/ static ssize_t sysfs_ctlreg_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { … } /** * sysfs_ctlreg_read - Read method for reading from ctlreg * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: if successful contains the data from the adapter IOREG space. * @off: offset into buffer to beginning of data. * @count: bytes to transfer. * * Description: * Accessed via /sys/class/scsi_host/hostxxx/ctlreg. * Uses the adapter io control registers to read data into buf. * * Returns: * -ERANGE off and count combo out of range * -EINVAL off, count or buff address invalid * value of count, buf contents read **/ static ssize_t sysfs_ctlreg_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { … } static struct bin_attribute sysfs_ctlreg_attr = …; /** * sysfs_mbox_write - Write method for writing information via mbox * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: contains the data to be written to sysfs mbox. * @off: offset into buffer to beginning of data. * @count: bytes to transfer. * * Description: * Deprecated function. All mailbox access from user space is performed via the * bsg interface. * * Returns: * -EPERM operation not permitted **/ static ssize_t sysfs_mbox_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { … } /** * sysfs_mbox_read - Read method for reading information via mbox * @filp: open sysfs file * @kobj: kernel kobject that contains the kernel class device. * @bin_attr: kernel attributes passed to us. * @buf: contains the data to be read from sysfs mbox. * @off: offset into buffer to beginning of data. * @count: bytes to transfer. * * Description: * Deprecated function. All mailbox access from user space is performed via the * bsg interface. * * Returns: * -EPERM operation not permitted **/ static ssize_t sysfs_mbox_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { … } static struct bin_attribute sysfs_mbox_attr = …; /** * lpfc_alloc_sysfs_attr - Creates the ctlreg and mbox entries * @vport: address of lpfc vport structure. * * Return codes: * zero on success * error return code from sysfs_create_bin_file() **/ int lpfc_alloc_sysfs_attr(struct lpfc_vport *vport) { … } /** * lpfc_free_sysfs_attr - Removes the ctlreg and mbox entries * @vport: address of lpfc vport structure. **/ void lpfc_free_sysfs_attr(struct lpfc_vport *vport) { … } /* * Dynamic FC Host Attributes Support */ /** * lpfc_get_host_symbolic_name - Copy symbolic name into the scsi host * @shost: kernel scsi host pointer. **/ static void lpfc_get_host_symbolic_name(struct Scsi_Host *shost) { … } /** * lpfc_get_host_port_id - Copy the vport DID into the scsi host port id * @shost: kernel scsi host pointer. **/ static void lpfc_get_host_port_id(struct Scsi_Host *shost) { … } /** * lpfc_get_host_port_type - Set the value of the scsi host port type * @shost: kernel scsi host pointer. **/ static void lpfc_get_host_port_type(struct Scsi_Host *shost) { … } /** * lpfc_get_host_port_state - Set the value of the scsi host port state * @shost: kernel scsi host pointer. **/ static void lpfc_get_host_port_state(struct Scsi_Host *shost) { … } /** * lpfc_get_host_speed - Set the value of the scsi host speed * @shost: kernel scsi host pointer. **/ static void lpfc_get_host_speed(struct Scsi_Host *shost) { … } /** * lpfc_get_host_fabric_name - Set the value of the scsi host fabric name * @shost: kernel scsi host pointer. **/ static void lpfc_get_host_fabric_name (struct Scsi_Host *shost) { … } /** * lpfc_get_stats - Return statistical information about the adapter * @shost: kernel scsi host pointer. * * Notes: * NULL on error for link down, no mbox pool, sli2 active, * management not allowed, memory allocation error, or mbox error. * * Returns: * NULL for error * address of the adapter host statistics **/ static struct fc_host_statistics * lpfc_get_stats(struct Scsi_Host *shost) { … } /** * lpfc_reset_stats - Copy the adapter link stats information * @shost: kernel scsi host pointer. **/ static void lpfc_reset_stats(struct Scsi_Host *shost) { … } /* * The LPFC driver treats linkdown handling as target loss events so there * are no sysfs handlers for link_down_tmo. */ /** * lpfc_get_node_by_target - Return the nodelist for a target * @starget: kernel scsi target pointer. * * Returns: * address of the node list if found * NULL target not found **/ static struct lpfc_nodelist * lpfc_get_node_by_target(struct scsi_target *starget) { … } /** * lpfc_get_starget_port_id - Set the target port id to the ndlp DID or -1 * @starget: kernel scsi target pointer. **/ static void lpfc_get_starget_port_id(struct scsi_target *starget) { … } /** * lpfc_get_starget_node_name - Set the target node name * @starget: kernel scsi target pointer. * * Description: Set the target node name to the ndlp node name wwn or zero. **/ static void lpfc_get_starget_node_name(struct scsi_target *starget) { … } /** * lpfc_get_starget_port_name - Set the target port name * @starget: kernel scsi target pointer. * * Description: set the target port name to the ndlp port name wwn or zero. **/ static void lpfc_get_starget_port_name(struct scsi_target *starget) { … } /** * lpfc_set_rport_loss_tmo - Set the rport dev loss tmo * @rport: fc rport address. * @timeout: new value for dev loss tmo. * * Description: * If timeout is non zero set the dev_loss_tmo to timeout, else set * dev_loss_tmo to one. **/ static void lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) { … } /* * lpfc_rport_show_function - Return rport target information * * Description: * Macro that uses field to generate a function with the name lpfc_show_rport_ * * lpfc_show_rport_##field: returns the bytes formatted in buf * @cdev: class converted to an fc_rport. * @buf: on return contains the target_field or zero. * * Returns: size of formatted string. **/ #define lpfc_rport_show_function(field, format_string, sz, cast) … #define lpfc_rport_rd_attr(field, format_string, sz) … /** * lpfc_set_vport_symbolic_name - Set the vport's symbolic name * @fc_vport: The fc_vport who's symbolic name has been changed. * * Description: * This function is called by the transport after the @fc_vport's symbolic name * has been changed. This function re-registers the symbolic name with the * switch to propagate the change into the fabric if the vport is active. **/ static void lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport) { … } /** * lpfc_hba_log_verbose_init - Set hba's log verbose level * @phba: Pointer to lpfc_hba struct. * @verbose: Verbose level to set. * * This function is called by the lpfc_get_cfgparam() routine to set the * module lpfc_log_verbose into the @phba cfg_log_verbose for use with * log message according to the module's lpfc_log_verbose parameter setting * before hba port or vport created. **/ static void lpfc_hba_log_verbose_init(struct lpfc_hba *phba, uint32_t verbose) { … } struct fc_function_template lpfc_transport_functions = …; struct fc_function_template lpfc_vport_transport_functions = …; /** * lpfc_get_hba_function_mode - Used to determine the HBA function in FCoE * Mode * @phba: lpfc_hba pointer. **/ static void lpfc_get_hba_function_mode(struct lpfc_hba *phba) { … } /** * lpfc_get_cfgparam - Used during probe_one to init the adapter structure * @phba: lpfc_hba pointer. **/ void lpfc_get_cfgparam(struct lpfc_hba *phba) { … } /** * lpfc_nvme_mod_param_dep - Adjust module parameter value based on * dependencies between protocols and roles. * @phba: lpfc_hba pointer. **/ void lpfc_nvme_mod_param_dep(struct lpfc_hba *phba) { … } /** * lpfc_get_vport_cfgparam - Used during port create, init the vport structure * @vport: lpfc_vport pointer. **/ void lpfc_get_vport_cfgparam(struct lpfc_vport *vport) { … }