/* * Intel(R) Enclosure LED Utilities * Copyright (C) 2009-2018 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. * * 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 St - Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifndef _BLOCK_H_INCLUDED_ #define _BLOCK_H_INCLUDED_ #include "cntrl.h" #include "ibpi.h" #include "time.h" #include "list.h" #include "raid.h" struct block_device; /** * @brief Pointer to a send message function. * * The pointer to a function which knows how to send LED message to a driver of * storage controller using the given protocol. * * @param[in] path path in sysfs to a host device * @see block_device::cntrl_path. * @param[in] ibpi an IBPI pattern (state) to visualize. * * @return 1 if successful, otherwise the function returns 0. */ typedef int (*send_message_t) (struct block_device *device, enum ibpi_pattern ibpi); /** * @brief Pointer to a flush buffer function. * * @param[in] device pointer to a block device * * @return 1 if successful, otherwise the function returns 0. */ typedef int (*flush_message_t) (struct block_device *device); /** * @brief Describes a block device. * * This structure describes a block device. It does not describe virtual devices * or partitions on physical block devices. */ struct block_device { /** * Real path in sysfs tree. This means i.e. if /sys/block/sda is symbolic link * then the link will be read and path stored in sysfs_path field. This path * may not exist in sysfs if connection to physical drive is lost. This filed * cannot have NULL pointer assigned. */ char *sysfs_path; /** * The pointer to a function which sends a message to driver in order to * control LEDs in an enclosure or DAS system - @see send_message_t for details. * This field cannot have NULL pointer assigned. */ send_message_t send_fn; /** * The pointer to a function which flush buffers filled by send_fn. */ flush_message_t flush_fn; /** * Canonical path to block device where enclosure management fields are located. * This path is always accessible even if the connection to physical device * is lost. In case of AHCI controller it points to SATA phy. In case of SAS * this path points to SES entry associated with the slot in an enclosure. * This field cannot have NULL pointer assign. */ char *cntrl_path; /** * The current state of block device. This is an IBPI pattern and it is used * to visualize the state of block device. */ enum ibpi_pattern ibpi; /** * The previous state of block device. */ enum ibpi_pattern ibpi_prev; /** * The time stamp used to determine if the given block device still exist or * it failed and the device is no longer available. Every time IBPI pattern * is updated, the time-stamp is updated, too. */ time_t timestamp; /** * The pointer to storage controller structure the device is connected to. */ struct cntrl_device *cntrl; struct _host_type *host; int host_id; /** * The index of phy utilized by directly attached to controller block device. * It is meaningful if device is controlled by isci driver. */ int phy_index; /** * The index in Enclosure. This is what should be used when using SES-2. */ int encl_index; struct enclosure_device *enclosure; /** * If disk is a raid member, this field will be set with a copy of raid device * struct. */ struct raid_device *raid_dev; }; /** * @brief Creates a block device structure. * * This function allocates memory for a new structure of block device. It reads * the sysfs entries and populates the structure fields. It performs all this * actions only if the block device is connected to the one of supported storage * controllers and the controller has enclosure management services enabled. * * @param[in] cntrl_list pointer to a list of supported controller * devices. * @param[in] sysfs_path a path to block device in sysfs. * * @return Pointer to block device structure if successful, otherwise the function * returns the NULL pointer. */ struct block_device *block_device_init(const struct list *cntrl_list, const char *path); /** * @brief Releases a block device structure. * * This function releases memory allocated for block device structure. * * @param[in] device pointer to block device structure. * * @return The function does not return a value. */ void block_device_fini(struct block_device *device); /** * @brief Duplicates a block device structure. * * The function allocates memory for a block device structure and copies values * stored in fields of source block structure. The function allocates new memory * for all string fields in a copy structure. It is safe to release source block * structure just after it has been duplicated. * * @param[in] device pointer to source block device structure. * * @return Pointer to block device structure if successful, otherwise the function * returns the NULL pointer. */ struct block_device *block_device_duplicate(struct block_device *device); /** * @brief Determines a storage controller. * * This is the internal function of 'block device' module. The function gets * a pointer to controller structure the device is connected to. * * @param[in] cntrl_list pointer to list of supported controllers. * @param[in] path path to block device in sysfs tree. * * @return Pointer to controller structure if successful, otherwise the function * returns NULL pointer. The NULL pointer means that block devices is * connected to unsupported storage controller. */ struct cntrl_device *block_get_controller(const struct list *cntrl_list, char *path); /** * The global timestamp variable. It is updated every time the sysfs is scanning * by an application. The value stored in this variable should be used to update * all timestamp stored in block device structures. */ extern time_t timestamp; /** * @brief Determines if block device is attached directly or via expander */ int dev_directly_attached(const char *path); /** * @brief Gets the host structure for given control device and host_id */ struct _host_type *block_get_host(struct cntrl_device *cntrl, int host_id); /** * @brief Checks the presence of block device. * * This is internal function of monitor service. The function is checking * whether block device is already on the list or it is missing from the list. * The function is design to be used as 'test' parameter for list_find_first() * function. * * @param[in] bd_old - an element from a list to compare to. * @param[in] bd_new - a block device being searched. * * @return 0 if the block devices do not match, otherwise function returns 1. */ int block_compare(const struct block_device *bd_old, const struct block_device *bd_new); #endif /* _BLOCK_H_INCLUDED_ */