?? ips.c
字號:
/*****************************************************************************//* ips.c -- driver for the IBM ServeRAID controller *//* *//* Written By: Keith Mitchell, IBM Corporation *//* *//* Copyright (C) 2000 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 about this driver should be mailed to: *//* ipslinux@us.ibm.com *//* *//* For system support issues, contact your local IBM Customer support. *//* Directions to find IBM Customer Support for each country can be found at: *//* http://www.ibm.com/planetwide/ *//* *//*****************************************************************************//*****************************************************************************//* 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@infradead.org> *//* 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 *//* 4.50.01 - Fix problem when there is a hole in logical drive numbering *//* 4.70.09 - Use a Common ( Large Buffer ) for Flashing from the JCRM CD *//* - Add IPSSEND Flash Support *//* - Set Sense Data for Unknown SCSI Command *//* - Use Slot Number from NVRAM Page 5 *//* - Restore caller's DCDB Structure *//* 4.70.12 - Corrective actions for bad controller ( during initialization )*//* 4.70.13 - Don't Send CDB's if we already know the device is not present *//* - Don't release HA Lock in ips_next() until SC taken off queue *//* - Unregister SCSI device in ips_release() *//* 4.70.15 - Fix Breakup for very large ( non-SG ) requests in ips_done() *//* 4.71.00 - Change all memory allocations to not use GFP_DMA flag *//* Code Clean-Up for 2.4.x kernel *//* 4.72.00 - Allow for a Scatter-Gather Element to exceed MAX_XFER Size *//* 4.72.01 - I/O Mapped Memory release ( so "insmod ips" does not Fail ) *//* Don't Issue Internal FFDC Command if there are Active Commands *//* Close Window for getting too many IOCTL's active *//* 4.80.00 Make ia64 Safe *//* 4.80.04 Eliminate calls to strtok() if 2.4.x or greater *//* Adjustments to Device Queue Depth *//* 4.80.14 Take all semaphores off stack *//* Clean Up New_IOCTL path *//* 4.80.20 Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel ) *//* 5 second delay needed after resetting an i960 adapter *//*****************************************************************************//* * 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 * ioctlsize - Initial size of the IOCTL buffer */ #include <asm/io.h>#include <asm/byteorder.h>#include <asm/page.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/slab.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/tqueue.h>#include <linux/interrupt.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/module.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.80"#define IPS_VERSION_LOW ".26 "#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__) && !defined(__ia64__) #error "This driver has only been tested on the x86/ia64 platforms"#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 */static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */static int ips_cd_boot = 0; /* Booting from ServeRAID Manager CD */static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */static int ips_FlashDataInUse = 0; /* CD Boot - Flash Data In Use Flag */#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 11static char ips_adapter_name[][30] = { "ServeRAID", "ServeRAID II", "ServeRAID on motherboard", "ServeRAID on motherboard", "ServeRAID 3H", "ServeRAID 3L", "ServeRAID 4H", "ServeRAID 4M", "ServeRAID 4L", "ServeRAID 4Mx", "ServeRAID 4Lx"};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 *);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -