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

📄 aic7xxx.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
/*+M************************************************************************* * Adaptec AIC7xxx device driver for Linux. * * Copyright (c) 1994 John Aycock *   The University of Calgary Department of Computer Science. * * 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, 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. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING.  If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F * driver (ultrastor.c), various Linux kernel source, the Adaptec EISA * config file (!adp7771.cfg), the Adaptec AHA-2740A Series User's Guide, * the Linux Kernel Hacker's Guide, Writing a SCSI Device Driver for Linux, * the Adaptec 1542 driver (aha1542.c), the Adaptec EISA overlay file * (adp7770.ovl), the Adaptec AHA-2740 Series Technical Reference Manual, * the Adaptec AIC-7770 Data Book, the ANSI SCSI specification, the * ANSI SCSI-2 specification (draft 10c), ... * * -------------------------------------------------------------------------- * *  Modifications by Daniel M. Eischen (deischen@iworks.InterWorks.org): * *  Substantially modified to include support for wide and twin bus *  adapters, DMAing of SCBs, tagged queueing, IRQ sharing, bug fixes, *  SCB paging, and other rework of the code. * *  Parts of this driver were also based on the FreeBSD driver by *  Justin T. Gibbs.  His copyright follows: * * -------------------------------------------------------------------------- * Copyright (c) 1994-1997 Justin Gibbs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions, and the following disclaimer, *    without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * Where this Software is combined with software released under the terms of * the GNU Public License ("GPL") and the terms of the GPL would require the * combined work to also be released under the terms of the GPL, the terms * and conditions of this License will apply in addition to those of the * GPL with the exception of any terms or conditions of this License that * conflict with, or are expressly prohibited by, the GPL. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *      $Id: aic7xxx.c,v 1.1.4.1 2004/01/16 22:41:26 roland Exp $ *--------------------------------------------------------------------------- * *  Thanks also go to (in alphabetical order) the following: * *    Rory Bolt     - Sequencer bug fixes *    Jay Estabrook - Initial DEC Alpha support *    Doug Ledford  - Much needed abort/reset bug fixes *    Kai Makisara  - DMAing of SCBs * *  A Boot time option was also added for not resetting the scsi bus. * *    Form:  aic7xxx=extended *           aic7xxx=no_reset *           aic7xxx=ultra *           aic7xxx=irq_trigger:[0,1]  # 0 edge, 1 level *           aic7xxx=verbose * *  Daniel M. Eischen, deischen@iworks.InterWorks.org, 1/23/97 * *-M*************************************************************************//*+M************************************************************************** * * Further driver modifications made by Doug Ledford <dledford@redhat.com> * * Copyright (c) 1997-1998 Doug Ledford * * These changes are released under the same licensing terms as the FreeBSD * driver written by Justin Gibbs.  Please see his Copyright notice above * for the exact terms and conditions covering my changes as well as the * warranty statement. * * Modifications made to the aic7xxx.c,v 4.1 driver from Dan Eischen include * but are not limited to: * *  1: Import of the latest FreeBSD sequencer code for this driver *  2: Modification of kernel code to accomodate different sequencer semantics *  3: Extensive changes throughout kernel portion of driver to improve *     abort/reset processing and error hanndling *  4: Other work contributed by various people on the Internet *  5: Changes to printk information and verbosity selection code *  6: General reliability related changes, especially in IRQ management *  7: Modifications to the default probe/attach order for supported cards *  8: SMP friendliness has been improved * * Overall, this driver represents a significant departure from the official * aic7xxx driver released by Dan Eischen in two ways.  First, in the code * itself.  A diff between the two version of the driver is now a several * thousand line diff.  Second, in approach to solving the same problem.  The * problem is importing the FreeBSD aic7xxx driver code to linux can be a * difficult and time consuming process, that also can be error prone.  Dan * Eischen's official driver uses the approach that the linux and FreeBSD * drivers should be as identical as possible.  To that end, his next version * of this driver will be using a mid-layer code library that he is developing * to moderate communications between the linux mid-level SCSI code and the * low level FreeBSD driver.  He intends to be able to essentially drop the * FreeBSD driver into the linux kernel with only a few minor tweaks to some * include files and the like and get things working, making for fast easy * imports of the FreeBSD code into linux. * * I disagree with Dan's approach.  Not that I don't think his way of doing * things would be nice, easy to maintain, and create a more uniform driver * between FreeBSD and Linux.  I have no objection to those issues.  My * disagreement is on the needed functionality.  There simply are certain * things that are done differently in FreeBSD than linux that will cause * problems for this driver regardless of any middle ware Dan implements. * The biggest example of this at the moment is interrupt semantics.  Linux * doesn't provide the same protection techniques as FreeBSD does, nor can * they be easily implemented in any middle ware code since they would truly * belong in the kernel proper and would effect all drivers.  For the time * being, I see issues such as these as major stumbling blocks to the * reliability of code based upon such middle ware.  Therefore, I choose to * use a different approach to importing the FreeBSD code that doesn't * involve any middle ware type code.  My approach is to import the sequencer * code from FreeBSD wholesale.  Then, to only make changes in the kernel * portion of the driver as they are needed for the new sequencer semantics. * In this way, the portion of the driver that speaks to the rest of the * linux kernel is fairly static and can be changed/modified to solve * any problems one might encounter without concern for the FreeBSD driver. * * Note: If time and experience should prove me wrong that the middle ware * code Dan writes is reliable in its operation, then I'll retract my above * statements.  But, for those that don't know, I'm from Missouri (in the US) * and our state motto is "The Show-Me State".  Well, before I will put * faith into it, you'll have to show me that it works :) * *_M*************************************************************************//* * The next three defines are user configurable.  These should be the only * defines a user might need to get in here and change.  There are other * defines buried deeper in the code, but those really shouldn't need touched * under normal conditions. *//* * AIC7XXX_FAKE_NEGOTIATION_CMDS *   We now have two distinctly different methods of device negotiation *   in this code.  The two methods are selected by either defining or not *   defining this option.  The difference is as follows: * *   With AIC7XXX_FAKE_NEGOTIATION_CMDS not set (commented out) *     When the driver is in need of issuing a negotiation command for any *     given device, it will add the negotiation message on to part of a *     regular SCSI command for the device.  In the process, if the device *     is configured for and using tagged queueing, then the code will *     also issue that single command as a non-tagged command, attach the *     negotiation message to that one command, and use a temporary *     queue depth of one to keep the untagged and tagged commands from *     overlapping. *       Pros: This doesn't use any extra SCB structures, it's simple, it *         works most of the time (if not all of the time now), and *         since we get the device capability info frmo the INQUIRY data *         now, shouldn't cause any problems. *       Cons: When we need to send a negotiation command to a device, we *         must use a command that is being sent to LUN 0 of the device. *         If we try sending one to high LUN numbers, then some devices *         get noticeably upset.  Since we have to wait for a command with *         LUN == 0 to come along, we may not be able to renegotiate when *         we want if the user is actually using say LUN 1 of a CD Changer *         instead of using LUN 0 for an extended period of time. * *   With AIC7XXX_FAKE_NEGOTIATION_CMDS defined *     When we need to negotiate with a device, instead of attaching our *     negotiation message to an existing command, we insert our own *     fictional Scsi_Cmnd into the chain that has the negotiation message *     attached to it.  We send this one command as untagged regardless *     of the device type, and we fiddle with the queue depth the same as *     we would with the option unset to avoid overlapping commands.  The *     primary difference between this and the unset option is that the *     negotiation message is no longer attached to a specific command, *     instead it is its own command and is merely triggered by a *     combination of both A) We need to negotiate and B) The mid level *     SCSI code has sent us a command.  We still don't do any negotiation *     unless there is a valid SCSI command to be processed. *       Pros: This fixes the problem above in the Cons section.  Since we *         issue our own fake command, we can set the LUN to 0 regardless *         of what the LUN is in the real command.  It also means that if *         the device get's nasty over negotiation issues, it won't be *         showing up on a regular command, so we won't get any SENSE buffer *         data or STATUS_BYTE returns to the mid level code that are caused *         by snits in the negotiation code. *       Cons: We add more code, and more complexity.  This means more ways *         in which things could break.  It means a larger driver.  It means *         more resource consumption for the fake commands.  However, the *         biggest problem is this.  Take a system where there is a CD-ROM *         on the SCSI bus.  Someone has a CD in the CD-ROM and is using it. *         For some reason the SCSI bus gets reset.  We don't touch the *         CD-ROM again for quite a period of time (so we don't renegotiate *         after the reset until we do touch the CD-ROM again).  In the *         time while we aren't using the CD-ROM, the current disc is *         removed and a new one put in.  When we go to check that disc, we *         will first have to renegotiate.  In so doing, we issue our fake *         SCSI command, which happens to be TEST_UNIT_READY.  The CD-ROM *         negotiates with us, then responds to our fake command with a *         CHECK_CONDITION status.  We REQUEST_SENSE from the CD-ROM, it *         then sends the SENSE data to our fake command to tell it that *         it has been through a disc change.  There, now we've cleared out *         the SENSE data along with our negotiation command, and when the *         real command executes, it won't pick up that the CD was changed. *         That's the biggest Con to this approach.  In the future, I could *         probably code around this problem though, so this option is still *         viable. * *  So, which command style should you use?  I would appreciate it if people *  could try out both types.  I want to know about any cases where one *  method works and the other doesn't.  If one method works on significantly *  more systems than another, then it will become the default.  If the second *  option turns out to work best, then I'll find a way to work around that *  big con I listed. * *  -- July 7, 02:33 *    OK...I just added some code that should make the Con listed for the *    fake commands a non issue now.  However, it needs testing.  For now, *    I'm going to make the default to use the fake commands, we'll see how *    it goes. */#define AIC7XXX_FAKE_NEGOTIATION_CMDS/* * AIC7XXX_STRICT_PCI_SETUP *   Should we assume the PCI config options on our controllers are set with *   sane and proper values, or should we be anal about our PCI config *   registers and force them to what we want?  The main advantage to *   defining this option is on non-Intel hardware where the BIOS may not *   have been run to set things up, or if you have one of the BIOSless *   Adaptec controllers, such as a 2910, that don't get set up by the *   BIOS.  However, keep in mind that we really do set the most important *   items in the driver regardless of this setting, this only controls some *   of the more esoteric PCI options on these cards.  In that sense, I *   would default to leaving this off.  However, if people wish to try *   things both ways, that would also help me to know if there are some *   machines where it works one way but not another. * *   -- July 7, 17:09 *     OK...I need this on my machine for testing, so the default is to *     leave it defined. * *   -- July 7, 18:49 *     I needed it for testing, but it didn't make any difference, so back *     off she goes. * *   -- July 16, 23:04 *     I turned it back on to try and compensate for the 2.1.x PCI code *     which no longer relies solely on the BIOS and now tries to set *     things itself. */#define AIC7XXX_STRICT_PCI_SETUP/* * AIC7XXX_VERBOSE_DEBUGGING *   This option enables a lot of extra printk();s in the code, surrounded *   by if (aic7xxx_verbose ...) statements.  Executing all of those if *   statements and the extra checks can get to where it actually does have *   an impact on CPU usage and such, as well as code size.  Disabling this *   define will keep some of those from becoming part of the code. * *   NOTE:  Currently, this option has no real effect, I will be adding the *   various #ifdef's in the code later when I've decided a section is *   complete and no longer needs debugging.  OK...a lot of things are now *   surrounded by this define, so turning this off does have an impact. *//* * #define AIC7XXX_VERBOSE_DEBUGGING */#if defined(MODULE) || defined(PCMCIA)#include <linux/module.h>#endif#if defined(PCMCIA)#  undef MODULE#endif#include <stdarg.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/byteorder.h>#include <linux/version.h>#include <linux/string.h>#include <linux/errno.h>#include <linux/kernel.h>

⌨️ 快捷键说明

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