Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /* aha152x.c -- Adaptec AHA-152x driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Author: Jürgen E. Fischer, fischer@norbit.de
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright 1993-2004 Jürgen E. Fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * $Id: aha152x.c,v 2.7 2004/01/24 11:42:59 fischer Exp $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * $Log: aha152x.c,v $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * Revision 2.7  2004/01/24 11:42:59  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * - gather code that is not used by PCMCIA at the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * - move request_region for !PCMCIA case to detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * - migration to new scsi host api (remove legacy code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * - free host scribble before scsi_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * - fix error handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * - one isapnp device added to id_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * Revision 2.6  2003/10/30 20:52:47  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  * - interfaces changes for kernel 2.6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * - aha152x_probe_one introduced for pcmcia stub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  * - fixed pnpdev handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  * - instead of allocation a new one, reuse command for request sense after check condition and reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  * - fixes race in is_complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * Revision 2.5  2002/04/14 11:24:53  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  * - isapnp support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  * - abort fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  * - 2.5 support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  * Revision 2.4  2000/12/16 12:53:56  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  * - allow REQUEST SENSE to be queued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  * - handle shared PCI interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  * Revision 2.3  2000/11/04 16:40:26  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  * - handle data overruns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  * - extend timeout for data phases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  * Revision 2.2  2000/08/08 19:54:53  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  * - minor changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  * Revision 2.1  2000/05/17 16:23:17  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  * - signature update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  * - fix for data out w/o scatter gather
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44)  * Revision 2.0  1999/12/25 15:07:32  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  * - interrupt routine completly reworked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  * - basic support for new eh code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  * Revision 1.21  1999/11/10 23:46:36  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  * - default to synchronous operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50)  * - synchronous negotiation fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51)  * - added timeout to loops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52)  * - debugging output can be controlled through procfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54)  * Revision 1.20  1999/11/07 18:37:31  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  * - synchronous operation works
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)  * - resid support for sg driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58)  * Revision 1.19  1999/11/02 22:39:59  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59)  * - moved leading comments to README.aha152x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60)  * - new additional module parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61)  * - updates for 2.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62)  * - support for the Tripace TC1550 controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63)  * - interrupt handling changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65)  * Revision 1.18  1996/09/07 20:10:40  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66)  * - fixed can_queue handling (multiple outstanding commands working again)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68)  * Revision 1.17  1996/08/17 16:05:14  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69)  * - biosparam improved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)  * - interrupt verification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71)  * - updated documentation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72)  * - cleanups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)  * Revision 1.16  1996/06/09 00:04:56  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  * - added configuration symbols for insmod (aha152x/aha152x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  * Revision 1.15  1996/04/30 14:52:06  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  * - proc info fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  * - support for extended translation for >1GB disks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  * Revision 1.14  1996/01/17  15:11:20  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  * - fixed lockup in MESSAGE IN phase after reconnection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * Revision 1.13  1996/01/09  02:15:53  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  * - some cleanups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  * - moved request_irq behind controller initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87)  *   (to avoid spurious interrupts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89)  * Revision 1.12  1995/12/16  12:26:07  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90)  * - barrier()s added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91)  * - configurable RESET delay added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93)  * Revision 1.11  1995/12/06  21:18:35  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94)  * - some minor updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96)  * Revision 1.10  1995/07/22  19:18:45  fischer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97)  * - support for 2 controllers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)  * - started synchronous data transfers (not working yet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  * Revision 1.9  1995/03/18  09:20:24  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  * - patches for PCMCIA and modules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)  * Revision 1.8  1995/01/21  22:07:19  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  * - snarf_region => request_region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  * - aha152x_intr interface change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  * Revision 1.7  1995/01/02  23:19:36  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  * - updated COMMAND_SIZE to cmd_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)  * - changed sti() to restore_flags()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110)  * - fixed some #ifdef which generated warnings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)  * Revision 1.6  1994/11/24  20:35:27  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113)  * - problem with odd number of bytes in fifo fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115)  * Revision 1.5  1994/10/30  14:39:56  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116)  * - abort code fixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117)  * - debugging improved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119)  * Revision 1.4  1994/09/12  11:33:01  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120)  * - irqaction to request_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  * - abortion updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123)  * Revision 1.3  1994/08/04  13:53:05  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)  * - updates for mid-level-driver changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  * - accept unexpected BUSFREE phase as error condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  * - parity check now configurable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  * Revision 1.2  1994/07/03  12:56:36  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  * - cleaned up debugging code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  * - more tweaking on reset delays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131)  * - updated abort/reset code (pretty untested...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133)  * Revision 1.1  1994/05/28  21:18:49  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134)  * - update for mid-level interface change (abort-reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135)  * - delays after resets adjusted for some slow devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137)  * Revision 1.0  1994/03/25  12:52:00  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138)  * - Fixed "more data than expected" problem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139)  * - added new BIOS signatures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141)  * Revision 0.102  1994/01/31  20:44:12  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142)  * - minor changes in insw/outsw handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144)  * Revision 0.101  1993/12/13  01:16:27  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145)  * - fixed STATUS phase (non-GOOD stati were dropped sometimes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146)  *   fixes problems with CD-ROM sector size detection & media change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)  * Revision 0.100  1993/12/10  16:58:47  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  * - fix for unsuccessful selections in case of non-continuous id assignments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150)  *   on the scsi bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152)  * Revision 0.99  1993/10/24  16:19:59  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153)  * - fixed DATA IN (rare read errors gone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155)  * Revision 0.98  1993/10/17  12:54:44  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  * - fixed some recent fixes (shame on me)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  * - moved initialization of scratch area to aha152x_queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)  * Revision 0.97  1993/10/09  18:53:53  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)  * - DATA IN fixed. Rarely left data in the fifo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162)  * Revision 0.96  1993/10/03  00:53:59  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163)  * - minor changes on DATA IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165)  * Revision 0.95  1993/09/24  10:36:01  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  * - change handling of MSGI after reselection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  * - fixed sti/cli
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * - minor changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  * Revision 0.94  1993/09/18  14:08:22  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  * - fixed bug in multiple outstanding command code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)  * - changed detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173)  * - support for kernel command line configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174)  * - reset corrected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  * - changed message handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177)  * Revision 0.93  1993/09/15  20:41:19  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178)  * - fixed bugs with multiple outstanding commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)  * Revision 0.92  1993/09/13  02:46:33  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181)  * - multiple outstanding commands work (no problems with IBM drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183)  * Revision 0.91  1993/09/12  20:51:46  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184)  * added multiple outstanding commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185)  * (some problem with this $%&? IBM device remain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187)  * Revision 0.9  1993/09/12  11:11:22  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)  * - corrected auto-configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  * - changed the auto-configuration (added some '#define's)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  * - added support for dis-/reconnection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)  * Revision 0.8  1993/09/06  23:09:39  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  * - added support for the drive activity light
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  * - minor changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196)  * Revision 0.7  1993/09/05  14:30:15  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197)  * - improved phase detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198)  * - now using the new snarf_region code of 0.99pl13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200)  * Revision 0.6  1993/09/02  11:01:38  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201)  * first public release; added some signatures and biosparam()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203)  * Revision 0.5  1993/08/30  10:23:30  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204)  * fixed timing problems with my IBM drive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206)  * Revision 0.4  1993/08/29  14:06:52  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207)  * fixed some problems with timeouts due incomplete commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209)  * Revision 0.3  1993/08/28  15:55:03  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210)  * writing data works too.  mounted and worked on a dos partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212)  * Revision 0.2  1993/08/27  22:42:07  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213)  * reading data works.  Mounted a msdos partition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215)  * Revision 0.1  1993/08/25  13:38:30  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216)  * first "damn thing doesn't work" version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218)  * Revision 0.0  1993/08/14  19:54:25  root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219)  * empty function bodies; detect() works.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221)  **************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223)  see Documentation/scsi/aha152x.rst for configuration details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) #include <linux/isapnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) #include <scsi/scsicam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) #include "scsi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) #include <scsi/scsi_dbg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) #include <scsi/scsi_transport_spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) #include <scsi/scsi_eh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) #include "aha152x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) static LIST_HEAD(aha152x_host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) /* DEFINES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) /* For PCMCIA cards, always use AUTOCONF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) #if defined(AHA152X_PCMCIA) || defined(MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) #if !defined(AUTOCONF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) #define AUTOCONF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) #if !defined(AUTOCONF) && !defined(SETUP0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) #error define AUTOCONF or SETUP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) #define	DO_LOCK(flags)		spin_lock_irqsave(&QLOCK,flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) #define	DO_UNLOCK(flags)	spin_unlock_irqrestore(&QLOCK,flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) #define LEAD		"(scsi%d:%d:%d) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) #define INFO_LEAD	KERN_INFO	LEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) #define CMDINFO(cmd) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			(cmd) ? ((cmd)->device->host->host_no) : -1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278)                         (cmd) ? ((cmd)->device->id & 0x0f) : -1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 			(cmd) ? ((u8)(cmd)->device->lun & 0x07) : -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) CMD_INC_RESID(struct scsi_cmnd *cmd, int inc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	scsi_set_resid(cmd, scsi_get_resid(cmd) + inc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) #define DELAY_DEFAULT 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) #if defined(AHA152X_PCMCIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) #define IRQ_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) #define IRQ_MAX 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) #define IRQ_MIN 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) #if defined(__PPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) #define IRQ_MAX (nr_irqs-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) #define IRQ_MAX 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	not_issued	= 0x0001,	/* command not yet issued */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	selecting	= 0x0002,	/* target is being selected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	identified	= 0x0004,	/* IDENTIFY was sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	disconnected	= 0x0008,	/* target disconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	completed	= 0x0010,	/* target sent COMMAND COMPLETE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	aborted		= 0x0020,	/* ABORT was sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	resetted	= 0x0040,	/* BUS DEVICE RESET was sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	spiordy		= 0x0080,	/* waiting for SPIORDY to raise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	syncneg		= 0x0100,	/* synchronous negotiation in progress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	aborting	= 0x0200,	/* ABORT is pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	resetting	= 0x0400,	/* BUS DEVICE RESET is pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	check_condition = 0x0800,	/* requesting sense after CHECK CONDITION */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) MODULE_AUTHOR("Jürgen Fischer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) MODULE_DESCRIPTION(AHA152X_REVID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) #if !defined(AHA152X_PCMCIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) #if defined(MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) static int io[] = {0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) module_param_hw_array(io, int, ioport, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) MODULE_PARM_DESC(io,"base io address of controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) static int irq[] = {0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) module_param_hw_array(irq, int, irq, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) MODULE_PARM_DESC(irq,"interrupt for controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) static int scsiid[] = {7, 7};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) module_param_array(scsiid, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) MODULE_PARM_DESC(scsiid,"scsi id of controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) static int reconnect[] = {1, 1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) module_param_array(reconnect, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) MODULE_PARM_DESC(reconnect,"allow targets to disconnect");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) static int parity[] = {1, 1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) module_param_array(parity, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) MODULE_PARM_DESC(parity,"use scsi parity");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) static int sync[] = {1, 1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) module_param_array(sync, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) MODULE_PARM_DESC(sync,"use synchronous transfers");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) static int delay[] = {DELAY_DEFAULT, DELAY_DEFAULT};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) module_param_array(delay, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) MODULE_PARM_DESC(delay,"scsi reset delay");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) static int exttrans[] = {0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) module_param_array(exttrans, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) MODULE_PARM_DESC(exttrans,"use extended translation");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) static int aha152x[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) module_param_array(aha152x, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) MODULE_PARM_DESC(aha152x, "parameters for first controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) static int aha152x1[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) module_param_array(aha152x1, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) MODULE_PARM_DESC(aha152x1, "parameters for second controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) #endif /* MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) #ifdef __ISAPNP__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) static struct isapnp_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1502), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1505), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1510), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1515), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1520), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x2015), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1522), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x2215), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1530), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x3015), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1532), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x3215), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x6360), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	{ ISAPNP_DEVICE_SINGLE_END, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) MODULE_DEVICE_TABLE(isapnp, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) #endif /* ISAPNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) #endif /* !AHA152X_PCMCIA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) static struct scsi_host_template aha152x_driver_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388)  * internal states of the host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) enum aha152x_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	idle=0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	unknown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	seldo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	seldi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	selto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	busfree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	msgo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	msgi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	datai,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	datao,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	parerr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	rsti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	maxstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410)  * current state information of the host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) struct aha152x_hostdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	struct scsi_cmnd *issue_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		/* pending commands to issue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	struct scsi_cmnd *current_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		/* current command on the bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	struct scsi_cmnd *disconnected_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		/* commands that disconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	struct scsi_cmnd *done_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		/* command that was completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		/* host lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	int	      total_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	int	      disconnections;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	int	      busfree_without_any_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	int	      busfree_without_old_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	int	      busfree_without_new_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	int	      busfree_without_done_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	int	      busfree_with_check_condition;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	int	      count[maxstate];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	int	      count_trans[maxstate];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	unsigned long time[maxstate];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	int commands;		/* current number of commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	int reconnect;		/* disconnection allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	int parity;		/* parity checking enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	int synchronous;	/* synchronous transferes enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	int delay;		/* reset out delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	int ext_trans;		/* extended translation enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	int swint;		/* software-interrupt was fired during detect() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	int service;		/* bh needs to be run */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	int in_intr;		/* bh is running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	/* current state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	   previous state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	   last state different from current state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	enum aha152x_state state, prevstate, laststate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	int target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		/* reconnecting target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	unsigned char syncrate[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		/* current synchronous transfer agreements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	unsigned char syncneg[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		/* 0: no negotiation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		 * 1: negotiation in progress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		 * 2: negotiation completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	int cmd_i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		/* number of sent bytes of current command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	int msgi_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		/* number of received message bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	unsigned char msgi[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		/* received message bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	int msgo_i, msgo_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		/* number of sent bytes and length of current messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	unsigned char msgo[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		/* pending messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	int data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		/* number of sent/received bytes in dataphase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	unsigned long io_port0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	unsigned long io_port1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) #ifdef __ISAPNP__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	struct pnp_dev *pnpdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	struct list_head host_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498)  * host specific command extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) struct aha152x_scdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	struct scsi_cmnd *next;	/* next sc in queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	struct completion *done;/* semaphore to block on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	struct scsi_eh_save ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) /* access macros for hostdata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) #define HOSTDATA(shpnt)		((struct aha152x_hostdata *) &shpnt->hostdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) #define HOSTNO			((shpnt)->host_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) #define CURRENT_SC		(HOSTDATA(shpnt)->current_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) #define DONE_SC			(HOSTDATA(shpnt)->done_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) #define ISSUE_SC		(HOSTDATA(shpnt)->issue_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) #define DISCONNECTED_SC		(HOSTDATA(shpnt)->disconnected_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) #define QLOCK			(HOSTDATA(shpnt)->lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) #define QLOCKER			(HOSTDATA(shpnt)->locker)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) #define QLOCKERL		(HOSTDATA(shpnt)->lockerl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) #define STATE			(HOSTDATA(shpnt)->state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) #define PREVSTATE		(HOSTDATA(shpnt)->prevstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) #define LASTSTATE		(HOSTDATA(shpnt)->laststate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) #define RECONN_TARGET		(HOSTDATA(shpnt)->target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) #define CMD_I			(HOSTDATA(shpnt)->cmd_i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) #define MSGO(i)			(HOSTDATA(shpnt)->msgo[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) #define MSGO_I			(HOSTDATA(shpnt)->msgo_i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) #define MSGOLEN			(HOSTDATA(shpnt)->msgo_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) #define ADDMSGO(x)		(MSGOLEN<256 ? (void)(MSGO(MSGOLEN++)=x) : aha152x_error(shpnt,"MSGO overflow"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) #define MSGI(i)			(HOSTDATA(shpnt)->msgi[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) #define MSGILEN			(HOSTDATA(shpnt)->msgi_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) #define ADDMSGI(x)		(MSGILEN<256 ? (void)(MSGI(MSGILEN++)=x) : aha152x_error(shpnt,"MSGI overflow"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) #define DATA_LEN		(HOSTDATA(shpnt)->data_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) #define SYNCRATE		(HOSTDATA(shpnt)->syncrate[CURRENT_SC->device->id])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) #define SYNCNEG			(HOSTDATA(shpnt)->syncneg[CURRENT_SC->device->id])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) #define DELAY			(HOSTDATA(shpnt)->delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) #define EXT_TRANS		(HOSTDATA(shpnt)->ext_trans)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) #define TC1550			(HOSTDATA(shpnt)->tc1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) #define RECONNECT		(HOSTDATA(shpnt)->reconnect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) #define PARITY			(HOSTDATA(shpnt)->parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) #define SYNCHRONOUS		(HOSTDATA(shpnt)->synchronous)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) #define HOSTIOPORT0		(HOSTDATA(shpnt)->io_port0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) #define HOSTIOPORT1		(HOSTDATA(shpnt)->io_port1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) #define SCDATA(SCpnt)		((struct aha152x_scdata *) (SCpnt)->host_scribble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) #define SCNEXT(SCpnt)		SCDATA(SCpnt)->next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) #define SCSEM(SCpnt)		SCDATA(SCpnt)->done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) #define SG_ADDRESS(buffer)	((char *) sg_virt((buffer)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) /* state handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) static void seldi_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) static void seldo_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) static void selto_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) static void busfree_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) static void msgo_init(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) static void msgo_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) static void msgo_end(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) static void cmd_init(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) static void cmd_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) static void cmd_end(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) static void datai_init(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) static void datai_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) static void datai_end(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) static void datao_init(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) static void datao_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) static void datao_end(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) static void status_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) static void msgi_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) static void msgi_end(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) static void parerr_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) static void rsti_run(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) static void is_complete(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592)  * driver states
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	char		*name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	void		(*init)(struct Scsi_Host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	void		(*run)(struct Scsi_Host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	void		(*end)(struct Scsi_Host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	int		spio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) } states[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	{ "idle",	NULL,		NULL,		NULL,		0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	{ "unknown",	NULL,		NULL,		NULL,		0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	{ "seldo",	NULL,		seldo_run,	NULL,		0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	{ "seldi",	NULL,		seldi_run,	NULL,		0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	{ "selto",	NULL,		selto_run,	NULL,		0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	{ "busfree",	NULL,		busfree_run,	NULL,		0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	{ "msgo",	msgo_init,	msgo_run,	msgo_end,	1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	{ "cmd",	cmd_init,	cmd_run,	cmd_end,	1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	{ "msgi",	NULL,		msgi_run,	msgi_end,	1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	{ "status",	NULL,		status_run,	NULL,		1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	{ "datai",	datai_init,	datai_run,	datai_end,	0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	{ "datao",	datao_init,	datao_run,	datao_end,	0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	{ "parerr",	NULL,		parerr_run,	NULL,		0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	{ "rsti",	NULL,		rsti_run,	NULL,		0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) /* setup & interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) static irqreturn_t intr(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) static void reset_ports(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) static void aha152x_error(struct Scsi_Host *shpnt, char *msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) static void done(struct Scsi_Host *shpnt, int error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) /* diagnostics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) static void show_command(struct scsi_cmnd * ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) static void show_queues(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) static void disp_enintr(struct Scsi_Host *shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)  *  queue services:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) static inline void append_SC(struct scsi_cmnd **SC, struct scsi_cmnd *new_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	struct scsi_cmnd *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	SCNEXT(new_SC) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	if (!*SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		*SC = new_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		for (end = *SC; SCNEXT(end); end = SCNEXT(end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 			;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		SCNEXT(end) = new_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) static inline struct scsi_cmnd *remove_first_SC(struct scsi_cmnd ** SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	struct scsi_cmnd *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	ptr = *SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		*SC = SCNEXT(*SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		SCNEXT(ptr)=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) static inline struct scsi_cmnd *remove_lun_SC(struct scsi_cmnd ** SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 					      int target, int lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	struct scsi_cmnd *ptr, *prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	for (ptr = *SC, prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	     ptr && ((ptr->device->id != target) || (ptr->device->lun != lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	     prev = ptr, ptr = SCNEXT(ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	     ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		if (prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 			SCNEXT(prev) = SCNEXT(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			*SC = SCNEXT(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		SCNEXT(ptr)=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) static inline struct scsi_cmnd *remove_SC(struct scsi_cmnd **SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 					  struct scsi_cmnd *SCp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	struct scsi_cmnd *ptr, *prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	for (ptr = *SC, prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	     ptr && SCp!=ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	     prev = ptr, ptr = SCNEXT(ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	     ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		if (prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			SCNEXT(prev) = SCNEXT(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 			*SC = SCNEXT(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		SCNEXT(ptr)=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) static irqreturn_t swintr(int irqno, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	struct Scsi_Host *shpnt = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	HOSTDATA(shpnt)->swint++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	SETPORT(DMACNTRL0, INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	struct Scsi_Host *shpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	shpnt = scsi_host_alloc(&aha152x_driver_template, sizeof(struct aha152x_hostdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	if (!shpnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		printk(KERN_ERR "aha152x: scsi_host_alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	INIT_LIST_HEAD(&HOSTDATA(shpnt)->host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	/* need to have host registered before triggering any interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	shpnt->io_port   = setup->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	shpnt->n_io_port = IO_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	shpnt->irq       = setup->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	if (!setup->tc1550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		HOSTIOPORT0 = setup->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		HOSTIOPORT1 = setup->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		HOSTIOPORT0 = setup->io_port+0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		HOSTIOPORT1 = setup->io_port-0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	spin_lock_init(&QLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	RECONNECT   = setup->reconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	SYNCHRONOUS = setup->synchronous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	PARITY      = setup->parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	DELAY       = setup->delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	EXT_TRANS   = setup->ext_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	SETPORT(SCSIID, setup->scsiid << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	shpnt->this_id = setup->scsiid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (setup->reconnect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		shpnt->can_queue = AHA152X_MAXQUEUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	/* RESET OUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	printk("aha152x: resetting bus...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	SETPORT(SCSISEQ, SCSIRSTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	mdelay(256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	SETPORT(SCSISEQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	mdelay(DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	reset_ports(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	       "aha152x%d%s: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	       "vital data: rev=%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	       "io=0x%03lx (0x%03lx/0x%03lx), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	       "irq=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	       "scsiid=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	       "reconnect=%s, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	       "parity=%s, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	       "synchronous=%s, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	       "delay=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	       "extended translation=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	       shpnt->host_no, setup->tc1550 ? " (tc1550 mode)" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	       GETPORT(REV) & 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	       shpnt->io_port, HOSTIOPORT0, HOSTIOPORT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	       shpnt->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	       shpnt->this_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	       RECONNECT ? "enabled" : "disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	       PARITY ? "enabled" : "disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	       SYNCHRONOUS ? "enabled" : "disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	       DELAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	       EXT_TRANS ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	/* not expecting any interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	SETPORT(SIMODE0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	SETPORT(SIMODE1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	if (request_irq(shpnt->irq, swintr, IRQF_SHARED, "aha152x", shpnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		printk(KERN_ERR "aha152x%d: irq %d busy.\n", shpnt->host_no, shpnt->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		goto out_host_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	HOSTDATA(shpnt)->swint = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	printk(KERN_INFO "aha152x%d: trying software interrupt, ", shpnt->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	SETPORT(DMACNTRL0, SWINT|INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	mdelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	free_irq(shpnt->irq, shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	if (!HOSTDATA(shpnt)->swint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		if (TESTHI(DMASTAT, INTSTAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 			printk("lost.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			printk("failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		SETPORT(DMACNTRL0, INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		printk(KERN_ERR "aha152x%d: irq %d possibly wrong.  "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 				"Please verify.\n", shpnt->host_no, shpnt->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		goto out_host_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	printk("ok.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	/* clear interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	SETPORT(SSTAT0, 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	SETPORT(SSTAT1, 0xef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	if (request_irq(shpnt->irq, intr, IRQF_SHARED, "aha152x", shpnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		printk(KERN_ERR "aha152x%d: failed to reassign irq %d.\n", shpnt->host_no, shpnt->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		goto out_host_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	if( scsi_add_host(shpnt, NULL) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		free_irq(shpnt->irq, shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		printk(KERN_ERR "aha152x%d: failed to add host.\n", shpnt->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		goto out_host_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	scsi_scan_host(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	return shpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) out_host_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	list_del(&HOSTDATA(shpnt)->host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	scsi_host_put(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) void aha152x_release(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	if (!shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	scsi_remove_host(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	if (shpnt->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		free_irq(shpnt->irq, shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) #if !defined(AHA152X_PCMCIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	if (shpnt->io_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		release_region(shpnt->io_port, IO_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) #ifdef __ISAPNP__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	if (HOSTDATA(shpnt)->pnpdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		pnp_device_detach(HOSTDATA(shpnt)->pnpdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	list_del(&HOSTDATA(shpnt)->host_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	scsi_host_put(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871)  * setup controller to generate interrupts depending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872)  * on current state (lock has to be acquired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) static int setup_expected_interrupts(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	if(CURRENT_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		CURRENT_SC->SCp.phase |= 1 << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		if(CURRENT_SC->SCp.phase & selecting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			SETPORT(SSTAT1, SELTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 			SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			SETPORT(SIMODE1, ENSELTIMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			SETPORT(SIMODE0, (CURRENT_SC->SCp.phase & spiordy) ? ENSPIORDY : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 			SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	} else if(STATE==seldi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		SETPORT(SIMODE0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		SETPORT(SIMODE1, ENSCSIRST | ( (ISSUE_SC||DONE_SC) ? ENBUSFREE : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	if(!HOSTDATA(shpnt)->in_intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		SETBITS(DMACNTRL0, INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	return TESTHI(DMASTAT, INTSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904)  *  Queue a command and setup interrupts for a free bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) static int aha152x_internal_queue(struct scsi_cmnd *SCpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 				  struct completion *complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 				  int phase, void (*done)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	struct Scsi_Host *shpnt = SCpnt->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	SCpnt->scsi_done	= done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	SCpnt->SCp.phase	= not_issued | phase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	SCpnt->SCp.Status	= 0x1; /* Ilegal status by SCSI standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	SCpnt->SCp.Message	= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	SCpnt->SCp.have_data_in	= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	SCpnt->SCp.sent_command	= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	if(SCpnt->SCp.phase & (resetting|check_condition)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		if (!SCpnt->host_scribble || SCSEM(SCpnt) || SCNEXT(SCpnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 			scmd_printk(KERN_ERR, SCpnt, "cannot reuse command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 			return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		if(!SCpnt->host_scribble) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			scmd_printk(KERN_ERR, SCpnt, "allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	SCNEXT(SCpnt)		= NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	SCSEM(SCpnt)		= complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	/* setup scratch area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	   SCp.ptr              : buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	   SCp.this_residual    : buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	   SCp.buffer           : next buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	   SCp.phase            : current state of the command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	if ((phase & resetting) || !scsi_sglist(SCpnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		SCpnt->SCp.ptr           = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		SCpnt->SCp.this_residual = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		scsi_set_resid(SCpnt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		SCpnt->SCp.buffer           = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		SCpnt->SCp.buffer           = scsi_sglist(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		SCpnt->SCp.ptr              = SG_ADDRESS(SCpnt->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	HOSTDATA(shpnt)->total_commands++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	/* Turn led on, when this is the first command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	HOSTDATA(shpnt)->commands++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	if (HOSTDATA(shpnt)->commands==1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		SETPORT(PORTA, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	append_SC(&ISSUE_SC, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	if(!HOSTDATA(shpnt)->in_intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		setup_expected_interrupts(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976)  *  queue a command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) static int aha152x_queue_lck(struct scsi_cmnd *SCpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			     void (*done)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	return aha152x_internal_queue(SCpnt, NULL, 0, done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) static DEF_SCSI_QCMD(aha152x_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) static void reset_done(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	if(SCSEM(SCpnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		complete(SCSEM(SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		printk(KERN_ERR "aha152x: reset_done w/o completion\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)  *  Abort a command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static int aha152x_abort(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	struct Scsi_Host *shpnt = SCpnt->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	struct scsi_cmnd *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	ptr=remove_SC(&ISSUE_SC, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	if(ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		HOSTDATA(shpnt)->commands--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		if (!HOSTDATA(shpnt)->commands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			SETPORT(PORTA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		kfree(SCpnt->host_scribble);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		SCpnt->host_scribble=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	 * FIXME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	 * for current command: queue ABORT for message out and raise ATN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	 * for disconnected command: pseudo SC with ABORT message or ABORT on reselection?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	scmd_printk(KERN_ERR, SCpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		    "cannot abort running or disconnected command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)  * Reset a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static int aha152x_device_reset(struct scsi_cmnd * SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	struct Scsi_Host *shpnt = SCpnt->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	DECLARE_COMPLETION(done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	int ret, issued, disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	unsigned char old_cmd_len = SCpnt->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	unsigned long timeleft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	if(CURRENT_SC==SCpnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		scmd_printk(KERN_ERR, SCpnt, "cannot reset current device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	issued       = remove_SC(&ISSUE_SC, SCpnt) == NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	disconnected = issued && remove_SC(&DISCONNECTED_SC, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	SCpnt->cmd_len         = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	aha152x_internal_queue(SCpnt, &done, resetting, reset_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	timeleft = wait_for_completion_timeout(&done, 100*HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	if (!timeleft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		/* remove command from issue queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		remove_SC(&ISSUE_SC, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	SCpnt->cmd_len         = old_cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	if(SCpnt->SCp.phase & resetted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		HOSTDATA(shpnt)->commands--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		if (!HOSTDATA(shpnt)->commands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			SETPORT(PORTA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		kfree(SCpnt->host_scribble);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		SCpnt->host_scribble=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		ret = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		/* requeue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		if(!issued) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			append_SC(&ISSUE_SC, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		} else if(disconnected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 			append_SC(&DISCONNECTED_SC, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		ret = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static void free_hard_reset_SCs(struct Scsi_Host *shpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 				struct scsi_cmnd **SCs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	struct scsi_cmnd *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	ptr=*SCs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	while(ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		struct scsi_cmnd *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		if(SCDATA(ptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			next = SCNEXT(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 			scmd_printk(KERN_DEBUG, ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 				    "queue corrupted at %p\n", ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 			next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		if (!ptr->device->soft_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			remove_SC(SCs, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			HOSTDATA(shpnt)->commands--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 			kfree(ptr->host_scribble);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			ptr->host_scribble=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		ptr = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)  * Reset the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)  * AIC-6260 has a hard reset (MRST signal), but apparently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)  * one cannot trigger it via software. So live with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)  * a soft reset; no-one seemed to have cared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static int aha152x_bus_reset_host(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	free_hard_reset_SCs(shpnt, &ISSUE_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	free_hard_reset_SCs(shpnt, &DISCONNECTED_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	SETPORT(SCSISEQ, SCSIRSTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	mdelay(256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	SETPORT(SCSISEQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	mdelay(DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	setup_expected_interrupts(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	if(HOSTDATA(shpnt)->commands==0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		SETPORT(PORTA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)  * Reset the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static int aha152x_bus_reset(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	return aha152x_bus_reset_host(SCpnt->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)  *  Restore default values to the AIC-6260 registers and reset the fifos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) static void reset_ports(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	/* disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	SETPORT(DMACNTRL0, RSTFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	SETPORT(SCSISEQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	SETPORT(SXFRCTL1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	SETPORT(SCSISIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	SETRATE(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	/* clear all interrupt conditions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	SETPORT(SSTAT0, 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	SETPORT(SSTAT1, 0xef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	SETPORT(SSTAT4, SYNCERR | FWERR | FRERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	SETPORT(DMACNTRL0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	SETPORT(DMACNTRL1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	SETPORT(BRSTCNTRL, 0xf1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	/* clear SCSI fifos and transfer count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	SETPORT(SXFRCTL0, CH1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	setup_expected_interrupts(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)  * Reset the host (bus and controller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) int aha152x_host_reset_host(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	aha152x_bus_reset_host(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	reset_ports(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)  * Return the "logical geometry"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) static int aha152x_biosparam(struct scsi_device *sdev, struct block_device *bdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		sector_t capacity, int *info_array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	struct Scsi_Host *shpnt = sdev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	/* try default translation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	info_array[0] = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	info_array[1] = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	info_array[2] = (unsigned long)capacity / (64 * 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	/* for disks >1GB do some guessing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	if (info_array[2] >= 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		int info[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 		/* try to figure out the geometry from the partition table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		if (scsicam_bios_param(bdev, capacity, info) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		    !((info[0] == 64 && info[1] == 32) || (info[0] == 255 && info[1] == 63))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 			if (EXT_TRANS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 				printk(KERN_NOTICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 				       "aha152x: unable to verify geometry for disk with >1GB.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 				       "         using extended translation.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 				info_array[0] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 				info_array[1] = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 				info_array[2] = (unsigned long)capacity / (255 * 63);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 				printk(KERN_NOTICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 				       "aha152x: unable to verify geometry for disk with >1GB.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 				       "         Using default translation. Please verify yourself.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 				       "         Perhaps you need to enable extended translation in the driver.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 				       "         See Documentation/scsi/aha152x.rst for details.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 			info_array[0] = info[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 			info_array[1] = info[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 			info_array[2] = info[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 			if (info[0] == 255 && !EXT_TRANS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 				printk(KERN_NOTICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 				       "aha152x: current partition table is using extended translation.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 				       "         using it also, although it's not explicitly enabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)  *  Internal done function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static void done(struct Scsi_Host *shpnt, int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	if (CURRENT_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		if(DONE_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 			scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 				    "there's already a completed command %p "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 				    "- will cause abort\n", DONE_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		DONE_SC = CURRENT_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 		CURRENT_SC = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 		DONE_SC->result = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		printk(KERN_ERR "aha152x: done() called outside of command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) static struct work_struct aha152x_tq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)  * Run service completions on the card with interrupts enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) static void run(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	struct aha152x_hostdata *hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	list_for_each_entry(hd, &aha152x_host_list, host_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 		struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		is_complete(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)  * Interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) static irqreturn_t intr(int irqno, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	struct Scsi_Host *shpnt = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	unsigned char rev, dmacntrl0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	 * Read a couple of registers that are known to not be all 1's. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	 * we read all 1's (-1), that means that either:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	 * a. The host adapter chip has gone bad, and we cannot control it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	 *	OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	 * b. The host adapter is a PCMCIA card that has been ejected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	 * In either case, we cannot do anything with the host adapter at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	 * this point in time. So just ignore the interrupt and return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	 * In the latter case, the interrupt might actually be meant for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	 * someone else sharing this IRQ, and that driver will handle it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	rev = GETPORT(REV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	dmacntrl0 = GETPORT(DMACNTRL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	if ((rev == 0xFF) && (dmacntrl0 == 0xFF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	if( TESTLO(DMASTAT, INTSTAT) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	/* no more interrupts from the controller, while we're busy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	   INTEN is restored by the BH handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	CLRBITS(DMACNTRL0, INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	if( HOSTDATA(shpnt)->service==0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		HOSTDATA(shpnt)->service=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 		/* Poke the BH handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 		INIT_WORK(&aha152x_tq, run);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		schedule_work(&aha152x_tq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)  * busfree phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)  * - handle completition/disconnection/error of current command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)  * - start selection for next command (if any)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) static void busfree_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	int action=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	SETPORT(SXFRCTL0, CH1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	SETPORT(SSTAT1, CLRBUSFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	if(CURRENT_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		action++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		CURRENT_SC->SCp.phase &= ~syncneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		if(CURRENT_SC->SCp.phase & completed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 			/* target sent COMMAND COMPLETE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 			done(shpnt, (CURRENT_SC->SCp.Status & 0xff) | ((CURRENT_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 		} else if(CURRENT_SC->SCp.phase & aborted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 			done(shpnt, (CURRENT_SC->SCp.Status & 0xff) | ((CURRENT_SC->SCp.Message & 0xff) << 8) | (DID_ABORT << 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		} else if(CURRENT_SC->SCp.phase & resetted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 			done(shpnt, (CURRENT_SC->SCp.Status & 0xff) | ((CURRENT_SC->SCp.Message & 0xff) << 8) | (DID_RESET << 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		} else if(CURRENT_SC->SCp.phase & disconnected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 			/* target sent DISCONNECT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 			HOSTDATA(shpnt)->disconnections++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 			append_SC(&DISCONNECTED_SC, CURRENT_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 			CURRENT_SC->SCp.phase |= 1 << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 			CURRENT_SC = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 			done(shpnt, DID_ERROR << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		HOSTDATA(shpnt)->busfree_without_old_command++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	if(DONE_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 		action++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 		if(DONE_SC->SCp.phase & check_condition) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 			struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 			struct aha152x_scdata *sc = SCDATA(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 			scsi_eh_restore_cmnd(cmd, &sc->ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 			cmd->SCp.Status = SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 			HOSTDATA(shpnt)->commands--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 			if (!HOSTDATA(shpnt)->commands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 				SETPORT(PORTA, 0);	/* turn led off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 		} else if(DONE_SC->SCp.Status==SAM_STAT_CHECK_CONDITION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 			HOSTDATA(shpnt)->busfree_with_check_condition++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 			if(!(DONE_SC->SCp.phase & not_issued)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 				struct aha152x_scdata *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 				struct scsi_cmnd *ptr = DONE_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 				DONE_SC=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 				sc = SCDATA(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 				/* It was allocated in aha152x_internal_queue? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 				BUG_ON(!sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 				scsi_eh_prep_cmnd(ptr, &sc->ses, NULL, 0, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 				DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 				aha152x_internal_queue(ptr, NULL, check_condition, ptr->scsi_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 				DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		if(DONE_SC && DONE_SC->scsi_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 			struct scsi_cmnd *ptr = DONE_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 			DONE_SC=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 			/* turn led off, when no commands are in the driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 			HOSTDATA(shpnt)->commands--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 			if (!HOSTDATA(shpnt)->commands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 				SETPORT(PORTA, 0);	/* turn led off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 			if(ptr->scsi_done != reset_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 				kfree(ptr->host_scribble);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 				ptr->host_scribble=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 			DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 			ptr->scsi_done(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 			DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		DONE_SC=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		HOSTDATA(shpnt)->busfree_without_done_command++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	if(ISSUE_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		CURRENT_SC = remove_first_SC(&ISSUE_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	if(CURRENT_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 		action++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		CURRENT_SC->SCp.phase |= selecting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		/* clear selection timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		SETPORT(SSTAT1, SELTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->device->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		SETPORT(SXFRCTL1, (PARITY ? ENSPCHK : 0 ) | ENSTIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		SETPORT(SCSISEQ, ENSELO | ENAUTOATNO | (DISCONNECTED_SC ? ENRESELI : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 		HOSTDATA(shpnt)->busfree_without_new_command++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		SETPORT(SCSISEQ, DISCONNECTED_SC ? ENRESELI : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	if(!action)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		HOSTDATA(shpnt)->busfree_without_any_action++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)  * Selection done (OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)  * - queue IDENTIFY message and SDTR to selected target for message out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)  *   (ATN asserted automagically via ENAUTOATNO in busfree())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) static void seldo_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	SETPORT(SCSISIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	SETPORT(SSTAT1, CLRBUSFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	SETPORT(SSTAT1, CLRPHASECHG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	CURRENT_SC->SCp.phase &= ~(selecting|not_issued);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	SETPORT(SCSISEQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	if (TESTLO(SSTAT0, SELDO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 			    "aha152x: passing bus free condition\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		done(shpnt, DID_NO_CONNECT << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	SETPORT(SSTAT0, CLRSELDO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	if (CURRENT_SC->SCp.phase & aborting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		ADDMSGO(ABORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	} else if (CURRENT_SC->SCp.phase & resetting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 		ADDMSGO(BUS_DEVICE_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	} else if (SYNCNEG==0 && SYNCHRONOUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 		CURRENT_SC->SCp.phase |= syncneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		MSGOLEN += spi_populate_sync_msg(&MSGO(MSGOLEN), 50, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		SYNCNEG=1;		/* negotiation in progress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	SETRATE(SYNCRATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)  * Selection timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)  * - return command to mid-level with failure cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) static void selto_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	SETPORT(SCSISEQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	SETPORT(SSTAT1, CLRSELTIMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	if (!CURRENT_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	CURRENT_SC->SCp.phase &= ~selecting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	if (CURRENT_SC->SCp.phase & aborted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 		done(shpnt, DID_ABORT << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	else if (TESTLO(SSTAT0, SELINGO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		done(shpnt, DID_BUS_BUSY << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 		/* ARBITRATION won, but SELECTION failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 		done(shpnt, DID_NO_CONNECT << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)  * Selection in done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)  * - put current command back to issue queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)  *   (reconnection of a disconnected nexus instead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)  *    of successful selection out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) static void seldi_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	int selid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	int target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	SETPORT(SCSISIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	SETPORT(SSTAT0, CLRSELDI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	SETPORT(SSTAT1, CLRBUSFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	SETPORT(SSTAT1, CLRPHASECHG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	if(CURRENT_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		if(!(CURRENT_SC->SCp.phase & not_issued))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 			scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 				    "command should not have been issued yet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		append_SC(&ISSUE_SC, CURRENT_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		CURRENT_SC = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	if (!DISCONNECTED_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	RECONN_TARGET=-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	selid = GETPORT(SELID) & ~(1 << shpnt->this_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	if (selid==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 		shost_printk(KERN_INFO, shpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 			     "target id unknown (%02x)\n", selid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	for(target=7; !(selid & (1 << target)); target--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	if(selid & ~(1 << target)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 		shost_printk(KERN_INFO, shpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 			     "multiple targets reconnected (%02x)\n", selid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	SETPORT(SCSIID, (shpnt->this_id << OID_) | target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	SETPORT(SCSISEQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	SETRATE(HOSTDATA(shpnt)->syncrate[target]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	RECONN_TARGET=target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)  * message in phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)  * - handle initial message after reconnection to identify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)  *   reconnecting nexus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)  * - queue command on DISCONNECTED_SC on DISCONNECT message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)  * - set completed flag on COMMAND COMPLETE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)  *   (other completition code moved to busfree_run)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)  * - handle response to SDTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)  * - clear synchronous transfer agreements on BUS RESET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)  * FIXME: what about SAVE POINTERS, RESTORE POINTERS?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) static void msgi_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		int sstat1 = GETPORT(SSTAT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		if(sstat1 & (PHASECHG|PHASEMIS|BUSFREE) || !(sstat1 & REQINIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 		if (TESTLO(SSTAT0, SPIORDY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		ADDMSGI(GETPORT(SCSIDAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		if(!CURRENT_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 			if(LASTSTATE!=seldi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 				shost_printk(KERN_ERR, shpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 					     "message in w/o current command"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 					     " not after reselection\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 			 * Handle reselection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 			if(!(MSGI(0) & IDENTIFY_BASE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 				shost_printk(KERN_ERR, shpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 					     "target didn't identify after reselection\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 			CURRENT_SC = remove_lun_SC(&DISCONNECTED_SC, RECONN_TARGET, MSGI(0) & 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 			if (!CURRENT_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 				show_queues(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 				shost_printk(KERN_ERR, shpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 					     "no disconnected command"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 					     " for target %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 					     RECONN_TARGET, MSGI(0) & 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 			CURRENT_SC->SCp.Message = MSGI(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 			CURRENT_SC->SCp.phase &= ~disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 			MSGILEN=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 			/* next message if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		CURRENT_SC->SCp.Message = MSGI(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 		switch (MSGI(0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		case DISCONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 			if (!RECONNECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 				scmd_printk(KERN_WARNING, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 					    "target was not allowed to disconnect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 			CURRENT_SC->SCp.phase |= disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 		case COMMAND_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 			CURRENT_SC->SCp.phase |= completed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 		case MESSAGE_REJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 			if (SYNCNEG==1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 				scmd_printk(KERN_INFO, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 					    "Synchronous Data Transfer Request"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 					    " was rejected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 				SYNCNEG=2;	/* negotiation completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 				scmd_printk(KERN_INFO, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 					    "inbound message (MESSAGE REJECT)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		case SAVE_POINTERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		case RESTORE_POINTERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		case EXTENDED_MESSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			if(MSGILEN<2 || MSGILEN<MSGI(1)+2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 				/* not yet completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 			switch (MSGI(2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 			case EXTENDED_SDTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 				{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 					long ticks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 					if (MSGI(1) != 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 						scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 							    "SDTR message length!=3\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 					if (!HOSTDATA(shpnt)->synchronous)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 					printk(INFO_LEAD, CMDINFO(CURRENT_SC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 					spi_print_msg(&MSGI(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 					printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 					ticks = (MSGI(3) * 4 + 49) / 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 					if (syncneg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 						/* negotiation in progress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 						if (ticks > 9 || MSGI(4) < 1 || MSGI(4) > 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 							ADDMSGO(MESSAGE_REJECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 							scmd_printk(KERN_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 								    CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 								    "received Synchronous Data Transfer Request invalid - rejected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 							break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 						}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 						SYNCRATE |= ((ticks - 2) << 4) + MSGI(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 					} else if (ticks <= 9 && MSGI(4) >= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 						ADDMSGO(EXTENDED_MESSAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 						ADDMSGO(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 						ADDMSGO(EXTENDED_SDTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 						if (ticks < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 							ticks = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 							ADDMSGO(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 						} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 							ADDMSGO(MSGI(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 						if (MSGI(4) > 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 							MSGI(4) = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 						ADDMSGO(MSGI(4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 						SYNCRATE |= ((ticks - 2) << 4) + MSGI(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 					} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 						/* requested SDTR is too slow, do it asynchronously */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 						scmd_printk(KERN_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 							    CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 							    "Synchronous Data Transfer Request too slow - Rejecting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 						ADDMSGO(MESSAGE_REJECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 					/* negotiation completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 					SYNCNEG=2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 					SETRATE(SYNCRATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 			case BUS_DEVICE_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 				{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 					int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 					for(i=0; i<8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 						HOSTDATA(shpnt)->syncrate[i]=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 						HOSTDATA(shpnt)->syncneg[i]=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 			case EXTENDED_MODIFY_DATA_POINTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 			case EXTENDED_EXTENDED_IDENTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 			case EXTENDED_WDTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 				ADDMSGO(MESSAGE_REJECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 		MSGILEN=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) static void msgi_end(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	if(MSGILEN>0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		scmd_printk(KERN_WARNING, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 			    "target left before message completed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 			    MSGILEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	if (MSGOLEN > 0 && !(GETPORT(SSTAT1) & BUSFREE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 		SETPORT(SCSISIG, P_MSGI | SIG_ATNO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)  * message out phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) static void msgo_init(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	if(MSGOLEN==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 		if((CURRENT_SC->SCp.phase & syncneg) && SYNCNEG==2 && SYNCRATE==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 			ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 			scmd_printk(KERN_INFO, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 				    "unexpected MESSAGE OUT phase; rejecting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 			ADDMSGO(MESSAGE_REJECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)  * message out phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) static void msgo_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	while(MSGO_I<MSGOLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		if (TESTLO(SSTAT0, SPIORDY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		if (MSGO_I==MSGOLEN-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 			/* Leave MESSAGE OUT after transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 			SETPORT(SSTAT1, CLRATNO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 		if (MSGO(MSGO_I) & IDENTIFY_BASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 			CURRENT_SC->SCp.phase |= identified;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 		if (MSGO(MSGO_I)==ABORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 			CURRENT_SC->SCp.phase |= aborted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 		if (MSGO(MSGO_I)==BUS_DEVICE_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 			CURRENT_SC->SCp.phase |= resetted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 		SETPORT(SCSIDAT, MSGO(MSGO_I++));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) static void msgo_end(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	if(MSGO_I<MSGOLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 		scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 			    "message sent incompletely (%d/%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 			    MSGO_I, MSGOLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 		if(SYNCNEG==1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 			scmd_printk(KERN_INFO, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 				    "Synchronous Data Transfer Request was rejected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 			SYNCNEG=2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	MSGO_I  = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	MSGOLEN = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)  * command phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) static void cmd_init(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	if (CURRENT_SC->SCp.sent_command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 		scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 			    "command already sent\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 		done(shpnt, DID_ERROR << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	CMD_I=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)  * command phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) static void cmd_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	while(CMD_I<CURRENT_SC->cmd_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		if (TESTLO(SSTAT0, SPIORDY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 		SETPORT(SCSIDAT, CURRENT_SC->cmnd[CMD_I++]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) static void cmd_end(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	if(CMD_I<CURRENT_SC->cmd_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 			    "command sent incompletely (%d/%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 			    CMD_I, CURRENT_SC->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 		CURRENT_SC->SCp.sent_command++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)  * status phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) static void status_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	if (TESTLO(SSTAT0, SPIORDY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	CURRENT_SC->SCp.Status = GETPORT(SCSIDAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)  * data in phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) static void datai_init(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	SETPORT(DMACNTRL0, RSTFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	SETPORT(DMACNTRL0, RSTFIFO|ENDMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	SETPORT(SXFRCTL0, CH1|CLRSTCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	SETPORT(SIMODE0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	SETPORT(SIMODE1, ENSCSIPERR | ENSCSIRST | ENPHASEMIS | ENBUSFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	DATA_LEN=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) static void datai_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	unsigned long the_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	int fifodata, data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	 * loop while the phase persists or the fifos are not empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	while(TESTLO(DMASTAT, INTSTAT) || TESTLO(DMASTAT, DFIFOEMP) || TESTLO(SSTAT2, SEMPTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 		/* FIXME: maybe this should be done by setting up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 		 * STCNT to trigger ENSWRAP interrupt, instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 		 * polling for DFIFOFULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		the_time=jiffies + 100*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 		while(TESTLO(DMASTAT, DFIFOFULL|INTSTAT) && time_before(jiffies,the_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 			barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 		if(TESTLO(DMASTAT, DFIFOFULL|INTSTAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 			scmd_printk(KERN_ERR, CURRENT_SC, "datai timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 		if(TESTHI(DMASTAT, DFIFOFULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 			fifodata = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 			the_time=jiffies + 100*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 			while(TESTLO(SSTAT2, SEMPTY) && time_before(jiffies,the_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 				barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 			if(TESTLO(SSTAT2, SEMPTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 				scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 					    "datai sempty timeout");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 			fifodata = GETPORT(FIFOSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		if(CURRENT_SC->SCp.this_residual>0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 			while(fifodata>0 && CURRENT_SC->SCp.this_residual>0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 				data_count = fifodata > CURRENT_SC->SCp.this_residual ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 						CURRENT_SC->SCp.this_residual :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 						fifodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 				fifodata -= data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 				if (data_count & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 					SETPORT(DMACNTRL0, ENDMA|_8BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 					*CURRENT_SC->SCp.ptr++ = GETPORT(DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 					CURRENT_SC->SCp.this_residual--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 					DATA_LEN++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 					SETPORT(DMACNTRL0, ENDMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 				if (data_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 					data_count >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 					insw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 					CURRENT_SC->SCp.ptr += 2 * data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 					CURRENT_SC->SCp.this_residual -= 2 * data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 					DATA_LEN += 2 * data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 				if (CURRENT_SC->SCp.this_residual == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 				    !sg_is_last(CURRENT_SC->SCp.buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 					/* advance to next buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 					CURRENT_SC->SCp.buffer = sg_next(CURRENT_SC->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 					CURRENT_SC->SCp.ptr           = SG_ADDRESS(CURRENT_SC->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 					CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 		} else if (fifodata > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 			scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 				    "no buffers left for %d(%d) bytes"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 				    " (data overrun!?)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 				    fifodata, GETPORT(FIFOSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 			SETPORT(DMACNTRL0, ENDMA|_8BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 			while(fifodata>0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 				GETPORT(DATAPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 				fifodata--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 				DATA_LEN++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 			SETPORT(DMACNTRL0, ENDMA|_8BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	if(TESTLO(DMASTAT, INTSTAT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	   TESTLO(DMASTAT, DFIFOEMP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 	   TESTLO(SSTAT2, SEMPTY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	   GETPORT(FIFOSTAT)>0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 		 * something went wrong, if there's something left in the fifos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 		 * or the phase didn't change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 		scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 			    "fifos should be empty and phase should have changed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	if(DATA_LEN!=GETSTCNT()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 		scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 			    "manual transfer count differs from automatic "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 			    "(count=%d;stcnt=%d;diff=%d;fifostat=%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 			    DATA_LEN, GETSTCNT(), GETSTCNT()-DATA_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 			    GETPORT(FIFOSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 		mdelay(10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) static void datai_end(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	CMD_INC_RESID(CURRENT_SC, -GETSTCNT());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	SETPORT(SXFRCTL0, CH1|CLRSTCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	SETPORT(DMACNTRL0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)  * data out phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) static void datao_init(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	SETPORT(DMACNTRL0, WRITE_READ | RSTFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	SETPORT(DMACNTRL0, WRITE_READ | ENDMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	SETPORT(SXFRCTL0, CH1|CLRSTCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	SETPORT(SIMODE0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	SETPORT(SIMODE1, ENSCSIPERR | ENSCSIRST | ENPHASEMIS | ENBUSFREE );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	DATA_LEN = scsi_get_resid(CURRENT_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) static void datao_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	unsigned long the_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	int data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	/* until phase changes or all data sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	while(TESTLO(DMASTAT, INTSTAT) && CURRENT_SC->SCp.this_residual>0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 		data_count = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		if(data_count > CURRENT_SC->SCp.this_residual)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 			data_count=CURRENT_SC->SCp.this_residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		if(TESTLO(DMASTAT, DFIFOEMP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 			scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 				    "datao fifo not empty (%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 				    GETPORT(FIFOSTAT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 		if(data_count & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 			SETPORT(DMACNTRL0,WRITE_READ|ENDMA|_8BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 			SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 			CURRENT_SC->SCp.this_residual--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 			CMD_INC_RESID(CURRENT_SC, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 			SETPORT(DMACNTRL0,WRITE_READ|ENDMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 		if(data_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 			data_count >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 			outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 			CURRENT_SC->SCp.ptr           += 2 * data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 			CURRENT_SC->SCp.this_residual -= 2 * data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 			CMD_INC_RESID(CURRENT_SC, -2 * data_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 		if (CURRENT_SC->SCp.this_residual == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		    !sg_is_last(CURRENT_SC->SCp.buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 			/* advance to next buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 			CURRENT_SC->SCp.buffer = sg_next(CURRENT_SC->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 			CURRENT_SC->SCp.ptr           = SG_ADDRESS(CURRENT_SC->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 			CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 		the_time=jiffies + 100*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 		while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT) && time_before(jiffies,the_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 			barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 		if(TESTLO(DMASTAT, DFIFOEMP|INTSTAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 			scmd_printk(KERN_ERR, CURRENT_SC, "dataout timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) static void datao_end(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	if(TESTLO(DMASTAT, DFIFOEMP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 		u32 datao_cnt = GETSTCNT();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		int datao_out = DATA_LEN - scsi_get_resid(CURRENT_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		int done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 		struct scatterlist *sg = scsi_sglist(CURRENT_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 		CMD_INC_RESID(CURRENT_SC, datao_out - datao_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 		done = scsi_bufflen(CURRENT_SC) - scsi_get_resid(CURRENT_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		/* Locate the first SG entry not yet sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		while (done > 0 && !sg_is_last(sg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 			if (done < sg->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 			done -= sg->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 			sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 		CURRENT_SC->SCp.buffer = sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) + done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 			done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	SETPORT(SXFRCTL0, CH1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	SETPORT(DMACNTRL0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)  * figure out what state we're in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) static int update_state(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	int dataphase=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	unsigned int stat0 = GETPORT(SSTAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 	unsigned int stat1 = GETPORT(SSTAT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 	PREVSTATE = STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	STATE=unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 	if(stat1 & SCSIRSTI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 		STATE=rsti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 		SETPORT(SCSISEQ,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 		SETPORT(SSTAT1,SCSIRSTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	} else if (stat0 & SELDI && PREVSTATE == busfree) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 		STATE=seldi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	} else if(stat0 & SELDO && CURRENT_SC && (CURRENT_SC->SCp.phase & selecting)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 		STATE=seldo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	} else if(stat1 & SELTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 		STATE=selto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	} else if(stat1 & BUSFREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 		STATE=busfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 		SETPORT(SSTAT1,BUSFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	} else if(stat1 & SCSIPERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 		STATE=parerr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 		SETPORT(SSTAT1,SCSIPERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 	} else if(stat1 & REQINIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 		switch(GETPORT(SCSISIG) & P_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 		case P_MSGI:	STATE=msgi;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 		case P_MSGO:	STATE=msgo;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 		case P_DATAO:	STATE=datao;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 		case P_DATAI:	STATE=datai;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 		case P_STATUS:	STATE=status;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 		case P_CMD:	STATE=cmd;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 		dataphase=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	if((stat0 & SELDI) && STATE!=seldi && !dataphase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 		scmd_printk(KERN_INFO, CURRENT_SC, "reselection missed?");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	if(STATE!=PREVSTATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 		LASTSTATE=PREVSTATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	return dataphase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)  * handle parity error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)  * FIXME: in which phase?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) static void parerr_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	scmd_printk(KERN_ERR, CURRENT_SC, "parity error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	done(shpnt, DID_PARITY << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)  * handle reset in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) static void rsti_run(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	struct scsi_cmnd *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	shost_printk(KERN_NOTICE, shpnt, "scsi reset in\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	ptr=DISCONNECTED_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	while(ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		struct scsi_cmnd *next = SCNEXT(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 		if (!ptr->device->soft_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 			remove_SC(&DISCONNECTED_SC, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 			kfree(ptr->host_scribble);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 			ptr->host_scribble=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 			ptr->result =  DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 			ptr->scsi_done(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 		ptr = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	if(CURRENT_SC && !CURRENT_SC->device->soft_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 		done(shpnt, DID_RESET << 16 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)  * bottom-half handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) static void is_complete(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	int dataphase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	int pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	if(!shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	if( HOSTDATA(shpnt)->service==0 )  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 		DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	HOSTDATA(shpnt)->service = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	if(HOSTDATA(shpnt)->in_intr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 		DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 		/* aha152x_error never returns.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 		aha152x_error(shpnt, "bottom-half already running!?");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	HOSTDATA(shpnt)->in_intr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	 * loop while there are interrupt conditions pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 		unsigned long start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 		DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 		dataphase=update_state(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 		 * end previous state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 		if(PREVSTATE!=STATE && states[PREVSTATE].end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 			states[PREVSTATE].end(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 		 * disable SPIO mode if previous phase used it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 		 * and this one doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 		if(states[PREVSTATE].spio && !states[STATE].spio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 			SETPORT(SXFRCTL0, CH1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 			SETPORT(DMACNTRL0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 			if(CURRENT_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 				CURRENT_SC->SCp.phase &= ~spiordy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 		 * accept current dataphase phase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 		if(dataphase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 			SETPORT(SSTAT0, REQINIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 			SETPORT(SCSISIG, GETPORT(SCSISIG) & P_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 			SETPORT(SSTAT1, PHASECHG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 		 * enable SPIO mode if previous didn't use it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 		 * and this one does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 		if(!states[PREVSTATE].spio && states[STATE].spio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 			SETPORT(DMACNTRL0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 			SETPORT(SXFRCTL0, CH1|SPIOEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 			if(CURRENT_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 				CURRENT_SC->SCp.phase |= spiordy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 		 * initialize for new state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 		if(PREVSTATE!=STATE && states[STATE].init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 			states[STATE].init(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 		 * handle current state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 		if(states[STATE].run)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 			states[STATE].run(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 			scmd_printk(KERN_ERR, CURRENT_SC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 				    "unexpected state (%x)\n", STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 		 * setup controller to interrupt on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 		 * the next expected condition and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		 * loop if it's already there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 		DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 		pending=setup_expected_interrupts(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 		HOSTDATA(shpnt)->count[STATE]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 		if(PREVSTATE!=STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 			HOSTDATA(shpnt)->count_trans[STATE]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 		HOSTDATA(shpnt)->time[STATE] += jiffies-start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	} while(pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	 * enable interrupts and leave bottom-half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 	HOSTDATA(shpnt)->in_intr--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 	SETBITS(DMACNTRL0, INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394)  * Dump the current driver status and panic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) static void aha152x_error(struct Scsi_Host *shpnt, char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	shost_printk(KERN_EMERG, shpnt, "%s\n", msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	show_queues(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 	panic("aha152x panic\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)  * display enabled interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) static void disp_enintr(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	int s0, s1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	s0 = GETPORT(SIMODE0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	s1 = GETPORT(SIMODE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	shost_printk(KERN_DEBUG, shpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		     "enabled interrupts (%s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 		     (s0 & ENSELDO) ? "ENSELDO " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 		     (s0 & ENSELDI) ? "ENSELDI " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 		     (s0 & ENSELINGO) ? "ENSELINGO " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 		     (s0 & ENSWRAP) ? "ENSWRAP " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 		     (s0 & ENSDONE) ? "ENSDONE " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 		     (s0 & ENSPIORDY) ? "ENSPIORDY " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 		     (s0 & ENDMADONE) ? "ENDMADONE " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		     (s1 & ENSELTIMO) ? "ENSELTIMO " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 		     (s1 & ENATNTARG) ? "ENATNTARG " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 		     (s1 & ENPHASEMIS) ? "ENPHASEMIS " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 		     (s1 & ENBUSFREE) ? "ENBUSFREE " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		     (s1 & ENSCSIPERR) ? "ENSCSIPERR " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		     (s1 & ENPHASECHG) ? "ENPHASECHG " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		     (s1 & ENREQINIT) ? "ENREQINIT " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)  * Show the command data of a command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) static void show_command(struct scsi_cmnd *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	scsi_print_command(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	scmd_printk(KERN_DEBUG, ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 		    "request_bufflen=%d; resid=%d; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 		    "phase |%s%s%s%s%s%s%s%s%s; next=0x%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 		    scsi_bufflen(ptr), scsi_get_resid(ptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 		    (ptr->SCp.phase & not_issued) ? "not issued|" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 		    (ptr->SCp.phase & selecting) ? "selecting|" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 		    (ptr->SCp.phase & identified) ? "identified|" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 		    (ptr->SCp.phase & disconnected) ? "disconnected|" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 		    (ptr->SCp.phase & completed) ? "completed|" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 		    (ptr->SCp.phase & spiordy) ? "spiordy|" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 		    (ptr->SCp.phase & syncneg) ? "syncneg|" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 		    (ptr->SCp.phase & aborted) ? "aborted|" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 		    (ptr->SCp.phase & resetted) ? "resetted|" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 		    (SCDATA(ptr)) ? SCNEXT(ptr) : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)  * Dump the queued data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) static void show_queues(struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	struct scsi_cmnd *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	printk(KERN_DEBUG "\nqueue status:\nissue_SC:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	for (ptr = ISSUE_SC; ptr; ptr = SCNEXT(ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 		show_command(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	printk(KERN_DEBUG "current_SC:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 	if (CURRENT_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 		show_command(CURRENT_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 		printk(KERN_DEBUG "none\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	printk(KERN_DEBUG "disconnected_SC:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	for (ptr = DISCONNECTED_SC; ptr; ptr = SCDATA(ptr) ? SCNEXT(ptr) : NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 		show_command(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	disp_enintr(shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) static void get_command(struct seq_file *m, struct scsi_cmnd * ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	seq_printf(m, "%p: target=%d; lun=%d; cmnd=( ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 		ptr, ptr->device->id, (u8)ptr->device->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 	for (i = 0; i < COMMAND_SIZE(ptr->cmnd[0]); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 		seq_printf(m, "0x%02x ", ptr->cmnd[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	seq_printf(m, "); resid=%d; residual=%d; buffers=%d; phase |",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 		scsi_get_resid(ptr), ptr->SCp.this_residual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 		sg_nents(ptr->SCp.buffer) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	if (ptr->SCp.phase & not_issued)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 		seq_puts(m, "not issued|");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	if (ptr->SCp.phase & selecting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 		seq_puts(m, "selecting|");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	if (ptr->SCp.phase & disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 		seq_puts(m, "disconnected|");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	if (ptr->SCp.phase & aborted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 		seq_puts(m, "aborted|");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 	if (ptr->SCp.phase & identified)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 		seq_puts(m, "identified|");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	if (ptr->SCp.phase & completed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 		seq_puts(m, "completed|");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	if (ptr->SCp.phase & spiordy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 		seq_puts(m, "spiordy|");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	if (ptr->SCp.phase & syncneg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 		seq_puts(m, "syncneg|");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	seq_printf(m, "; next=0x%p\n", SCNEXT(ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) static void get_ports(struct seq_file *m, struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	int s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	seq_printf(m, "\n%s: %s(%s) ", CURRENT_SC ? "on bus" : "waiting", states[STATE].name, states[PREVSTATE].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	s = GETPORT(SCSISEQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	seq_puts(m, "SCSISEQ( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	if (s & TEMODEO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 		seq_puts(m, "TARGET MODE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	if (s & ENSELO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 		seq_puts(m, "SELO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	if (s & ENSELI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 		seq_puts(m, "SELI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	if (s & ENRESELI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 		seq_puts(m, "RESELI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	if (s & ENAUTOATNO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 		seq_puts(m, "AUTOATNO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	if (s & ENAUTOATNI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 		seq_puts(m, "AUTOATNI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 	if (s & ENAUTOATNP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 		seq_puts(m, "AUTOATNP ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	if (s & SCSIRSTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 		seq_puts(m, "SCSIRSTO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	seq_puts(m, ");");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	seq_puts(m, " SCSISIG(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	s = GETPORT(SCSISIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	switch (s & P_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	case P_DATAO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 		seq_puts(m, "DATA OUT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	case P_DATAI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 		seq_puts(m, "DATA IN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	case P_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 		seq_puts(m, "COMMAND");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	case P_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 		seq_puts(m, "STATUS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	case P_MSGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 		seq_puts(m, "MESSAGE OUT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	case P_MSGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 		seq_puts(m, "MESSAGE IN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 		seq_puts(m, "*invalid*");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	seq_puts(m, "); ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 	seq_printf(m, "INTSTAT (%s); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	seq_puts(m, "SSTAT( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	s = GETPORT(SSTAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 	if (s & TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 		seq_puts(m, "TARGET ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	if (s & SELDO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 		seq_puts(m, "SELDO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 	if (s & SELDI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 		seq_puts(m, "SELDI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	if (s & SELINGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 		seq_puts(m, "SELINGO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	if (s & SWRAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 		seq_puts(m, "SWRAP ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	if (s & SDONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 		seq_puts(m, "SDONE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	if (s & SPIORDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 		seq_puts(m, "SPIORDY ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	if (s & DMADONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 		seq_puts(m, "DMADONE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	s = GETPORT(SSTAT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	if (s & SELTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 		seq_puts(m, "SELTO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	if (s & ATNTARG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 		seq_puts(m, "ATNTARG ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	if (s & SCSIRSTI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 		seq_puts(m, "SCSIRSTI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	if (s & PHASEMIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 		seq_puts(m, "PHASEMIS ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	if (s & BUSFREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 		seq_puts(m, "BUSFREE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	if (s & SCSIPERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 		seq_puts(m, "SCSIPERR ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	if (s & PHASECHG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 		seq_puts(m, "PHASECHG ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	if (s & REQINIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 		seq_puts(m, "REQINIT ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	seq_puts(m, "); ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	seq_puts(m, "SSTAT( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	s = GETPORT(SSTAT0) & GETPORT(SIMODE0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	if (s & TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 		seq_puts(m, "TARGET ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	if (s & SELDO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 		seq_puts(m, "SELDO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	if (s & SELDI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 		seq_puts(m, "SELDI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	if (s & SELINGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 		seq_puts(m, "SELINGO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	if (s & SWRAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 		seq_puts(m, "SWRAP ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	if (s & SDONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 		seq_puts(m, "SDONE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	if (s & SPIORDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 		seq_puts(m, "SPIORDY ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	if (s & DMADONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 		seq_puts(m, "DMADONE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	s = GETPORT(SSTAT1) & GETPORT(SIMODE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	if (s & SELTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 		seq_puts(m, "SELTO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	if (s & ATNTARG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 		seq_puts(m, "ATNTARG ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	if (s & SCSIRSTI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 		seq_puts(m, "SCSIRSTI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	if (s & PHASEMIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 		seq_puts(m, "PHASEMIS ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	if (s & BUSFREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 		seq_puts(m, "BUSFREE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	if (s & SCSIPERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 		seq_puts(m, "SCSIPERR ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	if (s & PHASECHG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 		seq_puts(m, "PHASECHG ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	if (s & REQINIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 		seq_puts(m, "REQINIT ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	seq_puts(m, "); ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	seq_puts(m, "SXFRCTL0( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 	s = GETPORT(SXFRCTL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	if (s & SCSIEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		seq_puts(m, "SCSIEN ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 	if (s & DMAEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 		seq_puts(m, "DMAEN ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	if (s & CH1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 		seq_puts(m, "CH1 ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	if (s & CLRSTCNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		seq_puts(m, "CLRSTCNT ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	if (s & SPIOEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 		seq_puts(m, "SPIOEN ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 	if (s & CLRCH1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 		seq_puts(m, "CLRCH1 ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	seq_puts(m, "); ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	seq_puts(m, "SIGNAL( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 	s = GETPORT(SCSISIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 	if (s & SIG_ATNI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 		seq_puts(m, "ATNI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 	if (s & SIG_SELI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 		seq_puts(m, "SELI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	if (s & SIG_BSYI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		seq_puts(m, "BSYI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	if (s & SIG_REQI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 		seq_puts(m, "REQI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	if (s & SIG_ACKI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 		seq_puts(m, "ACKI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	seq_puts(m, "); ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	seq_printf(m, "SELID(%02x), ", GETPORT(SELID));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 	seq_printf(m, "STCNT(%d), ", GETSTCNT());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	seq_puts(m, "SSTAT2( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	s = GETPORT(SSTAT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	if (s & SOFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 		seq_puts(m, "SOFFSET ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	if (s & SEMPTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 		seq_puts(m, "SEMPTY ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 	if (s & SFULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		seq_puts(m, "SFULL ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 	seq_printf(m, "); SFCNT (%d); ", s & (SFULL | SFCNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 	s = GETPORT(SSTAT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 	seq_printf(m, "SCSICNT (%d), OFFCNT(%d), ", (s & 0xf0) >> 4, s & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 	seq_puts(m, "SSTAT4( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	s = GETPORT(SSTAT4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 	if (s & SYNCERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 		seq_puts(m, "SYNCERR ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 	if (s & FWERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 		seq_puts(m, "FWERR ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	if (s & FRERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 		seq_puts(m, "FRERR ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	seq_puts(m, "); ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 	seq_puts(m, "DMACNTRL0( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 	s = GETPORT(DMACNTRL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 	seq_printf(m, "%s ", s & _8BIT ? "8BIT" : "16BIT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	seq_printf(m, "%s ", s & DMA ? "DMA" : "PIO");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 	seq_printf(m, "%s ", s & WRITE_READ ? "WRITE" : "READ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 	if (s & ENDMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 		seq_puts(m, "ENDMA ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 	if (s & INTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 		seq_puts(m, "INTEN ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 	if (s & RSTFIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 		seq_puts(m, "RSTFIFO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	if (s & SWINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 		seq_puts(m, "SWINT ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 	seq_puts(m, "); ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 	seq_puts(m, "DMASTAT( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 	s = GETPORT(DMASTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 	if (s & ATDONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 		seq_puts(m, "ATDONE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 	if (s & WORDRDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 		seq_puts(m, "WORDRDY ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	if (s & DFIFOFULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 		seq_puts(m, "DFIFOFULL ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	if (s & DFIFOEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 		seq_puts(m, "DFIFOEMP ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	seq_puts(m, ")\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 	seq_puts(m, "enabled interrupts( ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 	s = GETPORT(SIMODE0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	if (s & ENSELDO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 		seq_puts(m, "ENSELDO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 	if (s & ENSELDI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 		seq_puts(m, "ENSELDI ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 	if (s & ENSELINGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 		seq_puts(m, "ENSELINGO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	if (s & ENSWRAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 		seq_puts(m, "ENSWRAP ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 	if (s & ENSDONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 		seq_puts(m, "ENSDONE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 	if (s & ENSPIORDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 		seq_puts(m, "ENSPIORDY ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	if (s & ENDMADONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 		seq_puts(m, "ENDMADONE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 	s = GETPORT(SIMODE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	if (s & ENSELTIMO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 		seq_puts(m, "ENSELTIMO ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	if (s & ENATNTARG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 		seq_puts(m, "ENATNTARG ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	if (s & ENPHASEMIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 		seq_puts(m, "ENPHASEMIS ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	if (s & ENBUSFREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 		seq_puts(m, "ENBUSFREE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 	if (s & ENSCSIPERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 		seq_puts(m, "ENSCSIPERR ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	if (s & ENPHASECHG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 		seq_puts(m, "ENPHASECHG ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	if (s & ENREQINIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 		seq_puts(m, "ENREQINIT ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	seq_puts(m, ")\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) static int aha152x_set_info(struct Scsi_Host *shpnt, char *buffer, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 	if(!shpnt || !buffer || length<8 || strncmp("aha152x ", buffer, 8)!=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 	if(length>13 && strncmp("reset", buffer+8, 5)==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 		HOSTDATA(shpnt)->total_commands=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 		HOSTDATA(shpnt)->disconnections=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 		HOSTDATA(shpnt)->busfree_without_any_action=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 		HOSTDATA(shpnt)->busfree_without_old_command=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 		HOSTDATA(shpnt)->busfree_without_new_command=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		HOSTDATA(shpnt)->busfree_without_done_command=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 		HOSTDATA(shpnt)->busfree_with_check_condition=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 		for (i = idle; i<maxstate; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 			HOSTDATA(shpnt)->count[i]=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 			HOSTDATA(shpnt)->count_trans[i]=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 			HOSTDATA(shpnt)->time[i]=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 		shost_printk(KERN_INFO, shpnt, "aha152x: stats reset.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) static int aha152x_show_info(struct seq_file *m, struct Scsi_Host *shpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 	struct scsi_cmnd *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	seq_puts(m, AHA152X_REVID "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	seq_printf(m, "ioports 0x%04lx to 0x%04lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		shpnt->io_port, shpnt->io_port + shpnt->n_io_port - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	seq_printf(m, "interrupt 0x%02x\n", shpnt->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	seq_printf(m, "disconnection/reconnection %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 		RECONNECT ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	seq_printf(m, "parity checking %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 		PARITY ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	seq_printf(m, "synchronous transfers %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 		SYNCHRONOUS ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	seq_printf(m, "%d commands currently queued\n", HOSTDATA(shpnt)->commands);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	if(SYNCHRONOUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 		seq_puts(m, "synchronously operating targets (tick=50 ns):\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 		for (i = 0; i < 8; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 			if (HOSTDATA(shpnt)->syncrate[i] & 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 				seq_printf(m, "target %d: period %dT/%dns; req/ack offset %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 					i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 					(((HOSTDATA(shpnt)->syncrate[i] & 0x70) >> 4) + 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 					(((HOSTDATA(shpnt)->syncrate[i] & 0x70) >> 4) + 2) * 50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 				    HOSTDATA(shpnt)->syncrate[i] & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	seq_puts(m, "\nqueue status:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 	DO_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 	if (ISSUE_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 		seq_puts(m, "not yet issued commands:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 		for (ptr = ISSUE_SC; ptr; ptr = SCNEXT(ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 			get_command(m, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 		seq_puts(m, "no not yet issued commands\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	DO_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 	if (CURRENT_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 		seq_puts(m, "current command:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 		get_command(m, CURRENT_SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 		seq_puts(m, "no current command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	if (DISCONNECTED_SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 		seq_puts(m, "disconnected commands:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 		for (ptr = DISCONNECTED_SC; ptr; ptr = SCNEXT(ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 			get_command(m, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 		seq_puts(m, "no disconnected commands\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	get_ports(m, shpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) #if defined(AHA152X_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	seq_printf(m, "statistics:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 		"total commands:               %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 		"disconnections:               %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 		"busfree with check condition: %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 		"busfree without old command:  %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 		"busfree without new command:  %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 		"busfree without done command: %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 		"busfree without any action:   %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 		"state      "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 		"transitions  "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 		"count        "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 		"time\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 		HOSTDATA(shpnt)->total_commands,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		HOSTDATA(shpnt)->disconnections,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 		HOSTDATA(shpnt)->busfree_with_check_condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 		HOSTDATA(shpnt)->busfree_without_old_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 		HOSTDATA(shpnt)->busfree_without_new_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 		HOSTDATA(shpnt)->busfree_without_done_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		HOSTDATA(shpnt)->busfree_without_any_action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	for(i=0; i<maxstate; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 		seq_printf(m, "%-10s %-12d %-12d %-12ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 			states[i].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 			HOSTDATA(shpnt)->count_trans[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 			HOSTDATA(shpnt)->count[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 			HOSTDATA(shpnt)->time[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) static int aha152x_adjust_queue(struct scsi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) static struct scsi_host_template aha152x_driver_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	.module				= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	.name				= AHA152X_REVID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	.proc_name			= "aha152x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 	.show_info			= aha152x_show_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	.write_info			= aha152x_set_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	.queuecommand			= aha152x_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	.eh_abort_handler		= aha152x_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	.eh_device_reset_handler	= aha152x_device_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 	.eh_bus_reset_handler		= aha152x_bus_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	.bios_param			= aha152x_biosparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	.can_queue			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	.this_id			= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 	.sg_tablesize			= SG_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	.dma_boundary			= PAGE_SIZE - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 	.slave_alloc			= aha152x_adjust_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) #if !defined(AHA152X_PCMCIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) static int setup_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) static struct aha152x_setup setup[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) /* possible i/o addresses for the AIC-6260; default first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) static unsigned short ports[] = { 0x340, 0x140 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) #if !defined(SKIP_BIOSTEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) /* possible locations for the Adaptec BIOS; defaults first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) static unsigned int addresses[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	0xdc000,		/* default first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 	0xc8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	0xcc000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 	0xd0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	0xd4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	0xd8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	0xe0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	0xeb800,		/* VTech Platinum SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	0xf0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) /* signatures for various AIC-6[23]60 based controllers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938)    The point in detecting signatures is to avoid useless and maybe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)    harmful probes on ports. I'm not sure that all listed boards pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)    auto-configuration. For those which fail the BIOS signature is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941)    obsolete, because user intervention to supply the configuration is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942)    needed anyway.  May be an information whether or not the BIOS supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)    extended translation could be also useful here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) static struct signature {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 	unsigned char *signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	int sig_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 	int sig_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) } signatures[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 	{ "Adaptec AHA-1520 BIOS",	0x102e, 21 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 		/* Adaptec 152x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	{ "Adaptec AHA-1520B",		0x000b, 17 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 		/* Adaptec 152x rev B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	{ "Adaptec AHA-1520B",		0x0026, 17 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 		/* Iomega Jaz Jet ISA (AIC6370Q) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 	{ "Adaptec ASW-B626 BIOS",	0x1029, 21 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 		/* on-board controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 	{ "Adaptec BIOS: ASW-B626",	0x000f, 22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 		/* on-board controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	{ "Adaptec ASW-B626 S2",	0x2e6c, 19 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 		/* on-board controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	{ "Adaptec BIOS:AIC-6360",	0x000c, 21 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 		/* on-board controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	{ "ScsiPro SP-360 BIOS",	0x2873, 19 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 		/* ScsiPro-Controller  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	{ "GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 		/* Gigabyte Local-Bus-SCSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	{ "Adaptec BIOS:AVA-282X",	0x000c, 21 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 		/* Adaptec 282x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	{ "Adaptec IBM Dock II SCSI",   0x2edd, 24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 		/* IBM Thinkpad Dock II */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 	{ "Adaptec BIOS:AHA-1532P",     0x001c, 22 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 		/* IBM Thinkpad Dock II SCSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 	{ "DTC3520A Host Adapter BIOS", 0x318a, 26 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 		/* DTC 3520A ISA SCSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) #endif /* !SKIP_BIOSTEST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)  * Test, if port_base is valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) static int aha152x_porttest(int io_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	SETPORT(io_port + O_DMACNTRL1, 0);	/* reset stack pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 	for (i = 0; i < 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 		SETPORT(io_port + O_STACK, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	SETPORT(io_port + O_DMACNTRL1, 0);	/* reset stack pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	for (i = 0; i < 16 && GETPORT(io_port + O_STACK) == i; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	return (i == 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) static int tc1550_porttest(int io_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	SETPORT(io_port + O_TC_DMACNTRL1, 0);	/* reset stack pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	for (i = 0; i < 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 		SETPORT(io_port + O_STACK, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	SETPORT(io_port + O_TC_DMACNTRL1, 0);	/* reset stack pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	for (i = 0; i < 16 && GETPORT(io_port + O_TC_STACK) == i; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	return (i == 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) static int checksetup(struct aha152x_setup *setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	for (i = 0; i < ARRAY_SIZE(ports) && (setup->io_port != ports[i]); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 	if (i == ARRAY_SIZE(ports))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	if (!request_region(setup->io_port, IO_RANGE, "aha152x")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 		printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup->io_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	if( aha152x_porttest(setup->io_port) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 		setup->tc1550=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	} else if( tc1550_porttest(setup->io_port) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 		setup->tc1550=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 		release_region(setup->io_port, IO_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 	release_region(setup->io_port, IO_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 	if ((setup->irq < IRQ_MIN) || (setup->irq > IRQ_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 	if ((setup->scsiid < 0) || (setup->scsiid > 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 	if ((setup->reconnect < 0) || (setup->reconnect > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 	if ((setup->parity < 0) || (setup->parity > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 	if ((setup->synchronous < 0) || (setup->synchronous > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 	if ((setup->ext_trans < 0) || (setup->ext_trans > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) static int __init aha152x_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 	int i, j, ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) #if defined(AUTOCONF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 	aha152x_config conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) #ifdef __ISAPNP__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 	struct pnp_dev *dev=NULL, *pnpdev[2] = {NULL, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 	if ( setup_count ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 		printk(KERN_INFO "aha152x: processing commandline: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 		for (i = 0; i<setup_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 			if (!checksetup(&setup[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 				printk(KERN_ERR "\naha152x: %s\n", setup[i].conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 				printk(KERN_ERR "aha152x: invalid line\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 		printk("ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) #if defined(SETUP0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 	if (setup_count < ARRAY_SIZE(setup)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 		struct aha152x_setup override = SETUP0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 		if (setup_count == 0 || (override.io_port != setup[0].io_port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 			if (!checksetup(&override)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 				printk(KERN_ERR "\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 				       override.io_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 				       override.irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 				       override.scsiid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 				       override.reconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 				       override.parity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 				       override.synchronous,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 				       override.delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 				       override.ext_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 				setup[setup_count++] = override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) #if defined(SETUP1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 	if (setup_count < ARRAY_SIZE(setup)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 		struct aha152x_setup override = SETUP1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 		if (setup_count == 0 || (override.io_port != setup[0].io_port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 			if (!checksetup(&override)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 				printk(KERN_ERR "\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 				       override.io_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 				       override.irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 				       override.scsiid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 				       override.reconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 				       override.parity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 				       override.synchronous,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 				       override.delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 				       override.ext_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 				setup[setup_count++] = override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) #if defined(MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	if (setup_count<ARRAY_SIZE(setup) && (aha152x[0]!=0 || io[0]!=0 || irq[0]!=0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 		if(aha152x[0]!=0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 			setup[setup_count].conf        = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 			setup[setup_count].io_port     = aha152x[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 			setup[setup_count].irq         = aha152x[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 			setup[setup_count].scsiid      = aha152x[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 			setup[setup_count].reconnect   = aha152x[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 			setup[setup_count].parity      = aha152x[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 			setup[setup_count].synchronous = aha152x[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 			setup[setup_count].delay       = aha152x[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 			setup[setup_count].ext_trans   = aha152x[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 		} else if (io[0] != 0 || irq[0] != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 			if(io[0]!=0)  setup[setup_count].io_port = io[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 			if(irq[0]!=0) setup[setup_count].irq     = irq[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 			setup[setup_count].scsiid      = scsiid[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 			setup[setup_count].reconnect   = reconnect[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 			setup[setup_count].parity      = parity[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 			setup[setup_count].synchronous = sync[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 			setup[setup_count].delay       = delay[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 			setup[setup_count].ext_trans   = exttrans[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 		if (checksetup(&setup[setup_count]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 			setup_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 			printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 			       setup[setup_count].io_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 			       setup[setup_count].irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 			       setup[setup_count].scsiid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 			       setup[setup_count].reconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 			       setup[setup_count].parity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 			       setup[setup_count].synchronous,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 			       setup[setup_count].delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 			       setup[setup_count].ext_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 	if (setup_count<ARRAY_SIZE(setup) && (aha152x1[0]!=0 || io[1]!=0 || irq[1]!=0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 		if(aha152x1[0]!=0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 			setup[setup_count].conf        = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 			setup[setup_count].io_port     = aha152x1[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 			setup[setup_count].irq         = aha152x1[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 			setup[setup_count].scsiid      = aha152x1[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 			setup[setup_count].reconnect   = aha152x1[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 			setup[setup_count].parity      = aha152x1[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 			setup[setup_count].synchronous = aha152x1[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 			setup[setup_count].delay       = aha152x1[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 			setup[setup_count].ext_trans   = aha152x1[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 		} else if (io[1] != 0 || irq[1] != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 			if(io[1]!=0)  setup[setup_count].io_port = io[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 			if(irq[1]!=0) setup[setup_count].irq     = irq[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 			setup[setup_count].scsiid      = scsiid[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 			setup[setup_count].reconnect   = reconnect[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 			setup[setup_count].parity      = parity[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 			setup[setup_count].synchronous = sync[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 			setup[setup_count].delay       = delay[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 			setup[setup_count].ext_trans   = exttrans[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 		if (checksetup(&setup[setup_count]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 			setup_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 			printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 			       setup[setup_count].io_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 			       setup[setup_count].irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 			       setup[setup_count].scsiid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 			       setup[setup_count].reconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 			       setup[setup_count].parity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 			       setup[setup_count].synchronous,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 			       setup[setup_count].delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 			       setup[setup_count].ext_trans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) #ifdef __ISAPNP__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 	for(i=0; setup_count<ARRAY_SIZE(setup) && id_table[i].vendor; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 		while ( setup_count<ARRAY_SIZE(setup) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 			(dev=pnp_find_dev(NULL, id_table[i].vendor, id_table[i].function, dev)) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 			if (pnp_device_attach(dev) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 			if (pnp_activate_dev(dev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 				pnp_device_detach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 			if (!pnp_port_valid(dev, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 				pnp_device_detach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 			if (setup_count==1 && pnp_port_start(dev, 0)==setup[0].io_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 				pnp_device_detach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 			setup[setup_count].io_port     = pnp_port_start(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 			setup[setup_count].irq         = pnp_irq(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 			setup[setup_count].scsiid      = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 			setup[setup_count].reconnect   = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 			setup[setup_count].parity      = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 			setup[setup_count].synchronous = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 			setup[setup_count].delay       = DELAY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 			setup[setup_count].ext_trans   = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) #if defined(__ISAPNP__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 			pnpdev[setup_count]            = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 			printk (KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 				"aha152x: found ISAPnP adapter at io=0x%03x, irq=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 				setup[setup_count].io_port, setup[setup_count].irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 			setup_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) #if defined(AUTOCONF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	if (setup_count<ARRAY_SIZE(setup)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) #if !defined(SKIP_BIOSTEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 		ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 		for (i = 0; i < ARRAY_SIZE(addresses) && !ok; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 			void __iomem *p = ioremap(addresses[i], 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 			if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 			for (j = 0; j<ARRAY_SIZE(signatures) && !ok; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 				ok = check_signature(p + signatures[j].sig_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 								signatures[j].signature, signatures[j].sig_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 			iounmap(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 		if (!ok && setup_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 		printk(KERN_INFO "aha152x: BIOS test: passed, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 		printk(KERN_INFO "aha152x: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) #endif				/* !SKIP_BIOSTEST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 		ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 		for (i = 0; i < ARRAY_SIZE(ports) && setup_count < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 			if ((setup_count == 1) && (setup[0].io_port == ports[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 			if (!request_region(ports[i], IO_RANGE, "aha152x")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 				printk(KERN_ERR "aha152x: io port 0x%x busy.\n", ports[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 			if (aha152x_porttest(ports[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 				setup[setup_count].tc1550  = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 				conf.cf_port =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 				    (GETPORT(ports[i] + O_PORTA) << 8) + GETPORT(ports[i] + O_PORTB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 			} else if (tc1550_porttest(ports[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 				setup[setup_count].tc1550  = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 				conf.cf_port =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 				    (GETPORT(ports[i] + O_TC_PORTA) << 8) + GETPORT(ports[i] + O_TC_PORTB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 				release_region(ports[i], IO_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 			release_region(ports[i], IO_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 			ok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 			setup[setup_count].io_port = ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 			setup[setup_count].irq = IRQ_MIN + conf.cf_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 			setup[setup_count].scsiid = conf.cf_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 			setup[setup_count].reconnect = conf.cf_tardisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 			setup[setup_count].parity = !conf.cf_parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 			setup[setup_count].synchronous = conf.cf_syncneg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 			setup[setup_count].delay = DELAY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 			setup[setup_count].ext_trans = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 			setup_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 		if (ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 			printk("auto configuration: ok, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 	printk("%d controller(s) configured\n", setup_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 	for (i=0; i<setup_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 		if ( request_region(setup[i].io_port, IO_RANGE, "aha152x") ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 			struct Scsi_Host *shpnt = aha152x_probe_one(&setup[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 			if( !shpnt ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 				release_region(setup[i].io_port, IO_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) #if defined(__ISAPNP__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 			} else if( pnpdev[i] ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 				HOSTDATA(shpnt)->pnpdev=pnpdev[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 				pnpdev[i]=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 			printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup[i].io_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) #if defined(__ISAPNP__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 		if( pnpdev[i] )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 			pnp_device_detach(pnpdev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) static void __exit aha152x_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 	struct aha152x_hostdata *hd, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 	list_for_each_entry_safe(hd, tmp, &aha152x_host_list, host_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 		struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 		aha152x_release(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) module_init(aha152x_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) module_exit(aha152x_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) #if !defined(MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) static int __init aha152x_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	int ints[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	get_options(str, ARRAY_SIZE(ints), ints);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 	if(setup_count>=ARRAY_SIZE(setup)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 		printk(KERN_ERR "aha152x: you can only configure up to two controllers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	setup[setup_count].conf        = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 	setup[setup_count].io_port     = ints[0] >= 1 ? ints[1] : 0x340;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 	setup[setup_count].irq         = ints[0] >= 2 ? ints[2] : 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 	setup[setup_count].scsiid      = ints[0] >= 3 ? ints[3] : 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	setup[setup_count].reconnect   = ints[0] >= 4 ? ints[4] : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 	setup[setup_count].parity      = ints[0] >= 5 ? ints[5] : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	setup[setup_count].delay       = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	setup[setup_count].ext_trans   = ints[0] >= 8 ? ints[8] : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 	if (ints[0] > 8) {                                                /*}*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 		printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 		       "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 		setup_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) __setup("aha152x=", aha152x_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) #endif /* !AHA152X_PCMCIA */