// SPDX-License-Identifier: GPL-2.0-or-later /* * ipr.c -- driver for IBM Power Linux RAID adapters * * Written By: Brian King <[email protected]>, IBM Corporation * * Copyright (C) 2003, 2004 IBM Corporation */ /* * Notes: * * This driver is used to control the following SCSI adapters: * * IBM iSeries: 5702, 5703, 2780, 5709, 570A, 570B * * IBM pSeries: PCI-X Dual Channel Ultra 320 SCSI RAID Adapter * PCI-X Dual Channel Ultra 320 SCSI Adapter * PCI-X Dual Channel Ultra 320 SCSI RAID Enablement Card * Embedded SCSI adapter on p615 and p655 systems * * Supported Hardware Features: * - Ultra 320 SCSI controller * - PCI-X host interface * - Embedded PowerPC RISC Processor and Hardware XOR DMA Engine * - Non-Volatile Write Cache * - Supports attachment of non-RAID disks, tape, and optical devices * - RAID Levels 0, 5, 10 * - Hot spare * - Background Parity Checking * - Background Data Scrubbing * - Ability to increase the capacity of an existing RAID 5 disk array * by adding disks * * Driver Features: * - Tagged command queuing * - Adapter microcode download * - PCI hot plug * - SCSI device hot plug * */ #include <linux/fs.h> #include <linux/init.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/ioport.h> #include <linux/delay.h> #include <linux/pci.h> #include <linux/wait.h> #include <linux/spinlock.h> #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/blkdev.h> #include <linux/firmware.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/hdreg.h> #include <linux/reboot.h> #include <linux/stringify.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/processor.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> #include <scsi/scsi_tcq.h> #include <scsi/scsi_eh.h> #include <scsi/scsi_cmnd.h> #include "ipr.h" /* * Global Data */ static LIST_HEAD(ipr_ioa_head); static unsigned int ipr_log_level = …; static unsigned int ipr_max_speed = …; static unsigned int ipr_fastfail = …; static unsigned int ipr_transop_timeout = …; static unsigned int ipr_debug = …; static unsigned int ipr_max_devs = …; static unsigned int ipr_dual_ioa_raid = …; static unsigned int ipr_number_of_msix = …; static unsigned int ipr_fast_reboot; static DEFINE_SPINLOCK(ipr_driver_lock); /* This table describes the differences between DMA controller chips */ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = …; static const struct ipr_chip_t ipr_chip[] = …; static int ipr_max_bus_speeds[] = …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; module_param_named(max_speed, ipr_max_speed, uint, 0); MODULE_PARM_DESC(…) …; module_param_named(log_level, ipr_log_level, uint, 0); MODULE_PARM_DESC(…) …; module_param_named(fastfail, ipr_fastfail, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(…) …; module_param_named(transop_timeout, ipr_transop_timeout, int, 0); MODULE_PARM_DESC(…) …; module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(…) …; module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); MODULE_PARM_DESC(…) …; module_param_named(max_devs, ipr_max_devs, int, 0); MODULE_PARM_DESC(…) …; module_param_named(number_of_msix, ipr_number_of_msix, int, 0); MODULE_PARM_DESC(…) …; module_param_named(fast_reboot, ipr_fast_reboot, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(…) …; MODULE_LICENSE(…) …; MODULE_VERSION(…); /* A constant array of IOASCs/URCs/Error Messages */ static const struct ipr_error_table_t ipr_error_table[] = …; static const struct ipr_ses_table_entry ipr_ses_table[] = …; /* * Function Prototypes */ static int ipr_reset_alert(struct ipr_cmnd *); static void ipr_process_ccn(struct ipr_cmnd *); static void ipr_process_error(struct ipr_cmnd *); static void ipr_reset_ioa_job(struct ipr_cmnd *); static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *, enum ipr_shutdown_type); #ifdef CONFIG_SCSI_IPR_TRACE /** * ipr_trc_hook - Add a trace entry to the driver trace * @ipr_cmd: ipr command struct * @type: trace type * @add_data: additional data * * Return value: * none **/ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd, u8 type, u32 add_data) { … } #else #define ipr_trc_hook … #endif /** * ipr_lock_and_done - Acquire lock and complete command * @ipr_cmd: ipr command struct * * Return value: * none **/ static void ipr_lock_and_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reinit_ipr_cmnd - Re-initialize an IPR Cmnd block for reuse * @ipr_cmd: ipr command struct * * Return value: * none **/ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_init_ipr_cmnd - Initialize an IPR Cmnd block * @ipr_cmd: ipr command struct * @fast_done: fast done function call-back * * Return value: * none **/ static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd, void (*fast_done) (struct ipr_cmnd *)) { … } /** * __ipr_get_free_ipr_cmnd - Get a free IPR Cmnd block * @hrrq: hrr queue * * Return value: * pointer to ipr command struct **/ static struct ipr_cmnd *__ipr_get_free_ipr_cmnd(struct ipr_hrr_queue *hrrq) { … } /** * ipr_get_free_ipr_cmnd - Get a free IPR Cmnd block and initialize it * @ioa_cfg: ioa config struct * * Return value: * pointer to ipr command struct **/ static struct ipr_cmnd *ipr_get_free_ipr_cmnd(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_mask_and_clear_interrupts - Mask all and clear specified interrupts * @ioa_cfg: ioa config struct * @clr_ints: interrupts to clear * * This function masks all interrupts on the adapter, then clears the * interrupts specified in the mask * * Return value: * none **/ static void ipr_mask_and_clear_interrupts(struct ipr_ioa_cfg *ioa_cfg, u32 clr_ints) { … } /** * ipr_save_pcix_cmd_reg - Save PCI-X command register * @ioa_cfg: ioa config struct * * Return value: * 0 on success / -EIO on failure **/ static int ipr_save_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_set_pcix_cmd_reg - Setup PCI-X command register * @ioa_cfg: ioa config struct * * Return value: * 0 on success / -EIO on failure **/ static int ipr_set_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg) { … } /** * __ipr_scsi_eh_done - mid-layer done function for aborted ops * @ipr_cmd: ipr command struct * * This function is invoked by the interrupt handler for * ops generated by the SCSI mid-layer which are being aborted. * * Return value: * none **/ static void __ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_scsi_eh_done - mid-layer done function for aborted ops * @ipr_cmd: ipr command struct * * This function is invoked by the interrupt handler for * ops generated by the SCSI mid-layer which are being aborted. * * Return value: * none **/ static void ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_fail_all_ops - Fails all outstanding ops. * @ioa_cfg: ioa config struct * * This function fails all outstanding ops. * * Return value: * none **/ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_send_command - Send driver initiated requests. * @ipr_cmd: ipr command struct * * This function sends a command to the adapter using the correct write call. * In the case of sis64, calculate the ioarcb size required. Then or in the * appropriate bits. * * Return value: * none **/ static void ipr_send_command(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_do_req - Send driver initiated requests. * @ipr_cmd: ipr command struct * @done: done function * @timeout_func: timeout function * @timeout: timeout value * * This function sends the specified command to the adapter with the * timeout given. The done function is invoked on command completion. * * Return value: * none **/ static void ipr_do_req(struct ipr_cmnd *ipr_cmd, void (*done) (struct ipr_cmnd *), void (*timeout_func) (struct timer_list *), u32 timeout) { … } /** * ipr_internal_cmd_done - Op done function for an internally generated op. * @ipr_cmd: ipr command struct * * This function is the op done function for an internally generated, * blocking op. It simply wakes the sleeping thread. * * Return value: * none **/ static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_init_ioadl - initialize the ioadl for the correct SIS type * @ipr_cmd: ipr command struct * @dma_addr: dma address * @len: transfer length * @flags: ioadl flag value * * This function initializes an ioadl in the case where there is only a single * descriptor. * * Return value: * nothing **/ static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr, u32 len, int flags) { … } /** * ipr_send_blocking_cmd - Send command and sleep on its completion. * @ipr_cmd: ipr command struct * @timeout_func: function to invoke if command times out * @timeout: timeout * * Return value: * none **/ static void ipr_send_blocking_cmd(struct ipr_cmnd *ipr_cmd, void (*timeout_func) (struct timer_list *), u32 timeout) { … } static int ipr_get_hrrq_index(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_send_hcam - Send an HCAM to the adapter. * @ioa_cfg: ioa config struct * @type: HCAM type * @hostrcb: hostrcb struct * * This function will send a Host Controlled Async command to the adapter. * If HCAMs are currently not allowed to be issued to the adapter, it will * place the hostrcb on the free queue. * * Return value: * none **/ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, struct ipr_hostrcb *hostrcb) { … } /** * ipr_init_res_entry - Initialize a resource entry struct. * @res: resource entry struct * @cfgtew: config table entry wrapper struct * * Return value: * none **/ static void ipr_init_res_entry(struct ipr_resource_entry *res, struct ipr_config_table_entry_wrapper *cfgtew) { … } /** * ipr_is_same_device - Determine if two devices are the same. * @res: resource entry struct * @cfgtew: config table entry wrapper struct * * Return value: * 1 if the devices are the same / 0 otherwise **/ static int ipr_is_same_device(struct ipr_resource_entry *res, struct ipr_config_table_entry_wrapper *cfgtew) { … } /** * __ipr_format_res_path - Format the resource path for printing. * @res_path: resource path * @buffer: buffer * @len: length of buffer provided * * Return value: * pointer to buffer **/ static char *__ipr_format_res_path(u8 *res_path, char *buffer, int len) { … } /** * ipr_format_res_path - Format the resource path for printing. * @ioa_cfg: ioa config struct * @res_path: resource path * @buffer: buffer * @len: length of buffer provided * * Return value: * pointer to buffer **/ static char *ipr_format_res_path(struct ipr_ioa_cfg *ioa_cfg, u8 *res_path, char *buffer, int len) { … } /** * ipr_update_res_entry - Update the resource entry. * @res: resource entry struct * @cfgtew: config table entry wrapper struct * * Return value: * none **/ static void ipr_update_res_entry(struct ipr_resource_entry *res, struct ipr_config_table_entry_wrapper *cfgtew) { … } /** * ipr_clear_res_target - Clear the bit in the bit map representing the target * for the resource. * @res: resource entry struct * * Return value: * none **/ static void ipr_clear_res_target(struct ipr_resource_entry *res) { … } /** * ipr_handle_config_change - Handle a config change from the adapter * @ioa_cfg: ioa config struct * @hostrcb: hostrcb * * Return value: * none **/ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_process_ccn - Op done function for a CCN. * @ipr_cmd: ipr command struct * * This function is the op done function for a configuration * change notification host controlled async from the adapter. * * Return value: * none **/ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd) { … } /** * strip_whitespace - Strip and pad trailing whitespace. * @i: size of buffer * @buf: string to modify * * This function will strip all trailing whitespace and * NUL terminate the string. * **/ static void strip_whitespace(int i, char *buf) { … } /** * ipr_log_vpd_compact - Log the passed extended VPD compactly. * @prefix: string to print at start of printk * @hostrcb: hostrcb pointer * @vpd: vendor/product id/sn struct * * Return value: * none **/ static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb, struct ipr_vpd *vpd) { … } /** * ipr_log_vpd - Log the passed VPD to the error log. * @vpd: vendor/product id/sn struct * * Return value: * none **/ static void ipr_log_vpd(struct ipr_vpd *vpd) { … } /** * ipr_log_ext_vpd_compact - Log the passed extended VPD compactly. * @prefix: string to print at start of printk * @hostrcb: hostrcb pointer * @vpd: vendor/product id/sn/wwn struct * * Return value: * none **/ static void ipr_log_ext_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb, struct ipr_ext_vpd *vpd) { … } /** * ipr_log_ext_vpd - Log the passed extended VPD to the error log. * @vpd: vendor/product id/sn/wwn struct * * Return value: * none **/ static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd) { … } /** * ipr_log_enhanced_cache_error - Log a cache error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_cache_error - Log a cache error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_cache_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_enhanced_config_error - Log a configuration error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_sis64_config_error - Log a device error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_sis64_config_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_config_error - Log a configuration error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_config_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_enhanced_array_error - Log an array configuration error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_enhanced_array_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_array_error - Log an array configuration error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_hex_data - Log additional hex IOA error data. * @ioa_cfg: ioa config struct * @data: IOA error data * @len: data length * * Return value: * none **/ static void ipr_log_hex_data(struct ipr_ioa_cfg *ioa_cfg, __be32 *data, int len) { … } /** * ipr_log_enhanced_dual_ioa_error - Log an enhanced dual adapter error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_dual_ioa_error - Log a dual adapter error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } static const struct { … } path_active_desc[] = …; static const struct { … } path_state_desc[] = …; /** * ipr_log_fabric_path - Log a fabric path error * @hostrcb: hostrcb struct * @fabric: fabric descriptor * * Return value: * none **/ static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb, struct ipr_hostrcb_fabric_desc *fabric) { … } /** * ipr_log64_fabric_path - Log a fabric path error * @hostrcb: hostrcb struct * @fabric: fabric descriptor * * Return value: * none **/ static void ipr_log64_fabric_path(struct ipr_hostrcb *hostrcb, struct ipr_hostrcb64_fabric_desc *fabric) { … } static const struct { … } path_type_desc[] = …; static const struct { … } path_status_desc[] = …; static const char *link_rate[] = …; /** * ipr_log_path_elem - Log a fabric path element. * @hostrcb: hostrcb struct * @cfg: fabric path element struct * * Return value: * none **/ static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb, struct ipr_hostrcb_config_element *cfg) { … } /** * ipr_log64_path_elem - Log a fabric path element. * @hostrcb: hostrcb struct * @cfg: fabric path element struct * * Return value: * none **/ static void ipr_log64_path_elem(struct ipr_hostrcb *hostrcb, struct ipr_hostrcb64_config_element *cfg) { … } /** * ipr_log_fabric_error - Log a fabric error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_sis64_array_error - Log a sis64 array error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_sis64_fabric_error - Log a sis64 fabric error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_sis64_fabric_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_sis64_service_required_error - Log a sis64 service required error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_sis64_service_required_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_generic_error - Log an adapter error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_log_sis64_device_error - Log a cache error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * Return value: * none **/ static void ipr_log_sis64_device_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } /** * ipr_get_error - Find the specfied IOASC in the ipr_error_table. * @ioasc: IOASC * * This function will return the index of into the ipr_error_table * for the specified IOASC. If the IOASC is not in the table, * 0 will be returned, which points to the entry used for unknown errors. * * Return value: * index into the ipr_error_table **/ static u32 ipr_get_error(u32 ioasc) { … } /** * ipr_handle_log_data - Log an adapter error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct * * This function logs an adapter error to the system. * * Return value: * none **/ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { … } static struct ipr_hostrcb *ipr_get_free_hostrcb(struct ipr_ioa_cfg *ioa) { … } /** * ipr_process_error - Op done function for an adapter error log. * @ipr_cmd: ipr command struct * * This function is the op done function for an error log host * controlled async from the adapter. It will log the error and * send the HCAM back to the adapter. * * Return value: * none **/ static void ipr_process_error(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_timeout - An internally generated op has timed out. * @t: Timer context used to fetch ipr command struct * * This function blocks host requests and initiates an * adapter reset. * * Return value: * none **/ static void ipr_timeout(struct timer_list *t) { … } /** * ipr_oper_timeout - Adapter timed out transitioning to operational * @t: Timer context used to fetch ipr command struct * * This function blocks host requests and initiates an * adapter reset. * * Return value: * none **/ static void ipr_oper_timeout(struct timer_list *t) { … } /** * ipr_find_ses_entry - Find matching SES in SES table * @res: resource entry struct of SES * * Return value: * pointer to SES table entry / NULL on failure **/ static const struct ipr_ses_table_entry * ipr_find_ses_entry(struct ipr_resource_entry *res) { … } /** * ipr_get_max_scsi_speed - Determine max SCSI speed for a given bus * @ioa_cfg: ioa config struct * @bus: SCSI bus * @bus_width: bus width * * Return value: * SCSI bus speed in units of 100KHz, 1600 is 160 MHz * For a 2-byte wide SCSI bus, the maximum transfer speed is * twice the maximum transfer rate (e.g. for a wide enabled bus, * max 160MHz = max 320MB/sec). **/ static u32 ipr_get_max_scsi_speed(struct ipr_ioa_cfg *ioa_cfg, u8 bus, u8 bus_width) { … } /** * ipr_wait_iodbg_ack - Wait for an IODEBUG ACK from the IOA * @ioa_cfg: ioa config struct * @max_delay: max delay in micro-seconds to wait * * Waits for an IODEBUG ACK from the IOA, doing busy looping. * * Return value: * 0 on success / other on failure **/ static int ipr_wait_iodbg_ack(struct ipr_ioa_cfg *ioa_cfg, int max_delay) { … } /** * ipr_get_sis64_dump_data_section - Dump IOA memory * @ioa_cfg: ioa config struct * @start_addr: adapter address to dump * @dest: destination kernel buffer * @length_in_words: length to dump in 4 byte words * * Return value: * 0 on success **/ static int ipr_get_sis64_dump_data_section(struct ipr_ioa_cfg *ioa_cfg, u32 start_addr, __be32 *dest, u32 length_in_words) { … } /** * ipr_get_ldump_data_section - Dump IOA memory * @ioa_cfg: ioa config struct * @start_addr: adapter address to dump * @dest: destination kernel buffer * @length_in_words: length to dump in 4 byte words * * Return value: * 0 on success / -EIO on failure **/ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, u32 start_addr, __be32 *dest, u32 length_in_words) { … } #ifdef CONFIG_SCSI_IPR_DUMP /** * ipr_sdt_copy - Copy Smart Dump Table to kernel buffer * @ioa_cfg: ioa config struct * @pci_address: adapter address * @length: length of data to copy * * Copy data from PCI adapter to kernel buffer. * Note: length MUST be a 4 byte multiple * Return value: * 0 on success / other on failure **/ static int ipr_sdt_copy(struct ipr_ioa_cfg *ioa_cfg, unsigned long pci_address, u32 length) { … } /** * ipr_init_dump_entry_hdr - Initialize a dump entry header. * @hdr: dump entry header struct * * Return value: * nothing **/ static void ipr_init_dump_entry_hdr(struct ipr_dump_entry_header *hdr) { … } /** * ipr_dump_ioa_type_data - Fill in the adapter type in the dump. * @ioa_cfg: ioa config struct * @driver_dump: driver dump struct * * Return value: * nothing **/ static void ipr_dump_ioa_type_data(struct ipr_ioa_cfg *ioa_cfg, struct ipr_driver_dump *driver_dump) { … } /** * ipr_dump_version_data - Fill in the driver version in the dump. * @ioa_cfg: ioa config struct * @driver_dump: driver dump struct * * Return value: * nothing **/ static void ipr_dump_version_data(struct ipr_ioa_cfg *ioa_cfg, struct ipr_driver_dump *driver_dump) { … } /** * ipr_dump_trace_data - Fill in the IOA trace in the dump. * @ioa_cfg: ioa config struct * @driver_dump: driver dump struct * * Return value: * nothing **/ static void ipr_dump_trace_data(struct ipr_ioa_cfg *ioa_cfg, struct ipr_driver_dump *driver_dump) { … } /** * ipr_dump_location_data - Fill in the IOA location in the dump. * @ioa_cfg: ioa config struct * @driver_dump: driver dump struct * * Return value: * nothing **/ static void ipr_dump_location_data(struct ipr_ioa_cfg *ioa_cfg, struct ipr_driver_dump *driver_dump) { … } /** * ipr_get_ioa_dump - Perform a dump of the driver and adapter. * @ioa_cfg: ioa config struct * @dump: dump struct * * Return value: * nothing **/ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) { … } #else #define ipr_get_ioa_dump … #endif /** * ipr_release_dump - Free adapter dump memory * @kref: kref struct * * Return value: * nothing **/ static void ipr_release_dump(struct kref *kref) { … } static void ipr_add_remove_thread(struct work_struct *work) { … } /** * ipr_worker_thread - Worker thread * @work: ioa config struct * * Called at task level from a work thread. This function takes care * of adding and removing device from the mid-layer as configuration * changes are detected by the adapter. * * Return value: * nothing **/ static void ipr_worker_thread(struct work_struct *work) { … } #ifdef CONFIG_SCSI_IPR_TRACE /** * ipr_read_trace - Dump the adapter trace * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer * @off: offset * @count: buffer size * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_read_trace(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { … } static struct bin_attribute ipr_trace_attr = …; #endif /** * ipr_show_fw_version - Show the firmware version * @dev: class device struct * @attr: device attribute (unused) * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_fw_version(struct device *dev, struct device_attribute *attr, char *buf) { … } static struct device_attribute ipr_fw_version_attr = …; /** * ipr_show_log_level - Show the adapter's error logging level * @dev: class device struct * @attr: device attribute (unused) * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_log_level(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * ipr_store_log_level - Change the adapter's error logging level * @dev: class device struct * @attr: device attribute (unused) * @buf: buffer * @count: buffer size * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_store_log_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static struct device_attribute ipr_log_level_attr = …; /** * ipr_store_diagnostics - IOA Diagnostics interface * @dev: device struct * @attr: device attribute (unused) * @buf: buffer * @count: buffer size * * This function will reset the adapter and wait a reasonable * amount of time for any errors that the adapter might log. * * Return value: * count on success / other on failure **/ static ssize_t ipr_store_diagnostics(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static struct device_attribute ipr_diagnostics_attr = …; /** * ipr_show_adapter_state - Show the adapter's state * @dev: device struct * @attr: device attribute (unused) * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_adapter_state(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * ipr_store_adapter_state - Change adapter state * @dev: device struct * @attr: device attribute (unused) * @buf: buffer * @count: buffer size * * This function will change the adapter's state. * * Return value: * count on success / other on failure **/ static ssize_t ipr_store_adapter_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static struct device_attribute ipr_ioa_state_attr = …; /** * ipr_store_reset_adapter - Reset the adapter * @dev: device struct * @attr: device attribute (unused) * @buf: buffer * @count: buffer size * * This function will reset the adapter. * * Return value: * count on success / other on failure **/ static ssize_t ipr_store_reset_adapter(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static struct device_attribute ipr_ioa_reset_attr = …; static int ipr_iopoll(struct irq_poll *iop, int budget); /** * ipr_show_iopoll_weight - Show ipr polling mode * @dev: class device struct * @attr: device attribute (unused) * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_iopoll_weight(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * ipr_store_iopoll_weight - Change the adapter's polling mode * @dev: class device struct * @attr: device attribute (unused) * @buf: buffer * @count: buffer size * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_store_iopoll_weight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static struct device_attribute ipr_iopoll_weight_attr = …; /** * ipr_alloc_ucode_buffer - Allocates a microcode download buffer * @buf_len: buffer length * * Allocates a DMA'able buffer in chunks and assembles a scatter/gather * list to use for microcode download * * Return value: * pointer to sglist / NULL on failure **/ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len) { … } /** * ipr_free_ucode_buffer - Frees a microcode download buffer * @sglist: scatter/gather list pointer * * Free a DMA'able ucode download buffer previously allocated with * ipr_alloc_ucode_buffer * * Return value: * nothing **/ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist) { … } /** * ipr_copy_ucode_buffer - Copy user buffer to kernel buffer * @sglist: scatter/gather list pointer * @buffer: buffer pointer * @len: buffer length * * Copy a microcode image from a user buffer into a buffer allocated by * ipr_alloc_ucode_buffer * * Return value: * 0 on success / other on failure **/ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist, u8 *buffer, u32 len) { … } /** * ipr_build_ucode_ioadl64 - Build a microcode download IOADL * @ipr_cmd: ipr command struct * @sglist: scatter/gather list * * Builds a microcode download IOA data list (IOADL). * **/ static void ipr_build_ucode_ioadl64(struct ipr_cmnd *ipr_cmd, struct ipr_sglist *sglist) { … } /** * ipr_build_ucode_ioadl - Build a microcode download IOADL * @ipr_cmd: ipr command struct * @sglist: scatter/gather list * * Builds a microcode download IOA data list (IOADL). * **/ static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd, struct ipr_sglist *sglist) { … } /** * ipr_update_ioa_ucode - Update IOA's microcode * @ioa_cfg: ioa config struct * @sglist: scatter/gather list * * Initiate an adapter reset to update the IOA's microcode * * Return value: * 0 on success / -EIO on failure **/ static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg, struct ipr_sglist *sglist) { … } /** * ipr_store_update_fw - Update the firmware on the adapter * @dev: device struct * @attr: device attribute (unused) * @buf: buffer * @count: buffer size * * This function will update the firmware on the adapter. * * Return value: * count on success / other on failure **/ static ssize_t ipr_store_update_fw(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static struct device_attribute ipr_update_fw_attr = …; /** * ipr_show_fw_type - Show the adapter's firmware type. * @dev: class device struct * @attr: device attribute (unused) * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_fw_type(struct device *dev, struct device_attribute *attr, char *buf) { … } static struct device_attribute ipr_ioa_fw_type_attr = …; static ssize_t ipr_read_async_err_log(struct file *filep, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { … } static ssize_t ipr_next_async_err_log(struct file *filep, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { … } static struct bin_attribute ipr_ioa_async_err_log = …; static struct attribute *ipr_ioa_attrs[] = …; ATTRIBUTE_GROUPS(…); #ifdef CONFIG_SCSI_IPR_DUMP /** * ipr_read_dump - Dump the adapter * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer * @off: offset * @count: buffer size * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_read_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { … } /** * ipr_alloc_dump - Prepare for adapter dump * @ioa_cfg: ioa config struct * * Return value: * 0 on success / other on failure **/ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_free_dump - Free adapter dump memory * @ioa_cfg: ioa config struct * * Return value: * 0 on success / other on failure **/ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_write_dump - Setup dump state of adapter * @filp: open sysfs file * @kobj: kobject struct * @bin_attr: bin_attribute struct * @buf: buffer * @off: offset * @count: buffer size * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_write_dump(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { … } static struct bin_attribute ipr_dump_attr = …; #else static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { return 0; }; #endif /** * ipr_change_queue_depth - Change the device's queue depth * @sdev: scsi device struct * @qdepth: depth to set * * Return value: * actual depth set **/ static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth) { … } /** * ipr_show_adapter_handle - Show the adapter's resource handle for this device * @dev: device struct * @attr: device attribute structure * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribute *attr, char *buf) { … } static struct device_attribute ipr_adapter_handle_attr = …; /** * ipr_show_resource_path - Show the resource path or the resource address for * this device. * @dev: device struct * @attr: device attribute structure * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribute *attr, char *buf) { … } static struct device_attribute ipr_resource_path_attr = …; /** * ipr_show_device_id - Show the device_id for this device. * @dev: device struct * @attr: device attribute structure * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_device_id(struct device *dev, struct device_attribute *attr, char *buf) { … } static struct device_attribute ipr_device_id_attr = …; /** * ipr_show_resource_type - Show the resource type for this device. * @dev: device struct * @attr: device attribute structure * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_resource_type(struct device *dev, struct device_attribute *attr, char *buf) { … } static struct device_attribute ipr_resource_type_attr = …; /** * ipr_show_raw_mode - Show the adapter's raw mode * @dev: class device struct * @attr: device attribute (unused) * @buf: buffer * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_show_raw_mode(struct device *dev, struct device_attribute *attr, char *buf) { … } /** * ipr_store_raw_mode - Change the adapter's raw mode * @dev: class device struct * @attr: device attribute (unused) * @buf: buffer * @count: buffer size * * Return value: * number of bytes printed to buffer **/ static ssize_t ipr_store_raw_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { … } static struct device_attribute ipr_raw_mode_attr = …; static struct attribute *ipr_dev_attrs[] = …; ATTRIBUTE_GROUPS(…); /** * ipr_biosparam - Return the HSC mapping * @sdev: scsi device struct * @block_device: block device pointer * @capacity: capacity of the device * @parm: Array containing returned HSC values. * * This function generates the HSC parms that fdisk uses. * We want to make sure we return something that places partitions * on 4k boundaries for best performance with the IOA. * * Return value: * 0 on success **/ static int ipr_biosparam(struct scsi_device *sdev, struct block_device *block_device, sector_t capacity, int *parm) { … } /** * ipr_find_starget - Find target based on bus/target. * @starget: scsi target struct * * Return value: * resource entry pointer if found / NULL if not found **/ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget) { … } /** * ipr_target_destroy - Destroy a SCSI target * @starget: scsi target struct * **/ static void ipr_target_destroy(struct scsi_target *starget) { … } /** * ipr_find_sdev - Find device based on bus/target/lun. * @sdev: scsi device struct * * Return value: * resource entry pointer if found / NULL if not found **/ static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev) { … } /** * ipr_slave_destroy - Unconfigure a SCSI device * @sdev: scsi device struct * * Return value: * nothing **/ static void ipr_slave_destroy(struct scsi_device *sdev) { … } /** * ipr_device_configure - Configure a SCSI device * @sdev: scsi device struct * @lim: queue limits * * This function configures the specified scsi device. * * Return value: * 0 on success **/ static int ipr_device_configure(struct scsi_device *sdev, struct queue_limits *lim) { … } /** * ipr_slave_alloc - Prepare for commands to a device. * @sdev: scsi device struct * * This function saves a pointer to the resource entry * in the scsi device struct if the device exists. We * can then use this pointer in ipr_queuecommand when * handling new commands. * * Return value: * 0 on success / -ENXIO if device does not exist **/ static int ipr_slave_alloc(struct scsi_device *sdev) { … } /** * ipr_match_lun - Match function for specified LUN * @ipr_cmd: ipr command struct * @device: device to match (sdev) * * Returns: * 1 if command matches sdev / 0 if command does not match sdev **/ static int ipr_match_lun(struct ipr_cmnd *ipr_cmd, void *device) { … } /** * ipr_cmnd_is_free - Check if a command is free or not * @ipr_cmd: ipr command struct * * Returns: * true / false **/ static bool ipr_cmnd_is_free(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_wait_for_ops - Wait for matching commands to complete * @ioa_cfg: ioa config struct * @device: device to match (sdev) * @match: match function to use * * Returns: * SUCCESS / FAILED **/ static int ipr_wait_for_ops(struct ipr_ioa_cfg *ioa_cfg, void *device, int (*match)(struct ipr_cmnd *, void *)) { … } static int ipr_eh_host_reset(struct scsi_cmnd *cmd) { … } /** * ipr_device_reset - Reset the device * @ioa_cfg: ioa config struct * @res: resource entry struct * * This function issues a device reset to the affected device. * If the device is a SCSI device, a LUN reset will be sent * to the device first. If that does not work, a target reset * will be sent. * * Return value: * 0 on success / non-zero on failure **/ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, struct ipr_resource_entry *res) { … } /** * __ipr_eh_dev_reset - Reset the device * @scsi_cmd: scsi command struct * * This function issues a device reset to the affected device. * A LUN reset will be sent to the device first. If that does * not work, a target reset will be sent. * * Return value: * SUCCESS / FAILED **/ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd) { … } static int ipr_eh_dev_reset(struct scsi_cmnd *cmd) { … } /** * ipr_bus_reset_done - Op done function for bus reset. * @ipr_cmd: ipr command struct * * This function is the op done function for a bus reset * * Return value: * none **/ static void ipr_bus_reset_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_abort_timeout - An abort task has timed out * @t: Timer context used to fetch ipr command struct * * This function handles when an abort task times out. If this * happens we issue a bus reset since we have resources tied * up that must be freed before returning to the midlayer. * * Return value: * none **/ static void ipr_abort_timeout(struct timer_list *t) { … } /** * ipr_cancel_op - Cancel specified op * @scsi_cmd: scsi command struct * * This function cancels specified op. * * Return value: * SUCCESS / FAILED **/ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd) { … } /** * ipr_scan_finished - Report whether scan is done * @shost: scsi host struct * @elapsed_time: elapsed time * * Return value: * 0 if scan in progress / 1 if scan is complete **/ static int ipr_scan_finished(struct Scsi_Host *shost, unsigned long elapsed_time) { … } /** * ipr_eh_abort - Reset the host adapter * @scsi_cmd: scsi command struct * * Return value: * SUCCESS / FAILED **/ static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) { … } /** * ipr_handle_other_interrupt - Handle "other" interrupts * @ioa_cfg: ioa config struct * @int_reg: interrupt register * * Return value: * IRQ_NONE / IRQ_HANDLED **/ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg, u32 int_reg) { … } /** * ipr_isr_eh - Interrupt service routine error handler * @ioa_cfg: ioa config struct * @msg: message to log * @number: various meanings depending on the caller/message * * Return value: * none **/ static void ipr_isr_eh(struct ipr_ioa_cfg *ioa_cfg, char *msg, u16 number) { … } static int ipr_process_hrrq(struct ipr_hrr_queue *hrr_queue, int budget, struct list_head *doneq) { … } static int ipr_iopoll(struct irq_poll *iop, int budget) { … } /** * ipr_isr - Interrupt service routine * @irq: irq number * @devp: pointer to ioa config struct * * Return value: * IRQ_NONE / IRQ_HANDLED **/ static irqreturn_t ipr_isr(int irq, void *devp) { … } /** * ipr_isr_mhrrq - Interrupt service routine * @irq: irq number * @devp: pointer to ioa config struct * * Return value: * IRQ_NONE / IRQ_HANDLED **/ static irqreturn_t ipr_isr_mhrrq(int irq, void *devp) { … } /** * ipr_build_ioadl64 - Build a scatter/gather list and map the buffer * @ioa_cfg: ioa config struct * @ipr_cmd: ipr command struct * * Return value: * 0 on success / -1 on failure **/ static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg, struct ipr_cmnd *ipr_cmd) { … } /** * ipr_build_ioadl - Build a scatter/gather list and map the buffer * @ioa_cfg: ioa config struct * @ipr_cmd: ipr command struct * * Return value: * 0 on success / -1 on failure **/ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, struct ipr_cmnd *ipr_cmd) { … } /** * __ipr_erp_done - Process completion of ERP for a device * @ipr_cmd: ipr command struct * * This function copies the sense buffer into the scsi_cmd * struct and pushes the scsi_done function. * * Return value: * nothing **/ static void __ipr_erp_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_erp_done - Process completion of ERP for a device * @ipr_cmd: ipr command struct * * This function copies the sense buffer into the scsi_cmd * struct and pushes the scsi_done function. * * Return value: * nothing **/ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reinit_ipr_cmnd_for_erp - Re-initialize a cmnd block to be used for ERP * @ipr_cmd: ipr command struct * * Return value: * none **/ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) { … } /** * __ipr_erp_request_sense - Send request sense to a device * @ipr_cmd: ipr command struct * * This function sends a request sense to a device as a result * of a check condition. * * Return value: * nothing **/ static void __ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_erp_request_sense - Send request sense to a device * @ipr_cmd: ipr command struct * * This function sends a request sense to a device as a result * of a check condition. * * Return value: * nothing **/ static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_erp_cancel_all - Send cancel all to a device * @ipr_cmd: ipr command struct * * This function sends a cancel all to a device to clear the * queue. If we are running TCQ on the device, QERR is set to 1, * which means all outstanding ops have been dropped on the floor. * Cancel all will return them to us. * * Return value: * nothing **/ static void ipr_erp_cancel_all(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_dump_ioasa - Dump contents of IOASA * @ioa_cfg: ioa config struct * @ipr_cmd: ipr command struct * @res: resource entry struct * * This function is invoked by the interrupt handler when ops * fail. It will log the IOASA if appropriate. Only called * for GPDD ops. * * Return value: * none **/ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, struct ipr_cmnd *ipr_cmd, struct ipr_resource_entry *res) { … } /** * ipr_gen_sense - Generate SCSI sense data from an IOASA * @ipr_cmd: ipr command struct * * Return value: * none **/ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_get_autosense - Copy autosense data to sense buffer * @ipr_cmd: ipr command struct * * This function copies the autosense buffer to the buffer * in the scsi_cmd, if there is autosense available. * * Return value: * 1 if autosense was available / 0 if not **/ static int ipr_get_autosense(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_erp_start - Process an error response for a SCSI op * @ioa_cfg: ioa config struct * @ipr_cmd: ipr command struct * * This function determines whether or not to initiate ERP * on the affected device. * * Return value: * nothing **/ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, struct ipr_cmnd *ipr_cmd) { … } /** * ipr_scsi_done - mid-layer done function * @ipr_cmd: ipr command struct * * This function is invoked by the interrupt handler for * ops generated by the SCSI mid-layer * * Return value: * none **/ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_queuecommand - Queue a mid-layer request * @shost: scsi host struct * @scsi_cmd: scsi command struct * * This function queues a request generated by the mid-layer. * * Return value: * 0 on success * SCSI_MLQUEUE_DEVICE_BUSY if device is busy * SCSI_MLQUEUE_HOST_BUSY if host is busy **/ static int ipr_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scsi_cmd) { … } /** * ipr_ioa_info - Get information about the card/driver * @host: scsi host struct * * Return value: * pointer to buffer with description string **/ static const char *ipr_ioa_info(struct Scsi_Host *host) { … } static const struct scsi_host_template driver_template = …; /** * ipr_ioa_bringdown_done - IOA bring down completion. * @ipr_cmd: ipr command struct * * This function processes the completion of an adapter bring down. * It wakes any reset sleepers. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioa_bringdown_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioa_reset_done - IOA reset completion. * @ipr_cmd: ipr command struct * * This function processes the completion of an adapter reset. * It schedules any necessary mid-layer add/removes and * wakes any reset sleepers. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_set_sup_dev_dflt - Initialize a Set Supported Device buffer * @supported_dev: supported device struct * @vpids: vendor product id struct * * Return value: * none **/ static void ipr_set_sup_dev_dflt(struct ipr_supported_device *supported_dev, struct ipr_std_inq_vpids *vpids) { … } /** * ipr_set_supported_devs - Send Set Supported Devices for a device * @ipr_cmd: ipr command struct * * This function sends a Set Supported Devices to the adapter * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_get_mode_page - Locate specified mode page * @mode_pages: mode page buffer * @page_code: page code to find * @len: minimum required length for mode page * * Return value: * pointer to mode page / NULL on failure **/ static void *ipr_get_mode_page(struct ipr_mode_pages *mode_pages, u32 page_code, u32 len) { … } /** * ipr_check_term_power - Check for term power errors * @ioa_cfg: ioa config struct * @mode_pages: IOAFP mode pages buffer * * Check the IOAFP's mode page 28 for term power errors * * Return value: * nothing **/ static void ipr_check_term_power(struct ipr_ioa_cfg *ioa_cfg, struct ipr_mode_pages *mode_pages) { … } /** * ipr_scsi_bus_speed_limit - Limit the SCSI speed based on SES table * @ioa_cfg: ioa config struct * * Looks through the config table checking for SES devices. If * the SES device is in the SES table indicating a maximum SCSI * bus speed, the speed is limited for the bus. * * Return value: * none **/ static void ipr_scsi_bus_speed_limit(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_modify_ioafp_mode_page_28 - Modify IOAFP Mode Page 28 * @ioa_cfg: ioa config struct * @mode_pages: mode page 28 buffer * * Updates mode page 28 based on driver configuration * * Return value: * none **/ static void ipr_modify_ioafp_mode_page_28(struct ipr_ioa_cfg *ioa_cfg, struct ipr_mode_pages *mode_pages) { … } /** * ipr_build_mode_select - Build a mode select command * @ipr_cmd: ipr command struct * @res_handle: resource handle to send command to * @parm: Byte 2 of Mode Sense command * @dma_addr: DMA buffer address * @xfer_len: data transfer length * * Return value: * none **/ static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, __be32 res_handle, u8 parm, dma_addr_t dma_addr, u8 xfer_len) { … } /** * ipr_ioafp_mode_select_page28 - Issue Mode Select Page 28 to IOA * @ipr_cmd: ipr command struct * * This function sets up the SCSI bus attributes and sends * a Mode Select for Page 28 to activate them. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_build_mode_sense - Builds a mode sense command * @ipr_cmd: ipr command struct * @res_handle: resource entry struct * @parm: Byte 2 of mode sense command * @dma_addr: DMA address of mode sense buffer * @xfer_len: Size of DMA buffer * * Return value: * none **/ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, __be32 res_handle, u8 parm, dma_addr_t dma_addr, u8 xfer_len) { … } /** * ipr_reset_cmd_failed - Handle failure of IOA reset command * @ipr_cmd: ipr command struct * * This function handles the failure of an IOA bringup command. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_mode_sense_failed - Handle failure of IOAFP mode sense * @ipr_cmd: ipr command struct * * This function handles the failure of a Mode Sense to the IOAFP. * Some adapters do not handle all mode pages. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_mode_sense_page28 - Issue Mode Sense Page 28 to IOA * @ipr_cmd: ipr command struct * * This function send a Page 28 mode sense to the IOA to * retrieve SCSI bus attributes. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_mode_sense_page28(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_mode_select_page24 - Issue Mode Select to IOA * @ipr_cmd: ipr command struct * * This function enables dual IOA RAID support if possible. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_mode_select_page24(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_mode_sense_page24_failed - Handle failure of IOAFP mode sense * @ipr_cmd: ipr command struct * * This function handles the failure of a Mode Sense to the IOAFP. * Some adapters do not handle all mode pages. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_mode_sense_page24_failed(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_mode_sense_page24 - Issue Page 24 Mode Sense to IOA * @ipr_cmd: ipr command struct * * This function send a mode sense to the IOA to retrieve * the IOA Advanced Function Control mode page. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_mode_sense_page24(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_init_res_table - Initialize the resource table * @ipr_cmd: ipr command struct * * This function looks through the existing resource table, comparing * it with the config table. This function will take care of old/new * devices and schedule adding/removing them from the mid-layer * as appropriate. * * Return value: * IPR_RC_JOB_CONTINUE **/ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_query_ioa_cfg - Send a Query IOA Config to the adapter. * @ipr_cmd: ipr command struct * * This function sends a Query IOA Configuration command * to the adapter to retrieve the IOA configuration table. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) { … } static int ipr_ioa_service_action_failed(struct ipr_cmnd *ipr_cmd) { … } static void ipr_build_ioa_service_action(struct ipr_cmnd *ipr_cmd, __be32 res_handle, u8 sa_code) { … } /** * ipr_ioafp_set_caching_parameters - Issue Set Cache parameters service * action * @ipr_cmd: ipr command struct * * Return value: * none **/ static int ipr_ioafp_set_caching_parameters(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_inquiry - Send an Inquiry to the adapter. * @ipr_cmd: ipr command struct * @flags: flags to send * @page: page to inquire * @dma_addr: DMA address * @xfer_len: transfer data length * * This utility function sends an inquiry to the adapter. * * Return value: * none **/ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, dma_addr_t dma_addr, u8 xfer_len) { … } /** * ipr_inquiry_page_supported - Is the given inquiry page supported * @page0: inquiry page 0 buffer * @page: page code. * * This function determines if the specified inquiry page is supported. * * Return value: * 1 if page is supported / 0 if not **/ static int ipr_inquiry_page_supported(struct ipr_inquiry_page0 *page0, u8 page) { … } /** * ipr_ioafp_pageC4_inquiry - Send a Page 0xC4 Inquiry to the adapter. * @ipr_cmd: ipr command struct * * This function sends a Page 0xC4 inquiry to the adapter * to retrieve software VPD information. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_ioafp_pageC4_inquiry(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_cap_inquiry - Send a Page 0xD0 Inquiry to the adapter. * @ipr_cmd: ipr command struct * * This function sends a Page 0xD0 inquiry to the adapter * to retrieve adapter capabilities. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_page3_inquiry - Send a Page 3 Inquiry to the adapter. * @ipr_cmd: ipr command struct * * This function sends a Page 3 inquiry to the adapter * to retrieve software VPD information. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_page0_inquiry - Send a Page 0 Inquiry to the adapter. * @ipr_cmd: ipr command struct * * This function sends a Page 0 inquiry to the adapter * to retrieve supported inquiry pages. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_ioafp_page0_inquiry(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_std_inquiry - Send a Standard Inquiry to the adapter. * @ipr_cmd: ipr command struct * * This function sends a standard inquiry to the adapter. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_ioafp_identify_hrrq - Send Identify Host RRQ. * @ipr_cmd: ipr command struct * * This function send an Identify Host Request Response Queue * command to establish the HRRQ with the adapter. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_ioafp_identify_hrrq(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_timer_done - Adapter reset timer function * @t: Timer context used to fetch ipr command struct * * Description: This function is used in adapter reset processing * for timing events. If the reset_cmd pointer in the IOA * config struct is not this adapter's we are doing nested * resets and fail_all_ops will take care of freeing the * command block. * * Return value: * none **/ static void ipr_reset_timer_done(struct timer_list *t) { … } /** * ipr_reset_start_timer - Start a timer for adapter reset job * @ipr_cmd: ipr command struct * @timeout: timeout value * * Description: This function is used in adapter reset processing * for timing events. If the reset_cmd pointer in the IOA * config struct is not this adapter's we are doing nested * resets and fail_all_ops will take care of freeing the * command block. * * Return value: * none **/ static void ipr_reset_start_timer(struct ipr_cmnd *ipr_cmd, unsigned long timeout) { … } /** * ipr_init_ioa_mem - Initialize ioa_cfg control block * @ioa_cfg: ioa cfg struct * * Return value: * nothing **/ static void ipr_init_ioa_mem(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_reset_next_stage - Process IPL stage change based on feedback register. * @ipr_cmd: ipr command struct * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_enable_ioa - Enable the IOA following a reset. * @ipr_cmd: ipr command struct * * This function reinitializes some control blocks and * enables destructive diagnostics on the adapter. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_wait_for_dump - Wait for a dump to timeout. * @ipr_cmd: ipr command struct * * This function is invoked when an adapter dump has run out * of processing time. * * Return value: * IPR_RC_JOB_CONTINUE **/ static int ipr_reset_wait_for_dump(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_unit_check_no_data - Log a unit check/no data error log * @ioa_cfg: ioa config struct * * Logs an error indicating the adapter unit checked, but for some * reason, we were unable to fetch the unit check buffer. * * Return value: * nothing **/ static void ipr_unit_check_no_data(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_get_unit_check_buffer - Get the unit check buffer from the IOA * @ioa_cfg: ioa config struct * * Fetches the unit check buffer from the adapter by clocking the data * through the mailbox register. * * Return value: * nothing **/ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_reset_get_unit_check_job - Call to get the unit check buffer. * @ipr_cmd: ipr command struct * * Description: This function will call to get the unit check buffer. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_reset_get_unit_check_job(struct ipr_cmnd *ipr_cmd) { … } static int ipr_dump_mailbox_wait(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_restore_cfg_space - Restore PCI config space. * @ipr_cmd: ipr command struct * * Description: This function restores the saved PCI config space of * the adapter, fails all outstanding ops back to the callers, and * fetches the dump/unit check if applicable to this reset. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_bist_done - BIST has completed on the adapter. * @ipr_cmd: ipr command struct * * Description: Unblock config space and resume the reset process. * * Return value: * IPR_RC_JOB_CONTINUE **/ static int ipr_reset_bist_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_start_bist - Run BIST on the adapter. * @ipr_cmd: ipr command struct * * Description: This function runs BIST on the adapter, then delays 2 seconds. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_slot_reset_done - Clear PCI reset to the adapter * @ipr_cmd: ipr command struct * * Description: This clears PCI reset to the adapter and delays two seconds. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_reset_work - Pulse a PCIe fundamental reset * @work: work struct * * Description: This pulses warm reset to a slot. * **/ static void ipr_reset_reset_work(struct work_struct *work) { … } /** * ipr_reset_slot_reset - Reset the PCI slot of the adapter. * @ipr_cmd: ipr command struct * * Description: This asserts PCI reset to the adapter. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_block_config_access_wait - Wait for permission to block config access * @ipr_cmd: ipr command struct * * Description: This attempts to block config access to the IOA. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_block_config_access_wait(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_block_config_access - Block config access to the IOA * @ipr_cmd: ipr command struct * * Description: This attempts to block config access to the IOA * * Return value: * IPR_RC_JOB_CONTINUE **/ static int ipr_reset_block_config_access(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_allowed - Query whether or not IOA can be reset * @ioa_cfg: ioa config struct * * Return value: * 0 if reset not allowed / non-zero if reset is allowed **/ static int ipr_reset_allowed(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_reset_wait_to_start_bist - Wait for permission to reset IOA. * @ipr_cmd: ipr command struct * * Description: This function waits for adapter permission to run BIST, * then runs BIST. If the adapter does not give permission after a * reasonable time, we will reset the adapter anyway. The impact of * resetting the adapter without warning the adapter is the risk of * losing the persistent error log on the adapter. If the adapter is * reset while it is writing to the flash on the adapter, the flash * segment will have bad ECC and be zeroed. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_wait_to_start_bist(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_alert - Alert the adapter of a pending reset * @ipr_cmd: ipr command struct * * Description: This function alerts the adapter that it will be reset. * If memory space is not currently enabled, proceed directly * to running BIST on the adapter. The timer must always be started * so we guarantee we do not run BIST from ipr_isr. * * Return value: * IPR_RC_JOB_RETURN **/ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_quiesce_done - Complete IOA disconnect * @ipr_cmd: ipr command struct * * Description: Freeze the adapter to complete quiesce processing * * Return value: * IPR_RC_JOB_CONTINUE **/ static int ipr_reset_quiesce_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_cancel_hcam_done - Check for outstanding commands * @ipr_cmd: ipr command struct * * Description: Ensure nothing is outstanding to the IOA and * proceed with IOA disconnect. Otherwise reset the IOA. * * Return value: * IPR_RC_JOB_RETURN / IPR_RC_JOB_CONTINUE **/ static int ipr_reset_cancel_hcam_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_cancel_hcam - Cancel outstanding HCAMs * @ipr_cmd: ipr command struct * * Description: Cancel any oustanding HCAMs to the IOA. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_cancel_hcam(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_ucode_download_done - Microcode download completion * @ipr_cmd: ipr command struct * * Description: This function unmaps the microcode download buffer. * * Return value: * IPR_RC_JOB_CONTINUE **/ static int ipr_reset_ucode_download_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_ucode_download - Download microcode to the adapter * @ipr_cmd: ipr command struct * * Description: This function checks to see if it there is microcode * to download to the adapter. If there is, a download is performed. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_shutdown_ioa - Shutdown the adapter * @ipr_cmd: ipr command struct * * Description: This function issues an adapter shutdown of the * specified type to the specified adapter as part of the * adapter reset job. * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN **/ static int ipr_reset_shutdown_ioa(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_reset_ioa_job - Adapter reset job * @ipr_cmd: ipr command struct * * Description: This function is the job router for the adapter reset job. * * Return value: * none **/ static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd) { … } /** * _ipr_initiate_ioa_reset - Initiate an adapter reset * @ioa_cfg: ioa config struct * @job_step: first job step of reset job * @shutdown_type: shutdown type * * Description: This function will initiate the reset of the given adapter * starting at the selected job step. * If the caller needs to wait on the completion of the reset, * the caller must sleep on the reset_wait_q. * * Return value: * none **/ static void _ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg, int (*job_step) (struct ipr_cmnd *), enum ipr_shutdown_type shutdown_type) { … } /** * ipr_initiate_ioa_reset - Initiate an adapter reset * @ioa_cfg: ioa config struct * @shutdown_type: shutdown type * * Description: This function will initiate the reset of the given adapter. * If the caller needs to wait on the completion of the reset, * the caller must sleep on the reset_wait_q. * * Return value: * none **/ static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg, enum ipr_shutdown_type shutdown_type) { … } /** * ipr_reset_freeze - Hold off all I/O activity * @ipr_cmd: ipr command struct * * Description: If the PCI slot is frozen, hold off all I/O * activity; then, as soon as the slot is available again, * initiate an adapter reset. */ static int ipr_reset_freeze(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_pci_mmio_enabled - Called when MMIO has been re-enabled * @pdev: PCI device struct * * Description: This routine is called to tell us that the MMIO * access to the IOA has been restored */ static pci_ers_result_t ipr_pci_mmio_enabled(struct pci_dev *pdev) { … } /** * ipr_pci_frozen - Called when slot has experienced a PCI bus error. * @pdev: PCI device struct * * Description: This routine is called to tell us that the PCI bus * is down. Can't do anything here, except put the device driver * into a holding pattern, waiting for the PCI bus to come back. */ static void ipr_pci_frozen(struct pci_dev *pdev) { … } /** * ipr_pci_slot_reset - Called when PCI slot has been reset. * @pdev: PCI device struct * * Description: This routine is called by the pci error recovery * code after the PCI slot has been reset, just before we * should resume normal operations. */ static pci_ers_result_t ipr_pci_slot_reset(struct pci_dev *pdev) { … } /** * ipr_pci_perm_failure - Called when PCI slot is dead for good. * @pdev: PCI device struct * * Description: This routine is called when the PCI bus has * permanently failed. */ static void ipr_pci_perm_failure(struct pci_dev *pdev) { … } /** * ipr_pci_error_detected - Called when a PCI error is detected. * @pdev: PCI device struct * @state: PCI channel state * * Description: Called when a PCI error is detected. * * Return value: * PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT */ static pci_ers_result_t ipr_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { … } /** * ipr_probe_ioa_part2 - Initializes IOAs found in ipr_probe_ioa(..) * @ioa_cfg: ioa cfg struct * * Description: This is the second phase of adapter initialization * This function takes care of initilizing the adapter to the point * where it can accept new commands. * Return value: * none **/ static void ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_free_cmd_blks - Frees command blocks allocated for an adapter * @ioa_cfg: ioa config struct * * Return value: * none **/ static void ipr_free_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_free_mem - Frees memory allocated for an adapter * @ioa_cfg: ioa cfg struct * * Return value: * nothing **/ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_free_irqs - Free all allocated IRQs for the adapter. * @ioa_cfg: ipr cfg struct * * This function frees all allocated IRQs for the * specified adapter. * * Return value: * none **/ static void ipr_free_irqs(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_free_all_resources - Free all allocated resources for an adapter. * @ioa_cfg: ioa config struct * * This function frees all allocated resources for the * specified adapter. * * Return value: * none **/ static void ipr_free_all_resources(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_alloc_cmd_blks - Allocate command blocks for an adapter * @ioa_cfg: ioa config struct * * Return value: * 0 on success / -ENOMEM on allocation failure **/ static int ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_alloc_mem - Allocate memory for an adapter * @ioa_cfg: ioa config struct * * Return value: * 0 on success / non-zero for error **/ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_initialize_bus_attr - Initialize SCSI bus attributes to default values * @ioa_cfg: ioa config struct * * Return value: * none **/ static void ipr_initialize_bus_attr(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_init_regs - Initialize IOA registers * @ioa_cfg: ioa config struct * * Return value: * none **/ static void ipr_init_regs(struct ipr_ioa_cfg *ioa_cfg) { … } /** * ipr_init_ioa_cfg - Initialize IOA config struct * @ioa_cfg: ioa config struct * @host: scsi host struct * @pdev: PCI dev struct * * Return value: * none **/ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, struct Scsi_Host *host, struct pci_dev *pdev) { … } /** * ipr_get_chip_info - Find adapter chip information * @dev_id: PCI device id struct * * Return value: * ptr to chip information on success / NULL on failure **/ static const struct ipr_chip_t * ipr_get_chip_info(const struct pci_device_id *dev_id) { … } /** * ipr_wait_for_pci_err_recovery - Wait for any PCI error recovery to complete * during probe time * @ioa_cfg: ioa config struct * * Return value: * None **/ static void ipr_wait_for_pci_err_recovery(struct ipr_ioa_cfg *ioa_cfg) { … } static void name_msi_vectors(struct ipr_ioa_cfg *ioa_cfg) { … } static int ipr_request_other_msi_irqs(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev) { … } /** * ipr_test_intr - Handle the interrupt generated in ipr_test_msi(). * @devp: PCI device struct * @irq: IRQ number * * Description: Simply set the msi_received flag to 1 indicating that * Message Signaled Interrupts are supported. * * Return value: * 0 on success / non-zero on failure **/ static irqreturn_t ipr_test_intr(int irq, void *devp) { … } /** * ipr_test_msi - Test for Message Signaled Interrupt (MSI) support. * @ioa_cfg: ioa config struct * @pdev: PCI device struct * * Description: This routine sets up and initiates a test interrupt to determine * if the interrupt is received via the ipr_test_intr() service routine. * If the tests fails, the driver will fall back to LSI. * * Return value: * 0 on success / non-zero on failure **/ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev) { … } /* ipr_probe_ioa - Allocates memory and does first stage of initialization * @pdev: PCI device struct * @dev_id: PCI device id struct * * Return value: * 0 on success / non-zero on failure **/ static int ipr_probe_ioa(struct pci_dev *pdev, const struct pci_device_id *dev_id) { … } /** * ipr_initiate_ioa_bringdown - Bring down an adapter * @ioa_cfg: ioa config struct * @shutdown_type: shutdown type * * Description: This function will initiate bringing down the adapter. * This consists of issuing an IOA shutdown to the adapter * to flush the cache, and running BIST. * If the caller needs to wait on the completion of the reset, * the caller must sleep on the reset_wait_q. * * Return value: * none **/ static void ipr_initiate_ioa_bringdown(struct ipr_ioa_cfg *ioa_cfg, enum ipr_shutdown_type shutdown_type) { … } /** * __ipr_remove - Remove a single adapter * @pdev: pci device struct * * Adapter hot plug remove entry point. * * Return value: * none **/ static void __ipr_remove(struct pci_dev *pdev) { … } /** * ipr_remove - IOA hot plug remove entry point * @pdev: pci device struct * * Adapter hot plug remove entry point. * * Return value: * none **/ static void ipr_remove(struct pci_dev *pdev) { … } /** * ipr_probe - Adapter hot plug add entry point * @pdev: pci device struct * @dev_id: pci device ID * * Return value: * 0 on success / non-zero on failure **/ static int ipr_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) { … } /** * ipr_shutdown - Shutdown handler. * @pdev: pci device struct * * This function is invoked upon system shutdown/reboot. It will issue * an adapter shutdown to the adapter to flush the write cache. * * Return value: * none **/ static void ipr_shutdown(struct pci_dev *pdev) { … } static struct pci_device_id ipr_pci_table[] = …; MODULE_DEVICE_TABLE(pci, ipr_pci_table); static const struct pci_error_handlers ipr_err_handler = …; static struct pci_driver ipr_driver = …; /** * ipr_halt_done - Shutdown prepare completion * @ipr_cmd: ipr command struct * * Return value: * none **/ static void ipr_halt_done(struct ipr_cmnd *ipr_cmd) { … } /** * ipr_halt - Issue shutdown prepare to all adapters * @nb: Notifier block * @event: Notifier event * @buf: Notifier data (unused) * * Return value: * NOTIFY_OK on success / NOTIFY_DONE on failure **/ static int ipr_halt(struct notifier_block *nb, ulong event, void *buf) { … } static struct notifier_block ipr_notifier = …; /** * ipr_init - Module entry point * * Return value: * 0 on success / negative value on failure **/ static int __init ipr_init(void) { … } /** * ipr_exit - Module unload * * Module unload entry point. * * Return value: * none **/ static void __exit ipr_exit(void) { … } module_init(…) …; module_exit(ipr_exit);