aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic7xxx
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/aic7xxx
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/scsi/aic7xxx')
-rw-r--r--drivers/scsi/aic7xxx/Kconfig.aic79xx97
-rw-r--r--drivers/scsi/aic7xxx/Kconfig.aic7xxx100
-rw-r--r--drivers/scsi/aic7xxx/Makefile99
-rw-r--r--drivers/scsi/aic7xxx/aic7770.c415
-rw-r--r--drivers/scsi/aic7xxx/aic7770_osm.c264
-rw-r--r--drivers/scsi/aic7xxx/aic79xx.h1537
-rw-r--r--drivers/scsi/aic7xxx/aic79xx.reg3958
-rw-r--r--drivers/scsi/aic7xxx/aic79xx.seq2058
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c9888
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_inline.h965
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c5017
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h1147
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c368
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.c987
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.h70
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_proc.c362
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_reg.h_shipped3776
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped3635
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_seq.h_shipped1139
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx.h1352
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx.reg1594
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx.seq2398
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_93cx6.c306
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_93cx6.h102
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_core.c7451
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_inline.h649
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c5043
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h1130
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm_pci.c389
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_pci.c2407
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_pci.h124
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_proc.c385
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped1787
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped1681
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped1307
-rw-r--r--drivers/scsi/aic7xxx/aicasm/Makefile78
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm.c835
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm.h95
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_gram.y1945
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h131
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y164
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l156
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_scan.l607
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c677
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h207
-rw-r--r--drivers/scsi/aic7xxx/aiclib.c1412
-rw-r--r--drivers/scsi/aic7xxx/aiclib.h1085
-rw-r--r--drivers/scsi/aic7xxx/cam.h111
-rw-r--r--drivers/scsi/aic7xxx/queue.h501
-rw-r--r--drivers/scsi/aic7xxx/scsi_iu.h39
-rw-r--r--drivers/scsi/aic7xxx/scsi_message.h70
51 files changed, 72100 insertions, 0 deletions
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic79xx b/drivers/scsi/aic7xxx/Kconfig.aic79xx
new file mode 100644
index 000000000000..c2523a30a7f5
--- /dev/null
+++ b/drivers/scsi/aic7xxx/Kconfig.aic79xx
@@ -0,0 +1,97 @@
1#
2# AIC79XX 2.5.X Kernel configuration File.
3# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic79xx#4 $
4#
5config SCSI_AIC79XX
6 tristate "Adaptec AIC79xx U320 support"
7 depends on PCI && SCSI
8 help
9 This driver supports all of Adaptec's Ultra 320 PCI-X
10 based SCSI controllers.
11
12config AIC79XX_CMDS_PER_DEVICE
13 int "Maximum number of TCQ commands per device"
14 depends on SCSI_AIC79XX
15 default "32"
16 ---help---
17 Specify the number of commands you would like to allocate per SCSI
18 device when Tagged Command Queueing (TCQ) is enabled on that device.
19
20 This is an upper bound value for the number of tagged transactions
21 to be used for any device. The aic7xxx driver will automatically
22 vary this number based on device behavior. For devices with a
23 fixed maximum, the driver will eventually lock to this maximum
24 and display a console message inidicating this value.
25
26 Due to resource allocation issues in the Linux SCSI mid-layer, using
27 a high number of commands per device may result in memory allocation
28 failures when many devices are attached to the system. For this reason,
29 the default is set to 32. Higher values may result in higer performance
30 on some devices. The upper bound is 253. 0 disables tagged queueing.
31
32 Per device tag depth can be controlled via the kernel command line
33 "tag_info" option. See drivers/scsi/aic7xxx/README.aic79xx
34 for details.
35
36config AIC79XX_RESET_DELAY_MS
37 int "Initial bus reset delay in milli-seconds"
38 depends on SCSI_AIC79XX
39 default "15000"
40 ---help---
41 The number of milliseconds to delay after an initial bus reset.
42 The bus settle delay following all error recovery actions is
43 dictated by the SCSI layer and is not affected by this value.
44
45 Default: 15000 (15 seconds)
46
47config AIC79XX_BUILD_FIRMWARE
48 bool "Build Adapter Firmware with Kernel Build"
49 depends on SCSI_AIC79XX && !PREVENT_FIRMWARE_BUILD
50 help
51 This option should only be enabled if you are modifying the firmware
52 source to the aic79xx driver and wish to have the generated firmware
53 include files updated during a normal kernel build. The assembler
54 for the firmware requires lex and yacc or their equivalents, as well
55 as the db v1 library. You may have to install additional packages
56 or modify the assembler Makefile or the files it includes if your
57 build environment is different than that of the author.
58
59config AIC79XX_ENABLE_RD_STRM
60 bool "Enable Read Streaming for All Targets"
61 depends on SCSI_AIC79XX
62 default n
63 help
64 Read Streaming is a U320 protocol option that should enhance
65 performance. Early U320 drive firmware actually performs slower
66 with read streaming enabled so it is disabled by default. Read
67 Streaming can be configured in much the same way as tagged queueing
68 using the "rd_strm" command line option. See
69 drivers/scsi/aic7xxx/README.aic79xx for details.
70
71config AIC79XX_DEBUG_ENABLE
72 bool "Compile in Debugging Code"
73 depends on SCSI_AIC79XX
74 default y
75 help
76 Compile in aic79xx debugging code that can be useful in diagnosing
77 driver errors.
78
79config AIC79XX_DEBUG_MASK
80 int "Debug code enable mask (16383 for all debugging)"
81 depends on SCSI_AIC79XX
82 default "0"
83 help
84 Bit mask of debug options that is only valid if the
85 CONFIG_AIC79XX_DEBUG_ENBLE option is enabled. The bits in this mask
86 are defined in the drivers/scsi/aic7xxx/aic79xx.h - search for the
87 variable ahd_debug in that file to find them.
88
89config AIC79XX_REG_PRETTY_PRINT
90 bool "Decode registers during diagnostics"
91 depends on SCSI_AIC79XX
92 default y
93 help
94 Compile in register value tables for the output of expanded register
95 contents in diagnostics. This make it much easier to understand debug
96 output without having to refer to a data book and/or the aic7xxx.reg
97 file.
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
new file mode 100644
index 000000000000..8398e0dd4810
--- /dev/null
+++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
@@ -0,0 +1,100 @@
1#
2# AIC7XXX and AIC79XX 2.5.X Kernel configuration File.
3# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#7 $
4#
5config SCSI_AIC7XXX
6 tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
7 depends on (PCI || EISA) && SCSI
8 ---help---
9 This driver supports all of Adaptec's Fast through Ultra 160 PCI
10 based SCSI controllers as well as the aic7770 based EISA and VLB
11 SCSI controllers (the 274x and 284x series). For AAA and ARO based
12 configurations, only SCSI functionality is provided.
13
14 To compile this driver as a module, choose M here: the
15 module will be called aic7xxx.
16
17config AIC7XXX_CMDS_PER_DEVICE
18 int "Maximum number of TCQ commands per device"
19 depends on SCSI_AIC7XXX
20 default "32"
21 ---help---
22 Specify the number of commands you would like to allocate per SCSI
23 device when Tagged Command Queueing (TCQ) is enabled on that device.
24
25 This is an upper bound value for the number of tagged transactions
26 to be used for any device. The aic7xxx driver will automatically
27 vary this number based on device behavior. For devices with a
28 fixed maximum, the driver will eventually lock to this maximum
29 and display a console message inidicating this value.
30
31 Due to resource allocation issues in the Linux SCSI mid-layer, using
32 a high number of commands per device may result in memory allocation
33 failures when many devices are attached to the system. For this reason,
34 the default is set to 32. Higher values may result in higer performance
35 on some devices. The upper bound is 253. 0 disables tagged queueing.
36
37 Per device tag depth can be controlled via the kernel command line
38 "tag_info" option. See drivers/scsi/aic7xxx/README.aic7xxx
39 for details.
40
41config AIC7XXX_RESET_DELAY_MS
42 int "Initial bus reset delay in milli-seconds"
43 depends on SCSI_AIC7XXX
44 default "15000"
45 ---help---
46 The number of milliseconds to delay after an initial bus reset.
47 The bus settle delay following all error recovery actions is
48 dictated by the SCSI layer and is not affected by this value.
49
50 Default: 15000 (15 seconds)
51
52config AIC7XXX_PROBE_EISA_VL
53 bool "Probe for EISA and VL AIC7XXX Adapters"
54 depends on SCSI_AIC7XXX && EISA
55 help
56 Probe for EISA and VLB Aic7xxx controllers. In many newer systems,
57 the invasive probes necessary to detect these controllers can cause
58 other devices to fail. For this reason, the non-PCI probe code is
59 disabled by default. The current value of this option can be "toggled"
60 via the no_probe kernel command line option.
61
62config AIC7XXX_BUILD_FIRMWARE
63 bool "Build Adapter Firmware with Kernel Build"
64 depends on SCSI_AIC7XXX && !PREVENT_FIRMWARE_BUILD
65 help
66 This option should only be enabled if you are modifying the firmware
67 source to the aic7xxx driver and wish to have the generated firmware
68 include files updated during a normal kernel build. The assembler
69 for the firmware requires lex and yacc or their equivalents, as well
70 as the db v1 library. You may have to install additional packages
71 or modify the assembler Makefile or the files it includes if your
72 build environment is different than that of the author.
73
74config AIC7XXX_DEBUG_ENABLE
75 bool "Compile in Debugging Code"
76 depends on SCSI_AIC7XXX
77 default y
78 help
79 Compile in aic7xxx debugging code that can be useful in diagnosing
80 driver errors.
81
82config AIC7XXX_DEBUG_MASK
83 int "Debug code enable mask (2047 for all debugging)"
84 depends on SCSI_AIC7XXX
85 default "0"
86 help
87 Bit mask of debug options that is only valid if the
88 CONFIG_AIC7XXX_DEBUG_ENBLE option is enabled. The bits in this mask
89 are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the
90 variable ahc_debug in that file to find them.
91
92config AIC7XXX_REG_PRETTY_PRINT
93 bool "Decode registers during diagnostics"
94 depends on SCSI_AIC7XXX
95 default y
96 help
97 Compile in register value tables for the output of expanded register
98 contents in diagnostics. This make it much easier to understand debug
99 output without having to refer to a data book and/or the aic7xxx.reg
100 file.
diff --git a/drivers/scsi/aic7xxx/Makefile b/drivers/scsi/aic7xxx/Makefile
new file mode 100644
index 000000000000..9a6ce19a4030
--- /dev/null
+++ b/drivers/scsi/aic7xxx/Makefile
@@ -0,0 +1,99 @@
1#
2# Makefile for the Linux aic7xxx SCSI driver.
3#
4# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#8 $
5#
6
7# Let kbuild descend into aicasm when cleaning
8subdir- += aicasm
9
10obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx.o
11obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o
12
13# Core Fast -> U160 files
14aic7xxx-y += aic7xxx_core.o \
15 aic7xxx_93cx6.o
16aic7xxx-$(CONFIG_EISA) += aic7770.o
17aic7xxx-$(CONFIG_PCI) += aic7xxx_pci.o
18aic7xxx-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) += aic7xxx_reg_print.o
19
20# Platform Specific Fast -> U160 Files
21aic7xxx-y += aic7xxx_osm.o \
22 aic7xxx_proc.o
23aic7xxx-$(CONFIG_EISA) += aic7770_osm.o
24aic7xxx-$(CONFIG_PCI) += aic7xxx_osm_pci.o
25
26# Core U320 files
27aic79xx-y += aic79xx_core.o \
28 aic79xx_pci.o
29aic79xx-$(CONFIG_AIC79XX_REG_PRETTY_PRINT) += aic79xx_reg_print.o
30
31# Platform Specific U320 Files
32aic79xx-y += aic79xx_osm.o \
33 aic79xx_proc.o \
34 aic79xx_osm_pci.o
35
36EXTRA_CFLAGS += -Idrivers/scsi
37ifdef WARNINGS_BECOME_ERRORS
38EXTRA_CFLAGS += -Werror
39endif
40#EXTRA_CFLAGS += -g
41
42# Files generated that shall be removed upon make clean
43clean-files := aic7xxx_seq.h aic7xxx_reg.h aic7xxx_reg_print.c
44clean-files += aic79xx_seq.h aic79xx_reg.h aic79xx_reg_print.c
45
46# Dependencies for generated files need to be listed explicitly
47
48$(obj)/aic7xxx_core.o: $(obj)/aic7xxx_seq.h
49$(obj)/aic79xx_core.o: $(obj)/aic79xx_seq.h
50$(obj)/aic79xx_reg_print.c: $(src)/aic79xx_reg_print.c_shipped
51$(obj)/aic7xxx_reg_print.c: $(src)/aic7xxx_reg_print.c_shipped
52
53$(addprefix $(obj)/,$(aic7xxx-y)): $(obj)/aic7xxx_reg.h
54$(addprefix $(obj)/,$(aic79xx-y)): $(obj)/aic79xx_reg.h
55
56aic7xxx-gen-$(CONFIG_AIC7XXX_BUILD_FIRMWARE) := $(obj)/aic7xxx_seq.h \
57 $(obj)/aic7xxx_reg.h
58aic7xxx-gen-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) += $(obj)/aic7xxx_reg_print.c
59
60aicasm-7xxx-opts-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) := \
61 -p $(obj)/aic7xxx_reg_print.c -i aic7xxx_osm.h
62
63ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)
64# Create a dependency chain in generated files
65# to avoid concurrent invocations of the single
66# rule that builds them all.
67aic7xxx_seq.h: aic7xxx_reg.h
68ifeq ($(CONFIG_AIC7XXX_REG_PRETTY_PRINT),y)
69aic7xxx_reg.h: aic7xxx_reg_print.c
70endif
71$(aic7xxx-gen-y): $(src)/aic7xxx.seq $(src)/aic7xxx.reg $(obj)/aicasm/aicasm
72 $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic7xxx_reg.h \
73 $(aicasm-7xxx-opts-y) -o $(obj)/aic7xxx_seq.h \
74 $(src)/aic7xxx.seq
75endif
76
77aic79xx-gen-$(CONFIG_AIC79XX_BUILD_FIRMWARE) := $(obj)/aic79xx_seq.h \
78 $(obj)/aic79xx_reg.h
79aic79xx-gen-$(CONFIG_AIC79XX_REG_PRETTY_PRINT) += $(obj)/aic79xx_reg_print.c
80
81aicasm-79xx-opts-$(CONFIG_AIC79XX_REG_PRETTY_PRINT) := \
82 -p $(obj)/aic79xx_reg_print.c -i aic79xx_osm.h
83
84ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y)
85# Create a dependency chain in generated files
86# to avoid concurrent invocations of the single
87# rule that builds them all.
88aic79xx_seq.h: aic79xx_reg.h
89ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y)
90aic79xx_reg.h: aic79xx_reg_print.c
91endif
92$(aic79xx-gen-y): $(src)/aic79xx.seq $(src)/aic79xx.reg $(obj)/aicasm/aicasm
93 $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic79xx_reg.h \
94 $(aicasm-79xx-opts-y) -o $(obj)/aic79xx_seq.h \
95 $(src)/aic79xx.seq
96endif
97
98$(obj)/aicasm/aicasm: $(src)/aicasm/*.[chyl]
99 $(MAKE) -C $(src)/aicasm
diff --git a/drivers/scsi/aic7xxx/aic7770.c b/drivers/scsi/aic7xxx/aic7770.c
new file mode 100644
index 000000000000..92703bb35982
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7770.c
@@ -0,0 +1,415 @@
1/*
2 * Product specific probe and attach routines for:
3 * 27/284X and aic7770 motherboard SCSI controllers
4 *
5 * Copyright (c) 1994-1998, 2000, 2001 Justin T. Gibbs.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#32 $
41 *
42 * $FreeBSD$
43 */
44
45#ifdef __linux__
46#include "aic7xxx_osm.h"
47#include "aic7xxx_inline.h"
48#include "aic7xxx_93cx6.h"
49#else
50#include <dev/aic7xxx/aic7xxx_osm.h>
51#include <dev/aic7xxx/aic7xxx_inline.h>
52#include <dev/aic7xxx/aic7xxx_93cx6.h>
53#endif
54
55#define ID_AIC7770 0x04907770
56#define ID_AHA_274x 0x04907771
57#define ID_AHA_284xB 0x04907756 /* BIOS enabled */
58#define ID_AHA_284x 0x04907757 /* BIOS disabled*/
59#define ID_OLV_274x 0x04907782 /* Olivetti OEM */
60#define ID_OLV_274xD 0x04907783 /* Olivetti OEM (Differential) */
61
62static int aic7770_chip_init(struct ahc_softc *ahc);
63static int aic7770_suspend(struct ahc_softc *ahc);
64static int aic7770_resume(struct ahc_softc *ahc);
65static int aha2840_load_seeprom(struct ahc_softc *ahc);
66static ahc_device_setup_t ahc_aic7770_VL_setup;
67static ahc_device_setup_t ahc_aic7770_EISA_setup;
68static ahc_device_setup_t ahc_aic7770_setup;
69
70struct aic7770_identity aic7770_ident_table[] =
71{
72 {
73 ID_AHA_274x,
74 0xFFFFFFFF,
75 "Adaptec 274X SCSI adapter",
76 ahc_aic7770_EISA_setup
77 },
78 {
79 ID_AHA_284xB,
80 0xFFFFFFFE,
81 "Adaptec 284X SCSI adapter",
82 ahc_aic7770_VL_setup
83 },
84 {
85 ID_AHA_284x,
86 0xFFFFFFFE,
87 "Adaptec 284X SCSI adapter (BIOS Disabled)",
88 ahc_aic7770_VL_setup
89 },
90 {
91 ID_OLV_274x,
92 0xFFFFFFFF,
93 "Adaptec (Olivetti OEM) 274X SCSI adapter",
94 ahc_aic7770_EISA_setup
95 },
96 {
97 ID_OLV_274xD,
98 0xFFFFFFFF,
99 "Adaptec (Olivetti OEM) 274X Differential SCSI adapter",
100 ahc_aic7770_EISA_setup
101 },
102 /* Generic chip probes for devices we don't know 'exactly' */
103 {
104 ID_AIC7770,
105 0xFFFFFFFF,
106 "Adaptec aic7770 SCSI adapter",
107 ahc_aic7770_EISA_setup
108 }
109};
110const int ahc_num_aic7770_devs = NUM_ELEMENTS(aic7770_ident_table);
111
112struct aic7770_identity *
113aic7770_find_device(uint32_t id)
114{
115 struct aic7770_identity *entry;
116 int i;
117
118 for (i = 0; i < ahc_num_aic7770_devs; i++) {
119 entry = &aic7770_ident_table[i];
120 if (entry->full_id == (id & entry->id_mask))
121 return (entry);
122 }
123 return (NULL);
124}
125
126int
127aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
128{
129 u_long l;
130 int error;
131 int have_seeprom;
132 u_int hostconf;
133 u_int irq;
134 u_int intdef;
135
136 error = entry->setup(ahc);
137 have_seeprom = 0;
138 if (error != 0)
139 return (error);
140
141 error = aic7770_map_registers(ahc, io);
142 if (error != 0)
143 return (error);
144
145 /*
146 * Before we continue probing the card, ensure that
147 * its interrupts are *disabled*. We don't want
148 * a misstep to hang the machine in an interrupt
149 * storm.
150 */
151 ahc_intr_enable(ahc, FALSE);
152
153 ahc->description = entry->name;
154 error = ahc_softc_init(ahc);
155 if (error != 0)
156 return (error);
157
158 ahc->bus_chip_init = aic7770_chip_init;
159 ahc->bus_suspend = aic7770_suspend;
160 ahc->bus_resume = aic7770_resume;
161
162 error = ahc_reset(ahc, /*reinit*/FALSE);
163 if (error != 0)
164 return (error);
165
166 /* Make sure we have a valid interrupt vector */
167 intdef = ahc_inb(ahc, INTDEF);
168 irq = intdef & VECTOR;
169 switch (irq) {
170 case 9:
171 case 10:
172 case 11:
173 case 12:
174 case 14:
175 case 15:
176 break;
177 default:
178 printf("aic7770_config: invalid irq setting %d\n", intdef);
179 return (ENXIO);
180 }
181
182 if ((intdef & EDGE_TRIG) != 0)
183 ahc->flags |= AHC_EDGE_INTERRUPT;
184
185 switch (ahc->chip & (AHC_EISA|AHC_VL)) {
186 case AHC_EISA:
187 {
188 u_int biosctrl;
189 u_int scsiconf;
190 u_int scsiconf1;
191
192 biosctrl = ahc_inb(ahc, HA_274_BIOSCTRL);
193 scsiconf = ahc_inb(ahc, SCSICONF);
194 scsiconf1 = ahc_inb(ahc, SCSICONF + 1);
195
196 /* Get the primary channel information */
197 if ((biosctrl & CHANNEL_B_PRIMARY) != 0)
198 ahc->flags |= 1;
199
200 if ((biosctrl & BIOSMODE) == BIOSDISABLED) {
201 ahc->flags |= AHC_USEDEFAULTS;
202 } else {
203 if ((ahc->features & AHC_WIDE) != 0) {
204 ahc->our_id = scsiconf1 & HWSCSIID;
205 if (scsiconf & TERM_ENB)
206 ahc->flags |= AHC_TERM_ENB_A;
207 } else {
208 ahc->our_id = scsiconf & HSCSIID;
209 ahc->our_id_b = scsiconf1 & HSCSIID;
210 if (scsiconf & TERM_ENB)
211 ahc->flags |= AHC_TERM_ENB_A;
212 if (scsiconf1 & TERM_ENB)
213 ahc->flags |= AHC_TERM_ENB_B;
214 }
215 }
216 if ((ahc_inb(ahc, HA_274_BIOSGLOBAL) & HA_274_EXTENDED_TRANS))
217 ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
218 break;
219 }
220 case AHC_VL:
221 {
222 have_seeprom = aha2840_load_seeprom(ahc);
223 break;
224 }
225 default:
226 break;
227 }
228 if (have_seeprom == 0) {
229 free(ahc->seep_config, M_DEVBUF);
230 ahc->seep_config = NULL;
231 }
232
233 /*
234 * Ensure autoflush is enabled
235 */
236 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS);
237
238 /* Setup the FIFO threshold and the bus off time */
239 hostconf = ahc_inb(ahc, HOSTCONF);
240 ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH);
241 ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF);
242
243 ahc->bus_softc.aic7770_softc.busspd = hostconf & DFTHRSH;
244 ahc->bus_softc.aic7770_softc.bustime = (hostconf << 2) & BOFF;
245
246 /*
247 * Generic aic7xxx initialization.
248 */
249 error = ahc_init(ahc);
250 if (error != 0)
251 return (error);
252
253 error = aic7770_map_int(ahc, irq);
254 if (error != 0)
255 return (error);
256
257 ahc_list_lock(&l);
258 /*
259 * Link this softc in with all other ahc instances.
260 */
261 ahc_softc_insert(ahc);
262
263 /*
264 * Enable the board's BUS drivers
265 */
266 ahc_outb(ahc, BCTL, ENABLE);
267
268 ahc_list_unlock(&l);
269
270 return (0);
271}
272
273static int
274aic7770_chip_init(struct ahc_softc *ahc)
275{
276 ahc_outb(ahc, BUSSPD, ahc->bus_softc.aic7770_softc.busspd);
277 ahc_outb(ahc, BUSTIME, ahc->bus_softc.aic7770_softc.bustime);
278 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~AUTOFLUSHDIS);
279 ahc_outb(ahc, BCTL, ENABLE);
280 return (ahc_chip_init(ahc));
281}
282
283static int
284aic7770_suspend(struct ahc_softc *ahc)
285{
286 return (ahc_suspend(ahc));
287}
288
289static int
290aic7770_resume(struct ahc_softc *ahc)
291{
292 return (ahc_resume(ahc));
293}
294
295/*
296 * Read the 284x SEEPROM.
297 */
298static int
299aha2840_load_seeprom(struct ahc_softc *ahc)
300{
301 struct seeprom_descriptor sd;
302 struct seeprom_config *sc;
303 int have_seeprom;
304 uint8_t scsi_conf;
305
306 sd.sd_ahc = ahc;
307 sd.sd_control_offset = SEECTL_2840;
308 sd.sd_status_offset = STATUS_2840;
309 sd.sd_dataout_offset = STATUS_2840;
310 sd.sd_chip = C46;
311 sd.sd_MS = 0;
312 sd.sd_RDY = EEPROM_TF;
313 sd.sd_CS = CS_2840;
314 sd.sd_CK = CK_2840;
315 sd.sd_DO = DO_2840;
316 sd.sd_DI = DI_2840;
317 sc = ahc->seep_config;
318
319 if (bootverbose)
320 printf("%s: Reading SEEPROM...", ahc_name(ahc));
321 have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc,
322 /*start_addr*/0, sizeof(*sc)/2);
323
324 if (have_seeprom) {
325
326 if (ahc_verify_cksum(sc) == 0) {
327 if(bootverbose)
328 printf ("checksum error\n");
329 have_seeprom = 0;
330 } else if (bootverbose) {
331 printf("done.\n");
332 }
333 }
334
335 if (!have_seeprom) {
336 if (bootverbose)
337 printf("%s: No SEEPROM available\n", ahc_name(ahc));
338 ahc->flags |= AHC_USEDEFAULTS;
339 } else {
340 /*
341 * Put the data we've collected down into SRAM
342 * where ahc_init will find it.
343 */
344 int i;
345 int max_targ;
346 uint16_t discenable;
347
348 max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
349 discenable = 0;
350 for (i = 0; i < max_targ; i++){
351 uint8_t target_settings;
352
353 target_settings = (sc->device_flags[i] & CFXFER) << 4;
354 if (sc->device_flags[i] & CFSYNCH)
355 target_settings |= SOFS;
356 if (sc->device_flags[i] & CFWIDEB)
357 target_settings |= WIDEXFER;
358 if (sc->device_flags[i] & CFDISC)
359 discenable |= (0x01 << i);
360 ahc_outb(ahc, TARG_SCSIRATE + i, target_settings);
361 }
362 ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
363 ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
364
365 ahc->our_id = sc->brtime_id & CFSCSIID;
366
367 scsi_conf = (ahc->our_id & 0x7);
368 if (sc->adapter_control & CFSPARITY)
369 scsi_conf |= ENSPCHK;
370 if (sc->adapter_control & CFRESETB)
371 scsi_conf |= RESET_SCSI;
372
373 if (sc->bios_control & CF284XEXTEND)
374 ahc->flags |= AHC_EXTENDED_TRANS_A;
375 /* Set SCSICONF info */
376 ahc_outb(ahc, SCSICONF, scsi_conf);
377
378 if (sc->adapter_control & CF284XSTERM)
379 ahc->flags |= AHC_TERM_ENB_A;
380 }
381 return (have_seeprom);
382}
383
384static int
385ahc_aic7770_VL_setup(struct ahc_softc *ahc)
386{
387 int error;
388
389 error = ahc_aic7770_setup(ahc);
390 ahc->chip |= AHC_VL;
391 return (error);
392}
393
394static int
395ahc_aic7770_EISA_setup(struct ahc_softc *ahc)
396{
397 int error;
398
399 error = ahc_aic7770_setup(ahc);
400 ahc->chip |= AHC_EISA;
401 return (error);
402}
403
404static int
405ahc_aic7770_setup(struct ahc_softc *ahc)
406{
407 ahc->channel = 'A';
408 ahc->channel_b = 'B';
409 ahc->chip = AHC_AIC7770;
410 ahc->features = AHC_AIC7770_FE;
411 ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
412 ahc->flags |= AHC_PAGESCBS;
413 ahc->instruction_ram_size = 448;
414 return (0);
415}
diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c
new file mode 100644
index 000000000000..c2b47f2bdffd
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7770_osm.c
@@ -0,0 +1,264 @@
1/*
2 * Linux driver attachment glue for aic7770 based controllers.
3 *
4 * Copyright (c) 2000-2003 Adaptec Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon
16 * including a substantially similar Disclaimer requirement for further
17 * binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * Alternatively, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2 as published by the Free
24 * Software Foundation.
25 *
26 * NO WARRANTY
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGES.
38 *
39 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#14 $
40 */
41
42#include "aic7xxx_osm.h"
43
44#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
45#include <linux/device.h>
46#include <linux/eisa.h>
47
48#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */
49#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@') /* Bits 21-25 */
50#define EISA_MFCTR_CHAR2(ID) (char)(((ID>>16) & 0x1F) | '@') /* Bits 16-20 */
51#define EISA_PRODUCT_ID(ID) (short)((ID>>4) & 0xFFF) /* Bits 4-15 */
52#define EISA_REVISION_ID(ID) (uint8_t)(ID & 0x0F) /* Bits 0-3 */
53
54static int aic7770_eisa_dev_probe(struct device *dev);
55static int aic7770_eisa_dev_remove(struct device *dev);
56static struct eisa_driver aic7770_driver = {
57 .driver = {
58 .name = "aic7xxx",
59 .probe = aic7770_eisa_dev_probe,
60 .remove = aic7770_eisa_dev_remove,
61 }
62};
63
64typedef struct device *aic7770_dev_t;
65#else
66#define MINSLOT 1
67#define NUMSLOTS 16
68#define IDOFFSET 0x80
69
70typedef void *aic7770_dev_t;
71#endif
72
73static int aic7770_linux_config(struct aic7770_identity *entry,
74 aic7770_dev_t dev, u_int eisaBase);
75
76int
77ahc_linux_eisa_init(void)
78{
79#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
80 struct eisa_device_id *eid;
81 struct aic7770_identity *id;
82 int i;
83
84 if (aic7xxx_probe_eisa_vl == 0)
85 return -ENODEV;
86
87 /*
88 * Linux requires the EISA IDs to be specified in
89 * the EISA ID string format. Perform the conversion
90 * and setup a table with a NUL terminal entry.
91 */
92 aic7770_driver.id_table = malloc(sizeof(struct eisa_device_id) *
93 (ahc_num_aic7770_devs + 1),
94 M_DEVBUF, M_NOWAIT);
95 if (aic7770_driver.id_table == NULL)
96 return -ENOMEM;
97
98 for (eid = (struct eisa_device_id *)aic7770_driver.id_table,
99 id = aic7770_ident_table, i = 0;
100 i < ahc_num_aic7770_devs; eid++, id++, i++) {
101
102 sprintf(eid->sig, "%c%c%c%03X%01X",
103 EISA_MFCTR_CHAR0(id->full_id),
104 EISA_MFCTR_CHAR1(id->full_id),
105 EISA_MFCTR_CHAR2(id->full_id),
106 EISA_PRODUCT_ID(id->full_id),
107 EISA_REVISION_ID(id->full_id));
108 eid->driver_data = i;
109 }
110 eid->sig[0] = 0;
111
112 return eisa_driver_register(&aic7770_driver);
113#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */
114 struct aic7770_identity *entry;
115 u_int slot;
116 u_int eisaBase;
117 u_int i;
118 int ret = -ENODEV;
119
120 if (aic7xxx_probe_eisa_vl == 0)
121 return ret;
122
123 eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
124 for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
125 uint32_t eisa_id;
126 size_t id_size;
127
128 if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0)
129 continue;
130
131 eisa_id = 0;
132 id_size = sizeof(eisa_id);
133 for (i = 0; i < 4; i++) {
134 /* VLcards require priming*/
135 outb(0x80 + i, eisaBase + IDOFFSET);
136 eisa_id |= inb(eisaBase + IDOFFSET + i)
137 << ((id_size-i-1) * 8);
138 }
139 release_region(eisaBase, AHC_EISA_IOSIZE);
140 if (eisa_id & 0x80000000)
141 continue; /* no EISA card in slot */
142
143 entry = aic7770_find_device(eisa_id);
144 if (entry != NULL) {
145 aic7770_linux_config(entry, NULL, eisaBase);
146 ret = 0;
147 }
148 }
149 return ret;
150#endif
151}
152
153void
154ahc_linux_eisa_exit(void)
155{
156 if(aic7xxx_probe_eisa_vl != 0 && aic7770_driver.id_table != NULL) {
157 eisa_driver_unregister(&aic7770_driver);
158 free(aic7770_driver.id_table, M_DEVBUF);
159 }
160}
161
162static int
163aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev,
164 u_int eisaBase)
165{
166 struct ahc_softc *ahc;
167 char buf[80];
168 char *name;
169 int error;
170
171 /*
172 * Allocate a softc for this card and
173 * set it up for attachment by our
174 * common detect routine.
175 */
176 sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
177 name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
178 if (name == NULL)
179 return (ENOMEM);
180 strcpy(name, buf);
181 ahc = ahc_alloc(&aic7xxx_driver_template, name);
182 if (ahc == NULL)
183 return (ENOMEM);
184 error = aic7770_config(ahc, entry, eisaBase);
185 if (error != 0) {
186 ahc->bsh.ioport = 0;
187 ahc_free(ahc);
188 return (error);
189 }
190#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
191 dev->driver_data = (void *)ahc;
192 if (aic7xxx_detect_complete)
193 error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
194#endif
195 return (error);
196}
197
198int
199aic7770_map_registers(struct ahc_softc *ahc, u_int port)
200{
201 /*
202 * Lock out other contenders for our i/o space.
203 */
204 if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
205 return (ENOMEM);
206 ahc->tag = BUS_SPACE_PIO;
207 ahc->bsh.ioport = port;
208 return (0);
209}
210
211int
212aic7770_map_int(struct ahc_softc *ahc, u_int irq)
213{
214 int error;
215 int shared;
216
217 shared = 0;
218 if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
219 shared = SA_SHIRQ;
220
221 error = request_irq(irq, ahc_linux_isr, shared, "aic7xxx", ahc);
222 if (error == 0)
223 ahc->platform_data->irq = irq;
224
225 return (-error);
226}
227
228#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
229static int
230aic7770_eisa_dev_probe(struct device *dev)
231{
232 struct eisa_device *edev;
233
234 edev = to_eisa_device(dev);
235 return (aic7770_linux_config(aic7770_ident_table + edev->id.driver_data,
236 dev, edev->base_addr+AHC_EISA_SLOT_OFFSET));
237}
238
239static int
240aic7770_eisa_dev_remove(struct device *dev)
241{
242 struct ahc_softc *ahc;
243 u_long l;
244
245 /*
246 * We should be able to just perform
247 * the free directly, but check our
248 * list for extra sanity.
249 */
250 ahc_list_lock(&l);
251 ahc = ahc_find_softc((struct ahc_softc *)dev->driver_data);
252 if (ahc != NULL) {
253 u_long s;
254
255 ahc_lock(ahc, &s);
256 ahc_intr_enable(ahc, FALSE);
257 ahc_unlock(ahc, &s);
258 ahc_free(ahc);
259 }
260 ahc_list_unlock(&l);
261
262 return (0);
263}
264#endif
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h
new file mode 100644
index 000000000000..fd4b2f3eb0c2
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx.h
@@ -0,0 +1,1537 @@
1/*
2 * Core definitions and data structures shareable across OS platforms.
3 *
4 * Copyright (c) 1994-2002 Justin T. Gibbs.
5 * Copyright (c) 2000-2002 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#95 $
41 *
42 * $FreeBSD$
43 */
44
45#ifndef _AIC79XX_H_
46#define _AIC79XX_H_
47
48/* Register Definitions */
49#include "aic79xx_reg.h"
50
51/************************* Forward Declarations *******************************/
52struct ahd_platform_data;
53struct scb_platform_data;
54
55/****************************** Useful Macros *********************************/
56#ifndef MAX
57#define MAX(a,b) (((a) > (b)) ? (a) : (b))
58#endif
59
60#ifndef MIN
61#define MIN(a,b) (((a) < (b)) ? (a) : (b))
62#endif
63
64#ifndef TRUE
65#define TRUE 1
66#endif
67#ifndef FALSE
68#define FALSE 0
69#endif
70
71#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array))
72
73#define ALL_CHANNELS '\0'
74#define ALL_TARGETS_MASK 0xFFFF
75#define INITIATOR_WILDCARD (~0)
76#define SCB_LIST_NULL 0xFF00
77#define SCB_LIST_NULL_LE (ahd_htole16(SCB_LIST_NULL))
78#define QOUTFIFO_ENTRY_VALID 0x8000
79#define QOUTFIFO_ENTRY_VALID_LE (ahd_htole16(0x8000))
80#define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL)
81
82#define SCSIID_TARGET(ahd, scsiid) \
83 (((scsiid) & TID) >> TID_SHIFT)
84#define SCSIID_OUR_ID(scsiid) \
85 ((scsiid) & OID)
86#define SCSIID_CHANNEL(ahd, scsiid) ('A')
87#define SCB_IS_SCSIBUS_B(ahd, scb) (0)
88#define SCB_GET_OUR_ID(scb) \
89 SCSIID_OUR_ID((scb)->hscb->scsiid)
90#define SCB_GET_TARGET(ahd, scb) \
91 SCSIID_TARGET((ahd), (scb)->hscb->scsiid)
92#define SCB_GET_CHANNEL(ahd, scb) \
93 SCSIID_CHANNEL(ahd, (scb)->hscb->scsiid)
94#define SCB_GET_LUN(scb) \
95 ((scb)->hscb->lun)
96#define SCB_GET_TARGET_OFFSET(ahd, scb) \
97 SCB_GET_TARGET(ahd, scb)
98#define SCB_GET_TARGET_MASK(ahd, scb) \
99 (0x01 << (SCB_GET_TARGET_OFFSET(ahd, scb)))
100#ifdef AHD_DEBUG
101#define SCB_IS_SILENT(scb) \
102 ((ahd_debug & AHD_SHOW_MASKED_ERRORS) == 0 \
103 && (((scb)->flags & SCB_SILENT) != 0))
104#else
105#define SCB_IS_SILENT(scb) \
106 (((scb)->flags & SCB_SILENT) != 0)
107#endif
108/*
109 * TCLs have the following format: TTTTLLLLLLLL
110 */
111#define TCL_TARGET_OFFSET(tcl) \
112 ((((tcl) >> 4) & TID) >> 4)
113#define TCL_LUN(tcl) \
114 (tcl & (AHD_NUM_LUNS - 1))
115#define BUILD_TCL(scsiid, lun) \
116 ((lun) | (((scsiid) & TID) << 4))
117#define BUILD_TCL_RAW(target, channel, lun) \
118 ((lun) | ((target) << 8))
119
120#define SCB_GET_TAG(scb) \
121 ahd_le16toh(scb->hscb->tag)
122
123#ifndef AHD_TARGET_MODE
124#undef AHD_TMODE_ENABLE
125#define AHD_TMODE_ENABLE 0
126#endif
127
128#define AHD_BUILD_COL_IDX(target, lun) \
129 (((lun) << 4) | target)
130
131#define AHD_GET_SCB_COL_IDX(ahd, scb) \
132 ((SCB_GET_LUN(scb) << 4) | SCB_GET_TARGET(ahd, scb))
133
134#define AHD_SET_SCB_COL_IDX(scb, col_idx) \
135do { \
136 (scb)->hscb->scsiid = ((col_idx) << TID_SHIFT) & TID; \
137 (scb)->hscb->lun = ((col_idx) >> 4) & (AHD_NUM_LUNS_NONPKT-1); \
138} while (0)
139
140#define AHD_COPY_SCB_COL_IDX(dst, src) \
141do { \
142 dst->hscb->scsiid = src->hscb->scsiid; \
143 dst->hscb->lun = src->hscb->lun; \
144} while (0)
145
146#define AHD_NEVER_COL_IDX 0xFFFF
147
148/**************************** Driver Constants ********************************/
149/*
150 * The maximum number of supported targets.
151 */
152#define AHD_NUM_TARGETS 16
153
154/*
155 * The maximum number of supported luns.
156 * The identify message only supports 64 luns in non-packetized transfers.
157 * You can have 2^64 luns when information unit transfers are enabled,
158 * but until we see a need to support that many, we support 256.
159 */
160#define AHD_NUM_LUNS_NONPKT 64
161#define AHD_NUM_LUNS 256
162
163/*
164 * The maximum transfer per S/G segment.
165 */
166#define AHD_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter */
167
168/*
169 * The maximum amount of SCB storage in hardware on a controller.
170 * This value represents an upper bound. Due to software design,
171 * we may not be able to use this number.
172 */
173#define AHD_SCB_MAX 512
174
175/*
176 * The maximum number of concurrent transactions supported per driver instance.
177 * Sequencer Control Blocks (SCBs) store per-transaction information.
178 */
179#define AHD_MAX_QUEUE AHD_SCB_MAX
180
181/*
182 * Define the size of our QIN and QOUT FIFOs. They must be a power of 2
183 * in size and accommodate as many transactions as can be queued concurrently.
184 */
185#define AHD_QIN_SIZE AHD_MAX_QUEUE
186#define AHD_QOUT_SIZE AHD_MAX_QUEUE
187
188#define AHD_QIN_WRAP(x) ((x) & (AHD_QIN_SIZE-1))
189/*
190 * The maximum amount of SCB storage we allocate in host memory.
191 */
192#define AHD_SCB_MAX_ALLOC AHD_MAX_QUEUE
193
194/*
195 * Ring Buffer of incoming target commands.
196 * We allocate 256 to simplify the logic in the sequencer
197 * by using the natural wrap point of an 8bit counter.
198 */
199#define AHD_TMODE_CMDS 256
200
201/* Reset line assertion time in us */
202#define AHD_BUSRESET_DELAY 25
203
204/******************* Chip Characteristics/Operating Settings *****************/
205/*
206 * Chip Type
207 * The chip order is from least sophisticated to most sophisticated.
208 */
209typedef enum {
210 AHD_NONE = 0x0000,
211 AHD_CHIPID_MASK = 0x00FF,
212 AHD_AIC7901 = 0x0001,
213 AHD_AIC7902 = 0x0002,
214 AHD_AIC7901A = 0x0003,
215 AHD_PCI = 0x0100, /* Bus type PCI */
216 AHD_PCIX = 0x0200, /* Bus type PCIX */
217 AHD_BUS_MASK = 0x0F00
218} ahd_chip;
219
220/*
221 * Features available in each chip type.
222 */
223typedef enum {
224 AHD_FENONE = 0x00000,
225 AHD_WIDE = 0x00001,/* Wide Channel */
226 AHD_MULTI_FUNC = 0x00100,/* Multi-Function/Channel Device */
227 AHD_TARGETMODE = 0x01000,/* Has tested target mode support */
228 AHD_MULTIROLE = 0x02000,/* Space for two roles at a time */
229 AHD_RTI = 0x04000,/* Retained Training Support */
230 AHD_NEW_IOCELL_OPTS = 0x08000,/* More Signal knobs in the IOCELL */
231 AHD_NEW_DFCNTRL_OPTS = 0x10000,/* SCSIENWRDIS bit */
232 AHD_FAST_CDB_DELIVERY = 0x20000,/* CDB acks released to Output Sync */
233 AHD_REMOVABLE = 0x00000,/* Hot-Swap supported - None so far*/
234 AHD_AIC7901_FE = AHD_FENONE,
235 AHD_AIC7901A_FE = AHD_FENONE,
236 AHD_AIC7902_FE = AHD_MULTI_FUNC
237} ahd_feature;
238
239/*
240 * Bugs in the silicon that we work around in software.
241 */
242typedef enum {
243 AHD_BUGNONE = 0x0000,
244 /*
245 * Rev A hardware fails to update LAST/CURR/NEXTSCB
246 * correctly in certain packetized selection cases.
247 */
248 AHD_SENT_SCB_UPDATE_BUG = 0x0001,
249 /* The wrong SCB is accessed to check the abort pending bit. */
250 AHD_ABORT_LQI_BUG = 0x0002,
251 /* Packetized bitbucket crosses packet boundaries. */
252 AHD_PKT_BITBUCKET_BUG = 0x0004,
253 /* The selection timer runs twice as long as its setting. */
254 AHD_LONG_SETIMO_BUG = 0x0008,
255 /* The Non-LQ CRC error status is delayed until phase change. */
256 AHD_NLQICRC_DELAYED_BUG = 0x0010,
257 /* The chip must be reset for all outgoing bus resets. */
258 AHD_SCSIRST_BUG = 0x0020,
259 /* Some PCIX fields must be saved and restored across chip reset. */
260 AHD_PCIX_CHIPRST_BUG = 0x0040,
261 /* MMAPIO is not functional in PCI-X mode. */
262 AHD_PCIX_MMAPIO_BUG = 0x0080,
263 /* Reads to SCBRAM fail to reset the discard timer. */
264 AHD_PCIX_SCBRAM_RD_BUG = 0x0100,
265 /* Bug workarounds that can be disabled on non-PCIX busses. */
266 AHD_PCIX_BUG_MASK = AHD_PCIX_CHIPRST_BUG
267 | AHD_PCIX_MMAPIO_BUG
268 | AHD_PCIX_SCBRAM_RD_BUG,
269 /*
270 * LQOSTOP0 status set even for forced selections with ATN
271 * to perform non-packetized message delivery.
272 */
273 AHD_LQO_ATNO_BUG = 0x0200,
274 /* FIFO auto-flush does not always trigger. */
275 AHD_AUTOFLUSH_BUG = 0x0400,
276 /* The CLRLQO registers are not self-clearing. */
277 AHD_CLRLQO_AUTOCLR_BUG = 0x0800,
278 /* The PACKETIZED status bit refers to the previous connection. */
279 AHD_PKTIZED_STATUS_BUG = 0x1000,
280 /* "Short Luns" are not placed into outgoing LQ packets correctly. */
281 AHD_PKT_LUN_BUG = 0x2000,
282 /*
283 * Only the FIFO allocated to the non-packetized connection may
284 * be in use during a non-packetzied connection.
285 */
286 AHD_NONPACKFIFO_BUG = 0x4000,
287 /*
288 * Writing to a DFF SCBPTR register may fail if concurent with
289 * a hardware write to the other DFF SCBPTR register. This is
290 * not currently a concern in our sequencer since all chips with
291 * this bug have the AHD_NONPACKFIFO_BUG and all writes of concern
292 * occur in non-packetized connections.
293 */
294 AHD_MDFF_WSCBPTR_BUG = 0x8000,
295 /* SGHADDR updates are slow. */
296 AHD_REG_SLOW_SETTLE_BUG = 0x10000,
297 /*
298 * Changing the MODE_PTR coincident with an interrupt that
299 * switches to a different mode will cause the interrupt to
300 * be in the mode written outside of interrupt context.
301 */
302 AHD_SET_MODE_BUG = 0x20000,
303 /* Non-packetized busfree revision does not work. */
304 AHD_BUSFREEREV_BUG = 0x40000,
305 /*
306 * Paced transfers are indicated with a non-standard PPR
307 * option bit in the neg table, 160MHz is indicated by
308 * sync factor 0x7, and the offset if off by a factor of 2.
309 */
310 AHD_PACED_NEGTABLE_BUG = 0x80000,
311 /* LQOOVERRUN false positives. */
312 AHD_LQOOVERRUN_BUG = 0x100000,
313 /*
314 * Controller write to INTSTAT will lose to a host
315 * write to CLRINT.
316 */
317 AHD_INTCOLLISION_BUG = 0x200000,
318 /*
319 * The GEM318 violates the SCSI spec by not waiting
320 * the mandated bus settle delay between phase changes
321 * in some situations. Some aic79xx chip revs. are more
322 * strict in this regard and will treat REQ assertions
323 * that fall within the bus settle delay window as
324 * glitches. This flag tells the firmware to tolerate
325 * early REQ assertions.
326 */
327 AHD_EARLY_REQ_BUG = 0x400000,
328 /*
329 * The LED does not stay on long enough in packetized modes.
330 */
331 AHD_FAINT_LED_BUG = 0x800000
332} ahd_bug;
333
334/*
335 * Configuration specific settings.
336 * The driver determines these settings by probing the
337 * chip/controller's configuration.
338 */
339typedef enum {
340 AHD_FNONE = 0x00000,
341 AHD_BOOT_CHANNEL = 0x00001,/* We were set as the boot channel. */
342 AHD_USEDEFAULTS = 0x00004,/*
343 * For cards without an seeprom
344 * or a BIOS to initialize the chip's
345 * SRAM, we use the default target
346 * settings.
347 */
348 AHD_SEQUENCER_DEBUG = 0x00008,
349 AHD_RESET_BUS_A = 0x00010,
350 AHD_EXTENDED_TRANS_A = 0x00020,
351 AHD_TERM_ENB_A = 0x00040,
352 AHD_SPCHK_ENB_A = 0x00080,
353 AHD_STPWLEVEL_A = 0x00100,
354 AHD_INITIATORROLE = 0x00200,/*
355 * Allow initiator operations on
356 * this controller.
357 */
358 AHD_TARGETROLE = 0x00400,/*
359 * Allow target operations on this
360 * controller.
361 */
362 AHD_RESOURCE_SHORTAGE = 0x00800,
363 AHD_TQINFIFO_BLOCKED = 0x01000,/* Blocked waiting for ATIOs */
364 AHD_INT50_SPEEDFLEX = 0x02000,/*
365 * Internal 50pin connector
366 * sits behind an aic3860
367 */
368 AHD_BIOS_ENABLED = 0x04000,
369 AHD_ALL_INTERRUPTS = 0x08000,
370 AHD_39BIT_ADDRESSING = 0x10000,/* Use 39 bit addressing scheme. */
371 AHD_64BIT_ADDRESSING = 0x20000,/* Use 64 bit addressing scheme. */
372 AHD_CURRENT_SENSING = 0x40000,
373 AHD_SCB_CONFIG_USED = 0x80000,/* No SEEPROM but SCB had info. */
374 AHD_HP_BOARD = 0x100000,
375 AHD_RESET_POLL_ACTIVE = 0x200000,
376 AHD_UPDATE_PEND_CMDS = 0x400000,
377 AHD_RUNNING_QOUTFIFO = 0x800000,
378 AHD_HAD_FIRST_SEL = 0x1000000
379} ahd_flag;
380
381/************************* Hardware SCB Definition ***************************/
382
383/*
384 * The driver keeps up to MAX_SCB scb structures per card in memory. The SCB
385 * consists of a "hardware SCB" mirroring the fields available on the card
386 * and additional information the kernel stores for each transaction.
387 *
388 * To minimize space utilization, a portion of the hardware scb stores
389 * different data during different portions of a SCSI transaction.
390 * As initialized by the host driver for the initiator role, this area
391 * contains the SCSI cdb (or a pointer to the cdb) to be executed. After
392 * the cdb has been presented to the target, this area serves to store
393 * residual transfer information and the SCSI status byte.
394 * For the target role, the contents of this area do not change, but
395 * still serve a different purpose than for the initiator role. See
396 * struct target_data for details.
397 */
398
399/*
400 * Status information embedded in the shared poriton of
401 * an SCB after passing the cdb to the target. The kernel
402 * driver will only read this data for transactions that
403 * complete abnormally.
404 */
405struct initiator_status {
406 uint32_t residual_datacnt; /* Residual in the current S/G seg */
407 uint32_t residual_sgptr; /* The next S/G for this transfer */
408 uint8_t scsi_status; /* Standard SCSI status byte */
409};
410
411struct target_status {
412 uint32_t residual_datacnt; /* Residual in the current S/G seg */
413 uint32_t residual_sgptr; /* The next S/G for this transfer */
414 uint8_t scsi_status; /* SCSI status to give to initiator */
415 uint8_t target_phases; /* Bitmap of phases to execute */
416 uint8_t data_phase; /* Data-In or Data-Out */
417 uint8_t initiator_tag; /* Initiator's transaction tag */
418};
419
420/*
421 * Initiator mode SCB shared data area.
422 * If the embedded CDB is 12 bytes or less, we embed
423 * the sense buffer address in the SCB. This allows
424 * us to retrieve sense information without interrupting
425 * the host in packetized mode.
426 */
427typedef uint32_t sense_addr_t;
428#define MAX_CDB_LEN 16
429#define MAX_CDB_LEN_WITH_SENSE_ADDR (MAX_CDB_LEN - sizeof(sense_addr_t))
430union initiator_data {
431 struct {
432 uint64_t cdbptr;
433 uint8_t cdblen;
434 } cdb_from_host;
435 uint8_t cdb[MAX_CDB_LEN];
436 struct {
437 uint8_t cdb[MAX_CDB_LEN_WITH_SENSE_ADDR];
438 sense_addr_t sense_addr;
439 } cdb_plus_saddr;
440};
441
442/*
443 * Target mode version of the shared data SCB segment.
444 */
445struct target_data {
446 uint32_t spare[2];
447 uint8_t scsi_status; /* SCSI status to give to initiator */
448 uint8_t target_phases; /* Bitmap of phases to execute */
449 uint8_t data_phase; /* Data-In or Data-Out */
450 uint8_t initiator_tag; /* Initiator's transaction tag */
451};
452
453struct hardware_scb {
454/*0*/ union {
455 union initiator_data idata;
456 struct target_data tdata;
457 struct initiator_status istatus;
458 struct target_status tstatus;
459 } shared_data;
460/*
461 * A word about residuals.
462 * The scb is presented to the sequencer with the dataptr and datacnt
463 * fields initialized to the contents of the first S/G element to
464 * transfer. The sgptr field is initialized to the bus address for
465 * the S/G element that follows the first in the in core S/G array
466 * or'ed with the SG_FULL_RESID flag. Sgptr may point to an invalid
467 * S/G entry for this transfer (single S/G element transfer with the
468 * first elements address and length preloaded in the dataptr/datacnt
469 * fields). If no transfer is to occur, sgptr is set to SG_LIST_NULL.
470 * The SG_FULL_RESID flag ensures that the residual will be correctly
471 * noted even if no data transfers occur. Once the data phase is entered,
472 * the residual sgptr and datacnt are loaded from the sgptr and the
473 * datacnt fields. After each S/G element's dataptr and length are
474 * loaded into the hardware, the residual sgptr is advanced. After
475 * each S/G element is expired, its datacnt field is checked to see
476 * if the LAST_SEG flag is set. If so, SG_LIST_NULL is set in the
477 * residual sg ptr and the transfer is considered complete. If the
478 * sequencer determines that there is a residual in the tranfer, or
479 * there is non-zero status, it will set the SG_STATUS_VALID flag in
480 * sgptr and dma the scb back into host memory. To sumarize:
481 *
482 * Sequencer:
483 * o A residual has occurred if SG_FULL_RESID is set in sgptr,
484 * or residual_sgptr does not have SG_LIST_NULL set.
485 *
486 * o We are transfering the last segment if residual_datacnt has
487 * the SG_LAST_SEG flag set.
488 *
489 * Host:
490 * o A residual can only have occurred if a completed scb has the
491 * SG_STATUS_VALID flag set. Inspection of the SCSI status field,
492 * the residual_datacnt, and the residual_sgptr field will tell
493 * for sure.
494 *
495 * o residual_sgptr and sgptr refer to the "next" sg entry
496 * and so may point beyond the last valid sg entry for the
497 * transfer.
498 */
499#define SG_PTR_MASK 0xFFFFFFF8
500/*16*/ uint16_t tag; /* Reused by Sequencer. */
501/*18*/ uint8_t control; /* See SCB_CONTROL in aic79xx.reg for details */
502/*19*/ uint8_t scsiid; /*
503 * Selection out Id
504 * Our Id (bits 0-3) Their ID (bits 4-7)
505 */
506/*20*/ uint8_t lun;
507/*21*/ uint8_t task_attribute;
508/*22*/ uint8_t cdb_len;
509/*23*/ uint8_t task_management;
510/*24*/ uint64_t dataptr;
511/*32*/ uint32_t datacnt; /* Byte 3 is spare. */
512/*36*/ uint32_t sgptr;
513/*40*/ uint32_t hscb_busaddr;
514/*44*/ uint32_t next_hscb_busaddr;
515/********** Long lun field only downloaded for full 8 byte lun support ********/
516/*48*/ uint8_t pkt_long_lun[8];
517/******* Fields below are not Downloaded (Sequencer may use for scratch) ******/
518/*56*/ uint8_t spare[8];
519};
520
521/************************ Kernel SCB Definitions ******************************/
522/*
523 * Some fields of the SCB are OS dependent. Here we collect the
524 * definitions for elements that all OS platforms need to include
525 * in there SCB definition.
526 */
527
528/*
529 * Definition of a scatter/gather element as transfered to the controller.
530 * The aic7xxx chips only support a 24bit length. We use the top byte of
531 * the length to store additional address bits and a flag to indicate
532 * that a given segment terminates the transfer. This gives us an
533 * addressable range of 512GB on machines with 64bit PCI or with chips
534 * that can support dual address cycles on 32bit PCI busses.
535 */
536struct ahd_dma_seg {
537 uint32_t addr;
538 uint32_t len;
539#define AHD_DMA_LAST_SEG 0x80000000
540#define AHD_SG_HIGH_ADDR_MASK 0x7F000000
541#define AHD_SG_LEN_MASK 0x00FFFFFF
542};
543
544struct ahd_dma64_seg {
545 uint64_t addr;
546 uint32_t len;
547 uint32_t pad;
548};
549
550struct map_node {
551 bus_dmamap_t dmamap;
552 dma_addr_t physaddr;
553 uint8_t *vaddr;
554 SLIST_ENTRY(map_node) links;
555};
556
557/*
558 * The current state of this SCB.
559 */
560typedef enum {
561 SCB_FLAG_NONE = 0x00000,
562 SCB_TRANSMISSION_ERROR = 0x00001,/*
563 * We detected a parity or CRC
564 * error that has effected the
565 * payload of the command. This
566 * flag is checked when normal
567 * status is returned to catch
568 * the case of a target not
569 * responding to our attempt
570 * to report the error.
571 */
572 SCB_OTHERTCL_TIMEOUT = 0x00002,/*
573 * Another device was active
574 * during the first timeout for
575 * this SCB so we gave ourselves
576 * an additional timeout period
577 * in case it was hogging the
578 * bus.
579 */
580 SCB_DEVICE_RESET = 0x00004,
581 SCB_SENSE = 0x00008,
582 SCB_CDB32_PTR = 0x00010,
583 SCB_RECOVERY_SCB = 0x00020,
584 SCB_AUTO_NEGOTIATE = 0x00040,/* Negotiate to achieve goal. */
585 SCB_NEGOTIATE = 0x00080,/* Negotiation forced for command. */
586 SCB_ABORT = 0x00100,
587 SCB_ACTIVE = 0x00200,
588 SCB_TARGET_IMMEDIATE = 0x00400,
589 SCB_PACKETIZED = 0x00800,
590 SCB_EXPECT_PPR_BUSFREE = 0x01000,
591 SCB_PKT_SENSE = 0x02000,
592 SCB_CMDPHASE_ABORT = 0x04000,
593 SCB_ON_COL_LIST = 0x08000,
594 SCB_SILENT = 0x10000 /*
595 * Be quiet about transmission type
596 * errors. They are expected and we
597 * don't want to upset the user. This
598 * flag is typically used during DV.
599 */
600} scb_flag;
601
602struct scb {
603 struct hardware_scb *hscb;
604 union {
605 SLIST_ENTRY(scb) sle;
606 LIST_ENTRY(scb) le;
607 TAILQ_ENTRY(scb) tqe;
608 } links;
609 union {
610 SLIST_ENTRY(scb) sle;
611 LIST_ENTRY(scb) le;
612 TAILQ_ENTRY(scb) tqe;
613 } links2;
614#define pending_links links2.le
615#define collision_links links2.le
616 struct scb *col_scb;
617 ahd_io_ctx_t io_ctx;
618 struct ahd_softc *ahd_softc;
619 scb_flag flags;
620#ifndef __linux__
621 bus_dmamap_t dmamap;
622#endif
623 struct scb_platform_data *platform_data;
624 struct map_node *hscb_map;
625 struct map_node *sg_map;
626 struct map_node *sense_map;
627 void *sg_list;
628 uint8_t *sense_data;
629 dma_addr_t sg_list_busaddr;
630 dma_addr_t sense_busaddr;
631 u_int sg_count;/* How full ahd_dma_seg is */
632#define AHD_MAX_LQ_CRC_ERRORS 5
633 u_int crc_retry_count;
634};
635
636TAILQ_HEAD(scb_tailq, scb);
637LIST_HEAD(scb_list, scb);
638
639struct scb_data {
640 /*
641 * TAILQ of lists of free SCBs grouped by device
642 * collision domains.
643 */
644 struct scb_tailq free_scbs;
645
646 /*
647 * Per-device lists of SCBs whose tag ID would collide
648 * with an already active tag on the device.
649 */
650 struct scb_list free_scb_lists[AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT];
651
652 /*
653 * SCBs that will not collide with any active device.
654 */
655 struct scb_list any_dev_free_scb_list;
656
657 /*
658 * Mapping from tag to SCB.
659 */
660 struct scb *scbindex[AHD_SCB_MAX];
661
662 /*
663 * "Bus" addresses of our data structures.
664 */
665 bus_dma_tag_t hscb_dmat; /* dmat for our hardware SCB array */
666 bus_dma_tag_t sg_dmat; /* dmat for our sg segments */
667 bus_dma_tag_t sense_dmat; /* dmat for our sense buffers */
668 SLIST_HEAD(, map_node) hscb_maps;
669 SLIST_HEAD(, map_node) sg_maps;
670 SLIST_HEAD(, map_node) sense_maps;
671 int scbs_left; /* unallocated scbs in head map_node */
672 int sgs_left; /* unallocated sgs in head map_node */
673 int sense_left; /* unallocated sense in head map_node */
674 uint16_t numscbs;
675 uint16_t maxhscbs; /* Number of SCBs on the card */
676 uint8_t init_level; /*
677 * How far we've initialized
678 * this structure.
679 */
680};
681
682/************************ Target Mode Definitions *****************************/
683
684/*
685 * Connection desciptor for select-in requests in target mode.
686 */
687struct target_cmd {
688 uint8_t scsiid; /* Our ID and the initiator's ID */
689 uint8_t identify; /* Identify message */
690 uint8_t bytes[22]; /*
691 * Bytes contains any additional message
692 * bytes terminated by 0xFF. The remainder
693 * is the cdb to execute.
694 */
695 uint8_t cmd_valid; /*
696 * When a command is complete, the firmware
697 * will set cmd_valid to all bits set.
698 * After the host has seen the command,
699 * the bits are cleared. This allows us
700 * to just peek at host memory to determine
701 * if more work is complete. cmd_valid is on
702 * an 8 byte boundary to simplify setting
703 * it on aic7880 hardware which only has
704 * limited direct access to the DMA FIFO.
705 */
706 uint8_t pad[7];
707};
708
709/*
710 * Number of events we can buffer up if we run out
711 * of immediate notify ccbs.
712 */
713#define AHD_TMODE_EVENT_BUFFER_SIZE 8
714struct ahd_tmode_event {
715 uint8_t initiator_id;
716 uint8_t event_type; /* MSG type or EVENT_TYPE_BUS_RESET */
717#define EVENT_TYPE_BUS_RESET 0xFF
718 uint8_t event_arg;
719};
720
721/*
722 * Per enabled lun target mode state.
723 * As this state is directly influenced by the host OS'es target mode
724 * environment, we let the OS module define it. Forward declare the
725 * structure here so we can store arrays of them, etc. in OS neutral
726 * data structures.
727 */
728#ifdef AHD_TARGET_MODE
729struct ahd_tmode_lstate {
730 struct cam_path *path;
731 struct ccb_hdr_slist accept_tios;
732 struct ccb_hdr_slist immed_notifies;
733 struct ahd_tmode_event event_buffer[AHD_TMODE_EVENT_BUFFER_SIZE];
734 uint8_t event_r_idx;
735 uint8_t event_w_idx;
736};
737#else
738struct ahd_tmode_lstate;
739#endif
740
741/******************** Transfer Negotiation Datastructures *********************/
742#define AHD_TRANS_CUR 0x01 /* Modify current neogtiation status */
743#define AHD_TRANS_ACTIVE 0x03 /* Assume this target is on the bus */
744#define AHD_TRANS_GOAL 0x04 /* Modify negotiation goal */
745#define AHD_TRANS_USER 0x08 /* Modify user negotiation settings */
746#define AHD_PERIOD_10MHz 0x19
747
748#define AHD_WIDTH_UNKNOWN 0xFF
749#define AHD_PERIOD_UNKNOWN 0xFF
750#define AHD_OFFSET_UNKNOWN 0xFF
751#define AHD_PPR_OPTS_UNKNOWN 0xFF
752
753/*
754 * Transfer Negotiation Information.
755 */
756struct ahd_transinfo {
757 uint8_t protocol_version; /* SCSI Revision level */
758 uint8_t transport_version; /* SPI Revision level */
759 uint8_t width; /* Bus width */
760 uint8_t period; /* Sync rate factor */
761 uint8_t offset; /* Sync offset */
762 uint8_t ppr_options; /* Parallel Protocol Request options */
763};
764
765/*
766 * Per-initiator current, goal and user transfer negotiation information. */
767struct ahd_initiator_tinfo {
768 struct ahd_transinfo curr;
769 struct ahd_transinfo goal;
770 struct ahd_transinfo user;
771};
772
773/*
774 * Per enabled target ID state.
775 * Pointers to lun target state as well as sync/wide negotiation information
776 * for each initiator<->target mapping. For the initiator role we pretend
777 * that we are the target and the targets are the initiators since the
778 * negotiation is the same regardless of role.
779 */
780struct ahd_tmode_tstate {
781 struct ahd_tmode_lstate* enabled_luns[AHD_NUM_LUNS];
782 struct ahd_initiator_tinfo transinfo[AHD_NUM_TARGETS];
783
784 /*
785 * Per initiator state bitmasks.
786 */
787 uint16_t auto_negotiate;/* Auto Negotiation Required */
788 uint16_t discenable; /* Disconnection allowed */
789 uint16_t tagenable; /* Tagged Queuing allowed */
790};
791
792/*
793 * Points of interest along the negotiated transfer scale.
794 */
795#define AHD_SYNCRATE_160 0x8
796#define AHD_SYNCRATE_PACED 0x8
797#define AHD_SYNCRATE_DT 0x9
798#define AHD_SYNCRATE_ULTRA2 0xa
799#define AHD_SYNCRATE_ULTRA 0xc
800#define AHD_SYNCRATE_FAST 0x19
801#define AHD_SYNCRATE_MIN_DT AHD_SYNCRATE_FAST
802#define AHD_SYNCRATE_SYNC 0x32
803#define AHD_SYNCRATE_MIN 0x60
804#define AHD_SYNCRATE_ASYNC 0xFF
805#define AHD_SYNCRATE_MAX AHD_SYNCRATE_160
806
807/* Safe and valid period for async negotiations. */
808#define AHD_ASYNC_XFER_PERIOD 0x44
809
810/*
811 * In RevA, the synctable uses a 120MHz rate for the period
812 * factor 8 and 160MHz for the period factor 7. The 120MHz
813 * rate never made it into the official SCSI spec, so we must
814 * compensate when setting the negotiation table for Rev A
815 * parts.
816 */
817#define AHD_SYNCRATE_REVA_120 0x8
818#define AHD_SYNCRATE_REVA_160 0x7
819
820/***************************** Lookup Tables **********************************/
821/*
822 * Phase -> name and message out response
823 * to parity errors in each phase table.
824 */
825struct ahd_phase_table_entry {
826 uint8_t phase;
827 uint8_t mesg_out; /* Message response to parity errors */
828 char *phasemsg;
829};
830
831/************************** Serial EEPROM Format ******************************/
832
833struct seeprom_config {
834/*
835 * Per SCSI ID Configuration Flags
836 */
837 uint16_t device_flags[16]; /* words 0-15 */
838#define CFXFER 0x003F /* synchronous transfer rate */
839#define CFXFER_ASYNC 0x3F
840#define CFQAS 0x0040 /* Negotiate QAS */
841#define CFPACKETIZED 0x0080 /* Negotiate Packetized Transfers */
842#define CFSTART 0x0100 /* send start unit SCSI command */
843#define CFINCBIOS 0x0200 /* include in BIOS scan */
844#define CFDISC 0x0400 /* enable disconnection */
845#define CFMULTILUNDEV 0x0800 /* Probe multiple luns in BIOS scan */
846#define CFWIDEB 0x1000 /* wide bus device */
847#define CFHOSTMANAGED 0x8000 /* Managed by a RAID controller */
848
849/*
850 * BIOS Control Bits
851 */
852 uint16_t bios_control; /* word 16 */
853#define CFSUPREM 0x0001 /* support all removeable drives */
854#define CFSUPREMB 0x0002 /* support removeable boot drives */
855#define CFBIOSSTATE 0x000C /* BIOS Action State */
856#define CFBS_DISABLED 0x00
857#define CFBS_ENABLED 0x04
858#define CFBS_DISABLED_SCAN 0x08
859#define CFENABLEDV 0x0010 /* Perform Domain Validation */
860#define CFCTRL_A 0x0020 /* BIOS displays Ctrl-A message */
861#define CFSPARITY 0x0040 /* SCSI parity */
862#define CFEXTEND 0x0080 /* extended translation enabled */
863#define CFBOOTCD 0x0100 /* Support Bootable CD-ROM */
864#define CFMSG_LEVEL 0x0600 /* BIOS Message Level */
865#define CFMSG_VERBOSE 0x0000
866#define CFMSG_SILENT 0x0200
867#define CFMSG_DIAG 0x0400
868#define CFRESETB 0x0800 /* reset SCSI bus at boot */
869/* UNUSED 0xf000 */
870
871/*
872 * Host Adapter Control Bits
873 */
874 uint16_t adapter_control; /* word 17 */
875#define CFAUTOTERM 0x0001 /* Perform Auto termination */
876#define CFSTERM 0x0002 /* SCSI low byte termination */
877#define CFWSTERM 0x0004 /* SCSI high byte termination */
878#define CFSEAUTOTERM 0x0008 /* Ultra2 Perform secondary Auto Term*/
879#define CFSELOWTERM 0x0010 /* Ultra2 secondary low term */
880#define CFSEHIGHTERM 0x0020 /* Ultra2 secondary high term */
881#define CFSTPWLEVEL 0x0040 /* Termination level control */
882#define CFBIOSAUTOTERM 0x0080 /* Perform Auto termination */
883#define CFTERM_MENU 0x0100 /* BIOS displays termination menu */
884#define CFCLUSTERENB 0x8000 /* Cluster Enable */
885
886/*
887 * Bus Release Time, Host Adapter ID
888 */
889 uint16_t brtime_id; /* word 18 */
890#define CFSCSIID 0x000f /* host adapter SCSI ID */
891/* UNUSED 0x00f0 */
892#define CFBRTIME 0xff00 /* bus release time/PCI Latency Time */
893
894/*
895 * Maximum targets
896 */
897 uint16_t max_targets; /* word 19 */
898#define CFMAXTARG 0x00ff /* maximum targets */
899#define CFBOOTLUN 0x0f00 /* Lun to boot from */
900#define CFBOOTID 0xf000 /* Target to boot from */
901 uint16_t res_1[10]; /* words 20-29 */
902 uint16_t signature; /* BIOS Signature */
903#define CFSIGNATURE 0x400
904 uint16_t checksum; /* word 31 */
905};
906
907/*
908 * Vital Product Data used during POST and by the BIOS.
909 */
910struct vpd_config {
911 uint8_t bios_flags;
912#define VPDMASTERBIOS 0x0001
913#define VPDBOOTHOST 0x0002
914 uint8_t reserved_1[21];
915 uint8_t resource_type;
916 uint8_t resource_len[2];
917 uint8_t resource_data[8];
918 uint8_t vpd_tag;
919 uint16_t vpd_len;
920 uint8_t vpd_keyword[2];
921 uint8_t length;
922 uint8_t revision;
923 uint8_t device_flags;
924 uint8_t termnation_menus[2];
925 uint8_t fifo_threshold;
926 uint8_t end_tag;
927 uint8_t vpd_checksum;
928 uint16_t default_target_flags;
929 uint16_t default_bios_flags;
930 uint16_t default_ctrl_flags;
931 uint8_t default_irq;
932 uint8_t pci_lattime;
933 uint8_t max_target;
934 uint8_t boot_lun;
935 uint16_t signature;
936 uint8_t reserved_2;
937 uint8_t checksum;
938 uint8_t reserved_3[4];
939};
940
941/****************************** Flexport Logic ********************************/
942#define FLXADDR_TERMCTL 0x0
943#define FLX_TERMCTL_ENSECHIGH 0x8
944#define FLX_TERMCTL_ENSECLOW 0x4
945#define FLX_TERMCTL_ENPRIHIGH 0x2
946#define FLX_TERMCTL_ENPRILOW 0x1
947#define FLXADDR_ROMSTAT_CURSENSECTL 0x1
948#define FLX_ROMSTAT_SEECFG 0xF0
949#define FLX_ROMSTAT_EECFG 0x0F
950#define FLX_ROMSTAT_SEE_93C66 0x00
951#define FLX_ROMSTAT_SEE_NONE 0xF0
952#define FLX_ROMSTAT_EE_512x8 0x0
953#define FLX_ROMSTAT_EE_1MBx8 0x1
954#define FLX_ROMSTAT_EE_2MBx8 0x2
955#define FLX_ROMSTAT_EE_4MBx8 0x3
956#define FLX_ROMSTAT_EE_16MBx8 0x4
957#define CURSENSE_ENB 0x1
958#define FLXADDR_FLEXSTAT 0x2
959#define FLX_FSTAT_BUSY 0x1
960#define FLXADDR_CURRENT_STAT 0x4
961#define FLX_CSTAT_SEC_HIGH 0xC0
962#define FLX_CSTAT_SEC_LOW 0x30
963#define FLX_CSTAT_PRI_HIGH 0x0C
964#define FLX_CSTAT_PRI_LOW 0x03
965#define FLX_CSTAT_MASK 0x03
966#define FLX_CSTAT_SHIFT 2
967#define FLX_CSTAT_OKAY 0x0
968#define FLX_CSTAT_OVER 0x1
969#define FLX_CSTAT_UNDER 0x2
970#define FLX_CSTAT_INVALID 0x3
971
972int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
973 u_int start_addr, u_int count, int bstream);
974
975int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
976 u_int start_addr, u_int count);
977int ahd_wait_seeprom(struct ahd_softc *ahd);
978int ahd_verify_vpd_cksum(struct vpd_config *vpd);
979int ahd_verify_cksum(struct seeprom_config *sc);
980int ahd_acquire_seeprom(struct ahd_softc *ahd);
981void ahd_release_seeprom(struct ahd_softc *ahd);
982
983/**************************** Message Buffer *********************************/
984typedef enum {
985 MSG_FLAG_NONE = 0x00,
986 MSG_FLAG_EXPECT_PPR_BUSFREE = 0x01,
987 MSG_FLAG_IU_REQ_CHANGED = 0x02,
988 MSG_FLAG_EXPECT_IDE_BUSFREE = 0x04,
989 MSG_FLAG_EXPECT_QASREJ_BUSFREE = 0x08,
990 MSG_FLAG_PACKETIZED = 0x10
991} ahd_msg_flags;
992
993typedef enum {
994 MSG_TYPE_NONE = 0x00,
995 MSG_TYPE_INITIATOR_MSGOUT = 0x01,
996 MSG_TYPE_INITIATOR_MSGIN = 0x02,
997 MSG_TYPE_TARGET_MSGOUT = 0x03,
998 MSG_TYPE_TARGET_MSGIN = 0x04
999} ahd_msg_type;
1000
1001typedef enum {
1002 MSGLOOP_IN_PROG,
1003 MSGLOOP_MSGCOMPLETE,
1004 MSGLOOP_TERMINATED
1005} msg_loop_stat;
1006
1007/*********************** Software Configuration Structure *********************/
1008struct ahd_suspend_channel_state {
1009 uint8_t scsiseq;
1010 uint8_t sxfrctl0;
1011 uint8_t sxfrctl1;
1012 uint8_t simode0;
1013 uint8_t simode1;
1014 uint8_t seltimer;
1015 uint8_t seqctl;
1016};
1017
1018struct ahd_suspend_state {
1019 struct ahd_suspend_channel_state channel[2];
1020 uint8_t optionmode;
1021 uint8_t dscommand0;
1022 uint8_t dspcistatus;
1023 /* hsmailbox */
1024 uint8_t crccontrol1;
1025 uint8_t scbbaddr;
1026 /* Host and sequencer SCB counts */
1027 uint8_t dff_thrsh;
1028 uint8_t *scratch_ram;
1029 uint8_t *btt;
1030};
1031
1032typedef void (*ahd_bus_intr_t)(struct ahd_softc *);
1033
1034typedef enum {
1035 AHD_MODE_DFF0,
1036 AHD_MODE_DFF1,
1037 AHD_MODE_CCHAN,
1038 AHD_MODE_SCSI,
1039 AHD_MODE_CFG,
1040 AHD_MODE_UNKNOWN
1041} ahd_mode;
1042
1043#define AHD_MK_MSK(x) (0x01 << (x))
1044#define AHD_MODE_DFF0_MSK AHD_MK_MSK(AHD_MODE_DFF0)
1045#define AHD_MODE_DFF1_MSK AHD_MK_MSK(AHD_MODE_DFF1)
1046#define AHD_MODE_CCHAN_MSK AHD_MK_MSK(AHD_MODE_CCHAN)
1047#define AHD_MODE_SCSI_MSK AHD_MK_MSK(AHD_MODE_SCSI)
1048#define AHD_MODE_CFG_MSK AHD_MK_MSK(AHD_MODE_CFG)
1049#define AHD_MODE_UNKNOWN_MSK AHD_MK_MSK(AHD_MODE_UNKNOWN)
1050#define AHD_MODE_ANY_MSK (~0)
1051
1052typedef uint8_t ahd_mode_state;
1053
1054typedef void ahd_callback_t (void *);
1055
1056struct ahd_softc {
1057 bus_space_tag_t tags[2];
1058 bus_space_handle_t bshs[2];
1059#ifndef __linux__
1060 bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
1061#endif
1062 struct scb_data scb_data;
1063
1064 struct hardware_scb *next_queued_hscb;
1065
1066 /*
1067 * SCBs that have been sent to the controller
1068 */
1069 LIST_HEAD(, scb) pending_scbs;
1070
1071 /*
1072 * Current register window mode information.
1073 */
1074 ahd_mode dst_mode;
1075 ahd_mode src_mode;
1076
1077 /*
1078 * Saved register window mode information
1079 * used for restore on next unpause.
1080 */
1081 ahd_mode saved_dst_mode;
1082 ahd_mode saved_src_mode;
1083
1084 /*
1085 * Platform specific data.
1086 */
1087 struct ahd_platform_data *platform_data;
1088
1089 /*
1090 * Platform specific device information.
1091 */
1092 ahd_dev_softc_t dev_softc;
1093
1094 /*
1095 * Bus specific device information.
1096 */
1097 ahd_bus_intr_t bus_intr;
1098
1099 /*
1100 * Target mode related state kept on a per enabled lun basis.
1101 * Targets that are not enabled will have null entries.
1102 * As an initiator, we keep one target entry for our initiator
1103 * ID to store our sync/wide transfer settings.
1104 */
1105 struct ahd_tmode_tstate *enabled_targets[AHD_NUM_TARGETS];
1106
1107 /*
1108 * The black hole device responsible for handling requests for
1109 * disabled luns on enabled targets.
1110 */
1111 struct ahd_tmode_lstate *black_hole;
1112
1113 /*
1114 * Device instance currently on the bus awaiting a continue TIO
1115 * for a command that was not given the disconnect priveledge.
1116 */
1117 struct ahd_tmode_lstate *pending_device;
1118
1119 /*
1120 * Timer handles for timer driven callbacks.
1121 */
1122 ahd_timer_t reset_timer;
1123 ahd_timer_t stat_timer;
1124
1125 /*
1126 * Statistics.
1127 */
1128#define AHD_STAT_UPDATE_US 250000 /* 250ms */
1129#define AHD_STAT_BUCKETS 4
1130 u_int cmdcmplt_bucket;
1131 uint32_t cmdcmplt_counts[AHD_STAT_BUCKETS];
1132 uint32_t cmdcmplt_total;
1133
1134 /*
1135 * Card characteristics
1136 */
1137 ahd_chip chip;
1138 ahd_feature features;
1139 ahd_bug bugs;
1140 ahd_flag flags;
1141 struct seeprom_config *seep_config;
1142
1143 /* Values to store in the SEQCTL register for pause and unpause */
1144 uint8_t unpause;
1145 uint8_t pause;
1146
1147 /* Command Queues */
1148 uint16_t qoutfifonext;
1149 uint16_t qoutfifonext_valid_tag;
1150 uint16_t qinfifonext;
1151 uint16_t qinfifo[AHD_SCB_MAX];
1152 uint16_t *qoutfifo;
1153
1154 /* Critical Section Data */
1155 struct cs *critical_sections;
1156 u_int num_critical_sections;
1157
1158 /* Buffer for handling packetized bitbucket. */
1159 uint8_t *overrun_buf;
1160
1161 /* Links for chaining softcs */
1162 TAILQ_ENTRY(ahd_softc) links;
1163
1164 /* Channel Names ('A', 'B', etc.) */
1165 char channel;
1166
1167 /* Initiator Bus ID */
1168 uint8_t our_id;
1169
1170 /*
1171 * Target incoming command FIFO.
1172 */
1173 struct target_cmd *targetcmds;
1174 uint8_t tqinfifonext;
1175
1176 /*
1177 * Cached verson of the hs_mailbox so we can avoid
1178 * pausing the sequencer during mailbox updates.
1179 */
1180 uint8_t hs_mailbox;
1181
1182 /*
1183 * Incoming and outgoing message handling.
1184 */
1185 uint8_t send_msg_perror;
1186 ahd_msg_flags msg_flags;
1187 ahd_msg_type msg_type;
1188 uint8_t msgout_buf[12];/* Message we are sending */
1189 uint8_t msgin_buf[12];/* Message we are receiving */
1190 u_int msgout_len; /* Length of message to send */
1191 u_int msgout_index; /* Current index in msgout */
1192 u_int msgin_index; /* Current index in msgin */
1193
1194 /*
1195 * Mapping information for data structures shared
1196 * between the sequencer and kernel.
1197 */
1198 bus_dma_tag_t parent_dmat;
1199 bus_dma_tag_t shared_data_dmat;
1200 bus_dmamap_t shared_data_dmamap;
1201 dma_addr_t shared_data_busaddr;
1202
1203 /* Information saved through suspend/resume cycles */
1204 struct ahd_suspend_state suspend_state;
1205
1206 /* Number of enabled target mode device on this card */
1207 u_int enabled_luns;
1208
1209 /* Initialization level of this data structure */
1210 u_int init_level;
1211
1212 /* PCI cacheline size. */
1213 u_int pci_cachesize;
1214
1215 /* IO Cell Parameters */
1216 uint8_t iocell_opts[AHD_NUM_PER_DEV_ANNEXCOLS];
1217
1218 u_int stack_size;
1219 uint16_t *saved_stack;
1220
1221 /* Per-Unit descriptive information */
1222 const char *description;
1223 const char *bus_description;
1224 char *name;
1225 int unit;
1226
1227 /* Selection Timer settings */
1228 int seltime;
1229
1230 /*
1231 * Interrupt coalescing settings.
1232 */
1233#define AHD_INT_COALESCING_TIMER_DEFAULT 250 /*us*/
1234#define AHD_INT_COALESCING_MAXCMDS_DEFAULT 10
1235#define AHD_INT_COALESCING_MAXCMDS_MAX 127
1236#define AHD_INT_COALESCING_MINCMDS_DEFAULT 5
1237#define AHD_INT_COALESCING_MINCMDS_MAX 127
1238#define AHD_INT_COALESCING_THRESHOLD_DEFAULT 2000
1239#define AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT 1000
1240 u_int int_coalescing_timer;
1241 u_int int_coalescing_maxcmds;
1242 u_int int_coalescing_mincmds;
1243 u_int int_coalescing_threshold;
1244 u_int int_coalescing_stop_threshold;
1245
1246 uint16_t user_discenable;/* Disconnection allowed */
1247 uint16_t user_tagenable;/* Tagged Queuing allowed */
1248};
1249
1250TAILQ_HEAD(ahd_softc_tailq, ahd_softc);
1251extern struct ahd_softc_tailq ahd_tailq;
1252
1253/*************************** IO Cell Configuration ****************************/
1254#define AHD_PRECOMP_SLEW_INDEX \
1255 (AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0)
1256
1257#define AHD_AMPLITUDE_INDEX \
1258 (AHD_ANNEXCOL_AMPLITUDE - AHD_ANNEXCOL_PER_DEV0)
1259
1260#define AHD_SET_SLEWRATE(ahd, new_slew) \
1261do { \
1262 (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_SLEWRATE_MASK; \
1263 (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \
1264 (((new_slew) << AHD_SLEWRATE_SHIFT) & AHD_SLEWRATE_MASK); \
1265} while (0)
1266
1267#define AHD_SET_PRECOMP(ahd, new_pcomp) \
1268do { \
1269 (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK; \
1270 (ahd)->iocell_opts[AHD_PRECOMP_SLEW_INDEX] |= \
1271 (((new_pcomp) << AHD_PRECOMP_SHIFT) & AHD_PRECOMP_MASK); \
1272} while (0)
1273
1274#define AHD_SET_AMPLITUDE(ahd, new_amp) \
1275do { \
1276 (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] &= ~AHD_AMPLITUDE_MASK; \
1277 (ahd)->iocell_opts[AHD_AMPLITUDE_INDEX] |= \
1278 (((new_amp) << AHD_AMPLITUDE_SHIFT) & AHD_AMPLITUDE_MASK); \
1279} while (0)
1280
1281/************************ Active Device Information ***************************/
1282typedef enum {
1283 ROLE_UNKNOWN,
1284 ROLE_INITIATOR,
1285 ROLE_TARGET
1286} role_t;
1287
1288struct ahd_devinfo {
1289 int our_scsiid;
1290 int target_offset;
1291 uint16_t target_mask;
1292 u_int target;
1293 u_int lun;
1294 char channel;
1295 role_t role; /*
1296 * Only guaranteed to be correct if not
1297 * in the busfree state.
1298 */
1299};
1300
1301/****************************** PCI Structures ********************************/
1302#define AHD_PCI_IOADDR0 PCIR_MAPS /* I/O BAR*/
1303#define AHD_PCI_MEMADDR (PCIR_MAPS + 4) /* Memory BAR */
1304#define AHD_PCI_IOADDR1 (PCIR_MAPS + 12)/* Second I/O BAR */
1305
1306typedef int (ahd_device_setup_t)(struct ahd_softc *);
1307
1308struct ahd_pci_identity {
1309 uint64_t full_id;
1310 uint64_t id_mask;
1311 char *name;
1312 ahd_device_setup_t *setup;
1313};
1314extern struct ahd_pci_identity ahd_pci_ident_table [];
1315extern const u_int ahd_num_pci_devs;
1316
1317/***************************** VL/EISA Declarations ***************************/
1318struct aic7770_identity {
1319 uint32_t full_id;
1320 uint32_t id_mask;
1321 char *name;
1322 ahd_device_setup_t *setup;
1323};
1324extern struct aic7770_identity aic7770_ident_table [];
1325extern const int ahd_num_aic7770_devs;
1326
1327#define AHD_EISA_SLOT_OFFSET 0xc00
1328#define AHD_EISA_IOSIZE 0x100
1329
1330/*************************** Function Declarations ****************************/
1331/******************************************************************************/
1332void ahd_reset_cmds_pending(struct ahd_softc *ahd);
1333u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl);
1334void ahd_busy_tcl(struct ahd_softc *ahd,
1335 u_int tcl, u_int busyid);
1336static __inline void ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl);
1337static __inline void
1338ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
1339{
1340 ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
1341}
1342
1343/***************************** PCI Front End *********************************/
1344struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t);
1345int ahd_pci_config(struct ahd_softc *,
1346 struct ahd_pci_identity *);
1347int ahd_pci_test_register_access(struct ahd_softc *);
1348
1349/************************** SCB and SCB queue management **********************/
1350int ahd_probe_scbs(struct ahd_softc *);
1351void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd,
1352 struct scb *scb);
1353int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb,
1354 int target, char channel, int lun,
1355 u_int tag, role_t role);
1356
1357/****************************** Initialization ********************************/
1358struct ahd_softc *ahd_alloc(void *platform_arg, char *name);
1359int ahd_softc_init(struct ahd_softc *);
1360void ahd_controller_info(struct ahd_softc *ahd, char *buf);
1361int ahd_init(struct ahd_softc *ahd);
1362int ahd_default_config(struct ahd_softc *ahd);
1363int ahd_parse_vpddata(struct ahd_softc *ahd,
1364 struct vpd_config *vpd);
1365int ahd_parse_cfgdata(struct ahd_softc *ahd,
1366 struct seeprom_config *sc);
1367void ahd_intr_enable(struct ahd_softc *ahd, int enable);
1368void ahd_update_coalescing_values(struct ahd_softc *ahd,
1369 u_int timer,
1370 u_int maxcmds,
1371 u_int mincmds);
1372void ahd_enable_coalescing(struct ahd_softc *ahd,
1373 int enable);
1374void ahd_pause_and_flushwork(struct ahd_softc *ahd);
1375int ahd_suspend(struct ahd_softc *ahd);
1376int ahd_resume(struct ahd_softc *ahd);
1377void ahd_softc_insert(struct ahd_softc *);
1378struct ahd_softc *ahd_find_softc(struct ahd_softc *ahd);
1379void ahd_set_unit(struct ahd_softc *, int);
1380void ahd_set_name(struct ahd_softc *, char *);
1381struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
1382void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb);
1383void ahd_alloc_scbs(struct ahd_softc *ahd);
1384void ahd_free(struct ahd_softc *ahd);
1385int ahd_reset(struct ahd_softc *ahd, int reinit);
1386void ahd_shutdown(void *arg);
1387int ahd_write_flexport(struct ahd_softc *ahd,
1388 u_int addr, u_int value);
1389int ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
1390 uint8_t *value);
1391int ahd_wait_flexport(struct ahd_softc *ahd);
1392
1393/*************************** Interrupt Services *******************************/
1394void ahd_pci_intr(struct ahd_softc *ahd);
1395void ahd_clear_intstat(struct ahd_softc *ahd);
1396void ahd_flush_qoutfifo(struct ahd_softc *ahd);
1397void ahd_run_qoutfifo(struct ahd_softc *ahd);
1398#ifdef AHD_TARGET_MODE
1399void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused);
1400#endif
1401void ahd_handle_hwerrint(struct ahd_softc *ahd);
1402void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat);
1403void ahd_handle_scsiint(struct ahd_softc *ahd,
1404 u_int intstat);
1405void ahd_clear_critical_section(struct ahd_softc *ahd);
1406
1407/***************************** Error Recovery *********************************/
1408typedef enum {
1409 SEARCH_COMPLETE,
1410 SEARCH_COUNT,
1411 SEARCH_REMOVE,
1412 SEARCH_PRINT
1413} ahd_search_action;
1414int ahd_search_qinfifo(struct ahd_softc *ahd, int target,
1415 char channel, int lun, u_int tag,
1416 role_t role, uint32_t status,
1417 ahd_search_action action);
1418int ahd_search_disc_list(struct ahd_softc *ahd, int target,
1419 char channel, int lun, u_int tag,
1420 int stop_on_first, int remove,
1421 int save_state);
1422void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
1423int ahd_reset_channel(struct ahd_softc *ahd, char channel,
1424 int initiate_reset);
1425int ahd_abort_scbs(struct ahd_softc *ahd, int target,
1426 char channel, int lun, u_int tag,
1427 role_t role, uint32_t status);
1428void ahd_restart(struct ahd_softc *ahd);
1429void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo);
1430void ahd_handle_scb_status(struct ahd_softc *ahd,
1431 struct scb *scb);
1432void ahd_handle_scsi_status(struct ahd_softc *ahd,
1433 struct scb *scb);
1434void ahd_calc_residual(struct ahd_softc *ahd,
1435 struct scb *scb);
1436/*************************** Utility Functions ********************************/
1437struct ahd_phase_table_entry*
1438 ahd_lookup_phase_entry(int phase);
1439void ahd_compile_devinfo(struct ahd_devinfo *devinfo,
1440 u_int our_id, u_int target,
1441 u_int lun, char channel,
1442 role_t role);
1443/************************** Transfer Negotiation ******************************/
1444void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
1445 u_int *ppr_options, u_int maxsync);
1446void ahd_validate_offset(struct ahd_softc *ahd,
1447 struct ahd_initiator_tinfo *tinfo,
1448 u_int period, u_int *offset,
1449 int wide, role_t role);
1450void ahd_validate_width(struct ahd_softc *ahd,
1451 struct ahd_initiator_tinfo *tinfo,
1452 u_int *bus_width,
1453 role_t role);
1454/*
1455 * Negotiation types. These are used to qualify if we should renegotiate
1456 * even if our goal and current transport parameters are identical.
1457 */
1458typedef enum {
1459 AHD_NEG_TO_GOAL, /* Renegotiate only if goal and curr differ. */
1460 AHD_NEG_IF_NON_ASYNC, /* Renegotiate so long as goal is non-async. */
1461 AHD_NEG_ALWAYS /* Renegotiat even if goal is async. */
1462} ahd_neg_type;
1463int ahd_update_neg_request(struct ahd_softc*,
1464 struct ahd_devinfo*,
1465 struct ahd_tmode_tstate*,
1466 struct ahd_initiator_tinfo*,
1467 ahd_neg_type);
1468void ahd_set_width(struct ahd_softc *ahd,
1469 struct ahd_devinfo *devinfo,
1470 u_int width, u_int type, int paused);
1471void ahd_set_syncrate(struct ahd_softc *ahd,
1472 struct ahd_devinfo *devinfo,
1473 u_int period, u_int offset,
1474 u_int ppr_options,
1475 u_int type, int paused);
1476typedef enum {
1477 AHD_QUEUE_NONE,
1478 AHD_QUEUE_BASIC,
1479 AHD_QUEUE_TAGGED
1480} ahd_queue_alg;
1481
1482void ahd_set_tags(struct ahd_softc *ahd,
1483 struct ahd_devinfo *devinfo,
1484 ahd_queue_alg alg);
1485
1486/**************************** Target Mode *************************************/
1487#ifdef AHD_TARGET_MODE
1488void ahd_send_lstate_events(struct ahd_softc *,
1489 struct ahd_tmode_lstate *);
1490void ahd_handle_en_lun(struct ahd_softc *ahd,
1491 struct cam_sim *sim, union ccb *ccb);
1492cam_status ahd_find_tmode_devs(struct ahd_softc *ahd,
1493 struct cam_sim *sim, union ccb *ccb,
1494 struct ahd_tmode_tstate **tstate,
1495 struct ahd_tmode_lstate **lstate,
1496 int notfound_failure);
1497#ifndef AHD_TMODE_ENABLE
1498#define AHD_TMODE_ENABLE 0
1499#endif
1500#endif
1501/******************************* Debug ***************************************/
1502#ifdef AHD_DEBUG
1503extern uint32_t ahd_debug;
1504#define AHD_SHOW_MISC 0x00001
1505#define AHD_SHOW_SENSE 0x00002
1506#define AHD_SHOW_RECOVERY 0x00004
1507#define AHD_DUMP_SEEPROM 0x00008
1508#define AHD_SHOW_TERMCTL 0x00010
1509#define AHD_SHOW_MEMORY 0x00020
1510#define AHD_SHOW_MESSAGES 0x00040
1511#define AHD_SHOW_MODEPTR 0x00080
1512#define AHD_SHOW_SELTO 0x00100
1513#define AHD_SHOW_FIFOS 0x00200
1514#define AHD_SHOW_QFULL 0x00400
1515#define AHD_SHOW_DV 0x00800
1516#define AHD_SHOW_MASKED_ERRORS 0x01000
1517#define AHD_SHOW_QUEUE 0x02000
1518#define AHD_SHOW_TQIN 0x04000
1519#define AHD_SHOW_SG 0x08000
1520#define AHD_SHOW_INT_COALESCING 0x10000
1521#define AHD_DEBUG_SEQUENCER 0x20000
1522#endif
1523void ahd_print_scb(struct scb *scb);
1524void ahd_print_devinfo(struct ahd_softc *ahd,
1525 struct ahd_devinfo *devinfo);
1526void ahd_dump_sglist(struct scb *scb);
1527void ahd_dump_all_cards_state(void);
1528void ahd_dump_card_state(struct ahd_softc *ahd);
1529int ahd_print_register(ahd_reg_parse_entry_t *table,
1530 u_int num_entries,
1531 const char *name,
1532 u_int address,
1533 u_int value,
1534 u_int *cur_column,
1535 u_int wrap_point);
1536void ahd_dump_scbs(struct ahd_softc *ahd);
1537#endif /* _AIC79XX_H_ */
diff --git a/drivers/scsi/aic7xxx/aic79xx.reg b/drivers/scsi/aic7xxx/aic79xx.reg
new file mode 100644
index 000000000000..cca58edc8648
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx.reg
@@ -0,0 +1,3958 @@
1/*
2 * Aic79xx register and scratch ram definitions.
3 *
4 * Copyright (c) 1994-2001 Justin T. Gibbs.
5 * Copyright (c) 2000-2002 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $FreeBSD$
41 */
42VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $"
43
44/*
45 * This file is processed by the aic7xxx_asm utility for use in assembling
46 * firmware for the aic79xx family of SCSI host adapters as well as to generate
47 * a C header file for use in the kernel portion of the Aic79xx driver.
48 */
49
50/* Register window Modes */
51#define M_DFF0 0
52#define M_DFF1 1
53#define M_CCHAN 2
54#define M_SCSI 3
55#define M_CFG 4
56#define M_DST_SHIFT 4
57
58#define MK_MODE(src, dst) ((src) | ((dst) << M_DST_SHIFT))
59#define SET_MODE(src, dst) \
60 SET_SRC_MODE src; \
61 SET_DST_MODE dst; \
62 if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \
63 mvi MK_MODE(src, dst) call set_mode_work_around; \
64 } else { \
65 mvi MODE_PTR, MK_MODE(src, dst); \
66 }
67
68#define TOGGLE_DFF_MODE \
69 if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \
70 call toggle_dff_mode_work_around; \
71 } else { \
72 xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); \
73 }
74
75#define RESTORE_MODE(mode) \
76 if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \
77 mov mode call set_mode_work_around; \
78 } else { \
79 mov MODE_PTR, mode; \
80 }
81
82#define SET_SEQINTCODE(code) \
83 if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { \
84 mvi code call set_seqint_work_around; \
85 } else { \
86 mvi SEQINTCODE, code; \
87 }
88
89/*
90 * Mode Pointer
91 * Controls which of the 5, 512byte, address spaces should be used
92 * as the source and destination of any register accesses in our
93 * register window.
94 */
95register MODE_PTR {
96 address 0x000
97 access_mode RW
98 field DST_MODE 0x70
99 field SRC_MODE 0x07
100 mode_pointer
101}
102
103const SRC_MODE_SHIFT 0
104const DST_MODE_SHIFT 4
105
106/*
107 * Host Interrupt Status
108 */
109register INTSTAT {
110 address 0x001
111 access_mode RW
112 field HWERRINT 0x80
113 field BRKADRINT 0x40
114 field SWTMINT 0x20
115 field PCIINT 0x10
116 field SCSIINT 0x08
117 field SEQINT 0x04
118 field CMDCMPLT 0x02
119 field SPLTINT 0x01
120 mask INT_PEND 0xFF
121}
122
123/*
124 * Sequencer Interrupt Code
125 */
126register SEQINTCODE {
127 address 0x002
128 access_mode RW
129 field {
130 NO_SEQINT, /* No seqint pending. */
131 BAD_PHASE, /* unknown scsi bus phase */
132 SEND_REJECT, /* sending a message reject */
133 PROTO_VIOLATION, /* Protocol Violation */
134 NO_MATCH, /* no cmd match for reconnect */
135 IGN_WIDE_RES, /* Complex IGN Wide Res Msg */
136 PDATA_REINIT, /*
137 * Returned to data phase
138 * that requires data
139 * transfer pointers to be
140 * recalculated from the
141 * transfer residual.
142 */
143 HOST_MSG_LOOP, /*
144 * The bus is ready for the
145 * host to perform another
146 * message transaction. This
147 * mechanism is used for things
148 * like sync/wide negotiation
149 * that require a kernel based
150 * message state engine.
151 */
152 BAD_STATUS, /* Bad status from target */
153 DATA_OVERRUN, /*
154 * Target attempted to write
155 * beyond the bounds of its
156 * command.
157 */
158 MKMSG_FAILED, /*
159 * Target completed command
160 * without honoring our ATN
161 * request to issue a message.
162 */
163 MISSED_BUSFREE, /*
164 * The sequencer never saw
165 * the bus go free after
166 * either a command complete
167 * or disconnect message.
168 */
169 DUMP_CARD_STATE,
170 ILLEGAL_PHASE,
171 INVALID_SEQINT,
172 CFG4ISTAT_INTR,
173 STATUS_OVERRUN,
174 CFG4OVERRUN,
175 ENTERING_NONPACK,
176 TASKMGMT_FUNC_COMPLETE, /*
177 * Task management function
178 * request completed with
179 * an expected busfree.
180 */
181 TASKMGMT_CMD_CMPLT_OKAY, /*
182 * A command with a non-zero
183 * task management function
184 * has completed via the normal
185 * command completion method
186 * for commands with a zero
187 * task management function.
188 * This happens when an attempt
189 * to abort a command loses
190 * the race for the command to
191 * complete normally.
192 */
193 TRACEPOINT0,
194 TRACEPOINT1,
195 TRACEPOINT2,
196 TRACEPOINT3,
197 SAW_HWERR,
198 BAD_SCB_STATUS
199 }
200}
201
202/*
203 * Clear Host Interrupt
204 */
205register CLRINT {
206 address 0x003
207 access_mode WO
208 field CLRHWERRINT 0x80 /* Rev B or greater */
209 field CLRBRKADRINT 0x40
210 field CLRSWTMINT 0x20
211 field CLRPCIINT 0x10
212 field CLRSCSIINT 0x08
213 field CLRSEQINT 0x04
214 field CLRCMDINT 0x02
215 field CLRSPLTINT 0x01
216}
217
218/*
219 * Error Register
220 */
221register ERROR {
222 address 0x004
223 access_mode RO
224 field CIOPARERR 0x80
225 field CIOACCESFAIL 0x40 /* Rev B or greater */
226 field MPARERR 0x20
227 field DPARERR 0x10
228 field SQPARERR 0x08
229 field ILLOPCODE 0x04
230 field DSCTMOUT 0x02
231}
232
233/*
234 * Clear Error
235 */
236register CLRERR {
237 address 0x004
238 access_mode WO
239 field CLRCIOPARERR 0x80
240 field CLRCIOACCESFAIL 0x40 /* Rev B or greater */
241 field CLRMPARERR 0x20
242 field CLRDPARERR 0x10
243 field CLRSQPARERR 0x08
244 field CLRILLOPCODE 0x04
245 field CLRDSCTMOUT 0x02
246}
247
248/*
249 * Host Control Register
250 * Overall host control of the device.
251 */
252register HCNTRL {
253 address 0x005
254 access_mode RW
255 field SEQ_RESET 0x80 /* Rev B or greater */
256 field POWRDN 0x40
257 field SWINT 0x10
258 field SWTIMER_START_B 0x08 /* Rev B or greater */
259 field PAUSE 0x04
260 field INTEN 0x02
261 field CHIPRST 0x01
262 field CHIPRSTACK 0x01
263}
264
265/*
266 * Host New SCB Queue Offset
267 */
268register HNSCB_QOFF {
269 address 0x006
270 access_mode RW
271 size 2
272}
273
274/*
275 * Host Empty SCB Queue Offset
276 */
277register HESCB_QOFF {
278 address 0x008
279 access_mode RW
280}
281
282/*
283 * Host Mailbox
284 */
285register HS_MAILBOX {
286 address 0x00B
287 access_mode RW
288 mask HOST_TQINPOS 0x80 /* Boundary at either 0 or 128 */
289 mask ENINT_COALESCE 0x40 /* Perform interrupt coalescing */
290}
291
292/*
293 * Sequencer Interupt Status
294 */
295register SEQINTSTAT {
296 address 0x00C
297 access_mode RO
298 field SEQ_SWTMRTO 0x10
299 field SEQ_SEQINT 0x08
300 field SEQ_SCSIINT 0x04
301 field SEQ_PCIINT 0x02
302 field SEQ_SPLTINT 0x01
303}
304
305/*
306 * Clear SEQ Interrupt
307 */
308register CLRSEQINTSTAT {
309 address 0x00C
310 access_mode WO
311 field CLRSEQ_SWTMRTO 0x10
312 field CLRSEQ_SEQINT 0x08
313 field CLRSEQ_SCSIINT 0x04
314 field CLRSEQ_PCIINT 0x02
315 field CLRSEQ_SPLTINT 0x01
316}
317
318/*
319 * Software Timer
320 */
321register SWTIMER {
322 address 0x00E
323 access_mode RW
324 size 2
325}
326
327/*
328 * SEQ New SCB Queue Offset
329 */
330register SNSCB_QOFF {
331 address 0x010
332 access_mode RW
333 size 2
334 modes M_CCHAN
335}
336
337/*
338 * SEQ Empty SCB Queue Offset
339 */
340register SESCB_QOFF {
341 address 0x012
342 access_mode RW
343 modes M_CCHAN
344}
345
346/*
347 * SEQ Done SCB Queue Offset
348 */
349register SDSCB_QOFF {
350 address 0x014
351 access_mode RW
352 modes M_CCHAN
353 size 2
354}
355
356/*
357 * Queue Offset Control & Status
358 */
359register QOFF_CTLSTA {
360 address 0x016
361 access_mode RW
362 modes M_CCHAN
363 field EMPTY_SCB_AVAIL 0x80
364 field NEW_SCB_AVAIL 0x40
365 field SDSCB_ROLLOVR 0x20
366 field HS_MAILBOX_ACT 0x10
367 field SCB_QSIZE 0x0F {
368 SCB_QSIZE_4,
369 SCB_QSIZE_8,
370 SCB_QSIZE_16,
371 SCB_QSIZE_32,
372 SCB_QSIZE_64,
373 SCB_QSIZE_128,
374 SCB_QSIZE_256,
375 SCB_QSIZE_512,
376 SCB_QSIZE_1024,
377 SCB_QSIZE_2048,
378 SCB_QSIZE_4096,
379 SCB_QSIZE_8192,
380 SCB_QSIZE_16384
381 }
382}
383
384/*
385 * Interrupt Control
386 */
387register INTCTL {
388 address 0x018
389 access_mode RW
390 field SWTMINTMASK 0x80
391 field SWTMINTEN 0x40
392 field SWTIMER_START 0x20
393 field AUTOCLRCMDINT 0x10
394 field PCIINTEN 0x08
395 field SCSIINTEN 0x04
396 field SEQINTEN 0x02
397 field SPLTINTEN 0x01
398}
399
400/*
401 * Data FIFO Control
402 */
403register DFCNTRL {
404 address 0x019
405 access_mode RW
406 modes M_DFF0, M_DFF1
407 field PRELOADEN 0x80
408 field SCSIENWRDIS 0x40 /* Rev B only. */
409 field SCSIEN 0x20
410 field SCSIENACK 0x20
411 field HDMAEN 0x08
412 field HDMAENACK 0x08
413 field DIRECTION 0x04
414 field DIRECTIONACK 0x04
415 field FIFOFLUSH 0x02
416 field FIFOFLUSHACK 0x02
417 field DIRECTIONEN 0x01
418}
419
420/*
421 * Device Space Command 0
422 */
423register DSCOMMAND0 {
424 address 0x019
425 access_mode RW
426 modes M_CFG
427 field CACHETHEN 0x80 /* Cache Threshold enable */
428 field DPARCKEN 0x40 /* Data Parity Check Enable */
429 field MPARCKEN 0x20 /* Memory Parity Check Enable */
430 field EXTREQLCK 0x10 /* External Request Lock */
431 field DISABLE_TWATE 0x02 /* Rev B or greater */
432 field CIOPARCKEN 0x01 /* Internal bus parity error enable */
433}
434
435/*
436 * Data FIFO Status
437 */
438register DFSTATUS {
439 address 0x01A
440 access_mode RO
441 modes M_DFF0, M_DFF1
442 field PRELOAD_AVAIL 0x80
443 field PKT_PRELOAD_AVAIL 0x40
444 field MREQPEND 0x10
445 field HDONE 0x08
446 field DFTHRESH 0x04
447 field FIFOFULL 0x02
448 field FIFOEMP 0x01
449}
450
451/*
452 * S/G Cache Pointer
453 */
454register SG_CACHE_PRE {
455 address 0x01B
456 access_mode WO
457 modes M_DFF0, M_DFF1
458 field SG_ADDR_MASK 0xf8
459 field ODD_SEG 0x04
460 field LAST_SEG 0x02
461}
462
463register SG_CACHE_SHADOW {
464 address 0x01B
465 access_mode RO
466 modes M_DFF0, M_DFF1
467 field SG_ADDR_MASK 0xf8
468 field ODD_SEG 0x04
469 field LAST_SEG 0x02
470 field LAST_SEG_DONE 0x01
471}
472
473/*
474 * Arbiter Control
475 */
476register ARBCTL {
477 address 0x01B
478 access_mode RW
479 modes M_CFG
480 field RESET_HARB 0x80
481 field RETRY_SWEN 0x08
482 field USE_TIME 0x07
483}
484
485/*
486 * Data Channel Host Address
487 */
488register HADDR {
489 address 0x070
490 access_mode RW
491 size 8
492 modes M_DFF0, M_DFF1
493}
494
495/*
496 * Host Overlay DMA Address
497 */
498register HODMAADR {
499 address 0x070
500 access_mode RW
501 size 8
502 modes M_SCSI
503}
504
505/*
506 * PCI PLL Delay.
507 */
508register PLLDELAY {
509 address 0x070
510 access_mode RW
511 size 1
512 modes M_CFG
513 field SPLIT_DROP_REQ 0x80
514}
515
516/*
517 * Data Channel Host Count
518 */
519register HCNT {
520 address 0x078
521 access_mode RW
522 size 3
523 modes M_DFF0, M_DFF1
524}
525
526/*
527 * Host Overlay DMA Count
528 */
529register HODMACNT {
530 address 0x078
531 access_mode RW
532 size 2
533 modes M_SCSI
534}
535
536/*
537 * Host Overlay DMA Enable
538 */
539register HODMAEN {
540 address 0x07A
541 access_mode RW
542 modes M_SCSI
543}
544
545/*
546 * Scatter/Gather Host Address
547 */
548register SGHADDR {
549 address 0x07C
550 access_mode RW
551 size 8
552 modes M_DFF0, M_DFF1
553}
554
555/*
556 * SCB Host Address
557 */
558register SCBHADDR {
559 address 0x07C
560 access_mode RW
561 size 8
562 modes M_CCHAN
563}
564
565/*
566 * Scatter/Gather Host Count
567 */
568register SGHCNT {
569 address 0x084
570 access_mode RW
571 modes M_DFF0, M_DFF1
572}
573
574/*
575 * SCB Host Count
576 */
577register SCBHCNT {
578 address 0x084
579 access_mode RW
580 modes M_CCHAN
581}
582
583/*
584 * Data FIFO Threshold
585 */
586register DFF_THRSH {
587 address 0x088
588 access_mode RW
589 modes M_CFG
590 field WR_DFTHRSH 0x70 {
591 WR_DFTHRSH_MIN,
592 WR_DFTHRSH_25,
593 WR_DFTHRSH_50,
594 WR_DFTHRSH_63,
595 WR_DFTHRSH_75,
596 WR_DFTHRSH_85,
597 WR_DFTHRSH_90,
598 WR_DFTHRSH_MAX
599 }
600 field RD_DFTHRSH 0x07 {
601 RD_DFTHRSH_MIN,
602 RD_DFTHRSH_25,
603 RD_DFTHRSH_50,
604 RD_DFTHRSH_63,
605 RD_DFTHRSH_75,
606 RD_DFTHRSH_85,
607 RD_DFTHRSH_90,
608 RD_DFTHRSH_MAX
609 }
610}
611
612/*
613 * ROM Address
614 */
615register ROMADDR {
616 address 0x08A
617 access_mode RW
618 size 3
619}
620
621/*
622 * ROM Control
623 */
624register ROMCNTRL {
625 address 0x08D
626 access_mode RW
627 field ROMOP 0xE0
628 field ROMSPD 0x18
629 field REPEAT 0x02
630 field RDY 0x01
631}
632
633/*
634 * ROM Data
635 */
636register ROMDATA {
637 address 0x08E
638 access_mode RW
639}
640
641/*
642 * Data Channel Receive Message 0
643 */
644register DCHRXMSG0 {
645 address 0x090
646 access_mode RO
647 modes M_DFF0, M_DFF1
648 field CDNUM 0xF8
649 field CFNUM 0x07
650}
651
652/*
653 * CMC Recieve Message 0
654 */
655register CMCRXMSG0 {
656 address 0x090
657 access_mode RO
658 modes M_CCHAN
659 field CDNUM 0xF8
660 field CFNUM 0x07
661}
662
663/*
664 * Overlay Recieve Message 0
665 */
666register OVLYRXMSG0 {
667 address 0x090
668 access_mode RO
669 modes M_SCSI
670 field CDNUM 0xF8
671 field CFNUM 0x07
672}
673
674/*
675 * Relaxed Order Enable
676 */
677register ROENABLE {
678 address 0x090
679 access_mode RW
680 modes M_CFG
681 field MSIROEN 0x20
682 field OVLYROEN 0x10
683 field CMCROEN 0x08
684 field SGROEN 0x04
685 field DCH1ROEN 0x02
686 field DCH0ROEN 0x01
687}
688
689/*
690 * Data Channel Receive Message 1
691 */
692register DCHRXMSG1 {
693 address 0x091
694 access_mode RO
695 modes M_DFF0, M_DFF1
696 field CBNUM 0xFF
697}
698
699/*
700 * CMC Recieve Message 1
701 */
702register CMCRXMSG1 {
703 address 0x091
704 access_mode RO
705 modes M_CCHAN
706 field CBNUM 0xFF
707}
708
709/*
710 * Overlay Recieve Message 1
711 */
712register OVLYRXMSG1 {
713 address 0x091
714 access_mode RO
715 modes M_SCSI
716 field CBNUM 0xFF
717}
718
719/*
720 * No Snoop Enable
721 */
722register NSENABLE {
723 address 0x091
724 access_mode RW
725 modes M_CFG
726 field MSINSEN 0x20
727 field OVLYNSEN 0x10
728 field CMCNSEN 0x08
729 field SGNSEN 0x04
730 field DCH1NSEN 0x02
731 field DCH0NSEN 0x01
732}
733
734/*
735 * Data Channel Receive Message 2
736 */
737register DCHRXMSG2 {
738 address 0x092
739 access_mode RO
740 modes M_DFF0, M_DFF1
741 field MINDEX 0xFF
742}
743
744/*
745 * CMC Recieve Message 2
746 */
747register CMCRXMSG2 {
748 address 0x092
749 access_mode RO
750 modes M_CCHAN
751 field MINDEX 0xFF
752}
753
754/*
755 * Overlay Recieve Message 2
756 */
757register OVLYRXMSG2 {
758 address 0x092
759 access_mode RO
760 modes M_SCSI
761 field MINDEX 0xFF
762}
763
764/*
765 * Outstanding Split Transactions
766 */
767register OST {
768 address 0x092
769 access_mode RW
770 modes M_CFG
771}
772
773/*
774 * Data Channel Receive Message 3
775 */
776register DCHRXMSG3 {
777 address 0x093
778 access_mode RO
779 modes M_DFF0, M_DFF1
780 field MCLASS 0x0F
781}
782
783/*
784 * CMC Recieve Message 3
785 */
786register CMCRXMSG3 {
787 address 0x093
788 access_mode RO
789 modes M_CCHAN
790 field MCLASS 0x0F
791}
792
793/*
794 * Overlay Recieve Message 3
795 */
796register OVLYRXMSG3 {
797 address 0x093
798 access_mode RO
799 modes M_SCSI
800 field MCLASS 0x0F
801}
802
803/*
804 * PCI-X Control
805 */
806register PCIXCTL {
807 address 0x093
808 access_mode RW
809 modes M_CFG
810 field SERRPULSE 0x80
811 field UNEXPSCIEN 0x20
812 field SPLTSMADIS 0x10
813 field SPLTSTADIS 0x08
814 field SRSPDPEEN 0x04
815 field TSCSERREN 0x02
816 field CMPABCDIS 0x01
817}
818
819/*
820 * CMC Sequencer Byte Count
821 */
822register CMCSEQBCNT {
823 address 0x094
824 access_mode RO
825 modes M_CCHAN
826}
827
828/*
829 * Overlay Sequencer Byte Count
830 */
831register OVLYSEQBCNT {
832 address 0x094
833 access_mode RO
834 modes M_SCSI
835}
836
837/*
838 * Data Channel Sequencer Byte Count
839 */
840register DCHSEQBCNT {
841 address 0x094
842 access_mode RO
843 size 2
844 modes M_DFF0, M_DFF1
845}
846
847/*
848 * Data Channel Split Status 0
849 */
850register DCHSPLTSTAT0 {
851 address 0x096
852 access_mode RW
853 modes M_DFF0, M_DFF1
854 field STAETERM 0x80
855 field SCBCERR 0x40
856 field SCADERR 0x20
857 field SCDATBUCKET 0x10
858 field CNTNOTCMPLT 0x08
859 field RXOVRUN 0x04
860 field RXSCEMSG 0x02
861 field RXSPLTRSP 0x01
862}
863
864/*
865 * CMC Split Status 0
866 */
867register CMCSPLTSTAT0 {
868 address 0x096
869 access_mode RW
870 modes M_CCHAN
871 field STAETERM 0x80
872 field SCBCERR 0x40
873 field SCADERR 0x20
874 field SCDATBUCKET 0x10
875 field CNTNOTCMPLT 0x08
876 field RXOVRUN 0x04
877 field RXSCEMSG 0x02
878 field RXSPLTRSP 0x01
879}
880
881/*
882 * Overlay Split Status 0
883 */
884register OVLYSPLTSTAT0 {
885 address 0x096
886 access_mode RW
887 modes M_SCSI
888 field STAETERM 0x80
889 field SCBCERR 0x40
890 field SCADERR 0x20
891 field SCDATBUCKET 0x10
892 field CNTNOTCMPLT 0x08
893 field RXOVRUN 0x04
894 field RXSCEMSG 0x02
895 field RXSPLTRSP 0x01
896}
897
898/*
899 * Data Channel Split Status 1
900 */
901register DCHSPLTSTAT1 {
902 address 0x097
903 access_mode RW
904 modes M_DFF0, M_DFF1
905 field RXDATABUCKET 0x01
906}
907
908/*
909 * CMC Split Status 1
910 */
911register CMCSPLTSTAT1 {
912 address 0x097
913 access_mode RW
914 modes M_CCHAN
915 field RXDATABUCKET 0x01
916}
917
918/*
919 * Overlay Split Status 1
920 */
921register OVLYSPLTSTAT1 {
922 address 0x097
923 access_mode RW
924 modes M_SCSI
925 field RXDATABUCKET 0x01
926}
927
928/*
929 * S/G Receive Message 0
930 */
931register SGRXMSG0 {
932 address 0x098
933 access_mode RO
934 modes M_DFF0, M_DFF1
935 field CDNUM 0xF8
936 field CFNUM 0x07
937}
938
939/*
940 * S/G Receive Message 1
941 */
942register SGRXMSG1 {
943 address 0x099
944 access_mode RO
945 modes M_DFF0, M_DFF1
946 field CBNUM 0xFF
947}
948
949/*
950 * S/G Receive Message 2
951 */
952register SGRXMSG2 {
953 address 0x09A
954 access_mode RO
955 modes M_DFF0, M_DFF1
956 field MINDEX 0xFF
957}
958
959/*
960 * S/G Receive Message 3
961 */
962register SGRXMSG3 {
963 address 0x09B
964 access_mode RO
965 modes M_DFF0, M_DFF1
966 field MCLASS 0x0F
967}
968
969/*
970 * Slave Split Out Address 0
971 */
972register SLVSPLTOUTADR0 {
973 address 0x098
974 access_mode RO
975 modes M_SCSI
976 field LOWER_ADDR 0x7F
977}
978
979/*
980 * Slave Split Out Address 1
981 */
982register SLVSPLTOUTADR1 {
983 address 0x099
984 access_mode RO
985 modes M_SCSI
986 field REQ_DNUM 0xF8
987 field REQ_FNUM 0x07
988}
989
990/*
991 * Slave Split Out Address 2
992 */
993register SLVSPLTOUTADR2 {
994 address 0x09A
995 access_mode RO
996 modes M_SCSI
997 field REQ_BNUM 0xFF
998}
999
1000/*
1001 * Slave Split Out Address 3
1002 */
1003register SLVSPLTOUTADR3 {
1004 address 0x09B
1005 access_mode RO
1006 modes M_SCSI
1007 field RLXORD 020
1008 field TAG_NUM 0x1F
1009}
1010
1011/*
1012 * SG Sequencer Byte Count
1013 */
1014register SGSEQBCNT {
1015 address 0x09C
1016 access_mode RO
1017 modes M_DFF0, M_DFF1
1018}
1019
1020/*
1021 * Slave Split Out Attribute 0
1022 */
1023register SLVSPLTOUTATTR0 {
1024 address 0x09C
1025 access_mode RO
1026 modes M_SCSI
1027 field LOWER_BCNT 0xFF
1028}
1029
1030/*
1031 * Slave Split Out Attribute 1
1032 */
1033register SLVSPLTOUTATTR1 {
1034 address 0x09D
1035 access_mode RO
1036 modes M_SCSI
1037 field CMPLT_DNUM 0xF8
1038 field CMPLT_FNUM 0x07
1039}
1040
1041/*
1042 * Slave Split Out Attribute 2
1043 */
1044register SLVSPLTOUTATTR2 {
1045 address 0x09E
1046 access_mode RO
1047 size 2
1048 modes M_SCSI
1049 field CMPLT_BNUM 0xFF
1050}
1051/*
1052 * S/G Split Status 0
1053 */
1054register SGSPLTSTAT0 {
1055 address 0x09E
1056 access_mode RW
1057 modes M_DFF0, M_DFF1
1058 field STAETERM 0x80
1059 field SCBCERR 0x40
1060 field SCADERR 0x20
1061 field SCDATBUCKET 0x10
1062 field CNTNOTCMPLT 0x08
1063 field RXOVRUN 0x04
1064 field RXSCEMSG 0x02
1065 field RXSPLTRSP 0x01
1066}
1067
1068/*
1069 * S/G Split Status 1
1070 */
1071register SGSPLTSTAT1 {
1072 address 0x09F
1073 access_mode RW
1074 modes M_DFF0, M_DFF1
1075 field RXDATABUCKET 0x01
1076}
1077
1078/*
1079 * Special Function
1080 */
1081register SFUNCT {
1082 address 0x09f
1083 access_mode RW
1084 modes M_CFG
1085 field TEST_GROUP 0xF0
1086 field TEST_NUM 0x0F
1087}
1088
1089/*
1090 * Data FIFO 0 PCI Status
1091 */
1092register DF0PCISTAT {
1093 address 0x0A0
1094 access_mode RW
1095 modes M_CFG
1096 field DPE 0x80
1097 field SSE 0x40
1098 field RMA 0x20
1099 field RTA 0x10
1100 field SCAAPERR 0x08
1101 field RDPERR 0x04
1102 field TWATERR 0x02
1103 field DPR 0x01
1104}
1105
1106/*
1107 * Data FIFO 1 PCI Status
1108 */
1109register DF1PCISTAT {
1110 address 0x0A1
1111 access_mode RW
1112 modes M_CFG
1113 field DPE 0x80
1114 field SSE 0x40
1115 field RMA 0x20
1116 field RTA 0x10
1117 field SCAAPERR 0x08
1118 field RDPERR 0x04
1119 field TWATERR 0x02
1120 field DPR 0x01
1121}
1122
1123/*
1124 * S/G PCI Status
1125 */
1126register SGPCISTAT {
1127 address 0x0A2
1128 access_mode RW
1129 modes M_CFG
1130 field DPE 0x80
1131 field SSE 0x40
1132 field RMA 0x20
1133 field RTA 0x10
1134 field SCAAPERR 0x08
1135 field RDPERR 0x04
1136 field DPR 0x01
1137}
1138
1139/*
1140 * CMC PCI Status
1141 */
1142register CMCPCISTAT {
1143 address 0x0A3
1144 access_mode RW
1145 modes M_CFG
1146 field DPE 0x80
1147 field SSE 0x40
1148 field RMA 0x20
1149 field RTA 0x10
1150 field SCAAPERR 0x08
1151 field RDPERR 0x04
1152 field TWATERR 0x02
1153 field DPR 0x01
1154}
1155
1156/*
1157 * Overlay PCI Status
1158 */
1159register OVLYPCISTAT {
1160 address 0x0A4
1161 access_mode RW
1162 modes M_CFG
1163 field DPE 0x80
1164 field SSE 0x40
1165 field RMA 0x20
1166 field RTA 0x10
1167 field SCAAPERR 0x08
1168 field RDPERR 0x04
1169 field DPR 0x01
1170}
1171
1172/*
1173 * PCI Status for MSI Master DMA Transfer
1174 */
1175register MSIPCISTAT {
1176 address 0x0A6
1177 access_mode RW
1178 modes M_CFG
1179 field SSE 0x40
1180 field RMA 0x20
1181 field RTA 0x10
1182 field CLRPENDMSI 0x08
1183 field TWATERR 0x02
1184 field DPR 0x01
1185}
1186
1187/*
1188 * PCI Status for Target
1189 */
1190register TARGPCISTAT {
1191 address 0x0A7
1192 access_mode RW
1193 modes M_CFG
1194 field DPE 0x80
1195 field SSE 0x40
1196 field STA 0x08
1197 field TWATERR 0x02
1198}
1199
1200/*
1201 * LQ Packet In
1202 * The last LQ Packet received
1203 */
1204register LQIN {
1205 address 0x020
1206 access_mode RW
1207 size 20
1208 modes M_DFF0, M_DFF1, M_SCSI
1209}
1210
1211/*
1212 * SCB Type Pointer
1213 * SCB offset for Target Mode SCB type information
1214 */
1215register TYPEPTR {
1216 address 0x020
1217 access_mode RW
1218 modes M_CFG
1219}
1220
1221/*
1222 * Queue Tag Pointer
1223 * SCB offset to the Two Byte tag identifier used for target mode.
1224 */
1225register TAGPTR {
1226 address 0x021
1227 access_mode RW
1228 modes M_CFG
1229}
1230
1231/*
1232 * Logical Unit Number Pointer
1233 * SCB offset to the LSB (little endian) of the lun field.
1234 */
1235register LUNPTR {
1236 address 0x022
1237 access_mode RW
1238 modes M_CFG
1239}
1240
1241/*
1242 * Data Length Pointer
1243 * SCB offset for the 4 byte data length field in target mode.
1244 */
1245register DATALENPTR {
1246 address 0x023
1247 access_mode RW
1248 modes M_CFG
1249}
1250
1251/*
1252 * Status Length Pointer
1253 * SCB offset to the two byte status field in target SCBs.
1254 */
1255register STATLENPTR {
1256 address 0x024
1257 access_mode RW
1258 modes M_CFG
1259}
1260
1261/*
1262 * Command Length Pointer
1263 * Scb offset for the CDB length field in initiator SCBs.
1264 */
1265register CMDLENPTR {
1266 address 0x025
1267 access_mode RW
1268 modes M_CFG
1269}
1270
1271/*
1272 * Task Attribute Pointer
1273 * Scb offset for the byte field specifying the attribute byte
1274 * to be used in command packets.
1275 */
1276register ATTRPTR {
1277 address 0x026
1278 access_mode RW
1279 modes M_CFG
1280}
1281
1282/*
1283 * Task Management Flags Pointer
1284 * Scb offset for the byte field specifying the attribute flags
1285 * byte to be used in command packets.
1286 */
1287register FLAGPTR {
1288 address 0x027
1289 access_mode RW
1290 modes M_CFG
1291}
1292
1293/*
1294 * Command Pointer
1295 * Scb offset for the first byte in the CDB for initiator SCBs.
1296 */
1297register CMDPTR {
1298 address 0x028
1299 access_mode RW
1300 modes M_CFG
1301}
1302
1303/*
1304 * Queue Next Pointer
1305 * Scb offset for the 2 byte "next scb link".
1306 */
1307register QNEXTPTR {
1308 address 0x029
1309 access_mode RW
1310 modes M_CFG
1311}
1312
1313/*
1314 * SCSI ID Pointer
1315 * Scb offset to the value to place in the SCSIID register
1316 * during target mode connections.
1317 */
1318register IDPTR {
1319 address 0x02A
1320 access_mode RW
1321 modes M_CFG
1322}
1323
1324/*
1325 * Command Aborted Byte Pointer
1326 * Offset to the SCB flags field that includes the
1327 * "SCB aborted" status bit.
1328 */
1329register ABRTBYTEPTR {
1330 address 0x02B
1331 access_mode RW
1332 modes M_CFG
1333}
1334
1335/*
1336 * Command Aborted Bit Pointer
1337 * Bit offset in the SCB flags field for "SCB aborted" status.
1338 */
1339register ABRTBITPTR {
1340 address 0x02C
1341 access_mode RW
1342 modes M_CFG
1343}
1344
1345/*
1346 * Rev B or greater.
1347 */
1348register MAXCMDBYTES {
1349 address 0x02D
1350 access_mode RW
1351 modes M_CFG
1352}
1353
1354/*
1355 * Rev B or greater.
1356 */
1357register MAXCMD2RCV {
1358 address 0x02E
1359 access_mode RW
1360 modes M_CFG
1361}
1362
1363/*
1364 * Rev B or greater.
1365 */
1366register SHORTTHRESH {
1367 address 0x02F
1368 access_mode RW
1369 modes M_CFG
1370}
1371
1372/*
1373 * Logical Unit Number Length
1374 * The length, in bytes, of the SCB lun field.
1375 */
1376register LUNLEN {
1377 address 0x030
1378 access_mode RW
1379 modes M_CFG
1380 mask ILUNLEN 0x0F
1381 mask TLUNLEN 0xF0
1382}
1383const LUNLEN_SINGLE_LEVEL_LUN 0xF
1384
1385/*
1386 * CDB Limit
1387 * The size, in bytes, of the embedded CDB field in initator SCBs.
1388 */
1389register CDBLIMIT {
1390 address 0x031
1391 access_mode RW
1392 modes M_CFG
1393}
1394
1395/*
1396 * Maximum Commands
1397 * The maximum number of commands to issue during a
1398 * single packetized connection.
1399 */
1400register MAXCMD {
1401 address 0x032
1402 access_mode RW
1403 modes M_CFG
1404}
1405
1406/*
1407 * Maximum Command Counter
1408 * The number of commands already sent during this connection
1409 */
1410register MAXCMDCNT {
1411 address 0x033
1412 access_mode RW
1413 modes M_CFG
1414}
1415
1416/*
1417 * LQ Packet Reserved Bytes
1418 * The bytes to be sent in the currently reserved fileds
1419 * of all LQ packets.
1420 */
1421register LQRSVD01 {
1422 address 0x034
1423 access_mode RW
1424 modes M_SCSI
1425}
1426register LQRSVD16 {
1427 address 0x035
1428 access_mode RW
1429 modes M_SCSI
1430}
1431register LQRSVD17 {
1432 address 0x036
1433 access_mode RW
1434 modes M_SCSI
1435}
1436
1437/*
1438 * Command Reserved 0
1439 * The byte to be sent for the reserved byte 0 of
1440 * outgoing command packets.
1441 */
1442register CMDRSVD0 {
1443 address 0x037
1444 access_mode RW
1445 modes M_CFG
1446}
1447
1448/*
1449 * LQ Manager Control 0
1450 */
1451register LQCTL0 {
1452 address 0x038
1453 access_mode RW
1454 modes M_CFG
1455 field LQITARGCLT 0xC0
1456 field LQIINITGCLT 0x30
1457 field LQ0TARGCLT 0x0C
1458 field LQ0INITGCLT 0x03
1459}
1460
1461/*
1462 * LQ Manager Control 1
1463 */
1464register LQCTL1 {
1465 address 0x038
1466 access_mode RW
1467 modes M_DFF0, M_DFF1, M_SCSI
1468 field PCI2PCI 0x04
1469 field SINGLECMD 0x02
1470 field ABORTPENDING 0x01
1471}
1472
1473/*
1474 * LQ Manager Control 2
1475 */
1476register LQCTL2 {
1477 address 0x039
1478 access_mode RW
1479 modes M_DFF0, M_DFF1, M_SCSI
1480 field LQIRETRY 0x80
1481 field LQICONTINUE 0x40
1482 field LQITOIDLE 0x20
1483 field LQIPAUSE 0x10
1484 field LQORETRY 0x08
1485 field LQOCONTINUE 0x04
1486 field LQOTOIDLE 0x02
1487 field LQOPAUSE 0x01
1488}
1489
1490/*
1491 * SCSI RAM BIST0
1492 */
1493register SCSBIST0 {
1494 address 0x039
1495 access_mode RW
1496 modes M_CFG
1497 field GSBISTERR 0x40
1498 field GSBISTDONE 0x20
1499 field GSBISTRUN 0x10
1500 field OSBISTERR 0x04
1501 field OSBISTDONE 0x02
1502 field OSBISTRUN 0x01
1503}
1504
1505/*
1506 * SCSI Sequence Control0
1507 */
1508register SCSISEQ0 {
1509 address 0x03A
1510 access_mode RW
1511 modes M_DFF0, M_DFF1, M_SCSI
1512 field TEMODEO 0x80
1513 field ENSELO 0x40
1514 field ENARBO 0x20
1515 field FORCEBUSFREE 0x10
1516 field SCSIRSTO 0x01
1517}
1518
1519/*
1520 * SCSI RAM BIST 1
1521 */
1522register SCSBIST1 {
1523 address 0x03A
1524 access_mode RW
1525 modes M_CFG
1526 field NTBISTERR 0x04
1527 field NTBISTDONE 0x02
1528 field NTBISTRUN 0x01
1529}
1530
1531/*
1532 * SCSI Sequence Control 1
1533 */
1534register SCSISEQ1 {
1535 address 0x03B
1536 access_mode RW
1537 modes M_DFF0, M_DFF1, M_SCSI
1538 field MANUALCTL 0x40
1539 field ENSELI 0x20
1540 field ENRSELI 0x10
1541 field MANUALP 0x0C
1542 field ENAUTOATNP 0x02
1543 field ALTSTIM 0x01
1544}
1545
1546/*
1547 * SCSI Transfer Control 0
1548 */
1549register SXFRCTL0 {
1550 address 0x03C
1551 access_mode RW
1552 modes M_SCSI
1553 field DFON 0x80
1554 field DFPEXP 0x40
1555 field BIOSCANCELEN 0x10
1556 field SPIOEN 0x08
1557}
1558
1559/*
1560 * SCSI Transfer Control 1
1561 */
1562register SXFRCTL1 {
1563 address 0x03D
1564 access_mode RW
1565 modes M_SCSI
1566 field BITBUCKET 0x80
1567 field ENSACHK 0x40
1568 field ENSPCHK 0x20
1569 field STIMESEL 0x18
1570 field ENSTIMER 0x04
1571 field ACTNEGEN 0x02
1572 field STPWEN 0x01
1573}
1574
1575/*
1576 * SCSI Transfer Control 2
1577 */
1578register SXFRCTL2 {
1579 address 0x03E
1580 access_mode RW
1581 modes M_SCSI
1582 field AUTORSTDIS 0x10
1583 field CMDDMAEN 0x08
1584 field ASU 0x07
1585}
1586
1587/*
1588 * SCSI Bus Initiator IDs
1589 * Bitmask of observed initiators on the bus.
1590 */
1591register BUSINITID {
1592 address 0x03C
1593 access_mode RW
1594 modes M_CFG
1595 size 2
1596}
1597
1598/*
1599 * Data Length Counters
1600 * Packet byte counter.
1601 */
1602register DLCOUNT {
1603 address 0x03C
1604 access_mode RW
1605 modes M_DFF0, M_DFF1
1606 size 3
1607}
1608
1609/*
1610 * Data FIFO Status
1611 */
1612register DFFSTAT {
1613 address 0x03F
1614 access_mode RW
1615 modes M_SCSI
1616 field FIFO1FREE 0x20
1617 field FIFO0FREE 0x10
1618 /*
1619 * On the B, this enum only works
1620 * in the read direction. For writes,
1621 * you must use the B version of the
1622 * CURRFIFO_0 definition which is defined
1623 * as a constant outside of this register
1624 * definition to avoid confusing the
1625 * register pretty printing code.
1626 */
1627 enum CURRFIFO 0x03 {
1628 CURRFIFO_0,
1629 CURRFIFO_1,
1630 CURRFIFO_NONE 0x3
1631 }
1632}
1633
1634const B_CURRFIFO_0 0x2
1635
1636/*
1637 * SCSI Bus Target IDs
1638 * Bitmask of observed targets on the bus.
1639 */
1640register BUSTARGID {
1641 address 0x03E
1642 access_mode RW
1643 modes M_CFG
1644 size 2
1645}
1646
1647/*
1648 * SCSI Control Signal Out
1649 */
1650register SCSISIGO {
1651 address 0x040
1652 access_mode RW
1653 modes M_DFF0, M_DFF1, M_SCSI
1654 field CDO 0x80
1655 field IOO 0x40
1656 field MSGO 0x20
1657 field ATNO 0x10
1658 field SELO 0x08
1659 field BSYO 0x04
1660 field REQO 0x02
1661 field ACKO 0x01
1662/*
1663 * Possible phases to write into SCSISIG0
1664 */
1665 enum PHASE_MASK CDO|IOO|MSGO {
1666 P_DATAOUT 0x0,
1667 P_DATAIN IOO,
1668 P_DATAOUT_DT P_DATAOUT|MSGO,
1669 P_DATAIN_DT P_DATAIN|MSGO,
1670 P_COMMAND CDO,
1671 P_MESGOUT CDO|MSGO,
1672 P_STATUS CDO|IOO,
1673 P_MESGIN CDO|IOO|MSGO
1674 }
1675}
1676
1677register SCSISIGI {
1678 address 0x041
1679 access_mode RO
1680 modes M_DFF0, M_DFF1, M_SCSI
1681 field CDI 0x80
1682 field IOI 0x40
1683 field MSGI 0x20
1684 field ATNI 0x10
1685 field SELI 0x08
1686 field BSYI 0x04
1687 field REQI 0x02
1688 field ACKI 0x01
1689/*
1690 * Possible phases in SCSISIGI
1691 */
1692 enum PHASE_MASK CDO|IOO|MSGO {
1693 P_DATAOUT 0x0,
1694 P_DATAIN IOO,
1695 P_DATAOUT_DT P_DATAOUT|MSGO,
1696 P_DATAIN_DT P_DATAIN|MSGO,
1697 P_COMMAND CDO,
1698 P_MESGOUT CDO|MSGO,
1699 P_STATUS CDO|IOO,
1700 P_MESGIN CDO|IOO|MSGO
1701 }
1702}
1703
1704/*
1705 * Multiple Target IDs
1706 * Bitmask of ids to respond as a target.
1707 */
1708register MULTARGID {
1709 address 0x040
1710 access_mode RW
1711 modes M_CFG
1712 size 2
1713}
1714
1715/*
1716 * SCSI Phase
1717 */
1718register SCSIPHASE {
1719 address 0x042
1720 access_mode RO
1721 modes M_DFF0, M_DFF1, M_SCSI
1722 field STATUS_PHASE 0x20
1723 field COMMAND_PHASE 0x10
1724 field MSG_IN_PHASE 0x08
1725 field MSG_OUT_PHASE 0x04
1726 field DATA_PHASE_MASK 0x03 {
1727 DATA_OUT_PHASE 0x01,
1728 DATA_IN_PHASE 0x02
1729 }
1730}
1731
1732/*
1733 * SCSI Data 0 Image
1734 */
1735register SCSIDAT0_IMG {
1736 address 0x043
1737 access_mode RW
1738 modes M_DFF0, M_DFF1, M_SCSI
1739}
1740
1741/*
1742 * SCSI Latched Data
1743 */
1744register SCSIDAT {
1745 address 0x044
1746 access_mode RW
1747 modes M_DFF0, M_DFF1, M_SCSI
1748 size 2
1749}
1750
1751/*
1752 * SCSI Data Bus
1753 */
1754register SCSIBUS {
1755 address 0x046
1756 access_mode RW
1757 modes M_DFF0, M_DFF1, M_SCSI
1758 size 2
1759}
1760
1761/*
1762 * Target ID In
1763 */
1764register TARGIDIN {
1765 address 0x048
1766 access_mode RO
1767 modes M_DFF0, M_DFF1, M_SCSI
1768 field CLKOUT 0x80
1769 field TARGID 0x0F
1770}
1771
1772/*
1773 * Selection/Reselection ID
1774 * Upper four bits are the device id. The ONEBIT is set when the re/selecting
1775 * device did not set its own ID.
1776 */
1777register SELID {
1778 address 0x049
1779 access_mode RW
1780 modes M_DFF0, M_DFF1, M_SCSI
1781 field SELID_MASK 0xf0
1782 field ONEBIT 0x08
1783}
1784
1785/*
1786 * SCSI Block Control
1787 * Controls Bus type and channel selection. SELWIDE allows for the
1788 * coexistence of 8bit and 16bit devices on a wide bus.
1789 */
1790register SBLKCTL {
1791 address 0x04A
1792 access_mode RW
1793 modes M_DFF0, M_DFF1, M_SCSI
1794 field DIAGLEDEN 0x80
1795 field DIAGLEDON 0x40
1796 field ENAB40 0x08 /* LVD transceiver active */
1797 field ENAB20 0x04 /* SE/HVD transceiver active */
1798 field SELWIDE 0x02
1799}
1800
1801/*
1802 * Option Mode
1803 */
1804register OPTIONMODE {
1805 address 0x04A
1806 access_mode RW
1807 modes M_CFG
1808 field BIOSCANCTL 0x80
1809 field AUTOACKEN 0x40
1810 field BIASCANCTL 0x20
1811 field BUSFREEREV 0x10
1812 field ENDGFORMCHK 0x04
1813 field AUTO_MSGOUT_DE 0x02
1814 mask OPTIONMODE_DEFAULTS AUTO_MSGOUT_DE
1815}
1816
1817/*
1818 * SCSI Status 0
1819 */
1820register SSTAT0 {
1821 address 0x04B
1822 access_mode RO
1823 modes M_DFF0, M_DFF1, M_SCSI
1824 field TARGET 0x80 /* Board acting as target */
1825 field SELDO 0x40 /* Selection Done */
1826 field SELDI 0x20 /* Board has been selected */
1827 field SELINGO 0x10 /* Selection In Progress */
1828 field IOERR 0x08 /* LVD Tranceiver mode changed */
1829 field OVERRUN 0x04 /* SCSI Offset overrun detected */
1830 field SPIORDY 0x02 /* SCSI PIO Ready */
1831 field ARBDO 0x01 /* Arbitration Done Out */
1832}
1833
1834/*
1835 * Clear SCSI Interrupt 0
1836 * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT0.
1837 */
1838register CLRSINT0 {
1839 address 0x04B
1840 access_mode WO
1841 modes M_DFF0, M_DFF1, M_SCSI
1842 field CLRSELDO 0x40
1843 field CLRSELDI 0x20
1844 field CLRSELINGO 0x10
1845 field CLRIOERR 0x08
1846 field CLROVERRUN 0x04
1847 field CLRSPIORDY 0x02
1848 field CLRARBDO 0x01
1849}
1850
1851/*
1852 * SCSI Interrupt Mode 0
1853 * Setting any bit will enable the corresponding function
1854 * in SIMODE0 to interrupt via the IRQ pin.
1855 */
1856register SIMODE0 {
1857 address 0x04B
1858 access_mode RW
1859 modes M_CFG
1860 field ENSELDO 0x40
1861 field ENSELDI 0x20
1862 field ENSELINGO 0x10
1863 field ENIOERR 0x08
1864 field ENOVERRUN 0x04
1865 field ENSPIORDY 0x02
1866 field ENARBDO 0x01
1867}
1868
1869/*
1870 * SCSI Status 1
1871 */
1872register SSTAT1 {
1873 address 0x04C
1874 access_mode RO
1875 modes M_DFF0, M_DFF1, M_SCSI
1876 field SELTO 0x80
1877 field ATNTARG 0x40
1878 field SCSIRSTI 0x20
1879 field PHASEMIS 0x10
1880 field BUSFREE 0x08
1881 field SCSIPERR 0x04
1882 field STRB2FAST 0x02
1883 field REQINIT 0x01
1884}
1885
1886/*
1887 * Clear SCSI Interrupt 1
1888 * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT1.
1889 */
1890register CLRSINT1 {
1891 address 0x04C
1892 access_mode WO
1893 modes M_DFF0, M_DFF1, M_SCSI
1894 field CLRSELTIMEO 0x80
1895 field CLRATNO 0x40
1896 field CLRSCSIRSTI 0x20
1897 field CLRBUSFREE 0x08
1898 field CLRSCSIPERR 0x04
1899 field CLRSTRB2FAST 0x02
1900 field CLRREQINIT 0x01
1901}
1902
1903/*
1904 * SCSI Status 2
1905 */
1906register SSTAT2 {
1907 address 0x04d
1908 access_mode RO
1909 modes M_DFF0, M_DFF1, M_SCSI
1910 field BUSFREETIME 0xc0 {
1911 BUSFREE_LQO 0x40,
1912 BUSFREE_DFF0 0x80,
1913 BUSFREE_DFF1 0xC0
1914 }
1915 field NONPACKREQ 0x20
1916 field EXP_ACTIVE 0x10 /* SCSI Expander Active */
1917 field BSYX 0x08 /* Busy Expander */
1918 field WIDE_RES 0x04 /* Modes 0 and 1 only */
1919 field SDONE 0x02 /* Modes 0 and 1 only */
1920 field DMADONE 0x01 /* Modes 0 and 1 only */
1921}
1922
1923/*
1924 * Clear SCSI Interrupt 2
1925 */
1926register CLRSINT2 {
1927 address 0x04D
1928 access_mode WO
1929 modes M_DFF0, M_DFF1, M_SCSI
1930 field CLRNONPACKREQ 0x20
1931 field CLRWIDE_RES 0x04 /* Modes 0 and 1 only */
1932 field CLRSDONE 0x02 /* Modes 0 and 1 only */
1933 field CLRDMADONE 0x01 /* Modes 0 and 1 only */
1934}
1935
1936/*
1937 * SCSI Interrupt Mode 2
1938 */
1939register SIMODE2 {
1940 address 0x04D
1941 access_mode RW
1942 modes M_CFG
1943 field ENWIDE_RES 0x04
1944 field ENSDONE 0x02
1945 field ENDMADONE 0x01
1946}
1947
1948/*
1949 * Physical Error Diagnosis
1950 */
1951register PERRDIAG {
1952 address 0x04E
1953 access_mode RO
1954 modes M_DFF0, M_DFF1, M_SCSI
1955 field HIZERO 0x80
1956 field HIPERR 0x40
1957 field PREVPHASE 0x20
1958 field PARITYERR 0x10
1959 field AIPERR 0x08
1960 field CRCERR 0x04
1961 field DGFORMERR 0x02
1962 field DTERR 0x01
1963}
1964
1965/*
1966 * LQI Manager Current State
1967 */
1968register LQISTATE {
1969 address 0x04E
1970 access_mode RO
1971 modes M_CFG
1972}
1973
1974/*
1975 * SCSI Offset Count
1976 */
1977register SOFFCNT {
1978 address 0x04F
1979 access_mode RO
1980 modes M_DFF0, M_DFF1, M_SCSI
1981}
1982
1983/*
1984 * LQO Manager Current State
1985 */
1986register LQOSTATE {
1987 address 0x04F
1988 access_mode RO
1989 modes M_CFG
1990}
1991
1992/*
1993 * LQI Manager Status
1994 */
1995register LQISTAT0 {
1996 address 0x050
1997 access_mode RO
1998 modes M_DFF0, M_DFF1, M_SCSI
1999 field LQIATNQAS 0x20
2000 field LQICRCT1 0x10
2001 field LQICRCT2 0x08
2002 field LQIBADLQT 0x04
2003 field LQIATNLQ 0x02
2004 field LQIATNCMD 0x01
2005}
2006
2007/*
2008 * Clear LQI Interrupts 0
2009 */
2010register CLRLQIINT0 {
2011 address 0x050
2012 access_mode WO
2013 modes M_DFF0, M_DFF1, M_SCSI
2014 field CLRLQIATNQAS 0x20
2015 field CLRLQICRCT1 0x10
2016 field CLRLQICRCT2 0x08
2017 field CLRLQIBADLQT 0x04
2018 field CLRLQIATNLQ 0x02
2019 field CLRLQIATNCMD 0x01
2020}
2021
2022/*
2023 * LQI Manager Interrupt Mode 0
2024 */
2025register LQIMODE0 {
2026 address 0x050
2027 access_mode RW
2028 modes M_CFG
2029 field ENLQIATNQASK 0x20
2030 field ENLQICRCT1 0x10
2031 field ENLQICRCT2 0x08
2032 field ENLQIBADLQT 0x04
2033 field ENLQIATNLQ 0x02
2034 field ENLQIATNCMD 0x01
2035}
2036
2037/*
2038 * LQI Manager Status 1
2039 */
2040register LQISTAT1 {
2041 address 0x051
2042 access_mode RO
2043 modes M_DFF0, M_DFF1, M_SCSI
2044 field LQIPHASE_LQ 0x80
2045 field LQIPHASE_NLQ 0x40
2046 field LQIABORT 0x20
2047 field LQICRCI_LQ 0x10
2048 field LQICRCI_NLQ 0x08
2049 field LQIBADLQI 0x04
2050 field LQIOVERI_LQ 0x02
2051 field LQIOVERI_NLQ 0x01
2052}
2053
2054/*
2055 * Clear LQI Manager Interrupts1
2056 */
2057register CLRLQIINT1 {
2058 address 0x051
2059 access_mode WO
2060 modes M_DFF0, M_DFF1, M_SCSI
2061 field CLRLQIPHASE_LQ 0x80
2062 field CLRLQIPHASE_NLQ 0x40
2063 field CLRLIQABORT 0x20
2064 field CLRLQICRCI_LQ 0x10
2065 field CLRLQICRCI_NLQ 0x08
2066 field CLRLQIBADLQI 0x04
2067 field CLRLQIOVERI_LQ 0x02
2068 field CLRLQIOVERI_NLQ 0x01
2069}
2070
2071/*
2072 * LQI Manager Interrupt Mode 1
2073 */
2074register LQIMODE1 {
2075 address 0x051
2076 access_mode RW
2077 modes M_CFG
2078 field ENLQIPHASE_LQ 0x80 /* LQIPHASE1 */
2079 field ENLQIPHASE_NLQ 0x40 /* LQIPHASE2 */
2080 field ENLIQABORT 0x20
2081 field ENLQICRCI_LQ 0x10 /* LQICRCI1 */
2082 field ENLQICRCI_NLQ 0x08 /* LQICRCI2 */
2083 field ENLQIBADLQI 0x04
2084 field ENLQIOVERI_LQ 0x02 /* LQIOVERI1 */
2085 field ENLQIOVERI_NLQ 0x01 /* LQIOVERI2 */
2086}
2087
2088/*
2089 * LQI Manager Status 2
2090 */
2091register LQISTAT2 {
2092 address 0x052
2093 access_mode RO
2094 modes M_DFF0, M_DFF1, M_SCSI
2095 field PACKETIZED 0x80
2096 field LQIPHASE_OUTPKT 0x40
2097 field LQIWORKONLQ 0x20
2098 field LQIWAITFIFO 0x10
2099 field LQISTOPPKT 0x08
2100 field LQISTOPLQ 0x04
2101 field LQISTOPCMD 0x02
2102 field LQIGSAVAIL 0x01
2103}
2104
2105/*
2106 * SCSI Status 3
2107 */
2108register SSTAT3 {
2109 address 0x053
2110 access_mode RO
2111 modes M_DFF0, M_DFF1, M_SCSI
2112 field NTRAMPERR 0x02
2113 field OSRAMPERR 0x01
2114}
2115
2116/*
2117 * Clear SCSI Status 3
2118 */
2119register CLRSINT3 {
2120 address 0x053
2121 access_mode WO
2122 modes M_DFF0, M_DFF1, M_SCSI
2123 field CLRNTRAMPERR 0x02
2124 field CLROSRAMPERR 0x01
2125}
2126
2127/*
2128 * SCSI Interrupt Mode 3
2129 */
2130register SIMODE3 {
2131 address 0x053
2132 access_mode RW
2133 modes M_CFG
2134 field ENNTRAMPERR 0x02
2135 field ENOSRAMPERR 0x01
2136}
2137
2138/*
2139 * LQO Manager Status 0
2140 */
2141register LQOSTAT0 {
2142 address 0x054
2143 access_mode RO
2144 modes M_DFF0, M_DFF1, M_SCSI
2145 field LQOTARGSCBPERR 0x10
2146 field LQOSTOPT2 0x08
2147 field LQOATNLQ 0x04
2148 field LQOATNPKT 0x02
2149 field LQOTCRC 0x01
2150}
2151
2152/*
2153 * Clear LQO Manager interrupt 0
2154 */
2155register CLRLQOINT0 {
2156 address 0x054
2157 access_mode WO
2158 modes M_DFF0, M_DFF1, M_SCSI
2159 field CLRLQOTARGSCBPERR 0x10
2160 field CLRLQOSTOPT2 0x08
2161 field CLRLQOATNLQ 0x04
2162 field CLRLQOATNPKT 0x02
2163 field CLRLQOTCRC 0x01
2164}
2165
2166/*
2167 * LQO Manager Interrupt Mode 0
2168 */
2169register LQOMODE0 {
2170 address 0x054
2171 access_mode RW
2172 modes M_CFG
2173 field ENLQOTARGSCBPERR 0x10
2174 field ENLQOSTOPT2 0x08
2175 field ENLQOATNLQ 0x04
2176 field ENLQOATNPKT 0x02
2177 field ENLQOTCRC 0x01
2178}
2179
2180/*
2181 * LQO Manager Status 1
2182 */
2183register LQOSTAT1 {
2184 address 0x055
2185 access_mode RO
2186 modes M_DFF0, M_DFF1, M_SCSI
2187 field LQOINITSCBPERR 0x10
2188 field LQOSTOPI2 0x08
2189 field LQOBADQAS 0x04
2190 field LQOBUSFREE 0x02
2191 field LQOPHACHGINPKT 0x01
2192}
2193
2194/*
2195 * Clear LOQ Interrupt 1
2196 */
2197register CLRLQOINT1 {
2198 address 0x055
2199 access_mode WO
2200 modes M_DFF0, M_DFF1, M_SCSI
2201 field CLRLQOINITSCBPERR 0x10
2202 field CLRLQOSTOPI2 0x08
2203 field CLRLQOBADQAS 0x04
2204 field CLRLQOBUSFREE 0x02
2205 field CLRLQOPHACHGINPKT 0x01
2206}
2207
2208/*
2209 * LQO Manager Interrupt Mode 1
2210 */
2211register LQOMODE1 {
2212 address 0x055
2213 access_mode RW
2214 modes M_CFG
2215 field ENLQOINITSCBPERR 0x10
2216 field ENLQOSTOPI2 0x08
2217 field ENLQOBADQAS 0x04
2218 field ENLQOBUSFREE 0x02
2219 field ENLQOPHACHGINPKT 0x01
2220}
2221
2222/*
2223 * LQO Manager Status 2
2224 */
2225register LQOSTAT2 {
2226 address 0x056
2227 access_mode RO
2228 modes M_DFF0, M_DFF1, M_SCSI
2229 field LQOPKT 0xE0
2230 field LQOWAITFIFO 0x10
2231 field LQOPHACHGOUTPKT 0x02 /* outside of packet boundaries. */
2232 field LQOSTOP0 0x01 /* Stopped after sending all packets */
2233}
2234
2235/*
2236 * Output Synchronizer Space Count
2237 */
2238register OS_SPACE_CNT {
2239 address 0x056
2240 access_mode RO
2241 modes M_CFG
2242}
2243
2244/*
2245 * SCSI Interrupt Mode 1
2246 * Setting any bit will enable the corresponding function
2247 * in SIMODE1 to interrupt via the IRQ pin.
2248 */
2249register SIMODE1 {
2250 address 0x057
2251 access_mode RW
2252 modes M_DFF0, M_DFF1, M_SCSI
2253 field ENSELTIMO 0x80
2254 field ENATNTARG 0x40
2255 field ENSCSIRST 0x20
2256 field ENPHASEMIS 0x10
2257 field ENBUSFREE 0x08
2258 field ENSCSIPERR 0x04
2259 field ENSTRB2FAST 0x02
2260 field ENREQINIT 0x01
2261}
2262
2263/*
2264 * Good Status FIFO
2265 */
2266register GSFIFO {
2267 address 0x058
2268 access_mode RO
2269 size 2
2270 modes M_DFF0, M_DFF1, M_SCSI
2271}
2272
2273/*
2274 * Data FIFO SCSI Transfer Control
2275 */
2276register DFFSXFRCTL {
2277 address 0x05A
2278 access_mode RW
2279 modes M_DFF0, M_DFF1
2280 field DFFBITBUCKET 0x08
2281 field CLRSHCNT 0x04
2282 field CLRCHN 0x02
2283 field RSTCHN 0x01
2284}
2285
2286/*
2287 * Next SCSI Control Block
2288 */
2289register NEXTSCB {
2290 address 0x05A
2291 access_mode RW
2292 size 2
2293 modes M_SCSI
2294}
2295
2296/* Rev B only. */
2297register LQOSCSCTL {
2298 address 0x05A
2299 access_mode RW
2300 size 1
2301 modes M_CFG
2302 field LQOH2A_VERSION 0x80
2303 field LQONOCHKOVER 0x01
2304}
2305
2306/*
2307 * SEQ Interrupts
2308 */
2309register SEQINTSRC {
2310 address 0x05B
2311 access_mode RO
2312 modes M_DFF0, M_DFF1
2313 field CTXTDONE 0x40
2314 field SAVEPTRS 0x20
2315 field CFG4DATA 0x10
2316 field CFG4ISTAT 0x08
2317 field CFG4TSTAT 0x04
2318 field CFG4ICMD 0x02
2319 field CFG4TCMD 0x01
2320}
2321
2322/*
2323 * Clear Arp Interrupts
2324 */
2325register CLRSEQINTSRC {
2326 address 0x05B
2327 access_mode WO
2328 modes M_DFF0, M_DFF1
2329 field CLRCTXTDONE 0x40
2330 field CLRSAVEPTRS 0x20
2331 field CLRCFG4DATA 0x10
2332 field CLRCFG4ISTAT 0x08
2333 field CLRCFG4TSTAT 0x04
2334 field CLRCFG4ICMD 0x02
2335 field CLRCFG4TCMD 0x01
2336}
2337
2338/*
2339 * SEQ Interrupt Enabled (Shared)
2340 */
2341register SEQIMODE {
2342 address 0x05C
2343 access_mode RW
2344 modes M_DFF0, M_DFF1
2345 field ENCTXTDONE 0x40
2346 field ENSAVEPTRS 0x20
2347 field ENCFG4DATA 0x10
2348 field ENCFG4ISTAT 0x08
2349 field ENCFG4TSTAT 0x04
2350 field ENCFG4ICMD 0x02
2351 field ENCFG4TCMD 0x01
2352}
2353
2354/*
2355 * Current SCSI Control Block
2356 */
2357register CURRSCB {
2358 address 0x05C
2359 access_mode RW
2360 size 2
2361 modes M_SCSI
2362}
2363
2364/*
2365 * Data FIFO Status
2366 */
2367register MDFFSTAT {
2368 address 0x05D
2369 access_mode RO
2370 modes M_DFF0, M_DFF1
2371 field SHCNTNEGATIVE 0x40 /* Rev B or higher */
2372 field SHCNTMINUS1 0x20 /* Rev B or higher */
2373 field LASTSDONE 0x10
2374 field SHVALID 0x08
2375 field DLZERO 0x04 /* FIFO data ends on packet boundary. */
2376 field DATAINFIFO 0x02
2377 field FIFOFREE 0x01
2378}
2379
2380/*
2381 * CRC Control
2382 */
2383register CRCCONTROL {
2384 address 0x05d
2385 access_mode RW
2386 modes M_CFG
2387 field CRCVALCHKEN 0x40
2388}
2389
2390/*
2391 * SCSI Test Control
2392 */
2393register SCSITEST {
2394 address 0x05E
2395 access_mode RW
2396 modes M_CFG
2397 field CNTRTEST 0x08
2398 field SEL_TXPLL_DEBUG 0x04
2399}
2400
2401/*
2402 * Data FIFO Queue Tag
2403 */
2404register DFFTAG {
2405 address 0x05E
2406 access_mode RW
2407 size 2
2408 modes M_DFF0, M_DFF1
2409}
2410
2411/*
2412 * Last SCSI Control Block
2413 */
2414register LASTSCB {
2415 address 0x05E
2416 access_mode RW
2417 size 2
2418 modes M_SCSI
2419}
2420
2421/*
2422 * SCSI I/O Cell Power-down Control
2423 */
2424register IOPDNCTL {
2425 address 0x05F
2426 access_mode RW
2427 modes M_CFG
2428 field DISABLE_OE 0x80
2429 field PDN_IDIST 0x04
2430 field PDN_DIFFSENSE 0x01
2431}
2432
2433/*
2434 * Shaddow Host Address.
2435 */
2436register SHADDR {
2437 address 0x060
2438 access_mode RO
2439 size 8
2440 modes M_DFF0, M_DFF1
2441}
2442
2443/*
2444 * Data Group CRC Interval.
2445 */
2446register DGRPCRCI {
2447 address 0x060
2448 access_mode RW
2449 size 2
2450 modes M_CFG
2451}
2452
2453/*
2454 * Data Transfer Negotiation Address
2455 */
2456register NEGOADDR {
2457 address 0x060
2458 access_mode RW
2459 modes M_SCSI
2460}
2461
2462/*
2463 * Data Transfer Negotiation Data - Period Byte
2464 */
2465register NEGPERIOD {
2466 address 0x061
2467 access_mode RW
2468 modes M_SCSI
2469}
2470
2471/*
2472 * Packetized CRC Interval
2473 */
2474register PACKCRCI {
2475 address 0x062
2476 access_mode RW
2477 size 2
2478 modes M_CFG
2479}
2480
2481/*
2482 * Data Transfer Negotiation Data - Offset Byte
2483 */
2484register NEGOFFSET {
2485 address 0x062
2486 access_mode RW
2487 modes M_SCSI
2488}
2489
2490/*
2491 * Data Transfer Negotiation Data - PPR Options
2492 */
2493register NEGPPROPTS {
2494 address 0x063
2495 access_mode RW
2496 modes M_SCSI
2497 field PPROPT_PACE 0x08
2498 field PPROPT_QAS 0x04
2499 field PPROPT_DT 0x02
2500 field PPROPT_IUT 0x01
2501}
2502
2503/*
2504 * Data Transfer Negotiation Data - Connection Options
2505 */
2506register NEGCONOPTS {
2507 address 0x064
2508 access_mode RW
2509 modes M_SCSI
2510 field ENSNAPSHOT 0x40
2511 field RTI_WRTDIS 0x20
2512 field RTI_OVRDTRN 0x10
2513 field ENSLOWCRC 0x08
2514 field ENAUTOATNI 0x04
2515 field ENAUTOATNO 0x02
2516 field WIDEXFER 0x01
2517}
2518
2519/*
2520 * Negotiation Table Annex Column Index.
2521 */
2522register ANNEXCOL {
2523 address 0x065
2524 access_mode RW
2525 modes M_SCSI
2526}
2527
2528register SCSCHKN {
2529 address 0x066
2530 access_mode RW
2531 modes M_CFG
2532 field STSELSKIDDIS 0x40
2533 field CURRFIFODEF 0x20
2534 field WIDERESEN 0x10
2535 field SDONEMSKDIS 0x08
2536 field DFFACTCLR 0x04
2537 field SHVALIDSTDIS 0x02
2538 field LSTSGCLRDIS 0x01
2539}
2540
2541const AHD_ANNEXCOL_PER_DEV0 4
2542const AHD_NUM_PER_DEV_ANNEXCOLS 4
2543const AHD_ANNEXCOL_PRECOMP_SLEW 4
2544const AHD_PRECOMP_MASK 0x07
2545const AHD_PRECOMP_SHIFT 0
2546const AHD_PRECOMP_CUTBACK_17 0x04
2547const AHD_PRECOMP_CUTBACK_29 0x06
2548const AHD_PRECOMP_CUTBACK_37 0x07
2549const AHD_SLEWRATE_MASK 0x78
2550const AHD_SLEWRATE_SHIFT 3
2551/*
2552 * Rev A has only a single bit (high bit of field) of slew adjustment.
2553 * Rev B has 4 bits. The current default happens to be the same for both.
2554 */
2555const AHD_SLEWRATE_DEF_REVA 0x08
2556const AHD_SLEWRATE_DEF_REVB 0x08
2557
2558/* Rev A does not have any amplitude setting. */
2559const AHD_ANNEXCOL_AMPLITUDE 6
2560const AHD_AMPLITUDE_MASK 0x7
2561const AHD_AMPLITUDE_SHIFT 0
2562const AHD_AMPLITUDE_DEF 0x7
2563
2564/*
2565 * Negotiation Table Annex Data Port.
2566 */
2567register ANNEXDAT {
2568 address 0x066
2569 access_mode RW
2570 modes M_SCSI
2571}
2572
2573/*
2574 * Initiator's Own Id.
2575 * The SCSI ID to use for Selection Out and seen during a reselection..
2576 */
2577register IOWNID {
2578 address 0x067
2579 access_mode RW
2580 modes M_SCSI
2581}
2582
2583/*
2584 * 960MHz Phase-Locked Loop Control 0
2585 */
2586register PLL960CTL0 {
2587 address 0x068
2588 access_mode RW
2589 modes M_CFG
2590 field PLL_VCOSEL 0x80
2591 field PLL_PWDN 0x40
2592 field PLL_NS 0x30
2593 field PLL_ENLUD 0x08
2594 field PLL_ENLPF 0x04
2595 field PLL_DLPF 0x02
2596 field PLL_ENFBM 0x01
2597}
2598
2599/*
2600 * Target Own Id
2601 */
2602register TOWNID {
2603 address 0x069
2604 access_mode RW
2605 modes M_SCSI
2606}
2607
2608/*
2609 * 960MHz Phase-Locked Loop Control 1
2610 */
2611register PLL960CTL1 {
2612 address 0x069
2613 access_mode RW
2614 modes M_CFG
2615 field PLL_CNTEN 0x80
2616 field PLL_CNTCLR 0x40
2617 field PLL_RST 0x01
2618}
2619
2620/*
2621 * Expander Signature
2622 */
2623register XSIG {
2624 address 0x06A
2625 access_mode RW
2626 modes M_SCSI
2627}
2628
2629/*
2630 * Shadow Byte Count
2631 */
2632register SHCNT {
2633 address 0x068
2634 access_mode RW
2635 size 3
2636 modes M_DFF0, M_DFF1
2637}
2638
2639/*
2640 * Selection Out ID
2641 */
2642register SELOID {
2643 address 0x06B
2644 access_mode RW
2645 modes M_SCSI
2646}
2647
2648/*
2649 * 960-MHz Phase-Locked Loop Test Count
2650 */
2651register PLL960CNT0 {
2652 address 0x06A
2653 access_mode RO
2654 size 2
2655 modes M_CFG
2656}
2657
2658/*
2659 * 400-MHz Phase-Locked Loop Control 0
2660 */
2661register PLL400CTL0 {
2662 address 0x06C
2663 access_mode RW
2664 modes M_CFG
2665 field PLL_VCOSEL 0x80
2666 field PLL_PWDN 0x40
2667 field PLL_NS 0x30
2668 field PLL_ENLUD 0x08
2669 field PLL_ENLPF 0x04
2670 field PLL_DLPF 0x02
2671 field PLL_ENFBM 0x01
2672}
2673
2674/*
2675 * Arbitration Fairness
2676 */
2677register FAIRNESS {
2678 address 0x06C
2679 access_mode RW
2680 size 2
2681 modes M_SCSI
2682}
2683
2684/*
2685 * 400-MHz Phase-Locked Loop Control 1
2686 */
2687register PLL400CTL1 {
2688 address 0x06D
2689 access_mode RW
2690 modes M_CFG
2691 field PLL_CNTEN 0x80
2692 field PLL_CNTCLR 0x40
2693 field PLL_RST 0x01
2694}
2695
2696/*
2697 * Arbitration Unfairness
2698 */
2699register UNFAIRNESS {
2700 address 0x06E
2701 access_mode RW
2702 size 2
2703 modes M_SCSI
2704}
2705
2706/*
2707 * 400-MHz Phase-Locked Loop Test Count
2708 */
2709register PLL400CNT0 {
2710 address 0x06E
2711 access_mode RO
2712 size 2
2713 modes M_CFG
2714}
2715
2716/*
2717 * SCB Page Pointer
2718 */
2719register SCBPTR {
2720 address 0x0A8
2721 access_mode RW
2722 size 2
2723 modes M_DFF0, M_DFF1, M_CCHAN, M_SCSI
2724}
2725
2726/*
2727 * CMC SCB Array Count
2728 * Number of bytes to transfer between CMC SCB memory and SCBRAM.
2729 * Transfers must be 8byte aligned and sized.
2730 */
2731register CCSCBACNT {
2732 address 0x0AB
2733 access_mode RW
2734 modes M_CCHAN
2735}
2736
2737/*
2738 * SCB Autopointer
2739 * SCB-Next Address Snooping logic. When an SCB is transferred to
2740 * the card, the next SCB address to be used by the CMC array can
2741 * be autoloaded from that transfer.
2742 */
2743register SCBAUTOPTR {
2744 address 0x0AB
2745 access_mode RW
2746 modes M_CFG
2747 field AUSCBPTR_EN 0x80
2748 field SCBPTR_ADDR 0x38
2749 field SCBPTR_OFF 0x07
2750}
2751
2752/*
2753 * CMC SG Ram Address Pointer
2754 */
2755register CCSGADDR {
2756 address 0x0AC
2757 access_mode RW
2758 modes M_DFF0, M_DFF1
2759}
2760
2761/*
2762 * CMC SCB RAM Address Pointer
2763 */
2764register CCSCBADDR {
2765 address 0x0AC
2766 access_mode RW
2767 modes M_CCHAN
2768}
2769
2770/*
2771 * CMC SCB Ram Back-up Address Pointer
2772 * Indicates the true stop location of transfers halted prior
2773 * to SCBHCNT going to 0.
2774 */
2775register CCSCBADR_BK {
2776 address 0x0AC
2777 access_mode RO
2778 modes M_CFG
2779}
2780
2781/*
2782 * CMC SG Control
2783 */
2784register CCSGCTL {
2785 address 0x0AD
2786 access_mode RW
2787 modes M_DFF0, M_DFF1
2788 field CCSGDONE 0x80
2789 field SG_CACHE_AVAIL 0x10
2790 field CCSGENACK 0x08
2791 mask CCSGEN 0x0C
2792 field SG_FETCH_REQ 0x02
2793 field CCSGRESET 0x01
2794}
2795
2796/*
2797 * CMD SCB Control
2798 */
2799register CCSCBCTL {
2800 address 0x0AD
2801 access_mode RW
2802 modes M_CCHAN
2803 field CCSCBDONE 0x80
2804 field ARRDONE 0x40
2805 field CCARREN 0x10
2806 field CCSCBEN 0x08
2807 field CCSCBDIR 0x04
2808 field CCSCBRESET 0x01
2809}
2810
2811/*
2812 * CMC Ram BIST
2813 */
2814register CMC_RAMBIST {
2815 address 0x0AD
2816 access_mode RW
2817 modes M_CFG
2818 field SG_ELEMENT_SIZE 0x80
2819 field SCBRAMBIST_FAIL 0x40
2820 field SG_BIST_FAIL 0x20
2821 field SG_BIST_EN 0x10
2822 field CMC_BUFFER_BIST_FAIL 0x02
2823 field CMC_BUFFER_BIST_EN 0x01
2824}
2825
2826/*
2827 * CMC SG RAM Data Port
2828 */
2829register CCSGRAM {
2830 address 0x0B0
2831 access_mode RW
2832 modes M_DFF0, M_DFF1
2833}
2834
2835/*
2836 * CMC SCB RAM Data Port
2837 */
2838register CCSCBRAM {
2839 address 0x0B0
2840 access_mode RW
2841 modes M_CCHAN
2842}
2843
2844/*
2845 * Flex DMA Address.
2846 */
2847register FLEXADR {
2848 address 0x0B0
2849 access_mode RW
2850 size 3
2851 modes M_SCSI
2852}
2853
2854/*
2855 * Flex DMA Byte Count
2856 */
2857register FLEXCNT {
2858 address 0x0B3
2859 access_mode RW
2860 size 2
2861 modes M_SCSI
2862}
2863
2864/*
2865 * Flex DMA Status
2866 */
2867register FLEXDMASTAT {
2868 address 0x0B5
2869 access_mode RW
2870 modes M_SCSI
2871 field FLEXDMAERR 0x02
2872 field FLEXDMADONE 0x01
2873}
2874
2875/*
2876 * Flex DMA Data Port
2877 */
2878register FLEXDATA {
2879 address 0x0B6
2880 access_mode RW
2881 modes M_SCSI
2882}
2883
2884/*
2885 * Board Data
2886 */
2887register BRDDAT {
2888 address 0x0B8
2889 access_mode RW
2890 modes M_SCSI
2891}
2892
2893/*
2894 * Board Control
2895 */
2896register BRDCTL {
2897 address 0x0B9
2898 access_mode RW
2899 modes M_SCSI
2900 field FLXARBACK 0x80
2901 field FLXARBREQ 0x40
2902 field BRDADDR 0x38
2903 field BRDEN 0x04
2904 field BRDRW 0x02
2905 field BRDSTB 0x01
2906}
2907
2908/*
2909 * Serial EEPROM Address
2910 */
2911register SEEADR {
2912 address 0x0BA
2913 access_mode RW
2914 modes M_SCSI
2915}
2916
2917/*
2918 * Serial EEPROM Data
2919 */
2920register SEEDAT {
2921 address 0x0BC
2922 access_mode RW
2923 size 2
2924 modes M_SCSI
2925}
2926
2927/*
2928 * Serial EEPROM Status
2929 */
2930register SEESTAT {
2931 address 0x0BE
2932 access_mode RO
2933 modes M_SCSI
2934 field INIT_DONE 0x80
2935 field SEEOPCODE 0x70
2936 field LDALTID_L 0x08
2937 field SEEARBACK 0x04
2938 field SEEBUSY 0x02
2939 field SEESTART 0x01
2940}
2941
2942/*
2943 * Serial EEPROM Control
2944 */
2945register SEECTL {
2946 address 0x0BE
2947 access_mode RW
2948 modes M_SCSI
2949 field SEEOPCODE 0x70 {
2950 SEEOP_ERASE 0x70,
2951 SEEOP_READ 0x60,
2952 SEEOP_WRITE 0x50,
2953 /*
2954 * The following four commands use special
2955 * addresses for differentiation.
2956 */
2957 SEEOP_ERAL 0x40
2958 }
2959 mask SEEOP_EWEN 0x40
2960 mask SEEOP_WALL 0x40
2961 mask SEEOP_EWDS 0x40
2962 field SEERST 0x02
2963 field SEESTART 0x01
2964}
2965
2966const SEEOP_ERAL_ADDR 0x80
2967const SEEOP_EWEN_ADDR 0xC0
2968const SEEOP_WRAL_ADDR 0x40
2969const SEEOP_EWDS_ADDR 0x00
2970
2971/*
2972 * SCB Counter
2973 */
2974register SCBCNT {
2975 address 0x0BF
2976 access_mode RW
2977 modes M_SCSI
2978}
2979
2980/*
2981 * Data FIFO Write Address
2982 * Pointer to the next QWD location to be written to the data FIFO.
2983 */
2984register DFWADDR {
2985 address 0x0C0
2986 access_mode RW
2987 size 2
2988 modes M_DFF0, M_DFF1
2989}
2990
2991/*
2992 * DSP Filter Control
2993 */
2994register DSPFLTRCTL {
2995 address 0x0C0
2996 access_mode RW
2997 modes M_CFG
2998 field FLTRDISABLE 0x20
2999 field EDGESENSE 0x10
3000 field DSPFCNTSEL 0x0F
3001}
3002
3003/*
3004 * DSP Data Channel Control
3005 */
3006register DSPDATACTL {
3007 address 0x0C1
3008 access_mode RW
3009 modes M_CFG
3010 field BYPASSENAB 0x80
3011 field DESQDIS 0x10
3012 field RCVROFFSTDIS 0x04
3013 field XMITOFFSTDIS 0x02
3014}
3015
3016/*
3017 * Data FIFO Read Address
3018 * Pointer to the next QWD location to be read from the data FIFO.
3019 */
3020register DFRADDR {
3021 address 0x0C2
3022 access_mode RW
3023 size 2
3024 modes M_DFF0, M_DFF1
3025}
3026
3027/*
3028 * DSP REQ Control
3029 */
3030register DSPREQCTL {
3031 address 0x0C2
3032 access_mode RW
3033 modes M_CFG
3034 field MANREQCTL 0xC0
3035 field MANREQDLY 0x3F
3036}
3037
3038/*
3039 * DSP ACK Control
3040 */
3041register DSPACKCTL {
3042 address 0x0C3
3043 access_mode RW
3044 modes M_CFG
3045 field MANACKCTL 0xC0
3046 field MANACKDLY 0x3F
3047}
3048
3049/*
3050 * Data FIFO Data
3051 * Read/Write byte port into the data FIFO. The read and write
3052 * FIFO pointers increment with each read and write respectively
3053 * to this port.
3054 */
3055register DFDAT {
3056 address 0x0C4
3057 access_mode RW
3058 modes M_DFF0, M_DFF1
3059}
3060
3061/*
3062 * DSP Channel Select
3063 */
3064register DSPSELECT {
3065 address 0x0C4
3066 access_mode RW
3067 modes M_CFG
3068 field AUTOINCEN 0x80
3069 field DSPSEL 0x1F
3070}
3071
3072const NUMDSPS 0x14
3073
3074/*
3075 * Write Bias Control
3076 */
3077register WRTBIASCTL {
3078 address 0x0C5
3079 access_mode WO
3080 modes M_CFG
3081 field AUTOXBCDIS 0x80
3082 field XMITMANVAL 0x3F
3083}
3084
3085/*
3086 * Currently the WRTBIASCTL is the same as the default.
3087 */
3088const WRTBIASCTL_HP_DEFAULT 0x0
3089
3090/*
3091 * Receiver Bias Control
3092 */
3093register RCVRBIOSCTL {
3094 address 0x0C6
3095 access_mode WO
3096 modes M_CFG
3097 field AUTORBCDIS 0x80
3098 field RCVRMANVAL 0x3F
3099}
3100
3101/*
3102 * Write Bias Calculator
3103 */
3104register WRTBIASCALC {
3105 address 0x0C7
3106 access_mode RO
3107 modes M_CFG
3108}
3109
3110/*
3111 * Data FIFO Pointers
3112 * Contains the byte offset from DFWADDR and DWRADDR to the current
3113 * FIFO write/read locations.
3114 */
3115register DFPTRS {
3116 address 0x0C8
3117 access_mode RW
3118 modes M_DFF0, M_DFF1
3119}
3120
3121/*
3122 * Receiver Bias Calculator
3123 */
3124register RCVRBIASCALC {
3125 address 0x0C8
3126 access_mode RO
3127 modes M_CFG
3128}
3129
3130/*
3131 * Data FIFO Backup Read Pointer
3132 * Contains the data FIFO address to be restored if the last
3133 * data accessed from the data FIFO was not transferred successfully.
3134 */
3135register DFBKPTR {
3136 address 0x0C9
3137 access_mode RW
3138 size 2
3139 modes M_DFF0, M_DFF1
3140}
3141
3142/*
3143 * Skew Calculator
3144 */
3145register SKEWCALC {
3146 address 0x0C9
3147 access_mode RO
3148 modes M_CFG
3149}
3150
3151/*
3152 * Data FIFO Debug Control
3153 */
3154register DFDBCTL {
3155 address 0x0CB
3156 access_mode RW
3157 modes M_DFF0, M_DFF1
3158 field DFF_CIO_WR_RDY 0x20
3159 field DFF_CIO_RD_RDY 0x10
3160 field DFF_DIR_ERR 0x08
3161 field DFF_RAMBIST_FAIL 0x04
3162 field DFF_RAMBIST_DONE 0x02
3163 field DFF_RAMBIST_EN 0x01
3164}
3165
3166/*
3167 * Data FIFO Space Count
3168 * Number of FIFO locations that are free.
3169 */
3170register DFSCNT {
3171 address 0x0CC
3172 access_mode RO
3173 size 2
3174 modes M_DFF0, M_DFF1
3175}
3176
3177/*
3178 * Data FIFO Byte Count
3179 * Number of filled FIFO locations.
3180 */
3181register DFBCNT {
3182 address 0x0CE
3183 access_mode RO
3184 size 2
3185 modes M_DFF0, M_DFF1
3186}
3187
3188/*
3189 * Sequencer Program Overlay Address.
3190 * Low address must be written prior to high address.
3191 */
3192register OVLYADDR {
3193 address 0x0D4
3194 modes M_SCSI
3195 size 2
3196 access_mode RW
3197}
3198
3199/*
3200 * Sequencer Control 0
3201 * Error detection mode, speed configuration,
3202 * single step, breakpoints and program load.
3203 */
3204register SEQCTL0 {
3205 address 0x0D6
3206 access_mode RW
3207 field PERRORDIS 0x80
3208 field PAUSEDIS 0x40
3209 field FAILDIS 0x20
3210 field FASTMODE 0x10
3211 field BRKADRINTEN 0x08
3212 field STEP 0x04
3213 field SEQRESET 0x02
3214 field LOADRAM 0x01
3215}
3216
3217/*
3218 * Sequencer Control 1
3219 * Instruction RAM Diagnostics
3220 */
3221register SEQCTL1 {
3222 address 0x0D7
3223 access_mode RW
3224 field OVRLAY_DATA_CHK 0x08
3225 field RAMBIST_DONE 0x04
3226 field RAMBIST_FAIL 0x02
3227 field RAMBIST_EN 0x01
3228}
3229
3230/*
3231 * Sequencer Flags
3232 * Zero and Carry state of the ALU.
3233 */
3234register FLAGS {
3235 address 0x0D8
3236 access_mode RO
3237 field ZERO 0x02
3238 field CARRY 0x01
3239}
3240
3241/*
3242 * Sequencer Interrupt Control
3243 */
3244register SEQINTCTL {
3245 address 0x0D9
3246 access_mode RW
3247 field INTVEC1DSL 0x80
3248 field INT1_CONTEXT 0x20
3249 field SCS_SEQ_INT1M1 0x10
3250 field SCS_SEQ_INT1M0 0x08
3251 field INTMASK2 0x04
3252 field INTMASK1 0x02
3253 field IRET 0x01
3254}
3255
3256/*
3257 * Sequencer RAM Data Port
3258 * Single byte window into the Sequencer Instruction Ram area starting
3259 * at the address specified by OVLYADDR. To write a full instruction word,
3260 * simply write four bytes in succession. OVLYADDR will increment after the
3261 * most significant instrution byte (the byte with the parity bit) is written.
3262 */
3263register SEQRAM {
3264 address 0x0DA
3265 access_mode RW
3266}
3267
3268/*
3269 * Sequencer Program Counter
3270 * Low byte must be written prior to high byte.
3271 */
3272register PRGMCNT {
3273 address 0x0DE
3274 access_mode RW
3275 size 2
3276}
3277
3278/*
3279 * Accumulator
3280 */
3281register ACCUM {
3282 address 0x0E0
3283 access_mode RW
3284 accumulator
3285}
3286
3287/*
3288 * Source Index Register
3289 * Incrementing index for reads of SINDIR and the destination (low byte only)
3290 * for any immediate operands passed in jmp, jc, jnc, call instructions.
3291 * Example:
3292 * mvi 0xFF call some_routine;
3293 *
3294 * Will set SINDEX[0] to 0xFF and call the routine "some_routine.
3295 */
3296register SINDEX {
3297 address 0x0E2
3298 access_mode RW
3299 size 2
3300 sindex
3301}
3302
3303/*
3304 * Destination Index Register
3305 * Incrementing index for writes to DINDIR. Can be used as a scratch register.
3306 */
3307register DINDEX {
3308 address 0x0E4
3309 access_mode RW
3310 size 2
3311}
3312
3313/*
3314 * Break Address
3315 * Sequencer instruction breakpoint address address.
3316 */
3317register BRKADDR0 {
3318 address 0x0E6
3319 access_mode RW
3320}
3321
3322register BRKADDR1 {
3323 address 0x0E6
3324 access_mode RW
3325 field BRKDIS 0x80 /* Disable Breakpoint */
3326}
3327
3328/*
3329 * All Ones
3330 * All reads to this register return the value 0xFF.
3331 */
3332register ALLONES {
3333 address 0x0E8
3334 access_mode RO
3335 allones
3336}
3337
3338/*
3339 * All Zeros
3340 * All reads to this register return the value 0.
3341 */
3342register ALLZEROS {
3343 address 0x0EA
3344 access_mode RO
3345 allzeros
3346}
3347
3348/*
3349 * No Destination
3350 * Writes to this register have no effect.
3351 */
3352register NONE {
3353 address 0x0EA
3354 access_mode WO
3355 none
3356}
3357
3358/*
3359 * Source Index Indirect
3360 * Reading this register is equivalent to reading (register_base + SINDEX) and
3361 * incrementing SINDEX by 1.
3362 */
3363register SINDIR {
3364 address 0x0EC
3365 access_mode RO
3366}
3367
3368/*
3369 * Destination Index Indirect
3370 * Writing this register is equivalent to writing to (register_base + DINDEX)
3371 * and incrementing DINDEX by 1.
3372 */
3373register DINDIR {
3374 address 0x0ED
3375 access_mode WO
3376}
3377
3378/*
3379 * Function One
3380 * 2's complement to bit value conversion. Write the 2's complement value
3381 * (0-7 only) to the top nibble and retrieve the bit indexed by that value
3382 * on the next read of this register.
3383 * Example:
3384 * Write 0x60
3385 * Read 0x40
3386 */
3387register FUNCTION1 {
3388 address 0x0F0
3389 access_mode RW
3390}
3391
3392/*
3393 * Stack
3394 * Window into the stack. Each stack location is 10 bits wide reported
3395 * low byte followed by high byte. There are 8 stack locations.
3396 */
3397register STACK {
3398 address 0x0F2
3399 access_mode RW
3400}
3401
3402/*
3403 * Interrupt Vector 1 Address
3404 * Interrupt branch address for SCS SEQ_INT1 mode 0 and 1 interrupts.
3405 */
3406register INTVEC1_ADDR {
3407 address 0x0F4
3408 access_mode RW
3409 size 2
3410 modes M_CFG
3411}
3412
3413/*
3414 * Current Address
3415 * Address of the SEQRAM instruction currently executing instruction.
3416 */
3417register CURADDR {
3418 address 0x0F4
3419 access_mode RW
3420 size 2
3421 modes M_SCSI
3422}
3423
3424/*
3425 * Interrupt Vector 2 Address
3426 * Interrupt branch address for HST_SEQ_INT2 interrupts.
3427 */
3428register INTVEC2_ADDR {
3429 address 0x0F6
3430 access_mode RW
3431 size 2
3432 modes M_CFG
3433}
3434
3435/*
3436 * Last Address
3437 * Address of the SEQRAM instruction executed prior to the current instruction.
3438 */
3439register LASTADDR {
3440 address 0x0F6
3441 access_mode RW
3442 size 2
3443 modes M_SCSI
3444}
3445
3446register AHD_PCI_CONFIG_BASE {
3447 address 0x100
3448 access_mode RW
3449 size 256
3450 modes M_CFG
3451}
3452
3453/* ---------------------- Scratch RAM Offsets ------------------------- */
3454scratch_ram {
3455 /* Mode Specific */
3456 address 0x0A0
3457 size 8
3458 modes 0, 1, 2, 3
3459 REG0 {
3460 size 2
3461 }
3462 REG1 {
3463 size 2
3464 }
3465 REG_ISR {
3466 size 2
3467 }
3468 SG_STATE {
3469 size 1
3470 field SEGS_AVAIL 0x01
3471 field LOADING_NEEDED 0x02
3472 field FETCH_INPROG 0x04
3473 }
3474 /*
3475 * Track whether the transfer byte count for
3476 * the current data phase is odd.
3477 */
3478 DATA_COUNT_ODD {
3479 size 1
3480 }
3481}
3482
3483scratch_ram {
3484 /* Mode Specific */
3485 address 0x0F8
3486 size 8
3487 modes 0, 1, 2, 3
3488 LONGJMP_ADDR {
3489 size 2
3490 }
3491 ACCUM_SAVE {
3492 size 1
3493 }
3494}
3495
3496
3497scratch_ram {
3498 address 0x100
3499 size 128
3500 modes 0, 1, 2, 3
3501 /*
3502 * Per "other-id" execution queues. We use an array of
3503 * tail pointers into lists of SCBs sorted by "other-id".
3504 * The execution head pointer threads the head SCBs for
3505 * each list.
3506 */
3507 WAITING_SCB_TAILS {
3508 size 32
3509 }
3510 WAITING_TID_HEAD {
3511 size 2
3512 }
3513 WAITING_TID_TAIL {
3514 size 2
3515 }
3516 /*
3517 * SCBID of the next SCB in the new SCB queue.
3518 */
3519 NEXT_QUEUED_SCB_ADDR {
3520 size 4
3521 }
3522 /*
3523 * head of list of SCBs that have
3524 * completed but have not been
3525 * put into the qoutfifo.
3526 */
3527 COMPLETE_SCB_HEAD {
3528 size 2
3529 }
3530 /*
3531 * The list of completed SCBs in
3532 * the active DMA.
3533 */
3534 COMPLETE_SCB_DMAINPROG_HEAD {
3535 size 2
3536 }
3537 /*
3538 * head of list of SCBs that have
3539 * completed but need to be uploaded
3540 * to the host prior to being completed.
3541 */
3542 COMPLETE_DMA_SCB_HEAD {
3543 size 2
3544 }
3545 /* Counting semaphore to prevent new select-outs */
3546 QFREEZE_COUNT {
3547 size 2
3548 }
3549 /*
3550 * Mode to restore on legacy idle loop exit.
3551 */
3552 SAVED_MODE {
3553 size 1
3554 }
3555 /*
3556 * Single byte buffer used to designate the type or message
3557 * to send to a target.
3558 */
3559 MSG_OUT {
3560 size 1
3561 }
3562 /* Parameters for DMA Logic */
3563 DMAPARAMS {
3564 size 1
3565 field PRELOADEN 0x80
3566 field WIDEODD 0x40
3567 field SCSIEN 0x20
3568 field SDMAEN 0x10
3569 field SDMAENACK 0x10
3570 field HDMAEN 0x08
3571 field HDMAENACK 0x08
3572 field DIRECTION 0x04 /* Set indicates PCI->SCSI */
3573 field FIFOFLUSH 0x02
3574 field FIFORESET 0x01
3575 }
3576 SEQ_FLAGS {
3577 size 1
3578 field NOT_IDENTIFIED 0x80
3579 field NO_CDB_SENT 0x40
3580 field TARGET_CMD_IS_TAGGED 0x40
3581 field DPHASE 0x20
3582 /* Target flags */
3583 field TARG_CMD_PENDING 0x10
3584 field CMDPHASE_PENDING 0x08
3585 field DPHASE_PENDING 0x04
3586 field SPHASE_PENDING 0x02
3587 field NO_DISCONNECT 0x01
3588 }
3589 /*
3590 * Temporary storage for the
3591 * target/channel/lun of a
3592 * reconnecting target
3593 */
3594 SAVED_SCSIID {
3595 size 1
3596 }
3597 SAVED_LUN {
3598 size 1
3599 }
3600 /*
3601 * The last bus phase as seen by the sequencer.
3602 */
3603 LASTPHASE {
3604 size 1
3605 field CDI 0x80
3606 field IOI 0x40
3607 field MSGI 0x20
3608 field P_BUSFREE 0x01
3609 enum PHASE_MASK CDO|IOO|MSGO {
3610 P_DATAOUT 0x0,
3611 P_DATAIN IOO,
3612 P_DATAOUT_DT P_DATAOUT|MSGO,
3613 P_DATAIN_DT P_DATAIN|MSGO,
3614 P_COMMAND CDO,
3615 P_MESGOUT CDO|MSGO,
3616 P_STATUS CDO|IOO,
3617 P_MESGIN CDO|IOO|MSGO
3618 }
3619 }
3620 /*
3621 * Value to "or" into the SCBPTR[1] value to
3622 * indicate that an entry in the QINFIFO is valid.
3623 */
3624 QOUTFIFO_ENTRY_VALID_TAG {
3625 size 1
3626 }
3627 /*
3628 * Base address of our shared data with the kernel driver in host
3629 * memory. This includes the qoutfifo and target mode
3630 * incoming command queue.
3631 */
3632 SHARED_DATA_ADDR {
3633 size 4
3634 }
3635 /*
3636 * Pointer to location in host memory for next
3637 * position in the qoutfifo.
3638 */
3639 QOUTFIFO_NEXT_ADDR {
3640 size 4
3641 }
3642 /*
3643 * Kernel and sequencer offsets into the queue of
3644 * incoming target mode command descriptors. The
3645 * queue is full when the KERNEL_TQINPOS == TQINPOS.
3646 */
3647 KERNEL_TQINPOS {
3648 size 1
3649 }
3650 TQINPOS {
3651 size 1
3652 }
3653 ARG_1 {
3654 size 1
3655 mask SEND_MSG 0x80
3656 mask SEND_SENSE 0x40
3657 mask SEND_REJ 0x20
3658 mask MSGOUT_PHASEMIS 0x10
3659 mask EXIT_MSG_LOOP 0x08
3660 mask CONT_MSG_LOOP_WRITE 0x04
3661 mask CONT_MSG_LOOP_READ 0x03
3662 mask CONT_MSG_LOOP_TARG 0x02
3663 alias RETURN_1
3664 }
3665 ARG_2 {
3666 size 1
3667 alias RETURN_2
3668 }
3669
3670 /*
3671 * Snapshot of MSG_OUT taken after each message is sent.
3672 */
3673 LAST_MSG {
3674 size 1
3675 }
3676
3677 /*
3678 * Sequences the kernel driver has okayed for us. This allows
3679 * the driver to do things like prevent initiator or target
3680 * operations.
3681 */
3682 SCSISEQ_TEMPLATE {
3683 size 1
3684 field MANUALCTL 0x40
3685 field ENSELI 0x20
3686 field ENRSELI 0x10
3687 field MANUALP 0x0C
3688 field ENAUTOATNP 0x02
3689 field ALTSTIM 0x01
3690 }
3691
3692 /*
3693 * The initiator specified tag for this target mode transaction.
3694 */
3695 INITIATOR_TAG {
3696 size 1
3697 }
3698
3699 SEQ_FLAGS2 {
3700 size 1
3701 field TARGET_MSG_PENDING 0x02
3702 field SELECTOUT_QFROZEN 0x04
3703 }
3704
3705 ALLOCFIFO_SCBPTR {
3706 size 2
3707 }
3708
3709 /*
3710 * The maximum amount of time to wait, when interrupt coalescing
3711 * is enabled, before issueing a CMDCMPLT interrupt for a completed
3712 * command.
3713 */
3714 INT_COALESCING_TIMER {
3715 size 2
3716 }
3717
3718 /*
3719 * The maximum number of commands to coalesce into a single interrupt.
3720 * Actually the 2's complement of that value to simplify sequencer
3721 * code.
3722 */
3723 INT_COALESCING_MAXCMDS {
3724 size 1
3725 }
3726
3727 /*
3728 * The minimum number of commands still outstanding required
3729 * to continue coalescing (2's complement of value).
3730 */
3731 INT_COALESCING_MINCMDS {
3732 size 1
3733 }
3734
3735 /*
3736 * Number of commands "in-flight".
3737 */
3738 CMDS_PENDING {
3739 size 2
3740 }
3741
3742 /*
3743 * The count of commands that have been coalesced.
3744 */
3745 INT_COALESCING_CMDCOUNT {
3746 size 1
3747 }
3748
3749 /*
3750 * Since the HS_MAIBOX is self clearing, copy its contents to
3751 * this position in scratch ram every time it changes.
3752 */
3753 LOCAL_HS_MAILBOX {
3754 size 1
3755 }
3756 /*
3757 * Target-mode CDB type to CDB length table used
3758 * in non-packetized operation.
3759 */
3760 CMDSIZE_TABLE {
3761 size 8
3762 }
3763}
3764
3765/************************* Hardware SCB Definition ****************************/
3766scb {
3767 address 0x180
3768 size 64
3769 modes 0, 1, 2, 3
3770 SCB_RESIDUAL_DATACNT {
3771 size 4
3772 alias SCB_CDB_STORE
3773 alias SCB_HOST_CDB_PTR
3774 }
3775 SCB_RESIDUAL_SGPTR {
3776 size 4
3777 field SG_ADDR_MASK 0xf8 /* In the last byte */
3778 field SG_OVERRUN_RESID 0x02 /* In the first byte */
3779 field SG_LIST_NULL 0x01 /* In the first byte */
3780 }
3781 SCB_SCSI_STATUS {
3782 size 1
3783 alias SCB_HOST_CDB_LEN
3784 }
3785 SCB_TARGET_PHASES {
3786 size 1
3787 }
3788 SCB_TARGET_DATA_DIR {
3789 size 1
3790 }
3791 SCB_TARGET_ITAG {
3792 size 1
3793 }
3794 SCB_SENSE_BUSADDR {
3795 /*
3796 * Only valid if CDB length is less than 13 bytes or
3797 * we are using a CDB pointer. Otherwise contains
3798 * the last 4 bytes of embedded cdb information.
3799 */
3800 size 4
3801 alias SCB_NEXT_COMPLETE
3802 }
3803 SCB_TAG {
3804 alias SCB_FIFO_USE_COUNT
3805 size 2
3806 }
3807 SCB_CONTROL {
3808 size 1
3809 field TARGET_SCB 0x80
3810 field DISCENB 0x40
3811 field TAG_ENB 0x20
3812 field MK_MESSAGE 0x10
3813 field STATUS_RCVD 0x08
3814 field DISCONNECTED 0x04
3815 field SCB_TAG_TYPE 0x03
3816 }
3817 SCB_SCSIID {
3818 size 1
3819 field TID 0xF0
3820 field OID 0x0F
3821 }
3822 SCB_LUN {
3823 size 1
3824 field LID 0xff
3825 }
3826 SCB_TASK_ATTRIBUTE {
3827 size 1
3828 /*
3829 * Overloaded field for non-packetized
3830 * ignore wide residue message handling.
3831 */
3832 field SCB_XFERLEN_ODD 0x01
3833 }
3834 SCB_CDB_LEN {
3835 size 1
3836 field SCB_CDB_LEN_PTR 0x80 /* CDB in host memory */
3837 }
3838 SCB_TASK_MANAGEMENT {
3839 size 1
3840 }
3841 SCB_DATAPTR {
3842 size 8
3843 }
3844 SCB_DATACNT {
3845 /*
3846 * The last byte is really the high address bits for
3847 * the data address.
3848 */
3849 size 4
3850 field SG_LAST_SEG 0x80 /* In the fourth byte */
3851 field SG_HIGH_ADDR_BITS 0x7F /* In the fourth byte */
3852 }
3853 SCB_SGPTR {
3854 size 4
3855 field SG_STATUS_VALID 0x04 /* In the first byte */
3856 field SG_FULL_RESID 0x02 /* In the first byte */
3857 field SG_LIST_NULL 0x01 /* In the first byte */
3858 }
3859 SCB_BUSADDR {
3860 size 4
3861 }
3862 SCB_NEXT {
3863 alias SCB_NEXT_SCB_BUSADDR
3864 size 2
3865 }
3866 SCB_NEXT2 {
3867 size 2
3868 }
3869 SCB_SPARE {
3870 size 8
3871 alias SCB_PKT_LUN
3872 }
3873 SCB_DISCONNECTED_LISTS {
3874 size 8
3875 }
3876}
3877
3878/*********************************** Constants ********************************/
3879const MK_MESSAGE_BIT_OFFSET 4
3880const TID_SHIFT 4
3881const TARGET_CMD_CMPLT 0xfe
3882const INVALID_ADDR 0x80
3883#define SCB_LIST_NULL 0xff
3884#define QOUTFIFO_ENTRY_VALID_TOGGLE 0x80
3885
3886const CCSGADDR_MAX 0x80
3887const CCSCBADDR_MAX 0x80
3888const CCSGRAM_MAXSEGS 16
3889
3890/* Selection Timeout Timer Constants */
3891const STIMESEL_SHIFT 3
3892const STIMESEL_MIN 0x18
3893const STIMESEL_BUG_ADJ 0x8
3894
3895/* WDTR Message values */
3896const BUS_8_BIT 0x00
3897const BUS_16_BIT 0x01
3898const BUS_32_BIT 0x02
3899
3900/* Offset maximums */
3901const MAX_OFFSET 0xfe
3902const MAX_OFFSET_PACED 0xfe
3903const MAX_OFFSET_PACED_BUG 0x7f
3904/*
3905 * Some 160 devices incorrectly accept 0xfe as a
3906 * sync offset, but will overrun this value. Limit
3907 * to 0x7f for speed lower than U320 which will
3908 * avoid the persistent sync offset overruns.
3909 */
3910const MAX_OFFSET_NON_PACED 0x7f
3911const HOST_MSG 0xff
3912
3913/*
3914 * The size of our sense buffers.
3915 * Sense buffer mapping can be handled in either of two ways.
3916 * The first is to allocate a dmamap for each transaction.
3917 * Depending on the architecture, dmamaps can be costly. The
3918 * alternative is to statically map the buffers in much the same
3919 * way we handle our scatter gather lists. The driver implements
3920 * the later.
3921 */
3922const AHD_SENSE_BUFSIZE 256
3923
3924/* Target mode command processing constants */
3925const CMD_GROUP_CODE_SHIFT 0x05
3926
3927const STATUS_BUSY 0x08
3928const STATUS_QUEUE_FULL 0x28
3929const STATUS_PKT_SENSE 0xFF
3930const TARGET_DATA_IN 1
3931
3932const SCB_TRANSFER_SIZE_FULL_LUN 56
3933const SCB_TRANSFER_SIZE_1BYTE_LUN 48
3934/* PKT_OVERRUN_BUFSIZE must be a multiple of 256 less than 64K */
3935const PKT_OVERRUN_BUFSIZE 512
3936
3937/*
3938 * Timer parameters.
3939 */
3940const AHD_TIMER_US_PER_TICK 25
3941const AHD_TIMER_MAX_TICKS 0xFFFF
3942const AHD_TIMER_MAX_US (AHD_TIMER_MAX_TICKS * AHD_TIMER_US_PER_TICK)
3943
3944/*
3945 * Downloaded (kernel inserted) constants
3946 */
3947const SG_PREFETCH_CNT download
3948const SG_PREFETCH_CNT_LIMIT download
3949const SG_PREFETCH_ALIGN_MASK download
3950const SG_PREFETCH_ADDR_MASK download
3951const SG_SIZEOF download
3952const PKT_OVERRUN_BUFOFFSET download
3953const SCB_TRANSFER_SIZE download
3954
3955/*
3956 * BIOS SCB offsets
3957 */
3958const NVRAM_SCB_OFFSET 0x2C
diff --git a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq
new file mode 100644
index 000000000000..65339bc1ca99
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx.seq
@@ -0,0 +1,2058 @@
1/*
2 * Adaptec U320 device driver firmware for Linux and FreeBSD.
3 *
4 * Copyright (c) 1994-2001 Justin T. Gibbs.
5 * Copyright (c) 2000-2002 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $FreeBSD$
41 */
42
43VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#99 $"
44PATCH_ARG_LIST = "struct ahd_softc *ahd"
45PREFIX = "ahd_"
46
47#include "aic79xx.reg"
48#include "scsi_message.h"
49
50restart:
51if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {
52 test SEQINTCODE, 0xFF jz idle_loop;
53 SET_SEQINTCODE(NO_SEQINT)
54}
55
56idle_loop:
57
58 if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {
59 /*
60 * Convert ERROR status into a sequencer
61 * interrupt to handle the case of an
62 * interrupt collision on the hardware
63 * setting of HWERR.
64 */
65 test ERROR, 0xFF jz no_error_set;
66 SET_SEQINTCODE(SAW_HWERR)
67no_error_set:
68 }
69 SET_MODE(M_SCSI, M_SCSI)
70 test SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus;
71 test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz idle_loop_checkbus;
72 cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus;
73 /*
74 * ENSELO is cleared by a SELDO, so we must test for SELDO
75 * one last time.
76 */
77BEGIN_CRITICAL;
78 test SSTAT0, SELDO jnz select_out;
79END_CRITICAL;
80 call start_selection;
81idle_loop_checkbus:
82BEGIN_CRITICAL;
83 test SSTAT0, SELDO jnz select_out;
84END_CRITICAL;
85 test SSTAT0, SELDI jnz select_in;
86 test SCSIPHASE, ~DATA_PHASE_MASK jz idle_loop_check_nonpackreq;
87 test SCSISIGO, ATNO jz idle_loop_check_nonpackreq;
88 call unexpected_nonpkt_phase_find_ctxt;
89idle_loop_check_nonpackreq:
90 test SSTAT2, NONPACKREQ jz . + 2;
91 call unexpected_nonpkt_phase_find_ctxt;
92 if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {
93 and A, FIFO0FREE|FIFO1FREE, DFFSTAT;
94 cmp A, FIFO0FREE|FIFO1FREE jne . + 3;
95 and SBLKCTL, ~DIAGLEDEN|DIAGLEDON;
96 jmp . + 2;
97 or SBLKCTL, DIAGLEDEN|DIAGLEDON;
98 }
99 call idle_loop_gsfifo_in_scsi_mode;
100 call idle_loop_service_fifos;
101 call idle_loop_cchan;
102 jmp idle_loop;
103
104BEGIN_CRITICAL;
105idle_loop_gsfifo:
106 SET_MODE(M_SCSI, M_SCSI)
107idle_loop_gsfifo_in_scsi_mode:
108 test LQISTAT2, LQIGSAVAIL jz return;
109 /*
110 * We have received good status for this transaction. There may
111 * still be data in our FIFOs draining to the host. Complete
112 * the SCB only if all data has transferred to the host.
113 */
114good_status_IU_done:
115 bmov SCBPTR, GSFIFO, 2;
116 clr SCB_SCSI_STATUS;
117 /*
118 * If a command completed before an attempted task management
119 * function completed, notify the host after disabling any
120 * pending select-outs.
121 */
122 test SCB_TASK_MANAGEMENT, 0xFF jz gsfifo_complete_normally;
123 test SSTAT0, SELDO|SELINGO jnz . + 2;
124 and SCSISEQ0, ~ENSELO;
125 SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY)
126gsfifo_complete_normally:
127 or SCB_CONTROL, STATUS_RCVD;
128
129 /*
130 * Since this status did not consume a FIFO, we have to
131 * be a bit more dilligent in how we check for FIFOs pertaining
132 * to this transaction. There are two states that a FIFO still
133 * transferring data may be in.
134 *
135 * 1) Configured and draining to the host, with a FIFO handler.
136 * 2) Pending cfg4data, fifo not empty.
137 *
138 * Case 1 can be detected by noticing a non-zero FIFO active
139 * count in the SCB. In this case, we allow the routine servicing
140 * the FIFO to complete the SCB.
141 *
142 * Case 2 implies either a pending or yet to occur save data
143 * pointers for this same context in the other FIFO. So, if
144 * we detect case 1, we will properly defer the post of the SCB
145 * and achieve the desired result. The pending cfg4data will
146 * notice that status has been received and complete the SCB.
147 */
148 test SCB_FIFO_USE_COUNT, 0xFF jnz idle_loop_gsfifo_in_scsi_mode;
149 call complete;
150END_CRITICAL;
151 jmp idle_loop_gsfifo_in_scsi_mode;
152
153idle_loop_service_fifos:
154 SET_MODE(M_DFF0, M_DFF0)
155 test LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo;
156 call longjmp;
157idle_loop_next_fifo:
158 SET_MODE(M_DFF1, M_DFF1)
159 test LONGJMP_ADDR[1], INVALID_ADDR jz longjmp;
160return:
161 ret;
162
163idle_loop_cchan:
164 SET_MODE(M_CCHAN, M_CCHAN)
165 test QOFF_CTLSTA, HS_MAILBOX_ACT jz hs_mailbox_empty;
166 or QOFF_CTLSTA, HS_MAILBOX_ACT;
167 mov LOCAL_HS_MAILBOX, HS_MAILBOX;
168hs_mailbox_empty:
169BEGIN_CRITICAL;
170 test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;
171 test CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog;
172 test CCSCBCTL, CCSCBDONE jz return;
173END_CRITICAL;
174 /* FALLTHROUGH */
175scbdma_tohost_done:
176 test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;
177 /*
178 * An SCB has been succesfully uploaded to the host.
179 * If the SCB was uploaded for some reason other than
180 * bad SCSI status (currently only for underruns), we
181 * queue the SCB for normal completion. Otherwise, we
182 * wait until any select-out activity has halted, and
183 * then notify the host so that the transaction can be
184 * dealt with.
185 */
186 test SCB_SCSI_STATUS, 0xff jnz scbdma_notify_host;
187 and CCSCBCTL, ~(CCARREN|CCSCBEN);
188 bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;
189 bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
190 bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
191scbdma_notify_host:
192 SET_MODE(M_SCSI, M_SCSI)
193 test SCSISEQ0, ENSELO jnz return;
194 test SSTAT0, (SELDO|SELINGO) jnz return;
195 SET_MODE(M_CCHAN, M_CCHAN)
196 /*
197 * Remove SCB and notify host.
198 */
199 and CCSCBCTL, ~(CCARREN|CCSCBEN);
200 bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;
201 SET_SEQINTCODE(BAD_SCB_STATUS)
202 ret;
203fill_qoutfifo_dmadone:
204 and CCSCBCTL, ~(CCARREN|CCSCBEN);
205 call qoutfifo_updated;
206 mvi COMPLETE_SCB_DMAINPROG_HEAD[1], SCB_LIST_NULL;
207 bmov QOUTFIFO_NEXT_ADDR, SCBHADDR, 4;
208 test QOFF_CTLSTA, SDSCB_ROLLOVR jz return;
209 bmov QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4;
210 xor QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret;
211
212qoutfifo_updated:
213 /*
214 * If there are more commands waiting to be dma'ed
215 * to the host, always coalesce. Otherwise honor the
216 * host's wishes.
217 */
218 cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count;
219 cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count;
220 test LOCAL_HS_MAILBOX, ENINT_COALESCE jz issue_cmdcmplt;
221
222 /*
223 * If we have relatively few commands outstanding, don't
224 * bother waiting for another command to complete.
225 */
226 test CMDS_PENDING[1], 0xFF jnz coalesce_by_count;
227 /* Add -1 so that jnc means <= not just < */
228 add A, -1, INT_COALESCING_MINCMDS;
229 add NONE, A, CMDS_PENDING;
230 jnc issue_cmdcmplt;
231
232 /*
233 * If coalescing, only coalesce up to the limit
234 * provided by the host driver.
235 */
236coalesce_by_count:
237 mov A, INT_COALESCING_MAXCMDS;
238 add NONE, A, INT_COALESCING_CMDCOUNT;
239 jc issue_cmdcmplt;
240 /*
241 * If the timer is not currently active,
242 * fire it up.
243 */
244 test INTCTL, SWTMINTMASK jz return;
245 bmov SWTIMER, INT_COALESCING_TIMER, 2;
246 mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO;
247 or INTCTL, SWTMINTEN|SWTIMER_START;
248 and INTCTL, ~SWTMINTMASK ret;
249
250issue_cmdcmplt:
251 mvi INTSTAT, CMDCMPLT;
252 clr INT_COALESCING_CMDCOUNT;
253 or INTCTL, SWTMINTMASK ret;
254
255BEGIN_CRITICAL;
256fetch_new_scb_inprog:
257 test CCSCBCTL, ARRDONE jz return;
258fetch_new_scb_done:
259 and CCSCBCTL, ~(CCARREN|CCSCBEN);
260 bmov REG0, SCBPTR, 2;
261 clr A;
262 add CMDS_PENDING, 1;
263 adc CMDS_PENDING[1], A;
264 if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
265 /*
266 * "Short Luns" are not placed into outgoing LQ
267 * packets in the correct byte order. Use a full
268 * sized lun field instead and fill it with the
269 * one byte of lun information we support.
270 */
271 mov SCB_PKT_LUN[6], SCB_LUN;
272 }
273 /*
274 * The FIFO use count field is shared with the
275 * tag set by the host so that our SCB dma engine
276 * knows the correct location to store the SCB.
277 * Set it to zero before processing the SCB.
278 */
279 clr SCB_FIFO_USE_COUNT;
280 /* Update the next SCB address to download. */
281 bmov NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4;
282 mvi SCB_NEXT[1], SCB_LIST_NULL;
283 mvi SCB_NEXT2[1], SCB_LIST_NULL;
284 /* Increment our position in the QINFIFO. */
285 mov NONE, SNSCB_QOFF;
286 /*
287 * SCBs that want to send messages are always
288 * queued independently. This ensures that they
289 * are at the head of the SCB list to select out
290 * to a target and we will see the MK_MESSAGE flag.
291 */
292 test SCB_CONTROL, MK_MESSAGE jnz first_new_target_scb;
293 shr SINDEX, 3, SCB_SCSIID;
294 and SINDEX, ~0x1;
295 mvi SINDEX[1], (WAITING_SCB_TAILS >> 8);
296 bmov DINDEX, SINDEX, 2;
297 bmov SCBPTR, SINDIR, 2;
298 bmov DINDIR, REG0, 2;
299 cmp SCBPTR[1], SCB_LIST_NULL je first_new_target_scb;
300 bmov SCB_NEXT, REG0, 2 ret;
301first_new_target_scb:
302 cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je first_new_scb;
303 bmov SCBPTR, WAITING_TID_TAIL, 2;
304 bmov SCB_NEXT2, REG0, 2;
305 bmov WAITING_TID_TAIL, REG0, 2 ret;
306first_new_scb:
307 bmov WAITING_TID_HEAD, REG0, 2;
308 bmov WAITING_TID_TAIL, REG0, 2 ret;
309END_CRITICAL;
310
311scbdma_idle:
312 /*
313 * Give precedence to downloading new SCBs to execute
314 * unless select-outs are currently frozen.
315 */
316 test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz . + 2;
317BEGIN_CRITICAL;
318 test QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb;
319 cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne dma_complete_scb;
320 cmp COMPLETE_SCB_HEAD[1], SCB_LIST_NULL je return;
321 /* FALLTHROUGH */
322fill_qoutfifo:
323 /*
324 * Keep track of the SCBs we are dmaing just
325 * in case the DMA fails or is aborted.
326 */
327 mov A, QOUTFIFO_ENTRY_VALID_TAG;
328 bmov COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2;
329 mvi CCSCBCTL, CCSCBRESET;
330 bmov SCBHADDR, QOUTFIFO_NEXT_ADDR, 4;
331 bmov SCBPTR, COMPLETE_SCB_HEAD, 2;
332fill_qoutfifo_loop:
333 mov CCSCBRAM, SCBPTR;
334 or CCSCBRAM, A, SCBPTR[1];
335 mov NONE, SDSCB_QOFF;
336 inc INT_COALESCING_CMDCOUNT;
337 add CMDS_PENDING, -1;
338 adc CMDS_PENDING[1], -1;
339 cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done;
340 cmp CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done;
341 test QOFF_CTLSTA, SDSCB_ROLLOVR jnz fill_qoutfifo_done;
342 bmov SCBPTR, SCB_NEXT_COMPLETE, 2;
343 jmp fill_qoutfifo_loop;
344fill_qoutfifo_done:
345 mov SCBHCNT, CCSCBADDR;
346 mvi CCSCBCTL, CCSCBEN|CCSCBRESET;
347 bmov COMPLETE_SCB_HEAD, SCB_NEXT_COMPLETE, 2;
348 mvi SCB_NEXT_COMPLETE[1], SCB_LIST_NULL ret;
349
350fetch_new_scb:
351 bmov SCBHADDR, NEXT_QUEUED_SCB_ADDR, 4;
352 mvi CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET jmp dma_scb;
353dma_complete_scb:
354 bmov SCBPTR, COMPLETE_DMA_SCB_HEAD, 2;
355 bmov SCBHADDR, SCB_BUSADDR, 4;
356 mvi CCARREN|CCSCBEN|CCSCBRESET jmp dma_scb;
357END_CRITICAL;
358
359/*
360 * Either post or fetch an SCB from host memory. The caller
361 * is responsible for polling for transfer completion.
362 *
363 * Prerequisits: Mode == M_CCHAN
364 * SINDEX contains CCSCBCTL flags
365 * SCBHADDR set to Host SCB address
366 * SCBPTR set to SCB src location on "push" operations
367 */
368SET_SRC_MODE M_CCHAN;
369SET_DST_MODE M_CCHAN;
370dma_scb:
371 mvi SCBHCNT, SCB_TRANSFER_SIZE;
372 mov CCSCBCTL, SINDEX ret;
373
374BEGIN_CRITICAL;
375setjmp:
376 bmov LONGJMP_ADDR, STACK, 2 ret;
377setjmp_inline:
378 bmov LONGJMP_ADDR, STACK, 2;
379longjmp:
380 bmov STACK, LONGJMP_ADDR, 2 ret;
381END_CRITICAL;
382
383/*************************** Chip Bug Work Arounds ****************************/
384/*
385 * Must disable interrupts when setting the mode pointer
386 * register as an interrupt occurring mid update will
387 * fail to store the new mode value for restoration on
388 * an iret.
389 */
390if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) {
391set_mode_work_around:
392 mvi SEQINTCTL, INTVEC1DSL;
393 mov MODE_PTR, SINDEX;
394 clr SEQINTCTL ret;
395
396toggle_dff_mode_work_around:
397 mvi SEQINTCTL, INTVEC1DSL;
398 xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1);
399 clr SEQINTCTL ret;
400}
401
402
403if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {
404set_seqint_work_around:
405 mov SEQINTCODE, SINDEX;
406 mvi SEQINTCODE, NO_SEQINT ret;
407}
408
409/************************ Packetized LongJmp Routines *************************/
410SET_SRC_MODE M_SCSI;
411SET_DST_MODE M_SCSI;
412start_selection:
413BEGIN_CRITICAL;
414 if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) {
415 /*
416 * Razor #494
417 * Rev A hardware fails to update LAST/CURR/NEXTSCB
418 * correctly after a packetized selection in several
419 * situations:
420 *
421 * 1) If only one command existed in the queue, the
422 * LAST/CURR/NEXTSCB are unchanged.
423 *
424 * 2) In a non QAS, protocol allowed phase change,
425 * the queue is shifted 1 too far. LASTSCB is
426 * the last SCB that was correctly processed.
427 *
428 * 3) In the QAS case, if the full list of commands
429 * was successfully sent, NEXTSCB is NULL and neither
430 * CURRSCB nor LASTSCB can be trusted. We must
431 * manually walk the list counting MAXCMDCNT elements
432 * to find the last SCB that was sent correctly.
433 *
434 * To simplify the workaround for this bug in SELDO
435 * handling, we initialize LASTSCB prior to enabling
436 * selection so we can rely on it even for case #1 above.
437 */
438 bmov LASTSCB, WAITING_TID_HEAD, 2;
439 }
440 bmov CURRSCB, WAITING_TID_HEAD, 2;
441 bmov SCBPTR, WAITING_TID_HEAD, 2;
442 shr SELOID, 4, SCB_SCSIID;
443 /*
444 * If we want to send a message to the device, ensure
445 * we are selecting with atn irregardless of our packetized
446 * agreement. Since SPI4 only allows target reset or PPR
447 * messages if this is a packetized connection, the change
448 * to our negotiation table entry for this selection will
449 * be cleared when the message is acted on.
450 */
451 test SCB_CONTROL, MK_MESSAGE jz . + 3;
452 mov NEGOADDR, SELOID;
453 or NEGCONOPTS, ENAUTOATNO;
454 or SCSISEQ0, ENSELO ret;
455END_CRITICAL;
456
457/*
458 * Allocate a FIFO for a non-packetized transaction.
459 * In RevA hardware, both FIFOs must be free before we
460 * can allocate a FIFO for a non-packetized transaction.
461 */
462allocate_fifo_loop:
463 /*
464 * Do whatever work is required to free a FIFO.
465 */
466 call idle_loop_service_fifos;
467 SET_MODE(M_SCSI, M_SCSI)
468allocate_fifo:
469 if ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0) {
470 and A, FIFO0FREE|FIFO1FREE, DFFSTAT;
471 cmp A, FIFO0FREE|FIFO1FREE jne allocate_fifo_loop;
472 } else {
473 test DFFSTAT, FIFO1FREE jnz allocate_fifo1;
474 test DFFSTAT, FIFO0FREE jz allocate_fifo_loop;
475 mvi DFFSTAT, B_CURRFIFO_0;
476 SET_MODE(M_DFF0, M_DFF0)
477 bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret;
478 }
479SET_SRC_MODE M_SCSI;
480SET_DST_MODE M_SCSI;
481allocate_fifo1:
482 mvi DFFSTAT, CURRFIFO_1;
483 SET_MODE(M_DFF1, M_DFF1)
484 bmov SCBPTR, ALLOCFIFO_SCBPTR, 2 ret;
485
486/*
487 * We have been reselected as an initiator
488 * or selected as a target.
489 */
490SET_SRC_MODE M_SCSI;
491SET_DST_MODE M_SCSI;
492select_in:
493 if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
494 /*
495 * Test to ensure that the bus has not
496 * already gone free prior to clearing
497 * any stale busfree status. This avoids
498 * a window whereby a busfree just after
499 * a selection could be missed.
500 */
501 test SCSISIGI, BSYI jz . + 2;
502 mvi CLRSINT1,CLRBUSFREE;
503 or SIMODE1, ENBUSFREE;
504 }
505 or SXFRCTL0, SPIOEN;
506 and SAVED_SCSIID, SELID_MASK, SELID;
507 and A, OID, IOWNID;
508 or SAVED_SCSIID, A;
509 mvi CLRSINT0, CLRSELDI;
510 jmp ITloop;
511
512/*
513 * We have successfully selected out.
514 *
515 * Clear SELDO.
516 * Dequeue all SCBs sent from the waiting queue
517 * Requeue all SCBs *not* sent to the tail of the waiting queue
518 * Take Razor #494 into account for above.
519 *
520 * In Packetized Mode:
521 * Return to the idle loop. Our interrupt handler will take
522 * care of any incoming L_Qs.
523 *
524 * In Non-Packetize Mode:
525 * Continue to our normal state machine.
526 */
527SET_SRC_MODE M_SCSI;
528SET_DST_MODE M_SCSI;
529select_out:
530BEGIN_CRITICAL;
531 /* Clear out all SCBs that have been successfully sent. */
532 if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) {
533 /*
534 * For packetized, the LQO manager clears ENSELO on
535 * the assertion of SELDO. If we are non-packetized,
536 * LASTSCB and CURRSCB are accurate.
537 */
538 test SCSISEQ0, ENSELO jnz use_lastscb;
539
540 /*
541 * The update is correct for LQOSTAT1 errors. All
542 * but LQOBUSFREE are handled by kernel interrupts.
543 * If we see LQOBUSFREE, return to the idle loop.
544 * Once we are out of the select_out critical section,
545 * the kernel will cleanup the LQOBUSFREE and we will
546 * eventually restart the selection if appropriate.
547 */
548 test LQOSTAT1, LQOBUSFREE jnz idle_loop;
549
550 /*
551 * On a phase change oustside of packet boundaries,
552 * LASTSCB points to the currently active SCB context
553 * on the bus.
554 */
555 test LQOSTAT2, LQOPHACHGOUTPKT jnz use_lastscb;
556
557 /*
558 * If the hardware has traversed the whole list, NEXTSCB
559 * will be NULL, CURRSCB and LASTSCB cannot be trusted,
560 * but MAXCMDCNT is accurate. If we stop part way through
561 * the list or only had one command to issue, NEXTSCB[1] is
562 * not NULL and LASTSCB is the last command to go out.
563 */
564 cmp NEXTSCB[1], SCB_LIST_NULL jne use_lastscb;
565
566 /*
567 * Brute force walk.
568 */
569 bmov SCBPTR, WAITING_TID_HEAD, 2;
570 mvi SEQINTCTL, INTVEC1DSL;
571 mvi MODE_PTR, MK_MODE(M_CFG, M_CFG);
572 mov A, MAXCMDCNT;
573 mvi MODE_PTR, MK_MODE(M_SCSI, M_SCSI);
574 clr SEQINTCTL;
575find_lastscb_loop:
576 dec A;
577 test A, 0xFF jz found_last_sent_scb;
578 bmov SCBPTR, SCB_NEXT, 2;
579 jmp find_lastscb_loop;
580use_lastscb:
581 bmov SCBPTR, LASTSCB, 2;
582found_last_sent_scb:
583 bmov CURRSCB, SCBPTR, 2;
584curscb_ww_done:
585 } else {
586 bmov SCBPTR, CURRSCB, 2;
587 }
588
589 /*
590 * Requeue any SCBs not sent, to the tail of the waiting Q.
591 */
592 cmp SCB_NEXT[1], SCB_LIST_NULL je select_out_list_done;
593
594 /*
595 * We know that neither the per-TID list nor the list of
596 * TIDs is empty. Use this knowledge to our advantage.
597 */
598 bmov REG0, SCB_NEXT, 2;
599 bmov SCBPTR, WAITING_TID_TAIL, 2;
600 bmov SCB_NEXT2, REG0, 2;
601 bmov WAITING_TID_TAIL, REG0, 2;
602 jmp select_out_inc_tid_q;
603
604select_out_list_done:
605 /*
606 * The whole list made it. Just clear our TID's tail pointer
607 * unless we were queued independently due to our need to
608 * send a message.
609 */
610 test SCB_CONTROL, MK_MESSAGE jnz select_out_inc_tid_q;
611 shr DINDEX, 3, SCB_SCSIID;
612 or DINDEX, 1; /* Want only the second byte */
613 mvi DINDEX[1], ((WAITING_SCB_TAILS) >> 8);
614 mvi DINDIR, SCB_LIST_NULL;
615select_out_inc_tid_q:
616 bmov SCBPTR, WAITING_TID_HEAD, 2;
617 bmov WAITING_TID_HEAD, SCB_NEXT2, 2;
618 cmp WAITING_TID_HEAD[1], SCB_LIST_NULL jne . + 2;
619 mvi WAITING_TID_TAIL[1], SCB_LIST_NULL;
620 bmov SCBPTR, CURRSCB, 2;
621 mvi CLRSINT0, CLRSELDO;
622 test LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase;
623 test LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase;
624
625 /*
626 * If this is a packetized connection, return to our
627 * idle_loop and let our interrupt handler deal with
628 * any connection setup/teardown issues. The only
629 * exceptions are the case of MK_MESSAGE and task management
630 * SCBs.
631 */
632 if ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0) {
633 /*
634 * In the A, the LQO manager transitions to LQOSTOP0 even if
635 * we have selected out with ATN asserted and the target
636 * REQs in a non-packet phase.
637 */
638 test SCB_CONTROL, MK_MESSAGE jz select_out_no_message;
639 test SCSISIGO, ATNO jnz select_out_non_packetized;
640select_out_no_message:
641 }
642 test LQOSTAT2, LQOSTOP0 jz select_out_non_packetized;
643 test SCB_TASK_MANAGEMENT, 0xFF jz idle_loop;
644 SET_SEQINTCODE(TASKMGMT_FUNC_COMPLETE)
645 jmp idle_loop;
646
647select_out_non_packetized:
648 /* Non packetized request. */
649 and SCSISEQ0, ~ENSELO;
650 if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
651 /*
652 * Test to ensure that the bus has not
653 * already gone free prior to clearing
654 * any stale busfree status. This avoids
655 * a window whereby a busfree just after
656 * a selection could be missed.
657 */
658 test SCSISIGI, BSYI jz . + 2;
659 mvi CLRSINT1,CLRBUSFREE;
660 or SIMODE1, ENBUSFREE;
661 }
662 mov SAVED_SCSIID, SCB_SCSIID;
663 mov SAVED_LUN, SCB_LUN;
664 mvi SEQ_FLAGS, NO_CDB_SENT;
665END_CRITICAL;
666 or SXFRCTL0, SPIOEN;
667
668 /*
669 * As soon as we get a successful selection, the target
670 * should go into the message out phase since we have ATN
671 * asserted.
672 */
673 mvi MSG_OUT, MSG_IDENTIFYFLAG;
674
675 /*
676 * Main loop for information transfer phases. Wait for the
677 * target to assert REQ before checking MSG, C/D and I/O for
678 * the bus phase.
679 */
680mesgin_phasemis:
681ITloop:
682 call phase_lock;
683
684 mov A, LASTPHASE;
685
686 test A, ~P_DATAIN_DT jz p_data;
687 cmp A,P_COMMAND je p_command;
688 cmp A,P_MESGOUT je p_mesgout;
689 cmp A,P_STATUS je p_status;
690 cmp A,P_MESGIN je p_mesgin;
691
692 SET_SEQINTCODE(BAD_PHASE)
693 jmp ITloop; /* Try reading the bus again. */
694
695/*
696 * Command phase. Set up the DMA registers and let 'er rip.
697 */
698p_command:
699 test SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay;
700 SET_SEQINTCODE(PROTO_VIOLATION)
701p_command_okay:
702 test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))
703 jnz p_command_allocate_fifo;
704 /*
705 * Command retry. Free our current FIFO and
706 * re-allocate a FIFO so transfer state is
707 * reset.
708 */
709SET_SRC_MODE M_DFF1;
710SET_DST_MODE M_DFF1;
711 mvi DFFSXFRCTL, RSTCHN|CLRSHCNT;
712 SET_MODE(M_SCSI, M_SCSI)
713p_command_allocate_fifo:
714 bmov ALLOCFIFO_SCBPTR, SCBPTR, 2;
715 call allocate_fifo;
716SET_SRC_MODE M_DFF1;
717SET_DST_MODE M_DFF1;
718 add NONE, -17, SCB_CDB_LEN;
719 jnc p_command_embedded;
720p_command_from_host:
721 bmov HADDR[0], SCB_HOST_CDB_PTR, 9;
722 mvi SG_CACHE_PRE, LAST_SEG;
723 mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);
724 jmp p_command_xfer;
725p_command_embedded:
726 bmov SHCNT[0], SCB_CDB_LEN, 1;
727 bmov DFDAT, SCB_CDB_STORE, 16;
728 mvi DFCNTRL, SCSIEN;
729p_command_xfer:
730 and SEQ_FLAGS, ~NO_CDB_SENT;
731 if ((ahd->features & AHD_FAST_CDB_DELIVERY) != 0) {
732 /*
733 * To speed up CDB delivery in Rev B, all CDB acks
734 * are "released" to the output sync as soon as the
735 * command phase starts. There is only one problem
736 * with this approach. If the target changes phase
737 * before all data are sent, we have left over acks
738 * that can go out on the bus in a data phase. Due
739 * to other chip contraints, this only happens if
740 * the target goes to data-in, but if the acks go
741 * out before we can test SDONE, we'll think that
742 * the transfer has completed successfully. Work
743 * around this by taking advantage of the 400ns or
744 * 800ns dead time between command phase and the REQ
745 * of the new phase. If the transfer has completed
746 * successfully, SCSIEN should fall *long* before we
747 * see a phase change. We thus treat any phasemiss
748 * that occurs before SCSIEN falls as an incomplete
749 * transfer.
750 */
751 test SSTAT1, PHASEMIS jnz p_command_xfer_failed;
752 test DFCNTRL, SCSIEN jnz . - 1;
753 } else {
754 test DFCNTRL, SCSIEN jnz .;
755 }
756 /*
757 * DMA Channel automatically disabled.
758 * Don't allow a data phase if the command
759 * was not fully transferred.
760 */
761 test SSTAT2, SDONE jnz ITloop;
762p_command_xfer_failed:
763 or SEQ_FLAGS, NO_CDB_SENT;
764 jmp ITloop;
765
766
767/*
768 * Status phase. Wait for the data byte to appear, then read it
769 * and store it into the SCB.
770 */
771SET_SRC_MODE M_SCSI;
772SET_DST_MODE M_SCSI;
773p_status:
774 test SEQ_FLAGS,NOT_IDENTIFIED jnz mesgin_proto_violation;
775p_status_okay:
776 mov SCB_SCSI_STATUS, SCSIDAT;
777 or SCB_CONTROL, STATUS_RCVD;
778 jmp ITloop;
779
780/*
781 * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full
782 * indentify message sequence and send it to the target. The host may
783 * override this behavior by setting the MK_MESSAGE bit in the SCB
784 * control byte. This will cause us to interrupt the host and allow
785 * it to handle the message phase completely on its own. If the bit
786 * associated with this target is set, we will also interrupt the host,
787 * thereby allowing it to send a message on the next selection regardless
788 * of the transaction being sent.
789 *
790 * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message.
791 * This is done to allow the host to send messages outside of an identify
792 * sequence while protecting the seqencer from testing the MK_MESSAGE bit
793 * on an SCB that might not be for the current nexus. (For example, a
794 * BDR message in responce to a bad reselection would leave us pointed to
795 * an SCB that doesn't have anything to do with the current target).
796 *
797 * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag,
798 * bus device reset).
799 *
800 * When there are no messages to send, MSG_OUT should be set to MSG_NOOP,
801 * in case the target decides to put us in this phase for some strange
802 * reason.
803 */
804p_mesgout_retry:
805 /* Turn on ATN for the retry */
806 mvi SCSISIGO, ATNO;
807p_mesgout:
808 mov SINDEX, MSG_OUT;
809 cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host;
810 test SCB_CONTROL,MK_MESSAGE jnz host_message_loop;
811p_mesgout_identify:
812 or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN;
813 test SCB_CONTROL, DISCENB jnz . + 2;
814 and SINDEX, ~DISCENB;
815/*
816 * Send a tag message if TAG_ENB is set in the SCB control block.
817 * Use SCB_NONPACKET_TAG as the tag value.
818 */
819p_mesgout_tag:
820 test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte;
821 mov SCSIDAT, SINDEX; /* Send the identify message */
822 call phase_lock;
823 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done;
824 and SCSIDAT,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL;
825 call phase_lock;
826 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done;
827 mov SCBPTR jmp p_mesgout_onebyte;
828/*
829 * Interrupt the driver, and allow it to handle this message
830 * phase and any required retries.
831 */
832p_mesgout_from_host:
833 cmp SINDEX, HOST_MSG jne p_mesgout_onebyte;
834 jmp host_message_loop;
835
836p_mesgout_onebyte:
837 mvi CLRSINT1, CLRATNO;
838 mov SCSIDAT, SINDEX;
839
840/*
841 * If the next bus phase after ATN drops is message out, it means
842 * that the target is requesting that the last message(s) be resent.
843 */
844 call phase_lock;
845 cmp LASTPHASE, P_MESGOUT je p_mesgout_retry;
846
847p_mesgout_done:
848 mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */
849 mov LAST_MSG, MSG_OUT;
850 mvi MSG_OUT, MSG_NOOP; /* No message left */
851 jmp ITloop;
852
853/*
854 * Message in phase. Bytes are read using Automatic PIO mode.
855 */
856p_mesgin:
857 /* read the 1st message byte */
858 mvi ACCUM call inb_first;
859
860 test A,MSG_IDENTIFYFLAG jnz mesgin_identify;
861 cmp A,MSG_DISCONNECT je mesgin_disconnect;
862 cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs;
863 cmp ALLZEROS,A je mesgin_complete;
864 cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs;
865 cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_ign_wide_residue;
866 cmp A,MSG_NOOP je mesgin_done;
867
868/*
869 * Pushed message loop to allow the kernel to
870 * run it's own message state engine. To avoid an
871 * extra nop instruction after signaling the kernel,
872 * we perform the phase_lock before checking to see
873 * if we should exit the loop and skip the phase_lock
874 * in the ITloop. Performing back to back phase_locks
875 * shouldn't hurt, but why do it twice...
876 */
877host_message_loop:
878 call phase_lock; /* Benign the first time through. */
879 SET_SEQINTCODE(HOST_MSG_LOOP)
880 cmp RETURN_1, EXIT_MSG_LOOP je ITloop;
881 cmp RETURN_1, CONT_MSG_LOOP_WRITE jne . + 3;
882 mov SCSIDAT, RETURN_2;
883 jmp host_message_loop;
884 /* Must be CONT_MSG_LOOP_READ */
885 mov NONE, SCSIDAT; /* ACK Byte */
886 jmp host_message_loop;
887
888mesgin_ign_wide_residue:
889 mov SAVED_MODE, MODE_PTR;
890 SET_MODE(M_SCSI, M_SCSI)
891 shr NEGOADDR, 4, SAVED_SCSIID;
892 mov A, NEGCONOPTS;
893 RESTORE_MODE(SAVED_MODE)
894 test A, WIDEXFER jz mesgin_reject;
895 /* Pull the residue byte */
896 mvi REG0 call inb_next;
897 cmp REG0, 0x01 jne mesgin_reject;
898 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2;
899 test SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jnz mesgin_done;
900 SET_SEQINTCODE(IGN_WIDE_RES)
901 jmp mesgin_done;
902
903mesgin_proto_violation:
904 SET_SEQINTCODE(PROTO_VIOLATION)
905 jmp mesgin_done;
906mesgin_reject:
907 mvi MSG_MESSAGE_REJECT call mk_mesg;
908mesgin_done:
909 mov NONE,SCSIDAT; /*dummy read from latch to ACK*/
910 jmp ITloop;
911
912#define INDEX_DISC_LIST(scsiid, lun) \
913 and A, 0xC0, scsiid; \
914 or SCBPTR, A, lun; \
915 clr SCBPTR[1]; \
916 and SINDEX, 0x30, scsiid; \
917 shr SINDEX, 3; /* Multiply by 2 */ \
918 add SINDEX, (SCB_DISCONNECTED_LISTS & 0xFF); \
919 mvi SINDEX[1], ((SCB_DISCONNECTED_LISTS >> 8) & 0xFF)
920
921mesgin_identify:
922 /*
923 * Determine whether a target is using tagged or non-tagged
924 * transactions by first looking at the transaction stored in
925 * the per-device, disconnected array. If there is no untagged
926 * transaction for this target, this must be a tagged transaction.
927 */
928 and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A;
929 INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN);
930 bmov DINDEX, SINDEX, 2;
931 bmov REG0, SINDIR, 2;
932 cmp REG0[1], SCB_LIST_NULL je snoop_tag;
933 /* Untagged. Clear the busy table entry and setup the SCB. */
934 bmov DINDIR, ALLONES, 2;
935 bmov SCBPTR, REG0, 2;
936 jmp setup_SCB;
937
938/*
939 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message.
940 * If we get one, we use the tag returned to find the proper
941 * SCB. After receiving the tag, look for the SCB at SCB locations tag and
942 * tag + 256.
943 */
944snoop_tag:
945 if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {
946 or SEQ_FLAGS, 0x80;
947 }
948 mov NONE, SCSIDAT; /* ACK Identify MSG */
949 call phase_lock;
950 if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {
951 or SEQ_FLAGS, 0x1;
952 }
953 cmp LASTPHASE, P_MESGIN jne not_found_ITloop;
954 if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {
955 or SEQ_FLAGS, 0x2;
956 }
957 cmp SCSIBUS, MSG_SIMPLE_Q_TAG jne not_found;
958get_tag:
959 clr SCBPTR[1];
960 mvi SCBPTR call inb_next; /* tag value */
961verify_scb:
962 test SCB_CONTROL,DISCONNECTED jz verify_other_scb;
963 mov A, SAVED_SCSIID;
964 cmp SCB_SCSIID, A jne verify_other_scb;
965 mov A, SAVED_LUN;
966 cmp SCB_LUN, A je setup_SCB_disconnected;
967verify_other_scb:
968 xor SCBPTR[1], 1;
969 test SCBPTR[1], 0xFF jnz verify_scb;
970 jmp not_found;
971
972/*
973 * Ensure that the SCB the tag points to is for
974 * an SCB transaction to the reconnecting target.
975 */
976setup_SCB:
977 if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {
978 or SEQ_FLAGS, 0x10;
979 }
980 test SCB_CONTROL,DISCONNECTED jz not_found;
981setup_SCB_disconnected:
982 and SCB_CONTROL,~DISCONNECTED;
983 clr SEQ_FLAGS; /* make note of IDENTIFY */
984 test SCB_SGPTR, SG_LIST_NULL jnz . + 3;
985 bmov ALLOCFIFO_SCBPTR, SCBPTR, 2;
986 call allocate_fifo;
987 /* See if the host wants to send a message upon reconnection */
988 test SCB_CONTROL, MK_MESSAGE jz mesgin_done;
989 mvi HOST_MSG call mk_mesg;
990 jmp mesgin_done;
991
992not_found:
993 SET_SEQINTCODE(NO_MATCH)
994 jmp mesgin_done;
995
996not_found_ITloop:
997 SET_SEQINTCODE(NO_MATCH)
998 jmp ITloop;
999
1000/*
1001 * We received a "command complete" message. Put the SCB on the complete
1002 * queue and trigger a completion interrupt via the idle loop. Before doing
1003 * so, check to see if there
1004 * is a residual or the status byte is something other than STATUS_GOOD (0).
1005 * In either of these conditions, we upload the SCB back to the host so it can
1006 * process this information. In the case of a non zero status byte, we
1007 * additionally interrupt the kernel driver synchronously, allowing it to
1008 * decide if sense should be retrieved. If the kernel driver wishes to request
1009 * sense, it will fill the kernel SCB with a request sense command, requeue
1010 * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting
1011 * RETURN_1 to SEND_SENSE.
1012 */
1013mesgin_complete:
1014
1015 /*
1016 * If ATN is raised, we still want to give the target a message.
1017 * Perhaps there was a parity error on this last message byte.
1018 * Either way, the target should take us to message out phase
1019 * and then attempt to complete the command again. We should use a
1020 * critical section here to guard against a timeout triggering
1021 * for this command and setting ATN while we are still processing
1022 * the completion.
1023 test SCSISIGI, ATNI jnz mesgin_done;
1024 */
1025
1026 /*
1027 * If we are identified and have successfully sent the CDB,
1028 * any status will do. Optimize this fast path.
1029 */
1030 test SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation;
1031 test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted;
1032
1033 /*
1034 * If the target never sent an identify message but instead went
1035 * to mesgin to give an invalid message, let the host abort us.
1036 */
1037 test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation;
1038
1039 /*
1040 * If we recevied good status but never successfully sent the
1041 * cdb, abort the command.
1042 */
1043 test SCB_SCSI_STATUS,0xff jnz complete_accepted;
1044 test SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation;
1045complete_accepted:
1046
1047 /*
1048 * See if we attempted to deliver a message but the target ingnored us.
1049 */
1050 test SCB_CONTROL, MK_MESSAGE jz complete_nomsg;
1051 SET_SEQINTCODE(MKMSG_FAILED)
1052complete_nomsg:
1053 call queue_scb_completion;
1054 jmp await_busfree;
1055
1056freeze_queue:
1057 /* Cancel any pending select-out. */
1058 test SSTAT0, SELDO|SELINGO jnz . + 2;
1059 and SCSISEQ0, ~ENSELO;
1060 mov ACCUM_SAVE, A;
1061 clr A;
1062 add QFREEZE_COUNT, 1;
1063 adc QFREEZE_COUNT[1], A;
1064 or SEQ_FLAGS2, SELECTOUT_QFROZEN;
1065 mov A, ACCUM_SAVE ret;
1066
1067/*
1068 * Complete the current FIFO's SCB if data for this same
1069 * SCB is not transferring in the other FIFO.
1070 */
1071SET_SRC_MODE M_DFF1;
1072SET_DST_MODE M_DFF1;
1073pkt_complete_scb_if_fifos_idle:
1074 bmov ARG_1, SCBPTR, 2;
1075 mvi DFFSXFRCTL, CLRCHN;
1076 SET_MODE(M_SCSI, M_SCSI)
1077 bmov SCBPTR, ARG_1, 2;
1078 test SCB_FIFO_USE_COUNT, 0xFF jnz return;
1079queue_scb_completion:
1080 test SCB_SCSI_STATUS,0xff jnz bad_status;
1081 /*
1082 * Check for residuals
1083 */
1084 test SCB_SGPTR, SG_LIST_NULL jnz complete; /* No xfer */
1085 test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */
1086 test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb;
1087complete:
1088 bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
1089 bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
1090bad_status:
1091 cmp SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb;
1092 call freeze_queue;
1093upload_scb:
1094 /*
1095 * Restore SCB TAG since we reuse this field
1096 * in the sequencer. We don't want to corrupt
1097 * it on the host.
1098 */
1099 bmov SCB_TAG, SCBPTR, 2;
1100 bmov SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2;
1101 bmov COMPLETE_DMA_SCB_HEAD, SCBPTR, 2;
1102 or SCB_SGPTR, SG_STATUS_VALID ret;
1103
1104/*
1105 * Is it a disconnect message? Set a flag in the SCB to remind us
1106 * and await the bus going free. If this is an untagged transaction
1107 * store the SCB id for it in our untagged target table for lookup on
1108 * a reselction.
1109 */
1110mesgin_disconnect:
1111 /*
1112 * If ATN is raised, we still want to give the target a message.
1113 * Perhaps there was a parity error on this last message byte
1114 * or we want to abort this command. Either way, the target
1115 * should take us to message out phase and then attempt to
1116 * disconnect again.
1117 * XXX - Wait for more testing.
1118 test SCSISIGI, ATNI jnz mesgin_done;
1119 */
1120 test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT
1121 jnz mesgin_proto_violation;
1122 or SCB_CONTROL,DISCONNECTED;
1123 test SCB_CONTROL, TAG_ENB jnz await_busfree;
1124queue_disc_scb:
1125 bmov REG0, SCBPTR, 2;
1126 INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN);
1127 bmov DINDEX, SINDEX, 2;
1128 bmov DINDIR, REG0, 2;
1129 bmov SCBPTR, REG0, 2;
1130 /* FALLTHROUGH */
1131await_busfree:
1132 and SIMODE1, ~ENBUSFREE;
1133 if ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0) {
1134 /*
1135 * In the BUSFREEREV_BUG case, the
1136 * busfree status was cleared at the
1137 * beginning of the connection.
1138 */
1139 mvi CLRSINT1,CLRBUSFREE;
1140 }
1141 mov NONE, SCSIDAT; /* Ack the last byte */
1142 test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))
1143 jnz await_busfree_not_m_dff;
1144SET_SRC_MODE M_DFF1;
1145SET_DST_MODE M_DFF1;
1146await_busfree_clrchn:
1147 mvi DFFSXFRCTL, CLRCHN;
1148await_busfree_not_m_dff:
1149 call clear_target_state;
1150 test SSTAT1,REQINIT|BUSFREE jz .;
1151 test SSTAT1, BUSFREE jnz idle_loop;
1152 SET_SEQINTCODE(MISSED_BUSFREE)
1153
1154
1155/*
1156 * Save data pointers message:
1157 * Copying RAM values back to SCB, for Save Data Pointers message, but
1158 * only if we've actually been into a data phase to change them. This
1159 * protects against bogus data in scratch ram and the residual counts
1160 * since they are only initialized when we go into data_in or data_out.
1161 * Ack the message as soon as possible.
1162 */
1163SET_SRC_MODE M_DFF1;
1164SET_DST_MODE M_DFF1;
1165mesgin_sdptrs:
1166 mov NONE,SCSIDAT; /*dummy read from latch to ACK*/
1167 test SEQ_FLAGS, DPHASE jz ITloop;
1168 call save_pointers;
1169 jmp ITloop;
1170
1171save_pointers:
1172 /*
1173 * If we are asked to save our position at the end of the
1174 * transfer, just mark us at the end rather than perform a
1175 * full save.
1176 */
1177 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz save_pointers_full;
1178 or SCB_SGPTR, SG_LIST_NULL ret;
1179
1180save_pointers_full:
1181 /*
1182 * The SCB_DATAPTR becomes the current SHADDR.
1183 * All other information comes directly from our residual
1184 * state.
1185 */
1186 bmov SCB_DATAPTR, SHADDR, 8;
1187 bmov SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8 ret;
1188
1189/*
1190 * Restore pointers message? Data pointers are recopied from the
1191 * SCB anytime we enter a data phase for the first time, so all
1192 * we need to do is clear the DPHASE flag and let the data phase
1193 * code do the rest. We also reset/reallocate the FIFO to make
1194 * sure we have a clean start for the next data or command phase.
1195 */
1196mesgin_rdptrs:
1197 and SEQ_FLAGS, ~DPHASE;
1198 test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz msgin_rdptrs_get_fifo;
1199 mvi DFFSXFRCTL, RSTCHN|CLRSHCNT;
1200 SET_MODE(M_SCSI, M_SCSI)
1201msgin_rdptrs_get_fifo:
1202 call allocate_fifo;
1203 jmp mesgin_done;
1204
1205clear_target_state:
1206 mvi LASTPHASE, P_BUSFREE;
1207 /* clear target specific flags */
1208 mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret;
1209
1210phase_lock:
1211 if ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0) {
1212 /*
1213 * Don't ignore persistent REQ assertions just because
1214 * they were asserted within the bus settle delay window.
1215 * This allows us to tolerate devices like the GEM318
1216 * that violate the SCSI spec. We are careful not to
1217 * count REQ while we are waiting for it to fall during
1218 * an async phase due to our asserted ACK. Each
1219 * sequencer instruction takes ~25ns, so the REQ must
1220 * last at least 100ns in order to be counted as a true
1221 * REQ.
1222 */
1223 test SCSIPHASE, 0xFF jnz phase_locked;
1224 test SCSISIGI, ACKI jnz phase_lock;
1225 test SCSISIGI, REQI jz phase_lock;
1226 test SCSIPHASE, 0xFF jnz phase_locked;
1227 test SCSISIGI, ACKI jnz phase_lock;
1228 test SCSISIGI, REQI jz phase_lock;
1229phase_locked:
1230 } else {
1231 test SCSIPHASE, 0xFF jz .;
1232 }
1233 test SSTAT1, SCSIPERR jnz phase_lock;
1234phase_lock_latch_phase:
1235 and LASTPHASE, PHASE_MASK, SCSISIGI ret;
1236
1237/*
1238 * Functions to read data in Automatic PIO mode.
1239 *
1240 * An ACK is not sent on input from the target until SCSIDATL is read from.
1241 * So we wait until SCSIDATL is latched (the usual way), then read the data
1242 * byte directly off the bus using SCSIBUSL. When we have pulled the ATN
1243 * line, or we just want to acknowledge the byte, then we do a dummy read
1244 * from SCISDATL. The SCSI spec guarantees that the target will hold the
1245 * data byte on the bus until we send our ACK.
1246 *
1247 * The assumption here is that these are called in a particular sequence,
1248 * and that REQ is already set when inb_first is called. inb_{first,next}
1249 * use the same calling convention as inb.
1250 */
1251inb_next:
1252 mov NONE,SCSIDAT; /*dummy read from latch to ACK*/
1253inb_next_wait:
1254 /*
1255 * If there is a parity error, wait for the kernel to
1256 * see the interrupt and prepare our message response
1257 * before continuing.
1258 */
1259 test SCSIPHASE, 0xFF jz .;
1260 test SSTAT1, SCSIPERR jnz inb_next_wait;
1261inb_next_check_phase:
1262 and LASTPHASE, PHASE_MASK, SCSISIGI;
1263 cmp LASTPHASE, P_MESGIN jne mesgin_phasemis;
1264inb_first:
1265 clr DINDEX[1];
1266 mov DINDEX,SINDEX;
1267 mov DINDIR,SCSIBUS ret; /*read byte directly from bus*/
1268inb_last:
1269 mov NONE,SCSIDAT ret; /*dummy read from latch to ACK*/
1270
1271mk_mesg:
1272 mvi SCSISIGO, ATNO;
1273 mov MSG_OUT,SINDEX ret;
1274
1275SET_SRC_MODE M_DFF1;
1276SET_DST_MODE M_DFF1;
1277disable_ccsgen:
1278 test SG_STATE, FETCH_INPROG jz disable_ccsgen_fetch_done;
1279 clr CCSGCTL;
1280disable_ccsgen_fetch_done:
1281 clr SG_STATE ret;
1282
1283service_fifo:
1284 /*
1285 * Do we have any prefetch left???
1286 */
1287 test SG_STATE, SEGS_AVAIL jnz idle_sg_avail;
1288
1289 /*
1290 * Can this FIFO have access to the S/G cache yet?
1291 */
1292 test CCSGCTL, SG_CACHE_AVAIL jz return;
1293
1294 /* Did we just finish fetching segs? */
1295 test CCSGCTL, CCSGDONE jnz idle_sgfetch_complete;
1296
1297 /* Are we actively fetching segments? */
1298 test CCSGCTL, CCSGENACK jnz return;
1299
1300 /*
1301 * We fetch a "cacheline aligned" and sized amount of data
1302 * so we don't end up referencing a non-existant page.
1303 * Cacheline aligned is in quotes because the kernel will
1304 * set the prefetch amount to a reasonable level if the
1305 * cacheline size is unknown.
1306 */
1307 bmov SGHADDR, SCB_RESIDUAL_SGPTR, 4;
1308 mvi SGHCNT, SG_PREFETCH_CNT;
1309 if ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0) {
1310 /*
1311 * Need two instruction between "touches" of SGHADDR.
1312 */
1313 nop;
1314 }
1315 and SGHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR;
1316 mvi CCSGCTL, CCSGEN|CCSGRESET;
1317 or SG_STATE, FETCH_INPROG ret;
1318idle_sgfetch_complete:
1319 /*
1320 * Guard against SG_CACHE_AVAIL activating during sg fetch
1321 * request in the other FIFO.
1322 */
1323 test SG_STATE, FETCH_INPROG jz return;
1324 clr CCSGCTL;
1325 and CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR;
1326 mvi SG_STATE, SEGS_AVAIL|LOADING_NEEDED;
1327idle_sg_avail:
1328 /* Does the hardware have space for another SG entry? */
1329 test DFSTATUS, PRELOAD_AVAIL jz return;
1330 /*
1331 * On the A, preloading a segment before HDMAENACK
1332 * comes true can clobber the shaddow address of the
1333 * first segment in the S/G FIFO. Wait until it is
1334 * safe to proceed.
1335 */
1336 if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0) {
1337 test DFCNTRL, HDMAENACK jz return;
1338 }
1339 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
1340 bmov HADDR, CCSGRAM, 8;
1341 } else {
1342 bmov HADDR, CCSGRAM, 4;
1343 }
1344 bmov HCNT, CCSGRAM, 3;
1345 bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
1346 if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
1347 and HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3];
1348 }
1349 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
1350 /* Skip 4 bytes of pad. */
1351 add CCSGADDR, 4;
1352 }
1353sg_advance:
1354 clr A; /* add sizeof(struct scatter) */
1355 add SCB_RESIDUAL_SGPTR[0],SG_SIZEOF;
1356 adc SCB_RESIDUAL_SGPTR[1],A;
1357 adc SCB_RESIDUAL_SGPTR[2],A;
1358 adc SCB_RESIDUAL_SGPTR[3],A;
1359 mov SINDEX, SCB_RESIDUAL_SGPTR[0];
1360 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 3;
1361 or SINDEX, LAST_SEG;
1362 clr SG_STATE;
1363 mov SG_CACHE_PRE, SINDEX;
1364 if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0) {
1365 /*
1366 * Use SCSIENWRDIS so that SCSIEN is never
1367 * modified by this operation.
1368 */
1369 or DFCNTRL, PRELOADEN|HDMAEN|SCSIENWRDIS;
1370 } else {
1371 or DFCNTRL, PRELOADEN|HDMAEN;
1372 }
1373 /*
1374 * Do we have another segment in the cache?
1375 */
1376 add NONE, SG_PREFETCH_CNT_LIMIT, CCSGADDR;
1377 jnc return;
1378 and SG_STATE, ~SEGS_AVAIL ret;
1379
1380/*
1381 * Initialize the DMA address and counter from the SCB.
1382 */
1383load_first_seg:
1384 bmov HADDR, SCB_DATAPTR, 11;
1385 and REG_ISR, ~SG_FULL_RESID, SCB_SGPTR[0];
1386 test SCB_DATACNT[3], SG_LAST_SEG jz . + 2;
1387 or REG_ISR, LAST_SEG;
1388 mov SG_CACHE_PRE, REG_ISR;
1389 mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);
1390 /*
1391 * Since we've are entering a data phase, we will
1392 * rely on the SCB_RESID* fields. Initialize the
1393 * residual and clear the full residual flag.
1394 */
1395 and SCB_SGPTR[0], ~SG_FULL_RESID;
1396 bmov SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5;
1397 /* If we need more S/G elements, tell the idle loop */
1398 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz . + 2;
1399 mvi SG_STATE, LOADING_NEEDED ret;
1400 clr SG_STATE ret;
1401
1402p_data_handle_xfer:
1403 call setjmp;
1404 test SG_STATE, LOADING_NEEDED jnz service_fifo;
1405p_data_clear_handler:
1406 or LONGJMP_ADDR[1], INVALID_ADDR ret;
1407
1408p_data:
1409 test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed;
1410 SET_SEQINTCODE(PROTO_VIOLATION)
1411p_data_allowed:
1412
1413 test SEQ_FLAGS, DPHASE jz data_phase_initialize;
1414
1415 /*
1416 * If we re-enter the data phase after going through another
1417 * phase, our transfer location has almost certainly been
1418 * corrupted by the interveining, non-data, transfers. Ask
1419 * the host driver to fix us up based on the transfer residual
1420 * unless we already know that we should be bitbucketing.
1421 */
1422 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket;
1423 SET_SEQINTCODE(PDATA_REINIT)
1424 jmp data_phase_inbounds;
1425
1426p_data_bitbucket:
1427 /*
1428 * Turn on `Bit Bucket' mode, wait until the target takes
1429 * us to another phase, and then notify the host.
1430 */
1431 mov SAVED_MODE, MODE_PTR;
1432 test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))
1433 jnz bitbucket_not_m_dff;
1434 /*
1435 * Ensure that any FIFO contents are cleared out and the
1436 * FIFO free'd prior to starting the BITBUCKET. BITBUCKET
1437 * doesn't discard data already in the FIFO.
1438 */
1439 mvi DFFSXFRCTL, RSTCHN|CLRSHCNT;
1440 SET_MODE(M_SCSI, M_SCSI)
1441bitbucket_not_m_dff:
1442 or SXFRCTL1,BITBUCKET;
1443 /* Wait for non-data phase. */
1444 test SCSIPHASE, ~DATA_PHASE_MASK jz .;
1445 and SXFRCTL1, ~BITBUCKET;
1446 RESTORE_MODE(SAVED_MODE)
1447SET_SRC_MODE M_DFF1;
1448SET_DST_MODE M_DFF1;
1449 SET_SEQINTCODE(DATA_OVERRUN)
1450 jmp ITloop;
1451
1452data_phase_initialize:
1453 test SCB_SGPTR[0], SG_LIST_NULL jnz p_data_bitbucket;
1454 call load_first_seg;
1455data_phase_inbounds:
1456 /* We have seen a data phase at least once. */
1457 or SEQ_FLAGS, DPHASE;
1458 mov SAVED_MODE, MODE_PTR;
1459 test SG_STATE, LOADING_NEEDED jz data_group_dma_loop;
1460 call p_data_handle_xfer;
1461data_group_dma_loop:
1462 /*
1463 * The transfer is complete if either the last segment
1464 * completes or the target changes phase. Both conditions
1465 * will clear SCSIEN.
1466 */
1467 call idle_loop_service_fifos;
1468 call idle_loop_cchan;
1469 call idle_loop_gsfifo;
1470 RESTORE_MODE(SAVED_MODE)
1471 test DFCNTRL, SCSIEN jnz data_group_dma_loop;
1472
1473data_group_dmafinish:
1474 /*
1475 * The transfer has terminated either due to a phase
1476 * change, and/or the completion of the last segment.
1477 * We have two goals here. Do as much other work
1478 * as possible while the data fifo drains on a read
1479 * and respond as quickly as possible to the standard
1480 * messages (save data pointers/disconnect and command
1481 * complete) that usually follow a data phase.
1482 */
1483 call calc_residual;
1484
1485 /*
1486 * Go ahead and shut down the DMA engine now.
1487 */
1488 test DFCNTRL, DIRECTION jnz data_phase_finish;
1489data_group_fifoflush:
1490 if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {
1491 or DFCNTRL, FIFOFLUSH;
1492 }
1493 /*
1494 * We have enabled the auto-ack feature. This means
1495 * that the controller may have already transferred
1496 * some overrun bytes into the data FIFO and acked them
1497 * on the bus. The only way to detect this situation is
1498 * to wait for LAST_SEG_DONE to come true on a completed
1499 * transfer and then test to see if the data FIFO is
1500 * non-empty. We know there is more data yet to transfer
1501 * if SG_LIST_NULL is not yet set, thus there cannot be
1502 * an overrun.
1503 */
1504 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_finish;
1505 test SG_CACHE_SHADOW, LAST_SEG_DONE jz .;
1506 test DFSTATUS, FIFOEMP jnz data_phase_finish;
1507 /* Overrun */
1508 jmp p_data;
1509data_phase_finish:
1510 /*
1511 * If the target has left us in data phase, loop through
1512 * the dma code again. We will only loop if there is a
1513 * data overrun.
1514 */
1515 if ((ahd->flags & AHD_TARGETROLE) != 0) {
1516 test SSTAT0, TARGET jnz data_phase_done;
1517 }
1518 if ((ahd->flags & AHD_INITIATORROLE) != 0) {
1519 test SSTAT1, REQINIT jz .;
1520 test SCSIPHASE, DATA_PHASE_MASK jnz p_data;
1521 }
1522
1523data_phase_done:
1524 /* Kill off any pending prefetch */
1525 call disable_ccsgen;
1526 or LONGJMP_ADDR[1], INVALID_ADDR;
1527
1528 if ((ahd->flags & AHD_TARGETROLE) != 0) {
1529 test SEQ_FLAGS, DPHASE_PENDING jz ITloop;
1530 /*
1531 and SEQ_FLAGS, ~DPHASE_PENDING;
1532 * For data-in phases, wait for any pending acks from the
1533 * initiator before changing phase. We only need to
1534 * send Ignore Wide Residue messages for data-in phases.
1535 test DFCNTRL, DIRECTION jz target_ITloop;
1536 test SSTAT1, REQINIT jnz .;
1537 test SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jz target_ITloop;
1538 SET_MODE(M_SCSI, M_SCSI)
1539 test NEGCONOPTS, WIDEXFER jz target_ITloop;
1540 */
1541 /*
1542 * Issue an Ignore Wide Residue Message.
1543 mvi P_MESGIN|BSYO call change_phase;
1544 mvi MSG_IGN_WIDE_RESIDUE call target_outb;
1545 mvi 1 call target_outb;
1546 jmp target_ITloop;
1547 */
1548 } else {
1549 jmp ITloop;
1550 }
1551
1552/*
1553 * We assume that, even though data may still be
1554 * transferring to the host, that the SCSI side of
1555 * the DMA engine is now in a static state. This
1556 * allows us to update our notion of where we are
1557 * in this transfer.
1558 *
1559 * If, by chance, we stopped before being able
1560 * to fetch additional segments for this transfer,
1561 * yet the last S/G was completely exhausted,
1562 * call our idle loop until it is able to load
1563 * another segment. This will allow us to immediately
1564 * pickup on the next segment on the next data phase.
1565 *
1566 * If we happened to stop on the last segment, then
1567 * our residual information is still correct from
1568 * the idle loop and there is no need to perform
1569 * any fixups.
1570 */
1571residual_before_last_seg:
1572 test MDFFSTAT, SHVALID jnz sgptr_fixup;
1573 /*
1574 * Can never happen from an interrupt as the packetized
1575 * hardware will only interrupt us once SHVALID or
1576 * LAST_SEG_DONE.
1577 */
1578 call idle_loop_service_fifos;
1579 RESTORE_MODE(SAVED_MODE)
1580 /* FALLTHROUGH */
1581calc_residual:
1582 test SG_CACHE_SHADOW, LAST_SEG jz residual_before_last_seg;
1583 /* Record if we've consumed all S/G entries */
1584 test MDFFSTAT, SHVALID jz . + 2;
1585 bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret;
1586 or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL ret;
1587
1588sgptr_fixup:
1589 /*
1590 * Fixup the residual next S/G pointer. The S/G preload
1591 * feature of the chip allows us to load two elements
1592 * in addition to the currently active element. We
1593 * store the bottom byte of the next S/G pointer in
1594 * the SG_CACHE_PTR register so we can restore the
1595 * correct value when the DMA completes. If the next
1596 * sg ptr value has advanced to the point where higher
1597 * bytes in the address have been affected, fix them
1598 * too.
1599 */
1600 test SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done;
1601 test SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done;
1602 add SCB_RESIDUAL_SGPTR[1], -1;
1603 adc SCB_RESIDUAL_SGPTR[2], -1;
1604 adc SCB_RESIDUAL_SGPTR[3], -1;
1605sgptr_fixup_done:
1606 and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW;
1607 clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */
1608 bmov SCB_RESIDUAL_DATACNT, SHCNT, 3 ret;
1609
1610export timer_isr:
1611 call issue_cmdcmplt;
1612 mvi CLRSEQINTSTAT, CLRSEQ_SWTMRTO;
1613 if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) {
1614 /*
1615 * In H2A4, the mode pointer is not saved
1616 * for intvec2, but is restored on iret.
1617 * This can lead to the restoration of a
1618 * bogus mode ptr. Manually clear the
1619 * intmask bits and do a normal return
1620 * to compensate.
1621 */
1622 and SEQINTCTL, ~(INTMASK2|INTMASK1) ret;
1623 } else {
1624 or SEQINTCTL, IRET ret;
1625 }
1626
1627export seq_isr:
1628 if ((ahd->features & AHD_RTI) == 0) {
1629 /*
1630 * On RevA Silicon, if the target returns us to data-out
1631 * after we have already trained for data-out, it is
1632 * possible for us to transition the free running clock to
1633 * data-valid before the required 100ns P1 setup time (8 P1
1634 * assertions in fast-160 mode). This will only happen if
1635 * this L-Q is a continuation of a data transfer for which
1636 * we have already prefetched data into our FIFO (LQ/Data
1637 * followed by LQ/Data for the same write transaction).
1638 * This can cause some target implementations to miss the
1639 * first few data transfers on the bus. We detect this
1640 * situation by noticing that this is the first data transfer
1641 * after an LQ (LQIWORKONLQ true), that the data transfer is
1642 * a continuation of a transfer already setup in our FIFO
1643 * (SAVEPTRS interrupt), and that the transaction is a write
1644 * (DIRECTION set in DFCNTRL). The delay is performed by
1645 * disabling SCSIEN until we see the first REQ from the
1646 * target.
1647 *
1648 * First instruction in an ISR cannot be a branch on
1649 * Rev A. Snapshot LQISTAT2 so the status is not missed
1650 * and deffer the test by one instruction.
1651 */
1652 mov REG_ISR, LQISTAT2;
1653 test REG_ISR, LQIWORKONLQ jz main_isr;
1654 test SEQINTSRC, SAVEPTRS jz main_isr;
1655 test LONGJMP_ADDR[1], INVALID_ADDR jz saveptr_active_fifo;
1656 /*
1657 * Switch to the active FIFO after clearing the snapshot
1658 * savepointer in the current FIFO. We do this so that
1659 * a pending CTXTDONE or SAVEPTR is visible in the active
1660 * FIFO. This status is the only way we can detect if we
1661 * have lost the race (e.g. host paused us) and our attepts
1662 * to disable the channel occurred after all REQs were
1663 * already seen and acked (REQINIT never comes true).
1664 */
1665 mvi DFFSXFRCTL, CLRCHN;
1666 xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1);
1667 test DFCNTRL, DIRECTION jz interrupt_return;
1668 and DFCNTRL, ~SCSIEN;
1669snapshot_wait_data_valid:
1670 test SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz snapshot_data_valid;
1671 test SSTAT1, REQINIT jz snapshot_wait_data_valid;
1672snapshot_data_valid:
1673 or DFCNTRL, SCSIEN;
1674 or SEQINTCTL, IRET ret;
1675snapshot_saveptr:
1676 mvi DFFSXFRCTL, CLRCHN;
1677 or SEQINTCTL, IRET ret;
1678main_isr:
1679 }
1680 test SEQINTSRC, CFG4DATA jnz cfg4data_intr;
1681 test SEQINTSRC, CFG4ISTAT jnz cfg4istat_intr;
1682 test SEQINTSRC, SAVEPTRS jnz saveptr_intr;
1683 test SEQINTSRC, CFG4ICMD jnz cfg4icmd_intr;
1684 SET_SEQINTCODE(INVALID_SEQINT)
1685
1686/*
1687 * There are two types of save pointers interrupts:
1688 * The first is a snapshot save pointers where the current FIFO is not
1689 * active and contains a snapshot of the current poniter information.
1690 * This happens between packets in a stream for a single L_Q. Since we
1691 * are not performing a pointer save, we can safely clear the channel
1692 * so it can be used for other transactions. On RTI capable controllers,
1693 * where snapshots can, and are, disabled, the code to handle this type
1694 * of snapshot is not active.
1695 *
1696 * The second case is a save pointers on an active FIFO which occurs
1697 * if the target changes to a new L_Q or busfrees/QASes and the transfer
1698 * has a residual. This should occur coincident with a ctxtdone. We
1699 * disable the interrupt and allow our active routine to handle the
1700 * save.
1701 */
1702saveptr_intr:
1703 if ((ahd->features & AHD_RTI) == 0) {
1704 test LONGJMP_ADDR[1], INVALID_ADDR jnz snapshot_saveptr;
1705 }
1706saveptr_active_fifo:
1707 and SEQIMODE, ~ENSAVEPTRS;
1708 or SEQINTCTL, IRET ret;
1709
1710cfg4data_intr:
1711 test SCB_SGPTR[0], SG_LIST_NULL jnz pkt_handle_overrun_inc_use_count;
1712 call load_first_seg;
1713 call pkt_handle_xfer;
1714 inc SCB_FIFO_USE_COUNT;
1715interrupt_return:
1716 or SEQINTCTL, IRET ret;
1717
1718cfg4istat_intr:
1719 call freeze_queue;
1720 add NONE, -13, SCB_CDB_LEN;
1721 jnc cfg4istat_have_sense_addr;
1722 test SCB_CDB_LEN, SCB_CDB_LEN_PTR jnz cfg4istat_have_sense_addr;
1723 /*
1724 * Host sets up address/count and enables transfer.
1725 */
1726 SET_SEQINTCODE(CFG4ISTAT_INTR)
1727 jmp cfg4istat_setup_handler;
1728cfg4istat_have_sense_addr:
1729 bmov HADDR, SCB_SENSE_BUSADDR, 4;
1730 mvi HCNT[1], (AHD_SENSE_BUFSIZE >> 8);
1731 mvi SG_CACHE_PRE, LAST_SEG;
1732 mvi DFCNTRL, PRELOADEN|SCSIEN|HDMAEN;
1733cfg4istat_setup_handler:
1734 /*
1735 * Status pkt is transferring to host.
1736 * Wait in idle loop for transfer to complete.
1737 * If a command completed before an attempted
1738 * task management function completed, notify the host.
1739 */
1740 test SCB_TASK_MANAGEMENT, 0xFF jz cfg4istat_no_taskmgmt_func;
1741 SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY)
1742cfg4istat_no_taskmgmt_func:
1743 call pkt_handle_status;
1744 or SEQINTCTL, IRET ret;
1745
1746cfg4icmd_intr:
1747 /*
1748 * In the case of DMAing a CDB from the host, the normal
1749 * CDB buffer is formatted with an 8 byte address followed
1750 * by a 1 byte count.
1751 */
1752 bmov HADDR[0], SCB_HOST_CDB_PTR, 9;
1753 mvi SG_CACHE_PRE, LAST_SEG;
1754 mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);
1755 call pkt_handle_cdb;
1756 or SEQINTCTL, IRET ret;
1757
1758/*
1759 * See if the target has gone on in this context creating an
1760 * overrun condition. For the write case, the hardware cannot
1761 * ack bytes until data are provided. So, if the target begins
1762 * another packet without changing contexts, implying we are
1763 * not sitting on a packet boundary, we are in an overrun
1764 * situation. For the read case, the hardware will continue to
1765 * ack bytes into the FIFO, and may even ack the last overrun packet
1766 * into the FIFO. If the FIFO should become non-empty, we are in
1767 * a read overrun case.
1768 */
1769#define check_overrun \
1770 /* Not on a packet boundary. */ \
1771 test MDFFSTAT, DLZERO jz pkt_handle_overrun; \
1772 test DFSTATUS, FIFOEMP jz pkt_handle_overrun
1773
1774pkt_handle_xfer:
1775 test SG_STATE, LOADING_NEEDED jz pkt_last_seg;
1776 call setjmp;
1777 test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs;
1778 test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2;
1779 test SCSISIGO, ATNO jnz . + 2;
1780 test SSTAT2, NONPACKREQ jz pkt_service_fifo;
1781 /*
1782 * Defer handling of this NONPACKREQ until we
1783 * can be sure it pertains to this FIFO. SAVEPTRS
1784 * will not be asserted if the NONPACKREQ is for us,
1785 * so we must simulate it if shaddow is valid. If
1786 * shaddow is not valid, keep running this FIFO until we
1787 * have satisfied the transfer by loading segments and
1788 * waiting for either shaddow valid or last_seg_done.
1789 */
1790 test MDFFSTAT, SHVALID jnz pkt_saveptrs;
1791pkt_service_fifo:
1792 test SG_STATE, LOADING_NEEDED jnz service_fifo;
1793pkt_last_seg:
1794 call setjmp;
1795 test SEQINTSRC, SAVEPTRS jnz pkt_saveptrs;
1796 test SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_last_seg_done;
1797 test SCSIPHASE, ~DATA_PHASE_MASK jz . + 2;
1798 test SCSISIGO, ATNO jnz . + 2;
1799 test SSTAT2, NONPACKREQ jz return;
1800 test MDFFSTAT, SHVALID jz return;
1801 /* FALLTHROUGH */
1802
1803/*
1804 * Either a SAVEPTRS interrupt condition is pending for this FIFO
1805 * or we have a pending NONPACKREQ for this FIFO. We differentiate
1806 * between the two by capturing the state of the SAVEPTRS interrupt
1807 * prior to clearing this status and executing the common code for
1808 * these two cases.
1809 */
1810pkt_saveptrs:
1811BEGIN_CRITICAL;
1812 if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {
1813 or DFCNTRL, FIFOFLUSH;
1814 }
1815 mov REG0, SEQINTSRC;
1816 call calc_residual;
1817 call save_pointers;
1818 mvi CLRSEQINTSRC, CLRSAVEPTRS;
1819 call disable_ccsgen;
1820 or SEQIMODE, ENSAVEPTRS;
1821 test DFCNTRL, DIRECTION jnz pkt_saveptrs_check_status;
1822 test DFSTATUS, FIFOEMP jnz pkt_saveptrs_check_status;
1823 /*
1824 * Keep a handler around for this FIFO until it drains
1825 * to the host to guarantee that we don't complete the
1826 * command to the host before the data arrives.
1827 */
1828pkt_saveptrs_wait_fifoemp:
1829 call setjmp;
1830 test DFSTATUS, FIFOEMP jz return;
1831pkt_saveptrs_check_status:
1832 or LONGJMP_ADDR[1], INVALID_ADDR;
1833 test REG0, SAVEPTRS jz unexpected_nonpkt_phase;
1834 dec SCB_FIFO_USE_COUNT;
1835 test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;
1836 mvi DFFSXFRCTL, CLRCHN ret;
1837END_CRITICAL;
1838
1839/*
1840 * LAST_SEG_DONE status has been seen in the current FIFO.
1841 * This indicates that all of the allowed data for this
1842 * command has transferred across the SCSI and host buses.
1843 * Check for overrun and see if we can complete this command.
1844 */
1845pkt_last_seg_done:
1846BEGIN_CRITICAL;
1847 /*
1848 * Mark transfer as completed.
1849 */
1850 or SCB_SGPTR, SG_LIST_NULL;
1851
1852 /*
1853 * Wait for the current context to finish to verify that
1854 * no overrun condition has occurred.
1855 */
1856 test SEQINTSRC, CTXTDONE jnz pkt_ctxt_done;
1857 call setjmp;
1858pkt_wait_ctxt_done_loop:
1859 test SEQINTSRC, CTXTDONE jnz pkt_ctxt_done;
1860 /*
1861 * A sufficiently large overrun or a NONPACKREQ may
1862 * prevent CTXTDONE from ever asserting, so we must
1863 * poll for these statuses too.
1864 */
1865 check_overrun;
1866 test SSTAT2, NONPACKREQ jz return;
1867 test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase;
1868 /* FALLTHROUGH */
1869
1870pkt_ctxt_done:
1871 check_overrun;
1872 or LONGJMP_ADDR[1], INVALID_ADDR;
1873 /*
1874 * If status has been received, it is safe to skip
1875 * the check to see if another FIFO is active because
1876 * LAST_SEG_DONE has been observed. However, we check
1877 * the FIFO anyway since it costs us only one extra
1878 * instruction to leverage common code to perform the
1879 * SCB completion.
1880 */
1881 dec SCB_FIFO_USE_COUNT;
1882 test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;
1883 mvi DFFSXFRCTL, CLRCHN ret;
1884END_CRITICAL;
1885
1886/*
1887 * Must wait until CDB xfer is over before issuing the
1888 * clear channel.
1889 */
1890pkt_handle_cdb:
1891 call setjmp;
1892 test SG_CACHE_SHADOW, LAST_SEG_DONE jz return;
1893 or LONGJMP_ADDR[1], INVALID_ADDR;
1894 mvi DFFSXFRCTL, CLRCHN ret;
1895
1896/*
1897 * Watch over the status transfer. Our host sense buffer is
1898 * large enough to take the maximum allowed status packet.
1899 * None-the-less, we must still catch and report overruns to
1900 * the host. Additionally, properly catch unexpected non-packet
1901 * phases that are typically caused by CRC errors in status packet
1902 * transmission.
1903 */
1904pkt_handle_status:
1905 call setjmp;
1906 test SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_status_check_overrun;
1907 test SEQINTSRC, CTXTDONE jz pkt_status_check_nonpackreq;
1908 test SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_status_check_overrun;
1909pkt_status_IU_done:
1910 if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {
1911 or DFCNTRL, FIFOFLUSH;
1912 }
1913 test DFSTATUS, FIFOEMP jz return;
1914BEGIN_CRITICAL;
1915 or LONGJMP_ADDR[1], INVALID_ADDR;
1916 mvi SCB_SCSI_STATUS, STATUS_PKT_SENSE;
1917 or SCB_CONTROL, STATUS_RCVD;
1918 jmp pkt_complete_scb_if_fifos_idle;
1919END_CRITICAL;
1920pkt_status_check_overrun:
1921 /*
1922 * Status PKT overruns are uncerimoniously recovered with a
1923 * bus reset. If we've overrun, let the host know so that
1924 * recovery can be performed.
1925 *
1926 * LAST_SEG_DONE has been observed. If either CTXTDONE or
1927 * a NONPACKREQ phase change have occurred and the FIFO is
1928 * empty, there is no overrun.
1929 */
1930 test DFSTATUS, FIFOEMP jz pkt_status_report_overrun;
1931 test SEQINTSRC, CTXTDONE jz . + 2;
1932 test DFSTATUS, FIFOEMP jnz pkt_status_IU_done;
1933 test SCSIPHASE, ~DATA_PHASE_MASK jz return;
1934 test DFSTATUS, FIFOEMP jnz pkt_status_check_nonpackreq;
1935pkt_status_report_overrun:
1936 SET_SEQINTCODE(STATUS_OVERRUN)
1937 /* SEQUENCER RESTARTED */
1938pkt_status_check_nonpackreq:
1939 /*
1940 * CTXTDONE may be held off if a NONPACKREQ is associated with
1941 * the current context. If a NONPACKREQ is observed, decide
1942 * if it is for the current context. If it is for the current
1943 * context, we must defer NONPACKREQ processing until all data
1944 * has transferred to the host.
1945 */
1946 test SCSIPHASE, ~DATA_PHASE_MASK jz return;
1947 test SCSISIGO, ATNO jnz . + 2;
1948 test SSTAT2, NONPACKREQ jz return;
1949 test SEQINTSRC, CTXTDONE jnz pkt_status_IU_done;
1950 test DFSTATUS, FIFOEMP jz return;
1951 /*
1952 * The unexpected nonpkt phase handler assumes that any
1953 * data channel use will have a FIFO reference count. It
1954 * turns out that the status handler doesn't need a refernce
1955 * count since the status received flag, and thus completion
1956 * processing, cannot be set until the handler is finished.
1957 * We increment the count here to make the nonpkt handler
1958 * happy.
1959 */
1960 inc SCB_FIFO_USE_COUNT;
1961 /* FALLTHROUGH */
1962
1963/*
1964 * Nonpackreq is a polled status. It can come true in three situations:
1965 * we have received an L_Q, we have sent one or more L_Qs, or there is no
1966 * L_Q context associated with this REQ (REQ occurs immediately after a
1967 * (re)selection). Routines that know that the context responsible for this
1968 * nonpackreq call directly into unexpected_nonpkt_phase. In the case of the
1969 * top level idle loop, we exhaust all active contexts prior to determining that
1970 * we simply do not have the full I_T_L_Q for this phase.
1971 */
1972unexpected_nonpkt_phase_find_ctxt:
1973 /*
1974 * This nonpackreq is most likely associated with one of the tags
1975 * in a FIFO or an outgoing LQ. Only treat it as an I_T only
1976 * nonpackreq if we've cleared out the FIFOs and handled any
1977 * pending SELDO.
1978 */
1979SET_SRC_MODE M_SCSI;
1980SET_DST_MODE M_SCSI;
1981 and A, FIFO1FREE|FIFO0FREE, DFFSTAT;
1982 cmp A, FIFO1FREE|FIFO0FREE jne return;
1983 test SSTAT0, SELDO jnz return;
1984 mvi SCBPTR[1], SCB_LIST_NULL;
1985unexpected_nonpkt_phase:
1986 test MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))
1987 jnz unexpected_nonpkt_mode_cleared;
1988SET_SRC_MODE M_DFF0;
1989SET_DST_MODE M_DFF0;
1990 or LONGJMP_ADDR[1], INVALID_ADDR;
1991 dec SCB_FIFO_USE_COUNT;
1992 mvi DFFSXFRCTL, CLRCHN;
1993unexpected_nonpkt_mode_cleared:
1994 mvi CLRSINT2, CLRNONPACKREQ;
1995 test SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase;
1996 SET_SEQINTCODE(ENTERING_NONPACK)
1997 jmp ITloop;
1998
1999illegal_phase:
2000 SET_SEQINTCODE(ILLEGAL_PHASE)
2001 jmp ITloop;
2002
2003/*
2004 * We have entered an overrun situation. If we have working
2005 * BITBUCKET, flip that on and let the hardware eat any overrun
2006 * data. Otherwise use an overrun buffer in the host to simulate
2007 * BITBUCKET.
2008 */
2009pkt_handle_overrun_inc_use_count:
2010 inc SCB_FIFO_USE_COUNT;
2011pkt_handle_overrun:
2012 SET_SEQINTCODE(CFG4OVERRUN)
2013 call freeze_queue;
2014 if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0) {
2015 or DFFSXFRCTL, DFFBITBUCKET;
2016SET_SRC_MODE M_DFF1;
2017SET_DST_MODE M_DFF1;
2018 } else {
2019 call load_overrun_buf;
2020 mvi DFCNTRL, (HDMAEN|SCSIEN|PRELOADEN);
2021 }
2022 call setjmp;
2023 if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {
2024 test DFSTATUS, PRELOAD_AVAIL jz overrun_load_done;
2025 call load_overrun_buf;
2026 or DFCNTRL, PRELOADEN;
2027overrun_load_done:
2028 test SEQINTSRC, CTXTDONE jnz pkt_overrun_end;
2029 } else {
2030 test DFFSXFRCTL, DFFBITBUCKET jz pkt_overrun_end;
2031 }
2032 test SSTAT2, NONPACKREQ jz return;
2033pkt_overrun_end:
2034 or SCB_RESIDUAL_SGPTR, SG_OVERRUN_RESID;
2035 test SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase;
2036 dec SCB_FIFO_USE_COUNT;
2037 or LONGJMP_ADDR[1], INVALID_ADDR;
2038 test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;
2039 mvi DFFSXFRCTL, CLRCHN ret;
2040
2041if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {
2042load_overrun_buf:
2043 /*
2044 * Load a dummy segment if preload space is available.
2045 */
2046 mov HADDR[0], SHARED_DATA_ADDR;
2047 add HADDR[1], PKT_OVERRUN_BUFOFFSET, SHARED_DATA_ADDR[1];
2048 mov ACCUM_SAVE, A;
2049 clr A;
2050 adc HADDR[2], A, SHARED_DATA_ADDR[2];
2051 adc HADDR[3], A, SHARED_DATA_ADDR[3];
2052 mov A, ACCUM_SAVE;
2053 bmov HADDR[4], ALLZEROS, 4;
2054 /* PKT_OVERRUN_BUFSIZE is a multiple of 256 */
2055 clr HCNT[0];
2056 mvi HCNT[1], ((PKT_OVERRUN_BUFSIZE >> 8) & 0xFF);
2057 clr HCNT[2] ret;
2058}
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
new file mode 100644
index 000000000000..137fb1a37dd1
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -0,0 +1,9888 @@
1/*
2 * Core routines and tables shareable across OS platforms.
3 *
4 * Copyright (c) 1994-2002 Justin T. Gibbs.
5 * Copyright (c) 2000-2003 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#202 $
41 *
42 * $FreeBSD$
43 */
44
45#ifdef __linux__
46#include "aic79xx_osm.h"
47#include "aic79xx_inline.h"
48#include "aicasm/aicasm_insformat.h"
49#else
50#include <dev/aic7xxx/aic79xx_osm.h>
51#include <dev/aic7xxx/aic79xx_inline.h>
52#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
53#endif
54
55/******************************** Globals *************************************/
56struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq);
57
58/***************************** Lookup Tables **********************************/
59char *ahd_chip_names[] =
60{
61 "NONE",
62 "aic7901",
63 "aic7902",
64 "aic7901A"
65};
66static const u_int num_chip_names = NUM_ELEMENTS(ahd_chip_names);
67
68/*
69 * Hardware error codes.
70 */
71struct ahd_hard_error_entry {
72 uint8_t errno;
73 char *errmesg;
74};
75
76static struct ahd_hard_error_entry ahd_hard_errors[] = {
77 { DSCTMOUT, "Discard Timer has timed out" },
78 { ILLOPCODE, "Illegal Opcode in sequencer program" },
79 { SQPARERR, "Sequencer Parity Error" },
80 { DPARERR, "Data-path Parity Error" },
81 { MPARERR, "Scratch or SCB Memory Parity Error" },
82 { CIOPARERR, "CIOBUS Parity Error" },
83};
84static const u_int num_errors = NUM_ELEMENTS(ahd_hard_errors);
85
86static struct ahd_phase_table_entry ahd_phase_table[] =
87{
88 { P_DATAOUT, MSG_NOOP, "in Data-out phase" },
89 { P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" },
90 { P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" },
91 { P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" },
92 { P_COMMAND, MSG_NOOP, "in Command phase" },
93 { P_MESGOUT, MSG_NOOP, "in Message-out phase" },
94 { P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" },
95 { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
96 { P_BUSFREE, MSG_NOOP, "while idle" },
97 { 0, MSG_NOOP, "in unknown phase" }
98};
99
100/*
101 * In most cases we only wish to itterate over real phases, so
102 * exclude the last element from the count.
103 */
104static const u_int num_phases = NUM_ELEMENTS(ahd_phase_table) - 1;
105
106/* Our Sequencer Program */
107#include "aic79xx_seq.h"
108
109/**************************** Function Declarations ***************************/
110static void ahd_handle_transmission_error(struct ahd_softc *ahd);
111static void ahd_handle_lqiphase_error(struct ahd_softc *ahd,
112 u_int lqistat1);
113static int ahd_handle_pkt_busfree(struct ahd_softc *ahd,
114 u_int busfreetime);
115static int ahd_handle_nonpkt_busfree(struct ahd_softc *ahd);
116static void ahd_handle_proto_violation(struct ahd_softc *ahd);
117static void ahd_force_renegotiation(struct ahd_softc *ahd,
118 struct ahd_devinfo *devinfo);
119
120static struct ahd_tmode_tstate*
121 ahd_alloc_tstate(struct ahd_softc *ahd,
122 u_int scsi_id, char channel);
123#ifdef AHD_TARGET_MODE
124static void ahd_free_tstate(struct ahd_softc *ahd,
125 u_int scsi_id, char channel, int force);
126#endif
127static void ahd_devlimited_syncrate(struct ahd_softc *ahd,
128 struct ahd_initiator_tinfo *,
129 u_int *period,
130 u_int *ppr_options,
131 role_t role);
132static void ahd_update_neg_table(struct ahd_softc *ahd,
133 struct ahd_devinfo *devinfo,
134 struct ahd_transinfo *tinfo);
135static void ahd_update_pending_scbs(struct ahd_softc *ahd);
136static void ahd_fetch_devinfo(struct ahd_softc *ahd,
137 struct ahd_devinfo *devinfo);
138static void ahd_scb_devinfo(struct ahd_softc *ahd,
139 struct ahd_devinfo *devinfo,
140 struct scb *scb);
141static void ahd_setup_initiator_msgout(struct ahd_softc *ahd,
142 struct ahd_devinfo *devinfo,
143 struct scb *scb);
144static void ahd_build_transfer_msg(struct ahd_softc *ahd,
145 struct ahd_devinfo *devinfo);
146static void ahd_construct_sdtr(struct ahd_softc *ahd,
147 struct ahd_devinfo *devinfo,
148 u_int period, u_int offset);
149static void ahd_construct_wdtr(struct ahd_softc *ahd,
150 struct ahd_devinfo *devinfo,
151 u_int bus_width);
152static void ahd_construct_ppr(struct ahd_softc *ahd,
153 struct ahd_devinfo *devinfo,
154 u_int period, u_int offset,
155 u_int bus_width, u_int ppr_options);
156static void ahd_clear_msg_state(struct ahd_softc *ahd);
157static void ahd_handle_message_phase(struct ahd_softc *ahd);
158typedef enum {
159 AHDMSG_1B,
160 AHDMSG_2B,
161 AHDMSG_EXT
162} ahd_msgtype;
163static int ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type,
164 u_int msgval, int full);
165static int ahd_parse_msg(struct ahd_softc *ahd,
166 struct ahd_devinfo *devinfo);
167static int ahd_handle_msg_reject(struct ahd_softc *ahd,
168 struct ahd_devinfo *devinfo);
169static void ahd_handle_ign_wide_residue(struct ahd_softc *ahd,
170 struct ahd_devinfo *devinfo);
171static void ahd_reinitialize_dataptrs(struct ahd_softc *ahd);
172static void ahd_handle_devreset(struct ahd_softc *ahd,
173 struct ahd_devinfo *devinfo,
174 u_int lun, cam_status status,
175 char *message, int verbose_level);
176#ifdef AHD_TARGET_MODE
177static void ahd_setup_target_msgin(struct ahd_softc *ahd,
178 struct ahd_devinfo *devinfo,
179 struct scb *scb);
180#endif
181
182static u_int ahd_sglist_size(struct ahd_softc *ahd);
183static u_int ahd_sglist_allocsize(struct ahd_softc *ahd);
184static bus_dmamap_callback_t
185 ahd_dmamap_cb;
186static void ahd_initialize_hscbs(struct ahd_softc *ahd);
187static int ahd_init_scbdata(struct ahd_softc *ahd);
188static void ahd_fini_scbdata(struct ahd_softc *ahd);
189static void ahd_setup_iocell_workaround(struct ahd_softc *ahd);
190static void ahd_iocell_first_selection(struct ahd_softc *ahd);
191static void ahd_add_col_list(struct ahd_softc *ahd,
192 struct scb *scb, u_int col_idx);
193static void ahd_rem_col_list(struct ahd_softc *ahd,
194 struct scb *scb);
195static void ahd_chip_init(struct ahd_softc *ahd);
196static void ahd_qinfifo_requeue(struct ahd_softc *ahd,
197 struct scb *prev_scb,
198 struct scb *scb);
199static int ahd_qinfifo_count(struct ahd_softc *ahd);
200static int ahd_search_scb_list(struct ahd_softc *ahd, int target,
201 char channel, int lun, u_int tag,
202 role_t role, uint32_t status,
203 ahd_search_action action,
204 u_int *list_head, u_int tid);
205static void ahd_stitch_tid_list(struct ahd_softc *ahd,
206 u_int tid_prev, u_int tid_cur,
207 u_int tid_next);
208static void ahd_add_scb_to_free_list(struct ahd_softc *ahd,
209 u_int scbid);
210static u_int ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
211 u_int prev, u_int next, u_int tid);
212static void ahd_reset_current_bus(struct ahd_softc *ahd);
213static ahd_callback_t ahd_reset_poll;
214static ahd_callback_t ahd_stat_timer;
215#ifdef AHD_DUMP_SEQ
216static void ahd_dumpseq(struct ahd_softc *ahd);
217#endif
218static void ahd_loadseq(struct ahd_softc *ahd);
219static int ahd_check_patch(struct ahd_softc *ahd,
220 struct patch **start_patch,
221 u_int start_instr, u_int *skip_addr);
222static u_int ahd_resolve_seqaddr(struct ahd_softc *ahd,
223 u_int address);
224static void ahd_download_instr(struct ahd_softc *ahd,
225 u_int instrptr, uint8_t *dconsts);
226static int ahd_probe_stack_size(struct ahd_softc *ahd);
227static int ahd_scb_active_in_fifo(struct ahd_softc *ahd,
228 struct scb *scb);
229static void ahd_run_data_fifo(struct ahd_softc *ahd,
230 struct scb *scb);
231
232#ifdef AHD_TARGET_MODE
233static void ahd_queue_lstate_event(struct ahd_softc *ahd,
234 struct ahd_tmode_lstate *lstate,
235 u_int initiator_id,
236 u_int event_type,
237 u_int event_arg);
238static void ahd_update_scsiid(struct ahd_softc *ahd,
239 u_int targid_mask);
240static int ahd_handle_target_cmd(struct ahd_softc *ahd,
241 struct target_cmd *cmd);
242#endif
243
244/******************************** Private Inlines *****************************/
245static __inline void ahd_assert_atn(struct ahd_softc *ahd);
246static __inline int ahd_currently_packetized(struct ahd_softc *ahd);
247static __inline int ahd_set_active_fifo(struct ahd_softc *ahd);
248
249static __inline void
250ahd_assert_atn(struct ahd_softc *ahd)
251{
252 ahd_outb(ahd, SCSISIGO, ATNO);
253}
254
255/*
256 * Determine if the current connection has a packetized
257 * agreement. This does not necessarily mean that we
258 * are currently in a packetized transfer. We could
259 * just as easily be sending or receiving a message.
260 */
261static __inline int
262ahd_currently_packetized(struct ahd_softc *ahd)
263{
264 ahd_mode_state saved_modes;
265 int packetized;
266
267 saved_modes = ahd_save_modes(ahd);
268 if ((ahd->bugs & AHD_PKTIZED_STATUS_BUG) != 0) {
269 /*
270 * The packetized bit refers to the last
271 * connection, not the current one. Check
272 * for non-zero LQISTATE instead.
273 */
274 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
275 packetized = ahd_inb(ahd, LQISTATE) != 0;
276 } else {
277 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
278 packetized = ahd_inb(ahd, LQISTAT2) & PACKETIZED;
279 }
280 ahd_restore_modes(ahd, saved_modes);
281 return (packetized);
282}
283
284static __inline int
285ahd_set_active_fifo(struct ahd_softc *ahd)
286{
287 u_int active_fifo;
288
289 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
290 active_fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
291 switch (active_fifo) {
292 case 0:
293 case 1:
294 ahd_set_modes(ahd, active_fifo, active_fifo);
295 return (1);
296 default:
297 return (0);
298 }
299}
300
301/************************* Sequencer Execution Control ************************/
302/*
303 * Restart the sequencer program from address zero
304 */
305void
306ahd_restart(struct ahd_softc *ahd)
307{
308
309 ahd_pause(ahd);
310
311 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
312
313 /* No more pending messages */
314 ahd_clear_msg_state(ahd);
315 ahd_outb(ahd, SCSISIGO, 0); /* De-assert BSY */
316 ahd_outb(ahd, MSG_OUT, MSG_NOOP); /* No message to send */
317 ahd_outb(ahd, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET);
318 ahd_outb(ahd, SEQINTCTL, 0);
319 ahd_outb(ahd, LASTPHASE, P_BUSFREE);
320 ahd_outb(ahd, SEQ_FLAGS, 0);
321 ahd_outb(ahd, SAVED_SCSIID, 0xFF);
322 ahd_outb(ahd, SAVED_LUN, 0xFF);
323
324 /*
325 * Ensure that the sequencer's idea of TQINPOS
326 * matches our own. The sequencer increments TQINPOS
327 * only after it sees a DMA complete and a reset could
328 * occur before the increment leaving the kernel to believe
329 * the command arrived but the sequencer to not.
330 */
331 ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
332
333 /* Always allow reselection */
334 ahd_outb(ahd, SCSISEQ1,
335 ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
336 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
337 ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
338 ahd_unpause(ahd);
339}
340
341void
342ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo)
343{
344 ahd_mode_state saved_modes;
345
346#ifdef AHD_DEBUG
347 if ((ahd_debug & AHD_SHOW_FIFOS) != 0)
348 printf("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo);
349#endif
350 saved_modes = ahd_save_modes(ahd);
351 ahd_set_modes(ahd, fifo, fifo);
352 ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
353 if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
354 ahd_outb(ahd, CCSGCTL, CCSGRESET);
355 ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
356 ahd_outb(ahd, SG_STATE, 0);
357 ahd_restore_modes(ahd, saved_modes);
358}
359
360/************************* Input/Output Queues ********************************/
361/*
362 * Flush and completed commands that are sitting in the command
363 * complete queues down on the chip but have yet to be dma'ed back up.
364 */
365void
366ahd_flush_qoutfifo(struct ahd_softc *ahd)
367{
368 struct scb *scb;
369 ahd_mode_state saved_modes;
370 u_int saved_scbptr;
371 u_int ccscbctl;
372 u_int scbid;
373 u_int next_scbid;
374
375 saved_modes = ahd_save_modes(ahd);
376
377 /*
378 * Complete any SCBs that just finished being
379 * DMA'ed into the qoutfifo.
380 */
381 ahd_run_qoutfifo(ahd);
382
383 /*
384 * Flush the good status FIFO for compelted packetized commands.
385 */
386 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
387 saved_scbptr = ahd_get_scbptr(ahd);
388 while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) {
389 u_int fifo_mode;
390 u_int i;
391
392 scbid = (ahd_inb(ahd, GSFIFO+1) << 8)
393 | ahd_inb(ahd, GSFIFO);
394 scb = ahd_lookup_scb(ahd, scbid);
395 if (scb == NULL) {
396 printf("%s: Warning - GSFIFO SCB %d invalid\n",
397 ahd_name(ahd), scbid);
398 continue;
399 }
400 /*
401 * Determine if this transaction is still active in
402 * any FIFO. If it is, we must flush that FIFO to
403 * the host before completing the command.
404 */
405 fifo_mode = 0;
406 for (i = 0; i < 2; i++) {
407 /* Toggle to the other mode. */
408 fifo_mode ^= 1;
409 ahd_set_modes(ahd, fifo_mode, fifo_mode);
410 if (ahd_scb_active_in_fifo(ahd, scb) == 0)
411 continue;
412
413 ahd_run_data_fifo(ahd, scb);
414
415 /*
416 * Clearing this transaction in this FIFO may
417 * cause a CFG4DATA for this same transaction
418 * to assert in the other FIFO. Make sure we
419 * loop one more time and check the other FIFO.
420 */
421 i = 0;
422 }
423 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
424 ahd_set_scbptr(ahd, scbid);
425 if ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_LIST_NULL) == 0
426 && ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_FULL_RESID) != 0
427 || (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR)
428 & SG_LIST_NULL) != 0)) {
429 u_int comp_head;
430
431 /*
432 * The transfer completed with a residual.
433 * Place this SCB on the complete DMA list
434 * so that we Update our in-core copy of the
435 * SCB before completing the command.
436 */
437 ahd_outb(ahd, SCB_SCSI_STATUS, 0);
438 ahd_outb(ahd, SCB_SGPTR,
439 ahd_inb_scbram(ahd, SCB_SGPTR)
440 | SG_STATUS_VALID);
441 ahd_outw(ahd, SCB_TAG, SCB_GET_TAG(scb));
442 comp_head = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
443 ahd_outw(ahd, SCB_NEXT_COMPLETE, comp_head);
444 if (SCBID_IS_NULL(comp_head))
445 ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD,
446 SCB_GET_TAG(scb));
447 } else
448 ahd_complete_scb(ahd, scb);
449 }
450 ahd_set_scbptr(ahd, saved_scbptr);
451
452 /*
453 * Setup for command channel portion of flush.
454 */
455 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
456
457 /*
458 * Wait for any inprogress DMA to complete and clear DMA state
459 * if this if for an SCB in the qinfifo.
460 */
461 while (((ccscbctl = ahd_inb(ahd, CCSCBCTL)) & (CCARREN|CCSCBEN)) != 0) {
462
463 if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) {
464 if ((ccscbctl & ARRDONE) != 0)
465 break;
466 } else if ((ccscbctl & CCSCBDONE) != 0)
467 break;
468 ahd_delay(200);
469 }
470 if ((ccscbctl & CCSCBDIR) != 0)
471 ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN));
472
473 saved_scbptr = ahd_get_scbptr(ahd);
474 /*
475 * Manually update/complete any completed SCBs that are waiting to be
476 * DMA'ed back up to the host.
477 */
478 scbid = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
479 while (!SCBID_IS_NULL(scbid)) {
480 uint8_t *hscb_ptr;
481 u_int i;
482
483 ahd_set_scbptr(ahd, scbid);
484 next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
485 scb = ahd_lookup_scb(ahd, scbid);
486 if (scb == NULL) {
487 printf("%s: Warning - DMA-up and complete "
488 "SCB %d invalid\n", ahd_name(ahd), scbid);
489 continue;
490 }
491 hscb_ptr = (uint8_t *)scb->hscb;
492 for (i = 0; i < sizeof(struct hardware_scb); i++)
493 *hscb_ptr++ = ahd_inb_scbram(ahd, SCB_BASE + i);
494
495 ahd_complete_scb(ahd, scb);
496 scbid = next_scbid;
497 }
498 ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);
499
500 scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD);
501 while (!SCBID_IS_NULL(scbid)) {
502
503 ahd_set_scbptr(ahd, scbid);
504 next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
505 scb = ahd_lookup_scb(ahd, scbid);
506 if (scb == NULL) {
507 printf("%s: Warning - Complete SCB %d invalid\n",
508 ahd_name(ahd), scbid);
509 continue;
510 }
511
512 ahd_complete_scb(ahd, scb);
513 scbid = next_scbid;
514 }
515 ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
516
517 /*
518 * Restore state.
519 */
520 ahd_set_scbptr(ahd, saved_scbptr);
521 ahd_restore_modes(ahd, saved_modes);
522 ahd->flags |= AHD_UPDATE_PEND_CMDS;
523}
524
525/*
526 * Determine if an SCB for a packetized transaction
527 * is active in a FIFO.
528 */
529static int
530ahd_scb_active_in_fifo(struct ahd_softc *ahd, struct scb *scb)
531{
532
533 /*
534 * The FIFO is only active for our transaction if
535 * the SCBPTR matches the SCB's ID and the firmware
536 * has installed a handler for the FIFO or we have
537 * a pending SAVEPTRS or CFG4DATA interrupt.
538 */
539 if (ahd_get_scbptr(ahd) != SCB_GET_TAG(scb)
540 || ((ahd_inb(ahd, LONGJMP_ADDR+1) & INVALID_ADDR) != 0
541 && (ahd_inb(ahd, SEQINTSRC) & (CFG4DATA|SAVEPTRS)) == 0))
542 return (0);
543
544 return (1);
545}
546
547/*
548 * Run a data fifo to completion for a transaction we know
549 * has completed across the SCSI bus (good status has been
550 * received). We are already set to the correct FIFO mode
551 * on entry to this routine.
552 *
553 * This function attempts to operate exactly as the firmware
554 * would when running this FIFO. Care must be taken to update
555 * this routine any time the firmware's FIFO algorithm is
556 * changed.
557 */
558static void
559ahd_run_data_fifo(struct ahd_softc *ahd, struct scb *scb)
560{
561 u_int seqintsrc;
562
563 while (1) {
564 seqintsrc = ahd_inb(ahd, SEQINTSRC);
565 if ((seqintsrc & CFG4DATA) != 0) {
566 uint32_t datacnt;
567 uint32_t sgptr;
568
569 /*
570 * Clear full residual flag.
571 */
572 sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID;
573 ahd_outb(ahd, SCB_SGPTR, sgptr);
574
575 /*
576 * Load datacnt and address.
577 */
578 datacnt = ahd_inl_scbram(ahd, SCB_DATACNT);
579 if ((datacnt & AHD_DMA_LAST_SEG) != 0) {
580 sgptr |= LAST_SEG;
581 ahd_outb(ahd, SG_STATE, 0);
582 } else
583 ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
584 ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR));
585 ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK);
586 ahd_outb(ahd, SG_CACHE_PRE, sgptr);
587 ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
588
589 /*
590 * Initialize Residual Fields.
591 */
592 ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24);
593 ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK);
594
595 /*
596 * Mark the SCB as having a FIFO in use.
597 */
598 ahd_outb(ahd, SCB_FIFO_USE_COUNT,
599 ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1);
600
601 /*
602 * Install a "fake" handler for this FIFO.
603 */
604 ahd_outw(ahd, LONGJMP_ADDR, 0);
605
606 /*
607 * Notify the hardware that we have satisfied
608 * this sequencer interrupt.
609 */
610 ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA);
611 } else if ((seqintsrc & SAVEPTRS) != 0) {
612 uint32_t sgptr;
613 uint32_t resid;
614
615 if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) {
616 /*
617 * Snapshot Save Pointers. Clear
618 * the snapshot and continue.
619 */
620 ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
621 continue;
622 }
623
624 /*
625 * Disable S/G fetch so the DMA engine
626 * is available to future users.
627 */
628 if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
629 ahd_outb(ahd, CCSGCTL, 0);
630 ahd_outb(ahd, SG_STATE, 0);
631
632 /*
633 * Flush the data FIFO. Strickly only
634 * necessary for Rev A parts.
635 */
636 ahd_outb(ahd, DFCNTRL,
637 ahd_inb(ahd, DFCNTRL) | FIFOFLUSH);
638
639 /*
640 * Calculate residual.
641 */
642 sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
643 resid = ahd_inl(ahd, SHCNT);
644 resid |=
645 ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24;
646 ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid);
647 if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) {
648 /*
649 * Must back up to the correct S/G element.
650 * Typically this just means resetting our
651 * low byte to the offset in the SG_CACHE,
652 * but if we wrapped, we have to correct
653 * the other bytes of the sgptr too.
654 */
655 if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0
656 && (sgptr & 0x80) == 0)
657 sgptr -= 0x100;
658 sgptr &= ~0xFF;
659 sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW)
660 & SG_ADDR_MASK;
661 ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
662 ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0);
663 } else if ((resid & AHD_SG_LEN_MASK) == 0) {
664 ahd_outb(ahd, SCB_RESIDUAL_SGPTR,
665 sgptr | SG_LIST_NULL);
666 }
667 /*
668 * Save Pointers.
669 */
670 ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR));
671 ahd_outl(ahd, SCB_DATACNT, resid);
672 ahd_outl(ahd, SCB_SGPTR, sgptr);
673 ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS);
674 ahd_outb(ahd, SEQIMODE,
675 ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS);
676 /*
677 * If the data is to the SCSI bus, we are
678 * done, otherwise wait for FIFOEMP.
679 */
680 if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0)
681 break;
682 } else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) {
683 uint32_t sgptr;
684 uint64_t data_addr;
685 uint32_t data_len;
686 u_int dfcntrl;
687
688 /*
689 * Disable S/G fetch so the DMA engine
690 * is available to future users.
691 */
692 if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) {
693 ahd_outb(ahd, CCSGCTL, 0);
694 ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
695 }
696
697 /*
698 * Wait for the DMA engine to notice that the
699 * host transfer is enabled and that there is
700 * space in the S/G FIFO for new segments before
701 * loading more segments.
702 */
703 if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) == 0)
704 continue;
705 if ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) == 0)
706 continue;
707
708 /*
709 * Determine the offset of the next S/G
710 * element to load.
711 */
712 sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
713 sgptr &= SG_PTR_MASK;
714 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
715 struct ahd_dma64_seg *sg;
716
717 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
718 data_addr = sg->addr;
719 data_len = sg->len;
720 sgptr += sizeof(*sg);
721 } else {
722 struct ahd_dma_seg *sg;
723
724 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
725 data_addr = sg->len & AHD_SG_HIGH_ADDR_MASK;
726 data_addr <<= 8;
727 data_addr |= sg->addr;
728 data_len = sg->len;
729 sgptr += sizeof(*sg);
730 }
731
732 /*
733 * Update residual information.
734 */
735 ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, data_len >> 24);
736 ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
737
738 /*
739 * Load the S/G.
740 */
741 if (data_len & AHD_DMA_LAST_SEG) {
742 sgptr |= LAST_SEG;
743 ahd_outb(ahd, SG_STATE, 0);
744 }
745 ahd_outq(ahd, HADDR, data_addr);
746 ahd_outl(ahd, HCNT, data_len & AHD_SG_LEN_MASK);
747 ahd_outb(ahd, SG_CACHE_PRE, sgptr & 0xFF);
748
749 /*
750 * Advertise the segment to the hardware.
751 */
752 dfcntrl = ahd_inb(ahd, DFCNTRL)|PRELOADEN|HDMAEN;
753 if ((ahd->features & AHD_NEW_DFCNTRL_OPTS)!=0) {
754 /*
755 * Use SCSIENWRDIS so that SCSIEN
756 * is never modified by this
757 * operation.
758 */
759 dfcntrl |= SCSIENWRDIS;
760 }
761 ahd_outb(ahd, DFCNTRL, dfcntrl);
762 } else if ((ahd_inb(ahd, SG_CACHE_SHADOW)
763 & LAST_SEG_DONE) != 0) {
764
765 /*
766 * Transfer completed to the end of SG list
767 * and has flushed to the host.
768 */
769 ahd_outb(ahd, SCB_SGPTR,
770 ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL);
771 break;
772 } else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) {
773 break;
774 }
775 ahd_delay(200);
776 }
777 /*
778 * Clear any handler for this FIFO, decrement
779 * the FIFO use count for the SCB, and release
780 * the FIFO.
781 */
782 ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
783 ahd_outb(ahd, SCB_FIFO_USE_COUNT,
784 ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1);
785 ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
786}
787
788void
789ahd_run_qoutfifo(struct ahd_softc *ahd)
790{
791 struct scb *scb;
792 u_int scb_index;
793
794 if ((ahd->flags & AHD_RUNNING_QOUTFIFO) != 0)
795 panic("ahd_run_qoutfifo recursion");
796 ahd->flags |= AHD_RUNNING_QOUTFIFO;
797 ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD);
798 while ((ahd->qoutfifo[ahd->qoutfifonext]
799 & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) {
800
801 scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext]
802 & ~QOUTFIFO_ENTRY_VALID_LE);
803 scb = ahd_lookup_scb(ahd, scb_index);
804 if (scb == NULL) {
805 printf("%s: WARNING no command for scb %d "
806 "(cmdcmplt)\nQOUTPOS = %d\n",
807 ahd_name(ahd), scb_index,
808 ahd->qoutfifonext);
809 ahd_dump_card_state(ahd);
810 } else
811 ahd_complete_scb(ahd, scb);
812
813 ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1);
814 if (ahd->qoutfifonext == 0)
815 ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID_LE;
816 }
817 ahd->flags &= ~AHD_RUNNING_QOUTFIFO;
818}
819
820/************************* Interrupt Handling *********************************/
821void
822ahd_handle_hwerrint(struct ahd_softc *ahd)
823{
824 /*
825 * Some catastrophic hardware error has occurred.
826 * Print it for the user and disable the controller.
827 */
828 int i;
829 int error;
830
831 error = ahd_inb(ahd, ERROR);
832 for (i = 0; i < num_errors; i++) {
833 if ((error & ahd_hard_errors[i].errno) != 0)
834 printf("%s: hwerrint, %s\n",
835 ahd_name(ahd), ahd_hard_errors[i].errmesg);
836 }
837
838 ahd_dump_card_state(ahd);
839 panic("BRKADRINT");
840
841 /* Tell everyone that this HBA is no longer available */
842 ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
843 CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
844 CAM_NO_HBA);
845
846 /* Tell the system that this controller has gone away. */
847 ahd_free(ahd);
848}
849
850void
851ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
852{
853 u_int seqintcode;
854
855 /*
856 * Save the sequencer interrupt code and clear the SEQINT
857 * bit. We will unpause the sequencer, if appropriate,
858 * after servicing the request.
859 */
860 seqintcode = ahd_inb(ahd, SEQINTCODE);
861 ahd_outb(ahd, CLRINT, CLRSEQINT);
862 if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {
863 /*
864 * Unpause the sequencer and let it clear
865 * SEQINT by writing NO_SEQINT to it. This
866 * will cause the sequencer to be paused again,
867 * which is the expected state of this routine.
868 */
869 ahd_unpause(ahd);
870 while (!ahd_is_paused(ahd))
871 ;
872 ahd_outb(ahd, CLRINT, CLRSEQINT);
873 }
874 ahd_update_modes(ahd);
875#ifdef AHD_DEBUG
876 if ((ahd_debug & AHD_SHOW_MISC) != 0)
877 printf("%s: Handle Seqint Called for code %d\n",
878 ahd_name(ahd), seqintcode);
879#endif
880 switch (seqintcode) {
881 case BAD_SCB_STATUS:
882 {
883 struct scb *scb;
884 u_int scbid;
885 int cmds_pending;
886
887 scbid = ahd_get_scbptr(ahd);
888 scb = ahd_lookup_scb(ahd, scbid);
889 if (scb != NULL) {
890 ahd_complete_scb(ahd, scb);
891 } else {
892 printf("%s: WARNING no command for scb %d "
893 "(bad status)\n", ahd_name(ahd), scbid);
894 ahd_dump_card_state(ahd);
895 }
896 cmds_pending = ahd_inw(ahd, CMDS_PENDING);
897 if (cmds_pending > 0)
898 ahd_outw(ahd, CMDS_PENDING, cmds_pending - 1);
899 break;
900 }
901 case ENTERING_NONPACK:
902 {
903 struct scb *scb;
904 u_int scbid;
905
906 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
907 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
908 scbid = ahd_get_scbptr(ahd);
909 scb = ahd_lookup_scb(ahd, scbid);
910 if (scb == NULL) {
911 /*
912 * Somehow need to know if this
913 * is from a selection or reselection.
914 * From that, we can determine target
915 * ID so we at least have an I_T nexus.
916 */
917 } else {
918 ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
919 ahd_outb(ahd, SAVED_LUN, scb->hscb->lun);
920 ahd_outb(ahd, SEQ_FLAGS, 0x0);
921 }
922 if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0
923 && (ahd_inb(ahd, SCSISIGO) & ATNO) != 0) {
924 /*
925 * Phase change after read stream with
926 * CRC error with P0 asserted on last
927 * packet.
928 */
929#ifdef AHD_DEBUG
930 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
931 printf("%s: Assuming LQIPHASE_NLQ with "
932 "P0 assertion\n", ahd_name(ahd));
933#endif
934 }
935#ifdef AHD_DEBUG
936 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
937 printf("%s: Entering NONPACK\n", ahd_name(ahd));
938#endif
939 break;
940 }
941 case INVALID_SEQINT:
942 printf("%s: Invalid Sequencer interrupt occurred.\n",
943 ahd_name(ahd));
944 ahd_dump_card_state(ahd);
945 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
946 break;
947 case STATUS_OVERRUN:
948 {
949 struct scb *scb;
950 u_int scbid;
951
952 scbid = ahd_get_scbptr(ahd);
953 scb = ahd_lookup_scb(ahd, scbid);
954 if (scb != NULL)
955 ahd_print_path(ahd, scb);
956 else
957 printf("%s: ", ahd_name(ahd));
958 printf("SCB %d Packetized Status Overrun", scbid);
959 ahd_dump_card_state(ahd);
960 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
961 break;
962 }
963 case CFG4ISTAT_INTR:
964 {
965 struct scb *scb;
966 u_int scbid;
967
968 scbid = ahd_get_scbptr(ahd);
969 scb = ahd_lookup_scb(ahd, scbid);
970 if (scb == NULL) {
971 ahd_dump_card_state(ahd);
972 printf("CFG4ISTAT: Free SCB %d referenced", scbid);
973 panic("For safety");
974 }
975 ahd_outq(ahd, HADDR, scb->sense_busaddr);
976 ahd_outw(ahd, HCNT, AHD_SENSE_BUFSIZE);
977 ahd_outb(ahd, HCNT + 2, 0);
978 ahd_outb(ahd, SG_CACHE_PRE, SG_LAST_SEG);
979 ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
980 break;
981 }
982 case ILLEGAL_PHASE:
983 {
984 u_int bus_phase;
985
986 bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
987 printf("%s: ILLEGAL_PHASE 0x%x\n",
988 ahd_name(ahd), bus_phase);
989
990 switch (bus_phase) {
991 case P_DATAOUT:
992 case P_DATAIN:
993 case P_DATAOUT_DT:
994 case P_DATAIN_DT:
995 case P_MESGOUT:
996 case P_STATUS:
997 case P_MESGIN:
998 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
999 printf("%s: Issued Bus Reset.\n", ahd_name(ahd));
1000 break;
1001 case P_COMMAND:
1002 {
1003 struct ahd_devinfo devinfo;
1004 struct scb *scb;
1005 struct ahd_initiator_tinfo *targ_info;
1006 struct ahd_tmode_tstate *tstate;
1007 struct ahd_transinfo *tinfo;
1008 u_int scbid;
1009
1010 /*
1011 * If a target takes us into the command phase
1012 * assume that it has been externally reset and
1013 * has thus lost our previous packetized negotiation
1014 * agreement. Since we have not sent an identify
1015 * message and may not have fully qualified the
1016 * connection, we change our command to TUR, assert
1017 * ATN and ABORT the task when we go to message in
1018 * phase. The OSM will see the REQUEUE_REQUEST
1019 * status and retry the command.
1020 */
1021 scbid = ahd_get_scbptr(ahd);
1022 scb = ahd_lookup_scb(ahd, scbid);
1023 if (scb == NULL) {
1024 printf("Invalid phase with no valid SCB. "
1025 "Resetting bus.\n");
1026 ahd_reset_channel(ahd, 'A',
1027 /*Initiate Reset*/TRUE);
1028 break;
1029 }
1030 ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
1031 SCB_GET_TARGET(ahd, scb),
1032 SCB_GET_LUN(scb),
1033 SCB_GET_CHANNEL(ahd, scb),
1034 ROLE_INITIATOR);
1035 targ_info = ahd_fetch_transinfo(ahd,
1036 devinfo.channel,
1037 devinfo.our_scsiid,
1038 devinfo.target,
1039 &tstate);
1040 tinfo = &targ_info->curr;
1041 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
1042 AHD_TRANS_ACTIVE, /*paused*/TRUE);
1043 ahd_set_syncrate(ahd, &devinfo, /*period*/0,
1044 /*offset*/0, /*ppr_options*/0,
1045 AHD_TRANS_ACTIVE, /*paused*/TRUE);
1046 ahd_outb(ahd, SCB_CDB_STORE, 0);
1047 ahd_outb(ahd, SCB_CDB_STORE+1, 0);
1048 ahd_outb(ahd, SCB_CDB_STORE+2, 0);
1049 ahd_outb(ahd, SCB_CDB_STORE+3, 0);
1050 ahd_outb(ahd, SCB_CDB_STORE+4, 0);
1051 ahd_outb(ahd, SCB_CDB_STORE+5, 0);
1052 ahd_outb(ahd, SCB_CDB_LEN, 6);
1053 scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE);
1054 scb->hscb->control |= MK_MESSAGE;
1055 ahd_outb(ahd, SCB_CONTROL, scb->hscb->control);
1056 ahd_outb(ahd, MSG_OUT, HOST_MSG);
1057 ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
1058 /*
1059 * The lun is 0, regardless of the SCB's lun
1060 * as we have not sent an identify message.
1061 */
1062 ahd_outb(ahd, SAVED_LUN, 0);
1063 ahd_outb(ahd, SEQ_FLAGS, 0);
1064 ahd_assert_atn(ahd);
1065 scb->flags &= ~(SCB_PACKETIZED);
1066 scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT;
1067 ahd_freeze_devq(ahd, scb);
1068 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
1069 ahd_freeze_scb(scb);
1070
1071 /*
1072 * Allow the sequencer to continue with
1073 * non-pack processing.
1074 */
1075 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1076 ahd_outb(ahd, CLRLQOINT1, CLRLQOPHACHGINPKT);
1077 if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
1078 ahd_outb(ahd, CLRLQOINT1, 0);
1079 }
1080#ifdef AHD_DEBUG
1081 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1082 ahd_print_path(ahd, scb);
1083 printf("Unexpected command phase from "
1084 "packetized target\n");
1085 }
1086#endif
1087 break;
1088 }
1089 }
1090 break;
1091 }
1092 case CFG4OVERRUN:
1093 {
1094 struct scb *scb;
1095 u_int scb_index;
1096
1097#ifdef AHD_DEBUG
1098 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1099 printf("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd),
1100 ahd_inb(ahd, MODE_PTR));
1101 }
1102#endif
1103 scb_index = ahd_get_scbptr(ahd);
1104 scb = ahd_lookup_scb(ahd, scb_index);
1105 if (scb == NULL) {
1106 /*
1107 * Attempt to transfer to an SCB that is
1108 * not outstanding.
1109 */
1110 ahd_assert_atn(ahd);
1111 ahd_outb(ahd, MSG_OUT, HOST_MSG);
1112 ahd->msgout_buf[0] = MSG_ABORT_TASK;
1113 ahd->msgout_len = 1;
1114 ahd->msgout_index = 0;
1115 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
1116 /*
1117 * Clear status received flag to prevent any
1118 * attempt to complete this bogus SCB.
1119 */
1120 ahd_outb(ahd, SCB_CONTROL,
1121 ahd_inb_scbram(ahd, SCB_CONTROL)
1122 & ~STATUS_RCVD);
1123 }
1124 break;
1125 }
1126 case DUMP_CARD_STATE:
1127 {
1128 ahd_dump_card_state(ahd);
1129 break;
1130 }
1131 case PDATA_REINIT:
1132 {
1133#ifdef AHD_DEBUG
1134 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1135 printf("%s: PDATA_REINIT - DFCNTRL = 0x%x "
1136 "SG_CACHE_SHADOW = 0x%x\n",
1137 ahd_name(ahd), ahd_inb(ahd, DFCNTRL),
1138 ahd_inb(ahd, SG_CACHE_SHADOW));
1139 }
1140#endif
1141 ahd_reinitialize_dataptrs(ahd);
1142 break;
1143 }
1144 case HOST_MSG_LOOP:
1145 {
1146 struct ahd_devinfo devinfo;
1147
1148 /*
1149 * The sequencer has encountered a message phase
1150 * that requires host assistance for completion.
1151 * While handling the message phase(s), we will be
1152 * notified by the sequencer after each byte is
1153 * transfered so we can track bus phase changes.
1154 *
1155 * If this is the first time we've seen a HOST_MSG_LOOP
1156 * interrupt, initialize the state of the host message
1157 * loop.
1158 */
1159 ahd_fetch_devinfo(ahd, &devinfo);
1160 if (ahd->msg_type == MSG_TYPE_NONE) {
1161 struct scb *scb;
1162 u_int scb_index;
1163 u_int bus_phase;
1164
1165 bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
1166 if (bus_phase != P_MESGIN
1167 && bus_phase != P_MESGOUT) {
1168 printf("ahd_intr: HOST_MSG_LOOP bad "
1169 "phase 0x%x\n", bus_phase);
1170 /*
1171 * Probably transitioned to bus free before
1172 * we got here. Just punt the message.
1173 */
1174 ahd_dump_card_state(ahd);
1175 ahd_clear_intstat(ahd);
1176 ahd_restart(ahd);
1177 return;
1178 }
1179
1180 scb_index = ahd_get_scbptr(ahd);
1181 scb = ahd_lookup_scb(ahd, scb_index);
1182 if (devinfo.role == ROLE_INITIATOR) {
1183 if (bus_phase == P_MESGOUT)
1184 ahd_setup_initiator_msgout(ahd,
1185 &devinfo,
1186 scb);
1187 else {
1188 ahd->msg_type =
1189 MSG_TYPE_INITIATOR_MSGIN;
1190 ahd->msgin_index = 0;
1191 }
1192 }
1193#ifdef AHD_TARGET_MODE
1194 else {
1195 if (bus_phase == P_MESGOUT) {
1196 ahd->msg_type =
1197 MSG_TYPE_TARGET_MSGOUT;
1198 ahd->msgin_index = 0;
1199 }
1200 else
1201 ahd_setup_target_msgin(ahd,
1202 &devinfo,
1203 scb);
1204 }
1205#endif
1206 }
1207
1208 ahd_handle_message_phase(ahd);
1209 break;
1210 }
1211 case NO_MATCH:
1212 {
1213 /* Ensure we don't leave the selection hardware on */
1214 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
1215 ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
1216
1217 printf("%s:%c:%d: no active SCB for reconnecting "
1218 "target - issuing BUS DEVICE RESET\n",
1219 ahd_name(ahd), 'A', ahd_inb(ahd, SELID) >> 4);
1220 printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
1221 "REG0 == 0x%x ACCUM = 0x%x\n",
1222 ahd_inb(ahd, SAVED_SCSIID), ahd_inb(ahd, SAVED_LUN),
1223 ahd_inw(ahd, REG0), ahd_inb(ahd, ACCUM));
1224 printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
1225 "SINDEX == 0x%x\n",
1226 ahd_inb(ahd, SEQ_FLAGS), ahd_get_scbptr(ahd),
1227 ahd_find_busy_tcl(ahd,
1228 BUILD_TCL(ahd_inb(ahd, SAVED_SCSIID),
1229 ahd_inb(ahd, SAVED_LUN))),
1230 ahd_inw(ahd, SINDEX));
1231 printf("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
1232 "SCB_CONTROL == 0x%x\n",
1233 ahd_inb(ahd, SELID), ahd_inb_scbram(ahd, SCB_SCSIID),
1234 ahd_inb_scbram(ahd, SCB_LUN),
1235 ahd_inb_scbram(ahd, SCB_CONTROL));
1236 printf("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n",
1237 ahd_inb(ahd, SCSIBUS), ahd_inb(ahd, SCSISIGI));
1238 printf("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0));
1239 printf("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
1240 ahd_dump_card_state(ahd);
1241 ahd->msgout_buf[0] = MSG_BUS_DEV_RESET;
1242 ahd->msgout_len = 1;
1243 ahd->msgout_index = 0;
1244 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
1245 ahd_outb(ahd, MSG_OUT, HOST_MSG);
1246 ahd_assert_atn(ahd);
1247 break;
1248 }
1249 case PROTO_VIOLATION:
1250 {
1251 ahd_handle_proto_violation(ahd);
1252 break;
1253 }
1254 case IGN_WIDE_RES:
1255 {
1256 struct ahd_devinfo devinfo;
1257
1258 ahd_fetch_devinfo(ahd, &devinfo);
1259 ahd_handle_ign_wide_residue(ahd, &devinfo);
1260 break;
1261 }
1262 case BAD_PHASE:
1263 {
1264 u_int lastphase;
1265
1266 lastphase = ahd_inb(ahd, LASTPHASE);
1267 printf("%s:%c:%d: unknown scsi bus phase %x, "
1268 "lastphase = 0x%x. Attempting to continue\n",
1269 ahd_name(ahd), 'A',
1270 SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
1271 lastphase, ahd_inb(ahd, SCSISIGI));
1272 break;
1273 }
1274 case MISSED_BUSFREE:
1275 {
1276 u_int lastphase;
1277
1278 lastphase = ahd_inb(ahd, LASTPHASE);
1279 printf("%s:%c:%d: Missed busfree. "
1280 "Lastphase = 0x%x, Curphase = 0x%x\n",
1281 ahd_name(ahd), 'A',
1282 SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
1283 lastphase, ahd_inb(ahd, SCSISIGI));
1284 ahd_restart(ahd);
1285 return;
1286 }
1287 case DATA_OVERRUN:
1288 {
1289 /*
1290 * When the sequencer detects an overrun, it
1291 * places the controller in "BITBUCKET" mode
1292 * and allows the target to complete its transfer.
1293 * Unfortunately, none of the counters get updated
1294 * when the controller is in this mode, so we have
1295 * no way of knowing how large the overrun was.
1296 */
1297 struct scb *scb;
1298 u_int scbindex;
1299#ifdef AHD_DEBUG
1300 u_int lastphase;
1301#endif
1302
1303 scbindex = ahd_get_scbptr(ahd);
1304 scb = ahd_lookup_scb(ahd, scbindex);
1305#ifdef AHD_DEBUG
1306 lastphase = ahd_inb(ahd, LASTPHASE);
1307 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1308 ahd_print_path(ahd, scb);
1309 printf("data overrun detected %s. Tag == 0x%x.\n",
1310 ahd_lookup_phase_entry(lastphase)->phasemsg,
1311 SCB_GET_TAG(scb));
1312 ahd_print_path(ahd, scb);
1313 printf("%s seen Data Phase. Length = %ld. "
1314 "NumSGs = %d.\n",
1315 ahd_inb(ahd, SEQ_FLAGS) & DPHASE
1316 ? "Have" : "Haven't",
1317 ahd_get_transfer_length(scb), scb->sg_count);
1318 ahd_dump_sglist(scb);
1319 }
1320#endif
1321
1322 /*
1323 * Set this and it will take effect when the
1324 * target does a command complete.
1325 */
1326 ahd_freeze_devq(ahd, scb);
1327 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1328 ahd_freeze_scb(scb);
1329 break;
1330 }
1331 case MKMSG_FAILED:
1332 {
1333 struct ahd_devinfo devinfo;
1334 struct scb *scb;
1335 u_int scbid;
1336
1337 ahd_fetch_devinfo(ahd, &devinfo);
1338 printf("%s:%c:%d:%d: Attempt to issue message failed\n",
1339 ahd_name(ahd), devinfo.channel, devinfo.target,
1340 devinfo.lun);
1341 scbid = ahd_get_scbptr(ahd);
1342 scb = ahd_lookup_scb(ahd, scbid);
1343 if (scb != NULL
1344 && (scb->flags & SCB_RECOVERY_SCB) != 0)
1345 /*
1346 * Ensure that we didn't put a second instance of this
1347 * SCB into the QINFIFO.
1348 */
1349 ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
1350 SCB_GET_CHANNEL(ahd, scb),
1351 SCB_GET_LUN(scb), SCB_GET_TAG(scb),
1352 ROLE_INITIATOR, /*status*/0,
1353 SEARCH_REMOVE);
1354 ahd_outb(ahd, SCB_CONTROL,
1355 ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
1356 break;
1357 }
1358 case TASKMGMT_FUNC_COMPLETE:
1359 {
1360 u_int scbid;
1361 struct scb *scb;
1362
1363 scbid = ahd_get_scbptr(ahd);
1364 scb = ahd_lookup_scb(ahd, scbid);
1365 if (scb != NULL) {
1366 u_int lun;
1367 u_int tag;
1368 cam_status error;
1369
1370 ahd_print_path(ahd, scb);
1371 printf("Task Management Func 0x%x Complete\n",
1372 scb->hscb->task_management);
1373 lun = CAM_LUN_WILDCARD;
1374 tag = SCB_LIST_NULL;
1375
1376 switch (scb->hscb->task_management) {
1377 case SIU_TASKMGMT_ABORT_TASK:
1378 tag = SCB_GET_TAG(scb);
1379 case SIU_TASKMGMT_ABORT_TASK_SET:
1380 case SIU_TASKMGMT_CLEAR_TASK_SET:
1381 lun = scb->hscb->lun;
1382 error = CAM_REQ_ABORTED;
1383 ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
1384 'A', lun, tag, ROLE_INITIATOR,
1385 error);
1386 break;
1387 case SIU_TASKMGMT_LUN_RESET:
1388 lun = scb->hscb->lun;
1389 case SIU_TASKMGMT_TARGET_RESET:
1390 {
1391 struct ahd_devinfo devinfo;
1392
1393 ahd_scb_devinfo(ahd, &devinfo, scb);
1394 error = CAM_BDR_SENT;
1395 ahd_handle_devreset(ahd, &devinfo, lun,
1396 CAM_BDR_SENT,
1397 lun != CAM_LUN_WILDCARD
1398 ? "Lun Reset"
1399 : "Target Reset",
1400 /*verbose_level*/0);
1401 break;
1402 }
1403 default:
1404 panic("Unexpected TaskMgmt Func\n");
1405 break;
1406 }
1407 }
1408 break;
1409 }
1410 case TASKMGMT_CMD_CMPLT_OKAY:
1411 {
1412 u_int scbid;
1413 struct scb *scb;
1414
1415 /*
1416 * An ABORT TASK TMF failed to be delivered before
1417 * the targeted command completed normally.
1418 */
1419 scbid = ahd_get_scbptr(ahd);
1420 scb = ahd_lookup_scb(ahd, scbid);
1421 if (scb != NULL) {
1422 /*
1423 * Remove the second instance of this SCB from
1424 * the QINFIFO if it is still there.
1425 */
1426 ahd_print_path(ahd, scb);
1427 printf("SCB completes before TMF\n");
1428 /*
1429 * Handle losing the race. Wait until any
1430 * current selection completes. We will then
1431 * set the TMF back to zero in this SCB so that
1432 * the sequencer doesn't bother to issue another
1433 * sequencer interrupt for its completion.
1434 */
1435 while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
1436 && (ahd_inb(ahd, SSTAT0) & SELDO) == 0
1437 && (ahd_inb(ahd, SSTAT1) & SELTO) == 0)
1438 ;
1439 ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0);
1440 ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
1441 SCB_GET_CHANNEL(ahd, scb),
1442 SCB_GET_LUN(scb), SCB_GET_TAG(scb),
1443 ROLE_INITIATOR, /*status*/0,
1444 SEARCH_REMOVE);
1445 }
1446 break;
1447 }
1448 case TRACEPOINT0:
1449 case TRACEPOINT1:
1450 case TRACEPOINT2:
1451 case TRACEPOINT3:
1452 printf("%s: Tracepoint %d\n", ahd_name(ahd),
1453 seqintcode - TRACEPOINT0);
1454 break;
1455 case NO_SEQINT:
1456 break;
1457 case SAW_HWERR:
1458 ahd_handle_hwerrint(ahd);
1459 break;
1460 default:
1461 printf("%s: Unexpected SEQINTCODE %d\n", ahd_name(ahd),
1462 seqintcode);
1463 break;
1464 }
1465 /*
1466 * The sequencer is paused immediately on
1467 * a SEQINT, so we should restart it when
1468 * we're done.
1469 */
1470 ahd_unpause(ahd);
1471}
1472
1473void
1474ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
1475{
1476 struct scb *scb;
1477 u_int status0;
1478 u_int status3;
1479 u_int status;
1480 u_int lqistat1;
1481 u_int lqostat0;
1482 u_int scbid;
1483 u_int busfreetime;
1484
1485 ahd_update_modes(ahd);
1486 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1487
1488 status3 = ahd_inb(ahd, SSTAT3) & (NTRAMPERR|OSRAMPERR);
1489 status0 = ahd_inb(ahd, SSTAT0) & (IOERR|OVERRUN|SELDI|SELDO);
1490 status = ahd_inb(ahd, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
1491 lqistat1 = ahd_inb(ahd, LQISTAT1);
1492 lqostat0 = ahd_inb(ahd, LQOSTAT0);
1493 busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
1494 if ((status0 & (SELDI|SELDO)) != 0) {
1495 u_int simode0;
1496
1497 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
1498 simode0 = ahd_inb(ahd, SIMODE0);
1499 status0 &= simode0 & (IOERR|OVERRUN|SELDI|SELDO);
1500 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1501 }
1502 scbid = ahd_get_scbptr(ahd);
1503 scb = ahd_lookup_scb(ahd, scbid);
1504 if (scb != NULL
1505 && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
1506 scb = NULL;
1507
1508 /* Make sure the sequencer is in a safe location. */
1509 ahd_clear_critical_section(ahd);
1510
1511 if ((status0 & IOERR) != 0) {
1512 u_int now_lvd;
1513
1514 now_lvd = ahd_inb(ahd, SBLKCTL) & ENAB40;
1515 printf("%s: Transceiver State Has Changed to %s mode\n",
1516 ahd_name(ahd), now_lvd ? "LVD" : "SE");
1517 ahd_outb(ahd, CLRSINT0, CLRIOERR);
1518 /*
1519 * A change in I/O mode is equivalent to a bus reset.
1520 */
1521 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1522 ahd_pause(ahd);
1523 ahd_setup_iocell_workaround(ahd);
1524 ahd_unpause(ahd);
1525 } else if ((status0 & OVERRUN) != 0) {
1526 printf("%s: SCSI offset overrun detected. Resetting bus.\n",
1527 ahd_name(ahd));
1528 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1529 } else if ((status & SCSIRSTI) != 0) {
1530 printf("%s: Someone reset channel A\n", ahd_name(ahd));
1531 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE);
1532 } else if ((status & SCSIPERR) != 0) {
1533 ahd_handle_transmission_error(ahd);
1534 } else if (lqostat0 != 0) {
1535 printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0);
1536 ahd_outb(ahd, CLRLQOINT0, lqostat0);
1537 if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
1538 ahd_outb(ahd, CLRLQOINT1, 0);
1539 }
1540 } else if ((status & SELTO) != 0) {
1541 u_int scbid;
1542
1543 /* Stop the selection */
1544 ahd_outb(ahd, SCSISEQ0, 0);
1545
1546 /* No more pending messages */
1547 ahd_clear_msg_state(ahd);
1548
1549 /* Clear interrupt state */
1550 ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
1551
1552 /*
1553 * Although the driver does not care about the
1554 * 'Selection in Progress' status bit, the busy
1555 * LED does. SELINGO is only cleared by a sucessfull
1556 * selection, so we must manually clear it to insure
1557 * the LED turns off just incase no future successful
1558 * selections occur (e.g. no devices on the bus).
1559 */
1560 ahd_outb(ahd, CLRSINT0, CLRSELINGO);
1561
1562 scbid = ahd_inw(ahd, WAITING_TID_HEAD);
1563 scb = ahd_lookup_scb(ahd, scbid);
1564 if (scb == NULL) {
1565 printf("%s: ahd_intr - referenced scb not "
1566 "valid during SELTO scb(0x%x)\n",
1567 ahd_name(ahd), scbid);
1568 ahd_dump_card_state(ahd);
1569 } else {
1570 struct ahd_devinfo devinfo;
1571#ifdef AHD_DEBUG
1572 if ((ahd_debug & AHD_SHOW_SELTO) != 0) {
1573 ahd_print_path(ahd, scb);
1574 printf("Saw Selection Timeout for SCB 0x%x\n",
1575 scbid);
1576 }
1577#endif
1578 /*
1579 * Force a renegotiation with this target just in
1580 * case the cable was pulled and will later be
1581 * re-attached. The target may forget its negotiation
1582 * settings with us should it attempt to reselect
1583 * during the interruption. The target will not issue
1584 * a unit attention in this case, so we must always
1585 * renegotiate.
1586 */
1587 ahd_scb_devinfo(ahd, &devinfo, scb);
1588 ahd_force_renegotiation(ahd, &devinfo);
1589 ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT);
1590 ahd_freeze_devq(ahd, scb);
1591 }
1592 ahd_outb(ahd, CLRINT, CLRSCSIINT);
1593 ahd_iocell_first_selection(ahd);
1594 ahd_unpause(ahd);
1595 } else if ((status0 & (SELDI|SELDO)) != 0) {
1596 ahd_iocell_first_selection(ahd);
1597 ahd_unpause(ahd);
1598 } else if (status3 != 0) {
1599 printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n",
1600 ahd_name(ahd), status3);
1601 ahd_outb(ahd, CLRSINT3, status3);
1602 } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) {
1603 ahd_handle_lqiphase_error(ahd, lqistat1);
1604 } else if ((lqistat1 & LQICRCI_NLQ) != 0) {
1605 /*
1606 * This status can be delayed during some
1607 * streaming operations. The SCSIPHASE
1608 * handler has already dealt with this case
1609 * so just clear the error.
1610 */
1611 ahd_outb(ahd, CLRLQIINT1, CLRLQICRCI_NLQ);
1612 } else if ((status & BUSFREE) != 0) {
1613 u_int lqostat1;
1614 int restart;
1615 int clear_fifo;
1616 int packetized;
1617 u_int mode;
1618
1619 /*
1620 * Clear our selection hardware as soon as possible.
1621 * We may have an entry in the waiting Q for this target,
1622 * that is affected by this busfree and we don't want to
1623 * go about selecting the target while we handle the event.
1624 */
1625 ahd_outb(ahd, SCSISEQ0, 0);
1626
1627 /*
1628 * Determine what we were up to at the time of
1629 * the busfree.
1630 */
1631 mode = AHD_MODE_SCSI;
1632 busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
1633 lqostat1 = ahd_inb(ahd, LQOSTAT1);
1634 switch (busfreetime) {
1635 case BUSFREE_DFF0:
1636 case BUSFREE_DFF1:
1637 {
1638 u_int scbid;
1639 struct scb *scb;
1640
1641 mode = busfreetime == BUSFREE_DFF0
1642 ? AHD_MODE_DFF0 : AHD_MODE_DFF1;
1643 ahd_set_modes(ahd, mode, mode);
1644 scbid = ahd_get_scbptr(ahd);
1645 scb = ahd_lookup_scb(ahd, scbid);
1646 if (scb == NULL) {
1647 printf("%s: Invalid SCB %d in DFF%d "
1648 "during unexpected busfree\n",
1649 ahd_name(ahd), scbid, mode);
1650 packetized = 0;
1651 } else
1652 packetized = (scb->flags & SCB_PACKETIZED) != 0;
1653 clear_fifo = 1;
1654 break;
1655 }
1656 case BUSFREE_LQO:
1657 clear_fifo = 0;
1658 packetized = 1;
1659 break;
1660 default:
1661 clear_fifo = 0;
1662 packetized = (lqostat1 & LQOBUSFREE) != 0;
1663 if (!packetized
1664 && ahd_inb(ahd, LASTPHASE) == P_BUSFREE)
1665 packetized = 1;
1666 break;
1667 }
1668
1669#ifdef AHD_DEBUG
1670 if ((ahd_debug & AHD_SHOW_MISC) != 0)
1671 printf("Saw Busfree. Busfreetime = 0x%x.\n",
1672 busfreetime);
1673#endif
1674 /*
1675 * Busfrees that occur in non-packetized phases are
1676 * handled by the nonpkt_busfree handler.
1677 */
1678 if (packetized && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) {
1679 restart = ahd_handle_pkt_busfree(ahd, busfreetime);
1680 } else {
1681 packetized = 0;
1682 restart = ahd_handle_nonpkt_busfree(ahd);
1683 }
1684 /*
1685 * Clear the busfree interrupt status. The setting of
1686 * the interrupt is a pulse, so in a perfect world, we
1687 * would not need to muck with the ENBUSFREE logic. This
1688 * would ensure that if the bus moves on to another
1689 * connection, busfree protection is still in force. If
1690 * BUSFREEREV is broken, however, we must manually clear
1691 * the ENBUSFREE if the busfree occurred during a non-pack
1692 * connection so that we don't get false positives during
1693 * future, packetized, connections.
1694 */
1695 ahd_outb(ahd, CLRSINT1, CLRBUSFREE);
1696 if (packetized == 0
1697 && (ahd->bugs & AHD_BUSFREEREV_BUG) != 0)
1698 ahd_outb(ahd, SIMODE1,
1699 ahd_inb(ahd, SIMODE1) & ~ENBUSFREE);
1700
1701 if (clear_fifo)
1702 ahd_clear_fifo(ahd, mode);
1703
1704 ahd_clear_msg_state(ahd);
1705 ahd_outb(ahd, CLRINT, CLRSCSIINT);
1706 if (restart) {
1707 ahd_restart(ahd);
1708 } else {
1709 ahd_unpause(ahd);
1710 }
1711 } else {
1712 printf("%s: Missing case in ahd_handle_scsiint. status = %x\n",
1713 ahd_name(ahd), status);
1714 ahd_dump_card_state(ahd);
1715 ahd_clear_intstat(ahd);
1716 ahd_unpause(ahd);
1717 }
1718}
1719
1720static void
1721ahd_handle_transmission_error(struct ahd_softc *ahd)
1722{
1723 struct scb *scb;
1724 u_int scbid;
1725 u_int lqistat1;
1726 u_int lqistat2;
1727 u_int msg_out;
1728 u_int curphase;
1729 u_int lastphase;
1730 u_int perrdiag;
1731 u_int cur_col;
1732 int silent;
1733
1734 scb = NULL;
1735 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1736 lqistat1 = ahd_inb(ahd, LQISTAT1) & ~(LQIPHASE_LQ|LQIPHASE_NLQ);
1737 lqistat2 = ahd_inb(ahd, LQISTAT2);
1738 if ((lqistat1 & (LQICRCI_NLQ|LQICRCI_LQ)) == 0
1739 && (ahd->bugs & AHD_NLQICRC_DELAYED_BUG) != 0) {
1740 u_int lqistate;
1741
1742 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
1743 lqistate = ahd_inb(ahd, LQISTATE);
1744 if ((lqistate >= 0x1E && lqistate <= 0x24)
1745 || (lqistate == 0x29)) {
1746#ifdef AHD_DEBUG
1747 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1748 printf("%s: NLQCRC found via LQISTATE\n",
1749 ahd_name(ahd));
1750 }
1751#endif
1752 lqistat1 |= LQICRCI_NLQ;
1753 }
1754 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1755 }
1756
1757 ahd_outb(ahd, CLRLQIINT1, lqistat1);
1758 lastphase = ahd_inb(ahd, LASTPHASE);
1759 curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
1760 perrdiag = ahd_inb(ahd, PERRDIAG);
1761 msg_out = MSG_INITIATOR_DET_ERR;
1762 ahd_outb(ahd, CLRSINT1, CLRSCSIPERR);
1763
1764 /*
1765 * Try to find the SCB associated with this error.
1766 */
1767 silent = FALSE;
1768 if (lqistat1 == 0
1769 || (lqistat1 & LQICRCI_NLQ) != 0) {
1770 if ((lqistat1 & (LQICRCI_NLQ|LQIOVERI_NLQ)) != 0)
1771 ahd_set_active_fifo(ahd);
1772 scbid = ahd_get_scbptr(ahd);
1773 scb = ahd_lookup_scb(ahd, scbid);
1774 if (scb != NULL && SCB_IS_SILENT(scb))
1775 silent = TRUE;
1776 }
1777
1778 cur_col = 0;
1779 if (silent == FALSE) {
1780 printf("%s: Transmission error detected\n", ahd_name(ahd));
1781 ahd_lqistat1_print(lqistat1, &cur_col, 50);
1782 ahd_lastphase_print(lastphase, &cur_col, 50);
1783 ahd_scsisigi_print(curphase, &cur_col, 50);
1784 ahd_perrdiag_print(perrdiag, &cur_col, 50);
1785 printf("\n");
1786 ahd_dump_card_state(ahd);
1787 }
1788
1789 if ((lqistat1 & (LQIOVERI_LQ|LQIOVERI_NLQ)) != 0) {
1790 if (silent == FALSE) {
1791 printf("%s: Gross protocol error during incoming "
1792 "packet. lqistat1 == 0x%x. Resetting bus.\n",
1793 ahd_name(ahd), lqistat1);
1794 }
1795 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1796 return;
1797 } else if ((lqistat1 & LQICRCI_LQ) != 0) {
1798 /*
1799 * A CRC error has been detected on an incoming LQ.
1800 * The bus is currently hung on the last ACK.
1801 * Hit LQIRETRY to release the last ack, and
1802 * wait for the sequencer to determine that ATNO
1803 * is asserted while in message out to take us
1804 * to our host message loop. No NONPACKREQ or
1805 * LQIPHASE type errors will occur in this
1806 * scenario. After this first LQIRETRY, the LQI
1807 * manager will be in ISELO where it will
1808 * happily sit until another packet phase begins.
1809 * Unexpected bus free detection is enabled
1810 * through any phases that occur after we release
1811 * this last ack until the LQI manager sees a
1812 * packet phase. This implies we may have to
1813 * ignore a perfectly valid "unexected busfree"
1814 * after our "initiator detected error" message is
1815 * sent. A busfree is the expected response after
1816 * we tell the target that it's L_Q was corrupted.
1817 * (SPI4R09 10.7.3.3.3)
1818 */
1819 ahd_outb(ahd, LQCTL2, LQIRETRY);
1820 printf("LQIRetry for LQICRCI_LQ to release ACK\n");
1821 } else if ((lqistat1 & LQICRCI_NLQ) != 0) {
1822 /*
1823 * We detected a CRC error in a NON-LQ packet.
1824 * The hardware has varying behavior in this situation
1825 * depending on whether this packet was part of a
1826 * stream or not.
1827 *
1828 * PKT by PKT mode:
1829 * The hardware has already acked the complete packet.
1830 * If the target honors our outstanding ATN condition,
1831 * we should be (or soon will be) in MSGOUT phase.
1832 * This will trigger the LQIPHASE_LQ status bit as the
1833 * hardware was expecting another LQ. Unexpected
1834 * busfree detection is enabled. Once LQIPHASE_LQ is
1835 * true (first entry into host message loop is much
1836 * the same), we must clear LQIPHASE_LQ and hit
1837 * LQIRETRY so the hardware is ready to handle
1838 * a future LQ. NONPACKREQ will not be asserted again
1839 * once we hit LQIRETRY until another packet is
1840 * processed. The target may either go busfree
1841 * or start another packet in response to our message.
1842 *
1843 * Read Streaming P0 asserted:
1844 * If we raise ATN and the target completes the entire
1845 * stream (P0 asserted during the last packet), the
1846 * hardware will ack all data and return to the ISTART
1847 * state. When the target reponds to our ATN condition,
1848 * LQIPHASE_LQ will be asserted. We should respond to
1849 * this with an LQIRETRY to prepare for any future
1850 * packets. NONPACKREQ will not be asserted again
1851 * once we hit LQIRETRY until another packet is
1852 * processed. The target may either go busfree or
1853 * start another packet in response to our message.
1854 * Busfree detection is enabled.
1855 *
1856 * Read Streaming P0 not asserted:
1857 * If we raise ATN and the target transitions to
1858 * MSGOUT in or after a packet where P0 is not
1859 * asserted, the hardware will assert LQIPHASE_NLQ.
1860 * We should respond to the LQIPHASE_NLQ with an
1861 * LQIRETRY. Should the target stay in a non-pkt
1862 * phase after we send our message, the hardware
1863 * will assert LQIPHASE_LQ. Recovery is then just as
1864 * listed above for the read streaming with P0 asserted.
1865 * Busfree detection is enabled.
1866 */
1867 if (silent == FALSE)
1868 printf("LQICRC_NLQ\n");
1869 if (scb == NULL) {
1870 printf("%s: No SCB valid for LQICRC_NLQ. "
1871 "Resetting bus\n", ahd_name(ahd));
1872 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1873 return;
1874 }
1875 } else if ((lqistat1 & LQIBADLQI) != 0) {
1876 printf("Need to handle BADLQI!\n");
1877 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1878 return;
1879 } else if ((perrdiag & (PARITYERR|PREVPHASE)) == PARITYERR) {
1880 if ((curphase & ~P_DATAIN_DT) != 0) {
1881 /* Ack the byte. So we can continue. */
1882 if (silent == FALSE)
1883 printf("Acking %s to clear perror\n",
1884 ahd_lookup_phase_entry(curphase)->phasemsg);
1885 ahd_inb(ahd, SCSIDAT);
1886 }
1887
1888 if (curphase == P_MESGIN)
1889 msg_out = MSG_PARITY_ERROR;
1890 }
1891
1892 /*
1893 * We've set the hardware to assert ATN if we
1894 * get a parity error on "in" phases, so all we
1895 * need to do is stuff the message buffer with
1896 * the appropriate message. "In" phases have set
1897 * mesg_out to something other than MSG_NOP.
1898 */
1899 ahd->send_msg_perror = msg_out;
1900 if (scb != NULL && msg_out == MSG_INITIATOR_DET_ERR)
1901 scb->flags |= SCB_TRANSMISSION_ERROR;
1902 ahd_outb(ahd, MSG_OUT, HOST_MSG);
1903 ahd_outb(ahd, CLRINT, CLRSCSIINT);
1904 ahd_unpause(ahd);
1905}
1906
1907static void
1908ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1)
1909{
1910 /*
1911 * Clear the sources of the interrupts.
1912 */
1913 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1914 ahd_outb(ahd, CLRLQIINT1, lqistat1);
1915
1916 /*
1917 * If the "illegal" phase changes were in response
1918 * to our ATN to flag a CRC error, AND we ended up
1919 * on packet boundaries, clear the error, restart the
1920 * LQI manager as appropriate, and go on our merry
1921 * way toward sending the message. Otherwise, reset
1922 * the bus to clear the error.
1923 */
1924 ahd_set_active_fifo(ahd);
1925 if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0
1926 && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) {
1927 if ((lqistat1 & LQIPHASE_LQ) != 0) {
1928 printf("LQIRETRY for LQIPHASE_LQ\n");
1929 ahd_outb(ahd, LQCTL2, LQIRETRY);
1930 } else if ((lqistat1 & LQIPHASE_NLQ) != 0) {
1931 printf("LQIRETRY for LQIPHASE_NLQ\n");
1932 ahd_outb(ahd, LQCTL2, LQIRETRY);
1933 } else
1934 panic("ahd_handle_lqiphase_error: No phase errors\n");
1935 ahd_dump_card_state(ahd);
1936 ahd_outb(ahd, CLRINT, CLRSCSIINT);
1937 ahd_unpause(ahd);
1938 } else {
1939 printf("Reseting Channel for LQI Phase error\n");
1940 ahd_dump_card_state(ahd);
1941 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
1942 }
1943}
1944
1945/*
1946 * Packetized unexpected or expected busfree.
1947 * Entered in mode based on busfreetime.
1948 */
1949static int
1950ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
1951{
1952 u_int lqostat1;
1953
1954 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
1955 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
1956 lqostat1 = ahd_inb(ahd, LQOSTAT1);
1957 if ((lqostat1 & LQOBUSFREE) != 0) {
1958 struct scb *scb;
1959 u_int scbid;
1960 u_int saved_scbptr;
1961 u_int waiting_h;
1962 u_int waiting_t;
1963 u_int next;
1964
1965 if ((busfreetime & BUSFREE_LQO) == 0)
1966 printf("%s: Warning, BUSFREE time is 0x%x. "
1967 "Expected BUSFREE_LQO.\n",
1968 ahd_name(ahd), busfreetime);
1969 /*
1970 * The LQO manager detected an unexpected busfree
1971 * either:
1972 *
1973 * 1) During an outgoing LQ.
1974 * 2) After an outgoing LQ but before the first
1975 * REQ of the command packet.
1976 * 3) During an outgoing command packet.
1977 *
1978 * In all cases, CURRSCB is pointing to the
1979 * SCB that encountered the failure. Clean
1980 * up the queue, clear SELDO and LQOBUSFREE,
1981 * and allow the sequencer to restart the select
1982 * out at its lesure.
1983 */
1984 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1985 scbid = ahd_inw(ahd, CURRSCB);
1986 scb = ahd_lookup_scb(ahd, scbid);
1987 if (scb == NULL)
1988 panic("SCB not valid during LQOBUSFREE");
1989 /*
1990 * Clear the status.
1991 */
1992 ahd_outb(ahd, CLRLQOINT1, CLRLQOBUSFREE);
1993 if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0)
1994 ahd_outb(ahd, CLRLQOINT1, 0);
1995 ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
1996 ahd_flush_device_writes(ahd);
1997 ahd_outb(ahd, CLRSINT0, CLRSELDO);
1998
1999 /*
2000 * Return the LQO manager to its idle loop. It will
2001 * not do this automatically if the busfree occurs
2002 * after the first REQ of either the LQ or command
2003 * packet or between the LQ and command packet.
2004 */
2005 ahd_outb(ahd, LQCTL2, ahd_inb(ahd, LQCTL2) | LQOTOIDLE);
2006
2007 /*
2008 * Update the waiting for selection queue so
2009 * we restart on the correct SCB.
2010 */
2011 waiting_h = ahd_inw(ahd, WAITING_TID_HEAD);
2012 saved_scbptr = ahd_get_scbptr(ahd);
2013 if (waiting_h != scbid) {
2014
2015 ahd_outw(ahd, WAITING_TID_HEAD, scbid);
2016 waiting_t = ahd_inw(ahd, WAITING_TID_TAIL);
2017 if (waiting_t == waiting_h) {
2018 ahd_outw(ahd, WAITING_TID_TAIL, scbid);
2019 next = SCB_LIST_NULL;
2020 } else {
2021 ahd_set_scbptr(ahd, waiting_h);
2022 next = ahd_inw_scbram(ahd, SCB_NEXT2);
2023 }
2024 ahd_set_scbptr(ahd, scbid);
2025 ahd_outw(ahd, SCB_NEXT2, next);
2026 }
2027 ahd_set_scbptr(ahd, saved_scbptr);
2028 if (scb->crc_retry_count < AHD_MAX_LQ_CRC_ERRORS) {
2029 if (SCB_IS_SILENT(scb) == FALSE) {
2030 ahd_print_path(ahd, scb);
2031 printf("Probable outgoing LQ CRC error. "
2032 "Retrying command\n");
2033 }
2034 scb->crc_retry_count++;
2035 } else {
2036 ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
2037 ahd_freeze_scb(scb);
2038 ahd_freeze_devq(ahd, scb);
2039 }
2040 /* Return unpausing the sequencer. */
2041 return (0);
2042 } else if ((ahd_inb(ahd, PERRDIAG) & PARITYERR) != 0) {
2043 /*
2044 * Ignore what are really parity errors that
2045 * occur on the last REQ of a free running
2046 * clock prior to going busfree. Some drives
2047 * do not properly active negate just before
2048 * going busfree resulting in a parity glitch.
2049 */
2050 ahd_outb(ahd, CLRSINT1, CLRSCSIPERR|CLRBUSFREE);
2051#ifdef AHD_DEBUG
2052 if ((ahd_debug & AHD_SHOW_MASKED_ERRORS) != 0)
2053 printf("%s: Parity on last REQ detected "
2054 "during busfree phase.\n",
2055 ahd_name(ahd));
2056#endif
2057 /* Return unpausing the sequencer. */
2058 return (0);
2059 }
2060 if (ahd->src_mode != AHD_MODE_SCSI) {
2061 u_int scbid;
2062 struct scb *scb;
2063
2064 scbid = ahd_get_scbptr(ahd);
2065 scb = ahd_lookup_scb(ahd, scbid);
2066 ahd_print_path(ahd, scb);
2067 printf("Unexpected PKT busfree condition\n");
2068 ahd_dump_card_state(ahd);
2069 ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A',
2070 SCB_GET_LUN(scb), SCB_GET_TAG(scb),
2071 ROLE_INITIATOR, CAM_UNEXP_BUSFREE);
2072
2073 /* Return restarting the sequencer. */
2074 return (1);
2075 }
2076 printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd));
2077 ahd_dump_card_state(ahd);
2078 /* Restart the sequencer. */
2079 return (1);
2080}
2081
2082/*
2083 * Non-packetized unexpected or expected busfree.
2084 */
2085static int
2086ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
2087{
2088 struct ahd_devinfo devinfo;
2089 struct scb *scb;
2090 u_int lastphase;
2091 u_int saved_scsiid;
2092 u_int saved_lun;
2093 u_int target;
2094 u_int initiator_role_id;
2095 u_int scbid;
2096 u_int ppr_busfree;
2097 int printerror;
2098
2099 /*
2100 * Look at what phase we were last in. If its message out,
2101 * chances are pretty good that the busfree was in response
2102 * to one of our abort requests.
2103 */
2104 lastphase = ahd_inb(ahd, LASTPHASE);
2105 saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
2106 saved_lun = ahd_inb(ahd, SAVED_LUN);
2107 target = SCSIID_TARGET(ahd, saved_scsiid);
2108 initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
2109 ahd_compile_devinfo(&devinfo, initiator_role_id,
2110 target, saved_lun, 'A', ROLE_INITIATOR);
2111 printerror = 1;
2112
2113 scbid = ahd_get_scbptr(ahd);
2114 scb = ahd_lookup_scb(ahd, scbid);
2115 if (scb != NULL
2116 && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
2117 scb = NULL;
2118
2119 ppr_busfree = (ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0;
2120 if (lastphase == P_MESGOUT) {
2121 u_int tag;
2122
2123 tag = SCB_LIST_NULL;
2124 if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE)
2125 || ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) {
2126 int found;
2127 int sent_msg;
2128
2129 if (scb == NULL) {
2130 ahd_print_devinfo(ahd, &devinfo);
2131 printf("Abort for unidentified "
2132 "connection completed.\n");
2133 /* restart the sequencer. */
2134 return (1);
2135 }
2136 sent_msg = ahd->msgout_buf[ahd->msgout_index - 1];
2137 ahd_print_path(ahd, scb);
2138 printf("SCB %d - Abort%s Completed.\n",
2139 SCB_GET_TAG(scb),
2140 sent_msg == MSG_ABORT_TAG ? "" : " Tag");
2141
2142 if (sent_msg == MSG_ABORT_TAG)
2143 tag = SCB_GET_TAG(scb);
2144
2145 if ((scb->flags & SCB_CMDPHASE_ABORT) != 0) {
2146 /*
2147 * This abort is in response to an
2148 * unexpected switch to command phase
2149 * for a packetized connection. Since
2150 * the identify message was never sent,
2151 * "saved lun" is 0. We really want to
2152 * abort only the SCB that encountered
2153 * this error, which could have a different
2154 * lun. The SCB will be retried so the OS
2155 * will see the UA after renegotiating to
2156 * packetized.
2157 */
2158 tag = SCB_GET_TAG(scb);
2159 saved_lun = scb->hscb->lun;
2160 }
2161 found = ahd_abort_scbs(ahd, target, 'A', saved_lun,
2162 tag, ROLE_INITIATOR,
2163 CAM_REQ_ABORTED);
2164 printf("found == 0x%x\n", found);
2165 printerror = 0;
2166 } else if (ahd_sent_msg(ahd, AHDMSG_1B,
2167 MSG_BUS_DEV_RESET, TRUE)) {
2168#ifdef __FreeBSD__
2169 /*
2170 * Don't mark the user's request for this BDR
2171 * as completing with CAM_BDR_SENT. CAM3
2172 * specifies CAM_REQ_CMP.
2173 */
2174 if (scb != NULL
2175 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
2176 && ahd_match_scb(ahd, scb, target, 'A',
2177 CAM_LUN_WILDCARD, SCB_LIST_NULL,
2178 ROLE_INITIATOR))
2179 ahd_set_transaction_status(scb, CAM_REQ_CMP);
2180#endif
2181 ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
2182 CAM_BDR_SENT, "Bus Device Reset",
2183 /*verbose_level*/0);
2184 printerror = 0;
2185 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)
2186 && ppr_busfree == 0) {
2187 struct ahd_initiator_tinfo *tinfo;
2188 struct ahd_tmode_tstate *tstate;
2189
2190 /*
2191 * PPR Rejected. Try non-ppr negotiation
2192 * and retry command.
2193 */
2194#ifdef AHD_DEBUG
2195 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2196 printf("PPR negotiation rejected busfree.\n");
2197#endif
2198 tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
2199 devinfo.our_scsiid,
2200 devinfo.target, &tstate);
2201 tinfo->curr.transport_version = 2;
2202 tinfo->goal.transport_version = 2;
2203 tinfo->goal.ppr_options = 0;
2204 ahd_qinfifo_requeue_tail(ahd, scb);
2205 printerror = 0;
2206 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
2207 && ppr_busfree == 0) {
2208 /*
2209 * Negotiation Rejected. Go-narrow and
2210 * retry command.
2211 */
2212#ifdef AHD_DEBUG
2213 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2214 printf("WDTR negotiation rejected busfree.\n");
2215#endif
2216 ahd_set_width(ahd, &devinfo,
2217 MSG_EXT_WDTR_BUS_8_BIT,
2218 AHD_TRANS_CUR|AHD_TRANS_GOAL,
2219 /*paused*/TRUE);
2220 ahd_qinfifo_requeue_tail(ahd, scb);
2221 printerror = 0;
2222 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
2223 && ppr_busfree == 0) {
2224 /*
2225 * Negotiation Rejected. Go-async and
2226 * retry command.
2227 */
2228#ifdef AHD_DEBUG
2229 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2230 printf("SDTR negotiation rejected busfree.\n");
2231#endif
2232 ahd_set_syncrate(ahd, &devinfo,
2233 /*period*/0, /*offset*/0,
2234 /*ppr_options*/0,
2235 AHD_TRANS_CUR|AHD_TRANS_GOAL,
2236 /*paused*/TRUE);
2237 ahd_qinfifo_requeue_tail(ahd, scb);
2238 printerror = 0;
2239 } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
2240 && ahd_sent_msg(ahd, AHDMSG_1B,
2241 MSG_INITIATOR_DET_ERR, TRUE)) {
2242
2243#ifdef AHD_DEBUG
2244 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2245 printf("Expected IDE Busfree\n");
2246#endif
2247 printerror = 0;
2248 } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE)
2249 && ahd_sent_msg(ahd, AHDMSG_1B,
2250 MSG_MESSAGE_REJECT, TRUE)) {
2251
2252#ifdef AHD_DEBUG
2253 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2254 printf("Expected QAS Reject Busfree\n");
2255#endif
2256 printerror = 0;
2257 }
2258 }
2259
2260 /*
2261 * The busfree required flag is honored at the end of
2262 * the message phases. We check it last in case we
2263 * had to send some other message that caused a busfree.
2264 */
2265 if (printerror != 0
2266 && (lastphase == P_MESGIN || lastphase == P_MESGOUT)
2267 && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) {
2268
2269 ahd_freeze_devq(ahd, scb);
2270 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
2271 ahd_freeze_scb(scb);
2272 if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) {
2273 ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
2274 SCB_GET_CHANNEL(ahd, scb),
2275 SCB_GET_LUN(scb), SCB_LIST_NULL,
2276 ROLE_INITIATOR, CAM_REQ_ABORTED);
2277 } else {
2278#ifdef AHD_DEBUG
2279 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2280 printf("PPR Negotiation Busfree.\n");
2281#endif
2282 ahd_done(ahd, scb);
2283 }
2284 printerror = 0;
2285 }
2286 if (printerror != 0) {
2287 int aborted;
2288
2289 aborted = 0;
2290 if (scb != NULL) {
2291 u_int tag;
2292
2293 if ((scb->hscb->control & TAG_ENB) != 0)
2294 tag = SCB_GET_TAG(scb);
2295 else
2296 tag = SCB_LIST_NULL;
2297 ahd_print_path(ahd, scb);
2298 aborted = ahd_abort_scbs(ahd, target, 'A',
2299 SCB_GET_LUN(scb), tag,
2300 ROLE_INITIATOR,
2301 CAM_UNEXP_BUSFREE);
2302 } else {
2303 /*
2304 * We had not fully identified this connection,
2305 * so we cannot abort anything.
2306 */
2307 printf("%s: ", ahd_name(ahd));
2308 }
2309 if (lastphase != P_BUSFREE)
2310 ahd_force_renegotiation(ahd, &devinfo);
2311 printf("Unexpected busfree %s, %d SCBs aborted, "
2312 "PRGMCNT == 0x%x\n",
2313 ahd_lookup_phase_entry(lastphase)->phasemsg,
2314 aborted,
2315 ahd_inb(ahd, PRGMCNT)
2316 | (ahd_inb(ahd, PRGMCNT+1) << 8));
2317 ahd_dump_card_state(ahd);
2318 }
2319 /* Always restart the sequencer. */
2320 return (1);
2321}
2322
2323static void
2324ahd_handle_proto_violation(struct ahd_softc *ahd)
2325{
2326 struct ahd_devinfo devinfo;
2327 struct scb *scb;
2328 u_int scbid;
2329 u_int seq_flags;
2330 u_int curphase;
2331 u_int lastphase;
2332 int found;
2333
2334 ahd_fetch_devinfo(ahd, &devinfo);
2335 scbid = ahd_get_scbptr(ahd);
2336 scb = ahd_lookup_scb(ahd, scbid);
2337 seq_flags = ahd_inb(ahd, SEQ_FLAGS);
2338 curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
2339 lastphase = ahd_inb(ahd, LASTPHASE);
2340 if ((seq_flags & NOT_IDENTIFIED) != 0) {
2341
2342 /*
2343 * The reconnecting target either did not send an
2344 * identify message, or did, but we didn't find an SCB
2345 * to match.
2346 */
2347 ahd_print_devinfo(ahd, &devinfo);
2348 printf("Target did not send an IDENTIFY message. "
2349 "LASTPHASE = 0x%x.\n", lastphase);
2350 scb = NULL;
2351 } else if (scb == NULL) {
2352 /*
2353 * We don't seem to have an SCB active for this
2354 * transaction. Print an error and reset the bus.
2355 */
2356 ahd_print_devinfo(ahd, &devinfo);
2357 printf("No SCB found during protocol violation\n");
2358 goto proto_violation_reset;
2359 } else {
2360 ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
2361 if ((seq_flags & NO_CDB_SENT) != 0) {
2362 ahd_print_path(ahd, scb);
2363 printf("No or incomplete CDB sent to device.\n");
2364 } else if ((ahd_inb_scbram(ahd, SCB_CONTROL)
2365 & STATUS_RCVD) == 0) {
2366 /*
2367 * The target never bothered to provide status to
2368 * us prior to completing the command. Since we don't
2369 * know the disposition of this command, we must attempt
2370 * to abort it. Assert ATN and prepare to send an abort
2371 * message.
2372 */
2373 ahd_print_path(ahd, scb);
2374 printf("Completed command without status.\n");
2375 } else {
2376 ahd_print_path(ahd, scb);
2377 printf("Unknown protocol violation.\n");
2378 ahd_dump_card_state(ahd);
2379 }
2380 }
2381 if ((lastphase & ~P_DATAIN_DT) == 0
2382 || lastphase == P_COMMAND) {
2383proto_violation_reset:
2384 /*
2385 * Target either went directly to data
2386 * phase or didn't respond to our ATN.
2387 * The only safe thing to do is to blow
2388 * it away with a bus reset.
2389 */
2390 found = ahd_reset_channel(ahd, 'A', TRUE);
2391 printf("%s: Issued Channel %c Bus Reset. "
2392 "%d SCBs aborted\n", ahd_name(ahd), 'A', found);
2393 } else {
2394 /*
2395 * Leave the selection hardware off in case
2396 * this abort attempt will affect yet to
2397 * be sent commands.
2398 */
2399 ahd_outb(ahd, SCSISEQ0,
2400 ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
2401 ahd_assert_atn(ahd);
2402 ahd_outb(ahd, MSG_OUT, HOST_MSG);
2403 if (scb == NULL) {
2404 ahd_print_devinfo(ahd, &devinfo);
2405 ahd->msgout_buf[0] = MSG_ABORT_TASK;
2406 ahd->msgout_len = 1;
2407 ahd->msgout_index = 0;
2408 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2409 } else {
2410 ahd_print_path(ahd, scb);
2411 scb->flags |= SCB_ABORT;
2412 }
2413 printf("Protocol violation %s. Attempting to abort.\n",
2414 ahd_lookup_phase_entry(curphase)->phasemsg);
2415 }
2416}
2417
2418/*
2419 * Force renegotiation to occur the next time we initiate
2420 * a command to the current device.
2421 */
2422static void
2423ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
2424{
2425 struct ahd_initiator_tinfo *targ_info;
2426 struct ahd_tmode_tstate *tstate;
2427
2428#ifdef AHD_DEBUG
2429 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
2430 ahd_print_devinfo(ahd, devinfo);
2431 printf("Forcing renegotiation\n");
2432 }
2433#endif
2434 targ_info = ahd_fetch_transinfo(ahd,
2435 devinfo->channel,
2436 devinfo->our_scsiid,
2437 devinfo->target,
2438 &tstate);
2439 ahd_update_neg_request(ahd, devinfo, tstate,
2440 targ_info, AHD_NEG_IF_NON_ASYNC);
2441}
2442
2443#define AHD_MAX_STEPS 2000
2444void
2445ahd_clear_critical_section(struct ahd_softc *ahd)
2446{
2447 ahd_mode_state saved_modes;
2448 int stepping;
2449 int steps;
2450 int first_instr;
2451 u_int simode0;
2452 u_int simode1;
2453 u_int simode3;
2454 u_int lqimode0;
2455 u_int lqimode1;
2456 u_int lqomode0;
2457 u_int lqomode1;
2458
2459 if (ahd->num_critical_sections == 0)
2460 return;
2461
2462 stepping = FALSE;
2463 steps = 0;
2464 first_instr = 0;
2465 simode0 = 0;
2466 simode1 = 0;
2467 simode3 = 0;
2468 lqimode0 = 0;
2469 lqimode1 = 0;
2470 lqomode0 = 0;
2471 lqomode1 = 0;
2472 saved_modes = ahd_save_modes(ahd);
2473 for (;;) {
2474 struct cs *cs;
2475 u_int seqaddr;
2476 u_int i;
2477
2478 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2479 seqaddr = ahd_inb(ahd, CURADDR)
2480 | (ahd_inb(ahd, CURADDR+1) << 8);
2481
2482 cs = ahd->critical_sections;
2483 for (i = 0; i < ahd->num_critical_sections; i++, cs++) {
2484
2485 if (cs->begin < seqaddr && cs->end >= seqaddr)
2486 break;
2487 }
2488
2489 if (i == ahd->num_critical_sections)
2490 break;
2491
2492 if (steps > AHD_MAX_STEPS) {
2493 printf("%s: Infinite loop in critical section\n"
2494 "%s: First Instruction 0x%x now 0x%x\n",
2495 ahd_name(ahd), ahd_name(ahd), first_instr,
2496 seqaddr);
2497 ahd_dump_card_state(ahd);
2498 panic("critical section loop");
2499 }
2500
2501 steps++;
2502#ifdef AHD_DEBUG
2503 if ((ahd_debug & AHD_SHOW_MISC) != 0)
2504 printf("%s: Single stepping at 0x%x\n", ahd_name(ahd),
2505 seqaddr);
2506#endif
2507 if (stepping == FALSE) {
2508
2509 first_instr = seqaddr;
2510 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
2511 simode0 = ahd_inb(ahd, SIMODE0);
2512 simode3 = ahd_inb(ahd, SIMODE3);
2513 lqimode0 = ahd_inb(ahd, LQIMODE0);
2514 lqimode1 = ahd_inb(ahd, LQIMODE1);
2515 lqomode0 = ahd_inb(ahd, LQOMODE0);
2516 lqomode1 = ahd_inb(ahd, LQOMODE1);
2517 ahd_outb(ahd, SIMODE0, 0);
2518 ahd_outb(ahd, SIMODE3, 0);
2519 ahd_outb(ahd, LQIMODE0, 0);
2520 ahd_outb(ahd, LQIMODE1, 0);
2521 ahd_outb(ahd, LQOMODE0, 0);
2522 ahd_outb(ahd, LQOMODE1, 0);
2523 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2524 simode1 = ahd_inb(ahd, SIMODE1);
2525 /*
2526 * We don't clear ENBUSFREE. Unfortunately
2527 * we cannot re-enable busfree detection within
2528 * the current connection, so we must leave it
2529 * on while single stepping.
2530 */
2531 ahd_outb(ahd, SIMODE1, simode1 & ENBUSFREE);
2532 ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP);
2533 stepping = TRUE;
2534 }
2535 ahd_outb(ahd, CLRSINT1, CLRBUSFREE);
2536 ahd_outb(ahd, CLRINT, CLRSCSIINT);
2537 ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
2538 ahd_outb(ahd, HCNTRL, ahd->unpause);
2539 while (!ahd_is_paused(ahd))
2540 ahd_delay(200);
2541 ahd_update_modes(ahd);
2542 }
2543 if (stepping) {
2544 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
2545 ahd_outb(ahd, SIMODE0, simode0);
2546 ahd_outb(ahd, SIMODE3, simode3);
2547 ahd_outb(ahd, LQIMODE0, lqimode0);
2548 ahd_outb(ahd, LQIMODE1, lqimode1);
2549 ahd_outb(ahd, LQOMODE0, lqomode0);
2550 ahd_outb(ahd, LQOMODE1, lqomode1);
2551 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2552 ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP);
2553 ahd_outb(ahd, SIMODE1, simode1);
2554 /*
2555 * SCSIINT seems to glitch occassionally when
2556 * the interrupt masks are restored. Clear SCSIINT
2557 * one more time so that only persistent errors
2558 * are seen as a real interrupt.
2559 */
2560 ahd_outb(ahd, CLRINT, CLRSCSIINT);
2561 }
2562 ahd_restore_modes(ahd, saved_modes);
2563}
2564
2565/*
2566 * Clear any pending interrupt status.
2567 */
2568void
2569ahd_clear_intstat(struct ahd_softc *ahd)
2570{
2571 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
2572 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
2573 /* Clear any interrupt conditions this may have caused */
2574 ahd_outb(ahd, CLRLQIINT0, CLRLQIATNQAS|CLRLQICRCT1|CLRLQICRCT2
2575 |CLRLQIBADLQT|CLRLQIATNLQ|CLRLQIATNCMD);
2576 ahd_outb(ahd, CLRLQIINT1, CLRLQIPHASE_LQ|CLRLQIPHASE_NLQ|CLRLIQABORT
2577 |CLRLQICRCI_LQ|CLRLQICRCI_NLQ|CLRLQIBADLQI
2578 |CLRLQIOVERI_LQ|CLRLQIOVERI_NLQ|CLRNONPACKREQ);
2579 ahd_outb(ahd, CLRLQOINT0, CLRLQOTARGSCBPERR|CLRLQOSTOPT2|CLRLQOATNLQ
2580 |CLRLQOATNPKT|CLRLQOTCRC);
2581 ahd_outb(ahd, CLRLQOINT1, CLRLQOINITSCBPERR|CLRLQOSTOPI2|CLRLQOBADQAS
2582 |CLRLQOBUSFREE|CLRLQOPHACHGINPKT);
2583 if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
2584 ahd_outb(ahd, CLRLQOINT0, 0);
2585 ahd_outb(ahd, CLRLQOINT1, 0);
2586 }
2587 ahd_outb(ahd, CLRSINT3, CLRNTRAMPERR|CLROSRAMPERR);
2588 ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
2589 |CLRBUSFREE|CLRSCSIPERR|CLRREQINIT);
2590 ahd_outb(ahd, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO
2591 |CLRIOERR|CLROVERRUN);
2592 ahd_outb(ahd, CLRINT, CLRSCSIINT);
2593}
2594
2595/**************************** Debugging Routines ******************************/
2596#ifdef AHD_DEBUG
2597uint32_t ahd_debug = AHD_DEBUG_OPTS;
2598#endif
2599void
2600ahd_print_scb(struct scb *scb)
2601{
2602 struct hardware_scb *hscb;
2603 int i;
2604
2605 hscb = scb->hscb;
2606 printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
2607 (void *)scb,
2608 hscb->control,
2609 hscb->scsiid,
2610 hscb->lun,
2611 hscb->cdb_len);
2612 printf("Shared Data: ");
2613 for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++)
2614 printf("%#02x", hscb->shared_data.idata.cdb[i]);
2615 printf(" dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n",
2616 (uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF),
2617 (uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF),
2618 ahd_le32toh(hscb->datacnt),
2619 ahd_le32toh(hscb->sgptr),
2620 SCB_GET_TAG(scb));
2621 ahd_dump_sglist(scb);
2622}
2623
2624void
2625ahd_dump_sglist(struct scb *scb)
2626{
2627 int i;
2628
2629 if (scb->sg_count > 0) {
2630 if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) {
2631 struct ahd_dma64_seg *sg_list;
2632
2633 sg_list = (struct ahd_dma64_seg*)scb->sg_list;
2634 for (i = 0; i < scb->sg_count; i++) {
2635 uint64_t addr;
2636 uint32_t len;
2637
2638 addr = ahd_le64toh(sg_list[i].addr);
2639 len = ahd_le32toh(sg_list[i].len);
2640 printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
2641 i,
2642 (uint32_t)((addr >> 32) & 0xFFFFFFFF),
2643 (uint32_t)(addr & 0xFFFFFFFF),
2644 sg_list[i].len & AHD_SG_LEN_MASK,
2645 (sg_list[i].len & AHD_DMA_LAST_SEG)
2646 ? " Last" : "");
2647 }
2648 } else {
2649 struct ahd_dma_seg *sg_list;
2650
2651 sg_list = (struct ahd_dma_seg*)scb->sg_list;
2652 for (i = 0; i < scb->sg_count; i++) {
2653 uint32_t len;
2654
2655 len = ahd_le32toh(sg_list[i].len);
2656 printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
2657 i,
2658 (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
2659 ahd_le32toh(sg_list[i].addr),
2660 len & AHD_SG_LEN_MASK,
2661 len & AHD_DMA_LAST_SEG ? " Last" : "");
2662 }
2663 }
2664 }
2665}
2666
2667/************************* Transfer Negotiation *******************************/
2668/*
2669 * Allocate per target mode instance (ID we respond to as a target)
2670 * transfer negotiation data structures.
2671 */
2672static struct ahd_tmode_tstate *
2673ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel)
2674{
2675 struct ahd_tmode_tstate *master_tstate;
2676 struct ahd_tmode_tstate *tstate;
2677 int i;
2678
2679 master_tstate = ahd->enabled_targets[ahd->our_id];
2680 if (ahd->enabled_targets[scsi_id] != NULL
2681 && ahd->enabled_targets[scsi_id] != master_tstate)
2682 panic("%s: ahd_alloc_tstate - Target already allocated",
2683 ahd_name(ahd));
2684 tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT);
2685 if (tstate == NULL)
2686 return (NULL);
2687
2688 /*
2689 * If we have allocated a master tstate, copy user settings from
2690 * the master tstate (taken from SRAM or the EEPROM) for this
2691 * channel, but reset our current and goal settings to async/narrow
2692 * until an initiator talks to us.
2693 */
2694 if (master_tstate != NULL) {
2695 memcpy(tstate, master_tstate, sizeof(*tstate));
2696 memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
2697 for (i = 0; i < 16; i++) {
2698 memset(&tstate->transinfo[i].curr, 0,
2699 sizeof(tstate->transinfo[i].curr));
2700 memset(&tstate->transinfo[i].goal, 0,
2701 sizeof(tstate->transinfo[i].goal));
2702 }
2703 } else
2704 memset(tstate, 0, sizeof(*tstate));
2705 ahd->enabled_targets[scsi_id] = tstate;
2706 return (tstate);
2707}
2708
2709#ifdef AHD_TARGET_MODE
2710/*
2711 * Free per target mode instance (ID we respond to as a target)
2712 * transfer negotiation data structures.
2713 */
2714static void
2715ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force)
2716{
2717 struct ahd_tmode_tstate *tstate;
2718
2719 /*
2720 * Don't clean up our "master" tstate.
2721 * It has our default user settings.
2722 */
2723 if (scsi_id == ahd->our_id
2724 && force == FALSE)
2725 return;
2726
2727 tstate = ahd->enabled_targets[scsi_id];
2728 if (tstate != NULL)
2729 free(tstate, M_DEVBUF);
2730 ahd->enabled_targets[scsi_id] = NULL;
2731}
2732#endif
2733
2734/*
2735 * Called when we have an active connection to a target on the bus,
2736 * this function finds the nearest period to the input period limited
2737 * by the capabilities of the bus connectivity of and sync settings for
2738 * the target.
2739 */
2740void
2741ahd_devlimited_syncrate(struct ahd_softc *ahd,
2742 struct ahd_initiator_tinfo *tinfo,
2743 u_int *period, u_int *ppr_options, role_t role)
2744{
2745 struct ahd_transinfo *transinfo;
2746 u_int maxsync;
2747
2748 if ((ahd_inb(ahd, SBLKCTL) & ENAB40) != 0
2749 && (ahd_inb(ahd, SSTAT2) & EXP_ACTIVE) == 0) {
2750 maxsync = AHD_SYNCRATE_PACED;
2751 } else {
2752 maxsync = AHD_SYNCRATE_ULTRA;
2753 /* Can't do DT related options on an SE bus */
2754 *ppr_options &= MSG_EXT_PPR_QAS_REQ;
2755 }
2756 /*
2757 * Never allow a value higher than our current goal
2758 * period otherwise we may allow a target initiated
2759 * negotiation to go above the limit as set by the
2760 * user. In the case of an initiator initiated
2761 * sync negotiation, we limit based on the user
2762 * setting. This allows the system to still accept
2763 * incoming negotiations even if target initiated
2764 * negotiation is not performed.
2765 */
2766 if (role == ROLE_TARGET)
2767 transinfo = &tinfo->user;
2768 else
2769 transinfo = &tinfo->goal;
2770 *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN);
2771 if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
2772 maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2);
2773 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2774 }
2775 if (transinfo->period == 0) {
2776 *period = 0;
2777 *ppr_options = 0;
2778 } else {
2779 *period = MAX(*period, transinfo->period);
2780 ahd_find_syncrate(ahd, period, ppr_options, maxsync);
2781 }
2782}
2783
2784/*
2785 * Look up the valid period to SCSIRATE conversion in our table.
2786 * Return the period and offset that should be sent to the target
2787 * if this was the beginning of an SDTR.
2788 */
2789void
2790ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
2791 u_int *ppr_options, u_int maxsync)
2792{
2793 if (*period < maxsync)
2794 *period = maxsync;
2795
2796 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) != 0
2797 && *period > AHD_SYNCRATE_MIN_DT)
2798 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2799
2800 if (*period > AHD_SYNCRATE_MIN)
2801 *period = 0;
2802
2803 /* Honor PPR option conformance rules. */
2804 if (*period > AHD_SYNCRATE_PACED)
2805 *ppr_options &= ~MSG_EXT_PPR_RTI;
2806
2807 if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0)
2808 *ppr_options &= (MSG_EXT_PPR_DT_REQ|MSG_EXT_PPR_QAS_REQ);
2809
2810 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0)
2811 *ppr_options &= MSG_EXT_PPR_QAS_REQ;
2812
2813 /* Skip all PACED only entries if IU is not available */
2814 if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0
2815 && *period < AHD_SYNCRATE_DT)
2816 *period = AHD_SYNCRATE_DT;
2817
2818 /* Skip all DT only entries if DT is not available */
2819 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
2820 && *period < AHD_SYNCRATE_ULTRA2)
2821 *period = AHD_SYNCRATE_ULTRA2;
2822}
2823
2824/*
2825 * Truncate the given synchronous offset to a value the
2826 * current adapter type and syncrate are capable of.
2827 */
2828void
2829ahd_validate_offset(struct ahd_softc *ahd,
2830 struct ahd_initiator_tinfo *tinfo,
2831 u_int period, u_int *offset, int wide,
2832 role_t role)
2833{
2834 u_int maxoffset;
2835
2836 /* Limit offset to what we can do */
2837 if (period == 0)
2838 maxoffset = 0;
2839 else if (period <= AHD_SYNCRATE_PACED) {
2840 if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0)
2841 maxoffset = MAX_OFFSET_PACED_BUG;
2842 else
2843 maxoffset = MAX_OFFSET_PACED;
2844 } else
2845 maxoffset = MAX_OFFSET_NON_PACED;
2846 *offset = MIN(*offset, maxoffset);
2847 if (tinfo != NULL) {
2848 if (role == ROLE_TARGET)
2849 *offset = MIN(*offset, tinfo->user.offset);
2850 else
2851 *offset = MIN(*offset, tinfo->goal.offset);
2852 }
2853}
2854
2855/*
2856 * Truncate the given transfer width parameter to a value the
2857 * current adapter type is capable of.
2858 */
2859void
2860ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo,
2861 u_int *bus_width, role_t role)
2862{
2863 switch (*bus_width) {
2864 default:
2865 if (ahd->features & AHD_WIDE) {
2866 /* Respond Wide */
2867 *bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2868 break;
2869 }
2870 /* FALLTHROUGH */
2871 case MSG_EXT_WDTR_BUS_8_BIT:
2872 *bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2873 break;
2874 }
2875 if (tinfo != NULL) {
2876 if (role == ROLE_TARGET)
2877 *bus_width = MIN(tinfo->user.width, *bus_width);
2878 else
2879 *bus_width = MIN(tinfo->goal.width, *bus_width);
2880 }
2881}
2882
2883/*
2884 * Update the bitmask of targets for which the controller should
2885 * negotiate with at the next convenient oportunity. This currently
2886 * means the next time we send the initial identify messages for
2887 * a new transaction.
2888 */
2889int
2890ahd_update_neg_request(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
2891 struct ahd_tmode_tstate *tstate,
2892 struct ahd_initiator_tinfo *tinfo, ahd_neg_type neg_type)
2893{
2894 u_int auto_negotiate_orig;
2895
2896 auto_negotiate_orig = tstate->auto_negotiate;
2897 if (neg_type == AHD_NEG_ALWAYS) {
2898 /*
2899 * Force our "current" settings to be
2900 * unknown so that unless a bus reset
2901 * occurs the need to renegotiate is
2902 * recorded persistently.
2903 */
2904 if ((ahd->features & AHD_WIDE) != 0)
2905 tinfo->curr.width = AHD_WIDTH_UNKNOWN;
2906 tinfo->curr.period = AHD_PERIOD_UNKNOWN;
2907 tinfo->curr.offset = AHD_OFFSET_UNKNOWN;
2908 }
2909 if (tinfo->curr.period != tinfo->goal.period
2910 || tinfo->curr.width != tinfo->goal.width
2911 || tinfo->curr.offset != tinfo->goal.offset
2912 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
2913 || (neg_type == AHD_NEG_IF_NON_ASYNC
2914 && (tinfo->goal.offset != 0
2915 || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
2916 || tinfo->goal.ppr_options != 0)))
2917 tstate->auto_negotiate |= devinfo->target_mask;
2918 else
2919 tstate->auto_negotiate &= ~devinfo->target_mask;
2920
2921 return (auto_negotiate_orig != tstate->auto_negotiate);
2922}
2923
2924/*
2925 * Update the user/goal/curr tables of synchronous negotiation
2926 * parameters as well as, in the case of a current or active update,
2927 * any data structures on the host controller. In the case of an
2928 * active update, the specified target is currently talking to us on
2929 * the bus, so the transfer parameter update must take effect
2930 * immediately.
2931 */
2932void
2933ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
2934 u_int period, u_int offset, u_int ppr_options,
2935 u_int type, int paused)
2936{
2937 struct ahd_initiator_tinfo *tinfo;
2938 struct ahd_tmode_tstate *tstate;
2939 u_int old_period;
2940 u_int old_offset;
2941 u_int old_ppr;
2942 int active;
2943 int update_needed;
2944
2945 active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE;
2946 update_needed = 0;
2947
2948 if (period == 0 || offset == 0) {
2949 period = 0;
2950 offset = 0;
2951 }
2952
2953 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
2954 devinfo->target, &tstate);
2955
2956 if ((type & AHD_TRANS_USER) != 0) {
2957 tinfo->user.period = period;
2958 tinfo->user.offset = offset;
2959 tinfo->user.ppr_options = ppr_options;
2960 }
2961
2962 if ((type & AHD_TRANS_GOAL) != 0) {
2963 tinfo->goal.period = period;
2964 tinfo->goal.offset = offset;
2965 tinfo->goal.ppr_options = ppr_options;
2966 }
2967
2968 old_period = tinfo->curr.period;
2969 old_offset = tinfo->curr.offset;
2970 old_ppr = tinfo->curr.ppr_options;
2971
2972 if ((type & AHD_TRANS_CUR) != 0
2973 && (old_period != period
2974 || old_offset != offset
2975 || old_ppr != ppr_options)) {
2976
2977 update_needed++;
2978
2979 tinfo->curr.period = period;
2980 tinfo->curr.offset = offset;
2981 tinfo->curr.ppr_options = ppr_options;
2982
2983 ahd_send_async(ahd, devinfo->channel, devinfo->target,
2984 CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
2985 if (bootverbose) {
2986 if (offset != 0) {
2987 int options;
2988
2989 printf("%s: target %d synchronous with "
2990 "period = 0x%x, offset = 0x%x",
2991 ahd_name(ahd), devinfo->target,
2992 period, offset);
2993 options = 0;
2994 if ((ppr_options & MSG_EXT_PPR_RD_STRM) != 0) {
2995 printf("(RDSTRM");
2996 options++;
2997 }
2998 if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
2999 printf("%s", options ? "|DT" : "(DT");
3000 options++;
3001 }
3002 if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
3003 printf("%s", options ? "|IU" : "(IU");
3004 options++;
3005 }
3006 if ((ppr_options & MSG_EXT_PPR_RTI) != 0) {
3007 printf("%s", options ? "|RTI" : "(RTI");
3008 options++;
3009 }
3010 if ((ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) {
3011 printf("%s", options ? "|QAS" : "(QAS");
3012 options++;
3013 }
3014 if (options != 0)
3015 printf(")\n");
3016 else
3017 printf("\n");
3018 } else {
3019 printf("%s: target %d using "
3020 "asynchronous transfers%s\n",
3021 ahd_name(ahd), devinfo->target,
3022 (ppr_options & MSG_EXT_PPR_QAS_REQ) != 0
3023 ? "(QAS)" : "");
3024 }
3025 }
3026 }
3027 /*
3028 * Always refresh the neg-table to handle the case of the
3029 * sequencer setting the ENATNO bit for a MK_MESSAGE request.
3030 * We will always renegotiate in that case if this is a
3031 * packetized request. Also manage the busfree expected flag
3032 * from this common routine so that we catch changes due to
3033 * WDTR or SDTR messages.
3034 */
3035 if ((type & AHD_TRANS_CUR) != 0) {
3036 if (!paused)
3037 ahd_pause(ahd);
3038 ahd_update_neg_table(ahd, devinfo, &tinfo->curr);
3039 if (!paused)
3040 ahd_unpause(ahd);
3041 if (ahd->msg_type != MSG_TYPE_NONE) {
3042 if ((old_ppr & MSG_EXT_PPR_IU_REQ)
3043 != (ppr_options & MSG_EXT_PPR_IU_REQ)) {
3044#ifdef AHD_DEBUG
3045 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3046 ahd_print_devinfo(ahd, devinfo);
3047 printf("Expecting IU Change busfree\n");
3048 }
3049#endif
3050 ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE
3051 | MSG_FLAG_IU_REQ_CHANGED;
3052 }
3053 if ((old_ppr & MSG_EXT_PPR_IU_REQ) != 0) {
3054#ifdef AHD_DEBUG
3055 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3056 printf("PPR with IU_REQ outstanding\n");
3057#endif
3058 ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE;
3059 }
3060 }
3061 }
3062
3063 update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
3064 tinfo, AHD_NEG_TO_GOAL);
3065
3066 if (update_needed && active)
3067 ahd_update_pending_scbs(ahd);
3068}
3069
3070/*
3071 * Update the user/goal/curr tables of wide negotiation
3072 * parameters as well as, in the case of a current or active update,
3073 * any data structures on the host controller. In the case of an
3074 * active update, the specified target is currently talking to us on
3075 * the bus, so the transfer parameter update must take effect
3076 * immediately.
3077 */
3078void
3079ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3080 u_int width, u_int type, int paused)
3081{
3082 struct ahd_initiator_tinfo *tinfo;
3083 struct ahd_tmode_tstate *tstate;
3084 u_int oldwidth;
3085 int active;
3086 int update_needed;
3087
3088 active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE;
3089 update_needed = 0;
3090 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
3091 devinfo->target, &tstate);
3092
3093 if ((type & AHD_TRANS_USER) != 0)
3094 tinfo->user.width = width;
3095
3096 if ((type & AHD_TRANS_GOAL) != 0)
3097 tinfo->goal.width = width;
3098
3099 oldwidth = tinfo->curr.width;
3100 if ((type & AHD_TRANS_CUR) != 0 && oldwidth != width) {
3101
3102 update_needed++;
3103
3104 tinfo->curr.width = width;
3105 ahd_send_async(ahd, devinfo->channel, devinfo->target,
3106 CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
3107 if (bootverbose) {
3108 printf("%s: target %d using %dbit transfers\n",
3109 ahd_name(ahd), devinfo->target,
3110 8 * (0x01 << width));
3111 }
3112 }
3113
3114 if ((type & AHD_TRANS_CUR) != 0) {
3115 if (!paused)
3116 ahd_pause(ahd);
3117 ahd_update_neg_table(ahd, devinfo, &tinfo->curr);
3118 if (!paused)
3119 ahd_unpause(ahd);
3120 }
3121
3122 update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
3123 tinfo, AHD_NEG_TO_GOAL);
3124 if (update_needed && active)
3125 ahd_update_pending_scbs(ahd);
3126
3127}
3128
3129/*
3130 * Update the current state of tagged queuing for a given target.
3131 */
3132void
3133ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3134 ahd_queue_alg alg)
3135{
3136 ahd_platform_set_tags(ahd, devinfo, alg);
3137 ahd_send_async(ahd, devinfo->channel, devinfo->target,
3138 devinfo->lun, AC_TRANSFER_NEG, &alg);
3139}
3140
3141static void
3142ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3143 struct ahd_transinfo *tinfo)
3144{
3145 ahd_mode_state saved_modes;
3146 u_int period;
3147 u_int ppr_opts;
3148 u_int con_opts;
3149 u_int offset;
3150 u_int saved_negoaddr;
3151 uint8_t iocell_opts[sizeof(ahd->iocell_opts)];
3152
3153 saved_modes = ahd_save_modes(ahd);
3154 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3155
3156 saved_negoaddr = ahd_inb(ahd, NEGOADDR);
3157 ahd_outb(ahd, NEGOADDR, devinfo->target);
3158 period = tinfo->period;
3159 offset = tinfo->offset;
3160 memcpy(iocell_opts, ahd->iocell_opts, sizeof(ahd->iocell_opts));
3161 ppr_opts = tinfo->ppr_options & (MSG_EXT_PPR_QAS_REQ|MSG_EXT_PPR_DT_REQ
3162 |MSG_EXT_PPR_IU_REQ|MSG_EXT_PPR_RTI);
3163 con_opts = 0;
3164 if (period == 0)
3165 period = AHD_SYNCRATE_ASYNC;
3166 if (period == AHD_SYNCRATE_160) {
3167
3168 if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) {
3169 /*
3170 * When the SPI4 spec was finalized, PACE transfers
3171 * was not made a configurable option in the PPR
3172 * message. Instead it is assumed to be enabled for
3173 * any syncrate faster than 80MHz. Nevertheless,
3174 * Harpoon2A4 allows this to be configurable.
3175 *
3176 * Harpoon2A4 also assumes at most 2 data bytes per
3177 * negotiated REQ/ACK offset. Paced transfers take
3178 * 4, so we must adjust our offset.
3179 */
3180 ppr_opts |= PPROPT_PACE;
3181 offset *= 2;
3182
3183 /*
3184 * Harpoon2A assumed that there would be a
3185 * fallback rate between 160MHz and 80Mhz,
3186 * so 7 is used as the period factor rather
3187 * than 8 for 160MHz.
3188 */
3189 period = AHD_SYNCRATE_REVA_160;
3190 }
3191 if ((tinfo->ppr_options & MSG_EXT_PPR_PCOMP_EN) == 0)
3192 iocell_opts[AHD_PRECOMP_SLEW_INDEX] &=
3193 ~AHD_PRECOMP_MASK;
3194 } else {
3195 /*
3196 * Precomp should be disabled for non-paced transfers.
3197 */
3198 iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK;
3199
3200 if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0
3201 && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0) {
3202 /*
3203 * Slow down our CRC interval to be
3204 * compatible with devices that can't
3205 * handle a CRC at full speed.
3206 */
3207 con_opts |= ENSLOWCRC;
3208 }
3209 }
3210
3211 ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW);
3212 ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_PRECOMP_SLEW_INDEX]);
3213 ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_AMPLITUDE);
3214 ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_AMPLITUDE_INDEX]);
3215
3216 ahd_outb(ahd, NEGPERIOD, period);
3217 ahd_outb(ahd, NEGPPROPTS, ppr_opts);
3218 ahd_outb(ahd, NEGOFFSET, offset);
3219
3220 if (tinfo->width == MSG_EXT_WDTR_BUS_16_BIT)
3221 con_opts |= WIDEXFER;
3222
3223 /*
3224 * During packetized transfers, the target will
3225 * give us the oportunity to send command packets
3226 * without us asserting attention.
3227 */
3228 if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) == 0)
3229 con_opts |= ENAUTOATNO;
3230 ahd_outb(ahd, NEGCONOPTS, con_opts);
3231 ahd_outb(ahd, NEGOADDR, saved_negoaddr);
3232 ahd_restore_modes(ahd, saved_modes);
3233}
3234
3235/*
3236 * When the transfer settings for a connection change, setup for
3237 * negotiation in pending SCBs to effect the change as quickly as
3238 * possible. We also cancel any negotiations that are scheduled
3239 * for inflight SCBs that have not been started yet.
3240 */
3241static void
3242ahd_update_pending_scbs(struct ahd_softc *ahd)
3243{
3244 struct scb *pending_scb;
3245 int pending_scb_count;
3246 u_int scb_tag;
3247 int paused;
3248 u_int saved_scbptr;
3249 ahd_mode_state saved_modes;
3250
3251 /*
3252 * Traverse the pending SCB list and ensure that all of the
3253 * SCBs there have the proper settings. We can only safely
3254 * clear the negotiation required flag (setting requires the
3255 * execution queue to be modified) and this is only possible
3256 * if we are not already attempting to select out for this
3257 * SCB. For this reason, all callers only call this routine
3258 * if we are changing the negotiation settings for the currently
3259 * active transaction on the bus.
3260 */
3261 pending_scb_count = 0;
3262 LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
3263 struct ahd_devinfo devinfo;
3264 struct hardware_scb *pending_hscb;
3265 struct ahd_initiator_tinfo *tinfo;
3266 struct ahd_tmode_tstate *tstate;
3267
3268 ahd_scb_devinfo(ahd, &devinfo, pending_scb);
3269 tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
3270 devinfo.our_scsiid,
3271 devinfo.target, &tstate);
3272 pending_hscb = pending_scb->hscb;
3273 if ((tstate->auto_negotiate & devinfo.target_mask) == 0
3274 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
3275 pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
3276 pending_hscb->control &= ~MK_MESSAGE;
3277 }
3278 ahd_sync_scb(ahd, pending_scb,
3279 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3280 pending_scb_count++;
3281 }
3282
3283 if (pending_scb_count == 0)
3284 return;
3285
3286 if (ahd_is_paused(ahd)) {
3287 paused = 1;
3288 } else {
3289 paused = 0;
3290 ahd_pause(ahd);
3291 }
3292
3293 /*
3294 * Force the sequencer to reinitialize the selection for
3295 * the command at the head of the execution queue if it
3296 * has already been setup. The negotiation changes may
3297 * effect whether we select-out with ATN.
3298 */
3299 saved_modes = ahd_save_modes(ahd);
3300 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3301 ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
3302 saved_scbptr = ahd_get_scbptr(ahd);
3303 /* Ensure that the hscbs down on the card match the new information */
3304 for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) {
3305 struct hardware_scb *pending_hscb;
3306 u_int control;
3307
3308 pending_scb = ahd_lookup_scb(ahd, scb_tag);
3309 if (pending_scb == NULL)
3310 continue;
3311 ahd_set_scbptr(ahd, scb_tag);
3312 pending_hscb = pending_scb->hscb;
3313 control = ahd_inb_scbram(ahd, SCB_CONTROL);
3314 control &= ~MK_MESSAGE;
3315 control |= pending_hscb->control & MK_MESSAGE;
3316 ahd_outb(ahd, SCB_CONTROL, control);
3317 }
3318 ahd_set_scbptr(ahd, saved_scbptr);
3319 ahd_restore_modes(ahd, saved_modes);
3320
3321 if (paused == 0)
3322 ahd_unpause(ahd);
3323}
3324
3325/**************************** Pathing Information *****************************/
3326static void
3327ahd_fetch_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3328{
3329 ahd_mode_state saved_modes;
3330 u_int saved_scsiid;
3331 role_t role;
3332 int our_id;
3333
3334 saved_modes = ahd_save_modes(ahd);
3335 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3336
3337 if (ahd_inb(ahd, SSTAT0) & TARGET)
3338 role = ROLE_TARGET;
3339 else
3340 role = ROLE_INITIATOR;
3341
3342 if (role == ROLE_TARGET
3343 && (ahd_inb(ahd, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) {
3344 /* We were selected, so pull our id from TARGIDIN */
3345 our_id = ahd_inb(ahd, TARGIDIN) & OID;
3346 } else if (role == ROLE_TARGET)
3347 our_id = ahd_inb(ahd, TOWNID);
3348 else
3349 our_id = ahd_inb(ahd, IOWNID);
3350
3351 saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
3352 ahd_compile_devinfo(devinfo,
3353 our_id,
3354 SCSIID_TARGET(ahd, saved_scsiid),
3355 ahd_inb(ahd, SAVED_LUN),
3356 SCSIID_CHANNEL(ahd, saved_scsiid),
3357 role);
3358 ahd_restore_modes(ahd, saved_modes);
3359}
3360
3361void
3362ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3363{
3364 printf("%s:%c:%d:%d: ", ahd_name(ahd), 'A',
3365 devinfo->target, devinfo->lun);
3366}
3367
3368struct ahd_phase_table_entry*
3369ahd_lookup_phase_entry(int phase)
3370{
3371 struct ahd_phase_table_entry *entry;
3372 struct ahd_phase_table_entry *last_entry;
3373
3374 /*
3375 * num_phases doesn't include the default entry which
3376 * will be returned if the phase doesn't match.
3377 */
3378 last_entry = &ahd_phase_table[num_phases];
3379 for (entry = ahd_phase_table; entry < last_entry; entry++) {
3380 if (phase == entry->phase)
3381 break;
3382 }
3383 return (entry);
3384}
3385
3386void
3387ahd_compile_devinfo(struct ahd_devinfo *devinfo, u_int our_id, u_int target,
3388 u_int lun, char channel, role_t role)
3389{
3390 devinfo->our_scsiid = our_id;
3391 devinfo->target = target;
3392 devinfo->lun = lun;
3393 devinfo->target_offset = target;
3394 devinfo->channel = channel;
3395 devinfo->role = role;
3396 if (channel == 'B')
3397 devinfo->target_offset += 8;
3398 devinfo->target_mask = (0x01 << devinfo->target_offset);
3399}
3400
3401static void
3402ahd_scb_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3403 struct scb *scb)
3404{
3405 role_t role;
3406 int our_id;
3407
3408 our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
3409 role = ROLE_INITIATOR;
3410 if ((scb->hscb->control & TARGET_SCB) != 0)
3411 role = ROLE_TARGET;
3412 ahd_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahd, scb),
3413 SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahd, scb), role);
3414}
3415
3416
3417/************************ Message Phase Processing ****************************/
3418/*
3419 * When an initiator transaction with the MK_MESSAGE flag either reconnects
3420 * or enters the initial message out phase, we are interrupted. Fill our
3421 * outgoing message buffer with the appropriate message and beging handing
3422 * the message phase(s) manually.
3423 */
3424static void
3425ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3426 struct scb *scb)
3427{
3428 /*
3429 * To facilitate adding multiple messages together,
3430 * each routine should increment the index and len
3431 * variables instead of setting them explicitly.
3432 */
3433 ahd->msgout_index = 0;
3434 ahd->msgout_len = 0;
3435
3436 if (ahd_currently_packetized(ahd))
3437 ahd->msg_flags |= MSG_FLAG_PACKETIZED;
3438
3439 if (ahd->send_msg_perror
3440 && ahd_inb(ahd, MSG_OUT) == HOST_MSG) {
3441 ahd->msgout_buf[ahd->msgout_index++] = ahd->send_msg_perror;
3442 ahd->msgout_len++;
3443 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3444#ifdef AHD_DEBUG
3445 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3446 printf("Setting up for Parity Error delivery\n");
3447#endif
3448 return;
3449 } else if (scb == NULL) {
3450 printf("%s: WARNING. No pending message for "
3451 "I_T msgin. Issuing NO-OP\n", ahd_name(ahd));
3452 ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP;
3453 ahd->msgout_len++;
3454 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3455 return;
3456 }
3457
3458 if ((scb->flags & SCB_DEVICE_RESET) == 0
3459 && (scb->flags & SCB_PACKETIZED) == 0
3460 && ahd_inb(ahd, MSG_OUT) == MSG_IDENTIFYFLAG) {
3461 u_int identify_msg;
3462
3463 identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
3464 if ((scb->hscb->control & DISCENB) != 0)
3465 identify_msg |= MSG_IDENTIFY_DISCFLAG;
3466 ahd->msgout_buf[ahd->msgout_index++] = identify_msg;
3467 ahd->msgout_len++;
3468
3469 if ((scb->hscb->control & TAG_ENB) != 0) {
3470 ahd->msgout_buf[ahd->msgout_index++] =
3471 scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
3472 ahd->msgout_buf[ahd->msgout_index++] = SCB_GET_TAG(scb);
3473 ahd->msgout_len += 2;
3474 }
3475 }
3476
3477 if (scb->flags & SCB_DEVICE_RESET) {
3478 ahd->msgout_buf[ahd->msgout_index++] = MSG_BUS_DEV_RESET;
3479 ahd->msgout_len++;
3480 ahd_print_path(ahd, scb);
3481 printf("Bus Device Reset Message Sent\n");
3482 /*
3483 * Clear our selection hardware in advance of
3484 * the busfree. We may have an entry in the waiting
3485 * Q for this target, and we don't want to go about
3486 * selecting while we handle the busfree and blow it
3487 * away.
3488 */
3489 ahd_outb(ahd, SCSISEQ0, 0);
3490 } else if ((scb->flags & SCB_ABORT) != 0) {
3491
3492 if ((scb->hscb->control & TAG_ENB) != 0) {
3493 ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT_TAG;
3494 } else {
3495 ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT;
3496 }
3497 ahd->msgout_len++;
3498 ahd_print_path(ahd, scb);
3499 printf("Abort%s Message Sent\n",
3500 (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
3501 /*
3502 * Clear our selection hardware in advance of
3503 * the busfree. We may have an entry in the waiting
3504 * Q for this target, and we don't want to go about
3505 * selecting while we handle the busfree and blow it
3506 * away.
3507 */
3508 ahd_outb(ahd, SCSISEQ0, 0);
3509 } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
3510 ahd_build_transfer_msg(ahd, devinfo);
3511 /*
3512 * Clear our selection hardware in advance of potential
3513 * PPR IU status change busfree. We may have an entry in
3514 * the waiting Q for this target, and we don't want to go
3515 * about selecting while we handle the busfree and blow
3516 * it away.
3517 */
3518 ahd_outb(ahd, SCSISEQ0, 0);
3519 } else {
3520 printf("ahd_intr: AWAITING_MSG for an SCB that "
3521 "does not have a waiting message\n");
3522 printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
3523 devinfo->target_mask);
3524 panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x "
3525 "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control,
3526 ahd_inb_scbram(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT),
3527 scb->flags);
3528 }
3529
3530 /*
3531 * Clear the MK_MESSAGE flag from the SCB so we aren't
3532 * asked to send this message again.
3533 */
3534 ahd_outb(ahd, SCB_CONTROL,
3535 ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
3536 scb->hscb->control &= ~MK_MESSAGE;
3537 ahd->msgout_index = 0;
3538 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3539}
3540
3541/*
3542 * Build an appropriate transfer negotiation message for the
3543 * currently active target.
3544 */
3545static void
3546ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3547{
3548 /*
3549 * We need to initiate transfer negotiations.
3550 * If our current and goal settings are identical,
3551 * we want to renegotiate due to a check condition.
3552 */
3553 struct ahd_initiator_tinfo *tinfo;
3554 struct ahd_tmode_tstate *tstate;
3555 int dowide;
3556 int dosync;
3557 int doppr;
3558 u_int period;
3559 u_int ppr_options;
3560 u_int offset;
3561
3562 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
3563 devinfo->target, &tstate);
3564 /*
3565 * Filter our period based on the current connection.
3566 * If we can't perform DT transfers on this segment (not in LVD
3567 * mode for instance), then our decision to issue a PPR message
3568 * may change.
3569 */
3570 period = tinfo->goal.period;
3571 offset = tinfo->goal.offset;
3572 ppr_options = tinfo->goal.ppr_options;
3573 /* Target initiated PPR is not allowed in the SCSI spec */
3574 if (devinfo->role == ROLE_TARGET)
3575 ppr_options = 0;
3576 ahd_devlimited_syncrate(ahd, tinfo, &period,
3577 &ppr_options, devinfo->role);
3578 dowide = tinfo->curr.width != tinfo->goal.width;
3579 dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
3580 /*
3581 * Only use PPR if we have options that need it, even if the device
3582 * claims to support it. There might be an expander in the way
3583 * that doesn't.
3584 */
3585 doppr = ppr_options != 0;
3586
3587 if (!dowide && !dosync && !doppr) {
3588 dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
3589 dosync = tinfo->goal.offset != 0;
3590 }
3591
3592 if (!dowide && !dosync && !doppr) {
3593 /*
3594 * Force async with a WDTR message if we have a wide bus,
3595 * or just issue an SDTR with a 0 offset.
3596 */
3597 if ((ahd->features & AHD_WIDE) != 0)
3598 dowide = 1;
3599 else
3600 dosync = 1;
3601
3602 if (bootverbose) {
3603 ahd_print_devinfo(ahd, devinfo);
3604 printf("Ensuring async\n");
3605 }
3606 }
3607 /* Target initiated PPR is not allowed in the SCSI spec */
3608 if (devinfo->role == ROLE_TARGET)
3609 doppr = 0;
3610
3611 /*
3612 * Both the PPR message and SDTR message require the
3613 * goal syncrate to be limited to what the target device
3614 * is capable of handling (based on whether an LVD->SE
3615 * expander is on the bus), so combine these two cases.
3616 * Regardless, guarantee that if we are using WDTR and SDTR
3617 * messages that WDTR comes first.
3618 */
3619 if (doppr || (dosync && !dowide)) {
3620
3621 offset = tinfo->goal.offset;
3622 ahd_validate_offset(ahd, tinfo, period, &offset,
3623 doppr ? tinfo->goal.width
3624 : tinfo->curr.width,
3625 devinfo->role);
3626 if (doppr) {
3627 ahd_construct_ppr(ahd, devinfo, period, offset,
3628 tinfo->goal.width, ppr_options);
3629 } else {
3630 ahd_construct_sdtr(ahd, devinfo, period, offset);
3631 }
3632 } else {
3633 ahd_construct_wdtr(ahd, devinfo, tinfo->goal.width);
3634 }
3635}
3636
3637/*
3638 * Build a synchronous negotiation message in our message
3639 * buffer based on the input parameters.
3640 */
3641static void
3642ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3643 u_int period, u_int offset)
3644{
3645 if (offset == 0)
3646 period = AHD_ASYNC_XFER_PERIOD;
3647 ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
3648 ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR_LEN;
3649 ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_SDTR;
3650 ahd->msgout_buf[ahd->msgout_index++] = period;
3651 ahd->msgout_buf[ahd->msgout_index++] = offset;
3652 ahd->msgout_len += 5;
3653 if (bootverbose) {
3654 printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
3655 ahd_name(ahd), devinfo->channel, devinfo->target,
3656 devinfo->lun, period, offset);
3657 }
3658}
3659
3660/*
3661 * Build a wide negotiateion message in our message
3662 * buffer based on the input parameters.
3663 */
3664static void
3665ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3666 u_int bus_width)
3667{
3668 ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
3669 ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR_LEN;
3670 ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_WDTR;
3671 ahd->msgout_buf[ahd->msgout_index++] = bus_width;
3672 ahd->msgout_len += 4;
3673 if (bootverbose) {
3674 printf("(%s:%c:%d:%d): Sending WDTR %x\n",
3675 ahd_name(ahd), devinfo->channel, devinfo->target,
3676 devinfo->lun, bus_width);
3677 }
3678}
3679
3680/*
3681 * Build a parallel protocol request message in our message
3682 * buffer based on the input parameters.
3683 */
3684static void
3685ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3686 u_int period, u_int offset, u_int bus_width,
3687 u_int ppr_options)
3688{
3689 /*
3690 * Always request precompensation from
3691 * the other target if we are running
3692 * at paced syncrates.
3693 */
3694 if (period <= AHD_SYNCRATE_PACED)
3695 ppr_options |= MSG_EXT_PPR_PCOMP_EN;
3696 if (offset == 0)
3697 period = AHD_ASYNC_XFER_PERIOD;
3698 ahd->msgout_buf[ahd->msgout_index++] = MSG_EXTENDED;
3699 ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR_LEN;
3700 ahd->msgout_buf[ahd->msgout_index++] = MSG_EXT_PPR;
3701 ahd->msgout_buf[ahd->msgout_index++] = period;
3702 ahd->msgout_buf[ahd->msgout_index++] = 0;
3703 ahd->msgout_buf[ahd->msgout_index++] = offset;
3704 ahd->msgout_buf[ahd->msgout_index++] = bus_width;
3705 ahd->msgout_buf[ahd->msgout_index++] = ppr_options;
3706 ahd->msgout_len += 8;
3707 if (bootverbose) {
3708 printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
3709 "offset %x, ppr_options %x\n", ahd_name(ahd),
3710 devinfo->channel, devinfo->target, devinfo->lun,
3711 bus_width, period, offset, ppr_options);
3712 }
3713}
3714
3715/*
3716 * Clear any active message state.
3717 */
3718static void
3719ahd_clear_msg_state(struct ahd_softc *ahd)
3720{
3721 ahd_mode_state saved_modes;
3722
3723 saved_modes = ahd_save_modes(ahd);
3724 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3725 ahd->send_msg_perror = 0;
3726 ahd->msg_flags = MSG_FLAG_NONE;
3727 ahd->msgout_len = 0;
3728 ahd->msgin_index = 0;
3729 ahd->msg_type = MSG_TYPE_NONE;
3730 if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0) {
3731 /*
3732 * The target didn't care to respond to our
3733 * message request, so clear ATN.
3734 */
3735 ahd_outb(ahd, CLRSINT1, CLRATNO);
3736 }
3737 ahd_outb(ahd, MSG_OUT, MSG_NOOP);
3738 ahd_outb(ahd, SEQ_FLAGS2,
3739 ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
3740 ahd_restore_modes(ahd, saved_modes);
3741}
3742
3743/*
3744 * Manual message loop handler.
3745 */
3746static void
3747ahd_handle_message_phase(struct ahd_softc *ahd)
3748{
3749 struct ahd_devinfo devinfo;
3750 u_int bus_phase;
3751 int end_session;
3752
3753 ahd_fetch_devinfo(ahd, &devinfo);
3754 end_session = FALSE;
3755 bus_phase = ahd_inb(ahd, LASTPHASE);
3756
3757 if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0) {
3758 printf("LQIRETRY for LQIPHASE_OUTPKT\n");
3759 ahd_outb(ahd, LQCTL2, LQIRETRY);
3760 }
3761reswitch:
3762 switch (ahd->msg_type) {
3763 case MSG_TYPE_INITIATOR_MSGOUT:
3764 {
3765 int lastbyte;
3766 int phasemis;
3767 int msgdone;
3768
3769 if (ahd->msgout_len == 0 && ahd->send_msg_perror == 0)
3770 panic("HOST_MSG_LOOP interrupt with no active message");
3771
3772#ifdef AHD_DEBUG
3773 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3774 ahd_print_devinfo(ahd, &devinfo);
3775 printf("INITIATOR_MSG_OUT");
3776 }
3777#endif
3778 phasemis = bus_phase != P_MESGOUT;
3779 if (phasemis) {
3780#ifdef AHD_DEBUG
3781 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3782 printf(" PHASEMIS %s\n",
3783 ahd_lookup_phase_entry(bus_phase)
3784 ->phasemsg);
3785 }
3786#endif
3787 if (bus_phase == P_MESGIN) {
3788 /*
3789 * Change gears and see if
3790 * this messages is of interest to
3791 * us or should be passed back to
3792 * the sequencer.
3793 */
3794 ahd_outb(ahd, CLRSINT1, CLRATNO);
3795 ahd->send_msg_perror = 0;
3796 ahd->msg_type = MSG_TYPE_INITIATOR_MSGIN;
3797 ahd->msgin_index = 0;
3798 goto reswitch;
3799 }
3800 end_session = TRUE;
3801 break;
3802 }
3803
3804 if (ahd->send_msg_perror) {
3805 ahd_outb(ahd, CLRSINT1, CLRATNO);
3806 ahd_outb(ahd, CLRSINT1, CLRREQINIT);
3807#ifdef AHD_DEBUG
3808 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3809 printf(" byte 0x%x\n", ahd->send_msg_perror);
3810#endif
3811 /*
3812 * If we are notifying the target of a CRC error
3813 * during packetized operations, the target is
3814 * within its rights to acknowledge our message
3815 * with a busfree.
3816 */
3817 if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0
3818 && ahd->send_msg_perror == MSG_INITIATOR_DET_ERR)
3819 ahd->msg_flags |= MSG_FLAG_EXPECT_IDE_BUSFREE;
3820
3821 ahd_outb(ahd, RETURN_2, ahd->send_msg_perror);
3822 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE);
3823 break;
3824 }
3825
3826 msgdone = ahd->msgout_index == ahd->msgout_len;
3827 if (msgdone) {
3828 /*
3829 * The target has requested a retry.
3830 * Re-assert ATN, reset our message index to
3831 * 0, and try again.
3832 */
3833 ahd->msgout_index = 0;
3834 ahd_assert_atn(ahd);
3835 }
3836
3837 lastbyte = ahd->msgout_index == (ahd->msgout_len - 1);
3838 if (lastbyte) {
3839 /* Last byte is signified by dropping ATN */
3840 ahd_outb(ahd, CLRSINT1, CLRATNO);
3841 }
3842
3843 /*
3844 * Clear our interrupt status and present
3845 * the next byte on the bus.
3846 */
3847 ahd_outb(ahd, CLRSINT1, CLRREQINIT);
3848#ifdef AHD_DEBUG
3849 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3850 printf(" byte 0x%x\n",
3851 ahd->msgout_buf[ahd->msgout_index]);
3852#endif
3853 ahd_outb(ahd, RETURN_2, ahd->msgout_buf[ahd->msgout_index++]);
3854 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE);
3855 break;
3856 }
3857 case MSG_TYPE_INITIATOR_MSGIN:
3858 {
3859 int phasemis;
3860 int message_done;
3861
3862#ifdef AHD_DEBUG
3863 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3864 ahd_print_devinfo(ahd, &devinfo);
3865 printf("INITIATOR_MSG_IN");
3866 }
3867#endif
3868 phasemis = bus_phase != P_MESGIN;
3869 if (phasemis) {
3870#ifdef AHD_DEBUG
3871 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3872 printf(" PHASEMIS %s\n",
3873 ahd_lookup_phase_entry(bus_phase)
3874 ->phasemsg);
3875 }
3876#endif
3877 ahd->msgin_index = 0;
3878 if (bus_phase == P_MESGOUT
3879 && (ahd->send_msg_perror != 0
3880 || (ahd->msgout_len != 0
3881 && ahd->msgout_index == 0))) {
3882 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3883 goto reswitch;
3884 }
3885 end_session = TRUE;
3886 break;
3887 }
3888
3889 /* Pull the byte in without acking it */
3890 ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIBUS);
3891#ifdef AHD_DEBUG
3892 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3893 printf(" byte 0x%x\n",
3894 ahd->msgin_buf[ahd->msgin_index]);
3895#endif
3896
3897 message_done = ahd_parse_msg(ahd, &devinfo);
3898
3899 if (message_done) {
3900 /*
3901 * Clear our incoming message buffer in case there
3902 * is another message following this one.
3903 */
3904 ahd->msgin_index = 0;
3905
3906 /*
3907 * If this message illicited a response,
3908 * assert ATN so the target takes us to the
3909 * message out phase.
3910 */
3911 if (ahd->msgout_len != 0) {
3912#ifdef AHD_DEBUG
3913 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3914 ahd_print_devinfo(ahd, &devinfo);
3915 printf("Asserting ATN for response\n");
3916 }
3917#endif
3918 ahd_assert_atn(ahd);
3919 }
3920 } else
3921 ahd->msgin_index++;
3922
3923 if (message_done == MSGLOOP_TERMINATED) {
3924 end_session = TRUE;
3925 } else {
3926 /* Ack the byte */
3927 ahd_outb(ahd, CLRSINT1, CLRREQINIT);
3928 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_READ);
3929 }
3930 break;
3931 }
3932 case MSG_TYPE_TARGET_MSGIN:
3933 {
3934 int msgdone;
3935 int msgout_request;
3936
3937 /*
3938 * By default, the message loop will continue.
3939 */
3940 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);
3941
3942 if (ahd->msgout_len == 0)
3943 panic("Target MSGIN with no active message");
3944
3945 /*
3946 * If we interrupted a mesgout session, the initiator
3947 * will not know this until our first REQ. So, we
3948 * only honor mesgout requests after we've sent our
3949 * first byte.
3950 */
3951 if ((ahd_inb(ahd, SCSISIGI) & ATNI) != 0
3952 && ahd->msgout_index > 0)
3953 msgout_request = TRUE;
3954 else
3955 msgout_request = FALSE;
3956
3957 if (msgout_request) {
3958
3959 /*
3960 * Change gears and see if
3961 * this messages is of interest to
3962 * us or should be passed back to
3963 * the sequencer.
3964 */
3965 ahd->msg_type = MSG_TYPE_TARGET_MSGOUT;
3966 ahd_outb(ahd, SCSISIGO, P_MESGOUT | BSYO);
3967 ahd->msgin_index = 0;
3968 /* Dummy read to REQ for first byte */
3969 ahd_inb(ahd, SCSIDAT);
3970 ahd_outb(ahd, SXFRCTL0,
3971 ahd_inb(ahd, SXFRCTL0) | SPIOEN);
3972 break;
3973 }
3974
3975 msgdone = ahd->msgout_index == ahd->msgout_len;
3976 if (msgdone) {
3977 ahd_outb(ahd, SXFRCTL0,
3978 ahd_inb(ahd, SXFRCTL0) & ~SPIOEN);
3979 end_session = TRUE;
3980 break;
3981 }
3982
3983 /*
3984 * Present the next byte on the bus.
3985 */
3986 ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) | SPIOEN);
3987 ahd_outb(ahd, SCSIDAT, ahd->msgout_buf[ahd->msgout_index++]);
3988 break;
3989 }
3990 case MSG_TYPE_TARGET_MSGOUT:
3991 {
3992 int lastbyte;
3993 int msgdone;
3994
3995 /*
3996 * By default, the message loop will continue.
3997 */
3998 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);
3999
4000 /*
4001 * The initiator signals that this is
4002 * the last byte by dropping ATN.
4003 */
4004 lastbyte = (ahd_inb(ahd, SCSISIGI) & ATNI) == 0;
4005
4006 /*
4007 * Read the latched byte, but turn off SPIOEN first
4008 * so that we don't inadvertently cause a REQ for the
4009 * next byte.
4010 */
4011 ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) & ~SPIOEN);
4012 ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIDAT);
4013 msgdone = ahd_parse_msg(ahd, &devinfo);
4014 if (msgdone == MSGLOOP_TERMINATED) {
4015 /*
4016 * The message is *really* done in that it caused
4017 * us to go to bus free. The sequencer has already
4018 * been reset at this point, so pull the ejection
4019 * handle.
4020 */
4021 return;
4022 }
4023
4024 ahd->msgin_index++;
4025
4026 /*
4027 * XXX Read spec about initiator dropping ATN too soon
4028 * and use msgdone to detect it.
4029 */
4030 if (msgdone == MSGLOOP_MSGCOMPLETE) {
4031 ahd->msgin_index = 0;
4032
4033 /*
4034 * If this message illicited a response, transition
4035 * to the Message in phase and send it.
4036 */
4037 if (ahd->msgout_len != 0) {
4038 ahd_outb(ahd, SCSISIGO, P_MESGIN | BSYO);
4039 ahd_outb(ahd, SXFRCTL0,
4040 ahd_inb(ahd, SXFRCTL0) | SPIOEN);
4041 ahd->msg_type = MSG_TYPE_TARGET_MSGIN;
4042 ahd->msgin_index = 0;
4043 break;
4044 }
4045 }
4046
4047 if (lastbyte)
4048 end_session = TRUE;
4049 else {
4050 /* Ask for the next byte. */
4051 ahd_outb(ahd, SXFRCTL0,
4052 ahd_inb(ahd, SXFRCTL0) | SPIOEN);
4053 }
4054
4055 break;
4056 }
4057 default:
4058 panic("Unknown REQINIT message type");
4059 }
4060
4061 if (end_session) {
4062 if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) {
4063 printf("%s: Returning to Idle Loop\n",
4064 ahd_name(ahd));
4065 ahd_clear_msg_state(ahd);
4066
4067 /*
4068 * Perform the equivalent of a clear_target_state.
4069 */
4070 ahd_outb(ahd, LASTPHASE, P_BUSFREE);
4071 ahd_outb(ahd, SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT);
4072 ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
4073 } else {
4074 ahd_clear_msg_state(ahd);
4075 ahd_outb(ahd, RETURN_1, EXIT_MSG_LOOP);
4076 }
4077 }
4078}
4079
4080/*
4081 * See if we sent a particular extended message to the target.
4082 * If "full" is true, return true only if the target saw the full
4083 * message. If "full" is false, return true if the target saw at
4084 * least the first byte of the message.
4085 */
4086static int
4087ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full)
4088{
4089 int found;
4090 u_int index;
4091
4092 found = FALSE;
4093 index = 0;
4094
4095 while (index < ahd->msgout_len) {
4096 if (ahd->msgout_buf[index] == MSG_EXTENDED) {
4097 u_int end_index;
4098
4099 end_index = index + 1 + ahd->msgout_buf[index + 1];
4100 if (ahd->msgout_buf[index+2] == msgval
4101 && type == AHDMSG_EXT) {
4102
4103 if (full) {
4104 if (ahd->msgout_index > end_index)
4105 found = TRUE;
4106 } else if (ahd->msgout_index > index)
4107 found = TRUE;
4108 }
4109 index = end_index;
4110 } else if (ahd->msgout_buf[index] >= MSG_SIMPLE_TASK
4111 && ahd->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
4112
4113 /* Skip tag type and tag id or residue param*/
4114 index += 2;
4115 } else {
4116 /* Single byte message */
4117 if (type == AHDMSG_1B
4118 && ahd->msgout_index > index
4119 && (ahd->msgout_buf[index] == msgval
4120 || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0
4121 && msgval == MSG_IDENTIFYFLAG)))
4122 found = TRUE;
4123 index++;
4124 }
4125
4126 if (found)
4127 break;
4128 }
4129 return (found);
4130}
4131
4132/*
4133 * Wait for a complete incoming message, parse it, and respond accordingly.
4134 */
4135static int
4136ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
4137{
4138 struct ahd_initiator_tinfo *tinfo;
4139 struct ahd_tmode_tstate *tstate;
4140 int reject;
4141 int done;
4142 int response;
4143
4144 done = MSGLOOP_IN_PROG;
4145 response = FALSE;
4146 reject = FALSE;
4147 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
4148 devinfo->target, &tstate);
4149
4150 /*
4151 * Parse as much of the message as is available,
4152 * rejecting it if we don't support it. When
4153 * the entire message is available and has been
4154 * handled, return MSGLOOP_MSGCOMPLETE, indicating
4155 * that we have parsed an entire message.
4156 *
4157 * In the case of extended messages, we accept the length
4158 * byte outright and perform more checking once we know the
4159 * extended message type.
4160 */
4161 switch (ahd->msgin_buf[0]) {
4162 case MSG_DISCONNECT:
4163 case MSG_SAVEDATAPOINTER:
4164 case MSG_CMDCOMPLETE:
4165 case MSG_RESTOREPOINTERS:
4166 case MSG_IGN_WIDE_RESIDUE:
4167 /*
4168 * End our message loop as these are messages
4169 * the sequencer handles on its own.
4170 */
4171 done = MSGLOOP_TERMINATED;
4172 break;
4173 case MSG_MESSAGE_REJECT:
4174 response = ahd_handle_msg_reject(ahd, devinfo);
4175 /* FALLTHROUGH */
4176 case MSG_NOOP:
4177 done = MSGLOOP_MSGCOMPLETE;
4178 break;
4179 case MSG_EXTENDED:
4180 {
4181 /* Wait for enough of the message to begin validation */
4182 if (ahd->msgin_index < 2)
4183 break;
4184 switch (ahd->msgin_buf[2]) {
4185 case MSG_EXT_SDTR:
4186 {
4187 u_int period;
4188 u_int ppr_options;
4189 u_int offset;
4190 u_int saved_offset;
4191
4192 if (ahd->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
4193 reject = TRUE;
4194 break;
4195 }
4196
4197 /*
4198 * Wait until we have both args before validating
4199 * and acting on this message.
4200 *
4201 * Add one to MSG_EXT_SDTR_LEN to account for
4202 * the extended message preamble.
4203 */
4204 if (ahd->msgin_index < (MSG_EXT_SDTR_LEN + 1))
4205 break;
4206
4207 period = ahd->msgin_buf[3];
4208 ppr_options = 0;
4209 saved_offset = offset = ahd->msgin_buf[4];
4210 ahd_devlimited_syncrate(ahd, tinfo, &period,
4211 &ppr_options, devinfo->role);
4212 ahd_validate_offset(ahd, tinfo, period, &offset,
4213 tinfo->curr.width, devinfo->role);
4214 if (bootverbose) {
4215 printf("(%s:%c:%d:%d): Received "
4216 "SDTR period %x, offset %x\n\t"
4217 "Filtered to period %x, offset %x\n",
4218 ahd_name(ahd), devinfo->channel,
4219 devinfo->target, devinfo->lun,
4220 ahd->msgin_buf[3], saved_offset,
4221 period, offset);
4222 }
4223 ahd_set_syncrate(ahd, devinfo, period,
4224 offset, ppr_options,
4225 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4226 /*paused*/TRUE);
4227
4228 /*
4229 * See if we initiated Sync Negotiation
4230 * and didn't have to fall down to async
4231 * transfers.
4232 */
4233 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, TRUE)) {
4234 /* We started it */
4235 if (saved_offset != offset) {
4236 /* Went too low - force async */
4237 reject = TRUE;
4238 }
4239 } else {
4240 /*
4241 * Send our own SDTR in reply
4242 */
4243 if (bootverbose
4244 && devinfo->role == ROLE_INITIATOR) {
4245 printf("(%s:%c:%d:%d): Target "
4246 "Initiated SDTR\n",
4247 ahd_name(ahd), devinfo->channel,
4248 devinfo->target, devinfo->lun);
4249 }
4250 ahd->msgout_index = 0;
4251 ahd->msgout_len = 0;
4252 ahd_construct_sdtr(ahd, devinfo,
4253 period, offset);
4254 ahd->msgout_index = 0;
4255 response = TRUE;
4256 }
4257 done = MSGLOOP_MSGCOMPLETE;
4258 break;
4259 }
4260 case MSG_EXT_WDTR:
4261 {
4262 u_int bus_width;
4263 u_int saved_width;
4264 u_int sending_reply;
4265
4266 sending_reply = FALSE;
4267 if (ahd->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
4268 reject = TRUE;
4269 break;
4270 }
4271
4272 /*
4273 * Wait until we have our arg before validating
4274 * and acting on this message.
4275 *
4276 * Add one to MSG_EXT_WDTR_LEN to account for
4277 * the extended message preamble.
4278 */
4279 if (ahd->msgin_index < (MSG_EXT_WDTR_LEN + 1))
4280 break;
4281
4282 bus_width = ahd->msgin_buf[3];
4283 saved_width = bus_width;
4284 ahd_validate_width(ahd, tinfo, &bus_width,
4285 devinfo->role);
4286 if (bootverbose) {
4287 printf("(%s:%c:%d:%d): Received WDTR "
4288 "%x filtered to %x\n",
4289 ahd_name(ahd), devinfo->channel,
4290 devinfo->target, devinfo->lun,
4291 saved_width, bus_width);
4292 }
4293
4294 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, TRUE)) {
4295 /*
4296 * Don't send a WDTR back to the
4297 * target, since we asked first.
4298 * If the width went higher than our
4299 * request, reject it.
4300 */
4301 if (saved_width > bus_width) {
4302 reject = TRUE;
4303 printf("(%s:%c:%d:%d): requested %dBit "
4304 "transfers. Rejecting...\n",
4305 ahd_name(ahd), devinfo->channel,
4306 devinfo->target, devinfo->lun,
4307 8 * (0x01 << bus_width));
4308 bus_width = 0;
4309 }
4310 } else {
4311 /*
4312 * Send our own WDTR in reply
4313 */
4314 if (bootverbose
4315 && devinfo->role == ROLE_INITIATOR) {
4316 printf("(%s:%c:%d:%d): Target "
4317 "Initiated WDTR\n",
4318 ahd_name(ahd), devinfo->channel,
4319 devinfo->target, devinfo->lun);
4320 }
4321 ahd->msgout_index = 0;
4322 ahd->msgout_len = 0;
4323 ahd_construct_wdtr(ahd, devinfo, bus_width);
4324 ahd->msgout_index = 0;
4325 response = TRUE;
4326 sending_reply = TRUE;
4327 }
4328 /*
4329 * After a wide message, we are async, but
4330 * some devices don't seem to honor this portion
4331 * of the spec. Force a renegotiation of the
4332 * sync component of our transfer agreement even
4333 * if our goal is async. By updating our width
4334 * after forcing the negotiation, we avoid
4335 * renegotiating for width.
4336 */
4337 ahd_update_neg_request(ahd, devinfo, tstate,
4338 tinfo, AHD_NEG_ALWAYS);
4339 ahd_set_width(ahd, devinfo, bus_width,
4340 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4341 /*paused*/TRUE);
4342 if (sending_reply == FALSE && reject == FALSE) {
4343
4344 /*
4345 * We will always have an SDTR to send.
4346 */
4347 ahd->msgout_index = 0;
4348 ahd->msgout_len = 0;
4349 ahd_build_transfer_msg(ahd, devinfo);
4350 ahd->msgout_index = 0;
4351 response = TRUE;
4352 }
4353 done = MSGLOOP_MSGCOMPLETE;
4354 break;
4355 }
4356 case MSG_EXT_PPR:
4357 {
4358 u_int period;
4359 u_int offset;
4360 u_int bus_width;
4361 u_int ppr_options;
4362 u_int saved_width;
4363 u_int saved_offset;
4364 u_int saved_ppr_options;
4365
4366 if (ahd->msgin_buf[1] != MSG_EXT_PPR_LEN) {
4367 reject = TRUE;
4368 break;
4369 }
4370
4371 /*
4372 * Wait until we have all args before validating
4373 * and acting on this message.
4374 *
4375 * Add one to MSG_EXT_PPR_LEN to account for
4376 * the extended message preamble.
4377 */
4378 if (ahd->msgin_index < (MSG_EXT_PPR_LEN + 1))
4379 break;
4380
4381 period = ahd->msgin_buf[3];
4382 offset = ahd->msgin_buf[5];
4383 bus_width = ahd->msgin_buf[6];
4384 saved_width = bus_width;
4385 ppr_options = ahd->msgin_buf[7];
4386 /*
4387 * According to the spec, a DT only
4388 * period factor with no DT option
4389 * set implies async.
4390 */
4391 if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
4392 && period <= 9)
4393 offset = 0;
4394 saved_ppr_options = ppr_options;
4395 saved_offset = offset;
4396
4397 /*
4398 * Transfer options are only available if we
4399 * are negotiating wide.
4400 */
4401 if (bus_width == 0)
4402 ppr_options &= MSG_EXT_PPR_QAS_REQ;
4403
4404 ahd_validate_width(ahd, tinfo, &bus_width,
4405 devinfo->role);
4406 ahd_devlimited_syncrate(ahd, tinfo, &period,
4407 &ppr_options, devinfo->role);
4408 ahd_validate_offset(ahd, tinfo, period, &offset,
4409 bus_width, devinfo->role);
4410
4411 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, TRUE)) {
4412 /*
4413 * If we are unable to do any of the
4414 * requested options (we went too low),
4415 * then we'll have to reject the message.
4416 */
4417 if (saved_width > bus_width
4418 || saved_offset != offset
4419 || saved_ppr_options != ppr_options) {
4420 reject = TRUE;
4421 period = 0;
4422 offset = 0;
4423 bus_width = 0;
4424 ppr_options = 0;
4425 }
4426 } else {
4427 if (devinfo->role != ROLE_TARGET)
4428 printf("(%s:%c:%d:%d): Target "
4429 "Initiated PPR\n",
4430 ahd_name(ahd), devinfo->channel,
4431 devinfo->target, devinfo->lun);
4432 else
4433 printf("(%s:%c:%d:%d): Initiator "
4434 "Initiated PPR\n",
4435 ahd_name(ahd), devinfo->channel,
4436 devinfo->target, devinfo->lun);
4437 ahd->msgout_index = 0;
4438 ahd->msgout_len = 0;
4439 ahd_construct_ppr(ahd, devinfo, period, offset,
4440 bus_width, ppr_options);
4441 ahd->msgout_index = 0;
4442 response = TRUE;
4443 }
4444 if (bootverbose) {
4445 printf("(%s:%c:%d:%d): Received PPR width %x, "
4446 "period %x, offset %x,options %x\n"
4447 "\tFiltered to width %x, period %x, "
4448 "offset %x, options %x\n",
4449 ahd_name(ahd), devinfo->channel,
4450 devinfo->target, devinfo->lun,
4451 saved_width, ahd->msgin_buf[3],
4452 saved_offset, saved_ppr_options,
4453 bus_width, period, offset, ppr_options);
4454 }
4455 ahd_set_width(ahd, devinfo, bus_width,
4456 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4457 /*paused*/TRUE);
4458 ahd_set_syncrate(ahd, devinfo, period,
4459 offset, ppr_options,
4460 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4461 /*paused*/TRUE);
4462
4463 done = MSGLOOP_MSGCOMPLETE;
4464 break;
4465 }
4466 default:
4467 /* Unknown extended message. Reject it. */
4468 reject = TRUE;
4469 break;
4470 }
4471 break;
4472 }
4473#ifdef AHD_TARGET_MODE
4474 case MSG_BUS_DEV_RESET:
4475 ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD,
4476 CAM_BDR_SENT,
4477 "Bus Device Reset Received",
4478 /*verbose_level*/0);
4479 ahd_restart(ahd);
4480 done = MSGLOOP_TERMINATED;
4481 break;
4482 case MSG_ABORT_TAG:
4483 case MSG_ABORT:
4484 case MSG_CLEAR_QUEUE:
4485 {
4486 int tag;
4487
4488 /* Target mode messages */
4489 if (devinfo->role != ROLE_TARGET) {
4490 reject = TRUE;
4491 break;
4492 }
4493 tag = SCB_LIST_NULL;
4494 if (ahd->msgin_buf[0] == MSG_ABORT_TAG)
4495 tag = ahd_inb(ahd, INITIATOR_TAG);
4496 ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
4497 devinfo->lun, tag, ROLE_TARGET,
4498 CAM_REQ_ABORTED);
4499
4500 tstate = ahd->enabled_targets[devinfo->our_scsiid];
4501 if (tstate != NULL) {
4502 struct ahd_tmode_lstate* lstate;
4503
4504 lstate = tstate->enabled_luns[devinfo->lun];
4505 if (lstate != NULL) {
4506 ahd_queue_lstate_event(ahd, lstate,
4507 devinfo->our_scsiid,
4508 ahd->msgin_buf[0],
4509 /*arg*/tag);
4510 ahd_send_lstate_events(ahd, lstate);
4511 }
4512 }
4513 ahd_restart(ahd);
4514 done = MSGLOOP_TERMINATED;
4515 break;
4516 }
4517#endif
4518 case MSG_QAS_REQUEST:
4519#ifdef AHD_DEBUG
4520 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
4521 printf("%s: QAS request. SCSISIGI == 0x%x\n",
4522 ahd_name(ahd), ahd_inb(ahd, SCSISIGI));
4523#endif
4524 ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE;
4525 /* FALLTHROUGH */
4526 case MSG_TERM_IO_PROC:
4527 default:
4528 reject = TRUE;
4529 break;
4530 }
4531
4532 if (reject) {
4533 /*
4534 * Setup to reject the message.
4535 */
4536 ahd->msgout_index = 0;
4537 ahd->msgout_len = 1;
4538 ahd->msgout_buf[0] = MSG_MESSAGE_REJECT;
4539 done = MSGLOOP_MSGCOMPLETE;
4540 response = TRUE;
4541 }
4542
4543 if (done != MSGLOOP_IN_PROG && !response)
4544 /* Clear the outgoing message buffer */
4545 ahd->msgout_len = 0;
4546
4547 return (done);
4548}
4549
4550/*
4551 * Process a message reject message.
4552 */
4553static int
4554ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
4555{
4556 /*
4557 * What we care about here is if we had an
4558 * outstanding SDTR or WDTR message for this
4559 * target. If we did, this is a signal that
4560 * the target is refusing negotiation.
4561 */
4562 struct scb *scb;
4563 struct ahd_initiator_tinfo *tinfo;
4564 struct ahd_tmode_tstate *tstate;
4565 u_int scb_index;
4566 u_int last_msg;
4567 int response = 0;
4568
4569 scb_index = ahd_get_scbptr(ahd);
4570 scb = ahd_lookup_scb(ahd, scb_index);
4571 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel,
4572 devinfo->our_scsiid,
4573 devinfo->target, &tstate);
4574 /* Might be necessary */
4575 last_msg = ahd_inb(ahd, LAST_MSG);
4576
4577 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) {
4578 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/TRUE)
4579 && tinfo->goal.period <= AHD_SYNCRATE_PACED) {
4580 /*
4581 * Target may not like our SPI-4 PPR Options.
4582 * Attempt to negotiate 80MHz which will turn
4583 * off these options.
4584 */
4585 if (bootverbose) {
4586 printf("(%s:%c:%d:%d): PPR Rejected. "
4587 "Trying simple U160 PPR\n",
4588 ahd_name(ahd), devinfo->channel,
4589 devinfo->target, devinfo->lun);
4590 }
4591 tinfo->goal.period = AHD_SYNCRATE_DT;
4592 tinfo->goal.ppr_options &= MSG_EXT_PPR_IU_REQ
4593 | MSG_EXT_PPR_QAS_REQ
4594 | MSG_EXT_PPR_DT_REQ;
4595 } else {
4596 /*
4597 * Target does not support the PPR message.
4598 * Attempt to negotiate SPI-2 style.
4599 */
4600 if (bootverbose) {
4601 printf("(%s:%c:%d:%d): PPR Rejected. "
4602 "Trying WDTR/SDTR\n",
4603 ahd_name(ahd), devinfo->channel,
4604 devinfo->target, devinfo->lun);
4605 }
4606 tinfo->goal.ppr_options = 0;
4607 tinfo->curr.transport_version = 2;
4608 tinfo->goal.transport_version = 2;
4609 }
4610 ahd->msgout_index = 0;
4611 ahd->msgout_len = 0;
4612 ahd_build_transfer_msg(ahd, devinfo);
4613 ahd->msgout_index = 0;
4614 response = 1;
4615 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
4616
4617 /* note 8bit xfers */
4618 printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
4619 "8bit transfers\n", ahd_name(ahd),
4620 devinfo->channel, devinfo->target, devinfo->lun);
4621 ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
4622 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4623 /*paused*/TRUE);
4624 /*
4625 * No need to clear the sync rate. If the target
4626 * did not accept the command, our syncrate is
4627 * unaffected. If the target started the negotiation,
4628 * but rejected our response, we already cleared the
4629 * sync rate before sending our WDTR.
4630 */
4631 if (tinfo->goal.offset != tinfo->curr.offset) {
4632
4633 /* Start the sync negotiation */
4634 ahd->msgout_index = 0;
4635 ahd->msgout_len = 0;
4636 ahd_build_transfer_msg(ahd, devinfo);
4637 ahd->msgout_index = 0;
4638 response = 1;
4639 }
4640 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) {
4641 /* note asynch xfers and clear flag */
4642 ahd_set_syncrate(ahd, devinfo, /*period*/0,
4643 /*offset*/0, /*ppr_options*/0,
4644 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4645 /*paused*/TRUE);
4646 printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
4647 "Using asynchronous transfers\n",
4648 ahd_name(ahd), devinfo->channel,
4649 devinfo->target, devinfo->lun);
4650 } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
4651 int tag_type;
4652 int mask;
4653
4654 tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
4655
4656 if (tag_type == MSG_SIMPLE_TASK) {
4657 printf("(%s:%c:%d:%d): refuses tagged commands. "
4658 "Performing non-tagged I/O\n", ahd_name(ahd),
4659 devinfo->channel, devinfo->target, devinfo->lun);
4660 ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE);
4661 mask = ~0x23;
4662 } else {
4663 printf("(%s:%c:%d:%d): refuses %s tagged commands. "
4664 "Performing simple queue tagged I/O only\n",
4665 ahd_name(ahd), devinfo->channel, devinfo->target,
4666 devinfo->lun, tag_type == MSG_ORDERED_TASK
4667 ? "ordered" : "head of queue");
4668 ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC);
4669 mask = ~0x03;
4670 }
4671
4672 /*
4673 * Resend the identify for this CCB as the target
4674 * may believe that the selection is invalid otherwise.
4675 */
4676 ahd_outb(ahd, SCB_CONTROL,
4677 ahd_inb_scbram(ahd, SCB_CONTROL) & mask);
4678 scb->hscb->control &= mask;
4679 ahd_set_transaction_tag(scb, /*enabled*/FALSE,
4680 /*type*/MSG_SIMPLE_TASK);
4681 ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG);
4682 ahd_assert_atn(ahd);
4683 ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
4684 SCB_GET_TAG(scb));
4685
4686 /*
4687 * Requeue all tagged commands for this target
4688 * currently in our posession so they can be
4689 * converted to untagged commands.
4690 */
4691 ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
4692 SCB_GET_CHANNEL(ahd, scb),
4693 SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL,
4694 ROLE_INITIATOR, CAM_REQUEUE_REQ,
4695 SEARCH_COMPLETE);
4696 } else if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_IDENTIFYFLAG, TRUE)) {
4697 /*
4698 * Most likely the device believes that we had
4699 * previously negotiated packetized.
4700 */
4701 ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE
4702 | MSG_FLAG_IU_REQ_CHANGED;
4703
4704 ahd_force_renegotiation(ahd, devinfo);
4705 ahd->msgout_index = 0;
4706 ahd->msgout_len = 0;
4707 ahd_build_transfer_msg(ahd, devinfo);
4708 ahd->msgout_index = 0;
4709 response = 1;
4710 } else {
4711 /*
4712 * Otherwise, we ignore it.
4713 */
4714 printf("%s:%c:%d: Message reject for %x -- ignored\n",
4715 ahd_name(ahd), devinfo->channel, devinfo->target,
4716 last_msg);
4717 }
4718 return (response);
4719}
4720
4721/*
4722 * Process an ingnore wide residue message.
4723 */
4724static void
4725ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
4726{
4727 u_int scb_index;
4728 struct scb *scb;
4729
4730 scb_index = ahd_get_scbptr(ahd);
4731 scb = ahd_lookup_scb(ahd, scb_index);
4732 /*
4733 * XXX Actually check data direction in the sequencer?
4734 * Perhaps add datadir to some spare bits in the hscb?
4735 */
4736 if ((ahd_inb(ahd, SEQ_FLAGS) & DPHASE) == 0
4737 || ahd_get_transfer_dir(scb) != CAM_DIR_IN) {
4738 /*
4739 * Ignore the message if we haven't
4740 * seen an appropriate data phase yet.
4741 */
4742 } else {
4743 /*
4744 * If the residual occurred on the last
4745 * transfer and the transfer request was
4746 * expected to end on an odd count, do
4747 * nothing. Otherwise, subtract a byte
4748 * and update the residual count accordingly.
4749 */
4750 uint32_t sgptr;
4751
4752 sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
4753 if ((sgptr & SG_LIST_NULL) != 0
4754 && (ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
4755 & SCB_XFERLEN_ODD) != 0) {
4756 /*
4757 * If the residual occurred on the last
4758 * transfer and the transfer request was
4759 * expected to end on an odd count, do
4760 * nothing.
4761 */
4762 } else {
4763 uint32_t data_cnt;
4764 uint64_t data_addr;
4765 uint32_t sglen;
4766
4767 /* Pull in the rest of the sgptr */
4768 sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
4769 data_cnt = ahd_inl_scbram(ahd, SCB_RESIDUAL_DATACNT);
4770 if ((sgptr & SG_LIST_NULL) != 0) {
4771 /*
4772 * The residual data count is not updated
4773 * for the command run to completion case.
4774 * Explicitly zero the count.
4775 */
4776 data_cnt &= ~AHD_SG_LEN_MASK;
4777 }
4778 data_addr = ahd_inq(ahd, SHADDR);
4779 data_cnt += 1;
4780 data_addr -= 1;
4781 sgptr &= SG_PTR_MASK;
4782 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
4783 struct ahd_dma64_seg *sg;
4784
4785 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4786
4787 /*
4788 * The residual sg ptr points to the next S/G
4789 * to load so we must go back one.
4790 */
4791 sg--;
4792 sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
4793 if (sg != scb->sg_list
4794 && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
4795
4796 sg--;
4797 sglen = ahd_le32toh(sg->len);
4798 /*
4799 * Preserve High Address and SG_LIST
4800 * bits while setting the count to 1.
4801 */
4802 data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
4803 data_addr = ahd_le64toh(sg->addr)
4804 + (sglen & AHD_SG_LEN_MASK)
4805 - 1;
4806
4807 /*
4808 * Increment sg so it points to the
4809 * "next" sg.
4810 */
4811 sg++;
4812 sgptr = ahd_sg_virt_to_bus(ahd, scb,
4813 sg);
4814 }
4815 } else {
4816 struct ahd_dma_seg *sg;
4817
4818 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4819
4820 /*
4821 * The residual sg ptr points to the next S/G
4822 * to load so we must go back one.
4823 */
4824 sg--;
4825 sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
4826 if (sg != scb->sg_list
4827 && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
4828
4829 sg--;
4830 sglen = ahd_le32toh(sg->len);
4831 /*
4832 * Preserve High Address and SG_LIST
4833 * bits while setting the count to 1.
4834 */
4835 data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
4836 data_addr = ahd_le32toh(sg->addr)
4837 + (sglen & AHD_SG_LEN_MASK)
4838 - 1;
4839
4840 /*
4841 * Increment sg so it points to the
4842 * "next" sg.
4843 */
4844 sg++;
4845 sgptr = ahd_sg_virt_to_bus(ahd, scb,
4846 sg);
4847 }
4848 }
4849 /*
4850 * Toggle the "oddness" of the transfer length
4851 * to handle this mid-transfer ignore wide
4852 * residue. This ensures that the oddness is
4853 * correct for subsequent data transfers.
4854 */
4855 ahd_outb(ahd, SCB_TASK_ATTRIBUTE,
4856 ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
4857 ^ SCB_XFERLEN_ODD);
4858
4859 ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
4860 ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
4861 /*
4862 * The FIFO's pointers will be updated if/when the
4863 * sequencer re-enters a data phase.
4864 */
4865 }
4866 }
4867}
4868
4869
4870/*
4871 * Reinitialize the data pointers for the active transfer
4872 * based on its current residual.
4873 */
4874static void
4875ahd_reinitialize_dataptrs(struct ahd_softc *ahd)
4876{
4877 struct scb *scb;
4878 ahd_mode_state saved_modes;
4879 u_int scb_index;
4880 u_int wait;
4881 uint32_t sgptr;
4882 uint32_t resid;
4883 uint64_t dataptr;
4884
4885 AHD_ASSERT_MODES(ahd, AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK,
4886 AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK);
4887
4888 scb_index = ahd_get_scbptr(ahd);
4889 scb = ahd_lookup_scb(ahd, scb_index);
4890
4891 /*
4892 * Release and reacquire the FIFO so we
4893 * have a clean slate.
4894 */
4895 ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
4896 wait = 1000;
4897 while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE))
4898 ahd_delay(100);
4899 if (wait == 0) {
4900 ahd_print_path(ahd, scb);
4901 printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n");
4902 ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
4903 }
4904 saved_modes = ahd_save_modes(ahd);
4905 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
4906 ahd_outb(ahd, DFFSTAT,
4907 ahd_inb(ahd, DFFSTAT)
4908 | (saved_modes == 0x11 ? CURRFIFO_1 : CURRFIFO_0));
4909
4910 /*
4911 * Determine initial values for data_addr and data_cnt
4912 * for resuming the data phase.
4913 */
4914 sgptr = (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24)
4915 | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16)
4916 | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8)
4917 | ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
4918 sgptr &= SG_PTR_MASK;
4919
4920 resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16)
4921 | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 1) << 8)
4922 | ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT);
4923
4924 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
4925 struct ahd_dma64_seg *sg;
4926
4927 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4928
4929 /* The residual sg_ptr always points to the next sg */
4930 sg--;
4931
4932 dataptr = ahd_le64toh(sg->addr)
4933 + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
4934 - resid;
4935 ahd_outb(ahd, HADDR + 7, dataptr >> 56);
4936 ahd_outb(ahd, HADDR + 6, dataptr >> 48);
4937 ahd_outb(ahd, HADDR + 5, dataptr >> 40);
4938 ahd_outb(ahd, HADDR + 4, dataptr >> 32);
4939 } else {
4940 struct ahd_dma_seg *sg;
4941
4942 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4943
4944 /* The residual sg_ptr always points to the next sg */
4945 sg--;
4946
4947 dataptr = ahd_le32toh(sg->addr)
4948 + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
4949 - resid;
4950 ahd_outb(ahd, HADDR + 4,
4951 (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24);
4952 }
4953 ahd_outb(ahd, HADDR + 3, dataptr >> 24);
4954 ahd_outb(ahd, HADDR + 2, dataptr >> 16);
4955 ahd_outb(ahd, HADDR + 1, dataptr >> 8);
4956 ahd_outb(ahd, HADDR, dataptr);
4957 ahd_outb(ahd, HCNT + 2, resid >> 16);
4958 ahd_outb(ahd, HCNT + 1, resid >> 8);
4959 ahd_outb(ahd, HCNT, resid);
4960}
4961
4962/*
4963 * Handle the effects of issuing a bus device reset message.
4964 */
4965static void
4966ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
4967 u_int lun, cam_status status, char *message,
4968 int verbose_level)
4969{
4970#ifdef AHD_TARGET_MODE
4971 struct ahd_tmode_tstate* tstate;
4972#endif
4973 int found;
4974
4975 found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
4976 lun, SCB_LIST_NULL, devinfo->role,
4977 status);
4978
4979#ifdef AHD_TARGET_MODE
4980 /*
4981 * Send an immediate notify ccb to all target mord peripheral
4982 * drivers affected by this action.
4983 */
4984 tstate = ahd->enabled_targets[devinfo->our_scsiid];
4985 if (tstate != NULL) {
4986 u_int cur_lun;
4987 u_int max_lun;
4988
4989 if (lun != CAM_LUN_WILDCARD) {
4990 cur_lun = 0;
4991 max_lun = AHD_NUM_LUNS - 1;
4992 } else {
4993 cur_lun = lun;
4994 max_lun = lun;
4995 }
4996 for (cur_lun <= max_lun; cur_lun++) {
4997 struct ahd_tmode_lstate* lstate;
4998
4999 lstate = tstate->enabled_luns[cur_lun];
5000 if (lstate == NULL)
5001 continue;
5002
5003 ahd_queue_lstate_event(ahd, lstate, devinfo->our_scsiid,
5004 MSG_BUS_DEV_RESET, /*arg*/0);
5005 ahd_send_lstate_events(ahd, lstate);
5006 }
5007 }
5008#endif
5009
5010 /*
5011 * Go back to async/narrow transfers and renegotiate.
5012 */
5013 ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
5014 AHD_TRANS_CUR, /*paused*/TRUE);
5015 ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0,
5016 /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE);
5017
5018 ahd_send_async(ahd, devinfo->channel, devinfo->target,
5019 lun, AC_SENT_BDR, NULL);
5020
5021 if (message != NULL
5022 && (verbose_level <= bootverbose))
5023 printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),
5024 message, devinfo->channel, devinfo->target, found);
5025}
5026
5027#ifdef AHD_TARGET_MODE
5028static void
5029ahd_setup_target_msgin(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
5030 struct scb *scb)
5031{
5032
5033 /*
5034 * To facilitate adding multiple messages together,
5035 * each routine should increment the index and len
5036 * variables instead of setting them explicitly.
5037 */
5038 ahd->msgout_index = 0;
5039 ahd->msgout_len = 0;
5040
5041 if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
5042 ahd_build_transfer_msg(ahd, devinfo);
5043 else
5044 panic("ahd_intr: AWAITING target message with no message");
5045
5046 ahd->msgout_index = 0;
5047 ahd->msg_type = MSG_TYPE_TARGET_MSGIN;
5048}
5049#endif
5050/**************************** Initialization **********************************/
5051static u_int
5052ahd_sglist_size(struct ahd_softc *ahd)
5053{
5054 bus_size_t list_size;
5055
5056 list_size = sizeof(struct ahd_dma_seg) * AHD_NSEG;
5057 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
5058 list_size = sizeof(struct ahd_dma64_seg) * AHD_NSEG;
5059 return (list_size);
5060}
5061
5062/*
5063 * Calculate the optimum S/G List allocation size. S/G elements used
5064 * for a given transaction must be physically contiguous. Assume the
5065 * OS will allocate full pages to us, so it doesn't make sense to request
5066 * less than a page.
5067 */
5068static u_int
5069ahd_sglist_allocsize(struct ahd_softc *ahd)
5070{
5071 bus_size_t sg_list_increment;
5072 bus_size_t sg_list_size;
5073 bus_size_t max_list_size;
5074 bus_size_t best_list_size;
5075
5076 /* Start out with the minimum required for AHD_NSEG. */
5077 sg_list_increment = ahd_sglist_size(ahd);
5078 sg_list_size = sg_list_increment;
5079
5080 /* Get us as close as possible to a page in size. */
5081 while ((sg_list_size + sg_list_increment) <= PAGE_SIZE)
5082 sg_list_size += sg_list_increment;
5083
5084 /*
5085 * Try to reduce the amount of wastage by allocating
5086 * multiple pages.
5087 */
5088 best_list_size = sg_list_size;
5089 max_list_size = roundup(sg_list_increment, PAGE_SIZE);
5090 if (max_list_size < 4 * PAGE_SIZE)
5091 max_list_size = 4 * PAGE_SIZE;
5092 if (max_list_size > (AHD_SCB_MAX_ALLOC * sg_list_increment))
5093 max_list_size = (AHD_SCB_MAX_ALLOC * sg_list_increment);
5094 while ((sg_list_size + sg_list_increment) <= max_list_size
5095 && (sg_list_size % PAGE_SIZE) != 0) {
5096 bus_size_t new_mod;
5097 bus_size_t best_mod;
5098
5099 sg_list_size += sg_list_increment;
5100 new_mod = sg_list_size % PAGE_SIZE;
5101 best_mod = best_list_size % PAGE_SIZE;
5102 if (new_mod > best_mod || new_mod == 0) {
5103 best_list_size = sg_list_size;
5104 }
5105 }
5106 return (best_list_size);
5107}
5108
5109/*
5110 * Allocate a controller structure for a new device
5111 * and perform initial initializion.
5112 */
5113struct ahd_softc *
5114ahd_alloc(void *platform_arg, char *name)
5115{
5116 struct ahd_softc *ahd;
5117
5118#ifndef __FreeBSD__
5119 ahd = malloc(sizeof(*ahd), M_DEVBUF, M_NOWAIT);
5120 if (!ahd) {
5121 printf("aic7xxx: cannot malloc softc!\n");
5122 free(name, M_DEVBUF);
5123 return NULL;
5124 }
5125#else
5126 ahd = device_get_softc((device_t)platform_arg);
5127#endif
5128 memset(ahd, 0, sizeof(*ahd));
5129 ahd->seep_config = malloc(sizeof(*ahd->seep_config),
5130 M_DEVBUF, M_NOWAIT);
5131 if (ahd->seep_config == NULL) {
5132#ifndef __FreeBSD__
5133 free(ahd, M_DEVBUF);
5134#endif
5135 free(name, M_DEVBUF);
5136 return (NULL);
5137 }
5138 LIST_INIT(&ahd->pending_scbs);
5139 /* We don't know our unit number until the OSM sets it */
5140 ahd->name = name;
5141 ahd->unit = -1;
5142 ahd->description = NULL;
5143 ahd->bus_description = NULL;
5144 ahd->channel = 'A';
5145 ahd->chip = AHD_NONE;
5146 ahd->features = AHD_FENONE;
5147 ahd->bugs = AHD_BUGNONE;
5148 ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A
5149 | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A;
5150 ahd_timer_init(&ahd->reset_timer);
5151 ahd_timer_init(&ahd->stat_timer);
5152 ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
5153 ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
5154 ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
5155 ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT;
5156 ahd->int_coalescing_stop_threshold =
5157 AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT;
5158
5159 if (ahd_platform_alloc(ahd, platform_arg) != 0) {
5160 ahd_free(ahd);
5161 ahd = NULL;
5162 }
5163#ifdef AHD_DEBUG
5164 if ((ahd_debug & AHD_SHOW_MEMORY) != 0) {
5165 printf("%s: scb size = 0x%x, hscb size = 0x%x\n",
5166 ahd_name(ahd), (u_int)sizeof(struct scb),
5167 (u_int)sizeof(struct hardware_scb));
5168 }
5169#endif
5170 return (ahd);
5171}
5172
5173int
5174ahd_softc_init(struct ahd_softc *ahd)
5175{
5176
5177 ahd->unpause = 0;
5178 ahd->pause = PAUSE;
5179 return (0);
5180}
5181
5182void
5183ahd_softc_insert(struct ahd_softc *ahd)
5184{
5185 struct ahd_softc *list_ahd;
5186
5187#if AHD_PCI_CONFIG > 0
5188 /*
5189 * Second Function PCI devices need to inherit some
5190 * settings from function 0.
5191 */
5192 if ((ahd->features & AHD_MULTI_FUNC) != 0) {
5193 TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
5194 ahd_dev_softc_t list_pci;
5195 ahd_dev_softc_t pci;
5196
5197 list_pci = list_ahd->dev_softc;
5198 pci = ahd->dev_softc;
5199 if (ahd_get_pci_slot(list_pci) == ahd_get_pci_slot(pci)
5200 && ahd_get_pci_bus(list_pci) == ahd_get_pci_bus(pci)) {
5201 struct ahd_softc *master;
5202 struct ahd_softc *slave;
5203
5204 if (ahd_get_pci_function(list_pci) == 0) {
5205 master = list_ahd;
5206 slave = ahd;
5207 } else {
5208 master = ahd;
5209 slave = list_ahd;
5210 }
5211 slave->flags &= ~AHD_BIOS_ENABLED;
5212 slave->flags |=
5213 master->flags & AHD_BIOS_ENABLED;
5214 break;
5215 }
5216 }
5217 }
5218#endif
5219
5220 /*
5221 * Insertion sort into our list of softcs.
5222 */
5223 list_ahd = TAILQ_FIRST(&ahd_tailq);
5224 while (list_ahd != NULL
5225 && ahd_softc_comp(ahd, list_ahd) <= 0)
5226 list_ahd = TAILQ_NEXT(list_ahd, links);
5227 if (list_ahd != NULL)
5228 TAILQ_INSERT_BEFORE(list_ahd, ahd, links);
5229 else
5230 TAILQ_INSERT_TAIL(&ahd_tailq, ahd, links);
5231 ahd->init_level++;
5232}
5233
5234/*
5235 * Verify that the passed in softc pointer is for a
5236 * controller that is still configured.
5237 */
5238struct ahd_softc *
5239ahd_find_softc(struct ahd_softc *ahd)
5240{
5241 struct ahd_softc *list_ahd;
5242
5243 TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
5244 if (list_ahd == ahd)
5245 return (ahd);
5246 }
5247 return (NULL);
5248}
5249
5250void
5251ahd_set_unit(struct ahd_softc *ahd, int unit)
5252{
5253 ahd->unit = unit;
5254}
5255
5256void
5257ahd_set_name(struct ahd_softc *ahd, char *name)
5258{
5259 if (ahd->name != NULL)
5260 free(ahd->name, M_DEVBUF);
5261 ahd->name = name;
5262}
5263
5264void
5265ahd_free(struct ahd_softc *ahd)
5266{
5267 int i;
5268
5269 switch (ahd->init_level) {
5270 default:
5271 case 5:
5272 ahd_shutdown(ahd);
5273 /* FALLTHROUGH */
5274 case 4:
5275 ahd_dmamap_unload(ahd, ahd->shared_data_dmat,
5276 ahd->shared_data_dmamap);
5277 /* FALLTHROUGH */
5278 case 3:
5279 ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo,
5280 ahd->shared_data_dmamap);
5281 ahd_dmamap_destroy(ahd, ahd->shared_data_dmat,
5282 ahd->shared_data_dmamap);
5283 /* FALLTHROUGH */
5284 case 2:
5285 ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat);
5286 case 1:
5287#ifndef __linux__
5288 ahd_dma_tag_destroy(ahd, ahd->buffer_dmat);
5289#endif
5290 break;
5291 case 0:
5292 break;
5293 }
5294
5295#ifndef __linux__
5296 ahd_dma_tag_destroy(ahd, ahd->parent_dmat);
5297#endif
5298 ahd_platform_free(ahd);
5299 ahd_fini_scbdata(ahd);
5300 for (i = 0; i < AHD_NUM_TARGETS; i++) {
5301 struct ahd_tmode_tstate *tstate;
5302
5303 tstate = ahd->enabled_targets[i];
5304 if (tstate != NULL) {
5305#ifdef AHD_TARGET_MODE
5306 int j;
5307
5308 for (j = 0; j < AHD_NUM_LUNS; j++) {
5309 struct ahd_tmode_lstate *lstate;
5310
5311 lstate = tstate->enabled_luns[j];
5312 if (lstate != NULL) {
5313 xpt_free_path(lstate->path);
5314 free(lstate, M_DEVBUF);
5315 }
5316 }
5317#endif
5318 free(tstate, M_DEVBUF);
5319 }
5320 }
5321#ifdef AHD_TARGET_MODE
5322 if (ahd->black_hole != NULL) {
5323 xpt_free_path(ahd->black_hole->path);
5324 free(ahd->black_hole, M_DEVBUF);
5325 }
5326#endif
5327 if (ahd->name != NULL)
5328 free(ahd->name, M_DEVBUF);
5329 if (ahd->seep_config != NULL)
5330 free(ahd->seep_config, M_DEVBUF);
5331 if (ahd->saved_stack != NULL)
5332 free(ahd->saved_stack, M_DEVBUF);
5333#ifndef __FreeBSD__
5334 free(ahd, M_DEVBUF);
5335#endif
5336 return;
5337}
5338
5339void
5340ahd_shutdown(void *arg)
5341{
5342 struct ahd_softc *ahd;
5343
5344 ahd = (struct ahd_softc *)arg;
5345
5346 /*
5347 * Stop periodic timer callbacks.
5348 */
5349 ahd_timer_stop(&ahd->reset_timer);
5350 ahd_timer_stop(&ahd->stat_timer);
5351
5352 /* This will reset most registers to 0, but not all */
5353 ahd_reset(ahd, /*reinit*/FALSE);
5354}
5355
5356/*
5357 * Reset the controller and record some information about it
5358 * that is only available just after a reset. If "reinit" is
5359 * non-zero, this reset occured after initial configuration
5360 * and the caller requests that the chip be fully reinitialized
5361 * to a runable state. Chip interrupts are *not* enabled after
5362 * a reinitialization. The caller must enable interrupts via
5363 * ahd_intr_enable().
5364 */
5365int
5366ahd_reset(struct ahd_softc *ahd, int reinit)
5367{
5368 u_int sxfrctl1;
5369 int wait;
5370 uint32_t cmd;
5371
5372 /*
5373 * Preserve the value of the SXFRCTL1 register for all channels.
5374 * It contains settings that affect termination and we don't want
5375 * to disturb the integrity of the bus.
5376 */
5377 ahd_pause(ahd);
5378 ahd_update_modes(ahd);
5379 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
5380 sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
5381
5382 cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
5383 if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
5384 uint32_t mod_cmd;
5385
5386 /*
5387 * A4 Razor #632
5388 * During the assertion of CHIPRST, the chip
5389 * does not disable its parity logic prior to
5390 * the start of the reset. This may cause a
5391 * parity error to be detected and thus a
5392 * spurious SERR or PERR assertion. Disble
5393 * PERR and SERR responses during the CHIPRST.
5394 */
5395 mod_cmd = cmd & ~(PCIM_CMD_PERRESPEN|PCIM_CMD_SERRESPEN);
5396 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
5397 mod_cmd, /*bytes*/2);
5398 }
5399 ahd_outb(ahd, HCNTRL, CHIPRST | ahd->pause);
5400
5401 /*
5402 * Ensure that the reset has finished. We delay 1000us
5403 * prior to reading the register to make sure the chip
5404 * has sufficiently completed its reset to handle register
5405 * accesses.
5406 */
5407 wait = 1000;
5408 do {
5409 ahd_delay(1000);
5410 } while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK));
5411
5412 if (wait == 0) {
5413 printf("%s: WARNING - Failed chip reset! "
5414 "Trying to initialize anyway.\n", ahd_name(ahd));
5415 }
5416 ahd_outb(ahd, HCNTRL, ahd->pause);
5417
5418 if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
5419 /*
5420 * Clear any latched PCI error status and restore
5421 * previous SERR and PERR response enables.
5422 */
5423 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
5424 0xFF, /*bytes*/1);
5425 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
5426 cmd, /*bytes*/2);
5427 }
5428
5429 /*
5430 * Mode should be SCSI after a chip reset, but lets
5431 * set it just to be safe. We touch the MODE_PTR
5432 * register directly so as to bypass the lazy update
5433 * code in ahd_set_modes().
5434 */
5435 ahd_known_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
5436 ahd_outb(ahd, MODE_PTR,
5437 ahd_build_mode_state(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI));
5438
5439 /*
5440 * Restore SXFRCTL1.
5441 *
5442 * We must always initialize STPWEN to 1 before we
5443 * restore the saved values. STPWEN is initialized
5444 * to a tri-state condition which can only be cleared
5445 * by turning it on.
5446 */
5447 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
5448 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
5449
5450 /* Determine chip configuration */
5451 ahd->features &= ~AHD_WIDE;
5452 if ((ahd_inb(ahd, SBLKCTL) & SELWIDE) != 0)
5453 ahd->features |= AHD_WIDE;
5454
5455 /*
5456 * If a recovery action has forced a chip reset,
5457 * re-initialize the chip to our liking.
5458 */
5459 if (reinit != 0)
5460 ahd_chip_init(ahd);
5461
5462 return (0);
5463}
5464
5465/*
5466 * Determine the number of SCBs available on the controller
5467 */
5468int
5469ahd_probe_scbs(struct ahd_softc *ahd) {
5470 int i;
5471
5472 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
5473 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
5474 for (i = 0; i < AHD_SCB_MAX; i++) {
5475 int j;
5476
5477 ahd_set_scbptr(ahd, i);
5478 ahd_outw(ahd, SCB_BASE, i);
5479 for (j = 2; j < 64; j++)
5480 ahd_outb(ahd, SCB_BASE+j, 0);
5481 /* Start out life as unallocated (needing an abort) */
5482 ahd_outb(ahd, SCB_CONTROL, MK_MESSAGE);
5483 if (ahd_inw_scbram(ahd, SCB_BASE) != i)
5484 break;
5485 ahd_set_scbptr(ahd, 0);
5486 if (ahd_inw_scbram(ahd, SCB_BASE) != 0)
5487 break;
5488 }
5489 return (i);
5490}
5491
5492static void
5493ahd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
5494{
5495 dma_addr_t *baddr;
5496
5497 baddr = (dma_addr_t *)arg;
5498 *baddr = segs->ds_addr;
5499}
5500
5501static void
5502ahd_initialize_hscbs(struct ahd_softc *ahd)
5503{
5504 int i;
5505
5506 for (i = 0; i < ahd->scb_data.maxhscbs; i++) {
5507 ahd_set_scbptr(ahd, i);
5508
5509 /* Clear the control byte. */
5510 ahd_outb(ahd, SCB_CONTROL, 0);
5511
5512 /* Set the next pointer */
5513 ahd_outw(ahd, SCB_NEXT, SCB_LIST_NULL);
5514 }
5515}
5516
5517static int
5518ahd_init_scbdata(struct ahd_softc *ahd)
5519{
5520 struct scb_data *scb_data;
5521 int i;
5522
5523 scb_data = &ahd->scb_data;
5524 TAILQ_INIT(&scb_data->free_scbs);
5525 for (i = 0; i < AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT; i++)
5526 LIST_INIT(&scb_data->free_scb_lists[i]);
5527 LIST_INIT(&scb_data->any_dev_free_scb_list);
5528 SLIST_INIT(&scb_data->hscb_maps);
5529 SLIST_INIT(&scb_data->sg_maps);
5530 SLIST_INIT(&scb_data->sense_maps);
5531
5532 /* Determine the number of hardware SCBs and initialize them */
5533 scb_data->maxhscbs = ahd_probe_scbs(ahd);
5534 if (scb_data->maxhscbs == 0) {
5535 printf("%s: No SCB space found\n", ahd_name(ahd));
5536 return (ENXIO);
5537 }
5538
5539 ahd_initialize_hscbs(ahd);
5540
5541 /*
5542 * Create our DMA tags. These tags define the kinds of device
5543 * accessible memory allocations and memory mappings we will
5544 * need to perform during normal operation.
5545 *
5546 * Unless we need to further restrict the allocation, we rely
5547 * on the restrictions of the parent dmat, hence the common
5548 * use of MAXADDR and MAXSIZE.
5549 */
5550
5551 /* DMA tag for our hardware scb structures */
5552 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
5553 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
5554 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
5555 /*highaddr*/BUS_SPACE_MAXADDR,
5556 /*filter*/NULL, /*filterarg*/NULL,
5557 PAGE_SIZE, /*nsegments*/1,
5558 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
5559 /*flags*/0, &scb_data->hscb_dmat) != 0) {
5560 goto error_exit;
5561 }
5562
5563 scb_data->init_level++;
5564
5565 /* DMA tag for our S/G structures. */
5566 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/8,
5567 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
5568 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
5569 /*highaddr*/BUS_SPACE_MAXADDR,
5570 /*filter*/NULL, /*filterarg*/NULL,
5571 ahd_sglist_allocsize(ahd), /*nsegments*/1,
5572 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
5573 /*flags*/0, &scb_data->sg_dmat) != 0) {
5574 goto error_exit;
5575 }
5576#ifdef AHD_DEBUG
5577 if ((ahd_debug & AHD_SHOW_MEMORY) != 0)
5578 printf("%s: ahd_sglist_allocsize = 0x%x\n", ahd_name(ahd),
5579 ahd_sglist_allocsize(ahd));
5580#endif
5581
5582 scb_data->init_level++;
5583
5584 /* DMA tag for our sense buffers. We allocate in page sized chunks */
5585 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
5586 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
5587 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
5588 /*highaddr*/BUS_SPACE_MAXADDR,
5589 /*filter*/NULL, /*filterarg*/NULL,
5590 PAGE_SIZE, /*nsegments*/1,
5591 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
5592 /*flags*/0, &scb_data->sense_dmat) != 0) {
5593 goto error_exit;
5594 }
5595
5596 scb_data->init_level++;
5597
5598 /* Perform initial CCB allocation */
5599 ahd_alloc_scbs(ahd);
5600
5601 if (scb_data->numscbs == 0) {
5602 printf("%s: ahd_init_scbdata - "
5603 "Unable to allocate initial scbs\n",
5604 ahd_name(ahd));
5605 goto error_exit;
5606 }
5607
5608 /*
5609 * Note that we were successfull
5610 */
5611 return (0);
5612
5613error_exit:
5614
5615 return (ENOMEM);
5616}
5617
5618static struct scb *
5619ahd_find_scb_by_tag(struct ahd_softc *ahd, u_int tag)
5620{
5621 struct scb *scb;
5622
5623 /*
5624 * Look on the pending list.
5625 */
5626 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
5627 if (SCB_GET_TAG(scb) == tag)
5628 return (scb);
5629 }
5630
5631 /*
5632 * Then on all of the collision free lists.
5633 */
5634 TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
5635 struct scb *list_scb;
5636
5637 list_scb = scb;
5638 do {
5639 if (SCB_GET_TAG(list_scb) == tag)
5640 return (list_scb);
5641 list_scb = LIST_NEXT(list_scb, collision_links);
5642 } while (list_scb);
5643 }
5644
5645 /*
5646 * And finally on the generic free list.
5647 */
5648 LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
5649 if (SCB_GET_TAG(scb) == tag)
5650 return (scb);
5651 }
5652
5653 return (NULL);
5654}
5655
5656static void
5657ahd_fini_scbdata(struct ahd_softc *ahd)
5658{
5659 struct scb_data *scb_data;
5660
5661 scb_data = &ahd->scb_data;
5662 if (scb_data == NULL)
5663 return;
5664
5665 switch (scb_data->init_level) {
5666 default:
5667 case 7:
5668 {
5669 struct map_node *sns_map;
5670
5671 while ((sns_map = SLIST_FIRST(&scb_data->sense_maps)) != NULL) {
5672 SLIST_REMOVE_HEAD(&scb_data->sense_maps, links);
5673 ahd_dmamap_unload(ahd, scb_data->sense_dmat,
5674 sns_map->dmamap);
5675 ahd_dmamem_free(ahd, scb_data->sense_dmat,
5676 sns_map->vaddr, sns_map->dmamap);
5677 free(sns_map, M_DEVBUF);
5678 }
5679 ahd_dma_tag_destroy(ahd, scb_data->sense_dmat);
5680 /* FALLTHROUGH */
5681 }
5682 case 6:
5683 {
5684 struct map_node *sg_map;
5685
5686 while ((sg_map = SLIST_FIRST(&scb_data->sg_maps)) != NULL) {
5687 SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
5688 ahd_dmamap_unload(ahd, scb_data->sg_dmat,
5689 sg_map->dmamap);
5690 ahd_dmamem_free(ahd, scb_data->sg_dmat,
5691 sg_map->vaddr, sg_map->dmamap);
5692 free(sg_map, M_DEVBUF);
5693 }
5694 ahd_dma_tag_destroy(ahd, scb_data->sg_dmat);
5695 /* FALLTHROUGH */
5696 }
5697 case 5:
5698 {
5699 struct map_node *hscb_map;
5700
5701 while ((hscb_map = SLIST_FIRST(&scb_data->hscb_maps)) != NULL) {
5702 SLIST_REMOVE_HEAD(&scb_data->hscb_maps, links);
5703 ahd_dmamap_unload(ahd, scb_data->hscb_dmat,
5704 hscb_map->dmamap);
5705 ahd_dmamem_free(ahd, scb_data->hscb_dmat,
5706 hscb_map->vaddr, hscb_map->dmamap);
5707 free(hscb_map, M_DEVBUF);
5708 }
5709 ahd_dma_tag_destroy(ahd, scb_data->hscb_dmat);
5710 /* FALLTHROUGH */
5711 }
5712 case 4:
5713 case 3:
5714 case 2:
5715 case 1:
5716 case 0:
5717 break;
5718 }
5719}
5720
5721/*
5722 * DSP filter Bypass must be enabled until the first selection
5723 * after a change in bus mode (Razor #491 and #493).
5724 */
5725static void
5726ahd_setup_iocell_workaround(struct ahd_softc *ahd)
5727{
5728 ahd_mode_state saved_modes;
5729
5730 saved_modes = ahd_save_modes(ahd);
5731 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
5732 ahd_outb(ahd, DSPDATACTL, ahd_inb(ahd, DSPDATACTL)
5733 | BYPASSENAB | RCVROFFSTDIS | XMITOFFSTDIS);
5734 ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) | (ENSELDO|ENSELDI));
5735#ifdef AHD_DEBUG
5736 if ((ahd_debug & AHD_SHOW_MISC) != 0)
5737 printf("%s: Setting up iocell workaround\n", ahd_name(ahd));
5738#endif
5739 ahd_restore_modes(ahd, saved_modes);
5740 ahd->flags &= ~AHD_HAD_FIRST_SEL;
5741}
5742
5743static void
5744ahd_iocell_first_selection(struct ahd_softc *ahd)
5745{
5746 ahd_mode_state saved_modes;
5747 u_int sblkctl;
5748
5749 if ((ahd->flags & AHD_HAD_FIRST_SEL) != 0)
5750 return;
5751 saved_modes = ahd_save_modes(ahd);
5752 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
5753 sblkctl = ahd_inb(ahd, SBLKCTL);
5754 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
5755#ifdef AHD_DEBUG
5756 if ((ahd_debug & AHD_SHOW_MISC) != 0)
5757 printf("%s: iocell first selection\n", ahd_name(ahd));
5758#endif
5759 if ((sblkctl & ENAB40) != 0) {
5760 ahd_outb(ahd, DSPDATACTL,
5761 ahd_inb(ahd, DSPDATACTL) & ~BYPASSENAB);
5762#ifdef AHD_DEBUG
5763 if ((ahd_debug & AHD_SHOW_MISC) != 0)
5764 printf("%s: BYPASS now disabled\n", ahd_name(ahd));
5765#endif
5766 }
5767 ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI));
5768 ahd_outb(ahd, CLRINT, CLRSCSIINT);
5769 ahd_restore_modes(ahd, saved_modes);
5770 ahd->flags |= AHD_HAD_FIRST_SEL;
5771}
5772
5773/*************************** SCB Management ***********************************/
5774static void
5775ahd_add_col_list(struct ahd_softc *ahd, struct scb *scb, u_int col_idx)
5776{
5777 struct scb_list *free_list;
5778 struct scb_tailq *free_tailq;
5779 struct scb *first_scb;
5780
5781 scb->flags |= SCB_ON_COL_LIST;
5782 AHD_SET_SCB_COL_IDX(scb, col_idx);
5783 free_list = &ahd->scb_data.free_scb_lists[col_idx];
5784 free_tailq = &ahd->scb_data.free_scbs;
5785 first_scb = LIST_FIRST(free_list);
5786 if (first_scb != NULL) {
5787 LIST_INSERT_AFTER(first_scb, scb, collision_links);
5788 } else {
5789 LIST_INSERT_HEAD(free_list, scb, collision_links);
5790 TAILQ_INSERT_TAIL(free_tailq, scb, links.tqe);
5791 }
5792}
5793
5794static void
5795ahd_rem_col_list(struct ahd_softc *ahd, struct scb *scb)
5796{
5797 struct scb_list *free_list;
5798 struct scb_tailq *free_tailq;
5799 struct scb *first_scb;
5800 u_int col_idx;
5801
5802 scb->flags &= ~SCB_ON_COL_LIST;
5803 col_idx = AHD_GET_SCB_COL_IDX(ahd, scb);
5804 free_list = &ahd->scb_data.free_scb_lists[col_idx];
5805 free_tailq = &ahd->scb_data.free_scbs;
5806 first_scb = LIST_FIRST(free_list);
5807 if (first_scb == scb) {
5808 struct scb *next_scb;
5809
5810 /*
5811 * Maintain order in the collision free
5812 * lists for fairness if this device has
5813 * other colliding tags active.
5814 */
5815 next_scb = LIST_NEXT(scb, collision_links);
5816 if (next_scb != NULL) {
5817 TAILQ_INSERT_AFTER(free_tailq, scb,
5818 next_scb, links.tqe);
5819 }
5820 TAILQ_REMOVE(free_tailq, scb, links.tqe);
5821 }
5822 LIST_REMOVE(scb, collision_links);
5823}
5824
5825/*
5826 * Get a free scb. If there are none, see if we can allocate a new SCB.
5827 */
5828struct scb *
5829ahd_get_scb(struct ahd_softc *ahd, u_int col_idx)
5830{
5831 struct scb *scb;
5832 int tries;
5833
5834 tries = 0;
5835look_again:
5836 TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
5837 if (AHD_GET_SCB_COL_IDX(ahd, scb) != col_idx) {
5838 ahd_rem_col_list(ahd, scb);
5839 goto found;
5840 }
5841 }
5842 if ((scb = LIST_FIRST(&ahd->scb_data.any_dev_free_scb_list)) == NULL) {
5843
5844 if (tries++ != 0)
5845 return (NULL);
5846 ahd_alloc_scbs(ahd);
5847 goto look_again;
5848 }
5849 LIST_REMOVE(scb, links.le);
5850 if (col_idx != AHD_NEVER_COL_IDX
5851 && (scb->col_scb != NULL)
5852 && (scb->col_scb->flags & SCB_ACTIVE) == 0) {
5853 LIST_REMOVE(scb->col_scb, links.le);
5854 ahd_add_col_list(ahd, scb->col_scb, col_idx);
5855 }
5856found:
5857 scb->flags |= SCB_ACTIVE;
5858 return (scb);
5859}
5860
5861/*
5862 * Return an SCB resource to the free list.
5863 */
5864void
5865ahd_free_scb(struct ahd_softc *ahd, struct scb *scb)
5866{
5867
5868 /* Clean up for the next user */
5869 scb->flags = SCB_FLAG_NONE;
5870 scb->hscb->control = 0;
5871 ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = NULL;
5872
5873 if (scb->col_scb == NULL) {
5874
5875 /*
5876 * No collision possible. Just free normally.
5877 */
5878 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5879 scb, links.le);
5880 } else if ((scb->col_scb->flags & SCB_ON_COL_LIST) != 0) {
5881
5882 /*
5883 * The SCB we might have collided with is on
5884 * a free collision list. Put both SCBs on
5885 * the generic list.
5886 */
5887 ahd_rem_col_list(ahd, scb->col_scb);
5888 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5889 scb, links.le);
5890 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5891 scb->col_scb, links.le);
5892 } else if ((scb->col_scb->flags
5893 & (SCB_PACKETIZED|SCB_ACTIVE)) == SCB_ACTIVE
5894 && (scb->col_scb->hscb->control & TAG_ENB) != 0) {
5895
5896 /*
5897 * The SCB we might collide with on the next allocation
5898 * is still active in a non-packetized, tagged, context.
5899 * Put us on the SCB collision list.
5900 */
5901 ahd_add_col_list(ahd, scb,
5902 AHD_GET_SCB_COL_IDX(ahd, scb->col_scb));
5903 } else {
5904 /*
5905 * The SCB we might collide with on the next allocation
5906 * is either active in a packetized context, or free.
5907 * Since we can't collide, put this SCB on the generic
5908 * free list.
5909 */
5910 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5911 scb, links.le);
5912 }
5913
5914 ahd_platform_scb_free(ahd, scb);
5915}
5916
5917void
5918ahd_alloc_scbs(struct ahd_softc *ahd)
5919{
5920 struct scb_data *scb_data;
5921 struct scb *next_scb;
5922 struct hardware_scb *hscb;
5923 struct map_node *hscb_map;
5924 struct map_node *sg_map;
5925 struct map_node *sense_map;
5926 uint8_t *segs;
5927 uint8_t *sense_data;
5928 dma_addr_t hscb_busaddr;
5929 dma_addr_t sg_busaddr;
5930 dma_addr_t sense_busaddr;
5931 int newcount;
5932 int i;
5933
5934 scb_data = &ahd->scb_data;
5935 if (scb_data->numscbs >= AHD_SCB_MAX_ALLOC)
5936 /* Can't allocate any more */
5937 return;
5938
5939 if (scb_data->scbs_left != 0) {
5940 int offset;
5941
5942 offset = (PAGE_SIZE / sizeof(*hscb)) - scb_data->scbs_left;
5943 hscb_map = SLIST_FIRST(&scb_data->hscb_maps);
5944 hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset];
5945 hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb));
5946 } else {
5947 hscb_map = malloc(sizeof(*hscb_map), M_DEVBUF, M_NOWAIT);
5948
5949 if (hscb_map == NULL)
5950 return;
5951
5952 /* Allocate the next batch of hardware SCBs */
5953 if (ahd_dmamem_alloc(ahd, scb_data->hscb_dmat,
5954 (void **)&hscb_map->vaddr,
5955 BUS_DMA_NOWAIT, &hscb_map->dmamap) != 0) {
5956 free(hscb_map, M_DEVBUF);
5957 return;
5958 }
5959
5960 SLIST_INSERT_HEAD(&scb_data->hscb_maps, hscb_map, links);
5961
5962 ahd_dmamap_load(ahd, scb_data->hscb_dmat, hscb_map->dmamap,
5963 hscb_map->vaddr, PAGE_SIZE, ahd_dmamap_cb,
5964 &hscb_map->physaddr, /*flags*/0);
5965
5966 hscb = (struct hardware_scb *)hscb_map->vaddr;
5967 hscb_busaddr = hscb_map->physaddr;
5968 scb_data->scbs_left = PAGE_SIZE / sizeof(*hscb);
5969 }
5970
5971 if (scb_data->sgs_left != 0) {
5972 int offset;
5973
5974 offset = ((ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd))
5975 - scb_data->sgs_left) * ahd_sglist_size(ahd);
5976 sg_map = SLIST_FIRST(&scb_data->sg_maps);
5977 segs = sg_map->vaddr + offset;
5978 sg_busaddr = sg_map->physaddr + offset;
5979 } else {
5980 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
5981
5982 if (sg_map == NULL)
5983 return;
5984
5985 /* Allocate the next batch of S/G lists */
5986 if (ahd_dmamem_alloc(ahd, scb_data->sg_dmat,
5987 (void **)&sg_map->vaddr,
5988 BUS_DMA_NOWAIT, &sg_map->dmamap) != 0) {
5989 free(sg_map, M_DEVBUF);
5990 return;
5991 }
5992
5993 SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
5994
5995 ahd_dmamap_load(ahd, scb_data->sg_dmat, sg_map->dmamap,
5996 sg_map->vaddr, ahd_sglist_allocsize(ahd),
5997 ahd_dmamap_cb, &sg_map->physaddr, /*flags*/0);
5998
5999 segs = sg_map->vaddr;
6000 sg_busaddr = sg_map->physaddr;
6001 scb_data->sgs_left =
6002 ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd);
6003#ifdef AHD_DEBUG
6004 if (ahd_debug & AHD_SHOW_MEMORY)
6005 printf("Mapped SG data\n");
6006#endif
6007 }
6008
6009 if (scb_data->sense_left != 0) {
6010 int offset;
6011
6012 offset = PAGE_SIZE - (AHD_SENSE_BUFSIZE * scb_data->sense_left);
6013 sense_map = SLIST_FIRST(&scb_data->sense_maps);
6014 sense_data = sense_map->vaddr + offset;
6015 sense_busaddr = sense_map->physaddr + offset;
6016 } else {
6017 sense_map = malloc(sizeof(*sense_map), M_DEVBUF, M_NOWAIT);
6018
6019 if (sense_map == NULL)
6020 return;
6021
6022 /* Allocate the next batch of sense buffers */
6023 if (ahd_dmamem_alloc(ahd, scb_data->sense_dmat,
6024 (void **)&sense_map->vaddr,
6025 BUS_DMA_NOWAIT, &sense_map->dmamap) != 0) {
6026 free(sense_map, M_DEVBUF);
6027 return;
6028 }
6029
6030 SLIST_INSERT_HEAD(&scb_data->sense_maps, sense_map, links);
6031
6032 ahd_dmamap_load(ahd, scb_data->sense_dmat, sense_map->dmamap,
6033 sense_map->vaddr, PAGE_SIZE, ahd_dmamap_cb,
6034 &sense_map->physaddr, /*flags*/0);
6035
6036 sense_data = sense_map->vaddr;
6037 sense_busaddr = sense_map->physaddr;
6038 scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE;
6039#ifdef AHD_DEBUG
6040 if (ahd_debug & AHD_SHOW_MEMORY)
6041 printf("Mapped sense data\n");
6042#endif
6043 }
6044
6045 newcount = MIN(scb_data->sense_left, scb_data->scbs_left);
6046 newcount = MIN(newcount, scb_data->sgs_left);
6047 newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));
6048 scb_data->sense_left -= newcount;
6049 scb_data->scbs_left -= newcount;
6050 scb_data->sgs_left -= newcount;
6051 for (i = 0; i < newcount; i++) {
6052 u_int col_tag;
6053
6054 struct scb_platform_data *pdata;
6055#ifndef __linux__
6056 int error;
6057#endif
6058 next_scb = (struct scb *)malloc(sizeof(*next_scb),
6059 M_DEVBUF, M_NOWAIT);
6060 if (next_scb == NULL)
6061 break;
6062
6063 pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
6064 M_DEVBUF, M_NOWAIT);
6065 if (pdata == NULL) {
6066 free(next_scb, M_DEVBUF);
6067 break;
6068 }
6069 next_scb->platform_data = pdata;
6070 next_scb->hscb_map = hscb_map;
6071 next_scb->sg_map = sg_map;
6072 next_scb->sense_map = sense_map;
6073 next_scb->sg_list = segs;
6074 next_scb->sense_data = sense_data;
6075 next_scb->sense_busaddr = sense_busaddr;
6076 memset(hscb, 0, sizeof(*hscb));
6077 next_scb->hscb = hscb;
6078 hscb->hscb_busaddr = ahd_htole32(hscb_busaddr);
6079
6080 /*
6081 * The sequencer always starts with the second entry.
6082 * The first entry is embedded in the scb.
6083 */
6084 next_scb->sg_list_busaddr = sg_busaddr;
6085 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
6086 next_scb->sg_list_busaddr
6087 += sizeof(struct ahd_dma64_seg);
6088 else
6089 next_scb->sg_list_busaddr += sizeof(struct ahd_dma_seg);
6090 next_scb->ahd_softc = ahd;
6091 next_scb->flags = SCB_FLAG_NONE;
6092#ifndef __linux__
6093 error = ahd_dmamap_create(ahd, ahd->buffer_dmat, /*flags*/0,
6094 &next_scb->dmamap);
6095 if (error != 0) {
6096 free(next_scb, M_DEVBUF);
6097 free(pdata, M_DEVBUF);
6098 break;
6099 }
6100#endif
6101 next_scb->hscb->tag = ahd_htole16(scb_data->numscbs);
6102 col_tag = scb_data->numscbs ^ 0x100;
6103 next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag);
6104 if (next_scb->col_scb != NULL)
6105 next_scb->col_scb->col_scb = next_scb;
6106 ahd_free_scb(ahd, next_scb);
6107 hscb++;
6108 hscb_busaddr += sizeof(*hscb);
6109 segs += ahd_sglist_size(ahd);
6110 sg_busaddr += ahd_sglist_size(ahd);
6111 sense_data += AHD_SENSE_BUFSIZE;
6112 sense_busaddr += AHD_SENSE_BUFSIZE;
6113 scb_data->numscbs++;
6114 }
6115}
6116
6117void
6118ahd_controller_info(struct ahd_softc *ahd, char *buf)
6119{
6120 const char *speed;
6121 const char *type;
6122 int len;
6123
6124 len = sprintf(buf, "%s: ", ahd_chip_names[ahd->chip & AHD_CHIPID_MASK]);
6125 buf += len;
6126
6127 speed = "Ultra320 ";
6128 if ((ahd->features & AHD_WIDE) != 0) {
6129 type = "Wide ";
6130 } else {
6131 type = "Single ";
6132 }
6133 len = sprintf(buf, "%s%sChannel %c, SCSI Id=%d, ",
6134 speed, type, ahd->channel, ahd->our_id);
6135 buf += len;
6136
6137 sprintf(buf, "%s, %d SCBs", ahd->bus_description,
6138 ahd->scb_data.maxhscbs);
6139}
6140
6141static const char *channel_strings[] = {
6142 "Primary Low",
6143 "Primary High",
6144 "Secondary Low",
6145 "Secondary High"
6146};
6147
6148static const char *termstat_strings[] = {
6149 "Terminated Correctly",
6150 "Over Terminated",
6151 "Under Terminated",
6152 "Not Configured"
6153};
6154
6155/*
6156 * Start the board, ready for normal operation
6157 */
6158int
6159ahd_init(struct ahd_softc *ahd)
6160{
6161 uint8_t *base_vaddr;
6162 uint8_t *next_vaddr;
6163 dma_addr_t next_baddr;
6164 size_t driver_data_size;
6165 int i;
6166 int error;
6167 u_int warn_user;
6168 uint8_t current_sensing;
6169 uint8_t fstat;
6170
6171 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
6172
6173 ahd->stack_size = ahd_probe_stack_size(ahd);
6174 ahd->saved_stack = malloc(ahd->stack_size * sizeof(uint16_t),
6175 M_DEVBUF, M_NOWAIT);
6176 if (ahd->saved_stack == NULL)
6177 return (ENOMEM);
6178
6179 /*
6180 * Verify that the compiler hasn't over-agressively
6181 * padded important structures.
6182 */
6183 if (sizeof(struct hardware_scb) != 64)
6184 panic("Hardware SCB size is incorrect");
6185
6186#ifdef AHD_DEBUG
6187 if ((ahd_debug & AHD_DEBUG_SEQUENCER) != 0)
6188 ahd->flags |= AHD_SEQUENCER_DEBUG;
6189#endif
6190
6191 /*
6192 * Default to allowing initiator operations.
6193 */
6194 ahd->flags |= AHD_INITIATORROLE;
6195
6196 /*
6197 * Only allow target mode features if this unit has them enabled.
6198 */
6199 if ((AHD_TMODE_ENABLE & (0x1 << ahd->unit)) == 0)
6200 ahd->features &= ~AHD_TARGETMODE;
6201
6202#ifndef __linux__
6203 /* DMA tag for mapping buffers into device visible space. */
6204 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
6205 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
6206 /*lowaddr*/ahd->flags & AHD_39BIT_ADDRESSING
6207 ? (dma_addr_t)0x7FFFFFFFFFULL
6208 : BUS_SPACE_MAXADDR_32BIT,
6209 /*highaddr*/BUS_SPACE_MAXADDR,
6210 /*filter*/NULL, /*filterarg*/NULL,
6211 /*maxsize*/(AHD_NSEG - 1) * PAGE_SIZE,
6212 /*nsegments*/AHD_NSEG,
6213 /*maxsegsz*/AHD_MAXTRANSFER_SIZE,
6214 /*flags*/BUS_DMA_ALLOCNOW,
6215 &ahd->buffer_dmat) != 0) {
6216 return (ENOMEM);
6217 }
6218#endif
6219
6220 ahd->init_level++;
6221
6222 /*
6223 * DMA tag for our command fifos and other data in system memory
6224 * the card's sequencer must be able to access. For initiator
6225 * roles, we need to allocate space for the qoutfifo. When providing
6226 * for the target mode role, we must additionally provide space for
6227 * the incoming target command fifo.
6228 */
6229 driver_data_size = AHD_SCB_MAX * sizeof(uint16_t)
6230 + sizeof(struct hardware_scb);
6231 if ((ahd->features & AHD_TARGETMODE) != 0)
6232 driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd);
6233 if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0)
6234 driver_data_size += PKT_OVERRUN_BUFSIZE;
6235 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
6236 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
6237 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
6238 /*highaddr*/BUS_SPACE_MAXADDR,
6239 /*filter*/NULL, /*filterarg*/NULL,
6240 driver_data_size,
6241 /*nsegments*/1,
6242 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
6243 /*flags*/0, &ahd->shared_data_dmat) != 0) {
6244 return (ENOMEM);
6245 }
6246
6247 ahd->init_level++;
6248
6249 /* Allocation of driver data */
6250 if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat,
6251 (void **)&base_vaddr,
6252 BUS_DMA_NOWAIT, &ahd->shared_data_dmamap) != 0) {
6253 return (ENOMEM);
6254 }
6255
6256 ahd->init_level++;
6257
6258 /* And permanently map it in */
6259 ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,
6260 base_vaddr, driver_data_size, ahd_dmamap_cb,
6261 &ahd->shared_data_busaddr, /*flags*/0);
6262 ahd->qoutfifo = (uint16_t *)base_vaddr;
6263 next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE];
6264 next_baddr = ahd->shared_data_busaddr + AHD_QOUT_SIZE*sizeof(uint16_t);
6265 if ((ahd->features & AHD_TARGETMODE) != 0) {
6266 ahd->targetcmds = (struct target_cmd *)next_vaddr;
6267 next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
6268 next_baddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
6269 }
6270
6271 if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {
6272 ahd->overrun_buf = next_vaddr;
6273 next_vaddr += PKT_OVERRUN_BUFSIZE;
6274 next_baddr += PKT_OVERRUN_BUFSIZE;
6275 }
6276
6277 /*
6278 * We need one SCB to serve as the "next SCB". Since the
6279 * tag identifier in this SCB will never be used, there is
6280 * no point in using a valid HSCB tag from an SCB pulled from
6281 * the standard free pool. So, we allocate this "sentinel"
6282 * specially from the DMA safe memory chunk used for the QOUTFIFO.
6283 */
6284 ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr;
6285 ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr);
6286
6287 ahd->init_level++;
6288
6289 /* Allocate SCB data now that buffer_dmat is initialized */
6290 if (ahd_init_scbdata(ahd) != 0)
6291 return (ENOMEM);
6292
6293 if ((ahd->flags & AHD_INITIATORROLE) == 0)
6294 ahd->flags &= ~AHD_RESET_BUS_A;
6295
6296 /*
6297 * Before committing these settings to the chip, give
6298 * the OSM one last chance to modify our configuration.
6299 */
6300 ahd_platform_init(ahd);
6301
6302 /* Bring up the chip. */
6303 ahd_chip_init(ahd);
6304
6305 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
6306
6307 if ((ahd->flags & AHD_CURRENT_SENSING) == 0)
6308 goto init_done;
6309
6310 /*
6311 * Verify termination based on current draw and
6312 * warn user if the bus is over/under terminated.
6313 */
6314 error = ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL,
6315 CURSENSE_ENB);
6316 if (error != 0) {
6317 printf("%s: current sensing timeout 1\n", ahd_name(ahd));
6318 goto init_done;
6319 }
6320 for (i = 20, fstat = FLX_FSTAT_BUSY;
6321 (fstat & FLX_FSTAT_BUSY) != 0 && i; i--) {
6322 error = ahd_read_flexport(ahd, FLXADDR_FLEXSTAT, &fstat);
6323 if (error != 0) {
6324 printf("%s: current sensing timeout 2\n",
6325 ahd_name(ahd));
6326 goto init_done;
6327 }
6328 }
6329 if (i == 0) {
6330 printf("%s: Timedout during current-sensing test\n",
6331 ahd_name(ahd));
6332 goto init_done;
6333 }
6334
6335 /* Latch Current Sensing status. */
6336 error = ahd_read_flexport(ahd, FLXADDR_CURRENT_STAT, &current_sensing);
6337 if (error != 0) {
6338 printf("%s: current sensing timeout 3\n", ahd_name(ahd));
6339 goto init_done;
6340 }
6341
6342 /* Diable current sensing. */
6343 ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
6344
6345#ifdef AHD_DEBUG
6346 if ((ahd_debug & AHD_SHOW_TERMCTL) != 0) {
6347 printf("%s: current_sensing == 0x%x\n",
6348 ahd_name(ahd), current_sensing);
6349 }
6350#endif
6351 warn_user = 0;
6352 for (i = 0; i < 4; i++, current_sensing >>= FLX_CSTAT_SHIFT) {
6353 u_int term_stat;
6354
6355 term_stat = (current_sensing & FLX_CSTAT_MASK);
6356 switch (term_stat) {
6357 case FLX_CSTAT_OVER:
6358 case FLX_CSTAT_UNDER:
6359 warn_user++;
6360 case FLX_CSTAT_INVALID:
6361 case FLX_CSTAT_OKAY:
6362 if (warn_user == 0 && bootverbose == 0)
6363 break;
6364 printf("%s: %s Channel %s\n", ahd_name(ahd),
6365 channel_strings[i], termstat_strings[term_stat]);
6366 break;
6367 }
6368 }
6369 if (warn_user) {
6370 printf("%s: WARNING. Termination is not configured correctly.\n"
6371 "%s: WARNING. SCSI bus operations may FAIL.\n",
6372 ahd_name(ahd), ahd_name(ahd));
6373 }
6374init_done:
6375 ahd_restart(ahd);
6376 ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
6377 ahd_stat_timer, ahd);
6378 return (0);
6379}
6380
6381/*
6382 * (Re)initialize chip state after a chip reset.
6383 */
6384static void
6385ahd_chip_init(struct ahd_softc *ahd)
6386{
6387 uint32_t busaddr;
6388 u_int sxfrctl1;
6389 u_int scsiseq_template;
6390 u_int wait;
6391 u_int i;
6392 u_int target;
6393
6394 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6395 /*
6396 * Take the LED out of diagnostic mode
6397 */
6398 ahd_outb(ahd, SBLKCTL, ahd_inb(ahd, SBLKCTL) & ~(DIAGLEDEN|DIAGLEDON));
6399
6400 /*
6401 * Return HS_MAILBOX to its default value.
6402 */
6403 ahd->hs_mailbox = 0;
6404 ahd_outb(ahd, HS_MAILBOX, 0);
6405
6406 /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1. */
6407 ahd_outb(ahd, IOWNID, ahd->our_id);
6408 ahd_outb(ahd, TOWNID, ahd->our_id);
6409 sxfrctl1 = (ahd->flags & AHD_TERM_ENB_A) != 0 ? STPWEN : 0;
6410 sxfrctl1 |= (ahd->flags & AHD_SPCHK_ENB_A) != 0 ? ENSPCHK : 0;
6411 if ((ahd->bugs & AHD_LONG_SETIMO_BUG)
6412 && (ahd->seltime != STIMESEL_MIN)) {
6413 /*
6414 * The selection timer duration is twice as long
6415 * as it should be. Halve it by adding "1" to
6416 * the user specified setting.
6417 */
6418 sxfrctl1 |= ahd->seltime + STIMESEL_BUG_ADJ;
6419 } else {
6420 sxfrctl1 |= ahd->seltime;
6421 }
6422
6423 ahd_outb(ahd, SXFRCTL0, DFON);
6424 ahd_outb(ahd, SXFRCTL1, sxfrctl1|ahd->seltime|ENSTIMER|ACTNEGEN);
6425 ahd_outb(ahd, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
6426
6427 /*
6428 * Now that termination is set, wait for up
6429 * to 500ms for our transceivers to settle. If
6430 * the adapter does not have a cable attached,
6431 * the transceivers may never settle, so don't
6432 * complain if we fail here.
6433 */
6434 for (wait = 10000;
6435 (ahd_inb(ahd, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
6436 wait--)
6437 ahd_delay(100);
6438
6439 /* Clear any false bus resets due to the transceivers settling */
6440 ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
6441 ahd_outb(ahd, CLRINT, CLRSCSIINT);
6442
6443 /* Initialize mode specific S/G state. */
6444 for (i = 0; i < 2; i++) {
6445 ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
6446 ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
6447 ahd_outb(ahd, SG_STATE, 0);
6448 ahd_outb(ahd, CLRSEQINTSRC, 0xFF);
6449 ahd_outb(ahd, SEQIMODE,
6450 ENSAVEPTRS|ENCFG4DATA|ENCFG4ISTAT
6451 |ENCFG4TSTAT|ENCFG4ICMD|ENCFG4TCMD);
6452 }
6453
6454 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
6455 ahd_outb(ahd, DSCOMMAND0, ahd_inb(ahd, DSCOMMAND0)|MPARCKEN|CACHETHEN);
6456 ahd_outb(ahd, DFF_THRSH, RD_DFTHRSH_75|WR_DFTHRSH_75);
6457 ahd_outb(ahd, SIMODE0, ENIOERR|ENOVERRUN);
6458 ahd_outb(ahd, SIMODE3, ENNTRAMPERR|ENOSRAMPERR);
6459 if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
6460 ahd_outb(ahd, OPTIONMODE, AUTOACKEN|AUTO_MSGOUT_DE);
6461 } else {
6462 ahd_outb(ahd, OPTIONMODE, AUTOACKEN|BUSFREEREV|AUTO_MSGOUT_DE);
6463 }
6464 ahd_outb(ahd, SCSCHKN, CURRFIFODEF|WIDERESEN|SHVALIDSTDIS);
6465 if ((ahd->chip & AHD_BUS_MASK) == AHD_PCIX)
6466 /*
6467 * Do not issue a target abort when a split completion
6468 * error occurs. Let our PCIX interrupt handler deal
6469 * with it instead. H2A4 Razor #625
6470 */
6471 ahd_outb(ahd, PCIXCTL, ahd_inb(ahd, PCIXCTL) | SPLTSTADIS);
6472
6473 if ((ahd->bugs & AHD_LQOOVERRUN_BUG) != 0)
6474 ahd_outb(ahd, LQOSCSCTL, LQONOCHKOVER);
6475
6476 /*
6477 * Tweak IOCELL settings.
6478 */
6479 if ((ahd->flags & AHD_HP_BOARD) != 0) {
6480 for (i = 0; i < NUMDSPS; i++) {
6481 ahd_outb(ahd, DSPSELECT, i);
6482 ahd_outb(ahd, WRTBIASCTL, WRTBIASCTL_HP_DEFAULT);
6483 }
6484#ifdef AHD_DEBUG
6485 if ((ahd_debug & AHD_SHOW_MISC) != 0)
6486 printf("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd),
6487 WRTBIASCTL_HP_DEFAULT);
6488#endif
6489 }
6490 ahd_setup_iocell_workaround(ahd);
6491
6492 /*
6493 * Enable LQI Manager interrupts.
6494 */
6495 ahd_outb(ahd, LQIMODE1, ENLQIPHASE_LQ|ENLQIPHASE_NLQ|ENLIQABORT
6496 | ENLQICRCI_LQ|ENLQICRCI_NLQ|ENLQIBADLQI
6497 | ENLQIOVERI_LQ|ENLQIOVERI_NLQ);
6498 ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC);
6499 /*
6500 * An interrupt from LQOBUSFREE is made redundant by the
6501 * BUSFREE interrupt. We choose to have the sequencer catch
6502 * LQOPHCHGINPKT errors manually for the command phase at the
6503 * start of a packetized selection case.
6504 ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE|ENLQOPHACHGINPKT);
6505 */
6506 ahd_outb(ahd, LQOMODE1, 0);
6507
6508 /*
6509 * Setup sequencer interrupt handlers.
6510 */
6511 ahd_outw(ahd, INTVEC1_ADDR, ahd_resolve_seqaddr(ahd, LABEL_seq_isr));
6512 ahd_outw(ahd, INTVEC2_ADDR, ahd_resolve_seqaddr(ahd, LABEL_timer_isr));
6513
6514 /*
6515 * Setup SCB Offset registers.
6516 */
6517 if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
6518 ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb,
6519 pkt_long_lun));
6520 } else {
6521 ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, lun));
6522 }
6523 ahd_outb(ahd, CMDLENPTR, offsetof(struct hardware_scb, cdb_len));
6524 ahd_outb(ahd, ATTRPTR, offsetof(struct hardware_scb, task_attribute));
6525 ahd_outb(ahd, FLAGPTR, offsetof(struct hardware_scb, task_management));
6526 ahd_outb(ahd, CMDPTR, offsetof(struct hardware_scb,
6527 shared_data.idata.cdb));
6528 ahd_outb(ahd, QNEXTPTR,
6529 offsetof(struct hardware_scb, next_hscb_busaddr));
6530 ahd_outb(ahd, ABRTBITPTR, MK_MESSAGE_BIT_OFFSET);
6531 ahd_outb(ahd, ABRTBYTEPTR, offsetof(struct hardware_scb, control));
6532 if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
6533 ahd_outb(ahd, LUNLEN,
6534 sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1);
6535 } else {
6536 ahd_outb(ahd, LUNLEN, LUNLEN_SINGLE_LEVEL_LUN);
6537 }
6538 ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1);
6539 ahd_outb(ahd, MAXCMD, 0xFF);
6540 ahd_outb(ahd, SCBAUTOPTR,
6541 AUSCBPTR_EN | offsetof(struct hardware_scb, tag));
6542
6543 /* We haven't been enabled for target mode yet. */
6544 ahd_outb(ahd, MULTARGID, 0);
6545 ahd_outb(ahd, MULTARGID + 1, 0);
6546
6547 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6548 /* Initialize the negotiation table. */
6549 if ((ahd->features & AHD_NEW_IOCELL_OPTS) == 0) {
6550 /*
6551 * Clear the spare bytes in the neg table to avoid
6552 * spurious parity errors.
6553 */
6554 for (target = 0; target < AHD_NUM_TARGETS; target++) {
6555 ahd_outb(ahd, NEGOADDR, target);
6556 ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PER_DEV0);
6557 for (i = 0; i < AHD_NUM_PER_DEV_ANNEXCOLS; i++)
6558 ahd_outb(ahd, ANNEXDAT, 0);
6559 }
6560 }
6561 for (target = 0; target < AHD_NUM_TARGETS; target++) {
6562 struct ahd_devinfo devinfo;
6563 struct ahd_initiator_tinfo *tinfo;
6564 struct ahd_tmode_tstate *tstate;
6565
6566 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
6567 target, &tstate);
6568 ahd_compile_devinfo(&devinfo, ahd->our_id,
6569 target, CAM_LUN_WILDCARD,
6570 'A', ROLE_INITIATOR);
6571 ahd_update_neg_table(ahd, &devinfo, &tinfo->curr);
6572 }
6573
6574 ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR);
6575 ahd_outb(ahd, CLRINT, CLRSCSIINT);
6576
6577#ifdef NEEDS_MORE_TESTING
6578 /*
6579 * Always enable abort on incoming L_Qs if this feature is
6580 * supported. We use this to catch invalid SCB references.
6581 */
6582 if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0)
6583 ahd_outb(ahd, LQCTL1, ABORTPENDING);
6584 else
6585#endif
6586 ahd_outb(ahd, LQCTL1, 0);
6587
6588 /* All of our queues are empty */
6589 ahd->qoutfifonext = 0;
6590 ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID_LE;
6591 ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID >> 8);
6592 for (i = 0; i < AHD_QOUT_SIZE; i++)
6593 ahd->qoutfifo[i] = 0;
6594 ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD);
6595
6596 ahd->qinfifonext = 0;
6597 for (i = 0; i < AHD_QIN_SIZE; i++)
6598 ahd->qinfifo[i] = SCB_LIST_NULL;
6599
6600 if ((ahd->features & AHD_TARGETMODE) != 0) {
6601 /* All target command blocks start out invalid. */
6602 for (i = 0; i < AHD_TMODE_CMDS; i++)
6603 ahd->targetcmds[i].cmd_valid = 0;
6604 ahd_sync_tqinfifo(ahd, BUS_DMASYNC_PREREAD);
6605 ahd->tqinfifonext = 1;
6606 ahd_outb(ahd, KERNEL_TQINPOS, ahd->tqinfifonext - 1);
6607 ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
6608 }
6609
6610 /* Initialize Scratch Ram. */
6611 ahd_outb(ahd, SEQ_FLAGS, 0);
6612 ahd_outb(ahd, SEQ_FLAGS2, 0);
6613
6614 /* We don't have any waiting selections */
6615 ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL);
6616 ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL);
6617 for (i = 0; i < AHD_NUM_TARGETS; i++)
6618 ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL);
6619
6620 /*
6621 * Nobody is waiting to be DMAed into the QOUTFIFO.
6622 */
6623 ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
6624 ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL);
6625 ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);
6626
6627 /*
6628 * The Freeze Count is 0.
6629 */
6630 ahd_outw(ahd, QFREEZE_COUNT, 0);
6631
6632 /*
6633 * Tell the sequencer where it can find our arrays in memory.
6634 */
6635 busaddr = ahd->shared_data_busaddr;
6636 ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF);
6637 ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF);
6638 ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF);
6639 ahd_outb(ahd, SHARED_DATA_ADDR + 3, (busaddr >> 24) & 0xFF);
6640 ahd_outb(ahd, QOUTFIFO_NEXT_ADDR, busaddr & 0xFF);
6641 ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 1, (busaddr >> 8) & 0xFF);
6642 ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 2, (busaddr >> 16) & 0xFF);
6643 ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 3, (busaddr >> 24) & 0xFF);
6644
6645 /*
6646 * Setup the allowed SCSI Sequences based on operational mode.
6647 * If we are a target, we'll enable select in operations once
6648 * we've had a lun enabled.
6649 */
6650 scsiseq_template = ENAUTOATNP;
6651 if ((ahd->flags & AHD_INITIATORROLE) != 0)
6652 scsiseq_template |= ENRSELI;
6653 ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq_template);
6654
6655 /* There are no busy SCBs yet. */
6656 for (target = 0; target < AHD_NUM_TARGETS; target++) {
6657 int lun;
6658
6659 for (lun = 0; lun < AHD_NUM_LUNS_NONPKT; lun++)
6660 ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(target, 'A', lun));
6661 }
6662
6663 /*
6664 * Initialize the group code to command length table.
6665 * Vendor Unique codes are set to 0 so we only capture
6666 * the first byte of the cdb. These can be overridden
6667 * when target mode is enabled.
6668 */
6669 ahd_outb(ahd, CMDSIZE_TABLE, 5);
6670 ahd_outb(ahd, CMDSIZE_TABLE + 1, 9);
6671 ahd_outb(ahd, CMDSIZE_TABLE + 2, 9);
6672 ahd_outb(ahd, CMDSIZE_TABLE + 3, 0);
6673 ahd_outb(ahd, CMDSIZE_TABLE + 4, 15);
6674 ahd_outb(ahd, CMDSIZE_TABLE + 5, 11);
6675 ahd_outb(ahd, CMDSIZE_TABLE + 6, 0);
6676 ahd_outb(ahd, CMDSIZE_TABLE + 7, 0);
6677
6678 /* Tell the sequencer of our initial queue positions */
6679 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
6680 ahd_outb(ahd, QOFF_CTLSTA, SCB_QSIZE_512);
6681 ahd->qinfifonext = 0;
6682 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
6683 ahd_set_hescb_qoff(ahd, 0);
6684 ahd_set_snscb_qoff(ahd, 0);
6685 ahd_set_sescb_qoff(ahd, 0);
6686 ahd_set_sdscb_qoff(ahd, 0);
6687
6688 /*
6689 * Tell the sequencer which SCB will be the next one it receives.
6690 */
6691 busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
6692 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
6693 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
6694 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
6695 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
6696
6697 /*
6698 * Default to coalescing disabled.
6699 */
6700 ahd_outw(ahd, INT_COALESCING_CMDCOUNT, 0);
6701 ahd_outw(ahd, CMDS_PENDING, 0);
6702 ahd_update_coalescing_values(ahd, ahd->int_coalescing_timer,
6703 ahd->int_coalescing_maxcmds,
6704 ahd->int_coalescing_mincmds);
6705 ahd_enable_coalescing(ahd, FALSE);
6706
6707 ahd_loadseq(ahd);
6708 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6709}
6710
6711/*
6712 * Setup default device and controller settings.
6713 * This should only be called if our probe has
6714 * determined that no configuration data is available.
6715 */
6716int
6717ahd_default_config(struct ahd_softc *ahd)
6718{
6719 int targ;
6720
6721 ahd->our_id = 7;
6722
6723 /*
6724 * Allocate a tstate to house information for our
6725 * initiator presence on the bus as well as the user
6726 * data for any target mode initiator.
6727 */
6728 if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
6729 printf("%s: unable to allocate ahd_tmode_tstate. "
6730 "Failing attach\n", ahd_name(ahd));
6731 return (ENOMEM);
6732 }
6733
6734 for (targ = 0; targ < AHD_NUM_TARGETS; targ++) {
6735 struct ahd_devinfo devinfo;
6736 struct ahd_initiator_tinfo *tinfo;
6737 struct ahd_tmode_tstate *tstate;
6738 uint16_t target_mask;
6739
6740 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
6741 targ, &tstate);
6742 /*
6743 * We support SPC2 and SPI4.
6744 */
6745 tinfo->user.protocol_version = 4;
6746 tinfo->user.transport_version = 4;
6747
6748 target_mask = 0x01 << targ;
6749 ahd->user_discenable |= target_mask;
6750 tstate->discenable |= target_mask;
6751 ahd->user_tagenable |= target_mask;
6752#ifdef AHD_FORCE_160
6753 tinfo->user.period = AHD_SYNCRATE_DT;
6754#else
6755 tinfo->user.period = AHD_SYNCRATE_160;
6756#endif
6757 tinfo->user.offset = MAX_OFFSET;
6758 tinfo->user.ppr_options = MSG_EXT_PPR_RD_STRM
6759 | MSG_EXT_PPR_WR_FLOW
6760 | MSG_EXT_PPR_HOLD_MCS
6761 | MSG_EXT_PPR_IU_REQ
6762 | MSG_EXT_PPR_QAS_REQ
6763 | MSG_EXT_PPR_DT_REQ;
6764 if ((ahd->features & AHD_RTI) != 0)
6765 tinfo->user.ppr_options |= MSG_EXT_PPR_RTI;
6766
6767 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
6768
6769 /*
6770 * Start out Async/Narrow/Untagged and with
6771 * conservative protocol support.
6772 */
6773 tinfo->goal.protocol_version = 2;
6774 tinfo->goal.transport_version = 2;
6775 tinfo->curr.protocol_version = 2;
6776 tinfo->curr.transport_version = 2;
6777 ahd_compile_devinfo(&devinfo, ahd->our_id,
6778 targ, CAM_LUN_WILDCARD,
6779 'A', ROLE_INITIATOR);
6780 tstate->tagenable &= ~target_mask;
6781 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
6782 AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE);
6783 ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0,
6784 /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
6785 /*paused*/TRUE);
6786 }
6787 return (0);
6788}
6789
6790/*
6791 * Parse device configuration information.
6792 */
6793int
6794ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
6795{
6796 int targ;
6797 int max_targ;
6798
6799 max_targ = sc->max_targets & CFMAXTARG;
6800 ahd->our_id = sc->brtime_id & CFSCSIID;
6801
6802 /*
6803 * Allocate a tstate to house information for our
6804 * initiator presence on the bus as well as the user
6805 * data for any target mode initiator.
6806 */
6807 if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
6808 printf("%s: unable to allocate ahd_tmode_tstate. "
6809 "Failing attach\n", ahd_name(ahd));
6810 return (ENOMEM);
6811 }
6812
6813 for (targ = 0; targ < max_targ; targ++) {
6814 struct ahd_devinfo devinfo;
6815 struct ahd_initiator_tinfo *tinfo;
6816 struct ahd_transinfo *user_tinfo;
6817 struct ahd_tmode_tstate *tstate;
6818 uint16_t target_mask;
6819
6820 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
6821 targ, &tstate);
6822 user_tinfo = &tinfo->user;
6823
6824 /*
6825 * We support SPC2 and SPI4.
6826 */
6827 tinfo->user.protocol_version = 4;
6828 tinfo->user.transport_version = 4;
6829
6830 target_mask = 0x01 << targ;
6831 ahd->user_discenable &= ~target_mask;
6832 tstate->discenable &= ~target_mask;
6833 ahd->user_tagenable &= ~target_mask;
6834 if (sc->device_flags[targ] & CFDISC) {
6835 tstate->discenable |= target_mask;
6836 ahd->user_discenable |= target_mask;
6837 ahd->user_tagenable |= target_mask;
6838 } else {
6839 /*
6840 * Cannot be packetized without disconnection.
6841 */
6842 sc->device_flags[targ] &= ~CFPACKETIZED;
6843 }
6844
6845 user_tinfo->ppr_options = 0;
6846 user_tinfo->period = (sc->device_flags[targ] & CFXFER);
6847 if (user_tinfo->period < CFXFER_ASYNC) {
6848 if (user_tinfo->period <= AHD_PERIOD_10MHz)
6849 user_tinfo->ppr_options |= MSG_EXT_PPR_DT_REQ;
6850 user_tinfo->offset = MAX_OFFSET;
6851 } else {
6852 user_tinfo->offset = 0;
6853 user_tinfo->period = AHD_ASYNC_XFER_PERIOD;
6854 }
6855#ifdef AHD_FORCE_160
6856 if (user_tinfo->period <= AHD_SYNCRATE_160)
6857 user_tinfo->period = AHD_SYNCRATE_DT;
6858#endif
6859
6860 if ((sc->device_flags[targ] & CFPACKETIZED) != 0) {
6861 user_tinfo->ppr_options |= MSG_EXT_PPR_RD_STRM
6862 | MSG_EXT_PPR_WR_FLOW
6863 | MSG_EXT_PPR_HOLD_MCS
6864 | MSG_EXT_PPR_IU_REQ;
6865 if ((ahd->features & AHD_RTI) != 0)
6866 user_tinfo->ppr_options |= MSG_EXT_PPR_RTI;
6867 }
6868
6869 if ((sc->device_flags[targ] & CFQAS) != 0)
6870 user_tinfo->ppr_options |= MSG_EXT_PPR_QAS_REQ;
6871
6872 if ((sc->device_flags[targ] & CFWIDEB) != 0)
6873 user_tinfo->width = MSG_EXT_WDTR_BUS_16_BIT;
6874 else
6875 user_tinfo->width = MSG_EXT_WDTR_BUS_8_BIT;
6876#ifdef AHD_DEBUG
6877 if ((ahd_debug & AHD_SHOW_MISC) != 0)
6878 printf("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width,
6879 user_tinfo->period, user_tinfo->offset,
6880 user_tinfo->ppr_options);
6881#endif
6882 /*
6883 * Start out Async/Narrow/Untagged and with
6884 * conservative protocol support.
6885 */
6886 tstate->tagenable &= ~target_mask;
6887 tinfo->goal.protocol_version = 2;
6888 tinfo->goal.transport_version = 2;
6889 tinfo->curr.protocol_version = 2;
6890 tinfo->curr.transport_version = 2;
6891 ahd_compile_devinfo(&devinfo, ahd->our_id,
6892 targ, CAM_LUN_WILDCARD,
6893 'A', ROLE_INITIATOR);
6894 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
6895 AHD_TRANS_CUR|AHD_TRANS_GOAL, /*paused*/TRUE);
6896 ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0,
6897 /*ppr_options*/0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
6898 /*paused*/TRUE);
6899 }
6900
6901 ahd->flags &= ~AHD_SPCHK_ENB_A;
6902 if (sc->bios_control & CFSPARITY)
6903 ahd->flags |= AHD_SPCHK_ENB_A;
6904
6905 ahd->flags &= ~AHD_RESET_BUS_A;
6906 if (sc->bios_control & CFRESETB)
6907 ahd->flags |= AHD_RESET_BUS_A;
6908
6909 ahd->flags &= ~AHD_EXTENDED_TRANS_A;
6910 if (sc->bios_control & CFEXTEND)
6911 ahd->flags |= AHD_EXTENDED_TRANS_A;
6912
6913 ahd->flags &= ~AHD_BIOS_ENABLED;
6914 if ((sc->bios_control & CFBIOSSTATE) == CFBS_ENABLED)
6915 ahd->flags |= AHD_BIOS_ENABLED;
6916
6917 ahd->flags &= ~AHD_STPWLEVEL_A;
6918 if ((sc->adapter_control & CFSTPWLEVEL) != 0)
6919 ahd->flags |= AHD_STPWLEVEL_A;
6920
6921 return (0);
6922}
6923
6924/*
6925 * Parse device configuration information.
6926 */
6927int
6928ahd_parse_vpddata(struct ahd_softc *ahd, struct vpd_config *vpd)
6929{
6930 int error;
6931
6932 error = ahd_verify_vpd_cksum(vpd);
6933 if (error == 0)
6934 return (EINVAL);
6935 if ((vpd->bios_flags & VPDBOOTHOST) != 0)
6936 ahd->flags |= AHD_BOOT_CHANNEL;
6937 return (0);
6938}
6939
6940void
6941ahd_intr_enable(struct ahd_softc *ahd, int enable)
6942{
6943 u_int hcntrl;
6944
6945 hcntrl = ahd_inb(ahd, HCNTRL);
6946 hcntrl &= ~INTEN;
6947 ahd->pause &= ~INTEN;
6948 ahd->unpause &= ~INTEN;
6949 if (enable) {
6950 hcntrl |= INTEN;
6951 ahd->pause |= INTEN;
6952 ahd->unpause |= INTEN;
6953 }
6954 ahd_outb(ahd, HCNTRL, hcntrl);
6955}
6956
6957void
6958ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
6959 u_int mincmds)
6960{
6961 if (timer > AHD_TIMER_MAX_US)
6962 timer = AHD_TIMER_MAX_US;
6963 ahd->int_coalescing_timer = timer;
6964
6965 if (maxcmds > AHD_INT_COALESCING_MAXCMDS_MAX)
6966 maxcmds = AHD_INT_COALESCING_MAXCMDS_MAX;
6967 if (mincmds > AHD_INT_COALESCING_MINCMDS_MAX)
6968 mincmds = AHD_INT_COALESCING_MINCMDS_MAX;
6969 ahd->int_coalescing_maxcmds = maxcmds;
6970 ahd_outw(ahd, INT_COALESCING_TIMER, timer / AHD_TIMER_US_PER_TICK);
6971 ahd_outb(ahd, INT_COALESCING_MAXCMDS, -maxcmds);
6972 ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds);
6973}
6974
6975void
6976ahd_enable_coalescing(struct ahd_softc *ahd, int enable)
6977{
6978
6979 ahd->hs_mailbox &= ~ENINT_COALESCE;
6980 if (enable)
6981 ahd->hs_mailbox |= ENINT_COALESCE;
6982 ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox);
6983 ahd_flush_device_writes(ahd);
6984 ahd_run_qoutfifo(ahd);
6985}
6986
6987/*
6988 * Ensure that the card is paused in a location
6989 * outside of all critical sections and that all
6990 * pending work is completed prior to returning.
6991 * This routine should only be called from outside
6992 * an interrupt context.
6993 */
6994void
6995ahd_pause_and_flushwork(struct ahd_softc *ahd)
6996{
6997 u_int intstat;
6998 u_int maxloops;
6999 u_int qfreeze_cnt;
7000
7001 maxloops = 1000;
7002 ahd->flags |= AHD_ALL_INTERRUPTS;
7003 ahd_pause(ahd);
7004 /*
7005 * Increment the QFreeze Count so that the sequencer
7006 * will not start new selections. We do this only
7007 * until we are safely paused without further selections
7008 * pending.
7009 */
7010 ahd_outw(ahd, QFREEZE_COUNT, ahd_inw(ahd, QFREEZE_COUNT) + 1);
7011 ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN);
7012 do {
7013 struct scb *waiting_scb;
7014
7015 ahd_unpause(ahd);
7016 ahd_intr(ahd);
7017 ahd_pause(ahd);
7018 ahd_clear_critical_section(ahd);
7019 intstat = ahd_inb(ahd, INTSTAT);
7020 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7021 if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0)
7022 ahd_outb(ahd, SCSISEQ0,
7023 ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
7024 /*
7025 * In the non-packetized case, the sequencer (for Rev A),
7026 * relies on ENSELO remaining set after SELDO. The hardware
7027 * auto-clears ENSELO in the packetized case.
7028 */
7029 waiting_scb = ahd_lookup_scb(ahd,
7030 ahd_inw(ahd, WAITING_TID_HEAD));
7031 if (waiting_scb != NULL
7032 && (waiting_scb->flags & SCB_PACKETIZED) == 0
7033 && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0)
7034 ahd_outb(ahd, SCSISEQ0,
7035 ahd_inb(ahd, SCSISEQ0) | ENSELO);
7036 } while (--maxloops
7037 && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0)
7038 && ((intstat & INT_PEND) != 0
7039 || (ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
7040 || (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0));
7041
7042 if (maxloops == 0) {
7043 printf("Infinite interrupt loop, INTSTAT = %x",
7044 ahd_inb(ahd, INTSTAT));
7045 }
7046 qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);
7047 if (qfreeze_cnt == 0) {
7048 printf("%s: ahd_pause_and_flushwork with 0 qfreeze count!\n",
7049 ahd_name(ahd));
7050 } else {
7051 qfreeze_cnt--;
7052 }
7053 ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt);
7054 if (qfreeze_cnt == 0)
7055 ahd_outb(ahd, SEQ_FLAGS2,
7056 ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);
7057
7058 ahd_flush_qoutfifo(ahd);
7059
7060 ahd_platform_flushwork(ahd);
7061 ahd->flags &= ~AHD_ALL_INTERRUPTS;
7062}
7063
7064int
7065ahd_suspend(struct ahd_softc *ahd)
7066{
7067
7068 ahd_pause_and_flushwork(ahd);
7069
7070 if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
7071 ahd_unpause(ahd);
7072 return (EBUSY);
7073 }
7074 ahd_shutdown(ahd);
7075 return (0);
7076}
7077
7078int
7079ahd_resume(struct ahd_softc *ahd)
7080{
7081
7082 ahd_reset(ahd, /*reinit*/TRUE);
7083 ahd_intr_enable(ahd, TRUE);
7084 ahd_restart(ahd);
7085 return (0);
7086}
7087
7088/************************** Busy Target Table *********************************/
7089/*
7090 * Set SCBPTR to the SCB that contains the busy
7091 * table entry for TCL. Return the offset into
7092 * the SCB that contains the entry for TCL.
7093 * saved_scbid is dereferenced and set to the
7094 * scbid that should be restored once manipualtion
7095 * of the TCL entry is complete.
7096 */
7097static __inline u_int
7098ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
7099{
7100 /*
7101 * Index to the SCB that contains the busy entry.
7102 */
7103 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7104 *saved_scbid = ahd_get_scbptr(ahd);
7105 ahd_set_scbptr(ahd, TCL_LUN(tcl)
7106 | ((TCL_TARGET_OFFSET(tcl) & 0xC) << 4));
7107
7108 /*
7109 * And now calculate the SCB offset to the entry.
7110 * Each entry is 2 bytes wide, hence the
7111 * multiplication by 2.
7112 */
7113 return (((TCL_TARGET_OFFSET(tcl) & 0x3) << 1) + SCB_DISCONNECTED_LISTS);
7114}
7115
7116/*
7117 * Return the untagged transaction id for a given target/channel lun.
7118 */
7119u_int
7120ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
7121{
7122 u_int scbid;
7123 u_int scb_offset;
7124 u_int saved_scbptr;
7125
7126 scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
7127 scbid = ahd_inw_scbram(ahd, scb_offset);
7128 ahd_set_scbptr(ahd, saved_scbptr);
7129 return (scbid);
7130}
7131
7132void
7133ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid)
7134{
7135 u_int scb_offset;
7136 u_int saved_scbptr;
7137
7138 scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
7139 ahd_outw(ahd, scb_offset, scbid);
7140 ahd_set_scbptr(ahd, saved_scbptr);
7141}
7142
7143/************************** SCB and SCB queue management **********************/
7144int
7145ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target,
7146 char channel, int lun, u_int tag, role_t role)
7147{
7148 int targ = SCB_GET_TARGET(ahd, scb);
7149 char chan = SCB_GET_CHANNEL(ahd, scb);
7150 int slun = SCB_GET_LUN(scb);
7151 int match;
7152
7153 match = ((chan == channel) || (channel == ALL_CHANNELS));
7154 if (match != 0)
7155 match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
7156 if (match != 0)
7157 match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
7158 if (match != 0) {
7159#ifdef AHD_TARGET_MODE
7160 int group;
7161
7162 group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
7163 if (role == ROLE_INITIATOR) {
7164 match = (group != XPT_FC_GROUP_TMODE)
7165 && ((tag == SCB_GET_TAG(scb))
7166 || (tag == SCB_LIST_NULL));
7167 } else if (role == ROLE_TARGET) {
7168 match = (group == XPT_FC_GROUP_TMODE)
7169 && ((tag == scb->io_ctx->csio.tag_id)
7170 || (tag == SCB_LIST_NULL));
7171 }
7172#else /* !AHD_TARGET_MODE */
7173 match = ((tag == SCB_GET_TAG(scb)) || (tag == SCB_LIST_NULL));
7174#endif /* AHD_TARGET_MODE */
7175 }
7176
7177 return match;
7178}
7179
7180void
7181ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
7182{
7183 int target;
7184 char channel;
7185 int lun;
7186
7187 target = SCB_GET_TARGET(ahd, scb);
7188 lun = SCB_GET_LUN(scb);
7189 channel = SCB_GET_CHANNEL(ahd, scb);
7190
7191 ahd_search_qinfifo(ahd, target, channel, lun,
7192 /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
7193 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
7194
7195 ahd_platform_freeze_devq(ahd, scb);
7196}
7197
7198void
7199ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb)
7200{
7201 struct scb *prev_scb;
7202 ahd_mode_state saved_modes;
7203
7204 saved_modes = ahd_save_modes(ahd);
7205 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7206 prev_scb = NULL;
7207 if (ahd_qinfifo_count(ahd) != 0) {
7208 u_int prev_tag;
7209 u_int prev_pos;
7210
7211 prev_pos = AHD_QIN_WRAP(ahd->qinfifonext - 1);
7212 prev_tag = ahd->qinfifo[prev_pos];
7213 prev_scb = ahd_lookup_scb(ahd, prev_tag);
7214 }
7215 ahd_qinfifo_requeue(ahd, prev_scb, scb);
7216 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
7217 ahd_restore_modes(ahd, saved_modes);
7218}
7219
7220static void
7221ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb,
7222 struct scb *scb)
7223{
7224 if (prev_scb == NULL) {
7225 uint32_t busaddr;
7226
7227 busaddr = ahd_le32toh(scb->hscb->hscb_busaddr);
7228 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
7229 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
7230 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
7231 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
7232 } else {
7233 prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr;
7234 ahd_sync_scb(ahd, prev_scb,
7235 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
7236 }
7237 ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb);
7238 ahd->qinfifonext++;
7239 scb->hscb->next_hscb_busaddr = ahd->next_queued_hscb->hscb_busaddr;
7240 ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
7241}
7242
7243static int
7244ahd_qinfifo_count(struct ahd_softc *ahd)
7245{
7246 u_int qinpos;
7247 u_int wrap_qinpos;
7248 u_int wrap_qinfifonext;
7249
7250 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
7251 qinpos = ahd_get_snscb_qoff(ahd);
7252 wrap_qinpos = AHD_QIN_WRAP(qinpos);
7253 wrap_qinfifonext = AHD_QIN_WRAP(ahd->qinfifonext);
7254 if (wrap_qinfifonext >= wrap_qinpos)
7255 return (wrap_qinfifonext - wrap_qinpos);
7256 else
7257 return (wrap_qinfifonext
7258 + NUM_ELEMENTS(ahd->qinfifo) - wrap_qinpos);
7259}
7260
7261void
7262ahd_reset_cmds_pending(struct ahd_softc *ahd)
7263{
7264 struct scb *scb;
7265 ahd_mode_state saved_modes;
7266 u_int pending_cmds;
7267
7268 saved_modes = ahd_save_modes(ahd);
7269 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7270
7271 /*
7272 * Don't count any commands as outstanding that the
7273 * sequencer has already marked for completion.
7274 */
7275 ahd_flush_qoutfifo(ahd);
7276
7277 pending_cmds = 0;
7278 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
7279 pending_cmds++;
7280 }
7281 ahd_outw(ahd, CMDS_PENDING, pending_cmds - ahd_qinfifo_count(ahd));
7282 ahd_restore_modes(ahd, saved_modes);
7283 ahd->flags &= ~AHD_UPDATE_PEND_CMDS;
7284}
7285
7286int
7287ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
7288 int lun, u_int tag, role_t role, uint32_t status,
7289 ahd_search_action action)
7290{
7291 struct scb *scb;
7292 struct scb *prev_scb;
7293 ahd_mode_state saved_modes;
7294 u_int qinstart;
7295 u_int qinpos;
7296 u_int qintail;
7297 u_int tid_next;
7298 u_int tid_prev;
7299 u_int scbid;
7300 u_int savedscbptr;
7301 uint32_t busaddr;
7302 int found;
7303 int targets;
7304
7305 /* Must be in CCHAN mode */
7306 saved_modes = ahd_save_modes(ahd);
7307 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7308
7309 /*
7310 * Halt any pending SCB DMA. The sequencer will reinitiate
7311 * this dma if the qinfifo is not empty once we unpause.
7312 */
7313 if ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN|CCSCBDIR))
7314 == (CCARREN|CCSCBEN|CCSCBDIR)) {
7315 ahd_outb(ahd, CCSCBCTL,
7316 ahd_inb(ahd, CCSCBCTL) & ~(CCARREN|CCSCBEN));
7317 while ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0)
7318 ;
7319 }
7320 /* Determine sequencer's position in the qinfifo. */
7321 qintail = AHD_QIN_WRAP(ahd->qinfifonext);
7322 qinstart = ahd_get_snscb_qoff(ahd);
7323 qinpos = AHD_QIN_WRAP(qinstart);
7324 found = 0;
7325 prev_scb = NULL;
7326
7327 if (action == SEARCH_PRINT) {
7328 printf("qinstart = %d qinfifonext = %d\nQINFIFO:",
7329 qinstart, ahd->qinfifonext);
7330 }
7331
7332 /*
7333 * Start with an empty queue. Entries that are not chosen
7334 * for removal will be re-added to the queue as we go.
7335 */
7336 ahd->qinfifonext = qinstart;
7337 busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
7338 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
7339 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
7340 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
7341 ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
7342
7343 while (qinpos != qintail) {
7344 scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]);
7345 if (scb == NULL) {
7346 printf("qinpos = %d, SCB index = %d\n",
7347 qinpos, ahd->qinfifo[qinpos]);
7348 panic("Loop 1\n");
7349 }
7350
7351 if (ahd_match_scb(ahd, scb, target, channel, lun, tag, role)) {
7352 /*
7353 * We found an scb that needs to be acted on.
7354 */
7355 found++;
7356 switch (action) {
7357 case SEARCH_COMPLETE:
7358 {
7359 cam_status ostat;
7360 cam_status cstat;
7361
7362 ostat = ahd_get_transaction_status(scb);
7363 if (ostat == CAM_REQ_INPROG)
7364 ahd_set_transaction_status(scb,
7365 status);
7366 cstat = ahd_get_transaction_status(scb);
7367 if (cstat != CAM_REQ_CMP)
7368 ahd_freeze_scb(scb);
7369 if ((scb->flags & SCB_ACTIVE) == 0)
7370 printf("Inactive SCB in qinfifo\n");
7371 ahd_done(ahd, scb);
7372
7373 /* FALLTHROUGH */
7374 }
7375 case SEARCH_REMOVE:
7376 break;
7377 case SEARCH_PRINT:
7378 printf(" 0x%x", ahd->qinfifo[qinpos]);
7379 /* FALLTHROUGH */
7380 case SEARCH_COUNT:
7381 ahd_qinfifo_requeue(ahd, prev_scb, scb);
7382 prev_scb = scb;
7383 break;
7384 }
7385 } else {
7386 ahd_qinfifo_requeue(ahd, prev_scb, scb);
7387 prev_scb = scb;
7388 }
7389 qinpos = AHD_QIN_WRAP(qinpos+1);
7390 }
7391
7392 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
7393
7394 if (action == SEARCH_PRINT)
7395 printf("\nWAITING_TID_QUEUES:\n");
7396
7397 /*
7398 * Search waiting for selection lists. We traverse the
7399 * list of "their ids" waiting for selection and, if
7400 * appropriate, traverse the SCBs of each "their id"
7401 * looking for matches.
7402 */
7403 savedscbptr = ahd_get_scbptr(ahd);
7404 tid_next = ahd_inw(ahd, WAITING_TID_HEAD);
7405 tid_prev = SCB_LIST_NULL;
7406 targets = 0;
7407 for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) {
7408 u_int tid_head;
7409
7410 /*
7411 * We limit based on the number of SCBs since
7412 * MK_MESSAGE SCBs are not in the per-tid lists.
7413 */
7414 targets++;
7415 if (targets > AHD_SCB_MAX) {
7416 panic("TID LIST LOOP");
7417 }
7418 if (scbid >= ahd->scb_data.numscbs) {
7419 printf("%s: Waiting TID List inconsistency. "
7420 "SCB index == 0x%x, yet numscbs == 0x%x.",
7421 ahd_name(ahd), scbid, ahd->scb_data.numscbs);
7422 ahd_dump_card_state(ahd);
7423 panic("for safety");
7424 }
7425 scb = ahd_lookup_scb(ahd, scbid);
7426 if (scb == NULL) {
7427 printf("%s: SCB = 0x%x Not Active!\n",
7428 ahd_name(ahd), scbid);
7429 panic("Waiting TID List traversal\n");
7430 }
7431 ahd_set_scbptr(ahd, scbid);
7432 tid_next = ahd_inw_scbram(ahd, SCB_NEXT2);
7433 if (ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD,
7434 SCB_LIST_NULL, ROLE_UNKNOWN) == 0) {
7435 tid_prev = scbid;
7436 continue;
7437 }
7438
7439 /*
7440 * We found a list of scbs that needs to be searched.
7441 */
7442 if (action == SEARCH_PRINT)
7443 printf(" %d ( ", SCB_GET_TARGET(ahd, scb));
7444 tid_head = scbid;
7445 found += ahd_search_scb_list(ahd, target, channel,
7446 lun, tag, role, status,
7447 action, &tid_head,
7448 SCB_GET_TARGET(ahd, scb));
7449 if (tid_head != scbid)
7450 ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next);
7451 if (!SCBID_IS_NULL(tid_head))
7452 tid_prev = tid_head;
7453 if (action == SEARCH_PRINT)
7454 printf(")\n");
7455 }
7456 ahd_set_scbptr(ahd, savedscbptr);
7457 ahd_restore_modes(ahd, saved_modes);
7458 return (found);
7459}
7460
7461static int
7462ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
7463 int lun, u_int tag, role_t role, uint32_t status,
7464 ahd_search_action action, u_int *list_head, u_int tid)
7465{
7466 struct scb *scb;
7467 u_int scbid;
7468 u_int next;
7469 u_int prev;
7470 int found;
7471
7472 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
7473 found = 0;
7474 prev = SCB_LIST_NULL;
7475 next = *list_head;
7476 for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) {
7477 if (scbid >= ahd->scb_data.numscbs) {
7478 printf("%s:SCB List inconsistency. "
7479 "SCB == 0x%x, yet numscbs == 0x%x.",
7480 ahd_name(ahd), scbid, ahd->scb_data.numscbs);
7481 ahd_dump_card_state(ahd);
7482 panic("for safety");
7483 }
7484 scb = ahd_lookup_scb(ahd, scbid);
7485 if (scb == NULL) {
7486 printf("%s: SCB = %d Not Active!\n",
7487 ahd_name(ahd), scbid);
7488 panic("Waiting List traversal\n");
7489 }
7490 ahd_set_scbptr(ahd, scbid);
7491 next = ahd_inw_scbram(ahd, SCB_NEXT);
7492 if (ahd_match_scb(ahd, scb, target, channel,
7493 lun, SCB_LIST_NULL, role) == 0) {
7494 prev = scbid;
7495 continue;
7496 }
7497 found++;
7498 switch (action) {
7499 case SEARCH_COMPLETE:
7500 {
7501 cam_status ostat;
7502 cam_status cstat;
7503
7504 ostat = ahd_get_transaction_status(scb);
7505 if (ostat == CAM_REQ_INPROG)
7506 ahd_set_transaction_status(scb, status);
7507 cstat = ahd_get_transaction_status(scb);
7508 if (cstat != CAM_REQ_CMP)
7509 ahd_freeze_scb(scb);
7510 if ((scb->flags & SCB_ACTIVE) == 0)
7511 printf("Inactive SCB in Waiting List\n");
7512 ahd_done(ahd, scb);
7513 /* FALLTHROUGH */
7514 }
7515 case SEARCH_REMOVE:
7516 ahd_rem_wscb(ahd, scbid, prev, next, tid);
7517 if (prev == SCB_LIST_NULL)
7518 *list_head = next;
7519 break;
7520 case SEARCH_PRINT:
7521 printf("0x%x ", scbid);
7522 case SEARCH_COUNT:
7523 prev = scbid;
7524 break;
7525 }
7526 if (found > AHD_SCB_MAX)
7527 panic("SCB LIST LOOP");
7528 }
7529 if (action == SEARCH_COMPLETE
7530 || action == SEARCH_REMOVE)
7531 ahd_outw(ahd, CMDS_PENDING, ahd_inw(ahd, CMDS_PENDING) - found);
7532 return (found);
7533}
7534
7535static void
7536ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev,
7537 u_int tid_cur, u_int tid_next)
7538{
7539 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
7540
7541 if (SCBID_IS_NULL(tid_cur)) {
7542
7543 /* Bypass current TID list */
7544 if (SCBID_IS_NULL(tid_prev)) {
7545 ahd_outw(ahd, WAITING_TID_HEAD, tid_next);
7546 } else {
7547 ahd_set_scbptr(ahd, tid_prev);
7548 ahd_outw(ahd, SCB_NEXT2, tid_next);
7549 }
7550 if (SCBID_IS_NULL(tid_next))
7551 ahd_outw(ahd, WAITING_TID_TAIL, tid_prev);
7552 } else {
7553
7554 /* Stitch through tid_cur */
7555 if (SCBID_IS_NULL(tid_prev)) {
7556 ahd_outw(ahd, WAITING_TID_HEAD, tid_cur);
7557 } else {
7558 ahd_set_scbptr(ahd, tid_prev);
7559 ahd_outw(ahd, SCB_NEXT2, tid_cur);
7560 }
7561 ahd_set_scbptr(ahd, tid_cur);
7562 ahd_outw(ahd, SCB_NEXT2, tid_next);
7563
7564 if (SCBID_IS_NULL(tid_next))
7565 ahd_outw(ahd, WAITING_TID_TAIL, tid_cur);
7566 }
7567}
7568
7569/*
7570 * Manipulate the waiting for selection list and return the
7571 * scb that follows the one that we remove.
7572 */
7573static u_int
7574ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
7575 u_int prev, u_int next, u_int tid)
7576{
7577 u_int tail_offset;
7578
7579 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
7580 if (!SCBID_IS_NULL(prev)) {
7581 ahd_set_scbptr(ahd, prev);
7582 ahd_outw(ahd, SCB_NEXT, next);
7583 }
7584
7585 /*
7586 * SCBs that had MK_MESSAGE set in them will not
7587 * be queued to the per-target lists, so don't
7588 * blindly clear the tail pointer.
7589 */
7590 tail_offset = WAITING_SCB_TAILS + (2 * tid);
7591 if (SCBID_IS_NULL(next)
7592 && ahd_inw(ahd, tail_offset) == scbid)
7593 ahd_outw(ahd, tail_offset, prev);
7594 ahd_add_scb_to_free_list(ahd, scbid);
7595 return (next);
7596}
7597
7598/*
7599 * Add the SCB as selected by SCBPTR onto the on chip list of
7600 * free hardware SCBs. This list is empty/unused if we are not
7601 * performing SCB paging.
7602 */
7603static void
7604ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid)
7605{
7606/* XXX Need some other mechanism to designate "free". */
7607 /*
7608 * Invalidate the tag so that our abort
7609 * routines don't think it's active.
7610 ahd_outb(ahd, SCB_TAG, SCB_LIST_NULL);
7611 */
7612}
7613
7614/******************************** Error Handling ******************************/
7615/*
7616 * Abort all SCBs that match the given description (target/channel/lun/tag),
7617 * setting their status to the passed in status if the status has not already
7618 * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer
7619 * is paused before it is called.
7620 */
7621int
7622ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
7623 int lun, u_int tag, role_t role, uint32_t status)
7624{
7625 struct scb *scbp;
7626 struct scb *scbp_next;
7627 u_int i, j;
7628 u_int maxtarget;
7629 u_int minlun;
7630 u_int maxlun;
7631 int found;
7632 ahd_mode_state saved_modes;
7633
7634 /* restore this when we're done */
7635 saved_modes = ahd_save_modes(ahd);
7636 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7637
7638 found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL,
7639 role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
7640
7641 /*
7642 * Clean out the busy target table for any untagged commands.
7643 */
7644 i = 0;
7645 maxtarget = 16;
7646 if (target != CAM_TARGET_WILDCARD) {
7647 i = target;
7648 if (channel == 'B')
7649 i += 8;
7650 maxtarget = i + 1;
7651 }
7652
7653 if (lun == CAM_LUN_WILDCARD) {
7654 minlun = 0;
7655 maxlun = AHD_NUM_LUNS_NONPKT;
7656 } else if (lun >= AHD_NUM_LUNS_NONPKT) {
7657 minlun = maxlun = 0;
7658 } else {
7659 minlun = lun;
7660 maxlun = lun + 1;
7661 }
7662
7663 if (role != ROLE_TARGET) {
7664 for (;i < maxtarget; i++) {
7665 for (j = minlun;j < maxlun; j++) {
7666 u_int scbid;
7667 u_int tcl;
7668
7669 tcl = BUILD_TCL_RAW(i, 'A', j);
7670 scbid = ahd_find_busy_tcl(ahd, tcl);
7671 scbp = ahd_lookup_scb(ahd, scbid);
7672 if (scbp == NULL
7673 || ahd_match_scb(ahd, scbp, target, channel,
7674 lun, tag, role) == 0)
7675 continue;
7676 ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(i, 'A', j));
7677 }
7678 }
7679 }
7680
7681 /*
7682 * Don't abort commands that have already completed,
7683 * but haven't quite made it up to the host yet.
7684 */
7685 ahd_flush_qoutfifo(ahd);
7686
7687 /*
7688 * Go through the pending CCB list and look for
7689 * commands for this target that are still active.
7690 * These are other tagged commands that were
7691 * disconnected when the reset occurred.
7692 */
7693 scbp_next = LIST_FIRST(&ahd->pending_scbs);
7694 while (scbp_next != NULL) {
7695 scbp = scbp_next;
7696 scbp_next = LIST_NEXT(scbp, pending_links);
7697 if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) {
7698 cam_status ostat;
7699
7700 ostat = ahd_get_transaction_status(scbp);
7701 if (ostat == CAM_REQ_INPROG)
7702 ahd_set_transaction_status(scbp, status);
7703 if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP)
7704 ahd_freeze_scb(scbp);
7705 if ((scbp->flags & SCB_ACTIVE) == 0)
7706 printf("Inactive SCB on pending list\n");
7707 ahd_done(ahd, scbp);
7708 found++;
7709 }
7710 }
7711 ahd_restore_modes(ahd, saved_modes);
7712 ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status);
7713 ahd->flags |= AHD_UPDATE_PEND_CMDS;
7714 return found;
7715}
7716
7717static void
7718ahd_reset_current_bus(struct ahd_softc *ahd)
7719{
7720 uint8_t scsiseq;
7721
7722 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7723 ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST);
7724 scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO);
7725 ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO);
7726 ahd_flush_device_writes(ahd);
7727 ahd_delay(AHD_BUSRESET_DELAY);
7728 /* Turn off the bus reset */
7729 ahd_outb(ahd, SCSISEQ0, scsiseq);
7730 ahd_flush_device_writes(ahd);
7731 ahd_delay(AHD_BUSRESET_DELAY);
7732 if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) {
7733 /*
7734 * 2A Razor #474
7735 * Certain chip state is not cleared for
7736 * SCSI bus resets that we initiate, so
7737 * we must reset the chip.
7738 */
7739 ahd_reset(ahd, /*reinit*/TRUE);
7740 ahd_intr_enable(ahd, /*enable*/TRUE);
7741 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7742 }
7743
7744 ahd_clear_intstat(ahd);
7745}
7746
7747int
7748ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
7749{
7750 struct ahd_devinfo devinfo;
7751 u_int initiator;
7752 u_int target;
7753 u_int max_scsiid;
7754 int found;
7755 u_int fifo;
7756 u_int next_fifo;
7757
7758 ahd->pending_device = NULL;
7759
7760 ahd_compile_devinfo(&devinfo,
7761 CAM_TARGET_WILDCARD,
7762 CAM_TARGET_WILDCARD,
7763 CAM_LUN_WILDCARD,
7764 channel, ROLE_UNKNOWN);
7765 ahd_pause(ahd);
7766
7767 /* Make sure the sequencer is in a safe location. */
7768 ahd_clear_critical_section(ahd);
7769
7770#ifdef AHD_TARGET_MODE
7771 if ((ahd->flags & AHD_TARGETROLE) != 0) {
7772 ahd_run_tqinfifo(ahd, /*paused*/TRUE);
7773 }
7774#endif
7775 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7776
7777 /*
7778 * Disable selections so no automatic hardware
7779 * functions will modify chip state.
7780 */
7781 ahd_outb(ahd, SCSISEQ0, 0);
7782 ahd_outb(ahd, SCSISEQ1, 0);
7783
7784 /*
7785 * Safely shut down our DMA engines. Always start with
7786 * the FIFO that is not currently active (if any are
7787 * actively connected).
7788 */
7789 next_fifo = fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
7790 if (next_fifo > CURRFIFO_1)
7791 /* If disconneced, arbitrarily start with FIFO1. */
7792 next_fifo = fifo = 0;
7793 do {
7794 next_fifo ^= CURRFIFO_1;
7795 ahd_set_modes(ahd, next_fifo, next_fifo);
7796 ahd_outb(ahd, DFCNTRL,
7797 ahd_inb(ahd, DFCNTRL) & ~(SCSIEN|HDMAEN));
7798 while ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0)
7799 ahd_delay(10);
7800 /*
7801 * Set CURRFIFO to the now inactive channel.
7802 */
7803 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7804 ahd_outb(ahd, DFFSTAT, next_fifo);
7805 } while (next_fifo != fifo);
7806
7807 /*
7808 * Reset the bus if we are initiating this reset
7809 */
7810 ahd_clear_msg_state(ahd);
7811 ahd_outb(ahd, SIMODE1,
7812 ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE));
7813
7814 if (initiate_reset)
7815 ahd_reset_current_bus(ahd);
7816
7817 ahd_clear_intstat(ahd);
7818
7819 /*
7820 * Clean up all the state information for the
7821 * pending transactions on this bus.
7822 */
7823 found = ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, channel,
7824 CAM_LUN_WILDCARD, SCB_LIST_NULL,
7825 ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
7826
7827 /*
7828 * Cleanup anything left in the FIFOs.
7829 */
7830 ahd_clear_fifo(ahd, 0);
7831 ahd_clear_fifo(ahd, 1);
7832
7833 /*
7834 * Revert to async/narrow transfers until we renegotiate.
7835 */
7836 max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7;
7837 for (target = 0; target <= max_scsiid; target++) {
7838
7839 if (ahd->enabled_targets[target] == NULL)
7840 continue;
7841 for (initiator = 0; initiator <= max_scsiid; initiator++) {
7842 struct ahd_devinfo devinfo;
7843
7844 ahd_compile_devinfo(&devinfo, target, initiator,
7845 CAM_LUN_WILDCARD,
7846 'A', ROLE_UNKNOWN);
7847 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
7848 AHD_TRANS_CUR, /*paused*/TRUE);
7849 ahd_set_syncrate(ahd, &devinfo, /*period*/0,
7850 /*offset*/0, /*ppr_options*/0,
7851 AHD_TRANS_CUR, /*paused*/TRUE);
7852 }
7853 }
7854
7855#ifdef AHD_TARGET_MODE
7856 max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7;
7857
7858 /*
7859 * Send an immediate notify ccb to all target more peripheral
7860 * drivers affected by this action.
7861 */
7862 for (target = 0; target <= max_scsiid; target++) {
7863 struct ahd_tmode_tstate* tstate;
7864 u_int lun;
7865
7866 tstate = ahd->enabled_targets[target];
7867 if (tstate == NULL)
7868 continue;
7869 for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
7870 struct ahd_tmode_lstate* lstate;
7871
7872 lstate = tstate->enabled_luns[lun];
7873 if (lstate == NULL)
7874 continue;
7875
7876 ahd_queue_lstate_event(ahd, lstate, CAM_TARGET_WILDCARD,
7877 EVENT_TYPE_BUS_RESET, /*arg*/0);
7878 ahd_send_lstate_events(ahd, lstate);
7879 }
7880 }
7881#endif
7882 /* Notify the XPT that a bus reset occurred */
7883 ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
7884 CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
7885 ahd_restart(ahd);
7886 /*
7887 * Freeze the SIMQ until our poller can determine that
7888 * the bus reset has really gone away. We set the initial
7889 * timer to 0 to have the check performed as soon as possible
7890 * from the timer context.
7891 */
7892 if ((ahd->flags & AHD_RESET_POLL_ACTIVE) == 0) {
7893 ahd->flags |= AHD_RESET_POLL_ACTIVE;
7894 ahd_freeze_simq(ahd);
7895 ahd_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd);
7896 }
7897 return (found);
7898}
7899
7900
7901#define AHD_RESET_POLL_US 1000
7902static void
7903ahd_reset_poll(void *arg)
7904{
7905 struct ahd_softc *ahd;
7906 u_int scsiseq1;
7907 u_long l;
7908 u_long s;
7909
7910 ahd_list_lock(&l);
7911 ahd = ahd_find_softc((struct ahd_softc *)arg);
7912 if (ahd == NULL) {
7913 printf("ahd_reset_poll: Instance %p no longer exists\n", arg);
7914 ahd_list_unlock(&l);
7915 return;
7916 }
7917 ahd_lock(ahd, &s);
7918 ahd_pause(ahd);
7919 ahd_update_modes(ahd);
7920 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7921 ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
7922 if ((ahd_inb(ahd, SSTAT1) & SCSIRSTI) != 0) {
7923 ahd_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US,
7924 ahd_reset_poll, ahd);
7925 ahd_unpause(ahd);
7926 ahd_unlock(ahd, &s);
7927 ahd_list_unlock(&l);
7928 return;
7929 }
7930
7931 /* Reset is now low. Complete chip reinitialization. */
7932 ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST);
7933 scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
7934 ahd_outb(ahd, SCSISEQ1, scsiseq1 & (ENSELI|ENRSELI|ENAUTOATNP));
7935 ahd_unpause(ahd);
7936 ahd->flags &= ~AHD_RESET_POLL_ACTIVE;
7937 ahd_unlock(ahd, &s);
7938 ahd_release_simq(ahd);
7939 ahd_list_unlock(&l);
7940}
7941
7942/**************************** Statistics Processing ***************************/
7943static void
7944ahd_stat_timer(void *arg)
7945{
7946 struct ahd_softc *ahd;
7947 u_long l;
7948 u_long s;
7949 int enint_coal;
7950
7951 ahd_list_lock(&l);
7952 ahd = ahd_find_softc((struct ahd_softc *)arg);
7953 if (ahd == NULL) {
7954 printf("ahd_stat_timer: Instance %p no longer exists\n", arg);
7955 ahd_list_unlock(&l);
7956 return;
7957 }
7958 ahd_lock(ahd, &s);
7959
7960 enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
7961 if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold)
7962 enint_coal |= ENINT_COALESCE;
7963 else if (ahd->cmdcmplt_total < ahd->int_coalescing_stop_threshold)
7964 enint_coal &= ~ENINT_COALESCE;
7965
7966 if (enint_coal != (ahd->hs_mailbox & ENINT_COALESCE)) {
7967 ahd_enable_coalescing(ahd, enint_coal);
7968#ifdef AHD_DEBUG
7969 if ((ahd_debug & AHD_SHOW_INT_COALESCING) != 0)
7970 printf("%s: Interrupt coalescing "
7971 "now %sabled. Cmds %d\n",
7972 ahd_name(ahd),
7973 (enint_coal & ENINT_COALESCE) ? "en" : "dis",
7974 ahd->cmdcmplt_total);
7975#endif
7976 }
7977
7978 ahd->cmdcmplt_bucket = (ahd->cmdcmplt_bucket+1) & (AHD_STAT_BUCKETS-1);
7979 ahd->cmdcmplt_total -= ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket];
7980 ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0;
7981 ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
7982 ahd_stat_timer, ahd);
7983 ahd_unlock(ahd, &s);
7984 ahd_list_unlock(&l);
7985}
7986
7987/****************************** Status Processing *****************************/
7988void
7989ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb)
7990{
7991 if (scb->hscb->shared_data.istatus.scsi_status != 0) {
7992 ahd_handle_scsi_status(ahd, scb);
7993 } else {
7994 ahd_calc_residual(ahd, scb);
7995 ahd_done(ahd, scb);
7996 }
7997}
7998
7999void
8000ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
8001{
8002 struct hardware_scb *hscb;
8003 u_int qfreeze_cnt;
8004
8005 /*
8006 * The sequencer freezes its select-out queue
8007 * anytime a SCSI status error occurs. We must
8008 * handle the error and decrement the QFREEZE count
8009 * to allow the sequencer to continue.
8010 */
8011 hscb = scb->hscb;
8012
8013 /* Freeze the queue until the client sees the error. */
8014 ahd_freeze_devq(ahd, scb);
8015 ahd_freeze_scb(scb);
8016 qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);
8017 if (qfreeze_cnt == 0) {
8018 printf("%s: Bad status with 0 qfreeze count!\n", ahd_name(ahd));
8019 } else {
8020 qfreeze_cnt--;
8021 ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt);
8022 }
8023 if (qfreeze_cnt == 0)
8024 ahd_outb(ahd, SEQ_FLAGS2,
8025 ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);
8026
8027 /* Don't want to clobber the original sense code */
8028 if ((scb->flags & SCB_SENSE) != 0) {
8029 /*
8030 * Clear the SCB_SENSE Flag and perform
8031 * a normal command completion.
8032 */
8033 scb->flags &= ~SCB_SENSE;
8034 ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
8035 ahd_done(ahd, scb);
8036 return;
8037 }
8038 ahd_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
8039 ahd_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status);
8040 switch (hscb->shared_data.istatus.scsi_status) {
8041 case STATUS_PKT_SENSE:
8042 {
8043 struct scsi_status_iu_header *siu;
8044
8045 ahd_sync_sense(ahd, scb, BUS_DMASYNC_POSTREAD);
8046 siu = (struct scsi_status_iu_header *)scb->sense_data;
8047 ahd_set_scsi_status(scb, siu->status);
8048#ifdef AHD_DEBUG
8049 if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
8050 ahd_print_path(ahd, scb);
8051 printf("SCB 0x%x Received PKT Status of 0x%x\n",
8052 SCB_GET_TAG(scb), siu->status);
8053 printf("\tflags = 0x%x, sense len = 0x%x, "
8054 "pktfail = 0x%x\n",
8055 siu->flags, scsi_4btoul(siu->sense_length),
8056 scsi_4btoul(siu->pkt_failures_length));
8057 }
8058#endif
8059 if ((siu->flags & SIU_RSPVALID) != 0) {
8060 ahd_print_path(ahd, scb);
8061 if (scsi_4btoul(siu->pkt_failures_length) < 4) {
8062 printf("Unable to parse pkt_failures\n");
8063 } else {
8064
8065 switch (SIU_PKTFAIL_CODE(siu)) {
8066 case SIU_PFC_NONE:
8067 printf("No packet failure found\n");
8068 break;
8069 case SIU_PFC_CIU_FIELDS_INVALID:
8070 printf("Invalid Command IU Field\n");
8071 break;
8072 case SIU_PFC_TMF_NOT_SUPPORTED:
8073 printf("TMF not supportd\n");
8074 break;
8075 case SIU_PFC_TMF_FAILED:
8076 printf("TMF failed\n");
8077 break;
8078 case SIU_PFC_INVALID_TYPE_CODE:
8079 printf("Invalid L_Q Type code\n");
8080 break;
8081 case SIU_PFC_ILLEGAL_REQUEST:
8082 printf("Illegal request\n");
8083 default:
8084 break;
8085 }
8086 }
8087 if (siu->status == SCSI_STATUS_OK)
8088 ahd_set_transaction_status(scb,
8089 CAM_REQ_CMP_ERR);
8090 }
8091 if ((siu->flags & SIU_SNSVALID) != 0) {
8092 scb->flags |= SCB_PKT_SENSE;
8093#ifdef AHD_DEBUG
8094 if ((ahd_debug & AHD_SHOW_SENSE) != 0)
8095 printf("Sense data available\n");
8096#endif
8097 }
8098 ahd_done(ahd, scb);
8099 break;
8100 }
8101 case SCSI_STATUS_CMD_TERMINATED:
8102 case SCSI_STATUS_CHECK_COND:
8103 {
8104 struct ahd_devinfo devinfo;
8105 struct ahd_dma_seg *sg;
8106 struct scsi_sense *sc;
8107 struct ahd_initiator_tinfo *targ_info;
8108 struct ahd_tmode_tstate *tstate;
8109 struct ahd_transinfo *tinfo;
8110#ifdef AHD_DEBUG
8111 if (ahd_debug & AHD_SHOW_SENSE) {
8112 ahd_print_path(ahd, scb);
8113 printf("SCB %d: requests Check Status\n",
8114 SCB_GET_TAG(scb));
8115 }
8116#endif
8117
8118 if (ahd_perform_autosense(scb) == 0)
8119 break;
8120
8121 ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
8122 SCB_GET_TARGET(ahd, scb),
8123 SCB_GET_LUN(scb),
8124 SCB_GET_CHANNEL(ahd, scb),
8125 ROLE_INITIATOR);
8126 targ_info = ahd_fetch_transinfo(ahd,
8127 devinfo.channel,
8128 devinfo.our_scsiid,
8129 devinfo.target,
8130 &tstate);
8131 tinfo = &targ_info->curr;
8132 sg = scb->sg_list;
8133 sc = (struct scsi_sense *)hscb->shared_data.idata.cdb;
8134 /*
8135 * Save off the residual if there is one.
8136 */
8137 ahd_update_residual(ahd, scb);
8138#ifdef AHD_DEBUG
8139 if (ahd_debug & AHD_SHOW_SENSE) {
8140 ahd_print_path(ahd, scb);
8141 printf("Sending Sense\n");
8142 }
8143#endif
8144 scb->sg_count = 0;
8145 sg = ahd_sg_setup(ahd, scb, sg, ahd_get_sense_bufaddr(ahd, scb),
8146 ahd_get_sense_bufsize(ahd, scb),
8147 /*last*/TRUE);
8148 sc->opcode = REQUEST_SENSE;
8149 sc->byte2 = 0;
8150 if (tinfo->protocol_version <= SCSI_REV_2
8151 && SCB_GET_LUN(scb) < 8)
8152 sc->byte2 = SCB_GET_LUN(scb) << 5;
8153 sc->unused[0] = 0;
8154 sc->unused[1] = 0;
8155 sc->length = ahd_get_sense_bufsize(ahd, scb);
8156 sc->control = 0;
8157
8158 /*
8159 * We can't allow the target to disconnect.
8160 * This will be an untagged transaction and
8161 * having the target disconnect will make this
8162 * transaction indestinguishable from outstanding
8163 * tagged transactions.
8164 */
8165 hscb->control = 0;
8166
8167 /*
8168 * This request sense could be because the
8169 * the device lost power or in some other
8170 * way has lost our transfer negotiations.
8171 * Renegotiate if appropriate. Unit attention
8172 * errors will be reported before any data
8173 * phases occur.
8174 */
8175 if (ahd_get_residual(scb) == ahd_get_transfer_length(scb)) {
8176 ahd_update_neg_request(ahd, &devinfo,
8177 tstate, targ_info,
8178 AHD_NEG_IF_NON_ASYNC);
8179 }
8180 if (tstate->auto_negotiate & devinfo.target_mask) {
8181 hscb->control |= MK_MESSAGE;
8182 scb->flags &=
8183 ~(SCB_NEGOTIATE|SCB_ABORT|SCB_DEVICE_RESET);
8184 scb->flags |= SCB_AUTO_NEGOTIATE;
8185 }
8186 hscb->cdb_len = sizeof(*sc);
8187 ahd_setup_data_scb(ahd, scb);
8188 scb->flags |= SCB_SENSE;
8189 ahd_queue_scb(ahd, scb);
8190 /*
8191 * Ensure we have enough time to actually
8192 * retrieve the sense.
8193 */
8194 ahd_scb_timer_reset(scb, 5 * 1000000);
8195 break;
8196 }
8197 case SCSI_STATUS_OK:
8198 printf("%s: Interrupted for staus of 0???\n",
8199 ahd_name(ahd));
8200 /* FALLTHROUGH */
8201 default:
8202 ahd_done(ahd, scb);
8203 break;
8204 }
8205}
8206
8207/*
8208 * Calculate the residual for a just completed SCB.
8209 */
8210void
8211ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
8212{
8213 struct hardware_scb *hscb;
8214 struct initiator_status *spkt;
8215 uint32_t sgptr;
8216 uint32_t resid_sgptr;
8217 uint32_t resid;
8218
8219 /*
8220 * 5 cases.
8221 * 1) No residual.
8222 * SG_STATUS_VALID clear in sgptr.
8223 * 2) Transferless command
8224 * 3) Never performed any transfers.
8225 * sgptr has SG_FULL_RESID set.
8226 * 4) No residual but target did not
8227 * save data pointers after the
8228 * last transfer, so sgptr was
8229 * never updated.
8230 * 5) We have a partial residual.
8231 * Use residual_sgptr to determine
8232 * where we are.
8233 */
8234
8235 hscb = scb->hscb;
8236 sgptr = ahd_le32toh(hscb->sgptr);
8237 if ((sgptr & SG_STATUS_VALID) == 0)
8238 /* Case 1 */
8239 return;
8240 sgptr &= ~SG_STATUS_VALID;
8241
8242 if ((sgptr & SG_LIST_NULL) != 0)
8243 /* Case 2 */
8244 return;
8245
8246 /*
8247 * Residual fields are the same in both
8248 * target and initiator status packets,
8249 * so we can always use the initiator fields
8250 * regardless of the role for this SCB.
8251 */
8252 spkt = &hscb->shared_data.istatus;
8253 resid_sgptr = ahd_le32toh(spkt->residual_sgptr);
8254 if ((sgptr & SG_FULL_RESID) != 0) {
8255 /* Case 3 */
8256 resid = ahd_get_transfer_length(scb);
8257 } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
8258 /* Case 4 */
8259 return;
8260 } else if ((resid_sgptr & SG_OVERRUN_RESID) != 0) {
8261 ahd_print_path(ahd, scb);
8262 printf("data overrun detected Tag == 0x%x.\n",
8263 SCB_GET_TAG(scb));
8264 ahd_freeze_devq(ahd, scb);
8265 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
8266 ahd_freeze_scb(scb);
8267 return;
8268 } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
8269 panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
8270 /* NOTREACHED */
8271 } else {
8272 struct ahd_dma_seg *sg;
8273
8274 /*
8275 * Remainder of the SG where the transfer
8276 * stopped.
8277 */
8278 resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK;
8279 sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK);
8280
8281 /* The residual sg_ptr always points to the next sg */
8282 sg--;
8283
8284 /*
8285 * Add up the contents of all residual
8286 * SG segments that are after the SG where
8287 * the transfer stopped.
8288 */
8289 while ((ahd_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) {
8290 sg++;
8291 resid += ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
8292 }
8293 }
8294 if ((scb->flags & SCB_SENSE) == 0)
8295 ahd_set_residual(scb, resid);
8296 else
8297 ahd_set_sense_residual(scb, resid);
8298
8299#ifdef AHD_DEBUG
8300 if ((ahd_debug & AHD_SHOW_MISC) != 0) {
8301 ahd_print_path(ahd, scb);
8302 printf("Handled %sResidual of %d bytes\n",
8303 (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
8304 }
8305#endif
8306}
8307
8308/******************************* Target Mode **********************************/
8309#ifdef AHD_TARGET_MODE
8310/*
8311 * Add a target mode event to this lun's queue
8312 */
8313static void
8314ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate,
8315 u_int initiator_id, u_int event_type, u_int event_arg)
8316{
8317 struct ahd_tmode_event *event;
8318 int pending;
8319
8320 xpt_freeze_devq(lstate->path, /*count*/1);
8321 if (lstate->event_w_idx >= lstate->event_r_idx)
8322 pending = lstate->event_w_idx - lstate->event_r_idx;
8323 else
8324 pending = AHD_TMODE_EVENT_BUFFER_SIZE + 1
8325 - (lstate->event_r_idx - lstate->event_w_idx);
8326
8327 if (event_type == EVENT_TYPE_BUS_RESET
8328 || event_type == MSG_BUS_DEV_RESET) {
8329 /*
8330 * Any earlier events are irrelevant, so reset our buffer.
8331 * This has the effect of allowing us to deal with reset
8332 * floods (an external device holding down the reset line)
8333 * without losing the event that is really interesting.
8334 */
8335 lstate->event_r_idx = 0;
8336 lstate->event_w_idx = 0;
8337 xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE);
8338 }
8339
8340 if (pending == AHD_TMODE_EVENT_BUFFER_SIZE) {
8341 xpt_print_path(lstate->path);
8342 printf("immediate event %x:%x lost\n",
8343 lstate->event_buffer[lstate->event_r_idx].event_type,
8344 lstate->event_buffer[lstate->event_r_idx].event_arg);
8345 lstate->event_r_idx++;
8346 if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
8347 lstate->event_r_idx = 0;
8348 xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE);
8349 }
8350
8351 event = &lstate->event_buffer[lstate->event_w_idx];
8352 event->initiator_id = initiator_id;
8353 event->event_type = event_type;
8354 event->event_arg = event_arg;
8355 lstate->event_w_idx++;
8356 if (lstate->event_w_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
8357 lstate->event_w_idx = 0;
8358}
8359
8360/*
8361 * Send any target mode events queued up waiting
8362 * for immediate notify resources.
8363 */
8364void
8365ahd_send_lstate_events(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate)
8366{
8367 struct ccb_hdr *ccbh;
8368 struct ccb_immed_notify *inot;
8369
8370 while (lstate->event_r_idx != lstate->event_w_idx
8371 && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
8372 struct ahd_tmode_event *event;
8373
8374 event = &lstate->event_buffer[lstate->event_r_idx];
8375 SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
8376 inot = (struct ccb_immed_notify *)ccbh;
8377 switch (event->event_type) {
8378 case EVENT_TYPE_BUS_RESET:
8379 ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
8380 break;
8381 default:
8382 ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
8383 inot->message_args[0] = event->event_type;
8384 inot->message_args[1] = event->event_arg;
8385 break;
8386 }
8387 inot->initiator_id = event->initiator_id;
8388 inot->sense_len = 0;
8389 xpt_done((union ccb *)inot);
8390 lstate->event_r_idx++;
8391 if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
8392 lstate->event_r_idx = 0;
8393 }
8394}
8395#endif
8396
8397/******************** Sequencer Program Patching/Download *********************/
8398
8399#ifdef AHD_DUMP_SEQ
8400void
8401ahd_dumpseq(struct ahd_softc* ahd)
8402{
8403 int i;
8404 int max_prog;
8405
8406 max_prog = 2048;
8407
8408 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
8409 ahd_outb(ahd, PRGMCNT, 0);
8410 ahd_outb(ahd, PRGMCNT+1, 0);
8411 for (i = 0; i < max_prog; i++) {
8412 uint8_t ins_bytes[4];
8413
8414 ahd_insb(ahd, SEQRAM, ins_bytes, 4);
8415 printf("0x%08x\n", ins_bytes[0] << 24
8416 | ins_bytes[1] << 16
8417 | ins_bytes[2] << 8
8418 | ins_bytes[3]);
8419 }
8420}
8421#endif
8422
8423static void
8424ahd_loadseq(struct ahd_softc *ahd)
8425{
8426 struct cs cs_table[num_critical_sections];
8427 u_int begin_set[num_critical_sections];
8428 u_int end_set[num_critical_sections];
8429 struct patch *cur_patch;
8430 u_int cs_count;
8431 u_int cur_cs;
8432 u_int i;
8433 int downloaded;
8434 u_int skip_addr;
8435 u_int sg_prefetch_cnt;
8436 u_int sg_prefetch_cnt_limit;
8437 u_int sg_prefetch_align;
8438 u_int sg_size;
8439 uint8_t download_consts[DOWNLOAD_CONST_COUNT];
8440
8441 if (bootverbose)
8442 printf("%s: Downloading Sequencer Program...",
8443 ahd_name(ahd));
8444
8445#if DOWNLOAD_CONST_COUNT != 7
8446#error "Download Const Mismatch"
8447#endif
8448 /*
8449 * Start out with 0 critical sections
8450 * that apply to this firmware load.
8451 */
8452 cs_count = 0;
8453 cur_cs = 0;
8454 memset(begin_set, 0, sizeof(begin_set));
8455 memset(end_set, 0, sizeof(end_set));
8456
8457 /*
8458 * Setup downloadable constant table.
8459 *
8460 * The computation for the S/G prefetch variables is
8461 * a bit complicated. We would like to always fetch
8462 * in terms of cachelined sized increments. However,
8463 * if the cacheline is not an even multiple of the
8464 * SG element size or is larger than our SG RAM, using
8465 * just the cache size might leave us with only a portion
8466 * of an SG element at the tail of a prefetch. If the
8467 * cacheline is larger than our S/G prefetch buffer less
8468 * the size of an SG element, we may round down to a cacheline
8469 * that doesn't contain any or all of the S/G of interest
8470 * within the bounds of our S/G ram. Provide variables to
8471 * the sequencer that will allow it to handle these edge
8472 * cases.
8473 */
8474 /* Start by aligning to the nearest cacheline. */
8475 sg_prefetch_align = ahd->pci_cachesize;
8476 if (sg_prefetch_align == 0)
8477 sg_prefetch_align = 8;
8478 /* Round down to the nearest power of 2. */
8479 while (powerof2(sg_prefetch_align) == 0)
8480 sg_prefetch_align--;
8481 /*
8482 * If the cacheline boundary is greater than half our prefetch RAM
8483 * we risk not being able to fetch even a single complete S/G
8484 * segment if we align to that boundary.
8485 */
8486 if (sg_prefetch_align > CCSGADDR_MAX/2)
8487 sg_prefetch_align = CCSGADDR_MAX/2;
8488 /* Start by fetching a single cacheline. */
8489 sg_prefetch_cnt = sg_prefetch_align;
8490 /*
8491 * Increment the prefetch count by cachelines until
8492 * at least one S/G element will fit.
8493 */
8494 sg_size = sizeof(struct ahd_dma_seg);
8495 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
8496 sg_size = sizeof(struct ahd_dma64_seg);
8497 while (sg_prefetch_cnt < sg_size)
8498 sg_prefetch_cnt += sg_prefetch_align;
8499 /*
8500 * If the cacheline is not an even multiple of
8501 * the S/G size, we may only get a partial S/G when
8502 * we align. Add a cacheline if this is the case.
8503 */
8504 if ((sg_prefetch_align % sg_size) != 0
8505 && (sg_prefetch_cnt < CCSGADDR_MAX))
8506 sg_prefetch_cnt += sg_prefetch_align;
8507 /*
8508 * Lastly, compute a value that the sequencer can use
8509 * to determine if the remainder of the CCSGRAM buffer
8510 * has a full S/G element in it.
8511 */
8512 sg_prefetch_cnt_limit = -(sg_prefetch_cnt - sg_size + 1);
8513 download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
8514 download_consts[SG_PREFETCH_CNT_LIMIT] = sg_prefetch_cnt_limit;
8515 download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_align - 1);
8516 download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_align - 1);
8517 download_consts[SG_SIZEOF] = sg_size;
8518 download_consts[PKT_OVERRUN_BUFOFFSET] =
8519 (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256;
8520 download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN;
8521 cur_patch = patches;
8522 downloaded = 0;
8523 skip_addr = 0;
8524 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
8525 ahd_outb(ahd, PRGMCNT, 0);
8526 ahd_outb(ahd, PRGMCNT+1, 0);
8527
8528 for (i = 0; i < sizeof(seqprog)/4; i++) {
8529 if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) {
8530 /*
8531 * Don't download this instruction as it
8532 * is in a patch that was removed.
8533 */
8534 continue;
8535 }
8536 /*
8537 * Move through the CS table until we find a CS
8538 * that might apply to this instruction.
8539 */
8540 for (; cur_cs < num_critical_sections; cur_cs++) {
8541 if (critical_sections[cur_cs].end <= i) {
8542 if (begin_set[cs_count] == TRUE
8543 && end_set[cs_count] == FALSE) {
8544 cs_table[cs_count].end = downloaded;
8545 end_set[cs_count] = TRUE;
8546 cs_count++;
8547 }
8548 continue;
8549 }
8550 if (critical_sections[cur_cs].begin <= i
8551 && begin_set[cs_count] == FALSE) {
8552 cs_table[cs_count].begin = downloaded;
8553 begin_set[cs_count] = TRUE;
8554 }
8555 break;
8556 }
8557 ahd_download_instr(ahd, i, download_consts);
8558 downloaded++;
8559 }
8560
8561 ahd->num_critical_sections = cs_count;
8562 if (cs_count != 0) {
8563
8564 cs_count *= sizeof(struct cs);
8565 ahd->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
8566 if (ahd->critical_sections == NULL)
8567 panic("ahd_loadseq: Could not malloc");
8568 memcpy(ahd->critical_sections, cs_table, cs_count);
8569 }
8570 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE);
8571
8572 if (bootverbose) {
8573 printf(" %d instructions downloaded\n", downloaded);
8574 printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
8575 ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags);
8576 }
8577}
8578
8579static int
8580ahd_check_patch(struct ahd_softc *ahd, struct patch **start_patch,
8581 u_int start_instr, u_int *skip_addr)
8582{
8583 struct patch *cur_patch;
8584 struct patch *last_patch;
8585 u_int num_patches;
8586
8587 num_patches = sizeof(patches)/sizeof(struct patch);
8588 last_patch = &patches[num_patches];
8589 cur_patch = *start_patch;
8590
8591 while (cur_patch < last_patch && start_instr == cur_patch->begin) {
8592
8593 if (cur_patch->patch_func(ahd) == 0) {
8594
8595 /* Start rejecting code */
8596 *skip_addr = start_instr + cur_patch->skip_instr;
8597 cur_patch += cur_patch->skip_patch;
8598 } else {
8599 /* Accepted this patch. Advance to the next
8600 * one and wait for our intruction pointer to
8601 * hit this point.
8602 */
8603 cur_patch++;
8604 }
8605 }
8606
8607 *start_patch = cur_patch;
8608 if (start_instr < *skip_addr)
8609 /* Still skipping */
8610 return (0);
8611
8612 return (1);
8613}
8614
8615static u_int
8616ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address)
8617{
8618 struct patch *cur_patch;
8619 int address_offset;
8620 u_int skip_addr;
8621 u_int i;
8622
8623 address_offset = 0;
8624 cur_patch = patches;
8625 skip_addr = 0;
8626
8627 for (i = 0; i < address;) {
8628
8629 ahd_check_patch(ahd, &cur_patch, i, &skip_addr);
8630
8631 if (skip_addr > i) {
8632 int end_addr;
8633
8634 end_addr = MIN(address, skip_addr);
8635 address_offset += end_addr - i;
8636 i = skip_addr;
8637 } else {
8638 i++;
8639 }
8640 }
8641 return (address - address_offset);
8642}
8643
8644static void
8645ahd_download_instr(struct ahd_softc *ahd, u_int instrptr, uint8_t *dconsts)
8646{
8647 union ins_formats instr;
8648 struct ins_format1 *fmt1_ins;
8649 struct ins_format3 *fmt3_ins;
8650 u_int opcode;
8651
8652 /*
8653 * The firmware is always compiled into a little endian format.
8654 */
8655 instr.integer = ahd_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
8656
8657 fmt1_ins = &instr.format1;
8658 fmt3_ins = NULL;
8659
8660 /* Pull the opcode */
8661 opcode = instr.format1.opcode;
8662 switch (opcode) {
8663 case AIC_OP_JMP:
8664 case AIC_OP_JC:
8665 case AIC_OP_JNC:
8666 case AIC_OP_CALL:
8667 case AIC_OP_JNE:
8668 case AIC_OP_JNZ:
8669 case AIC_OP_JE:
8670 case AIC_OP_JZ:
8671 {
8672 fmt3_ins = &instr.format3;
8673 fmt3_ins->address = ahd_resolve_seqaddr(ahd, fmt3_ins->address);
8674 /* FALLTHROUGH */
8675 }
8676 case AIC_OP_OR:
8677 case AIC_OP_AND:
8678 case AIC_OP_XOR:
8679 case AIC_OP_ADD:
8680 case AIC_OP_ADC:
8681 case AIC_OP_BMOV:
8682 if (fmt1_ins->parity != 0) {
8683 fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
8684 }
8685 fmt1_ins->parity = 0;
8686 /* FALLTHROUGH */
8687 case AIC_OP_ROL:
8688 {
8689 int i, count;
8690
8691 /* Calculate odd parity for the instruction */
8692 for (i = 0, count = 0; i < 31; i++) {
8693 uint32_t mask;
8694
8695 mask = 0x01 << i;
8696 if ((instr.integer & mask) != 0)
8697 count++;
8698 }
8699 if ((count & 0x01) == 0)
8700 instr.format1.parity = 1;
8701
8702 /* The sequencer is a little endian cpu */
8703 instr.integer = ahd_htole32(instr.integer);
8704 ahd_outsb(ahd, SEQRAM, instr.bytes, 4);
8705 break;
8706 }
8707 default:
8708 panic("Unknown opcode encountered in seq program");
8709 break;
8710 }
8711}
8712
8713static int
8714ahd_probe_stack_size(struct ahd_softc *ahd)
8715{
8716 int last_probe;
8717
8718 last_probe = 0;
8719 while (1) {
8720 int i;
8721
8722 /*
8723 * We avoid using 0 as a pattern to avoid
8724 * confusion if the stack implementation
8725 * "back-fills" with zeros when "poping'
8726 * entries.
8727 */
8728 for (i = 1; i <= last_probe+1; i++) {
8729 ahd_outb(ahd, STACK, i & 0xFF);
8730 ahd_outb(ahd, STACK, (i >> 8) & 0xFF);
8731 }
8732
8733 /* Verify */
8734 for (i = last_probe+1; i > 0; i--) {
8735 u_int stack_entry;
8736
8737 stack_entry = ahd_inb(ahd, STACK)
8738 |(ahd_inb(ahd, STACK) << 8);
8739 if (stack_entry != i)
8740 goto sized;
8741 }
8742 last_probe++;
8743 }
8744sized:
8745 return (last_probe);
8746}
8747
8748void
8749ahd_dump_all_cards_state(void)
8750{
8751 struct ahd_softc *list_ahd;
8752
8753 TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
8754 ahd_dump_card_state(list_ahd);
8755 }
8756}
8757
8758int
8759ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries,
8760 const char *name, u_int address, u_int value,
8761 u_int *cur_column, u_int wrap_point)
8762{
8763 int printed;
8764 u_int printed_mask;
8765
8766 if (cur_column != NULL && *cur_column >= wrap_point) {
8767 printf("\n");
8768 *cur_column = 0;
8769 }
8770 printed = printf("%s[0x%x]", name, value);
8771 if (table == NULL) {
8772 printed += printf(" ");
8773 *cur_column += printed;
8774 return (printed);
8775 }
8776 printed_mask = 0;
8777 while (printed_mask != 0xFF) {
8778 int entry;
8779
8780 for (entry = 0; entry < num_entries; entry++) {
8781 if (((value & table[entry].mask)
8782 != table[entry].value)
8783 || ((printed_mask & table[entry].mask)
8784 == table[entry].mask))
8785 continue;
8786
8787 printed += printf("%s%s",
8788 printed_mask == 0 ? ":(" : "|",
8789 table[entry].name);
8790 printed_mask |= table[entry].mask;
8791
8792 break;
8793 }
8794 if (entry >= num_entries)
8795 break;
8796 }
8797 if (printed_mask != 0)
8798 printed += printf(") ");
8799 else
8800 printed += printf(" ");
8801 if (cur_column != NULL)
8802 *cur_column += printed;
8803 return (printed);
8804}
8805
8806void
8807ahd_dump_card_state(struct ahd_softc *ahd)
8808{
8809 struct scb *scb;
8810 ahd_mode_state saved_modes;
8811 u_int dffstat;
8812 int paused;
8813 u_int scb_index;
8814 u_int saved_scb_index;
8815 u_int cur_col;
8816 int i;
8817
8818 if (ahd_is_paused(ahd)) {
8819 paused = 1;
8820 } else {
8821 paused = 0;
8822 ahd_pause(ahd);
8823 }
8824 saved_modes = ahd_save_modes(ahd);
8825 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
8826 printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
8827 "%s: Dumping Card State at program address 0x%x Mode 0x%x\n",
8828 ahd_name(ahd),
8829 ahd_inb(ahd, CURADDR) | (ahd_inb(ahd, CURADDR+1) << 8),
8830 ahd_build_mode_state(ahd, ahd->saved_src_mode,
8831 ahd->saved_dst_mode));
8832 if (paused)
8833 printf("Card was paused\n");
8834
8835 if (ahd_check_cmdcmpltqueues(ahd))
8836 printf("Completions are pending\n");
8837
8838 /*
8839 * Mode independent registers.
8840 */
8841 cur_col = 0;
8842 ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50);
8843 ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50);
8844 ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50);
8845 ahd_saved_mode_print(ahd_inb(ahd, SAVED_MODE), &cur_col, 50);
8846 ahd_dffstat_print(ahd_inb(ahd, DFFSTAT), &cur_col, 50);
8847 ahd_scsisigi_print(ahd_inb(ahd, SCSISIGI), &cur_col, 50);
8848 ahd_scsiphase_print(ahd_inb(ahd, SCSIPHASE), &cur_col, 50);
8849 ahd_scsibus_print(ahd_inb(ahd, SCSIBUS), &cur_col, 50);
8850 ahd_lastphase_print(ahd_inb(ahd, LASTPHASE), &cur_col, 50);
8851 ahd_scsiseq0_print(ahd_inb(ahd, SCSISEQ0), &cur_col, 50);
8852 ahd_scsiseq1_print(ahd_inb(ahd, SCSISEQ1), &cur_col, 50);
8853 ahd_seqctl0_print(ahd_inb(ahd, SEQCTL0), &cur_col, 50);
8854 ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50);
8855 ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50);
8856 ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50);
8857 ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50);
8858 ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50);
8859 ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50);
8860 ahd_sstat3_print(ahd_inb(ahd, SSTAT3), &cur_col, 50);
8861 ahd_perrdiag_print(ahd_inb(ahd, PERRDIAG), &cur_col, 50);
8862 ahd_simode1_print(ahd_inb(ahd, SIMODE1), &cur_col, 50);
8863 ahd_lqistat0_print(ahd_inb(ahd, LQISTAT0), &cur_col, 50);
8864 ahd_lqistat1_print(ahd_inb(ahd, LQISTAT1), &cur_col, 50);
8865 ahd_lqistat2_print(ahd_inb(ahd, LQISTAT2), &cur_col, 50);
8866 ahd_lqostat0_print(ahd_inb(ahd, LQOSTAT0), &cur_col, 50);
8867 ahd_lqostat1_print(ahd_inb(ahd, LQOSTAT1), &cur_col, 50);
8868 ahd_lqostat2_print(ahd_inb(ahd, LQOSTAT2), &cur_col, 50);
8869 printf("\n");
8870 printf("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x "
8871 "CURRSCB 0x%x NEXTSCB 0x%x\n",
8872 ahd->scb_data.numscbs, ahd_inw(ahd, CMDS_PENDING),
8873 ahd_inw(ahd, LASTSCB), ahd_inw(ahd, CURRSCB),
8874 ahd_inw(ahd, NEXTSCB));
8875 cur_col = 0;
8876 /* QINFIFO */
8877 ahd_search_qinfifo(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
8878 CAM_LUN_WILDCARD, SCB_LIST_NULL,
8879 ROLE_UNKNOWN, /*status*/0, SEARCH_PRINT);
8880 saved_scb_index = ahd_get_scbptr(ahd);
8881 printf("Pending list:");
8882 i = 0;
8883 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
8884 if (i++ > AHD_SCB_MAX)
8885 break;
8886 cur_col = printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
8887 ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT));
8888 ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
8889 ahd_scb_control_print(ahd_inb_scbram(ahd, SCB_CONTROL),
8890 &cur_col, 60);
8891 ahd_scb_scsiid_print(ahd_inb_scbram(ahd, SCB_SCSIID),
8892 &cur_col, 60);
8893 }
8894 printf("\nTotal %d\n", i);
8895
8896 printf("Kernel Free SCB list: ");
8897 i = 0;
8898 TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
8899 struct scb *list_scb;
8900
8901 list_scb = scb;
8902 do {
8903 printf("%d ", SCB_GET_TAG(list_scb));
8904 list_scb = LIST_NEXT(list_scb, collision_links);
8905 } while (list_scb && i++ < AHD_SCB_MAX);
8906 }
8907
8908 LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
8909 if (i++ > AHD_SCB_MAX)
8910 break;
8911 printf("%d ", SCB_GET_TAG(scb));
8912 }
8913 printf("\n");
8914
8915 printf("Sequencer Complete DMA-inprog list: ");
8916 scb_index = ahd_inw(ahd, COMPLETE_SCB_DMAINPROG_HEAD);
8917 i = 0;
8918 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8919 ahd_set_scbptr(ahd, scb_index);
8920 printf("%d ", scb_index);
8921 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8922 }
8923 printf("\n");
8924
8925 printf("Sequencer Complete list: ");
8926 scb_index = ahd_inw(ahd, COMPLETE_SCB_HEAD);
8927 i = 0;
8928 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8929 ahd_set_scbptr(ahd, scb_index);
8930 printf("%d ", scb_index);
8931 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8932 }
8933 printf("\n");
8934
8935
8936 printf("Sequencer DMA-Up and Complete list: ");
8937 scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
8938 i = 0;
8939 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8940 ahd_set_scbptr(ahd, scb_index);
8941 printf("%d ", scb_index);
8942 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8943 }
8944 printf("\n");
8945 ahd_set_scbptr(ahd, saved_scb_index);
8946 dffstat = ahd_inb(ahd, DFFSTAT);
8947 for (i = 0; i < 2; i++) {
8948#ifdef AHD_DEBUG
8949 struct scb *fifo_scb;
8950#endif
8951 u_int fifo_scbptr;
8952
8953 ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
8954 fifo_scbptr = ahd_get_scbptr(ahd);
8955 printf("\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
8956 ahd_name(ahd), i,
8957 (dffstat & (FIFO0FREE << i)) ? "Free" : "Active",
8958 ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr);
8959 cur_col = 0;
8960 ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50);
8961 ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50);
8962 ahd_dfcntrl_print(ahd_inb(ahd, DFCNTRL), &cur_col, 50);
8963 ahd_dfstatus_print(ahd_inb(ahd, DFSTATUS), &cur_col, 50);
8964 ahd_sg_cache_shadow_print(ahd_inb(ahd, SG_CACHE_SHADOW),
8965 &cur_col, 50);
8966 ahd_sg_state_print(ahd_inb(ahd, SG_STATE), &cur_col, 50);
8967 ahd_dffsxfrctl_print(ahd_inb(ahd, DFFSXFRCTL), &cur_col, 50);
8968 ahd_soffcnt_print(ahd_inb(ahd, SOFFCNT), &cur_col, 50);
8969 ahd_mdffstat_print(ahd_inb(ahd, MDFFSTAT), &cur_col, 50);
8970 if (cur_col > 50) {
8971 printf("\n");
8972 cur_col = 0;
8973 }
8974 cur_col += printf("SHADDR = 0x%x%x, SHCNT = 0x%x ",
8975 ahd_inl(ahd, SHADDR+4),
8976 ahd_inl(ahd, SHADDR),
8977 (ahd_inb(ahd, SHCNT)
8978 | (ahd_inb(ahd, SHCNT + 1) << 8)
8979 | (ahd_inb(ahd, SHCNT + 2) << 16)));
8980 if (cur_col > 50) {
8981 printf("\n");
8982 cur_col = 0;
8983 }
8984 cur_col += printf("HADDR = 0x%x%x, HCNT = 0x%x ",
8985 ahd_inl(ahd, HADDR+4),
8986 ahd_inl(ahd, HADDR),
8987 (ahd_inb(ahd, HCNT)
8988 | (ahd_inb(ahd, HCNT + 1) << 8)
8989 | (ahd_inb(ahd, HCNT + 2) << 16)));
8990 ahd_ccsgctl_print(ahd_inb(ahd, CCSGCTL), &cur_col, 50);
8991#ifdef AHD_DEBUG
8992 if ((ahd_debug & AHD_SHOW_SG) != 0) {
8993 fifo_scb = ahd_lookup_scb(ahd, fifo_scbptr);
8994 if (fifo_scb != NULL)
8995 ahd_dump_sglist(fifo_scb);
8996 }
8997#endif
8998 }
8999 printf("\nLQIN: ");
9000 for (i = 0; i < 20; i++)
9001 printf("0x%x ", ahd_inb(ahd, LQIN + i));
9002 printf("\n");
9003 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
9004 printf("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n",
9005 ahd_name(ahd), ahd_inb(ahd, LQISTATE), ahd_inb(ahd, LQOSTATE),
9006 ahd_inb(ahd, OPTIONMODE));
9007 printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n",
9008 ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT),
9009 ahd_inb(ahd, MAXCMDCNT));
9010 ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50);
9011 printf("\n");
9012 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
9013 cur_col = 0;
9014 ahd_ccscbctl_print(ahd_inb(ahd, CCSCBCTL), &cur_col, 50);
9015 printf("\n");
9016 ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
9017 printf("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n",
9018 ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX),
9019 ahd_inw(ahd, DINDEX));
9020 printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n",
9021 ahd_name(ahd), ahd_get_scbptr(ahd),
9022 ahd_inw_scbram(ahd, SCB_NEXT),
9023 ahd_inw_scbram(ahd, SCB_NEXT2));
9024 printf("CDB %x %x %x %x %x %x\n",
9025 ahd_inb_scbram(ahd, SCB_CDB_STORE),
9026 ahd_inb_scbram(ahd, SCB_CDB_STORE+1),
9027 ahd_inb_scbram(ahd, SCB_CDB_STORE+2),
9028 ahd_inb_scbram(ahd, SCB_CDB_STORE+3),
9029 ahd_inb_scbram(ahd, SCB_CDB_STORE+4),
9030 ahd_inb_scbram(ahd, SCB_CDB_STORE+5));
9031 printf("STACK:");
9032 for (i = 0; i < ahd->stack_size; i++) {
9033 ahd->saved_stack[i] =
9034 ahd_inb(ahd, STACK)|(ahd_inb(ahd, STACK) << 8);
9035 printf(" 0x%x", ahd->saved_stack[i]);
9036 }
9037 for (i = ahd->stack_size-1; i >= 0; i--) {
9038 ahd_outb(ahd, STACK, ahd->saved_stack[i] & 0xFF);
9039 ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF);
9040 }
9041 printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
9042 ahd_platform_dump_card_state(ahd);
9043 ahd_restore_modes(ahd, saved_modes);
9044 if (paused == 0)
9045 ahd_unpause(ahd);
9046}
9047
9048void
9049ahd_dump_scbs(struct ahd_softc *ahd)
9050{
9051 ahd_mode_state saved_modes;
9052 u_int saved_scb_index;
9053 int i;
9054
9055 saved_modes = ahd_save_modes(ahd);
9056 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
9057 saved_scb_index = ahd_get_scbptr(ahd);
9058 for (i = 0; i < AHD_SCB_MAX; i++) {
9059 ahd_set_scbptr(ahd, i);
9060 printf("%3d", i);
9061 printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n",
9062 ahd_inb_scbram(ahd, SCB_CONTROL),
9063 ahd_inb_scbram(ahd, SCB_SCSIID),
9064 ahd_inw_scbram(ahd, SCB_NEXT),
9065 ahd_inw_scbram(ahd, SCB_NEXT2),
9066 ahd_inl_scbram(ahd, SCB_SGPTR),
9067 ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR));
9068 }
9069 printf("\n");
9070 ahd_set_scbptr(ahd, saved_scb_index);
9071 ahd_restore_modes(ahd, saved_modes);
9072}
9073
9074/**************************** Flexport Logic **********************************/
9075/*
9076 * Read count 16bit words from 16bit word address start_addr from the
9077 * SEEPROM attached to the controller, into buf, using the controller's
9078 * SEEPROM reading state machine. Optionally treat the data as a byte
9079 * stream in terms of byte order.
9080 */
9081int
9082ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
9083 u_int start_addr, u_int count, int bytestream)
9084{
9085 u_int cur_addr;
9086 u_int end_addr;
9087 int error;
9088
9089 /*
9090 * If we never make it through the loop even once,
9091 * we were passed invalid arguments.
9092 */
9093 error = EINVAL;
9094 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9095 end_addr = start_addr + count;
9096 for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
9097
9098 ahd_outb(ahd, SEEADR, cur_addr);
9099 ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART);
9100
9101 error = ahd_wait_seeprom(ahd);
9102 if (error)
9103 break;
9104 if (bytestream != 0) {
9105 uint8_t *bytestream_ptr;
9106
9107 bytestream_ptr = (uint8_t *)buf;
9108 *bytestream_ptr++ = ahd_inb(ahd, SEEDAT);
9109 *bytestream_ptr = ahd_inb(ahd, SEEDAT+1);
9110 } else {
9111 /*
9112 * ahd_inw() already handles machine byte order.
9113 */
9114 *buf = ahd_inw(ahd, SEEDAT);
9115 }
9116 buf++;
9117 }
9118 return (error);
9119}
9120
9121/*
9122 * Write count 16bit words from buf, into SEEPROM attache to the
9123 * controller starting at 16bit word address start_addr, using the
9124 * controller's SEEPROM writing state machine.
9125 */
9126int
9127ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
9128 u_int start_addr, u_int count)
9129{
9130 u_int cur_addr;
9131 u_int end_addr;
9132 int error;
9133 int retval;
9134
9135 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9136 error = ENOENT;
9137
9138 /* Place the chip into write-enable mode */
9139 ahd_outb(ahd, SEEADR, SEEOP_EWEN_ADDR);
9140 ahd_outb(ahd, SEECTL, SEEOP_EWEN | SEESTART);
9141 error = ahd_wait_seeprom(ahd);
9142 if (error)
9143 return (error);
9144
9145 /*
9146 * Write the data. If we don't get throught the loop at
9147 * least once, the arguments were invalid.
9148 */
9149 retval = EINVAL;
9150 end_addr = start_addr + count;
9151 for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
9152 ahd_outw(ahd, SEEDAT, *buf++);
9153 ahd_outb(ahd, SEEADR, cur_addr);
9154 ahd_outb(ahd, SEECTL, SEEOP_WRITE | SEESTART);
9155
9156 retval = ahd_wait_seeprom(ahd);
9157 if (retval)
9158 break;
9159 }
9160
9161 /*
9162 * Disable writes.
9163 */
9164 ahd_outb(ahd, SEEADR, SEEOP_EWDS_ADDR);
9165 ahd_outb(ahd, SEECTL, SEEOP_EWDS | SEESTART);
9166 error = ahd_wait_seeprom(ahd);
9167 if (error)
9168 return (error);
9169 return (retval);
9170}
9171
9172/*
9173 * Wait ~100us for the serial eeprom to satisfy our request.
9174 */
9175int
9176ahd_wait_seeprom(struct ahd_softc *ahd)
9177{
9178 int cnt;
9179
9180 cnt = 20;
9181 while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt)
9182 ahd_delay(5);
9183
9184 if (cnt == 0)
9185 return (ETIMEDOUT);
9186 return (0);
9187}
9188
9189/*
9190 * Validate the two checksums in the per_channel
9191 * vital product data struct.
9192 */
9193int
9194ahd_verify_vpd_cksum(struct vpd_config *vpd)
9195{
9196 int i;
9197 int maxaddr;
9198 uint32_t checksum;
9199 uint8_t *vpdarray;
9200
9201 vpdarray = (uint8_t *)vpd;
9202 maxaddr = offsetof(struct vpd_config, vpd_checksum);
9203 checksum = 0;
9204 for (i = offsetof(struct vpd_config, resource_type); i < maxaddr; i++)
9205 checksum = checksum + vpdarray[i];
9206 if (checksum == 0
9207 || (-checksum & 0xFF) != vpd->vpd_checksum)
9208 return (0);
9209
9210 checksum = 0;
9211 maxaddr = offsetof(struct vpd_config, checksum);
9212 for (i = offsetof(struct vpd_config, default_target_flags);
9213 i < maxaddr; i++)
9214 checksum = checksum + vpdarray[i];
9215 if (checksum == 0
9216 || (-checksum & 0xFF) != vpd->checksum)
9217 return (0);
9218 return (1);
9219}
9220
9221int
9222ahd_verify_cksum(struct seeprom_config *sc)
9223{
9224 int i;
9225 int maxaddr;
9226 uint32_t checksum;
9227 uint16_t *scarray;
9228
9229 maxaddr = (sizeof(*sc)/2) - 1;
9230 checksum = 0;
9231 scarray = (uint16_t *)sc;
9232
9233 for (i = 0; i < maxaddr; i++)
9234 checksum = checksum + scarray[i];
9235 if (checksum == 0
9236 || (checksum & 0xFFFF) != sc->checksum) {
9237 return (0);
9238 } else {
9239 return (1);
9240 }
9241}
9242
9243int
9244ahd_acquire_seeprom(struct ahd_softc *ahd)
9245{
9246 /*
9247 * We should be able to determine the SEEPROM type
9248 * from the flexport logic, but unfortunately not
9249 * all implementations have this logic and there is
9250 * no programatic method for determining if the logic
9251 * is present.
9252 */
9253 return (1);
9254#if 0
9255 uint8_t seetype;
9256 int error;
9257
9258 error = ahd_read_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, &seetype);
9259 if (error != 0
9260 || ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE))
9261 return (0);
9262 return (1);
9263#endif
9264}
9265
9266void
9267ahd_release_seeprom(struct ahd_softc *ahd)
9268{
9269 /* Currently a no-op */
9270}
9271
9272int
9273ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value)
9274{
9275 int error;
9276
9277 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9278 if (addr > 7)
9279 panic("ahd_write_flexport: address out of range");
9280 ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
9281 error = ahd_wait_flexport(ahd);
9282 if (error != 0)
9283 return (error);
9284 ahd_outb(ahd, BRDDAT, value);
9285 ahd_flush_device_writes(ahd);
9286 ahd_outb(ahd, BRDCTL, BRDSTB|BRDEN|(addr << 3));
9287 ahd_flush_device_writes(ahd);
9288 ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
9289 ahd_flush_device_writes(ahd);
9290 ahd_outb(ahd, BRDCTL, 0);
9291 ahd_flush_device_writes(ahd);
9292 return (0);
9293}
9294
9295int
9296ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value)
9297{
9298 int error;
9299
9300 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9301 if (addr > 7)
9302 panic("ahd_read_flexport: address out of range");
9303 ahd_outb(ahd, BRDCTL, BRDRW|BRDEN|(addr << 3));
9304 error = ahd_wait_flexport(ahd);
9305 if (error != 0)
9306 return (error);
9307 *value = ahd_inb(ahd, BRDDAT);
9308 ahd_outb(ahd, BRDCTL, 0);
9309 ahd_flush_device_writes(ahd);
9310 return (0);
9311}
9312
9313/*
9314 * Wait at most 2 seconds for flexport arbitration to succeed.
9315 */
9316int
9317ahd_wait_flexport(struct ahd_softc *ahd)
9318{
9319 int cnt;
9320
9321 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9322 cnt = 1000000 * 2 / 5;
9323 while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
9324 ahd_delay(5);
9325
9326 if (cnt == 0)
9327 return (ETIMEDOUT);
9328 return (0);
9329}
9330
9331/************************* Target Mode ****************************************/
9332#ifdef AHD_TARGET_MODE
9333cam_status
9334ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb,
9335 struct ahd_tmode_tstate **tstate,
9336 struct ahd_tmode_lstate **lstate,
9337 int notfound_failure)
9338{
9339
9340 if ((ahd->features & AHD_TARGETMODE) == 0)
9341 return (CAM_REQ_INVALID);
9342
9343 /*
9344 * Handle the 'black hole' device that sucks up
9345 * requests to unattached luns on enabled targets.
9346 */
9347 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
9348 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
9349 *tstate = NULL;
9350 *lstate = ahd->black_hole;
9351 } else {
9352 u_int max_id;
9353
9354 max_id = (ahd->features & AHD_WIDE) ? 15 : 7;
9355 if (ccb->ccb_h.target_id > max_id)
9356 return (CAM_TID_INVALID);
9357
9358 if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS)
9359 return (CAM_LUN_INVALID);
9360
9361 *tstate = ahd->enabled_targets[ccb->ccb_h.target_id];
9362 *lstate = NULL;
9363 if (*tstate != NULL)
9364 *lstate =
9365 (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
9366 }
9367
9368 if (notfound_failure != 0 && *lstate == NULL)
9369 return (CAM_PATH_INVALID);
9370
9371 return (CAM_REQ_CMP);
9372}
9373
9374void
9375ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
9376{
9377#if NOT_YET
9378 struct ahd_tmode_tstate *tstate;
9379 struct ahd_tmode_lstate *lstate;
9380 struct ccb_en_lun *cel;
9381 cam_status status;
9382 u_int target;
9383 u_int lun;
9384 u_int target_mask;
9385 u_long s;
9386 char channel;
9387
9388 status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, &lstate,
9389 /*notfound_failure*/FALSE);
9390
9391 if (status != CAM_REQ_CMP) {
9392 ccb->ccb_h.status = status;
9393 return;
9394 }
9395
9396 if ((ahd->features & AHD_MULTIROLE) != 0) {
9397 u_int our_id;
9398
9399 our_id = ahd->our_id;
9400 if (ccb->ccb_h.target_id != our_id) {
9401 if ((ahd->features & AHD_MULTI_TID) != 0
9402 && (ahd->flags & AHD_INITIATORROLE) != 0) {
9403 /*
9404 * Only allow additional targets if
9405 * the initiator role is disabled.
9406 * The hardware cannot handle a re-select-in
9407 * on the initiator id during a re-select-out
9408 * on a different target id.
9409 */
9410 status = CAM_TID_INVALID;
9411 } else if ((ahd->flags & AHD_INITIATORROLE) != 0
9412 || ahd->enabled_luns > 0) {
9413 /*
9414 * Only allow our target id to change
9415 * if the initiator role is not configured
9416 * and there are no enabled luns which
9417 * are attached to the currently registered
9418 * scsi id.
9419 */
9420 status = CAM_TID_INVALID;
9421 }
9422 }
9423 }
9424
9425 if (status != CAM_REQ_CMP) {
9426 ccb->ccb_h.status = status;
9427 return;
9428 }
9429
9430 /*
9431 * We now have an id that is valid.
9432 * If we aren't in target mode, switch modes.
9433 */
9434 if ((ahd->flags & AHD_TARGETROLE) == 0
9435 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
9436 u_long s;
9437
9438 printf("Configuring Target Mode\n");
9439 ahd_lock(ahd, &s);
9440 if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
9441 ccb->ccb_h.status = CAM_BUSY;
9442 ahd_unlock(ahd, &s);
9443 return;
9444 }
9445 ahd->flags |= AHD_TARGETROLE;
9446 if ((ahd->features & AHD_MULTIROLE) == 0)
9447 ahd->flags &= ~AHD_INITIATORROLE;
9448 ahd_pause(ahd);
9449 ahd_loadseq(ahd);
9450 ahd_restart(ahd);
9451 ahd_unlock(ahd, &s);
9452 }
9453 cel = &ccb->cel;
9454 target = ccb->ccb_h.target_id;
9455 lun = ccb->ccb_h.target_lun;
9456 channel = SIM_CHANNEL(ahd, sim);
9457 target_mask = 0x01 << target;
9458 if (channel == 'B')
9459 target_mask <<= 8;
9460
9461 if (cel->enable != 0) {
9462 u_int scsiseq1;
9463
9464 /* Are we already enabled?? */
9465 if (lstate != NULL) {
9466 xpt_print_path(ccb->ccb_h.path);
9467 printf("Lun already enabled\n");
9468 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
9469 return;
9470 }
9471
9472 if (cel->grp6_len != 0
9473 || cel->grp7_len != 0) {
9474 /*
9475 * Don't (yet?) support vendor
9476 * specific commands.
9477 */
9478 ccb->ccb_h.status = CAM_REQ_INVALID;
9479 printf("Non-zero Group Codes\n");
9480 return;
9481 }
9482
9483 /*
9484 * Seems to be okay.
9485 * Setup our data structures.
9486 */
9487 if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
9488 tstate = ahd_alloc_tstate(ahd, target, channel);
9489 if (tstate == NULL) {
9490 xpt_print_path(ccb->ccb_h.path);
9491 printf("Couldn't allocate tstate\n");
9492 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
9493 return;
9494 }
9495 }
9496 lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
9497 if (lstate == NULL) {
9498 xpt_print_path(ccb->ccb_h.path);
9499 printf("Couldn't allocate lstate\n");
9500 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
9501 return;
9502 }
9503 memset(lstate, 0, sizeof(*lstate));
9504 status = xpt_create_path(&lstate->path, /*periph*/NULL,
9505 xpt_path_path_id(ccb->ccb_h.path),
9506 xpt_path_target_id(ccb->ccb_h.path),
9507 xpt_path_lun_id(ccb->ccb_h.path));
9508 if (status != CAM_REQ_CMP) {
9509 free(lstate, M_DEVBUF);
9510 xpt_print_path(ccb->ccb_h.path);
9511 printf("Couldn't allocate path\n");
9512 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
9513 return;
9514 }
9515 SLIST_INIT(&lstate->accept_tios);
9516 SLIST_INIT(&lstate->immed_notifies);
9517 ahd_lock(ahd, &s);
9518 ahd_pause(ahd);
9519 if (target != CAM_TARGET_WILDCARD) {
9520 tstate->enabled_luns[lun] = lstate;
9521 ahd->enabled_luns++;
9522
9523 if ((ahd->features & AHD_MULTI_TID) != 0) {
9524 u_int targid_mask;
9525
9526 targid_mask = ahd_inb(ahd, TARGID)
9527 | (ahd_inb(ahd, TARGID + 1) << 8);
9528
9529 targid_mask |= target_mask;
9530 ahd_outb(ahd, TARGID, targid_mask);
9531 ahd_outb(ahd, TARGID+1, (targid_mask >> 8));
9532
9533 ahd_update_scsiid(ahd, targid_mask);
9534 } else {
9535 u_int our_id;
9536 char channel;
9537
9538 channel = SIM_CHANNEL(ahd, sim);
9539 our_id = SIM_SCSI_ID(ahd, sim);
9540
9541 /*
9542 * This can only happen if selections
9543 * are not enabled
9544 */
9545 if (target != our_id) {
9546 u_int sblkctl;
9547 char cur_channel;
9548 int swap;
9549
9550 sblkctl = ahd_inb(ahd, SBLKCTL);
9551 cur_channel = (sblkctl & SELBUSB)
9552 ? 'B' : 'A';
9553 if ((ahd->features & AHD_TWIN) == 0)
9554 cur_channel = 'A';
9555 swap = cur_channel != channel;
9556 ahd->our_id = target;
9557
9558 if (swap)
9559 ahd_outb(ahd, SBLKCTL,
9560 sblkctl ^ SELBUSB);
9561
9562 ahd_outb(ahd, SCSIID, target);
9563
9564 if (swap)
9565 ahd_outb(ahd, SBLKCTL, sblkctl);
9566 }
9567 }
9568 } else
9569 ahd->black_hole = lstate;
9570 /* Allow select-in operations */
9571 if (ahd->black_hole != NULL && ahd->enabled_luns > 0) {
9572 scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
9573 scsiseq1 |= ENSELI;
9574 ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
9575 scsiseq1 = ahd_inb(ahd, SCSISEQ1);
9576 scsiseq1 |= ENSELI;
9577 ahd_outb(ahd, SCSISEQ1, scsiseq1);
9578 }
9579 ahd_unpause(ahd);
9580 ahd_unlock(ahd, &s);
9581 ccb->ccb_h.status = CAM_REQ_CMP;
9582 xpt_print_path(ccb->ccb_h.path);
9583 printf("Lun now enabled for target mode\n");
9584 } else {
9585 struct scb *scb;
9586 int i, empty;
9587
9588 if (lstate == NULL) {
9589 ccb->ccb_h.status = CAM_LUN_INVALID;
9590 return;
9591 }
9592
9593 ahd_lock(ahd, &s);
9594
9595 ccb->ccb_h.status = CAM_REQ_CMP;
9596 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
9597 struct ccb_hdr *ccbh;
9598
9599 ccbh = &scb->io_ctx->ccb_h;
9600 if (ccbh->func_code == XPT_CONT_TARGET_IO
9601 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
9602 printf("CTIO pending\n");
9603 ccb->ccb_h.status = CAM_REQ_INVALID;
9604 ahd_unlock(ahd, &s);
9605 return;
9606 }
9607 }
9608
9609 if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
9610 printf("ATIOs pending\n");
9611 ccb->ccb_h.status = CAM_REQ_INVALID;
9612 }
9613
9614 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
9615 printf("INOTs pending\n");
9616 ccb->ccb_h.status = CAM_REQ_INVALID;
9617 }
9618
9619 if (ccb->ccb_h.status != CAM_REQ_CMP) {
9620 ahd_unlock(ahd, &s);
9621 return;
9622 }
9623
9624 xpt_print_path(ccb->ccb_h.path);
9625 printf("Target mode disabled\n");
9626 xpt_free_path(lstate->path);
9627 free(lstate, M_DEVBUF);
9628
9629 ahd_pause(ahd);
9630 /* Can we clean up the target too? */
9631 if (target != CAM_TARGET_WILDCARD) {
9632 tstate->enabled_luns[lun] = NULL;
9633 ahd->enabled_luns--;
9634 for (empty = 1, i = 0; i < 8; i++)
9635 if (tstate->enabled_luns[i] != NULL) {
9636 empty = 0;
9637 break;
9638 }
9639
9640 if (empty) {
9641 ahd_free_tstate(ahd, target, channel,
9642 /*force*/FALSE);
9643 if (ahd->features & AHD_MULTI_TID) {
9644 u_int targid_mask;
9645
9646 targid_mask = ahd_inb(ahd, TARGID)
9647 | (ahd_inb(ahd, TARGID + 1)
9648 << 8);
9649
9650 targid_mask &= ~target_mask;
9651 ahd_outb(ahd, TARGID, targid_mask);
9652 ahd_outb(ahd, TARGID+1,
9653 (targid_mask >> 8));
9654 ahd_update_scsiid(ahd, targid_mask);
9655 }
9656 }
9657 } else {
9658
9659 ahd->black_hole = NULL;
9660
9661 /*
9662 * We can't allow selections without
9663 * our black hole device.
9664 */
9665 empty = TRUE;
9666 }
9667 if (ahd->enabled_luns == 0) {
9668 /* Disallow select-in */
9669 u_int scsiseq1;
9670
9671 scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
9672 scsiseq1 &= ~ENSELI;
9673 ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
9674 scsiseq1 = ahd_inb(ahd, SCSISEQ1);
9675 scsiseq1 &= ~ENSELI;
9676 ahd_outb(ahd, SCSISEQ1, scsiseq1);
9677
9678 if ((ahd->features & AHD_MULTIROLE) == 0) {
9679 printf("Configuring Initiator Mode\n");
9680 ahd->flags &= ~AHD_TARGETROLE;
9681 ahd->flags |= AHD_INITIATORROLE;
9682 ahd_pause(ahd);
9683 ahd_loadseq(ahd);
9684 ahd_restart(ahd);
9685 /*
9686 * Unpaused. The extra unpause
9687 * that follows is harmless.
9688 */
9689 }
9690 }
9691 ahd_unpause(ahd);
9692 ahd_unlock(ahd, &s);
9693 }
9694#endif
9695}
9696
9697static void
9698ahd_update_scsiid(struct ahd_softc *ahd, u_int targid_mask)
9699{
9700#if NOT_YET
9701 u_int scsiid_mask;
9702 u_int scsiid;
9703
9704 if ((ahd->features & AHD_MULTI_TID) == 0)
9705 panic("ahd_update_scsiid called on non-multitid unit\n");
9706
9707 /*
9708 * Since we will rely on the TARGID mask
9709 * for selection enables, ensure that OID
9710 * in SCSIID is not set to some other ID
9711 * that we don't want to allow selections on.
9712 */
9713 if ((ahd->features & AHD_ULTRA2) != 0)
9714 scsiid = ahd_inb(ahd, SCSIID_ULTRA2);
9715 else
9716 scsiid = ahd_inb(ahd, SCSIID);
9717 scsiid_mask = 0x1 << (scsiid & OID);
9718 if ((targid_mask & scsiid_mask) == 0) {
9719 u_int our_id;
9720
9721 /* ffs counts from 1 */
9722 our_id = ffs(targid_mask);
9723 if (our_id == 0)
9724 our_id = ahd->our_id;
9725 else
9726 our_id--;
9727 scsiid &= TID;
9728 scsiid |= our_id;
9729 }
9730 if ((ahd->features & AHD_ULTRA2) != 0)
9731 ahd_outb(ahd, SCSIID_ULTRA2, scsiid);
9732 else
9733 ahd_outb(ahd, SCSIID, scsiid);
9734#endif
9735}
9736
9737void
9738ahd_run_tqinfifo(struct ahd_softc *ahd, int paused)
9739{
9740 struct target_cmd *cmd;
9741
9742 ahd_sync_tqinfifo(ahd, BUS_DMASYNC_POSTREAD);
9743 while ((cmd = &ahd->targetcmds[ahd->tqinfifonext])->cmd_valid != 0) {
9744
9745 /*
9746 * Only advance through the queue if we
9747 * have the resources to process the command.
9748 */
9749 if (ahd_handle_target_cmd(ahd, cmd) != 0)
9750 break;
9751
9752 cmd->cmd_valid = 0;
9753 ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
9754 ahd->shared_data_dmamap,
9755 ahd_targetcmd_offset(ahd, ahd->tqinfifonext),
9756 sizeof(struct target_cmd),
9757 BUS_DMASYNC_PREREAD);
9758 ahd->tqinfifonext++;
9759
9760 /*
9761 * Lazily update our position in the target mode incoming
9762 * command queue as seen by the sequencer.
9763 */
9764 if ((ahd->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
9765 u_int hs_mailbox;
9766
9767 hs_mailbox = ahd_inb(ahd, HS_MAILBOX);
9768 hs_mailbox &= ~HOST_TQINPOS;
9769 hs_mailbox |= ahd->tqinfifonext & HOST_TQINPOS;
9770 ahd_outb(ahd, HS_MAILBOX, hs_mailbox);
9771 }
9772 }
9773}
9774
9775static int
9776ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd)
9777{
9778 struct ahd_tmode_tstate *tstate;
9779 struct ahd_tmode_lstate *lstate;
9780 struct ccb_accept_tio *atio;
9781 uint8_t *byte;
9782 int initiator;
9783 int target;
9784 int lun;
9785
9786 initiator = SCSIID_TARGET(ahd, cmd->scsiid);
9787 target = SCSIID_OUR_ID(cmd->scsiid);
9788 lun = (cmd->identify & MSG_IDENTIFY_LUNMASK);
9789
9790 byte = cmd->bytes;
9791 tstate = ahd->enabled_targets[target];
9792 lstate = NULL;
9793 if (tstate != NULL)
9794 lstate = tstate->enabled_luns[lun];
9795
9796 /*
9797 * Commands for disabled luns go to the black hole driver.
9798 */
9799 if (lstate == NULL)
9800 lstate = ahd->black_hole;
9801
9802 atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
9803 if (atio == NULL) {
9804 ahd->flags |= AHD_TQINFIFO_BLOCKED;
9805 /*
9806 * Wait for more ATIOs from the peripheral driver for this lun.
9807 */
9808 return (1);
9809 } else
9810 ahd->flags &= ~AHD_TQINFIFO_BLOCKED;
9811#ifdef AHD_DEBUG
9812 if ((ahd_debug & AHD_SHOW_TQIN) != 0)
9813 printf("Incoming command from %d for %d:%d%s\n",
9814 initiator, target, lun,
9815 lstate == ahd->black_hole ? "(Black Holed)" : "");
9816#endif
9817 SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
9818
9819 if (lstate == ahd->black_hole) {
9820 /* Fill in the wildcards */
9821 atio->ccb_h.target_id = target;
9822 atio->ccb_h.target_lun = lun;
9823 }
9824
9825 /*
9826 * Package it up and send it off to
9827 * whomever has this lun enabled.
9828 */
9829 atio->sense_len = 0;
9830 atio->init_id = initiator;
9831 if (byte[0] != 0xFF) {
9832 /* Tag was included */
9833 atio->tag_action = *byte++;
9834 atio->tag_id = *byte++;
9835 atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
9836 } else {
9837 atio->ccb_h.flags = 0;
9838 }
9839 byte++;
9840
9841 /* Okay. Now determine the cdb size based on the command code */
9842 switch (*byte >> CMD_GROUP_CODE_SHIFT) {
9843 case 0:
9844 atio->cdb_len = 6;
9845 break;
9846 case 1:
9847 case 2:
9848 atio->cdb_len = 10;
9849 break;
9850 case 4:
9851 atio->cdb_len = 16;
9852 break;
9853 case 5:
9854 atio->cdb_len = 12;
9855 break;
9856 case 3:
9857 default:
9858 /* Only copy the opcode. */
9859 atio->cdb_len = 1;
9860 printf("Reserved or VU command code type encountered\n");
9861 break;
9862 }
9863
9864 memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
9865
9866 atio->ccb_h.status |= CAM_CDB_RECVD;
9867
9868 if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
9869 /*
9870 * We weren't allowed to disconnect.
9871 * We're hanging on the bus until a
9872 * continue target I/O comes in response
9873 * to this accept tio.
9874 */
9875#ifdef AHD_DEBUG
9876 if ((ahd_debug & AHD_SHOW_TQIN) != 0)
9877 printf("Received Immediate Command %d:%d:%d - %p\n",
9878 initiator, target, lun, ahd->pending_device);
9879#endif
9880 ahd->pending_device = lstate;
9881 ahd_freeze_ccb((union ccb *)atio);
9882 atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
9883 }
9884 xpt_done((union ccb*)atio);
9885 return (0);
9886}
9887
9888#endif
diff --git a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h
new file mode 100644
index 000000000000..d80bc5161fb1
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_inline.h
@@ -0,0 +1,965 @@
1/*
2 * Inline routines shareable across OS platforms.
3 *
4 * Copyright (c) 1994-2001 Justin T. Gibbs.
5 * Copyright (c) 2000-2003 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#51 $
41 *
42 * $FreeBSD$
43 */
44
45#ifndef _AIC79XX_INLINE_H_
46#define _AIC79XX_INLINE_H_
47
48/******************************** Debugging ***********************************/
49static __inline char *ahd_name(struct ahd_softc *ahd);
50
51static __inline char *
52ahd_name(struct ahd_softc *ahd)
53{
54 return (ahd->name);
55}
56
57/************************ Sequencer Execution Control *************************/
58static __inline void ahd_known_modes(struct ahd_softc *ahd,
59 ahd_mode src, ahd_mode dst);
60static __inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd,
61 ahd_mode src,
62 ahd_mode dst);
63static __inline void ahd_extract_mode_state(struct ahd_softc *ahd,
64 ahd_mode_state state,
65 ahd_mode *src, ahd_mode *dst);
66static __inline void ahd_set_modes(struct ahd_softc *ahd, ahd_mode src,
67 ahd_mode dst);
68static __inline void ahd_update_modes(struct ahd_softc *ahd);
69static __inline void ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode,
70 ahd_mode dstmode, const char *file,
71 int line);
72static __inline ahd_mode_state ahd_save_modes(struct ahd_softc *ahd);
73static __inline void ahd_restore_modes(struct ahd_softc *ahd,
74 ahd_mode_state state);
75static __inline int ahd_is_paused(struct ahd_softc *ahd);
76static __inline void ahd_pause(struct ahd_softc *ahd);
77static __inline void ahd_unpause(struct ahd_softc *ahd);
78
79static __inline void
80ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
81{
82 ahd->src_mode = src;
83 ahd->dst_mode = dst;
84 ahd->saved_src_mode = src;
85 ahd->saved_dst_mode = dst;
86}
87
88static __inline ahd_mode_state
89ahd_build_mode_state(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
90{
91 return ((src << SRC_MODE_SHIFT) | (dst << DST_MODE_SHIFT));
92}
93
94static __inline void
95ahd_extract_mode_state(struct ahd_softc *ahd, ahd_mode_state state,
96 ahd_mode *src, ahd_mode *dst)
97{
98 *src = (state & SRC_MODE) >> SRC_MODE_SHIFT;
99 *dst = (state & DST_MODE) >> DST_MODE_SHIFT;
100}
101
102static __inline void
103ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
104{
105 if (ahd->src_mode == src && ahd->dst_mode == dst)
106 return;
107#ifdef AHD_DEBUG
108 if (ahd->src_mode == AHD_MODE_UNKNOWN
109 || ahd->dst_mode == AHD_MODE_UNKNOWN)
110 panic("Setting mode prior to saving it.\n");
111 if ((ahd_debug & AHD_SHOW_MODEPTR) != 0)
112 printf("%s: Setting mode 0x%x\n", ahd_name(ahd),
113 ahd_build_mode_state(ahd, src, dst));
114#endif
115 ahd_outb(ahd, MODE_PTR, ahd_build_mode_state(ahd, src, dst));
116 ahd->src_mode = src;
117 ahd->dst_mode = dst;
118}
119
120static __inline void
121ahd_update_modes(struct ahd_softc *ahd)
122{
123 ahd_mode_state mode_ptr;
124 ahd_mode src;
125 ahd_mode dst;
126
127 mode_ptr = ahd_inb(ahd, MODE_PTR);
128#ifdef AHD_DEBUG
129 if ((ahd_debug & AHD_SHOW_MODEPTR) != 0)
130 printf("Reading mode 0x%x\n", mode_ptr);
131#endif
132 ahd_extract_mode_state(ahd, mode_ptr, &src, &dst);
133 ahd_known_modes(ahd, src, dst);
134}
135
136static __inline void
137ahd_assert_modes(struct ahd_softc *ahd, ahd_mode srcmode,
138 ahd_mode dstmode, const char *file, int line)
139{
140#ifdef AHD_DEBUG
141 if ((srcmode & AHD_MK_MSK(ahd->src_mode)) == 0
142 || (dstmode & AHD_MK_MSK(ahd->dst_mode)) == 0) {
143 panic("%s:%s:%d: Mode assertion failed.\n",
144 ahd_name(ahd), file, line);
145 }
146#endif
147}
148
149static __inline ahd_mode_state
150ahd_save_modes(struct ahd_softc *ahd)
151{
152 if (ahd->src_mode == AHD_MODE_UNKNOWN
153 || ahd->dst_mode == AHD_MODE_UNKNOWN)
154 ahd_update_modes(ahd);
155
156 return (ahd_build_mode_state(ahd, ahd->src_mode, ahd->dst_mode));
157}
158
159static __inline void
160ahd_restore_modes(struct ahd_softc *ahd, ahd_mode_state state)
161{
162 ahd_mode src;
163 ahd_mode dst;
164
165 ahd_extract_mode_state(ahd, state, &src, &dst);
166 ahd_set_modes(ahd, src, dst);
167}
168
169#define AHD_ASSERT_MODES(ahd, source, dest) \
170 ahd_assert_modes(ahd, source, dest, __FILE__, __LINE__);
171
172/*
173 * Determine whether the sequencer has halted code execution.
174 * Returns non-zero status if the sequencer is stopped.
175 */
176static __inline int
177ahd_is_paused(struct ahd_softc *ahd)
178{
179 return ((ahd_inb(ahd, HCNTRL) & PAUSE) != 0);
180}
181
182/*
183 * Request that the sequencer stop and wait, indefinitely, for it
184 * to stop. The sequencer will only acknowledge that it is paused
185 * once it has reached an instruction boundary and PAUSEDIS is
186 * cleared in the SEQCTL register. The sequencer may use PAUSEDIS
187 * for critical sections.
188 */
189static __inline void
190ahd_pause(struct ahd_softc *ahd)
191{
192 ahd_outb(ahd, HCNTRL, ahd->pause);
193
194 /*
195 * Since the sequencer can disable pausing in a critical section, we
196 * must loop until it actually stops.
197 */
198 while (ahd_is_paused(ahd) == 0)
199 ;
200}
201
202/*
203 * Allow the sequencer to continue program execution.
204 * We check here to ensure that no additional interrupt
205 * sources that would cause the sequencer to halt have been
206 * asserted. If, for example, a SCSI bus reset is detected
207 * while we are fielding a different, pausing, interrupt type,
208 * we don't want to release the sequencer before going back
209 * into our interrupt handler and dealing with this new
210 * condition.
211 */
212static __inline void
213ahd_unpause(struct ahd_softc *ahd)
214{
215 /*
216 * Automatically restore our modes to those saved
217 * prior to the first change of the mode.
218 */
219 if (ahd->saved_src_mode != AHD_MODE_UNKNOWN
220 && ahd->saved_dst_mode != AHD_MODE_UNKNOWN) {
221 if ((ahd->flags & AHD_UPDATE_PEND_CMDS) != 0)
222 ahd_reset_cmds_pending(ahd);
223 ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
224 }
225
226 if ((ahd_inb(ahd, INTSTAT) & ~CMDCMPLT) == 0)
227 ahd_outb(ahd, HCNTRL, ahd->unpause);
228
229 ahd_known_modes(ahd, AHD_MODE_UNKNOWN, AHD_MODE_UNKNOWN);
230}
231
232/*********************** Scatter Gather List Handling *************************/
233static __inline void *ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb,
234 void *sgptr, dma_addr_t addr,
235 bus_size_t len, int last);
236static __inline void ahd_setup_scb_common(struct ahd_softc *ahd,
237 struct scb *scb);
238static __inline void ahd_setup_data_scb(struct ahd_softc *ahd,
239 struct scb *scb);
240static __inline void ahd_setup_noxfer_scb(struct ahd_softc *ahd,
241 struct scb *scb);
242
243static __inline void *
244ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb,
245 void *sgptr, dma_addr_t addr, bus_size_t len, int last)
246{
247 scb->sg_count++;
248 if (sizeof(dma_addr_t) > 4
249 && (ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
250 struct ahd_dma64_seg *sg;
251
252 sg = (struct ahd_dma64_seg *)sgptr;
253 sg->addr = ahd_htole64(addr);
254 sg->len = ahd_htole32(len | (last ? AHD_DMA_LAST_SEG : 0));
255 return (sg + 1);
256 } else {
257 struct ahd_dma_seg *sg;
258
259 sg = (struct ahd_dma_seg *)sgptr;
260 sg->addr = ahd_htole32(addr & 0xFFFFFFFF);
261 sg->len = ahd_htole32(len | ((addr >> 8) & 0x7F000000)
262 | (last ? AHD_DMA_LAST_SEG : 0));
263 return (sg + 1);
264 }
265}
266
267static __inline void
268ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb)
269{
270 /* XXX Handle target mode SCBs. */
271 scb->crc_retry_count = 0;
272 if ((scb->flags & SCB_PACKETIZED) != 0) {
273 /* XXX what about ACA?? It is type 4, but TAG_TYPE == 0x3. */
274 scb->hscb->task_attribute = scb->hscb->control & SCB_TAG_TYPE;
275 } else {
276 if (ahd_get_transfer_length(scb) & 0x01)
277 scb->hscb->task_attribute = SCB_XFERLEN_ODD;
278 else
279 scb->hscb->task_attribute = 0;
280 }
281
282 if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR
283 || (scb->hscb->cdb_len & SCB_CDB_LEN_PTR) != 0)
284 scb->hscb->shared_data.idata.cdb_plus_saddr.sense_addr =
285 ahd_htole32(scb->sense_busaddr);
286}
287
288static __inline void
289ahd_setup_data_scb(struct ahd_softc *ahd, struct scb *scb)
290{
291 /*
292 * Copy the first SG into the "current" data ponter area.
293 */
294 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
295 struct ahd_dma64_seg *sg;
296
297 sg = (struct ahd_dma64_seg *)scb->sg_list;
298 scb->hscb->dataptr = sg->addr;
299 scb->hscb->datacnt = sg->len;
300 } else {
301 struct ahd_dma_seg *sg;
302 uint32_t *dataptr_words;
303
304 sg = (struct ahd_dma_seg *)scb->sg_list;
305 dataptr_words = (uint32_t*)&scb->hscb->dataptr;
306 dataptr_words[0] = sg->addr;
307 dataptr_words[1] = 0;
308 if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
309 uint64_t high_addr;
310
311 high_addr = ahd_le32toh(sg->len) & 0x7F000000;
312 scb->hscb->dataptr |= ahd_htole64(high_addr << 8);
313 }
314 scb->hscb->datacnt = sg->len;
315 }
316 /*
317 * Note where to find the SG entries in bus space.
318 * We also set the full residual flag which the
319 * sequencer will clear as soon as a data transfer
320 * occurs.
321 */
322 scb->hscb->sgptr = ahd_htole32(scb->sg_list_busaddr|SG_FULL_RESID);
323}
324
325static __inline void
326ahd_setup_noxfer_scb(struct ahd_softc *ahd, struct scb *scb)
327{
328 scb->hscb->sgptr = ahd_htole32(SG_LIST_NULL);
329 scb->hscb->dataptr = 0;
330 scb->hscb->datacnt = 0;
331}
332
333/************************** Memory mapping routines ***************************/
334static __inline size_t ahd_sg_size(struct ahd_softc *ahd);
335static __inline void *
336 ahd_sg_bus_to_virt(struct ahd_softc *ahd,
337 struct scb *scb,
338 uint32_t sg_busaddr);
339static __inline uint32_t
340 ahd_sg_virt_to_bus(struct ahd_softc *ahd,
341 struct scb *scb,
342 void *sg);
343static __inline void ahd_sync_scb(struct ahd_softc *ahd,
344 struct scb *scb, int op);
345static __inline void ahd_sync_sglist(struct ahd_softc *ahd,
346 struct scb *scb, int op);
347static __inline void ahd_sync_sense(struct ahd_softc *ahd,
348 struct scb *scb, int op);
349static __inline uint32_t
350 ahd_targetcmd_offset(struct ahd_softc *ahd,
351 u_int index);
352
353static __inline size_t
354ahd_sg_size(struct ahd_softc *ahd)
355{
356 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
357 return (sizeof(struct ahd_dma64_seg));
358 return (sizeof(struct ahd_dma_seg));
359}
360
361static __inline void *
362ahd_sg_bus_to_virt(struct ahd_softc *ahd, struct scb *scb, uint32_t sg_busaddr)
363{
364 dma_addr_t sg_offset;
365
366 /* sg_list_phys points to entry 1, not 0 */
367 sg_offset = sg_busaddr - (scb->sg_list_busaddr - ahd_sg_size(ahd));
368 return ((uint8_t *)scb->sg_list + sg_offset);
369}
370
371static __inline uint32_t
372ahd_sg_virt_to_bus(struct ahd_softc *ahd, struct scb *scb, void *sg)
373{
374 dma_addr_t sg_offset;
375
376 /* sg_list_phys points to entry 1, not 0 */
377 sg_offset = ((uint8_t *)sg - (uint8_t *)scb->sg_list)
378 - ahd_sg_size(ahd);
379
380 return (scb->sg_list_busaddr + sg_offset);
381}
382
383static __inline void
384ahd_sync_scb(struct ahd_softc *ahd, struct scb *scb, int op)
385{
386 ahd_dmamap_sync(ahd, ahd->scb_data.hscb_dmat,
387 scb->hscb_map->dmamap,
388 /*offset*/(uint8_t*)scb->hscb - scb->hscb_map->vaddr,
389 /*len*/sizeof(*scb->hscb), op);
390}
391
392static __inline void
393ahd_sync_sglist(struct ahd_softc *ahd, struct scb *scb, int op)
394{
395 if (scb->sg_count == 0)
396 return;
397
398 ahd_dmamap_sync(ahd, ahd->scb_data.sg_dmat,
399 scb->sg_map->dmamap,
400 /*offset*/scb->sg_list_busaddr - ahd_sg_size(ahd),
401 /*len*/ahd_sg_size(ahd) * scb->sg_count, op);
402}
403
404static __inline void
405ahd_sync_sense(struct ahd_softc *ahd, struct scb *scb, int op)
406{
407 ahd_dmamap_sync(ahd, ahd->scb_data.sense_dmat,
408 scb->sense_map->dmamap,
409 /*offset*/scb->sense_busaddr,
410 /*len*/AHD_SENSE_BUFSIZE, op);
411}
412
413static __inline uint32_t
414ahd_targetcmd_offset(struct ahd_softc *ahd, u_int index)
415{
416 return (((uint8_t *)&ahd->targetcmds[index])
417 - (uint8_t *)ahd->qoutfifo);
418}
419
420/*********************** Miscelaneous Support Functions ***********************/
421static __inline void ahd_complete_scb(struct ahd_softc *ahd,
422 struct scb *scb);
423static __inline void ahd_update_residual(struct ahd_softc *ahd,
424 struct scb *scb);
425static __inline struct ahd_initiator_tinfo *
426 ahd_fetch_transinfo(struct ahd_softc *ahd,
427 char channel, u_int our_id,
428 u_int remote_id,
429 struct ahd_tmode_tstate **tstate);
430static __inline uint16_t
431 ahd_inw(struct ahd_softc *ahd, u_int port);
432static __inline void ahd_outw(struct ahd_softc *ahd, u_int port,
433 u_int value);
434static __inline uint32_t
435 ahd_inl(struct ahd_softc *ahd, u_int port);
436static __inline void ahd_outl(struct ahd_softc *ahd, u_int port,
437 uint32_t value);
438static __inline uint64_t
439 ahd_inq(struct ahd_softc *ahd, u_int port);
440static __inline void ahd_outq(struct ahd_softc *ahd, u_int port,
441 uint64_t value);
442static __inline u_int ahd_get_scbptr(struct ahd_softc *ahd);
443static __inline void ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr);
444static __inline u_int ahd_get_hnscb_qoff(struct ahd_softc *ahd);
445static __inline void ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value);
446static __inline u_int ahd_get_hescb_qoff(struct ahd_softc *ahd);
447static __inline void ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value);
448static __inline u_int ahd_get_snscb_qoff(struct ahd_softc *ahd);
449static __inline void ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value);
450static __inline u_int ahd_get_sescb_qoff(struct ahd_softc *ahd);
451static __inline void ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value);
452static __inline u_int ahd_get_sdscb_qoff(struct ahd_softc *ahd);
453static __inline void ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value);
454static __inline u_int ahd_inb_scbram(struct ahd_softc *ahd, u_int offset);
455static __inline u_int ahd_inw_scbram(struct ahd_softc *ahd, u_int offset);
456static __inline uint32_t
457 ahd_inl_scbram(struct ahd_softc *ahd, u_int offset);
458static __inline uint64_t
459 ahd_inq_scbram(struct ahd_softc *ahd, u_int offset);
460static __inline void ahd_swap_with_next_hscb(struct ahd_softc *ahd,
461 struct scb *scb);
462static __inline void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb);
463static __inline uint8_t *
464 ahd_get_sense_buf(struct ahd_softc *ahd,
465 struct scb *scb);
466static __inline uint32_t
467 ahd_get_sense_bufaddr(struct ahd_softc *ahd,
468 struct scb *scb);
469
470static __inline void
471ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb)
472{
473 uint32_t sgptr;
474
475 sgptr = ahd_le32toh(scb->hscb->sgptr);
476 if ((sgptr & SG_STATUS_VALID) != 0)
477 ahd_handle_scb_status(ahd, scb);
478 else
479 ahd_done(ahd, scb);
480}
481
482/*
483 * Determine whether the sequencer reported a residual
484 * for this SCB/transaction.
485 */
486static __inline void
487ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
488{
489 uint32_t sgptr;
490
491 sgptr = ahd_le32toh(scb->hscb->sgptr);
492 if ((sgptr & SG_STATUS_VALID) != 0)
493 ahd_calc_residual(ahd, scb);
494}
495
496/*
497 * Return pointers to the transfer negotiation information
498 * for the specified our_id/remote_id pair.
499 */
500static __inline struct ahd_initiator_tinfo *
501ahd_fetch_transinfo(struct ahd_softc *ahd, char channel, u_int our_id,
502 u_int remote_id, struct ahd_tmode_tstate **tstate)
503{
504 /*
505 * Transfer data structures are stored from the perspective
506 * of the target role. Since the parameters for a connection
507 * in the initiator role to a given target are the same as
508 * when the roles are reversed, we pretend we are the target.
509 */
510 if (channel == 'B')
511 our_id += 8;
512 *tstate = ahd->enabled_targets[our_id];
513 return (&(*tstate)->transinfo[remote_id]);
514}
515
516#define AHD_COPY_COL_IDX(dst, src) \
517do { \
518 dst->hscb->scsiid = src->hscb->scsiid; \
519 dst->hscb->lun = src->hscb->lun; \
520} while (0)
521
522static __inline uint16_t
523ahd_inw(struct ahd_softc *ahd, u_int port)
524{
525 return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port));
526}
527
528static __inline void
529ahd_outw(struct ahd_softc *ahd, u_int port, u_int value)
530{
531 ahd_outb(ahd, port, value & 0xFF);
532 ahd_outb(ahd, port+1, (value >> 8) & 0xFF);
533}
534
535static __inline uint32_t
536ahd_inl(struct ahd_softc *ahd, u_int port)
537{
538 return ((ahd_inb(ahd, port))
539 | (ahd_inb(ahd, port+1) << 8)
540 | (ahd_inb(ahd, port+2) << 16)
541 | (ahd_inb(ahd, port+3) << 24));
542}
543
544static __inline void
545ahd_outl(struct ahd_softc *ahd, u_int port, uint32_t value)
546{
547 ahd_outb(ahd, port, (value) & 0xFF);
548 ahd_outb(ahd, port+1, ((value) >> 8) & 0xFF);
549 ahd_outb(ahd, port+2, ((value) >> 16) & 0xFF);
550 ahd_outb(ahd, port+3, ((value) >> 24) & 0xFF);
551}
552
553static __inline uint64_t
554ahd_inq(struct ahd_softc *ahd, u_int port)
555{
556 return ((ahd_inb(ahd, port))
557 | (ahd_inb(ahd, port+1) << 8)
558 | (ahd_inb(ahd, port+2) << 16)
559 | (ahd_inb(ahd, port+3) << 24)
560 | (((uint64_t)ahd_inb(ahd, port+4)) << 32)
561 | (((uint64_t)ahd_inb(ahd, port+5)) << 40)
562 | (((uint64_t)ahd_inb(ahd, port+6)) << 48)
563 | (((uint64_t)ahd_inb(ahd, port+7)) << 56));
564}
565
566static __inline void
567ahd_outq(struct ahd_softc *ahd, u_int port, uint64_t value)
568{
569 ahd_outb(ahd, port, value & 0xFF);
570 ahd_outb(ahd, port+1, (value >> 8) & 0xFF);
571 ahd_outb(ahd, port+2, (value >> 16) & 0xFF);
572 ahd_outb(ahd, port+3, (value >> 24) & 0xFF);
573 ahd_outb(ahd, port+4, (value >> 32) & 0xFF);
574 ahd_outb(ahd, port+5, (value >> 40) & 0xFF);
575 ahd_outb(ahd, port+6, (value >> 48) & 0xFF);
576 ahd_outb(ahd, port+7, (value >> 56) & 0xFF);
577}
578
579static __inline u_int
580ahd_get_scbptr(struct ahd_softc *ahd)
581{
582 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
583 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
584 return (ahd_inb(ahd, SCBPTR) | (ahd_inb(ahd, SCBPTR + 1) << 8));
585}
586
587static __inline void
588ahd_set_scbptr(struct ahd_softc *ahd, u_int scbptr)
589{
590 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
591 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
592 ahd_outb(ahd, SCBPTR, scbptr & 0xFF);
593 ahd_outb(ahd, SCBPTR+1, (scbptr >> 8) & 0xFF);
594}
595
596static __inline u_int
597ahd_get_hnscb_qoff(struct ahd_softc *ahd)
598{
599 return (ahd_inw_atomic(ahd, HNSCB_QOFF));
600}
601
602static __inline void
603ahd_set_hnscb_qoff(struct ahd_softc *ahd, u_int value)
604{
605 ahd_outw_atomic(ahd, HNSCB_QOFF, value);
606}
607
608static __inline u_int
609ahd_get_hescb_qoff(struct ahd_softc *ahd)
610{
611 return (ahd_inb(ahd, HESCB_QOFF));
612}
613
614static __inline void
615ahd_set_hescb_qoff(struct ahd_softc *ahd, u_int value)
616{
617 ahd_outb(ahd, HESCB_QOFF, value);
618}
619
620static __inline u_int
621ahd_get_snscb_qoff(struct ahd_softc *ahd)
622{
623 u_int oldvalue;
624
625 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
626 oldvalue = ahd_inw(ahd, SNSCB_QOFF);
627 ahd_outw(ahd, SNSCB_QOFF, oldvalue);
628 return (oldvalue);
629}
630
631static __inline void
632ahd_set_snscb_qoff(struct ahd_softc *ahd, u_int value)
633{
634 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
635 ahd_outw(ahd, SNSCB_QOFF, value);
636}
637
638static __inline u_int
639ahd_get_sescb_qoff(struct ahd_softc *ahd)
640{
641 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
642 return (ahd_inb(ahd, SESCB_QOFF));
643}
644
645static __inline void
646ahd_set_sescb_qoff(struct ahd_softc *ahd, u_int value)
647{
648 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
649 ahd_outb(ahd, SESCB_QOFF, value);
650}
651
652static __inline u_int
653ahd_get_sdscb_qoff(struct ahd_softc *ahd)
654{
655 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
656 return (ahd_inb(ahd, SDSCB_QOFF) | (ahd_inb(ahd, SDSCB_QOFF + 1) << 8));
657}
658
659static __inline void
660ahd_set_sdscb_qoff(struct ahd_softc *ahd, u_int value)
661{
662 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
663 ahd_outb(ahd, SDSCB_QOFF, value & 0xFF);
664 ahd_outb(ahd, SDSCB_QOFF+1, (value >> 8) & 0xFF);
665}
666
667static __inline u_int
668ahd_inb_scbram(struct ahd_softc *ahd, u_int offset)
669{
670 u_int value;
671
672 /*
673 * Workaround PCI-X Rev A. hardware bug.
674 * After a host read of SCB memory, the chip
675 * may become confused into thinking prefetch
676 * was required. This starts the discard timer
677 * running and can cause an unexpected discard
678 * timer interrupt. The work around is to read
679 * a normal register prior to the exhaustion of
680 * the discard timer. The mode pointer register
681 * has no side effects and so serves well for
682 * this purpose.
683 *
684 * Razor #528
685 */
686 value = ahd_inb(ahd, offset);
687 if ((ahd->flags & AHD_PCIX_SCBRAM_RD_BUG) != 0)
688 ahd_inb(ahd, MODE_PTR);
689 return (value);
690}
691
692static __inline u_int
693ahd_inw_scbram(struct ahd_softc *ahd, u_int offset)
694{
695 return (ahd_inb_scbram(ahd, offset)
696 | (ahd_inb_scbram(ahd, offset+1) << 8));
697}
698
699static __inline uint32_t
700ahd_inl_scbram(struct ahd_softc *ahd, u_int offset)
701{
702 return (ahd_inw_scbram(ahd, offset)
703 | (ahd_inw_scbram(ahd, offset+2) << 16));
704}
705
706static __inline uint64_t
707ahd_inq_scbram(struct ahd_softc *ahd, u_int offset)
708{
709 return (ahd_inl_scbram(ahd, offset)
710 | ((uint64_t)ahd_inl_scbram(ahd, offset+4)) << 32);
711}
712
713static __inline struct scb *
714ahd_lookup_scb(struct ahd_softc *ahd, u_int tag)
715{
716 struct scb* scb;
717
718 if (tag >= AHD_SCB_MAX)
719 return (NULL);
720 scb = ahd->scb_data.scbindex[tag];
721 if (scb != NULL)
722 ahd_sync_scb(ahd, scb,
723 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
724 return (scb);
725}
726
727static __inline void
728ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb)
729{
730 struct hardware_scb *q_hscb;
731 uint32_t saved_hscb_busaddr;
732
733 /*
734 * Our queuing method is a bit tricky. The card
735 * knows in advance which HSCB (by address) to download,
736 * and we can't disappoint it. To achieve this, the next
737 * HSCB to download is saved off in ahd->next_queued_hscb.
738 * When we are called to queue "an arbitrary scb",
739 * we copy the contents of the incoming HSCB to the one
740 * the sequencer knows about, swap HSCB pointers and
741 * finally assign the SCB to the tag indexed location
742 * in the scb_array. This makes sure that we can still
743 * locate the correct SCB by SCB_TAG.
744 */
745 q_hscb = ahd->next_queued_hscb;
746 saved_hscb_busaddr = q_hscb->hscb_busaddr;
747 memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
748 q_hscb->hscb_busaddr = saved_hscb_busaddr;
749 q_hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr;
750
751 /* Now swap HSCB pointers. */
752 ahd->next_queued_hscb = scb->hscb;
753 scb->hscb = q_hscb;
754
755 /* Now define the mapping from tag to SCB in the scbindex */
756 ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb;
757}
758
759/*
760 * Tell the sequencer about a new transaction to execute.
761 */
762static __inline void
763ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb)
764{
765 ahd_swap_with_next_hscb(ahd, scb);
766
767 if (SCBID_IS_NULL(SCB_GET_TAG(scb)))
768 panic("Attempt to queue invalid SCB tag %x\n",
769 SCB_GET_TAG(scb));
770
771 /*
772 * Keep a history of SCBs we've downloaded in the qinfifo.
773 */
774 ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb);
775 ahd->qinfifonext++;
776
777 if (scb->sg_count != 0)
778 ahd_setup_data_scb(ahd, scb);
779 else
780 ahd_setup_noxfer_scb(ahd, scb);
781 ahd_setup_scb_common(ahd, scb);
782
783 /*
784 * Make sure our data is consistent from the
785 * perspective of the adapter.
786 */
787 ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
788
789#ifdef AHD_DEBUG
790 if ((ahd_debug & AHD_SHOW_QUEUE) != 0) {
791 uint64_t host_dataptr;
792
793 host_dataptr = ahd_le64toh(scb->hscb->dataptr);
794 printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n",
795 ahd_name(ahd),
796 SCB_GET_TAG(scb), ahd_le32toh(scb->hscb->hscb_busaddr),
797 (u_int)((host_dataptr >> 32) & 0xFFFFFFFF),
798 (u_int)(host_dataptr & 0xFFFFFFFF),
799 ahd_le32toh(scb->hscb->datacnt));
800 }
801#endif
802 /* Tell the adapter about the newly queued SCB */
803 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
804}
805
806static __inline uint8_t *
807ahd_get_sense_buf(struct ahd_softc *ahd, struct scb *scb)
808{
809 return (scb->sense_data);
810}
811
812static __inline uint32_t
813ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb)
814{
815 return (scb->sense_busaddr);
816}
817
818/************************** Interrupt Processing ******************************/
819static __inline void ahd_sync_qoutfifo(struct ahd_softc *ahd, int op);
820static __inline void ahd_sync_tqinfifo(struct ahd_softc *ahd, int op);
821static __inline u_int ahd_check_cmdcmpltqueues(struct ahd_softc *ahd);
822static __inline int ahd_intr(struct ahd_softc *ahd);
823
824static __inline void
825ahd_sync_qoutfifo(struct ahd_softc *ahd, int op)
826{
827 ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,
828 /*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op);
829}
830
831static __inline void
832ahd_sync_tqinfifo(struct ahd_softc *ahd, int op)
833{
834#ifdef AHD_TARGET_MODE
835 if ((ahd->flags & AHD_TARGETROLE) != 0) {
836 ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
837 ahd->shared_data_dmamap,
838 ahd_targetcmd_offset(ahd, 0),
839 sizeof(struct target_cmd) * AHD_TMODE_CMDS,
840 op);
841 }
842#endif
843}
844
845/*
846 * See if the firmware has posted any completed commands
847 * into our in-core command complete fifos.
848 */
849#define AHD_RUN_QOUTFIFO 0x1
850#define AHD_RUN_TQINFIFO 0x2
851static __inline u_int
852ahd_check_cmdcmpltqueues(struct ahd_softc *ahd)
853{
854 u_int retval;
855
856 retval = 0;
857 ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,
858 /*offset*/ahd->qoutfifonext, /*len*/2,
859 BUS_DMASYNC_POSTREAD);
860 if ((ahd->qoutfifo[ahd->qoutfifonext]
861 & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag)
862 retval |= AHD_RUN_QOUTFIFO;
863#ifdef AHD_TARGET_MODE
864 if ((ahd->flags & AHD_TARGETROLE) != 0
865 && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) {
866 ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
867 ahd->shared_data_dmamap,
868 ahd_targetcmd_offset(ahd, ahd->tqinfifofnext),
869 /*len*/sizeof(struct target_cmd),
870 BUS_DMASYNC_POSTREAD);
871 if (ahd->targetcmds[ahd->tqinfifonext].cmd_valid != 0)
872 retval |= AHD_RUN_TQINFIFO;
873 }
874#endif
875 return (retval);
876}
877
878/*
879 * Catch an interrupt from the adapter
880 */
881static __inline int
882ahd_intr(struct ahd_softc *ahd)
883{
884 u_int intstat;
885
886 if ((ahd->pause & INTEN) == 0) {
887 /*
888 * Our interrupt is not enabled on the chip
889 * and may be disabled for re-entrancy reasons,
890 * so just return. This is likely just a shared
891 * interrupt.
892 */
893 return (0);
894 }
895
896 /*
897 * Instead of directly reading the interrupt status register,
898 * infer the cause of the interrupt by checking our in-core
899 * completion queues. This avoids a costly PCI bus read in
900 * most cases.
901 */
902 if ((ahd->flags & AHD_ALL_INTERRUPTS) == 0
903 && (ahd_check_cmdcmpltqueues(ahd) != 0))
904 intstat = CMDCMPLT;
905 else
906 intstat = ahd_inb(ahd, INTSTAT);
907
908 if ((intstat & INT_PEND) == 0)
909 return (0);
910
911 if (intstat & CMDCMPLT) {
912 ahd_outb(ahd, CLRINT, CLRCMDINT);
913
914 /*
915 * Ensure that the chip sees that we've cleared
916 * this interrupt before we walk the output fifo.
917 * Otherwise, we may, due to posted bus writes,
918 * clear the interrupt after we finish the scan,
919 * and after the sequencer has added new entries
920 * and asserted the interrupt again.
921 */
922 if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {
923 if (ahd_is_paused(ahd)) {
924 /*
925 * Potentially lost SEQINT.
926 * If SEQINTCODE is non-zero,
927 * simulate the SEQINT.
928 */
929 if (ahd_inb(ahd, SEQINTCODE) != NO_SEQINT)
930 intstat |= SEQINT;
931 }
932 } else {
933 ahd_flush_device_writes(ahd);
934 }
935 ahd_run_qoutfifo(ahd);
936 ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket]++;
937 ahd->cmdcmplt_total++;
938#ifdef AHD_TARGET_MODE
939 if ((ahd->flags & AHD_TARGETROLE) != 0)
940 ahd_run_tqinfifo(ahd, /*paused*/FALSE);
941#endif
942 }
943
944 /*
945 * Handle statuses that may invalidate our cached
946 * copy of INTSTAT separately.
947 */
948 if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) {
949 /* Hot eject. Do nothing */
950 } else if (intstat & HWERRINT) {
951 ahd_handle_hwerrint(ahd);
952 } else if ((intstat & (PCIINT|SPLTINT)) != 0) {
953 ahd->bus_intr(ahd);
954 } else {
955
956 if ((intstat & SEQINT) != 0)
957 ahd_handle_seqint(ahd, intstat);
958
959 if ((intstat & SCSIINT) != 0)
960 ahd_handle_scsiint(ahd, intstat);
961 }
962 return (1);
963}
964
965#endif /* _AIC79XX_INLINE_H_ */
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
new file mode 100644
index 000000000000..fb2877c303f0
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -0,0 +1,5017 @@
1/*
2 * Adaptec AIC79xx device driver for Linux.
3 *
4 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#171 $
5 *
6 * --------------------------------------------------------------------------
7 * Copyright (c) 1994-2000 Justin T. Gibbs.
8 * Copyright (c) 1997-1999 Doug Ledford
9 * Copyright (c) 2000-2003 Adaptec Inc.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include "aic79xx_osm.h"
46#include "aic79xx_inline.h"
47#include <scsi/scsicam.h>
48
49/*
50 * Include aiclib.c as part of our
51 * "module dependencies are hard" work around.
52 */
53#include "aiclib.c"
54
55#include <linux/init.h> /* __setup */
56
57#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
58#include "sd.h" /* For geometry detection */
59#endif
60
61#include <linux/mm.h> /* For fetching system memory size */
62#include <linux/delay.h> /* For ssleep/msleep */
63
64/*
65 * Lock protecting manipulation of the ahd softc list.
66 */
67spinlock_t ahd_list_spinlock;
68
69#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
70/* For dynamic sglist size calculation. */
71u_int ahd_linux_nseg;
72#endif
73
74/*
75 * Bucket size for counting good commands in between bad ones.
76 */
77#define AHD_LINUX_ERR_THRESH 1000
78
79/*
80 * Set this to the delay in seconds after SCSI bus reset.
81 * Note, we honor this only for the initial bus reset.
82 * The scsi error recovery code performs its own bus settle
83 * delay handling for error recovery actions.
84 */
85#ifdef CONFIG_AIC79XX_RESET_DELAY_MS
86#define AIC79XX_RESET_DELAY CONFIG_AIC79XX_RESET_DELAY_MS
87#else
88#define AIC79XX_RESET_DELAY 5000
89#endif
90
91/*
92 * To change the default number of tagged transactions allowed per-device,
93 * add a line to the lilo.conf file like:
94 * append="aic79xx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}"
95 * which will result in the first four devices on the first two
96 * controllers being set to a tagged queue depth of 32.
97 *
98 * The tag_commands is an array of 16 to allow for wide and twin adapters.
99 * Twin adapters will use indexes 0-7 for channel 0, and indexes 8-15
100 * for channel 1.
101 */
102typedef struct {
103 uint16_t tag_commands[16]; /* Allow for wide/twin adapters. */
104} adapter_tag_info_t;
105
106/*
107 * Modify this as you see fit for your system.
108 *
109 * 0 tagged queuing disabled
110 * 1 <= n <= 253 n == max tags ever dispatched.
111 *
112 * The driver will throttle the number of commands dispatched to a
113 * device if it returns queue full. For devices with a fixed maximum
114 * queue depth, the driver will eventually determine this depth and
115 * lock it in (a console message is printed to indicate that a lock
116 * has occurred). On some devices, queue full is returned for a temporary
117 * resource shortage. These devices will return queue full at varying
118 * depths. The driver will throttle back when the queue fulls occur and
119 * attempt to slowly increase the depth over time as the device recovers
120 * from the resource shortage.
121 *
122 * In this example, the first line will disable tagged queueing for all
123 * the devices on the first probed aic79xx adapter.
124 *
125 * The second line enables tagged queueing with 4 commands/LUN for IDs
126 * (0, 2-11, 13-15), disables tagged queueing for ID 12, and tells the
127 * driver to attempt to use up to 64 tags for ID 1.
128 *
129 * The third line is the same as the first line.
130 *
131 * The fourth line disables tagged queueing for devices 0 and 3. It
132 * enables tagged queueing for the other IDs, with 16 commands/LUN
133 * for IDs 1 and 4, 127 commands/LUN for ID 8, and 4 commands/LUN for
134 * IDs 2, 5-7, and 9-15.
135 */
136
137/*
138 * NOTE: The below structure is for reference only, the actual structure
139 * to modify in order to change things is just below this comment block.
140adapter_tag_info_t aic79xx_tag_info[] =
141{
142 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
143 {{4, 64, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4}},
144 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
145 {{0, 16, 4, 0, 16, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4}}
146};
147*/
148
149#ifdef CONFIG_AIC79XX_CMDS_PER_DEVICE
150#define AIC79XX_CMDS_PER_DEVICE CONFIG_AIC79XX_CMDS_PER_DEVICE
151#else
152#define AIC79XX_CMDS_PER_DEVICE AHD_MAX_QUEUE
153#endif
154
155#define AIC79XX_CONFIGED_TAG_COMMANDS { \
156 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
157 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
158 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
159 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
160 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
161 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
162 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
163 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE \
164}
165
166/*
167 * By default, use the number of commands specified by
168 * the users kernel configuration.
169 */
170static adapter_tag_info_t aic79xx_tag_info[] =
171{
172 {AIC79XX_CONFIGED_TAG_COMMANDS},
173 {AIC79XX_CONFIGED_TAG_COMMANDS},
174 {AIC79XX_CONFIGED_TAG_COMMANDS},
175 {AIC79XX_CONFIGED_TAG_COMMANDS},
176 {AIC79XX_CONFIGED_TAG_COMMANDS},
177 {AIC79XX_CONFIGED_TAG_COMMANDS},
178 {AIC79XX_CONFIGED_TAG_COMMANDS},
179 {AIC79XX_CONFIGED_TAG_COMMANDS},
180 {AIC79XX_CONFIGED_TAG_COMMANDS},
181 {AIC79XX_CONFIGED_TAG_COMMANDS},
182 {AIC79XX_CONFIGED_TAG_COMMANDS},
183 {AIC79XX_CONFIGED_TAG_COMMANDS},
184 {AIC79XX_CONFIGED_TAG_COMMANDS},
185 {AIC79XX_CONFIGED_TAG_COMMANDS},
186 {AIC79XX_CONFIGED_TAG_COMMANDS},
187 {AIC79XX_CONFIGED_TAG_COMMANDS}
188};
189
190/*
191 * By default, read streaming is disabled. In theory,
192 * read streaming should enhance performance, but early
193 * U320 drive firmware actually performs slower with
194 * read streaming enabled.
195 */
196#ifdef CONFIG_AIC79XX_ENABLE_RD_STRM
197#define AIC79XX_CONFIGED_RD_STRM 0xFFFF
198#else
199#define AIC79XX_CONFIGED_RD_STRM 0
200#endif
201
202static uint16_t aic79xx_rd_strm_info[] =
203{
204 AIC79XX_CONFIGED_RD_STRM,
205 AIC79XX_CONFIGED_RD_STRM,
206 AIC79XX_CONFIGED_RD_STRM,
207 AIC79XX_CONFIGED_RD_STRM,
208 AIC79XX_CONFIGED_RD_STRM,
209 AIC79XX_CONFIGED_RD_STRM,
210 AIC79XX_CONFIGED_RD_STRM,
211 AIC79XX_CONFIGED_RD_STRM,
212 AIC79XX_CONFIGED_RD_STRM,
213 AIC79XX_CONFIGED_RD_STRM,
214 AIC79XX_CONFIGED_RD_STRM,
215 AIC79XX_CONFIGED_RD_STRM,
216 AIC79XX_CONFIGED_RD_STRM,
217 AIC79XX_CONFIGED_RD_STRM,
218 AIC79XX_CONFIGED_RD_STRM,
219 AIC79XX_CONFIGED_RD_STRM
220};
221
222/*
223 * DV option:
224 *
225 * positive value = DV Enabled
226 * zero = DV Disabled
227 * negative value = DV Default for adapter type/seeprom
228 */
229#ifdef CONFIG_AIC79XX_DV_SETTING
230#define AIC79XX_CONFIGED_DV CONFIG_AIC79XX_DV_SETTING
231#else
232#define AIC79XX_CONFIGED_DV -1
233#endif
234
235static int8_t aic79xx_dv_settings[] =
236{
237 AIC79XX_CONFIGED_DV,
238 AIC79XX_CONFIGED_DV,
239 AIC79XX_CONFIGED_DV,
240 AIC79XX_CONFIGED_DV,
241 AIC79XX_CONFIGED_DV,
242 AIC79XX_CONFIGED_DV,
243 AIC79XX_CONFIGED_DV,
244 AIC79XX_CONFIGED_DV,
245 AIC79XX_CONFIGED_DV,
246 AIC79XX_CONFIGED_DV,
247 AIC79XX_CONFIGED_DV,
248 AIC79XX_CONFIGED_DV,
249 AIC79XX_CONFIGED_DV,
250 AIC79XX_CONFIGED_DV,
251 AIC79XX_CONFIGED_DV,
252 AIC79XX_CONFIGED_DV
253};
254
255/*
256 * The I/O cell on the chip is very configurable in respect to its analog
257 * characteristics. Set the defaults here; they can be overriden with
258 * the proper insmod parameters.
259 */
260struct ahd_linux_iocell_opts
261{
262 uint8_t precomp;
263 uint8_t slewrate;
264 uint8_t amplitude;
265};
266#define AIC79XX_DEFAULT_PRECOMP 0xFF
267#define AIC79XX_DEFAULT_SLEWRATE 0xFF
268#define AIC79XX_DEFAULT_AMPLITUDE 0xFF
269#define AIC79XX_DEFAULT_IOOPTS \
270{ \
271 AIC79XX_DEFAULT_PRECOMP, \
272 AIC79XX_DEFAULT_SLEWRATE, \
273 AIC79XX_DEFAULT_AMPLITUDE \
274}
275#define AIC79XX_PRECOMP_INDEX 0
276#define AIC79XX_SLEWRATE_INDEX 1
277#define AIC79XX_AMPLITUDE_INDEX 2
278static struct ahd_linux_iocell_opts aic79xx_iocell_info[] =
279{
280 AIC79XX_DEFAULT_IOOPTS,
281 AIC79XX_DEFAULT_IOOPTS,
282 AIC79XX_DEFAULT_IOOPTS,
283 AIC79XX_DEFAULT_IOOPTS,
284 AIC79XX_DEFAULT_IOOPTS,
285 AIC79XX_DEFAULT_IOOPTS,
286 AIC79XX_DEFAULT_IOOPTS,
287 AIC79XX_DEFAULT_IOOPTS,
288 AIC79XX_DEFAULT_IOOPTS,
289 AIC79XX_DEFAULT_IOOPTS,
290 AIC79XX_DEFAULT_IOOPTS,
291 AIC79XX_DEFAULT_IOOPTS,
292 AIC79XX_DEFAULT_IOOPTS,
293 AIC79XX_DEFAULT_IOOPTS,
294 AIC79XX_DEFAULT_IOOPTS,
295 AIC79XX_DEFAULT_IOOPTS
296};
297
298/*
299 * There should be a specific return value for this in scsi.h, but
300 * it seems that most drivers ignore it.
301 */
302#define DID_UNDERFLOW DID_ERROR
303
304void
305ahd_print_path(struct ahd_softc *ahd, struct scb *scb)
306{
307 printk("(scsi%d:%c:%d:%d): ",
308 ahd->platform_data->host->host_no,
309 scb != NULL ? SCB_GET_CHANNEL(ahd, scb) : 'X',
310 scb != NULL ? SCB_GET_TARGET(ahd, scb) : -1,
311 scb != NULL ? SCB_GET_LUN(scb) : -1);
312}
313
314/*
315 * XXX - these options apply unilaterally to _all_ adapters
316 * cards in the system. This should be fixed. Exceptions to this
317 * rule are noted in the comments.
318 */
319
320/*
321 * Skip the scsi bus reset. Non 0 make us skip the reset at startup. This
322 * has no effect on any later resets that might occur due to things like
323 * SCSI bus timeouts.
324 */
325static uint32_t aic79xx_no_reset;
326
327/*
328 * Certain PCI motherboards will scan PCI devices from highest to lowest,
329 * others scan from lowest to highest, and they tend to do all kinds of
330 * strange things when they come into contact with PCI bridge chips. The
331 * net result of all this is that the PCI card that is actually used to boot
332 * the machine is very hard to detect. Most motherboards go from lowest
333 * PCI slot number to highest, and the first SCSI controller found is the
334 * one you boot from. The only exceptions to this are when a controller
335 * has its BIOS disabled. So, we by default sort all of our SCSI controllers
336 * from lowest PCI slot number to highest PCI slot number. We also force
337 * all controllers with their BIOS disabled to the end of the list. This
338 * works on *almost* all computers. Where it doesn't work, we have this
339 * option. Setting this option to non-0 will reverse the order of the sort
340 * to highest first, then lowest, but will still leave cards with their BIOS
341 * disabled at the very end. That should fix everyone up unless there are
342 * really strange cirumstances.
343 */
344static uint32_t aic79xx_reverse_scan;
345
346/*
347 * Should we force EXTENDED translation on a controller.
348 * 0 == Use whatever is in the SEEPROM or default to off
349 * 1 == Use whatever is in the SEEPROM or default to on
350 */
351static uint32_t aic79xx_extended;
352
353/*
354 * PCI bus parity checking of the Adaptec controllers. This is somewhat
355 * dubious at best. To my knowledge, this option has never actually
356 * solved a PCI parity problem, but on certain machines with broken PCI
357 * chipset configurations, it can generate tons of false error messages.
358 * It's included in the driver for completeness.
359 * 0 = Shut off PCI parity check
360 * non-0 = Enable PCI parity check
361 *
362 * NOTE: you can't actually pass -1 on the lilo prompt. So, to set this
363 * variable to -1 you would actually want to simply pass the variable
364 * name without a number. That will invert the 0 which will result in
365 * -1.
366 */
367static uint32_t aic79xx_pci_parity = ~0;
368
369/*
370 * There are lots of broken chipsets in the world. Some of them will
371 * violate the PCI spec when we issue byte sized memory writes to our
372 * controller. I/O mapped register access, if allowed by the given
373 * platform, will work in almost all cases.
374 */
375uint32_t aic79xx_allow_memio = ~0;
376
377/*
378 * aic79xx_detect() has been run, so register all device arrivals
379 * immediately with the system rather than deferring to the sorted
380 * attachment performed by aic79xx_detect().
381 */
382int aic79xx_detect_complete;
383
384/*
385 * So that we can set how long each device is given as a selection timeout.
386 * The table of values goes like this:
387 * 0 - 256ms
388 * 1 - 128ms
389 * 2 - 64ms
390 * 3 - 32ms
391 * We default to 256ms because some older devices need a longer time
392 * to respond to initial selection.
393 */
394static uint32_t aic79xx_seltime;
395
396/*
397 * Certain devices do not perform any aging on commands. Should the
398 * device be saturated by commands in one portion of the disk, it is
399 * possible for transactions on far away sectors to never be serviced.
400 * To handle these devices, we can periodically send an ordered tag to
401 * force all outstanding transactions to be serviced prior to a new
402 * transaction.
403 */
404uint32_t aic79xx_periodic_otag;
405
406/*
407 * Module information and settable options.
408 */
409static char *aic79xx = NULL;
410
411MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>");
412MODULE_DESCRIPTION("Adaptec Aic790X U320 SCSI Host Bus Adapter driver");
413MODULE_LICENSE("Dual BSD/GPL");
414MODULE_VERSION(AIC79XX_DRIVER_VERSION);
415module_param(aic79xx, charp, 0);
416MODULE_PARM_DESC(aic79xx,
417"period delimited, options string.\n"
418" verbose Enable verbose/diagnostic logging\n"
419" allow_memio Allow device registers to be memory mapped\n"
420" debug Bitmask of debug values to enable\n"
421" no_reset Supress initial bus resets\n"
422" extended Enable extended geometry on all controllers\n"
423" periodic_otag Send an ordered tagged transaction\n"
424" periodically to prevent tag starvation.\n"
425" This may be required by some older disk\n"
426" or drives/RAID arrays.\n"
427" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n"
428" tag_info:<tag_str> Set per-target tag depth\n"
429" global_tag_depth:<int> Global tag depth for all targets on all buses\n"
430" rd_strm:<rd_strm_masks> Set per-target read streaming setting.\n"
431" dv:<dv_settings> Set per-controller Domain Validation Setting.\n"
432" slewrate:<slewrate_list>Set the signal slew rate (0-15).\n"
433" precomp:<pcomp_list> Set the signal precompensation (0-7).\n"
434" amplitude:<int> Set the signal amplitude (0-7).\n"
435" seltime:<int> Selection Timeout:\n"
436" (0/256ms,1/128ms,2/64ms,3/32ms)\n"
437"\n"
438" Sample /etc/modprobe.conf line:\n"
439" Enable verbose logging\n"
440" Set tag depth on Controller 2/Target 2 to 10 tags\n"
441" Shorten the selection timeout to 128ms\n"
442"\n"
443" options aic79xx 'aic79xx=verbose.tag_info:{{}.{}.{..10}}.seltime:1'\n"
444"\n"
445" Sample /etc/modprobe.conf line:\n"
446" Change Read Streaming for Controller's 2 and 3\n"
447"\n"
448" options aic79xx 'aic79xx=rd_strm:{..0xFFF0.0xC0F0}'");
449
450static void ahd_linux_handle_scsi_status(struct ahd_softc *,
451 struct ahd_linux_device *,
452 struct scb *);
453static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd,
454 Scsi_Cmnd *cmd);
455static void ahd_linux_filter_inquiry(struct ahd_softc *ahd,
456 struct ahd_devinfo *devinfo);
457static void ahd_linux_dev_timed_unfreeze(u_long arg);
458static void ahd_linux_sem_timeout(u_long arg);
459static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd);
460static void ahd_linux_size_nseg(void);
461static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd);
462static void ahd_linux_start_dv(struct ahd_softc *ahd);
463static void ahd_linux_dv_timeout(struct scsi_cmnd *cmd);
464static int ahd_linux_dv_thread(void *data);
465static void ahd_linux_kill_dv_thread(struct ahd_softc *ahd);
466static void ahd_linux_dv_target(struct ahd_softc *ahd, u_int target);
467static void ahd_linux_dv_transition(struct ahd_softc *ahd,
468 struct scsi_cmnd *cmd,
469 struct ahd_devinfo *devinfo,
470 struct ahd_linux_target *targ);
471static void ahd_linux_dv_fill_cmd(struct ahd_softc *ahd,
472 struct scsi_cmnd *cmd,
473 struct ahd_devinfo *devinfo);
474static void ahd_linux_dv_inq(struct ahd_softc *ahd,
475 struct scsi_cmnd *cmd,
476 struct ahd_devinfo *devinfo,
477 struct ahd_linux_target *targ,
478 u_int request_length);
479static void ahd_linux_dv_tur(struct ahd_softc *ahd,
480 struct scsi_cmnd *cmd,
481 struct ahd_devinfo *devinfo);
482static void ahd_linux_dv_rebd(struct ahd_softc *ahd,
483 struct scsi_cmnd *cmd,
484 struct ahd_devinfo *devinfo,
485 struct ahd_linux_target *targ);
486static void ahd_linux_dv_web(struct ahd_softc *ahd,
487 struct scsi_cmnd *cmd,
488 struct ahd_devinfo *devinfo,
489 struct ahd_linux_target *targ);
490static void ahd_linux_dv_reb(struct ahd_softc *ahd,
491 struct scsi_cmnd *cmd,
492 struct ahd_devinfo *devinfo,
493 struct ahd_linux_target *targ);
494static void ahd_linux_dv_su(struct ahd_softc *ahd,
495 struct scsi_cmnd *cmd,
496 struct ahd_devinfo *devinfo,
497 struct ahd_linux_target *targ);
498static int ahd_linux_fallback(struct ahd_softc *ahd,
499 struct ahd_devinfo *devinfo);
500static __inline int ahd_linux_dv_fallback(struct ahd_softc *ahd,
501 struct ahd_devinfo *devinfo);
502static void ahd_linux_dv_complete(Scsi_Cmnd *cmd);
503static void ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ);
504static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd,
505 struct ahd_devinfo *devinfo);
506static u_int ahd_linux_user_dv_setting(struct ahd_softc *ahd);
507static void ahd_linux_setup_user_rd_strm_settings(struct ahd_softc *ahd);
508static void ahd_linux_device_queue_depth(struct ahd_softc *ahd,
509 struct ahd_linux_device *dev);
510static struct ahd_linux_target* ahd_linux_alloc_target(struct ahd_softc*,
511 u_int, u_int);
512static void ahd_linux_free_target(struct ahd_softc*,
513 struct ahd_linux_target*);
514static struct ahd_linux_device* ahd_linux_alloc_device(struct ahd_softc*,
515 struct ahd_linux_target*,
516 u_int);
517static void ahd_linux_free_device(struct ahd_softc*,
518 struct ahd_linux_device*);
519static void ahd_linux_run_device_queue(struct ahd_softc*,
520 struct ahd_linux_device*);
521static void ahd_linux_setup_tag_info_global(char *p);
522static aic_option_callback_t ahd_linux_setup_tag_info;
523static aic_option_callback_t ahd_linux_setup_rd_strm_info;
524static aic_option_callback_t ahd_linux_setup_dv;
525static aic_option_callback_t ahd_linux_setup_iocell_info;
526static int ahd_linux_next_unit(void);
527static void ahd_runq_tasklet(unsigned long data);
528static int aic79xx_setup(char *c);
529
530/****************************** Inlines ***************************************/
531static __inline void ahd_schedule_completeq(struct ahd_softc *ahd);
532static __inline void ahd_schedule_runq(struct ahd_softc *ahd);
533static __inline void ahd_setup_runq_tasklet(struct ahd_softc *ahd);
534static __inline void ahd_teardown_runq_tasklet(struct ahd_softc *ahd);
535static __inline struct ahd_linux_device*
536 ahd_linux_get_device(struct ahd_softc *ahd, u_int channel,
537 u_int target, u_int lun, int alloc);
538static struct ahd_cmd *ahd_linux_run_complete_queue(struct ahd_softc *ahd);
539static __inline void ahd_linux_check_device_queue(struct ahd_softc *ahd,
540 struct ahd_linux_device *dev);
541static __inline struct ahd_linux_device *
542 ahd_linux_next_device_to_run(struct ahd_softc *ahd);
543static __inline void ahd_linux_run_device_queues(struct ahd_softc *ahd);
544static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
545
546static __inline void
547ahd_schedule_completeq(struct ahd_softc *ahd)
548{
549 if ((ahd->platform_data->flags & AHD_RUN_CMPLT_Q_TIMER) == 0) {
550 ahd->platform_data->flags |= AHD_RUN_CMPLT_Q_TIMER;
551 ahd->platform_data->completeq_timer.expires = jiffies;
552 add_timer(&ahd->platform_data->completeq_timer);
553 }
554}
555
556/*
557 * Must be called with our lock held.
558 */
559static __inline void
560ahd_schedule_runq(struct ahd_softc *ahd)
561{
562 tasklet_schedule(&ahd->platform_data->runq_tasklet);
563}
564
565static __inline
566void ahd_setup_runq_tasklet(struct ahd_softc *ahd)
567{
568 tasklet_init(&ahd->platform_data->runq_tasklet, ahd_runq_tasklet,
569 (unsigned long)ahd);
570}
571
572static __inline void
573ahd_teardown_runq_tasklet(struct ahd_softc *ahd)
574{
575 tasklet_kill(&ahd->platform_data->runq_tasklet);
576}
577
578static __inline struct ahd_linux_device*
579ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, u_int target,
580 u_int lun, int alloc)
581{
582 struct ahd_linux_target *targ;
583 struct ahd_linux_device *dev;
584 u_int target_offset;
585
586 target_offset = target;
587 if (channel != 0)
588 target_offset += 8;
589 targ = ahd->platform_data->targets[target_offset];
590 if (targ == NULL) {
591 if (alloc != 0) {
592 targ = ahd_linux_alloc_target(ahd, channel, target);
593 if (targ == NULL)
594 return (NULL);
595 } else
596 return (NULL);
597 }
598 dev = targ->devices[lun];
599 if (dev == NULL && alloc != 0)
600 dev = ahd_linux_alloc_device(ahd, targ, lun);
601 return (dev);
602}
603
604#define AHD_LINUX_MAX_RETURNED_ERRORS 4
605static struct ahd_cmd *
606ahd_linux_run_complete_queue(struct ahd_softc *ahd)
607{
608 struct ahd_cmd *acmd;
609 u_long done_flags;
610 int with_errors;
611
612 with_errors = 0;
613 ahd_done_lock(ahd, &done_flags);
614 while ((acmd = TAILQ_FIRST(&ahd->platform_data->completeq)) != NULL) {
615 Scsi_Cmnd *cmd;
616
617 if (with_errors > AHD_LINUX_MAX_RETURNED_ERRORS) {
618 /*
619 * Linux uses stack recursion to requeue
620 * commands that need to be retried. Avoid
621 * blowing out the stack by "spoon feeding"
622 * commands that completed with error back
623 * the operating system in case they are going
624 * to be retried. "ick"
625 */
626 ahd_schedule_completeq(ahd);
627 break;
628 }
629 TAILQ_REMOVE(&ahd->platform_data->completeq,
630 acmd, acmd_links.tqe);
631 cmd = &acmd_scsi_cmd(acmd);
632 cmd->host_scribble = NULL;
633 if (ahd_cmd_get_transaction_status(cmd) != DID_OK
634 || (cmd->result & 0xFF) != SCSI_STATUS_OK)
635 with_errors++;
636
637 cmd->scsi_done(cmd);
638 }
639 ahd_done_unlock(ahd, &done_flags);
640 return (acmd);
641}
642
643static __inline void
644ahd_linux_check_device_queue(struct ahd_softc *ahd,
645 struct ahd_linux_device *dev)
646{
647 if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) != 0
648 && dev->active == 0) {
649 dev->flags &= ~AHD_DEV_FREEZE_TIL_EMPTY;
650 dev->qfrozen--;
651 }
652
653 if (TAILQ_FIRST(&dev->busyq) == NULL
654 || dev->openings == 0 || dev->qfrozen != 0)
655 return;
656
657 ahd_linux_run_device_queue(ahd, dev);
658}
659
660static __inline struct ahd_linux_device *
661ahd_linux_next_device_to_run(struct ahd_softc *ahd)
662{
663
664 if ((ahd->flags & AHD_RESOURCE_SHORTAGE) != 0
665 || (ahd->platform_data->qfrozen != 0
666 && AHD_DV_SIMQ_FROZEN(ahd) == 0))
667 return (NULL);
668 return (TAILQ_FIRST(&ahd->platform_data->device_runq));
669}
670
671static __inline void
672ahd_linux_run_device_queues(struct ahd_softc *ahd)
673{
674 struct ahd_linux_device *dev;
675
676 while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) {
677 TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links);
678 dev->flags &= ~AHD_DEV_ON_RUN_LIST;
679 ahd_linux_check_device_queue(ahd, dev);
680 }
681}
682
683static __inline void
684ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
685{
686 Scsi_Cmnd *cmd;
687 int direction;
688
689 cmd = scb->io_ctx;
690 direction = scsi_to_pci_dma_dir(cmd->sc_data_direction);
691 ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
692 if (cmd->use_sg != 0) {
693 struct scatterlist *sg;
694
695 sg = (struct scatterlist *)cmd->request_buffer;
696 pci_unmap_sg(ahd->dev_softc, sg, cmd->use_sg, direction);
697 } else if (cmd->request_bufflen != 0) {
698 pci_unmap_single(ahd->dev_softc,
699 scb->platform_data->buf_busaddr,
700 cmd->request_bufflen, direction);
701 }
702}
703
704/******************************** Macros **************************************/
705#define BUILD_SCSIID(ahd, cmd) \
706 ((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id)
707
708/************************ Host template entry points *************************/
709static int ahd_linux_detect(Scsi_Host_Template *);
710static const char *ahd_linux_info(struct Scsi_Host *);
711static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
712#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
713static int ahd_linux_slave_alloc(Scsi_Device *);
714static int ahd_linux_slave_configure(Scsi_Device *);
715static void ahd_linux_slave_destroy(Scsi_Device *);
716#if defined(__i386__)
717static int ahd_linux_biosparam(struct scsi_device*,
718 struct block_device*, sector_t, int[]);
719#endif
720#else
721static int ahd_linux_release(struct Scsi_Host *);
722static void ahd_linux_select_queue_depth(struct Scsi_Host *host,
723 Scsi_Device *scsi_devs);
724#if defined(__i386__)
725static int ahd_linux_biosparam(Disk *, kdev_t, int[]);
726#endif
727#endif
728static int ahd_linux_bus_reset(Scsi_Cmnd *);
729static int ahd_linux_dev_reset(Scsi_Cmnd *);
730static int ahd_linux_abort(Scsi_Cmnd *);
731
732/*
733 * Calculate a safe value for AHD_NSEG (as expressed through ahd_linux_nseg).
734 *
735 * In pre-2.5.X...
736 * The midlayer allocates an S/G array dynamically when a command is issued
737 * using SCSI malloc. This array, which is in an OS dependent format that
738 * must later be copied to our private S/G list, is sized to house just the
739 * number of segments needed for the current transfer. Since the code that
740 * sizes the SCSI malloc pool does not take into consideration fragmentation
741 * of the pool, executing transactions numbering just a fraction of our
742 * concurrent transaction limit with SG list lengths aproaching AHC_NSEG will
743 * quickly depleat the SCSI malloc pool of usable space. Unfortunately, the
744 * mid-layer does not properly handle this scsi malloc failures for the S/G
745 * array and the result can be a lockup of the I/O subsystem. We try to size
746 * our S/G list so that it satisfies our drivers allocation requirements in
747 * addition to avoiding fragmentation of the SCSI malloc pool.
748 */
749static void
750ahd_linux_size_nseg(void)
751{
752#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
753 u_int cur_size;
754 u_int best_size;
755
756 /*
757 * The SCSI allocator rounds to the nearest 512 bytes
758 * an cannot allocate across a page boundary. Our algorithm
759 * is to start at 1K of scsi malloc space per-command and
760 * loop through all factors of the PAGE_SIZE and pick the best.
761 */
762 best_size = 0;
763 for (cur_size = 1024; cur_size <= PAGE_SIZE; cur_size *= 2) {
764 u_int nseg;
765
766 nseg = cur_size / sizeof(struct scatterlist);
767 if (nseg < AHD_LINUX_MIN_NSEG)
768 continue;
769
770 if (best_size == 0) {
771 best_size = cur_size;
772 ahd_linux_nseg = nseg;
773 } else {
774 u_int best_rem;
775 u_int cur_rem;
776
777 /*
778 * Compare the traits of the current "best_size"
779 * with the current size to determine if the
780 * current size is a better size.
781 */
782 best_rem = best_size % sizeof(struct scatterlist);
783 cur_rem = cur_size % sizeof(struct scatterlist);
784 if (cur_rem < best_rem) {
785 best_size = cur_size;
786 ahd_linux_nseg = nseg;
787 }
788 }
789 }
790#endif
791}
792
793/*
794 * Try to detect an Adaptec 79XX controller.
795 */
796static int
797ahd_linux_detect(Scsi_Host_Template *template)
798{
799 struct ahd_softc *ahd;
800 int found;
801 int error = 0;
802
803#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
804 /*
805 * It is a bug that the upper layer takes
806 * this lock just prior to calling us.
807 */
808 spin_unlock_irq(&io_request_lock);
809#endif
810
811 /*
812 * Sanity checking of Linux SCSI data structures so
813 * that some of our hacks^H^H^H^H^Hassumptions aren't
814 * violated.
815 */
816 if (offsetof(struct ahd_cmd_internal, end)
817 > offsetof(struct scsi_cmnd, host_scribble)) {
818 printf("ahd_linux_detect: SCSI data structures changed.\n");
819 printf("ahd_linux_detect: Unable to attach\n");
820 return (0);
821 }
822 /*
823 * Determine an appropriate size for our Scatter Gatther lists.
824 */
825 ahd_linux_size_nseg();
826#ifdef MODULE
827 /*
828 * If we've been passed any parameters, process them now.
829 */
830 if (aic79xx)
831 aic79xx_setup(aic79xx);
832#endif
833
834 template->proc_name = "aic79xx";
835
836 /*
837 * Initialize our softc list lock prior to
838 * probing for any adapters.
839 */
840 ahd_list_lockinit();
841
842#ifdef CONFIG_PCI
843 error = ahd_linux_pci_init();
844 if (error)
845 return error;
846#endif
847
848 /*
849 * Register with the SCSI layer all
850 * controllers we've found.
851 */
852 found = 0;
853 TAILQ_FOREACH(ahd, &ahd_tailq, links) {
854
855 if (ahd_linux_register_host(ahd, template) == 0)
856 found++;
857 }
858#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
859 spin_lock_irq(&io_request_lock);
860#endif
861 aic79xx_detect_complete++;
862 return 0;
863}
864
865#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
866/*
867 * Free the passed in Scsi_Host memory structures prior to unloading the
868 * module.
869 */
870static int
871ahd_linux_release(struct Scsi_Host * host)
872{
873 struct ahd_softc *ahd;
874 u_long l;
875
876 ahd_list_lock(&l);
877 if (host != NULL) {
878
879 /*
880 * We should be able to just perform
881 * the free directly, but check our
882 * list for extra sanity.
883 */
884 ahd = ahd_find_softc(*(struct ahd_softc **)host->hostdata);
885 if (ahd != NULL) {
886 u_long s;
887
888 ahd_lock(ahd, &s);
889 ahd_intr_enable(ahd, FALSE);
890 ahd_unlock(ahd, &s);
891 ahd_free(ahd);
892 }
893 }
894 ahd_list_unlock(&l);
895 return (0);
896}
897#endif
898
899/*
900 * Return a string describing the driver.
901 */
902static const char *
903ahd_linux_info(struct Scsi_Host *host)
904{
905 static char buffer[512];
906 char ahd_info[256];
907 char *bp;
908 struct ahd_softc *ahd;
909
910 bp = &buffer[0];
911 ahd = *(struct ahd_softc **)host->hostdata;
912 memset(bp, 0, sizeof(buffer));
913 strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev ");
914 strcat(bp, AIC79XX_DRIVER_VERSION);
915 strcat(bp, "\n");
916 strcat(bp, " <");
917 strcat(bp, ahd->description);
918 strcat(bp, ">\n");
919 strcat(bp, " ");
920 ahd_controller_info(ahd, ahd_info);
921 strcat(bp, ahd_info);
922 strcat(bp, "\n");
923
924 return (bp);
925}
926
927/*
928 * Queue an SCB to the controller.
929 */
930static int
931ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
932{
933 struct ahd_softc *ahd;
934 struct ahd_linux_device *dev;
935 u_long flags;
936
937 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
938
939 /*
940 * Save the callback on completion function.
941 */
942 cmd->scsi_done = scsi_done;
943
944 ahd_midlayer_entrypoint_lock(ahd, &flags);
945
946 /*
947 * Close the race of a command that was in the process of
948 * being queued to us just as our simq was frozen. Let
949 * DV commands through so long as we are only frozen to
950 * perform DV.
951 */
952 if (ahd->platform_data->qfrozen != 0
953 && AHD_DV_CMD(cmd) == 0) {
954
955 ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
956 ahd_linux_queue_cmd_complete(ahd, cmd);
957 ahd_schedule_completeq(ahd);
958 ahd_midlayer_entrypoint_unlock(ahd, &flags);
959 return (0);
960 }
961 dev = ahd_linux_get_device(ahd, cmd->device->channel,
962 cmd->device->id, cmd->device->lun,
963 /*alloc*/TRUE);
964 if (dev == NULL) {
965 ahd_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
966 ahd_linux_queue_cmd_complete(ahd, cmd);
967 ahd_schedule_completeq(ahd);
968 ahd_midlayer_entrypoint_unlock(ahd, &flags);
969 printf("%s: aic79xx_linux_queue - Unable to allocate device!\n",
970 ahd_name(ahd));
971 return (0);
972 }
973 if (cmd->cmd_len > MAX_CDB_LEN)
974 return (-EINVAL);
975 cmd->result = CAM_REQ_INPROG << 16;
976 TAILQ_INSERT_TAIL(&dev->busyq, (struct ahd_cmd *)cmd, acmd_links.tqe);
977 if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) {
978 TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links);
979 dev->flags |= AHD_DEV_ON_RUN_LIST;
980 ahd_linux_run_device_queues(ahd);
981 }
982 ahd_midlayer_entrypoint_unlock(ahd, &flags);
983 return (0);
984}
985
986#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
987static int
988ahd_linux_slave_alloc(Scsi_Device *device)
989{
990 struct ahd_softc *ahd;
991
992 ahd = *((struct ahd_softc **)device->host->hostdata);
993 if (bootverbose)
994 printf("%s: Slave Alloc %d\n", ahd_name(ahd), device->id);
995 return (0);
996}
997
998static int
999ahd_linux_slave_configure(Scsi_Device *device)
1000{
1001 struct ahd_softc *ahd;
1002 struct ahd_linux_device *dev;
1003 u_long flags;
1004
1005 ahd = *((struct ahd_softc **)device->host->hostdata);
1006 if (bootverbose)
1007 printf("%s: Slave Configure %d\n", ahd_name(ahd), device->id);
1008 ahd_midlayer_entrypoint_lock(ahd, &flags);
1009 /*
1010 * Since Linux has attached to the device, configure
1011 * it so we don't free and allocate the device
1012 * structure on every command.
1013 */
1014 dev = ahd_linux_get_device(ahd, device->channel,
1015 device->id, device->lun,
1016 /*alloc*/TRUE);
1017 if (dev != NULL) {
1018 dev->flags &= ~AHD_DEV_UNCONFIGURED;
1019 dev->flags |= AHD_DEV_SLAVE_CONFIGURED;
1020 dev->scsi_device = device;
1021 ahd_linux_device_queue_depth(ahd, dev);
1022 }
1023 ahd_midlayer_entrypoint_unlock(ahd, &flags);
1024 return (0);
1025}
1026
1027static void
1028ahd_linux_slave_destroy(Scsi_Device *device)
1029{
1030 struct ahd_softc *ahd;
1031 struct ahd_linux_device *dev;
1032 u_long flags;
1033
1034 ahd = *((struct ahd_softc **)device->host->hostdata);
1035 if (bootverbose)
1036 printf("%s: Slave Destroy %d\n", ahd_name(ahd), device->id);
1037 ahd_midlayer_entrypoint_lock(ahd, &flags);
1038 dev = ahd_linux_get_device(ahd, device->channel,
1039 device->id, device->lun,
1040 /*alloc*/FALSE);
1041
1042 /*
1043 * Filter out "silly" deletions of real devices by only
1044 * deleting devices that have had slave_configure()
1045 * called on them. All other devices that have not
1046 * been configured will automatically be deleted by
1047 * the refcounting process.
1048 */
1049 if (dev != NULL
1050 && (dev->flags & AHD_DEV_SLAVE_CONFIGURED) != 0) {
1051 dev->flags |= AHD_DEV_UNCONFIGURED;
1052 if (TAILQ_EMPTY(&dev->busyq)
1053 && dev->active == 0
1054 && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0)
1055 ahd_linux_free_device(ahd, dev);
1056 }
1057 ahd_midlayer_entrypoint_unlock(ahd, &flags);
1058}
1059#else
1060/*
1061 * Sets the queue depth for each SCSI device hanging
1062 * off the input host adapter.
1063 */
1064static void
1065ahd_linux_select_queue_depth(struct Scsi_Host * host,
1066 Scsi_Device * scsi_devs)
1067{
1068 Scsi_Device *device;
1069 Scsi_Device *ldev;
1070 struct ahd_softc *ahd;
1071 u_long flags;
1072
1073 ahd = *((struct ahd_softc **)host->hostdata);
1074 ahd_lock(ahd, &flags);
1075 for (device = scsi_devs; device != NULL; device = device->next) {
1076
1077 /*
1078 * Watch out for duplicate devices. This works around
1079 * some quirks in how the SCSI scanning code does its
1080 * device management.
1081 */
1082 for (ldev = scsi_devs; ldev != device; ldev = ldev->next) {
1083 if (ldev->host == device->host
1084 && ldev->channel == device->channel
1085 && ldev->id == device->id
1086 && ldev->lun == device->lun)
1087 break;
1088 }
1089 /* Skip duplicate. */
1090 if (ldev != device)
1091 continue;
1092
1093 if (device->host == host) {
1094 struct ahd_linux_device *dev;
1095
1096 /*
1097 * Since Linux has attached to the device, configure
1098 * it so we don't free and allocate the device
1099 * structure on every command.
1100 */
1101 dev = ahd_linux_get_device(ahd, device->channel,
1102 device->id, device->lun,
1103 /*alloc*/TRUE);
1104 if (dev != NULL) {
1105 dev->flags &= ~AHD_DEV_UNCONFIGURED;
1106 dev->scsi_device = device;
1107 ahd_linux_device_queue_depth(ahd, dev);
1108 device->queue_depth = dev->openings
1109 + dev->active;
1110 if ((dev->flags & (AHD_DEV_Q_BASIC
1111 | AHD_DEV_Q_TAGGED)) == 0) {
1112 /*
1113 * We allow the OS to queue 2 untagged
1114 * transactions to us at any time even
1115 * though we can only execute them
1116 * serially on the controller/device.
1117 * This should remove some latency.
1118 */
1119 device->queue_depth = 2;
1120 }
1121 }
1122 }
1123 }
1124 ahd_unlock(ahd, &flags);
1125}
1126#endif
1127
1128#if defined(__i386__)
1129/*
1130 * Return the disk geometry for the given SCSI device.
1131 */
1132static int
1133#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1134ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1135 sector_t capacity, int geom[])
1136{
1137 uint8_t *bh;
1138#else
1139ahd_linux_biosparam(Disk *disk, kdev_t dev, int geom[])
1140{
1141 struct scsi_device *sdev = disk->device;
1142 u_long capacity = disk->capacity;
1143 struct buffer_head *bh;
1144#endif
1145 int heads;
1146 int sectors;
1147 int cylinders;
1148 int ret;
1149 int extended;
1150 struct ahd_softc *ahd;
1151
1152 ahd = *((struct ahd_softc **)sdev->host->hostdata);
1153
1154#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1155 bh = scsi_bios_ptable(bdev);
1156#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17)
1157 bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev));
1158#else
1159 bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024);
1160#endif
1161
1162 if (bh) {
1163 ret = scsi_partsize(bh, capacity,
1164 &geom[2], &geom[0], &geom[1]);
1165#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1166 kfree(bh);
1167#else
1168 brelse(bh);
1169#endif
1170 if (ret != -1)
1171 return (ret);
1172 }
1173 heads = 64;
1174 sectors = 32;
1175 cylinders = aic_sector_div(capacity, heads, sectors);
1176
1177 if (aic79xx_extended != 0)
1178 extended = 1;
1179 else
1180 extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0;
1181 if (extended && cylinders >= 1024) {
1182 heads = 255;
1183 sectors = 63;
1184 cylinders = aic_sector_div(capacity, heads, sectors);
1185 }
1186 geom[0] = heads;
1187 geom[1] = sectors;
1188 geom[2] = cylinders;
1189 return (0);
1190}
1191#endif
1192
1193/*
1194 * Abort the current SCSI command(s).
1195 */
1196static int
1197ahd_linux_abort(Scsi_Cmnd *cmd)
1198{
1199 struct ahd_softc *ahd;
1200 struct ahd_cmd *acmd;
1201 struct ahd_cmd *list_acmd;
1202 struct ahd_linux_device *dev;
1203 struct scb *pending_scb;
1204 u_long s;
1205 u_int saved_scbptr;
1206 u_int active_scbptr;
1207 u_int last_phase;
1208 u_int cdb_byte;
1209 int retval;
1210 int was_paused;
1211 int paused;
1212 int wait;
1213 int disconnected;
1214 ahd_mode_state saved_modes;
1215
1216 pending_scb = NULL;
1217 paused = FALSE;
1218 wait = FALSE;
1219 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
1220 acmd = (struct ahd_cmd *)cmd;
1221
1222 printf("%s:%d:%d:%d: Attempting to abort cmd %p:",
1223 ahd_name(ahd), cmd->device->channel, cmd->device->id,
1224 cmd->device->lun, cmd);
1225 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
1226 printf(" 0x%x", cmd->cmnd[cdb_byte]);
1227 printf("\n");
1228
1229 /*
1230 * In all versions of Linux, we have to work around
1231 * a major flaw in how the mid-layer is locked down
1232 * if we are to sleep successfully in our error handler
1233 * while allowing our interrupt handler to run. Since
1234 * the midlayer acquires either the io_request_lock or
1235 * our lock prior to calling us, we must use the
1236 * spin_unlock_irq() method for unlocking our lock.
1237 * This will force interrupts to be enabled on the
1238 * current CPU. Since the EH thread should not have
1239 * been running with CPU interrupts disabled other than
1240 * by acquiring either the io_request_lock or our own
1241 * lock, this *should* be safe.
1242 */
1243 ahd_midlayer_entrypoint_lock(ahd, &s);
1244
1245 /*
1246 * First determine if we currently own this command.
1247 * Start by searching the device queue. If not found
1248 * there, check the pending_scb list. If not found
1249 * at all, and the system wanted us to just abort the
1250 * command, return success.
1251 */
1252 dev = ahd_linux_get_device(ahd, cmd->device->channel,
1253 cmd->device->id, cmd->device->lun,
1254 /*alloc*/FALSE);
1255
1256 if (dev == NULL) {
1257 /*
1258 * No target device for this command exists,
1259 * so we must not still own the command.
1260 */
1261 printf("%s:%d:%d:%d: Is not an active device\n",
1262 ahd_name(ahd), cmd->device->channel, cmd->device->id,
1263 cmd->device->lun);
1264 retval = SUCCESS;
1265 goto no_cmd;
1266 }
1267
1268 TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) {
1269 if (list_acmd == acmd)
1270 break;
1271 }
1272
1273 if (list_acmd != NULL) {
1274 printf("%s:%d:%d:%d: Command found on device queue\n",
1275 ahd_name(ahd), cmd->device->channel, cmd->device->id,
1276 cmd->device->lun);
1277 TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
1278 cmd->result = DID_ABORT << 16;
1279 ahd_linux_queue_cmd_complete(ahd, cmd);
1280 retval = SUCCESS;
1281 goto done;
1282 }
1283
1284 /*
1285 * See if we can find a matching cmd in the pending list.
1286 */
1287 LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
1288 if (pending_scb->io_ctx == cmd)
1289 break;
1290 }
1291
1292 if (pending_scb == NULL) {
1293 printf("%s:%d:%d:%d: Command not found\n",
1294 ahd_name(ahd), cmd->device->channel, cmd->device->id,
1295 cmd->device->lun);
1296 goto no_cmd;
1297 }
1298
1299 if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
1300 /*
1301 * We can't queue two recovery actions using the same SCB
1302 */
1303 retval = FAILED;
1304 goto done;
1305 }
1306
1307 /*
1308 * Ensure that the card doesn't do anything
1309 * behind our back. Also make sure that we
1310 * didn't "just" miss an interrupt that would
1311 * affect this cmd.
1312 */
1313 was_paused = ahd_is_paused(ahd);
1314 ahd_pause_and_flushwork(ahd);
1315 paused = TRUE;
1316
1317 if ((pending_scb->flags & SCB_ACTIVE) == 0) {
1318 printf("%s:%d:%d:%d: Command already completed\n",
1319 ahd_name(ahd), cmd->device->channel, cmd->device->id,
1320 cmd->device->lun);
1321 goto no_cmd;
1322 }
1323
1324 printf("%s: At time of recovery, card was %spaused\n",
1325 ahd_name(ahd), was_paused ? "" : "not ");
1326 ahd_dump_card_state(ahd);
1327
1328 disconnected = TRUE;
1329 if (ahd_search_qinfifo(ahd, cmd->device->id, cmd->device->channel + 'A',
1330 cmd->device->lun, SCB_GET_TAG(pending_scb),
1331 ROLE_INITIATOR, CAM_REQ_ABORTED,
1332 SEARCH_COMPLETE) > 0) {
1333 printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
1334 ahd_name(ahd), cmd->device->channel, cmd->device->id,
1335 cmd->device->lun);
1336 retval = SUCCESS;
1337 goto done;
1338 }
1339
1340 saved_modes = ahd_save_modes(ahd);
1341 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1342 last_phase = ahd_inb(ahd, LASTPHASE);
1343 saved_scbptr = ahd_get_scbptr(ahd);
1344 active_scbptr = saved_scbptr;
1345 if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
1346 struct scb *bus_scb;
1347
1348 bus_scb = ahd_lookup_scb(ahd, active_scbptr);
1349 if (bus_scb == pending_scb)
1350 disconnected = FALSE;
1351 }
1352
1353 /*
1354 * At this point, pending_scb is the scb associated with the
1355 * passed in command. That command is currently active on the
1356 * bus or is in the disconnected state.
1357 */
1358 if (last_phase != P_BUSFREE
1359 && SCB_GET_TAG(pending_scb) == active_scbptr) {
1360
1361 /*
1362 * We're active on the bus, so assert ATN
1363 * and hope that the target responds.
1364 */
1365 pending_scb = ahd_lookup_scb(ahd, active_scbptr);
1366 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
1367 ahd_outb(ahd, MSG_OUT, HOST_MSG);
1368 ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
1369 printf("%s:%d:%d:%d: Device is active, asserting ATN\n",
1370 ahd_name(ahd), cmd->device->channel,
1371 cmd->device->id, cmd->device->lun);
1372 wait = TRUE;
1373 } else if (disconnected) {
1374
1375 /*
1376 * Actually re-queue this SCB in an attempt
1377 * to select the device before it reconnects.
1378 */
1379 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
1380 ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));
1381 pending_scb->hscb->cdb_len = 0;
1382 pending_scb->hscb->task_attribute = 0;
1383 pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK;
1384
1385 if ((pending_scb->flags & SCB_PACKETIZED) != 0) {
1386 /*
1387 * Mark the SCB has having an outstanding
1388 * task management function. Should the command
1389 * complete normally before the task management
1390 * function can be sent, the host will be notified
1391 * to abort our requeued SCB.
1392 */
1393 ahd_outb(ahd, SCB_TASK_MANAGEMENT,
1394 pending_scb->hscb->task_management);
1395 } else {
1396 /*
1397 * If non-packetized, set the MK_MESSAGE control
1398 * bit indicating that we desire to send a message.
1399 * We also set the disconnected flag since there is
1400 * no guarantee that our SCB control byte matches
1401 * the version on the card. We don't want the
1402 * sequencer to abort the command thinking an
1403 * unsolicited reselection occurred.
1404 */
1405 pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
1406
1407 /*
1408 * The sequencer will never re-reference the
1409 * in-core SCB. To make sure we are notified
1410 * during reslection, set the MK_MESSAGE flag in
1411 * the card's copy of the SCB.
1412 */
1413 ahd_outb(ahd, SCB_CONTROL,
1414 ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);
1415 }
1416
1417 /*
1418 * Clear out any entries in the QINFIFO first
1419 * so we are the next SCB for this target
1420 * to run.
1421 */
1422 ahd_search_qinfifo(ahd, cmd->device->id,
1423 cmd->device->channel + 'A', cmd->device->lun,
1424 SCB_LIST_NULL, ROLE_INITIATOR,
1425 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
1426 ahd_qinfifo_requeue_tail(ahd, pending_scb);
1427 ahd_set_scbptr(ahd, saved_scbptr);
1428 ahd_print_path(ahd, pending_scb);
1429 printf("Device is disconnected, re-queuing SCB\n");
1430 wait = TRUE;
1431 } else {
1432 printf("%s:%d:%d:%d: Unable to deliver message\n",
1433 ahd_name(ahd), cmd->device->channel,
1434 cmd->device->id, cmd->device->lun);
1435 retval = FAILED;
1436 goto done;
1437 }
1438
1439no_cmd:
1440 /*
1441 * Our assumption is that if we don't have the command, no
1442 * recovery action was required, so we return success. Again,
1443 * the semantics of the mid-layer recovery engine are not
1444 * well defined, so this may change in time.
1445 */
1446 retval = SUCCESS;
1447done:
1448 if (paused)
1449 ahd_unpause(ahd);
1450 if (wait) {
1451 struct timer_list timer;
1452 int ret;
1453
1454 pending_scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;
1455 spin_unlock_irq(&ahd->platform_data->spin_lock);
1456 init_timer(&timer);
1457 timer.data = (u_long)pending_scb;
1458 timer.expires = jiffies + (5 * HZ);
1459 timer.function = ahd_linux_sem_timeout;
1460 add_timer(&timer);
1461 printf("Recovery code sleeping\n");
1462 down(&ahd->platform_data->eh_sem);
1463 printf("Recovery code awake\n");
1464 ret = del_timer_sync(&timer);
1465 if (ret == 0) {
1466 printf("Timer Expired\n");
1467 retval = FAILED;
1468 }
1469 spin_lock_irq(&ahd->platform_data->spin_lock);
1470 }
1471 ahd_schedule_runq(ahd);
1472 ahd_linux_run_complete_queue(ahd);
1473 ahd_midlayer_entrypoint_unlock(ahd, &s);
1474 return (retval);
1475}
1476
1477
1478static void
1479ahd_linux_dev_reset_complete(Scsi_Cmnd *cmd)
1480{
1481 free(cmd, M_DEVBUF);
1482}
1483
1484/*
1485 * Attempt to send a target reset message to the device that timed out.
1486 */
1487static int
1488ahd_linux_dev_reset(Scsi_Cmnd *cmd)
1489{
1490 struct ahd_softc *ahd;
1491 struct scsi_cmnd *recovery_cmd;
1492 struct ahd_linux_device *dev;
1493 struct ahd_initiator_tinfo *tinfo;
1494 struct ahd_tmode_tstate *tstate;
1495 struct scb *scb;
1496 struct hardware_scb *hscb;
1497 u_long s;
1498 struct timer_list timer;
1499 int retval;
1500
1501 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
1502 recovery_cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK);
1503 if (!recovery_cmd)
1504 return (FAILED);
1505 memset(recovery_cmd, 0, sizeof(struct scsi_cmnd));
1506 recovery_cmd->device = cmd->device;
1507 recovery_cmd->scsi_done = ahd_linux_dev_reset_complete;
1508#if AHD_DEBUG
1509 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
1510 printf("%s:%d:%d:%d: Device reset called for cmd %p\n",
1511 ahd_name(ahd), cmd->device->channel, cmd->device->id,
1512 cmd->device->lun, cmd);
1513#endif
1514 ahd_midlayer_entrypoint_lock(ahd, &s);
1515
1516 dev = ahd_linux_get_device(ahd, cmd->device->channel, cmd->device->id,
1517 cmd->device->lun, /*alloc*/FALSE);
1518 if (dev == NULL) {
1519 ahd_midlayer_entrypoint_unlock(ahd, &s);
1520 kfree(recovery_cmd);
1521 return (FAILED);
1522 }
1523 if ((scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX)) == NULL) {
1524 ahd_midlayer_entrypoint_unlock(ahd, &s);
1525 kfree(recovery_cmd);
1526 return (FAILED);
1527 }
1528 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
1529 cmd->device->id, &tstate);
1530 recovery_cmd->result = CAM_REQ_INPROG << 16;
1531 recovery_cmd->host_scribble = (char *)scb;
1532 scb->io_ctx = recovery_cmd;
1533 scb->platform_data->dev = dev;
1534 scb->sg_count = 0;
1535 ahd_set_residual(scb, 0);
1536 ahd_set_sense_residual(scb, 0);
1537 hscb = scb->hscb;
1538 hscb->control = 0;
1539 hscb->scsiid = BUILD_SCSIID(ahd, cmd);
1540 hscb->lun = cmd->device->lun;
1541 hscb->cdb_len = 0;
1542 hscb->task_management = SIU_TASKMGMT_LUN_RESET;
1543 scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
1544 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
1545 scb->flags |= SCB_PACKETIZED;
1546 } else {
1547 hscb->control |= MK_MESSAGE;
1548 }
1549 dev->openings--;
1550 dev->active++;
1551 dev->commands_issued++;
1552 LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
1553 ahd_queue_scb(ahd, scb);
1554
1555 scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;
1556 spin_unlock_irq(&ahd->platform_data->spin_lock);
1557 init_timer(&timer);
1558 timer.data = (u_long)scb;
1559 timer.expires = jiffies + (5 * HZ);
1560 timer.function = ahd_linux_sem_timeout;
1561 add_timer(&timer);
1562 printf("Recovery code sleeping\n");
1563 down(&ahd->platform_data->eh_sem);
1564 printf("Recovery code awake\n");
1565 retval = SUCCESS;
1566 if (del_timer_sync(&timer) == 0) {
1567 printf("Timer Expired\n");
1568 retval = FAILED;
1569 }
1570 spin_lock_irq(&ahd->platform_data->spin_lock);
1571 ahd_schedule_runq(ahd);
1572 ahd_linux_run_complete_queue(ahd);
1573 ahd_midlayer_entrypoint_unlock(ahd, &s);
1574 printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
1575 return (retval);
1576}
1577
1578/*
1579 * Reset the SCSI bus.
1580 */
1581static int
1582ahd_linux_bus_reset(Scsi_Cmnd *cmd)
1583{
1584 struct ahd_softc *ahd;
1585 u_long s;
1586 int found;
1587
1588 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
1589#ifdef AHD_DEBUG
1590 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
1591 printf("%s: Bus reset called for cmd %p\n",
1592 ahd_name(ahd), cmd);
1593#endif
1594 ahd_midlayer_entrypoint_lock(ahd, &s);
1595 found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
1596 /*initiate reset*/TRUE);
1597 ahd_linux_run_complete_queue(ahd);
1598 ahd_midlayer_entrypoint_unlock(ahd, &s);
1599
1600 if (bootverbose)
1601 printf("%s: SCSI bus reset delivered. "
1602 "%d SCBs aborted.\n", ahd_name(ahd), found);
1603
1604 return (SUCCESS);
1605}
1606
1607Scsi_Host_Template aic79xx_driver_template = {
1608 .module = THIS_MODULE,
1609 .name = "aic79xx",
1610 .proc_info = ahd_linux_proc_info,
1611 .info = ahd_linux_info,
1612 .queuecommand = ahd_linux_queue,
1613 .eh_abort_handler = ahd_linux_abort,
1614 .eh_device_reset_handler = ahd_linux_dev_reset,
1615 .eh_bus_reset_handler = ahd_linux_bus_reset,
1616#if defined(__i386__)
1617 .bios_param = ahd_linux_biosparam,
1618#endif
1619 .can_queue = AHD_MAX_QUEUE,
1620 .this_id = -1,
1621 .cmd_per_lun = 2,
1622 .use_clustering = ENABLE_CLUSTERING,
1623 .slave_alloc = ahd_linux_slave_alloc,
1624 .slave_configure = ahd_linux_slave_configure,
1625 .slave_destroy = ahd_linux_slave_destroy,
1626};
1627
1628/**************************** Tasklet Handler *********************************/
1629
1630/*
1631 * In 2.4.X and above, this routine is called from a tasklet,
1632 * so we must re-acquire our lock prior to executing this code.
1633 * In all prior kernels, ahd_schedule_runq() calls this routine
1634 * directly and ahd_schedule_runq() is called with our lock held.
1635 */
1636static void
1637ahd_runq_tasklet(unsigned long data)
1638{
1639 struct ahd_softc* ahd;
1640 struct ahd_linux_device *dev;
1641 u_long flags;
1642
1643 ahd = (struct ahd_softc *)data;
1644 ahd_lock(ahd, &flags);
1645 while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) {
1646
1647 TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links);
1648 dev->flags &= ~AHD_DEV_ON_RUN_LIST;
1649 ahd_linux_check_device_queue(ahd, dev);
1650 /* Yeild to our interrupt handler */
1651 ahd_unlock(ahd, &flags);
1652 ahd_lock(ahd, &flags);
1653 }
1654 ahd_unlock(ahd, &flags);
1655}
1656
1657/******************************** Bus DMA *************************************/
1658int
1659ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent,
1660 bus_size_t alignment, bus_size_t boundary,
1661 dma_addr_t lowaddr, dma_addr_t highaddr,
1662 bus_dma_filter_t *filter, void *filterarg,
1663 bus_size_t maxsize, int nsegments,
1664 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
1665{
1666 bus_dma_tag_t dmat;
1667
1668 dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT);
1669 if (dmat == NULL)
1670 return (ENOMEM);
1671
1672 /*
1673 * Linux is very simplistic about DMA memory. For now don't
1674 * maintain all specification information. Once Linux supplies
1675 * better facilities for doing these operations, or the
1676 * needs of this particular driver change, we might need to do
1677 * more here.
1678 */
1679 dmat->alignment = alignment;
1680 dmat->boundary = boundary;
1681 dmat->maxsize = maxsize;
1682 *ret_tag = dmat;
1683 return (0);
1684}
1685
1686void
1687ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat)
1688{
1689 free(dmat, M_DEVBUF);
1690}
1691
1692int
1693ahd_dmamem_alloc(struct ahd_softc *ahd, bus_dma_tag_t dmat, void** vaddr,
1694 int flags, bus_dmamap_t *mapp)
1695{
1696 bus_dmamap_t map;
1697
1698 map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT);
1699 if (map == NULL)
1700 return (ENOMEM);
1701 /*
1702 * Although we can dma data above 4GB, our
1703 * "consistent" memory is below 4GB for
1704 * space efficiency reasons (only need a 4byte
1705 * address). For this reason, we have to reset
1706 * our dma mask when doing allocations.
1707 */
1708 if (ahd->dev_softc != NULL)
1709 if (pci_set_dma_mask(ahd->dev_softc, 0xFFFFFFFF)) {
1710 printk(KERN_WARNING "aic79xx: No suitable DMA available.\n");
1711 kfree(map);
1712 return (ENODEV);
1713 }
1714 *vaddr = pci_alloc_consistent(ahd->dev_softc,
1715 dmat->maxsize, &map->bus_addr);
1716 if (ahd->dev_softc != NULL)
1717 if (pci_set_dma_mask(ahd->dev_softc,
1718 ahd->platform_data->hw_dma_mask)) {
1719 printk(KERN_WARNING "aic79xx: No suitable DMA available.\n");
1720 kfree(map);
1721 return (ENODEV);
1722 }
1723 if (*vaddr == NULL)
1724 return (ENOMEM);
1725 *mapp = map;
1726 return(0);
1727}
1728
1729void
1730ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat,
1731 void* vaddr, bus_dmamap_t map)
1732{
1733 pci_free_consistent(ahd->dev_softc, dmat->maxsize,
1734 vaddr, map->bus_addr);
1735}
1736
1737int
1738ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map,
1739 void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
1740 void *cb_arg, int flags)
1741{
1742 /*
1743 * Assume for now that this will only be used during
1744 * initialization and not for per-transaction buffer mapping.
1745 */
1746 bus_dma_segment_t stack_sg;
1747
1748 stack_sg.ds_addr = map->bus_addr;
1749 stack_sg.ds_len = dmat->maxsize;
1750 cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0);
1751 return (0);
1752}
1753
1754void
1755ahd_dmamap_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
1756{
1757 /*
1758 * The map may is NULL in our < 2.3.X implementation.
1759 */
1760 if (map != NULL)
1761 free(map, M_DEVBUF);
1762}
1763
1764int
1765ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
1766{
1767 /* Nothing to do */
1768 return (0);
1769}
1770
1771/********************* Platform Dependent Functions ***************************/
1772/*
1773 * Compare "left hand" softc with "right hand" softc, returning:
1774 * < 0 - lahd has a lower priority than rahd
1775 * 0 - Softcs are equal
1776 * > 0 - lahd has a higher priority than rahd
1777 */
1778int
1779ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd)
1780{
1781 int value;
1782
1783 /*
1784 * Under Linux, cards are ordered as follows:
1785 * 1) PCI devices that are marked as the boot controller.
1786 * 2) PCI devices with BIOS enabled sorted by bus/slot/func.
1787 * 3) All remaining PCI devices sorted by bus/slot/func.
1788 */
1789#if 0
1790 value = (lahd->flags & AHD_BOOT_CHANNEL)
1791 - (rahd->flags & AHD_BOOT_CHANNEL);
1792 if (value != 0)
1793 /* Controllers set for boot have a *higher* priority */
1794 return (value);
1795#endif
1796
1797 value = (lahd->flags & AHD_BIOS_ENABLED)
1798 - (rahd->flags & AHD_BIOS_ENABLED);
1799 if (value != 0)
1800 /* Controllers with BIOS enabled have a *higher* priority */
1801 return (value);
1802
1803 /* Still equal. Sort by bus/slot/func. */
1804 if (aic79xx_reverse_scan != 0)
1805 value = ahd_get_pci_bus(lahd->dev_softc)
1806 - ahd_get_pci_bus(rahd->dev_softc);
1807 else
1808 value = ahd_get_pci_bus(rahd->dev_softc)
1809 - ahd_get_pci_bus(lahd->dev_softc);
1810 if (value != 0)
1811 return (value);
1812 if (aic79xx_reverse_scan != 0)
1813 value = ahd_get_pci_slot(lahd->dev_softc)
1814 - ahd_get_pci_slot(rahd->dev_softc);
1815 else
1816 value = ahd_get_pci_slot(rahd->dev_softc)
1817 - ahd_get_pci_slot(lahd->dev_softc);
1818 if (value != 0)
1819 return (value);
1820
1821 value = rahd->channel - lahd->channel;
1822 return (value);
1823}
1824
1825static void
1826ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
1827{
1828
1829 if ((instance >= 0) && (targ >= 0)
1830 && (instance < NUM_ELEMENTS(aic79xx_tag_info))
1831 && (targ < AHD_NUM_TARGETS)) {
1832 aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF;
1833 if (bootverbose)
1834 printf("tag_info[%d:%d] = %d\n", instance, targ, value);
1835 }
1836}
1837
1838static void
1839ahd_linux_setup_rd_strm_info(u_long arg, int instance, int targ, int32_t value)
1840{
1841 if ((instance >= 0)
1842 && (instance < NUM_ELEMENTS(aic79xx_rd_strm_info))) {
1843 aic79xx_rd_strm_info[instance] = value & 0xFFFF;
1844 if (bootverbose)
1845 printf("rd_strm[%d] = 0x%x\n", instance, value);
1846 }
1847}
1848
1849static void
1850ahd_linux_setup_dv(u_long arg, int instance, int targ, int32_t value)
1851{
1852 if ((instance >= 0)
1853 && (instance < NUM_ELEMENTS(aic79xx_dv_settings))) {
1854 aic79xx_dv_settings[instance] = value;
1855 if (bootverbose)
1856 printf("dv[%d] = %d\n", instance, value);
1857 }
1858}
1859
1860static void
1861ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
1862{
1863
1864 if ((instance >= 0)
1865 && (instance < NUM_ELEMENTS(aic79xx_iocell_info))) {
1866 uint8_t *iocell_info;
1867
1868 iocell_info = (uint8_t*)&aic79xx_iocell_info[instance];
1869 iocell_info[index] = value & 0xFFFF;
1870 if (bootverbose)
1871 printf("iocell[%d:%ld] = %d\n", instance, index, value);
1872 }
1873}
1874
1875static void
1876ahd_linux_setup_tag_info_global(char *p)
1877{
1878 int tags, i, j;
1879
1880 tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
1881 printf("Setting Global Tags= %d\n", tags);
1882
1883 for (i = 0; i < NUM_ELEMENTS(aic79xx_tag_info); i++) {
1884 for (j = 0; j < AHD_NUM_TARGETS; j++) {
1885 aic79xx_tag_info[i].tag_commands[j] = tags;
1886 }
1887 }
1888}
1889
1890/*
1891 * Handle Linux boot parameters. This routine allows for assigning a value
1892 * to a parameter with a ':' between the parameter and the value.
1893 * ie. aic79xx=stpwlev:1,extended
1894 */
1895static int
1896aic79xx_setup(char *s)
1897{
1898 int i, n;
1899 char *p;
1900 char *end;
1901
1902 static struct {
1903 const char *name;
1904 uint32_t *flag;
1905 } options[] = {
1906 { "extended", &aic79xx_extended },
1907 { "no_reset", &aic79xx_no_reset },
1908 { "verbose", &aic79xx_verbose },
1909 { "allow_memio", &aic79xx_allow_memio},
1910#ifdef AHD_DEBUG
1911 { "debug", &ahd_debug },
1912#endif
1913 { "reverse_scan", &aic79xx_reverse_scan },
1914 { "periodic_otag", &aic79xx_periodic_otag },
1915 { "pci_parity", &aic79xx_pci_parity },
1916 { "seltime", &aic79xx_seltime },
1917 { "tag_info", NULL },
1918 { "global_tag_depth", NULL},
1919 { "rd_strm", NULL },
1920 { "dv", NULL },
1921 { "slewrate", NULL },
1922 { "precomp", NULL },
1923 { "amplitude", NULL },
1924 };
1925
1926 end = strchr(s, '\0');
1927
1928 /*
1929 * XXX ia64 gcc isn't smart enough to know that NUM_ELEMENTS
1930 * will never be 0 in this case.
1931 */
1932 n = 0;
1933
1934 while ((p = strsep(&s, ",.")) != NULL) {
1935 if (*p == '\0')
1936 continue;
1937 for (i = 0; i < NUM_ELEMENTS(options); i++) {
1938
1939 n = strlen(options[i].name);
1940 if (strncmp(options[i].name, p, n) == 0)
1941 break;
1942 }
1943 if (i == NUM_ELEMENTS(options))
1944 continue;
1945
1946 if (strncmp(p, "global_tag_depth", n) == 0) {
1947 ahd_linux_setup_tag_info_global(p + n);
1948 } else if (strncmp(p, "tag_info", n) == 0) {
1949 s = aic_parse_brace_option("tag_info", p + n, end,
1950 2, ahd_linux_setup_tag_info, 0);
1951 } else if (strncmp(p, "rd_strm", n) == 0) {
1952 s = aic_parse_brace_option("rd_strm", p + n, end,
1953 1, ahd_linux_setup_rd_strm_info, 0);
1954 } else if (strncmp(p, "dv", n) == 0) {
1955 s = aic_parse_brace_option("dv", p + n, end, 1,
1956 ahd_linux_setup_dv, 0);
1957 } else if (strncmp(p, "slewrate", n) == 0) {
1958 s = aic_parse_brace_option("slewrate",
1959 p + n, end, 1, ahd_linux_setup_iocell_info,
1960 AIC79XX_SLEWRATE_INDEX);
1961 } else if (strncmp(p, "precomp", n) == 0) {
1962 s = aic_parse_brace_option("precomp",
1963 p + n, end, 1, ahd_linux_setup_iocell_info,
1964 AIC79XX_PRECOMP_INDEX);
1965 } else if (strncmp(p, "amplitude", n) == 0) {
1966 s = aic_parse_brace_option("amplitude",
1967 p + n, end, 1, ahd_linux_setup_iocell_info,
1968 AIC79XX_AMPLITUDE_INDEX);
1969 } else if (p[n] == ':') {
1970 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
1971 } else if (!strncmp(p, "verbose", n)) {
1972 *(options[i].flag) = 1;
1973 } else {
1974 *(options[i].flag) ^= 0xFFFFFFFF;
1975 }
1976 }
1977 return 1;
1978}
1979
1980__setup("aic79xx=", aic79xx_setup);
1981
1982uint32_t aic79xx_verbose;
1983
1984int
1985ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template)
1986{
1987 char buf[80];
1988 struct Scsi_Host *host;
1989 char *new_name;
1990 u_long s;
1991 u_long target;
1992
1993 template->name = ahd->description;
1994 host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
1995 if (host == NULL)
1996 return (ENOMEM);
1997
1998 *((struct ahd_softc **)host->hostdata) = ahd;
1999 ahd_lock(ahd, &s);
2000#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2001 scsi_assign_lock(host, &ahd->platform_data->spin_lock);
2002#elif AHD_SCSI_HAS_HOST_LOCK != 0
2003 host->lock = &ahd->platform_data->spin_lock;
2004#endif
2005 ahd->platform_data->host = host;
2006 host->can_queue = AHD_MAX_QUEUE;
2007 host->cmd_per_lun = 2;
2008 host->sg_tablesize = AHD_NSEG;
2009 host->this_id = ahd->our_id;
2010 host->irq = ahd->platform_data->irq;
2011 host->max_id = (ahd->features & AHD_WIDE) ? 16 : 8;
2012 host->max_lun = AHD_NUM_LUNS;
2013 host->max_channel = 0;
2014 host->sg_tablesize = AHD_NSEG;
2015 ahd_set_unit(ahd, ahd_linux_next_unit());
2016 sprintf(buf, "scsi%d", host->host_no);
2017 new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
2018 if (new_name != NULL) {
2019 strcpy(new_name, buf);
2020 ahd_set_name(ahd, new_name);
2021 }
2022 host->unique_id = ahd->unit;
2023#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2024 scsi_set_pci_device(host, ahd->dev_softc);
2025#endif
2026 ahd_linux_setup_user_rd_strm_settings(ahd);
2027 ahd_linux_initialize_scsi_bus(ahd);
2028 ahd_unlock(ahd, &s);
2029 ahd->platform_data->dv_pid = kernel_thread(ahd_linux_dv_thread, ahd, 0);
2030 ahd_lock(ahd, &s);
2031 if (ahd->platform_data->dv_pid < 0) {
2032 printf("%s: Failed to create DV thread, error= %d\n",
2033 ahd_name(ahd), ahd->platform_data->dv_pid);
2034 return (-ahd->platform_data->dv_pid);
2035 }
2036 /*
2037 * Initially allocate *all* of our linux target objects
2038 * so that the DV thread will scan them all in parallel
2039 * just after driver initialization. Any device that
2040 * does not exist will have its target object destroyed
2041 * by the selection timeout handler. In the case of a
2042 * device that appears after the initial DV scan, async
2043 * negotiation will occur for the first command, and DV
2044 * will comence should that first command be successful.
2045 */
2046 for (target = 0; target < host->max_id; target++) {
2047
2048 /*
2049 * Skip our own ID. Some Compaq/HP storage devices
2050 * have enclosure management devices that respond to
2051 * single bit selection (i.e. selecting ourselves).
2052 * It is expected that either an external application
2053 * or a modified kernel will be used to probe this
2054 * ID if it is appropriate. To accommodate these
2055 * installations, ahc_linux_alloc_target() will allocate
2056 * for our ID if asked to do so.
2057 */
2058 if (target == ahd->our_id)
2059 continue;
2060
2061 ahd_linux_alloc_target(ahd, 0, target);
2062 }
2063 ahd_intr_enable(ahd, TRUE);
2064 ahd_linux_start_dv(ahd);
2065 ahd_unlock(ahd, &s);
2066
2067#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2068 scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */
2069 scsi_scan_host(host);
2070#endif
2071 return (0);
2072}
2073
2074uint64_t
2075ahd_linux_get_memsize(void)
2076{
2077 struct sysinfo si;
2078
2079 si_meminfo(&si);
2080 return ((uint64_t)si.totalram << PAGE_SHIFT);
2081}
2082
2083/*
2084 * Find the smallest available unit number to use
2085 * for a new device. We don't just use a static
2086 * count to handle the "repeated hot-(un)plug"
2087 * scenario.
2088 */
2089static int
2090ahd_linux_next_unit(void)
2091{
2092 struct ahd_softc *ahd;
2093 int unit;
2094
2095 unit = 0;
2096retry:
2097 TAILQ_FOREACH(ahd, &ahd_tailq, links) {
2098 if (ahd->unit == unit) {
2099 unit++;
2100 goto retry;
2101 }
2102 }
2103 return (unit);
2104}
2105
2106/*
2107 * Place the SCSI bus into a known state by either resetting it,
2108 * or forcing transfer negotiations on the next command to any
2109 * target.
2110 */
2111static void
2112ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd)
2113{
2114 u_int target_id;
2115 u_int numtarg;
2116
2117 target_id = 0;
2118 numtarg = 0;
2119
2120 if (aic79xx_no_reset != 0)
2121 ahd->flags &= ~AHD_RESET_BUS_A;
2122
2123 if ((ahd->flags & AHD_RESET_BUS_A) != 0)
2124 ahd_reset_channel(ahd, 'A', /*initiate_reset*/TRUE);
2125 else
2126 numtarg = (ahd->features & AHD_WIDE) ? 16 : 8;
2127
2128 /*
2129 * Force negotiation to async for all targets that
2130 * will not see an initial bus reset.
2131 */
2132 for (; target_id < numtarg; target_id++) {
2133 struct ahd_devinfo devinfo;
2134 struct ahd_initiator_tinfo *tinfo;
2135 struct ahd_tmode_tstate *tstate;
2136
2137 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
2138 target_id, &tstate);
2139 ahd_compile_devinfo(&devinfo, ahd->our_id, target_id,
2140 CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR);
2141 ahd_update_neg_request(ahd, &devinfo, tstate,
2142 tinfo, AHD_NEG_ALWAYS);
2143 }
2144 /* Give the bus some time to recover */
2145 if ((ahd->flags & AHD_RESET_BUS_A) != 0) {
2146 ahd_freeze_simq(ahd);
2147 init_timer(&ahd->platform_data->reset_timer);
2148 ahd->platform_data->reset_timer.data = (u_long)ahd;
2149 ahd->platform_data->reset_timer.expires =
2150 jiffies + (AIC79XX_RESET_DELAY * HZ)/1000;
2151 ahd->platform_data->reset_timer.function =
2152 (ahd_linux_callback_t *)ahd_release_simq;
2153 add_timer(&ahd->platform_data->reset_timer);
2154 }
2155}
2156
2157int
2158ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg)
2159{
2160 ahd->platform_data =
2161 malloc(sizeof(struct ahd_platform_data), M_DEVBUF, M_NOWAIT);
2162 if (ahd->platform_data == NULL)
2163 return (ENOMEM);
2164 memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data));
2165 TAILQ_INIT(&ahd->platform_data->completeq);
2166 TAILQ_INIT(&ahd->platform_data->device_runq);
2167 ahd->platform_data->irq = AHD_LINUX_NOIRQ;
2168 ahd->platform_data->hw_dma_mask = 0xFFFFFFFF;
2169 ahd_lockinit(ahd);
2170 ahd_done_lockinit(ahd);
2171 init_timer(&ahd->platform_data->completeq_timer);
2172 ahd->platform_data->completeq_timer.data = (u_long)ahd;
2173 ahd->platform_data->completeq_timer.function =
2174 (ahd_linux_callback_t *)ahd_linux_thread_run_complete_queue;
2175 init_MUTEX_LOCKED(&ahd->platform_data->eh_sem);
2176 init_MUTEX_LOCKED(&ahd->platform_data->dv_sem);
2177 init_MUTEX_LOCKED(&ahd->platform_data->dv_cmd_sem);
2178 ahd_setup_runq_tasklet(ahd);
2179 ahd->seltime = (aic79xx_seltime & 0x3) << 4;
2180 return (0);
2181}
2182
2183void
2184ahd_platform_free(struct ahd_softc *ahd)
2185{
2186 struct ahd_linux_target *targ;
2187 struct ahd_linux_device *dev;
2188 int i, j;
2189
2190 if (ahd->platform_data != NULL) {
2191 del_timer_sync(&ahd->platform_data->completeq_timer);
2192 ahd_linux_kill_dv_thread(ahd);
2193 ahd_teardown_runq_tasklet(ahd);
2194 if (ahd->platform_data->host != NULL) {
2195#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2196 scsi_remove_host(ahd->platform_data->host);
2197#endif
2198 scsi_host_put(ahd->platform_data->host);
2199 }
2200
2201 /* destroy all of the device and target objects */
2202 for (i = 0; i < AHD_NUM_TARGETS; i++) {
2203 targ = ahd->platform_data->targets[i];
2204 if (targ != NULL) {
2205 /* Keep target around through the loop. */
2206 targ->refcount++;
2207 for (j = 0; j < AHD_NUM_LUNS; j++) {
2208
2209 if (targ->devices[j] == NULL)
2210 continue;
2211 dev = targ->devices[j];
2212 ahd_linux_free_device(ahd, dev);
2213 }
2214 /*
2215 * Forcibly free the target now that
2216 * all devices are gone.
2217 */
2218 ahd_linux_free_target(ahd, targ);
2219 }
2220 }
2221
2222 if (ahd->platform_data->irq != AHD_LINUX_NOIRQ)
2223 free_irq(ahd->platform_data->irq, ahd);
2224 if (ahd->tags[0] == BUS_SPACE_PIO
2225 && ahd->bshs[0].ioport != 0)
2226 release_region(ahd->bshs[0].ioport, 256);
2227 if (ahd->tags[1] == BUS_SPACE_PIO
2228 && ahd->bshs[1].ioport != 0)
2229 release_region(ahd->bshs[1].ioport, 256);
2230 if (ahd->tags[0] == BUS_SPACE_MEMIO
2231 && ahd->bshs[0].maddr != NULL) {
2232 iounmap(ahd->bshs[0].maddr);
2233 release_mem_region(ahd->platform_data->mem_busaddr,
2234 0x1000);
2235 }
2236#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2237 /*
2238 * In 2.4 we detach from the scsi midlayer before the PCI
2239 * layer invokes our remove callback. No per-instance
2240 * detach is provided, so we must reach inside the PCI
2241 * subsystem's internals and detach our driver manually.
2242 */
2243 if (ahd->dev_softc != NULL)
2244 ahd->dev_softc->driver = NULL;
2245#endif
2246 free(ahd->platform_data, M_DEVBUF);
2247 }
2248}
2249
2250void
2251ahd_platform_init(struct ahd_softc *ahd)
2252{
2253 /*
2254 * Lookup and commit any modified IO Cell options.
2255 */
2256 if (ahd->unit < NUM_ELEMENTS(aic79xx_iocell_info)) {
2257 struct ahd_linux_iocell_opts *iocell_opts;
2258
2259 iocell_opts = &aic79xx_iocell_info[ahd->unit];
2260 if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP)
2261 AHD_SET_PRECOMP(ahd, iocell_opts->precomp);
2262 if (iocell_opts->slewrate != AIC79XX_DEFAULT_SLEWRATE)
2263 AHD_SET_SLEWRATE(ahd, iocell_opts->slewrate);
2264 if (iocell_opts->amplitude != AIC79XX_DEFAULT_AMPLITUDE)
2265 AHD_SET_AMPLITUDE(ahd, iocell_opts->amplitude);
2266 }
2267
2268}
2269
2270void
2271ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
2272{
2273 ahd_platform_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
2274 SCB_GET_CHANNEL(ahd, scb),
2275 SCB_GET_LUN(scb), SCB_LIST_NULL,
2276 ROLE_UNKNOWN, CAM_REQUEUE_REQ);
2277}
2278
2279void
2280ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
2281 ahd_queue_alg alg)
2282{
2283 struct ahd_linux_device *dev;
2284 int was_queuing;
2285 int now_queuing;
2286
2287 dev = ahd_linux_get_device(ahd, devinfo->channel - 'A',
2288 devinfo->target,
2289 devinfo->lun, /*alloc*/FALSE);
2290 if (dev == NULL)
2291 return;
2292 was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED);
2293 switch (alg) {
2294 default:
2295 case AHD_QUEUE_NONE:
2296 now_queuing = 0;
2297 break;
2298 case AHD_QUEUE_BASIC:
2299 now_queuing = AHD_DEV_Q_BASIC;
2300 break;
2301 case AHD_QUEUE_TAGGED:
2302 now_queuing = AHD_DEV_Q_TAGGED;
2303 break;
2304 }
2305 if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0
2306 && (was_queuing != now_queuing)
2307 && (dev->active != 0)) {
2308 dev->flags |= AHD_DEV_FREEZE_TIL_EMPTY;
2309 dev->qfrozen++;
2310 }
2311
2312 dev->flags &= ~(AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED|AHD_DEV_PERIODIC_OTAG);
2313 if (now_queuing) {
2314 u_int usertags;
2315
2316 usertags = ahd_linux_user_tagdepth(ahd, devinfo);
2317 if (!was_queuing) {
2318 /*
2319 * Start out agressively and allow our
2320 * dynamic queue depth algorithm to take
2321 * care of the rest.
2322 */
2323 dev->maxtags = usertags;
2324 dev->openings = dev->maxtags - dev->active;
2325 }
2326 if (dev->maxtags == 0) {
2327 /*
2328 * Queueing is disabled by the user.
2329 */
2330 dev->openings = 1;
2331 } else if (alg == AHD_QUEUE_TAGGED) {
2332 dev->flags |= AHD_DEV_Q_TAGGED;
2333 if (aic79xx_periodic_otag != 0)
2334 dev->flags |= AHD_DEV_PERIODIC_OTAG;
2335 } else
2336 dev->flags |= AHD_DEV_Q_BASIC;
2337 } else {
2338 /* We can only have one opening. */
2339 dev->maxtags = 0;
2340 dev->openings = 1 - dev->active;
2341 }
2342#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2343 if (dev->scsi_device != NULL) {
2344 switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
2345 case AHD_DEV_Q_BASIC:
2346 scsi_adjust_queue_depth(dev->scsi_device,
2347 MSG_SIMPLE_TASK,
2348 dev->openings + dev->active);
2349 break;
2350 case AHD_DEV_Q_TAGGED:
2351 scsi_adjust_queue_depth(dev->scsi_device,
2352 MSG_ORDERED_TASK,
2353 dev->openings + dev->active);
2354 break;
2355 default:
2356 /*
2357 * We allow the OS to queue 2 untagged transactions to
2358 * us at any time even though we can only execute them
2359 * serially on the controller/device. This should
2360 * remove some latency.
2361 */
2362 scsi_adjust_queue_depth(dev->scsi_device,
2363 /*NON-TAGGED*/0,
2364 /*queue depth*/2);
2365 break;
2366 }
2367 }
2368#endif
2369}
2370
2371int
2372ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel,
2373 int lun, u_int tag, role_t role, uint32_t status)
2374{
2375 int targ;
2376 int maxtarg;
2377 int maxlun;
2378 int clun;
2379 int count;
2380
2381 if (tag != SCB_LIST_NULL)
2382 return (0);
2383
2384 targ = 0;
2385 if (target != CAM_TARGET_WILDCARD) {
2386 targ = target;
2387 maxtarg = targ + 1;
2388 } else {
2389 maxtarg = (ahd->features & AHD_WIDE) ? 16 : 8;
2390 }
2391 clun = 0;
2392 if (lun != CAM_LUN_WILDCARD) {
2393 clun = lun;
2394 maxlun = clun + 1;
2395 } else {
2396 maxlun = AHD_NUM_LUNS;
2397 }
2398
2399 count = 0;
2400 for (; targ < maxtarg; targ++) {
2401
2402 for (; clun < maxlun; clun++) {
2403 struct ahd_linux_device *dev;
2404 struct ahd_busyq *busyq;
2405 struct ahd_cmd *acmd;
2406
2407 dev = ahd_linux_get_device(ahd, /*chan*/0, targ,
2408 clun, /*alloc*/FALSE);
2409 if (dev == NULL)
2410 continue;
2411
2412 busyq = &dev->busyq;
2413 while ((acmd = TAILQ_FIRST(busyq)) != NULL) {
2414 Scsi_Cmnd *cmd;
2415
2416 cmd = &acmd_scsi_cmd(acmd);
2417 TAILQ_REMOVE(busyq, acmd,
2418 acmd_links.tqe);
2419 count++;
2420 cmd->result = status << 16;
2421 ahd_linux_queue_cmd_complete(ahd, cmd);
2422 }
2423 }
2424 }
2425
2426 return (count);
2427}
2428
2429static void
2430ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd)
2431{
2432 u_long flags;
2433
2434 ahd_lock(ahd, &flags);
2435 del_timer(&ahd->platform_data->completeq_timer);
2436 ahd->platform_data->flags &= ~AHD_RUN_CMPLT_Q_TIMER;
2437 ahd_linux_run_complete_queue(ahd);
2438 ahd_unlock(ahd, &flags);
2439}
2440
2441static void
2442ahd_linux_start_dv(struct ahd_softc *ahd)
2443{
2444
2445 /*
2446 * Freeze the simq and signal ahd_linux_queue to not let any
2447 * more commands through
2448 */
2449 if ((ahd->platform_data->flags & AHD_DV_ACTIVE) == 0) {
2450#ifdef AHD_DEBUG
2451 if (ahd_debug & AHD_SHOW_DV)
2452 printf("%s: Starting DV\n", ahd_name(ahd));
2453#endif
2454
2455 ahd->platform_data->flags |= AHD_DV_ACTIVE;
2456 ahd_freeze_simq(ahd);
2457
2458 /* Wake up the DV kthread */
2459 up(&ahd->platform_data->dv_sem);
2460 }
2461}
2462
2463static int
2464ahd_linux_dv_thread(void *data)
2465{
2466 struct ahd_softc *ahd;
2467 int target;
2468 u_long s;
2469
2470 ahd = (struct ahd_softc *)data;
2471
2472#ifdef AHD_DEBUG
2473 if (ahd_debug & AHD_SHOW_DV)
2474 printf("In DV Thread\n");
2475#endif
2476
2477 /*
2478 * Complete thread creation.
2479 */
2480 lock_kernel();
2481#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
2482 /*
2483 * Don't care about any signals.
2484 */
2485 siginitsetinv(&current->blocked, 0);
2486
2487 daemonize();
2488 sprintf(current->comm, "ahd_dv_%d", ahd->unit);
2489#else
2490 daemonize("ahd_dv_%d", ahd->unit);
2491 current->flags |= PF_FREEZE;
2492#endif
2493 unlock_kernel();
2494
2495 while (1) {
2496 /*
2497 * Use down_interruptible() rather than down() to
2498 * avoid inclusion in the load average.
2499 */
2500 down_interruptible(&ahd->platform_data->dv_sem);
2501
2502 /* Check to see if we've been signaled to exit */
2503 ahd_lock(ahd, &s);
2504 if ((ahd->platform_data->flags & AHD_DV_SHUTDOWN) != 0) {
2505 ahd_unlock(ahd, &s);
2506 break;
2507 }
2508 ahd_unlock(ahd, &s);
2509
2510#ifdef AHD_DEBUG
2511 if (ahd_debug & AHD_SHOW_DV)
2512 printf("%s: Beginning Domain Validation\n",
2513 ahd_name(ahd));
2514#endif
2515
2516 /*
2517 * Wait for any pending commands to drain before proceeding.
2518 */
2519 ahd_lock(ahd, &s);
2520 while (LIST_FIRST(&ahd->pending_scbs) != NULL) {
2521 ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_EMPTY;
2522 ahd_unlock(ahd, &s);
2523 down_interruptible(&ahd->platform_data->dv_sem);
2524 ahd_lock(ahd, &s);
2525 }
2526
2527 /*
2528 * Wait for the SIMQ to be released so that DV is the
2529 * only reason the queue is frozen.
2530 */
2531 while (AHD_DV_SIMQ_FROZEN(ahd) == 0) {
2532 ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE;
2533 ahd_unlock(ahd, &s);
2534 down_interruptible(&ahd->platform_data->dv_sem);
2535 ahd_lock(ahd, &s);
2536 }
2537 ahd_unlock(ahd, &s);
2538
2539 for (target = 0; target < AHD_NUM_TARGETS; target++)
2540 ahd_linux_dv_target(ahd, target);
2541
2542 ahd_lock(ahd, &s);
2543 ahd->platform_data->flags &= ~AHD_DV_ACTIVE;
2544 ahd_unlock(ahd, &s);
2545
2546 /*
2547 * Release the SIMQ so that normal commands are
2548 * allowed to continue on the bus.
2549 */
2550 ahd_release_simq(ahd);
2551 }
2552 up(&ahd->platform_data->eh_sem);
2553 return (0);
2554}
2555
2556static void
2557ahd_linux_kill_dv_thread(struct ahd_softc *ahd)
2558{
2559 u_long s;
2560
2561 ahd_lock(ahd, &s);
2562 if (ahd->platform_data->dv_pid != 0) {
2563 ahd->platform_data->flags |= AHD_DV_SHUTDOWN;
2564 ahd_unlock(ahd, &s);
2565 up(&ahd->platform_data->dv_sem);
2566
2567 /*
2568 * Use the eh_sem as an indicator that the
2569 * dv thread is exiting. Note that the dv
2570 * thread must still return after performing
2571 * the up on our semaphore before it has
2572 * completely exited this module. Unfortunately,
2573 * there seems to be no easy way to wait for the
2574 * exit of a thread for which you are not the
2575 * parent (dv threads are parented by init).
2576 * Cross your fingers...
2577 */
2578 down(&ahd->platform_data->eh_sem);
2579
2580 /*
2581 * Mark the dv thread as already dead. This
2582 * avoids attempting to kill it a second time.
2583 * This is necessary because we must kill the
2584 * DV thread before calling ahd_free() in the
2585 * module shutdown case to avoid bogus locking
2586 * in the SCSI mid-layer, but we ahd_free() is
2587 * called without killing the DV thread in the
2588 * instance detach case, so ahd_platform_free()
2589 * calls us again to verify that the DV thread
2590 * is dead.
2591 */
2592 ahd->platform_data->dv_pid = 0;
2593 } else {
2594 ahd_unlock(ahd, &s);
2595 }
2596}
2597
2598#define AHD_LINUX_DV_INQ_SHORT_LEN 36
2599#define AHD_LINUX_DV_INQ_LEN 256
2600#define AHD_LINUX_DV_TIMEOUT (HZ / 4)
2601
2602#define AHD_SET_DV_STATE(ahd, targ, newstate) \
2603 ahd_set_dv_state(ahd, targ, newstate, __LINE__)
2604
2605static __inline void
2606ahd_set_dv_state(struct ahd_softc *ahd, struct ahd_linux_target *targ,
2607 ahd_dv_state newstate, u_int line)
2608{
2609 ahd_dv_state oldstate;
2610
2611 oldstate = targ->dv_state;
2612#ifdef AHD_DEBUG
2613 if (ahd_debug & AHD_SHOW_DV)
2614 printf("%s:%d: Going from state %d to state %d\n",
2615 ahd_name(ahd), line, oldstate, newstate);
2616#endif
2617
2618 if (oldstate == newstate)
2619 targ->dv_state_retry++;
2620 else
2621 targ->dv_state_retry = 0;
2622 targ->dv_state = newstate;
2623}
2624
2625static void
2626ahd_linux_dv_target(struct ahd_softc *ahd, u_int target_offset)
2627{
2628 struct ahd_devinfo devinfo;
2629 struct ahd_linux_target *targ;
2630 struct scsi_cmnd *cmd;
2631 struct scsi_device *scsi_dev;
2632 struct scsi_sense_data *sense;
2633 uint8_t *buffer;
2634 u_long s;
2635 u_int timeout;
2636 int echo_size;
2637
2638 sense = NULL;
2639 buffer = NULL;
2640 echo_size = 0;
2641 ahd_lock(ahd, &s);
2642 targ = ahd->platform_data->targets[target_offset];
2643 if (targ == NULL || (targ->flags & AHD_DV_REQUIRED) == 0) {
2644 ahd_unlock(ahd, &s);
2645 return;
2646 }
2647 ahd_compile_devinfo(&devinfo, ahd->our_id, targ->target, /*lun*/0,
2648 targ->channel + 'A', ROLE_INITIATOR);
2649#ifdef AHD_DEBUG
2650 if (ahd_debug & AHD_SHOW_DV) {
2651 ahd_print_devinfo(ahd, &devinfo);
2652 printf("Performing DV\n");
2653 }
2654#endif
2655
2656 ahd_unlock(ahd, &s);
2657
2658 cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK);
2659 scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK);
2660 scsi_dev->host = ahd->platform_data->host;
2661 scsi_dev->id = devinfo.target;
2662 scsi_dev->lun = devinfo.lun;
2663 scsi_dev->channel = devinfo.channel - 'A';
2664 ahd->platform_data->dv_scsi_dev = scsi_dev;
2665
2666 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_SHORT_ASYNC);
2667
2668 while (targ->dv_state != AHD_DV_STATE_EXIT) {
2669 timeout = AHD_LINUX_DV_TIMEOUT;
2670 switch (targ->dv_state) {
2671 case AHD_DV_STATE_INQ_SHORT_ASYNC:
2672 case AHD_DV_STATE_INQ_ASYNC:
2673 case AHD_DV_STATE_INQ_ASYNC_VERIFY:
2674 /*
2675 * Set things to async narrow to reduce the
2676 * chance that the INQ will fail.
2677 */
2678 ahd_lock(ahd, &s);
2679 ahd_set_syncrate(ahd, &devinfo, 0, 0, 0,
2680 AHD_TRANS_GOAL, /*paused*/FALSE);
2681 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
2682 AHD_TRANS_GOAL, /*paused*/FALSE);
2683 ahd_unlock(ahd, &s);
2684 timeout = 10 * HZ;
2685 targ->flags &= ~AHD_INQ_VALID;
2686 /* FALLTHROUGH */
2687 case AHD_DV_STATE_INQ_VERIFY:
2688 {
2689 u_int inq_len;
2690
2691 if (targ->dv_state == AHD_DV_STATE_INQ_SHORT_ASYNC)
2692 inq_len = AHD_LINUX_DV_INQ_SHORT_LEN;
2693 else
2694 inq_len = targ->inq_data->additional_length + 5;
2695 ahd_linux_dv_inq(ahd, cmd, &devinfo, targ, inq_len);
2696 break;
2697 }
2698 case AHD_DV_STATE_TUR:
2699 case AHD_DV_STATE_BUSY:
2700 timeout = 5 * HZ;
2701 ahd_linux_dv_tur(ahd, cmd, &devinfo);
2702 break;
2703 case AHD_DV_STATE_REBD:
2704 ahd_linux_dv_rebd(ahd, cmd, &devinfo, targ);
2705 break;
2706 case AHD_DV_STATE_WEB:
2707 ahd_linux_dv_web(ahd, cmd, &devinfo, targ);
2708 break;
2709
2710 case AHD_DV_STATE_REB:
2711 ahd_linux_dv_reb(ahd, cmd, &devinfo, targ);
2712 break;
2713
2714 case AHD_DV_STATE_SU:
2715 ahd_linux_dv_su(ahd, cmd, &devinfo, targ);
2716 timeout = 50 * HZ;
2717 break;
2718
2719 default:
2720 ahd_print_devinfo(ahd, &devinfo);
2721 printf("Unknown DV state %d\n", targ->dv_state);
2722 goto out;
2723 }
2724
2725 /* Queue the command and wait for it to complete */
2726 /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */
2727 init_timer(&cmd->eh_timeout);
2728#ifdef AHD_DEBUG
2729 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2730 /*
2731 * All of the printfs during negotiation
2732 * really slow down the negotiation.
2733 * Add a bit of time just to be safe.
2734 */
2735 timeout += HZ;
2736#endif
2737 scsi_add_timer(cmd, timeout, ahd_linux_dv_timeout);
2738 /*
2739 * In 2.5.X, it is assumed that all calls from the
2740 * "midlayer" (which we are emulating) will have the
2741 * ahd host lock held. For other kernels, the
2742 * io_request_lock must be held.
2743 */
2744#if AHD_SCSI_HAS_HOST_LOCK != 0
2745 ahd_lock(ahd, &s);
2746#else
2747 spin_lock_irqsave(&io_request_lock, s);
2748#endif
2749 ahd_linux_queue(cmd, ahd_linux_dv_complete);
2750#if AHD_SCSI_HAS_HOST_LOCK != 0
2751 ahd_unlock(ahd, &s);
2752#else
2753 spin_unlock_irqrestore(&io_request_lock, s);
2754#endif
2755 down_interruptible(&ahd->platform_data->dv_cmd_sem);
2756 /*
2757 * Wait for the SIMQ to be released so that DV is the
2758 * only reason the queue is frozen.
2759 */
2760 ahd_lock(ahd, &s);
2761 while (AHD_DV_SIMQ_FROZEN(ahd) == 0) {
2762 ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE;
2763 ahd_unlock(ahd, &s);
2764 down_interruptible(&ahd->platform_data->dv_sem);
2765 ahd_lock(ahd, &s);
2766 }
2767 ahd_unlock(ahd, &s);
2768
2769 ahd_linux_dv_transition(ahd, cmd, &devinfo, targ);
2770 }
2771
2772out:
2773 if ((targ->flags & AHD_INQ_VALID) != 0
2774 && ahd_linux_get_device(ahd, devinfo.channel - 'A',
2775 devinfo.target, devinfo.lun,
2776 /*alloc*/FALSE) == NULL) {
2777 /*
2778 * The DV state machine failed to configure this device.
2779 * This is normal if DV is disabled. Since we have inquiry
2780 * data, filter it and use the "optimistic" negotiation
2781 * parameters found in the inquiry string.
2782 */
2783 ahd_linux_filter_inquiry(ahd, &devinfo);
2784 if ((targ->flags & (AHD_BASIC_DV|AHD_ENHANCED_DV)) != 0) {
2785 ahd_print_devinfo(ahd, &devinfo);
2786 printf("DV failed to configure device. "
2787 "Please file a bug report against "
2788 "this driver.\n");
2789 }
2790 }
2791
2792 if (cmd != NULL)
2793 free(cmd, M_DEVBUF);
2794
2795 if (ahd->platform_data->dv_scsi_dev != NULL) {
2796 free(ahd->platform_data->dv_scsi_dev, M_DEVBUF);
2797 ahd->platform_data->dv_scsi_dev = NULL;
2798 }
2799
2800 ahd_lock(ahd, &s);
2801 if (targ->dv_buffer != NULL) {
2802 free(targ->dv_buffer, M_DEVBUF);
2803 targ->dv_buffer = NULL;
2804 }
2805 if (targ->dv_buffer1 != NULL) {
2806 free(targ->dv_buffer1, M_DEVBUF);
2807 targ->dv_buffer1 = NULL;
2808 }
2809 targ->flags &= ~AHD_DV_REQUIRED;
2810 if (targ->refcount == 0)
2811 ahd_linux_free_target(ahd, targ);
2812 ahd_unlock(ahd, &s);
2813}
2814
2815static __inline int
2816ahd_linux_dv_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
2817{
2818 u_long s;
2819 int retval;
2820
2821 ahd_lock(ahd, &s);
2822 retval = ahd_linux_fallback(ahd, devinfo);
2823 ahd_unlock(ahd, &s);
2824
2825 return (retval);
2826}
2827
2828static void
2829ahd_linux_dv_transition(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
2830 struct ahd_devinfo *devinfo,
2831 struct ahd_linux_target *targ)
2832{
2833 u_int32_t status;
2834
2835 status = aic_error_action(cmd, targ->inq_data,
2836 ahd_cmd_get_transaction_status(cmd),
2837 ahd_cmd_get_scsi_status(cmd));
2838
2839
2840#ifdef AHD_DEBUG
2841 if (ahd_debug & AHD_SHOW_DV) {
2842 ahd_print_devinfo(ahd, devinfo);
2843 printf("Entering ahd_linux_dv_transition, state= %d, "
2844 "status= 0x%x, cmd->result= 0x%x\n", targ->dv_state,
2845 status, cmd->result);
2846 }
2847#endif
2848
2849 switch (targ->dv_state) {
2850 case AHD_DV_STATE_INQ_SHORT_ASYNC:
2851 case AHD_DV_STATE_INQ_ASYNC:
2852 switch (status & SS_MASK) {
2853 case SS_NOP:
2854 {
2855 AHD_SET_DV_STATE(ahd, targ, targ->dv_state+1);
2856 break;
2857 }
2858 case SS_INQ_REFRESH:
2859 AHD_SET_DV_STATE(ahd, targ,
2860 AHD_DV_STATE_INQ_SHORT_ASYNC);
2861 break;
2862 case SS_TUR:
2863 case SS_RETRY:
2864 AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
2865 if (ahd_cmd_get_transaction_status(cmd)
2866 == CAM_REQUEUE_REQ)
2867 targ->dv_state_retry--;
2868 if ((status & SS_ERRMASK) == EBUSY)
2869 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY);
2870 if (targ->dv_state_retry < 10)
2871 break;
2872 /* FALLTHROUGH */
2873 default:
2874 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
2875#ifdef AHD_DEBUG
2876 if (ahd_debug & AHD_SHOW_DV) {
2877 ahd_print_devinfo(ahd, devinfo);
2878 printf("Failed DV inquiry, skipping\n");
2879 }
2880#endif
2881 break;
2882 }
2883 break;
2884 case AHD_DV_STATE_INQ_ASYNC_VERIFY:
2885 switch (status & SS_MASK) {
2886 case SS_NOP:
2887 {
2888 u_int xportflags;
2889 u_int spi3data;
2890
2891 if (memcmp(targ->inq_data, targ->dv_buffer,
2892 AHD_LINUX_DV_INQ_LEN) != 0) {
2893 /*
2894 * Inquiry data must have changed.
2895 * Try from the top again.
2896 */
2897 AHD_SET_DV_STATE(ahd, targ,
2898 AHD_DV_STATE_INQ_SHORT_ASYNC);
2899 break;
2900 }
2901
2902 AHD_SET_DV_STATE(ahd, targ, targ->dv_state+1);
2903 targ->flags |= AHD_INQ_VALID;
2904 if (ahd_linux_user_dv_setting(ahd) == 0)
2905 break;
2906
2907 xportflags = targ->inq_data->flags;
2908 if ((xportflags & (SID_Sync|SID_WBus16)) == 0)
2909 break;
2910
2911 spi3data = targ->inq_data->spi3data;
2912 switch (spi3data & SID_SPI_CLOCK_DT_ST) {
2913 default:
2914 case SID_SPI_CLOCK_ST:
2915 /* Assume only basic DV is supported. */
2916 targ->flags |= AHD_BASIC_DV;
2917 break;
2918 case SID_SPI_CLOCK_DT:
2919 case SID_SPI_CLOCK_DT_ST:
2920 targ->flags |= AHD_ENHANCED_DV;
2921 break;
2922 }
2923 break;
2924 }
2925 case SS_INQ_REFRESH:
2926 AHD_SET_DV_STATE(ahd, targ,
2927 AHD_DV_STATE_INQ_SHORT_ASYNC);
2928 break;
2929 case SS_TUR:
2930 case SS_RETRY:
2931 AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
2932 if (ahd_cmd_get_transaction_status(cmd)
2933 == CAM_REQUEUE_REQ)
2934 targ->dv_state_retry--;
2935
2936 if ((status & SS_ERRMASK) == EBUSY)
2937 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY);
2938 if (targ->dv_state_retry < 10)
2939 break;
2940 /* FALLTHROUGH */
2941 default:
2942 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
2943#ifdef AHD_DEBUG
2944 if (ahd_debug & AHD_SHOW_DV) {
2945 ahd_print_devinfo(ahd, devinfo);
2946 printf("Failed DV inquiry, skipping\n");
2947 }
2948#endif
2949 break;
2950 }
2951 break;
2952 case AHD_DV_STATE_INQ_VERIFY:
2953 switch (status & SS_MASK) {
2954 case SS_NOP:
2955 {
2956
2957 if (memcmp(targ->inq_data, targ->dv_buffer,
2958 AHD_LINUX_DV_INQ_LEN) == 0) {
2959 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
2960 break;
2961 }
2962
2963#ifdef AHD_DEBUG
2964 if (ahd_debug & AHD_SHOW_DV) {
2965 int i;
2966
2967 ahd_print_devinfo(ahd, devinfo);
2968 printf("Inquiry buffer mismatch:");
2969 for (i = 0; i < AHD_LINUX_DV_INQ_LEN; i++) {
2970 if ((i & 0xF) == 0)
2971 printf("\n ");
2972 printf("0x%x:0x0%x ",
2973 ((uint8_t *)targ->inq_data)[i],
2974 targ->dv_buffer[i]);
2975 }
2976 printf("\n");
2977 }
2978#endif
2979
2980 if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
2981 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
2982 break;
2983 }
2984 /*
2985 * Do not count "falling back"
2986 * against our retries.
2987 */
2988 targ->dv_state_retry = 0;
2989 AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
2990 break;
2991 }
2992 case SS_INQ_REFRESH:
2993 AHD_SET_DV_STATE(ahd, targ,
2994 AHD_DV_STATE_INQ_SHORT_ASYNC);
2995 break;
2996 case SS_TUR:
2997 case SS_RETRY:
2998 AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
2999 if (ahd_cmd_get_transaction_status(cmd)
3000 == CAM_REQUEUE_REQ) {
3001 targ->dv_state_retry--;
3002 } else if ((status & SSQ_FALLBACK) != 0) {
3003 if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
3004 AHD_SET_DV_STATE(ahd, targ,
3005 AHD_DV_STATE_EXIT);
3006 break;
3007 }
3008 /*
3009 * Do not count "falling back"
3010 * against our retries.
3011 */
3012 targ->dv_state_retry = 0;
3013 } else if ((status & SS_ERRMASK) == EBUSY)
3014 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY);
3015 if (targ->dv_state_retry < 10)
3016 break;
3017 /* FALLTHROUGH */
3018 default:
3019 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3020#ifdef AHD_DEBUG
3021 if (ahd_debug & AHD_SHOW_DV) {
3022 ahd_print_devinfo(ahd, devinfo);
3023 printf("Failed DV inquiry, skipping\n");
3024 }
3025#endif
3026 break;
3027 }
3028 break;
3029
3030 case AHD_DV_STATE_TUR:
3031 switch (status & SS_MASK) {
3032 case SS_NOP:
3033 if ((targ->flags & AHD_BASIC_DV) != 0) {
3034 ahd_linux_filter_inquiry(ahd, devinfo);
3035 AHD_SET_DV_STATE(ahd, targ,
3036 AHD_DV_STATE_INQ_VERIFY);
3037 } else if ((targ->flags & AHD_ENHANCED_DV) != 0) {
3038 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REBD);
3039 } else {
3040 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3041 }
3042 break;
3043 case SS_RETRY:
3044 case SS_TUR:
3045 if ((status & SS_ERRMASK) == EBUSY) {
3046 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY);
3047 break;
3048 }
3049 AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
3050 if (ahd_cmd_get_transaction_status(cmd)
3051 == CAM_REQUEUE_REQ) {
3052 targ->dv_state_retry--;
3053 } else if ((status & SSQ_FALLBACK) != 0) {
3054 if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
3055 AHD_SET_DV_STATE(ahd, targ,
3056 AHD_DV_STATE_EXIT);
3057 break;
3058 }
3059 /*
3060 * Do not count "falling back"
3061 * against our retries.
3062 */
3063 targ->dv_state_retry = 0;
3064 }
3065 if (targ->dv_state_retry >= 10) {
3066#ifdef AHD_DEBUG
3067 if (ahd_debug & AHD_SHOW_DV) {
3068 ahd_print_devinfo(ahd, devinfo);
3069 printf("DV TUR reties exhausted\n");
3070 }
3071#endif
3072 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3073 break;
3074 }
3075 if (status & SSQ_DELAY)
3076 ssleep(1);
3077
3078 break;
3079 case SS_START:
3080 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_SU);
3081 break;
3082 case SS_INQ_REFRESH:
3083 AHD_SET_DV_STATE(ahd, targ,
3084 AHD_DV_STATE_INQ_SHORT_ASYNC);
3085 break;
3086 default:
3087 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3088 break;
3089 }
3090 break;
3091
3092 case AHD_DV_STATE_REBD:
3093 switch (status & SS_MASK) {
3094 case SS_NOP:
3095 {
3096 uint32_t echo_size;
3097
3098 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB);
3099 echo_size = scsi_3btoul(&targ->dv_buffer[1]);
3100 echo_size &= 0x1FFF;
3101#ifdef AHD_DEBUG
3102 if (ahd_debug & AHD_SHOW_DV) {
3103 ahd_print_devinfo(ahd, devinfo);
3104 printf("Echo buffer size= %d\n", echo_size);
3105 }
3106#endif
3107 if (echo_size == 0) {
3108 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3109 break;
3110 }
3111
3112 /* Generate the buffer pattern */
3113 targ->dv_echo_size = echo_size;
3114 ahd_linux_generate_dv_pattern(targ);
3115 /*
3116 * Setup initial negotiation values.
3117 */
3118 ahd_linux_filter_inquiry(ahd, devinfo);
3119 break;
3120 }
3121 case SS_INQ_REFRESH:
3122 AHD_SET_DV_STATE(ahd, targ,
3123 AHD_DV_STATE_INQ_SHORT_ASYNC);
3124 break;
3125 case SS_RETRY:
3126 AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
3127 if (ahd_cmd_get_transaction_status(cmd)
3128 == CAM_REQUEUE_REQ)
3129 targ->dv_state_retry--;
3130 if (targ->dv_state_retry <= 10)
3131 break;
3132#ifdef AHD_DEBUG
3133 if (ahd_debug & AHD_SHOW_DV) {
3134 ahd_print_devinfo(ahd, devinfo);
3135 printf("DV REBD reties exhausted\n");
3136 }
3137#endif
3138 /* FALLTHROUGH */
3139 case SS_FATAL:
3140 default:
3141 /*
3142 * Setup initial negotiation values
3143 * and try level 1 DV.
3144 */
3145 ahd_linux_filter_inquiry(ahd, devinfo);
3146 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_VERIFY);
3147 targ->dv_echo_size = 0;
3148 break;
3149 }
3150 break;
3151
3152 case AHD_DV_STATE_WEB:
3153 switch (status & SS_MASK) {
3154 case SS_NOP:
3155 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REB);
3156 break;
3157 case SS_INQ_REFRESH:
3158 AHD_SET_DV_STATE(ahd, targ,
3159 AHD_DV_STATE_INQ_SHORT_ASYNC);
3160 break;
3161 case SS_RETRY:
3162 AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
3163 if (ahd_cmd_get_transaction_status(cmd)
3164 == CAM_REQUEUE_REQ) {
3165 targ->dv_state_retry--;
3166 } else if ((status & SSQ_FALLBACK) != 0) {
3167 if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
3168 AHD_SET_DV_STATE(ahd, targ,
3169 AHD_DV_STATE_EXIT);
3170 break;
3171 }
3172 /*
3173 * Do not count "falling back"
3174 * against our retries.
3175 */
3176 targ->dv_state_retry = 0;
3177 }
3178 if (targ->dv_state_retry <= 10)
3179 break;
3180 /* FALLTHROUGH */
3181#ifdef AHD_DEBUG
3182 if (ahd_debug & AHD_SHOW_DV) {
3183 ahd_print_devinfo(ahd, devinfo);
3184 printf("DV WEB reties exhausted\n");
3185 }
3186#endif
3187 default:
3188 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3189 break;
3190 }
3191 break;
3192
3193 case AHD_DV_STATE_REB:
3194 switch (status & SS_MASK) {
3195 case SS_NOP:
3196 if (memcmp(targ->dv_buffer, targ->dv_buffer1,
3197 targ->dv_echo_size) != 0) {
3198 if (ahd_linux_dv_fallback(ahd, devinfo) != 0)
3199 AHD_SET_DV_STATE(ahd, targ,
3200 AHD_DV_STATE_EXIT);
3201 else
3202 AHD_SET_DV_STATE(ahd, targ,
3203 AHD_DV_STATE_WEB);
3204 break;
3205 }
3206
3207 if (targ->dv_buffer != NULL) {
3208 free(targ->dv_buffer, M_DEVBUF);
3209 targ->dv_buffer = NULL;
3210 }
3211 if (targ->dv_buffer1 != NULL) {
3212 free(targ->dv_buffer1, M_DEVBUF);
3213 targ->dv_buffer1 = NULL;
3214 }
3215 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3216 break;
3217 case SS_INQ_REFRESH:
3218 AHD_SET_DV_STATE(ahd, targ,
3219 AHD_DV_STATE_INQ_SHORT_ASYNC);
3220 break;
3221 case SS_RETRY:
3222 AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
3223 if (ahd_cmd_get_transaction_status(cmd)
3224 == CAM_REQUEUE_REQ) {
3225 targ->dv_state_retry--;
3226 } else if ((status & SSQ_FALLBACK) != 0) {
3227 if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
3228 AHD_SET_DV_STATE(ahd, targ,
3229 AHD_DV_STATE_EXIT);
3230 break;
3231 }
3232 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB);
3233 }
3234 if (targ->dv_state_retry <= 10) {
3235 if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0)
3236 msleep(ahd->our_id*1000/10);
3237 break;
3238 }
3239#ifdef AHD_DEBUG
3240 if (ahd_debug & AHD_SHOW_DV) {
3241 ahd_print_devinfo(ahd, devinfo);
3242 printf("DV REB reties exhausted\n");
3243 }
3244#endif
3245 /* FALLTHROUGH */
3246 default:
3247 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3248 break;
3249 }
3250 break;
3251
3252 case AHD_DV_STATE_SU:
3253 switch (status & SS_MASK) {
3254 case SS_NOP:
3255 case SS_INQ_REFRESH:
3256 AHD_SET_DV_STATE(ahd, targ,
3257 AHD_DV_STATE_INQ_SHORT_ASYNC);
3258 break;
3259 default:
3260 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3261 break;
3262 }
3263 break;
3264
3265 case AHD_DV_STATE_BUSY:
3266 switch (status & SS_MASK) {
3267 case SS_NOP:
3268 case SS_INQ_REFRESH:
3269 AHD_SET_DV_STATE(ahd, targ,
3270 AHD_DV_STATE_INQ_SHORT_ASYNC);
3271 break;
3272 case SS_TUR:
3273 case SS_RETRY:
3274 AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
3275 if (ahd_cmd_get_transaction_status(cmd)
3276 == CAM_REQUEUE_REQ) {
3277 targ->dv_state_retry--;
3278 } else if (targ->dv_state_retry < 60) {
3279 if ((status & SSQ_DELAY) != 0)
3280 ssleep(1);
3281 } else {
3282#ifdef AHD_DEBUG
3283 if (ahd_debug & AHD_SHOW_DV) {
3284 ahd_print_devinfo(ahd, devinfo);
3285 printf("DV BUSY reties exhausted\n");
3286 }
3287#endif
3288 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3289 }
3290 break;
3291 default:
3292 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3293 break;
3294 }
3295 break;
3296
3297 default:
3298 printf("%s: Invalid DV completion state %d\n", ahd_name(ahd),
3299 targ->dv_state);
3300 AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
3301 break;
3302 }
3303}
3304
3305static void
3306ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
3307 struct ahd_devinfo *devinfo)
3308{
3309 memset(cmd, 0, sizeof(struct scsi_cmnd));
3310 cmd->device = ahd->platform_data->dv_scsi_dev;
3311 cmd->scsi_done = ahd_linux_dv_complete;
3312}
3313
3314/*
3315 * Synthesize an inquiry command. On the return trip, it'll be
3316 * sniffed and the device transfer settings set for us.
3317 */
3318static void
3319ahd_linux_dv_inq(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
3320 struct ahd_devinfo *devinfo, struct ahd_linux_target *targ,
3321 u_int request_length)
3322{
3323
3324#ifdef AHD_DEBUG
3325 if (ahd_debug & AHD_SHOW_DV) {
3326 ahd_print_devinfo(ahd, devinfo);
3327 printf("Sending INQ\n");
3328 }
3329#endif
3330 if (targ->inq_data == NULL)
3331 targ->inq_data = malloc(AHD_LINUX_DV_INQ_LEN,
3332 M_DEVBUF, M_WAITOK);
3333 if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC) {
3334 if (targ->dv_buffer != NULL)
3335 free(targ->dv_buffer, M_DEVBUF);
3336 targ->dv_buffer = malloc(AHD_LINUX_DV_INQ_LEN,
3337 M_DEVBUF, M_WAITOK);
3338 }
3339
3340 ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
3341 cmd->sc_data_direction = SCSI_DATA_READ;
3342 cmd->cmd_len = 6;
3343 cmd->cmnd[0] = INQUIRY;
3344 cmd->cmnd[4] = request_length;
3345 cmd->request_bufflen = request_length;
3346 if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC)
3347 cmd->request_buffer = targ->dv_buffer;
3348 else
3349 cmd->request_buffer = targ->inq_data;
3350 memset(cmd->request_buffer, 0, AHD_LINUX_DV_INQ_LEN);
3351}
3352
3353static void
3354ahd_linux_dv_tur(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
3355 struct ahd_devinfo *devinfo)
3356{
3357
3358#ifdef AHD_DEBUG
3359 if (ahd_debug & AHD_SHOW_DV) {
3360 ahd_print_devinfo(ahd, devinfo);
3361 printf("Sending TUR\n");
3362 }
3363#endif
3364 /* Do a TUR to clear out any non-fatal transitional state */
3365 ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
3366 cmd->sc_data_direction = SCSI_DATA_NONE;
3367 cmd->cmd_len = 6;
3368 cmd->cmnd[0] = TEST_UNIT_READY;
3369}
3370
3371#define AHD_REBD_LEN 4
3372
3373static void
3374ahd_linux_dv_rebd(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
3375 struct ahd_devinfo *devinfo, struct ahd_linux_target *targ)
3376{
3377
3378#ifdef AHD_DEBUG
3379 if (ahd_debug & AHD_SHOW_DV) {
3380 ahd_print_devinfo(ahd, devinfo);
3381 printf("Sending REBD\n");
3382 }
3383#endif
3384 if (targ->dv_buffer != NULL)
3385 free(targ->dv_buffer, M_DEVBUF);
3386 targ->dv_buffer = malloc(AHD_REBD_LEN, M_DEVBUF, M_WAITOK);
3387 ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
3388 cmd->sc_data_direction = SCSI_DATA_READ;
3389 cmd->cmd_len = 10;
3390 cmd->cmnd[0] = READ_BUFFER;
3391 cmd->cmnd[1] = 0x0b;
3392 scsi_ulto3b(AHD_REBD_LEN, &cmd->cmnd[6]);
3393 cmd->request_bufflen = AHD_REBD_LEN;
3394 cmd->underflow = cmd->request_bufflen;
3395 cmd->request_buffer = targ->dv_buffer;
3396}
3397
3398static void
3399ahd_linux_dv_web(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
3400 struct ahd_devinfo *devinfo, struct ahd_linux_target *targ)
3401{
3402
3403#ifdef AHD_DEBUG
3404 if (ahd_debug & AHD_SHOW_DV) {
3405 ahd_print_devinfo(ahd, devinfo);
3406 printf("Sending WEB\n");
3407 }
3408#endif
3409 ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
3410 cmd->sc_data_direction = SCSI_DATA_WRITE;
3411 cmd->cmd_len = 10;
3412 cmd->cmnd[0] = WRITE_BUFFER;
3413 cmd->cmnd[1] = 0x0a;
3414 scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]);
3415 cmd->request_bufflen = targ->dv_echo_size;
3416 cmd->underflow = cmd->request_bufflen;
3417 cmd->request_buffer = targ->dv_buffer;
3418}
3419
3420static void
3421ahd_linux_dv_reb(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
3422 struct ahd_devinfo *devinfo, struct ahd_linux_target *targ)
3423{
3424
3425#ifdef AHD_DEBUG
3426 if (ahd_debug & AHD_SHOW_DV) {
3427 ahd_print_devinfo(ahd, devinfo);
3428 printf("Sending REB\n");
3429 }
3430#endif
3431 ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
3432 cmd->sc_data_direction = SCSI_DATA_READ;
3433 cmd->cmd_len = 10;
3434 cmd->cmnd[0] = READ_BUFFER;
3435 cmd->cmnd[1] = 0x0a;
3436 scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]);
3437 cmd->request_bufflen = targ->dv_echo_size;
3438 cmd->underflow = cmd->request_bufflen;
3439 cmd->request_buffer = targ->dv_buffer1;
3440}
3441
3442static void
3443ahd_linux_dv_su(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
3444 struct ahd_devinfo *devinfo,
3445 struct ahd_linux_target *targ)
3446{
3447 u_int le;
3448
3449 le = SID_IS_REMOVABLE(targ->inq_data) ? SSS_LOEJ : 0;
3450
3451#ifdef AHD_DEBUG
3452 if (ahd_debug & AHD_SHOW_DV) {
3453 ahd_print_devinfo(ahd, devinfo);
3454 printf("Sending SU\n");
3455 }
3456#endif
3457 ahd_linux_dv_fill_cmd(ahd, cmd, devinfo);
3458 cmd->sc_data_direction = SCSI_DATA_NONE;
3459 cmd->cmd_len = 6;
3460 cmd->cmnd[0] = START_STOP_UNIT;
3461 cmd->cmnd[4] = le | SSS_START;
3462}
3463
3464static int
3465ahd_linux_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3466{
3467 struct ahd_linux_target *targ;
3468 struct ahd_initiator_tinfo *tinfo;
3469 struct ahd_transinfo *goal;
3470 struct ahd_tmode_tstate *tstate;
3471 u_int width;
3472 u_int period;
3473 u_int offset;
3474 u_int ppr_options;
3475 u_int cur_speed;
3476 u_int wide_speed;
3477 u_int narrow_speed;
3478 u_int fallback_speed;
3479
3480#ifdef AHD_DEBUG
3481 if (ahd_debug & AHD_SHOW_DV) {
3482 ahd_print_devinfo(ahd, devinfo);
3483 printf("Trying to fallback\n");
3484 }
3485#endif
3486 targ = ahd->platform_data->targets[devinfo->target_offset];
3487 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel,
3488 devinfo->our_scsiid,
3489 devinfo->target, &tstate);
3490 goal = &tinfo->goal;
3491 width = goal->width;
3492 period = goal->period;
3493 offset = goal->offset;
3494 ppr_options = goal->ppr_options;
3495 if (offset == 0)
3496 period = AHD_ASYNC_XFER_PERIOD;
3497 if (targ->dv_next_narrow_period == 0)
3498 targ->dv_next_narrow_period = MAX(period, AHD_SYNCRATE_ULTRA2);
3499 if (targ->dv_next_wide_period == 0)
3500 targ->dv_next_wide_period = period;
3501 if (targ->dv_max_width == 0)
3502 targ->dv_max_width = width;
3503 if (targ->dv_max_ppr_options == 0)
3504 targ->dv_max_ppr_options = ppr_options;
3505 if (targ->dv_last_ppr_options == 0)
3506 targ->dv_last_ppr_options = ppr_options;
3507
3508 cur_speed = aic_calc_speed(width, period, offset, AHD_SYNCRATE_MIN);
3509 wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT,
3510 targ->dv_next_wide_period,
3511 MAX_OFFSET, AHD_SYNCRATE_MIN);
3512 narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT,
3513 targ->dv_next_narrow_period,
3514 MAX_OFFSET, AHD_SYNCRATE_MIN);
3515 fallback_speed = aic_calc_speed(width, period+1, offset,
3516 AHD_SYNCRATE_MIN);
3517#ifdef AHD_DEBUG
3518 if (ahd_debug & AHD_SHOW_DV) {
3519 printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, "
3520 "fallback_speed= %d\n", cur_speed, wide_speed,
3521 narrow_speed, fallback_speed);
3522 }
3523#endif
3524
3525 if (cur_speed > 160000) {
3526 /*
3527 * Paced/DT/IU_REQ only transfer speeds. All we
3528 * can do is fallback in terms of syncrate.
3529 */
3530 period++;
3531 } else if (cur_speed > 80000) {
3532 if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
3533 /*
3534 * Try without IU_REQ as it may be confusing
3535 * an expander.
3536 */
3537 ppr_options &= ~MSG_EXT_PPR_IU_REQ;
3538 } else {
3539 /*
3540 * Paced/DT only transfer speeds. All we
3541 * can do is fallback in terms of syncrate.
3542 */
3543 period++;
3544 ppr_options = targ->dv_max_ppr_options;
3545 }
3546 } else if (cur_speed > 3300) {
3547
3548 /*
3549 * In this range we the following
3550 * options ordered from highest to
3551 * lowest desireability:
3552 *
3553 * o Wide/DT
3554 * o Wide/non-DT
3555 * o Narrow at a potentally higher sync rate.
3556 *
3557 * All modes are tested with and without IU_REQ
3558 * set since using IUs may confuse an expander.
3559 */
3560 if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
3561
3562 ppr_options &= ~MSG_EXT_PPR_IU_REQ;
3563 } else if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
3564 /*
3565 * Try going non-DT.
3566 */
3567 ppr_options = targ->dv_max_ppr_options;
3568 ppr_options &= ~MSG_EXT_PPR_DT_REQ;
3569 } else if (targ->dv_last_ppr_options != 0) {
3570 /*
3571 * Try without QAS or any other PPR options.
3572 * We may need a non-PPR message to work with
3573 * an expander. We look at the "last PPR options"
3574 * so we will perform this fallback even if the
3575 * target responded to our PPR negotiation with
3576 * no option bits set.
3577 */
3578 ppr_options = 0;
3579 } else if (width == MSG_EXT_WDTR_BUS_16_BIT) {
3580 /*
3581 * If the next narrow speed is greater than
3582 * the next wide speed, fallback to narrow.
3583 * Otherwise fallback to the next DT/Wide setting.
3584 * The narrow async speed will always be smaller
3585 * than the wide async speed, so handle this case
3586 * specifically.
3587 */
3588 ppr_options = targ->dv_max_ppr_options;
3589 if (narrow_speed > fallback_speed
3590 || period >= AHD_ASYNC_XFER_PERIOD) {
3591 targ->dv_next_wide_period = period+1;
3592 width = MSG_EXT_WDTR_BUS_8_BIT;
3593 period = targ->dv_next_narrow_period;
3594 } else {
3595 period++;
3596 }
3597 } else if ((ahd->features & AHD_WIDE) != 0
3598 && targ->dv_max_width != 0
3599 && wide_speed >= fallback_speed
3600 && (targ->dv_next_wide_period <= AHD_ASYNC_XFER_PERIOD
3601 || period >= AHD_ASYNC_XFER_PERIOD)) {
3602
3603 /*
3604 * We are narrow. Try falling back
3605 * to the next wide speed with
3606 * all supported ppr options set.
3607 */
3608 targ->dv_next_narrow_period = period+1;
3609 width = MSG_EXT_WDTR_BUS_16_BIT;
3610 period = targ->dv_next_wide_period;
3611 ppr_options = targ->dv_max_ppr_options;
3612 } else {
3613 /* Only narrow fallback is allowed. */
3614 period++;
3615 ppr_options = targ->dv_max_ppr_options;
3616 }
3617 } else {
3618 return (-1);
3619 }
3620 offset = MAX_OFFSET;
3621 ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_PACED);
3622 ahd_set_width(ahd, devinfo, width, AHD_TRANS_GOAL, FALSE);
3623 if (period == 0) {
3624 period = 0;
3625 offset = 0;
3626 ppr_options = 0;
3627 if (width == MSG_EXT_WDTR_BUS_8_BIT)
3628 targ->dv_next_narrow_period = AHD_ASYNC_XFER_PERIOD;
3629 else
3630 targ->dv_next_wide_period = AHD_ASYNC_XFER_PERIOD;
3631 }
3632 ahd_set_syncrate(ahd, devinfo, period, offset,
3633 ppr_options, AHD_TRANS_GOAL, FALSE);
3634 targ->dv_last_ppr_options = ppr_options;
3635 return (0);
3636}
3637
3638static void
3639ahd_linux_dv_timeout(struct scsi_cmnd *cmd)
3640{
3641 struct ahd_softc *ahd;
3642 struct scb *scb;
3643 u_long flags;
3644
3645 ahd = *((struct ahd_softc **)cmd->device->host->hostdata);
3646 ahd_lock(ahd, &flags);
3647
3648#ifdef AHD_DEBUG
3649 if (ahd_debug & AHD_SHOW_DV) {
3650 printf("%s: Timeout while doing DV command %x.\n",
3651 ahd_name(ahd), cmd->cmnd[0]);
3652 ahd_dump_card_state(ahd);
3653 }
3654#endif
3655
3656 /*
3657 * Guard against "done race". No action is
3658 * required if we just completed.
3659 */
3660 if ((scb = (struct scb *)cmd->host_scribble) == NULL) {
3661 ahd_unlock(ahd, &flags);
3662 return;
3663 }
3664
3665 /*
3666 * Command has not completed. Mark this
3667 * SCB as having failing status prior to
3668 * resetting the bus, so we get the correct
3669 * error code.
3670 */
3671 if ((scb->flags & SCB_SENSE) != 0)
3672 ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
3673 else
3674 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
3675 ahd_reset_channel(ahd, cmd->device->channel + 'A', /*initiate*/TRUE);
3676
3677 /*
3678 * Add a minimal bus settle delay for devices that are slow to
3679 * respond after bus resets.
3680 */
3681 ahd_freeze_simq(ahd);
3682 init_timer(&ahd->platform_data->reset_timer);
3683 ahd->platform_data->reset_timer.data = (u_long)ahd;
3684 ahd->platform_data->reset_timer.expires = jiffies + HZ / 2;
3685 ahd->platform_data->reset_timer.function =
3686 (ahd_linux_callback_t *)ahd_release_simq;
3687 add_timer(&ahd->platform_data->reset_timer);
3688 if (ahd_linux_next_device_to_run(ahd) != NULL)
3689 ahd_schedule_runq(ahd);
3690 ahd_linux_run_complete_queue(ahd);
3691 ahd_unlock(ahd, &flags);
3692}
3693
3694static void
3695ahd_linux_dv_complete(struct scsi_cmnd *cmd)
3696{
3697 struct ahd_softc *ahd;
3698
3699 ahd = *((struct ahd_softc **)cmd->device->host->hostdata);
3700
3701 /* Delete the DV timer before it goes off! */
3702 scsi_delete_timer(cmd);
3703
3704#ifdef AHD_DEBUG
3705 if (ahd_debug & AHD_SHOW_DV)
3706 printf("%s:%c:%d: Command completed, status= 0x%x\n",
3707 ahd_name(ahd), cmd->device->channel, cmd->device->id,
3708 cmd->result);
3709#endif
3710
3711 /* Wake up the state machine */
3712 up(&ahd->platform_data->dv_cmd_sem);
3713}
3714
3715static void
3716ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ)
3717{
3718 uint16_t b;
3719 u_int i;
3720 u_int j;
3721
3722 if (targ->dv_buffer != NULL)
3723 free(targ->dv_buffer, M_DEVBUF);
3724 targ->dv_buffer = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK);
3725 if (targ->dv_buffer1 != NULL)
3726 free(targ->dv_buffer1, M_DEVBUF);
3727 targ->dv_buffer1 = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK);
3728
3729 i = 0;
3730
3731 b = 0x0001;
3732 for (j = 0 ; i < targ->dv_echo_size; j++) {
3733 if (j < 32) {
3734 /*
3735 * 32bytes of sequential numbers.
3736 */
3737 targ->dv_buffer[i++] = j & 0xff;
3738 } else if (j < 48) {
3739 /*
3740 * 32bytes of repeating 0x0000, 0xffff.
3741 */
3742 targ->dv_buffer[i++] = (j & 0x02) ? 0xff : 0x00;
3743 } else if (j < 64) {
3744 /*
3745 * 32bytes of repeating 0x5555, 0xaaaa.
3746 */
3747 targ->dv_buffer[i++] = (j & 0x02) ? 0xaa : 0x55;
3748 } else {
3749 /*
3750 * Remaining buffer is filled with a repeating
3751 * patter of:
3752 *
3753 * 0xffff
3754 * ~0x0001 << shifted once in each loop.
3755 */
3756 if (j & 0x02) {
3757 if (j & 0x01) {
3758 targ->dv_buffer[i++] = ~(b >> 8) & 0xff;
3759 b <<= 1;
3760 if (b == 0x0000)
3761 b = 0x0001;
3762 } else {
3763 targ->dv_buffer[i++] = (~b & 0xff);
3764 }
3765 } else {
3766 targ->dv_buffer[i++] = 0xff;
3767 }
3768 }
3769 }
3770}
3771
3772static u_int
3773ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3774{
3775 static int warned_user;
3776 u_int tags;
3777
3778 tags = 0;
3779 if ((ahd->user_discenable & devinfo->target_mask) != 0) {
3780 if (ahd->unit >= NUM_ELEMENTS(aic79xx_tag_info)) {
3781
3782 if (warned_user == 0) {
3783 printf(KERN_WARNING
3784"aic79xx: WARNING: Insufficient tag_info instances\n"
3785"aic79xx: for installed controllers. Using defaults\n"
3786"aic79xx: Please update the aic79xx_tag_info array in\n"
3787"aic79xx: the aic79xx_osm.c source file.\n");
3788 warned_user++;
3789 }
3790 tags = AHD_MAX_QUEUE;
3791 } else {
3792 adapter_tag_info_t *tag_info;
3793
3794 tag_info = &aic79xx_tag_info[ahd->unit];
3795 tags = tag_info->tag_commands[devinfo->target_offset];
3796 if (tags > AHD_MAX_QUEUE)
3797 tags = AHD_MAX_QUEUE;
3798 }
3799 }
3800 return (tags);
3801}
3802
3803static u_int
3804ahd_linux_user_dv_setting(struct ahd_softc *ahd)
3805{
3806 static int warned_user;
3807 int dv;
3808
3809 if (ahd->unit >= NUM_ELEMENTS(aic79xx_dv_settings)) {
3810
3811 if (warned_user == 0) {
3812 printf(KERN_WARNING
3813"aic79xx: WARNING: Insufficient dv settings instances\n"
3814"aic79xx: for installed controllers. Using defaults\n"
3815"aic79xx: Please update the aic79xx_dv_settings array in"
3816"aic79xx: the aic79xx_osm.c source file.\n");
3817 warned_user++;
3818 }
3819 dv = -1;
3820 } else {
3821
3822 dv = aic79xx_dv_settings[ahd->unit];
3823 }
3824
3825 if (dv < 0) {
3826 /*
3827 * Apply the default.
3828 */
3829 dv = 1;
3830 if (ahd->seep_config != 0)
3831 dv = (ahd->seep_config->bios_control & CFENABLEDV);
3832 }
3833 return (dv);
3834}
3835
3836static void
3837ahd_linux_setup_user_rd_strm_settings(struct ahd_softc *ahd)
3838{
3839 static int warned_user;
3840 u_int rd_strm_mask;
3841 u_int target_id;
3842
3843 /*
3844 * If we have specific read streaming info for this controller,
3845 * apply it. Otherwise use the defaults.
3846 */
3847 if (ahd->unit >= NUM_ELEMENTS(aic79xx_rd_strm_info)) {
3848
3849 if (warned_user == 0) {
3850
3851 printf(KERN_WARNING
3852"aic79xx: WARNING: Insufficient rd_strm instances\n"
3853"aic79xx: for installed controllers. Using defaults\n"
3854"aic79xx: Please update the aic79xx_rd_strm_info array\n"
3855"aic79xx: in the aic79xx_osm.c source file.\n");
3856 warned_user++;
3857 }
3858 rd_strm_mask = AIC79XX_CONFIGED_RD_STRM;
3859 } else {
3860
3861 rd_strm_mask = aic79xx_rd_strm_info[ahd->unit];
3862 }
3863 for (target_id = 0; target_id < 16; target_id++) {
3864 struct ahd_devinfo devinfo;
3865 struct ahd_initiator_tinfo *tinfo;
3866 struct ahd_tmode_tstate *tstate;
3867
3868 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
3869 target_id, &tstate);
3870 ahd_compile_devinfo(&devinfo, ahd->our_id, target_id,
3871 CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR);
3872 tinfo->user.ppr_options &= ~MSG_EXT_PPR_RD_STRM;
3873 if ((rd_strm_mask & devinfo.target_mask) != 0)
3874 tinfo->user.ppr_options |= MSG_EXT_PPR_RD_STRM;
3875 }
3876}
3877
3878/*
3879 * Determines the queue depth for a given device.
3880 */
3881static void
3882ahd_linux_device_queue_depth(struct ahd_softc *ahd,
3883 struct ahd_linux_device *dev)
3884{
3885 struct ahd_devinfo devinfo;
3886 u_int tags;
3887
3888 ahd_compile_devinfo(&devinfo,
3889 ahd->our_id,
3890 dev->target->target, dev->lun,
3891 dev->target->channel == 0 ? 'A' : 'B',
3892 ROLE_INITIATOR);
3893 tags = ahd_linux_user_tagdepth(ahd, &devinfo);
3894 if (tags != 0
3895 && dev->scsi_device != NULL
3896 && dev->scsi_device->tagged_supported != 0) {
3897
3898 ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED);
3899 ahd_print_devinfo(ahd, &devinfo);
3900 printf("Tagged Queuing enabled. Depth %d\n", tags);
3901 } else {
3902 ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE);
3903 }
3904}
3905
3906static void
3907ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev)
3908{
3909 struct ahd_cmd *acmd;
3910 struct scsi_cmnd *cmd;
3911 struct scb *scb;
3912 struct hardware_scb *hscb;
3913 struct ahd_initiator_tinfo *tinfo;
3914 struct ahd_tmode_tstate *tstate;
3915 u_int col_idx;
3916 uint16_t mask;
3917
3918 if ((dev->flags & AHD_DEV_ON_RUN_LIST) != 0)
3919 panic("running device on run list");
3920
3921 while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL
3922 && dev->openings > 0 && dev->qfrozen == 0) {
3923
3924 /*
3925 * Schedule us to run later. The only reason we are not
3926 * running is because the whole controller Q is frozen.
3927 */
3928 if (ahd->platform_data->qfrozen != 0
3929 && AHD_DV_SIMQ_FROZEN(ahd) == 0) {
3930
3931 TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq,
3932 dev, links);
3933 dev->flags |= AHD_DEV_ON_RUN_LIST;
3934 return;
3935 }
3936
3937 cmd = &acmd_scsi_cmd(acmd);
3938
3939 /*
3940 * Get an scb to use.
3941 */
3942 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
3943 cmd->device->id, &tstate);
3944 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0
3945 || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
3946 col_idx = AHD_NEVER_COL_IDX;
3947 } else {
3948 col_idx = AHD_BUILD_COL_IDX(cmd->device->id,
3949 cmd->device->lun);
3950 }
3951 if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
3952 TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq,
3953 dev, links);
3954 dev->flags |= AHD_DEV_ON_RUN_LIST;
3955 ahd->flags |= AHD_RESOURCE_SHORTAGE;
3956 return;
3957 }
3958 TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe);
3959 scb->io_ctx = cmd;
3960 scb->platform_data->dev = dev;
3961 hscb = scb->hscb;
3962 cmd->host_scribble = (char *)scb;
3963
3964 /*
3965 * Fill out basics of the HSCB.
3966 */
3967 hscb->control = 0;
3968 hscb->scsiid = BUILD_SCSIID(ahd, cmd);
3969 hscb->lun = cmd->device->lun;
3970 scb->hscb->task_management = 0;
3971 mask = SCB_GET_TARGET_MASK(ahd, scb);
3972
3973 if ((ahd->user_discenable & mask) != 0)
3974 hscb->control |= DISCENB;
3975
3976 if (AHD_DV_CMD(cmd) != 0)
3977 scb->flags |= SCB_SILENT;
3978
3979 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0)
3980 scb->flags |= SCB_PACKETIZED;
3981
3982 if ((tstate->auto_negotiate & mask) != 0) {
3983 scb->flags |= SCB_AUTO_NEGOTIATE;
3984 scb->hscb->control |= MK_MESSAGE;
3985 }
3986
3987 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
3988#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
3989 int msg_bytes;
3990 uint8_t tag_msgs[2];
3991
3992 msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs);
3993 if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) {
3994 hscb->control |= tag_msgs[0];
3995 if (tag_msgs[0] == MSG_ORDERED_TASK)
3996 dev->commands_since_idle_or_otag = 0;
3997 } else
3998#endif
3999 if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH
4000 && (dev->flags & AHD_DEV_Q_TAGGED) != 0) {
4001 hscb->control |= MSG_ORDERED_TASK;
4002 dev->commands_since_idle_or_otag = 0;
4003 } else {
4004 hscb->control |= MSG_SIMPLE_TASK;
4005 }
4006 }
4007
4008 hscb->cdb_len = cmd->cmd_len;
4009 memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len);
4010
4011 scb->sg_count = 0;
4012 ahd_set_residual(scb, 0);
4013 ahd_set_sense_residual(scb, 0);
4014 if (cmd->use_sg != 0) {
4015 void *sg;
4016 struct scatterlist *cur_seg;
4017 u_int nseg;
4018 int dir;
4019
4020 cur_seg = (struct scatterlist *)cmd->request_buffer;
4021 dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
4022 nseg = pci_map_sg(ahd->dev_softc, cur_seg,
4023 cmd->use_sg, dir);
4024 scb->platform_data->xfer_len = 0;
4025 for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) {
4026 dma_addr_t addr;
4027 bus_size_t len;
4028
4029 addr = sg_dma_address(cur_seg);
4030 len = sg_dma_len(cur_seg);
4031 scb->platform_data->xfer_len += len;
4032 sg = ahd_sg_setup(ahd, scb, sg, addr, len,
4033 /*last*/nseg == 1);
4034 }
4035 } else if (cmd->request_bufflen != 0) {
4036 void *sg;
4037 dma_addr_t addr;
4038 int dir;
4039
4040 sg = scb->sg_list;
4041 dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
4042 addr = pci_map_single(ahd->dev_softc,
4043 cmd->request_buffer,
4044 cmd->request_bufflen, dir);
4045 scb->platform_data->xfer_len = cmd->request_bufflen;
4046 scb->platform_data->buf_busaddr = addr;
4047 sg = ahd_sg_setup(ahd, scb, sg, addr,
4048 cmd->request_bufflen, /*last*/TRUE);
4049 }
4050
4051 LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
4052 dev->openings--;
4053 dev->active++;
4054 dev->commands_issued++;
4055
4056 /* Update the error counting bucket and dump if needed */
4057 if (dev->target->cmds_since_error) {
4058 dev->target->cmds_since_error++;
4059 if (dev->target->cmds_since_error >
4060 AHD_LINUX_ERR_THRESH)
4061 dev->target->cmds_since_error = 0;
4062 }
4063
4064 if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0)
4065 dev->commands_since_idle_or_otag++;
4066 scb->flags |= SCB_ACTIVE;
4067 ahd_queue_scb(ahd, scb);
4068 }
4069}
4070
4071/*
4072 * SCSI controller interrupt handler.
4073 */
4074irqreturn_t
4075ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
4076{
4077 struct ahd_softc *ahd;
4078 u_long flags;
4079 int ours;
4080
4081 ahd = (struct ahd_softc *) dev_id;
4082 ahd_lock(ahd, &flags);
4083 ours = ahd_intr(ahd);
4084 if (ahd_linux_next_device_to_run(ahd) != NULL)
4085 ahd_schedule_runq(ahd);
4086 ahd_linux_run_complete_queue(ahd);
4087 ahd_unlock(ahd, &flags);
4088 return IRQ_RETVAL(ours);
4089}
4090
4091void
4092ahd_platform_flushwork(struct ahd_softc *ahd)
4093{
4094
4095 while (ahd_linux_run_complete_queue(ahd) != NULL)
4096 ;
4097}
4098
4099static struct ahd_linux_target*
4100ahd_linux_alloc_target(struct ahd_softc *ahd, u_int channel, u_int target)
4101{
4102 struct ahd_linux_target *targ;
4103
4104 targ = malloc(sizeof(*targ), M_DEVBUF, M_NOWAIT);
4105 if (targ == NULL)
4106 return (NULL);
4107 memset(targ, 0, sizeof(*targ));
4108 targ->channel = channel;
4109 targ->target = target;
4110 targ->ahd = ahd;
4111 targ->flags = AHD_DV_REQUIRED;
4112 ahd->platform_data->targets[target] = targ;
4113 return (targ);
4114}
4115
4116static void
4117ahd_linux_free_target(struct ahd_softc *ahd, struct ahd_linux_target *targ)
4118{
4119 struct ahd_devinfo devinfo;
4120 struct ahd_initiator_tinfo *tinfo;
4121 struct ahd_tmode_tstate *tstate;
4122 u_int our_id;
4123 u_int target_offset;
4124 char channel;
4125
4126 /*
4127 * Force a negotiation to async/narrow on any
4128 * future command to this device unless a bus
4129 * reset occurs between now and that command.
4130 */
4131 channel = 'A' + targ->channel;
4132 our_id = ahd->our_id;
4133 target_offset = targ->target;
4134 tinfo = ahd_fetch_transinfo(ahd, channel, our_id,
4135 targ->target, &tstate);
4136 ahd_compile_devinfo(&devinfo, our_id, targ->target, CAM_LUN_WILDCARD,
4137 channel, ROLE_INITIATOR);
4138 ahd_set_syncrate(ahd, &devinfo, 0, 0, 0,
4139 AHD_TRANS_GOAL, /*paused*/FALSE);
4140 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
4141 AHD_TRANS_GOAL, /*paused*/FALSE);
4142 ahd_update_neg_request(ahd, &devinfo, tstate, tinfo, AHD_NEG_ALWAYS);
4143 ahd->platform_data->targets[target_offset] = NULL;
4144 if (targ->inq_data != NULL)
4145 free(targ->inq_data, M_DEVBUF);
4146 if (targ->dv_buffer != NULL)
4147 free(targ->dv_buffer, M_DEVBUF);
4148 if (targ->dv_buffer1 != NULL)
4149 free(targ->dv_buffer1, M_DEVBUF);
4150 free(targ, M_DEVBUF);
4151}
4152
4153static struct ahd_linux_device*
4154ahd_linux_alloc_device(struct ahd_softc *ahd,
4155 struct ahd_linux_target *targ, u_int lun)
4156{
4157 struct ahd_linux_device *dev;
4158
4159 dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT);
4160 if (dev == NULL)
4161 return (NULL);
4162 memset(dev, 0, sizeof(*dev));
4163 init_timer(&dev->timer);
4164 TAILQ_INIT(&dev->busyq);
4165 dev->flags = AHD_DEV_UNCONFIGURED;
4166 dev->lun = lun;
4167 dev->target = targ;
4168
4169 /*
4170 * We start out life using untagged
4171 * transactions of which we allow one.
4172 */
4173 dev->openings = 1;
4174
4175 /*
4176 * Set maxtags to 0. This will be changed if we
4177 * later determine that we are dealing with
4178 * a tagged queuing capable device.
4179 */
4180 dev->maxtags = 0;
4181
4182 targ->refcount++;
4183 targ->devices[lun] = dev;
4184 return (dev);
4185}
4186
4187static void
4188ahd_linux_free_device(struct ahd_softc *ahd, struct ahd_linux_device *dev)
4189{
4190 struct ahd_linux_target *targ;
4191
4192 del_timer(&dev->timer);
4193 targ = dev->target;
4194 targ->devices[dev->lun] = NULL;
4195 free(dev, M_DEVBUF);
4196 targ->refcount--;
4197 if (targ->refcount == 0
4198 && (targ->flags & AHD_DV_REQUIRED) == 0)
4199 ahd_linux_free_target(ahd, targ);
4200}
4201
4202void
4203ahd_send_async(struct ahd_softc *ahd, char channel,
4204 u_int target, u_int lun, ac_code code, void *arg)
4205{
4206 switch (code) {
4207 case AC_TRANSFER_NEG:
4208 {
4209 char buf[80];
4210 struct ahd_linux_target *targ;
4211 struct info_str info;
4212 struct ahd_initiator_tinfo *tinfo;
4213 struct ahd_tmode_tstate *tstate;
4214
4215 info.buffer = buf;
4216 info.length = sizeof(buf);
4217 info.offset = 0;
4218 info.pos = 0;
4219 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
4220 target, &tstate);
4221
4222 /*
4223 * Don't bother reporting results while
4224 * negotiations are still pending.
4225 */
4226 if (tinfo->curr.period != tinfo->goal.period
4227 || tinfo->curr.width != tinfo->goal.width
4228 || tinfo->curr.offset != tinfo->goal.offset
4229 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
4230 if (bootverbose == 0)
4231 break;
4232
4233 /*
4234 * Don't bother reporting results that
4235 * are identical to those last reported.
4236 */
4237 targ = ahd->platform_data->targets[target];
4238 if (targ == NULL)
4239 break;
4240 if (tinfo->curr.period == targ->last_tinfo.period
4241 && tinfo->curr.width == targ->last_tinfo.width
4242 && tinfo->curr.offset == targ->last_tinfo.offset
4243 && tinfo->curr.ppr_options == targ->last_tinfo.ppr_options)
4244 if (bootverbose == 0)
4245 break;
4246
4247 targ->last_tinfo.period = tinfo->curr.period;
4248 targ->last_tinfo.width = tinfo->curr.width;
4249 targ->last_tinfo.offset = tinfo->curr.offset;
4250 targ->last_tinfo.ppr_options = tinfo->curr.ppr_options;
4251
4252 printf("(%s:%c:", ahd_name(ahd), channel);
4253 if (target == CAM_TARGET_WILDCARD)
4254 printf("*): ");
4255 else
4256 printf("%d): ", target);
4257 ahd_format_transinfo(&info, &tinfo->curr);
4258 if (info.pos < info.length)
4259 *info.buffer = '\0';
4260 else
4261 buf[info.length - 1] = '\0';
4262 printf("%s", buf);
4263 break;
4264 }
4265 case AC_SENT_BDR:
4266 {
4267#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
4268 WARN_ON(lun != CAM_LUN_WILDCARD);
4269 scsi_report_device_reset(ahd->platform_data->host,
4270 channel - 'A', target);
4271#else
4272 Scsi_Device *scsi_dev;
4273
4274 /*
4275 * Find the SCSI device associated with this
4276 * request and indicate that a UA is expected.
4277 */
4278 for (scsi_dev = ahd->platform_data->host->host_queue;
4279 scsi_dev != NULL; scsi_dev = scsi_dev->next) {
4280 if (channel - 'A' == scsi_dev->channel
4281 && target == scsi_dev->id
4282 && (lun == CAM_LUN_WILDCARD
4283 || lun == scsi_dev->lun)) {
4284 scsi_dev->was_reset = 1;
4285 scsi_dev->expecting_cc_ua = 1;
4286 }
4287 }
4288#endif
4289 break;
4290 }
4291 case AC_BUS_RESET:
4292 if (ahd->platform_data->host != NULL) {
4293 scsi_report_bus_reset(ahd->platform_data->host,
4294 channel - 'A');
4295 }
4296 break;
4297 default:
4298 panic("ahd_send_async: Unexpected async event");
4299 }
4300}
4301
4302/*
4303 * Calls the higher level scsi done function and frees the scb.
4304 */
4305void
4306ahd_done(struct ahd_softc *ahd, struct scb *scb)
4307{
4308 Scsi_Cmnd *cmd;
4309 struct ahd_linux_device *dev;
4310
4311 if ((scb->flags & SCB_ACTIVE) == 0) {
4312 printf("SCB %d done'd twice\n", SCB_GET_TAG(scb));
4313 ahd_dump_card_state(ahd);
4314 panic("Stopping for safety");
4315 }
4316 LIST_REMOVE(scb, pending_links);
4317 cmd = scb->io_ctx;
4318 dev = scb->platform_data->dev;
4319 dev->active--;
4320 dev->openings++;
4321 if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
4322 cmd->result &= ~(CAM_DEV_QFRZN << 16);
4323 dev->qfrozen--;
4324 }
4325 ahd_linux_unmap_scb(ahd, scb);
4326
4327 /*
4328 * Guard against stale sense data.
4329 * The Linux mid-layer assumes that sense
4330 * was retrieved anytime the first byte of
4331 * the sense buffer looks "sane".
4332 */
4333 cmd->sense_buffer[0] = 0;
4334 if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) {
4335 uint32_t amount_xferred;
4336
4337 amount_xferred =
4338 ahd_get_transfer_length(scb) - ahd_get_residual(scb);
4339 if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
4340#ifdef AHD_DEBUG
4341 if ((ahd_debug & AHD_SHOW_MISC) != 0) {
4342 ahd_print_path(ahd, scb);
4343 printf("Set CAM_UNCOR_PARITY\n");
4344 }
4345#endif
4346 ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
4347#ifdef AHD_REPORT_UNDERFLOWS
4348 /*
4349 * This code is disabled by default as some
4350 * clients of the SCSI system do not properly
4351 * initialize the underflow parameter. This
4352 * results in spurious termination of commands
4353 * that complete as expected (e.g. underflow is
4354 * allowed as command can return variable amounts
4355 * of data.
4356 */
4357 } else if (amount_xferred < scb->io_ctx->underflow) {
4358 u_int i;
4359
4360 ahd_print_path(ahd, scb);
4361 printf("CDB:");
4362 for (i = 0; i < scb->io_ctx->cmd_len; i++)
4363 printf(" 0x%x", scb->io_ctx->cmnd[i]);
4364 printf("\n");
4365 ahd_print_path(ahd, scb);
4366 printf("Saw underflow (%ld of %ld bytes). "
4367 "Treated as error\n",
4368 ahd_get_residual(scb),
4369 ahd_get_transfer_length(scb));
4370 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
4371#endif
4372 } else {
4373 ahd_set_transaction_status(scb, CAM_REQ_CMP);
4374 }
4375 } else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
4376 ahd_linux_handle_scsi_status(ahd, dev, scb);
4377 } else if (ahd_get_transaction_status(scb) == CAM_SEL_TIMEOUT) {
4378 dev->flags |= AHD_DEV_UNCONFIGURED;
4379 if (AHD_DV_CMD(cmd) == FALSE)
4380 dev->target->flags &= ~AHD_DV_REQUIRED;
4381 }
4382 /*
4383 * Start DV for devices that require it assuming the first command
4384 * sent does not result in a selection timeout.
4385 */
4386 if (ahd_get_transaction_status(scb) != CAM_SEL_TIMEOUT
4387 && (dev->target->flags & AHD_DV_REQUIRED) != 0)
4388 ahd_linux_start_dv(ahd);
4389
4390 if (dev->openings == 1
4391 && ahd_get_transaction_status(scb) == CAM_REQ_CMP
4392 && ahd_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
4393 dev->tag_success_count++;
4394 /*
4395 * Some devices deal with temporary internal resource
4396 * shortages by returning queue full. When the queue
4397 * full occurrs, we throttle back. Slowly try to get
4398 * back to our previous queue depth.
4399 */
4400 if ((dev->openings + dev->active) < dev->maxtags
4401 && dev->tag_success_count > AHD_TAG_SUCCESS_INTERVAL) {
4402 dev->tag_success_count = 0;
4403 dev->openings++;
4404 }
4405
4406 if (dev->active == 0)
4407 dev->commands_since_idle_or_otag = 0;
4408
4409 if (TAILQ_EMPTY(&dev->busyq)) {
4410 if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0
4411 && dev->active == 0
4412 && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0)
4413 ahd_linux_free_device(ahd, dev);
4414 } else if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) {
4415 TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links);
4416 dev->flags |= AHD_DEV_ON_RUN_LIST;
4417 }
4418
4419 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
4420 printf("Recovery SCB completes\n");
4421 if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
4422 || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
4423 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
4424 if ((scb->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) {
4425 scb->platform_data->flags &= ~AHD_SCB_UP_EH_SEM;
4426 up(&ahd->platform_data->eh_sem);
4427 }
4428 }
4429
4430 ahd_free_scb(ahd, scb);
4431 ahd_linux_queue_cmd_complete(ahd, cmd);
4432
4433 if ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_EMPTY) != 0
4434 && LIST_FIRST(&ahd->pending_scbs) == NULL) {
4435 ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_EMPTY;
4436 up(&ahd->platform_data->dv_sem);
4437 }
4438}
4439
4440static void
4441ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
4442 struct ahd_linux_device *dev, struct scb *scb)
4443{
4444 struct ahd_devinfo devinfo;
4445
4446 ahd_compile_devinfo(&devinfo,
4447 ahd->our_id,
4448 dev->target->target, dev->lun,
4449 dev->target->channel == 0 ? 'A' : 'B',
4450 ROLE_INITIATOR);
4451
4452 /*
4453 * We don't currently trust the mid-layer to
4454 * properly deal with queue full or busy. So,
4455 * when one occurs, we tell the mid-layer to
4456 * unconditionally requeue the command to us
4457 * so that we can retry it ourselves. We also
4458 * implement our own throttling mechanism so
4459 * we don't clobber the device with too many
4460 * commands.
4461 */
4462 switch (ahd_get_scsi_status(scb)) {
4463 default:
4464 break;
4465 case SCSI_STATUS_CHECK_COND:
4466 case SCSI_STATUS_CMD_TERMINATED:
4467 {
4468 Scsi_Cmnd *cmd;
4469
4470 /*
4471 * Copy sense information to the OS's cmd
4472 * structure if it is available.
4473 */
4474 cmd = scb->io_ctx;
4475 if ((scb->flags & (SCB_SENSE|SCB_PKT_SENSE)) != 0) {
4476 struct scsi_status_iu_header *siu;
4477 u_int sense_size;
4478 u_int sense_offset;
4479
4480 if (scb->flags & SCB_SENSE) {
4481 sense_size = MIN(sizeof(struct scsi_sense_data)
4482 - ahd_get_sense_residual(scb),
4483 sizeof(cmd->sense_buffer));
4484 sense_offset = 0;
4485 } else {
4486 /*
4487 * Copy only the sense data into the provided
4488 * buffer.
4489 */
4490 siu = (struct scsi_status_iu_header *)
4491 scb->sense_data;
4492 sense_size = MIN(scsi_4btoul(siu->sense_length),
4493 sizeof(cmd->sense_buffer));
4494 sense_offset = SIU_SENSE_OFFSET(siu);
4495 }
4496
4497 memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
4498 memcpy(cmd->sense_buffer,
4499 ahd_get_sense_buf(ahd, scb)
4500 + sense_offset, sense_size);
4501 cmd->result |= (DRIVER_SENSE << 24);
4502
4503#ifdef AHD_DEBUG
4504 if (ahd_debug & AHD_SHOW_SENSE) {
4505 int i;
4506
4507 printf("Copied %d bytes of sense data at %d:",
4508 sense_size, sense_offset);
4509 for (i = 0; i < sense_size; i++) {
4510 if ((i & 0xF) == 0)
4511 printf("\n");
4512 printf("0x%x ", cmd->sense_buffer[i]);
4513 }
4514 printf("\n");
4515 }
4516#endif
4517 }
4518 break;
4519 }
4520 case SCSI_STATUS_QUEUE_FULL:
4521 {
4522 /*
4523 * By the time the core driver has returned this
4524 * command, all other commands that were queued
4525 * to us but not the device have been returned.
4526 * This ensures that dev->active is equal to
4527 * the number of commands actually queued to
4528 * the device.
4529 */
4530 dev->tag_success_count = 0;
4531 if (dev->active != 0) {
4532 /*
4533 * Drop our opening count to the number
4534 * of commands currently outstanding.
4535 */
4536 dev->openings = 0;
4537#ifdef AHD_DEBUG
4538 if ((ahd_debug & AHD_SHOW_QFULL) != 0) {
4539 ahd_print_path(ahd, scb);
4540 printf("Dropping tag count to %d\n",
4541 dev->active);
4542 }
4543#endif
4544 if (dev->active == dev->tags_on_last_queuefull) {
4545
4546 dev->last_queuefull_same_count++;
4547 /*
4548 * If we repeatedly see a queue full
4549 * at the same queue depth, this
4550 * device has a fixed number of tag
4551 * slots. Lock in this tag depth
4552 * so we stop seeing queue fulls from
4553 * this device.
4554 */
4555 if (dev->last_queuefull_same_count
4556 == AHD_LOCK_TAGS_COUNT) {
4557 dev->maxtags = dev->active;
4558 ahd_print_path(ahd, scb);
4559 printf("Locking max tag count at %d\n",
4560 dev->active);
4561 }
4562 } else {
4563 dev->tags_on_last_queuefull = dev->active;
4564 dev->last_queuefull_same_count = 0;
4565 }
4566 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
4567 ahd_set_scsi_status(scb, SCSI_STATUS_OK);
4568 ahd_platform_set_tags(ahd, &devinfo,
4569 (dev->flags & AHD_DEV_Q_BASIC)
4570 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
4571 break;
4572 }
4573 /*
4574 * Drop down to a single opening, and treat this
4575 * as if the target returned BUSY SCSI status.
4576 */
4577 dev->openings = 1;
4578 ahd_platform_set_tags(ahd, &devinfo,
4579 (dev->flags & AHD_DEV_Q_BASIC)
4580 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
4581 ahd_set_scsi_status(scb, SCSI_STATUS_BUSY);
4582 /* FALLTHROUGH */
4583 }
4584 case SCSI_STATUS_BUSY:
4585 /*
4586 * Set a short timer to defer sending commands for
4587 * a bit since Linux will not delay in this case.
4588 */
4589 if ((dev->flags & AHD_DEV_TIMER_ACTIVE) != 0) {
4590 printf("%s:%c:%d: Device Timer still active during "
4591 "busy processing\n", ahd_name(ahd),
4592 dev->target->channel, dev->target->target);
4593 break;
4594 }
4595 dev->flags |= AHD_DEV_TIMER_ACTIVE;
4596 dev->qfrozen++;
4597 init_timer(&dev->timer);
4598 dev->timer.data = (u_long)dev;
4599 dev->timer.expires = jiffies + (HZ/2);
4600 dev->timer.function = ahd_linux_dev_timed_unfreeze;
4601 add_timer(&dev->timer);
4602 break;
4603 }
4604}
4605
4606static void
4607ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, Scsi_Cmnd *cmd)
4608{
4609 /*
4610 * Typically, the complete queue has very few entries
4611 * queued to it before the queue is emptied by
4612 * ahd_linux_run_complete_queue, so sorting the entries
4613 * by generation number should be inexpensive.
4614 * We perform the sort so that commands that complete
4615 * with an error are retuned in the order origionally
4616 * queued to the controller so that any subsequent retries
4617 * are performed in order. The underlying ahd routines do
4618 * not guarantee the order that aborted commands will be
4619 * returned to us.
4620 */
4621 struct ahd_completeq *completeq;
4622 struct ahd_cmd *list_cmd;
4623 struct ahd_cmd *acmd;
4624
4625 /*
4626 * Map CAM error codes into Linux Error codes. We
4627 * avoid the conversion so that the DV code has the
4628 * full error information available when making
4629 * state change decisions.
4630 */
4631 if (AHD_DV_CMD(cmd) == FALSE) {
4632 uint32_t status;
4633 u_int new_status;
4634
4635 status = ahd_cmd_get_transaction_status(cmd);
4636 if (status != CAM_REQ_CMP) {
4637 struct ahd_linux_device *dev;
4638 struct ahd_devinfo devinfo;
4639 cam_status cam_status;
4640 uint32_t action;
4641 u_int scsi_status;
4642
4643 dev = ahd_linux_get_device(ahd, cmd->device->channel,
4644 cmd->device->id,
4645 cmd->device->lun,
4646 /*alloc*/FALSE);
4647
4648 if (dev == NULL)
4649 goto no_fallback;
4650
4651 ahd_compile_devinfo(&devinfo,
4652 ahd->our_id,
4653 dev->target->target, dev->lun,
4654 dev->target->channel == 0 ? 'A':'B',
4655 ROLE_INITIATOR);
4656
4657 scsi_status = ahd_cmd_get_scsi_status(cmd);
4658 cam_status = ahd_cmd_get_transaction_status(cmd);
4659 action = aic_error_action(cmd, dev->target->inq_data,
4660 cam_status, scsi_status);
4661 if ((action & SSQ_FALLBACK) != 0) {
4662
4663 /* Update stats */
4664 dev->target->errors_detected++;
4665 if (dev->target->cmds_since_error == 0)
4666 dev->target->cmds_since_error++;
4667 else {
4668 dev->target->cmds_since_error = 0;
4669 ahd_linux_fallback(ahd, &devinfo);
4670 }
4671 }
4672 }
4673no_fallback:
4674 switch (status) {
4675 case CAM_REQ_INPROG:
4676 case CAM_REQ_CMP:
4677 case CAM_SCSI_STATUS_ERROR:
4678 new_status = DID_OK;
4679 break;
4680 case CAM_REQ_ABORTED:
4681 new_status = DID_ABORT;
4682 break;
4683 case CAM_BUSY:
4684 new_status = DID_BUS_BUSY;
4685 break;
4686 case CAM_REQ_INVALID:
4687 case CAM_PATH_INVALID:
4688 new_status = DID_BAD_TARGET;
4689 break;
4690 case CAM_SEL_TIMEOUT:
4691 new_status = DID_NO_CONNECT;
4692 break;
4693 case CAM_SCSI_BUS_RESET:
4694 case CAM_BDR_SENT:
4695 new_status = DID_RESET;
4696 break;
4697 case CAM_UNCOR_PARITY:
4698 new_status = DID_PARITY;
4699 break;
4700 case CAM_CMD_TIMEOUT:
4701 new_status = DID_TIME_OUT;
4702 break;
4703 case CAM_UA_ABORT:
4704 case CAM_REQ_CMP_ERR:
4705 case CAM_AUTOSENSE_FAIL:
4706 case CAM_NO_HBA:
4707 case CAM_DATA_RUN_ERR:
4708 case CAM_UNEXP_BUSFREE:
4709 case CAM_SEQUENCE_FAIL:
4710 case CAM_CCB_LEN_ERR:
4711 case CAM_PROVIDE_FAIL:
4712 case CAM_REQ_TERMIO:
4713 case CAM_UNREC_HBA_ERROR:
4714 case CAM_REQ_TOO_BIG:
4715 new_status = DID_ERROR;
4716 break;
4717 case CAM_REQUEUE_REQ:
4718 /*
4719 * If we want the request requeued, make sure there
4720 * are sufficent retries. In the old scsi error code,
4721 * we used to be able to specify a result code that
4722 * bypassed the retry count. Now we must use this
4723 * hack. We also "fake" a check condition with
4724 * a sense code of ABORTED COMMAND. This seems to
4725 * evoke a retry even if this command is being sent
4726 * via the eh thread. Ick! Ick! Ick!
4727 */
4728 if (cmd->retries > 0)
4729 cmd->retries--;
4730 new_status = DID_OK;
4731 ahd_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
4732 cmd->result |= (DRIVER_SENSE << 24);
4733 memset(cmd->sense_buffer, 0,
4734 sizeof(cmd->sense_buffer));
4735 cmd->sense_buffer[0] = SSD_ERRCODE_VALID
4736 | SSD_CURRENT_ERROR;
4737 cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND;
4738 break;
4739 default:
4740 /* We should never get here */
4741 new_status = DID_ERROR;
4742 break;
4743 }
4744
4745 ahd_cmd_set_transaction_status(cmd, new_status);
4746 }
4747
4748 completeq = &ahd->platform_data->completeq;
4749 list_cmd = TAILQ_FIRST(completeq);
4750 acmd = (struct ahd_cmd *)cmd;
4751 while (list_cmd != NULL
4752 && acmd_scsi_cmd(list_cmd).serial_number
4753 < acmd_scsi_cmd(acmd).serial_number)
4754 list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe);
4755 if (list_cmd != NULL)
4756 TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe);
4757 else
4758 TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe);
4759}
4760
4761static void
4762ahd_linux_filter_inquiry(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
4763{
4764 struct scsi_inquiry_data *sid;
4765 struct ahd_initiator_tinfo *tinfo;
4766 struct ahd_transinfo *user;
4767 struct ahd_transinfo *goal;
4768 struct ahd_transinfo *curr;
4769 struct ahd_tmode_tstate *tstate;
4770 struct ahd_linux_device *dev;
4771 u_int width;
4772 u_int period;
4773 u_int offset;
4774 u_int ppr_options;
4775 u_int trans_version;
4776 u_int prot_version;
4777
4778 /*
4779 * Determine if this lun actually exists. If so,
4780 * hold on to its corresponding device structure.
4781 * If not, make sure we release the device and
4782 * don't bother processing the rest of this inquiry
4783 * command.
4784 */
4785 dev = ahd_linux_get_device(ahd, devinfo->channel - 'A',
4786 devinfo->target, devinfo->lun,
4787 /*alloc*/TRUE);
4788
4789 sid = (struct scsi_inquiry_data *)dev->target->inq_data;
4790 if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) {
4791
4792 dev->flags &= ~AHD_DEV_UNCONFIGURED;
4793 } else {
4794 dev->flags |= AHD_DEV_UNCONFIGURED;
4795 return;
4796 }
4797
4798 /*
4799 * Update our notion of this device's transfer
4800 * negotiation capabilities.
4801 */
4802 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel,
4803 devinfo->our_scsiid,
4804 devinfo->target, &tstate);
4805 user = &tinfo->user;
4806 goal = &tinfo->goal;
4807 curr = &tinfo->curr;
4808 width = user->width;
4809 period = user->period;
4810 offset = user->offset;
4811 ppr_options = user->ppr_options;
4812 trans_version = user->transport_version;
4813 prot_version = MIN(user->protocol_version, SID_ANSI_REV(sid));
4814
4815 /*
4816 * Only attempt SPI3/4 once we've verified that
4817 * the device claims to support SPI3/4 features.
4818 */
4819 if (prot_version < SCSI_REV_2)
4820 trans_version = SID_ANSI_REV(sid);
4821 else
4822 trans_version = SCSI_REV_2;
4823
4824 if ((sid->flags & SID_WBus16) == 0)
4825 width = MSG_EXT_WDTR_BUS_8_BIT;
4826 if ((sid->flags & SID_Sync) == 0) {
4827 period = 0;
4828 offset = 0;
4829 ppr_options = 0;
4830 }
4831 if ((sid->spi3data & SID_SPI_QAS) == 0)
4832 ppr_options &= ~MSG_EXT_PPR_QAS_REQ;
4833 if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0)
4834 ppr_options &= MSG_EXT_PPR_QAS_REQ;
4835 if ((sid->spi3data & SID_SPI_IUS) == 0)
4836 ppr_options &= (MSG_EXT_PPR_DT_REQ
4837 | MSG_EXT_PPR_QAS_REQ);
4838
4839 if (prot_version > SCSI_REV_2
4840 && ppr_options != 0)
4841 trans_version = user->transport_version;
4842
4843 ahd_validate_width(ahd, /*tinfo limit*/NULL, &width, ROLE_UNKNOWN);
4844 ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_MAX);
4845 ahd_validate_offset(ahd, /*tinfo limit*/NULL, period,
4846 &offset, width, ROLE_UNKNOWN);
4847 if (offset == 0 || period == 0) {
4848 period = 0;
4849 offset = 0;
4850 ppr_options = 0;
4851 }
4852 /* Apply our filtered user settings. */
4853 curr->transport_version = trans_version;
4854 curr->protocol_version = prot_version;
4855 ahd_set_width(ahd, devinfo, width, AHD_TRANS_GOAL, /*paused*/FALSE);
4856 ahd_set_syncrate(ahd, devinfo, period, offset, ppr_options,
4857 AHD_TRANS_GOAL, /*paused*/FALSE);
4858}
4859
4860void
4861ahd_freeze_simq(struct ahd_softc *ahd)
4862{
4863 ahd->platform_data->qfrozen++;
4864 if (ahd->platform_data->qfrozen == 1) {
4865 scsi_block_requests(ahd->platform_data->host);
4866 ahd_platform_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
4867 CAM_LUN_WILDCARD, SCB_LIST_NULL,
4868 ROLE_INITIATOR, CAM_REQUEUE_REQ);
4869 }
4870}
4871
4872void
4873ahd_release_simq(struct ahd_softc *ahd)
4874{
4875 u_long s;
4876 int unblock_reqs;
4877
4878 unblock_reqs = 0;
4879 ahd_lock(ahd, &s);
4880 if (ahd->platform_data->qfrozen > 0)
4881 ahd->platform_data->qfrozen--;
4882 if (ahd->platform_data->qfrozen == 0) {
4883 unblock_reqs = 1;
4884 }
4885 if (AHD_DV_SIMQ_FROZEN(ahd)
4886 && ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_RELEASE) != 0)) {
4887 ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_RELEASE;
4888 up(&ahd->platform_data->dv_sem);
4889 }
4890 ahd_schedule_runq(ahd);
4891 ahd_unlock(ahd, &s);
4892 /*
4893 * There is still a race here. The mid-layer
4894 * should keep its own freeze count and use
4895 * a bottom half handler to run the queues
4896 * so we can unblock with our own lock held.
4897 */
4898 if (unblock_reqs)
4899 scsi_unblock_requests(ahd->platform_data->host);
4900}
4901
4902static void
4903ahd_linux_sem_timeout(u_long arg)
4904{
4905 struct scb *scb;
4906 struct ahd_softc *ahd;
4907 u_long s;
4908
4909 scb = (struct scb *)arg;
4910 ahd = scb->ahd_softc;
4911 ahd_lock(ahd, &s);
4912 if ((scb->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) {
4913 scb->platform_data->flags &= ~AHD_SCB_UP_EH_SEM;
4914 up(&ahd->platform_data->eh_sem);
4915 }
4916 ahd_unlock(ahd, &s);
4917}
4918
4919static void
4920ahd_linux_dev_timed_unfreeze(u_long arg)
4921{
4922 struct ahd_linux_device *dev;
4923 struct ahd_softc *ahd;
4924 u_long s;
4925
4926 dev = (struct ahd_linux_device *)arg;
4927 ahd = dev->target->ahd;
4928 ahd_lock(ahd, &s);
4929 dev->flags &= ~AHD_DEV_TIMER_ACTIVE;
4930 if (dev->qfrozen > 0)
4931 dev->qfrozen--;
4932 if (dev->qfrozen == 0
4933 && (dev->flags & AHD_DEV_ON_RUN_LIST) == 0)
4934 ahd_linux_run_device_queue(ahd, dev);
4935 if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0
4936 && dev->active == 0)
4937 ahd_linux_free_device(ahd, dev);
4938 ahd_unlock(ahd, &s);
4939}
4940
4941void
4942ahd_platform_dump_card_state(struct ahd_softc *ahd)
4943{
4944 struct ahd_linux_device *dev;
4945 int target;
4946 int maxtarget;
4947 int lun;
4948 int i;
4949
4950 maxtarget = (ahd->features & AHD_WIDE) ? 15 : 7;
4951 for (target = 0; target <=maxtarget; target++) {
4952
4953 for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
4954 struct ahd_cmd *acmd;
4955
4956 dev = ahd_linux_get_device(ahd, 0, target,
4957 lun, /*alloc*/FALSE);
4958 if (dev == NULL)
4959 continue;
4960
4961 printf("DevQ(%d:%d:%d): ", 0, target, lun);
4962 i = 0;
4963 TAILQ_FOREACH(acmd, &dev->busyq, acmd_links.tqe) {
4964 if (i++ > AHD_SCB_MAX)
4965 break;
4966 }
4967 printf("%d waiting\n", i);
4968 }
4969 }
4970}
4971
4972static int __init
4973ahd_linux_init(void)
4974{
4975#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
4976 return ahd_linux_detect(&aic79xx_driver_template);
4977#else
4978 scsi_register_module(MODULE_SCSI_HA, &aic79xx_driver_template);
4979 if (aic79xx_driver_template.present == 0) {
4980 scsi_unregister_module(MODULE_SCSI_HA,
4981 &aic79xx_driver_template);
4982 return (-ENODEV);
4983 }
4984
4985 return (0);
4986#endif
4987}
4988
4989static void __exit
4990ahd_linux_exit(void)
4991{
4992 struct ahd_softc *ahd;
4993
4994 /*
4995 * Shutdown DV threads before going into the SCSI mid-layer.
4996 * This avoids situations where the mid-layer locks the entire
4997 * kernel so that waiting for our DV threads to exit leads
4998 * to deadlock.
4999 */
5000 TAILQ_FOREACH(ahd, &ahd_tailq, links) {
5001
5002 ahd_linux_kill_dv_thread(ahd);
5003 }
5004
5005#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5006 /*
5007 * In 2.4 we have to unregister from the PCI core _after_
5008 * unregistering from the scsi midlayer to avoid dangling
5009 * references.
5010 */
5011 scsi_unregister_module(MODULE_SCSI_HA, &aic79xx_driver_template);
5012#endif
5013 ahd_linux_pci_exit();
5014}
5015
5016module_init(ahd_linux_init);
5017module_exit(ahd_linux_exit);
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
new file mode 100644
index 000000000000..605f92b6c5ca
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -0,0 +1,1147 @@
1/*
2 * Adaptec AIC79xx device driver for Linux.
3 *
4 * Copyright (c) 2000-2001 Adaptec Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon
16 * including a substantially similar Disclaimer requirement for further
17 * binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * Alternatively, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2 as published by the Free
24 * Software Foundation.
25 *
26 * NO WARRANTY
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGES.
38 *
39 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#137 $
40 *
41 */
42#ifndef _AIC79XX_LINUX_H_
43#define _AIC79XX_LINUX_H_
44
45#include <linux/types.h>
46#include <linux/blkdev.h>
47#include <linux/delay.h>
48#include <linux/ioport.h>
49#include <linux/pci.h>
50#include <linux/smp_lock.h>
51#include <linux/version.h>
52#include <linux/module.h>
53#include <asm/byteorder.h>
54#include <asm/io.h>
55
56#include <linux/interrupt.h> /* For tasklet support. */
57#include <linux/config.h>
58#include <linux/slab.h>
59
60/* Core SCSI definitions */
61#define AIC_LIB_PREFIX ahd
62#include "scsi.h"
63#include <scsi/scsi_host.h>
64
65/* Name space conflict with BSD queue macros */
66#ifdef LIST_HEAD
67#undef LIST_HEAD
68#endif
69
70#include "cam.h"
71#include "queue.h"
72#include "scsi_message.h"
73#include "scsi_iu.h"
74#include "aiclib.h"
75
76/*********************************** Debugging ********************************/
77#ifdef CONFIG_AIC79XX_DEBUG_ENABLE
78#ifdef CONFIG_AIC79XX_DEBUG_MASK
79#define AHD_DEBUG 1
80#define AHD_DEBUG_OPTS CONFIG_AIC79XX_DEBUG_MASK
81#else
82/*
83 * Compile in debugging code, but do not enable any printfs.
84 */
85#define AHD_DEBUG 1
86#define AHD_DEBUG_OPTS 0
87#endif
88/* No debugging code. */
89#endif
90
91/********************************** Misc Macros *******************************/
92#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
93#define powerof2(x) ((((x)-1)&(x))==0)
94
95/************************* Forward Declarations *******************************/
96struct ahd_softc;
97typedef struct pci_dev *ahd_dev_softc_t;
98typedef Scsi_Cmnd *ahd_io_ctx_t;
99
100/******************************* Byte Order ***********************************/
101#define ahd_htobe16(x) cpu_to_be16(x)
102#define ahd_htobe32(x) cpu_to_be32(x)
103#define ahd_htobe64(x) cpu_to_be64(x)
104#define ahd_htole16(x) cpu_to_le16(x)
105#define ahd_htole32(x) cpu_to_le32(x)
106#define ahd_htole64(x) cpu_to_le64(x)
107
108#define ahd_be16toh(x) be16_to_cpu(x)
109#define ahd_be32toh(x) be32_to_cpu(x)
110#define ahd_be64toh(x) be64_to_cpu(x)
111#define ahd_le16toh(x) le16_to_cpu(x)
112#define ahd_le32toh(x) le32_to_cpu(x)
113#define ahd_le64toh(x) le64_to_cpu(x)
114
115#ifndef LITTLE_ENDIAN
116#define LITTLE_ENDIAN 1234
117#endif
118
119#ifndef BIG_ENDIAN
120#define BIG_ENDIAN 4321
121#endif
122
123#ifndef BYTE_ORDER
124#if defined(__BIG_ENDIAN)
125#define BYTE_ORDER BIG_ENDIAN
126#endif
127#if defined(__LITTLE_ENDIAN)
128#define BYTE_ORDER LITTLE_ENDIAN
129#endif
130#endif /* BYTE_ORDER */
131
132/************************* Configuration Data *********************************/
133extern uint32_t aic79xx_allow_memio;
134extern int aic79xx_detect_complete;
135extern Scsi_Host_Template aic79xx_driver_template;
136
137/***************************** Bus Space/DMA **********************************/
138
139typedef uint32_t bus_size_t;
140
141typedef enum {
142 BUS_SPACE_MEMIO,
143 BUS_SPACE_PIO
144} bus_space_tag_t;
145
146typedef union {
147 u_long ioport;
148 volatile uint8_t __iomem *maddr;
149} bus_space_handle_t;
150
151typedef struct bus_dma_segment
152{
153 dma_addr_t ds_addr;
154 bus_size_t ds_len;
155} bus_dma_segment_t;
156
157struct ahd_linux_dma_tag
158{
159 bus_size_t alignment;
160 bus_size_t boundary;
161 bus_size_t maxsize;
162};
163typedef struct ahd_linux_dma_tag* bus_dma_tag_t;
164
165struct ahd_linux_dmamap
166{
167 dma_addr_t bus_addr;
168};
169typedef struct ahd_linux_dmamap* bus_dmamap_t;
170
171typedef int bus_dma_filter_t(void*, dma_addr_t);
172typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
173
174#define BUS_DMA_WAITOK 0x0
175#define BUS_DMA_NOWAIT 0x1
176#define BUS_DMA_ALLOCNOW 0x2
177#define BUS_DMA_LOAD_SEGS 0x4 /*
178 * Argument is an S/G list not
179 * a single buffer.
180 */
181
182#define BUS_SPACE_MAXADDR 0xFFFFFFFF
183#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
184#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
185
186int ahd_dma_tag_create(struct ahd_softc *, bus_dma_tag_t /*parent*/,
187 bus_size_t /*alignment*/, bus_size_t /*boundary*/,
188 dma_addr_t /*lowaddr*/, dma_addr_t /*highaddr*/,
189 bus_dma_filter_t*/*filter*/, void */*filterarg*/,
190 bus_size_t /*maxsize*/, int /*nsegments*/,
191 bus_size_t /*maxsegsz*/, int /*flags*/,
192 bus_dma_tag_t */*dma_tagp*/);
193
194void ahd_dma_tag_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/);
195
196int ahd_dmamem_alloc(struct ahd_softc *, bus_dma_tag_t /*dmat*/,
197 void** /*vaddr*/, int /*flags*/,
198 bus_dmamap_t* /*mapp*/);
199
200void ahd_dmamem_free(struct ahd_softc *, bus_dma_tag_t /*dmat*/,
201 void* /*vaddr*/, bus_dmamap_t /*map*/);
202
203void ahd_dmamap_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/,
204 bus_dmamap_t /*map*/);
205
206int ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t /*dmat*/,
207 bus_dmamap_t /*map*/, void * /*buf*/,
208 bus_size_t /*buflen*/, bus_dmamap_callback_t *,
209 void */*callback_arg*/, int /*flags*/);
210
211int ahd_dmamap_unload(struct ahd_softc *, bus_dma_tag_t, bus_dmamap_t);
212
213/*
214 * Operations performed by ahd_dmamap_sync().
215 */
216#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
217#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
218#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
219#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
220
221/*
222 * XXX
223 * ahd_dmamap_sync is only used on buffers allocated with
224 * the pci_alloc_consistent() API. Although I'm not sure how
225 * this works on architectures with a write buffer, Linux does
226 * not have an API to sync "coherent" memory. Perhaps we need
227 * to do an mb()?
228 */
229#define ahd_dmamap_sync(ahd, dma_tag, dmamap, offset, len, op)
230
231/************************** Timer DataStructures ******************************/
232typedef struct timer_list ahd_timer_t;
233
234/********************************** Includes **********************************/
235#ifdef CONFIG_AIC79XX_REG_PRETTY_PRINT
236#define AIC_DEBUG_REGISTERS 1
237#else
238#define AIC_DEBUG_REGISTERS 0
239#endif
240#include "aic79xx.h"
241
242/***************************** Timer Facilities *******************************/
243#define ahd_timer_init init_timer
244#define ahd_timer_stop del_timer_sync
245typedef void ahd_linux_callback_t (u_long);
246static __inline void ahd_timer_reset(ahd_timer_t *timer, u_int usec,
247 ahd_callback_t *func, void *arg);
248static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec);
249
250static __inline void
251ahd_timer_reset(ahd_timer_t *timer, u_int usec, ahd_callback_t *func, void *arg)
252{
253 struct ahd_softc *ahd;
254
255 ahd = (struct ahd_softc *)arg;
256 del_timer(timer);
257 timer->data = (u_long)arg;
258 timer->expires = jiffies + (usec * HZ)/1000000;
259 timer->function = (ahd_linux_callback_t*)func;
260 add_timer(timer);
261}
262
263static __inline void
264ahd_scb_timer_reset(struct scb *scb, u_int usec)
265{
266 mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
267}
268
269/***************************** SMP support ************************************/
270#include <linux/spinlock.h>
271
272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
273#define AHD_SCSI_HAS_HOST_LOCK 1
274#else
275#define AHD_SCSI_HAS_HOST_LOCK 0
276#endif
277
278#define AIC79XX_DRIVER_VERSION "1.3.11"
279
280/**************************** Front End Queues ********************************/
281/*
282 * Data structure used to cast the Linux struct scsi_cmnd to something
283 * that allows us to use the queue macros. The linux structure has
284 * plenty of space to hold the links fields as required by the queue
285 * macros, but the queue macors require them to have the correct type.
286 */
287struct ahd_cmd_internal {
288 /* Area owned by the Linux scsi layer. */
289 uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)];
290 union {
291 STAILQ_ENTRY(ahd_cmd) ste;
292 LIST_ENTRY(ahd_cmd) le;
293 TAILQ_ENTRY(ahd_cmd) tqe;
294 } links;
295 uint32_t end;
296};
297
298struct ahd_cmd {
299 union {
300 struct ahd_cmd_internal icmd;
301 struct scsi_cmnd scsi_cmd;
302 } un;
303};
304
305#define acmd_icmd(cmd) ((cmd)->un.icmd)
306#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)
307#define acmd_links un.icmd.links
308
309/*************************** Device Data Structures ***************************/
310/*
311 * A per probed device structure used to deal with some error recovery
312 * scenarios that the Linux mid-layer code just doesn't know how to
313 * handle. The structure allocated for a device only becomes persistent
314 * after a successfully completed inquiry command to the target when
315 * that inquiry data indicates a lun is present.
316 */
317TAILQ_HEAD(ahd_busyq, ahd_cmd);
318typedef enum {
319 AHD_DEV_UNCONFIGURED = 0x01,
320 AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
321 AHD_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */
322 AHD_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */
323 AHD_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */
324 AHD_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */
325 AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */
326 AHD_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */
327} ahd_linux_dev_flags;
328
329struct ahd_linux_target;
330struct ahd_linux_device {
331 TAILQ_ENTRY(ahd_linux_device) links;
332 struct ahd_busyq busyq;
333
334 /*
335 * The number of transactions currently
336 * queued to the device.
337 */
338 int active;
339
340 /*
341 * The currently allowed number of
342 * transactions that can be queued to
343 * the device. Must be signed for
344 * conversion from tagged to untagged
345 * mode where the device may have more
346 * than one outstanding active transaction.
347 */
348 int openings;
349
350 /*
351 * A positive count indicates that this
352 * device's queue is halted.
353 */
354 u_int qfrozen;
355
356 /*
357 * Cumulative command counter.
358 */
359 u_long commands_issued;
360
361 /*
362 * The number of tagged transactions when
363 * running at our current opening level
364 * that have been successfully received by
365 * this device since the last QUEUE FULL.
366 */
367 u_int tag_success_count;
368#define AHD_TAG_SUCCESS_INTERVAL 50
369
370 ahd_linux_dev_flags flags;
371
372 /*
373 * Per device timer.
374 */
375 struct timer_list timer;
376
377 /*
378 * The high limit for the tags variable.
379 */
380 u_int maxtags;
381
382 /*
383 * The computed number of tags outstanding
384 * at the time of the last QUEUE FULL event.
385 */
386 u_int tags_on_last_queuefull;
387
388 /*
389 * How many times we have seen a queue full
390 * with the same number of tags. This is used
391 * to stop our adaptive queue depth algorithm
392 * on devices with a fixed number of tags.
393 */
394 u_int last_queuefull_same_count;
395#define AHD_LOCK_TAGS_COUNT 50
396
397 /*
398 * How many transactions have been queued
399 * without the device going idle. We use
400 * this statistic to determine when to issue
401 * an ordered tag to prevent transaction
402 * starvation. This statistic is only updated
403 * if the AHD_DEV_PERIODIC_OTAG flag is set
404 * on this device.
405 */
406 u_int commands_since_idle_or_otag;
407#define AHD_OTAG_THRESH 500
408
409 int lun;
410 Scsi_Device *scsi_device;
411 struct ahd_linux_target *target;
412};
413
414typedef enum {
415 AHD_DV_REQUIRED = 0x01,
416 AHD_INQ_VALID = 0x02,
417 AHD_BASIC_DV = 0x04,
418 AHD_ENHANCED_DV = 0x08
419} ahd_linux_targ_flags;
420
421/* DV States */
422typedef enum {
423 AHD_DV_STATE_EXIT = 0,
424 AHD_DV_STATE_INQ_SHORT_ASYNC,
425 AHD_DV_STATE_INQ_ASYNC,
426 AHD_DV_STATE_INQ_ASYNC_VERIFY,
427 AHD_DV_STATE_TUR,
428 AHD_DV_STATE_REBD,
429 AHD_DV_STATE_INQ_VERIFY,
430 AHD_DV_STATE_WEB,
431 AHD_DV_STATE_REB,
432 AHD_DV_STATE_SU,
433 AHD_DV_STATE_BUSY
434} ahd_dv_state;
435
436struct ahd_linux_target {
437 struct ahd_linux_device *devices[AHD_NUM_LUNS];
438 int channel;
439 int target;
440 int refcount;
441 struct ahd_transinfo last_tinfo;
442 struct ahd_softc *ahd;
443 ahd_linux_targ_flags flags;
444 struct scsi_inquiry_data *inq_data;
445 /*
446 * The next "fallback" period to use for narrow/wide transfers.
447 */
448 uint8_t dv_next_narrow_period;
449 uint8_t dv_next_wide_period;
450 uint8_t dv_max_width;
451 uint8_t dv_max_ppr_options;
452 uint8_t dv_last_ppr_options;
453 u_int dv_echo_size;
454 ahd_dv_state dv_state;
455 u_int dv_state_retry;
456 uint8_t *dv_buffer;
457 uint8_t *dv_buffer1;
458
459 /*
460 * Cumulative counter of errors.
461 */
462 u_long errors_detected;
463 u_long cmds_since_error;
464};
465
466/********************* Definitions Required by the Core ***********************/
467/*
468 * Number of SG segments we require. So long as the S/G segments for
469 * a particular transaction are allocated in a physically contiguous
470 * manner and are allocated below 4GB, the number of S/G segments is
471 * unrestricted.
472 */
473#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
474/*
475 * We dynamically adjust the number of segments in pre-2.5 kernels to
476 * avoid fragmentation issues in the SCSI mid-layer's private memory
477 * allocator. See aic79xx_osm.c ahd_linux_size_nseg() for details.
478 */
479extern u_int ahd_linux_nseg;
480#define AHD_NSEG ahd_linux_nseg
481#define AHD_LINUX_MIN_NSEG 64
482#else
483#define AHD_NSEG 128
484#endif
485
486/*
487 * Per-SCB OSM storage.
488 */
489typedef enum {
490 AHD_SCB_UP_EH_SEM = 0x1
491} ahd_linux_scb_flags;
492
493struct scb_platform_data {
494 struct ahd_linux_device *dev;
495 dma_addr_t buf_busaddr;
496 uint32_t xfer_len;
497 uint32_t sense_resid; /* Auto-Sense residual */
498 ahd_linux_scb_flags flags;
499};
500
501/*
502 * Define a structure used for each host adapter. All members are
503 * aligned on a boundary >= the size of the member to honor the
504 * alignment restrictions of the various platforms supported by
505 * this driver.
506 */
507typedef enum {
508 AHD_DV_WAIT_SIMQ_EMPTY = 0x01,
509 AHD_DV_WAIT_SIMQ_RELEASE = 0x02,
510 AHD_DV_ACTIVE = 0x04,
511 AHD_DV_SHUTDOWN = 0x08,
512 AHD_RUN_CMPLT_Q_TIMER = 0x10
513} ahd_linux_softc_flags;
514
515TAILQ_HEAD(ahd_completeq, ahd_cmd);
516
517struct ahd_platform_data {
518 /*
519 * Fields accessed from interrupt context.
520 */
521 struct ahd_linux_target *targets[AHD_NUM_TARGETS];
522 TAILQ_HEAD(, ahd_linux_device) device_runq;
523 struct ahd_completeq completeq;
524
525 spinlock_t spin_lock;
526 struct tasklet_struct runq_tasklet;
527 u_int qfrozen;
528 pid_t dv_pid;
529 struct timer_list completeq_timer;
530 struct timer_list reset_timer;
531 struct timer_list stats_timer;
532 struct semaphore eh_sem;
533 struct semaphore dv_sem;
534 struct semaphore dv_cmd_sem; /* XXX This needs to be in
535 * the target struct
536 */
537 struct scsi_device *dv_scsi_dev;
538 struct Scsi_Host *host; /* pointer to scsi host */
539#define AHD_LINUX_NOIRQ ((uint32_t)~0)
540 uint32_t irq; /* IRQ for this adapter */
541 uint32_t bios_address;
542 uint32_t mem_busaddr; /* Mem Base Addr */
543 uint64_t hw_dma_mask;
544 ahd_linux_softc_flags flags;
545};
546
547/************************** OS Utility Wrappers *******************************/
548#define printf printk
549#define M_NOWAIT GFP_ATOMIC
550#define M_WAITOK 0
551#define malloc(size, type, flags) kmalloc(size, flags)
552#define free(ptr, type) kfree(ptr)
553
554static __inline void ahd_delay(long);
555static __inline void
556ahd_delay(long usec)
557{
558 /*
559 * udelay on Linux can have problems for
560 * multi-millisecond waits. Wait at most
561 * 1024us per call.
562 */
563 while (usec > 0) {
564 udelay(usec % 1024);
565 usec -= 1024;
566 }
567}
568
569
570/***************************** Low Level I/O **********************************/
571static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port);
572static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port);
573static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
574static __inline void ahd_outw_atomic(struct ahd_softc * ahd,
575 long port, uint16_t val);
576static __inline void ahd_outsb(struct ahd_softc * ahd, long port,
577 uint8_t *, int count);
578static __inline void ahd_insb(struct ahd_softc * ahd, long port,
579 uint8_t *, int count);
580
581static __inline uint8_t
582ahd_inb(struct ahd_softc * ahd, long port)
583{
584 uint8_t x;
585
586 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
587 x = readb(ahd->bshs[0].maddr + port);
588 } else {
589 x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
590 }
591 mb();
592 return (x);
593}
594
595static __inline uint16_t
596ahd_inw_atomic(struct ahd_softc * ahd, long port)
597{
598 uint8_t x;
599
600 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
601 x = readw(ahd->bshs[0].maddr + port);
602 } else {
603 x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
604 }
605 mb();
606 return (x);
607}
608
609static __inline void
610ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
611{
612 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
613 writeb(val, ahd->bshs[0].maddr + port);
614 } else {
615 outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
616 }
617 mb();
618}
619
620static __inline void
621ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
622{
623 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
624 writew(val, ahd->bshs[0].maddr + port);
625 } else {
626 outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
627 }
628 mb();
629}
630
631static __inline void
632ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
633{
634 int i;
635
636 /*
637 * There is probably a more efficient way to do this on Linux
638 * but we don't use this for anything speed critical and this
639 * should work.
640 */
641 for (i = 0; i < count; i++)
642 ahd_outb(ahd, port, *array++);
643}
644
645static __inline void
646ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
647{
648 int i;
649
650 /*
651 * There is probably a more efficient way to do this on Linux
652 * but we don't use this for anything speed critical and this
653 * should work.
654 */
655 for (i = 0; i < count; i++)
656 *array++ = ahd_inb(ahd, port);
657}
658
659/**************************** Initialization **********************************/
660int ahd_linux_register_host(struct ahd_softc *,
661 Scsi_Host_Template *);
662
663uint64_t ahd_linux_get_memsize(void);
664
665/*************************** Pretty Printing **********************************/
666struct info_str {
667 char *buffer;
668 int length;
669 off_t offset;
670 int pos;
671};
672
673void ahd_format_transinfo(struct info_str *info,
674 struct ahd_transinfo *tinfo);
675
676/******************************** Locking *************************************/
677/* Lock protecting internal data structures */
678static __inline void ahd_lockinit(struct ahd_softc *);
679static __inline void ahd_lock(struct ahd_softc *, unsigned long *flags);
680static __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags);
681
682/* Lock acquisition and release of the above lock in midlayer entry points. */
683static __inline void ahd_midlayer_entrypoint_lock(struct ahd_softc *,
684 unsigned long *flags);
685static __inline void ahd_midlayer_entrypoint_unlock(struct ahd_softc *,
686 unsigned long *flags);
687
688/* Lock held during command compeletion to the upper layer */
689static __inline void ahd_done_lockinit(struct ahd_softc *);
690static __inline void ahd_done_lock(struct ahd_softc *, unsigned long *flags);
691static __inline void ahd_done_unlock(struct ahd_softc *, unsigned long *flags);
692
693/* Lock held during ahd_list manipulation and ahd softc frees */
694extern spinlock_t ahd_list_spinlock;
695static __inline void ahd_list_lockinit(void);
696static __inline void ahd_list_lock(unsigned long *flags);
697static __inline void ahd_list_unlock(unsigned long *flags);
698
699static __inline void
700ahd_lockinit(struct ahd_softc *ahd)
701{
702 spin_lock_init(&ahd->platform_data->spin_lock);
703}
704
705static __inline void
706ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
707{
708 spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
709}
710
711static __inline void
712ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
713{
714 spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
715}
716
717static __inline void
718ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags)
719{
720 /*
721 * In 2.5.X and some 2.4.X versions, the midlayer takes our
722 * lock just before calling us, so we avoid locking again.
723 * For other kernel versions, the io_request_lock is taken
724 * just before our entry point is called. In this case, we
725 * trade the io_request_lock for our per-softc lock.
726 */
727#if AHD_SCSI_HAS_HOST_LOCK == 0
728 spin_unlock(&io_request_lock);
729 spin_lock(&ahd->platform_data->spin_lock);
730#endif
731}
732
733static __inline void
734ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags)
735{
736#if AHD_SCSI_HAS_HOST_LOCK == 0
737 spin_unlock(&ahd->platform_data->spin_lock);
738 spin_lock(&io_request_lock);
739#endif
740}
741
742static __inline void
743ahd_done_lockinit(struct ahd_softc *ahd)
744{
745 /*
746 * In 2.5.X, our own lock is held during completions.
747 * In previous versions, the io_request_lock is used.
748 * In either case, we can't initialize this lock again.
749 */
750}
751
752static __inline void
753ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags)
754{
755#if AHD_SCSI_HAS_HOST_LOCK == 0
756 spin_lock(&io_request_lock);
757#endif
758}
759
760static __inline void
761ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags)
762{
763#if AHD_SCSI_HAS_HOST_LOCK == 0
764 spin_unlock(&io_request_lock);
765#endif
766}
767
768static __inline void
769ahd_list_lockinit(void)
770{
771 spin_lock_init(&ahd_list_spinlock);
772}
773
774static __inline void
775ahd_list_lock(unsigned long *flags)
776{
777 spin_lock_irqsave(&ahd_list_spinlock, *flags);
778}
779
780static __inline void
781ahd_list_unlock(unsigned long *flags)
782{
783 spin_unlock_irqrestore(&ahd_list_spinlock, *flags);
784}
785
786/******************************* PCI Definitions ******************************/
787/*
788 * PCIM_xxx: mask to locate subfield in register
789 * PCIR_xxx: config register offset
790 * PCIC_xxx: device class
791 * PCIS_xxx: device subclass
792 * PCIP_xxx: device programming interface
793 * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
794 * PCID_xxx: device ID
795 */
796#define PCIR_DEVVENDOR 0x00
797#define PCIR_VENDOR 0x00
798#define PCIR_DEVICE 0x02
799#define PCIR_COMMAND 0x04
800#define PCIM_CMD_PORTEN 0x0001
801#define PCIM_CMD_MEMEN 0x0002
802#define PCIM_CMD_BUSMASTEREN 0x0004
803#define PCIM_CMD_MWRICEN 0x0010
804#define PCIM_CMD_PERRESPEN 0x0040
805#define PCIM_CMD_SERRESPEN 0x0100
806#define PCIR_STATUS 0x06
807#define PCIR_REVID 0x08
808#define PCIR_PROGIF 0x09
809#define PCIR_SUBCLASS 0x0a
810#define PCIR_CLASS 0x0b
811#define PCIR_CACHELNSZ 0x0c
812#define PCIR_LATTIMER 0x0d
813#define PCIR_HEADERTYPE 0x0e
814#define PCIM_MFDEV 0x80
815#define PCIR_BIST 0x0f
816#define PCIR_CAP_PTR 0x34
817
818/* config registers for header type 0 devices */
819#define PCIR_MAPS 0x10
820#define PCIR_SUBVEND_0 0x2c
821#define PCIR_SUBDEV_0 0x2e
822
823/****************************** PCI-X definitions *****************************/
824#define PCIXR_COMMAND 0x96
825#define PCIXR_DEVADDR 0x98
826#define PCIXM_DEVADDR_FNUM 0x0003 /* Function Number */
827#define PCIXM_DEVADDR_DNUM 0x00F8 /* Device Number */
828#define PCIXM_DEVADDR_BNUM 0xFF00 /* Bus Number */
829#define PCIXR_STATUS 0x9A
830#define PCIXM_STATUS_64BIT 0x0001 /* Active 64bit connection to device. */
831#define PCIXM_STATUS_133CAP 0x0002 /* Device is 133MHz capable */
832#define PCIXM_STATUS_SCDISC 0x0004 /* Split Completion Discarded */
833#define PCIXM_STATUS_UNEXPSC 0x0008 /* Unexpected Split Completion */
834#define PCIXM_STATUS_CMPLEXDEV 0x0010 /* Device Complexity (set == bridge) */
835#define PCIXM_STATUS_MAXMRDBC 0x0060 /* Maximum Burst Read Count */
836#define PCIXM_STATUS_MAXSPLITS 0x0380 /* Maximum Split Transactions */
837#define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */
838#define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */
839
840extern struct pci_driver aic79xx_pci_driver;
841
842typedef enum
843{
844 AHD_POWER_STATE_D0,
845 AHD_POWER_STATE_D1,
846 AHD_POWER_STATE_D2,
847 AHD_POWER_STATE_D3
848} ahd_power_state;
849
850void ahd_power_state_change(struct ahd_softc *ahd,
851 ahd_power_state new_state);
852
853/******************************* PCI Routines *********************************/
854int ahd_linux_pci_init(void);
855void ahd_linux_pci_exit(void);
856int ahd_pci_map_registers(struct ahd_softc *ahd);
857int ahd_pci_map_int(struct ahd_softc *ahd);
858
859static __inline uint32_t ahd_pci_read_config(ahd_dev_softc_t pci,
860 int reg, int width);
861
862static __inline uint32_t
863ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width)
864{
865 switch (width) {
866 case 1:
867 {
868 uint8_t retval;
869
870 pci_read_config_byte(pci, reg, &retval);
871 return (retval);
872 }
873 case 2:
874 {
875 uint16_t retval;
876 pci_read_config_word(pci, reg, &retval);
877 return (retval);
878 }
879 case 4:
880 {
881 uint32_t retval;
882 pci_read_config_dword(pci, reg, &retval);
883 return (retval);
884 }
885 default:
886 panic("ahd_pci_read_config: Read size too big");
887 /* NOTREACHED */
888 return (0);
889 }
890}
891
892static __inline void ahd_pci_write_config(ahd_dev_softc_t pci,
893 int reg, uint32_t value,
894 int width);
895
896static __inline void
897ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width)
898{
899 switch (width) {
900 case 1:
901 pci_write_config_byte(pci, reg, value);
902 break;
903 case 2:
904 pci_write_config_word(pci, reg, value);
905 break;
906 case 4:
907 pci_write_config_dword(pci, reg, value);
908 break;
909 default:
910 panic("ahd_pci_write_config: Write size too big");
911 /* NOTREACHED */
912 }
913}
914
915static __inline int ahd_get_pci_function(ahd_dev_softc_t);
916static __inline int
917ahd_get_pci_function(ahd_dev_softc_t pci)
918{
919 return (PCI_FUNC(pci->devfn));
920}
921
922static __inline int ahd_get_pci_slot(ahd_dev_softc_t);
923static __inline int
924ahd_get_pci_slot(ahd_dev_softc_t pci)
925{
926 return (PCI_SLOT(pci->devfn));
927}
928
929static __inline int ahd_get_pci_bus(ahd_dev_softc_t);
930static __inline int
931ahd_get_pci_bus(ahd_dev_softc_t pci)
932{
933 return (pci->bus->number);
934}
935
936static __inline void ahd_flush_device_writes(struct ahd_softc *);
937static __inline void
938ahd_flush_device_writes(struct ahd_softc *ahd)
939{
940 /* XXX Is this sufficient for all architectures??? */
941 ahd_inb(ahd, INTSTAT);
942}
943
944/**************************** Proc FS Support *********************************/
945#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
946int ahd_linux_proc_info(char *, char **, off_t, int, int, int);
947#else
948int ahd_linux_proc_info(struct Scsi_Host *, char *, char **,
949 off_t, int, int);
950#endif
951
952/*************************** Domain Validation ********************************/
953#define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete)
954#define AHD_DV_SIMQ_FROZEN(ahd) \
955 ((((ahd)->platform_data->flags & AHD_DV_ACTIVE) != 0) \
956 && (ahd)->platform_data->qfrozen == 1)
957
958/*********************** Transaction Access Wrappers **************************/
959static __inline void ahd_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
960static __inline void ahd_set_transaction_status(struct scb *, uint32_t);
961static __inline void ahd_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t);
962static __inline void ahd_set_scsi_status(struct scb *, uint32_t);
963static __inline uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd);
964static __inline uint32_t ahd_get_transaction_status(struct scb *);
965static __inline uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd);
966static __inline uint32_t ahd_get_scsi_status(struct scb *);
967static __inline void ahd_set_transaction_tag(struct scb *, int, u_int);
968static __inline u_long ahd_get_transfer_length(struct scb *);
969static __inline int ahd_get_transfer_dir(struct scb *);
970static __inline void ahd_set_residual(struct scb *, u_long);
971static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
972static __inline u_long ahd_get_residual(struct scb *);
973static __inline u_long ahd_get_sense_residual(struct scb *);
974static __inline int ahd_perform_autosense(struct scb *);
975static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
976 struct scb *);
977static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
978 struct ahd_devinfo *);
979static __inline void ahd_platform_scb_free(struct ahd_softc *ahd,
980 struct scb *scb);
981static __inline void ahd_freeze_scb(struct scb *scb);
982
983static __inline
984void ahd_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status)
985{
986 cmd->result &= ~(CAM_STATUS_MASK << 16);
987 cmd->result |= status << 16;
988}
989
990static __inline
991void ahd_set_transaction_status(struct scb *scb, uint32_t status)
992{
993 ahd_cmd_set_transaction_status(scb->io_ctx,status);
994}
995
996static __inline
997void ahd_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status)
998{
999 cmd->result &= ~0xFFFF;
1000 cmd->result |= status;
1001}
1002
1003static __inline
1004void ahd_set_scsi_status(struct scb *scb, uint32_t status)
1005{
1006 ahd_cmd_set_scsi_status(scb->io_ctx, status);
1007}
1008
1009static __inline
1010uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd)
1011{
1012 return ((cmd->result >> 16) & CAM_STATUS_MASK);
1013}
1014
1015static __inline
1016uint32_t ahd_get_transaction_status(struct scb *scb)
1017{
1018 return (ahd_cmd_get_transaction_status(scb->io_ctx));
1019}
1020
1021static __inline
1022uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd)
1023{
1024 return (cmd->result & 0xFFFF);
1025}
1026
1027static __inline
1028uint32_t ahd_get_scsi_status(struct scb *scb)
1029{
1030 return (ahd_cmd_get_scsi_status(scb->io_ctx));
1031}
1032
1033static __inline
1034void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
1035{
1036 /*
1037 * Nothing to do for linux as the incoming transaction
1038 * has no concept of tag/non tagged, etc.
1039 */
1040}
1041
1042static __inline
1043u_long ahd_get_transfer_length(struct scb *scb)
1044{
1045 return (scb->platform_data->xfer_len);
1046}
1047
1048static __inline
1049int ahd_get_transfer_dir(struct scb *scb)
1050{
1051 return (scb->io_ctx->sc_data_direction);
1052}
1053
1054static __inline
1055void ahd_set_residual(struct scb *scb, u_long resid)
1056{
1057 scb->io_ctx->resid = resid;
1058}
1059
1060static __inline
1061void ahd_set_sense_residual(struct scb *scb, u_long resid)
1062{
1063 scb->platform_data->sense_resid = resid;
1064}
1065
1066static __inline
1067u_long ahd_get_residual(struct scb *scb)
1068{
1069 return (scb->io_ctx->resid);
1070}
1071
1072static __inline
1073u_long ahd_get_sense_residual(struct scb *scb)
1074{
1075 return (scb->platform_data->sense_resid);
1076}
1077
1078static __inline
1079int ahd_perform_autosense(struct scb *scb)
1080{
1081 /*
1082 * We always perform autosense in Linux.
1083 * On other platforms this is set on a
1084 * per-transaction basis.
1085 */
1086 return (1);
1087}
1088
1089static __inline uint32_t
1090ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb)
1091{
1092 return (sizeof(struct scsi_sense_data));
1093}
1094
1095static __inline void
1096ahd_notify_xfer_settings_change(struct ahd_softc *ahd,
1097 struct ahd_devinfo *devinfo)
1098{
1099 /* Nothing to do here for linux */
1100}
1101
1102static __inline void
1103ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb)
1104{
1105 ahd->flags &= ~AHD_RESOURCE_SHORTAGE;
1106}
1107
1108int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg);
1109void ahd_platform_free(struct ahd_softc *ahd);
1110void ahd_platform_init(struct ahd_softc *ahd);
1111void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
1112void ahd_freeze_simq(struct ahd_softc *ahd);
1113void ahd_release_simq(struct ahd_softc *ahd);
1114
1115static __inline void
1116ahd_freeze_scb(struct scb *scb)
1117{
1118 if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
1119 scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
1120 scb->platform_data->dev->qfrozen++;
1121 }
1122}
1123
1124void ahd_platform_set_tags(struct ahd_softc *ahd,
1125 struct ahd_devinfo *devinfo, ahd_queue_alg);
1126int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
1127 char channel, int lun, u_int tag,
1128 role_t role, uint32_t status);
1129irqreturn_t
1130 ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
1131void ahd_platform_flushwork(struct ahd_softc *ahd);
1132int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *);
1133void ahd_done(struct ahd_softc*, struct scb*);
1134void ahd_send_async(struct ahd_softc *, char channel,
1135 u_int target, u_int lun, ac_code, void *);
1136void ahd_print_path(struct ahd_softc *, struct scb *);
1137void ahd_platform_dump_card_state(struct ahd_softc *ahd);
1138
1139#ifdef CONFIG_PCI
1140#define AHD_PCI_CONFIG 1
1141#else
1142#define AHD_PCI_CONFIG 0
1143#endif
1144#define bootverbose aic79xx_verbose
1145extern uint32_t aic79xx_verbose;
1146
1147#endif /* _AIC79XX_LINUX_H_ */
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
new file mode 100644
index 000000000000..91daf0c7fb10
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -0,0 +1,368 @@
1/*
2 * Linux driver attachment glue for PCI based U320 controllers.
3 *
4 * Copyright (c) 2000-2001 Adaptec Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon
16 * including a substantially similar Disclaimer requirement for further
17 * binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * Alternatively, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2 as published by the Free
24 * Software Foundation.
25 *
26 * NO WARRANTY
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGES.
38 *
39 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#25 $
40 */
41
42#include "aic79xx_osm.h"
43#include "aic79xx_inline.h"
44#include "aic79xx_pci.h"
45
46static int ahd_linux_pci_dev_probe(struct pci_dev *pdev,
47 const struct pci_device_id *ent);
48static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd,
49 u_long *base, u_long *base2);
50static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
51 u_long *bus_addr,
52 uint8_t __iomem **maddr);
53static void ahd_linux_pci_dev_remove(struct pci_dev *pdev);
54
55/* Define the macro locally since it's different for different class of chips.
56 */
57#define ID(x) \
58 ID2C(x), \
59 ID2C(IDIROC(x))
60
61static struct pci_device_id ahd_linux_pci_id_table[] = {
62 /* aic7901 based controllers */
63 ID(ID_AHA_29320A),
64 ID(ID_AHA_29320ALP),
65 /* aic7902 based controllers */
66 ID(ID_AHA_29320),
67 ID(ID_AHA_29320B),
68 ID(ID_AHA_29320LP),
69 ID(ID_AHA_39320),
70 ID(ID_AHA_39320_B),
71 ID(ID_AHA_39320A),
72 ID(ID_AHA_39320D),
73 ID(ID_AHA_39320D_HP),
74 ID(ID_AHA_39320D_B),
75 ID(ID_AHA_39320D_B_HP),
76 /* Generic chip probes for devices we don't know exactly. */
77 ID16(ID_AIC7901 & ID_9005_GENERIC_MASK),
78 ID(ID_AIC7901A & ID_DEV_VENDOR_MASK),
79 ID16(ID_AIC7902 & ID_9005_GENERIC_MASK),
80 { 0 }
81};
82
83MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table);
84
85struct pci_driver aic79xx_pci_driver = {
86 .name = "aic79xx",
87 .probe = ahd_linux_pci_dev_probe,
88 .remove = ahd_linux_pci_dev_remove,
89 .id_table = ahd_linux_pci_id_table
90};
91
92static void
93ahd_linux_pci_dev_remove(struct pci_dev *pdev)
94{
95 struct ahd_softc *ahd;
96 u_long l;
97
98 /*
99 * We should be able to just perform
100 * the free directly, but check our
101 * list for extra sanity.
102 */
103 ahd_list_lock(&l);
104 ahd = ahd_find_softc((struct ahd_softc *)pci_get_drvdata(pdev));
105 if (ahd != NULL) {
106 u_long s;
107
108 TAILQ_REMOVE(&ahd_tailq, ahd, links);
109 ahd_list_unlock(&l);
110 ahd_lock(ahd, &s);
111 ahd_intr_enable(ahd, FALSE);
112 ahd_unlock(ahd, &s);
113 ahd_free(ahd);
114 } else
115 ahd_list_unlock(&l);
116}
117
118static int
119ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
120{
121 char buf[80];
122 struct ahd_softc *ahd;
123 ahd_dev_softc_t pci;
124 struct ahd_pci_identity *entry;
125 char *name;
126 int error;
127
128 /*
129 * Some BIOSen report the same device multiple times.
130 */
131 TAILQ_FOREACH(ahd, &ahd_tailq, links) {
132 struct pci_dev *probed_pdev;
133
134 probed_pdev = ahd->dev_softc;
135 if (probed_pdev->bus->number == pdev->bus->number
136 && probed_pdev->devfn == pdev->devfn)
137 break;
138 }
139 if (ahd != NULL) {
140 /* Skip duplicate. */
141 return (-ENODEV);
142 }
143
144 pci = pdev;
145 entry = ahd_find_pci_device(pci);
146 if (entry == NULL)
147 return (-ENODEV);
148
149 /*
150 * Allocate a softc for this card and
151 * set it up for attachment by our
152 * common detect routine.
153 */
154 sprintf(buf, "ahd_pci:%d:%d:%d",
155 ahd_get_pci_bus(pci),
156 ahd_get_pci_slot(pci),
157 ahd_get_pci_function(pci));
158 name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
159 if (name == NULL)
160 return (-ENOMEM);
161 strcpy(name, buf);
162 ahd = ahd_alloc(NULL, name);
163 if (ahd == NULL)
164 return (-ENOMEM);
165 if (pci_enable_device(pdev)) {
166 ahd_free(ahd);
167 return (-ENODEV);
168 }
169 pci_set_master(pdev);
170
171 if (sizeof(dma_addr_t) > 4) {
172 uint64_t memsize;
173 const uint64_t mask_39bit = 0x7FFFFFFFFFULL;
174
175 memsize = ahd_linux_get_memsize();
176
177 if (memsize >= 0x8000000000ULL
178 && pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
179 ahd->flags |= AHD_64BIT_ADDRESSING;
180 ahd->platform_data->hw_dma_mask = DMA_64BIT_MASK;
181 } else if (memsize > 0x80000000
182 && pci_set_dma_mask(pdev, mask_39bit) == 0) {
183 ahd->flags |= AHD_39BIT_ADDRESSING;
184 ahd->platform_data->hw_dma_mask = mask_39bit;
185 }
186 } else {
187 pci_set_dma_mask(pdev, DMA_32BIT_MASK);
188 ahd->platform_data->hw_dma_mask = DMA_32BIT_MASK;
189 }
190 ahd->dev_softc = pci;
191 error = ahd_pci_config(ahd, entry);
192 if (error != 0) {
193 ahd_free(ahd);
194 return (-error);
195 }
196 pci_set_drvdata(pdev, ahd);
197 if (aic79xx_detect_complete) {
198#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
199 ahd_linux_register_host(ahd, &aic79xx_driver_template);
200#else
201 printf("aic79xx: ignoring PCI device found after "
202 "initialization\n");
203 return (-ENODEV);
204#endif
205 }
206 return (0);
207}
208
209int
210ahd_linux_pci_init(void)
211{
212 return (pci_module_init(&aic79xx_pci_driver));
213}
214
215void
216ahd_linux_pci_exit(void)
217{
218 pci_unregister_driver(&aic79xx_pci_driver);
219}
220
221static int
222ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
223 u_long *base2)
224{
225 *base = pci_resource_start(ahd->dev_softc, 0);
226 /*
227 * This is really the 3rd bar and should be at index 2,
228 * but the Linux PCI code doesn't know how to "count" 64bit
229 * bars.
230 */
231 *base2 = pci_resource_start(ahd->dev_softc, 3);
232 if (*base == 0 || *base2 == 0)
233 return (ENOMEM);
234 if (request_region(*base, 256, "aic79xx") == 0)
235 return (ENOMEM);
236 if (request_region(*base2, 256, "aic79xx") == 0) {
237 release_region(*base2, 256);
238 return (ENOMEM);
239 }
240 return (0);
241}
242
243static int
244ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
245 u_long *bus_addr,
246 uint8_t __iomem **maddr)
247{
248 u_long start;
249 u_long base_page;
250 u_long base_offset;
251 int error;
252
253 if (aic79xx_allow_memio == 0)
254 return (ENOMEM);
255
256 if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) != 0)
257 return (ENOMEM);
258
259 error = 0;
260 start = pci_resource_start(ahd->dev_softc, 1);
261 base_page = start & PAGE_MASK;
262 base_offset = start - base_page;
263 if (start != 0) {
264 *bus_addr = start;
265 if (request_mem_region(start, 0x1000, "aic79xx") == 0)
266 error = ENOMEM;
267 if (error == 0) {
268 *maddr = ioremap_nocache(base_page, base_offset + 256);
269 if (*maddr == NULL) {
270 error = ENOMEM;
271 release_mem_region(start, 0x1000);
272 } else
273 *maddr += base_offset;
274 }
275 } else
276 error = ENOMEM;
277 return (error);
278}
279
280int
281ahd_pci_map_registers(struct ahd_softc *ahd)
282{
283 uint32_t command;
284 u_long base;
285 uint8_t __iomem *maddr;
286 int error;
287
288 /*
289 * If its allowed, we prefer memory mapped access.
290 */
291 command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4);
292 command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
293 base = 0;
294 maddr = NULL;
295 error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr);
296 if (error == 0) {
297 ahd->platform_data->mem_busaddr = base;
298 ahd->tags[0] = BUS_SPACE_MEMIO;
299 ahd->bshs[0].maddr = maddr;
300 ahd->tags[1] = BUS_SPACE_MEMIO;
301 ahd->bshs[1].maddr = maddr + 0x100;
302 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
303 command | PCIM_CMD_MEMEN, 4);
304
305 if (ahd_pci_test_register_access(ahd) != 0) {
306
307 printf("aic79xx: PCI Device %d:%d:%d "
308 "failed memory mapped test. Using PIO.\n",
309 ahd_get_pci_bus(ahd->dev_softc),
310 ahd_get_pci_slot(ahd->dev_softc),
311 ahd_get_pci_function(ahd->dev_softc));
312 iounmap(maddr);
313 release_mem_region(ahd->platform_data->mem_busaddr,
314 0x1000);
315 ahd->bshs[0].maddr = NULL;
316 maddr = NULL;
317 } else
318 command |= PCIM_CMD_MEMEN;
319 } else if (bootverbose) {
320 printf("aic79xx: PCI%d:%d:%d MEM region 0x%lx "
321 "unavailable. Cannot memory map device.\n",
322 ahd_get_pci_bus(ahd->dev_softc),
323 ahd_get_pci_slot(ahd->dev_softc),
324 ahd_get_pci_function(ahd->dev_softc),
325 base);
326 }
327
328 if (maddr == NULL) {
329 u_long base2;
330
331 error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2);
332 if (error == 0) {
333 ahd->tags[0] = BUS_SPACE_PIO;
334 ahd->tags[1] = BUS_SPACE_PIO;
335 ahd->bshs[0].ioport = base;
336 ahd->bshs[1].ioport = base2;
337 command |= PCIM_CMD_PORTEN;
338 } else {
339 printf("aic79xx: PCI%d:%d:%d IO regions 0x%lx and 0x%lx"
340 "unavailable. Cannot map device.\n",
341 ahd_get_pci_bus(ahd->dev_softc),
342 ahd_get_pci_slot(ahd->dev_softc),
343 ahd_get_pci_function(ahd->dev_softc),
344 base, base2);
345 }
346 }
347 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4);
348 return (error);
349}
350
351int
352ahd_pci_map_int(struct ahd_softc *ahd)
353{
354 int error;
355
356 error = request_irq(ahd->dev_softc->irq, ahd_linux_isr,
357 SA_SHIRQ, "aic79xx", ahd);
358 if (error == 0)
359 ahd->platform_data->irq = ahd->dev_softc->irq;
360
361 return (-error);
362}
363
364void
365ahd_power_state_change(struct ahd_softc *ahd, ahd_power_state new_state)
366{
367 pci_set_power_state(ahd->dev_softc, new_state);
368}
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
new file mode 100644
index 000000000000..4c3bb7bb8420
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -0,0 +1,987 @@
1/*
2 * Product specific probe and attach routines for:
3 * aic7901 and aic7902 SCSI controllers
4 *
5 * Copyright (c) 1994-2001 Justin T. Gibbs.
6 * Copyright (c) 2000-2002 Adaptec Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * substantially similar to the "NO WARRANTY" disclaimer below
17 * ("Disclaimer") and any redistribution must be conditioned upon
18 * including a substantially similar Disclaimer requirement for further
19 * binary redistribution.
20 * 3. Neither the names of the above-listed copyright holders nor the names
21 * of any contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * Alternatively, this software may be distributed under the terms of the
25 * GNU General Public License ("GPL") version 2 as published by the Free
26 * Software Foundation.
27 *
28 * NO WARRANTY
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGES.
40 *
41 * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#77 $
42 *
43 * $FreeBSD$
44 */
45
46#ifdef __linux__
47#include "aic79xx_osm.h"
48#include "aic79xx_inline.h"
49#else
50#include <dev/aic7xxx/aic79xx_osm.h>
51#include <dev/aic7xxx/aic79xx_inline.h>
52#endif
53
54#include "aic79xx_pci.h"
55
56static __inline uint64_t
57ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
58{
59 uint64_t id;
60
61 id = subvendor
62 | (subdevice << 16)
63 | ((uint64_t)vendor << 32)
64 | ((uint64_t)device << 48);
65
66 return (id);
67}
68
69#define ID_AIC7902_PCI_REV_A4 0x3
70#define ID_AIC7902_PCI_REV_B0 0x10
71#define SUBID_HP 0x0E11
72
73#define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
74
75#define DEVID_9005_TYPE(id) ((id) & 0xF)
76#define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
77#define DEVID_9005_TYPE_HBA_2EXT 0x1 /* 2 External Ports */
78#define DEVID_9005_TYPE_IROC 0x8 /* Raid(0,1,10) Card */
79#define DEVID_9005_TYPE_MB 0xF /* On Motherboard */
80
81#define DEVID_9005_MFUNC(id) ((id) & 0x10)
82
83#define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
84
85#define SUBID_9005_TYPE(id) ((id) & 0xF)
86#define SUBID_9005_TYPE_HBA 0x0 /* Standard Card */
87#define SUBID_9005_TYPE_MB 0xF /* On Motherboard */
88
89#define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
90
91#define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
92
93#define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
94#define SUBID_9005_SEEPTYPE_NONE 0x0
95#define SUBID_9005_SEEPTYPE_4K 0x1
96
97static ahd_device_setup_t ahd_aic7901_setup;
98static ahd_device_setup_t ahd_aic7901A_setup;
99static ahd_device_setup_t ahd_aic7902_setup;
100static ahd_device_setup_t ahd_aic790X_setup;
101
102struct ahd_pci_identity ahd_pci_ident_table [] =
103{
104 /* aic7901 based controllers */
105 {
106 ID_AHA_29320A,
107 ID_ALL_MASK,
108 "Adaptec 29320A Ultra320 SCSI adapter",
109 ahd_aic7901_setup
110 },
111 {
112 ID_AHA_29320ALP,
113 ID_ALL_MASK,
114 "Adaptec 29320ALP Ultra320 SCSI adapter",
115 ahd_aic7901_setup
116 },
117 /* aic7902 based controllers */
118 {
119 ID_AHA_29320,
120 ID_ALL_MASK,
121 "Adaptec 29320 Ultra320 SCSI adapter",
122 ahd_aic7902_setup
123 },
124 {
125 ID_AHA_29320B,
126 ID_ALL_MASK,
127 "Adaptec 29320B Ultra320 SCSI adapter",
128 ahd_aic7902_setup
129 },
130 {
131 ID_AHA_29320LP,
132 ID_ALL_MASK,
133 "Adaptec 29320LP Ultra320 SCSI adapter",
134 ahd_aic7901A_setup
135 },
136 {
137 ID_AHA_39320,
138 ID_ALL_MASK,
139 "Adaptec 39320 Ultra320 SCSI adapter",
140 ahd_aic7902_setup
141 },
142 {
143 ID_AHA_39320_B,
144 ID_ALL_MASK,
145 "Adaptec 39320 Ultra320 SCSI adapter",
146 ahd_aic7902_setup
147 },
148 {
149 ID_AHA_39320A,
150 ID_ALL_MASK,
151 "Adaptec 39320A Ultra320 SCSI adapter",
152 ahd_aic7902_setup
153 },
154 {
155 ID_AHA_39320D,
156 ID_ALL_MASK,
157 "Adaptec 39320D Ultra320 SCSI adapter",
158 ahd_aic7902_setup
159 },
160 {
161 ID_AHA_39320D_HP,
162 ID_ALL_MASK,
163 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
164 ahd_aic7902_setup
165 },
166 {
167 ID_AHA_39320D_B,
168 ID_ALL_MASK,
169 "Adaptec 39320D Ultra320 SCSI adapter",
170 ahd_aic7902_setup
171 },
172 {
173 ID_AHA_39320D_B_HP,
174 ID_ALL_MASK,
175 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
176 ahd_aic7902_setup
177 },
178 /* Generic chip probes for devices we don't know 'exactly' */
179 {
180 ID_AIC7901 & ID_9005_GENERIC_MASK,
181 ID_9005_GENERIC_MASK,
182 "Adaptec AIC7901 Ultra320 SCSI adapter",
183 ahd_aic7901_setup
184 },
185 {
186 ID_AIC7901A & ID_DEV_VENDOR_MASK,
187 ID_DEV_VENDOR_MASK,
188 "Adaptec AIC7901A Ultra320 SCSI adapter",
189 ahd_aic7901A_setup
190 },
191 {
192 ID_AIC7902 & ID_9005_GENERIC_MASK,
193 ID_9005_GENERIC_MASK,
194 "Adaptec AIC7902 Ultra320 SCSI adapter",
195 ahd_aic7902_setup
196 }
197};
198
199const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
200
201#define DEVCONFIG 0x40
202#define PCIXINITPAT 0x0000E000ul
203#define PCIXINIT_PCI33_66 0x0000E000ul
204#define PCIXINIT_PCIX50_66 0x0000C000ul
205#define PCIXINIT_PCIX66_100 0x0000A000ul
206#define PCIXINIT_PCIX100_133 0x00008000ul
207#define PCI_BUS_MODES_INDEX(devconfig) \
208 (((devconfig) & PCIXINITPAT) >> 13)
209static const char *pci_bus_modes[] =
210{
211 "PCI bus mode unknown",
212 "PCI bus mode unknown",
213 "PCI bus mode unknown",
214 "PCI bus mode unknown",
215 "PCI-X 101-133Mhz",
216 "PCI-X 67-100Mhz",
217 "PCI-X 50-66Mhz",
218 "PCI 33 or 66Mhz"
219};
220
221#define TESTMODE 0x00000800ul
222#define IRDY_RST 0x00000200ul
223#define FRAME_RST 0x00000100ul
224#define PCI64BIT 0x00000080ul
225#define MRDCEN 0x00000040ul
226#define ENDIANSEL 0x00000020ul
227#define MIXQWENDIANEN 0x00000008ul
228#define DACEN 0x00000004ul
229#define STPWLEVEL 0x00000002ul
230#define QWENDIANSEL 0x00000001ul
231
232#define DEVCONFIG1 0x44
233#define PREQDIS 0x01
234
235#define CSIZE_LATTIME 0x0c
236#define CACHESIZE 0x000000fful
237#define LATTIME 0x0000ff00ul
238
239static int ahd_check_extport(struct ahd_softc *ahd);
240static void ahd_configure_termination(struct ahd_softc *ahd,
241 u_int adapter_control);
242static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
243
244struct ahd_pci_identity *
245ahd_find_pci_device(ahd_dev_softc_t pci)
246{
247 uint64_t full_id;
248 uint16_t device;
249 uint16_t vendor;
250 uint16_t subdevice;
251 uint16_t subvendor;
252 struct ahd_pci_identity *entry;
253 u_int i;
254
255 vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
256 device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
257 subvendor = ahd_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
258 subdevice = ahd_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
259 full_id = ahd_compose_id(device,
260 vendor,
261 subdevice,
262 subvendor);
263
264 /*
265 * Controllers, mask out the IROC/HostRAID bit
266 */
267
268 full_id &= ID_ALL_IROC_MASK;
269
270 for (i = 0; i < ahd_num_pci_devs; i++) {
271 entry = &ahd_pci_ident_table[i];
272 if (entry->full_id == (full_id & entry->id_mask)) {
273 /* Honor exclusion entries. */
274 if (entry->name == NULL)
275 return (NULL);
276 return (entry);
277 }
278 }
279 return (NULL);
280}
281
282int
283ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
284{
285 struct scb_data *shared_scb_data;
286 u_long l;
287 u_int command;
288 uint32_t devconfig;
289 uint16_t subvendor;
290 int error;
291
292 shared_scb_data = NULL;
293 ahd->description = entry->name;
294 /*
295 * Record if this is an HP board.
296 */
297 subvendor = ahd_pci_read_config(ahd->dev_softc,
298 PCIR_SUBVEND_0, /*bytes*/2);
299 if (subvendor == SUBID_HP)
300 ahd->flags |= AHD_HP_BOARD;
301
302 error = entry->setup(ahd);
303 if (error != 0)
304 return (error);
305
306 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
307 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
308 ahd->chip |= AHD_PCI;
309 /* Disable PCIX workarounds when running in PCI mode. */
310 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
311 } else {
312 ahd->chip |= AHD_PCIX;
313 }
314 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
315
316 ahd_power_state_change(ahd, AHD_POWER_STATE_D0);
317
318 error = ahd_pci_map_registers(ahd);
319 if (error != 0)
320 return (error);
321
322 /*
323 * If we need to support high memory, enable dual
324 * address cycles. This bit must be set to enable
325 * high address bit generation even if we are on a
326 * 64bit bus (PCI64BIT set in devconfig).
327 */
328 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
329 uint32_t devconfig;
330
331 if (bootverbose)
332 printf("%s: Enabling 39Bit Addressing\n",
333 ahd_name(ahd));
334 devconfig = ahd_pci_read_config(ahd->dev_softc,
335 DEVCONFIG, /*bytes*/4);
336 devconfig |= DACEN;
337 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
338 devconfig, /*bytes*/4);
339 }
340
341 /* Ensure busmastering is enabled */
342 command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
343 command |= PCIM_CMD_BUSMASTEREN;
344 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
345
346 error = ahd_softc_init(ahd);
347 if (error != 0)
348 return (error);
349
350 ahd->bus_intr = ahd_pci_intr;
351
352 error = ahd_reset(ahd, /*reinit*/FALSE);
353 if (error != 0)
354 return (ENXIO);
355
356 ahd->pci_cachesize =
357 ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
358 /*bytes*/1) & CACHESIZE;
359 ahd->pci_cachesize *= 4;
360
361 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
362 /* See if we have a SEEPROM and perform auto-term */
363 error = ahd_check_extport(ahd);
364 if (error != 0)
365 return (error);
366
367 /* Core initialization */
368 error = ahd_init(ahd);
369 if (error != 0)
370 return (error);
371
372 /*
373 * Allow interrupts now that we are completely setup.
374 */
375 error = ahd_pci_map_int(ahd);
376 if (error != 0)
377 return (error);
378
379 ahd_list_lock(&l);
380 /*
381 * Link this softc in with all other ahd instances.
382 */
383 ahd_softc_insert(ahd);
384 ahd_list_unlock(&l);
385 return (0);
386}
387
388/*
389 * Perform some simple tests that should catch situations where
390 * our registers are invalidly mapped.
391 */
392int
393ahd_pci_test_register_access(struct ahd_softc *ahd)
394{
395 uint32_t cmd;
396 u_int targpcistat;
397 u_int pci_status1;
398 int error;
399 uint8_t hcntrl;
400
401 error = EIO;
402
403 /*
404 * Enable PCI error interrupt status, but suppress NMIs
405 * generated by SERR raised due to target aborts.
406 */
407 cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
408 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
409 cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
410
411 /*
412 * First a simple test to see if any
413 * registers can be read. Reading
414 * HCNTRL has no side effects and has
415 * at least one bit that is guaranteed to
416 * be zero so it is a good register to
417 * use for this test.
418 */
419 hcntrl = ahd_inb(ahd, HCNTRL);
420 if (hcntrl == 0xFF)
421 goto fail;
422
423 /*
424 * Next create a situation where write combining
425 * or read prefetching could be initiated by the
426 * CPU or host bridge. Our device does not support
427 * either, so look for data corruption and/or flaged
428 * PCI errors. First pause without causing another
429 * chip reset.
430 */
431 hcntrl &= ~CHIPRST;
432 ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
433 while (ahd_is_paused(ahd) == 0)
434 ;
435
436 /* Clear any PCI errors that occurred before our driver attached. */
437 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
438 targpcistat = ahd_inb(ahd, TARGPCISTAT);
439 ahd_outb(ahd, TARGPCISTAT, targpcistat);
440 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
441 PCIR_STATUS + 1, /*bytes*/1);
442 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
443 pci_status1, /*bytes*/1);
444 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
445 ahd_outb(ahd, CLRINT, CLRPCIINT);
446
447 ahd_outb(ahd, SEQCTL0, PERRORDIS);
448 ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
449 if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
450 goto fail;
451
452 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
453 u_int targpcistat;
454
455 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
456 targpcistat = ahd_inb(ahd, TARGPCISTAT);
457 if ((targpcistat & STA) != 0)
458 goto fail;
459 }
460
461 error = 0;
462
463fail:
464 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
465
466 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
467 targpcistat = ahd_inb(ahd, TARGPCISTAT);
468
469 /* Silently clear any latched errors. */
470 ahd_outb(ahd, TARGPCISTAT, targpcistat);
471 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
472 PCIR_STATUS + 1, /*bytes*/1);
473 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
474 pci_status1, /*bytes*/1);
475 ahd_outb(ahd, CLRINT, CLRPCIINT);
476 }
477 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
478 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
479 return (error);
480}
481
482/*
483 * Check the external port logic for a serial eeprom
484 * and termination/cable detection contrls.
485 */
486static int
487ahd_check_extport(struct ahd_softc *ahd)
488{
489 struct vpd_config vpd;
490 struct seeprom_config *sc;
491 u_int adapter_control;
492 int have_seeprom;
493 int error;
494
495 sc = ahd->seep_config;
496 have_seeprom = ahd_acquire_seeprom(ahd);
497 if (have_seeprom) {
498 u_int start_addr;
499
500 /*
501 * Fetch VPD for this function and parse it.
502 */
503 if (bootverbose)
504 printf("%s: Reading VPD from SEEPROM...",
505 ahd_name(ahd));
506
507 /* Address is always in units of 16bit words */
508 start_addr = ((2 * sizeof(*sc))
509 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
510
511 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
512 start_addr, sizeof(vpd)/2,
513 /*bytestream*/TRUE);
514 if (error == 0)
515 error = ahd_parse_vpddata(ahd, &vpd);
516 if (bootverbose)
517 printf("%s: VPD parsing %s\n",
518 ahd_name(ahd),
519 error == 0 ? "successful" : "failed");
520
521 if (bootverbose)
522 printf("%s: Reading SEEPROM...", ahd_name(ahd));
523
524 /* Address is always in units of 16bit words */
525 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
526
527 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
528 start_addr, sizeof(*sc)/2,
529 /*bytestream*/FALSE);
530
531 if (error != 0) {
532 printf("Unable to read SEEPROM\n");
533 have_seeprom = 0;
534 } else {
535 have_seeprom = ahd_verify_cksum(sc);
536
537 if (bootverbose) {
538 if (have_seeprom == 0)
539 printf ("checksum error\n");
540 else
541 printf ("done.\n");
542 }
543 }
544 ahd_release_seeprom(ahd);
545 }
546
547 if (!have_seeprom) {
548 u_int nvram_scb;
549
550 /*
551 * Pull scratch ram settings and treat them as
552 * if they are the contents of an seeprom if
553 * the 'ADPT', 'BIOS', or 'ASPI' signature is found
554 * in SCB 0xFF. We manually compose the data as 16bit
555 * values to avoid endian issues.
556 */
557 ahd_set_scbptr(ahd, 0xFF);
558 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
559 if (nvram_scb != 0xFF
560 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
561 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
562 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
563 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
564 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
565 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
566 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
567 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
568 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
569 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
570 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
571 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
572 uint16_t *sc_data;
573 int i;
574
575 ahd_set_scbptr(ahd, nvram_scb);
576 sc_data = (uint16_t *)sc;
577 for (i = 0; i < 64; i += 2)
578 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
579 have_seeprom = ahd_verify_cksum(sc);
580 if (have_seeprom)
581 ahd->flags |= AHD_SCB_CONFIG_USED;
582 }
583 }
584
585#if AHD_DEBUG
586 if (have_seeprom != 0
587 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
588 uint16_t *sc_data;
589 int i;
590
591 printf("%s: Seeprom Contents:", ahd_name(ahd));
592 sc_data = (uint16_t *)sc;
593 for (i = 0; i < (sizeof(*sc)); i += 2)
594 printf("\n\t0x%.4x", sc_data[i]);
595 printf("\n");
596 }
597#endif
598
599 if (!have_seeprom) {
600 if (bootverbose)
601 printf("%s: No SEEPROM available.\n", ahd_name(ahd));
602 ahd->flags |= AHD_USEDEFAULTS;
603 error = ahd_default_config(ahd);
604 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
605 free(ahd->seep_config, M_DEVBUF);
606 ahd->seep_config = NULL;
607 } else {
608 error = ahd_parse_cfgdata(ahd, sc);
609 adapter_control = sc->adapter_control;
610 }
611 if (error != 0)
612 return (error);
613
614 ahd_configure_termination(ahd, adapter_control);
615
616 return (0);
617}
618
619static void
620ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
621{
622 int error;
623 u_int sxfrctl1;
624 uint8_t termctl;
625 uint32_t devconfig;
626
627 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
628 devconfig &= ~STPWLEVEL;
629 if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
630 devconfig |= STPWLEVEL;
631 if (bootverbose)
632 printf("%s: STPWLEVEL is %s\n",
633 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
634 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
635
636 /* Make sure current sensing is off. */
637 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
638 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
639 }
640
641 /*
642 * Read to sense. Write to set.
643 */
644 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
645 if ((adapter_control & CFAUTOTERM) == 0) {
646 if (bootverbose)
647 printf("%s: Manual Primary Termination\n",
648 ahd_name(ahd));
649 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
650 if ((adapter_control & CFSTERM) != 0)
651 termctl |= FLX_TERMCTL_ENPRILOW;
652 if ((adapter_control & CFWSTERM) != 0)
653 termctl |= FLX_TERMCTL_ENPRIHIGH;
654 } else if (error != 0) {
655 printf("%s: Primary Auto-Term Sensing failed! "
656 "Using Defaults.\n", ahd_name(ahd));
657 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
658 }
659
660 if ((adapter_control & CFSEAUTOTERM) == 0) {
661 if (bootverbose)
662 printf("%s: Manual Secondary Termination\n",
663 ahd_name(ahd));
664 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
665 if ((adapter_control & CFSELOWTERM) != 0)
666 termctl |= FLX_TERMCTL_ENSECLOW;
667 if ((adapter_control & CFSEHIGHTERM) != 0)
668 termctl |= FLX_TERMCTL_ENSECHIGH;
669 } else if (error != 0) {
670 printf("%s: Secondary Auto-Term Sensing failed! "
671 "Using Defaults.\n", ahd_name(ahd));
672 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
673 }
674
675 /*
676 * Now set the termination based on what we found.
677 */
678 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
679 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
680 ahd->flags |= AHD_TERM_ENB_A;
681 sxfrctl1 |= STPWEN;
682 }
683 /* Must set the latch once in order to be effective. */
684 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
685 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
686
687 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
688 if (error != 0) {
689 printf("%s: Unable to set termination settings!\n",
690 ahd_name(ahd));
691 } else if (bootverbose) {
692 printf("%s: Primary High byte termination %sabled\n",
693 ahd_name(ahd),
694 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
695
696 printf("%s: Primary Low byte termination %sabled\n",
697 ahd_name(ahd),
698 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
699
700 printf("%s: Secondary High byte termination %sabled\n",
701 ahd_name(ahd),
702 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
703
704 printf("%s: Secondary Low byte termination %sabled\n",
705 ahd_name(ahd),
706 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
707 }
708 return;
709}
710
711#define DPE 0x80
712#define SSE 0x40
713#define RMA 0x20
714#define RTA 0x10
715#define STA 0x08
716#define DPR 0x01
717
718static const char *split_status_source[] =
719{
720 "DFF0",
721 "DFF1",
722 "OVLY",
723 "CMC",
724};
725
726static const char *pci_status_source[] =
727{
728 "DFF0",
729 "DFF1",
730 "SG",
731 "CMC",
732 "OVLY",
733 "NONE",
734 "MSI",
735 "TARG"
736};
737
738static const char *split_status_strings[] =
739{
740 "%s: Received split response in %s.\n",
741 "%s: Received split completion error message in %s\n",
742 "%s: Receive overrun in %s\n",
743 "%s: Count not complete in %s\n",
744 "%s: Split completion data bucket in %s\n",
745 "%s: Split completion address error in %s\n",
746 "%s: Split completion byte count error in %s\n",
747 "%s: Signaled Target-abort to early terminate a split in %s\n"
748};
749
750static const char *pci_status_strings[] =
751{
752 "%s: Data Parity Error has been reported via PERR# in %s\n",
753 "%s: Target initial wait state error in %s\n",
754 "%s: Split completion read data parity error in %s\n",
755 "%s: Split completion address attribute parity error in %s\n",
756 "%s: Received a Target Abort in %s\n",
757 "%s: Received a Master Abort in %s\n",
758 "%s: Signal System Error Detected in %s\n",
759 "%s: Address or Write Phase Parity Error Detected in %s.\n"
760};
761
762void
763ahd_pci_intr(struct ahd_softc *ahd)
764{
765 uint8_t pci_status[8];
766 ahd_mode_state saved_modes;
767 u_int pci_status1;
768 u_int intstat;
769 u_int i;
770 u_int reg;
771
772 intstat = ahd_inb(ahd, INTSTAT);
773
774 if ((intstat & SPLTINT) != 0)
775 ahd_pci_split_intr(ahd, intstat);
776
777 if ((intstat & PCIINT) == 0)
778 return;
779
780 printf("%s: PCI error Interrupt\n", ahd_name(ahd));
781 saved_modes = ahd_save_modes(ahd);
782 ahd_dump_card_state(ahd);
783 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
784 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
785
786 if (i == 5)
787 continue;
788 pci_status[i] = ahd_inb(ahd, reg);
789 /* Clear latched errors. So our interrupt deasserts. */
790 ahd_outb(ahd, reg, pci_status[i]);
791 }
792
793 for (i = 0; i < 8; i++) {
794 u_int bit;
795
796 if (i == 5)
797 continue;
798
799 for (bit = 0; bit < 8; bit++) {
800
801 if ((pci_status[i] & (0x1 << bit)) != 0) {
802 static const char *s;
803
804 s = pci_status_strings[bit];
805 if (i == 7/*TARG*/ && bit == 3)
806 s = "%s: Signaled Target Abort\n";
807 printf(s, ahd_name(ahd), pci_status_source[i]);
808 }
809 }
810 }
811 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
812 PCIR_STATUS + 1, /*bytes*/1);
813 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
814 pci_status1, /*bytes*/1);
815 ahd_restore_modes(ahd, saved_modes);
816 ahd_outb(ahd, CLRINT, CLRPCIINT);
817 ahd_unpause(ahd);
818}
819
820static void
821ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
822{
823 uint8_t split_status[4];
824 uint8_t split_status1[4];
825 uint8_t sg_split_status[2];
826 uint8_t sg_split_status1[2];
827 ahd_mode_state saved_modes;
828 u_int i;
829 uint16_t pcix_status;
830
831 /*
832 * Check for splits in all modes. Modes 0 and 1
833 * additionally have SG engine splits to look at.
834 */
835 pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
836 /*bytes*/2);
837 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
838 ahd_name(ahd), pcix_status);
839 saved_modes = ahd_save_modes(ahd);
840 for (i = 0; i < 4; i++) {
841 ahd_set_modes(ahd, i, i);
842
843 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
844 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
845 /* Clear latched errors. So our interrupt deasserts. */
846 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
847 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
848 if (i > 1)
849 continue;
850 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
851 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
852 /* Clear latched errors. So our interrupt deasserts. */
853 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
854 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
855 }
856
857 for (i = 0; i < 4; i++) {
858 u_int bit;
859
860 for (bit = 0; bit < 8; bit++) {
861
862 if ((split_status[i] & (0x1 << bit)) != 0) {
863 static const char *s;
864
865 s = split_status_strings[bit];
866 printf(s, ahd_name(ahd),
867 split_status_source[i]);
868 }
869
870 if (i > 1)
871 continue;
872
873 if ((sg_split_status[i] & (0x1 << bit)) != 0) {
874 static const char *s;
875
876 s = split_status_strings[bit];
877 printf(s, ahd_name(ahd), "SG");
878 }
879 }
880 }
881 /*
882 * Clear PCI-X status bits.
883 */
884 ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
885 pcix_status, /*bytes*/2);
886 ahd_outb(ahd, CLRINT, CLRSPLTINT);
887 ahd_restore_modes(ahd, saved_modes);
888}
889
890static int
891ahd_aic7901_setup(struct ahd_softc *ahd)
892{
893
894 ahd->chip = AHD_AIC7901;
895 ahd->features = AHD_AIC7901_FE;
896 return (ahd_aic790X_setup(ahd));
897}
898
899static int
900ahd_aic7901A_setup(struct ahd_softc *ahd)
901{
902
903 ahd->chip = AHD_AIC7901A;
904 ahd->features = AHD_AIC7901A_FE;
905 return (ahd_aic790X_setup(ahd));
906}
907
908static int
909ahd_aic7902_setup(struct ahd_softc *ahd)
910{
911 ahd->chip = AHD_AIC7902;
912 ahd->features = AHD_AIC7902_FE;
913 return (ahd_aic790X_setup(ahd));
914}
915
916static int
917ahd_aic790X_setup(struct ahd_softc *ahd)
918{
919 ahd_dev_softc_t pci;
920 u_int rev;
921
922 pci = ahd->dev_softc;
923 rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
924 if (rev < ID_AIC7902_PCI_REV_A4) {
925 printf("%s: Unable to attach to unsupported chip revision %d\n",
926 ahd_name(ahd), rev);
927 ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
928 return (ENXIO);
929 }
930 ahd->channel = ahd_get_pci_function(pci) + 'A';
931 if (rev < ID_AIC7902_PCI_REV_B0) {
932 /*
933 * Enable A series workarounds.
934 */
935 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
936 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
937 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
938 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
939 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
940 | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
941 | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
942 | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
943 | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
944 | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
945 | AHD_FAINT_LED_BUG;
946
947 /*
948 * IO Cell paramter setup.
949 */
950 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
951
952 if ((ahd->flags & AHD_HP_BOARD) == 0)
953 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
954 } else {
955 u_int devconfig1;
956
957 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
958 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
959 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
960
961 /*
962 * Some issues have been resolved in the 7901B.
963 */
964 if ((ahd->features & AHD_MULTI_FUNC) != 0)
965 ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
966
967 /*
968 * IO Cell paramter setup.
969 */
970 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
971 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
972 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
973
974 /*
975 * Set the PREQDIS bit for H2B which disables some workaround
976 * that doesn't work on regular PCI busses.
977 * XXX - Find out exactly what this does from the hardware
978 * folks!
979 */
980 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
981 ahd_pci_write_config(pci, DEVCONFIG1,
982 devconfig1|PREQDIS, /*bytes*/1);
983 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
984 }
985
986 return (0);
987}
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.h b/drivers/scsi/aic7xxx/aic79xx_pci.h
new file mode 100644
index 000000000000..b5cfeabdfecf
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.h
@@ -0,0 +1,70 @@
1/*
2 * Adaptec AIC79xx device driver for Linux.
3 *
4 * Copyright (c) 2000-2001 Adaptec Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon
16 * including a substantially similar Disclaimer requirement for further
17 * binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * Alternatively, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2 as published by the Free
24 * Software Foundation.
25 *
26 * NO WARRANTY
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGES.
38 *
39 * $Id$
40 *
41 */
42#ifndef _AIC79XX_PCI_H_
43#define _AIC79XX_PCI_H_
44
45#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull
46#define ID_ALL_IROC_MASK 0xFF7FFFFFFFFFFFFFull
47#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
48#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
49#define ID_9005_GENERIC_IROC_MASK 0xFF70FFFF00000000ull
50
51#define ID_AIC7901 0x800F9005FFFF9005ull
52#define ID_AHA_29320A 0x8000900500609005ull
53#define ID_AHA_29320ALP 0x8017900500449005ull
54
55#define ID_AIC7901A 0x801E9005FFFF9005ull
56#define ID_AHA_29320 0x8012900500429005ull
57#define ID_AHA_29320B 0x8013900500439005ull
58#define ID_AHA_29320LP 0x8014900500449005ull
59
60#define ID_AIC7902 0x801F9005FFFF9005ull
61#define ID_AIC7902_B 0x801D9005FFFF9005ull
62#define ID_AHA_39320 0x8010900500409005ull
63#define ID_AHA_39320_B 0x8015900500409005ull
64#define ID_AHA_39320A 0x8016900500409005ull
65#define ID_AHA_39320D 0x8011900500419005ull
66#define ID_AHA_39320D_B 0x801C900500419005ull
67#define ID_AHA_39320D_HP 0x8011900500AC0E11ull
68#define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull
69
70#endif /* _AIC79XX_PCI_H_ */
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c
new file mode 100644
index 000000000000..e01cd6175e34
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_proc.c
@@ -0,0 +1,362 @@
1/*
2 * Copyright (c) 2000-2001 Adaptec Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions, and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * substantially similar to the "NO WARRANTY" disclaimer below
13 * ("Disclaimer") and any redistribution must be conditioned upon
14 * including a substantially similar Disclaimer requirement for further
15 * binary redistribution.
16 * 3. Neither the names of the above-listed copyright holders nor the names
17 * of any contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * NO WARRANTY
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
34 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGES.
36 *
37 * String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
38 * sym driver.
39 *
40 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#19 $
41 */
42#include "aic79xx_osm.h"
43#include "aic79xx_inline.h"
44
45static void copy_mem_info(struct info_str *info, char *data, int len);
46static int copy_info(struct info_str *info, char *fmt, ...);
47static void ahd_dump_target_state(struct ahd_softc *ahd,
48 struct info_str *info,
49 u_int our_id, char channel,
50 u_int target_id, u_int target_offset);
51static void ahd_dump_device_state(struct info_str *info,
52 struct ahd_linux_device *dev);
53static int ahd_proc_write_seeprom(struct ahd_softc *ahd,
54 char *buffer, int length);
55
56static void
57copy_mem_info(struct info_str *info, char *data, int len)
58{
59 if (info->pos + len > info->offset + info->length)
60 len = info->offset + info->length - info->pos;
61
62 if (info->pos + len < info->offset) {
63 info->pos += len;
64 return;
65 }
66
67 if (info->pos < info->offset) {
68 off_t partial;
69
70 partial = info->offset - info->pos;
71 data += partial;
72 info->pos += partial;
73 len -= partial;
74 }
75
76 if (len > 0) {
77 memcpy(info->buffer, data, len);
78 info->pos += len;
79 info->buffer += len;
80 }
81}
82
83static int
84copy_info(struct info_str *info, char *fmt, ...)
85{
86 va_list args;
87 char buf[256];
88 int len;
89
90 va_start(args, fmt);
91 len = vsprintf(buf, fmt, args);
92 va_end(args);
93
94 copy_mem_info(info, buf, len);
95 return (len);
96}
97
98void
99ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
100{
101 u_int speed;
102 u_int freq;
103 u_int mb;
104
105 if (tinfo->period == AHD_PERIOD_UNKNOWN) {
106 copy_info(info, "Renegotiation Pending\n");
107 return;
108 }
109 speed = 3300;
110 freq = 0;
111 if (tinfo->offset != 0) {
112 freq = aic_calc_syncsrate(tinfo->period);
113 speed = freq;
114 }
115 speed *= (0x01 << tinfo->width);
116 mb = speed / 1000;
117 if (mb > 0)
118 copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000);
119 else
120 copy_info(info, "%dKB/s transfers", speed);
121
122 if (freq != 0) {
123 int printed_options;
124
125 printed_options = 0;
126 copy_info(info, " (%d.%03dMHz", freq / 1000, freq % 1000);
127 if ((tinfo->ppr_options & MSG_EXT_PPR_RD_STRM) != 0) {
128 copy_info(info, " RDSTRM");
129 printed_options++;
130 }
131 if ((tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
132 copy_info(info, "%s", printed_options ? "|DT" : " DT");
133 printed_options++;
134 }
135 if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
136 copy_info(info, "%s", printed_options ? "|IU" : " IU");
137 printed_options++;
138 }
139 if ((tinfo->ppr_options & MSG_EXT_PPR_RTI) != 0) {
140 copy_info(info, "%s",
141 printed_options ? "|RTI" : " RTI");
142 printed_options++;
143 }
144 if ((tinfo->ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) {
145 copy_info(info, "%s",
146 printed_options ? "|QAS" : " QAS");
147 printed_options++;
148 }
149 }
150
151 if (tinfo->width > 0) {
152 if (freq != 0) {
153 copy_info(info, ", ");
154 } else {
155 copy_info(info, " (");
156 }
157 copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width));
158 } else if (freq != 0) {
159 copy_info(info, ")");
160 }
161 copy_info(info, "\n");
162}
163
164static void
165ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info,
166 u_int our_id, char channel, u_int target_id,
167 u_int target_offset)
168{
169 struct ahd_linux_target *targ;
170 struct ahd_initiator_tinfo *tinfo;
171 struct ahd_tmode_tstate *tstate;
172 int lun;
173
174 tinfo = ahd_fetch_transinfo(ahd, channel, our_id,
175 target_id, &tstate);
176 copy_info(info, "Target %d Negotiation Settings\n", target_id);
177 copy_info(info, "\tUser: ");
178 ahd_format_transinfo(info, &tinfo->user);
179 targ = ahd->platform_data->targets[target_offset];
180 if (targ == NULL)
181 return;
182
183 copy_info(info, "\tGoal: ");
184 ahd_format_transinfo(info, &tinfo->goal);
185 copy_info(info, "\tCurr: ");
186 ahd_format_transinfo(info, &tinfo->curr);
187 copy_info(info, "\tTransmission Errors %ld\n", targ->errors_detected);
188
189 for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
190 struct ahd_linux_device *dev;
191
192 dev = targ->devices[lun];
193
194 if (dev == NULL)
195 continue;
196
197 ahd_dump_device_state(info, dev);
198 }
199}
200
201static void
202ahd_dump_device_state(struct info_str *info, struct ahd_linux_device *dev)
203{
204 copy_info(info, "\tChannel %c Target %d Lun %d Settings\n",
205 dev->target->channel + 'A', dev->target->target, dev->lun);
206
207 copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued);
208 copy_info(info, "\t\tCommands Active %d\n", dev->active);
209 copy_info(info, "\t\tCommand Openings %d\n", dev->openings);
210 copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags);
211 copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen);
212}
213
214static int
215ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length)
216{
217 ahd_mode_state saved_modes;
218 int have_seeprom;
219 u_long s;
220 int paused;
221 int written;
222
223 /* Default to failure. */
224 written = -EINVAL;
225 ahd_lock(ahd, &s);
226 paused = ahd_is_paused(ahd);
227 if (!paused)
228 ahd_pause(ahd);
229
230 saved_modes = ahd_save_modes(ahd);
231 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
232 if (length != sizeof(struct seeprom_config)) {
233 printf("ahd_proc_write_seeprom: incorrect buffer size\n");
234 goto done;
235 }
236
237 have_seeprom = ahd_verify_cksum((struct seeprom_config*)buffer);
238 if (have_seeprom == 0) {
239 printf("ahd_proc_write_seeprom: cksum verification failed\n");
240 goto done;
241 }
242
243 have_seeprom = ahd_acquire_seeprom(ahd);
244 if (!have_seeprom) {
245 printf("ahd_proc_write_seeprom: No Serial EEPROM\n");
246 goto done;
247 } else {
248 u_int start_addr;
249
250 if (ahd->seep_config == NULL) {
251 ahd->seep_config = malloc(sizeof(*ahd->seep_config),
252 M_DEVBUF, M_NOWAIT);
253 if (ahd->seep_config == NULL) {
254 printf("aic79xx: Unable to allocate serial "
255 "eeprom buffer. Write failing\n");
256 goto done;
257 }
258 }
259 printf("aic79xx: Writing Serial EEPROM\n");
260 start_addr = 32 * (ahd->channel - 'A');
261 ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr,
262 sizeof(struct seeprom_config)/2);
263 ahd_read_seeprom(ahd, (uint16_t *)ahd->seep_config,
264 start_addr, sizeof(struct seeprom_config)/2,
265 /*ByteStream*/FALSE);
266 ahd_release_seeprom(ahd);
267 written = length;
268 }
269
270done:
271 ahd_restore_modes(ahd, saved_modes);
272 if (!paused)
273 ahd_unpause(ahd);
274 ahd_unlock(ahd, &s);
275 return (written);
276}
277/*
278 * Return information to handle /proc support for the driver.
279 */
280int
281#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
282ahd_linux_proc_info(char *buffer, char **start, off_t offset,
283 int length, int hostno, int inout)
284#else
285ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
286 off_t offset, int length, int inout)
287#endif
288{
289 struct ahd_softc *ahd;
290 struct info_str info;
291 char ahd_info[256];
292 u_long l;
293 u_int max_targ;
294 u_int i;
295 int retval;
296
297 retval = -EINVAL;
298 ahd_list_lock(&l);
299#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
300 TAILQ_FOREACH(ahd, &ahd_tailq, links) {
301 if (ahd->platform_data->host->host_no == hostno)
302 break;
303 }
304#else
305 ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata);
306#endif
307
308 if (ahd == NULL)
309 goto done;
310
311 /* Has data been written to the file? */
312 if (inout == TRUE) {
313 retval = ahd_proc_write_seeprom(ahd, buffer, length);
314 goto done;
315 }
316
317 if (start)
318 *start = buffer;
319
320 info.buffer = buffer;
321 info.length = length;
322 info.offset = offset;
323 info.pos = 0;
324
325 copy_info(&info, "Adaptec AIC79xx driver version: %s\n",
326 AIC79XX_DRIVER_VERSION);
327 copy_info(&info, "%s\n", ahd->description);
328 ahd_controller_info(ahd, ahd_info);
329 copy_info(&info, "%s\n", ahd_info);
330 copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n",
331 ahd->scb_data.numscbs, AHD_NSEG);
332
333 max_targ = 15;
334
335 if (ahd->seep_config == NULL)
336 copy_info(&info, "No Serial EEPROM\n");
337 else {
338 copy_info(&info, "Serial EEPROM:\n");
339 for (i = 0; i < sizeof(*ahd->seep_config)/2; i++) {
340 if (((i % 8) == 0) && (i != 0)) {
341 copy_info(&info, "\n");
342 }
343 copy_info(&info, "0x%.4x ",
344 ((uint16_t*)ahd->seep_config)[i]);
345 }
346 copy_info(&info, "\n");
347 }
348 copy_info(&info, "\n");
349
350 if ((ahd->features & AHD_WIDE) == 0)
351 max_targ = 7;
352
353 for (i = 0; i <= max_targ; i++) {
354
355 ahd_dump_target_state(ahd, &info, ahd->our_id, 'A',
356 /*target_id*/i, /*target_offset*/i);
357 }
358 retval = info.pos > info.offset ? info.pos - info.offset : 0;
359done:
360 ahd_list_unlock(&l);
361 return (retval);
362}
diff --git a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
new file mode 100644
index 000000000000..c01ac39090d9
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
@@ -0,0 +1,3776 @@
1/*
2 * DO NOT EDIT - This file is automatically generated
3 * from the following source files:
4 *
5 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
6 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
7 */
8typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
9typedef struct ahd_reg_parse_entry {
10 char *name;
11 uint8_t value;
12 uint8_t mask;
13} ahd_reg_parse_entry_t;
14
15#if AIC_DEBUG_REGISTERS
16ahd_reg_print_t ahd_mode_ptr_print;
17#else
18#define ahd_mode_ptr_print(regvalue, cur_col, wrap) \
19 ahd_print_register(NULL, 0, "MODE_PTR", 0x00, regvalue, cur_col, wrap)
20#endif
21
22#if AIC_DEBUG_REGISTERS
23ahd_reg_print_t ahd_intstat_print;
24#else
25#define ahd_intstat_print(regvalue, cur_col, wrap) \
26 ahd_print_register(NULL, 0, "INTSTAT", 0x01, regvalue, cur_col, wrap)
27#endif
28
29#if AIC_DEBUG_REGISTERS
30ahd_reg_print_t ahd_seqintcode_print;
31#else
32#define ahd_seqintcode_print(regvalue, cur_col, wrap) \
33 ahd_print_register(NULL, 0, "SEQINTCODE", 0x02, regvalue, cur_col, wrap)
34#endif
35
36#if AIC_DEBUG_REGISTERS
37ahd_reg_print_t ahd_clrint_print;
38#else
39#define ahd_clrint_print(regvalue, cur_col, wrap) \
40 ahd_print_register(NULL, 0, "CLRINT", 0x03, regvalue, cur_col, wrap)
41#endif
42
43#if AIC_DEBUG_REGISTERS
44ahd_reg_print_t ahd_error_print;
45#else
46#define ahd_error_print(regvalue, cur_col, wrap) \
47 ahd_print_register(NULL, 0, "ERROR", 0x04, regvalue, cur_col, wrap)
48#endif
49
50#if AIC_DEBUG_REGISTERS
51ahd_reg_print_t ahd_clrerr_print;
52#else
53#define ahd_clrerr_print(regvalue, cur_col, wrap) \
54 ahd_print_register(NULL, 0, "CLRERR", 0x04, regvalue, cur_col, wrap)
55#endif
56
57#if AIC_DEBUG_REGISTERS
58ahd_reg_print_t ahd_hcntrl_print;
59#else
60#define ahd_hcntrl_print(regvalue, cur_col, wrap) \
61 ahd_print_register(NULL, 0, "HCNTRL", 0x05, regvalue, cur_col, wrap)
62#endif
63
64#if AIC_DEBUG_REGISTERS
65ahd_reg_print_t ahd_hnscb_qoff_print;
66#else
67#define ahd_hnscb_qoff_print(regvalue, cur_col, wrap) \
68 ahd_print_register(NULL, 0, "HNSCB_QOFF", 0x06, regvalue, cur_col, wrap)
69#endif
70
71#if AIC_DEBUG_REGISTERS
72ahd_reg_print_t ahd_hescb_qoff_print;
73#else
74#define ahd_hescb_qoff_print(regvalue, cur_col, wrap) \
75 ahd_print_register(NULL, 0, "HESCB_QOFF", 0x08, regvalue, cur_col, wrap)
76#endif
77
78#if AIC_DEBUG_REGISTERS
79ahd_reg_print_t ahd_hs_mailbox_print;
80#else
81#define ahd_hs_mailbox_print(regvalue, cur_col, wrap) \
82 ahd_print_register(NULL, 0, "HS_MAILBOX", 0x0b, regvalue, cur_col, wrap)
83#endif
84
85#if AIC_DEBUG_REGISTERS
86ahd_reg_print_t ahd_clrseqintstat_print;
87#else
88#define ahd_clrseqintstat_print(regvalue, cur_col, wrap) \
89 ahd_print_register(NULL, 0, "CLRSEQINTSTAT", 0x0c, regvalue, cur_col, wrap)
90#endif
91
92#if AIC_DEBUG_REGISTERS
93ahd_reg_print_t ahd_seqintstat_print;
94#else
95#define ahd_seqintstat_print(regvalue, cur_col, wrap) \
96 ahd_print_register(NULL, 0, "SEQINTSTAT", 0x0c, regvalue, cur_col, wrap)
97#endif
98
99#if AIC_DEBUG_REGISTERS
100ahd_reg_print_t ahd_swtimer_print;
101#else
102#define ahd_swtimer_print(regvalue, cur_col, wrap) \
103 ahd_print_register(NULL, 0, "SWTIMER", 0x0e, regvalue, cur_col, wrap)
104#endif
105
106#if AIC_DEBUG_REGISTERS
107ahd_reg_print_t ahd_snscb_qoff_print;
108#else
109#define ahd_snscb_qoff_print(regvalue, cur_col, wrap) \
110 ahd_print_register(NULL, 0, "SNSCB_QOFF", 0x10, regvalue, cur_col, wrap)
111#endif
112
113#if AIC_DEBUG_REGISTERS
114ahd_reg_print_t ahd_sescb_qoff_print;
115#else
116#define ahd_sescb_qoff_print(regvalue, cur_col, wrap) \
117 ahd_print_register(NULL, 0, "SESCB_QOFF", 0x12, regvalue, cur_col, wrap)
118#endif
119
120#if AIC_DEBUG_REGISTERS
121ahd_reg_print_t ahd_sdscb_qoff_print;
122#else
123#define ahd_sdscb_qoff_print(regvalue, cur_col, wrap) \
124 ahd_print_register(NULL, 0, "SDSCB_QOFF", 0x14, regvalue, cur_col, wrap)
125#endif
126
127#if AIC_DEBUG_REGISTERS
128ahd_reg_print_t ahd_qoff_ctlsta_print;
129#else
130#define ahd_qoff_ctlsta_print(regvalue, cur_col, wrap) \
131 ahd_print_register(NULL, 0, "QOFF_CTLSTA", 0x16, regvalue, cur_col, wrap)
132#endif
133
134#if AIC_DEBUG_REGISTERS
135ahd_reg_print_t ahd_intctl_print;
136#else
137#define ahd_intctl_print(regvalue, cur_col, wrap) \
138 ahd_print_register(NULL, 0, "INTCTL", 0x18, regvalue, cur_col, wrap)
139#endif
140
141#if AIC_DEBUG_REGISTERS
142ahd_reg_print_t ahd_dfcntrl_print;
143#else
144#define ahd_dfcntrl_print(regvalue, cur_col, wrap) \
145 ahd_print_register(NULL, 0, "DFCNTRL", 0x19, regvalue, cur_col, wrap)
146#endif
147
148#if AIC_DEBUG_REGISTERS
149ahd_reg_print_t ahd_dscommand0_print;
150#else
151#define ahd_dscommand0_print(regvalue, cur_col, wrap) \
152 ahd_print_register(NULL, 0, "DSCOMMAND0", 0x19, regvalue, cur_col, wrap)
153#endif
154
155#if AIC_DEBUG_REGISTERS
156ahd_reg_print_t ahd_dfstatus_print;
157#else
158#define ahd_dfstatus_print(regvalue, cur_col, wrap) \
159 ahd_print_register(NULL, 0, "DFSTATUS", 0x1a, regvalue, cur_col, wrap)
160#endif
161
162#if AIC_DEBUG_REGISTERS
163ahd_reg_print_t ahd_sg_cache_shadow_print;
164#else
165#define ahd_sg_cache_shadow_print(regvalue, cur_col, wrap) \
166 ahd_print_register(NULL, 0, "SG_CACHE_SHADOW", 0x1b, regvalue, cur_col, wrap)
167#endif
168
169#if AIC_DEBUG_REGISTERS
170ahd_reg_print_t ahd_arbctl_print;
171#else
172#define ahd_arbctl_print(regvalue, cur_col, wrap) \
173 ahd_print_register(NULL, 0, "ARBCTL", 0x1b, regvalue, cur_col, wrap)
174#endif
175
176#if AIC_DEBUG_REGISTERS
177ahd_reg_print_t ahd_sg_cache_pre_print;
178#else
179#define ahd_sg_cache_pre_print(regvalue, cur_col, wrap) \
180 ahd_print_register(NULL, 0, "SG_CACHE_PRE", 0x1b, regvalue, cur_col, wrap)
181#endif
182
183#if AIC_DEBUG_REGISTERS
184ahd_reg_print_t ahd_lqin_print;
185#else
186#define ahd_lqin_print(regvalue, cur_col, wrap) \
187 ahd_print_register(NULL, 0, "LQIN", 0x20, regvalue, cur_col, wrap)
188#endif
189
190#if AIC_DEBUG_REGISTERS
191ahd_reg_print_t ahd_typeptr_print;
192#else
193#define ahd_typeptr_print(regvalue, cur_col, wrap) \
194 ahd_print_register(NULL, 0, "TYPEPTR", 0x20, regvalue, cur_col, wrap)
195#endif
196
197#if AIC_DEBUG_REGISTERS
198ahd_reg_print_t ahd_tagptr_print;
199#else
200#define ahd_tagptr_print(regvalue, cur_col, wrap) \
201 ahd_print_register(NULL, 0, "TAGPTR", 0x21, regvalue, cur_col, wrap)
202#endif
203
204#if AIC_DEBUG_REGISTERS
205ahd_reg_print_t ahd_lunptr_print;
206#else
207#define ahd_lunptr_print(regvalue, cur_col, wrap) \
208 ahd_print_register(NULL, 0, "LUNPTR", 0x22, regvalue, cur_col, wrap)
209#endif
210
211#if AIC_DEBUG_REGISTERS
212ahd_reg_print_t ahd_datalenptr_print;
213#else
214#define ahd_datalenptr_print(regvalue, cur_col, wrap) \
215 ahd_print_register(NULL, 0, "DATALENPTR", 0x23, regvalue, cur_col, wrap)
216#endif
217
218#if AIC_DEBUG_REGISTERS
219ahd_reg_print_t ahd_statlenptr_print;
220#else
221#define ahd_statlenptr_print(regvalue, cur_col, wrap) \
222 ahd_print_register(NULL, 0, "STATLENPTR", 0x24, regvalue, cur_col, wrap)
223#endif
224
225#if AIC_DEBUG_REGISTERS
226ahd_reg_print_t ahd_cmdlenptr_print;
227#else
228#define ahd_cmdlenptr_print(regvalue, cur_col, wrap) \
229 ahd_print_register(NULL, 0, "CMDLENPTR", 0x25, regvalue, cur_col, wrap)
230#endif
231
232#if AIC_DEBUG_REGISTERS
233ahd_reg_print_t ahd_attrptr_print;
234#else
235#define ahd_attrptr_print(regvalue, cur_col, wrap) \
236 ahd_print_register(NULL, 0, "ATTRPTR", 0x26, regvalue, cur_col, wrap)
237#endif
238
239#if AIC_DEBUG_REGISTERS
240ahd_reg_print_t ahd_flagptr_print;
241#else
242#define ahd_flagptr_print(regvalue, cur_col, wrap) \
243 ahd_print_register(NULL, 0, "FLAGPTR", 0x27, regvalue, cur_col, wrap)
244#endif
245
246#if AIC_DEBUG_REGISTERS
247ahd_reg_print_t ahd_cmdptr_print;
248#else
249#define ahd_cmdptr_print(regvalue, cur_col, wrap) \
250 ahd_print_register(NULL, 0, "CMDPTR", 0x28, regvalue, cur_col, wrap)
251#endif
252
253#if AIC_DEBUG_REGISTERS
254ahd_reg_print_t ahd_qnextptr_print;
255#else
256#define ahd_qnextptr_print(regvalue, cur_col, wrap) \
257 ahd_print_register(NULL, 0, "QNEXTPTR", 0x29, regvalue, cur_col, wrap)
258#endif
259
260#if AIC_DEBUG_REGISTERS
261ahd_reg_print_t ahd_idptr_print;
262#else
263#define ahd_idptr_print(regvalue, cur_col, wrap) \
264 ahd_print_register(NULL, 0, "IDPTR", 0x2a, regvalue, cur_col, wrap)
265#endif
266
267#if AIC_DEBUG_REGISTERS
268ahd_reg_print_t ahd_abrtbyteptr_print;
269#else
270#define ahd_abrtbyteptr_print(regvalue, cur_col, wrap) \
271 ahd_print_register(NULL, 0, "ABRTBYTEPTR", 0x2b, regvalue, cur_col, wrap)
272#endif
273
274#if AIC_DEBUG_REGISTERS
275ahd_reg_print_t ahd_abrtbitptr_print;
276#else
277#define ahd_abrtbitptr_print(regvalue, cur_col, wrap) \
278 ahd_print_register(NULL, 0, "ABRTBITPTR", 0x2c, regvalue, cur_col, wrap)
279#endif
280
281#if AIC_DEBUG_REGISTERS
282ahd_reg_print_t ahd_maxcmdbytes_print;
283#else
284#define ahd_maxcmdbytes_print(regvalue, cur_col, wrap) \
285 ahd_print_register(NULL, 0, "MAXCMDBYTES", 0x2d, regvalue, cur_col, wrap)
286#endif
287
288#if AIC_DEBUG_REGISTERS
289ahd_reg_print_t ahd_maxcmd2rcv_print;
290#else
291#define ahd_maxcmd2rcv_print(regvalue, cur_col, wrap) \
292 ahd_print_register(NULL, 0, "MAXCMD2RCV", 0x2e, regvalue, cur_col, wrap)
293#endif
294
295#if AIC_DEBUG_REGISTERS
296ahd_reg_print_t ahd_shortthresh_print;
297#else
298#define ahd_shortthresh_print(regvalue, cur_col, wrap) \
299 ahd_print_register(NULL, 0, "SHORTTHRESH", 0x2f, regvalue, cur_col, wrap)
300#endif
301
302#if AIC_DEBUG_REGISTERS
303ahd_reg_print_t ahd_lunlen_print;
304#else
305#define ahd_lunlen_print(regvalue, cur_col, wrap) \
306 ahd_print_register(NULL, 0, "LUNLEN", 0x30, regvalue, cur_col, wrap)
307#endif
308
309#if AIC_DEBUG_REGISTERS
310ahd_reg_print_t ahd_cdblimit_print;
311#else
312#define ahd_cdblimit_print(regvalue, cur_col, wrap) \
313 ahd_print_register(NULL, 0, "CDBLIMIT", 0x31, regvalue, cur_col, wrap)
314#endif
315
316#if AIC_DEBUG_REGISTERS
317ahd_reg_print_t ahd_maxcmd_print;
318#else
319#define ahd_maxcmd_print(regvalue, cur_col, wrap) \
320 ahd_print_register(NULL, 0, "MAXCMD", 0x32, regvalue, cur_col, wrap)
321#endif
322
323#if AIC_DEBUG_REGISTERS
324ahd_reg_print_t ahd_maxcmdcnt_print;
325#else
326#define ahd_maxcmdcnt_print(regvalue, cur_col, wrap) \
327 ahd_print_register(NULL, 0, "MAXCMDCNT", 0x33, regvalue, cur_col, wrap)
328#endif
329
330#if AIC_DEBUG_REGISTERS
331ahd_reg_print_t ahd_lqrsvd01_print;
332#else
333#define ahd_lqrsvd01_print(regvalue, cur_col, wrap) \
334 ahd_print_register(NULL, 0, "LQRSVD01", 0x34, regvalue, cur_col, wrap)
335#endif
336
337#if AIC_DEBUG_REGISTERS
338ahd_reg_print_t ahd_lqrsvd16_print;
339#else
340#define ahd_lqrsvd16_print(regvalue, cur_col, wrap) \
341 ahd_print_register(NULL, 0, "LQRSVD16", 0x35, regvalue, cur_col, wrap)
342#endif
343
344#if AIC_DEBUG_REGISTERS
345ahd_reg_print_t ahd_lqrsvd17_print;
346#else
347#define ahd_lqrsvd17_print(regvalue, cur_col, wrap) \
348 ahd_print_register(NULL, 0, "LQRSVD17", 0x36, regvalue, cur_col, wrap)
349#endif
350
351#if AIC_DEBUG_REGISTERS
352ahd_reg_print_t ahd_cmdrsvd0_print;
353#else
354#define ahd_cmdrsvd0_print(regvalue, cur_col, wrap) \
355 ahd_print_register(NULL, 0, "CMDRSVD0", 0x37, regvalue, cur_col, wrap)
356#endif
357
358#if AIC_DEBUG_REGISTERS
359ahd_reg_print_t ahd_lqctl0_print;
360#else
361#define ahd_lqctl0_print(regvalue, cur_col, wrap) \
362 ahd_print_register(NULL, 0, "LQCTL0", 0x38, regvalue, cur_col, wrap)
363#endif
364
365#if AIC_DEBUG_REGISTERS
366ahd_reg_print_t ahd_lqctl1_print;
367#else
368#define ahd_lqctl1_print(regvalue, cur_col, wrap) \
369 ahd_print_register(NULL, 0, "LQCTL1", 0x38, regvalue, cur_col, wrap)
370#endif
371
372#if AIC_DEBUG_REGISTERS
373ahd_reg_print_t ahd_scsbist0_print;
374#else
375#define ahd_scsbist0_print(regvalue, cur_col, wrap) \
376 ahd_print_register(NULL, 0, "SCSBIST0", 0x39, regvalue, cur_col, wrap)
377#endif
378
379#if AIC_DEBUG_REGISTERS
380ahd_reg_print_t ahd_lqctl2_print;
381#else
382#define ahd_lqctl2_print(regvalue, cur_col, wrap) \
383 ahd_print_register(NULL, 0, "LQCTL2", 0x39, regvalue, cur_col, wrap)
384#endif
385
386#if AIC_DEBUG_REGISTERS
387ahd_reg_print_t ahd_scsbist1_print;
388#else
389#define ahd_scsbist1_print(regvalue, cur_col, wrap) \
390 ahd_print_register(NULL, 0, "SCSBIST1", 0x3a, regvalue, cur_col, wrap)
391#endif
392
393#if AIC_DEBUG_REGISTERS
394ahd_reg_print_t ahd_scsiseq0_print;
395#else
396#define ahd_scsiseq0_print(regvalue, cur_col, wrap) \
397 ahd_print_register(NULL, 0, "SCSISEQ0", 0x3a, regvalue, cur_col, wrap)
398#endif
399
400#if AIC_DEBUG_REGISTERS
401ahd_reg_print_t ahd_scsiseq1_print;
402#else
403#define ahd_scsiseq1_print(regvalue, cur_col, wrap) \
404 ahd_print_register(NULL, 0, "SCSISEQ1", 0x3b, regvalue, cur_col, wrap)
405#endif
406
407#if AIC_DEBUG_REGISTERS
408ahd_reg_print_t ahd_sxfrctl0_print;
409#else
410#define ahd_sxfrctl0_print(regvalue, cur_col, wrap) \
411 ahd_print_register(NULL, 0, "SXFRCTL0", 0x3c, regvalue, cur_col, wrap)
412#endif
413
414#if AIC_DEBUG_REGISTERS
415ahd_reg_print_t ahd_businitid_print;
416#else
417#define ahd_businitid_print(regvalue, cur_col, wrap) \
418 ahd_print_register(NULL, 0, "BUSINITID", 0x3c, regvalue, cur_col, wrap)
419#endif
420
421#if AIC_DEBUG_REGISTERS
422ahd_reg_print_t ahd_dlcount_print;
423#else
424#define ahd_dlcount_print(regvalue, cur_col, wrap) \
425 ahd_print_register(NULL, 0, "DLCOUNT", 0x3c, regvalue, cur_col, wrap)
426#endif
427
428#if AIC_DEBUG_REGISTERS
429ahd_reg_print_t ahd_sxfrctl1_print;
430#else
431#define ahd_sxfrctl1_print(regvalue, cur_col, wrap) \
432 ahd_print_register(NULL, 0, "SXFRCTL1", 0x3d, regvalue, cur_col, wrap)
433#endif
434
435#if AIC_DEBUG_REGISTERS
436ahd_reg_print_t ahd_bustargid_print;
437#else
438#define ahd_bustargid_print(regvalue, cur_col, wrap) \
439 ahd_print_register(NULL, 0, "BUSTARGID", 0x3e, regvalue, cur_col, wrap)
440#endif
441
442#if AIC_DEBUG_REGISTERS
443ahd_reg_print_t ahd_sxfrctl2_print;
444#else
445#define ahd_sxfrctl2_print(regvalue, cur_col, wrap) \
446 ahd_print_register(NULL, 0, "SXFRCTL2", 0x3e, regvalue, cur_col, wrap)
447#endif
448
449#if AIC_DEBUG_REGISTERS
450ahd_reg_print_t ahd_dffstat_print;
451#else
452#define ahd_dffstat_print(regvalue, cur_col, wrap) \
453 ahd_print_register(NULL, 0, "DFFSTAT", 0x3f, regvalue, cur_col, wrap)
454#endif
455
456#if AIC_DEBUG_REGISTERS
457ahd_reg_print_t ahd_scsisigo_print;
458#else
459#define ahd_scsisigo_print(regvalue, cur_col, wrap) \
460 ahd_print_register(NULL, 0, "SCSISIGO", 0x40, regvalue, cur_col, wrap)
461#endif
462
463#if AIC_DEBUG_REGISTERS
464ahd_reg_print_t ahd_multargid_print;
465#else
466#define ahd_multargid_print(regvalue, cur_col, wrap) \
467 ahd_print_register(NULL, 0, "MULTARGID", 0x40, regvalue, cur_col, wrap)
468#endif
469
470#if AIC_DEBUG_REGISTERS
471ahd_reg_print_t ahd_scsisigi_print;
472#else
473#define ahd_scsisigi_print(regvalue, cur_col, wrap) \
474 ahd_print_register(NULL, 0, "SCSISIGI", 0x41, regvalue, cur_col, wrap)
475#endif
476
477#if AIC_DEBUG_REGISTERS
478ahd_reg_print_t ahd_scsiphase_print;
479#else
480#define ahd_scsiphase_print(regvalue, cur_col, wrap) \
481 ahd_print_register(NULL, 0, "SCSIPHASE", 0x42, regvalue, cur_col, wrap)
482#endif
483
484#if AIC_DEBUG_REGISTERS
485ahd_reg_print_t ahd_scsidat0_img_print;
486#else
487#define ahd_scsidat0_img_print(regvalue, cur_col, wrap) \
488 ahd_print_register(NULL, 0, "SCSIDAT0_IMG", 0x43, regvalue, cur_col, wrap)
489#endif
490
491#if AIC_DEBUG_REGISTERS
492ahd_reg_print_t ahd_scsidat_print;
493#else
494#define ahd_scsidat_print(regvalue, cur_col, wrap) \
495 ahd_print_register(NULL, 0, "SCSIDAT", 0x44, regvalue, cur_col, wrap)
496#endif
497
498#if AIC_DEBUG_REGISTERS
499ahd_reg_print_t ahd_scsibus_print;
500#else
501#define ahd_scsibus_print(regvalue, cur_col, wrap) \
502 ahd_print_register(NULL, 0, "SCSIBUS", 0x46, regvalue, cur_col, wrap)
503#endif
504
505#if AIC_DEBUG_REGISTERS
506ahd_reg_print_t ahd_targidin_print;
507#else
508#define ahd_targidin_print(regvalue, cur_col, wrap) \
509 ahd_print_register(NULL, 0, "TARGIDIN", 0x48, regvalue, cur_col, wrap)
510#endif
511
512#if AIC_DEBUG_REGISTERS
513ahd_reg_print_t ahd_selid_print;
514#else
515#define ahd_selid_print(regvalue, cur_col, wrap) \
516 ahd_print_register(NULL, 0, "SELID", 0x49, regvalue, cur_col, wrap)
517#endif
518
519#if AIC_DEBUG_REGISTERS
520ahd_reg_print_t ahd_sblkctl_print;
521#else
522#define ahd_sblkctl_print(regvalue, cur_col, wrap) \
523 ahd_print_register(NULL, 0, "SBLKCTL", 0x4a, regvalue, cur_col, wrap)
524#endif
525
526#if AIC_DEBUG_REGISTERS
527ahd_reg_print_t ahd_optionmode_print;
528#else
529#define ahd_optionmode_print(regvalue, cur_col, wrap) \
530 ahd_print_register(NULL, 0, "OPTIONMODE", 0x4a, regvalue, cur_col, wrap)
531#endif
532
533#if AIC_DEBUG_REGISTERS
534ahd_reg_print_t ahd_sstat0_print;
535#else
536#define ahd_sstat0_print(regvalue, cur_col, wrap) \
537 ahd_print_register(NULL, 0, "SSTAT0", 0x4b, regvalue, cur_col, wrap)
538#endif
539
540#if AIC_DEBUG_REGISTERS
541ahd_reg_print_t ahd_clrsint0_print;
542#else
543#define ahd_clrsint0_print(regvalue, cur_col, wrap) \
544 ahd_print_register(NULL, 0, "CLRSINT0", 0x4b, regvalue, cur_col, wrap)
545#endif
546
547#if AIC_DEBUG_REGISTERS
548ahd_reg_print_t ahd_simode0_print;
549#else
550#define ahd_simode0_print(regvalue, cur_col, wrap) \
551 ahd_print_register(NULL, 0, "SIMODE0", 0x4b, regvalue, cur_col, wrap)
552#endif
553
554#if AIC_DEBUG_REGISTERS
555ahd_reg_print_t ahd_clrsint1_print;
556#else
557#define ahd_clrsint1_print(regvalue, cur_col, wrap) \
558 ahd_print_register(NULL, 0, "CLRSINT1", 0x4c, regvalue, cur_col, wrap)
559#endif
560
561#if AIC_DEBUG_REGISTERS
562ahd_reg_print_t ahd_sstat1_print;
563#else
564#define ahd_sstat1_print(regvalue, cur_col, wrap) \
565 ahd_print_register(NULL, 0, "SSTAT1", 0x4c, regvalue, cur_col, wrap)
566#endif
567
568#if AIC_DEBUG_REGISTERS
569ahd_reg_print_t ahd_sstat2_print;
570#else
571#define ahd_sstat2_print(regvalue, cur_col, wrap) \
572 ahd_print_register(NULL, 0, "SSTAT2", 0x4d, regvalue, cur_col, wrap)
573#endif
574
575#if AIC_DEBUG_REGISTERS
576ahd_reg_print_t ahd_clrsint2_print;
577#else
578#define ahd_clrsint2_print(regvalue, cur_col, wrap) \
579 ahd_print_register(NULL, 0, "CLRSINT2", 0x4d, regvalue, cur_col, wrap)
580#endif
581
582#if AIC_DEBUG_REGISTERS
583ahd_reg_print_t ahd_simode2_print;
584#else
585#define ahd_simode2_print(regvalue, cur_col, wrap) \
586 ahd_print_register(NULL, 0, "SIMODE2", 0x4d, regvalue, cur_col, wrap)
587#endif
588
589#if AIC_DEBUG_REGISTERS
590ahd_reg_print_t ahd_perrdiag_print;
591#else
592#define ahd_perrdiag_print(regvalue, cur_col, wrap) \
593 ahd_print_register(NULL, 0, "PERRDIAG", 0x4e, regvalue, cur_col, wrap)
594#endif
595
596#if AIC_DEBUG_REGISTERS
597ahd_reg_print_t ahd_lqistate_print;
598#else
599#define ahd_lqistate_print(regvalue, cur_col, wrap) \
600 ahd_print_register(NULL, 0, "LQISTATE", 0x4e, regvalue, cur_col, wrap)
601#endif
602
603#if AIC_DEBUG_REGISTERS
604ahd_reg_print_t ahd_soffcnt_print;
605#else
606#define ahd_soffcnt_print(regvalue, cur_col, wrap) \
607 ahd_print_register(NULL, 0, "SOFFCNT", 0x4f, regvalue, cur_col, wrap)
608#endif
609
610#if AIC_DEBUG_REGISTERS
611ahd_reg_print_t ahd_lqostate_print;
612#else
613#define ahd_lqostate_print(regvalue, cur_col, wrap) \
614 ahd_print_register(NULL, 0, "LQOSTATE", 0x4f, regvalue, cur_col, wrap)
615#endif
616
617#if AIC_DEBUG_REGISTERS
618ahd_reg_print_t ahd_lqistat0_print;
619#else
620#define ahd_lqistat0_print(regvalue, cur_col, wrap) \
621 ahd_print_register(NULL, 0, "LQISTAT0", 0x50, regvalue, cur_col, wrap)
622#endif
623
624#if AIC_DEBUG_REGISTERS
625ahd_reg_print_t ahd_clrlqiint0_print;
626#else
627#define ahd_clrlqiint0_print(regvalue, cur_col, wrap) \
628 ahd_print_register(NULL, 0, "CLRLQIINT0", 0x50, regvalue, cur_col, wrap)
629#endif
630
631#if AIC_DEBUG_REGISTERS
632ahd_reg_print_t ahd_lqimode0_print;
633#else
634#define ahd_lqimode0_print(regvalue, cur_col, wrap) \
635 ahd_print_register(NULL, 0, "LQIMODE0", 0x50, regvalue, cur_col, wrap)
636#endif
637
638#if AIC_DEBUG_REGISTERS
639ahd_reg_print_t ahd_lqimode1_print;
640#else
641#define ahd_lqimode1_print(regvalue, cur_col, wrap) \
642 ahd_print_register(NULL, 0, "LQIMODE1", 0x51, regvalue, cur_col, wrap)
643#endif
644
645#if AIC_DEBUG_REGISTERS
646ahd_reg_print_t ahd_lqistat1_print;
647#else
648#define ahd_lqistat1_print(regvalue, cur_col, wrap) \
649 ahd_print_register(NULL, 0, "LQISTAT1", 0x51, regvalue, cur_col, wrap)
650#endif
651
652#if AIC_DEBUG_REGISTERS
653ahd_reg_print_t ahd_clrlqiint1_print;
654#else
655#define ahd_clrlqiint1_print(regvalue, cur_col, wrap) \
656 ahd_print_register(NULL, 0, "CLRLQIINT1", 0x51, regvalue, cur_col, wrap)
657#endif
658
659#if AIC_DEBUG_REGISTERS
660ahd_reg_print_t ahd_lqistat2_print;
661#else
662#define ahd_lqistat2_print(regvalue, cur_col, wrap) \
663 ahd_print_register(NULL, 0, "LQISTAT2", 0x52, regvalue, cur_col, wrap)
664#endif
665
666#if AIC_DEBUG_REGISTERS
667ahd_reg_print_t ahd_sstat3_print;
668#else
669#define ahd_sstat3_print(regvalue, cur_col, wrap) \
670 ahd_print_register(NULL, 0, "SSTAT3", 0x53, regvalue, cur_col, wrap)
671#endif
672
673#if AIC_DEBUG_REGISTERS
674ahd_reg_print_t ahd_simode3_print;
675#else
676#define ahd_simode3_print(regvalue, cur_col, wrap) \
677 ahd_print_register(NULL, 0, "SIMODE3", 0x53, regvalue, cur_col, wrap)
678#endif
679
680#if AIC_DEBUG_REGISTERS
681ahd_reg_print_t ahd_clrsint3_print;
682#else
683#define ahd_clrsint3_print(regvalue, cur_col, wrap) \
684 ahd_print_register(NULL, 0, "CLRSINT3", 0x53, regvalue, cur_col, wrap)
685#endif
686
687#if AIC_DEBUG_REGISTERS
688ahd_reg_print_t ahd_lqomode0_print;
689#else
690#define ahd_lqomode0_print(regvalue, cur_col, wrap) \
691 ahd_print_register(NULL, 0, "LQOMODE0", 0x54, regvalue, cur_col, wrap)
692#endif
693
694#if AIC_DEBUG_REGISTERS
695ahd_reg_print_t ahd_lqostat0_print;
696#else
697#define ahd_lqostat0_print(regvalue, cur_col, wrap) \
698 ahd_print_register(NULL, 0, "LQOSTAT0", 0x54, regvalue, cur_col, wrap)
699#endif
700
701#if AIC_DEBUG_REGISTERS
702ahd_reg_print_t ahd_clrlqoint0_print;
703#else
704#define ahd_clrlqoint0_print(regvalue, cur_col, wrap) \
705 ahd_print_register(NULL, 0, "CLRLQOINT0", 0x54, regvalue, cur_col, wrap)
706#endif
707
708#if AIC_DEBUG_REGISTERS
709ahd_reg_print_t ahd_lqostat1_print;
710#else
711#define ahd_lqostat1_print(regvalue, cur_col, wrap) \
712 ahd_print_register(NULL, 0, "LQOSTAT1", 0x55, regvalue, cur_col, wrap)
713#endif
714
715#if AIC_DEBUG_REGISTERS
716ahd_reg_print_t ahd_clrlqoint1_print;
717#else
718#define ahd_clrlqoint1_print(regvalue, cur_col, wrap) \
719 ahd_print_register(NULL, 0, "CLRLQOINT1", 0x55, regvalue, cur_col, wrap)
720#endif
721
722#if AIC_DEBUG_REGISTERS
723ahd_reg_print_t ahd_lqomode1_print;
724#else
725#define ahd_lqomode1_print(regvalue, cur_col, wrap) \
726 ahd_print_register(NULL, 0, "LQOMODE1", 0x55, regvalue, cur_col, wrap)
727#endif
728
729#if AIC_DEBUG_REGISTERS
730ahd_reg_print_t ahd_lqostat2_print;
731#else
732#define ahd_lqostat2_print(regvalue, cur_col, wrap) \
733 ahd_print_register(NULL, 0, "LQOSTAT2", 0x56, regvalue, cur_col, wrap)
734#endif
735
736#if AIC_DEBUG_REGISTERS
737ahd_reg_print_t ahd_os_space_cnt_print;
738#else
739#define ahd_os_space_cnt_print(regvalue, cur_col, wrap) \
740 ahd_print_register(NULL, 0, "OS_SPACE_CNT", 0x56, regvalue, cur_col, wrap)
741#endif
742
743#if AIC_DEBUG_REGISTERS
744ahd_reg_print_t ahd_simode1_print;
745#else
746#define ahd_simode1_print(regvalue, cur_col, wrap) \
747 ahd_print_register(NULL, 0, "SIMODE1", 0x57, regvalue, cur_col, wrap)
748#endif
749
750#if AIC_DEBUG_REGISTERS
751ahd_reg_print_t ahd_gsfifo_print;
752#else
753#define ahd_gsfifo_print(regvalue, cur_col, wrap) \
754 ahd_print_register(NULL, 0, "GSFIFO", 0x58, regvalue, cur_col, wrap)
755#endif
756
757#if AIC_DEBUG_REGISTERS
758ahd_reg_print_t ahd_dffsxfrctl_print;
759#else
760#define ahd_dffsxfrctl_print(regvalue, cur_col, wrap) \
761 ahd_print_register(NULL, 0, "DFFSXFRCTL", 0x5a, regvalue, cur_col, wrap)
762#endif
763
764#if AIC_DEBUG_REGISTERS
765ahd_reg_print_t ahd_lqoscsctl_print;
766#else
767#define ahd_lqoscsctl_print(regvalue, cur_col, wrap) \
768 ahd_print_register(NULL, 0, "LQOSCSCTL", 0x5a, regvalue, cur_col, wrap)
769#endif
770
771#if AIC_DEBUG_REGISTERS
772ahd_reg_print_t ahd_nextscb_print;
773#else
774#define ahd_nextscb_print(regvalue, cur_col, wrap) \
775 ahd_print_register(NULL, 0, "NEXTSCB", 0x5a, regvalue, cur_col, wrap)
776#endif
777
778#if AIC_DEBUG_REGISTERS
779ahd_reg_print_t ahd_clrseqintsrc_print;
780#else
781#define ahd_clrseqintsrc_print(regvalue, cur_col, wrap) \
782 ahd_print_register(NULL, 0, "CLRSEQINTSRC", 0x5b, regvalue, cur_col, wrap)
783#endif
784
785#if AIC_DEBUG_REGISTERS
786ahd_reg_print_t ahd_seqintsrc_print;
787#else
788#define ahd_seqintsrc_print(regvalue, cur_col, wrap) \
789 ahd_print_register(NULL, 0, "SEQINTSRC", 0x5b, regvalue, cur_col, wrap)
790#endif
791
792#if AIC_DEBUG_REGISTERS
793ahd_reg_print_t ahd_currscb_print;
794#else
795#define ahd_currscb_print(regvalue, cur_col, wrap) \
796 ahd_print_register(NULL, 0, "CURRSCB", 0x5c, regvalue, cur_col, wrap)
797#endif
798
799#if AIC_DEBUG_REGISTERS
800ahd_reg_print_t ahd_seqimode_print;
801#else
802#define ahd_seqimode_print(regvalue, cur_col, wrap) \
803 ahd_print_register(NULL, 0, "SEQIMODE", 0x5c, regvalue, cur_col, wrap)
804#endif
805
806#if AIC_DEBUG_REGISTERS
807ahd_reg_print_t ahd_mdffstat_print;
808#else
809#define ahd_mdffstat_print(regvalue, cur_col, wrap) \
810 ahd_print_register(NULL, 0, "MDFFSTAT", 0x5d, regvalue, cur_col, wrap)
811#endif
812
813#if AIC_DEBUG_REGISTERS
814ahd_reg_print_t ahd_crccontrol_print;
815#else
816#define ahd_crccontrol_print(regvalue, cur_col, wrap) \
817 ahd_print_register(NULL, 0, "CRCCONTROL", 0x5d, regvalue, cur_col, wrap)
818#endif
819
820#if AIC_DEBUG_REGISTERS
821ahd_reg_print_t ahd_dfftag_print;
822#else
823#define ahd_dfftag_print(regvalue, cur_col, wrap) \
824 ahd_print_register(NULL, 0, "DFFTAG", 0x5e, regvalue, cur_col, wrap)
825#endif
826
827#if AIC_DEBUG_REGISTERS
828ahd_reg_print_t ahd_lastscb_print;
829#else
830#define ahd_lastscb_print(regvalue, cur_col, wrap) \
831 ahd_print_register(NULL, 0, "LASTSCB", 0x5e, regvalue, cur_col, wrap)
832#endif
833
834#if AIC_DEBUG_REGISTERS
835ahd_reg_print_t ahd_scsitest_print;
836#else
837#define ahd_scsitest_print(regvalue, cur_col, wrap) \
838 ahd_print_register(NULL, 0, "SCSITEST", 0x5e, regvalue, cur_col, wrap)
839#endif
840
841#if AIC_DEBUG_REGISTERS
842ahd_reg_print_t ahd_iopdnctl_print;
843#else
844#define ahd_iopdnctl_print(regvalue, cur_col, wrap) \
845 ahd_print_register(NULL, 0, "IOPDNCTL", 0x5f, regvalue, cur_col, wrap)
846#endif
847
848#if AIC_DEBUG_REGISTERS
849ahd_reg_print_t ahd_shaddr_print;
850#else
851#define ahd_shaddr_print(regvalue, cur_col, wrap) \
852 ahd_print_register(NULL, 0, "SHADDR", 0x60, regvalue, cur_col, wrap)
853#endif
854
855#if AIC_DEBUG_REGISTERS
856ahd_reg_print_t ahd_negoaddr_print;
857#else
858#define ahd_negoaddr_print(regvalue, cur_col, wrap) \
859 ahd_print_register(NULL, 0, "NEGOADDR", 0x60, regvalue, cur_col, wrap)
860#endif
861
862#if AIC_DEBUG_REGISTERS
863ahd_reg_print_t ahd_dgrpcrci_print;
864#else
865#define ahd_dgrpcrci_print(regvalue, cur_col, wrap) \
866 ahd_print_register(NULL, 0, "DGRPCRCI", 0x60, regvalue, cur_col, wrap)
867#endif
868
869#if AIC_DEBUG_REGISTERS
870ahd_reg_print_t ahd_negperiod_print;
871#else
872#define ahd_negperiod_print(regvalue, cur_col, wrap) \
873 ahd_print_register(NULL, 0, "NEGPERIOD", 0x61, regvalue, cur_col, wrap)
874#endif
875
876#if AIC_DEBUG_REGISTERS
877ahd_reg_print_t ahd_packcrci_print;
878#else
879#define ahd_packcrci_print(regvalue, cur_col, wrap) \
880 ahd_print_register(NULL, 0, "PACKCRCI", 0x62, regvalue, cur_col, wrap)
881#endif
882
883#if AIC_DEBUG_REGISTERS
884ahd_reg_print_t ahd_negoffset_print;
885#else
886#define ahd_negoffset_print(regvalue, cur_col, wrap) \
887 ahd_print_register(NULL, 0, "NEGOFFSET", 0x62, regvalue, cur_col, wrap)
888#endif
889
890#if AIC_DEBUG_REGISTERS
891ahd_reg_print_t ahd_negppropts_print;
892#else
893#define ahd_negppropts_print(regvalue, cur_col, wrap) \
894 ahd_print_register(NULL, 0, "NEGPPROPTS", 0x63, regvalue, cur_col, wrap)
895#endif
896
897#if AIC_DEBUG_REGISTERS
898ahd_reg_print_t ahd_negconopts_print;
899#else
900#define ahd_negconopts_print(regvalue, cur_col, wrap) \
901 ahd_print_register(NULL, 0, "NEGCONOPTS", 0x64, regvalue, cur_col, wrap)
902#endif
903
904#if AIC_DEBUG_REGISTERS
905ahd_reg_print_t ahd_annexcol_print;
906#else
907#define ahd_annexcol_print(regvalue, cur_col, wrap) \
908 ahd_print_register(NULL, 0, "ANNEXCOL", 0x65, regvalue, cur_col, wrap)
909#endif
910
911#if AIC_DEBUG_REGISTERS
912ahd_reg_print_t ahd_scschkn_print;
913#else
914#define ahd_scschkn_print(regvalue, cur_col, wrap) \
915 ahd_print_register(NULL, 0, "SCSCHKN", 0x66, regvalue, cur_col, wrap)
916#endif
917
918#if AIC_DEBUG_REGISTERS
919ahd_reg_print_t ahd_annexdat_print;
920#else
921#define ahd_annexdat_print(regvalue, cur_col, wrap) \
922 ahd_print_register(NULL, 0, "ANNEXDAT", 0x66, regvalue, cur_col, wrap)
923#endif
924
925#if AIC_DEBUG_REGISTERS
926ahd_reg_print_t ahd_iownid_print;
927#else
928#define ahd_iownid_print(regvalue, cur_col, wrap) \
929 ahd_print_register(NULL, 0, "IOWNID", 0x67, regvalue, cur_col, wrap)
930#endif
931
932#if AIC_DEBUG_REGISTERS
933ahd_reg_print_t ahd_pll960ctl0_print;
934#else
935#define ahd_pll960ctl0_print(regvalue, cur_col, wrap) \
936 ahd_print_register(NULL, 0, "PLL960CTL0", 0x68, regvalue, cur_col, wrap)
937#endif
938
939#if AIC_DEBUG_REGISTERS
940ahd_reg_print_t ahd_shcnt_print;
941#else
942#define ahd_shcnt_print(regvalue, cur_col, wrap) \
943 ahd_print_register(NULL, 0, "SHCNT", 0x68, regvalue, cur_col, wrap)
944#endif
945
946#if AIC_DEBUG_REGISTERS
947ahd_reg_print_t ahd_townid_print;
948#else
949#define ahd_townid_print(regvalue, cur_col, wrap) \
950 ahd_print_register(NULL, 0, "TOWNID", 0x69, regvalue, cur_col, wrap)
951#endif
952
953#if AIC_DEBUG_REGISTERS
954ahd_reg_print_t ahd_pll960ctl1_print;
955#else
956#define ahd_pll960ctl1_print(regvalue, cur_col, wrap) \
957 ahd_print_register(NULL, 0, "PLL960CTL1", 0x69, regvalue, cur_col, wrap)
958#endif
959
960#if AIC_DEBUG_REGISTERS
961ahd_reg_print_t ahd_pll960cnt0_print;
962#else
963#define ahd_pll960cnt0_print(regvalue, cur_col, wrap) \
964 ahd_print_register(NULL, 0, "PLL960CNT0", 0x6a, regvalue, cur_col, wrap)
965#endif
966
967#if AIC_DEBUG_REGISTERS
968ahd_reg_print_t ahd_xsig_print;
969#else
970#define ahd_xsig_print(regvalue, cur_col, wrap) \
971 ahd_print_register(NULL, 0, "XSIG", 0x6a, regvalue, cur_col, wrap)
972#endif
973
974#if AIC_DEBUG_REGISTERS
975ahd_reg_print_t ahd_seloid_print;
976#else
977#define ahd_seloid_print(regvalue, cur_col, wrap) \
978 ahd_print_register(NULL, 0, "SELOID", 0x6b, regvalue, cur_col, wrap)
979#endif
980
981#if AIC_DEBUG_REGISTERS
982ahd_reg_print_t ahd_pll400ctl0_print;
983#else
984#define ahd_pll400ctl0_print(regvalue, cur_col, wrap) \
985 ahd_print_register(NULL, 0, "PLL400CTL0", 0x6c, regvalue, cur_col, wrap)
986#endif
987
988#if AIC_DEBUG_REGISTERS
989ahd_reg_print_t ahd_fairness_print;
990#else
991#define ahd_fairness_print(regvalue, cur_col, wrap) \
992 ahd_print_register(NULL, 0, "FAIRNESS", 0x6c, regvalue, cur_col, wrap)
993#endif
994
995#if AIC_DEBUG_REGISTERS
996ahd_reg_print_t ahd_pll400ctl1_print;
997#else
998#define ahd_pll400ctl1_print(regvalue, cur_col, wrap) \
999 ahd_print_register(NULL, 0, "PLL400CTL1", 0x6d, regvalue, cur_col, wrap)
1000#endif
1001
1002#if AIC_DEBUG_REGISTERS
1003ahd_reg_print_t ahd_pll400cnt0_print;
1004#else
1005#define ahd_pll400cnt0_print(regvalue, cur_col, wrap) \
1006 ahd_print_register(NULL, 0, "PLL400CNT0", 0x6e, regvalue, cur_col, wrap)
1007#endif
1008
1009#if AIC_DEBUG_REGISTERS
1010ahd_reg_print_t ahd_unfairness_print;
1011#else
1012#define ahd_unfairness_print(regvalue, cur_col, wrap) \
1013 ahd_print_register(NULL, 0, "UNFAIRNESS", 0x6e, regvalue, cur_col, wrap)
1014#endif
1015
1016#if AIC_DEBUG_REGISTERS
1017ahd_reg_print_t ahd_haddr_print;
1018#else
1019#define ahd_haddr_print(regvalue, cur_col, wrap) \
1020 ahd_print_register(NULL, 0, "HADDR", 0x70, regvalue, cur_col, wrap)
1021#endif
1022
1023#if AIC_DEBUG_REGISTERS
1024ahd_reg_print_t ahd_plldelay_print;
1025#else
1026#define ahd_plldelay_print(regvalue, cur_col, wrap) \
1027 ahd_print_register(NULL, 0, "PLLDELAY", 0x70, regvalue, cur_col, wrap)
1028#endif
1029
1030#if AIC_DEBUG_REGISTERS
1031ahd_reg_print_t ahd_hodmaadr_print;
1032#else
1033#define ahd_hodmaadr_print(regvalue, cur_col, wrap) \
1034 ahd_print_register(NULL, 0, "HODMAADR", 0x70, regvalue, cur_col, wrap)
1035#endif
1036
1037#if AIC_DEBUG_REGISTERS
1038ahd_reg_print_t ahd_hodmacnt_print;
1039#else
1040#define ahd_hodmacnt_print(regvalue, cur_col, wrap) \
1041 ahd_print_register(NULL, 0, "HODMACNT", 0x78, regvalue, cur_col, wrap)
1042#endif
1043
1044#if AIC_DEBUG_REGISTERS
1045ahd_reg_print_t ahd_hcnt_print;
1046#else
1047#define ahd_hcnt_print(regvalue, cur_col, wrap) \
1048 ahd_print_register(NULL, 0, "HCNT", 0x78, regvalue, cur_col, wrap)
1049#endif
1050
1051#if AIC_DEBUG_REGISTERS
1052ahd_reg_print_t ahd_hodmaen_print;
1053#else
1054#define ahd_hodmaen_print(regvalue, cur_col, wrap) \
1055 ahd_print_register(NULL, 0, "HODMAEN", 0x7a, regvalue, cur_col, wrap)
1056#endif
1057
1058#if AIC_DEBUG_REGISTERS
1059ahd_reg_print_t ahd_sghaddr_print;
1060#else
1061#define ahd_sghaddr_print(regvalue, cur_col, wrap) \
1062 ahd_print_register(NULL, 0, "SGHADDR", 0x7c, regvalue, cur_col, wrap)
1063#endif
1064
1065#if AIC_DEBUG_REGISTERS
1066ahd_reg_print_t ahd_scbhaddr_print;
1067#else
1068#define ahd_scbhaddr_print(regvalue, cur_col, wrap) \
1069 ahd_print_register(NULL, 0, "SCBHADDR", 0x7c, regvalue, cur_col, wrap)
1070#endif
1071
1072#if AIC_DEBUG_REGISTERS
1073ahd_reg_print_t ahd_sghcnt_print;
1074#else
1075#define ahd_sghcnt_print(regvalue, cur_col, wrap) \
1076 ahd_print_register(NULL, 0, "SGHCNT", 0x84, regvalue, cur_col, wrap)
1077#endif
1078
1079#if AIC_DEBUG_REGISTERS
1080ahd_reg_print_t ahd_scbhcnt_print;
1081#else
1082#define ahd_scbhcnt_print(regvalue, cur_col, wrap) \
1083 ahd_print_register(NULL, 0, "SCBHCNT", 0x84, regvalue, cur_col, wrap)
1084#endif
1085
1086#if AIC_DEBUG_REGISTERS
1087ahd_reg_print_t ahd_dff_thrsh_print;
1088#else
1089#define ahd_dff_thrsh_print(regvalue, cur_col, wrap) \
1090 ahd_print_register(NULL, 0, "DFF_THRSH", 0x88, regvalue, cur_col, wrap)
1091#endif
1092
1093#if AIC_DEBUG_REGISTERS
1094ahd_reg_print_t ahd_romaddr_print;
1095#else
1096#define ahd_romaddr_print(regvalue, cur_col, wrap) \
1097 ahd_print_register(NULL, 0, "ROMADDR", 0x8a, regvalue, cur_col, wrap)
1098#endif
1099
1100#if AIC_DEBUG_REGISTERS
1101ahd_reg_print_t ahd_romcntrl_print;
1102#else
1103#define ahd_romcntrl_print(regvalue, cur_col, wrap) \
1104 ahd_print_register(NULL, 0, "ROMCNTRL", 0x8d, regvalue, cur_col, wrap)
1105#endif
1106
1107#if AIC_DEBUG_REGISTERS
1108ahd_reg_print_t ahd_romdata_print;
1109#else
1110#define ahd_romdata_print(regvalue, cur_col, wrap) \
1111 ahd_print_register(NULL, 0, "ROMDATA", 0x8e, regvalue, cur_col, wrap)
1112#endif
1113
1114#if AIC_DEBUG_REGISTERS
1115ahd_reg_print_t ahd_cmcrxmsg0_print;
1116#else
1117#define ahd_cmcrxmsg0_print(regvalue, cur_col, wrap) \
1118 ahd_print_register(NULL, 0, "CMCRXMSG0", 0x90, regvalue, cur_col, wrap)
1119#endif
1120
1121#if AIC_DEBUG_REGISTERS
1122ahd_reg_print_t ahd_roenable_print;
1123#else
1124#define ahd_roenable_print(regvalue, cur_col, wrap) \
1125 ahd_print_register(NULL, 0, "ROENABLE", 0x90, regvalue, cur_col, wrap)
1126#endif
1127
1128#if AIC_DEBUG_REGISTERS
1129ahd_reg_print_t ahd_ovlyrxmsg0_print;
1130#else
1131#define ahd_ovlyrxmsg0_print(regvalue, cur_col, wrap) \
1132 ahd_print_register(NULL, 0, "OVLYRXMSG0", 0x90, regvalue, cur_col, wrap)
1133#endif
1134
1135#if AIC_DEBUG_REGISTERS
1136ahd_reg_print_t ahd_dchrxmsg0_print;
1137#else
1138#define ahd_dchrxmsg0_print(regvalue, cur_col, wrap) \
1139 ahd_print_register(NULL, 0, "DCHRXMSG0", 0x90, regvalue, cur_col, wrap)
1140#endif
1141
1142#if AIC_DEBUG_REGISTERS
1143ahd_reg_print_t ahd_ovlyrxmsg1_print;
1144#else
1145#define ahd_ovlyrxmsg1_print(regvalue, cur_col, wrap) \
1146 ahd_print_register(NULL, 0, "OVLYRXMSG1", 0x91, regvalue, cur_col, wrap)
1147#endif
1148
1149#if AIC_DEBUG_REGISTERS
1150ahd_reg_print_t ahd_nsenable_print;
1151#else
1152#define ahd_nsenable_print(regvalue, cur_col, wrap) \
1153 ahd_print_register(NULL, 0, "NSENABLE", 0x91, regvalue, cur_col, wrap)
1154#endif
1155
1156#if AIC_DEBUG_REGISTERS
1157ahd_reg_print_t ahd_dchrxmsg1_print;
1158#else
1159#define ahd_dchrxmsg1_print(regvalue, cur_col, wrap) \
1160 ahd_print_register(NULL, 0, "DCHRXMSG1", 0x91, regvalue, cur_col, wrap)
1161#endif
1162
1163#if AIC_DEBUG_REGISTERS
1164ahd_reg_print_t ahd_cmcrxmsg1_print;
1165#else
1166#define ahd_cmcrxmsg1_print(regvalue, cur_col, wrap) \
1167 ahd_print_register(NULL, 0, "CMCRXMSG1", 0x91, regvalue, cur_col, wrap)
1168#endif
1169
1170#if AIC_DEBUG_REGISTERS
1171ahd_reg_print_t ahd_dchrxmsg2_print;
1172#else
1173#define ahd_dchrxmsg2_print(regvalue, cur_col, wrap) \
1174 ahd_print_register(NULL, 0, "DCHRXMSG2", 0x92, regvalue, cur_col, wrap)
1175#endif
1176
1177#if AIC_DEBUG_REGISTERS
1178ahd_reg_print_t ahd_ovlyrxmsg2_print;
1179#else
1180#define ahd_ovlyrxmsg2_print(regvalue, cur_col, wrap) \
1181 ahd_print_register(NULL, 0, "OVLYRXMSG2", 0x92, regvalue, cur_col, wrap)
1182#endif
1183
1184#if AIC_DEBUG_REGISTERS
1185ahd_reg_print_t ahd_cmcrxmsg2_print;
1186#else
1187#define ahd_cmcrxmsg2_print(regvalue, cur_col, wrap) \
1188 ahd_print_register(NULL, 0, "CMCRXMSG2", 0x92, regvalue, cur_col, wrap)
1189#endif
1190
1191#if AIC_DEBUG_REGISTERS
1192ahd_reg_print_t ahd_ost_print;
1193#else
1194#define ahd_ost_print(regvalue, cur_col, wrap) \
1195 ahd_print_register(NULL, 0, "OST", 0x92, regvalue, cur_col, wrap)
1196#endif
1197
1198#if AIC_DEBUG_REGISTERS
1199ahd_reg_print_t ahd_dchrxmsg3_print;
1200#else
1201#define ahd_dchrxmsg3_print(regvalue, cur_col, wrap) \
1202 ahd_print_register(NULL, 0, "DCHRXMSG3", 0x93, regvalue, cur_col, wrap)
1203#endif
1204
1205#if AIC_DEBUG_REGISTERS
1206ahd_reg_print_t ahd_cmcrxmsg3_print;
1207#else
1208#define ahd_cmcrxmsg3_print(regvalue, cur_col, wrap) \
1209 ahd_print_register(NULL, 0, "CMCRXMSG3", 0x93, regvalue, cur_col, wrap)
1210#endif
1211
1212#if AIC_DEBUG_REGISTERS
1213ahd_reg_print_t ahd_pcixctl_print;
1214#else
1215#define ahd_pcixctl_print(regvalue, cur_col, wrap) \
1216 ahd_print_register(NULL, 0, "PCIXCTL", 0x93, regvalue, cur_col, wrap)
1217#endif
1218
1219#if AIC_DEBUG_REGISTERS
1220ahd_reg_print_t ahd_ovlyrxmsg3_print;
1221#else
1222#define ahd_ovlyrxmsg3_print(regvalue, cur_col, wrap) \
1223 ahd_print_register(NULL, 0, "OVLYRXMSG3", 0x93, regvalue, cur_col, wrap)
1224#endif
1225
1226#if AIC_DEBUG_REGISTERS
1227ahd_reg_print_t ahd_ovlyseqbcnt_print;
1228#else
1229#define ahd_ovlyseqbcnt_print(regvalue, cur_col, wrap) \
1230 ahd_print_register(NULL, 0, "OVLYSEQBCNT", 0x94, regvalue, cur_col, wrap)
1231#endif
1232
1233#if AIC_DEBUG_REGISTERS
1234ahd_reg_print_t ahd_cmcseqbcnt_print;
1235#else
1236#define ahd_cmcseqbcnt_print(regvalue, cur_col, wrap) \
1237 ahd_print_register(NULL, 0, "CMCSEQBCNT", 0x94, regvalue, cur_col, wrap)
1238#endif
1239
1240#if AIC_DEBUG_REGISTERS
1241ahd_reg_print_t ahd_dchseqbcnt_print;
1242#else
1243#define ahd_dchseqbcnt_print(regvalue, cur_col, wrap) \
1244 ahd_print_register(NULL, 0, "DCHSEQBCNT", 0x94, regvalue, cur_col, wrap)
1245#endif
1246
1247#if AIC_DEBUG_REGISTERS
1248ahd_reg_print_t ahd_cmcspltstat0_print;
1249#else
1250#define ahd_cmcspltstat0_print(regvalue, cur_col, wrap) \
1251 ahd_print_register(NULL, 0, "CMCSPLTSTAT0", 0x96, regvalue, cur_col, wrap)
1252#endif
1253
1254#if AIC_DEBUG_REGISTERS
1255ahd_reg_print_t ahd_ovlyspltstat0_print;
1256#else
1257#define ahd_ovlyspltstat0_print(regvalue, cur_col, wrap) \
1258 ahd_print_register(NULL, 0, "OVLYSPLTSTAT0", 0x96, regvalue, cur_col, wrap)
1259#endif
1260
1261#if AIC_DEBUG_REGISTERS
1262ahd_reg_print_t ahd_dchspltstat0_print;
1263#else
1264#define ahd_dchspltstat0_print(regvalue, cur_col, wrap) \
1265 ahd_print_register(NULL, 0, "DCHSPLTSTAT0", 0x96, regvalue, cur_col, wrap)
1266#endif
1267
1268#if AIC_DEBUG_REGISTERS
1269ahd_reg_print_t ahd_dchspltstat1_print;
1270#else
1271#define ahd_dchspltstat1_print(regvalue, cur_col, wrap) \
1272 ahd_print_register(NULL, 0, "DCHSPLTSTAT1", 0x97, regvalue, cur_col, wrap)
1273#endif
1274
1275#if AIC_DEBUG_REGISTERS
1276ahd_reg_print_t ahd_cmcspltstat1_print;
1277#else
1278#define ahd_cmcspltstat1_print(regvalue, cur_col, wrap) \
1279 ahd_print_register(NULL, 0, "CMCSPLTSTAT1", 0x97, regvalue, cur_col, wrap)
1280#endif
1281
1282#if AIC_DEBUG_REGISTERS
1283ahd_reg_print_t ahd_ovlyspltstat1_print;
1284#else
1285#define ahd_ovlyspltstat1_print(regvalue, cur_col, wrap) \
1286 ahd_print_register(NULL, 0, "OVLYSPLTSTAT1", 0x97, regvalue, cur_col, wrap)
1287#endif
1288
1289#if AIC_DEBUG_REGISTERS
1290ahd_reg_print_t ahd_sgrxmsg0_print;
1291#else
1292#define ahd_sgrxmsg0_print(regvalue, cur_col, wrap) \
1293 ahd_print_register(NULL, 0, "SGRXMSG0", 0x98, regvalue, cur_col, wrap)
1294#endif
1295
1296#if AIC_DEBUG_REGISTERS
1297ahd_reg_print_t ahd_slvspltoutadr0_print;
1298#else
1299#define ahd_slvspltoutadr0_print(regvalue, cur_col, wrap) \
1300 ahd_print_register(NULL, 0, "SLVSPLTOUTADR0", 0x98, regvalue, cur_col, wrap)
1301#endif
1302
1303#if AIC_DEBUG_REGISTERS
1304ahd_reg_print_t ahd_sgrxmsg1_print;
1305#else
1306#define ahd_sgrxmsg1_print(regvalue, cur_col, wrap) \
1307 ahd_print_register(NULL, 0, "SGRXMSG1", 0x99, regvalue, cur_col, wrap)
1308#endif
1309
1310#if AIC_DEBUG_REGISTERS
1311ahd_reg_print_t ahd_slvspltoutadr1_print;
1312#else
1313#define ahd_slvspltoutadr1_print(regvalue, cur_col, wrap) \
1314 ahd_print_register(NULL, 0, "SLVSPLTOUTADR1", 0x99, regvalue, cur_col, wrap)
1315#endif
1316
1317#if AIC_DEBUG_REGISTERS
1318ahd_reg_print_t ahd_sgrxmsg2_print;
1319#else
1320#define ahd_sgrxmsg2_print(regvalue, cur_col, wrap) \
1321 ahd_print_register(NULL, 0, "SGRXMSG2", 0x9a, regvalue, cur_col, wrap)
1322#endif
1323
1324#if AIC_DEBUG_REGISTERS
1325ahd_reg_print_t ahd_slvspltoutadr2_print;
1326#else
1327#define ahd_slvspltoutadr2_print(regvalue, cur_col, wrap) \
1328 ahd_print_register(NULL, 0, "SLVSPLTOUTADR2", 0x9a, regvalue, cur_col, wrap)
1329#endif
1330
1331#if AIC_DEBUG_REGISTERS
1332ahd_reg_print_t ahd_sgrxmsg3_print;
1333#else
1334#define ahd_sgrxmsg3_print(regvalue, cur_col, wrap) \
1335 ahd_print_register(NULL, 0, "SGRXMSG3", 0x9b, regvalue, cur_col, wrap)
1336#endif
1337
1338#if AIC_DEBUG_REGISTERS
1339ahd_reg_print_t ahd_slvspltoutadr3_print;
1340#else
1341#define ahd_slvspltoutadr3_print(regvalue, cur_col, wrap) \
1342 ahd_print_register(NULL, 0, "SLVSPLTOUTADR3", 0x9b, regvalue, cur_col, wrap)
1343#endif
1344
1345#if AIC_DEBUG_REGISTERS
1346ahd_reg_print_t ahd_sgseqbcnt_print;
1347#else
1348#define ahd_sgseqbcnt_print(regvalue, cur_col, wrap) \
1349 ahd_print_register(NULL, 0, "SGSEQBCNT", 0x9c, regvalue, cur_col, wrap)
1350#endif
1351
1352#if AIC_DEBUG_REGISTERS
1353ahd_reg_print_t ahd_slvspltoutattr0_print;
1354#else
1355#define ahd_slvspltoutattr0_print(regvalue, cur_col, wrap) \
1356 ahd_print_register(NULL, 0, "SLVSPLTOUTATTR0", 0x9c, regvalue, cur_col, wrap)
1357#endif
1358
1359#if AIC_DEBUG_REGISTERS
1360ahd_reg_print_t ahd_slvspltoutattr1_print;
1361#else
1362#define ahd_slvspltoutattr1_print(regvalue, cur_col, wrap) \
1363 ahd_print_register(NULL, 0, "SLVSPLTOUTATTR1", 0x9d, regvalue, cur_col, wrap)
1364#endif
1365
1366#if AIC_DEBUG_REGISTERS
1367ahd_reg_print_t ahd_slvspltoutattr2_print;
1368#else
1369#define ahd_slvspltoutattr2_print(regvalue, cur_col, wrap) \
1370 ahd_print_register(NULL, 0, "SLVSPLTOUTATTR2", 0x9e, regvalue, cur_col, wrap)
1371#endif
1372
1373#if AIC_DEBUG_REGISTERS
1374ahd_reg_print_t ahd_sgspltstat0_print;
1375#else
1376#define ahd_sgspltstat0_print(regvalue, cur_col, wrap) \
1377 ahd_print_register(NULL, 0, "SGSPLTSTAT0", 0x9e, regvalue, cur_col, wrap)
1378#endif
1379
1380#if AIC_DEBUG_REGISTERS
1381ahd_reg_print_t ahd_sfunct_print;
1382#else
1383#define ahd_sfunct_print(regvalue, cur_col, wrap) \
1384 ahd_print_register(NULL, 0, "SFUNCT", 0x9f, regvalue, cur_col, wrap)
1385#endif
1386
1387#if AIC_DEBUG_REGISTERS
1388ahd_reg_print_t ahd_sgspltstat1_print;
1389#else
1390#define ahd_sgspltstat1_print(regvalue, cur_col, wrap) \
1391 ahd_print_register(NULL, 0, "SGSPLTSTAT1", 0x9f, regvalue, cur_col, wrap)
1392#endif
1393
1394#if AIC_DEBUG_REGISTERS
1395ahd_reg_print_t ahd_df0pcistat_print;
1396#else
1397#define ahd_df0pcistat_print(regvalue, cur_col, wrap) \
1398 ahd_print_register(NULL, 0, "DF0PCISTAT", 0xa0, regvalue, cur_col, wrap)
1399#endif
1400
1401#if AIC_DEBUG_REGISTERS
1402ahd_reg_print_t ahd_reg0_print;
1403#else
1404#define ahd_reg0_print(regvalue, cur_col, wrap) \
1405 ahd_print_register(NULL, 0, "REG0", 0xa0, regvalue, cur_col, wrap)
1406#endif
1407
1408#if AIC_DEBUG_REGISTERS
1409ahd_reg_print_t ahd_df1pcistat_print;
1410#else
1411#define ahd_df1pcistat_print(regvalue, cur_col, wrap) \
1412 ahd_print_register(NULL, 0, "DF1PCISTAT", 0xa1, regvalue, cur_col, wrap)
1413#endif
1414
1415#if AIC_DEBUG_REGISTERS
1416ahd_reg_print_t ahd_sgpcistat_print;
1417#else
1418#define ahd_sgpcistat_print(regvalue, cur_col, wrap) \
1419 ahd_print_register(NULL, 0, "SGPCISTAT", 0xa2, regvalue, cur_col, wrap)
1420#endif
1421
1422#if AIC_DEBUG_REGISTERS
1423ahd_reg_print_t ahd_reg1_print;
1424#else
1425#define ahd_reg1_print(regvalue, cur_col, wrap) \
1426 ahd_print_register(NULL, 0, "REG1", 0xa2, regvalue, cur_col, wrap)
1427#endif
1428
1429#if AIC_DEBUG_REGISTERS
1430ahd_reg_print_t ahd_cmcpcistat_print;
1431#else
1432#define ahd_cmcpcistat_print(regvalue, cur_col, wrap) \
1433 ahd_print_register(NULL, 0, "CMCPCISTAT", 0xa3, regvalue, cur_col, wrap)
1434#endif
1435
1436#if AIC_DEBUG_REGISTERS
1437ahd_reg_print_t ahd_ovlypcistat_print;
1438#else
1439#define ahd_ovlypcistat_print(regvalue, cur_col, wrap) \
1440 ahd_print_register(NULL, 0, "OVLYPCISTAT", 0xa4, regvalue, cur_col, wrap)
1441#endif
1442
1443#if AIC_DEBUG_REGISTERS
1444ahd_reg_print_t ahd_reg_isr_print;
1445#else
1446#define ahd_reg_isr_print(regvalue, cur_col, wrap) \
1447 ahd_print_register(NULL, 0, "REG_ISR", 0xa4, regvalue, cur_col, wrap)
1448#endif
1449
1450#if AIC_DEBUG_REGISTERS
1451ahd_reg_print_t ahd_sg_state_print;
1452#else
1453#define ahd_sg_state_print(regvalue, cur_col, wrap) \
1454 ahd_print_register(NULL, 0, "SG_STATE", 0xa6, regvalue, cur_col, wrap)
1455#endif
1456
1457#if AIC_DEBUG_REGISTERS
1458ahd_reg_print_t ahd_msipcistat_print;
1459#else
1460#define ahd_msipcistat_print(regvalue, cur_col, wrap) \
1461 ahd_print_register(NULL, 0, "MSIPCISTAT", 0xa6, regvalue, cur_col, wrap)
1462#endif
1463
1464#if AIC_DEBUG_REGISTERS
1465ahd_reg_print_t ahd_targpcistat_print;
1466#else
1467#define ahd_targpcistat_print(regvalue, cur_col, wrap) \
1468 ahd_print_register(NULL, 0, "TARGPCISTAT", 0xa7, regvalue, cur_col, wrap)
1469#endif
1470
1471#if AIC_DEBUG_REGISTERS
1472ahd_reg_print_t ahd_data_count_odd_print;
1473#else
1474#define ahd_data_count_odd_print(regvalue, cur_col, wrap) \
1475 ahd_print_register(NULL, 0, "DATA_COUNT_ODD", 0xa7, regvalue, cur_col, wrap)
1476#endif
1477
1478#if AIC_DEBUG_REGISTERS
1479ahd_reg_print_t ahd_scbptr_print;
1480#else
1481#define ahd_scbptr_print(regvalue, cur_col, wrap) \
1482 ahd_print_register(NULL, 0, "SCBPTR", 0xa8, regvalue, cur_col, wrap)
1483#endif
1484
1485#if AIC_DEBUG_REGISTERS
1486ahd_reg_print_t ahd_ccscbacnt_print;
1487#else
1488#define ahd_ccscbacnt_print(regvalue, cur_col, wrap) \
1489 ahd_print_register(NULL, 0, "CCSCBACNT", 0xab, regvalue, cur_col, wrap)
1490#endif
1491
1492#if AIC_DEBUG_REGISTERS
1493ahd_reg_print_t ahd_scbautoptr_print;
1494#else
1495#define ahd_scbautoptr_print(regvalue, cur_col, wrap) \
1496 ahd_print_register(NULL, 0, "SCBAUTOPTR", 0xab, regvalue, cur_col, wrap)
1497#endif
1498
1499#if AIC_DEBUG_REGISTERS
1500ahd_reg_print_t ahd_ccsgaddr_print;
1501#else
1502#define ahd_ccsgaddr_print(regvalue, cur_col, wrap) \
1503 ahd_print_register(NULL, 0, "CCSGADDR", 0xac, regvalue, cur_col, wrap)
1504#endif
1505
1506#if AIC_DEBUG_REGISTERS
1507ahd_reg_print_t ahd_ccscbaddr_print;
1508#else
1509#define ahd_ccscbaddr_print(regvalue, cur_col, wrap) \
1510 ahd_print_register(NULL, 0, "CCSCBADDR", 0xac, regvalue, cur_col, wrap)
1511#endif
1512
1513#if AIC_DEBUG_REGISTERS
1514ahd_reg_print_t ahd_ccscbadr_bk_print;
1515#else
1516#define ahd_ccscbadr_bk_print(regvalue, cur_col, wrap) \
1517 ahd_print_register(NULL, 0, "CCSCBADR_BK", 0xac, regvalue, cur_col, wrap)
1518#endif
1519
1520#if AIC_DEBUG_REGISTERS
1521ahd_reg_print_t ahd_cmc_rambist_print;
1522#else
1523#define ahd_cmc_rambist_print(regvalue, cur_col, wrap) \
1524 ahd_print_register(NULL, 0, "CMC_RAMBIST", 0xad, regvalue, cur_col, wrap)
1525#endif
1526
1527#if AIC_DEBUG_REGISTERS
1528ahd_reg_print_t ahd_ccsgctl_print;
1529#else
1530#define ahd_ccsgctl_print(regvalue, cur_col, wrap) \
1531 ahd_print_register(NULL, 0, "CCSGCTL", 0xad, regvalue, cur_col, wrap)
1532#endif
1533
1534#if AIC_DEBUG_REGISTERS
1535ahd_reg_print_t ahd_ccscbctl_print;
1536#else
1537#define ahd_ccscbctl_print(regvalue, cur_col, wrap) \
1538 ahd_print_register(NULL, 0, "CCSCBCTL", 0xad, regvalue, cur_col, wrap)
1539#endif
1540
1541#if AIC_DEBUG_REGISTERS
1542ahd_reg_print_t ahd_ccsgram_print;
1543#else
1544#define ahd_ccsgram_print(regvalue, cur_col, wrap) \
1545 ahd_print_register(NULL, 0, "CCSGRAM", 0xb0, regvalue, cur_col, wrap)
1546#endif
1547
1548#if AIC_DEBUG_REGISTERS
1549ahd_reg_print_t ahd_flexadr_print;
1550#else
1551#define ahd_flexadr_print(regvalue, cur_col, wrap) \
1552 ahd_print_register(NULL, 0, "FLEXADR", 0xb0, regvalue, cur_col, wrap)
1553#endif
1554
1555#if AIC_DEBUG_REGISTERS
1556ahd_reg_print_t ahd_ccscbram_print;
1557#else
1558#define ahd_ccscbram_print(regvalue, cur_col, wrap) \
1559 ahd_print_register(NULL, 0, "CCSCBRAM", 0xb0, regvalue, cur_col, wrap)
1560#endif
1561
1562#if AIC_DEBUG_REGISTERS
1563ahd_reg_print_t ahd_flexcnt_print;
1564#else
1565#define ahd_flexcnt_print(regvalue, cur_col, wrap) \
1566 ahd_print_register(NULL, 0, "FLEXCNT", 0xb3, regvalue, cur_col, wrap)
1567#endif
1568
1569#if AIC_DEBUG_REGISTERS
1570ahd_reg_print_t ahd_flexdmastat_print;
1571#else
1572#define ahd_flexdmastat_print(regvalue, cur_col, wrap) \
1573 ahd_print_register(NULL, 0, "FLEXDMASTAT", 0xb5, regvalue, cur_col, wrap)
1574#endif
1575
1576#if AIC_DEBUG_REGISTERS
1577ahd_reg_print_t ahd_flexdata_print;
1578#else
1579#define ahd_flexdata_print(regvalue, cur_col, wrap) \
1580 ahd_print_register(NULL, 0, "FLEXDATA", 0xb6, regvalue, cur_col, wrap)
1581#endif
1582
1583#if AIC_DEBUG_REGISTERS
1584ahd_reg_print_t ahd_brddat_print;
1585#else
1586#define ahd_brddat_print(regvalue, cur_col, wrap) \
1587 ahd_print_register(NULL, 0, "BRDDAT", 0xb8, regvalue, cur_col, wrap)
1588#endif
1589
1590#if AIC_DEBUG_REGISTERS
1591ahd_reg_print_t ahd_brdctl_print;
1592#else
1593#define ahd_brdctl_print(regvalue, cur_col, wrap) \
1594 ahd_print_register(NULL, 0, "BRDCTL", 0xb9, regvalue, cur_col, wrap)
1595#endif
1596
1597#if AIC_DEBUG_REGISTERS
1598ahd_reg_print_t ahd_seeadr_print;
1599#else
1600#define ahd_seeadr_print(regvalue, cur_col, wrap) \
1601 ahd_print_register(NULL, 0, "SEEADR", 0xba, regvalue, cur_col, wrap)
1602#endif
1603
1604#if AIC_DEBUG_REGISTERS
1605ahd_reg_print_t ahd_seedat_print;
1606#else
1607#define ahd_seedat_print(regvalue, cur_col, wrap) \
1608 ahd_print_register(NULL, 0, "SEEDAT", 0xbc, regvalue, cur_col, wrap)
1609#endif
1610
1611#if AIC_DEBUG_REGISTERS
1612ahd_reg_print_t ahd_seectl_print;
1613#else
1614#define ahd_seectl_print(regvalue, cur_col, wrap) \
1615 ahd_print_register(NULL, 0, "SEECTL", 0xbe, regvalue, cur_col, wrap)
1616#endif
1617
1618#if AIC_DEBUG_REGISTERS
1619ahd_reg_print_t ahd_seestat_print;
1620#else
1621#define ahd_seestat_print(regvalue, cur_col, wrap) \
1622 ahd_print_register(NULL, 0, "SEESTAT", 0xbe, regvalue, cur_col, wrap)
1623#endif
1624
1625#if AIC_DEBUG_REGISTERS
1626ahd_reg_print_t ahd_scbcnt_print;
1627#else
1628#define ahd_scbcnt_print(regvalue, cur_col, wrap) \
1629 ahd_print_register(NULL, 0, "SCBCNT", 0xbf, regvalue, cur_col, wrap)
1630#endif
1631
1632#if AIC_DEBUG_REGISTERS
1633ahd_reg_print_t ahd_dfwaddr_print;
1634#else
1635#define ahd_dfwaddr_print(regvalue, cur_col, wrap) \
1636 ahd_print_register(NULL, 0, "DFWADDR", 0xc0, regvalue, cur_col, wrap)
1637#endif
1638
1639#if AIC_DEBUG_REGISTERS
1640ahd_reg_print_t ahd_dspfltrctl_print;
1641#else
1642#define ahd_dspfltrctl_print(regvalue, cur_col, wrap) \
1643 ahd_print_register(NULL, 0, "DSPFLTRCTL", 0xc0, regvalue, cur_col, wrap)
1644#endif
1645
1646#if AIC_DEBUG_REGISTERS
1647ahd_reg_print_t ahd_dspdatactl_print;
1648#else
1649#define ahd_dspdatactl_print(regvalue, cur_col, wrap) \
1650 ahd_print_register(NULL, 0, "DSPDATACTL", 0xc1, regvalue, cur_col, wrap)
1651#endif
1652
1653#if AIC_DEBUG_REGISTERS
1654ahd_reg_print_t ahd_dfraddr_print;
1655#else
1656#define ahd_dfraddr_print(regvalue, cur_col, wrap) \
1657 ahd_print_register(NULL, 0, "DFRADDR", 0xc2, regvalue, cur_col, wrap)
1658#endif
1659
1660#if AIC_DEBUG_REGISTERS
1661ahd_reg_print_t ahd_dspreqctl_print;
1662#else
1663#define ahd_dspreqctl_print(regvalue, cur_col, wrap) \
1664 ahd_print_register(NULL, 0, "DSPREQCTL", 0xc2, regvalue, cur_col, wrap)
1665#endif
1666
1667#if AIC_DEBUG_REGISTERS
1668ahd_reg_print_t ahd_dspackctl_print;
1669#else
1670#define ahd_dspackctl_print(regvalue, cur_col, wrap) \
1671 ahd_print_register(NULL, 0, "DSPACKCTL", 0xc3, regvalue, cur_col, wrap)
1672#endif
1673
1674#if AIC_DEBUG_REGISTERS
1675ahd_reg_print_t ahd_dfdat_print;
1676#else
1677#define ahd_dfdat_print(regvalue, cur_col, wrap) \
1678 ahd_print_register(NULL, 0, "DFDAT", 0xc4, regvalue, cur_col, wrap)
1679#endif
1680
1681#if AIC_DEBUG_REGISTERS
1682ahd_reg_print_t ahd_dspselect_print;
1683#else
1684#define ahd_dspselect_print(regvalue, cur_col, wrap) \
1685 ahd_print_register(NULL, 0, "DSPSELECT", 0xc4, regvalue, cur_col, wrap)
1686#endif
1687
1688#if AIC_DEBUG_REGISTERS
1689ahd_reg_print_t ahd_wrtbiasctl_print;
1690#else
1691#define ahd_wrtbiasctl_print(regvalue, cur_col, wrap) \
1692 ahd_print_register(NULL, 0, "WRTBIASCTL", 0xc5, regvalue, cur_col, wrap)
1693#endif
1694
1695#if AIC_DEBUG_REGISTERS
1696ahd_reg_print_t ahd_rcvrbiosctl_print;
1697#else
1698#define ahd_rcvrbiosctl_print(regvalue, cur_col, wrap) \
1699 ahd_print_register(NULL, 0, "RCVRBIOSCTL", 0xc6, regvalue, cur_col, wrap)
1700#endif
1701
1702#if AIC_DEBUG_REGISTERS
1703ahd_reg_print_t ahd_wrtbiascalc_print;
1704#else
1705#define ahd_wrtbiascalc_print(regvalue, cur_col, wrap) \
1706 ahd_print_register(NULL, 0, "WRTBIASCALC", 0xc7, regvalue, cur_col, wrap)
1707#endif
1708
1709#if AIC_DEBUG_REGISTERS
1710ahd_reg_print_t ahd_dfptrs_print;
1711#else
1712#define ahd_dfptrs_print(regvalue, cur_col, wrap) \
1713 ahd_print_register(NULL, 0, "DFPTRS", 0xc8, regvalue, cur_col, wrap)
1714#endif
1715
1716#if AIC_DEBUG_REGISTERS
1717ahd_reg_print_t ahd_rcvrbiascalc_print;
1718#else
1719#define ahd_rcvrbiascalc_print(regvalue, cur_col, wrap) \
1720 ahd_print_register(NULL, 0, "RCVRBIASCALC", 0xc8, regvalue, cur_col, wrap)
1721#endif
1722
1723#if AIC_DEBUG_REGISTERS
1724ahd_reg_print_t ahd_dfbkptr_print;
1725#else
1726#define ahd_dfbkptr_print(regvalue, cur_col, wrap) \
1727 ahd_print_register(NULL, 0, "DFBKPTR", 0xc9, regvalue, cur_col, wrap)
1728#endif
1729
1730#if AIC_DEBUG_REGISTERS
1731ahd_reg_print_t ahd_skewcalc_print;
1732#else
1733#define ahd_skewcalc_print(regvalue, cur_col, wrap) \
1734 ahd_print_register(NULL, 0, "SKEWCALC", 0xc9, regvalue, cur_col, wrap)
1735#endif
1736
1737#if AIC_DEBUG_REGISTERS
1738ahd_reg_print_t ahd_dfdbctl_print;
1739#else
1740#define ahd_dfdbctl_print(regvalue, cur_col, wrap) \
1741 ahd_print_register(NULL, 0, "DFDBCTL", 0xcb, regvalue, cur_col, wrap)
1742#endif
1743
1744#if AIC_DEBUG_REGISTERS
1745ahd_reg_print_t ahd_dfscnt_print;
1746#else
1747#define ahd_dfscnt_print(regvalue, cur_col, wrap) \
1748 ahd_print_register(NULL, 0, "DFSCNT", 0xcc, regvalue, cur_col, wrap)
1749#endif
1750
1751#if AIC_DEBUG_REGISTERS
1752ahd_reg_print_t ahd_dfbcnt_print;
1753#else
1754#define ahd_dfbcnt_print(regvalue, cur_col, wrap) \
1755 ahd_print_register(NULL, 0, "DFBCNT", 0xce, regvalue, cur_col, wrap)
1756#endif
1757
1758#if AIC_DEBUG_REGISTERS
1759ahd_reg_print_t ahd_ovlyaddr_print;
1760#else
1761#define ahd_ovlyaddr_print(regvalue, cur_col, wrap) \
1762 ahd_print_register(NULL, 0, "OVLYADDR", 0xd4, regvalue, cur_col, wrap)
1763#endif
1764
1765#if AIC_DEBUG_REGISTERS
1766ahd_reg_print_t ahd_seqctl0_print;
1767#else
1768#define ahd_seqctl0_print(regvalue, cur_col, wrap) \
1769 ahd_print_register(NULL, 0, "SEQCTL0", 0xd6, regvalue, cur_col, wrap)
1770#endif
1771
1772#if AIC_DEBUG_REGISTERS
1773ahd_reg_print_t ahd_seqctl1_print;
1774#else
1775#define ahd_seqctl1_print(regvalue, cur_col, wrap) \
1776 ahd_print_register(NULL, 0, "SEQCTL1", 0xd7, regvalue, cur_col, wrap)
1777#endif
1778
1779#if AIC_DEBUG_REGISTERS
1780ahd_reg_print_t ahd_flags_print;
1781#else
1782#define ahd_flags_print(regvalue, cur_col, wrap) \
1783 ahd_print_register(NULL, 0, "FLAGS", 0xd8, regvalue, cur_col, wrap)
1784#endif
1785
1786#if AIC_DEBUG_REGISTERS
1787ahd_reg_print_t ahd_seqintctl_print;
1788#else
1789#define ahd_seqintctl_print(regvalue, cur_col, wrap) \
1790 ahd_print_register(NULL, 0, "SEQINTCTL", 0xd9, regvalue, cur_col, wrap)
1791#endif
1792
1793#if AIC_DEBUG_REGISTERS
1794ahd_reg_print_t ahd_seqram_print;
1795#else
1796#define ahd_seqram_print(regvalue, cur_col, wrap) \
1797 ahd_print_register(NULL, 0, "SEQRAM", 0xda, regvalue, cur_col, wrap)
1798#endif
1799
1800#if AIC_DEBUG_REGISTERS
1801ahd_reg_print_t ahd_prgmcnt_print;
1802#else
1803#define ahd_prgmcnt_print(regvalue, cur_col, wrap) \
1804 ahd_print_register(NULL, 0, "PRGMCNT", 0xde, regvalue, cur_col, wrap)
1805#endif
1806
1807#if AIC_DEBUG_REGISTERS
1808ahd_reg_print_t ahd_accum_print;
1809#else
1810#define ahd_accum_print(regvalue, cur_col, wrap) \
1811 ahd_print_register(NULL, 0, "ACCUM", 0xe0, regvalue, cur_col, wrap)
1812#endif
1813
1814#if AIC_DEBUG_REGISTERS
1815ahd_reg_print_t ahd_sindex_print;
1816#else
1817#define ahd_sindex_print(regvalue, cur_col, wrap) \
1818 ahd_print_register(NULL, 0, "SINDEX", 0xe2, regvalue, cur_col, wrap)
1819#endif
1820
1821#if AIC_DEBUG_REGISTERS
1822ahd_reg_print_t ahd_dindex_print;
1823#else
1824#define ahd_dindex_print(regvalue, cur_col, wrap) \
1825 ahd_print_register(NULL, 0, "DINDEX", 0xe4, regvalue, cur_col, wrap)
1826#endif
1827
1828#if AIC_DEBUG_REGISTERS
1829ahd_reg_print_t ahd_brkaddr1_print;
1830#else
1831#define ahd_brkaddr1_print(regvalue, cur_col, wrap) \
1832 ahd_print_register(NULL, 0, "BRKADDR1", 0xe6, regvalue, cur_col, wrap)
1833#endif
1834
1835#if AIC_DEBUG_REGISTERS
1836ahd_reg_print_t ahd_brkaddr0_print;
1837#else
1838#define ahd_brkaddr0_print(regvalue, cur_col, wrap) \
1839 ahd_print_register(NULL, 0, "BRKADDR0", 0xe6, regvalue, cur_col, wrap)
1840#endif
1841
1842#if AIC_DEBUG_REGISTERS
1843ahd_reg_print_t ahd_allones_print;
1844#else
1845#define ahd_allones_print(regvalue, cur_col, wrap) \
1846 ahd_print_register(NULL, 0, "ALLONES", 0xe8, regvalue, cur_col, wrap)
1847#endif
1848
1849#if AIC_DEBUG_REGISTERS
1850ahd_reg_print_t ahd_allzeros_print;
1851#else
1852#define ahd_allzeros_print(regvalue, cur_col, wrap) \
1853 ahd_print_register(NULL, 0, "ALLZEROS", 0xea, regvalue, cur_col, wrap)
1854#endif
1855
1856#if AIC_DEBUG_REGISTERS
1857ahd_reg_print_t ahd_none_print;
1858#else
1859#define ahd_none_print(regvalue, cur_col, wrap) \
1860 ahd_print_register(NULL, 0, "NONE", 0xea, regvalue, cur_col, wrap)
1861#endif
1862
1863#if AIC_DEBUG_REGISTERS
1864ahd_reg_print_t ahd_sindir_print;
1865#else
1866#define ahd_sindir_print(regvalue, cur_col, wrap) \
1867 ahd_print_register(NULL, 0, "SINDIR", 0xec, regvalue, cur_col, wrap)
1868#endif
1869
1870#if AIC_DEBUG_REGISTERS
1871ahd_reg_print_t ahd_dindir_print;
1872#else
1873#define ahd_dindir_print(regvalue, cur_col, wrap) \
1874 ahd_print_register(NULL, 0, "DINDIR", 0xed, regvalue, cur_col, wrap)
1875#endif
1876
1877#if AIC_DEBUG_REGISTERS
1878ahd_reg_print_t ahd_function1_print;
1879#else
1880#define ahd_function1_print(regvalue, cur_col, wrap) \
1881 ahd_print_register(NULL, 0, "FUNCTION1", 0xf0, regvalue, cur_col, wrap)
1882#endif
1883
1884#if AIC_DEBUG_REGISTERS
1885ahd_reg_print_t ahd_stack_print;
1886#else
1887#define ahd_stack_print(regvalue, cur_col, wrap) \
1888 ahd_print_register(NULL, 0, "STACK", 0xf2, regvalue, cur_col, wrap)
1889#endif
1890
1891#if AIC_DEBUG_REGISTERS
1892ahd_reg_print_t ahd_curaddr_print;
1893#else
1894#define ahd_curaddr_print(regvalue, cur_col, wrap) \
1895 ahd_print_register(NULL, 0, "CURADDR", 0xf4, regvalue, cur_col, wrap)
1896#endif
1897
1898#if AIC_DEBUG_REGISTERS
1899ahd_reg_print_t ahd_intvec1_addr_print;
1900#else
1901#define ahd_intvec1_addr_print(regvalue, cur_col, wrap) \
1902 ahd_print_register(NULL, 0, "INTVEC1_ADDR", 0xf4, regvalue, cur_col, wrap)
1903#endif
1904
1905#if AIC_DEBUG_REGISTERS
1906ahd_reg_print_t ahd_intvec2_addr_print;
1907#else
1908#define ahd_intvec2_addr_print(regvalue, cur_col, wrap) \
1909 ahd_print_register(NULL, 0, "INTVEC2_ADDR", 0xf6, regvalue, cur_col, wrap)
1910#endif
1911
1912#if AIC_DEBUG_REGISTERS
1913ahd_reg_print_t ahd_lastaddr_print;
1914#else
1915#define ahd_lastaddr_print(regvalue, cur_col, wrap) \
1916 ahd_print_register(NULL, 0, "LASTADDR", 0xf6, regvalue, cur_col, wrap)
1917#endif
1918
1919#if AIC_DEBUG_REGISTERS
1920ahd_reg_print_t ahd_longjmp_addr_print;
1921#else
1922#define ahd_longjmp_addr_print(regvalue, cur_col, wrap) \
1923 ahd_print_register(NULL, 0, "LONGJMP_ADDR", 0xf8, regvalue, cur_col, wrap)
1924#endif
1925
1926#if AIC_DEBUG_REGISTERS
1927ahd_reg_print_t ahd_accum_save_print;
1928#else
1929#define ahd_accum_save_print(regvalue, cur_col, wrap) \
1930 ahd_print_register(NULL, 0, "ACCUM_SAVE", 0xfa, regvalue, cur_col, wrap)
1931#endif
1932
1933#if AIC_DEBUG_REGISTERS
1934ahd_reg_print_t ahd_waiting_scb_tails_print;
1935#else
1936#define ahd_waiting_scb_tails_print(regvalue, cur_col, wrap) \
1937 ahd_print_register(NULL, 0, "WAITING_SCB_TAILS", 0x100, regvalue, cur_col, wrap)
1938#endif
1939
1940#if AIC_DEBUG_REGISTERS
1941ahd_reg_print_t ahd_ahd_pci_config_base_print;
1942#else
1943#define ahd_ahd_pci_config_base_print(regvalue, cur_col, wrap) \
1944 ahd_print_register(NULL, 0, "AHD_PCI_CONFIG_BASE", 0x100, regvalue, cur_col, wrap)
1945#endif
1946
1947#if AIC_DEBUG_REGISTERS
1948ahd_reg_print_t ahd_sram_base_print;
1949#else
1950#define ahd_sram_base_print(regvalue, cur_col, wrap) \
1951 ahd_print_register(NULL, 0, "SRAM_BASE", 0x100, regvalue, cur_col, wrap)
1952#endif
1953
1954#if AIC_DEBUG_REGISTERS
1955ahd_reg_print_t ahd_waiting_tid_head_print;
1956#else
1957#define ahd_waiting_tid_head_print(regvalue, cur_col, wrap) \
1958 ahd_print_register(NULL, 0, "WAITING_TID_HEAD", 0x120, regvalue, cur_col, wrap)
1959#endif
1960
1961#if AIC_DEBUG_REGISTERS
1962ahd_reg_print_t ahd_waiting_tid_tail_print;
1963#else
1964#define ahd_waiting_tid_tail_print(regvalue, cur_col, wrap) \
1965 ahd_print_register(NULL, 0, "WAITING_TID_TAIL", 0x122, regvalue, cur_col, wrap)
1966#endif
1967
1968#if AIC_DEBUG_REGISTERS
1969ahd_reg_print_t ahd_next_queued_scb_addr_print;
1970#else
1971#define ahd_next_queued_scb_addr_print(regvalue, cur_col, wrap) \
1972 ahd_print_register(NULL, 0, "NEXT_QUEUED_SCB_ADDR", 0x124, regvalue, cur_col, wrap)
1973#endif
1974
1975#if AIC_DEBUG_REGISTERS
1976ahd_reg_print_t ahd_complete_scb_head_print;
1977#else
1978#define ahd_complete_scb_head_print(regvalue, cur_col, wrap) \
1979 ahd_print_register(NULL, 0, "COMPLETE_SCB_HEAD", 0x128, regvalue, cur_col, wrap)
1980#endif
1981
1982#if AIC_DEBUG_REGISTERS
1983ahd_reg_print_t ahd_complete_scb_dmainprog_head_print;
1984#else
1985#define ahd_complete_scb_dmainprog_head_print(regvalue, cur_col, wrap) \
1986 ahd_print_register(NULL, 0, "COMPLETE_SCB_DMAINPROG_HEAD", 0x12a, regvalue, cur_col, wrap)
1987#endif
1988
1989#if AIC_DEBUG_REGISTERS
1990ahd_reg_print_t ahd_complete_dma_scb_head_print;
1991#else
1992#define ahd_complete_dma_scb_head_print(regvalue, cur_col, wrap) \
1993 ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_HEAD", 0x12c, regvalue, cur_col, wrap)
1994#endif
1995
1996#if AIC_DEBUG_REGISTERS
1997ahd_reg_print_t ahd_qfreeze_count_print;
1998#else
1999#define ahd_qfreeze_count_print(regvalue, cur_col, wrap) \
2000 ahd_print_register(NULL, 0, "QFREEZE_COUNT", 0x12e, regvalue, cur_col, wrap)
2001#endif
2002
2003#if AIC_DEBUG_REGISTERS
2004ahd_reg_print_t ahd_saved_mode_print;
2005#else
2006#define ahd_saved_mode_print(regvalue, cur_col, wrap) \
2007 ahd_print_register(NULL, 0, "SAVED_MODE", 0x130, regvalue, cur_col, wrap)
2008#endif
2009
2010#if AIC_DEBUG_REGISTERS
2011ahd_reg_print_t ahd_msg_out_print;
2012#else
2013#define ahd_msg_out_print(regvalue, cur_col, wrap) \
2014 ahd_print_register(NULL, 0, "MSG_OUT", 0x131, regvalue, cur_col, wrap)
2015#endif
2016
2017#if AIC_DEBUG_REGISTERS
2018ahd_reg_print_t ahd_dmaparams_print;
2019#else
2020#define ahd_dmaparams_print(regvalue, cur_col, wrap) \
2021 ahd_print_register(NULL, 0, "DMAPARAMS", 0x132, regvalue, cur_col, wrap)
2022#endif
2023
2024#if AIC_DEBUG_REGISTERS
2025ahd_reg_print_t ahd_seq_flags_print;
2026#else
2027#define ahd_seq_flags_print(regvalue, cur_col, wrap) \
2028 ahd_print_register(NULL, 0, "SEQ_FLAGS", 0x133, regvalue, cur_col, wrap)
2029#endif
2030
2031#if AIC_DEBUG_REGISTERS
2032ahd_reg_print_t ahd_saved_scsiid_print;
2033#else
2034#define ahd_saved_scsiid_print(regvalue, cur_col, wrap) \
2035 ahd_print_register(NULL, 0, "SAVED_SCSIID", 0x134, regvalue, cur_col, wrap)
2036#endif
2037
2038#if AIC_DEBUG_REGISTERS
2039ahd_reg_print_t ahd_saved_lun_print;
2040#else
2041#define ahd_saved_lun_print(regvalue, cur_col, wrap) \
2042 ahd_print_register(NULL, 0, "SAVED_LUN", 0x135, regvalue, cur_col, wrap)
2043#endif
2044
2045#if AIC_DEBUG_REGISTERS
2046ahd_reg_print_t ahd_lastphase_print;
2047#else
2048#define ahd_lastphase_print(regvalue, cur_col, wrap) \
2049 ahd_print_register(NULL, 0, "LASTPHASE", 0x136, regvalue, cur_col, wrap)
2050#endif
2051
2052#if AIC_DEBUG_REGISTERS
2053ahd_reg_print_t ahd_qoutfifo_entry_valid_tag_print;
2054#else
2055#define ahd_qoutfifo_entry_valid_tag_print(regvalue, cur_col, wrap) \
2056 ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG", 0x137, regvalue, cur_col, wrap)
2057#endif
2058
2059#if AIC_DEBUG_REGISTERS
2060ahd_reg_print_t ahd_shared_data_addr_print;
2061#else
2062#define ahd_shared_data_addr_print(regvalue, cur_col, wrap) \
2063 ahd_print_register(NULL, 0, "SHARED_DATA_ADDR", 0x138, regvalue, cur_col, wrap)
2064#endif
2065
2066#if AIC_DEBUG_REGISTERS
2067ahd_reg_print_t ahd_qoutfifo_next_addr_print;
2068#else
2069#define ahd_qoutfifo_next_addr_print(regvalue, cur_col, wrap) \
2070 ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR", 0x13c, regvalue, cur_col, wrap)
2071#endif
2072
2073#if AIC_DEBUG_REGISTERS
2074ahd_reg_print_t ahd_kernel_tqinpos_print;
2075#else
2076#define ahd_kernel_tqinpos_print(regvalue, cur_col, wrap) \
2077 ahd_print_register(NULL, 0, "KERNEL_TQINPOS", 0x140, regvalue, cur_col, wrap)
2078#endif
2079
2080#if AIC_DEBUG_REGISTERS
2081ahd_reg_print_t ahd_tqinpos_print;
2082#else
2083#define ahd_tqinpos_print(regvalue, cur_col, wrap) \
2084 ahd_print_register(NULL, 0, "TQINPOS", 0x141, regvalue, cur_col, wrap)
2085#endif
2086
2087#if AIC_DEBUG_REGISTERS
2088ahd_reg_print_t ahd_arg_1_print;
2089#else
2090#define ahd_arg_1_print(regvalue, cur_col, wrap) \
2091 ahd_print_register(NULL, 0, "ARG_1", 0x142, regvalue, cur_col, wrap)
2092#endif
2093
2094#if AIC_DEBUG_REGISTERS
2095ahd_reg_print_t ahd_arg_2_print;
2096#else
2097#define ahd_arg_2_print(regvalue, cur_col, wrap) \
2098 ahd_print_register(NULL, 0, "ARG_2", 0x143, regvalue, cur_col, wrap)
2099#endif
2100
2101#if AIC_DEBUG_REGISTERS
2102ahd_reg_print_t ahd_last_msg_print;
2103#else
2104#define ahd_last_msg_print(regvalue, cur_col, wrap) \
2105 ahd_print_register(NULL, 0, "LAST_MSG", 0x144, regvalue, cur_col, wrap)
2106#endif
2107
2108#if AIC_DEBUG_REGISTERS
2109ahd_reg_print_t ahd_scsiseq_template_print;
2110#else
2111#define ahd_scsiseq_template_print(regvalue, cur_col, wrap) \
2112 ahd_print_register(NULL, 0, "SCSISEQ_TEMPLATE", 0x145, regvalue, cur_col, wrap)
2113#endif
2114
2115#if AIC_DEBUG_REGISTERS
2116ahd_reg_print_t ahd_initiator_tag_print;
2117#else
2118#define ahd_initiator_tag_print(regvalue, cur_col, wrap) \
2119 ahd_print_register(NULL, 0, "INITIATOR_TAG", 0x146, regvalue, cur_col, wrap)
2120#endif
2121
2122#if AIC_DEBUG_REGISTERS
2123ahd_reg_print_t ahd_seq_flags2_print;
2124#else
2125#define ahd_seq_flags2_print(regvalue, cur_col, wrap) \
2126 ahd_print_register(NULL, 0, "SEQ_FLAGS2", 0x147, regvalue, cur_col, wrap)
2127#endif
2128
2129#if AIC_DEBUG_REGISTERS
2130ahd_reg_print_t ahd_allocfifo_scbptr_print;
2131#else
2132#define ahd_allocfifo_scbptr_print(regvalue, cur_col, wrap) \
2133 ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR", 0x148, regvalue, cur_col, wrap)
2134#endif
2135
2136#if AIC_DEBUG_REGISTERS
2137ahd_reg_print_t ahd_int_coalescing_timer_print;
2138#else
2139#define ahd_int_coalescing_timer_print(regvalue, cur_col, wrap) \
2140 ahd_print_register(NULL, 0, "INT_COALESCING_TIMER", 0x14a, regvalue, cur_col, wrap)
2141#endif
2142
2143#if AIC_DEBUG_REGISTERS
2144ahd_reg_print_t ahd_int_coalescing_maxcmds_print;
2145#else
2146#define ahd_int_coalescing_maxcmds_print(regvalue, cur_col, wrap) \
2147 ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS", 0x14c, regvalue, cur_col, wrap)
2148#endif
2149
2150#if AIC_DEBUG_REGISTERS
2151ahd_reg_print_t ahd_int_coalescing_mincmds_print;
2152#else
2153#define ahd_int_coalescing_mincmds_print(regvalue, cur_col, wrap) \
2154 ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS", 0x14d, regvalue, cur_col, wrap)
2155#endif
2156
2157#if AIC_DEBUG_REGISTERS
2158ahd_reg_print_t ahd_cmds_pending_print;
2159#else
2160#define ahd_cmds_pending_print(regvalue, cur_col, wrap) \
2161 ahd_print_register(NULL, 0, "CMDS_PENDING", 0x14e, regvalue, cur_col, wrap)
2162#endif
2163
2164#if AIC_DEBUG_REGISTERS
2165ahd_reg_print_t ahd_int_coalescing_cmdcount_print;
2166#else
2167#define ahd_int_coalescing_cmdcount_print(regvalue, cur_col, wrap) \
2168 ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT", 0x150, regvalue, cur_col, wrap)
2169#endif
2170
2171#if AIC_DEBUG_REGISTERS
2172ahd_reg_print_t ahd_local_hs_mailbox_print;
2173#else
2174#define ahd_local_hs_mailbox_print(regvalue, cur_col, wrap) \
2175 ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX", 0x151, regvalue, cur_col, wrap)
2176#endif
2177
2178#if AIC_DEBUG_REGISTERS
2179ahd_reg_print_t ahd_cmdsize_table_print;
2180#else
2181#define ahd_cmdsize_table_print(regvalue, cur_col, wrap) \
2182 ahd_print_register(NULL, 0, "CMDSIZE_TABLE", 0x152, regvalue, cur_col, wrap)
2183#endif
2184
2185#if AIC_DEBUG_REGISTERS
2186ahd_reg_print_t ahd_scb_base_print;
2187#else
2188#define ahd_scb_base_print(regvalue, cur_col, wrap) \
2189 ahd_print_register(NULL, 0, "SCB_BASE", 0x180, regvalue, cur_col, wrap)
2190#endif
2191
2192#if AIC_DEBUG_REGISTERS
2193ahd_reg_print_t ahd_scb_residual_datacnt_print;
2194#else
2195#define ahd_scb_residual_datacnt_print(regvalue, cur_col, wrap) \
2196 ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT", 0x180, regvalue, cur_col, wrap)
2197#endif
2198
2199#if AIC_DEBUG_REGISTERS
2200ahd_reg_print_t ahd_scb_residual_sgptr_print;
2201#else
2202#define ahd_scb_residual_sgptr_print(regvalue, cur_col, wrap) \
2203 ahd_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", 0x184, regvalue, cur_col, wrap)
2204#endif
2205
2206#if AIC_DEBUG_REGISTERS
2207ahd_reg_print_t ahd_scb_scsi_status_print;
2208#else
2209#define ahd_scb_scsi_status_print(regvalue, cur_col, wrap) \
2210 ahd_print_register(NULL, 0, "SCB_SCSI_STATUS", 0x188, regvalue, cur_col, wrap)
2211#endif
2212
2213#if AIC_DEBUG_REGISTERS
2214ahd_reg_print_t ahd_scb_target_phases_print;
2215#else
2216#define ahd_scb_target_phases_print(regvalue, cur_col, wrap) \
2217 ahd_print_register(NULL, 0, "SCB_TARGET_PHASES", 0x189, regvalue, cur_col, wrap)
2218#endif
2219
2220#if AIC_DEBUG_REGISTERS
2221ahd_reg_print_t ahd_scb_target_data_dir_print;
2222#else
2223#define ahd_scb_target_data_dir_print(regvalue, cur_col, wrap) \
2224 ahd_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", 0x18a, regvalue, cur_col, wrap)
2225#endif
2226
2227#if AIC_DEBUG_REGISTERS
2228ahd_reg_print_t ahd_scb_target_itag_print;
2229#else
2230#define ahd_scb_target_itag_print(regvalue, cur_col, wrap) \
2231 ahd_print_register(NULL, 0, "SCB_TARGET_ITAG", 0x18b, regvalue, cur_col, wrap)
2232#endif
2233
2234#if AIC_DEBUG_REGISTERS
2235ahd_reg_print_t ahd_scb_sense_busaddr_print;
2236#else
2237#define ahd_scb_sense_busaddr_print(regvalue, cur_col, wrap) \
2238 ahd_print_register(NULL, 0, "SCB_SENSE_BUSADDR", 0x18c, regvalue, cur_col, wrap)
2239#endif
2240
2241#if AIC_DEBUG_REGISTERS
2242ahd_reg_print_t ahd_scb_tag_print;
2243#else
2244#define ahd_scb_tag_print(regvalue, cur_col, wrap) \
2245 ahd_print_register(NULL, 0, "SCB_TAG", 0x190, regvalue, cur_col, wrap)
2246#endif
2247
2248#if AIC_DEBUG_REGISTERS
2249ahd_reg_print_t ahd_scb_control_print;
2250#else
2251#define ahd_scb_control_print(regvalue, cur_col, wrap) \
2252 ahd_print_register(NULL, 0, "SCB_CONTROL", 0x192, regvalue, cur_col, wrap)
2253#endif
2254
2255#if AIC_DEBUG_REGISTERS
2256ahd_reg_print_t ahd_scb_scsiid_print;
2257#else
2258#define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \
2259 ahd_print_register(NULL, 0, "SCB_SCSIID", 0x193, regvalue, cur_col, wrap)
2260#endif
2261
2262#if AIC_DEBUG_REGISTERS
2263ahd_reg_print_t ahd_scb_lun_print;
2264#else
2265#define ahd_scb_lun_print(regvalue, cur_col, wrap) \
2266 ahd_print_register(NULL, 0, "SCB_LUN", 0x194, regvalue, cur_col, wrap)
2267#endif
2268
2269#if AIC_DEBUG_REGISTERS
2270ahd_reg_print_t ahd_scb_task_attribute_print;
2271#else
2272#define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \
2273 ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x195, regvalue, cur_col, wrap)
2274#endif
2275
2276#if AIC_DEBUG_REGISTERS
2277ahd_reg_print_t ahd_scb_cdb_len_print;
2278#else
2279#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \
2280 ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x196, regvalue, cur_col, wrap)
2281#endif
2282
2283#if AIC_DEBUG_REGISTERS
2284ahd_reg_print_t ahd_scb_task_management_print;
2285#else
2286#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \
2287 ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x197, regvalue, cur_col, wrap)
2288#endif
2289
2290#if AIC_DEBUG_REGISTERS
2291ahd_reg_print_t ahd_scb_dataptr_print;
2292#else
2293#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \
2294 ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x198, regvalue, cur_col, wrap)
2295#endif
2296
2297#if AIC_DEBUG_REGISTERS
2298ahd_reg_print_t ahd_scb_datacnt_print;
2299#else
2300#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \
2301 ahd_print_register(NULL, 0, "SCB_DATACNT", 0x1a0, regvalue, cur_col, wrap)
2302#endif
2303
2304#if AIC_DEBUG_REGISTERS
2305ahd_reg_print_t ahd_scb_sgptr_print;
2306#else
2307#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \
2308 ahd_print_register(NULL, 0, "SCB_SGPTR", 0x1a4, regvalue, cur_col, wrap)
2309#endif
2310
2311#if AIC_DEBUG_REGISTERS
2312ahd_reg_print_t ahd_scb_busaddr_print;
2313#else
2314#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \
2315 ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a8, regvalue, cur_col, wrap)
2316#endif
2317
2318#if AIC_DEBUG_REGISTERS
2319ahd_reg_print_t ahd_scb_next_print;
2320#else
2321#define ahd_scb_next_print(regvalue, cur_col, wrap) \
2322 ahd_print_register(NULL, 0, "SCB_NEXT", 0x1ac, regvalue, cur_col, wrap)
2323#endif
2324
2325#if AIC_DEBUG_REGISTERS
2326ahd_reg_print_t ahd_scb_next2_print;
2327#else
2328#define ahd_scb_next2_print(regvalue, cur_col, wrap) \
2329 ahd_print_register(NULL, 0, "SCB_NEXT2", 0x1ae, regvalue, cur_col, wrap)
2330#endif
2331
2332#if AIC_DEBUG_REGISTERS
2333ahd_reg_print_t ahd_scb_spare_print;
2334#else
2335#define ahd_scb_spare_print(regvalue, cur_col, wrap) \
2336 ahd_print_register(NULL, 0, "SCB_SPARE", 0x1b0, regvalue, cur_col, wrap)
2337#endif
2338
2339#if AIC_DEBUG_REGISTERS
2340ahd_reg_print_t ahd_scb_disconnected_lists_print;
2341#else
2342#define ahd_scb_disconnected_lists_print(regvalue, cur_col, wrap) \
2343 ahd_print_register(NULL, 0, "SCB_DISCONNECTED_LISTS", 0x1b8, regvalue, cur_col, wrap)
2344#endif
2345
2346
2347#define MODE_PTR 0x00
2348#define DST_MODE 0x70
2349#define SRC_MODE 0x07
2350
2351#define INTSTAT 0x01
2352#define INT_PEND 0xff
2353#define HWERRINT 0x80
2354#define BRKADRINT 0x40
2355#define SWTMINT 0x20
2356#define PCIINT 0x10
2357#define SCSIINT 0x08
2358#define SEQINT 0x04
2359#define CMDCMPLT 0x02
2360#define SPLTINT 0x01
2361
2362#define SEQINTCODE 0x02
2363#define BAD_SCB_STATUS 0x1a
2364#define SAW_HWERR 0x19
2365#define TRACEPOINT3 0x18
2366#define TRACEPOINT2 0x17
2367#define TRACEPOINT1 0x16
2368#define TRACEPOINT0 0x15
2369#define TASKMGMT_CMD_CMPLT_OKAY 0x14
2370#define TASKMGMT_FUNC_COMPLETE 0x13
2371#define ENTERING_NONPACK 0x12
2372#define CFG4OVERRUN 0x11
2373#define STATUS_OVERRUN 0x10
2374#define CFG4ISTAT_INTR 0x0f
2375#define INVALID_SEQINT 0x0e
2376#define ILLEGAL_PHASE 0x0d
2377#define DUMP_CARD_STATE 0x0c
2378#define MISSED_BUSFREE 0x0b
2379#define MKMSG_FAILED 0x0a
2380#define DATA_OVERRUN 0x09
2381#define BAD_STATUS 0x08
2382#define HOST_MSG_LOOP 0x07
2383#define PDATA_REINIT 0x06
2384#define IGN_WIDE_RES 0x05
2385#define NO_MATCH 0x04
2386#define PROTO_VIOLATION 0x03
2387#define SEND_REJECT 0x02
2388#define BAD_PHASE 0x01
2389#define NO_SEQINT 0x00
2390
2391#define CLRINT 0x03
2392#define CLRHWERRINT 0x80
2393#define CLRBRKADRINT 0x40
2394#define CLRSWTMINT 0x20
2395#define CLRPCIINT 0x10
2396#define CLRSCSIINT 0x08
2397#define CLRSEQINT 0x04
2398#define CLRCMDINT 0x02
2399#define CLRSPLTINT 0x01
2400
2401#define ERROR 0x04
2402#define CIOPARERR 0x80
2403#define CIOACCESFAIL 0x40
2404#define MPARERR 0x20
2405#define DPARERR 0x10
2406#define SQPARERR 0x08
2407#define ILLOPCODE 0x04
2408#define DSCTMOUT 0x02
2409
2410#define CLRERR 0x04
2411#define CLRCIOPARERR 0x80
2412#define CLRCIOACCESFAIL 0x40
2413#define CLRMPARERR 0x20
2414#define CLRDPARERR 0x10
2415#define CLRSQPARERR 0x08
2416#define CLRILLOPCODE 0x04
2417#define CLRDSCTMOUT 0x02
2418
2419#define HCNTRL 0x05
2420#define SEQ_RESET 0x80
2421#define POWRDN 0x40
2422#define SWINT 0x10
2423#define SWTIMER_START_B 0x08
2424#define PAUSE 0x04
2425#define INTEN 0x02
2426#define CHIPRST 0x01
2427#define CHIPRSTACK 0x01
2428
2429#define HNSCB_QOFF 0x06
2430
2431#define HESCB_QOFF 0x08
2432
2433#define HS_MAILBOX 0x0b
2434#define HOST_TQINPOS 0x80
2435#define ENINT_COALESCE 0x40
2436
2437#define CLRSEQINTSTAT 0x0c
2438#define CLRSEQ_SWTMRTO 0x10
2439#define CLRSEQ_SEQINT 0x08
2440#define CLRSEQ_SCSIINT 0x04
2441#define CLRSEQ_PCIINT 0x02
2442#define CLRSEQ_SPLTINT 0x01
2443
2444#define SEQINTSTAT 0x0c
2445#define SEQ_SWTMRTO 0x10
2446#define SEQ_SEQINT 0x08
2447#define SEQ_SCSIINT 0x04
2448#define SEQ_PCIINT 0x02
2449#define SEQ_SPLTINT 0x01
2450
2451#define SWTIMER 0x0e
2452
2453#define SNSCB_QOFF 0x10
2454
2455#define SESCB_QOFF 0x12
2456
2457#define SDSCB_QOFF 0x14
2458
2459#define QOFF_CTLSTA 0x16
2460#define EMPTY_SCB_AVAIL 0x80
2461#define NEW_SCB_AVAIL 0x40
2462#define SDSCB_ROLLOVR 0x20
2463#define HS_MAILBOX_ACT 0x10
2464#define SCB_QSIZE 0x0f
2465#define SCB_QSIZE_16384 0x0c
2466#define SCB_QSIZE_8192 0x0b
2467#define SCB_QSIZE_4096 0x0a
2468#define SCB_QSIZE_2048 0x09
2469#define SCB_QSIZE_1024 0x08
2470#define SCB_QSIZE_512 0x07
2471#define SCB_QSIZE_256 0x06
2472#define SCB_QSIZE_128 0x05
2473#define SCB_QSIZE_64 0x04
2474#define SCB_QSIZE_32 0x03
2475#define SCB_QSIZE_16 0x02
2476#define SCB_QSIZE_8 0x01
2477#define SCB_QSIZE_4 0x00
2478
2479#define INTCTL 0x18
2480#define SWTMINTMASK 0x80
2481#define SWTMINTEN 0x40
2482#define SWTIMER_START 0x20
2483#define AUTOCLRCMDINT 0x10
2484#define PCIINTEN 0x08
2485#define SCSIINTEN 0x04
2486#define SEQINTEN 0x02
2487#define SPLTINTEN 0x01
2488
2489#define DFCNTRL 0x19
2490#define SCSIENWRDIS 0x40
2491#define SCSIENACK 0x20
2492#define DIRECTIONACK 0x04
2493#define FIFOFLUSHACK 0x02
2494#define DIRECTIONEN 0x01
2495
2496#define DSCOMMAND0 0x19
2497#define CACHETHEN 0x80
2498#define DPARCKEN 0x40
2499#define MPARCKEN 0x20
2500#define EXTREQLCK 0x10
2501#define DISABLE_TWATE 0x02
2502#define CIOPARCKEN 0x01
2503
2504#define DFSTATUS 0x1a
2505#define PRELOAD_AVAIL 0x80
2506#define PKT_PRELOAD_AVAIL 0x40
2507#define MREQPEND 0x10
2508#define HDONE 0x08
2509#define DFTHRESH 0x04
2510#define FIFOFULL 0x02
2511#define FIFOEMP 0x01
2512
2513#define SG_CACHE_SHADOW 0x1b
2514#define ODD_SEG 0x04
2515#define LAST_SEG 0x02
2516#define LAST_SEG_DONE 0x01
2517
2518#define ARBCTL 0x1b
2519#define RESET_HARB 0x80
2520#define RETRY_SWEN 0x08
2521#define USE_TIME 0x07
2522
2523#define SG_CACHE_PRE 0x1b
2524
2525#define LQIN 0x20
2526
2527#define TYPEPTR 0x20
2528
2529#define TAGPTR 0x21
2530
2531#define LUNPTR 0x22
2532
2533#define DATALENPTR 0x23
2534
2535#define STATLENPTR 0x24
2536
2537#define CMDLENPTR 0x25
2538
2539#define ATTRPTR 0x26
2540
2541#define FLAGPTR 0x27
2542
2543#define CMDPTR 0x28
2544
2545#define QNEXTPTR 0x29
2546
2547#define IDPTR 0x2a
2548
2549#define ABRTBYTEPTR 0x2b
2550
2551#define ABRTBITPTR 0x2c
2552
2553#define MAXCMDBYTES 0x2d
2554
2555#define MAXCMD2RCV 0x2e
2556
2557#define SHORTTHRESH 0x2f
2558
2559#define LUNLEN 0x30
2560#define TLUNLEN 0xf0
2561#define ILUNLEN 0x0f
2562
2563#define CDBLIMIT 0x31
2564
2565#define MAXCMD 0x32
2566
2567#define MAXCMDCNT 0x33
2568
2569#define LQRSVD01 0x34
2570
2571#define LQRSVD16 0x35
2572
2573#define LQRSVD17 0x36
2574
2575#define CMDRSVD0 0x37
2576
2577#define LQCTL0 0x38
2578#define LQITARGCLT 0xc0
2579#define LQIINITGCLT 0x30
2580#define LQ0TARGCLT 0x0c
2581#define LQ0INITGCLT 0x03
2582
2583#define LQCTL1 0x38
2584#define PCI2PCI 0x04
2585#define SINGLECMD 0x02
2586#define ABORTPENDING 0x01
2587
2588#define SCSBIST0 0x39
2589#define GSBISTERR 0x40
2590#define GSBISTDONE 0x20
2591#define GSBISTRUN 0x10
2592#define OSBISTERR 0x04
2593#define OSBISTDONE 0x02
2594#define OSBISTRUN 0x01
2595
2596#define LQCTL2 0x39
2597#define LQIRETRY 0x80
2598#define LQICONTINUE 0x40
2599#define LQITOIDLE 0x20
2600#define LQIPAUSE 0x10
2601#define LQORETRY 0x08
2602#define LQOCONTINUE 0x04
2603#define LQOTOIDLE 0x02
2604#define LQOPAUSE 0x01
2605
2606#define SCSBIST1 0x3a
2607#define NTBISTERR 0x04
2608#define NTBISTDONE 0x02
2609#define NTBISTRUN 0x01
2610
2611#define SCSISEQ0 0x3a
2612#define TEMODEO 0x80
2613#define ENSELO 0x40
2614#define ENARBO 0x20
2615#define FORCEBUSFREE 0x10
2616#define SCSIRSTO 0x01
2617
2618#define SCSISEQ1 0x3b
2619
2620#define SXFRCTL0 0x3c
2621#define DFON 0x80
2622#define DFPEXP 0x40
2623#define BIOSCANCELEN 0x10
2624#define SPIOEN 0x08
2625
2626#define BUSINITID 0x3c
2627
2628#define DLCOUNT 0x3c
2629
2630#define SXFRCTL1 0x3d
2631#define BITBUCKET 0x80
2632#define ENSACHK 0x40
2633#define ENSPCHK 0x20
2634#define STIMESEL 0x18
2635#define ENSTIMER 0x04
2636#define ACTNEGEN 0x02
2637#define STPWEN 0x01
2638
2639#define BUSTARGID 0x3e
2640
2641#define SXFRCTL2 0x3e
2642#define AUTORSTDIS 0x10
2643#define CMDDMAEN 0x08
2644#define ASU 0x07
2645
2646#define DFFSTAT 0x3f
2647#define CURRFIFO 0x03
2648#define FIFO1FREE 0x20
2649#define FIFO0FREE 0x10
2650#define CURRFIFO_NONE 0x03
2651#define CURRFIFO_1 0x01
2652#define CURRFIFO_0 0x00
2653
2654#define SCSISIGO 0x40
2655#define CDO 0x80
2656#define IOO 0x40
2657#define MSGO 0x20
2658#define ATNO 0x10
2659#define SELO 0x08
2660#define BSYO 0x04
2661#define REQO 0x02
2662#define ACKO 0x01
2663
2664#define MULTARGID 0x40
2665
2666#define SCSISIGI 0x41
2667#define ATNI 0x10
2668#define SELI 0x08
2669#define BSYI 0x04
2670#define REQI 0x02
2671#define ACKI 0x01
2672
2673#define SCSIPHASE 0x42
2674#define STATUS_PHASE 0x20
2675#define COMMAND_PHASE 0x10
2676#define MSG_IN_PHASE 0x08
2677#define MSG_OUT_PHASE 0x04
2678#define DATA_PHASE_MASK 0x03
2679#define DATA_IN_PHASE 0x02
2680#define DATA_OUT_PHASE 0x01
2681
2682#define SCSIDAT0_IMG 0x43
2683
2684#define SCSIDAT 0x44
2685
2686#define SCSIBUS 0x46
2687
2688#define TARGIDIN 0x48
2689#define CLKOUT 0x80
2690#define TARGID 0x0f
2691
2692#define SELID 0x49
2693#define SELID_MASK 0xf0
2694#define ONEBIT 0x08
2695
2696#define SBLKCTL 0x4a
2697#define DIAGLEDEN 0x80
2698#define DIAGLEDON 0x40
2699#define ENAB40 0x08
2700#define ENAB20 0x04
2701#define SELWIDE 0x02
2702
2703#define OPTIONMODE 0x4a
2704#define OPTIONMODE_DEFAULTS 0x02
2705#define BIOSCANCTL 0x80
2706#define AUTOACKEN 0x40
2707#define BIASCANCTL 0x20
2708#define BUSFREEREV 0x10
2709#define ENDGFORMCHK 0x04
2710#define AUTO_MSGOUT_DE 0x02
2711
2712#define SSTAT0 0x4b
2713#define TARGET 0x80
2714#define SELDO 0x40
2715#define SELDI 0x20
2716#define SELINGO 0x10
2717#define IOERR 0x08
2718#define OVERRUN 0x04
2719#define SPIORDY 0x02
2720#define ARBDO 0x01
2721
2722#define CLRSINT0 0x4b
2723#define CLRSELDO 0x40
2724#define CLRSELDI 0x20
2725#define CLRSELINGO 0x10
2726#define CLRIOERR 0x08
2727#define CLROVERRUN 0x04
2728#define CLRSPIORDY 0x02
2729#define CLRARBDO 0x01
2730
2731#define SIMODE0 0x4b
2732#define ENSELDO 0x40
2733#define ENSELDI 0x20
2734#define ENSELINGO 0x10
2735#define ENIOERR 0x08
2736#define ENOVERRUN 0x04
2737#define ENSPIORDY 0x02
2738#define ENARBDO 0x01
2739
2740#define CLRSINT1 0x4c
2741#define CLRSELTIMEO 0x80
2742#define CLRATNO 0x40
2743#define CLRSCSIRSTI 0x20
2744#define CLRBUSFREE 0x08
2745#define CLRSCSIPERR 0x04
2746#define CLRSTRB2FAST 0x02
2747#define CLRREQINIT 0x01
2748
2749#define SSTAT1 0x4c
2750#define SELTO 0x80
2751#define ATNTARG 0x40
2752#define SCSIRSTI 0x20
2753#define PHASEMIS 0x10
2754#define BUSFREE 0x08
2755#define SCSIPERR 0x04
2756#define STRB2FAST 0x02
2757#define REQINIT 0x01
2758
2759#define SSTAT2 0x4d
2760#define BUSFREETIME 0xc0
2761#define NONPACKREQ 0x20
2762#define EXP_ACTIVE 0x10
2763#define BSYX 0x08
2764#define WIDE_RES 0x04
2765#define SDONE 0x02
2766#define DMADONE 0x01
2767#define BUSFREE_DFF1 0xc0
2768#define BUSFREE_DFF0 0x80
2769#define BUSFREE_LQO 0x40
2770
2771#define CLRSINT2 0x4d
2772#define CLRNONPACKREQ 0x20
2773#define CLRWIDE_RES 0x04
2774#define CLRSDONE 0x02
2775#define CLRDMADONE 0x01
2776
2777#define SIMODE2 0x4d
2778#define ENWIDE_RES 0x04
2779#define ENSDONE 0x02
2780#define ENDMADONE 0x01
2781
2782#define PERRDIAG 0x4e
2783#define HIZERO 0x80
2784#define HIPERR 0x40
2785#define PREVPHASE 0x20
2786#define PARITYERR 0x10
2787#define AIPERR 0x08
2788#define CRCERR 0x04
2789#define DGFORMERR 0x02
2790#define DTERR 0x01
2791
2792#define LQISTATE 0x4e
2793
2794#define SOFFCNT 0x4f
2795
2796#define LQOSTATE 0x4f
2797
2798#define LQISTAT0 0x50
2799#define LQIATNQAS 0x20
2800#define LQICRCT1 0x10
2801#define LQICRCT2 0x08
2802#define LQIBADLQT 0x04
2803#define LQIATNLQ 0x02
2804#define LQIATNCMD 0x01
2805
2806#define CLRLQIINT0 0x50
2807#define CLRLQIATNQAS 0x20
2808#define CLRLQICRCT1 0x10
2809#define CLRLQICRCT2 0x08
2810#define CLRLQIBADLQT 0x04
2811#define CLRLQIATNLQ 0x02
2812#define CLRLQIATNCMD 0x01
2813
2814#define LQIMODE0 0x50
2815#define ENLQIATNQASK 0x20
2816#define ENLQICRCT1 0x10
2817#define ENLQICRCT2 0x08
2818#define ENLQIBADLQT 0x04
2819#define ENLQIATNLQ 0x02
2820#define ENLQIATNCMD 0x01
2821
2822#define LQIMODE1 0x51
2823#define ENLQIPHASE_LQ 0x80
2824#define ENLQIPHASE_NLQ 0x40
2825#define ENLIQABORT 0x20
2826#define ENLQICRCI_LQ 0x10
2827#define ENLQICRCI_NLQ 0x08
2828#define ENLQIBADLQI 0x04
2829#define ENLQIOVERI_LQ 0x02
2830#define ENLQIOVERI_NLQ 0x01
2831
2832#define LQISTAT1 0x51
2833#define LQIPHASE_LQ 0x80
2834#define LQIPHASE_NLQ 0x40
2835#define LQIABORT 0x20
2836#define LQICRCI_LQ 0x10
2837#define LQICRCI_NLQ 0x08
2838#define LQIBADLQI 0x04
2839#define LQIOVERI_LQ 0x02
2840#define LQIOVERI_NLQ 0x01
2841
2842#define CLRLQIINT1 0x51
2843#define CLRLQIPHASE_LQ 0x80
2844#define CLRLQIPHASE_NLQ 0x40
2845#define CLRLIQABORT 0x20
2846#define CLRLQICRCI_LQ 0x10
2847#define CLRLQICRCI_NLQ 0x08
2848#define CLRLQIBADLQI 0x04
2849#define CLRLQIOVERI_LQ 0x02
2850#define CLRLQIOVERI_NLQ 0x01
2851
2852#define LQISTAT2 0x52
2853#define PACKETIZED 0x80
2854#define LQIPHASE_OUTPKT 0x40
2855#define LQIWORKONLQ 0x20
2856#define LQIWAITFIFO 0x10
2857#define LQISTOPPKT 0x08
2858#define LQISTOPLQ 0x04
2859#define LQISTOPCMD 0x02
2860#define LQIGSAVAIL 0x01
2861
2862#define SSTAT3 0x53
2863#define NTRAMPERR 0x02
2864#define OSRAMPERR 0x01
2865
2866#define SIMODE3 0x53
2867#define ENNTRAMPERR 0x02
2868#define ENOSRAMPERR 0x01
2869
2870#define CLRSINT3 0x53
2871#define CLRNTRAMPERR 0x02
2872#define CLROSRAMPERR 0x01
2873
2874#define LQOMODE0 0x54
2875#define ENLQOTARGSCBPERR 0x10
2876#define ENLQOSTOPT2 0x08
2877#define ENLQOATNLQ 0x04
2878#define ENLQOATNPKT 0x02
2879#define ENLQOTCRC 0x01
2880
2881#define LQOSTAT0 0x54
2882#define LQOTARGSCBPERR 0x10
2883#define LQOSTOPT2 0x08
2884#define LQOATNLQ 0x04
2885#define LQOATNPKT 0x02
2886#define LQOTCRC 0x01
2887
2888#define CLRLQOINT0 0x54
2889#define CLRLQOTARGSCBPERR 0x10
2890#define CLRLQOSTOPT2 0x08
2891#define CLRLQOATNLQ 0x04
2892#define CLRLQOATNPKT 0x02
2893#define CLRLQOTCRC 0x01
2894
2895#define LQOSTAT1 0x55
2896#define LQOINITSCBPERR 0x10
2897#define LQOSTOPI2 0x08
2898#define LQOBADQAS 0x04
2899#define LQOBUSFREE 0x02
2900#define LQOPHACHGINPKT 0x01
2901
2902#define CLRLQOINT1 0x55
2903#define CLRLQOINITSCBPERR 0x10
2904#define CLRLQOSTOPI2 0x08
2905#define CLRLQOBADQAS 0x04
2906#define CLRLQOBUSFREE 0x02
2907#define CLRLQOPHACHGINPKT 0x01
2908
2909#define LQOMODE1 0x55
2910#define ENLQOINITSCBPERR 0x10
2911#define ENLQOSTOPI2 0x08
2912#define ENLQOBADQAS 0x04
2913#define ENLQOBUSFREE 0x02
2914#define ENLQOPHACHGINPKT 0x01
2915
2916#define LQOSTAT2 0x56
2917#define LQOPKT 0xe0
2918#define LQOWAITFIFO 0x10
2919#define LQOPHACHGOUTPKT 0x02
2920#define LQOSTOP0 0x01
2921
2922#define OS_SPACE_CNT 0x56
2923
2924#define SIMODE1 0x57
2925#define ENSELTIMO 0x80
2926#define ENATNTARG 0x40
2927#define ENSCSIRST 0x20
2928#define ENPHASEMIS 0x10
2929#define ENBUSFREE 0x08
2930#define ENSCSIPERR 0x04
2931#define ENSTRB2FAST 0x02
2932#define ENREQINIT 0x01
2933
2934#define GSFIFO 0x58
2935
2936#define DFFSXFRCTL 0x5a
2937#define DFFBITBUCKET 0x08
2938#define CLRSHCNT 0x04
2939#define CLRCHN 0x02
2940#define RSTCHN 0x01
2941
2942#define LQOSCSCTL 0x5a
2943#define LQOH2A_VERSION 0x80
2944#define LQONOCHKOVER 0x01
2945
2946#define NEXTSCB 0x5a
2947
2948#define CLRSEQINTSRC 0x5b
2949#define CLRCTXTDONE 0x40
2950#define CLRSAVEPTRS 0x20
2951#define CLRCFG4DATA 0x10
2952#define CLRCFG4ISTAT 0x08
2953#define CLRCFG4TSTAT 0x04
2954#define CLRCFG4ICMD 0x02
2955#define CLRCFG4TCMD 0x01
2956
2957#define SEQINTSRC 0x5b
2958#define CTXTDONE 0x40
2959#define SAVEPTRS 0x20
2960#define CFG4DATA 0x10
2961#define CFG4ISTAT 0x08
2962#define CFG4TSTAT 0x04
2963#define CFG4ICMD 0x02
2964#define CFG4TCMD 0x01
2965
2966#define CURRSCB 0x5c
2967
2968#define SEQIMODE 0x5c
2969#define ENCTXTDONE 0x40
2970#define ENSAVEPTRS 0x20
2971#define ENCFG4DATA 0x10
2972#define ENCFG4ISTAT 0x08
2973#define ENCFG4TSTAT 0x04
2974#define ENCFG4ICMD 0x02
2975#define ENCFG4TCMD 0x01
2976
2977#define MDFFSTAT 0x5d
2978#define SHCNTNEGATIVE 0x40
2979#define SHCNTMINUS1 0x20
2980#define LASTSDONE 0x10
2981#define SHVALID 0x08
2982#define DLZERO 0x04
2983#define DATAINFIFO 0x02
2984#define FIFOFREE 0x01
2985
2986#define CRCCONTROL 0x5d
2987#define CRCVALCHKEN 0x40
2988
2989#define DFFTAG 0x5e
2990
2991#define LASTSCB 0x5e
2992
2993#define SCSITEST 0x5e
2994#define CNTRTEST 0x08
2995#define SEL_TXPLL_DEBUG 0x04
2996
2997#define IOPDNCTL 0x5f
2998#define DISABLE_OE 0x80
2999#define PDN_IDIST 0x04
3000#define PDN_DIFFSENSE 0x01
3001
3002#define SHADDR 0x60
3003
3004#define NEGOADDR 0x60
3005
3006#define DGRPCRCI 0x60
3007
3008#define NEGPERIOD 0x61
3009
3010#define PACKCRCI 0x62
3011
3012#define NEGOFFSET 0x62
3013
3014#define NEGPPROPTS 0x63
3015#define PPROPT_PACE 0x08
3016#define PPROPT_QAS 0x04
3017#define PPROPT_DT 0x02
3018#define PPROPT_IUT 0x01
3019
3020#define NEGCONOPTS 0x64
3021#define ENSNAPSHOT 0x40
3022#define RTI_WRTDIS 0x20
3023#define RTI_OVRDTRN 0x10
3024#define ENSLOWCRC 0x08
3025#define ENAUTOATNI 0x04
3026#define ENAUTOATNO 0x02
3027#define WIDEXFER 0x01
3028
3029#define ANNEXCOL 0x65
3030
3031#define SCSCHKN 0x66
3032#define STSELSKIDDIS 0x40
3033#define CURRFIFODEF 0x20
3034#define WIDERESEN 0x10
3035#define SDONEMSKDIS 0x08
3036#define DFFACTCLR 0x04
3037#define SHVALIDSTDIS 0x02
3038#define LSTSGCLRDIS 0x01
3039
3040#define ANNEXDAT 0x66
3041
3042#define IOWNID 0x67
3043
3044#define PLL960CTL0 0x68
3045
3046#define SHCNT 0x68
3047
3048#define TOWNID 0x69
3049
3050#define PLL960CTL1 0x69
3051
3052#define PLL960CNT0 0x6a
3053
3054#define XSIG 0x6a
3055
3056#define SELOID 0x6b
3057
3058#define PLL400CTL0 0x6c
3059#define PLL_VCOSEL 0x80
3060#define PLL_PWDN 0x40
3061#define PLL_NS 0x30
3062#define PLL_ENLUD 0x08
3063#define PLL_ENLPF 0x04
3064#define PLL_DLPF 0x02
3065#define PLL_ENFBM 0x01
3066
3067#define FAIRNESS 0x6c
3068
3069#define PLL400CTL1 0x6d
3070#define PLL_CNTEN 0x80
3071#define PLL_CNTCLR 0x40
3072#define PLL_RST 0x01
3073
3074#define PLL400CNT0 0x6e
3075
3076#define UNFAIRNESS 0x6e
3077
3078#define HADDR 0x70
3079
3080#define PLLDELAY 0x70
3081#define SPLIT_DROP_REQ 0x80
3082
3083#define HODMAADR 0x70
3084
3085#define HODMACNT 0x78
3086
3087#define HCNT 0x78
3088
3089#define HODMAEN 0x7a
3090
3091#define SGHADDR 0x7c
3092
3093#define SCBHADDR 0x7c
3094
3095#define SGHCNT 0x84
3096
3097#define SCBHCNT 0x84
3098
3099#define DFF_THRSH 0x88
3100#define WR_DFTHRSH 0x70
3101#define RD_DFTHRSH 0x07
3102#define WR_DFTHRSH_MAX 0x70
3103#define WR_DFTHRSH_90 0x60
3104#define WR_DFTHRSH_85 0x50
3105#define WR_DFTHRSH_75 0x40
3106#define WR_DFTHRSH_63 0x30
3107#define WR_DFTHRSH_50 0x20
3108#define WR_DFTHRSH_25 0x10
3109#define RD_DFTHRSH_MAX 0x07
3110#define RD_DFTHRSH_90 0x06
3111#define RD_DFTHRSH_85 0x05
3112#define RD_DFTHRSH_75 0x04
3113#define RD_DFTHRSH_63 0x03
3114#define RD_DFTHRSH_50 0x02
3115#define RD_DFTHRSH_25 0x01
3116#define WR_DFTHRSH_MIN 0x00
3117#define RD_DFTHRSH_MIN 0x00
3118
3119#define ROMADDR 0x8a
3120
3121#define ROMCNTRL 0x8d
3122#define ROMOP 0xe0
3123#define ROMSPD 0x18
3124#define REPEAT 0x02
3125#define RDY 0x01
3126
3127#define ROMDATA 0x8e
3128
3129#define CMCRXMSG0 0x90
3130
3131#define ROENABLE 0x90
3132#define MSIROEN 0x20
3133#define OVLYROEN 0x10
3134#define CMCROEN 0x08
3135#define SGROEN 0x04
3136#define DCH1ROEN 0x02
3137#define DCH0ROEN 0x01
3138
3139#define OVLYRXMSG0 0x90
3140
3141#define DCHRXMSG0 0x90
3142
3143#define OVLYRXMSG1 0x91
3144
3145#define NSENABLE 0x91
3146#define MSINSEN 0x20
3147#define OVLYNSEN 0x10
3148#define CMCNSEN 0x08
3149#define SGNSEN 0x04
3150#define DCH1NSEN 0x02
3151#define DCH0NSEN 0x01
3152
3153#define DCHRXMSG1 0x91
3154
3155#define CMCRXMSG1 0x91
3156
3157#define DCHRXMSG2 0x92
3158
3159#define OVLYRXMSG2 0x92
3160
3161#define CMCRXMSG2 0x92
3162
3163#define OST 0x92
3164
3165#define DCHRXMSG3 0x93
3166
3167#define CMCRXMSG3 0x93
3168
3169#define PCIXCTL 0x93
3170#define SERRPULSE 0x80
3171#define UNEXPSCIEN 0x20
3172#define SPLTSMADIS 0x10
3173#define SPLTSTADIS 0x08
3174#define SRSPDPEEN 0x04
3175#define TSCSERREN 0x02
3176#define CMPABCDIS 0x01
3177
3178#define OVLYRXMSG3 0x93
3179
3180#define OVLYSEQBCNT 0x94
3181
3182#define CMCSEQBCNT 0x94
3183
3184#define DCHSEQBCNT 0x94
3185
3186#define CMCSPLTSTAT0 0x96
3187
3188#define OVLYSPLTSTAT0 0x96
3189
3190#define DCHSPLTSTAT0 0x96
3191
3192#define DCHSPLTSTAT1 0x97
3193
3194#define CMCSPLTSTAT1 0x97
3195
3196#define OVLYSPLTSTAT1 0x97
3197
3198#define SGRXMSG0 0x98
3199#define CDNUM 0xf8
3200#define CFNUM 0x07
3201
3202#define SLVSPLTOUTADR0 0x98
3203#define LOWER_ADDR 0x7f
3204
3205#define SGRXMSG1 0x99
3206#define CBNUM 0xff
3207
3208#define SLVSPLTOUTADR1 0x99
3209#define REQ_DNUM 0xf8
3210#define REQ_FNUM 0x07
3211
3212#define SGRXMSG2 0x9a
3213#define MINDEX 0xff
3214
3215#define SLVSPLTOUTADR2 0x9a
3216#define REQ_BNUM 0xff
3217
3218#define SGRXMSG3 0x9b
3219#define MCLASS 0x0f
3220
3221#define SLVSPLTOUTADR3 0x9b
3222#define TAG_NUM 0x1f
3223#define RLXORD 0x10
3224
3225#define SGSEQBCNT 0x9c
3226
3227#define SLVSPLTOUTATTR0 0x9c
3228#define LOWER_BCNT 0xff
3229
3230#define SLVSPLTOUTATTR1 0x9d
3231#define CMPLT_DNUM 0xf8
3232#define CMPLT_FNUM 0x07
3233
3234#define SLVSPLTOUTATTR2 0x9e
3235#define CMPLT_BNUM 0xff
3236
3237#define SGSPLTSTAT0 0x9e
3238#define STAETERM 0x80
3239#define SCBCERR 0x40
3240#define SCADERR 0x20
3241#define SCDATBUCKET 0x10
3242#define CNTNOTCMPLT 0x08
3243#define RXOVRUN 0x04
3244#define RXSCEMSG 0x02
3245#define RXSPLTRSP 0x01
3246
3247#define SFUNCT 0x9f
3248#define TEST_GROUP 0xf0
3249#define TEST_NUM 0x0f
3250
3251#define SGSPLTSTAT1 0x9f
3252#define RXDATABUCKET 0x01
3253
3254#define DF0PCISTAT 0xa0
3255
3256#define REG0 0xa0
3257
3258#define DF1PCISTAT 0xa1
3259
3260#define SGPCISTAT 0xa2
3261
3262#define REG1 0xa2
3263
3264#define CMCPCISTAT 0xa3
3265
3266#define OVLYPCISTAT 0xa4
3267#define SCAAPERR 0x08
3268#define RDPERR 0x04
3269
3270#define REG_ISR 0xa4
3271
3272#define SG_STATE 0xa6
3273#define FETCH_INPROG 0x04
3274#define LOADING_NEEDED 0x02
3275#define SEGS_AVAIL 0x01
3276
3277#define MSIPCISTAT 0xa6
3278#define RMA 0x20
3279#define RTA 0x10
3280#define CLRPENDMSI 0x08
3281#define DPR 0x01
3282
3283#define TARGPCISTAT 0xa7
3284#define DPE 0x80
3285#define SSE 0x40
3286#define STA 0x08
3287#define TWATERR 0x02
3288
3289#define DATA_COUNT_ODD 0xa7
3290
3291#define SCBPTR 0xa8
3292
3293#define CCSCBACNT 0xab
3294
3295#define SCBAUTOPTR 0xab
3296#define AUSCBPTR_EN 0x80
3297#define SCBPTR_ADDR 0x38
3298#define SCBPTR_OFF 0x07
3299
3300#define CCSGADDR 0xac
3301
3302#define CCSCBADDR 0xac
3303
3304#define CCSCBADR_BK 0xac
3305
3306#define CMC_RAMBIST 0xad
3307#define SG_ELEMENT_SIZE 0x80
3308#define SCBRAMBIST_FAIL 0x40
3309#define SG_BIST_FAIL 0x20
3310#define SG_BIST_EN 0x10
3311#define CMC_BUFFER_BIST_FAIL 0x02
3312#define CMC_BUFFER_BIST_EN 0x01
3313
3314#define CCSGCTL 0xad
3315#define CCSGEN 0x0c
3316#define CCSGDONE 0x80
3317#define SG_CACHE_AVAIL 0x10
3318#define CCSGENACK 0x08
3319#define SG_FETCH_REQ 0x02
3320#define CCSGRESET 0x01
3321
3322#define CCSCBCTL 0xad
3323#define CCSCBDONE 0x80
3324#define ARRDONE 0x40
3325#define CCARREN 0x10
3326#define CCSCBEN 0x08
3327#define CCSCBDIR 0x04
3328#define CCSCBRESET 0x01
3329
3330#define CCSGRAM 0xb0
3331
3332#define FLEXADR 0xb0
3333
3334#define CCSCBRAM 0xb0
3335
3336#define FLEXCNT 0xb3
3337
3338#define FLEXDMASTAT 0xb5
3339#define FLEXDMAERR 0x02
3340#define FLEXDMADONE 0x01
3341
3342#define FLEXDATA 0xb6
3343
3344#define BRDDAT 0xb8
3345
3346#define BRDCTL 0xb9
3347#define FLXARBACK 0x80
3348#define FLXARBREQ 0x40
3349#define BRDADDR 0x38
3350#define BRDEN 0x04
3351#define BRDRW 0x02
3352#define BRDSTB 0x01
3353
3354#define SEEADR 0xba
3355
3356#define SEEDAT 0xbc
3357
3358#define SEECTL 0xbe
3359#define SEEOP_EWEN 0x40
3360#define SEEOP_WALL 0x40
3361#define SEEOP_EWDS 0x40
3362#define SEEOPCODE 0x70
3363#define SEERST 0x02
3364#define SEESTART 0x01
3365#define SEEOP_ERASE 0x70
3366#define SEEOP_READ 0x60
3367#define SEEOP_WRITE 0x50
3368#define SEEOP_ERAL 0x40
3369
3370#define SEESTAT 0xbe
3371#define INIT_DONE 0x80
3372#define LDALTID_L 0x08
3373#define SEEARBACK 0x04
3374#define SEEBUSY 0x02
3375
3376#define SCBCNT 0xbf
3377
3378#define DFWADDR 0xc0
3379
3380#define DSPFLTRCTL 0xc0
3381#define FLTRDISABLE 0x20
3382#define EDGESENSE 0x10
3383#define DSPFCNTSEL 0x0f
3384
3385#define DSPDATACTL 0xc1
3386#define BYPASSENAB 0x80
3387#define DESQDIS 0x10
3388#define RCVROFFSTDIS 0x04
3389#define XMITOFFSTDIS 0x02
3390
3391#define DFRADDR 0xc2
3392
3393#define DSPREQCTL 0xc2
3394#define MANREQCTL 0xc0
3395#define MANREQDLY 0x3f
3396
3397#define DSPACKCTL 0xc3
3398#define MANACKCTL 0xc0
3399#define MANACKDLY 0x3f
3400
3401#define DFDAT 0xc4
3402
3403#define DSPSELECT 0xc4
3404#define AUTOINCEN 0x80
3405#define DSPSEL 0x1f
3406
3407#define WRTBIASCTL 0xc5
3408#define AUTOXBCDIS 0x80
3409#define XMITMANVAL 0x3f
3410
3411#define RCVRBIOSCTL 0xc6
3412#define AUTORBCDIS 0x80
3413#define RCVRMANVAL 0x3f
3414
3415#define WRTBIASCALC 0xc7
3416
3417#define DFPTRS 0xc8
3418
3419#define RCVRBIASCALC 0xc8
3420
3421#define DFBKPTR 0xc9
3422
3423#define SKEWCALC 0xc9
3424
3425#define DFDBCTL 0xcb
3426#define DFF_CIO_WR_RDY 0x20
3427#define DFF_CIO_RD_RDY 0x10
3428#define DFF_DIR_ERR 0x08
3429#define DFF_RAMBIST_FAIL 0x04
3430#define DFF_RAMBIST_DONE 0x02
3431#define DFF_RAMBIST_EN 0x01
3432
3433#define DFSCNT 0xcc
3434
3435#define DFBCNT 0xce
3436
3437#define OVLYADDR 0xd4
3438
3439#define SEQCTL0 0xd6
3440#define PERRORDIS 0x80
3441#define PAUSEDIS 0x40
3442#define FAILDIS 0x20
3443#define FASTMODE 0x10
3444#define BRKADRINTEN 0x08
3445#define STEP 0x04
3446#define SEQRESET 0x02
3447#define LOADRAM 0x01
3448
3449#define SEQCTL1 0xd7
3450#define OVRLAY_DATA_CHK 0x08
3451#define RAMBIST_DONE 0x04
3452#define RAMBIST_FAIL 0x02
3453#define RAMBIST_EN 0x01
3454
3455#define FLAGS 0xd8
3456#define ZERO 0x02
3457#define CARRY 0x01
3458
3459#define SEQINTCTL 0xd9
3460#define INTVEC1DSL 0x80
3461#define INT1_CONTEXT 0x20
3462#define SCS_SEQ_INT1M1 0x10
3463#define SCS_SEQ_INT1M0 0x08
3464#define INTMASK2 0x04
3465#define INTMASK1 0x02
3466#define IRET 0x01
3467
3468#define SEQRAM 0xda
3469
3470#define PRGMCNT 0xde
3471
3472#define ACCUM 0xe0
3473
3474#define SINDEX 0xe2
3475
3476#define DINDEX 0xe4
3477
3478#define BRKADDR1 0xe6
3479#define BRKDIS 0x80
3480
3481#define BRKADDR0 0xe6
3482
3483#define ALLONES 0xe8
3484
3485#define ALLZEROS 0xea
3486
3487#define NONE 0xea
3488
3489#define SINDIR 0xec
3490
3491#define DINDIR 0xed
3492
3493#define FUNCTION1 0xf0
3494
3495#define STACK 0xf2
3496
3497#define CURADDR 0xf4
3498
3499#define INTVEC1_ADDR 0xf4
3500
3501#define INTVEC2_ADDR 0xf6
3502
3503#define LASTADDR 0xf6
3504
3505#define LONGJMP_ADDR 0xf8
3506
3507#define ACCUM_SAVE 0xfa
3508
3509#define WAITING_SCB_TAILS 0x100
3510
3511#define AHD_PCI_CONFIG_BASE 0x100
3512
3513#define SRAM_BASE 0x100
3514
3515#define WAITING_TID_HEAD 0x120
3516
3517#define WAITING_TID_TAIL 0x122
3518
3519#define NEXT_QUEUED_SCB_ADDR 0x124
3520
3521#define COMPLETE_SCB_HEAD 0x128
3522
3523#define COMPLETE_SCB_DMAINPROG_HEAD 0x12a
3524
3525#define COMPLETE_DMA_SCB_HEAD 0x12c
3526
3527#define QFREEZE_COUNT 0x12e
3528
3529#define SAVED_MODE 0x130
3530
3531#define MSG_OUT 0x131
3532
3533#define DMAPARAMS 0x132
3534#define PRELOADEN 0x80
3535#define WIDEODD 0x40
3536#define SCSIEN 0x20
3537#define SDMAEN 0x10
3538#define SDMAENACK 0x10
3539#define HDMAENACK 0x08
3540#define HDMAEN 0x08
3541#define DIRECTION 0x04
3542#define FIFOFLUSH 0x02
3543#define FIFORESET 0x01
3544
3545#define SEQ_FLAGS 0x133
3546#define NOT_IDENTIFIED 0x80
3547#define NO_CDB_SENT 0x40
3548#define TARGET_CMD_IS_TAGGED 0x40
3549#define DPHASE 0x20
3550#define TARG_CMD_PENDING 0x10
3551#define CMDPHASE_PENDING 0x08
3552#define DPHASE_PENDING 0x04
3553#define SPHASE_PENDING 0x02
3554#define NO_DISCONNECT 0x01
3555
3556#define SAVED_SCSIID 0x134
3557
3558#define SAVED_LUN 0x135
3559
3560#define LASTPHASE 0x136
3561#define PHASE_MASK 0xe0
3562#define CDI 0x80
3563#define IOI 0x40
3564#define MSGI 0x20
3565#define P_BUSFREE 0x01
3566#define P_MESGIN 0xe0
3567#define P_STATUS 0xc0
3568#define P_MESGOUT 0xa0
3569#define P_COMMAND 0x80
3570#define P_DATAIN_DT 0x60
3571#define P_DATAIN 0x40
3572#define P_DATAOUT_DT 0x20
3573#define P_DATAOUT 0x00
3574
3575#define QOUTFIFO_ENTRY_VALID_TAG 0x137
3576
3577#define SHARED_DATA_ADDR 0x138
3578
3579#define QOUTFIFO_NEXT_ADDR 0x13c
3580
3581#define KERNEL_TQINPOS 0x140
3582
3583#define TQINPOS 0x141
3584
3585#define ARG_1 0x142
3586#define RETURN_1 0x142
3587#define SEND_MSG 0x80
3588#define SEND_SENSE 0x40
3589#define SEND_REJ 0x20
3590#define MSGOUT_PHASEMIS 0x10
3591#define EXIT_MSG_LOOP 0x08
3592#define CONT_MSG_LOOP_WRITE 0x04
3593#define CONT_MSG_LOOP_READ 0x03
3594#define CONT_MSG_LOOP_TARG 0x02
3595
3596#define ARG_2 0x143
3597#define RETURN_2 0x143
3598
3599#define LAST_MSG 0x144
3600
3601#define SCSISEQ_TEMPLATE 0x145
3602#define MANUALCTL 0x40
3603#define ENSELI 0x20
3604#define ENRSELI 0x10
3605#define MANUALP 0x0c
3606#define ENAUTOATNP 0x02
3607#define ALTSTIM 0x01
3608
3609#define INITIATOR_TAG 0x146
3610
3611#define SEQ_FLAGS2 0x147
3612#define SELECTOUT_QFROZEN 0x04
3613#define TARGET_MSG_PENDING 0x02
3614
3615#define ALLOCFIFO_SCBPTR 0x148
3616
3617#define INT_COALESCING_TIMER 0x14a
3618
3619#define INT_COALESCING_MAXCMDS 0x14c
3620
3621#define INT_COALESCING_MINCMDS 0x14d
3622
3623#define CMDS_PENDING 0x14e
3624
3625#define INT_COALESCING_CMDCOUNT 0x150
3626
3627#define LOCAL_HS_MAILBOX 0x151
3628
3629#define CMDSIZE_TABLE 0x152
3630
3631#define SCB_BASE 0x180
3632
3633#define SCB_RESIDUAL_DATACNT 0x180
3634#define SCB_CDB_STORE 0x180
3635#define SCB_HOST_CDB_PTR 0x180
3636
3637#define SCB_RESIDUAL_SGPTR 0x184
3638#define SG_ADDR_MASK 0xf8
3639#define SG_OVERRUN_RESID 0x02
3640
3641#define SCB_SCSI_STATUS 0x188
3642#define SCB_HOST_CDB_LEN 0x188
3643
3644#define SCB_TARGET_PHASES 0x189
3645
3646#define SCB_TARGET_DATA_DIR 0x18a
3647
3648#define SCB_TARGET_ITAG 0x18b
3649
3650#define SCB_SENSE_BUSADDR 0x18c
3651#define SCB_NEXT_COMPLETE 0x18c
3652
3653#define SCB_TAG 0x190
3654#define SCB_FIFO_USE_COUNT 0x190
3655
3656#define SCB_CONTROL 0x192
3657#define TARGET_SCB 0x80
3658#define DISCENB 0x40
3659#define TAG_ENB 0x20
3660#define MK_MESSAGE 0x10
3661#define STATUS_RCVD 0x08
3662#define DISCONNECTED 0x04
3663#define SCB_TAG_TYPE 0x03
3664
3665#define SCB_SCSIID 0x193
3666#define TID 0xf0
3667#define OID 0x0f
3668
3669#define SCB_LUN 0x194
3670#define LID 0xff
3671
3672#define SCB_TASK_ATTRIBUTE 0x195
3673#define SCB_XFERLEN_ODD 0x01
3674
3675#define SCB_CDB_LEN 0x196
3676#define SCB_CDB_LEN_PTR 0x80
3677
3678#define SCB_TASK_MANAGEMENT 0x197
3679
3680#define SCB_DATAPTR 0x198
3681
3682#define SCB_DATACNT 0x1a0
3683#define SG_LAST_SEG 0x80
3684#define SG_HIGH_ADDR_BITS 0x7f
3685
3686#define SCB_SGPTR 0x1a4
3687#define SG_STATUS_VALID 0x04
3688#define SG_FULL_RESID 0x02
3689#define SG_LIST_NULL 0x01
3690
3691#define SCB_BUSADDR 0x1a8
3692
3693#define SCB_NEXT 0x1ac
3694#define SCB_NEXT_SCB_BUSADDR 0x1ac
3695
3696#define SCB_NEXT2 0x1ae
3697
3698#define SCB_SPARE 0x1b0
3699#define SCB_PKT_LUN 0x1b0
3700
3701#define SCB_DISCONNECTED_LISTS 0x1b8
3702
3703
3704#define AHD_TIMER_US_PER_TICK 0x19
3705#define SCB_TRANSFER_SIZE_FULL_LUN 0x38
3706#define STATUS_QUEUE_FULL 0x28
3707#define STATUS_BUSY 0x08
3708#define MAX_OFFSET_NON_PACED 0x7f
3709#define MAX_OFFSET_PACED 0xfe
3710#define BUS_32_BIT 0x02
3711#define CCSGADDR_MAX 0x80
3712#define TID_SHIFT 0x04
3713#define MK_MESSAGE_BIT_OFFSET 0x04
3714#define WRTBIASCTL_HP_DEFAULT 0x00
3715#define SEEOP_EWDS_ADDR 0x00
3716#define AHD_AMPLITUDE_SHIFT 0x00
3717#define AHD_AMPLITUDE_MASK 0x07
3718#define AHD_ANNEXCOL_AMPLITUDE 0x06
3719#define AHD_SLEWRATE_DEF_REVA 0x08
3720#define AHD_SLEWRATE_SHIFT 0x03
3721#define AHD_SLEWRATE_MASK 0x78
3722#define AHD_PRECOMP_CUTBACK_29 0x06
3723#define AHD_NUM_PER_DEV_ANNEXCOLS 0x04
3724#define B_CURRFIFO_0 0x02
3725#define LUNLEN_SINGLE_LEVEL_LUN 0x0f
3726#define NVRAM_SCB_OFFSET 0x2c
3727#define AHD_TIMER_MAX_US 0x18ffe7
3728#define AHD_TIMER_MAX_TICKS 0xffff
3729#define STATUS_PKT_SENSE 0xff
3730#define CMD_GROUP_CODE_SHIFT 0x05
3731#define AHD_SENSE_BUFSIZE 0x100
3732#define MAX_OFFSET_PACED_BUG 0x7f
3733#define BUS_8_BIT 0x00
3734#define STIMESEL_BUG_ADJ 0x08
3735#define STIMESEL_MIN 0x18
3736#define STIMESEL_SHIFT 0x03
3737#define CCSGRAM_MAXSEGS 0x10
3738#define INVALID_ADDR 0x80
3739#define TARGET_CMD_CMPLT 0xfe
3740#define SEEOP_WRAL_ADDR 0x40
3741#define SEEOP_ERAL_ADDR 0x80
3742#define AHD_AMPLITUDE_DEF 0x07
3743#define AHD_SLEWRATE_DEF_REVB 0x08
3744#define AHD_PRECOMP_CUTBACK_37 0x07
3745#define AHD_PRECOMP_CUTBACK_17 0x04
3746#define AHD_PRECOMP_SHIFT 0x00
3747#define AHD_PRECOMP_MASK 0x07
3748#define AHD_ANNEXCOL_PRECOMP_SLEW 0x04
3749#define SRC_MODE_SHIFT 0x00
3750#define PKT_OVERRUN_BUFSIZE 0x200
3751#define SCB_TRANSFER_SIZE_1BYTE_LUN 0x30
3752#define TARGET_DATA_IN 0x01
3753#define HOST_MSG 0xff
3754#define MAX_OFFSET 0xfe
3755#define BUS_16_BIT 0x01
3756#define CCSCBADDR_MAX 0x80
3757#define NUMDSPS 0x14
3758#define SEEOP_EWEN_ADDR 0xc0
3759#define AHD_ANNEXCOL_PER_DEV0 0x04
3760#define DST_MODE_SHIFT 0x04
3761
3762
3763/* Downloaded Constant Definitions */
3764#define SCB_TRANSFER_SIZE 0x06
3765#define PKT_OVERRUN_BUFOFFSET 0x05
3766#define SG_SIZEOF 0x04
3767#define SG_PREFETCH_ADDR_MASK 0x03
3768#define SG_PREFETCH_ALIGN_MASK 0x02
3769#define SG_PREFETCH_CNT_LIMIT 0x01
3770#define SG_PREFETCH_CNT 0x00
3771#define DOWNLOAD_CONST_COUNT 0x07
3772
3773
3774/* Exported Labels */
3775#define LABEL_seq_isr 0x269
3776#define LABEL_timer_isr 0x265
diff --git a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
new file mode 100644
index 000000000000..3098a757e3d7
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
@@ -0,0 +1,3635 @@
1/*
2 * DO NOT EDIT - This file is automatically generated
3 * from the following source files:
4 *
5 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
6 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
7 */
8
9#include "aic79xx_osm.h"
10
11static ahd_reg_parse_entry_t MODE_PTR_parse_table[] = {
12 { "SRC_MODE", 0x07, 0x07 },
13 { "DST_MODE", 0x70, 0x70 }
14};
15
16int
17ahd_mode_ptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
18{
19 return (ahd_print_register(MODE_PTR_parse_table, 2, "MODE_PTR",
20 0x00, regvalue, cur_col, wrap));
21}
22
23static ahd_reg_parse_entry_t INTSTAT_parse_table[] = {
24 { "SPLTINT", 0x01, 0x01 },
25 { "CMDCMPLT", 0x02, 0x02 },
26 { "SEQINT", 0x04, 0x04 },
27 { "SCSIINT", 0x08, 0x08 },
28 { "PCIINT", 0x10, 0x10 },
29 { "SWTMINT", 0x20, 0x20 },
30 { "BRKADRINT", 0x40, 0x40 },
31 { "HWERRINT", 0x80, 0x80 },
32 { "INT_PEND", 0xff, 0xff }
33};
34
35int
36ahd_intstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
37{
38 return (ahd_print_register(INTSTAT_parse_table, 9, "INTSTAT",
39 0x01, regvalue, cur_col, wrap));
40}
41
42static ahd_reg_parse_entry_t SEQINTCODE_parse_table[] = {
43 { "NO_SEQINT", 0x00, 0xff },
44 { "BAD_PHASE", 0x01, 0xff },
45 { "SEND_REJECT", 0x02, 0xff },
46 { "PROTO_VIOLATION", 0x03, 0xff },
47 { "NO_MATCH", 0x04, 0xff },
48 { "IGN_WIDE_RES", 0x05, 0xff },
49 { "PDATA_REINIT", 0x06, 0xff },
50 { "HOST_MSG_LOOP", 0x07, 0xff },
51 { "BAD_STATUS", 0x08, 0xff },
52 { "DATA_OVERRUN", 0x09, 0xff },
53 { "MKMSG_FAILED", 0x0a, 0xff },
54 { "MISSED_BUSFREE", 0x0b, 0xff },
55 { "DUMP_CARD_STATE", 0x0c, 0xff },
56 { "ILLEGAL_PHASE", 0x0d, 0xff },
57 { "INVALID_SEQINT", 0x0e, 0xff },
58 { "CFG4ISTAT_INTR", 0x0f, 0xff },
59 { "STATUS_OVERRUN", 0x10, 0xff },
60 { "CFG4OVERRUN", 0x11, 0xff },
61 { "ENTERING_NONPACK", 0x12, 0xff },
62 { "TASKMGMT_FUNC_COMPLETE",0x13, 0xff },
63 { "TASKMGMT_CMD_CMPLT_OKAY",0x14, 0xff },
64 { "TRACEPOINT0", 0x15, 0xff },
65 { "TRACEPOINT1", 0x16, 0xff },
66 { "TRACEPOINT2", 0x17, 0xff },
67 { "TRACEPOINT3", 0x18, 0xff },
68 { "SAW_HWERR", 0x19, 0xff },
69 { "BAD_SCB_STATUS", 0x1a, 0xff }
70};
71
72int
73ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap)
74{
75 return (ahd_print_register(SEQINTCODE_parse_table, 27, "SEQINTCODE",
76 0x02, regvalue, cur_col, wrap));
77}
78
79static ahd_reg_parse_entry_t CLRINT_parse_table[] = {
80 { "CLRSPLTINT", 0x01, 0x01 },
81 { "CLRCMDINT", 0x02, 0x02 },
82 { "CLRSEQINT", 0x04, 0x04 },
83 { "CLRSCSIINT", 0x08, 0x08 },
84 { "CLRPCIINT", 0x10, 0x10 },
85 { "CLRSWTMINT", 0x20, 0x20 },
86 { "CLRBRKADRINT", 0x40, 0x40 },
87 { "CLRHWERRINT", 0x80, 0x80 }
88};
89
90int
91ahd_clrint_print(u_int regvalue, u_int *cur_col, u_int wrap)
92{
93 return (ahd_print_register(CLRINT_parse_table, 8, "CLRINT",
94 0x03, regvalue, cur_col, wrap));
95}
96
97static ahd_reg_parse_entry_t ERROR_parse_table[] = {
98 { "DSCTMOUT", 0x02, 0x02 },
99 { "ILLOPCODE", 0x04, 0x04 },
100 { "SQPARERR", 0x08, 0x08 },
101 { "DPARERR", 0x10, 0x10 },
102 { "MPARERR", 0x20, 0x20 },
103 { "CIOACCESFAIL", 0x40, 0x40 },
104 { "CIOPARERR", 0x80, 0x80 }
105};
106
107int
108ahd_error_print(u_int regvalue, u_int *cur_col, u_int wrap)
109{
110 return (ahd_print_register(ERROR_parse_table, 7, "ERROR",
111 0x04, regvalue, cur_col, wrap));
112}
113
114static ahd_reg_parse_entry_t CLRERR_parse_table[] = {
115 { "CLRDSCTMOUT", 0x02, 0x02 },
116 { "CLRILLOPCODE", 0x04, 0x04 },
117 { "CLRSQPARERR", 0x08, 0x08 },
118 { "CLRDPARERR", 0x10, 0x10 },
119 { "CLRMPARERR", 0x20, 0x20 },
120 { "CLRCIOACCESFAIL", 0x40, 0x40 },
121 { "CLRCIOPARERR", 0x80, 0x80 }
122};
123
124int
125ahd_clrerr_print(u_int regvalue, u_int *cur_col, u_int wrap)
126{
127 return (ahd_print_register(CLRERR_parse_table, 7, "CLRERR",
128 0x04, regvalue, cur_col, wrap));
129}
130
131static ahd_reg_parse_entry_t HCNTRL_parse_table[] = {
132 { "CHIPRST", 0x01, 0x01 },
133 { "CHIPRSTACK", 0x01, 0x01 },
134 { "INTEN", 0x02, 0x02 },
135 { "PAUSE", 0x04, 0x04 },
136 { "SWTIMER_START_B", 0x08, 0x08 },
137 { "SWINT", 0x10, 0x10 },
138 { "POWRDN", 0x40, 0x40 },
139 { "SEQ_RESET", 0x80, 0x80 }
140};
141
142int
143ahd_hcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
144{
145 return (ahd_print_register(HCNTRL_parse_table, 8, "HCNTRL",
146 0x05, regvalue, cur_col, wrap));
147}
148
149int
150ahd_hnscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
151{
152 return (ahd_print_register(NULL, 0, "HNSCB_QOFF",
153 0x06, regvalue, cur_col, wrap));
154}
155
156int
157ahd_hescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
158{
159 return (ahd_print_register(NULL, 0, "HESCB_QOFF",
160 0x08, regvalue, cur_col, wrap));
161}
162
163static ahd_reg_parse_entry_t HS_MAILBOX_parse_table[] = {
164 { "ENINT_COALESCE", 0x40, 0x40 },
165 { "HOST_TQINPOS", 0x80, 0x80 }
166};
167
168int
169ahd_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap)
170{
171 return (ahd_print_register(HS_MAILBOX_parse_table, 2, "HS_MAILBOX",
172 0x0b, regvalue, cur_col, wrap));
173}
174
175static ahd_reg_parse_entry_t CLRSEQINTSTAT_parse_table[] = {
176 { "CLRSEQ_SPLTINT", 0x01, 0x01 },
177 { "CLRSEQ_PCIINT", 0x02, 0x02 },
178 { "CLRSEQ_SCSIINT", 0x04, 0x04 },
179 { "CLRSEQ_SEQINT", 0x08, 0x08 },
180 { "CLRSEQ_SWTMRTO", 0x10, 0x10 }
181};
182
183int
184ahd_clrseqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
185{
186 return (ahd_print_register(CLRSEQINTSTAT_parse_table, 5, "CLRSEQINTSTAT",
187 0x0c, regvalue, cur_col, wrap));
188}
189
190static ahd_reg_parse_entry_t SEQINTSTAT_parse_table[] = {
191 { "SEQ_SPLTINT", 0x01, 0x01 },
192 { "SEQ_PCIINT", 0x02, 0x02 },
193 { "SEQ_SCSIINT", 0x04, 0x04 },
194 { "SEQ_SEQINT", 0x08, 0x08 },
195 { "SEQ_SWTMRTO", 0x10, 0x10 }
196};
197
198int
199ahd_seqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
200{
201 return (ahd_print_register(SEQINTSTAT_parse_table, 5, "SEQINTSTAT",
202 0x0c, regvalue, cur_col, wrap));
203}
204
205int
206ahd_swtimer_print(u_int regvalue, u_int *cur_col, u_int wrap)
207{
208 return (ahd_print_register(NULL, 0, "SWTIMER",
209 0x0e, regvalue, cur_col, wrap));
210}
211
212int
213ahd_snscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
214{
215 return (ahd_print_register(NULL, 0, "SNSCB_QOFF",
216 0x10, regvalue, cur_col, wrap));
217}
218
219int
220ahd_sescb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
221{
222 return (ahd_print_register(NULL, 0, "SESCB_QOFF",
223 0x12, regvalue, cur_col, wrap));
224}
225
226int
227ahd_sdscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
228{
229 return (ahd_print_register(NULL, 0, "SDSCB_QOFF",
230 0x14, regvalue, cur_col, wrap));
231}
232
233static ahd_reg_parse_entry_t QOFF_CTLSTA_parse_table[] = {
234 { "SCB_QSIZE_4", 0x00, 0x0f },
235 { "SCB_QSIZE_8", 0x01, 0x0f },
236 { "SCB_QSIZE_16", 0x02, 0x0f },
237 { "SCB_QSIZE_32", 0x03, 0x0f },
238 { "SCB_QSIZE_64", 0x04, 0x0f },
239 { "SCB_QSIZE_128", 0x05, 0x0f },
240 { "SCB_QSIZE_256", 0x06, 0x0f },
241 { "SCB_QSIZE_512", 0x07, 0x0f },
242 { "SCB_QSIZE_1024", 0x08, 0x0f },
243 { "SCB_QSIZE_2048", 0x09, 0x0f },
244 { "SCB_QSIZE_4096", 0x0a, 0x0f },
245 { "SCB_QSIZE_8192", 0x0b, 0x0f },
246 { "SCB_QSIZE_16384", 0x0c, 0x0f },
247 { "SCB_QSIZE", 0x0f, 0x0f },
248 { "HS_MAILBOX_ACT", 0x10, 0x10 },
249 { "SDSCB_ROLLOVR", 0x20, 0x20 },
250 { "NEW_SCB_AVAIL", 0x40, 0x40 },
251 { "EMPTY_SCB_AVAIL", 0x80, 0x80 }
252};
253
254int
255ahd_qoff_ctlsta_print(u_int regvalue, u_int *cur_col, u_int wrap)
256{
257 return (ahd_print_register(QOFF_CTLSTA_parse_table, 18, "QOFF_CTLSTA",
258 0x16, regvalue, cur_col, wrap));
259}
260
261static ahd_reg_parse_entry_t INTCTL_parse_table[] = {
262 { "SPLTINTEN", 0x01, 0x01 },
263 { "SEQINTEN", 0x02, 0x02 },
264 { "SCSIINTEN", 0x04, 0x04 },
265 { "PCIINTEN", 0x08, 0x08 },
266 { "AUTOCLRCMDINT", 0x10, 0x10 },
267 { "SWTIMER_START", 0x20, 0x20 },
268 { "SWTMINTEN", 0x40, 0x40 },
269 { "SWTMINTMASK", 0x80, 0x80 }
270};
271
272int
273ahd_intctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
274{
275 return (ahd_print_register(INTCTL_parse_table, 8, "INTCTL",
276 0x18, regvalue, cur_col, wrap));
277}
278
279static ahd_reg_parse_entry_t DFCNTRL_parse_table[] = {
280 { "DIRECTIONEN", 0x01, 0x01 },
281 { "FIFOFLUSH", 0x02, 0x02 },
282 { "FIFOFLUSHACK", 0x02, 0x02 },
283 { "DIRECTION", 0x04, 0x04 },
284 { "DIRECTIONACK", 0x04, 0x04 },
285 { "HDMAEN", 0x08, 0x08 },
286 { "HDMAENACK", 0x08, 0x08 },
287 { "SCSIEN", 0x20, 0x20 },
288 { "SCSIENACK", 0x20, 0x20 },
289 { "SCSIENWRDIS", 0x40, 0x40 },
290 { "PRELOADEN", 0x80, 0x80 }
291};
292
293int
294ahd_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
295{
296 return (ahd_print_register(DFCNTRL_parse_table, 11, "DFCNTRL",
297 0x19, regvalue, cur_col, wrap));
298}
299
300static ahd_reg_parse_entry_t DSCOMMAND0_parse_table[] = {
301 { "CIOPARCKEN", 0x01, 0x01 },
302 { "DISABLE_TWATE", 0x02, 0x02 },
303 { "EXTREQLCK", 0x10, 0x10 },
304 { "MPARCKEN", 0x20, 0x20 },
305 { "DPARCKEN", 0x40, 0x40 },
306 { "CACHETHEN", 0x80, 0x80 }
307};
308
309int
310ahd_dscommand0_print(u_int regvalue, u_int *cur_col, u_int wrap)
311{
312 return (ahd_print_register(DSCOMMAND0_parse_table, 6, "DSCOMMAND0",
313 0x19, regvalue, cur_col, wrap));
314}
315
316static ahd_reg_parse_entry_t DFSTATUS_parse_table[] = {
317 { "FIFOEMP", 0x01, 0x01 },
318 { "FIFOFULL", 0x02, 0x02 },
319 { "DFTHRESH", 0x04, 0x04 },
320 { "HDONE", 0x08, 0x08 },
321 { "MREQPEND", 0x10, 0x10 },
322 { "PKT_PRELOAD_AVAIL", 0x40, 0x40 },
323 { "PRELOAD_AVAIL", 0x80, 0x80 }
324};
325
326int
327ahd_dfstatus_print(u_int regvalue, u_int *cur_col, u_int wrap)
328{
329 return (ahd_print_register(DFSTATUS_parse_table, 7, "DFSTATUS",
330 0x1a, regvalue, cur_col, wrap));
331}
332
333static ahd_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = {
334 { "LAST_SEG_DONE", 0x01, 0x01 },
335 { "LAST_SEG", 0x02, 0x02 },
336 { "ODD_SEG", 0x04, 0x04 },
337 { "SG_ADDR_MASK", 0xf8, 0xf8 }
338};
339
340int
341ahd_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap)
342{
343 return (ahd_print_register(SG_CACHE_SHADOW_parse_table, 4, "SG_CACHE_SHADOW",
344 0x1b, regvalue, cur_col, wrap));
345}
346
347static ahd_reg_parse_entry_t ARBCTL_parse_table[] = {
348 { "USE_TIME", 0x07, 0x07 },
349 { "RETRY_SWEN", 0x08, 0x08 },
350 { "RESET_HARB", 0x80, 0x80 }
351};
352
353int
354ahd_arbctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
355{
356 return (ahd_print_register(ARBCTL_parse_table, 3, "ARBCTL",
357 0x1b, regvalue, cur_col, wrap));
358}
359
360static ahd_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = {
361 { "LAST_SEG", 0x02, 0x02 },
362 { "ODD_SEG", 0x04, 0x04 },
363 { "SG_ADDR_MASK", 0xf8, 0xf8 }
364};
365
366int
367ahd_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap)
368{
369 return (ahd_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE",
370 0x1b, regvalue, cur_col, wrap));
371}
372
373int
374ahd_lqin_print(u_int regvalue, u_int *cur_col, u_int wrap)
375{
376 return (ahd_print_register(NULL, 0, "LQIN",
377 0x20, regvalue, cur_col, wrap));
378}
379
380int
381ahd_typeptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
382{
383 return (ahd_print_register(NULL, 0, "TYPEPTR",
384 0x20, regvalue, cur_col, wrap));
385}
386
387int
388ahd_tagptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
389{
390 return (ahd_print_register(NULL, 0, "TAGPTR",
391 0x21, regvalue, cur_col, wrap));
392}
393
394int
395ahd_lunptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
396{
397 return (ahd_print_register(NULL, 0, "LUNPTR",
398 0x22, regvalue, cur_col, wrap));
399}
400
401int
402ahd_datalenptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
403{
404 return (ahd_print_register(NULL, 0, "DATALENPTR",
405 0x23, regvalue, cur_col, wrap));
406}
407
408int
409ahd_statlenptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
410{
411 return (ahd_print_register(NULL, 0, "STATLENPTR",
412 0x24, regvalue, cur_col, wrap));
413}
414
415int
416ahd_cmdlenptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
417{
418 return (ahd_print_register(NULL, 0, "CMDLENPTR",
419 0x25, regvalue, cur_col, wrap));
420}
421
422int
423ahd_attrptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
424{
425 return (ahd_print_register(NULL, 0, "ATTRPTR",
426 0x26, regvalue, cur_col, wrap));
427}
428
429int
430ahd_flagptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
431{
432 return (ahd_print_register(NULL, 0, "FLAGPTR",
433 0x27, regvalue, cur_col, wrap));
434}
435
436int
437ahd_cmdptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
438{
439 return (ahd_print_register(NULL, 0, "CMDPTR",
440 0x28, regvalue, cur_col, wrap));
441}
442
443int
444ahd_qnextptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
445{
446 return (ahd_print_register(NULL, 0, "QNEXTPTR",
447 0x29, regvalue, cur_col, wrap));
448}
449
450int
451ahd_idptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
452{
453 return (ahd_print_register(NULL, 0, "IDPTR",
454 0x2a, regvalue, cur_col, wrap));
455}
456
457int
458ahd_abrtbyteptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
459{
460 return (ahd_print_register(NULL, 0, "ABRTBYTEPTR",
461 0x2b, regvalue, cur_col, wrap));
462}
463
464int
465ahd_abrtbitptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
466{
467 return (ahd_print_register(NULL, 0, "ABRTBITPTR",
468 0x2c, regvalue, cur_col, wrap));
469}
470
471int
472ahd_maxcmdbytes_print(u_int regvalue, u_int *cur_col, u_int wrap)
473{
474 return (ahd_print_register(NULL, 0, "MAXCMDBYTES",
475 0x2d, regvalue, cur_col, wrap));
476}
477
478int
479ahd_maxcmd2rcv_print(u_int regvalue, u_int *cur_col, u_int wrap)
480{
481 return (ahd_print_register(NULL, 0, "MAXCMD2RCV",
482 0x2e, regvalue, cur_col, wrap));
483}
484
485int
486ahd_shortthresh_print(u_int regvalue, u_int *cur_col, u_int wrap)
487{
488 return (ahd_print_register(NULL, 0, "SHORTTHRESH",
489 0x2f, regvalue, cur_col, wrap));
490}
491
492static ahd_reg_parse_entry_t LUNLEN_parse_table[] = {
493 { "ILUNLEN", 0x0f, 0x0f },
494 { "TLUNLEN", 0xf0, 0xf0 }
495};
496
497int
498ahd_lunlen_print(u_int regvalue, u_int *cur_col, u_int wrap)
499{
500 return (ahd_print_register(LUNLEN_parse_table, 2, "LUNLEN",
501 0x30, regvalue, cur_col, wrap));
502}
503
504int
505ahd_cdblimit_print(u_int regvalue, u_int *cur_col, u_int wrap)
506{
507 return (ahd_print_register(NULL, 0, "CDBLIMIT",
508 0x31, regvalue, cur_col, wrap));
509}
510
511int
512ahd_maxcmd_print(u_int regvalue, u_int *cur_col, u_int wrap)
513{
514 return (ahd_print_register(NULL, 0, "MAXCMD",
515 0x32, regvalue, cur_col, wrap));
516}
517
518int
519ahd_maxcmdcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
520{
521 return (ahd_print_register(NULL, 0, "MAXCMDCNT",
522 0x33, regvalue, cur_col, wrap));
523}
524
525int
526ahd_lqrsvd01_print(u_int regvalue, u_int *cur_col, u_int wrap)
527{
528 return (ahd_print_register(NULL, 0, "LQRSVD01",
529 0x34, regvalue, cur_col, wrap));
530}
531
532int
533ahd_lqrsvd16_print(u_int regvalue, u_int *cur_col, u_int wrap)
534{
535 return (ahd_print_register(NULL, 0, "LQRSVD16",
536 0x35, regvalue, cur_col, wrap));
537}
538
539int
540ahd_lqrsvd17_print(u_int regvalue, u_int *cur_col, u_int wrap)
541{
542 return (ahd_print_register(NULL, 0, "LQRSVD17",
543 0x36, regvalue, cur_col, wrap));
544}
545
546int
547ahd_cmdrsvd0_print(u_int regvalue, u_int *cur_col, u_int wrap)
548{
549 return (ahd_print_register(NULL, 0, "CMDRSVD0",
550 0x37, regvalue, cur_col, wrap));
551}
552
553static ahd_reg_parse_entry_t LQCTL0_parse_table[] = {
554 { "LQ0INITGCLT", 0x03, 0x03 },
555 { "LQ0TARGCLT", 0x0c, 0x0c },
556 { "LQIINITGCLT", 0x30, 0x30 },
557 { "LQITARGCLT", 0xc0, 0xc0 }
558};
559
560int
561ahd_lqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
562{
563 return (ahd_print_register(LQCTL0_parse_table, 4, "LQCTL0",
564 0x38, regvalue, cur_col, wrap));
565}
566
567static ahd_reg_parse_entry_t LQCTL1_parse_table[] = {
568 { "ABORTPENDING", 0x01, 0x01 },
569 { "SINGLECMD", 0x02, 0x02 },
570 { "PCI2PCI", 0x04, 0x04 }
571};
572
573int
574ahd_lqctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
575{
576 return (ahd_print_register(LQCTL1_parse_table, 3, "LQCTL1",
577 0x38, regvalue, cur_col, wrap));
578}
579
580static ahd_reg_parse_entry_t SCSBIST0_parse_table[] = {
581 { "OSBISTRUN", 0x01, 0x01 },
582 { "OSBISTDONE", 0x02, 0x02 },
583 { "OSBISTERR", 0x04, 0x04 },
584 { "GSBISTRUN", 0x10, 0x10 },
585 { "GSBISTDONE", 0x20, 0x20 },
586 { "GSBISTERR", 0x40, 0x40 }
587};
588
589int
590ahd_scsbist0_print(u_int regvalue, u_int *cur_col, u_int wrap)
591{
592 return (ahd_print_register(SCSBIST0_parse_table, 6, "SCSBIST0",
593 0x39, regvalue, cur_col, wrap));
594}
595
596static ahd_reg_parse_entry_t LQCTL2_parse_table[] = {
597 { "LQOPAUSE", 0x01, 0x01 },
598 { "LQOTOIDLE", 0x02, 0x02 },
599 { "LQOCONTINUE", 0x04, 0x04 },
600 { "LQORETRY", 0x08, 0x08 },
601 { "LQIPAUSE", 0x10, 0x10 },
602 { "LQITOIDLE", 0x20, 0x20 },
603 { "LQICONTINUE", 0x40, 0x40 },
604 { "LQIRETRY", 0x80, 0x80 }
605};
606
607int
608ahd_lqctl2_print(u_int regvalue, u_int *cur_col, u_int wrap)
609{
610 return (ahd_print_register(LQCTL2_parse_table, 8, "LQCTL2",
611 0x39, regvalue, cur_col, wrap));
612}
613
614static ahd_reg_parse_entry_t SCSBIST1_parse_table[] = {
615 { "NTBISTRUN", 0x01, 0x01 },
616 { "NTBISTDONE", 0x02, 0x02 },
617 { "NTBISTERR", 0x04, 0x04 }
618};
619
620int
621ahd_scsbist1_print(u_int regvalue, u_int *cur_col, u_int wrap)
622{
623 return (ahd_print_register(SCSBIST1_parse_table, 3, "SCSBIST1",
624 0x3a, regvalue, cur_col, wrap));
625}
626
627static ahd_reg_parse_entry_t SCSISEQ0_parse_table[] = {
628 { "SCSIRSTO", 0x01, 0x01 },
629 { "FORCEBUSFREE", 0x10, 0x10 },
630 { "ENARBO", 0x20, 0x20 },
631 { "ENSELO", 0x40, 0x40 },
632 { "TEMODEO", 0x80, 0x80 }
633};
634
635int
636ahd_scsiseq0_print(u_int regvalue, u_int *cur_col, u_int wrap)
637{
638 return (ahd_print_register(SCSISEQ0_parse_table, 5, "SCSISEQ0",
639 0x3a, regvalue, cur_col, wrap));
640}
641
642static ahd_reg_parse_entry_t SCSISEQ1_parse_table[] = {
643 { "ALTSTIM", 0x01, 0x01 },
644 { "ENAUTOATNP", 0x02, 0x02 },
645 { "MANUALP", 0x0c, 0x0c },
646 { "ENRSELI", 0x10, 0x10 },
647 { "ENSELI", 0x20, 0x20 },
648 { "MANUALCTL", 0x40, 0x40 }
649};
650
651int
652ahd_scsiseq1_print(u_int regvalue, u_int *cur_col, u_int wrap)
653{
654 return (ahd_print_register(SCSISEQ1_parse_table, 6, "SCSISEQ1",
655 0x3b, regvalue, cur_col, wrap));
656}
657
658static ahd_reg_parse_entry_t SXFRCTL0_parse_table[] = {
659 { "SPIOEN", 0x08, 0x08 },
660 { "BIOSCANCELEN", 0x10, 0x10 },
661 { "DFPEXP", 0x40, 0x40 },
662 { "DFON", 0x80, 0x80 }
663};
664
665int
666ahd_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
667{
668 return (ahd_print_register(SXFRCTL0_parse_table, 4, "SXFRCTL0",
669 0x3c, regvalue, cur_col, wrap));
670}
671
672int
673ahd_businitid_print(u_int regvalue, u_int *cur_col, u_int wrap)
674{
675 return (ahd_print_register(NULL, 0, "BUSINITID",
676 0x3c, regvalue, cur_col, wrap));
677}
678
679int
680ahd_dlcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
681{
682 return (ahd_print_register(NULL, 0, "DLCOUNT",
683 0x3c, regvalue, cur_col, wrap));
684}
685
686static ahd_reg_parse_entry_t SXFRCTL1_parse_table[] = {
687 { "STPWEN", 0x01, 0x01 },
688 { "ACTNEGEN", 0x02, 0x02 },
689 { "ENSTIMER", 0x04, 0x04 },
690 { "STIMESEL", 0x18, 0x18 },
691 { "ENSPCHK", 0x20, 0x20 },
692 { "ENSACHK", 0x40, 0x40 },
693 { "BITBUCKET", 0x80, 0x80 }
694};
695
696int
697ahd_sxfrctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
698{
699 return (ahd_print_register(SXFRCTL1_parse_table, 7, "SXFRCTL1",
700 0x3d, regvalue, cur_col, wrap));
701}
702
703int
704ahd_bustargid_print(u_int regvalue, u_int *cur_col, u_int wrap)
705{
706 return (ahd_print_register(NULL, 0, "BUSTARGID",
707 0x3e, regvalue, cur_col, wrap));
708}
709
710static ahd_reg_parse_entry_t SXFRCTL2_parse_table[] = {
711 { "ASU", 0x07, 0x07 },
712 { "CMDDMAEN", 0x08, 0x08 },
713 { "AUTORSTDIS", 0x10, 0x10 }
714};
715
716int
717ahd_sxfrctl2_print(u_int regvalue, u_int *cur_col, u_int wrap)
718{
719 return (ahd_print_register(SXFRCTL2_parse_table, 3, "SXFRCTL2",
720 0x3e, regvalue, cur_col, wrap));
721}
722
723static ahd_reg_parse_entry_t DFFSTAT_parse_table[] = {
724 { "CURRFIFO_0", 0x00, 0x03 },
725 { "CURRFIFO_1", 0x01, 0x03 },
726 { "CURRFIFO_NONE", 0x03, 0x03 },
727 { "FIFO0FREE", 0x10, 0x10 },
728 { "FIFO1FREE", 0x20, 0x20 },
729 { "CURRFIFO", 0x03, 0x03 }
730};
731
732int
733ahd_dffstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
734{
735 return (ahd_print_register(DFFSTAT_parse_table, 6, "DFFSTAT",
736 0x3f, regvalue, cur_col, wrap));
737}
738
739static ahd_reg_parse_entry_t SCSISIGO_parse_table[] = {
740 { "P_DATAOUT", 0x00, 0xe0 },
741 { "P_DATAOUT_DT", 0x20, 0xe0 },
742 { "P_DATAIN", 0x40, 0xe0 },
743 { "P_DATAIN_DT", 0x60, 0xe0 },
744 { "P_COMMAND", 0x80, 0xe0 },
745 { "P_MESGOUT", 0xa0, 0xe0 },
746 { "P_STATUS", 0xc0, 0xe0 },
747 { "P_MESGIN", 0xe0, 0xe0 },
748 { "ACKO", 0x01, 0x01 },
749 { "REQO", 0x02, 0x02 },
750 { "BSYO", 0x04, 0x04 },
751 { "SELO", 0x08, 0x08 },
752 { "ATNO", 0x10, 0x10 },
753 { "MSGO", 0x20, 0x20 },
754 { "IOO", 0x40, 0x40 },
755 { "CDO", 0x80, 0x80 },
756 { "PHASE_MASK", 0xe0, 0xe0 }
757};
758
759int
760ahd_scsisigo_print(u_int regvalue, u_int *cur_col, u_int wrap)
761{
762 return (ahd_print_register(SCSISIGO_parse_table, 17, "SCSISIGO",
763 0x40, regvalue, cur_col, wrap));
764}
765
766int
767ahd_multargid_print(u_int regvalue, u_int *cur_col, u_int wrap)
768{
769 return (ahd_print_register(NULL, 0, "MULTARGID",
770 0x40, regvalue, cur_col, wrap));
771}
772
773static ahd_reg_parse_entry_t SCSISIGI_parse_table[] = {
774 { "P_DATAOUT", 0x00, 0xe0 },
775 { "P_DATAOUT_DT", 0x20, 0xe0 },
776 { "P_DATAIN", 0x40, 0xe0 },
777 { "P_DATAIN_DT", 0x60, 0xe0 },
778 { "P_COMMAND", 0x80, 0xe0 },
779 { "P_MESGOUT", 0xa0, 0xe0 },
780 { "P_STATUS", 0xc0, 0xe0 },
781 { "P_MESGIN", 0xe0, 0xe0 },
782 { "ACKI", 0x01, 0x01 },
783 { "REQI", 0x02, 0x02 },
784 { "BSYI", 0x04, 0x04 },
785 { "SELI", 0x08, 0x08 },
786 { "ATNI", 0x10, 0x10 },
787 { "MSGI", 0x20, 0x20 },
788 { "IOI", 0x40, 0x40 },
789 { "CDI", 0x80, 0x80 },
790 { "PHASE_MASK", 0xe0, 0xe0 }
791};
792
793int
794ahd_scsisigi_print(u_int regvalue, u_int *cur_col, u_int wrap)
795{
796 return (ahd_print_register(SCSISIGI_parse_table, 17, "SCSISIGI",
797 0x41, regvalue, cur_col, wrap));
798}
799
800static ahd_reg_parse_entry_t SCSIPHASE_parse_table[] = {
801 { "DATA_OUT_PHASE", 0x01, 0x03 },
802 { "DATA_IN_PHASE", 0x02, 0x03 },
803 { "DATA_PHASE_MASK", 0x03, 0x03 },
804 { "MSG_OUT_PHASE", 0x04, 0x04 },
805 { "MSG_IN_PHASE", 0x08, 0x08 },
806 { "COMMAND_PHASE", 0x10, 0x10 },
807 { "STATUS_PHASE", 0x20, 0x20 }
808};
809
810int
811ahd_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
812{
813 return (ahd_print_register(SCSIPHASE_parse_table, 7, "SCSIPHASE",
814 0x42, regvalue, cur_col, wrap));
815}
816
817int
818ahd_scsidat0_img_print(u_int regvalue, u_int *cur_col, u_int wrap)
819{
820 return (ahd_print_register(NULL, 0, "SCSIDAT0_IMG",
821 0x43, regvalue, cur_col, wrap));
822}
823
824int
825ahd_scsidat_print(u_int regvalue, u_int *cur_col, u_int wrap)
826{
827 return (ahd_print_register(NULL, 0, "SCSIDAT",
828 0x44, regvalue, cur_col, wrap));
829}
830
831int
832ahd_scsibus_print(u_int regvalue, u_int *cur_col, u_int wrap)
833{
834 return (ahd_print_register(NULL, 0, "SCSIBUS",
835 0x46, regvalue, cur_col, wrap));
836}
837
838static ahd_reg_parse_entry_t TARGIDIN_parse_table[] = {
839 { "TARGID", 0x0f, 0x0f },
840 { "CLKOUT", 0x80, 0x80 }
841};
842
843int
844ahd_targidin_print(u_int regvalue, u_int *cur_col, u_int wrap)
845{
846 return (ahd_print_register(TARGIDIN_parse_table, 2, "TARGIDIN",
847 0x48, regvalue, cur_col, wrap));
848}
849
850static ahd_reg_parse_entry_t SELID_parse_table[] = {
851 { "ONEBIT", 0x08, 0x08 },
852 { "SELID_MASK", 0xf0, 0xf0 }
853};
854
855int
856ahd_selid_print(u_int regvalue, u_int *cur_col, u_int wrap)
857{
858 return (ahd_print_register(SELID_parse_table, 2, "SELID",
859 0x49, regvalue, cur_col, wrap));
860}
861
862static ahd_reg_parse_entry_t SBLKCTL_parse_table[] = {
863 { "SELWIDE", 0x02, 0x02 },
864 { "ENAB20", 0x04, 0x04 },
865 { "ENAB40", 0x08, 0x08 },
866 { "DIAGLEDON", 0x40, 0x40 },
867 { "DIAGLEDEN", 0x80, 0x80 }
868};
869
870int
871ahd_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
872{
873 return (ahd_print_register(SBLKCTL_parse_table, 5, "SBLKCTL",
874 0x4a, regvalue, cur_col, wrap));
875}
876
877static ahd_reg_parse_entry_t OPTIONMODE_parse_table[] = {
878 { "AUTO_MSGOUT_DE", 0x02, 0x02 },
879 { "ENDGFORMCHK", 0x04, 0x04 },
880 { "BUSFREEREV", 0x10, 0x10 },
881 { "BIASCANCTL", 0x20, 0x20 },
882 { "AUTOACKEN", 0x40, 0x40 },
883 { "BIOSCANCTL", 0x80, 0x80 },
884 { "OPTIONMODE_DEFAULTS",0x02, 0x02 }
885};
886
887int
888ahd_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap)
889{
890 return (ahd_print_register(OPTIONMODE_parse_table, 7, "OPTIONMODE",
891 0x4a, regvalue, cur_col, wrap));
892}
893
894static ahd_reg_parse_entry_t SSTAT0_parse_table[] = {
895 { "ARBDO", 0x01, 0x01 },
896 { "SPIORDY", 0x02, 0x02 },
897 { "OVERRUN", 0x04, 0x04 },
898 { "IOERR", 0x08, 0x08 },
899 { "SELINGO", 0x10, 0x10 },
900 { "SELDI", 0x20, 0x20 },
901 { "SELDO", 0x40, 0x40 },
902 { "TARGET", 0x80, 0x80 }
903};
904
905int
906ahd_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
907{
908 return (ahd_print_register(SSTAT0_parse_table, 8, "SSTAT0",
909 0x4b, regvalue, cur_col, wrap));
910}
911
912static ahd_reg_parse_entry_t CLRSINT0_parse_table[] = {
913 { "CLRARBDO", 0x01, 0x01 },
914 { "CLRSPIORDY", 0x02, 0x02 },
915 { "CLROVERRUN", 0x04, 0x04 },
916 { "CLRIOERR", 0x08, 0x08 },
917 { "CLRSELINGO", 0x10, 0x10 },
918 { "CLRSELDI", 0x20, 0x20 },
919 { "CLRSELDO", 0x40, 0x40 }
920};
921
922int
923ahd_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
924{
925 return (ahd_print_register(CLRSINT0_parse_table, 7, "CLRSINT0",
926 0x4b, regvalue, cur_col, wrap));
927}
928
929static ahd_reg_parse_entry_t SIMODE0_parse_table[] = {
930 { "ENARBDO", 0x01, 0x01 },
931 { "ENSPIORDY", 0x02, 0x02 },
932 { "ENOVERRUN", 0x04, 0x04 },
933 { "ENIOERR", 0x08, 0x08 },
934 { "ENSELINGO", 0x10, 0x10 },
935 { "ENSELDI", 0x20, 0x20 },
936 { "ENSELDO", 0x40, 0x40 }
937};
938
939int
940ahd_simode0_print(u_int regvalue, u_int *cur_col, u_int wrap)
941{
942 return (ahd_print_register(SIMODE0_parse_table, 7, "SIMODE0",
943 0x4b, regvalue, cur_col, wrap));
944}
945
946static ahd_reg_parse_entry_t CLRSINT1_parse_table[] = {
947 { "CLRREQINIT", 0x01, 0x01 },
948 { "CLRSTRB2FAST", 0x02, 0x02 },
949 { "CLRSCSIPERR", 0x04, 0x04 },
950 { "CLRBUSFREE", 0x08, 0x08 },
951 { "CLRSCSIRSTI", 0x20, 0x20 },
952 { "CLRATNO", 0x40, 0x40 },
953 { "CLRSELTIMEO", 0x80, 0x80 }
954};
955
956int
957ahd_clrsint1_print(u_int regvalue, u_int *cur_col, u_int wrap)
958{
959 return (ahd_print_register(CLRSINT1_parse_table, 7, "CLRSINT1",
960 0x4c, regvalue, cur_col, wrap));
961}
962
963static ahd_reg_parse_entry_t SSTAT1_parse_table[] = {
964 { "REQINIT", 0x01, 0x01 },
965 { "STRB2FAST", 0x02, 0x02 },
966 { "SCSIPERR", 0x04, 0x04 },
967 { "BUSFREE", 0x08, 0x08 },
968 { "PHASEMIS", 0x10, 0x10 },
969 { "SCSIRSTI", 0x20, 0x20 },
970 { "ATNTARG", 0x40, 0x40 },
971 { "SELTO", 0x80, 0x80 }
972};
973
974int
975ahd_sstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
976{
977 return (ahd_print_register(SSTAT1_parse_table, 8, "SSTAT1",
978 0x4c, regvalue, cur_col, wrap));
979}
980
981static ahd_reg_parse_entry_t SSTAT2_parse_table[] = {
982 { "BUSFREE_LQO", 0x40, 0xc0 },
983 { "BUSFREE_DFF0", 0x80, 0xc0 },
984 { "BUSFREE_DFF1", 0xc0, 0xc0 },
985 { "DMADONE", 0x01, 0x01 },
986 { "SDONE", 0x02, 0x02 },
987 { "WIDE_RES", 0x04, 0x04 },
988 { "BSYX", 0x08, 0x08 },
989 { "EXP_ACTIVE", 0x10, 0x10 },
990 { "NONPACKREQ", 0x20, 0x20 },
991 { "BUSFREETIME", 0xc0, 0xc0 }
992};
993
994int
995ahd_sstat2_print(u_int regvalue, u_int *cur_col, u_int wrap)
996{
997 return (ahd_print_register(SSTAT2_parse_table, 10, "SSTAT2",
998 0x4d, regvalue, cur_col, wrap));
999}
1000
1001static ahd_reg_parse_entry_t CLRSINT2_parse_table[] = {
1002 { "CLRDMADONE", 0x01, 0x01 },
1003 { "CLRSDONE", 0x02, 0x02 },
1004 { "CLRWIDE_RES", 0x04, 0x04 },
1005 { "CLRNONPACKREQ", 0x20, 0x20 }
1006};
1007
1008int
1009ahd_clrsint2_print(u_int regvalue, u_int *cur_col, u_int wrap)
1010{
1011 return (ahd_print_register(CLRSINT2_parse_table, 4, "CLRSINT2",
1012 0x4d, regvalue, cur_col, wrap));
1013}
1014
1015static ahd_reg_parse_entry_t SIMODE2_parse_table[] = {
1016 { "ENDMADONE", 0x01, 0x01 },
1017 { "ENSDONE", 0x02, 0x02 },
1018 { "ENWIDE_RES", 0x04, 0x04 }
1019};
1020
1021int
1022ahd_simode2_print(u_int regvalue, u_int *cur_col, u_int wrap)
1023{
1024 return (ahd_print_register(SIMODE2_parse_table, 3, "SIMODE2",
1025 0x4d, regvalue, cur_col, wrap));
1026}
1027
1028static ahd_reg_parse_entry_t PERRDIAG_parse_table[] = {
1029 { "DTERR", 0x01, 0x01 },
1030 { "DGFORMERR", 0x02, 0x02 },
1031 { "CRCERR", 0x04, 0x04 },
1032 { "AIPERR", 0x08, 0x08 },
1033 { "PARITYERR", 0x10, 0x10 },
1034 { "PREVPHASE", 0x20, 0x20 },
1035 { "HIPERR", 0x40, 0x40 },
1036 { "HIZERO", 0x80, 0x80 }
1037};
1038
1039int
1040ahd_perrdiag_print(u_int regvalue, u_int *cur_col, u_int wrap)
1041{
1042 return (ahd_print_register(PERRDIAG_parse_table, 8, "PERRDIAG",
1043 0x4e, regvalue, cur_col, wrap));
1044}
1045
1046int
1047ahd_lqistate_print(u_int regvalue, u_int *cur_col, u_int wrap)
1048{
1049 return (ahd_print_register(NULL, 0, "LQISTATE",
1050 0x4e, regvalue, cur_col, wrap));
1051}
1052
1053int
1054ahd_soffcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1055{
1056 return (ahd_print_register(NULL, 0, "SOFFCNT",
1057 0x4f, regvalue, cur_col, wrap));
1058}
1059
1060int
1061ahd_lqostate_print(u_int regvalue, u_int *cur_col, u_int wrap)
1062{
1063 return (ahd_print_register(NULL, 0, "LQOSTATE",
1064 0x4f, regvalue, cur_col, wrap));
1065}
1066
1067static ahd_reg_parse_entry_t LQISTAT0_parse_table[] = {
1068 { "LQIATNCMD", 0x01, 0x01 },
1069 { "LQIATNLQ", 0x02, 0x02 },
1070 { "LQIBADLQT", 0x04, 0x04 },
1071 { "LQICRCT2", 0x08, 0x08 },
1072 { "LQICRCT1", 0x10, 0x10 },
1073 { "LQIATNQAS", 0x20, 0x20 }
1074};
1075
1076int
1077ahd_lqistat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1078{
1079 return (ahd_print_register(LQISTAT0_parse_table, 6, "LQISTAT0",
1080 0x50, regvalue, cur_col, wrap));
1081}
1082
1083static ahd_reg_parse_entry_t CLRLQIINT0_parse_table[] = {
1084 { "CLRLQIATNCMD", 0x01, 0x01 },
1085 { "CLRLQIATNLQ", 0x02, 0x02 },
1086 { "CLRLQIBADLQT", 0x04, 0x04 },
1087 { "CLRLQICRCT2", 0x08, 0x08 },
1088 { "CLRLQICRCT1", 0x10, 0x10 },
1089 { "CLRLQIATNQAS", 0x20, 0x20 }
1090};
1091
1092int
1093ahd_clrlqiint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1094{
1095 return (ahd_print_register(CLRLQIINT0_parse_table, 6, "CLRLQIINT0",
1096 0x50, regvalue, cur_col, wrap));
1097}
1098
1099static ahd_reg_parse_entry_t LQIMODE0_parse_table[] = {
1100 { "ENLQIATNCMD", 0x01, 0x01 },
1101 { "ENLQIATNLQ", 0x02, 0x02 },
1102 { "ENLQIBADLQT", 0x04, 0x04 },
1103 { "ENLQICRCT2", 0x08, 0x08 },
1104 { "ENLQICRCT1", 0x10, 0x10 },
1105 { "ENLQIATNQASK", 0x20, 0x20 }
1106};
1107
1108int
1109ahd_lqimode0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1110{
1111 return (ahd_print_register(LQIMODE0_parse_table, 6, "LQIMODE0",
1112 0x50, regvalue, cur_col, wrap));
1113}
1114
1115static ahd_reg_parse_entry_t LQIMODE1_parse_table[] = {
1116 { "ENLQIOVERI_NLQ", 0x01, 0x01 },
1117 { "ENLQIOVERI_LQ", 0x02, 0x02 },
1118 { "ENLQIBADLQI", 0x04, 0x04 },
1119 { "ENLQICRCI_NLQ", 0x08, 0x08 },
1120 { "ENLQICRCI_LQ", 0x10, 0x10 },
1121 { "ENLIQABORT", 0x20, 0x20 },
1122 { "ENLQIPHASE_NLQ", 0x40, 0x40 },
1123 { "ENLQIPHASE_LQ", 0x80, 0x80 }
1124};
1125
1126int
1127ahd_lqimode1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1128{
1129 return (ahd_print_register(LQIMODE1_parse_table, 8, "LQIMODE1",
1130 0x51, regvalue, cur_col, wrap));
1131}
1132
1133static ahd_reg_parse_entry_t LQISTAT1_parse_table[] = {
1134 { "LQIOVERI_NLQ", 0x01, 0x01 },
1135 { "LQIOVERI_LQ", 0x02, 0x02 },
1136 { "LQIBADLQI", 0x04, 0x04 },
1137 { "LQICRCI_NLQ", 0x08, 0x08 },
1138 { "LQICRCI_LQ", 0x10, 0x10 },
1139 { "LQIABORT", 0x20, 0x20 },
1140 { "LQIPHASE_NLQ", 0x40, 0x40 },
1141 { "LQIPHASE_LQ", 0x80, 0x80 }
1142};
1143
1144int
1145ahd_lqistat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1146{
1147 return (ahd_print_register(LQISTAT1_parse_table, 8, "LQISTAT1",
1148 0x51, regvalue, cur_col, wrap));
1149}
1150
1151static ahd_reg_parse_entry_t CLRLQIINT1_parse_table[] = {
1152 { "CLRLQIOVERI_NLQ", 0x01, 0x01 },
1153 { "CLRLQIOVERI_LQ", 0x02, 0x02 },
1154 { "CLRLQIBADLQI", 0x04, 0x04 },
1155 { "CLRLQICRCI_NLQ", 0x08, 0x08 },
1156 { "CLRLQICRCI_LQ", 0x10, 0x10 },
1157 { "CLRLIQABORT", 0x20, 0x20 },
1158 { "CLRLQIPHASE_NLQ", 0x40, 0x40 },
1159 { "CLRLQIPHASE_LQ", 0x80, 0x80 }
1160};
1161
1162int
1163ahd_clrlqiint1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1164{
1165 return (ahd_print_register(CLRLQIINT1_parse_table, 8, "CLRLQIINT1",
1166 0x51, regvalue, cur_col, wrap));
1167}
1168
1169static ahd_reg_parse_entry_t LQISTAT2_parse_table[] = {
1170 { "LQIGSAVAIL", 0x01, 0x01 },
1171 { "LQISTOPCMD", 0x02, 0x02 },
1172 { "LQISTOPLQ", 0x04, 0x04 },
1173 { "LQISTOPPKT", 0x08, 0x08 },
1174 { "LQIWAITFIFO", 0x10, 0x10 },
1175 { "LQIWORKONLQ", 0x20, 0x20 },
1176 { "LQIPHASE_OUTPKT", 0x40, 0x40 },
1177 { "PACKETIZED", 0x80, 0x80 }
1178};
1179
1180int
1181ahd_lqistat2_print(u_int regvalue, u_int *cur_col, u_int wrap)
1182{
1183 return (ahd_print_register(LQISTAT2_parse_table, 8, "LQISTAT2",
1184 0x52, regvalue, cur_col, wrap));
1185}
1186
1187static ahd_reg_parse_entry_t SSTAT3_parse_table[] = {
1188 { "OSRAMPERR", 0x01, 0x01 },
1189 { "NTRAMPERR", 0x02, 0x02 }
1190};
1191
1192int
1193ahd_sstat3_print(u_int regvalue, u_int *cur_col, u_int wrap)
1194{
1195 return (ahd_print_register(SSTAT3_parse_table, 2, "SSTAT3",
1196 0x53, regvalue, cur_col, wrap));
1197}
1198
1199static ahd_reg_parse_entry_t SIMODE3_parse_table[] = {
1200 { "ENOSRAMPERR", 0x01, 0x01 },
1201 { "ENNTRAMPERR", 0x02, 0x02 }
1202};
1203
1204int
1205ahd_simode3_print(u_int regvalue, u_int *cur_col, u_int wrap)
1206{
1207 return (ahd_print_register(SIMODE3_parse_table, 2, "SIMODE3",
1208 0x53, regvalue, cur_col, wrap));
1209}
1210
1211static ahd_reg_parse_entry_t CLRSINT3_parse_table[] = {
1212 { "CLROSRAMPERR", 0x01, 0x01 },
1213 { "CLRNTRAMPERR", 0x02, 0x02 }
1214};
1215
1216int
1217ahd_clrsint3_print(u_int regvalue, u_int *cur_col, u_int wrap)
1218{
1219 return (ahd_print_register(CLRSINT3_parse_table, 2, "CLRSINT3",
1220 0x53, regvalue, cur_col, wrap));
1221}
1222
1223static ahd_reg_parse_entry_t LQOMODE0_parse_table[] = {
1224 { "ENLQOTCRC", 0x01, 0x01 },
1225 { "ENLQOATNPKT", 0x02, 0x02 },
1226 { "ENLQOATNLQ", 0x04, 0x04 },
1227 { "ENLQOSTOPT2", 0x08, 0x08 },
1228 { "ENLQOTARGSCBPERR", 0x10, 0x10 }
1229};
1230
1231int
1232ahd_lqomode0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1233{
1234 return (ahd_print_register(LQOMODE0_parse_table, 5, "LQOMODE0",
1235 0x54, regvalue, cur_col, wrap));
1236}
1237
1238static ahd_reg_parse_entry_t LQOSTAT0_parse_table[] = {
1239 { "LQOTCRC", 0x01, 0x01 },
1240 { "LQOATNPKT", 0x02, 0x02 },
1241 { "LQOATNLQ", 0x04, 0x04 },
1242 { "LQOSTOPT2", 0x08, 0x08 },
1243 { "LQOTARGSCBPERR", 0x10, 0x10 }
1244};
1245
1246int
1247ahd_lqostat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1248{
1249 return (ahd_print_register(LQOSTAT0_parse_table, 5, "LQOSTAT0",
1250 0x54, regvalue, cur_col, wrap));
1251}
1252
1253static ahd_reg_parse_entry_t CLRLQOINT0_parse_table[] = {
1254 { "CLRLQOTCRC", 0x01, 0x01 },
1255 { "CLRLQOATNPKT", 0x02, 0x02 },
1256 { "CLRLQOATNLQ", 0x04, 0x04 },
1257 { "CLRLQOSTOPT2", 0x08, 0x08 },
1258 { "CLRLQOTARGSCBPERR", 0x10, 0x10 }
1259};
1260
1261int
1262ahd_clrlqoint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1263{
1264 return (ahd_print_register(CLRLQOINT0_parse_table, 5, "CLRLQOINT0",
1265 0x54, regvalue, cur_col, wrap));
1266}
1267
1268static ahd_reg_parse_entry_t LQOSTAT1_parse_table[] = {
1269 { "LQOPHACHGINPKT", 0x01, 0x01 },
1270 { "LQOBUSFREE", 0x02, 0x02 },
1271 { "LQOBADQAS", 0x04, 0x04 },
1272 { "LQOSTOPI2", 0x08, 0x08 },
1273 { "LQOINITSCBPERR", 0x10, 0x10 }
1274};
1275
1276int
1277ahd_lqostat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1278{
1279 return (ahd_print_register(LQOSTAT1_parse_table, 5, "LQOSTAT1",
1280 0x55, regvalue, cur_col, wrap));
1281}
1282
1283static ahd_reg_parse_entry_t CLRLQOINT1_parse_table[] = {
1284 { "CLRLQOPHACHGINPKT", 0x01, 0x01 },
1285 { "CLRLQOBUSFREE", 0x02, 0x02 },
1286 { "CLRLQOBADQAS", 0x04, 0x04 },
1287 { "CLRLQOSTOPI2", 0x08, 0x08 },
1288 { "CLRLQOINITSCBPERR", 0x10, 0x10 }
1289};
1290
1291int
1292ahd_clrlqoint1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1293{
1294 return (ahd_print_register(CLRLQOINT1_parse_table, 5, "CLRLQOINT1",
1295 0x55, regvalue, cur_col, wrap));
1296}
1297
1298static ahd_reg_parse_entry_t LQOMODE1_parse_table[] = {
1299 { "ENLQOPHACHGINPKT", 0x01, 0x01 },
1300 { "ENLQOBUSFREE", 0x02, 0x02 },
1301 { "ENLQOBADQAS", 0x04, 0x04 },
1302 { "ENLQOSTOPI2", 0x08, 0x08 },
1303 { "ENLQOINITSCBPERR", 0x10, 0x10 }
1304};
1305
1306int
1307ahd_lqomode1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1308{
1309 return (ahd_print_register(LQOMODE1_parse_table, 5, "LQOMODE1",
1310 0x55, regvalue, cur_col, wrap));
1311}
1312
1313static ahd_reg_parse_entry_t LQOSTAT2_parse_table[] = {
1314 { "LQOSTOP0", 0x01, 0x01 },
1315 { "LQOPHACHGOUTPKT", 0x02, 0x02 },
1316 { "LQOWAITFIFO", 0x10, 0x10 },
1317 { "LQOPKT", 0xe0, 0xe0 }
1318};
1319
1320int
1321ahd_lqostat2_print(u_int regvalue, u_int *cur_col, u_int wrap)
1322{
1323 return (ahd_print_register(LQOSTAT2_parse_table, 4, "LQOSTAT2",
1324 0x56, regvalue, cur_col, wrap));
1325}
1326
1327int
1328ahd_os_space_cnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1329{
1330 return (ahd_print_register(NULL, 0, "OS_SPACE_CNT",
1331 0x56, regvalue, cur_col, wrap));
1332}
1333
1334static ahd_reg_parse_entry_t SIMODE1_parse_table[] = {
1335 { "ENREQINIT", 0x01, 0x01 },
1336 { "ENSTRB2FAST", 0x02, 0x02 },
1337 { "ENSCSIPERR", 0x04, 0x04 },
1338 { "ENBUSFREE", 0x08, 0x08 },
1339 { "ENPHASEMIS", 0x10, 0x10 },
1340 { "ENSCSIRST", 0x20, 0x20 },
1341 { "ENATNTARG", 0x40, 0x40 },
1342 { "ENSELTIMO", 0x80, 0x80 }
1343};
1344
1345int
1346ahd_simode1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1347{
1348 return (ahd_print_register(SIMODE1_parse_table, 8, "SIMODE1",
1349 0x57, regvalue, cur_col, wrap));
1350}
1351
1352int
1353ahd_gsfifo_print(u_int regvalue, u_int *cur_col, u_int wrap)
1354{
1355 return (ahd_print_register(NULL, 0, "GSFIFO",
1356 0x58, regvalue, cur_col, wrap));
1357}
1358
1359static ahd_reg_parse_entry_t DFFSXFRCTL_parse_table[] = {
1360 { "RSTCHN", 0x01, 0x01 },
1361 { "CLRCHN", 0x02, 0x02 },
1362 { "CLRSHCNT", 0x04, 0x04 },
1363 { "DFFBITBUCKET", 0x08, 0x08 }
1364};
1365
1366int
1367ahd_dffsxfrctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
1368{
1369 return (ahd_print_register(DFFSXFRCTL_parse_table, 4, "DFFSXFRCTL",
1370 0x5a, regvalue, cur_col, wrap));
1371}
1372
1373static ahd_reg_parse_entry_t LQOSCSCTL_parse_table[] = {
1374 { "LQONOCHKOVER", 0x01, 0x01 },
1375 { "LQOH2A_VERSION", 0x80, 0x80 }
1376};
1377
1378int
1379ahd_lqoscsctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
1380{
1381 return (ahd_print_register(LQOSCSCTL_parse_table, 2, "LQOSCSCTL",
1382 0x5a, regvalue, cur_col, wrap));
1383}
1384
1385int
1386ahd_nextscb_print(u_int regvalue, u_int *cur_col, u_int wrap)
1387{
1388 return (ahd_print_register(NULL, 0, "NEXTSCB",
1389 0x5a, regvalue, cur_col, wrap));
1390}
1391
1392static ahd_reg_parse_entry_t CLRSEQINTSRC_parse_table[] = {
1393 { "CLRCFG4TCMD", 0x01, 0x01 },
1394 { "CLRCFG4ICMD", 0x02, 0x02 },
1395 { "CLRCFG4TSTAT", 0x04, 0x04 },
1396 { "CLRCFG4ISTAT", 0x08, 0x08 },
1397 { "CLRCFG4DATA", 0x10, 0x10 },
1398 { "CLRSAVEPTRS", 0x20, 0x20 },
1399 { "CLRCTXTDONE", 0x40, 0x40 }
1400};
1401
1402int
1403ahd_clrseqintsrc_print(u_int regvalue, u_int *cur_col, u_int wrap)
1404{
1405 return (ahd_print_register(CLRSEQINTSRC_parse_table, 7, "CLRSEQINTSRC",
1406 0x5b, regvalue, cur_col, wrap));
1407}
1408
1409static ahd_reg_parse_entry_t SEQINTSRC_parse_table[] = {
1410 { "CFG4TCMD", 0x01, 0x01 },
1411 { "CFG4ICMD", 0x02, 0x02 },
1412 { "CFG4TSTAT", 0x04, 0x04 },
1413 { "CFG4ISTAT", 0x08, 0x08 },
1414 { "CFG4DATA", 0x10, 0x10 },
1415 { "SAVEPTRS", 0x20, 0x20 },
1416 { "CTXTDONE", 0x40, 0x40 }
1417};
1418
1419int
1420ahd_seqintsrc_print(u_int regvalue, u_int *cur_col, u_int wrap)
1421{
1422 return (ahd_print_register(SEQINTSRC_parse_table, 7, "SEQINTSRC",
1423 0x5b, regvalue, cur_col, wrap));
1424}
1425
1426int
1427ahd_currscb_print(u_int regvalue, u_int *cur_col, u_int wrap)
1428{
1429 return (ahd_print_register(NULL, 0, "CURRSCB",
1430 0x5c, regvalue, cur_col, wrap));
1431}
1432
1433static ahd_reg_parse_entry_t SEQIMODE_parse_table[] = {
1434 { "ENCFG4TCMD", 0x01, 0x01 },
1435 { "ENCFG4ICMD", 0x02, 0x02 },
1436 { "ENCFG4TSTAT", 0x04, 0x04 },
1437 { "ENCFG4ISTAT", 0x08, 0x08 },
1438 { "ENCFG4DATA", 0x10, 0x10 },
1439 { "ENSAVEPTRS", 0x20, 0x20 },
1440 { "ENCTXTDONE", 0x40, 0x40 }
1441};
1442
1443int
1444ahd_seqimode_print(u_int regvalue, u_int *cur_col, u_int wrap)
1445{
1446 return (ahd_print_register(SEQIMODE_parse_table, 7, "SEQIMODE",
1447 0x5c, regvalue, cur_col, wrap));
1448}
1449
1450static ahd_reg_parse_entry_t MDFFSTAT_parse_table[] = {
1451 { "FIFOFREE", 0x01, 0x01 },
1452 { "DATAINFIFO", 0x02, 0x02 },
1453 { "DLZERO", 0x04, 0x04 },
1454 { "SHVALID", 0x08, 0x08 },
1455 { "LASTSDONE", 0x10, 0x10 },
1456 { "SHCNTMINUS1", 0x20, 0x20 },
1457 { "SHCNTNEGATIVE", 0x40, 0x40 }
1458};
1459
1460int
1461ahd_mdffstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
1462{
1463 return (ahd_print_register(MDFFSTAT_parse_table, 7, "MDFFSTAT",
1464 0x5d, regvalue, cur_col, wrap));
1465}
1466
1467static ahd_reg_parse_entry_t CRCCONTROL_parse_table[] = {
1468 { "CRCVALCHKEN", 0x40, 0x40 }
1469};
1470
1471int
1472ahd_crccontrol_print(u_int regvalue, u_int *cur_col, u_int wrap)
1473{
1474 return (ahd_print_register(CRCCONTROL_parse_table, 1, "CRCCONTROL",
1475 0x5d, regvalue, cur_col, wrap));
1476}
1477
1478int
1479ahd_dfftag_print(u_int regvalue, u_int *cur_col, u_int wrap)
1480{
1481 return (ahd_print_register(NULL, 0, "DFFTAG",
1482 0x5e, regvalue, cur_col, wrap));
1483}
1484
1485int
1486ahd_lastscb_print(u_int regvalue, u_int *cur_col, u_int wrap)
1487{
1488 return (ahd_print_register(NULL, 0, "LASTSCB",
1489 0x5e, regvalue, cur_col, wrap));
1490}
1491
1492static ahd_reg_parse_entry_t SCSITEST_parse_table[] = {
1493 { "SEL_TXPLL_DEBUG", 0x04, 0x04 },
1494 { "CNTRTEST", 0x08, 0x08 }
1495};
1496
1497int
1498ahd_scsitest_print(u_int regvalue, u_int *cur_col, u_int wrap)
1499{
1500 return (ahd_print_register(SCSITEST_parse_table, 2, "SCSITEST",
1501 0x5e, regvalue, cur_col, wrap));
1502}
1503
1504static ahd_reg_parse_entry_t IOPDNCTL_parse_table[] = {
1505 { "PDN_DIFFSENSE", 0x01, 0x01 },
1506 { "PDN_IDIST", 0x04, 0x04 },
1507 { "DISABLE_OE", 0x80, 0x80 }
1508};
1509
1510int
1511ahd_iopdnctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
1512{
1513 return (ahd_print_register(IOPDNCTL_parse_table, 3, "IOPDNCTL",
1514 0x5f, regvalue, cur_col, wrap));
1515}
1516
1517int
1518ahd_shaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1519{
1520 return (ahd_print_register(NULL, 0, "SHADDR",
1521 0x60, regvalue, cur_col, wrap));
1522}
1523
1524int
1525ahd_negoaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1526{
1527 return (ahd_print_register(NULL, 0, "NEGOADDR",
1528 0x60, regvalue, cur_col, wrap));
1529}
1530
1531int
1532ahd_dgrpcrci_print(u_int regvalue, u_int *cur_col, u_int wrap)
1533{
1534 return (ahd_print_register(NULL, 0, "DGRPCRCI",
1535 0x60, regvalue, cur_col, wrap));
1536}
1537
1538int
1539ahd_negperiod_print(u_int regvalue, u_int *cur_col, u_int wrap)
1540{
1541 return (ahd_print_register(NULL, 0, "NEGPERIOD",
1542 0x61, regvalue, cur_col, wrap));
1543}
1544
1545int
1546ahd_packcrci_print(u_int regvalue, u_int *cur_col, u_int wrap)
1547{
1548 return (ahd_print_register(NULL, 0, "PACKCRCI",
1549 0x62, regvalue, cur_col, wrap));
1550}
1551
1552int
1553ahd_negoffset_print(u_int regvalue, u_int *cur_col, u_int wrap)
1554{
1555 return (ahd_print_register(NULL, 0, "NEGOFFSET",
1556 0x62, regvalue, cur_col, wrap));
1557}
1558
1559static ahd_reg_parse_entry_t NEGPPROPTS_parse_table[] = {
1560 { "PPROPT_IUT", 0x01, 0x01 },
1561 { "PPROPT_DT", 0x02, 0x02 },
1562 { "PPROPT_QAS", 0x04, 0x04 },
1563 { "PPROPT_PACE", 0x08, 0x08 }
1564};
1565
1566int
1567ahd_negppropts_print(u_int regvalue, u_int *cur_col, u_int wrap)
1568{
1569 return (ahd_print_register(NEGPPROPTS_parse_table, 4, "NEGPPROPTS",
1570 0x63, regvalue, cur_col, wrap));
1571}
1572
1573static ahd_reg_parse_entry_t NEGCONOPTS_parse_table[] = {
1574 { "WIDEXFER", 0x01, 0x01 },
1575 { "ENAUTOATNO", 0x02, 0x02 },
1576 { "ENAUTOATNI", 0x04, 0x04 },
1577 { "ENSLOWCRC", 0x08, 0x08 },
1578 { "RTI_OVRDTRN", 0x10, 0x10 },
1579 { "RTI_WRTDIS", 0x20, 0x20 },
1580 { "ENSNAPSHOT", 0x40, 0x40 }
1581};
1582
1583int
1584ahd_negconopts_print(u_int regvalue, u_int *cur_col, u_int wrap)
1585{
1586 return (ahd_print_register(NEGCONOPTS_parse_table, 7, "NEGCONOPTS",
1587 0x64, regvalue, cur_col, wrap));
1588}
1589
1590int
1591ahd_annexcol_print(u_int regvalue, u_int *cur_col, u_int wrap)
1592{
1593 return (ahd_print_register(NULL, 0, "ANNEXCOL",
1594 0x65, regvalue, cur_col, wrap));
1595}
1596
1597static ahd_reg_parse_entry_t SCSCHKN_parse_table[] = {
1598 { "LSTSGCLRDIS", 0x01, 0x01 },
1599 { "SHVALIDSTDIS", 0x02, 0x02 },
1600 { "DFFACTCLR", 0x04, 0x04 },
1601 { "SDONEMSKDIS", 0x08, 0x08 },
1602 { "WIDERESEN", 0x10, 0x10 },
1603 { "CURRFIFODEF", 0x20, 0x20 },
1604 { "STSELSKIDDIS", 0x40, 0x40 }
1605};
1606
1607int
1608ahd_scschkn_print(u_int regvalue, u_int *cur_col, u_int wrap)
1609{
1610 return (ahd_print_register(SCSCHKN_parse_table, 7, "SCSCHKN",
1611 0x66, regvalue, cur_col, wrap));
1612}
1613
1614int
1615ahd_annexdat_print(u_int regvalue, u_int *cur_col, u_int wrap)
1616{
1617 return (ahd_print_register(NULL, 0, "ANNEXDAT",
1618 0x66, regvalue, cur_col, wrap));
1619}
1620
1621int
1622ahd_iownid_print(u_int regvalue, u_int *cur_col, u_int wrap)
1623{
1624 return (ahd_print_register(NULL, 0, "IOWNID",
1625 0x67, regvalue, cur_col, wrap));
1626}
1627
1628static ahd_reg_parse_entry_t PLL960CTL0_parse_table[] = {
1629 { "PLL_ENFBM", 0x01, 0x01 },
1630 { "PLL_DLPF", 0x02, 0x02 },
1631 { "PLL_ENLPF", 0x04, 0x04 },
1632 { "PLL_ENLUD", 0x08, 0x08 },
1633 { "PLL_NS", 0x30, 0x30 },
1634 { "PLL_PWDN", 0x40, 0x40 },
1635 { "PLL_VCOSEL", 0x80, 0x80 }
1636};
1637
1638int
1639ahd_pll960ctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1640{
1641 return (ahd_print_register(PLL960CTL0_parse_table, 7, "PLL960CTL0",
1642 0x68, regvalue, cur_col, wrap));
1643}
1644
1645int
1646ahd_shcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1647{
1648 return (ahd_print_register(NULL, 0, "SHCNT",
1649 0x68, regvalue, cur_col, wrap));
1650}
1651
1652int
1653ahd_townid_print(u_int regvalue, u_int *cur_col, u_int wrap)
1654{
1655 return (ahd_print_register(NULL, 0, "TOWNID",
1656 0x69, regvalue, cur_col, wrap));
1657}
1658
1659static ahd_reg_parse_entry_t PLL960CTL1_parse_table[] = {
1660 { "PLL_RST", 0x01, 0x01 },
1661 { "PLL_CNTCLR", 0x40, 0x40 },
1662 { "PLL_CNTEN", 0x80, 0x80 }
1663};
1664
1665int
1666ahd_pll960ctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1667{
1668 return (ahd_print_register(PLL960CTL1_parse_table, 3, "PLL960CTL1",
1669 0x69, regvalue, cur_col, wrap));
1670}
1671
1672int
1673ahd_pll960cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1674{
1675 return (ahd_print_register(NULL, 0, "PLL960CNT0",
1676 0x6a, regvalue, cur_col, wrap));
1677}
1678
1679int
1680ahd_xsig_print(u_int regvalue, u_int *cur_col, u_int wrap)
1681{
1682 return (ahd_print_register(NULL, 0, "XSIG",
1683 0x6a, regvalue, cur_col, wrap));
1684}
1685
1686int
1687ahd_seloid_print(u_int regvalue, u_int *cur_col, u_int wrap)
1688{
1689 return (ahd_print_register(NULL, 0, "SELOID",
1690 0x6b, regvalue, cur_col, wrap));
1691}
1692
1693static ahd_reg_parse_entry_t PLL400CTL0_parse_table[] = {
1694 { "PLL_ENFBM", 0x01, 0x01 },
1695 { "PLL_DLPF", 0x02, 0x02 },
1696 { "PLL_ENLPF", 0x04, 0x04 },
1697 { "PLL_ENLUD", 0x08, 0x08 },
1698 { "PLL_NS", 0x30, 0x30 },
1699 { "PLL_PWDN", 0x40, 0x40 },
1700 { "PLL_VCOSEL", 0x80, 0x80 }
1701};
1702
1703int
1704ahd_pll400ctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1705{
1706 return (ahd_print_register(PLL400CTL0_parse_table, 7, "PLL400CTL0",
1707 0x6c, regvalue, cur_col, wrap));
1708}
1709
1710int
1711ahd_fairness_print(u_int regvalue, u_int *cur_col, u_int wrap)
1712{
1713 return (ahd_print_register(NULL, 0, "FAIRNESS",
1714 0x6c, regvalue, cur_col, wrap));
1715}
1716
1717static ahd_reg_parse_entry_t PLL400CTL1_parse_table[] = {
1718 { "PLL_RST", 0x01, 0x01 },
1719 { "PLL_CNTCLR", 0x40, 0x40 },
1720 { "PLL_CNTEN", 0x80, 0x80 }
1721};
1722
1723int
1724ahd_pll400ctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1725{
1726 return (ahd_print_register(PLL400CTL1_parse_table, 3, "PLL400CTL1",
1727 0x6d, regvalue, cur_col, wrap));
1728}
1729
1730int
1731ahd_pll400cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1732{
1733 return (ahd_print_register(NULL, 0, "PLL400CNT0",
1734 0x6e, regvalue, cur_col, wrap));
1735}
1736
1737int
1738ahd_unfairness_print(u_int regvalue, u_int *cur_col, u_int wrap)
1739{
1740 return (ahd_print_register(NULL, 0, "UNFAIRNESS",
1741 0x6e, regvalue, cur_col, wrap));
1742}
1743
1744int
1745ahd_haddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1746{
1747 return (ahd_print_register(NULL, 0, "HADDR",
1748 0x70, regvalue, cur_col, wrap));
1749}
1750
1751static ahd_reg_parse_entry_t PLLDELAY_parse_table[] = {
1752 { "SPLIT_DROP_REQ", 0x80, 0x80 }
1753};
1754
1755int
1756ahd_plldelay_print(u_int regvalue, u_int *cur_col, u_int wrap)
1757{
1758 return (ahd_print_register(PLLDELAY_parse_table, 1, "PLLDELAY",
1759 0x70, regvalue, cur_col, wrap));
1760}
1761
1762int
1763ahd_hodmaadr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1764{
1765 return (ahd_print_register(NULL, 0, "HODMAADR",
1766 0x70, regvalue, cur_col, wrap));
1767}
1768
1769int
1770ahd_hodmacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1771{
1772 return (ahd_print_register(NULL, 0, "HODMACNT",
1773 0x78, regvalue, cur_col, wrap));
1774}
1775
1776int
1777ahd_hcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1778{
1779 return (ahd_print_register(NULL, 0, "HCNT",
1780 0x78, regvalue, cur_col, wrap));
1781}
1782
1783int
1784ahd_hodmaen_print(u_int regvalue, u_int *cur_col, u_int wrap)
1785{
1786 return (ahd_print_register(NULL, 0, "HODMAEN",
1787 0x7a, regvalue, cur_col, wrap));
1788}
1789
1790int
1791ahd_sghaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1792{
1793 return (ahd_print_register(NULL, 0, "SGHADDR",
1794 0x7c, regvalue, cur_col, wrap));
1795}
1796
1797int
1798ahd_scbhaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1799{
1800 return (ahd_print_register(NULL, 0, "SCBHADDR",
1801 0x7c, regvalue, cur_col, wrap));
1802}
1803
1804int
1805ahd_sghcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1806{
1807 return (ahd_print_register(NULL, 0, "SGHCNT",
1808 0x84, regvalue, cur_col, wrap));
1809}
1810
1811int
1812ahd_scbhcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1813{
1814 return (ahd_print_register(NULL, 0, "SCBHCNT",
1815 0x84, regvalue, cur_col, wrap));
1816}
1817
1818static ahd_reg_parse_entry_t DFF_THRSH_parse_table[] = {
1819 { "WR_DFTHRSH_MIN", 0x00, 0x70 },
1820 { "RD_DFTHRSH_MIN", 0x00, 0x07 },
1821 { "RD_DFTHRSH_25", 0x01, 0x07 },
1822 { "RD_DFTHRSH_50", 0x02, 0x07 },
1823 { "RD_DFTHRSH_63", 0x03, 0x07 },
1824 { "RD_DFTHRSH_75", 0x04, 0x07 },
1825 { "RD_DFTHRSH_85", 0x05, 0x07 },
1826 { "RD_DFTHRSH_90", 0x06, 0x07 },
1827 { "RD_DFTHRSH_MAX", 0x07, 0x07 },
1828 { "WR_DFTHRSH_25", 0x10, 0x70 },
1829 { "WR_DFTHRSH_50", 0x20, 0x70 },
1830 { "WR_DFTHRSH_63", 0x30, 0x70 },
1831 { "WR_DFTHRSH_75", 0x40, 0x70 },
1832 { "WR_DFTHRSH_85", 0x50, 0x70 },
1833 { "WR_DFTHRSH_90", 0x60, 0x70 },
1834 { "WR_DFTHRSH_MAX", 0x70, 0x70 },
1835 { "RD_DFTHRSH", 0x07, 0x07 },
1836 { "WR_DFTHRSH", 0x70, 0x70 }
1837};
1838
1839int
1840ahd_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap)
1841{
1842 return (ahd_print_register(DFF_THRSH_parse_table, 18, "DFF_THRSH",
1843 0x88, regvalue, cur_col, wrap));
1844}
1845
1846int
1847ahd_romaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1848{
1849 return (ahd_print_register(NULL, 0, "ROMADDR",
1850 0x8a, regvalue, cur_col, wrap));
1851}
1852
1853static ahd_reg_parse_entry_t ROMCNTRL_parse_table[] = {
1854 { "RDY", 0x01, 0x01 },
1855 { "REPEAT", 0x02, 0x02 },
1856 { "ROMSPD", 0x18, 0x18 },
1857 { "ROMOP", 0xe0, 0xe0 }
1858};
1859
1860int
1861ahd_romcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
1862{
1863 return (ahd_print_register(ROMCNTRL_parse_table, 4, "ROMCNTRL",
1864 0x8d, regvalue, cur_col, wrap));
1865}
1866
1867int
1868ahd_romdata_print(u_int regvalue, u_int *cur_col, u_int wrap)
1869{
1870 return (ahd_print_register(NULL, 0, "ROMDATA",
1871 0x8e, regvalue, cur_col, wrap));
1872}
1873
1874static ahd_reg_parse_entry_t CMCRXMSG0_parse_table[] = {
1875 { "CFNUM", 0x07, 0x07 },
1876 { "CDNUM", 0xf8, 0xf8 }
1877};
1878
1879int
1880ahd_cmcrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1881{
1882 return (ahd_print_register(CMCRXMSG0_parse_table, 2, "CMCRXMSG0",
1883 0x90, regvalue, cur_col, wrap));
1884}
1885
1886static ahd_reg_parse_entry_t ROENABLE_parse_table[] = {
1887 { "DCH0ROEN", 0x01, 0x01 },
1888 { "DCH1ROEN", 0x02, 0x02 },
1889 { "SGROEN", 0x04, 0x04 },
1890 { "CMCROEN", 0x08, 0x08 },
1891 { "OVLYROEN", 0x10, 0x10 },
1892 { "MSIROEN", 0x20, 0x20 }
1893};
1894
1895int
1896ahd_roenable_print(u_int regvalue, u_int *cur_col, u_int wrap)
1897{
1898 return (ahd_print_register(ROENABLE_parse_table, 6, "ROENABLE",
1899 0x90, regvalue, cur_col, wrap));
1900}
1901
1902static ahd_reg_parse_entry_t OVLYRXMSG0_parse_table[] = {
1903 { "CFNUM", 0x07, 0x07 },
1904 { "CDNUM", 0xf8, 0xf8 }
1905};
1906
1907int
1908ahd_ovlyrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1909{
1910 return (ahd_print_register(OVLYRXMSG0_parse_table, 2, "OVLYRXMSG0",
1911 0x90, regvalue, cur_col, wrap));
1912}
1913
1914static ahd_reg_parse_entry_t DCHRXMSG0_parse_table[] = {
1915 { "CFNUM", 0x07, 0x07 },
1916 { "CDNUM", 0xf8, 0xf8 }
1917};
1918
1919int
1920ahd_dchrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap)
1921{
1922 return (ahd_print_register(DCHRXMSG0_parse_table, 2, "DCHRXMSG0",
1923 0x90, regvalue, cur_col, wrap));
1924}
1925
1926static ahd_reg_parse_entry_t OVLYRXMSG1_parse_table[] = {
1927 { "CBNUM", 0xff, 0xff }
1928};
1929
1930int
1931ahd_ovlyrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1932{
1933 return (ahd_print_register(OVLYRXMSG1_parse_table, 1, "OVLYRXMSG1",
1934 0x91, regvalue, cur_col, wrap));
1935}
1936
1937static ahd_reg_parse_entry_t NSENABLE_parse_table[] = {
1938 { "DCH0NSEN", 0x01, 0x01 },
1939 { "DCH1NSEN", 0x02, 0x02 },
1940 { "SGNSEN", 0x04, 0x04 },
1941 { "CMCNSEN", 0x08, 0x08 },
1942 { "OVLYNSEN", 0x10, 0x10 },
1943 { "MSINSEN", 0x20, 0x20 }
1944};
1945
1946int
1947ahd_nsenable_print(u_int regvalue, u_int *cur_col, u_int wrap)
1948{
1949 return (ahd_print_register(NSENABLE_parse_table, 6, "NSENABLE",
1950 0x91, regvalue, cur_col, wrap));
1951}
1952
1953static ahd_reg_parse_entry_t DCHRXMSG1_parse_table[] = {
1954 { "CBNUM", 0xff, 0xff }
1955};
1956
1957int
1958ahd_dchrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1959{
1960 return (ahd_print_register(DCHRXMSG1_parse_table, 1, "DCHRXMSG1",
1961 0x91, regvalue, cur_col, wrap));
1962}
1963
1964static ahd_reg_parse_entry_t CMCRXMSG1_parse_table[] = {
1965 { "CBNUM", 0xff, 0xff }
1966};
1967
1968int
1969ahd_cmcrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1970{
1971 return (ahd_print_register(CMCRXMSG1_parse_table, 1, "CMCRXMSG1",
1972 0x91, regvalue, cur_col, wrap));
1973}
1974
1975static ahd_reg_parse_entry_t DCHRXMSG2_parse_table[] = {
1976 { "MINDEX", 0xff, 0xff }
1977};
1978
1979int
1980ahd_dchrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap)
1981{
1982 return (ahd_print_register(DCHRXMSG2_parse_table, 1, "DCHRXMSG2",
1983 0x92, regvalue, cur_col, wrap));
1984}
1985
1986static ahd_reg_parse_entry_t OVLYRXMSG2_parse_table[] = {
1987 { "MINDEX", 0xff, 0xff }
1988};
1989
1990int
1991ahd_ovlyrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap)
1992{
1993 return (ahd_print_register(OVLYRXMSG2_parse_table, 1, "OVLYRXMSG2",
1994 0x92, regvalue, cur_col, wrap));
1995}
1996
1997static ahd_reg_parse_entry_t CMCRXMSG2_parse_table[] = {
1998 { "MINDEX", 0xff, 0xff }
1999};
2000
2001int
2002ahd_cmcrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap)
2003{
2004 return (ahd_print_register(CMCRXMSG2_parse_table, 1, "CMCRXMSG2",
2005 0x92, regvalue, cur_col, wrap));
2006}
2007
2008int
2009ahd_ost_print(u_int regvalue, u_int *cur_col, u_int wrap)
2010{
2011 return (ahd_print_register(NULL, 0, "OST",
2012 0x92, regvalue, cur_col, wrap));
2013}
2014
2015static ahd_reg_parse_entry_t DCHRXMSG3_parse_table[] = {
2016 { "MCLASS", 0x0f, 0x0f }
2017};
2018
2019int
2020ahd_dchrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap)
2021{
2022 return (ahd_print_register(DCHRXMSG3_parse_table, 1, "DCHRXMSG3",
2023 0x93, regvalue, cur_col, wrap));
2024}
2025
2026static ahd_reg_parse_entry_t CMCRXMSG3_parse_table[] = {
2027 { "MCLASS", 0x0f, 0x0f }
2028};
2029
2030int
2031ahd_cmcrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap)
2032{
2033 return (ahd_print_register(CMCRXMSG3_parse_table, 1, "CMCRXMSG3",
2034 0x93, regvalue, cur_col, wrap));
2035}
2036
2037static ahd_reg_parse_entry_t PCIXCTL_parse_table[] = {
2038 { "CMPABCDIS", 0x01, 0x01 },
2039 { "TSCSERREN", 0x02, 0x02 },
2040 { "SRSPDPEEN", 0x04, 0x04 },
2041 { "SPLTSTADIS", 0x08, 0x08 },
2042 { "SPLTSMADIS", 0x10, 0x10 },
2043 { "UNEXPSCIEN", 0x20, 0x20 },
2044 { "SERRPULSE", 0x80, 0x80 }
2045};
2046
2047int
2048ahd_pcixctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2049{
2050 return (ahd_print_register(PCIXCTL_parse_table, 7, "PCIXCTL",
2051 0x93, regvalue, cur_col, wrap));
2052}
2053
2054static ahd_reg_parse_entry_t OVLYRXMSG3_parse_table[] = {
2055 { "MCLASS", 0x0f, 0x0f }
2056};
2057
2058int
2059ahd_ovlyrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap)
2060{
2061 return (ahd_print_register(OVLYRXMSG3_parse_table, 1, "OVLYRXMSG3",
2062 0x93, regvalue, cur_col, wrap));
2063}
2064
2065int
2066ahd_ovlyseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2067{
2068 return (ahd_print_register(NULL, 0, "OVLYSEQBCNT",
2069 0x94, regvalue, cur_col, wrap));
2070}
2071
2072int
2073ahd_cmcseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2074{
2075 return (ahd_print_register(NULL, 0, "CMCSEQBCNT",
2076 0x94, regvalue, cur_col, wrap));
2077}
2078
2079int
2080ahd_dchseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2081{
2082 return (ahd_print_register(NULL, 0, "DCHSEQBCNT",
2083 0x94, regvalue, cur_col, wrap));
2084}
2085
2086static ahd_reg_parse_entry_t CMCSPLTSTAT0_parse_table[] = {
2087 { "RXSPLTRSP", 0x01, 0x01 },
2088 { "RXSCEMSG", 0x02, 0x02 },
2089 { "RXOVRUN", 0x04, 0x04 },
2090 { "CNTNOTCMPLT", 0x08, 0x08 },
2091 { "SCDATBUCKET", 0x10, 0x10 },
2092 { "SCADERR", 0x20, 0x20 },
2093 { "SCBCERR", 0x40, 0x40 },
2094 { "STAETERM", 0x80, 0x80 }
2095};
2096
2097int
2098ahd_cmcspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
2099{
2100 return (ahd_print_register(CMCSPLTSTAT0_parse_table, 8, "CMCSPLTSTAT0",
2101 0x96, regvalue, cur_col, wrap));
2102}
2103
2104static ahd_reg_parse_entry_t OVLYSPLTSTAT0_parse_table[] = {
2105 { "RXSPLTRSP", 0x01, 0x01 },
2106 { "RXSCEMSG", 0x02, 0x02 },
2107 { "RXOVRUN", 0x04, 0x04 },
2108 { "CNTNOTCMPLT", 0x08, 0x08 },
2109 { "SCDATBUCKET", 0x10, 0x10 },
2110 { "SCADERR", 0x20, 0x20 },
2111 { "SCBCERR", 0x40, 0x40 },
2112 { "STAETERM", 0x80, 0x80 }
2113};
2114
2115int
2116ahd_ovlyspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
2117{
2118 return (ahd_print_register(OVLYSPLTSTAT0_parse_table, 8, "OVLYSPLTSTAT0",
2119 0x96, regvalue, cur_col, wrap));
2120}
2121
2122static ahd_reg_parse_entry_t DCHSPLTSTAT0_parse_table[] = {
2123 { "RXSPLTRSP", 0x01, 0x01 },
2124 { "RXSCEMSG", 0x02, 0x02 },
2125 { "RXOVRUN", 0x04, 0x04 },
2126 { "CNTNOTCMPLT", 0x08, 0x08 },
2127 { "SCDATBUCKET", 0x10, 0x10 },
2128 { "SCADERR", 0x20, 0x20 },
2129 { "SCBCERR", 0x40, 0x40 },
2130 { "STAETERM", 0x80, 0x80 }
2131};
2132
2133int
2134ahd_dchspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
2135{
2136 return (ahd_print_register(DCHSPLTSTAT0_parse_table, 8, "DCHSPLTSTAT0",
2137 0x96, regvalue, cur_col, wrap));
2138}
2139
2140static ahd_reg_parse_entry_t DCHSPLTSTAT1_parse_table[] = {
2141 { "RXDATABUCKET", 0x01, 0x01 }
2142};
2143
2144int
2145ahd_dchspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
2146{
2147 return (ahd_print_register(DCHSPLTSTAT1_parse_table, 1, "DCHSPLTSTAT1",
2148 0x97, regvalue, cur_col, wrap));
2149}
2150
2151static ahd_reg_parse_entry_t CMCSPLTSTAT1_parse_table[] = {
2152 { "RXDATABUCKET", 0x01, 0x01 }
2153};
2154
2155int
2156ahd_cmcspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
2157{
2158 return (ahd_print_register(CMCSPLTSTAT1_parse_table, 1, "CMCSPLTSTAT1",
2159 0x97, regvalue, cur_col, wrap));
2160}
2161
2162static ahd_reg_parse_entry_t OVLYSPLTSTAT1_parse_table[] = {
2163 { "RXDATABUCKET", 0x01, 0x01 }
2164};
2165
2166int
2167ahd_ovlyspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
2168{
2169 return (ahd_print_register(OVLYSPLTSTAT1_parse_table, 1, "OVLYSPLTSTAT1",
2170 0x97, regvalue, cur_col, wrap));
2171}
2172
2173static ahd_reg_parse_entry_t SGRXMSG0_parse_table[] = {
2174 { "CFNUM", 0x07, 0x07 },
2175 { "CDNUM", 0xf8, 0xf8 }
2176};
2177
2178int
2179ahd_sgrxmsg0_print(u_int regvalue, u_int *cur_col, u_int wrap)
2180{
2181 return (ahd_print_register(SGRXMSG0_parse_table, 2, "SGRXMSG0",
2182 0x98, regvalue, cur_col, wrap));
2183}
2184
2185static ahd_reg_parse_entry_t SLVSPLTOUTADR0_parse_table[] = {
2186 { "LOWER_ADDR", 0x7f, 0x7f }
2187};
2188
2189int
2190ahd_slvspltoutadr0_print(u_int regvalue, u_int *cur_col, u_int wrap)
2191{
2192 return (ahd_print_register(SLVSPLTOUTADR0_parse_table, 1, "SLVSPLTOUTADR0",
2193 0x98, regvalue, cur_col, wrap));
2194}
2195
2196static ahd_reg_parse_entry_t SGRXMSG1_parse_table[] = {
2197 { "CBNUM", 0xff, 0xff }
2198};
2199
2200int
2201ahd_sgrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap)
2202{
2203 return (ahd_print_register(SGRXMSG1_parse_table, 1, "SGRXMSG1",
2204 0x99, regvalue, cur_col, wrap));
2205}
2206
2207static ahd_reg_parse_entry_t SLVSPLTOUTADR1_parse_table[] = {
2208 { "REQ_FNUM", 0x07, 0x07 },
2209 { "REQ_DNUM", 0xf8, 0xf8 }
2210};
2211
2212int
2213ahd_slvspltoutadr1_print(u_int regvalue, u_int *cur_col, u_int wrap)
2214{
2215 return (ahd_print_register(SLVSPLTOUTADR1_parse_table, 2, "SLVSPLTOUTADR1",
2216 0x99, regvalue, cur_col, wrap));
2217}
2218
2219static ahd_reg_parse_entry_t SGRXMSG2_parse_table[] = {
2220 { "MINDEX", 0xff, 0xff }
2221};
2222
2223int
2224ahd_sgrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap)
2225{
2226 return (ahd_print_register(SGRXMSG2_parse_table, 1, "SGRXMSG2",
2227 0x9a, regvalue, cur_col, wrap));
2228}
2229
2230static ahd_reg_parse_entry_t SLVSPLTOUTADR2_parse_table[] = {
2231 { "REQ_BNUM", 0xff, 0xff }
2232};
2233
2234int
2235ahd_slvspltoutadr2_print(u_int regvalue, u_int *cur_col, u_int wrap)
2236{
2237 return (ahd_print_register(SLVSPLTOUTADR2_parse_table, 1, "SLVSPLTOUTADR2",
2238 0x9a, regvalue, cur_col, wrap));
2239}
2240
2241static ahd_reg_parse_entry_t SGRXMSG3_parse_table[] = {
2242 { "MCLASS", 0x0f, 0x0f }
2243};
2244
2245int
2246ahd_sgrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap)
2247{
2248 return (ahd_print_register(SGRXMSG3_parse_table, 1, "SGRXMSG3",
2249 0x9b, regvalue, cur_col, wrap));
2250}
2251
2252static ahd_reg_parse_entry_t SLVSPLTOUTADR3_parse_table[] = {
2253 { "RLXORD", 0x10, 0x10 },
2254 { "TAG_NUM", 0x1f, 0x1f }
2255};
2256
2257int
2258ahd_slvspltoutadr3_print(u_int regvalue, u_int *cur_col, u_int wrap)
2259{
2260 return (ahd_print_register(SLVSPLTOUTADR3_parse_table, 2, "SLVSPLTOUTADR3",
2261 0x9b, regvalue, cur_col, wrap));
2262}
2263
2264int
2265ahd_sgseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2266{
2267 return (ahd_print_register(NULL, 0, "SGSEQBCNT",
2268 0x9c, regvalue, cur_col, wrap));
2269}
2270
2271static ahd_reg_parse_entry_t SLVSPLTOUTATTR0_parse_table[] = {
2272 { "LOWER_BCNT", 0xff, 0xff }
2273};
2274
2275int
2276ahd_slvspltoutattr0_print(u_int regvalue, u_int *cur_col, u_int wrap)
2277{
2278 return (ahd_print_register(SLVSPLTOUTATTR0_parse_table, 1, "SLVSPLTOUTATTR0",
2279 0x9c, regvalue, cur_col, wrap));
2280}
2281
2282static ahd_reg_parse_entry_t SLVSPLTOUTATTR1_parse_table[] = {
2283 { "CMPLT_FNUM", 0x07, 0x07 },
2284 { "CMPLT_DNUM", 0xf8, 0xf8 }
2285};
2286
2287int
2288ahd_slvspltoutattr1_print(u_int regvalue, u_int *cur_col, u_int wrap)
2289{
2290 return (ahd_print_register(SLVSPLTOUTATTR1_parse_table, 2, "SLVSPLTOUTATTR1",
2291 0x9d, regvalue, cur_col, wrap));
2292}
2293
2294static ahd_reg_parse_entry_t SLVSPLTOUTATTR2_parse_table[] = {
2295 { "CMPLT_BNUM", 0xff, 0xff }
2296};
2297
2298int
2299ahd_slvspltoutattr2_print(u_int regvalue, u_int *cur_col, u_int wrap)
2300{
2301 return (ahd_print_register(SLVSPLTOUTATTR2_parse_table, 1, "SLVSPLTOUTATTR2",
2302 0x9e, regvalue, cur_col, wrap));
2303}
2304
2305static ahd_reg_parse_entry_t SGSPLTSTAT0_parse_table[] = {
2306 { "RXSPLTRSP", 0x01, 0x01 },
2307 { "RXSCEMSG", 0x02, 0x02 },
2308 { "RXOVRUN", 0x04, 0x04 },
2309 { "CNTNOTCMPLT", 0x08, 0x08 },
2310 { "SCDATBUCKET", 0x10, 0x10 },
2311 { "SCADERR", 0x20, 0x20 },
2312 { "SCBCERR", 0x40, 0x40 },
2313 { "STAETERM", 0x80, 0x80 }
2314};
2315
2316int
2317ahd_sgspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
2318{
2319 return (ahd_print_register(SGSPLTSTAT0_parse_table, 8, "SGSPLTSTAT0",
2320 0x9e, regvalue, cur_col, wrap));
2321}
2322
2323static ahd_reg_parse_entry_t SFUNCT_parse_table[] = {
2324 { "TEST_NUM", 0x0f, 0x0f },
2325 { "TEST_GROUP", 0xf0, 0xf0 }
2326};
2327
2328int
2329ahd_sfunct_print(u_int regvalue, u_int *cur_col, u_int wrap)
2330{
2331 return (ahd_print_register(SFUNCT_parse_table, 2, "SFUNCT",
2332 0x9f, regvalue, cur_col, wrap));
2333}
2334
2335static ahd_reg_parse_entry_t SGSPLTSTAT1_parse_table[] = {
2336 { "RXDATABUCKET", 0x01, 0x01 }
2337};
2338
2339int
2340ahd_sgspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
2341{
2342 return (ahd_print_register(SGSPLTSTAT1_parse_table, 1, "SGSPLTSTAT1",
2343 0x9f, regvalue, cur_col, wrap));
2344}
2345
2346static ahd_reg_parse_entry_t DF0PCISTAT_parse_table[] = {
2347 { "DPR", 0x01, 0x01 },
2348 { "TWATERR", 0x02, 0x02 },
2349 { "RDPERR", 0x04, 0x04 },
2350 { "SCAAPERR", 0x08, 0x08 },
2351 { "RTA", 0x10, 0x10 },
2352 { "RMA", 0x20, 0x20 },
2353 { "SSE", 0x40, 0x40 },
2354 { "DPE", 0x80, 0x80 }
2355};
2356
2357int
2358ahd_df0pcistat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2359{
2360 return (ahd_print_register(DF0PCISTAT_parse_table, 8, "DF0PCISTAT",
2361 0xa0, regvalue, cur_col, wrap));
2362}
2363
2364int
2365ahd_reg0_print(u_int regvalue, u_int *cur_col, u_int wrap)
2366{
2367 return (ahd_print_register(NULL, 0, "REG0",
2368 0xa0, regvalue, cur_col, wrap));
2369}
2370
2371static ahd_reg_parse_entry_t DF1PCISTAT_parse_table[] = {
2372 { "DPR", 0x01, 0x01 },
2373 { "TWATERR", 0x02, 0x02 },
2374 { "RDPERR", 0x04, 0x04 },
2375 { "SCAAPERR", 0x08, 0x08 },
2376 { "RTA", 0x10, 0x10 },
2377 { "RMA", 0x20, 0x20 },
2378 { "SSE", 0x40, 0x40 },
2379 { "DPE", 0x80, 0x80 }
2380};
2381
2382int
2383ahd_df1pcistat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2384{
2385 return (ahd_print_register(DF1PCISTAT_parse_table, 8, "DF1PCISTAT",
2386 0xa1, regvalue, cur_col, wrap));
2387}
2388
2389static ahd_reg_parse_entry_t SGPCISTAT_parse_table[] = {
2390 { "DPR", 0x01, 0x01 },
2391 { "RDPERR", 0x04, 0x04 },
2392 { "SCAAPERR", 0x08, 0x08 },
2393 { "RTA", 0x10, 0x10 },
2394 { "RMA", 0x20, 0x20 },
2395 { "SSE", 0x40, 0x40 },
2396 { "DPE", 0x80, 0x80 }
2397};
2398
2399int
2400ahd_sgpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2401{
2402 return (ahd_print_register(SGPCISTAT_parse_table, 7, "SGPCISTAT",
2403 0xa2, regvalue, cur_col, wrap));
2404}
2405
2406int
2407ahd_reg1_print(u_int regvalue, u_int *cur_col, u_int wrap)
2408{
2409 return (ahd_print_register(NULL, 0, "REG1",
2410 0xa2, regvalue, cur_col, wrap));
2411}
2412
2413static ahd_reg_parse_entry_t CMCPCISTAT_parse_table[] = {
2414 { "DPR", 0x01, 0x01 },
2415 { "TWATERR", 0x02, 0x02 },
2416 { "RDPERR", 0x04, 0x04 },
2417 { "SCAAPERR", 0x08, 0x08 },
2418 { "RTA", 0x10, 0x10 },
2419 { "RMA", 0x20, 0x20 },
2420 { "SSE", 0x40, 0x40 },
2421 { "DPE", 0x80, 0x80 }
2422};
2423
2424int
2425ahd_cmcpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2426{
2427 return (ahd_print_register(CMCPCISTAT_parse_table, 8, "CMCPCISTAT",
2428 0xa3, regvalue, cur_col, wrap));
2429}
2430
2431static ahd_reg_parse_entry_t OVLYPCISTAT_parse_table[] = {
2432 { "DPR", 0x01, 0x01 },
2433 { "RDPERR", 0x04, 0x04 },
2434 { "SCAAPERR", 0x08, 0x08 },
2435 { "RTA", 0x10, 0x10 },
2436 { "RMA", 0x20, 0x20 },
2437 { "SSE", 0x40, 0x40 },
2438 { "DPE", 0x80, 0x80 }
2439};
2440
2441int
2442ahd_ovlypcistat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2443{
2444 return (ahd_print_register(OVLYPCISTAT_parse_table, 7, "OVLYPCISTAT",
2445 0xa4, regvalue, cur_col, wrap));
2446}
2447
2448int
2449ahd_reg_isr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2450{
2451 return (ahd_print_register(NULL, 0, "REG_ISR",
2452 0xa4, regvalue, cur_col, wrap));
2453}
2454
2455static ahd_reg_parse_entry_t SG_STATE_parse_table[] = {
2456 { "SEGS_AVAIL", 0x01, 0x01 },
2457 { "LOADING_NEEDED", 0x02, 0x02 },
2458 { "FETCH_INPROG", 0x04, 0x04 }
2459};
2460
2461int
2462ahd_sg_state_print(u_int regvalue, u_int *cur_col, u_int wrap)
2463{
2464 return (ahd_print_register(SG_STATE_parse_table, 3, "SG_STATE",
2465 0xa6, regvalue, cur_col, wrap));
2466}
2467
2468static ahd_reg_parse_entry_t MSIPCISTAT_parse_table[] = {
2469 { "DPR", 0x01, 0x01 },
2470 { "TWATERR", 0x02, 0x02 },
2471 { "CLRPENDMSI", 0x08, 0x08 },
2472 { "RTA", 0x10, 0x10 },
2473 { "RMA", 0x20, 0x20 },
2474 { "SSE", 0x40, 0x40 }
2475};
2476
2477int
2478ahd_msipcistat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2479{
2480 return (ahd_print_register(MSIPCISTAT_parse_table, 6, "MSIPCISTAT",
2481 0xa6, regvalue, cur_col, wrap));
2482}
2483
2484static ahd_reg_parse_entry_t TARGPCISTAT_parse_table[] = {
2485 { "TWATERR", 0x02, 0x02 },
2486 { "STA", 0x08, 0x08 },
2487 { "SSE", 0x40, 0x40 },
2488 { "DPE", 0x80, 0x80 }
2489};
2490
2491int
2492ahd_targpcistat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2493{
2494 return (ahd_print_register(TARGPCISTAT_parse_table, 4, "TARGPCISTAT",
2495 0xa7, regvalue, cur_col, wrap));
2496}
2497
2498int
2499ahd_data_count_odd_print(u_int regvalue, u_int *cur_col, u_int wrap)
2500{
2501 return (ahd_print_register(NULL, 0, "DATA_COUNT_ODD",
2502 0xa7, regvalue, cur_col, wrap));
2503}
2504
2505int
2506ahd_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2507{
2508 return (ahd_print_register(NULL, 0, "SCBPTR",
2509 0xa8, regvalue, cur_col, wrap));
2510}
2511
2512int
2513ahd_ccscbacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2514{
2515 return (ahd_print_register(NULL, 0, "CCSCBACNT",
2516 0xab, regvalue, cur_col, wrap));
2517}
2518
2519static ahd_reg_parse_entry_t SCBAUTOPTR_parse_table[] = {
2520 { "SCBPTR_OFF", 0x07, 0x07 },
2521 { "SCBPTR_ADDR", 0x38, 0x38 },
2522 { "AUSCBPTR_EN", 0x80, 0x80 }
2523};
2524
2525int
2526ahd_scbautoptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2527{
2528 return (ahd_print_register(SCBAUTOPTR_parse_table, 3, "SCBAUTOPTR",
2529 0xab, regvalue, cur_col, wrap));
2530}
2531
2532int
2533ahd_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2534{
2535 return (ahd_print_register(NULL, 0, "CCSGADDR",
2536 0xac, regvalue, cur_col, wrap));
2537}
2538
2539int
2540ahd_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2541{
2542 return (ahd_print_register(NULL, 0, "CCSCBADDR",
2543 0xac, regvalue, cur_col, wrap));
2544}
2545
2546int
2547ahd_ccscbadr_bk_print(u_int regvalue, u_int *cur_col, u_int wrap)
2548{
2549 return (ahd_print_register(NULL, 0, "CCSCBADR_BK",
2550 0xac, regvalue, cur_col, wrap));
2551}
2552
2553static ahd_reg_parse_entry_t CMC_RAMBIST_parse_table[] = {
2554 { "CMC_BUFFER_BIST_EN", 0x01, 0x01 },
2555 { "CMC_BUFFER_BIST_FAIL",0x02, 0x02 },
2556 { "SG_BIST_EN", 0x10, 0x10 },
2557 { "SG_BIST_FAIL", 0x20, 0x20 },
2558 { "SCBRAMBIST_FAIL", 0x40, 0x40 },
2559 { "SG_ELEMENT_SIZE", 0x80, 0x80 }
2560};
2561
2562int
2563ahd_cmc_rambist_print(u_int regvalue, u_int *cur_col, u_int wrap)
2564{
2565 return (ahd_print_register(CMC_RAMBIST_parse_table, 6, "CMC_RAMBIST",
2566 0xad, regvalue, cur_col, wrap));
2567}
2568
2569static ahd_reg_parse_entry_t CCSGCTL_parse_table[] = {
2570 { "CCSGRESET", 0x01, 0x01 },
2571 { "SG_FETCH_REQ", 0x02, 0x02 },
2572 { "CCSGENACK", 0x08, 0x08 },
2573 { "SG_CACHE_AVAIL", 0x10, 0x10 },
2574 { "CCSGDONE", 0x80, 0x80 },
2575 { "CCSGEN", 0x0c, 0x0c }
2576};
2577
2578int
2579ahd_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2580{
2581 return (ahd_print_register(CCSGCTL_parse_table, 6, "CCSGCTL",
2582 0xad, regvalue, cur_col, wrap));
2583}
2584
2585static ahd_reg_parse_entry_t CCSCBCTL_parse_table[] = {
2586 { "CCSCBRESET", 0x01, 0x01 },
2587 { "CCSCBDIR", 0x04, 0x04 },
2588 { "CCSCBEN", 0x08, 0x08 },
2589 { "CCARREN", 0x10, 0x10 },
2590 { "ARRDONE", 0x40, 0x40 },
2591 { "CCSCBDONE", 0x80, 0x80 }
2592};
2593
2594int
2595ahd_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2596{
2597 return (ahd_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL",
2598 0xad, regvalue, cur_col, wrap));
2599}
2600
2601int
2602ahd_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap)
2603{
2604 return (ahd_print_register(NULL, 0, "CCSGRAM",
2605 0xb0, regvalue, cur_col, wrap));
2606}
2607
2608int
2609ahd_flexadr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2610{
2611 return (ahd_print_register(NULL, 0, "FLEXADR",
2612 0xb0, regvalue, cur_col, wrap));
2613}
2614
2615int
2616ahd_ccscbram_print(u_int regvalue, u_int *cur_col, u_int wrap)
2617{
2618 return (ahd_print_register(NULL, 0, "CCSCBRAM",
2619 0xb0, regvalue, cur_col, wrap));
2620}
2621
2622int
2623ahd_flexcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2624{
2625 return (ahd_print_register(NULL, 0, "FLEXCNT",
2626 0xb3, regvalue, cur_col, wrap));
2627}
2628
2629static ahd_reg_parse_entry_t FLEXDMASTAT_parse_table[] = {
2630 { "FLEXDMADONE", 0x01, 0x01 },
2631 { "FLEXDMAERR", 0x02, 0x02 }
2632};
2633
2634int
2635ahd_flexdmastat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2636{
2637 return (ahd_print_register(FLEXDMASTAT_parse_table, 2, "FLEXDMASTAT",
2638 0xb5, regvalue, cur_col, wrap));
2639}
2640
2641int
2642ahd_flexdata_print(u_int regvalue, u_int *cur_col, u_int wrap)
2643{
2644 return (ahd_print_register(NULL, 0, "FLEXDATA",
2645 0xb6, regvalue, cur_col, wrap));
2646}
2647
2648int
2649ahd_brddat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2650{
2651 return (ahd_print_register(NULL, 0, "BRDDAT",
2652 0xb8, regvalue, cur_col, wrap));
2653}
2654
2655static ahd_reg_parse_entry_t BRDCTL_parse_table[] = {
2656 { "BRDSTB", 0x01, 0x01 },
2657 { "BRDRW", 0x02, 0x02 },
2658 { "BRDEN", 0x04, 0x04 },
2659 { "BRDADDR", 0x38, 0x38 },
2660 { "FLXARBREQ", 0x40, 0x40 },
2661 { "FLXARBACK", 0x80, 0x80 }
2662};
2663
2664int
2665ahd_brdctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2666{
2667 return (ahd_print_register(BRDCTL_parse_table, 6, "BRDCTL",
2668 0xb9, regvalue, cur_col, wrap));
2669}
2670
2671int
2672ahd_seeadr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2673{
2674 return (ahd_print_register(NULL, 0, "SEEADR",
2675 0xba, regvalue, cur_col, wrap));
2676}
2677
2678int
2679ahd_seedat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2680{
2681 return (ahd_print_register(NULL, 0, "SEEDAT",
2682 0xbc, regvalue, cur_col, wrap));
2683}
2684
2685static ahd_reg_parse_entry_t SEECTL_parse_table[] = {
2686 { "SEEOP_ERAL", 0x40, 0x70 },
2687 { "SEEOP_WRITE", 0x50, 0x70 },
2688 { "SEEOP_READ", 0x60, 0x70 },
2689 { "SEEOP_ERASE", 0x70, 0x70 },
2690 { "SEESTART", 0x01, 0x01 },
2691 { "SEERST", 0x02, 0x02 },
2692 { "SEEOPCODE", 0x70, 0x70 },
2693 { "SEEOP_EWEN", 0x40, 0x40 },
2694 { "SEEOP_WALL", 0x40, 0x40 },
2695 { "SEEOP_EWDS", 0x40, 0x40 }
2696};
2697
2698int
2699ahd_seectl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2700{
2701 return (ahd_print_register(SEECTL_parse_table, 10, "SEECTL",
2702 0xbe, regvalue, cur_col, wrap));
2703}
2704
2705static ahd_reg_parse_entry_t SEESTAT_parse_table[] = {
2706 { "SEESTART", 0x01, 0x01 },
2707 { "SEEBUSY", 0x02, 0x02 },
2708 { "SEEARBACK", 0x04, 0x04 },
2709 { "LDALTID_L", 0x08, 0x08 },
2710 { "SEEOPCODE", 0x70, 0x70 },
2711 { "INIT_DONE", 0x80, 0x80 }
2712};
2713
2714int
2715ahd_seestat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2716{
2717 return (ahd_print_register(SEESTAT_parse_table, 6, "SEESTAT",
2718 0xbe, regvalue, cur_col, wrap));
2719}
2720
2721int
2722ahd_scbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2723{
2724 return (ahd_print_register(NULL, 0, "SCBCNT",
2725 0xbf, regvalue, cur_col, wrap));
2726}
2727
2728int
2729ahd_dfwaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2730{
2731 return (ahd_print_register(NULL, 0, "DFWADDR",
2732 0xc0, regvalue, cur_col, wrap));
2733}
2734
2735static ahd_reg_parse_entry_t DSPFLTRCTL_parse_table[] = {
2736 { "DSPFCNTSEL", 0x0f, 0x0f },
2737 { "EDGESENSE", 0x10, 0x10 },
2738 { "FLTRDISABLE", 0x20, 0x20 }
2739};
2740
2741int
2742ahd_dspfltrctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2743{
2744 return (ahd_print_register(DSPFLTRCTL_parse_table, 3, "DSPFLTRCTL",
2745 0xc0, regvalue, cur_col, wrap));
2746}
2747
2748static ahd_reg_parse_entry_t DSPDATACTL_parse_table[] = {
2749 { "XMITOFFSTDIS", 0x02, 0x02 },
2750 { "RCVROFFSTDIS", 0x04, 0x04 },
2751 { "DESQDIS", 0x10, 0x10 },
2752 { "BYPASSENAB", 0x80, 0x80 }
2753};
2754
2755int
2756ahd_dspdatactl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2757{
2758 return (ahd_print_register(DSPDATACTL_parse_table, 4, "DSPDATACTL",
2759 0xc1, regvalue, cur_col, wrap));
2760}
2761
2762int
2763ahd_dfraddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2764{
2765 return (ahd_print_register(NULL, 0, "DFRADDR",
2766 0xc2, regvalue, cur_col, wrap));
2767}
2768
2769static ahd_reg_parse_entry_t DSPREQCTL_parse_table[] = {
2770 { "MANREQDLY", 0x3f, 0x3f },
2771 { "MANREQCTL", 0xc0, 0xc0 }
2772};
2773
2774int
2775ahd_dspreqctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2776{
2777 return (ahd_print_register(DSPREQCTL_parse_table, 2, "DSPREQCTL",
2778 0xc2, regvalue, cur_col, wrap));
2779}
2780
2781static ahd_reg_parse_entry_t DSPACKCTL_parse_table[] = {
2782 { "MANACKDLY", 0x3f, 0x3f },
2783 { "MANACKCTL", 0xc0, 0xc0 }
2784};
2785
2786int
2787ahd_dspackctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2788{
2789 return (ahd_print_register(DSPACKCTL_parse_table, 2, "DSPACKCTL",
2790 0xc3, regvalue, cur_col, wrap));
2791}
2792
2793int
2794ahd_dfdat_print(u_int regvalue, u_int *cur_col, u_int wrap)
2795{
2796 return (ahd_print_register(NULL, 0, "DFDAT",
2797 0xc4, regvalue, cur_col, wrap));
2798}
2799
2800static ahd_reg_parse_entry_t DSPSELECT_parse_table[] = {
2801 { "DSPSEL", 0x1f, 0x1f },
2802 { "AUTOINCEN", 0x80, 0x80 }
2803};
2804
2805int
2806ahd_dspselect_print(u_int regvalue, u_int *cur_col, u_int wrap)
2807{
2808 return (ahd_print_register(DSPSELECT_parse_table, 2, "DSPSELECT",
2809 0xc4, regvalue, cur_col, wrap));
2810}
2811
2812static ahd_reg_parse_entry_t WRTBIASCTL_parse_table[] = {
2813 { "XMITMANVAL", 0x3f, 0x3f },
2814 { "AUTOXBCDIS", 0x80, 0x80 }
2815};
2816
2817int
2818ahd_wrtbiasctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2819{
2820 return (ahd_print_register(WRTBIASCTL_parse_table, 2, "WRTBIASCTL",
2821 0xc5, regvalue, cur_col, wrap));
2822}
2823
2824static ahd_reg_parse_entry_t RCVRBIOSCTL_parse_table[] = {
2825 { "RCVRMANVAL", 0x3f, 0x3f },
2826 { "AUTORBCDIS", 0x80, 0x80 }
2827};
2828
2829int
2830ahd_rcvrbiosctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2831{
2832 return (ahd_print_register(RCVRBIOSCTL_parse_table, 2, "RCVRBIOSCTL",
2833 0xc6, regvalue, cur_col, wrap));
2834}
2835
2836int
2837ahd_wrtbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap)
2838{
2839 return (ahd_print_register(NULL, 0, "WRTBIASCALC",
2840 0xc7, regvalue, cur_col, wrap));
2841}
2842
2843int
2844ahd_dfptrs_print(u_int regvalue, u_int *cur_col, u_int wrap)
2845{
2846 return (ahd_print_register(NULL, 0, "DFPTRS",
2847 0xc8, regvalue, cur_col, wrap));
2848}
2849
2850int
2851ahd_rcvrbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap)
2852{
2853 return (ahd_print_register(NULL, 0, "RCVRBIASCALC",
2854 0xc8, regvalue, cur_col, wrap));
2855}
2856
2857int
2858ahd_dfbkptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2859{
2860 return (ahd_print_register(NULL, 0, "DFBKPTR",
2861 0xc9, regvalue, cur_col, wrap));
2862}
2863
2864int
2865ahd_skewcalc_print(u_int regvalue, u_int *cur_col, u_int wrap)
2866{
2867 return (ahd_print_register(NULL, 0, "SKEWCALC",
2868 0xc9, regvalue, cur_col, wrap));
2869}
2870
2871static ahd_reg_parse_entry_t DFDBCTL_parse_table[] = {
2872 { "DFF_RAMBIST_EN", 0x01, 0x01 },
2873 { "DFF_RAMBIST_DONE", 0x02, 0x02 },
2874 { "DFF_RAMBIST_FAIL", 0x04, 0x04 },
2875 { "DFF_DIR_ERR", 0x08, 0x08 },
2876 { "DFF_CIO_RD_RDY", 0x10, 0x10 },
2877 { "DFF_CIO_WR_RDY", 0x20, 0x20 }
2878};
2879
2880int
2881ahd_dfdbctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2882{
2883 return (ahd_print_register(DFDBCTL_parse_table, 6, "DFDBCTL",
2884 0xcb, regvalue, cur_col, wrap));
2885}
2886
2887int
2888ahd_dfscnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2889{
2890 return (ahd_print_register(NULL, 0, "DFSCNT",
2891 0xcc, regvalue, cur_col, wrap));
2892}
2893
2894int
2895ahd_dfbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2896{
2897 return (ahd_print_register(NULL, 0, "DFBCNT",
2898 0xce, regvalue, cur_col, wrap));
2899}
2900
2901int
2902ahd_ovlyaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
2903{
2904 return (ahd_print_register(NULL, 0, "OVLYADDR",
2905 0xd4, regvalue, cur_col, wrap));
2906}
2907
2908static ahd_reg_parse_entry_t SEQCTL0_parse_table[] = {
2909 { "LOADRAM", 0x01, 0x01 },
2910 { "SEQRESET", 0x02, 0x02 },
2911 { "STEP", 0x04, 0x04 },
2912 { "BRKADRINTEN", 0x08, 0x08 },
2913 { "FASTMODE", 0x10, 0x10 },
2914 { "FAILDIS", 0x20, 0x20 },
2915 { "PAUSEDIS", 0x40, 0x40 },
2916 { "PERRORDIS", 0x80, 0x80 }
2917};
2918
2919int
2920ahd_seqctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
2921{
2922 return (ahd_print_register(SEQCTL0_parse_table, 8, "SEQCTL0",
2923 0xd6, regvalue, cur_col, wrap));
2924}
2925
2926static ahd_reg_parse_entry_t SEQCTL1_parse_table[] = {
2927 { "RAMBIST_EN", 0x01, 0x01 },
2928 { "RAMBIST_FAIL", 0x02, 0x02 },
2929 { "RAMBIST_DONE", 0x04, 0x04 },
2930 { "OVRLAY_DATA_CHK", 0x08, 0x08 }
2931};
2932
2933int
2934ahd_seqctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
2935{
2936 return (ahd_print_register(SEQCTL1_parse_table, 4, "SEQCTL1",
2937 0xd7, regvalue, cur_col, wrap));
2938}
2939
2940static ahd_reg_parse_entry_t FLAGS_parse_table[] = {
2941 { "CARRY", 0x01, 0x01 },
2942 { "ZERO", 0x02, 0x02 }
2943};
2944
2945int
2946ahd_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
2947{
2948 return (ahd_print_register(FLAGS_parse_table, 2, "FLAGS",
2949 0xd8, regvalue, cur_col, wrap));
2950}
2951
2952static ahd_reg_parse_entry_t SEQINTCTL_parse_table[] = {
2953 { "IRET", 0x01, 0x01 },
2954 { "INTMASK1", 0x02, 0x02 },
2955 { "INTMASK2", 0x04, 0x04 },
2956 { "SCS_SEQ_INT1M0", 0x08, 0x08 },
2957 { "SCS_SEQ_INT1M1", 0x10, 0x10 },
2958 { "INT1_CONTEXT", 0x20, 0x20 },
2959 { "INTVEC1DSL", 0x80, 0x80 }
2960};
2961
2962int
2963ahd_seqintctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
2964{
2965 return (ahd_print_register(SEQINTCTL_parse_table, 7, "SEQINTCTL",
2966 0xd9, regvalue, cur_col, wrap));
2967}
2968
2969int
2970ahd_seqram_print(u_int regvalue, u_int *cur_col, u_int wrap)
2971{
2972 return (ahd_print_register(NULL, 0, "SEQRAM",
2973 0xda, regvalue, cur_col, wrap));
2974}
2975
2976int
2977ahd_prgmcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
2978{
2979 return (ahd_print_register(NULL, 0, "PRGMCNT",
2980 0xde, regvalue, cur_col, wrap));
2981}
2982
2983int
2984ahd_accum_print(u_int regvalue, u_int *cur_col, u_int wrap)
2985{
2986 return (ahd_print_register(NULL, 0, "ACCUM",
2987 0xe0, regvalue, cur_col, wrap));
2988}
2989
2990int
2991ahd_sindex_print(u_int regvalue, u_int *cur_col, u_int wrap)
2992{
2993 return (ahd_print_register(NULL, 0, "SINDEX",
2994 0xe2, regvalue, cur_col, wrap));
2995}
2996
2997int
2998ahd_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap)
2999{
3000 return (ahd_print_register(NULL, 0, "DINDEX",
3001 0xe4, regvalue, cur_col, wrap));
3002}
3003
3004static ahd_reg_parse_entry_t BRKADDR1_parse_table[] = {
3005 { "BRKDIS", 0x80, 0x80 }
3006};
3007
3008int
3009ahd_brkaddr1_print(u_int regvalue, u_int *cur_col, u_int wrap)
3010{
3011 return (ahd_print_register(BRKADDR1_parse_table, 1, "BRKADDR1",
3012 0xe6, regvalue, cur_col, wrap));
3013}
3014
3015int
3016ahd_brkaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap)
3017{
3018 return (ahd_print_register(NULL, 0, "BRKADDR0",
3019 0xe6, regvalue, cur_col, wrap));
3020}
3021
3022int
3023ahd_allones_print(u_int regvalue, u_int *cur_col, u_int wrap)
3024{
3025 return (ahd_print_register(NULL, 0, "ALLONES",
3026 0xe8, regvalue, cur_col, wrap));
3027}
3028
3029int
3030ahd_allzeros_print(u_int regvalue, u_int *cur_col, u_int wrap)
3031{
3032 return (ahd_print_register(NULL, 0, "ALLZEROS",
3033 0xea, regvalue, cur_col, wrap));
3034}
3035
3036int
3037ahd_none_print(u_int regvalue, u_int *cur_col, u_int wrap)
3038{
3039 return (ahd_print_register(NULL, 0, "NONE",
3040 0xea, regvalue, cur_col, wrap));
3041}
3042
3043int
3044ahd_sindir_print(u_int regvalue, u_int *cur_col, u_int wrap)
3045{
3046 return (ahd_print_register(NULL, 0, "SINDIR",
3047 0xec, regvalue, cur_col, wrap));
3048}
3049
3050int
3051ahd_dindir_print(u_int regvalue, u_int *cur_col, u_int wrap)
3052{
3053 return (ahd_print_register(NULL, 0, "DINDIR",
3054 0xed, regvalue, cur_col, wrap));
3055}
3056
3057int
3058ahd_function1_print(u_int regvalue, u_int *cur_col, u_int wrap)
3059{
3060 return (ahd_print_register(NULL, 0, "FUNCTION1",
3061 0xf0, regvalue, cur_col, wrap));
3062}
3063
3064int
3065ahd_stack_print(u_int regvalue, u_int *cur_col, u_int wrap)
3066{
3067 return (ahd_print_register(NULL, 0, "STACK",
3068 0xf2, regvalue, cur_col, wrap));
3069}
3070
3071int
3072ahd_curaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3073{
3074 return (ahd_print_register(NULL, 0, "CURADDR",
3075 0xf4, regvalue, cur_col, wrap));
3076}
3077
3078int
3079ahd_intvec1_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3080{
3081 return (ahd_print_register(NULL, 0, "INTVEC1_ADDR",
3082 0xf4, regvalue, cur_col, wrap));
3083}
3084
3085int
3086ahd_intvec2_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3087{
3088 return (ahd_print_register(NULL, 0, "INTVEC2_ADDR",
3089 0xf6, regvalue, cur_col, wrap));
3090}
3091
3092int
3093ahd_lastaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3094{
3095 return (ahd_print_register(NULL, 0, "LASTADDR",
3096 0xf6, regvalue, cur_col, wrap));
3097}
3098
3099int
3100ahd_longjmp_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3101{
3102 return (ahd_print_register(NULL, 0, "LONGJMP_ADDR",
3103 0xf8, regvalue, cur_col, wrap));
3104}
3105
3106int
3107ahd_accum_save_print(u_int regvalue, u_int *cur_col, u_int wrap)
3108{
3109 return (ahd_print_register(NULL, 0, "ACCUM_SAVE",
3110 0xfa, regvalue, cur_col, wrap));
3111}
3112
3113int
3114ahd_waiting_scb_tails_print(u_int regvalue, u_int *cur_col, u_int wrap)
3115{
3116 return (ahd_print_register(NULL, 0, "WAITING_SCB_TAILS",
3117 0x100, regvalue, cur_col, wrap));
3118}
3119
3120int
3121ahd_ahd_pci_config_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
3122{
3123 return (ahd_print_register(NULL, 0, "AHD_PCI_CONFIG_BASE",
3124 0x100, regvalue, cur_col, wrap));
3125}
3126
3127int
3128ahd_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
3129{
3130 return (ahd_print_register(NULL, 0, "SRAM_BASE",
3131 0x100, regvalue, cur_col, wrap));
3132}
3133
3134int
3135ahd_waiting_tid_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
3136{
3137 return (ahd_print_register(NULL, 0, "WAITING_TID_HEAD",
3138 0x120, regvalue, cur_col, wrap));
3139}
3140
3141int
3142ahd_waiting_tid_tail_print(u_int regvalue, u_int *cur_col, u_int wrap)
3143{
3144 return (ahd_print_register(NULL, 0, "WAITING_TID_TAIL",
3145 0x122, regvalue, cur_col, wrap));
3146}
3147
3148int
3149ahd_next_queued_scb_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3150{
3151 return (ahd_print_register(NULL, 0, "NEXT_QUEUED_SCB_ADDR",
3152 0x124, regvalue, cur_col, wrap));
3153}
3154
3155int
3156ahd_complete_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
3157{
3158 return (ahd_print_register(NULL, 0, "COMPLETE_SCB_HEAD",
3159 0x128, regvalue, cur_col, wrap));
3160}
3161
3162int
3163ahd_complete_scb_dmainprog_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
3164{
3165 return (ahd_print_register(NULL, 0, "COMPLETE_SCB_DMAINPROG_HEAD",
3166 0x12a, regvalue, cur_col, wrap));
3167}
3168
3169int
3170ahd_complete_dma_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
3171{
3172 return (ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_HEAD",
3173 0x12c, regvalue, cur_col, wrap));
3174}
3175
3176int
3177ahd_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap)
3178{
3179 return (ahd_print_register(NULL, 0, "QFREEZE_COUNT",
3180 0x12e, regvalue, cur_col, wrap));
3181}
3182
3183int
3184ahd_saved_mode_print(u_int regvalue, u_int *cur_col, u_int wrap)
3185{
3186 return (ahd_print_register(NULL, 0, "SAVED_MODE",
3187 0x130, regvalue, cur_col, wrap));
3188}
3189
3190int
3191ahd_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap)
3192{
3193 return (ahd_print_register(NULL, 0, "MSG_OUT",
3194 0x131, regvalue, cur_col, wrap));
3195}
3196
3197static ahd_reg_parse_entry_t DMAPARAMS_parse_table[] = {
3198 { "FIFORESET", 0x01, 0x01 },
3199 { "FIFOFLUSH", 0x02, 0x02 },
3200 { "DIRECTION", 0x04, 0x04 },
3201 { "HDMAEN", 0x08, 0x08 },
3202 { "HDMAENACK", 0x08, 0x08 },
3203 { "SDMAEN", 0x10, 0x10 },
3204 { "SDMAENACK", 0x10, 0x10 },
3205 { "SCSIEN", 0x20, 0x20 },
3206 { "WIDEODD", 0x40, 0x40 },
3207 { "PRELOADEN", 0x80, 0x80 }
3208};
3209
3210int
3211ahd_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap)
3212{
3213 return (ahd_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS",
3214 0x132, regvalue, cur_col, wrap));
3215}
3216
3217static ahd_reg_parse_entry_t SEQ_FLAGS_parse_table[] = {
3218 { "NO_DISCONNECT", 0x01, 0x01 },
3219 { "SPHASE_PENDING", 0x02, 0x02 },
3220 { "DPHASE_PENDING", 0x04, 0x04 },
3221 { "CMDPHASE_PENDING", 0x08, 0x08 },
3222 { "TARG_CMD_PENDING", 0x10, 0x10 },
3223 { "DPHASE", 0x20, 0x20 },
3224 { "NO_CDB_SENT", 0x40, 0x40 },
3225 { "TARGET_CMD_IS_TAGGED",0x40, 0x40 },
3226 { "NOT_IDENTIFIED", 0x80, 0x80 }
3227};
3228
3229int
3230ahd_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
3231{
3232 return (ahd_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS",
3233 0x133, regvalue, cur_col, wrap));
3234}
3235
3236int
3237ahd_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
3238{
3239 return (ahd_print_register(NULL, 0, "SAVED_SCSIID",
3240 0x134, regvalue, cur_col, wrap));
3241}
3242
3243int
3244ahd_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
3245{
3246 return (ahd_print_register(NULL, 0, "SAVED_LUN",
3247 0x135, regvalue, cur_col, wrap));
3248}
3249
3250static ahd_reg_parse_entry_t LASTPHASE_parse_table[] = {
3251 { "P_DATAOUT", 0x00, 0xe0 },
3252 { "P_DATAOUT_DT", 0x20, 0xe0 },
3253 { "P_DATAIN", 0x40, 0xe0 },
3254 { "P_DATAIN_DT", 0x60, 0xe0 },
3255 { "P_COMMAND", 0x80, 0xe0 },
3256 { "P_MESGOUT", 0xa0, 0xe0 },
3257 { "P_STATUS", 0xc0, 0xe0 },
3258 { "P_MESGIN", 0xe0, 0xe0 },
3259 { "P_BUSFREE", 0x01, 0x01 },
3260 { "MSGI", 0x20, 0x20 },
3261 { "IOI", 0x40, 0x40 },
3262 { "CDI", 0x80, 0x80 },
3263 { "PHASE_MASK", 0xe0, 0xe0 }
3264};
3265
3266int
3267ahd_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
3268{
3269 return (ahd_print_register(LASTPHASE_parse_table, 13, "LASTPHASE",
3270 0x136, regvalue, cur_col, wrap));
3271}
3272
3273int
3274ahd_qoutfifo_entry_valid_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
3275{
3276 return (ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG",
3277 0x137, regvalue, cur_col, wrap));
3278}
3279
3280int
3281ahd_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3282{
3283 return (ahd_print_register(NULL, 0, "SHARED_DATA_ADDR",
3284 0x138, regvalue, cur_col, wrap));
3285}
3286
3287int
3288ahd_qoutfifo_next_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3289{
3290 return (ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR",
3291 0x13c, regvalue, cur_col, wrap));
3292}
3293
3294int
3295ahd_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
3296{
3297 return (ahd_print_register(NULL, 0, "KERNEL_TQINPOS",
3298 0x140, regvalue, cur_col, wrap));
3299}
3300
3301int
3302ahd_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
3303{
3304 return (ahd_print_register(NULL, 0, "TQINPOS",
3305 0x141, regvalue, cur_col, wrap));
3306}
3307
3308static ahd_reg_parse_entry_t ARG_1_parse_table[] = {
3309 { "CONT_MSG_LOOP_TARG", 0x02, 0x02 },
3310 { "CONT_MSG_LOOP_READ", 0x03, 0x03 },
3311 { "CONT_MSG_LOOP_WRITE",0x04, 0x04 },
3312 { "EXIT_MSG_LOOP", 0x08, 0x08 },
3313 { "MSGOUT_PHASEMIS", 0x10, 0x10 },
3314 { "SEND_REJ", 0x20, 0x20 },
3315 { "SEND_SENSE", 0x40, 0x40 },
3316 { "SEND_MSG", 0x80, 0x80 }
3317};
3318
3319int
3320ahd_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap)
3321{
3322 return (ahd_print_register(ARG_1_parse_table, 8, "ARG_1",
3323 0x142, regvalue, cur_col, wrap));
3324}
3325
3326int
3327ahd_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap)
3328{
3329 return (ahd_print_register(NULL, 0, "ARG_2",
3330 0x143, regvalue, cur_col, wrap));
3331}
3332
3333int
3334ahd_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap)
3335{
3336 return (ahd_print_register(NULL, 0, "LAST_MSG",
3337 0x144, regvalue, cur_col, wrap));
3338}
3339
3340static ahd_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = {
3341 { "ALTSTIM", 0x01, 0x01 },
3342 { "ENAUTOATNP", 0x02, 0x02 },
3343 { "MANUALP", 0x0c, 0x0c },
3344 { "ENRSELI", 0x10, 0x10 },
3345 { "ENSELI", 0x20, 0x20 },
3346 { "MANUALCTL", 0x40, 0x40 }
3347};
3348
3349int
3350ahd_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap)
3351{
3352 return (ahd_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE",
3353 0x145, regvalue, cur_col, wrap));
3354}
3355
3356int
3357ahd_initiator_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
3358{
3359 return (ahd_print_register(NULL, 0, "INITIATOR_TAG",
3360 0x146, regvalue, cur_col, wrap));
3361}
3362
3363static ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = {
3364 { "TARGET_MSG_PENDING", 0x02, 0x02 },
3365 { "SELECTOUT_QFROZEN", 0x04, 0x04 }
3366};
3367
3368int
3369ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap)
3370{
3371 return (ahd_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2",
3372 0x147, regvalue, cur_col, wrap));
3373}
3374
3375int
3376ahd_allocfifo_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3377{
3378 return (ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR",
3379 0x148, regvalue, cur_col, wrap));
3380}
3381
3382int
3383ahd_int_coalescing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap)
3384{
3385 return (ahd_print_register(NULL, 0, "INT_COALESCING_TIMER",
3386 0x14a, regvalue, cur_col, wrap));
3387}
3388
3389int
3390ahd_int_coalescing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
3391{
3392 return (ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS",
3393 0x14c, regvalue, cur_col, wrap));
3394}
3395
3396int
3397ahd_int_coalescing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
3398{
3399 return (ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS",
3400 0x14d, regvalue, cur_col, wrap));
3401}
3402
3403int
3404ahd_cmds_pending_print(u_int regvalue, u_int *cur_col, u_int wrap)
3405{
3406 return (ahd_print_register(NULL, 0, "CMDS_PENDING",
3407 0x14e, regvalue, cur_col, wrap));
3408}
3409
3410int
3411ahd_int_coalescing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
3412{
3413 return (ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT",
3414 0x150, regvalue, cur_col, wrap));
3415}
3416
3417int
3418ahd_local_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap)
3419{
3420 return (ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX",
3421 0x151, regvalue, cur_col, wrap));
3422}
3423
3424int
3425ahd_cmdsize_table_print(u_int regvalue, u_int *cur_col, u_int wrap)
3426{
3427 return (ahd_print_register(NULL, 0, "CMDSIZE_TABLE",
3428 0x152, regvalue, cur_col, wrap));
3429}
3430
3431int
3432ahd_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
3433{
3434 return (ahd_print_register(NULL, 0, "SCB_BASE",
3435 0x180, regvalue, cur_col, wrap));
3436}
3437
3438int
3439ahd_scb_residual_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
3440{
3441 return (ahd_print_register(NULL, 0, "SCB_RESIDUAL_DATACNT",
3442 0x180, regvalue, cur_col, wrap));
3443}
3444
3445static ahd_reg_parse_entry_t SCB_RESIDUAL_SGPTR_parse_table[] = {
3446 { "SG_LIST_NULL", 0x01, 0x01 },
3447 { "SG_OVERRUN_RESID", 0x02, 0x02 },
3448 { "SG_ADDR_MASK", 0xf8, 0xf8 }
3449};
3450
3451int
3452ahd_scb_residual_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3453{
3454 return (ahd_print_register(SCB_RESIDUAL_SGPTR_parse_table, 3, "SCB_RESIDUAL_SGPTR",
3455 0x184, regvalue, cur_col, wrap));
3456}
3457
3458int
3459ahd_scb_scsi_status_print(u_int regvalue, u_int *cur_col, u_int wrap)
3460{
3461 return (ahd_print_register(NULL, 0, "SCB_SCSI_STATUS",
3462 0x188, regvalue, cur_col, wrap));
3463}
3464
3465int
3466ahd_scb_target_phases_print(u_int regvalue, u_int *cur_col, u_int wrap)
3467{
3468 return (ahd_print_register(NULL, 0, "SCB_TARGET_PHASES",
3469 0x189, regvalue, cur_col, wrap));
3470}
3471
3472int
3473ahd_scb_target_data_dir_print(u_int regvalue, u_int *cur_col, u_int wrap)
3474{
3475 return (ahd_print_register(NULL, 0, "SCB_TARGET_DATA_DIR",
3476 0x18a, regvalue, cur_col, wrap));
3477}
3478
3479int
3480ahd_scb_target_itag_print(u_int regvalue, u_int *cur_col, u_int wrap)
3481{
3482 return (ahd_print_register(NULL, 0, "SCB_TARGET_ITAG",
3483 0x18b, regvalue, cur_col, wrap));
3484}
3485
3486int
3487ahd_scb_sense_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3488{
3489 return (ahd_print_register(NULL, 0, "SCB_SENSE_BUSADDR",
3490 0x18c, regvalue, cur_col, wrap));
3491}
3492
3493int
3494ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
3495{
3496 return (ahd_print_register(NULL, 0, "SCB_TAG",
3497 0x190, regvalue, cur_col, wrap));
3498}
3499
3500static ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = {
3501 { "SCB_TAG_TYPE", 0x03, 0x03 },
3502 { "DISCONNECTED", 0x04, 0x04 },
3503 { "STATUS_RCVD", 0x08, 0x08 },
3504 { "MK_MESSAGE", 0x10, 0x10 },
3505 { "TAG_ENB", 0x20, 0x20 },
3506 { "DISCENB", 0x40, 0x40 },
3507 { "TARGET_SCB", 0x80, 0x80 }
3508};
3509
3510int
3511ahd_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap)
3512{
3513 return (ahd_print_register(SCB_CONTROL_parse_table, 7, "SCB_CONTROL",
3514 0x192, regvalue, cur_col, wrap));
3515}
3516
3517static ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = {
3518 { "OID", 0x0f, 0x0f },
3519 { "TID", 0xf0, 0xf0 }
3520};
3521
3522int
3523ahd_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
3524{
3525 return (ahd_print_register(SCB_SCSIID_parse_table, 2, "SCB_SCSIID",
3526 0x193, regvalue, cur_col, wrap));
3527}
3528
3529static ahd_reg_parse_entry_t SCB_LUN_parse_table[] = {
3530 { "LID", 0xff, 0xff }
3531};
3532
3533int
3534ahd_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
3535{
3536 return (ahd_print_register(SCB_LUN_parse_table, 1, "SCB_LUN",
3537 0x194, regvalue, cur_col, wrap));
3538}
3539
3540static ahd_reg_parse_entry_t SCB_TASK_ATTRIBUTE_parse_table[] = {
3541 { "SCB_XFERLEN_ODD", 0x01, 0x01 }
3542};
3543
3544int
3545ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap)
3546{
3547 return (ahd_print_register(SCB_TASK_ATTRIBUTE_parse_table, 1, "SCB_TASK_ATTRIBUTE",
3548 0x195, regvalue, cur_col, wrap));
3549}
3550
3551static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = {
3552 { "SCB_CDB_LEN_PTR", 0x80, 0x80 }
3553};
3554
3555int
3556ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap)
3557{
3558 return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN",
3559 0x196, regvalue, cur_col, wrap));
3560}
3561
3562int
3563ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap)
3564{
3565 return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT",
3566 0x197, regvalue, cur_col, wrap));
3567}
3568
3569int
3570ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3571{
3572 return (ahd_print_register(NULL, 0, "SCB_DATAPTR",
3573 0x198, regvalue, cur_col, wrap));
3574}
3575
3576static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = {
3577 { "SG_HIGH_ADDR_BITS", 0x7f, 0x7f },
3578 { "SG_LAST_SEG", 0x80, 0x80 }
3579};
3580
3581int
3582ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
3583{
3584 return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT",
3585 0x1a0, regvalue, cur_col, wrap));
3586}
3587
3588static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = {
3589 { "SG_LIST_NULL", 0x01, 0x01 },
3590 { "SG_FULL_RESID", 0x02, 0x02 },
3591 { "SG_STATUS_VALID", 0x04, 0x04 }
3592};
3593
3594int
3595ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3596{
3597 return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR",
3598 0x1a4, regvalue, cur_col, wrap));
3599}
3600
3601int
3602ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
3603{
3604 return (ahd_print_register(NULL, 0, "SCB_BUSADDR",
3605 0x1a8, regvalue, cur_col, wrap));
3606}
3607
3608int
3609ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
3610{
3611 return (ahd_print_register(NULL, 0, "SCB_NEXT",
3612 0x1ac, regvalue, cur_col, wrap));
3613}
3614
3615int
3616ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap)
3617{
3618 return (ahd_print_register(NULL, 0, "SCB_NEXT2",
3619 0x1ae, regvalue, cur_col, wrap));
3620}
3621
3622int
3623ahd_scb_spare_print(u_int regvalue, u_int *cur_col, u_int wrap)
3624{
3625 return (ahd_print_register(NULL, 0, "SCB_SPARE",
3626 0x1b0, regvalue, cur_col, wrap));
3627}
3628
3629int
3630ahd_scb_disconnected_lists_print(u_int regvalue, u_int *cur_col, u_int wrap)
3631{
3632 return (ahd_print_register(NULL, 0, "SCB_DISCONNECTED_LISTS",
3633 0x1b8, regvalue, cur_col, wrap));
3634}
3635
diff --git a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
new file mode 100644
index 000000000000..77c471f934e0
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
@@ -0,0 +1,1139 @@
1/*
2 * DO NOT EDIT - This file is automatically generated
3 * from the following source files:
4 *
5 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
6 * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
7 */
8static uint8_t seqprog[] = {
9 0xff, 0x02, 0x06, 0x78,
10 0x00, 0xea, 0x50, 0x59,
11 0x01, 0xea, 0x04, 0x30,
12 0xff, 0x04, 0x0c, 0x78,
13 0x19, 0xea, 0x50, 0x59,
14 0x19, 0xea, 0x04, 0x00,
15 0x33, 0xea, 0x44, 0x59,
16 0x33, 0xea, 0x00, 0x00,
17 0x60, 0x3a, 0x1a, 0x68,
18 0x04, 0x47, 0x1b, 0x68,
19 0xff, 0x21, 0x1b, 0x70,
20 0x40, 0x4b, 0x92, 0x69,
21 0x00, 0xe2, 0x54, 0x59,
22 0x40, 0x4b, 0x92, 0x69,
23 0x20, 0x4b, 0x82, 0x69,
24 0xfc, 0x42, 0x24, 0x78,
25 0x10, 0x40, 0x24, 0x78,
26 0x00, 0xe2, 0xc4, 0x5d,
27 0x20, 0x4d, 0x28, 0x78,
28 0x00, 0xe2, 0xc4, 0x5d,
29 0x30, 0x3f, 0xc0, 0x09,
30 0x30, 0xe0, 0x30, 0x60,
31 0x7f, 0x4a, 0x94, 0x08,
32 0x00, 0xe2, 0x32, 0x40,
33 0xc0, 0x4a, 0x94, 0x00,
34 0x00, 0xe2, 0x3e, 0x58,
35 0x00, 0xe2, 0x56, 0x58,
36 0x00, 0xe2, 0x66, 0x58,
37 0x00, 0xe2, 0x06, 0x40,
38 0x33, 0xea, 0x44, 0x59,
39 0x33, 0xea, 0x00, 0x00,
40 0x01, 0x52, 0x64, 0x78,
41 0x02, 0x58, 0x50, 0x31,
42 0xff, 0xea, 0x10, 0x0b,
43 0xff, 0x97, 0x4f, 0x78,
44 0x50, 0x4b, 0x4a, 0x68,
45 0xbf, 0x3a, 0x74, 0x08,
46 0x14, 0xea, 0x50, 0x59,
47 0x14, 0xea, 0x04, 0x00,
48 0x08, 0x92, 0x25, 0x03,
49 0xff, 0x90, 0x3f, 0x68,
50 0x00, 0xe2, 0x56, 0x5b,
51 0x00, 0xe2, 0x3e, 0x40,
52 0x00, 0xea, 0x44, 0x59,
53 0x01, 0xea, 0x00, 0x30,
54 0x80, 0xf9, 0x5e, 0x68,
55 0x00, 0xe2, 0x42, 0x59,
56 0x11, 0xea, 0x44, 0x59,
57 0x11, 0xea, 0x00, 0x00,
58 0x80, 0xf9, 0x42, 0x79,
59 0xff, 0xea, 0xd4, 0x0d,
60 0x22, 0xea, 0x44, 0x59,
61 0x22, 0xea, 0x00, 0x00,
62 0x10, 0x16, 0x70, 0x78,
63 0x01, 0x0b, 0xa2, 0x32,
64 0x10, 0x16, 0x2c, 0x00,
65 0x18, 0xad, 0x00, 0x79,
66 0x04, 0xad, 0xca, 0x68,
67 0x80, 0xad, 0x64, 0x78,
68 0x10, 0xad, 0x98, 0x78,
69 0xff, 0x88, 0x83, 0x68,
70 0xe7, 0xad, 0x5a, 0x09,
71 0x02, 0x8c, 0x59, 0x32,
72 0x02, 0x28, 0x19, 0x33,
73 0x02, 0xa8, 0x50, 0x36,
74 0x33, 0xea, 0x44, 0x59,
75 0x33, 0xea, 0x00, 0x00,
76 0x40, 0x3a, 0x64, 0x68,
77 0x50, 0x4b, 0x64, 0x68,
78 0x22, 0xea, 0x44, 0x59,
79 0x22, 0xea, 0x00, 0x00,
80 0xe7, 0xad, 0x5a, 0x09,
81 0x02, 0x8c, 0x59, 0x32,
82 0x1a, 0xea, 0x50, 0x59,
83 0x1a, 0xea, 0x04, 0x00,
84 0xff, 0xea, 0xd4, 0x0d,
85 0xe7, 0xad, 0x5a, 0x09,
86 0x00, 0xe2, 0xa6, 0x58,
87 0xff, 0xea, 0x56, 0x02,
88 0x04, 0x7c, 0x78, 0x32,
89 0x20, 0x16, 0x64, 0x78,
90 0x04, 0x38, 0x79, 0x32,
91 0x80, 0x37, 0x6f, 0x16,
92 0xff, 0x2d, 0xb5, 0x60,
93 0xff, 0x29, 0xb5, 0x60,
94 0x40, 0x51, 0xc5, 0x78,
95 0xff, 0x4f, 0xb5, 0x68,
96 0xff, 0x4d, 0xc1, 0x19,
97 0x00, 0x4e, 0xd5, 0x19,
98 0x00, 0xe2, 0xc4, 0x50,
99 0x01, 0x4c, 0xc1, 0x31,
100 0x00, 0x50, 0xd5, 0x19,
101 0x00, 0xe2, 0xc4, 0x48,
102 0x80, 0x18, 0x64, 0x78,
103 0x02, 0x4a, 0x1d, 0x30,
104 0x10, 0xea, 0x18, 0x00,
105 0x60, 0x18, 0x30, 0x00,
106 0x7f, 0x18, 0x30, 0x0c,
107 0x02, 0xea, 0x02, 0x00,
108 0xff, 0xea, 0xa0, 0x0a,
109 0x80, 0x18, 0x30, 0x04,
110 0x40, 0xad, 0x64, 0x78,
111 0xe7, 0xad, 0x5a, 0x09,
112 0x02, 0xa8, 0x40, 0x31,
113 0xff, 0xea, 0xc0, 0x09,
114 0x01, 0x4e, 0x9d, 0x1a,
115 0x00, 0x4f, 0x9f, 0x22,
116 0x01, 0x94, 0x6d, 0x33,
117 0x01, 0xea, 0x20, 0x33,
118 0x04, 0xac, 0x49, 0x32,
119 0xff, 0xea, 0x5a, 0x03,
120 0xff, 0xea, 0x5e, 0x03,
121 0x01, 0x10, 0xd4, 0x31,
122 0x10, 0x92, 0xf5, 0x68,
123 0x3d, 0x93, 0xc5, 0x29,
124 0xfe, 0xe2, 0xc4, 0x09,
125 0x01, 0xea, 0xc6, 0x01,
126 0x02, 0xe2, 0xc8, 0x31,
127 0x02, 0xec, 0x50, 0x31,
128 0x02, 0xa0, 0xda, 0x31,
129 0xff, 0xa9, 0xf4, 0x70,
130 0x02, 0xa0, 0x58, 0x37,
131 0xff, 0x21, 0xfd, 0x70,
132 0x02, 0x22, 0x51, 0x31,
133 0x02, 0xa0, 0x5c, 0x33,
134 0x02, 0xa0, 0x44, 0x36,
135 0x02, 0xa0, 0x40, 0x32,
136 0x02, 0xa0, 0x44, 0x36,
137 0x04, 0x47, 0x05, 0x69,
138 0x40, 0x16, 0x30, 0x69,
139 0xff, 0x2d, 0x35, 0x61,
140 0xff, 0x29, 0x65, 0x70,
141 0x01, 0x37, 0xc1, 0x31,
142 0x02, 0x28, 0x55, 0x32,
143 0x01, 0xea, 0x5a, 0x01,
144 0x04, 0x3c, 0xf9, 0x30,
145 0x02, 0x28, 0x51, 0x31,
146 0x01, 0xa8, 0x60, 0x31,
147 0x00, 0xa9, 0x60, 0x01,
148 0x01, 0x14, 0xd4, 0x31,
149 0x01, 0x50, 0xa1, 0x1a,
150 0xff, 0x4e, 0x9d, 0x1a,
151 0xff, 0x4f, 0x9f, 0x22,
152 0xff, 0x8d, 0x29, 0x71,
153 0x80, 0xac, 0x28, 0x71,
154 0x20, 0x16, 0x28, 0x69,
155 0x02, 0x8c, 0x51, 0x31,
156 0x00, 0xe2, 0x12, 0x41,
157 0x01, 0xac, 0x08, 0x31,
158 0x09, 0xea, 0x5a, 0x01,
159 0x02, 0x8c, 0x51, 0x32,
160 0xff, 0xea, 0x1a, 0x07,
161 0x04, 0x24, 0xf9, 0x30,
162 0x1d, 0xea, 0x3a, 0x41,
163 0x02, 0x2c, 0x51, 0x31,
164 0x04, 0xa8, 0xf9, 0x30,
165 0x19, 0xea, 0x3a, 0x41,
166 0x06, 0xea, 0x08, 0x81,
167 0x01, 0xe2, 0x5a, 0x35,
168 0x02, 0xf2, 0xf0, 0x35,
169 0x02, 0xf2, 0xf0, 0x31,
170 0x02, 0xf8, 0xe4, 0x35,
171 0x80, 0xea, 0xb2, 0x01,
172 0x01, 0xe2, 0x00, 0x30,
173 0xff, 0xea, 0xb2, 0x0d,
174 0x80, 0xea, 0xb2, 0x01,
175 0x11, 0x00, 0x00, 0x10,
176 0xff, 0xea, 0xb2, 0x0d,
177 0x01, 0xe2, 0x04, 0x30,
178 0x01, 0xea, 0x04, 0x34,
179 0x02, 0x20, 0xbd, 0x30,
180 0x02, 0x20, 0xb9, 0x30,
181 0x02, 0x20, 0x51, 0x31,
182 0x4c, 0x93, 0xd7, 0x28,
183 0x10, 0x92, 0x63, 0x79,
184 0x01, 0x6b, 0xc0, 0x30,
185 0x02, 0x64, 0xc8, 0x00,
186 0x40, 0x3a, 0x74, 0x04,
187 0x00, 0xe2, 0x56, 0x58,
188 0x33, 0xea, 0x44, 0x59,
189 0x33, 0xea, 0x00, 0x00,
190 0x30, 0x3f, 0xc0, 0x09,
191 0x30, 0xe0, 0x64, 0x61,
192 0x20, 0x3f, 0x7a, 0x69,
193 0x10, 0x3f, 0x64, 0x79,
194 0x02, 0xea, 0x7e, 0x00,
195 0x00, 0xea, 0x44, 0x59,
196 0x01, 0xea, 0x00, 0x30,
197 0x02, 0x48, 0x51, 0x35,
198 0x01, 0xea, 0x7e, 0x00,
199 0x11, 0xea, 0x44, 0x59,
200 0x11, 0xea, 0x00, 0x00,
201 0x02, 0x48, 0x51, 0x35,
202 0x08, 0xea, 0x98, 0x00,
203 0x08, 0x57, 0xae, 0x00,
204 0x08, 0x3c, 0x78, 0x00,
205 0xf0, 0x49, 0x68, 0x0a,
206 0x0f, 0x67, 0xc0, 0x09,
207 0x00, 0x34, 0x69, 0x02,
208 0x20, 0xea, 0x96, 0x00,
209 0x00, 0xe2, 0xf8, 0x41,
210 0x40, 0x3a, 0xae, 0x69,
211 0x02, 0x55, 0x06, 0x68,
212 0x02, 0x56, 0xae, 0x69,
213 0xff, 0x5b, 0xae, 0x61,
214 0x02, 0x20, 0x51, 0x31,
215 0x80, 0xea, 0xb2, 0x01,
216 0x44, 0xea, 0x00, 0x00,
217 0x01, 0x33, 0xc0, 0x31,
218 0x33, 0xea, 0x00, 0x00,
219 0xff, 0xea, 0xb2, 0x09,
220 0xff, 0xe0, 0xc0, 0x19,
221 0xff, 0xe0, 0xb0, 0x79,
222 0x02, 0xac, 0x51, 0x31,
223 0x00, 0xe2, 0xa6, 0x41,
224 0x02, 0x5e, 0x50, 0x31,
225 0x02, 0xa8, 0xb8, 0x30,
226 0x02, 0x5c, 0x50, 0x31,
227 0xff, 0xad, 0xc1, 0x71,
228 0x02, 0xac, 0x41, 0x31,
229 0x02, 0x22, 0x51, 0x31,
230 0x02, 0xa0, 0x5c, 0x33,
231 0x02, 0xa0, 0x44, 0x32,
232 0x00, 0xe2, 0xca, 0x41,
233 0x10, 0x92, 0xcb, 0x69,
234 0x3d, 0x93, 0xc9, 0x29,
235 0x01, 0xe4, 0xc8, 0x01,
236 0x01, 0xea, 0xca, 0x01,
237 0xff, 0xea, 0xda, 0x01,
238 0x02, 0x20, 0x51, 0x31,
239 0x02, 0xae, 0x41, 0x32,
240 0xff, 0x21, 0xd3, 0x61,
241 0xff, 0xea, 0x46, 0x02,
242 0x02, 0x5c, 0x50, 0x31,
243 0x40, 0xea, 0x96, 0x00,
244 0x02, 0x56, 0xcc, 0x6d,
245 0x01, 0x55, 0xcc, 0x6d,
246 0x10, 0x92, 0xdf, 0x79,
247 0x10, 0x40, 0xe8, 0x69,
248 0x01, 0x56, 0xe8, 0x79,
249 0xff, 0x97, 0x07, 0x78,
250 0x13, 0xea, 0x50, 0x59,
251 0x13, 0xea, 0x04, 0x00,
252 0x00, 0xe2, 0x06, 0x40,
253 0xbf, 0x3a, 0x74, 0x08,
254 0x08, 0xea, 0x98, 0x00,
255 0x08, 0x57, 0xae, 0x00,
256 0x01, 0x93, 0x69, 0x32,
257 0x01, 0x94, 0x6b, 0x32,
258 0x40, 0xea, 0x66, 0x02,
259 0x08, 0x3c, 0x78, 0x00,
260 0x80, 0xea, 0x62, 0x02,
261 0x00, 0xe2, 0xb8, 0x5b,
262 0x01, 0x36, 0xc1, 0x31,
263 0x9f, 0xe0, 0x4c, 0x7c,
264 0x80, 0xe0, 0x0c, 0x72,
265 0xa0, 0xe0, 0x44, 0x72,
266 0xc0, 0xe0, 0x3a, 0x72,
267 0xe0, 0xe0, 0x74, 0x72,
268 0x01, 0xea, 0x50, 0x59,
269 0x01, 0xea, 0x04, 0x00,
270 0x00, 0xe2, 0xf8, 0x41,
271 0x80, 0x33, 0x13, 0x7a,
272 0x03, 0xea, 0x50, 0x59,
273 0x03, 0xea, 0x04, 0x00,
274 0xee, 0x00, 0x1a, 0x6a,
275 0x05, 0xea, 0xb4, 0x00,
276 0x33, 0xea, 0x44, 0x59,
277 0x33, 0xea, 0x00, 0x00,
278 0x02, 0xa8, 0x90, 0x32,
279 0x00, 0xe2, 0x6a, 0x59,
280 0xef, 0x96, 0xd5, 0x19,
281 0x00, 0xe2, 0x2a, 0x52,
282 0x09, 0x80, 0xe1, 0x30,
283 0x02, 0xea, 0x36, 0x00,
284 0xa8, 0xea, 0x32, 0x00,
285 0x00, 0xe2, 0x30, 0x42,
286 0x01, 0x96, 0xd1, 0x30,
287 0x10, 0x80, 0x89, 0x31,
288 0x20, 0xea, 0x32, 0x00,
289 0xbf, 0x33, 0x67, 0x0a,
290 0x20, 0x19, 0x32, 0x6a,
291 0x02, 0x4d, 0xf8, 0x69,
292 0x40, 0x33, 0x67, 0x02,
293 0x00, 0xe2, 0xf8, 0x41,
294 0x80, 0x33, 0xb5, 0x6a,
295 0x01, 0x44, 0x10, 0x33,
296 0x08, 0x92, 0x25, 0x03,
297 0x00, 0xe2, 0xf8, 0x41,
298 0x10, 0xea, 0x80, 0x00,
299 0x01, 0x31, 0xc5, 0x31,
300 0x80, 0xe2, 0x60, 0x62,
301 0x10, 0x92, 0x85, 0x6a,
302 0xc0, 0x94, 0xc5, 0x01,
303 0x40, 0x92, 0x51, 0x6a,
304 0xbf, 0xe2, 0xc4, 0x09,
305 0x20, 0x92, 0x65, 0x7a,
306 0x01, 0xe2, 0x88, 0x30,
307 0x00, 0xe2, 0xb8, 0x5b,
308 0xa0, 0x36, 0x6d, 0x62,
309 0x23, 0x92, 0x89, 0x08,
310 0x00, 0xe2, 0xb8, 0x5b,
311 0xa0, 0x36, 0x6d, 0x62,
312 0x00, 0xa8, 0x64, 0x42,
313 0xff, 0xe2, 0x64, 0x62,
314 0x00, 0xe2, 0x84, 0x42,
315 0x40, 0xea, 0x98, 0x00,
316 0x01, 0xe2, 0x88, 0x30,
317 0x00, 0xe2, 0xb8, 0x5b,
318 0xa0, 0x36, 0x43, 0x72,
319 0x40, 0xea, 0x98, 0x00,
320 0x01, 0x31, 0x89, 0x32,
321 0x08, 0xea, 0x62, 0x02,
322 0x00, 0xe2, 0xf8, 0x41,
323 0xe0, 0xea, 0xd4, 0x5b,
324 0x80, 0xe0, 0xc0, 0x6a,
325 0x04, 0xe0, 0x66, 0x73,
326 0x02, 0xe0, 0x96, 0x73,
327 0x00, 0xea, 0x1e, 0x73,
328 0x03, 0xe0, 0xa6, 0x73,
329 0x23, 0xe0, 0x96, 0x72,
330 0x08, 0xe0, 0xbc, 0x72,
331 0x00, 0xe2, 0xb8, 0x5b,
332 0x07, 0xea, 0x50, 0x59,
333 0x07, 0xea, 0x04, 0x00,
334 0x08, 0x42, 0xf9, 0x71,
335 0x04, 0x42, 0x93, 0x62,
336 0x01, 0x43, 0x89, 0x30,
337 0x00, 0xe2, 0x84, 0x42,
338 0x01, 0x44, 0xd4, 0x31,
339 0x00, 0xe2, 0x84, 0x42,
340 0x01, 0x00, 0x60, 0x32,
341 0x33, 0xea, 0x44, 0x59,
342 0x33, 0xea, 0x00, 0x00,
343 0x4c, 0x34, 0xc1, 0x28,
344 0x01, 0x64, 0xc0, 0x31,
345 0x00, 0x30, 0x45, 0x59,
346 0x01, 0x30, 0x01, 0x30,
347 0x01, 0xe0, 0xba, 0x7a,
348 0xa0, 0xea, 0xca, 0x5b,
349 0x01, 0xa0, 0xba, 0x62,
350 0x01, 0x84, 0xaf, 0x7a,
351 0x01, 0x95, 0xbd, 0x6a,
352 0x05, 0xea, 0x50, 0x59,
353 0x05, 0xea, 0x04, 0x00,
354 0x00, 0xe2, 0xbc, 0x42,
355 0x03, 0xea, 0x50, 0x59,
356 0x03, 0xea, 0x04, 0x00,
357 0x00, 0xe2, 0xbc, 0x42,
358 0x07, 0xea, 0xdc, 0x5b,
359 0x01, 0x44, 0xd4, 0x31,
360 0x00, 0xe2, 0xf8, 0x41,
361 0x3f, 0xe0, 0x6a, 0x0a,
362 0xc0, 0x34, 0xc1, 0x09,
363 0x00, 0x35, 0x51, 0x01,
364 0xff, 0xea, 0x52, 0x09,
365 0x30, 0x34, 0xc5, 0x09,
366 0x3d, 0xe2, 0xc4, 0x29,
367 0xb8, 0xe2, 0xc4, 0x19,
368 0x01, 0xea, 0xc6, 0x01,
369 0x02, 0xe2, 0xc8, 0x31,
370 0x02, 0xec, 0x40, 0x31,
371 0xff, 0xa1, 0xdc, 0x72,
372 0x02, 0xe8, 0xda, 0x31,
373 0x02, 0xa0, 0x50, 0x31,
374 0x00, 0xe2, 0xfe, 0x42,
375 0x80, 0x33, 0x67, 0x02,
376 0x01, 0x44, 0xd4, 0x31,
377 0x00, 0xe2, 0xb8, 0x5b,
378 0x01, 0x33, 0x67, 0x02,
379 0xe0, 0x36, 0x19, 0x63,
380 0x02, 0x33, 0x67, 0x02,
381 0x20, 0x46, 0x12, 0x63,
382 0xff, 0xea, 0x52, 0x09,
383 0xa8, 0xea, 0xca, 0x5b,
384 0x04, 0x92, 0xf9, 0x7a,
385 0x01, 0x34, 0xc1, 0x31,
386 0x00, 0x93, 0xf9, 0x62,
387 0x01, 0x35, 0xc1, 0x31,
388 0x00, 0x94, 0x03, 0x73,
389 0x01, 0xa9, 0x52, 0x11,
390 0xff, 0xa9, 0xee, 0x6a,
391 0x00, 0xe2, 0x12, 0x43,
392 0x10, 0x33, 0x67, 0x02,
393 0x04, 0x92, 0x13, 0x7b,
394 0xfb, 0x92, 0x25, 0x0b,
395 0xff, 0xea, 0x66, 0x0a,
396 0x01, 0xa4, 0x0d, 0x6b,
397 0x02, 0xa8, 0x90, 0x32,
398 0x00, 0xe2, 0x6a, 0x59,
399 0x10, 0x92, 0xbd, 0x7a,
400 0xff, 0xea, 0xdc, 0x5b,
401 0x00, 0xe2, 0xbc, 0x42,
402 0x04, 0xea, 0x50, 0x59,
403 0x04, 0xea, 0x04, 0x00,
404 0x00, 0xe2, 0xbc, 0x42,
405 0x04, 0xea, 0x50, 0x59,
406 0x04, 0xea, 0x04, 0x00,
407 0x00, 0xe2, 0xf8, 0x41,
408 0x08, 0x92, 0xb5, 0x7a,
409 0xc0, 0x33, 0x29, 0x7b,
410 0x80, 0x33, 0xb5, 0x6a,
411 0xff, 0x88, 0x29, 0x6b,
412 0x40, 0x33, 0xb5, 0x6a,
413 0x10, 0x92, 0x2f, 0x7b,
414 0x0a, 0xea, 0x50, 0x59,
415 0x0a, 0xea, 0x04, 0x00,
416 0x00, 0xe2, 0x4e, 0x5b,
417 0x00, 0xe2, 0x82, 0x43,
418 0x50, 0x4b, 0x36, 0x6b,
419 0xbf, 0x3a, 0x74, 0x08,
420 0x01, 0xe0, 0xf4, 0x31,
421 0xff, 0xea, 0xc0, 0x09,
422 0x01, 0x2e, 0x5d, 0x1a,
423 0x00, 0x2f, 0x5f, 0x22,
424 0x04, 0x47, 0x8f, 0x02,
425 0x01, 0xfa, 0xc0, 0x35,
426 0x02, 0xa8, 0x84, 0x32,
427 0x02, 0xea, 0xb4, 0x00,
428 0x33, 0xea, 0x44, 0x59,
429 0x33, 0xea, 0x00, 0x00,
430 0x02, 0x42, 0x51, 0x31,
431 0xff, 0x90, 0x65, 0x68,
432 0xff, 0x88, 0x5b, 0x6b,
433 0x01, 0xa4, 0x57, 0x6b,
434 0x02, 0xa4, 0x5f, 0x6b,
435 0x01, 0x84, 0x5f, 0x7b,
436 0x02, 0x28, 0x19, 0x33,
437 0x02, 0xa8, 0x50, 0x36,
438 0xff, 0x88, 0x5f, 0x73,
439 0x00, 0xe2, 0x32, 0x5b,
440 0x02, 0xa8, 0x20, 0x33,
441 0x02, 0x2c, 0x19, 0x33,
442 0x02, 0xa8, 0x58, 0x32,
443 0x04, 0xa4, 0x49, 0x07,
444 0xc0, 0x33, 0xb5, 0x6a,
445 0x04, 0x92, 0x25, 0x03,
446 0x20, 0x92, 0x83, 0x6b,
447 0x02, 0xa8, 0x40, 0x31,
448 0xc0, 0x34, 0xc1, 0x09,
449 0x00, 0x35, 0x51, 0x01,
450 0xff, 0xea, 0x52, 0x09,
451 0x30, 0x34, 0xc5, 0x09,
452 0x3d, 0xe2, 0xc4, 0x29,
453 0xb8, 0xe2, 0xc4, 0x19,
454 0x01, 0xea, 0xc6, 0x01,
455 0x02, 0xe2, 0xc8, 0x31,
456 0x02, 0xa0, 0xda, 0x31,
457 0x02, 0xa0, 0x50, 0x31,
458 0xf7, 0x57, 0xae, 0x08,
459 0x08, 0xea, 0x98, 0x00,
460 0x01, 0x44, 0xd4, 0x31,
461 0xee, 0x00, 0x8c, 0x6b,
462 0x02, 0xea, 0xb4, 0x00,
463 0x00, 0xe2, 0xb4, 0x5b,
464 0x09, 0x4c, 0x8e, 0x7b,
465 0x08, 0x4c, 0x06, 0x68,
466 0x0b, 0xea, 0x50, 0x59,
467 0x0b, 0xea, 0x04, 0x00,
468 0x01, 0x44, 0xd4, 0x31,
469 0x20, 0x33, 0xf9, 0x79,
470 0x00, 0xe2, 0x9e, 0x5b,
471 0x00, 0xe2, 0xf8, 0x41,
472 0x01, 0x84, 0xa3, 0x7b,
473 0x01, 0xa4, 0x49, 0x07,
474 0x08, 0x60, 0x30, 0x33,
475 0x08, 0x80, 0x41, 0x37,
476 0xdf, 0x33, 0x67, 0x0a,
477 0xee, 0x00, 0xb0, 0x6b,
478 0x05, 0xea, 0xb4, 0x00,
479 0x33, 0xea, 0x44, 0x59,
480 0x33, 0xea, 0x00, 0x00,
481 0x00, 0xe2, 0x6a, 0x59,
482 0x00, 0xe2, 0xbc, 0x42,
483 0x01, 0xea, 0x6c, 0x02,
484 0xc0, 0xea, 0x66, 0x06,
485 0xff, 0x42, 0xc4, 0x6b,
486 0x01, 0x41, 0xb8, 0x6b,
487 0x02, 0x41, 0xb8, 0x7b,
488 0xff, 0x42, 0xc4, 0x6b,
489 0x01, 0x41, 0xb8, 0x6b,
490 0x02, 0x41, 0xb8, 0x7b,
491 0xff, 0x42, 0xc4, 0x7b,
492 0x04, 0x4c, 0xb8, 0x6b,
493 0xe0, 0x41, 0x6c, 0x0e,
494 0x01, 0x44, 0xd4, 0x31,
495 0xff, 0x42, 0xcc, 0x7b,
496 0x04, 0x4c, 0xcc, 0x6b,
497 0xe0, 0x41, 0x6c, 0x0a,
498 0xe0, 0x36, 0xf9, 0x61,
499 0xff, 0xea, 0xca, 0x09,
500 0x01, 0xe2, 0xc8, 0x31,
501 0x01, 0x46, 0xda, 0x35,
502 0x01, 0x44, 0xd4, 0x35,
503 0x10, 0xea, 0x80, 0x00,
504 0x01, 0xe2, 0x62, 0x36,
505 0x04, 0xa6, 0xe4, 0x7b,
506 0xff, 0xea, 0x5a, 0x09,
507 0xff, 0xea, 0x4c, 0x0d,
508 0x01, 0xa6, 0x02, 0x6c,
509 0x10, 0xad, 0x64, 0x78,
510 0x80, 0xad, 0xfa, 0x6b,
511 0x08, 0xad, 0x64, 0x68,
512 0x04, 0x84, 0xf9, 0x30,
513 0x00, 0xea, 0x08, 0x81,
514 0xff, 0xea, 0xd4, 0x09,
515 0x02, 0x84, 0xf9, 0x88,
516 0x0d, 0xea, 0x5a, 0x01,
517 0x04, 0xa6, 0x4c, 0x05,
518 0x04, 0xa6, 0x64, 0x78,
519 0xff, 0xea, 0x5a, 0x09,
520 0x03, 0x84, 0x59, 0x89,
521 0x03, 0xea, 0x4c, 0x01,
522 0x80, 0x1a, 0x64, 0x78,
523 0x08, 0x19, 0x64, 0x78,
524 0x08, 0xb0, 0xe0, 0x30,
525 0x04, 0xb0, 0xe0, 0x30,
526 0x03, 0xb0, 0xf0, 0x30,
527 0x01, 0xb0, 0x06, 0x33,
528 0x7f, 0x83, 0xe9, 0x08,
529 0x04, 0xac, 0x58, 0x19,
530 0xff, 0xea, 0xc0, 0x09,
531 0x04, 0x84, 0x09, 0x9b,
532 0x00, 0x85, 0x0b, 0x23,
533 0x00, 0x86, 0x0d, 0x23,
534 0x00, 0x87, 0x0f, 0x23,
535 0x01, 0x84, 0xc5, 0x31,
536 0x80, 0x83, 0x25, 0x7c,
537 0x02, 0xe2, 0xc4, 0x01,
538 0xff, 0xea, 0x4c, 0x09,
539 0x01, 0xe2, 0x36, 0x30,
540 0xc8, 0x19, 0x32, 0x00,
541 0x88, 0x19, 0x32, 0x00,
542 0x01, 0xac, 0xd4, 0x99,
543 0x00, 0xe2, 0x64, 0x50,
544 0xfe, 0xa6, 0x4c, 0x0d,
545 0x0b, 0x98, 0xe1, 0x30,
546 0xfd, 0xa4, 0x49, 0x09,
547 0x80, 0xa3, 0x39, 0x7c,
548 0x02, 0xa4, 0x48, 0x01,
549 0x01, 0xa4, 0x36, 0x30,
550 0xa8, 0xea, 0x32, 0x00,
551 0xfd, 0xa4, 0x49, 0x0b,
552 0x05, 0xa3, 0x07, 0x33,
553 0x80, 0x83, 0x45, 0x6c,
554 0x02, 0xea, 0x4c, 0x05,
555 0xff, 0xea, 0x4c, 0x0d,
556 0x00, 0xe2, 0x3e, 0x59,
557 0x02, 0xa6, 0xe6, 0x6b,
558 0x80, 0xf9, 0xf2, 0x05,
559 0xc0, 0x33, 0x53, 0x7c,
560 0x03, 0xea, 0x50, 0x59,
561 0x03, 0xea, 0x04, 0x00,
562 0x20, 0x33, 0x77, 0x7c,
563 0x01, 0x84, 0x5d, 0x6c,
564 0x06, 0xea, 0x50, 0x59,
565 0x06, 0xea, 0x04, 0x00,
566 0x00, 0xe2, 0x7a, 0x44,
567 0x01, 0x00, 0x60, 0x32,
568 0xee, 0x00, 0x66, 0x6c,
569 0x05, 0xea, 0xb4, 0x00,
570 0x33, 0xea, 0x44, 0x59,
571 0x33, 0xea, 0x00, 0x00,
572 0x80, 0x3d, 0x7a, 0x00,
573 0xfc, 0x42, 0x68, 0x7c,
574 0x7f, 0x3d, 0x7a, 0x08,
575 0x00, 0x30, 0x45, 0x59,
576 0x01, 0x30, 0x01, 0x30,
577 0x09, 0xea, 0x50, 0x59,
578 0x09, 0xea, 0x04, 0x00,
579 0x00, 0xe2, 0xf8, 0x41,
580 0x01, 0xa4, 0x5d, 0x6c,
581 0x00, 0xe2, 0x30, 0x5c,
582 0x20, 0x33, 0x67, 0x02,
583 0x01, 0x00, 0x60, 0x32,
584 0x02, 0xa6, 0x82, 0x7c,
585 0x00, 0xe2, 0x46, 0x5c,
586 0x00, 0xe2, 0x56, 0x58,
587 0x00, 0xe2, 0x66, 0x58,
588 0x00, 0xe2, 0x3a, 0x58,
589 0x00, 0x30, 0x45, 0x59,
590 0x01, 0x30, 0x01, 0x30,
591 0x20, 0x19, 0x82, 0x6c,
592 0x00, 0xe2, 0xb2, 0x5c,
593 0x04, 0x19, 0x9c, 0x6c,
594 0x02, 0x19, 0x32, 0x00,
595 0x01, 0x84, 0x9d, 0x7c,
596 0x01, 0x1b, 0x96, 0x7c,
597 0x01, 0x1a, 0x9c, 0x6c,
598 0x00, 0xe2, 0x4c, 0x44,
599 0x80, 0x4b, 0xa2, 0x6c,
600 0x01, 0x4c, 0x9e, 0x7c,
601 0x03, 0x42, 0x4c, 0x6c,
602 0x00, 0xe2, 0xe0, 0x5b,
603 0x80, 0xf9, 0xf2, 0x01,
604 0x04, 0x33, 0xf9, 0x79,
605 0x00, 0xe2, 0xf8, 0x41,
606 0x08, 0x5d, 0xba, 0x6c,
607 0x00, 0xe2, 0x56, 0x58,
608 0x00, 0x30, 0x45, 0x59,
609 0x01, 0x30, 0x01, 0x30,
610 0x02, 0x1b, 0xaa, 0x7c,
611 0x08, 0x5d, 0xb8, 0x7c,
612 0x03, 0x68, 0x00, 0x37,
613 0x01, 0x84, 0x09, 0x07,
614 0x80, 0x1b, 0xc4, 0x7c,
615 0x80, 0x84, 0xc5, 0x6c,
616 0xff, 0x85, 0x0b, 0x1b,
617 0xff, 0x86, 0x0d, 0x23,
618 0xff, 0x87, 0x0f, 0x23,
619 0xf8, 0x1b, 0x08, 0x0b,
620 0xff, 0xea, 0x06, 0x0b,
621 0x03, 0x68, 0x00, 0x37,
622 0x00, 0xe2, 0xc4, 0x58,
623 0x10, 0xea, 0x18, 0x00,
624 0xf9, 0xd9, 0xb2, 0x0d,
625 0x01, 0xd9, 0xb2, 0x05,
626 0x01, 0x52, 0x48, 0x31,
627 0x20, 0xa4, 0xee, 0x7c,
628 0x20, 0x5b, 0xee, 0x7c,
629 0x80, 0xf9, 0xfc, 0x7c,
630 0x02, 0xea, 0xb4, 0x00,
631 0x11, 0x00, 0x00, 0x10,
632 0x04, 0x19, 0x08, 0x7d,
633 0xdf, 0x19, 0x32, 0x08,
634 0x60, 0x5b, 0xe6, 0x6c,
635 0x01, 0x4c, 0xe2, 0x7c,
636 0x20, 0x19, 0x32, 0x00,
637 0x01, 0xd9, 0xb2, 0x05,
638 0x02, 0xea, 0xb4, 0x00,
639 0x01, 0xd9, 0xb2, 0x05,
640 0x10, 0x5b, 0x00, 0x6d,
641 0x08, 0x5b, 0x0a, 0x6d,
642 0x20, 0x5b, 0xfa, 0x6c,
643 0x02, 0x5b, 0x2a, 0x6d,
644 0x0e, 0xea, 0x50, 0x59,
645 0x0e, 0xea, 0x04, 0x00,
646 0x80, 0xf9, 0xea, 0x6c,
647 0xdf, 0x5c, 0xb8, 0x08,
648 0x01, 0xd9, 0xb2, 0x05,
649 0x01, 0xa4, 0xe5, 0x6d,
650 0x00, 0xe2, 0x30, 0x5c,
651 0x00, 0xe2, 0x34, 0x5d,
652 0x01, 0x90, 0x21, 0x1b,
653 0x01, 0xd9, 0xb2, 0x05,
654 0x00, 0xe2, 0x32, 0x5b,
655 0xf3, 0x96, 0xd5, 0x19,
656 0x00, 0xe2, 0x18, 0x55,
657 0x80, 0x96, 0x19, 0x6d,
658 0x0f, 0xea, 0x50, 0x59,
659 0x0f, 0xea, 0x04, 0x00,
660 0x00, 0xe2, 0x20, 0x45,
661 0x04, 0x8c, 0xe1, 0x30,
662 0x01, 0xea, 0xf2, 0x00,
663 0x02, 0xea, 0x36, 0x00,
664 0xa8, 0xea, 0x32, 0x00,
665 0xff, 0x97, 0x27, 0x7d,
666 0x14, 0xea, 0x50, 0x59,
667 0x14, 0xea, 0x04, 0x00,
668 0x00, 0xe2, 0x96, 0x5d,
669 0x01, 0xd9, 0xb2, 0x05,
670 0x09, 0x80, 0xe1, 0x30,
671 0x02, 0xea, 0x36, 0x00,
672 0xa8, 0xea, 0x32, 0x00,
673 0x00, 0xe2, 0x8e, 0x5d,
674 0x01, 0xd9, 0xb2, 0x05,
675 0x02, 0xa6, 0x44, 0x7d,
676 0x00, 0xe2, 0x3e, 0x59,
677 0x20, 0x5b, 0x52, 0x6d,
678 0xfc, 0x42, 0x3e, 0x7d,
679 0x10, 0x40, 0x40, 0x6d,
680 0x20, 0x4d, 0x42, 0x7d,
681 0x08, 0x5d, 0x52, 0x6d,
682 0x02, 0xa6, 0xe6, 0x6b,
683 0x00, 0xe2, 0x3e, 0x59,
684 0x20, 0x5b, 0x52, 0x6d,
685 0x01, 0x1b, 0x72, 0x6d,
686 0xfc, 0x42, 0x4e, 0x7d,
687 0x10, 0x40, 0x50, 0x6d,
688 0x20, 0x4d, 0x64, 0x78,
689 0x08, 0x5d, 0x64, 0x78,
690 0x02, 0x19, 0x32, 0x00,
691 0x01, 0x5b, 0x40, 0x31,
692 0x00, 0xe2, 0xb2, 0x5c,
693 0x00, 0xe2, 0x9e, 0x5b,
694 0x20, 0xea, 0xb6, 0x00,
695 0x00, 0xe2, 0xe0, 0x5b,
696 0x20, 0x5c, 0xb8, 0x00,
697 0x04, 0x19, 0x68, 0x6d,
698 0x01, 0x1a, 0x68, 0x6d,
699 0x00, 0xe2, 0x3e, 0x59,
700 0x01, 0x1a, 0x64, 0x78,
701 0x80, 0xf9, 0xf2, 0x01,
702 0x20, 0xa0, 0xcc, 0x7d,
703 0xff, 0x90, 0x21, 0x1b,
704 0x08, 0x92, 0x43, 0x6b,
705 0x02, 0xea, 0xb4, 0x04,
706 0x01, 0xa4, 0x49, 0x03,
707 0x40, 0x5b, 0x82, 0x6d,
708 0x00, 0xe2, 0x3e, 0x59,
709 0x40, 0x5b, 0x82, 0x6d,
710 0x04, 0x5d, 0xe6, 0x7d,
711 0x01, 0x1a, 0xe6, 0x7d,
712 0x20, 0x4d, 0x64, 0x78,
713 0x40, 0x5b, 0xcc, 0x7d,
714 0x04, 0x5d, 0xe6, 0x7d,
715 0x01, 0x1a, 0xe6, 0x7d,
716 0x80, 0xf9, 0xf2, 0x01,
717 0xff, 0x90, 0x21, 0x1b,
718 0x08, 0x92, 0x43, 0x6b,
719 0x02, 0xea, 0xb4, 0x04,
720 0x00, 0xe2, 0x3e, 0x59,
721 0x01, 0x1b, 0x64, 0x78,
722 0x80, 0xf9, 0xf2, 0x01,
723 0x02, 0xea, 0xb4, 0x04,
724 0x00, 0xe2, 0x3e, 0x59,
725 0x01, 0x1b, 0xaa, 0x6d,
726 0x40, 0x5b, 0xb8, 0x7d,
727 0x01, 0x1b, 0xaa, 0x6d,
728 0x02, 0x19, 0x32, 0x00,
729 0x01, 0x1a, 0x64, 0x78,
730 0x80, 0xf9, 0xf2, 0x01,
731 0xff, 0xea, 0x10, 0x03,
732 0x08, 0x92, 0x25, 0x03,
733 0x00, 0xe2, 0x42, 0x43,
734 0x01, 0x1a, 0xb4, 0x7d,
735 0x40, 0x5b, 0xb0, 0x7d,
736 0x01, 0x1a, 0x9e, 0x6d,
737 0xfc, 0x42, 0x64, 0x78,
738 0x01, 0x1a, 0xb8, 0x6d,
739 0x10, 0xea, 0x50, 0x59,
740 0x10, 0xea, 0x04, 0x00,
741 0xfc, 0x42, 0x64, 0x78,
742 0x10, 0x40, 0xbe, 0x6d,
743 0x20, 0x4d, 0x64, 0x78,
744 0x40, 0x5b, 0x9e, 0x6d,
745 0x01, 0x1a, 0x64, 0x78,
746 0x01, 0x90, 0x21, 0x1b,
747 0x30, 0x3f, 0xc0, 0x09,
748 0x30, 0xe0, 0x64, 0x60,
749 0x40, 0x4b, 0x64, 0x68,
750 0xff, 0xea, 0x52, 0x01,
751 0xee, 0x00, 0xd2, 0x6d,
752 0x80, 0xf9, 0xf2, 0x01,
753 0xff, 0x90, 0x21, 0x1b,
754 0x02, 0xea, 0xb4, 0x00,
755 0x20, 0xea, 0x9a, 0x00,
756 0xf3, 0x42, 0xde, 0x6d,
757 0x12, 0xea, 0x50, 0x59,
758 0x12, 0xea, 0x04, 0x00,
759 0x00, 0xe2, 0xf8, 0x41,
760 0x0d, 0xea, 0x50, 0x59,
761 0x0d, 0xea, 0x04, 0x00,
762 0x00, 0xe2, 0xf8, 0x41,
763 0x01, 0x90, 0x21, 0x1b,
764 0x11, 0xea, 0x50, 0x59,
765 0x11, 0xea, 0x04, 0x00,
766 0x00, 0xe2, 0x32, 0x5b,
767 0x08, 0x5a, 0xb4, 0x00,
768 0x00, 0xe2, 0x0c, 0x5e,
769 0xa8, 0xea, 0x32, 0x00,
770 0x00, 0xe2, 0x3e, 0x59,
771 0x80, 0x1a, 0xfa, 0x7d,
772 0x00, 0xe2, 0x0c, 0x5e,
773 0x80, 0x19, 0x32, 0x00,
774 0x40, 0x5b, 0x00, 0x6e,
775 0x08, 0x5a, 0x00, 0x7e,
776 0x20, 0x4d, 0x64, 0x78,
777 0x02, 0x84, 0x09, 0x03,
778 0x40, 0x5b, 0xcc, 0x7d,
779 0xff, 0x90, 0x21, 0x1b,
780 0x80, 0xf9, 0xf2, 0x01,
781 0x08, 0x92, 0x43, 0x6b,
782 0x02, 0xea, 0xb4, 0x04,
783 0x01, 0x38, 0xe1, 0x30,
784 0x05, 0x39, 0xe3, 0x98,
785 0x01, 0xe0, 0xf4, 0x31,
786 0xff, 0xea, 0xc0, 0x09,
787 0x00, 0x3a, 0xe5, 0x20,
788 0x00, 0x3b, 0xe7, 0x20,
789 0x01, 0xfa, 0xc0, 0x31,
790 0x04, 0xea, 0xe8, 0x30,
791 0xff, 0xea, 0xf0, 0x08,
792 0x02, 0xea, 0xf2, 0x00,
793 0xff, 0xea, 0xf4, 0x0c
794};
795
796typedef int ahd_patch_func_t (struct ahd_softc *ahd);
797static ahd_patch_func_t ahd_patch22_func;
798
799static int
800ahd_patch22_func(struct ahd_softc *ahd)
801{
802 return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0);
803}
804
805static ahd_patch_func_t ahd_patch21_func;
806
807static int
808ahd_patch21_func(struct ahd_softc *ahd)
809{
810 return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0);
811}
812
813static ahd_patch_func_t ahd_patch20_func;
814
815static int
816ahd_patch20_func(struct ahd_softc *ahd)
817{
818 return ((ahd->features & AHD_RTI) == 0);
819}
820
821static ahd_patch_func_t ahd_patch19_func;
822
823static int
824ahd_patch19_func(struct ahd_softc *ahd)
825{
826 return ((ahd->flags & AHD_INITIATORROLE) != 0);
827}
828
829static ahd_patch_func_t ahd_patch18_func;
830
831static int
832ahd_patch18_func(struct ahd_softc *ahd)
833{
834 return ((ahd->flags & AHD_TARGETROLE) != 0);
835}
836
837static ahd_patch_func_t ahd_patch17_func;
838
839static int
840ahd_patch17_func(struct ahd_softc *ahd)
841{
842 return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0);
843}
844
845static ahd_patch_func_t ahd_patch16_func;
846
847static int
848ahd_patch16_func(struct ahd_softc *ahd)
849{
850 return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0);
851}
852
853static ahd_patch_func_t ahd_patch15_func;
854
855static int
856ahd_patch15_func(struct ahd_softc *ahd)
857{
858 return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0);
859}
860
861static ahd_patch_func_t ahd_patch14_func;
862
863static int
864ahd_patch14_func(struct ahd_softc *ahd)
865{
866 return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0);
867}
868
869static ahd_patch_func_t ahd_patch13_func;
870
871static int
872ahd_patch13_func(struct ahd_softc *ahd)
873{
874 return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0);
875}
876
877static ahd_patch_func_t ahd_patch12_func;
878
879static int
880ahd_patch12_func(struct ahd_softc *ahd)
881{
882 return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0);
883}
884
885static ahd_patch_func_t ahd_patch11_func;
886
887static int
888ahd_patch11_func(struct ahd_softc *ahd)
889{
890 return ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0);
891}
892
893static ahd_patch_func_t ahd_patch10_func;
894
895static int
896ahd_patch10_func(struct ahd_softc *ahd)
897{
898 return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0);
899}
900
901static ahd_patch_func_t ahd_patch9_func;
902
903static int
904ahd_patch9_func(struct ahd_softc *ahd)
905{
906 return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0);
907}
908
909static ahd_patch_func_t ahd_patch8_func;
910
911static int
912ahd_patch8_func(struct ahd_softc *ahd)
913{
914 return ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0);
915}
916
917static ahd_patch_func_t ahd_patch7_func;
918
919static int
920ahd_patch7_func(struct ahd_softc *ahd)
921{
922 return ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0);
923}
924
925static ahd_patch_func_t ahd_patch6_func;
926
927static int
928ahd_patch6_func(struct ahd_softc *ahd)
929{
930 return ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0);
931}
932
933static ahd_patch_func_t ahd_patch5_func;
934
935static int
936ahd_patch5_func(struct ahd_softc *ahd)
937{
938 return ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0);
939}
940
941static ahd_patch_func_t ahd_patch4_func;
942
943static int
944ahd_patch4_func(struct ahd_softc *ahd)
945{
946 return ((ahd->bugs & AHD_PKT_LUN_BUG) != 0);
947}
948
949static ahd_patch_func_t ahd_patch3_func;
950
951static int
952ahd_patch3_func(struct ahd_softc *ahd)
953{
954 return ((ahd->bugs & AHD_FAINT_LED_BUG) != 0);
955}
956
957static ahd_patch_func_t ahd_patch2_func;
958
959static int
960ahd_patch2_func(struct ahd_softc *ahd)
961{
962 return ((ahd->bugs & AHD_SET_MODE_BUG) != 0);
963}
964
965static ahd_patch_func_t ahd_patch1_func;
966
967static int
968ahd_patch1_func(struct ahd_softc *ahd)
969{
970 return ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0);
971}
972
973static ahd_patch_func_t ahd_patch0_func;
974
975static int
976ahd_patch0_func(struct ahd_softc *ahd)
977{
978 return (0);
979}
980
981static struct patch {
982 ahd_patch_func_t *patch_func;
983 uint32_t begin :10,
984 skip_instr :10,
985 skip_patch :12;
986} patches[] = {
987 { ahd_patch1_func, 0, 3, 3 },
988 { ahd_patch1_func, 1, 1, 2 },
989 { ahd_patch0_func, 2, 1, 1 },
990 { ahd_patch1_func, 3, 3, 3 },
991 { ahd_patch1_func, 4, 1, 2 },
992 { ahd_patch0_func, 5, 1, 1 },
993 { ahd_patch2_func, 6, 1, 2 },
994 { ahd_patch0_func, 7, 1, 1 },
995 { ahd_patch3_func, 20, 5, 1 },
996 { ahd_patch2_func, 29, 1, 2 },
997 { ahd_patch0_func, 30, 1, 1 },
998 { ahd_patch1_func, 37, 1, 2 },
999 { ahd_patch0_func, 38, 1, 1 },
1000 { ahd_patch2_func, 43, 1, 2 },
1001 { ahd_patch0_func, 44, 1, 1 },
1002 { ahd_patch2_func, 47, 1, 2 },
1003 { ahd_patch0_func, 48, 1, 1 },
1004 { ahd_patch2_func, 51, 1, 2 },
1005 { ahd_patch0_func, 52, 1, 1 },
1006 { ahd_patch2_func, 65, 1, 2 },
1007 { ahd_patch0_func, 66, 1, 1 },
1008 { ahd_patch2_func, 69, 1, 2 },
1009 { ahd_patch0_func, 70, 1, 1 },
1010 { ahd_patch1_func, 73, 1, 2 },
1011 { ahd_patch0_func, 74, 1, 1 },
1012 { ahd_patch4_func, 107, 1, 1 },
1013 { ahd_patch2_func, 162, 6, 1 },
1014 { ahd_patch1_func, 168, 2, 1 },
1015 { ahd_patch5_func, 170, 1, 1 },
1016 { ahd_patch2_func, 179, 1, 2 },
1017 { ahd_patch0_func, 180, 1, 1 },
1018 { ahd_patch6_func, 181, 2, 2 },
1019 { ahd_patch0_func, 183, 6, 3 },
1020 { ahd_patch2_func, 186, 1, 2 },
1021 { ahd_patch0_func, 187, 1, 1 },
1022 { ahd_patch2_func, 190, 1, 2 },
1023 { ahd_patch0_func, 191, 1, 1 },
1024 { ahd_patch7_func, 193, 2, 1 },
1025 { ahd_patch5_func, 201, 16, 2 },
1026 { ahd_patch0_func, 217, 1, 1 },
1027 { ahd_patch8_func, 237, 2, 1 },
1028 { ahd_patch1_func, 241, 1, 2 },
1029 { ahd_patch0_func, 242, 1, 1 },
1030 { ahd_patch7_func, 245, 2, 1 },
1031 { ahd_patch1_func, 259, 1, 2 },
1032 { ahd_patch0_func, 260, 1, 1 },
1033 { ahd_patch1_func, 263, 1, 2 },
1034 { ahd_patch0_func, 264, 1, 1 },
1035 { ahd_patch2_func, 267, 1, 2 },
1036 { ahd_patch0_func, 268, 1, 1 },
1037 { ahd_patch1_func, 323, 1, 2 },
1038 { ahd_patch0_func, 324, 1, 1 },
1039 { ahd_patch2_func, 332, 1, 2 },
1040 { ahd_patch0_func, 333, 1, 1 },
1041 { ahd_patch2_func, 336, 1, 2 },
1042 { ahd_patch0_func, 337, 1, 1 },
1043 { ahd_patch1_func, 343, 1, 2 },
1044 { ahd_patch0_func, 344, 1, 1 },
1045 { ahd_patch1_func, 346, 1, 2 },
1046 { ahd_patch0_func, 347, 1, 1 },
1047 { ahd_patch9_func, 366, 1, 1 },
1048 { ahd_patch9_func, 369, 1, 1 },
1049 { ahd_patch9_func, 371, 1, 1 },
1050 { ahd_patch9_func, 383, 1, 1 },
1051 { ahd_patch1_func, 393, 1, 2 },
1052 { ahd_patch0_func, 394, 1, 1 },
1053 { ahd_patch1_func, 396, 1, 2 },
1054 { ahd_patch0_func, 397, 1, 1 },
1055 { ahd_patch1_func, 405, 1, 2 },
1056 { ahd_patch0_func, 406, 1, 1 },
1057 { ahd_patch2_func, 419, 1, 2 },
1058 { ahd_patch0_func, 420, 1, 1 },
1059 { ahd_patch10_func, 450, 1, 1 },
1060 { ahd_patch1_func, 457, 1, 2 },
1061 { ahd_patch0_func, 458, 1, 1 },
1062 { ahd_patch2_func, 470, 1, 2 },
1063 { ahd_patch0_func, 471, 1, 1 },
1064 { ahd_patch11_func, 476, 6, 2 },
1065 { ahd_patch0_func, 482, 1, 1 },
1066 { ahd_patch12_func, 505, 1, 1 },
1067 { ahd_patch13_func, 514, 1, 1 },
1068 { ahd_patch14_func, 515, 1, 2 },
1069 { ahd_patch0_func, 516, 1, 1 },
1070 { ahd_patch15_func, 519, 1, 1 },
1071 { ahd_patch14_func, 520, 1, 1 },
1072 { ahd_patch16_func, 531, 1, 2 },
1073 { ahd_patch0_func, 532, 1, 1 },
1074 { ahd_patch1_func, 551, 1, 2 },
1075 { ahd_patch0_func, 552, 1, 1 },
1076 { ahd_patch1_func, 555, 1, 2 },
1077 { ahd_patch0_func, 556, 1, 1 },
1078 { ahd_patch2_func, 561, 1, 2 },
1079 { ahd_patch0_func, 562, 1, 1 },
1080 { ahd_patch2_func, 566, 1, 2 },
1081 { ahd_patch0_func, 567, 1, 1 },
1082 { ahd_patch1_func, 568, 1, 2 },
1083 { ahd_patch0_func, 569, 1, 1 },
1084 { ahd_patch2_func, 580, 1, 2 },
1085 { ahd_patch0_func, 581, 1, 1 },
1086 { ahd_patch17_func, 585, 1, 1 },
1087 { ahd_patch18_func, 590, 1, 1 },
1088 { ahd_patch19_func, 591, 2, 1 },
1089 { ahd_patch18_func, 595, 1, 2 },
1090 { ahd_patch0_func, 596, 1, 1 },
1091 { ahd_patch2_func, 599, 1, 2 },
1092 { ahd_patch0_func, 600, 1, 1 },
1093 { ahd_patch2_func, 615, 1, 2 },
1094 { ahd_patch0_func, 616, 1, 1 },
1095 { ahd_patch20_func, 617, 14, 1 },
1096 { ahd_patch1_func, 635, 1, 2 },
1097 { ahd_patch0_func, 636, 1, 1 },
1098 { ahd_patch20_func, 637, 1, 1 },
1099 { ahd_patch1_func, 649, 1, 2 },
1100 { ahd_patch0_func, 650, 1, 1 },
1101 { ahd_patch1_func, 657, 1, 2 },
1102 { ahd_patch0_func, 658, 1, 1 },
1103 { ahd_patch17_func, 681, 1, 1 },
1104 { ahd_patch17_func, 719, 1, 1 },
1105 { ahd_patch1_func, 730, 1, 2 },
1106 { ahd_patch0_func, 731, 1, 1 },
1107 { ahd_patch1_func, 748, 1, 2 },
1108 { ahd_patch0_func, 749, 1, 1 },
1109 { ahd_patch1_func, 751, 1, 2 },
1110 { ahd_patch0_func, 752, 1, 1 },
1111 { ahd_patch1_func, 755, 1, 2 },
1112 { ahd_patch0_func, 756, 1, 1 },
1113 { ahd_patch21_func, 758, 1, 2 },
1114 { ahd_patch0_func, 759, 2, 1 },
1115 { ahd_patch22_func, 762, 4, 2 },
1116 { ahd_patch0_func, 766, 1, 1 },
1117 { ahd_patch22_func, 774, 11, 1 }
1118};
1119
1120static struct cs {
1121 uint16_t begin;
1122 uint16_t end;
1123} critical_sections[] = {
1124 { 11, 12 },
1125 { 13, 14 },
1126 { 29, 42 },
1127 { 56, 59 },
1128 { 101, 128 },
1129 { 129, 157 },
1130 { 159, 162 },
1131 { 170, 178 },
1132 { 201, 250 },
1133 { 681, 697 },
1134 { 697, 711 },
1135 { 721, 725 }
1136};
1137
1138static const int num_critical_sections = sizeof(critical_sections)
1139 / sizeof(*critical_sections);
diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h
new file mode 100644
index 000000000000..8ff16fd8ed49
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx.h
@@ -0,0 +1,1352 @@
1/*
2 * Core definitions and data structures shareable across OS platforms.
3 *
4 * Copyright (c) 1994-2001 Justin T. Gibbs.
5 * Copyright (c) 2000-2001 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#79 $
41 *
42 * $FreeBSD$
43 */
44
45#ifndef _AIC7XXX_H_
46#define _AIC7XXX_H_
47
48/* Register Definitions */
49#include "aic7xxx_reg.h"
50
51/************************* Forward Declarations *******************************/
52struct ahc_platform_data;
53struct scb_platform_data;
54struct seeprom_descriptor;
55
56/****************************** Useful Macros *********************************/
57#ifndef MAX
58#define MAX(a,b) (((a) > (b)) ? (a) : (b))
59#endif
60
61#ifndef MIN
62#define MIN(a,b) (((a) < (b)) ? (a) : (b))
63#endif
64
65#ifndef TRUE
66#define TRUE 1
67#endif
68#ifndef FALSE
69#define FALSE 0
70#endif
71
72#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array))
73
74#define ALL_CHANNELS '\0'
75#define ALL_TARGETS_MASK 0xFFFF
76#define INITIATOR_WILDCARD (~0)
77
78#define SCSIID_TARGET(ahc, scsiid) \
79 (((scsiid) & ((((ahc)->features & AHC_TWIN) != 0) ? TWIN_TID : TID)) \
80 >> TID_SHIFT)
81#define SCSIID_OUR_ID(scsiid) \
82 ((scsiid) & OID)
83#define SCSIID_CHANNEL(ahc, scsiid) \
84 ((((ahc)->features & AHC_TWIN) != 0) \
85 ? ((((scsiid) & TWIN_CHNLB) != 0) ? 'B' : 'A') \
86 : 'A')
87#define SCB_IS_SCSIBUS_B(ahc, scb) \
88 (SCSIID_CHANNEL(ahc, (scb)->hscb->scsiid) == 'B')
89#define SCB_GET_OUR_ID(scb) \
90 SCSIID_OUR_ID((scb)->hscb->scsiid)
91#define SCB_GET_TARGET(ahc, scb) \
92 SCSIID_TARGET((ahc), (scb)->hscb->scsiid)
93#define SCB_GET_CHANNEL(ahc, scb) \
94 SCSIID_CHANNEL(ahc, (scb)->hscb->scsiid)
95#define SCB_GET_LUN(scb) \
96 ((scb)->hscb->lun & LID)
97#define SCB_GET_TARGET_OFFSET(ahc, scb) \
98 (SCB_GET_TARGET(ahc, scb) + (SCB_IS_SCSIBUS_B(ahc, scb) ? 8 : 0))
99#define SCB_GET_TARGET_MASK(ahc, scb) \
100 (0x01 << (SCB_GET_TARGET_OFFSET(ahc, scb)))
101#ifdef AHC_DEBUG
102#define SCB_IS_SILENT(scb) \
103 ((ahc_debug & AHC_SHOW_MASKED_ERRORS) == 0 \
104 && (((scb)->flags & SCB_SILENT) != 0))
105#else
106#define SCB_IS_SILENT(scb) \
107 (((scb)->flags & SCB_SILENT) != 0)
108#endif
109#define TCL_TARGET_OFFSET(tcl) \
110 ((((tcl) >> 4) & TID) >> 4)
111#define TCL_LUN(tcl) \
112 (tcl & (AHC_NUM_LUNS - 1))
113#define BUILD_TCL(scsiid, lun) \
114 ((lun) | (((scsiid) & TID) << 4))
115
116#ifndef AHC_TARGET_MODE
117#undef AHC_TMODE_ENABLE
118#define AHC_TMODE_ENABLE 0
119#endif
120
121/**************************** Driver Constants ********************************/
122/*
123 * The maximum number of supported targets.
124 */
125#define AHC_NUM_TARGETS 16
126
127/*
128 * The maximum number of supported luns.
129 * The identify message only supports 64 luns in SPI3.
130 * You can have 2^64 luns when information unit transfers are enabled,
131 * but it is doubtful this driver will ever support IUTs.
132 */
133#define AHC_NUM_LUNS 64
134
135/*
136 * The maximum transfer per S/G segment.
137 */
138#define AHC_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter */
139
140/*
141 * The maximum amount of SCB storage in hardware on a controller.
142 * This value represents an upper bound. Controllers vary in the number
143 * they actually support.
144 */
145#define AHC_SCB_MAX 255
146
147/*
148 * The maximum number of concurrent transactions supported per driver instance.
149 * Sequencer Control Blocks (SCBs) store per-transaction information. Although
150 * the space for SCBs on the host adapter varies by model, the driver will
151 * page the SCBs between host and controller memory as needed. We are limited
152 * to 253 because:
153 * 1) The 8bit nature of the RISC engine holds us to an 8bit value.
154 * 2) We reserve one value, 255, to represent the invalid element.
155 * 3) Our input queue scheme requires one SCB to always be reserved
156 * in advance of queuing any SCBs. This takes us down to 254.
157 * 4) To handle our output queue correctly on machines that only
158 * support 32bit stores, we must clear the array 4 bytes at a
159 * time. To avoid colliding with a DMA write from the sequencer,
160 * we must be sure that 4 slots are empty when we write to clear
161 * the queue. This reduces us to 253 SCBs: 1 that just completed
162 * and the known three additional empty slots in the queue that
163 * precede it.
164 */
165#define AHC_MAX_QUEUE 253
166
167/*
168 * The maximum amount of SCB storage we allocate in host memory. This
169 * number should reflect the 1 additional SCB we require to handle our
170 * qinfifo mechanism.
171 */
172#define AHC_SCB_MAX_ALLOC (AHC_MAX_QUEUE+1)
173
174/*
175 * Ring Buffer of incoming target commands.
176 * We allocate 256 to simplify the logic in the sequencer
177 * by using the natural wrap point of an 8bit counter.
178 */
179#define AHC_TMODE_CMDS 256
180
181/* Reset line assertion time in us */
182#define AHC_BUSRESET_DELAY 25
183
184/******************* Chip Characteristics/Operating Settings *****************/
185/*
186 * Chip Type
187 * The chip order is from least sophisticated to most sophisticated.
188 */
189typedef enum {
190 AHC_NONE = 0x0000,
191 AHC_CHIPID_MASK = 0x00FF,
192 AHC_AIC7770 = 0x0001,
193 AHC_AIC7850 = 0x0002,
194 AHC_AIC7855 = 0x0003,
195 AHC_AIC7859 = 0x0004,
196 AHC_AIC7860 = 0x0005,
197 AHC_AIC7870 = 0x0006,
198 AHC_AIC7880 = 0x0007,
199 AHC_AIC7895 = 0x0008,
200 AHC_AIC7895C = 0x0009,
201 AHC_AIC7890 = 0x000a,
202 AHC_AIC7896 = 0x000b,
203 AHC_AIC7892 = 0x000c,
204 AHC_AIC7899 = 0x000d,
205 AHC_VL = 0x0100, /* Bus type VL */
206 AHC_EISA = 0x0200, /* Bus type EISA */
207 AHC_PCI = 0x0400, /* Bus type PCI */
208 AHC_BUS_MASK = 0x0F00
209} ahc_chip;
210
211/*
212 * Features available in each chip type.
213 */
214typedef enum {
215 AHC_FENONE = 0x00000,
216 AHC_ULTRA = 0x00001, /* Supports 20MHz Transfers */
217 AHC_ULTRA2 = 0x00002, /* Supports 40MHz Transfers */
218 AHC_WIDE = 0x00004, /* Wide Channel */
219 AHC_TWIN = 0x00008, /* Twin Channel */
220 AHC_MORE_SRAM = 0x00010, /* 80 bytes instead of 64 */
221 AHC_CMD_CHAN = 0x00020, /* Has a Command DMA Channel */
222 AHC_QUEUE_REGS = 0x00040, /* Has Queue management registers */
223 AHC_SG_PRELOAD = 0x00080, /* Can perform auto-SG preload */
224 AHC_SPIOCAP = 0x00100, /* Has a Serial Port I/O Cap Register */
225 AHC_MULTI_TID = 0x00200, /* Has bitmask of TIDs for select-in */
226 AHC_HS_MAILBOX = 0x00400, /* Has HS_MAILBOX register */
227 AHC_DT = 0x00800, /* Double Transition transfers */
228 AHC_NEW_TERMCTL = 0x01000, /* Newer termination scheme */
229 AHC_MULTI_FUNC = 0x02000, /* Multi-Function Twin Channel Device */
230 AHC_LARGE_SCBS = 0x04000, /* 64byte SCBs */
231 AHC_AUTORATE = 0x08000, /* Automatic update of SCSIRATE/OFFSET*/
232 AHC_AUTOPAUSE = 0x10000, /* Automatic pause on register access */
233 AHC_TARGETMODE = 0x20000, /* Has tested target mode support */
234 AHC_MULTIROLE = 0x40000, /* Space for two roles at a time */
235 AHC_REMOVABLE = 0x80000, /* Hot-Swap supported */
236 AHC_AIC7770_FE = AHC_FENONE,
237 /*
238 * The real 7850 does not support Ultra modes, but there are
239 * several cards that use the generic 7850 PCI ID even though
240 * they are using an Ultra capable chip (7859/7860). We start
241 * out with the AHC_ULTRA feature set and then check the DEVSTATUS
242 * register to determine if the capability is really present.
243 */
244 AHC_AIC7850_FE = AHC_SPIOCAP|AHC_AUTOPAUSE|AHC_TARGETMODE|AHC_ULTRA,
245 AHC_AIC7860_FE = AHC_AIC7850_FE,
246 AHC_AIC7870_FE = AHC_TARGETMODE,
247 AHC_AIC7880_FE = AHC_AIC7870_FE|AHC_ULTRA,
248 /*
249 * Although we have space for both the initiator and
250 * target roles on ULTRA2 chips, we currently disable
251 * the initiator role to allow multi-scsi-id target mode
252 * configurations. We can only respond on the same SCSI
253 * ID as our initiator role if we allow initiator operation.
254 * At some point, we should add a configuration knob to
255 * allow both roles to be loaded.
256 */
257 AHC_AIC7890_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA2
258 |AHC_QUEUE_REGS|AHC_SG_PRELOAD|AHC_MULTI_TID
259 |AHC_HS_MAILBOX|AHC_NEW_TERMCTL|AHC_LARGE_SCBS
260 |AHC_TARGETMODE,
261 AHC_AIC7892_FE = AHC_AIC7890_FE|AHC_DT|AHC_AUTORATE|AHC_AUTOPAUSE,
262 AHC_AIC7895_FE = AHC_AIC7880_FE|AHC_MORE_SRAM|AHC_AUTOPAUSE
263 |AHC_CMD_CHAN|AHC_MULTI_FUNC|AHC_LARGE_SCBS,
264 AHC_AIC7895C_FE = AHC_AIC7895_FE|AHC_MULTI_TID,
265 AHC_AIC7896_FE = AHC_AIC7890_FE|AHC_MULTI_FUNC,
266 AHC_AIC7899_FE = AHC_AIC7892_FE|AHC_MULTI_FUNC
267} ahc_feature;
268
269/*
270 * Bugs in the silicon that we work around in software.
271 */
272typedef enum {
273 AHC_BUGNONE = 0x00,
274 /*
275 * On all chips prior to the U2 product line,
276 * the WIDEODD S/G segment feature does not
277 * work during scsi->HostBus transfers.
278 */
279 AHC_TMODE_WIDEODD_BUG = 0x01,
280 /*
281 * On the aic7890/91 Rev 0 chips, the autoflush
282 * feature does not work. A manual flush of
283 * the DMA FIFO is required.
284 */
285 AHC_AUTOFLUSH_BUG = 0x02,
286 /*
287 * On many chips, cacheline streaming does not work.
288 */
289 AHC_CACHETHEN_BUG = 0x04,
290 /*
291 * On the aic7896/97 chips, cacheline
292 * streaming must be enabled.
293 */
294 AHC_CACHETHEN_DIS_BUG = 0x08,
295 /*
296 * PCI 2.1 Retry failure on non-empty data fifo.
297 */
298 AHC_PCI_2_1_RETRY_BUG = 0x10,
299 /*
300 * Controller does not handle cacheline residuals
301 * properly on S/G segments if PCI MWI instructions
302 * are allowed.
303 */
304 AHC_PCI_MWI_BUG = 0x20,
305 /*
306 * An SCB upload using the SCB channel's
307 * auto array entry copy feature may
308 * corrupt data. This appears to only
309 * occur on 66MHz systems.
310 */
311 AHC_SCBCHAN_UPLOAD_BUG = 0x40
312} ahc_bug;
313
314/*
315 * Configuration specific settings.
316 * The driver determines these settings by probing the
317 * chip/controller's configuration.
318 */
319typedef enum {
320 AHC_FNONE = 0x000,
321 AHC_PRIMARY_CHANNEL = 0x003, /*
322 * The channel that should
323 * be probed first.
324 */
325 AHC_USEDEFAULTS = 0x004, /*
326 * For cards without an seeprom
327 * or a BIOS to initialize the chip's
328 * SRAM, we use the default target
329 * settings.
330 */
331 AHC_SEQUENCER_DEBUG = 0x008,
332 AHC_SHARED_SRAM = 0x010,
333 AHC_LARGE_SEEPROM = 0x020, /* Uses C56_66 not C46 */
334 AHC_RESET_BUS_A = 0x040,
335 AHC_RESET_BUS_B = 0x080,
336 AHC_EXTENDED_TRANS_A = 0x100,
337 AHC_EXTENDED_TRANS_B = 0x200,
338 AHC_TERM_ENB_A = 0x400,
339 AHC_TERM_ENB_B = 0x800,
340 AHC_INITIATORROLE = 0x1000, /*
341 * Allow initiator operations on
342 * this controller.
343 */
344 AHC_TARGETROLE = 0x2000, /*
345 * Allow target operations on this
346 * controller.
347 */
348 AHC_NEWEEPROM_FMT = 0x4000,
349 AHC_RESOURCE_SHORTAGE = 0x8000,
350 AHC_TQINFIFO_BLOCKED = 0x10000, /* Blocked waiting for ATIOs */
351 AHC_INT50_SPEEDFLEX = 0x20000, /*
352 * Internal 50pin connector
353 * sits behind an aic3860
354 */
355 AHC_SCB_BTT = 0x40000, /*
356 * The busy targets table is
357 * stored in SCB space rather
358 * than SRAM.
359 */
360 AHC_BIOS_ENABLED = 0x80000,
361 AHC_ALL_INTERRUPTS = 0x100000,
362 AHC_PAGESCBS = 0x400000, /* Enable SCB paging */
363 AHC_EDGE_INTERRUPT = 0x800000, /* Device uses edge triggered ints */
364 AHC_39BIT_ADDRESSING = 0x1000000, /* Use 39 bit addressing scheme. */
365 AHC_LSCBS_ENABLED = 0x2000000, /* 64Byte SCBs enabled */
366 AHC_SCB_CONFIG_USED = 0x4000000, /* No SEEPROM but SCB2 had info. */
367 AHC_NO_BIOS_INIT = 0x8000000, /* No BIOS left over settings. */
368 AHC_DISABLE_PCI_PERR = 0x10000000,
369 AHC_HAS_TERM_LOGIC = 0x20000000
370} ahc_flag;
371
372/************************* Hardware SCB Definition ***************************/
373
374/*
375 * The driver keeps up to MAX_SCB scb structures per card in memory. The SCB
376 * consists of a "hardware SCB" mirroring the fields available on the card
377 * and additional information the kernel stores for each transaction.
378 *
379 * To minimize space utilization, a portion of the hardware scb stores
380 * different data during different portions of a SCSI transaction.
381 * As initialized by the host driver for the initiator role, this area
382 * contains the SCSI cdb (or a pointer to the cdb) to be executed. After
383 * the cdb has been presented to the target, this area serves to store
384 * residual transfer information and the SCSI status byte.
385 * For the target role, the contents of this area do not change, but
386 * still serve a different purpose than for the initiator role. See
387 * struct target_data for details.
388 */
389
390/*
391 * Status information embedded in the shared poriton of
392 * an SCB after passing the cdb to the target. The kernel
393 * driver will only read this data for transactions that
394 * complete abnormally (non-zero status byte).
395 */
396struct status_pkt {
397 uint32_t residual_datacnt; /* Residual in the current S/G seg */
398 uint32_t residual_sg_ptr; /* The next S/G for this transfer */
399 uint8_t scsi_status; /* Standard SCSI status byte */
400};
401
402/*
403 * Target mode version of the shared data SCB segment.
404 */
405struct target_data {
406 uint32_t residual_datacnt; /* Residual in the current S/G seg */
407 uint32_t residual_sg_ptr; /* The next S/G for this transfer */
408 uint8_t scsi_status; /* SCSI status to give to initiator */
409 uint8_t target_phases; /* Bitmap of phases to execute */
410 uint8_t data_phase; /* Data-In or Data-Out */
411 uint8_t initiator_tag; /* Initiator's transaction tag */
412};
413
414struct hardware_scb {
415/*0*/ union {
416 /*
417 * If the cdb is 12 bytes or less, we embed it directly
418 * in the SCB. For longer cdbs, we embed the address
419 * of the cdb payload as seen by the chip and a DMA
420 * is used to pull it in.
421 */
422 uint8_t cdb[12];
423 uint32_t cdb_ptr;
424 struct status_pkt status;
425 struct target_data tdata;
426 } shared_data;
427/*
428 * A word about residuals.
429 * The scb is presented to the sequencer with the dataptr and datacnt
430 * fields initialized to the contents of the first S/G element to
431 * transfer. The sgptr field is initialized to the bus address for
432 * the S/G element that follows the first in the in core S/G array
433 * or'ed with the SG_FULL_RESID flag. Sgptr may point to an invalid
434 * S/G entry for this transfer (single S/G element transfer with the
435 * first elements address and length preloaded in the dataptr/datacnt
436 * fields). If no transfer is to occur, sgptr is set to SG_LIST_NULL.
437 * The SG_FULL_RESID flag ensures that the residual will be correctly
438 * noted even if no data transfers occur. Once the data phase is entered,
439 * the residual sgptr and datacnt are loaded from the sgptr and the
440 * datacnt fields. After each S/G element's dataptr and length are
441 * loaded into the hardware, the residual sgptr is advanced. After
442 * each S/G element is expired, its datacnt field is checked to see
443 * if the LAST_SEG flag is set. If so, SG_LIST_NULL is set in the
444 * residual sg ptr and the transfer is considered complete. If the
445 * sequencer determines that there is a residual in the tranfer, it
446 * will set the SG_RESID_VALID flag in sgptr and dma the scb back into
447 * host memory. To sumarize:
448 *
449 * Sequencer:
450 * o A residual has occurred if SG_FULL_RESID is set in sgptr,
451 * or residual_sgptr does not have SG_LIST_NULL set.
452 *
453 * o We are transfering the last segment if residual_datacnt has
454 * the SG_LAST_SEG flag set.
455 *
456 * Host:
457 * o A residual has occurred if a completed scb has the
458 * SG_RESID_VALID flag set.
459 *
460 * o residual_sgptr and sgptr refer to the "next" sg entry
461 * and so may point beyond the last valid sg entry for the
462 * transfer.
463 */
464/*12*/ uint32_t dataptr;
465/*16*/ uint32_t datacnt; /*
466 * Byte 3 (numbered from 0) of
467 * the datacnt is really the
468 * 4th byte in that data address.
469 */
470/*20*/ uint32_t sgptr;
471#define SG_PTR_MASK 0xFFFFFFF8
472/*24*/ uint8_t control; /* See SCB_CONTROL in aic7xxx.reg for details */
473/*25*/ uint8_t scsiid; /* what to load in the SCSIID register */
474/*26*/ uint8_t lun;
475/*27*/ uint8_t tag; /*
476 * Index into our kernel SCB array.
477 * Also used as the tag for tagged I/O
478 */
479/*28*/ uint8_t cdb_len;
480/*29*/ uint8_t scsirate; /* Value for SCSIRATE register */
481/*30*/ uint8_t scsioffset; /* Value for SCSIOFFSET register */
482/*31*/ uint8_t next; /*
483 * Used for threading SCBs in the
484 * "Waiting for Selection" and
485 * "Disconnected SCB" lists down
486 * in the sequencer.
487 */
488/*32*/ uint8_t cdb32[32]; /*
489 * CDB storage for cdbs of size
490 * 13->32. We store them here
491 * because hardware scbs are
492 * allocated from DMA safe
493 * memory so we are guaranteed
494 * the controller can access
495 * this data.
496 */
497};
498
499/************************ Kernel SCB Definitions ******************************/
500/*
501 * Some fields of the SCB are OS dependent. Here we collect the
502 * definitions for elements that all OS platforms need to include
503 * in there SCB definition.
504 */
505
506/*
507 * Definition of a scatter/gather element as transfered to the controller.
508 * The aic7xxx chips only support a 24bit length. We use the top byte of
509 * the length to store additional address bits and a flag to indicate
510 * that a given segment terminates the transfer. This gives us an
511 * addressable range of 512GB on machines with 64bit PCI or with chips
512 * that can support dual address cycles on 32bit PCI busses.
513 */
514struct ahc_dma_seg {
515 uint32_t addr;
516 uint32_t len;
517#define AHC_DMA_LAST_SEG 0x80000000
518#define AHC_SG_HIGH_ADDR_MASK 0x7F000000
519#define AHC_SG_LEN_MASK 0x00FFFFFF
520};
521
522struct sg_map_node {
523 bus_dmamap_t sg_dmamap;
524 dma_addr_t sg_physaddr;
525 struct ahc_dma_seg* sg_vaddr;
526 SLIST_ENTRY(sg_map_node) links;
527};
528
529/*
530 * The current state of this SCB.
531 */
532typedef enum {
533 SCB_FREE = 0x0000,
534 SCB_OTHERTCL_TIMEOUT = 0x0002,/*
535 * Another device was active
536 * during the first timeout for
537 * this SCB so we gave ourselves
538 * an additional timeout period
539 * in case it was hogging the
540 * bus.
541 */
542 SCB_DEVICE_RESET = 0x0004,
543 SCB_SENSE = 0x0008,
544 SCB_CDB32_PTR = 0x0010,
545 SCB_RECOVERY_SCB = 0x0020,
546 SCB_AUTO_NEGOTIATE = 0x0040,/* Negotiate to achieve goal. */
547 SCB_NEGOTIATE = 0x0080,/* Negotiation forced for command. */
548 SCB_ABORT = 0x0100,
549 SCB_UNTAGGEDQ = 0x0200,
550 SCB_ACTIVE = 0x0400,
551 SCB_TARGET_IMMEDIATE = 0x0800,
552 SCB_TRANSMISSION_ERROR = 0x1000,/*
553 * We detected a parity or CRC
554 * error that has effected the
555 * payload of the command. This
556 * flag is checked when normal
557 * status is returned to catch
558 * the case of a target not
559 * responding to our attempt
560 * to report the error.
561 */
562 SCB_TARGET_SCB = 0x2000,
563 SCB_SILENT = 0x4000 /*
564 * Be quiet about transmission type
565 * errors. They are expected and we
566 * don't want to upset the user. This
567 * flag is typically used during DV.
568 */
569} scb_flag;
570
571struct scb {
572 struct hardware_scb *hscb;
573 union {
574 SLIST_ENTRY(scb) sle;
575 TAILQ_ENTRY(scb) tqe;
576 } links;
577 LIST_ENTRY(scb) pending_links;
578 ahc_io_ctx_t io_ctx;
579 struct ahc_softc *ahc_softc;
580 scb_flag flags;
581#ifndef __linux__
582 bus_dmamap_t dmamap;
583#endif
584 struct scb_platform_data *platform_data;
585 struct sg_map_node *sg_map;
586 struct ahc_dma_seg *sg_list;
587 dma_addr_t sg_list_phys;
588 u_int sg_count;/* How full ahc_dma_seg is */
589};
590
591struct scb_data {
592 SLIST_HEAD(, scb) free_scbs; /*
593 * Pool of SCBs ready to be assigned
594 * commands to execute.
595 */
596 struct scb *scbindex[256]; /*
597 * Mapping from tag to SCB.
598 * As tag identifiers are an
599 * 8bit value, we provide space
600 * for all possible tag values.
601 * Any lookups to entries at or
602 * above AHC_SCB_MAX_ALLOC will
603 * always fail.
604 */
605 struct hardware_scb *hscbs; /* Array of hardware SCBs */
606 struct scb *scbarray; /* Array of kernel SCBs */
607 struct scsi_sense_data *sense; /* Per SCB sense data */
608
609 /*
610 * "Bus" addresses of our data structures.
611 */
612 bus_dma_tag_t hscb_dmat; /* dmat for our hardware SCB array */
613 bus_dmamap_t hscb_dmamap;
614 dma_addr_t hscb_busaddr;
615 bus_dma_tag_t sense_dmat;
616 bus_dmamap_t sense_dmamap;
617 dma_addr_t sense_busaddr;
618 bus_dma_tag_t sg_dmat; /* dmat for our sg segments */
619 SLIST_HEAD(, sg_map_node) sg_maps;
620 uint8_t numscbs;
621 uint8_t maxhscbs; /* Number of SCBs on the card */
622 uint8_t init_level; /*
623 * How far we've initialized
624 * this structure.
625 */
626};
627
628/************************ Target Mode Definitions *****************************/
629
630/*
631 * Connection desciptor for select-in requests in target mode.
632 */
633struct target_cmd {
634 uint8_t scsiid; /* Our ID and the initiator's ID */
635 uint8_t identify; /* Identify message */
636 uint8_t bytes[22]; /*
637 * Bytes contains any additional message
638 * bytes terminated by 0xFF. The remainder
639 * is the cdb to execute.
640 */
641 uint8_t cmd_valid; /*
642 * When a command is complete, the firmware
643 * will set cmd_valid to all bits set.
644 * After the host has seen the command,
645 * the bits are cleared. This allows us
646 * to just peek at host memory to determine
647 * if more work is complete. cmd_valid is on
648 * an 8 byte boundary to simplify setting
649 * it on aic7880 hardware which only has
650 * limited direct access to the DMA FIFO.
651 */
652 uint8_t pad[7];
653};
654
655/*
656 * Number of events we can buffer up if we run out
657 * of immediate notify ccbs.
658 */
659#define AHC_TMODE_EVENT_BUFFER_SIZE 8
660struct ahc_tmode_event {
661 uint8_t initiator_id;
662 uint8_t event_type; /* MSG type or EVENT_TYPE_BUS_RESET */
663#define EVENT_TYPE_BUS_RESET 0xFF
664 uint8_t event_arg;
665};
666
667/*
668 * Per enabled lun target mode state.
669 * As this state is directly influenced by the host OS'es target mode
670 * environment, we let the OS module define it. Forward declare the
671 * structure here so we can store arrays of them, etc. in OS neutral
672 * data structures.
673 */
674#ifdef AHC_TARGET_MODE
675struct ahc_tmode_lstate {
676 struct cam_path *path;
677 struct ccb_hdr_slist accept_tios;
678 struct ccb_hdr_slist immed_notifies;
679 struct ahc_tmode_event event_buffer[AHC_TMODE_EVENT_BUFFER_SIZE];
680 uint8_t event_r_idx;
681 uint8_t event_w_idx;
682};
683#else
684struct ahc_tmode_lstate;
685#endif
686
687/******************** Transfer Negotiation Datastructures *********************/
688#define AHC_TRANS_CUR 0x01 /* Modify current neogtiation status */
689#define AHC_TRANS_ACTIVE 0x03 /* Assume this target is on the bus */
690#define AHC_TRANS_GOAL 0x04 /* Modify negotiation goal */
691#define AHC_TRANS_USER 0x08 /* Modify user negotiation settings */
692
693#define AHC_WIDTH_UNKNOWN 0xFF
694#define AHC_PERIOD_UNKNOWN 0xFF
695#define AHC_OFFSET_UNKNOWN 0xFF
696#define AHC_PPR_OPTS_UNKNOWN 0xFF
697
698/*
699 * Transfer Negotiation Information.
700 */
701struct ahc_transinfo {
702 uint8_t protocol_version; /* SCSI Revision level */
703 uint8_t transport_version; /* SPI Revision level */
704 uint8_t width; /* Bus width */
705 uint8_t period; /* Sync rate factor */
706 uint8_t offset; /* Sync offset */
707 uint8_t ppr_options; /* Parallel Protocol Request options */
708};
709
710/*
711 * Per-initiator current, goal and user transfer negotiation information. */
712struct ahc_initiator_tinfo {
713 uint8_t scsirate; /* Computed value for SCSIRATE reg */
714 struct ahc_transinfo curr;
715 struct ahc_transinfo goal;
716 struct ahc_transinfo user;
717};
718
719/*
720 * Per enabled target ID state.
721 * Pointers to lun target state as well as sync/wide negotiation information
722 * for each initiator<->target mapping. For the initiator role we pretend
723 * that we are the target and the targets are the initiators since the
724 * negotiation is the same regardless of role.
725 */
726struct ahc_tmode_tstate {
727 struct ahc_tmode_lstate* enabled_luns[AHC_NUM_LUNS];
728 struct ahc_initiator_tinfo transinfo[AHC_NUM_TARGETS];
729
730 /*
731 * Per initiator state bitmasks.
732 */
733 uint16_t auto_negotiate;/* Auto Negotiation Required */
734 uint16_t ultraenb; /* Using ultra sync rate */
735 uint16_t discenable; /* Disconnection allowed */
736 uint16_t tagenable; /* Tagged Queuing allowed */
737};
738
739/*
740 * Data structure for our table of allowed synchronous transfer rates.
741 */
742struct ahc_syncrate {
743 u_int sxfr_u2; /* Value of the SXFR parameter for Ultra2+ Chips */
744 u_int sxfr; /* Value of the SXFR parameter for <= Ultra Chips */
745#define ULTRA_SXFR 0x100 /* Rate Requires Ultra Mode set */
746#define ST_SXFR 0x010 /* Rate Single Transition Only */
747#define DT_SXFR 0x040 /* Rate Double Transition Only */
748 uint8_t period; /* Period to send to SCSI target */
749 char *rate;
750};
751
752/* Safe and valid period for async negotiations. */
753#define AHC_ASYNC_XFER_PERIOD 0x45
754#define AHC_ULTRA2_XFER_PERIOD 0x0a
755
756/*
757 * Indexes into our table of syncronous transfer rates.
758 */
759#define AHC_SYNCRATE_DT 0
760#define AHC_SYNCRATE_ULTRA2 1
761#define AHC_SYNCRATE_ULTRA 3
762#define AHC_SYNCRATE_FAST 6
763#define AHC_SYNCRATE_MAX AHC_SYNCRATE_DT
764#define AHC_SYNCRATE_MIN 13
765
766/***************************** Lookup Tables **********************************/
767/*
768 * Phase -> name and message out response
769 * to parity errors in each phase table.
770 */
771struct ahc_phase_table_entry {
772 uint8_t phase;
773 uint8_t mesg_out; /* Message response to parity errors */
774 char *phasemsg;
775};
776
777/************************** Serial EEPROM Format ******************************/
778
779struct seeprom_config {
780/*
781 * Per SCSI ID Configuration Flags
782 */
783 uint16_t device_flags[16]; /* words 0-15 */
784#define CFXFER 0x0007 /* synchronous transfer rate */
785#define CFSYNCH 0x0008 /* enable synchronous transfer */
786#define CFDISC 0x0010 /* enable disconnection */
787#define CFWIDEB 0x0020 /* wide bus device */
788#define CFSYNCHISULTRA 0x0040 /* CFSYNCH is an ultra offset (2940AU)*/
789#define CFSYNCSINGLE 0x0080 /* Single-Transition signalling */
790#define CFSTART 0x0100 /* send start unit SCSI command */
791#define CFINCBIOS 0x0200 /* include in BIOS scan */
792#define CFRNFOUND 0x0400 /* report even if not found */
793#define CFMULTILUNDEV 0x0800 /* Probe multiple luns in BIOS scan */
794#define CFWBCACHEENB 0x4000 /* Enable W-Behind Cache on disks */
795#define CFWBCACHENOP 0xc000 /* Don't touch W-Behind Cache */
796
797/*
798 * BIOS Control Bits
799 */
800 uint16_t bios_control; /* word 16 */
801#define CFSUPREM 0x0001 /* support all removeable drives */
802#define CFSUPREMB 0x0002 /* support removeable boot drives */
803#define CFBIOSEN 0x0004 /* BIOS enabled */
804#define CFBIOS_BUSSCAN 0x0008 /* Have the BIOS Scan the Bus */
805#define CFSM2DRV 0x0010 /* support more than two drives */
806#define CFSTPWLEVEL 0x0010 /* Termination level control */
807#define CF284XEXTEND 0x0020 /* extended translation (284x cards) */
808#define CFCTRL_A 0x0020 /* BIOS displays Ctrl-A message */
809#define CFTERM_MENU 0x0040 /* BIOS displays termination menu */
810#define CFEXTEND 0x0080 /* extended translation enabled */
811#define CFSCAMEN 0x0100 /* SCAM enable */
812#define CFMSG_LEVEL 0x0600 /* BIOS Message Level */
813#define CFMSG_VERBOSE 0x0000
814#define CFMSG_SILENT 0x0200
815#define CFMSG_DIAG 0x0400
816#define CFBOOTCD 0x0800 /* Support Bootable CD-ROM */
817/* UNUSED 0xff00 */
818
819/*
820 * Host Adapter Control Bits
821 */
822 uint16_t adapter_control; /* word 17 */
823#define CFAUTOTERM 0x0001 /* Perform Auto termination */
824#define CFULTRAEN 0x0002 /* Ultra SCSI speed enable */
825#define CF284XSELTO 0x0003 /* Selection timeout (284x cards) */
826#define CF284XFIFO 0x000C /* FIFO Threshold (284x cards) */
827#define CFSTERM 0x0004 /* SCSI low byte termination */
828#define CFWSTERM 0x0008 /* SCSI high byte termination */
829#define CFSPARITY 0x0010 /* SCSI parity */
830#define CF284XSTERM 0x0020 /* SCSI low byte term (284x cards) */
831#define CFMULTILUN 0x0020
832#define CFRESETB 0x0040 /* reset SCSI bus at boot */
833#define CFCLUSTERENB 0x0080 /* Cluster Enable */
834#define CFBOOTCHAN 0x0300 /* probe this channel first */
835#define CFBOOTCHANSHIFT 8
836#define CFSEAUTOTERM 0x0400 /* Ultra2 Perform secondary Auto Term*/
837#define CFSELOWTERM 0x0800 /* Ultra2 secondary low term */
838#define CFSEHIGHTERM 0x1000 /* Ultra2 secondary high term */
839#define CFENABLEDV 0x4000 /* Perform Domain Validation*/
840
841/*
842 * Bus Release Time, Host Adapter ID
843 */
844 uint16_t brtime_id; /* word 18 */
845#define CFSCSIID 0x000f /* host adapter SCSI ID */
846/* UNUSED 0x00f0 */
847#define CFBRTIME 0xff00 /* bus release time */
848
849/*
850 * Maximum targets
851 */
852 uint16_t max_targets; /* word 19 */
853#define CFMAXTARG 0x00ff /* maximum targets */
854#define CFBOOTLUN 0x0f00 /* Lun to boot from */
855#define CFBOOTID 0xf000 /* Target to boot from */
856 uint16_t res_1[10]; /* words 20-29 */
857 uint16_t signature; /* Signature == 0x250 */
858#define CFSIGNATURE 0x250
859#define CFSIGNATURE2 0x300
860 uint16_t checksum; /* word 31 */
861};
862
863/**************************** Message Buffer *********************************/
864typedef enum {
865 MSG_TYPE_NONE = 0x00,
866 MSG_TYPE_INITIATOR_MSGOUT = 0x01,
867 MSG_TYPE_INITIATOR_MSGIN = 0x02,
868 MSG_TYPE_TARGET_MSGOUT = 0x03,
869 MSG_TYPE_TARGET_MSGIN = 0x04
870} ahc_msg_type;
871
872typedef enum {
873 MSGLOOP_IN_PROG,
874 MSGLOOP_MSGCOMPLETE,
875 MSGLOOP_TERMINATED
876} msg_loop_stat;
877
878/*********************** Software Configuration Structure *********************/
879TAILQ_HEAD(scb_tailq, scb);
880
881struct ahc_aic7770_softc {
882 /*
883 * Saved register state used for chip_init().
884 */
885 uint8_t busspd;
886 uint8_t bustime;
887};
888
889struct ahc_pci_softc {
890 /*
891 * Saved register state used for chip_init().
892 */
893 uint32_t devconfig;
894 uint16_t targcrccnt;
895 uint8_t command;
896 uint8_t csize_lattime;
897 uint8_t optionmode;
898 uint8_t crccontrol1;
899 uint8_t dscommand0;
900 uint8_t dspcistatus;
901 uint8_t scbbaddr;
902 uint8_t dff_thrsh;
903};
904
905union ahc_bus_softc {
906 struct ahc_aic7770_softc aic7770_softc;
907 struct ahc_pci_softc pci_softc;
908};
909
910typedef void (*ahc_bus_intr_t)(struct ahc_softc *);
911typedef int (*ahc_bus_chip_init_t)(struct ahc_softc *);
912typedef int (*ahc_bus_suspend_t)(struct ahc_softc *);
913typedef int (*ahc_bus_resume_t)(struct ahc_softc *);
914typedef void ahc_callback_t (void *);
915
916struct ahc_softc {
917 bus_space_tag_t tag;
918 bus_space_handle_t bsh;
919#ifndef __linux__
920 bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
921#endif
922 struct scb_data *scb_data;
923
924 struct scb *next_queued_scb;
925
926 /*
927 * SCBs that have been sent to the controller
928 */
929 LIST_HEAD(, scb) pending_scbs;
930
931 /*
932 * Counting lock for deferring the release of additional
933 * untagged transactions from the untagged_queues. When
934 * the lock is decremented to 0, all queues in the
935 * untagged_queues array are run.
936 */
937 u_int untagged_queue_lock;
938
939 /*
940 * Per-target queue of untagged-transactions. The
941 * transaction at the head of the queue is the
942 * currently pending untagged transaction for the
943 * target. The driver only allows a single untagged
944 * transaction per target.
945 */
946 struct scb_tailq untagged_queues[AHC_NUM_TARGETS];
947
948 /*
949 * Bus attachment specific data.
950 */
951 union ahc_bus_softc bus_softc;
952
953 /*
954 * Platform specific data.
955 */
956 struct ahc_platform_data *platform_data;
957
958 /*
959 * Platform specific device information.
960 */
961 ahc_dev_softc_t dev_softc;
962
963 /*
964 * Bus specific device information.
965 */
966 ahc_bus_intr_t bus_intr;
967
968 /*
969 * Bus specific initialization required
970 * after a chip reset.
971 */
972 ahc_bus_chip_init_t bus_chip_init;
973
974 /*
975 * Bus specific suspend routine.
976 */
977 ahc_bus_suspend_t bus_suspend;
978
979 /*
980 * Bus specific resume routine.
981 */
982 ahc_bus_resume_t bus_resume;
983
984 /*
985 * Target mode related state kept on a per enabled lun basis.
986 * Targets that are not enabled will have null entries.
987 * As an initiator, we keep one target entry for our initiator
988 * ID to store our sync/wide transfer settings.
989 */
990 struct ahc_tmode_tstate *enabled_targets[AHC_NUM_TARGETS];
991
992 /*
993 * The black hole device responsible for handling requests for
994 * disabled luns on enabled targets.
995 */
996 struct ahc_tmode_lstate *black_hole;
997
998 /*
999 * Device instance currently on the bus awaiting a continue TIO
1000 * for a command that was not given the disconnect priveledge.
1001 */
1002 struct ahc_tmode_lstate *pending_device;
1003
1004 /*
1005 * Card characteristics
1006 */
1007 ahc_chip chip;
1008 ahc_feature features;
1009 ahc_bug bugs;
1010 ahc_flag flags;
1011 struct seeprom_config *seep_config;
1012
1013 /* Values to store in the SEQCTL register for pause and unpause */
1014 uint8_t unpause;
1015 uint8_t pause;
1016
1017 /* Command Queues */
1018 uint8_t qoutfifonext;
1019 uint8_t qinfifonext;
1020 uint8_t *qoutfifo;
1021 uint8_t *qinfifo;
1022
1023 /* Critical Section Data */
1024 struct cs *critical_sections;
1025 u_int num_critical_sections;
1026
1027 /* Links for chaining softcs */
1028 TAILQ_ENTRY(ahc_softc) links;
1029
1030 /* Channel Names ('A', 'B', etc.) */
1031 char channel;
1032 char channel_b;
1033
1034 /* Initiator Bus ID */
1035 uint8_t our_id;
1036 uint8_t our_id_b;
1037
1038 /*
1039 * PCI error detection.
1040 */
1041 int unsolicited_ints;
1042
1043 /*
1044 * Target incoming command FIFO.
1045 */
1046 struct target_cmd *targetcmds;
1047 uint8_t tqinfifonext;
1048
1049 /*
1050 * Cached copy of the sequencer control register.
1051 */
1052 uint8_t seqctl;
1053
1054 /*
1055 * Incoming and outgoing message handling.
1056 */
1057 uint8_t send_msg_perror;
1058 ahc_msg_type msg_type;
1059 uint8_t msgout_buf[12];/* Message we are sending */
1060 uint8_t msgin_buf[12];/* Message we are receiving */
1061 u_int msgout_len; /* Length of message to send */
1062 u_int msgout_index; /* Current index in msgout */
1063 u_int msgin_index; /* Current index in msgin */
1064
1065 /*
1066 * Mapping information for data structures shared
1067 * between the sequencer and kernel.
1068 */
1069 bus_dma_tag_t parent_dmat;
1070 bus_dma_tag_t shared_data_dmat;
1071 bus_dmamap_t shared_data_dmamap;
1072 dma_addr_t shared_data_busaddr;
1073
1074 /*
1075 * Bus address of the one byte buffer used to
1076 * work-around a DMA bug for chips <= aic7880
1077 * in target mode.
1078 */
1079 dma_addr_t dma_bug_buf;
1080
1081 /* Number of enabled target mode device on this card */
1082 u_int enabled_luns;
1083
1084 /* Initialization level of this data structure */
1085 u_int init_level;
1086
1087 /* PCI cacheline size. */
1088 u_int pci_cachesize;
1089
1090 /*
1091 * Count of parity errors we have seen as a target.
1092 * We auto-disable parity error checking after seeing
1093 * AHC_PCI_TARGET_PERR_THRESH number of errors.
1094 */
1095 u_int pci_target_perr_count;
1096#define AHC_PCI_TARGET_PERR_THRESH 10
1097
1098 /* Maximum number of sequencer instructions supported. */
1099 u_int instruction_ram_size;
1100
1101 /* Per-Unit descriptive information */
1102 const char *description;
1103 char *name;
1104 int unit;
1105
1106 /* Selection Timer settings */
1107 int seltime;
1108 int seltime_b;
1109
1110 uint16_t user_discenable;/* Disconnection allowed */
1111 uint16_t user_tagenable;/* Tagged Queuing allowed */
1112};
1113
1114TAILQ_HEAD(ahc_softc_tailq, ahc_softc);
1115extern struct ahc_softc_tailq ahc_tailq;
1116
1117/************************ Active Device Information ***************************/
1118typedef enum {
1119 ROLE_UNKNOWN,
1120 ROLE_INITIATOR,
1121 ROLE_TARGET
1122} role_t;
1123
1124struct ahc_devinfo {
1125 int our_scsiid;
1126 int target_offset;
1127 uint16_t target_mask;
1128 u_int target;
1129 u_int lun;
1130 char channel;
1131 role_t role; /*
1132 * Only guaranteed to be correct if not
1133 * in the busfree state.
1134 */
1135};
1136
1137/****************************** PCI Structures ********************************/
1138typedef int (ahc_device_setup_t)(struct ahc_softc *);
1139
1140struct ahc_pci_identity {
1141 uint64_t full_id;
1142 uint64_t id_mask;
1143 char *name;
1144 ahc_device_setup_t *setup;
1145};
1146extern struct ahc_pci_identity ahc_pci_ident_table[];
1147extern const u_int ahc_num_pci_devs;
1148
1149/***************************** VL/EISA Declarations ***************************/
1150struct aic7770_identity {
1151 uint32_t full_id;
1152 uint32_t id_mask;
1153 const char *name;
1154 ahc_device_setup_t *setup;
1155};
1156extern struct aic7770_identity aic7770_ident_table[];
1157extern const int ahc_num_aic7770_devs;
1158
1159#define AHC_EISA_SLOT_OFFSET 0xc00
1160#define AHC_EISA_IOSIZE 0x100
1161
1162/*************************** Function Declarations ****************************/
1163/******************************************************************************/
1164u_int ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl);
1165void ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl);
1166void ahc_busy_tcl(struct ahc_softc *ahc,
1167 u_int tcl, u_int busyid);
1168
1169/***************************** PCI Front End *********************************/
1170struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t);
1171int ahc_pci_config(struct ahc_softc *,
1172 struct ahc_pci_identity *);
1173int ahc_pci_test_register_access(struct ahc_softc *);
1174
1175/*************************** EISA/VL Front End ********************************/
1176struct aic7770_identity *aic7770_find_device(uint32_t);
1177int aic7770_config(struct ahc_softc *ahc,
1178 struct aic7770_identity *,
1179 u_int port);
1180
1181/************************** SCB and SCB queue management **********************/
1182int ahc_probe_scbs(struct ahc_softc *);
1183void ahc_run_untagged_queues(struct ahc_softc *ahc);
1184void ahc_run_untagged_queue(struct ahc_softc *ahc,
1185 struct scb_tailq *queue);
1186void ahc_qinfifo_requeue_tail(struct ahc_softc *ahc,
1187 struct scb *scb);
1188int ahc_match_scb(struct ahc_softc *ahc, struct scb *scb,
1189 int target, char channel, int lun,
1190 u_int tag, role_t role);
1191
1192/****************************** Initialization ********************************/
1193struct ahc_softc *ahc_alloc(void *platform_arg, char *name);
1194int ahc_softc_init(struct ahc_softc *);
1195void ahc_controller_info(struct ahc_softc *ahc, char *buf);
1196int ahc_chip_init(struct ahc_softc *ahc);
1197int ahc_init(struct ahc_softc *ahc);
1198void ahc_intr_enable(struct ahc_softc *ahc, int enable);
1199void ahc_pause_and_flushwork(struct ahc_softc *ahc);
1200int ahc_suspend(struct ahc_softc *ahc);
1201int ahc_resume(struct ahc_softc *ahc);
1202void ahc_softc_insert(struct ahc_softc *);
1203struct ahc_softc *ahc_find_softc(struct ahc_softc *ahc);
1204void ahc_set_unit(struct ahc_softc *, int);
1205void ahc_set_name(struct ahc_softc *, char *);
1206void ahc_alloc_scbs(struct ahc_softc *ahc);
1207void ahc_free(struct ahc_softc *ahc);
1208int ahc_reset(struct ahc_softc *ahc, int reinit);
1209void ahc_shutdown(void *arg);
1210
1211/*************************** Interrupt Services *******************************/
1212void ahc_clear_intstat(struct ahc_softc *ahc);
1213void ahc_run_qoutfifo(struct ahc_softc *ahc);
1214#ifdef AHC_TARGET_MODE
1215void ahc_run_tqinfifo(struct ahc_softc *ahc, int paused);
1216#endif
1217void ahc_handle_brkadrint(struct ahc_softc *ahc);
1218void ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat);
1219void ahc_handle_scsiint(struct ahc_softc *ahc,
1220 u_int intstat);
1221void ahc_clear_critical_section(struct ahc_softc *ahc);
1222
1223/***************************** Error Recovery *********************************/
1224typedef enum {
1225 SEARCH_COMPLETE,
1226 SEARCH_COUNT,
1227 SEARCH_REMOVE
1228} ahc_search_action;
1229int ahc_search_qinfifo(struct ahc_softc *ahc, int target,
1230 char channel, int lun, u_int tag,
1231 role_t role, uint32_t status,
1232 ahc_search_action action);
1233int ahc_search_untagged_queues(struct ahc_softc *ahc,
1234 ahc_io_ctx_t ctx,
1235 int target, char channel,
1236 int lun, uint32_t status,
1237 ahc_search_action action);
1238int ahc_search_disc_list(struct ahc_softc *ahc, int target,
1239 char channel, int lun, u_int tag,
1240 int stop_on_first, int remove,
1241 int save_state);
1242void ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
1243int ahc_reset_channel(struct ahc_softc *ahc, char channel,
1244 int initiate_reset);
1245int ahc_abort_scbs(struct ahc_softc *ahc, int target,
1246 char channel, int lun, u_int tag,
1247 role_t role, uint32_t status);
1248void ahc_restart(struct ahc_softc *ahc);
1249void ahc_calc_residual(struct ahc_softc *ahc,
1250 struct scb *scb);
1251/*************************** Utility Functions ********************************/
1252struct ahc_phase_table_entry*
1253 ahc_lookup_phase_entry(int phase);
1254void ahc_compile_devinfo(struct ahc_devinfo *devinfo,
1255 u_int our_id, u_int target,
1256 u_int lun, char channel,
1257 role_t role);
1258/************************** Transfer Negotiation ******************************/
1259struct ahc_syncrate* ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
1260 u_int *ppr_options, u_int maxsync);
1261u_int ahc_find_period(struct ahc_softc *ahc,
1262 u_int scsirate, u_int maxsync);
1263void ahc_validate_offset(struct ahc_softc *ahc,
1264 struct ahc_initiator_tinfo *tinfo,
1265 struct ahc_syncrate *syncrate,
1266 u_int *offset, int wide,
1267 role_t role);
1268void ahc_validate_width(struct ahc_softc *ahc,
1269 struct ahc_initiator_tinfo *tinfo,
1270 u_int *bus_width,
1271 role_t role);
1272/*
1273 * Negotiation types. These are used to qualify if we should renegotiate
1274 * even if our goal and current transport parameters are identical.
1275 */
1276typedef enum {
1277 AHC_NEG_TO_GOAL, /* Renegotiate only if goal and curr differ. */
1278 AHC_NEG_IF_NON_ASYNC, /* Renegotiate so long as goal is non-async. */
1279 AHC_NEG_ALWAYS /* Renegotiat even if goal is async. */
1280} ahc_neg_type;
1281int ahc_update_neg_request(struct ahc_softc*,
1282 struct ahc_devinfo*,
1283 struct ahc_tmode_tstate*,
1284 struct ahc_initiator_tinfo*,
1285 ahc_neg_type);
1286void ahc_set_width(struct ahc_softc *ahc,
1287 struct ahc_devinfo *devinfo,
1288 u_int width, u_int type, int paused);
1289void ahc_set_syncrate(struct ahc_softc *ahc,
1290 struct ahc_devinfo *devinfo,
1291 struct ahc_syncrate *syncrate,
1292 u_int period, u_int offset,
1293 u_int ppr_options,
1294 u_int type, int paused);
1295typedef enum {
1296 AHC_QUEUE_NONE,
1297 AHC_QUEUE_BASIC,
1298 AHC_QUEUE_TAGGED
1299} ahc_queue_alg;
1300
1301void ahc_set_tags(struct ahc_softc *ahc,
1302 struct ahc_devinfo *devinfo,
1303 ahc_queue_alg alg);
1304
1305/**************************** Target Mode *************************************/
1306#ifdef AHC_TARGET_MODE
1307void ahc_send_lstate_events(struct ahc_softc *,
1308 struct ahc_tmode_lstate *);
1309void ahc_handle_en_lun(struct ahc_softc *ahc,
1310 struct cam_sim *sim, union ccb *ccb);
1311cam_status ahc_find_tmode_devs(struct ahc_softc *ahc,
1312 struct cam_sim *sim, union ccb *ccb,
1313 struct ahc_tmode_tstate **tstate,
1314 struct ahc_tmode_lstate **lstate,
1315 int notfound_failure);
1316#ifndef AHC_TMODE_ENABLE
1317#define AHC_TMODE_ENABLE 0
1318#endif
1319#endif
1320/******************************* Debug ***************************************/
1321#ifdef AHC_DEBUG
1322extern uint32_t ahc_debug;
1323#define AHC_SHOW_MISC 0x0001
1324#define AHC_SHOW_SENSE 0x0002
1325#define AHC_DUMP_SEEPROM 0x0004
1326#define AHC_SHOW_TERMCTL 0x0008
1327#define AHC_SHOW_MEMORY 0x0010
1328#define AHC_SHOW_MESSAGES 0x0020
1329#define AHC_SHOW_DV 0x0040
1330#define AHC_SHOW_SELTO 0x0080
1331#define AHC_SHOW_QFULL 0x0200
1332#define AHC_SHOW_QUEUE 0x0400
1333#define AHC_SHOW_TQIN 0x0800
1334#define AHC_SHOW_MASKED_ERRORS 0x1000
1335#define AHC_DEBUG_SEQUENCER 0x2000
1336#endif
1337void ahc_print_scb(struct scb *scb);
1338void ahc_print_devinfo(struct ahc_softc *ahc,
1339 struct ahc_devinfo *dev);
1340void ahc_dump_card_state(struct ahc_softc *ahc);
1341int ahc_print_register(ahc_reg_parse_entry_t *table,
1342 u_int num_entries,
1343 const char *name,
1344 u_int address,
1345 u_int value,
1346 u_int *cur_column,
1347 u_int wrap_point);
1348/******************************* SEEPROM *************************************/
1349int ahc_acquire_seeprom(struct ahc_softc *ahc,
1350 struct seeprom_descriptor *sd);
1351void ahc_release_seeprom(struct seeprom_descriptor *sd);
1352#endif /* _AIC7XXX_H_ */
diff --git a/drivers/scsi/aic7xxx/aic7xxx.reg b/drivers/scsi/aic7xxx/aic7xxx.reg
new file mode 100644
index 000000000000..810ec700d9fc
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx.reg
@@ -0,0 +1,1594 @@
1/*
2 * Aic7xxx register and scratch ram definitions.
3 *
4 * Copyright (c) 1994-2001 Justin T. Gibbs.
5 * Copyright (c) 2000-2001 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $FreeBSD$
41 */
42VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $"
43
44/*
45 * This file is processed by the aic7xxx_asm utility for use in assembling
46 * firmware for the aic7xxx family of SCSI host adapters as well as to generate
47 * a C header file for use in the kernel portion of the Aic7xxx driver.
48 *
49 * All page numbers refer to the Adaptec AIC-7770 Data Book available from
50 * Adaptec's Technical Documents Department 1-800-934-2766
51 */
52
53/*
54 * SCSI Sequence Control (p. 3-11).
55 * Each bit, when set starts a specific SCSI sequence on the bus
56 */
57register SCSISEQ {
58 address 0x000
59 access_mode RW
60 field TEMODE 0x80
61 field ENSELO 0x40
62 field ENSELI 0x20
63 field ENRSELI 0x10
64 field ENAUTOATNO 0x08
65 field ENAUTOATNI 0x04
66 field ENAUTOATNP 0x02
67 field SCSIRSTO 0x01
68}
69
70/*
71 * SCSI Transfer Control 0 Register (pp. 3-13).
72 * Controls the SCSI module data path.
73 */
74register SXFRCTL0 {
75 address 0x001
76 access_mode RW
77 field DFON 0x80
78 field DFPEXP 0x40
79 field FAST20 0x20
80 field CLRSTCNT 0x10
81 field SPIOEN 0x08
82 field SCAMEN 0x04
83 field CLRCHN 0x02
84}
85
86/*
87 * SCSI Transfer Control 1 Register (pp. 3-14,15).
88 * Controls the SCSI module data path.
89 */
90register SXFRCTL1 {
91 address 0x002
92 access_mode RW
93 field BITBUCKET 0x80
94 field SWRAPEN 0x40
95 field ENSPCHK 0x20
96 mask STIMESEL 0x18
97 field ENSTIMER 0x04
98 field ACTNEGEN 0x02
99 field STPWEN 0x01 /* Powered Termination */
100}
101
102/*
103 * SCSI Control Signal Read Register (p. 3-15).
104 * Reads the actual state of the SCSI bus pins
105 */
106register SCSISIGI {
107 address 0x003
108 access_mode RO
109 field CDI 0x80
110 field IOI 0x40
111 field MSGI 0x20
112 field ATNI 0x10
113 field SELI 0x08
114 field BSYI 0x04
115 field REQI 0x02
116 field ACKI 0x01
117/*
118 * Possible phases in SCSISIGI
119 */
120 mask PHASE_MASK CDI|IOI|MSGI
121 mask P_DATAOUT 0x00
122 mask P_DATAIN IOI
123 mask P_DATAOUT_DT P_DATAOUT|MSGI
124 mask P_DATAIN_DT P_DATAIN|MSGI
125 mask P_COMMAND CDI
126 mask P_MESGOUT CDI|MSGI
127 mask P_STATUS CDI|IOI
128 mask P_MESGIN CDI|IOI|MSGI
129}
130
131/*
132 * SCSI Control Signal Write Register (p. 3-16).
133 * Writing to this register modifies the control signals on the bus. Only
134 * those signals that are allowed in the current mode (Initiator/Target) are
135 * asserted.
136 */
137register SCSISIGO {
138 address 0x003
139 access_mode WO
140 field CDO 0x80
141 field IOO 0x40
142 field MSGO 0x20
143 field ATNO 0x10
144 field SELO 0x08
145 field BSYO 0x04
146 field REQO 0x02
147 field ACKO 0x01
148/*
149 * Possible phases to write into SCSISIG0
150 */
151 mask PHASE_MASK CDI|IOI|MSGI
152 mask P_DATAOUT 0x00
153 mask P_DATAIN IOI
154 mask P_COMMAND CDI
155 mask P_MESGOUT CDI|MSGI
156 mask P_STATUS CDI|IOI
157 mask P_MESGIN CDI|IOI|MSGI
158}
159
160/*
161 * SCSI Rate Control (p. 3-17).
162 * Contents of this register determine the Synchronous SCSI data transfer
163 * rate and the maximum synchronous Req/Ack offset. An offset of 0 in the
164 * SOFS (3:0) bits disables synchronous data transfers. Any offset value
165 * greater than 0 enables synchronous transfers.
166 */
167register SCSIRATE {
168 address 0x004
169 access_mode RW
170 field WIDEXFER 0x80 /* Wide transfer control */
171 field ENABLE_CRC 0x40 /* CRC for D-Phases */
172 field SINGLE_EDGE 0x10 /* Disable DT Transfers */
173 mask SXFR 0x70 /* Sync transfer rate */
174 mask SXFR_ULTRA2 0x0f /* Sync transfer rate */
175 mask SOFS 0x0f /* Sync offset */
176}
177
178/*
179 * SCSI ID (p. 3-18).
180 * Contains the ID of the board and the current target on the
181 * selected channel.
182 */
183register SCSIID {
184 address 0x005
185 access_mode RW
186 mask TID 0xf0 /* Target ID mask */
187 mask TWIN_TID 0x70
188 field TWIN_CHNLB 0x80
189 mask OID 0x0f /* Our ID mask */
190 /*
191 * SCSI Maximum Offset (p. 4-61 aic7890/91 Data Book)
192 * The aic7890/91 allow an offset of up to 127 transfers in both wide
193 * and narrow mode.
194 */
195 alias SCSIOFFSET
196 mask SOFS_ULTRA2 0x7f /* Sync offset U2 chips */
197}
198
199/*
200 * SCSI Latched Data (p. 3-19).
201 * Read/Write latches used to transfer data on the SCSI bus during
202 * Automatic or Manual PIO mode. SCSIDATH can be used for the
203 * upper byte of a 16bit wide asynchronouse data phase transfer.
204 */
205register SCSIDATL {
206 address 0x006
207 access_mode RW
208}
209
210register SCSIDATH {
211 address 0x007
212 access_mode RW
213}
214
215/*
216 * SCSI Transfer Count (pp. 3-19,20)
217 * These registers count down the number of bytes transferred
218 * across the SCSI bus. The counter is decremented only once
219 * the data has been safely transferred. SDONE in SSTAT0 is
220 * set when STCNT goes to 0
221 */
222register STCNT {
223 address 0x008
224 size 3
225 access_mode RW
226}
227
228/* ALT_MODE registers (Ultra2 and Ultra160 chips) */
229register SXFRCTL2 {
230 address 0x013
231 access_mode RW
232 field AUTORSTDIS 0x10
233 field CMDDMAEN 0x08
234 mask ASYNC_SETUP 0x07
235}
236
237/* ALT_MODE register on Ultra160 chips */
238register OPTIONMODE {
239 address 0x008
240 access_mode RW
241 field AUTORATEEN 0x80
242 field AUTOACKEN 0x40
243 field ATNMGMNTEN 0x20
244 field BUSFREEREV 0x10
245 field EXPPHASEDIS 0x08
246 field SCSIDATL_IMGEN 0x04
247 field AUTO_MSGOUT_DE 0x02
248 field DIS_MSGIN_DUALEDGE 0x01
249 mask OPTIONMODE_DEFAULTS AUTO_MSGOUT_DE|DIS_MSGIN_DUALEDGE
250}
251
252/* ALT_MODE register on Ultra160 chips */
253register TARGCRCCNT {
254 address 0x00a
255 size 2
256 access_mode RW
257}
258
259/*
260 * Clear SCSI Interrupt 0 (p. 3-20)
261 * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT0.
262 */
263register CLRSINT0 {
264 address 0x00b
265 access_mode WO
266 field CLRSELDO 0x40
267 field CLRSELDI 0x20
268 field CLRSELINGO 0x10
269 field CLRSWRAP 0x08
270 field CLRIOERR 0x08 /* Ultra2 Only */
271 field CLRSPIORDY 0x02
272}
273
274/*
275 * SCSI Status 0 (p. 3-21)
276 * Contains one set of SCSI Interrupt codes
277 * These are most likely of interest to the sequencer
278 */
279register SSTAT0 {
280 address 0x00b
281 access_mode RO
282 field TARGET 0x80 /* Board acting as target */
283 field SELDO 0x40 /* Selection Done */
284 field SELDI 0x20 /* Board has been selected */
285 field SELINGO 0x10 /* Selection In Progress */
286 field SWRAP 0x08 /* 24bit counter wrap */
287 field IOERR 0x08 /* LVD Tranceiver mode changed */
288 field SDONE 0x04 /* STCNT = 0x000000 */
289 field SPIORDY 0x02 /* SCSI PIO Ready */
290 field DMADONE 0x01 /* DMA transfer completed */
291}
292
293/*
294 * Clear SCSI Interrupt 1 (p. 3-23)
295 * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT1.
296 */
297register CLRSINT1 {
298 address 0x00c
299 access_mode WO
300 field CLRSELTIMEO 0x80
301 field CLRATNO 0x40
302 field CLRSCSIRSTI 0x20
303 field CLRBUSFREE 0x08
304 field CLRSCSIPERR 0x04
305 field CLRPHASECHG 0x02
306 field CLRREQINIT 0x01
307}
308
309/*
310 * SCSI Status 1 (p. 3-24)
311 */
312register SSTAT1 {
313 address 0x00c
314 access_mode RO
315 field SELTO 0x80
316 field ATNTARG 0x40
317 field SCSIRSTI 0x20
318 field PHASEMIS 0x10
319 field BUSFREE 0x08
320 field SCSIPERR 0x04
321 field PHASECHG 0x02
322 field REQINIT 0x01
323}
324
325/*
326 * SCSI Status 2 (pp. 3-25,26)
327 */
328register SSTAT2 {
329 address 0x00d
330 access_mode RO
331 field OVERRUN 0x80
332 field SHVALID 0x40 /* Shaddow Layer non-zero */
333 field EXP_ACTIVE 0x10 /* SCSI Expander Active */
334 field CRCVALERR 0x08 /* CRC doesn't match (U3 only) */
335 field CRCENDERR 0x04 /* No terminal CRC packet (U3 only) */
336 field CRCREQERR 0x02 /* Illegal CRC packet req (U3 only) */
337 field DUAL_EDGE_ERR 0x01 /* Incorrect data phase (U3 only) */
338 mask SFCNT 0x1f
339}
340
341/*
342 * SCSI Status 3 (p. 3-26)
343 */
344register SSTAT3 {
345 address 0x00e
346 access_mode RO
347 mask SCSICNT 0xf0
348 mask OFFCNT 0x0f
349 mask U2OFFCNT 0x7f
350}
351
352/*
353 * SCSI ID for the aic7890/91 chips
354 */
355register SCSIID_ULTRA2 {
356 address 0x00f
357 access_mode RW
358 mask TID 0xf0 /* Target ID mask */
359 mask OID 0x0f /* Our ID mask */
360}
361
362/*
363 * SCSI Interrupt Mode 1 (p. 3-28)
364 * Setting any bit will enable the corresponding function
365 * in SIMODE0 to interrupt via the IRQ pin.
366 */
367register SIMODE0 {
368 address 0x010
369 access_mode RW
370 field ENSELDO 0x40
371 field ENSELDI 0x20
372 field ENSELINGO 0x10
373 field ENSWRAP 0x08
374 field ENIOERR 0x08 /* LVD Tranceiver mode changes */
375 field ENSDONE 0x04
376 field ENSPIORDY 0x02
377 field ENDMADONE 0x01
378}
379
380/*
381 * SCSI Interrupt Mode 1 (pp. 3-28,29)
382 * Setting any bit will enable the corresponding function
383 * in SIMODE1 to interrupt via the IRQ pin.
384 */
385register SIMODE1 {
386 address 0x011
387 access_mode RW
388 field ENSELTIMO 0x80
389 field ENATNTARG 0x40
390 field ENSCSIRST 0x20
391 field ENPHASEMIS 0x10
392 field ENBUSFREE 0x08
393 field ENSCSIPERR 0x04
394 field ENPHASECHG 0x02
395 field ENREQINIT 0x01
396}
397
398/*
399 * SCSI Data Bus (High) (p. 3-29)
400 * This register reads data on the SCSI Data bus directly.
401 */
402register SCSIBUSL {
403 address 0x012
404 access_mode RW
405}
406
407register SCSIBUSH {
408 address 0x013
409 access_mode RW
410}
411
412/*
413 * SCSI/Host Address (p. 3-30)
414 * These registers hold the host address for the byte about to be
415 * transferred on the SCSI bus. They are counted up in the same
416 * manner as STCNT is counted down. SHADDR should always be used
417 * to determine the address of the last byte transferred since HADDR
418 * can be skewed by write ahead.
419 */
420register SHADDR {
421 address 0x014
422 size 4
423 access_mode RO
424}
425
426/*
427 * Selection Timeout Timer (p. 3-30)
428 */
429register SELTIMER {
430 address 0x018
431 access_mode RW
432 field STAGE6 0x20
433 field STAGE5 0x10
434 field STAGE4 0x08
435 field STAGE3 0x04
436 field STAGE2 0x02
437 field STAGE1 0x01
438 alias TARGIDIN
439}
440
441/*
442 * Selection/Reselection ID (p. 3-31)
443 * Upper four bits are the device id. The ONEBIT is set when the re/selecting
444 * device did not set its own ID.
445 */
446register SELID {
447 address 0x019
448 access_mode RW
449 mask SELID_MASK 0xf0
450 field ONEBIT 0x08
451}
452
453register SCAMCTL {
454 address 0x01a
455 access_mode RW
456 field ENSCAMSELO 0x80
457 field CLRSCAMSELID 0x40
458 field ALTSTIM 0x20
459 field DFLTTID 0x10
460 mask SCAMLVL 0x03
461}
462
463/*
464 * Target Mode Selecting in ID bitmask (aic7890/91/96/97)
465 */
466register TARGID {
467 address 0x01b
468 size 2
469 access_mode RW
470}
471
472/*
473 * Serial Port I/O Cabability register (p. 4-95 aic7860 Data Book)
474 * Indicates if external logic has been attached to the chip to
475 * perform the tasks of accessing a serial eeprom, testing termination
476 * strength, and performing cable detection. On the aic7860, most of
477 * these features are handled on chip, but on the aic7855 an attached
478 * aic3800 does the grunt work.
479 */
480register SPIOCAP {
481 address 0x01b
482 access_mode RW
483 field SOFT1 0x80
484 field SOFT0 0x40
485 field SOFTCMDEN 0x20
486 field EXT_BRDCTL 0x10 /* External Board control */
487 field SEEPROM 0x08 /* External serial eeprom logic */
488 field EEPROM 0x04 /* Writable external BIOS ROM */
489 field ROM 0x02 /* Logic for accessing external ROM */
490 field SSPIOCPS 0x01 /* Termination and cable detection */
491}
492
493register BRDCTL {
494 address 0x01d
495 field BRDDAT7 0x80
496 field BRDDAT6 0x40
497 field BRDDAT5 0x20
498 field BRDSTB 0x10
499 field BRDCS 0x08
500 field BRDRW 0x04
501 field BRDCTL1 0x02
502 field BRDCTL0 0x01
503 /* 7890 Definitions */
504 field BRDDAT4 0x10
505 field BRDDAT3 0x08
506 field BRDDAT2 0x04
507 field BRDRW_ULTRA2 0x02
508 field BRDSTB_ULTRA2 0x01
509}
510
511/*
512 * Serial EEPROM Control (p. 4-92 in 7870 Databook)
513 * Controls the reading and writing of an external serial 1-bit
514 * EEPROM Device. In order to access the serial EEPROM, you must
515 * first set the SEEMS bit that generates a request to the memory
516 * port for access to the serial EEPROM device. When the memory
517 * port is not busy servicing another request, it reconfigures
518 * to allow access to the serial EEPROM. When this happens, SEERDY
519 * gets set high to verify that the memory port access has been
520 * granted.
521 *
522 * After successful arbitration for the memory port, the SEECS bit of
523 * the SEECTL register is connected to the chip select. The SEECK,
524 * SEEDO, and SEEDI are connected to the clock, data out, and data in
525 * lines respectively. The SEERDY bit of SEECTL is useful in that it
526 * gives us an 800 nsec timer. After a write to the SEECTL register,
527 * the SEERDY goes high 800 nsec later. The one exception to this is
528 * when we first request access to the memory port. The SEERDY goes
529 * high to signify that access has been granted and, for this case, has
530 * no implied timing.
531 *
532 * See 93cx6.c for detailed information on the protocol necessary to
533 * read the serial EEPROM.
534 */
535register SEECTL {
536 address 0x01e
537 field EXTARBACK 0x80
538 field EXTARBREQ 0x40
539 field SEEMS 0x20
540 field SEERDY 0x10
541 field SEECS 0x08
542 field SEECK 0x04
543 field SEEDO 0x02
544 field SEEDI 0x01
545}
546/*
547 * SCSI Block Control (p. 3-32)
548 * Controls Bus type and channel selection. In a twin channel configuration
549 * addresses 0x00-0x1e are gated to the appropriate channel based on this
550 * register. SELWIDE allows for the coexistence of 8bit and 16bit devices
551 * on a wide bus.
552 */
553register SBLKCTL {
554 address 0x01f
555 access_mode RW
556 field DIAGLEDEN 0x80 /* Aic78X0 only */
557 field DIAGLEDON 0x40 /* Aic78X0 only */
558 field AUTOFLUSHDIS 0x20
559 field SELBUSB 0x08
560 field ENAB40 0x08 /* LVD transceiver active */
561 field ENAB20 0x04 /* SE/HVD transceiver active */
562 field SELWIDE 0x02
563 field XCVR 0x01 /* External transceiver active */
564}
565
566/*
567 * Sequencer Control (p. 3-33)
568 * Error detection mode and speed configuration
569 */
570register SEQCTL {
571 address 0x060
572 access_mode RW
573 field PERRORDIS 0x80
574 field PAUSEDIS 0x40
575 field FAILDIS 0x20
576 field FASTMODE 0x10
577 field BRKADRINTEN 0x08
578 field STEP 0x04
579 field SEQRESET 0x02
580 field LOADRAM 0x01
581}
582
583/*
584 * Sequencer RAM Data (p. 3-34)
585 * Single byte window into the Scratch Ram area starting at the address
586 * specified by SEQADDR0 and SEQADDR1. To write a full word, simply write
587 * four bytes in succession. The SEQADDRs will increment after the most
588 * significant byte is written
589 */
590register SEQRAM {
591 address 0x061
592 access_mode RW
593}
594
595/*
596 * Sequencer Address Registers (p. 3-35)
597 * Only the first bit of SEQADDR1 holds addressing information
598 */
599register SEQADDR0 {
600 address 0x062
601 access_mode RW
602}
603
604register SEQADDR1 {
605 address 0x063
606 access_mode RW
607 mask SEQADDR1_MASK 0x01
608}
609
610/*
611 * Accumulator
612 * We cheat by passing arguments in the Accumulator up to the kernel driver
613 */
614register ACCUM {
615 address 0x064
616 access_mode RW
617 accumulator
618}
619
620register SINDEX {
621 address 0x065
622 access_mode RW
623 sindex
624}
625
626register DINDEX {
627 address 0x066
628 access_mode RW
629}
630
631register ALLONES {
632 address 0x069
633 access_mode RO
634 allones
635}
636
637register ALLZEROS {
638 address 0x06a
639 access_mode RO
640 allzeros
641}
642
643register NONE {
644 address 0x06a
645 access_mode WO
646 none
647}
648
649register FLAGS {
650 address 0x06b
651 access_mode RO
652 field ZERO 0x02
653 field CARRY 0x01
654}
655
656register SINDIR {
657 address 0x06c
658 access_mode RO
659}
660
661register DINDIR {
662 address 0x06d
663 access_mode WO
664}
665
666register FUNCTION1 {
667 address 0x06e
668 access_mode RW
669}
670
671register STACK {
672 address 0x06f
673 access_mode RO
674}
675
676const STACK_SIZE 4
677
678/*
679 * Board Control (p. 3-43)
680 */
681register BCTL {
682 address 0x084
683 access_mode RW
684 field ACE 0x08
685 field ENABLE 0x01
686}
687
688/*
689 * On the aic78X0 chips, Board Control is replaced by the DSCommand
690 * register (p. 4-64)
691 */
692register DSCOMMAND0 {
693 address 0x084
694 access_mode RW
695 field CACHETHEN 0x80 /* Cache Threshold enable */
696 field DPARCKEN 0x40 /* Data Parity Check Enable */
697 field MPARCKEN 0x20 /* Memory Parity Check Enable */
698 field EXTREQLCK 0x10 /* External Request Lock */
699 /* aic7890/91/96/97 only */
700 field INTSCBRAMSEL 0x08 /* Internal SCB RAM Select */
701 field RAMPS 0x04 /* External SCB RAM Present */
702 field USCBSIZE32 0x02 /* Use 32byte SCB Page Size */
703 field CIOPARCKEN 0x01 /* Internal bus parity error enable */
704}
705
706register DSCOMMAND1 {
707 address 0x085
708 access_mode RW
709 mask DSLATT 0xfc /* PCI latency timer (non-ultra2) */
710 field HADDLDSEL1 0x02 /* Host Address Load Select Bits */
711 field HADDLDSEL0 0x01
712}
713
714/*
715 * Bus On/Off Time (p. 3-44) aic7770 only
716 */
717register BUSTIME {
718 address 0x085
719 access_mode RW
720 mask BOFF 0xf0
721 mask BON 0x0f
722}
723
724/*
725 * Bus Speed (p. 3-45) aic7770 only
726 */
727register BUSSPD {
728 address 0x086
729 access_mode RW
730 mask DFTHRSH 0xc0
731 mask STBOFF 0x38
732 mask STBON 0x07
733 mask DFTHRSH_100 0xc0
734 mask DFTHRSH_75 0x80
735}
736
737/* aic7850/55/60/70/80/95 only */
738register DSPCISTATUS {
739 address 0x086
740 mask DFTHRSH_100 0xc0
741}
742
743/* aic7890/91/96/97 only */
744register HS_MAILBOX {
745 address 0x086
746 mask HOST_MAILBOX 0xF0
747 mask SEQ_MAILBOX 0x0F
748 mask HOST_TQINPOS 0x80 /* Boundary at either 0 or 128 */
749}
750
751const HOST_MAILBOX_SHIFT 4
752const SEQ_MAILBOX_SHIFT 0
753
754/*
755 * Host Control (p. 3-47) R/W
756 * Overall host control of the device.
757 */
758register HCNTRL {
759 address 0x087
760 access_mode RW
761 field POWRDN 0x40
762 field SWINT 0x10
763 field IRQMS 0x08
764 field PAUSE 0x04
765 field INTEN 0x02
766 field CHIPRST 0x01
767 field CHIPRSTACK 0x01
768}
769
770/*
771 * Host Address (p. 3-48)
772 * This register contains the address of the byte about
773 * to be transferred across the host bus.
774 */
775register HADDR {
776 address 0x088
777 size 4
778 access_mode RW
779}
780
781register HCNT {
782 address 0x08c
783 size 3
784 access_mode RW
785}
786
787/*
788 * SCB Pointer (p. 3-49)
789 * Gate one of the SCBs into the SCBARRAY window.
790 */
791register SCBPTR {
792 address 0x090
793 access_mode RW
794}
795
796/*
797 * Interrupt Status (p. 3-50)
798 * Status for system interrupts
799 */
800register INTSTAT {
801 address 0x091
802 access_mode RW
803 field BRKADRINT 0x08
804 field SCSIINT 0x04
805 field CMDCMPLT 0x02
806 field SEQINT 0x01
807 mask BAD_PHASE SEQINT /* unknown scsi bus phase */
808 mask SEND_REJECT 0x10|SEQINT /* sending a message reject */
809 mask PROTO_VIOLATION 0x20|SEQINT /* SCSI protocol violation */
810 mask NO_MATCH 0x30|SEQINT /* no cmd match for reconnect */
811 mask IGN_WIDE_RES 0x40|SEQINT /* Complex IGN Wide Res Msg */
812 mask PDATA_REINIT 0x50|SEQINT /*
813 * Returned to data phase
814 * that requires data
815 * transfer pointers to be
816 * recalculated from the
817 * transfer residual.
818 */
819 mask HOST_MSG_LOOP 0x60|SEQINT /*
820 * The bus is ready for the
821 * host to perform another
822 * message transaction. This
823 * mechanism is used for things
824 * like sync/wide negotiation
825 * that require a kernel based
826 * message state engine.
827 */
828 mask BAD_STATUS 0x70|SEQINT /* Bad status from target */
829 mask PERR_DETECTED 0x80|SEQINT /*
830 * Either the phase_lock
831 * or inb_next routine has
832 * noticed a parity error.
833 */
834 mask DATA_OVERRUN 0x90|SEQINT /*
835 * Target attempted to write
836 * beyond the bounds of its
837 * command.
838 */
839 mask MKMSG_FAILED 0xa0|SEQINT /*
840 * Target completed command
841 * without honoring our ATN
842 * request to issue a message.
843 */
844 mask MISSED_BUSFREE 0xb0|SEQINT /*
845 * The sequencer never saw
846 * the bus go free after
847 * either a command complete
848 * or disconnect message.
849 */
850 mask SCB_MISMATCH 0xc0|SEQINT /*
851 * Downloaded SCB's tag does
852 * not match the entry we
853 * intended to download.
854 */
855 mask NO_FREE_SCB 0xd0|SEQINT /*
856 * get_free_or_disc_scb failed.
857 */
858 mask OUT_OF_RANGE 0xe0|SEQINT
859
860 mask SEQINT_MASK 0xf0|SEQINT /* SEQINT Status Codes */
861 mask INT_PEND (BRKADRINT|SEQINT|SCSIINT|CMDCMPLT)
862}
863
864/*
865 * Hard Error (p. 3-53)
866 * Reporting of catastrophic errors. You usually cannot recover from
867 * these without a full board reset.
868 */
869register ERROR {
870 address 0x092
871 access_mode RO
872 field CIOPARERR 0x80 /* Ultra2 only */
873 field PCIERRSTAT 0x40 /* PCI only */
874 field MPARERR 0x20 /* PCI only */
875 field DPARERR 0x10 /* PCI only */
876 field SQPARERR 0x08
877 field ILLOPCODE 0x04
878 field ILLSADDR 0x02
879 field ILLHADDR 0x01
880}
881
882/*
883 * Clear Interrupt Status (p. 3-52)
884 */
885register CLRINT {
886 address 0x092
887 access_mode WO
888 field CLRPARERR 0x10 /* PCI only */
889 field CLRBRKADRINT 0x08
890 field CLRSCSIINT 0x04
891 field CLRCMDINT 0x02
892 field CLRSEQINT 0x01
893}
894
895register DFCNTRL {
896 address 0x093
897 access_mode RW
898 field PRELOADEN 0x80 /* aic7890 only */
899 field WIDEODD 0x40
900 field SCSIEN 0x20
901 field SDMAEN 0x10
902 field SDMAENACK 0x10
903 field HDMAEN 0x08
904 field HDMAENACK 0x08
905 field DIRECTION 0x04
906 field FIFOFLUSH 0x02
907 field FIFORESET 0x01
908}
909
910register DFSTATUS {
911 address 0x094
912 access_mode RO
913 field PRELOAD_AVAIL 0x80
914 field DFCACHETH 0x40
915 field FIFOQWDEMP 0x20
916 field MREQPEND 0x10
917 field HDONE 0x08
918 field DFTHRESH 0x04
919 field FIFOFULL 0x02
920 field FIFOEMP 0x01
921}
922
923register DFWADDR {
924 address 0x95
925 access_mode RW
926}
927
928register DFRADDR {
929 address 0x97
930 access_mode RW
931}
932
933register DFDAT {
934 address 0x099
935 access_mode RW
936}
937
938/*
939 * SCB Auto Increment (p. 3-59)
940 * Byte offset into the SCB Array and an optional bit to allow auto
941 * incrementing of the address during download and upload operations
942 */
943register SCBCNT {
944 address 0x09a
945 access_mode RW
946 field SCBAUTO 0x80
947 mask SCBCNT_MASK 0x1f
948}
949
950/*
951 * Queue In FIFO (p. 3-60)
952 * Input queue for queued SCBs (commands that the seqencer has yet to start)
953 */
954register QINFIFO {
955 address 0x09b
956 access_mode RW
957}
958
959/*
960 * Queue In Count (p. 3-60)
961 * Number of queued SCBs
962 */
963register QINCNT {
964 address 0x09c
965 access_mode RO
966}
967
968/*
969 * Queue Out FIFO (p. 3-61)
970 * Queue of SCBs that have completed and await the host
971 */
972register QOUTFIFO {
973 address 0x09d
974 access_mode WO
975}
976
977register CRCCONTROL1 {
978 address 0x09d
979 access_mode RW
980 field CRCONSEEN 0x80
981 field CRCVALCHKEN 0x40
982 field CRCENDCHKEN 0x20
983 field CRCREQCHKEN 0x10
984 field TARGCRCENDEN 0x08
985 field TARGCRCCNTEN 0x04
986}
987
988
989/*
990 * Queue Out Count (p. 3-61)
991 * Number of queued SCBs in the Out FIFO
992 */
993register QOUTCNT {
994 address 0x09e
995 access_mode RO
996}
997
998register SCSIPHASE {
999 address 0x09e
1000 access_mode RO
1001 field STATUS_PHASE 0x20
1002 field COMMAND_PHASE 0x10
1003 field MSG_IN_PHASE 0x08
1004 field MSG_OUT_PHASE 0x04
1005 field DATA_IN_PHASE 0x02
1006 field DATA_OUT_PHASE 0x01
1007 mask DATA_PHASE_MASK 0x03
1008}
1009
1010/*
1011 * Special Function
1012 */
1013register SFUNCT {
1014 address 0x09f
1015 access_mode RW
1016 field ALT_MODE 0x80
1017}
1018
1019/*
1020 * SCB Definition (p. 5-4)
1021 */
1022scb {
1023 address 0x0a0
1024 size 64
1025
1026 SCB_CDB_PTR {
1027 size 4
1028 alias SCB_RESIDUAL_DATACNT
1029 alias SCB_CDB_STORE
1030 }
1031 SCB_RESIDUAL_SGPTR {
1032 size 4
1033 }
1034 SCB_SCSI_STATUS {
1035 size 1
1036 }
1037 SCB_TARGET_PHASES {
1038 size 1
1039 }
1040 SCB_TARGET_DATA_DIR {
1041 size 1
1042 }
1043 SCB_TARGET_ITAG {
1044 size 1
1045 }
1046 SCB_DATAPTR {
1047 size 4
1048 }
1049 SCB_DATACNT {
1050 /*
1051 * The last byte is really the high address bits for
1052 * the data address.
1053 */
1054 size 4
1055 field SG_LAST_SEG 0x80 /* In the fourth byte */
1056 mask SG_HIGH_ADDR_BITS 0x7F /* In the fourth byte */
1057 }
1058 SCB_SGPTR {
1059 size 4
1060 field SG_RESID_VALID 0x04 /* In the first byte */
1061 field SG_FULL_RESID 0x02 /* In the first byte */
1062 field SG_LIST_NULL 0x01 /* In the first byte */
1063 }
1064 SCB_CONTROL {
1065 size 1
1066 field TARGET_SCB 0x80
1067 field STATUS_RCVD 0x80
1068 field DISCENB 0x40
1069 field TAG_ENB 0x20
1070 field MK_MESSAGE 0x10
1071 field ULTRAENB 0x08
1072 field DISCONNECTED 0x04
1073 mask SCB_TAG_TYPE 0x03
1074 }
1075 SCB_SCSIID {
1076 size 1
1077 field TWIN_CHNLB 0x80
1078 mask TWIN_TID 0x70
1079 mask TID 0xf0
1080 mask OID 0x0f
1081 }
1082 SCB_LUN {
1083 field SCB_XFERLEN_ODD 0x80
1084 mask LID 0x3f
1085 size 1
1086 }
1087 SCB_TAG {
1088 size 1
1089 }
1090 SCB_CDB_LEN {
1091 size 1
1092 }
1093 SCB_SCSIRATE {
1094 size 1
1095 }
1096 SCB_SCSIOFFSET {
1097 size 1
1098 }
1099 SCB_NEXT {
1100 size 1
1101 }
1102 SCB_64_SPARE {
1103 size 16
1104 }
1105 SCB_64_BTT {
1106 size 16
1107 }
1108}
1109
1110const SCB_UPLOAD_SIZE 32
1111const SCB_DOWNLOAD_SIZE 32
1112const SCB_DOWNLOAD_SIZE_64 48
1113
1114const SG_SIZEOF 0x08 /* sizeof(struct ahc_dma) */
1115
1116/* --------------------- AHA-2840-only definitions -------------------- */
1117
1118register SEECTL_2840 {
1119 address 0x0c0
1120 access_mode RW
1121 field CS_2840 0x04
1122 field CK_2840 0x02
1123 field DO_2840 0x01
1124}
1125
1126register STATUS_2840 {
1127 address 0x0c1
1128 access_mode RW
1129 field EEPROM_TF 0x80
1130 mask BIOS_SEL 0x60
1131 mask ADSEL 0x1e
1132 field DI_2840 0x01
1133}
1134
1135/* --------------------- AIC-7870-only definitions -------------------- */
1136
1137register CCHADDR {
1138 address 0x0E0
1139 size 8
1140}
1141
1142register CCHCNT {
1143 address 0x0E8
1144}
1145
1146register CCSGRAM {
1147 address 0x0E9
1148}
1149
1150register CCSGADDR {
1151 address 0x0EA
1152}
1153
1154register CCSGCTL {
1155 address 0x0EB
1156 field CCSGDONE 0x80
1157 field CCSGEN 0x08
1158 field SG_FETCH_NEEDED 0x02 /* Bit used for software state */
1159 field CCSGRESET 0x01
1160}
1161
1162register CCSCBCNT {
1163 address 0xEF
1164}
1165
1166register CCSCBCTL {
1167 address 0x0EE
1168 field CCSCBDONE 0x80
1169 field ARRDONE 0x40 /* SCB Array prefetch done */
1170 field CCARREN 0x10
1171 field CCSCBEN 0x08
1172 field CCSCBDIR 0x04
1173 field CCSCBRESET 0x01
1174}
1175
1176register CCSCBADDR {
1177 address 0x0ED
1178}
1179
1180register CCSCBRAM {
1181 address 0xEC
1182}
1183
1184/*
1185 * SCB bank address (7895/7896/97 only)
1186 */
1187register SCBBADDR {
1188 address 0x0F0
1189 access_mode RW
1190}
1191
1192register CCSCBPTR {
1193 address 0x0F1
1194}
1195
1196register HNSCB_QOFF {
1197 address 0x0F4
1198}
1199
1200register SNSCB_QOFF {
1201 address 0x0F6
1202}
1203
1204register SDSCB_QOFF {
1205 address 0x0F8
1206}
1207
1208register QOFF_CTLSTA {
1209 address 0x0FA
1210 field SCB_AVAIL 0x40
1211 field SNSCB_ROLLOVER 0x20
1212 field SDSCB_ROLLOVER 0x10
1213 mask SCB_QSIZE 0x07
1214 mask SCB_QSIZE_256 0x06
1215}
1216
1217register DFF_THRSH {
1218 address 0x0FB
1219 mask WR_DFTHRSH 0x70
1220 mask RD_DFTHRSH 0x07
1221 mask RD_DFTHRSH_MIN 0x00
1222 mask RD_DFTHRSH_25 0x01
1223 mask RD_DFTHRSH_50 0x02
1224 mask RD_DFTHRSH_63 0x03
1225 mask RD_DFTHRSH_75 0x04
1226 mask RD_DFTHRSH_85 0x05
1227 mask RD_DFTHRSH_90 0x06
1228 mask RD_DFTHRSH_MAX 0x07
1229 mask WR_DFTHRSH_MIN 0x00
1230 mask WR_DFTHRSH_25 0x10
1231 mask WR_DFTHRSH_50 0x20
1232 mask WR_DFTHRSH_63 0x30
1233 mask WR_DFTHRSH_75 0x40
1234 mask WR_DFTHRSH_85 0x50
1235 mask WR_DFTHRSH_90 0x60
1236 mask WR_DFTHRSH_MAX 0x70
1237}
1238
1239register SG_CACHE_PRE {
1240 access_mode WO
1241 address 0x0fc
1242 mask SG_ADDR_MASK 0xf8
1243 field LAST_SEG 0x02
1244 field LAST_SEG_DONE 0x01
1245}
1246
1247register SG_CACHE_SHADOW {
1248 access_mode RO
1249 address 0x0fc
1250 mask SG_ADDR_MASK 0xf8
1251 field LAST_SEG 0x02
1252 field LAST_SEG_DONE 0x01
1253}
1254/* ---------------------- Scratch RAM Offsets ------------------------- */
1255/* These offsets are either to values that are initialized by the board's
1256 * BIOS or are specified by the sequencer code.
1257 *
1258 * The host adapter card (at least the BIOS) uses 20-2f for SCSI
1259 * device information, 32-33 and 5a-5f as well. As it turns out, the
1260 * BIOS trashes 20-2f, writing the synchronous negotiation results
1261 * on top of the BIOS values, so we re-use those for our per-target
1262 * scratchspace (actually a value that can be copied directly into
1263 * SCSIRATE). The kernel driver will enable synchronous negotiation
1264 * for all targets that have a value other than 0 in the lower four
1265 * bits of the target scratch space. This should work regardless of
1266 * whether the bios has been installed.
1267 */
1268
1269scratch_ram {
1270 address 0x020
1271 size 58
1272
1273 /*
1274 * 1 byte per target starting at this address for configuration values
1275 */
1276 BUSY_TARGETS {
1277 alias TARG_SCSIRATE
1278 size 16
1279 }
1280 /*
1281 * Bit vector of targets that have ULTRA enabled as set by
1282 * the BIOS. The Sequencer relies on a per-SCB field to
1283 * control whether to enable Ultra transfers or not. During
1284 * initialization, we read this field and reuse it for 2
1285 * entries in the busy target table.
1286 */
1287 ULTRA_ENB {
1288 alias CMDSIZE_TABLE
1289 size 2
1290 }
1291 /*
1292 * Bit vector of targets that have disconnection disabled as set by
1293 * the BIOS. The Sequencer relies in a per-SCB field to control the
1294 * disconnect priveldge. During initialization, we read this field
1295 * and reuse it for 2 entries in the busy target table.
1296 */
1297 DISC_DSB {
1298 size 2
1299 }
1300 CMDSIZE_TABLE_TAIL {
1301 size 4
1302 }
1303 /*
1304 * Partial transfer past cacheline end to be
1305 * transferred using an extra S/G.
1306 */
1307 MWI_RESIDUAL {
1308 size 1
1309 alias TARG_IMMEDIATE_SCB
1310 }
1311 /*
1312 * SCBID of the next SCB to be started by the controller.
1313 */
1314 NEXT_QUEUED_SCB {
1315 size 1
1316 }
1317 /*
1318 * Single byte buffer used to designate the type or message
1319 * to send to a target.
1320 */
1321 MSG_OUT {
1322 size 1
1323 }
1324 /* Parameters for DMA Logic */
1325 DMAPARAMS {
1326 size 1
1327 field PRELOADEN 0x80
1328 field WIDEODD 0x40
1329 field SCSIEN 0x20
1330 field SDMAEN 0x10
1331 field SDMAENACK 0x10
1332 field HDMAEN 0x08
1333 field HDMAENACK 0x08
1334 field DIRECTION 0x04 /* Set indicates PCI->SCSI */
1335 field FIFOFLUSH 0x02
1336 field FIFORESET 0x01
1337 }
1338 SEQ_FLAGS {
1339 size 1
1340 field NOT_IDENTIFIED 0x80
1341 field NO_CDB_SENT 0x40
1342 field TARGET_CMD_IS_TAGGED 0x40
1343 field DPHASE 0x20
1344 /* Target flags */
1345 field TARG_CMD_PENDING 0x10
1346 field CMDPHASE_PENDING 0x08
1347 field DPHASE_PENDING 0x04
1348 field SPHASE_PENDING 0x02
1349 field NO_DISCONNECT 0x01
1350 }
1351 /*
1352 * Temporary storage for the
1353 * target/channel/lun of a
1354 * reconnecting target
1355 */
1356 SAVED_SCSIID {
1357 size 1
1358 }
1359 SAVED_LUN {
1360 size 1
1361 }
1362 /*
1363 * The last bus phase as seen by the sequencer.
1364 */
1365 LASTPHASE {
1366 size 1
1367 field CDI 0x80
1368 field IOI 0x40
1369 field MSGI 0x20
1370 mask PHASE_MASK CDI|IOI|MSGI
1371 mask P_DATAOUT 0x00
1372 mask P_DATAIN IOI
1373 mask P_COMMAND CDI
1374 mask P_MESGOUT CDI|MSGI
1375 mask P_STATUS CDI|IOI
1376 mask P_MESGIN CDI|IOI|MSGI
1377 mask P_BUSFREE 0x01
1378 }
1379 /*
1380 * head of list of SCBs awaiting
1381 * selection
1382 */
1383 WAITING_SCBH {
1384 size 1
1385 }
1386 /*
1387 * head of list of SCBs that are
1388 * disconnected. Used for SCB
1389 * paging.
1390 */
1391 DISCONNECTED_SCBH {
1392 size 1
1393 }
1394 /*
1395 * head of list of SCBs that are
1396 * not in use. Used for SCB paging.
1397 */
1398 FREE_SCBH {
1399 size 1
1400 }
1401 /*
1402 * head of list of SCBs that have
1403 * completed but have not been
1404 * put into the qoutfifo.
1405 */
1406 COMPLETE_SCBH {
1407 size 1
1408 }
1409 /*
1410 * Address of the hardware scb array in the host.
1411 */
1412 HSCB_ADDR {
1413 size 4
1414 }
1415 /*
1416 * Base address of our shared data with the kernel driver in host
1417 * memory. This includes the qoutfifo and target mode
1418 * incoming command queue.
1419 */
1420 SHARED_DATA_ADDR {
1421 size 4
1422 }
1423 KERNEL_QINPOS {
1424 size 1
1425 }
1426 QINPOS {
1427 size 1
1428 }
1429 QOUTPOS {
1430 size 1
1431 }
1432 /*
1433 * Kernel and sequencer offsets into the queue of
1434 * incoming target mode command descriptors. The
1435 * queue is full when the KERNEL_TQINPOS == TQINPOS.
1436 */
1437 KERNEL_TQINPOS {
1438 size 1
1439 }
1440 TQINPOS {
1441 size 1
1442 }
1443 ARG_1 {
1444 size 1
1445 mask SEND_MSG 0x80
1446 mask SEND_SENSE 0x40
1447 mask SEND_REJ 0x20
1448 mask MSGOUT_PHASEMIS 0x10
1449 mask EXIT_MSG_LOOP 0x08
1450 mask CONT_MSG_LOOP 0x04
1451 mask CONT_TARG_SESSION 0x02
1452 alias RETURN_1
1453 }
1454 ARG_2 {
1455 size 1
1456 alias RETURN_2
1457 }
1458
1459 /*
1460 * Snapshot of MSG_OUT taken after each message is sent.
1461 */
1462 LAST_MSG {
1463 size 1
1464 }
1465
1466 /*
1467 * Sequences the kernel driver has okayed for us. This allows
1468 * the driver to do things like prevent initiator or target
1469 * operations.
1470 */
1471 SCSISEQ_TEMPLATE {
1472 size 1
1473 field ENSELO 0x40
1474 field ENSELI 0x20
1475 field ENRSELI 0x10
1476 field ENAUTOATNO 0x08
1477 field ENAUTOATNI 0x04
1478 field ENAUTOATNP 0x02
1479 }
1480}
1481
1482scratch_ram {
1483 address 0x056
1484 size 4
1485 /*
1486 * These scratch ram locations are initialized by the 274X BIOS.
1487 * We reuse them after capturing the BIOS settings during
1488 * initialization.
1489 */
1490
1491 /*
1492 * The initiator specified tag for this target mode transaction.
1493 */
1494 HA_274_BIOSGLOBAL {
1495 size 1
1496 field HA_274_EXTENDED_TRANS 0x01
1497 alias INITIATOR_TAG
1498 }
1499
1500 SEQ_FLAGS2 {
1501 size 1
1502 field SCB_DMA 0x01
1503 field TARGET_MSG_PENDING 0x02
1504 }
1505}
1506
1507scratch_ram {
1508 address 0x05a
1509 size 6
1510 /*
1511 * These are reserved registers in the card's scratch ram on the 2742.
1512 * The EISA configuraiton chip is mapped here. On Rev E. of the
1513 * aic7770, the sequencer can use this area for scratch, but the
1514 * host cannot directly access these registers. On later chips, this
1515 * area can be read and written by both the host and the sequencer.
1516 * Even on later chips, many of these locations are initialized by
1517 * the BIOS.
1518 */
1519 SCSICONF {
1520 size 1
1521 field TERM_ENB 0x80
1522 field RESET_SCSI 0x40
1523 field ENSPCHK 0x20
1524 mask HSCSIID 0x07 /* our SCSI ID */
1525 mask HWSCSIID 0x0f /* our SCSI ID if Wide Bus */
1526 }
1527 INTDEF {
1528 address 0x05c
1529 size 1
1530 field EDGE_TRIG 0x80
1531 mask VECTOR 0x0f
1532 }
1533 HOSTCONF {
1534 address 0x05d
1535 size 1
1536 }
1537 HA_274_BIOSCTRL {
1538 address 0x05f
1539 size 1
1540 mask BIOSMODE 0x30
1541 mask BIOSDISABLED 0x30
1542 field CHANNEL_B_PRIMARY 0x08
1543 }
1544}
1545
1546scratch_ram {
1547 address 0x070
1548 size 16
1549
1550 /*
1551 * Per target SCSI offset values for Ultra2 controllers.
1552 */
1553 TARG_OFFSET {
1554 size 16
1555 }
1556}
1557
1558const TID_SHIFT 4
1559const SCB_LIST_NULL 0xff
1560const TARGET_CMD_CMPLT 0xfe
1561
1562const CCSGADDR_MAX 0x80
1563const CCSGRAM_MAXSEGS 16
1564
1565/* WDTR Message values */
1566const BUS_8_BIT 0x00
1567const BUS_16_BIT 0x01
1568const BUS_32_BIT 0x02
1569
1570/* Offset maximums */
1571const MAX_OFFSET_8BIT 0x0f
1572const MAX_OFFSET_16BIT 0x08
1573const MAX_OFFSET_ULTRA2 0x7f
1574const MAX_OFFSET 0x7f
1575const HOST_MSG 0xff
1576
1577/* Target mode command processing constants */
1578const CMD_GROUP_CODE_SHIFT 0x05
1579
1580const STATUS_BUSY 0x08
1581const STATUS_QUEUE_FULL 0x28
1582const TARGET_DATA_IN 1
1583
1584/*
1585 * Downloaded (kernel inserted) constants
1586 */
1587/* Offsets into the SCBID array where different data is stored */
1588const QOUTFIFO_OFFSET download
1589const QINFIFO_OFFSET download
1590const CACHESIZE_MASK download
1591const INVERTED_CACHESIZE_MASK download
1592const SG_PREFETCH_CNT download
1593const SG_PREFETCH_ALIGN_MASK download
1594const SG_PREFETCH_ADDR_MASK download
diff --git a/drivers/scsi/aic7xxx/aic7xxx.seq b/drivers/scsi/aic7xxx/aic7xxx.seq
new file mode 100644
index 000000000000..d84b741fbab5
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx.seq
@@ -0,0 +1,2398 @@
1/*
2 * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD.
3 *
4 * Copyright (c) 1994-2001 Justin T. Gibbs.
5 * Copyright (c) 2000-2001 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $FreeBSD$
41 */
42
43VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $"
44PATCH_ARG_LIST = "struct ahc_softc *ahc"
45PREFIX = "ahc_"
46
47#include "aic7xxx.reg"
48#include "scsi_message.h"
49
50/*
51 * A few words on the waiting SCB list:
52 * After starting the selection hardware, we check for reconnecting targets
53 * as well as for our selection to complete just in case the reselection wins
54 * bus arbitration. The problem with this is that we must keep track of the
55 * SCB that we've already pulled from the QINFIFO and started the selection
56 * on just in case the reselection wins so that we can retry the selection at
57 * a later time. This problem cannot be resolved by holding a single entry
58 * in scratch ram since a reconnecting target can request sense and this will
59 * create yet another SCB waiting for selection. The solution used here is to
60 * use byte 27 of the SCB as a psuedo-next pointer and to thread a list
61 * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes,
62 * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to
63 * this list everytime a request sense occurs or after completing a non-tagged
64 * command for which a second SCB has been queued. The sequencer will
65 * automatically consume the entries.
66 */
67
68bus_free_sel:
69 /*
70 * Turn off the selection hardware. We need to reset the
71 * selection request in order to perform a new selection.
72 */
73 and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP;
74 and SIMODE1, ~ENBUSFREE;
75poll_for_work:
76 call clear_target_state;
77 and SXFRCTL0, ~SPIOEN;
78 if ((ahc->features & AHC_ULTRA2) != 0) {
79 clr SCSIBUSL;
80 }
81 test SCSISEQ, ENSELO jnz poll_for_selection;
82 if ((ahc->features & AHC_TWIN) != 0) {
83 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */
84 test SCSISEQ, ENSELO jnz poll_for_selection;
85 }
86 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting;
87poll_for_work_loop:
88 if ((ahc->features & AHC_TWIN) != 0) {
89 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */
90 }
91 test SSTAT0, SELDO|SELDI jnz selection;
92test_queue:
93 /* Has the driver posted any work for us? */
94BEGIN_CRITICAL;
95 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
96 test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop;
97 } else {
98 mov A, QINPOS;
99 cmp KERNEL_QINPOS, A je poll_for_work_loop;
100 }
101 mov ARG_1, NEXT_QUEUED_SCB;
102
103 /*
104 * We have at least one queued SCB now and we don't have any
105 * SCBs in the list of SCBs awaiting selection. Allocate a
106 * card SCB for the host's SCB and get to work on it.
107 */
108 if ((ahc->flags & AHC_PAGESCBS) != 0) {
109 mov ALLZEROS call get_free_or_disc_scb;
110 } else {
111 /* In the non-paging case, the SCBID == hardware SCB index */
112 mov SCBPTR, ARG_1;
113 }
114 or SEQ_FLAGS2, SCB_DMA;
115END_CRITICAL;
116dma_queued_scb:
117 /*
118 * DMA the SCB from host ram into the current SCB location.
119 */
120 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
121 mov ARG_1 call dma_scb;
122 /*
123 * Check one last time to see if this SCB was canceled
124 * before we completed the DMA operation. If it was,
125 * the QINFIFO next pointer will not match our saved
126 * value.
127 */
128 mov A, ARG_1;
129BEGIN_CRITICAL;
130 cmp NEXT_QUEUED_SCB, A jne abort_qinscb;
131 if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
132 cmp SCB_TAG, A je . + 2;
133 mvi SCB_MISMATCH call set_seqint;
134 }
135 mov NEXT_QUEUED_SCB, SCB_NEXT;
136 mov SCB_NEXT,WAITING_SCBH;
137 mov WAITING_SCBH, SCBPTR;
138 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
139 mov NONE, SNSCB_QOFF;
140 } else {
141 inc QINPOS;
142 }
143 and SEQ_FLAGS2, ~SCB_DMA;
144END_CRITICAL;
145start_waiting:
146 /*
147 * Start the first entry on the waiting SCB list.
148 */
149 mov SCBPTR, WAITING_SCBH;
150 call start_selection;
151
152poll_for_selection:
153 /*
154 * Twin channel devices cannot handle things like SELTO
155 * interrupts on the "background" channel. So, while
156 * selecting, keep polling the current channel until
157 * either a selection or reselection occurs.
158 */
159 test SSTAT0, SELDO|SELDI jz poll_for_selection;
160
161selection:
162 /*
163 * We aren't expecting a bus free, so interrupt
164 * the kernel driver if it happens.
165 */
166 mvi CLRSINT1,CLRBUSFREE;
167 if ((ahc->features & AHC_DT) == 0) {
168 or SIMODE1, ENBUSFREE;
169 }
170
171 /*
172 * Guard against a bus free after (re)selection
173 * but prior to enabling the busfree interrupt. SELDI
174 * and SELDO will be cleared in that case.
175 */
176 test SSTAT0, SELDI|SELDO jz bus_free_sel;
177 test SSTAT0,SELDO jnz select_out;
178select_in:
179 if ((ahc->flags & AHC_TARGETROLE) != 0) {
180 if ((ahc->flags & AHC_INITIATORROLE) != 0) {
181 test SSTAT0, TARGET jz initiator_reselect;
182 }
183 mvi CLRSINT0, CLRSELDI;
184
185 /*
186 * We've just been selected. Assert BSY and
187 * setup the phase for receiving messages
188 * from the target.
189 */
190 mvi SCSISIGO, P_MESGOUT|BSYO;
191
192 /*
193 * Setup the DMA for sending the identify and
194 * command information.
195 */
196 mvi SEQ_FLAGS, CMDPHASE_PENDING;
197
198 mov A, TQINPOS;
199 if ((ahc->features & AHC_CMD_CHAN) != 0) {
200 mvi DINDEX, CCHADDR;
201 mvi SHARED_DATA_ADDR call set_32byte_addr;
202 mvi CCSCBCTL, CCSCBRESET;
203 } else {
204 mvi DINDEX, HADDR;
205 mvi SHARED_DATA_ADDR call set_32byte_addr;
206 mvi DFCNTRL, FIFORESET;
207 }
208
209 /* Initiator that selected us */
210 and SAVED_SCSIID, SELID_MASK, SELID;
211 /* The Target ID we were selected at */
212 if ((ahc->features & AHC_MULTI_TID) != 0) {
213 and A, OID, TARGIDIN;
214 } else if ((ahc->features & AHC_ULTRA2) != 0) {
215 and A, OID, SCSIID_ULTRA2;
216 } else {
217 and A, OID, SCSIID;
218 }
219 or SAVED_SCSIID, A;
220 if ((ahc->features & AHC_TWIN) != 0) {
221 test SBLKCTL, SELBUSB jz . + 2;
222 or SAVED_SCSIID, TWIN_CHNLB;
223 }
224 if ((ahc->features & AHC_CMD_CHAN) != 0) {
225 mov CCSCBRAM, SAVED_SCSIID;
226 } else {
227 mov DFDAT, SAVED_SCSIID;
228 }
229
230 /*
231 * If ATN isn't asserted, the target isn't interested
232 * in talking to us. Go directly to bus free.
233 * XXX SCSI-1 may require us to assume lun 0 if
234 * ATN is false.
235 */
236 test SCSISIGI, ATNI jz target_busfree;
237
238 /*
239 * Watch ATN closely now as we pull in messages from the
240 * initiator. We follow the guidlines from section 6.5
241 * of the SCSI-2 spec for what messages are allowed when.
242 */
243 call target_inb;
244
245 /*
246 * Our first message must be one of IDENTIFY, ABORT, or
247 * BUS_DEVICE_RESET.
248 */
249 test DINDEX, MSG_IDENTIFYFLAG jz host_target_message_loop;
250 /* Store for host */
251 if ((ahc->features & AHC_CMD_CHAN) != 0) {
252 mov CCSCBRAM, DINDEX;
253 } else {
254 mov DFDAT, DINDEX;
255 }
256 and SAVED_LUN, MSG_IDENTIFY_LUNMASK, DINDEX;
257
258 /* Remember for disconnection decision */
259 test DINDEX, MSG_IDENTIFY_DISCFLAG jnz . + 2;
260 /* XXX Honor per target settings too */
261 or SEQ_FLAGS, NO_DISCONNECT;
262
263 test SCSISIGI, ATNI jz ident_messages_done;
264 call target_inb;
265 /*
266 * If this is a tagged request, the tagged message must
267 * immediately follow the identify. We test for a valid
268 * tag message by seeing if it is >= MSG_SIMPLE_Q_TAG and
269 * < MSG_IGN_WIDE_RESIDUE.
270 */
271 add A, -MSG_SIMPLE_Q_TAG, DINDEX;
272 jnc ident_messages_done_msg_pending;
273 add A, -MSG_IGN_WIDE_RESIDUE, DINDEX;
274 jc ident_messages_done_msg_pending;
275
276 /* Store for host */
277 if ((ahc->features & AHC_CMD_CHAN) != 0) {
278 mov CCSCBRAM, DINDEX;
279 } else {
280 mov DFDAT, DINDEX;
281 }
282
283 /*
284 * If the initiator doesn't feel like providing a tag number,
285 * we've got a failed selection and must transition to bus
286 * free.
287 */
288 test SCSISIGI, ATNI jz target_busfree;
289
290 /*
291 * Store the tag for the host.
292 */
293 call target_inb;
294 if ((ahc->features & AHC_CMD_CHAN) != 0) {
295 mov CCSCBRAM, DINDEX;
296 } else {
297 mov DFDAT, DINDEX;
298 }
299 mov INITIATOR_TAG, DINDEX;
300 or SEQ_FLAGS, TARGET_CMD_IS_TAGGED;
301
302ident_messages_done:
303 /* Terminate the ident list */
304 if ((ahc->features & AHC_CMD_CHAN) != 0) {
305 mvi CCSCBRAM, SCB_LIST_NULL;
306 } else {
307 mvi DFDAT, SCB_LIST_NULL;
308 }
309 or SEQ_FLAGS, TARG_CMD_PENDING;
310 test SEQ_FLAGS2, TARGET_MSG_PENDING
311 jnz target_mesgout_pending;
312 test SCSISIGI, ATNI jnz target_mesgout_continue;
313 jmp target_ITloop;
314
315
316ident_messages_done_msg_pending:
317 or SEQ_FLAGS2, TARGET_MSG_PENDING;
318 jmp ident_messages_done;
319
320 /*
321 * Pushed message loop to allow the kernel to
322 * run it's own target mode message state engine.
323 */
324host_target_message_loop:
325 mvi HOST_MSG_LOOP call set_seqint;
326 cmp RETURN_1, EXIT_MSG_LOOP je target_ITloop;
327 test SSTAT0, SPIORDY jz .;
328 jmp host_target_message_loop;
329 }
330
331if ((ahc->flags & AHC_INITIATORROLE) != 0) {
332/*
333 * Reselection has been initiated by a target. Make a note that we've been
334 * reselected, but haven't seen an IDENTIFY message from the target yet.
335 */
336initiator_reselect:
337 /* XXX test for and handle ONE BIT condition */
338 or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN;
339 and SAVED_SCSIID, SELID_MASK, SELID;
340 if ((ahc->features & AHC_ULTRA2) != 0) {
341 and A, OID, SCSIID_ULTRA2;
342 } else {
343 and A, OID, SCSIID;
344 }
345 or SAVED_SCSIID, A;
346 if ((ahc->features & AHC_TWIN) != 0) {
347 test SBLKCTL, SELBUSB jz . + 2;
348 or SAVED_SCSIID, TWIN_CHNLB;
349 }
350 mvi CLRSINT0, CLRSELDI;
351 jmp ITloop;
352}
353
354abort_qinscb:
355 call add_scb_to_free_list;
356 jmp poll_for_work_loop;
357
358start_selection:
359 /*
360 * If bus reset interrupts have been disabled (from a previous
361 * reset), re-enable them now. Resets are only of interest
362 * when we have outstanding transactions, so we can safely
363 * defer re-enabling the interrupt until, as an initiator,
364 * we start sending out transactions again.
365 */
366 test SIMODE1, ENSCSIRST jnz . + 3;
367 mvi CLRSINT1, CLRSCSIRSTI;
368 or SIMODE1, ENSCSIRST;
369 if ((ahc->features & AHC_TWIN) != 0) {
370 and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */
371 test SCB_SCSIID, TWIN_CHNLB jz . + 2;
372 or SINDEX, SELBUSB;
373 mov SBLKCTL,SINDEX; /* select channel */
374 }
375initialize_scsiid:
376 if ((ahc->features & AHC_ULTRA2) != 0) {
377 mov SCSIID_ULTRA2, SCB_SCSIID;
378 } else if ((ahc->features & AHC_TWIN) != 0) {
379 and SCSIID, TWIN_TID|OID, SCB_SCSIID;
380 } else {
381 mov SCSIID, SCB_SCSIID;
382 }
383 if ((ahc->flags & AHC_TARGETROLE) != 0) {
384 mov SINDEX, SCSISEQ_TEMPLATE;
385 test SCB_CONTROL, TARGET_SCB jz . + 2;
386 or SINDEX, TEMODE;
387 mov SCSISEQ, SINDEX ret;
388 } else {
389 mov SCSISEQ, SCSISEQ_TEMPLATE ret;
390 }
391
392/*
393 * Initialize transfer settings with SCB provided settings.
394 */
395set_transfer_settings:
396 if ((ahc->features & AHC_ULTRA) != 0) {
397 test SCB_CONTROL, ULTRAENB jz . + 2;
398 or SXFRCTL0, FAST20;
399 }
400 /*
401 * Initialize SCSIRATE with the appropriate value for this target.
402 */
403 if ((ahc->features & AHC_ULTRA2) != 0) {
404 bmov SCSIRATE, SCB_SCSIRATE, 2 ret;
405 } else {
406 mov SCSIRATE, SCB_SCSIRATE ret;
407 }
408
409if ((ahc->flags & AHC_TARGETROLE) != 0) {
410/*
411 * We carefully toggle SPIOEN to allow us to return the
412 * message byte we receive so it can be checked prior to
413 * driving REQ on the bus for the next byte.
414 */
415target_inb:
416 /*
417 * Drive REQ on the bus by enabling SCSI PIO.
418 */
419 or SXFRCTL0, SPIOEN;
420 /* Wait for the byte */
421 test SSTAT0, SPIORDY jz .;
422 /* Prevent our read from triggering another REQ */
423 and SXFRCTL0, ~SPIOEN;
424 /* Save latched contents */
425 mov DINDEX, SCSIDATL ret;
426}
427
428/*
429 * After the selection, remove this SCB from the "waiting SCB"
430 * list. This is achieved by simply moving our "next" pointer into
431 * WAITING_SCBH. Our next pointer will be set to null the next time this
432 * SCB is used, so don't bother with it now.
433 */
434select_out:
435 /* Turn off the selection hardware */
436 and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ;
437 mov SCBPTR, WAITING_SCBH;
438 mov WAITING_SCBH,SCB_NEXT;
439 mov SAVED_SCSIID, SCB_SCSIID;
440 and SAVED_LUN, LID, SCB_LUN;
441 call set_transfer_settings;
442 if ((ahc->flags & AHC_TARGETROLE) != 0) {
443 test SSTAT0, TARGET jz initiator_select;
444
445 or SXFRCTL0, CLRSTCNT|CLRCHN;
446
447 /*
448 * Put tag in connonical location since not
449 * all connections have an SCB.
450 */
451 mov INITIATOR_TAG, SCB_TARGET_ITAG;
452
453 /*
454 * We've just re-selected an initiator.
455 * Assert BSY and setup the phase for
456 * sending our identify messages.
457 */
458 mvi P_MESGIN|BSYO call change_phase;
459 mvi CLRSINT0, CLRSELDO;
460
461 /*
462 * Start out with a simple identify message.
463 */
464 or SAVED_LUN, MSG_IDENTIFYFLAG call target_outb;
465
466 /*
467 * If we are the result of a tagged command, send
468 * a simple Q tag and the tag id.
469 */
470 test SCB_CONTROL, TAG_ENB jz . + 3;
471 mvi MSG_SIMPLE_Q_TAG call target_outb;
472 mov SCB_TARGET_ITAG call target_outb;
473target_synccmd:
474 /*
475 * Now determine what phases the host wants us
476 * to go through.
477 */
478 mov SEQ_FLAGS, SCB_TARGET_PHASES;
479
480 test SCB_CONTROL, MK_MESSAGE jz target_ITloop;
481 mvi P_MESGIN|BSYO call change_phase;
482 jmp host_target_message_loop;
483target_ITloop:
484 /*
485 * Start honoring ATN signals now that
486 * we properly identified ourselves.
487 */
488 test SCSISIGI, ATNI jnz target_mesgout;
489 test SEQ_FLAGS, CMDPHASE_PENDING jnz target_cmdphase;
490 test SEQ_FLAGS, DPHASE_PENDING jnz target_dphase;
491 test SEQ_FLAGS, SPHASE_PENDING jnz target_sphase;
492
493 /*
494 * No more work to do. Either disconnect or not depending
495 * on the state of NO_DISCONNECT.
496 */
497 test SEQ_FLAGS, NO_DISCONNECT jz target_disconnect;
498 mvi TARG_IMMEDIATE_SCB, SCB_LIST_NULL;
499 call complete_target_cmd;
500 if ((ahc->flags & AHC_PAGESCBS) != 0) {
501 mov ALLZEROS call get_free_or_disc_scb;
502 }
503 cmp TARG_IMMEDIATE_SCB, SCB_LIST_NULL je .;
504 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
505 mov TARG_IMMEDIATE_SCB call dma_scb;
506 call set_transfer_settings;
507 or SXFRCTL0, CLRSTCNT|CLRCHN;
508 jmp target_synccmd;
509
510target_mesgout:
511 mvi SCSISIGO, P_MESGOUT|BSYO;
512target_mesgout_continue:
513 call target_inb;
514target_mesgout_pending:
515 and SEQ_FLAGS2, ~TARGET_MSG_PENDING;
516 /* Local Processing goes here... */
517 jmp host_target_message_loop;
518
519target_disconnect:
520 mvi P_MESGIN|BSYO call change_phase;
521 test SEQ_FLAGS, DPHASE jz . + 2;
522 mvi MSG_SAVEDATAPOINTER call target_outb;
523 mvi MSG_DISCONNECT call target_outb;
524
525target_busfree_wait:
526 /* Wait for preceding I/O session to complete. */
527 test SCSISIGI, ACKI jnz .;
528target_busfree:
529 and SIMODE1, ~ENBUSFREE;
530 if ((ahc->features & AHC_ULTRA2) != 0) {
531 clr SCSIBUSL;
532 }
533 clr SCSISIGO;
534 mvi LASTPHASE, P_BUSFREE;
535 call complete_target_cmd;
536 jmp poll_for_work;
537
538target_cmdphase:
539 /*
540 * The target has dropped ATN (doesn't want to abort or BDR)
541 * and we believe this selection to be valid. If the ring
542 * buffer for new commands is full, return busy or queue full.
543 */
544 if ((ahc->features & AHC_HS_MAILBOX) != 0) {
545 and A, HOST_TQINPOS, HS_MAILBOX;
546 } else {
547 mov A, KERNEL_TQINPOS;
548 }
549 cmp TQINPOS, A jne tqinfifo_has_space;
550 mvi P_STATUS|BSYO call change_phase;
551 test SEQ_FLAGS, TARGET_CMD_IS_TAGGED jz . + 3;
552 mvi STATUS_QUEUE_FULL call target_outb;
553 jmp target_busfree_wait;
554 mvi STATUS_BUSY call target_outb;
555 jmp target_busfree_wait;
556tqinfifo_has_space:
557 mvi P_COMMAND|BSYO call change_phase;
558 call target_inb;
559 mov A, DINDEX;
560 /* Store for host */
561 if ((ahc->features & AHC_CMD_CHAN) != 0) {
562 mov CCSCBRAM, A;
563 } else {
564 mov DFDAT, A;
565 }
566
567 /*
568 * Determine the number of bytes to read
569 * based on the command group code via table lookup.
570 * We reuse the first 8 bytes of the TARG_SCSIRATE
571 * BIOS array for this table. Count is one less than
572 * the total for the command since we've already fetched
573 * the first byte.
574 */
575 shr A, CMD_GROUP_CODE_SHIFT;
576 add SINDEX, CMDSIZE_TABLE, A;
577 mov A, SINDIR;
578
579 test A, 0xFF jz command_phase_done;
580 or SXFRCTL0, SPIOEN;
581command_loop:
582 test SSTAT0, SPIORDY jz .;
583 cmp A, 1 jne . + 2;
584 and SXFRCTL0, ~SPIOEN; /* Last Byte */
585 if ((ahc->features & AHC_CMD_CHAN) != 0) {
586 mov CCSCBRAM, SCSIDATL;
587 } else {
588 mov DFDAT, SCSIDATL;
589 }
590 dec A;
591 test A, 0xFF jnz command_loop;
592
593command_phase_done:
594 and SEQ_FLAGS, ~CMDPHASE_PENDING;
595 jmp target_ITloop;
596
597target_dphase:
598 /*
599 * Data phases on the bus are from the
600 * perspective of the initiator. The dma
601 * code looks at LASTPHASE to determine the
602 * data direction of the DMA. Toggle it for
603 * target transfers.
604 */
605 xor LASTPHASE, IOI, SCB_TARGET_DATA_DIR;
606 or SCB_TARGET_DATA_DIR, BSYO call change_phase;
607 jmp p_data;
608
609target_sphase:
610 mvi P_STATUS|BSYO call change_phase;
611 mvi LASTPHASE, P_STATUS;
612 mov SCB_SCSI_STATUS call target_outb;
613 /* XXX Watch for ATN or parity errors??? */
614 mvi SCSISIGO, P_MESGIN|BSYO;
615 /* MSG_CMDCMPLT is 0, but we can't do an immediate of 0 */
616 mov ALLZEROS call target_outb;
617 jmp target_busfree_wait;
618
619complete_target_cmd:
620 test SEQ_FLAGS, TARG_CMD_PENDING jnz . + 2;
621 mov SCB_TAG jmp complete_post;
622 if ((ahc->features & AHC_CMD_CHAN) != 0) {
623 /* Set the valid byte */
624 mvi CCSCBADDR, 24;
625 mov CCSCBRAM, ALLONES;
626 mvi CCHCNT, 28;
627 or CCSCBCTL, CCSCBEN|CCSCBRESET;
628 test CCSCBCTL, CCSCBDONE jz .;
629 clr CCSCBCTL;
630 } else {
631 /* Set the valid byte */
632 or DFCNTRL, FIFORESET;
633 mvi DFWADDR, 3; /* Third 64bit word or byte 24 */
634 mov DFDAT, ALLONES;
635 mvi 28 call set_hcnt;
636 or DFCNTRL, HDMAEN|FIFOFLUSH;
637 call dma_finish;
638 }
639 inc TQINPOS;
640 mvi INTSTAT,CMDCMPLT ret;
641 }
642
643if ((ahc->flags & AHC_INITIATORROLE) != 0) {
644initiator_select:
645 or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN;
646 /*
647 * As soon as we get a successful selection, the target
648 * should go into the message out phase since we have ATN
649 * asserted.
650 */
651 mvi MSG_OUT, MSG_IDENTIFYFLAG;
652 mvi SEQ_FLAGS, NO_CDB_SENT;
653 mvi CLRSINT0, CLRSELDO;
654
655 /*
656 * Main loop for information transfer phases. Wait for the
657 * target to assert REQ before checking MSG, C/D and I/O for
658 * the bus phase.
659 */
660mesgin_phasemis:
661ITloop:
662 call phase_lock;
663
664 mov A, LASTPHASE;
665
666 test A, ~P_DATAIN jz p_data;
667 cmp A,P_COMMAND je p_command;
668 cmp A,P_MESGOUT je p_mesgout;
669 cmp A,P_STATUS je p_status;
670 cmp A,P_MESGIN je p_mesgin;
671
672 mvi BAD_PHASE call set_seqint;
673 jmp ITloop; /* Try reading the bus again. */
674
675await_busfree:
676 and SIMODE1, ~ENBUSFREE;
677 mov NONE, SCSIDATL; /* Ack the last byte */
678 if ((ahc->features & AHC_ULTRA2) != 0) {
679 clr SCSIBUSL; /* Prevent bit leakage durint SELTO */
680 }
681 and SXFRCTL0, ~SPIOEN;
682 test SSTAT1,REQINIT|BUSFREE jz .;
683 test SSTAT1, BUSFREE jnz poll_for_work;
684 mvi MISSED_BUSFREE call set_seqint;
685}
686
687clear_target_state:
688 /*
689 * We assume that the kernel driver may reset us
690 * at any time, even in the middle of a DMA, so
691 * clear DFCNTRL too.
692 */
693 clr DFCNTRL;
694 or SXFRCTL0, CLRSTCNT|CLRCHN;
695
696 /*
697 * We don't know the target we will connect to,
698 * so default to narrow transfers to avoid
699 * parity problems.
700 */
701 if ((ahc->features & AHC_ULTRA2) != 0) {
702 bmov SCSIRATE, ALLZEROS, 2;
703 } else {
704 clr SCSIRATE;
705 if ((ahc->features & AHC_ULTRA) != 0) {
706 and SXFRCTL0, ~(FAST20);
707 }
708 }
709 mvi LASTPHASE, P_BUSFREE;
710 /* clear target specific flags */
711 mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret;
712
713sg_advance:
714 clr A; /* add sizeof(struct scatter) */
715 add SCB_RESIDUAL_SGPTR[0],SG_SIZEOF;
716 adc SCB_RESIDUAL_SGPTR[1],A;
717 adc SCB_RESIDUAL_SGPTR[2],A;
718 adc SCB_RESIDUAL_SGPTR[3],A ret;
719
720if ((ahc->features & AHC_CMD_CHAN) != 0) {
721disable_ccsgen:
722 test CCSGCTL, CCSGEN jz return;
723 test CCSGCTL, CCSGDONE jz .;
724disable_ccsgen_fetch_done:
725 clr CCSGCTL;
726 test CCSGCTL, CCSGEN jnz .;
727 ret;
728idle_loop:
729 /*
730 * Do we need any more segments for this transfer?
731 */
732 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz return;
733
734 /* Did we just finish fetching segs? */
735 cmp CCSGCTL, CCSGEN|CCSGDONE je idle_sgfetch_complete;
736
737 /* Are we actively fetching segments? */
738 test CCSGCTL, CCSGEN jnz return;
739
740 /*
741 * Do we have any prefetch left???
742 */
743 cmp CCSGADDR, SG_PREFETCH_CNT jne idle_sg_avail;
744
745 /*
746 * Need to fetch segments, but we can only do that
747 * if the command channel is completely idle. Make
748 * sure we don't have an SCB prefetch going on.
749 */
750 test CCSCBCTL, CCSCBEN jnz return;
751
752 /*
753 * We fetch a "cacheline aligned" and sized amount of data
754 * so we don't end up referencing a non-existant page.
755 * Cacheline aligned is in quotes because the kernel will
756 * set the prefetch amount to a reasonable level if the
757 * cacheline size is unknown.
758 */
759 mvi CCHCNT, SG_PREFETCH_CNT;
760 and CCHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR;
761 bmov CCHADDR[1], SCB_RESIDUAL_SGPTR[1], 3;
762 mvi CCSGCTL, CCSGEN|CCSGRESET ret;
763idle_sgfetch_complete:
764 call disable_ccsgen_fetch_done;
765 and CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR;
766idle_sg_avail:
767 if ((ahc->features & AHC_ULTRA2) != 0) {
768 /* Does the hardware have space for another SG entry? */
769 test DFSTATUS, PRELOAD_AVAIL jz return;
770 bmov HADDR, CCSGRAM, 7;
771 bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
772 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
773 mov SCB_RESIDUAL_DATACNT[3] call set_hhaddr;
774 }
775 call sg_advance;
776 mov SINDEX, SCB_RESIDUAL_SGPTR[0];
777 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2;
778 or SINDEX, LAST_SEG;
779 mov SG_CACHE_PRE, SINDEX;
780 /* Load the segment */
781 or DFCNTRL, PRELOADEN;
782 }
783 ret;
784}
785
786if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0) {
787/*
788 * Calculate the trailing portion of this S/G segment that cannot
789 * be transferred using memory write and invalidate PCI transactions.
790 * XXX Can we optimize this for PCI writes only???
791 */
792calc_mwi_residual:
793 /*
794 * If the ending address is on a cacheline boundary,
795 * there is no need for an extra segment.
796 */
797 mov A, HCNT[0];
798 add A, A, HADDR[0];
799 and A, CACHESIZE_MASK;
800 test A, 0xFF jz return;
801
802 /*
803 * If the transfer is less than a cachline,
804 * there is no need for an extra segment.
805 */
806 test HCNT[1], 0xFF jnz calc_mwi_residual_final;
807 test HCNT[2], 0xFF jnz calc_mwi_residual_final;
808 add NONE, INVERTED_CACHESIZE_MASK, HCNT[0];
809 jnc return;
810
811calc_mwi_residual_final:
812 mov MWI_RESIDUAL, A;
813 not A;
814 inc A;
815 add HCNT[0], A;
816 adc HCNT[1], -1;
817 adc HCNT[2], -1 ret;
818}
819
820p_data:
821 test SEQ_FLAGS,NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed;
822 mvi PROTO_VIOLATION call set_seqint;
823p_data_allowed:
824 if ((ahc->features & AHC_ULTRA2) != 0) {
825 mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN;
826 } else {
827 mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET;
828 }
829 test LASTPHASE, IOI jnz . + 2;
830 or DMAPARAMS, DIRECTION;
831 if ((ahc->features & AHC_CMD_CHAN) != 0) {
832 /* We don't have any valid S/G elements */
833 mvi CCSGADDR, SG_PREFETCH_CNT;
834 }
835 test SEQ_FLAGS, DPHASE jz data_phase_initialize;
836
837 /*
838 * If we re-enter the data phase after going through another
839 * phase, our transfer location has almost certainly been
840 * corrupted by the interveining, non-data, transfers. Ask
841 * the host driver to fix us up based on the transfer residual.
842 */
843 mvi PDATA_REINIT call set_seqint;
844 jmp data_phase_loop;
845
846data_phase_initialize:
847 /* We have seen a data phase for the first time */
848 or SEQ_FLAGS, DPHASE;
849
850 /*
851 * Initialize the DMA address and counter from the SCB.
852 * Also set SCB_RESIDUAL_SGPTR, including the LAST_SEG
853 * flag in the highest byte of the data count. We cannot
854 * modify the saved values in the SCB until we see a save
855 * data pointers message.
856 */
857 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
858 /* The lowest address byte must be loaded last. */
859 mov SCB_DATACNT[3] call set_hhaddr;
860 }
861 if ((ahc->features & AHC_CMD_CHAN) != 0) {
862 bmov HADDR, SCB_DATAPTR, 7;
863 bmov SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5;
864 } else {
865 mvi DINDEX, HADDR;
866 mvi SCB_DATAPTR call bcopy_7;
867 mvi DINDEX, SCB_RESIDUAL_DATACNT + 3;
868 mvi SCB_DATACNT + 3 call bcopy_5;
869 }
870 if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0) {
871 call calc_mwi_residual;
872 }
873 and SCB_RESIDUAL_SGPTR[0], ~SG_FULL_RESID;
874
875 if ((ahc->features & AHC_ULTRA2) == 0) {
876 if ((ahc->features & AHC_CMD_CHAN) != 0) {
877 bmov STCNT, HCNT, 3;
878 } else {
879 call set_stcnt_from_hcnt;
880 }
881 }
882
883data_phase_loop:
884 /* Guard against overruns */
885 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_inbounds;
886
887 /*
888 * Turn on `Bit Bucket' mode, wait until the target takes
889 * us to another phase, and then notify the host.
890 */
891 and DMAPARAMS, DIRECTION;
892 mov DFCNTRL, DMAPARAMS;
893 or SXFRCTL1,BITBUCKET;
894 if ((ahc->features & AHC_DT) == 0) {
895 test SSTAT1,PHASEMIS jz .;
896 } else {
897 test SCSIPHASE, DATA_PHASE_MASK jnz .;
898 }
899 and SXFRCTL1, ~BITBUCKET;
900 mvi DATA_OVERRUN call set_seqint;
901 jmp ITloop;
902
903data_phase_inbounds:
904 if ((ahc->features & AHC_ULTRA2) != 0) {
905 mov SINDEX, SCB_RESIDUAL_SGPTR[0];
906 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2;
907 or SINDEX, LAST_SEG;
908 mov SG_CACHE_PRE, SINDEX;
909 mov DFCNTRL, DMAPARAMS;
910ultra2_dma_loop:
911 call idle_loop;
912 /*
913 * The transfer is complete if either the last segment
914 * completes or the target changes phase.
915 */
916 test SG_CACHE_SHADOW, LAST_SEG_DONE jnz ultra2_dmafinish;
917 if ((ahc->features & AHC_DT) == 0) {
918 if ((ahc->flags & AHC_TARGETROLE) != 0) {
919 /*
920 * As a target, we control the phases,
921 * so ignore PHASEMIS.
922 */
923 test SSTAT0, TARGET jnz ultra2_dma_loop;
924 }
925 if ((ahc->flags & AHC_INITIATORROLE) != 0) {
926 test SSTAT1,PHASEMIS jz ultra2_dma_loop;
927 }
928 } else {
929 test DFCNTRL, SCSIEN jnz ultra2_dma_loop;
930 }
931
932ultra2_dmafinish:
933 /*
934 * The transfer has terminated either due to a phase
935 * change, and/or the completion of the last segment.
936 * We have two goals here. Do as much other work
937 * as possible while the data fifo drains on a read
938 * and respond as quickly as possible to the standard
939 * messages (save data pointers/disconnect and command
940 * complete) that usually follow a data phase.
941 */
942 if ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0) {
943 /*
944 * On chips with broken auto-flush, start
945 * the flushing process now. We'll poke
946 * the chip from time to time to keep the
947 * flush process going as we complete the
948 * data phase.
949 */
950 or DFCNTRL, FIFOFLUSH;
951 }
952 /*
953 * We assume that, even though data may still be
954 * transferring to the host, that the SCSI side of
955 * the DMA engine is now in a static state. This
956 * allows us to update our notion of where we are
957 * in this transfer.
958 *
959 * If, by chance, we stopped before being able
960 * to fetch additional segments for this transfer,
961 * yet the last S/G was completely exhausted,
962 * call our idle loop until it is able to load
963 * another segment. This will allow us to immediately
964 * pickup on the next segment on the next data phase.
965 *
966 * If we happened to stop on the last segment, then
967 * our residual information is still correct from
968 * the idle loop and there is no need to perform
969 * any fixups.
970 */
971ultra2_ensure_sg:
972 test SG_CACHE_SHADOW, LAST_SEG jz ultra2_shvalid;
973 /* Record if we've consumed all S/G entries */
974 test SSTAT2, SHVALID jnz residuals_correct;
975 or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL;
976 jmp residuals_correct;
977
978ultra2_shvalid:
979 test SSTAT2, SHVALID jnz sgptr_fixup;
980 call idle_loop;
981 jmp ultra2_ensure_sg;
982
983sgptr_fixup:
984 /*
985 * Fixup the residual next S/G pointer. The S/G preload
986 * feature of the chip allows us to load two elements
987 * in addition to the currently active element. We
988 * store the bottom byte of the next S/G pointer in
989 * the SG_CACEPTR register so we can restore the
990 * correct value when the DMA completes. If the next
991 * sg ptr value has advanced to the point where higher
992 * bytes in the address have been affected, fix them
993 * too.
994 */
995 test SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done;
996 test SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done;
997 add SCB_RESIDUAL_SGPTR[1], -1;
998 adc SCB_RESIDUAL_SGPTR[2], -1;
999 adc SCB_RESIDUAL_SGPTR[3], -1;
1000sgptr_fixup_done:
1001 and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW;
1002 /* We are not the last seg */
1003 and SCB_RESIDUAL_DATACNT[3], ~SG_LAST_SEG;
1004residuals_correct:
1005 /*
1006 * Go ahead and shut down the DMA engine now.
1007 * In the future, we'll want to handle end of
1008 * transfer messages prior to doing this, but this
1009 * requires similar restructuring for pre-ULTRA2
1010 * controllers.
1011 */
1012 test DMAPARAMS, DIRECTION jnz ultra2_fifoempty;
1013ultra2_fifoflush:
1014 if ((ahc->features & AHC_DT) == 0) {
1015 if ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0) {
1016 /*
1017 * On Rev A of the aic7890, the autoflush
1018 * feature doesn't function correctly.
1019 * Perform an explicit manual flush. During
1020 * a manual flush, the FIFOEMP bit becomes
1021 * true every time the PCI FIFO empties
1022 * regardless of the state of the SCSI FIFO.
1023 * It can take up to 4 clock cycles for the
1024 * SCSI FIFO to get data into the PCI FIFO
1025 * and for FIFOEMP to de-assert. Here we
1026 * guard against this condition by making
1027 * sure the FIFOEMP bit stays on for 5 full
1028 * clock cycles.
1029 */
1030 or DFCNTRL, FIFOFLUSH;
1031 test DFSTATUS, FIFOEMP jz ultra2_fifoflush;
1032 test DFSTATUS, FIFOEMP jz ultra2_fifoflush;
1033 test DFSTATUS, FIFOEMP jz ultra2_fifoflush;
1034 test DFSTATUS, FIFOEMP jz ultra2_fifoflush;
1035 }
1036 test DFSTATUS, FIFOEMP jz ultra2_fifoflush;
1037 } else {
1038 /*
1039 * We enable the auto-ack feature on DT capable
1040 * controllers. This means that the controller may
1041 * have already transferred some overrun bytes into
1042 * the data FIFO and acked them on the bus. The only
1043 * way to detect this situation is to wait for
1044 * LAST_SEG_DONE to come true on a completed transfer
1045 * and then test to see if the data FIFO is non-empty.
1046 */
1047 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL
1048 jz ultra2_wait_fifoemp;
1049 test SG_CACHE_SHADOW, LAST_SEG_DONE jz .;
1050 /*
1051 * FIFOEMP can lag LAST_SEG_DONE. Wait a few
1052 * clocks before calling this an overrun.
1053 */
1054 test DFSTATUS, FIFOEMP jnz ultra2_fifoempty;
1055 test DFSTATUS, FIFOEMP jnz ultra2_fifoempty;
1056 test DFSTATUS, FIFOEMP jnz ultra2_fifoempty;
1057 /* Overrun */
1058 jmp data_phase_loop;
1059ultra2_wait_fifoemp:
1060 test DFSTATUS, FIFOEMP jz .;
1061 }
1062ultra2_fifoempty:
1063 /* Don't clobber an inprogress host data transfer */
1064 test DFSTATUS, MREQPEND jnz ultra2_fifoempty;
1065ultra2_dmahalt:
1066 and DFCNTRL, ~(SCSIEN|HDMAEN);
1067 test DFCNTRL, SCSIEN|HDMAEN jnz .;
1068 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
1069 /*
1070 * Keep HHADDR cleared for future, 32bit addressed
1071 * only, DMA operations.
1072 *
1073 * Due to bayonette style S/G handling, our residual
1074 * data must be "fixed up" once the transfer is halted.
1075 * Here we fixup the HSHADDR stored in the high byte
1076 * of the residual data cnt. By postponing the fixup,
1077 * we can batch the clearing of HADDR with the fixup.
1078 * If we halted on the last segment, the residual is
1079 * already correct. If we are not on the last
1080 * segment, copy the high address directly from HSHADDR.
1081 * We don't need to worry about maintaining the
1082 * SG_LAST_SEG flag as it will always be false in the
1083 * case where an update is required.
1084 */
1085 or DSCOMMAND1, HADDLDSEL0;
1086 test SG_CACHE_SHADOW, LAST_SEG jnz . + 2;
1087 mov SCB_RESIDUAL_DATACNT[3], SHADDR;
1088 clr HADDR;
1089 and DSCOMMAND1, ~HADDLDSEL0;
1090 }
1091 } else {
1092 /* If we are the last SG block, tell the hardware. */
1093 if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0
1094 && ahc->pci_cachesize != 0) {
1095 test MWI_RESIDUAL, 0xFF jnz dma_mid_sg;
1096 }
1097 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz dma_mid_sg;
1098 if ((ahc->flags & AHC_TARGETROLE) != 0) {
1099 test SSTAT0, TARGET jz dma_last_sg;
1100 if ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0) {
1101 test DMAPARAMS, DIRECTION jz dma_mid_sg;
1102 }
1103 }
1104dma_last_sg:
1105 and DMAPARAMS, ~WIDEODD;
1106dma_mid_sg:
1107 /* Start DMA data transfer. */
1108 mov DFCNTRL, DMAPARAMS;
1109dma_loop:
1110 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1111 call idle_loop;
1112 }
1113 test SSTAT0,DMADONE jnz dma_dmadone;
1114 test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */
1115dma_phasemis:
1116 /*
1117 * We will be "done" DMAing when the transfer count goes to
1118 * zero, or the target changes the phase (in light of this,
1119 * it makes sense that the DMA circuitry doesn't ACK when
1120 * PHASEMIS is active). If we are doing a SCSI->Host transfer,
1121 * the data FIFO should be flushed auto-magically on STCNT=0
1122 * or a phase change, so just wait for FIFO empty status.
1123 */
1124dma_checkfifo:
1125 test DFCNTRL,DIRECTION jnz dma_fifoempty;
1126dma_fifoflush:
1127 test DFSTATUS,FIFOEMP jz dma_fifoflush;
1128dma_fifoempty:
1129 /* Don't clobber an inprogress host data transfer */
1130 test DFSTATUS, MREQPEND jnz dma_fifoempty;
1131
1132 /*
1133 * Now shut off the DMA and make sure that the DMA
1134 * hardware has actually stopped. Touching the DMA
1135 * counters, etc. while a DMA is active will result
1136 * in an ILLSADDR exception.
1137 */
1138dma_dmadone:
1139 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN);
1140dma_halt:
1141 /*
1142 * Some revisions of the aic78XX have a problem where, if the
1143 * data fifo is full, but the PCI input latch is not empty,
1144 * HDMAEN cannot be cleared. The fix used here is to drain
1145 * the prefetched but unused data from the data fifo until
1146 * there is space for the input latch to drain.
1147 */
1148 if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0) {
1149 mov NONE, DFDAT;
1150 }
1151 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt;
1152
1153 /* See if we have completed this last segment */
1154 test STCNT[0], 0xff jnz data_phase_finish;
1155 test STCNT[1], 0xff jnz data_phase_finish;
1156 test STCNT[2], 0xff jnz data_phase_finish;
1157
1158 /*
1159 * Advance the scatter-gather pointers if needed
1160 */
1161 if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0
1162 && ahc->pci_cachesize != 0) {
1163 test MWI_RESIDUAL, 0xFF jz no_mwi_resid;
1164 /*
1165 * Reload HADDR from SHADDR and setup the
1166 * count to be the size of our residual.
1167 */
1168 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1169 bmov HADDR, SHADDR, 4;
1170 mov HCNT, MWI_RESIDUAL;
1171 bmov HCNT[1], ALLZEROS, 2;
1172 } else {
1173 mvi DINDEX, HADDR;
1174 mvi SHADDR call bcopy_4;
1175 mov MWI_RESIDUAL call set_hcnt;
1176 }
1177 clr MWI_RESIDUAL;
1178 jmp sg_load_done;
1179no_mwi_resid:
1180 }
1181 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz sg_load;
1182 or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL;
1183 jmp data_phase_finish;
1184sg_load:
1185 /*
1186 * Load the next SG element's data address and length
1187 * into the DMA engine. If we don't have hardware
1188 * to perform a prefetch, we'll have to fetch the
1189 * segment from host memory first.
1190 */
1191 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1192 /* Wait for the idle loop to complete */
1193 test CCSGCTL, CCSGEN jz . + 3;
1194 call idle_loop;
1195 test CCSGCTL, CCSGEN jnz . - 1;
1196 bmov HADDR, CCSGRAM, 7;
1197 /*
1198 * Workaround for flaky external SCB RAM
1199 * on certain aic7895 setups. It seems
1200 * unable to handle direct transfers from
1201 * S/G ram to certain SCB locations.
1202 */
1203 mov SINDEX, CCSGRAM;
1204 mov SCB_RESIDUAL_DATACNT[3], SINDEX;
1205 } else {
1206 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
1207 mov ALLZEROS call set_hhaddr;
1208 }
1209 mvi DINDEX, HADDR;
1210 mvi SCB_RESIDUAL_SGPTR call bcopy_4;
1211
1212 mvi SG_SIZEOF call set_hcnt;
1213
1214 or DFCNTRL, HDMAEN|DIRECTION|FIFORESET;
1215
1216 call dma_finish;
1217
1218 mvi DINDEX, HADDR;
1219 call dfdat_in_7;
1220 mov SCB_RESIDUAL_DATACNT[3], DFDAT;
1221 }
1222
1223 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
1224 mov SCB_RESIDUAL_DATACNT[3] call set_hhaddr;
1225
1226 /*
1227 * The lowest address byte must be loaded
1228 * last as it triggers the computation of
1229 * some items in the PCI block. The ULTRA2
1230 * chips do this on PRELOAD.
1231 */
1232 mov HADDR, HADDR;
1233 }
1234 if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0
1235 && ahc->pci_cachesize != 0) {
1236 call calc_mwi_residual;
1237 }
1238
1239 /* Point to the new next sg in memory */
1240 call sg_advance;
1241
1242sg_load_done:
1243 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1244 bmov STCNT, HCNT, 3;
1245 } else {
1246 call set_stcnt_from_hcnt;
1247 }
1248
1249 if ((ahc->flags & AHC_TARGETROLE) != 0) {
1250 test SSTAT0, TARGET jnz data_phase_loop;
1251 }
1252 }
1253data_phase_finish:
1254 /*
1255 * If the target has left us in data phase, loop through
1256 * the dma code again. In the case of ULTRA2 adapters,
1257 * we should only loop if there is a data overrun. For
1258 * all other adapters, we'll loop after each S/G element
1259 * is loaded as well as if there is an overrun.
1260 */
1261 if ((ahc->flags & AHC_TARGETROLE) != 0) {
1262 test SSTAT0, TARGET jnz data_phase_done;
1263 }
1264 if ((ahc->flags & AHC_INITIATORROLE) != 0) {
1265 test SSTAT1, REQINIT jz .;
1266 if ((ahc->features & AHC_DT) == 0) {
1267 test SSTAT1,PHASEMIS jz data_phase_loop;
1268 } else {
1269 test SCSIPHASE, DATA_PHASE_MASK jnz data_phase_loop;
1270 }
1271 }
1272
1273data_phase_done:
1274 /*
1275 * After a DMA finishes, save the SG and STCNT residuals back into
1276 * the SCB. We use STCNT instead of HCNT, since it's a reflection
1277 * of how many bytes were transferred on the SCSI (as opposed to the
1278 * host) bus.
1279 */
1280 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1281 /* Kill off any pending prefetch */
1282 call disable_ccsgen;
1283 }
1284
1285 if ((ahc->features & AHC_ULTRA2) == 0) {
1286 /*
1287 * Clear the high address byte so that all other DMA
1288 * operations, which use 32bit addressing, can assume
1289 * HHADDR is 0.
1290 */
1291 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
1292 mov ALLZEROS call set_hhaddr;
1293 }
1294 }
1295
1296 /*
1297 * Update our residual information before the information is
1298 * lost by some other type of SCSI I/O (e.g. PIO). If we have
1299 * transferred all data, no update is needed.
1300 *
1301 */
1302 test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jnz residual_update_done;
1303 if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0
1304 && ahc->pci_cachesize != 0) {
1305 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1306 test MWI_RESIDUAL, 0xFF jz bmov_resid;
1307 }
1308 mov A, MWI_RESIDUAL;
1309 add SCB_RESIDUAL_DATACNT[0], A, STCNT[0];
1310 clr A;
1311 adc SCB_RESIDUAL_DATACNT[1], A, STCNT[1];
1312 adc SCB_RESIDUAL_DATACNT[2], A, STCNT[2];
1313 clr MWI_RESIDUAL;
1314 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1315 jmp . + 2;
1316bmov_resid:
1317 bmov SCB_RESIDUAL_DATACNT, STCNT, 3;
1318 }
1319 } else if ((ahc->features & AHC_CMD_CHAN) != 0) {
1320 bmov SCB_RESIDUAL_DATACNT, STCNT, 3;
1321 } else {
1322 mov SCB_RESIDUAL_DATACNT[0], STCNT[0];
1323 mov SCB_RESIDUAL_DATACNT[1], STCNT[1];
1324 mov SCB_RESIDUAL_DATACNT[2], STCNT[2];
1325 }
1326residual_update_done:
1327 /*
1328 * Since we've been through a data phase, the SCB_RESID* fields
1329 * are now initialized. Clear the full residual flag.
1330 */
1331 and SCB_SGPTR[0], ~SG_FULL_RESID;
1332
1333 if ((ahc->features & AHC_ULTRA2) != 0) {
1334 /* Clear the channel in case we return to data phase later */
1335 or SXFRCTL0, CLRSTCNT|CLRCHN;
1336 or SXFRCTL0, CLRSTCNT|CLRCHN;
1337 }
1338
1339 if ((ahc->flags & AHC_TARGETROLE) != 0) {
1340 test SEQ_FLAGS, DPHASE_PENDING jz ITloop;
1341 and SEQ_FLAGS, ~DPHASE_PENDING;
1342 /*
1343 * For data-in phases, wait for any pending acks from the
1344 * initiator before changing phase. We only need to
1345 * send Ignore Wide Residue messages for data-in phases.
1346 */
1347 test DFCNTRL, DIRECTION jz target_ITloop;
1348 test SSTAT1, REQINIT jnz .;
1349 test SCB_LUN, SCB_XFERLEN_ODD jz target_ITloop;
1350 test SCSIRATE, WIDEXFER jz target_ITloop;
1351 /*
1352 * Issue an Ignore Wide Residue Message.
1353 */
1354 mvi P_MESGIN|BSYO call change_phase;
1355 mvi MSG_IGN_WIDE_RESIDUE call target_outb;
1356 mvi 1 call target_outb;
1357 jmp target_ITloop;
1358 } else {
1359 jmp ITloop;
1360 }
1361
1362if ((ahc->flags & AHC_INITIATORROLE) != 0) {
1363/*
1364 * Command phase. Set up the DMA registers and let 'er rip.
1365 */
1366p_command:
1367 test SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay;
1368 mvi PROTO_VIOLATION call set_seqint;
1369p_command_okay:
1370
1371 if ((ahc->features & AHC_ULTRA2) != 0) {
1372 bmov HCNT[0], SCB_CDB_LEN, 1;
1373 bmov HCNT[1], ALLZEROS, 2;
1374 mvi SG_CACHE_PRE, LAST_SEG;
1375 } else if ((ahc->features & AHC_CMD_CHAN) != 0) {
1376 bmov STCNT[0], SCB_CDB_LEN, 1;
1377 bmov STCNT[1], ALLZEROS, 2;
1378 } else {
1379 mov STCNT[0], SCB_CDB_LEN;
1380 clr STCNT[1];
1381 clr STCNT[2];
1382 }
1383 add NONE, -13, SCB_CDB_LEN;
1384 mvi SCB_CDB_STORE jnc p_command_embedded;
1385p_command_from_host:
1386 if ((ahc->features & AHC_ULTRA2) != 0) {
1387 bmov HADDR[0], SCB_CDB_PTR, 4;
1388 mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN|DIRECTION);
1389 } else {
1390 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1391 bmov HADDR[0], SCB_CDB_PTR, 4;
1392 bmov HCNT, STCNT, 3;
1393 } else {
1394 mvi DINDEX, HADDR;
1395 mvi SCB_CDB_PTR call bcopy_4;
1396 mov SCB_CDB_LEN call set_hcnt;
1397 }
1398 mvi DFCNTRL, (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET);
1399 }
1400 jmp p_command_xfer;
1401p_command_embedded:
1402 /*
1403 * The data fifo seems to require 4 byte aligned
1404 * transfers from the sequencer. Force this to
1405 * be the case by clearing HADDR[0] even though
1406 * we aren't going to touch host memory.
1407 */
1408 clr HADDR[0];
1409 if ((ahc->features & AHC_ULTRA2) != 0) {
1410 mvi DFCNTRL, (PRELOADEN|SCSIEN|DIRECTION);
1411 bmov DFDAT, SCB_CDB_STORE, 12;
1412 } else if ((ahc->features & AHC_CMD_CHAN) != 0) {
1413 if ((ahc->flags & AHC_SCB_BTT) != 0) {
1414 /*
1415 * On the 7895 the data FIFO will
1416 * get corrupted if you try to dump
1417 * data from external SCB memory into
1418 * the FIFO while it is enabled. So,
1419 * fill the fifo and then enable SCSI
1420 * transfers.
1421 */
1422 mvi DFCNTRL, (DIRECTION|FIFORESET);
1423 } else {
1424 mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET);
1425 }
1426 bmov DFDAT, SCB_CDB_STORE, 12;
1427 if ((ahc->flags & AHC_SCB_BTT) != 0) {
1428 mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFOFLUSH);
1429 } else {
1430 or DFCNTRL, FIFOFLUSH;
1431 }
1432 } else {
1433 mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET);
1434 call copy_to_fifo_6;
1435 call copy_to_fifo_6;
1436 or DFCNTRL, FIFOFLUSH;
1437 }
1438p_command_xfer:
1439 and SEQ_FLAGS, ~NO_CDB_SENT;
1440 if ((ahc->features & AHC_DT) == 0) {
1441 test SSTAT0, SDONE jnz . + 2;
1442 test SSTAT1, PHASEMIS jz . - 1;
1443 /*
1444 * Wait for our ACK to go-away on it's own
1445 * instead of being killed by SCSIEN getting cleared.
1446 */
1447 test SCSISIGI, ACKI jnz .;
1448 } else {
1449 test DFCNTRL, SCSIEN jnz .;
1450 }
1451 test SSTAT0, SDONE jnz p_command_successful;
1452 /*
1453 * Don't allow a data phase if the command
1454 * was not fully transferred.
1455 */
1456 or SEQ_FLAGS, NO_CDB_SENT;
1457p_command_successful:
1458 and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN);
1459 test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz .;
1460 jmp ITloop;
1461
1462/*
1463 * Status phase. Wait for the data byte to appear, then read it
1464 * and store it into the SCB.
1465 */
1466p_status:
1467 test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation;
1468p_status_okay:
1469 mov SCB_SCSI_STATUS, SCSIDATL;
1470 or SCB_CONTROL, STATUS_RCVD;
1471 jmp ITloop;
1472
1473/*
1474 * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full
1475 * indentify message sequence and send it to the target. The host may
1476 * override this behavior by setting the MK_MESSAGE bit in the SCB
1477 * control byte. This will cause us to interrupt the host and allow
1478 * it to handle the message phase completely on its own. If the bit
1479 * associated with this target is set, we will also interrupt the host,
1480 * thereby allowing it to send a message on the next selection regardless
1481 * of the transaction being sent.
1482 *
1483 * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message.
1484 * This is done to allow the host to send messages outside of an identify
1485 * sequence while protecting the seqencer from testing the MK_MESSAGE bit
1486 * on an SCB that might not be for the current nexus. (For example, a
1487 * BDR message in responce to a bad reselection would leave us pointed to
1488 * an SCB that doesn't have anything to do with the current target).
1489 *
1490 * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag,
1491 * bus device reset).
1492 *
1493 * When there are no messages to send, MSG_OUT should be set to MSG_NOOP,
1494 * in case the target decides to put us in this phase for some strange
1495 * reason.
1496 */
1497p_mesgout_retry:
1498 /* Turn on ATN for the retry */
1499 if ((ahc->features & AHC_DT) == 0) {
1500 or SCSISIGO, ATNO, LASTPHASE;
1501 } else {
1502 mvi SCSISIGO, ATNO;
1503 }
1504p_mesgout:
1505 mov SINDEX, MSG_OUT;
1506 cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host;
1507 test SCB_CONTROL,MK_MESSAGE jnz host_message_loop;
1508p_mesgout_identify:
1509 or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SAVED_LUN;
1510 test SCB_CONTROL, DISCENB jnz . + 2;
1511 and SINDEX, ~DISCENB;
1512/*
1513 * Send a tag message if TAG_ENB is set in the SCB control block.
1514 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value.
1515 */
1516p_mesgout_tag:
1517 test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte;
1518 mov SCSIDATL, SINDEX; /* Send the identify message */
1519 call phase_lock;
1520 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done;
1521 and SCSIDATL,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL;
1522 call phase_lock;
1523 cmp LASTPHASE, P_MESGOUT jne p_mesgout_done;
1524 mov SCB_TAG jmp p_mesgout_onebyte;
1525/*
1526 * Interrupt the driver, and allow it to handle this message
1527 * phase and any required retries.
1528 */
1529p_mesgout_from_host:
1530 cmp SINDEX, HOST_MSG jne p_mesgout_onebyte;
1531 jmp host_message_loop;
1532
1533p_mesgout_onebyte:
1534 mvi CLRSINT1, CLRATNO;
1535 mov SCSIDATL, SINDEX;
1536
1537/*
1538 * If the next bus phase after ATN drops is message out, it means
1539 * that the target is requesting that the last message(s) be resent.
1540 */
1541 call phase_lock;
1542 cmp LASTPHASE, P_MESGOUT je p_mesgout_retry;
1543
1544p_mesgout_done:
1545 mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */
1546 mov LAST_MSG, MSG_OUT;
1547 mvi MSG_OUT, MSG_NOOP; /* No message left */
1548 jmp ITloop;
1549
1550/*
1551 * Message in phase. Bytes are read using Automatic PIO mode.
1552 */
1553p_mesgin:
1554 mvi ACCUM call inb_first; /* read the 1st message byte */
1555
1556 test A,MSG_IDENTIFYFLAG jnz mesgin_identify;
1557 cmp A,MSG_DISCONNECT je mesgin_disconnect;
1558 cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs;
1559 cmp ALLZEROS,A je mesgin_complete;
1560 cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs;
1561 cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_ign_wide_residue;
1562 cmp A,MSG_NOOP je mesgin_done;
1563
1564/*
1565 * Pushed message loop to allow the kernel to
1566 * run it's own message state engine. To avoid an
1567 * extra nop instruction after signaling the kernel,
1568 * we perform the phase_lock before checking to see
1569 * if we should exit the loop and skip the phase_lock
1570 * in the ITloop. Performing back to back phase_locks
1571 * shouldn't hurt, but why do it twice...
1572 */
1573host_message_loop:
1574 mvi HOST_MSG_LOOP call set_seqint;
1575 call phase_lock;
1576 cmp RETURN_1, EXIT_MSG_LOOP je ITloop + 1;
1577 jmp host_message_loop;
1578
1579mesgin_ign_wide_residue:
1580if ((ahc->features & AHC_WIDE) != 0) {
1581 test SCSIRATE, WIDEXFER jz mesgin_reject;
1582 /* Pull the residue byte */
1583 mvi ARG_1 call inb_next;
1584 cmp ARG_1, 0x01 jne mesgin_reject;
1585 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2;
1586 test SCB_LUN, SCB_XFERLEN_ODD jnz mesgin_done;
1587 mvi IGN_WIDE_RES call set_seqint;
1588 jmp mesgin_done;
1589}
1590
1591mesgin_proto_violation:
1592 mvi PROTO_VIOLATION call set_seqint;
1593 jmp mesgin_done;
1594mesgin_reject:
1595 mvi MSG_MESSAGE_REJECT call mk_mesg;
1596mesgin_done:
1597 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/
1598 jmp ITloop;
1599
1600/*
1601 * We received a "command complete" message. Put the SCB_TAG into the QOUTFIFO,
1602 * and trigger a completion interrupt. Before doing so, check to see if there
1603 * is a residual or the status byte is something other than STATUS_GOOD (0).
1604 * In either of these conditions, we upload the SCB back to the host so it can
1605 * process this information. In the case of a non zero status byte, we
1606 * additionally interrupt the kernel driver synchronously, allowing it to
1607 * decide if sense should be retrieved. If the kernel driver wishes to request
1608 * sense, it will fill the kernel SCB with a request sense command, requeue
1609 * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting
1610 * RETURN_1 to SEND_SENSE.
1611 */
1612mesgin_complete:
1613
1614 /*
1615 * If ATN is raised, we still want to give the target a message.
1616 * Perhaps there was a parity error on this last message byte.
1617 * Either way, the target should take us to message out phase
1618 * and then attempt to complete the command again. We should use a
1619 * critical section here to guard against a timeout triggering
1620 * for this command and setting ATN while we are still processing
1621 * the completion.
1622 test SCSISIGI, ATNI jnz mesgin_done;
1623 */
1624
1625 /*
1626 * If we are identified and have successfully sent the CDB,
1627 * any status will do. Optimize this fast path.
1628 */
1629 test SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation;
1630 test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted;
1631
1632 /*
1633 * If the target never sent an identify message but instead went
1634 * to mesgin to give an invalid message, let the host abort us.
1635 */
1636 test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation;
1637
1638 /*
1639 * If we recevied good status but never successfully sent the
1640 * cdb, abort the command.
1641 */
1642 test SCB_SCSI_STATUS,0xff jnz complete_accepted;
1643 test SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation;
1644
1645complete_accepted:
1646 /*
1647 * See if we attempted to deliver a message but the target ingnored us.
1648 */
1649 test SCB_CONTROL, MK_MESSAGE jz . + 2;
1650 mvi MKMSG_FAILED call set_seqint;
1651
1652 /*
1653 * Check for residuals
1654 */
1655 test SCB_SGPTR, SG_LIST_NULL jnz check_status;/* No xfer */
1656 test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */
1657 test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb;
1658check_status:
1659 test SCB_SCSI_STATUS,0xff jz complete; /* Good Status? */
1660upload_scb:
1661 or SCB_SGPTR, SG_RESID_VALID;
1662 mvi DMAPARAMS, FIFORESET;
1663 mov SCB_TAG call dma_scb;
1664 test SCB_SCSI_STATUS, 0xff jz complete; /* Just a residual? */
1665 mvi BAD_STATUS call set_seqint; /* let driver know */
1666 cmp RETURN_1, SEND_SENSE jne complete;
1667 call add_scb_to_free_list;
1668 jmp await_busfree;
1669complete:
1670 mov SCB_TAG call complete_post;
1671 jmp await_busfree;
1672}
1673
1674complete_post:
1675 /* Post the SCBID in SINDEX and issue an interrupt */
1676 call add_scb_to_free_list;
1677 mov ARG_1, SINDEX;
1678 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
1679 mov A, SDSCB_QOFF;
1680 } else {
1681 mov A, QOUTPOS;
1682 }
1683 mvi QOUTFIFO_OFFSET call post_byte_setup;
1684 mov ARG_1 call post_byte;
1685 if ((ahc->features & AHC_QUEUE_REGS) == 0) {
1686 inc QOUTPOS;
1687 }
1688 mvi INTSTAT,CMDCMPLT ret;
1689
1690if ((ahc->flags & AHC_INITIATORROLE) != 0) {
1691/*
1692 * Is it a disconnect message? Set a flag in the SCB to remind us
1693 * and await the bus going free. If this is an untagged transaction
1694 * store the SCB id for it in our untagged target table for lookup on
1695 * a reselction.
1696 */
1697mesgin_disconnect:
1698 /*
1699 * If ATN is raised, we still want to give the target a message.
1700 * Perhaps there was a parity error on this last message byte
1701 * or we want to abort this command. Either way, the target
1702 * should take us to message out phase and then attempt to
1703 * disconnect again.
1704 * XXX - Wait for more testing.
1705 test SCSISIGI, ATNI jnz mesgin_done;
1706 */
1707 test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT
1708 jnz mesgin_proto_violation;
1709 or SCB_CONTROL,DISCONNECTED;
1710 if ((ahc->flags & AHC_PAGESCBS) != 0) {
1711 call add_scb_to_disc_list;
1712 }
1713 test SCB_CONTROL, TAG_ENB jnz await_busfree;
1714 mov ARG_1, SCB_TAG;
1715 and SAVED_LUN, LID, SCB_LUN;
1716 mov SCB_SCSIID call set_busy_target;
1717 jmp await_busfree;
1718
1719/*
1720 * Save data pointers message:
1721 * Copying RAM values back to SCB, for Save Data Pointers message, but
1722 * only if we've actually been into a data phase to change them. This
1723 * protects against bogus data in scratch ram and the residual counts
1724 * since they are only initialized when we go into data_in or data_out.
1725 * Ack the message as soon as possible. For chips without S/G pipelining,
1726 * we can only ack the message after SHADDR has been saved. On these
1727 * chips, SHADDR increments with every bus transaction, even PIO.
1728 */
1729mesgin_sdptrs:
1730 if ((ahc->features & AHC_ULTRA2) != 0) {
1731 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/
1732 test SEQ_FLAGS, DPHASE jz ITloop;
1733 } else {
1734 test SEQ_FLAGS, DPHASE jz mesgin_done;
1735 }
1736
1737 /*
1738 * If we are asked to save our position at the end of the
1739 * transfer, just mark us at the end rather than perform a
1740 * full save.
1741 */
1742 test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz mesgin_sdptrs_full;
1743 or SCB_SGPTR, SG_LIST_NULL;
1744 if ((ahc->features & AHC_ULTRA2) != 0) {
1745 jmp ITloop;
1746 } else {
1747 jmp mesgin_done;
1748 }
1749
1750mesgin_sdptrs_full:
1751
1752 /*
1753 * The SCB_SGPTR becomes the next one we'll download,
1754 * and the SCB_DATAPTR becomes the current SHADDR.
1755 * Use the residual number since STCNT is corrupted by
1756 * any message transfer.
1757 */
1758 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1759 bmov SCB_DATAPTR, SHADDR, 4;
1760 if ((ahc->features & AHC_ULTRA2) == 0) {
1761 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/
1762 }
1763 bmov SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8;
1764 } else {
1765 mvi DINDEX, SCB_DATAPTR;
1766 mvi SHADDR call bcopy_4;
1767 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/
1768 mvi SCB_RESIDUAL_DATACNT call bcopy_8;
1769 }
1770 jmp ITloop;
1771
1772/*
1773 * Restore pointers message? Data pointers are recopied from the
1774 * SCB anytime we enter a data phase for the first time, so all
1775 * we need to do is clear the DPHASE flag and let the data phase
1776 * code do the rest. We also reset/reallocate the FIFO to make
1777 * sure we have a clean start for the next data or command phase.
1778 */
1779mesgin_rdptrs:
1780 and SEQ_FLAGS, ~DPHASE; /*
1781 * We'll reload them
1782 * the next time through
1783 * the dataphase.
1784 */
1785 or SXFRCTL0, CLRSTCNT|CLRCHN;
1786 jmp mesgin_done;
1787
1788/*
1789 * Index into our Busy Target table. SINDEX and DINDEX are modified
1790 * upon return. SCBPTR may be modified by this action.
1791 */
1792set_busy_target:
1793 shr DINDEX, 4, SINDEX;
1794 if ((ahc->flags & AHC_SCB_BTT) != 0) {
1795 mov SCBPTR, SAVED_LUN;
1796 add DINDEX, SCB_64_BTT;
1797 } else {
1798 add DINDEX, BUSY_TARGETS;
1799 }
1800 mov DINDIR, ARG_1 ret;
1801
1802/*
1803 * Identify message? For a reconnecting target, this tells us the lun
1804 * that the reconnection is for - find the correct SCB and switch to it,
1805 * clearing the "disconnected" bit so we don't "find" it by accident later.
1806 */
1807mesgin_identify:
1808 /*
1809 * Determine whether a target is using tagged or non-tagged
1810 * transactions by first looking at the transaction stored in
1811 * the busy target array. If there is no untagged transaction
1812 * for this target or the transaction is for a different lun, then
1813 * this must be a tagged transaction.
1814 */
1815 shr SINDEX, 4, SAVED_SCSIID;
1816 and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A;
1817 if ((ahc->flags & AHC_SCB_BTT) != 0) {
1818 add SINDEX, SCB_64_BTT;
1819 mov SCBPTR, SAVED_LUN;
1820 if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
1821 add NONE, -SCB_64_BTT, SINDEX;
1822 jc . + 2;
1823 mvi INTSTAT, OUT_OF_RANGE;
1824 nop;
1825 add NONE, -(SCB_64_BTT + 16), SINDEX;
1826 jnc . + 2;
1827 mvi INTSTAT, OUT_OF_RANGE;
1828 nop;
1829 }
1830 } else {
1831 add SINDEX, BUSY_TARGETS;
1832 if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
1833 add NONE, -BUSY_TARGETS, SINDEX;
1834 jc . + 2;
1835 mvi INTSTAT, OUT_OF_RANGE;
1836 nop;
1837 add NONE, -(BUSY_TARGETS + 16), SINDEX;
1838 jnc . + 2;
1839 mvi INTSTAT, OUT_OF_RANGE;
1840 nop;
1841 }
1842 }
1843 mov ARG_1, SINDIR;
1844 cmp ARG_1, SCB_LIST_NULL je snoop_tag;
1845 if ((ahc->flags & AHC_PAGESCBS) != 0) {
1846 mov ARG_1 call findSCB;
1847 } else {
1848 mov SCBPTR, ARG_1;
1849 }
1850 if ((ahc->flags & AHC_SCB_BTT) != 0) {
1851 jmp setup_SCB_id_lun_okay;
1852 } else {
1853 /*
1854 * We only allow one untagged command per-target
1855 * at a time. So, if the lun doesn't match, look
1856 * for a tag message.
1857 */
1858 and A, LID, SCB_LUN;
1859 cmp SAVED_LUN, A je setup_SCB_id_lun_okay;
1860 if ((ahc->flags & AHC_PAGESCBS) != 0) {
1861 /*
1862 * findSCB removes the SCB from the
1863 * disconnected list, so we must replace
1864 * it there should this SCB be for another
1865 * lun.
1866 */
1867 call cleanup_scb;
1868 }
1869 }
1870
1871/*
1872 * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message.
1873 * If we get one, we use the tag returned to find the proper
1874 * SCB. With SCB paging, we must search for non-tagged
1875 * transactions since the SCB may exist in any slot. If we're not
1876 * using SCB paging, we can use the tag as the direct index to the
1877 * SCB.
1878 */
1879snoop_tag:
1880 if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
1881 or SEQ_FLAGS, 0x80;
1882 }
1883 mov NONE,SCSIDATL; /* ACK Identify MSG */
1884 call phase_lock;
1885 if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
1886 or SEQ_FLAGS, 0x1;
1887 }
1888 cmp LASTPHASE, P_MESGIN jne not_found;
1889 if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
1890 or SEQ_FLAGS, 0x2;
1891 }
1892 cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found;
1893get_tag:
1894 if ((ahc->flags & AHC_PAGESCBS) != 0) {
1895 mvi ARG_1 call inb_next; /* tag value */
1896 mov ARG_1 call findSCB;
1897 } else {
1898 mvi ARG_1 call inb_next; /* tag value */
1899 mov SCBPTR, ARG_1;
1900 }
1901
1902/*
1903 * Ensure that the SCB the tag points to is for
1904 * an SCB transaction to the reconnecting target.
1905 */
1906setup_SCB:
1907 if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
1908 or SEQ_FLAGS, 0x4;
1909 }
1910 mov A, SCB_SCSIID;
1911 cmp SAVED_SCSIID, A jne not_found_cleanup_scb;
1912 if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
1913 or SEQ_FLAGS, 0x8;
1914 }
1915setup_SCB_id_okay:
1916 and A, LID, SCB_LUN;
1917 cmp SAVED_LUN, A jne not_found_cleanup_scb;
1918setup_SCB_id_lun_okay:
1919 if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
1920 or SEQ_FLAGS, 0x10;
1921 }
1922 test SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb;
1923 and SCB_CONTROL,~DISCONNECTED;
1924 test SCB_CONTROL, TAG_ENB jnz setup_SCB_tagged;
1925 if ((ahc->flags & AHC_SCB_BTT) != 0) {
1926 mov A, SCBPTR;
1927 }
1928 mvi ARG_1, SCB_LIST_NULL;
1929 mov SAVED_SCSIID call set_busy_target;
1930 if ((ahc->flags & AHC_SCB_BTT) != 0) {
1931 mov SCBPTR, A;
1932 }
1933setup_SCB_tagged:
1934 clr SEQ_FLAGS; /* make note of IDENTIFY */
1935 call set_transfer_settings;
1936 /* See if the host wants to send a message upon reconnection */
1937 test SCB_CONTROL, MK_MESSAGE jz mesgin_done;
1938 mvi HOST_MSG call mk_mesg;
1939 jmp mesgin_done;
1940
1941not_found_cleanup_scb:
1942 if ((ahc->flags & AHC_PAGESCBS) != 0) {
1943 call cleanup_scb;
1944 }
1945not_found:
1946 mvi NO_MATCH call set_seqint;
1947 jmp mesgin_done;
1948
1949mk_mesg:
1950 if ((ahc->features & AHC_DT) == 0) {
1951 or SCSISIGO, ATNO, LASTPHASE;
1952 } else {
1953 mvi SCSISIGO, ATNO;
1954 }
1955 mov MSG_OUT,SINDEX ret;
1956
1957/*
1958 * Functions to read data in Automatic PIO mode.
1959 *
1960 * According to Adaptec's documentation, an ACK is not sent on input from
1961 * the target until SCSIDATL is read from. So we wait until SCSIDATL is
1962 * latched (the usual way), then read the data byte directly off the bus
1963 * using SCSIBUSL. When we have pulled the ATN line, or we just want to
1964 * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI
1965 * spec guarantees that the target will hold the data byte on the bus until
1966 * we send our ACK.
1967 *
1968 * The assumption here is that these are called in a particular sequence,
1969 * and that REQ is already set when inb_first is called. inb_{first,next}
1970 * use the same calling convention as inb.
1971 */
1972inb_next_wait_perr:
1973 mvi PERR_DETECTED call set_seqint;
1974 jmp inb_next_wait;
1975inb_next:
1976 mov NONE,SCSIDATL; /*dummy read from latch to ACK*/
1977inb_next_wait:
1978 /*
1979 * If there is a parity error, wait for the kernel to
1980 * see the interrupt and prepare our message response
1981 * before continuing.
1982 */
1983 test SSTAT1, REQINIT jz inb_next_wait;
1984 test SSTAT1, SCSIPERR jnz inb_next_wait_perr;
1985inb_next_check_phase:
1986 and LASTPHASE, PHASE_MASK, SCSISIGI;
1987 cmp LASTPHASE, P_MESGIN jne mesgin_phasemis;
1988inb_first:
1989 mov DINDEX,SINDEX;
1990 mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/
1991inb_last:
1992 mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/
1993}
1994
1995if ((ahc->flags & AHC_TARGETROLE) != 0) {
1996/*
1997 * Change to a new phase. If we are changing the state of the I/O signal,
1998 * from out to in, wait an additional data release delay before continuing.
1999 */
2000change_phase:
2001 /* Wait for preceeding I/O session to complete. */
2002 test SCSISIGI, ACKI jnz .;
2003
2004 /* Change the phase */
2005 and DINDEX, IOI, SCSISIGI;
2006 mov SCSISIGO, SINDEX;
2007 and A, IOI, SINDEX;
2008
2009 /*
2010 * If the data direction has changed, from
2011 * out (initiator driving) to in (target driving),
2012 * we must wait at least a data release delay plus
2013 * the normal bus settle delay. [SCSI III SPI 10.11.0]
2014 */
2015 cmp DINDEX, A je change_phase_wait;
2016 test SINDEX, IOI jz change_phase_wait;
2017 call change_phase_wait;
2018change_phase_wait:
2019 nop;
2020 nop;
2021 nop;
2022 nop ret;
2023
2024/*
2025 * Send a byte to an initiator in Automatic PIO mode.
2026 */
2027target_outb:
2028 or SXFRCTL0, SPIOEN;
2029 test SSTAT0, SPIORDY jz .;
2030 mov SCSIDATL, SINDEX;
2031 test SSTAT0, SPIORDY jz .;
2032 and SXFRCTL0, ~SPIOEN ret;
2033}
2034
2035/*
2036 * Locate a disconnected SCB by SCBID. Upon return, SCBPTR and SINDEX will
2037 * be set to the position of the SCB. If the SCB cannot be found locally,
2038 * it will be paged in from host memory. RETURN_2 stores the address of the
2039 * preceding SCB in the disconnected list which can be used to speed up
2040 * removal of the found SCB from the disconnected list.
2041 */
2042if ((ahc->flags & AHC_PAGESCBS) != 0) {
2043BEGIN_CRITICAL;
2044findSCB:
2045 mov A, SINDEX; /* Tag passed in SINDEX */
2046 cmp DISCONNECTED_SCBH, SCB_LIST_NULL je findSCB_notFound;
2047 mov SCBPTR, DISCONNECTED_SCBH; /* Initialize SCBPTR */
2048 mvi ARG_2, SCB_LIST_NULL; /* Head of list */
2049 jmp findSCB_loop;
2050findSCB_next:
2051 cmp SCB_NEXT, SCB_LIST_NULL je findSCB_notFound;
2052 mov ARG_2, SCBPTR;
2053 mov SCBPTR,SCB_NEXT;
2054findSCB_loop:
2055 cmp SCB_TAG, A jne findSCB_next;
2056rem_scb_from_disc_list:
2057 cmp ARG_2, SCB_LIST_NULL je rHead;
2058 mov DINDEX, SCB_NEXT;
2059 mov SINDEX, SCBPTR;
2060 mov SCBPTR, ARG_2;
2061 mov SCB_NEXT, DINDEX;
2062 mov SCBPTR, SINDEX ret;
2063rHead:
2064 mov DISCONNECTED_SCBH,SCB_NEXT ret;
2065END_CRITICAL;
2066findSCB_notFound:
2067 /*
2068 * We didn't find it. Page in the SCB.
2069 */
2070 mov ARG_1, A; /* Save tag */
2071 mov ALLZEROS call get_free_or_disc_scb;
2072 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
2073 mov ARG_1 jmp dma_scb;
2074}
2075
2076/*
2077 * Prepare the hardware to post a byte to host memory given an
2078 * index of (A + (256 * SINDEX)) and a base address of SHARED_DATA_ADDR.
2079 */
2080post_byte_setup:
2081 mov ARG_2, SINDEX;
2082 if ((ahc->features & AHC_CMD_CHAN) != 0) {
2083 mvi DINDEX, CCHADDR;
2084 mvi SHARED_DATA_ADDR call set_1byte_addr;
2085 mvi CCHCNT, 1;
2086 mvi CCSCBCTL, CCSCBRESET ret;
2087 } else {
2088 mvi DINDEX, HADDR;
2089 mvi SHARED_DATA_ADDR call set_1byte_addr;
2090 mvi 1 call set_hcnt;
2091 mvi DFCNTRL, FIFORESET ret;
2092 }
2093
2094post_byte:
2095 if ((ahc->features & AHC_CMD_CHAN) != 0) {
2096 bmov CCSCBRAM, SINDEX, 1;
2097 or CCSCBCTL, CCSCBEN|CCSCBRESET;
2098 test CCSCBCTL, CCSCBDONE jz .;
2099 clr CCSCBCTL ret;
2100 } else {
2101 mov DFDAT, SINDEX;
2102 or DFCNTRL, HDMAEN|FIFOFLUSH;
2103 jmp dma_finish;
2104 }
2105
2106phase_lock_perr:
2107 mvi PERR_DETECTED call set_seqint;
2108phase_lock:
2109 /*
2110 * If there is a parity error, wait for the kernel to
2111 * see the interrupt and prepare our message response
2112 * before continuing.
2113 */
2114 test SSTAT1, REQINIT jz phase_lock;
2115 test SSTAT1, SCSIPERR jnz phase_lock_perr;
2116phase_lock_latch_phase:
2117 if ((ahc->features & AHC_DT) == 0) {
2118 and SCSISIGO, PHASE_MASK, SCSISIGI;
2119 }
2120 and LASTPHASE, PHASE_MASK, SCSISIGI ret;
2121
2122if ((ahc->features & AHC_CMD_CHAN) == 0) {
2123set_hcnt:
2124 mov HCNT[0], SINDEX;
2125clear_hcnt:
2126 clr HCNT[1];
2127 clr HCNT[2] ret;
2128
2129set_stcnt_from_hcnt:
2130 mov STCNT[0], HCNT[0];
2131 mov STCNT[1], HCNT[1];
2132 mov STCNT[2], HCNT[2] ret;
2133
2134bcopy_8:
2135 mov DINDIR, SINDIR;
2136bcopy_7:
2137 mov DINDIR, SINDIR;
2138 mov DINDIR, SINDIR;
2139bcopy_5:
2140 mov DINDIR, SINDIR;
2141bcopy_4:
2142 mov DINDIR, SINDIR;
2143bcopy_3:
2144 mov DINDIR, SINDIR;
2145 mov DINDIR, SINDIR;
2146 mov DINDIR, SINDIR ret;
2147}
2148
2149if ((ahc->flags & AHC_TARGETROLE) != 0) {
2150/*
2151 * Setup addr assuming that A is an index into
2152 * an array of 32byte objects, SINDEX contains
2153 * the base address of that array, and DINDEX
2154 * contains the base address of the location
2155 * to store the indexed address.
2156 */
2157set_32byte_addr:
2158 shr ARG_2, 3, A;
2159 shl A, 5;
2160 jmp set_1byte_addr;
2161}
2162
2163/*
2164 * Setup addr assuming that A is an index into
2165 * an array of 64byte objects, SINDEX contains
2166 * the base address of that array, and DINDEX
2167 * contains the base address of the location
2168 * to store the indexed address.
2169 */
2170set_64byte_addr:
2171 shr ARG_2, 2, A;
2172 shl A, 6;
2173
2174/*
2175 * Setup addr assuming that A + (ARG_2 * 256) is an
2176 * index into an array of 1byte objects, SINDEX contains
2177 * the base address of that array, and DINDEX contains
2178 * the base address of the location to store the computed
2179 * address.
2180 */
2181set_1byte_addr:
2182 add DINDIR, A, SINDIR;
2183 mov A, ARG_2;
2184 adc DINDIR, A, SINDIR;
2185 clr A;
2186 adc DINDIR, A, SINDIR;
2187 adc DINDIR, A, SINDIR ret;
2188
2189/*
2190 * Either post or fetch an SCB from host memory based on the
2191 * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX.
2192 */
2193dma_scb:
2194 mov A, SINDEX;
2195 if ((ahc->features & AHC_CMD_CHAN) != 0) {
2196 mvi DINDEX, CCHADDR;
2197 mvi HSCB_ADDR call set_64byte_addr;
2198 mov CCSCBPTR, SCBPTR;
2199 test DMAPARAMS, DIRECTION jz dma_scb_tohost;
2200 if ((ahc->flags & AHC_SCB_BTT) != 0) {
2201 mvi CCHCNT, SCB_DOWNLOAD_SIZE_64;
2202 } else {
2203 mvi CCHCNT, SCB_DOWNLOAD_SIZE;
2204 }
2205 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET;
2206 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .;
2207 jmp dma_scb_finish;
2208dma_scb_tohost:
2209 mvi CCHCNT, SCB_UPLOAD_SIZE;
2210 if ((ahc->features & AHC_ULTRA2) == 0) {
2211 mvi CCSCBCTL, CCSCBRESET;
2212 bmov CCSCBRAM, SCB_BASE, SCB_UPLOAD_SIZE;
2213 or CCSCBCTL, CCSCBEN|CCSCBRESET;
2214 test CCSCBCTL, CCSCBDONE jz .;
2215 } else if ((ahc->bugs & AHC_SCBCHAN_UPLOAD_BUG) != 0) {
2216 mvi CCSCBCTL, CCARREN|CCSCBRESET;
2217 cmp CCSCBCTL, ARRDONE|CCARREN jne .;
2218 mvi CCHCNT, SCB_UPLOAD_SIZE;
2219 mvi CCSCBCTL, CCSCBEN|CCSCBRESET;
2220 cmp CCSCBCTL, CCSCBDONE|CCSCBEN jne .;
2221 } else {
2222 mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET;
2223 cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .;
2224 }
2225dma_scb_finish:
2226 clr CCSCBCTL;
2227 test CCSCBCTL, CCARREN|CCSCBEN jnz .;
2228 ret;
2229 } else {
2230 mvi DINDEX, HADDR;
2231 mvi HSCB_ADDR call set_64byte_addr;
2232 mvi SCB_DOWNLOAD_SIZE call set_hcnt;
2233 mov DFCNTRL, DMAPARAMS;
2234 test DMAPARAMS, DIRECTION jnz dma_scb_fromhost;
2235 /* Fill it with the SCB data */
2236copy_scb_tofifo:
2237 mvi SINDEX, SCB_BASE;
2238 add A, SCB_DOWNLOAD_SIZE, SINDEX;
2239copy_scb_tofifo_loop:
2240 call copy_to_fifo_8;
2241 cmp SINDEX, A jne copy_scb_tofifo_loop;
2242 or DFCNTRL, HDMAEN|FIFOFLUSH;
2243 jmp dma_finish;
2244dma_scb_fromhost:
2245 mvi DINDEX, SCB_BASE;
2246 if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0) {
2247 /*
2248 * The PCI module will only issue a PCI
2249 * retry if the data FIFO is empty. If the
2250 * host disconnects in the middle of a
2251 * transfer, we must empty the fifo of all
2252 * available data to force the chip to
2253 * continue the transfer. This does not
2254 * happen for SCSI transfers as the SCSI module
2255 * will drain the FIFO as data are made available.
2256 * When the hang occurs, we know that a multiple
2257 * of 8 bytes is in the FIFO because the PCI
2258 * module has an 8 byte input latch that only
2259 * dumps to the FIFO when HCNT == 0 or the
2260 * latch is full.
2261 */
2262 clr A;
2263 /* Wait for at least 8 bytes of data to arrive. */
2264dma_scb_hang_fifo:
2265 test DFSTATUS, FIFOQWDEMP jnz dma_scb_hang_fifo;
2266dma_scb_hang_wait:
2267 test DFSTATUS, MREQPEND jnz dma_scb_hang_wait;
2268 test DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
2269 test DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
2270 test DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
2271 /*
2272 * The PCI module no longer intends to perform
2273 * a PCI transaction. Drain the fifo.
2274 */
2275dma_scb_hang_dma_drain_fifo:
2276 not A, HCNT;
2277 add A, SCB_DOWNLOAD_SIZE+SCB_BASE+1;
2278 and A, ~0x7;
2279 mov DINDIR,DFDAT;
2280 cmp DINDEX, A jne . - 1;
2281 cmp DINDEX, SCB_DOWNLOAD_SIZE+SCB_BASE
2282 je dma_finish_nowait;
2283 /* Restore A as the lines left to transfer. */
2284 add A, -SCB_BASE, DINDEX;
2285 shr A, 3;
2286 jmp dma_scb_hang_fifo;
2287dma_scb_hang_dma_done:
2288 and DFCNTRL, ~HDMAEN;
2289 test DFCNTRL, HDMAEN jnz .;
2290 add SEQADDR0, A;
2291 } else {
2292 call dma_finish;
2293 }
2294 call dfdat_in_8;
2295 call dfdat_in_8;
2296 call dfdat_in_8;
2297dfdat_in_8:
2298 mov DINDIR,DFDAT;
2299dfdat_in_7:
2300 mov DINDIR,DFDAT;
2301 mov DINDIR,DFDAT;
2302 mov DINDIR,DFDAT;
2303 mov DINDIR,DFDAT;
2304 mov DINDIR,DFDAT;
2305dfdat_in_2:
2306 mov DINDIR,DFDAT;
2307 mov DINDIR,DFDAT ret;
2308 }
2309
2310copy_to_fifo_8:
2311 mov DFDAT,SINDIR;
2312 mov DFDAT,SINDIR;
2313copy_to_fifo_6:
2314 mov DFDAT,SINDIR;
2315copy_to_fifo_5:
2316 mov DFDAT,SINDIR;
2317copy_to_fifo_4:
2318 mov DFDAT,SINDIR;
2319 mov DFDAT,SINDIR;
2320 mov DFDAT,SINDIR;
2321 mov DFDAT,SINDIR ret;
2322
2323/*
2324 * Wait for DMA from host memory to data FIFO to complete, then disable
2325 * DMA and wait for it to acknowledge that it's off.
2326 */
2327dma_finish:
2328 test DFSTATUS,HDONE jz dma_finish;
2329dma_finish_nowait:
2330 /* Turn off DMA */
2331 and DFCNTRL, ~HDMAEN;
2332 test DFCNTRL, HDMAEN jnz .;
2333 ret;
2334
2335/*
2336 * Restore an SCB that failed to match an incoming reselection
2337 * to the correct/safe state. If the SCB is for a disconnected
2338 * transaction, it must be returned to the disconnected list.
2339 * If it is not in the disconnected state, it must be free.
2340 */
2341cleanup_scb:
2342 if ((ahc->flags & AHC_PAGESCBS) != 0) {
2343 test SCB_CONTROL,DISCONNECTED jnz add_scb_to_disc_list;
2344 }
2345add_scb_to_free_list:
2346 if ((ahc->flags & AHC_PAGESCBS) != 0) {
2347BEGIN_CRITICAL;
2348 mov SCB_NEXT, FREE_SCBH;
2349 mvi SCB_TAG, SCB_LIST_NULL;
2350 mov FREE_SCBH, SCBPTR ret;
2351END_CRITICAL;
2352 } else {
2353 mvi SCB_TAG, SCB_LIST_NULL ret;
2354 }
2355
2356if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
2357set_hhaddr:
2358 or DSCOMMAND1, HADDLDSEL0;
2359 and HADDR, SG_HIGH_ADDR_BITS, SINDEX;
2360 and DSCOMMAND1, ~HADDLDSEL0 ret;
2361}
2362
2363if ((ahc->flags & AHC_PAGESCBS) != 0) {
2364get_free_or_disc_scb:
2365BEGIN_CRITICAL;
2366 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb;
2367 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb;
2368return_error:
2369 mvi NO_FREE_SCB call set_seqint;
2370 mvi SINDEX, SCB_LIST_NULL ret;
2371dequeue_disc_scb:
2372 mov SCBPTR, DISCONNECTED_SCBH;
2373 mov DISCONNECTED_SCBH, SCB_NEXT;
2374END_CRITICAL;
2375 mvi DMAPARAMS, FIFORESET;
2376 mov SCB_TAG jmp dma_scb;
2377BEGIN_CRITICAL;
2378dequeue_free_scb:
2379 mov SCBPTR, FREE_SCBH;
2380 mov FREE_SCBH, SCB_NEXT ret;
2381END_CRITICAL;
2382
2383add_scb_to_disc_list:
2384/*
2385 * Link this SCB into the DISCONNECTED list. This list holds the
2386 * candidates for paging out an SCB if one is needed for a new command.
2387 * Modifying the disconnected list is a critical(pause dissabled) section.
2388 */
2389BEGIN_CRITICAL;
2390 mov SCB_NEXT, DISCONNECTED_SCBH;
2391 mov DISCONNECTED_SCBH, SCBPTR ret;
2392END_CRITICAL;
2393}
2394set_seqint:
2395 mov INTSTAT, SINDEX;
2396 nop;
2397return:
2398 ret;
diff --git a/drivers/scsi/aic7xxx/aic7xxx_93cx6.c b/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
new file mode 100644
index 000000000000..468d612a44f6
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
@@ -0,0 +1,306 @@
1/*
2 * Interface for the 93C66/56/46/26/06 serial eeprom parts.
3 *
4 * Copyright (c) 1995, 1996 Daniel M. Eischen
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#17 $
32 *
33 * $FreeBSD$
34 */
35
36/*
37 * The instruction set of the 93C66/56/46/26/06 chips are as follows:
38 *
39 * Start OP *
40 * Function Bit Code Address** Data Description
41 * -------------------------------------------------------------------
42 * READ 1 10 A5 - A0 Reads data stored in memory,
43 * starting at specified address
44 * EWEN 1 00 11XXXX Write enable must precede
45 * all programming modes
46 * ERASE 1 11 A5 - A0 Erase register A5A4A3A2A1A0
47 * WRITE 1 01 A5 - A0 D15 - D0 Writes register
48 * ERAL 1 00 10XXXX Erase all registers
49 * WRAL 1 00 01XXXX D15 - D0 Writes to all registers
50 * EWDS 1 00 00XXXX Disables all programming
51 * instructions
52 * *Note: A value of X for address is a don't care condition.
53 * **Note: There are 8 address bits for the 93C56/66 chips unlike
54 * the 93C46/26/06 chips which have 6 address bits.
55 *
56 * The 93C46 has a four wire interface: clock, chip select, data in, and
57 * data out. In order to perform one of the above functions, you need
58 * to enable the chip select for a clock period (typically a minimum of
59 * 1 usec, with the clock high and low a minimum of 750 and 250 nsec
60 * respectively). While the chip select remains high, you can clock in
61 * the instructions (above) starting with the start bit, followed by the
62 * OP code, Address, and Data (if needed). For the READ instruction, the
63 * requested 16-bit register contents is read from the data out line but
64 * is preceded by an initial zero (leading 0, followed by 16-bits, MSB
65 * first). The clock cycling from low to high initiates the next data
66 * bit to be sent from the chip.
67 *
68 */
69
70#ifdef __linux__
71#include "aic7xxx_osm.h"
72#include "aic7xxx_inline.h"
73#include "aic7xxx_93cx6.h"
74#else
75#include <dev/aic7xxx/aic7xxx_osm.h>
76#include <dev/aic7xxx/aic7xxx_inline.h>
77#include <dev/aic7xxx/aic7xxx_93cx6.h>
78#endif
79
80/*
81 * Right now, we only have to read the SEEPROM. But we make it easier to
82 * add other 93Cx6 functions.
83 */
84static struct seeprom_cmd {
85 uint8_t len;
86 uint8_t bits[9];
87} seeprom_read = {3, {1, 1, 0}};
88
89static struct seeprom_cmd seeprom_ewen = {9, {1, 0, 0, 1, 1, 0, 0, 0, 0}};
90static struct seeprom_cmd seeprom_ewds = {9, {1, 0, 0, 0, 0, 0, 0, 0, 0}};
91static struct seeprom_cmd seeprom_write = {3, {1, 0, 1}};
92
93/*
94 * Wait for the SEERDY to go high; about 800 ns.
95 */
96#define CLOCK_PULSE(sd, rdy) \
97 while ((SEEPROM_STATUS_INB(sd) & rdy) == 0) { \
98 ; /* Do nothing */ \
99 } \
100 (void)SEEPROM_INB(sd); /* Clear clock */
101
102/*
103 * Send a START condition and the given command
104 */
105static void
106send_seeprom_cmd(struct seeprom_descriptor *sd, struct seeprom_cmd *cmd)
107{
108 uint8_t temp;
109 int i = 0;
110
111 /* Send chip select for one clock cycle. */
112 temp = sd->sd_MS ^ sd->sd_CS;
113 SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
114 CLOCK_PULSE(sd, sd->sd_RDY);
115
116 for (i = 0; i < cmd->len; i++) {
117 if (cmd->bits[i] != 0)
118 temp ^= sd->sd_DO;
119 SEEPROM_OUTB(sd, temp);
120 CLOCK_PULSE(sd, sd->sd_RDY);
121 SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
122 CLOCK_PULSE(sd, sd->sd_RDY);
123 if (cmd->bits[i] != 0)
124 temp ^= sd->sd_DO;
125 }
126}
127
128/*
129 * Clear CS put the chip in the reset state, where it can wait for new commands.
130 */
131static void
132reset_seeprom(struct seeprom_descriptor *sd)
133{
134 uint8_t temp;
135
136 temp = sd->sd_MS;
137 SEEPROM_OUTB(sd, temp);
138 CLOCK_PULSE(sd, sd->sd_RDY);
139 SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
140 CLOCK_PULSE(sd, sd->sd_RDY);
141 SEEPROM_OUTB(sd, temp);
142 CLOCK_PULSE(sd, sd->sd_RDY);
143}
144
145/*
146 * Read the serial EEPROM and returns 1 if successful and 0 if
147 * not successful.
148 */
149int
150ahc_read_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
151 u_int start_addr, u_int count)
152{
153 int i = 0;
154 u_int k = 0;
155 uint16_t v;
156 uint8_t temp;
157
158 /*
159 * Read the requested registers of the seeprom. The loop
160 * will range from 0 to count-1.
161 */
162 for (k = start_addr; k < count + start_addr; k++) {
163 /*
164 * Now we're ready to send the read command followed by the
165 * address of the 16-bit register we want to read.
166 */
167 send_seeprom_cmd(sd, &seeprom_read);
168
169 /* Send the 6 or 8 bit address (MSB first, LSB last). */
170 temp = sd->sd_MS ^ sd->sd_CS;
171 for (i = (sd->sd_chip - 1); i >= 0; i--) {
172 if ((k & (1 << i)) != 0)
173 temp ^= sd->sd_DO;
174 SEEPROM_OUTB(sd, temp);
175 CLOCK_PULSE(sd, sd->sd_RDY);
176 SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
177 CLOCK_PULSE(sd, sd->sd_RDY);
178 if ((k & (1 << i)) != 0)
179 temp ^= sd->sd_DO;
180 }
181
182 /*
183 * Now read the 16 bit register. An initial 0 precedes the
184 * register contents which begins with bit 15 (MSB) and ends
185 * with bit 0 (LSB). The initial 0 will be shifted off the
186 * top of our word as we let the loop run from 0 to 16.
187 */
188 v = 0;
189 for (i = 16; i >= 0; i--) {
190 SEEPROM_OUTB(sd, temp);
191 CLOCK_PULSE(sd, sd->sd_RDY);
192 v <<= 1;
193 if (SEEPROM_DATA_INB(sd) & sd->sd_DI)
194 v |= 1;
195 SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
196 CLOCK_PULSE(sd, sd->sd_RDY);
197 }
198
199 buf[k - start_addr] = v;
200
201 /* Reset the chip select for the next command cycle. */
202 reset_seeprom(sd);
203 }
204#ifdef AHC_DUMP_EEPROM
205 printf("\nSerial EEPROM:\n\t");
206 for (k = 0; k < count; k = k + 1) {
207 if (((k % 8) == 0) && (k != 0)) {
208 printf ("\n\t");
209 }
210 printf (" 0x%x", buf[k]);
211 }
212 printf ("\n");
213#endif
214 return (1);
215}
216
217/*
218 * Write the serial EEPROM and return 1 if successful and 0 if
219 * not successful.
220 */
221int
222ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
223 u_int start_addr, u_int count)
224{
225 uint16_t v;
226 uint8_t temp;
227 int i, k;
228
229 /* Place the chip into write-enable mode */
230 send_seeprom_cmd(sd, &seeprom_ewen);
231 reset_seeprom(sd);
232
233 /* Write all requested data out to the seeprom. */
234 temp = sd->sd_MS ^ sd->sd_CS;
235 for (k = start_addr; k < count + start_addr; k++) {
236 /* Send the write command */
237 send_seeprom_cmd(sd, &seeprom_write);
238
239 /* Send the 6 or 8 bit address (MSB first). */
240 for (i = (sd->sd_chip - 1); i >= 0; i--) {
241 if ((k & (1 << i)) != 0)
242 temp ^= sd->sd_DO;
243 SEEPROM_OUTB(sd, temp);
244 CLOCK_PULSE(sd, sd->sd_RDY);
245 SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
246 CLOCK_PULSE(sd, sd->sd_RDY);
247 if ((k & (1 << i)) != 0)
248 temp ^= sd->sd_DO;
249 }
250
251 /* Write the 16 bit value, MSB first */
252 v = buf[k - start_addr];
253 for (i = 15; i >= 0; i--) {
254 if ((v & (1 << i)) != 0)
255 temp ^= sd->sd_DO;
256 SEEPROM_OUTB(sd, temp);
257 CLOCK_PULSE(sd, sd->sd_RDY);
258 SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
259 CLOCK_PULSE(sd, sd->sd_RDY);
260 if ((v & (1 << i)) != 0)
261 temp ^= sd->sd_DO;
262 }
263
264 /* Wait for the chip to complete the write */
265 temp = sd->sd_MS;
266 SEEPROM_OUTB(sd, temp);
267 CLOCK_PULSE(sd, sd->sd_RDY);
268 temp = sd->sd_MS ^ sd->sd_CS;
269 do {
270 SEEPROM_OUTB(sd, temp);
271 CLOCK_PULSE(sd, sd->sd_RDY);
272 SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
273 CLOCK_PULSE(sd, sd->sd_RDY);
274 } while ((SEEPROM_DATA_INB(sd) & sd->sd_DI) == 0);
275
276 reset_seeprom(sd);
277 }
278
279 /* Put the chip back into write-protect mode */
280 send_seeprom_cmd(sd, &seeprom_ewds);
281 reset_seeprom(sd);
282
283 return (1);
284}
285
286int
287ahc_verify_cksum(struct seeprom_config *sc)
288{
289 int i;
290 int maxaddr;
291 uint32_t checksum;
292 uint16_t *scarray;
293
294 maxaddr = (sizeof(*sc)/2) - 1;
295 checksum = 0;
296 scarray = (uint16_t *)sc;
297
298 for (i = 0; i < maxaddr; i++)
299 checksum = checksum + scarray[i];
300 if (checksum == 0
301 || (checksum & 0xFFFF) != sc->checksum) {
302 return (0);
303 } else {
304 return(1);
305 }
306}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_93cx6.h b/drivers/scsi/aic7xxx/aic7xxx_93cx6.h
new file mode 100644
index 000000000000..859c43ccdd46
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_93cx6.h
@@ -0,0 +1,102 @@
1/*
2 * Interface to the 93C46/56 serial EEPROM that is used to store BIOS
3 * settings for the aic7xxx based adaptec SCSI controllers. It can
4 * also be used for 93C26 and 93C06 serial EEPROMS.
5 *
6 * Copyright (c) 1994, 1995, 2000 Justin T. Gibbs.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * substantially similar to the "NO WARRANTY" disclaimer below
17 * ("Disclaimer") and any redistribution must be conditioned upon
18 * including a substantially similar Disclaimer requirement for further
19 * binary redistribution.
20 * 3. Neither the names of the above-listed copyright holders nor the names
21 * of any contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * Alternatively, this software may be distributed under the terms of the
25 * GNU General Public License ("GPL") version 2 as published by the Free
26 * Software Foundation.
27 *
28 * NO WARRANTY
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGES.
40 *
41 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.h#12 $
42 *
43 * $FreeBSD$
44 */
45#ifndef _AIC7XXX_93CX6_H_
46#define _AIC7XXX_93CX6_H_
47
48typedef enum {
49 C46 = 6,
50 C56_66 = 8
51} seeprom_chip_t;
52
53struct seeprom_descriptor {
54 struct ahc_softc *sd_ahc;
55 u_int sd_control_offset;
56 u_int sd_status_offset;
57 u_int sd_dataout_offset;
58 seeprom_chip_t sd_chip;
59 uint16_t sd_MS;
60 uint16_t sd_RDY;
61 uint16_t sd_CS;
62 uint16_t sd_CK;
63 uint16_t sd_DO;
64 uint16_t sd_DI;
65};
66
67/*
68 * This function will read count 16-bit words from the serial EEPROM and
69 * return their value in buf. The port address of the aic7xxx serial EEPROM
70 * control register is passed in as offset. The following parameters are
71 * also passed in:
72 *
73 * CS - Chip select
74 * CK - Clock
75 * DO - Data out
76 * DI - Data in
77 * RDY - SEEPROM ready
78 * MS - Memory port mode select
79 *
80 * A failed read attempt returns 0, and a successful read returns 1.
81 */
82
83#define SEEPROM_INB(sd) \
84 ahc_inb(sd->sd_ahc, sd->sd_control_offset)
85#define SEEPROM_OUTB(sd, value) \
86do { \
87 ahc_outb(sd->sd_ahc, sd->sd_control_offset, value); \
88 ahc_flush_device_writes(sd->sd_ahc); \
89} while(0)
90
91#define SEEPROM_STATUS_INB(sd) \
92 ahc_inb(sd->sd_ahc, sd->sd_status_offset)
93#define SEEPROM_DATA_INB(sd) \
94 ahc_inb(sd->sd_ahc, sd->sd_dataout_offset)
95
96int ahc_read_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
97 u_int start_addr, u_int count);
98int ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
99 u_int start_addr, u_int count);
100int ahc_verify_cksum(struct seeprom_config *sc);
101
102#endif /* _AIC7XXX_93CX6_H_ */
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
new file mode 100644
index 000000000000..9a6b4a570aa7
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -0,0 +1,7451 @@
1/*
2 * Core routines and tables shareable across OS platforms.
3 *
4 * Copyright (c) 1994-2002 Justin T. Gibbs.
5 * Copyright (c) 2000-2002 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#134 $
41 *
42 * $FreeBSD$
43 */
44
45#ifdef __linux__
46#include "aic7xxx_osm.h"
47#include "aic7xxx_inline.h"
48#include "aicasm/aicasm_insformat.h"
49#else
50#include <dev/aic7xxx/aic7xxx_osm.h>
51#include <dev/aic7xxx/aic7xxx_inline.h>
52#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
53#endif
54
55/****************************** Softc Data ************************************/
56struct ahc_softc_tailq ahc_tailq = TAILQ_HEAD_INITIALIZER(ahc_tailq);
57
58/***************************** Lookup Tables **********************************/
59char *ahc_chip_names[] =
60{
61 "NONE",
62 "aic7770",
63 "aic7850",
64 "aic7855",
65 "aic7859",
66 "aic7860",
67 "aic7870",
68 "aic7880",
69 "aic7895",
70 "aic7895C",
71 "aic7890/91",
72 "aic7896/97",
73 "aic7892",
74 "aic7899"
75};
76static const u_int num_chip_names = NUM_ELEMENTS(ahc_chip_names);
77
78/*
79 * Hardware error codes.
80 */
81struct ahc_hard_error_entry {
82 uint8_t errno;
83 char *errmesg;
84};
85
86static struct ahc_hard_error_entry ahc_hard_errors[] = {
87 { ILLHADDR, "Illegal Host Access" },
88 { ILLSADDR, "Illegal Sequencer Address referrenced" },
89 { ILLOPCODE, "Illegal Opcode in sequencer program" },
90 { SQPARERR, "Sequencer Parity Error" },
91 { DPARERR, "Data-path Parity Error" },
92 { MPARERR, "Scratch or SCB Memory Parity Error" },
93 { PCIERRSTAT, "PCI Error detected" },
94 { CIOPARERR, "CIOBUS Parity Error" },
95};
96static const u_int num_errors = NUM_ELEMENTS(ahc_hard_errors);
97
98static struct ahc_phase_table_entry ahc_phase_table[] =
99{
100 { P_DATAOUT, MSG_NOOP, "in Data-out phase" },
101 { P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" },
102 { P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" },
103 { P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" },
104 { P_COMMAND, MSG_NOOP, "in Command phase" },
105 { P_MESGOUT, MSG_NOOP, "in Message-out phase" },
106 { P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" },
107 { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
108 { P_BUSFREE, MSG_NOOP, "while idle" },
109 { 0, MSG_NOOP, "in unknown phase" }
110};
111
112/*
113 * In most cases we only wish to itterate over real phases, so
114 * exclude the last element from the count.
115 */
116static const u_int num_phases = NUM_ELEMENTS(ahc_phase_table) - 1;
117
118/*
119 * Valid SCSIRATE values. (p. 3-17)
120 * Provides a mapping of tranfer periods in ns to the proper value to
121 * stick in the scsixfer reg.
122 */
123static struct ahc_syncrate ahc_syncrates[] =
124{
125 /* ultra2 fast/ultra period rate */
126 { 0x42, 0x000, 9, "80.0" },
127 { 0x03, 0x000, 10, "40.0" },
128 { 0x04, 0x000, 11, "33.0" },
129 { 0x05, 0x100, 12, "20.0" },
130 { 0x06, 0x110, 15, "16.0" },
131 { 0x07, 0x120, 18, "13.4" },
132 { 0x08, 0x000, 25, "10.0" },
133 { 0x19, 0x010, 31, "8.0" },
134 { 0x1a, 0x020, 37, "6.67" },
135 { 0x1b, 0x030, 43, "5.7" },
136 { 0x1c, 0x040, 50, "5.0" },
137 { 0x00, 0x050, 56, "4.4" },
138 { 0x00, 0x060, 62, "4.0" },
139 { 0x00, 0x070, 68, "3.6" },
140 { 0x00, 0x000, 0, NULL }
141};
142
143/* Our Sequencer Program */
144#include "aic7xxx_seq.h"
145
146/**************************** Function Declarations ***************************/
147static void ahc_force_renegotiation(struct ahc_softc *ahc,
148 struct ahc_devinfo *devinfo);
149static struct ahc_tmode_tstate*
150 ahc_alloc_tstate(struct ahc_softc *ahc,
151 u_int scsi_id, char channel);
152#ifdef AHC_TARGET_MODE
153static void ahc_free_tstate(struct ahc_softc *ahc,
154 u_int scsi_id, char channel, int force);
155#endif
156static struct ahc_syncrate*
157 ahc_devlimited_syncrate(struct ahc_softc *ahc,
158 struct ahc_initiator_tinfo *,
159 u_int *period,
160 u_int *ppr_options,
161 role_t role);
162static void ahc_update_pending_scbs(struct ahc_softc *ahc);
163static void ahc_fetch_devinfo(struct ahc_softc *ahc,
164 struct ahc_devinfo *devinfo);
165static void ahc_scb_devinfo(struct ahc_softc *ahc,
166 struct ahc_devinfo *devinfo,
167 struct scb *scb);
168static void ahc_assert_atn(struct ahc_softc *ahc);
169static void ahc_setup_initiator_msgout(struct ahc_softc *ahc,
170 struct ahc_devinfo *devinfo,
171 struct scb *scb);
172static void ahc_build_transfer_msg(struct ahc_softc *ahc,
173 struct ahc_devinfo *devinfo);
174static void ahc_construct_sdtr(struct ahc_softc *ahc,
175 struct ahc_devinfo *devinfo,
176 u_int period, u_int offset);
177static void ahc_construct_wdtr(struct ahc_softc *ahc,
178 struct ahc_devinfo *devinfo,
179 u_int bus_width);
180static void ahc_construct_ppr(struct ahc_softc *ahc,
181 struct ahc_devinfo *devinfo,
182 u_int period, u_int offset,
183 u_int bus_width, u_int ppr_options);
184static void ahc_clear_msg_state(struct ahc_softc *ahc);
185static void ahc_handle_proto_violation(struct ahc_softc *ahc);
186static void ahc_handle_message_phase(struct ahc_softc *ahc);
187typedef enum {
188 AHCMSG_1B,
189 AHCMSG_2B,
190 AHCMSG_EXT
191} ahc_msgtype;
192static int ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type,
193 u_int msgval, int full);
194static int ahc_parse_msg(struct ahc_softc *ahc,
195 struct ahc_devinfo *devinfo);
196static int ahc_handle_msg_reject(struct ahc_softc *ahc,
197 struct ahc_devinfo *devinfo);
198static void ahc_handle_ign_wide_residue(struct ahc_softc *ahc,
199 struct ahc_devinfo *devinfo);
200static void ahc_reinitialize_dataptrs(struct ahc_softc *ahc);
201static void ahc_handle_devreset(struct ahc_softc *ahc,
202 struct ahc_devinfo *devinfo,
203 cam_status status, char *message,
204 int verbose_level);
205#ifdef AHC_TARGET_MODE
206static void ahc_setup_target_msgin(struct ahc_softc *ahc,
207 struct ahc_devinfo *devinfo,
208 struct scb *scb);
209#endif
210
211static bus_dmamap_callback_t ahc_dmamap_cb;
212static void ahc_build_free_scb_list(struct ahc_softc *ahc);
213static int ahc_init_scbdata(struct ahc_softc *ahc);
214static void ahc_fini_scbdata(struct ahc_softc *ahc);
215static void ahc_qinfifo_requeue(struct ahc_softc *ahc,
216 struct scb *prev_scb,
217 struct scb *scb);
218static int ahc_qinfifo_count(struct ahc_softc *ahc);
219static u_int ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,
220 u_int prev, u_int scbptr);
221static void ahc_add_curscb_to_free_list(struct ahc_softc *ahc);
222static u_int ahc_rem_wscb(struct ahc_softc *ahc,
223 u_int scbpos, u_int prev);
224static void ahc_reset_current_bus(struct ahc_softc *ahc);
225#ifdef AHC_DUMP_SEQ
226static void ahc_dumpseq(struct ahc_softc *ahc);
227#endif
228static int ahc_loadseq(struct ahc_softc *ahc);
229static int ahc_check_patch(struct ahc_softc *ahc,
230 struct patch **start_patch,
231 u_int start_instr, u_int *skip_addr);
232static void ahc_download_instr(struct ahc_softc *ahc,
233 u_int instrptr, uint8_t *dconsts);
234#ifdef AHC_TARGET_MODE
235static void ahc_queue_lstate_event(struct ahc_softc *ahc,
236 struct ahc_tmode_lstate *lstate,
237 u_int initiator_id,
238 u_int event_type,
239 u_int event_arg);
240static void ahc_update_scsiid(struct ahc_softc *ahc,
241 u_int targid_mask);
242static int ahc_handle_target_cmd(struct ahc_softc *ahc,
243 struct target_cmd *cmd);
244#endif
245/************************* Sequencer Execution Control ************************/
246/*
247 * Restart the sequencer program from address zero
248 */
249void
250ahc_restart(struct ahc_softc *ahc)
251{
252
253 ahc_pause(ahc);
254
255 /* No more pending messages. */
256 ahc_clear_msg_state(ahc);
257
258 ahc_outb(ahc, SCSISIGO, 0); /* De-assert BSY */
259 ahc_outb(ahc, MSG_OUT, MSG_NOOP); /* No message to send */
260 ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
261 ahc_outb(ahc, LASTPHASE, P_BUSFREE);
262 ahc_outb(ahc, SAVED_SCSIID, 0xFF);
263 ahc_outb(ahc, SAVED_LUN, 0xFF);
264
265 /*
266 * Ensure that the sequencer's idea of TQINPOS
267 * matches our own. The sequencer increments TQINPOS
268 * only after it sees a DMA complete and a reset could
269 * occur before the increment leaving the kernel to believe
270 * the command arrived but the sequencer to not.
271 */
272 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
273
274 /* Always allow reselection */
275 ahc_outb(ahc, SCSISEQ,
276 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
277 if ((ahc->features & AHC_CMD_CHAN) != 0) {
278 /* Ensure that no DMA operations are in progress */
279 ahc_outb(ahc, CCSCBCNT, 0);
280 ahc_outb(ahc, CCSGCTL, 0);
281 ahc_outb(ahc, CCSCBCTL, 0);
282 }
283 /*
284 * If we were in the process of DMA'ing SCB data into
285 * an SCB, replace that SCB on the free list. This prevents
286 * an SCB leak.
287 */
288 if ((ahc_inb(ahc, SEQ_FLAGS2) & SCB_DMA) != 0) {
289 ahc_add_curscb_to_free_list(ahc);
290 ahc_outb(ahc, SEQ_FLAGS2,
291 ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
292 }
293 ahc_outb(ahc, MWI_RESIDUAL, 0);
294 ahc_outb(ahc, SEQCTL, ahc->seqctl);
295 ahc_outb(ahc, SEQADDR0, 0);
296 ahc_outb(ahc, SEQADDR1, 0);
297 ahc_unpause(ahc);
298}
299
300/************************* Input/Output Queues ********************************/
301void
302ahc_run_qoutfifo(struct ahc_softc *ahc)
303{
304 struct scb *scb;
305 u_int scb_index;
306
307 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
308 while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {
309
310 scb_index = ahc->qoutfifo[ahc->qoutfifonext];
311 if ((ahc->qoutfifonext & 0x03) == 0x03) {
312 u_int modnext;
313
314 /*
315 * Clear 32bits of QOUTFIFO at a time
316 * so that we don't clobber an incoming
317 * byte DMA to the array on architectures
318 * that only support 32bit load and store
319 * operations.
320 */
321 modnext = ahc->qoutfifonext & ~0x3;
322 *((uint32_t *)(&ahc->qoutfifo[modnext])) = 0xFFFFFFFFUL;
323 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
324 ahc->shared_data_dmamap,
325 /*offset*/modnext, /*len*/4,
326 BUS_DMASYNC_PREREAD);
327 }
328 ahc->qoutfifonext++;
329
330 scb = ahc_lookup_scb(ahc, scb_index);
331 if (scb == NULL) {
332 printf("%s: WARNING no command for scb %d "
333 "(cmdcmplt)\nQOUTPOS = %d\n",
334 ahc_name(ahc), scb_index,
335 (ahc->qoutfifonext - 1) & 0xFF);
336 continue;
337 }
338
339 /*
340 * Save off the residual
341 * if there is one.
342 */
343 ahc_update_residual(ahc, scb);
344 ahc_done(ahc, scb);
345 }
346}
347
348void
349ahc_run_untagged_queues(struct ahc_softc *ahc)
350{
351 int i;
352
353 for (i = 0; i < 16; i++)
354 ahc_run_untagged_queue(ahc, &ahc->untagged_queues[i]);
355}
356
357void
358ahc_run_untagged_queue(struct ahc_softc *ahc, struct scb_tailq *queue)
359{
360 struct scb *scb;
361
362 if (ahc->untagged_queue_lock != 0)
363 return;
364
365 if ((scb = TAILQ_FIRST(queue)) != NULL
366 && (scb->flags & SCB_ACTIVE) == 0) {
367 scb->flags |= SCB_ACTIVE;
368 ahc_queue_scb(ahc, scb);
369 }
370}
371
372/************************* Interrupt Handling *********************************/
373void
374ahc_handle_brkadrint(struct ahc_softc *ahc)
375{
376 /*
377 * We upset the sequencer :-(
378 * Lookup the error message
379 */
380 int i;
381 int error;
382
383 error = ahc_inb(ahc, ERROR);
384 for (i = 0; error != 1 && i < num_errors; i++)
385 error >>= 1;
386 printf("%s: brkadrint, %s at seqaddr = 0x%x\n",
387 ahc_name(ahc), ahc_hard_errors[i].errmesg,
388 ahc_inb(ahc, SEQADDR0) |
389 (ahc_inb(ahc, SEQADDR1) << 8));
390
391 ahc_dump_card_state(ahc);
392
393 /* Tell everyone that this HBA is no longer available */
394 ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
395 CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
396 CAM_NO_HBA);
397
398 /* Disable all interrupt sources by resetting the controller */
399 ahc_shutdown(ahc);
400}
401
402void
403ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
404{
405 struct scb *scb;
406 struct ahc_devinfo devinfo;
407
408 ahc_fetch_devinfo(ahc, &devinfo);
409
410 /*
411 * Clear the upper byte that holds SEQINT status
412 * codes and clear the SEQINT bit. We will unpause
413 * the sequencer, if appropriate, after servicing
414 * the request.
415 */
416 ahc_outb(ahc, CLRINT, CLRSEQINT);
417 switch (intstat & SEQINT_MASK) {
418 case BAD_STATUS:
419 {
420 u_int scb_index;
421 struct hardware_scb *hscb;
422
423 /*
424 * Set the default return value to 0 (don't
425 * send sense). The sense code will change
426 * this if needed.
427 */
428 ahc_outb(ahc, RETURN_1, 0);
429
430 /*
431 * The sequencer will notify us when a command
432 * has an error that would be of interest to
433 * the kernel. This allows us to leave the sequencer
434 * running in the common case of command completes
435 * without error. The sequencer will already have
436 * dma'd the SCB back up to us, so we can reference
437 * the in kernel copy directly.
438 */
439 scb_index = ahc_inb(ahc, SCB_TAG);
440 scb = ahc_lookup_scb(ahc, scb_index);
441 if (scb == NULL) {
442 ahc_print_devinfo(ahc, &devinfo);
443 printf("ahc_intr - referenced scb "
444 "not valid during seqint 0x%x scb(%d)\n",
445 intstat, scb_index);
446 ahc_dump_card_state(ahc);
447 panic("for safety");
448 goto unpause;
449 }
450
451 hscb = scb->hscb;
452
453 /* Don't want to clobber the original sense code */
454 if ((scb->flags & SCB_SENSE) != 0) {
455 /*
456 * Clear the SCB_SENSE Flag and have
457 * the sequencer do a normal command
458 * complete.
459 */
460 scb->flags &= ~SCB_SENSE;
461 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
462 break;
463 }
464 ahc_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
465 /* Freeze the queue until the client sees the error. */
466 ahc_freeze_devq(ahc, scb);
467 ahc_freeze_scb(scb);
468 ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
469 switch (hscb->shared_data.status.scsi_status) {
470 case SCSI_STATUS_OK:
471 printf("%s: Interrupted for staus of 0???\n",
472 ahc_name(ahc));
473 break;
474 case SCSI_STATUS_CMD_TERMINATED:
475 case SCSI_STATUS_CHECK_COND:
476 {
477 struct ahc_dma_seg *sg;
478 struct scsi_sense *sc;
479 struct ahc_initiator_tinfo *targ_info;
480 struct ahc_tmode_tstate *tstate;
481 struct ahc_transinfo *tinfo;
482#ifdef AHC_DEBUG
483 if (ahc_debug & AHC_SHOW_SENSE) {
484 ahc_print_path(ahc, scb);
485 printf("SCB %d: requests Check Status\n",
486 scb->hscb->tag);
487 }
488#endif
489
490 if (ahc_perform_autosense(scb) == 0)
491 break;
492
493 targ_info = ahc_fetch_transinfo(ahc,
494 devinfo.channel,
495 devinfo.our_scsiid,
496 devinfo.target,
497 &tstate);
498 tinfo = &targ_info->curr;
499 sg = scb->sg_list;
500 sc = (struct scsi_sense *)(&hscb->shared_data.cdb);
501 /*
502 * Save off the residual if there is one.
503 */
504 ahc_update_residual(ahc, scb);
505#ifdef AHC_DEBUG
506 if (ahc_debug & AHC_SHOW_SENSE) {
507 ahc_print_path(ahc, scb);
508 printf("Sending Sense\n");
509 }
510#endif
511 sg->addr = ahc_get_sense_bufaddr(ahc, scb);
512 sg->len = ahc_get_sense_bufsize(ahc, scb);
513 sg->len |= AHC_DMA_LAST_SEG;
514
515 /* Fixup byte order */
516 sg->addr = ahc_htole32(sg->addr);
517 sg->len = ahc_htole32(sg->len);
518
519 sc->opcode = REQUEST_SENSE;
520 sc->byte2 = 0;
521 if (tinfo->protocol_version <= SCSI_REV_2
522 && SCB_GET_LUN(scb) < 8)
523 sc->byte2 = SCB_GET_LUN(scb) << 5;
524 sc->unused[0] = 0;
525 sc->unused[1] = 0;
526 sc->length = sg->len;
527 sc->control = 0;
528
529 /*
530 * We can't allow the target to disconnect.
531 * This will be an untagged transaction and
532 * having the target disconnect will make this
533 * transaction indestinguishable from outstanding
534 * tagged transactions.
535 */
536 hscb->control = 0;
537
538 /*
539 * This request sense could be because the
540 * the device lost power or in some other
541 * way has lost our transfer negotiations.
542 * Renegotiate if appropriate. Unit attention
543 * errors will be reported before any data
544 * phases occur.
545 */
546 if (ahc_get_residual(scb)
547 == ahc_get_transfer_length(scb)) {
548 ahc_update_neg_request(ahc, &devinfo,
549 tstate, targ_info,
550 AHC_NEG_IF_NON_ASYNC);
551 }
552 if (tstate->auto_negotiate & devinfo.target_mask) {
553 hscb->control |= MK_MESSAGE;
554 scb->flags &= ~SCB_NEGOTIATE;
555 scb->flags |= SCB_AUTO_NEGOTIATE;
556 }
557 hscb->cdb_len = sizeof(*sc);
558 hscb->dataptr = sg->addr;
559 hscb->datacnt = sg->len;
560 hscb->sgptr = scb->sg_list_phys | SG_FULL_RESID;
561 hscb->sgptr = ahc_htole32(hscb->sgptr);
562 scb->sg_count = 1;
563 scb->flags |= SCB_SENSE;
564 ahc_qinfifo_requeue_tail(ahc, scb);
565 ahc_outb(ahc, RETURN_1, SEND_SENSE);
566 /*
567 * Ensure we have enough time to actually
568 * retrieve the sense.
569 */
570 ahc_scb_timer_reset(scb, 5 * 1000000);
571 break;
572 }
573 default:
574 break;
575 }
576 break;
577 }
578 case NO_MATCH:
579 {
580 /* Ensure we don't leave the selection hardware on */
581 ahc_outb(ahc, SCSISEQ,
582 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
583
584 printf("%s:%c:%d: no active SCB for reconnecting "
585 "target - issuing BUS DEVICE RESET\n",
586 ahc_name(ahc), devinfo.channel, devinfo.target);
587 printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
588 "ARG_1 == 0x%x ACCUM = 0x%x\n",
589 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
590 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
591 printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
592 "SINDEX == 0x%x\n",
593 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
594 ahc_index_busy_tcl(ahc,
595 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
596 ahc_inb(ahc, SAVED_LUN))),
597 ahc_inb(ahc, SINDEX));
598 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
599 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
600 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
601 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
602 ahc_inb(ahc, SCB_CONTROL));
603 printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
604 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
605 printf("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
606 printf("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
607 ahc_dump_card_state(ahc);
608 ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
609 ahc->msgout_len = 1;
610 ahc->msgout_index = 0;
611 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
612 ahc_outb(ahc, MSG_OUT, HOST_MSG);
613 ahc_assert_atn(ahc);
614 break;
615 }
616 case SEND_REJECT:
617 {
618 u_int rejbyte = ahc_inb(ahc, ACCUM);
619 printf("%s:%c:%d: Warning - unknown message received from "
620 "target (0x%x). Rejecting\n",
621 ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
622 break;
623 }
624 case PROTO_VIOLATION:
625 {
626 ahc_handle_proto_violation(ahc);
627 break;
628 }
629 case IGN_WIDE_RES:
630 ahc_handle_ign_wide_residue(ahc, &devinfo);
631 break;
632 case PDATA_REINIT:
633 ahc_reinitialize_dataptrs(ahc);
634 break;
635 case BAD_PHASE:
636 {
637 u_int lastphase;
638
639 lastphase = ahc_inb(ahc, LASTPHASE);
640 printf("%s:%c:%d: unknown scsi bus phase %x, "
641 "lastphase = 0x%x. Attempting to continue\n",
642 ahc_name(ahc), devinfo.channel, devinfo.target,
643 lastphase, ahc_inb(ahc, SCSISIGI));
644 break;
645 }
646 case MISSED_BUSFREE:
647 {
648 u_int lastphase;
649
650 lastphase = ahc_inb(ahc, LASTPHASE);
651 printf("%s:%c:%d: Missed busfree. "
652 "Lastphase = 0x%x, Curphase = 0x%x\n",
653 ahc_name(ahc), devinfo.channel, devinfo.target,
654 lastphase, ahc_inb(ahc, SCSISIGI));
655 ahc_restart(ahc);
656 return;
657 }
658 case HOST_MSG_LOOP:
659 {
660 /*
661 * The sequencer has encountered a message phase
662 * that requires host assistance for completion.
663 * While handling the message phase(s), we will be
664 * notified by the sequencer after each byte is
665 * transfered so we can track bus phase changes.
666 *
667 * If this is the first time we've seen a HOST_MSG_LOOP
668 * interrupt, initialize the state of the host message
669 * loop.
670 */
671 if (ahc->msg_type == MSG_TYPE_NONE) {
672 struct scb *scb;
673 u_int scb_index;
674 u_int bus_phase;
675
676 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
677 if (bus_phase != P_MESGIN
678 && bus_phase != P_MESGOUT) {
679 printf("ahc_intr: HOST_MSG_LOOP bad "
680 "phase 0x%x\n",
681 bus_phase);
682 /*
683 * Probably transitioned to bus free before
684 * we got here. Just punt the message.
685 */
686 ahc_clear_intstat(ahc);
687 ahc_restart(ahc);
688 return;
689 }
690
691 scb_index = ahc_inb(ahc, SCB_TAG);
692 scb = ahc_lookup_scb(ahc, scb_index);
693 if (devinfo.role == ROLE_INITIATOR) {
694 if (scb == NULL)
695 panic("HOST_MSG_LOOP with "
696 "invalid SCB %x\n", scb_index);
697
698 if (bus_phase == P_MESGOUT)
699 ahc_setup_initiator_msgout(ahc,
700 &devinfo,
701 scb);
702 else {
703 ahc->msg_type =
704 MSG_TYPE_INITIATOR_MSGIN;
705 ahc->msgin_index = 0;
706 }
707 }
708#ifdef AHC_TARGET_MODE
709 else {
710 if (bus_phase == P_MESGOUT) {
711 ahc->msg_type =
712 MSG_TYPE_TARGET_MSGOUT;
713 ahc->msgin_index = 0;
714 }
715 else
716 ahc_setup_target_msgin(ahc,
717 &devinfo,
718 scb);
719 }
720#endif
721 }
722
723 ahc_handle_message_phase(ahc);
724 break;
725 }
726 case PERR_DETECTED:
727 {
728 /*
729 * If we've cleared the parity error interrupt
730 * but the sequencer still believes that SCSIPERR
731 * is true, it must be that the parity error is
732 * for the currently presented byte on the bus,
733 * and we are not in a phase (data-in) where we will
734 * eventually ack this byte. Ack the byte and
735 * throw it away in the hope that the target will
736 * take us to message out to deliver the appropriate
737 * error message.
738 */
739 if ((intstat & SCSIINT) == 0
740 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {
741
742 if ((ahc->features & AHC_DT) == 0) {
743 u_int curphase;
744
745 /*
746 * The hardware will only let you ack bytes
747 * if the expected phase in SCSISIGO matches
748 * the current phase. Make sure this is
749 * currently the case.
750 */
751 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
752 ahc_outb(ahc, LASTPHASE, curphase);
753 ahc_outb(ahc, SCSISIGO, curphase);
754 }
755 if ((ahc_inb(ahc, SCSISIGI) & (CDI|MSGI)) == 0) {
756 int wait;
757
758 /*
759 * In a data phase. Faster to bitbucket
760 * the data than to individually ack each
761 * byte. This is also the only strategy
762 * that will work with AUTOACK enabled.
763 */
764 ahc_outb(ahc, SXFRCTL1,
765 ahc_inb(ahc, SXFRCTL1) | BITBUCKET);
766 wait = 5000;
767 while (--wait != 0) {
768 if ((ahc_inb(ahc, SCSISIGI)
769 & (CDI|MSGI)) != 0)
770 break;
771 ahc_delay(100);
772 }
773 ahc_outb(ahc, SXFRCTL1,
774 ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
775 if (wait == 0) {
776 struct scb *scb;
777 u_int scb_index;
778
779 ahc_print_devinfo(ahc, &devinfo);
780 printf("Unable to clear parity error. "
781 "Resetting bus.\n");
782 scb_index = ahc_inb(ahc, SCB_TAG);
783 scb = ahc_lookup_scb(ahc, scb_index);
784 if (scb != NULL)
785 ahc_set_transaction_status(scb,
786 CAM_UNCOR_PARITY);
787 ahc_reset_channel(ahc, devinfo.channel,
788 /*init reset*/TRUE);
789 }
790 } else {
791 ahc_inb(ahc, SCSIDATL);
792 }
793 }
794 break;
795 }
796 case DATA_OVERRUN:
797 {
798 /*
799 * When the sequencer detects an overrun, it
800 * places the controller in "BITBUCKET" mode
801 * and allows the target to complete its transfer.
802 * Unfortunately, none of the counters get updated
803 * when the controller is in this mode, so we have
804 * no way of knowing how large the overrun was.
805 */
806 u_int scbindex = ahc_inb(ahc, SCB_TAG);
807 u_int lastphase = ahc_inb(ahc, LASTPHASE);
808 u_int i;
809
810 scb = ahc_lookup_scb(ahc, scbindex);
811 for (i = 0; i < num_phases; i++) {
812 if (lastphase == ahc_phase_table[i].phase)
813 break;
814 }
815 ahc_print_path(ahc, scb);
816 printf("data overrun detected %s."
817 " Tag == 0x%x.\n",
818 ahc_phase_table[i].phasemsg,
819 scb->hscb->tag);
820 ahc_print_path(ahc, scb);
821 printf("%s seen Data Phase. Length = %ld. NumSGs = %d.\n",
822 ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
823 ahc_get_transfer_length(scb), scb->sg_count);
824 if (scb->sg_count > 0) {
825 for (i = 0; i < scb->sg_count; i++) {
826
827 printf("sg[%d] - Addr 0x%x%x : Length %d\n",
828 i,
829 (ahc_le32toh(scb->sg_list[i].len) >> 24
830 & SG_HIGH_ADDR_BITS),
831 ahc_le32toh(scb->sg_list[i].addr),
832 ahc_le32toh(scb->sg_list[i].len)
833 & AHC_SG_LEN_MASK);
834 }
835 }
836 /*
837 * Set this and it will take effect when the
838 * target does a command complete.
839 */
840 ahc_freeze_devq(ahc, scb);
841 if ((scb->flags & SCB_SENSE) == 0) {
842 ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
843 } else {
844 scb->flags &= ~SCB_SENSE;
845 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
846 }
847 ahc_freeze_scb(scb);
848
849 if ((ahc->features & AHC_ULTRA2) != 0) {
850 /*
851 * Clear the channel in case we return
852 * to data phase later.
853 */
854 ahc_outb(ahc, SXFRCTL0,
855 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
856 ahc_outb(ahc, SXFRCTL0,
857 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
858 }
859 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
860 u_int dscommand1;
861
862 /* Ensure HHADDR is 0 for future DMA operations. */
863 dscommand1 = ahc_inb(ahc, DSCOMMAND1);
864 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
865 ahc_outb(ahc, HADDR, 0);
866 ahc_outb(ahc, DSCOMMAND1, dscommand1);
867 }
868 break;
869 }
870 case MKMSG_FAILED:
871 {
872 u_int scbindex;
873
874 printf("%s:%c:%d:%d: Attempt to issue message failed\n",
875 ahc_name(ahc), devinfo.channel, devinfo.target,
876 devinfo.lun);
877 scbindex = ahc_inb(ahc, SCB_TAG);
878 scb = ahc_lookup_scb(ahc, scbindex);
879 if (scb != NULL
880 && (scb->flags & SCB_RECOVERY_SCB) != 0)
881 /*
882 * Ensure that we didn't put a second instance of this
883 * SCB into the QINFIFO.
884 */
885 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
886 SCB_GET_CHANNEL(ahc, scb),
887 SCB_GET_LUN(scb), scb->hscb->tag,
888 ROLE_INITIATOR, /*status*/0,
889 SEARCH_REMOVE);
890 break;
891 }
892 case NO_FREE_SCB:
893 {
894 printf("%s: No free or disconnected SCBs\n", ahc_name(ahc));
895 ahc_dump_card_state(ahc);
896 panic("for safety");
897 break;
898 }
899 case SCB_MISMATCH:
900 {
901 u_int scbptr;
902
903 scbptr = ahc_inb(ahc, SCBPTR);
904 printf("Bogus TAG after DMA. SCBPTR %d, tag %d, our tag %d\n",
905 scbptr, ahc_inb(ahc, ARG_1),
906 ahc->scb_data->hscbs[scbptr].tag);
907 ahc_dump_card_state(ahc);
908 panic("for saftey");
909 break;
910 }
911 case OUT_OF_RANGE:
912 {
913 printf("%s: BTT calculation out of range\n", ahc_name(ahc));
914 printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
915 "ARG_1 == 0x%x ACCUM = 0x%x\n",
916 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
917 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
918 printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
919 "SINDEX == 0x%x\n, A == 0x%x\n",
920 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
921 ahc_index_busy_tcl(ahc,
922 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
923 ahc_inb(ahc, SAVED_LUN))),
924 ahc_inb(ahc, SINDEX),
925 ahc_inb(ahc, ACCUM));
926 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
927 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
928 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
929 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
930 ahc_inb(ahc, SCB_CONTROL));
931 printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
932 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
933 ahc_dump_card_state(ahc);
934 panic("for safety");
935 break;
936 }
937 default:
938 printf("ahc_intr: seqint, "
939 "intstat == 0x%x, scsisigi = 0x%x\n",
940 intstat, ahc_inb(ahc, SCSISIGI));
941 break;
942 }
943unpause:
944 /*
945 * The sequencer is paused immediately on
946 * a SEQINT, so we should restart it when
947 * we're done.
948 */
949 ahc_unpause(ahc);
950}
951
952void
953ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
954{
955 u_int scb_index;
956 u_int status0;
957 u_int status;
958 struct scb *scb;
959 char cur_channel;
960 char intr_channel;
961
962 if ((ahc->features & AHC_TWIN) != 0
963 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))
964 cur_channel = 'B';
965 else
966 cur_channel = 'A';
967 intr_channel = cur_channel;
968
969 if ((ahc->features & AHC_ULTRA2) != 0)
970 status0 = ahc_inb(ahc, SSTAT0) & IOERR;
971 else
972 status0 = 0;
973 status = ahc_inb(ahc, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
974 if (status == 0 && status0 == 0) {
975 if ((ahc->features & AHC_TWIN) != 0) {
976 /* Try the other channel */
977 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
978 status = ahc_inb(ahc, SSTAT1)
979 & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
980 intr_channel = (cur_channel == 'A') ? 'B' : 'A';
981 }
982 if (status == 0) {
983 printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
984 ahc_outb(ahc, CLRINT, CLRSCSIINT);
985 ahc_unpause(ahc);
986 return;
987 }
988 }
989
990 /* Make sure the sequencer is in a safe location. */
991 ahc_clear_critical_section(ahc);
992
993 scb_index = ahc_inb(ahc, SCB_TAG);
994 scb = ahc_lookup_scb(ahc, scb_index);
995 if (scb != NULL
996 && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
997 scb = NULL;
998
999 if ((ahc->features & AHC_ULTRA2) != 0
1000 && (status0 & IOERR) != 0) {
1001 int now_lvd;
1002
1003 now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;
1004 printf("%s: Transceiver State Has Changed to %s mode\n",
1005 ahc_name(ahc), now_lvd ? "LVD" : "SE");
1006 ahc_outb(ahc, CLRSINT0, CLRIOERR);
1007 /*
1008 * When transitioning to SE mode, the reset line
1009 * glitches, triggering an arbitration bug in some
1010 * Ultra2 controllers. This bug is cleared when we
1011 * assert the reset line. Since a reset glitch has
1012 * already occurred with this transition and a
1013 * transceiver state change is handled just like
1014 * a bus reset anyway, asserting the reset line
1015 * ourselves is safe.
1016 */
1017 ahc_reset_channel(ahc, intr_channel,
1018 /*Initiate Reset*/now_lvd == 0);
1019 } else if ((status & SCSIRSTI) != 0) {
1020 printf("%s: Someone reset channel %c\n",
1021 ahc_name(ahc), intr_channel);
1022 if (intr_channel != cur_channel)
1023 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
1024 ahc_reset_channel(ahc, intr_channel, /*Initiate Reset*/FALSE);
1025 } else if ((status & SCSIPERR) != 0) {
1026 /*
1027 * Determine the bus phase and queue an appropriate message.
1028 * SCSIPERR is latched true as soon as a parity error
1029 * occurs. If the sequencer acked the transfer that
1030 * caused the parity error and the currently presented
1031 * transfer on the bus has correct parity, SCSIPERR will
1032 * be cleared by CLRSCSIPERR. Use this to determine if
1033 * we should look at the last phase the sequencer recorded,
1034 * or the current phase presented on the bus.
1035 */
1036 struct ahc_devinfo devinfo;
1037 u_int mesg_out;
1038 u_int curphase;
1039 u_int errorphase;
1040 u_int lastphase;
1041 u_int scsirate;
1042 u_int i;
1043 u_int sstat2;
1044 int silent;
1045
1046 lastphase = ahc_inb(ahc, LASTPHASE);
1047 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
1048 sstat2 = ahc_inb(ahc, SSTAT2);
1049 ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
1050 /*
1051 * For all phases save DATA, the sequencer won't
1052 * automatically ack a byte that has a parity error
1053 * in it. So the only way that the current phase
1054 * could be 'data-in' is if the parity error is for
1055 * an already acked byte in the data phase. During
1056 * synchronous data-in transfers, we may actually
1057 * ack bytes before latching the current phase in
1058 * LASTPHASE, leading to the discrepancy between
1059 * curphase and lastphase.
1060 */
1061 if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0
1062 || curphase == P_DATAIN || curphase == P_DATAIN_DT)
1063 errorphase = curphase;
1064 else
1065 errorphase = lastphase;
1066
1067 for (i = 0; i < num_phases; i++) {
1068 if (errorphase == ahc_phase_table[i].phase)
1069 break;
1070 }
1071 mesg_out = ahc_phase_table[i].mesg_out;
1072 silent = FALSE;
1073 if (scb != NULL) {
1074 if (SCB_IS_SILENT(scb))
1075 silent = TRUE;
1076 else
1077 ahc_print_path(ahc, scb);
1078 scb->flags |= SCB_TRANSMISSION_ERROR;
1079 } else
1080 printf("%s:%c:%d: ", ahc_name(ahc), intr_channel,
1081 SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));
1082 scsirate = ahc_inb(ahc, SCSIRATE);
1083 if (silent == FALSE) {
1084 printf("parity error detected %s. "
1085 "SEQADDR(0x%x) SCSIRATE(0x%x)\n",
1086 ahc_phase_table[i].phasemsg,
1087 ahc_inw(ahc, SEQADDR0),
1088 scsirate);
1089 if ((ahc->features & AHC_DT) != 0) {
1090 if ((sstat2 & CRCVALERR) != 0)
1091 printf("\tCRC Value Mismatch\n");
1092 if ((sstat2 & CRCENDERR) != 0)
1093 printf("\tNo terminal CRC packet "
1094 "recevied\n");
1095 if ((sstat2 & CRCREQERR) != 0)
1096 printf("\tIllegal CRC packet "
1097 "request\n");
1098 if ((sstat2 & DUAL_EDGE_ERR) != 0)
1099 printf("\tUnexpected %sDT Data Phase\n",
1100 (scsirate & SINGLE_EDGE)
1101 ? "" : "non-");
1102 }
1103 }
1104
1105 if ((ahc->features & AHC_DT) != 0
1106 && (sstat2 & DUAL_EDGE_ERR) != 0) {
1107 /*
1108 * This error applies regardless of
1109 * data direction, so ignore the value
1110 * in the phase table.
1111 */
1112 mesg_out = MSG_INITIATOR_DET_ERR;
1113 }
1114
1115 /*
1116 * We've set the hardware to assert ATN if we
1117 * get a parity error on "in" phases, so all we
1118 * need to do is stuff the message buffer with
1119 * the appropriate message. "In" phases have set
1120 * mesg_out to something other than MSG_NOP.
1121 */
1122 if (mesg_out != MSG_NOOP) {
1123 if (ahc->msg_type != MSG_TYPE_NONE)
1124 ahc->send_msg_perror = TRUE;
1125 else
1126 ahc_outb(ahc, MSG_OUT, mesg_out);
1127 }
1128 /*
1129 * Force a renegotiation with this target just in
1130 * case we are out of sync for some external reason
1131 * unknown (or unreported) by the target.
1132 */
1133 ahc_fetch_devinfo(ahc, &devinfo);
1134 ahc_force_renegotiation(ahc, &devinfo);
1135
1136 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1137 ahc_unpause(ahc);
1138 } else if ((status & SELTO) != 0) {
1139 u_int scbptr;
1140
1141 /* Stop the selection */
1142 ahc_outb(ahc, SCSISEQ, 0);
1143
1144 /* No more pending messages */
1145 ahc_clear_msg_state(ahc);
1146
1147 /* Clear interrupt state */
1148 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
1149 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
1150
1151 /*
1152 * Although the driver does not care about the
1153 * 'Selection in Progress' status bit, the busy
1154 * LED does. SELINGO is only cleared by a sucessfull
1155 * selection, so we must manually clear it to insure
1156 * the LED turns off just incase no future successful
1157 * selections occur (e.g. no devices on the bus).
1158 */
1159 ahc_outb(ahc, CLRSINT0, CLRSELINGO);
1160
1161 scbptr = ahc_inb(ahc, WAITING_SCBH);
1162 ahc_outb(ahc, SCBPTR, scbptr);
1163 scb_index = ahc_inb(ahc, SCB_TAG);
1164
1165 scb = ahc_lookup_scb(ahc, scb_index);
1166 if (scb == NULL) {
1167 printf("%s: ahc_intr - referenced scb not "
1168 "valid during SELTO scb(%d, %d)\n",
1169 ahc_name(ahc), scbptr, scb_index);
1170 ahc_dump_card_state(ahc);
1171 } else {
1172 struct ahc_devinfo devinfo;
1173#ifdef AHC_DEBUG
1174 if ((ahc_debug & AHC_SHOW_SELTO) != 0) {
1175 ahc_print_path(ahc, scb);
1176 printf("Saw Selection Timeout for SCB 0x%x\n",
1177 scb_index);
1178 }
1179#endif
1180 /*
1181 * Force a renegotiation with this target just in
1182 * case the cable was pulled and will later be
1183 * re-attached. The target may forget its negotiation
1184 * settings with us should it attempt to reselect
1185 * during the interruption. The target will not issue
1186 * a unit attention in this case, so we must always
1187 * renegotiate.
1188 */
1189 ahc_scb_devinfo(ahc, &devinfo, scb);
1190 ahc_force_renegotiation(ahc, &devinfo);
1191 ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);
1192 ahc_freeze_devq(ahc, scb);
1193 }
1194 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1195 ahc_restart(ahc);
1196 } else if ((status & BUSFREE) != 0
1197 && (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {
1198 struct ahc_devinfo devinfo;
1199 u_int lastphase;
1200 u_int saved_scsiid;
1201 u_int saved_lun;
1202 u_int target;
1203 u_int initiator_role_id;
1204 char channel;
1205 int printerror;
1206
1207 /*
1208 * Clear our selection hardware as soon as possible.
1209 * We may have an entry in the waiting Q for this target,
1210 * that is affected by this busfree and we don't want to
1211 * go about selecting the target while we handle the event.
1212 */
1213 ahc_outb(ahc, SCSISEQ,
1214 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
1215
1216 /*
1217 * Disable busfree interrupts and clear the busfree
1218 * interrupt status. We do this here so that several
1219 * bus transactions occur prior to clearing the SCSIINT
1220 * latch. It can take a bit for the clearing to take effect.
1221 */
1222 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
1223 ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);
1224
1225 /*
1226 * Look at what phase we were last in.
1227 * If its message out, chances are pretty good
1228 * that the busfree was in response to one of
1229 * our abort requests.
1230 */
1231 lastphase = ahc_inb(ahc, LASTPHASE);
1232 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
1233 saved_lun = ahc_inb(ahc, SAVED_LUN);
1234 target = SCSIID_TARGET(ahc, saved_scsiid);
1235 initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
1236 channel = SCSIID_CHANNEL(ahc, saved_scsiid);
1237 ahc_compile_devinfo(&devinfo, initiator_role_id,
1238 target, saved_lun, channel, ROLE_INITIATOR);
1239 printerror = 1;
1240
1241 if (lastphase == P_MESGOUT) {
1242 u_int tag;
1243
1244 tag = SCB_LIST_NULL;
1245 if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE)
1246 || ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) {
1247 if (ahc->msgout_buf[ahc->msgout_index - 1]
1248 == MSG_ABORT_TAG)
1249 tag = scb->hscb->tag;
1250 ahc_print_path(ahc, scb);
1251 printf("SCB %d - Abort%s Completed.\n",
1252 scb->hscb->tag, tag == SCB_LIST_NULL ?
1253 "" : " Tag");
1254 ahc_abort_scbs(ahc, target, channel,
1255 saved_lun, tag,
1256 ROLE_INITIATOR,
1257 CAM_REQ_ABORTED);
1258 printerror = 0;
1259 } else if (ahc_sent_msg(ahc, AHCMSG_1B,
1260 MSG_BUS_DEV_RESET, TRUE)) {
1261#ifdef __FreeBSD__
1262 /*
1263 * Don't mark the user's request for this BDR
1264 * as completing with CAM_BDR_SENT. CAM3
1265 * specifies CAM_REQ_CMP.
1266 */
1267 if (scb != NULL
1268 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
1269 && ahc_match_scb(ahc, scb, target, channel,
1270 CAM_LUN_WILDCARD,
1271 SCB_LIST_NULL,
1272 ROLE_INITIATOR)) {
1273 ahc_set_transaction_status(scb, CAM_REQ_CMP);
1274 }
1275#endif
1276 ahc_compile_devinfo(&devinfo,
1277 initiator_role_id,
1278 target,
1279 CAM_LUN_WILDCARD,
1280 channel,
1281 ROLE_INITIATOR);
1282 ahc_handle_devreset(ahc, &devinfo,
1283 CAM_BDR_SENT,
1284 "Bus Device Reset",
1285 /*verbose_level*/0);
1286 printerror = 0;
1287 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1288 MSG_EXT_PPR, FALSE)) {
1289 struct ahc_initiator_tinfo *tinfo;
1290 struct ahc_tmode_tstate *tstate;
1291
1292 /*
1293 * PPR Rejected. Try non-ppr negotiation
1294 * and retry command.
1295 */
1296 tinfo = ahc_fetch_transinfo(ahc,
1297 devinfo.channel,
1298 devinfo.our_scsiid,
1299 devinfo.target,
1300 &tstate);
1301 tinfo->curr.transport_version = 2;
1302 tinfo->goal.transport_version = 2;
1303 tinfo->goal.ppr_options = 0;
1304 ahc_qinfifo_requeue_tail(ahc, scb);
1305 printerror = 0;
1306 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1307 MSG_EXT_WDTR, FALSE)) {
1308 /*
1309 * Negotiation Rejected. Go-narrow and
1310 * retry command.
1311 */
1312 ahc_set_width(ahc, &devinfo,
1313 MSG_EXT_WDTR_BUS_8_BIT,
1314 AHC_TRANS_CUR|AHC_TRANS_GOAL,
1315 /*paused*/TRUE);
1316 ahc_qinfifo_requeue_tail(ahc, scb);
1317 printerror = 0;
1318 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1319 MSG_EXT_SDTR, FALSE)) {
1320 /*
1321 * Negotiation Rejected. Go-async and
1322 * retry command.
1323 */
1324 ahc_set_syncrate(ahc, &devinfo,
1325 /*syncrate*/NULL,
1326 /*period*/0, /*offset*/0,
1327 /*ppr_options*/0,
1328 AHC_TRANS_CUR|AHC_TRANS_GOAL,
1329 /*paused*/TRUE);
1330 ahc_qinfifo_requeue_tail(ahc, scb);
1331 printerror = 0;
1332 }
1333 }
1334 if (printerror != 0) {
1335 u_int i;
1336
1337 if (scb != NULL) {
1338 u_int tag;
1339
1340 if ((scb->hscb->control & TAG_ENB) != 0)
1341 tag = scb->hscb->tag;
1342 else
1343 tag = SCB_LIST_NULL;
1344 ahc_print_path(ahc, scb);
1345 ahc_abort_scbs(ahc, target, channel,
1346 SCB_GET_LUN(scb), tag,
1347 ROLE_INITIATOR,
1348 CAM_UNEXP_BUSFREE);
1349 } else {
1350 /*
1351 * We had not fully identified this connection,
1352 * so we cannot abort anything.
1353 */
1354 printf("%s: ", ahc_name(ahc));
1355 }
1356 for (i = 0; i < num_phases; i++) {
1357 if (lastphase == ahc_phase_table[i].phase)
1358 break;
1359 }
1360 if (lastphase != P_BUSFREE) {
1361 /*
1362 * Renegotiate with this device at the
1363 * next oportunity just in case this busfree
1364 * is due to a negotiation mismatch with the
1365 * device.
1366 */
1367 ahc_force_renegotiation(ahc, &devinfo);
1368 }
1369 printf("Unexpected busfree %s\n"
1370 "SEQADDR == 0x%x\n",
1371 ahc_phase_table[i].phasemsg,
1372 ahc_inb(ahc, SEQADDR0)
1373 | (ahc_inb(ahc, SEQADDR1) << 8));
1374 }
1375 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1376 ahc_restart(ahc);
1377 } else {
1378 printf("%s: Missing case in ahc_handle_scsiint. status = %x\n",
1379 ahc_name(ahc), status);
1380 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1381 }
1382}
1383
1384/*
1385 * Force renegotiation to occur the next time we initiate
1386 * a command to the current device.
1387 */
1388static void
1389ahc_force_renegotiation(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
1390{
1391 struct ahc_initiator_tinfo *targ_info;
1392 struct ahc_tmode_tstate *tstate;
1393
1394 targ_info = ahc_fetch_transinfo(ahc,
1395 devinfo->channel,
1396 devinfo->our_scsiid,
1397 devinfo->target,
1398 &tstate);
1399 ahc_update_neg_request(ahc, devinfo, tstate,
1400 targ_info, AHC_NEG_IF_NON_ASYNC);
1401}
1402
1403#define AHC_MAX_STEPS 2000
1404void
1405ahc_clear_critical_section(struct ahc_softc *ahc)
1406{
1407 int stepping;
1408 int steps;
1409 u_int simode0;
1410 u_int simode1;
1411
1412 if (ahc->num_critical_sections == 0)
1413 return;
1414
1415 stepping = FALSE;
1416 steps = 0;
1417 simode0 = 0;
1418 simode1 = 0;
1419 for (;;) {
1420 struct cs *cs;
1421 u_int seqaddr;
1422 u_int i;
1423
1424 seqaddr = ahc_inb(ahc, SEQADDR0)
1425 | (ahc_inb(ahc, SEQADDR1) << 8);
1426
1427 /*
1428 * Seqaddr represents the next instruction to execute,
1429 * so we are really executing the instruction just
1430 * before it.
1431 */
1432 if (seqaddr != 0)
1433 seqaddr -= 1;
1434 cs = ahc->critical_sections;
1435 for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
1436
1437 if (cs->begin < seqaddr && cs->end >= seqaddr)
1438 break;
1439 }
1440
1441 if (i == ahc->num_critical_sections)
1442 break;
1443
1444 if (steps > AHC_MAX_STEPS) {
1445 printf("%s: Infinite loop in critical section\n",
1446 ahc_name(ahc));
1447 ahc_dump_card_state(ahc);
1448 panic("critical section loop");
1449 }
1450
1451 steps++;
1452 if (stepping == FALSE) {
1453
1454 /*
1455 * Disable all interrupt sources so that the
1456 * sequencer will not be stuck by a pausing
1457 * interrupt condition while we attempt to
1458 * leave a critical section.
1459 */
1460 simode0 = ahc_inb(ahc, SIMODE0);
1461 ahc_outb(ahc, SIMODE0, 0);
1462 simode1 = ahc_inb(ahc, SIMODE1);
1463 if ((ahc->features & AHC_DT) != 0)
1464 /*
1465 * On DT class controllers, we
1466 * use the enhanced busfree logic.
1467 * Unfortunately we cannot re-enable
1468 * busfree detection within the
1469 * current connection, so we must
1470 * leave it on while single stepping.
1471 */
1472 ahc_outb(ahc, SIMODE1, simode1 & ENBUSFREE);
1473 else
1474 ahc_outb(ahc, SIMODE1, 0);
1475 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1476 ahc_outb(ahc, SEQCTL, ahc->seqctl | STEP);
1477 stepping = TRUE;
1478 }
1479 if ((ahc->features & AHC_DT) != 0) {
1480 ahc_outb(ahc, CLRSINT1, CLRBUSFREE);
1481 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1482 }
1483 ahc_outb(ahc, HCNTRL, ahc->unpause);
1484 while (!ahc_is_paused(ahc))
1485 ahc_delay(200);
1486 }
1487 if (stepping) {
1488 ahc_outb(ahc, SIMODE0, simode0);
1489 ahc_outb(ahc, SIMODE1, simode1);
1490 ahc_outb(ahc, SEQCTL, ahc->seqctl);
1491 }
1492}
1493
1494/*
1495 * Clear any pending interrupt status.
1496 */
1497void
1498ahc_clear_intstat(struct ahc_softc *ahc)
1499{
1500 /* Clear any interrupt conditions this may have caused */
1501 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
1502 |CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|
1503 CLRREQINIT);
1504 ahc_flush_device_writes(ahc);
1505 ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
1506 ahc_flush_device_writes(ahc);
1507 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1508 ahc_flush_device_writes(ahc);
1509}
1510
1511/**************************** Debugging Routines ******************************/
1512#ifdef AHC_DEBUG
1513uint32_t ahc_debug = AHC_DEBUG_OPTS;
1514#endif
1515
1516void
1517ahc_print_scb(struct scb *scb)
1518{
1519 int i;
1520
1521 struct hardware_scb *hscb = scb->hscb;
1522
1523 printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
1524 (void *)scb,
1525 hscb->control,
1526 hscb->scsiid,
1527 hscb->lun,
1528 hscb->cdb_len);
1529 printf("Shared Data: ");
1530 for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
1531 printf("%#02x", hscb->shared_data.cdb[i]);
1532 printf(" dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
1533 ahc_le32toh(hscb->dataptr),
1534 ahc_le32toh(hscb->datacnt),
1535 ahc_le32toh(hscb->sgptr),
1536 hscb->tag);
1537 if (scb->sg_count > 0) {
1538 for (i = 0; i < scb->sg_count; i++) {
1539 printf("sg[%d] - Addr 0x%x%x : Length %d\n",
1540 i,
1541 (ahc_le32toh(scb->sg_list[i].len) >> 24
1542 & SG_HIGH_ADDR_BITS),
1543 ahc_le32toh(scb->sg_list[i].addr),
1544 ahc_le32toh(scb->sg_list[i].len));
1545 }
1546 }
1547}
1548
1549/************************* Transfer Negotiation *******************************/
1550/*
1551 * Allocate per target mode instance (ID we respond to as a target)
1552 * transfer negotiation data structures.
1553 */
1554static struct ahc_tmode_tstate *
1555ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)
1556{
1557 struct ahc_tmode_tstate *master_tstate;
1558 struct ahc_tmode_tstate *tstate;
1559 int i;
1560
1561 master_tstate = ahc->enabled_targets[ahc->our_id];
1562 if (channel == 'B') {
1563 scsi_id += 8;
1564 master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];
1565 }
1566 if (ahc->enabled_targets[scsi_id] != NULL
1567 && ahc->enabled_targets[scsi_id] != master_tstate)
1568 panic("%s: ahc_alloc_tstate - Target already allocated",
1569 ahc_name(ahc));
1570 tstate = (struct ahc_tmode_tstate*)malloc(sizeof(*tstate),
1571 M_DEVBUF, M_NOWAIT);
1572 if (tstate == NULL)
1573 return (NULL);
1574
1575 /*
1576 * If we have allocated a master tstate, copy user settings from
1577 * the master tstate (taken from SRAM or the EEPROM) for this
1578 * channel, but reset our current and goal settings to async/narrow
1579 * until an initiator talks to us.
1580 */
1581 if (master_tstate != NULL) {
1582 memcpy(tstate, master_tstate, sizeof(*tstate));
1583 memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
1584 tstate->ultraenb = 0;
1585 for (i = 0; i < AHC_NUM_TARGETS; i++) {
1586 memset(&tstate->transinfo[i].curr, 0,
1587 sizeof(tstate->transinfo[i].curr));
1588 memset(&tstate->transinfo[i].goal, 0,
1589 sizeof(tstate->transinfo[i].goal));
1590 }
1591 } else
1592 memset(tstate, 0, sizeof(*tstate));
1593 ahc->enabled_targets[scsi_id] = tstate;
1594 return (tstate);
1595}
1596
1597#ifdef AHC_TARGET_MODE
1598/*
1599 * Free per target mode instance (ID we respond to as a target)
1600 * transfer negotiation data structures.
1601 */
1602static void
1603ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)
1604{
1605 struct ahc_tmode_tstate *tstate;
1606
1607 /*
1608 * Don't clean up our "master" tstate.
1609 * It has our default user settings.
1610 */
1611 if (((channel == 'B' && scsi_id == ahc->our_id_b)
1612 || (channel == 'A' && scsi_id == ahc->our_id))
1613 && force == FALSE)
1614 return;
1615
1616 if (channel == 'B')
1617 scsi_id += 8;
1618 tstate = ahc->enabled_targets[scsi_id];
1619 if (tstate != NULL)
1620 free(tstate, M_DEVBUF);
1621 ahc->enabled_targets[scsi_id] = NULL;
1622}
1623#endif
1624
1625/*
1626 * Called when we have an active connection to a target on the bus,
1627 * this function finds the nearest syncrate to the input period limited
1628 * by the capabilities of the bus connectivity of and sync settings for
1629 * the target.
1630 */
1631struct ahc_syncrate *
1632ahc_devlimited_syncrate(struct ahc_softc *ahc,
1633 struct ahc_initiator_tinfo *tinfo,
1634 u_int *period, u_int *ppr_options, role_t role)
1635{
1636 struct ahc_transinfo *transinfo;
1637 u_int maxsync;
1638
1639 if ((ahc->features & AHC_ULTRA2) != 0) {
1640 if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 0
1641 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {
1642 maxsync = AHC_SYNCRATE_DT;
1643 } else {
1644 maxsync = AHC_SYNCRATE_ULTRA;
1645 /* Can't do DT on an SE bus */
1646 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1647 }
1648 } else if ((ahc->features & AHC_ULTRA) != 0) {
1649 maxsync = AHC_SYNCRATE_ULTRA;
1650 } else {
1651 maxsync = AHC_SYNCRATE_FAST;
1652 }
1653 /*
1654 * Never allow a value higher than our current goal
1655 * period otherwise we may allow a target initiated
1656 * negotiation to go above the limit as set by the
1657 * user. In the case of an initiator initiated
1658 * sync negotiation, we limit based on the user
1659 * setting. This allows the system to still accept
1660 * incoming negotiations even if target initiated
1661 * negotiation is not performed.
1662 */
1663 if (role == ROLE_TARGET)
1664 transinfo = &tinfo->user;
1665 else
1666 transinfo = &tinfo->goal;
1667 *ppr_options &= transinfo->ppr_options;
1668 if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
1669 maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2);
1670 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1671 }
1672 if (transinfo->period == 0) {
1673 *period = 0;
1674 *ppr_options = 0;
1675 return (NULL);
1676 }
1677 *period = MAX(*period, transinfo->period);
1678 return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));
1679}
1680
1681/*
1682 * Look up the valid period to SCSIRATE conversion in our table.
1683 * Return the period and offset that should be sent to the target
1684 * if this was the beginning of an SDTR.
1685 */
1686struct ahc_syncrate *
1687ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
1688 u_int *ppr_options, u_int maxsync)
1689{
1690 struct ahc_syncrate *syncrate;
1691
1692 if ((ahc->features & AHC_DT) == 0)
1693 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1694
1695 /* Skip all DT only entries if DT is not available */
1696 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
1697 && maxsync < AHC_SYNCRATE_ULTRA2)
1698 maxsync = AHC_SYNCRATE_ULTRA2;
1699
1700 for (syncrate = &ahc_syncrates[maxsync];
1701 syncrate->rate != NULL;
1702 syncrate++) {
1703
1704 /*
1705 * The Ultra2 table doesn't go as low
1706 * as for the Fast/Ultra cards.
1707 */
1708 if ((ahc->features & AHC_ULTRA2) != 0
1709 && (syncrate->sxfr_u2 == 0))
1710 break;
1711
1712 if (*period <= syncrate->period) {
1713 /*
1714 * When responding to a target that requests
1715 * sync, the requested rate may fall between
1716 * two rates that we can output, but still be
1717 * a rate that we can receive. Because of this,
1718 * we want to respond to the target with
1719 * the same rate that it sent to us even
1720 * if the period we use to send data to it
1721 * is lower. Only lower the response period
1722 * if we must.
1723 */
1724 if (syncrate == &ahc_syncrates[maxsync])
1725 *period = syncrate->period;
1726
1727 /*
1728 * At some speeds, we only support
1729 * ST transfers.
1730 */
1731 if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
1732 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1733 break;
1734 }
1735 }
1736
1737 if ((*period == 0)
1738 || (syncrate->rate == NULL)
1739 || ((ahc->features & AHC_ULTRA2) != 0
1740 && (syncrate->sxfr_u2 == 0))) {
1741 /* Use asynchronous transfers. */
1742 *period = 0;
1743 syncrate = NULL;
1744 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1745 }
1746 return (syncrate);
1747}
1748
1749/*
1750 * Convert from an entry in our syncrate table to the SCSI equivalent
1751 * sync "period" factor.
1752 */
1753u_int
1754ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
1755{
1756 struct ahc_syncrate *syncrate;
1757
1758 if ((ahc->features & AHC_ULTRA2) != 0)
1759 scsirate &= SXFR_ULTRA2;
1760 else
1761 scsirate &= SXFR;
1762
1763 syncrate = &ahc_syncrates[maxsync];
1764 while (syncrate->rate != NULL) {
1765
1766 if ((ahc->features & AHC_ULTRA2) != 0) {
1767 if (syncrate->sxfr_u2 == 0)
1768 break;
1769 else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))
1770 return (syncrate->period);
1771 } else if (scsirate == (syncrate->sxfr & SXFR)) {
1772 return (syncrate->period);
1773 }
1774 syncrate++;
1775 }
1776 return (0); /* async */
1777}
1778
1779/*
1780 * Truncate the given synchronous offset to a value the
1781 * current adapter type and syncrate are capable of.
1782 */
1783void
1784ahc_validate_offset(struct ahc_softc *ahc,
1785 struct ahc_initiator_tinfo *tinfo,
1786 struct ahc_syncrate *syncrate,
1787 u_int *offset, int wide, role_t role)
1788{
1789 u_int maxoffset;
1790
1791 /* Limit offset to what we can do */
1792 if (syncrate == NULL) {
1793 maxoffset = 0;
1794 } else if ((ahc->features & AHC_ULTRA2) != 0) {
1795 maxoffset = MAX_OFFSET_ULTRA2;
1796 } else {
1797 if (wide)
1798 maxoffset = MAX_OFFSET_16BIT;
1799 else
1800 maxoffset = MAX_OFFSET_8BIT;
1801 }
1802 *offset = MIN(*offset, maxoffset);
1803 if (tinfo != NULL) {
1804 if (role == ROLE_TARGET)
1805 *offset = MIN(*offset, tinfo->user.offset);
1806 else
1807 *offset = MIN(*offset, tinfo->goal.offset);
1808 }
1809}
1810
1811/*
1812 * Truncate the given transfer width parameter to a value the
1813 * current adapter type is capable of.
1814 */
1815void
1816ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo,
1817 u_int *bus_width, role_t role)
1818{
1819 switch (*bus_width) {
1820 default:
1821 if (ahc->features & AHC_WIDE) {
1822 /* Respond Wide */
1823 *bus_width = MSG_EXT_WDTR_BUS_16_BIT;
1824 break;
1825 }
1826 /* FALLTHROUGH */
1827 case MSG_EXT_WDTR_BUS_8_BIT:
1828 *bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1829 break;
1830 }
1831 if (tinfo != NULL) {
1832 if (role == ROLE_TARGET)
1833 *bus_width = MIN(tinfo->user.width, *bus_width);
1834 else
1835 *bus_width = MIN(tinfo->goal.width, *bus_width);
1836 }
1837}
1838
1839/*
1840 * Update the bitmask of targets for which the controller should
1841 * negotiate with at the next convenient oportunity. This currently
1842 * means the next time we send the initial identify messages for
1843 * a new transaction.
1844 */
1845int
1846ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
1847 struct ahc_tmode_tstate *tstate,
1848 struct ahc_initiator_tinfo *tinfo, ahc_neg_type neg_type)
1849{
1850 u_int auto_negotiate_orig;
1851
1852 auto_negotiate_orig = tstate->auto_negotiate;
1853 if (neg_type == AHC_NEG_ALWAYS) {
1854 /*
1855 * Force our "current" settings to be
1856 * unknown so that unless a bus reset
1857 * occurs the need to renegotiate is
1858 * recorded persistently.
1859 */
1860 if ((ahc->features & AHC_WIDE) != 0)
1861 tinfo->curr.width = AHC_WIDTH_UNKNOWN;
1862 tinfo->curr.period = AHC_PERIOD_UNKNOWN;
1863 tinfo->curr.offset = AHC_OFFSET_UNKNOWN;
1864 }
1865 if (tinfo->curr.period != tinfo->goal.period
1866 || tinfo->curr.width != tinfo->goal.width
1867 || tinfo->curr.offset != tinfo->goal.offset
1868 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
1869 || (neg_type == AHC_NEG_IF_NON_ASYNC
1870 && (tinfo->goal.offset != 0
1871 || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
1872 || tinfo->goal.ppr_options != 0)))
1873 tstate->auto_negotiate |= devinfo->target_mask;
1874 else
1875 tstate->auto_negotiate &= ~devinfo->target_mask;
1876
1877 return (auto_negotiate_orig != tstate->auto_negotiate);
1878}
1879
1880/*
1881 * Update the user/goal/curr tables of synchronous negotiation
1882 * parameters as well as, in the case of a current or active update,
1883 * any data structures on the host controller. In the case of an
1884 * active update, the specified target is currently talking to us on
1885 * the bus, so the transfer parameter update must take effect
1886 * immediately.
1887 */
1888void
1889ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
1890 struct ahc_syncrate *syncrate, u_int period,
1891 u_int offset, u_int ppr_options, u_int type, int paused)
1892{
1893 struct ahc_initiator_tinfo *tinfo;
1894 struct ahc_tmode_tstate *tstate;
1895 u_int old_period;
1896 u_int old_offset;
1897 u_int old_ppr;
1898 int active;
1899 int update_needed;
1900
1901 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
1902 update_needed = 0;
1903
1904 if (syncrate == NULL) {
1905 period = 0;
1906 offset = 0;
1907 }
1908
1909 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
1910 devinfo->target, &tstate);
1911
1912 if ((type & AHC_TRANS_USER) != 0) {
1913 tinfo->user.period = period;
1914 tinfo->user.offset = offset;
1915 tinfo->user.ppr_options = ppr_options;
1916 }
1917
1918 if ((type & AHC_TRANS_GOAL) != 0) {
1919 tinfo->goal.period = period;
1920 tinfo->goal.offset = offset;
1921 tinfo->goal.ppr_options = ppr_options;
1922 }
1923
1924 old_period = tinfo->curr.period;
1925 old_offset = tinfo->curr.offset;
1926 old_ppr = tinfo->curr.ppr_options;
1927
1928 if ((type & AHC_TRANS_CUR) != 0
1929 && (old_period != period
1930 || old_offset != offset
1931 || old_ppr != ppr_options)) {
1932 u_int scsirate;
1933
1934 update_needed++;
1935 scsirate = tinfo->scsirate;
1936 if ((ahc->features & AHC_ULTRA2) != 0) {
1937
1938 scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);
1939 if (syncrate != NULL) {
1940 scsirate |= syncrate->sxfr_u2;
1941 if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0)
1942 scsirate |= ENABLE_CRC;
1943 else
1944 scsirate |= SINGLE_EDGE;
1945 }
1946 } else {
1947
1948 scsirate &= ~(SXFR|SOFS);
1949 /*
1950 * Ensure Ultra mode is set properly for
1951 * this target.
1952 */
1953 tstate->ultraenb &= ~devinfo->target_mask;
1954 if (syncrate != NULL) {
1955 if (syncrate->sxfr & ULTRA_SXFR) {
1956 tstate->ultraenb |=
1957 devinfo->target_mask;
1958 }
1959 scsirate |= syncrate->sxfr & SXFR;
1960 scsirate |= offset & SOFS;
1961 }
1962 if (active) {
1963 u_int sxfrctl0;
1964
1965 sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
1966 sxfrctl0 &= ~FAST20;
1967 if (tstate->ultraenb & devinfo->target_mask)
1968 sxfrctl0 |= FAST20;
1969 ahc_outb(ahc, SXFRCTL0, sxfrctl0);
1970 }
1971 }
1972 if (active) {
1973 ahc_outb(ahc, SCSIRATE, scsirate);
1974 if ((ahc->features & AHC_ULTRA2) != 0)
1975 ahc_outb(ahc, SCSIOFFSET, offset);
1976 }
1977
1978 tinfo->scsirate = scsirate;
1979 tinfo->curr.period = period;
1980 tinfo->curr.offset = offset;
1981 tinfo->curr.ppr_options = ppr_options;
1982
1983 ahc_send_async(ahc, devinfo->channel, devinfo->target,
1984 CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
1985 if (bootverbose) {
1986 if (offset != 0) {
1987 printf("%s: target %d synchronous at %sMHz%s, "
1988 "offset = 0x%x\n", ahc_name(ahc),
1989 devinfo->target, syncrate->rate,
1990 (ppr_options & MSG_EXT_PPR_DT_REQ)
1991 ? " DT" : "", offset);
1992 } else {
1993 printf("%s: target %d using "
1994 "asynchronous transfers\n",
1995 ahc_name(ahc), devinfo->target);
1996 }
1997 }
1998 }
1999
2000 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
2001 tinfo, AHC_NEG_TO_GOAL);
2002
2003 if (update_needed)
2004 ahc_update_pending_scbs(ahc);
2005}
2006
2007/*
2008 * Update the user/goal/curr tables of wide negotiation
2009 * parameters as well as, in the case of a current or active update,
2010 * any data structures on the host controller. In the case of an
2011 * active update, the specified target is currently talking to us on
2012 * the bus, so the transfer parameter update must take effect
2013 * immediately.
2014 */
2015void
2016ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2017 u_int width, u_int type, int paused)
2018{
2019 struct ahc_initiator_tinfo *tinfo;
2020 struct ahc_tmode_tstate *tstate;
2021 u_int oldwidth;
2022 int active;
2023 int update_needed;
2024
2025 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
2026 update_needed = 0;
2027 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
2028 devinfo->target, &tstate);
2029
2030 if ((type & AHC_TRANS_USER) != 0)
2031 tinfo->user.width = width;
2032
2033 if ((type & AHC_TRANS_GOAL) != 0)
2034 tinfo->goal.width = width;
2035
2036 oldwidth = tinfo->curr.width;
2037 if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {
2038 u_int scsirate;
2039
2040 update_needed++;
2041 scsirate = tinfo->scsirate;
2042 scsirate &= ~WIDEXFER;
2043 if (width == MSG_EXT_WDTR_BUS_16_BIT)
2044 scsirate |= WIDEXFER;
2045
2046 tinfo->scsirate = scsirate;
2047
2048 if (active)
2049 ahc_outb(ahc, SCSIRATE, scsirate);
2050
2051 tinfo->curr.width = width;
2052
2053 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2054 CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
2055 if (bootverbose) {
2056 printf("%s: target %d using %dbit transfers\n",
2057 ahc_name(ahc), devinfo->target,
2058 8 * (0x01 << width));
2059 }
2060 }
2061
2062 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
2063 tinfo, AHC_NEG_TO_GOAL);
2064 if (update_needed)
2065 ahc_update_pending_scbs(ahc);
2066}
2067
2068/*
2069 * Update the current state of tagged queuing for a given target.
2070 */
2071void
2072ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2073 ahc_queue_alg alg)
2074{
2075 ahc_platform_set_tags(ahc, devinfo, alg);
2076 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2077 devinfo->lun, AC_TRANSFER_NEG, &alg);
2078}
2079
2080/*
2081 * When the transfer settings for a connection change, update any
2082 * in-transit SCBs to contain the new data so the hardware will
2083 * be set correctly during future (re)selections.
2084 */
2085static void
2086ahc_update_pending_scbs(struct ahc_softc *ahc)
2087{
2088 struct scb *pending_scb;
2089 int pending_scb_count;
2090 int i;
2091 int paused;
2092 u_int saved_scbptr;
2093
2094 /*
2095 * Traverse the pending SCB list and ensure that all of the
2096 * SCBs there have the proper settings.
2097 */
2098 pending_scb_count = 0;
2099 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
2100 struct ahc_devinfo devinfo;
2101 struct hardware_scb *pending_hscb;
2102 struct ahc_initiator_tinfo *tinfo;
2103 struct ahc_tmode_tstate *tstate;
2104
2105 ahc_scb_devinfo(ahc, &devinfo, pending_scb);
2106 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
2107 devinfo.our_scsiid,
2108 devinfo.target, &tstate);
2109 pending_hscb = pending_scb->hscb;
2110 pending_hscb->control &= ~ULTRAENB;
2111 if ((tstate->ultraenb & devinfo.target_mask) != 0)
2112 pending_hscb->control |= ULTRAENB;
2113 pending_hscb->scsirate = tinfo->scsirate;
2114 pending_hscb->scsioffset = tinfo->curr.offset;
2115 if ((tstate->auto_negotiate & devinfo.target_mask) == 0
2116 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
2117 pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
2118 pending_hscb->control &= ~MK_MESSAGE;
2119 }
2120 ahc_sync_scb(ahc, pending_scb,
2121 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2122 pending_scb_count++;
2123 }
2124
2125 if (pending_scb_count == 0)
2126 return;
2127
2128 if (ahc_is_paused(ahc)) {
2129 paused = 1;
2130 } else {
2131 paused = 0;
2132 ahc_pause(ahc);
2133 }
2134
2135 saved_scbptr = ahc_inb(ahc, SCBPTR);
2136 /* Ensure that the hscbs down on the card match the new information */
2137 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
2138 struct hardware_scb *pending_hscb;
2139 u_int control;
2140 u_int scb_tag;
2141
2142 ahc_outb(ahc, SCBPTR, i);
2143 scb_tag = ahc_inb(ahc, SCB_TAG);
2144 pending_scb = ahc_lookup_scb(ahc, scb_tag);
2145 if (pending_scb == NULL)
2146 continue;
2147
2148 pending_hscb = pending_scb->hscb;
2149 control = ahc_inb(ahc, SCB_CONTROL);
2150 control &= ~(ULTRAENB|MK_MESSAGE);
2151 control |= pending_hscb->control & (ULTRAENB|MK_MESSAGE);
2152 ahc_outb(ahc, SCB_CONTROL, control);
2153 ahc_outb(ahc, SCB_SCSIRATE, pending_hscb->scsirate);
2154 ahc_outb(ahc, SCB_SCSIOFFSET, pending_hscb->scsioffset);
2155 }
2156 ahc_outb(ahc, SCBPTR, saved_scbptr);
2157
2158 if (paused == 0)
2159 ahc_unpause(ahc);
2160}
2161
2162/**************************** Pathing Information *****************************/
2163static void
2164ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2165{
2166 u_int saved_scsiid;
2167 role_t role;
2168 int our_id;
2169
2170 if (ahc_inb(ahc, SSTAT0) & TARGET)
2171 role = ROLE_TARGET;
2172 else
2173 role = ROLE_INITIATOR;
2174
2175 if (role == ROLE_TARGET
2176 && (ahc->features & AHC_MULTI_TID) != 0
2177 && (ahc_inb(ahc, SEQ_FLAGS)
2178 & (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) {
2179 /* We were selected, so pull our id from TARGIDIN */
2180 our_id = ahc_inb(ahc, TARGIDIN) & OID;
2181 } else if ((ahc->features & AHC_ULTRA2) != 0)
2182 our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
2183 else
2184 our_id = ahc_inb(ahc, SCSIID) & OID;
2185
2186 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
2187 ahc_compile_devinfo(devinfo,
2188 our_id,
2189 SCSIID_TARGET(ahc, saved_scsiid),
2190 ahc_inb(ahc, SAVED_LUN),
2191 SCSIID_CHANNEL(ahc, saved_scsiid),
2192 role);
2193}
2194
2195struct ahc_phase_table_entry*
2196ahc_lookup_phase_entry(int phase)
2197{
2198 struct ahc_phase_table_entry *entry;
2199 struct ahc_phase_table_entry *last_entry;
2200
2201 /*
2202 * num_phases doesn't include the default entry which
2203 * will be returned if the phase doesn't match.
2204 */
2205 last_entry = &ahc_phase_table[num_phases];
2206 for (entry = ahc_phase_table; entry < last_entry; entry++) {
2207 if (phase == entry->phase)
2208 break;
2209 }
2210 return (entry);
2211}
2212
2213void
2214ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
2215 u_int lun, char channel, role_t role)
2216{
2217 devinfo->our_scsiid = our_id;
2218 devinfo->target = target;
2219 devinfo->lun = lun;
2220 devinfo->target_offset = target;
2221 devinfo->channel = channel;
2222 devinfo->role = role;
2223 if (channel == 'B')
2224 devinfo->target_offset += 8;
2225 devinfo->target_mask = (0x01 << devinfo->target_offset);
2226}
2227
2228void
2229ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2230{
2231 printf("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel,
2232 devinfo->target, devinfo->lun);
2233}
2234
2235static void
2236ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2237 struct scb *scb)
2238{
2239 role_t role;
2240 int our_id;
2241
2242 our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
2243 role = ROLE_INITIATOR;
2244 if ((scb->flags & SCB_TARGET_SCB) != 0)
2245 role = ROLE_TARGET;
2246 ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb),
2247 SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role);
2248}
2249
2250
2251/************************ Message Phase Processing ****************************/
2252static void
2253ahc_assert_atn(struct ahc_softc *ahc)
2254{
2255 u_int scsisigo;
2256
2257 scsisigo = ATNO;
2258 if ((ahc->features & AHC_DT) == 0)
2259 scsisigo |= ahc_inb(ahc, SCSISIGI);
2260 ahc_outb(ahc, SCSISIGO, scsisigo);
2261}
2262
2263/*
2264 * When an initiator transaction with the MK_MESSAGE flag either reconnects
2265 * or enters the initial message out phase, we are interrupted. Fill our
2266 * outgoing message buffer with the appropriate message and beging handing
2267 * the message phase(s) manually.
2268 */
2269static void
2270ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2271 struct scb *scb)
2272{
2273 /*
2274 * To facilitate adding multiple messages together,
2275 * each routine should increment the index and len
2276 * variables instead of setting them explicitly.
2277 */
2278 ahc->msgout_index = 0;
2279 ahc->msgout_len = 0;
2280
2281 if ((scb->flags & SCB_DEVICE_RESET) == 0
2282 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {
2283 u_int identify_msg;
2284
2285 identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
2286 if ((scb->hscb->control & DISCENB) != 0)
2287 identify_msg |= MSG_IDENTIFY_DISCFLAG;
2288 ahc->msgout_buf[ahc->msgout_index++] = identify_msg;
2289 ahc->msgout_len++;
2290
2291 if ((scb->hscb->control & TAG_ENB) != 0) {
2292 ahc->msgout_buf[ahc->msgout_index++] =
2293 scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
2294 ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;
2295 ahc->msgout_len += 2;
2296 }
2297 }
2298
2299 if (scb->flags & SCB_DEVICE_RESET) {
2300 ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;
2301 ahc->msgout_len++;
2302 ahc_print_path(ahc, scb);
2303 printf("Bus Device Reset Message Sent\n");
2304 /*
2305 * Clear our selection hardware in advance of
2306 * the busfree. We may have an entry in the waiting
2307 * Q for this target, and we don't want to go about
2308 * selecting while we handle the busfree and blow it
2309 * away.
2310 */
2311 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
2312 } else if ((scb->flags & SCB_ABORT) != 0) {
2313 if ((scb->hscb->control & TAG_ENB) != 0)
2314 ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT_TAG;
2315 else
2316 ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
2317 ahc->msgout_len++;
2318 ahc_print_path(ahc, scb);
2319 printf("Abort%s Message Sent\n",
2320 (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
2321 /*
2322 * Clear our selection hardware in advance of
2323 * the busfree. We may have an entry in the waiting
2324 * Q for this target, and we don't want to go about
2325 * selecting while we handle the busfree and blow it
2326 * away.
2327 */
2328 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
2329 } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
2330 ahc_build_transfer_msg(ahc, devinfo);
2331 } else {
2332 printf("ahc_intr: AWAITING_MSG for an SCB that "
2333 "does not have a waiting message\n");
2334 printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
2335 devinfo->target_mask);
2336 panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "
2337 "SCB flags = %x", scb->hscb->tag, scb->hscb->control,
2338 ahc_inb(ahc, MSG_OUT), scb->flags);
2339 }
2340
2341 /*
2342 * Clear the MK_MESSAGE flag from the SCB so we aren't
2343 * asked to send this message again.
2344 */
2345 ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);
2346 scb->hscb->control &= ~MK_MESSAGE;
2347 ahc->msgout_index = 0;
2348 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2349}
2350
2351/*
2352 * Build an appropriate transfer negotiation message for the
2353 * currently active target.
2354 */
2355static void
2356ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2357{
2358 /*
2359 * We need to initiate transfer negotiations.
2360 * If our current and goal settings are identical,
2361 * we want to renegotiate due to a check condition.
2362 */
2363 struct ahc_initiator_tinfo *tinfo;
2364 struct ahc_tmode_tstate *tstate;
2365 struct ahc_syncrate *rate;
2366 int dowide;
2367 int dosync;
2368 int doppr;
2369 u_int period;
2370 u_int ppr_options;
2371 u_int offset;
2372
2373 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
2374 devinfo->target, &tstate);
2375 /*
2376 * Filter our period based on the current connection.
2377 * If we can't perform DT transfers on this segment (not in LVD
2378 * mode for instance), then our decision to issue a PPR message
2379 * may change.
2380 */
2381 period = tinfo->goal.period;
2382 offset = tinfo->goal.offset;
2383 ppr_options = tinfo->goal.ppr_options;
2384 /* Target initiated PPR is not allowed in the SCSI spec */
2385 if (devinfo->role == ROLE_TARGET)
2386 ppr_options = 0;
2387 rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
2388 &ppr_options, devinfo->role);
2389 dowide = tinfo->curr.width != tinfo->goal.width;
2390 dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
2391 /*
2392 * Only use PPR if we have options that need it, even if the device
2393 * claims to support it. There might be an expander in the way
2394 * that doesn't.
2395 */
2396 doppr = ppr_options != 0;
2397
2398 if (!dowide && !dosync && !doppr) {
2399 dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
2400 dosync = tinfo->goal.offset != 0;
2401 }
2402
2403 if (!dowide && !dosync && !doppr) {
2404 /*
2405 * Force async with a WDTR message if we have a wide bus,
2406 * or just issue an SDTR with a 0 offset.
2407 */
2408 if ((ahc->features & AHC_WIDE) != 0)
2409 dowide = 1;
2410 else
2411 dosync = 1;
2412
2413 if (bootverbose) {
2414 ahc_print_devinfo(ahc, devinfo);
2415 printf("Ensuring async\n");
2416 }
2417 }
2418
2419 /* Target initiated PPR is not allowed in the SCSI spec */
2420 if (devinfo->role == ROLE_TARGET)
2421 doppr = 0;
2422
2423 /*
2424 * Both the PPR message and SDTR message require the
2425 * goal syncrate to be limited to what the target device
2426 * is capable of handling (based on whether an LVD->SE
2427 * expander is on the bus), so combine these two cases.
2428 * Regardless, guarantee that if we are using WDTR and SDTR
2429 * messages that WDTR comes first.
2430 */
2431 if (doppr || (dosync && !dowide)) {
2432
2433 offset = tinfo->goal.offset;
2434 ahc_validate_offset(ahc, tinfo, rate, &offset,
2435 doppr ? tinfo->goal.width
2436 : tinfo->curr.width,
2437 devinfo->role);
2438 if (doppr) {
2439 ahc_construct_ppr(ahc, devinfo, period, offset,
2440 tinfo->goal.width, ppr_options);
2441 } else {
2442 ahc_construct_sdtr(ahc, devinfo, period, offset);
2443 }
2444 } else {
2445 ahc_construct_wdtr(ahc, devinfo, tinfo->goal.width);
2446 }
2447}
2448
2449/*
2450 * Build a synchronous negotiation message in our message
2451 * buffer based on the input parameters.
2452 */
2453static void
2454ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2455 u_int period, u_int offset)
2456{
2457 if (offset == 0)
2458 period = AHC_ASYNC_XFER_PERIOD;
2459 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
2460 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN;
2461 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR;
2462 ahc->msgout_buf[ahc->msgout_index++] = period;
2463 ahc->msgout_buf[ahc->msgout_index++] = offset;
2464 ahc->msgout_len += 5;
2465 if (bootverbose) {
2466 printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
2467 ahc_name(ahc), devinfo->channel, devinfo->target,
2468 devinfo->lun, period, offset);
2469 }
2470}
2471
2472/*
2473 * Build a wide negotiation message in our message
2474 * buffer based on the input parameters.
2475 */
2476static void
2477ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2478 u_int bus_width)
2479{
2480 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
2481 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN;
2482 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR;
2483 ahc->msgout_buf[ahc->msgout_index++] = bus_width;
2484 ahc->msgout_len += 4;
2485 if (bootverbose) {
2486 printf("(%s:%c:%d:%d): Sending WDTR %x\n",
2487 ahc_name(ahc), devinfo->channel, devinfo->target,
2488 devinfo->lun, bus_width);
2489 }
2490}
2491
2492/*
2493 * Build a parallel protocol request message in our message
2494 * buffer based on the input parameters.
2495 */
2496static void
2497ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2498 u_int period, u_int offset, u_int bus_width,
2499 u_int ppr_options)
2500{
2501 if (offset == 0)
2502 period = AHC_ASYNC_XFER_PERIOD;
2503 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
2504 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN;
2505 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR;
2506 ahc->msgout_buf[ahc->msgout_index++] = period;
2507 ahc->msgout_buf[ahc->msgout_index++] = 0;
2508 ahc->msgout_buf[ahc->msgout_index++] = offset;
2509 ahc->msgout_buf[ahc->msgout_index++] = bus_width;
2510 ahc->msgout_buf[ahc->msgout_index++] = ppr_options;
2511 ahc->msgout_len += 8;
2512 if (bootverbose) {
2513 printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
2514 "offset %x, ppr_options %x\n", ahc_name(ahc),
2515 devinfo->channel, devinfo->target, devinfo->lun,
2516 bus_width, period, offset, ppr_options);
2517 }
2518}
2519
2520/*
2521 * Clear any active message state.
2522 */
2523static void
2524ahc_clear_msg_state(struct ahc_softc *ahc)
2525{
2526 ahc->msgout_len = 0;
2527 ahc->msgin_index = 0;
2528 ahc->msg_type = MSG_TYPE_NONE;
2529 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0) {
2530 /*
2531 * The target didn't care to respond to our
2532 * message request, so clear ATN.
2533 */
2534 ahc_outb(ahc, CLRSINT1, CLRATNO);
2535 }
2536 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
2537 ahc_outb(ahc, SEQ_FLAGS2,
2538 ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
2539}
2540
2541static void
2542ahc_handle_proto_violation(struct ahc_softc *ahc)
2543{
2544 struct ahc_devinfo devinfo;
2545 struct scb *scb;
2546 u_int scbid;
2547 u_int seq_flags;
2548 u_int curphase;
2549 u_int lastphase;
2550 int found;
2551
2552 ahc_fetch_devinfo(ahc, &devinfo);
2553 scbid = ahc_inb(ahc, SCB_TAG);
2554 scb = ahc_lookup_scb(ahc, scbid);
2555 seq_flags = ahc_inb(ahc, SEQ_FLAGS);
2556 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
2557 lastphase = ahc_inb(ahc, LASTPHASE);
2558 if ((seq_flags & NOT_IDENTIFIED) != 0) {
2559
2560 /*
2561 * The reconnecting target either did not send an
2562 * identify message, or did, but we didn't find an SCB
2563 * to match.
2564 */
2565 ahc_print_devinfo(ahc, &devinfo);
2566 printf("Target did not send an IDENTIFY message. "
2567 "LASTPHASE = 0x%x.\n", lastphase);
2568 scb = NULL;
2569 } else if (scb == NULL) {
2570 /*
2571 * We don't seem to have an SCB active for this
2572 * transaction. Print an error and reset the bus.
2573 */
2574 ahc_print_devinfo(ahc, &devinfo);
2575 printf("No SCB found during protocol violation\n");
2576 goto proto_violation_reset;
2577 } else {
2578 ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
2579 if ((seq_flags & NO_CDB_SENT) != 0) {
2580 ahc_print_path(ahc, scb);
2581 printf("No or incomplete CDB sent to device.\n");
2582 } else if ((ahc_inb(ahc, SCB_CONTROL) & STATUS_RCVD) == 0) {
2583 /*
2584 * The target never bothered to provide status to
2585 * us prior to completing the command. Since we don't
2586 * know the disposition of this command, we must attempt
2587 * to abort it. Assert ATN and prepare to send an abort
2588 * message.
2589 */
2590 ahc_print_path(ahc, scb);
2591 printf("Completed command without status.\n");
2592 } else {
2593 ahc_print_path(ahc, scb);
2594 printf("Unknown protocol violation.\n");
2595 ahc_dump_card_state(ahc);
2596 }
2597 }
2598 if ((lastphase & ~P_DATAIN_DT) == 0
2599 || lastphase == P_COMMAND) {
2600proto_violation_reset:
2601 /*
2602 * Target either went directly to data/command
2603 * phase or didn't respond to our ATN.
2604 * The only safe thing to do is to blow
2605 * it away with a bus reset.
2606 */
2607 found = ahc_reset_channel(ahc, 'A', TRUE);
2608 printf("%s: Issued Channel %c Bus Reset. "
2609 "%d SCBs aborted\n", ahc_name(ahc), 'A', found);
2610 } else {
2611 /*
2612 * Leave the selection hardware off in case
2613 * this abort attempt will affect yet to
2614 * be sent commands.
2615 */
2616 ahc_outb(ahc, SCSISEQ,
2617 ahc_inb(ahc, SCSISEQ) & ~ENSELO);
2618 ahc_assert_atn(ahc);
2619 ahc_outb(ahc, MSG_OUT, HOST_MSG);
2620 if (scb == NULL) {
2621 ahc_print_devinfo(ahc, &devinfo);
2622 ahc->msgout_buf[0] = MSG_ABORT_TASK;
2623 ahc->msgout_len = 1;
2624 ahc->msgout_index = 0;
2625 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2626 } else {
2627 ahc_print_path(ahc, scb);
2628 scb->flags |= SCB_ABORT;
2629 }
2630 printf("Protocol violation %s. Attempting to abort.\n",
2631 ahc_lookup_phase_entry(curphase)->phasemsg);
2632 }
2633}
2634
2635/*
2636 * Manual message loop handler.
2637 */
2638static void
2639ahc_handle_message_phase(struct ahc_softc *ahc)
2640{
2641 struct ahc_devinfo devinfo;
2642 u_int bus_phase;
2643 int end_session;
2644
2645 ahc_fetch_devinfo(ahc, &devinfo);
2646 end_session = FALSE;
2647 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
2648
2649reswitch:
2650 switch (ahc->msg_type) {
2651 case MSG_TYPE_INITIATOR_MSGOUT:
2652 {
2653 int lastbyte;
2654 int phasemis;
2655 int msgdone;
2656
2657 if (ahc->msgout_len == 0)
2658 panic("HOST_MSG_LOOP interrupt with no active message");
2659
2660#ifdef AHC_DEBUG
2661 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2662 ahc_print_devinfo(ahc, &devinfo);
2663 printf("INITIATOR_MSG_OUT");
2664 }
2665#endif
2666 phasemis = bus_phase != P_MESGOUT;
2667 if (phasemis) {
2668#ifdef AHC_DEBUG
2669 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2670 printf(" PHASEMIS %s\n",
2671 ahc_lookup_phase_entry(bus_phase)
2672 ->phasemsg);
2673 }
2674#endif
2675 if (bus_phase == P_MESGIN) {
2676 /*
2677 * Change gears and see if
2678 * this messages is of interest to
2679 * us or should be passed back to
2680 * the sequencer.
2681 */
2682 ahc_outb(ahc, CLRSINT1, CLRATNO);
2683 ahc->send_msg_perror = FALSE;
2684 ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN;
2685 ahc->msgin_index = 0;
2686 goto reswitch;
2687 }
2688 end_session = TRUE;
2689 break;
2690 }
2691
2692 if (ahc->send_msg_perror) {
2693 ahc_outb(ahc, CLRSINT1, CLRATNO);
2694 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
2695#ifdef AHC_DEBUG
2696 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2697 printf(" byte 0x%x\n", ahc->send_msg_perror);
2698#endif
2699 ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);
2700 break;
2701 }
2702
2703 msgdone = ahc->msgout_index == ahc->msgout_len;
2704 if (msgdone) {
2705 /*
2706 * The target has requested a retry.
2707 * Re-assert ATN, reset our message index to
2708 * 0, and try again.
2709 */
2710 ahc->msgout_index = 0;
2711 ahc_assert_atn(ahc);
2712 }
2713
2714 lastbyte = ahc->msgout_index == (ahc->msgout_len - 1);
2715 if (lastbyte) {
2716 /* Last byte is signified by dropping ATN */
2717 ahc_outb(ahc, CLRSINT1, CLRATNO);
2718 }
2719
2720 /*
2721 * Clear our interrupt status and present
2722 * the next byte on the bus.
2723 */
2724 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
2725#ifdef AHC_DEBUG
2726 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2727 printf(" byte 0x%x\n",
2728 ahc->msgout_buf[ahc->msgout_index]);
2729#endif
2730 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
2731 break;
2732 }
2733 case MSG_TYPE_INITIATOR_MSGIN:
2734 {
2735 int phasemis;
2736 int message_done;
2737
2738#ifdef AHC_DEBUG
2739 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2740 ahc_print_devinfo(ahc, &devinfo);
2741 printf("INITIATOR_MSG_IN");
2742 }
2743#endif
2744 phasemis = bus_phase != P_MESGIN;
2745 if (phasemis) {
2746#ifdef AHC_DEBUG
2747 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2748 printf(" PHASEMIS %s\n",
2749 ahc_lookup_phase_entry(bus_phase)
2750 ->phasemsg);
2751 }
2752#endif
2753 ahc->msgin_index = 0;
2754 if (bus_phase == P_MESGOUT
2755 && (ahc->send_msg_perror == TRUE
2756 || (ahc->msgout_len != 0
2757 && ahc->msgout_index == 0))) {
2758 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2759 goto reswitch;
2760 }
2761 end_session = TRUE;
2762 break;
2763 }
2764
2765 /* Pull the byte in without acking it */
2766 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);
2767#ifdef AHC_DEBUG
2768 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2769 printf(" byte 0x%x\n",
2770 ahc->msgin_buf[ahc->msgin_index]);
2771#endif
2772
2773 message_done = ahc_parse_msg(ahc, &devinfo);
2774
2775 if (message_done) {
2776 /*
2777 * Clear our incoming message buffer in case there
2778 * is another message following this one.
2779 */
2780 ahc->msgin_index = 0;
2781
2782 /*
2783 * If this message illicited a response,
2784 * assert ATN so the target takes us to the
2785 * message out phase.
2786 */
2787 if (ahc->msgout_len != 0) {
2788#ifdef AHC_DEBUG
2789 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2790 ahc_print_devinfo(ahc, &devinfo);
2791 printf("Asserting ATN for response\n");
2792 }
2793#endif
2794 ahc_assert_atn(ahc);
2795 }
2796 } else
2797 ahc->msgin_index++;
2798
2799 if (message_done == MSGLOOP_TERMINATED) {
2800 end_session = TRUE;
2801 } else {
2802 /* Ack the byte */
2803 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
2804 ahc_inb(ahc, SCSIDATL);
2805 }
2806 break;
2807 }
2808 case MSG_TYPE_TARGET_MSGIN:
2809 {
2810 int msgdone;
2811 int msgout_request;
2812
2813 if (ahc->msgout_len == 0)
2814 panic("Target MSGIN with no active message");
2815
2816 /*
2817 * If we interrupted a mesgout session, the initiator
2818 * will not know this until our first REQ. So, we
2819 * only honor mesgout requests after we've sent our
2820 * first byte.
2821 */
2822 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0
2823 && ahc->msgout_index > 0)
2824 msgout_request = TRUE;
2825 else
2826 msgout_request = FALSE;
2827
2828 if (msgout_request) {
2829
2830 /*
2831 * Change gears and see if
2832 * this messages is of interest to
2833 * us or should be passed back to
2834 * the sequencer.
2835 */
2836 ahc->msg_type = MSG_TYPE_TARGET_MSGOUT;
2837 ahc_outb(ahc, SCSISIGO, P_MESGOUT | BSYO);
2838 ahc->msgin_index = 0;
2839 /* Dummy read to REQ for first byte */
2840 ahc_inb(ahc, SCSIDATL);
2841 ahc_outb(ahc, SXFRCTL0,
2842 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2843 break;
2844 }
2845
2846 msgdone = ahc->msgout_index == ahc->msgout_len;
2847 if (msgdone) {
2848 ahc_outb(ahc, SXFRCTL0,
2849 ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
2850 end_session = TRUE;
2851 break;
2852 }
2853
2854 /*
2855 * Present the next byte on the bus.
2856 */
2857 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2858 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
2859 break;
2860 }
2861 case MSG_TYPE_TARGET_MSGOUT:
2862 {
2863 int lastbyte;
2864 int msgdone;
2865
2866 /*
2867 * The initiator signals that this is
2868 * the last byte by dropping ATN.
2869 */
2870 lastbyte = (ahc_inb(ahc, SCSISIGI) & ATNI) == 0;
2871
2872 /*
2873 * Read the latched byte, but turn off SPIOEN first
2874 * so that we don't inadvertently cause a REQ for the
2875 * next byte.
2876 */
2877 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
2878 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIDATL);
2879 msgdone = ahc_parse_msg(ahc, &devinfo);
2880 if (msgdone == MSGLOOP_TERMINATED) {
2881 /*
2882 * The message is *really* done in that it caused
2883 * us to go to bus free. The sequencer has already
2884 * been reset at this point, so pull the ejection
2885 * handle.
2886 */
2887 return;
2888 }
2889
2890 ahc->msgin_index++;
2891
2892 /*
2893 * XXX Read spec about initiator dropping ATN too soon
2894 * and use msgdone to detect it.
2895 */
2896 if (msgdone == MSGLOOP_MSGCOMPLETE) {
2897 ahc->msgin_index = 0;
2898
2899 /*
2900 * If this message illicited a response, transition
2901 * to the Message in phase and send it.
2902 */
2903 if (ahc->msgout_len != 0) {
2904 ahc_outb(ahc, SCSISIGO, P_MESGIN | BSYO);
2905 ahc_outb(ahc, SXFRCTL0,
2906 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2907 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
2908 ahc->msgin_index = 0;
2909 break;
2910 }
2911 }
2912
2913 if (lastbyte)
2914 end_session = TRUE;
2915 else {
2916 /* Ask for the next byte. */
2917 ahc_outb(ahc, SXFRCTL0,
2918 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2919 }
2920
2921 break;
2922 }
2923 default:
2924 panic("Unknown REQINIT message type");
2925 }
2926
2927 if (end_session) {
2928 ahc_clear_msg_state(ahc);
2929 ahc_outb(ahc, RETURN_1, EXIT_MSG_LOOP);
2930 } else
2931 ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
2932}
2933
2934/*
2935 * See if we sent a particular extended message to the target.
2936 * If "full" is true, return true only if the target saw the full
2937 * message. If "full" is false, return true if the target saw at
2938 * least the first byte of the message.
2939 */
2940static int
2941ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
2942{
2943 int found;
2944 u_int index;
2945
2946 found = FALSE;
2947 index = 0;
2948
2949 while (index < ahc->msgout_len) {
2950 if (ahc->msgout_buf[index] == MSG_EXTENDED) {
2951 u_int end_index;
2952
2953 end_index = index + 1 + ahc->msgout_buf[index + 1];
2954 if (ahc->msgout_buf[index+2] == msgval
2955 && type == AHCMSG_EXT) {
2956
2957 if (full) {
2958 if (ahc->msgout_index > end_index)
2959 found = TRUE;
2960 } else if (ahc->msgout_index > index)
2961 found = TRUE;
2962 }
2963 index = end_index;
2964 } else if (ahc->msgout_buf[index] >= MSG_SIMPLE_TASK
2965 && ahc->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
2966
2967 /* Skip tag type and tag id or residue param*/
2968 index += 2;
2969 } else {
2970 /* Single byte message */
2971 if (type == AHCMSG_1B
2972 && ahc->msgout_buf[index] == msgval
2973 && ahc->msgout_index > index)
2974 found = TRUE;
2975 index++;
2976 }
2977
2978 if (found)
2979 break;
2980 }
2981 return (found);
2982}
2983
2984/*
2985 * Wait for a complete incoming message, parse it, and respond accordingly.
2986 */
2987static int
2988ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2989{
2990 struct ahc_initiator_tinfo *tinfo;
2991 struct ahc_tmode_tstate *tstate;
2992 int reject;
2993 int done;
2994 int response;
2995 u_int targ_scsirate;
2996
2997 done = MSGLOOP_IN_PROG;
2998 response = FALSE;
2999 reject = FALSE;
3000 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
3001 devinfo->target, &tstate);
3002 targ_scsirate = tinfo->scsirate;
3003
3004 /*
3005 * Parse as much of the message as is available,
3006 * rejecting it if we don't support it. When
3007 * the entire message is available and has been
3008 * handled, return MSGLOOP_MSGCOMPLETE, indicating
3009 * that we have parsed an entire message.
3010 *
3011 * In the case of extended messages, we accept the length
3012 * byte outright and perform more checking once we know the
3013 * extended message type.
3014 */
3015 switch (ahc->msgin_buf[0]) {
3016 case MSG_DISCONNECT:
3017 case MSG_SAVEDATAPOINTER:
3018 case MSG_CMDCOMPLETE:
3019 case MSG_RESTOREPOINTERS:
3020 case MSG_IGN_WIDE_RESIDUE:
3021 /*
3022 * End our message loop as these are messages
3023 * the sequencer handles on its own.
3024 */
3025 done = MSGLOOP_TERMINATED;
3026 break;
3027 case MSG_MESSAGE_REJECT:
3028 response = ahc_handle_msg_reject(ahc, devinfo);
3029 /* FALLTHROUGH */
3030 case MSG_NOOP:
3031 done = MSGLOOP_MSGCOMPLETE;
3032 break;
3033 case MSG_EXTENDED:
3034 {
3035 /* Wait for enough of the message to begin validation */
3036 if (ahc->msgin_index < 2)
3037 break;
3038 switch (ahc->msgin_buf[2]) {
3039 case MSG_EXT_SDTR:
3040 {
3041 struct ahc_syncrate *syncrate;
3042 u_int period;
3043 u_int ppr_options;
3044 u_int offset;
3045 u_int saved_offset;
3046
3047 if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
3048 reject = TRUE;
3049 break;
3050 }
3051
3052 /*
3053 * Wait until we have both args before validating
3054 * and acting on this message.
3055 *
3056 * Add one to MSG_EXT_SDTR_LEN to account for
3057 * the extended message preamble.
3058 */
3059 if (ahc->msgin_index < (MSG_EXT_SDTR_LEN + 1))
3060 break;
3061
3062 period = ahc->msgin_buf[3];
3063 ppr_options = 0;
3064 saved_offset = offset = ahc->msgin_buf[4];
3065 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
3066 &ppr_options,
3067 devinfo->role);
3068 ahc_validate_offset(ahc, tinfo, syncrate, &offset,
3069 targ_scsirate & WIDEXFER,
3070 devinfo->role);
3071 if (bootverbose) {
3072 printf("(%s:%c:%d:%d): Received "
3073 "SDTR period %x, offset %x\n\t"
3074 "Filtered to period %x, offset %x\n",
3075 ahc_name(ahc), devinfo->channel,
3076 devinfo->target, devinfo->lun,
3077 ahc->msgin_buf[3], saved_offset,
3078 period, offset);
3079 }
3080 ahc_set_syncrate(ahc, devinfo,
3081 syncrate, period,
3082 offset, ppr_options,
3083 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3084 /*paused*/TRUE);
3085
3086 /*
3087 * See if we initiated Sync Negotiation
3088 * and didn't have to fall down to async
3089 * transfers.
3090 */
3091 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, TRUE)) {
3092 /* We started it */
3093 if (saved_offset != offset) {
3094 /* Went too low - force async */
3095 reject = TRUE;
3096 }
3097 } else {
3098 /*
3099 * Send our own SDTR in reply
3100 */
3101 if (bootverbose
3102 && devinfo->role == ROLE_INITIATOR) {
3103 printf("(%s:%c:%d:%d): Target "
3104 "Initiated SDTR\n",
3105 ahc_name(ahc), devinfo->channel,
3106 devinfo->target, devinfo->lun);
3107 }
3108 ahc->msgout_index = 0;
3109 ahc->msgout_len = 0;
3110 ahc_construct_sdtr(ahc, devinfo,
3111 period, offset);
3112 ahc->msgout_index = 0;
3113 response = TRUE;
3114 }
3115 done = MSGLOOP_MSGCOMPLETE;
3116 break;
3117 }
3118 case MSG_EXT_WDTR:
3119 {
3120 u_int bus_width;
3121 u_int saved_width;
3122 u_int sending_reply;
3123
3124 sending_reply = FALSE;
3125 if (ahc->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
3126 reject = TRUE;
3127 break;
3128 }
3129
3130 /*
3131 * Wait until we have our arg before validating
3132 * and acting on this message.
3133 *
3134 * Add one to MSG_EXT_WDTR_LEN to account for
3135 * the extended message preamble.
3136 */
3137 if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1))
3138 break;
3139
3140 bus_width = ahc->msgin_buf[3];
3141 saved_width = bus_width;
3142 ahc_validate_width(ahc, tinfo, &bus_width,
3143 devinfo->role);
3144 if (bootverbose) {
3145 printf("(%s:%c:%d:%d): Received WDTR "
3146 "%x filtered to %x\n",
3147 ahc_name(ahc), devinfo->channel,
3148 devinfo->target, devinfo->lun,
3149 saved_width, bus_width);
3150 }
3151
3152 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, TRUE)) {
3153 /*
3154 * Don't send a WDTR back to the
3155 * target, since we asked first.
3156 * If the width went higher than our
3157 * request, reject it.
3158 */
3159 if (saved_width > bus_width) {
3160 reject = TRUE;
3161 printf("(%s:%c:%d:%d): requested %dBit "
3162 "transfers. Rejecting...\n",
3163 ahc_name(ahc), devinfo->channel,
3164 devinfo->target, devinfo->lun,
3165 8 * (0x01 << bus_width));
3166 bus_width = 0;
3167 }
3168 } else {
3169 /*
3170 * Send our own WDTR in reply
3171 */
3172 if (bootverbose
3173 && devinfo->role == ROLE_INITIATOR) {
3174 printf("(%s:%c:%d:%d): Target "
3175 "Initiated WDTR\n",
3176 ahc_name(ahc), devinfo->channel,
3177 devinfo->target, devinfo->lun);
3178 }
3179 ahc->msgout_index = 0;
3180 ahc->msgout_len = 0;
3181 ahc_construct_wdtr(ahc, devinfo, bus_width);
3182 ahc->msgout_index = 0;
3183 response = TRUE;
3184 sending_reply = TRUE;
3185 }
3186 /*
3187 * After a wide message, we are async, but
3188 * some devices don't seem to honor this portion
3189 * of the spec. Force a renegotiation of the
3190 * sync component of our transfer agreement even
3191 * if our goal is async. By updating our width
3192 * after forcing the negotiation, we avoid
3193 * renegotiating for width.
3194 */
3195 ahc_update_neg_request(ahc, devinfo, tstate,
3196 tinfo, AHC_NEG_ALWAYS);
3197 ahc_set_width(ahc, devinfo, bus_width,
3198 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3199 /*paused*/TRUE);
3200 if (sending_reply == FALSE && reject == FALSE) {
3201
3202 /*
3203 * We will always have an SDTR to send.
3204 */
3205 ahc->msgout_index = 0;
3206 ahc->msgout_len = 0;
3207 ahc_build_transfer_msg(ahc, devinfo);
3208 ahc->msgout_index = 0;
3209 response = TRUE;
3210 }
3211 done = MSGLOOP_MSGCOMPLETE;
3212 break;
3213 }
3214 case MSG_EXT_PPR:
3215 {
3216 struct ahc_syncrate *syncrate;
3217 u_int period;
3218 u_int offset;
3219 u_int bus_width;
3220 u_int ppr_options;
3221 u_int saved_width;
3222 u_int saved_offset;
3223 u_int saved_ppr_options;
3224
3225 if (ahc->msgin_buf[1] != MSG_EXT_PPR_LEN) {
3226 reject = TRUE;
3227 break;
3228 }
3229
3230 /*
3231 * Wait until we have all args before validating
3232 * and acting on this message.
3233 *
3234 * Add one to MSG_EXT_PPR_LEN to account for
3235 * the extended message preamble.
3236 */
3237 if (ahc->msgin_index < (MSG_EXT_PPR_LEN + 1))
3238 break;
3239
3240 period = ahc->msgin_buf[3];
3241 offset = ahc->msgin_buf[5];
3242 bus_width = ahc->msgin_buf[6];
3243 saved_width = bus_width;
3244 ppr_options = ahc->msgin_buf[7];
3245 /*
3246 * According to the spec, a DT only
3247 * period factor with no DT option
3248 * set implies async.
3249 */
3250 if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
3251 && period == 9)
3252 offset = 0;
3253 saved_ppr_options = ppr_options;
3254 saved_offset = offset;
3255
3256 /*
3257 * Mask out any options we don't support
3258 * on any controller. Transfer options are
3259 * only available if we are negotiating wide.
3260 */
3261 ppr_options &= MSG_EXT_PPR_DT_REQ;
3262 if (bus_width == 0)
3263 ppr_options = 0;
3264
3265 ahc_validate_width(ahc, tinfo, &bus_width,
3266 devinfo->role);
3267 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
3268 &ppr_options,
3269 devinfo->role);
3270 ahc_validate_offset(ahc, tinfo, syncrate,
3271 &offset, bus_width,
3272 devinfo->role);
3273
3274 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, TRUE)) {
3275 /*
3276 * If we are unable to do any of the
3277 * requested options (we went too low),
3278 * then we'll have to reject the message.
3279 */
3280 if (saved_width > bus_width
3281 || saved_offset != offset
3282 || saved_ppr_options != ppr_options) {
3283 reject = TRUE;
3284 period = 0;
3285 offset = 0;
3286 bus_width = 0;
3287 ppr_options = 0;
3288 syncrate = NULL;
3289 }
3290 } else {
3291 if (devinfo->role != ROLE_TARGET)
3292 printf("(%s:%c:%d:%d): Target "
3293 "Initiated PPR\n",
3294 ahc_name(ahc), devinfo->channel,
3295 devinfo->target, devinfo->lun);
3296 else
3297 printf("(%s:%c:%d:%d): Initiator "
3298 "Initiated PPR\n",
3299 ahc_name(ahc), devinfo->channel,
3300 devinfo->target, devinfo->lun);
3301 ahc->msgout_index = 0;
3302 ahc->msgout_len = 0;
3303 ahc_construct_ppr(ahc, devinfo, period, offset,
3304 bus_width, ppr_options);
3305 ahc->msgout_index = 0;
3306 response = TRUE;
3307 }
3308 if (bootverbose) {
3309 printf("(%s:%c:%d:%d): Received PPR width %x, "
3310 "period %x, offset %x,options %x\n"
3311 "\tFiltered to width %x, period %x, "
3312 "offset %x, options %x\n",
3313 ahc_name(ahc), devinfo->channel,
3314 devinfo->target, devinfo->lun,
3315 saved_width, ahc->msgin_buf[3],
3316 saved_offset, saved_ppr_options,
3317 bus_width, period, offset, ppr_options);
3318 }
3319 ahc_set_width(ahc, devinfo, bus_width,
3320 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3321 /*paused*/TRUE);
3322 ahc_set_syncrate(ahc, devinfo,
3323 syncrate, period,
3324 offset, ppr_options,
3325 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3326 /*paused*/TRUE);
3327 done = MSGLOOP_MSGCOMPLETE;
3328 break;
3329 }
3330 default:
3331 /* Unknown extended message. Reject it. */
3332 reject = TRUE;
3333 break;
3334 }
3335 break;
3336 }
3337#ifdef AHC_TARGET_MODE
3338 case MSG_BUS_DEV_RESET:
3339 ahc_handle_devreset(ahc, devinfo,
3340 CAM_BDR_SENT,
3341 "Bus Device Reset Received",
3342 /*verbose_level*/0);
3343 ahc_restart(ahc);
3344 done = MSGLOOP_TERMINATED;
3345 break;
3346 case MSG_ABORT_TAG:
3347 case MSG_ABORT:
3348 case MSG_CLEAR_QUEUE:
3349 {
3350 int tag;
3351
3352 /* Target mode messages */
3353 if (devinfo->role != ROLE_TARGET) {
3354 reject = TRUE;
3355 break;
3356 }
3357 tag = SCB_LIST_NULL;
3358 if (ahc->msgin_buf[0] == MSG_ABORT_TAG)
3359 tag = ahc_inb(ahc, INITIATOR_TAG);
3360 ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
3361 devinfo->lun, tag, ROLE_TARGET,
3362 CAM_REQ_ABORTED);
3363
3364 tstate = ahc->enabled_targets[devinfo->our_scsiid];
3365 if (tstate != NULL) {
3366 struct ahc_tmode_lstate* lstate;
3367
3368 lstate = tstate->enabled_luns[devinfo->lun];
3369 if (lstate != NULL) {
3370 ahc_queue_lstate_event(ahc, lstate,
3371 devinfo->our_scsiid,
3372 ahc->msgin_buf[0],
3373 /*arg*/tag);
3374 ahc_send_lstate_events(ahc, lstate);
3375 }
3376 }
3377 ahc_restart(ahc);
3378 done = MSGLOOP_TERMINATED;
3379 break;
3380 }
3381#endif
3382 case MSG_TERM_IO_PROC:
3383 default:
3384 reject = TRUE;
3385 break;
3386 }
3387
3388 if (reject) {
3389 /*
3390 * Setup to reject the message.
3391 */
3392 ahc->msgout_index = 0;
3393 ahc->msgout_len = 1;
3394 ahc->msgout_buf[0] = MSG_MESSAGE_REJECT;
3395 done = MSGLOOP_MSGCOMPLETE;
3396 response = TRUE;
3397 }
3398
3399 if (done != MSGLOOP_IN_PROG && !response)
3400 /* Clear the outgoing message buffer */
3401 ahc->msgout_len = 0;
3402
3403 return (done);
3404}
3405
3406/*
3407 * Process a message reject message.
3408 */
3409static int
3410ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3411{
3412 /*
3413 * What we care about here is if we had an
3414 * outstanding SDTR or WDTR message for this
3415 * target. If we did, this is a signal that
3416 * the target is refusing negotiation.
3417 */
3418 struct scb *scb;
3419 struct ahc_initiator_tinfo *tinfo;
3420 struct ahc_tmode_tstate *tstate;
3421 u_int scb_index;
3422 u_int last_msg;
3423 int response = 0;
3424
3425 scb_index = ahc_inb(ahc, SCB_TAG);
3426 scb = ahc_lookup_scb(ahc, scb_index);
3427 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
3428 devinfo->our_scsiid,
3429 devinfo->target, &tstate);
3430 /* Might be necessary */
3431 last_msg = ahc_inb(ahc, LAST_MSG);
3432
3433 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) {
3434 /*
3435 * Target does not support the PPR message.
3436 * Attempt to negotiate SPI-2 style.
3437 */
3438 if (bootverbose) {
3439 printf("(%s:%c:%d:%d): PPR Rejected. "
3440 "Trying WDTR/SDTR\n",
3441 ahc_name(ahc), devinfo->channel,
3442 devinfo->target, devinfo->lun);
3443 }
3444 tinfo->goal.ppr_options = 0;
3445 tinfo->curr.transport_version = 2;
3446 tinfo->goal.transport_version = 2;
3447 ahc->msgout_index = 0;
3448 ahc->msgout_len = 0;
3449 ahc_build_transfer_msg(ahc, devinfo);
3450 ahc->msgout_index = 0;
3451 response = 1;
3452 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
3453
3454 /* note 8bit xfers */
3455 printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
3456 "8bit transfers\n", ahc_name(ahc),
3457 devinfo->channel, devinfo->target, devinfo->lun);
3458 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
3459 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3460 /*paused*/TRUE);
3461 /*
3462 * No need to clear the sync rate. If the target
3463 * did not accept the command, our syncrate is
3464 * unaffected. If the target started the negotiation,
3465 * but rejected our response, we already cleared the
3466 * sync rate before sending our WDTR.
3467 */
3468 if (tinfo->goal.offset != tinfo->curr.offset) {
3469
3470 /* Start the sync negotiation */
3471 ahc->msgout_index = 0;
3472 ahc->msgout_len = 0;
3473 ahc_build_transfer_msg(ahc, devinfo);
3474 ahc->msgout_index = 0;
3475 response = 1;
3476 }
3477 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) {
3478 /* note asynch xfers and clear flag */
3479 ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,
3480 /*offset*/0, /*ppr_options*/0,
3481 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3482 /*paused*/TRUE);
3483 printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
3484 "Using asynchronous transfers\n",
3485 ahc_name(ahc), devinfo->channel,
3486 devinfo->target, devinfo->lun);
3487 } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
3488 int tag_type;
3489 int mask;
3490
3491 tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
3492
3493 if (tag_type == MSG_SIMPLE_TASK) {
3494 printf("(%s:%c:%d:%d): refuses tagged commands. "
3495 "Performing non-tagged I/O\n", ahc_name(ahc),
3496 devinfo->channel, devinfo->target, devinfo->lun);
3497 ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE);
3498 mask = ~0x23;
3499 } else {
3500 printf("(%s:%c:%d:%d): refuses %s tagged commands. "
3501 "Performing simple queue tagged I/O only\n",
3502 ahc_name(ahc), devinfo->channel, devinfo->target,
3503 devinfo->lun, tag_type == MSG_ORDERED_TASK
3504 ? "ordered" : "head of queue");
3505 ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC);
3506 mask = ~0x03;
3507 }
3508
3509 /*
3510 * Resend the identify for this CCB as the target
3511 * may believe that the selection is invalid otherwise.
3512 */
3513 ahc_outb(ahc, SCB_CONTROL,
3514 ahc_inb(ahc, SCB_CONTROL) & mask);
3515 scb->hscb->control &= mask;
3516 ahc_set_transaction_tag(scb, /*enabled*/FALSE,
3517 /*type*/MSG_SIMPLE_TASK);
3518 ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
3519 ahc_assert_atn(ahc);
3520
3521 /*
3522 * This transaction is now at the head of
3523 * the untagged queue for this target.
3524 */
3525 if ((ahc->flags & AHC_SCB_BTT) == 0) {
3526 struct scb_tailq *untagged_q;
3527
3528 untagged_q =
3529 &(ahc->untagged_queues[devinfo->target_offset]);
3530 TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);
3531 scb->flags |= SCB_UNTAGGEDQ;
3532 }
3533 ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
3534 scb->hscb->tag);
3535
3536 /*
3537 * Requeue all tagged commands for this target
3538 * currently in our posession so they can be
3539 * converted to untagged commands.
3540 */
3541 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
3542 SCB_GET_CHANNEL(ahc, scb),
3543 SCB_GET_LUN(scb), /*tag*/SCB_LIST_NULL,
3544 ROLE_INITIATOR, CAM_REQUEUE_REQ,
3545 SEARCH_COMPLETE);
3546 } else {
3547 /*
3548 * Otherwise, we ignore it.
3549 */
3550 printf("%s:%c:%d: Message reject for %x -- ignored\n",
3551 ahc_name(ahc), devinfo->channel, devinfo->target,
3552 last_msg);
3553 }
3554 return (response);
3555}
3556
3557/*
3558 * Process an ingnore wide residue message.
3559 */
3560static void
3561ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3562{
3563 u_int scb_index;
3564 struct scb *scb;
3565
3566 scb_index = ahc_inb(ahc, SCB_TAG);
3567 scb = ahc_lookup_scb(ahc, scb_index);
3568 /*
3569 * XXX Actually check data direction in the sequencer?
3570 * Perhaps add datadir to some spare bits in the hscb?
3571 */
3572 if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0
3573 || ahc_get_transfer_dir(scb) != CAM_DIR_IN) {
3574 /*
3575 * Ignore the message if we haven't
3576 * seen an appropriate data phase yet.
3577 */
3578 } else {
3579 /*
3580 * If the residual occurred on the last
3581 * transfer and the transfer request was
3582 * expected to end on an odd count, do
3583 * nothing. Otherwise, subtract a byte
3584 * and update the residual count accordingly.
3585 */
3586 uint32_t sgptr;
3587
3588 sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
3589 if ((sgptr & SG_LIST_NULL) != 0
3590 && (ahc_inb(ahc, SCB_LUN) & SCB_XFERLEN_ODD) != 0) {
3591 /*
3592 * If the residual occurred on the last
3593 * transfer and the transfer request was
3594 * expected to end on an odd count, do
3595 * nothing.
3596 */
3597 } else {
3598 struct ahc_dma_seg *sg;
3599 uint32_t data_cnt;
3600 uint32_t data_addr;
3601 uint32_t sglen;
3602
3603 /* Pull in all of the sgptr */
3604 sgptr = ahc_inl(ahc, SCB_RESIDUAL_SGPTR);
3605 data_cnt = ahc_inl(ahc, SCB_RESIDUAL_DATACNT);
3606
3607 if ((sgptr & SG_LIST_NULL) != 0) {
3608 /*
3609 * The residual data count is not updated
3610 * for the command run to completion case.
3611 * Explicitly zero the count.
3612 */
3613 data_cnt &= ~AHC_SG_LEN_MASK;
3614 }
3615
3616 data_addr = ahc_inl(ahc, SHADDR);
3617
3618 data_cnt += 1;
3619 data_addr -= 1;
3620 sgptr &= SG_PTR_MASK;
3621
3622 sg = ahc_sg_bus_to_virt(scb, sgptr);
3623
3624 /*
3625 * The residual sg ptr points to the next S/G
3626 * to load so we must go back one.
3627 */
3628 sg--;
3629 sglen = ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
3630 if (sg != scb->sg_list
3631 && sglen < (data_cnt & AHC_SG_LEN_MASK)) {
3632
3633 sg--;
3634 sglen = ahc_le32toh(sg->len);
3635 /*
3636 * Preserve High Address and SG_LIST bits
3637 * while setting the count to 1.
3638 */
3639 data_cnt = 1 | (sglen & (~AHC_SG_LEN_MASK));
3640 data_addr = ahc_le32toh(sg->addr)
3641 + (sglen & AHC_SG_LEN_MASK) - 1;
3642
3643 /*
3644 * Increment sg so it points to the
3645 * "next" sg.
3646 */
3647 sg++;
3648 sgptr = ahc_sg_virt_to_bus(scb, sg);
3649 }
3650 ahc_outl(ahc, SCB_RESIDUAL_SGPTR, sgptr);
3651 ahc_outl(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
3652 /*
3653 * Toggle the "oddness" of the transfer length
3654 * to handle this mid-transfer ignore wide
3655 * residue. This ensures that the oddness is
3656 * correct for subsequent data transfers.
3657 */
3658 ahc_outb(ahc, SCB_LUN,
3659 ahc_inb(ahc, SCB_LUN) ^ SCB_XFERLEN_ODD);
3660 }
3661 }
3662}
3663
3664
3665/*
3666 * Reinitialize the data pointers for the active transfer
3667 * based on its current residual.
3668 */
3669static void
3670ahc_reinitialize_dataptrs(struct ahc_softc *ahc)
3671{
3672 struct scb *scb;
3673 struct ahc_dma_seg *sg;
3674 u_int scb_index;
3675 uint32_t sgptr;
3676 uint32_t resid;
3677 uint32_t dataptr;
3678
3679 scb_index = ahc_inb(ahc, SCB_TAG);
3680 scb = ahc_lookup_scb(ahc, scb_index);
3681 sgptr = (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
3682 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
3683 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8)
3684 | ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
3685
3686 sgptr &= SG_PTR_MASK;
3687 sg = ahc_sg_bus_to_virt(scb, sgptr);
3688
3689 /* The residual sg_ptr always points to the next sg */
3690 sg--;
3691
3692 resid = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 2) << 16)
3693 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 1) << 8)
3694 | ahc_inb(ahc, SCB_RESIDUAL_DATACNT);
3695
3696 dataptr = ahc_le32toh(sg->addr)
3697 + (ahc_le32toh(sg->len) & AHC_SG_LEN_MASK)
3698 - resid;
3699 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
3700 u_int dscommand1;
3701
3702 dscommand1 = ahc_inb(ahc, DSCOMMAND1);
3703 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
3704 ahc_outb(ahc, HADDR,
3705 (ahc_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);
3706 ahc_outb(ahc, DSCOMMAND1, dscommand1);
3707 }
3708 ahc_outb(ahc, HADDR + 3, dataptr >> 24);
3709 ahc_outb(ahc, HADDR + 2, dataptr >> 16);
3710 ahc_outb(ahc, HADDR + 1, dataptr >> 8);
3711 ahc_outb(ahc, HADDR, dataptr);
3712 ahc_outb(ahc, HCNT + 2, resid >> 16);
3713 ahc_outb(ahc, HCNT + 1, resid >> 8);
3714 ahc_outb(ahc, HCNT, resid);
3715 if ((ahc->features & AHC_ULTRA2) == 0) {
3716 ahc_outb(ahc, STCNT + 2, resid >> 16);
3717 ahc_outb(ahc, STCNT + 1, resid >> 8);
3718 ahc_outb(ahc, STCNT, resid);
3719 }
3720}
3721
3722/*
3723 * Handle the effects of issuing a bus device reset message.
3724 */
3725static void
3726ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
3727 cam_status status, char *message, int verbose_level)
3728{
3729#ifdef AHC_TARGET_MODE
3730 struct ahc_tmode_tstate* tstate;
3731 u_int lun;
3732#endif
3733 int found;
3734
3735 found = ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
3736 CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
3737 status);
3738
3739#ifdef AHC_TARGET_MODE
3740 /*
3741 * Send an immediate notify ccb to all target mord peripheral
3742 * drivers affected by this action.
3743 */
3744 tstate = ahc->enabled_targets[devinfo->our_scsiid];
3745 if (tstate != NULL) {
3746 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
3747 struct ahc_tmode_lstate* lstate;
3748
3749 lstate = tstate->enabled_luns[lun];
3750 if (lstate == NULL)
3751 continue;
3752
3753 ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,
3754 MSG_BUS_DEV_RESET, /*arg*/0);
3755 ahc_send_lstate_events(ahc, lstate);
3756 }
3757 }
3758#endif
3759
3760 /*
3761 * Go back to async/narrow transfers and renegotiate.
3762 */
3763 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
3764 AHC_TRANS_CUR, /*paused*/TRUE);
3765 ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL,
3766 /*period*/0, /*offset*/0, /*ppr_options*/0,
3767 AHC_TRANS_CUR, /*paused*/TRUE);
3768
3769 ahc_send_async(ahc, devinfo->channel, devinfo->target,
3770 CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
3771
3772 if (message != NULL
3773 && (verbose_level <= bootverbose))
3774 printf("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
3775 message, devinfo->channel, devinfo->target, found);
3776}
3777
3778#ifdef AHC_TARGET_MODE
3779static void
3780ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
3781 struct scb *scb)
3782{
3783
3784 /*
3785 * To facilitate adding multiple messages together,
3786 * each routine should increment the index and len
3787 * variables instead of setting them explicitly.
3788 */
3789 ahc->msgout_index = 0;
3790 ahc->msgout_len = 0;
3791
3792 if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
3793 ahc_build_transfer_msg(ahc, devinfo);
3794 else
3795 panic("ahc_intr: AWAITING target message with no message");
3796
3797 ahc->msgout_index = 0;
3798 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
3799}
3800#endif
3801/**************************** Initialization **********************************/
3802/*
3803 * Allocate a controller structure for a new device
3804 * and perform initial initializion.
3805 */
3806struct ahc_softc *
3807ahc_alloc(void *platform_arg, char *name)
3808{
3809 struct ahc_softc *ahc;
3810 int i;
3811
3812#ifndef __FreeBSD__
3813 ahc = malloc(sizeof(*ahc), M_DEVBUF, M_NOWAIT);
3814 if (!ahc) {
3815 printf("aic7xxx: cannot malloc softc!\n");
3816 free(name, M_DEVBUF);
3817 return NULL;
3818 }
3819#else
3820 ahc = device_get_softc((device_t)platform_arg);
3821#endif
3822 memset(ahc, 0, sizeof(*ahc));
3823 ahc->seep_config = malloc(sizeof(*ahc->seep_config),
3824 M_DEVBUF, M_NOWAIT);
3825 if (ahc->seep_config == NULL) {
3826#ifndef __FreeBSD__
3827 free(ahc, M_DEVBUF);
3828#endif
3829 free(name, M_DEVBUF);
3830 return (NULL);
3831 }
3832 LIST_INIT(&ahc->pending_scbs);
3833 /* We don't know our unit number until the OSM sets it */
3834 ahc->name = name;
3835 ahc->unit = -1;
3836 ahc->description = NULL;
3837 ahc->channel = 'A';
3838 ahc->channel_b = 'B';
3839 ahc->chip = AHC_NONE;
3840 ahc->features = AHC_FENONE;
3841 ahc->bugs = AHC_BUGNONE;
3842 ahc->flags = AHC_FNONE;
3843 /*
3844 * Default to all error reporting enabled with the
3845 * sequencer operating at its fastest speed.
3846 * The bus attach code may modify this.
3847 */
3848 ahc->seqctl = FASTMODE;
3849
3850 for (i = 0; i < AHC_NUM_TARGETS; i++)
3851 TAILQ_INIT(&ahc->untagged_queues[i]);
3852 if (ahc_platform_alloc(ahc, platform_arg) != 0) {
3853 ahc_free(ahc);
3854 ahc = NULL;
3855 }
3856 return (ahc);
3857}
3858
3859int
3860ahc_softc_init(struct ahc_softc *ahc)
3861{
3862
3863 /* The IRQMS bit is only valid on VL and EISA chips */
3864 if ((ahc->chip & AHC_PCI) == 0)
3865 ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
3866 else
3867 ahc->unpause = 0;
3868 ahc->pause = ahc->unpause | PAUSE;
3869 /* XXX The shared scb data stuff should be deprecated */
3870 if (ahc->scb_data == NULL) {
3871 ahc->scb_data = malloc(sizeof(*ahc->scb_data),
3872 M_DEVBUF, M_NOWAIT);
3873 if (ahc->scb_data == NULL)
3874 return (ENOMEM);
3875 memset(ahc->scb_data, 0, sizeof(*ahc->scb_data));
3876 }
3877
3878 return (0);
3879}
3880
3881void
3882ahc_softc_insert(struct ahc_softc *ahc)
3883{
3884 struct ahc_softc *list_ahc;
3885
3886#if AHC_PCI_CONFIG > 0
3887 /*
3888 * Second Function PCI devices need to inherit some
3889 * settings from function 0.
3890 */
3891 if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
3892 && (ahc->features & AHC_MULTI_FUNC) != 0) {
3893 TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
3894 ahc_dev_softc_t list_pci;
3895 ahc_dev_softc_t pci;
3896
3897 list_pci = list_ahc->dev_softc;
3898 pci = ahc->dev_softc;
3899 if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
3900 && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
3901 struct ahc_softc *master;
3902 struct ahc_softc *slave;
3903
3904 if (ahc_get_pci_function(list_pci) == 0) {
3905 master = list_ahc;
3906 slave = ahc;
3907 } else {
3908 master = ahc;
3909 slave = list_ahc;
3910 }
3911 slave->flags &= ~AHC_BIOS_ENABLED;
3912 slave->flags |=
3913 master->flags & AHC_BIOS_ENABLED;
3914 slave->flags &= ~AHC_PRIMARY_CHANNEL;
3915 slave->flags |=
3916 master->flags & AHC_PRIMARY_CHANNEL;
3917 break;
3918 }
3919 }
3920 }
3921#endif
3922
3923 /*
3924 * Insertion sort into our list of softcs.
3925 */
3926 list_ahc = TAILQ_FIRST(&ahc_tailq);
3927 while (list_ahc != NULL
3928 && ahc_softc_comp(ahc, list_ahc) <= 0)
3929 list_ahc = TAILQ_NEXT(list_ahc, links);
3930 if (list_ahc != NULL)
3931 TAILQ_INSERT_BEFORE(list_ahc, ahc, links);
3932 else
3933 TAILQ_INSERT_TAIL(&ahc_tailq, ahc, links);
3934 ahc->init_level++;
3935}
3936
3937/*
3938 * Verify that the passed in softc pointer is for a
3939 * controller that is still configured.
3940 */
3941struct ahc_softc *
3942ahc_find_softc(struct ahc_softc *ahc)
3943{
3944 struct ahc_softc *list_ahc;
3945
3946 TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
3947 if (list_ahc == ahc)
3948 return (ahc);
3949 }
3950 return (NULL);
3951}
3952
3953void
3954ahc_set_unit(struct ahc_softc *ahc, int unit)
3955{
3956 ahc->unit = unit;
3957}
3958
3959void
3960ahc_set_name(struct ahc_softc *ahc, char *name)
3961{
3962 if (ahc->name != NULL)
3963 free(ahc->name, M_DEVBUF);
3964 ahc->name = name;
3965}
3966
3967void
3968ahc_free(struct ahc_softc *ahc)
3969{
3970 int i;
3971
3972 switch (ahc->init_level) {
3973 default:
3974 case 5:
3975 ahc_shutdown(ahc);
3976 /* FALLTHROUGH */
3977 case 4:
3978 ahc_dmamap_unload(ahc, ahc->shared_data_dmat,
3979 ahc->shared_data_dmamap);
3980 /* FALLTHROUGH */
3981 case 3:
3982 ahc_dmamem_free(ahc, ahc->shared_data_dmat, ahc->qoutfifo,
3983 ahc->shared_data_dmamap);
3984 ahc_dmamap_destroy(ahc, ahc->shared_data_dmat,
3985 ahc->shared_data_dmamap);
3986 /* FALLTHROUGH */
3987 case 2:
3988 ahc_dma_tag_destroy(ahc, ahc->shared_data_dmat);
3989 case 1:
3990#ifndef __linux__
3991 ahc_dma_tag_destroy(ahc, ahc->buffer_dmat);
3992#endif
3993 break;
3994 case 0:
3995 break;
3996 }
3997
3998#ifndef __linux__
3999 ahc_dma_tag_destroy(ahc, ahc->parent_dmat);
4000#endif
4001 ahc_platform_free(ahc);
4002 ahc_fini_scbdata(ahc);
4003 for (i = 0; i < AHC_NUM_TARGETS; i++) {
4004 struct ahc_tmode_tstate *tstate;
4005
4006 tstate = ahc->enabled_targets[i];
4007 if (tstate != NULL) {
4008#ifdef AHC_TARGET_MODE
4009 int j;
4010
4011 for (j = 0; j < AHC_NUM_LUNS; j++) {
4012 struct ahc_tmode_lstate *lstate;
4013
4014 lstate = tstate->enabled_luns[j];
4015 if (lstate != NULL) {
4016 xpt_free_path(lstate->path);
4017 free(lstate, M_DEVBUF);
4018 }
4019 }
4020#endif
4021 free(tstate, M_DEVBUF);
4022 }
4023 }
4024#ifdef AHC_TARGET_MODE
4025 if (ahc->black_hole != NULL) {
4026 xpt_free_path(ahc->black_hole->path);
4027 free(ahc->black_hole, M_DEVBUF);
4028 }
4029#endif
4030 if (ahc->name != NULL)
4031 free(ahc->name, M_DEVBUF);
4032 if (ahc->seep_config != NULL)
4033 free(ahc->seep_config, M_DEVBUF);
4034#ifndef __FreeBSD__
4035 free(ahc, M_DEVBUF);
4036#endif
4037 return;
4038}
4039
4040void
4041ahc_shutdown(void *arg)
4042{
4043 struct ahc_softc *ahc;
4044 int i;
4045
4046 ahc = (struct ahc_softc *)arg;
4047
4048 /* This will reset most registers to 0, but not all */
4049 ahc_reset(ahc, /*reinit*/FALSE);
4050 ahc_outb(ahc, SCSISEQ, 0);
4051 ahc_outb(ahc, SXFRCTL0, 0);
4052 ahc_outb(ahc, DSPCISTATUS, 0);
4053
4054 for (i = TARG_SCSIRATE; i < SCSICONF; i++)
4055 ahc_outb(ahc, i, 0);
4056}
4057
4058/*
4059 * Reset the controller and record some information about it
4060 * that is only available just after a reset. If "reinit" is
4061 * non-zero, this reset occured after initial configuration
4062 * and the caller requests that the chip be fully reinitialized
4063 * to a runable state. Chip interrupts are *not* enabled after
4064 * a reinitialization. The caller must enable interrupts via
4065 * ahc_intr_enable().
4066 */
4067int
4068ahc_reset(struct ahc_softc *ahc, int reinit)
4069{
4070 u_int sblkctl;
4071 u_int sxfrctl1_a, sxfrctl1_b;
4072 int error;
4073 int wait;
4074
4075 /*
4076 * Preserve the value of the SXFRCTL1 register for all channels.
4077 * It contains settings that affect termination and we don't want
4078 * to disturb the integrity of the bus.
4079 */
4080 ahc_pause(ahc);
4081 if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) {
4082 /*
4083 * The chip has not been initialized since
4084 * PCI/EISA/VLB bus reset. Don't trust
4085 * "left over BIOS data".
4086 */
4087 ahc->flags |= AHC_NO_BIOS_INIT;
4088 }
4089 sxfrctl1_b = 0;
4090 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
4091 u_int sblkctl;
4092
4093 /*
4094 * Save channel B's settings in case this chip
4095 * is setup for TWIN channel operation.
4096 */
4097 sblkctl = ahc_inb(ahc, SBLKCTL);
4098 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
4099 sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
4100 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
4101 }
4102 sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
4103
4104 ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
4105
4106 /*
4107 * Ensure that the reset has finished. We delay 1000us
4108 * prior to reading the register to make sure the chip
4109 * has sufficiently completed its reset to handle register
4110 * accesses.
4111 */
4112 wait = 1000;
4113 do {
4114 ahc_delay(1000);
4115 } while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
4116
4117 if (wait == 0) {
4118 printf("%s: WARNING - Failed chip reset! "
4119 "Trying to initialize anyway.\n", ahc_name(ahc));
4120 }
4121 ahc_outb(ahc, HCNTRL, ahc->pause);
4122
4123 /* Determine channel configuration */
4124 sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);
4125 /* No Twin Channel PCI cards */
4126 if ((ahc->chip & AHC_PCI) != 0)
4127 sblkctl &= ~SELBUSB;
4128 switch (sblkctl) {
4129 case 0:
4130 /* Single Narrow Channel */
4131 break;
4132 case 2:
4133 /* Wide Channel */
4134 ahc->features |= AHC_WIDE;
4135 break;
4136 case 8:
4137 /* Twin Channel */
4138 ahc->features |= AHC_TWIN;
4139 break;
4140 default:
4141 printf(" Unsupported adapter type. Ignoring\n");
4142 return(-1);
4143 }
4144
4145 /*
4146 * Reload sxfrctl1.
4147 *
4148 * We must always initialize STPWEN to 1 before we
4149 * restore the saved values. STPWEN is initialized
4150 * to a tri-state condition which can only be cleared
4151 * by turning it on.
4152 */
4153 if ((ahc->features & AHC_TWIN) != 0) {
4154 u_int sblkctl;
4155
4156 sblkctl = ahc_inb(ahc, SBLKCTL);
4157 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
4158 ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
4159 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
4160 }
4161 ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
4162
4163 error = 0;
4164 if (reinit != 0)
4165 /*
4166 * If a recovery action has forced a chip reset,
4167 * re-initialize the chip to our liking.
4168 */
4169 error = ahc->bus_chip_init(ahc);
4170#ifdef AHC_DUMP_SEQ
4171 else
4172 ahc_dumpseq(ahc);
4173#endif
4174
4175 return (error);
4176}
4177
4178/*
4179 * Determine the number of SCBs available on the controller
4180 */
4181int
4182ahc_probe_scbs(struct ahc_softc *ahc) {
4183 int i;
4184
4185 for (i = 0; i < AHC_SCB_MAX; i++) {
4186
4187 ahc_outb(ahc, SCBPTR, i);
4188 ahc_outb(ahc, SCB_BASE, i);
4189 if (ahc_inb(ahc, SCB_BASE) != i)
4190 break;
4191 ahc_outb(ahc, SCBPTR, 0);
4192 if (ahc_inb(ahc, SCB_BASE) != 0)
4193 break;
4194 }
4195 return (i);
4196}
4197
4198static void
4199ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
4200{
4201 dma_addr_t *baddr;
4202
4203 baddr = (dma_addr_t *)arg;
4204 *baddr = segs->ds_addr;
4205}
4206
4207static void
4208ahc_build_free_scb_list(struct ahc_softc *ahc)
4209{
4210 int scbsize;
4211 int i;
4212
4213 scbsize = 32;
4214 if ((ahc->flags & AHC_LSCBS_ENABLED) != 0)
4215 scbsize = 64;
4216
4217 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
4218 int j;
4219
4220 ahc_outb(ahc, SCBPTR, i);
4221
4222 /*
4223 * Touch all SCB bytes to avoid parity errors
4224 * should one of our debugging routines read
4225 * an otherwise uninitiatlized byte.
4226 */
4227 for (j = 0; j < scbsize; j++)
4228 ahc_outb(ahc, SCB_BASE+j, 0xFF);
4229
4230 /* Clear the control byte. */
4231 ahc_outb(ahc, SCB_CONTROL, 0);
4232
4233 /* Set the next pointer */
4234 if ((ahc->flags & AHC_PAGESCBS) != 0)
4235 ahc_outb(ahc, SCB_NEXT, i+1);
4236 else
4237 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
4238
4239 /* Make the tag number, SCSIID, and lun invalid */
4240 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
4241 ahc_outb(ahc, SCB_SCSIID, 0xFF);
4242 ahc_outb(ahc, SCB_LUN, 0xFF);
4243 }
4244
4245 if ((ahc->flags & AHC_PAGESCBS) != 0) {
4246 /* SCB 0 heads the free list. */
4247 ahc_outb(ahc, FREE_SCBH, 0);
4248 } else {
4249 /* No free list. */
4250 ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);
4251 }
4252
4253 /* Make sure that the last SCB terminates the free list */
4254 ahc_outb(ahc, SCBPTR, i-1);
4255 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
4256}
4257
4258static int
4259ahc_init_scbdata(struct ahc_softc *ahc)
4260{
4261 struct scb_data *scb_data;
4262
4263 scb_data = ahc->scb_data;
4264 SLIST_INIT(&scb_data->free_scbs);
4265 SLIST_INIT(&scb_data->sg_maps);
4266
4267 /* Allocate SCB resources */
4268 scb_data->scbarray =
4269 (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC,
4270 M_DEVBUF, M_NOWAIT);
4271 if (scb_data->scbarray == NULL)
4272 return (ENOMEM);
4273 memset(scb_data->scbarray, 0, sizeof(struct scb) * AHC_SCB_MAX_ALLOC);
4274
4275 /* Determine the number of hardware SCBs and initialize them */
4276
4277 scb_data->maxhscbs = ahc_probe_scbs(ahc);
4278 if (ahc->scb_data->maxhscbs == 0) {
4279 printf("%s: No SCB space found\n", ahc_name(ahc));
4280 return (ENXIO);
4281 }
4282
4283 /*
4284 * Create our DMA tags. These tags define the kinds of device
4285 * accessible memory allocations and memory mappings we will
4286 * need to perform during normal operation.
4287 *
4288 * Unless we need to further restrict the allocation, we rely
4289 * on the restrictions of the parent dmat, hence the common
4290 * use of MAXADDR and MAXSIZE.
4291 */
4292
4293 /* DMA tag for our hardware scb structures */
4294 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
4295 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
4296 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
4297 /*highaddr*/BUS_SPACE_MAXADDR,
4298 /*filter*/NULL, /*filterarg*/NULL,
4299 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
4300 /*nsegments*/1,
4301 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
4302 /*flags*/0, &scb_data->hscb_dmat) != 0) {
4303 goto error_exit;
4304 }
4305
4306 scb_data->init_level++;
4307
4308 /* Allocation for our hscbs */
4309 if (ahc_dmamem_alloc(ahc, scb_data->hscb_dmat,
4310 (void **)&scb_data->hscbs,
4311 BUS_DMA_NOWAIT, &scb_data->hscb_dmamap) != 0) {
4312 goto error_exit;
4313 }
4314
4315 scb_data->init_level++;
4316
4317 /* And permanently map them */
4318 ahc_dmamap_load(ahc, scb_data->hscb_dmat, scb_data->hscb_dmamap,
4319 scb_data->hscbs,
4320 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
4321 ahc_dmamap_cb, &scb_data->hscb_busaddr, /*flags*/0);
4322
4323 scb_data->init_level++;
4324
4325 /* DMA tag for our sense buffers */
4326 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
4327 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
4328 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
4329 /*highaddr*/BUS_SPACE_MAXADDR,
4330 /*filter*/NULL, /*filterarg*/NULL,
4331 AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
4332 /*nsegments*/1,
4333 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
4334 /*flags*/0, &scb_data->sense_dmat) != 0) {
4335 goto error_exit;
4336 }
4337
4338 scb_data->init_level++;
4339
4340 /* Allocate them */
4341 if (ahc_dmamem_alloc(ahc, scb_data->sense_dmat,
4342 (void **)&scb_data->sense,
4343 BUS_DMA_NOWAIT, &scb_data->sense_dmamap) != 0) {
4344 goto error_exit;
4345 }
4346
4347 scb_data->init_level++;
4348
4349 /* And permanently map them */
4350 ahc_dmamap_load(ahc, scb_data->sense_dmat, scb_data->sense_dmamap,
4351 scb_data->sense,
4352 AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
4353 ahc_dmamap_cb, &scb_data->sense_busaddr, /*flags*/0);
4354
4355 scb_data->init_level++;
4356
4357 /* DMA tag for our S/G structures. We allocate in page sized chunks */
4358 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/8,
4359 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
4360 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
4361 /*highaddr*/BUS_SPACE_MAXADDR,
4362 /*filter*/NULL, /*filterarg*/NULL,
4363 PAGE_SIZE, /*nsegments*/1,
4364 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
4365 /*flags*/0, &scb_data->sg_dmat) != 0) {
4366 goto error_exit;
4367 }
4368
4369 scb_data->init_level++;
4370
4371 /* Perform initial CCB allocation */
4372 memset(scb_data->hscbs, 0,
4373 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb));
4374 ahc_alloc_scbs(ahc);
4375
4376 if (scb_data->numscbs == 0) {
4377 printf("%s: ahc_init_scbdata - "
4378 "Unable to allocate initial scbs\n",
4379 ahc_name(ahc));
4380 goto error_exit;
4381 }
4382
4383 /*
4384 * Reserve the next queued SCB.
4385 */
4386 ahc->next_queued_scb = ahc_get_scb(ahc);
4387
4388 /*
4389 * Note that we were successfull
4390 */
4391 return (0);
4392
4393error_exit:
4394
4395 return (ENOMEM);
4396}
4397
4398static void
4399ahc_fini_scbdata(struct ahc_softc *ahc)
4400{
4401 struct scb_data *scb_data;
4402
4403 scb_data = ahc->scb_data;
4404 if (scb_data == NULL)
4405 return;
4406
4407 switch (scb_data->init_level) {
4408 default:
4409 case 7:
4410 {
4411 struct sg_map_node *sg_map;
4412
4413 while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
4414 SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
4415 ahc_dmamap_unload(ahc, scb_data->sg_dmat,
4416 sg_map->sg_dmamap);
4417 ahc_dmamem_free(ahc, scb_data->sg_dmat,
4418 sg_map->sg_vaddr,
4419 sg_map->sg_dmamap);
4420 free(sg_map, M_DEVBUF);
4421 }
4422 ahc_dma_tag_destroy(ahc, scb_data->sg_dmat);
4423 }
4424 case 6:
4425 ahc_dmamap_unload(ahc, scb_data->sense_dmat,
4426 scb_data->sense_dmamap);
4427 case 5:
4428 ahc_dmamem_free(ahc, scb_data->sense_dmat, scb_data->sense,
4429 scb_data->sense_dmamap);
4430 ahc_dmamap_destroy(ahc, scb_data->sense_dmat,
4431 scb_data->sense_dmamap);
4432 case 4:
4433 ahc_dma_tag_destroy(ahc, scb_data->sense_dmat);
4434 case 3:
4435 ahc_dmamap_unload(ahc, scb_data->hscb_dmat,
4436 scb_data->hscb_dmamap);
4437 case 2:
4438 ahc_dmamem_free(ahc, scb_data->hscb_dmat, scb_data->hscbs,
4439 scb_data->hscb_dmamap);
4440 ahc_dmamap_destroy(ahc, scb_data->hscb_dmat,
4441 scb_data->hscb_dmamap);
4442 case 1:
4443 ahc_dma_tag_destroy(ahc, scb_data->hscb_dmat);
4444 break;
4445 case 0:
4446 break;
4447 }
4448 if (scb_data->scbarray != NULL)
4449 free(scb_data->scbarray, M_DEVBUF);
4450}
4451
4452void
4453ahc_alloc_scbs(struct ahc_softc *ahc)
4454{
4455 struct scb_data *scb_data;
4456 struct scb *next_scb;
4457 struct sg_map_node *sg_map;
4458 dma_addr_t physaddr;
4459 struct ahc_dma_seg *segs;
4460 int newcount;
4461 int i;
4462
4463 scb_data = ahc->scb_data;
4464 if (scb_data->numscbs >= AHC_SCB_MAX_ALLOC)
4465 /* Can't allocate any more */
4466 return;
4467
4468 next_scb = &scb_data->scbarray[scb_data->numscbs];
4469
4470 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
4471
4472 if (sg_map == NULL)
4473 return;
4474
4475 /* Allocate S/G space for the next batch of SCBS */
4476 if (ahc_dmamem_alloc(ahc, scb_data->sg_dmat,
4477 (void **)&sg_map->sg_vaddr,
4478 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
4479 free(sg_map, M_DEVBUF);
4480 return;
4481 }
4482
4483 SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
4484
4485 ahc_dmamap_load(ahc, scb_data->sg_dmat, sg_map->sg_dmamap,
4486 sg_map->sg_vaddr, PAGE_SIZE, ahc_dmamap_cb,
4487 &sg_map->sg_physaddr, /*flags*/0);
4488
4489 segs = sg_map->sg_vaddr;
4490 physaddr = sg_map->sg_physaddr;
4491
4492 newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
4493 newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
4494 for (i = 0; i < newcount; i++) {
4495 struct scb_platform_data *pdata;
4496#ifndef __linux__
4497 int error;
4498#endif
4499 pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
4500 M_DEVBUF, M_NOWAIT);
4501 if (pdata == NULL)
4502 break;
4503 next_scb->platform_data = pdata;
4504 next_scb->sg_map = sg_map;
4505 next_scb->sg_list = segs;
4506 /*
4507 * The sequencer always starts with the second entry.
4508 * The first entry is embedded in the scb.
4509 */
4510 next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
4511 next_scb->ahc_softc = ahc;
4512 next_scb->flags = SCB_FREE;
4513#ifndef __linux__
4514 error = ahc_dmamap_create(ahc, ahc->buffer_dmat, /*flags*/0,
4515 &next_scb->dmamap);
4516 if (error != 0)
4517 break;
4518#endif
4519 next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
4520 next_scb->hscb->tag = ahc->scb_data->numscbs;
4521 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
4522 next_scb, links.sle);
4523 segs += AHC_NSEG;
4524 physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
4525 next_scb++;
4526 ahc->scb_data->numscbs++;
4527 }
4528}
4529
4530void
4531ahc_controller_info(struct ahc_softc *ahc, char *buf)
4532{
4533 int len;
4534
4535 len = sprintf(buf, "%s: ", ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);
4536 buf += len;
4537 if ((ahc->features & AHC_TWIN) != 0)
4538 len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "
4539 "B SCSI Id=%d, primary %c, ",
4540 ahc->our_id, ahc->our_id_b,
4541 (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
4542 else {
4543 const char *speed;
4544 const char *type;
4545
4546 speed = "";
4547 if ((ahc->features & AHC_ULTRA) != 0) {
4548 speed = "Ultra ";
4549 } else if ((ahc->features & AHC_DT) != 0) {
4550 speed = "Ultra160 ";
4551 } else if ((ahc->features & AHC_ULTRA2) != 0) {
4552 speed = "Ultra2 ";
4553 }
4554 if ((ahc->features & AHC_WIDE) != 0) {
4555 type = "Wide";
4556 } else {
4557 type = "Single";
4558 }
4559 len = sprintf(buf, "%s%s Channel %c, SCSI Id=%d, ",
4560 speed, type, ahc->channel, ahc->our_id);
4561 }
4562 buf += len;
4563
4564 if ((ahc->flags & AHC_PAGESCBS) != 0)
4565 sprintf(buf, "%d/%d SCBs",
4566 ahc->scb_data->maxhscbs, AHC_MAX_QUEUE);
4567 else
4568 sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs);
4569}
4570
4571int
4572ahc_chip_init(struct ahc_softc *ahc)
4573{
4574 int term;
4575 int error;
4576 u_int i;
4577 u_int scsi_conf;
4578 u_int scsiseq_template;
4579 uint32_t physaddr;
4580
4581 ahc_outb(ahc, SEQ_FLAGS, 0);
4582 ahc_outb(ahc, SEQ_FLAGS2, 0);
4583
4584 /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/
4585 if (ahc->features & AHC_TWIN) {
4586
4587 /*
4588 * Setup Channel B first.
4589 */
4590 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
4591 term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;
4592 ahc_outb(ahc, SCSIID, ahc->our_id_b);
4593 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
4594 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
4595 |term|ahc->seltime_b|ENSTIMER|ACTNEGEN);
4596 if ((ahc->features & AHC_ULTRA2) != 0)
4597 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
4598 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
4599 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
4600
4601 /* Select Channel A */
4602 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
4603 }
4604 term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
4605 if ((ahc->features & AHC_ULTRA2) != 0)
4606 ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
4607 else
4608 ahc_outb(ahc, SCSIID, ahc->our_id);
4609 scsi_conf = ahc_inb(ahc, SCSICONF);
4610 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
4611 |term|ahc->seltime
4612 |ENSTIMER|ACTNEGEN);
4613 if ((ahc->features & AHC_ULTRA2) != 0)
4614 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
4615 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
4616 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
4617
4618 /* There are no untagged SCBs active yet. */
4619 for (i = 0; i < 16; i++) {
4620 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
4621 if ((ahc->flags & AHC_SCB_BTT) != 0) {
4622 int lun;
4623
4624 /*
4625 * The SCB based BTT allows an entry per
4626 * target and lun pair.
4627 */
4628 for (lun = 1; lun < AHC_NUM_LUNS; lun++)
4629 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));
4630 }
4631 }
4632
4633 /* All of our queues are empty */
4634 for (i = 0; i < 256; i++)
4635 ahc->qoutfifo[i] = SCB_LIST_NULL;
4636 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD);
4637
4638 for (i = 0; i < 256; i++)
4639 ahc->qinfifo[i] = SCB_LIST_NULL;
4640
4641 if ((ahc->features & AHC_MULTI_TID) != 0) {
4642 ahc_outb(ahc, TARGID, 0);
4643 ahc_outb(ahc, TARGID + 1, 0);
4644 }
4645
4646 /*
4647 * Tell the sequencer where it can find our arrays in memory.
4648 */
4649 physaddr = ahc->scb_data->hscb_busaddr;
4650 ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);
4651 ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);
4652 ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);
4653 ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);
4654
4655 physaddr = ahc->shared_data_busaddr;
4656 ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF);
4657 ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF);
4658 ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF);
4659 ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF);
4660
4661 /*
4662 * Initialize the group code to command length table.
4663 * This overrides the values in TARG_SCSIRATE, so only
4664 * setup the table after we have processed that information.
4665 */
4666 ahc_outb(ahc, CMDSIZE_TABLE, 5);
4667 ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);
4668 ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);
4669 ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);
4670 ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);
4671 ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
4672 ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
4673 ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
4674
4675 if ((ahc->features & AHC_HS_MAILBOX) != 0)
4676 ahc_outb(ahc, HS_MAILBOX, 0);
4677
4678 /* Tell the sequencer of our initial queue positions */
4679 if ((ahc->features & AHC_TARGETMODE) != 0) {
4680 ahc->tqinfifonext = 1;
4681 ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
4682 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
4683 }
4684 ahc->qinfifonext = 0;
4685 ahc->qoutfifonext = 0;
4686 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
4687 ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);
4688 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
4689 ahc_outb(ahc, SNSCB_QOFF, ahc->qinfifonext);
4690 ahc_outb(ahc, SDSCB_QOFF, 0);
4691 } else {
4692 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
4693 ahc_outb(ahc, QINPOS, ahc->qinfifonext);
4694 ahc_outb(ahc, QOUTPOS, ahc->qoutfifonext);
4695 }
4696
4697 /* We don't have any waiting selections */
4698 ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);
4699
4700 /* Our disconnection list is empty too */
4701 ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
4702
4703 /* Message out buffer starts empty */
4704 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
4705
4706 /*
4707 * Setup the allowed SCSI Sequences based on operational mode.
4708 * If we are a target, we'll enalbe select in operations once
4709 * we've had a lun enabled.
4710 */
4711 scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
4712 if ((ahc->flags & AHC_INITIATORROLE) != 0)
4713 scsiseq_template |= ENRSELI;
4714 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
4715
4716 /* Initialize our list of free SCBs. */
4717 ahc_build_free_scb_list(ahc);
4718
4719 /*
4720 * Tell the sequencer which SCB will be the next one it receives.
4721 */
4722 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
4723
4724 /*
4725 * Load the Sequencer program and Enable the adapter
4726 * in "fast" mode.
4727 */
4728 if (bootverbose)
4729 printf("%s: Downloading Sequencer Program...",
4730 ahc_name(ahc));
4731
4732 error = ahc_loadseq(ahc);
4733 if (error != 0)
4734 return (error);
4735
4736 if ((ahc->features & AHC_ULTRA2) != 0) {
4737 int wait;
4738
4739 /*
4740 * Wait for up to 500ms for our transceivers
4741 * to settle. If the adapter does not have
4742 * a cable attached, the transceivers may
4743 * never settle, so don't complain if we
4744 * fail here.
4745 */
4746 for (wait = 5000;
4747 (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
4748 wait--)
4749 ahc_delay(100);
4750 }
4751 ahc_restart(ahc);
4752 return (0);
4753}
4754
4755/*
4756 * Start the board, ready for normal operation
4757 */
4758int
4759ahc_init(struct ahc_softc *ahc)
4760{
4761 int max_targ;
4762 u_int i;
4763 u_int scsi_conf;
4764 u_int ultraenb;
4765 u_int discenable;
4766 u_int tagenable;
4767 size_t driver_data_size;
4768
4769#ifdef AHC_DEBUG
4770 if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0)
4771 ahc->flags |= AHC_SEQUENCER_DEBUG;
4772#endif
4773
4774#ifdef AHC_PRINT_SRAM
4775 printf("Scratch Ram:");
4776 for (i = 0x20; i < 0x5f; i++) {
4777 if (((i % 8) == 0) && (i != 0)) {
4778 printf ("\n ");
4779 }
4780 printf (" 0x%x", ahc_inb(ahc, i));
4781 }
4782 if ((ahc->features & AHC_MORE_SRAM) != 0) {
4783 for (i = 0x70; i < 0x7f; i++) {
4784 if (((i % 8) == 0) && (i != 0)) {
4785 printf ("\n ");
4786 }
4787 printf (" 0x%x", ahc_inb(ahc, i));
4788 }
4789 }
4790 printf ("\n");
4791 /*
4792 * Reading uninitialized scratch ram may
4793 * generate parity errors.
4794 */
4795 ahc_outb(ahc, CLRINT, CLRPARERR);
4796 ahc_outb(ahc, CLRINT, CLRBRKADRINT);
4797#endif
4798 max_targ = 15;
4799
4800 /*
4801 * Assume we have a board at this stage and it has been reset.
4802 */
4803 if ((ahc->flags & AHC_USEDEFAULTS) != 0)
4804 ahc->our_id = ahc->our_id_b = 7;
4805
4806 /*
4807 * Default to allowing initiator operations.
4808 */
4809 ahc->flags |= AHC_INITIATORROLE;
4810
4811 /*
4812 * Only allow target mode features if this unit has them enabled.
4813 */
4814 if ((AHC_TMODE_ENABLE & (0x1 << ahc->unit)) == 0)
4815 ahc->features &= ~AHC_TARGETMODE;
4816
4817#ifndef __linux__
4818 /* DMA tag for mapping buffers into device visible space. */
4819 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
4820 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
4821 /*lowaddr*/ahc->flags & AHC_39BIT_ADDRESSING
4822 ? (dma_addr_t)0x7FFFFFFFFFULL
4823 : BUS_SPACE_MAXADDR_32BIT,
4824 /*highaddr*/BUS_SPACE_MAXADDR,
4825 /*filter*/NULL, /*filterarg*/NULL,
4826 /*maxsize*/(AHC_NSEG - 1) * PAGE_SIZE,
4827 /*nsegments*/AHC_NSEG,
4828 /*maxsegsz*/AHC_MAXTRANSFER_SIZE,
4829 /*flags*/BUS_DMA_ALLOCNOW,
4830 &ahc->buffer_dmat) != 0) {
4831 return (ENOMEM);
4832 }
4833#endif
4834
4835 ahc->init_level++;
4836
4837 /*
4838 * DMA tag for our command fifos and other data in system memory
4839 * the card's sequencer must be able to access. For initiator
4840 * roles, we need to allocate space for the qinfifo and qoutfifo.
4841 * The qinfifo and qoutfifo are composed of 256 1 byte elements.
4842 * When providing for the target mode role, we must additionally
4843 * provide space for the incoming target command fifo and an extra
4844 * byte to deal with a dma bug in some chip versions.
4845 */
4846 driver_data_size = 2 * 256 * sizeof(uint8_t);
4847 if ((ahc->features & AHC_TARGETMODE) != 0)
4848 driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)
4849 + /*DMA WideOdd Bug Buffer*/1;
4850 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
4851 /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
4852 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
4853 /*highaddr*/BUS_SPACE_MAXADDR,
4854 /*filter*/NULL, /*filterarg*/NULL,
4855 driver_data_size,
4856 /*nsegments*/1,
4857 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
4858 /*flags*/0, &ahc->shared_data_dmat) != 0) {
4859 return (ENOMEM);
4860 }
4861
4862 ahc->init_level++;
4863
4864 /* Allocation of driver data */
4865 if (ahc_dmamem_alloc(ahc, ahc->shared_data_dmat,
4866 (void **)&ahc->qoutfifo,
4867 BUS_DMA_NOWAIT, &ahc->shared_data_dmamap) != 0) {
4868 return (ENOMEM);
4869 }
4870
4871 ahc->init_level++;
4872
4873 /* And permanently map it in */
4874 ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
4875 ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,
4876 &ahc->shared_data_busaddr, /*flags*/0);
4877
4878 if ((ahc->features & AHC_TARGETMODE) != 0) {
4879 ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
4880 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];
4881 ahc->dma_bug_buf = ahc->shared_data_busaddr
4882 + driver_data_size - 1;
4883 /* All target command blocks start out invalid. */
4884 for (i = 0; i < AHC_TMODE_CMDS; i++)
4885 ahc->targetcmds[i].cmd_valid = 0;
4886 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD);
4887 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];
4888 }
4889 ahc->qinfifo = &ahc->qoutfifo[256];
4890
4891 ahc->init_level++;
4892
4893 /* Allocate SCB data now that buffer_dmat is initialized */
4894 if (ahc->scb_data->maxhscbs == 0)
4895 if (ahc_init_scbdata(ahc) != 0)
4896 return (ENOMEM);
4897
4898 /*
4899 * Allocate a tstate to house information for our
4900 * initiator presence on the bus as well as the user
4901 * data for any target mode initiator.
4902 */
4903 if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
4904 printf("%s: unable to allocate ahc_tmode_tstate. "
4905 "Failing attach\n", ahc_name(ahc));
4906 return (ENOMEM);
4907 }
4908
4909 if ((ahc->features & AHC_TWIN) != 0) {
4910 if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
4911 printf("%s: unable to allocate ahc_tmode_tstate. "
4912 "Failing attach\n", ahc_name(ahc));
4913 return (ENOMEM);
4914 }
4915 }
4916
4917 if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {
4918 ahc->flags |= AHC_PAGESCBS;
4919 } else {
4920 ahc->flags &= ~AHC_PAGESCBS;
4921 }
4922
4923#ifdef AHC_DEBUG
4924 if (ahc_debug & AHC_SHOW_MISC) {
4925 printf("%s: hardware scb %u bytes; kernel scb %u bytes; "
4926 "ahc_dma %u bytes\n",
4927 ahc_name(ahc),
4928 (u_int)sizeof(struct hardware_scb),
4929 (u_int)sizeof(struct scb),
4930 (u_int)sizeof(struct ahc_dma_seg));
4931 }
4932#endif /* AHC_DEBUG */
4933
4934 /*
4935 * Look at the information that board initialization or
4936 * the board bios has left us.
4937 */
4938 if (ahc->features & AHC_TWIN) {
4939 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
4940 if ((scsi_conf & RESET_SCSI) != 0
4941 && (ahc->flags & AHC_INITIATORROLE) != 0)
4942 ahc->flags |= AHC_RESET_BUS_B;
4943 }
4944
4945 scsi_conf = ahc_inb(ahc, SCSICONF);
4946 if ((scsi_conf & RESET_SCSI) != 0
4947 && (ahc->flags & AHC_INITIATORROLE) != 0)
4948 ahc->flags |= AHC_RESET_BUS_A;
4949
4950 ultraenb = 0;
4951 tagenable = ALL_TARGETS_MASK;
4952
4953 /* Grab the disconnection disable table and invert it for our needs */
4954 if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
4955 printf("%s: Host Adapter Bios disabled. Using default SCSI "
4956 "device parameters\n", ahc_name(ahc));
4957 ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
4958 AHC_TERM_ENB_A|AHC_TERM_ENB_B;
4959 discenable = ALL_TARGETS_MASK;
4960 if ((ahc->features & AHC_ULTRA) != 0)
4961 ultraenb = ALL_TARGETS_MASK;
4962 } else {
4963 discenable = ~((ahc_inb(ahc, DISC_DSB + 1) << 8)
4964 | ahc_inb(ahc, DISC_DSB));
4965 if ((ahc->features & (AHC_ULTRA|AHC_ULTRA2)) != 0)
4966 ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)
4967 | ahc_inb(ahc, ULTRA_ENB);
4968 }
4969
4970 if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
4971 max_targ = 7;
4972
4973 for (i = 0; i <= max_targ; i++) {
4974 struct ahc_initiator_tinfo *tinfo;
4975 struct ahc_tmode_tstate *tstate;
4976 u_int our_id;
4977 u_int target_id;
4978 char channel;
4979
4980 channel = 'A';
4981 our_id = ahc->our_id;
4982 target_id = i;
4983 if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
4984 channel = 'B';
4985 our_id = ahc->our_id_b;
4986 target_id = i % 8;
4987 }
4988 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
4989 target_id, &tstate);
4990 /* Default to async narrow across the board */
4991 memset(tinfo, 0, sizeof(*tinfo));
4992 if (ahc->flags & AHC_USEDEFAULTS) {
4993 if ((ahc->features & AHC_WIDE) != 0)
4994 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
4995
4996 /*
4997 * These will be truncated when we determine the
4998 * connection type we have with the target.
4999 */
5000 tinfo->user.period = ahc_syncrates->period;
5001 tinfo->user.offset = MAX_OFFSET;
5002 } else {
5003 u_int scsirate;
5004 uint16_t mask;
5005
5006 /* Take the settings leftover in scratch RAM. */
5007 scsirate = ahc_inb(ahc, TARG_SCSIRATE + i);
5008 mask = (0x01 << i);
5009 if ((ahc->features & AHC_ULTRA2) != 0) {
5010 u_int offset;
5011 u_int maxsync;
5012
5013 if ((scsirate & SOFS) == 0x0F) {
5014 /*
5015 * Haven't negotiated yet,
5016 * so the format is different.
5017 */
5018 scsirate = (scsirate & SXFR) >> 4
5019 | (ultraenb & mask)
5020 ? 0x08 : 0x0
5021 | (scsirate & WIDEXFER);
5022 offset = MAX_OFFSET_ULTRA2;
5023 } else
5024 offset = ahc_inb(ahc, TARG_OFFSET + i);
5025 if ((scsirate & ~WIDEXFER) == 0 && offset != 0)
5026 /* Set to the lowest sync rate, 5MHz */
5027 scsirate |= 0x1c;
5028 maxsync = AHC_SYNCRATE_ULTRA2;
5029 if ((ahc->features & AHC_DT) != 0)
5030 maxsync = AHC_SYNCRATE_DT;
5031 tinfo->user.period =
5032 ahc_find_period(ahc, scsirate, maxsync);
5033 if (offset == 0)
5034 tinfo->user.period = 0;
5035 else
5036 tinfo->user.offset = MAX_OFFSET;
5037 if ((scsirate & SXFR_ULTRA2) <= 8/*10MHz*/
5038 && (ahc->features & AHC_DT) != 0)
5039 tinfo->user.ppr_options =
5040 MSG_EXT_PPR_DT_REQ;
5041 } else if ((scsirate & SOFS) != 0) {
5042 if ((scsirate & SXFR) == 0x40
5043 && (ultraenb & mask) != 0) {
5044 /* Treat 10MHz as a non-ultra speed */
5045 scsirate &= ~SXFR;
5046 ultraenb &= ~mask;
5047 }
5048 tinfo->user.period =
5049 ahc_find_period(ahc, scsirate,
5050 (ultraenb & mask)
5051 ? AHC_SYNCRATE_ULTRA
5052 : AHC_SYNCRATE_FAST);
5053 if (tinfo->user.period != 0)
5054 tinfo->user.offset = MAX_OFFSET;
5055 }
5056 if (tinfo->user.period == 0)
5057 tinfo->user.offset = 0;
5058 if ((scsirate & WIDEXFER) != 0
5059 && (ahc->features & AHC_WIDE) != 0)
5060 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
5061 tinfo->user.protocol_version = 4;
5062 if ((ahc->features & AHC_DT) != 0)
5063 tinfo->user.transport_version = 3;
5064 else
5065 tinfo->user.transport_version = 2;
5066 tinfo->goal.protocol_version = 2;
5067 tinfo->goal.transport_version = 2;
5068 tinfo->curr.protocol_version = 2;
5069 tinfo->curr.transport_version = 2;
5070 }
5071 tstate->ultraenb = 0;
5072 }
5073 ahc->user_discenable = discenable;
5074 ahc->user_tagenable = tagenable;
5075
5076 return (ahc->bus_chip_init(ahc));
5077}
5078
5079void
5080ahc_intr_enable(struct ahc_softc *ahc, int enable)
5081{
5082 u_int hcntrl;
5083
5084 hcntrl = ahc_inb(ahc, HCNTRL);
5085 hcntrl &= ~INTEN;
5086 ahc->pause &= ~INTEN;
5087 ahc->unpause &= ~INTEN;
5088 if (enable) {
5089 hcntrl |= INTEN;
5090 ahc->pause |= INTEN;
5091 ahc->unpause |= INTEN;
5092 }
5093 ahc_outb(ahc, HCNTRL, hcntrl);
5094}
5095
5096/*
5097 * Ensure that the card is paused in a location
5098 * outside of all critical sections and that all
5099 * pending work is completed prior to returning.
5100 * This routine should only be called from outside
5101 * an interrupt context.
5102 */
5103void
5104ahc_pause_and_flushwork(struct ahc_softc *ahc)
5105{
5106 int intstat;
5107 int maxloops;
5108 int paused;
5109
5110 maxloops = 1000;
5111 ahc->flags |= AHC_ALL_INTERRUPTS;
5112 paused = FALSE;
5113 do {
5114 if (paused)
5115 ahc_unpause(ahc);
5116 ahc_intr(ahc);
5117 ahc_pause(ahc);
5118 paused = TRUE;
5119 ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO);
5120 ahc_clear_critical_section(ahc);
5121 intstat = ahc_inb(ahc, INTSTAT);
5122 } while (--maxloops
5123 && (intstat != 0xFF || (ahc->features & AHC_REMOVABLE) == 0)
5124 && ((intstat & INT_PEND) != 0
5125 || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO)) != 0));
5126 if (maxloops == 0) {
5127 printf("Infinite interrupt loop, INTSTAT = %x",
5128 ahc_inb(ahc, INTSTAT));
5129 }
5130 ahc_platform_flushwork(ahc);
5131 ahc->flags &= ~AHC_ALL_INTERRUPTS;
5132}
5133
5134int
5135ahc_suspend(struct ahc_softc *ahc)
5136{
5137
5138 ahc_pause_and_flushwork(ahc);
5139
5140 if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
5141 ahc_unpause(ahc);
5142 return (EBUSY);
5143 }
5144
5145#ifdef AHC_TARGET_MODE
5146 /*
5147 * XXX What about ATIOs that have not yet been serviced?
5148 * Perhaps we should just refuse to be suspended if we
5149 * are acting in a target role.
5150 */
5151 if (ahc->pending_device != NULL) {
5152 ahc_unpause(ahc);
5153 return (EBUSY);
5154 }
5155#endif
5156 ahc_shutdown(ahc);
5157 return (0);
5158}
5159
5160int
5161ahc_resume(struct ahc_softc *ahc)
5162{
5163
5164 ahc_reset(ahc, /*reinit*/TRUE);
5165 ahc_intr_enable(ahc, TRUE);
5166 ahc_restart(ahc);
5167 return (0);
5168}
5169
5170/************************** Busy Target Table *********************************/
5171/*
5172 * Return the untagged transaction id for a given target/channel lun.
5173 * Optionally, clear the entry.
5174 */
5175u_int
5176ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
5177{
5178 u_int scbid;
5179 u_int target_offset;
5180
5181 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5182 u_int saved_scbptr;
5183
5184 saved_scbptr = ahc_inb(ahc, SCBPTR);
5185 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
5186 scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
5187 ahc_outb(ahc, SCBPTR, saved_scbptr);
5188 } else {
5189 target_offset = TCL_TARGET_OFFSET(tcl);
5190 scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
5191 }
5192
5193 return (scbid);
5194}
5195
5196void
5197ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
5198{
5199 u_int target_offset;
5200
5201 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5202 u_int saved_scbptr;
5203
5204 saved_scbptr = ahc_inb(ahc, SCBPTR);
5205 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
5206 ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
5207 ahc_outb(ahc, SCBPTR, saved_scbptr);
5208 } else {
5209 target_offset = TCL_TARGET_OFFSET(tcl);
5210 ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
5211 }
5212}
5213
5214void
5215ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
5216{
5217 u_int target_offset;
5218
5219 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5220 u_int saved_scbptr;
5221
5222 saved_scbptr = ahc_inb(ahc, SCBPTR);
5223 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
5224 ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
5225 ahc_outb(ahc, SCBPTR, saved_scbptr);
5226 } else {
5227 target_offset = TCL_TARGET_OFFSET(tcl);
5228 ahc_outb(ahc, BUSY_TARGETS + target_offset, scbid);
5229 }
5230}
5231
5232/************************** SCB and SCB queue management **********************/
5233int
5234ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target,
5235 char channel, int lun, u_int tag, role_t role)
5236{
5237 int targ = SCB_GET_TARGET(ahc, scb);
5238 char chan = SCB_GET_CHANNEL(ahc, scb);
5239 int slun = SCB_GET_LUN(scb);
5240 int match;
5241
5242 match = ((chan == channel) || (channel == ALL_CHANNELS));
5243 if (match != 0)
5244 match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
5245 if (match != 0)
5246 match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
5247 if (match != 0) {
5248#ifdef AHC_TARGET_MODE
5249 int group;
5250
5251 group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
5252 if (role == ROLE_INITIATOR) {
5253 match = (group != XPT_FC_GROUP_TMODE)
5254 && ((tag == scb->hscb->tag)
5255 || (tag == SCB_LIST_NULL));
5256 } else if (role == ROLE_TARGET) {
5257 match = (group == XPT_FC_GROUP_TMODE)
5258 && ((tag == scb->io_ctx->csio.tag_id)
5259 || (tag == SCB_LIST_NULL));
5260 }
5261#else /* !AHC_TARGET_MODE */
5262 match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));
5263#endif /* AHC_TARGET_MODE */
5264 }
5265
5266 return match;
5267}
5268
5269void
5270ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
5271{
5272 int target;
5273 char channel;
5274 int lun;
5275
5276 target = SCB_GET_TARGET(ahc, scb);
5277 lun = SCB_GET_LUN(scb);
5278 channel = SCB_GET_CHANNEL(ahc, scb);
5279
5280 ahc_search_qinfifo(ahc, target, channel, lun,
5281 /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
5282 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
5283
5284 ahc_platform_freeze_devq(ahc, scb);
5285}
5286
5287void
5288ahc_qinfifo_requeue_tail(struct ahc_softc *ahc, struct scb *scb)
5289{
5290 struct scb *prev_scb;
5291
5292 prev_scb = NULL;
5293 if (ahc_qinfifo_count(ahc) != 0) {
5294 u_int prev_tag;
5295 uint8_t prev_pos;
5296
5297 prev_pos = ahc->qinfifonext - 1;
5298 prev_tag = ahc->qinfifo[prev_pos];
5299 prev_scb = ahc_lookup_scb(ahc, prev_tag);
5300 }
5301 ahc_qinfifo_requeue(ahc, prev_scb, scb);
5302 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5303 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
5304 } else {
5305 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
5306 }
5307}
5308
5309static void
5310ahc_qinfifo_requeue(struct ahc_softc *ahc, struct scb *prev_scb,
5311 struct scb *scb)
5312{
5313 if (prev_scb == NULL) {
5314 ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
5315 } else {
5316 prev_scb->hscb->next = scb->hscb->tag;
5317 ahc_sync_scb(ahc, prev_scb,
5318 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
5319 }
5320 ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
5321 scb->hscb->next = ahc->next_queued_scb->hscb->tag;
5322 ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
5323}
5324
5325static int
5326ahc_qinfifo_count(struct ahc_softc *ahc)
5327{
5328 uint8_t qinpos;
5329 uint8_t diff;
5330
5331 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5332 qinpos = ahc_inb(ahc, SNSCB_QOFF);
5333 ahc_outb(ahc, SNSCB_QOFF, qinpos);
5334 } else
5335 qinpos = ahc_inb(ahc, QINPOS);
5336 diff = ahc->qinfifonext - qinpos;
5337 return (diff);
5338}
5339
5340int
5341ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
5342 int lun, u_int tag, role_t role, uint32_t status,
5343 ahc_search_action action)
5344{
5345 struct scb *scb;
5346 struct scb *prev_scb;
5347 uint8_t qinstart;
5348 uint8_t qinpos;
5349 uint8_t qintail;
5350 uint8_t next;
5351 uint8_t prev;
5352 uint8_t curscbptr;
5353 int found;
5354 int have_qregs;
5355
5356 qintail = ahc->qinfifonext;
5357 have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;
5358 if (have_qregs) {
5359 qinstart = ahc_inb(ahc, SNSCB_QOFF);
5360 ahc_outb(ahc, SNSCB_QOFF, qinstart);
5361 } else
5362 qinstart = ahc_inb(ahc, QINPOS);
5363 qinpos = qinstart;
5364 found = 0;
5365 prev_scb = NULL;
5366
5367 if (action == SEARCH_COMPLETE) {
5368 /*
5369 * Don't attempt to run any queued untagged transactions
5370 * until we are done with the abort process.
5371 */
5372 ahc_freeze_untagged_queues(ahc);
5373 }
5374
5375 /*
5376 * Start with an empty queue. Entries that are not chosen
5377 * for removal will be re-added to the queue as we go.
5378 */
5379 ahc->qinfifonext = qinpos;
5380 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
5381
5382 while (qinpos != qintail) {
5383 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);
5384 if (scb == NULL) {
5385 printf("qinpos = %d, SCB index = %d\n",
5386 qinpos, ahc->qinfifo[qinpos]);
5387 panic("Loop 1\n");
5388 }
5389
5390 if (ahc_match_scb(ahc, scb, target, channel, lun, tag, role)) {
5391 /*
5392 * We found an scb that needs to be acted on.
5393 */
5394 found++;
5395 switch (action) {
5396 case SEARCH_COMPLETE:
5397 {
5398 cam_status ostat;
5399 cam_status cstat;
5400
5401 ostat = ahc_get_transaction_status(scb);
5402 if (ostat == CAM_REQ_INPROG)
5403 ahc_set_transaction_status(scb, status);
5404 cstat = ahc_get_transaction_status(scb);
5405 if (cstat != CAM_REQ_CMP)
5406 ahc_freeze_scb(scb);
5407 if ((scb->flags & SCB_ACTIVE) == 0)
5408 printf("Inactive SCB in qinfifo\n");
5409 ahc_done(ahc, scb);
5410
5411 /* FALLTHROUGH */
5412 }
5413 case SEARCH_REMOVE:
5414 break;
5415 case SEARCH_COUNT:
5416 ahc_qinfifo_requeue(ahc, prev_scb, scb);
5417 prev_scb = scb;
5418 break;
5419 }
5420 } else {
5421 ahc_qinfifo_requeue(ahc, prev_scb, scb);
5422 prev_scb = scb;
5423 }
5424 qinpos++;
5425 }
5426
5427 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5428 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
5429 } else {
5430 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
5431 }
5432
5433 if (action != SEARCH_COUNT
5434 && (found != 0)
5435 && (qinstart != ahc->qinfifonext)) {
5436 /*
5437 * The sequencer may be in the process of dmaing
5438 * down the SCB at the beginning of the queue.
5439 * This could be problematic if either the first,
5440 * or the second SCB is removed from the queue
5441 * (the first SCB includes a pointer to the "next"
5442 * SCB to dma). If we have removed any entries, swap
5443 * the first element in the queue with the next HSCB
5444 * so the sequencer will notice that NEXT_QUEUED_SCB
5445 * has changed during its dma attempt and will retry
5446 * the DMA.
5447 */
5448 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);
5449
5450 if (scb == NULL) {
5451 printf("found = %d, qinstart = %d, qinfifionext = %d\n",
5452 found, qinstart, ahc->qinfifonext);
5453 panic("First/Second Qinfifo fixup\n");
5454 }
5455 /*
5456 * ahc_swap_with_next_hscb forces our next pointer to
5457 * point to the reserved SCB for future commands. Save
5458 * and restore our original next pointer to maintain
5459 * queue integrity.
5460 */
5461 next = scb->hscb->next;
5462 ahc->scb_data->scbindex[scb->hscb->tag] = NULL;
5463 ahc_swap_with_next_hscb(ahc, scb);
5464 scb->hscb->next = next;
5465 ahc->qinfifo[qinstart] = scb->hscb->tag;
5466
5467 /* Tell the card about the new head of the qinfifo. */
5468 ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
5469
5470 /* Fixup the tail "next" pointer. */
5471 qintail = ahc->qinfifonext - 1;
5472 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]);
5473 scb->hscb->next = ahc->next_queued_scb->hscb->tag;
5474 }
5475
5476 /*
5477 * Search waiting for selection list.
5478 */
5479 curscbptr = ahc_inb(ahc, SCBPTR);
5480 next = ahc_inb(ahc, WAITING_SCBH); /* Start at head of list. */
5481 prev = SCB_LIST_NULL;
5482
5483 while (next != SCB_LIST_NULL) {
5484 uint8_t scb_index;
5485
5486 ahc_outb(ahc, SCBPTR, next);
5487 scb_index = ahc_inb(ahc, SCB_TAG);
5488 if (scb_index >= ahc->scb_data->numscbs) {
5489 printf("Waiting List inconsistency. "
5490 "SCB index == %d, yet numscbs == %d.",
5491 scb_index, ahc->scb_data->numscbs);
5492 ahc_dump_card_state(ahc);
5493 panic("for safety");
5494 }
5495 scb = ahc_lookup_scb(ahc, scb_index);
5496 if (scb == NULL) {
5497 printf("scb_index = %d, next = %d\n",
5498 scb_index, next);
5499 panic("Waiting List traversal\n");
5500 }
5501 if (ahc_match_scb(ahc, scb, target, channel,
5502 lun, SCB_LIST_NULL, role)) {
5503 /*
5504 * We found an scb that needs to be acted on.
5505 */
5506 found++;
5507 switch (action) {
5508 case SEARCH_COMPLETE:
5509 {
5510 cam_status ostat;
5511 cam_status cstat;
5512
5513 ostat = ahc_get_transaction_status(scb);
5514 if (ostat == CAM_REQ_INPROG)
5515 ahc_set_transaction_status(scb,
5516 status);
5517 cstat = ahc_get_transaction_status(scb);
5518 if (cstat != CAM_REQ_CMP)
5519 ahc_freeze_scb(scb);
5520 if ((scb->flags & SCB_ACTIVE) == 0)
5521 printf("Inactive SCB in Waiting List\n");
5522 ahc_done(ahc, scb);
5523 /* FALLTHROUGH */
5524 }
5525 case SEARCH_REMOVE:
5526 next = ahc_rem_wscb(ahc, next, prev);
5527 break;
5528 case SEARCH_COUNT:
5529 prev = next;
5530 next = ahc_inb(ahc, SCB_NEXT);
5531 break;
5532 }
5533 } else {
5534
5535 prev = next;
5536 next = ahc_inb(ahc, SCB_NEXT);
5537 }
5538 }
5539 ahc_outb(ahc, SCBPTR, curscbptr);
5540
5541 found += ahc_search_untagged_queues(ahc, /*ahc_io_ctx_t*/NULL, target,
5542 channel, lun, status, action);
5543
5544 if (action == SEARCH_COMPLETE)
5545 ahc_release_untagged_queues(ahc);
5546 return (found);
5547}
5548
5549int
5550ahc_search_untagged_queues(struct ahc_softc *ahc, ahc_io_ctx_t ctx,
5551 int target, char channel, int lun, uint32_t status,
5552 ahc_search_action action)
5553{
5554 struct scb *scb;
5555 int maxtarget;
5556 int found;
5557 int i;
5558
5559 if (action == SEARCH_COMPLETE) {
5560 /*
5561 * Don't attempt to run any queued untagged transactions
5562 * until we are done with the abort process.
5563 */
5564 ahc_freeze_untagged_queues(ahc);
5565 }
5566
5567 found = 0;
5568 i = 0;
5569 if ((ahc->flags & AHC_SCB_BTT) == 0) {
5570
5571 maxtarget = 16;
5572 if (target != CAM_TARGET_WILDCARD) {
5573
5574 i = target;
5575 if (channel == 'B')
5576 i += 8;
5577 maxtarget = i + 1;
5578 }
5579 } else {
5580 maxtarget = 0;
5581 }
5582
5583 for (; i < maxtarget; i++) {
5584 struct scb_tailq *untagged_q;
5585 struct scb *next_scb;
5586
5587 untagged_q = &(ahc->untagged_queues[i]);
5588 next_scb = TAILQ_FIRST(untagged_q);
5589 while (next_scb != NULL) {
5590
5591 scb = next_scb;
5592 next_scb = TAILQ_NEXT(scb, links.tqe);
5593
5594 /*
5595 * The head of the list may be the currently
5596 * active untagged command for a device.
5597 * We're only searching for commands that
5598 * have not been started. A transaction
5599 * marked active but still in the qinfifo
5600 * is removed by the qinfifo scanning code
5601 * above.
5602 */
5603 if ((scb->flags & SCB_ACTIVE) != 0)
5604 continue;
5605
5606 if (ahc_match_scb(ahc, scb, target, channel, lun,
5607 SCB_LIST_NULL, ROLE_INITIATOR) == 0
5608 || (ctx != NULL && ctx != scb->io_ctx))
5609 continue;
5610
5611 /*
5612 * We found an scb that needs to be acted on.
5613 */
5614 found++;
5615 switch (action) {
5616 case SEARCH_COMPLETE:
5617 {
5618 cam_status ostat;
5619 cam_status cstat;
5620
5621 ostat = ahc_get_transaction_status(scb);
5622 if (ostat == CAM_REQ_INPROG)
5623 ahc_set_transaction_status(scb, status);
5624 cstat = ahc_get_transaction_status(scb);
5625 if (cstat != CAM_REQ_CMP)
5626 ahc_freeze_scb(scb);
5627 if ((scb->flags & SCB_ACTIVE) == 0)
5628 printf("Inactive SCB in untaggedQ\n");
5629 ahc_done(ahc, scb);
5630 break;
5631 }
5632 case SEARCH_REMOVE:
5633 scb->flags &= ~SCB_UNTAGGEDQ;
5634 TAILQ_REMOVE(untagged_q, scb, links.tqe);
5635 break;
5636 case SEARCH_COUNT:
5637 break;
5638 }
5639 }
5640 }
5641
5642 if (action == SEARCH_COMPLETE)
5643 ahc_release_untagged_queues(ahc);
5644 return (found);
5645}
5646
5647int
5648ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,
5649 int lun, u_int tag, int stop_on_first, int remove,
5650 int save_state)
5651{
5652 struct scb *scbp;
5653 u_int next;
5654 u_int prev;
5655 u_int count;
5656 u_int active_scb;
5657
5658 count = 0;
5659 next = ahc_inb(ahc, DISCONNECTED_SCBH);
5660 prev = SCB_LIST_NULL;
5661
5662 if (save_state) {
5663 /* restore this when we're done */
5664 active_scb = ahc_inb(ahc, SCBPTR);
5665 } else
5666 /* Silence compiler */
5667 active_scb = SCB_LIST_NULL;
5668
5669 while (next != SCB_LIST_NULL) {
5670 u_int scb_index;
5671
5672 ahc_outb(ahc, SCBPTR, next);
5673 scb_index = ahc_inb(ahc, SCB_TAG);
5674 if (scb_index >= ahc->scb_data->numscbs) {
5675 printf("Disconnected List inconsistency. "
5676 "SCB index == %d, yet numscbs == %d.",
5677 scb_index, ahc->scb_data->numscbs);
5678 ahc_dump_card_state(ahc);
5679 panic("for safety");
5680 }
5681
5682 if (next == prev) {
5683 panic("Disconnected List Loop. "
5684 "cur SCBPTR == %x, prev SCBPTR == %x.",
5685 next, prev);
5686 }
5687 scbp = ahc_lookup_scb(ahc, scb_index);
5688 if (ahc_match_scb(ahc, scbp, target, channel, lun,
5689 tag, ROLE_INITIATOR)) {
5690 count++;
5691 if (remove) {
5692 next =
5693 ahc_rem_scb_from_disc_list(ahc, prev, next);
5694 } else {
5695 prev = next;
5696 next = ahc_inb(ahc, SCB_NEXT);
5697 }
5698 if (stop_on_first)
5699 break;
5700 } else {
5701 prev = next;
5702 next = ahc_inb(ahc, SCB_NEXT);
5703 }
5704 }
5705 if (save_state)
5706 ahc_outb(ahc, SCBPTR, active_scb);
5707 return (count);
5708}
5709
5710/*
5711 * Remove an SCB from the on chip list of disconnected transactions.
5712 * This is empty/unused if we are not performing SCB paging.
5713 */
5714static u_int
5715ahc_rem_scb_from_disc_list(struct ahc_softc *ahc, u_int prev, u_int scbptr)
5716{
5717 u_int next;
5718
5719 ahc_outb(ahc, SCBPTR, scbptr);
5720 next = ahc_inb(ahc, SCB_NEXT);
5721
5722 ahc_outb(ahc, SCB_CONTROL, 0);
5723
5724 ahc_add_curscb_to_free_list(ahc);
5725
5726 if (prev != SCB_LIST_NULL) {
5727 ahc_outb(ahc, SCBPTR, prev);
5728 ahc_outb(ahc, SCB_NEXT, next);
5729 } else
5730 ahc_outb(ahc, DISCONNECTED_SCBH, next);
5731
5732 return (next);
5733}
5734
5735/*
5736 * Add the SCB as selected by SCBPTR onto the on chip list of
5737 * free hardware SCBs. This list is empty/unused if we are not
5738 * performing SCB paging.
5739 */
5740static void
5741ahc_add_curscb_to_free_list(struct ahc_softc *ahc)
5742{
5743 /*
5744 * Invalidate the tag so that our abort
5745 * routines don't think it's active.
5746 */
5747 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
5748
5749 if ((ahc->flags & AHC_PAGESCBS) != 0) {
5750 ahc_outb(ahc, SCB_NEXT, ahc_inb(ahc, FREE_SCBH));
5751 ahc_outb(ahc, FREE_SCBH, ahc_inb(ahc, SCBPTR));
5752 }
5753}
5754
5755/*
5756 * Manipulate the waiting for selection list and return the
5757 * scb that follows the one that we remove.
5758 */
5759static u_int
5760ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
5761{
5762 u_int curscb, next;
5763
5764 /*
5765 * Select the SCB we want to abort and
5766 * pull the next pointer out of it.
5767 */
5768 curscb = ahc_inb(ahc, SCBPTR);
5769 ahc_outb(ahc, SCBPTR, scbpos);
5770 next = ahc_inb(ahc, SCB_NEXT);
5771
5772 /* Clear the necessary fields */
5773 ahc_outb(ahc, SCB_CONTROL, 0);
5774
5775 ahc_add_curscb_to_free_list(ahc);
5776
5777 /* update the waiting list */
5778 if (prev == SCB_LIST_NULL) {
5779 /* First in the list */
5780 ahc_outb(ahc, WAITING_SCBH, next);
5781
5782 /*
5783 * Ensure we aren't attempting to perform
5784 * selection for this entry.
5785 */
5786 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
5787 } else {
5788 /*
5789 * Select the scb that pointed to us
5790 * and update its next pointer.
5791 */
5792 ahc_outb(ahc, SCBPTR, prev);
5793 ahc_outb(ahc, SCB_NEXT, next);
5794 }
5795
5796 /*
5797 * Point us back at the original scb position.
5798 */
5799 ahc_outb(ahc, SCBPTR, curscb);
5800 return next;
5801}
5802
5803/******************************** Error Handling ******************************/
5804/*
5805 * Abort all SCBs that match the given description (target/channel/lun/tag),
5806 * setting their status to the passed in status if the status has not already
5807 * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer
5808 * is paused before it is called.
5809 */
5810int
5811ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
5812 int lun, u_int tag, role_t role, uint32_t status)
5813{
5814 struct scb *scbp;
5815 struct scb *scbp_next;
5816 u_int active_scb;
5817 int i, j;
5818 int maxtarget;
5819 int minlun;
5820 int maxlun;
5821
5822 int found;
5823
5824 /*
5825 * Don't attempt to run any queued untagged transactions
5826 * until we are done with the abort process.
5827 */
5828 ahc_freeze_untagged_queues(ahc);
5829
5830 /* restore this when we're done */
5831 active_scb = ahc_inb(ahc, SCBPTR);
5832
5833 found = ahc_search_qinfifo(ahc, target, channel, lun, SCB_LIST_NULL,
5834 role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
5835
5836 /*
5837 * Clean out the busy target table for any untagged commands.
5838 */
5839 i = 0;
5840 maxtarget = 16;
5841 if (target != CAM_TARGET_WILDCARD) {
5842 i = target;
5843 if (channel == 'B')
5844 i += 8;
5845 maxtarget = i + 1;
5846 }
5847
5848 if (lun == CAM_LUN_WILDCARD) {
5849
5850 /*
5851 * Unless we are using an SCB based
5852 * busy targets table, there is only
5853 * one table entry for all luns of
5854 * a target.
5855 */
5856 minlun = 0;
5857 maxlun = 1;
5858 if ((ahc->flags & AHC_SCB_BTT) != 0)
5859 maxlun = AHC_NUM_LUNS;
5860 } else {
5861 minlun = lun;
5862 maxlun = lun + 1;
5863 }
5864
5865 if (role != ROLE_TARGET) {
5866 for (;i < maxtarget; i++) {
5867 for (j = minlun;j < maxlun; j++) {
5868 u_int scbid;
5869 u_int tcl;
5870
5871 tcl = BUILD_TCL(i << 4, j);
5872 scbid = ahc_index_busy_tcl(ahc, tcl);
5873 scbp = ahc_lookup_scb(ahc, scbid);
5874 if (scbp == NULL
5875 || ahc_match_scb(ahc, scbp, target, channel,
5876 lun, tag, role) == 0)
5877 continue;
5878 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, j));
5879 }
5880 }
5881
5882 /*
5883 * Go through the disconnected list and remove any entries we
5884 * have queued for completion, 0'ing their control byte too.
5885 * We save the active SCB and restore it ourselves, so there
5886 * is no reason for this search to restore it too.
5887 */
5888 ahc_search_disc_list(ahc, target, channel, lun, tag,
5889 /*stop_on_first*/FALSE, /*remove*/TRUE,
5890 /*save_state*/FALSE);
5891 }
5892
5893 /*
5894 * Go through the hardware SCB array looking for commands that
5895 * were active but not on any list. In some cases, these remnants
5896 * might not still have mappings in the scbindex array (e.g. unexpected
5897 * bus free with the same scb queued for an abort). Don't hold this
5898 * against them.
5899 */
5900 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
5901 u_int scbid;
5902
5903 ahc_outb(ahc, SCBPTR, i);
5904 scbid = ahc_inb(ahc, SCB_TAG);
5905 scbp = ahc_lookup_scb(ahc, scbid);
5906 if ((scbp == NULL && scbid != SCB_LIST_NULL)
5907 || (scbp != NULL
5908 && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)))
5909 ahc_add_curscb_to_free_list(ahc);
5910 }
5911
5912 /*
5913 * Go through the pending CCB list and look for
5914 * commands for this target that are still active.
5915 * These are other tagged commands that were
5916 * disconnected when the reset occurred.
5917 */
5918 scbp_next = LIST_FIRST(&ahc->pending_scbs);
5919 while (scbp_next != NULL) {
5920 scbp = scbp_next;
5921 scbp_next = LIST_NEXT(scbp, pending_links);
5922 if (ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {
5923 cam_status ostat;
5924
5925 ostat = ahc_get_transaction_status(scbp);
5926 if (ostat == CAM_REQ_INPROG)
5927 ahc_set_transaction_status(scbp, status);
5928 if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)
5929 ahc_freeze_scb(scbp);
5930 if ((scbp->flags & SCB_ACTIVE) == 0)
5931 printf("Inactive SCB on pending list\n");
5932 ahc_done(ahc, scbp);
5933 found++;
5934 }
5935 }
5936 ahc_outb(ahc, SCBPTR, active_scb);
5937 ahc_platform_abort_scbs(ahc, target, channel, lun, tag, role, status);
5938 ahc_release_untagged_queues(ahc);
5939 return found;
5940}
5941
5942static void
5943ahc_reset_current_bus(struct ahc_softc *ahc)
5944{
5945 uint8_t scsiseq;
5946
5947 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);
5948 scsiseq = ahc_inb(ahc, SCSISEQ);
5949 ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
5950 ahc_flush_device_writes(ahc);
5951 ahc_delay(AHC_BUSRESET_DELAY);
5952 /* Turn off the bus reset */
5953 ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
5954
5955 ahc_clear_intstat(ahc);
5956
5957 /* Re-enable reset interrupts */
5958 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) | ENSCSIRST);
5959}
5960
5961int
5962ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
5963{
5964 struct ahc_devinfo devinfo;
5965 u_int initiator, target, max_scsiid;
5966 u_int sblkctl;
5967 u_int scsiseq;
5968 u_int simode1;
5969 int found;
5970 int restart_needed;
5971 char cur_channel;
5972
5973 ahc->pending_device = NULL;
5974
5975 ahc_compile_devinfo(&devinfo,
5976 CAM_TARGET_WILDCARD,
5977 CAM_TARGET_WILDCARD,
5978 CAM_LUN_WILDCARD,
5979 channel, ROLE_UNKNOWN);
5980 ahc_pause(ahc);
5981
5982 /* Make sure the sequencer is in a safe location. */
5983 ahc_clear_critical_section(ahc);
5984
5985 /*
5986 * Run our command complete fifos to ensure that we perform
5987 * completion processing on any commands that 'completed'
5988 * before the reset occurred.
5989 */
5990 ahc_run_qoutfifo(ahc);
5991#ifdef AHC_TARGET_MODE
5992 /*
5993 * XXX - In Twin mode, the tqinfifo may have commands
5994 * for an unaffected channel in it. However, if
5995 * we have run out of ATIO resources to drain that
5996 * queue, we may not get them all out here. Further,
5997 * the blocked transactions for the reset channel
5998 * should just be killed off, irrespecitve of whether
5999 * we are blocked on ATIO resources. Write a routine
6000 * to compact the tqinfifo appropriately.
6001 */
6002 if ((ahc->flags & AHC_TARGETROLE) != 0) {
6003 ahc_run_tqinfifo(ahc, /*paused*/TRUE);
6004 }
6005#endif
6006
6007 /*
6008 * Reset the bus if we are initiating this reset
6009 */
6010 sblkctl = ahc_inb(ahc, SBLKCTL);
6011 cur_channel = 'A';
6012 if ((ahc->features & AHC_TWIN) != 0
6013 && ((sblkctl & SELBUSB) != 0))
6014 cur_channel = 'B';
6015 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
6016 if (cur_channel != channel) {
6017 /* Case 1: Command for another bus is active
6018 * Stealthily reset the other bus without
6019 * upsetting the current bus.
6020 */
6021 ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
6022 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
6023#ifdef AHC_TARGET_MODE
6024 /*
6025 * Bus resets clear ENSELI, so we cannot
6026 * defer re-enabling bus reset interrupts
6027 * if we are in target mode.
6028 */
6029 if ((ahc->flags & AHC_TARGETROLE) != 0)
6030 simode1 |= ENSCSIRST;
6031#endif
6032 ahc_outb(ahc, SIMODE1, simode1);
6033 if (initiate_reset)
6034 ahc_reset_current_bus(ahc);
6035 ahc_clear_intstat(ahc);
6036 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
6037 ahc_outb(ahc, SBLKCTL, sblkctl);
6038 restart_needed = FALSE;
6039 } else {
6040 /* Case 2: A command from this bus is active or we're idle */
6041 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
6042#ifdef AHC_TARGET_MODE
6043 /*
6044 * Bus resets clear ENSELI, so we cannot
6045 * defer re-enabling bus reset interrupts
6046 * if we are in target mode.
6047 */
6048 if ((ahc->flags & AHC_TARGETROLE) != 0)
6049 simode1 |= ENSCSIRST;
6050#endif
6051 ahc_outb(ahc, SIMODE1, simode1);
6052 if (initiate_reset)
6053 ahc_reset_current_bus(ahc);
6054 ahc_clear_intstat(ahc);
6055 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
6056 restart_needed = TRUE;
6057 }
6058
6059 /*
6060 * Clean up all the state information for the
6061 * pending transactions on this bus.
6062 */
6063 found = ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, channel,
6064 CAM_LUN_WILDCARD, SCB_LIST_NULL,
6065 ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
6066
6067 max_scsiid = (ahc->features & AHC_WIDE) ? 15 : 7;
6068
6069#ifdef AHC_TARGET_MODE
6070 /*
6071 * Send an immediate notify ccb to all target more peripheral
6072 * drivers affected by this action.
6073 */
6074 for (target = 0; target <= max_scsiid; target++) {
6075 struct ahc_tmode_tstate* tstate;
6076 u_int lun;
6077
6078 tstate = ahc->enabled_targets[target];
6079 if (tstate == NULL)
6080 continue;
6081 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
6082 struct ahc_tmode_lstate* lstate;
6083
6084 lstate = tstate->enabled_luns[lun];
6085 if (lstate == NULL)
6086 continue;
6087
6088 ahc_queue_lstate_event(ahc, lstate, CAM_TARGET_WILDCARD,
6089 EVENT_TYPE_BUS_RESET, /*arg*/0);
6090 ahc_send_lstate_events(ahc, lstate);
6091 }
6092 }
6093#endif
6094 /* Notify the XPT that a bus reset occurred */
6095 ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,
6096 CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
6097
6098 /*
6099 * Revert to async/narrow transfers until we renegotiate.
6100 */
6101 for (target = 0; target <= max_scsiid; target++) {
6102
6103 if (ahc->enabled_targets[target] == NULL)
6104 continue;
6105 for (initiator = 0; initiator <= max_scsiid; initiator++) {
6106 struct ahc_devinfo devinfo;
6107
6108 ahc_compile_devinfo(&devinfo, target, initiator,
6109 CAM_LUN_WILDCARD,
6110 channel, ROLE_UNKNOWN);
6111 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
6112 AHC_TRANS_CUR, /*paused*/TRUE);
6113 ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,
6114 /*period*/0, /*offset*/0,
6115 /*ppr_options*/0, AHC_TRANS_CUR,
6116 /*paused*/TRUE);
6117 }
6118 }
6119
6120 if (restart_needed)
6121 ahc_restart(ahc);
6122 else
6123 ahc_unpause(ahc);
6124 return found;
6125}
6126
6127
6128/***************************** Residual Processing ****************************/
6129/*
6130 * Calculate the residual for a just completed SCB.
6131 */
6132void
6133ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
6134{
6135 struct hardware_scb *hscb;
6136 struct status_pkt *spkt;
6137 uint32_t sgptr;
6138 uint32_t resid_sgptr;
6139 uint32_t resid;
6140
6141 /*
6142 * 5 cases.
6143 * 1) No residual.
6144 * SG_RESID_VALID clear in sgptr.
6145 * 2) Transferless command
6146 * 3) Never performed any transfers.
6147 * sgptr has SG_FULL_RESID set.
6148 * 4) No residual but target did not
6149 * save data pointers after the
6150 * last transfer, so sgptr was
6151 * never updated.
6152 * 5) We have a partial residual.
6153 * Use residual_sgptr to determine
6154 * where we are.
6155 */
6156
6157 hscb = scb->hscb;
6158 sgptr = ahc_le32toh(hscb->sgptr);
6159 if ((sgptr & SG_RESID_VALID) == 0)
6160 /* Case 1 */
6161 return;
6162 sgptr &= ~SG_RESID_VALID;
6163
6164 if ((sgptr & SG_LIST_NULL) != 0)
6165 /* Case 2 */
6166 return;
6167
6168 spkt = &hscb->shared_data.status;
6169 resid_sgptr = ahc_le32toh(spkt->residual_sg_ptr);
6170 if ((sgptr & SG_FULL_RESID) != 0) {
6171 /* Case 3 */
6172 resid = ahc_get_transfer_length(scb);
6173 } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
6174 /* Case 4 */
6175 return;
6176 } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
6177 panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
6178 } else {
6179 struct ahc_dma_seg *sg;
6180
6181 /*
6182 * Remainder of the SG where the transfer
6183 * stopped.
6184 */
6185 resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
6186 sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);
6187
6188 /* The residual sg_ptr always points to the next sg */
6189 sg--;
6190
6191 /*
6192 * Add up the contents of all residual
6193 * SG segments that are after the SG where
6194 * the transfer stopped.
6195 */
6196 while ((ahc_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {
6197 sg++;
6198 resid += ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
6199 }
6200 }
6201 if ((scb->flags & SCB_SENSE) == 0)
6202 ahc_set_residual(scb, resid);
6203 else
6204 ahc_set_sense_residual(scb, resid);
6205
6206#ifdef AHC_DEBUG
6207 if ((ahc_debug & AHC_SHOW_MISC) != 0) {
6208 ahc_print_path(ahc, scb);
6209 printf("Handled %sResidual of %d bytes\n",
6210 (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
6211 }
6212#endif
6213}
6214
6215/******************************* Target Mode **********************************/
6216#ifdef AHC_TARGET_MODE
6217/*
6218 * Add a target mode event to this lun's queue
6219 */
6220static void
6221ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,
6222 u_int initiator_id, u_int event_type, u_int event_arg)
6223{
6224 struct ahc_tmode_event *event;
6225 int pending;
6226
6227 xpt_freeze_devq(lstate->path, /*count*/1);
6228 if (lstate->event_w_idx >= lstate->event_r_idx)
6229 pending = lstate->event_w_idx - lstate->event_r_idx;
6230 else
6231 pending = AHC_TMODE_EVENT_BUFFER_SIZE + 1
6232 - (lstate->event_r_idx - lstate->event_w_idx);
6233
6234 if (event_type == EVENT_TYPE_BUS_RESET
6235 || event_type == MSG_BUS_DEV_RESET) {
6236 /*
6237 * Any earlier events are irrelevant, so reset our buffer.
6238 * This has the effect of allowing us to deal with reset
6239 * floods (an external device holding down the reset line)
6240 * without losing the event that is really interesting.
6241 */
6242 lstate->event_r_idx = 0;
6243 lstate->event_w_idx = 0;
6244 xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE);
6245 }
6246
6247 if (pending == AHC_TMODE_EVENT_BUFFER_SIZE) {
6248 xpt_print_path(lstate->path);
6249 printf("immediate event %x:%x lost\n",
6250 lstate->event_buffer[lstate->event_r_idx].event_type,
6251 lstate->event_buffer[lstate->event_r_idx].event_arg);
6252 lstate->event_r_idx++;
6253 if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
6254 lstate->event_r_idx = 0;
6255 xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE);
6256 }
6257
6258 event = &lstate->event_buffer[lstate->event_w_idx];
6259 event->initiator_id = initiator_id;
6260 event->event_type = event_type;
6261 event->event_arg = event_arg;
6262 lstate->event_w_idx++;
6263 if (lstate->event_w_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
6264 lstate->event_w_idx = 0;
6265}
6266
6267/*
6268 * Send any target mode events queued up waiting
6269 * for immediate notify resources.
6270 */
6271void
6272ahc_send_lstate_events(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate)
6273{
6274 struct ccb_hdr *ccbh;
6275 struct ccb_immed_notify *inot;
6276
6277 while (lstate->event_r_idx != lstate->event_w_idx
6278 && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
6279 struct ahc_tmode_event *event;
6280
6281 event = &lstate->event_buffer[lstate->event_r_idx];
6282 SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
6283 inot = (struct ccb_immed_notify *)ccbh;
6284 switch (event->event_type) {
6285 case EVENT_TYPE_BUS_RESET:
6286 ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
6287 break;
6288 default:
6289 ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
6290 inot->message_args[0] = event->event_type;
6291 inot->message_args[1] = event->event_arg;
6292 break;
6293 }
6294 inot->initiator_id = event->initiator_id;
6295 inot->sense_len = 0;
6296 xpt_done((union ccb *)inot);
6297 lstate->event_r_idx++;
6298 if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
6299 lstate->event_r_idx = 0;
6300 }
6301}
6302#endif
6303
6304/******************** Sequencer Program Patching/Download *********************/
6305
6306#ifdef AHC_DUMP_SEQ
6307void
6308ahc_dumpseq(struct ahc_softc* ahc)
6309{
6310 int i;
6311
6312 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
6313 ahc_outb(ahc, SEQADDR0, 0);
6314 ahc_outb(ahc, SEQADDR1, 0);
6315 for (i = 0; i < ahc->instruction_ram_size; i++) {
6316 uint8_t ins_bytes[4];
6317
6318 ahc_insb(ahc, SEQRAM, ins_bytes, 4);
6319 printf("0x%08x\n", ins_bytes[0] << 24
6320 | ins_bytes[1] << 16
6321 | ins_bytes[2] << 8
6322 | ins_bytes[3]);
6323 }
6324}
6325#endif
6326
6327static int
6328ahc_loadseq(struct ahc_softc *ahc)
6329{
6330 struct cs cs_table[num_critical_sections];
6331 u_int begin_set[num_critical_sections];
6332 u_int end_set[num_critical_sections];
6333 struct patch *cur_patch;
6334 u_int cs_count;
6335 u_int cur_cs;
6336 u_int i;
6337 u_int skip_addr;
6338 u_int sg_prefetch_cnt;
6339 int downloaded;
6340 uint8_t download_consts[7];
6341
6342 /*
6343 * Start out with 0 critical sections
6344 * that apply to this firmware load.
6345 */
6346 cs_count = 0;
6347 cur_cs = 0;
6348 memset(begin_set, 0, sizeof(begin_set));
6349 memset(end_set, 0, sizeof(end_set));
6350
6351 /* Setup downloadable constant table */
6352 download_consts[QOUTFIFO_OFFSET] = 0;
6353 if (ahc->targetcmds != NULL)
6354 download_consts[QOUTFIFO_OFFSET] += 32;
6355 download_consts[QINFIFO_OFFSET] = download_consts[QOUTFIFO_OFFSET] + 1;
6356 download_consts[CACHESIZE_MASK] = ahc->pci_cachesize - 1;
6357 download_consts[INVERTED_CACHESIZE_MASK] = ~(ahc->pci_cachesize - 1);
6358 sg_prefetch_cnt = ahc->pci_cachesize;
6359 if (sg_prefetch_cnt < (2 * sizeof(struct ahc_dma_seg)))
6360 sg_prefetch_cnt = 2 * sizeof(struct ahc_dma_seg);
6361 download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
6362 download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_cnt - 1);
6363 download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_cnt - 1);
6364
6365 cur_patch = patches;
6366 downloaded = 0;
6367 skip_addr = 0;
6368 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
6369 ahc_outb(ahc, SEQADDR0, 0);
6370 ahc_outb(ahc, SEQADDR1, 0);
6371
6372 for (i = 0; i < sizeof(seqprog)/4; i++) {
6373 if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {
6374 /*
6375 * Don't download this instruction as it
6376 * is in a patch that was removed.
6377 */
6378 continue;
6379 }
6380
6381 if (downloaded == ahc->instruction_ram_size) {
6382 /*
6383 * We're about to exceed the instruction
6384 * storage capacity for this chip. Fail
6385 * the load.
6386 */
6387 printf("\n%s: Program too large for instruction memory "
6388 "size of %d!\n", ahc_name(ahc),
6389 ahc->instruction_ram_size);
6390 return (ENOMEM);
6391 }
6392
6393 /*
6394 * Move through the CS table until we find a CS
6395 * that might apply to this instruction.
6396 */
6397 for (; cur_cs < num_critical_sections; cur_cs++) {
6398 if (critical_sections[cur_cs].end <= i) {
6399 if (begin_set[cs_count] == TRUE
6400 && end_set[cs_count] == FALSE) {
6401 cs_table[cs_count].end = downloaded;
6402 end_set[cs_count] = TRUE;
6403 cs_count++;
6404 }
6405 continue;
6406 }
6407 if (critical_sections[cur_cs].begin <= i
6408 && begin_set[cs_count] == FALSE) {
6409 cs_table[cs_count].begin = downloaded;
6410 begin_set[cs_count] = TRUE;
6411 }
6412 break;
6413 }
6414 ahc_download_instr(ahc, i, download_consts);
6415 downloaded++;
6416 }
6417
6418 ahc->num_critical_sections = cs_count;
6419 if (cs_count != 0) {
6420
6421 cs_count *= sizeof(struct cs);
6422 ahc->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
6423 if (ahc->critical_sections == NULL)
6424 panic("ahc_loadseq: Could not malloc");
6425 memcpy(ahc->critical_sections, cs_table, cs_count);
6426 }
6427 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
6428
6429 if (bootverbose) {
6430 printf(" %d instructions downloaded\n", downloaded);
6431 printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
6432 ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags);
6433 }
6434 return (0);
6435}
6436
6437static int
6438ahc_check_patch(struct ahc_softc *ahc, struct patch **start_patch,
6439 u_int start_instr, u_int *skip_addr)
6440{
6441 struct patch *cur_patch;
6442 struct patch *last_patch;
6443 u_int num_patches;
6444
6445 num_patches = sizeof(patches)/sizeof(struct patch);
6446 last_patch = &patches[num_patches];
6447 cur_patch = *start_patch;
6448
6449 while (cur_patch < last_patch && start_instr == cur_patch->begin) {
6450
6451 if (cur_patch->patch_func(ahc) == 0) {
6452
6453 /* Start rejecting code */
6454 *skip_addr = start_instr + cur_patch->skip_instr;
6455 cur_patch += cur_patch->skip_patch;
6456 } else {
6457 /* Accepted this patch. Advance to the next
6458 * one and wait for our intruction pointer to
6459 * hit this point.
6460 */
6461 cur_patch++;
6462 }
6463 }
6464
6465 *start_patch = cur_patch;
6466 if (start_instr < *skip_addr)
6467 /* Still skipping */
6468 return (0);
6469
6470 return (1);
6471}
6472
6473static void
6474ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts)
6475{
6476 union ins_formats instr;
6477 struct ins_format1 *fmt1_ins;
6478 struct ins_format3 *fmt3_ins;
6479 u_int opcode;
6480
6481 /*
6482 * The firmware is always compiled into a little endian format.
6483 */
6484 instr.integer = ahc_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
6485
6486 fmt1_ins = &instr.format1;
6487 fmt3_ins = NULL;
6488
6489 /* Pull the opcode */
6490 opcode = instr.format1.opcode;
6491 switch (opcode) {
6492 case AIC_OP_JMP:
6493 case AIC_OP_JC:
6494 case AIC_OP_JNC:
6495 case AIC_OP_CALL:
6496 case AIC_OP_JNE:
6497 case AIC_OP_JNZ:
6498 case AIC_OP_JE:
6499 case AIC_OP_JZ:
6500 {
6501 struct patch *cur_patch;
6502 int address_offset;
6503 u_int address;
6504 u_int skip_addr;
6505 u_int i;
6506
6507 fmt3_ins = &instr.format3;
6508 address_offset = 0;
6509 address = fmt3_ins->address;
6510 cur_patch = patches;
6511 skip_addr = 0;
6512
6513 for (i = 0; i < address;) {
6514
6515 ahc_check_patch(ahc, &cur_patch, i, &skip_addr);
6516
6517 if (skip_addr > i) {
6518 int end_addr;
6519
6520 end_addr = MIN(address, skip_addr);
6521 address_offset += end_addr - i;
6522 i = skip_addr;
6523 } else {
6524 i++;
6525 }
6526 }
6527 address -= address_offset;
6528 fmt3_ins->address = address;
6529 /* FALLTHROUGH */
6530 }
6531 case AIC_OP_OR:
6532 case AIC_OP_AND:
6533 case AIC_OP_XOR:
6534 case AIC_OP_ADD:
6535 case AIC_OP_ADC:
6536 case AIC_OP_BMOV:
6537 if (fmt1_ins->parity != 0) {
6538 fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
6539 }
6540 fmt1_ins->parity = 0;
6541 if ((ahc->features & AHC_CMD_CHAN) == 0
6542 && opcode == AIC_OP_BMOV) {
6543 /*
6544 * Block move was added at the same time
6545 * as the command channel. Verify that
6546 * this is only a move of a single element
6547 * and convert the BMOV to a MOV
6548 * (AND with an immediate of FF).
6549 */
6550 if (fmt1_ins->immediate != 1)
6551 panic("%s: BMOV not supported\n",
6552 ahc_name(ahc));
6553 fmt1_ins->opcode = AIC_OP_AND;
6554 fmt1_ins->immediate = 0xff;
6555 }
6556 /* FALLTHROUGH */
6557 case AIC_OP_ROL:
6558 if ((ahc->features & AHC_ULTRA2) != 0) {
6559 int i, count;
6560
6561 /* Calculate odd parity for the instruction */
6562 for (i = 0, count = 0; i < 31; i++) {
6563 uint32_t mask;
6564
6565 mask = 0x01 << i;
6566 if ((instr.integer & mask) != 0)
6567 count++;
6568 }
6569 if ((count & 0x01) == 0)
6570 instr.format1.parity = 1;
6571 } else {
6572 /* Compress the instruction for older sequencers */
6573 if (fmt3_ins != NULL) {
6574 instr.integer =
6575 fmt3_ins->immediate
6576 | (fmt3_ins->source << 8)
6577 | (fmt3_ins->address << 16)
6578 | (fmt3_ins->opcode << 25);
6579 } else {
6580 instr.integer =
6581 fmt1_ins->immediate
6582 | (fmt1_ins->source << 8)
6583 | (fmt1_ins->destination << 16)
6584 | (fmt1_ins->ret << 24)
6585 | (fmt1_ins->opcode << 25);
6586 }
6587 }
6588 /* The sequencer is a little endian cpu */
6589 instr.integer = ahc_htole32(instr.integer);
6590 ahc_outsb(ahc, SEQRAM, instr.bytes, 4);
6591 break;
6592 default:
6593 panic("Unknown opcode encountered in seq program");
6594 break;
6595 }
6596}
6597
6598int
6599ahc_print_register(ahc_reg_parse_entry_t *table, u_int num_entries,
6600 const char *name, u_int address, u_int value,
6601 u_int *cur_column, u_int wrap_point)
6602{
6603 int printed;
6604 u_int printed_mask;
6605
6606 if (cur_column != NULL && *cur_column >= wrap_point) {
6607 printf("\n");
6608 *cur_column = 0;
6609 }
6610 printed = printf("%s[0x%x]", name, value);
6611 if (table == NULL) {
6612 printed += printf(" ");
6613 *cur_column += printed;
6614 return (printed);
6615 }
6616 printed_mask = 0;
6617 while (printed_mask != 0xFF) {
6618 int entry;
6619
6620 for (entry = 0; entry < num_entries; entry++) {
6621 if (((value & table[entry].mask)
6622 != table[entry].value)
6623 || ((printed_mask & table[entry].mask)
6624 == table[entry].mask))
6625 continue;
6626
6627 printed += printf("%s%s",
6628 printed_mask == 0 ? ":(" : "|",
6629 table[entry].name);
6630 printed_mask |= table[entry].mask;
6631
6632 break;
6633 }
6634 if (entry >= num_entries)
6635 break;
6636 }
6637 if (printed_mask != 0)
6638 printed += printf(") ");
6639 else
6640 printed += printf(" ");
6641 if (cur_column != NULL)
6642 *cur_column += printed;
6643 return (printed);
6644}
6645
6646void
6647ahc_dump_card_state(struct ahc_softc *ahc)
6648{
6649 struct scb *scb;
6650 struct scb_tailq *untagged_q;
6651 u_int cur_col;
6652 int paused;
6653 int target;
6654 int maxtarget;
6655 int i;
6656 uint8_t last_phase;
6657 uint8_t qinpos;
6658 uint8_t qintail;
6659 uint8_t qoutpos;
6660 uint8_t scb_index;
6661 uint8_t saved_scbptr;
6662
6663 if (ahc_is_paused(ahc)) {
6664 paused = 1;
6665 } else {
6666 paused = 0;
6667 ahc_pause(ahc);
6668 }
6669
6670 saved_scbptr = ahc_inb(ahc, SCBPTR);
6671 last_phase = ahc_inb(ahc, LASTPHASE);
6672 printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
6673 "%s: Dumping Card State %s, at SEQADDR 0x%x\n",
6674 ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,
6675 ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
6676 if (paused)
6677 printf("Card was paused\n");
6678 printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
6679 ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
6680 ahc_inb(ahc, ARG_2));
6681 printf("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT),
6682 ahc_inb(ahc, SCBPTR));
6683 cur_col = 0;
6684 if ((ahc->features & AHC_DT) != 0)
6685 ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50);
6686 ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50);
6687 ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50);
6688 ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50);
6689 ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50);
6690 ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50);
6691 ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50);
6692 ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50);
6693 ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50);
6694 ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50);
6695 ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50);
6696 ahc_sstat1_print(ahc_inb(ahc, SSTAT1), &cur_col, 50);
6697 ahc_sstat2_print(ahc_inb(ahc, SSTAT2), &cur_col, 50);
6698 ahc_sstat3_print(ahc_inb(ahc, SSTAT3), &cur_col, 50);
6699 ahc_simode0_print(ahc_inb(ahc, SIMODE0), &cur_col, 50);
6700 ahc_simode1_print(ahc_inb(ahc, SIMODE1), &cur_col, 50);
6701 ahc_sxfrctl0_print(ahc_inb(ahc, SXFRCTL0), &cur_col, 50);
6702 ahc_dfcntrl_print(ahc_inb(ahc, DFCNTRL), &cur_col, 50);
6703 ahc_dfstatus_print(ahc_inb(ahc, DFSTATUS), &cur_col, 50);
6704 if (cur_col != 0)
6705 printf("\n");
6706 printf("STACK:");
6707 for (i = 0; i < STACK_SIZE; i++)
6708 printf(" 0x%x", ahc_inb(ahc, STACK)|(ahc_inb(ahc, STACK) << 8));
6709 printf("\nSCB count = %d\n", ahc->scb_data->numscbs);
6710 printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);
6711 printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));
6712 /* QINFIFO */
6713 printf("QINFIFO entries: ");
6714 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
6715 qinpos = ahc_inb(ahc, SNSCB_QOFF);
6716 ahc_outb(ahc, SNSCB_QOFF, qinpos);
6717 } else
6718 qinpos = ahc_inb(ahc, QINPOS);
6719 qintail = ahc->qinfifonext;
6720 while (qinpos != qintail) {
6721 printf("%d ", ahc->qinfifo[qinpos]);
6722 qinpos++;
6723 }
6724 printf("\n");
6725
6726 printf("Waiting Queue entries: ");
6727 scb_index = ahc_inb(ahc, WAITING_SCBH);
6728 i = 0;
6729 while (scb_index != SCB_LIST_NULL && i++ < 256) {
6730 ahc_outb(ahc, SCBPTR, scb_index);
6731 printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
6732 scb_index = ahc_inb(ahc, SCB_NEXT);
6733 }
6734 printf("\n");
6735
6736 printf("Disconnected Queue entries: ");
6737 scb_index = ahc_inb(ahc, DISCONNECTED_SCBH);
6738 i = 0;
6739 while (scb_index != SCB_LIST_NULL && i++ < 256) {
6740 ahc_outb(ahc, SCBPTR, scb_index);
6741 printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
6742 scb_index = ahc_inb(ahc, SCB_NEXT);
6743 }
6744 printf("\n");
6745
6746 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
6747 printf("QOUTFIFO entries: ");
6748 qoutpos = ahc->qoutfifonext;
6749 i = 0;
6750 while (ahc->qoutfifo[qoutpos] != SCB_LIST_NULL && i++ < 256) {
6751 printf("%d ", ahc->qoutfifo[qoutpos]);
6752 qoutpos++;
6753 }
6754 printf("\n");
6755
6756 printf("Sequencer Free SCB List: ");
6757 scb_index = ahc_inb(ahc, FREE_SCBH);
6758 i = 0;
6759 while (scb_index != SCB_LIST_NULL && i++ < 256) {
6760 ahc_outb(ahc, SCBPTR, scb_index);
6761 printf("%d ", scb_index);
6762 scb_index = ahc_inb(ahc, SCB_NEXT);
6763 }
6764 printf("\n");
6765
6766 printf("Sequencer SCB Info: ");
6767 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
6768 ahc_outb(ahc, SCBPTR, i);
6769 cur_col = printf("\n%3d ", i);
6770
6771 ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), &cur_col, 60);
6772 ahc_scb_scsiid_print(ahc_inb(ahc, SCB_SCSIID), &cur_col, 60);
6773 ahc_scb_lun_print(ahc_inb(ahc, SCB_LUN), &cur_col, 60);
6774 ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
6775 }
6776 printf("\n");
6777
6778 printf("Pending list: ");
6779 i = 0;
6780 LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
6781 if (i++ > 256)
6782 break;
6783 cur_col = printf("\n%3d ", scb->hscb->tag);
6784 ahc_scb_control_print(scb->hscb->control, &cur_col, 60);
6785 ahc_scb_scsiid_print(scb->hscb->scsiid, &cur_col, 60);
6786 ahc_scb_lun_print(scb->hscb->lun, &cur_col, 60);
6787 if ((ahc->flags & AHC_PAGESCBS) == 0) {
6788 ahc_outb(ahc, SCBPTR, scb->hscb->tag);
6789 printf("(");
6790 ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL),
6791 &cur_col, 60);
6792 ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
6793 printf(")");
6794 }
6795 }
6796 printf("\n");
6797
6798 printf("Kernel Free SCB list: ");
6799 i = 0;
6800 SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {
6801 if (i++ > 256)
6802 break;
6803 printf("%d ", scb->hscb->tag);
6804 }
6805 printf("\n");
6806
6807 maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;
6808 for (target = 0; target <= maxtarget; target++) {
6809 untagged_q = &ahc->untagged_queues[target];
6810 if (TAILQ_FIRST(untagged_q) == NULL)
6811 continue;
6812 printf("Untagged Q(%d): ", target);
6813 i = 0;
6814 TAILQ_FOREACH(scb, untagged_q, links.tqe) {
6815 if (i++ > 256)
6816 break;
6817 printf("%d ", scb->hscb->tag);
6818 }
6819 printf("\n");
6820 }
6821
6822 ahc_platform_dump_card_state(ahc);
6823 printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
6824 ahc_outb(ahc, SCBPTR, saved_scbptr);
6825 if (paused == 0)
6826 ahc_unpause(ahc);
6827}
6828
6829/************************* Target Mode ****************************************/
6830#ifdef AHC_TARGET_MODE
6831cam_status
6832ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb,
6833 struct ahc_tmode_tstate **tstate,
6834 struct ahc_tmode_lstate **lstate,
6835 int notfound_failure)
6836{
6837
6838 if ((ahc->features & AHC_TARGETMODE) == 0)
6839 return (CAM_REQ_INVALID);
6840
6841 /*
6842 * Handle the 'black hole' device that sucks up
6843 * requests to unattached luns on enabled targets.
6844 */
6845 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
6846 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
6847 *tstate = NULL;
6848 *lstate = ahc->black_hole;
6849 } else {
6850 u_int max_id;
6851
6852 max_id = (ahc->features & AHC_WIDE) ? 15 : 7;
6853 if (ccb->ccb_h.target_id > max_id)
6854 return (CAM_TID_INVALID);
6855
6856 if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS)
6857 return (CAM_LUN_INVALID);
6858
6859 *tstate = ahc->enabled_targets[ccb->ccb_h.target_id];
6860 *lstate = NULL;
6861 if (*tstate != NULL)
6862 *lstate =
6863 (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
6864 }
6865
6866 if (notfound_failure != 0 && *lstate == NULL)
6867 return (CAM_PATH_INVALID);
6868
6869 return (CAM_REQ_CMP);
6870}
6871
6872void
6873ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
6874{
6875 struct ahc_tmode_tstate *tstate;
6876 struct ahc_tmode_lstate *lstate;
6877 struct ccb_en_lun *cel;
6878 cam_status status;
6879 u_long s;
6880 u_int target;
6881 u_int lun;
6882 u_int target_mask;
6883 u_int our_id;
6884 int error;
6885 char channel;
6886
6887 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate,
6888 /*notfound_failure*/FALSE);
6889
6890 if (status != CAM_REQ_CMP) {
6891 ccb->ccb_h.status = status;
6892 return;
6893 }
6894
6895 if (cam_sim_bus(sim) == 0)
6896 our_id = ahc->our_id;
6897 else
6898 our_id = ahc->our_id_b;
6899
6900 if (ccb->ccb_h.target_id != our_id) {
6901 /*
6902 * our_id represents our initiator ID, or
6903 * the ID of the first target to have an
6904 * enabled lun in target mode. There are
6905 * two cases that may preclude enabling a
6906 * target id other than our_id.
6907 *
6908 * o our_id is for an active initiator role.
6909 * Since the hardware does not support
6910 * reselections to the initiator role at
6911 * anything other than our_id, and our_id
6912 * is used by the hardware to indicate the
6913 * ID to use for both select-out and
6914 * reselect-out operations, the only target
6915 * ID we can support in this mode is our_id.
6916 *
6917 * o The MULTARGID feature is not available and
6918 * a previous target mode ID has been enabled.
6919 */
6920 if ((ahc->features & AHC_MULTIROLE) != 0) {
6921
6922 if ((ahc->features & AHC_MULTI_TID) != 0
6923 && (ahc->flags & AHC_INITIATORROLE) != 0) {
6924 /*
6925 * Only allow additional targets if
6926 * the initiator role is disabled.
6927 * The hardware cannot handle a re-select-in
6928 * on the initiator id during a re-select-out
6929 * on a different target id.
6930 */
6931 status = CAM_TID_INVALID;
6932 } else if ((ahc->flags & AHC_INITIATORROLE) != 0
6933 || ahc->enabled_luns > 0) {
6934 /*
6935 * Only allow our target id to change
6936 * if the initiator role is not configured
6937 * and there are no enabled luns which
6938 * are attached to the currently registered
6939 * scsi id.
6940 */
6941 status = CAM_TID_INVALID;
6942 }
6943 } else if ((ahc->features & AHC_MULTI_TID) == 0
6944 && ahc->enabled_luns > 0) {
6945
6946 status = CAM_TID_INVALID;
6947 }
6948 }
6949
6950 if (status != CAM_REQ_CMP) {
6951 ccb->ccb_h.status = status;
6952 return;
6953 }
6954
6955 /*
6956 * We now have an id that is valid.
6957 * If we aren't in target mode, switch modes.
6958 */
6959 if ((ahc->flags & AHC_TARGETROLE) == 0
6960 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
6961 u_long s;
6962 ahc_flag saved_flags;
6963
6964 printf("Configuring Target Mode\n");
6965 ahc_lock(ahc, &s);
6966 if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
6967 ccb->ccb_h.status = CAM_BUSY;
6968 ahc_unlock(ahc, &s);
6969 return;
6970 }
6971 saved_flags = ahc->flags;
6972 ahc->flags |= AHC_TARGETROLE;
6973 if ((ahc->features & AHC_MULTIROLE) == 0)
6974 ahc->flags &= ~AHC_INITIATORROLE;
6975 ahc_pause(ahc);
6976 error = ahc_loadseq(ahc);
6977 if (error != 0) {
6978 /*
6979 * Restore original configuration and notify
6980 * the caller that we cannot support target mode.
6981 * Since the adapter started out in this
6982 * configuration, the firmware load will succeed,
6983 * so there is no point in checking ahc_loadseq's
6984 * return value.
6985 */
6986 ahc->flags = saved_flags;
6987 (void)ahc_loadseq(ahc);
6988 ahc_restart(ahc);
6989 ahc_unlock(ahc, &s);
6990 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
6991 return;
6992 }
6993 ahc_restart(ahc);
6994 ahc_unlock(ahc, &s);
6995 }
6996 cel = &ccb->cel;
6997 target = ccb->ccb_h.target_id;
6998 lun = ccb->ccb_h.target_lun;
6999 channel = SIM_CHANNEL(ahc, sim);
7000 target_mask = 0x01 << target;
7001 if (channel == 'B')
7002 target_mask <<= 8;
7003
7004 if (cel->enable != 0) {
7005 u_int scsiseq;
7006
7007 /* Are we already enabled?? */
7008 if (lstate != NULL) {
7009 xpt_print_path(ccb->ccb_h.path);
7010 printf("Lun already enabled\n");
7011 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
7012 return;
7013 }
7014
7015 if (cel->grp6_len != 0
7016 || cel->grp7_len != 0) {
7017 /*
7018 * Don't (yet?) support vendor
7019 * specific commands.
7020 */
7021 ccb->ccb_h.status = CAM_REQ_INVALID;
7022 printf("Non-zero Group Codes\n");
7023 return;
7024 }
7025
7026 /*
7027 * Seems to be okay.
7028 * Setup our data structures.
7029 */
7030 if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
7031 tstate = ahc_alloc_tstate(ahc, target, channel);
7032 if (tstate == NULL) {
7033 xpt_print_path(ccb->ccb_h.path);
7034 printf("Couldn't allocate tstate\n");
7035 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
7036 return;
7037 }
7038 }
7039 lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
7040 if (lstate == NULL) {
7041 xpt_print_path(ccb->ccb_h.path);
7042 printf("Couldn't allocate lstate\n");
7043 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
7044 return;
7045 }
7046 memset(lstate, 0, sizeof(*lstate));
7047 status = xpt_create_path(&lstate->path, /*periph*/NULL,
7048 xpt_path_path_id(ccb->ccb_h.path),
7049 xpt_path_target_id(ccb->ccb_h.path),
7050 xpt_path_lun_id(ccb->ccb_h.path));
7051 if (status != CAM_REQ_CMP) {
7052 free(lstate, M_DEVBUF);
7053 xpt_print_path(ccb->ccb_h.path);
7054 printf("Couldn't allocate path\n");
7055 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
7056 return;
7057 }
7058 SLIST_INIT(&lstate->accept_tios);
7059 SLIST_INIT(&lstate->immed_notifies);
7060 ahc_lock(ahc, &s);
7061 ahc_pause(ahc);
7062 if (target != CAM_TARGET_WILDCARD) {
7063 tstate->enabled_luns[lun] = lstate;
7064 ahc->enabled_luns++;
7065
7066 if ((ahc->features & AHC_MULTI_TID) != 0) {
7067 u_int targid_mask;
7068
7069 targid_mask = ahc_inb(ahc, TARGID)
7070 | (ahc_inb(ahc, TARGID + 1) << 8);
7071
7072 targid_mask |= target_mask;
7073 ahc_outb(ahc, TARGID, targid_mask);
7074 ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
7075
7076 ahc_update_scsiid(ahc, targid_mask);
7077 } else {
7078 u_int our_id;
7079 char channel;
7080
7081 channel = SIM_CHANNEL(ahc, sim);
7082 our_id = SIM_SCSI_ID(ahc, sim);
7083
7084 /*
7085 * This can only happen if selections
7086 * are not enabled
7087 */
7088 if (target != our_id) {
7089 u_int sblkctl;
7090 char cur_channel;
7091 int swap;
7092
7093 sblkctl = ahc_inb(ahc, SBLKCTL);
7094 cur_channel = (sblkctl & SELBUSB)
7095 ? 'B' : 'A';
7096 if ((ahc->features & AHC_TWIN) == 0)
7097 cur_channel = 'A';
7098 swap = cur_channel != channel;
7099 if (channel == 'A')
7100 ahc->our_id = target;
7101 else
7102 ahc->our_id_b = target;
7103
7104 if (swap)
7105 ahc_outb(ahc, SBLKCTL,
7106 sblkctl ^ SELBUSB);
7107
7108 ahc_outb(ahc, SCSIID, target);
7109
7110 if (swap)
7111 ahc_outb(ahc, SBLKCTL, sblkctl);
7112 }
7113 }
7114 } else
7115 ahc->black_hole = lstate;
7116 /* Allow select-in operations */
7117 if (ahc->black_hole != NULL && ahc->enabled_luns > 0) {
7118 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
7119 scsiseq |= ENSELI;
7120 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
7121 scsiseq = ahc_inb(ahc, SCSISEQ);
7122 scsiseq |= ENSELI;
7123 ahc_outb(ahc, SCSISEQ, scsiseq);
7124 }
7125 ahc_unpause(ahc);
7126 ahc_unlock(ahc, &s);
7127 ccb->ccb_h.status = CAM_REQ_CMP;
7128 xpt_print_path(ccb->ccb_h.path);
7129 printf("Lun now enabled for target mode\n");
7130 } else {
7131 struct scb *scb;
7132 int i, empty;
7133
7134 if (lstate == NULL) {
7135 ccb->ccb_h.status = CAM_LUN_INVALID;
7136 return;
7137 }
7138
7139 ahc_lock(ahc, &s);
7140
7141 ccb->ccb_h.status = CAM_REQ_CMP;
7142 LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
7143 struct ccb_hdr *ccbh;
7144
7145 ccbh = &scb->io_ctx->ccb_h;
7146 if (ccbh->func_code == XPT_CONT_TARGET_IO
7147 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
7148 printf("CTIO pending\n");
7149 ccb->ccb_h.status = CAM_REQ_INVALID;
7150 ahc_unlock(ahc, &s);
7151 return;
7152 }
7153 }
7154
7155 if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
7156 printf("ATIOs pending\n");
7157 ccb->ccb_h.status = CAM_REQ_INVALID;
7158 }
7159
7160 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
7161 printf("INOTs pending\n");
7162 ccb->ccb_h.status = CAM_REQ_INVALID;
7163 }
7164
7165 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7166 ahc_unlock(ahc, &s);
7167 return;
7168 }
7169
7170 xpt_print_path(ccb->ccb_h.path);
7171 printf("Target mode disabled\n");
7172 xpt_free_path(lstate->path);
7173 free(lstate, M_DEVBUF);
7174
7175 ahc_pause(ahc);
7176 /* Can we clean up the target too? */
7177 if (target != CAM_TARGET_WILDCARD) {
7178 tstate->enabled_luns[lun] = NULL;
7179 ahc->enabled_luns--;
7180 for (empty = 1, i = 0; i < 8; i++)
7181 if (tstate->enabled_luns[i] != NULL) {
7182 empty = 0;
7183 break;
7184 }
7185
7186 if (empty) {
7187 ahc_free_tstate(ahc, target, channel,
7188 /*force*/FALSE);
7189 if (ahc->features & AHC_MULTI_TID) {
7190 u_int targid_mask;
7191
7192 targid_mask = ahc_inb(ahc, TARGID)
7193 | (ahc_inb(ahc, TARGID + 1)
7194 << 8);
7195
7196 targid_mask &= ~target_mask;
7197 ahc_outb(ahc, TARGID, targid_mask);
7198 ahc_outb(ahc, TARGID+1,
7199 (targid_mask >> 8));
7200 ahc_update_scsiid(ahc, targid_mask);
7201 }
7202 }
7203 } else {
7204
7205 ahc->black_hole = NULL;
7206
7207 /*
7208 * We can't allow selections without
7209 * our black hole device.
7210 */
7211 empty = TRUE;
7212 }
7213 if (ahc->enabled_luns == 0) {
7214 /* Disallow select-in */
7215 u_int scsiseq;
7216
7217 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
7218 scsiseq &= ~ENSELI;
7219 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
7220 scsiseq = ahc_inb(ahc, SCSISEQ);
7221 scsiseq &= ~ENSELI;
7222 ahc_outb(ahc, SCSISEQ, scsiseq);
7223
7224 if ((ahc->features & AHC_MULTIROLE) == 0) {
7225 printf("Configuring Initiator Mode\n");
7226 ahc->flags &= ~AHC_TARGETROLE;
7227 ahc->flags |= AHC_INITIATORROLE;
7228 /*
7229 * Returning to a configuration that
7230 * fit previously will always succeed.
7231 */
7232 (void)ahc_loadseq(ahc);
7233 ahc_restart(ahc);
7234 /*
7235 * Unpaused. The extra unpause
7236 * that follows is harmless.
7237 */
7238 }
7239 }
7240 ahc_unpause(ahc);
7241 ahc_unlock(ahc, &s);
7242 }
7243}
7244
7245static void
7246ahc_update_scsiid(struct ahc_softc *ahc, u_int targid_mask)
7247{
7248 u_int scsiid_mask;
7249 u_int scsiid;
7250
7251 if ((ahc->features & AHC_MULTI_TID) == 0)
7252 panic("ahc_update_scsiid called on non-multitid unit\n");
7253
7254 /*
7255 * Since we will rely on the TARGID mask
7256 * for selection enables, ensure that OID
7257 * in SCSIID is not set to some other ID
7258 * that we don't want to allow selections on.
7259 */
7260 if ((ahc->features & AHC_ULTRA2) != 0)
7261 scsiid = ahc_inb(ahc, SCSIID_ULTRA2);
7262 else
7263 scsiid = ahc_inb(ahc, SCSIID);
7264 scsiid_mask = 0x1 << (scsiid & OID);
7265 if ((targid_mask & scsiid_mask) == 0) {
7266 u_int our_id;
7267
7268 /* ffs counts from 1 */
7269 our_id = ffs(targid_mask);
7270 if (our_id == 0)
7271 our_id = ahc->our_id;
7272 else
7273 our_id--;
7274 scsiid &= TID;
7275 scsiid |= our_id;
7276 }
7277 if ((ahc->features & AHC_ULTRA2) != 0)
7278 ahc_outb(ahc, SCSIID_ULTRA2, scsiid);
7279 else
7280 ahc_outb(ahc, SCSIID, scsiid);
7281}
7282
7283void
7284ahc_run_tqinfifo(struct ahc_softc *ahc, int paused)
7285{
7286 struct target_cmd *cmd;
7287
7288 /*
7289 * If the card supports auto-access pause,
7290 * we can access the card directly regardless
7291 * of whether it is paused or not.
7292 */
7293 if ((ahc->features & AHC_AUTOPAUSE) != 0)
7294 paused = TRUE;
7295
7296 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_POSTREAD);
7297 while ((cmd = &ahc->targetcmds[ahc->tqinfifonext])->cmd_valid != 0) {
7298
7299 /*
7300 * Only advance through the queue if we
7301 * have the resources to process the command.
7302 */
7303 if (ahc_handle_target_cmd(ahc, cmd) != 0)
7304 break;
7305
7306 cmd->cmd_valid = 0;
7307 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
7308 ahc->shared_data_dmamap,
7309 ahc_targetcmd_offset(ahc, ahc->tqinfifonext),
7310 sizeof(struct target_cmd),
7311 BUS_DMASYNC_PREREAD);
7312 ahc->tqinfifonext++;
7313
7314 /*
7315 * Lazily update our position in the target mode incoming
7316 * command queue as seen by the sequencer.
7317 */
7318 if ((ahc->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
7319 if ((ahc->features & AHC_HS_MAILBOX) != 0) {
7320 u_int hs_mailbox;
7321
7322 hs_mailbox = ahc_inb(ahc, HS_MAILBOX);
7323 hs_mailbox &= ~HOST_TQINPOS;
7324 hs_mailbox |= ahc->tqinfifonext & HOST_TQINPOS;
7325 ahc_outb(ahc, HS_MAILBOX, hs_mailbox);
7326 } else {
7327 if (!paused)
7328 ahc_pause(ahc);
7329 ahc_outb(ahc, KERNEL_TQINPOS,
7330 ahc->tqinfifonext & HOST_TQINPOS);
7331 if (!paused)
7332 ahc_unpause(ahc);
7333 }
7334 }
7335 }
7336}
7337
7338static int
7339ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
7340{
7341 struct ahc_tmode_tstate *tstate;
7342 struct ahc_tmode_lstate *lstate;
7343 struct ccb_accept_tio *atio;
7344 uint8_t *byte;
7345 int initiator;
7346 int target;
7347 int lun;
7348
7349 initiator = SCSIID_TARGET(ahc, cmd->scsiid);
7350 target = SCSIID_OUR_ID(cmd->scsiid);
7351 lun = (cmd->identify & MSG_IDENTIFY_LUNMASK);
7352
7353 byte = cmd->bytes;
7354 tstate = ahc->enabled_targets[target];
7355 lstate = NULL;
7356 if (tstate != NULL)
7357 lstate = tstate->enabled_luns[lun];
7358
7359 /*
7360 * Commands for disabled luns go to the black hole driver.
7361 */
7362 if (lstate == NULL)
7363 lstate = ahc->black_hole;
7364
7365 atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
7366 if (atio == NULL) {
7367 ahc->flags |= AHC_TQINFIFO_BLOCKED;
7368 /*
7369 * Wait for more ATIOs from the peripheral driver for this lun.
7370 */
7371 if (bootverbose)
7372 printf("%s: ATIOs exhausted\n", ahc_name(ahc));
7373 return (1);
7374 } else
7375 ahc->flags &= ~AHC_TQINFIFO_BLOCKED;
7376#if 0
7377 printf("Incoming command from %d for %d:%d%s\n",
7378 initiator, target, lun,
7379 lstate == ahc->black_hole ? "(Black Holed)" : "");
7380#endif
7381 SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
7382
7383 if (lstate == ahc->black_hole) {
7384 /* Fill in the wildcards */
7385 atio->ccb_h.target_id = target;
7386 atio->ccb_h.target_lun = lun;
7387 }
7388
7389 /*
7390 * Package it up and send it off to
7391 * whomever has this lun enabled.
7392 */
7393 atio->sense_len = 0;
7394 atio->init_id = initiator;
7395 if (byte[0] != 0xFF) {
7396 /* Tag was included */
7397 atio->tag_action = *byte++;
7398 atio->tag_id = *byte++;
7399 atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
7400 } else {
7401 atio->ccb_h.flags = 0;
7402 }
7403 byte++;
7404
7405 /* Okay. Now determine the cdb size based on the command code */
7406 switch (*byte >> CMD_GROUP_CODE_SHIFT) {
7407 case 0:
7408 atio->cdb_len = 6;
7409 break;
7410 case 1:
7411 case 2:
7412 atio->cdb_len = 10;
7413 break;
7414 case 4:
7415 atio->cdb_len = 16;
7416 break;
7417 case 5:
7418 atio->cdb_len = 12;
7419 break;
7420 case 3:
7421 default:
7422 /* Only copy the opcode. */
7423 atio->cdb_len = 1;
7424 printf("Reserved or VU command code type encountered\n");
7425 break;
7426 }
7427
7428 memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
7429
7430 atio->ccb_h.status |= CAM_CDB_RECVD;
7431
7432 if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
7433 /*
7434 * We weren't allowed to disconnect.
7435 * We're hanging on the bus until a
7436 * continue target I/O comes in response
7437 * to this accept tio.
7438 */
7439#if 0
7440 printf("Received Immediate Command %d:%d:%d - %p\n",
7441 initiator, target, lun, ahc->pending_device);
7442#endif
7443 ahc->pending_device = lstate;
7444 ahc_freeze_ccb((union ccb *)atio);
7445 atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
7446 }
7447 xpt_done((union ccb*)atio);
7448 return (0);
7449}
7450
7451#endif
diff --git a/drivers/scsi/aic7xxx/aic7xxx_inline.h b/drivers/scsi/aic7xxx/aic7xxx_inline.h
new file mode 100644
index 000000000000..2cc8a17ed8b4
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_inline.h
@@ -0,0 +1,649 @@
1/*
2 * Inline routines shareable across OS platforms.
3 *
4 * Copyright (c) 1994-2001 Justin T. Gibbs.
5 * Copyright (c) 2000-2001 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#43 $
41 *
42 * $FreeBSD$
43 */
44
45#ifndef _AIC7XXX_INLINE_H_
46#define _AIC7XXX_INLINE_H_
47
48/************************* Sequencer Execution Control ************************/
49static __inline void ahc_pause_bug_fix(struct ahc_softc *ahc);
50static __inline int ahc_is_paused(struct ahc_softc *ahc);
51static __inline void ahc_pause(struct ahc_softc *ahc);
52static __inline void ahc_unpause(struct ahc_softc *ahc);
53
54/*
55 * Work around any chip bugs related to halting sequencer execution.
56 * On Ultra2 controllers, we must clear the CIOBUS stretch signal by
57 * reading a register that will set this signal and deassert it.
58 * Without this workaround, if the chip is paused, by an interrupt or
59 * manual pause while accessing scb ram, accesses to certain registers
60 * will hang the system (infinite pci retries).
61 */
62static __inline void
63ahc_pause_bug_fix(struct ahc_softc *ahc)
64{
65 if ((ahc->features & AHC_ULTRA2) != 0)
66 (void)ahc_inb(ahc, CCSCBCTL);
67}
68
69/*
70 * Determine whether the sequencer has halted code execution.
71 * Returns non-zero status if the sequencer is stopped.
72 */
73static __inline int
74ahc_is_paused(struct ahc_softc *ahc)
75{
76 return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);
77}
78
79/*
80 * Request that the sequencer stop and wait, indefinitely, for it
81 * to stop. The sequencer will only acknowledge that it is paused
82 * once it has reached an instruction boundary and PAUSEDIS is
83 * cleared in the SEQCTL register. The sequencer may use PAUSEDIS
84 * for critical sections.
85 */
86static __inline void
87ahc_pause(struct ahc_softc *ahc)
88{
89 ahc_outb(ahc, HCNTRL, ahc->pause);
90
91 /*
92 * Since the sequencer can disable pausing in a critical section, we
93 * must loop until it actually stops.
94 */
95 while (ahc_is_paused(ahc) == 0)
96 ;
97
98 ahc_pause_bug_fix(ahc);
99}
100
101/*
102 * Allow the sequencer to continue program execution.
103 * We check here to ensure that no additional interrupt
104 * sources that would cause the sequencer to halt have been
105 * asserted. If, for example, a SCSI bus reset is detected
106 * while we are fielding a different, pausing, interrupt type,
107 * we don't want to release the sequencer before going back
108 * into our interrupt handler and dealing with this new
109 * condition.
110 */
111static __inline void
112ahc_unpause(struct ahc_softc *ahc)
113{
114 if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)
115 ahc_outb(ahc, HCNTRL, ahc->unpause);
116}
117
118/*********************** Untagged Transaction Routines ************************/
119static __inline void ahc_freeze_untagged_queues(struct ahc_softc *ahc);
120static __inline void ahc_release_untagged_queues(struct ahc_softc *ahc);
121
122/*
123 * Block our completion routine from starting the next untagged
124 * transaction for this target or target lun.
125 */
126static __inline void
127ahc_freeze_untagged_queues(struct ahc_softc *ahc)
128{
129 if ((ahc->flags & AHC_SCB_BTT) == 0)
130 ahc->untagged_queue_lock++;
131}
132
133/*
134 * Allow the next untagged transaction for this target or target lun
135 * to be executed. We use a counting semaphore to allow the lock
136 * to be acquired recursively. Once the count drops to zero, the
137 * transaction queues will be run.
138 */
139static __inline void
140ahc_release_untagged_queues(struct ahc_softc *ahc)
141{
142 if ((ahc->flags & AHC_SCB_BTT) == 0) {
143 ahc->untagged_queue_lock--;
144 if (ahc->untagged_queue_lock == 0)
145 ahc_run_untagged_queues(ahc);
146 }
147}
148
149/************************** Memory mapping routines ***************************/
150static __inline struct ahc_dma_seg *
151 ahc_sg_bus_to_virt(struct scb *scb,
152 uint32_t sg_busaddr);
153static __inline uint32_t
154 ahc_sg_virt_to_bus(struct scb *scb,
155 struct ahc_dma_seg *sg);
156static __inline uint32_t
157 ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index);
158static __inline void ahc_sync_scb(struct ahc_softc *ahc,
159 struct scb *scb, int op);
160static __inline void ahc_sync_sglist(struct ahc_softc *ahc,
161 struct scb *scb, int op);
162static __inline uint32_t
163 ahc_targetcmd_offset(struct ahc_softc *ahc,
164 u_int index);
165
166static __inline struct ahc_dma_seg *
167ahc_sg_bus_to_virt(struct scb *scb, uint32_t sg_busaddr)
168{
169 int sg_index;
170
171 sg_index = (sg_busaddr - scb->sg_list_phys)/sizeof(struct ahc_dma_seg);
172 /* sg_list_phys points to entry 1, not 0 */
173 sg_index++;
174
175 return (&scb->sg_list[sg_index]);
176}
177
178static __inline uint32_t
179ahc_sg_virt_to_bus(struct scb *scb, struct ahc_dma_seg *sg)
180{
181 int sg_index;
182
183 /* sg_list_phys points to entry 1, not 0 */
184 sg_index = sg - &scb->sg_list[1];
185
186 return (scb->sg_list_phys + (sg_index * sizeof(*scb->sg_list)));
187}
188
189static __inline uint32_t
190ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index)
191{
192 return (ahc->scb_data->hscb_busaddr
193 + (sizeof(struct hardware_scb) * index));
194}
195
196static __inline void
197ahc_sync_scb(struct ahc_softc *ahc, struct scb *scb, int op)
198{
199 ahc_dmamap_sync(ahc, ahc->scb_data->hscb_dmat,
200 ahc->scb_data->hscb_dmamap,
201 /*offset*/(scb->hscb - ahc->hscbs) * sizeof(*scb->hscb),
202 /*len*/sizeof(*scb->hscb), op);
203}
204
205static __inline void
206ahc_sync_sglist(struct ahc_softc *ahc, struct scb *scb, int op)
207{
208 if (scb->sg_count == 0)
209 return;
210
211 ahc_dmamap_sync(ahc, ahc->scb_data->sg_dmat, scb->sg_map->sg_dmamap,
212 /*offset*/(scb->sg_list - scb->sg_map->sg_vaddr)
213 * sizeof(struct ahc_dma_seg),
214 /*len*/sizeof(struct ahc_dma_seg) * scb->sg_count, op);
215}
216
217static __inline uint32_t
218ahc_targetcmd_offset(struct ahc_softc *ahc, u_int index)
219{
220 return (((uint8_t *)&ahc->targetcmds[index]) - ahc->qoutfifo);
221}
222
223/******************************** Debugging ***********************************/
224static __inline char *ahc_name(struct ahc_softc *ahc);
225
226static __inline char *
227ahc_name(struct ahc_softc *ahc)
228{
229 return (ahc->name);
230}
231
232/*********************** Miscelaneous Support Functions ***********************/
233
234static __inline void ahc_update_residual(struct ahc_softc *ahc,
235 struct scb *scb);
236static __inline struct ahc_initiator_tinfo *
237 ahc_fetch_transinfo(struct ahc_softc *ahc,
238 char channel, u_int our_id,
239 u_int remote_id,
240 struct ahc_tmode_tstate **tstate);
241static __inline uint16_t
242 ahc_inw(struct ahc_softc *ahc, u_int port);
243static __inline void ahc_outw(struct ahc_softc *ahc, u_int port,
244 u_int value);
245static __inline uint32_t
246 ahc_inl(struct ahc_softc *ahc, u_int port);
247static __inline void ahc_outl(struct ahc_softc *ahc, u_int port,
248 uint32_t value);
249static __inline uint64_t
250 ahc_inq(struct ahc_softc *ahc, u_int port);
251static __inline void ahc_outq(struct ahc_softc *ahc, u_int port,
252 uint64_t value);
253static __inline struct scb*
254 ahc_get_scb(struct ahc_softc *ahc);
255static __inline void ahc_free_scb(struct ahc_softc *ahc, struct scb *scb);
256static __inline void ahc_swap_with_next_hscb(struct ahc_softc *ahc,
257 struct scb *scb);
258static __inline void ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb);
259static __inline struct scsi_sense_data *
260 ahc_get_sense_buf(struct ahc_softc *ahc,
261 struct scb *scb);
262static __inline uint32_t
263 ahc_get_sense_bufaddr(struct ahc_softc *ahc,
264 struct scb *scb);
265
266/*
267 * Determine whether the sequencer reported a residual
268 * for this SCB/transaction.
269 */
270static __inline void
271ahc_update_residual(struct ahc_softc *ahc, struct scb *scb)
272{
273 uint32_t sgptr;
274
275 sgptr = ahc_le32toh(scb->hscb->sgptr);
276 if ((sgptr & SG_RESID_VALID) != 0)
277 ahc_calc_residual(ahc, scb);
278}
279
280/*
281 * Return pointers to the transfer negotiation information
282 * for the specified our_id/remote_id pair.
283 */
284static __inline struct ahc_initiator_tinfo *
285ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id,
286 u_int remote_id, struct ahc_tmode_tstate **tstate)
287{
288 /*
289 * Transfer data structures are stored from the perspective
290 * of the target role. Since the parameters for a connection
291 * in the initiator role to a given target are the same as
292 * when the roles are reversed, we pretend we are the target.
293 */
294 if (channel == 'B')
295 our_id += 8;
296 *tstate = ahc->enabled_targets[our_id];
297 return (&(*tstate)->transinfo[remote_id]);
298}
299
300static __inline uint16_t
301ahc_inw(struct ahc_softc *ahc, u_int port)
302{
303 return ((ahc_inb(ahc, port+1) << 8) | ahc_inb(ahc, port));
304}
305
306static __inline void
307ahc_outw(struct ahc_softc *ahc, u_int port, u_int value)
308{
309 ahc_outb(ahc, port, value & 0xFF);
310 ahc_outb(ahc, port+1, (value >> 8) & 0xFF);
311}
312
313static __inline uint32_t
314ahc_inl(struct ahc_softc *ahc, u_int port)
315{
316 return ((ahc_inb(ahc, port))
317 | (ahc_inb(ahc, port+1) << 8)
318 | (ahc_inb(ahc, port+2) << 16)
319 | (ahc_inb(ahc, port+3) << 24));
320}
321
322static __inline void
323ahc_outl(struct ahc_softc *ahc, u_int port, uint32_t value)
324{
325 ahc_outb(ahc, port, (value) & 0xFF);
326 ahc_outb(ahc, port+1, ((value) >> 8) & 0xFF);
327 ahc_outb(ahc, port+2, ((value) >> 16) & 0xFF);
328 ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF);
329}
330
331static __inline uint64_t
332ahc_inq(struct ahc_softc *ahc, u_int port)
333{
334 return ((ahc_inb(ahc, port))
335 | (ahc_inb(ahc, port+1) << 8)
336 | (ahc_inb(ahc, port+2) << 16)
337 | (ahc_inb(ahc, port+3) << 24)
338 | (((uint64_t)ahc_inb(ahc, port+4)) << 32)
339 | (((uint64_t)ahc_inb(ahc, port+5)) << 40)
340 | (((uint64_t)ahc_inb(ahc, port+6)) << 48)
341 | (((uint64_t)ahc_inb(ahc, port+7)) << 56));
342}
343
344static __inline void
345ahc_outq(struct ahc_softc *ahc, u_int port, uint64_t value)
346{
347 ahc_outb(ahc, port, value & 0xFF);
348 ahc_outb(ahc, port+1, (value >> 8) & 0xFF);
349 ahc_outb(ahc, port+2, (value >> 16) & 0xFF);
350 ahc_outb(ahc, port+3, (value >> 24) & 0xFF);
351 ahc_outb(ahc, port+4, (value >> 32) & 0xFF);
352 ahc_outb(ahc, port+5, (value >> 40) & 0xFF);
353 ahc_outb(ahc, port+6, (value >> 48) & 0xFF);
354 ahc_outb(ahc, port+7, (value >> 56) & 0xFF);
355}
356
357/*
358 * Get a free scb. If there are none, see if we can allocate a new SCB.
359 */
360static __inline struct scb *
361ahc_get_scb(struct ahc_softc *ahc)
362{
363 struct scb *scb;
364
365 if ((scb = SLIST_FIRST(&ahc->scb_data->free_scbs)) == NULL) {
366 ahc_alloc_scbs(ahc);
367 scb = SLIST_FIRST(&ahc->scb_data->free_scbs);
368 if (scb == NULL)
369 return (NULL);
370 }
371 SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links.sle);
372 return (scb);
373}
374
375/*
376 * Return an SCB resource to the free list.
377 */
378static __inline void
379ahc_free_scb(struct ahc_softc *ahc, struct scb *scb)
380{
381 struct hardware_scb *hscb;
382
383 hscb = scb->hscb;
384 /* Clean up for the next user */
385 ahc->scb_data->scbindex[hscb->tag] = NULL;
386 scb->flags = SCB_FREE;
387 hscb->control = 0;
388
389 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle);
390
391 /* Notify the OSM that a resource is now available. */
392 ahc_platform_scb_free(ahc, scb);
393}
394
395static __inline struct scb *
396ahc_lookup_scb(struct ahc_softc *ahc, u_int tag)
397{
398 struct scb* scb;
399
400 scb = ahc->scb_data->scbindex[tag];
401 if (scb != NULL)
402 ahc_sync_scb(ahc, scb,
403 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
404 return (scb);
405}
406
407static __inline void
408ahc_swap_with_next_hscb(struct ahc_softc *ahc, struct scb *scb)
409{
410 struct hardware_scb *q_hscb;
411 u_int saved_tag;
412
413 /*
414 * Our queuing method is a bit tricky. The card
415 * knows in advance which HSCB to download, and we
416 * can't disappoint it. To achieve this, the next
417 * SCB to download is saved off in ahc->next_queued_scb.
418 * When we are called to queue "an arbitrary scb",
419 * we copy the contents of the incoming HSCB to the one
420 * the sequencer knows about, swap HSCB pointers and
421 * finally assign the SCB to the tag indexed location
422 * in the scb_array. This makes sure that we can still
423 * locate the correct SCB by SCB_TAG.
424 */
425 q_hscb = ahc->next_queued_scb->hscb;
426 saved_tag = q_hscb->tag;
427 memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
428 if ((scb->flags & SCB_CDB32_PTR) != 0) {
429 q_hscb->shared_data.cdb_ptr =
430 ahc_htole32(ahc_hscb_busaddr(ahc, q_hscb->tag)
431 + offsetof(struct hardware_scb, cdb32));
432 }
433 q_hscb->tag = saved_tag;
434 q_hscb->next = scb->hscb->tag;
435
436 /* Now swap HSCB pointers. */
437 ahc->next_queued_scb->hscb = scb->hscb;
438 scb->hscb = q_hscb;
439
440 /* Now define the mapping from tag to SCB in the scbindex */
441 ahc->scb_data->scbindex[scb->hscb->tag] = scb;
442}
443
444/*
445 * Tell the sequencer about a new transaction to execute.
446 */
447static __inline void
448ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb)
449{
450 ahc_swap_with_next_hscb(ahc, scb);
451
452 if (scb->hscb->tag == SCB_LIST_NULL
453 || scb->hscb->next == SCB_LIST_NULL)
454 panic("Attempt to queue invalid SCB tag %x:%x\n",
455 scb->hscb->tag, scb->hscb->next);
456
457 /*
458 * Setup data "oddness".
459 */
460 scb->hscb->lun &= LID;
461 if (ahc_get_transfer_length(scb) & 0x1)
462 scb->hscb->lun |= SCB_XFERLEN_ODD;
463
464 /*
465 * Keep a history of SCBs we've downloaded in the qinfifo.
466 */
467 ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
468
469 /*
470 * Make sure our data is consistent from the
471 * perspective of the adapter.
472 */
473 ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
474
475 /* Tell the adapter about the newly queued SCB */
476 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
477 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
478 } else {
479 if ((ahc->features & AHC_AUTOPAUSE) == 0)
480 ahc_pause(ahc);
481 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
482 if ((ahc->features & AHC_AUTOPAUSE) == 0)
483 ahc_unpause(ahc);
484 }
485}
486
487static __inline struct scsi_sense_data *
488ahc_get_sense_buf(struct ahc_softc *ahc, struct scb *scb)
489{
490 int offset;
491
492 offset = scb - ahc->scb_data->scbarray;
493 return (&ahc->scb_data->sense[offset]);
494}
495
496static __inline uint32_t
497ahc_get_sense_bufaddr(struct ahc_softc *ahc, struct scb *scb)
498{
499 int offset;
500
501 offset = scb - ahc->scb_data->scbarray;
502 return (ahc->scb_data->sense_busaddr
503 + (offset * sizeof(struct scsi_sense_data)));
504}
505
506/************************** Interrupt Processing ******************************/
507static __inline void ahc_sync_qoutfifo(struct ahc_softc *ahc, int op);
508static __inline void ahc_sync_tqinfifo(struct ahc_softc *ahc, int op);
509static __inline u_int ahc_check_cmdcmpltqueues(struct ahc_softc *ahc);
510static __inline int ahc_intr(struct ahc_softc *ahc);
511
512static __inline void
513ahc_sync_qoutfifo(struct ahc_softc *ahc, int op)
514{
515 ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
516 /*offset*/0, /*len*/256, op);
517}
518
519static __inline void
520ahc_sync_tqinfifo(struct ahc_softc *ahc, int op)
521{
522#ifdef AHC_TARGET_MODE
523 if ((ahc->flags & AHC_TARGETROLE) != 0) {
524 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
525 ahc->shared_data_dmamap,
526 ahc_targetcmd_offset(ahc, 0),
527 sizeof(struct target_cmd) * AHC_TMODE_CMDS,
528 op);
529 }
530#endif
531}
532
533/*
534 * See if the firmware has posted any completed commands
535 * into our in-core command complete fifos.
536 */
537#define AHC_RUN_QOUTFIFO 0x1
538#define AHC_RUN_TQINFIFO 0x2
539static __inline u_int
540ahc_check_cmdcmpltqueues(struct ahc_softc *ahc)
541{
542 u_int retval;
543
544 retval = 0;
545 ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
546 /*offset*/ahc->qoutfifonext, /*len*/1,
547 BUS_DMASYNC_POSTREAD);
548 if (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL)
549 retval |= AHC_RUN_QOUTFIFO;
550#ifdef AHC_TARGET_MODE
551 if ((ahc->flags & AHC_TARGETROLE) != 0
552 && (ahc->flags & AHC_TQINFIFO_BLOCKED) == 0) {
553 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
554 ahc->shared_data_dmamap,
555 ahc_targetcmd_offset(ahc, ahc->tqinfifofnext),
556 /*len*/sizeof(struct target_cmd),
557 BUS_DMASYNC_POSTREAD);
558 if (ahc->targetcmds[ahc->tqinfifonext].cmd_valid != 0)
559 retval |= AHC_RUN_TQINFIFO;
560 }
561#endif
562 return (retval);
563}
564
565/*
566 * Catch an interrupt from the adapter
567 */
568static __inline int
569ahc_intr(struct ahc_softc *ahc)
570{
571 u_int intstat;
572
573 if ((ahc->pause & INTEN) == 0) {
574 /*
575 * Our interrupt is not enabled on the chip
576 * and may be disabled for re-entrancy reasons,
577 * so just return. This is likely just a shared
578 * interrupt.
579 */
580 return (0);
581 }
582 /*
583 * Instead of directly reading the interrupt status register,
584 * infer the cause of the interrupt by checking our in-core
585 * completion queues. This avoids a costly PCI bus read in
586 * most cases.
587 */
588 if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0
589 && (ahc_check_cmdcmpltqueues(ahc) != 0))
590 intstat = CMDCMPLT;
591 else {
592 intstat = ahc_inb(ahc, INTSTAT);
593 }
594
595 if ((intstat & INT_PEND) == 0) {
596#if AHC_PCI_CONFIG > 0
597 if (ahc->unsolicited_ints > 500) {
598 ahc->unsolicited_ints = 0;
599 if ((ahc->chip & AHC_PCI) != 0
600 && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0)
601 ahc->bus_intr(ahc);
602 }
603#endif
604 ahc->unsolicited_ints++;
605 return (0);
606 }
607 ahc->unsolicited_ints = 0;
608
609 if (intstat & CMDCMPLT) {
610 ahc_outb(ahc, CLRINT, CLRCMDINT);
611
612 /*
613 * Ensure that the chip sees that we've cleared
614 * this interrupt before we walk the output fifo.
615 * Otherwise, we may, due to posted bus writes,
616 * clear the interrupt after we finish the scan,
617 * and after the sequencer has added new entries
618 * and asserted the interrupt again.
619 */
620 ahc_flush_device_writes(ahc);
621 ahc_run_qoutfifo(ahc);
622#ifdef AHC_TARGET_MODE
623 if ((ahc->flags & AHC_TARGETROLE) != 0)
624 ahc_run_tqinfifo(ahc, /*paused*/FALSE);
625#endif
626 }
627
628 /*
629 * Handle statuses that may invalidate our cached
630 * copy of INTSTAT separately.
631 */
632 if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) {
633 /* Hot eject. Do nothing */
634 } else if (intstat & BRKADRINT) {
635 ahc_handle_brkadrint(ahc);
636 } else if ((intstat & (SEQINT|SCSIINT)) != 0) {
637
638 ahc_pause_bug_fix(ahc);
639
640 if ((intstat & SEQINT) != 0)
641 ahc_handle_seqint(ahc, intstat);
642
643 if ((intstat & SCSIINT) != 0)
644 ahc_handle_scsiint(ahc, intstat);
645 }
646 return (1);
647}
648
649#endif /* _AIC7XXX_INLINE_H_ */
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
new file mode 100644
index 000000000000..031c6aaa5ca5
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -0,0 +1,5043 @@
1/*
2 * Adaptec AIC7xxx device driver for Linux.
3 *
4 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#235 $
5 *
6 * Copyright (c) 1994 John Aycock
7 * The University of Calgary Department of Computer Science.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; see the file COPYING. If not, write to
21 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F
24 * driver (ultrastor.c), various Linux kernel source, the Adaptec EISA
25 * config file (!adp7771.cfg), the Adaptec AHA-2740A Series User's Guide,
26 * the Linux Kernel Hacker's Guide, Writing a SCSI Device Driver for Linux,
27 * the Adaptec 1542 driver (aha1542.c), the Adaptec EISA overlay file
28 * (adp7770.ovl), the Adaptec AHA-2740 Series Technical Reference Manual,
29 * the Adaptec AIC-7770 Data Book, the ANSI SCSI specification, the
30 * ANSI SCSI-2 specification (draft 10c), ...
31 *
32 * --------------------------------------------------------------------------
33 *
34 * Modifications by Daniel M. Eischen (deischen@iworks.InterWorks.org):
35 *
36 * Substantially modified to include support for wide and twin bus
37 * adapters, DMAing of SCBs, tagged queueing, IRQ sharing, bug fixes,
38 * SCB paging, and other rework of the code.
39 *
40 * --------------------------------------------------------------------------
41 * Copyright (c) 1994-2000 Justin T. Gibbs.
42 * Copyright (c) 2000-2001 Adaptec Inc.
43 * All rights reserved.
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions, and the following disclaimer,
50 * without modification.
51 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
52 * substantially similar to the "NO WARRANTY" disclaimer below
53 * ("Disclaimer") and any redistribution must be conditioned upon
54 * including a substantially similar Disclaimer requirement for further
55 * binary redistribution.
56 * 3. Neither the names of the above-listed copyright holders nor the names
57 * of any contributors may be used to endorse or promote products derived
58 * from this software without specific prior written permission.
59 *
60 * Alternatively, this software may be distributed under the terms of the
61 * GNU General Public License ("GPL") version 2 as published by the Free
62 * Software Foundation.
63 *
64 * NO WARRANTY
65 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
66 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
67 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
68 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
69 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
70 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
71 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
72 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
73 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
74 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
75 * POSSIBILITY OF SUCH DAMAGES.
76 *
77 *---------------------------------------------------------------------------
78 *
79 * Thanks also go to (in alphabetical order) the following:
80 *
81 * Rory Bolt - Sequencer bug fixes
82 * Jay Estabrook - Initial DEC Alpha support
83 * Doug Ledford - Much needed abort/reset bug fixes
84 * Kai Makisara - DMAing of SCBs
85 *
86 * A Boot time option was also added for not resetting the scsi bus.
87 *
88 * Form: aic7xxx=extended
89 * aic7xxx=no_reset
90 * aic7xxx=verbose
91 *
92 * Daniel M. Eischen, deischen@iworks.InterWorks.org, 1/23/97
93 *
94 * Id: aic7xxx.c,v 4.1 1997/06/12 08:23:42 deang Exp
95 */
96
97/*
98 * Further driver modifications made by Doug Ledford <dledford@redhat.com>
99 *
100 * Copyright (c) 1997-1999 Doug Ledford
101 *
102 * These changes are released under the same licensing terms as the FreeBSD
103 * driver written by Justin Gibbs. Please see his Copyright notice above
104 * for the exact terms and conditions covering my changes as well as the
105 * warranty statement.
106 *
107 * Modifications made to the aic7xxx.c,v 4.1 driver from Dan Eischen include
108 * but are not limited to:
109 *
110 * 1: Import of the latest FreeBSD sequencer code for this driver
111 * 2: Modification of kernel code to accommodate different sequencer semantics
112 * 3: Extensive changes throughout kernel portion of driver to improve
113 * abort/reset processing and error hanndling
114 * 4: Other work contributed by various people on the Internet
115 * 5: Changes to printk information and verbosity selection code
116 * 6: General reliability related changes, especially in IRQ management
117 * 7: Modifications to the default probe/attach order for supported cards
118 * 8: SMP friendliness has been improved
119 *
120 */
121
122#include "aic7xxx_osm.h"
123#include "aic7xxx_inline.h"
124#include <scsi/scsicam.h>
125
126/*
127 * Include aiclib.c as part of our
128 * "module dependencies are hard" work around.
129 */
130#include "aiclib.c"
131
132#include <linux/init.h> /* __setup */
133
134#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
135#include "sd.h" /* For geometry detection */
136#endif
137
138#include <linux/mm.h> /* For fetching system memory size */
139#include <linux/blkdev.h> /* For block_size() */
140#include <linux/delay.h> /* For ssleep/msleep */
141
142/*
143 * Lock protecting manipulation of the ahc softc list.
144 */
145spinlock_t ahc_list_spinlock;
146
147#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
148/* For dynamic sglist size calculation. */
149u_int ahc_linux_nseg;
150#endif
151
152/*
153 * Set this to the delay in seconds after SCSI bus reset.
154 * Note, we honor this only for the initial bus reset.
155 * The scsi error recovery code performs its own bus settle
156 * delay handling for error recovery actions.
157 */
158#ifdef CONFIG_AIC7XXX_RESET_DELAY_MS
159#define AIC7XXX_RESET_DELAY CONFIG_AIC7XXX_RESET_DELAY_MS
160#else
161#define AIC7XXX_RESET_DELAY 5000
162#endif
163
164/*
165 * Control collection of SCSI transfer statistics for the /proc filesystem.
166 *
167 * NOTE: Do NOT enable this when running on kernels version 1.2.x and below.
168 * NOTE: This does affect performance since it has to maintain statistics.
169 */
170#ifdef CONFIG_AIC7XXX_PROC_STATS
171#define AIC7XXX_PROC_STATS
172#endif
173
174/*
175 * To change the default number of tagged transactions allowed per-device,
176 * add a line to the lilo.conf file like:
177 * append="aic7xxx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}"
178 * which will result in the first four devices on the first two
179 * controllers being set to a tagged queue depth of 32.
180 *
181 * The tag_commands is an array of 16 to allow for wide and twin adapters.
182 * Twin adapters will use indexes 0-7 for channel 0, and indexes 8-15
183 * for channel 1.
184 */
185typedef struct {
186 uint8_t tag_commands[16]; /* Allow for wide/twin adapters. */
187} adapter_tag_info_t;
188
189/*
190 * Modify this as you see fit for your system.
191 *
192 * 0 tagged queuing disabled
193 * 1 <= n <= 253 n == max tags ever dispatched.
194 *
195 * The driver will throttle the number of commands dispatched to a
196 * device if it returns queue full. For devices with a fixed maximum
197 * queue depth, the driver will eventually determine this depth and
198 * lock it in (a console message is printed to indicate that a lock
199 * has occurred). On some devices, queue full is returned for a temporary
200 * resource shortage. These devices will return queue full at varying
201 * depths. The driver will throttle back when the queue fulls occur and
202 * attempt to slowly increase the depth over time as the device recovers
203 * from the resource shortage.
204 *
205 * In this example, the first line will disable tagged queueing for all
206 * the devices on the first probed aic7xxx adapter.
207 *
208 * The second line enables tagged queueing with 4 commands/LUN for IDs
209 * (0, 2-11, 13-15), disables tagged queueing for ID 12, and tells the
210 * driver to attempt to use up to 64 tags for ID 1.
211 *
212 * The third line is the same as the first line.
213 *
214 * The fourth line disables tagged queueing for devices 0 and 3. It
215 * enables tagged queueing for the other IDs, with 16 commands/LUN
216 * for IDs 1 and 4, 127 commands/LUN for ID 8, and 4 commands/LUN for
217 * IDs 2, 5-7, and 9-15.
218 */
219
220/*
221 * NOTE: The below structure is for reference only, the actual structure
222 * to modify in order to change things is just below this comment block.
223adapter_tag_info_t aic7xxx_tag_info[] =
224{
225 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
226 {{4, 64, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4}},
227 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
228 {{0, 16, 4, 0, 16, 4, 4, 4, 127, 4, 4, 4, 4, 4, 4, 4}}
229};
230*/
231
232#ifdef CONFIG_AIC7XXX_CMDS_PER_DEVICE
233#define AIC7XXX_CMDS_PER_DEVICE CONFIG_AIC7XXX_CMDS_PER_DEVICE
234#else
235#define AIC7XXX_CMDS_PER_DEVICE AHC_MAX_QUEUE
236#endif
237
238#define AIC7XXX_CONFIGED_TAG_COMMANDS { \
239 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
240 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
241 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
242 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
243 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
244 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
245 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
246 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE \
247}
248
249/*
250 * By default, use the number of commands specified by
251 * the users kernel configuration.
252 */
253static adapter_tag_info_t aic7xxx_tag_info[] =
254{
255 {AIC7XXX_CONFIGED_TAG_COMMANDS},
256 {AIC7XXX_CONFIGED_TAG_COMMANDS},
257 {AIC7XXX_CONFIGED_TAG_COMMANDS},
258 {AIC7XXX_CONFIGED_TAG_COMMANDS},
259 {AIC7XXX_CONFIGED_TAG_COMMANDS},
260 {AIC7XXX_CONFIGED_TAG_COMMANDS},
261 {AIC7XXX_CONFIGED_TAG_COMMANDS},
262 {AIC7XXX_CONFIGED_TAG_COMMANDS},
263 {AIC7XXX_CONFIGED_TAG_COMMANDS},
264 {AIC7XXX_CONFIGED_TAG_COMMANDS},
265 {AIC7XXX_CONFIGED_TAG_COMMANDS},
266 {AIC7XXX_CONFIGED_TAG_COMMANDS},
267 {AIC7XXX_CONFIGED_TAG_COMMANDS},
268 {AIC7XXX_CONFIGED_TAG_COMMANDS},
269 {AIC7XXX_CONFIGED_TAG_COMMANDS},
270 {AIC7XXX_CONFIGED_TAG_COMMANDS}
271};
272
273/*
274 * DV option:
275 *
276 * positive value = DV Enabled
277 * zero = DV Disabled
278 * negative value = DV Default for adapter type/seeprom
279 */
280#ifdef CONFIG_AIC7XXX_DV_SETTING
281#define AIC7XXX_CONFIGED_DV CONFIG_AIC7XXX_DV_SETTING
282#else
283#define AIC7XXX_CONFIGED_DV -1
284#endif
285
286static int8_t aic7xxx_dv_settings[] =
287{
288 AIC7XXX_CONFIGED_DV,
289 AIC7XXX_CONFIGED_DV,
290 AIC7XXX_CONFIGED_DV,
291 AIC7XXX_CONFIGED_DV,
292 AIC7XXX_CONFIGED_DV,
293 AIC7XXX_CONFIGED_DV,
294 AIC7XXX_CONFIGED_DV,
295 AIC7XXX_CONFIGED_DV,
296 AIC7XXX_CONFIGED_DV,
297 AIC7XXX_CONFIGED_DV,
298 AIC7XXX_CONFIGED_DV,
299 AIC7XXX_CONFIGED_DV,
300 AIC7XXX_CONFIGED_DV,
301 AIC7XXX_CONFIGED_DV,
302 AIC7XXX_CONFIGED_DV,
303 AIC7XXX_CONFIGED_DV
304};
305
306/*
307 * There should be a specific return value for this in scsi.h, but
308 * it seems that most drivers ignore it.
309 */
310#define DID_UNDERFLOW DID_ERROR
311
312void
313ahc_print_path(struct ahc_softc *ahc, struct scb *scb)
314{
315 printk("(scsi%d:%c:%d:%d): ",
316 ahc->platform_data->host->host_no,
317 scb != NULL ? SCB_GET_CHANNEL(ahc, scb) : 'X',
318 scb != NULL ? SCB_GET_TARGET(ahc, scb) : -1,
319 scb != NULL ? SCB_GET_LUN(scb) : -1);
320}
321
322/*
323 * XXX - these options apply unilaterally to _all_ 274x/284x/294x
324 * cards in the system. This should be fixed. Exceptions to this
325 * rule are noted in the comments.
326 */
327
328/*
329 * Skip the scsi bus reset. Non 0 make us skip the reset at startup. This
330 * has no effect on any later resets that might occur due to things like
331 * SCSI bus timeouts.
332 */
333static uint32_t aic7xxx_no_reset;
334
335/*
336 * Certain PCI motherboards will scan PCI devices from highest to lowest,
337 * others scan from lowest to highest, and they tend to do all kinds of
338 * strange things when they come into contact with PCI bridge chips. The
339 * net result of all this is that the PCI card that is actually used to boot
340 * the machine is very hard to detect. Most motherboards go from lowest
341 * PCI slot number to highest, and the first SCSI controller found is the
342 * one you boot from. The only exceptions to this are when a controller
343 * has its BIOS disabled. So, we by default sort all of our SCSI controllers
344 * from lowest PCI slot number to highest PCI slot number. We also force
345 * all controllers with their BIOS disabled to the end of the list. This
346 * works on *almost* all computers. Where it doesn't work, we have this
347 * option. Setting this option to non-0 will reverse the order of the sort
348 * to highest first, then lowest, but will still leave cards with their BIOS
349 * disabled at the very end. That should fix everyone up unless there are
350 * really strange cirumstances.
351 */
352static uint32_t aic7xxx_reverse_scan;
353
354/*
355 * Should we force EXTENDED translation on a controller.
356 * 0 == Use whatever is in the SEEPROM or default to off
357 * 1 == Use whatever is in the SEEPROM or default to on
358 */
359static uint32_t aic7xxx_extended;
360
361/*
362 * PCI bus parity checking of the Adaptec controllers. This is somewhat
363 * dubious at best. To my knowledge, this option has never actually
364 * solved a PCI parity problem, but on certain machines with broken PCI
365 * chipset configurations where stray PCI transactions with bad parity are
366 * the norm rather than the exception, the error messages can be overwelming.
367 * It's included in the driver for completeness.
368 * 0 = Shut off PCI parity check
369 * non-0 = reverse polarity pci parity checking
370 */
371static uint32_t aic7xxx_pci_parity = ~0;
372
373/*
374 * Certain newer motherboards have put new PCI based devices into the
375 * IO spaces that used to typically be occupied by VLB or EISA cards.
376 * This overlap can cause these newer motherboards to lock up when scanned
377 * for older EISA and VLB devices. Setting this option to non-0 will
378 * cause the driver to skip scanning for any VLB or EISA controllers and
379 * only support the PCI controllers. NOTE: this means that if the kernel
380 * os compiled with PCI support disabled, then setting this to non-0
381 * would result in never finding any devices :)
382 */
383#ifndef CONFIG_AIC7XXX_PROBE_EISA_VL
384uint32_t aic7xxx_probe_eisa_vl;
385#else
386uint32_t aic7xxx_probe_eisa_vl = ~0;
387#endif
388
389/*
390 * There are lots of broken chipsets in the world. Some of them will
391 * violate the PCI spec when we issue byte sized memory writes to our
392 * controller. I/O mapped register access, if allowed by the given
393 * platform, will work in almost all cases.
394 */
395uint32_t aic7xxx_allow_memio = ~0;
396
397/*
398 * aic7xxx_detect() has been run, so register all device arrivals
399 * immediately with the system rather than deferring to the sorted
400 * attachment performed by aic7xxx_detect().
401 */
402int aic7xxx_detect_complete;
403
404/*
405 * So that we can set how long each device is given as a selection timeout.
406 * The table of values goes like this:
407 * 0 - 256ms
408 * 1 - 128ms
409 * 2 - 64ms
410 * 3 - 32ms
411 * We default to 256ms because some older devices need a longer time
412 * to respond to initial selection.
413 */
414static uint32_t aic7xxx_seltime;
415
416/*
417 * Certain devices do not perform any aging on commands. Should the
418 * device be saturated by commands in one portion of the disk, it is
419 * possible for transactions on far away sectors to never be serviced.
420 * To handle these devices, we can periodically send an ordered tag to
421 * force all outstanding transactions to be serviced prior to a new
422 * transaction.
423 */
424uint32_t aic7xxx_periodic_otag;
425
426/*
427 * Module information and settable options.
428 */
429static char *aic7xxx = NULL;
430
431MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>");
432MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver");
433MODULE_LICENSE("Dual BSD/GPL");
434MODULE_VERSION(AIC7XXX_DRIVER_VERSION);
435module_param(aic7xxx, charp, 0444);
436MODULE_PARM_DESC(aic7xxx,
437"period delimited, options string.\n"
438" verbose Enable verbose/diagnostic logging\n"
439" allow_memio Allow device registers to be memory mapped\n"
440" debug Bitmask of debug values to enable\n"
441" no_probe Toggle EISA/VLB controller probing\n"
442" probe_eisa_vl Toggle EISA/VLB controller probing\n"
443" no_reset Supress initial bus resets\n"
444" extended Enable extended geometry on all controllers\n"
445" periodic_otag Send an ordered tagged transaction\n"
446" periodically to prevent tag starvation.\n"
447" This may be required by some older disk\n"
448" drives or RAID arrays.\n"
449" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n"
450" tag_info:<tag_str> Set per-target tag depth\n"
451" global_tag_depth:<int> Global tag depth for every target\n"
452" on every bus\n"
453" dv:<dv_settings> Set per-controller Domain Validation Setting.\n"
454" seltime:<int> Selection Timeout\n"
455" (0/256ms,1/128ms,2/64ms,3/32ms)\n"
456"\n"
457" Sample /etc/modprobe.conf line:\n"
458" Toggle EISA/VLB probing\n"
459" Set tag depth on Controller 1/Target 1 to 10 tags\n"
460" Shorten the selection timeout to 128ms\n"
461"\n"
462" options aic7xxx 'aic7xxx=probe_eisa_vl.tag_info:{{}.{.10}}.seltime:1'\n"
463);
464
465static void ahc_linux_handle_scsi_status(struct ahc_softc *,
466 struct ahc_linux_device *,
467 struct scb *);
468static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
469 Scsi_Cmnd *cmd);
470static void ahc_linux_filter_inquiry(struct ahc_softc*, struct ahc_devinfo*);
471static void ahc_linux_sem_timeout(u_long arg);
472static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
473static void ahc_linux_release_simq(u_long arg);
474static void ahc_linux_dev_timed_unfreeze(u_long arg);
475static int ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag);
476static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
477static void ahc_linux_size_nseg(void);
478static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc);
479static void ahc_linux_start_dv(struct ahc_softc *ahc);
480static void ahc_linux_dv_timeout(struct scsi_cmnd *cmd);
481static int ahc_linux_dv_thread(void *data);
482static void ahc_linux_kill_dv_thread(struct ahc_softc *ahc);
483static void ahc_linux_dv_target(struct ahc_softc *ahc, u_int target);
484static void ahc_linux_dv_transition(struct ahc_softc *ahc,
485 struct scsi_cmnd *cmd,
486 struct ahc_devinfo *devinfo,
487 struct ahc_linux_target *targ);
488static void ahc_linux_dv_fill_cmd(struct ahc_softc *ahc,
489 struct scsi_cmnd *cmd,
490 struct ahc_devinfo *devinfo);
491static void ahc_linux_dv_inq(struct ahc_softc *ahc,
492 struct scsi_cmnd *cmd,
493 struct ahc_devinfo *devinfo,
494 struct ahc_linux_target *targ,
495 u_int request_length);
496static void ahc_linux_dv_tur(struct ahc_softc *ahc,
497 struct scsi_cmnd *cmd,
498 struct ahc_devinfo *devinfo);
499static void ahc_linux_dv_rebd(struct ahc_softc *ahc,
500 struct scsi_cmnd *cmd,
501 struct ahc_devinfo *devinfo,
502 struct ahc_linux_target *targ);
503static void ahc_linux_dv_web(struct ahc_softc *ahc,
504 struct scsi_cmnd *cmd,
505 struct ahc_devinfo *devinfo,
506 struct ahc_linux_target *targ);
507static void ahc_linux_dv_reb(struct ahc_softc *ahc,
508 struct scsi_cmnd *cmd,
509 struct ahc_devinfo *devinfo,
510 struct ahc_linux_target *targ);
511static void ahc_linux_dv_su(struct ahc_softc *ahc,
512 struct scsi_cmnd *cmd,
513 struct ahc_devinfo *devinfo,
514 struct ahc_linux_target *targ);
515static int ahc_linux_fallback(struct ahc_softc *ahc,
516 struct ahc_devinfo *devinfo);
517static void ahc_linux_dv_complete(Scsi_Cmnd *cmd);
518static void ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ);
519static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
520 struct ahc_devinfo *devinfo);
521static u_int ahc_linux_user_dv_setting(struct ahc_softc *ahc);
522static void ahc_linux_device_queue_depth(struct ahc_softc *ahc,
523 struct ahc_linux_device *dev);
524static struct ahc_linux_target* ahc_linux_alloc_target(struct ahc_softc*,
525 u_int, u_int);
526static void ahc_linux_free_target(struct ahc_softc*,
527 struct ahc_linux_target*);
528static struct ahc_linux_device* ahc_linux_alloc_device(struct ahc_softc*,
529 struct ahc_linux_target*,
530 u_int);
531static void ahc_linux_free_device(struct ahc_softc*,
532 struct ahc_linux_device*);
533static void ahc_linux_run_device_queue(struct ahc_softc*,
534 struct ahc_linux_device*);
535static void ahc_linux_setup_tag_info_global(char *p);
536static aic_option_callback_t ahc_linux_setup_tag_info;
537static aic_option_callback_t ahc_linux_setup_dv;
538static int aic7xxx_setup(char *s);
539static int ahc_linux_next_unit(void);
540static void ahc_runq_tasklet(unsigned long data);
541static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc);
542
543/********************************* Inlines ************************************/
544static __inline void ahc_schedule_runq(struct ahc_softc *ahc);
545static __inline struct ahc_linux_device*
546 ahc_linux_get_device(struct ahc_softc *ahc, u_int channel,
547 u_int target, u_int lun, int alloc);
548static __inline void ahc_schedule_completeq(struct ahc_softc *ahc);
549static __inline void ahc_linux_check_device_queue(struct ahc_softc *ahc,
550 struct ahc_linux_device *dev);
551static __inline struct ahc_linux_device *
552 ahc_linux_next_device_to_run(struct ahc_softc *ahc);
553static __inline void ahc_linux_run_device_queues(struct ahc_softc *ahc);
554static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
555
556static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
557 struct ahc_dma_seg *sg,
558 dma_addr_t addr, bus_size_t len);
559
560static __inline void
561ahc_schedule_completeq(struct ahc_softc *ahc)
562{
563 if ((ahc->platform_data->flags & AHC_RUN_CMPLT_Q_TIMER) == 0) {
564 ahc->platform_data->flags |= AHC_RUN_CMPLT_Q_TIMER;
565 ahc->platform_data->completeq_timer.expires = jiffies;
566 add_timer(&ahc->platform_data->completeq_timer);
567 }
568}
569
570/*
571 * Must be called with our lock held.
572 */
573static __inline void
574ahc_schedule_runq(struct ahc_softc *ahc)
575{
576 tasklet_schedule(&ahc->platform_data->runq_tasklet);
577}
578
579static __inline struct ahc_linux_device*
580ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
581 u_int lun, int alloc)
582{
583 struct ahc_linux_target *targ;
584 struct ahc_linux_device *dev;
585 u_int target_offset;
586
587 target_offset = target;
588 if (channel != 0)
589 target_offset += 8;
590 targ = ahc->platform_data->targets[target_offset];
591 if (targ == NULL) {
592 if (alloc != 0) {
593 targ = ahc_linux_alloc_target(ahc, channel, target);
594 if (targ == NULL)
595 return (NULL);
596 } else
597 return (NULL);
598 }
599 dev = targ->devices[lun];
600 if (dev == NULL && alloc != 0)
601 dev = ahc_linux_alloc_device(ahc, targ, lun);
602 return (dev);
603}
604
605#define AHC_LINUX_MAX_RETURNED_ERRORS 4
606static struct ahc_cmd *
607ahc_linux_run_complete_queue(struct ahc_softc *ahc)
608{
609 struct ahc_cmd *acmd;
610 u_long done_flags;
611 int with_errors;
612
613 with_errors = 0;
614 ahc_done_lock(ahc, &done_flags);
615 while ((acmd = TAILQ_FIRST(&ahc->platform_data->completeq)) != NULL) {
616 Scsi_Cmnd *cmd;
617
618 if (with_errors > AHC_LINUX_MAX_RETURNED_ERRORS) {
619 /*
620 * Linux uses stack recursion to requeue
621 * commands that need to be retried. Avoid
622 * blowing out the stack by "spoon feeding"
623 * commands that completed with error back
624 * the operating system in case they are going
625 * to be retried. "ick"
626 */
627 ahc_schedule_completeq(ahc);
628 break;
629 }
630 TAILQ_REMOVE(&ahc->platform_data->completeq,
631 acmd, acmd_links.tqe);
632 cmd = &acmd_scsi_cmd(acmd);
633 cmd->host_scribble = NULL;
634 if (ahc_cmd_get_transaction_status(cmd) != DID_OK
635 || (cmd->result & 0xFF) != SCSI_STATUS_OK)
636 with_errors++;
637
638 cmd->scsi_done(cmd);
639 }
640 ahc_done_unlock(ahc, &done_flags);
641 return (acmd);
642}
643
644static __inline void
645ahc_linux_check_device_queue(struct ahc_softc *ahc,
646 struct ahc_linux_device *dev)
647{
648 if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) != 0
649 && dev->active == 0) {
650 dev->flags &= ~AHC_DEV_FREEZE_TIL_EMPTY;
651 dev->qfrozen--;
652 }
653
654 if (TAILQ_FIRST(&dev->busyq) == NULL
655 || dev->openings == 0 || dev->qfrozen != 0)
656 return;
657
658 ahc_linux_run_device_queue(ahc, dev);
659}
660
661static __inline struct ahc_linux_device *
662ahc_linux_next_device_to_run(struct ahc_softc *ahc)
663{
664
665 if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0
666 || (ahc->platform_data->qfrozen != 0
667 && AHC_DV_SIMQ_FROZEN(ahc) == 0))
668 return (NULL);
669 return (TAILQ_FIRST(&ahc->platform_data->device_runq));
670}
671
672static __inline void
673ahc_linux_run_device_queues(struct ahc_softc *ahc)
674{
675 struct ahc_linux_device *dev;
676
677 while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) {
678 TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links);
679 dev->flags &= ~AHC_DEV_ON_RUN_LIST;
680 ahc_linux_check_device_queue(ahc, dev);
681 }
682}
683
684static __inline void
685ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
686{
687 Scsi_Cmnd *cmd;
688
689 cmd = scb->io_ctx;
690 ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE);
691 if (cmd->use_sg != 0) {
692 struct scatterlist *sg;
693
694 sg = (struct scatterlist *)cmd->request_buffer;
695 pci_unmap_sg(ahc->dev_softc, sg, cmd->use_sg,
696 scsi_to_pci_dma_dir(cmd->sc_data_direction));
697 } else if (cmd->request_bufflen != 0) {
698 pci_unmap_single(ahc->dev_softc,
699 scb->platform_data->buf_busaddr,
700 cmd->request_bufflen,
701 scsi_to_pci_dma_dir(cmd->sc_data_direction));
702 }
703}
704
705static __inline int
706ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
707 struct ahc_dma_seg *sg, dma_addr_t addr, bus_size_t len)
708{
709 int consumed;
710
711 if ((scb->sg_count + 1) > AHC_NSEG)
712 panic("Too few segs for dma mapping. "
713 "Increase AHC_NSEG\n");
714
715 consumed = 1;
716 sg->addr = ahc_htole32(addr & 0xFFFFFFFF);
717 scb->platform_data->xfer_len += len;
718
719 if (sizeof(dma_addr_t) > 4
720 && (ahc->flags & AHC_39BIT_ADDRESSING) != 0)
721 len |= (addr >> 8) & AHC_SG_HIGH_ADDR_MASK;
722
723 sg->len = ahc_htole32(len);
724 return (consumed);
725}
726
727/************************ Host template entry points *************************/
728static int ahc_linux_detect(Scsi_Host_Template *);
729static int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
730static const char *ahc_linux_info(struct Scsi_Host *);
731#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
732static int ahc_linux_slave_alloc(Scsi_Device *);
733static int ahc_linux_slave_configure(Scsi_Device *);
734static void ahc_linux_slave_destroy(Scsi_Device *);
735#if defined(__i386__)
736static int ahc_linux_biosparam(struct scsi_device*,
737 struct block_device*,
738 sector_t, int[]);
739#endif
740#else
741static int ahc_linux_release(struct Scsi_Host *);
742static void ahc_linux_select_queue_depth(struct Scsi_Host *host,
743 Scsi_Device *scsi_devs);
744#if defined(__i386__)
745static int ahc_linux_biosparam(Disk *, kdev_t, int[]);
746#endif
747#endif
748static int ahc_linux_bus_reset(Scsi_Cmnd *);
749static int ahc_linux_dev_reset(Scsi_Cmnd *);
750static int ahc_linux_abort(Scsi_Cmnd *);
751
752/*
753 * Calculate a safe value for AHC_NSEG (as expressed through ahc_linux_nseg).
754 *
755 * In pre-2.5.X...
756 * The midlayer allocates an S/G array dynamically when a command is issued
757 * using SCSI malloc. This array, which is in an OS dependent format that
758 * must later be copied to our private S/G list, is sized to house just the
759 * number of segments needed for the current transfer. Since the code that
760 * sizes the SCSI malloc pool does not take into consideration fragmentation
761 * of the pool, executing transactions numbering just a fraction of our
762 * concurrent transaction limit with list lengths aproaching AHC_NSEG will
763 * quickly depleat the SCSI malloc pool of usable space. Unfortunately, the
764 * mid-layer does not properly handle this scsi malloc failures for the S/G
765 * array and the result can be a lockup of the I/O subsystem. We try to size
766 * our S/G list so that it satisfies our drivers allocation requirements in
767 * addition to avoiding fragmentation of the SCSI malloc pool.
768 */
769static void
770ahc_linux_size_nseg(void)
771{
772#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
773 u_int cur_size;
774 u_int best_size;
775
776 /*
777 * The SCSI allocator rounds to the nearest 512 bytes
778 * an cannot allocate across a page boundary. Our algorithm
779 * is to start at 1K of scsi malloc space per-command and
780 * loop through all factors of the PAGE_SIZE and pick the best.
781 */
782 best_size = 0;
783 for (cur_size = 1024; cur_size <= PAGE_SIZE; cur_size *= 2) {
784 u_int nseg;
785
786 nseg = cur_size / sizeof(struct scatterlist);
787 if (nseg < AHC_LINUX_MIN_NSEG)
788 continue;
789
790 if (best_size == 0) {
791 best_size = cur_size;
792 ahc_linux_nseg = nseg;
793 } else {
794 u_int best_rem;
795 u_int cur_rem;
796
797 /*
798 * Compare the traits of the current "best_size"
799 * with the current size to determine if the
800 * current size is a better size.
801 */
802 best_rem = best_size % sizeof(struct scatterlist);
803 cur_rem = cur_size % sizeof(struct scatterlist);
804 if (cur_rem < best_rem) {
805 best_size = cur_size;
806 ahc_linux_nseg = nseg;
807 }
808 }
809 }
810#endif
811}
812
813/*
814 * Try to detect an Adaptec 7XXX controller.
815 */
816static int
817ahc_linux_detect(Scsi_Host_Template *template)
818{
819 struct ahc_softc *ahc;
820 int found = 0;
821
822#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
823 /*
824 * It is a bug that the upper layer takes
825 * this lock just prior to calling us.
826 */
827 spin_unlock_irq(&io_request_lock);
828#endif
829
830 /*
831 * Sanity checking of Linux SCSI data structures so
832 * that some of our hacks^H^H^H^H^Hassumptions aren't
833 * violated.
834 */
835 if (offsetof(struct ahc_cmd_internal, end)
836 > offsetof(struct scsi_cmnd, host_scribble)) {
837 printf("ahc_linux_detect: SCSI data structures changed.\n");
838 printf("ahc_linux_detect: Unable to attach\n");
839 return (0);
840 }
841 ahc_linux_size_nseg();
842 /*
843 * If we've been passed any parameters, process them now.
844 */
845 if (aic7xxx)
846 aic7xxx_setup(aic7xxx);
847
848 template->proc_name = "aic7xxx";
849
850 /*
851 * Initialize our softc list lock prior to
852 * probing for any adapters.
853 */
854 ahc_list_lockinit();
855
856 found = ahc_linux_pci_init();
857 if (!ahc_linux_eisa_init())
858 found++;
859
860 /*
861 * Register with the SCSI layer all
862 * controllers we've found.
863 */
864 TAILQ_FOREACH(ahc, &ahc_tailq, links) {
865
866 if (ahc_linux_register_host(ahc, template) == 0)
867 found++;
868 }
869
870#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
871 spin_lock_irq(&io_request_lock);
872#endif
873 aic7xxx_detect_complete++;
874
875 return (found);
876}
877
878#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
879/*
880 * Free the passed in Scsi_Host memory structures prior to unloading the
881 * module.
882 */
883int
884ahc_linux_release(struct Scsi_Host * host)
885{
886 struct ahc_softc *ahc;
887 u_long l;
888
889 ahc_list_lock(&l);
890 if (host != NULL) {
891
892 /*
893 * We should be able to just perform
894 * the free directly, but check our
895 * list for extra sanity.
896 */
897 ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata);
898 if (ahc != NULL) {
899 u_long s;
900
901 ahc_lock(ahc, &s);
902 ahc_intr_enable(ahc, FALSE);
903 ahc_unlock(ahc, &s);
904 ahc_free(ahc);
905 }
906 }
907 ahc_list_unlock(&l);
908 return (0);
909}
910#endif
911
912/*
913 * Return a string describing the driver.
914 */
915static const char *
916ahc_linux_info(struct Scsi_Host *host)
917{
918 static char buffer[512];
919 char ahc_info[256];
920 char *bp;
921 struct ahc_softc *ahc;
922
923 bp = &buffer[0];
924 ahc = *(struct ahc_softc **)host->hostdata;
925 memset(bp, 0, sizeof(buffer));
926 strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev ");
927 strcat(bp, AIC7XXX_DRIVER_VERSION);
928 strcat(bp, "\n");
929 strcat(bp, " <");
930 strcat(bp, ahc->description);
931 strcat(bp, ">\n");
932 strcat(bp, " ");
933 ahc_controller_info(ahc, ahc_info);
934 strcat(bp, ahc_info);
935 strcat(bp, "\n");
936
937 return (bp);
938}
939
940/*
941 * Queue an SCB to the controller.
942 */
943static int
944ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
945{
946 struct ahc_softc *ahc;
947 struct ahc_linux_device *dev;
948 u_long flags;
949
950 ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
951
952 /*
953 * Save the callback on completion function.
954 */
955 cmd->scsi_done = scsi_done;
956
957 ahc_midlayer_entrypoint_lock(ahc, &flags);
958
959 /*
960 * Close the race of a command that was in the process of
961 * being queued to us just as our simq was frozen. Let
962 * DV commands through so long as we are only frozen to
963 * perform DV.
964 */
965 if (ahc->platform_data->qfrozen != 0
966 && AHC_DV_CMD(cmd) == 0) {
967
968 ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
969 ahc_linux_queue_cmd_complete(ahc, cmd);
970 ahc_schedule_completeq(ahc);
971 ahc_midlayer_entrypoint_unlock(ahc, &flags);
972 return (0);
973 }
974 dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
975 cmd->device->lun, /*alloc*/TRUE);
976 if (dev == NULL) {
977 ahc_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
978 ahc_linux_queue_cmd_complete(ahc, cmd);
979 ahc_schedule_completeq(ahc);
980 ahc_midlayer_entrypoint_unlock(ahc, &flags);
981 printf("%s: aic7xxx_linux_queue - Unable to allocate device!\n",
982 ahc_name(ahc));
983 return (0);
984 }
985 cmd->result = CAM_REQ_INPROG << 16;
986 TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe);
987 if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
988 TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
989 dev->flags |= AHC_DEV_ON_RUN_LIST;
990 ahc_linux_run_device_queues(ahc);
991 }
992 ahc_midlayer_entrypoint_unlock(ahc, &flags);
993 return (0);
994}
995
996#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
997static int
998ahc_linux_slave_alloc(Scsi_Device *device)
999{
1000 struct ahc_softc *ahc;
1001
1002 ahc = *((struct ahc_softc **)device->host->hostdata);
1003 if (bootverbose)
1004 printf("%s: Slave Alloc %d\n", ahc_name(ahc), device->id);
1005 return (0);
1006}
1007
1008static int
1009ahc_linux_slave_configure(Scsi_Device *device)
1010{
1011 struct ahc_softc *ahc;
1012 struct ahc_linux_device *dev;
1013 u_long flags;
1014
1015 ahc = *((struct ahc_softc **)device->host->hostdata);
1016 if (bootverbose)
1017 printf("%s: Slave Configure %d\n", ahc_name(ahc), device->id);
1018 ahc_midlayer_entrypoint_lock(ahc, &flags);
1019 /*
1020 * Since Linux has attached to the device, configure
1021 * it so we don't free and allocate the device
1022 * structure on every command.
1023 */
1024 dev = ahc_linux_get_device(ahc, device->channel,
1025 device->id, device->lun,
1026 /*alloc*/TRUE);
1027 if (dev != NULL) {
1028 dev->flags &= ~AHC_DEV_UNCONFIGURED;
1029 dev->scsi_device = device;
1030 ahc_linux_device_queue_depth(ahc, dev);
1031 }
1032 ahc_midlayer_entrypoint_unlock(ahc, &flags);
1033 return (0);
1034}
1035
1036static void
1037ahc_linux_slave_destroy(Scsi_Device *device)
1038{
1039 struct ahc_softc *ahc;
1040 struct ahc_linux_device *dev;
1041 u_long flags;
1042
1043 ahc = *((struct ahc_softc **)device->host->hostdata);
1044 if (bootverbose)
1045 printf("%s: Slave Destroy %d\n", ahc_name(ahc), device->id);
1046 ahc_midlayer_entrypoint_lock(ahc, &flags);
1047 dev = ahc_linux_get_device(ahc, device->channel,
1048 device->id, device->lun,
1049 /*alloc*/FALSE);
1050 /*
1051 * Filter out "silly" deletions of real devices by only
1052 * deleting devices that have had slave_configure()
1053 * called on them. All other devices that have not
1054 * been configured will automatically be deleted by
1055 * the refcounting process.
1056 */
1057 if (dev != NULL
1058 && (dev->flags & AHC_DEV_SLAVE_CONFIGURED) != 0) {
1059 dev->flags |= AHC_DEV_UNCONFIGURED;
1060 if (TAILQ_EMPTY(&dev->busyq)
1061 && dev->active == 0
1062 && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0)
1063 ahc_linux_free_device(ahc, dev);
1064 }
1065 ahc_midlayer_entrypoint_unlock(ahc, &flags);
1066}
1067#else
1068/*
1069 * Sets the queue depth for each SCSI device hanging
1070 * off the input host adapter.
1071 */
1072static void
1073ahc_linux_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs)
1074{
1075 Scsi_Device *device;
1076 Scsi_Device *ldev;
1077 struct ahc_softc *ahc;
1078 u_long flags;
1079
1080 ahc = *((struct ahc_softc **)host->hostdata);
1081 ahc_lock(ahc, &flags);
1082 for (device = scsi_devs; device != NULL; device = device->next) {
1083
1084 /*
1085 * Watch out for duplicate devices. This works around
1086 * some quirks in how the SCSI scanning code does its
1087 * device management.
1088 */
1089 for (ldev = scsi_devs; ldev != device; ldev = ldev->next) {
1090 if (ldev->host == device->host
1091 && ldev->channel == device->channel
1092 && ldev->id == device->id
1093 && ldev->lun == device->lun)
1094 break;
1095 }
1096 /* Skip duplicate. */
1097 if (ldev != device)
1098 continue;
1099
1100 if (device->host == host) {
1101 struct ahc_linux_device *dev;
1102
1103 /*
1104 * Since Linux has attached to the device, configure
1105 * it so we don't free and allocate the device
1106 * structure on every command.
1107 */
1108 dev = ahc_linux_get_device(ahc, device->channel,
1109 device->id, device->lun,
1110 /*alloc*/TRUE);
1111 if (dev != NULL) {
1112 dev->flags &= ~AHC_DEV_UNCONFIGURED;
1113 dev->scsi_device = device;
1114 ahc_linux_device_queue_depth(ahc, dev);
1115 device->queue_depth = dev->openings
1116 + dev->active;
1117 if ((dev->flags & (AHC_DEV_Q_BASIC
1118 | AHC_DEV_Q_TAGGED)) == 0) {
1119 /*
1120 * We allow the OS to queue 2 untagged
1121 * transactions to us at any time even
1122 * though we can only execute them
1123 * serially on the controller/device.
1124 * This should remove some latency.
1125 */
1126 device->queue_depth = 2;
1127 }
1128 }
1129 }
1130 }
1131 ahc_unlock(ahc, &flags);
1132}
1133#endif
1134
1135#if defined(__i386__)
1136/*
1137 * Return the disk geometry for the given SCSI device.
1138 */
1139static int
1140#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1141ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1142 sector_t capacity, int geom[])
1143{
1144 uint8_t *bh;
1145#else
1146ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[])
1147{
1148 struct scsi_device *sdev = disk->device;
1149 u_long capacity = disk->capacity;
1150 struct buffer_head *bh;
1151#endif
1152 int heads;
1153 int sectors;
1154 int cylinders;
1155 int ret;
1156 int extended;
1157 struct ahc_softc *ahc;
1158 u_int channel;
1159
1160 ahc = *((struct ahc_softc **)sdev->host->hostdata);
1161 channel = sdev->channel;
1162
1163#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1164 bh = scsi_bios_ptable(bdev);
1165#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17)
1166 bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev));
1167#else
1168 bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024);
1169#endif
1170
1171 if (bh) {
1172 ret = scsi_partsize(bh, capacity,
1173 &geom[2], &geom[0], &geom[1]);
1174#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1175 kfree(bh);
1176#else
1177 brelse(bh);
1178#endif
1179 if (ret != -1)
1180 return (ret);
1181 }
1182 heads = 64;
1183 sectors = 32;
1184 cylinders = aic_sector_div(capacity, heads, sectors);
1185
1186 if (aic7xxx_extended != 0)
1187 extended = 1;
1188 else if (channel == 0)
1189 extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0;
1190 else
1191 extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0;
1192 if (extended && cylinders >= 1024) {
1193 heads = 255;
1194 sectors = 63;
1195 cylinders = aic_sector_div(capacity, heads, sectors);
1196 }
1197 geom[0] = heads;
1198 geom[1] = sectors;
1199 geom[2] = cylinders;
1200 return (0);
1201}
1202#endif
1203
1204/*
1205 * Abort the current SCSI command(s).
1206 */
1207static int
1208ahc_linux_abort(Scsi_Cmnd *cmd)
1209{
1210 int error;
1211
1212 error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT);
1213 if (error != 0)
1214 printf("aic7xxx_abort returns 0x%x\n", error);
1215 return (error);
1216}
1217
1218/*
1219 * Attempt to send a target reset message to the device that timed out.
1220 */
1221static int
1222ahc_linux_dev_reset(Scsi_Cmnd *cmd)
1223{
1224 int error;
1225
1226 error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
1227 if (error != 0)
1228 printf("aic7xxx_dev_reset returns 0x%x\n", error);
1229 return (error);
1230}
1231
1232/*
1233 * Reset the SCSI bus.
1234 */
1235static int
1236ahc_linux_bus_reset(Scsi_Cmnd *cmd)
1237{
1238 struct ahc_softc *ahc;
1239 u_long s;
1240 int found;
1241
1242 ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
1243 ahc_midlayer_entrypoint_lock(ahc, &s);
1244 found = ahc_reset_channel(ahc, cmd->device->channel + 'A',
1245 /*initiate reset*/TRUE);
1246 ahc_linux_run_complete_queue(ahc);
1247 ahc_midlayer_entrypoint_unlock(ahc, &s);
1248
1249 if (bootverbose)
1250 printf("%s: SCSI bus reset delivered. "
1251 "%d SCBs aborted.\n", ahc_name(ahc), found);
1252
1253 return SUCCESS;
1254}
1255
1256Scsi_Host_Template aic7xxx_driver_template = {
1257 .module = THIS_MODULE,
1258 .name = "aic7xxx",
1259 .proc_info = ahc_linux_proc_info,
1260 .info = ahc_linux_info,
1261 .queuecommand = ahc_linux_queue,
1262 .eh_abort_handler = ahc_linux_abort,
1263 .eh_device_reset_handler = ahc_linux_dev_reset,
1264 .eh_bus_reset_handler = ahc_linux_bus_reset,
1265#if defined(__i386__)
1266 .bios_param = ahc_linux_biosparam,
1267#endif
1268 .can_queue = AHC_MAX_QUEUE,
1269 .this_id = -1,
1270 .cmd_per_lun = 2,
1271 .use_clustering = ENABLE_CLUSTERING,
1272 .slave_alloc = ahc_linux_slave_alloc,
1273 .slave_configure = ahc_linux_slave_configure,
1274 .slave_destroy = ahc_linux_slave_destroy,
1275};
1276
1277/**************************** Tasklet Handler *********************************/
1278
1279/*
1280 * In 2.4.X and above, this routine is called from a tasklet,
1281 * so we must re-acquire our lock prior to executing this code.
1282 * In all prior kernels, ahc_schedule_runq() calls this routine
1283 * directly and ahc_schedule_runq() is called with our lock held.
1284 */
1285static void
1286ahc_runq_tasklet(unsigned long data)
1287{
1288 struct ahc_softc* ahc;
1289 struct ahc_linux_device *dev;
1290 u_long flags;
1291
1292 ahc = (struct ahc_softc *)data;
1293 ahc_lock(ahc, &flags);
1294 while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) {
1295
1296 TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links);
1297 dev->flags &= ~AHC_DEV_ON_RUN_LIST;
1298 ahc_linux_check_device_queue(ahc, dev);
1299 /* Yeild to our interrupt handler */
1300 ahc_unlock(ahc, &flags);
1301 ahc_lock(ahc, &flags);
1302 }
1303 ahc_unlock(ahc, &flags);
1304}
1305
1306/******************************** Macros **************************************/
1307#define BUILD_SCSIID(ahc, cmd) \
1308 ((((cmd)->device->id << TID_SHIFT) & TID) \
1309 | (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
1310 | (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB))
1311
1312/******************************** Bus DMA *************************************/
1313int
1314ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent,
1315 bus_size_t alignment, bus_size_t boundary,
1316 dma_addr_t lowaddr, dma_addr_t highaddr,
1317 bus_dma_filter_t *filter, void *filterarg,
1318 bus_size_t maxsize, int nsegments,
1319 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
1320{
1321 bus_dma_tag_t dmat;
1322
1323 dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT);
1324 if (dmat == NULL)
1325 return (ENOMEM);
1326
1327 /*
1328 * Linux is very simplistic about DMA memory. For now don't
1329 * maintain all specification information. Once Linux supplies
1330 * better facilities for doing these operations, or the
1331 * needs of this particular driver change, we might need to do
1332 * more here.
1333 */
1334 dmat->alignment = alignment;
1335 dmat->boundary = boundary;
1336 dmat->maxsize = maxsize;
1337 *ret_tag = dmat;
1338 return (0);
1339}
1340
1341void
1342ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat)
1343{
1344 free(dmat, M_DEVBUF);
1345}
1346
1347int
1348ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr,
1349 int flags, bus_dmamap_t *mapp)
1350{
1351 bus_dmamap_t map;
1352
1353 map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT);
1354 if (map == NULL)
1355 return (ENOMEM);
1356 /*
1357 * Although we can dma data above 4GB, our
1358 * "consistent" memory is below 4GB for
1359 * space efficiency reasons (only need a 4byte
1360 * address). For this reason, we have to reset
1361 * our dma mask when doing allocations.
1362 */
1363 if (ahc->dev_softc != NULL)
1364 if (pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF)) {
1365 printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
1366 kfree(map);
1367 return (ENODEV);
1368 }
1369 *vaddr = pci_alloc_consistent(ahc->dev_softc,
1370 dmat->maxsize, &map->bus_addr);
1371 if (ahc->dev_softc != NULL)
1372 if (pci_set_dma_mask(ahc->dev_softc,
1373 ahc->platform_data->hw_dma_mask)) {
1374 printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
1375 kfree(map);
1376 return (ENODEV);
1377 }
1378 if (*vaddr == NULL)
1379 return (ENOMEM);
1380 *mapp = map;
1381 return(0);
1382}
1383
1384void
1385ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat,
1386 void* vaddr, bus_dmamap_t map)
1387{
1388 pci_free_consistent(ahc->dev_softc, dmat->maxsize,
1389 vaddr, map->bus_addr);
1390}
1391
1392int
1393ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map,
1394 void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
1395 void *cb_arg, int flags)
1396{
1397 /*
1398 * Assume for now that this will only be used during
1399 * initialization and not for per-transaction buffer mapping.
1400 */
1401 bus_dma_segment_t stack_sg;
1402
1403 stack_sg.ds_addr = map->bus_addr;
1404 stack_sg.ds_len = dmat->maxsize;
1405 cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0);
1406 return (0);
1407}
1408
1409void
1410ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
1411{
1412 /*
1413 * The map may is NULL in our < 2.3.X implementation.
1414 * Now it's 2.6.5, but just in case...
1415 */
1416 BUG_ON(map == NULL);
1417 free(map, M_DEVBUF);
1418}
1419
1420int
1421ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
1422{
1423 /* Nothing to do */
1424 return (0);
1425}
1426
1427/********************* Platform Dependent Functions ***************************/
1428/*
1429 * Compare "left hand" softc with "right hand" softc, returning:
1430 * < 0 - lahc has a lower priority than rahc
1431 * 0 - Softcs are equal
1432 * > 0 - lahc has a higher priority than rahc
1433 */
1434int
1435ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
1436{
1437 int value;
1438 int rvalue;
1439 int lvalue;
1440
1441 /*
1442 * Under Linux, cards are ordered as follows:
1443 * 1) VLB/EISA BIOS enabled devices sorted by BIOS address.
1444 * 2) PCI devices with BIOS enabled sorted by bus/slot/func.
1445 * 3) All remaining VLB/EISA devices sorted by ioport.
1446 * 4) All remaining PCI devices sorted by bus/slot/func.
1447 */
1448 value = (lahc->flags & AHC_BIOS_ENABLED)
1449 - (rahc->flags & AHC_BIOS_ENABLED);
1450 if (value != 0)
1451 /* Controllers with BIOS enabled have a *higher* priority */
1452 return (value);
1453
1454 /*
1455 * Same BIOS setting, now sort based on bus type.
1456 * EISA and VL controllers sort together. EISA/VL
1457 * have higher priority than PCI.
1458 */
1459 rvalue = (rahc->chip & AHC_BUS_MASK);
1460 if (rvalue == AHC_VL)
1461 rvalue = AHC_EISA;
1462 lvalue = (lahc->chip & AHC_BUS_MASK);
1463 if (lvalue == AHC_VL)
1464 lvalue = AHC_EISA;
1465 value = rvalue - lvalue;
1466 if (value != 0)
1467 return (value);
1468
1469 /* Still equal. Sort by BIOS address, ioport, or bus/slot/func. */
1470 switch (rvalue) {
1471#ifdef CONFIG_PCI
1472 case AHC_PCI:
1473 {
1474 char primary_channel;
1475
1476 if (aic7xxx_reverse_scan != 0)
1477 value = ahc_get_pci_bus(lahc->dev_softc)
1478 - ahc_get_pci_bus(rahc->dev_softc);
1479 else
1480 value = ahc_get_pci_bus(rahc->dev_softc)
1481 - ahc_get_pci_bus(lahc->dev_softc);
1482 if (value != 0)
1483 break;
1484 if (aic7xxx_reverse_scan != 0)
1485 value = ahc_get_pci_slot(lahc->dev_softc)
1486 - ahc_get_pci_slot(rahc->dev_softc);
1487 else
1488 value = ahc_get_pci_slot(rahc->dev_softc)
1489 - ahc_get_pci_slot(lahc->dev_softc);
1490 if (value != 0)
1491 break;
1492 /*
1493 * On multi-function devices, the user can choose
1494 * to have function 1 probed before function 0.
1495 * Give whichever channel is the primary channel
1496 * the highest priority.
1497 */
1498 primary_channel = (lahc->flags & AHC_PRIMARY_CHANNEL) + 'A';
1499 value = -1;
1500 if (lahc->channel == primary_channel)
1501 value = 1;
1502 break;
1503 }
1504#endif
1505 case AHC_EISA:
1506 if ((rahc->flags & AHC_BIOS_ENABLED) != 0) {
1507 value = rahc->platform_data->bios_address
1508 - lahc->platform_data->bios_address;
1509 } else {
1510 value = rahc->bsh.ioport
1511 - lahc->bsh.ioport;
1512 }
1513 break;
1514 default:
1515 panic("ahc_softc_sort: invalid bus type");
1516 }
1517 return (value);
1518}
1519
1520static void
1521ahc_linux_setup_tag_info_global(char *p)
1522{
1523 int tags, i, j;
1524
1525 tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
1526 printf("Setting Global Tags= %d\n", tags);
1527
1528 for (i = 0; i < NUM_ELEMENTS(aic7xxx_tag_info); i++) {
1529 for (j = 0; j < AHC_NUM_TARGETS; j++) {
1530 aic7xxx_tag_info[i].tag_commands[j] = tags;
1531 }
1532 }
1533}
1534
1535static void
1536ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
1537{
1538
1539 if ((instance >= 0) && (targ >= 0)
1540 && (instance < NUM_ELEMENTS(aic7xxx_tag_info))
1541 && (targ < AHC_NUM_TARGETS)) {
1542 aic7xxx_tag_info[instance].tag_commands[targ] = value & 0xff;
1543 if (bootverbose)
1544 printf("tag_info[%d:%d] = %d\n", instance, targ, value);
1545 }
1546}
1547
1548static void
1549ahc_linux_setup_dv(u_long arg, int instance, int targ, int32_t value)
1550{
1551
1552 if ((instance >= 0)
1553 && (instance < NUM_ELEMENTS(aic7xxx_dv_settings))) {
1554 aic7xxx_dv_settings[instance] = value;
1555 if (bootverbose)
1556 printf("dv[%d] = %d\n", instance, value);
1557 }
1558}
1559
1560/*
1561 * Handle Linux boot parameters. This routine allows for assigning a value
1562 * to a parameter with a ':' between the parameter and the value.
1563 * ie. aic7xxx=stpwlev:1,extended
1564 */
1565static int
1566aic7xxx_setup(char *s)
1567{
1568 int i, n;
1569 char *p;
1570 char *end;
1571
1572 static struct {
1573 const char *name;
1574 uint32_t *flag;
1575 } options[] = {
1576 { "extended", &aic7xxx_extended },
1577 { "no_reset", &aic7xxx_no_reset },
1578 { "verbose", &aic7xxx_verbose },
1579 { "allow_memio", &aic7xxx_allow_memio},
1580#ifdef AHC_DEBUG
1581 { "debug", &ahc_debug },
1582#endif
1583 { "reverse_scan", &aic7xxx_reverse_scan },
1584 { "no_probe", &aic7xxx_probe_eisa_vl },
1585 { "probe_eisa_vl", &aic7xxx_probe_eisa_vl },
1586 { "periodic_otag", &aic7xxx_periodic_otag },
1587 { "pci_parity", &aic7xxx_pci_parity },
1588 { "seltime", &aic7xxx_seltime },
1589 { "tag_info", NULL },
1590 { "global_tag_depth", NULL },
1591 { "dv", NULL }
1592 };
1593
1594 end = strchr(s, '\0');
1595
1596 /*
1597 * XXX ia64 gcc isn't smart enough to know that NUM_ELEMENTS
1598 * will never be 0 in this case.
1599 */
1600 n = 0;
1601
1602 while ((p = strsep(&s, ",.")) != NULL) {
1603 if (*p == '\0')
1604 continue;
1605 for (i = 0; i < NUM_ELEMENTS(options); i++) {
1606
1607 n = strlen(options[i].name);
1608 if (strncmp(options[i].name, p, n) == 0)
1609 break;
1610 }
1611 if (i == NUM_ELEMENTS(options))
1612 continue;
1613
1614 if (strncmp(p, "global_tag_depth", n) == 0) {
1615 ahc_linux_setup_tag_info_global(p + n);
1616 } else if (strncmp(p, "tag_info", n) == 0) {
1617 s = aic_parse_brace_option("tag_info", p + n, end,
1618 2, ahc_linux_setup_tag_info, 0);
1619 } else if (strncmp(p, "dv", n) == 0) {
1620 s = aic_parse_brace_option("dv", p + n, end, 1,
1621 ahc_linux_setup_dv, 0);
1622 } else if (p[n] == ':') {
1623 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
1624 } else if (strncmp(p, "verbose", n) == 0) {
1625 *(options[i].flag) = 1;
1626 } else {
1627 *(options[i].flag) ^= 0xFFFFFFFF;
1628 }
1629 }
1630 return 1;
1631}
1632
1633__setup("aic7xxx=", aic7xxx_setup);
1634
1635uint32_t aic7xxx_verbose;
1636
1637int
1638ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
1639{
1640 char buf[80];
1641 struct Scsi_Host *host;
1642 char *new_name;
1643 u_long s;
1644 u_int targ_offset;
1645
1646 template->name = ahc->description;
1647 host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
1648 if (host == NULL)
1649 return (ENOMEM);
1650
1651 *((struct ahc_softc **)host->hostdata) = ahc;
1652 ahc_lock(ahc, &s);
1653#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1654 scsi_assign_lock(host, &ahc->platform_data->spin_lock);
1655#elif AHC_SCSI_HAS_HOST_LOCK != 0
1656 host->lock = &ahc->platform_data->spin_lock;
1657#endif
1658 ahc->platform_data->host = host;
1659 host->can_queue = AHC_MAX_QUEUE;
1660 host->cmd_per_lun = 2;
1661 /* XXX No way to communicate the ID for multiple channels */
1662 host->this_id = ahc->our_id;
1663 host->irq = ahc->platform_data->irq;
1664 host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8;
1665 host->max_lun = AHC_NUM_LUNS;
1666 host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
1667 host->sg_tablesize = AHC_NSEG;
1668 ahc_set_unit(ahc, ahc_linux_next_unit());
1669 sprintf(buf, "scsi%d", host->host_no);
1670 new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
1671 if (new_name != NULL) {
1672 strcpy(new_name, buf);
1673 ahc_set_name(ahc, new_name);
1674 }
1675 host->unique_id = ahc->unit;
1676#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1677 scsi_set_pci_device(host, ahc->dev_softc);
1678#endif
1679 ahc_linux_initialize_scsi_bus(ahc);
1680 ahc_unlock(ahc, &s);
1681 ahc->platform_data->dv_pid = kernel_thread(ahc_linux_dv_thread, ahc, 0);
1682 ahc_lock(ahc, &s);
1683 if (ahc->platform_data->dv_pid < 0) {
1684 printf("%s: Failed to create DV thread, error= %d\n",
1685 ahc_name(ahc), ahc->platform_data->dv_pid);
1686 return (-ahc->platform_data->dv_pid);
1687 }
1688 /*
1689 * Initially allocate *all* of our linux target objects
1690 * so that the DV thread will scan them all in parallel
1691 * just after driver initialization. Any device that
1692 * does not exist will have its target object destroyed
1693 * by the selection timeout handler. In the case of a
1694 * device that appears after the initial DV scan, async
1695 * negotiation will occur for the first command, and DV
1696 * will comence should that first command be successful.
1697 */
1698 for (targ_offset = 0;
1699 targ_offset < host->max_id * (host->max_channel + 1);
1700 targ_offset++) {
1701 u_int channel;
1702 u_int target;
1703
1704 channel = 0;
1705 target = targ_offset;
1706 if (target > 7
1707 && (ahc->features & AHC_TWIN) != 0) {
1708 channel = 1;
1709 target &= 0x7;
1710 }
1711 /*
1712 * Skip our own ID. Some Compaq/HP storage devices
1713 * have enclosure management devices that respond to
1714 * single bit selection (i.e. selecting ourselves).
1715 * It is expected that either an external application
1716 * or a modified kernel will be used to probe this
1717 * ID if it is appropriate. To accommodate these
1718 * installations, ahc_linux_alloc_target() will allocate
1719 * for our ID if asked to do so.
1720 */
1721 if ((channel == 0 && target == ahc->our_id)
1722 || (channel == 1 && target == ahc->our_id_b))
1723 continue;
1724
1725 ahc_linux_alloc_target(ahc, channel, target);
1726 }
1727 ahc_intr_enable(ahc, TRUE);
1728 ahc_linux_start_dv(ahc);
1729 ahc_unlock(ahc, &s);
1730
1731#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1732 scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */
1733 scsi_scan_host(host);
1734#endif
1735 return (0);
1736}
1737
1738uint64_t
1739ahc_linux_get_memsize(void)
1740{
1741 struct sysinfo si;
1742
1743 si_meminfo(&si);
1744 return ((uint64_t)si.totalram << PAGE_SHIFT);
1745}
1746
1747/*
1748 * Find the smallest available unit number to use
1749 * for a new device. We don't just use a static
1750 * count to handle the "repeated hot-(un)plug"
1751 * scenario.
1752 */
1753static int
1754ahc_linux_next_unit(void)
1755{
1756 struct ahc_softc *ahc;
1757 int unit;
1758
1759 unit = 0;
1760retry:
1761 TAILQ_FOREACH(ahc, &ahc_tailq, links) {
1762 if (ahc->unit == unit) {
1763 unit++;
1764 goto retry;
1765 }
1766 }
1767 return (unit);
1768}
1769
1770/*
1771 * Place the SCSI bus into a known state by either resetting it,
1772 * or forcing transfer negotiations on the next command to any
1773 * target.
1774 */
1775void
1776ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
1777{
1778 int i;
1779 int numtarg;
1780
1781 i = 0;
1782 numtarg = 0;
1783
1784 if (aic7xxx_no_reset != 0)
1785 ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
1786
1787 if ((ahc->flags & AHC_RESET_BUS_A) != 0)
1788 ahc_reset_channel(ahc, 'A', /*initiate_reset*/TRUE);
1789 else
1790 numtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
1791
1792 if ((ahc->features & AHC_TWIN) != 0) {
1793
1794 if ((ahc->flags & AHC_RESET_BUS_B) != 0) {
1795 ahc_reset_channel(ahc, 'B', /*initiate_reset*/TRUE);
1796 } else {
1797 if (numtarg == 0)
1798 i = 8;
1799 numtarg += 8;
1800 }
1801 }
1802
1803 /*
1804 * Force negotiation to async for all targets that
1805 * will not see an initial bus reset.
1806 */
1807 for (; i < numtarg; i++) {
1808 struct ahc_devinfo devinfo;
1809 struct ahc_initiator_tinfo *tinfo;
1810 struct ahc_tmode_tstate *tstate;
1811 u_int our_id;
1812 u_int target_id;
1813 char channel;
1814
1815 channel = 'A';
1816 our_id = ahc->our_id;
1817 target_id = i;
1818 if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
1819 channel = 'B';
1820 our_id = ahc->our_id_b;
1821 target_id = i % 8;
1822 }
1823 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
1824 target_id, &tstate);
1825 ahc_compile_devinfo(&devinfo, our_id, target_id,
1826 CAM_LUN_WILDCARD, channel, ROLE_INITIATOR);
1827 ahc_update_neg_request(ahc, &devinfo, tstate,
1828 tinfo, AHC_NEG_ALWAYS);
1829 }
1830 /* Give the bus some time to recover */
1831 if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
1832 ahc_linux_freeze_simq(ahc);
1833 init_timer(&ahc->platform_data->reset_timer);
1834 ahc->platform_data->reset_timer.data = (u_long)ahc;
1835 ahc->platform_data->reset_timer.expires =
1836 jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000;
1837 ahc->platform_data->reset_timer.function =
1838 ahc_linux_release_simq;
1839 add_timer(&ahc->platform_data->reset_timer);
1840 }
1841}
1842
1843int
1844ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
1845{
1846
1847 ahc->platform_data =
1848 malloc(sizeof(struct ahc_platform_data), M_DEVBUF, M_NOWAIT);
1849 if (ahc->platform_data == NULL)
1850 return (ENOMEM);
1851 memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
1852 TAILQ_INIT(&ahc->platform_data->completeq);
1853 TAILQ_INIT(&ahc->platform_data->device_runq);
1854 ahc->platform_data->irq = AHC_LINUX_NOIRQ;
1855 ahc->platform_data->hw_dma_mask = 0xFFFFFFFF;
1856 ahc_lockinit(ahc);
1857 ahc_done_lockinit(ahc);
1858 init_timer(&ahc->platform_data->completeq_timer);
1859 ahc->platform_data->completeq_timer.data = (u_long)ahc;
1860 ahc->platform_data->completeq_timer.function =
1861 (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue;
1862 init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
1863 init_MUTEX_LOCKED(&ahc->platform_data->dv_sem);
1864 init_MUTEX_LOCKED(&ahc->platform_data->dv_cmd_sem);
1865 tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet,
1866 (unsigned long)ahc);
1867 ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
1868 ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
1869 if (aic7xxx_pci_parity == 0)
1870 ahc->flags |= AHC_DISABLE_PCI_PERR;
1871
1872 return (0);
1873}
1874
1875void
1876ahc_platform_free(struct ahc_softc *ahc)
1877{
1878 struct ahc_linux_target *targ;
1879 struct ahc_linux_device *dev;
1880 int i, j;
1881
1882 if (ahc->platform_data != NULL) {
1883 del_timer_sync(&ahc->platform_data->completeq_timer);
1884 ahc_linux_kill_dv_thread(ahc);
1885 tasklet_kill(&ahc->platform_data->runq_tasklet);
1886 if (ahc->platform_data->host != NULL) {
1887#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1888 scsi_remove_host(ahc->platform_data->host);
1889#endif
1890 scsi_host_put(ahc->platform_data->host);
1891 }
1892
1893 /* destroy all of the device and target objects */
1894 for (i = 0; i < AHC_NUM_TARGETS; i++) {
1895 targ = ahc->platform_data->targets[i];
1896 if (targ != NULL) {
1897 /* Keep target around through the loop. */
1898 targ->refcount++;
1899 for (j = 0; j < AHC_NUM_LUNS; j++) {
1900
1901 if (targ->devices[j] == NULL)
1902 continue;
1903 dev = targ->devices[j];
1904 ahc_linux_free_device(ahc, dev);
1905 }
1906 /*
1907 * Forcibly free the target now that
1908 * all devices are gone.
1909 */
1910 ahc_linux_free_target(ahc, targ);
1911 }
1912 }
1913
1914 if (ahc->platform_data->irq != AHC_LINUX_NOIRQ)
1915 free_irq(ahc->platform_data->irq, ahc);
1916 if (ahc->tag == BUS_SPACE_PIO
1917 && ahc->bsh.ioport != 0)
1918 release_region(ahc->bsh.ioport, 256);
1919 if (ahc->tag == BUS_SPACE_MEMIO
1920 && ahc->bsh.maddr != NULL) {
1921 iounmap(ahc->bsh.maddr);
1922 release_mem_region(ahc->platform_data->mem_busaddr,
1923 0x1000);
1924 }
1925#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1926 /*
1927 * In 2.4 we detach from the scsi midlayer before the PCI
1928 * layer invokes our remove callback. No per-instance
1929 * detach is provided, so we must reach inside the PCI
1930 * subsystem's internals and detach our driver manually.
1931 */
1932 if (ahc->dev_softc != NULL)
1933 ahc->dev_softc->driver = NULL;
1934#endif
1935 free(ahc->platform_data, M_DEVBUF);
1936 }
1937}
1938
1939void
1940ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
1941{
1942 ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb),
1943 SCB_GET_CHANNEL(ahc, scb),
1944 SCB_GET_LUN(scb), SCB_LIST_NULL,
1945 ROLE_UNKNOWN, CAM_REQUEUE_REQ);
1946}
1947
1948void
1949ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
1950 ahc_queue_alg alg)
1951{
1952 struct ahc_linux_device *dev;
1953 int was_queuing;
1954 int now_queuing;
1955
1956 dev = ahc_linux_get_device(ahc, devinfo->channel - 'A',
1957 devinfo->target,
1958 devinfo->lun, /*alloc*/FALSE);
1959 if (dev == NULL)
1960 return;
1961 was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED);
1962 switch (alg) {
1963 default:
1964 case AHC_QUEUE_NONE:
1965 now_queuing = 0;
1966 break;
1967 case AHC_QUEUE_BASIC:
1968 now_queuing = AHC_DEV_Q_BASIC;
1969 break;
1970 case AHC_QUEUE_TAGGED:
1971 now_queuing = AHC_DEV_Q_TAGGED;
1972 break;
1973 }
1974 if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0
1975 && (was_queuing != now_queuing)
1976 && (dev->active != 0)) {
1977 dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY;
1978 dev->qfrozen++;
1979 }
1980
1981 dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG);
1982 if (now_queuing) {
1983 u_int usertags;
1984
1985 usertags = ahc_linux_user_tagdepth(ahc, devinfo);
1986 if (!was_queuing) {
1987 /*
1988 * Start out agressively and allow our
1989 * dynamic queue depth algorithm to take
1990 * care of the rest.
1991 */
1992 dev->maxtags = usertags;
1993 dev->openings = dev->maxtags - dev->active;
1994 }
1995 if (dev->maxtags == 0) {
1996 /*
1997 * Queueing is disabled by the user.
1998 */
1999 dev->openings = 1;
2000 } else if (alg == AHC_QUEUE_TAGGED) {
2001 dev->flags |= AHC_DEV_Q_TAGGED;
2002 if (aic7xxx_periodic_otag != 0)
2003 dev->flags |= AHC_DEV_PERIODIC_OTAG;
2004 } else
2005 dev->flags |= AHC_DEV_Q_BASIC;
2006 } else {
2007 /* We can only have one opening. */
2008 dev->maxtags = 0;
2009 dev->openings = 1 - dev->active;
2010 }
2011#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
2012 if (dev->scsi_device != NULL) {
2013 switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
2014 case AHC_DEV_Q_BASIC:
2015 scsi_adjust_queue_depth(dev->scsi_device,
2016 MSG_SIMPLE_TASK,
2017 dev->openings + dev->active);
2018 break;
2019 case AHC_DEV_Q_TAGGED:
2020 scsi_adjust_queue_depth(dev->scsi_device,
2021 MSG_ORDERED_TASK,
2022 dev->openings + dev->active);
2023 break;
2024 default:
2025 /*
2026 * We allow the OS to queue 2 untagged transactions to
2027 * us at any time even though we can only execute them
2028 * serially on the controller/device. This should
2029 * remove some latency.
2030 */
2031 scsi_adjust_queue_depth(dev->scsi_device,
2032 /*NON-TAGGED*/0,
2033 /*queue depth*/2);
2034 break;
2035 }
2036 }
2037#endif
2038}
2039
2040int
2041ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel,
2042 int lun, u_int tag, role_t role, uint32_t status)
2043{
2044 int chan;
2045 int maxchan;
2046 int targ;
2047 int maxtarg;
2048 int clun;
2049 int maxlun;
2050 int count;
2051
2052 if (tag != SCB_LIST_NULL)
2053 return (0);
2054
2055 chan = 0;
2056 if (channel != ALL_CHANNELS) {
2057 chan = channel - 'A';
2058 maxchan = chan + 1;
2059 } else {
2060 maxchan = (ahc->features & AHC_TWIN) ? 2 : 1;
2061 }
2062 targ = 0;
2063 if (target != CAM_TARGET_WILDCARD) {
2064 targ = target;
2065 maxtarg = targ + 1;
2066 } else {
2067 maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
2068 }
2069 clun = 0;
2070 if (lun != CAM_LUN_WILDCARD) {
2071 clun = lun;
2072 maxlun = clun + 1;
2073 } else {
2074 maxlun = AHC_NUM_LUNS;
2075 }
2076
2077 count = 0;
2078 for (; chan < maxchan; chan++) {
2079
2080 for (; targ < maxtarg; targ++) {
2081
2082 for (; clun < maxlun; clun++) {
2083 struct ahc_linux_device *dev;
2084 struct ahc_busyq *busyq;
2085 struct ahc_cmd *acmd;
2086
2087 dev = ahc_linux_get_device(ahc, chan,
2088 targ, clun,
2089 /*alloc*/FALSE);
2090 if (dev == NULL)
2091 continue;
2092
2093 busyq = &dev->busyq;
2094 while ((acmd = TAILQ_FIRST(busyq)) != NULL) {
2095 Scsi_Cmnd *cmd;
2096
2097 cmd = &acmd_scsi_cmd(acmd);
2098 TAILQ_REMOVE(busyq, acmd,
2099 acmd_links.tqe);
2100 count++;
2101 cmd->result = status << 16;
2102 ahc_linux_queue_cmd_complete(ahc, cmd);
2103 }
2104 }
2105 }
2106 }
2107
2108 return (count);
2109}
2110
2111static void
2112ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc)
2113{
2114 u_long flags;
2115
2116 ahc_lock(ahc, &flags);
2117 del_timer(&ahc->platform_data->completeq_timer);
2118 ahc->platform_data->flags &= ~AHC_RUN_CMPLT_Q_TIMER;
2119 ahc_linux_run_complete_queue(ahc);
2120 ahc_unlock(ahc, &flags);
2121}
2122
2123static void
2124ahc_linux_start_dv(struct ahc_softc *ahc)
2125{
2126
2127 /*
2128 * Freeze the simq and signal ahc_linux_queue to not let any
2129 * more commands through.
2130 */
2131 if ((ahc->platform_data->flags & AHC_DV_ACTIVE) == 0) {
2132#ifdef AHC_DEBUG
2133 if (ahc_debug & AHC_SHOW_DV)
2134 printf("%s: Waking DV thread\n", ahc_name(ahc));
2135#endif
2136
2137 ahc->platform_data->flags |= AHC_DV_ACTIVE;
2138 ahc_linux_freeze_simq(ahc);
2139
2140 /* Wake up the DV kthread */
2141 up(&ahc->platform_data->dv_sem);
2142 }
2143}
2144
2145static void
2146ahc_linux_kill_dv_thread(struct ahc_softc *ahc)
2147{
2148 u_long s;
2149
2150 ahc_lock(ahc, &s);
2151 if (ahc->platform_data->dv_pid != 0) {
2152 ahc->platform_data->flags |= AHC_DV_SHUTDOWN;
2153 ahc_unlock(ahc, &s);
2154 up(&ahc->platform_data->dv_sem);
2155
2156 /*
2157 * Use the eh_sem as an indicator that the
2158 * dv thread is exiting. Note that the dv
2159 * thread must still return after performing
2160 * the up on our semaphore before it has
2161 * completely exited this module. Unfortunately,
2162 * there seems to be no easy way to wait for the
2163 * exit of a thread for which you are not the
2164 * parent (dv threads are parented by init).
2165 * Cross your fingers...
2166 */
2167 down(&ahc->platform_data->eh_sem);
2168
2169 /*
2170 * Mark the dv thread as already dead. This
2171 * avoids attempting to kill it a second time.
2172 * This is necessary because we must kill the
2173 * DV thread before calling ahc_free() in the
2174 * module shutdown case to avoid bogus locking
2175 * in the SCSI mid-layer, but we ahc_free() is
2176 * called without killing the DV thread in the
2177 * instance detach case, so ahc_platform_free()
2178 * calls us again to verify that the DV thread
2179 * is dead.
2180 */
2181 ahc->platform_data->dv_pid = 0;
2182 } else {
2183 ahc_unlock(ahc, &s);
2184 }
2185}
2186
2187static int
2188ahc_linux_dv_thread(void *data)
2189{
2190 struct ahc_softc *ahc;
2191 int target;
2192 u_long s;
2193
2194 ahc = (struct ahc_softc *)data;
2195
2196#ifdef AHC_DEBUG
2197 if (ahc_debug & AHC_SHOW_DV)
2198 printf("Launching DV Thread\n");
2199#endif
2200
2201 /*
2202 * Complete thread creation.
2203 */
2204 lock_kernel();
2205#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
2206 /*
2207 * Don't care about any signals.
2208 */
2209 siginitsetinv(&current->blocked, 0);
2210
2211 daemonize();
2212 sprintf(current->comm, "ahc_dv_%d", ahc->unit);
2213#else
2214 daemonize("ahc_dv_%d", ahc->unit);
2215 current->flags |= PF_FREEZE;
2216#endif
2217 unlock_kernel();
2218
2219 while (1) {
2220 /*
2221 * Use down_interruptible() rather than down() to
2222 * avoid inclusion in the load average.
2223 */
2224 down_interruptible(&ahc->platform_data->dv_sem);
2225
2226 /* Check to see if we've been signaled to exit */
2227 ahc_lock(ahc, &s);
2228 if ((ahc->platform_data->flags & AHC_DV_SHUTDOWN) != 0) {
2229 ahc_unlock(ahc, &s);
2230 break;
2231 }
2232 ahc_unlock(ahc, &s);
2233
2234#ifdef AHC_DEBUG
2235 if (ahc_debug & AHC_SHOW_DV)
2236 printf("%s: Beginning Domain Validation\n",
2237 ahc_name(ahc));
2238#endif
2239
2240 /*
2241 * Wait for any pending commands to drain before proceeding.
2242 */
2243 ahc_lock(ahc, &s);
2244 while (LIST_FIRST(&ahc->pending_scbs) != NULL) {
2245 ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_EMPTY;
2246 ahc_unlock(ahc, &s);
2247 down_interruptible(&ahc->platform_data->dv_sem);
2248 ahc_lock(ahc, &s);
2249 }
2250
2251 /*
2252 * Wait for the SIMQ to be released so that DV is the
2253 * only reason the queue is frozen.
2254 */
2255 while (AHC_DV_SIMQ_FROZEN(ahc) == 0) {
2256 ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE;
2257 ahc_unlock(ahc, &s);
2258 down_interruptible(&ahc->platform_data->dv_sem);
2259 ahc_lock(ahc, &s);
2260 }
2261 ahc_unlock(ahc, &s);
2262
2263 for (target = 0; target < AHC_NUM_TARGETS; target++)
2264 ahc_linux_dv_target(ahc, target);
2265
2266 ahc_lock(ahc, &s);
2267 ahc->platform_data->flags &= ~AHC_DV_ACTIVE;
2268 ahc_unlock(ahc, &s);
2269
2270 /*
2271 * Release the SIMQ so that normal commands are
2272 * allowed to continue on the bus.
2273 */
2274 ahc_linux_release_simq((u_long)ahc);
2275 }
2276 up(&ahc->platform_data->eh_sem);
2277 return (0);
2278}
2279
2280#define AHC_LINUX_DV_INQ_SHORT_LEN 36
2281#define AHC_LINUX_DV_INQ_LEN 256
2282#define AHC_LINUX_DV_TIMEOUT (HZ / 4)
2283
2284#define AHC_SET_DV_STATE(ahc, targ, newstate) \
2285 ahc_set_dv_state(ahc, targ, newstate, __LINE__)
2286
2287static __inline void
2288ahc_set_dv_state(struct ahc_softc *ahc, struct ahc_linux_target *targ,
2289 ahc_dv_state newstate, u_int line)
2290{
2291 ahc_dv_state oldstate;
2292
2293 oldstate = targ->dv_state;
2294#ifdef AHC_DEBUG
2295 if (ahc_debug & AHC_SHOW_DV)
2296 printf("%s:%d: Going from state %d to state %d\n",
2297 ahc_name(ahc), line, oldstate, newstate);
2298#endif
2299
2300 if (oldstate == newstate)
2301 targ->dv_state_retry++;
2302 else
2303 targ->dv_state_retry = 0;
2304 targ->dv_state = newstate;
2305}
2306
2307static void
2308ahc_linux_dv_target(struct ahc_softc *ahc, u_int target_offset)
2309{
2310 struct ahc_devinfo devinfo;
2311 struct ahc_linux_target *targ;
2312 struct scsi_cmnd *cmd;
2313 struct scsi_device *scsi_dev;
2314 struct scsi_sense_data *sense;
2315 uint8_t *buffer;
2316 u_long s;
2317 u_int timeout;
2318 int echo_size;
2319
2320 sense = NULL;
2321 buffer = NULL;
2322 echo_size = 0;
2323 ahc_lock(ahc, &s);
2324 targ = ahc->platform_data->targets[target_offset];
2325 if (targ == NULL || (targ->flags & AHC_DV_REQUIRED) == 0) {
2326 ahc_unlock(ahc, &s);
2327 return;
2328 }
2329 ahc_compile_devinfo(&devinfo,
2330 targ->channel == 0 ? ahc->our_id : ahc->our_id_b,
2331 targ->target, /*lun*/0, targ->channel + 'A',
2332 ROLE_INITIATOR);
2333#ifdef AHC_DEBUG
2334 if (ahc_debug & AHC_SHOW_DV) {
2335 ahc_print_devinfo(ahc, &devinfo);
2336 printf("Performing DV\n");
2337 }
2338#endif
2339
2340 ahc_unlock(ahc, &s);
2341
2342 cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK);
2343 scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK);
2344 scsi_dev->host = ahc->platform_data->host;
2345 scsi_dev->id = devinfo.target;
2346 scsi_dev->lun = devinfo.lun;
2347 scsi_dev->channel = devinfo.channel - 'A';
2348 ahc->platform_data->dv_scsi_dev = scsi_dev;
2349
2350 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_SHORT_ASYNC);
2351
2352 while (targ->dv_state != AHC_DV_STATE_EXIT) {
2353 timeout = AHC_LINUX_DV_TIMEOUT;
2354 switch (targ->dv_state) {
2355 case AHC_DV_STATE_INQ_SHORT_ASYNC:
2356 case AHC_DV_STATE_INQ_ASYNC:
2357 case AHC_DV_STATE_INQ_ASYNC_VERIFY:
2358 /*
2359 * Set things to async narrow to reduce the
2360 * chance that the INQ will fail.
2361 */
2362 ahc_lock(ahc, &s);
2363 ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
2364 AHC_TRANS_GOAL, /*paused*/FALSE);
2365 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
2366 AHC_TRANS_GOAL, /*paused*/FALSE);
2367 ahc_unlock(ahc, &s);
2368 timeout = 10 * HZ;
2369 targ->flags &= ~AHC_INQ_VALID;
2370 /* FALLTHROUGH */
2371 case AHC_DV_STATE_INQ_VERIFY:
2372 {
2373 u_int inq_len;
2374
2375 if (targ->dv_state == AHC_DV_STATE_INQ_SHORT_ASYNC)
2376 inq_len = AHC_LINUX_DV_INQ_SHORT_LEN;
2377 else
2378 inq_len = targ->inq_data->additional_length + 5;
2379 ahc_linux_dv_inq(ahc, cmd, &devinfo, targ, inq_len);
2380 break;
2381 }
2382 case AHC_DV_STATE_TUR:
2383 case AHC_DV_STATE_BUSY:
2384 timeout = 5 * HZ;
2385 ahc_linux_dv_tur(ahc, cmd, &devinfo);
2386 break;
2387 case AHC_DV_STATE_REBD:
2388 ahc_linux_dv_rebd(ahc, cmd, &devinfo, targ);
2389 break;
2390 case AHC_DV_STATE_WEB:
2391 ahc_linux_dv_web(ahc, cmd, &devinfo, targ);
2392 break;
2393
2394 case AHC_DV_STATE_REB:
2395 ahc_linux_dv_reb(ahc, cmd, &devinfo, targ);
2396 break;
2397
2398 case AHC_DV_STATE_SU:
2399 ahc_linux_dv_su(ahc, cmd, &devinfo, targ);
2400 timeout = 50 * HZ;
2401 break;
2402
2403 default:
2404 ahc_print_devinfo(ahc, &devinfo);
2405 printf("Unknown DV state %d\n", targ->dv_state);
2406 goto out;
2407 }
2408
2409 /* Queue the command and wait for it to complete */
2410 /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */
2411 init_timer(&cmd->eh_timeout);
2412#ifdef AHC_DEBUG
2413 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2414 /*
2415 * All of the printfs during negotiation
2416 * really slow down the negotiation.
2417 * Add a bit of time just to be safe.
2418 */
2419 timeout += HZ;
2420#endif
2421 scsi_add_timer(cmd, timeout, ahc_linux_dv_timeout);
2422 /*
2423 * In 2.5.X, it is assumed that all calls from the
2424 * "midlayer" (which we are emulating) will have the
2425 * ahc host lock held. For other kernels, the
2426 * io_request_lock must be held.
2427 */
2428#if AHC_SCSI_HAS_HOST_LOCK != 0
2429 ahc_lock(ahc, &s);
2430#else
2431 spin_lock_irqsave(&io_request_lock, s);
2432#endif
2433 ahc_linux_queue(cmd, ahc_linux_dv_complete);
2434#if AHC_SCSI_HAS_HOST_LOCK != 0
2435 ahc_unlock(ahc, &s);
2436#else
2437 spin_unlock_irqrestore(&io_request_lock, s);
2438#endif
2439 down_interruptible(&ahc->platform_data->dv_cmd_sem);
2440 /*
2441 * Wait for the SIMQ to be released so that DV is the
2442 * only reason the queue is frozen.
2443 */
2444 ahc_lock(ahc, &s);
2445 while (AHC_DV_SIMQ_FROZEN(ahc) == 0) {
2446 ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE;
2447 ahc_unlock(ahc, &s);
2448 down_interruptible(&ahc->platform_data->dv_sem);
2449 ahc_lock(ahc, &s);
2450 }
2451 ahc_unlock(ahc, &s);
2452
2453 ahc_linux_dv_transition(ahc, cmd, &devinfo, targ);
2454 }
2455
2456out:
2457 if ((targ->flags & AHC_INQ_VALID) != 0
2458 && ahc_linux_get_device(ahc, devinfo.channel - 'A',
2459 devinfo.target, devinfo.lun,
2460 /*alloc*/FALSE) == NULL) {
2461 /*
2462 * The DV state machine failed to configure this device.
2463 * This is normal if DV is disabled. Since we have inquiry
2464 * data, filter it and use the "optimistic" negotiation
2465 * parameters found in the inquiry string.
2466 */
2467 ahc_linux_filter_inquiry(ahc, &devinfo);
2468 if ((targ->flags & (AHC_BASIC_DV|AHC_ENHANCED_DV)) != 0) {
2469 ahc_print_devinfo(ahc, &devinfo);
2470 printf("DV failed to configure device. "
2471 "Please file a bug report against "
2472 "this driver.\n");
2473 }
2474 }
2475
2476 if (cmd != NULL)
2477 free(cmd, M_DEVBUF);
2478
2479 if (ahc->platform_data->dv_scsi_dev != NULL) {
2480 free(ahc->platform_data->dv_scsi_dev, M_DEVBUF);
2481 ahc->platform_data->dv_scsi_dev = NULL;
2482 }
2483
2484 ahc_lock(ahc, &s);
2485 if (targ->dv_buffer != NULL) {
2486 free(targ->dv_buffer, M_DEVBUF);
2487 targ->dv_buffer = NULL;
2488 }
2489 if (targ->dv_buffer1 != NULL) {
2490 free(targ->dv_buffer1, M_DEVBUF);
2491 targ->dv_buffer1 = NULL;
2492 }
2493 targ->flags &= ~AHC_DV_REQUIRED;
2494 if (targ->refcount == 0)
2495 ahc_linux_free_target(ahc, targ);
2496 ahc_unlock(ahc, &s);
2497}
2498
2499static void
2500ahc_linux_dv_transition(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
2501 struct ahc_devinfo *devinfo,
2502 struct ahc_linux_target *targ)
2503{
2504 u_int32_t status;
2505
2506 status = aic_error_action(cmd, targ->inq_data,
2507 ahc_cmd_get_transaction_status(cmd),
2508 ahc_cmd_get_scsi_status(cmd));
2509
2510#ifdef AHC_DEBUG
2511 if (ahc_debug & AHC_SHOW_DV) {
2512 ahc_print_devinfo(ahc, devinfo);
2513 printf("Entering ahc_linux_dv_transition, state= %d, "
2514 "status= 0x%x, cmd->result= 0x%x\n", targ->dv_state,
2515 status, cmd->result);
2516 }
2517#endif
2518
2519 switch (targ->dv_state) {
2520 case AHC_DV_STATE_INQ_SHORT_ASYNC:
2521 case AHC_DV_STATE_INQ_ASYNC:
2522 switch (status & SS_MASK) {
2523 case SS_NOP:
2524 {
2525 AHC_SET_DV_STATE(ahc, targ, targ->dv_state+1);
2526 break;
2527 }
2528 case SS_INQ_REFRESH:
2529 AHC_SET_DV_STATE(ahc, targ,
2530 AHC_DV_STATE_INQ_SHORT_ASYNC);
2531 break;
2532 case SS_TUR:
2533 case SS_RETRY:
2534 AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
2535 if (ahc_cmd_get_transaction_status(cmd)
2536 == CAM_REQUEUE_REQ)
2537 targ->dv_state_retry--;
2538 if ((status & SS_ERRMASK) == EBUSY)
2539 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
2540 if (targ->dv_state_retry < 10)
2541 break;
2542 /* FALLTHROUGH */
2543 default:
2544 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2545#ifdef AHC_DEBUG
2546 if (ahc_debug & AHC_SHOW_DV) {
2547 ahc_print_devinfo(ahc, devinfo);
2548 printf("Failed DV inquiry, skipping\n");
2549 }
2550#endif
2551 break;
2552 }
2553 break;
2554 case AHC_DV_STATE_INQ_ASYNC_VERIFY:
2555 switch (status & SS_MASK) {
2556 case SS_NOP:
2557 {
2558 u_int xportflags;
2559 u_int spi3data;
2560
2561 if (memcmp(targ->inq_data, targ->dv_buffer,
2562 AHC_LINUX_DV_INQ_LEN) != 0) {
2563 /*
2564 * Inquiry data must have changed.
2565 * Try from the top again.
2566 */
2567 AHC_SET_DV_STATE(ahc, targ,
2568 AHC_DV_STATE_INQ_SHORT_ASYNC);
2569 break;
2570 }
2571
2572 AHC_SET_DV_STATE(ahc, targ, targ->dv_state+1);
2573 targ->flags |= AHC_INQ_VALID;
2574 if (ahc_linux_user_dv_setting(ahc) == 0)
2575 break;
2576
2577 xportflags = targ->inq_data->flags;
2578 if ((xportflags & (SID_Sync|SID_WBus16)) == 0)
2579 break;
2580
2581 spi3data = targ->inq_data->spi3data;
2582 switch (spi3data & SID_SPI_CLOCK_DT_ST) {
2583 default:
2584 case SID_SPI_CLOCK_ST:
2585 /* Assume only basic DV is supported. */
2586 targ->flags |= AHC_BASIC_DV;
2587 break;
2588 case SID_SPI_CLOCK_DT:
2589 case SID_SPI_CLOCK_DT_ST:
2590 targ->flags |= AHC_ENHANCED_DV;
2591 break;
2592 }
2593 break;
2594 }
2595 case SS_INQ_REFRESH:
2596 AHC_SET_DV_STATE(ahc, targ,
2597 AHC_DV_STATE_INQ_SHORT_ASYNC);
2598 break;
2599 case SS_TUR:
2600 case SS_RETRY:
2601 AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
2602 if (ahc_cmd_get_transaction_status(cmd)
2603 == CAM_REQUEUE_REQ)
2604 targ->dv_state_retry--;
2605
2606 if ((status & SS_ERRMASK) == EBUSY)
2607 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
2608 if (targ->dv_state_retry < 10)
2609 break;
2610 /* FALLTHROUGH */
2611 default:
2612 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2613#ifdef AHC_DEBUG
2614 if (ahc_debug & AHC_SHOW_DV) {
2615 ahc_print_devinfo(ahc, devinfo);
2616 printf("Failed DV inquiry, skipping\n");
2617 }
2618#endif
2619 break;
2620 }
2621 break;
2622 case AHC_DV_STATE_INQ_VERIFY:
2623 switch (status & SS_MASK) {
2624 case SS_NOP:
2625 {
2626
2627 if (memcmp(targ->inq_data, targ->dv_buffer,
2628 AHC_LINUX_DV_INQ_LEN) == 0) {
2629 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2630 break;
2631 }
2632#ifdef AHC_DEBUG
2633 if (ahc_debug & AHC_SHOW_DV) {
2634 int i;
2635
2636 ahc_print_devinfo(ahc, devinfo);
2637 printf("Inquiry buffer mismatch:");
2638 for (i = 0; i < AHC_LINUX_DV_INQ_LEN; i++) {
2639 if ((i & 0xF) == 0)
2640 printf("\n ");
2641 printf("0x%x:0x0%x ",
2642 ((uint8_t *)targ->inq_data)[i],
2643 targ->dv_buffer[i]);
2644 }
2645 printf("\n");
2646 }
2647#endif
2648
2649 if (ahc_linux_fallback(ahc, devinfo) != 0) {
2650 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2651 break;
2652 }
2653 /*
2654 * Do not count "falling back"
2655 * against our retries.
2656 */
2657 targ->dv_state_retry = 0;
2658 AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
2659 break;
2660 }
2661 case SS_INQ_REFRESH:
2662 AHC_SET_DV_STATE(ahc, targ,
2663 AHC_DV_STATE_INQ_SHORT_ASYNC);
2664 break;
2665 case SS_TUR:
2666 case SS_RETRY:
2667 AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
2668 if (ahc_cmd_get_transaction_status(cmd)
2669 == CAM_REQUEUE_REQ) {
2670 targ->dv_state_retry--;
2671 } else if ((status & SSQ_FALLBACK) != 0) {
2672 if (ahc_linux_fallback(ahc, devinfo) != 0) {
2673 AHC_SET_DV_STATE(ahc, targ,
2674 AHC_DV_STATE_EXIT);
2675 break;
2676 }
2677 /*
2678 * Do not count "falling back"
2679 * against our retries.
2680 */
2681 targ->dv_state_retry = 0;
2682 } else if ((status & SS_ERRMASK) == EBUSY)
2683 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
2684 if (targ->dv_state_retry < 10)
2685 break;
2686 /* FALLTHROUGH */
2687 default:
2688 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2689#ifdef AHC_DEBUG
2690 if (ahc_debug & AHC_SHOW_DV) {
2691 ahc_print_devinfo(ahc, devinfo);
2692 printf("Failed DV inquiry, skipping\n");
2693 }
2694#endif
2695 break;
2696 }
2697 break;
2698
2699 case AHC_DV_STATE_TUR:
2700 switch (status & SS_MASK) {
2701 case SS_NOP:
2702 if ((targ->flags & AHC_BASIC_DV) != 0) {
2703 ahc_linux_filter_inquiry(ahc, devinfo);
2704 AHC_SET_DV_STATE(ahc, targ,
2705 AHC_DV_STATE_INQ_VERIFY);
2706 } else if ((targ->flags & AHC_ENHANCED_DV) != 0) {
2707 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REBD);
2708 } else {
2709 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2710 }
2711 break;
2712 case SS_RETRY:
2713 case SS_TUR:
2714 if ((status & SS_ERRMASK) == EBUSY) {
2715 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
2716 break;
2717 }
2718 AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
2719 if (ahc_cmd_get_transaction_status(cmd)
2720 == CAM_REQUEUE_REQ) {
2721 targ->dv_state_retry--;
2722 } else if ((status & SSQ_FALLBACK) != 0) {
2723 if (ahc_linux_fallback(ahc, devinfo) != 0) {
2724 AHC_SET_DV_STATE(ahc, targ,
2725 AHC_DV_STATE_EXIT);
2726 break;
2727 }
2728 /*
2729 * Do not count "falling back"
2730 * against our retries.
2731 */
2732 targ->dv_state_retry = 0;
2733 }
2734 if (targ->dv_state_retry >= 10) {
2735#ifdef AHC_DEBUG
2736 if (ahc_debug & AHC_SHOW_DV) {
2737 ahc_print_devinfo(ahc, devinfo);
2738 printf("DV TUR reties exhausted\n");
2739 }
2740#endif
2741 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2742 break;
2743 }
2744 if (status & SSQ_DELAY)
2745 ssleep(1);
2746
2747 break;
2748 case SS_START:
2749 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_SU);
2750 break;
2751 case SS_INQ_REFRESH:
2752 AHC_SET_DV_STATE(ahc, targ,
2753 AHC_DV_STATE_INQ_SHORT_ASYNC);
2754 break;
2755 default:
2756 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2757 break;
2758 }
2759 break;
2760
2761 case AHC_DV_STATE_REBD:
2762 switch (status & SS_MASK) {
2763 case SS_NOP:
2764 {
2765 uint32_t echo_size;
2766
2767 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB);
2768 echo_size = scsi_3btoul(&targ->dv_buffer[1]);
2769 echo_size &= 0x1FFF;
2770#ifdef AHC_DEBUG
2771 if (ahc_debug & AHC_SHOW_DV) {
2772 ahc_print_devinfo(ahc, devinfo);
2773 printf("Echo buffer size= %d\n", echo_size);
2774 }
2775#endif
2776 if (echo_size == 0) {
2777 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2778 break;
2779 }
2780
2781 /* Generate the buffer pattern */
2782 targ->dv_echo_size = echo_size;
2783 ahc_linux_generate_dv_pattern(targ);
2784 /*
2785 * Setup initial negotiation values.
2786 */
2787 ahc_linux_filter_inquiry(ahc, devinfo);
2788 break;
2789 }
2790 case SS_INQ_REFRESH:
2791 AHC_SET_DV_STATE(ahc, targ,
2792 AHC_DV_STATE_INQ_SHORT_ASYNC);
2793 break;
2794 case SS_RETRY:
2795 AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
2796 if (ahc_cmd_get_transaction_status(cmd)
2797 == CAM_REQUEUE_REQ)
2798 targ->dv_state_retry--;
2799 if (targ->dv_state_retry <= 10)
2800 break;
2801#ifdef AHC_DEBUG
2802 if (ahc_debug & AHC_SHOW_DV) {
2803 ahc_print_devinfo(ahc, devinfo);
2804 printf("DV REBD reties exhausted\n");
2805 }
2806#endif
2807 /* FALLTHROUGH */
2808 case SS_FATAL:
2809 default:
2810 /*
2811 * Setup initial negotiation values
2812 * and try level 1 DV.
2813 */
2814 ahc_linux_filter_inquiry(ahc, devinfo);
2815 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_VERIFY);
2816 targ->dv_echo_size = 0;
2817 break;
2818 }
2819 break;
2820
2821 case AHC_DV_STATE_WEB:
2822 switch (status & SS_MASK) {
2823 case SS_NOP:
2824 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REB);
2825 break;
2826 case SS_INQ_REFRESH:
2827 AHC_SET_DV_STATE(ahc, targ,
2828 AHC_DV_STATE_INQ_SHORT_ASYNC);
2829 break;
2830 case SS_RETRY:
2831 AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
2832 if (ahc_cmd_get_transaction_status(cmd)
2833 == CAM_REQUEUE_REQ) {
2834 targ->dv_state_retry--;
2835 } else if ((status & SSQ_FALLBACK) != 0) {
2836 if (ahc_linux_fallback(ahc, devinfo) != 0) {
2837 AHC_SET_DV_STATE(ahc, targ,
2838 AHC_DV_STATE_EXIT);
2839 break;
2840 }
2841 /*
2842 * Do not count "falling back"
2843 * against our retries.
2844 */
2845 targ->dv_state_retry = 0;
2846 }
2847 if (targ->dv_state_retry <= 10)
2848 break;
2849 /* FALLTHROUGH */
2850#ifdef AHC_DEBUG
2851 if (ahc_debug & AHC_SHOW_DV) {
2852 ahc_print_devinfo(ahc, devinfo);
2853 printf("DV WEB reties exhausted\n");
2854 }
2855#endif
2856 default:
2857 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2858 break;
2859 }
2860 break;
2861
2862 case AHC_DV_STATE_REB:
2863 switch (status & SS_MASK) {
2864 case SS_NOP:
2865 if (memcmp(targ->dv_buffer, targ->dv_buffer1,
2866 targ->dv_echo_size) != 0) {
2867 if (ahc_linux_fallback(ahc, devinfo) != 0)
2868 AHC_SET_DV_STATE(ahc, targ,
2869 AHC_DV_STATE_EXIT);
2870 else
2871 AHC_SET_DV_STATE(ahc, targ,
2872 AHC_DV_STATE_WEB);
2873 break;
2874 }
2875
2876 if (targ->dv_buffer != NULL) {
2877 free(targ->dv_buffer, M_DEVBUF);
2878 targ->dv_buffer = NULL;
2879 }
2880 if (targ->dv_buffer1 != NULL) {
2881 free(targ->dv_buffer1, M_DEVBUF);
2882 targ->dv_buffer1 = NULL;
2883 }
2884 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2885 break;
2886 case SS_INQ_REFRESH:
2887 AHC_SET_DV_STATE(ahc, targ,
2888 AHC_DV_STATE_INQ_SHORT_ASYNC);
2889 break;
2890 case SS_RETRY:
2891 AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
2892 if (ahc_cmd_get_transaction_status(cmd)
2893 == CAM_REQUEUE_REQ) {
2894 targ->dv_state_retry--;
2895 } else if ((status & SSQ_FALLBACK) != 0) {
2896 if (ahc_linux_fallback(ahc, devinfo) != 0) {
2897 AHC_SET_DV_STATE(ahc, targ,
2898 AHC_DV_STATE_EXIT);
2899 break;
2900 }
2901 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB);
2902 }
2903 if (targ->dv_state_retry <= 10) {
2904 if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0)
2905 msleep(ahc->our_id*1000/10);
2906 break;
2907 }
2908#ifdef AHC_DEBUG
2909 if (ahc_debug & AHC_SHOW_DV) {
2910 ahc_print_devinfo(ahc, devinfo);
2911 printf("DV REB reties exhausted\n");
2912 }
2913#endif
2914 /* FALLTHROUGH */
2915 default:
2916 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2917 break;
2918 }
2919 break;
2920
2921 case AHC_DV_STATE_SU:
2922 switch (status & SS_MASK) {
2923 case SS_NOP:
2924 case SS_INQ_REFRESH:
2925 AHC_SET_DV_STATE(ahc, targ,
2926 AHC_DV_STATE_INQ_SHORT_ASYNC);
2927 break;
2928 default:
2929 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2930 break;
2931 }
2932 break;
2933
2934 case AHC_DV_STATE_BUSY:
2935 switch (status & SS_MASK) {
2936 case SS_NOP:
2937 case SS_INQ_REFRESH:
2938 AHC_SET_DV_STATE(ahc, targ,
2939 AHC_DV_STATE_INQ_SHORT_ASYNC);
2940 break;
2941 case SS_TUR:
2942 case SS_RETRY:
2943 AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
2944 if (ahc_cmd_get_transaction_status(cmd)
2945 == CAM_REQUEUE_REQ) {
2946 targ->dv_state_retry--;
2947 } else if (targ->dv_state_retry < 60) {
2948 if ((status & SSQ_DELAY) != 0)
2949 ssleep(1);
2950 } else {
2951#ifdef AHC_DEBUG
2952 if (ahc_debug & AHC_SHOW_DV) {
2953 ahc_print_devinfo(ahc, devinfo);
2954 printf("DV BUSY reties exhausted\n");
2955 }
2956#endif
2957 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2958 }
2959 break;
2960 default:
2961 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2962 break;
2963 }
2964 break;
2965
2966 default:
2967 printf("%s: Invalid DV completion state %d\n", ahc_name(ahc),
2968 targ->dv_state);
2969 AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
2970 break;
2971 }
2972}
2973
2974static void
2975ahc_linux_dv_fill_cmd(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
2976 struct ahc_devinfo *devinfo)
2977{
2978 memset(cmd, 0, sizeof(struct scsi_cmnd));
2979 cmd->device = ahc->platform_data->dv_scsi_dev;
2980 cmd->scsi_done = ahc_linux_dv_complete;
2981}
2982
2983/*
2984 * Synthesize an inquiry command. On the return trip, it'll be
2985 * sniffed and the device transfer settings set for us.
2986 */
2987static void
2988ahc_linux_dv_inq(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
2989 struct ahc_devinfo *devinfo, struct ahc_linux_target *targ,
2990 u_int request_length)
2991{
2992
2993#ifdef AHC_DEBUG
2994 if (ahc_debug & AHC_SHOW_DV) {
2995 ahc_print_devinfo(ahc, devinfo);
2996 printf("Sending INQ\n");
2997 }
2998#endif
2999 if (targ->inq_data == NULL)
3000 targ->inq_data = malloc(AHC_LINUX_DV_INQ_LEN,
3001 M_DEVBUF, M_WAITOK);
3002 if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC) {
3003 if (targ->dv_buffer != NULL)
3004 free(targ->dv_buffer, M_DEVBUF);
3005 targ->dv_buffer = malloc(AHC_LINUX_DV_INQ_LEN,
3006 M_DEVBUF, M_WAITOK);
3007 }
3008
3009 ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
3010 cmd->sc_data_direction = SCSI_DATA_READ;
3011 cmd->cmd_len = 6;
3012 cmd->cmnd[0] = INQUIRY;
3013 cmd->cmnd[4] = request_length;
3014 cmd->request_bufflen = request_length;
3015 if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC)
3016 cmd->request_buffer = targ->dv_buffer;
3017 else
3018 cmd->request_buffer = targ->inq_data;
3019 memset(cmd->request_buffer, 0, AHC_LINUX_DV_INQ_LEN);
3020}
3021
3022static void
3023ahc_linux_dv_tur(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
3024 struct ahc_devinfo *devinfo)
3025{
3026
3027#ifdef AHC_DEBUG
3028 if (ahc_debug & AHC_SHOW_DV) {
3029 ahc_print_devinfo(ahc, devinfo);
3030 printf("Sending TUR\n");
3031 }
3032#endif
3033 /* Do a TUR to clear out any non-fatal transitional state */
3034 ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
3035 cmd->sc_data_direction = SCSI_DATA_NONE;
3036 cmd->cmd_len = 6;
3037 cmd->cmnd[0] = TEST_UNIT_READY;
3038}
3039
3040#define AHC_REBD_LEN 4
3041
3042static void
3043ahc_linux_dv_rebd(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
3044 struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
3045{
3046
3047#ifdef AHC_DEBUG
3048 if (ahc_debug & AHC_SHOW_DV) {
3049 ahc_print_devinfo(ahc, devinfo);
3050 printf("Sending REBD\n");
3051 }
3052#endif
3053 if (targ->dv_buffer != NULL)
3054 free(targ->dv_buffer, M_DEVBUF);
3055 targ->dv_buffer = malloc(AHC_REBD_LEN, M_DEVBUF, M_WAITOK);
3056 ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
3057 cmd->sc_data_direction = SCSI_DATA_READ;
3058 cmd->cmd_len = 10;
3059 cmd->cmnd[0] = READ_BUFFER;
3060 cmd->cmnd[1] = 0x0b;
3061 scsi_ulto3b(AHC_REBD_LEN, &cmd->cmnd[6]);
3062 cmd->request_bufflen = AHC_REBD_LEN;
3063 cmd->underflow = cmd->request_bufflen;
3064 cmd->request_buffer = targ->dv_buffer;
3065}
3066
3067static void
3068ahc_linux_dv_web(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
3069 struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
3070{
3071
3072#ifdef AHC_DEBUG
3073 if (ahc_debug & AHC_SHOW_DV) {
3074 ahc_print_devinfo(ahc, devinfo);
3075 printf("Sending WEB\n");
3076 }
3077#endif
3078 ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
3079 cmd->sc_data_direction = SCSI_DATA_WRITE;
3080 cmd->cmd_len = 10;
3081 cmd->cmnd[0] = WRITE_BUFFER;
3082 cmd->cmnd[1] = 0x0a;
3083 scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]);
3084 cmd->request_bufflen = targ->dv_echo_size;
3085 cmd->underflow = cmd->request_bufflen;
3086 cmd->request_buffer = targ->dv_buffer;
3087}
3088
3089static void
3090ahc_linux_dv_reb(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
3091 struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
3092{
3093
3094#ifdef AHC_DEBUG
3095 if (ahc_debug & AHC_SHOW_DV) {
3096 ahc_print_devinfo(ahc, devinfo);
3097 printf("Sending REB\n");
3098 }
3099#endif
3100 ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
3101 cmd->sc_data_direction = SCSI_DATA_READ;
3102 cmd->cmd_len = 10;
3103 cmd->cmnd[0] = READ_BUFFER;
3104 cmd->cmnd[1] = 0x0a;
3105 scsi_ulto3b(targ->dv_echo_size, &cmd->cmnd[6]);
3106 cmd->request_bufflen = targ->dv_echo_size;
3107 cmd->underflow = cmd->request_bufflen;
3108 cmd->request_buffer = targ->dv_buffer1;
3109}
3110
3111static void
3112ahc_linux_dv_su(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
3113 struct ahc_devinfo *devinfo,
3114 struct ahc_linux_target *targ)
3115{
3116 u_int le;
3117
3118 le = SID_IS_REMOVABLE(targ->inq_data) ? SSS_LOEJ : 0;
3119
3120#ifdef AHC_DEBUG
3121 if (ahc_debug & AHC_SHOW_DV) {
3122 ahc_print_devinfo(ahc, devinfo);
3123 printf("Sending SU\n");
3124 }
3125#endif
3126 ahc_linux_dv_fill_cmd(ahc, cmd, devinfo);
3127 cmd->sc_data_direction = SCSI_DATA_NONE;
3128 cmd->cmd_len = 6;
3129 cmd->cmnd[0] = START_STOP_UNIT;
3130 cmd->cmnd[4] = le | SSS_START;
3131}
3132
3133static int
3134ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3135{
3136 struct ahc_linux_target *targ;
3137 struct ahc_initiator_tinfo *tinfo;
3138 struct ahc_transinfo *goal;
3139 struct ahc_tmode_tstate *tstate;
3140 struct ahc_syncrate *syncrate;
3141 u_long s;
3142 u_int width;
3143 u_int period;
3144 u_int offset;
3145 u_int ppr_options;
3146 u_int cur_speed;
3147 u_int wide_speed;
3148 u_int narrow_speed;
3149 u_int fallback_speed;
3150
3151#ifdef AHC_DEBUG
3152 if (ahc_debug & AHC_SHOW_DV) {
3153 ahc_print_devinfo(ahc, devinfo);
3154 printf("Trying to fallback\n");
3155 }
3156#endif
3157 ahc_lock(ahc, &s);
3158 targ = ahc->platform_data->targets[devinfo->target_offset];
3159 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
3160 devinfo->our_scsiid,
3161 devinfo->target, &tstate);
3162 goal = &tinfo->goal;
3163 width = goal->width;
3164 period = goal->period;
3165 offset = goal->offset;
3166 ppr_options = goal->ppr_options;
3167 if (offset == 0)
3168 period = AHC_ASYNC_XFER_PERIOD;
3169 if (targ->dv_next_narrow_period == 0)
3170 targ->dv_next_narrow_period = MAX(period, AHC_SYNCRATE_ULTRA2);
3171 if (targ->dv_next_wide_period == 0)
3172 targ->dv_next_wide_period = period;
3173 if (targ->dv_max_width == 0)
3174 targ->dv_max_width = width;
3175 if (targ->dv_max_ppr_options == 0)
3176 targ->dv_max_ppr_options = ppr_options;
3177 if (targ->dv_last_ppr_options == 0)
3178 targ->dv_last_ppr_options = ppr_options;
3179
3180 cur_speed = aic_calc_speed(width, period, offset, AHC_SYNCRATE_MIN);
3181 wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT,
3182 targ->dv_next_wide_period,
3183 MAX_OFFSET,
3184 AHC_SYNCRATE_MIN);
3185 narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT,
3186 targ->dv_next_narrow_period,
3187 MAX_OFFSET,
3188 AHC_SYNCRATE_MIN);
3189 fallback_speed = aic_calc_speed(width, period+1, offset,
3190 AHC_SYNCRATE_MIN);
3191#ifdef AHC_DEBUG
3192 if (ahc_debug & AHC_SHOW_DV) {
3193 printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, "
3194 "fallback_speed= %d\n", cur_speed, wide_speed,
3195 narrow_speed, fallback_speed);
3196 }
3197#endif
3198
3199 if (cur_speed > 160000) {
3200 /*
3201 * Paced/DT/IU_REQ only transfer speeds. All we
3202 * can do is fallback in terms of syncrate.
3203 */
3204 period++;
3205 } else if (cur_speed > 80000) {
3206 if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
3207 /*
3208 * Try without IU_REQ as it may be confusing
3209 * an expander.
3210 */
3211 ppr_options &= ~MSG_EXT_PPR_IU_REQ;
3212 } else {
3213 /*
3214 * Paced/DT only transfer speeds. All we
3215 * can do is fallback in terms of syncrate.
3216 */
3217 period++;
3218 ppr_options = targ->dv_max_ppr_options;
3219 }
3220 } else if (cur_speed > 3300) {
3221
3222 /*
3223 * In this range we the following
3224 * options ordered from highest to
3225 * lowest desireability:
3226 *
3227 * o Wide/DT
3228 * o Wide/non-DT
3229 * o Narrow at a potentally higher sync rate.
3230 *
3231 * All modes are tested with and without IU_REQ
3232 * set since using IUs may confuse an expander.
3233 */
3234 if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
3235
3236 ppr_options &= ~MSG_EXT_PPR_IU_REQ;
3237 } else if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
3238 /*
3239 * Try going non-DT.
3240 */
3241 ppr_options = targ->dv_max_ppr_options;
3242 ppr_options &= ~MSG_EXT_PPR_DT_REQ;
3243 } else if (targ->dv_last_ppr_options != 0) {
3244 /*
3245 * Try without QAS or any other PPR options.
3246 * We may need a non-PPR message to work with
3247 * an expander. We look at the "last PPR options"
3248 * so we will perform this fallback even if the
3249 * target responded to our PPR negotiation with
3250 * no option bits set.
3251 */
3252 ppr_options = 0;
3253 } else if (width == MSG_EXT_WDTR_BUS_16_BIT) {
3254 /*
3255 * If the next narrow speed is greater than
3256 * the next wide speed, fallback to narrow.
3257 * Otherwise fallback to the next DT/Wide setting.
3258 * The narrow async speed will always be smaller
3259 * than the wide async speed, so handle this case
3260 * specifically.
3261 */
3262 ppr_options = targ->dv_max_ppr_options;
3263 if (narrow_speed > fallback_speed
3264 || period >= AHC_ASYNC_XFER_PERIOD) {
3265 targ->dv_next_wide_period = period+1;
3266 width = MSG_EXT_WDTR_BUS_8_BIT;
3267 period = targ->dv_next_narrow_period;
3268 } else {
3269 period++;
3270 }
3271 } else if ((ahc->features & AHC_WIDE) != 0
3272 && targ->dv_max_width != 0
3273 && wide_speed >= fallback_speed
3274 && (targ->dv_next_wide_period <= AHC_ASYNC_XFER_PERIOD
3275 || period >= AHC_ASYNC_XFER_PERIOD)) {
3276
3277 /*
3278 * We are narrow. Try falling back
3279 * to the next wide speed with
3280 * all supported ppr options set.
3281 */
3282 targ->dv_next_narrow_period = period+1;
3283 width = MSG_EXT_WDTR_BUS_16_BIT;
3284 period = targ->dv_next_wide_period;
3285 ppr_options = targ->dv_max_ppr_options;
3286 } else {
3287 /* Only narrow fallback is allowed. */
3288 period++;
3289 ppr_options = targ->dv_max_ppr_options;
3290 }
3291 } else {
3292 ahc_unlock(ahc, &s);
3293 return (-1);
3294 }
3295 offset = MAX_OFFSET;
3296 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
3297 AHC_SYNCRATE_DT);
3298 ahc_set_width(ahc, devinfo, width, AHC_TRANS_GOAL, FALSE);
3299 if (period == 0) {
3300 period = 0;
3301 offset = 0;
3302 ppr_options = 0;
3303 if (width == MSG_EXT_WDTR_BUS_8_BIT)
3304 targ->dv_next_narrow_period = AHC_ASYNC_XFER_PERIOD;
3305 else
3306 targ->dv_next_wide_period = AHC_ASYNC_XFER_PERIOD;
3307 }
3308 ahc_set_syncrate(ahc, devinfo, syncrate, period, offset,
3309 ppr_options, AHC_TRANS_GOAL, FALSE);
3310 targ->dv_last_ppr_options = ppr_options;
3311 ahc_unlock(ahc, &s);
3312 return (0);
3313}
3314
3315static void
3316ahc_linux_dv_timeout(struct scsi_cmnd *cmd)
3317{
3318 struct ahc_softc *ahc;
3319 struct scb *scb;
3320 u_long flags;
3321
3322 ahc = *((struct ahc_softc **)cmd->device->host->hostdata);
3323 ahc_lock(ahc, &flags);
3324
3325#ifdef AHC_DEBUG
3326 if (ahc_debug & AHC_SHOW_DV) {
3327 printf("%s: Timeout while doing DV command %x.\n",
3328 ahc_name(ahc), cmd->cmnd[0]);
3329 ahc_dump_card_state(ahc);
3330 }
3331#endif
3332
3333 /*
3334 * Guard against "done race". No action is
3335 * required if we just completed.
3336 */
3337 if ((scb = (struct scb *)cmd->host_scribble) == NULL) {
3338 ahc_unlock(ahc, &flags);
3339 return;
3340 }
3341
3342 /*
3343 * Command has not completed. Mark this
3344 * SCB as having failing status prior to
3345 * resetting the bus, so we get the correct
3346 * error code.
3347 */
3348 if ((scb->flags & SCB_SENSE) != 0)
3349 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
3350 else
3351 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
3352 ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate*/TRUE);
3353
3354 /*
3355 * Add a minimal bus settle delay for devices that are slow to
3356 * respond after bus resets.
3357 */
3358 ahc_linux_freeze_simq(ahc);
3359 init_timer(&ahc->platform_data->reset_timer);
3360 ahc->platform_data->reset_timer.data = (u_long)ahc;
3361 ahc->platform_data->reset_timer.expires = jiffies + HZ / 2;
3362 ahc->platform_data->reset_timer.function =
3363 (ahc_linux_callback_t *)ahc_linux_release_simq;
3364 add_timer(&ahc->platform_data->reset_timer);
3365 if (ahc_linux_next_device_to_run(ahc) != NULL)
3366 ahc_schedule_runq(ahc);
3367 ahc_linux_run_complete_queue(ahc);
3368 ahc_unlock(ahc, &flags);
3369}
3370
3371static void
3372ahc_linux_dv_complete(struct scsi_cmnd *cmd)
3373{
3374 struct ahc_softc *ahc;
3375
3376 ahc = *((struct ahc_softc **)cmd->device->host->hostdata);
3377
3378 /* Delete the DV timer before it goes off! */
3379 scsi_delete_timer(cmd);
3380
3381#ifdef AHC_DEBUG
3382 if (ahc_debug & AHC_SHOW_DV)
3383 printf("%s:%d:%d: Command completed, status= 0x%x\n",
3384 ahc_name(ahc), cmd->device->channel,
3385 cmd->device->id, cmd->result);
3386#endif
3387
3388 /* Wake up the state machine */
3389 up(&ahc->platform_data->dv_cmd_sem);
3390}
3391
3392static void
3393ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ)
3394{
3395 uint16_t b;
3396 u_int i;
3397 u_int j;
3398
3399 if (targ->dv_buffer != NULL)
3400 free(targ->dv_buffer, M_DEVBUF);
3401 targ->dv_buffer = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK);
3402 if (targ->dv_buffer1 != NULL)
3403 free(targ->dv_buffer1, M_DEVBUF);
3404 targ->dv_buffer1 = malloc(targ->dv_echo_size, M_DEVBUF, M_WAITOK);
3405
3406 i = 0;
3407 b = 0x0001;
3408 for (j = 0 ; i < targ->dv_echo_size; j++) {
3409 if (j < 32) {
3410 /*
3411 * 32bytes of sequential numbers.
3412 */
3413 targ->dv_buffer[i++] = j & 0xff;
3414 } else if (j < 48) {
3415 /*
3416 * 32bytes of repeating 0x0000, 0xffff.
3417 */
3418 targ->dv_buffer[i++] = (j & 0x02) ? 0xff : 0x00;
3419 } else if (j < 64) {
3420 /*
3421 * 32bytes of repeating 0x5555, 0xaaaa.
3422 */
3423 targ->dv_buffer[i++] = (j & 0x02) ? 0xaa : 0x55;
3424 } else {
3425 /*
3426 * Remaining buffer is filled with a repeating
3427 * patter of:
3428 *
3429 * 0xffff
3430 * ~0x0001 << shifted once in each loop.
3431 */
3432 if (j & 0x02) {
3433 if (j & 0x01) {
3434 targ->dv_buffer[i++] = ~(b >> 8) & 0xff;
3435 b <<= 1;
3436 if (b == 0x0000)
3437 b = 0x0001;
3438 } else {
3439 targ->dv_buffer[i++] = (~b & 0xff);
3440 }
3441 } else {
3442 targ->dv_buffer[i++] = 0xff;
3443 }
3444 }
3445 }
3446}
3447
3448static u_int
3449ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3450{
3451 static int warned_user;
3452 u_int tags;
3453
3454 tags = 0;
3455 if ((ahc->user_discenable & devinfo->target_mask) != 0) {
3456 if (ahc->unit >= NUM_ELEMENTS(aic7xxx_tag_info)) {
3457 if (warned_user == 0) {
3458
3459 printf(KERN_WARNING
3460"aic7xxx: WARNING: Insufficient tag_info instances\n"
3461"aic7xxx: for installed controllers. Using defaults\n"
3462"aic7xxx: Please update the aic7xxx_tag_info array in\n"
3463"aic7xxx: the aic7xxx_osm..c source file.\n");
3464 warned_user++;
3465 }
3466 tags = AHC_MAX_QUEUE;
3467 } else {
3468 adapter_tag_info_t *tag_info;
3469
3470 tag_info = &aic7xxx_tag_info[ahc->unit];
3471 tags = tag_info->tag_commands[devinfo->target_offset];
3472 if (tags > AHC_MAX_QUEUE)
3473 tags = AHC_MAX_QUEUE;
3474 }
3475 }
3476 return (tags);
3477}
3478
3479static u_int
3480ahc_linux_user_dv_setting(struct ahc_softc *ahc)
3481{
3482 static int warned_user;
3483 int dv;
3484
3485 if (ahc->unit >= NUM_ELEMENTS(aic7xxx_dv_settings)) {
3486 if (warned_user == 0) {
3487
3488 printf(KERN_WARNING
3489"aic7xxx: WARNING: Insufficient dv settings instances\n"
3490"aic7xxx: for installed controllers. Using defaults\n"
3491"aic7xxx: Please update the aic7xxx_dv_settings array\n"
3492"aic7xxx: in the aic7xxx_osm.c source file.\n");
3493 warned_user++;
3494 }
3495 dv = -1;
3496 } else {
3497
3498 dv = aic7xxx_dv_settings[ahc->unit];
3499 }
3500
3501 if (dv < 0) {
3502 u_long s;
3503
3504 /*
3505 * Apply the default.
3506 */
3507 /*
3508 * XXX - Enable DV on non-U160 controllers once it
3509 * has been tested there.
3510 */
3511 ahc_lock(ahc, &s);
3512 dv = (ahc->features & AHC_DT);
3513 if (ahc->seep_config != 0
3514 && ahc->seep_config->signature >= CFSIGNATURE2)
3515 dv = (ahc->seep_config->adapter_control & CFENABLEDV);
3516 ahc_unlock(ahc, &s);
3517 }
3518 return (dv);
3519}
3520
3521/*
3522 * Determines the queue depth for a given device.
3523 */
3524static void
3525ahc_linux_device_queue_depth(struct ahc_softc *ahc,
3526 struct ahc_linux_device *dev)
3527{
3528 struct ahc_devinfo devinfo;
3529 u_int tags;
3530
3531 ahc_compile_devinfo(&devinfo,
3532 dev->target->channel == 0
3533 ? ahc->our_id : ahc->our_id_b,
3534 dev->target->target, dev->lun,
3535 dev->target->channel == 0 ? 'A' : 'B',
3536 ROLE_INITIATOR);
3537 tags = ahc_linux_user_tagdepth(ahc, &devinfo);
3538 if (tags != 0
3539 && dev->scsi_device != NULL
3540 && dev->scsi_device->tagged_supported != 0) {
3541
3542 ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED);
3543 ahc_print_devinfo(ahc, &devinfo);
3544 printf("Tagged Queuing enabled. Depth %d\n", tags);
3545 } else {
3546 ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE);
3547 }
3548}
3549
3550static void
3551ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
3552{
3553 struct ahc_cmd *acmd;
3554 struct scsi_cmnd *cmd;
3555 struct scb *scb;
3556 struct hardware_scb *hscb;
3557 struct ahc_initiator_tinfo *tinfo;
3558 struct ahc_tmode_tstate *tstate;
3559 uint16_t mask;
3560
3561 if ((dev->flags & AHC_DEV_ON_RUN_LIST) != 0)
3562 panic("running device on run list");
3563
3564 while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL
3565 && dev->openings > 0 && dev->qfrozen == 0) {
3566
3567 /*
3568 * Schedule us to run later. The only reason we are not
3569 * running is because the whole controller Q is frozen.
3570 */
3571 if (ahc->platform_data->qfrozen != 0
3572 && AHC_DV_SIMQ_FROZEN(ahc) == 0) {
3573 TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
3574 dev, links);
3575 dev->flags |= AHC_DEV_ON_RUN_LIST;
3576 return;
3577 }
3578 /*
3579 * Get an scb to use.
3580 */
3581 if ((scb = ahc_get_scb(ahc)) == NULL) {
3582 TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
3583 dev, links);
3584 dev->flags |= AHC_DEV_ON_RUN_LIST;
3585 ahc->flags |= AHC_RESOURCE_SHORTAGE;
3586 return;
3587 }
3588 TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe);
3589 cmd = &acmd_scsi_cmd(acmd);
3590 scb->io_ctx = cmd;
3591 scb->platform_data->dev = dev;
3592 hscb = scb->hscb;
3593 cmd->host_scribble = (char *)scb;
3594
3595 /*
3596 * Fill out basics of the HSCB.
3597 */
3598 hscb->control = 0;
3599 hscb->scsiid = BUILD_SCSIID(ahc, cmd);
3600 hscb->lun = cmd->device->lun;
3601 mask = SCB_GET_TARGET_MASK(ahc, scb);
3602 tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
3603 SCB_GET_OUR_ID(scb),
3604 SCB_GET_TARGET(ahc, scb), &tstate);
3605 hscb->scsirate = tinfo->scsirate;
3606 hscb->scsioffset = tinfo->curr.offset;
3607 if ((tstate->ultraenb & mask) != 0)
3608 hscb->control |= ULTRAENB;
3609
3610 if ((ahc->user_discenable & mask) != 0)
3611 hscb->control |= DISCENB;
3612
3613 if (AHC_DV_CMD(cmd) != 0)
3614 scb->flags |= SCB_SILENT;
3615
3616 if ((tstate->auto_negotiate & mask) != 0) {
3617 scb->flags |= SCB_AUTO_NEGOTIATE;
3618 scb->hscb->control |= MK_MESSAGE;
3619 }
3620
3621 if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
3622#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
3623 int msg_bytes;
3624 uint8_t tag_msgs[2];
3625
3626 msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs);
3627 if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) {
3628 hscb->control |= tag_msgs[0];
3629 if (tag_msgs[0] == MSG_ORDERED_TASK)
3630 dev->commands_since_idle_or_otag = 0;
3631 } else
3632#endif
3633 if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
3634 && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
3635 hscb->control |= MSG_ORDERED_TASK;
3636 dev->commands_since_idle_or_otag = 0;
3637 } else {
3638 hscb->control |= MSG_SIMPLE_TASK;
3639 }
3640 }
3641
3642 hscb->cdb_len = cmd->cmd_len;
3643 if (hscb->cdb_len <= 12) {
3644 memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
3645 } else {
3646 memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
3647 scb->flags |= SCB_CDB32_PTR;
3648 }
3649
3650 scb->platform_data->xfer_len = 0;
3651 ahc_set_residual(scb, 0);
3652 ahc_set_sense_residual(scb, 0);
3653 scb->sg_count = 0;
3654 if (cmd->use_sg != 0) {
3655 struct ahc_dma_seg *sg;
3656 struct scatterlist *cur_seg;
3657 struct scatterlist *end_seg;
3658 int nseg;
3659
3660 cur_seg = (struct scatterlist *)cmd->request_buffer;
3661 nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
3662 scsi_to_pci_dma_dir(cmd->sc_data_direction));
3663 end_seg = cur_seg + nseg;
3664 /* Copy the segments into the SG list. */
3665 sg = scb->sg_list;
3666 /*
3667 * The sg_count may be larger than nseg if
3668 * a transfer crosses a 32bit page.
3669 */
3670 while (cur_seg < end_seg) {
3671 dma_addr_t addr;
3672 bus_size_t len;
3673 int consumed;
3674
3675 addr = sg_dma_address(cur_seg);
3676 len = sg_dma_len(cur_seg);
3677 consumed = ahc_linux_map_seg(ahc, scb,
3678 sg, addr, len);
3679 sg += consumed;
3680 scb->sg_count += consumed;
3681 cur_seg++;
3682 }
3683 sg--;
3684 sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
3685
3686 /*
3687 * Reset the sg list pointer.
3688 */
3689 scb->hscb->sgptr =
3690 ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
3691
3692 /*
3693 * Copy the first SG into the "current"
3694 * data pointer area.
3695 */
3696 scb->hscb->dataptr = scb->sg_list->addr;
3697 scb->hscb->datacnt = scb->sg_list->len;
3698 } else if (cmd->request_bufflen != 0) {
3699 struct ahc_dma_seg *sg;
3700 dma_addr_t addr;
3701
3702 sg = scb->sg_list;
3703 addr = pci_map_single(ahc->dev_softc,
3704 cmd->request_buffer,
3705 cmd->request_bufflen,
3706 scsi_to_pci_dma_dir(cmd->sc_data_direction));
3707 scb->platform_data->buf_busaddr = addr;
3708 scb->sg_count = ahc_linux_map_seg(ahc, scb,
3709 sg, addr,
3710 cmd->request_bufflen);
3711 sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
3712
3713 /*
3714 * Reset the sg list pointer.
3715 */
3716 scb->hscb->sgptr =
3717 ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
3718
3719 /*
3720 * Copy the first SG into the "current"
3721 * data pointer area.
3722 */
3723 scb->hscb->dataptr = sg->addr;
3724 scb->hscb->datacnt = sg->len;
3725 } else {
3726 scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
3727 scb->hscb->dataptr = 0;
3728 scb->hscb->datacnt = 0;
3729 scb->sg_count = 0;
3730 }
3731
3732 ahc_sync_sglist(ahc, scb, BUS_DMASYNC_PREWRITE);
3733 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
3734 dev->openings--;
3735 dev->active++;
3736 dev->commands_issued++;
3737 if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
3738 dev->commands_since_idle_or_otag++;
3739
3740 /*
3741 * We only allow one untagged transaction
3742 * per target in the initiator role unless
3743 * we are storing a full busy target *lun*
3744 * table in SCB space.
3745 */
3746 if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0
3747 && (ahc->features & AHC_SCB_BTT) == 0) {
3748 struct scb_tailq *untagged_q;
3749 int target_offset;
3750
3751 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
3752 untagged_q = &(ahc->untagged_queues[target_offset]);
3753 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
3754 scb->flags |= SCB_UNTAGGEDQ;
3755 if (TAILQ_FIRST(untagged_q) != scb)
3756 continue;
3757 }
3758 scb->flags |= SCB_ACTIVE;
3759 ahc_queue_scb(ahc, scb);
3760 }
3761}
3762
3763/*
3764 * SCSI controller interrupt handler.
3765 */
3766irqreturn_t
3767ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
3768{
3769 struct ahc_softc *ahc;
3770 u_long flags;
3771 int ours;
3772
3773 ahc = (struct ahc_softc *) dev_id;
3774 ahc_lock(ahc, &flags);
3775 ours = ahc_intr(ahc);
3776 if (ahc_linux_next_device_to_run(ahc) != NULL)
3777 ahc_schedule_runq(ahc);
3778 ahc_linux_run_complete_queue(ahc);
3779 ahc_unlock(ahc, &flags);
3780 return IRQ_RETVAL(ours);
3781}
3782
3783void
3784ahc_platform_flushwork(struct ahc_softc *ahc)
3785{
3786
3787 while (ahc_linux_run_complete_queue(ahc) != NULL)
3788 ;
3789}
3790
3791static struct ahc_linux_target*
3792ahc_linux_alloc_target(struct ahc_softc *ahc, u_int channel, u_int target)
3793{
3794 struct ahc_linux_target *targ;
3795 u_int target_offset;
3796
3797 target_offset = target;
3798 if (channel != 0)
3799 target_offset += 8;
3800
3801 targ = malloc(sizeof(*targ), M_DEVBUG, M_NOWAIT);
3802 if (targ == NULL)
3803 return (NULL);
3804 memset(targ, 0, sizeof(*targ));
3805 targ->channel = channel;
3806 targ->target = target;
3807 targ->ahc = ahc;
3808 targ->flags = AHC_DV_REQUIRED;
3809 ahc->platform_data->targets[target_offset] = targ;
3810 return (targ);
3811}
3812
3813static void
3814ahc_linux_free_target(struct ahc_softc *ahc, struct ahc_linux_target *targ)
3815{
3816 struct ahc_devinfo devinfo;
3817 struct ahc_initiator_tinfo *tinfo;
3818 struct ahc_tmode_tstate *tstate;
3819 u_int our_id;
3820 u_int target_offset;
3821 char channel;
3822
3823 /*
3824 * Force a negotiation to async/narrow on any
3825 * future command to this device unless a bus
3826 * reset occurs between now and that command.
3827 */
3828 channel = 'A' + targ->channel;
3829 our_id = ahc->our_id;
3830 target_offset = targ->target;
3831 if (targ->channel != 0) {
3832 target_offset += 8;
3833 our_id = ahc->our_id_b;
3834 }
3835 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
3836 targ->target, &tstate);
3837 ahc_compile_devinfo(&devinfo, our_id, targ->target, CAM_LUN_WILDCARD,
3838 channel, ROLE_INITIATOR);
3839 ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
3840 AHC_TRANS_GOAL, /*paused*/FALSE);
3841 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
3842 AHC_TRANS_GOAL, /*paused*/FALSE);
3843 ahc_update_neg_request(ahc, &devinfo, tstate, tinfo, AHC_NEG_ALWAYS);
3844 ahc->platform_data->targets[target_offset] = NULL;
3845 if (targ->inq_data != NULL)
3846 free(targ->inq_data, M_DEVBUF);
3847 if (targ->dv_buffer != NULL)
3848 free(targ->dv_buffer, M_DEVBUF);
3849 if (targ->dv_buffer1 != NULL)
3850 free(targ->dv_buffer1, M_DEVBUF);
3851 free(targ, M_DEVBUF);
3852}
3853
3854static struct ahc_linux_device*
3855ahc_linux_alloc_device(struct ahc_softc *ahc,
3856 struct ahc_linux_target *targ, u_int lun)
3857{
3858 struct ahc_linux_device *dev;
3859
3860 dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT);
3861 if (dev == NULL)
3862 return (NULL);
3863 memset(dev, 0, sizeof(*dev));
3864 init_timer(&dev->timer);
3865 TAILQ_INIT(&dev->busyq);
3866 dev->flags = AHC_DEV_UNCONFIGURED;
3867 dev->lun = lun;
3868 dev->target = targ;
3869
3870 /*
3871 * We start out life using untagged
3872 * transactions of which we allow one.
3873 */
3874 dev->openings = 1;
3875
3876 /*
3877 * Set maxtags to 0. This will be changed if we
3878 * later determine that we are dealing with
3879 * a tagged queuing capable device.
3880 */
3881 dev->maxtags = 0;
3882
3883 targ->refcount++;
3884 targ->devices[lun] = dev;
3885 return (dev);
3886}
3887
3888static void
3889__ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
3890{
3891 struct ahc_linux_target *targ;
3892
3893 targ = dev->target;
3894 targ->devices[dev->lun] = NULL;
3895 free(dev, M_DEVBUF);
3896 targ->refcount--;
3897 if (targ->refcount == 0
3898 && (targ->flags & AHC_DV_REQUIRED) == 0)
3899 ahc_linux_free_target(ahc, targ);
3900}
3901
3902static void
3903ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
3904{
3905 del_timer_sync(&dev->timer);
3906 __ahc_linux_free_device(ahc, dev);
3907}
3908
3909void
3910ahc_send_async(struct ahc_softc *ahc, char channel,
3911 u_int target, u_int lun, ac_code code, void *arg)
3912{
3913 switch (code) {
3914 case AC_TRANSFER_NEG:
3915 {
3916 char buf[80];
3917 struct ahc_linux_target *targ;
3918 struct info_str info;
3919 struct ahc_initiator_tinfo *tinfo;
3920 struct ahc_tmode_tstate *tstate;
3921 int target_offset;
3922
3923 info.buffer = buf;
3924 info.length = sizeof(buf);
3925 info.offset = 0;
3926 info.pos = 0;
3927 tinfo = ahc_fetch_transinfo(ahc, channel,
3928 channel == 'A' ? ahc->our_id
3929 : ahc->our_id_b,
3930 target, &tstate);
3931
3932 /*
3933 * Don't bother reporting results while
3934 * negotiations are still pending.
3935 */
3936 if (tinfo->curr.period != tinfo->goal.period
3937 || tinfo->curr.width != tinfo->goal.width
3938 || tinfo->curr.offset != tinfo->goal.offset
3939 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
3940 if (bootverbose == 0)
3941 break;
3942
3943 /*
3944 * Don't bother reporting results that
3945 * are identical to those last reported.
3946 */
3947 target_offset = target;
3948 if (channel == 'B')
3949 target_offset += 8;
3950 targ = ahc->platform_data->targets[target_offset];
3951 if (targ == NULL)
3952 break;
3953 if (tinfo->curr.period == targ->last_tinfo.period
3954 && tinfo->curr.width == targ->last_tinfo.width
3955 && tinfo->curr.offset == targ->last_tinfo.offset
3956 && tinfo->curr.ppr_options == targ->last_tinfo.ppr_options)
3957 if (bootverbose == 0)
3958 break;
3959
3960 targ->last_tinfo.period = tinfo->curr.period;
3961 targ->last_tinfo.width = tinfo->curr.width;
3962 targ->last_tinfo.offset = tinfo->curr.offset;
3963 targ->last_tinfo.ppr_options = tinfo->curr.ppr_options;
3964
3965 printf("(%s:%c:", ahc_name(ahc), channel);
3966 if (target == CAM_TARGET_WILDCARD)
3967 printf("*): ");
3968 else
3969 printf("%d): ", target);
3970 ahc_format_transinfo(&info, &tinfo->curr);
3971 if (info.pos < info.length)
3972 *info.buffer = '\0';
3973 else
3974 buf[info.length - 1] = '\0';
3975 printf("%s", buf);
3976 break;
3977 }
3978 case AC_SENT_BDR:
3979 {
3980#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
3981 WARN_ON(lun != CAM_LUN_WILDCARD);
3982 scsi_report_device_reset(ahc->platform_data->host,
3983 channel - 'A', target);
3984#else
3985 Scsi_Device *scsi_dev;
3986
3987 /*
3988 * Find the SCSI device associated with this
3989 * request and indicate that a UA is expected.
3990 */
3991 for (scsi_dev = ahc->platform_data->host->host_queue;
3992 scsi_dev != NULL; scsi_dev = scsi_dev->next) {
3993 if (channel - 'A' == scsi_dev->channel
3994 && target == scsi_dev->id
3995 && (lun == CAM_LUN_WILDCARD
3996 || lun == scsi_dev->lun)) {
3997 scsi_dev->was_reset = 1;
3998 scsi_dev->expecting_cc_ua = 1;
3999 }
4000 }
4001#endif
4002 break;
4003 }
4004 case AC_BUS_RESET:
4005 if (ahc->platform_data->host != NULL) {
4006 scsi_report_bus_reset(ahc->platform_data->host,
4007 channel - 'A');
4008 }
4009 break;
4010 default:
4011 panic("ahc_send_async: Unexpected async event");
4012 }
4013}
4014
4015/*
4016 * Calls the higher level scsi done function and frees the scb.
4017 */
4018void
4019ahc_done(struct ahc_softc *ahc, struct scb *scb)
4020{
4021 Scsi_Cmnd *cmd;
4022 struct ahc_linux_device *dev;
4023
4024 LIST_REMOVE(scb, pending_links);
4025 if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
4026 struct scb_tailq *untagged_q;
4027 int target_offset;
4028
4029 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
4030 untagged_q = &(ahc->untagged_queues[target_offset]);
4031 TAILQ_REMOVE(untagged_q, scb, links.tqe);
4032 ahc_run_untagged_queue(ahc, untagged_q);
4033 }
4034
4035 if ((scb->flags & SCB_ACTIVE) == 0) {
4036 printf("SCB %d done'd twice\n", scb->hscb->tag);
4037 ahc_dump_card_state(ahc);
4038 panic("Stopping for safety");
4039 }
4040 cmd = scb->io_ctx;
4041 dev = scb->platform_data->dev;
4042 dev->active--;
4043 dev->openings++;
4044 if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
4045 cmd->result &= ~(CAM_DEV_QFRZN << 16);
4046 dev->qfrozen--;
4047 }
4048 ahc_linux_unmap_scb(ahc, scb);
4049
4050 /*
4051 * Guard against stale sense data.
4052 * The Linux mid-layer assumes that sense
4053 * was retrieved anytime the first byte of
4054 * the sense buffer looks "sane".
4055 */
4056 cmd->sense_buffer[0] = 0;
4057 if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) {
4058 uint32_t amount_xferred;
4059
4060 amount_xferred =
4061 ahc_get_transfer_length(scb) - ahc_get_residual(scb);
4062 if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
4063#ifdef AHC_DEBUG
4064 if ((ahc_debug & AHC_SHOW_MISC) != 0) {
4065 ahc_print_path(ahc, scb);
4066 printf("Set CAM_UNCOR_PARITY\n");
4067 }
4068#endif
4069 ahc_set_transaction_status(scb, CAM_UNCOR_PARITY);
4070#ifdef AHC_REPORT_UNDERFLOWS
4071 /*
4072 * This code is disabled by default as some
4073 * clients of the SCSI system do not properly
4074 * initialize the underflow parameter. This
4075 * results in spurious termination of commands
4076 * that complete as expected (e.g. underflow is
4077 * allowed as command can return variable amounts
4078 * of data.
4079 */
4080 } else if (amount_xferred < scb->io_ctx->underflow) {
4081 u_int i;
4082
4083 ahc_print_path(ahc, scb);
4084 printf("CDB:");
4085 for (i = 0; i < scb->io_ctx->cmd_len; i++)
4086 printf(" 0x%x", scb->io_ctx->cmnd[i]);
4087 printf("\n");
4088 ahc_print_path(ahc, scb);
4089 printf("Saw underflow (%ld of %ld bytes). "
4090 "Treated as error\n",
4091 ahc_get_residual(scb),
4092 ahc_get_transfer_length(scb));
4093 ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
4094#endif
4095 } else {
4096 ahc_set_transaction_status(scb, CAM_REQ_CMP);
4097 }
4098 } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
4099 ahc_linux_handle_scsi_status(ahc, dev, scb);
4100 } else if (ahc_get_transaction_status(scb) == CAM_SEL_TIMEOUT) {
4101 dev->flags |= AHC_DEV_UNCONFIGURED;
4102 if (AHC_DV_CMD(cmd) == FALSE)
4103 dev->target->flags &= ~AHC_DV_REQUIRED;
4104 }
4105 /*
4106 * Start DV for devices that require it assuming the first command
4107 * sent does not result in a selection timeout.
4108 */
4109 if (ahc_get_transaction_status(scb) != CAM_SEL_TIMEOUT
4110 && (dev->target->flags & AHC_DV_REQUIRED) != 0)
4111 ahc_linux_start_dv(ahc);
4112
4113 if (dev->openings == 1
4114 && ahc_get_transaction_status(scb) == CAM_REQ_CMP
4115 && ahc_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
4116 dev->tag_success_count++;
4117 /*
4118 * Some devices deal with temporary internal resource
4119 * shortages by returning queue full. When the queue
4120 * full occurrs, we throttle back. Slowly try to get
4121 * back to our previous queue depth.
4122 */
4123 if ((dev->openings + dev->active) < dev->maxtags
4124 && dev->tag_success_count > AHC_TAG_SUCCESS_INTERVAL) {
4125 dev->tag_success_count = 0;
4126 dev->openings++;
4127 }
4128
4129 if (dev->active == 0)
4130 dev->commands_since_idle_or_otag = 0;
4131
4132 if (TAILQ_EMPTY(&dev->busyq)) {
4133 if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0
4134 && dev->active == 0
4135 && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0)
4136 ahc_linux_free_device(ahc, dev);
4137 } else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
4138 TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
4139 dev->flags |= AHC_DEV_ON_RUN_LIST;
4140 }
4141
4142 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
4143 printf("Recovery SCB completes\n");
4144 if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
4145 || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
4146 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
4147 if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
4148 ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
4149 up(&ahc->platform_data->eh_sem);
4150 }
4151 }
4152
4153 ahc_free_scb(ahc, scb);
4154 ahc_linux_queue_cmd_complete(ahc, cmd);
4155
4156 if ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_EMPTY) != 0
4157 && LIST_FIRST(&ahc->pending_scbs) == NULL) {
4158 ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_EMPTY;
4159 up(&ahc->platform_data->dv_sem);
4160 }
4161
4162}
4163
4164static void
4165ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
4166 struct ahc_linux_device *dev, struct scb *scb)
4167{
4168 struct ahc_devinfo devinfo;
4169
4170 ahc_compile_devinfo(&devinfo,
4171 ahc->our_id,
4172 dev->target->target, dev->lun,
4173 dev->target->channel == 0 ? 'A' : 'B',
4174 ROLE_INITIATOR);
4175
4176 /*
4177 * We don't currently trust the mid-layer to
4178 * properly deal with queue full or busy. So,
4179 * when one occurs, we tell the mid-layer to
4180 * unconditionally requeue the command to us
4181 * so that we can retry it ourselves. We also
4182 * implement our own throttling mechanism so
4183 * we don't clobber the device with too many
4184 * commands.
4185 */
4186 switch (ahc_get_scsi_status(scb)) {
4187 default:
4188 break;
4189 case SCSI_STATUS_CHECK_COND:
4190 case SCSI_STATUS_CMD_TERMINATED:
4191 {
4192 Scsi_Cmnd *cmd;
4193
4194 /*
4195 * Copy sense information to the OS's cmd
4196 * structure if it is available.
4197 */
4198 cmd = scb->io_ctx;
4199 if (scb->flags & SCB_SENSE) {
4200 u_int sense_size;
4201
4202 sense_size = MIN(sizeof(struct scsi_sense_data)
4203 - ahc_get_sense_residual(scb),
4204 sizeof(cmd->sense_buffer));
4205 memcpy(cmd->sense_buffer,
4206 ahc_get_sense_buf(ahc, scb), sense_size);
4207 if (sense_size < sizeof(cmd->sense_buffer))
4208 memset(&cmd->sense_buffer[sense_size], 0,
4209 sizeof(cmd->sense_buffer) - sense_size);
4210 cmd->result |= (DRIVER_SENSE << 24);
4211#ifdef AHC_DEBUG
4212 if (ahc_debug & AHC_SHOW_SENSE) {
4213 int i;
4214
4215 printf("Copied %d bytes of sense data:",
4216 sense_size);
4217 for (i = 0; i < sense_size; i++) {
4218 if ((i & 0xF) == 0)
4219 printf("\n");
4220 printf("0x%x ", cmd->sense_buffer[i]);
4221 }
4222 printf("\n");
4223 }
4224#endif
4225 }
4226 break;
4227 }
4228 case SCSI_STATUS_QUEUE_FULL:
4229 {
4230 /*
4231 * By the time the core driver has returned this
4232 * command, all other commands that were queued
4233 * to us but not the device have been returned.
4234 * This ensures that dev->active is equal to
4235 * the number of commands actually queued to
4236 * the device.
4237 */
4238 dev->tag_success_count = 0;
4239 if (dev->active != 0) {
4240 /*
4241 * Drop our opening count to the number
4242 * of commands currently outstanding.
4243 */
4244 dev->openings = 0;
4245/*
4246 ahc_print_path(ahc, scb);
4247 printf("Dropping tag count to %d\n", dev->active);
4248 */
4249 if (dev->active == dev->tags_on_last_queuefull) {
4250
4251 dev->last_queuefull_same_count++;
4252 /*
4253 * If we repeatedly see a queue full
4254 * at the same queue depth, this
4255 * device has a fixed number of tag
4256 * slots. Lock in this tag depth
4257 * so we stop seeing queue fulls from
4258 * this device.
4259 */
4260 if (dev->last_queuefull_same_count
4261 == AHC_LOCK_TAGS_COUNT) {
4262 dev->maxtags = dev->active;
4263 ahc_print_path(ahc, scb);
4264 printf("Locking max tag count at %d\n",
4265 dev->active);
4266 }
4267 } else {
4268 dev->tags_on_last_queuefull = dev->active;
4269 dev->last_queuefull_same_count = 0;
4270 }
4271 ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
4272 ahc_set_scsi_status(scb, SCSI_STATUS_OK);
4273 ahc_platform_set_tags(ahc, &devinfo,
4274 (dev->flags & AHC_DEV_Q_BASIC)
4275 ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
4276 break;
4277 }
4278 /*
4279 * Drop down to a single opening, and treat this
4280 * as if the target returned BUSY SCSI status.
4281 */
4282 dev->openings = 1;
4283 ahc_set_scsi_status(scb, SCSI_STATUS_BUSY);
4284 ahc_platform_set_tags(ahc, &devinfo,
4285 (dev->flags & AHC_DEV_Q_BASIC)
4286 ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
4287 /* FALLTHROUGH */
4288 }
4289 case SCSI_STATUS_BUSY:
4290 {
4291 /*
4292 * Set a short timer to defer sending commands for
4293 * a bit since Linux will not delay in this case.
4294 */
4295 if ((dev->flags & AHC_DEV_TIMER_ACTIVE) != 0) {
4296 printf("%s:%c:%d: Device Timer still active during "
4297 "busy processing\n", ahc_name(ahc),
4298 dev->target->channel, dev->target->target);
4299 break;
4300 }
4301 dev->flags |= AHC_DEV_TIMER_ACTIVE;
4302 dev->qfrozen++;
4303 init_timer(&dev->timer);
4304 dev->timer.data = (u_long)dev;
4305 dev->timer.expires = jiffies + (HZ/2);
4306 dev->timer.function = ahc_linux_dev_timed_unfreeze;
4307 add_timer(&dev->timer);
4308 break;
4309 }
4310 }
4311}
4312
4313static void
4314ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd)
4315{
4316 /*
4317 * Typically, the complete queue has very few entries
4318 * queued to it before the queue is emptied by
4319 * ahc_linux_run_complete_queue, so sorting the entries
4320 * by generation number should be inexpensive.
4321 * We perform the sort so that commands that complete
4322 * with an error are retuned in the order origionally
4323 * queued to the controller so that any subsequent retries
4324 * are performed in order. The underlying ahc routines do
4325 * not guarantee the order that aborted commands will be
4326 * returned to us.
4327 */
4328 struct ahc_completeq *completeq;
4329 struct ahc_cmd *list_cmd;
4330 struct ahc_cmd *acmd;
4331
4332 /*
4333 * Map CAM error codes into Linux Error codes. We
4334 * avoid the conversion so that the DV code has the
4335 * full error information available when making
4336 * state change decisions.
4337 */
4338 if (AHC_DV_CMD(cmd) == FALSE) {
4339 u_int new_status;
4340
4341 switch (ahc_cmd_get_transaction_status(cmd)) {
4342 case CAM_REQ_INPROG:
4343 case CAM_REQ_CMP:
4344 case CAM_SCSI_STATUS_ERROR:
4345 new_status = DID_OK;
4346 break;
4347 case CAM_REQ_ABORTED:
4348 new_status = DID_ABORT;
4349 break;
4350 case CAM_BUSY:
4351 new_status = DID_BUS_BUSY;
4352 break;
4353 case CAM_REQ_INVALID:
4354 case CAM_PATH_INVALID:
4355 new_status = DID_BAD_TARGET;
4356 break;
4357 case CAM_SEL_TIMEOUT:
4358 new_status = DID_NO_CONNECT;
4359 break;
4360 case CAM_SCSI_BUS_RESET:
4361 case CAM_BDR_SENT:
4362 new_status = DID_RESET;
4363 break;
4364 case CAM_UNCOR_PARITY:
4365 new_status = DID_PARITY;
4366 break;
4367 case CAM_CMD_TIMEOUT:
4368 new_status = DID_TIME_OUT;
4369 break;
4370 case CAM_UA_ABORT:
4371 case CAM_REQ_CMP_ERR:
4372 case CAM_AUTOSENSE_FAIL:
4373 case CAM_NO_HBA:
4374 case CAM_DATA_RUN_ERR:
4375 case CAM_UNEXP_BUSFREE:
4376 case CAM_SEQUENCE_FAIL:
4377 case CAM_CCB_LEN_ERR:
4378 case CAM_PROVIDE_FAIL:
4379 case CAM_REQ_TERMIO:
4380 case CAM_UNREC_HBA_ERROR:
4381 case CAM_REQ_TOO_BIG:
4382 new_status = DID_ERROR;
4383 break;
4384 case CAM_REQUEUE_REQ:
4385 /*
4386 * If we want the request requeued, make sure there
4387 * are sufficent retries. In the old scsi error code,
4388 * we used to be able to specify a result code that
4389 * bypassed the retry count. Now we must use this
4390 * hack. We also "fake" a check condition with
4391 * a sense code of ABORTED COMMAND. This seems to
4392 * evoke a retry even if this command is being sent
4393 * via the eh thread. Ick! Ick! Ick!
4394 */
4395 if (cmd->retries > 0)
4396 cmd->retries--;
4397 new_status = DID_OK;
4398 ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
4399 cmd->result |= (DRIVER_SENSE << 24);
4400 memset(cmd->sense_buffer, 0,
4401 sizeof(cmd->sense_buffer));
4402 cmd->sense_buffer[0] = SSD_ERRCODE_VALID
4403 | SSD_CURRENT_ERROR;
4404 cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND;
4405 break;
4406 default:
4407 /* We should never get here */
4408 new_status = DID_ERROR;
4409 break;
4410 }
4411
4412 ahc_cmd_set_transaction_status(cmd, new_status);
4413 }
4414
4415 completeq = &ahc->platform_data->completeq;
4416 list_cmd = TAILQ_FIRST(completeq);
4417 acmd = (struct ahc_cmd *)cmd;
4418 while (list_cmd != NULL
4419 && acmd_scsi_cmd(list_cmd).serial_number
4420 < acmd_scsi_cmd(acmd).serial_number)
4421 list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe);
4422 if (list_cmd != NULL)
4423 TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe);
4424 else
4425 TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe);
4426}
4427
4428static void
4429ahc_linux_filter_inquiry(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
4430{
4431 struct scsi_inquiry_data *sid;
4432 struct ahc_initiator_tinfo *tinfo;
4433 struct ahc_transinfo *user;
4434 struct ahc_transinfo *goal;
4435 struct ahc_transinfo *curr;
4436 struct ahc_tmode_tstate *tstate;
4437 struct ahc_syncrate *syncrate;
4438 struct ahc_linux_device *dev;
4439 u_int maxsync;
4440 u_int width;
4441 u_int period;
4442 u_int offset;
4443 u_int ppr_options;
4444 u_int trans_version;
4445 u_int prot_version;
4446
4447 /*
4448 * Determine if this lun actually exists. If so,
4449 * hold on to its corresponding device structure.
4450 * If not, make sure we release the device and
4451 * don't bother processing the rest of this inquiry
4452 * command.
4453 */
4454 dev = ahc_linux_get_device(ahc, devinfo->channel - 'A',
4455 devinfo->target, devinfo->lun,
4456 /*alloc*/TRUE);
4457
4458 sid = (struct scsi_inquiry_data *)dev->target->inq_data;
4459 if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) {
4460
4461 dev->flags &= ~AHC_DEV_UNCONFIGURED;
4462 } else {
4463 dev->flags |= AHC_DEV_UNCONFIGURED;
4464 return;
4465 }
4466
4467 /*
4468 * Update our notion of this device's transfer
4469 * negotiation capabilities.
4470 */
4471 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
4472 devinfo->our_scsiid,
4473 devinfo->target, &tstate);
4474 user = &tinfo->user;
4475 goal = &tinfo->goal;
4476 curr = &tinfo->curr;
4477 width = user->width;
4478 period = user->period;
4479 offset = user->offset;
4480 ppr_options = user->ppr_options;
4481 trans_version = user->transport_version;
4482 prot_version = MIN(user->protocol_version, SID_ANSI_REV(sid));
4483
4484 /*
4485 * Only attempt SPI3/4 once we've verified that
4486 * the device claims to support SPI3/4 features.
4487 */
4488 if (prot_version < SCSI_REV_2)
4489 trans_version = SID_ANSI_REV(sid);
4490 else
4491 trans_version = SCSI_REV_2;
4492
4493 if ((sid->flags & SID_WBus16) == 0)
4494 width = MSG_EXT_WDTR_BUS_8_BIT;
4495 if ((sid->flags & SID_Sync) == 0) {
4496 period = 0;
4497 offset = 0;
4498 ppr_options = 0;
4499 }
4500 if ((sid->spi3data & SID_SPI_QAS) == 0)
4501 ppr_options &= ~MSG_EXT_PPR_QAS_REQ;
4502 if ((sid->spi3data & SID_SPI_CLOCK_DT) == 0)
4503 ppr_options &= MSG_EXT_PPR_QAS_REQ;
4504 if ((sid->spi3data & SID_SPI_IUS) == 0)
4505 ppr_options &= (MSG_EXT_PPR_DT_REQ
4506 | MSG_EXT_PPR_QAS_REQ);
4507
4508 if (prot_version > SCSI_REV_2
4509 && ppr_options != 0)
4510 trans_version = user->transport_version;
4511
4512 ahc_validate_width(ahc, /*tinfo limit*/NULL, &width, ROLE_UNKNOWN);
4513 if ((ahc->features & AHC_ULTRA2) != 0)
4514 maxsync = AHC_SYNCRATE_DT;
4515 else if ((ahc->features & AHC_ULTRA) != 0)
4516 maxsync = AHC_SYNCRATE_ULTRA;
4517 else
4518 maxsync = AHC_SYNCRATE_FAST;
4519
4520 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, maxsync);
4521 ahc_validate_offset(ahc, /*tinfo limit*/NULL, syncrate,
4522 &offset, width, ROLE_UNKNOWN);
4523 if (offset == 0 || period == 0) {
4524 period = 0;
4525 offset = 0;
4526 ppr_options = 0;
4527 }
4528 /* Apply our filtered user settings. */
4529 curr->transport_version = trans_version;
4530 curr->protocol_version = prot_version;
4531 ahc_set_width(ahc, devinfo, width, AHC_TRANS_GOAL, /*paused*/FALSE);
4532 ahc_set_syncrate(ahc, devinfo, syncrate, period,
4533 offset, ppr_options, AHC_TRANS_GOAL,
4534 /*paused*/FALSE);
4535}
4536
4537static void
4538ahc_linux_sem_timeout(u_long arg)
4539{
4540 struct ahc_softc *ahc;
4541 u_long s;
4542
4543 ahc = (struct ahc_softc *)arg;
4544
4545 ahc_lock(ahc, &s);
4546 if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
4547 ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
4548 up(&ahc->platform_data->eh_sem);
4549 }
4550 ahc_unlock(ahc, &s);
4551}
4552
4553static void
4554ahc_linux_freeze_simq(struct ahc_softc *ahc)
4555{
4556 ahc->platform_data->qfrozen++;
4557 if (ahc->platform_data->qfrozen == 1) {
4558 scsi_block_requests(ahc->platform_data->host);
4559
4560 /* XXX What about Twin channels? */
4561 ahc_platform_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
4562 CAM_LUN_WILDCARD, SCB_LIST_NULL,
4563 ROLE_INITIATOR, CAM_REQUEUE_REQ);
4564 }
4565}
4566
4567static void
4568ahc_linux_release_simq(u_long arg)
4569{
4570 struct ahc_softc *ahc;
4571 u_long s;
4572 int unblock_reqs;
4573
4574 ahc = (struct ahc_softc *)arg;
4575
4576 unblock_reqs = 0;
4577 ahc_lock(ahc, &s);
4578 if (ahc->platform_data->qfrozen > 0)
4579 ahc->platform_data->qfrozen--;
4580 if (ahc->platform_data->qfrozen == 0)
4581 unblock_reqs = 1;
4582 if (AHC_DV_SIMQ_FROZEN(ahc)
4583 && ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_RELEASE) != 0)) {
4584 ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_RELEASE;
4585 up(&ahc->platform_data->dv_sem);
4586 }
4587 ahc_schedule_runq(ahc);
4588 ahc_unlock(ahc, &s);
4589 /*
4590 * There is still a race here. The mid-layer
4591 * should keep its own freeze count and use
4592 * a bottom half handler to run the queues
4593 * so we can unblock with our own lock held.
4594 */
4595 if (unblock_reqs)
4596 scsi_unblock_requests(ahc->platform_data->host);
4597}
4598
4599static void
4600ahc_linux_dev_timed_unfreeze(u_long arg)
4601{
4602 struct ahc_linux_device *dev;
4603 struct ahc_softc *ahc;
4604 u_long s;
4605
4606 dev = (struct ahc_linux_device *)arg;
4607 ahc = dev->target->ahc;
4608 ahc_lock(ahc, &s);
4609 dev->flags &= ~AHC_DEV_TIMER_ACTIVE;
4610 if (dev->qfrozen > 0)
4611 dev->qfrozen--;
4612 if (dev->qfrozen == 0
4613 && (dev->flags & AHC_DEV_ON_RUN_LIST) == 0)
4614 ahc_linux_run_device_queue(ahc, dev);
4615 if (TAILQ_EMPTY(&dev->busyq)
4616 && dev->active == 0)
4617 __ahc_linux_free_device(ahc, dev);
4618 ahc_unlock(ahc, &s);
4619}
4620
4621static int
4622ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
4623{
4624 struct ahc_softc *ahc;
4625 struct ahc_cmd *acmd;
4626 struct ahc_cmd *list_acmd;
4627 struct ahc_linux_device *dev;
4628 struct scb *pending_scb;
4629 u_long s;
4630 u_int saved_scbptr;
4631 u_int active_scb_index;
4632 u_int last_phase;
4633 u_int saved_scsiid;
4634 u_int cdb_byte;
4635 int retval;
4636 int was_paused;
4637 int paused;
4638 int wait;
4639 int disconnected;
4640
4641 pending_scb = NULL;
4642 paused = FALSE;
4643 wait = FALSE;
4644 ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
4645 acmd = (struct ahc_cmd *)cmd;
4646
4647 printf("%s:%d:%d:%d: Attempting to queue a%s message\n",
4648 ahc_name(ahc), cmd->device->channel,
4649 cmd->device->id, cmd->device->lun,
4650 flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
4651
4652 printf("CDB:");
4653 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
4654 printf(" 0x%x", cmd->cmnd[cdb_byte]);
4655 printf("\n");
4656
4657 /*
4658 * In all versions of Linux, we have to work around
4659 * a major flaw in how the mid-layer is locked down
4660 * if we are to sleep successfully in our error handler
4661 * while allowing our interrupt handler to run. Since
4662 * the midlayer acquires either the io_request_lock or
4663 * our lock prior to calling us, we must use the
4664 * spin_unlock_irq() method for unlocking our lock.
4665 * This will force interrupts to be enabled on the
4666 * current CPU. Since the EH thread should not have
4667 * been running with CPU interrupts disabled other than
4668 * by acquiring either the io_request_lock or our own
4669 * lock, this *should* be safe.
4670 */
4671 ahc_midlayer_entrypoint_lock(ahc, &s);
4672
4673 /*
4674 * First determine if we currently own this command.
4675 * Start by searching the device queue. If not found
4676 * there, check the pending_scb list. If not found
4677 * at all, and the system wanted us to just abort the
4678 * command, return success.
4679 */
4680 dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
4681 cmd->device->lun, /*alloc*/FALSE);
4682
4683 if (dev == NULL) {
4684 /*
4685 * No target device for this command exists,
4686 * so we must not still own the command.
4687 */
4688 printf("%s:%d:%d:%d: Is not an active device\n",
4689 ahc_name(ahc), cmd->device->channel, cmd->device->id,
4690 cmd->device->lun);
4691 retval = SUCCESS;
4692 goto no_cmd;
4693 }
4694
4695 TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) {
4696 if (list_acmd == acmd)
4697 break;
4698 }
4699
4700 if (list_acmd != NULL) {
4701 printf("%s:%d:%d:%d: Command found on device queue\n",
4702 ahc_name(ahc), cmd->device->channel, cmd->device->id,
4703 cmd->device->lun);
4704 if (flag == SCB_ABORT) {
4705 TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
4706 cmd->result = DID_ABORT << 16;
4707 ahc_linux_queue_cmd_complete(ahc, cmd);
4708 retval = SUCCESS;
4709 goto done;
4710 }
4711 }
4712
4713 if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
4714 && ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
4715 cmd->device->channel + 'A',
4716 cmd->device->lun,
4717 CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) {
4718 printf("%s:%d:%d:%d: Command found on untagged queue\n",
4719 ahc_name(ahc), cmd->device->channel, cmd->device->id,
4720 cmd->device->lun);
4721 retval = SUCCESS;
4722 goto done;
4723 }
4724
4725 /*
4726 * See if we can find a matching cmd in the pending list.
4727 */
4728 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
4729 if (pending_scb->io_ctx == cmd)
4730 break;
4731 }
4732
4733 if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
4734
4735 /* Any SCB for this device will do for a target reset */
4736 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
4737 if (ahc_match_scb(ahc, pending_scb, cmd->device->id,
4738 cmd->device->channel + 'A',
4739 CAM_LUN_WILDCARD,
4740 SCB_LIST_NULL, ROLE_INITIATOR) == 0)
4741 break;
4742 }
4743 }
4744
4745 if (pending_scb == NULL) {
4746 printf("%s:%d:%d:%d: Command not found\n",
4747 ahc_name(ahc), cmd->device->channel, cmd->device->id,
4748 cmd->device->lun);
4749 goto no_cmd;
4750 }
4751
4752 if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
4753 /*
4754 * We can't queue two recovery actions using the same SCB
4755 */
4756 retval = FAILED;
4757 goto done;
4758 }
4759
4760 /*
4761 * Ensure that the card doesn't do anything
4762 * behind our back and that we didn't "just" miss
4763 * an interrupt that would affect this cmd.
4764 */
4765 was_paused = ahc_is_paused(ahc);
4766 ahc_pause_and_flushwork(ahc);
4767 paused = TRUE;
4768
4769 if ((pending_scb->flags & SCB_ACTIVE) == 0) {
4770 printf("%s:%d:%d:%d: Command already completed\n",
4771 ahc_name(ahc), cmd->device->channel, cmd->device->id,
4772 cmd->device->lun);
4773 goto no_cmd;
4774 }
4775
4776 printf("%s: At time of recovery, card was %spaused\n",
4777 ahc_name(ahc), was_paused ? "" : "not ");
4778 ahc_dump_card_state(ahc);
4779
4780 disconnected = TRUE;
4781 if (flag == SCB_ABORT) {
4782 if (ahc_search_qinfifo(ahc, cmd->device->id,
4783 cmd->device->channel + 'A',
4784 cmd->device->lun,
4785 pending_scb->hscb->tag,
4786 ROLE_INITIATOR, CAM_REQ_ABORTED,
4787 SEARCH_COMPLETE) > 0) {
4788 printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
4789 ahc_name(ahc), cmd->device->channel,
4790 cmd->device->id, cmd->device->lun);
4791 retval = SUCCESS;
4792 goto done;
4793 }
4794 } else if (ahc_search_qinfifo(ahc, cmd->device->id,
4795 cmd->device->channel + 'A',
4796 cmd->device->lun, pending_scb->hscb->tag,
4797 ROLE_INITIATOR, /*status*/0,
4798 SEARCH_COUNT) > 0) {
4799 disconnected = FALSE;
4800 }
4801
4802 if (disconnected && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
4803 struct scb *bus_scb;
4804
4805 bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG));
4806 if (bus_scb == pending_scb)
4807 disconnected = FALSE;
4808 else if (flag != SCB_ABORT
4809 && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid
4810 && ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb))
4811 disconnected = FALSE;
4812 }
4813
4814 /*
4815 * At this point, pending_scb is the scb associated with the
4816 * passed in command. That command is currently active on the
4817 * bus, is in the disconnected state, or we're hoping to find
4818 * a command for the same target active on the bus to abuse to
4819 * send a BDR. Queue the appropriate message based on which of
4820 * these states we are in.
4821 */
4822 last_phase = ahc_inb(ahc, LASTPHASE);
4823 saved_scbptr = ahc_inb(ahc, SCBPTR);
4824 active_scb_index = ahc_inb(ahc, SCB_TAG);
4825 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
4826 if (last_phase != P_BUSFREE
4827 && (pending_scb->hscb->tag == active_scb_index
4828 || (flag == SCB_DEVICE_RESET
4829 && SCSIID_TARGET(ahc, saved_scsiid) == cmd->device->id))) {
4830
4831 /*
4832 * We're active on the bus, so assert ATN
4833 * and hope that the target responds.
4834 */
4835 pending_scb = ahc_lookup_scb(ahc, active_scb_index);
4836 pending_scb->flags |= SCB_RECOVERY_SCB|flag;
4837 ahc_outb(ahc, MSG_OUT, HOST_MSG);
4838 ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
4839 printf("%s:%d:%d:%d: Device is active, asserting ATN\n",
4840 ahc_name(ahc), cmd->device->channel, cmd->device->id,
4841 cmd->device->lun);
4842 wait = TRUE;
4843 } else if (disconnected) {
4844
4845 /*
4846 * Actually re-queue this SCB in an attempt
4847 * to select the device before it reconnects.
4848 * In either case (selection or reselection),
4849 * we will now issue the approprate message
4850 * to the timed-out device.
4851 *
4852 * Set the MK_MESSAGE control bit indicating
4853 * that we desire to send a message. We
4854 * also set the disconnected flag since
4855 * in the paging case there is no guarantee
4856 * that our SCB control byte matches the
4857 * version on the card. We don't want the
4858 * sequencer to abort the command thinking
4859 * an unsolicited reselection occurred.
4860 */
4861 pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
4862 pending_scb->flags |= SCB_RECOVERY_SCB|flag;
4863
4864 /*
4865 * Remove any cached copy of this SCB in the
4866 * disconnected list in preparation for the
4867 * queuing of our abort SCB. We use the
4868 * same element in the SCB, SCB_NEXT, for
4869 * both the qinfifo and the disconnected list.
4870 */
4871 ahc_search_disc_list(ahc, cmd->device->id,
4872 cmd->device->channel + 'A',
4873 cmd->device->lun, pending_scb->hscb->tag,
4874 /*stop_on_first*/TRUE,
4875 /*remove*/TRUE,
4876 /*save_state*/FALSE);
4877
4878 /*
4879 * In the non-paging case, the sequencer will
4880 * never re-reference the in-core SCB.
4881 * To make sure we are notified during
4882 * reslection, set the MK_MESSAGE flag in
4883 * the card's copy of the SCB.
4884 */
4885 if ((ahc->flags & AHC_PAGESCBS) == 0) {
4886 ahc_outb(ahc, SCBPTR, pending_scb->hscb->tag);
4887 ahc_outb(ahc, SCB_CONTROL,
4888 ahc_inb(ahc, SCB_CONTROL)|MK_MESSAGE);
4889 }
4890
4891 /*
4892 * Clear out any entries in the QINFIFO first
4893 * so we are the next SCB for this target
4894 * to run.
4895 */
4896 ahc_search_qinfifo(ahc, cmd->device->id,
4897 cmd->device->channel + 'A',
4898 cmd->device->lun, SCB_LIST_NULL,
4899 ROLE_INITIATOR, CAM_REQUEUE_REQ,
4900 SEARCH_COMPLETE);
4901 ahc_qinfifo_requeue_tail(ahc, pending_scb);
4902 ahc_outb(ahc, SCBPTR, saved_scbptr);
4903 ahc_print_path(ahc, pending_scb);
4904 printf("Device is disconnected, re-queuing SCB\n");
4905 wait = TRUE;
4906 } else {
4907 printf("%s:%d:%d:%d: Unable to deliver message\n",
4908 ahc_name(ahc), cmd->device->channel, cmd->device->id,
4909 cmd->device->lun);
4910 retval = FAILED;
4911 goto done;
4912 }
4913
4914no_cmd:
4915 /*
4916 * Our assumption is that if we don't have the command, no
4917 * recovery action was required, so we return success. Again,
4918 * the semantics of the mid-layer recovery engine are not
4919 * well defined, so this may change in time.
4920 */
4921 retval = SUCCESS;
4922done:
4923 if (paused)
4924 ahc_unpause(ahc);
4925 if (wait) {
4926 struct timer_list timer;
4927 int ret;
4928
4929 ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE;
4930 spin_unlock_irq(&ahc->platform_data->spin_lock);
4931 init_timer(&timer);
4932 timer.data = (u_long)ahc;
4933 timer.expires = jiffies + (5 * HZ);
4934 timer.function = ahc_linux_sem_timeout;
4935 add_timer(&timer);
4936 printf("Recovery code sleeping\n");
4937 down(&ahc->platform_data->eh_sem);
4938 printf("Recovery code awake\n");
4939 ret = del_timer_sync(&timer);
4940 if (ret == 0) {
4941 printf("Timer Expired\n");
4942 retval = FAILED;
4943 }
4944 spin_lock_irq(&ahc->platform_data->spin_lock);
4945 }
4946 ahc_schedule_runq(ahc);
4947 ahc_linux_run_complete_queue(ahc);
4948 ahc_midlayer_entrypoint_unlock(ahc, &s);
4949 return (retval);
4950}
4951
4952void
4953ahc_platform_dump_card_state(struct ahc_softc *ahc)
4954{
4955 struct ahc_linux_device *dev;
4956 int channel;
4957 int maxchannel;
4958 int target;
4959 int maxtarget;
4960 int lun;
4961 int i;
4962
4963 maxchannel = (ahc->features & AHC_TWIN) ? 1 : 0;
4964 maxtarget = (ahc->features & AHC_WIDE) ? 15 : 7;
4965 for (channel = 0; channel <= maxchannel; channel++) {
4966
4967 for (target = 0; target <=maxtarget; target++) {
4968
4969 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
4970 struct ahc_cmd *acmd;
4971
4972 dev = ahc_linux_get_device(ahc, channel, target,
4973 lun, /*alloc*/FALSE);
4974 if (dev == NULL)
4975 continue;
4976
4977 printf("DevQ(%d:%d:%d): ",
4978 channel, target, lun);
4979 i = 0;
4980 TAILQ_FOREACH(acmd, &dev->busyq,
4981 acmd_links.tqe) {
4982 if (i++ > AHC_SCB_MAX)
4983 break;
4984 }
4985 printf("%d waiting\n", i);
4986 }
4987 }
4988 }
4989}
4990
4991static void ahc_linux_exit(void);
4992
4993static int __init
4994ahc_linux_init(void)
4995{
4996#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
4997 int rc = ahc_linux_detect(&aic7xxx_driver_template);
4998 if (rc)
4999 return rc;
5000 ahc_linux_exit();
5001 return -ENODEV;
5002#else
5003 scsi_register_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
5004 if (aic7xxx_driver_template.present == 0) {
5005 scsi_unregister_module(MODULE_SCSI_HA,
5006 &aic7xxx_driver_template);
5007 return (-ENODEV);
5008 }
5009
5010 return (0);
5011#endif
5012}
5013
5014static void
5015ahc_linux_exit(void)
5016{
5017 struct ahc_softc *ahc;
5018
5019 /*
5020 * Shutdown DV threads before going into the SCSI mid-layer.
5021 * This avoids situations where the mid-layer locks the entire
5022 * kernel so that waiting for our DV threads to exit leads
5023 * to deadlock.
5024 */
5025 TAILQ_FOREACH(ahc, &ahc_tailq, links) {
5026
5027 ahc_linux_kill_dv_thread(ahc);
5028 }
5029
5030#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5031 /*
5032 * In 2.4 we have to unregister from the PCI core _after_
5033 * unregistering from the scsi midlayer to avoid dangling
5034 * references.
5035 */
5036 scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
5037#endif
5038 ahc_linux_pci_exit();
5039 ahc_linux_eisa_exit();
5040}
5041
5042module_init(ahc_linux_init);
5043module_exit(ahc_linux_exit);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
new file mode 100644
index 000000000000..db3bd6321dd4
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -0,0 +1,1130 @@
1/*
2 * Adaptec AIC7xxx device driver for Linux.
3 *
4 * Copyright (c) 1994 John Aycock
5 * The University of Calgary Department of Computer Science.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * Copyright (c) 2000-2003 Adaptec Inc.
22 * All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions, and the following disclaimer,
29 * without modification.
30 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
31 * substantially similar to the "NO WARRANTY" disclaimer below
32 * ("Disclaimer") and any redistribution must be conditioned upon
33 * including a substantially similar Disclaimer requirement for further
34 * binary redistribution.
35 * 3. Neither the names of the above-listed copyright holders nor the names
36 * of any contributors may be used to endorse or promote products derived
37 * from this software without specific prior written permission.
38 *
39 * Alternatively, this software may be distributed under the terms of the
40 * GNU General Public License ("GPL") version 2 as published by the Free
41 * Software Foundation.
42 *
43 * NO WARRANTY
44 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
45 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
46 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
47 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
48 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
53 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
54 * POSSIBILITY OF SUCH DAMAGES.
55 *
56 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#151 $
57 *
58 */
59#ifndef _AIC7XXX_LINUX_H_
60#define _AIC7XXX_LINUX_H_
61
62#include <linux/types.h>
63#include <linux/blkdev.h>
64#include <linux/delay.h>
65#include <linux/ioport.h>
66#include <linux/pci.h>
67#include <linux/smp_lock.h>
68#include <linux/version.h>
69#include <linux/module.h>
70#include <asm/byteorder.h>
71#include <asm/io.h>
72
73#include <linux/interrupt.h> /* For tasklet support. */
74#include <linux/config.h>
75#include <linux/slab.h>
76
77/* Core SCSI definitions */
78#define AIC_LIB_PREFIX ahc
79#include "scsi.h"
80#include <scsi/scsi_host.h>
81
82/* Name space conflict with BSD queue macros */
83#ifdef LIST_HEAD
84#undef LIST_HEAD
85#endif
86
87#include "cam.h"
88#include "queue.h"
89#include "scsi_message.h"
90#include "aiclib.h"
91
92/*********************************** Debugging ********************************/
93#ifdef CONFIG_AIC7XXX_DEBUG_ENABLE
94#ifdef CONFIG_AIC7XXX_DEBUG_MASK
95#define AHC_DEBUG 1
96#define AHC_DEBUG_OPTS CONFIG_AIC7XXX_DEBUG_MASK
97#else
98/*
99 * Compile in debugging code, but do not enable any printfs.
100 */
101#define AHC_DEBUG 1
102#endif
103/* No debugging code. */
104#endif
105
106/************************* Forward Declarations *******************************/
107struct ahc_softc;
108typedef struct pci_dev *ahc_dev_softc_t;
109typedef Scsi_Cmnd *ahc_io_ctx_t;
110
111/******************************* Byte Order ***********************************/
112#define ahc_htobe16(x) cpu_to_be16(x)
113#define ahc_htobe32(x) cpu_to_be32(x)
114#define ahc_htobe64(x) cpu_to_be64(x)
115#define ahc_htole16(x) cpu_to_le16(x)
116#define ahc_htole32(x) cpu_to_le32(x)
117#define ahc_htole64(x) cpu_to_le64(x)
118
119#define ahc_be16toh(x) be16_to_cpu(x)
120#define ahc_be32toh(x) be32_to_cpu(x)
121#define ahc_be64toh(x) be64_to_cpu(x)
122#define ahc_le16toh(x) le16_to_cpu(x)
123#define ahc_le32toh(x) le32_to_cpu(x)
124#define ahc_le64toh(x) le64_to_cpu(x)
125
126#ifndef LITTLE_ENDIAN
127#define LITTLE_ENDIAN 1234
128#endif
129
130#ifndef BIG_ENDIAN
131#define BIG_ENDIAN 4321
132#endif
133
134#ifndef BYTE_ORDER
135#if defined(__BIG_ENDIAN)
136#define BYTE_ORDER BIG_ENDIAN
137#endif
138#if defined(__LITTLE_ENDIAN)
139#define BYTE_ORDER LITTLE_ENDIAN
140#endif
141#endif /* BYTE_ORDER */
142
143/************************* Configuration Data *********************************/
144extern u_int aic7xxx_no_probe;
145extern u_int aic7xxx_allow_memio;
146extern int aic7xxx_detect_complete;
147extern Scsi_Host_Template aic7xxx_driver_template;
148
149/***************************** Bus Space/DMA **********************************/
150
151typedef uint32_t bus_size_t;
152
153typedef enum {
154 BUS_SPACE_MEMIO,
155 BUS_SPACE_PIO
156} bus_space_tag_t;
157
158typedef union {
159 u_long ioport;
160 volatile uint8_t __iomem *maddr;
161} bus_space_handle_t;
162
163typedef struct bus_dma_segment
164{
165 dma_addr_t ds_addr;
166 bus_size_t ds_len;
167} bus_dma_segment_t;
168
169struct ahc_linux_dma_tag
170{
171 bus_size_t alignment;
172 bus_size_t boundary;
173 bus_size_t maxsize;
174};
175typedef struct ahc_linux_dma_tag* bus_dma_tag_t;
176
177struct ahc_linux_dmamap
178{
179 dma_addr_t bus_addr;
180};
181typedef struct ahc_linux_dmamap* bus_dmamap_t;
182
183typedef int bus_dma_filter_t(void*, dma_addr_t);
184typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
185
186#define BUS_DMA_WAITOK 0x0
187#define BUS_DMA_NOWAIT 0x1
188#define BUS_DMA_ALLOCNOW 0x2
189#define BUS_DMA_LOAD_SEGS 0x4 /*
190 * Argument is an S/G list not
191 * a single buffer.
192 */
193
194#define BUS_SPACE_MAXADDR 0xFFFFFFFF
195#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
196#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
197
198int ahc_dma_tag_create(struct ahc_softc *, bus_dma_tag_t /*parent*/,
199 bus_size_t /*alignment*/, bus_size_t /*boundary*/,
200 dma_addr_t /*lowaddr*/, dma_addr_t /*highaddr*/,
201 bus_dma_filter_t*/*filter*/, void */*filterarg*/,
202 bus_size_t /*maxsize*/, int /*nsegments*/,
203 bus_size_t /*maxsegsz*/, int /*flags*/,
204 bus_dma_tag_t */*dma_tagp*/);
205
206void ahc_dma_tag_destroy(struct ahc_softc *, bus_dma_tag_t /*tag*/);
207
208int ahc_dmamem_alloc(struct ahc_softc *, bus_dma_tag_t /*dmat*/,
209 void** /*vaddr*/, int /*flags*/,
210 bus_dmamap_t* /*mapp*/);
211
212void ahc_dmamem_free(struct ahc_softc *, bus_dma_tag_t /*dmat*/,
213 void* /*vaddr*/, bus_dmamap_t /*map*/);
214
215void ahc_dmamap_destroy(struct ahc_softc *, bus_dma_tag_t /*tag*/,
216 bus_dmamap_t /*map*/);
217
218int ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t /*dmat*/,
219 bus_dmamap_t /*map*/, void * /*buf*/,
220 bus_size_t /*buflen*/, bus_dmamap_callback_t *,
221 void */*callback_arg*/, int /*flags*/);
222
223int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
224
225/*
226 * Operations performed by ahc_dmamap_sync().
227 */
228#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
229#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
230#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
231#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
232
233/*
234 * XXX
235 * ahc_dmamap_sync is only used on buffers allocated with
236 * the pci_alloc_consistent() API. Although I'm not sure how
237 * this works on architectures with a write buffer, Linux does
238 * not have an API to sync "coherent" memory. Perhaps we need
239 * to do an mb()?
240 */
241#define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op)
242
243/************************** Timer DataStructures ******************************/
244typedef struct timer_list ahc_timer_t;
245
246/********************************** Includes **********************************/
247#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
248#define AIC_DEBUG_REGISTERS 1
249#else
250#define AIC_DEBUG_REGISTERS 0
251#endif
252#include "aic7xxx.h"
253
254/***************************** Timer Facilities *******************************/
255#define ahc_timer_init init_timer
256#define ahc_timer_stop del_timer_sync
257typedef void ahc_linux_callback_t (u_long);
258static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec,
259 ahc_callback_t *func, void *arg);
260static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec);
261
262static __inline void
263ahc_timer_reset(ahc_timer_t *timer, int usec, ahc_callback_t *func, void *arg)
264{
265 struct ahc_softc *ahc;
266
267 ahc = (struct ahc_softc *)arg;
268 del_timer(timer);
269 timer->data = (u_long)arg;
270 timer->expires = jiffies + (usec * HZ)/1000000;
271 timer->function = (ahc_linux_callback_t*)func;
272 add_timer(timer);
273}
274
275static __inline void
276ahc_scb_timer_reset(struct scb *scb, u_int usec)
277{
278 mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
279}
280
281/***************************** SMP support ************************************/
282#include <linux/spinlock.h>
283
284#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
285#define AHC_SCSI_HAS_HOST_LOCK 1
286#else
287#define AHC_SCSI_HAS_HOST_LOCK 0
288#endif
289
290#define AIC7XXX_DRIVER_VERSION "6.2.36"
291
292/**************************** Front End Queues ********************************/
293/*
294 * Data structure used to cast the Linux struct scsi_cmnd to something
295 * that allows us to use the queue macros. The linux structure has
296 * plenty of space to hold the links fields as required by the queue
297 * macros, but the queue macors require them to have the correct type.
298 */
299struct ahc_cmd_internal {
300 /* Area owned by the Linux scsi layer. */
301 uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)];
302 union {
303 STAILQ_ENTRY(ahc_cmd) ste;
304 LIST_ENTRY(ahc_cmd) le;
305 TAILQ_ENTRY(ahc_cmd) tqe;
306 } links;
307 uint32_t end;
308};
309
310struct ahc_cmd {
311 union {
312 struct ahc_cmd_internal icmd;
313 struct scsi_cmnd scsi_cmd;
314 } un;
315};
316
317#define acmd_icmd(cmd) ((cmd)->un.icmd)
318#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)
319#define acmd_links un.icmd.links
320
321/*************************** Device Data Structures ***************************/
322/*
323 * A per probed device structure used to deal with some error recovery
324 * scenarios that the Linux mid-layer code just doesn't know how to
325 * handle. The structure allocated for a device only becomes persistent
326 * after a successfully completed inquiry command to the target when
327 * that inquiry data indicates a lun is present.
328 */
329TAILQ_HEAD(ahc_busyq, ahc_cmd);
330typedef enum {
331 AHC_DEV_UNCONFIGURED = 0x01,
332 AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
333 AHC_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */
334 AHC_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */
335 AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */
336 AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */
337 AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */
338 AHC_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */
339} ahc_linux_dev_flags;
340
341struct ahc_linux_target;
342struct ahc_linux_device {
343 TAILQ_ENTRY(ahc_linux_device) links;
344 struct ahc_busyq busyq;
345
346 /*
347 * The number of transactions currently
348 * queued to the device.
349 */
350 int active;
351
352 /*
353 * The currently allowed number of
354 * transactions that can be queued to
355 * the device. Must be signed for
356 * conversion from tagged to untagged
357 * mode where the device may have more
358 * than one outstanding active transaction.
359 */
360 int openings;
361
362 /*
363 * A positive count indicates that this
364 * device's queue is halted.
365 */
366 u_int qfrozen;
367
368 /*
369 * Cumulative command counter.
370 */
371 u_long commands_issued;
372
373 /*
374 * The number of tagged transactions when
375 * running at our current opening level
376 * that have been successfully received by
377 * this device since the last QUEUE FULL.
378 */
379 u_int tag_success_count;
380#define AHC_TAG_SUCCESS_INTERVAL 50
381
382 ahc_linux_dev_flags flags;
383
384 /*
385 * Per device timer.
386 */
387 struct timer_list timer;
388
389 /*
390 * The high limit for the tags variable.
391 */
392 u_int maxtags;
393
394 /*
395 * The computed number of tags outstanding
396 * at the time of the last QUEUE FULL event.
397 */
398 u_int tags_on_last_queuefull;
399
400 /*
401 * How many times we have seen a queue full
402 * with the same number of tags. This is used
403 * to stop our adaptive queue depth algorithm
404 * on devices with a fixed number of tags.
405 */
406 u_int last_queuefull_same_count;
407#define AHC_LOCK_TAGS_COUNT 50
408
409 /*
410 * How many transactions have been queued
411 * without the device going idle. We use
412 * this statistic to determine when to issue
413 * an ordered tag to prevent transaction
414 * starvation. This statistic is only updated
415 * if the AHC_DEV_PERIODIC_OTAG flag is set
416 * on this device.
417 */
418 u_int commands_since_idle_or_otag;
419#define AHC_OTAG_THRESH 500
420
421 int lun;
422 Scsi_Device *scsi_device;
423 struct ahc_linux_target *target;
424};
425
426typedef enum {
427 AHC_DV_REQUIRED = 0x01,
428 AHC_INQ_VALID = 0x02,
429 AHC_BASIC_DV = 0x04,
430 AHC_ENHANCED_DV = 0x08
431} ahc_linux_targ_flags;
432
433/* DV States */
434typedef enum {
435 AHC_DV_STATE_EXIT = 0,
436 AHC_DV_STATE_INQ_SHORT_ASYNC,
437 AHC_DV_STATE_INQ_ASYNC,
438 AHC_DV_STATE_INQ_ASYNC_VERIFY,
439 AHC_DV_STATE_TUR,
440 AHC_DV_STATE_REBD,
441 AHC_DV_STATE_INQ_VERIFY,
442 AHC_DV_STATE_WEB,
443 AHC_DV_STATE_REB,
444 AHC_DV_STATE_SU,
445 AHC_DV_STATE_BUSY
446} ahc_dv_state;
447
448struct ahc_linux_target {
449 struct ahc_linux_device *devices[AHC_NUM_LUNS];
450 int channel;
451 int target;
452 int refcount;
453 struct ahc_transinfo last_tinfo;
454 struct ahc_softc *ahc;
455 ahc_linux_targ_flags flags;
456 struct scsi_inquiry_data *inq_data;
457 /*
458 * The next "fallback" period to use for narrow/wide transfers.
459 */
460 uint8_t dv_next_narrow_period;
461 uint8_t dv_next_wide_period;
462 uint8_t dv_max_width;
463 uint8_t dv_max_ppr_options;
464 uint8_t dv_last_ppr_options;
465 u_int dv_echo_size;
466 ahc_dv_state dv_state;
467 u_int dv_state_retry;
468 char *dv_buffer;
469 char *dv_buffer1;
470};
471
472/********************* Definitions Required by the Core ***********************/
473/*
474 * Number of SG segments we require. So long as the S/G segments for
475 * a particular transaction are allocated in a physically contiguous
476 * manner and are allocated below 4GB, the number of S/G segments is
477 * unrestricted.
478 */
479#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
480/*
481 * We dynamically adjust the number of segments in pre-2.5 kernels to
482 * avoid fragmentation issues in the SCSI mid-layer's private memory
483 * allocator. See aic7xxx_osm.c ahc_linux_size_nseg() for details.
484 */
485extern u_int ahc_linux_nseg;
486#define AHC_NSEG ahc_linux_nseg
487#define AHC_LINUX_MIN_NSEG 64
488#else
489#define AHC_NSEG 128
490#endif
491
492/*
493 * Per-SCB OSM storage.
494 */
495typedef enum {
496 AHC_UP_EH_SEMAPHORE = 0x1
497} ahc_linux_scb_flags;
498
499struct scb_platform_data {
500 struct ahc_linux_device *dev;
501 dma_addr_t buf_busaddr;
502 uint32_t xfer_len;
503 uint32_t sense_resid; /* Auto-Sense residual */
504 ahc_linux_scb_flags flags;
505};
506
507/*
508 * Define a structure used for each host adapter. All members are
509 * aligned on a boundary >= the size of the member to honor the
510 * alignment restrictions of the various platforms supported by
511 * this driver.
512 */
513typedef enum {
514 AHC_DV_WAIT_SIMQ_EMPTY = 0x01,
515 AHC_DV_WAIT_SIMQ_RELEASE = 0x02,
516 AHC_DV_ACTIVE = 0x04,
517 AHC_DV_SHUTDOWN = 0x08,
518 AHC_RUN_CMPLT_Q_TIMER = 0x10
519} ahc_linux_softc_flags;
520
521TAILQ_HEAD(ahc_completeq, ahc_cmd);
522
523struct ahc_platform_data {
524 /*
525 * Fields accessed from interrupt context.
526 */
527 struct ahc_linux_target *targets[AHC_NUM_TARGETS];
528 TAILQ_HEAD(, ahc_linux_device) device_runq;
529 struct ahc_completeq completeq;
530
531 spinlock_t spin_lock;
532 struct tasklet_struct runq_tasklet;
533 u_int qfrozen;
534 pid_t dv_pid;
535 struct timer_list completeq_timer;
536 struct timer_list reset_timer;
537 struct semaphore eh_sem;
538 struct semaphore dv_sem;
539 struct semaphore dv_cmd_sem; /* XXX This needs to be in
540 * the target struct
541 */
542 struct scsi_device *dv_scsi_dev;
543 struct Scsi_Host *host; /* pointer to scsi host */
544#define AHC_LINUX_NOIRQ ((uint32_t)~0)
545 uint32_t irq; /* IRQ for this adapter */
546 uint32_t bios_address;
547 uint32_t mem_busaddr; /* Mem Base Addr */
548 uint64_t hw_dma_mask;
549 ahc_linux_softc_flags flags;
550};
551
552/************************** OS Utility Wrappers *******************************/
553#define printf printk
554#define M_NOWAIT GFP_ATOMIC
555#define M_WAITOK 0
556#define malloc(size, type, flags) kmalloc(size, flags)
557#define free(ptr, type) kfree(ptr)
558
559static __inline void ahc_delay(long);
560static __inline void
561ahc_delay(long usec)
562{
563 /*
564 * udelay on Linux can have problems for
565 * multi-millisecond waits. Wait at most
566 * 1024us per call.
567 */
568 while (usec > 0) {
569 udelay(usec % 1024);
570 usec -= 1024;
571 }
572}
573
574
575/***************************** Low Level I/O **********************************/
576static __inline uint8_t ahc_inb(struct ahc_softc * ahc, long port);
577static __inline void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val);
578static __inline void ahc_outsb(struct ahc_softc * ahc, long port,
579 uint8_t *, int count);
580static __inline void ahc_insb(struct ahc_softc * ahc, long port,
581 uint8_t *, int count);
582
583static __inline uint8_t
584ahc_inb(struct ahc_softc * ahc, long port)
585{
586 uint8_t x;
587
588 if (ahc->tag == BUS_SPACE_MEMIO) {
589 x = readb(ahc->bsh.maddr + port);
590 } else {
591 x = inb(ahc->bsh.ioport + port);
592 }
593 mb();
594 return (x);
595}
596
597static __inline void
598ahc_outb(struct ahc_softc * ahc, long port, uint8_t val)
599{
600 if (ahc->tag == BUS_SPACE_MEMIO) {
601 writeb(val, ahc->bsh.maddr + port);
602 } else {
603 outb(val, ahc->bsh.ioport + port);
604 }
605 mb();
606}
607
608static __inline void
609ahc_outsb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
610{
611 int i;
612
613 /*
614 * There is probably a more efficient way to do this on Linux
615 * but we don't use this for anything speed critical and this
616 * should work.
617 */
618 for (i = 0; i < count; i++)
619 ahc_outb(ahc, port, *array++);
620}
621
622static __inline void
623ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
624{
625 int i;
626
627 /*
628 * There is probably a more efficient way to do this on Linux
629 * but we don't use this for anything speed critical and this
630 * should work.
631 */
632 for (i = 0; i < count; i++)
633 *array++ = ahc_inb(ahc, port);
634}
635
636/**************************** Initialization **********************************/
637int ahc_linux_register_host(struct ahc_softc *,
638 Scsi_Host_Template *);
639
640uint64_t ahc_linux_get_memsize(void);
641
642/*************************** Pretty Printing **********************************/
643struct info_str {
644 char *buffer;
645 int length;
646 off_t offset;
647 int pos;
648};
649
650void ahc_format_transinfo(struct info_str *info,
651 struct ahc_transinfo *tinfo);
652
653/******************************** Locking *************************************/
654/* Lock protecting internal data structures */
655static __inline void ahc_lockinit(struct ahc_softc *);
656static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags);
657static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags);
658
659/* Lock acquisition and release of the above lock in midlayer entry points. */
660static __inline void ahc_midlayer_entrypoint_lock(struct ahc_softc *,
661 unsigned long *flags);
662static __inline void ahc_midlayer_entrypoint_unlock(struct ahc_softc *,
663 unsigned long *flags);
664
665/* Lock held during command compeletion to the upper layer */
666static __inline void ahc_done_lockinit(struct ahc_softc *);
667static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags);
668static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags);
669
670/* Lock held during ahc_list manipulation and ahc softc frees */
671extern spinlock_t ahc_list_spinlock;
672static __inline void ahc_list_lockinit(void);
673static __inline void ahc_list_lock(unsigned long *flags);
674static __inline void ahc_list_unlock(unsigned long *flags);
675
676static __inline void
677ahc_lockinit(struct ahc_softc *ahc)
678{
679 spin_lock_init(&ahc->platform_data->spin_lock);
680}
681
682static __inline void
683ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
684{
685 spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);
686}
687
688static __inline void
689ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
690{
691 spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
692}
693
694static __inline void
695ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags)
696{
697 /*
698 * In 2.5.X and some 2.4.X versions, the midlayer takes our
699 * lock just before calling us, so we avoid locking again.
700 * For other kernel versions, the io_request_lock is taken
701 * just before our entry point is called. In this case, we
702 * trade the io_request_lock for our per-softc lock.
703 */
704#if AHC_SCSI_HAS_HOST_LOCK == 0
705 spin_unlock(&io_request_lock);
706 spin_lock(&ahc->platform_data->spin_lock);
707#endif
708}
709
710static __inline void
711ahc_midlayer_entrypoint_unlock(struct ahc_softc *ahc, unsigned long *flags)
712{
713#if AHC_SCSI_HAS_HOST_LOCK == 0
714 spin_unlock(&ahc->platform_data->spin_lock);
715 spin_lock(&io_request_lock);
716#endif
717}
718
719static __inline void
720ahc_done_lockinit(struct ahc_softc *ahc)
721{
722 /*
723 * In 2.5.X, our own lock is held during completions.
724 * In previous versions, the io_request_lock is used.
725 * In either case, we can't initialize this lock again.
726 */
727}
728
729static __inline void
730ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags)
731{
732#if AHC_SCSI_HAS_HOST_LOCK == 0
733 spin_lock_irqsave(&io_request_lock, *flags);
734#endif
735}
736
737static __inline void
738ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags)
739{
740#if AHC_SCSI_HAS_HOST_LOCK == 0
741 spin_unlock_irqrestore(&io_request_lock, *flags);
742#endif
743}
744
745static __inline void
746ahc_list_lockinit(void)
747{
748 spin_lock_init(&ahc_list_spinlock);
749}
750
751static __inline void
752ahc_list_lock(unsigned long *flags)
753{
754 spin_lock_irqsave(&ahc_list_spinlock, *flags);
755}
756
757static __inline void
758ahc_list_unlock(unsigned long *flags)
759{
760 spin_unlock_irqrestore(&ahc_list_spinlock, *flags);
761}
762
763/******************************* PCI Definitions ******************************/
764/*
765 * PCIM_xxx: mask to locate subfield in register
766 * PCIR_xxx: config register offset
767 * PCIC_xxx: device class
768 * PCIS_xxx: device subclass
769 * PCIP_xxx: device programming interface
770 * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
771 * PCID_xxx: device ID
772 */
773#define PCIR_DEVVENDOR 0x00
774#define PCIR_VENDOR 0x00
775#define PCIR_DEVICE 0x02
776#define PCIR_COMMAND 0x04
777#define PCIM_CMD_PORTEN 0x0001
778#define PCIM_CMD_MEMEN 0x0002
779#define PCIM_CMD_BUSMASTEREN 0x0004
780#define PCIM_CMD_MWRICEN 0x0010
781#define PCIM_CMD_PERRESPEN 0x0040
782#define PCIM_CMD_SERRESPEN 0x0100
783#define PCIR_STATUS 0x06
784#define PCIR_REVID 0x08
785#define PCIR_PROGIF 0x09
786#define PCIR_SUBCLASS 0x0a
787#define PCIR_CLASS 0x0b
788#define PCIR_CACHELNSZ 0x0c
789#define PCIR_LATTIMER 0x0d
790#define PCIR_HEADERTYPE 0x0e
791#define PCIM_MFDEV 0x80
792#define PCIR_BIST 0x0f
793#define PCIR_CAP_PTR 0x34
794
795/* config registers for header type 0 devices */
796#define PCIR_MAPS 0x10
797#define PCIR_SUBVEND_0 0x2c
798#define PCIR_SUBDEV_0 0x2e
799
800extern struct pci_driver aic7xxx_pci_driver;
801
802typedef enum
803{
804 AHC_POWER_STATE_D0,
805 AHC_POWER_STATE_D1,
806 AHC_POWER_STATE_D2,
807 AHC_POWER_STATE_D3
808} ahc_power_state;
809
810/**************************** VL/EISA Routines ********************************/
811#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \
812 && (defined(__i386__) || defined(__alpha__)) \
813 && (!defined(CONFIG_EISA)))
814#define CONFIG_EISA
815#endif
816
817#ifdef CONFIG_EISA
818extern uint32_t aic7xxx_probe_eisa_vl;
819int ahc_linux_eisa_init(void);
820void ahc_linux_eisa_exit(void);
821int aic7770_map_registers(struct ahc_softc *ahc,
822 u_int port);
823int aic7770_map_int(struct ahc_softc *ahc, u_int irq);
824#else
825static inline int ahc_linux_eisa_init(void) {
826 return -ENODEV;
827}
828static inline void ahc_linux_eisa_exit(void) {
829}
830#endif
831
832/******************************* PCI Routines *********************************/
833#ifdef CONFIG_PCI
834int ahc_linux_pci_init(void);
835void ahc_linux_pci_exit(void);
836int ahc_pci_map_registers(struct ahc_softc *ahc);
837int ahc_pci_map_int(struct ahc_softc *ahc);
838
839static __inline uint32_t ahc_pci_read_config(ahc_dev_softc_t pci,
840 int reg, int width);
841
842static __inline uint32_t
843ahc_pci_read_config(ahc_dev_softc_t pci, int reg, int width)
844{
845 switch (width) {
846 case 1:
847 {
848 uint8_t retval;
849
850 pci_read_config_byte(pci, reg, &retval);
851 return (retval);
852 }
853 case 2:
854 {
855 uint16_t retval;
856 pci_read_config_word(pci, reg, &retval);
857 return (retval);
858 }
859 case 4:
860 {
861 uint32_t retval;
862 pci_read_config_dword(pci, reg, &retval);
863 return (retval);
864 }
865 default:
866 panic("ahc_pci_read_config: Read size too big");
867 /* NOTREACHED */
868 return (0);
869 }
870}
871
872static __inline void ahc_pci_write_config(ahc_dev_softc_t pci,
873 int reg, uint32_t value,
874 int width);
875
876static __inline void
877ahc_pci_write_config(ahc_dev_softc_t pci, int reg, uint32_t value, int width)
878{
879 switch (width) {
880 case 1:
881 pci_write_config_byte(pci, reg, value);
882 break;
883 case 2:
884 pci_write_config_word(pci, reg, value);
885 break;
886 case 4:
887 pci_write_config_dword(pci, reg, value);
888 break;
889 default:
890 panic("ahc_pci_write_config: Write size too big");
891 /* NOTREACHED */
892 }
893}
894
895static __inline int ahc_get_pci_function(ahc_dev_softc_t);
896static __inline int
897ahc_get_pci_function(ahc_dev_softc_t pci)
898{
899 return (PCI_FUNC(pci->devfn));
900}
901
902static __inline int ahc_get_pci_slot(ahc_dev_softc_t);
903static __inline int
904ahc_get_pci_slot(ahc_dev_softc_t pci)
905{
906 return (PCI_SLOT(pci->devfn));
907}
908
909static __inline int ahc_get_pci_bus(ahc_dev_softc_t);
910static __inline int
911ahc_get_pci_bus(ahc_dev_softc_t pci)
912{
913 return (pci->bus->number);
914}
915#else
916static inline int ahc_linux_pci_init(void) {
917 return 0;
918}
919static inline void ahc_linux_pci_exit(void) {
920}
921#endif
922
923static __inline void ahc_flush_device_writes(struct ahc_softc *);
924static __inline void
925ahc_flush_device_writes(struct ahc_softc *ahc)
926{
927 /* XXX Is this sufficient for all architectures??? */
928 ahc_inb(ahc, INTSTAT);
929}
930
931/**************************** Proc FS Support *********************************/
932#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
933int ahc_linux_proc_info(char *, char **, off_t, int, int, int);
934#else
935int ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
936 off_t, int, int);
937#endif
938
939/*************************** Domain Validation ********************************/
940#define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete)
941#define AHC_DV_SIMQ_FROZEN(ahc) \
942 ((((ahc)->platform_data->flags & AHC_DV_ACTIVE) != 0) \
943 && (ahc)->platform_data->qfrozen == 1)
944
945/*********************** Transaction Access Wrappers *************************/
946static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
947static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
948static __inline void ahc_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t);
949static __inline void ahc_set_scsi_status(struct scb *, uint32_t);
950static __inline uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd);
951static __inline uint32_t ahc_get_transaction_status(struct scb *);
952static __inline uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd);
953static __inline uint32_t ahc_get_scsi_status(struct scb *);
954static __inline void ahc_set_transaction_tag(struct scb *, int, u_int);
955static __inline u_long ahc_get_transfer_length(struct scb *);
956static __inline int ahc_get_transfer_dir(struct scb *);
957static __inline void ahc_set_residual(struct scb *, u_long);
958static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
959static __inline u_long ahc_get_residual(struct scb *);
960static __inline u_long ahc_get_sense_residual(struct scb *);
961static __inline int ahc_perform_autosense(struct scb *);
962static __inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
963 struct scb *);
964static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
965 struct ahc_devinfo *);
966static __inline void ahc_platform_scb_free(struct ahc_softc *ahc,
967 struct scb *scb);
968static __inline void ahc_freeze_scb(struct scb *scb);
969
970static __inline
971void ahc_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status)
972{
973 cmd->result &= ~(CAM_STATUS_MASK << 16);
974 cmd->result |= status << 16;
975}
976
977static __inline
978void ahc_set_transaction_status(struct scb *scb, uint32_t status)
979{
980 ahc_cmd_set_transaction_status(scb->io_ctx,status);
981}
982
983static __inline
984void ahc_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status)
985{
986 cmd->result &= ~0xFFFF;
987 cmd->result |= status;
988}
989
990static __inline
991void ahc_set_scsi_status(struct scb *scb, uint32_t status)
992{
993 ahc_cmd_set_scsi_status(scb->io_ctx, status);
994}
995
996static __inline
997uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd)
998{
999 return ((cmd->result >> 16) & CAM_STATUS_MASK);
1000}
1001
1002static __inline
1003uint32_t ahc_get_transaction_status(struct scb *scb)
1004{
1005 return (ahc_cmd_get_transaction_status(scb->io_ctx));
1006}
1007
1008static __inline
1009uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd)
1010{
1011 return (cmd->result & 0xFFFF);
1012}
1013
1014static __inline
1015uint32_t ahc_get_scsi_status(struct scb *scb)
1016{
1017 return (ahc_cmd_get_scsi_status(scb->io_ctx));
1018}
1019
1020static __inline
1021void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
1022{
1023 /*
1024 * Nothing to do for linux as the incoming transaction
1025 * has no concept of tag/non tagged, etc.
1026 */
1027}
1028
1029static __inline
1030u_long ahc_get_transfer_length(struct scb *scb)
1031{
1032 return (scb->platform_data->xfer_len);
1033}
1034
1035static __inline
1036int ahc_get_transfer_dir(struct scb *scb)
1037{
1038 return (scb->io_ctx->sc_data_direction);
1039}
1040
1041static __inline
1042void ahc_set_residual(struct scb *scb, u_long resid)
1043{
1044 scb->io_ctx->resid = resid;
1045}
1046
1047static __inline
1048void ahc_set_sense_residual(struct scb *scb, u_long resid)
1049{
1050 scb->platform_data->sense_resid = resid;
1051}
1052
1053static __inline
1054u_long ahc_get_residual(struct scb *scb)
1055{
1056 return (scb->io_ctx->resid);
1057}
1058
1059static __inline
1060u_long ahc_get_sense_residual(struct scb *scb)
1061{
1062 return (scb->platform_data->sense_resid);
1063}
1064
1065static __inline
1066int ahc_perform_autosense(struct scb *scb)
1067{
1068 /*
1069 * We always perform autosense in Linux.
1070 * On other platforms this is set on a
1071 * per-transaction basis.
1072 */
1073 return (1);
1074}
1075
1076static __inline uint32_t
1077ahc_get_sense_bufsize(struct ahc_softc *ahc, struct scb *scb)
1078{
1079 return (sizeof(struct scsi_sense_data));
1080}
1081
1082static __inline void
1083ahc_notify_xfer_settings_change(struct ahc_softc *ahc,
1084 struct ahc_devinfo *devinfo)
1085{
1086 /* Nothing to do here for linux */
1087}
1088
1089static __inline void
1090ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb)
1091{
1092 ahc->flags &= ~AHC_RESOURCE_SHORTAGE;
1093}
1094
1095int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
1096void ahc_platform_free(struct ahc_softc *ahc);
1097void ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
1098
1099static __inline void
1100ahc_freeze_scb(struct scb *scb)
1101{
1102 if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
1103 scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
1104 scb->platform_data->dev->qfrozen++;
1105 }
1106}
1107
1108void ahc_platform_set_tags(struct ahc_softc *ahc,
1109 struct ahc_devinfo *devinfo, ahc_queue_alg);
1110int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
1111 char channel, int lun, u_int tag,
1112 role_t role, uint32_t status);
1113irqreturn_t
1114 ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
1115void ahc_platform_flushwork(struct ahc_softc *ahc);
1116int ahc_softc_comp(struct ahc_softc *, struct ahc_softc *);
1117void ahc_done(struct ahc_softc*, struct scb*);
1118void ahc_send_async(struct ahc_softc *, char channel,
1119 u_int target, u_int lun, ac_code, void *);
1120void ahc_print_path(struct ahc_softc *, struct scb *);
1121void ahc_platform_dump_card_state(struct ahc_softc *ahc);
1122
1123#ifdef CONFIG_PCI
1124#define AHC_PCI_CONFIG 1
1125#else
1126#define AHC_PCI_CONFIG 0
1127#endif
1128#define bootverbose aic7xxx_verbose
1129extern u_int aic7xxx_verbose;
1130#endif /* _AIC7XXX_LINUX_H_ */
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
new file mode 100644
index 000000000000..6f6674aa31ef
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -0,0 +1,389 @@
1/*
2 * Linux driver attachment glue for PCI based controllers.
3 *
4 * Copyright (c) 2000-2001 Adaptec Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon
16 * including a substantially similar Disclaimer requirement for further
17 * binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * Alternatively, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2 as published by the Free
24 * Software Foundation.
25 *
26 * NO WARRANTY
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGES.
38 *
39 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#47 $
40 */
41
42#include "aic7xxx_osm.h"
43#include "aic7xxx_pci.h"
44
45static int ahc_linux_pci_dev_probe(struct pci_dev *pdev,
46 const struct pci_device_id *ent);
47static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc,
48 u_long *base);
49static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
50 u_long *bus_addr,
51 uint8_t __iomem **maddr);
52static void ahc_linux_pci_dev_remove(struct pci_dev *pdev);
53
54/* Define the macro locally since it's different for different class of chips.
55*/
56#define ID(x) ID_C(x, PCI_CLASS_STORAGE_SCSI)
57
58static struct pci_device_id ahc_linux_pci_id_table[] = {
59 /* aic7850 based controllers */
60 ID(ID_AHA_2902_04_10_15_20C_30C),
61 /* aic7860 based controllers */
62 ID(ID_AHA_2930CU),
63 ID(ID_AHA_1480A & ID_DEV_VENDOR_MASK),
64 ID(ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK),
65 ID(ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK),
66 ID(ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK),
67 /* aic7870 based controllers */
68 ID(ID_AHA_2940),
69 ID(ID_AHA_3940),
70 ID(ID_AHA_398X),
71 ID(ID_AHA_2944),
72 ID(ID_AHA_3944),
73 ID(ID_AHA_4944),
74 /* aic7880 based controllers */
75 ID(ID_AHA_2940U & ID_DEV_VENDOR_MASK),
76 ID(ID_AHA_3940U & ID_DEV_VENDOR_MASK),
77 ID(ID_AHA_2944U & ID_DEV_VENDOR_MASK),
78 ID(ID_AHA_3944U & ID_DEV_VENDOR_MASK),
79 ID(ID_AHA_398XU & ID_DEV_VENDOR_MASK),
80 ID(ID_AHA_4944U & ID_DEV_VENDOR_MASK),
81 ID(ID_AHA_2930U & ID_DEV_VENDOR_MASK),
82 ID(ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK),
83 ID(ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK),
84 /* aic7890 based controllers */
85 ID(ID_AHA_2930U2),
86 ID(ID_AHA_2940U2B),
87 ID(ID_AHA_2940U2_OEM),
88 ID(ID_AHA_2940U2),
89 ID(ID_AHA_2950U2B),
90 ID16(ID_AIC7890_ARO & ID_AIC7895_ARO_MASK),
91 ID(ID_AAA_131U2),
92 /* aic7890 based controllers */
93 ID(ID_AHA_29160),
94 ID(ID_AHA_29160_CPQ),
95 ID(ID_AHA_29160N),
96 ID(ID_AHA_29160C),
97 ID(ID_AHA_29160B),
98 ID(ID_AHA_19160B),
99 ID(ID_AIC7892_ARO),
100 /* aic7892 based controllers */
101 ID(ID_AHA_2940U_DUAL),
102 ID(ID_AHA_3940AU),
103 ID(ID_AHA_3944AU),
104 ID(ID_AIC7895_ARO),
105 ID(ID_AHA_3950U2B_0),
106 ID(ID_AHA_3950U2B_1),
107 ID(ID_AHA_3950U2D_0),
108 ID(ID_AHA_3950U2D_1),
109 ID(ID_AIC7896_ARO),
110 /* aic7899 based controllers */
111 ID(ID_AHA_3960D),
112 ID(ID_AHA_3960D_CPQ),
113 ID(ID_AIC7899_ARO),
114 /* Generic chip probes for devices we don't know exactly. */
115 ID(ID_AIC7850 & ID_DEV_VENDOR_MASK),
116 ID(ID_AIC7855 & ID_DEV_VENDOR_MASK),
117 ID(ID_AIC7859 & ID_DEV_VENDOR_MASK),
118 ID(ID_AIC7860 & ID_DEV_VENDOR_MASK),
119 ID(ID_AIC7870 & ID_DEV_VENDOR_MASK),
120 ID(ID_AIC7880 & ID_DEV_VENDOR_MASK),
121 ID16(ID_AIC7890 & ID_9005_GENERIC_MASK),
122 ID16(ID_AIC7892 & ID_9005_GENERIC_MASK),
123 ID(ID_AIC7895 & ID_DEV_VENDOR_MASK),
124 ID16(ID_AIC7896 & ID_9005_GENERIC_MASK),
125 ID16(ID_AIC7899 & ID_9005_GENERIC_MASK),
126 ID(ID_AIC7810 & ID_DEV_VENDOR_MASK),
127 ID(ID_AIC7815 & ID_DEV_VENDOR_MASK),
128 { 0 }
129};
130
131MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table);
132
133struct pci_driver aic7xxx_pci_driver = {
134 .name = "aic7xxx",
135 .probe = ahc_linux_pci_dev_probe,
136 .remove = ahc_linux_pci_dev_remove,
137 .id_table = ahc_linux_pci_id_table
138};
139
140static void
141ahc_linux_pci_dev_remove(struct pci_dev *pdev)
142{
143 struct ahc_softc *ahc;
144 u_long l;
145
146 /*
147 * We should be able to just perform
148 * the free directly, but check our
149 * list for extra sanity.
150 */
151 ahc_list_lock(&l);
152 ahc = ahc_find_softc((struct ahc_softc *)pci_get_drvdata(pdev));
153 if (ahc != NULL) {
154 u_long s;
155
156 TAILQ_REMOVE(&ahc_tailq, ahc, links);
157 ahc_list_unlock(&l);
158 ahc_lock(ahc, &s);
159 ahc_intr_enable(ahc, FALSE);
160 ahc_unlock(ahc, &s);
161 ahc_free(ahc);
162 } else
163 ahc_list_unlock(&l);
164}
165
166static int
167ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
168{
169 char buf[80];
170 const uint64_t mask_39bit = 0x7FFFFFFFFFULL;
171 struct ahc_softc *ahc;
172 ahc_dev_softc_t pci;
173 struct ahc_pci_identity *entry;
174 char *name;
175 int error;
176
177 /*
178 * Some BIOSen report the same device multiple times.
179 */
180 TAILQ_FOREACH(ahc, &ahc_tailq, links) {
181 struct pci_dev *probed_pdev;
182
183 probed_pdev = ahc->dev_softc;
184 if (probed_pdev->bus->number == pdev->bus->number
185 && probed_pdev->devfn == pdev->devfn)
186 break;
187 }
188 if (ahc != NULL) {
189 /* Skip duplicate. */
190 return (-ENODEV);
191 }
192
193 pci = pdev;
194 entry = ahc_find_pci_device(pci);
195 if (entry == NULL)
196 return (-ENODEV);
197
198 /*
199 * Allocate a softc for this card and
200 * set it up for attachment by our
201 * common detect routine.
202 */
203 sprintf(buf, "ahc_pci:%d:%d:%d",
204 ahc_get_pci_bus(pci),
205 ahc_get_pci_slot(pci),
206 ahc_get_pci_function(pci));
207 name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
208 if (name == NULL)
209 return (-ENOMEM);
210 strcpy(name, buf);
211 ahc = ahc_alloc(NULL, name);
212 if (ahc == NULL)
213 return (-ENOMEM);
214 if (pci_enable_device(pdev)) {
215 ahc_free(ahc);
216 return (-ENODEV);
217 }
218 pci_set_master(pdev);
219
220 if (sizeof(dma_addr_t) > 4
221 && ahc_linux_get_memsize() > 0x80000000
222 && pci_set_dma_mask(pdev, mask_39bit) == 0) {
223 ahc->flags |= AHC_39BIT_ADDRESSING;
224 ahc->platform_data->hw_dma_mask = mask_39bit;
225 } else {
226 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
227 printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
228 return (-ENODEV);
229 }
230 ahc->platform_data->hw_dma_mask = DMA_32BIT_MASK;
231 }
232 ahc->dev_softc = pci;
233 error = ahc_pci_config(ahc, entry);
234 if (error != 0) {
235 ahc_free(ahc);
236 return (-error);
237 }
238 pci_set_drvdata(pdev, ahc);
239 if (aic7xxx_detect_complete) {
240#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
241 ahc_linux_register_host(ahc, &aic7xxx_driver_template);
242#else
243 printf("aic7xxx: ignoring PCI device found after "
244 "initialization\n");
245 return (-ENODEV);
246#endif
247 }
248 return (0);
249}
250
251int
252ahc_linux_pci_init(void)
253{
254 /* Translate error or zero return into zero or one */
255 return pci_module_init(&aic7xxx_pci_driver) ? 0 : 1;
256}
257
258void
259ahc_linux_pci_exit(void)
260{
261 pci_unregister_driver(&aic7xxx_pci_driver);
262}
263
264static int
265ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base)
266{
267 if (aic7xxx_allow_memio == 0)
268 return (ENOMEM);
269
270 *base = pci_resource_start(ahc->dev_softc, 0);
271 if (*base == 0)
272 return (ENOMEM);
273 if (request_region(*base, 256, "aic7xxx") == 0)
274 return (ENOMEM);
275 return (0);
276}
277
278static int
279ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
280 u_long *bus_addr,
281 uint8_t __iomem **maddr)
282{
283 u_long start;
284 int error;
285
286 error = 0;
287 start = pci_resource_start(ahc->dev_softc, 1);
288 if (start != 0) {
289 *bus_addr = start;
290 if (request_mem_region(start, 0x1000, "aic7xxx") == 0)
291 error = ENOMEM;
292 if (error == 0) {
293 *maddr = ioremap_nocache(start, 256);
294 if (*maddr == NULL) {
295 error = ENOMEM;
296 release_mem_region(start, 0x1000);
297 }
298 }
299 } else
300 error = ENOMEM;
301 return (error);
302}
303
304int
305ahc_pci_map_registers(struct ahc_softc *ahc)
306{
307 uint32_t command;
308 u_long base;
309 uint8_t __iomem *maddr;
310 int error;
311
312 /*
313 * If its allowed, we prefer memory mapped access.
314 */
315 command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, 4);
316 command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
317 base = 0;
318 maddr = NULL;
319 error = ahc_linux_pci_reserve_mem_region(ahc, &base, &maddr);
320 if (error == 0) {
321 ahc->platform_data->mem_busaddr = base;
322 ahc->tag = BUS_SPACE_MEMIO;
323 ahc->bsh.maddr = maddr;
324 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
325 command | PCIM_CMD_MEMEN, 4);
326
327 /*
328 * Do a quick test to see if memory mapped
329 * I/O is functioning correctly.
330 */
331 if (ahc_pci_test_register_access(ahc) != 0) {
332
333 printf("aic7xxx: PCI Device %d:%d:%d "
334 "failed memory mapped test. Using PIO.\n",
335 ahc_get_pci_bus(ahc->dev_softc),
336 ahc_get_pci_slot(ahc->dev_softc),
337 ahc_get_pci_function(ahc->dev_softc));
338 iounmap(maddr);
339 release_mem_region(ahc->platform_data->mem_busaddr,
340 0x1000);
341 ahc->bsh.maddr = NULL;
342 maddr = NULL;
343 } else
344 command |= PCIM_CMD_MEMEN;
345 } else {
346 printf("aic7xxx: PCI%d:%d:%d MEM region 0x%lx "
347 "unavailable. Cannot memory map device.\n",
348 ahc_get_pci_bus(ahc->dev_softc),
349 ahc_get_pci_slot(ahc->dev_softc),
350 ahc_get_pci_function(ahc->dev_softc),
351 base);
352 }
353
354 /*
355 * We always prefer memory mapped access.
356 */
357 if (maddr == NULL) {
358
359 error = ahc_linux_pci_reserve_io_region(ahc, &base);
360 if (error == 0) {
361 ahc->tag = BUS_SPACE_PIO;
362 ahc->bsh.ioport = base;
363 command |= PCIM_CMD_PORTEN;
364 } else {
365 printf("aic7xxx: PCI%d:%d:%d IO region 0x%lx[0..255] "
366 "unavailable. Cannot map device.\n",
367 ahc_get_pci_bus(ahc->dev_softc),
368 ahc_get_pci_slot(ahc->dev_softc),
369 ahc_get_pci_function(ahc->dev_softc),
370 base);
371 }
372 }
373 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, 4);
374 return (error);
375}
376
377int
378ahc_pci_map_int(struct ahc_softc *ahc)
379{
380 int error;
381
382 error = request_irq(ahc->dev_softc->irq, ahc_linux_isr,
383 SA_SHIRQ, "aic7xxx", ahc);
384 if (error == 0)
385 ahc->platform_data->irq = ahc->dev_softc->irq;
386
387 return (-error);
388}
389
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
new file mode 100644
index 000000000000..7ddcc97fb243
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c
@@ -0,0 +1,2407 @@
1/*
2 * Product specific probe and attach routines for:
3 * 3940, 2940, aic7895, aic7890, aic7880,
4 * aic7870, aic7860 and aic7850 SCSI controllers
5 *
6 * Copyright (c) 1994-2001 Justin T. Gibbs.
7 * Copyright (c) 2000-2001 Adaptec Inc.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions, and the following disclaimer,
15 * without modification.
16 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
17 * substantially similar to the "NO WARRANTY" disclaimer below
18 * ("Disclaimer") and any redistribution must be conditioned upon
19 * including a substantially similar Disclaimer requirement for further
20 * binary redistribution.
21 * 3. Neither the names of the above-listed copyright holders nor the names
22 * of any contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * Alternatively, this software may be distributed under the terms of the
26 * GNU General Public License ("GPL") version 2 as published by the Free
27 * Software Foundation.
28 *
29 * NO WARRANTY
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
39 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGES.
41 *
42 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#69 $
43 *
44 * $FreeBSD$
45 */
46
47#ifdef __linux__
48#include "aic7xxx_osm.h"
49#include "aic7xxx_inline.h"
50#include "aic7xxx_93cx6.h"
51#else
52#include <dev/aic7xxx/aic7xxx_osm.h>
53#include <dev/aic7xxx/aic7xxx_inline.h>
54#include <dev/aic7xxx/aic7xxx_93cx6.h>
55#endif
56
57#include "aic7xxx_pci.h"
58
59static __inline uint64_t
60ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
61{
62 uint64_t id;
63
64 id = subvendor
65 | (subdevice << 16)
66 | ((uint64_t)vendor << 32)
67 | ((uint64_t)device << 48);
68
69 return (id);
70}
71
72#define AHC_PCI_IOADDR PCIR_MAPS /* I/O Address */
73#define AHC_PCI_MEMADDR (PCIR_MAPS + 4) /* Mem I/O Address */
74
75#define DEVID_9005_TYPE(id) ((id) & 0xF)
76#define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */
77#define DEVID_9005_TYPE_AAA 0x3 /* RAID Card */
78#define DEVID_9005_TYPE_SISL 0x5 /* Container ROMB */
79#define DEVID_9005_TYPE_MB 0xF /* On Motherboard */
80
81#define DEVID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
82#define DEVID_9005_MAXRATE_U160 0x0
83#define DEVID_9005_MAXRATE_ULTRA2 0x1
84#define DEVID_9005_MAXRATE_ULTRA 0x2
85#define DEVID_9005_MAXRATE_FAST 0x3
86
87#define DEVID_9005_MFUNC(id) (((id) & 0x40) >> 6)
88
89#define DEVID_9005_CLASS(id) (((id) & 0xFF00) >> 8)
90#define DEVID_9005_CLASS_SPI 0x0 /* Parallel SCSI */
91
92#define SUBID_9005_TYPE(id) ((id) & 0xF)
93#define SUBID_9005_TYPE_MB 0xF /* On Motherboard */
94#define SUBID_9005_TYPE_CARD 0x0 /* Standard Card */
95#define SUBID_9005_TYPE_LCCARD 0x1 /* Low Cost Card */
96#define SUBID_9005_TYPE_RAID 0x3 /* Combined with Raid */
97
98#define SUBID_9005_TYPE_KNOWN(id) \
99 ((((id) & 0xF) == SUBID_9005_TYPE_MB) \
100 || (((id) & 0xF) == SUBID_9005_TYPE_CARD) \
101 || (((id) & 0xF) == SUBID_9005_TYPE_LCCARD) \
102 || (((id) & 0xF) == SUBID_9005_TYPE_RAID))
103
104#define SUBID_9005_MAXRATE(id) (((id) & 0x30) >> 4)
105#define SUBID_9005_MAXRATE_ULTRA2 0x0
106#define SUBID_9005_MAXRATE_ULTRA 0x1
107#define SUBID_9005_MAXRATE_U160 0x2
108#define SUBID_9005_MAXRATE_RESERVED 0x3
109
110#define SUBID_9005_SEEPTYPE(id) \
111 ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
112 ? ((id) & 0xC0) >> 6 \
113 : ((id) & 0x300) >> 8)
114#define SUBID_9005_SEEPTYPE_NONE 0x0
115#define SUBID_9005_SEEPTYPE_1K 0x1
116#define SUBID_9005_SEEPTYPE_2K_4K 0x2
117#define SUBID_9005_SEEPTYPE_RESERVED 0x3
118#define SUBID_9005_AUTOTERM(id) \
119 ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
120 ? (((id) & 0x400) >> 10) == 0 \
121 : (((id) & 0x40) >> 6) == 0)
122
123#define SUBID_9005_NUMCHAN(id) \
124 ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
125 ? ((id) & 0x300) >> 8 \
126 : ((id) & 0xC00) >> 10)
127
128#define SUBID_9005_LEGACYCONN(id) \
129 ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
130 ? 0 \
131 : ((id) & 0x80) >> 7)
132
133#define SUBID_9005_MFUNCENB(id) \
134 ((SUBID_9005_TYPE(id) == SUBID_9005_TYPE_MB) \
135 ? ((id) & 0x800) >> 11 \
136 : ((id) & 0x1000) >> 12)
137/*
138 * Informational only. Should use chip register to be
139 * certain, but may be use in identification strings.
140 */
141#define SUBID_9005_CARD_SCSIWIDTH_MASK 0x2000
142#define SUBID_9005_CARD_PCIWIDTH_MASK 0x4000
143#define SUBID_9005_CARD_SEDIFF_MASK 0x8000
144
145static ahc_device_setup_t ahc_aic785X_setup;
146static ahc_device_setup_t ahc_aic7860_setup;
147static ahc_device_setup_t ahc_apa1480_setup;
148static ahc_device_setup_t ahc_aic7870_setup;
149static ahc_device_setup_t ahc_aha394X_setup;
150static ahc_device_setup_t ahc_aha494X_setup;
151static ahc_device_setup_t ahc_aha398X_setup;
152static ahc_device_setup_t ahc_aic7880_setup;
153static ahc_device_setup_t ahc_aha2940Pro_setup;
154static ahc_device_setup_t ahc_aha394XU_setup;
155static ahc_device_setup_t ahc_aha398XU_setup;
156static ahc_device_setup_t ahc_aic7890_setup;
157static ahc_device_setup_t ahc_aic7892_setup;
158static ahc_device_setup_t ahc_aic7895_setup;
159static ahc_device_setup_t ahc_aic7896_setup;
160static ahc_device_setup_t ahc_aic7899_setup;
161static ahc_device_setup_t ahc_aha29160C_setup;
162static ahc_device_setup_t ahc_raid_setup;
163static ahc_device_setup_t ahc_aha394XX_setup;
164static ahc_device_setup_t ahc_aha494XX_setup;
165static ahc_device_setup_t ahc_aha398XX_setup;
166
167struct ahc_pci_identity ahc_pci_ident_table [] =
168{
169 /* aic7850 based controllers */
170 {
171 ID_AHA_2902_04_10_15_20C_30C,
172 ID_ALL_MASK,
173 "Adaptec 2902/04/10/15/20C/30C SCSI adapter",
174 ahc_aic785X_setup
175 },
176 /* aic7860 based controllers */
177 {
178 ID_AHA_2930CU,
179 ID_ALL_MASK,
180 "Adaptec 2930CU SCSI adapter",
181 ahc_aic7860_setup
182 },
183 {
184 ID_AHA_1480A & ID_DEV_VENDOR_MASK,
185 ID_DEV_VENDOR_MASK,
186 "Adaptec 1480A Ultra SCSI adapter",
187 ahc_apa1480_setup
188 },
189 {
190 ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK,
191 ID_DEV_VENDOR_MASK,
192 "Adaptec 2940A Ultra SCSI adapter",
193 ahc_aic7860_setup
194 },
195 {
196 ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK,
197 ID_DEV_VENDOR_MASK,
198 "Adaptec 2940A/CN Ultra SCSI adapter",
199 ahc_aic7860_setup
200 },
201 {
202 ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK,
203 ID_DEV_VENDOR_MASK,
204 "Adaptec 2930C Ultra SCSI adapter (VAR)",
205 ahc_aic7860_setup
206 },
207 /* aic7870 based controllers */
208 {
209 ID_AHA_2940,
210 ID_ALL_MASK,
211 "Adaptec 2940 SCSI adapter",
212 ahc_aic7870_setup
213 },
214 {
215 ID_AHA_3940,
216 ID_ALL_MASK,
217 "Adaptec 3940 SCSI adapter",
218 ahc_aha394X_setup
219 },
220 {
221 ID_AHA_398X,
222 ID_ALL_MASK,
223 "Adaptec 398X SCSI RAID adapter",
224 ahc_aha398X_setup
225 },
226 {
227 ID_AHA_2944,
228 ID_ALL_MASK,
229 "Adaptec 2944 SCSI adapter",
230 ahc_aic7870_setup
231 },
232 {
233 ID_AHA_3944,
234 ID_ALL_MASK,
235 "Adaptec 3944 SCSI adapter",
236 ahc_aha394X_setup
237 },
238 {
239 ID_AHA_4944,
240 ID_ALL_MASK,
241 "Adaptec 4944 SCSI adapter",
242 ahc_aha494X_setup
243 },
244 /* aic7880 based controllers */
245 {
246 ID_AHA_2940U & ID_DEV_VENDOR_MASK,
247 ID_DEV_VENDOR_MASK,
248 "Adaptec 2940 Ultra SCSI adapter",
249 ahc_aic7880_setup
250 },
251 {
252 ID_AHA_3940U & ID_DEV_VENDOR_MASK,
253 ID_DEV_VENDOR_MASK,
254 "Adaptec 3940 Ultra SCSI adapter",
255 ahc_aha394XU_setup
256 },
257 {
258 ID_AHA_2944U & ID_DEV_VENDOR_MASK,
259 ID_DEV_VENDOR_MASK,
260 "Adaptec 2944 Ultra SCSI adapter",
261 ahc_aic7880_setup
262 },
263 {
264 ID_AHA_3944U & ID_DEV_VENDOR_MASK,
265 ID_DEV_VENDOR_MASK,
266 "Adaptec 3944 Ultra SCSI adapter",
267 ahc_aha394XU_setup
268 },
269 {
270 ID_AHA_398XU & ID_DEV_VENDOR_MASK,
271 ID_DEV_VENDOR_MASK,
272 "Adaptec 398X Ultra SCSI RAID adapter",
273 ahc_aha398XU_setup
274 },
275 {
276 /*
277 * XXX Don't know the slot numbers
278 * so we can't identify channels
279 */
280 ID_AHA_4944U & ID_DEV_VENDOR_MASK,
281 ID_DEV_VENDOR_MASK,
282 "Adaptec 4944 Ultra SCSI adapter",
283 ahc_aic7880_setup
284 },
285 {
286 ID_AHA_2930U & ID_DEV_VENDOR_MASK,
287 ID_DEV_VENDOR_MASK,
288 "Adaptec 2930 Ultra SCSI adapter",
289 ahc_aic7880_setup
290 },
291 {
292 ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK,
293 ID_DEV_VENDOR_MASK,
294 "Adaptec 2940 Pro Ultra SCSI adapter",
295 ahc_aha2940Pro_setup
296 },
297 {
298 ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK,
299 ID_DEV_VENDOR_MASK,
300 "Adaptec 2940/CN Ultra SCSI adapter",
301 ahc_aic7880_setup
302 },
303 /* Ignore all SISL (AAC on MB) based controllers. */
304 {
305 ID_9005_SISL_ID,
306 ID_9005_SISL_MASK,
307 NULL,
308 NULL
309 },
310 /* aic7890 based controllers */
311 {
312 ID_AHA_2930U2,
313 ID_ALL_MASK,
314 "Adaptec 2930 Ultra2 SCSI adapter",
315 ahc_aic7890_setup
316 },
317 {
318 ID_AHA_2940U2B,
319 ID_ALL_MASK,
320 "Adaptec 2940B Ultra2 SCSI adapter",
321 ahc_aic7890_setup
322 },
323 {
324 ID_AHA_2940U2_OEM,
325 ID_ALL_MASK,
326 "Adaptec 2940 Ultra2 SCSI adapter (OEM)",
327 ahc_aic7890_setup
328 },
329 {
330 ID_AHA_2940U2,
331 ID_ALL_MASK,
332 "Adaptec 2940 Ultra2 SCSI adapter",
333 ahc_aic7890_setup
334 },
335 {
336 ID_AHA_2950U2B,
337 ID_ALL_MASK,
338 "Adaptec 2950 Ultra2 SCSI adapter",
339 ahc_aic7890_setup
340 },
341 {
342 ID_AIC7890_ARO,
343 ID_ALL_MASK,
344 "Adaptec aic7890/91 Ultra2 SCSI adapter (ARO)",
345 ahc_aic7890_setup
346 },
347 {
348 ID_AAA_131U2,
349 ID_ALL_MASK,
350 "Adaptec AAA-131 Ultra2 RAID adapter",
351 ahc_aic7890_setup
352 },
353 /* aic7892 based controllers */
354 {
355 ID_AHA_29160,
356 ID_ALL_MASK,
357 "Adaptec 29160 Ultra160 SCSI adapter",
358 ahc_aic7892_setup
359 },
360 {
361 ID_AHA_29160_CPQ,
362 ID_ALL_MASK,
363 "Adaptec (Compaq OEM) 29160 Ultra160 SCSI adapter",
364 ahc_aic7892_setup
365 },
366 {
367 ID_AHA_29160N,
368 ID_ALL_MASK,
369 "Adaptec 29160N Ultra160 SCSI adapter",
370 ahc_aic7892_setup
371 },
372 {
373 ID_AHA_29160C,
374 ID_ALL_MASK,
375 "Adaptec 29160C Ultra160 SCSI adapter",
376 ahc_aha29160C_setup
377 },
378 {
379 ID_AHA_29160B,
380 ID_ALL_MASK,
381 "Adaptec 29160B Ultra160 SCSI adapter",
382 ahc_aic7892_setup
383 },
384 {
385 ID_AHA_19160B,
386 ID_ALL_MASK,
387 "Adaptec 19160B Ultra160 SCSI adapter",
388 ahc_aic7892_setup
389 },
390 {
391 ID_AIC7892_ARO,
392 ID_ALL_MASK,
393 "Adaptec aic7892 Ultra160 SCSI adapter (ARO)",
394 ahc_aic7892_setup
395 },
396 /* aic7895 based controllers */
397 {
398 ID_AHA_2940U_DUAL,
399 ID_ALL_MASK,
400 "Adaptec 2940/DUAL Ultra SCSI adapter",
401 ahc_aic7895_setup
402 },
403 {
404 ID_AHA_3940AU,
405 ID_ALL_MASK,
406 "Adaptec 3940A Ultra SCSI adapter",
407 ahc_aic7895_setup
408 },
409 {
410 ID_AHA_3944AU,
411 ID_ALL_MASK,
412 "Adaptec 3944A Ultra SCSI adapter",
413 ahc_aic7895_setup
414 },
415 {
416 ID_AIC7895_ARO,
417 ID_AIC7895_ARO_MASK,
418 "Adaptec aic7895 Ultra SCSI adapter (ARO)",
419 ahc_aic7895_setup
420 },
421 /* aic7896/97 based controllers */
422 {
423 ID_AHA_3950U2B_0,
424 ID_ALL_MASK,
425 "Adaptec 3950B Ultra2 SCSI adapter",
426 ahc_aic7896_setup
427 },
428 {
429 ID_AHA_3950U2B_1,
430 ID_ALL_MASK,
431 "Adaptec 3950B Ultra2 SCSI adapter",
432 ahc_aic7896_setup
433 },
434 {
435 ID_AHA_3950U2D_0,
436 ID_ALL_MASK,
437 "Adaptec 3950D Ultra2 SCSI adapter",
438 ahc_aic7896_setup
439 },
440 {
441 ID_AHA_3950U2D_1,
442 ID_ALL_MASK,
443 "Adaptec 3950D Ultra2 SCSI adapter",
444 ahc_aic7896_setup
445 },
446 {
447 ID_AIC7896_ARO,
448 ID_ALL_MASK,
449 "Adaptec aic7896/97 Ultra2 SCSI adapter (ARO)",
450 ahc_aic7896_setup
451 },
452 /* aic7899 based controllers */
453 {
454 ID_AHA_3960D,
455 ID_ALL_MASK,
456 "Adaptec 3960D Ultra160 SCSI adapter",
457 ahc_aic7899_setup
458 },
459 {
460 ID_AHA_3960D_CPQ,
461 ID_ALL_MASK,
462 "Adaptec (Compaq OEM) 3960D Ultra160 SCSI adapter",
463 ahc_aic7899_setup
464 },
465 {
466 ID_AIC7899_ARO,
467 ID_ALL_MASK,
468 "Adaptec aic7899 Ultra160 SCSI adapter (ARO)",
469 ahc_aic7899_setup
470 },
471 /* Generic chip probes for devices we don't know 'exactly' */
472 {
473 ID_AIC7850 & ID_DEV_VENDOR_MASK,
474 ID_DEV_VENDOR_MASK,
475 "Adaptec aic7850 SCSI adapter",
476 ahc_aic785X_setup
477 },
478 {
479 ID_AIC7855 & ID_DEV_VENDOR_MASK,
480 ID_DEV_VENDOR_MASK,
481 "Adaptec aic7855 SCSI adapter",
482 ahc_aic785X_setup
483 },
484 {
485 ID_AIC7859 & ID_DEV_VENDOR_MASK,
486 ID_DEV_VENDOR_MASK,
487 "Adaptec aic7859 SCSI adapter",
488 ahc_aic7860_setup
489 },
490 {
491 ID_AIC7860 & ID_DEV_VENDOR_MASK,
492 ID_DEV_VENDOR_MASK,
493 "Adaptec aic7860 Ultra SCSI adapter",
494 ahc_aic7860_setup
495 },
496 {
497 ID_AIC7870 & ID_DEV_VENDOR_MASK,
498 ID_DEV_VENDOR_MASK,
499 "Adaptec aic7870 SCSI adapter",
500 ahc_aic7870_setup
501 },
502 {
503 ID_AIC7880 & ID_DEV_VENDOR_MASK,
504 ID_DEV_VENDOR_MASK,
505 "Adaptec aic7880 Ultra SCSI adapter",
506 ahc_aic7880_setup
507 },
508 {
509 ID_AIC7890 & ID_9005_GENERIC_MASK,
510 ID_9005_GENERIC_MASK,
511 "Adaptec aic7890/91 Ultra2 SCSI adapter",
512 ahc_aic7890_setup
513 },
514 {
515 ID_AIC7892 & ID_9005_GENERIC_MASK,
516 ID_9005_GENERIC_MASK,
517 "Adaptec aic7892 Ultra160 SCSI adapter",
518 ahc_aic7892_setup
519 },
520 {
521 ID_AIC7895 & ID_DEV_VENDOR_MASK,
522 ID_DEV_VENDOR_MASK,
523 "Adaptec aic7895 Ultra SCSI adapter",
524 ahc_aic7895_setup
525 },
526 {
527 ID_AIC7896 & ID_9005_GENERIC_MASK,
528 ID_9005_GENERIC_MASK,
529 "Adaptec aic7896/97 Ultra2 SCSI adapter",
530 ahc_aic7896_setup
531 },
532 {
533 ID_AIC7899 & ID_9005_GENERIC_MASK,
534 ID_9005_GENERIC_MASK,
535 "Adaptec aic7899 Ultra160 SCSI adapter",
536 ahc_aic7899_setup
537 },
538 {
539 ID_AIC7810 & ID_DEV_VENDOR_MASK,
540 ID_DEV_VENDOR_MASK,
541 "Adaptec aic7810 RAID memory controller",
542 ahc_raid_setup
543 },
544 {
545 ID_AIC7815 & ID_DEV_VENDOR_MASK,
546 ID_DEV_VENDOR_MASK,
547 "Adaptec aic7815 RAID memory controller",
548 ahc_raid_setup
549 }
550};
551
552const u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table);
553
554#define AHC_394X_SLOT_CHANNEL_A 4
555#define AHC_394X_SLOT_CHANNEL_B 5
556
557#define AHC_398X_SLOT_CHANNEL_A 4
558#define AHC_398X_SLOT_CHANNEL_B 8
559#define AHC_398X_SLOT_CHANNEL_C 12
560
561#define AHC_494X_SLOT_CHANNEL_A 4
562#define AHC_494X_SLOT_CHANNEL_B 5
563#define AHC_494X_SLOT_CHANNEL_C 6
564#define AHC_494X_SLOT_CHANNEL_D 7
565
566#define DEVCONFIG 0x40
567#define PCIERRGENDIS 0x80000000ul
568#define SCBSIZE32 0x00010000ul /* aic789X only */
569#define REXTVALID 0x00001000ul /* ultra cards only */
570#define MPORTMODE 0x00000400ul /* aic7870+ only */
571#define RAMPSM 0x00000200ul /* aic7870+ only */
572#define VOLSENSE 0x00000100ul
573#define PCI64BIT 0x00000080ul /* 64Bit PCI bus (Ultra2 Only)*/
574#define SCBRAMSEL 0x00000080ul
575#define MRDCEN 0x00000040ul
576#define EXTSCBTIME 0x00000020ul /* aic7870 only */
577#define EXTSCBPEN 0x00000010ul /* aic7870 only */
578#define BERREN 0x00000008ul
579#define DACEN 0x00000004ul
580#define STPWLEVEL 0x00000002ul
581#define DIFACTNEGEN 0x00000001ul /* aic7870 only */
582
583#define CSIZE_LATTIME 0x0c
584#define CACHESIZE 0x0000003ful /* only 5 bits */
585#define LATTIME 0x0000ff00ul
586
587/* PCI STATUS definitions */
588#define DPE 0x80
589#define SSE 0x40
590#define RMA 0x20
591#define RTA 0x10
592#define STA 0x08
593#define DPR 0x01
594
595static int ahc_9005_subdevinfo_valid(uint16_t vendor, uint16_t device,
596 uint16_t subvendor, uint16_t subdevice);
597static int ahc_ext_scbram_present(struct ahc_softc *ahc);
598static void ahc_scbram_config(struct ahc_softc *ahc, int enable,
599 int pcheck, int fast, int large);
600static void ahc_probe_ext_scbram(struct ahc_softc *ahc);
601static void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1);
602static void ahc_parse_pci_eeprom(struct ahc_softc *ahc,
603 struct seeprom_config *sc);
604static void configure_termination(struct ahc_softc *ahc,
605 struct seeprom_descriptor *sd,
606 u_int adapter_control,
607 u_int *sxfrctl1);
608
609static void ahc_new_term_detect(struct ahc_softc *ahc,
610 int *enableSEC_low,
611 int *enableSEC_high,
612 int *enablePRI_low,
613 int *enablePRI_high,
614 int *eeprom_present);
615static void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
616 int *internal68_present,
617 int *externalcable_present,
618 int *eeprom_present);
619static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
620 int *externalcable_present,
621 int *eeprom_present);
622static void write_brdctl(struct ahc_softc *ahc, uint8_t value);
623static uint8_t read_brdctl(struct ahc_softc *ahc);
624static void ahc_pci_intr(struct ahc_softc *ahc);
625static int ahc_pci_chip_init(struct ahc_softc *ahc);
626static int ahc_pci_suspend(struct ahc_softc *ahc);
627static int ahc_pci_resume(struct ahc_softc *ahc);
628
629static int
630ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor,
631 uint16_t subdevice, uint16_t subvendor)
632{
633 int result;
634
635 /* Default to invalid. */
636 result = 0;
637 if (vendor == 0x9005
638 && subvendor == 0x9005
639 && subdevice != device
640 && SUBID_9005_TYPE_KNOWN(subdevice) != 0) {
641
642 switch (SUBID_9005_TYPE(subdevice)) {
643 case SUBID_9005_TYPE_MB:
644 break;
645 case SUBID_9005_TYPE_CARD:
646 case SUBID_9005_TYPE_LCCARD:
647 /*
648 * Currently only trust Adaptec cards to
649 * get the sub device info correct.
650 */
651 if (DEVID_9005_TYPE(device) == DEVID_9005_TYPE_HBA)
652 result = 1;
653 break;
654 case SUBID_9005_TYPE_RAID:
655 break;
656 default:
657 break;
658 }
659 }
660 return (result);
661}
662
663struct ahc_pci_identity *
664ahc_find_pci_device(ahc_dev_softc_t pci)
665{
666 uint64_t full_id;
667 uint16_t device;
668 uint16_t vendor;
669 uint16_t subdevice;
670 uint16_t subvendor;
671 struct ahc_pci_identity *entry;
672 u_int i;
673
674 vendor = ahc_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
675 device = ahc_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
676 subvendor = ahc_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
677 subdevice = ahc_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
678 full_id = ahc_compose_id(device, vendor, subdevice, subvendor);
679
680 /*
681 * If the second function is not hooked up, ignore it.
682 * Unfortunately, not all MB vendors implement the
683 * subdevice ID as per the Adaptec spec, so do our best
684 * to sanity check it prior to accepting the subdevice
685 * ID as valid.
686 */
687 if (ahc_get_pci_function(pci) > 0
688 && ahc_9005_subdevinfo_valid(vendor, device, subvendor, subdevice)
689 && SUBID_9005_MFUNCENB(subdevice) == 0)
690 return (NULL);
691
692 for (i = 0; i < ahc_num_pci_devs; i++) {
693 entry = &ahc_pci_ident_table[i];
694 if (entry->full_id == (full_id & entry->id_mask)) {
695 /* Honor exclusion entries. */
696 if (entry->name == NULL)
697 return (NULL);
698 return (entry);
699 }
700 }
701 return (NULL);
702}
703
704int
705ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
706{
707 u_long l;
708 u_int command;
709 u_int our_id;
710 u_int sxfrctl1;
711 u_int scsiseq;
712 u_int dscommand0;
713 uint32_t devconfig;
714 int error;
715 uint8_t sblkctl;
716
717 our_id = 0;
718 error = entry->setup(ahc);
719 if (error != 0)
720 return (error);
721 ahc->chip |= AHC_PCI;
722 ahc->description = entry->name;
723
724 pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);
725
726 error = ahc_pci_map_registers(ahc);
727 if (error != 0)
728 return (error);
729
730 /*
731 * Before we continue probing the card, ensure that
732 * its interrupts are *disabled*. We don't want
733 * a misstep to hang the machine in an interrupt
734 * storm.
735 */
736 ahc_intr_enable(ahc, FALSE);
737
738 devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
739
740 /*
741 * If we need to support high memory, enable dual
742 * address cycles. This bit must be set to enable
743 * high address bit generation even if we are on a
744 * 64bit bus (PCI64BIT set in devconfig).
745 */
746 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
747
748 if (bootverbose)
749 printf("%s: Enabling 39Bit Addressing\n",
750 ahc_name(ahc));
751 devconfig |= DACEN;
752 }
753
754 /* Ensure that pci error generation, a test feature, is disabled. */
755 devconfig |= PCIERRGENDIS;
756
757 ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
758
759 /* Ensure busmastering is enabled */
760 command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
761 command |= PCIM_CMD_BUSMASTEREN;
762
763 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
764
765 /* On all PCI adapters, we allow SCB paging */
766 ahc->flags |= AHC_PAGESCBS;
767
768 error = ahc_softc_init(ahc);
769 if (error != 0)
770 return (error);
771
772 /*
773 * Disable PCI parity error checking. Users typically
774 * do this to work around broken PCI chipsets that get
775 * the parity timing wrong and thus generate lots of spurious
776 * errors. The chip only allows us to disable *all* parity
777 * error reporting when doing this, so CIO bus, scb ram, and
778 * scratch ram parity errors will be ignored too.
779 */
780 if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
781 ahc->seqctl |= FAILDIS;
782
783 ahc->bus_intr = ahc_pci_intr;
784 ahc->bus_chip_init = ahc_pci_chip_init;
785 ahc->bus_suspend = ahc_pci_suspend;
786 ahc->bus_resume = ahc_pci_resume;
787
788 /* Remeber how the card was setup in case there is no SEEPROM */
789 if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
790 ahc_pause(ahc);
791 if ((ahc->features & AHC_ULTRA2) != 0)
792 our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
793 else
794 our_id = ahc_inb(ahc, SCSIID) & OID;
795 sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN;
796 scsiseq = ahc_inb(ahc, SCSISEQ);
797 } else {
798 sxfrctl1 = STPWEN;
799 our_id = 7;
800 scsiseq = 0;
801 }
802
803 error = ahc_reset(ahc, /*reinit*/FALSE);
804 if (error != 0)
805 return (ENXIO);
806
807 if ((ahc->features & AHC_DT) != 0) {
808 u_int sfunct;
809
810 /* Perform ALT-Mode Setup */
811 sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
812 ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
813 ahc_outb(ahc, OPTIONMODE,
814 OPTIONMODE_DEFAULTS|AUTOACKEN|BUSFREEREV|EXPPHASEDIS);
815 ahc_outb(ahc, SFUNCT, sfunct);
816
817 /* Normal mode setup */
818 ahc_outb(ahc, CRCCONTROL1, CRCVALCHKEN|CRCENDCHKEN|CRCREQCHKEN
819 |TARGCRCENDEN);
820 }
821
822 dscommand0 = ahc_inb(ahc, DSCOMMAND0);
823 dscommand0 |= MPARCKEN|CACHETHEN;
824 if ((ahc->features & AHC_ULTRA2) != 0) {
825
826 /*
827 * DPARCKEN doesn't work correctly on
828 * some MBs so don't use it.
829 */
830 dscommand0 &= ~DPARCKEN;
831 }
832
833 /*
834 * Handle chips that must have cache line
835 * streaming (dis/en)abled.
836 */
837 if ((ahc->bugs & AHC_CACHETHEN_DIS_BUG) != 0)
838 dscommand0 |= CACHETHEN;
839
840 if ((ahc->bugs & AHC_CACHETHEN_BUG) != 0)
841 dscommand0 &= ~CACHETHEN;
842
843 ahc_outb(ahc, DSCOMMAND0, dscommand0);
844
845 ahc->pci_cachesize =
846 ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME,
847 /*bytes*/1) & CACHESIZE;
848 ahc->pci_cachesize *= 4;
849
850 if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0
851 && ahc->pci_cachesize == 4) {
852
853 ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
854 0, /*bytes*/1);
855 ahc->pci_cachesize = 0;
856 }
857
858 /*
859 * We cannot perform ULTRA speeds without the presense
860 * of the external precision resistor.
861 */
862 if ((ahc->features & AHC_ULTRA) != 0) {
863 uint32_t devconfig;
864
865 devconfig = ahc_pci_read_config(ahc->dev_softc,
866 DEVCONFIG, /*bytes*/4);
867 if ((devconfig & REXTVALID) == 0)
868 ahc->features &= ~AHC_ULTRA;
869 }
870
871 /* See if we have a SEEPROM and perform auto-term */
872 check_extport(ahc, &sxfrctl1);
873
874 /*
875 * Take the LED out of diagnostic mode
876 */
877 sblkctl = ahc_inb(ahc, SBLKCTL);
878 ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
879
880 if ((ahc->features & AHC_ULTRA2) != 0) {
881 ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_MAX|WR_DFTHRSH_MAX);
882 } else {
883 ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100);
884 }
885
886 if (ahc->flags & AHC_USEDEFAULTS) {
887 /*
888 * PCI Adapter default setup
889 * Should only be used if the adapter does not have
890 * a SEEPROM.
891 */
892 /* See if someone else set us up already */
893 if ((ahc->flags & AHC_NO_BIOS_INIT) == 0
894 && scsiseq != 0) {
895 printf("%s: Using left over BIOS settings\n",
896 ahc_name(ahc));
897 ahc->flags &= ~AHC_USEDEFAULTS;
898 ahc->flags |= AHC_BIOS_ENABLED;
899 } else {
900 /*
901 * Assume only one connector and always turn
902 * on termination.
903 */
904 our_id = 0x07;
905 sxfrctl1 = STPWEN;
906 }
907 ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI);
908
909 ahc->our_id = our_id;
910 }
911
912 /*
913 * Take a look to see if we have external SRAM.
914 * We currently do not attempt to use SRAM that is
915 * shared among multiple controllers.
916 */
917 ahc_probe_ext_scbram(ahc);
918
919 /*
920 * Record our termination setting for the
921 * generic initialization routine.
922 */
923 if ((sxfrctl1 & STPWEN) != 0)
924 ahc->flags |= AHC_TERM_ENB_A;
925
926 /*
927 * Save chip register configuration data for chip resets
928 * that occur during runtime and resume events.
929 */
930 ahc->bus_softc.pci_softc.devconfig =
931 ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
932 ahc->bus_softc.pci_softc.command =
933 ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
934 ahc->bus_softc.pci_softc.csize_lattime =
935 ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1);
936 ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
937 ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
938 if ((ahc->features & AHC_DT) != 0) {
939 u_int sfunct;
940
941 sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
942 ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
943 ahc->bus_softc.pci_softc.optionmode = ahc_inb(ahc, OPTIONMODE);
944 ahc->bus_softc.pci_softc.targcrccnt = ahc_inw(ahc, TARGCRCCNT);
945 ahc_outb(ahc, SFUNCT, sfunct);
946 ahc->bus_softc.pci_softc.crccontrol1 =
947 ahc_inb(ahc, CRCCONTROL1);
948 }
949 if ((ahc->features & AHC_MULTI_FUNC) != 0)
950 ahc->bus_softc.pci_softc.scbbaddr = ahc_inb(ahc, SCBBADDR);
951
952 if ((ahc->features & AHC_ULTRA2) != 0)
953 ahc->bus_softc.pci_softc.dff_thrsh = ahc_inb(ahc, DFF_THRSH);
954
955 /* Core initialization */
956 error = ahc_init(ahc);
957 if (error != 0)
958 return (error);
959
960 /*
961 * Allow interrupts now that we are completely setup.
962 */
963 error = ahc_pci_map_int(ahc);
964 if (error != 0)
965 return (error);
966
967 ahc_list_lock(&l);
968 /*
969 * Link this softc in with all other ahc instances.
970 */
971 ahc_softc_insert(ahc);
972 ahc_list_unlock(&l);
973 return (0);
974}
975
976/*
977 * Test for the presense of external sram in an
978 * "unshared" configuration.
979 */
980static int
981ahc_ext_scbram_present(struct ahc_softc *ahc)
982{
983 u_int chip;
984 int ramps;
985 int single_user;
986 uint32_t devconfig;
987
988 chip = ahc->chip & AHC_CHIPID_MASK;
989 devconfig = ahc_pci_read_config(ahc->dev_softc,
990 DEVCONFIG, /*bytes*/4);
991 single_user = (devconfig & MPORTMODE) != 0;
992
993 if ((ahc->features & AHC_ULTRA2) != 0)
994 ramps = (ahc_inb(ahc, DSCOMMAND0) & RAMPS) != 0;
995 else if (chip == AHC_AIC7895 || chip == AHC_AIC7895C)
996 /*
997 * External SCBRAM arbitration is flakey
998 * on these chips. Unfortunately this means
999 * we don't use the extra SCB ram space on the
1000 * 3940AUW.
1001 */
1002 ramps = 0;
1003 else if (chip >= AHC_AIC7870)
1004 ramps = (devconfig & RAMPSM) != 0;
1005 else
1006 ramps = 0;
1007
1008 if (ramps && single_user)
1009 return (1);
1010 return (0);
1011}
1012
1013/*
1014 * Enable external scbram.
1015 */
1016static void
1017ahc_scbram_config(struct ahc_softc *ahc, int enable, int pcheck,
1018 int fast, int large)
1019{
1020 uint32_t devconfig;
1021
1022 if (ahc->features & AHC_MULTI_FUNC) {
1023 /*
1024 * Set the SCB Base addr (highest address bit)
1025 * depending on which channel we are.
1026 */
1027 ahc_outb(ahc, SCBBADDR, ahc_get_pci_function(ahc->dev_softc));
1028 }
1029
1030 ahc->flags &= ~AHC_LSCBS_ENABLED;
1031 if (large)
1032 ahc->flags |= AHC_LSCBS_ENABLED;
1033 devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
1034 if ((ahc->features & AHC_ULTRA2) != 0) {
1035 u_int dscommand0;
1036
1037 dscommand0 = ahc_inb(ahc, DSCOMMAND0);
1038 if (enable)
1039 dscommand0 &= ~INTSCBRAMSEL;
1040 else
1041 dscommand0 |= INTSCBRAMSEL;
1042 if (large)
1043 dscommand0 &= ~USCBSIZE32;
1044 else
1045 dscommand0 |= USCBSIZE32;
1046 ahc_outb(ahc, DSCOMMAND0, dscommand0);
1047 } else {
1048 if (fast)
1049 devconfig &= ~EXTSCBTIME;
1050 else
1051 devconfig |= EXTSCBTIME;
1052 if (enable)
1053 devconfig &= ~SCBRAMSEL;
1054 else
1055 devconfig |= SCBRAMSEL;
1056 if (large)
1057 devconfig &= ~SCBSIZE32;
1058 else
1059 devconfig |= SCBSIZE32;
1060 }
1061 if (pcheck)
1062 devconfig |= EXTSCBPEN;
1063 else
1064 devconfig &= ~EXTSCBPEN;
1065
1066 ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
1067}
1068
1069/*
1070 * Take a look to see if we have external SRAM.
1071 * We currently do not attempt to use SRAM that is
1072 * shared among multiple controllers.
1073 */
1074static void
1075ahc_probe_ext_scbram(struct ahc_softc *ahc)
1076{
1077 int num_scbs;
1078 int test_num_scbs;
1079 int enable;
1080 int pcheck;
1081 int fast;
1082 int large;
1083
1084 enable = FALSE;
1085 pcheck = FALSE;
1086 fast = FALSE;
1087 large = FALSE;
1088 num_scbs = 0;
1089
1090 if (ahc_ext_scbram_present(ahc) == 0)
1091 goto done;
1092
1093 /*
1094 * Probe for the best parameters to use.
1095 */
1096 ahc_scbram_config(ahc, /*enable*/TRUE, pcheck, fast, large);
1097 num_scbs = ahc_probe_scbs(ahc);
1098 if (num_scbs == 0) {
1099 /* The SRAM wasn't really present. */
1100 goto done;
1101 }
1102 enable = TRUE;
1103
1104 /*
1105 * Clear any outstanding parity error
1106 * and ensure that parity error reporting
1107 * is enabled.
1108 */
1109 ahc_outb(ahc, SEQCTL, 0);
1110 ahc_outb(ahc, CLRINT, CLRPARERR);
1111 ahc_outb(ahc, CLRINT, CLRBRKADRINT);
1112
1113 /* Now see if we can do parity */
1114 ahc_scbram_config(ahc, enable, /*pcheck*/TRUE, fast, large);
1115 num_scbs = ahc_probe_scbs(ahc);
1116 if ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
1117 || (ahc_inb(ahc, ERROR) & MPARERR) == 0)
1118 pcheck = TRUE;
1119
1120 /* Clear any resulting parity error */
1121 ahc_outb(ahc, CLRINT, CLRPARERR);
1122 ahc_outb(ahc, CLRINT, CLRBRKADRINT);
1123
1124 /* Now see if we can do fast timing */
1125 ahc_scbram_config(ahc, enable, pcheck, /*fast*/TRUE, large);
1126 test_num_scbs = ahc_probe_scbs(ahc);
1127 if (test_num_scbs == num_scbs
1128 && ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0
1129 || (ahc_inb(ahc, ERROR) & MPARERR) == 0))
1130 fast = TRUE;
1131
1132 /*
1133 * See if we can use large SCBs and still maintain
1134 * the same overall count of SCBs.
1135 */
1136 if ((ahc->features & AHC_LARGE_SCBS) != 0) {
1137 ahc_scbram_config(ahc, enable, pcheck, fast, /*large*/TRUE);
1138 test_num_scbs = ahc_probe_scbs(ahc);
1139 if (test_num_scbs >= num_scbs) {
1140 large = TRUE;
1141 num_scbs = test_num_scbs;
1142 if (num_scbs >= 64) {
1143 /*
1144 * We have enough space to move the
1145 * "busy targets table" into SCB space
1146 * and make it qualify all the way to the
1147 * lun level.
1148 */
1149 ahc->flags |= AHC_SCB_BTT;
1150 }
1151 }
1152 }
1153done:
1154 /*
1155 * Disable parity error reporting until we
1156 * can load instruction ram.
1157 */
1158 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
1159 /* Clear any latched parity error */
1160 ahc_outb(ahc, CLRINT, CLRPARERR);
1161 ahc_outb(ahc, CLRINT, CLRBRKADRINT);
1162 if (bootverbose && enable) {
1163 printf("%s: External SRAM, %s access%s, %dbytes/SCB\n",
1164 ahc_name(ahc), fast ? "fast" : "slow",
1165 pcheck ? ", parity checking enabled" : "",
1166 large ? 64 : 32);
1167 }
1168 ahc_scbram_config(ahc, enable, pcheck, fast, large);
1169}
1170
1171/*
1172 * Perform some simple tests that should catch situations where
1173 * our registers are invalidly mapped.
1174 */
1175int
1176ahc_pci_test_register_access(struct ahc_softc *ahc)
1177{
1178 int error;
1179 u_int status1;
1180 uint32_t cmd;
1181 uint8_t hcntrl;
1182
1183 error = EIO;
1184
1185 /*
1186 * Enable PCI error interrupt status, but suppress NMIs
1187 * generated by SERR raised due to target aborts.
1188 */
1189 cmd = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
1190 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
1191 cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
1192
1193 /*
1194 * First a simple test to see if any
1195 * registers can be read. Reading
1196 * HCNTRL has no side effects and has
1197 * at least one bit that is guaranteed to
1198 * be zero so it is a good register to
1199 * use for this test.
1200 */
1201 hcntrl = ahc_inb(ahc, HCNTRL);
1202 if (hcntrl == 0xFF)
1203 goto fail;
1204
1205 /*
1206 * Next create a situation where write combining
1207 * or read prefetching could be initiated by the
1208 * CPU or host bridge. Our device does not support
1209 * either, so look for data corruption and/or flagged
1210 * PCI errors. First pause without causing another
1211 * chip reset.
1212 */
1213 hcntrl &= ~CHIPRST;
1214 ahc_outb(ahc, HCNTRL, hcntrl|PAUSE);
1215 while (ahc_is_paused(ahc) == 0)
1216 ;
1217
1218 /* Clear any PCI errors that occurred before our driver attached. */
1219 status1 = ahc_pci_read_config(ahc->dev_softc,
1220 PCIR_STATUS + 1, /*bytes*/1);
1221 ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
1222 status1, /*bytes*/1);
1223 ahc_outb(ahc, CLRINT, CLRPARERR);
1224
1225 ahc_outb(ahc, SEQCTL, PERRORDIS);
1226 ahc_outb(ahc, SCBPTR, 0);
1227 ahc_outl(ahc, SCB_BASE, 0x5aa555aa);
1228 if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa)
1229 goto fail;
1230
1231 status1 = ahc_pci_read_config(ahc->dev_softc,
1232 PCIR_STATUS + 1, /*bytes*/1);
1233 if ((status1 & STA) != 0)
1234 goto fail;
1235
1236 error = 0;
1237
1238fail:
1239 /* Silently clear any latched errors. */
1240 status1 = ahc_pci_read_config(ahc->dev_softc,
1241 PCIR_STATUS + 1, /*bytes*/1);
1242 ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
1243 status1, /*bytes*/1);
1244 ahc_outb(ahc, CLRINT, CLRPARERR);
1245 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
1246 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
1247 return (error);
1248}
1249
1250/*
1251 * Check the external port logic for a serial eeprom
1252 * and termination/cable detection contrls.
1253 */
1254static void
1255check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
1256{
1257 struct seeprom_descriptor sd;
1258 struct seeprom_config *sc;
1259 int have_seeprom;
1260 int have_autoterm;
1261
1262 sd.sd_ahc = ahc;
1263 sd.sd_control_offset = SEECTL;
1264 sd.sd_status_offset = SEECTL;
1265 sd.sd_dataout_offset = SEECTL;
1266 sc = ahc->seep_config;
1267
1268 /*
1269 * For some multi-channel devices, the c46 is simply too
1270 * small to work. For the other controller types, we can
1271 * get our information from either SEEPROM type. Set the
1272 * type to start our probe with accordingly.
1273 */
1274 if (ahc->flags & AHC_LARGE_SEEPROM)
1275 sd.sd_chip = C56_66;
1276 else
1277 sd.sd_chip = C46;
1278
1279 sd.sd_MS = SEEMS;
1280 sd.sd_RDY = SEERDY;
1281 sd.sd_CS = SEECS;
1282 sd.sd_CK = SEECK;
1283 sd.sd_DO = SEEDO;
1284 sd.sd_DI = SEEDI;
1285
1286 have_seeprom = ahc_acquire_seeprom(ahc, &sd);
1287 if (have_seeprom) {
1288
1289 if (bootverbose)
1290 printf("%s: Reading SEEPROM...", ahc_name(ahc));
1291
1292 for (;;) {
1293 u_int start_addr;
1294
1295 start_addr = 32 * (ahc->channel - 'A');
1296
1297 have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc,
1298 start_addr,
1299 sizeof(*sc)/2);
1300
1301 if (have_seeprom)
1302 have_seeprom = ahc_verify_cksum(sc);
1303
1304 if (have_seeprom != 0 || sd.sd_chip == C56_66) {
1305 if (bootverbose) {
1306 if (have_seeprom == 0)
1307 printf ("checksum error\n");
1308 else
1309 printf ("done.\n");
1310 }
1311 break;
1312 }
1313 sd.sd_chip = C56_66;
1314 }
1315 ahc_release_seeprom(&sd);
1316 }
1317
1318 if (!have_seeprom) {
1319 /*
1320 * Pull scratch ram settings and treat them as
1321 * if they are the contents of an seeprom if
1322 * the 'ADPT' signature is found in SCB2.
1323 * We manually compose the data as 16bit values
1324 * to avoid endian issues.
1325 */
1326 ahc_outb(ahc, SCBPTR, 2);
1327 if (ahc_inb(ahc, SCB_BASE) == 'A'
1328 && ahc_inb(ahc, SCB_BASE + 1) == 'D'
1329 && ahc_inb(ahc, SCB_BASE + 2) == 'P'
1330 && ahc_inb(ahc, SCB_BASE + 3) == 'T') {
1331 uint16_t *sc_data;
1332 int i;
1333
1334 sc_data = (uint16_t *)sc;
1335 for (i = 0; i < 32; i++, sc_data++) {
1336 int j;
1337
1338 j = i * 2;
1339 *sc_data = ahc_inb(ahc, SRAM_BASE + j)
1340 | ahc_inb(ahc, SRAM_BASE + j + 1) << 8;
1341 }
1342 have_seeprom = ahc_verify_cksum(sc);
1343 if (have_seeprom)
1344 ahc->flags |= AHC_SCB_CONFIG_USED;
1345 }
1346 /*
1347 * Clear any SCB parity errors in case this data and
1348 * its associated parity was not initialized by the BIOS
1349 */
1350 ahc_outb(ahc, CLRINT, CLRPARERR);
1351 ahc_outb(ahc, CLRINT, CLRBRKADRINT);
1352 }
1353
1354 if (!have_seeprom) {
1355 if (bootverbose)
1356 printf("%s: No SEEPROM available.\n", ahc_name(ahc));
1357 ahc->flags |= AHC_USEDEFAULTS;
1358 free(ahc->seep_config, M_DEVBUF);
1359 ahc->seep_config = NULL;
1360 sc = NULL;
1361 } else {
1362 ahc_parse_pci_eeprom(ahc, sc);
1363 }
1364
1365 /*
1366 * Cards that have the external logic necessary to talk to
1367 * a SEEPROM, are almost certain to have the remaining logic
1368 * necessary for auto-termination control. This assumption
1369 * hasn't failed yet...
1370 */
1371 have_autoterm = have_seeprom;
1372
1373 /*
1374 * Some low-cost chips have SEEPROM and auto-term control built
1375 * in, instead of using a GAL. They can tell us directly
1376 * if the termination logic is enabled.
1377 */
1378 if ((ahc->features & AHC_SPIOCAP) != 0) {
1379 if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) == 0)
1380 have_autoterm = FALSE;
1381 }
1382
1383 if (have_autoterm) {
1384 ahc->flags |= AHC_HAS_TERM_LOGIC;
1385 ahc_acquire_seeprom(ahc, &sd);
1386 configure_termination(ahc, &sd, sc->adapter_control, sxfrctl1);
1387 ahc_release_seeprom(&sd);
1388 } else if (have_seeprom) {
1389 *sxfrctl1 &= ~STPWEN;
1390 if ((sc->adapter_control & CFSTERM) != 0)
1391 *sxfrctl1 |= STPWEN;
1392 if (bootverbose)
1393 printf("%s: Low byte termination %sabled\n",
1394 ahc_name(ahc),
1395 (*sxfrctl1 & STPWEN) ? "en" : "dis");
1396 }
1397}
1398
1399static void
1400ahc_parse_pci_eeprom(struct ahc_softc *ahc, struct seeprom_config *sc)
1401{
1402 /*
1403 * Put the data we've collected down into SRAM
1404 * where ahc_init will find it.
1405 */
1406 int i;
1407 int max_targ = sc->max_targets & CFMAXTARG;
1408 u_int scsi_conf;
1409 uint16_t discenable;
1410 uint16_t ultraenb;
1411
1412 discenable = 0;
1413 ultraenb = 0;
1414 if ((sc->adapter_control & CFULTRAEN) != 0) {
1415 /*
1416 * Determine if this adapter has a "newstyle"
1417 * SEEPROM format.
1418 */
1419 for (i = 0; i < max_targ; i++) {
1420 if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0) {
1421 ahc->flags |= AHC_NEWEEPROM_FMT;
1422 break;
1423 }
1424 }
1425 }
1426
1427 for (i = 0; i < max_targ; i++) {
1428 u_int scsirate;
1429 uint16_t target_mask;
1430
1431 target_mask = 0x01 << i;
1432 if (sc->device_flags[i] & CFDISC)
1433 discenable |= target_mask;
1434 if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) {
1435 if ((sc->device_flags[i] & CFSYNCHISULTRA) != 0)
1436 ultraenb |= target_mask;
1437 } else if ((sc->adapter_control & CFULTRAEN) != 0) {
1438 ultraenb |= target_mask;
1439 }
1440 if ((sc->device_flags[i] & CFXFER) == 0x04
1441 && (ultraenb & target_mask) != 0) {
1442 /* Treat 10MHz as a non-ultra speed */
1443 sc->device_flags[i] &= ~CFXFER;
1444 ultraenb &= ~target_mask;
1445 }
1446 if ((ahc->features & AHC_ULTRA2) != 0) {
1447 u_int offset;
1448
1449 if (sc->device_flags[i] & CFSYNCH)
1450 offset = MAX_OFFSET_ULTRA2;
1451 else
1452 offset = 0;
1453 ahc_outb(ahc, TARG_OFFSET + i, offset);
1454
1455 /*
1456 * The ultra enable bits contain the
1457 * high bit of the ultra2 sync rate
1458 * field.
1459 */
1460 scsirate = (sc->device_flags[i] & CFXFER)
1461 | ((ultraenb & target_mask) ? 0x8 : 0x0);
1462 if (sc->device_flags[i] & CFWIDEB)
1463 scsirate |= WIDEXFER;
1464 } else {
1465 scsirate = (sc->device_flags[i] & CFXFER) << 4;
1466 if (sc->device_flags[i] & CFSYNCH)
1467 scsirate |= SOFS;
1468 if (sc->device_flags[i] & CFWIDEB)
1469 scsirate |= WIDEXFER;
1470 }
1471 ahc_outb(ahc, TARG_SCSIRATE + i, scsirate);
1472 }
1473 ahc->our_id = sc->brtime_id & CFSCSIID;
1474
1475 scsi_conf = (ahc->our_id & 0x7);
1476 if (sc->adapter_control & CFSPARITY)
1477 scsi_conf |= ENSPCHK;
1478 if (sc->adapter_control & CFRESETB)
1479 scsi_conf |= RESET_SCSI;
1480
1481 ahc->flags |= (sc->adapter_control & CFBOOTCHAN) >> CFBOOTCHANSHIFT;
1482
1483 if (sc->bios_control & CFEXTEND)
1484 ahc->flags |= AHC_EXTENDED_TRANS_A;
1485
1486 if (sc->bios_control & CFBIOSEN)
1487 ahc->flags |= AHC_BIOS_ENABLED;
1488 if (ahc->features & AHC_ULTRA
1489 && (ahc->flags & AHC_NEWEEPROM_FMT) == 0) {
1490 /* Should we enable Ultra mode? */
1491 if (!(sc->adapter_control & CFULTRAEN))
1492 /* Treat us as a non-ultra card */
1493 ultraenb = 0;
1494 }
1495
1496 if (sc->signature == CFSIGNATURE
1497 || sc->signature == CFSIGNATURE2) {
1498 uint32_t devconfig;
1499
1500 /* Honor the STPWLEVEL settings */
1501 devconfig = ahc_pci_read_config(ahc->dev_softc,
1502 DEVCONFIG, /*bytes*/4);
1503 devconfig &= ~STPWLEVEL;
1504 if ((sc->bios_control & CFSTPWLEVEL) != 0)
1505 devconfig |= STPWLEVEL;
1506 ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
1507 devconfig, /*bytes*/4);
1508 }
1509 /* Set SCSICONF info */
1510 ahc_outb(ahc, SCSICONF, scsi_conf);
1511 ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
1512 ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
1513 ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff);
1514 ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff);
1515}
1516
1517static void
1518configure_termination(struct ahc_softc *ahc,
1519 struct seeprom_descriptor *sd,
1520 u_int adapter_control,
1521 u_int *sxfrctl1)
1522{
1523 uint8_t brddat;
1524
1525 brddat = 0;
1526
1527 /*
1528 * Update the settings in sxfrctl1 to match the
1529 * termination settings
1530 */
1531 *sxfrctl1 = 0;
1532
1533 /*
1534 * SEECS must be on for the GALS to latch
1535 * the data properly. Be sure to leave MS
1536 * on or we will release the seeprom.
1537 */
1538 SEEPROM_OUTB(sd, sd->sd_MS | sd->sd_CS);
1539 if ((adapter_control & CFAUTOTERM) != 0
1540 || (ahc->features & AHC_NEW_TERMCTL) != 0) {
1541 int internal50_present;
1542 int internal68_present;
1543 int externalcable_present;
1544 int eeprom_present;
1545 int enableSEC_low;
1546 int enableSEC_high;
1547 int enablePRI_low;
1548 int enablePRI_high;
1549 int sum;
1550
1551 enableSEC_low = 0;
1552 enableSEC_high = 0;
1553 enablePRI_low = 0;
1554 enablePRI_high = 0;
1555 if ((ahc->features & AHC_NEW_TERMCTL) != 0) {
1556 ahc_new_term_detect(ahc, &enableSEC_low,
1557 &enableSEC_high,
1558 &enablePRI_low,
1559 &enablePRI_high,
1560 &eeprom_present);
1561 if ((adapter_control & CFSEAUTOTERM) == 0) {
1562 if (bootverbose)
1563 printf("%s: Manual SE Termination\n",
1564 ahc_name(ahc));
1565 enableSEC_low = (adapter_control & CFSELOWTERM);
1566 enableSEC_high =
1567 (adapter_control & CFSEHIGHTERM);
1568 }
1569 if ((adapter_control & CFAUTOTERM) == 0) {
1570 if (bootverbose)
1571 printf("%s: Manual LVD Termination\n",
1572 ahc_name(ahc));
1573 enablePRI_low = (adapter_control & CFSTERM);
1574 enablePRI_high = (adapter_control & CFWSTERM);
1575 }
1576 /* Make the table calculations below happy */
1577 internal50_present = 0;
1578 internal68_present = 1;
1579 externalcable_present = 1;
1580 } else if ((ahc->features & AHC_SPIOCAP) != 0) {
1581 aic785X_cable_detect(ahc, &internal50_present,
1582 &externalcable_present,
1583 &eeprom_present);
1584 /* Can never support a wide connector. */
1585 internal68_present = 0;
1586 } else {
1587 aic787X_cable_detect(ahc, &internal50_present,
1588 &internal68_present,
1589 &externalcable_present,
1590 &eeprom_present);
1591 }
1592
1593 if ((ahc->features & AHC_WIDE) == 0)
1594 internal68_present = 0;
1595
1596 if (bootverbose
1597 && (ahc->features & AHC_ULTRA2) == 0) {
1598 printf("%s: internal 50 cable %s present",
1599 ahc_name(ahc),
1600 internal50_present ? "is":"not");
1601
1602 if ((ahc->features & AHC_WIDE) != 0)
1603 printf(", internal 68 cable %s present",
1604 internal68_present ? "is":"not");
1605 printf("\n%s: external cable %s present\n",
1606 ahc_name(ahc),
1607 externalcable_present ? "is":"not");
1608 }
1609 if (bootverbose)
1610 printf("%s: BIOS eeprom %s present\n",
1611 ahc_name(ahc), eeprom_present ? "is" : "not");
1612
1613 if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) {
1614 /*
1615 * The 50 pin connector is a separate bus,
1616 * so force it to always be terminated.
1617 * In the future, perform current sensing
1618 * to determine if we are in the middle of
1619 * a properly terminated bus.
1620 */
1621 internal50_present = 0;
1622 }
1623
1624 /*
1625 * Now set the termination based on what
1626 * we found.
1627 * Flash Enable = BRDDAT7
1628 * Secondary High Term Enable = BRDDAT6
1629 * Secondary Low Term Enable = BRDDAT5 (7890)
1630 * Primary High Term Enable = BRDDAT4 (7890)
1631 */
1632 if ((ahc->features & AHC_ULTRA2) == 0
1633 && (internal50_present != 0)
1634 && (internal68_present != 0)
1635 && (externalcable_present != 0)) {
1636 printf("%s: Illegal cable configuration!!. "
1637 "Only two connectors on the "
1638 "adapter may be used at a "
1639 "time!\n", ahc_name(ahc));
1640
1641 /*
1642 * Pretend there are no cables in the hope
1643 * that having all of the termination on
1644 * gives us a more stable bus.
1645 */
1646 internal50_present = 0;
1647 internal68_present = 0;
1648 externalcable_present = 0;
1649 }
1650
1651 if ((ahc->features & AHC_WIDE) != 0
1652 && ((externalcable_present == 0)
1653 || (internal68_present == 0)
1654 || (enableSEC_high != 0))) {
1655 brddat |= BRDDAT6;
1656 if (bootverbose) {
1657 if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)
1658 printf("%s: 68 pin termination "
1659 "Enabled\n", ahc_name(ahc));
1660 else
1661 printf("%s: %sHigh byte termination "
1662 "Enabled\n", ahc_name(ahc),
1663 enableSEC_high ? "Secondary "
1664 : "");
1665 }
1666 }
1667
1668 sum = internal50_present + internal68_present
1669 + externalcable_present;
1670 if (sum < 2 || (enableSEC_low != 0)) {
1671 if ((ahc->features & AHC_ULTRA2) != 0)
1672 brddat |= BRDDAT5;
1673 else
1674 *sxfrctl1 |= STPWEN;
1675 if (bootverbose) {
1676 if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)
1677 printf("%s: 50 pin termination "
1678 "Enabled\n", ahc_name(ahc));
1679 else
1680 printf("%s: %sLow byte termination "
1681 "Enabled\n", ahc_name(ahc),
1682 enableSEC_low ? "Secondary "
1683 : "");
1684 }
1685 }
1686
1687 if (enablePRI_low != 0) {
1688 *sxfrctl1 |= STPWEN;
1689 if (bootverbose)
1690 printf("%s: Primary Low Byte termination "
1691 "Enabled\n", ahc_name(ahc));
1692 }
1693
1694 /*
1695 * Setup STPWEN before setting up the rest of
1696 * the termination per the tech note on the U160 cards.
1697 */
1698 ahc_outb(ahc, SXFRCTL1, *sxfrctl1);
1699
1700 if (enablePRI_high != 0) {
1701 brddat |= BRDDAT4;
1702 if (bootverbose)
1703 printf("%s: Primary High Byte "
1704 "termination Enabled\n",
1705 ahc_name(ahc));
1706 }
1707
1708 write_brdctl(ahc, brddat);
1709
1710 } else {
1711 if ((adapter_control & CFSTERM) != 0) {
1712 *sxfrctl1 |= STPWEN;
1713
1714 if (bootverbose)
1715 printf("%s: %sLow byte termination Enabled\n",
1716 ahc_name(ahc),
1717 (ahc->features & AHC_ULTRA2) ? "Primary "
1718 : "");
1719 }
1720
1721 if ((adapter_control & CFWSTERM) != 0
1722 && (ahc->features & AHC_WIDE) != 0) {
1723 brddat |= BRDDAT6;
1724 if (bootverbose)
1725 printf("%s: %sHigh byte termination Enabled\n",
1726 ahc_name(ahc),
1727 (ahc->features & AHC_ULTRA2)
1728 ? "Secondary " : "");
1729 }
1730
1731 /*
1732 * Setup STPWEN before setting up the rest of
1733 * the termination per the tech note on the U160 cards.
1734 */
1735 ahc_outb(ahc, SXFRCTL1, *sxfrctl1);
1736
1737 if ((ahc->features & AHC_WIDE) != 0)
1738 write_brdctl(ahc, brddat);
1739 }
1740 SEEPROM_OUTB(sd, sd->sd_MS); /* Clear CS */
1741}
1742
1743static void
1744ahc_new_term_detect(struct ahc_softc *ahc, int *enableSEC_low,
1745 int *enableSEC_high, int *enablePRI_low,
1746 int *enablePRI_high, int *eeprom_present)
1747{
1748 uint8_t brdctl;
1749
1750 /*
1751 * BRDDAT7 = Eeprom
1752 * BRDDAT6 = Enable Secondary High Byte termination
1753 * BRDDAT5 = Enable Secondary Low Byte termination
1754 * BRDDAT4 = Enable Primary high byte termination
1755 * BRDDAT3 = Enable Primary low byte termination
1756 */
1757 brdctl = read_brdctl(ahc);
1758 *eeprom_present = brdctl & BRDDAT7;
1759 *enableSEC_high = (brdctl & BRDDAT6);
1760 *enableSEC_low = (brdctl & BRDDAT5);
1761 *enablePRI_high = (brdctl & BRDDAT4);
1762 *enablePRI_low = (brdctl & BRDDAT3);
1763}
1764
1765static void
1766aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
1767 int *internal68_present, int *externalcable_present,
1768 int *eeprom_present)
1769{
1770 uint8_t brdctl;
1771
1772 /*
1773 * First read the status of our cables.
1774 * Set the rom bank to 0 since the
1775 * bank setting serves as a multiplexor
1776 * for the cable detection logic.
1777 * BRDDAT5 controls the bank switch.
1778 */
1779 write_brdctl(ahc, 0);
1780
1781 /*
1782 * Now read the state of the internal
1783 * connectors. BRDDAT6 is INT50 and
1784 * BRDDAT7 is INT68.
1785 */
1786 brdctl = read_brdctl(ahc);
1787 *internal50_present = (brdctl & BRDDAT6) ? 0 : 1;
1788 *internal68_present = (brdctl & BRDDAT7) ? 0 : 1;
1789
1790 /*
1791 * Set the rom bank to 1 and determine
1792 * the other signals.
1793 */
1794 write_brdctl(ahc, BRDDAT5);
1795
1796 /*
1797 * Now read the state of the external
1798 * connectors. BRDDAT6 is EXT68 and
1799 * BRDDAT7 is EPROMPS.
1800 */
1801 brdctl = read_brdctl(ahc);
1802 *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;
1803 *eeprom_present = (brdctl & BRDDAT7) ? 1 : 0;
1804}
1805
1806static void
1807aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,
1808 int *externalcable_present, int *eeprom_present)
1809{
1810 uint8_t brdctl;
1811 uint8_t spiocap;
1812
1813 spiocap = ahc_inb(ahc, SPIOCAP);
1814 spiocap &= ~SOFTCMDEN;
1815 spiocap |= EXT_BRDCTL;
1816 ahc_outb(ahc, SPIOCAP, spiocap);
1817 ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);
1818 ahc_flush_device_writes(ahc);
1819 ahc_delay(500);
1820 ahc_outb(ahc, BRDCTL, 0);
1821 ahc_flush_device_writes(ahc);
1822 ahc_delay(500);
1823 brdctl = ahc_inb(ahc, BRDCTL);
1824 *internal50_present = (brdctl & BRDDAT5) ? 0 : 1;
1825 *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;
1826 *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0;
1827}
1828
1829int
1830ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd)
1831{
1832 int wait;
1833
1834 if ((ahc->features & AHC_SPIOCAP) != 0
1835 && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0)
1836 return (0);
1837
1838 /*
1839 * Request access of the memory port. When access is
1840 * granted, SEERDY will go high. We use a 1 second
1841 * timeout which should be near 1 second more than
1842 * is needed. Reason: after the chip reset, there
1843 * should be no contention.
1844 */
1845 SEEPROM_OUTB(sd, sd->sd_MS);
1846 wait = 1000; /* 1 second timeout in msec */
1847 while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) {
1848 ahc_delay(1000); /* delay 1 msec */
1849 }
1850 if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) {
1851 SEEPROM_OUTB(sd, 0);
1852 return (0);
1853 }
1854 return(1);
1855}
1856
1857void
1858ahc_release_seeprom(struct seeprom_descriptor *sd)
1859{
1860 /* Release access to the memory port and the serial EEPROM. */
1861 SEEPROM_OUTB(sd, 0);
1862}
1863
1864static void
1865write_brdctl(struct ahc_softc *ahc, uint8_t value)
1866{
1867 uint8_t brdctl;
1868
1869 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
1870 brdctl = BRDSTB;
1871 if (ahc->channel == 'B')
1872 brdctl |= BRDCS;
1873 } else if ((ahc->features & AHC_ULTRA2) != 0) {
1874 brdctl = 0;
1875 } else {
1876 brdctl = BRDSTB|BRDCS;
1877 }
1878 ahc_outb(ahc, BRDCTL, brdctl);
1879 ahc_flush_device_writes(ahc);
1880 brdctl |= value;
1881 ahc_outb(ahc, BRDCTL, brdctl);
1882 ahc_flush_device_writes(ahc);
1883 if ((ahc->features & AHC_ULTRA2) != 0)
1884 brdctl |= BRDSTB_ULTRA2;
1885 else
1886 brdctl &= ~BRDSTB;
1887 ahc_outb(ahc, BRDCTL, brdctl);
1888 ahc_flush_device_writes(ahc);
1889 if ((ahc->features & AHC_ULTRA2) != 0)
1890 brdctl = 0;
1891 else
1892 brdctl &= ~BRDCS;
1893 ahc_outb(ahc, BRDCTL, brdctl);
1894}
1895
1896static uint8_t
1897read_brdctl(struct ahc_softc *ahc)
1898{
1899 uint8_t brdctl;
1900 uint8_t value;
1901
1902 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
1903 brdctl = BRDRW;
1904 if (ahc->channel == 'B')
1905 brdctl |= BRDCS;
1906 } else if ((ahc->features & AHC_ULTRA2) != 0) {
1907 brdctl = BRDRW_ULTRA2;
1908 } else {
1909 brdctl = BRDRW|BRDCS;
1910 }
1911 ahc_outb(ahc, BRDCTL, brdctl);
1912 ahc_flush_device_writes(ahc);
1913 value = ahc_inb(ahc, BRDCTL);
1914 ahc_outb(ahc, BRDCTL, 0);
1915 return (value);
1916}
1917
1918static void
1919ahc_pci_intr(struct ahc_softc *ahc)
1920{
1921 u_int error;
1922 u_int status1;
1923
1924 error = ahc_inb(ahc, ERROR);
1925 if ((error & PCIERRSTAT) == 0)
1926 return;
1927
1928 status1 = ahc_pci_read_config(ahc->dev_softc,
1929 PCIR_STATUS + 1, /*bytes*/1);
1930
1931 printf("%s: PCI error Interrupt at seqaddr = 0x%x\n",
1932 ahc_name(ahc),
1933 ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
1934
1935 if (status1 & DPE) {
1936 ahc->pci_target_perr_count++;
1937 printf("%s: Data Parity Error Detected during address "
1938 "or write data phase\n", ahc_name(ahc));
1939 }
1940 if (status1 & SSE) {
1941 printf("%s: Signal System Error Detected\n", ahc_name(ahc));
1942 }
1943 if (status1 & RMA) {
1944 printf("%s: Received a Master Abort\n", ahc_name(ahc));
1945 }
1946 if (status1 & RTA) {
1947 printf("%s: Received a Target Abort\n", ahc_name(ahc));
1948 }
1949 if (status1 & STA) {
1950 printf("%s: Signaled a Target Abort\n", ahc_name(ahc));
1951 }
1952 if (status1 & DPR) {
1953 printf("%s: Data Parity Error has been reported via PERR#\n",
1954 ahc_name(ahc));
1955 }
1956
1957 /* Clear latched errors. */
1958 ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
1959 status1, /*bytes*/1);
1960
1961 if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {
1962 printf("%s: Latched PCIERR interrupt with "
1963 "no status bits set\n", ahc_name(ahc));
1964 } else {
1965 ahc_outb(ahc, CLRINT, CLRPARERR);
1966 }
1967
1968 if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) {
1969 printf(
1970"%s: WARNING WARNING WARNING WARNING\n"
1971"%s: Too many PCI parity errors observed as a target.\n"
1972"%s: Some device on this bus is generating bad parity.\n"
1973"%s: This is an error *observed by*, not *generated by*, this controller.\n"
1974"%s: PCI parity error checking has been disabled.\n"
1975"%s: WARNING WARNING WARNING WARNING\n",
1976 ahc_name(ahc), ahc_name(ahc), ahc_name(ahc),
1977 ahc_name(ahc), ahc_name(ahc), ahc_name(ahc));
1978 ahc->seqctl |= FAILDIS;
1979 ahc_outb(ahc, SEQCTL, ahc->seqctl);
1980 }
1981 ahc_unpause(ahc);
1982}
1983
1984static int
1985ahc_pci_chip_init(struct ahc_softc *ahc)
1986{
1987 ahc_outb(ahc, DSCOMMAND0, ahc->bus_softc.pci_softc.dscommand0);
1988 ahc_outb(ahc, DSPCISTATUS, ahc->bus_softc.pci_softc.dspcistatus);
1989 if ((ahc->features & AHC_DT) != 0) {
1990 u_int sfunct;
1991
1992 sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
1993 ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
1994 ahc_outb(ahc, OPTIONMODE, ahc->bus_softc.pci_softc.optionmode);
1995 ahc_outw(ahc, TARGCRCCNT, ahc->bus_softc.pci_softc.targcrccnt);
1996 ahc_outb(ahc, SFUNCT, sfunct);
1997 ahc_outb(ahc, CRCCONTROL1,
1998 ahc->bus_softc.pci_softc.crccontrol1);
1999 }
2000 if ((ahc->features & AHC_MULTI_FUNC) != 0)
2001 ahc_outb(ahc, SCBBADDR, ahc->bus_softc.pci_softc.scbbaddr);
2002
2003 if ((ahc->features & AHC_ULTRA2) != 0)
2004 ahc_outb(ahc, DFF_THRSH, ahc->bus_softc.pci_softc.dff_thrsh);
2005
2006 return (ahc_chip_init(ahc));
2007}
2008
2009static int
2010ahc_pci_suspend(struct ahc_softc *ahc)
2011{
2012 return (ahc_suspend(ahc));
2013}
2014
2015static int
2016ahc_pci_resume(struct ahc_softc *ahc)
2017{
2018
2019 pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);
2020
2021 /*
2022 * We assume that the OS has restored our register
2023 * mappings, etc. Just update the config space registers
2024 * that the OS doesn't know about and rely on our chip
2025 * reset handler to handle the rest.
2026 */
2027 ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4,
2028 ahc->bus_softc.pci_softc.devconfig);
2029 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1,
2030 ahc->bus_softc.pci_softc.command);
2031 ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1,
2032 ahc->bus_softc.pci_softc.csize_lattime);
2033 if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) {
2034 struct seeprom_descriptor sd;
2035 u_int sxfrctl1;
2036
2037 sd.sd_ahc = ahc;
2038 sd.sd_control_offset = SEECTL;
2039 sd.sd_status_offset = SEECTL;
2040 sd.sd_dataout_offset = SEECTL;
2041
2042 ahc_acquire_seeprom(ahc, &sd);
2043 configure_termination(ahc, &sd,
2044 ahc->seep_config->adapter_control,
2045 &sxfrctl1);
2046 ahc_release_seeprom(&sd);
2047 }
2048 return (ahc_resume(ahc));
2049}
2050
2051static int
2052ahc_aic785X_setup(struct ahc_softc *ahc)
2053{
2054 ahc_dev_softc_t pci;
2055 uint8_t rev;
2056
2057 pci = ahc->dev_softc;
2058 ahc->channel = 'A';
2059 ahc->chip = AHC_AIC7850;
2060 ahc->features = AHC_AIC7850_FE;
2061 ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
2062 rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
2063 if (rev >= 1)
2064 ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
2065 ahc->instruction_ram_size = 512;
2066 return (0);
2067}
2068
2069static int
2070ahc_aic7860_setup(struct ahc_softc *ahc)
2071{
2072 ahc_dev_softc_t pci;
2073 uint8_t rev;
2074
2075 pci = ahc->dev_softc;
2076 ahc->channel = 'A';
2077 ahc->chip = AHC_AIC7860;
2078 ahc->features = AHC_AIC7860_FE;
2079 ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
2080 rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
2081 if (rev >= 1)
2082 ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
2083 ahc->instruction_ram_size = 512;
2084 return (0);
2085}
2086
2087static int
2088ahc_apa1480_setup(struct ahc_softc *ahc)
2089{
2090 int error;
2091
2092 error = ahc_aic7860_setup(ahc);
2093 if (error != 0)
2094 return (error);
2095 ahc->features |= AHC_REMOVABLE;
2096 return (0);
2097}
2098
2099static int
2100ahc_aic7870_setup(struct ahc_softc *ahc)
2101{
2102
2103 ahc->channel = 'A';
2104 ahc->chip = AHC_AIC7870;
2105 ahc->features = AHC_AIC7870_FE;
2106 ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
2107 ahc->instruction_ram_size = 512;
2108 return (0);
2109}
2110
2111static int
2112ahc_aha394X_setup(struct ahc_softc *ahc)
2113{
2114 int error;
2115
2116 error = ahc_aic7870_setup(ahc);
2117 if (error == 0)
2118 error = ahc_aha394XX_setup(ahc);
2119 return (error);
2120}
2121
2122static int
2123ahc_aha398X_setup(struct ahc_softc *ahc)
2124{
2125 int error;
2126
2127 error = ahc_aic7870_setup(ahc);
2128 if (error == 0)
2129 error = ahc_aha398XX_setup(ahc);
2130 return (error);
2131}
2132
2133static int
2134ahc_aha494X_setup(struct ahc_softc *ahc)
2135{
2136 int error;
2137
2138 error = ahc_aic7870_setup(ahc);
2139 if (error == 0)
2140 error = ahc_aha494XX_setup(ahc);
2141 return (error);
2142}
2143
2144static int
2145ahc_aic7880_setup(struct ahc_softc *ahc)
2146{
2147 ahc_dev_softc_t pci;
2148 uint8_t rev;
2149
2150 pci = ahc->dev_softc;
2151 ahc->channel = 'A';
2152 ahc->chip = AHC_AIC7880;
2153 ahc->features = AHC_AIC7880_FE;
2154 ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
2155 rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
2156 if (rev >= 1) {
2157 ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
2158 } else {
2159 ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
2160 }
2161 ahc->instruction_ram_size = 512;
2162 return (0);
2163}
2164
2165static int
2166ahc_aha2940Pro_setup(struct ahc_softc *ahc)
2167{
2168
2169 ahc->flags |= AHC_INT50_SPEEDFLEX;
2170 return (ahc_aic7880_setup(ahc));
2171}
2172
2173static int
2174ahc_aha394XU_setup(struct ahc_softc *ahc)
2175{
2176 int error;
2177
2178 error = ahc_aic7880_setup(ahc);
2179 if (error == 0)
2180 error = ahc_aha394XX_setup(ahc);
2181 return (error);
2182}
2183
2184static int
2185ahc_aha398XU_setup(struct ahc_softc *ahc)
2186{
2187 int error;
2188
2189 error = ahc_aic7880_setup(ahc);
2190 if (error == 0)
2191 error = ahc_aha398XX_setup(ahc);
2192 return (error);
2193}
2194
2195static int
2196ahc_aic7890_setup(struct ahc_softc *ahc)
2197{
2198 ahc_dev_softc_t pci;
2199 uint8_t rev;
2200
2201 pci = ahc->dev_softc;
2202 ahc->channel = 'A';
2203 ahc->chip = AHC_AIC7890;
2204 ahc->features = AHC_AIC7890_FE;
2205 ahc->flags |= AHC_NEWEEPROM_FMT;
2206 rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
2207 if (rev == 0)
2208 ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG;
2209 ahc->instruction_ram_size = 768;
2210 return (0);
2211}
2212
2213static int
2214ahc_aic7892_setup(struct ahc_softc *ahc)
2215{
2216
2217 ahc->channel = 'A';
2218 ahc->chip = AHC_AIC7892;
2219 ahc->features = AHC_AIC7892_FE;
2220 ahc->flags |= AHC_NEWEEPROM_FMT;
2221 ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
2222 ahc->instruction_ram_size = 1024;
2223 return (0);
2224}
2225
2226static int
2227ahc_aic7895_setup(struct ahc_softc *ahc)
2228{
2229 ahc_dev_softc_t pci;
2230 uint8_t rev;
2231
2232 pci = ahc->dev_softc;
2233 ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
2234 /*
2235 * The 'C' revision of the aic7895 has a few additional features.
2236 */
2237 rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
2238 if (rev >= 4) {
2239 ahc->chip = AHC_AIC7895C;
2240 ahc->features = AHC_AIC7895C_FE;
2241 } else {
2242 u_int command;
2243
2244 ahc->chip = AHC_AIC7895;
2245 ahc->features = AHC_AIC7895_FE;
2246
2247 /*
2248 * The BIOS disables the use of MWI transactions
2249 * since it does not have the MWI bug work around
2250 * we have. Disabling MWI reduces performance, so
2251 * turn it on again.
2252 */
2253 command = ahc_pci_read_config(pci, PCIR_COMMAND, /*bytes*/1);
2254 command |= PCIM_CMD_MWRICEN;
2255 ahc_pci_write_config(pci, PCIR_COMMAND, command, /*bytes*/1);
2256 ahc->bugs |= AHC_PCI_MWI_BUG;
2257 }
2258 /*
2259 * XXX Does CACHETHEN really not work??? What about PCI retry?
2260 * on C level chips. Need to test, but for now, play it safe.
2261 */
2262 ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_PCI_2_1_RETRY_BUG
2263 | AHC_CACHETHEN_BUG;
2264
2265#if 0
2266 uint32_t devconfig;
2267
2268 /*
2269 * Cachesize must also be zero due to stray DAC
2270 * problem when sitting behind some bridges.
2271 */
2272 ahc_pci_write_config(pci, CSIZE_LATTIME, 0, /*bytes*/1);
2273 devconfig = ahc_pci_read_config(pci, DEVCONFIG, /*bytes*/1);
2274 devconfig |= MRDCEN;
2275 ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1);
2276#endif
2277 ahc->flags |= AHC_NEWEEPROM_FMT;
2278 ahc->instruction_ram_size = 512;
2279 return (0);
2280}
2281
2282static int
2283ahc_aic7896_setup(struct ahc_softc *ahc)
2284{
2285 ahc_dev_softc_t pci;
2286
2287 pci = ahc->dev_softc;
2288 ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
2289 ahc->chip = AHC_AIC7896;
2290 ahc->features = AHC_AIC7896_FE;
2291 ahc->flags |= AHC_NEWEEPROM_FMT;
2292 ahc->bugs |= AHC_CACHETHEN_DIS_BUG;
2293 ahc->instruction_ram_size = 768;
2294 return (0);
2295}
2296
2297static int
2298ahc_aic7899_setup(struct ahc_softc *ahc)
2299{
2300 ahc_dev_softc_t pci;
2301
2302 pci = ahc->dev_softc;
2303 ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
2304 ahc->chip = AHC_AIC7899;
2305 ahc->features = AHC_AIC7899_FE;
2306 ahc->flags |= AHC_NEWEEPROM_FMT;
2307 ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;
2308 ahc->instruction_ram_size = 1024;
2309 return (0);
2310}
2311
2312static int
2313ahc_aha29160C_setup(struct ahc_softc *ahc)
2314{
2315 int error;
2316
2317 error = ahc_aic7899_setup(ahc);
2318 if (error != 0)
2319 return (error);
2320 ahc->features |= AHC_REMOVABLE;
2321 return (0);
2322}
2323
2324static int
2325ahc_raid_setup(struct ahc_softc *ahc)
2326{
2327 printf("RAID functionality unsupported\n");
2328 return (ENXIO);
2329}
2330
2331static int
2332ahc_aha394XX_setup(struct ahc_softc *ahc)
2333{
2334 ahc_dev_softc_t pci;
2335
2336 pci = ahc->dev_softc;
2337 switch (ahc_get_pci_slot(pci)) {
2338 case AHC_394X_SLOT_CHANNEL_A:
2339 ahc->channel = 'A';
2340 break;
2341 case AHC_394X_SLOT_CHANNEL_B:
2342 ahc->channel = 'B';
2343 break;
2344 default:
2345 printf("adapter at unexpected slot %d\n"
2346 "unable to map to a channel\n",
2347 ahc_get_pci_slot(pci));
2348 ahc->channel = 'A';
2349 }
2350 return (0);
2351}
2352
2353static int
2354ahc_aha398XX_setup(struct ahc_softc *ahc)
2355{
2356 ahc_dev_softc_t pci;
2357
2358 pci = ahc->dev_softc;
2359 switch (ahc_get_pci_slot(pci)) {
2360 case AHC_398X_SLOT_CHANNEL_A:
2361 ahc->channel = 'A';
2362 break;
2363 case AHC_398X_SLOT_CHANNEL_B:
2364 ahc->channel = 'B';
2365 break;
2366 case AHC_398X_SLOT_CHANNEL_C:
2367 ahc->channel = 'C';
2368 break;
2369 default:
2370 printf("adapter at unexpected slot %d\n"
2371 "unable to map to a channel\n",
2372 ahc_get_pci_slot(pci));
2373 ahc->channel = 'A';
2374 break;
2375 }
2376 ahc->flags |= AHC_LARGE_SEEPROM;
2377 return (0);
2378}
2379
2380static int
2381ahc_aha494XX_setup(struct ahc_softc *ahc)
2382{
2383 ahc_dev_softc_t pci;
2384
2385 pci = ahc->dev_softc;
2386 switch (ahc_get_pci_slot(pci)) {
2387 case AHC_494X_SLOT_CHANNEL_A:
2388 ahc->channel = 'A';
2389 break;
2390 case AHC_494X_SLOT_CHANNEL_B:
2391 ahc->channel = 'B';
2392 break;
2393 case AHC_494X_SLOT_CHANNEL_C:
2394 ahc->channel = 'C';
2395 break;
2396 case AHC_494X_SLOT_CHANNEL_D:
2397 ahc->channel = 'D';
2398 break;
2399 default:
2400 printf("adapter at unexpected slot %d\n"
2401 "unable to map to a channel\n",
2402 ahc_get_pci_slot(pci));
2403 ahc->channel = 'A';
2404 }
2405 ahc->flags |= AHC_LARGE_SEEPROM;
2406 return (0);
2407}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.h b/drivers/scsi/aic7xxx/aic7xxx_pci.h
new file mode 100644
index 000000000000..be27fcb20346
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.h
@@ -0,0 +1,124 @@
1/*
2 * Adaptec AIC7xxx device driver for Linux.
3 *
4 * Copyright (c) 2000-2001 Adaptec Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon
16 * including a substantially similar Disclaimer requirement for further
17 * binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * Alternatively, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2 as published by the Free
24 * Software Foundation.
25 *
26 * NO WARRANTY
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGES.
38 *
39 * $Id$
40 *
41 */
42#ifndef _AIC7XXX_PCI_H_
43#define _AIC7XXX_PCI_H_
44
45#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull
46#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
47#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
48#define ID_9005_SISL_MASK 0x000FFFFF00000000ull
49#define ID_9005_SISL_ID 0x0005900500000000ull
50#define ID_AIC7850 0x5078900400000000ull
51#define ID_AHA_2902_04_10_15_20C_30C 0x5078900478509004ull
52#define ID_AIC7855 0x5578900400000000ull
53#define ID_AIC7859 0x3860900400000000ull
54#define ID_AHA_2930CU 0x3860900438699004ull
55#define ID_AIC7860 0x6078900400000000ull
56#define ID_AIC7860C 0x6078900478609004ull
57#define ID_AHA_1480A 0x6075900400000000ull
58#define ID_AHA_2940AU_0 0x6178900400000000ull
59#define ID_AHA_2940AU_1 0x6178900478619004ull
60#define ID_AHA_2940AU_CN 0x2178900478219004ull
61#define ID_AHA_2930C_VAR 0x6038900438689004ull
62
63#define ID_AIC7870 0x7078900400000000ull
64#define ID_AHA_2940 0x7178900400000000ull
65#define ID_AHA_3940 0x7278900400000000ull
66#define ID_AHA_398X 0x7378900400000000ull
67#define ID_AHA_2944 0x7478900400000000ull
68#define ID_AHA_3944 0x7578900400000000ull
69#define ID_AHA_4944 0x7678900400000000ull
70
71#define ID_AIC7880 0x8078900400000000ull
72#define ID_AIC7880_B 0x8078900478809004ull
73#define ID_AHA_2940U 0x8178900400000000ull
74#define ID_AHA_3940U 0x8278900400000000ull
75#define ID_AHA_2944U 0x8478900400000000ull
76#define ID_AHA_3944U 0x8578900400000000ull
77#define ID_AHA_398XU 0x8378900400000000ull
78#define ID_AHA_4944U 0x8678900400000000ull
79#define ID_AHA_2940UB 0x8178900478819004ull
80#define ID_AHA_2930U 0x8878900478889004ull
81#define ID_AHA_2940U_PRO 0x8778900478879004ull
82#define ID_AHA_2940U_CN 0x0078900478009004ull
83
84#define ID_AIC7895 0x7895900478959004ull
85#define ID_AIC7895_ARO 0x7890900478939004ull
86#define ID_AIC7895_ARO_MASK 0xFFF0FFFFFFFFFFFFull
87#define ID_AHA_2940U_DUAL 0x7895900478919004ull
88#define ID_AHA_3940AU 0x7895900478929004ull
89#define ID_AHA_3944AU 0x7895900478949004ull
90
91#define ID_AIC7890 0x001F9005000F9005ull
92#define ID_AIC7890_ARO 0x00139005000F9005ull
93#define ID_AAA_131U2 0x0013900500039005ull
94#define ID_AHA_2930U2 0x0011900501819005ull
95#define ID_AHA_2940U2B 0x00109005A1009005ull
96#define ID_AHA_2940U2_OEM 0x0010900521809005ull
97#define ID_AHA_2940U2 0x00109005A1809005ull
98#define ID_AHA_2950U2B 0x00109005E1009005ull
99
100#define ID_AIC7892 0x008F9005FFFF9005ull
101#define ID_AIC7892_ARO 0x00839005FFFF9005ull
102#define ID_AHA_29160 0x00809005E2A09005ull
103#define ID_AHA_29160_CPQ 0x00809005E2A00E11ull
104#define ID_AHA_29160N 0x0080900562A09005ull
105#define ID_AHA_29160C 0x0080900562209005ull
106#define ID_AHA_29160B 0x00809005E2209005ull
107#define ID_AHA_19160B 0x0081900562A19005ull
108
109#define ID_AIC7896 0x005F9005FFFF9005ull
110#define ID_AIC7896_ARO 0x00539005FFFF9005ull
111#define ID_AHA_3950U2B_0 0x00509005FFFF9005ull
112#define ID_AHA_3950U2B_1 0x00509005F5009005ull
113#define ID_AHA_3950U2D_0 0x00519005FFFF9005ull
114#define ID_AHA_3950U2D_1 0x00519005B5009005ull
115
116#define ID_AIC7899 0x00CF9005FFFF9005ull
117#define ID_AIC7899_ARO 0x00C39005FFFF9005ull
118#define ID_AHA_3960D 0x00C09005F6209005ull
119#define ID_AHA_3960D_CPQ 0x00C09005F6200E11ull
120
121#define ID_AIC7810 0x1078900400000000ull
122#define ID_AIC7815 0x7815900400000000ull
123
124#endif /* _AIC7XXX_PCI_H_ */
diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c
new file mode 100644
index 000000000000..85e80eecc9d0
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c
@@ -0,0 +1,385 @@
1/*
2 * Copyright (c) 2000-2001 Adaptec Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions, and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * substantially similar to the "NO WARRANTY" disclaimer below
13 * ("Disclaimer") and any redistribution must be conditioned upon
14 * including a substantially similar Disclaimer requirement for further
15 * binary redistribution.
16 * 3. Neither the names of the above-listed copyright holders nor the names
17 * of any contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation.
23 *
24 * NO WARRANTY
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
34 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGES.
36 *
37 * String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
38 * sym driver.
39 *
40 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#29 $
41 */
42#include "aic7xxx_osm.h"
43#include "aic7xxx_inline.h"
44#include "aic7xxx_93cx6.h"
45
46static void copy_mem_info(struct info_str *info, char *data, int len);
47static int copy_info(struct info_str *info, char *fmt, ...);
48static void ahc_dump_target_state(struct ahc_softc *ahc,
49 struct info_str *info,
50 u_int our_id, char channel,
51 u_int target_id, u_int target_offset);
52static void ahc_dump_device_state(struct info_str *info,
53 struct ahc_linux_device *dev);
54static int ahc_proc_write_seeprom(struct ahc_softc *ahc,
55 char *buffer, int length);
56
57static void
58copy_mem_info(struct info_str *info, char *data, int len)
59{
60 if (info->pos + len > info->offset + info->length)
61 len = info->offset + info->length - info->pos;
62
63 if (info->pos + len < info->offset) {
64 info->pos += len;
65 return;
66 }
67
68 if (info->pos < info->offset) {
69 off_t partial;
70
71 partial = info->offset - info->pos;
72 data += partial;
73 info->pos += partial;
74 len -= partial;
75 }
76
77 if (len > 0) {
78 memcpy(info->buffer, data, len);
79 info->pos += len;
80 info->buffer += len;
81 }
82}
83
84static int
85copy_info(struct info_str *info, char *fmt, ...)
86{
87 va_list args;
88 char buf[256];
89 int len;
90
91 va_start(args, fmt);
92 len = vsprintf(buf, fmt, args);
93 va_end(args);
94
95 copy_mem_info(info, buf, len);
96 return (len);
97}
98
99void
100ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo)
101{
102 u_int speed;
103 u_int freq;
104 u_int mb;
105
106 speed = 3300;
107 freq = 0;
108 if (tinfo->offset != 0) {
109 freq = aic_calc_syncsrate(tinfo->period);
110 speed = freq;
111 }
112 speed *= (0x01 << tinfo->width);
113 mb = speed / 1000;
114 if (mb > 0)
115 copy_info(info, "%d.%03dMB/s transfers", mb, speed % 1000);
116 else
117 copy_info(info, "%dKB/s transfers", speed);
118
119 if (freq != 0) {
120 copy_info(info, " (%d.%03dMHz%s, offset %d",
121 freq / 1000, freq % 1000,
122 (tinfo->ppr_options & MSG_EXT_PPR_DT_REQ) != 0
123 ? " DT" : "", tinfo->offset);
124 }
125
126 if (tinfo->width > 0) {
127 if (freq != 0) {
128 copy_info(info, ", ");
129 } else {
130 copy_info(info, " (");
131 }
132 copy_info(info, "%dbit)", 8 * (0x01 << tinfo->width));
133 } else if (freq != 0) {
134 copy_info(info, ")");
135 }
136 copy_info(info, "\n");
137}
138
139static void
140ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info,
141 u_int our_id, char channel, u_int target_id,
142 u_int target_offset)
143{
144 struct ahc_linux_target *targ;
145 struct ahc_initiator_tinfo *tinfo;
146 struct ahc_tmode_tstate *tstate;
147 int lun;
148
149 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
150 target_id, &tstate);
151 if ((ahc->features & AHC_TWIN) != 0)
152 copy_info(info, "Channel %c ", channel);
153 copy_info(info, "Target %d Negotiation Settings\n", target_id);
154 copy_info(info, "\tUser: ");
155 ahc_format_transinfo(info, &tinfo->user);
156 targ = ahc->platform_data->targets[target_offset];
157 if (targ == NULL)
158 return;
159
160 copy_info(info, "\tGoal: ");
161 ahc_format_transinfo(info, &tinfo->goal);
162 copy_info(info, "\tCurr: ");
163 ahc_format_transinfo(info, &tinfo->curr);
164
165 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
166 struct ahc_linux_device *dev;
167
168 dev = targ->devices[lun];
169
170 if (dev == NULL)
171 continue;
172
173 ahc_dump_device_state(info, dev);
174 }
175}
176
177static void
178ahc_dump_device_state(struct info_str *info, struct ahc_linux_device *dev)
179{
180 copy_info(info, "\tChannel %c Target %d Lun %d Settings\n",
181 dev->target->channel + 'A', dev->target->target, dev->lun);
182
183 copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued);
184 copy_info(info, "\t\tCommands Active %d\n", dev->active);
185 copy_info(info, "\t\tCommand Openings %d\n", dev->openings);
186 copy_info(info, "\t\tMax Tagged Openings %d\n", dev->maxtags);
187 copy_info(info, "\t\tDevice Queue Frozen Count %d\n", dev->qfrozen);
188}
189
190static int
191ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length)
192{
193 struct seeprom_descriptor sd;
194 int have_seeprom;
195 u_long s;
196 int paused;
197 int written;
198
199 /* Default to failure. */
200 written = -EINVAL;
201 ahc_lock(ahc, &s);
202 paused = ahc_is_paused(ahc);
203 if (!paused)
204 ahc_pause(ahc);
205
206 if (length != sizeof(struct seeprom_config)) {
207 printf("ahc_proc_write_seeprom: incorrect buffer size\n");
208 goto done;
209 }
210
211 have_seeprom = ahc_verify_cksum((struct seeprom_config*)buffer);
212 if (have_seeprom == 0) {
213 printf("ahc_proc_write_seeprom: cksum verification failed\n");
214 goto done;
215 }
216
217 sd.sd_ahc = ahc;
218#if AHC_PCI_CONFIG > 0
219 if ((ahc->chip & AHC_PCI) != 0) {
220 sd.sd_control_offset = SEECTL;
221 sd.sd_status_offset = SEECTL;
222 sd.sd_dataout_offset = SEECTL;
223 if (ahc->flags & AHC_LARGE_SEEPROM)
224 sd.sd_chip = C56_66;
225 else
226 sd.sd_chip = C46;
227 sd.sd_MS = SEEMS;
228 sd.sd_RDY = SEERDY;
229 sd.sd_CS = SEECS;
230 sd.sd_CK = SEECK;
231 sd.sd_DO = SEEDO;
232 sd.sd_DI = SEEDI;
233 have_seeprom = ahc_acquire_seeprom(ahc, &sd);
234 } else
235#endif
236 if ((ahc->chip & AHC_VL) != 0) {
237 sd.sd_control_offset = SEECTL_2840;
238 sd.sd_status_offset = STATUS_2840;
239 sd.sd_dataout_offset = STATUS_2840;
240 sd.sd_chip = C46;
241 sd.sd_MS = 0;
242 sd.sd_RDY = EEPROM_TF;
243 sd.sd_CS = CS_2840;
244 sd.sd_CK = CK_2840;
245 sd.sd_DO = DO_2840;
246 sd.sd_DI = DI_2840;
247 have_seeprom = TRUE;
248 } else {
249 printf("ahc_proc_write_seeprom: unsupported adapter type\n");
250 goto done;
251 }
252
253 if (!have_seeprom) {
254 printf("ahc_proc_write_seeprom: No Serial EEPROM\n");
255 goto done;
256 } else {
257 u_int start_addr;
258
259 if (ahc->seep_config == NULL) {
260 ahc->seep_config = malloc(sizeof(*ahc->seep_config),
261 M_DEVBUF, M_NOWAIT);
262 if (ahc->seep_config == NULL) {
263 printf("aic7xxx: Unable to allocate serial "
264 "eeprom buffer. Write failing\n");
265 goto done;
266 }
267 }
268 printf("aic7xxx: Writing Serial EEPROM\n");
269 start_addr = 32 * (ahc->channel - 'A');
270 ahc_write_seeprom(&sd, (u_int16_t *)buffer, start_addr,
271 sizeof(struct seeprom_config)/2);
272 ahc_read_seeprom(&sd, (uint16_t *)ahc->seep_config,
273 start_addr, sizeof(struct seeprom_config)/2);
274#if AHC_PCI_CONFIG > 0
275 if ((ahc->chip & AHC_VL) == 0)
276 ahc_release_seeprom(&sd);
277#endif
278 written = length;
279 }
280
281done:
282 if (!paused)
283 ahc_unpause(ahc);
284 ahc_unlock(ahc, &s);
285 return (written);
286}
287
288/*
289 * Return information to handle /proc support for the driver.
290 */
291int
292#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
293ahc_linux_proc_info(char *buffer, char **start, off_t offset,
294 int length, int hostno, int inout)
295#else
296ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
297 off_t offset, int length, int inout)
298#endif
299{
300 struct ahc_softc *ahc;
301 struct info_str info;
302 char ahc_info[256];
303 u_long s;
304 u_int max_targ;
305 u_int i;
306 int retval;
307
308 retval = -EINVAL;
309 ahc_list_lock(&s);
310#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
311 TAILQ_FOREACH(ahc, &ahc_tailq, links) {
312 if (ahc->platform_data->host->host_no == hostno)
313 break;
314 }
315#else
316 ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata);
317#endif
318
319 if (ahc == NULL)
320 goto done;
321
322 /* Has data been written to the file? */
323 if (inout == TRUE) {
324 retval = ahc_proc_write_seeprom(ahc, buffer, length);
325 goto done;
326 }
327
328 if (start)
329 *start = buffer;
330
331 info.buffer = buffer;
332 info.length = length;
333 info.offset = offset;
334 info.pos = 0;
335
336 copy_info(&info, "Adaptec AIC7xxx driver version: %s\n",
337 AIC7XXX_DRIVER_VERSION);
338 copy_info(&info, "%s\n", ahc->description);
339 ahc_controller_info(ahc, ahc_info);
340 copy_info(&info, "%s\n", ahc_info);
341 copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n",
342 ahc->scb_data->numscbs, AHC_NSEG);
343
344
345 if (ahc->seep_config == NULL)
346 copy_info(&info, "No Serial EEPROM\n");
347 else {
348 copy_info(&info, "Serial EEPROM:\n");
349 for (i = 0; i < sizeof(*ahc->seep_config)/2; i++) {
350 if (((i % 8) == 0) && (i != 0)) {
351 copy_info(&info, "\n");
352 }
353 copy_info(&info, "0x%.4x ",
354 ((uint16_t*)ahc->seep_config)[i]);
355 }
356 copy_info(&info, "\n");
357 }
358 copy_info(&info, "\n");
359
360 max_targ = 15;
361 if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
362 max_targ = 7;
363
364 for (i = 0; i <= max_targ; i++) {
365 u_int our_id;
366 u_int target_id;
367 char channel;
368
369 channel = 'A';
370 our_id = ahc->our_id;
371 target_id = i;
372 if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
373 channel = 'B';
374 our_id = ahc->our_id_b;
375 target_id = i % 8;
376 }
377
378 ahc_dump_target_state(ahc, &info, our_id,
379 channel, target_id, i);
380 }
381 retval = info.pos > info.offset ? info.pos - info.offset : 0;
382done:
383 ahc_list_unlock(&s);
384 return (retval);
385}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped
new file mode 100644
index 000000000000..7c1390ed1179
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped
@@ -0,0 +1,1787 @@
1/*
2 * DO NOT EDIT - This file is automatically generated
3 * from the following source files:
4 *
5 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
6 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
7 */
8typedef int (ahc_reg_print_t)(u_int, u_int *, u_int);
9typedef struct ahc_reg_parse_entry {
10 char *name;
11 uint8_t value;
12 uint8_t mask;
13} ahc_reg_parse_entry_t;
14
15#if AIC_DEBUG_REGISTERS
16ahc_reg_print_t ahc_scsiseq_print;
17#else
18#define ahc_scsiseq_print(regvalue, cur_col, wrap) \
19 ahc_print_register(NULL, 0, "SCSISEQ", 0x00, regvalue, cur_col, wrap)
20#endif
21
22#if AIC_DEBUG_REGISTERS
23ahc_reg_print_t ahc_sxfrctl0_print;
24#else
25#define ahc_sxfrctl0_print(regvalue, cur_col, wrap) \
26 ahc_print_register(NULL, 0, "SXFRCTL0", 0x01, regvalue, cur_col, wrap)
27#endif
28
29#if AIC_DEBUG_REGISTERS
30ahc_reg_print_t ahc_sxfrctl1_print;
31#else
32#define ahc_sxfrctl1_print(regvalue, cur_col, wrap) \
33 ahc_print_register(NULL, 0, "SXFRCTL1", 0x02, regvalue, cur_col, wrap)
34#endif
35
36#if AIC_DEBUG_REGISTERS
37ahc_reg_print_t ahc_scsisigo_print;
38#else
39#define ahc_scsisigo_print(regvalue, cur_col, wrap) \
40 ahc_print_register(NULL, 0, "SCSISIGO", 0x03, regvalue, cur_col, wrap)
41#endif
42
43#if AIC_DEBUG_REGISTERS
44ahc_reg_print_t ahc_scsisigi_print;
45#else
46#define ahc_scsisigi_print(regvalue, cur_col, wrap) \
47 ahc_print_register(NULL, 0, "SCSISIGI", 0x03, regvalue, cur_col, wrap)
48#endif
49
50#if AIC_DEBUG_REGISTERS
51ahc_reg_print_t ahc_scsirate_print;
52#else
53#define ahc_scsirate_print(regvalue, cur_col, wrap) \
54 ahc_print_register(NULL, 0, "SCSIRATE", 0x04, regvalue, cur_col, wrap)
55#endif
56
57#if AIC_DEBUG_REGISTERS
58ahc_reg_print_t ahc_scsiid_print;
59#else
60#define ahc_scsiid_print(regvalue, cur_col, wrap) \
61 ahc_print_register(NULL, 0, "SCSIID", 0x05, regvalue, cur_col, wrap)
62#endif
63
64#if AIC_DEBUG_REGISTERS
65ahc_reg_print_t ahc_scsidatl_print;
66#else
67#define ahc_scsidatl_print(regvalue, cur_col, wrap) \
68 ahc_print_register(NULL, 0, "SCSIDATL", 0x06, regvalue, cur_col, wrap)
69#endif
70
71#if AIC_DEBUG_REGISTERS
72ahc_reg_print_t ahc_scsidath_print;
73#else
74#define ahc_scsidath_print(regvalue, cur_col, wrap) \
75 ahc_print_register(NULL, 0, "SCSIDATH", 0x07, regvalue, cur_col, wrap)
76#endif
77
78#if AIC_DEBUG_REGISTERS
79ahc_reg_print_t ahc_stcnt_print;
80#else
81#define ahc_stcnt_print(regvalue, cur_col, wrap) \
82 ahc_print_register(NULL, 0, "STCNT", 0x08, regvalue, cur_col, wrap)
83#endif
84
85#if AIC_DEBUG_REGISTERS
86ahc_reg_print_t ahc_optionmode_print;
87#else
88#define ahc_optionmode_print(regvalue, cur_col, wrap) \
89 ahc_print_register(NULL, 0, "OPTIONMODE", 0x08, regvalue, cur_col, wrap)
90#endif
91
92#if AIC_DEBUG_REGISTERS
93ahc_reg_print_t ahc_targcrccnt_print;
94#else
95#define ahc_targcrccnt_print(regvalue, cur_col, wrap) \
96 ahc_print_register(NULL, 0, "TARGCRCCNT", 0x0a, regvalue, cur_col, wrap)
97#endif
98
99#if AIC_DEBUG_REGISTERS
100ahc_reg_print_t ahc_clrsint0_print;
101#else
102#define ahc_clrsint0_print(regvalue, cur_col, wrap) \
103 ahc_print_register(NULL, 0, "CLRSINT0", 0x0b, regvalue, cur_col, wrap)
104#endif
105
106#if AIC_DEBUG_REGISTERS
107ahc_reg_print_t ahc_sstat0_print;
108#else
109#define ahc_sstat0_print(regvalue, cur_col, wrap) \
110 ahc_print_register(NULL, 0, "SSTAT0", 0x0b, regvalue, cur_col, wrap)
111#endif
112
113#if AIC_DEBUG_REGISTERS
114ahc_reg_print_t ahc_clrsint1_print;
115#else
116#define ahc_clrsint1_print(regvalue, cur_col, wrap) \
117 ahc_print_register(NULL, 0, "CLRSINT1", 0x0c, regvalue, cur_col, wrap)
118#endif
119
120#if AIC_DEBUG_REGISTERS
121ahc_reg_print_t ahc_sstat1_print;
122#else
123#define ahc_sstat1_print(regvalue, cur_col, wrap) \
124 ahc_print_register(NULL, 0, "SSTAT1", 0x0c, regvalue, cur_col, wrap)
125#endif
126
127#if AIC_DEBUG_REGISTERS
128ahc_reg_print_t ahc_sstat2_print;
129#else
130#define ahc_sstat2_print(regvalue, cur_col, wrap) \
131 ahc_print_register(NULL, 0, "SSTAT2", 0x0d, regvalue, cur_col, wrap)
132#endif
133
134#if AIC_DEBUG_REGISTERS
135ahc_reg_print_t ahc_sstat3_print;
136#else
137#define ahc_sstat3_print(regvalue, cur_col, wrap) \
138 ahc_print_register(NULL, 0, "SSTAT3", 0x0e, regvalue, cur_col, wrap)
139#endif
140
141#if AIC_DEBUG_REGISTERS
142ahc_reg_print_t ahc_scsiid_ultra2_print;
143#else
144#define ahc_scsiid_ultra2_print(regvalue, cur_col, wrap) \
145 ahc_print_register(NULL, 0, "SCSIID_ULTRA2", 0x0f, regvalue, cur_col, wrap)
146#endif
147
148#if AIC_DEBUG_REGISTERS
149ahc_reg_print_t ahc_simode0_print;
150#else
151#define ahc_simode0_print(regvalue, cur_col, wrap) \
152 ahc_print_register(NULL, 0, "SIMODE0", 0x10, regvalue, cur_col, wrap)
153#endif
154
155#if AIC_DEBUG_REGISTERS
156ahc_reg_print_t ahc_simode1_print;
157#else
158#define ahc_simode1_print(regvalue, cur_col, wrap) \
159 ahc_print_register(NULL, 0, "SIMODE1", 0x11, regvalue, cur_col, wrap)
160#endif
161
162#if AIC_DEBUG_REGISTERS
163ahc_reg_print_t ahc_scsibusl_print;
164#else
165#define ahc_scsibusl_print(regvalue, cur_col, wrap) \
166 ahc_print_register(NULL, 0, "SCSIBUSL", 0x12, regvalue, cur_col, wrap)
167#endif
168
169#if AIC_DEBUG_REGISTERS
170ahc_reg_print_t ahc_scsibush_print;
171#else
172#define ahc_scsibush_print(regvalue, cur_col, wrap) \
173 ahc_print_register(NULL, 0, "SCSIBUSH", 0x13, regvalue, cur_col, wrap)
174#endif
175
176#if AIC_DEBUG_REGISTERS
177ahc_reg_print_t ahc_sxfrctl2_print;
178#else
179#define ahc_sxfrctl2_print(regvalue, cur_col, wrap) \
180 ahc_print_register(NULL, 0, "SXFRCTL2", 0x13, regvalue, cur_col, wrap)
181#endif
182
183#if AIC_DEBUG_REGISTERS
184ahc_reg_print_t ahc_shaddr_print;
185#else
186#define ahc_shaddr_print(regvalue, cur_col, wrap) \
187 ahc_print_register(NULL, 0, "SHADDR", 0x14, regvalue, cur_col, wrap)
188#endif
189
190#if AIC_DEBUG_REGISTERS
191ahc_reg_print_t ahc_seltimer_print;
192#else
193#define ahc_seltimer_print(regvalue, cur_col, wrap) \
194 ahc_print_register(NULL, 0, "SELTIMER", 0x18, regvalue, cur_col, wrap)
195#endif
196
197#if AIC_DEBUG_REGISTERS
198ahc_reg_print_t ahc_selid_print;
199#else
200#define ahc_selid_print(regvalue, cur_col, wrap) \
201 ahc_print_register(NULL, 0, "SELID", 0x19, regvalue, cur_col, wrap)
202#endif
203
204#if AIC_DEBUG_REGISTERS
205ahc_reg_print_t ahc_scamctl_print;
206#else
207#define ahc_scamctl_print(regvalue, cur_col, wrap) \
208 ahc_print_register(NULL, 0, "SCAMCTL", 0x1a, regvalue, cur_col, wrap)
209#endif
210
211#if AIC_DEBUG_REGISTERS
212ahc_reg_print_t ahc_targid_print;
213#else
214#define ahc_targid_print(regvalue, cur_col, wrap) \
215 ahc_print_register(NULL, 0, "TARGID", 0x1b, regvalue, cur_col, wrap)
216#endif
217
218#if AIC_DEBUG_REGISTERS
219ahc_reg_print_t ahc_spiocap_print;
220#else
221#define ahc_spiocap_print(regvalue, cur_col, wrap) \
222 ahc_print_register(NULL, 0, "SPIOCAP", 0x1b, regvalue, cur_col, wrap)
223#endif
224
225#if AIC_DEBUG_REGISTERS
226ahc_reg_print_t ahc_brdctl_print;
227#else
228#define ahc_brdctl_print(regvalue, cur_col, wrap) \
229 ahc_print_register(NULL, 0, "BRDCTL", 0x1d, regvalue, cur_col, wrap)
230#endif
231
232#if AIC_DEBUG_REGISTERS
233ahc_reg_print_t ahc_seectl_print;
234#else
235#define ahc_seectl_print(regvalue, cur_col, wrap) \
236 ahc_print_register(NULL, 0, "SEECTL", 0x1e, regvalue, cur_col, wrap)
237#endif
238
239#if AIC_DEBUG_REGISTERS
240ahc_reg_print_t ahc_sblkctl_print;
241#else
242#define ahc_sblkctl_print(regvalue, cur_col, wrap) \
243 ahc_print_register(NULL, 0, "SBLKCTL", 0x1f, regvalue, cur_col, wrap)
244#endif
245
246#if AIC_DEBUG_REGISTERS
247ahc_reg_print_t ahc_busy_targets_print;
248#else
249#define ahc_busy_targets_print(regvalue, cur_col, wrap) \
250 ahc_print_register(NULL, 0, "BUSY_TARGETS", 0x20, regvalue, cur_col, wrap)
251#endif
252
253#if AIC_DEBUG_REGISTERS
254ahc_reg_print_t ahc_ultra_enb_print;
255#else
256#define ahc_ultra_enb_print(regvalue, cur_col, wrap) \
257 ahc_print_register(NULL, 0, "ULTRA_ENB", 0x30, regvalue, cur_col, wrap)
258#endif
259
260#if AIC_DEBUG_REGISTERS
261ahc_reg_print_t ahc_disc_dsb_print;
262#else
263#define ahc_disc_dsb_print(regvalue, cur_col, wrap) \
264 ahc_print_register(NULL, 0, "DISC_DSB", 0x32, regvalue, cur_col, wrap)
265#endif
266
267#if AIC_DEBUG_REGISTERS
268ahc_reg_print_t ahc_cmdsize_table_tail_print;
269#else
270#define ahc_cmdsize_table_tail_print(regvalue, cur_col, wrap) \
271 ahc_print_register(NULL, 0, "CMDSIZE_TABLE_TAIL", 0x34, regvalue, cur_col, wrap)
272#endif
273
274#if AIC_DEBUG_REGISTERS
275ahc_reg_print_t ahc_mwi_residual_print;
276#else
277#define ahc_mwi_residual_print(regvalue, cur_col, wrap) \
278 ahc_print_register(NULL, 0, "MWI_RESIDUAL", 0x38, regvalue, cur_col, wrap)
279#endif
280
281#if AIC_DEBUG_REGISTERS
282ahc_reg_print_t ahc_next_queued_scb_print;
283#else
284#define ahc_next_queued_scb_print(regvalue, cur_col, wrap) \
285 ahc_print_register(NULL, 0, "NEXT_QUEUED_SCB", 0x39, regvalue, cur_col, wrap)
286#endif
287
288#if AIC_DEBUG_REGISTERS
289ahc_reg_print_t ahc_msg_out_print;
290#else
291#define ahc_msg_out_print(regvalue, cur_col, wrap) \
292 ahc_print_register(NULL, 0, "MSG_OUT", 0x3a, regvalue, cur_col, wrap)
293#endif
294
295#if AIC_DEBUG_REGISTERS
296ahc_reg_print_t ahc_dmaparams_print;
297#else
298#define ahc_dmaparams_print(regvalue, cur_col, wrap) \
299 ahc_print_register(NULL, 0, "DMAPARAMS", 0x3b, regvalue, cur_col, wrap)
300#endif
301
302#if AIC_DEBUG_REGISTERS
303ahc_reg_print_t ahc_seq_flags_print;
304#else
305#define ahc_seq_flags_print(regvalue, cur_col, wrap) \
306 ahc_print_register(NULL, 0, "SEQ_FLAGS", 0x3c, regvalue, cur_col, wrap)
307#endif
308
309#if AIC_DEBUG_REGISTERS
310ahc_reg_print_t ahc_saved_scsiid_print;
311#else
312#define ahc_saved_scsiid_print(regvalue, cur_col, wrap) \
313 ahc_print_register(NULL, 0, "SAVED_SCSIID", 0x3d, regvalue, cur_col, wrap)
314#endif
315
316#if AIC_DEBUG_REGISTERS
317ahc_reg_print_t ahc_saved_lun_print;
318#else
319#define ahc_saved_lun_print(regvalue, cur_col, wrap) \
320 ahc_print_register(NULL, 0, "SAVED_LUN", 0x3e, regvalue, cur_col, wrap)
321#endif
322
323#if AIC_DEBUG_REGISTERS
324ahc_reg_print_t ahc_lastphase_print;
325#else
326#define ahc_lastphase_print(regvalue, cur_col, wrap) \
327 ahc_print_register(NULL, 0, "LASTPHASE", 0x3f, regvalue, cur_col, wrap)
328#endif
329
330#if AIC_DEBUG_REGISTERS
331ahc_reg_print_t ahc_waiting_scbh_print;
332#else
333#define ahc_waiting_scbh_print(regvalue, cur_col, wrap) \
334 ahc_print_register(NULL, 0, "WAITING_SCBH", 0x40, regvalue, cur_col, wrap)
335#endif
336
337#if AIC_DEBUG_REGISTERS
338ahc_reg_print_t ahc_disconnected_scbh_print;
339#else
340#define ahc_disconnected_scbh_print(regvalue, cur_col, wrap) \
341 ahc_print_register(NULL, 0, "DISCONNECTED_SCBH", 0x41, regvalue, cur_col, wrap)
342#endif
343
344#if AIC_DEBUG_REGISTERS
345ahc_reg_print_t ahc_free_scbh_print;
346#else
347#define ahc_free_scbh_print(regvalue, cur_col, wrap) \
348 ahc_print_register(NULL, 0, "FREE_SCBH", 0x42, regvalue, cur_col, wrap)
349#endif
350
351#if AIC_DEBUG_REGISTERS
352ahc_reg_print_t ahc_complete_scbh_print;
353#else
354#define ahc_complete_scbh_print(regvalue, cur_col, wrap) \
355 ahc_print_register(NULL, 0, "COMPLETE_SCBH", 0x43, regvalue, cur_col, wrap)
356#endif
357
358#if AIC_DEBUG_REGISTERS
359ahc_reg_print_t ahc_hscb_addr_print;
360#else
361#define ahc_hscb_addr_print(regvalue, cur_col, wrap) \
362 ahc_print_register(NULL, 0, "HSCB_ADDR", 0x44, regvalue, cur_col, wrap)
363#endif
364
365#if AIC_DEBUG_REGISTERS
366ahc_reg_print_t ahc_shared_data_addr_print;
367#else
368#define ahc_shared_data_addr_print(regvalue, cur_col, wrap) \
369 ahc_print_register(NULL, 0, "SHARED_DATA_ADDR", 0x48, regvalue, cur_col, wrap)
370#endif
371
372#if AIC_DEBUG_REGISTERS
373ahc_reg_print_t ahc_kernel_qinpos_print;
374#else
375#define ahc_kernel_qinpos_print(regvalue, cur_col, wrap) \
376 ahc_print_register(NULL, 0, "KERNEL_QINPOS", 0x4c, regvalue, cur_col, wrap)
377#endif
378
379#if AIC_DEBUG_REGISTERS
380ahc_reg_print_t ahc_qinpos_print;
381#else
382#define ahc_qinpos_print(regvalue, cur_col, wrap) \
383 ahc_print_register(NULL, 0, "QINPOS", 0x4d, regvalue, cur_col, wrap)
384#endif
385
386#if AIC_DEBUG_REGISTERS
387ahc_reg_print_t ahc_qoutpos_print;
388#else
389#define ahc_qoutpos_print(regvalue, cur_col, wrap) \
390 ahc_print_register(NULL, 0, "QOUTPOS", 0x4e, regvalue, cur_col, wrap)
391#endif
392
393#if AIC_DEBUG_REGISTERS
394ahc_reg_print_t ahc_kernel_tqinpos_print;
395#else
396#define ahc_kernel_tqinpos_print(regvalue, cur_col, wrap) \
397 ahc_print_register(NULL, 0, "KERNEL_TQINPOS", 0x4f, regvalue, cur_col, wrap)
398#endif
399
400#if AIC_DEBUG_REGISTERS
401ahc_reg_print_t ahc_tqinpos_print;
402#else
403#define ahc_tqinpos_print(regvalue, cur_col, wrap) \
404 ahc_print_register(NULL, 0, "TQINPOS", 0x50, regvalue, cur_col, wrap)
405#endif
406
407#if AIC_DEBUG_REGISTERS
408ahc_reg_print_t ahc_arg_1_print;
409#else
410#define ahc_arg_1_print(regvalue, cur_col, wrap) \
411 ahc_print_register(NULL, 0, "ARG_1", 0x51, regvalue, cur_col, wrap)
412#endif
413
414#if AIC_DEBUG_REGISTERS
415ahc_reg_print_t ahc_arg_2_print;
416#else
417#define ahc_arg_2_print(regvalue, cur_col, wrap) \
418 ahc_print_register(NULL, 0, "ARG_2", 0x52, regvalue, cur_col, wrap)
419#endif
420
421#if AIC_DEBUG_REGISTERS
422ahc_reg_print_t ahc_last_msg_print;
423#else
424#define ahc_last_msg_print(regvalue, cur_col, wrap) \
425 ahc_print_register(NULL, 0, "LAST_MSG", 0x53, regvalue, cur_col, wrap)
426#endif
427
428#if AIC_DEBUG_REGISTERS
429ahc_reg_print_t ahc_scsiseq_template_print;
430#else
431#define ahc_scsiseq_template_print(regvalue, cur_col, wrap) \
432 ahc_print_register(NULL, 0, "SCSISEQ_TEMPLATE", 0x54, regvalue, cur_col, wrap)
433#endif
434
435#if AIC_DEBUG_REGISTERS
436ahc_reg_print_t ahc_ha_274_biosglobal_print;
437#else
438#define ahc_ha_274_biosglobal_print(regvalue, cur_col, wrap) \
439 ahc_print_register(NULL, 0, "HA_274_BIOSGLOBAL", 0x56, regvalue, cur_col, wrap)
440#endif
441
442#if AIC_DEBUG_REGISTERS
443ahc_reg_print_t ahc_seq_flags2_print;
444#else
445#define ahc_seq_flags2_print(regvalue, cur_col, wrap) \
446 ahc_print_register(NULL, 0, "SEQ_FLAGS2", 0x57, regvalue, cur_col, wrap)
447#endif
448
449#if AIC_DEBUG_REGISTERS
450ahc_reg_print_t ahc_scsiconf_print;
451#else
452#define ahc_scsiconf_print(regvalue, cur_col, wrap) \
453 ahc_print_register(NULL, 0, "SCSICONF", 0x5a, regvalue, cur_col, wrap)
454#endif
455
456#if AIC_DEBUG_REGISTERS
457ahc_reg_print_t ahc_intdef_print;
458#else
459#define ahc_intdef_print(regvalue, cur_col, wrap) \
460 ahc_print_register(NULL, 0, "INTDEF", 0x5c, regvalue, cur_col, wrap)
461#endif
462
463#if AIC_DEBUG_REGISTERS
464ahc_reg_print_t ahc_hostconf_print;
465#else
466#define ahc_hostconf_print(regvalue, cur_col, wrap) \
467 ahc_print_register(NULL, 0, "HOSTCONF", 0x5d, regvalue, cur_col, wrap)
468#endif
469
470#if AIC_DEBUG_REGISTERS
471ahc_reg_print_t ahc_ha_274_biosctrl_print;
472#else
473#define ahc_ha_274_biosctrl_print(regvalue, cur_col, wrap) \
474 ahc_print_register(NULL, 0, "HA_274_BIOSCTRL", 0x5f, regvalue, cur_col, wrap)
475#endif
476
477#if AIC_DEBUG_REGISTERS
478ahc_reg_print_t ahc_seqctl_print;
479#else
480#define ahc_seqctl_print(regvalue, cur_col, wrap) \
481 ahc_print_register(NULL, 0, "SEQCTL", 0x60, regvalue, cur_col, wrap)
482#endif
483
484#if AIC_DEBUG_REGISTERS
485ahc_reg_print_t ahc_seqram_print;
486#else
487#define ahc_seqram_print(regvalue, cur_col, wrap) \
488 ahc_print_register(NULL, 0, "SEQRAM", 0x61, regvalue, cur_col, wrap)
489#endif
490
491#if AIC_DEBUG_REGISTERS
492ahc_reg_print_t ahc_seqaddr0_print;
493#else
494#define ahc_seqaddr0_print(regvalue, cur_col, wrap) \
495 ahc_print_register(NULL, 0, "SEQADDR0", 0x62, regvalue, cur_col, wrap)
496#endif
497
498#if AIC_DEBUG_REGISTERS
499ahc_reg_print_t ahc_seqaddr1_print;
500#else
501#define ahc_seqaddr1_print(regvalue, cur_col, wrap) \
502 ahc_print_register(NULL, 0, "SEQADDR1", 0x63, regvalue, cur_col, wrap)
503#endif
504
505#if AIC_DEBUG_REGISTERS
506ahc_reg_print_t ahc_accum_print;
507#else
508#define ahc_accum_print(regvalue, cur_col, wrap) \
509 ahc_print_register(NULL, 0, "ACCUM", 0x64, regvalue, cur_col, wrap)
510#endif
511
512#if AIC_DEBUG_REGISTERS
513ahc_reg_print_t ahc_sindex_print;
514#else
515#define ahc_sindex_print(regvalue, cur_col, wrap) \
516 ahc_print_register(NULL, 0, "SINDEX", 0x65, regvalue, cur_col, wrap)
517#endif
518
519#if AIC_DEBUG_REGISTERS
520ahc_reg_print_t ahc_dindex_print;
521#else
522#define ahc_dindex_print(regvalue, cur_col, wrap) \
523 ahc_print_register(NULL, 0, "DINDEX", 0x66, regvalue, cur_col, wrap)
524#endif
525
526#if AIC_DEBUG_REGISTERS
527ahc_reg_print_t ahc_allones_print;
528#else
529#define ahc_allones_print(regvalue, cur_col, wrap) \
530 ahc_print_register(NULL, 0, "ALLONES", 0x69, regvalue, cur_col, wrap)
531#endif
532
533#if AIC_DEBUG_REGISTERS
534ahc_reg_print_t ahc_allzeros_print;
535#else
536#define ahc_allzeros_print(regvalue, cur_col, wrap) \
537 ahc_print_register(NULL, 0, "ALLZEROS", 0x6a, regvalue, cur_col, wrap)
538#endif
539
540#if AIC_DEBUG_REGISTERS
541ahc_reg_print_t ahc_none_print;
542#else
543#define ahc_none_print(regvalue, cur_col, wrap) \
544 ahc_print_register(NULL, 0, "NONE", 0x6a, regvalue, cur_col, wrap)
545#endif
546
547#if AIC_DEBUG_REGISTERS
548ahc_reg_print_t ahc_flags_print;
549#else
550#define ahc_flags_print(regvalue, cur_col, wrap) \
551 ahc_print_register(NULL, 0, "FLAGS", 0x6b, regvalue, cur_col, wrap)
552#endif
553
554#if AIC_DEBUG_REGISTERS
555ahc_reg_print_t ahc_sindir_print;
556#else
557#define ahc_sindir_print(regvalue, cur_col, wrap) \
558 ahc_print_register(NULL, 0, "SINDIR", 0x6c, regvalue, cur_col, wrap)
559#endif
560
561#if AIC_DEBUG_REGISTERS
562ahc_reg_print_t ahc_dindir_print;
563#else
564#define ahc_dindir_print(regvalue, cur_col, wrap) \
565 ahc_print_register(NULL, 0, "DINDIR", 0x6d, regvalue, cur_col, wrap)
566#endif
567
568#if AIC_DEBUG_REGISTERS
569ahc_reg_print_t ahc_function1_print;
570#else
571#define ahc_function1_print(regvalue, cur_col, wrap) \
572 ahc_print_register(NULL, 0, "FUNCTION1", 0x6e, regvalue, cur_col, wrap)
573#endif
574
575#if AIC_DEBUG_REGISTERS
576ahc_reg_print_t ahc_stack_print;
577#else
578#define ahc_stack_print(regvalue, cur_col, wrap) \
579 ahc_print_register(NULL, 0, "STACK", 0x6f, regvalue, cur_col, wrap)
580#endif
581
582#if AIC_DEBUG_REGISTERS
583ahc_reg_print_t ahc_targ_offset_print;
584#else
585#define ahc_targ_offset_print(regvalue, cur_col, wrap) \
586 ahc_print_register(NULL, 0, "TARG_OFFSET", 0x70, regvalue, cur_col, wrap)
587#endif
588
589#if AIC_DEBUG_REGISTERS
590ahc_reg_print_t ahc_sram_base_print;
591#else
592#define ahc_sram_base_print(regvalue, cur_col, wrap) \
593 ahc_print_register(NULL, 0, "SRAM_BASE", 0x70, regvalue, cur_col, wrap)
594#endif
595
596#if AIC_DEBUG_REGISTERS
597ahc_reg_print_t ahc_bctl_print;
598#else
599#define ahc_bctl_print(regvalue, cur_col, wrap) \
600 ahc_print_register(NULL, 0, "BCTL", 0x84, regvalue, cur_col, wrap)
601#endif
602
603#if AIC_DEBUG_REGISTERS
604ahc_reg_print_t ahc_dscommand0_print;
605#else
606#define ahc_dscommand0_print(regvalue, cur_col, wrap) \
607 ahc_print_register(NULL, 0, "DSCOMMAND0", 0x84, regvalue, cur_col, wrap)
608#endif
609
610#if AIC_DEBUG_REGISTERS
611ahc_reg_print_t ahc_bustime_print;
612#else
613#define ahc_bustime_print(regvalue, cur_col, wrap) \
614 ahc_print_register(NULL, 0, "BUSTIME", 0x85, regvalue, cur_col, wrap)
615#endif
616
617#if AIC_DEBUG_REGISTERS
618ahc_reg_print_t ahc_dscommand1_print;
619#else
620#define ahc_dscommand1_print(regvalue, cur_col, wrap) \
621 ahc_print_register(NULL, 0, "DSCOMMAND1", 0x85, regvalue, cur_col, wrap)
622#endif
623
624#if AIC_DEBUG_REGISTERS
625ahc_reg_print_t ahc_busspd_print;
626#else
627#define ahc_busspd_print(regvalue, cur_col, wrap) \
628 ahc_print_register(NULL, 0, "BUSSPD", 0x86, regvalue, cur_col, wrap)
629#endif
630
631#if AIC_DEBUG_REGISTERS
632ahc_reg_print_t ahc_hs_mailbox_print;
633#else
634#define ahc_hs_mailbox_print(regvalue, cur_col, wrap) \
635 ahc_print_register(NULL, 0, "HS_MAILBOX", 0x86, regvalue, cur_col, wrap)
636#endif
637
638#if AIC_DEBUG_REGISTERS
639ahc_reg_print_t ahc_dspcistatus_print;
640#else
641#define ahc_dspcistatus_print(regvalue, cur_col, wrap) \
642 ahc_print_register(NULL, 0, "DSPCISTATUS", 0x86, regvalue, cur_col, wrap)
643#endif
644
645#if AIC_DEBUG_REGISTERS
646ahc_reg_print_t ahc_hcntrl_print;
647#else
648#define ahc_hcntrl_print(regvalue, cur_col, wrap) \
649 ahc_print_register(NULL, 0, "HCNTRL", 0x87, regvalue, cur_col, wrap)
650#endif
651
652#if AIC_DEBUG_REGISTERS
653ahc_reg_print_t ahc_haddr_print;
654#else
655#define ahc_haddr_print(regvalue, cur_col, wrap) \
656 ahc_print_register(NULL, 0, "HADDR", 0x88, regvalue, cur_col, wrap)
657#endif
658
659#if AIC_DEBUG_REGISTERS
660ahc_reg_print_t ahc_hcnt_print;
661#else
662#define ahc_hcnt_print(regvalue, cur_col, wrap) \
663 ahc_print_register(NULL, 0, "HCNT", 0x8c, regvalue, cur_col, wrap)
664#endif
665
666#if AIC_DEBUG_REGISTERS
667ahc_reg_print_t ahc_scbptr_print;
668#else
669#define ahc_scbptr_print(regvalue, cur_col, wrap) \
670 ahc_print_register(NULL, 0, "SCBPTR", 0x90, regvalue, cur_col, wrap)
671#endif
672
673#if AIC_DEBUG_REGISTERS
674ahc_reg_print_t ahc_intstat_print;
675#else
676#define ahc_intstat_print(regvalue, cur_col, wrap) \
677 ahc_print_register(NULL, 0, "INTSTAT", 0x91, regvalue, cur_col, wrap)
678#endif
679
680#if AIC_DEBUG_REGISTERS
681ahc_reg_print_t ahc_clrint_print;
682#else
683#define ahc_clrint_print(regvalue, cur_col, wrap) \
684 ahc_print_register(NULL, 0, "CLRINT", 0x92, regvalue, cur_col, wrap)
685#endif
686
687#if AIC_DEBUG_REGISTERS
688ahc_reg_print_t ahc_error_print;
689#else
690#define ahc_error_print(regvalue, cur_col, wrap) \
691 ahc_print_register(NULL, 0, "ERROR", 0x92, regvalue, cur_col, wrap)
692#endif
693
694#if AIC_DEBUG_REGISTERS
695ahc_reg_print_t ahc_dfcntrl_print;
696#else
697#define ahc_dfcntrl_print(regvalue, cur_col, wrap) \
698 ahc_print_register(NULL, 0, "DFCNTRL", 0x93, regvalue, cur_col, wrap)
699#endif
700
701#if AIC_DEBUG_REGISTERS
702ahc_reg_print_t ahc_dfstatus_print;
703#else
704#define ahc_dfstatus_print(regvalue, cur_col, wrap) \
705 ahc_print_register(NULL, 0, "DFSTATUS", 0x94, regvalue, cur_col, wrap)
706#endif
707
708#if AIC_DEBUG_REGISTERS
709ahc_reg_print_t ahc_dfwaddr_print;
710#else
711#define ahc_dfwaddr_print(regvalue, cur_col, wrap) \
712 ahc_print_register(NULL, 0, "DFWADDR", 0x95, regvalue, cur_col, wrap)
713#endif
714
715#if AIC_DEBUG_REGISTERS
716ahc_reg_print_t ahc_dfraddr_print;
717#else
718#define ahc_dfraddr_print(regvalue, cur_col, wrap) \
719 ahc_print_register(NULL, 0, "DFRADDR", 0x97, regvalue, cur_col, wrap)
720#endif
721
722#if AIC_DEBUG_REGISTERS
723ahc_reg_print_t ahc_dfdat_print;
724#else
725#define ahc_dfdat_print(regvalue, cur_col, wrap) \
726 ahc_print_register(NULL, 0, "DFDAT", 0x99, regvalue, cur_col, wrap)
727#endif
728
729#if AIC_DEBUG_REGISTERS
730ahc_reg_print_t ahc_scbcnt_print;
731#else
732#define ahc_scbcnt_print(regvalue, cur_col, wrap) \
733 ahc_print_register(NULL, 0, "SCBCNT", 0x9a, regvalue, cur_col, wrap)
734#endif
735
736#if AIC_DEBUG_REGISTERS
737ahc_reg_print_t ahc_qinfifo_print;
738#else
739#define ahc_qinfifo_print(regvalue, cur_col, wrap) \
740 ahc_print_register(NULL, 0, "QINFIFO", 0x9b, regvalue, cur_col, wrap)
741#endif
742
743#if AIC_DEBUG_REGISTERS
744ahc_reg_print_t ahc_qincnt_print;
745#else
746#define ahc_qincnt_print(regvalue, cur_col, wrap) \
747 ahc_print_register(NULL, 0, "QINCNT", 0x9c, regvalue, cur_col, wrap)
748#endif
749
750#if AIC_DEBUG_REGISTERS
751ahc_reg_print_t ahc_qoutfifo_print;
752#else
753#define ahc_qoutfifo_print(regvalue, cur_col, wrap) \
754 ahc_print_register(NULL, 0, "QOUTFIFO", 0x9d, regvalue, cur_col, wrap)
755#endif
756
757#if AIC_DEBUG_REGISTERS
758ahc_reg_print_t ahc_crccontrol1_print;
759#else
760#define ahc_crccontrol1_print(regvalue, cur_col, wrap) \
761 ahc_print_register(NULL, 0, "CRCCONTROL1", 0x9d, regvalue, cur_col, wrap)
762#endif
763
764#if AIC_DEBUG_REGISTERS
765ahc_reg_print_t ahc_qoutcnt_print;
766#else
767#define ahc_qoutcnt_print(regvalue, cur_col, wrap) \
768 ahc_print_register(NULL, 0, "QOUTCNT", 0x9e, regvalue, cur_col, wrap)
769#endif
770
771#if AIC_DEBUG_REGISTERS
772ahc_reg_print_t ahc_scsiphase_print;
773#else
774#define ahc_scsiphase_print(regvalue, cur_col, wrap) \
775 ahc_print_register(NULL, 0, "SCSIPHASE", 0x9e, regvalue, cur_col, wrap)
776#endif
777
778#if AIC_DEBUG_REGISTERS
779ahc_reg_print_t ahc_sfunct_print;
780#else
781#define ahc_sfunct_print(regvalue, cur_col, wrap) \
782 ahc_print_register(NULL, 0, "SFUNCT", 0x9f, regvalue, cur_col, wrap)
783#endif
784
785#if AIC_DEBUG_REGISTERS
786ahc_reg_print_t ahc_scb_base_print;
787#else
788#define ahc_scb_base_print(regvalue, cur_col, wrap) \
789 ahc_print_register(NULL, 0, "SCB_BASE", 0xa0, regvalue, cur_col, wrap)
790#endif
791
792#if AIC_DEBUG_REGISTERS
793ahc_reg_print_t ahc_scb_cdb_ptr_print;
794#else
795#define ahc_scb_cdb_ptr_print(regvalue, cur_col, wrap) \
796 ahc_print_register(NULL, 0, "SCB_CDB_PTR", 0xa0, regvalue, cur_col, wrap)
797#endif
798
799#if AIC_DEBUG_REGISTERS
800ahc_reg_print_t ahc_scb_residual_sgptr_print;
801#else
802#define ahc_scb_residual_sgptr_print(regvalue, cur_col, wrap) \
803 ahc_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR", 0xa4, regvalue, cur_col, wrap)
804#endif
805
806#if AIC_DEBUG_REGISTERS
807ahc_reg_print_t ahc_scb_scsi_status_print;
808#else
809#define ahc_scb_scsi_status_print(regvalue, cur_col, wrap) \
810 ahc_print_register(NULL, 0, "SCB_SCSI_STATUS", 0xa8, regvalue, cur_col, wrap)
811#endif
812
813#if AIC_DEBUG_REGISTERS
814ahc_reg_print_t ahc_scb_target_phases_print;
815#else
816#define ahc_scb_target_phases_print(regvalue, cur_col, wrap) \
817 ahc_print_register(NULL, 0, "SCB_TARGET_PHASES", 0xa9, regvalue, cur_col, wrap)
818#endif
819
820#if AIC_DEBUG_REGISTERS
821ahc_reg_print_t ahc_scb_target_data_dir_print;
822#else
823#define ahc_scb_target_data_dir_print(regvalue, cur_col, wrap) \
824 ahc_print_register(NULL, 0, "SCB_TARGET_DATA_DIR", 0xaa, regvalue, cur_col, wrap)
825#endif
826
827#if AIC_DEBUG_REGISTERS
828ahc_reg_print_t ahc_scb_target_itag_print;
829#else
830#define ahc_scb_target_itag_print(regvalue, cur_col, wrap) \
831 ahc_print_register(NULL, 0, "SCB_TARGET_ITAG", 0xab, regvalue, cur_col, wrap)
832#endif
833
834#if AIC_DEBUG_REGISTERS
835ahc_reg_print_t ahc_scb_dataptr_print;
836#else
837#define ahc_scb_dataptr_print(regvalue, cur_col, wrap) \
838 ahc_print_register(NULL, 0, "SCB_DATAPTR", 0xac, regvalue, cur_col, wrap)
839#endif
840
841#if AIC_DEBUG_REGISTERS
842ahc_reg_print_t ahc_scb_datacnt_print;
843#else
844#define ahc_scb_datacnt_print(regvalue, cur_col, wrap) \
845 ahc_print_register(NULL, 0, "SCB_DATACNT", 0xb0, regvalue, cur_col, wrap)
846#endif
847
848#if AIC_DEBUG_REGISTERS
849ahc_reg_print_t ahc_scb_sgptr_print;
850#else
851#define ahc_scb_sgptr_print(regvalue, cur_col, wrap) \
852 ahc_print_register(NULL, 0, "SCB_SGPTR", 0xb4, regvalue, cur_col, wrap)
853#endif
854
855#if AIC_DEBUG_REGISTERS
856ahc_reg_print_t ahc_scb_control_print;
857#else
858#define ahc_scb_control_print(regvalue, cur_col, wrap) \
859 ahc_print_register(NULL, 0, "SCB_CONTROL", 0xb8, regvalue, cur_col, wrap)
860#endif
861
862#if AIC_DEBUG_REGISTERS
863ahc_reg_print_t ahc_scb_scsiid_print;
864#else
865#define ahc_scb_scsiid_print(regvalue, cur_col, wrap) \
866 ahc_print_register(NULL, 0, "SCB_SCSIID", 0xb9, regvalue, cur_col, wrap)
867#endif
868
869#if AIC_DEBUG_REGISTERS
870ahc_reg_print_t ahc_scb_lun_print;
871#else
872#define ahc_scb_lun_print(regvalue, cur_col, wrap) \
873 ahc_print_register(NULL, 0, "SCB_LUN", 0xba, regvalue, cur_col, wrap)
874#endif
875
876#if AIC_DEBUG_REGISTERS
877ahc_reg_print_t ahc_scb_tag_print;
878#else
879#define ahc_scb_tag_print(regvalue, cur_col, wrap) \
880 ahc_print_register(NULL, 0, "SCB_TAG", 0xbb, regvalue, cur_col, wrap)
881#endif
882
883#if AIC_DEBUG_REGISTERS
884ahc_reg_print_t ahc_scb_cdb_len_print;
885#else
886#define ahc_scb_cdb_len_print(regvalue, cur_col, wrap) \
887 ahc_print_register(NULL, 0, "SCB_CDB_LEN", 0xbc, regvalue, cur_col, wrap)
888#endif
889
890#if AIC_DEBUG_REGISTERS
891ahc_reg_print_t ahc_scb_scsirate_print;
892#else
893#define ahc_scb_scsirate_print(regvalue, cur_col, wrap) \
894 ahc_print_register(NULL, 0, "SCB_SCSIRATE", 0xbd, regvalue, cur_col, wrap)
895#endif
896
897#if AIC_DEBUG_REGISTERS
898ahc_reg_print_t ahc_scb_scsioffset_print;
899#else
900#define ahc_scb_scsioffset_print(regvalue, cur_col, wrap) \
901 ahc_print_register(NULL, 0, "SCB_SCSIOFFSET", 0xbe, regvalue, cur_col, wrap)
902#endif
903
904#if AIC_DEBUG_REGISTERS
905ahc_reg_print_t ahc_scb_next_print;
906#else
907#define ahc_scb_next_print(regvalue, cur_col, wrap) \
908 ahc_print_register(NULL, 0, "SCB_NEXT", 0xbf, regvalue, cur_col, wrap)
909#endif
910
911#if AIC_DEBUG_REGISTERS
912ahc_reg_print_t ahc_scb_64_spare_print;
913#else
914#define ahc_scb_64_spare_print(regvalue, cur_col, wrap) \
915 ahc_print_register(NULL, 0, "SCB_64_SPARE", 0xc0, regvalue, cur_col, wrap)
916#endif
917
918#if AIC_DEBUG_REGISTERS
919ahc_reg_print_t ahc_seectl_2840_print;
920#else
921#define ahc_seectl_2840_print(regvalue, cur_col, wrap) \
922 ahc_print_register(NULL, 0, "SEECTL_2840", 0xc0, regvalue, cur_col, wrap)
923#endif
924
925#if AIC_DEBUG_REGISTERS
926ahc_reg_print_t ahc_status_2840_print;
927#else
928#define ahc_status_2840_print(regvalue, cur_col, wrap) \
929 ahc_print_register(NULL, 0, "STATUS_2840", 0xc1, regvalue, cur_col, wrap)
930#endif
931
932#if AIC_DEBUG_REGISTERS
933ahc_reg_print_t ahc_scb_64_btt_print;
934#else
935#define ahc_scb_64_btt_print(regvalue, cur_col, wrap) \
936 ahc_print_register(NULL, 0, "SCB_64_BTT", 0xd0, regvalue, cur_col, wrap)
937#endif
938
939#if AIC_DEBUG_REGISTERS
940ahc_reg_print_t ahc_cchaddr_print;
941#else
942#define ahc_cchaddr_print(regvalue, cur_col, wrap) \
943 ahc_print_register(NULL, 0, "CCHADDR", 0xe0, regvalue, cur_col, wrap)
944#endif
945
946#if AIC_DEBUG_REGISTERS
947ahc_reg_print_t ahc_cchcnt_print;
948#else
949#define ahc_cchcnt_print(regvalue, cur_col, wrap) \
950 ahc_print_register(NULL, 0, "CCHCNT", 0xe8, regvalue, cur_col, wrap)
951#endif
952
953#if AIC_DEBUG_REGISTERS
954ahc_reg_print_t ahc_ccsgram_print;
955#else
956#define ahc_ccsgram_print(regvalue, cur_col, wrap) \
957 ahc_print_register(NULL, 0, "CCSGRAM", 0xe9, regvalue, cur_col, wrap)
958#endif
959
960#if AIC_DEBUG_REGISTERS
961ahc_reg_print_t ahc_ccsgaddr_print;
962#else
963#define ahc_ccsgaddr_print(regvalue, cur_col, wrap) \
964 ahc_print_register(NULL, 0, "CCSGADDR", 0xea, regvalue, cur_col, wrap)
965#endif
966
967#if AIC_DEBUG_REGISTERS
968ahc_reg_print_t ahc_ccsgctl_print;
969#else
970#define ahc_ccsgctl_print(regvalue, cur_col, wrap) \
971 ahc_print_register(NULL, 0, "CCSGCTL", 0xeb, regvalue, cur_col, wrap)
972#endif
973
974#if AIC_DEBUG_REGISTERS
975ahc_reg_print_t ahc_ccscbram_print;
976#else
977#define ahc_ccscbram_print(regvalue, cur_col, wrap) \
978 ahc_print_register(NULL, 0, "CCSCBRAM", 0xec, regvalue, cur_col, wrap)
979#endif
980
981#if AIC_DEBUG_REGISTERS
982ahc_reg_print_t ahc_ccscbaddr_print;
983#else
984#define ahc_ccscbaddr_print(regvalue, cur_col, wrap) \
985 ahc_print_register(NULL, 0, "CCSCBADDR", 0xed, regvalue, cur_col, wrap)
986#endif
987
988#if AIC_DEBUG_REGISTERS
989ahc_reg_print_t ahc_ccscbctl_print;
990#else
991#define ahc_ccscbctl_print(regvalue, cur_col, wrap) \
992 ahc_print_register(NULL, 0, "CCSCBCTL", 0xee, regvalue, cur_col, wrap)
993#endif
994
995#if AIC_DEBUG_REGISTERS
996ahc_reg_print_t ahc_ccscbcnt_print;
997#else
998#define ahc_ccscbcnt_print(regvalue, cur_col, wrap) \
999 ahc_print_register(NULL, 0, "CCSCBCNT", 0xef, regvalue, cur_col, wrap)
1000#endif
1001
1002#if AIC_DEBUG_REGISTERS
1003ahc_reg_print_t ahc_scbbaddr_print;
1004#else
1005#define ahc_scbbaddr_print(regvalue, cur_col, wrap) \
1006 ahc_print_register(NULL, 0, "SCBBADDR", 0xf0, regvalue, cur_col, wrap)
1007#endif
1008
1009#if AIC_DEBUG_REGISTERS
1010ahc_reg_print_t ahc_ccscbptr_print;
1011#else
1012#define ahc_ccscbptr_print(regvalue, cur_col, wrap) \
1013 ahc_print_register(NULL, 0, "CCSCBPTR", 0xf1, regvalue, cur_col, wrap)
1014#endif
1015
1016#if AIC_DEBUG_REGISTERS
1017ahc_reg_print_t ahc_hnscb_qoff_print;
1018#else
1019#define ahc_hnscb_qoff_print(regvalue, cur_col, wrap) \
1020 ahc_print_register(NULL, 0, "HNSCB_QOFF", 0xf4, regvalue, cur_col, wrap)
1021#endif
1022
1023#if AIC_DEBUG_REGISTERS
1024ahc_reg_print_t ahc_snscb_qoff_print;
1025#else
1026#define ahc_snscb_qoff_print(regvalue, cur_col, wrap) \
1027 ahc_print_register(NULL, 0, "SNSCB_QOFF", 0xf6, regvalue, cur_col, wrap)
1028#endif
1029
1030#if AIC_DEBUG_REGISTERS
1031ahc_reg_print_t ahc_sdscb_qoff_print;
1032#else
1033#define ahc_sdscb_qoff_print(regvalue, cur_col, wrap) \
1034 ahc_print_register(NULL, 0, "SDSCB_QOFF", 0xf8, regvalue, cur_col, wrap)
1035#endif
1036
1037#if AIC_DEBUG_REGISTERS
1038ahc_reg_print_t ahc_qoff_ctlsta_print;
1039#else
1040#define ahc_qoff_ctlsta_print(regvalue, cur_col, wrap) \
1041 ahc_print_register(NULL, 0, "QOFF_CTLSTA", 0xfa, regvalue, cur_col, wrap)
1042#endif
1043
1044#if AIC_DEBUG_REGISTERS
1045ahc_reg_print_t ahc_dff_thrsh_print;
1046#else
1047#define ahc_dff_thrsh_print(regvalue, cur_col, wrap) \
1048 ahc_print_register(NULL, 0, "DFF_THRSH", 0xfb, regvalue, cur_col, wrap)
1049#endif
1050
1051#if AIC_DEBUG_REGISTERS
1052ahc_reg_print_t ahc_sg_cache_shadow_print;
1053#else
1054#define ahc_sg_cache_shadow_print(regvalue, cur_col, wrap) \
1055 ahc_print_register(NULL, 0, "SG_CACHE_SHADOW", 0xfc, regvalue, cur_col, wrap)
1056#endif
1057
1058#if AIC_DEBUG_REGISTERS
1059ahc_reg_print_t ahc_sg_cache_pre_print;
1060#else
1061#define ahc_sg_cache_pre_print(regvalue, cur_col, wrap) \
1062 ahc_print_register(NULL, 0, "SG_CACHE_PRE", 0xfc, regvalue, cur_col, wrap)
1063#endif
1064
1065
1066#define SCSISEQ 0x00
1067#define TEMODE 0x80
1068#define SCSIRSTO 0x01
1069
1070#define SXFRCTL0 0x01
1071#define DFON 0x80
1072#define DFPEXP 0x40
1073#define FAST20 0x20
1074#define CLRSTCNT 0x10
1075#define SPIOEN 0x08
1076#define SCAMEN 0x04
1077#define CLRCHN 0x02
1078
1079#define SXFRCTL1 0x02
1080#define STIMESEL 0x18
1081#define BITBUCKET 0x80
1082#define SWRAPEN 0x40
1083#define ENSTIMER 0x04
1084#define ACTNEGEN 0x02
1085#define STPWEN 0x01
1086
1087#define SCSISIGO 0x03
1088#define CDO 0x80
1089#define IOO 0x40
1090#define MSGO 0x20
1091#define ATNO 0x10
1092#define SELO 0x08
1093#define BSYO 0x04
1094#define REQO 0x02
1095#define ACKO 0x01
1096
1097#define SCSISIGI 0x03
1098#define P_DATAIN_DT 0x60
1099#define P_DATAOUT_DT 0x20
1100#define ATNI 0x10
1101#define SELI 0x08
1102#define BSYI 0x04
1103#define REQI 0x02
1104#define ACKI 0x01
1105
1106#define SCSIRATE 0x04
1107#define SXFR 0x70
1108#define SOFS 0x0f
1109#define SXFR_ULTRA2 0x0f
1110#define WIDEXFER 0x80
1111#define ENABLE_CRC 0x40
1112#define SINGLE_EDGE 0x10
1113
1114#define SCSIID 0x05
1115#define SCSIOFFSET 0x05
1116#define SOFS_ULTRA2 0x7f
1117
1118#define SCSIDATL 0x06
1119
1120#define SCSIDATH 0x07
1121
1122#define STCNT 0x08
1123
1124#define OPTIONMODE 0x08
1125#define OPTIONMODE_DEFAULTS 0x03
1126#define AUTORATEEN 0x80
1127#define AUTOACKEN 0x40
1128#define ATNMGMNTEN 0x20
1129#define BUSFREEREV 0x10
1130#define EXPPHASEDIS 0x08
1131#define SCSIDATL_IMGEN 0x04
1132#define AUTO_MSGOUT_DE 0x02
1133#define DIS_MSGIN_DUALEDGE 0x01
1134
1135#define TARGCRCCNT 0x0a
1136
1137#define CLRSINT0 0x0b
1138#define CLRSELDO 0x40
1139#define CLRSELDI 0x20
1140#define CLRSELINGO 0x10
1141#define CLRIOERR 0x08
1142#define CLRSWRAP 0x08
1143#define CLRSPIORDY 0x02
1144
1145#define SSTAT0 0x0b
1146#define TARGET 0x80
1147#define SELDO 0x40
1148#define SELDI 0x20
1149#define SELINGO 0x10
1150#define SWRAP 0x08
1151#define IOERR 0x08
1152#define SDONE 0x04
1153#define SPIORDY 0x02
1154#define DMADONE 0x01
1155
1156#define CLRSINT1 0x0c
1157#define CLRSELTIMEO 0x80
1158#define CLRATNO 0x40
1159#define CLRSCSIRSTI 0x20
1160#define CLRBUSFREE 0x08
1161#define CLRSCSIPERR 0x04
1162#define CLRPHASECHG 0x02
1163#define CLRREQINIT 0x01
1164
1165#define SSTAT1 0x0c
1166#define SELTO 0x80
1167#define ATNTARG 0x40
1168#define SCSIRSTI 0x20
1169#define PHASEMIS 0x10
1170#define BUSFREE 0x08
1171#define SCSIPERR 0x04
1172#define PHASECHG 0x02
1173#define REQINIT 0x01
1174
1175#define SSTAT2 0x0d
1176#define SFCNT 0x1f
1177#define OVERRUN 0x80
1178#define SHVALID 0x40
1179#define EXP_ACTIVE 0x10
1180#define CRCVALERR 0x08
1181#define CRCENDERR 0x04
1182#define CRCREQERR 0x02
1183#define DUAL_EDGE_ERR 0x01
1184
1185#define SSTAT3 0x0e
1186#define SCSICNT 0xf0
1187#define U2OFFCNT 0x7f
1188#define OFFCNT 0x0f
1189
1190#define SCSIID_ULTRA2 0x0f
1191
1192#define SIMODE0 0x10
1193#define ENSELDO 0x40
1194#define ENSELDI 0x20
1195#define ENSELINGO 0x10
1196#define ENIOERR 0x08
1197#define ENSWRAP 0x08
1198#define ENSDONE 0x04
1199#define ENSPIORDY 0x02
1200#define ENDMADONE 0x01
1201
1202#define SIMODE1 0x11
1203#define ENSELTIMO 0x80
1204#define ENATNTARG 0x40
1205#define ENSCSIRST 0x20
1206#define ENPHASEMIS 0x10
1207#define ENBUSFREE 0x08
1208#define ENSCSIPERR 0x04
1209#define ENPHASECHG 0x02
1210#define ENREQINIT 0x01
1211
1212#define SCSIBUSL 0x12
1213
1214#define SCSIBUSH 0x13
1215
1216#define SXFRCTL2 0x13
1217#define ASYNC_SETUP 0x07
1218#define AUTORSTDIS 0x10
1219#define CMDDMAEN 0x08
1220
1221#define SHADDR 0x14
1222
1223#define SELTIMER 0x18
1224#define TARGIDIN 0x18
1225#define STAGE6 0x20
1226#define STAGE5 0x10
1227#define STAGE4 0x08
1228#define STAGE3 0x04
1229#define STAGE2 0x02
1230#define STAGE1 0x01
1231
1232#define SELID 0x19
1233#define SELID_MASK 0xf0
1234#define ONEBIT 0x08
1235
1236#define SCAMCTL 0x1a
1237#define SCAMLVL 0x03
1238#define ENSCAMSELO 0x80
1239#define CLRSCAMSELID 0x40
1240#define ALTSTIM 0x20
1241#define DFLTTID 0x10
1242
1243#define TARGID 0x1b
1244
1245#define SPIOCAP 0x1b
1246#define SOFT1 0x80
1247#define SOFT0 0x40
1248#define SOFTCMDEN 0x20
1249#define EXT_BRDCTL 0x10
1250#define SEEPROM 0x08
1251#define EEPROM 0x04
1252#define ROM 0x02
1253#define SSPIOCPS 0x01
1254
1255#define BRDCTL 0x1d
1256#define BRDDAT7 0x80
1257#define BRDDAT6 0x40
1258#define BRDDAT5 0x20
1259#define BRDDAT4 0x10
1260#define BRDSTB 0x10
1261#define BRDDAT3 0x08
1262#define BRDCS 0x08
1263#define BRDDAT2 0x04
1264#define BRDRW 0x04
1265#define BRDRW_ULTRA2 0x02
1266#define BRDCTL1 0x02
1267#define BRDCTL0 0x01
1268#define BRDSTB_ULTRA2 0x01
1269
1270#define SEECTL 0x1e
1271#define EXTARBACK 0x80
1272#define EXTARBREQ 0x40
1273#define SEEMS 0x20
1274#define SEERDY 0x10
1275#define SEECS 0x08
1276#define SEECK 0x04
1277#define SEEDO 0x02
1278#define SEEDI 0x01
1279
1280#define SBLKCTL 0x1f
1281#define DIAGLEDEN 0x80
1282#define DIAGLEDON 0x40
1283#define AUTOFLUSHDIS 0x20
1284#define ENAB40 0x08
1285#define SELBUSB 0x08
1286#define ENAB20 0x04
1287#define SELWIDE 0x02
1288#define XCVR 0x01
1289
1290#define BUSY_TARGETS 0x20
1291#define TARG_SCSIRATE 0x20
1292
1293#define ULTRA_ENB 0x30
1294#define CMDSIZE_TABLE 0x30
1295
1296#define DISC_DSB 0x32
1297
1298#define CMDSIZE_TABLE_TAIL 0x34
1299
1300#define MWI_RESIDUAL 0x38
1301#define TARG_IMMEDIATE_SCB 0x38
1302
1303#define NEXT_QUEUED_SCB 0x39
1304
1305#define MSG_OUT 0x3a
1306
1307#define DMAPARAMS 0x3b
1308#define PRELOADEN 0x80
1309#define WIDEODD 0x40
1310#define SCSIEN 0x20
1311#define SDMAEN 0x10
1312#define SDMAENACK 0x10
1313#define HDMAEN 0x08
1314#define HDMAENACK 0x08
1315#define DIRECTION 0x04
1316#define FIFOFLUSH 0x02
1317#define FIFORESET 0x01
1318
1319#define SEQ_FLAGS 0x3c
1320#define NOT_IDENTIFIED 0x80
1321#define NO_CDB_SENT 0x40
1322#define TARGET_CMD_IS_TAGGED 0x40
1323#define DPHASE 0x20
1324#define TARG_CMD_PENDING 0x10
1325#define CMDPHASE_PENDING 0x08
1326#define DPHASE_PENDING 0x04
1327#define SPHASE_PENDING 0x02
1328#define NO_DISCONNECT 0x01
1329
1330#define SAVED_SCSIID 0x3d
1331
1332#define SAVED_LUN 0x3e
1333
1334#define LASTPHASE 0x3f
1335#define P_MESGIN 0xe0
1336#define PHASE_MASK 0xe0
1337#define P_STATUS 0xc0
1338#define P_MESGOUT 0xa0
1339#define P_COMMAND 0x80
1340#define P_DATAIN 0x40
1341#define P_BUSFREE 0x01
1342#define P_DATAOUT 0x00
1343#define CDI 0x80
1344#define IOI 0x40
1345#define MSGI 0x20
1346
1347#define WAITING_SCBH 0x40
1348
1349#define DISCONNECTED_SCBH 0x41
1350
1351#define FREE_SCBH 0x42
1352
1353#define COMPLETE_SCBH 0x43
1354
1355#define HSCB_ADDR 0x44
1356
1357#define SHARED_DATA_ADDR 0x48
1358
1359#define KERNEL_QINPOS 0x4c
1360
1361#define QINPOS 0x4d
1362
1363#define QOUTPOS 0x4e
1364
1365#define KERNEL_TQINPOS 0x4f
1366
1367#define TQINPOS 0x50
1368
1369#define ARG_1 0x51
1370#define RETURN_1 0x51
1371#define SEND_MSG 0x80
1372#define SEND_SENSE 0x40
1373#define SEND_REJ 0x20
1374#define MSGOUT_PHASEMIS 0x10
1375#define EXIT_MSG_LOOP 0x08
1376#define CONT_MSG_LOOP 0x04
1377#define CONT_TARG_SESSION 0x02
1378
1379#define ARG_2 0x52
1380#define RETURN_2 0x52
1381
1382#define LAST_MSG 0x53
1383
1384#define SCSISEQ_TEMPLATE 0x54
1385#define ENSELO 0x40
1386#define ENSELI 0x20
1387#define ENRSELI 0x10
1388#define ENAUTOATNO 0x08
1389#define ENAUTOATNI 0x04
1390#define ENAUTOATNP 0x02
1391
1392#define HA_274_BIOSGLOBAL 0x56
1393#define INITIATOR_TAG 0x56
1394#define HA_274_EXTENDED_TRANS 0x01
1395
1396#define SEQ_FLAGS2 0x57
1397#define TARGET_MSG_PENDING 0x02
1398#define SCB_DMA 0x01
1399
1400#define SCSICONF 0x5a
1401#define HWSCSIID 0x0f
1402#define HSCSIID 0x07
1403#define TERM_ENB 0x80
1404#define RESET_SCSI 0x40
1405#define ENSPCHK 0x20
1406
1407#define INTDEF 0x5c
1408#define VECTOR 0x0f
1409#define EDGE_TRIG 0x80
1410
1411#define HOSTCONF 0x5d
1412
1413#define HA_274_BIOSCTRL 0x5f
1414#define BIOSDISABLED 0x30
1415#define BIOSMODE 0x30
1416#define CHANNEL_B_PRIMARY 0x08
1417
1418#define SEQCTL 0x60
1419#define PERRORDIS 0x80
1420#define PAUSEDIS 0x40
1421#define FAILDIS 0x20
1422#define FASTMODE 0x10
1423#define BRKADRINTEN 0x08
1424#define STEP 0x04
1425#define SEQRESET 0x02
1426#define LOADRAM 0x01
1427
1428#define SEQRAM 0x61
1429
1430#define SEQADDR0 0x62
1431
1432#define SEQADDR1 0x63
1433#define SEQADDR1_MASK 0x01
1434
1435#define ACCUM 0x64
1436
1437#define SINDEX 0x65
1438
1439#define DINDEX 0x66
1440
1441#define ALLONES 0x69
1442
1443#define ALLZEROS 0x6a
1444
1445#define NONE 0x6a
1446
1447#define FLAGS 0x6b
1448#define ZERO 0x02
1449#define CARRY 0x01
1450
1451#define SINDIR 0x6c
1452
1453#define DINDIR 0x6d
1454
1455#define FUNCTION1 0x6e
1456
1457#define STACK 0x6f
1458
1459#define TARG_OFFSET 0x70
1460
1461#define SRAM_BASE 0x70
1462
1463#define BCTL 0x84
1464#define ACE 0x08
1465#define ENABLE 0x01
1466
1467#define DSCOMMAND0 0x84
1468#define CACHETHEN 0x80
1469#define DPARCKEN 0x40
1470#define MPARCKEN 0x20
1471#define EXTREQLCK 0x10
1472#define INTSCBRAMSEL 0x08
1473#define RAMPS 0x04
1474#define USCBSIZE32 0x02
1475#define CIOPARCKEN 0x01
1476
1477#define BUSTIME 0x85
1478#define BOFF 0xf0
1479#define BON 0x0f
1480
1481#define DSCOMMAND1 0x85
1482#define DSLATT 0xfc
1483#define HADDLDSEL1 0x02
1484#define HADDLDSEL0 0x01
1485
1486#define BUSSPD 0x86
1487#define DFTHRSH 0xc0
1488#define DFTHRSH_75 0x80
1489#define STBOFF 0x38
1490#define STBON 0x07
1491
1492#define HS_MAILBOX 0x86
1493#define HOST_MAILBOX 0xf0
1494#define HOST_TQINPOS 0x80
1495#define SEQ_MAILBOX 0x0f
1496
1497#define DSPCISTATUS 0x86
1498#define DFTHRSH_100 0xc0
1499
1500#define HCNTRL 0x87
1501#define POWRDN 0x40
1502#define SWINT 0x10
1503#define IRQMS 0x08
1504#define PAUSE 0x04
1505#define INTEN 0x02
1506#define CHIPRST 0x01
1507#define CHIPRSTACK 0x01
1508
1509#define HADDR 0x88
1510
1511#define HCNT 0x8c
1512
1513#define SCBPTR 0x90
1514
1515#define INTSTAT 0x91
1516#define SEQINT_MASK 0xf1
1517#define OUT_OF_RANGE 0xe1
1518#define NO_FREE_SCB 0xd1
1519#define SCB_MISMATCH 0xc1
1520#define MISSED_BUSFREE 0xb1
1521#define MKMSG_FAILED 0xa1
1522#define DATA_OVERRUN 0x91
1523#define PERR_DETECTED 0x81
1524#define BAD_STATUS 0x71
1525#define HOST_MSG_LOOP 0x61
1526#define PDATA_REINIT 0x51
1527#define IGN_WIDE_RES 0x41
1528#define NO_MATCH 0x31
1529#define PROTO_VIOLATION 0x21
1530#define SEND_REJECT 0x11
1531#define INT_PEND 0x0f
1532#define BAD_PHASE 0x01
1533#define BRKADRINT 0x08
1534#define SCSIINT 0x04
1535#define CMDCMPLT 0x02
1536#define SEQINT 0x01
1537
1538#define CLRINT 0x92
1539#define CLRPARERR 0x10
1540#define CLRBRKADRINT 0x08
1541#define CLRSCSIINT 0x04
1542#define CLRCMDINT 0x02
1543#define CLRSEQINT 0x01
1544
1545#define ERROR 0x92
1546#define CIOPARERR 0x80
1547#define PCIERRSTAT 0x40
1548#define MPARERR 0x20
1549#define DPARERR 0x10
1550#define SQPARERR 0x08
1551#define ILLOPCODE 0x04
1552#define ILLSADDR 0x02
1553#define ILLHADDR 0x01
1554
1555#define DFCNTRL 0x93
1556
1557#define DFSTATUS 0x94
1558#define PRELOAD_AVAIL 0x80
1559#define DFCACHETH 0x40
1560#define FIFOQWDEMP 0x20
1561#define MREQPEND 0x10
1562#define HDONE 0x08
1563#define DFTHRESH 0x04
1564#define FIFOFULL 0x02
1565#define FIFOEMP 0x01
1566
1567#define DFWADDR 0x95
1568
1569#define DFRADDR 0x97
1570
1571#define DFDAT 0x99
1572
1573#define SCBCNT 0x9a
1574#define SCBCNT_MASK 0x1f
1575#define SCBAUTO 0x80
1576
1577#define QINFIFO 0x9b
1578
1579#define QINCNT 0x9c
1580
1581#define QOUTFIFO 0x9d
1582
1583#define CRCCONTROL1 0x9d
1584#define CRCONSEEN 0x80
1585#define CRCVALCHKEN 0x40
1586#define CRCENDCHKEN 0x20
1587#define CRCREQCHKEN 0x10
1588#define TARGCRCENDEN 0x08
1589#define TARGCRCCNTEN 0x04
1590
1591#define QOUTCNT 0x9e
1592
1593#define SCSIPHASE 0x9e
1594#define DATA_PHASE_MASK 0x03
1595#define STATUS_PHASE 0x20
1596#define COMMAND_PHASE 0x10
1597#define MSG_IN_PHASE 0x08
1598#define MSG_OUT_PHASE 0x04
1599#define DATA_IN_PHASE 0x02
1600#define DATA_OUT_PHASE 0x01
1601
1602#define SFUNCT 0x9f
1603#define ALT_MODE 0x80
1604
1605#define SCB_BASE 0xa0
1606
1607#define SCB_CDB_PTR 0xa0
1608#define SCB_RESIDUAL_DATACNT 0xa0
1609#define SCB_CDB_STORE 0xa0
1610
1611#define SCB_RESIDUAL_SGPTR 0xa4
1612
1613#define SCB_SCSI_STATUS 0xa8
1614
1615#define SCB_TARGET_PHASES 0xa9
1616
1617#define SCB_TARGET_DATA_DIR 0xaa
1618
1619#define SCB_TARGET_ITAG 0xab
1620
1621#define SCB_DATAPTR 0xac
1622
1623#define SCB_DATACNT 0xb0
1624#define SG_HIGH_ADDR_BITS 0x7f
1625#define SG_LAST_SEG 0x80
1626
1627#define SCB_SGPTR 0xb4
1628#define SG_RESID_VALID 0x04
1629#define SG_FULL_RESID 0x02
1630#define SG_LIST_NULL 0x01
1631
1632#define SCB_CONTROL 0xb8
1633#define SCB_TAG_TYPE 0x03
1634#define STATUS_RCVD 0x80
1635#define TARGET_SCB 0x80
1636#define DISCENB 0x40
1637#define TAG_ENB 0x20
1638#define MK_MESSAGE 0x10
1639#define ULTRAENB 0x08
1640#define DISCONNECTED 0x04
1641
1642#define SCB_SCSIID 0xb9
1643#define TID 0xf0
1644#define TWIN_TID 0x70
1645#define OID 0x0f
1646#define TWIN_CHNLB 0x80
1647
1648#define SCB_LUN 0xba
1649#define LID 0x3f
1650#define SCB_XFERLEN_ODD 0x80
1651
1652#define SCB_TAG 0xbb
1653
1654#define SCB_CDB_LEN 0xbc
1655
1656#define SCB_SCSIRATE 0xbd
1657
1658#define SCB_SCSIOFFSET 0xbe
1659
1660#define SCB_NEXT 0xbf
1661
1662#define SCB_64_SPARE 0xc0
1663
1664#define SEECTL_2840 0xc0
1665#define CS_2840 0x04
1666#define CK_2840 0x02
1667#define DO_2840 0x01
1668
1669#define STATUS_2840 0xc1
1670#define BIOS_SEL 0x60
1671#define ADSEL 0x1e
1672#define EEPROM_TF 0x80
1673#define DI_2840 0x01
1674
1675#define SCB_64_BTT 0xd0
1676
1677#define CCHADDR 0xe0
1678
1679#define CCHCNT 0xe8
1680
1681#define CCSGRAM 0xe9
1682
1683#define CCSGADDR 0xea
1684
1685#define CCSGCTL 0xeb
1686#define CCSGDONE 0x80
1687#define CCSGEN 0x08
1688#define SG_FETCH_NEEDED 0x02
1689#define CCSGRESET 0x01
1690
1691#define CCSCBRAM 0xec
1692
1693#define CCSCBADDR 0xed
1694
1695#define CCSCBCTL 0xee
1696#define CCSCBDONE 0x80
1697#define ARRDONE 0x40
1698#define CCARREN 0x10
1699#define CCSCBEN 0x08
1700#define CCSCBDIR 0x04
1701#define CCSCBRESET 0x01
1702
1703#define CCSCBCNT 0xef
1704
1705#define SCBBADDR 0xf0
1706
1707#define CCSCBPTR 0xf1
1708
1709#define HNSCB_QOFF 0xf4
1710
1711#define SNSCB_QOFF 0xf6
1712
1713#define SDSCB_QOFF 0xf8
1714
1715#define QOFF_CTLSTA 0xfa
1716#define SCB_QSIZE 0x07
1717#define SCB_QSIZE_256 0x06
1718#define SCB_AVAIL 0x40
1719#define SNSCB_ROLLOVER 0x20
1720#define SDSCB_ROLLOVER 0x10
1721
1722#define DFF_THRSH 0xfb
1723#define WR_DFTHRSH 0x70
1724#define WR_DFTHRSH_MAX 0x70
1725#define WR_DFTHRSH_90 0x60
1726#define WR_DFTHRSH_85 0x50
1727#define WR_DFTHRSH_75 0x40
1728#define WR_DFTHRSH_63 0x30
1729#define WR_DFTHRSH_50 0x20
1730#define WR_DFTHRSH_25 0x10
1731#define RD_DFTHRSH 0x07
1732#define RD_DFTHRSH_MAX 0x07
1733#define RD_DFTHRSH_90 0x06
1734#define RD_DFTHRSH_85 0x05
1735#define RD_DFTHRSH_75 0x04
1736#define RD_DFTHRSH_63 0x03
1737#define RD_DFTHRSH_50 0x02
1738#define RD_DFTHRSH_25 0x01
1739#define RD_DFTHRSH_MIN 0x00
1740#define WR_DFTHRSH_MIN 0x00
1741
1742#define SG_CACHE_SHADOW 0xfc
1743#define SG_ADDR_MASK 0xf8
1744#define LAST_SEG 0x02
1745#define LAST_SEG_DONE 0x01
1746
1747#define SG_CACHE_PRE 0xfc
1748
1749
1750#define MAX_OFFSET_ULTRA2 0x7f
1751#define MAX_OFFSET_16BIT 0x08
1752#define BUS_8_BIT 0x00
1753#define TARGET_CMD_CMPLT 0xfe
1754#define STATUS_QUEUE_FULL 0x28
1755#define STATUS_BUSY 0x08
1756#define MAX_OFFSET_8BIT 0x0f
1757#define BUS_32_BIT 0x02
1758#define CCSGADDR_MAX 0x80
1759#define TID_SHIFT 0x04
1760#define SCB_DOWNLOAD_SIZE_64 0x30
1761#define HOST_MAILBOX_SHIFT 0x04
1762#define CMD_GROUP_CODE_SHIFT 0x05
1763#define CCSGRAM_MAXSEGS 0x10
1764#define SCB_LIST_NULL 0xff
1765#define SG_SIZEOF 0x08
1766#define SCB_DOWNLOAD_SIZE 0x20
1767#define SEQ_MAILBOX_SHIFT 0x00
1768#define TARGET_DATA_IN 0x01
1769#define HOST_MSG 0xff
1770#define MAX_OFFSET 0x7f
1771#define BUS_16_BIT 0x01
1772#define SCB_UPLOAD_SIZE 0x20
1773#define STACK_SIZE 0x04
1774
1775
1776/* Downloaded Constant Definitions */
1777#define INVERTED_CACHESIZE_MASK 0x03
1778#define SG_PREFETCH_ADDR_MASK 0x06
1779#define SG_PREFETCH_ALIGN_MASK 0x05
1780#define QOUTFIFO_OFFSET 0x00
1781#define SG_PREFETCH_CNT 0x04
1782#define CACHESIZE_MASK 0x02
1783#define QINFIFO_OFFSET 0x01
1784#define DOWNLOAD_CONST_COUNT 0x07
1785
1786
1787/* Exported Labels */
diff --git a/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped b/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped
new file mode 100644
index 000000000000..9c713775d44a
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped
@@ -0,0 +1,1681 @@
1/*
2 * DO NOT EDIT - This file is automatically generated
3 * from the following source files:
4 *
5 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
6 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
7 */
8
9#include "aic7xxx_osm.h"
10
11static ahc_reg_parse_entry_t SCSISEQ_parse_table[] = {
12 { "SCSIRSTO", 0x01, 0x01 },
13 { "ENAUTOATNP", 0x02, 0x02 },
14 { "ENAUTOATNI", 0x04, 0x04 },
15 { "ENAUTOATNO", 0x08, 0x08 },
16 { "ENRSELI", 0x10, 0x10 },
17 { "ENSELI", 0x20, 0x20 },
18 { "ENSELO", 0x40, 0x40 },
19 { "TEMODE", 0x80, 0x80 }
20};
21
22int
23ahc_scsiseq_print(u_int regvalue, u_int *cur_col, u_int wrap)
24{
25 return (ahc_print_register(SCSISEQ_parse_table, 8, "SCSISEQ",
26 0x00, regvalue, cur_col, wrap));
27}
28
29static ahc_reg_parse_entry_t SXFRCTL0_parse_table[] = {
30 { "CLRCHN", 0x02, 0x02 },
31 { "SCAMEN", 0x04, 0x04 },
32 { "SPIOEN", 0x08, 0x08 },
33 { "CLRSTCNT", 0x10, 0x10 },
34 { "FAST20", 0x20, 0x20 },
35 { "DFPEXP", 0x40, 0x40 },
36 { "DFON", 0x80, 0x80 }
37};
38
39int
40ahc_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
41{
42 return (ahc_print_register(SXFRCTL0_parse_table, 7, "SXFRCTL0",
43 0x01, regvalue, cur_col, wrap));
44}
45
46static ahc_reg_parse_entry_t SXFRCTL1_parse_table[] = {
47 { "STPWEN", 0x01, 0x01 },
48 { "ACTNEGEN", 0x02, 0x02 },
49 { "ENSTIMER", 0x04, 0x04 },
50 { "ENSPCHK", 0x20, 0x20 },
51 { "SWRAPEN", 0x40, 0x40 },
52 { "BITBUCKET", 0x80, 0x80 },
53 { "STIMESEL", 0x18, 0x18 }
54};
55
56int
57ahc_sxfrctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
58{
59 return (ahc_print_register(SXFRCTL1_parse_table, 7, "SXFRCTL1",
60 0x02, regvalue, cur_col, wrap));
61}
62
63static ahc_reg_parse_entry_t SCSISIGO_parse_table[] = {
64 { "ACKO", 0x01, 0x01 },
65 { "REQO", 0x02, 0x02 },
66 { "BSYO", 0x04, 0x04 },
67 { "SELO", 0x08, 0x08 },
68 { "ATNO", 0x10, 0x10 },
69 { "MSGO", 0x20, 0x20 },
70 { "IOO", 0x40, 0x40 },
71 { "CDO", 0x80, 0x80 },
72 { "P_DATAOUT", 0x00, 0x00 },
73 { "P_DATAIN", 0x40, 0x40 },
74 { "P_COMMAND", 0x80, 0x80 },
75 { "P_MESGOUT", 0xa0, 0xa0 },
76 { "P_STATUS", 0xc0, 0xc0 },
77 { "PHASE_MASK", 0xe0, 0xe0 },
78 { "P_MESGIN", 0xe0, 0xe0 }
79};
80
81int
82ahc_scsisigo_print(u_int regvalue, u_int *cur_col, u_int wrap)
83{
84 return (ahc_print_register(SCSISIGO_parse_table, 15, "SCSISIGO",
85 0x03, regvalue, cur_col, wrap));
86}
87
88static ahc_reg_parse_entry_t SCSISIGI_parse_table[] = {
89 { "ACKI", 0x01, 0x01 },
90 { "REQI", 0x02, 0x02 },
91 { "BSYI", 0x04, 0x04 },
92 { "SELI", 0x08, 0x08 },
93 { "ATNI", 0x10, 0x10 },
94 { "MSGI", 0x20, 0x20 },
95 { "IOI", 0x40, 0x40 },
96 { "CDI", 0x80, 0x80 },
97 { "P_DATAOUT", 0x00, 0x00 },
98 { "P_DATAOUT_DT", 0x20, 0x20 },
99 { "P_DATAIN", 0x40, 0x40 },
100 { "P_DATAIN_DT", 0x60, 0x60 },
101 { "P_COMMAND", 0x80, 0x80 },
102 { "P_MESGOUT", 0xa0, 0xa0 },
103 { "P_STATUS", 0xc0, 0xc0 },
104 { "PHASE_MASK", 0xe0, 0xe0 },
105 { "P_MESGIN", 0xe0, 0xe0 }
106};
107
108int
109ahc_scsisigi_print(u_int regvalue, u_int *cur_col, u_int wrap)
110{
111 return (ahc_print_register(SCSISIGI_parse_table, 17, "SCSISIGI",
112 0x03, regvalue, cur_col, wrap));
113}
114
115static ahc_reg_parse_entry_t SCSIRATE_parse_table[] = {
116 { "SINGLE_EDGE", 0x10, 0x10 },
117 { "ENABLE_CRC", 0x40, 0x40 },
118 { "WIDEXFER", 0x80, 0x80 },
119 { "SXFR_ULTRA2", 0x0f, 0x0f },
120 { "SOFS", 0x0f, 0x0f },
121 { "SXFR", 0x70, 0x70 }
122};
123
124int
125ahc_scsirate_print(u_int regvalue, u_int *cur_col, u_int wrap)
126{
127 return (ahc_print_register(SCSIRATE_parse_table, 6, "SCSIRATE",
128 0x04, regvalue, cur_col, wrap));
129}
130
131static ahc_reg_parse_entry_t SCSIID_parse_table[] = {
132 { "TWIN_CHNLB", 0x80, 0x80 },
133 { "OID", 0x0f, 0x0f },
134 { "TWIN_TID", 0x70, 0x70 },
135 { "SOFS_ULTRA2", 0x7f, 0x7f },
136 { "TID", 0xf0, 0xf0 }
137};
138
139int
140ahc_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
141{
142 return (ahc_print_register(SCSIID_parse_table, 5, "SCSIID",
143 0x05, regvalue, cur_col, wrap));
144}
145
146int
147ahc_scsidatl_print(u_int regvalue, u_int *cur_col, u_int wrap)
148{
149 return (ahc_print_register(NULL, 0, "SCSIDATL",
150 0x06, regvalue, cur_col, wrap));
151}
152
153int
154ahc_scsidath_print(u_int regvalue, u_int *cur_col, u_int wrap)
155{
156 return (ahc_print_register(NULL, 0, "SCSIDATH",
157 0x07, regvalue, cur_col, wrap));
158}
159
160int
161ahc_stcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
162{
163 return (ahc_print_register(NULL, 0, "STCNT",
164 0x08, regvalue, cur_col, wrap));
165}
166
167static ahc_reg_parse_entry_t OPTIONMODE_parse_table[] = {
168 { "DIS_MSGIN_DUALEDGE", 0x01, 0x01 },
169 { "AUTO_MSGOUT_DE", 0x02, 0x02 },
170 { "SCSIDATL_IMGEN", 0x04, 0x04 },
171 { "EXPPHASEDIS", 0x08, 0x08 },
172 { "BUSFREEREV", 0x10, 0x10 },
173 { "ATNMGMNTEN", 0x20, 0x20 },
174 { "AUTOACKEN", 0x40, 0x40 },
175 { "AUTORATEEN", 0x80, 0x80 },
176 { "OPTIONMODE_DEFAULTS",0x03, 0x03 }
177};
178
179int
180ahc_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap)
181{
182 return (ahc_print_register(OPTIONMODE_parse_table, 9, "OPTIONMODE",
183 0x08, regvalue, cur_col, wrap));
184}
185
186int
187ahc_targcrccnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
188{
189 return (ahc_print_register(NULL, 0, "TARGCRCCNT",
190 0x0a, regvalue, cur_col, wrap));
191}
192
193static ahc_reg_parse_entry_t CLRSINT0_parse_table[] = {
194 { "CLRSPIORDY", 0x02, 0x02 },
195 { "CLRSWRAP", 0x08, 0x08 },
196 { "CLRIOERR", 0x08, 0x08 },
197 { "CLRSELINGO", 0x10, 0x10 },
198 { "CLRSELDI", 0x20, 0x20 },
199 { "CLRSELDO", 0x40, 0x40 }
200};
201
202int
203ahc_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
204{
205 return (ahc_print_register(CLRSINT0_parse_table, 6, "CLRSINT0",
206 0x0b, regvalue, cur_col, wrap));
207}
208
209static ahc_reg_parse_entry_t SSTAT0_parse_table[] = {
210 { "DMADONE", 0x01, 0x01 },
211 { "SPIORDY", 0x02, 0x02 },
212 { "SDONE", 0x04, 0x04 },
213 { "SWRAP", 0x08, 0x08 },
214 { "IOERR", 0x08, 0x08 },
215 { "SELINGO", 0x10, 0x10 },
216 { "SELDI", 0x20, 0x20 },
217 { "SELDO", 0x40, 0x40 },
218 { "TARGET", 0x80, 0x80 }
219};
220
221int
222ahc_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
223{
224 return (ahc_print_register(SSTAT0_parse_table, 9, "SSTAT0",
225 0x0b, regvalue, cur_col, wrap));
226}
227
228static ahc_reg_parse_entry_t CLRSINT1_parse_table[] = {
229 { "CLRREQINIT", 0x01, 0x01 },
230 { "CLRPHASECHG", 0x02, 0x02 },
231 { "CLRSCSIPERR", 0x04, 0x04 },
232 { "CLRBUSFREE", 0x08, 0x08 },
233 { "CLRSCSIRSTI", 0x20, 0x20 },
234 { "CLRATNO", 0x40, 0x40 },
235 { "CLRSELTIMEO", 0x80, 0x80 }
236};
237
238int
239ahc_clrsint1_print(u_int regvalue, u_int *cur_col, u_int wrap)
240{
241 return (ahc_print_register(CLRSINT1_parse_table, 7, "CLRSINT1",
242 0x0c, regvalue, cur_col, wrap));
243}
244
245static ahc_reg_parse_entry_t SSTAT1_parse_table[] = {
246 { "REQINIT", 0x01, 0x01 },
247 { "PHASECHG", 0x02, 0x02 },
248 { "SCSIPERR", 0x04, 0x04 },
249 { "BUSFREE", 0x08, 0x08 },
250 { "PHASEMIS", 0x10, 0x10 },
251 { "SCSIRSTI", 0x20, 0x20 },
252 { "ATNTARG", 0x40, 0x40 },
253 { "SELTO", 0x80, 0x80 }
254};
255
256int
257ahc_sstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
258{
259 return (ahc_print_register(SSTAT1_parse_table, 8, "SSTAT1",
260 0x0c, regvalue, cur_col, wrap));
261}
262
263static ahc_reg_parse_entry_t SSTAT2_parse_table[] = {
264 { "DUAL_EDGE_ERR", 0x01, 0x01 },
265 { "CRCREQERR", 0x02, 0x02 },
266 { "CRCENDERR", 0x04, 0x04 },
267 { "CRCVALERR", 0x08, 0x08 },
268 { "EXP_ACTIVE", 0x10, 0x10 },
269 { "SHVALID", 0x40, 0x40 },
270 { "OVERRUN", 0x80, 0x80 },
271 { "SFCNT", 0x1f, 0x1f }
272};
273
274int
275ahc_sstat2_print(u_int regvalue, u_int *cur_col, u_int wrap)
276{
277 return (ahc_print_register(SSTAT2_parse_table, 8, "SSTAT2",
278 0x0d, regvalue, cur_col, wrap));
279}
280
281static ahc_reg_parse_entry_t SSTAT3_parse_table[] = {
282 { "OFFCNT", 0x0f, 0x0f },
283 { "U2OFFCNT", 0x7f, 0x7f },
284 { "SCSICNT", 0xf0, 0xf0 }
285};
286
287int
288ahc_sstat3_print(u_int regvalue, u_int *cur_col, u_int wrap)
289{
290 return (ahc_print_register(SSTAT3_parse_table, 3, "SSTAT3",
291 0x0e, regvalue, cur_col, wrap));
292}
293
294static ahc_reg_parse_entry_t SCSIID_ULTRA2_parse_table[] = {
295 { "OID", 0x0f, 0x0f },
296 { "TID", 0xf0, 0xf0 }
297};
298
299int
300ahc_scsiid_ultra2_print(u_int regvalue, u_int *cur_col, u_int wrap)
301{
302 return (ahc_print_register(SCSIID_ULTRA2_parse_table, 2, "SCSIID_ULTRA2",
303 0x0f, regvalue, cur_col, wrap));
304}
305
306static ahc_reg_parse_entry_t SIMODE0_parse_table[] = {
307 { "ENDMADONE", 0x01, 0x01 },
308 { "ENSPIORDY", 0x02, 0x02 },
309 { "ENSDONE", 0x04, 0x04 },
310 { "ENSWRAP", 0x08, 0x08 },
311 { "ENIOERR", 0x08, 0x08 },
312 { "ENSELINGO", 0x10, 0x10 },
313 { "ENSELDI", 0x20, 0x20 },
314 { "ENSELDO", 0x40, 0x40 }
315};
316
317int
318ahc_simode0_print(u_int regvalue, u_int *cur_col, u_int wrap)
319{
320 return (ahc_print_register(SIMODE0_parse_table, 8, "SIMODE0",
321 0x10, regvalue, cur_col, wrap));
322}
323
324static ahc_reg_parse_entry_t SIMODE1_parse_table[] = {
325 { "ENREQINIT", 0x01, 0x01 },
326 { "ENPHASECHG", 0x02, 0x02 },
327 { "ENSCSIPERR", 0x04, 0x04 },
328 { "ENBUSFREE", 0x08, 0x08 },
329 { "ENPHASEMIS", 0x10, 0x10 },
330 { "ENSCSIRST", 0x20, 0x20 },
331 { "ENATNTARG", 0x40, 0x40 },
332 { "ENSELTIMO", 0x80, 0x80 }
333};
334
335int
336ahc_simode1_print(u_int regvalue, u_int *cur_col, u_int wrap)
337{
338 return (ahc_print_register(SIMODE1_parse_table, 8, "SIMODE1",
339 0x11, regvalue, cur_col, wrap));
340}
341
342int
343ahc_scsibusl_print(u_int regvalue, u_int *cur_col, u_int wrap)
344{
345 return (ahc_print_register(NULL, 0, "SCSIBUSL",
346 0x12, regvalue, cur_col, wrap));
347}
348
349int
350ahc_scsibush_print(u_int regvalue, u_int *cur_col, u_int wrap)
351{
352 return (ahc_print_register(NULL, 0, "SCSIBUSH",
353 0x13, regvalue, cur_col, wrap));
354}
355
356static ahc_reg_parse_entry_t SXFRCTL2_parse_table[] = {
357 { "CMDDMAEN", 0x08, 0x08 },
358 { "AUTORSTDIS", 0x10, 0x10 },
359 { "ASYNC_SETUP", 0x07, 0x07 }
360};
361
362int
363ahc_sxfrctl2_print(u_int regvalue, u_int *cur_col, u_int wrap)
364{
365 return (ahc_print_register(SXFRCTL2_parse_table, 3, "SXFRCTL2",
366 0x13, regvalue, cur_col, wrap));
367}
368
369int
370ahc_shaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
371{
372 return (ahc_print_register(NULL, 0, "SHADDR",
373 0x14, regvalue, cur_col, wrap));
374}
375
376static ahc_reg_parse_entry_t SELTIMER_parse_table[] = {
377 { "STAGE1", 0x01, 0x01 },
378 { "STAGE2", 0x02, 0x02 },
379 { "STAGE3", 0x04, 0x04 },
380 { "STAGE4", 0x08, 0x08 },
381 { "STAGE5", 0x10, 0x10 },
382 { "STAGE6", 0x20, 0x20 }
383};
384
385int
386ahc_seltimer_print(u_int regvalue, u_int *cur_col, u_int wrap)
387{
388 return (ahc_print_register(SELTIMER_parse_table, 6, "SELTIMER",
389 0x18, regvalue, cur_col, wrap));
390}
391
392static ahc_reg_parse_entry_t SELID_parse_table[] = {
393 { "ONEBIT", 0x08, 0x08 },
394 { "SELID_MASK", 0xf0, 0xf0 }
395};
396
397int
398ahc_selid_print(u_int regvalue, u_int *cur_col, u_int wrap)
399{
400 return (ahc_print_register(SELID_parse_table, 2, "SELID",
401 0x19, regvalue, cur_col, wrap));
402}
403
404static ahc_reg_parse_entry_t SCAMCTL_parse_table[] = {
405 { "DFLTTID", 0x10, 0x10 },
406 { "ALTSTIM", 0x20, 0x20 },
407 { "CLRSCAMSELID", 0x40, 0x40 },
408 { "ENSCAMSELO", 0x80, 0x80 },
409 { "SCAMLVL", 0x03, 0x03 }
410};
411
412int
413ahc_scamctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
414{
415 return (ahc_print_register(SCAMCTL_parse_table, 5, "SCAMCTL",
416 0x1a, regvalue, cur_col, wrap));
417}
418
419int
420ahc_targid_print(u_int regvalue, u_int *cur_col, u_int wrap)
421{
422 return (ahc_print_register(NULL, 0, "TARGID",
423 0x1b, regvalue, cur_col, wrap));
424}
425
426static ahc_reg_parse_entry_t SPIOCAP_parse_table[] = {
427 { "SSPIOCPS", 0x01, 0x01 },
428 { "ROM", 0x02, 0x02 },
429 { "EEPROM", 0x04, 0x04 },
430 { "SEEPROM", 0x08, 0x08 },
431 { "EXT_BRDCTL", 0x10, 0x10 },
432 { "SOFTCMDEN", 0x20, 0x20 },
433 { "SOFT0", 0x40, 0x40 },
434 { "SOFT1", 0x80, 0x80 }
435};
436
437int
438ahc_spiocap_print(u_int regvalue, u_int *cur_col, u_int wrap)
439{
440 return (ahc_print_register(SPIOCAP_parse_table, 8, "SPIOCAP",
441 0x1b, regvalue, cur_col, wrap));
442}
443
444static ahc_reg_parse_entry_t BRDCTL_parse_table[] = {
445 { "BRDCTL0", 0x01, 0x01 },
446 { "BRDSTB_ULTRA2", 0x01, 0x01 },
447 { "BRDCTL1", 0x02, 0x02 },
448 { "BRDRW_ULTRA2", 0x02, 0x02 },
449 { "BRDRW", 0x04, 0x04 },
450 { "BRDDAT2", 0x04, 0x04 },
451 { "BRDCS", 0x08, 0x08 },
452 { "BRDDAT3", 0x08, 0x08 },
453 { "BRDSTB", 0x10, 0x10 },
454 { "BRDDAT4", 0x10, 0x10 },
455 { "BRDDAT5", 0x20, 0x20 },
456 { "BRDDAT6", 0x40, 0x40 },
457 { "BRDDAT7", 0x80, 0x80 }
458};
459
460int
461ahc_brdctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
462{
463 return (ahc_print_register(BRDCTL_parse_table, 13, "BRDCTL",
464 0x1d, regvalue, cur_col, wrap));
465}
466
467static ahc_reg_parse_entry_t SEECTL_parse_table[] = {
468 { "SEEDI", 0x01, 0x01 },
469 { "SEEDO", 0x02, 0x02 },
470 { "SEECK", 0x04, 0x04 },
471 { "SEECS", 0x08, 0x08 },
472 { "SEERDY", 0x10, 0x10 },
473 { "SEEMS", 0x20, 0x20 },
474 { "EXTARBREQ", 0x40, 0x40 },
475 { "EXTARBACK", 0x80, 0x80 }
476};
477
478int
479ahc_seectl_print(u_int regvalue, u_int *cur_col, u_int wrap)
480{
481 return (ahc_print_register(SEECTL_parse_table, 8, "SEECTL",
482 0x1e, regvalue, cur_col, wrap));
483}
484
485static ahc_reg_parse_entry_t SBLKCTL_parse_table[] = {
486 { "XCVR", 0x01, 0x01 },
487 { "SELWIDE", 0x02, 0x02 },
488 { "ENAB20", 0x04, 0x04 },
489 { "SELBUSB", 0x08, 0x08 },
490 { "ENAB40", 0x08, 0x08 },
491 { "AUTOFLUSHDIS", 0x20, 0x20 },
492 { "DIAGLEDON", 0x40, 0x40 },
493 { "DIAGLEDEN", 0x80, 0x80 }
494};
495
496int
497ahc_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
498{
499 return (ahc_print_register(SBLKCTL_parse_table, 8, "SBLKCTL",
500 0x1f, regvalue, cur_col, wrap));
501}
502
503int
504ahc_busy_targets_print(u_int regvalue, u_int *cur_col, u_int wrap)
505{
506 return (ahc_print_register(NULL, 0, "BUSY_TARGETS",
507 0x20, regvalue, cur_col, wrap));
508}
509
510int
511ahc_ultra_enb_print(u_int regvalue, u_int *cur_col, u_int wrap)
512{
513 return (ahc_print_register(NULL, 0, "ULTRA_ENB",
514 0x30, regvalue, cur_col, wrap));
515}
516
517int
518ahc_disc_dsb_print(u_int regvalue, u_int *cur_col, u_int wrap)
519{
520 return (ahc_print_register(NULL, 0, "DISC_DSB",
521 0x32, regvalue, cur_col, wrap));
522}
523
524int
525ahc_cmdsize_table_tail_print(u_int regvalue, u_int *cur_col, u_int wrap)
526{
527 return (ahc_print_register(NULL, 0, "CMDSIZE_TABLE_TAIL",
528 0x34, regvalue, cur_col, wrap));
529}
530
531int
532ahc_mwi_residual_print(u_int regvalue, u_int *cur_col, u_int wrap)
533{
534 return (ahc_print_register(NULL, 0, "MWI_RESIDUAL",
535 0x38, regvalue, cur_col, wrap));
536}
537
538int
539ahc_next_queued_scb_print(u_int regvalue, u_int *cur_col, u_int wrap)
540{
541 return (ahc_print_register(NULL, 0, "NEXT_QUEUED_SCB",
542 0x39, regvalue, cur_col, wrap));
543}
544
545int
546ahc_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap)
547{
548 return (ahc_print_register(NULL, 0, "MSG_OUT",
549 0x3a, regvalue, cur_col, wrap));
550}
551
552static ahc_reg_parse_entry_t DMAPARAMS_parse_table[] = {
553 { "FIFORESET", 0x01, 0x01 },
554 { "FIFOFLUSH", 0x02, 0x02 },
555 { "DIRECTION", 0x04, 0x04 },
556 { "HDMAEN", 0x08, 0x08 },
557 { "HDMAENACK", 0x08, 0x08 },
558 { "SDMAEN", 0x10, 0x10 },
559 { "SDMAENACK", 0x10, 0x10 },
560 { "SCSIEN", 0x20, 0x20 },
561 { "WIDEODD", 0x40, 0x40 },
562 { "PRELOADEN", 0x80, 0x80 }
563};
564
565int
566ahc_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap)
567{
568 return (ahc_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS",
569 0x3b, regvalue, cur_col, wrap));
570}
571
572static ahc_reg_parse_entry_t SEQ_FLAGS_parse_table[] = {
573 { "NO_DISCONNECT", 0x01, 0x01 },
574 { "SPHASE_PENDING", 0x02, 0x02 },
575 { "DPHASE_PENDING", 0x04, 0x04 },
576 { "CMDPHASE_PENDING", 0x08, 0x08 },
577 { "TARG_CMD_PENDING", 0x10, 0x10 },
578 { "DPHASE", 0x20, 0x20 },
579 { "NO_CDB_SENT", 0x40, 0x40 },
580 { "TARGET_CMD_IS_TAGGED",0x40, 0x40 },
581 { "NOT_IDENTIFIED", 0x80, 0x80 }
582};
583
584int
585ahc_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
586{
587 return (ahc_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS",
588 0x3c, regvalue, cur_col, wrap));
589}
590
591int
592ahc_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
593{
594 return (ahc_print_register(NULL, 0, "SAVED_SCSIID",
595 0x3d, regvalue, cur_col, wrap));
596}
597
598int
599ahc_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
600{
601 return (ahc_print_register(NULL, 0, "SAVED_LUN",
602 0x3e, regvalue, cur_col, wrap));
603}
604
605static ahc_reg_parse_entry_t LASTPHASE_parse_table[] = {
606 { "MSGI", 0x20, 0x20 },
607 { "IOI", 0x40, 0x40 },
608 { "CDI", 0x80, 0x80 },
609 { "P_DATAOUT", 0x00, 0x00 },
610 { "P_BUSFREE", 0x01, 0x01 },
611 { "P_DATAIN", 0x40, 0x40 },
612 { "P_COMMAND", 0x80, 0x80 },
613 { "P_MESGOUT", 0xa0, 0xa0 },
614 { "P_STATUS", 0xc0, 0xc0 },
615 { "PHASE_MASK", 0xe0, 0xe0 },
616 { "P_MESGIN", 0xe0, 0xe0 }
617};
618
619int
620ahc_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
621{
622 return (ahc_print_register(LASTPHASE_parse_table, 11, "LASTPHASE",
623 0x3f, regvalue, cur_col, wrap));
624}
625
626int
627ahc_waiting_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap)
628{
629 return (ahc_print_register(NULL, 0, "WAITING_SCBH",
630 0x40, regvalue, cur_col, wrap));
631}
632
633int
634ahc_disconnected_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap)
635{
636 return (ahc_print_register(NULL, 0, "DISCONNECTED_SCBH",
637 0x41, regvalue, cur_col, wrap));
638}
639
640int
641ahc_free_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap)
642{
643 return (ahc_print_register(NULL, 0, "FREE_SCBH",
644 0x42, regvalue, cur_col, wrap));
645}
646
647int
648ahc_complete_scbh_print(u_int regvalue, u_int *cur_col, u_int wrap)
649{
650 return (ahc_print_register(NULL, 0, "COMPLETE_SCBH",
651 0x43, regvalue, cur_col, wrap));
652}
653
654int
655ahc_hscb_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
656{
657 return (ahc_print_register(NULL, 0, "HSCB_ADDR",
658 0x44, regvalue, cur_col, wrap));
659}
660
661int
662ahc_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
663{
664 return (ahc_print_register(NULL, 0, "SHARED_DATA_ADDR",
665 0x48, regvalue, cur_col, wrap));
666}
667
668int
669ahc_kernel_qinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
670{
671 return (ahc_print_register(NULL, 0, "KERNEL_QINPOS",
672 0x4c, regvalue, cur_col, wrap));
673}
674
675int
676ahc_qinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
677{
678 return (ahc_print_register(NULL, 0, "QINPOS",
679 0x4d, regvalue, cur_col, wrap));
680}
681
682int
683ahc_qoutpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
684{
685 return (ahc_print_register(NULL, 0, "QOUTPOS",
686 0x4e, regvalue, cur_col, wrap));
687}
688
689int
690ahc_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
691{
692 return (ahc_print_register(NULL, 0, "KERNEL_TQINPOS",
693 0x4f, regvalue, cur_col, wrap));
694}
695
696int
697ahc_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
698{
699 return (ahc_print_register(NULL, 0, "TQINPOS",
700 0x50, regvalue, cur_col, wrap));
701}
702
703static ahc_reg_parse_entry_t ARG_1_parse_table[] = {
704 { "CONT_TARG_SESSION", 0x02, 0x02 },
705 { "CONT_MSG_LOOP", 0x04, 0x04 },
706 { "EXIT_MSG_LOOP", 0x08, 0x08 },
707 { "MSGOUT_PHASEMIS", 0x10, 0x10 },
708 { "SEND_REJ", 0x20, 0x20 },
709 { "SEND_SENSE", 0x40, 0x40 },
710 { "SEND_MSG", 0x80, 0x80 }
711};
712
713int
714ahc_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap)
715{
716 return (ahc_print_register(ARG_1_parse_table, 7, "ARG_1",
717 0x51, regvalue, cur_col, wrap));
718}
719
720int
721ahc_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap)
722{
723 return (ahc_print_register(NULL, 0, "ARG_2",
724 0x52, regvalue, cur_col, wrap));
725}
726
727int
728ahc_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap)
729{
730 return (ahc_print_register(NULL, 0, "LAST_MSG",
731 0x53, regvalue, cur_col, wrap));
732}
733
734static ahc_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = {
735 { "ENAUTOATNP", 0x02, 0x02 },
736 { "ENAUTOATNI", 0x04, 0x04 },
737 { "ENAUTOATNO", 0x08, 0x08 },
738 { "ENRSELI", 0x10, 0x10 },
739 { "ENSELI", 0x20, 0x20 },
740 { "ENSELO", 0x40, 0x40 }
741};
742
743int
744ahc_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap)
745{
746 return (ahc_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE",
747 0x54, regvalue, cur_col, wrap));
748}
749
750static ahc_reg_parse_entry_t HA_274_BIOSGLOBAL_parse_table[] = {
751 { "HA_274_EXTENDED_TRANS",0x01, 0x01 }
752};
753
754int
755ahc_ha_274_biosglobal_print(u_int regvalue, u_int *cur_col, u_int wrap)
756{
757 return (ahc_print_register(HA_274_BIOSGLOBAL_parse_table, 1, "HA_274_BIOSGLOBAL",
758 0x56, regvalue, cur_col, wrap));
759}
760
761static ahc_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = {
762 { "SCB_DMA", 0x01, 0x01 },
763 { "TARGET_MSG_PENDING", 0x02, 0x02 }
764};
765
766int
767ahc_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap)
768{
769 return (ahc_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2",
770 0x57, regvalue, cur_col, wrap));
771}
772
773static ahc_reg_parse_entry_t SCSICONF_parse_table[] = {
774 { "ENSPCHK", 0x20, 0x20 },
775 { "RESET_SCSI", 0x40, 0x40 },
776 { "TERM_ENB", 0x80, 0x80 },
777 { "HSCSIID", 0x07, 0x07 },
778 { "HWSCSIID", 0x0f, 0x0f }
779};
780
781int
782ahc_scsiconf_print(u_int regvalue, u_int *cur_col, u_int wrap)
783{
784 return (ahc_print_register(SCSICONF_parse_table, 5, "SCSICONF",
785 0x5a, regvalue, cur_col, wrap));
786}
787
788static ahc_reg_parse_entry_t INTDEF_parse_table[] = {
789 { "EDGE_TRIG", 0x80, 0x80 },
790 { "VECTOR", 0x0f, 0x0f }
791};
792
793int
794ahc_intdef_print(u_int regvalue, u_int *cur_col, u_int wrap)
795{
796 return (ahc_print_register(INTDEF_parse_table, 2, "INTDEF",
797 0x5c, regvalue, cur_col, wrap));
798}
799
800int
801ahc_hostconf_print(u_int regvalue, u_int *cur_col, u_int wrap)
802{
803 return (ahc_print_register(NULL, 0, "HOSTCONF",
804 0x5d, regvalue, cur_col, wrap));
805}
806
807static ahc_reg_parse_entry_t HA_274_BIOSCTRL_parse_table[] = {
808 { "CHANNEL_B_PRIMARY", 0x08, 0x08 },
809 { "BIOSMODE", 0x30, 0x30 },
810 { "BIOSDISABLED", 0x30, 0x30 }
811};
812
813int
814ahc_ha_274_biosctrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
815{
816 return (ahc_print_register(HA_274_BIOSCTRL_parse_table, 3, "HA_274_BIOSCTRL",
817 0x5f, regvalue, cur_col, wrap));
818}
819
820static ahc_reg_parse_entry_t SEQCTL_parse_table[] = {
821 { "LOADRAM", 0x01, 0x01 },
822 { "SEQRESET", 0x02, 0x02 },
823 { "STEP", 0x04, 0x04 },
824 { "BRKADRINTEN", 0x08, 0x08 },
825 { "FASTMODE", 0x10, 0x10 },
826 { "FAILDIS", 0x20, 0x20 },
827 { "PAUSEDIS", 0x40, 0x40 },
828 { "PERRORDIS", 0x80, 0x80 }
829};
830
831int
832ahc_seqctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
833{
834 return (ahc_print_register(SEQCTL_parse_table, 8, "SEQCTL",
835 0x60, regvalue, cur_col, wrap));
836}
837
838int
839ahc_seqram_print(u_int regvalue, u_int *cur_col, u_int wrap)
840{
841 return (ahc_print_register(NULL, 0, "SEQRAM",
842 0x61, regvalue, cur_col, wrap));
843}
844
845int
846ahc_seqaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap)
847{
848 return (ahc_print_register(NULL, 0, "SEQADDR0",
849 0x62, regvalue, cur_col, wrap));
850}
851
852static ahc_reg_parse_entry_t SEQADDR1_parse_table[] = {
853 { "SEQADDR1_MASK", 0x01, 0x01 }
854};
855
856int
857ahc_seqaddr1_print(u_int regvalue, u_int *cur_col, u_int wrap)
858{
859 return (ahc_print_register(SEQADDR1_parse_table, 1, "SEQADDR1",
860 0x63, regvalue, cur_col, wrap));
861}
862
863int
864ahc_accum_print(u_int regvalue, u_int *cur_col, u_int wrap)
865{
866 return (ahc_print_register(NULL, 0, "ACCUM",
867 0x64, regvalue, cur_col, wrap));
868}
869
870int
871ahc_sindex_print(u_int regvalue, u_int *cur_col, u_int wrap)
872{
873 return (ahc_print_register(NULL, 0, "SINDEX",
874 0x65, regvalue, cur_col, wrap));
875}
876
877int
878ahc_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap)
879{
880 return (ahc_print_register(NULL, 0, "DINDEX",
881 0x66, regvalue, cur_col, wrap));
882}
883
884int
885ahc_allones_print(u_int regvalue, u_int *cur_col, u_int wrap)
886{
887 return (ahc_print_register(NULL, 0, "ALLONES",
888 0x69, regvalue, cur_col, wrap));
889}
890
891int
892ahc_allzeros_print(u_int regvalue, u_int *cur_col, u_int wrap)
893{
894 return (ahc_print_register(NULL, 0, "ALLZEROS",
895 0x6a, regvalue, cur_col, wrap));
896}
897
898int
899ahc_none_print(u_int regvalue, u_int *cur_col, u_int wrap)
900{
901 return (ahc_print_register(NULL, 0, "NONE",
902 0x6a, regvalue, cur_col, wrap));
903}
904
905static ahc_reg_parse_entry_t FLAGS_parse_table[] = {
906 { "CARRY", 0x01, 0x01 },
907 { "ZERO", 0x02, 0x02 }
908};
909
910int
911ahc_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
912{
913 return (ahc_print_register(FLAGS_parse_table, 2, "FLAGS",
914 0x6b, regvalue, cur_col, wrap));
915}
916
917int
918ahc_sindir_print(u_int regvalue, u_int *cur_col, u_int wrap)
919{
920 return (ahc_print_register(NULL, 0, "SINDIR",
921 0x6c, regvalue, cur_col, wrap));
922}
923
924int
925ahc_dindir_print(u_int regvalue, u_int *cur_col, u_int wrap)
926{
927 return (ahc_print_register(NULL, 0, "DINDIR",
928 0x6d, regvalue, cur_col, wrap));
929}
930
931int
932ahc_function1_print(u_int regvalue, u_int *cur_col, u_int wrap)
933{
934 return (ahc_print_register(NULL, 0, "FUNCTION1",
935 0x6e, regvalue, cur_col, wrap));
936}
937
938int
939ahc_stack_print(u_int regvalue, u_int *cur_col, u_int wrap)
940{
941 return (ahc_print_register(NULL, 0, "STACK",
942 0x6f, regvalue, cur_col, wrap));
943}
944
945int
946ahc_targ_offset_print(u_int regvalue, u_int *cur_col, u_int wrap)
947{
948 return (ahc_print_register(NULL, 0, "TARG_OFFSET",
949 0x70, regvalue, cur_col, wrap));
950}
951
952int
953ahc_sram_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
954{
955 return (ahc_print_register(NULL, 0, "SRAM_BASE",
956 0x70, regvalue, cur_col, wrap));
957}
958
959static ahc_reg_parse_entry_t BCTL_parse_table[] = {
960 { "ENABLE", 0x01, 0x01 },
961 { "ACE", 0x08, 0x08 }
962};
963
964int
965ahc_bctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
966{
967 return (ahc_print_register(BCTL_parse_table, 2, "BCTL",
968 0x84, regvalue, cur_col, wrap));
969}
970
971static ahc_reg_parse_entry_t DSCOMMAND0_parse_table[] = {
972 { "CIOPARCKEN", 0x01, 0x01 },
973 { "USCBSIZE32", 0x02, 0x02 },
974 { "RAMPS", 0x04, 0x04 },
975 { "INTSCBRAMSEL", 0x08, 0x08 },
976 { "EXTREQLCK", 0x10, 0x10 },
977 { "MPARCKEN", 0x20, 0x20 },
978 { "DPARCKEN", 0x40, 0x40 },
979 { "CACHETHEN", 0x80, 0x80 }
980};
981
982int
983ahc_dscommand0_print(u_int regvalue, u_int *cur_col, u_int wrap)
984{
985 return (ahc_print_register(DSCOMMAND0_parse_table, 8, "DSCOMMAND0",
986 0x84, regvalue, cur_col, wrap));
987}
988
989static ahc_reg_parse_entry_t BUSTIME_parse_table[] = {
990 { "BON", 0x0f, 0x0f },
991 { "BOFF", 0xf0, 0xf0 }
992};
993
994int
995ahc_bustime_print(u_int regvalue, u_int *cur_col, u_int wrap)
996{
997 return (ahc_print_register(BUSTIME_parse_table, 2, "BUSTIME",
998 0x85, regvalue, cur_col, wrap));
999}
1000
1001static ahc_reg_parse_entry_t DSCOMMAND1_parse_table[] = {
1002 { "HADDLDSEL0", 0x01, 0x01 },
1003 { "HADDLDSEL1", 0x02, 0x02 },
1004 { "DSLATT", 0xfc, 0xfc }
1005};
1006
1007int
1008ahc_dscommand1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1009{
1010 return (ahc_print_register(DSCOMMAND1_parse_table, 3, "DSCOMMAND1",
1011 0x85, regvalue, cur_col, wrap));
1012}
1013
1014static ahc_reg_parse_entry_t BUSSPD_parse_table[] = {
1015 { "STBON", 0x07, 0x07 },
1016 { "STBOFF", 0x38, 0x38 },
1017 { "DFTHRSH_75", 0x80, 0x80 },
1018 { "DFTHRSH", 0xc0, 0xc0 },
1019 { "DFTHRSH_100", 0xc0, 0xc0 }
1020};
1021
1022int
1023ahc_busspd_print(u_int regvalue, u_int *cur_col, u_int wrap)
1024{
1025 return (ahc_print_register(BUSSPD_parse_table, 5, "BUSSPD",
1026 0x86, regvalue, cur_col, wrap));
1027}
1028
1029static ahc_reg_parse_entry_t HS_MAILBOX_parse_table[] = {
1030 { "SEQ_MAILBOX", 0x0f, 0x0f },
1031 { "HOST_TQINPOS", 0x80, 0x80 },
1032 { "HOST_MAILBOX", 0xf0, 0xf0 }
1033};
1034
1035int
1036ahc_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap)
1037{
1038 return (ahc_print_register(HS_MAILBOX_parse_table, 3, "HS_MAILBOX",
1039 0x86, regvalue, cur_col, wrap));
1040}
1041
1042static ahc_reg_parse_entry_t DSPCISTATUS_parse_table[] = {
1043 { "DFTHRSH_100", 0xc0, 0xc0 }
1044};
1045
1046int
1047ahc_dspcistatus_print(u_int regvalue, u_int *cur_col, u_int wrap)
1048{
1049 return (ahc_print_register(DSPCISTATUS_parse_table, 1, "DSPCISTATUS",
1050 0x86, regvalue, cur_col, wrap));
1051}
1052
1053static ahc_reg_parse_entry_t HCNTRL_parse_table[] = {
1054 { "CHIPRST", 0x01, 0x01 },
1055 { "CHIPRSTACK", 0x01, 0x01 },
1056 { "INTEN", 0x02, 0x02 },
1057 { "PAUSE", 0x04, 0x04 },
1058 { "IRQMS", 0x08, 0x08 },
1059 { "SWINT", 0x10, 0x10 },
1060 { "POWRDN", 0x40, 0x40 }
1061};
1062
1063int
1064ahc_hcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
1065{
1066 return (ahc_print_register(HCNTRL_parse_table, 7, "HCNTRL",
1067 0x87, regvalue, cur_col, wrap));
1068}
1069
1070int
1071ahc_haddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1072{
1073 return (ahc_print_register(NULL, 0, "HADDR",
1074 0x88, regvalue, cur_col, wrap));
1075}
1076
1077int
1078ahc_hcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1079{
1080 return (ahc_print_register(NULL, 0, "HCNT",
1081 0x8c, regvalue, cur_col, wrap));
1082}
1083
1084int
1085ahc_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1086{
1087 return (ahc_print_register(NULL, 0, "SCBPTR",
1088 0x90, regvalue, cur_col, wrap));
1089}
1090
1091static ahc_reg_parse_entry_t INTSTAT_parse_table[] = {
1092 { "SEQINT", 0x01, 0x01 },
1093 { "CMDCMPLT", 0x02, 0x02 },
1094 { "SCSIINT", 0x04, 0x04 },
1095 { "BRKADRINT", 0x08, 0x08 },
1096 { "BAD_PHASE", 0x01, 0x01 },
1097 { "INT_PEND", 0x0f, 0x0f },
1098 { "SEND_REJECT", 0x11, 0x11 },
1099 { "PROTO_VIOLATION", 0x21, 0x21 },
1100 { "NO_MATCH", 0x31, 0x31 },
1101 { "IGN_WIDE_RES", 0x41, 0x41 },
1102 { "PDATA_REINIT", 0x51, 0x51 },
1103 { "HOST_MSG_LOOP", 0x61, 0x61 },
1104 { "BAD_STATUS", 0x71, 0x71 },
1105 { "PERR_DETECTED", 0x81, 0x81 },
1106 { "DATA_OVERRUN", 0x91, 0x91 },
1107 { "MKMSG_FAILED", 0xa1, 0xa1 },
1108 { "MISSED_BUSFREE", 0xb1, 0xb1 },
1109 { "SCB_MISMATCH", 0xc1, 0xc1 },
1110 { "NO_FREE_SCB", 0xd1, 0xd1 },
1111 { "OUT_OF_RANGE", 0xe1, 0xe1 },
1112 { "SEQINT_MASK", 0xf1, 0xf1 }
1113};
1114
1115int
1116ahc_intstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
1117{
1118 return (ahc_print_register(INTSTAT_parse_table, 21, "INTSTAT",
1119 0x91, regvalue, cur_col, wrap));
1120}
1121
1122static ahc_reg_parse_entry_t CLRINT_parse_table[] = {
1123 { "CLRSEQINT", 0x01, 0x01 },
1124 { "CLRCMDINT", 0x02, 0x02 },
1125 { "CLRSCSIINT", 0x04, 0x04 },
1126 { "CLRBRKADRINT", 0x08, 0x08 },
1127 { "CLRPARERR", 0x10, 0x10 }
1128};
1129
1130int
1131ahc_clrint_print(u_int regvalue, u_int *cur_col, u_int wrap)
1132{
1133 return (ahc_print_register(CLRINT_parse_table, 5, "CLRINT",
1134 0x92, regvalue, cur_col, wrap));
1135}
1136
1137static ahc_reg_parse_entry_t ERROR_parse_table[] = {
1138 { "ILLHADDR", 0x01, 0x01 },
1139 { "ILLSADDR", 0x02, 0x02 },
1140 { "ILLOPCODE", 0x04, 0x04 },
1141 { "SQPARERR", 0x08, 0x08 },
1142 { "DPARERR", 0x10, 0x10 },
1143 { "MPARERR", 0x20, 0x20 },
1144 { "PCIERRSTAT", 0x40, 0x40 },
1145 { "CIOPARERR", 0x80, 0x80 }
1146};
1147
1148int
1149ahc_error_print(u_int regvalue, u_int *cur_col, u_int wrap)
1150{
1151 return (ahc_print_register(ERROR_parse_table, 8, "ERROR",
1152 0x92, regvalue, cur_col, wrap));
1153}
1154
1155static ahc_reg_parse_entry_t DFCNTRL_parse_table[] = {
1156 { "FIFORESET", 0x01, 0x01 },
1157 { "FIFOFLUSH", 0x02, 0x02 },
1158 { "DIRECTION", 0x04, 0x04 },
1159 { "HDMAEN", 0x08, 0x08 },
1160 { "HDMAENACK", 0x08, 0x08 },
1161 { "SDMAEN", 0x10, 0x10 },
1162 { "SDMAENACK", 0x10, 0x10 },
1163 { "SCSIEN", 0x20, 0x20 },
1164 { "WIDEODD", 0x40, 0x40 },
1165 { "PRELOADEN", 0x80, 0x80 }
1166};
1167
1168int
1169ahc_dfcntrl_print(u_int regvalue, u_int *cur_col, u_int wrap)
1170{
1171 return (ahc_print_register(DFCNTRL_parse_table, 10, "DFCNTRL",
1172 0x93, regvalue, cur_col, wrap));
1173}
1174
1175static ahc_reg_parse_entry_t DFSTATUS_parse_table[] = {
1176 { "FIFOEMP", 0x01, 0x01 },
1177 { "FIFOFULL", 0x02, 0x02 },
1178 { "DFTHRESH", 0x04, 0x04 },
1179 { "HDONE", 0x08, 0x08 },
1180 { "MREQPEND", 0x10, 0x10 },
1181 { "FIFOQWDEMP", 0x20, 0x20 },
1182 { "DFCACHETH", 0x40, 0x40 },
1183 { "PRELOAD_AVAIL", 0x80, 0x80 }
1184};
1185
1186int
1187ahc_dfstatus_print(u_int regvalue, u_int *cur_col, u_int wrap)
1188{
1189 return (ahc_print_register(DFSTATUS_parse_table, 8, "DFSTATUS",
1190 0x94, regvalue, cur_col, wrap));
1191}
1192
1193int
1194ahc_dfwaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1195{
1196 return (ahc_print_register(NULL, 0, "DFWADDR",
1197 0x95, regvalue, cur_col, wrap));
1198}
1199
1200int
1201ahc_dfraddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1202{
1203 return (ahc_print_register(NULL, 0, "DFRADDR",
1204 0x97, regvalue, cur_col, wrap));
1205}
1206
1207int
1208ahc_dfdat_print(u_int regvalue, u_int *cur_col, u_int wrap)
1209{
1210 return (ahc_print_register(NULL, 0, "DFDAT",
1211 0x99, regvalue, cur_col, wrap));
1212}
1213
1214static ahc_reg_parse_entry_t SCBCNT_parse_table[] = {
1215 { "SCBAUTO", 0x80, 0x80 },
1216 { "SCBCNT_MASK", 0x1f, 0x1f }
1217};
1218
1219int
1220ahc_scbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1221{
1222 return (ahc_print_register(SCBCNT_parse_table, 2, "SCBCNT",
1223 0x9a, regvalue, cur_col, wrap));
1224}
1225
1226int
1227ahc_qinfifo_print(u_int regvalue, u_int *cur_col, u_int wrap)
1228{
1229 return (ahc_print_register(NULL, 0, "QINFIFO",
1230 0x9b, regvalue, cur_col, wrap));
1231}
1232
1233int
1234ahc_qincnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1235{
1236 return (ahc_print_register(NULL, 0, "QINCNT",
1237 0x9c, regvalue, cur_col, wrap));
1238}
1239
1240int
1241ahc_qoutfifo_print(u_int regvalue, u_int *cur_col, u_int wrap)
1242{
1243 return (ahc_print_register(NULL, 0, "QOUTFIFO",
1244 0x9d, regvalue, cur_col, wrap));
1245}
1246
1247static ahc_reg_parse_entry_t CRCCONTROL1_parse_table[] = {
1248 { "TARGCRCCNTEN", 0x04, 0x04 },
1249 { "TARGCRCENDEN", 0x08, 0x08 },
1250 { "CRCREQCHKEN", 0x10, 0x10 },
1251 { "CRCENDCHKEN", 0x20, 0x20 },
1252 { "CRCVALCHKEN", 0x40, 0x40 },
1253 { "CRCONSEEN", 0x80, 0x80 }
1254};
1255
1256int
1257ahc_crccontrol1_print(u_int regvalue, u_int *cur_col, u_int wrap)
1258{
1259 return (ahc_print_register(CRCCONTROL1_parse_table, 6, "CRCCONTROL1",
1260 0x9d, regvalue, cur_col, wrap));
1261}
1262
1263int
1264ahc_qoutcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1265{
1266 return (ahc_print_register(NULL, 0, "QOUTCNT",
1267 0x9e, regvalue, cur_col, wrap));
1268}
1269
1270static ahc_reg_parse_entry_t SCSIPHASE_parse_table[] = {
1271 { "DATA_OUT_PHASE", 0x01, 0x01 },
1272 { "DATA_IN_PHASE", 0x02, 0x02 },
1273 { "MSG_OUT_PHASE", 0x04, 0x04 },
1274 { "MSG_IN_PHASE", 0x08, 0x08 },
1275 { "COMMAND_PHASE", 0x10, 0x10 },
1276 { "STATUS_PHASE", 0x20, 0x20 },
1277 { "DATA_PHASE_MASK", 0x03, 0x03 }
1278};
1279
1280int
1281ahc_scsiphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
1282{
1283 return (ahc_print_register(SCSIPHASE_parse_table, 7, "SCSIPHASE",
1284 0x9e, regvalue, cur_col, wrap));
1285}
1286
1287static ahc_reg_parse_entry_t SFUNCT_parse_table[] = {
1288 { "ALT_MODE", 0x80, 0x80 }
1289};
1290
1291int
1292ahc_sfunct_print(u_int regvalue, u_int *cur_col, u_int wrap)
1293{
1294 return (ahc_print_register(SFUNCT_parse_table, 1, "SFUNCT",
1295 0x9f, regvalue, cur_col, wrap));
1296}
1297
1298int
1299ahc_scb_base_print(u_int regvalue, u_int *cur_col, u_int wrap)
1300{
1301 return (ahc_print_register(NULL, 0, "SCB_BASE",
1302 0xa0, regvalue, cur_col, wrap));
1303}
1304
1305int
1306ahc_scb_cdb_ptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1307{
1308 return (ahc_print_register(NULL, 0, "SCB_CDB_PTR",
1309 0xa0, regvalue, cur_col, wrap));
1310}
1311
1312int
1313ahc_scb_residual_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1314{
1315 return (ahc_print_register(NULL, 0, "SCB_RESIDUAL_SGPTR",
1316 0xa4, regvalue, cur_col, wrap));
1317}
1318
1319int
1320ahc_scb_scsi_status_print(u_int regvalue, u_int *cur_col, u_int wrap)
1321{
1322 return (ahc_print_register(NULL, 0, "SCB_SCSI_STATUS",
1323 0xa8, regvalue, cur_col, wrap));
1324}
1325
1326int
1327ahc_scb_target_phases_print(u_int regvalue, u_int *cur_col, u_int wrap)
1328{
1329 return (ahc_print_register(NULL, 0, "SCB_TARGET_PHASES",
1330 0xa9, regvalue, cur_col, wrap));
1331}
1332
1333int
1334ahc_scb_target_data_dir_print(u_int regvalue, u_int *cur_col, u_int wrap)
1335{
1336 return (ahc_print_register(NULL, 0, "SCB_TARGET_DATA_DIR",
1337 0xaa, regvalue, cur_col, wrap));
1338}
1339
1340int
1341ahc_scb_target_itag_print(u_int regvalue, u_int *cur_col, u_int wrap)
1342{
1343 return (ahc_print_register(NULL, 0, "SCB_TARGET_ITAG",
1344 0xab, regvalue, cur_col, wrap));
1345}
1346
1347int
1348ahc_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1349{
1350 return (ahc_print_register(NULL, 0, "SCB_DATAPTR",
1351 0xac, regvalue, cur_col, wrap));
1352}
1353
1354static ahc_reg_parse_entry_t SCB_DATACNT_parse_table[] = {
1355 { "SG_LAST_SEG", 0x80, 0x80 },
1356 { "SG_HIGH_ADDR_BITS", 0x7f, 0x7f }
1357};
1358
1359int
1360ahc_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1361{
1362 return (ahc_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT",
1363 0xb0, regvalue, cur_col, wrap));
1364}
1365
1366static ahc_reg_parse_entry_t SCB_SGPTR_parse_table[] = {
1367 { "SG_LIST_NULL", 0x01, 0x01 },
1368 { "SG_FULL_RESID", 0x02, 0x02 },
1369 { "SG_RESID_VALID", 0x04, 0x04 }
1370};
1371
1372int
1373ahc_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1374{
1375 return (ahc_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR",
1376 0xb4, regvalue, cur_col, wrap));
1377}
1378
1379static ahc_reg_parse_entry_t SCB_CONTROL_parse_table[] = {
1380 { "DISCONNECTED", 0x04, 0x04 },
1381 { "ULTRAENB", 0x08, 0x08 },
1382 { "MK_MESSAGE", 0x10, 0x10 },
1383 { "TAG_ENB", 0x20, 0x20 },
1384 { "DISCENB", 0x40, 0x40 },
1385 { "TARGET_SCB", 0x80, 0x80 },
1386 { "STATUS_RCVD", 0x80, 0x80 },
1387 { "SCB_TAG_TYPE", 0x03, 0x03 }
1388};
1389
1390int
1391ahc_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap)
1392{
1393 return (ahc_print_register(SCB_CONTROL_parse_table, 8, "SCB_CONTROL",
1394 0xb8, regvalue, cur_col, wrap));
1395}
1396
1397static ahc_reg_parse_entry_t SCB_SCSIID_parse_table[] = {
1398 { "TWIN_CHNLB", 0x80, 0x80 },
1399 { "OID", 0x0f, 0x0f },
1400 { "TWIN_TID", 0x70, 0x70 },
1401 { "TID", 0xf0, 0xf0 }
1402};
1403
1404int
1405ahc_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
1406{
1407 return (ahc_print_register(SCB_SCSIID_parse_table, 4, "SCB_SCSIID",
1408 0xb9, regvalue, cur_col, wrap));
1409}
1410
1411static ahc_reg_parse_entry_t SCB_LUN_parse_table[] = {
1412 { "SCB_XFERLEN_ODD", 0x80, 0x80 },
1413 { "LID", 0x3f, 0x3f }
1414};
1415
1416int
1417ahc_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
1418{
1419 return (ahc_print_register(SCB_LUN_parse_table, 2, "SCB_LUN",
1420 0xba, regvalue, cur_col, wrap));
1421}
1422
1423int
1424ahc_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
1425{
1426 return (ahc_print_register(NULL, 0, "SCB_TAG",
1427 0xbb, regvalue, cur_col, wrap));
1428}
1429
1430int
1431ahc_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap)
1432{
1433 return (ahc_print_register(NULL, 0, "SCB_CDB_LEN",
1434 0xbc, regvalue, cur_col, wrap));
1435}
1436
1437int
1438ahc_scb_scsirate_print(u_int regvalue, u_int *cur_col, u_int wrap)
1439{
1440 return (ahc_print_register(NULL, 0, "SCB_SCSIRATE",
1441 0xbd, regvalue, cur_col, wrap));
1442}
1443
1444int
1445ahc_scb_scsioffset_print(u_int regvalue, u_int *cur_col, u_int wrap)
1446{
1447 return (ahc_print_register(NULL, 0, "SCB_SCSIOFFSET",
1448 0xbe, regvalue, cur_col, wrap));
1449}
1450
1451int
1452ahc_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
1453{
1454 return (ahc_print_register(NULL, 0, "SCB_NEXT",
1455 0xbf, regvalue, cur_col, wrap));
1456}
1457
1458int
1459ahc_scb_64_spare_print(u_int regvalue, u_int *cur_col, u_int wrap)
1460{
1461 return (ahc_print_register(NULL, 0, "SCB_64_SPARE",
1462 0xc0, regvalue, cur_col, wrap));
1463}
1464
1465static ahc_reg_parse_entry_t SEECTL_2840_parse_table[] = {
1466 { "DO_2840", 0x01, 0x01 },
1467 { "CK_2840", 0x02, 0x02 },
1468 { "CS_2840", 0x04, 0x04 }
1469};
1470
1471int
1472ahc_seectl_2840_print(u_int regvalue, u_int *cur_col, u_int wrap)
1473{
1474 return (ahc_print_register(SEECTL_2840_parse_table, 3, "SEECTL_2840",
1475 0xc0, regvalue, cur_col, wrap));
1476}
1477
1478static ahc_reg_parse_entry_t STATUS_2840_parse_table[] = {
1479 { "DI_2840", 0x01, 0x01 },
1480 { "EEPROM_TF", 0x80, 0x80 },
1481 { "ADSEL", 0x1e, 0x1e },
1482 { "BIOS_SEL", 0x60, 0x60 }
1483};
1484
1485int
1486ahc_status_2840_print(u_int regvalue, u_int *cur_col, u_int wrap)
1487{
1488 return (ahc_print_register(STATUS_2840_parse_table, 4, "STATUS_2840",
1489 0xc1, regvalue, cur_col, wrap));
1490}
1491
1492int
1493ahc_scb_64_btt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1494{
1495 return (ahc_print_register(NULL, 0, "SCB_64_BTT",
1496 0xd0, regvalue, cur_col, wrap));
1497}
1498
1499int
1500ahc_cchaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1501{
1502 return (ahc_print_register(NULL, 0, "CCHADDR",
1503 0xe0, regvalue, cur_col, wrap));
1504}
1505
1506int
1507ahc_cchcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1508{
1509 return (ahc_print_register(NULL, 0, "CCHCNT",
1510 0xe8, regvalue, cur_col, wrap));
1511}
1512
1513int
1514ahc_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap)
1515{
1516 return (ahc_print_register(NULL, 0, "CCSGRAM",
1517 0xe9, regvalue, cur_col, wrap));
1518}
1519
1520int
1521ahc_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1522{
1523 return (ahc_print_register(NULL, 0, "CCSGADDR",
1524 0xea, regvalue, cur_col, wrap));
1525}
1526
1527static ahc_reg_parse_entry_t CCSGCTL_parse_table[] = {
1528 { "CCSGRESET", 0x01, 0x01 },
1529 { "SG_FETCH_NEEDED", 0x02, 0x02 },
1530 { "CCSGEN", 0x08, 0x08 },
1531 { "CCSGDONE", 0x80, 0x80 }
1532};
1533
1534int
1535ahc_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
1536{
1537 return (ahc_print_register(CCSGCTL_parse_table, 4, "CCSGCTL",
1538 0xeb, regvalue, cur_col, wrap));
1539}
1540
1541int
1542ahc_ccscbram_print(u_int regvalue, u_int *cur_col, u_int wrap)
1543{
1544 return (ahc_print_register(NULL, 0, "CCSCBRAM",
1545 0xec, regvalue, cur_col, wrap));
1546}
1547
1548int
1549ahc_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1550{
1551 return (ahc_print_register(NULL, 0, "CCSCBADDR",
1552 0xed, regvalue, cur_col, wrap));
1553}
1554
1555static ahc_reg_parse_entry_t CCSCBCTL_parse_table[] = {
1556 { "CCSCBRESET", 0x01, 0x01 },
1557 { "CCSCBDIR", 0x04, 0x04 },
1558 { "CCSCBEN", 0x08, 0x08 },
1559 { "CCARREN", 0x10, 0x10 },
1560 { "ARRDONE", 0x40, 0x40 },
1561 { "CCSCBDONE", 0x80, 0x80 }
1562};
1563
1564int
1565ahc_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
1566{
1567 return (ahc_print_register(CCSCBCTL_parse_table, 6, "CCSCBCTL",
1568 0xee, regvalue, cur_col, wrap));
1569}
1570
1571int
1572ahc_ccscbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
1573{
1574 return (ahc_print_register(NULL, 0, "CCSCBCNT",
1575 0xef, regvalue, cur_col, wrap));
1576}
1577
1578int
1579ahc_scbbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1580{
1581 return (ahc_print_register(NULL, 0, "SCBBADDR",
1582 0xf0, regvalue, cur_col, wrap));
1583}
1584
1585int
1586ahc_ccscbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
1587{
1588 return (ahc_print_register(NULL, 0, "CCSCBPTR",
1589 0xf1, regvalue, cur_col, wrap));
1590}
1591
1592int
1593ahc_hnscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
1594{
1595 return (ahc_print_register(NULL, 0, "HNSCB_QOFF",
1596 0xf4, regvalue, cur_col, wrap));
1597}
1598
1599int
1600ahc_snscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
1601{
1602 return (ahc_print_register(NULL, 0, "SNSCB_QOFF",
1603 0xf6, regvalue, cur_col, wrap));
1604}
1605
1606int
1607ahc_sdscb_qoff_print(u_int regvalue, u_int *cur_col, u_int wrap)
1608{
1609 return (ahc_print_register(NULL, 0, "SDSCB_QOFF",
1610 0xf8, regvalue, cur_col, wrap));
1611}
1612
1613static ahc_reg_parse_entry_t QOFF_CTLSTA_parse_table[] = {
1614 { "SDSCB_ROLLOVER", 0x10, 0x10 },
1615 { "SNSCB_ROLLOVER", 0x20, 0x20 },
1616 { "SCB_AVAIL", 0x40, 0x40 },
1617 { "SCB_QSIZE_256", 0x06, 0x06 },
1618 { "SCB_QSIZE", 0x07, 0x07 }
1619};
1620
1621int
1622ahc_qoff_ctlsta_print(u_int regvalue, u_int *cur_col, u_int wrap)
1623{
1624 return (ahc_print_register(QOFF_CTLSTA_parse_table, 5, "QOFF_CTLSTA",
1625 0xfa, regvalue, cur_col, wrap));
1626}
1627
1628static ahc_reg_parse_entry_t DFF_THRSH_parse_table[] = {
1629 { "RD_DFTHRSH_MIN", 0x00, 0x00 },
1630 { "WR_DFTHRSH_MIN", 0x00, 0x00 },
1631 { "RD_DFTHRSH_25", 0x01, 0x01 },
1632 { "RD_DFTHRSH_50", 0x02, 0x02 },
1633 { "RD_DFTHRSH_63", 0x03, 0x03 },
1634 { "RD_DFTHRSH_75", 0x04, 0x04 },
1635 { "RD_DFTHRSH_85", 0x05, 0x05 },
1636 { "RD_DFTHRSH_90", 0x06, 0x06 },
1637 { "RD_DFTHRSH", 0x07, 0x07 },
1638 { "RD_DFTHRSH_MAX", 0x07, 0x07 },
1639 { "WR_DFTHRSH_25", 0x10, 0x10 },
1640 { "WR_DFTHRSH_50", 0x20, 0x20 },
1641 { "WR_DFTHRSH_63", 0x30, 0x30 },
1642 { "WR_DFTHRSH_75", 0x40, 0x40 },
1643 { "WR_DFTHRSH_85", 0x50, 0x50 },
1644 { "WR_DFTHRSH_90", 0x60, 0x60 },
1645 { "WR_DFTHRSH", 0x70, 0x70 },
1646 { "WR_DFTHRSH_MAX", 0x70, 0x70 }
1647};
1648
1649int
1650ahc_dff_thrsh_print(u_int regvalue, u_int *cur_col, u_int wrap)
1651{
1652 return (ahc_print_register(DFF_THRSH_parse_table, 18, "DFF_THRSH",
1653 0xfb, regvalue, cur_col, wrap));
1654}
1655
1656static ahc_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = {
1657 { "LAST_SEG_DONE", 0x01, 0x01 },
1658 { "LAST_SEG", 0x02, 0x02 },
1659 { "SG_ADDR_MASK", 0xf8, 0xf8 }
1660};
1661
1662int
1663ahc_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap)
1664{
1665 return (ahc_print_register(SG_CACHE_SHADOW_parse_table, 3, "SG_CACHE_SHADOW",
1666 0xfc, regvalue, cur_col, wrap));
1667}
1668
1669static ahc_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = {
1670 { "LAST_SEG_DONE", 0x01, 0x01 },
1671 { "LAST_SEG", 0x02, 0x02 },
1672 { "SG_ADDR_MASK", 0xf8, 0xf8 }
1673};
1674
1675int
1676ahc_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap)
1677{
1678 return (ahc_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE",
1679 0xfc, regvalue, cur_col, wrap));
1680}
1681
diff --git a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped
new file mode 100644
index 000000000000..cf411368a871
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped
@@ -0,0 +1,1307 @@
1/*
2 * DO NOT EDIT - This file is automatically generated
3 * from the following source files:
4 *
5 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
6 * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
7 */
8static uint8_t seqprog[] = {
9 0xb2, 0x00, 0x00, 0x08,
10 0xf7, 0x11, 0x22, 0x08,
11 0x00, 0x65, 0xec, 0x59,
12 0xf7, 0x01, 0x02, 0x08,
13 0xff, 0x6a, 0x24, 0x08,
14 0x40, 0x00, 0x40, 0x68,
15 0x08, 0x1f, 0x3e, 0x10,
16 0x40, 0x00, 0x40, 0x68,
17 0xff, 0x40, 0x3c, 0x60,
18 0x08, 0x1f, 0x3e, 0x10,
19 0x60, 0x0b, 0x42, 0x68,
20 0x40, 0xfa, 0x12, 0x78,
21 0x01, 0x4d, 0xc8, 0x30,
22 0x00, 0x4c, 0x12, 0x70,
23 0x01, 0x39, 0xa2, 0x30,
24 0x00, 0x6a, 0xc0, 0x5e,
25 0x01, 0x51, 0x20, 0x31,
26 0x01, 0x57, 0xae, 0x00,
27 0x0d, 0x6a, 0x76, 0x00,
28 0x00, 0x51, 0x12, 0x5e,
29 0x01, 0x51, 0xc8, 0x30,
30 0x00, 0x39, 0xc8, 0x60,
31 0x00, 0xbb, 0x30, 0x70,
32 0xc1, 0x6a, 0xd8, 0x5e,
33 0x01, 0xbf, 0x72, 0x30,
34 0x01, 0x40, 0x7e, 0x31,
35 0x01, 0x90, 0x80, 0x30,
36 0x01, 0xf6, 0xd4, 0x30,
37 0x01, 0x4d, 0x9a, 0x18,
38 0xfe, 0x57, 0xae, 0x08,
39 0x01, 0x40, 0x20, 0x31,
40 0x00, 0x65, 0xcc, 0x58,
41 0x60, 0x0b, 0x40, 0x78,
42 0x08, 0x6a, 0x18, 0x00,
43 0x08, 0x11, 0x22, 0x00,
44 0x60, 0x0b, 0x00, 0x78,
45 0x40, 0x0b, 0xfa, 0x68,
46 0x80, 0x0b, 0xb6, 0x78,
47 0x20, 0x6a, 0x16, 0x00,
48 0xa4, 0x6a, 0x06, 0x00,
49 0x08, 0x6a, 0x78, 0x00,
50 0x01, 0x50, 0xc8, 0x30,
51 0xe0, 0x6a, 0xcc, 0x00,
52 0x48, 0x6a, 0xfc, 0x5d,
53 0x01, 0x6a, 0xdc, 0x01,
54 0x88, 0x6a, 0xcc, 0x00,
55 0x48, 0x6a, 0xfc, 0x5d,
56 0x01, 0x6a, 0x26, 0x01,
57 0xf0, 0x19, 0x7a, 0x08,
58 0x0f, 0x18, 0xc8, 0x08,
59 0x0f, 0x0f, 0xc8, 0x08,
60 0x0f, 0x05, 0xc8, 0x08,
61 0x00, 0x3d, 0x7a, 0x00,
62 0x08, 0x1f, 0x6e, 0x78,
63 0x80, 0x3d, 0x7a, 0x00,
64 0x01, 0x3d, 0xd8, 0x31,
65 0x01, 0x3d, 0x32, 0x31,
66 0x10, 0x03, 0x4e, 0x79,
67 0x00, 0x65, 0xf2, 0x58,
68 0x80, 0x66, 0xae, 0x78,
69 0x01, 0x66, 0xd8, 0x31,
70 0x01, 0x66, 0x32, 0x31,
71 0x3f, 0x66, 0x7c, 0x08,
72 0x40, 0x66, 0x82, 0x68,
73 0x01, 0x3c, 0x78, 0x00,
74 0x10, 0x03, 0x9e, 0x78,
75 0x00, 0x65, 0xf2, 0x58,
76 0xe0, 0x66, 0xc8, 0x18,
77 0x00, 0x65, 0xaa, 0x50,
78 0xdd, 0x66, 0xc8, 0x18,
79 0x00, 0x65, 0xaa, 0x48,
80 0x01, 0x66, 0xd8, 0x31,
81 0x01, 0x66, 0x32, 0x31,
82 0x10, 0x03, 0x4e, 0x79,
83 0x00, 0x65, 0xf2, 0x58,
84 0x01, 0x66, 0xd8, 0x31,
85 0x01, 0x66, 0x32, 0x31,
86 0x01, 0x66, 0xac, 0x30,
87 0x40, 0x3c, 0x78, 0x00,
88 0xff, 0x6a, 0xd8, 0x01,
89 0xff, 0x6a, 0x32, 0x01,
90 0x10, 0x3c, 0x78, 0x00,
91 0x02, 0x57, 0x40, 0x69,
92 0x10, 0x03, 0x3e, 0x69,
93 0x00, 0x65, 0x20, 0x41,
94 0x02, 0x57, 0xae, 0x00,
95 0x00, 0x65, 0x9e, 0x40,
96 0x61, 0x6a, 0xd8, 0x5e,
97 0x08, 0x51, 0x20, 0x71,
98 0x02, 0x0b, 0xb2, 0x78,
99 0x00, 0x65, 0xae, 0x40,
100 0x1a, 0x01, 0x02, 0x00,
101 0xf0, 0x19, 0x7a, 0x08,
102 0x0f, 0x0f, 0xc8, 0x08,
103 0x0f, 0x05, 0xc8, 0x08,
104 0x00, 0x3d, 0x7a, 0x00,
105 0x08, 0x1f, 0xc4, 0x78,
106 0x80, 0x3d, 0x7a, 0x00,
107 0x20, 0x6a, 0x16, 0x00,
108 0x00, 0x65, 0xcc, 0x41,
109 0x00, 0x65, 0xb2, 0x5e,
110 0x00, 0x65, 0x12, 0x40,
111 0x20, 0x11, 0xd2, 0x68,
112 0x20, 0x6a, 0x18, 0x00,
113 0x20, 0x11, 0x22, 0x00,
114 0xf7, 0x1f, 0xca, 0x08,
115 0x80, 0xb9, 0xd8, 0x78,
116 0x08, 0x65, 0xca, 0x00,
117 0x01, 0x65, 0x3e, 0x30,
118 0x01, 0xb9, 0x1e, 0x30,
119 0x7f, 0xb9, 0x0a, 0x08,
120 0x01, 0xb9, 0x0a, 0x30,
121 0x01, 0x54, 0xca, 0x30,
122 0x80, 0xb8, 0xe6, 0x78,
123 0x80, 0x65, 0xca, 0x00,
124 0x01, 0x65, 0x00, 0x34,
125 0x01, 0x54, 0x00, 0x34,
126 0x08, 0xb8, 0xee, 0x78,
127 0x20, 0x01, 0x02, 0x00,
128 0x02, 0xbd, 0x08, 0x34,
129 0x01, 0xbd, 0x08, 0x34,
130 0x08, 0x01, 0x02, 0x00,
131 0x02, 0x0b, 0xf4, 0x78,
132 0xf7, 0x01, 0x02, 0x08,
133 0x01, 0x06, 0xcc, 0x34,
134 0xb2, 0x00, 0x00, 0x08,
135 0x01, 0x40, 0x20, 0x31,
136 0x01, 0xbf, 0x80, 0x30,
137 0x01, 0xb9, 0x7a, 0x30,
138 0x3f, 0xba, 0x7c, 0x08,
139 0x00, 0x65, 0xea, 0x58,
140 0x80, 0x0b, 0xc4, 0x79,
141 0x12, 0x01, 0x02, 0x00,
142 0x01, 0xab, 0xac, 0x30,
143 0xe4, 0x6a, 0x6e, 0x5d,
144 0x40, 0x6a, 0x16, 0x00,
145 0x80, 0x3e, 0x84, 0x5d,
146 0x20, 0xb8, 0x18, 0x79,
147 0x20, 0x6a, 0x84, 0x5d,
148 0x00, 0xab, 0x84, 0x5d,
149 0x01, 0xa9, 0x78, 0x30,
150 0x10, 0xb8, 0x20, 0x79,
151 0xe4, 0x6a, 0x6e, 0x5d,
152 0x00, 0x65, 0xae, 0x40,
153 0x10, 0x03, 0x3c, 0x69,
154 0x08, 0x3c, 0x5a, 0x69,
155 0x04, 0x3c, 0x92, 0x69,
156 0x02, 0x3c, 0x98, 0x69,
157 0x01, 0x3c, 0x44, 0x79,
158 0xff, 0x6a, 0x70, 0x00,
159 0x00, 0x65, 0xa4, 0x59,
160 0x00, 0x6a, 0xc0, 0x5e,
161 0xff, 0x38, 0x30, 0x71,
162 0x0d, 0x6a, 0x76, 0x00,
163 0x00, 0x38, 0x12, 0x5e,
164 0x00, 0x65, 0xea, 0x58,
165 0x12, 0x01, 0x02, 0x00,
166 0x00, 0x65, 0x18, 0x41,
167 0xa4, 0x6a, 0x06, 0x00,
168 0x00, 0x65, 0xf2, 0x58,
169 0xfd, 0x57, 0xae, 0x08,
170 0x00, 0x65, 0xae, 0x40,
171 0xe4, 0x6a, 0x6e, 0x5d,
172 0x20, 0x3c, 0x4a, 0x79,
173 0x02, 0x6a, 0x84, 0x5d,
174 0x04, 0x6a, 0x84, 0x5d,
175 0x01, 0x03, 0x4c, 0x69,
176 0xf7, 0x11, 0x22, 0x08,
177 0xff, 0x6a, 0x24, 0x08,
178 0xff, 0x6a, 0x06, 0x08,
179 0x01, 0x6a, 0x7e, 0x00,
180 0x00, 0x65, 0xa4, 0x59,
181 0x00, 0x65, 0x04, 0x40,
182 0x80, 0x86, 0xc8, 0x08,
183 0x01, 0x4f, 0xc8, 0x30,
184 0x00, 0x50, 0x6c, 0x61,
185 0xc4, 0x6a, 0x6e, 0x5d,
186 0x40, 0x3c, 0x68, 0x79,
187 0x28, 0x6a, 0x84, 0x5d,
188 0x00, 0x65, 0x4c, 0x41,
189 0x08, 0x6a, 0x84, 0x5d,
190 0x00, 0x65, 0x4c, 0x41,
191 0x84, 0x6a, 0x6e, 0x5d,
192 0x00, 0x65, 0xf2, 0x58,
193 0x01, 0x66, 0xc8, 0x30,
194 0x01, 0x64, 0xd8, 0x31,
195 0x01, 0x64, 0x32, 0x31,
196 0x5b, 0x64, 0xc8, 0x28,
197 0x30, 0x64, 0xca, 0x18,
198 0x01, 0x6c, 0xc8, 0x30,
199 0xff, 0x64, 0x8e, 0x79,
200 0x08, 0x01, 0x02, 0x00,
201 0x02, 0x0b, 0x80, 0x79,
202 0x01, 0x64, 0x86, 0x61,
203 0xf7, 0x01, 0x02, 0x08,
204 0x01, 0x06, 0xd8, 0x31,
205 0x01, 0x06, 0x32, 0x31,
206 0xff, 0x64, 0xc8, 0x18,
207 0xff, 0x64, 0x80, 0x69,
208 0xf7, 0x3c, 0x78, 0x08,
209 0x00, 0x65, 0x20, 0x41,
210 0x40, 0xaa, 0x7e, 0x10,
211 0x04, 0xaa, 0x6e, 0x5d,
212 0x00, 0x65, 0x56, 0x42,
213 0xc4, 0x6a, 0x6e, 0x5d,
214 0xc0, 0x6a, 0x7e, 0x00,
215 0x00, 0xa8, 0x84, 0x5d,
216 0xe4, 0x6a, 0x06, 0x00,
217 0x00, 0x6a, 0x84, 0x5d,
218 0x00, 0x65, 0x4c, 0x41,
219 0x10, 0x3c, 0xa8, 0x69,
220 0x00, 0xbb, 0x8a, 0x44,
221 0x18, 0x6a, 0xda, 0x01,
222 0x01, 0x69, 0xd8, 0x31,
223 0x1c, 0x6a, 0xd0, 0x01,
224 0x09, 0xee, 0xdc, 0x01,
225 0x80, 0xee, 0xb0, 0x79,
226 0xff, 0x6a, 0xdc, 0x09,
227 0x01, 0x93, 0x26, 0x01,
228 0x03, 0x6a, 0x2a, 0x01,
229 0x01, 0x69, 0x32, 0x31,
230 0x1c, 0x6a, 0xe0, 0x5d,
231 0x0a, 0x93, 0x26, 0x01,
232 0x00, 0x65, 0xa8, 0x5e,
233 0x01, 0x50, 0xa0, 0x18,
234 0x02, 0x6a, 0x22, 0x05,
235 0x1a, 0x01, 0x02, 0x00,
236 0x80, 0x6a, 0x74, 0x00,
237 0x40, 0x6a, 0x78, 0x00,
238 0x40, 0x6a, 0x16, 0x00,
239 0x00, 0x65, 0xd8, 0x5d,
240 0x01, 0x3f, 0xc8, 0x30,
241 0xbf, 0x64, 0x56, 0x7a,
242 0x80, 0x64, 0x9e, 0x73,
243 0xa0, 0x64, 0x00, 0x74,
244 0xc0, 0x64, 0xf4, 0x73,
245 0xe0, 0x64, 0x30, 0x74,
246 0x01, 0x6a, 0xd8, 0x5e,
247 0x00, 0x65, 0xcc, 0x41,
248 0xf7, 0x11, 0x22, 0x08,
249 0x01, 0x06, 0xd4, 0x30,
250 0xff, 0x6a, 0x24, 0x08,
251 0xf7, 0x01, 0x02, 0x08,
252 0x09, 0x0c, 0xe6, 0x79,
253 0x08, 0x0c, 0x04, 0x68,
254 0xb1, 0x6a, 0xd8, 0x5e,
255 0xff, 0x6a, 0x26, 0x09,
256 0x12, 0x01, 0x02, 0x00,
257 0x02, 0x6a, 0x08, 0x30,
258 0xff, 0x6a, 0x08, 0x08,
259 0xdf, 0x01, 0x02, 0x08,
260 0x01, 0x6a, 0x7e, 0x00,
261 0xc0, 0x6a, 0x78, 0x04,
262 0xff, 0x6a, 0xc8, 0x08,
263 0x08, 0xa4, 0x48, 0x19,
264 0x00, 0xa5, 0x4a, 0x21,
265 0x00, 0xa6, 0x4c, 0x21,
266 0x00, 0xa7, 0x4e, 0x25,
267 0x08, 0xeb, 0xdc, 0x7e,
268 0x80, 0xeb, 0x06, 0x7a,
269 0xff, 0x6a, 0xd6, 0x09,
270 0x08, 0xeb, 0x0a, 0x6a,
271 0xff, 0x6a, 0xd4, 0x0c,
272 0x80, 0xa3, 0xdc, 0x6e,
273 0x88, 0xeb, 0x20, 0x72,
274 0x08, 0xeb, 0xdc, 0x6e,
275 0x04, 0xea, 0x24, 0xe2,
276 0x08, 0xee, 0xdc, 0x6e,
277 0x04, 0x6a, 0xd0, 0x81,
278 0x05, 0xa4, 0xc0, 0x89,
279 0x03, 0xa5, 0xc2, 0x31,
280 0x09, 0x6a, 0xd6, 0x05,
281 0x00, 0x65, 0x08, 0x5a,
282 0x06, 0xa4, 0xd4, 0x89,
283 0x80, 0x94, 0xdc, 0x7e,
284 0x07, 0xe9, 0x10, 0x31,
285 0x01, 0xe9, 0x46, 0x31,
286 0x00, 0xa3, 0xba, 0x5e,
287 0x00, 0x65, 0xfa, 0x59,
288 0x01, 0xa4, 0xca, 0x30,
289 0x80, 0xa3, 0x34, 0x7a,
290 0x02, 0x65, 0xca, 0x00,
291 0x01, 0x65, 0xf8, 0x31,
292 0x80, 0x93, 0x26, 0x01,
293 0xff, 0x6a, 0xd4, 0x0c,
294 0x01, 0x8c, 0xc8, 0x30,
295 0x00, 0x88, 0xc8, 0x18,
296 0x02, 0x64, 0xc8, 0x88,
297 0xff, 0x64, 0xdc, 0x7e,
298 0xff, 0x8d, 0x4a, 0x6a,
299 0xff, 0x8e, 0x4a, 0x6a,
300 0x03, 0x8c, 0xd4, 0x98,
301 0x00, 0x65, 0xdc, 0x56,
302 0x01, 0x64, 0x70, 0x30,
303 0xff, 0x64, 0xc8, 0x10,
304 0x01, 0x64, 0xc8, 0x18,
305 0x00, 0x8c, 0x18, 0x19,
306 0xff, 0x8d, 0x1a, 0x21,
307 0xff, 0x8e, 0x1c, 0x25,
308 0xc0, 0x3c, 0x5a, 0x7a,
309 0x21, 0x6a, 0xd8, 0x5e,
310 0xa8, 0x6a, 0x76, 0x00,
311 0x79, 0x6a, 0x76, 0x00,
312 0x40, 0x3f, 0x62, 0x6a,
313 0x04, 0x3b, 0x76, 0x00,
314 0x04, 0x6a, 0xd4, 0x81,
315 0x20, 0x3c, 0x6a, 0x7a,
316 0x51, 0x6a, 0xd8, 0x5e,
317 0x00, 0x65, 0x82, 0x42,
318 0x20, 0x3c, 0x78, 0x00,
319 0x00, 0xb3, 0xba, 0x5e,
320 0x07, 0xac, 0x10, 0x31,
321 0x05, 0xb3, 0x46, 0x31,
322 0x88, 0x6a, 0xcc, 0x00,
323 0xac, 0x6a, 0xee, 0x5d,
324 0xa3, 0x6a, 0xcc, 0x00,
325 0xb3, 0x6a, 0xf2, 0x5d,
326 0x00, 0x65, 0x3a, 0x5a,
327 0xfd, 0xa4, 0x48, 0x09,
328 0x03, 0x8c, 0x10, 0x30,
329 0x00, 0x65, 0xe6, 0x5d,
330 0x01, 0xa4, 0x94, 0x7a,
331 0x04, 0x3b, 0x76, 0x08,
332 0x01, 0x3b, 0x26, 0x31,
333 0x80, 0x02, 0x04, 0x00,
334 0x10, 0x0c, 0x8a, 0x7a,
335 0x03, 0x9e, 0x8c, 0x6a,
336 0x7f, 0x02, 0x04, 0x08,
337 0x91, 0x6a, 0xd8, 0x5e,
338 0x00, 0x65, 0xcc, 0x41,
339 0x01, 0xa4, 0xca, 0x30,
340 0x80, 0xa3, 0x9a, 0x7a,
341 0x02, 0x65, 0xca, 0x00,
342 0x01, 0x65, 0xf8, 0x31,
343 0x01, 0x3b, 0x26, 0x31,
344 0x00, 0x65, 0x0e, 0x5a,
345 0x01, 0xfc, 0xa8, 0x6a,
346 0x80, 0x0b, 0x9e, 0x6a,
347 0x10, 0x0c, 0x9e, 0x7a,
348 0x20, 0x93, 0x9e, 0x6a,
349 0x02, 0x93, 0x26, 0x01,
350 0x02, 0xfc, 0xb2, 0x7a,
351 0x40, 0x0d, 0xc6, 0x6a,
352 0x01, 0xa4, 0x48, 0x01,
353 0x00, 0x65, 0xc6, 0x42,
354 0x40, 0x0d, 0xb8, 0x6a,
355 0x00, 0x65, 0x0e, 0x5a,
356 0x00, 0x65, 0xaa, 0x42,
357 0x80, 0xfc, 0xc2, 0x7a,
358 0x80, 0xa4, 0xc2, 0x6a,
359 0xff, 0xa5, 0x4a, 0x19,
360 0xff, 0xa6, 0x4c, 0x21,
361 0xff, 0xa7, 0x4e, 0x21,
362 0xf8, 0xfc, 0x48, 0x09,
363 0x7f, 0xa3, 0x46, 0x09,
364 0x04, 0x3b, 0xe2, 0x6a,
365 0x02, 0x93, 0x26, 0x01,
366 0x01, 0x94, 0xc8, 0x7a,
367 0x01, 0x94, 0xc8, 0x7a,
368 0x01, 0x94, 0xc8, 0x7a,
369 0x01, 0x94, 0xc8, 0x7a,
370 0x01, 0x94, 0xc8, 0x7a,
371 0x01, 0xa4, 0xe0, 0x7a,
372 0x01, 0xfc, 0xd6, 0x7a,
373 0x01, 0x94, 0xe2, 0x6a,
374 0x01, 0x94, 0xe2, 0x6a,
375 0x01, 0x94, 0xe2, 0x6a,
376 0x00, 0x65, 0x82, 0x42,
377 0x01, 0x94, 0xe0, 0x7a,
378 0x10, 0x94, 0xe2, 0x6a,
379 0xd7, 0x93, 0x26, 0x09,
380 0x28, 0x93, 0xe6, 0x6a,
381 0x01, 0x85, 0x0a, 0x01,
382 0x02, 0xfc, 0xee, 0x6a,
383 0x01, 0x14, 0x46, 0x31,
384 0xff, 0x6a, 0x10, 0x09,
385 0xfe, 0x85, 0x0a, 0x09,
386 0xff, 0x38, 0xfc, 0x6a,
387 0x80, 0xa3, 0xfc, 0x7a,
388 0x80, 0x0b, 0xfa, 0x7a,
389 0x04, 0x3b, 0xfc, 0x7a,
390 0xbf, 0x3b, 0x76, 0x08,
391 0x01, 0x3b, 0x26, 0x31,
392 0x00, 0x65, 0x0e, 0x5a,
393 0x01, 0x0b, 0x0a, 0x6b,
394 0x10, 0x0c, 0xfe, 0x7a,
395 0x04, 0x93, 0x08, 0x6b,
396 0x01, 0x94, 0x06, 0x7b,
397 0x10, 0x94, 0x08, 0x6b,
398 0xc7, 0x93, 0x26, 0x09,
399 0x01, 0x99, 0xd4, 0x30,
400 0x38, 0x93, 0x0c, 0x6b,
401 0xff, 0x08, 0x5a, 0x6b,
402 0xff, 0x09, 0x5a, 0x6b,
403 0xff, 0x0a, 0x5a, 0x6b,
404 0xff, 0x38, 0x28, 0x7b,
405 0x04, 0x14, 0x10, 0x31,
406 0x01, 0x38, 0x18, 0x31,
407 0x02, 0x6a, 0x1a, 0x31,
408 0x88, 0x6a, 0xcc, 0x00,
409 0x14, 0x6a, 0xf4, 0x5d,
410 0x00, 0x38, 0xe0, 0x5d,
411 0xff, 0x6a, 0x70, 0x08,
412 0x00, 0x65, 0x54, 0x43,
413 0x80, 0xa3, 0x2e, 0x7b,
414 0x01, 0xa4, 0x48, 0x01,
415 0x00, 0x65, 0x5a, 0x43,
416 0x08, 0xeb, 0x34, 0x7b,
417 0x00, 0x65, 0x0e, 0x5a,
418 0x08, 0xeb, 0x30, 0x6b,
419 0x07, 0xe9, 0x10, 0x31,
420 0x01, 0xe9, 0xca, 0x30,
421 0x01, 0x65, 0x46, 0x31,
422 0x00, 0x6a, 0xba, 0x5e,
423 0x88, 0x6a, 0xcc, 0x00,
424 0xa4, 0x6a, 0xf4, 0x5d,
425 0x08, 0x6a, 0xe0, 0x5d,
426 0x0d, 0x93, 0x26, 0x01,
427 0x00, 0x65, 0xa8, 0x5e,
428 0x88, 0x6a, 0xcc, 0x00,
429 0x00, 0x65, 0x8a, 0x5e,
430 0x01, 0x99, 0x46, 0x31,
431 0x00, 0xa3, 0xba, 0x5e,
432 0x01, 0x88, 0x10, 0x31,
433 0x00, 0x65, 0x3a, 0x5a,
434 0x00, 0x65, 0xfa, 0x59,
435 0x03, 0x8c, 0x10, 0x30,
436 0x00, 0x65, 0xe6, 0x5d,
437 0x80, 0x0b, 0x82, 0x6a,
438 0x80, 0x0b, 0x62, 0x6b,
439 0x01, 0x0c, 0x5c, 0x7b,
440 0x10, 0x0c, 0x82, 0x7a,
441 0x03, 0x9e, 0x82, 0x6a,
442 0x00, 0x65, 0x04, 0x5a,
443 0x00, 0x6a, 0xba, 0x5e,
444 0x01, 0xa4, 0x82, 0x6b,
445 0xff, 0x38, 0x78, 0x7b,
446 0x01, 0x38, 0xc8, 0x30,
447 0x00, 0x08, 0x40, 0x19,
448 0xff, 0x6a, 0xc8, 0x08,
449 0x00, 0x09, 0x42, 0x21,
450 0x00, 0x0a, 0x44, 0x21,
451 0xff, 0x6a, 0x70, 0x08,
452 0x00, 0x65, 0x7a, 0x43,
453 0x03, 0x08, 0x40, 0x31,
454 0x03, 0x08, 0x40, 0x31,
455 0x01, 0x08, 0x40, 0x31,
456 0x01, 0x09, 0x42, 0x31,
457 0x01, 0x0a, 0x44, 0x31,
458 0xfd, 0xb4, 0x68, 0x09,
459 0x12, 0x01, 0x02, 0x00,
460 0x12, 0x01, 0x02, 0x00,
461 0x04, 0x3c, 0xcc, 0x79,
462 0xfb, 0x3c, 0x78, 0x08,
463 0x04, 0x93, 0x20, 0x79,
464 0x01, 0x0c, 0x8e, 0x6b,
465 0x80, 0xba, 0x20, 0x79,
466 0x80, 0x04, 0x20, 0x79,
467 0xe4, 0x6a, 0x6e, 0x5d,
468 0x23, 0x6a, 0x84, 0x5d,
469 0x01, 0x6a, 0x84, 0x5d,
470 0x00, 0x65, 0x20, 0x41,
471 0x00, 0x65, 0xcc, 0x41,
472 0x80, 0x3c, 0xa2, 0x7b,
473 0x21, 0x6a, 0xd8, 0x5e,
474 0x01, 0xbc, 0x18, 0x31,
475 0x02, 0x6a, 0x1a, 0x31,
476 0x02, 0x6a, 0xf8, 0x01,
477 0x01, 0xbc, 0x10, 0x30,
478 0x02, 0x6a, 0x12, 0x30,
479 0x01, 0xbc, 0x10, 0x30,
480 0xff, 0x6a, 0x12, 0x08,
481 0xff, 0x6a, 0x14, 0x08,
482 0xf3, 0xbc, 0xd4, 0x18,
483 0xa0, 0x6a, 0xc8, 0x53,
484 0x04, 0xa0, 0x10, 0x31,
485 0xac, 0x6a, 0x26, 0x01,
486 0x04, 0xa0, 0x10, 0x31,
487 0x03, 0x08, 0x18, 0x31,
488 0x88, 0x6a, 0xcc, 0x00,
489 0xa0, 0x6a, 0xf4, 0x5d,
490 0x00, 0xbc, 0xe0, 0x5d,
491 0x3d, 0x6a, 0x26, 0x01,
492 0x00, 0x65, 0xe0, 0x43,
493 0xff, 0x6a, 0x10, 0x09,
494 0xa4, 0x6a, 0x26, 0x01,
495 0x0c, 0xa0, 0x32, 0x31,
496 0x05, 0x6a, 0x26, 0x01,
497 0x35, 0x6a, 0x26, 0x01,
498 0x0c, 0xa0, 0x32, 0x31,
499 0x36, 0x6a, 0x26, 0x01,
500 0x02, 0x93, 0x26, 0x01,
501 0x35, 0x6a, 0x26, 0x01,
502 0x00, 0x65, 0x9c, 0x5e,
503 0x00, 0x65, 0x9c, 0x5e,
504 0x02, 0x93, 0x26, 0x01,
505 0xbf, 0x3c, 0x78, 0x08,
506 0x04, 0x0b, 0xe6, 0x6b,
507 0x10, 0x0c, 0xe2, 0x7b,
508 0x01, 0x03, 0xe6, 0x6b,
509 0x20, 0x93, 0xe8, 0x6b,
510 0x04, 0x0b, 0xee, 0x6b,
511 0x40, 0x3c, 0x78, 0x00,
512 0xc7, 0x93, 0x26, 0x09,
513 0x38, 0x93, 0xf0, 0x6b,
514 0x00, 0x65, 0xcc, 0x41,
515 0x80, 0x3c, 0x56, 0x6c,
516 0x01, 0x06, 0x50, 0x31,
517 0x80, 0xb8, 0x70, 0x01,
518 0x00, 0x65, 0xcc, 0x41,
519 0x10, 0x3f, 0x06, 0x00,
520 0x10, 0x6a, 0x06, 0x00,
521 0x01, 0x3a, 0xca, 0x30,
522 0x80, 0x65, 0x1c, 0x64,
523 0x10, 0xb8, 0x40, 0x6c,
524 0xc0, 0x3e, 0xca, 0x00,
525 0x40, 0xb8, 0x0c, 0x6c,
526 0xbf, 0x65, 0xca, 0x08,
527 0x20, 0xb8, 0x20, 0x7c,
528 0x01, 0x65, 0x0c, 0x30,
529 0x00, 0x65, 0xd8, 0x5d,
530 0xa0, 0x3f, 0x28, 0x64,
531 0x23, 0xb8, 0x0c, 0x08,
532 0x00, 0x65, 0xd8, 0x5d,
533 0xa0, 0x3f, 0x28, 0x64,
534 0x00, 0xbb, 0x20, 0x44,
535 0xff, 0x65, 0x20, 0x64,
536 0x00, 0x65, 0x40, 0x44,
537 0x40, 0x6a, 0x18, 0x00,
538 0x01, 0x65, 0x0c, 0x30,
539 0x00, 0x65, 0xd8, 0x5d,
540 0xa0, 0x3f, 0xfc, 0x73,
541 0x40, 0x6a, 0x18, 0x00,
542 0x01, 0x3a, 0xa6, 0x30,
543 0x08, 0x6a, 0x74, 0x00,
544 0x00, 0x65, 0xcc, 0x41,
545 0x64, 0x6a, 0x68, 0x5d,
546 0x80, 0x64, 0xd8, 0x6c,
547 0x04, 0x64, 0x9a, 0x74,
548 0x02, 0x64, 0xaa, 0x74,
549 0x00, 0x6a, 0x60, 0x74,
550 0x03, 0x64, 0xc8, 0x74,
551 0x23, 0x64, 0x48, 0x74,
552 0x08, 0x64, 0x5c, 0x74,
553 0x61, 0x6a, 0xd8, 0x5e,
554 0x00, 0x65, 0xd8, 0x5d,
555 0x08, 0x51, 0xce, 0x71,
556 0x00, 0x65, 0x40, 0x44,
557 0x80, 0x04, 0x5a, 0x7c,
558 0x51, 0x6a, 0x5e, 0x5d,
559 0x01, 0x51, 0x5a, 0x64,
560 0x01, 0xa4, 0x52, 0x7c,
561 0x80, 0xba, 0x5c, 0x6c,
562 0x41, 0x6a, 0xd8, 0x5e,
563 0x00, 0x65, 0x5c, 0x44,
564 0x21, 0x6a, 0xd8, 0x5e,
565 0x00, 0x65, 0x5c, 0x44,
566 0x07, 0x6a, 0x54, 0x5d,
567 0x01, 0x06, 0xd4, 0x30,
568 0x00, 0x65, 0xcc, 0x41,
569 0x80, 0xb8, 0x56, 0x7c,
570 0xc0, 0x3c, 0x6a, 0x7c,
571 0x80, 0x3c, 0x56, 0x6c,
572 0xff, 0xa8, 0x6a, 0x6c,
573 0x40, 0x3c, 0x56, 0x6c,
574 0x10, 0xb8, 0x6e, 0x7c,
575 0xa1, 0x6a, 0xd8, 0x5e,
576 0x01, 0xb4, 0x74, 0x6c,
577 0x02, 0xb4, 0x76, 0x6c,
578 0x01, 0xa4, 0x76, 0x7c,
579 0xff, 0xa8, 0x86, 0x7c,
580 0x04, 0xb4, 0x68, 0x01,
581 0x01, 0x6a, 0x76, 0x00,
582 0x00, 0xbb, 0x12, 0x5e,
583 0xff, 0xa8, 0x86, 0x7c,
584 0x71, 0x6a, 0xd8, 0x5e,
585 0x40, 0x51, 0x86, 0x64,
586 0x00, 0x65, 0xb2, 0x5e,
587 0x00, 0x65, 0xde, 0x41,
588 0x00, 0xbb, 0x8a, 0x5c,
589 0x00, 0x65, 0xde, 0x41,
590 0x00, 0x65, 0xb2, 0x5e,
591 0x01, 0x65, 0xa2, 0x30,
592 0x01, 0xf8, 0xc8, 0x30,
593 0x01, 0x4e, 0xc8, 0x30,
594 0x00, 0x6a, 0xb6, 0xdd,
595 0x00, 0x51, 0xc8, 0x5d,
596 0x01, 0x4e, 0x9c, 0x18,
597 0x02, 0x6a, 0x22, 0x05,
598 0xc0, 0x3c, 0x56, 0x6c,
599 0x04, 0xb8, 0x70, 0x01,
600 0x00, 0x65, 0xd4, 0x5e,
601 0x20, 0xb8, 0xde, 0x69,
602 0x01, 0xbb, 0xa2, 0x30,
603 0x3f, 0xba, 0x7c, 0x08,
604 0x00, 0xb9, 0xce, 0x5c,
605 0x00, 0x65, 0xde, 0x41,
606 0x01, 0x06, 0xd4, 0x30,
607 0x20, 0x3c, 0xcc, 0x79,
608 0x20, 0x3c, 0x5c, 0x7c,
609 0x01, 0xa4, 0xb8, 0x7c,
610 0x01, 0xb4, 0x68, 0x01,
611 0x00, 0x65, 0xcc, 0x41,
612 0x00, 0x65, 0x5c, 0x44,
613 0x04, 0x14, 0x58, 0x31,
614 0x01, 0x06, 0xd4, 0x30,
615 0x08, 0xa0, 0x60, 0x31,
616 0xac, 0x6a, 0xcc, 0x00,
617 0x14, 0x6a, 0xf4, 0x5d,
618 0x01, 0x06, 0xd4, 0x30,
619 0xa0, 0x6a, 0xec, 0x5d,
620 0x00, 0x65, 0xcc, 0x41,
621 0xdf, 0x3c, 0x78, 0x08,
622 0x12, 0x01, 0x02, 0x00,
623 0x00, 0x65, 0x5c, 0x44,
624 0x4c, 0x65, 0xcc, 0x28,
625 0x01, 0x3e, 0x20, 0x31,
626 0xd0, 0x66, 0xcc, 0x18,
627 0x20, 0x66, 0xcc, 0x18,
628 0x01, 0x51, 0xda, 0x34,
629 0x4c, 0x3d, 0xca, 0x28,
630 0x3f, 0x64, 0x7c, 0x08,
631 0xd0, 0x65, 0xca, 0x18,
632 0x01, 0x3e, 0x20, 0x31,
633 0x30, 0x65, 0xd4, 0x18,
634 0x00, 0x65, 0xe6, 0x4c,
635 0xe1, 0x6a, 0x22, 0x01,
636 0xff, 0x6a, 0xd4, 0x08,
637 0x20, 0x65, 0xd4, 0x18,
638 0x00, 0x65, 0xee, 0x54,
639 0xe1, 0x6a, 0x22, 0x01,
640 0xff, 0x6a, 0xd4, 0x08,
641 0x20, 0x65, 0xca, 0x18,
642 0xe0, 0x65, 0xd4, 0x18,
643 0x00, 0x65, 0xf8, 0x4c,
644 0xe1, 0x6a, 0x22, 0x01,
645 0xff, 0x6a, 0xd4, 0x08,
646 0xd0, 0x65, 0xd4, 0x18,
647 0x00, 0x65, 0x00, 0x55,
648 0xe1, 0x6a, 0x22, 0x01,
649 0xff, 0x6a, 0xd4, 0x08,
650 0x01, 0x6c, 0xa2, 0x30,
651 0xff, 0x51, 0x12, 0x75,
652 0x00, 0x51, 0x8e, 0x5d,
653 0x01, 0x51, 0x20, 0x31,
654 0x00, 0x65, 0x34, 0x45,
655 0x3f, 0xba, 0xc8, 0x08,
656 0x00, 0x3e, 0x34, 0x75,
657 0x00, 0x65, 0xb0, 0x5e,
658 0x80, 0x3c, 0x78, 0x00,
659 0x01, 0x06, 0xd4, 0x30,
660 0x00, 0x65, 0xd8, 0x5d,
661 0x01, 0x3c, 0x78, 0x00,
662 0xe0, 0x3f, 0x50, 0x65,
663 0x02, 0x3c, 0x78, 0x00,
664 0x20, 0x12, 0x50, 0x65,
665 0x51, 0x6a, 0x5e, 0x5d,
666 0x00, 0x51, 0x8e, 0x5d,
667 0x51, 0x6a, 0x5e, 0x5d,
668 0x01, 0x51, 0x20, 0x31,
669 0x04, 0x3c, 0x78, 0x00,
670 0x01, 0xb9, 0xc8, 0x30,
671 0x00, 0x3d, 0x4e, 0x65,
672 0x08, 0x3c, 0x78, 0x00,
673 0x3f, 0xba, 0xc8, 0x08,
674 0x00, 0x3e, 0x4e, 0x65,
675 0x10, 0x3c, 0x78, 0x00,
676 0x04, 0xb8, 0x4e, 0x7d,
677 0xfb, 0xb8, 0x70, 0x09,
678 0x20, 0xb8, 0x44, 0x6d,
679 0x01, 0x90, 0xc8, 0x30,
680 0xff, 0x6a, 0xa2, 0x00,
681 0x00, 0x3d, 0xce, 0x5c,
682 0x01, 0x64, 0x20, 0x31,
683 0xff, 0x6a, 0x78, 0x08,
684 0x00, 0x65, 0xea, 0x58,
685 0x10, 0xb8, 0x5c, 0x7c,
686 0xff, 0x6a, 0x54, 0x5d,
687 0x00, 0x65, 0x5c, 0x44,
688 0x00, 0x65, 0xb0, 0x5e,
689 0x31, 0x6a, 0xd8, 0x5e,
690 0x00, 0x65, 0x5c, 0x44,
691 0x10, 0x3f, 0x06, 0x00,
692 0x10, 0x6a, 0x06, 0x00,
693 0x01, 0x65, 0x74, 0x34,
694 0x81, 0x6a, 0xd8, 0x5e,
695 0x00, 0x65, 0x60, 0x45,
696 0x01, 0x06, 0xd4, 0x30,
697 0x01, 0x0c, 0x60, 0x7d,
698 0x04, 0x0c, 0x5a, 0x6d,
699 0xe0, 0x03, 0x7e, 0x08,
700 0xe0, 0x3f, 0xcc, 0x61,
701 0x01, 0x65, 0xcc, 0x30,
702 0x01, 0x12, 0xda, 0x34,
703 0x01, 0x06, 0xd4, 0x34,
704 0x01, 0x03, 0x6e, 0x6d,
705 0x40, 0x03, 0xcc, 0x08,
706 0x01, 0x65, 0x06, 0x30,
707 0x40, 0x65, 0xc8, 0x08,
708 0x00, 0x66, 0x7c, 0x75,
709 0x40, 0x65, 0x7c, 0x7d,
710 0x00, 0x65, 0x7c, 0x5d,
711 0xff, 0x6a, 0xd4, 0x08,
712 0xff, 0x6a, 0xd4, 0x08,
713 0xff, 0x6a, 0xd4, 0x08,
714 0xff, 0x6a, 0xd4, 0x0c,
715 0x08, 0x01, 0x02, 0x00,
716 0x02, 0x0b, 0x86, 0x7d,
717 0x01, 0x65, 0x0c, 0x30,
718 0x02, 0x0b, 0x8a, 0x7d,
719 0xf7, 0x01, 0x02, 0x0c,
720 0x01, 0x65, 0xc8, 0x30,
721 0xff, 0x41, 0xae, 0x75,
722 0x01, 0x41, 0x20, 0x31,
723 0xff, 0x6a, 0xa4, 0x00,
724 0x00, 0x65, 0x9e, 0x45,
725 0xff, 0xbf, 0xae, 0x75,
726 0x01, 0x90, 0xa4, 0x30,
727 0x01, 0xbf, 0x20, 0x31,
728 0x00, 0xbb, 0x98, 0x65,
729 0xff, 0x52, 0xac, 0x75,
730 0x01, 0xbf, 0xcc, 0x30,
731 0x01, 0x90, 0xca, 0x30,
732 0x01, 0x52, 0x20, 0x31,
733 0x01, 0x66, 0x7e, 0x31,
734 0x01, 0x65, 0x20, 0x35,
735 0x01, 0xbf, 0x82, 0x34,
736 0x01, 0x64, 0xa2, 0x30,
737 0x00, 0x6a, 0xc0, 0x5e,
738 0x0d, 0x6a, 0x76, 0x00,
739 0x00, 0x51, 0x12, 0x46,
740 0x01, 0x65, 0xa4, 0x30,
741 0xe0, 0x6a, 0xcc, 0x00,
742 0x48, 0x6a, 0x06, 0x5e,
743 0x01, 0x6a, 0xd0, 0x01,
744 0x01, 0x6a, 0xdc, 0x05,
745 0x88, 0x6a, 0xcc, 0x00,
746 0x48, 0x6a, 0x06, 0x5e,
747 0x01, 0x6a, 0xe0, 0x5d,
748 0x01, 0x6a, 0x26, 0x05,
749 0x01, 0x65, 0xd8, 0x31,
750 0x09, 0xee, 0xdc, 0x01,
751 0x80, 0xee, 0xcc, 0x7d,
752 0xff, 0x6a, 0xdc, 0x0d,
753 0x01, 0x65, 0x32, 0x31,
754 0x0a, 0x93, 0x26, 0x01,
755 0x00, 0x65, 0xa8, 0x46,
756 0x81, 0x6a, 0xd8, 0x5e,
757 0x01, 0x0c, 0xd8, 0x7d,
758 0x04, 0x0c, 0xd6, 0x6d,
759 0xe0, 0x03, 0x06, 0x08,
760 0xe0, 0x03, 0x7e, 0x0c,
761 0x01, 0x65, 0x18, 0x31,
762 0xff, 0x6a, 0x1a, 0x09,
763 0xff, 0x6a, 0x1c, 0x0d,
764 0x01, 0x8c, 0x10, 0x30,
765 0x01, 0x8d, 0x12, 0x30,
766 0x01, 0x8e, 0x14, 0x34,
767 0x01, 0x6c, 0xda, 0x30,
768 0x01, 0x6c, 0xda, 0x30,
769 0x01, 0x6c, 0xda, 0x30,
770 0x01, 0x6c, 0xda, 0x30,
771 0x01, 0x6c, 0xda, 0x30,
772 0x01, 0x6c, 0xda, 0x30,
773 0x01, 0x6c, 0xda, 0x30,
774 0x01, 0x6c, 0xda, 0x34,
775 0x3d, 0x64, 0xa4, 0x28,
776 0x55, 0x64, 0xc8, 0x28,
777 0x00, 0x65, 0x06, 0x46,
778 0x2e, 0x64, 0xa4, 0x28,
779 0x66, 0x64, 0xc8, 0x28,
780 0x00, 0x6c, 0xda, 0x18,
781 0x01, 0x52, 0xc8, 0x30,
782 0x00, 0x6c, 0xda, 0x20,
783 0xff, 0x6a, 0xc8, 0x08,
784 0x00, 0x6c, 0xda, 0x20,
785 0x00, 0x6c, 0xda, 0x24,
786 0x01, 0x65, 0xc8, 0x30,
787 0xe0, 0x6a, 0xcc, 0x00,
788 0x44, 0x6a, 0x02, 0x5e,
789 0x01, 0x90, 0xe2, 0x31,
790 0x04, 0x3b, 0x26, 0x7e,
791 0x30, 0x6a, 0xd0, 0x01,
792 0x20, 0x6a, 0xd0, 0x01,
793 0x1d, 0x6a, 0xdc, 0x01,
794 0xdc, 0xee, 0x22, 0x66,
795 0x00, 0x65, 0x3e, 0x46,
796 0x20, 0x6a, 0xd0, 0x01,
797 0x01, 0x6a, 0xdc, 0x01,
798 0x20, 0xa0, 0xd8, 0x31,
799 0x09, 0xee, 0xdc, 0x01,
800 0x80, 0xee, 0x2e, 0x7e,
801 0x11, 0x6a, 0xdc, 0x01,
802 0x50, 0xee, 0x32, 0x66,
803 0x20, 0x6a, 0xd0, 0x01,
804 0x09, 0x6a, 0xdc, 0x01,
805 0x88, 0xee, 0x38, 0x66,
806 0x19, 0x6a, 0xdc, 0x01,
807 0xd8, 0xee, 0x3c, 0x66,
808 0xff, 0x6a, 0xdc, 0x09,
809 0x18, 0xee, 0x40, 0x6e,
810 0xff, 0x6a, 0xd4, 0x0c,
811 0x88, 0x6a, 0xcc, 0x00,
812 0x44, 0x6a, 0x02, 0x5e,
813 0x20, 0x6a, 0xe0, 0x5d,
814 0x01, 0x3b, 0x26, 0x31,
815 0x04, 0x3b, 0x5a, 0x6e,
816 0xa0, 0x6a, 0xca, 0x00,
817 0x20, 0x65, 0xc8, 0x18,
818 0x00, 0x65, 0x98, 0x5e,
819 0x00, 0x65, 0x52, 0x66,
820 0x0a, 0x93, 0x26, 0x01,
821 0x00, 0x65, 0xa8, 0x46,
822 0xa0, 0x6a, 0xcc, 0x00,
823 0xff, 0x6a, 0xc8, 0x08,
824 0x20, 0x94, 0x5e, 0x6e,
825 0x10, 0x94, 0x60, 0x6e,
826 0x08, 0x94, 0x7a, 0x6e,
827 0x08, 0x94, 0x7a, 0x6e,
828 0x08, 0x94, 0x7a, 0x6e,
829 0xff, 0x8c, 0xc8, 0x10,
830 0xc1, 0x64, 0xc8, 0x18,
831 0xf8, 0x64, 0xc8, 0x08,
832 0x01, 0x99, 0xda, 0x30,
833 0x00, 0x66, 0x6e, 0x66,
834 0xc0, 0x66, 0xaa, 0x76,
835 0x60, 0x66, 0xc8, 0x18,
836 0x3d, 0x64, 0xc8, 0x28,
837 0x00, 0x65, 0x5e, 0x46,
838 0xf7, 0x93, 0x26, 0x09,
839 0x08, 0x93, 0x7c, 0x6e,
840 0x00, 0x62, 0xc4, 0x18,
841 0x00, 0x65, 0xa8, 0x5e,
842 0x00, 0x65, 0x88, 0x5e,
843 0x00, 0x65, 0x88, 0x5e,
844 0x00, 0x65, 0x88, 0x5e,
845 0x01, 0x99, 0xda, 0x30,
846 0x01, 0x99, 0xda, 0x30,
847 0x01, 0x99, 0xda, 0x30,
848 0x01, 0x99, 0xda, 0x30,
849 0x01, 0x99, 0xda, 0x30,
850 0x01, 0x99, 0xda, 0x30,
851 0x01, 0x99, 0xda, 0x30,
852 0x01, 0x99, 0xda, 0x34,
853 0x01, 0x6c, 0x32, 0x31,
854 0x01, 0x6c, 0x32, 0x31,
855 0x01, 0x6c, 0x32, 0x31,
856 0x01, 0x6c, 0x32, 0x31,
857 0x01, 0x6c, 0x32, 0x31,
858 0x01, 0x6c, 0x32, 0x31,
859 0x01, 0x6c, 0x32, 0x31,
860 0x01, 0x6c, 0x32, 0x35,
861 0x08, 0x94, 0xa8, 0x7e,
862 0xf7, 0x93, 0x26, 0x09,
863 0x08, 0x93, 0xac, 0x6e,
864 0xff, 0x6a, 0xd4, 0x0c,
865 0x04, 0xb8, 0xd4, 0x6e,
866 0x01, 0x42, 0x7e, 0x31,
867 0xff, 0x6a, 0x76, 0x01,
868 0x01, 0x90, 0x84, 0x34,
869 0xff, 0x6a, 0x76, 0x05,
870 0x01, 0x85, 0x0a, 0x01,
871 0x7f, 0x65, 0x10, 0x09,
872 0xfe, 0x85, 0x0a, 0x0d,
873 0xff, 0x42, 0xd0, 0x66,
874 0xff, 0x41, 0xc8, 0x66,
875 0xd1, 0x6a, 0xd8, 0x5e,
876 0xff, 0x6a, 0xca, 0x04,
877 0x01, 0x41, 0x20, 0x31,
878 0x01, 0xbf, 0x82, 0x30,
879 0x01, 0x6a, 0x76, 0x00,
880 0x00, 0xbb, 0x12, 0x46,
881 0x01, 0x42, 0x20, 0x31,
882 0x01, 0xbf, 0x84, 0x34,
883 0x01, 0x41, 0x7e, 0x31,
884 0x01, 0x90, 0x82, 0x34,
885 0x01, 0x65, 0x22, 0x31,
886 0xff, 0x6a, 0xd4, 0x08,
887 0xff, 0x6a, 0xd4, 0x0c
888};
889
890typedef int ahc_patch_func_t (struct ahc_softc *ahc);
891static ahc_patch_func_t ahc_patch23_func;
892
893static int
894ahc_patch23_func(struct ahc_softc *ahc)
895{
896 return ((ahc->bugs & AHC_SCBCHAN_UPLOAD_BUG) != 0);
897}
898
899static ahc_patch_func_t ahc_patch22_func;
900
901static int
902ahc_patch22_func(struct ahc_softc *ahc)
903{
904 return ((ahc->features & AHC_CMD_CHAN) == 0);
905}
906
907static ahc_patch_func_t ahc_patch21_func;
908
909static int
910ahc_patch21_func(struct ahc_softc *ahc)
911{
912 return ((ahc->features & AHC_QUEUE_REGS) == 0);
913}
914
915static ahc_patch_func_t ahc_patch20_func;
916
917static int
918ahc_patch20_func(struct ahc_softc *ahc)
919{
920 return ((ahc->features & AHC_WIDE) != 0);
921}
922
923static ahc_patch_func_t ahc_patch19_func;
924
925static int
926ahc_patch19_func(struct ahc_softc *ahc)
927{
928 return ((ahc->flags & AHC_SCB_BTT) != 0);
929}
930
931static ahc_patch_func_t ahc_patch18_func;
932
933static int
934ahc_patch18_func(struct ahc_softc *ahc)
935{
936 return ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0);
937}
938
939static ahc_patch_func_t ahc_patch17_func;
940
941static int
942ahc_patch17_func(struct ahc_softc *ahc)
943{
944 return ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0);
945}
946
947static ahc_patch_func_t ahc_patch16_func;
948
949static int
950ahc_patch16_func(struct ahc_softc *ahc)
951{
952 return ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0);
953}
954
955static ahc_patch_func_t ahc_patch15_func;
956
957static int
958ahc_patch15_func(struct ahc_softc *ahc)
959{
960 return ((ahc->features & AHC_ULTRA2) == 0);
961}
962
963static ahc_patch_func_t ahc_patch14_func;
964
965static int
966ahc_patch14_func(struct ahc_softc *ahc)
967{
968 return ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0);
969}
970
971static ahc_patch_func_t ahc_patch13_func;
972
973static int
974ahc_patch13_func(struct ahc_softc *ahc)
975{
976 return ((ahc->flags & AHC_39BIT_ADDRESSING) != 0);
977}
978
979static ahc_patch_func_t ahc_patch12_func;
980
981static int
982ahc_patch12_func(struct ahc_softc *ahc)
983{
984 return ((ahc->features & AHC_HS_MAILBOX) != 0);
985}
986
987static ahc_patch_func_t ahc_patch11_func;
988
989static int
990ahc_patch11_func(struct ahc_softc *ahc)
991{
992 return ((ahc->features & AHC_ULTRA) != 0);
993}
994
995static ahc_patch_func_t ahc_patch10_func;
996
997static int
998ahc_patch10_func(struct ahc_softc *ahc)
999{
1000 return ((ahc->features & AHC_MULTI_TID) != 0);
1001}
1002
1003static ahc_patch_func_t ahc_patch9_func;
1004
1005static int
1006ahc_patch9_func(struct ahc_softc *ahc)
1007{
1008 return ((ahc->features & AHC_CMD_CHAN) != 0);
1009}
1010
1011static ahc_patch_func_t ahc_patch8_func;
1012
1013static int
1014ahc_patch8_func(struct ahc_softc *ahc)
1015{
1016 return ((ahc->flags & AHC_INITIATORROLE) != 0);
1017}
1018
1019static ahc_patch_func_t ahc_patch7_func;
1020
1021static int
1022ahc_patch7_func(struct ahc_softc *ahc)
1023{
1024 return ((ahc->flags & AHC_TARGETROLE) != 0);
1025}
1026
1027static ahc_patch_func_t ahc_patch6_func;
1028
1029static int
1030ahc_patch6_func(struct ahc_softc *ahc)
1031{
1032 return ((ahc->features & AHC_DT) == 0);
1033}
1034
1035static ahc_patch_func_t ahc_patch5_func;
1036
1037static int
1038ahc_patch5_func(struct ahc_softc *ahc)
1039{
1040 return ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0);
1041}
1042
1043static ahc_patch_func_t ahc_patch4_func;
1044
1045static int
1046ahc_patch4_func(struct ahc_softc *ahc)
1047{
1048 return ((ahc->flags & AHC_PAGESCBS) != 0);
1049}
1050
1051static ahc_patch_func_t ahc_patch3_func;
1052
1053static int
1054ahc_patch3_func(struct ahc_softc *ahc)
1055{
1056 return ((ahc->features & AHC_QUEUE_REGS) != 0);
1057}
1058
1059static ahc_patch_func_t ahc_patch2_func;
1060
1061static int
1062ahc_patch2_func(struct ahc_softc *ahc)
1063{
1064 return ((ahc->features & AHC_TWIN) != 0);
1065}
1066
1067static ahc_patch_func_t ahc_patch1_func;
1068
1069static int
1070ahc_patch1_func(struct ahc_softc *ahc)
1071{
1072 return ((ahc->features & AHC_ULTRA2) != 0);
1073}
1074
1075static ahc_patch_func_t ahc_patch0_func;
1076
1077static int
1078ahc_patch0_func(struct ahc_softc *ahc)
1079{
1080 return (0);
1081}
1082
1083static struct patch {
1084 ahc_patch_func_t *patch_func;
1085 uint32_t begin :10,
1086 skip_instr :10,
1087 skip_patch :12;
1088} patches[] = {
1089 { ahc_patch1_func, 4, 1, 1 },
1090 { ahc_patch2_func, 6, 2, 1 },
1091 { ahc_patch2_func, 9, 1, 1 },
1092 { ahc_patch3_func, 11, 1, 2 },
1093 { ahc_patch0_func, 12, 2, 1 },
1094 { ahc_patch4_func, 15, 1, 2 },
1095 { ahc_patch0_func, 16, 1, 1 },
1096 { ahc_patch5_func, 22, 2, 1 },
1097 { ahc_patch3_func, 27, 1, 2 },
1098 { ahc_patch0_func, 28, 1, 1 },
1099 { ahc_patch6_func, 34, 1, 1 },
1100 { ahc_patch7_func, 37, 54, 19 },
1101 { ahc_patch8_func, 37, 1, 1 },
1102 { ahc_patch9_func, 42, 3, 2 },
1103 { ahc_patch0_func, 45, 3, 1 },
1104 { ahc_patch10_func, 49, 1, 2 },
1105 { ahc_patch0_func, 50, 2, 3 },
1106 { ahc_patch1_func, 50, 1, 2 },
1107 { ahc_patch0_func, 51, 1, 1 },
1108 { ahc_patch2_func, 53, 2, 1 },
1109 { ahc_patch9_func, 55, 1, 2 },
1110 { ahc_patch0_func, 56, 1, 1 },
1111 { ahc_patch9_func, 60, 1, 2 },
1112 { ahc_patch0_func, 61, 1, 1 },
1113 { ahc_patch9_func, 71, 1, 2 },
1114 { ahc_patch0_func, 72, 1, 1 },
1115 { ahc_patch9_func, 75, 1, 2 },
1116 { ahc_patch0_func, 76, 1, 1 },
1117 { ahc_patch9_func, 79, 1, 2 },
1118 { ahc_patch0_func, 80, 1, 1 },
1119 { ahc_patch8_func, 91, 9, 4 },
1120 { ahc_patch1_func, 93, 1, 2 },
1121 { ahc_patch0_func, 94, 1, 1 },
1122 { ahc_patch2_func, 96, 2, 1 },
1123 { ahc_patch2_func, 105, 4, 1 },
1124 { ahc_patch1_func, 109, 1, 2 },
1125 { ahc_patch0_func, 110, 2, 3 },
1126 { ahc_patch2_func, 110, 1, 2 },
1127 { ahc_patch0_func, 111, 1, 1 },
1128 { ahc_patch7_func, 112, 4, 2 },
1129 { ahc_patch0_func, 116, 1, 1 },
1130 { ahc_patch11_func, 117, 2, 1 },
1131 { ahc_patch1_func, 119, 1, 2 },
1132 { ahc_patch0_func, 120, 1, 1 },
1133 { ahc_patch7_func, 121, 4, 1 },
1134 { ahc_patch7_func, 131, 95, 11 },
1135 { ahc_patch4_func, 151, 1, 1 },
1136 { ahc_patch1_func, 168, 1, 1 },
1137 { ahc_patch12_func, 173, 1, 2 },
1138 { ahc_patch0_func, 174, 1, 1 },
1139 { ahc_patch9_func, 185, 1, 2 },
1140 { ahc_patch0_func, 186, 1, 1 },
1141 { ahc_patch9_func, 195, 1, 2 },
1142 { ahc_patch0_func, 196, 1, 1 },
1143 { ahc_patch9_func, 212, 6, 2 },
1144 { ahc_patch0_func, 218, 6, 1 },
1145 { ahc_patch8_func, 226, 20, 2 },
1146 { ahc_patch1_func, 241, 1, 1 },
1147 { ahc_patch1_func, 248, 1, 2 },
1148 { ahc_patch0_func, 249, 2, 2 },
1149 { ahc_patch11_func, 250, 1, 1 },
1150 { ahc_patch9_func, 258, 27, 3 },
1151 { ahc_patch1_func, 274, 10, 2 },
1152 { ahc_patch13_func, 277, 1, 1 },
1153 { ahc_patch14_func, 285, 14, 1 },
1154 { ahc_patch1_func, 301, 1, 2 },
1155 { ahc_patch0_func, 302, 1, 1 },
1156 { ahc_patch9_func, 305, 1, 1 },
1157 { ahc_patch13_func, 310, 1, 1 },
1158 { ahc_patch9_func, 311, 2, 2 },
1159 { ahc_patch0_func, 313, 4, 1 },
1160 { ahc_patch14_func, 317, 1, 1 },
1161 { ahc_patch15_func, 319, 2, 3 },
1162 { ahc_patch9_func, 319, 1, 2 },
1163 { ahc_patch0_func, 320, 1, 1 },
1164 { ahc_patch6_func, 325, 1, 2 },
1165 { ahc_patch0_func, 326, 1, 1 },
1166 { ahc_patch1_func, 330, 47, 11 },
1167 { ahc_patch6_func, 337, 2, 4 },
1168 { ahc_patch7_func, 337, 1, 1 },
1169 { ahc_patch8_func, 338, 1, 1 },
1170 { ahc_patch0_func, 339, 1, 1 },
1171 { ahc_patch16_func, 340, 1, 1 },
1172 { ahc_patch6_func, 356, 6, 3 },
1173 { ahc_patch16_func, 356, 5, 1 },
1174 { ahc_patch0_func, 362, 7, 1 },
1175 { ahc_patch13_func, 372, 5, 1 },
1176 { ahc_patch0_func, 377, 52, 17 },
1177 { ahc_patch14_func, 377, 1, 1 },
1178 { ahc_patch7_func, 379, 2, 2 },
1179 { ahc_patch17_func, 380, 1, 1 },
1180 { ahc_patch9_func, 383, 1, 1 },
1181 { ahc_patch18_func, 390, 1, 1 },
1182 { ahc_patch14_func, 395, 9, 3 },
1183 { ahc_patch9_func, 396, 3, 2 },
1184 { ahc_patch0_func, 399, 3, 1 },
1185 { ahc_patch9_func, 407, 6, 2 },
1186 { ahc_patch0_func, 413, 9, 2 },
1187 { ahc_patch13_func, 413, 1, 1 },
1188 { ahc_patch13_func, 422, 2, 1 },
1189 { ahc_patch14_func, 424, 1, 1 },
1190 { ahc_patch9_func, 426, 1, 2 },
1191 { ahc_patch0_func, 427, 1, 1 },
1192 { ahc_patch7_func, 428, 1, 1 },
1193 { ahc_patch7_func, 429, 1, 1 },
1194 { ahc_patch8_func, 430, 3, 3 },
1195 { ahc_patch6_func, 431, 1, 2 },
1196 { ahc_patch0_func, 432, 1, 1 },
1197 { ahc_patch9_func, 433, 1, 1 },
1198 { ahc_patch15_func, 434, 1, 2 },
1199 { ahc_patch13_func, 434, 1, 1 },
1200 { ahc_patch14_func, 436, 9, 4 },
1201 { ahc_patch9_func, 436, 1, 1 },
1202 { ahc_patch9_func, 443, 2, 1 },
1203 { ahc_patch0_func, 445, 4, 3 },
1204 { ahc_patch9_func, 445, 1, 2 },
1205 { ahc_patch0_func, 446, 3, 1 },
1206 { ahc_patch1_func, 450, 2, 1 },
1207 { ahc_patch7_func, 452, 10, 2 },
1208 { ahc_patch0_func, 462, 1, 1 },
1209 { ahc_patch8_func, 463, 118, 22 },
1210 { ahc_patch1_func, 465, 3, 2 },
1211 { ahc_patch0_func, 468, 5, 3 },
1212 { ahc_patch9_func, 468, 2, 2 },
1213 { ahc_patch0_func, 470, 3, 1 },
1214 { ahc_patch1_func, 475, 2, 2 },
1215 { ahc_patch0_func, 477, 6, 3 },
1216 { ahc_patch9_func, 477, 2, 2 },
1217 { ahc_patch0_func, 479, 3, 1 },
1218 { ahc_patch1_func, 485, 2, 2 },
1219 { ahc_patch0_func, 487, 9, 7 },
1220 { ahc_patch9_func, 487, 5, 6 },
1221 { ahc_patch19_func, 487, 1, 2 },
1222 { ahc_patch0_func, 488, 1, 1 },
1223 { ahc_patch19_func, 490, 1, 2 },
1224 { ahc_patch0_func, 491, 1, 1 },
1225 { ahc_patch0_func, 492, 4, 1 },
1226 { ahc_patch6_func, 497, 3, 2 },
1227 { ahc_patch0_func, 500, 1, 1 },
1228 { ahc_patch6_func, 510, 1, 2 },
1229 { ahc_patch0_func, 511, 1, 1 },
1230 { ahc_patch20_func, 548, 7, 1 },
1231 { ahc_patch3_func, 583, 1, 2 },
1232 { ahc_patch0_func, 584, 1, 1 },
1233 { ahc_patch21_func, 587, 1, 1 },
1234 { ahc_patch8_func, 589, 106, 33 },
1235 { ahc_patch4_func, 591, 1, 1 },
1236 { ahc_patch1_func, 597, 2, 2 },
1237 { ahc_patch0_func, 599, 1, 1 },
1238 { ahc_patch1_func, 602, 1, 2 },
1239 { ahc_patch0_func, 603, 1, 1 },
1240 { ahc_patch9_func, 604, 3, 3 },
1241 { ahc_patch15_func, 605, 1, 1 },
1242 { ahc_patch0_func, 607, 4, 1 },
1243 { ahc_patch19_func, 616, 2, 2 },
1244 { ahc_patch0_func, 618, 1, 1 },
1245 { ahc_patch19_func, 622, 10, 3 },
1246 { ahc_patch5_func, 624, 8, 1 },
1247 { ahc_patch0_func, 632, 9, 2 },
1248 { ahc_patch5_func, 633, 8, 1 },
1249 { ahc_patch4_func, 643, 1, 2 },
1250 { ahc_patch0_func, 644, 1, 1 },
1251 { ahc_patch19_func, 645, 1, 2 },
1252 { ahc_patch0_func, 646, 3, 2 },
1253 { ahc_patch4_func, 648, 1, 1 },
1254 { ahc_patch5_func, 649, 1, 1 },
1255 { ahc_patch5_func, 652, 1, 1 },
1256 { ahc_patch5_func, 654, 1, 1 },
1257 { ahc_patch4_func, 656, 2, 2 },
1258 { ahc_patch0_func, 658, 2, 1 },
1259 { ahc_patch5_func, 660, 1, 1 },
1260 { ahc_patch5_func, 663, 1, 1 },
1261 { ahc_patch5_func, 666, 1, 1 },
1262 { ahc_patch19_func, 670, 1, 1 },
1263 { ahc_patch19_func, 673, 1, 1 },
1264 { ahc_patch4_func, 679, 1, 1 },
1265 { ahc_patch6_func, 682, 1, 2 },
1266 { ahc_patch0_func, 683, 1, 1 },
1267 { ahc_patch7_func, 695, 16, 1 },
1268 { ahc_patch4_func, 711, 20, 1 },
1269 { ahc_patch9_func, 732, 4, 2 },
1270 { ahc_patch0_func, 736, 4, 1 },
1271 { ahc_patch9_func, 740, 4, 2 },
1272 { ahc_patch0_func, 744, 3, 1 },
1273 { ahc_patch6_func, 750, 1, 1 },
1274 { ahc_patch22_func, 752, 14, 1 },
1275 { ahc_patch7_func, 766, 3, 1 },
1276 { ahc_patch9_func, 778, 24, 8 },
1277 { ahc_patch19_func, 782, 1, 2 },
1278 { ahc_patch0_func, 783, 1, 1 },
1279 { ahc_patch15_func, 788, 4, 2 },
1280 { ahc_patch0_func, 792, 7, 3 },
1281 { ahc_patch23_func, 792, 5, 2 },
1282 { ahc_patch0_func, 797, 2, 1 },
1283 { ahc_patch0_func, 802, 42, 3 },
1284 { ahc_patch18_func, 814, 18, 2 },
1285 { ahc_patch0_func, 832, 1, 1 },
1286 { ahc_patch4_func, 856, 1, 1 },
1287 { ahc_patch4_func, 857, 3, 2 },
1288 { ahc_patch0_func, 860, 1, 1 },
1289 { ahc_patch13_func, 861, 3, 1 },
1290 { ahc_patch4_func, 864, 12, 1 }
1291};
1292
1293static struct cs {
1294 uint16_t begin;
1295 uint16_t end;
1296} critical_sections[] = {
1297 { 11, 18 },
1298 { 21, 30 },
1299 { 711, 727 },
1300 { 857, 860 },
1301 { 864, 870 },
1302 { 872, 874 },
1303 { 874, 876 }
1304};
1305
1306static const int num_critical_sections = sizeof(critical_sections)
1307 / sizeof(*critical_sections);
diff --git a/drivers/scsi/aic7xxx/aicasm/Makefile b/drivers/scsi/aic7xxx/aicasm/Makefile
new file mode 100644
index 000000000000..8c91fda6482c
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/Makefile
@@ -0,0 +1,78 @@
1PROG= aicasm
2
3.SUFFIXES= .l .y .c .h
4
5CSRCS= aicasm.c aicasm_symbol.c
6YSRCS= aicasm_gram.y aicasm_macro_gram.y
7LSRCS= aicasm_scan.l aicasm_macro_scan.l
8
9GENHDRS= aicdb.h $(YSRCS:.y=.h)
10GENSRCS= $(YSRCS:.y=.c) $(LSRCS:.l=.c)
11
12SRCS= ${CSRCS} ${GENSRCS}
13LIBS= -ldb
14clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG)
15# Override default kernel CFLAGS. This is a userland app.
16AICASM_CFLAGS:= -I/usr/include -I.
17YFLAGS= -d
18
19NOMAN= noman
20
21ifneq ($(HOSTCC),)
22AICASM_CC= $(HOSTCC)
23else
24AICASM_CC= $(CC)
25endif
26
27ifdef DEBUG
28CFLAGS+= -DDEBUG -g
29YFLAGS+= -t -v
30LFLAGS= -d
31endif
32
33$(PROG): ${GENHDRS} $(SRCS)
34 $(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(PROG) $(LIBS)
35
36aicdb.h:
37 @if [ -e "/usr/include/db4/db_185.h" ]; then \
38 echo "#include <db4/db_185.h>" > aicdb.h; \
39 elif [ -e "/usr/include/db3/db_185.h" ]; then \
40 echo "#include <db3/db_185.h>" > aicdb.h; \
41 elif [ -e "/usr/include/db2/db_185.h" ]; then \
42 echo "#include <db2/db_185.h>" > aicdb.h; \
43 elif [ -e "/usr/include/db1/db_185.h" ]; then \
44 echo "#include <db1/db_185.h>" > aicdb.h; \
45 elif [ -e "/usr/include/db/db_185.h" ]; then \
46 echo "#include <db/db_185.h>" > aicdb.h; \
47 elif [ -e "/usr/include/db_185.h" ]; then \
48 echo "#include <db_185.h>" > aicdb.h; \
49 else \
50 echo "*** Install db development libraries"; \
51 fi
52
53clean:
54 rm -f $(clean-files)
55
56# Create a dependency chain in generated files
57# to avoid concurrent invocations of the single
58# rule that builds them all.
59aicasm_gram.c: aicasm_gram.h
60aicasm_gram.c aicasm_gram.h: aicasm_gram.y
61 $(YACC) $(YFLAGS) -b $(<:.y=) $<
62 mv $(<:.y=).tab.c $(<:.y=.c)
63 mv $(<:.y=).tab.h $(<:.y=.h)
64
65# Create a dependency chain in generated files
66# to avoid concurrent invocations of the single
67# rule that builds them all.
68aicasm_macro_gram.c: aicasm_macro_gram.h
69aicasm_macro_gram.c aicasm_macro_gram.h: aicasm_macro_gram.y
70 $(YACC) $(YFLAGS) -b $(<:.y=) -p mm $<
71 mv $(<:.y=).tab.c $(<:.y=.c)
72 mv $(<:.y=).tab.h $(<:.y=.h)
73
74aicasm_scan.c: aicasm_scan.l
75 $(LEX) $(LFLAGS) -o$@ $<
76
77aicasm_macro_scan.c: aicasm_macro_scan.l
78 $(LEX) $(LFLAGS) -Pmm -o$@ $<
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.c b/drivers/scsi/aic7xxx/aicasm/aicasm.c
new file mode 100644
index 000000000000..c34639481904
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm.c
@@ -0,0 +1,835 @@
1/*
2 * Aic7xxx SCSI host adapter firmware asssembler
3 *
4 * Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs.
5 * Copyright (c) 2001, 2002 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#22 $
41 *
42 * $FreeBSD$
43 */
44#include <sys/types.h>
45#include <sys/mman.h>
46
47#include <ctype.h>
48#include <inttypes.h>
49#include <regex.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#include <sysexits.h>
54#include <unistd.h>
55
56#if linux
57#include <endian.h>
58#else
59#include <machine/endian.h>
60#endif
61
62#include "aicasm.h"
63#include "aicasm_symbol.h"
64#include "aicasm_insformat.h"
65
66typedef struct patch {
67 STAILQ_ENTRY(patch) links;
68 int patch_func;
69 u_int begin;
70 u_int skip_instr;
71 u_int skip_patch;
72} patch_t;
73
74STAILQ_HEAD(patch_list, patch) patches;
75
76static void usage(void);
77static void back_patch(void);
78static void output_code(void);
79static void output_listing(char *ifilename);
80static void dump_scope(scope_t *scope);
81static void emit_patch(scope_t *scope, int patch);
82static int check_patch(patch_t **start_patch, int start_instr,
83 int *skip_addr, int *func_vals);
84
85struct path_list search_path;
86int includes_search_curdir;
87char *appname;
88char *stock_include_file;
89FILE *ofile;
90char *ofilename;
91char *regfilename;
92FILE *regfile;
93char *listfilename;
94FILE *listfile;
95char *regdiagfilename;
96FILE *regdiagfile;
97int src_mode;
98int dst_mode;
99
100static STAILQ_HEAD(,instruction) seq_program;
101struct cs_tailq cs_tailq;
102struct scope_list scope_stack;
103symlist_t patch_functions;
104
105#if DEBUG
106extern int yy_flex_debug;
107extern int mm_flex_debug;
108extern int yydebug;
109extern int mmdebug;
110#endif
111extern FILE *yyin;
112extern int yyparse(void);
113
114int main(int argc, char *argv[]);
115
116int
117main(int argc, char *argv[])
118{
119 extern char *optarg;
120 extern int optind;
121 int ch;
122 int retval;
123 char *inputfilename;
124 scope_t *sentinal;
125
126 STAILQ_INIT(&patches);
127 SLIST_INIT(&search_path);
128 STAILQ_INIT(&seq_program);
129 TAILQ_INIT(&cs_tailq);
130 SLIST_INIT(&scope_stack);
131
132 /* Set Sentinal scope node */
133 sentinal = scope_alloc();
134 sentinal->type = SCOPE_ROOT;
135
136 includes_search_curdir = 1;
137 appname = *argv;
138 regfile = NULL;
139 listfile = NULL;
140#if DEBUG
141 yy_flex_debug = 0;
142 mm_flex_debug = 0;
143 yydebug = 0;
144 mmdebug = 0;
145#endif
146 while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:")) != -1) {
147 switch(ch) {
148 case 'd':
149#if DEBUG
150 if (strcmp(optarg, "s") == 0) {
151 yy_flex_debug = 1;
152 mm_flex_debug = 1;
153 } else if (strcmp(optarg, "p") == 0) {
154 yydebug = 1;
155 mmdebug = 1;
156 } else {
157 fprintf(stderr, "%s: -d Requires either an "
158 "'s' or 'p' argument\n", appname);
159 usage();
160 }
161#else
162 stop("-d: Assembler not built with debugging "
163 "information", EX_SOFTWARE);
164#endif
165 break;
166 case 'i':
167 stock_include_file = optarg;
168 break;
169 case 'l':
170 /* Create a program listing */
171 if ((listfile = fopen(optarg, "w")) == NULL) {
172 perror(optarg);
173 stop(NULL, EX_CANTCREAT);
174 }
175 listfilename = optarg;
176 break;
177 case 'n':
178 /* Don't complain about the -nostdinc directrive */
179 if (strcmp(optarg, "ostdinc")) {
180 fprintf(stderr, "%s: Unknown option -%c%s\n",
181 appname, ch, optarg);
182 usage();
183 /* NOTREACHED */
184 }
185 break;
186 case 'o':
187 if ((ofile = fopen(optarg, "w")) == NULL) {
188 perror(optarg);
189 stop(NULL, EX_CANTCREAT);
190 }
191 ofilename = optarg;
192 break;
193 case 'p':
194 /* Create Register Diagnostic "printing" Functions */
195 if ((regdiagfile = fopen(optarg, "w")) == NULL) {
196 perror(optarg);
197 stop(NULL, EX_CANTCREAT);
198 }
199 regdiagfilename = optarg;
200 break;
201 case 'r':
202 if ((regfile = fopen(optarg, "w")) == NULL) {
203 perror(optarg);
204 stop(NULL, EX_CANTCREAT);
205 }
206 regfilename = optarg;
207 break;
208 case 'I':
209 {
210 path_entry_t include_dir;
211
212 if (strcmp(optarg, "-") == 0) {
213 if (includes_search_curdir == 0) {
214 fprintf(stderr, "%s: Warning - '-I-' "
215 "specified multiple "
216 "times\n", appname);
217 }
218 includes_search_curdir = 0;
219 for (include_dir = SLIST_FIRST(&search_path);
220 include_dir != NULL;
221 include_dir = SLIST_NEXT(include_dir,
222 links))
223 /*
224 * All entries before a '-I-' only
225 * apply to includes specified with
226 * quotes instead of "<>".
227 */
228 include_dir->quoted_includes_only = 1;
229 } else {
230 include_dir =
231 (path_entry_t)malloc(sizeof(*include_dir));
232 if (include_dir == NULL) {
233 perror(optarg);
234 stop(NULL, EX_OSERR);
235 }
236 include_dir->directory = strdup(optarg);
237 if (include_dir->directory == NULL) {
238 perror(optarg);
239 stop(NULL, EX_OSERR);
240 }
241 include_dir->quoted_includes_only = 0;
242 SLIST_INSERT_HEAD(&search_path, include_dir,
243 links);
244 }
245 break;
246 }
247 case '?':
248 default:
249 usage();
250 /* NOTREACHED */
251 }
252 }
253 argc -= optind;
254 argv += optind;
255
256 if (argc != 1) {
257 fprintf(stderr, "%s: No input file specifiled\n", appname);
258 usage();
259 /* NOTREACHED */
260 }
261
262 if (regdiagfile != NULL
263 && (regfile == NULL || stock_include_file == NULL)) {
264 fprintf(stderr,
265 "%s: The -p option requires the -r and -i options.\n",
266 appname);
267 usage();
268 /* NOTREACHED */
269 }
270 symtable_open();
271 inputfilename = *argv;
272 include_file(*argv, SOURCE_FILE);
273 retval = yyparse();
274 if (retval == 0) {
275 if (SLIST_FIRST(&scope_stack) == NULL
276 || SLIST_FIRST(&scope_stack)->type != SCOPE_ROOT) {
277 stop("Unterminated conditional expression", EX_DATAERR);
278 /* NOTREACHED */
279 }
280
281 /* Process outmost scope */
282 process_scope(SLIST_FIRST(&scope_stack));
283 /*
284 * Decend the tree of scopes and insert/emit
285 * patches as appropriate. We perform a depth first
286 * tranversal, recursively handling each scope.
287 */
288 /* start at the root scope */
289 dump_scope(SLIST_FIRST(&scope_stack));
290
291 /* Patch up forward jump addresses */
292 back_patch();
293
294 if (ofile != NULL)
295 output_code();
296 if (regfile != NULL)
297 symtable_dump(regfile, regdiagfile);
298 if (listfile != NULL)
299 output_listing(inputfilename);
300 }
301
302 stop(NULL, 0);
303 /* NOTREACHED */
304 return (0);
305}
306
307static void
308usage()
309{
310
311 (void)fprintf(stderr,
312"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n"
313" [-r register_output_file [-p register_diag_file -i includefile]]\n"
314" [-l program_list_file]\n"
315" input_file\n", appname);
316 exit(EX_USAGE);
317}
318
319static void
320back_patch()
321{
322 struct instruction *cur_instr;
323
324 for (cur_instr = STAILQ_FIRST(&seq_program);
325 cur_instr != NULL;
326 cur_instr = STAILQ_NEXT(cur_instr, links)) {
327 if (cur_instr->patch_label != NULL) {
328 struct ins_format3 *f3_instr;
329 u_int address;
330
331 if (cur_instr->patch_label->type != LABEL) {
332 char buf[255];
333
334 snprintf(buf, sizeof(buf),
335 "Undefined label %s",
336 cur_instr->patch_label->name);
337 stop(buf, EX_DATAERR);
338 /* NOTREACHED */
339 }
340 f3_instr = &cur_instr->format.format3;
341 address = f3_instr->address;
342 address += cur_instr->patch_label->info.linfo->address;
343 f3_instr->address = address;
344 }
345 }
346}
347
348static void
349output_code()
350{
351 struct instruction *cur_instr;
352 patch_t *cur_patch;
353 critical_section_t *cs;
354 symbol_node_t *cur_node;
355 int instrcount;
356
357 instrcount = 0;
358 fprintf(ofile,
359"/*\n"
360" * DO NOT EDIT - This file is automatically generated\n"
361" * from the following source files:\n"
362" *\n"
363"%s */\n", versions);
364
365 fprintf(ofile, "static uint8_t seqprog[] = {\n");
366 for (cur_instr = STAILQ_FIRST(&seq_program);
367 cur_instr != NULL;
368 cur_instr = STAILQ_NEXT(cur_instr, links)) {
369
370 fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x",
371 cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n",
372#if BYTE_ORDER == LITTLE_ENDIAN
373 cur_instr->format.bytes[0],
374 cur_instr->format.bytes[1],
375 cur_instr->format.bytes[2],
376 cur_instr->format.bytes[3]);
377#else
378 cur_instr->format.bytes[3],
379 cur_instr->format.bytes[2],
380 cur_instr->format.bytes[1],
381 cur_instr->format.bytes[0]);
382#endif
383 instrcount++;
384 }
385 fprintf(ofile, "\n};\n\n");
386
387 if (patch_arg_list == NULL)
388 stop("Patch argument list not defined",
389 EX_DATAERR);
390
391 /*
392 * Output patch information. Patch functions first.
393 */
394 fprintf(ofile,
395"typedef int %spatch_func_t (%s);\n", prefix, patch_arg_list);
396
397 for (cur_node = SLIST_FIRST(&patch_functions);
398 cur_node != NULL;
399 cur_node = SLIST_NEXT(cur_node,links)) {
400 fprintf(ofile,
401"static %spatch_func_t %spatch%d_func;\n"
402"\n"
403"static int\n"
404"%spatch%d_func(%s)\n"
405"{\n"
406" return (%s);\n"
407"}\n\n",
408 prefix,
409 prefix,
410 cur_node->symbol->info.condinfo->func_num,
411 prefix,
412 cur_node->symbol->info.condinfo->func_num,
413 patch_arg_list,
414 cur_node->symbol->name);
415 }
416
417 fprintf(ofile,
418"static struct patch {\n"
419" %spatch_func_t *patch_func;\n"
420" uint32_t begin :10,\n"
421" skip_instr :10,\n"
422" skip_patch :12;\n"
423"} patches[] = {\n", prefix);
424
425 for (cur_patch = STAILQ_FIRST(&patches);
426 cur_patch != NULL;
427 cur_patch = STAILQ_NEXT(cur_patch,links)) {
428 fprintf(ofile, "%s\t{ %spatch%d_func, %d, %d, %d }",
429 cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n",
430 prefix,
431 cur_patch->patch_func, cur_patch->begin,
432 cur_patch->skip_instr, cur_patch->skip_patch);
433 }
434
435 fprintf(ofile, "\n};\n\n");
436
437 fprintf(ofile,
438"static struct cs {\n"
439" uint16_t begin;\n"
440" uint16_t end;\n"
441"} critical_sections[] = {\n");
442
443 for (cs = TAILQ_FIRST(&cs_tailq);
444 cs != NULL;
445 cs = TAILQ_NEXT(cs, links)) {
446 fprintf(ofile, "%s\t{ %d, %d }",
447 cs == TAILQ_FIRST(&cs_tailq) ? "" : ",\n",
448 cs->begin_addr, cs->end_addr);
449 }
450
451 fprintf(ofile, "\n};\n\n");
452
453 fprintf(ofile,
454"static const int num_critical_sections = sizeof(critical_sections)\n"
455" / sizeof(*critical_sections);\n");
456
457 fprintf(stderr, "%s: %d instructions used\n", appname, instrcount);
458}
459
460static void
461dump_scope(scope_t *scope)
462{
463 scope_t *cur_scope;
464
465 /*
466 * Emit the first patch for this scope
467 */
468 emit_patch(scope, 0);
469
470 /*
471 * Dump each scope within this one.
472 */
473 cur_scope = TAILQ_FIRST(&scope->inner_scope);
474
475 while (cur_scope != NULL) {
476
477 dump_scope(cur_scope);
478
479 cur_scope = TAILQ_NEXT(cur_scope, scope_links);
480 }
481
482 /*
483 * Emit the second, closing, patch for this scope
484 */
485 emit_patch(scope, 1);
486}
487
488void
489emit_patch(scope_t *scope, int patch)
490{
491 patch_info_t *pinfo;
492 patch_t *new_patch;
493
494 pinfo = &scope->patches[patch];
495
496 if (pinfo->skip_instr == 0)
497 /* No-Op patch */
498 return;
499
500 new_patch = (patch_t *)malloc(sizeof(*new_patch));
501
502 if (new_patch == NULL)
503 stop("Could not malloc patch structure", EX_OSERR);
504
505 memset(new_patch, 0, sizeof(*new_patch));
506
507 if (patch == 0) {
508 new_patch->patch_func = scope->func_num;
509 new_patch->begin = scope->begin_addr;
510 } else {
511 new_patch->patch_func = 0;
512 new_patch->begin = scope->end_addr;
513 }
514 new_patch->skip_instr = pinfo->skip_instr;
515 new_patch->skip_patch = pinfo->skip_patch;
516 STAILQ_INSERT_TAIL(&patches, new_patch, links);
517}
518
519void
520output_listing(char *ifilename)
521{
522 char buf[1024];
523 FILE *ifile;
524 struct instruction *cur_instr;
525 patch_t *cur_patch;
526 symbol_node_t *cur_func;
527 int *func_values;
528 int instrcount;
529 int instrptr;
530 int line;
531 int func_count;
532 int skip_addr;
533
534 instrcount = 0;
535 instrptr = 0;
536 line = 1;
537 skip_addr = 0;
538 if ((ifile = fopen(ifilename, "r")) == NULL) {
539 perror(ifilename);
540 stop(NULL, EX_DATAERR);
541 }
542
543 /*
544 * Determine which options to apply to this listing.
545 */
546 for (func_count = 0, cur_func = SLIST_FIRST(&patch_functions);
547 cur_func != NULL;
548 cur_func = SLIST_NEXT(cur_func, links))
549 func_count++;
550
551 func_values = NULL;
552 if (func_count != 0) {
553 func_values = (int *)malloc(func_count * sizeof(int));
554
555 if (func_values == NULL)
556 stop("Could not malloc", EX_OSERR);
557
558 func_values[0] = 0; /* FALSE func */
559 func_count--;
560
561 /*
562 * Ask the user to fill in the return values for
563 * the rest of the functions.
564 */
565
566
567 for (cur_func = SLIST_FIRST(&patch_functions);
568 cur_func != NULL && SLIST_NEXT(cur_func, links) != NULL;
569 cur_func = SLIST_NEXT(cur_func, links), func_count--) {
570 int input;
571
572 fprintf(stdout, "\n(%s)\n", cur_func->symbol->name);
573 fprintf(stdout,
574 "Enter the return value for "
575 "this expression[T/F]:");
576
577 while (1) {
578
579 input = getchar();
580 input = toupper(input);
581
582 if (input == 'T') {
583 func_values[func_count] = 1;
584 break;
585 } else if (input == 'F') {
586 func_values[func_count] = 0;
587 break;
588 }
589 }
590 if (isatty(fileno(stdin)) == 0)
591 putchar(input);
592 }
593 fprintf(stdout, "\nThanks!\n");
594 }
595
596 /* Now output the listing */
597 cur_patch = STAILQ_FIRST(&patches);
598 for (cur_instr = STAILQ_FIRST(&seq_program);
599 cur_instr != NULL;
600 cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {
601
602 if (check_patch(&cur_patch, instrcount,
603 &skip_addr, func_values) == 0) {
604 /* Don't count this instruction as it is in a patch
605 * that was removed.
606 */
607 continue;
608 }
609
610 while (line < cur_instr->srcline) {
611 fgets(buf, sizeof(buf), ifile);
612 fprintf(listfile, "\t\t%s", buf);
613 line++;
614 }
615 fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr,
616#if BYTE_ORDER == LITTLE_ENDIAN
617 cur_instr->format.bytes[0],
618 cur_instr->format.bytes[1],
619 cur_instr->format.bytes[2],
620 cur_instr->format.bytes[3]);
621#else
622 cur_instr->format.bytes[3],
623 cur_instr->format.bytes[2],
624 cur_instr->format.bytes[1],
625 cur_instr->format.bytes[0]);
626#endif
627 fgets(buf, sizeof(buf), ifile);
628 fprintf(listfile, "\t%s", buf);
629 line++;
630 instrptr++;
631 }
632 /* Dump the remainder of the file */
633 while(fgets(buf, sizeof(buf), ifile) != NULL)
634 fprintf(listfile, "\t\t%s", buf);
635
636 fclose(ifile);
637}
638
639static int
640check_patch(patch_t **start_patch, int start_instr,
641 int *skip_addr, int *func_vals)
642{
643 patch_t *cur_patch;
644
645 cur_patch = *start_patch;
646
647 while (cur_patch != NULL && start_instr == cur_patch->begin) {
648 if (func_vals[cur_patch->patch_func] == 0) {
649 int skip;
650
651 /* Start rejecting code */
652 *skip_addr = start_instr + cur_patch->skip_instr;
653 for (skip = cur_patch->skip_patch;
654 skip > 0 && cur_patch != NULL;
655 skip--)
656 cur_patch = STAILQ_NEXT(cur_patch, links);
657 } else {
658 /* Accepted this patch. Advance to the next
659 * one and wait for our intruction pointer to
660 * hit this point.
661 */
662 cur_patch = STAILQ_NEXT(cur_patch, links);
663 }
664 }
665
666 *start_patch = cur_patch;
667 if (start_instr < *skip_addr)
668 /* Still skipping */
669 return (0);
670
671 return (1);
672}
673
674/*
675 * Print out error information if appropriate, and clean up before
676 * terminating the program.
677 */
678void
679stop(const char *string, int err_code)
680{
681 if (string != NULL) {
682 fprintf(stderr, "%s: ", appname);
683 if (yyfilename != NULL) {
684 fprintf(stderr, "Stopped at file %s, line %d - ",
685 yyfilename, yylineno);
686 }
687 fprintf(stderr, "%s\n", string);
688 }
689
690 if (ofile != NULL) {
691 fclose(ofile);
692 if (err_code != 0) {
693 fprintf(stderr, "%s: Removing %s due to error\n",
694 appname, ofilename);
695 unlink(ofilename);
696 }
697 }
698
699 if (regfile != NULL) {
700 fclose(regfile);
701 if (err_code != 0) {
702 fprintf(stderr, "%s: Removing %s due to error\n",
703 appname, regfilename);
704 unlink(regfilename);
705 }
706 }
707
708 if (listfile != NULL) {
709 fclose(listfile);
710 if (err_code != 0) {
711 fprintf(stderr, "%s: Removing %s due to error\n",
712 appname, listfilename);
713 unlink(listfilename);
714 }
715 }
716
717 symlist_free(&patch_functions);
718 symtable_close();
719
720 exit(err_code);
721}
722
723struct instruction *
724seq_alloc()
725{
726 struct instruction *new_instr;
727
728 new_instr = (struct instruction *)malloc(sizeof(struct instruction));
729 if (new_instr == NULL)
730 stop("Unable to malloc instruction object", EX_SOFTWARE);
731 memset(new_instr, 0, sizeof(*new_instr));
732 STAILQ_INSERT_TAIL(&seq_program, new_instr, links);
733 new_instr->srcline = yylineno;
734 return new_instr;
735}
736
737critical_section_t *
738cs_alloc()
739{
740 critical_section_t *new_cs;
741
742 new_cs= (critical_section_t *)malloc(sizeof(critical_section_t));
743 if (new_cs == NULL)
744 stop("Unable to malloc critical_section object", EX_SOFTWARE);
745 memset(new_cs, 0, sizeof(*new_cs));
746
747 TAILQ_INSERT_TAIL(&cs_tailq, new_cs, links);
748 return new_cs;
749}
750
751scope_t *
752scope_alloc()
753{
754 scope_t *new_scope;
755
756 new_scope = (scope_t *)malloc(sizeof(scope_t));
757 if (new_scope == NULL)
758 stop("Unable to malloc scope object", EX_SOFTWARE);
759 memset(new_scope, 0, sizeof(*new_scope));
760 TAILQ_INIT(&new_scope->inner_scope);
761
762 if (SLIST_FIRST(&scope_stack) != NULL) {
763 TAILQ_INSERT_TAIL(&SLIST_FIRST(&scope_stack)->inner_scope,
764 new_scope, scope_links);
765 }
766 /* This patch is now the current scope */
767 SLIST_INSERT_HEAD(&scope_stack, new_scope, scope_stack_links);
768 return new_scope;
769}
770
771void
772process_scope(scope_t *scope)
773{
774 /*
775 * We are "leaving" this scope. We should now have
776 * enough information to process the lists of scopes
777 * we encapsulate.
778 */
779 scope_t *cur_scope;
780 u_int skip_patch_count;
781 u_int skip_instr_count;
782
783 cur_scope = TAILQ_LAST(&scope->inner_scope, scope_tailq);
784 skip_patch_count = 0;
785 skip_instr_count = 0;
786 while (cur_scope != NULL) {
787 u_int patch0_patch_skip;
788
789 patch0_patch_skip = 0;
790 switch (cur_scope->type) {
791 case SCOPE_IF:
792 case SCOPE_ELSE_IF:
793 if (skip_instr_count != 0) {
794 /* Create a tail patch */
795 patch0_patch_skip++;
796 cur_scope->patches[1].skip_patch =
797 skip_patch_count + 1;
798 cur_scope->patches[1].skip_instr =
799 skip_instr_count;
800 }
801
802 /* Count Head patch */
803 patch0_patch_skip++;
804
805 /* Count any patches contained in our inner scope */
806 patch0_patch_skip += cur_scope->inner_scope_patches;
807
808 cur_scope->patches[0].skip_patch = patch0_patch_skip;
809 cur_scope->patches[0].skip_instr =
810 cur_scope->end_addr - cur_scope->begin_addr;
811
812 skip_instr_count += cur_scope->patches[0].skip_instr;
813
814 skip_patch_count += patch0_patch_skip;
815 if (cur_scope->type == SCOPE_IF) {
816 scope->inner_scope_patches += skip_patch_count;
817 skip_patch_count = 0;
818 skip_instr_count = 0;
819 }
820 break;
821 case SCOPE_ELSE:
822 /* Count any patches contained in our innter scope */
823 skip_patch_count += cur_scope->inner_scope_patches;
824
825 skip_instr_count += cur_scope->end_addr
826 - cur_scope->begin_addr;
827 break;
828 case SCOPE_ROOT:
829 stop("Unexpected scope type encountered", EX_SOFTWARE);
830 /* NOTREACHED */
831 }
832
833 cur_scope = TAILQ_PREV(cur_scope, scope_tailq, scope_links);
834 }
835}
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.h b/drivers/scsi/aic7xxx/aicasm/aicasm.h
new file mode 100644
index 000000000000..51678dd46ff7
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm.h
@@ -0,0 +1,95 @@
1/*
2 * Assembler for the sequencer program downloaded to Aic7xxx SCSI host adapters
3 *
4 * Copyright (c) 1997 Justin T. Gibbs.
5 * Copyright (c) 2001, 2002 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.h#14 $
41 *
42 * $FreeBSD$
43 */
44
45#ifdef __linux__
46#include "../queue.h"
47#else
48#include <sys/queue.h>
49#endif
50
51#ifndef TRUE
52#define TRUE 1
53#endif
54
55#ifndef FALSE
56#define FALSE 0
57#endif
58
59typedef struct path_entry {
60 char *directory;
61 int quoted_includes_only;
62 SLIST_ENTRY(path_entry) links;
63} *path_entry_t;
64
65typedef enum {
66 QUOTED_INCLUDE,
67 BRACKETED_INCLUDE,
68 SOURCE_FILE
69} include_type;
70
71SLIST_HEAD(path_list, path_entry);
72
73extern struct path_list search_path;
74extern struct cs_tailq cs_tailq;
75extern struct scope_list scope_stack;
76extern struct symlist patch_functions;
77extern int includes_search_curdir; /* False if we've seen -I- */
78extern char *appname;
79extern char *stock_include_file;
80extern int yylineno;
81extern char *yyfilename;
82extern char *prefix;
83extern char *patch_arg_list;
84extern char *versions;
85extern int src_mode;
86extern int dst_mode;
87struct symbol;
88
89void stop(const char *errstring, int err_code);
90void include_file(char *file_name, include_type type);
91void expand_macro(struct symbol *macro_symbol);
92struct instruction *seq_alloc(void);
93struct critical_section *cs_alloc(void);
94struct scope *scope_alloc(void);
95void process_scope(struct scope *);
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
new file mode 100644
index 000000000000..67e046d96625
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
@@ -0,0 +1,1945 @@
1%{
2/*
3 * Parser for the Aic7xxx SCSI Host adapter sequencer assembler.
4 *
5 * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
6 * Copyright (c) 2001, 2002 Adaptec Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * substantially similar to the "NO WARRANTY" disclaimer below
17 * ("Disclaimer") and any redistribution must be conditioned upon
18 * including a substantially similar Disclaimer requirement for further
19 * binary redistribution.
20 * 3. Neither the names of the above-listed copyright holders nor the names
21 * of any contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * Alternatively, this software may be distributed under the terms of the
25 * GNU General Public License ("GPL") version 2 as published by the Free
26 * Software Foundation.
27 *
28 * NO WARRANTY
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGES.
40 *
41 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_gram.y#29 $
42 *
43 * $FreeBSD$
44 */
45
46#include <sys/types.h>
47
48#include <inttypes.h>
49#include <regex.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#include <sysexits.h>
54
55#ifdef __linux__
56#include "../queue.h"
57#else
58#include <sys/queue.h>
59#endif
60
61#include "aicasm.h"
62#include "aicasm_symbol.h"
63#include "aicasm_insformat.h"
64
65int yylineno;
66char *yyfilename;
67char stock_prefix[] = "aic_";
68char *prefix = stock_prefix;
69char *patch_arg_list;
70char *versions;
71static char errbuf[255];
72static char regex_pattern[255];
73static symbol_t *cur_symbol;
74static symbol_t *field_symbol;
75static symbol_t *scb_or_sram_symbol;
76static symtype cur_symtype;
77static symbol_ref_t accumulator;
78static symbol_ref_t mode_ptr;
79static symbol_ref_t allones;
80static symbol_ref_t allzeros;
81static symbol_ref_t none;
82static symbol_ref_t sindex;
83static int instruction_ptr;
84static int num_srams;
85static int sram_or_scb_offset;
86static int download_constant_count;
87static int in_critical_section;
88static u_int enum_increment;
89static u_int enum_next_value;
90
91static void process_field(int field_type, symbol_t *sym, int mask);
92static void initialize_symbol(symbol_t *symbol);
93static void add_macro_arg(const char *argtext, int position);
94static void add_macro_body(const char *bodytext);
95static void process_register(symbol_t **p_symbol);
96static void format_1_instr(int opcode, symbol_ref_t *dest,
97 expression_t *immed, symbol_ref_t *src, int ret);
98static void format_2_instr(int opcode, symbol_ref_t *dest,
99 expression_t *places, symbol_ref_t *src, int ret);
100static void format_3_instr(int opcode, symbol_ref_t *src,
101 expression_t *immed, symbol_ref_t *address);
102static void test_readable_symbol(symbol_t *symbol);
103static void test_writable_symbol(symbol_t *symbol);
104static void type_check(symbol_t *symbol, expression_t *expression, int and_op);
105static void make_expression(expression_t *immed, int value);
106static void add_conditional(symbol_t *symbol);
107static void add_version(const char *verstring);
108static int is_download_const(expression_t *immed);
109
110#define SRAM_SYMNAME "SRAM_BASE"
111#define SCB_SYMNAME "SCB_BASE"
112%}
113
114%union {
115 u_int value;
116 char *str;
117 symbol_t *sym;
118 symbol_ref_t sym_ref;
119 expression_t expression;
120}
121
122%token T_REGISTER
123
124%token <value> T_CONST
125
126%token T_EXPORT
127
128%token T_DOWNLOAD
129
130%token T_SCB
131
132%token T_SRAM
133
134%token T_ALIAS
135
136%token T_SIZE
137
138%token T_EXPR_LSHIFT
139
140%token T_EXPR_RSHIFT
141
142%token <value> T_ADDRESS
143
144%token T_ACCESS_MODE
145
146%token T_MODES
147
148%token T_DEFINE
149
150%token T_SET_SRC_MODE
151
152%token T_SET_DST_MODE
153
154%token <value> T_MODE
155
156%token T_BEGIN_CS
157
158%token T_END_CS
159
160%token T_FIELD
161
162%token T_ENUM
163
164%token T_MASK
165
166%token <value> T_NUMBER
167
168%token <str> T_PATH T_STRING T_ARG T_MACROBODY
169
170%token <sym> T_CEXPR
171
172%token T_EOF T_INCLUDE T_VERSION T_PREFIX T_PATCH_ARG_LIST
173
174%token <value> T_SHR T_SHL T_ROR T_ROL
175
176%token <value> T_MVI T_MOV T_CLR T_BMOV
177
178%token <value> T_JMP T_JC T_JNC T_JE T_JNE T_JNZ T_JZ T_CALL
179
180%token <value> T_ADD T_ADC
181
182%token <value> T_INC T_DEC
183
184%token <value> T_STC T_CLC
185
186%token <value> T_CMP T_NOT T_XOR
187
188%token <value> T_TEST T_AND
189
190%token <value> T_OR
191
192%token T_RET
193
194%token T_NOP
195
196%token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX T_MODE_PTR
197
198%token T_A
199
200%token <sym> T_SYMBOL
201
202%token T_NL
203
204%token T_IF T_ELSE T_ELSE_IF T_ENDIF
205
206%type <sym_ref> reg_symbol address destination source opt_source
207
208%type <expression> expression immediate immediate_or_a
209
210%type <value> export ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne
211
212%type <value> mode_value mode_list macro_arglist
213
214%left '|'
215%left '&'
216%left T_EXPR_LSHIFT T_EXPR_RSHIFT
217%left '+' '-'
218%left '*' '/'
219%right '~'
220%nonassoc UMINUS
221%%
222
223program:
224 include
225| program include
226| prefix
227| program prefix
228| patch_arg_list
229| program patch_arg_list
230| version
231| program version
232| register
233| program register
234| constant
235| program constant
236| macrodefn
237| program macrodefn
238| scratch_ram
239| program scratch_ram
240| scb
241| program scb
242| label
243| program label
244| set_src_mode
245| program set_src_mode
246| set_dst_mode
247| program set_dst_mode
248| critical_section_start
249| program critical_section_start
250| critical_section_end
251| program critical_section_end
252| conditional
253| program conditional
254| code
255| program code
256;
257
258include:
259 T_INCLUDE '<' T_PATH '>'
260 {
261 include_file($3, BRACKETED_INCLUDE);
262 }
263| T_INCLUDE '"' T_PATH '"'
264 {
265 include_file($3, QUOTED_INCLUDE);
266 }
267;
268
269prefix:
270 T_PREFIX '=' T_STRING
271 {
272 if (prefix != stock_prefix)
273 stop("Prefix multiply defined",
274 EX_DATAERR);
275 prefix = strdup($3);
276 if (prefix == NULL)
277 stop("Unable to record prefix", EX_SOFTWARE);
278 }
279;
280
281patch_arg_list:
282 T_PATCH_ARG_LIST '=' T_STRING
283 {
284 if (patch_arg_list != NULL)
285 stop("Patch argument list multiply defined",
286 EX_DATAERR);
287 patch_arg_list = strdup($3);
288 if (patch_arg_list == NULL)
289 stop("Unable to record patch arg list", EX_SOFTWARE);
290 }
291;
292
293version:
294 T_VERSION '=' T_STRING
295 { add_version($3); }
296;
297
298register:
299 T_REGISTER { cur_symtype = REGISTER; } reg_definition
300;
301
302reg_definition:
303 T_SYMBOL '{'
304 {
305 if ($1->type != UNINITIALIZED) {
306 stop("Register multiply defined", EX_DATAERR);
307 /* NOTREACHED */
308 }
309 cur_symbol = $1;
310 cur_symbol->type = cur_symtype;
311 initialize_symbol(cur_symbol);
312 }
313 reg_attribute_list
314 '}'
315 {
316 /*
317 * Default to allowing everything in for registers
318 * with no bit or mask definitions.
319 */
320 if (cur_symbol->info.rinfo->valid_bitmask == 0)
321 cur_symbol->info.rinfo->valid_bitmask = 0xFF;
322
323 if (cur_symbol->info.rinfo->size == 0)
324 cur_symbol->info.rinfo->size = 1;
325
326 /*
327 * This might be useful for registers too.
328 */
329 if (cur_symbol->type != REGISTER) {
330 if (cur_symbol->info.rinfo->address == 0)
331 cur_symbol->info.rinfo->address =
332 sram_or_scb_offset;
333 sram_or_scb_offset +=
334 cur_symbol->info.rinfo->size;
335 }
336 cur_symbol = NULL;
337 }
338;
339
340reg_attribute_list:
341 reg_attribute
342| reg_attribute_list reg_attribute
343;
344
345reg_attribute:
346 reg_address
347| size
348| access_mode
349| modes
350| field_defn
351| enum_defn
352| mask_defn
353| alias
354| accumulator
355| mode_pointer
356| allones
357| allzeros
358| none
359| sindex
360;
361
362reg_address:
363 T_ADDRESS T_NUMBER
364 {
365 cur_symbol->info.rinfo->address = $2;
366 }
367;
368
369size:
370 T_SIZE T_NUMBER
371 {
372 cur_symbol->info.rinfo->size = $2;
373 if (scb_or_sram_symbol != NULL) {
374 u_int max_addr;
375 u_int sym_max_addr;
376
377 max_addr = scb_or_sram_symbol->info.rinfo->address
378 + scb_or_sram_symbol->info.rinfo->size;
379 sym_max_addr = cur_symbol->info.rinfo->address
380 + cur_symbol->info.rinfo->size;
381
382 if (sym_max_addr > max_addr)
383 stop("SCB or SRAM space exhausted", EX_DATAERR);
384 }
385 }
386;
387
388access_mode:
389 T_ACCESS_MODE T_MODE
390 {
391 cur_symbol->info.rinfo->mode = $2;
392 }
393;
394
395modes:
396 T_MODES mode_list
397 {
398 cur_symbol->info.rinfo->modes = $2;
399 }
400;
401
402mode_list:
403 mode_value
404 {
405 $$ = $1;
406 }
407| mode_list ',' mode_value
408 {
409 $$ = $1 | $3;
410 }
411;
412
413mode_value:
414 T_NUMBER
415 {
416 if ($1 > 4) {
417 stop("Valid register modes range between 0 and 4.",
418 EX_DATAERR);
419 /* NOTREACHED */
420 }
421
422 $$ = (0x1 << $1);
423 }
424| T_SYMBOL
425 {
426 symbol_t *symbol;
427
428 symbol = $1;
429 if (symbol->type != CONST) {
430 stop("Only \"const\" symbols allowed in "
431 "mode definitions.", EX_DATAERR);
432 /* NOTREACHED */
433 }
434 if (symbol->info.cinfo->value > 4) {
435 stop("Valid register modes range between 0 and 4.",
436 EX_DATAERR);
437 /* NOTREACHED */
438 }
439 $$ = (0x1 << symbol->info.cinfo->value);
440 }
441;
442
443field_defn:
444 T_FIELD
445 {
446 field_symbol = NULL;
447 enum_next_value = 0;
448 enum_increment = 1;
449 }
450 '{' enum_entry_list '}'
451| T_FIELD T_SYMBOL expression
452 {
453 process_field(FIELD, $2, $3.value);
454 field_symbol = $2;
455 enum_next_value = 0;
456 enum_increment = 0x01 << (ffs($3.value) - 1);
457 }
458 '{' enum_entry_list '}'
459| T_FIELD T_SYMBOL expression
460 {
461 process_field(FIELD, $2, $3.value);
462 }
463;
464
465enum_defn:
466 T_ENUM
467 {
468 field_symbol = NULL;
469 enum_next_value = 0;
470 enum_increment = 1;
471 }
472 '{' enum_entry_list '}'
473| T_ENUM T_SYMBOL expression
474 {
475 process_field(ENUM, $2, $3.value);
476 field_symbol = $2;
477 enum_next_value = 0;
478 enum_increment = 0x01 << (ffs($3.value) - 1);
479 }
480 '{' enum_entry_list '}'
481;
482
483enum_entry_list:
484 enum_entry
485| enum_entry_list ',' enum_entry
486;
487
488enum_entry:
489 T_SYMBOL
490 {
491 process_field(ENUM_ENTRY, $1, enum_next_value);
492 enum_next_value += enum_increment;
493 }
494| T_SYMBOL expression
495 {
496 process_field(ENUM_ENTRY, $1, $2.value);
497 enum_next_value = $2.value + enum_increment;
498 }
499;
500
501mask_defn:
502 T_MASK T_SYMBOL expression
503 {
504 process_field(MASK, $2, $3.value);
505 }
506;
507
508alias:
509 T_ALIAS T_SYMBOL
510 {
511 if ($2->type != UNINITIALIZED) {
512 stop("Re-definition of register alias",
513 EX_DATAERR);
514 /* NOTREACHED */
515 }
516 $2->type = ALIAS;
517 initialize_symbol($2);
518 $2->info.ainfo->parent = cur_symbol;
519 }
520;
521
522accumulator:
523 T_ACCUM
524 {
525 if (accumulator.symbol != NULL) {
526 stop("Only one accumulator definition allowed",
527 EX_DATAERR);
528 /* NOTREACHED */
529 }
530 accumulator.symbol = cur_symbol;
531 }
532;
533
534mode_pointer:
535 T_MODE_PTR
536 {
537 if (mode_ptr.symbol != NULL) {
538 stop("Only one mode pointer definition allowed",
539 EX_DATAERR);
540 /* NOTREACHED */
541 }
542 mode_ptr.symbol = cur_symbol;
543 }
544;
545
546allones:
547 T_ALLONES
548 {
549 if (allones.symbol != NULL) {
550 stop("Only one definition of allones allowed",
551 EX_DATAERR);
552 /* NOTREACHED */
553 }
554 allones.symbol = cur_symbol;
555 }
556;
557
558allzeros:
559 T_ALLZEROS
560 {
561 if (allzeros.symbol != NULL) {
562 stop("Only one definition of allzeros allowed",
563 EX_DATAERR);
564 /* NOTREACHED */
565 }
566 allzeros.symbol = cur_symbol;
567 }
568;
569
570none:
571 T_NONE
572 {
573 if (none.symbol != NULL) {
574 stop("Only one definition of none allowed",
575 EX_DATAERR);
576 /* NOTREACHED */
577 }
578 none.symbol = cur_symbol;
579 }
580;
581
582sindex:
583 T_SINDEX
584 {
585 if (sindex.symbol != NULL) {
586 stop("Only one definition of sindex allowed",
587 EX_DATAERR);
588 /* NOTREACHED */
589 }
590 sindex.symbol = cur_symbol;
591 }
592;
593
594expression:
595 expression '|' expression
596 {
597 $$.value = $1.value | $3.value;
598 symlist_merge(&$$.referenced_syms,
599 &$1.referenced_syms,
600 &$3.referenced_syms);
601 }
602| expression '&' expression
603 {
604 $$.value = $1.value & $3.value;
605 symlist_merge(&$$.referenced_syms,
606 &$1.referenced_syms,
607 &$3.referenced_syms);
608 }
609| expression '+' expression
610 {
611 $$.value = $1.value + $3.value;
612 symlist_merge(&$$.referenced_syms,
613 &$1.referenced_syms,
614 &$3.referenced_syms);
615 }
616| expression '-' expression
617 {
618 $$.value = $1.value - $3.value;
619 symlist_merge(&($$.referenced_syms),
620 &($1.referenced_syms),
621 &($3.referenced_syms));
622 }
623| expression '*' expression
624 {
625 $$.value = $1.value * $3.value;
626 symlist_merge(&($$.referenced_syms),
627 &($1.referenced_syms),
628 &($3.referenced_syms));
629 }
630| expression '/' expression
631 {
632 $$.value = $1.value / $3.value;
633 symlist_merge(&($$.referenced_syms),
634 &($1.referenced_syms),
635 &($3.referenced_syms));
636 }
637| expression T_EXPR_LSHIFT expression
638 {
639 $$.value = $1.value << $3.value;
640 symlist_merge(&$$.referenced_syms,
641 &$1.referenced_syms,
642 &$3.referenced_syms);
643 }
644| expression T_EXPR_RSHIFT expression
645 {
646 $$.value = $1.value >> $3.value;
647 symlist_merge(&$$.referenced_syms,
648 &$1.referenced_syms,
649 &$3.referenced_syms);
650 }
651| '(' expression ')'
652 {
653 $$ = $2;
654 }
655| '~' expression
656 {
657 $$ = $2;
658 $$.value = (~$$.value) & 0xFF;
659 }
660| '-' expression %prec UMINUS
661 {
662 $$ = $2;
663 $$.value = -$$.value;
664 }
665| T_NUMBER
666 {
667 $$.value = $1;
668 SLIST_INIT(&$$.referenced_syms);
669 }
670| T_SYMBOL
671 {
672 symbol_t *symbol;
673
674 symbol = $1;
675 switch (symbol->type) {
676 case ALIAS:
677 symbol = $1->info.ainfo->parent;
678 case REGISTER:
679 case SCBLOC:
680 case SRAMLOC:
681 $$.value = symbol->info.rinfo->address;
682 break;
683 case MASK:
684 case FIELD:
685 case ENUM:
686 case ENUM_ENTRY:
687 $$.value = symbol->info.finfo->value;
688 break;
689 case DOWNLOAD_CONST:
690 case CONST:
691 $$.value = symbol->info.cinfo->value;
692 break;
693 case UNINITIALIZED:
694 default:
695 {
696 snprintf(errbuf, sizeof(errbuf),
697 "Undefined symbol %s referenced",
698 symbol->name);
699 stop(errbuf, EX_DATAERR);
700 /* NOTREACHED */
701 break;
702 }
703 }
704 SLIST_INIT(&$$.referenced_syms);
705 symlist_add(&$$.referenced_syms, symbol, SYMLIST_INSERT_HEAD);
706 }
707;
708
709constant:
710 T_CONST T_SYMBOL expression
711 {
712 if ($2->type != UNINITIALIZED) {
713 stop("Re-definition of symbol as a constant",
714 EX_DATAERR);
715 /* NOTREACHED */
716 }
717 $2->type = CONST;
718 initialize_symbol($2);
719 $2->info.cinfo->value = $3.value;
720 }
721| T_CONST T_SYMBOL T_DOWNLOAD
722 {
723 if ($1) {
724 stop("Invalid downloaded constant declaration",
725 EX_DATAERR);
726 /* NOTREACHED */
727 }
728 if ($2->type != UNINITIALIZED) {
729 stop("Re-definition of symbol as a downloaded constant",
730 EX_DATAERR);
731 /* NOTREACHED */
732 }
733 $2->type = DOWNLOAD_CONST;
734 initialize_symbol($2);
735 $2->info.cinfo->value = download_constant_count++;
736 }
737;
738
739macrodefn_prologue:
740 T_DEFINE T_SYMBOL
741 {
742 if ($2->type != UNINITIALIZED) {
743 stop("Re-definition of symbol as a macro",
744 EX_DATAERR);
745 /* NOTREACHED */
746 }
747 cur_symbol = $2;
748 cur_symbol->type = MACRO;
749 initialize_symbol(cur_symbol);
750 }
751;
752
753macrodefn:
754 macrodefn_prologue T_MACROBODY
755 {
756 add_macro_body($2);
757 }
758| macrodefn_prologue '(' macro_arglist ')' T_MACROBODY
759 {
760 add_macro_body($5);
761 cur_symbol->info.macroinfo->narg = $3;
762 }
763;
764
765macro_arglist:
766 {
767 /* Macros can take no arguments */
768 $$ = 0;
769 }
770| T_ARG
771 {
772 $$ = 1;
773 add_macro_arg($1, 0);
774 }
775| macro_arglist ',' T_ARG
776 {
777 if ($1 == 0) {
778 stop("Comma without preceeding argument in arg list",
779 EX_DATAERR);
780 /* NOTREACHED */
781 }
782 $$ = $1 + 1;
783 add_macro_arg($3, $1);
784 }
785;
786
787scratch_ram:
788 T_SRAM '{'
789 {
790 snprintf(errbuf, sizeof(errbuf), "%s%d", SRAM_SYMNAME,
791 num_srams);
792 cur_symbol = symtable_get(SRAM_SYMNAME);
793 cur_symtype = SRAMLOC;
794 cur_symbol->type = SRAMLOC;
795 initialize_symbol(cur_symbol);
796 }
797 reg_address
798 {
799 sram_or_scb_offset = cur_symbol->info.rinfo->address;
800 }
801 size
802 {
803 scb_or_sram_symbol = cur_symbol;
804 }
805 scb_or_sram_attributes
806 '}'
807 {
808 cur_symbol = NULL;
809 scb_or_sram_symbol = NULL;
810 }
811;
812
813scb:
814 T_SCB '{'
815 {
816 cur_symbol = symtable_get(SCB_SYMNAME);
817 cur_symtype = SCBLOC;
818 if (cur_symbol->type != UNINITIALIZED) {
819 stop("Only one SRAM definition allowed",
820 EX_SOFTWARE);
821 /* NOTREACHED */
822 }
823 cur_symbol->type = SCBLOC;
824 initialize_symbol(cur_symbol);
825 /* 64 bytes of SCB space */
826 cur_symbol->info.rinfo->size = 64;
827 }
828 reg_address
829 {
830 sram_or_scb_offset = cur_symbol->info.rinfo->address;
831 }
832 size
833 {
834 scb_or_sram_symbol = cur_symbol;
835 }
836 scb_or_sram_attributes
837 '}'
838 {
839 cur_symbol = NULL;
840 scb_or_sram_symbol = NULL;
841 }
842;
843
844scb_or_sram_attributes:
845 /* NULL definition is okay */
846| modes
847| scb_or_sram_reg_list
848| modes scb_or_sram_reg_list
849;
850
851scb_or_sram_reg_list:
852 reg_definition
853| scb_or_sram_reg_list reg_definition
854;
855
856reg_symbol:
857 T_SYMBOL
858 {
859 process_register(&$1);
860 $$.symbol = $1;
861 $$.offset = 0;
862 }
863| T_SYMBOL '[' T_SYMBOL ']'
864 {
865 process_register(&$1);
866 if ($3->type != CONST) {
867 stop("register offset must be a constant", EX_DATAERR);
868 /* NOTREACHED */
869 }
870 if (($3->info.cinfo->value + 1) > $1->info.rinfo->size) {
871 stop("Accessing offset beyond range of register",
872 EX_DATAERR);
873 /* NOTREACHED */
874 }
875 $$.symbol = $1;
876 $$.offset = $3->info.cinfo->value;
877 }
878| T_SYMBOL '[' T_NUMBER ']'
879 {
880 process_register(&$1);
881 if (($3 + 1) > $1->info.rinfo->size) {
882 stop("Accessing offset beyond range of register",
883 EX_DATAERR);
884 /* NOTREACHED */
885 }
886 $$.symbol = $1;
887 $$.offset = $3;
888 }
889| T_A
890 {
891 if (accumulator.symbol == NULL) {
892 stop("No accumulator has been defined", EX_DATAERR);
893 /* NOTREACHED */
894 }
895 $$.symbol = accumulator.symbol;
896 $$.offset = 0;
897 }
898;
899
900destination:
901 reg_symbol
902 {
903 test_writable_symbol($1.symbol);
904 $$ = $1;
905 }
906;
907
908immediate:
909 expression
910 { $$ = $1; }
911;
912
913immediate_or_a:
914 expression
915 {
916 if ($1.value == 0 && is_download_const(&$1) == 0) {
917 snprintf(errbuf, sizeof(errbuf),
918 "\nExpression evaluates to 0 and thus "
919 "references the accumulator.\n "
920 "If this is the desired effect, use 'A' "
921 "instead.\n");
922 stop(errbuf, EX_DATAERR);
923 }
924 $$ = $1;
925 }
926| T_A
927 {
928 SLIST_INIT(&$$.referenced_syms);
929 symlist_add(&$$.referenced_syms, accumulator.symbol,
930 SYMLIST_INSERT_HEAD);
931 $$.value = 0;
932 }
933;
934
935source:
936 reg_symbol
937 {
938 test_readable_symbol($1.symbol);
939 $$ = $1;
940 }
941;
942
943opt_source:
944 {
945 $$.symbol = NULL;
946 $$.offset = 0;
947 }
948| ',' source
949 { $$ = $2; }
950;
951
952ret:
953 { $$ = 0; }
954| T_RET
955 { $$ = 1; }
956;
957
958set_src_mode:
959 T_SET_SRC_MODE T_NUMBER ';'
960 {
961 src_mode = $2;
962 }
963;
964
965set_dst_mode:
966 T_SET_DST_MODE T_NUMBER ';'
967 {
968 dst_mode = $2;
969 }
970;
971
972critical_section_start:
973 T_BEGIN_CS ';'
974 {
975 critical_section_t *cs;
976
977 if (in_critical_section != FALSE) {
978 stop("Critical Section within Critical Section",
979 EX_DATAERR);
980 /* NOTREACHED */
981 }
982 cs = cs_alloc();
983 cs->begin_addr = instruction_ptr;
984 in_critical_section = TRUE;
985 }
986;
987
988critical_section_end:
989 T_END_CS ';'
990 {
991 critical_section_t *cs;
992
993 if (in_critical_section == FALSE) {
994 stop("Unballanced 'end_cs'", EX_DATAERR);
995 /* NOTREACHED */
996 }
997 cs = TAILQ_LAST(&cs_tailq, cs_tailq);
998 cs->end_addr = instruction_ptr;
999 in_critical_section = FALSE;
1000 }
1001;
1002
1003export:
1004 { $$ = 0; }
1005| T_EXPORT
1006 { $$ = 1; }
1007;
1008
1009label:
1010 export T_SYMBOL ':'
1011 {
1012 if ($2->type != UNINITIALIZED) {
1013 stop("Program label multiply defined", EX_DATAERR);
1014 /* NOTREACHED */
1015 }
1016 $2->type = LABEL;
1017 initialize_symbol($2);
1018 $2->info.linfo->address = instruction_ptr;
1019 $2->info.linfo->exported = $1;
1020 }
1021;
1022
1023address:
1024 T_SYMBOL
1025 {
1026 $$.symbol = $1;
1027 $$.offset = 0;
1028 }
1029| T_SYMBOL '+' T_NUMBER
1030 {
1031 $$.symbol = $1;
1032 $$.offset = $3;
1033 }
1034| T_SYMBOL '-' T_NUMBER
1035 {
1036 $$.symbol = $1;
1037 $$.offset = -$3;
1038 }
1039| '.'
1040 {
1041 $$.symbol = NULL;
1042 $$.offset = 0;
1043 }
1044| '.' '+' T_NUMBER
1045 {
1046 $$.symbol = NULL;
1047 $$.offset = $3;
1048 }
1049| '.' '-' T_NUMBER
1050 {
1051 $$.symbol = NULL;
1052 $$.offset = -$3;
1053 }
1054;
1055
1056conditional:
1057 T_IF T_CEXPR '{'
1058 {
1059 scope_t *new_scope;
1060
1061 add_conditional($2);
1062 new_scope = scope_alloc();
1063 new_scope->type = SCOPE_IF;
1064 new_scope->begin_addr = instruction_ptr;
1065 new_scope->func_num = $2->info.condinfo->func_num;
1066 }
1067| T_ELSE T_IF T_CEXPR '{'
1068 {
1069 scope_t *new_scope;
1070 scope_t *scope_context;
1071 scope_t *last_scope;
1072
1073 /*
1074 * Ensure that the previous scope is either an
1075 * if or and else if.
1076 */
1077 scope_context = SLIST_FIRST(&scope_stack);
1078 last_scope = TAILQ_LAST(&scope_context->inner_scope,
1079 scope_tailq);
1080 if (last_scope == NULL
1081 || last_scope->type == T_ELSE) {
1082
1083 stop("'else if' without leading 'if'", EX_DATAERR);
1084 /* NOTREACHED */
1085 }
1086 add_conditional($3);
1087 new_scope = scope_alloc();
1088 new_scope->type = SCOPE_ELSE_IF;
1089 new_scope->begin_addr = instruction_ptr;
1090 new_scope->func_num = $3->info.condinfo->func_num;
1091 }
1092| T_ELSE '{'
1093 {
1094 scope_t *new_scope;
1095 scope_t *scope_context;
1096 scope_t *last_scope;
1097
1098 /*
1099 * Ensure that the previous scope is either an
1100 * if or and else if.
1101 */
1102 scope_context = SLIST_FIRST(&scope_stack);
1103 last_scope = TAILQ_LAST(&scope_context->inner_scope,
1104 scope_tailq);
1105 if (last_scope == NULL
1106 || last_scope->type == SCOPE_ELSE) {
1107
1108 stop("'else' without leading 'if'", EX_DATAERR);
1109 /* NOTREACHED */
1110 }
1111 new_scope = scope_alloc();
1112 new_scope->type = SCOPE_ELSE;
1113 new_scope->begin_addr = instruction_ptr;
1114 }
1115;
1116
1117conditional:
1118 '}'
1119 {
1120 scope_t *scope_context;
1121
1122 scope_context = SLIST_FIRST(&scope_stack);
1123 if (scope_context->type == SCOPE_ROOT) {
1124 stop("Unexpected '}' encountered", EX_DATAERR);
1125 /* NOTREACHED */
1126 }
1127
1128 scope_context->end_addr = instruction_ptr;
1129
1130 /* Pop the scope */
1131 SLIST_REMOVE_HEAD(&scope_stack, scope_stack_links);
1132
1133 process_scope(scope_context);
1134
1135 if (SLIST_FIRST(&scope_stack) == NULL) {
1136 stop("Unexpected '}' encountered", EX_DATAERR);
1137 /* NOTREACHED */
1138 }
1139 }
1140;
1141
1142f1_opcode:
1143 T_AND { $$ = AIC_OP_AND; }
1144| T_XOR { $$ = AIC_OP_XOR; }
1145| T_ADD { $$ = AIC_OP_ADD; }
1146| T_ADC { $$ = AIC_OP_ADC; }
1147;
1148
1149code:
1150 f1_opcode destination ',' immediate_or_a opt_source ret ';'
1151 {
1152 format_1_instr($1, &$2, &$4, &$5, $6);
1153 }
1154;
1155
1156code:
1157 T_OR reg_symbol ',' immediate_or_a opt_source ret ';'
1158 {
1159 format_1_instr(AIC_OP_OR, &$2, &$4, &$5, $6);
1160 }
1161;
1162
1163code:
1164 T_INC destination opt_source ret ';'
1165 {
1166 expression_t immed;
1167
1168 make_expression(&immed, 1);
1169 format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4);
1170 }
1171;
1172
1173code:
1174 T_DEC destination opt_source ret ';'
1175 {
1176 expression_t immed;
1177
1178 make_expression(&immed, -1);
1179 format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4);
1180 }
1181;
1182
1183code:
1184 T_CLC ret ';'
1185 {
1186 expression_t immed;
1187
1188 make_expression(&immed, -1);
1189 format_1_instr(AIC_OP_ADD, &none, &immed, &allzeros, $2);
1190 }
1191| T_CLC T_MVI destination ',' immediate_or_a ret ';'
1192 {
1193 format_1_instr(AIC_OP_ADD, &$3, &$5, &allzeros, $6);
1194 }
1195;
1196
1197code:
1198 T_STC ret ';'
1199 {
1200 expression_t immed;
1201
1202 make_expression(&immed, 1);
1203 format_1_instr(AIC_OP_ADD, &none, &immed, &allones, $2);
1204 }
1205| T_STC destination ret ';'
1206 {
1207 expression_t immed;
1208
1209 make_expression(&immed, 1);
1210 format_1_instr(AIC_OP_ADD, &$2, &immed, &allones, $3);
1211 }
1212;
1213
1214code:
1215 T_BMOV destination ',' source ',' immediate ret ';'
1216 {
1217 format_1_instr(AIC_OP_BMOV, &$2, &$6, &$4, $7);
1218 }
1219;
1220
1221code:
1222 T_MOV destination ',' source ret ';'
1223 {
1224 expression_t immed;
1225
1226 make_expression(&immed, 1);
1227 format_1_instr(AIC_OP_BMOV, &$2, &immed, &$4, $5);
1228 }
1229;
1230
1231code:
1232 T_MVI destination ',' immediate ret ';'
1233 {
1234 if ($4.value == 0
1235 && is_download_const(&$4) == 0) {
1236 expression_t immed;
1237
1238 /*
1239 * Allow move immediates of 0 so that macros,
1240 * that can't know the immediate's value and
1241 * otherwise compensate, still work.
1242 */
1243 make_expression(&immed, 1);
1244 format_1_instr(AIC_OP_BMOV, &$2, &immed, &allzeros, $5);
1245 } else {
1246 format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5);
1247 }
1248 }
1249;
1250
1251code:
1252 T_NOT destination opt_source ret ';'
1253 {
1254 expression_t immed;
1255
1256 make_expression(&immed, 0xff);
1257 format_1_instr(AIC_OP_XOR, &$2, &immed, &$3, $4);
1258 }
1259;
1260
1261code:
1262 T_CLR destination ret ';'
1263 {
1264 expression_t immed;
1265
1266 make_expression(&immed, 0xff);
1267 format_1_instr(AIC_OP_AND, &$2, &immed, &allzeros, $3);
1268 }
1269;
1270
1271code:
1272 T_NOP ret ';'
1273 {
1274 expression_t immed;
1275
1276 make_expression(&immed, 0xff);
1277 format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, $2);
1278 }
1279;
1280
1281code:
1282 T_RET ';'
1283 {
1284 expression_t immed;
1285
1286 make_expression(&immed, 0xff);
1287 format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, TRUE);
1288 }
1289;
1290
1291 /*
1292 * This grammer differs from the one in the aic7xxx
1293 * reference manual since the grammer listed there is
1294 * ambiguous and causes a shift/reduce conflict.
1295 * It also seems more logical as the "immediate"
1296 * argument is listed as the second arg like the
1297 * other formats.
1298 */
1299
1300f2_opcode:
1301 T_SHL { $$ = AIC_OP_SHL; }
1302| T_SHR { $$ = AIC_OP_SHR; }
1303| T_ROL { $$ = AIC_OP_ROL; }
1304| T_ROR { $$ = AIC_OP_ROR; }
1305;
1306
1307code:
1308 f2_opcode destination ',' expression opt_source ret ';'
1309 {
1310 format_2_instr($1, &$2, &$4, &$5, $6);
1311 }
1312;
1313
1314jmp_jc_jnc_call:
1315 T_JMP { $$ = AIC_OP_JMP; }
1316| T_JC { $$ = AIC_OP_JC; }
1317| T_JNC { $$ = AIC_OP_JNC; }
1318| T_CALL { $$ = AIC_OP_CALL; }
1319;
1320
1321jz_jnz:
1322 T_JZ { $$ = AIC_OP_JZ; }
1323| T_JNZ { $$ = AIC_OP_JNZ; }
1324;
1325
1326je_jne:
1327 T_JE { $$ = AIC_OP_JE; }
1328| T_JNE { $$ = AIC_OP_JNE; }
1329;
1330
1331code:
1332 jmp_jc_jnc_call address ';'
1333 {
1334 expression_t immed;
1335
1336 make_expression(&immed, 0);
1337 format_3_instr($1, &sindex, &immed, &$2);
1338 }
1339;
1340
1341code:
1342 T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';'
1343 {
1344 format_3_instr($5, &$2, &$4, &$6);
1345 }
1346;
1347
1348code:
1349 T_TEST source ',' immediate_or_a jz_jnz address ';'
1350 {
1351 format_3_instr($5, &$2, &$4, &$6);
1352 }
1353;
1354
1355code:
1356 T_CMP source ',' immediate_or_a je_jne address ';'
1357 {
1358 format_3_instr($5, &$2, &$4, &$6);
1359 }
1360;
1361
1362code:
1363 T_MOV source jmp_jc_jnc_call address ';'
1364 {
1365 expression_t immed;
1366
1367 make_expression(&immed, 0);
1368 format_3_instr($3, &$2, &immed, &$4);
1369 }
1370;
1371
1372code:
1373 T_MVI immediate jmp_jc_jnc_call address ';'
1374 {
1375 format_3_instr($3, &allzeros, &$2, &$4);
1376 }
1377;
1378
1379%%
1380
1381static void
1382process_field(int field_type, symbol_t *sym, int value)
1383{
1384 /*
1385 * Add the current register to its
1386 * symbol list, if it already exists,
1387 * warn if we are setting it to a
1388 * different value, or in the bit to
1389 * the "allowed bits" of this register.
1390 */
1391 if (sym->type == UNINITIALIZED) {
1392 sym->type = field_type;
1393 initialize_symbol(sym);
1394 sym->info.finfo->value = value;
1395 if (field_type != ENUM_ENTRY) {
1396 if (field_type != MASK && value == 0) {
1397 stop("Empty Field, or Enum", EX_DATAERR);
1398 /* NOTREACHED */
1399 }
1400 sym->info.finfo->value = value;
1401 sym->info.finfo->mask = value;
1402 } else if (field_symbol != NULL) {
1403 sym->info.finfo->mask = field_symbol->info.finfo->value;
1404 } else {
1405 sym->info.finfo->mask = 0xFF;
1406 }
1407 } else if (sym->type != field_type) {
1408 stop("Field definition mirrors a definition of the same "
1409 " name, but a different type", EX_DATAERR);
1410 /* NOTREACHED */
1411 } else if (value != sym->info.finfo->value) {
1412 stop("Field redefined with a conflicting value", EX_DATAERR);
1413 /* NOTREACHED */
1414 }
1415 /* Fail if this symbol is already listed */
1416 if (symlist_search(&(sym->info.finfo->symrefs),
1417 cur_symbol->name) != NULL) {
1418 stop("Field defined multiple times for register", EX_DATAERR);
1419 /* NOTREACHED */
1420 }
1421 symlist_add(&(sym->info.finfo->symrefs), cur_symbol,
1422 SYMLIST_INSERT_HEAD);
1423 cur_symbol->info.rinfo->valid_bitmask |= sym->info.finfo->mask;
1424 cur_symbol->info.rinfo->typecheck_masks = TRUE;
1425 symlist_add(&(cur_symbol->info.rinfo->fields), sym, SYMLIST_SORT);
1426}
1427
1428static void
1429initialize_symbol(symbol_t *symbol)
1430{
1431 switch (symbol->type) {
1432 case UNINITIALIZED:
1433 stop("Call to initialize_symbol with type field unset",
1434 EX_SOFTWARE);
1435 /* NOTREACHED */
1436 break;
1437 case REGISTER:
1438 case SRAMLOC:
1439 case SCBLOC:
1440 symbol->info.rinfo =
1441 (struct reg_info *)malloc(sizeof(struct reg_info));
1442 if (symbol->info.rinfo == NULL) {
1443 stop("Can't create register info", EX_SOFTWARE);
1444 /* NOTREACHED */
1445 }
1446 memset(symbol->info.rinfo, 0,
1447 sizeof(struct reg_info));
1448 SLIST_INIT(&(symbol->info.rinfo->fields));
1449 /*
1450 * Default to allowing access in all register modes
1451 * or to the mode specified by the SCB or SRAM space
1452 * we are in.
1453 */
1454 if (scb_or_sram_symbol != NULL)
1455 symbol->info.rinfo->modes =
1456 scb_or_sram_symbol->info.rinfo->modes;
1457 else
1458 symbol->info.rinfo->modes = ~0;
1459 break;
1460 case ALIAS:
1461 symbol->info.ainfo =
1462 (struct alias_info *)malloc(sizeof(struct alias_info));
1463 if (symbol->info.ainfo == NULL) {
1464 stop("Can't create alias info", EX_SOFTWARE);
1465 /* NOTREACHED */
1466 }
1467 memset(symbol->info.ainfo, 0,
1468 sizeof(struct alias_info));
1469 break;
1470 case MASK:
1471 case FIELD:
1472 case ENUM:
1473 case ENUM_ENTRY:
1474 symbol->info.finfo =
1475 (struct field_info *)malloc(sizeof(struct field_info));
1476 if (symbol->info.finfo == NULL) {
1477 stop("Can't create field info", EX_SOFTWARE);
1478 /* NOTREACHED */
1479 }
1480 memset(symbol->info.finfo, 0, sizeof(struct field_info));
1481 SLIST_INIT(&(symbol->info.finfo->symrefs));
1482 break;
1483 case CONST:
1484 case DOWNLOAD_CONST:
1485 symbol->info.cinfo =
1486 (struct const_info *)malloc(sizeof(struct const_info));
1487 if (symbol->info.cinfo == NULL) {
1488 stop("Can't create alias info", EX_SOFTWARE);
1489 /* NOTREACHED */
1490 }
1491 memset(symbol->info.cinfo, 0,
1492 sizeof(struct const_info));
1493 break;
1494 case LABEL:
1495 symbol->info.linfo =
1496 (struct label_info *)malloc(sizeof(struct label_info));
1497 if (symbol->info.linfo == NULL) {
1498 stop("Can't create label info", EX_SOFTWARE);
1499 /* NOTREACHED */
1500 }
1501 memset(symbol->info.linfo, 0,
1502 sizeof(struct label_info));
1503 break;
1504 case CONDITIONAL:
1505 symbol->info.condinfo =
1506 (struct cond_info *)malloc(sizeof(struct cond_info));
1507 if (symbol->info.condinfo == NULL) {
1508 stop("Can't create conditional info", EX_SOFTWARE);
1509 /* NOTREACHED */
1510 }
1511 memset(symbol->info.condinfo, 0,
1512 sizeof(struct cond_info));
1513 break;
1514 case MACRO:
1515 symbol->info.macroinfo =
1516 (struct macro_info *)malloc(sizeof(struct macro_info));
1517 if (symbol->info.macroinfo == NULL) {
1518 stop("Can't create macro info", EX_SOFTWARE);
1519 /* NOTREACHED */
1520 }
1521 memset(symbol->info.macroinfo, 0,
1522 sizeof(struct macro_info));
1523 STAILQ_INIT(&symbol->info.macroinfo->args);
1524 break;
1525 default:
1526 stop("Call to initialize_symbol with invalid symbol type",
1527 EX_SOFTWARE);
1528 /* NOTREACHED */
1529 break;
1530 }
1531}
1532
1533static void
1534add_macro_arg(const char *argtext, int argnum)
1535{
1536 struct macro_arg *marg;
1537 int i;
1538 int retval;
1539
1540
1541 if (cur_symbol == NULL || cur_symbol->type != MACRO) {
1542 stop("Invalid current symbol for adding macro arg",
1543 EX_SOFTWARE);
1544 /* NOTREACHED */
1545 }
1546
1547 marg = (struct macro_arg *)malloc(sizeof(*marg));
1548 if (marg == NULL) {
1549 stop("Can't create macro_arg structure", EX_SOFTWARE);
1550 /* NOTREACHED */
1551 }
1552 marg->replacement_text = NULL;
1553 retval = snprintf(regex_pattern, sizeof(regex_pattern),
1554 "[^-/A-Za-z0-9_](%s)([^-/A-Za-z0-9_]|$)",
1555 argtext);
1556 if (retval >= sizeof(regex_pattern)) {
1557 stop("Regex text buffer too small for arg",
1558 EX_SOFTWARE);
1559 /* NOTREACHED */
1560 }
1561 retval = regcomp(&marg->arg_regex, regex_pattern, REG_EXTENDED);
1562 if (retval != 0) {
1563 stop("Regex compilation failed", EX_SOFTWARE);
1564 /* NOTREACHED */
1565 }
1566 STAILQ_INSERT_TAIL(&cur_symbol->info.macroinfo->args, marg, links);
1567}
1568
1569static void
1570add_macro_body(const char *bodytext)
1571{
1572 if (cur_symbol == NULL || cur_symbol->type != MACRO) {
1573 stop("Invalid current symbol for adding macro arg",
1574 EX_SOFTWARE);
1575 /* NOTREACHED */
1576 }
1577 cur_symbol->info.macroinfo->body = strdup(bodytext);
1578 if (cur_symbol->info.macroinfo->body == NULL) {
1579 stop("Can't duplicate macro body text", EX_SOFTWARE);
1580 /* NOTREACHED */
1581 }
1582}
1583
1584static void
1585process_register(symbol_t **p_symbol)
1586{
1587 symbol_t *symbol = *p_symbol;
1588
1589 if (symbol->type == UNINITIALIZED) {
1590 snprintf(errbuf, sizeof(errbuf), "Undefined register %s",
1591 symbol->name);
1592 stop(errbuf, EX_DATAERR);
1593 /* NOTREACHED */
1594 } else if (symbol->type == ALIAS) {
1595 *p_symbol = symbol->info.ainfo->parent;
1596 } else if ((symbol->type != REGISTER)
1597 && (symbol->type != SCBLOC)
1598 && (symbol->type != SRAMLOC)) {
1599 snprintf(errbuf, sizeof(errbuf),
1600 "Specified symbol %s is not a register",
1601 symbol->name);
1602 stop(errbuf, EX_DATAERR);
1603 }
1604}
1605
1606static void
1607format_1_instr(int opcode, symbol_ref_t *dest, expression_t *immed,
1608 symbol_ref_t *src, int ret)
1609{
1610 struct instruction *instr;
1611 struct ins_format1 *f1_instr;
1612
1613 if (src->symbol == NULL)
1614 src = dest;
1615
1616 /* Test register permissions */
1617 test_writable_symbol(dest->symbol);
1618 test_readable_symbol(src->symbol);
1619
1620 /* Ensure that immediate makes sense for this destination */
1621 type_check(dest->symbol, immed, opcode);
1622
1623 /* Allocate sequencer space for the instruction and fill it out */
1624 instr = seq_alloc();
1625 f1_instr = &instr->format.format1;
1626 f1_instr->ret = ret ? 1 : 0;
1627 f1_instr->opcode = opcode;
1628 f1_instr->destination = dest->symbol->info.rinfo->address
1629 + dest->offset;
1630 f1_instr->source = src->symbol->info.rinfo->address
1631 + src->offset;
1632 f1_instr->immediate = immed->value;
1633
1634 if (is_download_const(immed))
1635 f1_instr->parity = 1;
1636 else if (dest->symbol == mode_ptr.symbol) {
1637 u_int src_value;
1638 u_int dst_value;
1639
1640 /*
1641 * Attempt to update mode information if
1642 * we are operating on the mode register.
1643 */
1644 if (src->symbol == allones.symbol)
1645 src_value = 0xFF;
1646 else if (src->symbol == allzeros.symbol)
1647 src_value = 0;
1648 else if (src->symbol == mode_ptr.symbol)
1649 src_value = (dst_mode << 4) | src_mode;
1650 else
1651 goto cant_update;
1652
1653 switch (opcode) {
1654 case AIC_OP_AND:
1655 dst_value = src_value & immed->value;
1656 break;
1657 case AIC_OP_XOR:
1658 dst_value = src_value ^ immed->value;
1659 break;
1660 case AIC_OP_ADD:
1661 dst_value = (src_value + immed->value) & 0xFF;
1662 break;
1663 case AIC_OP_OR:
1664 dst_value = src_value | immed->value;
1665 break;
1666 case AIC_OP_BMOV:
1667 dst_value = src_value;
1668 break;
1669 default:
1670 goto cant_update;
1671 }
1672 src_mode = dst_value & 0xF;
1673 dst_mode = (dst_value >> 4) & 0xF;
1674 }
1675
1676cant_update:
1677 symlist_free(&immed->referenced_syms);
1678 instruction_ptr++;
1679}
1680
1681static void
1682format_2_instr(int opcode, symbol_ref_t *dest, expression_t *places,
1683 symbol_ref_t *src, int ret)
1684{
1685 struct instruction *instr;
1686 struct ins_format2 *f2_instr;
1687 uint8_t shift_control;
1688
1689 if (src->symbol == NULL)
1690 src = dest;
1691
1692 /* Test register permissions */
1693 test_writable_symbol(dest->symbol);
1694 test_readable_symbol(src->symbol);
1695
1696 /* Allocate sequencer space for the instruction and fill it out */
1697 instr = seq_alloc();
1698 f2_instr = &instr->format.format2;
1699 f2_instr->ret = ret ? 1 : 0;
1700 f2_instr->opcode = AIC_OP_ROL;
1701 f2_instr->destination = dest->symbol->info.rinfo->address
1702 + dest->offset;
1703 f2_instr->source = src->symbol->info.rinfo->address
1704 + src->offset;
1705 if (places->value > 8 || places->value <= 0) {
1706 stop("illegal shift value", EX_DATAERR);
1707 /* NOTREACHED */
1708 }
1709 switch (opcode) {
1710 case AIC_OP_SHL:
1711 if (places->value == 8)
1712 shift_control = 0xf0;
1713 else
1714 shift_control = (places->value << 4) | places->value;
1715 break;
1716 case AIC_OP_SHR:
1717 if (places->value == 8) {
1718 shift_control = 0xf8;
1719 } else {
1720 shift_control = (places->value << 4)
1721 | (8 - places->value)
1722 | 0x08;
1723 }
1724 break;
1725 case AIC_OP_ROL:
1726 shift_control = places->value & 0x7;
1727 break;
1728 case AIC_OP_ROR:
1729 shift_control = (8 - places->value) | 0x08;
1730 break;
1731 default:
1732 shift_control = 0; /* Quiet Compiler */
1733 stop("Invalid shift operation specified", EX_SOFTWARE);
1734 /* NOTREACHED */
1735 break;
1736 };
1737 f2_instr->shift_control = shift_control;
1738 symlist_free(&places->referenced_syms);
1739 instruction_ptr++;
1740}
1741
1742static void
1743format_3_instr(int opcode, symbol_ref_t *src,
1744 expression_t *immed, symbol_ref_t *address)
1745{
1746 struct instruction *instr;
1747 struct ins_format3 *f3_instr;
1748 int addr;
1749
1750 /* Test register permissions */
1751 test_readable_symbol(src->symbol);
1752
1753 /* Ensure that immediate makes sense for this source */
1754 type_check(src->symbol, immed, opcode);
1755
1756 /* Allocate sequencer space for the instruction and fill it out */
1757 instr = seq_alloc();
1758 f3_instr = &instr->format.format3;
1759 if (address->symbol == NULL) {
1760 /* 'dot' referrence. Use the current instruction pointer */
1761 addr = instruction_ptr + address->offset;
1762 } else if (address->symbol->type == UNINITIALIZED) {
1763 /* forward reference */
1764 addr = address->offset;
1765 instr->patch_label = address->symbol;
1766 } else
1767 addr = address->symbol->info.linfo->address + address->offset;
1768 f3_instr->opcode = opcode;
1769 f3_instr->address = addr;
1770 f3_instr->source = src->symbol->info.rinfo->address
1771 + src->offset;
1772 f3_instr->immediate = immed->value;
1773
1774 if (is_download_const(immed))
1775 f3_instr->parity = 1;
1776
1777 symlist_free(&immed->referenced_syms);
1778 instruction_ptr++;
1779}
1780
1781static void
1782test_readable_symbol(symbol_t *symbol)
1783{
1784
1785 if ((symbol->info.rinfo->modes & (0x1 << src_mode)) == 0) {
1786 snprintf(errbuf, sizeof(errbuf),
1787 "Register %s unavailable in source reg mode %d",
1788 symbol->name, src_mode);
1789 stop(errbuf, EX_DATAERR);
1790 }
1791
1792 if (symbol->info.rinfo->mode == WO) {
1793 stop("Write Only register specified as source",
1794 EX_DATAERR);
1795 /* NOTREACHED */
1796 }
1797}
1798
1799static void
1800test_writable_symbol(symbol_t *symbol)
1801{
1802
1803 if ((symbol->info.rinfo->modes & (0x1 << dst_mode)) == 0) {
1804 snprintf(errbuf, sizeof(errbuf),
1805 "Register %s unavailable in destination reg mode %d",
1806 symbol->name, dst_mode);
1807 stop(errbuf, EX_DATAERR);
1808 }
1809
1810 if (symbol->info.rinfo->mode == RO) {
1811 stop("Read Only register specified as destination",
1812 EX_DATAERR);
1813 /* NOTREACHED */
1814 }
1815}
1816
1817static void
1818type_check(symbol_t *symbol, expression_t *expression, int opcode)
1819{
1820 symbol_node_t *node;
1821 int and_op;
1822
1823 and_op = FALSE;
1824 if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ)
1825 and_op = TRUE;
1826
1827 /*
1828 * Make sure that we aren't attempting to write something
1829 * that hasn't been defined. If this is an and operation,
1830 * this is a mask, so "undefined" bits are okay.
1831 */
1832 if (and_op == FALSE
1833 && (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) {
1834 snprintf(errbuf, sizeof(errbuf),
1835 "Invalid bit(s) 0x%x in immediate written to %s",
1836 expression->value & ~symbol->info.rinfo->valid_bitmask,
1837 symbol->name);
1838 stop(errbuf, EX_DATAERR);
1839 /* NOTREACHED */
1840 }
1841
1842 /*
1843 * Now make sure that all of the symbols referenced by the
1844 * expression are defined for this register.
1845 */
1846 if (symbol->info.rinfo->typecheck_masks != FALSE) {
1847 for(node = expression->referenced_syms.slh_first;
1848 node != NULL;
1849 node = node->links.sle_next) {
1850 if ((node->symbol->type == MASK
1851 || node->symbol->type == FIELD
1852 || node->symbol->type == ENUM
1853 || node->symbol->type == ENUM_ENTRY)
1854 && symlist_search(&node->symbol->info.finfo->symrefs,
1855 symbol->name) == NULL) {
1856 snprintf(errbuf, sizeof(errbuf),
1857 "Invalid field or mask %s "
1858 "for register %s",
1859 node->symbol->name, symbol->name);
1860 stop(errbuf, EX_DATAERR);
1861 /* NOTREACHED */
1862 }
1863 }
1864 }
1865}
1866
1867static void
1868make_expression(expression_t *immed, int value)
1869{
1870 SLIST_INIT(&immed->referenced_syms);
1871 immed->value = value & 0xff;
1872}
1873
1874static void
1875add_conditional(symbol_t *symbol)
1876{
1877 static int numfuncs;
1878
1879 if (numfuncs == 0) {
1880 /* add a special conditional, "0" */
1881 symbol_t *false_func;
1882
1883 false_func = symtable_get("0");
1884 if (false_func->type != UNINITIALIZED) {
1885 stop("Conditional expression '0' "
1886 "conflicts with a symbol", EX_DATAERR);
1887 /* NOTREACHED */
1888 }
1889 false_func->type = CONDITIONAL;
1890 initialize_symbol(false_func);
1891 false_func->info.condinfo->func_num = numfuncs++;
1892 symlist_add(&patch_functions, false_func, SYMLIST_INSERT_HEAD);
1893 }
1894
1895 /* This condition has occurred before */
1896 if (symbol->type == CONDITIONAL)
1897 return;
1898
1899 if (symbol->type != UNINITIALIZED) {
1900 stop("Conditional expression conflicts with a symbol",
1901 EX_DATAERR);
1902 /* NOTREACHED */
1903 }
1904
1905 symbol->type = CONDITIONAL;
1906 initialize_symbol(symbol);
1907 symbol->info.condinfo->func_num = numfuncs++;
1908 symlist_add(&patch_functions, symbol, SYMLIST_INSERT_HEAD);
1909}
1910
1911static void
1912add_version(const char *verstring)
1913{
1914 const char prefix[] = " * ";
1915 int newlen;
1916 int oldlen;
1917
1918 newlen = strlen(verstring) + strlen(prefix);
1919 oldlen = 0;
1920 if (versions != NULL)
1921 oldlen = strlen(versions);
1922 versions = realloc(versions, newlen + oldlen + 2);
1923 if (versions == NULL)
1924 stop("Can't allocate version string", EX_SOFTWARE);
1925 strcpy(&versions[oldlen], prefix);
1926 strcpy(&versions[oldlen + strlen(prefix)], verstring);
1927 versions[newlen + oldlen] = '\n';
1928 versions[newlen + oldlen + 1] = '\0';
1929}
1930
1931void
1932yyerror(const char *string)
1933{
1934 stop(string, EX_DATAERR);
1935}
1936
1937static int
1938is_download_const(expression_t *immed)
1939{
1940 if ((immed->referenced_syms.slh_first != NULL)
1941 && (immed->referenced_syms.slh_first->symbol->type == DOWNLOAD_CONST))
1942 return (TRUE);
1943
1944 return (FALSE);
1945}
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
new file mode 100644
index 000000000000..3e80f07df49c
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
@@ -0,0 +1,131 @@
1/*
2 * Instruction formats for the sequencer program downloaded to
3 * Aic7xxx SCSI host adapters
4 *
5 * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_insformat.h#11 $
41 *
42 * $FreeBSD$
43 */
44
45struct ins_format1 {
46#if BYTE_ORDER == LITTLE_ENDIAN
47 uint32_t immediate : 8,
48 source : 9,
49 destination : 9,
50 ret : 1,
51 opcode : 4,
52 parity : 1;
53#else
54 uint32_t parity : 1,
55 opcode : 4,
56 ret : 1,
57 destination : 9,
58 source : 9,
59 immediate : 8;
60#endif
61};
62
63struct ins_format2 {
64#if BYTE_ORDER == LITTLE_ENDIAN
65 uint32_t shift_control : 8,
66 source : 9,
67 destination : 9,
68 ret : 1,
69 opcode : 4,
70 parity : 1;
71#else
72 uint32_t parity : 1,
73 opcode : 4,
74 ret : 1,
75 destination : 9,
76 source : 9,
77 shift_control : 8;
78#endif
79};
80
81struct ins_format3 {
82#if BYTE_ORDER == LITTLE_ENDIAN
83 uint32_t immediate : 8,
84 source : 9,
85 address : 10,
86 opcode : 4,
87 parity : 1;
88#else
89 uint32_t parity : 1,
90 opcode : 4,
91 address : 10,
92 source : 9,
93 immediate : 8;
94#endif
95};
96
97union ins_formats {
98 struct ins_format1 format1;
99 struct ins_format2 format2;
100 struct ins_format3 format3;
101 uint8_t bytes[4];
102 uint32_t integer;
103};
104struct instruction {
105 union ins_formats format;
106 u_int srcline;
107 struct symbol *patch_label;
108 STAILQ_ENTRY(instruction) links;
109};
110
111#define AIC_OP_OR 0x0
112#define AIC_OP_AND 0x1
113#define AIC_OP_XOR 0x2
114#define AIC_OP_ADD 0x3
115#define AIC_OP_ADC 0x4
116#define AIC_OP_ROL 0x5
117#define AIC_OP_BMOV 0x6
118
119#define AIC_OP_JMP 0x8
120#define AIC_OP_JC 0x9
121#define AIC_OP_JNC 0xa
122#define AIC_OP_CALL 0xb
123#define AIC_OP_JNE 0xc
124#define AIC_OP_JNZ 0xd
125#define AIC_OP_JE 0xe
126#define AIC_OP_JZ 0xf
127
128/* Pseudo Ops */
129#define AIC_OP_SHL 0x10
130#define AIC_OP_SHR 0x20
131#define AIC_OP_ROR 0x30
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
new file mode 100644
index 000000000000..439f760b34b5
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
@@ -0,0 +1,164 @@
1%{
2/*
3 * Sub-parser for macro invocation in the Aic7xxx SCSI
4 * Host adapter sequencer assembler.
5 *
6 * Copyright (c) 2001 Adaptec Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * substantially similar to the "NO WARRANTY" disclaimer below
17 * ("Disclaimer") and any redistribution must be conditioned upon
18 * including a substantially similar Disclaimer requirement for further
19 * binary redistribution.
20 * 3. Neither the names of the above-listed copyright holders nor the names
21 * of any contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * Alternatively, this software may be distributed under the terms of the
25 * GNU General Public License ("GPL") version 2 as published by the Free
26 * Software Foundation.
27 *
28 * NO WARRANTY
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGES.
40 *
41 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $
42 *
43 * $FreeBSD$
44 */
45
46#include <sys/types.h>
47
48#include <inttypes.h>
49#include <regex.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#include <sysexits.h>
54
55#ifdef __linux__
56#include "../queue.h"
57#else
58#include <sys/queue.h>
59#endif
60
61#include "aicasm.h"
62#include "aicasm_symbol.h"
63#include "aicasm_insformat.h"
64
65static symbol_t *macro_symbol;
66
67static void add_macro_arg(const char *argtext, int position);
68
69%}
70
71%union {
72 int value;
73 char *str;
74 symbol_t *sym;
75}
76
77
78%token <str> T_ARG
79
80%token <sym> T_SYMBOL
81
82%type <value> macro_arglist
83
84%%
85
86macrocall:
87 T_SYMBOL '('
88 {
89 macro_symbol = $1;
90 }
91 macro_arglist ')'
92 {
93 if (macro_symbol->info.macroinfo->narg != $4) {
94 printf("Narg == %d", macro_symbol->info.macroinfo->narg);
95 stop("Too few arguments for macro invocation",
96 EX_DATAERR);
97 /* NOTREACHED */
98 }
99 macro_symbol = NULL;
100 YYACCEPT;
101 }
102;
103
104macro_arglist:
105 {
106 /* Macros can take 0 arguments */
107 $$ = 0;
108 }
109| T_ARG
110 {
111 $$ = 1;
112 add_macro_arg($1, 1);
113 }
114| macro_arglist ',' T_ARG
115 {
116 if ($1 == 0) {
117 stop("Comma without preceeding argument in arg list",
118 EX_DATAERR);
119 /* NOTREACHED */
120 }
121 $$ = $1 + 1;
122 add_macro_arg($3, $$);
123 }
124;
125
126%%
127
128static void
129add_macro_arg(const char *argtext, int argnum)
130{
131 struct macro_arg *marg;
132 int i;
133
134 if (macro_symbol == NULL || macro_symbol->type != MACRO) {
135 stop("Invalid current symbol for adding macro arg",
136 EX_SOFTWARE);
137 /* NOTREACHED */
138 }
139 /*
140 * Macro Invocation. Find the appropriate argument and fill
141 * in the replace ment text for this call.
142 */
143 i = 0;
144 STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
145 i++;
146 if (i == argnum)
147 break;
148 }
149 if (marg == NULL) {
150 stop("Too many arguments for macro invocation", EX_DATAERR);
151 /* NOTREACHED */
152 }
153 marg->replacement_text = strdup(argtext);
154 if (marg->replacement_text == NULL) {
155 stop("Unable to replicate replacement text", EX_SOFTWARE);
156 /* NOTREACHED */
157 }
158}
159
160void
161mmerror(const char *string)
162{
163 stop(string, EX_DATAERR);
164}
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l
new file mode 100644
index 000000000000..f06e7035cb35
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l
@@ -0,0 +1,156 @@
1%{
2/*
3 * Sub-Lexical Analyzer for macro invokation in
4 * the Aic7xxx SCSI Host adapter sequencer assembler.
5 *
6 * Copyright (c) 2001 Adaptec Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * substantially similar to the "NO WARRANTY" disclaimer below
17 * ("Disclaimer") and any redistribution must be conditioned upon
18 * including a substantially similar Disclaimer requirement for further
19 * binary redistribution.
20 * 3. Neither the names of the above-listed copyright holders nor the names
21 * of any contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * Alternatively, this software may be distributed under the terms of the
25 * GNU General Public License ("GPL") version 2 as published by the Free
26 * Software Foundation.
27 *
28 * NO WARRANTY
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGES.
40 *
41 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#8 $
42 *
43 * $FreeBSD$
44 */
45
46#include <sys/types.h>
47
48#include <inttypes.h>
49#include <limits.h>
50#include <regex.h>
51#include <stdio.h>
52#include <string.h>
53#include <sysexits.h>
54#ifdef __linux__
55#include "../queue.h"
56#else
57#include <sys/queue.h>
58#endif
59
60#include "aicasm.h"
61#include "aicasm_symbol.h"
62#include "aicasm_macro_gram.h"
63
64#define MAX_STR_CONST 4096
65static char string_buf[MAX_STR_CONST];
66static char *string_buf_ptr;
67static int parren_count;
68static char buf[255];
69%}
70
71WORD [A-Za-z_][-A-Za-z_0-9]*
72SPACE [ \t]+
73MCARG [^(), \t]+
74
75%x ARGLIST
76
77%%
78\n {
79 ++yylineno;
80 }
81\r ;
82<ARGLIST>{SPACE} ;
83<ARGLIST>\( {
84 parren_count++;
85 if (parren_count == 1) {
86 string_buf_ptr = string_buf;
87 return ('(');
88 }
89 *string_buf_ptr++ = '(';
90 }
91<ARGLIST>\) {
92 if (parren_count == 1) {
93 if (string_buf_ptr != string_buf) {
94 /*
95 * Return an argument and
96 * rescan this parren so we
97 * can return it as well.
98 */
99 *string_buf_ptr = '\0';
100 mmlval.str = string_buf;
101 string_buf_ptr = string_buf;
102 unput(')');
103 return T_ARG;
104 }
105 BEGIN INITIAL;
106 return (')');
107 }
108 parren_count--;
109 *string_buf_ptr++ = ')';
110 }
111<ARGLIST>{MCARG} {
112 char *yptr;
113
114 yptr = mmtext;
115 while (*yptr)
116 *string_buf_ptr++ = *yptr++;
117 }
118<ARGLIST>\, {
119 if (string_buf_ptr != string_buf) {
120 /*
121 * Return an argument and
122 * rescan this comma so we
123 * can return it as well.
124 */
125 *string_buf_ptr = '\0';
126 mmlval.str = string_buf;
127 string_buf_ptr = string_buf;
128 unput(',');
129 return T_ARG;
130 }
131 return ',';
132 }
133{WORD}[(] {
134 /* May be a symbol or a macro invocation. */
135 mmlval.sym = symtable_get(mmtext);
136 if (mmlval.sym->type != MACRO) {
137 stop("Expecting Macro Name",
138 EX_DATAERR);
139 }
140 unput('(');
141 parren_count = 0;
142 BEGIN ARGLIST;
143 return T_SYMBOL;
144 }
145. {
146 snprintf(buf, sizeof(buf), "Invalid character "
147 "'%c'", mmtext[0]);
148 stop(buf, EX_DATAERR);
149 }
150%%
151
152int
153mmwrap()
154{
155 stop("EOF encountered in macro call", EX_DATAERR);
156}
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
new file mode 100644
index 000000000000..45c0b233d0bc
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l
@@ -0,0 +1,607 @@
1%{
2/*
3 * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
4 *
5 * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
6 * Copyright (c) 2001, 2002 Adaptec Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * substantially similar to the "NO WARRANTY" disclaimer below
17 * ("Disclaimer") and any redistribution must be conditioned upon
18 * including a substantially similar Disclaimer requirement for further
19 * binary redistribution.
20 * 3. Neither the names of the above-listed copyright holders nor the names
21 * of any contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * Alternatively, this software may be distributed under the terms of the
25 * GNU General Public License ("GPL") version 2 as published by the Free
26 * Software Foundation.
27 *
28 * NO WARRANTY
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGES.
40 *
41 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#19 $
42 *
43 * $FreeBSD$
44 */
45
46#include <sys/types.h>
47
48#include <inttypes.h>
49#include <limits.h>
50#include <regex.h>
51#include <stdio.h>
52#include <string.h>
53#include <sysexits.h>
54#ifdef __linux__
55#include "../queue.h"
56#else
57#include <sys/queue.h>
58#endif
59
60#include "aicasm.h"
61#include "aicasm_symbol.h"
62#include "aicasm_gram.h"
63
64/* This is used for macro body capture too, so err on the large size. */
65#define MAX_STR_CONST 4096
66static char string_buf[MAX_STR_CONST];
67static char *string_buf_ptr;
68static int parren_count;
69static int quote_count;
70static char buf[255];
71%}
72
73PATH ([/]*[-A-Za-z0-9_.])+
74WORD [A-Za-z_][-A-Za-z_0-9]*
75SPACE [ \t]+
76MCARG [^(), \t]+
77MBODY ((\\[^\n])*[^\n\\]*)+
78
79%x COMMENT
80%x CEXPR
81%x INCLUDE
82%x STRING
83%x MACRODEF
84%x MACROARGLIST
85%x MACROCALLARGS
86%x MACROBODY
87
88%%
89\n { ++yylineno; }
90\r ;
91"/*" { BEGIN COMMENT; /* Enter comment eating state */ }
92<COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); }
93<COMMENT>\n { ++yylineno; }
94<COMMENT>[^*/\n]* ;
95<COMMENT>"*"+[^*/\n]* ;
96<COMMENT>"/"+[^*/\n]* ;
97<COMMENT>"*"+"/" { BEGIN INITIAL; }
98if[ \t]*\( {
99 string_buf_ptr = string_buf;
100 parren_count = 1;
101 BEGIN CEXPR;
102 return T_IF;
103 }
104<CEXPR>\( { *string_buf_ptr++ = '('; parren_count++; }
105<CEXPR>\) {
106 parren_count--;
107 if (parren_count == 0) {
108 /* All done */
109 BEGIN INITIAL;
110 *string_buf_ptr = '\0';
111 yylval.sym = symtable_get(string_buf);
112 return T_CEXPR;
113 } else {
114 *string_buf_ptr++ = ')';
115 }
116 }
117<CEXPR>\n { ++yylineno; }
118<CEXPR>\r ;
119<CEXPR>[^()\n]+ {
120 char *yptr;
121
122 yptr = yytext;
123 while (*yptr != '\0') {
124 /* Remove duplicate spaces */
125 if (*yptr == '\t')
126 *yptr = ' ';
127 if (*yptr == ' '
128 && string_buf_ptr != string_buf
129 && string_buf_ptr[-1] == ' ')
130 yptr++;
131 else
132 *string_buf_ptr++ = *yptr++;
133 }
134 }
135
136VERSION { return T_VERSION; }
137PREFIX { return T_PREFIX; }
138PATCH_ARG_LIST { return T_PATCH_ARG_LIST; }
139\" {
140 string_buf_ptr = string_buf;
141 BEGIN STRING;
142 }
143<STRING>[^"]+ {
144 char *yptr;
145
146 yptr = yytext;
147 while (*yptr)
148 *string_buf_ptr++ = *yptr++;
149 }
150<STRING>\" {
151 /* All done */
152 BEGIN INITIAL;
153 *string_buf_ptr = '\0';
154 yylval.str = string_buf;
155 return T_STRING;
156 }
157{SPACE} ;
158
159 /* Register/SCB/SRAM definition keywords */
160export { return T_EXPORT; }
161register { return T_REGISTER; }
162const { yylval.value = FALSE; return T_CONST; }
163download { return T_DOWNLOAD; }
164address { return T_ADDRESS; }
165access_mode { return T_ACCESS_MODE; }
166modes { return T_MODES; }
167RW|RO|WO {
168 if (strcmp(yytext, "RW") == 0)
169 yylval.value = RW;
170 else if (strcmp(yytext, "RO") == 0)
171 yylval.value = RO;
172 else
173 yylval.value = WO;
174 return T_MODE;
175 }
176BEGIN_CRITICAL { return T_BEGIN_CS; }
177END_CRITICAL { return T_END_CS; }
178SET_SRC_MODE { return T_SET_SRC_MODE; }
179SET_DST_MODE { return T_SET_DST_MODE; }
180field { return T_FIELD; }
181enum { return T_ENUM; }
182mask { return T_MASK; }
183alias { return T_ALIAS; }
184size { return T_SIZE; }
185scb { return T_SCB; }
186scratch_ram { return T_SRAM; }
187accumulator { return T_ACCUM; }
188mode_pointer { return T_MODE_PTR; }
189allones { return T_ALLONES; }
190allzeros { return T_ALLZEROS; }
191none { return T_NONE; }
192sindex { return T_SINDEX; }
193A { return T_A; }
194
195 /* Opcodes */
196shl { return T_SHL; }
197shr { return T_SHR; }
198ror { return T_ROR; }
199rol { return T_ROL; }
200mvi { return T_MVI; }
201mov { return T_MOV; }
202clr { return T_CLR; }
203jmp { return T_JMP; }
204jc { return T_JC; }
205jnc { return T_JNC; }
206je { return T_JE; }
207jne { return T_JNE; }
208jz { return T_JZ; }
209jnz { return T_JNZ; }
210call { return T_CALL; }
211add { return T_ADD; }
212adc { return T_ADC; }
213bmov { return T_BMOV; }
214inc { return T_INC; }
215dec { return T_DEC; }
216stc { return T_STC; }
217clc { return T_CLC; }
218cmp { return T_CMP; }
219not { return T_NOT; }
220xor { return T_XOR; }
221test { return T_TEST;}
222and { return T_AND; }
223or { return T_OR; }
224ret { return T_RET; }
225nop { return T_NOP; }
226else { return T_ELSE; }
227
228 /* Allowed Symbols */
229\<\< { return T_EXPR_LSHIFT; }
230\>\> { return T_EXPR_RSHIFT; }
231[-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; }
232
233 /* Number processing */
2340[0-7]* {
235 yylval.value = strtol(yytext, NULL, 8);
236 return T_NUMBER;
237 }
238
2390[xX][0-9a-fA-F]+ {
240 yylval.value = strtoul(yytext + 2, NULL, 16);
241 return T_NUMBER;
242 }
243
244[1-9][0-9]* {
245 yylval.value = strtol(yytext, NULL, 10);
246 return T_NUMBER;
247 }
248 /* Include Files */
249#include{SPACE} {
250 BEGIN INCLUDE;
251 quote_count = 0;
252 return T_INCLUDE;
253 }
254<INCLUDE>[<] { return yytext[0]; }
255<INCLUDE>[>] { BEGIN INITIAL; return yytext[0]; }
256<INCLUDE>[\"] {
257 if (quote_count != 0)
258 BEGIN INITIAL;
259 quote_count++;
260 return yytext[0];
261 }
262<INCLUDE>{PATH} {
263 char *yptr;
264
265 yptr = yytext;
266 string_buf_ptr = string_buf;
267 while (*yptr)
268 *string_buf_ptr++ = *yptr++;
269 yylval.str = string_buf;
270 *string_buf_ptr = '\0';
271 return T_PATH;
272 }
273<INCLUDE>. { stop("Invalid include line", EX_DATAERR); }
274#define{SPACE} {
275 BEGIN MACRODEF;
276 return T_DEFINE;
277 }
278<MACRODEF>{WORD}{SPACE} {
279 char *yptr;
280
281 /* Strip space and return as a normal symbol */
282 yptr = yytext;
283 while (*yptr != ' ' && *yptr != '\t')
284 yptr++;
285 *yptr = '\0';
286 yylval.sym = symtable_get(yytext);
287 string_buf_ptr = string_buf;
288 BEGIN MACROBODY;
289 return T_SYMBOL;
290 }
291<MACRODEF>{WORD}\( {
292 /*
293 * We store the symbol with its opening
294 * parren so we can differentiate macros
295 * that take args from macros with the
296 * same name that do not take args as
297 * is allowed in C.
298 */
299 BEGIN MACROARGLIST;
300 yylval.sym = symtable_get(yytext);
301 unput('(');
302 return T_SYMBOL;
303 }
304<MACROARGLIST>{WORD} {
305 yylval.str = yytext;
306 return T_ARG;
307 }
308<MACROARGLIST>{SPACE} ;
309<MACROARGLIST>[(,] {
310 return yytext[0];
311 }
312<MACROARGLIST>[)] {
313 string_buf_ptr = string_buf;
314 BEGIN MACROBODY;
315 return ')';
316 }
317<MACROARGLIST>. {
318 snprintf(buf, sizeof(buf), "Invalid character "
319 "'%c' in macro argument list",
320 yytext[0]);
321 stop(buf, EX_DATAERR);
322 }
323<MACROCALLARGS>{SPACE} ;
324<MACROCALLARGS>\( {
325 parren_count++;
326 if (parren_count == 1)
327 return ('(');
328 *string_buf_ptr++ = '(';
329 }
330<MACROCALLARGS>\) {
331 parren_count--;
332 if (parren_count == 0) {
333 BEGIN INITIAL;
334 return (')');
335 }
336 *string_buf_ptr++ = ')';
337 }
338<MACROCALLARGS>{MCARG} {
339 char *yptr;
340
341 yptr = yytext;
342 while (*yptr)
343 *string_buf_ptr++ = *yptr++;
344 }
345<MACROCALLARGS>\, {
346 if (string_buf_ptr != string_buf) {
347 /*
348 * Return an argument and
349 * rescan this comma so we
350 * can return it as well.
351 */
352 *string_buf_ptr = '\0';
353 yylval.str = string_buf;
354 string_buf_ptr = string_buf;
355 unput(',');
356 return T_ARG;
357 }
358 return ',';
359 }
360<MACROBODY>\\\n {
361 /* Eat escaped newlines. */
362 ++yylineno;
363 }
364<MACROBODY>\r ;
365<MACROBODY>\n {
366 /* Macros end on the first unescaped newline. */
367 BEGIN INITIAL;
368 *string_buf_ptr = '\0';
369 yylval.str = string_buf;
370 ++yylineno;
371 return T_MACROBODY;
372 }
373<MACROBODY>{MBODY} {
374 char *yptr;
375 char c;
376
377 yptr = yytext;
378 while (c = *yptr++) {
379 /*
380 * Strip carriage returns.
381 */
382 if (c == '\r')
383 continue;
384 *string_buf_ptr++ = c;
385 }
386 }
387{WORD}\( {
388 char *yptr;
389 char *ycopy;
390
391 /* May be a symbol or a macro invocation. */
392 yylval.sym = symtable_get(yytext);
393 if (yylval.sym->type == MACRO) {
394 YY_BUFFER_STATE old_state;
395 YY_BUFFER_STATE temp_state;
396
397 ycopy = strdup(yytext);
398 yptr = ycopy + yyleng;
399 while (yptr > ycopy)
400 unput(*--yptr);
401 old_state = YY_CURRENT_BUFFER;
402 temp_state =
403 yy_create_buffer(stdin,
404 YY_BUF_SIZE);
405 yy_switch_to_buffer(temp_state);
406 mm_switch_to_buffer(old_state);
407 mmparse();
408 mm_switch_to_buffer(temp_state);
409 yy_switch_to_buffer(old_state);
410 mm_delete_buffer(temp_state);
411 expand_macro(yylval.sym);
412 } else {
413 if (yylval.sym->type == UNINITIALIZED) {
414 /* Try without the '(' */
415 symbol_delete(yylval.sym);
416 yytext[yyleng-1] = '\0';
417 yylval.sym =
418 symtable_get(yytext);
419 }
420 unput('(');
421 return T_SYMBOL;
422 }
423 }
424{WORD} {
425 yylval.sym = symtable_get(yytext);
426 if (yylval.sym->type == MACRO) {
427 expand_macro(yylval.sym);
428 } else {
429 return T_SYMBOL;
430 }
431 }
432. {
433 snprintf(buf, sizeof(buf), "Invalid character "
434 "'%c'", yytext[0]);
435 stop(buf, EX_DATAERR);
436 }
437%%
438
439typedef struct include {
440 YY_BUFFER_STATE buffer;
441 int lineno;
442 char *filename;
443 SLIST_ENTRY(include) links;
444}include_t;
445
446SLIST_HEAD(, include) include_stack;
447
448void
449include_file(char *file_name, include_type type)
450{
451 FILE *newfile;
452 include_t *include;
453
454 newfile = NULL;
455 /* Try the current directory first */
456 if (includes_search_curdir != 0 || type == SOURCE_FILE)
457 newfile = fopen(file_name, "r");
458
459 if (newfile == NULL && type != SOURCE_FILE) {
460 path_entry_t include_dir;
461 for (include_dir = search_path.slh_first;
462 include_dir != NULL;
463 include_dir = include_dir->links.sle_next) {
464 char fullname[PATH_MAX];
465
466 if ((include_dir->quoted_includes_only == TRUE)
467 && (type != QUOTED_INCLUDE))
468 continue;
469
470 snprintf(fullname, sizeof(fullname),
471 "%s/%s", include_dir->directory, file_name);
472
473 if ((newfile = fopen(fullname, "r")) != NULL)
474 break;
475 }
476 }
477
478 if (newfile == NULL) {
479 perror(file_name);
480 stop("Unable to open input file", EX_SOFTWARE);
481 /* NOTREACHED */
482 }
483
484 if (type != SOURCE_FILE) {
485 include = (include_t *)malloc(sizeof(include_t));
486 if (include == NULL) {
487 stop("Unable to allocate include stack entry",
488 EX_SOFTWARE);
489 /* NOTREACHED */
490 }
491 include->buffer = YY_CURRENT_BUFFER;
492 include->lineno = yylineno;
493 include->filename = yyfilename;
494 SLIST_INSERT_HEAD(&include_stack, include, links);
495 }
496 yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
497 yylineno = 1;
498 yyfilename = strdup(file_name);
499}
500
501static void next_substitution(struct symbol *mac_symbol, const char *body_pos,
502 const char **next_match,
503 struct macro_arg **match_marg, regmatch_t *match);
504
505void
506expand_macro(struct symbol *macro_symbol)
507{
508 struct macro_arg *marg;
509 struct macro_arg *match_marg;
510 const char *body_head;
511 const char *body_pos;
512 const char *next_match;
513
514 /*
515 * Due to the nature of unput, we must work
516 * backwards through the macro body performing
517 * any expansions.
518 */
519 body_head = macro_symbol->info.macroinfo->body;
520 body_pos = body_head + strlen(body_head);
521 while (body_pos > body_head) {
522 regmatch_t match;
523
524 next_match = body_head;
525 match_marg = NULL;
526 next_substitution(macro_symbol, body_pos, &next_match,
527 &match_marg, &match);
528
529 /* Put back everything up until the replacement. */
530 while (body_pos > next_match)
531 unput(*--body_pos);
532
533 /* Perform the replacement. */
534 if (match_marg != NULL) {
535 const char *strp;
536
537 next_match = match_marg->replacement_text;
538 strp = next_match + strlen(next_match);
539 while (strp > next_match)
540 unput(*--strp);
541
542 /* Skip past the unexpanded macro arg. */
543 body_pos -= match.rm_eo - match.rm_so;
544 }
545 }
546
547 /* Cleanup replacement text. */
548 STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
549 free(marg->replacement_text);
550 }
551}
552
553/*
554 * Find the next substitution in the macro working backwards from
555 * body_pos until the beginning of the macro buffer. next_match
556 * should be initialized to the beginning of the macro buffer prior
557 * to calling this routine.
558 */
559static void
560next_substitution(struct symbol *mac_symbol, const char *body_pos,
561 const char **next_match, struct macro_arg **match_marg,
562 regmatch_t *match)
563{
564 regmatch_t matches[2];
565 struct macro_arg *marg;
566 const char *search_pos;
567 int retval;
568
569 do {
570 search_pos = *next_match;
571
572 STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) {
573
574 retval = regexec(&marg->arg_regex, search_pos, 2,
575 matches, 0);
576 if (retval == 0
577 && (matches[1].rm_eo + search_pos) <= body_pos
578 && (matches[1].rm_eo + search_pos) > *next_match) {
579 *match = matches[1];
580 *next_match = match->rm_eo + search_pos;
581 *match_marg = marg;
582 }
583 }
584 } while (search_pos != *next_match);
585}
586
587int
588yywrap()
589{
590 include_t *include;
591
592 yy_delete_buffer(YY_CURRENT_BUFFER);
593 (void)fclose(yyin);
594 if (yyfilename != NULL)
595 free(yyfilename);
596 yyfilename = NULL;
597 include = include_stack.slh_first;
598 if (include != NULL) {
599 yy_switch_to_buffer(include->buffer);
600 yylineno = include->lineno;
601 yyfilename = include->filename;
602 SLIST_REMOVE_HEAD(&include_stack, links);
603 free(include);
604 return (0);
605 }
606 return (1);
607}
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
new file mode 100644
index 000000000000..f1f448dff569
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
@@ -0,0 +1,677 @@
1/*
2 * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation
3 *
4 * Copyright (c) 1997 Justin T. Gibbs.
5 * Copyright (c) 2002 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 $
41 *
42 * $FreeBSD$
43 */
44
45#include <sys/types.h>
46
47#ifdef __linux__
48#include "aicdb.h"
49#else
50#include <db.h>
51#endif
52#include <fcntl.h>
53#include <inttypes.h>
54#include <regex.h>
55#include <stdio.h>
56#include <stdlib.h>
57#include <string.h>
58#include <sysexits.h>
59
60#include "aicasm_symbol.h"
61#include "aicasm.h"
62
63static DB *symtable;
64
65symbol_t *
66symbol_create(char *name)
67{
68 symbol_t *new_symbol;
69
70 new_symbol = (symbol_t *)malloc(sizeof(symbol_t));
71 if (new_symbol == NULL) {
72 perror("Unable to create new symbol");
73 exit(EX_SOFTWARE);
74 }
75 memset(new_symbol, 0, sizeof(*new_symbol));
76 new_symbol->name = strdup(name);
77 if (new_symbol->name == NULL)
78 stop("Unable to strdup symbol name", EX_SOFTWARE);
79 new_symbol->type = UNINITIALIZED;
80 return (new_symbol);
81}
82
83void
84symbol_delete(symbol_t *symbol)
85{
86 if (symtable != NULL) {
87 DBT key;
88
89 key.data = symbol->name;
90 key.size = strlen(symbol->name);
91 symtable->del(symtable, &key, /*flags*/0);
92 }
93 switch(symbol->type) {
94 case SCBLOC:
95 case SRAMLOC:
96 case REGISTER:
97 if (symbol->info.rinfo != NULL)
98 free(symbol->info.rinfo);
99 break;
100 case ALIAS:
101 if (symbol->info.ainfo != NULL)
102 free(symbol->info.ainfo);
103 break;
104 case MASK:
105 case FIELD:
106 case ENUM:
107 case ENUM_ENTRY:
108 if (symbol->info.finfo != NULL) {
109 symlist_free(&symbol->info.finfo->symrefs);
110 free(symbol->info.finfo);
111 }
112 break;
113 case DOWNLOAD_CONST:
114 case CONST:
115 if (symbol->info.cinfo != NULL)
116 free(symbol->info.cinfo);
117 break;
118 case LABEL:
119 if (symbol->info.linfo != NULL)
120 free(symbol->info.linfo);
121 break;
122 case UNINITIALIZED:
123 default:
124 break;
125 }
126 free(symbol->name);
127 free(symbol);
128}
129
130void
131symtable_open()
132{
133 symtable = dbopen(/*filename*/NULL,
134 O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH,
135 /*openinfo*/NULL);
136
137 if (symtable == NULL) {
138 perror("Symbol table creation failed");
139 exit(EX_SOFTWARE);
140 /* NOTREACHED */
141 }
142}
143
144void
145symtable_close()
146{
147 if (symtable != NULL) {
148 DBT key;
149 DBT data;
150
151 while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) {
152 symbol_t *stored_ptr;
153
154 memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
155 symbol_delete(stored_ptr);
156 }
157 symtable->close(symtable);
158 }
159}
160
161/*
162 * The semantics of get is to return an uninitialized symbol entry
163 * if a lookup fails.
164 */
165symbol_t *
166symtable_get(char *name)
167{
168 symbol_t *stored_ptr;
169 DBT key;
170 DBT data;
171 int retval;
172
173 key.data = (void *)name;
174 key.size = strlen(name);
175
176 if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) {
177 if (retval == -1) {
178 perror("Symbol table get operation failed");
179 exit(EX_SOFTWARE);
180 /* NOTREACHED */
181 } else if (retval == 1) {
182 /* Symbol wasn't found, so create a new one */
183 symbol_t *new_symbol;
184
185 new_symbol = symbol_create(name);
186 data.data = &new_symbol;
187 data.size = sizeof(new_symbol);
188 if (symtable->put(symtable, &key, &data,
189 /*flags*/0) !=0) {
190 perror("Symtable put failed");
191 exit(EX_SOFTWARE);
192 }
193 return (new_symbol);
194 } else {
195 perror("Unexpected return value from db get routine");
196 exit(EX_SOFTWARE);
197 /* NOTREACHED */
198 }
199 }
200 memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
201 return (stored_ptr);
202}
203
204symbol_node_t *
205symlist_search(symlist_t *symlist, char *symname)
206{
207 symbol_node_t *curnode;
208
209 curnode = SLIST_FIRST(symlist);
210 while(curnode != NULL) {
211 if (strcmp(symname, curnode->symbol->name) == 0)
212 break;
213 curnode = SLIST_NEXT(curnode, links);
214 }
215 return (curnode);
216}
217
218void
219symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
220{
221 symbol_node_t *newnode;
222
223 newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t));
224 if (newnode == NULL) {
225 stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE);
226 /* NOTREACHED */
227 }
228 newnode->symbol = symbol;
229 if (how == SYMLIST_SORT) {
230 symbol_node_t *curnode;
231 int field;
232
233 field = FALSE;
234 switch(symbol->type) {
235 case REGISTER:
236 case SCBLOC:
237 case SRAMLOC:
238 break;
239 case FIELD:
240 case MASK:
241 case ENUM:
242 case ENUM_ENTRY:
243 field = TRUE;
244 break;
245 default:
246 stop("symlist_add: Invalid symbol type for sorting",
247 EX_SOFTWARE);
248 /* NOTREACHED */
249 }
250
251 curnode = SLIST_FIRST(symlist);
252 if (curnode == NULL
253 || (field
254 && (curnode->symbol->type > newnode->symbol->type
255 || (curnode->symbol->type == newnode->symbol->type
256 && (curnode->symbol->info.finfo->value >
257 newnode->symbol->info.finfo->value))))
258 || (!field && (curnode->symbol->info.rinfo->address >
259 newnode->symbol->info.rinfo->address))) {
260 SLIST_INSERT_HEAD(symlist, newnode, links);
261 return;
262 }
263
264 while (1) {
265 if (SLIST_NEXT(curnode, links) == NULL) {
266 SLIST_INSERT_AFTER(curnode, newnode,
267 links);
268 break;
269 } else {
270 symbol_t *cursymbol;
271
272 cursymbol = SLIST_NEXT(curnode, links)->symbol;
273 if ((field
274 && (cursymbol->type > symbol->type
275 || (cursymbol->type == symbol->type
276 && (cursymbol->info.finfo->value >
277 symbol->info.finfo->value))))
278 || (!field
279 && (cursymbol->info.rinfo->address >
280 symbol->info.rinfo->address))) {
281 SLIST_INSERT_AFTER(curnode, newnode,
282 links);
283 break;
284 }
285 }
286 curnode = SLIST_NEXT(curnode, links);
287 }
288 } else {
289 SLIST_INSERT_HEAD(symlist, newnode, links);
290 }
291}
292
293void
294symlist_free(symlist_t *symlist)
295{
296 symbol_node_t *node1, *node2;
297
298 node1 = SLIST_FIRST(symlist);
299 while (node1 != NULL) {
300 node2 = SLIST_NEXT(node1, links);
301 free(node1);
302 node1 = node2;
303 }
304 SLIST_INIT(symlist);
305}
306
307void
308symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
309 symlist_t *symlist_src2)
310{
311 symbol_node_t *node;
312
313 *symlist_dest = *symlist_src1;
314 while((node = SLIST_FIRST(symlist_src2)) != NULL) {
315 SLIST_REMOVE_HEAD(symlist_src2, links);
316 SLIST_INSERT_HEAD(symlist_dest, node, links);
317 }
318
319 /* These are now empty */
320 SLIST_INIT(symlist_src1);
321 SLIST_INIT(symlist_src2);
322}
323
324void
325aic_print_file_prologue(FILE *ofile)
326{
327
328 if (ofile == NULL)
329 return;
330
331 fprintf(ofile,
332"/*\n"
333" * DO NOT EDIT - This file is automatically generated\n"
334" * from the following source files:\n"
335" *\n"
336"%s */\n",
337 versions);
338}
339
340void
341aic_print_include(FILE *dfile, char *include_file)
342{
343
344 if (dfile == NULL)
345 return;
346 fprintf(dfile, "\n#include \"%s\"\n\n", include_file);
347}
348
349void
350aic_print_reg_dump_types(FILE *ofile)
351{
352 if (ofile == NULL)
353 return;
354
355 fprintf(ofile,
356"typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n"
357"typedef struct %sreg_parse_entry {\n"
358" char *name;\n"
359" uint8_t value;\n"
360" uint8_t mask;\n"
361"} %sreg_parse_entry_t;\n"
362"\n",
363 prefix, prefix, prefix);
364}
365
366static void
367aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode)
368{
369 if (dfile == NULL)
370 return;
371
372 fprintf(dfile,
373"static %sreg_parse_entry_t %s_parse_table[] = {\n",
374 prefix,
375 regnode->symbol->name);
376}
377
378static void
379aic_print_reg_dump_end(FILE *ofile, FILE *dfile,
380 symbol_node_t *regnode, u_int num_entries)
381{
382 char *lower_name;
383 char *letter;
384
385 lower_name = strdup(regnode->symbol->name);
386 if (lower_name == NULL)
387 stop("Unable to strdup symbol name", EX_SOFTWARE);
388
389 for (letter = lower_name; *letter != '\0'; letter++)
390 *letter = tolower(*letter);
391
392 if (dfile != NULL) {
393 if (num_entries != 0)
394 fprintf(dfile,
395"\n"
396"};\n"
397"\n");
398
399 fprintf(dfile,
400"int\n"
401"%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n"
402"{\n"
403" return (%sprint_register(%s%s, %d, \"%s\",\n"
404" 0x%02x, regvalue, cur_col, wrap));\n"
405"}\n"
406"\n",
407 prefix,
408 lower_name,
409 prefix,
410 num_entries != 0 ? regnode->symbol->name : "NULL",
411 num_entries != 0 ? "_parse_table" : "",
412 num_entries,
413 regnode->symbol->name,
414 regnode->symbol->info.rinfo->address);
415 }
416
417 fprintf(ofile,
418"#if AIC_DEBUG_REGISTERS\n"
419"%sreg_print_t %s%s_print;\n"
420"#else\n"
421"#define %s%s_print(regvalue, cur_col, wrap) \\\n"
422" %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n"
423"#endif\n"
424"\n",
425 prefix,
426 prefix,
427 lower_name,
428 prefix,
429 lower_name,
430 prefix,
431 regnode->symbol->name,
432 regnode->symbol->info.rinfo->address);
433}
434
435static void
436aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode)
437{
438 int num_tabs;
439
440 if (dfile == NULL)
441 return;
442
443 fprintf(dfile,
444" { \"%s\",",
445 curnode->symbol->name);
446
447 num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8;
448
449 while (num_tabs-- > 0)
450 fputc('\t', dfile);
451 fprintf(dfile, "0x%02x, 0x%02x }",
452 curnode->symbol->info.finfo->value,
453 curnode->symbol->info.finfo->mask);
454}
455
456void
457symtable_dump(FILE *ofile, FILE *dfile)
458{
459 /*
460 * Sort the registers by address with a simple insertion sort.
461 * Put bitmasks next to the first register that defines them.
462 * Put constants at the end.
463 */
464 symlist_t registers;
465 symlist_t masks;
466 symlist_t constants;
467 symlist_t download_constants;
468 symlist_t aliases;
469 symlist_t exported_labels;
470 symbol_node_t *curnode;
471 symbol_node_t *regnode;
472 DBT key;
473 DBT data;
474 int flag;
475 u_int i;
476
477 if (symtable == NULL)
478 return;
479
480 SLIST_INIT(&registers);
481 SLIST_INIT(&masks);
482 SLIST_INIT(&constants);
483 SLIST_INIT(&download_constants);
484 SLIST_INIT(&aliases);
485 SLIST_INIT(&exported_labels);
486 flag = R_FIRST;
487 while (symtable->seq(symtable, &key, &data, flag) == 0) {
488 symbol_t *cursym;
489
490 memcpy(&cursym, data.data, sizeof(cursym));
491 switch(cursym->type) {
492 case REGISTER:
493 case SCBLOC:
494 case SRAMLOC:
495 symlist_add(&registers, cursym, SYMLIST_SORT);
496 break;
497 case MASK:
498 case FIELD:
499 case ENUM:
500 case ENUM_ENTRY:
501 symlist_add(&masks, cursym, SYMLIST_SORT);
502 break;
503 case CONST:
504 symlist_add(&constants, cursym,
505 SYMLIST_INSERT_HEAD);
506 break;
507 case DOWNLOAD_CONST:
508 symlist_add(&download_constants, cursym,
509 SYMLIST_INSERT_HEAD);
510 break;
511 case ALIAS:
512 symlist_add(&aliases, cursym,
513 SYMLIST_INSERT_HEAD);
514 break;
515 case LABEL:
516 if (cursym->info.linfo->exported == 0)
517 break;
518 symlist_add(&exported_labels, cursym,
519 SYMLIST_INSERT_HEAD);
520 break;
521 default:
522 break;
523 }
524 flag = R_NEXT;
525 }
526
527 /* Register dianostic functions/declarations first. */
528 aic_print_file_prologue(ofile);
529 aic_print_reg_dump_types(ofile);
530 aic_print_file_prologue(dfile);
531 aic_print_include(dfile, stock_include_file);
532 SLIST_FOREACH(curnode, &registers, links) {
533
534 switch(curnode->symbol->type) {
535 case REGISTER:
536 case SCBLOC:
537 case SRAMLOC:
538 {
539 symlist_t *fields;
540 symbol_node_t *fieldnode;
541 int num_entries;
542
543 num_entries = 0;
544 fields = &curnode->symbol->info.rinfo->fields;
545 SLIST_FOREACH(fieldnode, fields, links) {
546 if (num_entries == 0)
547 aic_print_reg_dump_start(dfile,
548 curnode);
549 else if (dfile != NULL)
550 fputs(",\n", dfile);
551 num_entries++;
552 aic_print_reg_dump_entry(dfile, fieldnode);
553 }
554 aic_print_reg_dump_end(ofile, dfile,
555 curnode, num_entries);
556 }
557 default:
558 break;
559 }
560 }
561
562 /* Fold in the masks and bits */
563 while (SLIST_FIRST(&masks) != NULL) {
564 char *regname;
565
566 curnode = SLIST_FIRST(&masks);
567 SLIST_REMOVE_HEAD(&masks, links);
568
569 regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs);
570 regname = regnode->symbol->name;
571 regnode = symlist_search(&registers, regname);
572 SLIST_INSERT_AFTER(regnode, curnode, links);
573 }
574
575 /* Add the aliases */
576 while (SLIST_FIRST(&aliases) != NULL) {
577 char *regname;
578
579 curnode = SLIST_FIRST(&aliases);
580 SLIST_REMOVE_HEAD(&aliases, links);
581
582 regname = curnode->symbol->info.ainfo->parent->name;
583 regnode = symlist_search(&registers, regname);
584 SLIST_INSERT_AFTER(regnode, curnode, links);
585 }
586
587 /* Output generated #defines. */
588 while (SLIST_FIRST(&registers) != NULL) {
589 symbol_node_t *curnode;
590 u_int value;
591 char *tab_str;
592 char *tab_str2;
593
594 curnode = SLIST_FIRST(&registers);
595 SLIST_REMOVE_HEAD(&registers, links);
596 switch(curnode->symbol->type) {
597 case REGISTER:
598 case SCBLOC:
599 case SRAMLOC:
600 fprintf(ofile, "\n");
601 value = curnode->symbol->info.rinfo->address;
602 tab_str = "\t";
603 tab_str2 = "\t\t";
604 break;
605 case ALIAS:
606 {
607 symbol_t *parent;
608
609 parent = curnode->symbol->info.ainfo->parent;
610 value = parent->info.rinfo->address;
611 tab_str = "\t";
612 tab_str2 = "\t\t";
613 break;
614 }
615 case MASK:
616 case FIELD:
617 case ENUM:
618 case ENUM_ENTRY:
619 value = curnode->symbol->info.finfo->value;
620 tab_str = "\t\t";
621 tab_str2 = "\t";
622 break;
623 default:
624 value = 0; /* Quiet compiler */
625 tab_str = NULL;
626 tab_str2 = NULL;
627 stop("symtable_dump: Invalid symbol type "
628 "encountered", EX_SOFTWARE);
629 break;
630 }
631 fprintf(ofile, "#define%s%-16s%s0x%02x\n",
632 tab_str, curnode->symbol->name, tab_str2,
633 value);
634 free(curnode);
635 }
636 fprintf(ofile, "\n\n");
637
638 while (SLIST_FIRST(&constants) != NULL) {
639 symbol_node_t *curnode;
640
641 curnode = SLIST_FIRST(&constants);
642 SLIST_REMOVE_HEAD(&constants, links);
643 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
644 curnode->symbol->name,
645 curnode->symbol->info.cinfo->value);
646 free(curnode);
647 }
648
649
650 fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
651
652 for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) {
653 symbol_node_t *curnode;
654
655 curnode = SLIST_FIRST(&download_constants);
656 SLIST_REMOVE_HEAD(&download_constants, links);
657 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
658 curnode->symbol->name,
659 curnode->symbol->info.cinfo->value);
660 free(curnode);
661 }
662 fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i);
663
664 fprintf(ofile, "\n\n/* Exported Labels */\n");
665
666 while (SLIST_FIRST(&exported_labels) != NULL) {
667 symbol_node_t *curnode;
668
669 curnode = SLIST_FIRST(&exported_labels);
670 SLIST_REMOVE_HEAD(&exported_labels, links);
671 fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n",
672 curnode->symbol->name,
673 curnode->symbol->info.linfo->address);
674 free(curnode);
675 }
676}
677
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
new file mode 100644
index 000000000000..afc22e8b4903
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
@@ -0,0 +1,207 @@
1/*
2 * Aic7xxx SCSI host adapter firmware asssembler symbol table definitions
3 *
4 * Copyright (c) 1997 Justin T. Gibbs.
5 * Copyright (c) 2002 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15 * substantially similar to the "NO WARRANTY" disclaimer below
16 * ("Disclaimer") and any redistribution must be conditioned upon
17 * including a substantially similar Disclaimer requirement for further
18 * binary redistribution.
19 * 3. Neither the names of the above-listed copyright holders nor the names
20 * of any contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * Alternatively, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") version 2 as published by the Free
25 * Software Foundation.
26 *
27 * NO WARRANTY
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGES.
39 *
40 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.h#17 $
41 *
42 * $FreeBSD$
43 */
44
45#ifdef __linux__
46#include "../queue.h"
47#else
48#include <sys/queue.h>
49#endif
50
51typedef enum {
52 UNINITIALIZED,
53 REGISTER,
54 ALIAS,
55 SCBLOC,
56 SRAMLOC,
57 ENUM_ENTRY,
58 FIELD,
59 MASK,
60 ENUM,
61 CONST,
62 DOWNLOAD_CONST,
63 LABEL,
64 CONDITIONAL,
65 MACRO
66} symtype;
67
68typedef enum {
69 RO = 0x01,
70 WO = 0x02,
71 RW = 0x03
72}amode_t;
73
74typedef SLIST_HEAD(symlist, symbol_node) symlist_t;
75
76struct reg_info {
77 u_int address;
78 int size;
79 amode_t mode;
80 symlist_t fields;
81 uint8_t valid_bitmask;
82 uint8_t modes;
83 int typecheck_masks;
84};
85
86struct field_info {
87 symlist_t symrefs;
88 uint8_t value;
89 uint8_t mask;
90};
91
92struct const_info {
93 u_int value;
94 int define;
95};
96
97struct alias_info {
98 struct symbol *parent;
99};
100
101struct label_info {
102 int address;
103 int exported;
104};
105
106struct cond_info {
107 int func_num;
108};
109
110struct macro_arg {
111 STAILQ_ENTRY(macro_arg) links;
112 regex_t arg_regex;
113 char *replacement_text;
114};
115STAILQ_HEAD(macro_arg_list, macro_arg) args;
116
117struct macro_info {
118 struct macro_arg_list args;
119 int narg;
120 const char* body;
121};
122
123typedef struct expression_info {
124 symlist_t referenced_syms;
125 int value;
126} expression_t;
127
128typedef struct symbol {
129 char *name;
130 symtype type;
131 union {
132 struct reg_info *rinfo;
133 struct field_info *finfo;
134 struct const_info *cinfo;
135 struct alias_info *ainfo;
136 struct label_info *linfo;
137 struct cond_info *condinfo;
138 struct macro_info *macroinfo;
139 }info;
140} symbol_t;
141
142typedef struct symbol_ref {
143 symbol_t *symbol;
144 int offset;
145} symbol_ref_t;
146
147typedef struct symbol_node {
148 SLIST_ENTRY(symbol_node) links;
149 symbol_t *symbol;
150} symbol_node_t;
151
152typedef struct critical_section {
153 TAILQ_ENTRY(critical_section) links;
154 int begin_addr;
155 int end_addr;
156} critical_section_t;
157
158typedef enum {
159 SCOPE_ROOT,
160 SCOPE_IF,
161 SCOPE_ELSE_IF,
162 SCOPE_ELSE
163} scope_type;
164
165typedef struct patch_info {
166 int skip_patch;
167 int skip_instr;
168} patch_info_t;
169
170typedef struct scope {
171 SLIST_ENTRY(scope) scope_stack_links;
172 TAILQ_ENTRY(scope) scope_links;
173 TAILQ_HEAD(, scope) inner_scope;
174 scope_type type;
175 int inner_scope_patches;
176 int begin_addr;
177 int end_addr;
178 patch_info_t patches[2];
179 int func_num;
180} scope_t;
181
182TAILQ_HEAD(cs_tailq, critical_section);
183SLIST_HEAD(scope_list, scope);
184TAILQ_HEAD(scope_tailq, scope);
185
186void symbol_delete(symbol_t *symbol);
187
188void symtable_open(void);
189
190void symtable_close(void);
191
192symbol_t *
193 symtable_get(char *name);
194
195symbol_node_t *
196 symlist_search(symlist_t *symlist, char *symname);
197
198void
199 symlist_add(symlist_t *symlist, symbol_t *symbol, int how);
200#define SYMLIST_INSERT_HEAD 0x00
201#define SYMLIST_SORT 0x01
202
203void symlist_free(symlist_t *symlist);
204
205void symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
206 symlist_t *symlist_src2);
207void symtable_dump(FILE *ofile, FILE *dfile);
diff --git a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c
new file mode 100644
index 000000000000..79bfd9efd8ed
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aiclib.c
@@ -0,0 +1,1412 @@
1/*
2 * Implementation of Utility functions for all SCSI device types.
3 *
4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification, immediately at the beginning of the file.
14 * 2. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $
30 * $Id$
31 */
32
33#include <linux/blkdev.h>
34#include <linux/delay.h>
35#include <linux/version.h>
36
37/* Core SCSI definitions */
38#include "scsi.h"
39#include <scsi/scsi_host.h>
40#include "aiclib.h"
41#include "cam.h"
42
43#ifndef FALSE
44#define FALSE 0
45#endif /* FALSE */
46#ifndef TRUE
47#define TRUE 1
48#endif /* TRUE */
49#ifndef ERESTART
50#define ERESTART -1 /* restart syscall */
51#endif
52#ifndef EJUSTRETURN
53#define EJUSTRETURN -2 /* don't modify regs, just return */
54#endif
55
56static int ascentrycomp(const void *key, const void *member);
57static int senseentrycomp(const void *key, const void *member);
58static void fetchtableentries(int sense_key, int asc, int ascq,
59 struct scsi_inquiry_data *,
60 const struct sense_key_table_entry **,
61 const struct asc_table_entry **);
62static void * scsibsearch(const void *key, const void *base, size_t nmemb,
63 size_t size,
64 int (*compar)(const void *, const void *));
65typedef int (cam_quirkmatch_t)(caddr_t, caddr_t);
66static int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern,
67 int str_len);
68static caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table,
69 int num_entries, int entry_size,
70 cam_quirkmatch_t *comp_func);
71
72#define SCSI_NO_SENSE_STRINGS 1
73#if !defined(SCSI_NO_SENSE_STRINGS)
74#define SST(asc, ascq, action, desc) \
75 asc, ascq, action, desc
76#else
77static const char empty_string[] = "";
78
79#define SST(asc, ascq, action, desc) \
80 asc, ascq, action, empty_string
81#endif
82
83static const struct sense_key_table_entry sense_key_table[] =
84{
85 { SSD_KEY_NO_SENSE, SS_NOP, "NO SENSE" },
86 { SSD_KEY_RECOVERED_ERROR, SS_NOP|SSQ_PRINT_SENSE, "RECOVERED ERROR" },
87 {
88 SSD_KEY_NOT_READY, SS_TUR|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY,
89 "NOT READY"
90 },
91 { SSD_KEY_MEDIUM_ERROR, SS_RDEF, "MEDIUM ERROR" },
92 { SSD_KEY_HARDWARE_ERROR, SS_RDEF, "HARDWARE FAILURE" },
93 { SSD_KEY_ILLEGAL_REQUEST, SS_FATAL|EINVAL, "ILLEGAL REQUEST" },
94 { SSD_KEY_UNIT_ATTENTION, SS_FATAL|ENXIO, "UNIT ATTENTION" },
95 { SSD_KEY_DATA_PROTECT, SS_FATAL|EACCES, "DATA PROTECT" },
96 { SSD_KEY_BLANK_CHECK, SS_FATAL|ENOSPC, "BLANK CHECK" },
97 { SSD_KEY_Vendor_Specific, SS_FATAL|EIO, "Vendor Specific" },
98 { SSD_KEY_COPY_ABORTED, SS_FATAL|EIO, "COPY ABORTED" },
99 { SSD_KEY_ABORTED_COMMAND, SS_RDEF, "ABORTED COMMAND" },
100 { SSD_KEY_EQUAL, SS_NOP, "EQUAL" },
101 { SSD_KEY_VOLUME_OVERFLOW, SS_FATAL|EIO, "VOLUME OVERFLOW" },
102 { SSD_KEY_MISCOMPARE, SS_NOP, "MISCOMPARE" },
103 { SSD_KEY_RESERVED, SS_FATAL|EIO, "RESERVED" }
104};
105
106static const int sense_key_table_size =
107 sizeof(sense_key_table)/sizeof(sense_key_table[0]);
108
109static struct asc_table_entry quantum_fireball_entries[] = {
110 {SST(0x04, 0x0b, SS_START|SSQ_DECREMENT_COUNT|ENXIO,
111 "Logical unit not ready, initializing cmd. required")}
112};
113
114static struct asc_table_entry sony_mo_entries[] = {
115 {SST(0x04, 0x00, SS_START|SSQ_DECREMENT_COUNT|ENXIO,
116 "Logical unit not ready, cause not reportable")}
117};
118
119static struct scsi_sense_quirk_entry sense_quirk_table[] = {
120 {
121 /*
122 * The Quantum Fireball ST and SE like to return 0x04 0x0b when
123 * they really should return 0x04 0x02. 0x04,0x0b isn't
124 * defined in any SCSI spec, and it isn't mentioned in the
125 * hardware manual for these drives.
126 */
127 {T_DIRECT, SIP_MEDIA_FIXED, "QUANTUM", "FIREBALL S*", "*"},
128 /*num_sense_keys*/0,
129 sizeof(quantum_fireball_entries)/sizeof(struct asc_table_entry),
130 /*sense key entries*/NULL,
131 quantum_fireball_entries
132 },
133 {
134 /*
135 * This Sony MO drive likes to return 0x04, 0x00 when it
136 * isn't spun up.
137 */
138 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SONY", "SMO-*", "*"},
139 /*num_sense_keys*/0,
140 sizeof(sony_mo_entries)/sizeof(struct asc_table_entry),
141 /*sense key entries*/NULL,
142 sony_mo_entries
143 }
144};
145
146static const int sense_quirk_table_size =
147 sizeof(sense_quirk_table)/sizeof(sense_quirk_table[0]);
148
149static struct asc_table_entry asc_table[] = {
150/*
151 * From File: ASC-NUM.TXT
152 * SCSI ASC/ASCQ Assignments
153 * Numeric Sorted Listing
154 * as of 5/12/97
155 *
156 * D - DIRECT ACCESS DEVICE (SBC) device column key
157 * .T - SEQUENTIAL ACCESS DEVICE (SSC) -------------------
158 * . L - PRINTER DEVICE (SSC) blank = reserved
159 * . P - PROCESSOR DEVICE (SPC) not blank = allowed
160 * . .W - WRITE ONCE READ MULTIPLE DEVICE (SBC)
161 * . . R - CD DEVICE (MMC)
162 * . . S - SCANNER DEVICE (SGC)
163 * . . .O - OPTICAL MEMORY DEVICE (SBC)
164 * . . . M - MEDIA CHANGER DEVICE (SMC)
165 * . . . C - COMMUNICATION DEVICE (SSC)
166 * . . . .A - STORAGE ARRAY DEVICE (SCC)
167 * . . . . E - ENCLOSURE SERVICES DEVICE (SES)
168 * DTLPWRSOMCAE ASC ASCQ Action Description
169 * ------------ ---- ---- ------ -----------------------------------*/
170/* DTLPWRSOMCAE */{SST(0x00, 0x00, SS_NOP,
171 "No additional sense information") },
172/* T S */{SST(0x00, 0x01, SS_RDEF,
173 "Filemark detected") },
174/* T S */{SST(0x00, 0x02, SS_RDEF,
175 "End-of-partition/medium detected") },
176/* T */{SST(0x00, 0x03, SS_RDEF,
177 "Setmark detected") },
178/* T S */{SST(0x00, 0x04, SS_RDEF,
179 "Beginning-of-partition/medium detected") },
180/* T S */{SST(0x00, 0x05, SS_RDEF,
181 "End-of-data detected") },
182/* DTLPWRSOMCAE */{SST(0x00, 0x06, SS_RDEF,
183 "I/O process terminated") },
184/* R */{SST(0x00, 0x11, SS_FATAL|EBUSY,
185 "Audio play operation in progress") },
186/* R */{SST(0x00, 0x12, SS_NOP,
187 "Audio play operation paused") },
188/* R */{SST(0x00, 0x13, SS_NOP,
189 "Audio play operation successfully completed") },
190/* R */{SST(0x00, 0x14, SS_RDEF,
191 "Audio play operation stopped due to error") },
192/* R */{SST(0x00, 0x15, SS_NOP,
193 "No current audio status to return") },
194/* DTLPWRSOMCAE */{SST(0x00, 0x16, SS_FATAL|EBUSY,
195 "Operation in progress") },
196/* DTL WRSOM AE */{SST(0x00, 0x17, SS_RDEF,
197 "Cleaning requested") },
198/* D W O */{SST(0x01, 0x00, SS_RDEF,
199 "No index/sector signal") },
200/* D WR OM */{SST(0x02, 0x00, SS_RDEF,
201 "No seek complete") },
202/* DTL W SO */{SST(0x03, 0x00, SS_RDEF,
203 "Peripheral device write fault") },
204/* T */{SST(0x03, 0x01, SS_RDEF,
205 "No write current") },
206/* T */{SST(0x03, 0x02, SS_RDEF,
207 "Excessive write errors") },
208/* DTLPWRSOMCAE */{SST(0x04, 0x00,
209 SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EIO,
210 "Logical unit not ready, cause not reportable") },
211/* DTLPWRSOMCAE */{SST(0x04, 0x01,
212 SS_TUR|SSQ_DELAY|SSQ_MANY|SSQ_DECREMENT_COUNT|EBUSY,
213 "Logical unit is in process of becoming ready") },
214/* DTLPWRSOMCAE */{SST(0x04, 0x02, SS_START|SSQ_DECREMENT_COUNT|ENXIO,
215 "Logical unit not ready, initializing cmd. required") },
216/* DTLPWRSOMCAE */{SST(0x04, 0x03, SS_FATAL|ENXIO,
217 "Logical unit not ready, manual intervention required")},
218/* DTL O */{SST(0x04, 0x04, SS_FATAL|EBUSY,
219 "Logical unit not ready, format in progress") },
220/* DT W OMCA */{SST(0x04, 0x05, SS_FATAL|EBUSY,
221 "Logical unit not ready, rebuild in progress") },
222/* DT W OMCA */{SST(0x04, 0x06, SS_FATAL|EBUSY,
223 "Logical unit not ready, recalculation in progress") },
224/* DTLPWRSOMCAE */{SST(0x04, 0x07, SS_FATAL|EBUSY,
225 "Logical unit not ready, operation in progress") },
226/* R */{SST(0x04, 0x08, SS_FATAL|EBUSY,
227 "Logical unit not ready, long write in progress") },
228/* DTL WRSOMCAE */{SST(0x05, 0x00, SS_RDEF,
229 "Logical unit does not respond to selection") },
230/* D WR OM */{SST(0x06, 0x00, SS_RDEF,
231 "No reference position found") },
232/* DTL WRSOM */{SST(0x07, 0x00, SS_RDEF,
233 "Multiple peripheral devices selected") },
234/* DTL WRSOMCAE */{SST(0x08, 0x00, SS_RDEF,
235 "Logical unit communication failure") },
236/* DTL WRSOMCAE */{SST(0x08, 0x01, SS_RDEF,
237 "Logical unit communication time-out") },
238/* DTL WRSOMCAE */{SST(0x08, 0x02, SS_RDEF,
239 "Logical unit communication parity error") },
240/* DT R OM */{SST(0x08, 0x03, SS_RDEF,
241 "Logical unit communication crc error (ultra-dma/32)")},
242/* DT WR O */{SST(0x09, 0x00, SS_RDEF,
243 "Track following error") },
244/* WR O */{SST(0x09, 0x01, SS_RDEF,
245 "Tracking servo failure") },
246/* WR O */{SST(0x09, 0x02, SS_RDEF,
247 "Focus servo failure") },
248/* WR O */{SST(0x09, 0x03, SS_RDEF,
249 "Spindle servo failure") },
250/* DT WR O */{SST(0x09, 0x04, SS_RDEF,
251 "Head select fault") },
252/* DTLPWRSOMCAE */{SST(0x0A, 0x00, SS_FATAL|ENOSPC,
253 "Error log overflow") },
254/* DTLPWRSOMCAE */{SST(0x0B, 0x00, SS_RDEF,
255 "Warning") },
256/* DTLPWRSOMCAE */{SST(0x0B, 0x01, SS_RDEF,
257 "Specified temperature exceeded") },
258/* DTLPWRSOMCAE */{SST(0x0B, 0x02, SS_RDEF,
259 "Enclosure degraded") },
260/* T RS */{SST(0x0C, 0x00, SS_RDEF,
261 "Write error") },
262/* D W O */{SST(0x0C, 0x01, SS_NOP|SSQ_PRINT_SENSE,
263 "Write error - recovered with auto reallocation") },
264/* D W O */{SST(0x0C, 0x02, SS_RDEF,
265 "Write error - auto reallocation failed") },
266/* D W O */{SST(0x0C, 0x03, SS_RDEF,
267 "Write error - recommend reassignment") },
268/* DT W O */{SST(0x0C, 0x04, SS_RDEF,
269 "Compression check miscompare error") },
270/* DT W O */{SST(0x0C, 0x05, SS_RDEF,
271 "Data expansion occurred during compression") },
272/* DT W O */{SST(0x0C, 0x06, SS_RDEF,
273 "Block not compressible") },
274/* R */{SST(0x0C, 0x07, SS_RDEF,
275 "Write error - recovery needed") },
276/* R */{SST(0x0C, 0x08, SS_RDEF,
277 "Write error - recovery failed") },
278/* R */{SST(0x0C, 0x09, SS_RDEF,
279 "Write error - loss of streaming") },
280/* R */{SST(0x0C, 0x0A, SS_RDEF,
281 "Write error - padding blocks added") },
282/* D W O */{SST(0x10, 0x00, SS_RDEF,
283 "ID CRC or ECC error") },
284/* DT WRSO */{SST(0x11, 0x00, SS_RDEF,
285 "Unrecovered read error") },
286/* DT W SO */{SST(0x11, 0x01, SS_RDEF,
287 "Read retries exhausted") },
288/* DT W SO */{SST(0x11, 0x02, SS_RDEF,
289 "Error too long to correct") },
290/* DT W SO */{SST(0x11, 0x03, SS_RDEF,
291 "Multiple read errors") },
292/* D W O */{SST(0x11, 0x04, SS_RDEF,
293 "Unrecovered read error - auto reallocate failed") },
294/* WR O */{SST(0x11, 0x05, SS_RDEF,
295 "L-EC uncorrectable error") },
296/* WR O */{SST(0x11, 0x06, SS_RDEF,
297 "CIRC unrecovered error") },
298/* W O */{SST(0x11, 0x07, SS_RDEF,
299 "Data re-synchronization error") },
300/* T */{SST(0x11, 0x08, SS_RDEF,
301 "Incomplete block read") },
302/* T */{SST(0x11, 0x09, SS_RDEF,
303 "No gap found") },
304/* DT O */{SST(0x11, 0x0A, SS_RDEF,
305 "Miscorrected error") },
306/* D W O */{SST(0x11, 0x0B, SS_RDEF,
307 "Unrecovered read error - recommend reassignment") },
308/* D W O */{SST(0x11, 0x0C, SS_RDEF,
309 "Unrecovered read error - recommend rewrite the data")},
310/* DT WR O */{SST(0x11, 0x0D, SS_RDEF,
311 "De-compression CRC error") },
312/* DT WR O */{SST(0x11, 0x0E, SS_RDEF,
313 "Cannot decompress using declared algorithm") },
314/* R */{SST(0x11, 0x0F, SS_RDEF,
315 "Error reading UPC/EAN number") },
316/* R */{SST(0x11, 0x10, SS_RDEF,
317 "Error reading ISRC number") },
318/* R */{SST(0x11, 0x11, SS_RDEF,
319 "Read error - loss of streaming") },
320/* D W O */{SST(0x12, 0x00, SS_RDEF,
321 "Address mark not found for id field") },
322/* D W O */{SST(0x13, 0x00, SS_RDEF,
323 "Address mark not found for data field") },
324/* DTL WRSO */{SST(0x14, 0x00, SS_RDEF,
325 "Recorded entity not found") },
326/* DT WR O */{SST(0x14, 0x01, SS_RDEF,
327 "Record not found") },
328/* T */{SST(0x14, 0x02, SS_RDEF,
329 "Filemark or setmark not found") },
330/* T */{SST(0x14, 0x03, SS_RDEF,
331 "End-of-data not found") },
332/* T */{SST(0x14, 0x04, SS_RDEF,
333 "Block sequence error") },
334/* DT W O */{SST(0x14, 0x05, SS_RDEF,
335 "Record not found - recommend reassignment") },
336/* DT W O */{SST(0x14, 0x06, SS_RDEF,
337 "Record not found - data auto-reallocated") },
338/* DTL WRSOM */{SST(0x15, 0x00, SS_RDEF,
339 "Random positioning error") },
340/* DTL WRSOM */{SST(0x15, 0x01, SS_RDEF,
341 "Mechanical positioning error") },
342/* DT WR O */{SST(0x15, 0x02, SS_RDEF,
343 "Positioning error detected by read of medium") },
344/* D W O */{SST(0x16, 0x00, SS_RDEF,
345 "Data synchronization mark error") },
346/* D W O */{SST(0x16, 0x01, SS_RDEF,
347 "Data sync error - data rewritten") },
348/* D W O */{SST(0x16, 0x02, SS_RDEF,
349 "Data sync error - recommend rewrite") },
350/* D W O */{SST(0x16, 0x03, SS_NOP|SSQ_PRINT_SENSE,
351 "Data sync error - data auto-reallocated") },
352/* D W O */{SST(0x16, 0x04, SS_RDEF,
353 "Data sync error - recommend reassignment") },
354/* DT WRSO */{SST(0x17, 0x00, SS_NOP|SSQ_PRINT_SENSE,
355 "Recovered data with no error correction applied") },
356/* DT WRSO */{SST(0x17, 0x01, SS_NOP|SSQ_PRINT_SENSE,
357 "Recovered data with retries") },
358/* DT WR O */{SST(0x17, 0x02, SS_NOP|SSQ_PRINT_SENSE,
359 "Recovered data with positive head offset") },
360/* DT WR O */{SST(0x17, 0x03, SS_NOP|SSQ_PRINT_SENSE,
361 "Recovered data with negative head offset") },
362/* WR O */{SST(0x17, 0x04, SS_NOP|SSQ_PRINT_SENSE,
363 "Recovered data with retries and/or CIRC applied") },
364/* D WR O */{SST(0x17, 0x05, SS_NOP|SSQ_PRINT_SENSE,
365 "Recovered data using previous sector id") },
366/* D W O */{SST(0x17, 0x06, SS_NOP|SSQ_PRINT_SENSE,
367 "Recovered data without ECC - data auto-reallocated") },
368/* D W O */{SST(0x17, 0x07, SS_NOP|SSQ_PRINT_SENSE,
369 "Recovered data without ECC - recommend reassignment")},
370/* D W O */{SST(0x17, 0x08, SS_NOP|SSQ_PRINT_SENSE,
371 "Recovered data without ECC - recommend rewrite") },
372/* D W O */{SST(0x17, 0x09, SS_NOP|SSQ_PRINT_SENSE,
373 "Recovered data without ECC - data rewritten") },
374/* D W O */{SST(0x18, 0x00, SS_NOP|SSQ_PRINT_SENSE,
375 "Recovered data with error correction applied") },
376/* D WR O */{SST(0x18, 0x01, SS_NOP|SSQ_PRINT_SENSE,
377 "Recovered data with error corr. & retries applied") },
378/* D WR O */{SST(0x18, 0x02, SS_NOP|SSQ_PRINT_SENSE,
379 "Recovered data - data auto-reallocated") },
380/* R */{SST(0x18, 0x03, SS_NOP|SSQ_PRINT_SENSE,
381 "Recovered data with CIRC") },
382/* R */{SST(0x18, 0x04, SS_NOP|SSQ_PRINT_SENSE,
383 "Recovered data with L-EC") },
384/* D WR O */{SST(0x18, 0x05, SS_NOP|SSQ_PRINT_SENSE,
385 "Recovered data - recommend reassignment") },
386/* D WR O */{SST(0x18, 0x06, SS_NOP|SSQ_PRINT_SENSE,
387 "Recovered data - recommend rewrite") },
388/* D W O */{SST(0x18, 0x07, SS_NOP|SSQ_PRINT_SENSE,
389 "Recovered data with ECC - data rewritten") },
390/* D O */{SST(0x19, 0x00, SS_RDEF,
391 "Defect list error") },
392/* D O */{SST(0x19, 0x01, SS_RDEF,
393 "Defect list not available") },
394/* D O */{SST(0x19, 0x02, SS_RDEF,
395 "Defect list error in primary list") },
396/* D O */{SST(0x19, 0x03, SS_RDEF,
397 "Defect list error in grown list") },
398/* DTLPWRSOMCAE */{SST(0x1A, 0x00, SS_RDEF,
399 "Parameter list length error") },
400/* DTLPWRSOMCAE */{SST(0x1B, 0x00, SS_RDEF,
401 "Synchronous data transfer error") },
402/* D O */{SST(0x1C, 0x00, SS_RDEF,
403 "Defect list not found") },
404/* D O */{SST(0x1C, 0x01, SS_RDEF,
405 "Primary defect list not found") },
406/* D O */{SST(0x1C, 0x02, SS_RDEF,
407 "Grown defect list not found") },
408/* D W O */{SST(0x1D, 0x00, SS_FATAL,
409 "Miscompare during verify operation" )},
410/* D W O */{SST(0x1E, 0x00, SS_NOP|SSQ_PRINT_SENSE,
411 "Recovered id with ecc correction") },
412/* D O */{SST(0x1F, 0x00, SS_RDEF,
413 "Partial defect list transfer") },
414/* DTLPWRSOMCAE */{SST(0x20, 0x00, SS_FATAL|EINVAL,
415 "Invalid command operation code") },
416/* DT WR OM */{SST(0x21, 0x00, SS_FATAL|EINVAL,
417 "Logical block address out of range" )},
418/* DT WR OM */{SST(0x21, 0x01, SS_FATAL|EINVAL,
419 "Invalid element address") },
420/* D */{SST(0x22, 0x00, SS_FATAL|EINVAL,
421 "Illegal function") }, /* Deprecated. Use 20 00, 24 00, or 26 00 instead */
422/* DTLPWRSOMCAE */{SST(0x24, 0x00, SS_FATAL|EINVAL,
423 "Invalid field in CDB") },
424/* DTLPWRSOMCAE */{SST(0x25, 0x00, SS_FATAL|ENXIO,
425 "Logical unit not supported") },
426/* DTLPWRSOMCAE */{SST(0x26, 0x00, SS_FATAL|EINVAL,
427 "Invalid field in parameter list") },
428/* DTLPWRSOMCAE */{SST(0x26, 0x01, SS_FATAL|EINVAL,
429 "Parameter not supported") },
430/* DTLPWRSOMCAE */{SST(0x26, 0x02, SS_FATAL|EINVAL,
431 "Parameter value invalid") },
432/* DTLPWRSOMCAE */{SST(0x26, 0x03, SS_FATAL|EINVAL,
433 "Threshold parameters not supported") },
434/* DTLPWRSOMCAE */{SST(0x26, 0x04, SS_FATAL|EINVAL,
435 "Invalid release of active persistent reservation") },
436/* DT W O */{SST(0x27, 0x00, SS_FATAL|EACCES,
437 "Write protected") },
438/* DT W O */{SST(0x27, 0x01, SS_FATAL|EACCES,
439 "Hardware write protected") },
440/* DT W O */{SST(0x27, 0x02, SS_FATAL|EACCES,
441 "Logical unit software write protected") },
442/* T */{SST(0x27, 0x03, SS_FATAL|EACCES,
443 "Associated write protect") },
444/* T */{SST(0x27, 0x04, SS_FATAL|EACCES,
445 "Persistent write protect") },
446/* T */{SST(0x27, 0x05, SS_FATAL|EACCES,
447 "Permanent write protect") },
448/* DTLPWRSOMCAE */{SST(0x28, 0x00, SS_RDEF,
449 "Not ready to ready change, medium may have changed") },
450/* DTLPWRSOMCAE */{SST(0x28, 0x01, SS_FATAL|ENXIO,
451 "Import or export element accessed") },
452/*
453 * XXX JGibbs - All of these should use the same errno, but I don't think
454 * ENXIO is the correct choice. Should we borrow from the networking
455 * errnos? ECONNRESET anyone?
456 */
457/* DTLPWRSOMCAE */{SST(0x29, 0x00, SS_RDEF,
458 "Power on, reset, or bus device reset occurred") },
459/* DTLPWRSOMCAE */{SST(0x29, 0x01, SS_RDEF,
460 "Power on occurred") },
461/* DTLPWRSOMCAE */{SST(0x29, 0x02, SS_RDEF,
462 "Scsi bus reset occurred") },
463/* DTLPWRSOMCAE */{SST(0x29, 0x03, SS_RDEF,
464 "Bus device reset function occurred") },
465/* DTLPWRSOMCAE */{SST(0x29, 0x04, SS_RDEF,
466 "Device internal reset") },
467/* DTLPWRSOMCAE */{SST(0x29, 0x05, SS_RDEF,
468 "Transceiver mode changed to single-ended") },
469/* DTLPWRSOMCAE */{SST(0x29, 0x06, SS_RDEF,
470 "Transceiver mode changed to LVD") },
471/* DTL WRSOMCAE */{SST(0x2A, 0x00, SS_RDEF,
472 "Parameters changed") },
473/* DTL WRSOMCAE */{SST(0x2A, 0x01, SS_RDEF,
474 "Mode parameters changed") },
475/* DTL WRSOMCAE */{SST(0x2A, 0x02, SS_RDEF,
476 "Log parameters changed") },
477/* DTLPWRSOMCAE */{SST(0x2A, 0x03, SS_RDEF,
478 "Reservations preempted") },
479/* DTLPWRSO C */{SST(0x2B, 0x00, SS_RDEF,
480 "Copy cannot execute since host cannot disconnect") },
481/* DTLPWRSOMCAE */{SST(0x2C, 0x00, SS_RDEF,
482 "Command sequence error") },
483/* S */{SST(0x2C, 0x01, SS_RDEF,
484 "Too many windows specified") },
485/* S */{SST(0x2C, 0x02, SS_RDEF,
486 "Invalid combination of windows specified") },
487/* R */{SST(0x2C, 0x03, SS_RDEF,
488 "Current program area is not empty") },
489/* R */{SST(0x2C, 0x04, SS_RDEF,
490 "Current program area is empty") },
491/* T */{SST(0x2D, 0x00, SS_RDEF,
492 "Overwrite error on update in place") },
493/* DTLPWRSOMCAE */{SST(0x2F, 0x00, SS_RDEF,
494 "Commands cleared by another initiator") },
495/* DT WR OM */{SST(0x30, 0x00, SS_RDEF,
496 "Incompatible medium installed") },
497/* DT WR O */{SST(0x30, 0x01, SS_RDEF,
498 "Cannot read medium - unknown format") },
499/* DT WR O */{SST(0x30, 0x02, SS_RDEF,
500 "Cannot read medium - incompatible format") },
501/* DT */{SST(0x30, 0x03, SS_RDEF,
502 "Cleaning cartridge installed") },
503/* DT WR O */{SST(0x30, 0x04, SS_RDEF,
504 "Cannot write medium - unknown format") },
505/* DT WR O */{SST(0x30, 0x05, SS_RDEF,
506 "Cannot write medium - incompatible format") },
507/* DT W O */{SST(0x30, 0x06, SS_RDEF,
508 "Cannot format medium - incompatible medium") },
509/* DTL WRSOM AE */{SST(0x30, 0x07, SS_RDEF,
510 "Cleaning failure") },
511/* R */{SST(0x30, 0x08, SS_RDEF,
512 "Cannot write - application code mismatch") },
513/* R */{SST(0x30, 0x09, SS_RDEF,
514 "Current session not fixated for append") },
515/* DT WR O */{SST(0x31, 0x00, SS_RDEF,
516 "Medium format corrupted") },
517/* D L R O */{SST(0x31, 0x01, SS_RDEF,
518 "Format command failed") },
519/* D W O */{SST(0x32, 0x00, SS_RDEF,
520 "No defect spare location available") },
521/* D W O */{SST(0x32, 0x01, SS_RDEF,
522 "Defect list update failure") },
523/* T */{SST(0x33, 0x00, SS_RDEF,
524 "Tape length error") },
525/* DTLPWRSOMCAE */{SST(0x34, 0x00, SS_RDEF,
526 "Enclosure failure") },
527/* DTLPWRSOMCAE */{SST(0x35, 0x00, SS_RDEF,
528 "Enclosure services failure") },
529/* DTLPWRSOMCAE */{SST(0x35, 0x01, SS_RDEF,
530 "Unsupported enclosure function") },
531/* DTLPWRSOMCAE */{SST(0x35, 0x02, SS_RDEF,
532 "Enclosure services unavailable") },
533/* DTLPWRSOMCAE */{SST(0x35, 0x03, SS_RDEF,
534 "Enclosure services transfer failure") },
535/* DTLPWRSOMCAE */{SST(0x35, 0x04, SS_RDEF,
536 "Enclosure services transfer refused") },
537/* L */{SST(0x36, 0x00, SS_RDEF,
538 "Ribbon, ink, or toner failure") },
539/* DTL WRSOMCAE */{SST(0x37, 0x00, SS_RDEF,
540 "Rounded parameter") },
541/* DTL WRSOMCAE */{SST(0x39, 0x00, SS_RDEF,
542 "Saving parameters not supported") },
543/* DTL WRSOM */{SST(0x3A, 0x00, SS_NOP,
544 "Medium not present") },
545/* DT WR OM */{SST(0x3A, 0x01, SS_NOP,
546 "Medium not present - tray closed") },
547/* DT WR OM */{SST(0x3A, 0x01, SS_NOP,
548 "Medium not present - tray open") },
549/* DT WR OM */{SST(0x3A, 0x03, SS_NOP,
550 "Medium not present - Loadable") },
551/* DT WR OM */{SST(0x3A, 0x04, SS_NOP,
552 "Medium not present - medium auxiliary "
553 "memory accessible") },
554/* DT WR OM */{SST(0x3A, 0xFF, SS_NOP, NULL) },/* Range 0x05->0xFF */
555/* TL */{SST(0x3B, 0x00, SS_RDEF,
556 "Sequential positioning error") },
557/* T */{SST(0x3B, 0x01, SS_RDEF,
558 "Tape position error at beginning-of-medium") },
559/* T */{SST(0x3B, 0x02, SS_RDEF,
560 "Tape position error at end-of-medium") },
561/* L */{SST(0x3B, 0x03, SS_RDEF,
562 "Tape or electronic vertical forms unit not ready") },
563/* L */{SST(0x3B, 0x04, SS_RDEF,
564 "Slew failure") },
565/* L */{SST(0x3B, 0x05, SS_RDEF,
566 "Paper jam") },
567/* L */{SST(0x3B, 0x06, SS_RDEF,
568 "Failed to sense top-of-form") },
569/* L */{SST(0x3B, 0x07, SS_RDEF,
570 "Failed to sense bottom-of-form") },
571/* T */{SST(0x3B, 0x08, SS_RDEF,
572 "Reposition error") },
573/* S */{SST(0x3B, 0x09, SS_RDEF,
574 "Read past end of medium") },
575/* S */{SST(0x3B, 0x0A, SS_RDEF,
576 "Read past beginning of medium") },
577/* S */{SST(0x3B, 0x0B, SS_RDEF,
578 "Position past end of medium") },
579/* T S */{SST(0x3B, 0x0C, SS_RDEF,
580 "Position past beginning of medium") },
581/* DT WR OM */{SST(0x3B, 0x0D, SS_FATAL|ENOSPC,
582 "Medium destination element full") },
583/* DT WR OM */{SST(0x3B, 0x0E, SS_RDEF,
584 "Medium source element empty") },
585/* R */{SST(0x3B, 0x0F, SS_RDEF,
586 "End of medium reached") },
587/* DT WR OM */{SST(0x3B, 0x11, SS_RDEF,
588 "Medium magazine not accessible") },
589/* DT WR OM */{SST(0x3B, 0x12, SS_RDEF,
590 "Medium magazine removed") },
591/* DT WR OM */{SST(0x3B, 0x13, SS_RDEF,
592 "Medium magazine inserted") },
593/* DT WR OM */{SST(0x3B, 0x14, SS_RDEF,
594 "Medium magazine locked") },
595/* DT WR OM */{SST(0x3B, 0x15, SS_RDEF,
596 "Medium magazine unlocked") },
597/* DTLPWRSOMCAE */{SST(0x3D, 0x00, SS_RDEF,
598 "Invalid bits in identify message") },
599/* DTLPWRSOMCAE */{SST(0x3E, 0x00, SS_RDEF,
600 "Logical unit has not self-configured yet") },
601/* DTLPWRSOMCAE */{SST(0x3E, 0x01, SS_RDEF,
602 "Logical unit failure") },
603/* DTLPWRSOMCAE */{SST(0x3E, 0x02, SS_RDEF,
604 "Timeout on logical unit") },
605/* DTLPWRSOMCAE */{SST(0x3F, 0x00, SS_RDEF,
606 "Target operating conditions have changed") },
607/* DTLPWRSOMCAE */{SST(0x3F, 0x01, SS_RDEF,
608 "Microcode has been changed") },
609/* DTLPWRSOMC */{SST(0x3F, 0x02, SS_RDEF,
610 "Changed operating definition") },
611/* DTLPWRSOMCAE */{SST(0x3F, 0x03, SS_INQ_REFRESH|SSQ_DECREMENT_COUNT,
612 "Inquiry data has changed") },
613/* DT WR OMCAE */{SST(0x3F, 0x04, SS_RDEF,
614 "Component device attached") },
615/* DT WR OMCAE */{SST(0x3F, 0x05, SS_RDEF,
616 "Device identifier changed") },
617/* DT WR OMCAE */{SST(0x3F, 0x06, SS_RDEF,
618 "Redundancy group created or modified") },
619/* DT WR OMCAE */{SST(0x3F, 0x07, SS_RDEF,
620 "Redundancy group deleted") },
621/* DT WR OMCAE */{SST(0x3F, 0x08, SS_RDEF,
622 "Spare created or modified") },
623/* DT WR OMCAE */{SST(0x3F, 0x09, SS_RDEF,
624 "Spare deleted") },
625/* DT WR OMCAE */{SST(0x3F, 0x0A, SS_RDEF,
626 "Volume set created or modified") },
627/* DT WR OMCAE */{SST(0x3F, 0x0B, SS_RDEF,
628 "Volume set deleted") },
629/* DT WR OMCAE */{SST(0x3F, 0x0C, SS_RDEF,
630 "Volume set deassigned") },
631/* DT WR OMCAE */{SST(0x3F, 0x0D, SS_RDEF,
632 "Volume set reassigned") },
633/* DTLPWRSOMCAE */{SST(0x3F, 0x0E, SS_RDEF,
634 "Reported luns data has changed") },
635/* DTLPWRSOMCAE */{SST(0x3F, 0x0F, SS_RETRY|SSQ_DECREMENT_COUNT
636 | SSQ_DELAY_RANDOM|EBUSY,
637 "Echo buffer overwritten") },
638/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF, "Medium Loadable") },
639/* DT WR OM B*/{SST(0x3F, 0x0F, SS_RDEF,
640 "Medium auxiliary memory accessible") },
641/* D */{SST(0x40, 0x00, SS_RDEF,
642 "Ram failure") }, /* deprecated - use 40 NN instead */
643/* DTLPWRSOMCAE */{SST(0x40, 0x80, SS_RDEF,
644 "Diagnostic failure: ASCQ = Component ID") },
645/* DTLPWRSOMCAE */{SST(0x40, 0xFF, SS_RDEF|SSQ_RANGE,
646 NULL) },/* Range 0x80->0xFF */
647/* D */{SST(0x41, 0x00, SS_RDEF,
648 "Data path failure") }, /* deprecated - use 40 NN instead */
649/* D */{SST(0x42, 0x00, SS_RDEF,
650 "Power-on or self-test failure") }, /* deprecated - use 40 NN instead */
651/* DTLPWRSOMCAE */{SST(0x43, 0x00, SS_RDEF,
652 "Message error") },
653/* DTLPWRSOMCAE */{SST(0x44, 0x00, SS_RDEF,
654 "Internal target failure") },
655/* DTLPWRSOMCAE */{SST(0x45, 0x00, SS_RDEF,
656 "Select or reselect failure") },
657/* DTLPWRSOMC */{SST(0x46, 0x00, SS_RDEF,
658 "Unsuccessful soft reset") },
659/* DTLPWRSOMCAE */{SST(0x47, 0x00, SS_RDEF|SSQ_FALLBACK,
660 "SCSI parity error") },
661/* DTLPWRSOMCAE */{SST(0x47, 0x01, SS_RDEF|SSQ_FALLBACK,
662 "Data Phase CRC error detected") },
663/* DTLPWRSOMCAE */{SST(0x47, 0x02, SS_RDEF|SSQ_FALLBACK,
664 "SCSI parity error detected during ST data phase") },
665/* DTLPWRSOMCAE */{SST(0x47, 0x03, SS_RDEF|SSQ_FALLBACK,
666 "Information Unit iuCRC error") },
667/* DTLPWRSOMCAE */{SST(0x47, 0x04, SS_RDEF|SSQ_FALLBACK,
668 "Asynchronous information protection error detected") },
669/* DTLPWRSOMCAE */{SST(0x47, 0x05, SS_RDEF|SSQ_FALLBACK,
670 "Protocol server CRC error") },
671/* DTLPWRSOMCAE */{SST(0x48, 0x00, SS_RDEF|SSQ_FALLBACK,
672 "Initiator detected error message received") },
673/* DTLPWRSOMCAE */{SST(0x49, 0x00, SS_RDEF,
674 "Invalid message error") },
675/* DTLPWRSOMCAE */{SST(0x4A, 0x00, SS_RDEF,
676 "Command phase error") },
677/* DTLPWRSOMCAE */{SST(0x4B, 0x00, SS_RDEF,
678 "Data phase error") },
679/* DTLPWRSOMCAE */{SST(0x4C, 0x00, SS_RDEF,
680 "Logical unit failed self-configuration") },
681/* DTLPWRSOMCAE */{SST(0x4D, 0x00, SS_RDEF,
682 "Tagged overlapped commands: ASCQ = Queue tag ID") },
683/* DTLPWRSOMCAE */{SST(0x4D, 0xFF, SS_RDEF|SSQ_RANGE,
684 NULL)}, /* Range 0x00->0xFF */
685/* DTLPWRSOMCAE */{SST(0x4E, 0x00, SS_RDEF,
686 "Overlapped commands attempted") },
687/* T */{SST(0x50, 0x00, SS_RDEF,
688 "Write append error") },
689/* T */{SST(0x50, 0x01, SS_RDEF,
690 "Write append position error") },
691/* T */{SST(0x50, 0x02, SS_RDEF,
692 "Position error related to timing") },
693/* T O */{SST(0x51, 0x00, SS_RDEF,
694 "Erase failure") },
695/* T */{SST(0x52, 0x00, SS_RDEF,
696 "Cartridge fault") },
697/* DTL WRSOM */{SST(0x53, 0x00, SS_RDEF,
698 "Media load or eject failed") },
699/* T */{SST(0x53, 0x01, SS_RDEF,
700 "Unload tape failure") },
701/* DT WR OM */{SST(0x53, 0x02, SS_RDEF,
702 "Medium removal prevented") },
703/* P */{SST(0x54, 0x00, SS_RDEF,
704 "Scsi to host system interface failure") },
705/* P */{SST(0x55, 0x00, SS_RDEF,
706 "System resource failure") },
707/* D O */{SST(0x55, 0x01, SS_FATAL|ENOSPC,
708 "System buffer full") },
709/* R */{SST(0x57, 0x00, SS_RDEF,
710 "Unable to recover table-of-contents") },
711/* O */{SST(0x58, 0x00, SS_RDEF,
712 "Generation does not exist") },
713/* O */{SST(0x59, 0x00, SS_RDEF,
714 "Updated block read") },
715/* DTLPWRSOM */{SST(0x5A, 0x00, SS_RDEF,
716 "Operator request or state change input") },
717/* DT WR OM */{SST(0x5A, 0x01, SS_RDEF,
718 "Operator medium removal request") },
719/* DT W O */{SST(0x5A, 0x02, SS_RDEF,
720 "Operator selected write protect") },
721/* DT W O */{SST(0x5A, 0x03, SS_RDEF,
722 "Operator selected write permit") },
723/* DTLPWRSOM */{SST(0x5B, 0x00, SS_RDEF,
724 "Log exception") },
725/* DTLPWRSOM */{SST(0x5B, 0x01, SS_RDEF,
726 "Threshold condition met") },
727/* DTLPWRSOM */{SST(0x5B, 0x02, SS_RDEF,
728 "Log counter at maximum") },
729/* DTLPWRSOM */{SST(0x5B, 0x03, SS_RDEF,
730 "Log list codes exhausted") },
731/* D O */{SST(0x5C, 0x00, SS_RDEF,
732 "RPL status change") },
733/* D O */{SST(0x5C, 0x01, SS_NOP|SSQ_PRINT_SENSE,
734 "Spindles synchronized") },
735/* D O */{SST(0x5C, 0x02, SS_RDEF,
736 "Spindles not synchronized") },
737/* DTLPWRSOMCAE */{SST(0x5D, 0x00, SS_RDEF,
738 "Failure prediction threshold exceeded") },
739/* DTLPWRSOMCAE */{SST(0x5D, 0xFF, SS_RDEF,
740 "Failure prediction threshold exceeded (false)") },
741/* DTLPWRSO CA */{SST(0x5E, 0x00, SS_RDEF,
742 "Low power condition on") },
743/* DTLPWRSO CA */{SST(0x5E, 0x01, SS_RDEF,
744 "Idle condition activated by timer") },
745/* DTLPWRSO CA */{SST(0x5E, 0x02, SS_RDEF,
746 "Standby condition activated by timer") },
747/* DTLPWRSO CA */{SST(0x5E, 0x03, SS_RDEF,
748 "Idle condition activated by command") },
749/* DTLPWRSO CA */{SST(0x5E, 0x04, SS_RDEF,
750 "Standby condition activated by command") },
751/* S */{SST(0x60, 0x00, SS_RDEF,
752 "Lamp failure") },
753/* S */{SST(0x61, 0x00, SS_RDEF,
754 "Video acquisition error") },
755/* S */{SST(0x61, 0x01, SS_RDEF,
756 "Unable to acquire video") },
757/* S */{SST(0x61, 0x02, SS_RDEF,
758 "Out of focus") },
759/* S */{SST(0x62, 0x00, SS_RDEF,
760 "Scan head positioning error") },
761/* R */{SST(0x63, 0x00, SS_RDEF,
762 "End of user area encountered on this track") },
763/* R */{SST(0x63, 0x01, SS_FATAL|ENOSPC,
764 "Packet does not fit in available space") },
765/* R */{SST(0x64, 0x00, SS_RDEF,
766 "Illegal mode for this track") },
767/* R */{SST(0x64, 0x01, SS_RDEF,
768 "Invalid packet size") },
769/* DTLPWRSOMCAE */{SST(0x65, 0x00, SS_RDEF,
770 "Voltage fault") },
771/* S */{SST(0x66, 0x00, SS_RDEF,
772 "Automatic document feeder cover up") },
773/* S */{SST(0x66, 0x01, SS_RDEF,
774 "Automatic document feeder lift up") },
775/* S */{SST(0x66, 0x02, SS_RDEF,
776 "Document jam in automatic document feeder") },
777/* S */{SST(0x66, 0x03, SS_RDEF,
778 "Document miss feed automatic in document feeder") },
779/* A */{SST(0x67, 0x00, SS_RDEF,
780 "Configuration failure") },
781/* A */{SST(0x67, 0x01, SS_RDEF,
782 "Configuration of incapable logical units failed") },
783/* A */{SST(0x67, 0x02, SS_RDEF,
784 "Add logical unit failed") },
785/* A */{SST(0x67, 0x03, SS_RDEF,
786 "Modification of logical unit failed") },
787/* A */{SST(0x67, 0x04, SS_RDEF,
788 "Exchange of logical unit failed") },
789/* A */{SST(0x67, 0x05, SS_RDEF,
790 "Remove of logical unit failed") },
791/* A */{SST(0x67, 0x06, SS_RDEF,
792 "Attachment of logical unit failed") },
793/* A */{SST(0x67, 0x07, SS_RDEF,
794 "Creation of logical unit failed") },
795/* A */{SST(0x68, 0x00, SS_RDEF,
796 "Logical unit not configured") },
797/* A */{SST(0x69, 0x00, SS_RDEF,
798 "Data loss on logical unit") },
799/* A */{SST(0x69, 0x01, SS_RDEF,
800 "Multiple logical unit failures") },
801/* A */{SST(0x69, 0x02, SS_RDEF,
802 "Parity/data mismatch") },
803/* A */{SST(0x6A, 0x00, SS_RDEF,
804 "Informational, refer to log") },
805/* A */{SST(0x6B, 0x00, SS_RDEF,
806 "State change has occurred") },
807/* A */{SST(0x6B, 0x01, SS_RDEF,
808 "Redundancy level got better") },
809/* A */{SST(0x6B, 0x02, SS_RDEF,
810 "Redundancy level got worse") },
811/* A */{SST(0x6C, 0x00, SS_RDEF,
812 "Rebuild failure occurred") },
813/* A */{SST(0x6D, 0x00, SS_RDEF,
814 "Recalculate failure occurred") },
815/* A */{SST(0x6E, 0x00, SS_RDEF,
816 "Command to logical unit failed") },
817/* T */{SST(0x70, 0x00, SS_RDEF,
818 "Decompression exception short: ASCQ = Algorithm ID") },
819/* T */{SST(0x70, 0xFF, SS_RDEF|SSQ_RANGE,
820 NULL) }, /* Range 0x00 -> 0xFF */
821/* T */{SST(0x71, 0x00, SS_RDEF,
822 "Decompression exception long: ASCQ = Algorithm ID") },
823/* T */{SST(0x71, 0xFF, SS_RDEF|SSQ_RANGE,
824 NULL) }, /* Range 0x00 -> 0xFF */
825/* R */{SST(0x72, 0x00, SS_RDEF,
826 "Session fixation error") },
827/* R */{SST(0x72, 0x01, SS_RDEF,
828 "Session fixation error writing lead-in") },
829/* R */{SST(0x72, 0x02, SS_RDEF,
830 "Session fixation error writing lead-out") },
831/* R */{SST(0x72, 0x03, SS_RDEF,
832 "Session fixation error - incomplete track in session") },
833/* R */{SST(0x72, 0x04, SS_RDEF,
834 "Empty or partially written reserved track") },
835/* R */{SST(0x73, 0x00, SS_RDEF,
836 "CD control error") },
837/* R */{SST(0x73, 0x01, SS_RDEF,
838 "Power calibration area almost full") },
839/* R */{SST(0x73, 0x02, SS_FATAL|ENOSPC,
840 "Power calibration area is full") },
841/* R */{SST(0x73, 0x03, SS_RDEF,
842 "Power calibration area error") },
843/* R */{SST(0x73, 0x04, SS_RDEF,
844 "Program memory area update failure") },
845/* R */{SST(0x73, 0x05, SS_RDEF,
846 "program memory area is full") }
847};
848
849static const int asc_table_size = sizeof(asc_table)/sizeof(asc_table[0]);
850
851struct asc_key
852{
853 int asc;
854 int ascq;
855};
856
857static int
858ascentrycomp(const void *key, const void *member)
859{
860 int asc;
861 int ascq;
862 const struct asc_table_entry *table_entry;
863
864 asc = ((const struct asc_key *)key)->asc;
865 ascq = ((const struct asc_key *)key)->ascq;
866 table_entry = (const struct asc_table_entry *)member;
867
868 if (asc >= table_entry->asc) {
869
870 if (asc > table_entry->asc)
871 return (1);
872
873 if (ascq <= table_entry->ascq) {
874 /* Check for ranges */
875 if (ascq == table_entry->ascq
876 || ((table_entry->action & SSQ_RANGE) != 0
877 && ascq >= (table_entry - 1)->ascq))
878 return (0);
879 return (-1);
880 }
881 return (1);
882 }
883 return (-1);
884}
885
886static int
887senseentrycomp(const void *key, const void *member)
888{
889 int sense_key;
890 const struct sense_key_table_entry *table_entry;
891
892 sense_key = *((const int *)key);
893 table_entry = (const struct sense_key_table_entry *)member;
894
895 if (sense_key >= table_entry->sense_key) {
896 if (sense_key == table_entry->sense_key)
897 return (0);
898 return (1);
899 }
900 return (-1);
901}
902
903static void
904fetchtableentries(int sense_key, int asc, int ascq,
905 struct scsi_inquiry_data *inq_data,
906 const struct sense_key_table_entry **sense_entry,
907 const struct asc_table_entry **asc_entry)
908{
909 void *match;
910 const struct asc_table_entry *asc_tables[2];
911 const struct sense_key_table_entry *sense_tables[2];
912 struct asc_key asc_ascq;
913 size_t asc_tables_size[2];
914 size_t sense_tables_size[2];
915 int num_asc_tables;
916 int num_sense_tables;
917 int i;
918
919 /* Default to failure */
920 *sense_entry = NULL;
921 *asc_entry = NULL;
922 match = NULL;
923 if (inq_data != NULL)
924 match = cam_quirkmatch((void *)inq_data,
925 (void *)sense_quirk_table,
926 sense_quirk_table_size,
927 sizeof(*sense_quirk_table),
928 aic_inquiry_match);
929
930 if (match != NULL) {
931 struct scsi_sense_quirk_entry *quirk;
932
933 quirk = (struct scsi_sense_quirk_entry *)match;
934 asc_tables[0] = quirk->asc_info;
935 asc_tables_size[0] = quirk->num_ascs;
936 asc_tables[1] = asc_table;
937 asc_tables_size[1] = asc_table_size;
938 num_asc_tables = 2;
939 sense_tables[0] = quirk->sense_key_info;
940 sense_tables_size[0] = quirk->num_sense_keys;
941 sense_tables[1] = sense_key_table;
942 sense_tables_size[1] = sense_key_table_size;
943 num_sense_tables = 2;
944 } else {
945 asc_tables[0] = asc_table;
946 asc_tables_size[0] = asc_table_size;
947 num_asc_tables = 1;
948 sense_tables[0] = sense_key_table;
949 sense_tables_size[0] = sense_key_table_size;
950 num_sense_tables = 1;
951 }
952
953 asc_ascq.asc = asc;
954 asc_ascq.ascq = ascq;
955 for (i = 0; i < num_asc_tables; i++) {
956 void *found_entry;
957
958 found_entry = scsibsearch(&asc_ascq, asc_tables[i],
959 asc_tables_size[i],
960 sizeof(**asc_tables),
961 ascentrycomp);
962
963 if (found_entry) {
964 *asc_entry = (struct asc_table_entry *)found_entry;
965 break;
966 }
967 }
968
969 for (i = 0; i < num_sense_tables; i++) {
970 void *found_entry;
971
972 found_entry = scsibsearch(&sense_key, sense_tables[i],
973 sense_tables_size[i],
974 sizeof(**sense_tables),
975 senseentrycomp);
976
977 if (found_entry) {
978 *sense_entry =
979 (struct sense_key_table_entry *)found_entry;
980 break;
981 }
982 }
983}
984
985static void *
986scsibsearch(const void *key, const void *base, size_t nmemb, size_t size,
987 int (*compar)(const void *, const void *))
988{
989 const void *entry;
990 u_int l;
991 u_int u;
992 u_int m;
993
994 l = -1;
995 u = nmemb;
996 while (l + 1 != u) {
997 m = (l + u) / 2;
998 entry = base + m * size;
999 if (compar(key, entry) > 0)
1000 l = m;
1001 else
1002 u = m;
1003 }
1004
1005 entry = base + u * size;
1006 if (u == nmemb
1007 || compar(key, entry) != 0)
1008 return (NULL);
1009
1010 return ((void *)entry);
1011}
1012
1013/*
1014 * Compare string with pattern, returning 0 on match.
1015 * Short pattern matches trailing blanks in name,
1016 * wildcard '*' in pattern matches rest of name,
1017 * wildcard '?' matches a single non-space character.
1018 */
1019static int
1020cam_strmatch(const uint8_t *str, const uint8_t *pattern, int str_len)
1021{
1022
1023 while (*pattern != '\0'&& str_len > 0) {
1024
1025 if (*pattern == '*') {
1026 return (0);
1027 }
1028 if ((*pattern != *str)
1029 && (*pattern != '?' || *str == ' ')) {
1030 return (1);
1031 }
1032 pattern++;
1033 str++;
1034 str_len--;
1035 }
1036 while (str_len > 0 && *str++ == ' ')
1037 str_len--;
1038
1039 return (str_len);
1040}
1041
1042static caddr_t
1043cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries,
1044 int entry_size, cam_quirkmatch_t *comp_func)
1045{
1046 for (; num_entries > 0; num_entries--, quirk_table += entry_size) {
1047 if ((*comp_func)(target, quirk_table) == 0)
1048 return (quirk_table);
1049 }
1050 return (NULL);
1051}
1052
1053void
1054aic_sense_desc(int sense_key, int asc, int ascq,
1055 struct scsi_inquiry_data *inq_data,
1056 const char **sense_key_desc, const char **asc_desc)
1057{
1058 const struct asc_table_entry *asc_entry;
1059 const struct sense_key_table_entry *sense_entry;
1060
1061 fetchtableentries(sense_key, asc, ascq,
1062 inq_data,
1063 &sense_entry,
1064 &asc_entry);
1065
1066 *sense_key_desc = sense_entry->desc;
1067
1068 if (asc_entry != NULL)
1069 *asc_desc = asc_entry->desc;
1070 else if (asc >= 0x80 && asc <= 0xff)
1071 *asc_desc = "Vendor Specific ASC";
1072 else if (ascq >= 0x80 && ascq <= 0xff)
1073 *asc_desc = "Vendor Specific ASCQ";
1074 else
1075 *asc_desc = "Reserved ASC/ASCQ pair";
1076}
1077
1078/*
1079 * Given sense and device type information, return the appropriate action.
1080 * If we do not understand the specific error as identified by the ASC/ASCQ
1081 * pair, fall back on the more generic actions derived from the sense key.
1082 */
1083aic_sense_action
1084aic_sense_error_action(struct scsi_sense_data *sense_data,
1085 struct scsi_inquiry_data *inq_data, uint32_t sense_flags)
1086{
1087 const struct asc_table_entry *asc_entry;
1088 const struct sense_key_table_entry *sense_entry;
1089 int error_code, sense_key, asc, ascq;
1090 aic_sense_action action;
1091
1092 scsi_extract_sense(sense_data, &error_code, &sense_key, &asc, &ascq);
1093
1094 if (error_code == SSD_DEFERRED_ERROR) {
1095 /*
1096 * XXX dufault@FreeBSD.org
1097 * This error doesn't relate to the command associated
1098 * with this request sense. A deferred error is an error
1099 * for a command that has already returned GOOD status
1100 * (see SCSI2 8.2.14.2).
1101 *
1102 * By my reading of that section, it looks like the current
1103 * command has been cancelled, we should now clean things up
1104 * (hopefully recovering any lost data) and then retry the
1105 * current command. There are two easy choices, both wrong:
1106 *
1107 * 1. Drop through (like we had been doing), thus treating
1108 * this as if the error were for the current command and
1109 * return and stop the current command.
1110 *
1111 * 2. Issue a retry (like I made it do) thus hopefully
1112 * recovering the current transfer, and ignoring the
1113 * fact that we've dropped a command.
1114 *
1115 * These should probably be handled in a device specific
1116 * sense handler or punted back up to a user mode daemon
1117 */
1118 action = SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE;
1119 } else {
1120 fetchtableentries(sense_key, asc, ascq,
1121 inq_data,
1122 &sense_entry,
1123 &asc_entry);
1124
1125 /*
1126 * Override the 'No additional Sense' entry (0,0)
1127 * with the error action of the sense key.
1128 */
1129 if (asc_entry != NULL
1130 && (asc != 0 || ascq != 0))
1131 action = asc_entry->action;
1132 else
1133 action = sense_entry->action;
1134
1135 if (sense_key == SSD_KEY_RECOVERED_ERROR) {
1136 /*
1137 * The action succeeded but the device wants
1138 * the user to know that some recovery action
1139 * was required.
1140 */
1141 action &= ~(SS_MASK|SSQ_MASK|SS_ERRMASK);
1142 action |= SS_NOP|SSQ_PRINT_SENSE;
1143 } else if (sense_key == SSD_KEY_ILLEGAL_REQUEST) {
1144 if ((sense_flags & SF_QUIET_IR) != 0)
1145 action &= ~SSQ_PRINT_SENSE;
1146 } else if (sense_key == SSD_KEY_UNIT_ATTENTION) {
1147 if ((sense_flags & SF_RETRY_UA) != 0
1148 && (action & SS_MASK) == SS_FAIL) {
1149 action &= ~(SS_MASK|SSQ_MASK);
1150 action |= SS_RETRY|SSQ_DECREMENT_COUNT|
1151 SSQ_PRINT_SENSE;
1152 }
1153 }
1154 }
1155
1156 if ((sense_flags & SF_PRINT_ALWAYS) != 0)
1157 action |= SSQ_PRINT_SENSE;
1158 else if ((sense_flags & SF_NO_PRINT) != 0)
1159 action &= ~SSQ_PRINT_SENSE;
1160
1161 return (action);
1162}
1163
1164/*
1165 * Try make as good a match as possible with
1166 * available sub drivers
1167 */
1168int
1169aic_inquiry_match(caddr_t inqbuffer, caddr_t table_entry)
1170{
1171 struct scsi_inquiry_pattern *entry;
1172 struct scsi_inquiry_data *inq;
1173
1174 entry = (struct scsi_inquiry_pattern *)table_entry;
1175 inq = (struct scsi_inquiry_data *)inqbuffer;
1176
1177 if (((SID_TYPE(inq) == entry->type)
1178 || (entry->type == T_ANY))
1179 && (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE
1180 : entry->media_type & SIP_MEDIA_FIXED)
1181 && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0)
1182 && (cam_strmatch(inq->product, entry->product,
1183 sizeof(inq->product)) == 0)
1184 && (cam_strmatch(inq->revision, entry->revision,
1185 sizeof(inq->revision)) == 0)) {
1186 return (0);
1187 }
1188 return (-1);
1189}
1190
1191/*
1192 * Table of syncrates that don't follow the "divisible by 4"
1193 * rule. This table will be expanded in future SCSI specs.
1194 */
1195static struct {
1196 u_int period_factor;
1197 u_int period; /* in 100ths of ns */
1198} scsi_syncrates[] = {
1199 { 0x08, 625 }, /* FAST-160 */
1200 { 0x09, 1250 }, /* FAST-80 */
1201 { 0x0a, 2500 }, /* FAST-40 40MHz */
1202 { 0x0b, 3030 }, /* FAST-40 33MHz */
1203 { 0x0c, 5000 } /* FAST-20 */
1204};
1205
1206/*
1207 * Return the frequency in kHz corresponding to the given
1208 * sync period factor.
1209 */
1210u_int
1211aic_calc_syncsrate(u_int period_factor)
1212{
1213 int i;
1214 int num_syncrates;
1215
1216 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
1217 /* See if the period is in the "exception" table */
1218 for (i = 0; i < num_syncrates; i++) {
1219
1220 if (period_factor == scsi_syncrates[i].period_factor) {
1221 /* Period in kHz */
1222 return (100000000 / scsi_syncrates[i].period);
1223 }
1224 }
1225
1226 /*
1227 * Wasn't in the table, so use the standard
1228 * 4 times conversion.
1229 */
1230 return (10000000 / (period_factor * 4 * 10));
1231}
1232
1233/*
1234 * Return speed in KB/s.
1235 */
1236u_int
1237aic_calc_speed(u_int width, u_int period, u_int offset, u_int min_rate)
1238{
1239 u_int freq;
1240
1241 if (offset != 0 && period < min_rate)
1242 freq = aic_calc_syncsrate(period);
1243 else
1244 /* Roughly 3.3MB/s for async */
1245 freq = 3300;
1246 freq <<= width;
1247 return (freq);
1248}
1249
1250uint32_t
1251aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data,
1252 cam_status status, u_int scsi_status)
1253{
1254 aic_sense_action err_action;
1255 int sense;
1256
1257 sense = (cmd->result >> 24) == DRIVER_SENSE;
1258
1259 switch (status) {
1260 case CAM_REQ_CMP:
1261 err_action = SS_NOP;
1262 break;
1263 case CAM_AUTOSENSE_FAIL:
1264 case CAM_SCSI_STATUS_ERROR:
1265
1266 switch (scsi_status) {
1267 case SCSI_STATUS_OK:
1268 case SCSI_STATUS_COND_MET:
1269 case SCSI_STATUS_INTERMED:
1270 case SCSI_STATUS_INTERMED_COND_MET:
1271 err_action = SS_NOP;
1272 break;
1273 case SCSI_STATUS_CMD_TERMINATED:
1274 case SCSI_STATUS_CHECK_COND:
1275 if (sense != 0) {
1276 struct scsi_sense_data *sense;
1277
1278 sense = (struct scsi_sense_data *)
1279 &cmd->sense_buffer;
1280 err_action =
1281 aic_sense_error_action(sense, inq_data, 0);
1282
1283 } else {
1284 err_action = SS_RETRY|SSQ_FALLBACK
1285 | SSQ_DECREMENT_COUNT|EIO;
1286 }
1287 break;
1288 case SCSI_STATUS_QUEUE_FULL:
1289 case SCSI_STATUS_BUSY:
1290 err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY
1291 | SSQ_DECREMENT_COUNT|EBUSY;
1292 break;
1293 case SCSI_STATUS_RESERV_CONFLICT:
1294 default:
1295 err_action = SS_FAIL|EBUSY;
1296 break;
1297 }
1298 break;
1299 case CAM_CMD_TIMEOUT:
1300 case CAM_REQ_CMP_ERR:
1301 case CAM_UNEXP_BUSFREE:
1302 case CAM_UNCOR_PARITY:
1303 case CAM_DATA_RUN_ERR:
1304 err_action = SS_RETRY|SSQ_FALLBACK|EIO;
1305 break;
1306 case CAM_UA_ABORT:
1307 case CAM_UA_TERMIO:
1308 case CAM_MSG_REJECT_REC:
1309 case CAM_SEL_TIMEOUT:
1310 err_action = SS_FAIL|EIO;
1311 break;
1312 case CAM_REQ_INVALID:
1313 case CAM_PATH_INVALID:
1314 case CAM_DEV_NOT_THERE:
1315 case CAM_NO_HBA:
1316 case CAM_PROVIDE_FAIL:
1317 case CAM_REQ_TOO_BIG:
1318 case CAM_RESRC_UNAVAIL:
1319 case CAM_BUSY:
1320 default:
1321 /* panic?? These should never occur in our application. */
1322 err_action = SS_FAIL|EIO;
1323 break;
1324 case CAM_SCSI_BUS_RESET:
1325 case CAM_BDR_SENT:
1326 case CAM_REQUEUE_REQ:
1327 /* Unconditional requeue */
1328 err_action = SS_RETRY;
1329 break;
1330 }
1331
1332 return (err_action);
1333}
1334
1335char *
1336aic_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
1337 aic_option_callback_t *callback, u_long callback_arg)
1338{
1339 char *tok_end;
1340 char *tok_end2;
1341 int i;
1342 int instance;
1343 int targ;
1344 int done;
1345 char tok_list[] = {'.', ',', '{', '}', '\0'};
1346
1347 /* All options use a ':' name/arg separator */
1348 if (*opt_arg != ':')
1349 return (opt_arg);
1350 opt_arg++;
1351 instance = -1;
1352 targ = -1;
1353 done = FALSE;
1354 /*
1355 * Restore separator that may be in
1356 * the middle of our option argument.
1357 */
1358 tok_end = strchr(opt_arg, '\0');
1359 if (tok_end < end)
1360 *tok_end = ',';
1361 while (!done) {
1362 switch (*opt_arg) {
1363 case '{':
1364 if (instance == -1) {
1365 instance = 0;
1366 } else {
1367 if (depth > 1) {
1368 if (targ == -1)
1369 targ = 0;
1370 } else {
1371 printf("Malformed Option %s\n",
1372 opt_name);
1373 done = TRUE;
1374 }
1375 }
1376 opt_arg++;
1377 break;
1378 case '}':
1379 if (targ != -1)
1380 targ = -1;
1381 else if (instance != -1)
1382 instance = -1;
1383 opt_arg++;
1384 break;
1385 case ',':
1386 case '.':
1387 if (instance == -1)
1388 done = TRUE;
1389 else if (targ >= 0)
1390 targ++;
1391 else if (instance >= 0)
1392 instance++;
1393 opt_arg++;
1394 break;
1395 case '\0':
1396 done = TRUE;
1397 break;
1398 default:
1399 tok_end = end;
1400 for (i = 0; tok_list[i]; i++) {
1401 tok_end2 = strchr(opt_arg, tok_list[i]);
1402 if ((tok_end2) && (tok_end2 < tok_end))
1403 tok_end = tok_end2;
1404 }
1405 callback(callback_arg, instance, targ,
1406 simple_strtol(opt_arg, NULL, 0));
1407 opt_arg = tok_end;
1408 break;
1409 }
1410 }
1411 return (opt_arg);
1412}
diff --git a/drivers/scsi/aic7xxx/aiclib.h b/drivers/scsi/aic7xxx/aiclib.h
new file mode 100644
index 000000000000..bfe6f954d3c4
--- /dev/null
+++ b/drivers/scsi/aic7xxx/aiclib.h
@@ -0,0 +1,1085 @@
1/*
2 * Largely written by Julian Elischer (julian@tfs.com)
3 * for TRW Financial Systems.
4 *
5 * TRW Financial Systems, in accordance with their agreement with Carnegie
6 * Mellon University, makes this software available to CMU to distribute
7 * or use in any manner that they see fit as long as this message is kept with
8 * the software. For this reason TFS also grants any other persons or
9 * organisations permission to use or modify this software.
10 *
11 * TFS supplies this software to be publicly redistributed
12 * on the understanding that TFS is not responsible for the correct
13 * functioning of this software in any circumstances.
14 *
15 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
16 *
17 * $FreeBSD: src/sys/cam/scsi/scsi_all.h,v 1.21 2002/10/08 17:12:44 ken Exp $
18 *
19 * Copyright (c) 2003 Adaptec Inc.
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions, and the following disclaimer,
27 * without modification.
28 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
29 * substantially similar to the "NO WARRANTY" disclaimer below
30 * ("Disclaimer") and any redistribution must be conditioned upon
31 * including a substantially similar Disclaimer requirement for further
32 * binary redistribution.
33 * 3. Neither the names of the above-listed copyright holders nor the names
34 * of any contributors may be used to endorse or promote products derived
35 * from this software without specific prior written permission.
36 *
37 * Alternatively, this software may be distributed under the terms of the
38 * GNU General Public License ("GPL") version 2 as published by the Free
39 * Software Foundation.
40 *
41 * NO WARRANTY
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
51 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
52 * POSSIBILITY OF SUCH DAMAGES.
53 *
54 * $Id$
55 */
56
57#ifndef _AICLIB_H
58#define _AICLIB_H
59
60/*
61 * Linux Interrupt Support.
62 */
63#ifndef IRQ_RETVAL
64typedef void irqreturn_t;
65#define IRQ_RETVAL(x)
66#endif
67
68/*
69 * SCSI command format
70 */
71
72/*
73 * Define dome bits that are in ALL (or a lot of) scsi commands
74 */
75#define SCSI_CTL_LINK 0x01
76#define SCSI_CTL_FLAG 0x02
77#define SCSI_CTL_VENDOR 0xC0
78#define SCSI_CMD_LUN 0xA0 /* these two should not be needed */
79#define SCSI_CMD_LUN_SHIFT 5 /* LUN in the cmd is no longer SCSI */
80
81#define SCSI_MAX_CDBLEN 16 /*
82 * 16 byte commands are in the
83 * SCSI-3 spec
84 */
85/* 6byte CDBs special case 0 length to be 256 */
86#define SCSI_CDB6_LEN(len) ((len) == 0 ? 256 : len)
87
88/*
89 * This type defines actions to be taken when a particular sense code is
90 * received. Right now, these flags are only defined to take up 16 bits,
91 * but can be expanded in the future if necessary.
92 */
93typedef enum {
94 SS_NOP = 0x000000, /* Do nothing */
95 SS_RETRY = 0x010000, /* Retry the command */
96 SS_FAIL = 0x020000, /* Bail out */
97 SS_START = 0x030000, /* Send a Start Unit command to the device,
98 * then retry the original command.
99 */
100 SS_TUR = 0x040000, /* Send a Test Unit Ready command to the
101 * device, then retry the original command.
102 */
103 SS_REQSENSE = 0x050000, /* Send a RequestSense command to the
104 * device, then retry the original command.
105 */
106 SS_INQ_REFRESH = 0x060000,
107 SS_MASK = 0xff0000
108} aic_sense_action;
109
110typedef enum {
111 SSQ_NONE = 0x0000,
112 SSQ_DECREMENT_COUNT = 0x0100, /* Decrement the retry count */
113 SSQ_MANY = 0x0200, /* send lots of recovery commands */
114 SSQ_RANGE = 0x0400, /*
115 * This table entry represents the
116 * end of a range of ASCQs that
117 * have identical error actions
118 * and text.
119 */
120 SSQ_PRINT_SENSE = 0x0800,
121 SSQ_DELAY = 0x1000, /* Delay before retry. */
122 SSQ_DELAY_RANDOM = 0x2000, /* Randomized delay before retry. */
123 SSQ_FALLBACK = 0x4000, /* Do a speed fallback to recover */
124 SSQ_MASK = 0xff00
125} aic_sense_action_qualifier;
126
127/* Mask for error status values */
128#define SS_ERRMASK 0xff
129
130/* The default, retyable, error action */
131#define SS_RDEF SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE|EIO
132
133/* The retyable, error action, with table specified error code */
134#define SS_RET SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE
135
136/* Fatal error action, with table specified error code */
137#define SS_FATAL SS_FAIL|SSQ_PRINT_SENSE
138
139struct scsi_generic
140{
141 uint8_t opcode;
142 uint8_t bytes[11];
143};
144
145struct scsi_request_sense
146{
147 uint8_t opcode;
148 uint8_t byte2;
149 uint8_t unused[2];
150 uint8_t length;
151 uint8_t control;
152};
153
154struct scsi_test_unit_ready
155{
156 uint8_t opcode;
157 uint8_t byte2;
158 uint8_t unused[3];
159 uint8_t control;
160};
161
162struct scsi_send_diag
163{
164 uint8_t opcode;
165 uint8_t byte2;
166#define SSD_UOL 0x01
167#define SSD_DOL 0x02
168#define SSD_SELFTEST 0x04
169#define SSD_PF 0x10
170 uint8_t unused[1];
171 uint8_t paramlen[2];
172 uint8_t control;
173};
174
175struct scsi_sense
176{
177 uint8_t opcode;
178 uint8_t byte2;
179 uint8_t unused[2];
180 uint8_t length;
181 uint8_t control;
182};
183
184struct scsi_inquiry
185{
186 uint8_t opcode;
187 uint8_t byte2;
188#define SI_EVPD 0x01
189 uint8_t page_code;
190 uint8_t reserved;
191 uint8_t length;
192 uint8_t control;
193};
194
195struct scsi_mode_sense_6
196{
197 uint8_t opcode;
198 uint8_t byte2;
199#define SMS_DBD 0x08
200 uint8_t page;
201#define SMS_PAGE_CODE 0x3F
202#define SMS_VENDOR_SPECIFIC_PAGE 0x00
203#define SMS_DISCONNECT_RECONNECT_PAGE 0x02
204#define SMS_PERIPHERAL_DEVICE_PAGE 0x09
205#define SMS_CONTROL_MODE_PAGE 0x0A
206#define SMS_ALL_PAGES_PAGE 0x3F
207#define SMS_PAGE_CTRL_MASK 0xC0
208#define SMS_PAGE_CTRL_CURRENT 0x00
209#define SMS_PAGE_CTRL_CHANGEABLE 0x40
210#define SMS_PAGE_CTRL_DEFAULT 0x80
211#define SMS_PAGE_CTRL_SAVED 0xC0
212 uint8_t unused;
213 uint8_t length;
214 uint8_t control;
215};
216
217struct scsi_mode_sense_10
218{
219 uint8_t opcode;
220 uint8_t byte2; /* same bits as small version */
221 uint8_t page; /* same bits as small version */
222 uint8_t unused[4];
223 uint8_t length[2];
224 uint8_t control;
225};
226
227struct scsi_mode_select_6
228{
229 uint8_t opcode;
230 uint8_t byte2;
231#define SMS_SP 0x01
232#define SMS_PF 0x10
233 uint8_t unused[2];
234 uint8_t length;
235 uint8_t control;
236};
237
238struct scsi_mode_select_10
239{
240 uint8_t opcode;
241 uint8_t byte2; /* same bits as small version */
242 uint8_t unused[5];
243 uint8_t length[2];
244 uint8_t control;
245};
246
247/*
248 * When sending a mode select to a tape drive, the medium type must be 0.
249 */
250struct scsi_mode_hdr_6
251{
252 uint8_t datalen;
253 uint8_t medium_type;
254 uint8_t dev_specific;
255 uint8_t block_descr_len;
256};
257
258struct scsi_mode_hdr_10
259{
260 uint8_t datalen[2];
261 uint8_t medium_type;
262 uint8_t dev_specific;
263 uint8_t reserved[2];
264 uint8_t block_descr_len[2];
265};
266
267struct scsi_mode_block_descr
268{
269 uint8_t density_code;
270 uint8_t num_blocks[3];
271 uint8_t reserved;
272 uint8_t block_len[3];
273};
274
275struct scsi_log_sense
276{
277 uint8_t opcode;
278 uint8_t byte2;
279#define SLS_SP 0x01
280#define SLS_PPC 0x02
281 uint8_t page;
282#define SLS_PAGE_CODE 0x3F
283#define SLS_ALL_PAGES_PAGE 0x00
284#define SLS_OVERRUN_PAGE 0x01
285#define SLS_ERROR_WRITE_PAGE 0x02
286#define SLS_ERROR_READ_PAGE 0x03
287#define SLS_ERROR_READREVERSE_PAGE 0x04
288#define SLS_ERROR_VERIFY_PAGE 0x05
289#define SLS_ERROR_NONMEDIUM_PAGE 0x06
290#define SLS_ERROR_LASTN_PAGE 0x07
291#define SLS_PAGE_CTRL_MASK 0xC0
292#define SLS_PAGE_CTRL_THRESHOLD 0x00
293#define SLS_PAGE_CTRL_CUMULATIVE 0x40
294#define SLS_PAGE_CTRL_THRESH_DEFAULT 0x80
295#define SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0
296 uint8_t reserved[2];
297 uint8_t paramptr[2];
298 uint8_t length[2];
299 uint8_t control;
300};
301
302struct scsi_log_select
303{
304 uint8_t opcode;
305 uint8_t byte2;
306/* SLS_SP 0x01 */
307#define SLS_PCR 0x02
308 uint8_t page;
309/* SLS_PAGE_CTRL_MASK 0xC0 */
310/* SLS_PAGE_CTRL_THRESHOLD 0x00 */
311/* SLS_PAGE_CTRL_CUMULATIVE 0x40 */
312/* SLS_PAGE_CTRL_THRESH_DEFAULT 0x80 */
313/* SLS_PAGE_CTRL_CUMUL_DEFAULT 0xC0 */
314 uint8_t reserved[4];
315 uint8_t length[2];
316 uint8_t control;
317};
318
319struct scsi_log_header
320{
321 uint8_t page;
322 uint8_t reserved;
323 uint8_t datalen[2];
324};
325
326struct scsi_log_param_header {
327 uint8_t param_code[2];
328 uint8_t param_control;
329#define SLP_LP 0x01
330#define SLP_LBIN 0x02
331#define SLP_TMC_MASK 0x0C
332#define SLP_TMC_ALWAYS 0x00
333#define SLP_TMC_EQUAL 0x04
334#define SLP_TMC_NOTEQUAL 0x08
335#define SLP_TMC_GREATER 0x0C
336#define SLP_ETC 0x10
337#define SLP_TSD 0x20
338#define SLP_DS 0x40
339#define SLP_DU 0x80
340 uint8_t param_len;
341};
342
343struct scsi_control_page {
344 uint8_t page_code;
345 uint8_t page_length;
346 uint8_t rlec;
347#define SCB_RLEC 0x01 /*Report Log Exception Cond*/
348 uint8_t queue_flags;
349#define SCP_QUEUE_ALG_MASK 0xF0
350#define SCP_QUEUE_ALG_RESTRICTED 0x00
351#define SCP_QUEUE_ALG_UNRESTRICTED 0x10
352#define SCP_QUEUE_ERR 0x02 /*Queued I/O aborted for CACs*/
353#define SCP_QUEUE_DQUE 0x01 /*Queued I/O disabled*/
354 uint8_t eca_and_aen;
355#define SCP_EECA 0x80 /*Enable Extended CA*/
356#define SCP_RAENP 0x04 /*Ready AEN Permission*/
357#define SCP_UAAENP 0x02 /*UA AEN Permission*/
358#define SCP_EAENP 0x01 /*Error AEN Permission*/
359 uint8_t reserved;
360 uint8_t aen_holdoff_period[2];
361};
362
363struct scsi_reserve
364{
365 uint8_t opcode;
366 uint8_t byte2;
367 uint8_t unused[2];
368 uint8_t length;
369 uint8_t control;
370};
371
372struct scsi_release
373{
374 uint8_t opcode;
375 uint8_t byte2;
376 uint8_t unused[2];
377 uint8_t length;
378 uint8_t control;
379};
380
381struct scsi_prevent
382{
383 uint8_t opcode;
384 uint8_t byte2;
385 uint8_t unused[2];
386 uint8_t how;
387 uint8_t control;
388};
389#define PR_PREVENT 0x01
390#define PR_ALLOW 0x00
391
392struct scsi_sync_cache
393{
394 uint8_t opcode;
395 uint8_t byte2;
396 uint8_t begin_lba[4];
397 uint8_t reserved;
398 uint8_t lb_count[2];
399 uint8_t control;
400};
401
402
403struct scsi_changedef
404{
405 uint8_t opcode;
406 uint8_t byte2;
407 uint8_t unused1;
408 uint8_t how;
409 uint8_t unused[4];
410 uint8_t datalen;
411 uint8_t control;
412};
413
414struct scsi_read_buffer
415{
416 uint8_t opcode;
417 uint8_t byte2;
418#define RWB_MODE 0x07
419#define RWB_MODE_HDR_DATA 0x00
420#define RWB_MODE_DATA 0x02
421#define RWB_MODE_DOWNLOAD 0x04
422#define RWB_MODE_DOWNLOAD_SAVE 0x05
423 uint8_t buffer_id;
424 uint8_t offset[3];
425 uint8_t length[3];
426 uint8_t control;
427};
428
429struct scsi_write_buffer
430{
431 uint8_t opcode;
432 uint8_t byte2;
433 uint8_t buffer_id;
434 uint8_t offset[3];
435 uint8_t length[3];
436 uint8_t control;
437};
438
439struct scsi_rw_6
440{
441 uint8_t opcode;
442 uint8_t addr[3];
443/* only 5 bits are valid in the MSB address byte */
444#define SRW_TOPADDR 0x1F
445 uint8_t length;
446 uint8_t control;
447};
448
449struct scsi_rw_10
450{
451 uint8_t opcode;
452#define SRW10_RELADDR 0x01
453#define SRW10_FUA 0x08
454#define SRW10_DPO 0x10
455 uint8_t byte2;
456 uint8_t addr[4];
457 uint8_t reserved;
458 uint8_t length[2];
459 uint8_t control;
460};
461
462struct scsi_rw_12
463{
464 uint8_t opcode;
465#define SRW12_RELADDR 0x01
466#define SRW12_FUA 0x08
467#define SRW12_DPO 0x10
468 uint8_t byte2;
469 uint8_t addr[4];
470 uint8_t length[4];
471 uint8_t reserved;
472 uint8_t control;
473};
474
475struct scsi_start_stop_unit
476{
477 uint8_t opcode;
478 uint8_t byte2;
479#define SSS_IMMED 0x01
480 uint8_t reserved[2];
481 uint8_t how;
482#define SSS_START 0x01
483#define SSS_LOEJ 0x02
484 uint8_t control;
485};
486
487#define SC_SCSI_1 0x01
488#define SC_SCSI_2 0x03
489
490/*
491 * Opcodes
492 */
493
494#define TEST_UNIT_READY 0x00
495#define REQUEST_SENSE 0x03
496#define READ_6 0x08
497#define WRITE_6 0x0a
498#define INQUIRY 0x12
499#define MODE_SELECT_6 0x15
500#define MODE_SENSE_6 0x1a
501#define START_STOP_UNIT 0x1b
502#define START_STOP 0x1b
503#define RESERVE 0x16
504#define RELEASE 0x17
505#define RECEIVE_DIAGNOSTIC 0x1c
506#define SEND_DIAGNOSTIC 0x1d
507#define PREVENT_ALLOW 0x1e
508#define READ_CAPACITY 0x25
509#define READ_10 0x28
510#define WRITE_10 0x2a
511#define POSITION_TO_ELEMENT 0x2b
512#define SYNCHRONIZE_CACHE 0x35
513#define WRITE_BUFFER 0x3b
514#define READ_BUFFER 0x3c
515#define CHANGE_DEFINITION 0x40
516#define LOG_SELECT 0x4c
517#define LOG_SENSE 0x4d
518#ifdef XXXCAM
519#define MODE_SENSE_10 0x5A
520#endif
521#define MODE_SELECT_10 0x55
522#define MOVE_MEDIUM 0xa5
523#define READ_12 0xa8
524#define WRITE_12 0xaa
525#define READ_ELEMENT_STATUS 0xb8
526
527
528/*
529 * Device Types
530 */
531#define T_DIRECT 0x00
532#define T_SEQUENTIAL 0x01
533#define T_PRINTER 0x02
534#define T_PROCESSOR 0x03
535#define T_WORM 0x04
536#define T_CDROM 0x05
537#define T_SCANNER 0x06
538#define T_OPTICAL 0x07
539#define T_CHANGER 0x08
540#define T_COMM 0x09
541#define T_ASC0 0x0a
542#define T_ASC1 0x0b
543#define T_STORARRAY 0x0c
544#define T_ENCLOSURE 0x0d
545#define T_RBC 0x0e
546#define T_OCRW 0x0f
547#define T_NODEVICE 0x1F
548#define T_ANY 0xFF /* Used in Quirk table matches */
549
550#define T_REMOV 1
551#define T_FIXED 0
552
553/*
554 * This length is the initial inquiry length used by the probe code, as
555 * well as the legnth necessary for aic_print_inquiry() to function
556 * correctly. If either use requires a different length in the future,
557 * the two values should be de-coupled.
558 */
559#define SHORT_INQUIRY_LENGTH 36
560
561struct scsi_inquiry_data
562{
563 uint8_t device;
564#define SID_TYPE(inq_data) ((inq_data)->device & 0x1f)
565#define SID_QUAL(inq_data) (((inq_data)->device & 0xE0) >> 5)
566#define SID_QUAL_LU_CONNECTED 0x00 /*
567 * The specified peripheral device
568 * type is currently connected to
569 * logical unit. If the target cannot
570 * determine whether or not a physical
571 * device is currently connected, it
572 * shall also use this peripheral
573 * qualifier when returning the INQUIRY
574 * data. This peripheral qualifier
575 * does not mean that the device is
576 * ready for access by the initiator.
577 */
578#define SID_QUAL_LU_OFFLINE 0x01 /*
579 * The target is capable of supporting
580 * the specified peripheral device type
581 * on this logical unit; however, the
582 * physical device is not currently
583 * connected to this logical unit.
584 */
585#define SID_QUAL_RSVD 0x02
586#define SID_QUAL_BAD_LU 0x03 /*
587 * The target is not capable of
588 * supporting a physical device on
589 * this logical unit. For this
590 * peripheral qualifier the peripheral
591 * device type shall be set to 1Fh to
592 * provide compatibility with previous
593 * versions of SCSI. All other
594 * peripheral device type values are
595 * reserved for this peripheral
596 * qualifier.
597 */
598#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0)
599 uint8_t dev_qual2;
600#define SID_QUAL2 0x7F
601#define SID_IS_REMOVABLE(inq_data) (((inq_data)->dev_qual2 & 0x80) != 0)
602 uint8_t version;
603#define SID_ANSI_REV(inq_data) ((inq_data)->version & 0x07)
604#define SCSI_REV_0 0
605#define SCSI_REV_CCS 1
606#define SCSI_REV_2 2
607#define SCSI_REV_SPC 3
608#define SCSI_REV_SPC2 4
609
610#define SID_ECMA 0x38
611#define SID_ISO 0xC0
612 uint8_t response_format;
613#define SID_AENC 0x80
614#define SID_TrmIOP 0x40
615 uint8_t additional_length;
616 uint8_t reserved[2];
617 uint8_t flags;
618#define SID_SftRe 0x01
619#define SID_CmdQue 0x02
620#define SID_Linked 0x08
621#define SID_Sync 0x10
622#define SID_WBus16 0x20
623#define SID_WBus32 0x40
624#define SID_RelAdr 0x80
625#define SID_VENDOR_SIZE 8
626 char vendor[SID_VENDOR_SIZE];
627#define SID_PRODUCT_SIZE 16
628 char product[SID_PRODUCT_SIZE];
629#define SID_REVISION_SIZE 4
630 char revision[SID_REVISION_SIZE];
631 /*
632 * The following fields were taken from SCSI Primary Commands - 2
633 * (SPC-2) Revision 14, Dated 11 November 1999
634 */
635#define SID_VENDOR_SPECIFIC_0_SIZE 20
636 uint8_t vendor_specific0[SID_VENDOR_SPECIFIC_0_SIZE];
637 /*
638 * An extension of SCSI Parallel Specific Values
639 */
640#define SID_SPI_IUS 0x01
641#define SID_SPI_QAS 0x02
642#define SID_SPI_CLOCK_ST 0x00
643#define SID_SPI_CLOCK_DT 0x04
644#define SID_SPI_CLOCK_DT_ST 0x0C
645#define SID_SPI_MASK 0x0F
646 uint8_t spi3data;
647 uint8_t reserved2;
648 /*
649 * Version Descriptors, stored 2 byte values.
650 */
651 uint8_t version1[2];
652 uint8_t version2[2];
653 uint8_t version3[2];
654 uint8_t version4[2];
655 uint8_t version5[2];
656 uint8_t version6[2];
657 uint8_t version7[2];
658 uint8_t version8[2];
659
660 uint8_t reserved3[22];
661
662#define SID_VENDOR_SPECIFIC_1_SIZE 160
663 uint8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE];
664};
665
666struct scsi_vpd_unit_serial_number
667{
668 uint8_t device;
669 uint8_t page_code;
670#define SVPD_UNIT_SERIAL_NUMBER 0x80
671 uint8_t reserved;
672 uint8_t length; /* serial number length */
673#define SVPD_SERIAL_NUM_SIZE 251
674 uint8_t serial_num[SVPD_SERIAL_NUM_SIZE];
675};
676
677struct scsi_read_capacity
678{
679 uint8_t opcode;
680 uint8_t byte2;
681 uint8_t addr[4];
682 uint8_t unused[3];
683 uint8_t control;
684};
685
686struct scsi_read_capacity_data
687{
688 uint8_t addr[4];
689 uint8_t length[4];
690};
691
692struct scsi_report_luns
693{
694 uint8_t opcode;
695 uint8_t byte2;
696 uint8_t unused[3];
697 uint8_t addr[4];
698 uint8_t control;
699};
700
701struct scsi_report_luns_data {
702 uint8_t length[4]; /* length of LUN inventory, in bytes */
703 uint8_t reserved[4]; /* unused */
704 /*
705 * LUN inventory- we only support the type zero form for now.
706 */
707 struct {
708 uint8_t lundata[8];
709 } luns[1];
710};
711#define RPL_LUNDATA_ATYP_MASK 0xc0 /* MBZ for type 0 lun */
712#define RPL_LUNDATA_T0LUN 1 /* @ lundata[1] */
713
714
715struct scsi_sense_data
716{
717 uint8_t error_code;
718#define SSD_ERRCODE 0x7F
719#define SSD_CURRENT_ERROR 0x70
720#define SSD_DEFERRED_ERROR 0x71
721#define SSD_ERRCODE_VALID 0x80
722 uint8_t segment;
723 uint8_t flags;
724#define SSD_KEY 0x0F
725#define SSD_KEY_NO_SENSE 0x00
726#define SSD_KEY_RECOVERED_ERROR 0x01
727#define SSD_KEY_NOT_READY 0x02
728#define SSD_KEY_MEDIUM_ERROR 0x03
729#define SSD_KEY_HARDWARE_ERROR 0x04
730#define SSD_KEY_ILLEGAL_REQUEST 0x05
731#define SSD_KEY_UNIT_ATTENTION 0x06
732#define SSD_KEY_DATA_PROTECT 0x07
733#define SSD_KEY_BLANK_CHECK 0x08
734#define SSD_KEY_Vendor_Specific 0x09
735#define SSD_KEY_COPY_ABORTED 0x0a
736#define SSD_KEY_ABORTED_COMMAND 0x0b
737#define SSD_KEY_EQUAL 0x0c
738#define SSD_KEY_VOLUME_OVERFLOW 0x0d
739#define SSD_KEY_MISCOMPARE 0x0e
740#define SSD_KEY_RESERVED 0x0f
741#define SSD_ILI 0x20
742#define SSD_EOM 0x40
743#define SSD_FILEMARK 0x80
744 uint8_t info[4];
745 uint8_t extra_len;
746 uint8_t cmd_spec_info[4];
747 uint8_t add_sense_code;
748 uint8_t add_sense_code_qual;
749 uint8_t fru;
750 uint8_t sense_key_spec[3];
751#define SSD_SCS_VALID 0x80
752#define SSD_FIELDPTR_CMD 0x40
753#define SSD_BITPTR_VALID 0x08
754#define SSD_BITPTR_VALUE 0x07
755#define SSD_MIN_SIZE 18
756 uint8_t extra_bytes[14];
757#define SSD_FULL_SIZE sizeof(struct scsi_sense_data)
758};
759
760struct scsi_mode_header_6
761{
762 uint8_t data_length; /* Sense data length */
763 uint8_t medium_type;
764 uint8_t dev_spec;
765 uint8_t blk_desc_len;
766};
767
768struct scsi_mode_header_10
769{
770 uint8_t data_length[2];/* Sense data length */
771 uint8_t medium_type;
772 uint8_t dev_spec;
773 uint8_t unused[2];
774 uint8_t blk_desc_len[2];
775};
776
777struct scsi_mode_page_header
778{
779 uint8_t page_code;
780 uint8_t page_length;
781};
782
783struct scsi_mode_blk_desc
784{
785 uint8_t density;
786 uint8_t nblocks[3];
787 uint8_t reserved;
788 uint8_t blklen[3];
789};
790
791#define SCSI_DEFAULT_DENSITY 0x00 /* use 'default' density */
792#define SCSI_SAME_DENSITY 0x7f /* use 'same' density- >= SCSI-2 only */
793
794
795/*
796 * Status Byte
797 */
798#define SCSI_STATUS_OK 0x00
799#define SCSI_STATUS_CHECK_COND 0x02
800#define SCSI_STATUS_COND_MET 0x04
801#define SCSI_STATUS_BUSY 0x08
802#define SCSI_STATUS_INTERMED 0x10
803#define SCSI_STATUS_INTERMED_COND_MET 0x14
804#define SCSI_STATUS_RESERV_CONFLICT 0x18
805#define SCSI_STATUS_CMD_TERMINATED 0x22 /* Obsolete in SAM-2 */
806#define SCSI_STATUS_QUEUE_FULL 0x28
807#define SCSI_STATUS_ACA_ACTIVE 0x30
808#define SCSI_STATUS_TASK_ABORTED 0x40
809
810struct scsi_inquiry_pattern {
811 uint8_t type;
812 uint8_t media_type;
813#define SIP_MEDIA_REMOVABLE 0x01
814#define SIP_MEDIA_FIXED 0x02
815 const char *vendor;
816 const char *product;
817 const char *revision;
818};
819
820struct scsi_static_inquiry_pattern {
821 uint8_t type;
822 uint8_t media_type;
823 char vendor[SID_VENDOR_SIZE+1];
824 char product[SID_PRODUCT_SIZE+1];
825 char revision[SID_REVISION_SIZE+1];
826};
827
828struct scsi_sense_quirk_entry {
829 struct scsi_inquiry_pattern inq_pat;
830 int num_sense_keys;
831 int num_ascs;
832 struct sense_key_table_entry *sense_key_info;
833 struct asc_table_entry *asc_info;
834};
835
836struct sense_key_table_entry {
837 uint8_t sense_key;
838 uint32_t action;
839 const char *desc;
840};
841
842struct asc_table_entry {
843 uint8_t asc;
844 uint8_t ascq;
845 uint32_t action;
846 const char *desc;
847};
848
849struct op_table_entry {
850 uint8_t opcode;
851 uint16_t opmask;
852 const char *desc;
853};
854
855struct scsi_op_quirk_entry {
856 struct scsi_inquiry_pattern inq_pat;
857 int num_ops;
858 struct op_table_entry *op_table;
859};
860
861typedef enum {
862 SSS_FLAG_NONE = 0x00,
863 SSS_FLAG_PRINT_COMMAND = 0x01
864} scsi_sense_string_flags;
865
866extern const char *scsi_sense_key_text[];
867
868/************************* Large Disk Handling ********************************/
869#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
870static __inline int aic_sector_div(u_long capacity, int heads, int sectors);
871
872static __inline int
873aic_sector_div(u_long capacity, int heads, int sectors)
874{
875 return (capacity / (heads * sectors));
876}
877#else
878static __inline int aic_sector_div(sector_t capacity, int heads, int sectors);
879
880static __inline int
881aic_sector_div(sector_t capacity, int heads, int sectors)
882{
883 /* ugly, ugly sector_div calling convention.. */
884 sector_div(capacity, (heads * sectors));
885 return (int)capacity;
886}
887#endif
888
889/**************************** Module Library Hack *****************************/
890/*
891 * What we'd like to do is have a single "scsi library" module that both the
892 * aic7xxx and aic79xx drivers could load and depend on. A cursory examination
893 * of implementing module dependencies in Linux (handling the install and
894 * initrd cases) does not look promissing. For now, we just duplicate this
895 * code in both drivers using a simple symbol renaming scheme that hides this
896 * hack from the drivers.
897 */
898#define AIC_LIB_ENTRY_CONCAT(x, prefix) prefix ## x
899#define AIC_LIB_ENTRY_EXPAND(x, prefix) AIC_LIB_ENTRY_CONCAT(x, prefix)
900#define AIC_LIB_ENTRY(x) AIC_LIB_ENTRY_EXPAND(x, AIC_LIB_PREFIX)
901
902#define aic_sense_desc AIC_LIB_ENTRY(_sense_desc)
903#define aic_sense_error_action AIC_LIB_ENTRY(_sense_error_action)
904#define aic_error_action AIC_LIB_ENTRY(_error_action)
905#define aic_op_desc AIC_LIB_ENTRY(_op_desc)
906#define aic_cdb_string AIC_LIB_ENTRY(_cdb_string)
907#define aic_print_inquiry AIC_LIB_ENTRY(_print_inquiry)
908#define aic_calc_syncsrate AIC_LIB_ENTRY(_calc_syncrate)
909#define aic_calc_syncparam AIC_LIB_ENTRY(_calc_syncparam)
910#define aic_calc_speed AIC_LIB_ENTRY(_calc_speed)
911#define aic_inquiry_match AIC_LIB_ENTRY(_inquiry_match)
912#define aic_static_inquiry_match AIC_LIB_ENTRY(_static_inquiry_match)
913#define aic_parse_brace_option AIC_LIB_ENTRY(_parse_brace_option)
914
915/******************************************************************************/
916
917void aic_sense_desc(int /*sense_key*/, int /*asc*/,
918 int /*ascq*/, struct scsi_inquiry_data*,
919 const char** /*sense_key_desc*/,
920 const char** /*asc_desc*/);
921aic_sense_action aic_sense_error_action(struct scsi_sense_data*,
922 struct scsi_inquiry_data*,
923 uint32_t /*sense_flags*/);
924uint32_t aic_error_action(struct scsi_cmnd *,
925 struct scsi_inquiry_data *,
926 cam_status, u_int);
927
928#define SF_RETRY_UA 0x01
929#define SF_NO_PRINT 0x02
930#define SF_QUIET_IR 0x04 /* Be quiet about Illegal Request reponses */
931#define SF_PRINT_ALWAYS 0x08
932
933
934const char * aic_op_desc(uint16_t /*opcode*/, struct scsi_inquiry_data*);
935char * aic_cdb_string(uint8_t* /*cdb_ptr*/, char* /*cdb_string*/,
936 size_t /*len*/);
937void aic_print_inquiry(struct scsi_inquiry_data*);
938
939u_int aic_calc_syncsrate(u_int /*period_factor*/);
940u_int aic_calc_syncparam(u_int /*period*/);
941u_int aic_calc_speed(u_int width, u_int period, u_int offset,
942 u_int min_rate);
943
944int aic_inquiry_match(caddr_t /*inqbuffer*/,
945 caddr_t /*table_entry*/);
946int aic_static_inquiry_match(caddr_t /*inqbuffer*/,
947 caddr_t /*table_entry*/);
948
949typedef void aic_option_callback_t(u_long, int, int, int32_t);
950char * aic_parse_brace_option(char *opt_name, char *opt_arg,
951 char *end, int depth,
952 aic_option_callback_t *, u_long);
953
954static __inline void scsi_extract_sense(struct scsi_sense_data *sense,
955 int *error_code, int *sense_key,
956 int *asc, int *ascq);
957static __inline void scsi_ulto2b(uint32_t val, uint8_t *bytes);
958static __inline void scsi_ulto3b(uint32_t val, uint8_t *bytes);
959static __inline void scsi_ulto4b(uint32_t val, uint8_t *bytes);
960static __inline uint32_t scsi_2btoul(uint8_t *bytes);
961static __inline uint32_t scsi_3btoul(uint8_t *bytes);
962static __inline int32_t scsi_3btol(uint8_t *bytes);
963static __inline uint32_t scsi_4btoul(uint8_t *bytes);
964
965static __inline void scsi_extract_sense(struct scsi_sense_data *sense,
966 int *error_code, int *sense_key,
967 int *asc, int *ascq)
968{
969 *error_code = sense->error_code & SSD_ERRCODE;
970 *sense_key = sense->flags & SSD_KEY;
971 *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0;
972 *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0;
973}
974
975static __inline void
976scsi_ulto2b(uint32_t val, uint8_t *bytes)
977{
978
979 bytes[0] = (val >> 8) & 0xff;
980 bytes[1] = val & 0xff;
981}
982
983static __inline void
984scsi_ulto3b(uint32_t val, uint8_t *bytes)
985{
986
987 bytes[0] = (val >> 16) & 0xff;
988 bytes[1] = (val >> 8) & 0xff;
989 bytes[2] = val & 0xff;
990}
991
992static __inline void
993scsi_ulto4b(uint32_t val, uint8_t *bytes)
994{
995
996 bytes[0] = (val >> 24) & 0xff;
997 bytes[1] = (val >> 16) & 0xff;
998 bytes[2] = (val >> 8) & 0xff;
999 bytes[3] = val & 0xff;
1000}
1001
1002static __inline uint32_t
1003scsi_2btoul(uint8_t *bytes)
1004{
1005 uint32_t rv;
1006
1007 rv = (bytes[0] << 8) |
1008 bytes[1];
1009 return (rv);
1010}
1011
1012static __inline uint32_t
1013scsi_3btoul(uint8_t *bytes)
1014{
1015 uint32_t rv;
1016
1017 rv = (bytes[0] << 16) |
1018 (bytes[1] << 8) |
1019 bytes[2];
1020 return (rv);
1021}
1022
1023static __inline int32_t
1024scsi_3btol(uint8_t *bytes)
1025{
1026 uint32_t rc = scsi_3btoul(bytes);
1027
1028 if (rc & 0x00800000)
1029 rc |= 0xff000000;
1030
1031 return (int32_t) rc;
1032}
1033
1034static __inline uint32_t
1035scsi_4btoul(uint8_t *bytes)
1036{
1037 uint32_t rv;
1038
1039 rv = (bytes[0] << 24) |
1040 (bytes[1] << 16) |
1041 (bytes[2] << 8) |
1042 bytes[3];
1043 return (rv);
1044}
1045
1046/* Macros for generating the elements of the PCI ID tables. */
1047
1048#define GETID(v, s) (unsigned)(((v) >> (s)) & 0xFFFF ?: PCI_ANY_ID)
1049
1050#define ID_C(x, c) \
1051{ \
1052 GETID(x,32), GETID(x,48), GETID(x,0), GETID(x,16), \
1053 (c) << 8, 0xFFFF00, 0 \
1054}
1055
1056#define ID2C(x) \
1057 ID_C(x, PCI_CLASS_STORAGE_SCSI), \
1058 ID_C(x, PCI_CLASS_STORAGE_RAID)
1059
1060#define IDIROC(x) ((x) | ~ID_ALL_IROC_MASK)
1061
1062/* Generate IDs for all 16 possibilites.
1063 * The argument has already masked out
1064 * the 4 least significant bits of the device id.
1065 * (e.g., mask: ID_9005_GENERIC_MASK).
1066 */
1067#define ID16(x) \
1068 ID(x), \
1069 ID((x) | 0x0001000000000000ull), \
1070 ID((x) | 0x0002000000000000ull), \
1071 ID((x) | 0x0003000000000000ull), \
1072 ID((x) | 0x0004000000000000ull), \
1073 ID((x) | 0x0005000000000000ull), \
1074 ID((x) | 0x0006000000000000ull), \
1075 ID((x) | 0x0007000000000000ull), \
1076 ID((x) | 0x0008000000000000ull), \
1077 ID((x) | 0x0009000000000000ull), \
1078 ID((x) | 0x000A000000000000ull), \
1079 ID((x) | 0x000B000000000000ull), \
1080 ID((x) | 0x000C000000000000ull), \
1081 ID((x) | 0x000D000000000000ull), \
1082 ID((x) | 0x000E000000000000ull), \
1083 ID((x) | 0x000F000000000000ull)
1084
1085#endif /*_AICLIB_H */
diff --git a/drivers/scsi/aic7xxx/cam.h b/drivers/scsi/aic7xxx/cam.h
new file mode 100644
index 000000000000..d40ba0760c76
--- /dev/null
+++ b/drivers/scsi/aic7xxx/cam.h
@@ -0,0 +1,111 @@
1/*
2 * Data structures and definitions for the CAM system.
3 *
4 * Copyright (c) 1997 Justin T. Gibbs.
5 * Copyright (c) 2000 Adaptec Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL").
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/cam.h#15 $
33 */
34
35#ifndef _AIC7XXX_CAM_H
36#define _AIC7XXX_CAM_H 1
37
38#include <linux/types.h>
39
40#define CAM_BUS_WILDCARD ((u_int)~0)
41#define CAM_TARGET_WILDCARD ((u_int)~0)
42#define CAM_LUN_WILDCARD ((u_int)~0)
43
44/* CAM Status field values */
45typedef enum {
46 CAM_REQ_INPROG, /* CCB request is in progress */
47 CAM_REQ_CMP, /* CCB request completed without error */
48 CAM_REQ_ABORTED, /* CCB request aborted by the host */
49 CAM_UA_ABORT, /* Unable to abort CCB request */
50 CAM_REQ_CMP_ERR, /* CCB request completed with an error */
51 CAM_BUSY, /* CAM subsytem is busy */
52 CAM_REQ_INVALID, /* CCB request was invalid */
53 CAM_PATH_INVALID, /* Supplied Path ID is invalid */
54 CAM_SEL_TIMEOUT, /* Target Selection Timeout */
55 CAM_CMD_TIMEOUT, /* Command timeout */
56 CAM_SCSI_STATUS_ERROR, /* SCSI error, look at error code in CCB */
57 CAM_SCSI_BUS_RESET, /* SCSI Bus Reset Sent/Received */
58 CAM_UNCOR_PARITY, /* Uncorrectable parity error occurred */
59 CAM_AUTOSENSE_FAIL, /* Autosense: request sense cmd fail */
60 CAM_NO_HBA, /* No HBA Detected Error */
61 CAM_DATA_RUN_ERR, /* Data Overrun error */
62 CAM_UNEXP_BUSFREE, /* Unexpected Bus Free */
63 CAM_SEQUENCE_FAIL, /* Protocol Violation */
64 CAM_CCB_LEN_ERR, /* CCB length supplied is inadequate */
65 CAM_PROVIDE_FAIL, /* Unable to provide requested capability */
66 CAM_BDR_SENT, /* A SCSI BDR msg was sent to target */
67 CAM_REQ_TERMIO, /* CCB request terminated by the host */
68 CAM_UNREC_HBA_ERROR, /* Unrecoverable Host Bus Adapter Error */
69 CAM_REQ_TOO_BIG, /* The request was too large for this host */
70 CAM_UA_TERMIO, /* Unable to terminate I/O CCB request */
71 CAM_MSG_REJECT_REC, /* Message Reject Received */
72 CAM_DEV_NOT_THERE, /* SCSI Device Not Installed/there */
73 CAM_RESRC_UNAVAIL, /* Resource Unavailable */
74 /*
75 * This request should be requeued to preserve
76 * transaction ordering. This typically occurs
77 * when the SIM recognizes an error that should
78 * freeze the queue and must place additional
79 * requests for the target at the sim level
80 * back into the XPT queue.
81 */
82 CAM_REQUEUE_REQ,
83 CAM_DEV_QFRZN = 0x40,
84
85 CAM_STATUS_MASK = 0x3F
86} cam_status;
87
88/*
89 * Definitions for the asynchronous callback CCB fields.
90 */
91typedef enum {
92 AC_GETDEV_CHANGED = 0x800,/* Getdev info might have changed */
93 AC_INQ_CHANGED = 0x400,/* Inquiry info might have changed */
94 AC_TRANSFER_NEG = 0x200,/* New transfer settings in effect */
95 AC_LOST_DEVICE = 0x100,/* A device went away */
96 AC_FOUND_DEVICE = 0x080,/* A new device was found */
97 AC_PATH_DEREGISTERED = 0x040,/* A path has de-registered */
98 AC_PATH_REGISTERED = 0x020,/* A new path has been registered */
99 AC_SENT_BDR = 0x010,/* A BDR message was sent to target */
100 AC_SCSI_AEN = 0x008,/* A SCSI AEN has been received */
101 AC_UNSOL_RESEL = 0x002,/* Unsolicited reselection occurred */
102 AC_BUS_RESET = 0x001 /* A SCSI bus reset occurred */
103} ac_code;
104
105typedef enum {
106 CAM_DIR_IN = SCSI_DATA_READ,
107 CAM_DIR_OUT = SCSI_DATA_WRITE,
108 CAM_DIR_NONE = SCSI_DATA_NONE
109} ccb_flags;
110
111#endif /* _AIC7XXX_CAM_H */
diff --git a/drivers/scsi/aic7xxx/queue.h b/drivers/scsi/aic7xxx/queue.h
new file mode 100644
index 000000000000..8adf8003a164
--- /dev/null
+++ b/drivers/scsi/aic7xxx/queue.h
@@ -0,0 +1,501 @@
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * @(#)queue.h 8.5 (Berkeley) 8/20/94
27 * $FreeBSD: src/sys/sys/queue.h,v 1.38 2000/05/26 02:06:56 jake Exp $
28 */
29
30#ifndef _SYS_QUEUE_H_
31#define _SYS_QUEUE_H_
32
33/*
34 * This file defines five types of data structures: singly-linked lists,
35 * singly-linked tail queues, lists, tail queues, and circular queues.
36 *
37 * A singly-linked list is headed by a single forward pointer. The elements
38 * are singly linked for minimum space and pointer manipulation overhead at
39 * the expense of O(n) removal for arbitrary elements. New elements can be
40 * added to the list after an existing element or at the head of the list.
41 * Elements being removed from the head of the list should use the explicit
42 * macro for this purpose for optimum efficiency. A singly-linked list may
43 * only be traversed in the forward direction. Singly-linked lists are ideal
44 * for applications with large datasets and few or no removals or for
45 * implementing a LIFO queue.
46 *
47 * A singly-linked tail queue is headed by a pair of pointers, one to the
48 * head of the list and the other to the tail of the list. The elements are
49 * singly linked for minimum space and pointer manipulation overhead at the
50 * expense of O(n) removal for arbitrary elements. New elements can be added
51 * to the list after an existing element, at the head of the list, or at the
52 * end of the list. Elements being removed from the head of the tail queue
53 * should use the explicit macro for this purpose for optimum efficiency.
54 * A singly-linked tail queue may only be traversed in the forward direction.
55 * Singly-linked tail queues are ideal for applications with large datasets
56 * and few or no removals or for implementing a FIFO queue.
57 *
58 * A list is headed by a single forward pointer (or an array of forward
59 * pointers for a hash table header). The elements are doubly linked
60 * so that an arbitrary element can be removed without a need to
61 * traverse the list. New elements can be added to the list before
62 * or after an existing element or at the head of the list. A list
63 * may only be traversed in the forward direction.
64 *
65 * A tail queue is headed by a pair of pointers, one to the head of the
66 * list and the other to the tail of the list. The elements are doubly
67 * linked so that an arbitrary element can be removed without a need to
68 * traverse the list. New elements can be added to the list before or
69 * after an existing element, at the head of the list, or at the end of
70 * the list. A tail queue may be traversed in either direction.
71 *
72 * A circle queue is headed by a pair of pointers, one to the head of the
73 * list and the other to the tail of the list. The elements are doubly
74 * linked so that an arbitrary element can be removed without a need to
75 * traverse the list. New elements can be added to the list before or after
76 * an existing element, at the head of the list, or at the end of the list.
77 * A circle queue may be traversed in either direction, but has a more
78 * complex end of list detection.
79 *
80 * For details on the use of these macros, see the queue(3) manual page.
81 *
82 *
83 * SLIST LIST STAILQ TAILQ CIRCLEQ
84 * _HEAD + + + + +
85 * _HEAD_INITIALIZER + + + + +
86 * _ENTRY + + + + +
87 * _INIT + + + + +
88 * _EMPTY + + + + +
89 * _FIRST + + + + +
90 * _NEXT + + + + +
91 * _PREV - - - + +
92 * _LAST - - + + +
93 * _FOREACH + + + + +
94 * _FOREACH_REVERSE - - - + +
95 * _INSERT_HEAD + + + + +
96 * _INSERT_BEFORE - + - + +
97 * _INSERT_AFTER + + + + +
98 * _INSERT_TAIL - - + + +
99 * _REMOVE_HEAD + - + - -
100 * _REMOVE + + + + +
101 *
102 */
103
104/*
105 * Singly-linked List declarations.
106 */
107#define SLIST_HEAD(name, type) \
108struct name { \
109 struct type *slh_first; /* first element */ \
110}
111
112#define SLIST_HEAD_INITIALIZER(head) \
113 { NULL }
114
115#define SLIST_ENTRY(type) \
116struct { \
117 struct type *sle_next; /* next element */ \
118}
119
120/*
121 * Singly-linked List functions.
122 */
123#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
124
125#define SLIST_FIRST(head) ((head)->slh_first)
126
127#define SLIST_FOREACH(var, head, field) \
128 for ((var) = SLIST_FIRST((head)); \
129 (var); \
130 (var) = SLIST_NEXT((var), field))
131
132#define SLIST_INIT(head) do { \
133 SLIST_FIRST((head)) = NULL; \
134} while (0)
135
136#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
137 SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
138 SLIST_NEXT((slistelm), field) = (elm); \
139} while (0)
140
141#define SLIST_INSERT_HEAD(head, elm, field) do { \
142 SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
143 SLIST_FIRST((head)) = (elm); \
144} while (0)
145
146#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
147
148#define SLIST_REMOVE(head, elm, type, field) do { \
149 if (SLIST_FIRST((head)) == (elm)) { \
150 SLIST_REMOVE_HEAD((head), field); \
151 } \
152 else { \
153 struct type *curelm = SLIST_FIRST((head)); \
154 while (SLIST_NEXT(curelm, field) != (elm)) \
155 curelm = SLIST_NEXT(curelm, field); \
156 SLIST_NEXT(curelm, field) = \
157 SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
158 } \
159} while (0)
160
161#define SLIST_REMOVE_HEAD(head, field) do { \
162 SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
163} while (0)
164
165/*
166 * Singly-linked Tail queue declarations.
167 */
168#define STAILQ_HEAD(name, type) \
169struct name { \
170 struct type *stqh_first;/* first element */ \
171 struct type **stqh_last;/* addr of last next element */ \
172}
173
174#define STAILQ_HEAD_INITIALIZER(head) \
175 { NULL, &(head).stqh_first }
176
177#define STAILQ_ENTRY(type) \
178struct { \
179 struct type *stqe_next; /* next element */ \
180}
181
182/*
183 * Singly-linked Tail queue functions.
184 */
185#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
186
187#define STAILQ_FIRST(head) ((head)->stqh_first)
188
189#define STAILQ_FOREACH(var, head, field) \
190 for((var) = STAILQ_FIRST((head)); \
191 (var); \
192 (var) = STAILQ_NEXT((var), field))
193
194#define STAILQ_INIT(head) do { \
195 STAILQ_FIRST((head)) = NULL; \
196 (head)->stqh_last = &STAILQ_FIRST((head)); \
197} while (0)
198
199#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
200 if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
201 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
202 STAILQ_NEXT((tqelm), field) = (elm); \
203} while (0)
204
205#define STAILQ_INSERT_HEAD(head, elm, field) do { \
206 if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
207 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
208 STAILQ_FIRST((head)) = (elm); \
209} while (0)
210
211#define STAILQ_INSERT_TAIL(head, elm, field) do { \
212 STAILQ_NEXT((elm), field) = NULL; \
213 STAILQ_LAST((head)) = (elm); \
214 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
215} while (0)
216
217#define STAILQ_LAST(head) (*(head)->stqh_last)
218
219#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
220
221#define STAILQ_REMOVE(head, elm, type, field) do { \
222 if (STAILQ_FIRST((head)) == (elm)) { \
223 STAILQ_REMOVE_HEAD(head, field); \
224 } \
225 else { \
226 struct type *curelm = STAILQ_FIRST((head)); \
227 while (STAILQ_NEXT(curelm, field) != (elm)) \
228 curelm = STAILQ_NEXT(curelm, field); \
229 if ((STAILQ_NEXT(curelm, field) = \
230 STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
231 (head)->stqh_last = &STAILQ_NEXT((curelm), field);\
232 } \
233} while (0)
234
235#define STAILQ_REMOVE_HEAD(head, field) do { \
236 if ((STAILQ_FIRST((head)) = \
237 STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
238 (head)->stqh_last = &STAILQ_FIRST((head)); \
239} while (0)
240
241#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
242 if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
243 (head)->stqh_last = &STAILQ_FIRST((head)); \
244} while (0)
245
246/*
247 * List declarations.
248 */
249#define LIST_HEAD(name, type) \
250struct name { \
251 struct type *lh_first; /* first element */ \
252}
253
254#define LIST_HEAD_INITIALIZER(head) \
255 { NULL }
256
257#define LIST_ENTRY(type) \
258struct { \
259 struct type *le_next; /* next element */ \
260 struct type **le_prev; /* address of previous next element */ \
261}
262
263/*
264 * List functions.
265 */
266
267#define LIST_EMPTY(head) ((head)->lh_first == NULL)
268
269#define LIST_FIRST(head) ((head)->lh_first)
270
271#define LIST_FOREACH(var, head, field) \
272 for ((var) = LIST_FIRST((head)); \
273 (var); \
274 (var) = LIST_NEXT((var), field))
275
276#define LIST_INIT(head) do { \
277 LIST_FIRST((head)) = NULL; \
278} while (0)
279
280#define LIST_INSERT_AFTER(listelm, elm, field) do { \
281 if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
282 LIST_NEXT((listelm), field)->field.le_prev = \
283 &LIST_NEXT((elm), field); \
284 LIST_NEXT((listelm), field) = (elm); \
285 (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
286} while (0)
287
288#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
289 (elm)->field.le_prev = (listelm)->field.le_prev; \
290 LIST_NEXT((elm), field) = (listelm); \
291 *(listelm)->field.le_prev = (elm); \
292 (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
293} while (0)
294
295#define LIST_INSERT_HEAD(head, elm, field) do { \
296 if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
297 LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
298 LIST_FIRST((head)) = (elm); \
299 (elm)->field.le_prev = &LIST_FIRST((head)); \
300} while (0)
301
302#define LIST_NEXT(elm, field) ((elm)->field.le_next)
303
304#define LIST_REMOVE(elm, field) do { \
305 if (LIST_NEXT((elm), field) != NULL) \
306 LIST_NEXT((elm), field)->field.le_prev = \
307 (elm)->field.le_prev; \
308 *(elm)->field.le_prev = LIST_NEXT((elm), field); \
309} while (0)
310
311/*
312 * Tail queue declarations.
313 */
314#define TAILQ_HEAD(name, type) \
315struct name { \
316 struct type *tqh_first; /* first element */ \
317 struct type **tqh_last; /* addr of last next element */ \
318}
319
320#define TAILQ_HEAD_INITIALIZER(head) \
321 { NULL, &(head).tqh_first }
322
323#define TAILQ_ENTRY(type) \
324struct { \
325 struct type *tqe_next; /* next element */ \
326 struct type **tqe_prev; /* address of previous next element */ \
327}
328
329/*
330 * Tail queue functions.
331 */
332#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
333
334#define TAILQ_FIRST(head) ((head)->tqh_first)
335
336#define TAILQ_FOREACH(var, head, field) \
337 for ((var) = TAILQ_FIRST((head)); \
338 (var); \
339 (var) = TAILQ_NEXT((var), field))
340
341#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
342 for ((var) = TAILQ_LAST((head), headname); \
343 (var); \
344 (var) = TAILQ_PREV((var), headname, field))
345
346#define TAILQ_INIT(head) do { \
347 TAILQ_FIRST((head)) = NULL; \
348 (head)->tqh_last = &TAILQ_FIRST((head)); \
349} while (0)
350
351#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
352 if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
353 TAILQ_NEXT((elm), field)->field.tqe_prev = \
354 &TAILQ_NEXT((elm), field); \
355 else \
356 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
357 TAILQ_NEXT((listelm), field) = (elm); \
358 (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
359} while (0)
360
361#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
362 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
363 TAILQ_NEXT((elm), field) = (listelm); \
364 *(listelm)->field.tqe_prev = (elm); \
365 (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
366} while (0)
367
368#define TAILQ_INSERT_HEAD(head, elm, field) do { \
369 if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
370 TAILQ_FIRST((head))->field.tqe_prev = \
371 &TAILQ_NEXT((elm), field); \
372 else \
373 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
374 TAILQ_FIRST((head)) = (elm); \
375 (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
376} while (0)
377
378#define TAILQ_INSERT_TAIL(head, elm, field) do { \
379 TAILQ_NEXT((elm), field) = NULL; \
380 (elm)->field.tqe_prev = (head)->tqh_last; \
381 *(head)->tqh_last = (elm); \
382 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
383} while (0)
384
385#define TAILQ_LAST(head, headname) \
386 (*(((struct headname *)((head)->tqh_last))->tqh_last))
387
388#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
389
390#define TAILQ_PREV(elm, headname, field) \
391 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
392
393#define TAILQ_REMOVE(head, elm, field) do { \
394 if ((TAILQ_NEXT((elm), field)) != NULL) \
395 TAILQ_NEXT((elm), field)->field.tqe_prev = \
396 (elm)->field.tqe_prev; \
397 else \
398 (head)->tqh_last = (elm)->field.tqe_prev; \
399 *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
400} while (0)
401
402/*
403 * Circular queue declarations.
404 */
405#define CIRCLEQ_HEAD(name, type) \
406struct name { \
407 struct type *cqh_first; /* first element */ \
408 struct type *cqh_last; /* last element */ \
409}
410
411#define CIRCLEQ_HEAD_INITIALIZER(head) \
412 { (void *)&(head), (void *)&(head) }
413
414#define CIRCLEQ_ENTRY(type) \
415struct { \
416 struct type *cqe_next; /* next element */ \
417 struct type *cqe_prev; /* previous element */ \
418}
419
420/*
421 * Circular queue functions.
422 */
423#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
424
425#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
426
427#define CIRCLEQ_FOREACH(var, head, field) \
428 for ((var) = CIRCLEQ_FIRST((head)); \
429 (var) != (void *)(head); \
430 (var) = CIRCLEQ_NEXT((var), field))
431
432#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
433 for ((var) = CIRCLEQ_LAST((head)); \
434 (var) != (void *)(head); \
435 (var) = CIRCLEQ_PREV((var), field))
436
437#define CIRCLEQ_INIT(head) do { \
438 CIRCLEQ_FIRST((head)) = (void *)(head); \
439 CIRCLEQ_LAST((head)) = (void *)(head); \
440} while (0)
441
442#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
443 CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \
444 CIRCLEQ_PREV((elm), field) = (listelm); \
445 if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \
446 CIRCLEQ_LAST((head)) = (elm); \
447 else \
448 CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\
449 CIRCLEQ_NEXT((listelm), field) = (elm); \
450} while (0)
451
452#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
453 CIRCLEQ_NEXT((elm), field) = (listelm); \
454 CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \
455 if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \
456 CIRCLEQ_FIRST((head)) = (elm); \
457 else \
458 CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\
459 CIRCLEQ_PREV((listelm), field) = (elm); \
460} while (0)
461
462#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
463 CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \
464 CIRCLEQ_PREV((elm), field) = (void *)(head); \
465 if (CIRCLEQ_LAST((head)) == (void *)(head)) \
466 CIRCLEQ_LAST((head)) = (elm); \
467 else \
468 CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \
469 CIRCLEQ_FIRST((head)) = (elm); \
470} while (0)
471
472#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
473 CIRCLEQ_NEXT((elm), field) = (void *)(head); \
474 CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \
475 if (CIRCLEQ_FIRST((head)) == (void *)(head)) \
476 CIRCLEQ_FIRST((head)) = (elm); \
477 else \
478 CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \
479 CIRCLEQ_LAST((head)) = (elm); \
480} while (0)
481
482#define CIRCLEQ_LAST(head) ((head)->cqh_last)
483
484#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
485
486#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
487
488#define CIRCLEQ_REMOVE(head, elm, field) do { \
489 if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \
490 CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \
491 else \
492 CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \
493 CIRCLEQ_PREV((elm), field); \
494 if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \
495 CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \
496 else \
497 CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \
498 CIRCLEQ_NEXT((elm), field); \
499} while (0)
500
501#endif /* !_SYS_QUEUE_H_ */
diff --git a/drivers/scsi/aic7xxx/scsi_iu.h b/drivers/scsi/aic7xxx/scsi_iu.h
new file mode 100644
index 000000000000..0eafd3c17730
--- /dev/null
+++ b/drivers/scsi/aic7xxx/scsi_iu.h
@@ -0,0 +1,39 @@
1/*
2 * This file is in the public domain.
3 */
4#ifndef _SCSI_SCSI_IU_H
5#define _SCSI_SCSI_IU_H 1
6
7struct scsi_status_iu_header
8{
9 u_int8_t reserved[2];
10 u_int8_t flags;
11#define SIU_SNSVALID 0x2
12#define SIU_RSPVALID 0x1
13 u_int8_t status;
14 u_int8_t sense_length[4];
15 u_int8_t pkt_failures_length[4];
16 u_int8_t pkt_failures[1];
17};
18
19#define SIU_PKTFAIL_OFFSET(siu) 12
20#define SIU_PKTFAIL_CODE(siu) (scsi_4btoul((siu)->pkt_failures) & 0xFF)
21#define SIU_PFC_NONE 0
22#define SIU_PFC_CIU_FIELDS_INVALID 2
23#define SIU_PFC_TMF_NOT_SUPPORTED 4
24#define SIU_PFC_TMF_FAILED 5
25#define SIU_PFC_INVALID_TYPE_CODE 6
26#define SIU_PFC_ILLEGAL_REQUEST 7
27#define SIU_SENSE_OFFSET(siu) \
28 (12 + (((siu)->flags & SIU_RSPVALID) \
29 ? scsi_4btoul((siu)->pkt_failures_length) \
30 : 0))
31
32#define SIU_TASKMGMT_NONE 0x00
33#define SIU_TASKMGMT_ABORT_TASK 0x01
34#define SIU_TASKMGMT_ABORT_TASK_SET 0x02
35#define SIU_TASKMGMT_CLEAR_TASK_SET 0x04
36#define SIU_TASKMGMT_LUN_RESET 0x08
37#define SIU_TASKMGMT_TARGET_RESET 0x20
38#define SIU_TASKMGMT_CLEAR_ACA 0x40
39#endif /*_SCSI_SCSI_IU_H*/
diff --git a/drivers/scsi/aic7xxx/scsi_message.h b/drivers/scsi/aic7xxx/scsi_message.h
new file mode 100644
index 000000000000..75811e245ec7
--- /dev/null
+++ b/drivers/scsi/aic7xxx/scsi_message.h
@@ -0,0 +1,70 @@
1/*
2 * This file is in the public domain.
3 * $FreeBSD: src/sys/cam/scsi/scsi_message.h,v 1.2 2000/05/01 20:21:29 peter Exp $
4 */
5
6/* Messages (1 byte) */ /* I/T (M)andatory or (O)ptional */
7#define MSG_CMDCOMPLETE 0x00 /* M/M */
8#define MSG_TASK_COMPLETE 0x00 /* M/M */ /* SPI3 Terminology */
9#define MSG_EXTENDED 0x01 /* O/O */
10#define MSG_SAVEDATAPOINTER 0x02 /* O/O */
11#define MSG_RESTOREPOINTERS 0x03 /* O/O */
12#define MSG_DISCONNECT 0x04 /* O/O */
13#define MSG_INITIATOR_DET_ERR 0x05 /* M/M */
14#define MSG_ABORT 0x06 /* O/M */
15#define MSG_ABORT_TASK_SET 0x06 /* O/M */ /* SPI3 Terminology */
16#define MSG_MESSAGE_REJECT 0x07 /* M/M */
17#define MSG_NOOP 0x08 /* M/M */
18#define MSG_PARITY_ERROR 0x09 /* M/M */
19#define MSG_LINK_CMD_COMPLETE 0x0a /* O/O */
20#define MSG_LINK_CMD_COMPLETEF 0x0b /* O/O */
21#define MSG_BUS_DEV_RESET 0x0c /* O/M */
22#define MSG_TARGET_RESET 0x0c /* O/M */ /* SPI3 Terminology */
23#define MSG_ABORT_TAG 0x0d /* O/O */
24#define MSG_ABORT_TASK 0x0d /* O/O */ /* SPI3 Terminology */
25#define MSG_CLEAR_QUEUE 0x0e /* O/O */
26#define MSG_CLEAR_TASK_SET 0x0e /* O/O */ /* SPI3 Terminology */
27#define MSG_INIT_RECOVERY 0x0f /* O/O */ /* Deprecated in SPI3 */
28#define MSG_REL_RECOVERY 0x10 /* O/O */ /* Deprecated in SPI3 */
29#define MSG_TERM_IO_PROC 0x11 /* O/O */ /* Deprecated in SPI3 */
30#define MSG_CLEAR_ACA 0x16 /* O/O */ /* SPI3 */
31#define MSG_LOGICAL_UNIT_RESET 0x17 /* O/O */ /* SPI3 */
32#define MSG_QAS_REQUEST 0x55 /* O/O */ /* SPI3 */
33
34/* Messages (2 byte) */
35#define MSG_SIMPLE_Q_TAG 0x20 /* O/O */
36#define MSG_SIMPLE_TASK 0x20 /* O/O */ /* SPI3 Terminology */
37#define MSG_HEAD_OF_Q_TAG 0x21 /* O/O */
38#define MSG_HEAD_OF_QUEUE_TASK 0x21 /* O/O */ /* SPI3 Terminology */
39#define MSG_ORDERED_Q_TAG 0x22 /* O/O */
40#define MSG_ORDERED_TASK 0x22 /* O/O */ /* SPI3 Terminology */
41#define MSG_IGN_WIDE_RESIDUE 0x23 /* O/O */
42#define MSG_ACA_TASK 0x24 /* 0/0 */ /* SPI3 */
43
44/* Identify message */ /* M/M */
45#define MSG_IDENTIFYFLAG 0x80
46#define MSG_IDENTIFY_DISCFLAG 0x40
47#define MSG_IDENTIFY(lun, disc) (((disc) ? 0xc0 : MSG_IDENTIFYFLAG) | (lun))
48#define MSG_ISIDENTIFY(m) ((m) & MSG_IDENTIFYFLAG)
49#define MSG_IDENTIFY_LUNMASK 0x3F
50
51/* Extended messages (opcode and length) */
52#define MSG_EXT_SDTR 0x01
53#define MSG_EXT_SDTR_LEN 0x03
54
55#define MSG_EXT_WDTR 0x03
56#define MSG_EXT_WDTR_LEN 0x02
57#define MSG_EXT_WDTR_BUS_8_BIT 0x00
58#define MSG_EXT_WDTR_BUS_16_BIT 0x01
59#define MSG_EXT_WDTR_BUS_32_BIT 0x02 /* Deprecated in SPI3 */
60
61#define MSG_EXT_PPR 0x04 /* SPI3 */
62#define MSG_EXT_PPR_LEN 0x06
63#define MSG_EXT_PPR_PCOMP_EN 0x80
64#define MSG_EXT_PPR_RTI 0x40
65#define MSG_EXT_PPR_RD_STRM 0x20
66#define MSG_EXT_PPR_WR_FLOW 0x10
67#define MSG_EXT_PPR_HOLD_MCS 0x08
68#define MSG_EXT_PPR_QAS_REQ 0x04
69#define MSG_EXT_PPR_DT_REQ 0x02
70#define MSG_EXT_PPR_IU_REQ 0x01