/* * Management Module Support for MPT (Message Passing Technology) based * controllers * * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.c * Copyright (C) 2012-2014 LSI Corporation * Copyright (C) 2013-2014 Avago Technologies * (mailto: [email protected]) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * NO WARRANTY * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is * solely responsible for determining the appropriateness of using and * distributing the Program and assumes all risks associated with its * exercise of rights under this Agreement, including but not limited to * the risks and costs of program errors, damage to or loss of data, * programs or equipment, and unavailability or interruption of operations. * DISCLAIMER OF LIABILITY * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/types.h> #include <linux/pci.h> #include <linux/delay.h> #include <linux/compat.h> #include <linux/poll.h> #include <linux/io.h> #include <linux/uaccess.h> #include "mpt3sas_base.h" #include "mpt3sas_ctl.h" static struct fasync_struct *async_queue; static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait); /** * enum block_state - blocking state * @NON_BLOCKING: non blocking * @BLOCKING: blocking * * These states are for ioctls that need to wait for a response * from firmware, so they probably require sleep. */ enum block_state { … }; /** * _ctl_display_some_debug - debug routine * @ioc: per adapter object * @smid: system request message index * @calling_function_name: string pass from calling function * @mpi_reply: reply message frame * Context: none. * * Function for displaying debug info helpful when debugging issues * in this module. */ static void _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, char *calling_function_name, MPI2DefaultReply_t *mpi_reply) { … } /** * mpt3sas_ctl_done - ctl module completion routine * @ioc: per adapter object * @smid: system request message index * @msix_index: MSIX table index supplied by the OS * @reply: reply message frame(lower 32bit addr) * Context: none. * * The callback handler when using ioc->ctl_cb_idx. * * Return: 1 meaning mf should be freed from _base_interrupt * 0 means the mf is freed from this function. */ u8 mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) { … } /** * _ctl_check_event_type - determines when an event needs logging * @ioc: per adapter object * @event: firmware event * * The bitmask in ioc->event_type[] indicates which events should be * be saved in the driver event_log. This bitmask is set by application. * * Return: 1 when event should be captured, or zero means no match. */ static int _ctl_check_event_type(struct MPT3SAS_ADAPTER *ioc, u16 event) { … } /** * mpt3sas_ctl_add_to_event_log - add event * @ioc: per adapter object * @mpi_reply: reply message frame */ void mpt3sas_ctl_add_to_event_log(struct MPT3SAS_ADAPTER *ioc, Mpi2EventNotificationReply_t *mpi_reply) { … } /** * mpt3sas_ctl_event_callback - firmware event handler (called at ISR time) * @ioc: per adapter object * @msix_index: MSIX table index supplied by the OS * @reply: reply message frame(lower 32bit addr) * Context: interrupt. * * This function merely adds a new work task into ioc->firmware_event_thread. * The tasks are worked from _firmware_event_work in user context. * * Return: 1 meaning mf should be freed from _base_interrupt * 0 means the mf is freed from this function. */ u8 mpt3sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply) { … } /** * _ctl_verify_adapter - validates ioc_number passed from application * @ioc_number: ? * @iocpp: The ioc pointer is returned in this. * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device & * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device. * * Return: (-1) means error, else ioc_number. */ static int _ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp, int mpi_version) { … } /** * mpt3sas_ctl_pre_reset_handler - reset callback handler (for ctl) * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. */ void mpt3sas_ctl_pre_reset_handler(struct MPT3SAS_ADAPTER *ioc) { … } /** * mpt3sas_ctl_clear_outstanding_ioctls - clears outstanding ioctl cmd. * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. */ void mpt3sas_ctl_clear_outstanding_ioctls(struct MPT3SAS_ADAPTER *ioc) { … } /** * mpt3sas_ctl_reset_done_handler - reset callback handler (for ctl) * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. */ void mpt3sas_ctl_reset_done_handler(struct MPT3SAS_ADAPTER *ioc) { … } /** * _ctl_fasync - * @fd: ? * @filep: ? * @mode: ? * * Called when application request fasyn callback handler. */ static int _ctl_fasync(int fd, struct file *filep, int mode) { … } /** * _ctl_poll - * @filep: ? * @wait: ? * */ static __poll_t _ctl_poll(struct file *filep, poll_table *wait) { … } /** * _ctl_set_task_mid - assign an active smid to tm request * @ioc: per adapter object * @karg: (struct mpt3_ioctl_command) * @tm_request: pointer to mf from user space * * Return: 0 when an smid if found, else fail. * during failure, the reply frame is filled. */ static int _ctl_set_task_mid(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command *karg, Mpi2SCSITaskManagementRequest_t *tm_request) { … } /** * _ctl_do_mpt_command - main handler for MPT3COMMAND opcode * @ioc: per adapter object * @karg: (struct mpt3_ioctl_command) * @mf: pointer to mf in user space */ static long _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, void __user *mf) { … } /** * _ctl_getiocinfo - main handler for MPT3IOCINFO opcode * @ioc: per adapter object * @arg: user space buffer containing ioctl content */ static long _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_eventquery - main handler for MPT3EVENTQUERY opcode * @ioc: per adapter object * @arg: user space buffer containing ioctl content */ static long _ctl_eventquery(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_eventenable - main handler for MPT3EVENTENABLE opcode * @ioc: per adapter object * @arg: user space buffer containing ioctl content */ static long _ctl_eventenable(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_eventreport - main handler for MPT3EVENTREPORT opcode * @ioc: per adapter object * @arg: user space buffer containing ioctl content */ static long _ctl_eventreport(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_do_reset - main handler for MPT3HARDRESET opcode * @ioc: per adapter object * @arg: user space buffer containing ioctl content */ static long _ctl_do_reset(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_btdh_search_sas_device - searching for sas device * @ioc: per adapter object * @btdh: btdh ioctl payload */ static int _ctl_btdh_search_sas_device(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_btdh_mapping *btdh) { … } /** * _ctl_btdh_search_pcie_device - searching for pcie device * @ioc: per adapter object * @btdh: btdh ioctl payload */ static int _ctl_btdh_search_pcie_device(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_btdh_mapping *btdh) { … } /** * _ctl_btdh_search_raid_device - searching for raid device * @ioc: per adapter object * @btdh: btdh ioctl payload */ static int _ctl_btdh_search_raid_device(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_btdh_mapping *btdh) { … } /** * _ctl_btdh_mapping - main handler for MPT3BTDHMAPPING opcode * @ioc: per adapter object * @arg: user space buffer containing ioctl content */ static long _ctl_btdh_mapping(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_diag_capability - return diag buffer capability * @ioc: per adapter object * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED * * returns 1 when diag buffer support is enabled in firmware */ static u8 _ctl_diag_capability(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type) { … } /** * _ctl_diag_get_bufftype - return diag buffer type * either TRACE, SNAPSHOT, or EXTENDED * @ioc: per adapter object * @unique_id: specifies the unique_id for the buffer * * returns MPT3_DIAG_UID_NOT_FOUND if the id not found */ static u8 _ctl_diag_get_bufftype(struct MPT3SAS_ADAPTER *ioc, u32 unique_id) { … } /** * _ctl_diag_register_2 - wrapper for registering diag buffer support * @ioc: per adapter object * @diag_register: the diag_register struct passed in from user space * */ static long _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc, struct mpt3_diag_register *diag_register) { … } /** * mpt3sas_enable_diag_buffer - enabling diag_buffers support driver load time * @ioc: per adapter object * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1 * * This is called when command line option diag_buffer_enable is enabled * at driver load time. */ void mpt3sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register) { … } /** * _ctl_diag_register - application register with driver * @ioc: per adapter object * @arg: user space buffer containing ioctl content * * This will allow the driver to setup any required buffers that will be * needed by firmware to communicate with the driver. */ static long _ctl_diag_register(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_diag_unregister - application unregister with driver * @ioc: per adapter object * @arg: user space buffer containing ioctl content * * This will allow the driver to cleanup any memory allocated for diag * messages and to free up any resources. */ static long _ctl_diag_unregister(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_diag_query - query relevant info associated with diag buffers * @ioc: per adapter object * @arg: user space buffer containing ioctl content * * The application will send only buffer_type and unique_id. Driver will * inspect unique_id first, if valid, fill in all the info. If unique_id is * 0x00, the driver will return info specified by Buffer Type. */ static long _ctl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * mpt3sas_send_diag_release - Diag Release Message * @ioc: per adapter object * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED * @issue_reset: specifies whether host reset is required. * */ int mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset) { … } /** * _ctl_diag_release - request to send Diag Release Message to firmware * @ioc: ? * @arg: user space buffer containing ioctl content * * This allows ownership of the specified buffer to returned to the driver, * allowing an application to read the buffer without fear that firmware is * overwriting information in the buffer. */ static long _ctl_diag_release(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_diag_read_buffer - request for copy of the diag buffer * @ioc: per adapter object * @arg: user space buffer containing ioctl content */ static long _ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_addnl_diag_query - query relevant info associated with diag buffers * @ioc: per adapter object * @arg: user space buffer containing ioctl content * * The application will send only unique_id. Driver will * inspect unique_id first, if valid, fill the details related to cause * for diag buffer release. */ static long _ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } /** * _ctl_enable_diag_sbr_reload - enable sbr reload bit * @ioc: per adapter object * @arg: user space buffer containing ioctl content * * Enable the SBR reload bit */ static int _ctl_enable_diag_sbr_reload(struct MPT3SAS_ADAPTER *ioc, void __user *arg) { … } #ifdef CONFIG_COMPAT /** * _ctl_compat_mpt_command - convert 32bit pointers to 64bit. * @ioc: per adapter object * @cmd: ioctl opcode * @arg: (struct mpt3_ioctl_command32) * * MPT3COMMAND32 - Handle 32bit applications running on 64bit os. */ static long _ctl_compat_mpt_command(struct MPT3SAS_ADAPTER *ioc, unsigned cmd, void __user *arg) { … } #endif /** * _ctl_ioctl_main - main ioctl entry point * @file: (struct file) * @cmd: ioctl opcode * @arg: user space data buffer * @compat: handles 32 bit applications in 64bit os * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device & * MPI25_VERSION | MPI26_VERSION for mpt3ctl ioctl device. */ static long _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, u8 compat, u16 mpi_version) { … } /** * _ctl_ioctl - mpt3ctl main ioctl entry point (unlocked) * @file: (struct file) * @cmd: ioctl opcode * @arg: ? */ static long _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { … } /** * _ctl_mpt2_ioctl - mpt2ctl main ioctl entry point (unlocked) * @file: (struct file) * @cmd: ioctl opcode * @arg: ? */ static long _ctl_mpt2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { … } #ifdef CONFIG_COMPAT /** * _ctl_ioctl_compat - main ioctl entry point (compat) * @file: ? * @cmd: ? * @arg: ? * * This routine handles 32 bit applications in 64bit os. */ static long _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg) { … } /** * _ctl_mpt2_ioctl_compat - main ioctl entry point (compat) * @file: ? * @cmd: ? * @arg: ? * * This routine handles 32 bit applications in 64bit os. */ static long _ctl_mpt2_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg) { … } #endif /* scsi host attributes */ /** * version_fw_show - firmware version * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t version_fw_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(version_fw); /** * version_bios_show - bios version * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t version_bios_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(version_bios); /** * version_mpi_show - MPI (message passing interface) version * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t version_mpi_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(version_mpi); /** * version_product_show - product name * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t version_product_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(version_product); /** * version_nvdata_persistent_show - ndvata persistent version * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t version_nvdata_persistent_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(version_nvdata_persistent); /** * version_nvdata_default_show - nvdata default version * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t version_nvdata_default_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(version_nvdata_default); /** * board_name_show - board name * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t board_name_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(board_name); /** * board_assembly_show - board assembly name * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t board_assembly_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(board_assembly); /** * board_tracer_show - board tracer number * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t board_tracer_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(board_tracer); /** * io_delay_show - io missing delay * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * This is for firmware implemention for deboucing device * removal events. * * A sysfs 'read-only' shost attribute. */ static ssize_t io_delay_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(io_delay); /** * device_delay_show - device missing delay * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * This is for firmware implemention for deboucing device * removal events. * * A sysfs 'read-only' shost attribute. */ static ssize_t device_delay_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(device_delay); /** * fw_queue_depth_show - global credits * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * This is firmware queue depth limit * * A sysfs 'read-only' shost attribute. */ static ssize_t fw_queue_depth_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(fw_queue_depth); /** * host_sas_address_show - sas address * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * This is the controller sas address * * A sysfs 'read-only' shost attribute. */ static ssize_t host_sas_address_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(host_sas_address); /** * logging_level_show - logging level * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read/write' shost attribute. */ static ssize_t logging_level_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static ssize_t logging_level_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(logging_level); /** * fwfault_debug_show - show/store fwfault_debug * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * mpt3sas_fwfault_debug is command line option * A sysfs 'read/write' shost attribute. */ static ssize_t fwfault_debug_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static ssize_t fwfault_debug_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(fwfault_debug); /** * ioc_reset_count_show - ioc reset count * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * This is firmware queue depth limit * * A sysfs 'read-only' shost attribute. */ static ssize_t ioc_reset_count_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(ioc_reset_count); /** * reply_queue_count_show - number of reply queues * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * This is number of reply queues * * A sysfs 'read-only' shost attribute. */ static ssize_t reply_queue_count_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(reply_queue_count); /** * BRM_status_show - Backup Rail Monitor Status * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * This is number of reply queues * * A sysfs 'read-only' shost attribute. */ static ssize_t BRM_status_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(BRM_status); struct DIAG_BUFFER_START { … }; /** * host_trace_buffer_size_show - host buffer size (trace only) * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t host_trace_buffer_size_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(host_trace_buffer_size); /** * host_trace_buffer_show - firmware ring buffer (trace only) * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read/write' shost attribute. * * You will only be able to read 4k bytes of ring buffer at a time. * In order to read beyond 4k bytes, you will have to write out the * offset to the same attribute, it will move the pointer. */ static ssize_t host_trace_buffer_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static ssize_t host_trace_buffer_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(host_trace_buffer); /*****************************************/ /** * host_trace_buffer_enable_show - firmware ring buffer (trace only) * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read/write' shost attribute. * * This is a mechnism to post/release host_trace_buffers */ static ssize_t host_trace_buffer_enable_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static ssize_t host_trace_buffer_enable_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(host_trace_buffer_enable); /*********** diagnostic trigger suppport *********************************/ /** * diag_trigger_master_show - show the diag_trigger_master attribute * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read/write' shost attribute. */ static ssize_t diag_trigger_master_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } /** * diag_trigger_master_store - store the diag_trigger_master attribute * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * @count: ? * * A sysfs 'read/write' shost attribute. */ static ssize_t diag_trigger_master_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(diag_trigger_master); /** * diag_trigger_event_show - show the diag_trigger_event attribute * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read/write' shost attribute. */ static ssize_t diag_trigger_event_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } /** * diag_trigger_event_store - store the diag_trigger_event attribute * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * @count: ? * * A sysfs 'read/write' shost attribute. */ static ssize_t diag_trigger_event_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(diag_trigger_event); /** * diag_trigger_scsi_show - show the diag_trigger_scsi attribute * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read/write' shost attribute. */ static ssize_t diag_trigger_scsi_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } /** * diag_trigger_scsi_store - store the diag_trigger_scsi attribute * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * @count: ? * * A sysfs 'read/write' shost attribute. */ static ssize_t diag_trigger_scsi_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(diag_trigger_scsi); /** * diag_trigger_mpi_show - show the diag_trigger_mpi attribute * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * A sysfs 'read/write' shost attribute. */ static ssize_t diag_trigger_mpi_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } /** * diag_trigger_mpi_store - store the diag_trigger_mpi attribute * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * @count: ? * * A sysfs 'read/write' shost attribute. */ static ssize_t diag_trigger_mpi_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(diag_trigger_mpi); /*********** diagnostic trigger suppport *** END ****************************/ /*****************************************/ /** * drv_support_bitmap_show - driver supported feature bitmap * @cdev: pointer to embedded class device * @attr: unused * @buf: the buffer returned * * A sysfs 'read-only' shost attribute. */ static ssize_t drv_support_bitmap_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(drv_support_bitmap); /** * enable_sdev_max_qd_show - display whether sdev max qd is enabled/disabled * @cdev: pointer to embedded class device * @attr: unused * @buf: the buffer returned * * A sysfs read/write shost attribute. This attribute is used to set the * targets queue depth to HBA IO queue depth if this attribute is enabled. */ static ssize_t enable_sdev_max_qd_show(struct device *cdev, struct device_attribute *attr, char *buf) { … } /** * enable_sdev_max_qd_store - Enable/disable sdev max qd * @cdev: pointer to embedded class device * @attr: unused * @buf: the buffer returned * @count: unused * * A sysfs read/write shost attribute. This attribute is used to set the * targets queue depth to HBA IO queue depth if this attribute is enabled. * If this attribute is disabled then targets will have corresponding default * queue depth. */ static ssize_t enable_sdev_max_qd_store(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(enable_sdev_max_qd); static struct attribute *mpt3sas_host_attrs[] = …; static const struct attribute_group mpt3sas_host_attr_group = …; const struct attribute_group *mpt3sas_host_groups[] = …; /* device attributes */ /** * sas_address_show - sas address * @dev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * This is the sas address for the target * * A sysfs 'read-only' shost attribute. */ static ssize_t sas_address_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(sas_address); /** * sas_device_handle_show - device handle * @dev: pointer to embedded class device * @attr: ? * @buf: the buffer returned * * This is the firmware assigned device handle * * A sysfs 'read-only' shost attribute. */ static ssize_t sas_device_handle_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(sas_device_handle); /** * sas_ncq_prio_supported_show - Indicate if device supports NCQ priority * @dev: pointer to embedded device * @attr: sas_ncq_prio_supported attribute descriptor * @buf: the buffer returned * * A sysfs 'read-only' sdev attribute, only works with SATA */ static ssize_t sas_ncq_prio_supported_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static DEVICE_ATTR_RO(sas_ncq_prio_supported); /** * sas_ncq_prio_enable_show - send prioritized io commands to device * @dev: pointer to embedded device * @attr: ? * @buf: the buffer returned * * A sysfs 'read/write' sdev attribute, only works with SATA */ static ssize_t sas_ncq_prio_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { … } static ssize_t sas_ncq_prio_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static DEVICE_ATTR_RW(sas_ncq_prio_enable); static struct attribute *mpt3sas_dev_attrs[] = …; static const struct attribute_group mpt3sas_dev_attr_group = …; const struct attribute_group *mpt3sas_dev_groups[] = …; /* file operations table for mpt3ctl device */ static const struct file_operations ctl_fops = …; /* file operations table for mpt2ctl device */ static const struct file_operations ctl_gen2_fops = …; static struct miscdevice ctl_dev = …; static struct miscdevice gen2_ctl_dev = …; /** * mpt3sas_ctl_init - main entry point for ctl. * @hbas_to_enumerate: ? */ void mpt3sas_ctl_init(ushort hbas_to_enumerate) { … } /** * mpt3sas_ctl_release - release dma for ctl * @ioc: per adapter object */ void mpt3sas_ctl_release(struct MPT3SAS_ADAPTER *ioc) { … } /** * mpt3sas_ctl_exit - exit point for ctl * @hbas_to_enumerate: ? */ void mpt3sas_ctl_exit(ushort hbas_to_enumerate) { … }