📄 aha152x.c
字号:
/* aha152x.c -- Adaptec AHA-152x driver * Author: J黵gen E. Fischer, fischer@norbit.de * Copyright 1993-1999 J黵gen E. Fischer * * 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. * * * $Id: aha152x.c,v 2.3 2000/11/04 16:40:26 fischer Exp $ * * $Log: aha152x.c,v $ * Revision 2.3 2000/11/04 16:40:26 fischer * - handle data overruns * - extend timeout for data phases * * Revision 2.2 2000/08/08 19:54:53 fischer * - minor changes * * Revision 2.1 2000/05/17 16:23:17 fischer * - signature update * - fix for data out w/o scatter gather * * Revision 2.0 1999/12/25 15:07:32 fischer * - interrupt routine completly reworked * - basic support for new eh code * * Revision 1.21 1999/11/10 23:46:36 fischer * - default to synchronous operation * - synchronous negotiation fixed * - added timeout to loops * - debugging output can be controlled through procfs * * Revision 1.20 1999/11/07 18:37:31 fischer * - synchronous operation works * - resid support for sg driver * * Revision 1.19 1999/11/02 22:39:59 fischer * - moved leading comments to README.aha152x * - new additional module parameters * - updates for 2.3 * - support for the Tripace TC1550 controller * - interrupt handling changed * * Revision 1.18 1996/09/07 20:10:40 fischer * - fixed can_queue handling (multiple outstanding commands working again) * * Revision 1.17 1996/08/17 16:05:14 fischer * - biosparam improved * - interrupt verification * - updated documentation * - cleanups * * Revision 1.16 1996/06/09 00:04:56 root * - added configuration symbols for insmod (aha152x/aha152x1) * * Revision 1.15 1996/04/30 14:52:06 fischer * - proc info fixed * - support for extended translation for >1GB disks * * Revision 1.14 1996/01/17 15:11:20 fischer * - fixed lockup in MESSAGE IN phase after reconnection * * Revision 1.13 1996/01/09 02:15:53 fischer * - some cleanups * - moved request_irq behind controller initialization * (to avoid spurious interrupts) * * Revision 1.12 1995/12/16 12:26:07 fischer * - barrier()s added * - configurable RESET delay added * * Revision 1.11 1995/12/06 21:18:35 fischer * - some minor updates * * Revision 1.10 1995/07/22 19:18:45 fischer * - support for 2 controllers * - started synchronous data transfers (not working yet) * * Revision 1.9 1995/03/18 09:20:24 root * - patches for PCMCIA and modules * * Revision 1.8 1995/01/21 22:07:19 root * - snarf_region => request_region * - aha152x_intr interface change * * Revision 1.7 1995/01/02 23:19:36 root * - updated COMMAND_SIZE to cmd_len * - changed sti() to restore_flags() * - fixed some #ifdef which generated warnings * * Revision 1.6 1994/11/24 20:35:27 root * - problem with odd number of bytes in fifo fixed * * Revision 1.5 1994/10/30 14:39:56 root * - abort code fixed * - debugging improved * * Revision 1.4 1994/09/12 11:33:01 root * - irqaction to request_irq * - abortion updated * * Revision 1.3 1994/08/04 13:53:05 root * - updates for mid-level-driver changes * - accept unexpected BUSFREE phase as error condition * - parity check now configurable * * Revision 1.2 1994/07/03 12:56:36 root * - cleaned up debugging code * - more tweaking on reset delays * - updated abort/reset code (pretty untested...) * * Revision 1.1 1994/05/28 21:18:49 root * - update for mid-level interface change (abort-reset) * - delays after resets adjusted for some slow devices * * Revision 1.0 1994/03/25 12:52:00 root * - Fixed "more data than expected" problem * - added new BIOS signatures * * Revision 0.102 1994/01/31 20:44:12 root * - minor changes in insw/outsw handling * * Revision 0.101 1993/12/13 01:16:27 root * - fixed STATUS phase (non-GOOD stati were dropped sometimes; * fixes problems with CD-ROM sector size detection & media change) * * Revision 0.100 1993/12/10 16:58:47 root * - fix for unsuccessful selections in case of non-continuous id assignments * on the scsi bus. * * Revision 0.99 1993/10/24 16:19:59 root * - fixed DATA IN (rare read errors gone) * * Revision 0.98 1993/10/17 12:54:44 root * - fixed some recent fixes (shame on me) * - moved initialization of scratch area to aha152x_queue * * Revision 0.97 1993/10/09 18:53:53 root * - DATA IN fixed. Rarely left data in the fifo. * * Revision 0.96 1993/10/03 00:53:59 root * - minor changes on DATA IN * * Revision 0.95 1993/09/24 10:36:01 root * - change handling of MSGI after reselection * - fixed sti/cli * - minor changes * * Revision 0.94 1993/09/18 14:08:22 root * - fixed bug in multiple outstanding command code * - changed detection * - support for kernel command line configuration * - reset corrected * - changed message handling * * Revision 0.93 1993/09/15 20:41:19 root * - fixed bugs with multiple outstanding commands * * Revision 0.92 1993/09/13 02:46:33 root * - multiple outstanding commands work (no problems with IBM drive) * * Revision 0.91 1993/09/12 20:51:46 root * added multiple outstanding commands * (some problem with this $%&? IBM device remain) * * Revision 0.9 1993/09/12 11:11:22 root * - corrected auto-configuration * - changed the auto-configuration (added some '#define's) * - added support for dis-/reconnection * * Revision 0.8 1993/09/06 23:09:39 root * - added support for the drive activity light * - minor changes * * Revision 0.7 1993/09/05 14:30:15 root * - improved phase detection * - now using the new snarf_region code of 0.99pl13 * * Revision 0.6 1993/09/02 11:01:38 root * first public release; added some signatures and biosparam() * * Revision 0.5 1993/08/30 10:23:30 root * fixed timing problems with my IBM drive * * Revision 0.4 1993/08/29 14:06:52 root * fixed some problems with timeouts due incomplete commands * * Revision 0.3 1993/08/28 15:55:03 root * writing data works too. mounted and worked on a dos partition * * Revision 0.2 1993/08/27 22:42:07 root * reading data works. Mounted a msdos partition. * * Revision 0.1 1993/08/25 13:38:30 root * first "damn thing doesn't work" version * * Revision 0.0 1993/08/14 19:54:25 root * empty function bodies; detect() works. * * ************************************************************************** see README.aha152x for configuration details **************************************************************************/#include <linux/module.h>#if defined(PCMCIA)#undef MODULE#endif#include <linux/sched.h>#include <asm/io.h>#include <linux/blk.h>#include "scsi.h"#include "sd.h"#include "hosts.h"#include "constants.h"#include <asm/system.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/wait.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/proc_fs.h>#include <linux/interrupt.h>#include <linux/init.h>#include <linux/kernel.h>#include <asm/semaphore.h>#include <linux/spinlock.h>#include "aha152x.h"#include <linux/stat.h>#include <scsi/scsicam.h>/* DEFINES *//* For PCMCIA cards, always use AUTOCONF */#if defined(PCMCIA) || defined(MODULE)#if !defined(AUTOCONF)#define AUTOCONF#endif#endif#if !defined(AUTOCONF) && !defined(SETUP0)#error define AUTOCONF or SETUP0#endif#if defined(AHA152X_DEBUG)#define DEBUG_DEFAULT debug_eh#define DPRINTK(when,msgs...) \ do { if(HOSTDATA(shpnt)->debug & (when)) printk(msgs); } while(0)#define DO_LOCK(flags) \ do { \ if(spin_is_locked(&QLOCK)) { \ DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \ } \ DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ spin_lock_irqsave(&QLOCK,flags); \ DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ QLOCKER=__FUNCTION__; \ QLOCKERL=__LINE__; \ } while(0)#define DO_UNLOCK(flags) \ do { \ DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \ spin_unlock_irqrestore(&QLOCK,flags); \ DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \ QLOCKER="(not locked)"; \ QLOCKERL=0; \ } while(0)#else#define DPRINTK(when,msgs...)#define DO_LOCK(flags) spin_lock_irqsave(&QLOCK,flags)#define DO_UNLOCK(flags) spin_unlock_irqrestore(&QLOCK,flags)#endif#define LEAD "(scsi%d:%d:%d) "#define WARN_LEAD KERN_WARNING LEAD#define INFO_LEAD KERN_INFO LEAD#define NOTE_LEAD KERN_NOTICE LEAD#define ERR_LEAD KERN_ERR LEAD#define DEBUG_LEAD KERN_DEBUG LEAD#define CMDINFO(cmd) \ (cmd) ? ((cmd)->host->host_no) : -1, \ (cmd) ? ((cmd)->target & 0x0f) : -1, \ (cmd) ? ((cmd)->lun & 0x07) : -1#define DELAY_DEFAULT 100/* possible irq range */#if defined(PCMCIA)#define IRQ_MIN 0#define IRQ_MAX 16#else#define IRQ_MIN 9#define IRQ_MAX 12#endif#define IRQS IRQ_MAX-IRQ_MIN+1enum { not_issued = 0x0001, /* command not yet issued */ selecting = 0x0002, /* target is beeing selected */ identified = 0x0004, /* IDENTIFY was sent */ disconnected = 0x0008, /* target disconnected */ completed = 0x0010, /* target sent COMMAND COMPLETE */ aborted = 0x0020, /* ABORT was sent */ resetted = 0x0040, /* BUS DEVICE RESET was sent */ spiordy = 0x0080, /* waiting for SPIORDY to raise */ syncneg = 0x0100, /* synchronous negotiation in progress */ aborting = 0x0200, /* ABORT is pending */ resetting = 0x0400, /* BUS DEVICE RESET is pending */};#if defined(MODULE)MODULE_AUTHOR("J黵gen Fischer");MODULE_DESCRIPTION(AHA152X_REVID);MODULE_PARM(io, "1-2i");MODULE_PARM_DESC(io,"base io address of controller");static int io[] = {0, 0};MODULE_PARM(irq, "1-2i");MODULE_PARM_DESC(irq,"interrupt for controller");static int irq[] = {0, 0};MODULE_PARM(scsiid, "1-2i");MODULE_PARM_DESC(scsiid,"scsi id of controller");static int scsiid[] = {7, 7};MODULE_PARM(reconnect, "1-2i");MODULE_PARM_DESC(reconnect,"allow targets to disconnect");static int reconnect[] = {1, 1};MODULE_PARM(parity, "1-2i");MODULE_PARM_DESC(parity,"use scsi parity");static int parity[] = {1, 1};MODULE_PARM(sync, "1-2i");MODULE_PARM_DESC(sync,"use synchronous transfers");static int sync[] = {1, 1};MODULE_PARM(delay, "1-2i");MODULE_PARM_DESC(delay,"scsi reset delay");static int delay[] = {DELAY_DEFAULT, DELAY_DEFAULT};MODULE_PARM(exttrans, "1-2i");MODULE_PARM_DESC(exttrans,"use extended translation");static int exttrans[] = {0, 0};#if !defined(AHA152X_DEBUG)MODULE_PARM(aha152x, "1-8i");MODULE_PARM_DESC(aha152x, "parameters for first controller");static int aha152x[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};MODULE_PARM(aha152x1, "1-8i");MODULE_PARM_DESC(aha152x1, "parameters for second controller");static int aha152x1[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};#elseMODULE_PARM(debug, "1-2i");MODULE_PARM_DESC(debug, "flags for driver debugging");static int debug[] = {DEBUG_DEFAULT, DEBUG_DEFAULT};MODULE_PARM(aha152x, "1-9i");MODULE_PARM_DESC(aha152x, "parameters for first controller");static int aha152x[] = {0, 11, 7, 1, 1, 1, DELAY_DEFAULT, 0, DEBUG_DEFAULT};MODULE_PARM(aha152x1, "1-9i");MODULE_PARM_DESC(aha152x1, "parameters for second controller");static int aha152x1[] = {0, 11, 7, 1, 1, 1, DELAY_DEFAULT, 0, DEBUG_DEFAULT};#endif /* !defined(AHA152X_DEBUG) */#endif /* MODULE *//* set by aha152x_setup according to the command line */static int setup_count = 0;static int registered_count = 0;static struct aha152x_setup { int io_port; int irq; int scsiid; int reconnect; int parity; int synchronous; int delay; int ext_trans; int tc1550;#if defined(AHA152X_DEBUG) int debug;#endif char *conf;} setup[2];static struct Scsi_Host *aha152x_host[IRQS];/* * internal states of the host * */ enum aha152x_state { idle=0, unknown, seldo, seldi, selto, busfree, msgo, cmd, msgi, status, datai, datao, parerr, rsti, maxstate};/* * current state information of the host * */struct aha152x_hostdata { Scsi_Cmnd *issue_SC; /* pending commands to issue */ Scsi_Cmnd *current_SC; /* current command on the bus */ Scsi_Cmnd *disconnected_SC; /* commands that disconnected */ Scsi_Cmnd *done_SC; /* command that was completed */ spinlock_t lock; /* host lock */#if defined(AHA152X_DEBUG) char *locker; /* which function has the lock */ int lockerl; /* where did it get it */ int debug; /* current debugging setting */#endif#if defined(AHA152X_STAT) int total_commands; int disconnections; int busfree_without_any_action; int busfree_without_old_command; int busfree_without_new_command; int busfree_without_done_command; int busfree_with_check_condition; int count[maxstate]; int count_trans[maxstate]; unsigned long time[maxstate];#endif int commands; /* current number of commands */ int reconnect; /* disconnection allowed */ int parity; /* parity checking enabled */ int synchronous; /* synchronous transferes enabled */ int delay; /* reset out delay */ int ext_trans; /* extended translation enabled */ int swint; /* software-interrupt was fired during detect() */ int service; /* bh needs to be run */ int in_intr; /* bh is running */ /* current state, previous state, last state different from current state */ enum aha152x_state state, prevstate, laststate; int target; /* reconnecting target */ unsigned char syncrate[8]; /* current synchronous transfer agreements */ unsigned char syncneg[8]; /* 0: no negotiation; * 1: negotiation in progress; * 2: negotiation completed */ int cmd_i; /* number of sent bytes of current command */ int msgi_len; /* number of received message bytes */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -