⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ips.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************//* ips.c -- driver for the IBM ServeRAID controller                          *//*                                                                           *//* Written By: Keith Mitchell, IBM Corporation                               *//*                                                                           *//* Copyright (C) 1999 IBM Corporation                                        *//*                                                                           *//* 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//*                                                                           *//* Bugs/Comments/Suggestions should be mailed to:                            *//*      ipslinux@us.ibm.com                                                  *//*                                                                           *//*****************************************************************************//*****************************************************************************//* Change Log                                                                *//*                                                                           *//* 0.99.02  - Breakup commands that are bigger than 8 * the stripe size      *//* 0.99.03  - Make interrupt routine handle all completed request on the     *//*            adapter not just the first one                                 *//*          - Make sure passthru commands get woken up if we run out of      *//*            SCBs                                                           *//*          - Send all of the commands on the queue at once rather than      *//*            one at a time since the card will support it.                  *//* 0.99.04  - Fix race condition in the passthru mechanism -- this required  *//*            the interface to the utilities to change                       *//*          - Fix error recovery code                                        *//* 0.99.05  - Fix an oops when we get certain passthru commands              *//* 1.00.00  - Initial Public Release                                         *//*            Functionally equivalent to 0.99.05                             *//* 3.60.00  - Bump max commands to 128 for use with ServeRAID firmware 3.60  *//*          - Change version to 3.60 to coincide with ServeRAID release      *//*            numbering.                                                     *//* 3.60.01  - Remove bogus error check in passthru routine                   *//* 3.60.02  - Make DCDB direction based on lookup table                      *//*          - Only allow one DCDB command to a SCSI ID at a time             *//* 4.00.00  - Add support for ServeRAID 4                                    *//* 4.00.01  - Add support for First Failure Data Capture                     *//* 4.00.02  - Fix problem with PT DCDB with no buffer                        *//* 4.00.03  - Add alternative passthru interface                             *//*          - Add ability to flash ServeRAID BIOS                            *//* 4.00.04  - Rename structures/constants to be prefixed with IPS_           *//* 4.00.05  - Remove wish_block from init routine                            *//*          - Use linux/spinlock.h instead of asm/spinlock.h for kernels     *//*            2.3.18 and later                                               *//*          - Sync with other changes from the 2.3 kernels                   *//* 4.00.06  - Fix timeout with initial FFDC command                          *//* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@caldera.de>    *//* 4.10.00  - Add support for ServeRAID 4M/4L                                *//* 4.10.13  - Fix for dynamic unload and proc file system                    *//* 4.20.03  - Rename version to coincide with new release schedules          *//*            Performance fixes                                              *//*            Fix truncation of /proc files with cat                         *//*            Merge in changes through kernel 2.4.0test1ac21                 *//* 4.20.13  - Fix some failure cases / reset code                            *//*          - Hook into the reboot_notifier to flush the controller cache    *//*                                                                           *//*****************************************************************************//* * Conditional Compilation directives for this driver: * * IPS_DEBUG            - Turn on debugging info * * * Parameters: * * debug:<number>       - Set debug level to <number> *                        NOTE: only works when IPS_DEBUG compile directive *                              is used. * *       1              - Normal debug messages *       2              - Verbose debug messages *       11             - Method trace (non interrupt) *       12             - Method trace (includes interrupt) * * noreset              - Don't reset the controller * nocmdline            - Turn off passthru support * noi2o                - Don't use I2O Queues (ServeRAID 4 only) * nommap               - Don't use memory mapped I/O */  #include <linux/module.h>#include <asm/io.h>#include <asm/byteorder.h>#include <linux/stddef.h>#include <linux/version.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/ioport.h>#include <linux/malloc.h>#include <linux/vmalloc.h>#include <linux/delay.h>#include <linux/sched.h>#include <linux/pci.h>#include <linux/proc_fs.h>#include <linux/reboot.h>#include <linux/blk.h>#include <linux/types.h>#ifndef NO_IPS_CMDLINE#include <scsi/sg.h>#endif#include "sd.h"#include "scsi.h"#include "hosts.h"#include "ips.h"#include <linux/stat.h>#include <linux/config.h>#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,18)#include <linux/spinlock.h>#else#include <asm/spinlock.h>#endif#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)#include <linux/init.h>#endif#include <linux/smp.h>#ifdef MODULE   static char *ips = NULL;   MODULE_PARM(ips, "s");#endif/* * DRIVER_VER */#define IPS_VERSION_HIGH        "4.20"#define IPS_VERSION_LOW         ".20 "#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)struct proc_dir_entry proc_scsi_ips = {   0,   3, "ips",   S_IFDIR | S_IRUGO | S_IXUGO, 2};#endif#if !defined(__i386__)   #error "This driver has only been tested on the x86 platform"#endif#if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0)   #error "This driver only works with kernel 2.2.0 and later"#endif#if !defined(NO_IPS_CMDLINE) && ((SG_BIG_BUFF < 8192) || !defined(SG_BIG_BUFF))   #error "To use the command-line interface you need to define SG_BIG_BUFF"#endif#ifdef IPS_DEBUG   #define METHOD_TRACE(s, i)    if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");   #define DEBUG(i, s)           if (ips_debug >= i) printk(KERN_NOTICE s "\n");   #define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);#else   #define METHOD_TRACE(s, i)   #define DEBUG(i, s)   #define DEBUG_VAR(i, s, v...)#endif/* * global variables */static const char * ips_name = "ips";static struct Scsi_Host * ips_sh[IPS_MAX_ADAPTERS];  /* Array of host controller structures */static ips_ha_t * ips_ha[IPS_MAX_ADAPTERS];          /* Array of HA structures */static unsigned int ips_next_controller = 0;static unsigned int ips_num_controllers = 0;static unsigned int ips_released_controllers = 0;static int          ips_cmd_timeout = 60;static int          ips_reset_timeout = 60 * 5;static int          ips_force_memio = 1;             /* Always use Memory Mapped I/O    */static int          ips_force_i2o = 1;               /* Always use I2O command delivery */static int          ips_resetcontroller = 1;         /* Reset the controller            */static int          ips_cmdline = 1;                 /* Support for passthru            */#ifdef IPS_DEBUGstatic int          ips_debug = 0;                   /* Debug mode                      */#endif/* * Necessary forward function protoypes */static int ips_halt(struct notifier_block *nb, ulong event, void *buf);#define MAX_ADAPTER_NAME 9static char ips_adapter_name[][30] = {   "ServeRAID",   "ServeRAID II",   "ServeRAID on motherboard",   "ServeRAID on motherboard",   "ServeRAID 3H",   "ServeRAID 3L",   "ServeRAID 4H",   "ServeRAID 4M",   "ServeRAID 4L"};static struct notifier_block ips_notifier = {   ips_halt, NULL, 0};/* * Direction table */static char ips_command_direction[] = {IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_UNK,IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_IN,   IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_OUT,IPS_DATA_NONE, IPS_DATA_UNK,  IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_IN,IPS_DATA_UNK,  IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_NONE, IPS_DATA_UNK,IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,IPS_DATA_OUT,  IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_NONE, IPS_DATA_NONE,IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_OUT,IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_NONE,IPS_DATA_UNK,  IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,IPS_DATA_NONE, IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_OUT,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,  IPS_DATA_IN,   IPS_DATA_NONE,IPS_DATA_OUT,  IPS_DATA_UNK,  IPS_DATA_NONE, IPS_DATA_UNK,  IPS_DATA_OUT,IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_NONE,IPS_DATA_UNK,  IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_IN,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_OUT,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK};/* * Function prototypes */int ips_detect(Scsi_Host_Template *);int ips_release(struct Scsi_Host *);int ips_eh_abort(Scsi_Cmnd *);int ips_eh_reset(Scsi_Cmnd *);int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));int ips_biosparam(Disk *, kdev_t, int *);const char * ips_info(struct Scsi_Host *);void do_ipsintr(int, void *, struct pt_regs *);static int ips_hainit(ips_ha_t *);static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);static int ips_send(ips_ha_t *, ips_scb_t *, ips_scb_callback);static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);static int ips_send_cmd(ips_ha_t *, ips_scb_t *);static int ips_online(ips_ha_t *, ips_scb_t *);static int ips_inquiry(ips_ha_t *, ips_scb_t *);static int ips_rdcap(ips_ha_t *, ips_scb_t *);static int ips_msense(ips_ha_t *, ips_scb_t *);static int ips_reqsen(ips_ha_t *, ips_scb_t *);static int ips_allocatescbs(ips_ha_t *);static int ips_reset_copperhead(ips_ha_t *);static int ips_reset_copperhead_memio(ips_ha_t *);static int ips_reset_morpheus(ips_ha_t *);static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);static int ips_isintr_copperhead(ips_ha_t *);static int ips_isintr_copperhead_memio(ips_ha_t *);static int ips_isintr_morpheus(ips_ha_t *);static int ips_wait(ips_ha_t *, int, int);static int ips_write_driver_status(ips_ha_t *, int);static int ips_read_adapter_status(ips_ha_t *, int);static int ips_read_subsystem_parameters(ips_ha_t *, int);static int ips_read_config(ips_ha_t *, int);static int ips_clear_adapter(ips_ha_t *, int);static int ips_readwrite_page5(ips_ha_t *, int, int);static int ips_init_copperhead(ips_ha_t *);static int ips_init_copperhead_memio(ips_ha_t *);static int ips_init_morpheus(ips_ha_t *);static int ips_isinit_copperhead(ips_ha_t *);static int ips_isinit_copperhead_memio(ips_ha_t *);static int ips_isinit_morpheus(ips_ha_t *);static u32 ips_statupd_copperhead(ips_ha_t *);static u32 ips_statupd_copperhead_memio(ips_ha_t *);static u32 ips_statupd_morpheus(ips_ha_t *);static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);static void ips_enable_int_copperhead(ips_ha_t *);static void ips_enable_int_copperhead_memio(ips_ha_t *);static void ips_enable_int_morpheus(ips_ha_t *);static void ips_intr_copperhead(ips_ha_t *);static void ips_intr_morpheus(ips_ha_t *);static void ips_next(ips_ha_t *, int);static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);static void ipsintr_done(ips_ha_t *, struct ips_scb *);static void ips_done(ips_ha_t *, ips_scb_t *);static void ips_free(ips_ha_t *);static void ips_init_scb(ips_ha_t *, ips_scb_t *);static void ips_freescb(ips_ha_t *, ips_scb_t *);static void ips_statinit(ips_ha_t *);static void ips_statinit_memio(ips_ha_t *);static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);static void ips_ffdc_reset(ips_ha_t *, int);static void ips_ffdc_time(ips_ha_t *, int);static ips_scb_t * ips_getscb(ips_ha_t *);static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -