ips.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,776 行 · 第 1/5 页
C
1,776 行
/*****************************************************************************//* ips.c -- driver for the Adaptec / IBM ServeRAID controller *//* *//* Written By: Keith Mitchell, IBM Corporation *//* Jack Hammer, Adaptec, Inc. *//* David Jeffery, Adaptec, Inc. *//* *//* Copyright (C) 2000 IBM Corporation *//* Copyright (C) 2002,2003 Adaptec, Inc. *//* *//* 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@adaptec.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 firmware 3.60 *//* - Change version to 3.60 to coincide with 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 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 *//* 4.80.26 - Clean up potential code problems ( Arjan's recommendations ) *//* 4.90.01 - Version Matching for FirmWare, BIOS, and Driver *//* 4.90.05 - Use New PCI Architecture to facilitate Hot Plug Development *//* 4.90.08 - Increase Delays in Flashing ( Trombone Only - 4H ) *//* 4.90.08 - Data Corruption if First Scatter Gather Element is > 64K *//* 4.90.11 - Don't actually RESET unless it's physically required *//* - Remove unused compile options *//* 5.00.01 - Sarasota ( 5i ) adapters must always be scanned first *//* - Get rid on IOCTL_NEW_COMMAND code *//* - Add Extended DCDB Commands for Tape Support in 5I *//* 5.10.12 - use pci_dma interfaces, update for 2.5 kernel changes *//* 5.10.15 - remove unused code (sem, macros, etc.) *//* 5.30.00 - use __devexit_p() *//* 6.00.00 - Add 6x Adapters and Battery Flash *//* 6.10.00 - Remove 1G Addressing Limitations *//* 6.11.xx - Get VersionInfo buffer off the stack ! DDTS 60401 *//* 6.11.xx - Make Logical Drive Info structure safe for DMA DDTS 60639 *//*****************************************************************************//* * 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) * * 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/delay.h>#include <linux/pci.h>#include <linux/proc_fs.h>#include <linux/reboot.h>#include <linux/interrupt.h>#include <linux/blkdev.h>#include <linux/types.h>#include <scsi/sg.h>#include "scsi.h"#include <scsi/scsi_host.h>#include "ips.h"#include <linux/module.h>#include <linux/stat.h>#include <linux/config.h>#include <linux/spinlock.h>#include <linux/init.h>#include <linux/smp.h>#ifdef MODULEstatic char *ips = NULL;MODULE_PARM(ips, "s");#endif/* * DRIVER_VER */#define IPS_VERSION_HIGH "7.00"#define IPS_VERSION_LOW ".15 "#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"#endif#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)#include <linux/blk.h>#include "sd.h"#define IPS_SG_ADDRESS(sg) ((sg)->address)#define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)#define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags)#ifndef __devexit_p#define __devexit_p(x) x#endif#else#define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \ page_address((sg)->page)+(sg)->offset : NULL)#define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0)#define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0)#endif#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \ SCSI_DATA_NONE == scb->scsi_cmd->sc_data_direction) ? \ PCI_DMA_BIDIRECTIONAL : \ scsi_to_pci_dma_dir(scb->scsi_cmd->sc_data_direction))#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;static unsigned int ips_num_controllers;static unsigned int ips_released_controllers;static int ips_hotplug;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_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */static int ips_cd_boot; /* Booting from Manager CD */static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */static dma_addr_t ips_flashbusaddr;static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */static Scsi_Host_Template ips_driver_template = { .detect = ips_detect, .release = ips_release, .info = ips_info, .queuecommand = ips_queue, .eh_abort_handler = ips_eh_abort, .eh_host_reset_handler = ips_eh_reset, .proc_name = "ips",#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) .proc_info = ips_proc_info, .slave_configure = ips_slave_configure,#else .proc_info = ips_proc24_info, .select_queue_depths = ips_select_queue_depth,#endif .bios_param = ips_biosparam, .this_id = -1, .sg_tablesize = IPS_MAX_SG, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING,#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) .use_new_eh_code = 1,#endif};IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table *//* This table describes all ServeRAID Adapters */static struct pci_device_id ips_pci_table[] = { { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0, }};MODULE_DEVICE_TABLE( pci, ips_pci_table );static char ips_hot_plug_name[] = "ips"; static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);static void __devexit ips_remove_device(struct pci_dev *pci_dev); struct pci_driver ips_pci_driver = { .name = ips_hot_plug_name, .id_table = ips_pci_table, .probe = ips_insert_device, .remove = __devexit_p(ips_remove_device),}; /* * Necessary forward function protoypes */static int ips_halt(struct notifier_block *nb, ulong event, void *buf);#define MAX_ADAPTER_NAME 15static 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", "ServeRAID 5i", "ServeRAID 5i", "ServeRAID 6M", "ServeRAID 6i", "ServeRAID 7t", "ServeRAID 7k", "ServeRAID 7M"};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_NONE, 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,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?