[PATCH 5/6] scsi: remove stale BusLogic driver

Arnd Bergmann
2022-06-06T08:41:59Z

From: Arnd Bergmann <arnd@arndb.de>

The BusLogic driver is the last remaining driver that relies on the
deprecated bus_to_virt() function, which in turn only works on a few
architectures, and is incompatible with both swiotlb and iommu support.

Before commit 391e2f25601e ("[SCSI] BusLogic: Port driver to 64-bit."),
the driver had a dependency on x86-32, presumably because of this
problem. However, the change introduced another bug that made it still
impossible to use the driver on any 64-bit machine.

This was in turn fixed in commit 56f396146af2 ("scsi: BusLogic: Fix
64-bit system enumeration error for Buslogic"), 8 years later.

The fact that this was found at all is an indication that there are
users, and it seems that Maciej, Matt and Khalid all have access to
this hardware, but if it took eight years to find the problem,
it's likely that nobody actually relies on it.

Remove it as part of the global virt_to_bus()/bus_to_virt() removal.
If anyone is still interested in keeping this driver, the alternative
is to stop it from using bus_to_virt(), possibly along the lines of
how dpt_i2o gets around the same issue.

Cc: Maciej W. Rozycki <macro@orcam.me.uk>
Cc: Matt Wang <wwentao@vmware.com>
Cc: Khalid Aziz <khalid@gonehiking.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
Documentation/scsi/BusLogic.rst | 581 ---
Documentation/scsi/FlashPoint.rst | 176 -
MAINTAINERS | 7 -
drivers/scsi/BusLogic.c | 3727 --------------
drivers/scsi/BusLogic.h | 1284 -----
drivers/scsi/FlashPoint.c | 7560 -----------------------------
drivers/scsi/Kconfig | 24 -
7 files changed, 13359 deletions(-)
delete mode 100644 Documentation/scsi/BusLogic.rst
delete mode 100644 Documentation/scsi/FlashPoint.rst
delete mode 100644 drivers/scsi/BusLogic.c
delete mode 100644 drivers/scsi/BusLogic.h
delete mode 100644 drivers/scsi/FlashPoint.c

diff --git a/Documentation/scsi/BusLogic.rst b/Documentation/scsi/BusLogic.rst
deleted file mode 100644
index d7d4d56981ca..000000000000
--- a/Documentation/scsi/BusLogic.rst
+++ /dev/null
@@ -1,581 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=========================================================
-BusLogic MultiMaster and FlashPoint SCSI Driver for Linux
-=========================================================
-
- Version 2.0.15 for Linux 2.0
-
- Version 2.1.15 for Linux 2.1
-
- PRODUCTION RELEASE
-
- 17 August 1998
-
- Leonard N. Zubkoff
-
- Dandelion Digital
-
- lnz@dandelion.com
-
- Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
-
-
-Introduction
-============
-
-BusLogic, Inc. designed and manufactured a variety of high performance SCSI
-host adapters which share a common programming interface across a diverse
-collection of bus architectures by virtue of their MultiMaster ASIC technology.
-BusLogic was acquired by Mylex Corporation in February 1996, but the products
-supported by this driver originated under the BusLogic name and so that name is
-retained in the source code and documentation.
-
-This driver supports all present BusLogic MultiMaster Host Adapters, and should
-support any future MultiMaster designs with little or no modification. More
-recently, BusLogic introduced the FlashPoint Host Adapters, which are less
-costly and rely on the host CPU, rather than including an onboard processor.
-Despite not having an onboard CPU, the FlashPoint Host Adapters perform very
-well and have very low command latency. BusLogic has recently provided me with
-the FlashPoint Driver Developer's Kit, which comprises documentation and freely
-redistributable source code for the FlashPoint SCCB Manager. The SCCB Manager
-is the library of code that runs on the host CPU and performs functions
-analogous to the firmware on the MultiMaster Host Adapters. Thanks to their
-having provided the SCCB Manager, this driver now supports the FlashPoint Host
-Adapters as well.
-
-My primary goals in writing this completely new BusLogic driver for Linux are
-to achieve the full performance that BusLogic SCSI Host Adapters and modern
-SCSI peripherals are capable of, and to provide a highly robust driver that can
-be depended upon for high performance mission critical applications. All of
-the major performance features can be configured from the Linux kernel command
-line or at module initialization time, allowing individual installations to
-tune driver performance and error recovery to their particular needs.
-
-The latest information on Linux support for BusLogic SCSI Host Adapters, as
-well as the most recent release of this driver and the latest firmware for the
-BT-948/958/958D, will always be available from my Linux Home Page at URL
-"http://sourceforge.net/projects/dandelion/".
-
-Bug reports should be sent via electronic mail to "lnz@dandelion.com". Please
-include with the bug report the complete configuration messages reported by the
-driver and SCSI subsystem at startup, along with any subsequent system messages
-relevant to SCSI operations, and a detailed description of your system's
-hardware configuration.
-
-Mylex has been an excellent company to work with and I highly recommend their
-products to the Linux community. In November 1995, I was offered the
-opportunity to become a beta test site for their latest MultiMaster product,
-the BT-948 PCI Ultra SCSI Host Adapter, and then again for the BT-958 PCI Wide
-Ultra SCSI Host Adapter in January 1996. This was mutually beneficial since
-Mylex received a degree and kind of testing that their own testing group cannot
-readily achieve, and the Linux community has available high performance host
-adapters that have been well tested with Linux even before being brought to
-market. This relationship has also given me the opportunity to interact
-directly with their technical staff, to understand more about the internal
-workings of their products, and in turn to educate them about the needs and
-potential of the Linux community.
-
-More recently, Mylex has reaffirmed the company's interest in supporting the
-Linux community, and I am now working on a Linux driver for the DAC960 PCI RAID
-Controllers. Mylex's interest and support is greatly appreciated.
-
-Unlike some other vendors, if you contact Mylex Technical Support with a
-problem and are running Linux, they will not tell you that your use of their
-products is unsupported. Their latest product marketing literature even states
-"Mylex SCSI host adapters are compatible with all major operating systems
-including: ... Linux ...".
-
-Mylex Corporation is located at 34551 Ardenwood Blvd., Fremont, California
-94555, USA and can be reached at 510/796-6100 or on the World Wide Web at
-http://www.mylex.com. Mylex HBA Technical Support can be reached by electronic
-mail at techsup@mylex.com, by Voice at 510/608-2400, or by FAX at 510/745-7715.
-Contact information for offices in Europe and Japan is available on the Web
-site.
-
-
-Driver Features
-===============
-
-Configuration Reporting and Testing
------------------------------------
-
- During system initialization, the driver reports extensively on the host
- adapter hardware configuration, including the synchronous transfer parameters
- requested and negotiated with each target device. AutoSCSI settings for
- Synchronous Negotiation, Wide Negotiation, and Disconnect/Reconnect are
- reported for each target device, as well as the status of Tagged Queuing.
- If the same setting is in effect for all target devices, then a single word
- or phrase is used; otherwise, a letter is provided for each target device to
- indicate the individual status. The following examples
- should clarify this reporting format:
-
- Synchronous Negotiation: Ultra
-
- Synchronous negotiation is enabled for all target devices and the host
- adapter will attempt to negotiate for 20.0 mega-transfers/second.
-
- Synchronous Negotiation: Fast
-
- Synchronous negotiation is enabled for all target devices and the host
- adapter will attempt to negotiate for 10.0 mega-transfers/second.
-
- Synchronous Negotiation: Slow
-
- Synchronous negotiation is enabled for all target devices and the host
- adapter will attempt to negotiate for 5.0 mega-transfers/second.
-
- Synchronous Negotiation: Disabled
-
- Synchronous negotiation is disabled and all target devices are limited to
- asynchronous operation.
-
- Synchronous Negotiation: UFSNUUU#UUUUUUUU
-
- Synchronous negotiation to Ultra speed is enabled for target devices 0
- and 4 through 15, to Fast speed for target device 1, to Slow speed for
- target device 2, and is not permitted to target device 3. The host
- adapter's SCSI ID is represented by the "#".
-
- The status of Wide Negotiation, Disconnect/Reconnect, and Tagged Queuing
- are reported as "Enabled", Disabled", or a sequence of "Y" and "N" letters.
-
-Performance Features
---------------------
-
- BusLogic SCSI Host Adapters directly implement SCSI-2 Tagged Queuing, and so
- support has been included in the driver to utilize tagged queuing with any
- target devices that report having the tagged queuing capability. Tagged
- queuing allows for multiple outstanding commands to be issued to each target
- device or logical unit, and can improve I/O performance substantially. In
- addition, BusLogic's Strict Round Robin Mode is used to optimize host adapter
- performance, and scatter/gather I/O can support as many segments as can be
- effectively utilized by the Linux I/O subsystem. Control over the use of
- tagged queuing for each target device as well as individual selection of the
- tagged queue depth is available through driver options provided on the kernel
- command line or at module initialization time. By default, the queue depth
- is determined automatically based on the host adapter's total queue depth and
- the number, type, speed, and capabilities of the target devices found. In
- addition, tagged queuing is automatically disabled whenever the host adapter
- firmware version is known not to implement it correctly, or whenever a tagged
- queue depth of 1 is selected. Tagged queuing is also disabled for individual
- target devices if disconnect/reconnect is disabled for that device.
-
-Robustness Features
--------------------
-
- The driver implements extensive error recovery procedures. When the higher
- level parts of the SCSI subsystem request that a timed out command be reset,
- a selection is made between a full host adapter hard reset and SCSI bus reset
- versus sending a bus device reset message to the individual target device
- based on the recommendation of the SCSI subsystem. Error recovery strategies
- are selectable through driver options individually for each target device,
- and also include sending a bus device reset to the specific target device
- associated with the command being reset, as well as suppressing error
- recovery entirely to avoid perturbing an improperly functioning device. If
- the bus device reset error recovery strategy is selected and sending a bus
- device reset does not restore correct operation, the next command that is
- reset will force a full host adapter hard reset and SCSI bus reset. SCSI bus
- resets caused by other devices and detected by the host adapter are also
- handled by issuing a soft reset to the host adapter and re-initialization.
- Finally, if tagged queuing is active and more than one command reset occurs
- in a 10 minute interval, or if a command reset occurs within the first 10
- minutes of operation, then tagged queuing will be disabled for that target
- device. These error recovery options improve overall system robustness by
- preventing individual errant devices from causing the system as a whole to
- lock up or crash, and thereby allowing a clean shutdown and restart after the
- offending component is removed.
-
-PCI Configuration Support
--------------------------
-
- On PCI systems running kernels compiled with PCI BIOS support enabled, this
- driver will interrogate the PCI configuration space and use the I/O port
- addresses assigned by the system BIOS, rather than the ISA compatible I/O
- port addresses. The ISA compatible I/O port address is then disabled by the
- driver. On PCI systems it is also recommended that the AutoSCSI utility be
- used to disable the ISA compatible I/O port entirely as it is not necessary.
- The ISA compatible I/O port is disabled by default on the BT-948/958/958D.
-
-/proc File System Support
--------------------------
-
- Copies of the host adapter configuration information together with updated
- data transfer and error recovery statistics are available through the
- /proc/scsi/BusLogic/<N> interface.
-
-Shared Interrupts Support
--------------------------
-
- On systems that support shared interrupts, any number of BusLogic Host
- Adapters may share the same interrupt request channel.
-
-
-Supported Host Adapters
-=======================
-
-The following list comprises the supported BusLogic SCSI Host Adapters as of
-the date of this document. It is recommended that anyone purchasing a BusLogic
-Host Adapter not in the following table contact the author beforehand to verify
-that it is or will be supported.
-
-FlashPoint Series PCI Host Adapters:
-
-======================= =============================================
-FlashPoint LT (BT-930) Ultra SCSI-3
-FlashPoint LT (BT-930R) Ultra SCSI-3 with RAIDPlus
-FlashPoint LT (BT-920) Ultra SCSI-3 (BT-930 without BIOS)
-FlashPoint DL (BT-932) Dual Channel Ultra SCSI-3
-FlashPoint DL (BT-932R) Dual Channel Ultra SCSI-3 with RAIDPlus
-FlashPoint LW (BT-950) Wide Ultra SCSI-3
-FlashPoint LW (BT-950R) Wide Ultra SCSI-3 with RAIDPlus
-FlashPoint DW (BT-952) Dual Channel Wide Ultra SCSI-3
-FlashPoint DW (BT-952R) Dual Channel Wide Ultra SCSI-3 with RAIDPlus
-======================= =============================================
-
-MultiMaster "W" Series Host Adapters:
-
-======= === ==============================
-BT-948 PCI Ultra SCSI-3
-BT-958 PCI Wide Ultra SCSI-3
-BT-958D PCI Wide Differential Ultra SCSI-3
-======= === ==============================
-
-MultiMaster "C" Series Host Adapters:
-
-======== ==== ==============================
-BT-946C PCI Fast SCSI-2
-BT-956C PCI Wide Fast SCSI-2
-BT-956CD PCI Wide Differential Fast SCSI-2
-BT-445C VLB Fast SCSI-2
-BT-747C EISA Fast SCSI-2
-BT-757C EISA Wide Fast SCSI-2
-BT-757CD EISA Wide Differential Fast SCSI-2
-======== ==== ==============================
-
-MultiMaster "S" Series Host Adapters:
-
-======= ==== ==============================
-BT-445S VLB Fast SCSI-2
-BT-747S EISA Fast SCSI-2
-BT-747D EISA Differential Fast SCSI-2
-BT-757S EISA Wide Fast SCSI-2
-BT-757D EISA Wide Differential Fast SCSI-2
-BT-742A EISA SCSI-2 (742A revision H)
-======= ==== ==============================
-
-MultiMaster "A" Series Host Adapters:
-
-======= ==== ==============================
-BT-742A EISA SCSI-2 (742A revisions A - G)
-======= ==== ==============================
-
-AMI FastDisk Host Adapters that are true BusLogic MultiMaster clones are also
-supported by this driver.
-
-BusLogic SCSI Host Adapters are available packaged both as bare boards and as
-retail kits. The BT- model numbers above refer to the bare board packaging.
-The retail kit model numbers are found by replacing BT- with KT- in the above
-list. The retail kit includes the bare board and manual as well as cabling and
-driver media and documentation that are not provided with bare boards.
-
-
-FlashPoint Installation Notes
-=============================
-
-RAIDPlus Support
-----------------
-
- FlashPoint Host Adapters now include RAIDPlus, Mylex's bootable software
- RAID. RAIDPlus is not supported on Linux, and there are no plans to support
- it. The MD driver in Linux 2.0 provides for concatenation (LINEAR) and
- striping (RAID-0), and support for mirroring (RAID-1), fixed parity (RAID-4),
- and distributed parity (RAID-5) is available separately. The built-in Linux
- RAID support is generally more flexible and is expected to perform better
- than RAIDPlus, so there is little impetus to include RAIDPlus support in the
- BusLogic driver.
-
-Enabling UltraSCSI Transfers
-----------------------------
-
- FlashPoint Host Adapters ship with their configuration set to "Factory
- Default" settings that are conservative and do not allow for UltraSCSI speed
- to be negotiated. This results in fewer problems when these host adapters
- are installed in systems with cabling or termination that is not sufficient
- for UltraSCSI operation, or where existing SCSI devices do not properly
- respond to synchronous transfer negotiation for UltraSCSI speed. AutoSCSI
- may be used to load "Optimum Performance" settings which allow UltraSCSI
- speed to be negotiated with all devices, or UltraSCSI speed can be enabled on
- an individual basis. It is recommended that SCAM be manually disabled after
- the "Optimum Performance" settings are loaded.
-
-
-BT-948/958/958D Installation Notes
-==================================
-
-The BT-948/958/958D PCI Ultra SCSI Host Adapters have some features which may
-require attention in some circumstances when installing Linux.
-
-PCI I/O Port Assignments
-------------------------
-
- When configured to factory default settings, the BT-948/958/958D will only
- recognize the PCI I/O port assignments made by the motherboard's PCI BIOS.
- The BT-948/958/958D will not respond to any of the ISA compatible I/O ports
- that previous BusLogic SCSI Host Adapters respond to. This driver supports
- the PCI I/O port assignments, so this is the preferred configuration.
- However, if the obsolete BusLogic driver must be used for any reason, such as
- a Linux distribution that does not yet use this driver in its boot kernel,
- BusLogic has provided an AutoSCSI configuration option to enable a legacy ISA
- compatible I/O port.
-
- To enable this backward compatibility option, invoke the AutoSCSI utility via
- Ctrl-B at system startup and select "Adapter Configuration", "View/Modify
- Configuration", and then change the "ISA Compatible Port" setting from
- "Disable" to "Primary" or "Alternate". Once this driver has been installed,
- the "ISA Compatible Port" option should be set back to "Disable" to avoid
- possible future I/O port conflicts. The older BT-946C/956C/956CD also have
- this configuration option, but the factory default setting is "Primary".
-
-PCI Slot Scanning Order
------------------------
-
- In systems with multiple BusLogic PCI Host Adapters, the order in which the
- PCI slots are scanned may appear reversed with the BT-948/958/958D as
- compared to the BT-946C/956C/956CD. For booting from a SCSI disk to work
- correctly, it is necessary that the host adapter's BIOS and the kernel agree
- on which disk is the boot device, which requires that they recognize the PCI
- host adapters in the same order. The motherboard's PCI BIOS provides a
- standard way of enumerating the PCI host adapters, which is used by the Linux
- kernel. Some PCI BIOS implementations enumerate the PCI slots in order of
- increasing bus number and device number, while others do so in the opposite
- direction.
-
- Unfortunately, Microsoft decided that Windows 95 would always enumerate the
- PCI slots in order of increasing bus number and device number regardless of
- the PCI BIOS enumeration, and requires that their scheme be supported by the
- host adapter's BIOS to receive Windows 95 certification. Therefore, the
- factory default settings of the BT-948/958/958D enumerate the host adapters
- by increasing bus number and device number. To disable this feature, invoke
- the AutoSCSI utility via Ctrl-B at system startup and select "Adapter
- Configuration", "View/Modify Configuration", press Ctrl-F10, and then change
- the "Use Bus And Device # For PCI Scanning Seq." option to OFF.
-
- This driver will interrogate the setting of the PCI Scanning Sequence option
- so as to recognize the host adapters in the same order as they are enumerated
- by the host adapter's BIOS.
-
-Enabling UltraSCSI Transfers
-----------------------------
-
- The BT-948/958/958D ship with their configuration set to "Factory Default"
- settings that are conservative and do not allow for UltraSCSI speed to be
- negotiated. This results in fewer problems when these host adapters are
- installed in systems with cabling or termination that is not sufficient for
- UltraSCSI operation, or where existing SCSI devices do not properly respond
- to synchronous transfer negotiation for UltraSCSI speed. AutoSCSI may be
- used to load "Optimum Performance" settings which allow UltraSCSI speed to be
- negotiated with all devices, or UltraSCSI speed can be enabled on an
- individual basis. It is recommended that SCAM be manually disabled after the
- "Optimum Performance" settings are loaded.
-
-
-Driver Options
-==============
-
-BusLogic Driver Options may be specified either via the Linux Kernel Command
-Line or via the Loadable Kernel Module Installation Facility. Driver Options
-for multiple host adapters may be specified either by separating the option
-strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
-command line. Individual option specifications for a single host adapter are
-separated by commas. The Probing and Debugging Options apply to all host
-adapters whereas the remaining options apply individually only to the
-selected host adapter.
-
-The BusLogic Driver Probing Options comprise the following:
-
-NoProbe
-
- The "NoProbe" option disables all probing and therefore no BusLogic Host
- Adapters will be detected.
-
-NoProbePCI
-
- The "NoProbePCI" options disables the interrogation of PCI Configuration
- Space and therefore only ISA Multimaster Host Adapters will be detected, as
- well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
- Port set to "Primary" or "Alternate".
-
-NoSortPCI
-
- The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
- enumerated in the order provided by the PCI BIOS, ignoring any setting of
- the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
-
-MultiMasterFirst
-
- The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
- before FlashPoint Host Adapters. By default, if both FlashPoint and PCI
- MultiMaster Host Adapters are present, this driver will probe for
- FlashPoint Host Adapters first unless the BIOS primary disk is controlled
- by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host
- Adapters will be probed first.
-
-FlashPointFirst
-
- The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
- before MultiMaster Host Adapters.
-
-The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
-the Queue Depth and whether Tagged Queuing is permitted for each Target
-Device (assuming that the Target Device supports Tagged Queuing). The Queue
-Depth is the number of SCSI Commands that are allowed to be concurrently
-presented for execution (either to the Host Adapter or Target Device). Note
-that explicitly enabling Tagged Queuing may lead to problems; the option to
-enable or disable Tagged Queuing is provided primarily to allow disabling
-Tagged Queuing on Target Devices that do not implement it correctly. The
-following options are available:
-
-QueueDepth:<integer>
-
- The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
- Target Devices that support Tagged Queuing, as well as the maximum Queue
- Depth for devices that do not support Tagged Queuing. If no Queue Depth
- option is provided, the Queue Depth will be determined automatically based
- on the Host Adapter's Total Queue Depth and the number, type, speed, and
- capabilities of the detected Target Devices. Target Devices that
- do not support Tagged Queuing always have their Queue Depth set to
- BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
- lower Queue Depth option is provided. A Queue Depth of 1 automatically
- disables Tagged Queuing.
-
-QueueDepth:[<integer>,<integer>...]
-
- The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
- individually for each Target Device. If an <integer> is omitted, the
- associated Target Device will have its Queue Depth selected automatically.
-
-TaggedQueuing:Default
-
- The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
- based on the firmware version of the BusLogic Host Adapter and based on
- whether the Queue Depth allows queuing multiple commands.
-
-TaggedQueuing:Enable
-
- The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
- all Target Devices on this Host Adapter, overriding any limitation that
- would otherwise be imposed based on the Host Adapter firmware version.
-
-TaggedQueuing:Disable
-
- The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
- for all Target Devices on this Host Adapter.
-
-TaggedQueuing:<Target-Spec>
-
- The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
- Tagged Queuing individually for each Target Device. <Target-Spec> is a
- sequence of "Y", "N", and "X" characters. "Y" enables Tagged Queuing, "N"
- disables Tagged Queuing, and "X" accepts the default based on the firmware
- version. The first character refers to Target Device 0, the second to
- Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
- does not cover all the Target Devices, unspecified characters are assumed
- to be "X".
-
-The BusLogic Driver Miscellaneous Options comprise the following:
-
-BusSettleTime:<seconds>
-
- The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
- seconds. The Bus Settle Time is the amount of time to wait between a Host
- Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
- Commands. If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
-
-InhibitTargetInquiry
-
- The "InhibitTargetInquiry" option inhibits the execution of an Inquire
- Target Devices or Inquire Installed Devices command on MultiMaster Host
- Adapters. This may be necessary with some older Target Devices that do not
- respond correctly when Logical Units above 0 are addressed.
-
-The BusLogic Driver Debugging Options comprise the following:
-
-TraceProbe
-
- The "TraceProbe" option enables tracing of Host Adapter Probing.
-
-TraceHardwareReset
-
- The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
- Reset.
-
-TraceConfiguration
-
- The "TraceConfiguration" option enables tracing of Host Adapter
- Configuration.
-
-TraceErrors
-
- The "TraceErrors" option enables tracing of SCSI Commands that return an
- error from the Target Device. The CDB and Sense Data will be printed for
- each SCSI Command that fails.
-
-Debug
-
- The "Debug" option enables all debugging options.
-
-The following examples demonstrate setting the Queue Depth for Target Devices
-1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
-Devices on the second host adapter to 31, and the Bus Settle Time on the
-second host adapter to 30 seconds.
-
-Linux Kernel Command Line::
-
- linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
-
-LILO Linux Boot Loader (in /etc/lilo.conf)::
-
- append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
-
-INSMOD Loadable Kernel Module Installation Facility::
-
- insmod BusLogic.o \
- 'BusLogic="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
-
-
-.. Note::
-
- Module Utilities 2.1.71 or later is required for correct parsing
- of driver options containing commas.
-
-
-Driver Installation
-===================
-
-This distribution was prepared for Linux kernel version 2.0.35, but should be
-compatible with 2.0.4 or any later 2.0 series kernel.
-
-To install the new BusLogic SCSI driver, you may use the following commands,
-replacing "/usr/src" with wherever you keep your Linux kernel source tree::
-
- cd /usr/src
- tar -xvzf BusLogic-2.0.15.tar.gz
- mv README.* LICENSE.* BusLogic.[ch] FlashPoint.c linux/drivers/scsi
- patch -p0 < BusLogic.patch (only for 2.0.33 and below)
- cd linux
- make config
- make zImage
-
-Then install "arch/x86/boot/zImage" as your standard kernel, run lilo if
-appropriate, and reboot.
-
-
-BusLogic Announcements Mailing List
-===================================
-
-The BusLogic Announcements Mailing List provides a forum for informing Linux
-users of new driver releases and other announcements regarding Linux support
-for BusLogic SCSI Host Adapters. To join the mailing list, send a message to
-"buslogic-announce-request@dandelion.com" with the line "subscribe" in the
-message body.
diff --git a/Documentation/scsi/FlashPoint.rst b/Documentation/scsi/FlashPoint.rst
deleted file mode 100644
index ef3c07e94ad6..000000000000
--- a/Documentation/scsi/FlashPoint.rst
+++ /dev/null
@@ -1,176 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===================================
-The BusLogic FlashPoint SCSI Driver
-===================================
-
-The BusLogic FlashPoint SCSI Host Adapters are now fully supported on Linux.
-The upgrade program described below has been officially terminated effective
-31 March 1997 since it is no longer needed.
-
-::
-
- MYLEX INTRODUCES LINUX OPERATING SYSTEM SUPPORT FOR ITS
- BUSLOGIC FLASHPOINT LINE OF SCSI HOST ADAPTERS
-
-
- FREMONT, CA, -- October 8, 1996 -- Mylex Corporation has expanded Linux
- operating system support to its BusLogic brand of FlashPoint Ultra SCSI
- host adapters. All of BusLogic's other SCSI host adapters, including the
- MultiMaster line, currently support the Linux operating system. Linux
- drivers and information will be available on October 15th at
- http://sourceforge.net/projects/dandelion/.
-
- "Mylex is committed to supporting the Linux community," says Peter Shambora,
- vice president of marketing for Mylex. "We have supported Linux driver
- development and provided technical support for our host adapters for several
- years, and are pleased to now make our FlashPoint products available to this
- user base."
-
-The Linux Operating System
-==========================
-
-Linux is a freely-distributed implementation of UNIX for Intel x86, Sun
-SPARC, SGI MIPS, Motorola 68k, Digital Alpha AXP and Motorola PowerPC
-machines. It supports a wide range of software, including the X Window
-System, Emacs, and TCP/IP networking. Further information is available at
-http://www.linux.org and http://www.ssc.com/.
-
-FlashPoint Host Adapters
-========================
-
-The FlashPoint family of Ultra SCSI host adapters, designed for workstation
-and file server environments, are available in narrow, wide, dual channel,
-and dual channel wide versions. These adapters feature SeqEngine
-automation technology, which minimizes SCSI command overhead and reduces
-the number of interrupts generated to the CPU.
-
-About Mylex
-===========
-
-Mylex Corporation (NASDAQ/NM SYMBOL: MYLX), founded in 1983, is a leading
-producer of RAID technology and network management products. The company
-produces high performance disk array (RAID) controllers, and complementary
-computer products for network servers, mass storage systems, workstations
-and system boards. Through its wide range of RAID controllers and its
-BusLogic line of Ultra SCSI host adapter products, Mylex provides enabling
-intelligent I/O technologies that increase network management control,
-enhance CPU utilization, optimize I/O performance, and ensure data security
-and availability. Products are sold globally through a network of OEMs,
-major distributors, VARs, and system integrators. Mylex Corporation is
-headquartered at 34551 Ardenwood Blvd., Fremont, CA.
-
-Contact:
-========
-
-::
-
- Peter Shambora
- Vice President of Marketing
- Mylex Corp.
- 510/796-6100
- peters@mylex.com
-
-
-::
-
- ANNOUNCEMENT
- BusLogic FlashPoint LT/BT-948 Upgrade Program
- 1 February 1996
-
- ADDITIONAL ANNOUNCEMENT
- BusLogic FlashPoint LW/BT-958 Upgrade Program
- 14 June 1996
-
- Ever since its introduction last October, the BusLogic FlashPoint LT has
- been problematic for members of the Linux community, in that no Linux
- drivers have been available for this new Ultra SCSI product. Despite its
- officially being positioned as a desktop workstation product, and not being
- particularly well suited for a high performance multitasking operating
- system like Linux, the FlashPoint LT has been touted by computer system
- vendors as the latest thing, and has been sold even on many of their high
- end systems, to the exclusion of the older MultiMaster products. This has
- caused grief for many people who inadvertently purchased a system expecting
- that all BusLogic SCSI Host Adapters were supported by Linux, only to
- discover that the FlashPoint was not supported and would not be for quite
- some time, if ever.
-
- After this problem was identified, BusLogic contacted its major OEM
- customers to make sure the BT-946C/956C MultiMaster cards would still be
- made available, and that Linux users who mistakenly ordered systems with
- the FlashPoint would be able to upgrade to the BT-946C. While this helped
- many purchasers of new systems, it was only a partial solution to the
- overall problem of FlashPoint support for Linux users. It did nothing to
- assist the people who initially purchased a FlashPoint for a supported
- operating system and then later decided to run Linux, or those who had
- ended up with a FlashPoint LT, believing it was supported, and were unable
- to return it.
-
- In the middle of December, I asked to meet with BusLogic's senior
- management to discuss the issues related to Linux and free software support
- for the FlashPoint. Rumors of varying accuracy had been circulating
- publicly about BusLogic's attitude toward the Linux community, and I felt
- it was best that these issues be addressed directly. I sent an email
- message after 11pm one evening, and the meeting took place the next
- afternoon. Unfortunately, corporate wheels sometimes grind slowly,
- especially when a company is being acquired, and so it's taken until now
- before the details were completely determined and a public statement could
- be made.
-
- BusLogic is not prepared at this time to release the information necessary
- for third parties to write drivers for the FlashPoint. The only existing
- FlashPoint drivers have been written directly by BusLogic Engineering, and
- there is no FlashPoint documentation sufficiently detailed to allow outside
- developers to write a driver without substantial assistance. While there
- are people at BusLogic who would rather not release the details of the
- FlashPoint architecture at all, that debate has not yet been settled either
- way. In any event, even if documentation were available today it would
- take quite a while for a usable driver to be written, especially since I'm
- not convinced that the effort required would be worthwhile.
-
- However, BusLogic does remain committed to providing a high performance
- SCSI solution for the Linux community, and does not want to see anyone left
- unable to run Linux because they have a Flashpoint LT. Therefore, BusLogic
- has put in place a direct upgrade program to allow any Linux user worldwide
- to trade in their FlashPoint LT for the new BT-948 MultiMaster PCI Ultra
- SCSI Host Adapter. The BT-948 is the Ultra SCSI successor to the BT-946C
- and has all the best features of both the BT-946C and FlashPoint LT,
- including smart termination and a flash PROM for easy firmware updates, and
- is of course compatible with the present Linux driver. The price for this
- upgrade has been set at US $45 plus shipping and handling, and the upgrade
- program will be administered through BusLogic Technical Support, which can
- be reached by electronic mail at techsup@buslogic.com, by Voice at +1 408
- 654-0760, or by FAX at +1 408 492-1542.
-
- As of 14 June 1996, the original BusLogic FlashPoint LT to BT-948 upgrade
- program has now been extended to encompass the FlashPoint LW Wide Ultra
- SCSI Host Adapter. Any Linux user worldwide may trade in their FlashPoint
- LW (BT-950) for a BT-958 MultiMaster PCI Ultra SCSI Host Adapter. The
- price for this upgrade has been set at US $65 plus shipping and handling.
-
- I was a beta test site for the BT-948/958, and versions 1.2.1 and 1.3.1 of
- my BusLogic driver already included latent support for the BT-948/958.
- Additional cosmetic support for the Ultra SCSI MultiMaster cards was added
- subsequent releases. As a result of this cooperative testing process,
- several firmware bugs were found and corrected. My heavily loaded Linux
- test system provided an ideal environment for testing error recovery
- processes that are much more rarely exercised in production systems, but
- are crucial to overall system stability. It was especially convenient
- being able to work directly with their firmware engineer in demonstrating
- the problems under control of the firmware debugging environment; things
- sure have come a long way since the last time I worked on firmware for an
- embedded system. I am presently working on some performance testing and
- expect to have some data to report in the not too distant future.
-
- BusLogic asked me to send this announcement since a large percentage of the
- questions regarding support for the FlashPoint have either been sent to me
- directly via email, or have appeared in the Linux newsgroups in which I
- participate. To summarize, BusLogic is offering Linux users an upgrade
- from the unsupported FlashPoint LT (BT-930) to the supported BT-948 for US
- $45 plus shipping and handling, or from the unsupported FlashPoint LW
- (BT-950) to the supported BT-958 for $65 plus shipping and handling.
- Contact BusLogic Technical Support at techsup@buslogic.com or +1 408
- 654-0760 to take advantage of their offer.
-
- Leonard N. Zubkoff
- lnz@dandelion.com
diff --git a/MAINTAINERS b/MAINTAINERS
index d8e2cdbb93e3..f3f9167c169e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4279,13 +4279,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git
F: Documentation/devicetree/bindings/devfreq/exynos-bus.txt
F: drivers/devfreq/exynos-bus.c

-BUSLOGIC SCSI DRIVER
-M: Khalid Aziz <khalid@gonehiking.org>
-L: linux-scsi@vger.kernel.org
-S: Maintained
-F: drivers/scsi/BusLogic.*
-F: drivers/scsi/FlashPoint.*
-
C-MEDIA CMI8788 DRIVER
M: Clemens Ladisch <clemens@ladisch.de>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
deleted file mode 100644
index a897c8f914cf..000000000000
--- a/drivers/scsi/BusLogic.c
+++ /dev/null
@@ -1,3727 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-/*
-
- Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
-
- Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
-
-
- The author respectfully requests that any modifications to this software be
- sent directly to him for evaluation and testing.
-
- Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
- advice has been invaluable, to David Gentzel, for writing the original Linux
- BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
-
- Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
- Manager available as freely redistributable source code.
-
-*/
-
-#define blogic_drvr_version "2.1.17"
-#define blogic_drvr_date "12 September 2013"
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/types.h>
-#include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/stat.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/jiffies.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/msdos_partition.h>
-#include <scsi/scsicam.h>
-
-#include <asm/dma.h>
-#include <asm/io.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_tcq.h>
-#include "BusLogic.h"
-#include "FlashPoint.c"
-
-#ifndef FAILURE
-#define FAILURE (-1)
-#endif
-
-static struct scsi_host_template blogic_template;
-
-/*
- blogic_drvr_options_count is a count of the number of BusLogic Driver
- Options specifications provided via the Linux Kernel Command Line or via
- the Loadable Kernel Module Installation Facility.
-*/
-
-static int blogic_drvr_options_count;
-
-
-/*
- blogic_drvr_options is an array of Driver Options structures representing
- BusLogic Driver Options specifications provided via the Linux Kernel Command
- Line or via the Loadable Kernel Module Installation Facility.
-*/
-
-static struct blogic_drvr_options blogic_drvr_options[BLOGIC_MAX_ADAPTERS];
-
-
-/*
- BusLogic can be assigned a string by insmod.
-*/
-
-MODULE_LICENSE("GPL");
-#ifdef MODULE
-static char *BusLogic;
-module_param(BusLogic, charp, 0);
-#endif
-
-
-/*
- blogic_probe_options is a set of Probe Options to be applied across
- all BusLogic Host Adapters.
-*/
-
-static struct blogic_probe_options blogic_probe_options;
-
-
-/*
- blogic_global_options is a set of Global Options to be applied across
- all BusLogic Host Adapters.
-*/
-
-static struct blogic_global_options blogic_global_options;
-
-static LIST_HEAD(blogic_host_list);
-
-/*
- blogic_probeinfo_count is the number of entries in blogic_probeinfo_list.
-*/
-
-static int blogic_probeinfo_count;
-
-
-/*
- blogic_probeinfo_list is the list of I/O Addresses and Bus Probe Information
- to be checked for potential BusLogic Host Adapters. It is initialized by
- interrogating the PCI Configuration Space on PCI machines as well as from the
- list of standard BusLogic I/O Addresses.
-*/
-
-static struct blogic_probeinfo *blogic_probeinfo_list;
-
-
-/*
- blogic_cmd_failure_reason holds a string identifying the reason why a
- call to blogic_cmd failed. It is only non-NULL when blogic_cmd
- returns a failure code.
-*/
-
-static char *blogic_cmd_failure_reason;
-
-/*
- blogic_announce_drvr announces the Driver Version and Date, Author's
- Name, Copyright Notice, and Electronic Mail Address.
-*/
-
-static void blogic_announce_drvr(struct blogic_adapter *adapter)
-{
- blogic_announce("***** BusLogic SCSI Driver Version " blogic_drvr_version " of " blogic_drvr_date " *****\n", adapter);
- blogic_announce("Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>\n", adapter);
-}
-
-
-/*
- blogic_drvr_info returns the Host Adapter Name to identify this SCSI
- Driver and Host Adapter.
-*/
-
-static const char *blogic_drvr_info(struct Scsi_Host *host)
-{
- struct blogic_adapter *adapter =
- (struct blogic_adapter *) host->hostdata;
- return adapter->full_model;
-}
-
-/*
- blogic_init_ccbs initializes a group of Command Control Blocks (CCBs)
- for Host Adapter from the blk_size bytes located at blk_pointer. The newly
- created CCBs are added to Host Adapter's free list.
-*/
-
-static void blogic_init_ccbs(struct blogic_adapter *adapter, void *blk_pointer,
- int blk_size, dma_addr_t blkp)
-{
- struct blogic_ccb *ccb = (struct blogic_ccb *) blk_pointer;
- unsigned int offset = 0;
- memset(blk_pointer, 0, blk_size);
- ccb->allocgrp_head = blkp;
- ccb->allocgrp_size = blk_size;
- while ((blk_size -= sizeof(struct blogic_ccb)) >= 0) {
- ccb->status = BLOGIC_CCB_FREE;
- ccb->adapter = adapter;
- ccb->dma_handle = (u32) blkp + offset;
- if (blogic_flashpoint_type(adapter)) {
- ccb->callback = blogic_qcompleted_ccb;
- ccb->base_addr = adapter->fpinfo.base_addr;
- }
- ccb->next = adapter->free_ccbs;
- ccb->next_all = adapter->all_ccbs;
- adapter->free_ccbs = ccb;
- adapter->all_ccbs = ccb;
- adapter->alloc_ccbs++;
- ccb++;
- offset += sizeof(struct blogic_ccb);
- }
-}
-
-
-/*
- blogic_create_initccbs allocates the initial CCBs for Host Adapter.
-*/
-
-static bool __init blogic_create_initccbs(struct blogic_adapter *adapter)
-{
- int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
- void *blk_pointer;
- dma_addr_t blkp;
-
- while (adapter->alloc_ccbs < adapter->initccbs) {
- blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
- blk_size, &blkp, GFP_KERNEL);
- if (blk_pointer == NULL) {
- blogic_err("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
- adapter);
- return false;
- }
- blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
- }
- return true;
-}
-
-
-/*
- blogic_destroy_ccbs deallocates the CCBs for Host Adapter.
-*/
-
-static void blogic_destroy_ccbs(struct blogic_adapter *adapter)
-{
- struct blogic_ccb *next_ccb = adapter->all_ccbs, *ccb, *lastccb = NULL;
- adapter->all_ccbs = NULL;
- adapter->free_ccbs = NULL;
- while ((ccb = next_ccb) != NULL) {
- next_ccb = ccb->next_all;
- if (ccb->allocgrp_head) {
- if (lastccb)
- dma_free_coherent(&adapter->pci_device->dev,
- lastccb->allocgrp_size, lastccb,
- lastccb->allocgrp_head);
- lastccb = ccb;
- }
- }
- if (lastccb)
- dma_free_coherent(&adapter->pci_device->dev,
- lastccb->allocgrp_size, lastccb,
- lastccb->allocgrp_head);
-}
-
-
-/*
- blogic_create_addlccbs allocates Additional CCBs for Host Adapter. If
- allocation fails and there are no remaining CCBs available, the Driver Queue
- Depth is decreased to a known safe value to avoid potential deadlocks when
- multiple host adapters share the same IRQ Channel.
-*/
-
-static void blogic_create_addlccbs(struct blogic_adapter *adapter,
- int addl_ccbs, bool print_success)
-{
- int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
- int prev_alloc = adapter->alloc_ccbs;
- void *blk_pointer;
- dma_addr_t blkp;
- if (addl_ccbs <= 0)
- return;
- while (adapter->alloc_ccbs - prev_alloc < addl_ccbs) {
- blk_pointer = dma_alloc_coherent(&adapter->pci_device->dev,
- blk_size, &blkp, GFP_KERNEL);
- if (blk_pointer == NULL)
- break;
- blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
- }
- if (adapter->alloc_ccbs > prev_alloc) {
- if (print_success)
- blogic_notice("Allocated %d additional CCBs (total now %d)\n", adapter, adapter->alloc_ccbs - prev_alloc, adapter->alloc_ccbs);
- return;
- }
- blogic_notice("Failed to allocate additional CCBs\n", adapter);
- if (adapter->drvr_qdepth > adapter->alloc_ccbs - adapter->tgt_count) {
- adapter->drvr_qdepth = adapter->alloc_ccbs - adapter->tgt_count;
- adapter->scsi_host->can_queue = adapter->drvr_qdepth;
- }
-}
-
-/*
- blogic_alloc_ccb allocates a CCB from Host Adapter's free list,
- allocating more memory from the Kernel if necessary. The Host Adapter's
- Lock should already have been acquired by the caller.
-*/
-
-static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
-{
- static unsigned long serial;
- struct blogic_ccb *ccb;
- ccb = adapter->free_ccbs;
- if (ccb != NULL) {
- ccb->serial = ++serial;
- adapter->free_ccbs = ccb->next;
- ccb->next = NULL;
- if (adapter->free_ccbs == NULL)
- blogic_create_addlccbs(adapter, adapter->inc_ccbs,
- true);
- return ccb;
- }
- blogic_create_addlccbs(adapter, adapter->inc_ccbs, true);
- ccb = adapter->free_ccbs;
- if (ccb == NULL)
- return NULL;
- ccb->serial = ++serial;
- adapter->free_ccbs = ccb->next;
- ccb->next = NULL;
- return ccb;
-}
-
-
-/*
- blogic_dealloc_ccb deallocates a CCB, returning it to the Host Adapter's
- free list. The Host Adapter's Lock should already have been acquired by the
- caller.
-*/
-
-static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
-{
- struct blogic_adapter *adapter = ccb->adapter;
-
- if (ccb->command != NULL)
- scsi_dma_unmap(ccb->command);
- if (dma_unmap)
- dma_unmap_single(&adapter->pci_device->dev, ccb->sensedata,
- ccb->sense_datalen, DMA_FROM_DEVICE);
-
- ccb->command = NULL;
- ccb->status = BLOGIC_CCB_FREE;
- ccb->next = adapter->free_ccbs;
- adapter->free_ccbs = ccb;
-}
-
-
-/*
- blogic_cmd sends the command opcode to adapter, optionally
- providing paramlen bytes of param and receiving at most
- replylen bytes of reply; any excess reply data is received but
- discarded.
-
- On success, this function returns the number of reply bytes read from
- the Host Adapter (including any discarded data); on failure, it returns
- -1 if the command was invalid, or -2 if a timeout occurred.
-
- blogic_cmd is called exclusively during host adapter detection and
- initialization, so performance and latency are not critical, and exclusive
- access to the Host Adapter hardware is assumed. Once the host adapter and
- driver are initialized, the only Host Adapter command that is issued is the
- single byte Execute Mailbox Command operation code, which does not require
- waiting for the Host Adapter Ready bit to be set in the Status Register.
-*/
-
-static int blogic_cmd(struct blogic_adapter *adapter, enum blogic_opcode opcode,
- void *param, int paramlen, void *reply, int replylen)
-{
- unsigned char *param_p = (unsigned char *) param;
- unsigned char *reply_p = (unsigned char *) reply;
- union blogic_stat_reg statusreg;
- union blogic_int_reg intreg;
- unsigned long processor_flag = 0;
- int reply_b = 0, result;
- long timeout;
- /*
- Clear out the Reply Data if provided.
- */
- if (replylen > 0)
- memset(reply, 0, replylen);
- /*
- If the IRQ Channel has not yet been acquired, then interrupts
- must be disabled while issuing host adapter commands since a
- Command Complete interrupt could occur if the IRQ Channel was
- previously enabled by another BusLogic Host Adapter or another
- driver sharing the same IRQ Channel.
- */
- if (!adapter->irq_acquired)
- local_irq_save(processor_flag);
- /*
- Wait for the Host Adapter Ready bit to be set and the
- Command/Parameter Register Busy bit to be reset in the Status
- Register.
- */
- timeout = 10000;
- while (--timeout >= 0) {
- statusreg.all = blogic_rdstatus(adapter);
- if (statusreg.sr.adapter_ready && !statusreg.sr.cmd_param_busy)
- break;
- udelay(100);
- }
- if (timeout < 0) {
- blogic_cmd_failure_reason =
- "Timeout waiting for Host Adapter Ready";
- result = -2;
- goto done;
- }
- /*
- Write the opcode to the Command/Parameter Register.
- */
- adapter->adapter_cmd_complete = false;
- blogic_setcmdparam(adapter, opcode);
- /*
- Write any additional Parameter Bytes.
- */
- timeout = 10000;
- while (paramlen > 0 && --timeout >= 0) {
- /*
- Wait 100 microseconds to give the Host Adapter enough
- time to determine whether the last value written to the
- Command/Parameter Register was valid or not. If the
- Command Complete bit is set in the Interrupt Register,
- then the Command Invalid bit in the Status Register will
- be reset if the Operation Code or Parameter was valid
- and the command has completed, or set if the Operation
- Code or Parameter was invalid. If the Data In Register
- Ready bit is set in the Status Register, then the
- Operation Code was valid, and data is waiting to be read
- back from the Host Adapter. Otherwise, wait for the
- Command/Parameter Register Busy bit in the Status
- Register to be reset.
- */
- udelay(100);
- intreg.all = blogic_rdint(adapter);
- statusreg.all = blogic_rdstatus(adapter);
- if (intreg.ir.cmd_complete)
- break;
- if (adapter->adapter_cmd_complete)
- break;
- if (statusreg.sr.datain_ready)
- break;
- if (statusreg.sr.cmd_param_busy)
- continue;
- blogic_setcmdparam(adapter, *param_p++);
- paramlen--;
- }
- if (timeout < 0) {
- blogic_cmd_failure_reason =
- "Timeout waiting for Parameter Acceptance";
- result = -2;
- goto done;
- }
- /*
- The Modify I/O Address command does not cause a Command Complete
- Interrupt.
- */
- if (opcode == BLOGIC_MOD_IOADDR) {
- statusreg.all = blogic_rdstatus(adapter);
- if (statusreg.sr.cmd_invalid) {
- blogic_cmd_failure_reason =
- "Modify I/O Address Invalid";
- result = -1;
- goto done;
- }
- if (blogic_global_options.trace_config)
- blogic_notice("blogic_cmd(%02X) Status = %02X: (Modify I/O Address)\n", adapter, opcode, statusreg.all);
- result = 0;
- goto done;
- }
- /*
- Select an appropriate timeout value for awaiting command completion.
- */
- switch (opcode) {
- case BLOGIC_INQ_DEV0TO7:
- case BLOGIC_INQ_DEV8TO15:
- case BLOGIC_INQ_DEV:
- /* Approximately 60 seconds. */
- timeout = 60 * 10000;
- break;
- default:
- /* Approximately 1 second. */
- timeout = 10000;
- break;
- }
- /*
- Receive any Reply Bytes, waiting for either the Command
- Complete bit to be set in the Interrupt Register, or for the
- Interrupt Handler to set the Host Adapter Command Completed
- bit in the Host Adapter structure.
- */
- while (--timeout >= 0) {
- intreg.all = blogic_rdint(adapter);
- statusreg.all = blogic_rdstatus(adapter);
- if (intreg.ir.cmd_complete)
- break;
- if (adapter->adapter_cmd_complete)
- break;
- if (statusreg.sr.datain_ready) {
- if (++reply_b <= replylen)
- *reply_p++ = blogic_rddatain(adapter);
- else
- blogic_rddatain(adapter);
- }
- if (opcode == BLOGIC_FETCH_LOCALRAM &&
- statusreg.sr.adapter_ready)
- break;
- udelay(100);
- }
- if (timeout < 0) {
- blogic_cmd_failure_reason =
- "Timeout waiting for Command Complete";
- result = -2;
- goto done;
- }
- /*
- Clear any pending Command Complete Interrupt.
- */
- blogic_intreset(adapter);
- /*
- Provide tracing information if requested.
- */
- if (blogic_global_options.trace_config) {
- int i;
- blogic_notice("blogic_cmd(%02X) Status = %02X: %2d ==> %2d:",
- adapter, opcode, statusreg.all, replylen,
- reply_b);
- if (replylen > reply_b)
- replylen = reply_b;
- for (i = 0; i < replylen; i++)
- blogic_notice(" %02X", adapter,
- ((unsigned char *) reply)[i]);
- blogic_notice("\n", adapter);
- }
- /*
- Process Command Invalid conditions.
- */
- if (statusreg.sr.cmd_invalid) {
- /*
- Some early BusLogic Host Adapters may not recover
- properly from a Command Invalid condition, so if this
- appears to be the case, a Soft Reset is issued to the
- Host Adapter. Potentially invalid commands are never
- attempted after Mailbox Initialization is performed,
- so there should be no Host Adapter state lost by a
- Soft Reset in response to a Command Invalid condition.
- */
- udelay(1000);
- statusreg.all = blogic_rdstatus(adapter);
- if (statusreg.sr.cmd_invalid || statusreg.sr.rsvd ||
- statusreg.sr.datain_ready ||
- statusreg.sr.cmd_param_busy ||
- !statusreg.sr.adapter_ready ||
- !statusreg.sr.init_reqd ||
- statusreg.sr.diag_active ||
- statusreg.sr.diag_failed) {
- blogic_softreset(adapter);
- udelay(1000);
- }
- blogic_cmd_failure_reason = "Command Invalid";
- result = -1;
- goto done;
- }
- /*
- Handle Excess Parameters Supplied conditions.
- */
- if (paramlen > 0) {
- blogic_cmd_failure_reason = "Excess Parameters Supplied";
- result = -1;
- goto done;
- }
- /*
- Indicate the command completed successfully.
- */
- blogic_cmd_failure_reason = NULL;
- result = reply_b;
- /*
- Restore the interrupt status if necessary and return.
- */
-done:
- if (!adapter->irq_acquired)
- local_irq_restore(processor_flag);
- return result;
-}
-
-
-/*
- blogic_sort_probeinfo sorts a section of blogic_probeinfo_list in order
- of increasing PCI Bus and Device Number.
-*/
-
-static void __init blogic_sort_probeinfo(struct blogic_probeinfo
- *probeinfo_list, int probeinfo_cnt)
-{
- int last_exchange = probeinfo_cnt - 1, bound, j;
-
- while (last_exchange > 0) {
- bound = last_exchange;
- last_exchange = 0;
- for (j = 0; j < bound; j++) {
- struct blogic_probeinfo *probeinfo1 =
- &probeinfo_list[j];
- struct blogic_probeinfo *probeinfo2 =
- &probeinfo_list[j + 1];
- if (probeinfo1->bus > probeinfo2->bus ||
- (probeinfo1->bus == probeinfo2->bus &&
- (probeinfo1->dev > probeinfo2->dev))) {
- struct blogic_probeinfo tmp_probeinfo;
-
- memcpy(&tmp_probeinfo, probeinfo1,
- sizeof(struct blogic_probeinfo));
- memcpy(probeinfo1, probeinfo2,
- sizeof(struct blogic_probeinfo));
- memcpy(probeinfo2, &tmp_probeinfo,
- sizeof(struct blogic_probeinfo));
- last_exchange = j;
- }
- }
- }
-}
-
-
-/*
- blogic_init_mm_probeinfo initializes the list of I/O Address
- and Bus Probe Information to be checked for potential BusLogic MultiMaster
- SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
- machines as well as from the list of standard BusLogic MultiMaster ISA
- I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found.
-*/
-
-static int __init blogic_init_mm_probeinfo(struct blogic_adapter *adapter)
-{
- struct blogic_probeinfo *pr_probeinfo =
- &blogic_probeinfo_list[blogic_probeinfo_count];
- int nonpr_mmindex = blogic_probeinfo_count + 1;
- int nonpr_mmcount = 0, mmcount = 0;
- bool force_scan_order = false;
- bool force_scan_order_checked = false;
- struct pci_dev *pci_device = NULL;
- int i;
- if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
- return 0;
- blogic_probeinfo_count++;
- /*
- Iterate over the MultiMaster PCI Host Adapters. For each
- enumerated host adapter, determine whether its ISA Compatible
- I/O Port is enabled and if so, whether it is assigned the
- Primary I/O Address. A host adapter that is assigned the
- Primary I/O Address will always be the preferred boot device.
- The MultiMaster BIOS will first recognize a host adapter at
- the Primary I/O Address, then any other PCI host adapters,
- and finally any host adapters located at the remaining
- standard ISA I/O Addresses. When a PCI host adapter is found
- with its ISA Compatible I/O Port enabled, a command is issued
- to disable the ISA Compatible I/O Port, and it is noted that the
- particular standard ISA I/O Address need not be probed.
- */
- pr_probeinfo->io_addr = 0;
- while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
- PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
- pci_device)) != NULL) {
- struct blogic_adapter *host_adapter = adapter;
- struct blogic_adapter_info adapter_info;
- enum blogic_isa_ioport mod_ioaddr_req;
- unsigned char bus;
- unsigned char device;
- unsigned int irq_ch;
- unsigned long base_addr0;
- unsigned long base_addr1;
- unsigned long io_addr;
- unsigned long pci_addr;
-
- if (pci_enable_device(pci_device))
- continue;
-
- if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
- continue;
-
- bus = pci_device->bus->number;
- device = pci_device->devfn >> 3;
- irq_ch = pci_device->irq;
- io_addr = base_addr0 = pci_resource_start(pci_device, 0);
- pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
-
- if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
- blogic_err("BusLogic: Base Address0 0x%lX not I/O for MultiMaster Host Adapter\n", NULL, base_addr0);
- blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
- continue;
- }
- if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
- blogic_err("BusLogic: Base Address1 0x%lX not Memory for MultiMaster Host Adapter\n", NULL, base_addr1);
- blogic_err("at PCI Bus %d Device %d PCI Address 0x%lX\n", NULL, bus, device, pci_addr);
- continue;
- }
- if (irq_ch == 0) {
- blogic_err("BusLogic: IRQ Channel %d invalid for MultiMaster Host Adapter\n", NULL, irq_ch);
- blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
- continue;
- }
- if (blogic_global_options.trace_probe) {
- blogic_notice("BusLogic: PCI MultiMaster Host Adapter detected at\n", NULL);
- blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address 0x%lX PCI Address 0x%lX\n", NULL, bus, device, io_addr, pci_addr);
- }
- /*
- Issue the Inquire PCI Host Adapter Information command to determine
- the ISA Compatible I/O Port. If the ISA Compatible I/O Port is
- known and enabled, note that the particular Standard ISA I/O
- Address should not be probed.
- */
- host_adapter->io_addr = io_addr;
- blogic_intreset(host_adapter);
- if (blogic_cmd(host_adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
- &adapter_info, sizeof(adapter_info)) !=
- sizeof(adapter_info))
- adapter_info.isa_port = BLOGIC_IO_DISABLE;
- /*
- Issue the Modify I/O Address command to disable the
- ISA Compatible I/O Port. On PCI Host Adapters, the
- Modify I/O Address command allows modification of the
- ISA compatible I/O Address that the Host Adapter
- responds to; it does not affect the PCI compliant
- I/O Address assigned at system initialization.
- */
- mod_ioaddr_req = BLOGIC_IO_DISABLE;
- blogic_cmd(host_adapter, BLOGIC_MOD_IOADDR, &mod_ioaddr_req,
- sizeof(mod_ioaddr_req), NULL, 0);
- /*
- For the first MultiMaster Host Adapter enumerated,
- issue the Fetch Host Adapter Local RAM command to read
- byte 45 of the AutoSCSI area, for the setting of the
- "Use Bus And Device # For PCI Scanning Seq." option.
- Issue the Inquire Board ID command since this option is
- only valid for the BT-948/958/958D.
- */
- if (!force_scan_order_checked) {
- struct blogic_fetch_localram fetch_localram;
- struct blogic_autoscsi_byte45 autoscsi_byte45;
- struct blogic_board_id id;
-
- fetch_localram.offset = BLOGIC_AUTOSCSI_BASE + 45;
- fetch_localram.count = sizeof(autoscsi_byte45);
- blogic_cmd(host_adapter, BLOGIC_FETCH_LOCALRAM,
- &fetch_localram, sizeof(fetch_localram),
- &autoscsi_byte45,
- sizeof(autoscsi_byte45));
- blogic_cmd(host_adapter, BLOGIC_GET_BOARD_ID, NULL, 0,
- &id, sizeof(id));
- if (id.fw_ver_digit1 == '5')
- force_scan_order =
- autoscsi_byte45.force_scan_order;
- force_scan_order_checked = true;
- }
- /*
- Determine whether this MultiMaster Host Adapter has its
- ISA Compatible I/O Port enabled and is assigned the
- Primary I/O Address. If it does, then it is the Primary
- MultiMaster Host Adapter and must be recognized first.
- If it does not, then it is added to the list for probing
- after any Primary MultiMaster Host Adapter is probed.
- */
- if (adapter_info.isa_port == BLOGIC_IO_330) {
- pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
- pr_probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
- pr_probeinfo->io_addr = io_addr;
- pr_probeinfo->pci_addr = pci_addr;
- pr_probeinfo->bus = bus;
- pr_probeinfo->dev = device;
- pr_probeinfo->irq_ch = irq_ch;
- pr_probeinfo->pci_device = pci_dev_get(pci_device);
- mmcount++;
- } else if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
- struct blogic_probeinfo *probeinfo =
- &blogic_probeinfo_list[blogic_probeinfo_count++];
- probeinfo->adapter_type = BLOGIC_MULTIMASTER;
- probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
- probeinfo->io_addr = io_addr;
- probeinfo->pci_addr = pci_addr;
- probeinfo->bus = bus;
- probeinfo->dev = device;
- probeinfo->irq_ch = irq_ch;
- probeinfo->pci_device = pci_dev_get(pci_device);
- nonpr_mmcount++;
- mmcount++;
- } else
- blogic_warn("BusLogic: Too many Host Adapters detected\n", NULL);
- }
- /*
- If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq."
- option is ON for the first enumerated MultiMaster Host Adapter,
- and if that host adapter is a BT-948/958/958D, then the
- MultiMaster BIOS will recognize MultiMaster Host Adapters in
- the order of increasing PCI Bus and Device Number. In that case,
- sort the probe information into the same order the BIOS uses.
- If this option is OFF, then the MultiMaster BIOS will recognize
- MultiMaster Host Adapters in the order they are enumerated by
- the PCI BIOS, and hence no sorting is necessary.
- */
- if (force_scan_order)
- blogic_sort_probeinfo(&blogic_probeinfo_list[nonpr_mmindex],
- nonpr_mmcount);
- /*
- Iterate over the older non-compliant MultiMaster PCI Host Adapters,
- noting the PCI bus location and assigned IRQ Channel.
- */
- pci_device = NULL;
- while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
- PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
- pci_device)) != NULL) {
- unsigned char bus;
- unsigned char device;
- unsigned int irq_ch;
- unsigned long io_addr;
-
- if (pci_enable_device(pci_device))
- continue;
-
- if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
- continue;
-
- bus = pci_device->bus->number;
- device = pci_device->devfn >> 3;
- irq_ch = pci_device->irq;
- io_addr = pci_resource_start(pci_device, 0);
-
- if (io_addr == 0 || irq_ch == 0)
- continue;
- for (i = 0; i < blogic_probeinfo_count; i++) {
- struct blogic_probeinfo *probeinfo =
- &blogic_probeinfo_list[i];
- if (probeinfo->io_addr == io_addr &&
- probeinfo->adapter_type == BLOGIC_MULTIMASTER) {
- probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
- probeinfo->pci_addr = 0;
- probeinfo->bus = bus;
- probeinfo->dev = device;
- probeinfo->irq_ch = irq_ch;
- probeinfo->pci_device = pci_dev_get(pci_device);
- break;
- }
- }
- }
- return mmcount;
-}
-
-
-/*
- blogic_init_fp_probeinfo initializes the list of I/O Address
- and Bus Probe Information to be checked for potential BusLogic FlashPoint
- Host Adapters by interrogating the PCI Configuration Space. It returns the
- number of FlashPoint Host Adapters found.
-*/
-
-static int __init blogic_init_fp_probeinfo(struct blogic_adapter *adapter)
-{
- int fpindex = blogic_probeinfo_count, fpcount = 0;
- struct pci_dev *pci_device = NULL;
- /*
- Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
- */
- while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
- PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
- pci_device)) != NULL) {
- unsigned char bus;
- unsigned char device;
- unsigned int irq_ch;
- unsigned long base_addr0;
- unsigned long base_addr1;
- unsigned long io_addr;
- unsigned long pci_addr;
-
- if (pci_enable_device(pci_device))
- continue;
-
- if (dma_set_mask(&pci_device->dev, DMA_BIT_MASK(32)))
- continue;
-
- bus = pci_device->bus->number;
- device = pci_device->devfn >> 3;
- irq_ch = pci_device->irq;
- io_addr = base_addr0 = pci_resource_start(pci_device, 0);
- pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
-#ifdef CONFIG_SCSI_FLASHPOINT
- if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
- blogic_err("BusLogic: Base Address0 0x%lX not I/O for FlashPoint Host Adapter\n", NULL, base_addr0);
- blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
- continue;
- }
- if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
- blogic_err("BusLogic: Base Address1 0x%lX not Memory for FlashPoint Host Adapter\n", NULL, base_addr1);
- blogic_err("at PCI Bus %d Device %d PCI Address 0x%lX\n", NULL, bus, device, pci_addr);
- continue;
- }
- if (irq_ch == 0) {
- blogic_err("BusLogic: IRQ Channel %d invalid for FlashPoint Host Adapter\n", NULL, irq_ch);
- blogic_err("at PCI Bus %d Device %d I/O Address 0x%lX\n", NULL, bus, device, io_addr);
- continue;
- }
- if (blogic_global_options.trace_probe) {
- blogic_notice("BusLogic: FlashPoint Host Adapter detected at\n", NULL);
- blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address 0x%lX PCI Address 0x%lX\n", NULL, bus, device, io_addr, pci_addr);
- }
- if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
- struct blogic_probeinfo *probeinfo =
- &blogic_probeinfo_list[blogic_probeinfo_count++];
- probeinfo->adapter_type = BLOGIC_FLASHPOINT;
- probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
- probeinfo->io_addr = io_addr;
- probeinfo->pci_addr = pci_addr;
- probeinfo->bus = bus;
- probeinfo->dev = device;
- probeinfo->irq_ch = irq_ch;
- probeinfo->pci_device = pci_dev_get(pci_device);
- fpcount++;
- } else
- blogic_warn("BusLogic: Too many Host Adapters detected\n", NULL);
-#else
- blogic_err("BusLogic: FlashPoint Host Adapter detected at PCI Bus %d Device %d\n", NULL, bus, device);
- blogic_err("BusLogic: I/O Address 0x%lX PCI Address 0x%lX, irq %d, but FlashPoint\n", NULL, io_addr, pci_addr, irq_ch);
- blogic_err("BusLogic: support was omitted in this kernel configuration.\n", NULL);
-#endif
- }
- /*
- The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
- increasing PCI Bus and Device Number, so sort the probe information into
- the same order the BIOS uses.
- */
- blogic_sort_probeinfo(&blogic_probeinfo_list[fpindex], fpcount);
- return fpcount;
-}
-
-
-/*
- blogic_init_probeinfo_list initializes the list of I/O Address and Bus
- Probe Information to be checked for potential BusLogic SCSI Host Adapters by
- interrogating the PCI Configuration Space on PCI machines as well as from the
- list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both
- FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
- probe for FlashPoint Host Adapters first unless the BIOS primary disk is
- controlled by the first PCI MultiMaster Host Adapter, in which case
- MultiMaster Host Adapters will be probed first. The BusLogic Driver Options
- specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
- a particular probe order.
-*/
-
-static void __init blogic_init_probeinfo_list(struct blogic_adapter *adapter)
-{
- /*
- If a PCI BIOS is present, interrogate it for MultiMaster and
- FlashPoint Host Adapters; otherwise, default to the standard
- ISA MultiMaster probe.
- */
- if (!blogic_probe_options.noprobe_pci) {
- if (blogic_probe_options.multimaster_first) {
- blogic_init_mm_probeinfo(adapter);
- blogic_init_fp_probeinfo(adapter);
- } else if (blogic_probe_options.flashpoint_first) {
- blogic_init_fp_probeinfo(adapter);
- blogic_init_mm_probeinfo(adapter);
- } else {
- int fpcount = blogic_init_fp_probeinfo(adapter);
- int mmcount = blogic_init_mm_probeinfo(adapter);
- if (fpcount > 0 && mmcount > 0) {
- struct blogic_probeinfo *probeinfo =
- &blogic_probeinfo_list[fpcount];
- struct blogic_adapter *myadapter = adapter;
- struct blogic_fetch_localram fetch_localram;
- struct blogic_bios_drvmap d0_mapbyte;
-
- while (probeinfo->adapter_bus_type !=
- BLOGIC_PCI_BUS)
- probeinfo++;
- myadapter->io_addr = probeinfo->io_addr;
- fetch_localram.offset =
- BLOGIC_BIOS_BASE + BLOGIC_BIOS_DRVMAP;
- fetch_localram.count = sizeof(d0_mapbyte);
- blogic_cmd(myadapter, BLOGIC_FETCH_LOCALRAM,
- &fetch_localram,
- sizeof(fetch_localram),
- &d0_mapbyte,
- sizeof(d0_mapbyte));
- /*
- If the Map Byte for BIOS Drive 0 indicates
- that BIOS Drive 0 is controlled by this
- PCI MultiMaster Host Adapter, then reverse
- the probe order so that MultiMaster Host
- Adapters are probed before FlashPoint Host
- Adapters.
- */
- if (d0_mapbyte.diskgeom != BLOGIC_BIOS_NODISK) {
- struct blogic_probeinfo saved_probeinfo[BLOGIC_MAX_ADAPTERS];
- int mmcount = blogic_probeinfo_count - fpcount;
-
- memcpy(saved_probeinfo,
- blogic_probeinfo_list,
- blogic_probeinfo_count * sizeof(struct blogic_probeinfo));
- memcpy(&blogic_probeinfo_list[0],
- &saved_probeinfo[fpcount],
- mmcount * sizeof(struct blogic_probeinfo));
- memcpy(&blogic_probeinfo_list[mmcount],
- &saved_probeinfo[0],
- fpcount * sizeof(struct blogic_probeinfo));
- }
- }
- }
- }
-}
-
-
-/*
- blogic_failure prints a standardized error message, and then returns false.
-*/
-
-static bool blogic_failure(struct blogic_adapter *adapter, char *msg)
-{
- blogic_announce_drvr(adapter);
- if (adapter->adapter_bus_type == BLOGIC_PCI_BUS) {
- blogic_err("While configuring BusLogic PCI Host Adapter at\n",
- adapter);
- blogic_err("Bus %d Device %d I/O Address 0x%lX PCI Address 0x%lX:\n", adapter, adapter->bus, adapter->dev, adapter->io_addr, adapter->pci_addr);
- } else
- blogic_err("While configuring BusLogic Host Adapter at I/O Address 0x%lX:\n", adapter, adapter->io_addr);
- blogic_err("%s FAILED - DETACHING\n", adapter, msg);
- if (blogic_cmd_failure_reason != NULL)
- blogic_err("ADDITIONAL FAILURE INFO - %s\n", adapter,
- blogic_cmd_failure_reason);
- return false;
-}
-
-
-/*
- blogic_probe probes for a BusLogic Host Adapter.
-*/
-
-static bool __init blogic_probe(struct blogic_adapter *adapter)
-{
- union blogic_stat_reg statusreg;
- union blogic_int_reg intreg;
- union blogic_geo_reg georeg;
- /*
- FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
- */
- if (blogic_flashpoint_type(adapter)) {
- struct fpoint_info *fpinfo = &adapter->fpinfo;
- fpinfo->base_addr = (u32) adapter->io_addr;
- fpinfo->irq_ch = adapter->irq_ch;
- fpinfo->present = false;
- if (!(FlashPoint_ProbeHostAdapter(fpinfo) == 0 &&
- fpinfo->present)) {
- blogic_err("BusLogic: FlashPoint Host Adapter detected at PCI Bus %d Device %d\n", adapter, adapter->bus, adapter->dev);
- blogic_err("BusLogic: I/O Address 0x%lX PCI Address 0x%lX, but FlashPoint\n", adapter, adapter->io_addr, adapter->pci_addr);
- blogic_err("BusLogic: Probe Function failed to validate it.\n", adapter);
- return false;
- }
- if (blogic_global_options.trace_probe)
- blogic_notice("BusLogic_Probe(0x%lX): FlashPoint Found\n", adapter, adapter->io_addr);
- /*
- Indicate the Host Adapter Probe completed successfully.
- */
- return true;
- }
- /*
- Read the Status, Interrupt, and Geometry Registers to test if there are I/O
- ports that respond, and to check the values to determine if they are from a
- BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which
- case there is definitely no BusLogic Host Adapter at this base I/O Address.
- The test here is a subset of that used by the BusLogic Host Adapter BIOS.
- */
- statusreg.all = blogic_rdstatus(adapter);
- intreg.all = blogic_rdint(adapter);
- georeg.all = blogic_rdgeom(adapter);
- if (blogic_global_options.trace_probe)
- blogic_notice("BusLogic_Probe(0x%lX): Status 0x%02X, Interrupt 0x%02X, Geometry 0x%02X\n", adapter, adapter->io_addr, statusreg.all, intreg.all, georeg.all);
- if (statusreg.all == 0 || statusreg.sr.diag_active ||
- statusreg.sr.cmd_param_busy || statusreg.sr.rsvd ||
- statusreg.sr.cmd_invalid || intreg.ir.rsvd != 0)
- return false;
- /*
- Check the undocumented Geometry Register to test if there is
- an I/O port that responded. Adaptec Host Adapters do not
- implement the Geometry Register, so this test helps serve to
- avoid incorrectly recognizing an Adaptec 1542A or 1542B as a
- BusLogic. Unfortunately, the Adaptec 1542C series does respond
- to the Geometry Register I/O port, but it will be rejected
- later when the Inquire Extended Setup Information command is
- issued in blogic_checkadapter. The AMI FastDisk Host Adapter
- is a BusLogic clone that implements the same interface as
- earlier BusLogic Host Adapters, including the undocumented
- commands, and is therefore supported by this driver. However,
- the AMI FastDisk always returns 0x00 upon reading the Geometry
- Register, so the extended translation option should always be
- left disabled on the AMI FastDisk.
- */
- if (georeg.all == 0xFF)
- return false;
- /*
- Indicate the Host Adapter Probe completed successfully.
- */
- return true;
-}
-
-
-/*
- blogic_hwreset issues a Hardware Reset to the Host Adapter
- and waits for Host Adapter Diagnostics to complete. If hard_reset is true, a
- Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a
- Soft Reset is performed which only resets the Host Adapter without forcing a
- SCSI Bus Reset.
-*/
-
-static bool blogic_hwreset(struct blogic_adapter *adapter, bool hard_reset)
-{
- union blogic_stat_reg statusreg;
- int timeout;
- /*
- FlashPoint Host Adapters are Hard Reset by the FlashPoint
- SCCB Manager.
- */
- if (blogic_flashpoint_type(adapter)) {
- struct fpoint_info *fpinfo = &adapter->fpinfo;
- fpinfo->softreset = !hard_reset;
- fpinfo->report_underrun = true;
- adapter->cardhandle =
- FlashPoint_HardwareResetHostAdapter(fpinfo);
- if (adapter->cardhandle == (void *)FPOINT_BADCARD_HANDLE)
- return false;
- /*
- Indicate the Host Adapter Hard Reset completed successfully.
- */
- return true;
- }
- /*
- Issue a Hard Reset or Soft Reset Command to the Host Adapter.
- The Host Adapter should respond by setting Diagnostic Active in
- the Status Register.
- */
- if (hard_reset)
- blogic_hardreset(adapter);
- else
- blogic_softreset(adapter);
- /*
- Wait until Diagnostic Active is set in the Status Register.
- */
- timeout = 5 * 10000;
- while (--timeout >= 0) {
- statusreg.all = blogic_rdstatus(adapter);
- if (statusreg.sr.diag_active)
- break;
- udelay(100);
- }
- if (blogic_global_options.trace_hw_reset)
- blogic_notice("BusLogic_HardwareReset(0x%lX): Diagnostic Active, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
- if (timeout < 0)
- return false;
- /*
- Wait 100 microseconds to allow completion of any initial diagnostic
- activity which might leave the contents of the Status Register
- unpredictable.
- */
- udelay(100);
- /*
- Wait until Diagnostic Active is reset in the Status Register.
- */
- timeout = 10 * 10000;
- while (--timeout >= 0) {
- statusreg.all = blogic_rdstatus(adapter);
- if (!statusreg.sr.diag_active)
- break;
- udelay(100);
- }
- if (blogic_global_options.trace_hw_reset)
- blogic_notice("BusLogic_HardwareReset(0x%lX): Diagnostic Completed, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
- if (timeout < 0)
- return false;
- /*
- Wait until at least one of the Diagnostic Failure, Host Adapter
- Ready, or Data In Register Ready bits is set in the Status Register.
- */
- timeout = 10000;
- while (--timeout >= 0) {
- statusreg.all = blogic_rdstatus(adapter);
- if (statusreg.sr.diag_failed || statusreg.sr.adapter_ready ||
- statusreg.sr.datain_ready)
- break;
- udelay(100);
- }
- if (blogic_global_options.trace_hw_reset)
- blogic_notice("BusLogic_HardwareReset(0x%lX): Host Adapter Ready, Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
- if (timeout < 0)
- return false;
- /*
- If Diagnostic Failure is set or Host Adapter Ready is reset,
- then an error occurred during the Host Adapter diagnostics.
- If Data In Register Ready is set, then there is an Error Code
- available.
- */
- if (statusreg.sr.diag_failed || !statusreg.sr.adapter_ready) {
- blogic_cmd_failure_reason = NULL;
- blogic_failure(adapter, "HARD RESET DIAGNOSTICS");
- blogic_err("HOST ADAPTER STATUS REGISTER = %02X\n", adapter,
- statusreg.all);
- if (statusreg.sr.datain_ready)
- blogic_err("HOST ADAPTER ERROR CODE = %d\n", adapter,
- blogic_rddatain(adapter));
- return false;
- }
- /*
- Indicate the Host Adapter Hard Reset completed successfully.
- */
- return true;
-}
-
-
-/*
- blogic_checkadapter checks to be sure this really is a BusLogic
- Host Adapter.
-*/
-
-static bool __init blogic_checkadapter(struct blogic_adapter *adapter)
-{
- struct blogic_ext_setup ext_setupinfo;
- unsigned char req_replylen;
- bool result = true;
- /*
- FlashPoint Host Adapters do not require this protection.
- */
- if (blogic_flashpoint_type(adapter))
- return true;
- /*
- Issue the Inquire Extended Setup Information command. Only genuine
- BusLogic Host Adapters and true clones support this command.
- Adaptec 1542C series Host Adapters that respond to the Geometry
- Register I/O port will fail this command.
- */
- req_replylen = sizeof(ext_setupinfo);
- if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
- sizeof(req_replylen), &ext_setupinfo,
- sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
- result = false;
- /*
- Provide tracing information if requested and return.
- */
- if (blogic_global_options.trace_probe)
- blogic_notice("BusLogic_Check(0x%lX): MultiMaster %s\n", adapter,
- adapter->io_addr,
- (result ? "Found" : "Not Found"));
- return result;
-}
-
-
-/*
- blogic_rdconfig reads the Configuration Information
- from Host Adapter and initializes the Host Adapter structure.
-*/
-
-static bool __init blogic_rdconfig(struct blogic_adapter *adapter)
-{
- struct blogic_board_id id;
- struct blogic_config config;
- struct blogic_setup_info setupinfo;
- struct blogic_ext_setup ext_setupinfo;
- unsigned char model[5];
- unsigned char fw_ver_digit3;
- unsigned char fw_ver_letter;
- struct blogic_adapter_info adapter_info;
- struct blogic_fetch_localram fetch_localram;
- struct blogic_autoscsi autoscsi;
- union blogic_geo_reg georeg;
- unsigned char req_replylen;
- unsigned char *tgt, ch;
- int tgt_id, i;
- /*
- Configuration Information for FlashPoint Host Adapters is
- provided in the fpoint_info structure by the FlashPoint
- SCCB Manager's Probe Function. Initialize fields in the
- Host Adapter structure from the fpoint_info structure.
- */
- if (blogic_flashpoint_type(adapter)) {
- struct fpoint_info *fpinfo = &adapter->fpinfo;
- tgt = adapter->model;
- *tgt++ = 'B';
- *tgt++ = 'T';
- *tgt++ = '-';
- for (i = 0; i < sizeof(fpinfo->model); i++)
- *tgt++ = fpinfo->model[i];
- *tgt++ = '\0';
- strcpy(adapter->fw_ver, FLASHPOINT_FW_VER);
- adapter->scsi_id = fpinfo->scsi_id;
- adapter->ext_trans_enable = fpinfo->ext_trans_enable;
- adapter->parity = fpinfo->parity;
- adapter->reset_enabled = !fpinfo->softreset;
- adapter->level_int = true;
- adapter->wide = fpinfo->wide;
- adapter->differential = false;
- adapter->scam = true;
- adapter->ultra = true;
- adapter->ext_lun = true;
- adapter->terminfo_valid = true;
- adapter->low_term = fpinfo->low_term;
- adapter->high_term = fpinfo->high_term;
- adapter->scam_enabled = fpinfo->scam_enabled;
- adapter->scam_lev2 = fpinfo->scam_lev2;
- adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
- adapter->maxdev = (adapter->wide ? 16 : 8);
- adapter->maxlun = 32;
- adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
- adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
- adapter->drvr_qdepth = 255;
- adapter->adapter_qdepth = adapter->drvr_qdepth;
- adapter->sync_ok = fpinfo->sync_ok;
- adapter->fast_ok = fpinfo->fast_ok;
- adapter->ultra_ok = fpinfo->ultra_ok;
- adapter->wide_ok = fpinfo->wide_ok;
- adapter->discon_ok = fpinfo->discon_ok;
- adapter->tagq_ok = 0xFFFF;
- goto common;
- }
- /*
- Issue the Inquire Board ID command.
- */
- if (blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id,
- sizeof(id)) != sizeof(id))
- return blogic_failure(adapter, "INQUIRE BOARD ID");
- /*
- Issue the Inquire Configuration command.
- */
- if (blogic_cmd(adapter, BLOGIC_INQ_CONFIG, NULL, 0, &config,
- sizeof(config))
- != sizeof(config))
- return blogic_failure(adapter, "INQUIRE CONFIGURATION");
- /*
- Issue the Inquire Setup Information command.
- */
- req_replylen = sizeof(setupinfo);
- if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
- sizeof(req_replylen), &setupinfo,
- sizeof(setupinfo)) != sizeof(setupinfo))
- return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
- /*
- Issue the Inquire Extended Setup Information command.
- */
- req_replylen = sizeof(ext_setupinfo);
- if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
- sizeof(req_replylen), &ext_setupinfo,
- sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
- return blogic_failure(adapter,
- "INQUIRE EXTENDED SETUP INFORMATION");
- /*
- Issue the Inquire Firmware Version 3rd Digit command.
- */
- fw_ver_digit3 = '\0';
- if (id.fw_ver_digit1 > '0')
- if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_D3, NULL, 0,
- &fw_ver_digit3,
- sizeof(fw_ver_digit3)) != sizeof(fw_ver_digit3))
- return blogic_failure(adapter,
- "INQUIRE FIRMWARE 3RD DIGIT");
- /*
- Issue the Inquire Host Adapter Model Number command.
- */
- if (ext_setupinfo.bus_type == 'A' && id.fw_ver_digit1 == '2')
- /* BusLogic BT-542B ISA 2.xx */
- strcpy(model, "542B");
- else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '2' &&
- (id.fw_ver_digit2 <= '1' || (id.fw_ver_digit2 == '2' &&
- fw_ver_digit3 == '0')))
- /* BusLogic BT-742A EISA 2.1x or 2.20 */
- strcpy(model, "742A");
- else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '0')
- /* AMI FastDisk EISA Series 441 0.x */
- strcpy(model, "747A");
- else {
- req_replylen = sizeof(model);
- if (blogic_cmd(adapter, BLOGIC_INQ_MODELNO, &req_replylen,
- sizeof(req_replylen), &model,
- sizeof(model)) != sizeof(model))
- return blogic_failure(adapter,
- "INQUIRE HOST ADAPTER MODEL NUMBER");
- }
- /*
- BusLogic MultiMaster Host Adapters can be identified by their
- model number and the major version number of their firmware
- as follows:
-
- 5.xx BusLogic "W" Series Host Adapters:
- BT-948/958/958D
- 4.xx BusLogic "C" Series Host Adapters:
- BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
- 3.xx BusLogic "S" Series Host Adapters:
- BT-747S/747D/757S/757D/445S/545S/542D
- BT-542B/742A (revision H)
- 2.xx BusLogic "A" Series Host Adapters:
- BT-542B/742A (revision G and below)
- 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
- */
- /*
- Save the Model Name and Host Adapter Name in the Host Adapter
- structure.
- */
- tgt = adapter->model;
- *tgt++ = 'B';
- *tgt++ = 'T';
- *tgt++ = '-';
- for (i = 0; i < sizeof(model); i++) {
- ch = model[i];
- if (ch == ' ' || ch == '\0')
- break;
- *tgt++ = ch;
- }
- *tgt++ = '\0';
- /*
- Save the Firmware Version in the Host Adapter structure.
- */
- tgt = adapter->fw_ver;
- *tgt++ = id.fw_ver_digit1;
- *tgt++ = '.';
- *tgt++ = id.fw_ver_digit2;
- if (fw_ver_digit3 != ' ' && fw_ver_digit3 != '\0')
- *tgt++ = fw_ver_digit3;
- *tgt = '\0';
- /*
- Issue the Inquire Firmware Version Letter command.
- */
- if (strcmp(adapter->fw_ver, "3.3") >= 0) {
- if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_LETTER, NULL, 0,
- &fw_ver_letter,
- sizeof(fw_ver_letter)) != sizeof(fw_ver_letter))
- return blogic_failure(adapter,
- "INQUIRE FIRMWARE VERSION LETTER");
- if (fw_ver_letter != ' ' && fw_ver_letter != '\0')
- *tgt++ = fw_ver_letter;
- *tgt = '\0';
- }
- /*
- Save the Host Adapter SCSI ID in the Host Adapter structure.
- */
- adapter->scsi_id = config.id;
- /*
- Determine the Bus Type and save it in the Host Adapter structure,
- determine and save the IRQ Channel if necessary, and determine
- and save the DMA Channel for ISA Host Adapters.
- */
- adapter->adapter_bus_type =
- blogic_adater_bus_types[adapter->model[3] - '4'];
- if (adapter->irq_ch == 0) {
- if (config.irq_ch9)
- adapter->irq_ch = 9;
- else if (config.irq_ch10)
- adapter->irq_ch = 10;
- else if (config.irq_ch11)
- adapter->irq_ch = 11;
- else if (config.irq_ch12)
- adapter->irq_ch = 12;
- else if (config.irq_ch14)
- adapter->irq_ch = 14;
- else if (config.irq_ch15)
- adapter->irq_ch = 15;
- }
- /*
- Determine whether Extended Translation is enabled and save it in
- the Host Adapter structure.
- */
- georeg.all = blogic_rdgeom(adapter);
- adapter->ext_trans_enable = georeg.gr.ext_trans_enable;
- /*
- Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
- SCSI flag, Differential SCSI flag, SCAM Supported flag, and
- Ultra SCSI flag in the Host Adapter structure.
- */
- adapter->adapter_sglimit = ext_setupinfo.sg_limit;
- adapter->drvr_sglimit = adapter->adapter_sglimit;
- if (adapter->adapter_sglimit > BLOGIC_SG_LIMIT)
- adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
- if (ext_setupinfo.misc.level_int)
- adapter->level_int = true;
- adapter->wide = ext_setupinfo.wide;
- adapter->differential = ext_setupinfo.differential;
- adapter->scam = ext_setupinfo.scam;
- adapter->ultra = ext_setupinfo.ultra;
- /*
- Determine whether Extended LUN Format CCBs are supported and save the
- information in the Host Adapter structure.
- */
- if (adapter->fw_ver[0] == '5' || (adapter->fw_ver[0] == '4' &&
- adapter->wide))
- adapter->ext_lun = true;
- /*
- Issue the Inquire PCI Host Adapter Information command to read the
- Termination Information from "W" series MultiMaster Host Adapters.
- */
- if (adapter->fw_ver[0] == '5') {
- if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
- &adapter_info,
- sizeof(adapter_info)) != sizeof(adapter_info))
- return blogic_failure(adapter,
- "INQUIRE PCI HOST ADAPTER INFORMATION");
- /*
- Save the Termination Information in the Host Adapter
- structure.
- */
- if (adapter_info.genericinfo_valid) {
- adapter->terminfo_valid = true;
- adapter->low_term = adapter_info.low_term;
- adapter->high_term = adapter_info.high_term;
- }
- }
- /*
- Issue the Fetch Host Adapter Local RAM command to read the
- AutoSCSI data from "W" and "C" series MultiMaster Host Adapters.
- */
- if (adapter->fw_ver[0] >= '4') {
- fetch_localram.offset = BLOGIC_AUTOSCSI_BASE;
- fetch_localram.count = sizeof(autoscsi);
- if (blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM, &fetch_localram,
- sizeof(fetch_localram), &autoscsi,
- sizeof(autoscsi)) != sizeof(autoscsi))
- return blogic_failure(adapter,
- "FETCH HOST ADAPTER LOCAL RAM");
- /*
- Save the Parity Checking Enabled, Bus Reset Enabled,
- and Termination Information in the Host Adapter structure.
- */
- adapter->parity = autoscsi.parity;
- adapter->reset_enabled = autoscsi.reset_enabled;
- if (adapter->fw_ver[0] == '4') {
- adapter->terminfo_valid = true;
- adapter->low_term = autoscsi.low_term;
- adapter->high_term = autoscsi.high_term;
- }
- /*
- Save the Wide Permitted, Fast Permitted, Synchronous
- Permitted, Disconnect Permitted, Ultra Permitted, and
- SCAM Information in the Host Adapter structure.
- */
- adapter->wide_ok = autoscsi.wide_ok;
- adapter->fast_ok = autoscsi.fast_ok;
- adapter->sync_ok = autoscsi.sync_ok;
- adapter->discon_ok = autoscsi.discon_ok;
- if (adapter->ultra)
- adapter->ultra_ok = autoscsi.ultra_ok;
- if (adapter->scam) {
- adapter->scam_enabled = autoscsi.scam_enabled;
- adapter->scam_lev2 = autoscsi.scam_lev2;
- }
- }
- /*
- Initialize fields in the Host Adapter structure for "S" and "A"
- series MultiMaster Host Adapters.
- */
- if (adapter->fw_ver[0] < '4') {
- if (setupinfo.sync) {
- adapter->sync_ok = 0xFF;
- if (adapter->adapter_bus_type == BLOGIC_EISA_BUS) {
- if (ext_setupinfo.misc.fast_on_eisa)
- adapter->fast_ok = 0xFF;
- if (strcmp(adapter->model, "BT-757") == 0)
- adapter->wide_ok = 0xFF;
- }
- }
- adapter->discon_ok = 0xFF;
- adapter->parity = setupinfo.parity;
- adapter->reset_enabled = true;
- }
- /*
- Determine the maximum number of Target IDs and Logical Units
- supported by this driver for Wide and Narrow Host Adapters.
- */
- adapter->maxdev = (adapter->wide ? 16 : 8);
- adapter->maxlun = (adapter->ext_lun ? 32 : 8);
- /*
- Select appropriate values for the Mailbox Count, Driver Queue Depth,
- Initial CCBs, and Incremental CCBs variables based on whether
- or not Strict Round Robin Mode is supported. If Strict Round
- Robin Mode is supported, then there is no performance degradation
- in using the maximum possible number of Outgoing and Incoming
- Mailboxes and allowing the Tagged and Untagged Queue Depths to
- determine the actual utilization. If Strict Round Robin Mode is
- not supported, then the Host Adapter must scan all the Outgoing
- Mailboxes whenever an Outgoing Mailbox entry is made, which can
- cause a substantial performance penalty. The host adapters
- actually have room to store the following number of CCBs
- internally; that is, they can internally queue and manage this
- many active commands on the SCSI bus simultaneously. Performance
- measurements demonstrate that the Driver Queue Depth should be
- set to the Mailbox Count, rather than the Host Adapter Queue
- Depth (internal CCB capacity), as it is more efficient to have the
- queued commands waiting in Outgoing Mailboxes if necessary than
- to block the process in the higher levels of the SCSI Subsystem.
-
- 192 BT-948/958/958D
- 100 BT-946C/956C/956CD/747C/757C/757CD/445C
- 50 BT-545C/540CF
- 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
- */
- if (adapter->fw_ver[0] == '5')
- adapter->adapter_qdepth = 192;
- else if (adapter->fw_ver[0] == '4')
- adapter->adapter_qdepth = 100;
- else
- adapter->adapter_qdepth = 30;
- if (strcmp(adapter->fw_ver, "3.31") >= 0) {
- adapter->strict_rr = true;
- adapter->mbox_count = BLOGIC_MAX_MAILBOX;
- } else {
- adapter->strict_rr = false;
- adapter->mbox_count = 32;
- }
- adapter->drvr_qdepth = adapter->mbox_count;
- adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
- adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
- /*
- Tagged Queuing support is available and operates properly on
- all "W" series MultiMaster Host Adapters, on "C" series
- MultiMaster Host Adapters with firmware version 4.22 and above,
- and on "S" series MultiMaster Host Adapters with firmware version
- 3.35 and above.
- */
- adapter->tagq_ok = 0;
- switch (adapter->fw_ver[0]) {
- case '5':
- adapter->tagq_ok = 0xFFFF;
- break;
- case '4':
- if (strcmp(adapter->fw_ver, "4.22") >= 0)
- adapter->tagq_ok = 0xFFFF;
- break;
- case '3':
- if (strcmp(adapter->fw_ver, "3.35") >= 0)
- adapter->tagq_ok = 0xFFFF;
- break;
- }
- /*
- Determine the Host Adapter BIOS Address if the BIOS is enabled and
- save it in the Host Adapter structure. The BIOS is disabled if the
- bios_addr is 0.
- */
- adapter->bios_addr = ext_setupinfo.bios_addr << 12;
- /*
- BusLogic BT-445S Host Adapters prior to board revision E have a
- hardware bug whereby when the BIOS is enabled, transfers to/from
- the same address range the BIOS occupies modulo 16MB are handled
- incorrectly. Only properly functioning BT-445S Host Adapters
- have firmware version 3.37.
- */
- if (adapter->bios_addr > 0 &&
- strcmp(adapter->model, "BT-445S") == 0 &&
- strcmp(adapter->fw_ver, "3.37") < 0)
- return blogic_failure(adapter, "Too old firmware");
- /*
- Initialize parameters common to MultiMaster and FlashPoint
- Host Adapters.
- */
-common:
- /*
- Initialize the Host Adapter Full Model Name from the Model Name.
- */
- strcpy(adapter->full_model, "BusLogic ");
- strcat(adapter->full_model, adapter->model);
- /*
- Select an appropriate value for the Tagged Queue Depth either from a
- BusLogic Driver Options specification, or based on whether this Host
- Adapter requires that ISA Bounce Buffers be used. The Tagged Queue
- Depth is left at 0 for automatic determination in
- BusLogic_SelectQueueDepths. Initialize the Untagged Queue Depth.
- */
- for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
- unsigned char qdepth = 0;
- if (adapter->drvr_opts != NULL &&
- adapter->drvr_opts->qdepth[tgt_id] > 0)
- qdepth = adapter->drvr_opts->qdepth[tgt_id];
- adapter->qdepth[tgt_id] = qdepth;
- }
- adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH;
- if (adapter->drvr_opts != NULL)
- adapter->common_qdepth = adapter->drvr_opts->common_qdepth;
- if (adapter->common_qdepth > 0 &&
- adapter->common_qdepth < adapter->untag_qdepth)
- adapter->untag_qdepth = adapter->common_qdepth;
- /*
- Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
- Therefore, mask the Tagged Queuing Permitted Default bits with the
- Disconnect/Reconnect Permitted bits.
- */
- adapter->tagq_ok &= adapter->discon_ok;
- /*
- Combine the default Tagged Queuing Permitted bits with any
- BusLogic Driver Options Tagged Queuing specification.
- */
- if (adapter->drvr_opts != NULL)
- adapter->tagq_ok = (adapter->drvr_opts->tagq_ok &
- adapter->drvr_opts->tagq_ok_mask) |
- (adapter->tagq_ok & ~adapter->drvr_opts->tagq_ok_mask);
-
- /*
- Select an appropriate value for Bus Settle Time either from a
- BusLogic Driver Options specification, or from
- BLOGIC_BUS_SETTLE_TIME.
- */
- if (adapter->drvr_opts != NULL &&
- adapter->drvr_opts->bus_settle_time > 0)
- adapter->bus_settle_time = adapter->drvr_opts->bus_settle_time;
- else
- adapter->bus_settle_time = BLOGIC_BUS_SETTLE_TIME;
- /*
- Indicate reading the Host Adapter Configuration completed
- successfully.
- */
- return true;
-}
-
-
-/*
- blogic_reportconfig reports the configuration of Host Adapter.
-*/
-
-static bool __init blogic_reportconfig(struct blogic_adapter *adapter)
-{
- unsigned short alltgt_mask = (1 << adapter->maxdev) - 1;
- unsigned short sync_ok, fast_ok;
- unsigned short ultra_ok, wide_ok;
- unsigned short discon_ok, tagq_ok;
- bool common_syncneg, common_tagq_depth;
- char syncstr[BLOGIC_MAXDEV + 1];
- char widestr[BLOGIC_MAXDEV + 1];
- char discon_str[BLOGIC_MAXDEV + 1];
- char tagq_str[BLOGIC_MAXDEV + 1];
- char *syncmsg = syncstr;
- char *widemsg = widestr;
- char *discon_msg = discon_str;
- char *tagq_msg = tagq_str;
- int tgt_id;
-
- blogic_info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n", adapter, adapter->model, blogic_adapter_busnames[adapter->adapter_bus_type], (adapter->wide ? " Wide" : ""), (adapter->differential ? " Differential" : ""), (adapter->ultra ? " Ultra" : ""));
- blogic_info(" Firmware Version: %s, I/O Address: 0x%lX, IRQ Channel: %d/%s\n", adapter, adapter->fw_ver, adapter->io_addr, adapter->irq_ch, (adapter->level_int ? "Level" : "Edge"));
- if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) {
- blogic_info(" DMA Channel: None, ", adapter);
- if (adapter->bios_addr > 0)
- blogic_info("BIOS Address: 0x%X, ", adapter,
- adapter->bios_addr);
- else
- blogic_info("BIOS Address: None, ", adapter);
- } else {
- blogic_info(" PCI Bus: %d, Device: %d, Address: ", adapter,
- adapter->bus, adapter->dev);
- if (adapter->pci_addr > 0)
- blogic_info("0x%lX, ", adapter, adapter->pci_addr);
- else
- blogic_info("Unassigned, ", adapter);
- }
- blogic_info("Host Adapter SCSI ID: %d\n", adapter, adapter->scsi_id);
- blogic_info(" Parity Checking: %s, Extended Translation: %s\n",
- adapter, (adapter->parity ? "Enabled" : "Disabled"),
- (adapter->ext_trans_enable ? "Enabled" : "Disabled"));
- alltgt_mask &= ~(1 << adapter->scsi_id);
- sync_ok = adapter->sync_ok & alltgt_mask;
- fast_ok = adapter->fast_ok & alltgt_mask;
- ultra_ok = adapter->ultra_ok & alltgt_mask;
- if ((blogic_multimaster_type(adapter) &&
- (adapter->fw_ver[0] >= '4' ||
- adapter->adapter_bus_type == BLOGIC_EISA_BUS)) ||
- blogic_flashpoint_type(adapter)) {
- common_syncneg = false;
- if (sync_ok == 0) {
- syncmsg = "Disabled";
- common_syncneg = true;
- } else if (sync_ok == alltgt_mask) {
- if (fast_ok == 0) {
- syncmsg = "Slow";
- common_syncneg = true;
- } else if (fast_ok == alltgt_mask) {
- if (ultra_ok == 0) {
- syncmsg = "Fast";
- common_syncneg = true;
- } else if (ultra_ok == alltgt_mask) {
- syncmsg = "Ultra";
- common_syncneg = true;
- }
- }
- }
- if (!common_syncneg) {
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- syncstr[tgt_id] = ((!(sync_ok & (1 << tgt_id))) ? 'N' : (!(fast_ok & (1 << tgt_id)) ? 'S' : (!(ultra_ok & (1 << tgt_id)) ? 'F' : 'U')));
- syncstr[adapter->scsi_id] = '#';
- syncstr[adapter->maxdev] = '\0';
- }
- } else
- syncmsg = (sync_ok == 0 ? "Disabled" : "Enabled");
- wide_ok = adapter->wide_ok & alltgt_mask;
- if (wide_ok == 0)
- widemsg = "Disabled";
- else if (wide_ok == alltgt_mask)
- widemsg = "Enabled";
- else {
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- widestr[tgt_id] = ((wide_ok & (1 << tgt_id)) ? 'Y' : 'N');
- widestr[adapter->scsi_id] = '#';
- widestr[adapter->maxdev] = '\0';
- }
- discon_ok = adapter->discon_ok & alltgt_mask;
- if (discon_ok == 0)
- discon_msg = "Disabled";
- else if (discon_ok == alltgt_mask)
- discon_msg = "Enabled";
- else {
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- discon_str[tgt_id] = ((discon_ok & (1 << tgt_id)) ? 'Y' : 'N');
- discon_str[adapter->scsi_id] = '#';
- discon_str[adapter->maxdev] = '\0';
- }
- tagq_ok = adapter->tagq_ok & alltgt_mask;
- if (tagq_ok == 0)
- tagq_msg = "Disabled";
- else if (tagq_ok == alltgt_mask)
- tagq_msg = "Enabled";
- else {
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- tagq_str[tgt_id] = ((tagq_ok & (1 << tgt_id)) ? 'Y' : 'N');
- tagq_str[adapter->scsi_id] = '#';
- tagq_str[adapter->maxdev] = '\0';
- }
- blogic_info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n",
- adapter, syncmsg, widemsg);
- blogic_info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", adapter,
- discon_msg, tagq_msg);
- if (blogic_multimaster_type(adapter)) {
- blogic_info(" Scatter/Gather Limit: %d of %d segments, Mailboxes: %d\n", adapter, adapter->drvr_sglimit, adapter->adapter_sglimit, adapter->mbox_count);
- blogic_info(" Driver Queue Depth: %d, Host Adapter Queue Depth: %d\n", adapter, adapter->drvr_qdepth, adapter->adapter_qdepth);
- } else
- blogic_info(" Driver Queue Depth: %d, Scatter/Gather Limit: %d segments\n", adapter, adapter->drvr_qdepth, adapter->drvr_sglimit);
- blogic_info(" Tagged Queue Depth: ", adapter);
- common_tagq_depth = true;
- for (tgt_id = 1; tgt_id < adapter->maxdev; tgt_id++)
- if (adapter->qdepth[tgt_id] != adapter->qdepth[0]) {
- common_tagq_depth = false;
- break;
- }
- if (common_tagq_depth) {
- if (adapter->qdepth[0] > 0)
- blogic_info("%d", adapter, adapter->qdepth[0]);
- else
- blogic_info("Automatic", adapter);
- } else
- blogic_info("Individual", adapter);
- blogic_info(", Untagged Queue Depth: %d\n", adapter,
- adapter->untag_qdepth);
- if (adapter->terminfo_valid) {
- if (adapter->wide)
- blogic_info(" SCSI Bus Termination: %s", adapter,
- (adapter->low_term ? (adapter->high_term ? "Both Enabled" : "Low Enabled") : (adapter->high_term ? "High Enabled" : "Both Disabled")));
- else
- blogic_info(" SCSI Bus Termination: %s", adapter,
- (adapter->low_term ? "Enabled" : "Disabled"));
- if (adapter->scam)
- blogic_info(", SCAM: %s", adapter,
- (adapter->scam_enabled ? (adapter->scam_lev2 ? "Enabled, Level 2" : "Enabled, Level 1") : "Disabled"));
- blogic_info("\n", adapter);
- }
- /*
- Indicate reporting the Host Adapter configuration completed
- successfully.
- */
- return true;
-}
-
-
-/*
- blogic_getres acquires the system resources necessary to use
- Host Adapter.
-*/
-
-static bool __init blogic_getres(struct blogic_adapter *adapter)
-{
- if (adapter->irq_ch == 0) {
- blogic_err("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
- adapter);
- return false;
- }
- /*
- Acquire shared access to the IRQ Channel.
- */
- if (request_irq(adapter->irq_ch, blogic_inthandler, IRQF_SHARED,
- adapter->full_model, adapter) < 0) {
- blogic_err("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
- adapter, adapter->irq_ch);
- return false;
- }
- adapter->irq_acquired = true;
- /*
- Indicate the System Resource Acquisition completed successfully,
- */
- return true;
-}
-
-
-/*
- blogic_relres releases any system resources previously acquired
- by blogic_getres.
-*/
-
-static void blogic_relres(struct blogic_adapter *adapter)
-{
- /*
- Release shared access to the IRQ Channel.
- */
- if (adapter->irq_acquired)
- free_irq(adapter->irq_ch, adapter);
- /*
- Release any allocated memory structs not released elsewhere
- */
- if (adapter->mbox_space)
- dma_free_coherent(&adapter->pci_device->dev, adapter->mbox_sz,
- adapter->mbox_space, adapter->mbox_space_handle);
- pci_dev_put(adapter->pci_device);
- adapter->mbox_space = NULL;
- adapter->mbox_space_handle = 0;
- adapter->mbox_sz = 0;
-}
-
-
-/*
- blogic_initadapter initializes Host Adapter. This is the only
- function called during SCSI Host Adapter detection which modifies the state
- of the Host Adapter from its initial power on or hard reset state.
-*/
-
-static bool blogic_initadapter(struct blogic_adapter *adapter)
-{
- struct blogic_extmbox_req extmbox_req;
- enum blogic_rr_req rr_req;
- enum blogic_setccb_fmt setccb_fmt;
- int tgt_id;
-
- /*
- Initialize the pointers to the first and last CCBs that are
- queued for completion processing.
- */
- adapter->firstccb = NULL;
- adapter->lastccb = NULL;
-
- /*
- Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
- Command Successful Flag, Active Commands, and Commands Since Reset
- for each Target Device.
- */
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
- adapter->bdr_pend[tgt_id] = NULL;
- adapter->tgt_flags[tgt_id].tagq_active = false;
- adapter->tgt_flags[tgt_id].cmd_good = false;
- adapter->active_cmds[tgt_id] = 0;
- adapter->cmds_since_rst[tgt_id] = 0;
- }
-
- /*
- FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
- */
- if (blogic_flashpoint_type(adapter))
- goto done;
-
- /*
- Initialize the Outgoing and Incoming Mailbox pointers.
- */
- adapter->mbox_sz = adapter->mbox_count * (sizeof(struct blogic_outbox) + sizeof(struct blogic_inbox));
- adapter->mbox_space = dma_alloc_coherent(&adapter->pci_device->dev,
- adapter->mbox_sz, &adapter->mbox_space_handle,
- GFP_KERNEL);
- if (adapter->mbox_space == NULL)
- return blogic_failure(adapter, "MAILBOX ALLOCATION");
- adapter->first_outbox = (struct blogic_outbox *) adapter->mbox_space;
- adapter->last_outbox = adapter->first_outbox + adapter->mbox_count - 1;
- adapter->next_outbox = adapter->first_outbox;
- adapter->first_inbox = (struct blogic_inbox *) (adapter->last_outbox + 1);
- adapter->last_inbox = adapter->first_inbox + adapter->mbox_count - 1;
- adapter->next_inbox = adapter->first_inbox;
-
- /*
- Initialize the Outgoing and Incoming Mailbox structures.
- */
- memset(adapter->first_outbox, 0,
- adapter->mbox_count * sizeof(struct blogic_outbox));
- memset(adapter->first_inbox, 0,
- adapter->mbox_count * sizeof(struct blogic_inbox));
-
- /*
- Initialize the Host Adapter's Pointer to the Outgoing/Incoming
- Mailboxes.
- */
- extmbox_req.mbox_count = adapter->mbox_count;
- extmbox_req.base_mbox_addr = (u32) adapter->mbox_space_handle;
- if (blogic_cmd(adapter, BLOGIC_INIT_EXT_MBOX, &extmbox_req,
- sizeof(extmbox_req), NULL, 0) < 0)
- return blogic_failure(adapter, "MAILBOX INITIALIZATION");
- /*
- Enable Strict Round Robin Mode if supported by the Host Adapter. In
- Strict Round Robin Mode, the Host Adapter only looks at the next
- Outgoing Mailbox for each new command, rather than scanning
- through all the Outgoing Mailboxes to find any that have new
- commands in them. Strict Round Robin Mode is significantly more
- efficient.
- */
- if (adapter->strict_rr) {
- rr_req = BLOGIC_STRICT_RR_MODE;
- if (blogic_cmd(adapter, BLOGIC_STRICT_RR, &rr_req,
- sizeof(rr_req), NULL, 0) < 0)
- return blogic_failure(adapter,
- "ENABLE STRICT ROUND ROBIN MODE");
- }
-
- /*
- For Host Adapters that support Extended LUN Format CCBs, issue the
- Set CCB Format command to allow 32 Logical Units per Target Device.
- */
- if (adapter->ext_lun) {
- setccb_fmt = BLOGIC_EXT_LUN_CCB;
- if (blogic_cmd(adapter, BLOGIC_SETCCB_FMT, &setccb_fmt,
- sizeof(setccb_fmt), NULL, 0) < 0)
- return blogic_failure(adapter, "SET CCB FORMAT");
- }
-
- /*
- Announce Successful Initialization.
- */
-done:
- if (!adapter->adapter_initd) {
- blogic_info("*** %s Initialized Successfully ***\n", adapter,
- adapter->full_model);
- blogic_info("\n", adapter);
- } else
- blogic_warn("*** %s Initialized Successfully ***\n", adapter,
- adapter->full_model);
- adapter->adapter_initd = true;
-
- /*
- Indicate the Host Adapter Initialization completed successfully.
- */
- return true;
-}
-
-
-/*
- blogic_inquiry inquires about the Target Devices accessible
- through Host Adapter.
-*/
-
-static bool __init blogic_inquiry(struct blogic_adapter *adapter)
-{
- u16 installed_devs;
- u8 installed_devs0to7[8];
- struct blogic_setup_info setupinfo;
- u8 sync_period[BLOGIC_MAXDEV];
- unsigned char req_replylen;
- int tgt_id;
-
- /*
- Wait a few seconds between the Host Adapter Hard Reset which
- initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
- SCSI devices get confused if they receive SCSI Commands too soon
- after a SCSI Bus Reset.
- */
- blogic_delay(adapter->bus_settle_time);
- /*
- FlashPoint Host Adapters do not provide for Target Device Inquiry.
- */
- if (blogic_flashpoint_type(adapter))
- return true;
- /*
- Inhibit the Target Device Inquiry if requested.
- */
- if (adapter->drvr_opts != NULL && adapter->drvr_opts->stop_tgt_inquiry)
- return true;
- /*
- Issue the Inquire Target Devices command for host adapters with
- firmware version 4.25 or later, or the Inquire Installed Devices
- ID 0 to 7 command for older host adapters. This is necessary to
- force Synchronous Transfer Negotiation so that the Inquire Setup
- Information and Inquire Synchronous Period commands will return
- valid data. The Inquire Target Devices command is preferable to
- Inquire Installed Devices ID 0 to 7 since it only probes Logical
- Unit 0 of each Target Device.
- */
- if (strcmp(adapter->fw_ver, "4.25") >= 0) {
-
- /*
- Issue a Inquire Target Devices command. Inquire Target
- Devices only tests Logical Unit 0 of each Target Device
- unlike the Inquire Installed Devices commands which test
- Logical Units 0 - 7. Two bytes are returned, where byte
- 0 bit 0 set indicates that Target Device 0 exists, and so on.
- */
-
- if (blogic_cmd(adapter, BLOGIC_INQ_DEV, NULL, 0,
- &installed_devs, sizeof(installed_devs))
- != sizeof(installed_devs))
- return blogic_failure(adapter, "INQUIRE TARGET DEVICES");
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- adapter->tgt_flags[tgt_id].tgt_exists =
- (installed_devs & (1 << tgt_id) ? true : false);
- } else {
-
- /*
- Issue an Inquire Installed Devices command. For each
- Target Device, a byte is returned where bit 0 set
- indicates that Logical Unit 0 * exists, bit 1 set
- indicates that Logical Unit 1 exists, and so on.
- */
-
- if (blogic_cmd(adapter, BLOGIC_INQ_DEV0TO7, NULL, 0,
- &installed_devs0to7, sizeof(installed_devs0to7))
- != sizeof(installed_devs0to7))
- return blogic_failure(adapter,
- "INQUIRE INSTALLED DEVICES ID 0 TO 7");
- for (tgt_id = 0; tgt_id < 8; tgt_id++)
- adapter->tgt_flags[tgt_id].tgt_exists =
- installed_devs0to7[tgt_id] != 0;
- }
- /*
- Issue the Inquire Setup Information command.
- */
- req_replylen = sizeof(setupinfo);
- if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
- sizeof(req_replylen), &setupinfo, sizeof(setupinfo))
- != sizeof(setupinfo))
- return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- adapter->sync_offset[tgt_id] = (tgt_id < 8 ? setupinfo.sync0to7[tgt_id].offset : setupinfo.sync8to15[tgt_id - 8].offset);
- if (strcmp(adapter->fw_ver, "5.06L") >= 0)
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- adapter->tgt_flags[tgt_id].wide_active = (tgt_id < 8 ? (setupinfo.wide_tx_active0to7 & (1 << tgt_id) ? true : false) : (setupinfo.wide_tx_active8to15 & (1 << (tgt_id - 8)) ? true : false));
- /*
- Issue the Inquire Synchronous Period command.
- */
- if (adapter->fw_ver[0] >= '3') {
-
- /* Issue a Inquire Synchronous Period command. For each
- Target Device, a byte is returned which represents the
- Synchronous Transfer Period in units of 10 nanoseconds.
- */
-
- req_replylen = sizeof(sync_period);
- if (blogic_cmd(adapter, BLOGIC_INQ_SYNC_PERIOD, &req_replylen,
- sizeof(req_replylen), &sync_period,
- sizeof(sync_period)) != sizeof(sync_period))
- return blogic_failure(adapter,
- "INQUIRE SYNCHRONOUS PERIOD");
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- adapter->sync_period[tgt_id] = sync_period[tgt_id];
- } else
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- if (setupinfo.sync0to7[tgt_id].offset > 0)
- adapter->sync_period[tgt_id] = 20 + 5 * setupinfo.sync0to7[tgt_id].tx_period;
- /*
- Indicate the Target Device Inquiry completed successfully.
- */
- return true;
-}
-
-/*
- blogic_inithoststruct initializes the fields in the SCSI Host
- structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
- SCSI Host structure are intentionally left uninitialized, as this driver
- handles acquisition and release of these resources explicitly, as well as
- ensuring exclusive access to the Host Adapter hardware and data structures
- through explicit acquisition and release of the Host Adapter's Lock.
-*/
-
-static void __init blogic_inithoststruct(struct blogic_adapter *adapter,
- struct Scsi_Host *host)
-{
- host->max_id = adapter->maxdev;
- host->max_lun = adapter->maxlun;
- host->max_channel = 0;
- host->unique_id = adapter->io_addr;
- host->this_id = adapter->scsi_id;
- host->can_queue = adapter->drvr_qdepth;
- host->sg_tablesize = adapter->drvr_sglimit;
- host->cmd_per_lun = adapter->untag_qdepth;
-}
-
-/*
- blogic_slaveconfig will actually set the queue depth on individual
- scsi devices as they are permanently added to the device chain. We
- shamelessly rip off the SelectQueueDepths code to make this work mostly
- like it used to. Since we don't get called once at the end of the scan
- but instead get called for each device, we have to do things a bit
- differently.
-*/
-static int blogic_slaveconfig(struct scsi_device *dev)
-{
- struct blogic_adapter *adapter =
- (struct blogic_adapter *) dev->host->hostdata;
- int tgt_id = dev->id;
- int qdepth = adapter->qdepth[tgt_id];
-
- if (adapter->tgt_flags[tgt_id].tagq_ok &&
- (adapter->tagq_ok & (1 << tgt_id))) {
- if (qdepth == 0)
- qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH;
- adapter->qdepth[tgt_id] = qdepth;
- scsi_change_queue_depth(dev, qdepth);
- } else {
- adapter->tagq_ok &= ~(1 << tgt_id);
- qdepth = adapter->untag_qdepth;
- adapter->qdepth[tgt_id] = qdepth;
- scsi_change_queue_depth(dev, qdepth);
- }
- qdepth = 0;
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
- if (adapter->tgt_flags[tgt_id].tgt_exists)
- qdepth += adapter->qdepth[tgt_id];
- if (qdepth > adapter->alloc_ccbs)
- blogic_create_addlccbs(adapter, qdepth - adapter->alloc_ccbs,
- false);
- return 0;
-}
-
-/*
- blogic_init probes for BusLogic Host Adapters at the standard
- I/O Addresses where they may be located, initializing, registering, and
- reporting the configuration of each BusLogic Host Adapter it finds. It
- returns the number of BusLogic Host Adapters successfully initialized and
- registered.
-*/
-
-static int __init blogic_init(void)
-{
- int adapter_count = 0, drvr_optindex = 0, probeindex;
- struct blogic_adapter *adapter;
- int ret = 0;
-
-#ifdef MODULE
- if (BusLogic)
- blogic_setup(BusLogic);
-#endif
-
- if (blogic_probe_options.noprobe)
- return -ENODEV;
- blogic_probeinfo_list =
- kcalloc(BLOGIC_MAX_ADAPTERS, sizeof(struct blogic_probeinfo),
- GFP_KERNEL);
- if (blogic_probeinfo_list == NULL) {
- blogic_err("BusLogic: Unable to allocate Probe Info List\n",
- NULL);
- return -ENOMEM;
- }
-
- adapter = kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL);
- if (adapter == NULL) {
- kfree(blogic_probeinfo_list);
- blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL);
- return -ENOMEM;
- }
-
-#ifdef MODULE
- if (BusLogic != NULL)
- blogic_setup(BusLogic);
-#endif
- blogic_init_probeinfo_list(adapter);
- for (probeindex = 0; probeindex < blogic_probeinfo_count; probeindex++) {
- struct blogic_probeinfo *probeinfo =
- &blogic_probeinfo_list[probeindex];
- struct blogic_adapter *myadapter = adapter;
- struct Scsi_Host *host;
-
- if (probeinfo->io_addr == 0)
- continue;
- memset(myadapter, 0, sizeof(struct blogic_adapter));
- myadapter->adapter_type = probeinfo->adapter_type;
- myadapter->adapter_bus_type = probeinfo->adapter_bus_type;
- myadapter->io_addr = probeinfo->io_addr;
- myadapter->pci_addr = probeinfo->pci_addr;
- myadapter->bus = probeinfo->bus;
- myadapter->dev = probeinfo->dev;
- myadapter->pci_device = probeinfo->pci_device;
- myadapter->irq_ch = probeinfo->irq_ch;
- myadapter->addr_count =
- blogic_adapter_addr_count[myadapter->adapter_type];
-
- /*
- Make sure region is free prior to probing.
- */
- if (!request_region(myadapter->io_addr, myadapter->addr_count,
- "BusLogic"))
- continue;
- /*
- Probe the Host Adapter. If unsuccessful, abort further
- initialization.
- */
- if (!blogic_probe(myadapter)) {
- release_region(myadapter->io_addr,
- myadapter->addr_count);
- continue;
- }
- /*
- Hard Reset the Host Adapter. If unsuccessful, abort further
- initialization.
- */
- if (!blogic_hwreset(myadapter, true)) {
- release_region(myadapter->io_addr,
- myadapter->addr_count);
- continue;
- }
- /*
- Check the Host Adapter. If unsuccessful, abort further
- initialization.
- */
- if (!blogic_checkadapter(myadapter)) {
- release_region(myadapter->io_addr,
- myadapter->addr_count);
- continue;
- }
- /*
- Initialize the Driver Options field if provided.
- */
- if (drvr_optindex < blogic_drvr_options_count)
- myadapter->drvr_opts =
- &blogic_drvr_options[drvr_optindex++];
- /*
- Announce the Driver Version and Date, Author's Name,
- Copyright Notice, and Electronic Mail Address.
- */
- blogic_announce_drvr(myadapter);
- /*
- Register the SCSI Host structure.
- */
-
- host = scsi_host_alloc(&blogic_template,
- sizeof(struct blogic_adapter));
- if (host == NULL) {
- release_region(myadapter->io_addr,
- myadapter->addr_count);
- continue;
- }
- myadapter = (struct blogic_adapter *) host->hostdata;
- memcpy(myadapter, adapter, sizeof(struct blogic_adapter));
- myadapter->scsi_host = host;
- myadapter->host_no = host->host_no;
- /*
- Add Host Adapter to the end of the list of registered
- BusLogic Host Adapters.
- */
- list_add_tail(&myadapter->host_list, &blogic_host_list);
-
- /*
- Read the Host Adapter Configuration, Configure the Host
- Adapter, Acquire the System Resources necessary to use
- the Host Adapter, then Create the Initial CCBs, Initialize
- the Host Adapter, and finally perform Target Device
- Inquiry. From this point onward, any failure will be
- assumed to be due to a problem with the Host Adapter,
- rather than due to having mistakenly identified this port
- as belonging to a BusLogic Host Adapter. The I/O Address
- range will not be released, thereby preventing it from
- being incorrectly identified as any other type of Host
- Adapter.
- */
- if (blogic_rdconfig(myadapter) &&
- blogic_reportconfig(myadapter) &&
- blogic_getres(myadapter) &&
- blogic_create_initccbs(myadapter) &&
- blogic_initadapter(myadapter) &&
- blogic_inquiry(myadapter)) {
- /*
- Initialization has been completed successfully.
- Release and re-register usage of the I/O Address
- range so that the Model Name of the Host Adapter
- will appear, and initialize the SCSI Host structure.
- */
- release_region(myadapter->io_addr,
- myadapter->addr_count);
- if (!request_region(myadapter->io_addr,
- myadapter->addr_count,
- myadapter->full_model)) {
- printk(KERN_WARNING
- "BusLogic: Release and re-register of "
- "port 0x%04lx failed \n",
- (unsigned long)myadapter->io_addr);
- blogic_destroy_ccbs(myadapter);
- blogic_relres(myadapter);
- list_del(&myadapter->host_list);
- scsi_host_put(host);
- ret = -ENOMEM;
- } else {
- blogic_inithoststruct(myadapter,
- host);
- if (scsi_add_host(host, myadapter->pci_device
- ? &myadapter->pci_device->dev
- : NULL)) {
- printk(KERN_WARNING
- "BusLogic: scsi_add_host()"
- "failed!\n");
- blogic_destroy_ccbs(myadapter);
- blogic_relres(myadapter);
- list_del(&myadapter->host_list);
- scsi_host_put(host);
- ret = -ENODEV;
- } else {
- scsi_scan_host(host);
- adapter_count++;
- }
- }
- } else {
- /*
- An error occurred during Host Adapter Configuration
- Querying, Host Adapter Configuration, Resource
- Acquisition, CCB Creation, Host Adapter
- Initialization, or Target Device Inquiry, so
- remove Host Adapter from the list of registered
- BusLogic Host Adapters, destroy the CCBs, Release
- the System Resources, and Unregister the SCSI
- Host.
- */
- blogic_destroy_ccbs(myadapter);
- blogic_relres(myadapter);
- list_del(&myadapter->host_list);
- scsi_host_put(host);
- ret = -ENODEV;
- }
- }
- kfree(adapter);
- kfree(blogic_probeinfo_list);
- blogic_probeinfo_list = NULL;
- return ret;
-}
-
-
-/*
- blogic_deladapter releases all resources previously acquired to
- support a specific Host Adapter, including the I/O Address range, and
- unregisters the BusLogic Host Adapter.
-*/
-
-static int __exit blogic_deladapter(struct blogic_adapter *adapter)
-{
- struct Scsi_Host *host = adapter->scsi_host;
-
- scsi_remove_host(host);
-
- /*
- FlashPoint Host Adapters must first be released by the FlashPoint
- SCCB Manager.
- */
- if (blogic_flashpoint_type(adapter))
- FlashPoint_ReleaseHostAdapter(adapter->cardhandle);
- /*
- Destroy the CCBs and release any system resources acquired to
- support Host Adapter.
- */
- blogic_destroy_ccbs(adapter);
- blogic_relres(adapter);
- /*
- Release usage of the I/O Address range.
- */
- release_region(adapter->io_addr, adapter->addr_count);
- /*
- Remove Host Adapter from the list of registered BusLogic
- Host Adapters.
- */
- list_del(&adapter->host_list);
-
- scsi_host_put(host);
- return 0;
-}
-
-
-/*
- blogic_qcompleted_ccb queues CCB for completion processing.
-*/
-
-static void blogic_qcompleted_ccb(struct blogic_ccb *ccb)
-{
- struct blogic_adapter *adapter = ccb->adapter;
-
- ccb->status = BLOGIC_CCB_COMPLETE;
- ccb->next = NULL;
- if (adapter->firstccb == NULL) {
- adapter->firstccb = ccb;
- adapter->lastccb = ccb;
- } else {
- adapter->lastccb->next = ccb;
- adapter->lastccb = ccb;
- }
- adapter->active_cmds[ccb->tgt_id]--;
-}
-
-
-/*
- blogic_resultcode computes a SCSI Subsystem Result Code from
- the Host Adapter Status and Target Device Status.
-*/
-
-static int blogic_resultcode(struct blogic_adapter *adapter,
- enum blogic_adapter_status adapter_status,
- enum blogic_tgt_status tgt_status)
-{
- int hoststatus;
-
- switch (adapter_status) {
- case BLOGIC_CMD_CMPLT_NORMAL:
- case BLOGIC_LINK_CMD_CMPLT:
- case BLOGIC_LINK_CMD_CMPLT_FLAG:
- hoststatus = DID_OK;
- break;
- case BLOGIC_SELECT_TIMEOUT:
- hoststatus = DID_TIME_OUT;
- break;
- case BLOGIC_INVALID_OUTBOX_CODE:
- case BLOGIC_INVALID_CMD_CODE:
- case BLOGIC_BAD_CMD_PARAM:
- blogic_warn("BusLogic Driver Protocol Error 0x%02X\n",
- adapter, adapter_status);
- fallthrough;
- case BLOGIC_DATA_UNDERRUN:
- case BLOGIC_DATA_OVERRUN:
- case BLOGIC_NOEXPECT_BUSFREE:
- case BLOGIC_LINKCCB_BADLUN:
- case BLOGIC_AUTOREQSENSE_FAIL:
- case BLOGIC_TAGQUEUE_REJECT:
- case BLOGIC_BAD_MSG_RCVD:
- case BLOGIC_HW_FAIL:
- case BLOGIC_BAD_RECONNECT:
- case BLOGIC_ABRT_QUEUE:
- case BLOGIC_ADAPTER_SW_ERROR:
- case BLOGIC_HW_TIMEOUT:
- case BLOGIC_PARITY_ERR:
- hoststatus = DID_ERROR;
- break;
- case BLOGIC_INVALID_BUSPHASE:
- case BLOGIC_NORESPONSE_TO_ATN:
- case BLOGIC_HW_RESET:
- case BLOGIC_RST_FROM_OTHERDEV:
- case BLOGIC_HW_BDR:
- hoststatus = DID_RESET;
- break;
- default:
- blogic_warn("Unknown Host Adapter Status 0x%02X\n", adapter,
- adapter_status);
- hoststatus = DID_ERROR;
- break;
- }
- return (hoststatus << 16) | tgt_status;
-}
-
-
-/*
- blogic_scan_inbox scans the Incoming Mailboxes saving any
- Incoming Mailbox entries for completion processing.
-*/
-
-static void blogic_scan_inbox(struct blogic_adapter *adapter)
-{
- /*
- Scan through the Incoming Mailboxes in Strict Round Robin
- fashion, saving any completed CCBs for further processing. It
- is essential that for each CCB and SCSI Command issued, command
- completion processing is performed exactly once. Therefore,
- only Incoming Mailboxes with completion code Command Completed
- Without Error, Command Completed With Error, or Command Aborted
- At Host Request are saved for completion processing. When an
- Incoming Mailbox has a completion code of Aborted Command Not
- Found, the CCB had already completed or been aborted before the
- current Abort request was processed, and so completion processing
- has already occurred and no further action should be taken.
- */
- struct blogic_inbox *next_inbox = adapter->next_inbox;
- enum blogic_cmplt_code comp_code;
-
- while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) {
- /*
- We are only allowed to do this because we limit our
- architectures we run on to machines where bus_to_virt(
- actually works. There *needs* to be a dma_addr_to_virt()
- in the new PCI DMA mapping interface to replace
- bus_to_virt() or else this code is going to become very
- innefficient.
- */
- struct blogic_ccb *ccb =
- (struct blogic_ccb *) bus_to_virt(next_inbox->ccb);
- if (comp_code != BLOGIC_CMD_NOTFOUND) {
- if (ccb->status == BLOGIC_CCB_ACTIVE ||
- ccb->status == BLOGIC_CCB_RESET) {
- /*
- Save the Completion Code for this CCB and
- queue the CCB for completion processing.
- */
- ccb->comp_code = comp_code;
- blogic_qcompleted_ccb(ccb);
- } else {
- /*
- If a CCB ever appears in an Incoming Mailbox
- and is not marked as status Active or Reset,
- then there is most likely a bug in
- the Host Adapter firmware.
- */
- blogic_warn("Illegal CCB #%ld status %d in Incoming Mailbox\n", adapter, ccb->serial, ccb->status);
- }
- }
- next_inbox->comp_code = BLOGIC_INBOX_FREE;
- if (++next_inbox > adapter->last_inbox)
- next_inbox = adapter->first_inbox;
- }
- adapter->next_inbox = next_inbox;
-}
-
-
-/*
- blogic_process_ccbs iterates over the completed CCBs for Host
- Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
- calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock
- should already have been acquired by the caller.
-*/
-
-static void blogic_process_ccbs(struct blogic_adapter *adapter)
-{
- if (adapter->processing_ccbs)
- return;
- adapter->processing_ccbs = true;
- while (adapter->firstccb != NULL) {
- struct blogic_ccb *ccb = adapter->firstccb;
- struct scsi_cmnd *command = ccb->command;
- adapter->firstccb = ccb->next;
- if (adapter->firstccb == NULL)
- adapter->lastccb = NULL;
- /*
- Process the Completed CCB.
- */
- if (ccb->opcode == BLOGIC_BDR) {
- int tgt_id = ccb->tgt_id;
-
- blogic_warn("Bus Device Reset CCB #%ld to Target %d Completed\n", adapter, ccb->serial, tgt_id);
- blogic_inc_count(&adapter->tgt_stats[tgt_id].bdr_done);
- adapter->tgt_flags[tgt_id].tagq_active = false;
- adapter->cmds_since_rst[tgt_id] = 0;
- adapter->last_resetdone[tgt_id] = jiffies;
- /*
- Place CCB back on the Host Adapter's free list.
- */
- blogic_dealloc_ccb(ccb, 1);
-#if 0 /* this needs to be redone different for new EH */
- /*
- Bus Device Reset CCBs have the command field
- non-NULL only when a Bus Device Reset was requested
- for a command that did not have a currently active
- CCB in the Host Adapter (i.e., a Synchronous Bus
- Device Reset), and hence would not have its
- Completion Routine called otherwise.
- */
- while (command != NULL) {
- struct scsi_cmnd *nxt_cmd =
- command->reset_chain;
- command->reset_chain = NULL;
- command->result = DID_RESET << 16;
- scsi_done(command);
- command = nxt_cmd;
- }
-#endif
- /*
- Iterate over the CCBs for this Host Adapter
- performing completion processing for any CCBs
- marked as Reset for this Target.
- */
- for (ccb = adapter->all_ccbs; ccb != NULL;
- ccb = ccb->next_all)
- if (ccb->status == BLOGIC_CCB_RESET &&
- ccb->tgt_id == tgt_id) {
- command = ccb->command;
- blogic_dealloc_ccb(ccb, 1);
- adapter->active_cmds[tgt_id]--;
- command->result = DID_RESET << 16;
- scsi_done(command);
- }
- adapter->bdr_pend[tgt_id] = NULL;
- } else {
- /*
- Translate the Completion Code, Host Adapter Status,
- and Target Device Status into a SCSI Subsystem
- Result Code.
- */
- switch (ccb->comp_code) {
- case BLOGIC_INBOX_FREE:
- case BLOGIC_CMD_NOTFOUND:
- case BLOGIC_INVALID_CCB:
- blogic_warn("CCB #%ld to Target %d Impossible State\n", adapter, ccb->serial, ccb->tgt_id);
- break;
- case BLOGIC_CMD_COMPLETE_GOOD:
- adapter->tgt_stats[ccb->tgt_id]
- .cmds_complete++;
- adapter->tgt_flags[ccb->tgt_id]
- .cmd_good = true;
- command->result = DID_OK << 16;
- break;
- case BLOGIC_CMD_ABORT_BY_HOST:
- blogic_warn("CCB #%ld to Target %d Aborted\n",
- adapter, ccb->serial, ccb->tgt_id);
- blogic_inc_count(&adapter->tgt_stats[ccb->tgt_id].aborts_done);
- command->result = DID_ABORT << 16;
- break;
- case BLOGIC_CMD_COMPLETE_ERROR:
- command->result = blogic_resultcode(adapter,
- ccb->adapter_status, ccb->tgt_status);
- if (ccb->adapter_status != BLOGIC_SELECT_TIMEOUT) {
- adapter->tgt_stats[ccb->tgt_id]
- .cmds_complete++;
- if (blogic_global_options.trace_err) {
- int i;
- blogic_notice("CCB #%ld Target %d: Result %X Host "
- "Adapter Status %02X Target Status %02X\n", adapter, ccb->serial, ccb->tgt_id, command->result, ccb->adapter_status, ccb->tgt_status);
- blogic_notice("CDB ", adapter);
- for (i = 0; i < ccb->cdblen; i++)
- blogic_notice(" %02X", adapter, ccb->cdb[i]);
- blogic_notice("\n", adapter);
- blogic_notice("Sense ", adapter);
- for (i = 0; i < ccb->sense_datalen; i++)
- blogic_notice(" %02X", adapter, command->sense_buffer[i]);
- blogic_notice("\n", adapter);
- }
- }
- break;
- }
- /*
- When an INQUIRY command completes normally, save the
- CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
- Wide Data Transfers Supported) bits.
- */
- if (ccb->cdb[0] == INQUIRY && ccb->cdb[1] == 0 &&
- ccb->adapter_status == BLOGIC_CMD_CMPLT_NORMAL) {
- struct blogic_tgt_flags *tgt_flags =
- &adapter->tgt_flags[ccb->tgt_id];
- struct scsi_inquiry *inquiry =
- (struct scsi_inquiry *) scsi_sglist(command);
- tgt_flags->tgt_exists = true;
- tgt_flags->tagq_ok = inquiry->CmdQue;
- tgt_flags->wide_ok = inquiry->WBus16;
- }
- /*
- Place CCB back on the Host Adapter's free list.
- */
- blogic_dealloc_ccb(ccb, 1);
- /*
- Call the SCSI Command Completion Routine.
- */
- scsi_done(command);
- }
- }
- adapter->processing_ccbs = false;
-}
-
-
-/*
- blogic_inthandler handles hardware interrupts from BusLogic Host
- Adapters.
-*/
-
-static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
-{
- struct blogic_adapter *adapter = (struct blogic_adapter *) devid;
- unsigned long processor_flag;
- /*
- Acquire exclusive access to Host Adapter.
- */
- spin_lock_irqsave(adapter->scsi_host->host_lock, processor_flag);
- /*
- Handle Interrupts appropriately for each Host Adapter type.
- */
- if (blogic_multimaster_type(adapter)) {
- union blogic_int_reg intreg;
- /*
- Read the Host Adapter Interrupt Register.
- */
- intreg.all = blogic_rdint(adapter);
- if (intreg.ir.int_valid) {
- /*
- Acknowledge the interrupt and reset the Host Adapter
- Interrupt Register.
- */
- blogic_intreset(adapter);
- /*
- Process valid External SCSI Bus Reset and Incoming
- Mailbox Loaded Interrupts. Command Complete
- Interrupts are noted, and Outgoing Mailbox Available
- Interrupts are ignored, as they are never enabled.
- */
- if (intreg.ir.ext_busreset)
- adapter->adapter_extreset = true;
- else if (intreg.ir.mailin_loaded)
- blogic_scan_inbox(adapter);
- else if (intreg.ir.cmd_complete)
- adapter->adapter_cmd_complete = true;
- }
- } else {
- /*
- Check if there is a pending interrupt for this Host Adapter.
- */
- if (FlashPoint_InterruptPending(adapter->cardhandle))
- switch (FlashPoint_HandleInterrupt(adapter->cardhandle)) {
- case FPOINT_NORMAL_INT:
- break;
- case FPOINT_EXT_RESET:
- adapter->adapter_extreset = true;
- break;
- case FPOINT_INTERN_ERR:
- blogic_warn("Internal FlashPoint Error detected - Resetting Host Adapter\n", adapter);
- adapter->adapter_intern_err = true;
- break;
- }
- }
- /*
- Process any completed CCBs.
- */
- if (adapter->firstccb != NULL)
- blogic_process_ccbs(adapter);
- /*
- Reset the Host Adapter if requested.
- */
- if (adapter->adapter_extreset) {
- blogic_warn("Resetting %s due to External SCSI Bus Reset\n", adapter, adapter->full_model);
- blogic_inc_count(&adapter->ext_resets);
- blogic_resetadapter(adapter, false);
- adapter->adapter_extreset = false;
- } else if (adapter->adapter_intern_err) {
- blogic_warn("Resetting %s due to Host Adapter Internal Error\n", adapter, adapter->full_model);
- blogic_inc_count(&adapter->adapter_intern_errors);
- blogic_resetadapter(adapter, true);
- adapter->adapter_intern_err = false;
- }
- /*
- Release exclusive access to Host Adapter.
- */
- spin_unlock_irqrestore(adapter->scsi_host->host_lock, processor_flag);
- return IRQ_HANDLED;
-}
-
-
-/*
- blogic_write_outbox places CCB and Action Code into an Outgoing
- Mailbox for execution by Host Adapter. The Host Adapter's Lock should
- already have been acquired by the caller.
-*/
-
-static bool blogic_write_outbox(struct blogic_adapter *adapter,
- enum blogic_action action, struct blogic_ccb *ccb)
-{
- struct blogic_outbox *next_outbox;
-
- next_outbox = adapter->next_outbox;
- if (next_outbox->action == BLOGIC_OUTBOX_FREE) {
- ccb->status = BLOGIC_CCB_ACTIVE;
- /*
- The CCB field must be written before the Action Code field
- since the Host Adapter is operating asynchronously and the
- locking code does not protect against simultaneous access
- by the Host Adapter.
- */
- next_outbox->ccb = ccb->dma_handle;
- next_outbox->action = action;
- blogic_execmbox(adapter);
- if (++next_outbox > adapter->last_outbox)
- next_outbox = adapter->first_outbox;
- adapter->next_outbox = next_outbox;
- if (action == BLOGIC_MBOX_START) {
- adapter->active_cmds[ccb->tgt_id]++;
- if (ccb->opcode != BLOGIC_BDR)
- adapter->tgt_stats[ccb->tgt_id].cmds_tried++;
- }
- return true;
- }
- return false;
-}
-
-/* Error Handling (EH) support */
-
-static int blogic_hostreset(struct scsi_cmnd *SCpnt)
-{
- struct blogic_adapter *adapter =
- (struct blogic_adapter *) SCpnt->device->host->hostdata;
-
- unsigned int id = SCpnt->device->id;
- struct blogic_tgt_stats *stats = &adapter->tgt_stats[id];
- int rc;
-
- spin_lock_irq(SCpnt->device->host->host_lock);
-
- blogic_inc_count(&stats->adapter_reset_req);
-
- rc = blogic_resetadapter(adapter, false);
- spin_unlock_irq(SCpnt->device->host->host_lock);
- return rc;
-}
-
-/*
- blogic_qcmd creates a CCB for Command and places it into an
- Outgoing Mailbox for execution by the associated Host Adapter.
-*/
-
-static int blogic_qcmd_lck(struct scsi_cmnd *command)
-{
- void (*comp_cb)(struct scsi_cmnd *) = scsi_done;
- struct blogic_adapter *adapter =
- (struct blogic_adapter *) command->device->host->hostdata;
- struct blogic_tgt_flags *tgt_flags =
- &adapter->tgt_flags[command->device->id];
- struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
- unsigned char *cdb = command->cmnd;
- int cdblen = command->cmd_len;
- int tgt_id = command->device->id;
- int lun = command->device->lun;
- int buflen = scsi_bufflen(command);
- int count;
- struct blogic_ccb *ccb;
- dma_addr_t sense_buf;
-
- /*
- SCSI REQUEST_SENSE commands will be executed automatically by the
- Host Adapter for any errors, so they should not be executed
- explicitly unless the Sense Data is zero indicating that no error
- occurred.
- */
- if (cdb[0] == REQUEST_SENSE && command->sense_buffer[0] != 0) {
- command->result = DID_OK << 16;
- comp_cb(command);
- return 0;
- }
- /*
- Allocate a CCB from the Host Adapter's free list. In the unlikely
- event that there are none available and memory allocation fails,
- wait 1 second and try again. If that fails, the Host Adapter is
- probably hung so signal an error as a Host Adapter Hard Reset
- should be initiated soon.
- */
- ccb = blogic_alloc_ccb(adapter);
- if (ccb == NULL) {
- spin_unlock_irq(adapter->scsi_host->host_lock);
- blogic_delay(1);
- spin_lock_irq(adapter->scsi_host->host_lock);
- ccb = blogic_alloc_ccb(adapter);
- if (ccb == NULL) {
- command->result = DID_ERROR << 16;
- comp_cb(command);
- return 0;
- }
- }
-
- /*
- Initialize the fields in the BusLogic Command Control Block (CCB).
- */
- count = scsi_dma_map(command);
- BUG_ON(count < 0);
- if (count) {
- struct scatterlist *sg;
- int i;
-
- ccb->opcode = BLOGIC_INITIATOR_CCB_SG;
- ccb->datalen = count * sizeof(struct blogic_sg_seg);
- if (blogic_multimaster_type(adapter))
- ccb->data = (unsigned int) ccb->dma_handle +
- ((unsigned long) &ccb->sglist -
- (unsigned long) ccb);
- else
- ccb->data = virt_to_32bit_virt(ccb->sglist);
-
- scsi_for_each_sg(command, sg, count, i) {
- ccb->sglist[i].segbytes = sg_dma_len(sg);
- ccb->sglist[i].segdata = sg_dma_address(sg);
- }
- } else if (!count) {
- ccb->opcode = BLOGIC_INITIATOR_CCB;
- ccb->datalen = buflen;
- ccb->data = 0;
- }
-
- switch (cdb[0]) {
- case READ_6:
- case READ_10:
- ccb->datadir = BLOGIC_DATAIN_CHECKED;
- tgt_stats[tgt_id].read_cmds++;
- blogic_addcount(&tgt_stats[tgt_id].bytesread, buflen);
- blogic_incszbucket(tgt_stats[tgt_id].read_sz_buckets, buflen);
- break;
- case WRITE_6:
- case WRITE_10:
- ccb->datadir = BLOGIC_DATAOUT_CHECKED;
- tgt_stats[tgt_id].write_cmds++;
- blogic_addcount(&tgt_stats[tgt_id].byteswritten, buflen);
- blogic_incszbucket(tgt_stats[tgt_id].write_sz_buckets, buflen);
- break;
- default:
- ccb->datadir = BLOGIC_UNCHECKED_TX;
- break;
- }
- ccb->cdblen = cdblen;
- ccb->adapter_status = 0;
- ccb->tgt_status = 0;
- ccb->tgt_id = tgt_id;
- ccb->lun = lun;
- ccb->tag_enable = false;
- ccb->legacytag_enable = false;
- /*
- BusLogic recommends that after a Reset the first couple of
- commands that are sent to a Target Device be sent in a non
- Tagged Queue fashion so that the Host Adapter and Target Device
- can establish Synchronous and Wide Transfer before Queue Tag
- messages can interfere with the Synchronous and Wide Negotiation
- messages. By waiting to enable Tagged Queuing until after the
- first BLOGIC_MAX_TAG_DEPTH commands have been queued, it is
- assured that after a Reset any pending commands are requeued
- before Tagged Queuing is enabled and that the Tagged Queuing
- message will not occur while the partition table is being printed.
- In addition, some devices do not properly handle the transition
- from non-tagged to tagged commands, so it is necessary to wait
- until there are no pending commands for a target device
- before queuing tagged commands.
- */
- if (adapter->cmds_since_rst[tgt_id]++ >= BLOGIC_MAX_TAG_DEPTH &&
- !tgt_flags->tagq_active &&
- adapter->active_cmds[tgt_id] == 0
- && tgt_flags->tagq_ok &&
- (adapter->tagq_ok & (1 << tgt_id))) {
- tgt_flags->tagq_active = true;
- blogic_notice("Tagged Queuing now active for Target %d\n",
- adapter, tgt_id);
- }
- if (tgt_flags->tagq_active) {
- enum blogic_queuetag queuetag = BLOGIC_SIMPLETAG;
- /*
- When using Tagged Queuing with Simple Queue Tags, it
- appears that disk drive controllers do not guarantee that
- a queued command will not remain in a disconnected state
- indefinitely if commands that read or write nearer the
- head position continue to arrive without interruption.
- Therefore, for each Target Device this driver keeps track
- of the last time either the queue was empty or an Ordered
- Queue Tag was issued. If more than 4 seconds (one fifth
- of the 20 second disk timeout) have elapsed since this
- last sequence point, this command will be issued with an
- Ordered Queue Tag rather than a Simple Queue Tag, which
- forces the Target Device to complete all previously
- queued commands before this command may be executed.
- */
- if (adapter->active_cmds[tgt_id] == 0)
- adapter->last_seqpoint[tgt_id] = jiffies;
- else if (time_after(jiffies,
- adapter->last_seqpoint[tgt_id] + 4 * HZ)) {
- adapter->last_seqpoint[tgt_id] = jiffies;
- queuetag = BLOGIC_ORDEREDTAG;
- }
- if (adapter->ext_lun) {
- ccb->tag_enable = true;
- ccb->queuetag = queuetag;
- } else {
- ccb->legacytag_enable = true;
- ccb->legacy_tag = queuetag;
- }
- }
- memcpy(ccb->cdb, cdb, cdblen);
- ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
- ccb->command = command;
- sense_buf = dma_map_single(&adapter->pci_device->dev,
- command->sense_buffer, ccb->sense_datalen,
- DMA_FROM_DEVICE);
- if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
- blogic_err("DMA mapping for sense data buffer failed\n",
- adapter);
- blogic_dealloc_ccb(ccb, 0);
- return SCSI_MLQUEUE_HOST_BUSY;
- }
- ccb->sensedata = sense_buf;
- if (blogic_multimaster_type(adapter)) {
- /*
- Place the CCB in an Outgoing Mailbox. The higher levels
- of the SCSI Subsystem should not attempt to queue more
- commands than can be placed in Outgoing Mailboxes, so
- there should always be one free. In the unlikely event
- that there are none available, wait 1 second and try
- again. If that fails, the Host Adapter is probably hung
- so signal an error as a Host Adapter Hard Reset should
- be initiated soon.
- */
- if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
- spin_unlock_irq(adapter->scsi_host->host_lock);
- blogic_warn("Unable to write Outgoing Mailbox - Pausing for 1 second\n", adapter);
- blogic_delay(1);
- spin_lock_irq(adapter->scsi_host->host_lock);
- if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
- ccb)) {
- blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter);
- blogic_dealloc_ccb(ccb, 1);
- command->result = DID_ERROR << 16;
- scsi_done(command);
- }
- }
- } else {
- /*
- Call the FlashPoint SCCB Manager to start execution of
- the CCB.
- */
- ccb->status = BLOGIC_CCB_ACTIVE;
- adapter->active_cmds[tgt_id]++;
- tgt_stats[tgt_id].cmds_tried++;
- FlashPoint_StartCCB(adapter->cardhandle, ccb);
- /*
- The Command may have already completed and
- blogic_qcompleted_ccb been called, or it may still be
- pending.
- */
- if (ccb->status == BLOGIC_CCB_COMPLETE)
- blogic_process_ccbs(adapter);
- }
- return 0;
-}
-
-static DEF_SCSI_QCMD(blogic_qcmd)
-
-#if 0
-/*
- blogic_abort aborts Command if possible.
-*/
-
-static int blogic_abort(struct scsi_cmnd *command)
-{
- struct blogic_adapter *adapter =
- (struct blogic_adapter *) command->device->host->hostdata;
-
- int tgt_id = command->device->id;
- struct blogic_ccb *ccb;
- blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request);
-
- /*
- Attempt to find an Active CCB for this Command. If no Active
- CCB for this Command is found, then no Abort is necessary.
- */
- for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
- if (ccb->command == command)
- break;
- if (ccb == NULL) {
- blogic_warn("Unable to Abort Command to Target %d - No CCB Found\n", adapter, tgt_id);
- return SUCCESS;
- } else if (ccb->status == BLOGIC_CCB_COMPLETE) {
- blogic_warn("Unable to Abort Command to Target %d - CCB Completed\n", adapter, tgt_id);
- return SUCCESS;
- } else if (ccb->status == BLOGIC_CCB_RESET) {
- blogic_warn("Unable to Abort Command to Target %d - CCB Reset\n", adapter, tgt_id);
- return SUCCESS;
- }
- if (blogic_multimaster_type(adapter)) {
- /*
- Attempt to Abort this CCB. MultiMaster Firmware versions
- prior to 5.xx do not generate Abort Tag messages, but only
- generate the non-tagged Abort message. Since non-tagged
- commands are not sent by the Host Adapter until the queue
- of outstanding tagged commands has completed, and the
- Abort message is treated as a non-tagged command, it is
- effectively impossible to abort commands when Tagged
- Queuing is active. Firmware version 5.xx does generate
- Abort Tag messages, so it is possible to abort commands
- when Tagged Queuing is active.
- */
- if (adapter->tgt_flags[tgt_id].tagq_active &&
- adapter->fw_ver[0] < '5') {
- blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id);
- return FAILURE;
- } else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT,
- ccb)) {
- blogic_warn("Aborting CCB #%ld to Target %d\n",
- adapter, ccb->serial, tgt_id);
- blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
- return SUCCESS;
- } else {
- blogic_warn("Unable to Abort CCB #%ld to Target %d - No Outgoing Mailboxes\n", adapter, ccb->serial, tgt_id);
- return FAILURE;
- }
- } else {
- /*
- Call the FlashPoint SCCB Manager to abort execution of
- the CCB.
- */
- blogic_warn("Aborting CCB #%ld to Target %d\n", adapter,
- ccb->serial, tgt_id);
- blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
- FlashPoint_AbortCCB(adapter->cardhandle, ccb);
- /*
- The Abort may have already been completed and
- blogic_qcompleted_ccb been called, or it
- may still be pending.
- */
- if (ccb->status == BLOGIC_CCB_COMPLETE)
- blogic_process_ccbs(adapter);
- return SUCCESS;
- }
- return SUCCESS;
-}
-
-#endif
-/*
- blogic_resetadapter resets Host Adapter if possible, marking all
- currently executing SCSI Commands as having been Reset.
-*/
-
-static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
-{
- struct blogic_ccb *ccb;
- int tgt_id;
-
- /*
- * Attempt to Reset and Reinitialize the Host Adapter.
- */
-
- if (!(blogic_hwreset(adapter, hard_reset) &&
- blogic_initadapter(adapter))) {
- blogic_err("Resetting %s Failed\n", adapter,
- adapter->full_model);
- return FAILURE;
- }
-
- /*
- * Deallocate all currently executing CCBs.
- */
-
- for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
- if (ccb->status == BLOGIC_CCB_ACTIVE)
- blogic_dealloc_ccb(ccb, 1);
- /*
- * Wait a few seconds between the Host Adapter Hard Reset which
- * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
- * SCSI devices get confused if they receive SCSI Commands too soon
- * after a SCSI Bus Reset.
- */
-
- if (hard_reset) {
- spin_unlock_irq(adapter->scsi_host->host_lock);
- blogic_delay(adapter->bus_settle_time);
- spin_lock_irq(adapter->scsi_host->host_lock);
- }
-
- for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
- adapter->last_resettried[tgt_id] = jiffies;
- adapter->last_resetdone[tgt_id] = jiffies;
- }
- return SUCCESS;
-}
-
-/*
- blogic_diskparam returns the Heads/Sectors/Cylinders BIOS Disk
- Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
- the appropriate number of cylinders so as not to exceed drive capacity. In
- order for disks equal to or larger than 1 GB to be addressable by the BIOS
- without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
- may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
- series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
- series MultiMaster Host Adapters. With Extended Translation enabled, drives
- between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
- heads and 32 sectors, and drives above 2 GB inclusive are given a disk
- geometry of 255 heads and 63 sectors. However, if the BIOS detects that the
- Extended Translation setting does not match the geometry in the partition
- table, then the translation inferred from the partition table will be used by
- the BIOS, and a warning may be displayed.
-*/
-
-static int blogic_diskparam(struct scsi_device *sdev, struct block_device *dev,
- sector_t capacity, int *params)
-{
- struct blogic_adapter *adapter =
- (struct blogic_adapter *) sdev->host->hostdata;
- struct bios_diskparam *diskparam = (struct bios_diskparam *) params;
- unsigned char *buf;
-
- if (adapter->ext_trans_enable && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */) {
- if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */) {
- diskparam->heads = 255;
- diskparam->sectors = 63;
- } else {
- diskparam->heads = 128;
- diskparam->sectors = 32;
- }
- } else {
- diskparam->heads = 64;
- diskparam->sectors = 32;
- }
- diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
- buf = scsi_bios_ptable(dev);
- if (buf == NULL)
- return 0;
- /*
- If the boot sector partition table flag is valid, search for
- a partition table entry whose end_head matches one of the
- standard BusLogic geometry translations (64/32, 128/32, or 255/63).
- */
- if (*(unsigned short *) (buf + 64) == MSDOS_LABEL_MAGIC) {
- struct msdos_partition *part1_entry =
- (struct msdos_partition *)buf;
- struct msdos_partition *part_entry = part1_entry;
- int saved_cyl = diskparam->cylinders, part_no;
- unsigned char part_end_head = 0, part_end_sector = 0;
-
- for (part_no = 0; part_no < 4; part_no++) {
- part_end_head = part_entry->end_head;
- part_end_sector = part_entry->end_sector & 0x3F;
- if (part_end_head == 64 - 1) {
- diskparam->heads = 64;
- diskparam->sectors = 32;
- break;
- } else if (part_end_head == 128 - 1) {
- diskparam->heads = 128;
- diskparam->sectors = 32;
- break;
- } else if (part_end_head == 255 - 1) {
- diskparam->heads = 255;
- diskparam->sectors = 63;
- break;
- }
- part_entry++;
- }
- if (part_no == 4) {
- part_end_head = part1_entry->end_head;
- part_end_sector = part1_entry->end_sector & 0x3F;
- }
- diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
- if (part_no < 4 && part_end_sector == diskparam->sectors) {
- if (diskparam->cylinders != saved_cyl)
- blogic_warn("Adopting Geometry %d/%d from Partition Table\n", adapter, diskparam->heads, diskparam->sectors);
- } else if (part_end_head > 0 || part_end_sector > 0) {
- blogic_warn("Warning: Partition Table appears to have Geometry %d/%d which is\n", adapter, part_end_head + 1, part_end_sector);
- blogic_warn("not compatible with current BusLogic Host Adapter Geometry %d/%d\n", adapter, diskparam->heads, diskparam->sectors);
- }
- }
- kfree(buf);
- return 0;
-}
-
-
-/*
- BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
-*/
-
-static int blogic_write_info(struct Scsi_Host *shost, char *procbuf,
- int bytes_avail)
-{
- struct blogic_adapter *adapter =
- (struct blogic_adapter *) shost->hostdata;
- struct blogic_tgt_stats *tgt_stats;
-
- tgt_stats = adapter->tgt_stats;
- adapter->ext_resets = 0;
- adapter->adapter_intern_errors = 0;
- memset(tgt_stats, 0, BLOGIC_MAXDEV * sizeof(struct blogic_tgt_stats));
- return 0;
-}
-
-static int blogic_show_info(struct seq_file *m, struct Scsi_Host *shost)
-{
- struct blogic_adapter *adapter = (struct blogic_adapter *) shost->hostdata;
- struct blogic_tgt_stats *tgt_stats;
- int tgt;
-
- tgt_stats = adapter->tgt_stats;
- seq_write(m, adapter->msgbuf, adapter->msgbuflen);
- seq_printf(m, "\n\
-Current Driver Queue Depth: %d\n\
-Currently Allocated CCBs: %d\n", adapter->drvr_qdepth, adapter->alloc_ccbs);
- seq_puts(m, "\n\n\
- DATA TRANSFER STATISTICS\n\
-\n\
-Target Tagged Queuing Queue Depth Active Attempted Completed\n\
-====== ============== =========== ====== ========= =========\n");
- for (tgt = 0; tgt < adapter->maxdev; tgt++) {
- struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
- if (!tgt_flags->tgt_exists)
- continue;
- seq_printf(m, " %2d %s", tgt, (tgt_flags->tagq_ok ? (tgt_flags->tagq_active ? " Active" : (adapter->tagq_ok & (1 << tgt)
- ? " Permitted" : " Disabled"))
- : "Not Supported"));
- seq_printf(m,
- " %3d %3u %9u %9u\n", adapter->qdepth[tgt], adapter->active_cmds[tgt], tgt_stats[tgt].cmds_tried, tgt_stats[tgt].cmds_complete);
- }
- seq_puts(m, "\n\
-Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
-====== ============= ============== =================== ===================\n");
- for (tgt = 0; tgt < adapter->maxdev; tgt++) {
- struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
- if (!tgt_flags->tgt_exists)
- continue;
- seq_printf(m, " %2d %9u %9u", tgt, tgt_stats[tgt].read_cmds, tgt_stats[tgt].write_cmds);
- if (tgt_stats[tgt].bytesread.billions > 0)
- seq_printf(m, " %9u%09u", tgt_stats[tgt].bytesread.billions, tgt_stats[tgt].bytesread.units);
- else
- seq_printf(m, " %9u", tgt_stats[tgt].bytesread.units);
- if (tgt_stats[tgt].byteswritten.billions > 0)
- seq_printf(m, " %9u%09u\n", tgt_stats[tgt].byteswritten.billions, tgt_stats[tgt].byteswritten.units);
- else
- seq_printf(m, " %9u\n", tgt_stats[tgt].byteswritten.units);
- }
- seq_puts(m, "\n\
-Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
-====== ======= ========= ========= ========= ========= =========\n");
- for (tgt = 0; tgt < adapter->maxdev; tgt++) {
- struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
- if (!tgt_flags->tgt_exists)
- continue;
- seq_printf(m,
- " %2d Read %9u %9u %9u %9u %9u\n", tgt,
- tgt_stats[tgt].read_sz_buckets[0],
- tgt_stats[tgt].read_sz_buckets[1], tgt_stats[tgt].read_sz_buckets[2], tgt_stats[tgt].read_sz_buckets[3], tgt_stats[tgt].read_sz_buckets[4]);
- seq_printf(m,
- " %2d Write %9u %9u %9u %9u %9u\n", tgt,
- tgt_stats[tgt].write_sz_buckets[0],
- tgt_stats[tgt].write_sz_buckets[1], tgt_stats[tgt].write_sz_buckets[2], tgt_stats[tgt].write_sz_buckets[3], tgt_stats[tgt].write_sz_buckets[4]);
- }
- seq_puts(m, "\n\
-Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
-====== ======= ========= ========= ========= ========= =========\n");
- for (tgt = 0; tgt < adapter->maxdev; tgt++) {
- struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
- if (!tgt_flags->tgt_exists)
- continue;
- seq_printf(m,
- " %2d Read %9u %9u %9u %9u %9u\n", tgt,
- tgt_stats[tgt].read_sz_buckets[5],
- tgt_stats[tgt].read_sz_buckets[6], tgt_stats[tgt].read_sz_buckets[7], tgt_stats[tgt].read_sz_buckets[8], tgt_stats[tgt].read_sz_buckets[9]);
- seq_printf(m,
- " %2d Write %9u %9u %9u %9u %9u\n", tgt,
- tgt_stats[tgt].write_sz_buckets[5],
- tgt_stats[tgt].write_sz_buckets[6], tgt_stats[tgt].write_sz_buckets[7], tgt_stats[tgt].write_sz_buckets[8], tgt_stats[tgt].write_sz_buckets[9]);
- }
- seq_puts(m, "\n\n\
- ERROR RECOVERY STATISTICS\n\
-\n\
- Command Aborts Bus Device Resets Host Adapter Resets\n\
-Target Requested Completed Requested Completed Requested Completed\n\
- ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
-====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
- for (tgt = 0; tgt < adapter->maxdev; tgt++) {
- struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
- if (!tgt_flags->tgt_exists)
- continue;
- seq_printf(m, " %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n",
- tgt, tgt_stats[tgt].aborts_request,
- tgt_stats[tgt].aborts_tried,
- tgt_stats[tgt].aborts_done,
- tgt_stats[tgt].bdr_request,
- tgt_stats[tgt].bdr_tried,
- tgt_stats[tgt].bdr_done,
- tgt_stats[tgt].adapter_reset_req,
- tgt_stats[tgt].adapter_reset_attempt,
- tgt_stats[tgt].adapter_reset_done);
- }
- seq_printf(m, "\nExternal Host Adapter Resets: %d\n", adapter->ext_resets);
- seq_printf(m, "Host Adapter Internal Errors: %d\n", adapter->adapter_intern_errors);
- return 0;
-}
-
-
-/*
- blogic_msg prints Driver Messages.
-*/
-__printf(2, 4)
-static void blogic_msg(enum blogic_msglevel msglevel, char *fmt,
- struct blogic_adapter *adapter, ...)
-{
- static char buf[BLOGIC_LINEBUF_SIZE];
- static bool begin = true;
- va_list args;
- int len = 0;
-
- va_start(args, adapter);
- len = vscnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
- if (msglevel == BLOGIC_ANNOUNCE_LEVEL) {
- static int msglines = 0;
- strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
- adapter->msgbuflen += len;
- if (++msglines <= 2)
- printk("%sscsi: %s", blogic_msglevelmap[msglevel], buf);
- } else if (msglevel == BLOGIC_INFO_LEVEL) {
- strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
- adapter->msgbuflen += len;
- if (begin) {
- if (buf[0] != '\n' || len > 1)
- printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
- } else
- pr_cont("%s", buf);
- } else {
- if (begin) {
- if (adapter != NULL && adapter->adapter_initd)
- printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
- else
- printk("%s%s", blogic_msglevelmap[msglevel], buf);
- } else
- pr_cont("%s", buf);
- }
- begin = (buf[len - 1] == '\n');
-}
-
-
-/*
- blogic_parse parses an individual option keyword. It returns true
- and updates the pointer if the keyword is recognized and false otherwise.
-*/
-
-static bool __init blogic_parse(char **str, char *keyword)
-{
- char *pointer = *str;
- while (*keyword != '\0') {
- char strch = *pointer++;
- char keywordch = *keyword++;
- if (strch >= 'A' && strch <= 'Z')
- strch += 'a' - 'Z';
- if (keywordch >= 'A' && keywordch <= 'Z')
- keywordch += 'a' - 'Z';
- if (strch != keywordch)
- return false;
- }
- *str = pointer;
- return true;
-}
-
-
-/*
- blogic_parseopts handles processing of BusLogic Driver Options
- specifications.
-
- BusLogic Driver Options may be specified either via the Linux Kernel Command
- Line or via the Loadable Kernel Module Installation Facility. Driver Options
- for multiple host adapters may be specified either by separating the option
- strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
- command line. Individual option specifications for a single host adapter are
- separated by commas. The Probing and Debugging Options apply to all host
- adapters whereas the remaining options apply individually only to the
- selected host adapter.
-
- The BusLogic Driver Probing Options are described in
- <file:Documentation/scsi/BusLogic.rst>.
-*/
-
-static int __init blogic_parseopts(char *options)
-{
- while (true) {
- struct blogic_drvr_options *drvr_opts =
- &blogic_drvr_options[blogic_drvr_options_count++];
- int tgt_id;
-
- memset(drvr_opts, 0, sizeof(struct blogic_drvr_options));
- while (*options != '\0' && *options != ';') {
- if (blogic_parse(&options, "NoProbePCI"))
- blogic_probe_options.noprobe_pci = true;
- else if (blogic_parse(&options, "NoProbe"))
- blogic_probe_options.noprobe = true;
- else if (blogic_parse(&options, "NoSortPCI"))
- blogic_probe_options.nosort_pci = true;
- else if (blogic_parse(&options, "MultiMasterFirst"))
- blogic_probe_options.multimaster_first = true;
- else if (blogic_parse(&options, "FlashPointFirst"))
- blogic_probe_options.flashpoint_first = true;
- /* Tagged Queuing Options. */
- else if (blogic_parse(&options, "QueueDepth:[") ||
- blogic_parse(&options, "QD:[")) {
- for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
- unsigned short qdepth = simple_strtoul(options, &options, 0);
- if (qdepth > BLOGIC_MAX_TAG_DEPTH) {
- blogic_err("BusLogic: Invalid Driver Options (invalid Queue Depth %d)\n", NULL, qdepth);
- return 0;
- }
- drvr_opts->qdepth[tgt_id] = qdepth;
- if (*options == ',')
- options++;
- else if (*options == ']')
- break;
- else {
- blogic_err("BusLogic: Invalid Driver Options (',' or ']' expected at '%s')\n", NULL, options);
- return 0;
- }
- }
- if (*options != ']') {
- blogic_err("BusLogic: Invalid Driver Options (']' expected at '%s')\n", NULL, options);
- return 0;
- } else
- options++;
- } else if (blogic_parse(&options, "QueueDepth:") || blogic_parse(&options, "QD:")) {
- unsigned short qdepth = simple_strtoul(options, &options, 0);
- if (qdepth == 0 ||
- qdepth > BLOGIC_MAX_TAG_DEPTH) {
- blogic_err("BusLogic: Invalid Driver Options (invalid Queue Depth %d)\n", NULL, qdepth);
- return 0;
- }
- drvr_opts->common_qdepth = qdepth;
- for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
- drvr_opts->qdepth[tgt_id] = qdepth;
- } else if (blogic_parse(&options, "TaggedQueuing:") ||
- blogic_parse(&options, "TQ:")) {
- if (blogic_parse(&options, "Default")) {
- drvr_opts->tagq_ok = 0x0000;
- drvr_opts->tagq_ok_mask = 0x0000;
- } else if (blogic_parse(&options, "Enable")) {
- drvr_opts->tagq_ok = 0xFFFF;
- drvr_opts->tagq_ok_mask = 0xFFFF;
- } else if (blogic_parse(&options, "Disable")) {
- drvr_opts->tagq_ok = 0x0000;
- drvr_opts->tagq_ok_mask = 0xFFFF;
- } else {
- unsigned short tgt_bit;
- for (tgt_id = 0, tgt_bit = 1;
- tgt_id < BLOGIC_MAXDEV;
- tgt_id++, tgt_bit <<= 1)
- switch (*options++) {
- case 'Y':
- drvr_opts->tagq_ok |= tgt_bit;
- drvr_opts->tagq_ok_mask |= tgt_bit;
- break;
- case 'N':
- drvr_opts->tagq_ok &= ~tgt_bit;
- drvr_opts->tagq_ok_mask |= tgt_bit;
- break;
- case 'X':
- break;
- default:
- options--;
- tgt_id = BLOGIC_MAXDEV;
- break;
- }
- }
- }
- /* Miscellaneous Options. */
- else if (blogic_parse(&options, "BusSettleTime:") ||
- blogic_parse(&options, "BST:")) {
- unsigned short bus_settle_time =
- simple_strtoul(options, &options, 0);
- if (bus_settle_time > 5 * 60) {
- blogic_err("BusLogic: Invalid Driver Options (invalid Bus Settle Time %d)\n", NULL, bus_settle_time);
- return 0;
- }
- drvr_opts->bus_settle_time = bus_settle_time;
- } else if (blogic_parse(&options,
- "InhibitTargetInquiry"))
- drvr_opts->stop_tgt_inquiry = true;
- /* Debugging Options. */
- else if (blogic_parse(&options, "TraceProbe"))
- blogic_global_options.trace_probe = true;
- else if (blogic_parse(&options, "TraceHardwareReset"))
- blogic_global_options.trace_hw_reset = true;
- else if (blogic_parse(&options, "TraceConfiguration"))
- blogic_global_options.trace_config = true;
- else if (blogic_parse(&options, "TraceErrors"))
- blogic_global_options.trace_err = true;
- else if (blogic_parse(&options, "Debug")) {
- blogic_global_options.trace_probe = true;
- blogic_global_options.trace_hw_reset = true;
- blogic_global_options.trace_config = true;
- blogic_global_options.trace_err = true;
- }
- if (*options == ',')
- options++;
- else if (*options != ';' && *options != '\0') {
- blogic_err("BusLogic: Unexpected Driver Option '%s' ignored\n", NULL, options);
- *options = '\0';
- }
- }
- if (!(blogic_drvr_options_count == 0 ||
- blogic_probeinfo_count == 0 ||
- blogic_drvr_options_count == blogic_probeinfo_count)) {
- blogic_err("BusLogic: Invalid Driver Options (all or no I/O Addresses must be specified)\n", NULL);
- return 0;
- }
- /*
- Tagged Queuing is disabled when the Queue Depth is 1 since queuing
- multiple commands is not possible.
- */
- for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
- if (drvr_opts->qdepth[tgt_id] == 1) {
- unsigned short tgt_bit = 1 << tgt_id;
- drvr_opts->tagq_ok &= ~tgt_bit;
- drvr_opts->tagq_ok_mask |= tgt_bit;
- }
- if (*options == ';')
- options++;
- if (*options == '\0')
- return 0;
- }
- return 1;
-}
-
-/*
- Get it all started
-*/
-
-static struct scsi_host_template blogic_template = {
- .module = THIS_MODULE,
- .proc_name = "BusLogic",
- .write_info = blogic_write_info,
- .show_info = blogic_show_info,
- .name = "BusLogic",
- .info = blogic_drvr_info,
- .queuecommand = blogic_qcmd,
- .slave_configure = blogic_slaveconfig,
- .bios_param = blogic_diskparam,
- .eh_host_reset_handler = blogic_hostreset,
-#if 0
- .eh_abort_handler = blogic_abort,
-#endif
- .max_sectors = 128,
-};
-
-/*
- blogic_setup handles processing of Kernel Command Line Arguments.
-*/
-
-static int __init blogic_setup(char *str)
-{
- int ints[3];
-
- (void) get_options(str, ARRAY_SIZE(ints), ints);
-
- if (ints[0] != 0) {
- blogic_err("BusLogic: Obsolete Command Line Entry Format Ignored\n", NULL);
- return 0;
- }
- if (str == NULL || *str == '\0')
- return 0;
- return blogic_parseopts(str);
-}
-
-/*
- * Exit function. Deletes all hosts associated with this driver.
- */
-
-static void __exit blogic_exit(void)
-{
- struct blogic_adapter *ha, *next;
-
- list_for_each_entry_safe(ha, next, &blogic_host_list, host_list)
- blogic_deladapter(ha);
-}
-
-__setup("BusLogic=", blogic_setup);
-
-#ifdef MODULE
-/*static struct pci_device_id blogic_pci_tbl[] = {
- { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { }
-};*/
-static const struct pci_device_id blogic_pci_tbl[] = {
- {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)},
- {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)},
- {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)},
- {0, },
-};
-#endif
-MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
-
-module_init(blogic_init);
-module_exit(blogic_exit);
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
deleted file mode 100644
index 7d1ec10f2430..000000000000
--- a/drivers/scsi/BusLogic.h
+++ /dev/null
@@ -1,1284 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
-
- Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
-
- Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
-
-
- The author respectfully requests that any modifications to this software be
- sent directly to him for evaluation and testing.
-
- Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
- advice has been invaluable, to David Gentzel, for writing the original Linux
- BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
-
- Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
- Manager available as freely redistributable source code.
-
-*/
-
-#ifndef _BUSLOGIC_H
-#define _BUSLOGIC_H
-
-
-#ifndef PACKED
-#define PACKED __attribute__((packed))
-#endif
-
-/*
- Define the maximum number of BusLogic Host Adapters supported by this driver.
-*/
-
-#define BLOGIC_MAX_ADAPTERS 16
-
-
-/*
- Define the maximum number of Target Devices supported by this driver.
-*/
-
-#define BLOGIC_MAXDEV 16
-
-
-/*
- Define the maximum number of Scatter/Gather Segments used by this driver.
- For optimal performance, it is important that this limit be at least as
- large as the largest single request generated by the I/O Subsystem.
-*/
-
-#define BLOGIC_SG_LIMIT 128
-
-
-/*
- Define the maximum, maximum automatic, minimum automatic, and default Queue
- Depth to allow for Target Devices depending on whether or not they support
- Tagged Queuing and whether or not ISA Bounce Buffers are required.
-*/
-
-#define BLOGIC_MAX_TAG_DEPTH 64
-#define BLOGIC_MAX_AUTO_TAG_DEPTH 28
-#define BLOGIC_MIN_AUTO_TAG_DEPTH 7
-#define BLOGIC_TAG_DEPTH_BB 3
-#define BLOGIC_UNTAG_DEPTH 3
-#define BLOGIC_UNTAG_DEPTH_BB 2
-
-
-/*
- Define the default amount of time in seconds to wait between a Host Adapter
- Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI commands.
- Some SCSI devices get confused if they receive SCSI commands too soon after
- a SCSI Bus Reset.
-*/
-
-#define BLOGIC_BUS_SETTLE_TIME 2
-
-
-/*
- Define the maximum number of Mailboxes that should be used for MultiMaster
- Host Adapters. This number is chosen to be larger than the maximum Host
- Adapter Queue Depth and small enough so that the Host Adapter structure
- does not cross an allocation block size boundary.
-*/
-
-#define BLOGIC_MAX_MAILBOX 211
-
-
-/*
- Define the number of CCBs that should be allocated as a group to optimize
- Kernel memory allocation.
-*/
-
-#define BLOGIC_CCB_GRP_ALLOCSIZE 7
-
-
-/*
- Define the Host Adapter Line and Message Buffer Sizes.
-*/
-
-#define BLOGIC_LINEBUF_SIZE 100
-#define BLOGIC_MSGBUF_SIZE 9700
-
-
-/*
- Define the Driver Message Levels.
-*/
-
-enum blogic_msglevel {
- BLOGIC_ANNOUNCE_LEVEL = 0,
- BLOGIC_INFO_LEVEL = 1,
- BLOGIC_NOTICE_LEVEL = 2,
- BLOGIC_WARN_LEVEL = 3,
- BLOGIC_ERR_LEVEL = 4
-};
-
-static char *blogic_msglevelmap[] = { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING, KERN_ERR };
-
-
-/*
- Define Driver Message macros.
-*/
-
-#define blogic_announce(format, args...) \
- blogic_msg(BLOGIC_ANNOUNCE_LEVEL, format, ##args)
-
-#define blogic_info(format, args...) \
- blogic_msg(BLOGIC_INFO_LEVEL, format, ##args)
-
-#define blogic_notice(format, args...) \
- blogic_msg(BLOGIC_NOTICE_LEVEL, format, ##args)
-
-#define blogic_warn(format, args...) \
- blogic_msg(BLOGIC_WARN_LEVEL, format, ##args)
-
-#define blogic_err(format, args...) \
- blogic_msg(BLOGIC_ERR_LEVEL, format, ##args)
-
-
-/*
- Define the types of BusLogic Host Adapters that are supported and the number
- of I/O Addresses required by each type.
-*/
-
-enum blogic_adapter_type {
- BLOGIC_MULTIMASTER = 1,
- BLOGIC_FLASHPOINT = 2
-} PACKED;
-
-#define BLOGIC_MULTIMASTER_ADDR_COUNT 4
-#define BLOGIC_FLASHPOINT_ADDR_COUNT 256
-
-static int blogic_adapter_addr_count[3] = { 0, BLOGIC_MULTIMASTER_ADDR_COUNT, BLOGIC_FLASHPOINT_ADDR_COUNT };
-
-
-/*
- Define macros for testing the Host Adapter Type.
-*/
-
-#ifdef CONFIG_SCSI_FLASHPOINT
-
-#define blogic_multimaster_type(adapter) \
- (adapter->adapter_type == BLOGIC_MULTIMASTER)
-
-#define blogic_flashpoint_type(adapter) \
- (adapter->adapter_type == BLOGIC_FLASHPOINT)
-
-#else
-
-#define blogic_multimaster_type(adapter) (true)
-#define blogic_flashpoint_type(adapter) (false)
-
-#endif
-
-
-/*
- Define the possible Host Adapter Bus Types.
-*/
-
-enum blogic_adapter_bus_type {
- BLOGIC_UNKNOWN_BUS = 0,
- BLOGIC_ISA_BUS = 1,
- BLOGIC_EISA_BUS = 2,
- BLOGIC_PCI_BUS = 3,
- BLOGIC_VESA_BUS = 4,
- BLOGIC_MCA_BUS = 5
-} PACKED;
-
-static char *blogic_adapter_busnames[] = { "Unknown", "ISA", "EISA", "PCI", "VESA", "MCA" };
-
-static enum blogic_adapter_bus_type blogic_adater_bus_types[] = {
- BLOGIC_VESA_BUS, /* BT-4xx */
- BLOGIC_ISA_BUS, /* BT-5xx */
- BLOGIC_MCA_BUS, /* BT-6xx */
- BLOGIC_EISA_BUS, /* BT-7xx */
- BLOGIC_UNKNOWN_BUS, /* BT-8xx */
- BLOGIC_PCI_BUS /* BT-9xx */
-};
-
-/*
- Define the possible Host Adapter BIOS Disk Geometry Translations.
-*/
-
-enum blogic_bios_diskgeometry {
- BLOGIC_BIOS_NODISK = 0,
- BLOGIC_BIOS_DISK64x32 = 1,
- BLOGIC_BIOS_DISK128x32 = 2,
- BLOGIC_BIOS_DISK255x63 = 3
-} PACKED;
-
-
-/*
- Define a 10^18 Statistics Byte Counter data type.
-*/
-
-struct blogic_byte_count {
- unsigned int units;
- unsigned int billions;
-};
-
-
-/*
- Define the structure for I/O Address and Bus Probing Information.
-*/
-
-struct blogic_probeinfo {
- enum blogic_adapter_type adapter_type;
- enum blogic_adapter_bus_type adapter_bus_type;
- unsigned long io_addr;
- unsigned long pci_addr;
- struct pci_dev *pci_device;
- unsigned char bus;
- unsigned char dev;
- unsigned char irq_ch;
-};
-
-/*
- Define the Probe Options.
-*/
-
-struct blogic_probe_options {
- bool noprobe:1; /* Bit 0 */
- bool noprobe_pci:1; /* Bit 2 */
- bool nosort_pci:1; /* Bit 3 */
- bool multimaster_first:1; /* Bit 4 */
- bool flashpoint_first:1; /* Bit 5 */
-};
-
-/*
- Define the Global Options.
-*/
-
-struct blogic_global_options {
- bool trace_probe:1; /* Bit 0 */
- bool trace_hw_reset:1; /* Bit 1 */
- bool trace_config:1; /* Bit 2 */
- bool trace_err:1; /* Bit 3 */
-};
-
-/*
- Define the BusLogic SCSI Host Adapter I/O Register Offsets.
-*/
-
-#define BLOGIC_CNTRL_REG 0 /* WO register */
-#define BLOGIC_STATUS_REG 0 /* RO register */
-#define BLOGIC_CMD_PARM_REG 1 /* WO register */
-#define BLOGIC_DATAIN_REG 1 /* RO register */
-#define BLOGIC_INT_REG 2 /* RO register */
-#define BLOGIC_GEOMETRY_REG 3 /* RO register */
-
-/*
- Define the structure of the write-only Control Register.
-*/
-
-union blogic_cntrl_reg {
- unsigned char all;
- struct {
- unsigned char:4; /* Bits 0-3 */
- bool bus_reset:1; /* Bit 4 */
- bool int_reset:1; /* Bit 5 */
- bool soft_reset:1; /* Bit 6 */
- bool hard_reset:1; /* Bit 7 */
- } cr;
-};
-
-/*
- Define the structure of the read-only Status Register.
-*/
-
-union blogic_stat_reg {
- unsigned char all;
- struct {
- bool cmd_invalid:1; /* Bit 0 */
- bool rsvd:1; /* Bit 1 */
- bool datain_ready:1; /* Bit 2 */
- bool cmd_param_busy:1; /* Bit 3 */
- bool adapter_ready:1; /* Bit 4 */
- bool init_reqd:1; /* Bit 5 */
- bool diag_failed:1; /* Bit 6 */
- bool diag_active:1; /* Bit 7 */
- } sr;
-};
-
-/*
- Define the structure of the read-only Interrupt Register.
-*/
-
-union blogic_int_reg {
- unsigned char all;
- struct {
- bool mailin_loaded:1; /* Bit 0 */
- bool mailout_avail:1; /* Bit 1 */
- bool cmd_complete:1; /* Bit 2 */
- bool ext_busreset:1; /* Bit 3 */
- unsigned char rsvd:3; /* Bits 4-6 */
- bool int_valid:1; /* Bit 7 */
- } ir;
-};
-
-/*
- Define the structure of the read-only Geometry Register.
-*/
-
-union blogic_geo_reg {
- unsigned char all;
- struct {
- enum blogic_bios_diskgeometry d0_geo:2; /* Bits 0-1 */
- enum blogic_bios_diskgeometry d1_geo:2; /* Bits 2-3 */
- unsigned char:3; /* Bits 4-6 */
- bool ext_trans_enable:1; /* Bit 7 */
- } gr;
-};
-
-/*
- Define the BusLogic SCSI Host Adapter Command Register Operation Codes.
-*/
-
-enum blogic_opcode {
- BLOGIC_TEST_CMP_COMPLETE = 0x00,
- BLOGIC_INIT_MBOX = 0x01,
- BLOGIC_EXEC_MBOX_CMD = 0x02,
- BLOGIC_EXEC_BIOS_CMD = 0x03,
- BLOGIC_GET_BOARD_ID = 0x04,
- BLOGIC_ENABLE_OUTBOX_AVAIL_INT = 0x05,
- BLOGIC_SET_SELECT_TIMEOUT = 0x06,
- BLOGIC_SET_PREEMPT_TIME = 0x07,
- BLOGIC_SET_TIMEOFF_BUS = 0x08,
- BLOGIC_SET_TXRATE = 0x09,
- BLOGIC_INQ_DEV0TO7 = 0x0A,
- BLOGIC_INQ_CONFIG = 0x0B,
- BLOGIC_TGT_MODE = 0x0C,
- BLOGIC_INQ_SETUPINFO = 0x0D,
- BLOGIC_WRITE_LOCALRAM = 0x1A,
- BLOGIC_READ_LOCALRAM = 0x1B,
- BLOGIC_WRITE_BUSMASTER_FIFO = 0x1C,
- BLOGIC_READ_BUSMASTER_FIFO = 0x1D,
- BLOGIC_ECHO_CMDDATA = 0x1F,
- BLOGIC_ADAPTER_DIAG = 0x20,
- BLOGIC_SET_OPTIONS = 0x21,
- BLOGIC_INQ_DEV8TO15 = 0x23,
- BLOGIC_INQ_DEV = 0x24,
- BLOGIC_DISABLE_INT = 0x25,
- BLOGIC_INIT_EXT_MBOX = 0x81,
- BLOGIC_EXEC_SCS_CMD = 0x83,
- BLOGIC_INQ_FWVER_D3 = 0x84,
- BLOGIC_INQ_FWVER_LETTER = 0x85,
- BLOGIC_INQ_PCI_INFO = 0x86,
- BLOGIC_INQ_MODELNO = 0x8B,
- BLOGIC_INQ_SYNC_PERIOD = 0x8C,
- BLOGIC_INQ_EXTSETUP = 0x8D,
- BLOGIC_STRICT_RR = 0x8F,
- BLOGIC_STORE_LOCALRAM = 0x90,
- BLOGIC_FETCH_LOCALRAM = 0x91,
- BLOGIC_STORE_TO_EEPROM = 0x92,
- BLOGIC_LOAD_AUTOSCSICODE = 0x94,
- BLOGIC_MOD_IOADDR = 0x95,
- BLOGIC_SETCCB_FMT = 0x96,
- BLOGIC_WRITE_INQBUF = 0x9A,
- BLOGIC_READ_INQBUF = 0x9B,
- BLOGIC_FLASH_LOAD = 0xA7,
- BLOGIC_READ_SCAMDATA = 0xA8,
- BLOGIC_WRITE_SCAMDATA = 0xA9
-};
-
-/*
- Define the Inquire Board ID reply structure.
-*/
-
-struct blogic_board_id {
- unsigned char type; /* Byte 0 */
- unsigned char custom_features; /* Byte 1 */
- unsigned char fw_ver_digit1; /* Byte 2 */
- unsigned char fw_ver_digit2; /* Byte 3 */
-};
-
-/*
- Define the Inquire Configuration reply structure.
-*/
-
-struct blogic_config {
- unsigned char:5; /* Byte 0 Bits 0-4 */
- bool dma_ch5:1; /* Byte 0 Bit 5 */
- bool dma_ch6:1; /* Byte 0 Bit 6 */
- bool dma_ch7:1; /* Byte 0 Bit 7 */
- bool irq_ch9:1; /* Byte 1 Bit 0 */
- bool irq_ch10:1; /* Byte 1 Bit 1 */
- bool irq_ch11:1; /* Byte 1 Bit 2 */
- bool irq_ch12:1; /* Byte 1 Bit 3 */
- unsigned char:1; /* Byte 1 Bit 4 */
- bool irq_ch14:1; /* Byte 1 Bit 5 */
- bool irq_ch15:1; /* Byte 1 Bit 6 */
- unsigned char:1; /* Byte 1 Bit 7 */
- unsigned char id:4; /* Byte 2 Bits 0-3 */
- unsigned char:4; /* Byte 2 Bits 4-7 */
-};
-
-/*
- Define the Inquire Setup Information reply structure.
-*/
-
-struct blogic_syncval {
- unsigned char offset:4; /* Bits 0-3 */
- unsigned char tx_period:3; /* Bits 4-6 */
- bool sync:1; /* Bit 7 */
-};
-
-struct blogic_setup_info {
- bool sync:1; /* Byte 0 Bit 0 */
- bool parity:1; /* Byte 0 Bit 1 */
- unsigned char:6; /* Byte 0 Bits 2-7 */
- unsigned char tx_rate; /* Byte 1 */
- unsigned char preempt_time; /* Byte 2 */
- unsigned char timeoff_bus; /* Byte 3 */
- unsigned char mbox_count; /* Byte 4 */
- unsigned char mbox_addr[3]; /* Bytes 5-7 */
- struct blogic_syncval sync0to7[8]; /* Bytes 8-15 */
- unsigned char disconnect_ok0to7; /* Byte 16 */
- unsigned char sig; /* Byte 17 */
- unsigned char char_d; /* Byte 18 */
- unsigned char bus_type; /* Byte 19 */
- unsigned char wide_tx_ok0to7; /* Byte 20 */
- unsigned char wide_tx_active0to7; /* Byte 21 */
- struct blogic_syncval sync8to15[8]; /* Bytes 22-29 */
- unsigned char disconnect_ok8to15; /* Byte 30 */
- unsigned char:8; /* Byte 31 */
- unsigned char wide_tx_ok8to15; /* Byte 32 */
- unsigned char wide_tx_active8to15; /* Byte 33 */
-};
-
-/*
- Define the Initialize Extended Mailbox request structure.
-*/
-
-struct blogic_extmbox_req {
- unsigned char mbox_count; /* Byte 0 */
- u32 base_mbox_addr; /* Bytes 1-4 */
-} PACKED;
-
-
-/*
- Define the Inquire PCI Host Adapter Information reply type. The ISA
- Compatible I/O Port values are defined here and are also used with
- the Modify I/O Address command.
-*/
-
-enum blogic_isa_ioport {
- BLOGIC_IO_330 = 0,
- BLOGIC_IO_334 = 1,
- BLOGIC_IO_230 = 2,
- BLOGIC_IO_234 = 3,
- BLOGIC_IO_130 = 4,
- BLOGIC_IO_134 = 5,
- BLOGIC_IO_DISABLE = 6,
- BLOGIC_IO_DISABLE2 = 7
-} PACKED;
-
-struct blogic_adapter_info {
- enum blogic_isa_ioport isa_port; /* Byte 0 */
- unsigned char irq_ch; /* Byte 1 */
- bool low_term:1; /* Byte 2 Bit 0 */
- bool high_term:1; /* Byte 2 Bit 1 */
- unsigned char:2; /* Byte 2 Bits 2-3 */
- bool JP1:1; /* Byte 2 Bit 4 */
- bool JP2:1; /* Byte 2 Bit 5 */
- bool JP3:1; /* Byte 2 Bit 6 */
- bool genericinfo_valid:1; /* Byte 2 Bit 7 */
- unsigned char:8; /* Byte 3 */
-};
-
-/*
- Define the Inquire Extended Setup Information reply structure.
-*/
-
-struct blogic_ext_setup {
- unsigned char bus_type; /* Byte 0 */
- unsigned char bios_addr; /* Byte 1 */
- unsigned short sg_limit; /* Bytes 2-3 */
- unsigned char mbox_count; /* Byte 4 */
- u32 base_mbox_addr; /* Bytes 5-8 */
- struct {
- unsigned char:2; /* Byte 9 Bits 0-1 */
- bool fast_on_eisa:1; /* Byte 9 Bit 2 */
- unsigned char:3; /* Byte 9 Bits 3-5 */
- bool level_int:1; /* Byte 9 Bit 6 */
- unsigned char:1; /* Byte 9 Bit 7 */
- } misc;
- unsigned char fw_rev[3]; /* Bytes 10-12 */
- bool wide:1; /* Byte 13 Bit 0 */
- bool differential:1; /* Byte 13 Bit 1 */
- bool scam:1; /* Byte 13 Bit 2 */
- bool ultra:1; /* Byte 13 Bit 3 */
- bool smart_term:1; /* Byte 13 Bit 4 */
- unsigned char:3; /* Byte 13 Bits 5-7 */
-} PACKED;
-
-/*
- Define the Enable Strict Round Robin Mode request type.
-*/
-
-enum blogic_rr_req {
- BLOGIC_AGGRESSIVE_RR = 0,
- BLOGIC_STRICT_RR_MODE = 1
-} PACKED;
-
-
-/*
- Define the Fetch Host Adapter Local RAM request type.
-*/
-
-#define BLOGIC_BIOS_BASE 0
-#define BLOGIC_AUTOSCSI_BASE 64
-
-struct blogic_fetch_localram {
- unsigned char offset; /* Byte 0 */
- unsigned char count; /* Byte 1 */
-};
-
-/*
- Define the Host Adapter Local RAM AutoSCSI structure.
-*/
-
-struct blogic_autoscsi {
- unsigned char factory_sig[2]; /* Bytes 0-1 */
- unsigned char info_bytes; /* Byte 2 */
- unsigned char adapter_type[6]; /* Bytes 3-8 */
- unsigned char:8; /* Byte 9 */
- bool floppy:1; /* Byte 10 Bit 0 */
- bool floppy_sec:1; /* Byte 10 Bit 1 */
- bool level_int:1; /* Byte 10 Bit 2 */
- unsigned char:2; /* Byte 10 Bits 3-4 */
- unsigned char systemram_bios:3; /* Byte 10 Bits 5-7 */
- unsigned char dma_ch:7; /* Byte 11 Bits 0-6 */
- bool dma_autoconf:1; /* Byte 11 Bit 7 */
- unsigned char irq_ch:7; /* Byte 12 Bits 0-6 */
- bool irq_autoconf:1; /* Byte 12 Bit 7 */
- unsigned char dma_tx_rate; /* Byte 13 */
- unsigned char scsi_id; /* Byte 14 */
- bool low_term:1; /* Byte 15 Bit 0 */
- bool parity:1; /* Byte 15 Bit 1 */
- bool high_term:1; /* Byte 15 Bit 2 */
- bool noisy_cable:1; /* Byte 15 Bit 3 */
- bool fast_sync_neg:1; /* Byte 15 Bit 4 */
- bool reset_enabled:1; /* Byte 15 Bit 5 */
- bool:1; /* Byte 15 Bit 6 */
- bool active_negation:1; /* Byte 15 Bit 7 */
- unsigned char bus_on_delay; /* Byte 16 */
- unsigned char bus_off_delay; /* Byte 17 */
- bool bios_enabled:1; /* Byte 18 Bit 0 */
- bool int19_redir_enabled:1; /* Byte 18 Bit 1 */
- bool ext_trans_enable:1; /* Byte 18 Bit 2 */
- bool removable_as_fixed:1; /* Byte 18 Bit 3 */
- bool:1; /* Byte 18 Bit 4 */
- bool morethan2_drives:1; /* Byte 18 Bit 5 */
- bool bios_int:1; /* Byte 18 Bit 6 */
- bool floptical:1; /* Byte 19 Bit 7 */
- unsigned short dev_enabled; /* Bytes 19-20 */
- unsigned short wide_ok; /* Bytes 21-22 */
- unsigned short fast_ok; /* Bytes 23-24 */
- unsigned short sync_ok; /* Bytes 25-26 */
- unsigned short discon_ok; /* Bytes 27-28 */
- unsigned short send_start_unit; /* Bytes 29-30 */
- unsigned short ignore_bios_scan; /* Bytes 31-32 */
- unsigned char pci_int_pin:2; /* Byte 33 Bits 0-1 */
- unsigned char adapter_ioport:2; /* Byte 33 Bits 2-3 */
- bool strict_rr_enabled:1; /* Byte 33 Bit 4 */
- bool vesabus_33mhzplus:1; /* Byte 33 Bit 5 */
- bool vesa_burst_write:1; /* Byte 33 Bit 6 */
- bool vesa_burst_read:1; /* Byte 33 Bit 7 */
- unsigned short ultra_ok; /* Bytes 34-35 */
- unsigned int:32; /* Bytes 36-39 */
- unsigned char:8; /* Byte 40 */
- unsigned char autoscsi_maxlun; /* Byte 41 */
- bool:1; /* Byte 42 Bit 0 */
- bool scam_dominant:1; /* Byte 42 Bit 1 */
- bool scam_enabled:1; /* Byte 42 Bit 2 */
- bool scam_lev2:1; /* Byte 42 Bit 3 */
- unsigned char:4; /* Byte 42 Bits 4-7 */
- bool int13_exten:1; /* Byte 43 Bit 0 */
- bool:1; /* Byte 43 Bit 1 */
- bool cd_boot:1; /* Byte 43 Bit 2 */
- unsigned char:5; /* Byte 43 Bits 3-7 */
- unsigned char boot_id:4; /* Byte 44 Bits 0-3 */
- unsigned char boot_ch:4; /* Byte 44 Bits 4-7 */
- unsigned char force_scan_order:1; /* Byte 45 Bit 0 */
- unsigned char:7; /* Byte 45 Bits 1-7 */
- unsigned short nontagged_to_alt_ok; /* Bytes 46-47 */
- unsigned short reneg_sync_on_check; /* Bytes 48-49 */
- unsigned char rsvd[10]; /* Bytes 50-59 */
- unsigned char manuf_diag[2]; /* Bytes 60-61 */
- unsigned short cksum; /* Bytes 62-63 */
-} PACKED;
-
-/*
- Define the Host Adapter Local RAM Auto SCSI Byte 45 structure.
-*/
-
-struct blogic_autoscsi_byte45 {
- unsigned char force_scan_order:1; /* Bit 0 */
- unsigned char:7; /* Bits 1-7 */
-};
-
-/*
- Define the Host Adapter Local RAM BIOS Drive Map Byte structure.
-*/
-
-#define BLOGIC_BIOS_DRVMAP 17
-
-struct blogic_bios_drvmap {
- unsigned char tgt_idbit3:1; /* Bit 0 */
- unsigned char:2; /* Bits 1-2 */
- enum blogic_bios_diskgeometry diskgeom:2; /* Bits 3-4 */
- unsigned char tgt_id:3; /* Bits 5-7 */
-};
-
-/*
- Define the Set CCB Format request type. Extended LUN Format CCBs are
- necessary to support more than 8 Logical Units per Target Device.
-*/
-
-enum blogic_setccb_fmt {
- BLOGIC_LEGACY_LUN_CCB = 0,
- BLOGIC_EXT_LUN_CCB = 1
-} PACKED;
-
-/*
- Define the Outgoing Mailbox Action Codes.
-*/
-
-enum blogic_action {
- BLOGIC_OUTBOX_FREE = 0x00,
- BLOGIC_MBOX_START = 0x01,
- BLOGIC_MBOX_ABORT = 0x02
-} PACKED;
-
-
-/*
- Define the Incoming Mailbox Completion Codes. The MultiMaster Firmware
- only uses codes 0 - 4. The FlashPoint SCCB Manager has no mailboxes, so
- completion codes are stored in the CCB; it only uses codes 1, 2, 4, and 5.
-*/
-
-enum blogic_cmplt_code {
- BLOGIC_INBOX_FREE = 0x00,
- BLOGIC_CMD_COMPLETE_GOOD = 0x01,
- BLOGIC_CMD_ABORT_BY_HOST = 0x02,
- BLOGIC_CMD_NOTFOUND = 0x03,
- BLOGIC_CMD_COMPLETE_ERROR = 0x04,
- BLOGIC_INVALID_CCB = 0x05
-} PACKED;
-
-/*
- Define the Command Control Block (CCB) Opcodes.
-*/
-
-enum blogic_ccb_opcode {
- BLOGIC_INITIATOR_CCB = 0x00,
- BLOGIC_TGT_CCB = 0x01,
- BLOGIC_INITIATOR_CCB_SG = 0x02,
- BLOGIC_INITIATOR_CCBB_RESIDUAL = 0x03,
- BLOGIC_INITIATOR_CCB_SG_RESIDUAL = 0x04,
- BLOGIC_BDR = 0x81
-} PACKED;
-
-
-/*
- Define the CCB Data Direction Codes.
-*/
-
-enum blogic_datadir {
- BLOGIC_UNCHECKED_TX = 0,
- BLOGIC_DATAIN_CHECKED = 1,
- BLOGIC_DATAOUT_CHECKED = 2,
- BLOGIC_NOTX = 3
-};
-
-
-/*
- Define the Host Adapter Status Codes. The MultiMaster Firmware does not
- return status code 0x0C; it uses 0x12 for both overruns and underruns.
-*/
-
-enum blogic_adapter_status {
- BLOGIC_CMD_CMPLT_NORMAL = 0x00,
- BLOGIC_LINK_CMD_CMPLT = 0x0A,
- BLOGIC_LINK_CMD_CMPLT_FLAG = 0x0B,
- BLOGIC_DATA_UNDERRUN = 0x0C,
- BLOGIC_SELECT_TIMEOUT = 0x11,
- BLOGIC_DATA_OVERRUN = 0x12,
- BLOGIC_NOEXPECT_BUSFREE = 0x13,
- BLOGIC_INVALID_BUSPHASE = 0x14,
- BLOGIC_INVALID_OUTBOX_CODE = 0x15,
- BLOGIC_INVALID_CMD_CODE = 0x16,
- BLOGIC_LINKCCB_BADLUN = 0x17,
- BLOGIC_BAD_CMD_PARAM = 0x1A,
- BLOGIC_AUTOREQSENSE_FAIL = 0x1B,
- BLOGIC_TAGQUEUE_REJECT = 0x1C,
- BLOGIC_BAD_MSG_RCVD = 0x1D,
- BLOGIC_HW_FAIL = 0x20,
- BLOGIC_NORESPONSE_TO_ATN = 0x21,
- BLOGIC_HW_RESET = 0x22,
- BLOGIC_RST_FROM_OTHERDEV = 0x23,
- BLOGIC_BAD_RECONNECT = 0x24,
- BLOGIC_HW_BDR = 0x25,
- BLOGIC_ABRT_QUEUE = 0x26,
- BLOGIC_ADAPTER_SW_ERROR = 0x27,
- BLOGIC_HW_TIMEOUT = 0x30,
- BLOGIC_PARITY_ERR = 0x34
-} PACKED;
-
-
-/*
- Define the SCSI Target Device Status Codes.
-*/
-
-enum blogic_tgt_status {
- BLOGIC_OP_GOOD = 0x00,
- BLOGIC_CHECKCONDITION = 0x02,
- BLOGIC_DEVBUSY = 0x08
-} PACKED;
-
-/*
- Define the Queue Tag Codes.
-*/
-
-enum blogic_queuetag {
- BLOGIC_SIMPLETAG = 0,
- BLOGIC_HEADTAG = 1,
- BLOGIC_ORDEREDTAG = 2,
- BLOGIC_RSVDTAG = 3
-};
-
-/*
- Define the SCSI Command Descriptor Block (CDB).
-*/
-
-#define BLOGIC_CDB_MAXLEN 12
-
-
-/*
- Define the Scatter/Gather Segment structure required by the MultiMaster
- Firmware Interface and the FlashPoint SCCB Manager.
-*/
-
-struct blogic_sg_seg {
- u32 segbytes; /* Bytes 0-3 */
- u32 segdata; /* Bytes 4-7 */
-};
-
-/*
- Define the Driver CCB Status Codes.
-*/
-
-enum blogic_ccb_status {
- BLOGIC_CCB_FREE = 0,
- BLOGIC_CCB_ACTIVE = 1,
- BLOGIC_CCB_COMPLETE = 2,
- BLOGIC_CCB_RESET = 3
-} PACKED;
-
-
-/*
- Define the 32 Bit Mode Command Control Block (CCB) structure. The first 40
- bytes are defined by and common to both the MultiMaster Firmware and the
- FlashPoint SCCB Manager. The next 60 bytes are defined by the FlashPoint
- SCCB Manager. The remaining components are defined by the Linux BusLogic
- Driver. Extended LUN Format CCBs differ from Legacy LUN Format 32 Bit Mode
- CCBs only in having the TagEnable and QueueTag fields moved from byte 17 to
- byte 1, and the Logical Unit field in byte 17 expanded to 6 bits. In theory,
- Extended LUN Format CCBs can support up to 64 Logical Units, but in practice
- many devices will respond improperly to Logical Units between 32 and 63, and
- the SCSI-2 specification defines Bit 5 as LUNTAR. Extended LUN Format CCBs
- are used by recent versions of the MultiMaster Firmware, as well as by the
- FlashPoint SCCB Manager; the FlashPoint SCCB Manager only supports 32 Logical
- Units. Since 64 Logical Units are unlikely to be needed in practice, and
- since they are problematic for the above reasons, and since limiting them to
- 5 bits simplifies the CCB structure definition, this driver only supports
- 32 Logical Units per Target Device.
-*/
-
-struct blogic_ccb {
- /*
- MultiMaster Firmware and FlashPoint SCCB Manager Common Portion.
- */
- enum blogic_ccb_opcode opcode; /* Byte 0 */
- unsigned char:3; /* Byte 1 Bits 0-2 */
- enum blogic_datadir datadir:2; /* Byte 1 Bits 3-4 */
- bool tag_enable:1; /* Byte 1 Bit 5 */
- enum blogic_queuetag queuetag:2; /* Byte 1 Bits 6-7 */
- unsigned char cdblen; /* Byte 2 */
- unsigned char sense_datalen; /* Byte 3 */
- u32 datalen; /* Bytes 4-7 */
- u32 data; /* Bytes 8-11 */
- unsigned char:8; /* Byte 12 */
- unsigned char:8; /* Byte 13 */
- enum blogic_adapter_status adapter_status; /* Byte 14 */
- enum blogic_tgt_status tgt_status; /* Byte 15 */
- unsigned char tgt_id; /* Byte 16 */
- unsigned char lun:5; /* Byte 17 Bits 0-4 */
- bool legacytag_enable:1; /* Byte 17 Bit 5 */
- enum blogic_queuetag legacy_tag:2; /* Byte 17 Bits 6-7 */
- unsigned char cdb[BLOGIC_CDB_MAXLEN]; /* Bytes 18-29 */
- unsigned char:8; /* Byte 30 */
- unsigned char:8; /* Byte 31 */
- u32 rsvd_int; /* Bytes 32-35 */
- u32 sensedata; /* Bytes 36-39 */
- /*
- FlashPoint SCCB Manager Defined Portion.
- */
- void (*callback) (struct blogic_ccb *); /* Bytes 40-43 */
- u32 base_addr; /* Bytes 44-47 */
- enum blogic_cmplt_code comp_code; /* Byte 48 */
-#ifdef CONFIG_SCSI_FLASHPOINT
- unsigned char:8; /* Byte 49 */
- u16 os_flags; /* Bytes 50-51 */
- unsigned char private[24]; /* Bytes 52-99 */
- void *rsvd1;
- void *rsvd2;
- unsigned char private2[16];
-#endif
- /*
- BusLogic Linux Driver Defined Portion.
- */
- dma_addr_t allocgrp_head;
- unsigned int allocgrp_size;
- u32 dma_handle;
- enum blogic_ccb_status status;
- unsigned long serial;
- struct scsi_cmnd *command;
- struct blogic_adapter *adapter;
- struct blogic_ccb *next;
- struct blogic_ccb *next_all;
- struct blogic_sg_seg sglist[BLOGIC_SG_LIMIT];
-};
-
-/*
- Define the 32 Bit Mode Outgoing Mailbox structure.
-*/
-
-struct blogic_outbox {
- u32 ccb; /* Bytes 0-3 */
- u32:24; /* Bytes 4-6 */
- enum blogic_action action; /* Byte 7 */
-};
-
-/*
- Define the 32 Bit Mode Incoming Mailbox structure.
-*/
-
-struct blogic_inbox {
- u32 ccb; /* Bytes 0-3 */
- enum blogic_adapter_status adapter_status; /* Byte 4 */
- enum blogic_tgt_status tgt_status; /* Byte 5 */
- unsigned char:8; /* Byte 6 */
- enum blogic_cmplt_code comp_code; /* Byte 7 */
-};
-
-
-/*
- Define the BusLogic Driver Options structure.
-*/
-
-struct blogic_drvr_options {
- unsigned short tagq_ok;
- unsigned short tagq_ok_mask;
- unsigned short bus_settle_time;
- unsigned short stop_tgt_inquiry;
- unsigned char common_qdepth;
- unsigned char qdepth[BLOGIC_MAXDEV];
-};
-
-/*
- Define the Host Adapter Target Flags structure.
-*/
-
-struct blogic_tgt_flags {
- bool tgt_exists:1;
- bool tagq_ok:1;
- bool wide_ok:1;
- bool tagq_active:1;
- bool wide_active:1;
- bool cmd_good:1;
- bool tgt_info_in:1;
-};
-
-/*
- Define the Host Adapter Target Statistics structure.
-*/
-
-#define BLOGIC_SZ_BUCKETS 10
-
-struct blogic_tgt_stats {
- unsigned int cmds_tried;
- unsigned int cmds_complete;
- unsigned int read_cmds;
- unsigned int write_cmds;
- struct blogic_byte_count bytesread;
- struct blogic_byte_count byteswritten;
- unsigned int read_sz_buckets[BLOGIC_SZ_BUCKETS];
- unsigned int write_sz_buckets[BLOGIC_SZ_BUCKETS];
- unsigned short aborts_request;
- unsigned short aborts_tried;
- unsigned short aborts_done;
- unsigned short bdr_request;
- unsigned short bdr_tried;
- unsigned short bdr_done;
- unsigned short adapter_reset_req;
- unsigned short adapter_reset_attempt;
- unsigned short adapter_reset_done;
-};
-
-/*
- Define the FlashPoint Card Handle data type.
-*/
-
-#define FPOINT_BADCARD_HANDLE 0xFFFFFFFFL
-
-
-/*
- Define the FlashPoint Information structure. This structure is defined
- by the FlashPoint SCCB Manager.
-*/
-
-struct fpoint_info {
- u32 base_addr; /* Bytes 0-3 */
- bool present; /* Byte 4 */
- unsigned char irq_ch; /* Byte 5 */
- unsigned char scsi_id; /* Byte 6 */
- unsigned char scsi_lun; /* Byte 7 */
- u16 fw_rev; /* Bytes 8-9 */
- u16 sync_ok; /* Bytes 10-11 */
- u16 fast_ok; /* Bytes 12-13 */
- u16 ultra_ok; /* Bytes 14-15 */
- u16 discon_ok; /* Bytes 16-17 */
- u16 wide_ok; /* Bytes 18-19 */
- bool parity:1; /* Byte 20 Bit 0 */
- bool wide:1; /* Byte 20 Bit 1 */
- bool softreset:1; /* Byte 20 Bit 2 */
- bool ext_trans_enable:1; /* Byte 20 Bit 3 */
- bool low_term:1; /* Byte 20 Bit 4 */
- bool high_term:1; /* Byte 20 Bit 5 */
- bool report_underrun:1; /* Byte 20 Bit 6 */
- bool scam_enabled:1; /* Byte 20 Bit 7 */
- bool scam_lev2:1; /* Byte 21 Bit 0 */
- unsigned char:7; /* Byte 21 Bits 1-7 */
- unsigned char family; /* Byte 22 */
- unsigned char bus_type; /* Byte 23 */
- unsigned char model[3]; /* Bytes 24-26 */
- unsigned char relative_cardnum; /* Byte 27 */
- unsigned char rsvd[4]; /* Bytes 28-31 */
- u32 os_rsvd; /* Bytes 32-35 */
- unsigned char translation_info[4]; /* Bytes 36-39 */
- u32 rsvd2[5]; /* Bytes 40-59 */
- u32 sec_range; /* Bytes 60-63 */
-};
-
-/*
- Define the BusLogic Driver Host Adapter structure.
-*/
-
-struct blogic_adapter {
- struct Scsi_Host *scsi_host;
- struct pci_dev *pci_device;
- enum blogic_adapter_type adapter_type;
- enum blogic_adapter_bus_type adapter_bus_type;
- unsigned long io_addr;
- unsigned long pci_addr;
- unsigned short addr_count;
- unsigned char host_no;
- unsigned char model[9];
- unsigned char fw_ver[6];
- unsigned char full_model[18];
- unsigned char bus;
- unsigned char dev;
- unsigned char irq_ch;
- unsigned char scsi_id;
- bool irq_acquired:1;
- bool ext_trans_enable:1;
- bool parity:1;
- bool reset_enabled:1;
- bool level_int:1;
- bool wide:1;
- bool differential:1;
- bool scam:1;
- bool ultra:1;
- bool ext_lun:1;
- bool terminfo_valid:1;
- bool low_term:1;
- bool high_term:1;
- bool strict_rr:1;
- bool scam_enabled:1;
- bool scam_lev2:1;
- bool adapter_initd:1;
- bool adapter_extreset:1;
- bool adapter_intern_err:1;
- bool processing_ccbs;
- volatile bool adapter_cmd_complete;
- unsigned short adapter_sglimit;
- unsigned short drvr_sglimit;
- unsigned short maxdev;
- unsigned short maxlun;
- unsigned short mbox_count;
- unsigned short initccbs;
- unsigned short inc_ccbs;
- unsigned short alloc_ccbs;
- unsigned short drvr_qdepth;
- unsigned short adapter_qdepth;
- unsigned short untag_qdepth;
- unsigned short common_qdepth;
- unsigned short bus_settle_time;
- unsigned short sync_ok;
- unsigned short fast_ok;
- unsigned short ultra_ok;
- unsigned short wide_ok;
- unsigned short discon_ok;
- unsigned short tagq_ok;
- unsigned short ext_resets;
- unsigned short adapter_intern_errors;
- unsigned short tgt_count;
- unsigned short msgbuflen;
- u32 bios_addr;
- struct blogic_drvr_options *drvr_opts;
- struct fpoint_info fpinfo;
- void *cardhandle;
- struct list_head host_list;
- struct blogic_ccb *all_ccbs;
- struct blogic_ccb *free_ccbs;
- struct blogic_ccb *firstccb;
- struct blogic_ccb *lastccb;
- struct blogic_ccb *bdr_pend[BLOGIC_MAXDEV];
- struct blogic_tgt_flags tgt_flags[BLOGIC_MAXDEV];
- unsigned char qdepth[BLOGIC_MAXDEV];
- unsigned char sync_period[BLOGIC_MAXDEV];
- unsigned char sync_offset[BLOGIC_MAXDEV];
- unsigned char active_cmds[BLOGIC_MAXDEV];
- unsigned int cmds_since_rst[BLOGIC_MAXDEV];
- unsigned long last_seqpoint[BLOGIC_MAXDEV];
- unsigned long last_resettried[BLOGIC_MAXDEV];
- unsigned long last_resetdone[BLOGIC_MAXDEV];
- struct blogic_outbox *first_outbox;
- struct blogic_outbox *last_outbox;
- struct blogic_outbox *next_outbox;
- struct blogic_inbox *first_inbox;
- struct blogic_inbox *last_inbox;
- struct blogic_inbox *next_inbox;
- struct blogic_tgt_stats tgt_stats[BLOGIC_MAXDEV];
- unsigned char *mbox_space;
- dma_addr_t mbox_space_handle;
- unsigned int mbox_sz;
- unsigned long ccb_offset;
- char msgbuf[BLOGIC_MSGBUF_SIZE];
-};
-
-/*
- Define a structure for the BIOS Disk Parameters.
-*/
-
-struct bios_diskparam {
- int heads;
- int sectors;
- int cylinders;
-};
-
-/*
- Define a structure for the SCSI Inquiry command results.
-*/
-
-struct scsi_inquiry {
- unsigned char devtype:5; /* Byte 0 Bits 0-4 */
- unsigned char dev_qual:3; /* Byte 0 Bits 5-7 */
- unsigned char dev_modifier:7; /* Byte 1 Bits 0-6 */
- bool rmb:1; /* Byte 1 Bit 7 */
- unsigned char ansi_ver:3; /* Byte 2 Bits 0-2 */
- unsigned char ecma_ver:3; /* Byte 2 Bits 3-5 */
- unsigned char iso_ver:2; /* Byte 2 Bits 6-7 */
- unsigned char resp_fmt:4; /* Byte 3 Bits 0-3 */
- unsigned char:2; /* Byte 3 Bits 4-5 */
- bool TrmIOP:1; /* Byte 3 Bit 6 */
- bool AENC:1; /* Byte 3 Bit 7 */
- unsigned char addl_len; /* Byte 4 */
- unsigned char:8; /* Byte 5 */
- unsigned char:8; /* Byte 6 */
- bool SftRe:1; /* Byte 7 Bit 0 */
- bool CmdQue:1; /* Byte 7 Bit 1 */
- bool:1; /* Byte 7 Bit 2 */
- bool linked:1; /* Byte 7 Bit 3 */
- bool sync:1; /* Byte 7 Bit 4 */
- bool WBus16:1; /* Byte 7 Bit 5 */
- bool WBus32:1; /* Byte 7 Bit 6 */
- bool RelAdr:1; /* Byte 7 Bit 7 */
- unsigned char vendor[8]; /* Bytes 8-15 */
- unsigned char product[16]; /* Bytes 16-31 */
- unsigned char product_rev[4]; /* Bytes 32-35 */
-};
-
-
-/*
- Define functions to provide an abstraction for reading and writing the
- Host Adapter I/O Registers.
-*/
-
-static inline void blogic_busreset(struct blogic_adapter *adapter)
-{
- union blogic_cntrl_reg cr;
- cr.all = 0;
- cr.cr.bus_reset = true;
- outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
-}
-
-static inline void blogic_intreset(struct blogic_adapter *adapter)
-{
- union blogic_cntrl_reg cr;
- cr.all = 0;
- cr.cr.int_reset = true;
- outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
-}
-
-static inline void blogic_softreset(struct blogic_adapter *adapter)
-{
- union blogic_cntrl_reg cr;
- cr.all = 0;
- cr.cr.soft_reset = true;
- outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
-}
-
-static inline void blogic_hardreset(struct blogic_adapter *adapter)
-{
- union blogic_cntrl_reg cr;
- cr.all = 0;
- cr.cr.hard_reset = true;
- outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
-}
-
-static inline unsigned char blogic_rdstatus(struct blogic_adapter *adapter)
-{
- return inb(adapter->io_addr + BLOGIC_STATUS_REG);
-}
-
-static inline void blogic_setcmdparam(struct blogic_adapter *adapter,
- unsigned char value)
-{
- outb(value, adapter->io_addr + BLOGIC_CMD_PARM_REG);
-}
-
-static inline unsigned char blogic_rddatain(struct blogic_adapter *adapter)
-{
- return inb(adapter->io_addr + BLOGIC_DATAIN_REG);
-}
-
-static inline unsigned char blogic_rdint(struct blogic_adapter *adapter)
-{
- return inb(adapter->io_addr + BLOGIC_INT_REG);
-}
-
-static inline unsigned char blogic_rdgeom(struct blogic_adapter *adapter)
-{
- return inb(adapter->io_addr + BLOGIC_GEOMETRY_REG);
-}
-
-/*
- blogic_execmbox issues an Execute Mailbox Command, which
- notifies the Host Adapter that an entry has been made in an Outgoing
- Mailbox.
-*/
-
-static inline void blogic_execmbox(struct blogic_adapter *adapter)
-{
- blogic_setcmdparam(adapter, BLOGIC_EXEC_MBOX_CMD);
-}
-
-/*
- blogic_delay waits for Seconds to elapse.
-*/
-
-static inline void blogic_delay(int seconds)
-{
- mdelay(1000 * seconds);
-}
-
-/*
- virt_to_32bit_virt maps between Kernel Virtual Addresses and
- 32 bit Kernel Virtual Addresses. This avoids compilation warnings
- on 64 bit architectures.
-*/
-
-static inline u32 virt_to_32bit_virt(void *virt_addr)
-{
- return (u32) (unsigned long) virt_addr;
-}
-
-/*
- blogic_inc_count increments counter by 1, stopping at
- 65535 rather than wrapping around to 0.
-*/
-
-static inline void blogic_inc_count(unsigned short *count)
-{
- if (*count < 65535)
- (*count)++;
-}
-
-/*
- blogic_addcount increments Byte Counter by Amount.
-*/
-
-static inline void blogic_addcount(struct blogic_byte_count *bytecount,
- unsigned int amount)
-{
- bytecount->units += amount;
- if (bytecount->units > 999999999) {
- bytecount->units -= 1000000000;
- bytecount->billions++;
- }
-}
-
-/*
- blogic_incszbucket increments the Bucket for Amount.
-*/
-
-static inline void blogic_incszbucket(unsigned int *cmdsz_buckets,
- unsigned int amount)
-{
- int index = 0;
- if (amount < 8 * 1024) {
- if (amount < 2 * 1024)
- index = (amount < 1 * 1024 ? 0 : 1);
- else
- index = (amount < 4 * 1024 ? 2 : 3);
- } else if (amount < 128 * 1024) {
- if (amount < 32 * 1024)
- index = (amount < 16 * 1024 ? 4 : 5);
- else
- index = (amount < 64 * 1024 ? 6 : 7);
- } else
- index = (amount < 256 * 1024 ? 8 : 9);
- cmdsz_buckets[index]++;
-}
-
-/*
- Define the version number of the FlashPoint Firmware (SCCB Manager).
-*/
-
-#define FLASHPOINT_FW_VER "5.02"
-
-/*
- Define the possible return values from FlashPoint_HandleInterrupt.
-*/
-
-#define FPOINT_NORMAL_INT 0x00
-#define FPOINT_INTERN_ERR 0xFE
-#define FPOINT_EXT_RESET 0xFF
-
-/*
- Define prototypes for the forward referenced BusLogic Driver
- Internal Functions.
-*/
-
-static const char *blogic_drvr_info(struct Scsi_Host *);
-static int blogic_qcmd(struct Scsi_Host *h, struct scsi_cmnd *);
-static int blogic_diskparam(struct scsi_device *, struct block_device *, sector_t, int *);
-static int blogic_slaveconfig(struct scsi_device *);
-static void blogic_qcompleted_ccb(struct blogic_ccb *);
-static irqreturn_t blogic_inthandler(int, void *);
-static int blogic_resetadapter(struct blogic_adapter *, bool hard_reset);
-static void blogic_msg(enum blogic_msglevel, char *, struct blogic_adapter *, ...);
-static int __init blogic_setup(char *);
-
-#endif /* _BUSLOGIC_H */
diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c
deleted file mode 100644
index 90253208a72f..000000000000
--- a/drivers/scsi/FlashPoint.c
+++ /dev/null
@@ -1,7560 +0,0 @@
-/*
-
- FlashPoint.c -- FlashPoint SCCB Manager for Linux
-
- This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
- Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
- Linux compatibility. It was provided by BusLogic in the form of 16 separate
- source files, which would have unnecessarily cluttered the scsi directory, so
- the individual files have been combined into this single file.
-
- Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
-
- This file is available under both the GNU General Public License
- and a BSD-style copyright; see LICENSE.FlashPoint for details.
-
-*/
-
-
-#ifdef CONFIG_SCSI_FLASHPOINT
-
-#define MAX_CARDS 8
-#undef BUSTYPE_PCI
-
-#define CRCMASK 0xA001
-
-#define FAILURE 0xFFFFFFFFL
-
-struct sccb;
-typedef void (*CALL_BK_FN) (struct sccb *);
-
-struct sccb_mgr_info {
- u32 si_baseaddr;
- unsigned char si_present;
- unsigned char si_intvect;
- unsigned char si_id;
- unsigned char si_lun;
- u16 si_fw_revision;
- u16 si_per_targ_init_sync;
- u16 si_per_targ_fast_nego;
- u16 si_per_targ_ultra_nego;
- u16 si_per_targ_no_disc;
- u16 si_per_targ_wide_nego;
- u16 si_mflags;
- unsigned char si_card_family;
- unsigned char si_bustype;
- unsigned char si_card_model[3];
- unsigned char si_relative_cardnum;
- unsigned char si_reserved[4];
- u32 si_OS_reserved;
- unsigned char si_XlatInfo[4];
- u32 si_reserved2[5];
- u32 si_secondary_range;
-};
-
-#define SCSI_PARITY_ENA 0x0001
-#define LOW_BYTE_TERM 0x0010
-#define HIGH_BYTE_TERM 0x0020
-#define BUSTYPE_PCI 0x3
-
-#define SUPPORT_16TAR_32LUN 0x0002
-#define SOFT_RESET 0x0004
-#define EXTENDED_TRANSLATION 0x0008
-#define POST_ALL_UNDERRRUNS 0x0040
-#define FLAG_SCAM_ENABLED 0x0080
-#define FLAG_SCAM_LEVEL2 0x0100
-
-#define HARPOON_FAMILY 0x02
-
-/* SCCB struct used for both SCCB and UCB manager compiles!
- * The UCB Manager treats the SCCB as it's 'native hardware structure'
- */
-
-/*#pragma pack(1)*/
-struct sccb {
- unsigned char OperationCode;
- unsigned char ControlByte;
- unsigned char CdbLength;
- unsigned char RequestSenseLength;
- u32 DataLength;
- void *DataPointer;
- unsigned char CcbRes[2];
- unsigned char HostStatus;
- unsigned char TargetStatus;
- unsigned char TargID;
- unsigned char Lun;
- unsigned char Cdb[12];
- unsigned char CcbRes1;
- unsigned char Reserved1;
- u32 Reserved2;
- u32 SensePointer;
-
- CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
- u32 SccbIOPort; /* Identifies board base port */
- unsigned char SccbStatus;
- unsigned char SCCBRes2;
- u16 SccbOSFlags;
-
- u32 Sccb_XferCnt; /* actual transfer count */
- u32 Sccb_ATC;
- u32 SccbVirtDataPtr; /* virtual addr for OS/2 */
- u32 Sccb_res1;
- u16 Sccb_MGRFlags;
- u16 Sccb_sgseg;
- unsigned char Sccb_scsimsg; /* identify msg for selection */
- unsigned char Sccb_tag;
- unsigned char Sccb_scsistat;
- unsigned char Sccb_idmsg; /* image of last msg in */
- struct sccb *Sccb_forwardlink;
- struct sccb *Sccb_backlink;
- u32 Sccb_savedATC;
- unsigned char Save_Cdb[6];
- unsigned char Save_CdbLen;
- unsigned char Sccb_XferState;
- u32 Sccb_SGoffset;
-};
-
-#pragma pack()
-
-#define SCATTER_GATHER_COMMAND 0x02
-#define RESIDUAL_COMMAND 0x03
-#define RESIDUAL_SG_COMMAND 0x04
-#define RESET_COMMAND 0x81
-
-#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
-#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
-#define SCCB_DATA_XFER_OUT 0x10 /* Write */
-#define SCCB_DATA_XFER_IN 0x08 /* Read */
-
-#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
-
-#define BUS_FREE_ST 0
-#define SELECT_ST 1
-#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
-#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
-#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
-#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
-#define COMMAND_ST 6
-#define DATA_OUT_ST 7
-#define DATA_IN_ST 8
-#define DISCONNECT_ST 9
-#define ABORT_ST 11
-
-#define F_HOST_XFER_DIR 0x01
-#define F_ALL_XFERRED 0x02
-#define F_SG_XFER 0x04
-#define F_AUTO_SENSE 0x08
-#define F_ODD_BALL_CNT 0x10
-#define F_NO_DATA_YET 0x80
-
-#define F_STATUSLOADED 0x01
-#define F_DEV_SELECTED 0x04
-
-#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
-#define SCCB_DATA_UNDER_RUN 0x0C
-#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
-#define SCCB_DATA_OVER_RUN 0x12
-#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
-
-#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
-#define SCCB_BM_ERR 0x30 /* BusMaster error. */
-#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
-
-#define SCCB_IN_PROCESS 0x00
-#define SCCB_SUCCESS 0x01
-#define SCCB_ABORT 0x02
-#define SCCB_ERROR 0x04
-
-#define ORION_FW_REV 3110
-
-#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
-
-#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
-
-#define MAX_SCSI_TAR 16
-#define MAX_LUN 32
-#define LUN_MASK 0x1f
-
-#define SG_BUF_CNT 16 /*Number of prefetched elements. */
-
-#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
-
-#define RD_HARPOON(ioport) inb((u32)ioport)
-#define RDW_HARPOON(ioport) inw((u32)ioport)
-#define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
-#define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
-#define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
-#define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
-
-#define TAR_SYNC_MASK (BIT(7)+BIT(6))
-#define SYNC_TRYING BIT(6)
-#define SYNC_SUPPORTED (BIT(7)+BIT(6))
-
-#define TAR_WIDE_MASK (BIT(5)+BIT(4))
-#define WIDE_ENABLED BIT(4)
-#define WIDE_NEGOCIATED BIT(5)
-
-#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
-#define TAG_Q_TRYING BIT(2)
-#define TAG_Q_REJECT BIT(3)
-
-#define TAR_ALLOW_DISC BIT(0)
-
-#define EE_SYNC_MASK (BIT(0)+BIT(1))
-#define EE_SYNC_5MB BIT(0)
-#define EE_SYNC_10MB BIT(1)
-#define EE_SYNC_20MB (BIT(0)+BIT(1))
-
-#define EE_WIDE_SCSI BIT(7)
-
-struct sccb_mgr_tar_info {
-
- struct sccb *TarSelQ_Head;
- struct sccb *TarSelQ_Tail;
- unsigned char TarLUN_CA; /*Contingent Allgiance */
- unsigned char TarTagQ_Cnt;
- unsigned char TarSelQ_Cnt;
- unsigned char TarStatus;
- unsigned char TarEEValue;
- unsigned char TarSyncCtrl;
- unsigned char TarReserved[2]; /* for alignment */
- unsigned char LunDiscQ_Idx[MAX_LUN];
- unsigned char TarLUNBusy[MAX_LUN];
-};
-
-struct nvram_info {
- unsigned char niModel; /* Model No. of card */
- unsigned char niCardNo; /* Card no. */
- u32 niBaseAddr; /* Port Address of card */
- unsigned char niSysConf; /* Adapter Configuration byte -
- Byte 16 of eeprom map */
- unsigned char niScsiConf; /* SCSI Configuration byte -
- Byte 17 of eeprom map */
- unsigned char niScamConf; /* SCAM Configuration byte -
- Byte 20 of eeprom map */
- unsigned char niAdapId; /* Host Adapter ID -
- Byte 24 of eerpom map */
- unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte
- of targets */
- unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name
- string of Targets */
-};
-
-#define MODEL_LT 1
-#define MODEL_DL 2
-#define MODEL_LW 3
-#define MODEL_DW 4
-
-struct sccb_card {
- struct sccb *currentSCCB;
- struct sccb_mgr_info *cardInfo;
-
- u32 ioPort;
-
- unsigned short cmdCounter;
- unsigned char discQCount;
- unsigned char tagQ_Lst;
- unsigned char cardIndex;
- unsigned char scanIndex;
- unsigned char globalFlags;
- unsigned char ourId;
- struct nvram_info *pNvRamInfo;
- struct sccb *discQ_Tbl[QUEUE_DEPTH];
-
-};
-
-#define F_TAG_STARTED 0x01
-#define F_CONLUN_IO 0x02
-#define F_DO_RENEGO 0x04
-#define F_NO_FILTER 0x08
-#define F_GREEN_PC 0x10
-#define F_HOST_XFER_ACT 0x20
-#define F_NEW_SCCB_CMD 0x40
-#define F_UPDATE_EEPROM 0x80
-
-#define ID_STRING_LENGTH 32
-#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
-
-#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
-
-#define ASSIGN_ID 0x00
-#define SET_P_FLAG 0x01
-#define CFG_CMPLT 0x03
-#define DOM_MSTR 0x0F
-#define SYNC_PTRN 0x1F
-
-#define ID_0_7 0x18
-#define ID_8_F 0x11
-#define MISC_CODE 0x14
-#define CLR_P_FLAG 0x18
-
-#define INIT_SELTD 0x01
-#define LEVEL2_TAR 0x02
-
-enum scam_id_st { ID0, ID1, ID2, ID3, ID4, ID5, ID6, ID7, ID8, ID9, ID10, ID11,
- ID12,
- ID13, ID14, ID15, ID_UNUSED, ID_UNASSIGNED, ID_ASSIGNED, LEGACY,
- CLR_PRIORITY, NO_ID_AVAIL
-};
-
-typedef struct SCCBscam_info {
-
- unsigned char id_string[ID_STRING_LENGTH];
- enum scam_id_st state;
-
-} SCCBSCAM_INFO;
-
-
-#define SMIDENT 0x80
-#define DISC_PRIV 0x40
-
-#define SM8BIT 0x00
-#define SM16BIT 0x01
-
-#define SIX_BYTE_CMD 0x06
-#define TWELVE_BYTE_CMD 0x0C
-
-#define ASYNC 0x00
-#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
-
-#define EEPROM_WD_CNT 256
-
-#define EEPROM_CHECK_SUM 0
-#define FW_SIGNATURE 2
-#define MODEL_NUMB_0 4
-#define MODEL_NUMB_2 6
-#define MODEL_NUMB_4 8
-#define SYSTEM_CONFIG 16
-#define SCSI_CONFIG 17
-#define BIOS_CONFIG 18
-#define SCAM_CONFIG 20
-#define ADAPTER_SCSI_ID 24
-
-#define IGNORE_B_SCAN 32
-#define SEND_START_ENA 34
-#define DEVICE_ENABLE 36
-
-#define SYNC_RATE_TBL 38
-#define SYNC_RATE_TBL01 38
-#define SYNC_RATE_TBL23 40
-#define SYNC_RATE_TBL45 42
-#define SYNC_RATE_TBL67 44
-#define SYNC_RATE_TBL89 46
-#define SYNC_RATE_TBLab 48
-#define SYNC_RATE_TBLcd 50
-#define SYNC_RATE_TBLef 52
-
-#define EE_SCAMBASE 256
-
-#define SCAM_ENABLED BIT(2)
-#define SCAM_LEVEL2 BIT(3)
-
-#define RENEGO_ENA BIT(10)
-#define CONNIO_ENA BIT(11)
-#define GREEN_PC_ENA BIT(12)
-
-#define AUTO_RATE_00 00
-#define AUTO_RATE_05 01
-#define AUTO_RATE_10 02
-#define AUTO_RATE_20 03
-
-#define WIDE_NEGO_BIT BIT(7)
-#define DISC_ENABLE_BIT BIT(6)
-
-#define hp_vendor_id_0 0x00 /* LSB */
-#define ORION_VEND_0 0x4B
-
-#define hp_vendor_id_1 0x01 /* MSB */
-#define ORION_VEND_1 0x10
-
-#define hp_device_id_0 0x02 /* LSB */
-#define ORION_DEV_0 0x30
-
-#define hp_device_id_1 0x03 /* MSB */
-#define ORION_DEV_1 0x81
-
- /* Sub Vendor ID and Sub Device ID only available in
- Harpoon Version 2 and higher */
-
-#define hp_sub_device_id_0 0x06 /* LSB */
-
-#define hp_semaphore 0x0C
-#define SCCB_MGR_ACTIVE BIT(0)
-#define TICKLE_ME BIT(1)
-#define SCCB_MGR_PRESENT BIT(3)
-#define BIOS_IN_USE BIT(4)
-
-#define hp_sys_ctrl 0x0F
-
-#define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
-#define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
-#define HALT_MACH BIT(3) /*Halt State Machine */
-#define HARD_ABORT BIT(4) /*Hard Abort */
-
-#define hp_host_blk_cnt 0x13
-
-#define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */
-
-#define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */
-
-#define hp_int_mask 0x17
-
-#define INT_CMD_COMPL BIT(0) /* DMA command complete */
-#define INT_EXT_STATUS BIT(1) /* Extended Status Set */
-
-#define hp_xfer_cnt_lo 0x18
-#define hp_xfer_cnt_hi 0x1A
-#define hp_xfer_cmd 0x1B
-
-#define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
-#define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
-
-#define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
-
-#define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
-
-#define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
-
-#define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
-#define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
-
-#define hp_host_addr_lo 0x1C
-#define hp_host_addr_hmi 0x1E
-
-#define hp_ee_ctrl 0x22
-
-#define EXT_ARB_ACK BIT(7)
-#define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
-#define SEE_MS BIT(5)
-#define SEE_CS BIT(3)
-#define SEE_CLK BIT(2)
-#define SEE_DO BIT(1)
-#define SEE_DI BIT(0)
-
-#define EE_READ 0x06
-#define EE_WRITE 0x05
-#define EWEN 0x04
-#define EWEN_ADDR 0x03C0
-#define EWDS 0x04
-#define EWDS_ADDR 0x0000
-
-#define hp_bm_ctrl 0x26
-
-#define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
-#define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
-#define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
-#define FAST_SINGLE BIT(6) /*?? */
-
-#define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
-
-#define hp_sg_addr 0x28
-#define hp_page_ctrl 0x29
-
-#define SCATTER_EN BIT(0)
-#define SGRAM_ARAM BIT(1)
-#define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
-#define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
-
-#define hp_pci_stat_cfg 0x2D
-
-#define REC_MASTER_ABORT BIT(5) /*received Master abort */
-
-#define hp_rev_num 0x33
-
-#define hp_stack_data 0x34
-#define hp_stack_addr 0x35
-
-#define hp_ext_status 0x36
-
-#define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
-#define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
-#define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
-#define CMD_ABORTED BIT(4) /*Command aborted */
-#define BM_PARITY_ERR BIT(5) /*parity error on data received */
-#define PIO_OVERRUN BIT(6) /*Slave data overrun */
-#define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
-#define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
- BM_PARITY_ERR | PIO_OVERRUN)
-
-#define hp_int_status 0x37
-
-#define EXT_STATUS_ON BIT(1) /*Extended status is valid */
-#define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
-#define INT_ASSERTED BIT(5) /* */
-
-#define hp_fifo_cnt 0x38
-
-#define hp_intena 0x40
-
-#define RESET BIT(7)
-#define PROG_HLT BIT(6)
-#define PARITY BIT(5)
-#define FIFO BIT(4)
-#define SEL BIT(3)
-#define SCAM_SEL BIT(2)
-#define RSEL BIT(1)
-#define TIMEOUT BIT(0)
-#define BUS_FREE BIT(15)
-#define XFER_CNT_0 BIT(14)
-#define PHASE BIT(13)
-#define IUNKWN BIT(12)
-#define ICMD_COMP BIT(11)
-#define ITICKLE BIT(10)
-#define IDO_STRT BIT(9)
-#define ITAR_DISC BIT(8)
-#define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
-#define CLR_ALL_INT 0xFFFF
-#define CLR_ALL_INT_1 0xFF00
-
-#define hp_intstat 0x42
-
-#define hp_scsisig 0x44
-
-#define SCSI_SEL BIT(7)
-#define SCSI_BSY BIT(6)
-#define SCSI_REQ BIT(5)
-#define SCSI_ACK BIT(4)
-#define SCSI_ATN BIT(3)
-#define SCSI_CD BIT(2)
-#define SCSI_MSG BIT(1)
-#define SCSI_IOBIT BIT(0)
-
-#define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
-#define S_MSGO_PH (BIT(2)+BIT(1) )
-#define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
-#define S_DATAI_PH ( BIT(0))
-#define S_DATAO_PH 0x00
-#define S_ILL_PH ( BIT(1) )
-
-#define hp_scsictrl_0 0x45
-
-#define SEL_TAR BIT(6)
-#define ENA_ATN BIT(4)
-#define ENA_RESEL BIT(2)
-#define SCSI_RST BIT(1)
-#define ENA_SCAM_SEL BIT(0)
-
-#define hp_portctrl_0 0x46
-
-#define SCSI_PORT BIT(7)
-#define SCSI_INBIT BIT(6)
-#define DMA_PORT BIT(5)
-#define DMA_RD BIT(4)
-#define HOST_PORT BIT(3)
-#define HOST_WRT BIT(2)
-#define SCSI_BUS_EN BIT(1)
-#define START_TO BIT(0)
-
-#define hp_scsireset 0x47
-
-#define SCSI_INI BIT(6)
-#define SCAM_EN BIT(5)
-#define DMA_RESET BIT(3)
-#define HPSCSI_RESET BIT(2)
-#define PROG_RESET BIT(1)
-#define FIFO_CLR BIT(0)
-
-#define hp_xfercnt_0 0x48
-#define hp_xfercnt_2 0x4A
-
-#define hp_fifodata_0 0x4C
-#define hp_addstat 0x4E
-
-#define SCAM_TIMER BIT(7)
-#define SCSI_MODE8 BIT(3)
-#define SCSI_PAR_ERR BIT(0)
-
-#define hp_prgmcnt_0 0x4F
-
-#define hp_selfid_0 0x50
-#define hp_selfid_1 0x51
-#define hp_arb_id 0x52
-
-#define hp_select_id 0x53
-
-#define hp_synctarg_base 0x54
-#define hp_synctarg_12 0x54
-#define hp_synctarg_13 0x55
-#define hp_synctarg_14 0x56
-#define hp_synctarg_15 0x57
-
-#define hp_synctarg_8 0x58
-#define hp_synctarg_9 0x59
-#define hp_synctarg_10 0x5A
-#define hp_synctarg_11 0x5B
-
-#define hp_synctarg_4 0x5C
-#define hp_synctarg_5 0x5D
-#define hp_synctarg_6 0x5E
-#define hp_synctarg_7 0x5F
-
-#define hp_synctarg_0 0x60
-#define hp_synctarg_1 0x61
-#define hp_synctarg_2 0x62
-#define hp_synctarg_3 0x63
-
-#define NARROW_SCSI BIT(4)
-#define DEFAULT_OFFSET 0x0F
-
-#define hp_autostart_0 0x64
-#define hp_autostart_1 0x65
-#define hp_autostart_3 0x67
-
-#define AUTO_IMMED BIT(5)
-#define SELECT BIT(6)
-#define END_DATA (BIT(7)+BIT(6))
-
-#define hp_gp_reg_0 0x68
-#define hp_gp_reg_1 0x69
-#define hp_gp_reg_3 0x6B
-
-#define hp_seltimeout 0x6C
-
-#define TO_4ms 0x67 /* 3.9959ms */
-
-#define TO_5ms 0x03 /* 4.9152ms */
-#define TO_10ms 0x07 /* 11.xxxms */
-#define TO_250ms 0x99 /* 250.68ms */
-#define TO_290ms 0xB1 /* 289.99ms */
-
-#define hp_clkctrl_0 0x6D
-
-#define PWR_DWN BIT(6)
-#define ACTdeassert BIT(4)
-#define CLK_40MHZ (BIT(1) + BIT(0))
-
-#define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
-
-#define hp_fiforead 0x6E
-#define hp_fifowrite 0x6F
-
-#define hp_offsetctr 0x70
-#define hp_xferstat 0x71
-
-#define FIFO_EMPTY BIT(6)
-
-#define hp_portctrl_1 0x72
-
-#define CHK_SCSI_P BIT(3)
-#define HOST_MODE8 BIT(0)
-
-#define hp_xfer_pad 0x73
-
-#define ID_UNLOCK BIT(3)
-
-#define hp_scsidata_0 0x74
-#define hp_scsidata_1 0x75
-
-#define hp_aramBase 0x80
-#define BIOS_DATA_OFFSET 0x60
-#define BIOS_RELATIVE_CARD 0x64
-
-#define AR3 (BIT(9) + BIT(8))
-#define SDATA BIT(10)
-
-#define CRD_OP BIT(11) /* Cmp Reg. w/ Data */
-
-#define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */
-
-#define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
-
-#define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
-
-#define ADATA_OUT 0x00
-#define ADATA_IN BIT(8)
-#define ACOMMAND BIT(10)
-#define ASTATUS (BIT(10)+BIT(8))
-#define AMSG_OUT (BIT(10)+BIT(9))
-#define AMSG_IN (BIT(10)+BIT(9)+BIT(8))
-
-#define BRH_OP BIT(13) /* Branch */
-
-#define ALWAYS 0x00
-#define EQUAL BIT(8)
-#define NOT_EQ BIT(9)
-
-#define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */
-
-#define FIFO_0 BIT(10)
-
-#define MPM_OP BIT(15) /* Match phase and move data */
-
-#define MRR_OP BIT(14) /* Move DReg. to Reg. */
-
-#define S_IDREG (BIT(2)+BIT(1)+BIT(0))
-
-#define D_AR0 0x00
-#define D_AR1 BIT(0)
-#define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
-
-#define RAT_OP (BIT(14)+BIT(13)+BIT(11))
-
-#define SSI_OP (BIT(15)+BIT(11))
-
-#define SSI_ITAR_DISC (ITAR_DISC >> 8)
-#define SSI_IDO_STRT (IDO_STRT >> 8)
-
-#define SSI_ICMD_COMP (ICMD_COMP >> 8)
-#define SSI_ITICKLE (ITICKLE >> 8)
-
-#define SSI_IUNKWN (IUNKWN >> 8)
-#define SSI_INO_CC (IUNKWN >> 8)
-#define SSI_IRFAIL (IUNKWN >> 8)
-
-#define NP 0x10 /*Next Phase */
-#define NTCMD 0x02 /*Non- Tagged Command start */
-#define CMDPZ 0x04 /*Command phase */
-#define DINT 0x12 /*Data Out/In interrupt */
-#define DI 0x13 /*Data Out */
-#define DC 0x19 /*Disconnect Message */
-#define ST 0x1D /*Status Phase */
-#define UNKNWN 0x24 /*Unknown bus action */
-#define CC 0x25 /*Command Completion failure */
-#define TICK 0x26 /*New target reselected us. */
-#define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
-
-#define ID_MSG_STRT hp_aramBase + 0x00
-#define NON_TAG_ID_MSG hp_aramBase + 0x06
-#define CMD_STRT hp_aramBase + 0x08
-#define SYNC_MSGS hp_aramBase + 0x08
-
-#define TAG_STRT 0x00
-#define DISCONNECT_START 0x10/2
-#define END_DATA_START 0x14/2
-#define CMD_ONLY_STRT CMDPZ/2
-#define SELCHK_STRT SELCHK/2
-
-#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
-/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
- xfercnt <<= 16,\
- xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
- */
-#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
- addr >>= 16,\
- WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
- WR_HARP32(port,hp_xfercnt_0,count),\
- WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
- count >>= 16,\
- WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
-
-#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
- WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
-
-#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
- WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
-
-#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
- WR_HARPOON(port+hp_scsireset, 0x00))
-
-#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
- (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
-
-#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
- (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
-
-#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
- (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
-
-#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
- (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
-
-static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
- unsigned char syncFlag);
-static void FPT_ssel(u32 port, unsigned char p_card);
-static void FPT_sres(u32 port, unsigned char p_card,
- struct sccb_card *pCurrCard);
-static void FPT_shandem(u32 port, unsigned char p_card,
- struct sccb *pCurrSCCB);
-static void FPT_stsyncn(u32 port, unsigned char p_card);
-static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
- unsigned char offset);
-static void FPT_sssyncv(u32 p_port, unsigned char p_id,
- unsigned char p_sync_value,
- struct sccb_mgr_tar_info *currTar_Info);
-static void FPT_sresb(u32 port, unsigned char p_card);
-static void FPT_sxfrp(u32 p_port, unsigned char p_card);
-static void FPT_schkdd(u32 port, unsigned char p_card);
-static unsigned char FPT_RdStack(u32 port, unsigned char index);
-static void FPT_WrStack(u32 portBase, unsigned char index,
- unsigned char data);
-static unsigned char FPT_ChkIfChipInitialized(u32 ioPort);
-
-static void FPT_SendMsg(u32 port, unsigned char message);
-static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
- unsigned char error_code);
-
-static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
-static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
-
-static unsigned char FPT_siwidn(u32 port, unsigned char p_card);
-static void FPT_stwidn(u32 port, unsigned char p_card);
-static void FPT_siwidr(u32 port, unsigned char width);
-
-static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
- unsigned char p_card);
-static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card);
-static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
- struct sccb *p_SCCB, unsigned char p_card);
-static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
- unsigned char p_card);
-static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
-static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card);
-static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
- unsigned char p_card);
-static void FPT_utilUpdateResidual(struct sccb *p_SCCB);
-static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
-static unsigned char FPT_CalcLrc(unsigned char buffer[]);
-
-static void FPT_Wait1Second(u32 p_port);
-static void FPT_Wait(u32 p_port, unsigned char p_delay);
-static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode);
-static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
- unsigned short ee_addr);
-static unsigned short FPT_utilEERead(u32 p_port,
- unsigned short ee_addr);
-static unsigned short FPT_utilEEReadOrg(u32 p_port,
- unsigned short ee_addr);
-static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
- unsigned short ee_addr);
-
-static void FPT_phaseDataOut(u32 port, unsigned char p_card);
-static void FPT_phaseDataIn(u32 port, unsigned char p_card);
-static void FPT_phaseCommand(u32 port, unsigned char p_card);
-static void FPT_phaseStatus(u32 port, unsigned char p_card);
-static void FPT_phaseMsgOut(u32 port, unsigned char p_card);
-static void FPT_phaseMsgIn(u32 port, unsigned char p_card);
-static void FPT_phaseIllegal(u32 port, unsigned char p_card);
-
-static void FPT_phaseDecode(u32 port, unsigned char p_card);
-static void FPT_phaseChkFifo(u32 port, unsigned char p_card);
-static void FPT_phaseBusFree(u32 p_port, unsigned char p_card);
-
-static void FPT_XbowInit(u32 port, unsigned char scamFlg);
-static void FPT_BusMasterInit(u32 p_port);
-static void FPT_DiagEEPROM(u32 p_port);
-
-static void FPT_dataXferProcessor(u32 port,
- struct sccb_card *pCurrCard);
-static void FPT_busMstrSGDataXferStart(u32 port,
- struct sccb *pCurrSCCB);
-static void FPT_busMstrDataXferStart(u32 port,
- struct sccb *pCurrSCCB);
-static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
- struct sccb *pCurrSCCB);
-static void FPT_hostDataXferRestart(struct sccb *currSCCB);
-
-static unsigned char FPT_SccbMgr_bad_isr(u32 p_port,
- unsigned char p_card,
- struct sccb_card *pCurrCard,
- unsigned short p_int);
-
-static void FPT_SccbMgrTableInitAll(void);
-static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
- unsigned char p_card);
-static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
- unsigned char target);
-
-static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
- unsigned char p_power_up);
-
-static int FPT_scarb(u32 p_port, unsigned char p_sel_type);
-static void FPT_scbusf(u32 p_port);
-static void FPT_scsel(u32 p_port);
-static void FPT_scasid(unsigned char p_card, u32 p_port);
-static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data);
-static unsigned char FPT_scsendi(u32 p_port,
- unsigned char p_id_string[]);
-static unsigned char FPT_sciso(u32 p_port,
- unsigned char p_id_string[]);
-static void FPT_scwirod(u32 p_port, unsigned char p_data_bit);
-static void FPT_scwiros(u32 p_port, unsigned char p_data_bit);
-static unsigned char FPT_scvalq(unsigned char p_quintet);
-static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id);
-static void FPT_scwtsel(u32 p_port);
-static void FPT_inisci(unsigned char p_card, u32 p_port,
- unsigned char p_our_id);
-static void FPT_scsavdi(unsigned char p_card, u32 p_port);
-static unsigned char FPT_scmachid(unsigned char p_card,
- unsigned char p_id_string[]);
-
-static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card);
-static void FPT_autoLoadDefaultMap(u32 p_port);
-
-static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
- { {{0}} };
-static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} };
-static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} };
-static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} };
-
-static unsigned char FPT_mbCards = 0;
-static unsigned char FPT_scamHAString[] =
- { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
- ' ', 'B', 'T', '-', '9', '3', '0',
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
-};
-
-static unsigned short FPT_default_intena = 0;
-
-static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = {
-0};
-
-/*---------------------------------------------------------------------
- *
- * Function: FlashPoint_ProbeHostAdapter
- *
- * Description: Setup and/or Search for cards and return info to caller.
- *
- *---------------------------------------------------------------------*/
-
-static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
-{
- static unsigned char first_time = 1;
-
- unsigned char i, j, id, ScamFlg;
- unsigned short temp, temp2, temp3, temp4, temp5, temp6;
- u32 ioport;
- struct nvram_info *pCurrNvRam;
-
- ioport = pCardInfo->si_baseaddr;
-
- if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0)
- return (int)FAILURE;
-
- if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1))
- return (int)FAILURE;
-
- if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0))
- return (int)FAILURE;
-
- if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1))
- return (int)FAILURE;
-
- if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) {
-
-/* For new Harpoon then check for sub_device ID LSB
- the bits(0-3) must be all ZERO for compatible with
- current version of SCCBMgr, else skip this Harpoon
- device. */
-
- if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f)
- return (int)FAILURE;
- }
-
- if (first_time) {
- FPT_SccbMgrTableInitAll();
- first_time = 0;
- FPT_mbCards = 0;
- }
-
- if (FPT_RdStack(ioport, 0) != 0x00) {
- if (FPT_ChkIfChipInitialized(ioport) == 0) {
- pCurrNvRam = NULL;
- WR_HARPOON(ioport + hp_semaphore, 0x00);
- FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
- FPT_DiagEEPROM(ioport);
- } else {
- if (FPT_mbCards < MAX_MB_CARDS) {
- pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
- FPT_mbCards++;
- pCurrNvRam->niBaseAddr = ioport;
- FPT_RNVRamData(pCurrNvRam);
- } else
- return (int)FAILURE;
- }
- } else
- pCurrNvRam = NULL;
-
- WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
- WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
-
- if (pCurrNvRam)
- pCardInfo->si_id = pCurrNvRam->niAdapId;
- else
- pCardInfo->si_id =
- (unsigned
- char)(FPT_utilEERead(ioport,
- (ADAPTER_SCSI_ID /
- 2)) & (unsigned char)0x0FF);
-
- pCardInfo->si_lun = 0x00;
- pCardInfo->si_fw_revision = ORION_FW_REV;
- temp2 = 0x0000;
- temp3 = 0x0000;
- temp4 = 0x0000;
- temp5 = 0x0000;
- temp6 = 0x0000;
-
- for (id = 0; id < (16 / 2); id++) {
-
- if (pCurrNvRam) {
- temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
- temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
- (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
- } else
- temp =
- FPT_utilEERead(ioport,
- (unsigned short)((SYNC_RATE_TBL / 2)
- + id));
-
- for (i = 0; i < 2; temp >>= 8, i++) {
-
- temp2 >>= 1;
- temp3 >>= 1;
- temp4 >>= 1;
- temp5 >>= 1;
- temp6 >>= 1;
- switch (temp & 0x3) {
- case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
- temp6 |= 0x8000;
- fallthrough;
- case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
- temp5 |= 0x8000;
- fallthrough;
- case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
- temp2 |= 0x8000;
- fallthrough;
- case AUTO_RATE_00: /* Asynchronous */
- break;
- }
-
- if (temp & DISC_ENABLE_BIT)
- temp3 |= 0x8000;
-
- if (temp & WIDE_NEGO_BIT)
- temp4 |= 0x8000;
-
- }
- }
-
- pCardInfo->si_per_targ_init_sync = temp2;
- pCardInfo->si_per_targ_no_disc = temp3;
- pCardInfo->si_per_targ_wide_nego = temp4;
- pCardInfo->si_per_targ_fast_nego = temp5;
- pCardInfo->si_per_targ_ultra_nego = temp6;
-
- if (pCurrNvRam)
- i = pCurrNvRam->niSysConf;
- else
- i = (unsigned
- char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
-
- if (pCurrNvRam)
- ScamFlg = pCurrNvRam->niScamConf;
- else
- ScamFlg =
- (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
-
- pCardInfo->si_mflags = 0x0000;
-
- if (i & 0x01)
- pCardInfo->si_mflags |= SCSI_PARITY_ENA;
-
- if (!(i & 0x02))
- pCardInfo->si_mflags |= SOFT_RESET;
-
- if (i & 0x10)
- pCardInfo->si_mflags |= EXTENDED_TRANSLATION;
-
- if (ScamFlg & SCAM_ENABLED)
- pCardInfo->si_mflags |= FLAG_SCAM_ENABLED;
-
- if (ScamFlg & SCAM_LEVEL2)
- pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2;
-
- j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
- if (i & 0x04) {
- j |= SCSI_TERM_ENA_L;
- }
- WR_HARPOON(ioport + hp_bm_ctrl, j);
-
- j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
- if (i & 0x08) {
- j |= SCSI_TERM_ENA_H;
- }
- WR_HARPOON(ioport + hp_ee_ctrl, j);
-
- if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
-
- pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN;
-
- pCardInfo->si_card_family = HARPOON_FAMILY;
- pCardInfo->si_bustype = BUSTYPE_PCI;
-
- if (pCurrNvRam) {
- pCardInfo->si_card_model[0] = '9';
- switch (pCurrNvRam->niModel & 0x0f) {
- case MODEL_LT:
- pCardInfo->si_card_model[1] = '3';
- pCardInfo->si_card_model[2] = '0';
- break;
- case MODEL_LW:
- pCardInfo->si_card_model[1] = '5';
- pCardInfo->si_card_model[2] = '0';
- break;
- case MODEL_DL:
- pCardInfo->si_card_model[1] = '3';
- pCardInfo->si_card_model[2] = '2';
- break;
- case MODEL_DW:
- pCardInfo->si_card_model[1] = '5';
- pCardInfo->si_card_model[2] = '2';
- break;
- }
- } else {
- temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
- pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
- temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
-
- pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
- pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
- }
-
- if (pCardInfo->si_card_model[1] == '3') {
- if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
- pCardInfo->si_mflags |= LOW_BYTE_TERM;
- } else if (pCardInfo->si_card_model[2] == '0') {
- temp = RD_HARPOON(ioport + hp_xfer_pad);
- WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
- if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
- pCardInfo->si_mflags |= LOW_BYTE_TERM;
- WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
- if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
- pCardInfo->si_mflags |= HIGH_BYTE_TERM;
- WR_HARPOON(ioport + hp_xfer_pad, temp);
- } else {
- temp = RD_HARPOON(ioport + hp_ee_ctrl);
- temp2 = RD_HARPOON(ioport + hp_xfer_pad);
- WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
- WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
- temp3 = 0;
- for (i = 0; i < 8; i++) {
- temp3 <<= 1;
- if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
- temp3 |= 1;
- WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
- WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
- }
- WR_HARPOON(ioport + hp_ee_ctrl, temp);
- WR_HARPOON(ioport + hp_xfer_pad, temp2);
- if (!(temp3 & BIT(7)))
- pCardInfo->si_mflags |= LOW_BYTE_TERM;
- if (!(temp3 & BIT(6)))
- pCardInfo->si_mflags |= HIGH_BYTE_TERM;
- }
-
- ARAM_ACCESS(ioport);
-
- for (i = 0; i < 4; i++) {
-
- pCardInfo->si_XlatInfo[i] =
- RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
- }
-
- /* return with -1 if no sort, else return with
- logical card number sorted by BIOS (zero-based) */
-
- pCardInfo->si_relative_cardnum =
- (unsigned
- char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
-
- SGRAM_ACCESS(ioport);
-
- FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
- FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
- FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
- FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
- FPT_s_PhaseTbl[4] = FPT_phaseCommand;
- FPT_s_PhaseTbl[5] = FPT_phaseStatus;
- FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
- FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
-
- pCardInfo->si_present = 0x01;
-
- return 0;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FlashPoint_HardwareResetHostAdapter
- *
- * Description: Setup adapter for normal operation (hard reset).
- *
- *---------------------------------------------------------------------*/
-
-static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
- *pCardInfo)
-{
- struct sccb_card *CurrCard = NULL;
- struct nvram_info *pCurrNvRam;
- unsigned char i, j, thisCard, ScamFlg;
- unsigned short temp, sync_bit_map, id;
- u32 ioport;
-
- ioport = pCardInfo->si_baseaddr;
-
- for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
-
- if (thisCard == MAX_CARDS)
- return (void *)FAILURE;
-
- if (FPT_BL_Card[thisCard].ioPort == ioport) {
-
- CurrCard = &FPT_BL_Card[thisCard];
- FPT_SccbMgrTableInitCard(CurrCard, thisCard);
- break;
- }
-
- else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
-
- FPT_BL_Card[thisCard].ioPort = ioport;
- CurrCard = &FPT_BL_Card[thisCard];
-
- if (FPT_mbCards)
- for (i = 0; i < FPT_mbCards; i++) {
- if (CurrCard->ioPort ==
- FPT_nvRamInfo[i].niBaseAddr)
- CurrCard->pNvRamInfo =
- &FPT_nvRamInfo[i];
- }
- FPT_SccbMgrTableInitCard(CurrCard, thisCard);
- CurrCard->cardIndex = thisCard;
- CurrCard->cardInfo = pCardInfo;
-
- break;
- }
- }
-
- pCurrNvRam = CurrCard->pNvRamInfo;
-
- if (pCurrNvRam) {
- ScamFlg = pCurrNvRam->niScamConf;
- } else {
- ScamFlg =
- (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
- }
-
- FPT_BusMasterInit(ioport);
- FPT_XbowInit(ioport, ScamFlg);
-
- FPT_autoLoadDefaultMap(ioport);
-
- for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
- }
-
- WR_HARPOON(ioport + hp_selfid_0, id);
- WR_HARPOON(ioport + hp_selfid_1, 0x00);
- WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
- CurrCard->ourId = pCardInfo->si_id;
-
- i = (unsigned char)pCardInfo->si_mflags;
- if (i & SCSI_PARITY_ENA)
- WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
-
- j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
- if (i & LOW_BYTE_TERM)
- j |= SCSI_TERM_ENA_L;
- WR_HARPOON(ioport + hp_bm_ctrl, j);
-
- j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
- if (i & HIGH_BYTE_TERM)
- j |= SCSI_TERM_ENA_H;
- WR_HARPOON(ioport + hp_ee_ctrl, j);
-
- if (!(pCardInfo->si_mflags & SOFT_RESET)) {
-
- FPT_sresb(ioport, thisCard);
-
- FPT_scini(thisCard, pCardInfo->si_id, 0);
- }
-
- if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS)
- CurrCard->globalFlags |= F_NO_FILTER;
-
- if (pCurrNvRam) {
- if (pCurrNvRam->niSysConf & 0x10)
- CurrCard->globalFlags |= F_GREEN_PC;
- } else {
- if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
- CurrCard->globalFlags |= F_GREEN_PC;
- }
-
- /* Set global flag to indicate Re-Negotiation to be done on all
- ckeck condition */
- if (pCurrNvRam) {
- if (pCurrNvRam->niScsiConf & 0x04)
- CurrCard->globalFlags |= F_DO_RENEGO;
- } else {
- if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
- CurrCard->globalFlags |= F_DO_RENEGO;
- }
-
- if (pCurrNvRam) {
- if (pCurrNvRam->niScsiConf & 0x08)
- CurrCard->globalFlags |= F_CONLUN_IO;
- } else {
- if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
- CurrCard->globalFlags |= F_CONLUN_IO;
- }
-
- temp = pCardInfo->si_per_targ_no_disc;
-
- for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
-
- if (temp & id)
- FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
- }
-
- sync_bit_map = 0x0001;
-
- for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
-
- if (pCurrNvRam) {
- temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
- temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
- (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
- } else
- temp =
- FPT_utilEERead(ioport,
- (unsigned short)((SYNC_RATE_TBL / 2)
- + id));
-
- for (i = 0; i < 2; temp >>= 8, i++) {
-
- if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
-
- FPT_sccbMgrTbl[thisCard][id * 2 +
- i].TarEEValue =
- (unsigned char)temp;
- }
-
- else {
- FPT_sccbMgrTbl[thisCard][id * 2 +
- i].TarStatus |=
- SYNC_SUPPORTED;
- FPT_sccbMgrTbl[thisCard][id * 2 +
- i].TarEEValue =
- (unsigned char)(temp & ~EE_SYNC_MASK);
- }
-
-/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
- (id*2+i >= 8)){
-*/
- if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
-
- FPT_sccbMgrTbl[thisCard][id * 2 +
- i].TarEEValue |=
- EE_WIDE_SCSI;
-
- }
-
- else { /* NARROW SCSI */
- FPT_sccbMgrTbl[thisCard][id * 2 +
- i].TarStatus |=
- WIDE_NEGOCIATED;
- }
-
- sync_bit_map <<= 1;
-
- }
- }
-
- WR_HARPOON((ioport + hp_semaphore),
- (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
- SCCB_MGR_PRESENT));
-
- return (void *)CurrCard;
-}
-
-static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
-{
- unsigned char i;
- u32 portBase;
- u32 regOffset;
- u32 scamData;
- u32 *pScamTbl;
- struct nvram_info *pCurrNvRam;
-
- pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
-
- if (pCurrNvRam) {
- FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
- FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
- FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
- FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
- FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
-
- for (i = 0; i < MAX_SCSI_TAR / 2; i++)
- FPT_WrStack(pCurrNvRam->niBaseAddr,
- (unsigned char)(i + 5),
- pCurrNvRam->niSyncTbl[i]);
-
- portBase = pCurrNvRam->niBaseAddr;
-
- for (i = 0; i < MAX_SCSI_TAR; i++) {
- regOffset = hp_aramBase + 64 + i * 4;
- pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
- scamData = *pScamTbl;
- WR_HARP32(portBase, regOffset, scamData);
- }
-
- } else {
- FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
- }
-}
-
-static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
-{
- unsigned char i;
- u32 portBase;
- u32 regOffset;
- u32 scamData;
- u32 *pScamTbl;
-
- pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
- pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
- pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
- pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
- pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
-
- for (i = 0; i < MAX_SCSI_TAR / 2; i++)
- pNvRamInfo->niSyncTbl[i] =
- FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
-
- portBase = pNvRamInfo->niBaseAddr;
-
- for (i = 0; i < MAX_SCSI_TAR; i++) {
- regOffset = hp_aramBase + 64 + i * 4;
- RD_HARP32(portBase, regOffset, scamData);
- pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
- *pScamTbl = scamData;
- }
-
-}
-
-static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
-{
- WR_HARPOON(portBase + hp_stack_addr, index);
- return RD_HARPOON(portBase + hp_stack_data);
-}
-
-static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
-{
- WR_HARPOON(portBase + hp_stack_addr, index);
- WR_HARPOON(portBase + hp_stack_data, data);
-}
-
-static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
-{
- if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
- return 0;
- if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
- != CLKCTRL_DEFAULT)
- return 0;
- if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
- (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
- return 1;
- return 0;
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FlashPoint_StartCCB
- *
- * Description: Start a command pointed to by p_Sccb. When the
- * command is completed it will be returned via the
- * callback function.
- *
- *---------------------------------------------------------------------*/
-static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
-{
- u32 ioport;
- unsigned char thisCard, lun;
- struct sccb *pSaveSccb;
- CALL_BK_FN callback;
- struct sccb_card *pCurrCard = curr_card;
-
- thisCard = pCurrCard->cardIndex;
- ioport = pCurrCard->ioPort;
-
- if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
-
- p_Sccb->HostStatus = SCCB_COMPLETE;
- p_Sccb->SccbStatus = SCCB_ERROR;
- callback = (CALL_BK_FN) p_Sccb->SccbCallback;
- if (callback)
- callback(p_Sccb);
-
- return;
- }
-
- FPT_sinits(p_Sccb, thisCard);
-
- if (!pCurrCard->cmdCounter) {
- WR_HARPOON(ioport + hp_semaphore,
- (RD_HARPOON(ioport + hp_semaphore)
- | SCCB_MGR_ACTIVE));
-
- if (pCurrCard->globalFlags & F_GREEN_PC) {
- WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
- WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
- }
- }
-
- pCurrCard->cmdCounter++;
-
- if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
-
- WR_HARPOON(ioport + hp_semaphore,
- (RD_HARPOON(ioport + hp_semaphore)
- | TICKLE_ME));
- if (p_Sccb->OperationCode == RESET_COMMAND) {
- pSaveSccb =
- pCurrCard->currentSCCB;
- pCurrCard->currentSCCB = p_Sccb;
- FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
- pCurrCard->currentSCCB =
- pSaveSccb;
- } else {
- FPT_queueAddSccb(p_Sccb, thisCard);
- }
- }
-
- else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
-
- if (p_Sccb->OperationCode == RESET_COMMAND) {
- pSaveSccb =
- pCurrCard->currentSCCB;
- pCurrCard->currentSCCB = p_Sccb;
- FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
- pCurrCard->currentSCCB =
- pSaveSccb;
- } else {
- FPT_queueAddSccb(p_Sccb, thisCard);
- }
- }
-
- else {
-
- MDISABLE_INT(ioport);
-
- if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
- ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
- TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
- lun = p_Sccb->Lun;
- else
- lun = 0;
- if ((pCurrCard->currentSCCB == NULL) &&
- (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
- && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
- == 0)) {
-
- pCurrCard->currentSCCB = p_Sccb;
- FPT_ssel(p_Sccb->SccbIOPort, thisCard);
- }
-
- else {
-
- if (p_Sccb->OperationCode == RESET_COMMAND) {
- pSaveSccb = pCurrCard->currentSCCB;
- pCurrCard->currentSCCB = p_Sccb;
- FPT_queueSelectFail(&FPT_BL_Card[thisCard],
- thisCard);
- pCurrCard->currentSCCB = pSaveSccb;
- } else {
- FPT_queueAddSccb(p_Sccb, thisCard);
- }
- }
-
- MENABLE_INT(ioport);
- }
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FlashPoint_AbortCCB
- *
- * Description: Abort the command pointed to by p_Sccb. When the
- * command is completed it will be returned via the
- * callback function.
- *
- *---------------------------------------------------------------------*/
-static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
-{
- u32 ioport;
-
- unsigned char thisCard;
- CALL_BK_FN callback;
- struct sccb *pSaveSCCB;
- struct sccb_mgr_tar_info *currTar_Info;
-
- ioport = ((struct sccb_card *)pCurrCard)->ioPort;
-
- thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
-
- if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
-
- if (FPT_queueFindSccb(p_Sccb, thisCard)) {
-
- ((struct sccb_card *)pCurrCard)->cmdCounter--;
-
- if (!((struct sccb_card *)pCurrCard)->cmdCounter)
- WR_HARPOON(ioport + hp_semaphore,
- (RD_HARPOON(ioport + hp_semaphore)
- & (unsigned
- char)(~(SCCB_MGR_ACTIVE |
- TICKLE_ME))));
-
- p_Sccb->SccbStatus = SCCB_ABORT;
- callback = p_Sccb->SccbCallback;
- callback(p_Sccb);
-
- return 0;
- }
-
- else {
- if (((struct sccb_card *)pCurrCard)->currentSCCB ==
- p_Sccb) {
- p_Sccb->SccbStatus = SCCB_ABORT;
- return 0;
-
- }
-
- else {
- if (p_Sccb->Sccb_tag) {
- MDISABLE_INT(ioport);
- if (((struct sccb_card *)pCurrCard)->
- discQ_Tbl[p_Sccb->Sccb_tag] ==
- p_Sccb) {
- p_Sccb->SccbStatus = SCCB_ABORT;
- p_Sccb->Sccb_scsistat =
- ABORT_ST;
- p_Sccb->Sccb_scsimsg =
- ABORT_TASK;
-
- if (((struct sccb_card *)
- pCurrCard)->currentSCCB ==
- NULL) {
- ((struct sccb_card *)
- pCurrCard)->
- currentSCCB = p_Sccb;
- FPT_ssel(ioport,
- thisCard);
- } else {
- pSaveSCCB =
- ((struct sccb_card
- *)pCurrCard)->
- currentSCCB;
- ((struct sccb_card *)
- pCurrCard)->
- currentSCCB = p_Sccb;
- FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
- ((struct sccb_card *)
- pCurrCard)->
- currentSCCB = pSaveSCCB;
- }
- }
- MENABLE_INT(ioport);
- return 0;
- } else {
- currTar_Info =
- &FPT_sccbMgrTbl[thisCard][p_Sccb->
- TargID];
-
- if (FPT_BL_Card[thisCard].
- discQ_Tbl[currTar_Info->
- LunDiscQ_Idx[p_Sccb->Lun]]
- == p_Sccb) {
- p_Sccb->SccbStatus = SCCB_ABORT;
- return 0;
- }
- }
- }
- }
- }
- return -1;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FlashPoint_InterruptPending
- *
- * Description: Do a quick check to determine if there is a pending
- * interrupt for this card and disable the IRQ Pin if so.
- *
- *---------------------------------------------------------------------*/
-static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
-{
- u32 ioport;
-
- ioport = ((struct sccb_card *)pCurrCard)->ioPort;
-
- if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
- return 1;
- }
-
- else
-
- return 0;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FlashPoint_HandleInterrupt
- *
- * Description: This is our entry point when an interrupt is generated
- * by the card and the upper level driver passes it on to
- * us.
- *
- *---------------------------------------------------------------------*/
-static int FlashPoint_HandleInterrupt(void *pcard)
-{
- struct sccb *currSCCB;
- unsigned char thisCard, result, bm_status, bm_int_st;
- unsigned short hp_int;
- unsigned char i, target;
- struct sccb_card *pCurrCard = pcard;
- u32 ioport;
-
- thisCard = pCurrCard->cardIndex;
- ioport = pCurrCard->ioPort;
-
- MDISABLE_INT(ioport);
-
- if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON)
- bm_status = RD_HARPOON(ioport + hp_ext_status) &
- (unsigned char)BAD_EXT_STATUS;
- else
- bm_status = 0;
-
- WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
-
- while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
- FPT_default_intena) | bm_status) {
-
- currSCCB = pCurrCard->currentSCCB;
-
- if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
- result =
- FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
- hp_int);
- WRW_HARPOON((ioport + hp_intstat),
- (FIFO | TIMEOUT | RESET | SCAM_SEL));
- bm_status = 0;
-
- if (result) {
-
- MENABLE_INT(ioport);
- return result;
- }
- }
-
- else if (hp_int & ICMD_COMP) {
-
- if (!(hp_int & BUS_FREE)) {
- /* Wait for the BusFree before starting a new command. We
- must also check for being reselected since the BusFree
- may not show up if another device reselects us in 1.5us or
- less. SRR Wednesday, 3/8/1995.
- */
- while (!
- (RDW_HARPOON((ioport + hp_intstat)) &
- (BUS_FREE | RSEL))) ;
- }
-
- if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
-
- FPT_phaseChkFifo(ioport, thisCard);
-
-/* WRW_HARPOON((ioport+hp_intstat),
- (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
- */
-
- WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
-
- FPT_autoCmdCmplt(ioport, thisCard);
-
- }
-
- else if (hp_int & ITAR_DISC) {
-
- if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
- FPT_phaseChkFifo(ioport, thisCard);
-
- if (RD_HARPOON(ioport + hp_gp_reg_1) ==
- SAVE_POINTERS) {
-
- WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
- currSCCB->Sccb_XferState |= F_NO_DATA_YET;
-
- currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
- }
-
- currSCCB->Sccb_scsistat = DISCONNECT_ST;
- FPT_queueDisconnect(currSCCB, thisCard);
-
- /* Wait for the BusFree before starting a new command. We
- must also check for being reselected since the BusFree
- may not show up if another device reselects us in 1.5us or
- less. SRR Wednesday, 3/8/1995.
- */
- while (!
- (RDW_HARPOON((ioport + hp_intstat)) &
- (BUS_FREE | RSEL))
- && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
- && RD_HARPOON((ioport + hp_scsisig)) ==
- (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
- SCSI_IOBIT))) ;
-
- /*
- The additional loop exit condition above detects a timing problem
- with the revision D/E harpoon chips. The caller should reset the
- host adapter to recover when 0xFE is returned.
- */
- if (!
- (RDW_HARPOON((ioport + hp_intstat)) &
- (BUS_FREE | RSEL))) {
- MENABLE_INT(ioport);
- return 0xFE;
- }
-
- WRW_HARPOON((ioport + hp_intstat),
- (BUS_FREE | ITAR_DISC));
-
- pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
-
- }
-
- else if (hp_int & RSEL) {
-
- WRW_HARPOON((ioport + hp_intstat),
- (PROG_HLT | RSEL | PHASE | BUS_FREE));
-
- if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
- if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
- FPT_phaseChkFifo(ioport, thisCard);
-
- if (RD_HARPOON(ioport + hp_gp_reg_1) ==
- SAVE_POINTERS) {
- WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
- currSCCB->Sccb_XferState |=
- F_NO_DATA_YET;
- currSCCB->Sccb_savedATC =
- currSCCB->Sccb_ATC;
- }
-
- WRW_HARPOON((ioport + hp_intstat),
- (BUS_FREE | ITAR_DISC));
- currSCCB->Sccb_scsistat = DISCONNECT_ST;
- FPT_queueDisconnect(currSCCB, thisCard);
- }
-
- FPT_sres(ioport, thisCard, pCurrCard);
- FPT_phaseDecode(ioport, thisCard);
-
- }
-
- else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
-
- WRW_HARPOON((ioport + hp_intstat),
- (IDO_STRT | XFER_CNT_0));
- FPT_phaseDecode(ioport, thisCard);
-
- }
-
- else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
- WRW_HARPOON((ioport + hp_intstat),
- (PHASE | IUNKWN | PROG_HLT));
- if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
- 0x3f) < (unsigned char)SELCHK) {
- FPT_phaseDecode(ioport, thisCard);
- } else {
- /* Harpoon problem some SCSI target device respond to selection
- with short BUSY pulse (<400ns) this will make the Harpoon is not able
- to latch the correct Target ID into reg. x53.
- The work around require to correct this reg. But when write to this
- reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
- need to read this reg first then restore it later. After update to 0x53 */
-
- i = (unsigned
- char)(RD_HARPOON(ioport + hp_fifowrite));
- target =
- (unsigned
- char)(RD_HARPOON(ioport + hp_gp_reg_3));
- WR_HARPOON(ioport + hp_xfer_pad,
- (unsigned char)ID_UNLOCK);
- WR_HARPOON(ioport + hp_select_id,
- (unsigned char)(target | target <<
- 4));
- WR_HARPOON(ioport + hp_xfer_pad,
- (unsigned char)0x00);
- WR_HARPOON(ioport + hp_fifowrite, i);
- WR_HARPOON(ioport + hp_autostart_3,
- (AUTO_IMMED + TAG_STRT));
- }
- }
-
- else if (hp_int & XFER_CNT_0) {
-
- WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
-
- FPT_schkdd(ioport, thisCard);
-
- }
-
- else if (hp_int & BUS_FREE) {
-
- WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
-
- if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
-
- FPT_hostDataXferAbort(ioport, thisCard,
- currSCCB);
- }
-
- FPT_phaseBusFree(ioport, thisCard);
- }
-
- else if (hp_int & ITICKLE) {
-
- WRW_HARPOON((ioport + hp_intstat), ITICKLE);
- pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
- }
-
- if (((struct sccb_card *)pCurrCard)->
- globalFlags & F_NEW_SCCB_CMD) {
-
- pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
-
- if (pCurrCard->currentSCCB == NULL)
- FPT_queueSearchSelect(pCurrCard, thisCard);
-
- if (pCurrCard->currentSCCB != NULL) {
- pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
- FPT_ssel(ioport, thisCard);
- }
-
- break;
-
- }
-
- } /*end while */
-
- MENABLE_INT(ioport);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Sccb_bad_isr
- *
- * Description: Some type of interrupt has occurred which is slightly
- * out of the ordinary. We will now decode it fully, in
- * this routine. This is broken up in an attempt to save
- * processing time.
- *
- *---------------------------------------------------------------------*/
-static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
- struct sccb_card *pCurrCard,
- unsigned short p_int)
-{
- unsigned char temp, ScamFlg;
- struct sccb_mgr_tar_info *currTar_Info;
- struct nvram_info *pCurrNvRam;
-
- if (RD_HARPOON(p_port + hp_ext_status) &
- (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
-
- if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
-
- FPT_hostDataXferAbort(p_port, p_card,
- pCurrCard->currentSCCB);
- }
-
- if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
- {
- WR_HARPOON(p_port + hp_pci_stat_cfg,
- (RD_HARPOON(p_port + hp_pci_stat_cfg) &
- ~REC_MASTER_ABORT));
-
- WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
-
- }
-
- if (pCurrCard->currentSCCB != NULL) {
-
- if (!pCurrCard->currentSCCB->HostStatus)
- pCurrCard->currentSCCB->HostStatus =
- SCCB_BM_ERR;
-
- FPT_sxfrp(p_port, p_card);
-
- temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
- (EXT_ARB_ACK | SCSI_TERM_ENA_H));
- WR_HARPOON(p_port + hp_ee_ctrl,
- ((unsigned char)temp | SEE_MS | SEE_CS));
- WR_HARPOON(p_port + hp_ee_ctrl, temp);
-
- if (!
- (RDW_HARPOON((p_port + hp_intstat)) &
- (BUS_FREE | RESET))) {
- FPT_phaseDecode(p_port, p_card);
- }
- }
- }
-
- else if (p_int & RESET) {
-
- WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
- WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
- if (pCurrCard->currentSCCB != NULL) {
-
- if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
-
- FPT_hostDataXferAbort(p_port, p_card,
- pCurrCard->currentSCCB);
- }
-
- DISABLE_AUTO(p_port);
-
- FPT_sresb(p_port, p_card);
-
- while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
- }
-
- pCurrNvRam = pCurrCard->pNvRamInfo;
- if (pCurrNvRam) {
- ScamFlg = pCurrNvRam->niScamConf;
- } else {
- ScamFlg =
- (unsigned char)FPT_utilEERead(p_port,
- SCAM_CONFIG / 2);
- }
-
- FPT_XbowInit(p_port, ScamFlg);
-
- FPT_scini(p_card, pCurrCard->ourId, 0);
-
- return 0xFF;
- }
-
- else if (p_int & FIFO) {
-
- WRW_HARPOON((p_port + hp_intstat), FIFO);
-
- if (pCurrCard->currentSCCB != NULL)
- FPT_sxfrp(p_port, p_card);
- }
-
- else if (p_int & TIMEOUT) {
-
- DISABLE_AUTO(p_port);
-
- WRW_HARPOON((p_port + hp_intstat),
- (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
- IUNKWN));
-
- pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
-
- currTar_Info =
- &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
- if ((pCurrCard->globalFlags & F_CONLUN_IO)
- && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
- TAG_Q_TRYING))
- currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
- 0;
- else
- currTar_Info->TarLUNBusy[0] = 0;
-
- if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
- currTar_Info->TarSyncCtrl = 0;
- currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
- }
-
- if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
- currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
- }
-
- FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
- currTar_Info);
-
- FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
-
- }
-
- else if (p_int & SCAM_SEL) {
-
- FPT_scarb(p_port, LEVEL2_TAR);
- FPT_scsel(p_port);
- FPT_scasid(p_card, p_port);
-
- FPT_scbusf(p_port);
-
- WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
- }
-
- return 0x00;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: SccbMgrTableInit
- *
- * Description: Initialize all Sccb manager data structures.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_SccbMgrTableInitAll(void)
-{
- unsigned char thisCard;
-
- for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
- FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
-
- FPT_BL_Card[thisCard].ioPort = 0x00;
- FPT_BL_Card[thisCard].cardInfo = NULL;
- FPT_BL_Card[thisCard].cardIndex = 0xFF;
- FPT_BL_Card[thisCard].ourId = 0x00;
- FPT_BL_Card[thisCard].pNvRamInfo = NULL;
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: SccbMgrTableInit
- *
- * Description: Initialize all Sccb manager data structures.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
- unsigned char p_card)
-{
- unsigned char scsiID, qtag;
-
- for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
- FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
- }
-
- for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
- FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
- FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
- FPT_SccbMgrTableInitTarget(p_card, scsiID);
- }
-
- pCurrCard->scanIndex = 0x00;
- pCurrCard->currentSCCB = NULL;
- pCurrCard->globalFlags = 0x00;
- pCurrCard->cmdCounter = 0x00;
- pCurrCard->tagQ_Lst = 0x01;
- pCurrCard->discQCount = 0;
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: SccbMgrTableInit
- *
- * Description: Initialize all Sccb manager data structures.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
- unsigned char target)
-{
-
- unsigned char lun, qtag;
- struct sccb_mgr_tar_info *currTar_Info;
-
- currTar_Info = &FPT_sccbMgrTbl[p_card][target];
-
- currTar_Info->TarSelQ_Cnt = 0;
- currTar_Info->TarSyncCtrl = 0;
-
- currTar_Info->TarSelQ_Head = NULL;
- currTar_Info->TarSelQ_Tail = NULL;
- currTar_Info->TarTagQ_Cnt = 0;
- currTar_Info->TarLUN_CA = 0;
-
- for (lun = 0; lun < MAX_LUN; lun++) {
- currTar_Info->TarLUNBusy[lun] = 0;
- currTar_Info->LunDiscQ_Idx[lun] = 0;
- }
-
- for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
- if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
- if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
- target) {
- FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
- FPT_BL_Card[p_card].discQCount--;
- }
- }
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: sfetm
- *
- * Description: Read in a message byte from the SCSI bus, and check
- * for a parity error.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
-{
- unsigned char message;
- unsigned short TimeOutLoop;
-
- TimeOutLoop = 0;
- while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
- (TimeOutLoop++ < 20000)) {
- }
-
- WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
-
- message = RD_HARPOON(port + hp_scsidata_0);
-
- WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
-
- if (TimeOutLoop > 20000)
- message = 0x00; /* force message byte = 0 if Time Out on Req */
-
- if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
- (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
- WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
- WR_HARPOON(port + hp_xferstat, 0);
- WR_HARPOON(port + hp_fiforead, 0);
- WR_HARPOON(port + hp_fifowrite, 0);
- if (pCurrSCCB != NULL) {
- pCurrSCCB->Sccb_scsimsg = MSG_PARITY_ERROR;
- }
- message = 0x00;
- do {
- ACCEPT_MSG_ATN(port);
- TimeOutLoop = 0;
- while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
- (TimeOutLoop++ < 20000)) {
- }
- if (TimeOutLoop > 20000) {
- WRW_HARPOON((port + hp_intstat), PARITY);
- return message;
- }
- if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
- S_MSGI_PH) {
- WRW_HARPOON((port + hp_intstat), PARITY);
- return message;
- }
- WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
-
- RD_HARPOON(port + hp_scsidata_0);
-
- WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
-
- } while (1);
-
- }
- WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
- WR_HARPOON(port + hp_xferstat, 0);
- WR_HARPOON(port + hp_fiforead, 0);
- WR_HARPOON(port + hp_fifowrite, 0);
- return message;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_ssel
- *
- * Description: Load up automation and select target device.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_ssel(u32 port, unsigned char p_card)
-{
-
- unsigned char auto_loaded, i, target, *theCCB;
-
- u32 cdb_reg;
- struct sccb_card *CurrCard;
- struct sccb *currSCCB;
- struct sccb_mgr_tar_info *currTar_Info;
- unsigned char lastTag, lun;
-
- CurrCard = &FPT_BL_Card[p_card];
- currSCCB = CurrCard->currentSCCB;
- target = currSCCB->TargID;
- currTar_Info = &FPT_sccbMgrTbl[p_card][target];
- lastTag = CurrCard->tagQ_Lst;
-
- ARAM_ACCESS(port);
-
- if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
- currSCCB->ControlByte &= ~F_USE_CMD_Q;
-
- if (((CurrCard->globalFlags & F_CONLUN_IO) &&
- ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
-
- lun = currSCCB->Lun;
- else
- lun = 0;
-
- if (CurrCard->globalFlags & F_TAG_STARTED) {
- if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
- if ((currTar_Info->TarLUN_CA == 0)
- && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
- == TAG_Q_TRYING)) {
-
- if (currTar_Info->TarTagQ_Cnt != 0) {
- currTar_Info->TarLUNBusy[lun] = 1;
- FPT_queueSelectFail(CurrCard, p_card);
- SGRAM_ACCESS(port);
- return;
- }
-
- else {
- currTar_Info->TarLUNBusy[lun] = 1;
- }
-
- }
- /*End non-tagged */
- else {
- currTar_Info->TarLUNBusy[lun] = 1;
- }
-
- }
- /*!Use cmd Q Tagged */
- else {
- if (currTar_Info->TarLUN_CA == 1) {
- FPT_queueSelectFail(CurrCard, p_card);
- SGRAM_ACCESS(port);
- return;
- }
-
- currTar_Info->TarLUNBusy[lun] = 1;
-
- } /*else use cmd Q tagged */
-
- }
- /*if glob tagged started */
- else {
- currTar_Info->TarLUNBusy[lun] = 1;
- }
-
- if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
- ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
- || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
- if (CurrCard->discQCount >= QUEUE_DEPTH) {
- currTar_Info->TarLUNBusy[lun] = 1;
- FPT_queueSelectFail(CurrCard, p_card);
- SGRAM_ACCESS(port);
- return;
- }
- for (i = 1; i < QUEUE_DEPTH; i++) {
- if (++lastTag >= QUEUE_DEPTH)
- lastTag = 1;
- if (CurrCard->discQ_Tbl[lastTag] == NULL) {
- CurrCard->tagQ_Lst = lastTag;
- currTar_Info->LunDiscQ_Idx[lun] = lastTag;
- CurrCard->discQ_Tbl[lastTag] = currSCCB;
- CurrCard->discQCount++;
- break;
- }
- }
- if (i == QUEUE_DEPTH) {
- currTar_Info->TarLUNBusy[lun] = 1;
- FPT_queueSelectFail(CurrCard, p_card);
- SGRAM_ACCESS(port);
- return;
- }
- }
-
- auto_loaded = 0;
-
- WR_HARPOON(port + hp_select_id, target);
- WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
-
- if (currSCCB->OperationCode == RESET_COMMAND) {
- WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
- (currSCCB->
- Sccb_idmsg & ~DISC_PRIV)));
-
- WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
-
- currSCCB->Sccb_scsimsg = TARGET_RESET;
-
- WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
- auto_loaded = 1;
- currSCCB->Sccb_scsistat = SELECT_BDR_ST;
-
- if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
- currTar_Info->TarSyncCtrl = 0;
- currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
- }
-
- if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
- currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
- }
-
- FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
- FPT_SccbMgrTableInitTarget(p_card, target);
-
- }
-
- else if (currSCCB->Sccb_scsistat == ABORT_ST) {
- WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
- (currSCCB->
- Sccb_idmsg & ~DISC_PRIV)));
-
- WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
-
- WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
- (((unsigned
- char)(currSCCB->
- ControlByte &
- TAG_TYPE_MASK)
- >> 6) | (unsigned char)
- 0x20)));
- WRW_HARPOON((port + SYNC_MSGS + 2),
- (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
- WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
-
- WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
- auto_loaded = 1;
-
- }
-
- else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
- auto_loaded = FPT_siwidn(port, p_card);
- currSCCB->Sccb_scsistat = SELECT_WN_ST;
- }
-
- else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
- == SYNC_SUPPORTED)) {
- auto_loaded = FPT_sisyncn(port, p_card, 0);
- currSCCB->Sccb_scsistat = SELECT_SN_ST;
- }
-
- if (!auto_loaded) {
-
- if (currSCCB->ControlByte & F_USE_CMD_Q) {
-
- CurrCard->globalFlags |= F_TAG_STARTED;
-
- if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
- == TAG_Q_REJECT) {
- currSCCB->ControlByte &= ~F_USE_CMD_Q;
-
- /* Fix up the start instruction with a jump to
- Non-Tag-CMD handling */
- WRW_HARPOON((port + ID_MSG_STRT),
- BRH_OP + ALWAYS + NTCMD);
-
- WRW_HARPOON((port + NON_TAG_ID_MSG),
- (MPM_OP + AMSG_OUT +
- currSCCB->Sccb_idmsg));
-
- WR_HARPOON(port + hp_autostart_3,
- (SELECT + SELCHK_STRT));
-
- /* Setup our STATE so we know what happened when
- the wheels fall off. */
- currSCCB->Sccb_scsistat = SELECT_ST;
-
- currTar_Info->TarLUNBusy[lun] = 1;
- }
-
- else {
- WRW_HARPOON((port + ID_MSG_STRT),
- (MPM_OP + AMSG_OUT +
- currSCCB->Sccb_idmsg));
-
- WRW_HARPOON((port + ID_MSG_STRT + 2),
- (MPM_OP + AMSG_OUT +
- (((unsigned char)(currSCCB->
- ControlByte &
- TAG_TYPE_MASK)
- >> 6) | (unsigned char)0x20)));
-
- for (i = 1; i < QUEUE_DEPTH; i++) {
- if (++lastTag >= QUEUE_DEPTH)
- lastTag = 1;
- if (CurrCard->discQ_Tbl[lastTag] ==
- NULL) {
- WRW_HARPOON((port +
- ID_MSG_STRT + 6),
- (MPM_OP + AMSG_OUT +
- lastTag));
- CurrCard->tagQ_Lst = lastTag;
- currSCCB->Sccb_tag = lastTag;
- CurrCard->discQ_Tbl[lastTag] =
- currSCCB;
- CurrCard->discQCount++;
- break;
- }
- }
-
- if (i == QUEUE_DEPTH) {
- currTar_Info->TarLUNBusy[lun] = 1;
- FPT_queueSelectFail(CurrCard, p_card);
- SGRAM_ACCESS(port);
- return;
- }
-
- currSCCB->Sccb_scsistat = SELECT_Q_ST;
-
- WR_HARPOON(port + hp_autostart_3,
- (SELECT + SELCHK_STRT));
- }
- }
-
- else {
-
- WRW_HARPOON((port + ID_MSG_STRT),
- BRH_OP + ALWAYS + NTCMD);
-
- WRW_HARPOON((port + NON_TAG_ID_MSG),
- (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
-
- currSCCB->Sccb_scsistat = SELECT_ST;
-
- WR_HARPOON(port + hp_autostart_3,
- (SELECT + SELCHK_STRT));
- }
-
- theCCB = (unsigned char *)&currSCCB->Cdb[0];
-
- cdb_reg = port + CMD_STRT;
-
- for (i = 0; i < currSCCB->CdbLength; i++) {
- WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
- cdb_reg += 2;
- theCCB++;
- }
-
- if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
- WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
-
- }
- /* auto_loaded */
- WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
- WR_HARPOON(port + hp_xferstat, 0x00);
-
- WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
-
- WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
-
- if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
- WR_HARPOON(port + hp_scsictrl_0,
- (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
- } else {
-
-/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
- auto_loaded |= AUTO_IMMED; */
- auto_loaded = AUTO_IMMED;
-
- DISABLE_AUTO(port);
-
- WR_HARPOON(port + hp_autostart_3, auto_loaded);
- }
-
- SGRAM_ACCESS(port);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_sres
- *
- * Description: Hookup the correct CCB and handle the incoming messages.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_sres(u32 port, unsigned char p_card,
- struct sccb_card *pCurrCard)
-{
-
- unsigned char our_target, message, lun = 0, tag, msgRetryCount;
-
- struct sccb_mgr_tar_info *currTar_Info;
- struct sccb *currSCCB;
-
- if (pCurrCard->currentSCCB != NULL) {
- currTar_Info =
- &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
- DISABLE_AUTO(port);
-
- WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
-
- currSCCB = pCurrCard->currentSCCB;
- if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
- currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
- currSCCB->Sccb_scsistat = BUS_FREE_ST;
- }
- if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
- currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
- currSCCB->Sccb_scsistat = BUS_FREE_ST;
- }
- if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
- ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
- TAG_Q_TRYING))) {
- currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
- if (currSCCB->Sccb_scsistat != ABORT_ST) {
- pCurrCard->discQCount--;
- pCurrCard->discQ_Tbl[currTar_Info->
- LunDiscQ_Idx[currSCCB->
- Lun]]
- = NULL;
- }
- } else {
- currTar_Info->TarLUNBusy[0] = 0;
- if (currSCCB->Sccb_tag) {
- if (currSCCB->Sccb_scsistat != ABORT_ST) {
- pCurrCard->discQCount--;
- pCurrCard->discQ_Tbl[currSCCB->
- Sccb_tag] = NULL;
- }
- } else {
- if (currSCCB->Sccb_scsistat != ABORT_ST) {
- pCurrCard->discQCount--;
- pCurrCard->discQ_Tbl[currTar_Info->
- LunDiscQ_Idx[0]] =
- NULL;
- }
- }
- }
-
- FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
- }
-
- WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
-
- our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
- currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
-
- msgRetryCount = 0;
- do {
-
- currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
- tag = 0;
-
- while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
- if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
-
- WRW_HARPOON((port + hp_intstat), PHASE);
- return;
- }
- }
-
- WRW_HARPOON((port + hp_intstat), PHASE);
- if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
-
- message = FPT_sfm(port, pCurrCard->currentSCCB);
- if (message) {
-
- if (message <= (0x80 | LUN_MASK)) {
- lun = message & (unsigned char)LUN_MASK;
-
- if ((currTar_Info->
- TarStatus & TAR_TAG_Q_MASK) ==
- TAG_Q_TRYING) {
- if (currTar_Info->TarTagQ_Cnt !=
- 0) {
-
- if (!
- (currTar_Info->
- TarLUN_CA)) {
- ACCEPT_MSG(port); /*Release the ACK for ID msg. */
-
- message =
- FPT_sfm
- (port,
- pCurrCard->
- currentSCCB);
- if (message) {
- ACCEPT_MSG
- (port);
- }
-
- else
- message
- = 0;
-
- if (message !=
- 0) {
- tag =
- FPT_sfm
- (port,
- pCurrCard->
- currentSCCB);
-
- if (!
- (tag))
- message
- =
- 0;
- }
-
- }
- /*C.A. exists! */
- }
- /*End Q cnt != 0 */
- }
- /*End Tag cmds supported! */
- }
- /*End valid ID message. */
- else {
-
- ACCEPT_MSG_ATN(port);
- }
-
- }
- /* End good id message. */
- else {
-
- message = 0;
- }
- } else {
- ACCEPT_MSG_ATN(port);
-
- while (!
- (RDW_HARPOON((port + hp_intstat)) &
- (PHASE | RESET))
- && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
- && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
-
- return;
- }
-
- if (message == 0) {
- msgRetryCount++;
- if (msgRetryCount == 1) {
- FPT_SendMsg(port, MSG_PARITY_ERROR);
- } else {
- FPT_SendMsg(port, TARGET_RESET);
-
- FPT_sssyncv(port, our_target, NARROW_SCSI,
- currTar_Info);
-
- if (FPT_sccbMgrTbl[p_card][our_target].
- TarEEValue & EE_SYNC_MASK) {
-
- FPT_sccbMgrTbl[p_card][our_target].
- TarStatus &= ~TAR_SYNC_MASK;
-
- }
-
- if (FPT_sccbMgrTbl[p_card][our_target].
- TarEEValue & EE_WIDE_SCSI) {
-
- FPT_sccbMgrTbl[p_card][our_target].
- TarStatus &= ~TAR_WIDE_MASK;
- }
-
- FPT_queueFlushTargSccb(p_card, our_target,
- SCCB_COMPLETE);
- FPT_SccbMgrTableInitTarget(p_card, our_target);
- return;
- }
- }
- } while (message == 0);
-
- if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
- ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
- currTar_Info->TarLUNBusy[lun] = 1;
- pCurrCard->currentSCCB =
- pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
- if (pCurrCard->currentSCCB != NULL) {
- ACCEPT_MSG(port);
- } else {
- ACCEPT_MSG_ATN(port);
- }
- } else {
- currTar_Info->TarLUNBusy[0] = 1;
-
- if (tag) {
- if (pCurrCard->discQ_Tbl[tag] != NULL) {
- pCurrCard->currentSCCB =
- pCurrCard->discQ_Tbl[tag];
- currTar_Info->TarTagQ_Cnt--;
- ACCEPT_MSG(port);
- } else {
- ACCEPT_MSG_ATN(port);
- }
- } else {
- pCurrCard->currentSCCB =
- pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
- if (pCurrCard->currentSCCB != NULL) {
- ACCEPT_MSG(port);
- } else {
- ACCEPT_MSG_ATN(port);
- }
- }
- }
-
- if (pCurrCard->currentSCCB != NULL) {
- if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
- /* During Abort Tag command, the target could have got re-selected
- and completed the command. Check the select Q and remove the CCB
- if it is in the Select Q */
- FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
- }
- }
-
- while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
- !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
- (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
-}
-
-static void FPT_SendMsg(u32 port, unsigned char message)
-{
- while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
- if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
-
- WRW_HARPOON((port + hp_intstat), PHASE);
- return;
- }
- }
-
- WRW_HARPOON((port + hp_intstat), PHASE);
- if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
- WRW_HARPOON((port + hp_intstat),
- (BUS_FREE | PHASE | XFER_CNT_0));
-
- WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
-
- WR_HARPOON(port + hp_scsidata_0, message);
-
- WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
-
- ACCEPT_MSG(port);
-
- WR_HARPOON(port + hp_portctrl_0, 0x00);
-
- if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
- (message == ABORT_TASK)) {
- while (!
- (RDW_HARPOON((port + hp_intstat)) &
- (BUS_FREE | PHASE))) {
- }
-
- if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
- WRW_HARPOON((port + hp_intstat), BUS_FREE);
- }
- }
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_sdecm
- *
- * Description: Determine the proper response to the message from the
- * target device.
- *
- *---------------------------------------------------------------------*/
-static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
-{
- struct sccb *currSCCB;
- struct sccb_card *CurrCard;
- struct sccb_mgr_tar_info *currTar_Info;
-
- CurrCard = &FPT_BL_Card[p_card];
- currSCCB = CurrCard->currentSCCB;
-
- currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
-
- if (message == RESTORE_POINTERS) {
- if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
- currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
-
- FPT_hostDataXferRestart(currSCCB);
- }
-
- ACCEPT_MSG(port);
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
-
- else if (message == COMMAND_COMPLETE) {
-
- if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
- currTar_Info->TarStatus &=
- ~(unsigned char)TAR_TAG_Q_MASK;
- currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
- }
-
- ACCEPT_MSG(port);
-
- }
-
- else if ((message == NOP) || (message >= IDENTIFY_BASE) ||
- (message == INITIATE_RECOVERY) ||
- (message == RELEASE_RECOVERY)) {
-
- ACCEPT_MSG(port);
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
-
- else if (message == MESSAGE_REJECT) {
-
- if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
- (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
- ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
- || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
- TAG_Q_TRYING))
- {
- WRW_HARPOON((port + hp_intstat), BUS_FREE);
-
- ACCEPT_MSG(port);
-
- while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
- (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
- {
- }
-
- if (currSCCB->Lun == 0x00) {
- if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
-
- currTar_Info->TarStatus |=
- (unsigned char)SYNC_SUPPORTED;
-
- currTar_Info->TarEEValue &=
- ~EE_SYNC_MASK;
- }
-
- else if (currSCCB->Sccb_scsistat ==
- SELECT_WN_ST) {
-
- currTar_Info->TarStatus =
- (currTar_Info->
- TarStatus & ~WIDE_ENABLED) |
- WIDE_NEGOCIATED;
-
- currTar_Info->TarEEValue &=
- ~EE_WIDE_SCSI;
-
- }
-
- else if ((currTar_Info->
- TarStatus & TAR_TAG_Q_MASK) ==
- TAG_Q_TRYING) {
- currTar_Info->TarStatus =
- (currTar_Info->
- TarStatus & ~(unsigned char)
- TAR_TAG_Q_MASK) | TAG_Q_REJECT;
-
- currSCCB->ControlByte &= ~F_USE_CMD_Q;
- CurrCard->discQCount--;
- CurrCard->discQ_Tbl[currSCCB->
- Sccb_tag] = NULL;
- currSCCB->Sccb_tag = 0x00;
-
- }
- }
-
- if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
-
- if (currSCCB->Lun == 0x00) {
- WRW_HARPOON((port + hp_intstat),
- BUS_FREE);
- CurrCard->globalFlags |= F_NEW_SCCB_CMD;
- }
- }
-
- else {
-
- if ((CurrCard->globalFlags & F_CONLUN_IO) &&
- ((currTar_Info->
- TarStatus & TAR_TAG_Q_MASK) !=
- TAG_Q_TRYING))
- currTar_Info->TarLUNBusy[currSCCB->
- Lun] = 1;
- else
- currTar_Info->TarLUNBusy[0] = 1;
-
- currSCCB->ControlByte &=
- ~(unsigned char)F_USE_CMD_Q;
-
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
-
- }
- }
-
- else {
- ACCEPT_MSG(port);
-
- while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
- (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
- {
- }
-
- if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
- }
- }
-
- else if (message == EXTENDED_MESSAGE) {
-
- ACCEPT_MSG(port);
- FPT_shandem(port, p_card, currSCCB);
- }
-
- else if (message == IGNORE_WIDE_RESIDUE) {
-
- ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
-
- message = FPT_sfm(port, currSCCB);
-
- if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
- ACCEPT_MSG(port);
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
-
- else {
-
- currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
- currSCCB->Sccb_scsimsg = MESSAGE_REJECT;
-
- ACCEPT_MSG_ATN(port);
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_shandem
- *
- * Description: Decide what to do with the extended message.
- *
- *---------------------------------------------------------------------*/
-static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
-{
- unsigned char length, message;
-
- length = FPT_sfm(port, pCurrSCCB);
- if (length) {
-
- ACCEPT_MSG(port);
- message = FPT_sfm(port, pCurrSCCB);
- if (message) {
-
- if (message == EXTENDED_SDTR) {
-
- if (length == 0x03) {
-
- ACCEPT_MSG(port);
- FPT_stsyncn(port, p_card);
- } else {
-
- pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
- ACCEPT_MSG_ATN(port);
- }
- } else if (message == EXTENDED_WDTR) {
-
- if (length == 0x02) {
-
- ACCEPT_MSG(port);
- FPT_stwidn(port, p_card);
- } else {
-
- pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
- ACCEPT_MSG_ATN(port);
-
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED +
- DISCONNECT_START));
- }
- } else {
-
- pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
- ACCEPT_MSG_ATN(port);
-
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
- } else {
- if (pCurrSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
- ACCEPT_MSG(port);
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
- } else {
- if (pCurrSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_sisyncn
- *
- * Description: Read in a message byte from the SCSI bus, and check
- * for a parity error.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
- unsigned char syncFlag)
-{
- struct sccb *currSCCB;
- struct sccb_mgr_tar_info *currTar_Info;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
- currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
-
- if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
-
- WRW_HARPOON((port + ID_MSG_STRT),
- (MPM_OP + AMSG_OUT +
- (currSCCB->
- Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
-
- WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
-
- WRW_HARPOON((port + SYNC_MSGS + 0),
- (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
- WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
- WRW_HARPOON((port + SYNC_MSGS + 4),
- (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
-
- if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
-
- WRW_HARPOON((port + SYNC_MSGS + 6),
- (MPM_OP + AMSG_OUT + 12));
-
- else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
- EE_SYNC_10MB)
-
- WRW_HARPOON((port + SYNC_MSGS + 6),
- (MPM_OP + AMSG_OUT + 25));
-
- else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
- EE_SYNC_5MB)
-
- WRW_HARPOON((port + SYNC_MSGS + 6),
- (MPM_OP + AMSG_OUT + 50));
-
- else
- WRW_HARPOON((port + SYNC_MSGS + 6),
- (MPM_OP + AMSG_OUT + 00));
-
- WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
- WRW_HARPOON((port + SYNC_MSGS + 10),
- (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
- WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
-
- if (syncFlag == 0) {
- WR_HARPOON(port + hp_autostart_3,
- (SELECT + SELCHK_STRT));
- currTar_Info->TarStatus =
- ((currTar_Info->
- TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
- (unsigned char)SYNC_TRYING);
- } else {
- WR_HARPOON(port + hp_autostart_3,
- (AUTO_IMMED + CMD_ONLY_STRT));
- }
-
- return 1;
- }
-
- else {
-
- currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
- currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
- return 0;
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_stsyncn
- *
- * Description: The has sent us a Sync Nego message so handle it as
- * necessary.
- *
- *---------------------------------------------------------------------*/
-static void FPT_stsyncn(u32 port, unsigned char p_card)
-{
- unsigned char sync_msg, offset, sync_reg, our_sync_msg;
- struct sccb *currSCCB;
- struct sccb_mgr_tar_info *currTar_Info;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
- currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
-
- sync_msg = FPT_sfm(port, currSCCB);
-
- if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- return;
- }
-
- ACCEPT_MSG(port);
-
- offset = FPT_sfm(port, currSCCB);
-
- if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- return;
- }
-
- if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
-
- our_sync_msg = 12; /* Setup our Message to 20mb/s */
-
- else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
-
- our_sync_msg = 25; /* Setup our Message to 10mb/s */
-
- else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
-
- our_sync_msg = 50; /* Setup our Message to 5mb/s */
- else
-
- our_sync_msg = 0; /* Message = Async */
-
- if (sync_msg < our_sync_msg) {
- sync_msg = our_sync_msg; /*if faster, then set to max. */
- }
-
- if (offset == ASYNC)
- sync_msg = ASYNC;
-
- if (offset > MAX_OFFSET)
- offset = MAX_OFFSET;
-
- sync_reg = 0x00;
-
- if (sync_msg > 12)
-
- sync_reg = 0x20; /* Use 10MB/s */
-
- if (sync_msg > 25)
-
- sync_reg = 0x40; /* Use 6.6MB/s */
-
- if (sync_msg > 38)
-
- sync_reg = 0x60; /* Use 5MB/s */
-
- if (sync_msg > 50)
-
- sync_reg = 0x80; /* Use 4MB/s */
-
- if (sync_msg > 62)
-
- sync_reg = 0xA0; /* Use 3.33MB/s */
-
- if (sync_msg > 75)
-
- sync_reg = 0xC0; /* Use 2.85MB/s */
-
- if (sync_msg > 87)
-
- sync_reg = 0xE0; /* Use 2.5MB/s */
-
- if (sync_msg > 100) {
-
- sync_reg = 0x00; /* Use ASYNC */
- offset = 0x00;
- }
-
- if (currTar_Info->TarStatus & WIDE_ENABLED)
-
- sync_reg |= offset;
-
- else
-
- sync_reg |= (offset | NARROW_SCSI);
-
- FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
-
- if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
-
- ACCEPT_MSG(port);
-
- currTar_Info->TarStatus = ((currTar_Info->TarStatus &
- ~(unsigned char)TAR_SYNC_MASK) |
- (unsigned char)SYNC_SUPPORTED);
-
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
-
- else {
-
- ACCEPT_MSG_ATN(port);
-
- FPT_sisyncr(port, sync_msg, offset);
-
- currTar_Info->TarStatus = ((currTar_Info->TarStatus &
- ~(unsigned char)TAR_SYNC_MASK) |
- (unsigned char)SYNC_SUPPORTED);
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_sisyncr
- *
- * Description: Answer the targets sync message.
- *
- *---------------------------------------------------------------------*/
-static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
- unsigned char offset)
-{
- ARAM_ACCESS(port);
- WRW_HARPOON((port + SYNC_MSGS + 0),
- (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
- WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
- WRW_HARPOON((port + SYNC_MSGS + 4),
- (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
- WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
- WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
- WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
- WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
- SGRAM_ACCESS(port);
-
- WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
- WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
-
- WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
-
- while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_siwidn
- *
- * Description: Read in a message byte from the SCSI bus, and check
- * for a parity error.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
-{
- struct sccb *currSCCB;
- struct sccb_mgr_tar_info *currTar_Info;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
- currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
-
- if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
-
- WRW_HARPOON((port + ID_MSG_STRT),
- (MPM_OP + AMSG_OUT +
- (currSCCB->
- Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
-
- WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
-
- WRW_HARPOON((port + SYNC_MSGS + 0),
- (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
- WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
- WRW_HARPOON((port + SYNC_MSGS + 4),
- (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
- WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
- WRW_HARPOON((port + SYNC_MSGS + 8),
- (MPM_OP + AMSG_OUT + SM16BIT));
- WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
-
- WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
-
- currTar_Info->TarStatus = ((currTar_Info->TarStatus &
- ~(unsigned char)TAR_WIDE_MASK) |
- (unsigned char)WIDE_ENABLED);
-
- return 1;
- }
-
- else {
-
- currTar_Info->TarStatus = ((currTar_Info->TarStatus &
- ~(unsigned char)TAR_WIDE_MASK) |
- WIDE_NEGOCIATED);
-
- currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
- return 0;
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_stwidn
- *
- * Description: The has sent us a Wide Nego message so handle it as
- * necessary.
- *
- *---------------------------------------------------------------------*/
-static void FPT_stwidn(u32 port, unsigned char p_card)
-{
- unsigned char width;
- struct sccb *currSCCB;
- struct sccb_mgr_tar_info *currTar_Info;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
- currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
-
- width = FPT_sfm(port, currSCCB);
-
- if ((width == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- return;
- }
-
- if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
- width = 0;
-
- if (width) {
- currTar_Info->TarStatus |= WIDE_ENABLED;
- width = 0;
- } else {
- width = NARROW_SCSI;
- currTar_Info->TarStatus &= ~WIDE_ENABLED;
- }
-
- FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
-
- if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
-
- currTar_Info->TarStatus |= WIDE_NEGOCIATED;
-
- if (!
- ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
- SYNC_SUPPORTED)) {
- ACCEPT_MSG_ATN(port);
- ARAM_ACCESS(port);
- FPT_sisyncn(port, p_card, 1);
- currSCCB->Sccb_scsistat = SELECT_SN_ST;
- SGRAM_ACCESS(port);
- } else {
- ACCEPT_MSG(port);
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
- }
-
- else {
-
- ACCEPT_MSG_ATN(port);
-
- if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
- width = SM16BIT;
- else
- width = SM8BIT;
-
- FPT_siwidr(port, width);
-
- currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_siwidr
- *
- * Description: Answer the targets Wide nego message.
- *
- *---------------------------------------------------------------------*/
-static void FPT_siwidr(u32 port, unsigned char width)
-{
- ARAM_ACCESS(port);
- WRW_HARPOON((port + SYNC_MSGS + 0),
- (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
- WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
- WRW_HARPOON((port + SYNC_MSGS + 4),
- (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
- WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
- WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
- WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
- SGRAM_ACCESS(port);
-
- WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
- WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
-
- WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
-
- while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_sssyncv
- *
- * Description: Write the desired value to the Sync Register for the
- * ID specified.
- *
- *---------------------------------------------------------------------*/
-static void FPT_sssyncv(u32 p_port, unsigned char p_id,
- unsigned char p_sync_value,
- struct sccb_mgr_tar_info *currTar_Info)
-{
- unsigned char index;
-
- index = p_id;
-
- switch (index) {
-
- case 0:
- index = 12; /* hp_synctarg_0 */
- break;
- case 1:
- index = 13; /* hp_synctarg_1 */
- break;
- case 2:
- index = 14; /* hp_synctarg_2 */
- break;
- case 3:
- index = 15; /* hp_synctarg_3 */
- break;
- case 4:
- index = 8; /* hp_synctarg_4 */
- break;
- case 5:
- index = 9; /* hp_synctarg_5 */
- break;
- case 6:
- index = 10; /* hp_synctarg_6 */
- break;
- case 7:
- index = 11; /* hp_synctarg_7 */
- break;
- case 8:
- index = 4; /* hp_synctarg_8 */
- break;
- case 9:
- index = 5; /* hp_synctarg_9 */
- break;
- case 10:
- index = 6; /* hp_synctarg_10 */
- break;
- case 11:
- index = 7; /* hp_synctarg_11 */
- break;
- case 12:
- index = 0; /* hp_synctarg_12 */
- break;
- case 13:
- index = 1; /* hp_synctarg_13 */
- break;
- case 14:
- index = 2; /* hp_synctarg_14 */
- break;
- case 15:
- index = 3; /* hp_synctarg_15 */
-
- }
-
- WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
-
- currTar_Info->TarSyncCtrl = p_sync_value;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_sresb
- *
- * Description: Reset the desired card's SCSI bus.
- *
- *---------------------------------------------------------------------*/
-static void FPT_sresb(u32 port, unsigned char p_card)
-{
- unsigned char scsiID, i;
-
- struct sccb_mgr_tar_info *currTar_Info;
-
- WR_HARPOON(port + hp_page_ctrl,
- (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
- WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
-
- WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
-
- scsiID = RD_HARPOON(port + hp_seltimeout);
- WR_HARPOON(port + hp_seltimeout, TO_5ms);
- WRW_HARPOON((port + hp_intstat), TIMEOUT);
-
- WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
-
- while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
- }
-
- WR_HARPOON(port + hp_seltimeout, scsiID);
-
- WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
-
- FPT_Wait(port, TO_5ms);
-
- WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
-
- WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
-
- for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
- currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
-
- if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
- currTar_Info->TarSyncCtrl = 0;
- currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
- }
-
- if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
- currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
- }
-
- FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
-
- FPT_SccbMgrTableInitTarget(p_card, scsiID);
- }
-
- FPT_BL_Card[p_card].scanIndex = 0x00;
- FPT_BL_Card[p_card].currentSCCB = NULL;
- FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
- | F_NEW_SCCB_CMD);
- FPT_BL_Card[p_card].cmdCounter = 0x00;
- FPT_BL_Card[p_card].discQCount = 0x00;
- FPT_BL_Card[p_card].tagQ_Lst = 0x01;
-
- for (i = 0; i < QUEUE_DEPTH; i++)
- FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
-
- WR_HARPOON(port + hp_page_ctrl,
- (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_ssenss
- *
- * Description: Setup for the Auto Sense command.
- *
- *---------------------------------------------------------------------*/
-static void FPT_ssenss(struct sccb_card *pCurrCard)
-{
- unsigned char i;
- struct sccb *currSCCB;
-
- currSCCB = pCurrCard->currentSCCB;
-
- currSCCB->Save_CdbLen = currSCCB->CdbLength;
-
- for (i = 0; i < 6; i++) {
-
- currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
- }
-
- currSCCB->CdbLength = SIX_BYTE_CMD;
- currSCCB->Cdb[0] = REQUEST_SENSE;
- currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
- currSCCB->Cdb[2] = 0x00;
- currSCCB->Cdb[3] = 0x00;
- currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
- currSCCB->Cdb[5] = 0x00;
-
- currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
-
- currSCCB->Sccb_ATC = 0x00;
-
- currSCCB->Sccb_XferState |= F_AUTO_SENSE;
-
- currSCCB->Sccb_XferState &= ~F_SG_XFER;
-
- currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
-
- currSCCB->ControlByte = 0x00;
-
- currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_sxfrp
- *
- * Description: Transfer data into the bit bucket until the device
- * decides to switch phase.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_sxfrp(u32 p_port, unsigned char p_card)
-{
- unsigned char curr_phz;
-
- DISABLE_AUTO(p_port);
-
- if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
-
- FPT_hostDataXferAbort(p_port, p_card,
- FPT_BL_Card[p_card].currentSCCB);
-
- }
-
- /* If the Automation handled the end of the transfer then do not
- match the phase or we will get out of sync with the ISR. */
-
- if (RDW_HARPOON((p_port + hp_intstat)) &
- (BUS_FREE | XFER_CNT_0 | AUTO_INT))
- return;
-
- WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
-
- curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
-
- WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
-
- WR_HARPOON(p_port + hp_scsisig, curr_phz);
-
- while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
- (curr_phz ==
- (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
- {
- if (curr_phz & (unsigned char)SCSI_IOBIT) {
- WR_HARPOON(p_port + hp_portctrl_0,
- (SCSI_PORT | HOST_PORT | SCSI_INBIT));
-
- if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
- RD_HARPOON(p_port + hp_fifodata_0);
- }
- } else {
- WR_HARPOON(p_port + hp_portctrl_0,
- (SCSI_PORT | HOST_PORT | HOST_WRT));
- if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
- WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
- }
- }
- } /* End of While loop for padding data I/O phase */
-
- while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
- if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
- break;
- }
-
- WR_HARPOON(p_port + hp_portctrl_0,
- (SCSI_PORT | HOST_PORT | SCSI_INBIT));
- while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
- RD_HARPOON(p_port + hp_fifodata_0);
- }
-
- if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
- WR_HARPOON(p_port + hp_autostart_0,
- (AUTO_IMMED + DISCONNECT_START));
- while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
- }
-
- if (RDW_HARPOON((p_port + hp_intstat)) &
- (ICMD_COMP | ITAR_DISC))
- while (!
- (RDW_HARPOON((p_port + hp_intstat)) &
- (BUS_FREE | RSEL))) ;
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_schkdd
- *
- * Description: Make sure data has been flushed from both FIFOs and abort
- * the operations if necessary.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_schkdd(u32 port, unsigned char p_card)
-{
- unsigned short TimeOutLoop;
- unsigned char sPhase;
-
- struct sccb *currSCCB;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
-
- if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
- (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
- return;
- }
-
- if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
-
- currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
-
- currSCCB->Sccb_XferCnt = 1;
-
- currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
- WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
- WR_HARPOON(port + hp_xferstat, 0x00);
- }
-
- else {
-
- currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
-
- currSCCB->Sccb_XferCnt = 0;
- }
-
- if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
- (currSCCB->HostStatus == SCCB_COMPLETE)) {
-
- currSCCB->HostStatus = SCCB_PARITY_ERR;
- WRW_HARPOON((port + hp_intstat), PARITY);
- }
-
- FPT_hostDataXferAbort(port, p_card, currSCCB);
-
- while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
- }
-
- TimeOutLoop = 0;
-
- while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
- if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
- return;
- }
- if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
- break;
- }
- if (RDW_HARPOON((port + hp_intstat)) & RESET) {
- return;
- }
- if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
- || (TimeOutLoop++ > 0x3000))
- break;
- }
-
- sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
- if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
- (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
- (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
- (sPhase == (SCSI_BSY | S_DATAI_PH))) {
-
- WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
-
- if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
- if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
- FPT_phaseDataIn(port, p_card);
- }
-
- else {
- FPT_phaseDataOut(port, p_card);
- }
- } else {
- FPT_sxfrp(port, p_card);
- if (!(RDW_HARPOON((port + hp_intstat)) &
- (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
- WRW_HARPOON((port + hp_intstat), AUTO_INT);
- FPT_phaseDecode(port, p_card);
- }
- }
-
- }
-
- else {
- WR_HARPOON(port + hp_portctrl_0, 0x00);
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_sinits
- *
- * Description: Setup SCCB manager fields in this SCCB.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
-{
- struct sccb_mgr_tar_info *currTar_Info;
-
- if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
- return;
- }
- currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
-
- p_sccb->Sccb_XferState = 0x00;
- p_sccb->Sccb_XferCnt = p_sccb->DataLength;
-
- if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
- (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
-
- p_sccb->Sccb_SGoffset = 0;
- p_sccb->Sccb_XferState = F_SG_XFER;
- p_sccb->Sccb_XferCnt = 0x00;
- }
-
- if (p_sccb->DataLength == 0x00)
-
- p_sccb->Sccb_XferState |= F_ALL_XFERRED;
-
- if (p_sccb->ControlByte & F_USE_CMD_Q) {
- if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
- p_sccb->ControlByte &= ~F_USE_CMD_Q;
-
- else
- currTar_Info->TarStatus |= TAG_Q_TRYING;
- }
-
-/* For !single SCSI device in system & device allow Disconnect
- or command is tag_q type then send Cmd with Disconnect Enable
- else send Cmd with Disconnect Disable */
-
-/*
- if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
- (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
- (currTar_Info->TarStatus & TAG_Q_TRYING)) {
-*/
- if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
- (currTar_Info->TarStatus & TAG_Q_TRYING)) {
- p_sccb->Sccb_idmsg = IDENTIFY(true, p_sccb->Lun);
- } else {
- p_sccb->Sccb_idmsg = IDENTIFY(false, p_sccb->Lun);
- }
-
- p_sccb->HostStatus = 0x00;
- p_sccb->TargetStatus = 0x00;
- p_sccb->Sccb_tag = 0x00;
- p_sccb->Sccb_MGRFlags = 0x00;
- p_sccb->Sccb_sgseg = 0x00;
- p_sccb->Sccb_ATC = 0x00;
- p_sccb->Sccb_savedATC = 0x00;
-/*
- p_sccb->SccbVirtDataPtr = 0x00;
- p_sccb->Sccb_forwardlink = NULL;
- p_sccb->Sccb_backlink = NULL;
- */
- p_sccb->Sccb_scsistat = BUS_FREE_ST;
- p_sccb->SccbStatus = SCCB_IN_PROCESS;
- p_sccb->Sccb_scsimsg = NOP;
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Phase Decode
- *
- * Description: Determine the phase and call the appropriate function.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
-{
- unsigned char phase_ref;
- void (*phase) (u32, unsigned char);
-
- DISABLE_AUTO(p_port);
-
- phase_ref =
- (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
-
- phase = FPT_s_PhaseTbl[phase_ref];
-
- (*phase) (p_port, p_card); /* Call the correct phase func */
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Data Out Phase
- *
- * Description: Start up both the BusMaster and Xbow.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_phaseDataOut(u32 port, unsigned char p_card)
-{
-
- struct sccb *currSCCB;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
- if (currSCCB == NULL) {
- return; /* Exit if No SCCB record */
- }
-
- currSCCB->Sccb_scsistat = DATA_OUT_ST;
- currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
-
- WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
-
- WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
-
- WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
-
- FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
-
- if (currSCCB->Sccb_XferCnt == 0) {
-
- if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
- (currSCCB->HostStatus == SCCB_COMPLETE))
- currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
-
- FPT_sxfrp(port, p_card);
- if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
- FPT_phaseDecode(port, p_card);
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Data In Phase
- *
- * Description: Startup the BusMaster and the XBOW.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_phaseDataIn(u32 port, unsigned char p_card)
-{
-
- struct sccb *currSCCB;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
-
- if (currSCCB == NULL) {
- return; /* Exit if No SCCB record */
- }
-
- currSCCB->Sccb_scsistat = DATA_IN_ST;
- currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
- currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
-
- WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
-
- WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
-
- WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
-
- FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
-
- if (currSCCB->Sccb_XferCnt == 0) {
-
- if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
- (currSCCB->HostStatus == SCCB_COMPLETE))
- currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
-
- FPT_sxfrp(port, p_card);
- if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
- FPT_phaseDecode(port, p_card);
-
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Command Phase
- *
- * Description: Load the CDB into the automation and start it up.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
-{
- struct sccb *currSCCB;
- u32 cdb_reg;
- unsigned char i;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
-
- if (currSCCB->OperationCode == RESET_COMMAND) {
-
- currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
- currSCCB->CdbLength = SIX_BYTE_CMD;
- }
-
- WR_HARPOON(p_port + hp_scsisig, 0x00);
-
- ARAM_ACCESS(p_port);
-
- cdb_reg = p_port + CMD_STRT;
-
- for (i = 0; i < currSCCB->CdbLength; i++) {
-
- if (currSCCB->OperationCode == RESET_COMMAND)
-
- WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
-
- else
- WRW_HARPOON(cdb_reg,
- (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
- cdb_reg += 2;
- }
-
- if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
- WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
-
- WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
-
- currSCCB->Sccb_scsistat = COMMAND_ST;
-
- WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
- SGRAM_ACCESS(p_port);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Status phase
- *
- * Description: Bring in the status and command complete message bytes
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_phaseStatus(u32 port, unsigned char p_card)
-{
- /* Start-up the automation to finish off this command and let the
- isr handle the interrupt for command complete when it comes in.
- We could wait here for the interrupt to be generated?
- */
-
- WR_HARPOON(port + hp_scsisig, 0x00);
-
- WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Phase Message Out
- *
- * Description: Send out our message (if we have one) and handle whatever
- * else is involed.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
-{
- unsigned char message, scsiID;
- struct sccb *currSCCB;
- struct sccb_mgr_tar_info *currTar_Info;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
-
- if (currSCCB != NULL) {
-
- message = currSCCB->Sccb_scsimsg;
- scsiID = currSCCB->TargID;
-
- if (message == TARGET_RESET) {
-
- currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
- currTar_Info->TarSyncCtrl = 0;
- FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
-
- if (FPT_sccbMgrTbl[p_card][scsiID].
- TarEEValue & EE_SYNC_MASK) {
-
- FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
- ~TAR_SYNC_MASK;
-
- }
-
- if (FPT_sccbMgrTbl[p_card][scsiID].
- TarEEValue & EE_WIDE_SCSI) {
-
- FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
- ~TAR_WIDE_MASK;
- }
-
- FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
- FPT_SccbMgrTableInitTarget(p_card, scsiID);
- } else if (currSCCB->Sccb_scsistat == ABORT_ST) {
- currSCCB->HostStatus = SCCB_COMPLETE;
- if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
- NULL) {
- FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
- Sccb_tag] = NULL;
- FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
- }
-
- }
-
- else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
-
- if (message == NOP) {
- currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
-
- FPT_ssel(port, p_card);
- return;
- }
- } else {
-
- if (message == ABORT_TASK_SET)
-
- FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
- }
-
- } else {
- message = ABORT_TASK_SET;
- }
-
- WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
-
- WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
-
- WR_HARPOON(port + hp_scsidata_0, message);
-
- WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
-
- ACCEPT_MSG(port);
-
- WR_HARPOON(port + hp_portctrl_0, 0x00);
-
- if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
- (message == ABORT_TASK)) {
-
- while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
- }
-
- if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
- WRW_HARPOON((port + hp_intstat), BUS_FREE);
-
- if (currSCCB != NULL) {
-
- if ((FPT_BL_Card[p_card].
- globalFlags & F_CONLUN_IO)
- &&
- ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus & TAR_TAG_Q_MASK) !=
- TAG_Q_TRYING))
- FPT_sccbMgrTbl[p_card][currSCCB->
- TargID].
- TarLUNBusy[currSCCB->Lun] = 0;
- else
- FPT_sccbMgrTbl[p_card][currSCCB->
- TargID].
- TarLUNBusy[0] = 0;
-
- FPT_queueCmdComplete(&FPT_BL_Card[p_card],
- currSCCB, p_card);
- }
-
- else {
- FPT_BL_Card[p_card].globalFlags |=
- F_NEW_SCCB_CMD;
- }
- }
-
- else {
-
- FPT_sxfrp(port, p_card);
- }
- }
-
- else {
-
- if (message == MSG_PARITY_ERROR) {
- currSCCB->Sccb_scsimsg = NOP;
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- } else {
- FPT_sxfrp(port, p_card);
- }
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Message In phase
- *
- * Description: Bring in the message and determine what to do with it.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
-{
- unsigned char message;
- struct sccb *currSCCB;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
-
- if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
-
- FPT_phaseChkFifo(port, p_card);
- }
-
- message = RD_HARPOON(port + hp_scsidata_0);
- if ((message == DISCONNECT) || (message == SAVE_POINTERS)) {
-
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + END_DATA_START));
-
- }
-
- else {
-
- message = FPT_sfm(port, currSCCB);
- if (message) {
-
- FPT_sdecm(message, port, p_card);
-
- } else {
- if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
- ACCEPT_MSG(port);
- WR_HARPOON(port + hp_autostart_1,
- (AUTO_IMMED + DISCONNECT_START));
- }
- }
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Illegal phase
- *
- * Description: Target switched to some illegal phase, so all we can do
- * is report an error back to the host (if that is possible)
- * and send an ABORT message to the misbehaving target.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_phaseIllegal(u32 port, unsigned char p_card)
-{
- struct sccb *currSCCB;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
-
- WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
- if (currSCCB != NULL) {
-
- currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
- currSCCB->Sccb_scsistat = ABORT_ST;
- currSCCB->Sccb_scsimsg = ABORT_TASK_SET;
- }
-
- ACCEPT_MSG_ATN(port);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Phase Check FIFO
- *
- * Description: Make sure data has been flushed from both FIFOs and abort
- * the operations if necessary.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
-{
- u32 xfercnt;
- struct sccb *currSCCB;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
-
- if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
-
- while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
- (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
- }
-
- if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
- currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
-
- currSCCB->Sccb_XferCnt = 0;
-
- if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
- (currSCCB->HostStatus == SCCB_COMPLETE)) {
- currSCCB->HostStatus = SCCB_PARITY_ERR;
- WRW_HARPOON((port + hp_intstat), PARITY);
- }
-
- FPT_hostDataXferAbort(port, p_card, currSCCB);
-
- FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
-
- while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
- && (RD_HARPOON(port + hp_ext_status) &
- BM_CMD_BUSY)) {
- }
-
- }
- }
-
- /*End Data In specific code. */
- GET_XFER_CNT(port, xfercnt);
-
- WR_HARPOON(port + hp_xfercnt_0, 0x00);
-
- WR_HARPOON(port + hp_portctrl_0, 0x00);
-
- currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
-
- currSCCB->Sccb_XferCnt = xfercnt;
-
- if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
- (currSCCB->HostStatus == SCCB_COMPLETE)) {
-
- currSCCB->HostStatus = SCCB_PARITY_ERR;
- WRW_HARPOON((port + hp_intstat), PARITY);
- }
-
- FPT_hostDataXferAbort(port, p_card, currSCCB);
-
- WR_HARPOON(port + hp_fifowrite, 0x00);
- WR_HARPOON(port + hp_fiforead, 0x00);
- WR_HARPOON(port + hp_xferstat, 0x00);
-
- WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Phase Bus Free
- *
- * Description: We just went bus free so figure out if it was
- * because of command complete or from a disconnect.
- *
- *---------------------------------------------------------------------*/
-static void FPT_phaseBusFree(u32 port, unsigned char p_card)
-{
- struct sccb *currSCCB;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
-
- if (currSCCB != NULL) {
-
- DISABLE_AUTO(port);
-
- if (currSCCB->OperationCode == RESET_COMMAND) {
-
- if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
- ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[currSCCB->Lun] = 0;
- else
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[0] = 0;
-
- FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
- p_card);
-
- FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
-
- }
-
- else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
- (unsigned char)SYNC_SUPPORTED;
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
- ~EE_SYNC_MASK;
- }
-
- else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
- (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
-
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
- ~EE_WIDE_SCSI;
- }
-
- else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
- /* Make sure this is not a phony BUS_FREE. If we were
- reselected or if BUSY is NOT on then this is a
- valid BUS FREE. SRR Wednesday, 5/10/1995. */
-
- if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
- (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus &= ~TAR_TAG_Q_MASK;
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus |= TAG_Q_REJECT;
- }
-
- else {
- return;
- }
- }
-
- else {
-
- currSCCB->Sccb_scsistat = BUS_FREE_ST;
-
- if (!currSCCB->HostStatus) {
- currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
- }
-
- if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
- ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[currSCCB->Lun] = 0;
- else
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[0] = 0;
-
- FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
- p_card);
- return;
- }
-
- FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
-
- } /*end if !=null */
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Auto Load Default Map
- *
- * Description: Load the Automation RAM with the default map values.
- *
- *---------------------------------------------------------------------*/
-static void FPT_autoLoadDefaultMap(u32 p_port)
-{
- u32 map_addr;
-
- ARAM_ACCESS(p_port);
- map_addr = p_port + hp_aramBase;
-
- WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */
- map_addr += 2;
- WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */
- map_addr += 2;
- WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */
- map_addr += 2; /*This means AYNC DATA IN */
- WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */
- map_addr += 2;
- WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */
- map_addr += 2;
- WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
- map_addr += 2;
- WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */
- map_addr += 2;
- WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */
- map_addr += 2;
- WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */
- map_addr += 2;
- WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */
- map_addr += 2;
- WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */
- map_addr += 2;
- WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */
- map_addr += 2;
- WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */
- map_addr += 2;
- WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */
- map_addr += 2;
- WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
- map_addr += 2;
- WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
- map_addr += 2;
- WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */
- map_addr += 2;
- WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */
- map_addr += 2;
-
- WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
- map_addr += 2;
- WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
- map_addr += 2;
- WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */
- map_addr += 2;
- WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
- map_addr += 2; /* DIDN'T GET ONE */
- WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */
- map_addr += 2;
- WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */
- map_addr += 2;
- WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
-
- SGRAM_ACCESS(p_port);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Auto Command Complete
- *
- * Description: Post command back to host and find another command
- * to execute.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
-{
- struct sccb *currSCCB;
- unsigned char status_byte;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
-
- status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
-
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
-
- if (status_byte != SAM_STAT_GOOD) {
-
- if (status_byte == SAM_STAT_TASK_SET_FULL) {
-
- if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
- ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[currSCCB->Lun] = 1;
- if (FPT_BL_Card[p_card].discQCount != 0)
- FPT_BL_Card[p_card].discQCount--;
- FPT_BL_Card[p_card].
- discQ_Tbl[FPT_sccbMgrTbl[p_card]
- [currSCCB->TargID].
- LunDiscQ_Idx[currSCCB->Lun]] =
- NULL;
- } else {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[0] = 1;
- if (currSCCB->Sccb_tag) {
- if (FPT_BL_Card[p_card].discQCount != 0)
- FPT_BL_Card[p_card].
- discQCount--;
- FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
- Sccb_tag]
- = NULL;
- } else {
- if (FPT_BL_Card[p_card].discQCount != 0)
- FPT_BL_Card[p_card].
- discQCount--;
- FPT_BL_Card[p_card].
- discQ_Tbl[FPT_sccbMgrTbl[p_card]
- [currSCCB->TargID].
- LunDiscQ_Idx[0]] = NULL;
- }
- }
-
- currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
-
- FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
-
- return;
- }
-
- if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
- (unsigned char)SYNC_SUPPORTED;
-
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
- ~EE_SYNC_MASK;
- FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
-
- if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
- ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[currSCCB->Lun] = 1;
- if (FPT_BL_Card[p_card].discQCount != 0)
- FPT_BL_Card[p_card].discQCount--;
- FPT_BL_Card[p_card].
- discQ_Tbl[FPT_sccbMgrTbl[p_card]
- [currSCCB->TargID].
- LunDiscQ_Idx[currSCCB->Lun]] =
- NULL;
- } else {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[0] = 1;
- if (currSCCB->Sccb_tag) {
- if (FPT_BL_Card[p_card].discQCount != 0)
- FPT_BL_Card[p_card].
- discQCount--;
- FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
- Sccb_tag]
- = NULL;
- } else {
- if (FPT_BL_Card[p_card].discQCount != 0)
- FPT_BL_Card[p_card].
- discQCount--;
- FPT_BL_Card[p_card].
- discQ_Tbl[FPT_sccbMgrTbl[p_card]
- [currSCCB->TargID].
- LunDiscQ_Idx[0]] = NULL;
- }
- }
- return;
-
- }
-
- if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
-
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
- (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
-
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
- ~EE_WIDE_SCSI;
- FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
-
- if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
- ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[currSCCB->Lun] = 1;
- if (FPT_BL_Card[p_card].discQCount != 0)
- FPT_BL_Card[p_card].discQCount--;
- FPT_BL_Card[p_card].
- discQ_Tbl[FPT_sccbMgrTbl[p_card]
- [currSCCB->TargID].
- LunDiscQ_Idx[currSCCB->Lun]] =
- NULL;
- } else {
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUNBusy[0] = 1;
- if (currSCCB->Sccb_tag) {
- if (FPT_BL_Card[p_card].discQCount != 0)
- FPT_BL_Card[p_card].
- discQCount--;
- FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
- Sccb_tag]
- = NULL;
- } else {
- if (FPT_BL_Card[p_card].discQCount != 0)
- FPT_BL_Card[p_card].
- discQCount--;
- FPT_BL_Card[p_card].
- discQ_Tbl[FPT_sccbMgrTbl[p_card]
- [currSCCB->TargID].
- LunDiscQ_Idx[0]] = NULL;
- }
- }
- return;
-
- }
-
- if (status_byte == SAM_STAT_CHECK_CONDITION) {
- if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
- if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarEEValue & EE_SYNC_MASK) {
- FPT_sccbMgrTbl[p_card][currSCCB->
- TargID].
- TarStatus &= ~TAR_SYNC_MASK;
- }
- if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarEEValue & EE_WIDE_SCSI) {
- FPT_sccbMgrTbl[p_card][currSCCB->
- TargID].
- TarStatus &= ~TAR_WIDE_MASK;
- }
- }
- }
-
- if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
-
- currSCCB->SccbStatus = SCCB_ERROR;
- currSCCB->TargetStatus = status_byte;
-
- if (status_byte == SAM_STAT_CHECK_CONDITION) {
-
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarLUN_CA = 1;
-
- if (currSCCB->RequestSenseLength !=
- NO_AUTO_REQUEST_SENSE) {
-
- if (currSCCB->RequestSenseLength == 0)
- currSCCB->RequestSenseLength =
- 14;
-
- FPT_ssenss(&FPT_BL_Card[p_card]);
- FPT_BL_Card[p_card].globalFlags |=
- F_NEW_SCCB_CMD;
-
- if (((FPT_BL_Card[p_card].
- globalFlags & F_CONLUN_IO)
- &&
- ((FPT_sccbMgrTbl[p_card]
- [currSCCB->TargID].
- TarStatus & TAR_TAG_Q_MASK) !=
- TAG_Q_TRYING))) {
- FPT_sccbMgrTbl[p_card]
- [currSCCB->TargID].
- TarLUNBusy[currSCCB->Lun] =
- 1;
- if (FPT_BL_Card[p_card].
- discQCount != 0)
- FPT_BL_Card[p_card].
- discQCount--;
- FPT_BL_Card[p_card].
- discQ_Tbl[FPT_sccbMgrTbl
- [p_card]
- [currSCCB->
- TargID].
- LunDiscQ_Idx
- [currSCCB->Lun]] =
- NULL;
- } else {
- FPT_sccbMgrTbl[p_card]
- [currSCCB->TargID].
- TarLUNBusy[0] = 1;
- if (currSCCB->Sccb_tag) {
- if (FPT_BL_Card[p_card].
- discQCount != 0)
- FPT_BL_Card
- [p_card].
- discQCount--;
- FPT_BL_Card[p_card].
- discQ_Tbl[currSCCB->
- Sccb_tag]
- = NULL;
- } else {
- if (FPT_BL_Card[p_card].
- discQCount != 0)
- FPT_BL_Card
- [p_card].
- discQCount--;
- FPT_BL_Card[p_card].
- discQ_Tbl
- [FPT_sccbMgrTbl
- [p_card][currSCCB->
- TargID].
- LunDiscQ_Idx[0]] =
- NULL;
- }
- }
- return;
- }
- }
- }
- }
-
- if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
- ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
- TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
- Lun] = 0;
- else
- FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
-
- FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
-}
-
-#define SHORT_WAIT 0x0000000F
-#define LONG_WAIT 0x0000FFFFL
-
-/*---------------------------------------------------------------------
- *
- * Function: Data Transfer Processor
- *
- * Description: This routine performs two tasks.
- * (1) Start data transfer by calling HOST_DATA_XFER_START
- * function. Once data transfer is started, (2) Depends
- * on the type of data transfer mode Scatter/Gather mode
- * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
- * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
- * data transfer done. In Scatter/Gather mode, this routine
- * checks bus master command complete and dual rank busy
- * bit to keep chaining SC transfer command. Similarly,
- * in Scatter/Gather mode, it checks Sccb_MGRFlag
- * (F_HOST_XFER_ACT bit) for data transfer done.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
-{
- struct sccb *currSCCB;
-
- currSCCB = pCurrCard->currentSCCB;
-
- if (currSCCB->Sccb_XferState & F_SG_XFER) {
- if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
- {
- currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
- currSCCB->Sccb_SGoffset = 0x00;
- }
- pCurrCard->globalFlags |= F_HOST_XFER_ACT;
-
- FPT_busMstrSGDataXferStart(port, currSCCB);
- }
-
- else {
- if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
- pCurrCard->globalFlags |= F_HOST_XFER_ACT;
-
- FPT_busMstrDataXferStart(port, currSCCB);
- }
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: BusMaster Scatter Gather Data Transfer Start
- *
- * Description:
- *
- *---------------------------------------------------------------------*/
-static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
-{
- u32 count, addr, tmpSGCnt;
- unsigned int sg_index;
- unsigned char sg_count, i;
- u32 reg_offset;
- struct blogic_sg_seg *segp;
-
- if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
- count = ((u32)HOST_RD_CMD) << 24;
- else
- count = ((u32)HOST_WRT_CMD) << 24;
-
- sg_count = 0;
- tmpSGCnt = 0;
- sg_index = pcurrSCCB->Sccb_sgseg;
- reg_offset = hp_aramBase;
-
- i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
- ~(SGRAM_ARAM | SCATTER_EN));
-
- WR_HARPOON(p_port + hp_page_ctrl, i);
-
- while ((sg_count < (unsigned char)SG_BUF_CNT) &&
- ((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
- pcurrSCCB->DataLength)) {
-
- segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
- sg_index;
- tmpSGCnt += segp->segbytes;
- count |= segp->segbytes;
- addr = segp->segdata;
-
- if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
- addr +=
- ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
- count =
- (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
- tmpSGCnt = count & 0x00FFFFFFL;
- }
-
- WR_HARP32(p_port, reg_offset, addr);
- reg_offset += 4;
-
- WR_HARP32(p_port, reg_offset, count);
- reg_offset += 4;
-
- count &= 0xFF000000L;
- sg_index++;
- sg_count++;
-
- } /*End While */
-
- pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
-
- WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
-
- if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
-
- WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
-
- WR_HARPOON(p_port + hp_portctrl_0,
- (DMA_PORT | SCSI_PORT | SCSI_INBIT));
- WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
- }
-
- else {
-
- if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
- (tmpSGCnt & 0x000000001)) {
-
- pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
- tmpSGCnt--;
- }
-
- WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
-
- WR_HARPOON(p_port + hp_portctrl_0,
- (SCSI_PORT | DMA_PORT | DMA_RD));
- WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
- }
-
- WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: BusMaster Data Transfer Start
- *
- * Description:
- *
- *---------------------------------------------------------------------*/
-static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
-{
- u32 addr, count;
-
- if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
-
- count = pcurrSCCB->Sccb_XferCnt;
-
- addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
- }
-
- else {
- addr = pcurrSCCB->SensePointer;
- count = pcurrSCCB->RequestSenseLength;
-
- }
-
- HP_SETUP_ADDR_CNT(p_port, addr, count);
-
- if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
-
- WR_HARPOON(p_port + hp_portctrl_0,
- (DMA_PORT | SCSI_PORT | SCSI_INBIT));
- WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
-
- WR_HARPOON(p_port + hp_xfer_cmd,
- (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
- }
-
- else {
-
- WR_HARPOON(p_port + hp_portctrl_0,
- (SCSI_PORT | DMA_PORT | DMA_RD));
- WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
-
- WR_HARPOON(p_port + hp_xfer_cmd,
- (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
-
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: BusMaster Timeout Handler
- *
- * Description: This function is called after a bus master command busy time
- * out is detected. This routines issue halt state machine
- * with a software time out for command busy. If command busy
- * is still asserted at the end of the time out, it issues
- * hard abort with another software time out. It hard abort
- * command busy is also time out, it'll just give up.
- *
- *---------------------------------------------------------------------*/
-static unsigned char FPT_busMstrTimeOut(u32 p_port)
-{
- unsigned long timeout;
-
- timeout = LONG_WAIT;
-
- WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
-
- while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
- && timeout--) {
- }
-
- if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
- WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
-
- timeout = LONG_WAIT;
- while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
- && timeout--) {
- }
- }
-
- RD_HARPOON(p_port + hp_int_status); /*Clear command complete */
-
- if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
- return 1;
- }
-
- else {
- return 0;
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Host Data Transfer Abort
- *
- * Description: Abort any in progress transfer.
- *
- *---------------------------------------------------------------------*/
-static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
- struct sccb *pCurrSCCB)
-{
-
- unsigned long timeout;
- unsigned long remain_cnt;
- u32 sg_ptr;
- struct blogic_sg_seg *segp;
-
- FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
-
- if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
-
- if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
-
- WR_HARPOON(port + hp_bm_ctrl,
- (RD_HARPOON(port + hp_bm_ctrl) |
- FLUSH_XFER_CNTR));
- timeout = LONG_WAIT;
-
- while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
- && timeout--) {
- }
-
- WR_HARPOON(port + hp_bm_ctrl,
- (RD_HARPOON(port + hp_bm_ctrl) &
- ~FLUSH_XFER_CNTR));
-
- if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
-
- if (FPT_busMstrTimeOut(port)) {
-
- if (pCurrSCCB->HostStatus == 0x00)
-
- pCurrSCCB->HostStatus =
- SCCB_BM_ERR;
-
- }
-
- if (RD_HARPOON(port + hp_int_status) &
- INT_EXT_STATUS)
-
- if (RD_HARPOON(port + hp_ext_status) &
- BAD_EXT_STATUS)
-
- if (pCurrSCCB->HostStatus ==
- 0x00)
- {
- pCurrSCCB->HostStatus =
- SCCB_BM_ERR;
- }
- }
- }
- }
-
- else if (pCurrSCCB->Sccb_XferCnt) {
-
- if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
-
- WR_HARPOON(port + hp_page_ctrl,
- (RD_HARPOON(port + hp_page_ctrl) &
- ~SCATTER_EN));
-
- WR_HARPOON(port + hp_sg_addr, 0x00);
-
- sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
-
- if (sg_ptr >
- (unsigned int)(pCurrSCCB->DataLength /
- SG_ELEMENT_SIZE)) {
-
- sg_ptr = (u32)(pCurrSCCB->DataLength /
- SG_ELEMENT_SIZE);
- }
-
- remain_cnt = pCurrSCCB->Sccb_XferCnt;
-
- while (remain_cnt < 0x01000000L) {
-
- sg_ptr--;
- segp = (struct blogic_sg_seg *)(pCurrSCCB->
- DataPointer) + (sg_ptr * 2);
- if (remain_cnt > (unsigned long)segp->segbytes)
- remain_cnt -=
- (unsigned long)segp->segbytes;
- else
- break;
- }
-
- if (remain_cnt < 0x01000000L) {
-
- pCurrSCCB->Sccb_SGoffset = remain_cnt;
-
- pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
-
- if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
- pCurrSCCB->DataLength && (remain_cnt == 0))
-
- pCurrSCCB->Sccb_XferState |=
- F_ALL_XFERRED;
- }
-
- else {
-
- if (pCurrSCCB->HostStatus == 0x00) {
-
- pCurrSCCB->HostStatus =
- SCCB_GROSS_FW_ERR;
- }
- }
- }
-
- if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
-
- if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
-
- FPT_busMstrTimeOut(port);
- }
-
- else {
-
- if (RD_HARPOON(port + hp_int_status) &
- INT_EXT_STATUS) {
-
- if (RD_HARPOON(port + hp_ext_status) &
- BAD_EXT_STATUS) {
-
- if (pCurrSCCB->HostStatus ==
- 0x00) {
-
- pCurrSCCB->HostStatus =
- SCCB_BM_ERR;
- }
- }
- }
-
- }
- }
-
- else {
-
- if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
-
- timeout = SHORT_WAIT;
-
- while ((RD_HARPOON(port + hp_ext_status) &
- BM_CMD_BUSY)
- && ((RD_HARPOON(port + hp_fifo_cnt)) >=
- BM_THRESHOLD) && timeout--) {
- }
- }
-
- if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
-
- WR_HARPOON(port + hp_bm_ctrl,
- (RD_HARPOON(port + hp_bm_ctrl) |
- FLUSH_XFER_CNTR));
-
- timeout = LONG_WAIT;
-
- while ((RD_HARPOON(port + hp_ext_status) &
- BM_CMD_BUSY) && timeout--) {
- }
-
- WR_HARPOON(port + hp_bm_ctrl,
- (RD_HARPOON(port + hp_bm_ctrl) &
- ~FLUSH_XFER_CNTR));
-
- if (RD_HARPOON(port + hp_ext_status) &
- BM_CMD_BUSY) {
-
- if (pCurrSCCB->HostStatus == 0x00) {
-
- pCurrSCCB->HostStatus =
- SCCB_BM_ERR;
- }
-
- FPT_busMstrTimeOut(port);
- }
- }
-
- if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
-
- if (RD_HARPOON(port + hp_ext_status) &
- BAD_EXT_STATUS) {
-
- if (pCurrSCCB->HostStatus == 0x00) {
-
- pCurrSCCB->HostStatus =
- SCCB_BM_ERR;
- }
- }
- }
- }
-
- }
-
- else {
-
- if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
-
- timeout = LONG_WAIT;
-
- while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
- && timeout--) {
- }
-
- if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
-
- if (pCurrSCCB->HostStatus == 0x00) {
-
- pCurrSCCB->HostStatus = SCCB_BM_ERR;
- }
-
- FPT_busMstrTimeOut(port);
- }
- }
-
- if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
-
- if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
-
- if (pCurrSCCB->HostStatus == 0x00) {
-
- pCurrSCCB->HostStatus = SCCB_BM_ERR;
- }
- }
-
- }
-
- if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
-
- WR_HARPOON(port + hp_page_ctrl,
- (RD_HARPOON(port + hp_page_ctrl) &
- ~SCATTER_EN));
-
- WR_HARPOON(port + hp_sg_addr, 0x00);
-
- pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
-
- pCurrSCCB->Sccb_SGoffset = 0x00;
-
- if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
- pCurrSCCB->DataLength) {
-
- pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
- pCurrSCCB->Sccb_sgseg =
- (unsigned short)(pCurrSCCB->DataLength /
- SG_ELEMENT_SIZE);
- }
- }
-
- else {
- if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
- pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
- }
- }
-
- WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Host Data Transfer Restart
- *
- * Description: Reset the available count due to a restore data
- * pointers message.
- *
- *---------------------------------------------------------------------*/
-static void FPT_hostDataXferRestart(struct sccb *currSCCB)
-{
- unsigned long data_count;
- unsigned int sg_index;
- struct blogic_sg_seg *segp;
-
- if (currSCCB->Sccb_XferState & F_SG_XFER) {
-
- currSCCB->Sccb_XferCnt = 0;
-
- sg_index = 0xffff; /*Index by long words into sg list. */
- data_count = 0; /*Running count of SG xfer counts. */
-
-
- while (data_count < currSCCB->Sccb_ATC) {
-
- sg_index++;
- segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
- (sg_index * 2);
- data_count += segp->segbytes;
- }
-
- if (data_count == currSCCB->Sccb_ATC) {
-
- currSCCB->Sccb_SGoffset = 0;
- sg_index++;
- }
-
- else {
- currSCCB->Sccb_SGoffset =
- data_count - currSCCB->Sccb_ATC;
- }
-
- currSCCB->Sccb_sgseg = (unsigned short)sg_index;
- }
-
- else {
- currSCCB->Sccb_XferCnt =
- currSCCB->DataLength - currSCCB->Sccb_ATC;
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scini
- *
- * Description: Setup all data structures necessary for SCAM selection.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
- unsigned char p_power_up)
-{
-
- unsigned char loser, assigned_id;
- u32 p_port;
-
- unsigned char i, k, ScamFlg;
- struct sccb_card *currCard;
- struct nvram_info *pCurrNvRam;
-
- currCard = &FPT_BL_Card[p_card];
- p_port = currCard->ioPort;
- pCurrNvRam = currCard->pNvRamInfo;
-
- if (pCurrNvRam) {
- ScamFlg = pCurrNvRam->niScamConf;
- i = pCurrNvRam->niSysConf;
- } else {
- ScamFlg =
- (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
- i = (unsigned
- char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
- }
- if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
- return;
-
- FPT_inisci(p_card, p_port, p_our_id);
-
- /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
- too slow to return to SCAM selection */
-
- /* if (p_power_up)
- FPT_Wait1Second(p_port);
- else
- FPT_Wait(p_port, TO_250ms); */
-
- FPT_Wait1Second(p_port);
-
- if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
- while (!(FPT_scarb(p_port, INIT_SELTD))) {
- }
-
- FPT_scsel(p_port);
-
- do {
- FPT_scxferc(p_port, SYNC_PTRN);
- FPT_scxferc(p_port, DOM_MSTR);
- loser =
- FPT_scsendi(p_port,
- &FPT_scamInfo[p_our_id].id_string[0]);
- } while (loser == 0xFF);
-
- FPT_scbusf(p_port);
-
- if ((p_power_up) && (!loser)) {
- FPT_sresb(p_port, p_card);
- FPT_Wait(p_port, TO_250ms);
-
- while (!(FPT_scarb(p_port, INIT_SELTD))) {
- }
-
- FPT_scsel(p_port);
-
- do {
- FPT_scxferc(p_port, SYNC_PTRN);
- FPT_scxferc(p_port, DOM_MSTR);
- loser =
- FPT_scsendi(p_port,
- &FPT_scamInfo[p_our_id].
- id_string[0]);
- } while (loser == 0xFF);
-
- FPT_scbusf(p_port);
- }
- }
-
- else {
- loser = 0;
- }
-
- if (!loser) {
-
- FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
-
- if (ScamFlg & SCAM_ENABLED) {
-
- for (i = 0; i < MAX_SCSI_TAR; i++) {
- if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
- (FPT_scamInfo[i].state == ID_UNUSED)) {
- if (FPT_scsell(p_port, i)) {
- FPT_scamInfo[i].state = LEGACY;
- if ((FPT_scamInfo[i].
- id_string[0] != 0xFF)
- || (FPT_scamInfo[i].
- id_string[1] != 0xFA)) {
-
- FPT_scamInfo[i].
- id_string[0] = 0xFF;
- FPT_scamInfo[i].
- id_string[1] = 0xFA;
- if (pCurrNvRam == NULL)
- currCard->
- globalFlags
- |=
- F_UPDATE_EEPROM;
- }
- }
- }
- }
-
- FPT_sresb(p_port, p_card);
- FPT_Wait1Second(p_port);
- while (!(FPT_scarb(p_port, INIT_SELTD))) {
- }
- FPT_scsel(p_port);
- FPT_scasid(p_card, p_port);
- }
-
- }
-
- else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
- FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
- assigned_id = 0;
- FPT_scwtsel(p_port);
-
- do {
- while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
- }
-
- i = FPT_scxferc(p_port, 0x00);
- if (i == ASSIGN_ID) {
- if (!
- (FPT_scsendi
- (p_port,
- &FPT_scamInfo[p_our_id].id_string[0]))) {
- i = FPT_scxferc(p_port, 0x00);
- if (FPT_scvalq(i)) {
- k = FPT_scxferc(p_port, 0x00);
-
- if (FPT_scvalq(k)) {
- currCard->ourId =
- ((unsigned char)(i
- <<
- 3)
- +
- (k &
- (unsigned char)7))
- & (unsigned char)
- 0x3F;
- FPT_inisci(p_card,
- p_port,
- p_our_id);
- FPT_scamInfo[currCard->
- ourId].
- state = ID_ASSIGNED;
- FPT_scamInfo[currCard->
- ourId].
- id_string[0]
- = SLV_TYPE_CODE0;
- assigned_id = 1;
- }
- }
- }
- }
-
- else if (i == SET_P_FLAG) {
- if (!(FPT_scsendi(p_port,
- &FPT_scamInfo[p_our_id].
- id_string[0])))
- FPT_scamInfo[p_our_id].id_string[0] |=
- 0x80;
- }
- } while (!assigned_id);
-
- while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
- }
- }
-
- if (ScamFlg & SCAM_ENABLED) {
- FPT_scbusf(p_port);
- if (currCard->globalFlags & F_UPDATE_EEPROM) {
- FPT_scsavdi(p_card, p_port);
- currCard->globalFlags &= ~F_UPDATE_EEPROM;
- }
- }
-
-/*
- for (i=0,k=0; i < MAX_SCSI_TAR; i++)
- {
- if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
- (FPT_scamInfo[i].state == LEGACY))
- k++;
- }
-
- if (k==2)
- currCard->globalFlags |= F_SINGLE_DEVICE;
- else
- currCard->globalFlags &= ~F_SINGLE_DEVICE;
-*/
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scarb
- *
- * Description: Gain control of the bus and wait SCAM select time (250ms)
- *
- *---------------------------------------------------------------------*/
-
-static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
-{
- if (p_sel_type == INIT_SELTD) {
-
- while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
- }
-
- if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
- return 0;
-
- if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
- return 0;
-
- WR_HARPOON(p_port + hp_scsisig,
- (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
-
- if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
-
- WR_HARPOON(p_port + hp_scsisig,
- (RD_HARPOON(p_port + hp_scsisig) &
- ~SCSI_BSY));
- return 0;
- }
-
- WR_HARPOON(p_port + hp_scsisig,
- (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
-
- if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
-
- WR_HARPOON(p_port + hp_scsisig,
- (RD_HARPOON(p_port + hp_scsisig) &
- ~(SCSI_BSY | SCSI_SEL)));
- return 0;
- }
- }
-
- WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
- & ~ACTdeassert));
- WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
- WR_HARPOON(p_port + hp_scsidata_0, 0x00);
- WR_HARPOON(p_port + hp_scsidata_1, 0x00);
- WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
-
- WR_HARPOON(p_port + hp_scsisig,
- (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
-
- WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
- & ~SCSI_BSY));
-
- FPT_Wait(p_port, TO_250ms);
-
- return 1;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scbusf
- *
- * Description: Release the SCSI bus and disable SCAM selection.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_scbusf(u32 p_port)
-{
- WR_HARPOON(p_port + hp_page_ctrl,
- (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
-
- WR_HARPOON(p_port + hp_scsidata_0, 0x00);
-
- WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
- & ~SCSI_BUS_EN));
-
- WR_HARPOON(p_port + hp_scsisig, 0x00);
-
- WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
- & ~SCAM_EN));
-
- WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
- | ACTdeassert));
-
- WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
-
- WR_HARPOON(p_port + hp_page_ctrl,
- (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scasid
- *
- * Description: Assign an ID to all the SCAM devices.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_scasid(unsigned char p_card, u32 p_port)
-{
- unsigned char temp_id_string[ID_STRING_LENGTH];
-
- unsigned char i, k, scam_id;
- unsigned char crcBytes[3];
- struct nvram_info *pCurrNvRam;
- unsigned short *pCrcBytes;
-
- pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
-
- i = 0;
-
- while (!i) {
-
- for (k = 0; k < ID_STRING_LENGTH; k++) {
- temp_id_string[k] = (unsigned char)0x00;
- }
-
- FPT_scxferc(p_port, SYNC_PTRN);
- FPT_scxferc(p_port, ASSIGN_ID);
-
- if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
- if (pCurrNvRam) {
- pCrcBytes = (unsigned short *)&crcBytes[0];
- *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
- crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
- temp_id_string[1] = crcBytes[2];
- temp_id_string[2] = crcBytes[0];
- temp_id_string[3] = crcBytes[1];
- for (k = 4; k < ID_STRING_LENGTH; k++)
- temp_id_string[k] = (unsigned char)0x00;
- }
- i = FPT_scmachid(p_card, temp_id_string);
-
- if (i == CLR_PRIORITY) {
- FPT_scxferc(p_port, MISC_CODE);
- FPT_scxferc(p_port, CLR_P_FLAG);
- i = 0; /*Not the last ID yet. */
- }
-
- else if (i != NO_ID_AVAIL) {
- if (i < 8)
- FPT_scxferc(p_port, ID_0_7);
- else
- FPT_scxferc(p_port, ID_8_F);
-
- scam_id = (i & (unsigned char)0x07);
-
- for (k = 1; k < 0x08; k <<= 1)
- if (!(k & i))
- scam_id += 0x08; /*Count number of zeros in DB0-3. */
-
- FPT_scxferc(p_port, scam_id);
-
- i = 0; /*Not the last ID yet. */
- }
- }
-
- else {
- i = 1;
- }
-
- } /*End while */
-
- FPT_scxferc(p_port, SYNC_PTRN);
- FPT_scxferc(p_port, CFG_CMPLT);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scsel
- *
- * Description: Select all the SCAM devices.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_scsel(u32 p_port)
-{
-
- WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
- FPT_scwiros(p_port, SCSI_MSG);
-
- WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
-
- WR_HARPOON(p_port + hp_scsisig,
- (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
- WR_HARPOON(p_port + hp_scsidata_0,
- (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
- (unsigned char)(BIT(7) + BIT(6))));
-
- WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
- FPT_scwiros(p_port, SCSI_SEL);
-
- WR_HARPOON(p_port + hp_scsidata_0,
- (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
- ~(unsigned char)BIT(6)));
- FPT_scwirod(p_port, BIT(6));
-
- WR_HARPOON(p_port + hp_scsisig,
- (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scxferc
- *
- * Description: Handshake the p_data (DB4-0) across the bus.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
-{
- unsigned char curr_data, ret_data;
-
- curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
-
- WR_HARPOON(p_port + hp_scsidata_0, curr_data);
-
- curr_data &= ~BIT(7);
-
- WR_HARPOON(p_port + hp_scsidata_0, curr_data);
-
- FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */
- while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
-
- ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
-
- curr_data |= BIT(6);
-
- WR_HARPOON(p_port + hp_scsidata_0, curr_data);
-
- curr_data &= ~BIT(5);
-
- WR_HARPOON(p_port + hp_scsidata_0, curr_data);
-
- FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */
-
- curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
- curr_data |= BIT(7);
-
- WR_HARPOON(p_port + hp_scsidata_0, curr_data);
-
- curr_data &= ~BIT(6);
-
- WR_HARPOON(p_port + hp_scsidata_0, curr_data);
-
- FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */
-
- return ret_data;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scsendi
- *
- * Description: Transfer our Identification string to determine if we
- * will be the dominant master.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
-{
- unsigned char ret_data, byte_cnt, bit_cnt, defer;
-
- defer = 0;
-
- for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
-
- for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
-
- if (defer)
- ret_data = FPT_scxferc(p_port, 00);
-
- else if (p_id_string[byte_cnt] & bit_cnt)
-
- ret_data = FPT_scxferc(p_port, 02);
-
- else {
-
- ret_data = FPT_scxferc(p_port, 01);
- if (ret_data & 02)
- defer = 1;
- }
-
- if ((ret_data & 0x1C) == 0x10)
- return 0x00; /*End of isolation stage, we won! */
-
- if (ret_data & 0x1C)
- return 0xFF;
-
- if ((defer) && (!(ret_data & 0x1F)))
- return 0x01; /*End of isolation stage, we lost. */
-
- } /*bit loop */
-
- } /*byte loop */
-
- if (defer)
- return 0x01; /*We lost */
- else
- return 0; /*We WON! Yeeessss! */
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_sciso
- *
- * Description: Transfer the Identification string.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
-{
- unsigned char ret_data, the_data, byte_cnt, bit_cnt;
-
- the_data = 0;
-
- for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
-
- for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
-
- ret_data = FPT_scxferc(p_port, 0);
-
- if (ret_data & 0xFC)
- return 0xFF;
-
- else {
-
- the_data <<= 1;
- if (ret_data & BIT(1)) {
- the_data |= 1;
- }
- }
-
- if ((ret_data & 0x1F) == 0) {
-/*
- if(bit_cnt != 0 || bit_cnt != 8)
- {
- byte_cnt = 0;
- bit_cnt = 0;
- FPT_scxferc(p_port, SYNC_PTRN);
- FPT_scxferc(p_port, ASSIGN_ID);
- continue;
- }
-*/
- if (byte_cnt)
- return 0x00;
- else
- return 0xFF;
- }
-
- } /*bit loop */
-
- p_id_string[byte_cnt] = the_data;
-
- } /*byte loop */
-
- return 0;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scwirod
- *
- * Description: Sample the SCSI data bus making sure the signal has been
- * deasserted for the correct number of consecutive samples.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
-{
- unsigned char i;
-
- i = 0;
- while (i < MAX_SCSI_TAR) {
-
- if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
-
- i = 0;
-
- else
-
- i++;
-
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scwiros
- *
- * Description: Sample the SCSI Signal lines making sure the signal has been
- * deasserted for the correct number of consecutive samples.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
-{
- unsigned char i;
-
- i = 0;
- while (i < MAX_SCSI_TAR) {
-
- if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
-
- i = 0;
-
- else
-
- i++;
-
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scvalq
- *
- * Description: Make sure we received a valid data byte.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_scvalq(unsigned char p_quintet)
-{
- unsigned char count;
-
- for (count = 1; count < 0x08; count <<= 1) {
- if (!(p_quintet & count))
- p_quintet -= 0x80;
- }
-
- if (p_quintet & 0x18)
- return 0;
-
- else
- return 1;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scsell
- *
- * Description: Select the specified device ID using a selection timeout
- * less than 4ms. If somebody responds then it is a legacy
- * drive and this ID must be marked as such.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
-{
- unsigned long i;
-
- WR_HARPOON(p_port + hp_page_ctrl,
- (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
-
- ARAM_ACCESS(p_port);
-
- WR_HARPOON(p_port + hp_addstat,
- (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
- WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
-
- for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
- WRW_HARPOON(i, (MPM_OP + ACOMMAND));
- }
- WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
-
- WRW_HARPOON((p_port + hp_intstat),
- (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
-
- WR_HARPOON(p_port + hp_select_id, targ_id);
-
- WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
- WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
- WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
-
- while (!(RDW_HARPOON((p_port + hp_intstat)) &
- (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
- }
-
- if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
- FPT_Wait(p_port, TO_250ms);
-
- DISABLE_AUTO(p_port);
-
- WR_HARPOON(p_port + hp_addstat,
- (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
- WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
-
- SGRAM_ACCESS(p_port);
-
- if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
-
- WRW_HARPOON((p_port + hp_intstat),
- (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
-
- WR_HARPOON(p_port + hp_page_ctrl,
- (RD_HARPOON(p_port + hp_page_ctrl) &
- ~G_INT_DISABLE));
-
- return 0; /*No legacy device */
- }
-
- else {
-
- while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
- if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
- WR_HARPOON(p_port + hp_scsisig,
- (SCSI_ACK + S_ILL_PH));
- ACCEPT_MSG(p_port);
- }
- }
-
- WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
-
- WR_HARPOON(p_port + hp_page_ctrl,
- (RD_HARPOON(p_port + hp_page_ctrl) &
- ~G_INT_DISABLE));
-
- return 1; /*Found one of them oldies! */
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scwtsel
- *
- * Description: Wait to be selected by another SCAM initiator.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_scwtsel(u32 p_port)
-{
- while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_inisci
- *
- * Description: Setup the data Structure with the info from the EEPROM.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
-{
- unsigned char i, k, max_id;
- unsigned short ee_data;
- struct nvram_info *pCurrNvRam;
-
- pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
-
- if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
- max_id = 0x08;
-
- else
- max_id = 0x10;
-
- if (pCurrNvRam) {
- for (i = 0; i < max_id; i++) {
-
- for (k = 0; k < 4; k++)
- FPT_scamInfo[i].id_string[k] =
- pCurrNvRam->niScamTbl[i][k];
- for (k = 4; k < ID_STRING_LENGTH; k++)
- FPT_scamInfo[i].id_string[k] =
- (unsigned char)0x00;
-
- if (FPT_scamInfo[i].id_string[0] == 0x00)
- FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
- else
- FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
-
- }
- } else {
- for (i = 0; i < max_id; i++) {
- for (k = 0; k < ID_STRING_LENGTH; k += 2) {
- ee_data =
- FPT_utilEERead(p_port,
- (unsigned
- short)((EE_SCAMBASE / 2) +
- (unsigned short)(i *
- ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
- FPT_scamInfo[i].id_string[k] =
- (unsigned char)ee_data;
- ee_data >>= 8;
- FPT_scamInfo[i].id_string[k + 1] =
- (unsigned char)ee_data;
- }
-
- if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
- (FPT_scamInfo[i].id_string[0] == 0xFF))
-
- FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
-
- else
- FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
-
- }
- }
- for (k = 0; k < ID_STRING_LENGTH; k++)
- FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scmachid
- *
- * Description: Match the Device ID string with our values stored in
- * the EEPROM.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_scmachid(unsigned char p_card,
- unsigned char p_id_string[])
-{
-
- unsigned char i, k, match;
-
- for (i = 0; i < MAX_SCSI_TAR; i++) {
-
- match = 1;
-
- for (k = 0; k < ID_STRING_LENGTH; k++) {
- if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
- match = 0;
- }
-
- if (match) {
- FPT_scamInfo[i].state = ID_ASSIGNED;
- return i;
- }
-
- }
-
- if (p_id_string[0] & BIT(5))
- i = 8;
- else
- i = MAX_SCSI_TAR;
-
- if (((p_id_string[0] & 0x06) == 0x02)
- || ((p_id_string[0] & 0x06) == 0x04))
- match = p_id_string[1] & (unsigned char)0x1F;
- else
- match = 7;
-
- while (i > 0) {
- i--;
-
- if (FPT_scamInfo[match].state == ID_UNUSED) {
- for (k = 0; k < ID_STRING_LENGTH; k++) {
- FPT_scamInfo[match].id_string[k] =
- p_id_string[k];
- }
-
- FPT_scamInfo[match].state = ID_ASSIGNED;
-
- if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
- FPT_BL_Card[p_card].globalFlags |=
- F_UPDATE_EEPROM;
- return match;
-
- }
-
- match--;
-
- if (match == 0xFF) {
- if (p_id_string[0] & BIT(5))
- match = 7;
- else
- match = MAX_SCSI_TAR - 1;
- }
- }
-
- if (p_id_string[0] & BIT(7)) {
- return CLR_PRIORITY;
- }
-
- if (p_id_string[0] & BIT(5))
- i = 8;
- else
- i = MAX_SCSI_TAR;
-
- if (((p_id_string[0] & 0x06) == 0x02)
- || ((p_id_string[0] & 0x06) == 0x04))
- match = p_id_string[1] & (unsigned char)0x1F;
- else
- match = 7;
-
- while (i > 0) {
-
- i--;
-
- if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
- for (k = 0; k < ID_STRING_LENGTH; k++) {
- FPT_scamInfo[match].id_string[k] =
- p_id_string[k];
- }
-
- FPT_scamInfo[match].id_string[0] |= BIT(7);
- FPT_scamInfo[match].state = ID_ASSIGNED;
- if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
- FPT_BL_Card[p_card].globalFlags |=
- F_UPDATE_EEPROM;
- return match;
-
- }
-
- match--;
-
- if (match == 0xFF) {
- if (p_id_string[0] & BIT(5))
- match = 7;
- else
- match = MAX_SCSI_TAR - 1;
- }
- }
-
- return NO_ID_AVAIL;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_scsavdi
- *
- * Description: Save off the device SCAM ID strings.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_scsavdi(unsigned char p_card, u32 p_port)
-{
- unsigned char i, k, max_id;
- unsigned short ee_data, sum_data;
-
- sum_data = 0x0000;
-
- for (i = 1; i < EE_SCAMBASE / 2; i++) {
- sum_data += FPT_utilEERead(p_port, i);
- }
-
- FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */
-
- if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
- max_id = 0x08;
-
- else
- max_id = 0x10;
-
- for (i = 0; i < max_id; i++) {
-
- for (k = 0; k < ID_STRING_LENGTH; k += 2) {
- ee_data = FPT_scamInfo[i].id_string[k + 1];
- ee_data <<= 8;
- ee_data |= FPT_scamInfo[i].id_string[k];
- sum_data += ee_data;
- FPT_utilEEWrite(p_port, ee_data,
- (unsigned short)((EE_SCAMBASE / 2) +
- (unsigned short)(i *
- ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
- }
- }
-
- FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
- FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_XbowInit
- *
- * Description: Setup the Xbow for normal operation.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
-{
- unsigned char i;
-
- i = RD_HARPOON(port + hp_page_ctrl);
- WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
-
- WR_HARPOON(port + hp_scsireset, 0x00);
- WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
-
- WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
- FIFO_CLR));
-
- WR_HARPOON(port + hp_scsireset, SCSI_INI);
-
- WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
-
- WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */
- WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
-
- WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
-
- FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
- BUS_FREE | XFER_CNT_0 | AUTO_INT;
-
- if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
- FPT_default_intena |= SCAM_SEL;
-
- WRW_HARPOON((port + hp_intena), FPT_default_intena);
-
- WR_HARPOON(port + hp_seltimeout, TO_290ms);
-
- /* Turn on SCSI_MODE8 for narrow cards to fix the
- strapping issue with the DUAL CHANNEL card */
- if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
- WR_HARPOON(port + hp_addstat, SCSI_MODE8);
-
- WR_HARPOON(port + hp_page_ctrl, i);
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_BusMasterInit
- *
- * Description: Initialize the BusMaster for normal operations.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_BusMasterInit(u32 p_port)
-{
-
- WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
- WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
-
- WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
-
- WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
-
- WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
-
- RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */
- WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
- WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
- ~SCATTER_EN));
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_DiagEEPROM
- *
- * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
- * necessary.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_DiagEEPROM(u32 p_port)
-{
- unsigned short index, temp, max_wd_cnt;
-
- if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
- max_wd_cnt = EEPROM_WD_CNT;
- else
- max_wd_cnt = EEPROM_WD_CNT * 2;
-
- temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
-
- if (temp == 0x4641) {
-
- for (index = 2; index < max_wd_cnt; index++) {
-
- temp += FPT_utilEERead(p_port, index);
-
- }
-
- if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
-
- return; /*EEPROM is Okay so return now! */
- }
- }
-
- FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
-
- for (index = 0; index < max_wd_cnt; index++) {
-
- FPT_utilEEWrite(p_port, 0x0000, index);
- }
-
- temp = 0;
-
- FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
- temp += 0x4641;
- FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
- temp += 0x3920;
- FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
- temp += 0x3033;
- FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
- temp += 0x2020;
- FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
- temp += 0x70D3;
- FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
- temp += 0x0010;
- FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
- temp += 0x0003;
- FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
- temp += 0x0007;
-
- FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
- temp += 0x0000;
- FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
- temp += 0x0000;
- FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
- temp += 0x0000;
-
- FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
- temp += 0x4242;
- FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
- temp += 0x4242;
- FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
- temp += 0x4242;
- FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
- temp += 0x4242;
- FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
- temp += 0x4242;
- FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
- temp += 0x4242;
- FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
- temp += 0x4242;
- FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
- temp += 0x4242;
-
- FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */
- temp += 0x6C46;
- FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */
- temp += 0x7361;
- FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
- temp += 0x5068;
- FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
- temp += 0x696F;
- FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
- temp += 0x746E;
- FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
- temp += 0x4C20;
- FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
- temp += 0x2054;
- FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
- temp += 0x2020;
-
- index = ((EE_SCAMBASE / 2) + (7 * 16));
- FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
- temp += (0x0700 + TYPE_CODE0);
- index++;
- FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
- temp += 0x5542; /* BUSLOGIC */
- index++;
- FPT_utilEEWrite(p_port, 0x4C53, index);
- temp += 0x4C53;
- index++;
- FPT_utilEEWrite(p_port, 0x474F, index);
- temp += 0x474F;
- index++;
- FPT_utilEEWrite(p_port, 0x4349, index);
- temp += 0x4349;
- index++;
- FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
- temp += 0x5442; /* BT- 930 */
- index++;
- FPT_utilEEWrite(p_port, 0x202D, index);
- temp += 0x202D;
- index++;
- FPT_utilEEWrite(p_port, 0x3339, index);
- temp += 0x3339;
- index++; /*Serial # */
- FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
- temp += 0x2030;
- index++;
- FPT_utilEEWrite(p_port, 0x5453, index);
- temp += 0x5453;
- index++;
- FPT_utilEEWrite(p_port, 0x5645, index);
- temp += 0x5645;
- index++;
- FPT_utilEEWrite(p_port, 0x2045, index);
- temp += 0x2045;
- index++;
- FPT_utilEEWrite(p_port, 0x202F, index);
- temp += 0x202F;
- index++;
- FPT_utilEEWrite(p_port, 0x4F4A, index);
- temp += 0x4F4A;
- index++;
- FPT_utilEEWrite(p_port, 0x204E, index);
- temp += 0x204E;
- index++;
- FPT_utilEEWrite(p_port, 0x3539, index);
- temp += 0x3539;
-
- FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
-
- FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Queue Search Select
- *
- * Description: Try to find a new command to execute.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
- unsigned char p_card)
-{
- unsigned char scan_ptr, lun;
- struct sccb_mgr_tar_info *currTar_Info;
- struct sccb *pOldSccb;
-
- scan_ptr = pCurrCard->scanIndex;
- do {
- currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
- if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
- ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
- TAG_Q_TRYING)) {
- if (currTar_Info->TarSelQ_Cnt != 0) {
-
- scan_ptr++;
- if (scan_ptr == MAX_SCSI_TAR)
- scan_ptr = 0;
-
- for (lun = 0; lun < MAX_LUN; lun++) {
- if (currTar_Info->TarLUNBusy[lun] == 0) {
-
- pCurrCard->currentSCCB =
- currTar_Info->TarSelQ_Head;
- pOldSccb = NULL;
-
- while ((pCurrCard->
- currentSCCB != NULL)
- && (lun !=
- pCurrCard->
- currentSCCB->Lun)) {
- pOldSccb =
- pCurrCard->
- currentSCCB;
- pCurrCard->currentSCCB =
- (struct sccb
- *)(pCurrCard->
- currentSCCB)->
- Sccb_forwardlink;
- }
- if (pCurrCard->currentSCCB ==
- NULL)
- continue;
- if (pOldSccb != NULL) {
- pOldSccb->
- Sccb_forwardlink =
- (struct sccb
- *)(pCurrCard->
- currentSCCB)->
- Sccb_forwardlink;
- pOldSccb->
- Sccb_backlink =
- (struct sccb
- *)(pCurrCard->
- currentSCCB)->
- Sccb_backlink;
- currTar_Info->
- TarSelQ_Cnt--;
- } else {
- currTar_Info->
- TarSelQ_Head =
- (struct sccb
- *)(pCurrCard->
- currentSCCB)->
- Sccb_forwardlink;
-
- if (currTar_Info->
- TarSelQ_Head ==
- NULL) {
- currTar_Info->
- TarSelQ_Tail
- = NULL;
- currTar_Info->
- TarSelQ_Cnt
- = 0;
- } else {
- currTar_Info->
- TarSelQ_Cnt--;
- currTar_Info->
- TarSelQ_Head->
- Sccb_backlink
- =
- (struct sccb
- *)NULL;
- }
- }
- pCurrCard->scanIndex = scan_ptr;
-
- pCurrCard->globalFlags |=
- F_NEW_SCCB_CMD;
-
- break;
- }
- }
- }
-
- else {
- scan_ptr++;
- if (scan_ptr == MAX_SCSI_TAR) {
- scan_ptr = 0;
- }
- }
-
- } else {
- if ((currTar_Info->TarSelQ_Cnt != 0) &&
- (currTar_Info->TarLUNBusy[0] == 0)) {
-
- pCurrCard->currentSCCB =
- currTar_Info->TarSelQ_Head;
-
- currTar_Info->TarSelQ_Head =
- (struct sccb *)(pCurrCard->currentSCCB)->
- Sccb_forwardlink;
-
- if (currTar_Info->TarSelQ_Head == NULL) {
- currTar_Info->TarSelQ_Tail = NULL;
- currTar_Info->TarSelQ_Cnt = 0;
- } else {
- currTar_Info->TarSelQ_Cnt--;
- currTar_Info->TarSelQ_Head->
- Sccb_backlink = (struct sccb *)NULL;
- }
-
- scan_ptr++;
- if (scan_ptr == MAX_SCSI_TAR)
- scan_ptr = 0;
-
- pCurrCard->scanIndex = scan_ptr;
-
- pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
-
- break;
- }
-
- else {
- scan_ptr++;
- if (scan_ptr == MAX_SCSI_TAR) {
- scan_ptr = 0;
- }
- }
- }
- } while (scan_ptr != pCurrCard->scanIndex);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Queue Select Fail
- *
- * Description: Add the current SCCB to the head of the Queue.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
- unsigned char p_card)
-{
- unsigned char thisTarg;
- struct sccb_mgr_tar_info *currTar_Info;
-
- if (pCurrCard->currentSCCB != NULL) {
- thisTarg =
- (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
- TargID);
- currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
-
- pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
-
- pCurrCard->currentSCCB->Sccb_forwardlink =
- currTar_Info->TarSelQ_Head;
-
- if (currTar_Info->TarSelQ_Cnt == 0) {
- currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
- }
-
- else {
- currTar_Info->TarSelQ_Head->Sccb_backlink =
- pCurrCard->currentSCCB;
- }
-
- currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
-
- pCurrCard->currentSCCB = NULL;
- currTar_Info->TarSelQ_Cnt++;
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Queue Command Complete
- *
- * Description: Call the callback function with the current SCCB.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
- struct sccb *p_sccb, unsigned char p_card)
-{
-
- unsigned char i, SCSIcmd;
- CALL_BK_FN callback;
- struct sccb_mgr_tar_info *currTar_Info;
-
- SCSIcmd = p_sccb->Cdb[0];
-
- if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
-
- if ((p_sccb->
- ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
- && (p_sccb->HostStatus == SCCB_COMPLETE)
- && (p_sccb->TargetStatus != SAM_STAT_CHECK_CONDITION))
-
- if ((SCSIcmd == READ_6) ||
- (SCSIcmd == WRITE_6) ||
- (SCSIcmd == READ_10) ||
- (SCSIcmd == WRITE_10) ||
- (SCSIcmd == WRITE_VERIFY) ||
- (SCSIcmd == START_STOP) ||
- (pCurrCard->globalFlags & F_NO_FILTER)
- )
- p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
- }
-
- if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
- if (p_sccb->HostStatus || p_sccb->TargetStatus)
- p_sccb->SccbStatus = SCCB_ERROR;
- else
- p_sccb->SccbStatus = SCCB_SUCCESS;
- }
-
- if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
-
- p_sccb->CdbLength = p_sccb->Save_CdbLen;
- for (i = 0; i < 6; i++) {
- p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
- }
- }
-
- if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
- (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
-
- FPT_utilUpdateResidual(p_sccb);
- }
-
- pCurrCard->cmdCounter--;
- if (!pCurrCard->cmdCounter) {
-
- if (pCurrCard->globalFlags & F_GREEN_PC) {
- WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
- (PWR_DWN | CLKCTRL_DEFAULT));
- WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
- }
-
- WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
- (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
- ~SCCB_MGR_ACTIVE));
-
- }
-
- if (pCurrCard->discQCount != 0) {
- currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
- if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
- ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
- TAG_Q_TRYING))) {
- pCurrCard->discQCount--;
- pCurrCard->discQ_Tbl[currTar_Info->
- LunDiscQ_Idx[p_sccb->Lun]] = NULL;
- } else {
- if (p_sccb->Sccb_tag) {
- pCurrCard->discQCount--;
- pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
- } else {
- pCurrCard->discQCount--;
- pCurrCard->discQ_Tbl[currTar_Info->
- LunDiscQ_Idx[0]] = NULL;
- }
- }
-
- }
-
- callback = (CALL_BK_FN) p_sccb->SccbCallback;
- callback(p_sccb);
- pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
- pCurrCard->currentSCCB = NULL;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Queue Disconnect
- *
- * Description: Add SCCB to our disconnect array.
- *
- *---------------------------------------------------------------------*/
-static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
-{
- struct sccb_mgr_tar_info *currTar_Info;
-
- currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
-
- if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
- ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
- FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
- LunDiscQ_Idx[p_sccb->Lun]] =
- p_sccb;
- } else {
- if (p_sccb->Sccb_tag) {
- FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
- p_sccb;
- FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
- 0;
- FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
- } else {
- FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
- LunDiscQ_Idx[0]] = p_sccb;
- }
- }
- FPT_BL_Card[p_card].currentSCCB = NULL;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Queue Flush SCCB
- *
- * Description: Flush all SCCB's back to the host driver for this target.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
-{
- unsigned char qtag, thisTarg;
- struct sccb *currSCCB;
- struct sccb_mgr_tar_info *currTar_Info;
-
- currSCCB = FPT_BL_Card[p_card].currentSCCB;
- if (currSCCB != NULL) {
- thisTarg = (unsigned char)currSCCB->TargID;
- currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
-
- for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
-
- if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
- (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
- thisTarg)) {
-
- FPT_BL_Card[p_card].discQ_Tbl[qtag]->
- HostStatus = (unsigned char)error_code;
-
- FPT_queueCmdComplete(&FPT_BL_Card[p_card],
- FPT_BL_Card[p_card].
- discQ_Tbl[qtag], p_card);
-
- FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
- currTar_Info->TarTagQ_Cnt--;
-
- }
- }
- }
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Queue Flush Target SCCB
- *
- * Description: Flush all SCCB's back to the host driver for this target.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
- unsigned char error_code)
-{
- unsigned char qtag;
- struct sccb_mgr_tar_info *currTar_Info;
-
- currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
-
- for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
-
- if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
- (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
-
- FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
- (unsigned char)error_code;
-
- FPT_queueCmdComplete(&FPT_BL_Card[p_card],
- FPT_BL_Card[p_card].
- discQ_Tbl[qtag], p_card);
-
- FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
- currTar_Info->TarTagQ_Cnt--;
-
- }
- }
-
-}
-
-static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
-{
- struct sccb_mgr_tar_info *currTar_Info;
- currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
-
- p_SCCB->Sccb_forwardlink = NULL;
-
- p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
-
- if (currTar_Info->TarSelQ_Cnt == 0) {
-
- currTar_Info->TarSelQ_Head = p_SCCB;
- }
-
- else {
-
- currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
- }
-
- currTar_Info->TarSelQ_Tail = p_SCCB;
- currTar_Info->TarSelQ_Cnt++;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Queue Find SCCB
- *
- * Description: Search the target select Queue for this SCCB, and
- * remove it if found.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
- unsigned char p_card)
-{
- struct sccb *q_ptr;
- struct sccb_mgr_tar_info *currTar_Info;
-
- currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
-
- q_ptr = currTar_Info->TarSelQ_Head;
-
- while (q_ptr != NULL) {
-
- if (q_ptr == p_SCCB) {
-
- if (currTar_Info->TarSelQ_Head == q_ptr) {
-
- currTar_Info->TarSelQ_Head =
- q_ptr->Sccb_forwardlink;
- }
-
- if (currTar_Info->TarSelQ_Tail == q_ptr) {
-
- currTar_Info->TarSelQ_Tail =
- q_ptr->Sccb_backlink;
- }
-
- if (q_ptr->Sccb_forwardlink != NULL) {
- q_ptr->Sccb_forwardlink->Sccb_backlink =
- q_ptr->Sccb_backlink;
- }
-
- if (q_ptr->Sccb_backlink != NULL) {
- q_ptr->Sccb_backlink->Sccb_forwardlink =
- q_ptr->Sccb_forwardlink;
- }
-
- currTar_Info->TarSelQ_Cnt--;
-
- return 1;
- }
-
- else {
- q_ptr = q_ptr->Sccb_forwardlink;
- }
- }
-
- return 0;
-
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Utility Update Residual Count
- *
- * Description: Update the XferCnt to the remaining byte count.
- * If we transferred all the data then just write zero.
- * If Non-SG transfer then report Total Cnt - Actual Transfer
- * Cnt. For SG transfers add the count fields of all
- * remaining SG elements, as well as any partial remaining
- * element.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
-{
- unsigned long partial_cnt;
- unsigned int sg_index;
- struct blogic_sg_seg *segp;
-
- if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
-
- p_SCCB->DataLength = 0x0000;
- }
-
- else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
-
- partial_cnt = 0x0000;
-
- sg_index = p_SCCB->Sccb_sgseg;
-
-
- if (p_SCCB->Sccb_SGoffset) {
-
- partial_cnt = p_SCCB->Sccb_SGoffset;
- sg_index++;
- }
-
- while (((unsigned long)sg_index *
- (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
- segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
- (sg_index * 2);
- partial_cnt += segp->segbytes;
- sg_index++;
- }
-
- p_SCCB->DataLength = partial_cnt;
- }
-
- else {
-
- p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Wait 1 Second
- *
- * Description: Wait for 1 second.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_Wait1Second(u32 p_port)
-{
- unsigned char i;
-
- for (i = 0; i < 4; i++) {
-
- FPT_Wait(p_port, TO_250ms);
-
- if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
- break;
-
- if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
- break;
- }
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: FPT_Wait
- *
- * Description: Wait the desired delay.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_Wait(u32 p_port, unsigned char p_delay)
-{
- unsigned char old_timer;
- unsigned char green_flag;
-
- old_timer = RD_HARPOON(p_port + hp_seltimeout);
-
- green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
- WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
-
- WR_HARPOON(p_port + hp_seltimeout, p_delay);
- WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
- WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
-
- WR_HARPOON(p_port + hp_portctrl_0,
- (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
-
- while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
-
- if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
- break;
-
- if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
- break;
- }
-
- WR_HARPOON(p_port + hp_portctrl_0,
- (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
-
- WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
- WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
-
- WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
-
- WR_HARPOON(p_port + hp_seltimeout, old_timer);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Enable/Disable Write to EEPROM
- *
- * Description: The EEPROM must first be enabled for writes
- * A total of 9 clocks are needed.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
-{
- unsigned char ee_value;
-
- ee_value =
- (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
- (EXT_ARB_ACK | SCSI_TERM_ENA_H));
-
- if (p_mode)
-
- FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
-
- else
-
- FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
-
- WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Write EEPROM
- *
- * Description: Write a word to the EEPROM at the specified
- * address.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
- unsigned short ee_addr)
-{
-
- unsigned char ee_value;
- unsigned short i;
-
- ee_value =
- (unsigned
- char)((RD_HARPOON(p_port + hp_ee_ctrl) &
- (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
-
- FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
-
- ee_value |= (SEE_MS + SEE_CS);
-
- for (i = 0x8000; i != 0; i >>= 1) {
-
- if (i & ee_data)
- ee_value |= SEE_DO;
- else
- ee_value &= ~SEE_DO;
-
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- ee_value |= SEE_CLK; /* Clock data! */
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- ee_value &= ~SEE_CLK;
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- }
- ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
- WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
-
- FPT_Wait(p_port, TO_10ms);
-
- WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
- WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Read EEPROM
- *
- * Description: Read a word from the EEPROM at the desired
- * address.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned short FPT_utilEERead(u32 p_port,
- unsigned short ee_addr)
-{
- unsigned short i, ee_data1, ee_data2;
-
- i = 0;
- ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
- do {
- ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
-
- if (ee_data1 == ee_data2)
- return ee_data1;
-
- ee_data1 = ee_data2;
- i++;
-
- } while (i < 4);
-
- return ee_data1;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Read EEPROM Original
- *
- * Description: Read a word from the EEPROM at the desired
- * address.
- *
- *---------------------------------------------------------------------*/
-
-static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
-{
-
- unsigned char ee_value;
- unsigned short i, ee_data;
-
- ee_value =
- (unsigned
- char)((RD_HARPOON(p_port + hp_ee_ctrl) &
- (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
-
- FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
-
- ee_value |= (SEE_MS + SEE_CS);
- ee_data = 0;
-
- for (i = 1; i <= 16; i++) {
-
- ee_value |= SEE_CLK; /* Clock data! */
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- ee_value &= ~SEE_CLK;
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
-
- ee_data <<= 1;
-
- if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
- ee_data |= 1;
- }
-
- ee_value &= ~(SEE_MS + SEE_CS);
- WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
-
- return ee_data;
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: Send EE command and Address to the EEPROM
- *
- * Description: Transfers the correct command and sends the address
- * to the eeprom.
- *
- *---------------------------------------------------------------------*/
-
-static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
- unsigned short ee_addr)
-{
- unsigned char ee_value;
- unsigned char narrow_flg;
-
- unsigned short i;
-
- narrow_flg =
- (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
- NARROW_SCSI_CARD);
-
- ee_value = SEE_MS;
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
-
- ee_value |= SEE_CS; /* Set CS to EEPROM */
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
-
- for (i = 0x04; i != 0; i >>= 1) {
-
- if (i & ee_cmd)
- ee_value |= SEE_DO;
- else
- ee_value &= ~SEE_DO;
-
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- ee_value |= SEE_CLK; /* Clock data! */
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- ee_value &= ~SEE_CLK;
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- }
-
- if (narrow_flg)
- i = 0x0080;
-
- else
- i = 0x0200;
-
- while (i != 0) {
-
- if (i & ee_addr)
- ee_value |= SEE_DO;
- else
- ee_value &= ~SEE_DO;
-
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- ee_value |= SEE_CLK; /* Clock data! */
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- ee_value &= ~SEE_CLK;
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
- WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
-
- i >>= 1;
- }
-}
-
-static unsigned short FPT_CalcCrc16(unsigned char buffer[])
-{
- unsigned short crc = 0;
- int i, j;
- unsigned short ch;
- for (i = 0; i < ID_STRING_LENGTH; i++) {
- ch = (unsigned short)buffer[i];
- for (j = 0; j < 8; j++) {
- if ((crc ^ ch) & 1)
- crc = (crc >> 1) ^ CRCMASK;
- else
- crc >>= 1;
- ch >>= 1;
- }
- }
- return crc;
-}
-
-static unsigned char FPT_CalcLrc(unsigned char buffer[])
-{
- int i;
- unsigned char lrc;
- lrc = 0;
- for (i = 0; i < ID_STRING_LENGTH; i++)
- lrc ^= buffer[i];
- return lrc;
-}
-
-/*
- The following inline definitions avoid type conflicts.
-*/
-
-static inline unsigned char
-FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
-{
- return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
- FlashPointInfo);
-}
-
-static inline void *
-FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
-{
- return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
- FlashPointInfo);
-}
-
-static inline void
-FlashPoint__ReleaseHostAdapter(void *CardHandle)
-{
- FlashPoint_ReleaseHostAdapter(CardHandle);
-}
-
-static inline void
-FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
-{
- FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
-}
-
-static inline void
-FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
-{
- FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
-}
-
-static inline bool
-FlashPoint__InterruptPending(void *CardHandle)
-{
- return FlashPoint_InterruptPending(CardHandle);
-}
-
-static inline int
-FlashPoint__HandleInterrupt(void *CardHandle)
-{
- return FlashPoint_HandleInterrupt(CardHandle);
-}
-
-#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
-#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
-#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
-#define FlashPoint_StartCCB FlashPoint__StartCCB
-#define FlashPoint_AbortCCB FlashPoint__AbortCCB
-#define FlashPoint_InterruptPending FlashPoint__InterruptPending
-#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
-
-#else /* !CONFIG_SCSI_FLASHPOINT */
-
-/*
- Define prototypes for the FlashPoint SCCB Manager Functions.
-*/
-
-extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
-extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
-extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
-extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
-extern bool FlashPoint_InterruptPending(void *);
-extern int FlashPoint_HandleInterrupt(void *);
-extern void FlashPoint_ReleaseHostAdapter(void *);
-
-#endif /* CONFIG_SCSI_FLASHPOINT */
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index cf75588a2587..b271967f59a6 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -511,30 +511,6 @@ config SCSI_HPTIOP
To compile this driver as a module, choose M here; the module
will be called hptiop. If unsure, say N.

-config SCSI_BUSLOGIC
- tristate "BusLogic SCSI support"
- depends on PCI && SCSI && VIRT_TO_BUS
- help
- This is support for BusLogic MultiMaster and FlashPoint SCSI Host
- Adapters. Consult the SCSI-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, and the files
- <file:Documentation/scsi/BusLogic.rst> and
- <file:Documentation/scsi/FlashPoint.rst> for more information.
- Note that support for FlashPoint is only available for 32-bit
- x86 configurations.
-
- To compile this driver as a module, choose M here: the
- module will be called BusLogic.
-
-config SCSI_FLASHPOINT
- bool "FlashPoint support"
- depends on SCSI_BUSLOGIC && PCI
- help
- This option allows you to add FlashPoint support to the
- BusLogic SCSI driver. The FlashPoint SCCB Manager code is
- substantial, so users of MultiMaster Host Adapters may not
- wish to include it.
-
config SCSI_MYRB
tristate "Mylex DAC960/DAC1100 PCI RAID Controller (Block Interface)"
depends on PCI
--
2.29.2